From 042acd9ed21c37b708775297da275abf6459097e Mon Sep 17 00:00:00 2001
From: mleku
Date: Thu, 25 Dec 2025 12:38:54 +0100
Subject: [PATCH] Track all dist assets and remove debug logging
---
app/web/dist/bundle.css | 87 +++++++++++++++++++++++++++++++++
app/web/dist/bundle.js | 2 +-
app/web/dist/bundle.js.map | 1 +
app/web/dist/favicon.png | Bin 0 -> 387663 bytes
app/web/dist/global.css | 69 ++++++++++++++++++++++++++
app/web/dist/orly.png | Bin 0 -> 526586 bytes
app/web/src/BlossomView.svelte | 4 --
7 files changed, 158 insertions(+), 5 deletions(-)
create mode 100644 app/web/dist/bundle.css
create mode 100644 app/web/dist/bundle.js.map
create mode 100644 app/web/dist/favicon.png
create mode 100644 app/web/dist/global.css
create mode 100644 app/web/dist/orly.png
diff --git a/app/web/dist/bundle.css b/app/web/dist/bundle.css
new file mode 100644
index 0000000..f3ca83b
--- /dev/null
+++ b/app/web/dist/bundle.css
@@ -0,0 +1,87 @@
+.modal-overlay.svelte-4xpfbi.svelte-4xpfbi{position:fixed;top:0;left:0;width:100%;height:100%;background-color:rgba(0, 0, 0, 0.5);display:flex;justify-content:center;align-items:center;z-index:1000}.modal.svelte-4xpfbi.svelte-4xpfbi{background:var(--bg-color);border-radius:8px;box-shadow:0 4px 20px rgba(0, 0, 0, 0.3);width:90%;max-width:500px;max-height:90vh;overflow-y:auto;border:1px solid var(--border-color)}.modal-header.svelte-4xpfbi.svelte-4xpfbi{display:flex;justify-content:space-between;align-items:center;padding:20px;border-bottom:1px solid var(--border-color)}.modal-header.svelte-4xpfbi h2.svelte-4xpfbi{margin:0;color:var(--text-color);font-size:1.5rem}.close-btn.svelte-4xpfbi.svelte-4xpfbi{background:none;border:none;font-size:1.5rem;cursor:pointer;color:var(--text-color);padding:0;width:30px;height:30px;display:flex;align-items:center;justify-content:center;border-radius:50%;transition:background-color 0.2s}.close-btn.svelte-4xpfbi.svelte-4xpfbi:hover{background-color:var(--tab-hover-bg)}.tab-container.svelte-4xpfbi.svelte-4xpfbi{padding:20px}.tabs.svelte-4xpfbi.svelte-4xpfbi{display:flex;border-bottom:1px solid var(--border-color);margin-bottom:20px}.tab-btn.svelte-4xpfbi.svelte-4xpfbi{flex:1;padding:12px 16px;background:none;border:none;cursor:pointer;color:var(--text-color);font-size:1rem;transition:all 0.2s;border-bottom:2px solid transparent}.tab-btn.svelte-4xpfbi.svelte-4xpfbi:hover{background-color:var(--tab-hover-bg)}.tab-btn.active.svelte-4xpfbi.svelte-4xpfbi{border-bottom-color:var(--primary);color:var(--primary)}.tab-content.svelte-4xpfbi.svelte-4xpfbi{min-height:200px}.extension-login.svelte-4xpfbi.svelte-4xpfbi,.nsec-login.svelte-4xpfbi.svelte-4xpfbi{display:flex;flex-direction:column;gap:16px}.extension-login.svelte-4xpfbi p.svelte-4xpfbi,.nsec-login.svelte-4xpfbi p.svelte-4xpfbi{margin:0;color:var(--text-color);line-height:1.5}.login-extension-btn.svelte-4xpfbi.svelte-4xpfbi,.login-nsec-btn.svelte-4xpfbi.svelte-4xpfbi{padding:12px 24px;background:var(--primary);color:var(--text-color);border:none;border-radius:6px;cursor:pointer;font-size:1rem;transition:background-color 0.2s}.login-extension-btn.svelte-4xpfbi.svelte-4xpfbi:hover:not(:disabled),.login-nsec-btn.svelte-4xpfbi.svelte-4xpfbi:hover:not(:disabled){background:#00acc1}.login-extension-btn.svelte-4xpfbi.svelte-4xpfbi:disabled,.login-nsec-btn.svelte-4xpfbi.svelte-4xpfbi:disabled{background:#ccc;cursor:not-allowed}.nsec-input.svelte-4xpfbi.svelte-4xpfbi{padding:12px;border:1px solid var(--input-border);border-radius:6px;font-size:1rem;background:var(--bg-color);color:var(--text-color)}.nsec-input.svelte-4xpfbi.svelte-4xpfbi:focus{outline:none;border-color:var(--primary)}.generate-btn.svelte-4xpfbi.svelte-4xpfbi{padding:10px 20px;background:var(--success, #4caf50);color:white;border:none;border-radius:6px;cursor:pointer;font-size:0.95rem;transition:background-color 0.2s}.generate-btn.svelte-4xpfbi.svelte-4xpfbi:hover:not(:disabled){background:#45a049}.generate-btn.svelte-4xpfbi.svelte-4xpfbi:disabled{background:#ccc;cursor:not-allowed}.generated-info.svelte-4xpfbi.svelte-4xpfbi{background:var(--card-bg, #f5f5f5);padding:12px;border-radius:6px;border:1px solid var(--border-color)}.generated-info.svelte-4xpfbi label.svelte-4xpfbi{display:block;font-size:0.85rem;color:var(--muted-foreground, #666);margin-bottom:6px}.npub-display.svelte-4xpfbi.svelte-4xpfbi{display:block;word-break:break-all;font-size:0.85rem;background:var(--bg-color);padding:8px;border-radius:4px;color:var(--text-color)}.password-section.svelte-4xpfbi.svelte-4xpfbi{display:flex;flex-direction:column;gap:8px}.password-section.svelte-4xpfbi label.svelte-4xpfbi{font-size:0.9rem;color:var(--text-color);font-weight:500}.password-input.svelte-4xpfbi.svelte-4xpfbi{padding:10px 12px;border:1px solid var(--input-border);border-radius:6px;font-size:0.95rem;background:var(--bg-color);color:var(--text-color)}.password-input.svelte-4xpfbi.svelte-4xpfbi:focus{outline:none;border-color:var(--primary)}.password-hint.svelte-4xpfbi.svelte-4xpfbi{font-size:0.8rem;color:var(--muted-foreground, #888);font-style:italic}.stored-info.svelte-4xpfbi.svelte-4xpfbi{background:var(--card-bg, #f5f5f5);padding:12px;border-radius:6px;border:1px solid var(--border-color)}.stored-info.svelte-4xpfbi label.svelte-4xpfbi{display:block;font-size:0.85rem;color:var(--muted-foreground, #666);margin-bottom:6px}.clear-btn.svelte-4xpfbi.svelte-4xpfbi{padding:10px 20px;background:transparent;color:var(--error, #dc3545);border:1px solid var(--error, #dc3545);border-radius:6px;cursor:pointer;font-size:0.9rem;transition:all 0.2s}.clear-btn.svelte-4xpfbi.svelte-4xpfbi:hover:not(:disabled){background:var(--error, #dc3545);color:white}.clear-btn.svelte-4xpfbi.svelte-4xpfbi:disabled{opacity:0.5;cursor:not-allowed}.message.svelte-4xpfbi.svelte-4xpfbi{padding:10px;border-radius:4px;margin-top:16px;text-align:center}.error-message.svelte-4xpfbi.svelte-4xpfbi{background:#ffebee;color:#c62828;border:1px solid #ffcdd2}.success-message.svelte-4xpfbi.svelte-4xpfbi{background:#e8f5e8;color:#2e7d32;border:1px solid #c8e6c9}.modal.dark-theme.svelte-4xpfbi .error-message.svelte-4xpfbi{background:#4a2c2a;color:#ffcdd2;border:1px solid #6d4c41}.modal.dark-theme.svelte-4xpfbi .success-message.svelte-4xpfbi{background:#2e4a2e;color:#a5d6a7;border:1px solid #4caf50}.deriving-overlay.svelte-4xpfbi.svelte-4xpfbi{position:fixed;top:0;left:0;width:100%;height:100%;background-color:rgba(0, 0, 0, 0.7);display:flex;justify-content:center;align-items:center;z-index:2000}.deriving-modal.svelte-4xpfbi.svelte-4xpfbi{background:var(--bg-color, #fff);border-radius:12px;padding:2rem;text-align:center;box-shadow:0 8px 32px rgba(0, 0, 0, 0.3);min-width:280px}.deriving-modal.svelte-4xpfbi h3.svelte-4xpfbi{margin:1rem 0 0.5rem;color:var(--text-color, #333);font-size:1.2rem}.deriving-timer.svelte-4xpfbi.svelte-4xpfbi{font-size:2.5rem;font-weight:bold;color:var(--primary, #00bcd4);font-family:monospace;margin:0.5rem 0}.deriving-note.svelte-4xpfbi.svelte-4xpfbi{margin:0.5rem 0 0;color:var(--muted-foreground, #666);font-size:0.9rem}.deriving-spinner.svelte-4xpfbi.svelte-4xpfbi{width:48px;height:48px;border:4px solid var(--border-color, #e0e0e0);border-top-color:var(--primary, #00bcd4);border-radius:50%;margin:0 auto;animation:svelte-4xpfbi-spin 1s linear infinite}@keyframes svelte-4xpfbi-spin{to{transform:rotate(360deg)}}.deriving-modal.dark-theme.svelte-4xpfbi.svelte-4xpfbi{background:#1a1a1a}.deriving-modal.dark-theme.svelte-4xpfbi h3.svelte-4xpfbi{color:#fff}.deriving-modal.dark-theme.svelte-4xpfbi .deriving-note.svelte-4xpfbi{color:#aaa}
+.header.svelte-1y8wjwc.svelte-1y8wjwc{margin-bottom:30px}.header.svelte-1y8wjwc h2.svelte-1y8wjwc{margin:0 0 10px 0;color:var(--text-color)}.header.svelte-1y8wjwc p.svelte-1y8wjwc{margin:0;color:var(--text-color);opacity:0.8}.owner-only-notice.svelte-1y8wjwc.svelte-1y8wjwc{margin-top:10px;padding:8px 12px;background-color:var(--warning-bg);border:1px solid var(--warning);border-radius:4px;color:var(--text-color);font-size:0.9em}.message.svelte-1y8wjwc.svelte-1y8wjwc{padding:10px 15px;border-radius:4px;margin-bottom:20px}.message.success.svelte-1y8wjwc.svelte-1y8wjwc{background-color:var(--success-bg);color:var(--success-text);border:1px solid var(--success)}.message.error.svelte-1y8wjwc.svelte-1y8wjwc{background-color:var(--error-bg);color:var(--error-text);border:1px solid var(--danger)}.message.info.svelte-1y8wjwc.svelte-1y8wjwc{background-color:var(--primary-bg);color:var(--text-color);border:1px solid var(--info)}.tabs.svelte-1y8wjwc.svelte-1y8wjwc{display:flex;border-bottom:1px solid var(--border-color);margin-bottom:20px}.tab.svelte-1y8wjwc.svelte-1y8wjwc{padding:10px 20px;border:none;background:none;cursor:pointer;border-bottom:2px solid transparent;transition:all 0.2s;color:var(--text-color)}.tab.svelte-1y8wjwc.svelte-1y8wjwc:hover{background-color:var(--button-hover-bg)}.tab.active.svelte-1y8wjwc.svelte-1y8wjwc{border-bottom-color:var(--accent-color);color:var(--accent-color)}.tab-content.svelte-1y8wjwc.svelte-1y8wjwc{min-height:400px}.section.svelte-1y8wjwc.svelte-1y8wjwc{margin-bottom:30px}.section.svelte-1y8wjwc h3.svelte-1y8wjwc{margin:0 0 15px 0;color:var(--text-color)}.add-form.svelte-1y8wjwc.svelte-1y8wjwc{display:flex;gap:10px;margin-bottom:20px;flex-wrap:wrap}.add-form.svelte-1y8wjwc input.svelte-1y8wjwc{padding:8px 12px;border:1px solid var(--input-border);border-radius:4px;background:var(--bg-color);color:var(--text-color);flex:1;min-width:200px}.add-form.svelte-1y8wjwc button.svelte-1y8wjwc{padding:8px 16px;background-color:var(--accent-color);color:var(--text-color);border:none;border-radius:4px;cursor:pointer}.add-form.svelte-1y8wjwc button.svelte-1y8wjwc:disabled{background-color:var(--secondary);cursor:not-allowed}.list.svelte-1y8wjwc.svelte-1y8wjwc{border:1px solid var(--border-color);border-radius:4px;max-height:300px;overflow-y:auto;background:var(--bg-color)}.list-item.svelte-1y8wjwc.svelte-1y8wjwc{padding:10px 15px;border-bottom:1px solid var(--border-color);display:flex;align-items:center;gap:15px;color:var(--text-color)}.list-item.svelte-1y8wjwc.svelte-1y8wjwc:last-child{border-bottom:none}.pubkey.svelte-1y8wjwc.svelte-1y8wjwc,.event-id.svelte-1y8wjwc.svelte-1y8wjwc,.ip.svelte-1y8wjwc.svelte-1y8wjwc,.kind.svelte-1y8wjwc.svelte-1y8wjwc{font-family:monospace;font-size:0.9em;color:var(--text-color)}.reason.svelte-1y8wjwc.svelte-1y8wjwc{color:var(--text-color);opacity:0.7;font-style:italic}.remove-btn.svelte-1y8wjwc.svelte-1y8wjwc{padding:4px 8px;background-color:var(--danger);color:var(--text-color);border:none;border-radius:3px;cursor:pointer;font-size:0.8em}.actions.svelte-1y8wjwc.svelte-1y8wjwc{display:flex;gap:5px;margin-left:auto}.actions.svelte-1y8wjwc button.svelte-1y8wjwc{padding:4px 8px;border:none;border-radius:3px;cursor:pointer;font-size:0.8em}.actions.svelte-1y8wjwc button.svelte-1y8wjwc:first-child{background-color:var(--success);color:var(--text-color)}.actions.svelte-1y8wjwc button.svelte-1y8wjwc:last-child{background-color:var(--danger);color:var(--text-color)}.config-form.svelte-1y8wjwc.svelte-1y8wjwc{display:flex;flex-direction:column;gap:20px}.form-group.svelte-1y8wjwc.svelte-1y8wjwc{display:flex;flex-direction:column;gap:10px}.form-group.svelte-1y8wjwc label.svelte-1y8wjwc{font-weight:bold;color:var(--text-color)}.form-group.svelte-1y8wjwc input.svelte-1y8wjwc,.form-group.svelte-1y8wjwc textarea.svelte-1y8wjwc{padding:8px 12px;border:1px solid var(--input-border);border-radius:4px;background:var(--bg-color);color:var(--text-color)}.form-group.svelte-1y8wjwc textarea.svelte-1y8wjwc{min-height:80px;resize:vertical}.config-actions.svelte-1y8wjwc.svelte-1y8wjwc{margin-bottom:20px;padding:10px;background-color:var(--button-bg);border-radius:4px}.refresh-btn.svelte-1y8wjwc.svelte-1y8wjwc{padding:8px 16px;background-color:var(--success);color:var(--text-color);border:none;border-radius:4px;cursor:pointer;font-size:0.9em}.refresh-btn.svelte-1y8wjwc.svelte-1y8wjwc:hover:not(:disabled){background-color:var(--success);filter:brightness(0.9)}.refresh-btn.svelte-1y8wjwc.svelte-1y8wjwc:disabled{background-color:var(--secondary);cursor:not-allowed}.config-update-section.svelte-1y8wjwc.svelte-1y8wjwc{margin-top:20px;padding:15px;background-color:var(--button-bg);border-radius:6px;text-align:center}.update-all-btn.svelte-1y8wjwc.svelte-1y8wjwc{padding:12px 24px;background-color:var(--success);color:var(--text-color);border:none;border-radius:6px;cursor:pointer;font-size:1em;font-weight:600;min-width:200px}.update-all-btn.svelte-1y8wjwc.svelte-1y8wjwc:hover:not(:disabled){background-color:var(--success);filter:brightness(0.9);transform:translateY(-1px);box-shadow:0 2px 4px rgba(0, 0, 0, 0.1)}.update-all-btn.svelte-1y8wjwc.svelte-1y8wjwc:disabled{background-color:var(--secondary);cursor:not-allowed;transform:none;box-shadow:none}.no-items.svelte-1y8wjwc.svelte-1y8wjwc{padding:20px;text-align:center;color:var(--text-color);opacity:0.7;font-style:italic}
+.main-header.svelte-1qkhxam{color:var(--text-color);position:fixed;top:0;left:0;right:0;height:3em;background:var(--header-bg);border:0;z-index:1000;display:flex;align-items:stretch;padding:0 0.25em}.header-content.svelte-1qkhxam{display:flex;align-items:stretch;width:100%;padding:0;margin:0}.logo.svelte-1qkhxam{height:2.5em;width:auto;flex-shrink:0;align-self:center}.header-title.svelte-1qkhxam{flex:1;display:flex;align-items:center;align-self:center}.app-title.svelte-1qkhxam{font-size:1.2em;font-weight:600;color:var(--text-color);display:flex;align-items:center;gap:0.5em}.permission-badge.svelte-1qkhxam{background:var(--primary);color:var(--text-color);padding:0.2em 0.5em;border-radius:0.5em;font-size:0.7em;font-weight:500;text-transform:uppercase;letter-spacing:0.5px}.header-buttons.svelte-1qkhxam{display:flex;align-items:stretch;align-self:stretch;margin-left:auto}.login-btn.svelte-1qkhxam,.user-profile-btn.svelte-1qkhxam{background:transparent;color:var(--button-text);border:0;cursor:pointer;font-size:1em;transition:background-color 0.2s;flex-shrink:0;padding:0.5em;margin:0;display:flex !important;align-items:center !important;justify-content:center}.login-btn.svelte-1qkhxam:hover,.user-profile-btn.svelte-1qkhxam:hover{background:var(--card-bg)}.user-profile-btn.svelte-1qkhxam{gap:0.5em;justify-content:flex-start;padding:0 0.5em}.user-avatar.svelte-1qkhxam{height:2.5em;width:2.5em;border-radius:50%;object-fit:cover;flex-shrink:0;align-self:center;vertical-align:middle}.user-avatar-placeholder.svelte-1qkhxam{height:2.5em;width:2.5em;border-radius:50%;background:var(--bg-color);display:flex;align-items:center;justify-content:center;font-size:1.2em;flex-shrink:0;align-self:center}.user-name.svelte-1qkhxam{font-weight:500;white-space:nowrap;line-height:1;align-self:center;max-width:none !important;overflow:visible !important;text-overflow:unset !important;width:auto !important}
+.sidebar.svelte-wfmuj{position:fixed;left:0;top:3em;width:200px;bottom:0;background:var(--sidebar-bg);overflow-y:auto;z-index:100}.sidebar-content.svelte-wfmuj{padding:0;background:var(--sidebar-bg)}.tabs.svelte-wfmuj{display:flex;flex-direction:column;padding:0}.tab.svelte-wfmuj{display:flex;align-items:center;padding:0.75em;padding-left:1em;background:transparent;color:var(--text-color);border:none;cursor:pointer;transition:background-color 0.2s;gap:0.75rem;text-align:left;width:100%}.tab.svelte-wfmuj:hover{background-color:var(--bg-color)}.tab.active.svelte-wfmuj{background-color:var(--bg-color)}.tab-icon.svelte-wfmuj{font-size:1.2em;flex-shrink:0;width:1.5em;text-align:center}.tab-label.svelte-wfmuj{font-size:0.9em;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1}.tab-close-icon.svelte-wfmuj{cursor:pointer;transition:opacity 0.2s;font-size:0.8em;margin-left:auto;padding:0.25rem;flex-shrink:0}.tab-close-icon.svelte-wfmuj:hover{opacity:0.7;background-color:var(--warning);color:var(--text-color)}@media(max-width: 1280px){.sidebar.svelte-wfmuj{width:60px}.tab-label.svelte-wfmuj{display:none}.tab-close-icon.svelte-wfmuj{display:none}.tab.svelte-wfmuj{justify-content:flex-start}}@media(max-width: 640px){.sidebar.svelte-wfmuj{width:160px}.tab-label.svelte-wfmuj{display:block}.tab.svelte-wfmuj{justify-content:flex-start}}.version-link.svelte-wfmuj{position:absolute;bottom:0;left:0;right:0;display:flex;align-items:center;gap:0.5rem;padding:0.75em 1em;color:var(--text-color);text-decoration:none;font-size:0.8em;transition:background-color 0.2s, color 0.2s;background:transparent}.version-link.svelte-wfmuj:hover{background-color:var(--bg-color)}.version-icon.svelte-wfmuj{width:1.2em;height:1.2em;flex-shrink:0;color:#4a9c5d}.version-text.svelte-wfmuj{white-space:nowrap}@media(max-width: 1280px){.version-text.svelte-wfmuj{display:none}.version-link.svelte-wfmuj{justify-content:flex-start;padding-left:1.25em}}@media(max-width: 640px){.version-text.svelte-wfmuj{display:inline}}
+.export-section.svelte-jzrdtj.svelte-jzrdtj{border-radius:8px;padding:1em;margin:1em;width:100%;max-width:32em;box-sizing:border-box;background-color:var(--card-bg)}.export-section.svelte-jzrdtj h3.svelte-jzrdtj{margin:0 0 1rem 0;color:var(--text-color);font-size:1.2rem;font-weight:600}.export-section.svelte-jzrdtj p.svelte-jzrdtj{margin:0 0 1.5rem 0;color:var(--text-color);opacity:0.8;line-height:1.4}.export-btn.svelte-jzrdtj.svelte-jzrdtj{background-color:var(--primary);color:var(--text-color);border:none;padding:0.75em 1.5em;border-radius:0.5em;cursor:pointer;font-weight:bold;font-size:0.9em;transition:background-color 0.2s}.export-btn.svelte-jzrdtj.svelte-jzrdtj:hover{background-color:var(--accent-hover-color)}.login-prompt.svelte-jzrdtj.svelte-jzrdtj{text-align:center;padding:2em;background-color:var(--card-bg);border-radius:8px;border:1px solid var(--border-color);width:100%;max-width:32em;box-sizing:border-box}.login-prompt.svelte-jzrdtj p.svelte-jzrdtj{margin:0 0 1.5rem 0;color:var(--text-color);font-size:1.1rem}.login-btn.svelte-jzrdtj.svelte-jzrdtj{background-color:var(--primary);color:var(--text-color);border:none;padding:0.75em 1.5em;border-radius:4px;cursor:pointer;font-weight:bold;font-size:0.9em;transition:background-color 0.2s}.login-btn.svelte-jzrdtj.svelte-jzrdtj:hover{background-color:var(--accent-hover-color)}
+.import-section.svelte-nonyqh.svelte-nonyqh{background:transparent;padding:1em;border-radius:8px;margin-bottom:1.5rem;width:100%;max-width:32em;box-sizing:border-box}.import-section.svelte-nonyqh h3.svelte-nonyqh{margin:0 0 1rem 0;color:var(--text-color);font-size:1.2rem;font-weight:600}.import-section.svelte-nonyqh p.svelte-nonyqh{margin:0 0 1.5rem 0;color:var(--text-color);opacity:0.8;line-height:1.4}.recovery-controls-card.svelte-nonyqh.svelte-nonyqh{background-color:var(--card-bg);padding:1em;border:0;display:flex;flex-direction:column;border-radius:0.5em;gap:1em}#import-file.svelte-nonyqh.svelte-nonyqh{padding:0.5em;border:0;background:var(--input-bg);color:var(--input-text-color)}.import-btn.svelte-nonyqh.svelte-nonyqh{background-color:var(--primary);color:var(--text-color);border-radius:0.5em;padding:0.75em 1.5em;border:0;cursor:pointer;font-weight:bold;font-size:0.9em;transition:background-color 0.2s;align-self:flex-start}.import-btn.svelte-nonyqh.svelte-nonyqh:hover:not(:disabled){background-color:var(--accent-hover-color)}.import-btn.svelte-nonyqh.svelte-nonyqh:disabled{background-color:var(--secondary);cursor:not-allowed}.import-row.svelte-nonyqh.svelte-nonyqh{display:flex;align-items:center;gap:1em}.import-message.svelte-nonyqh.svelte-nonyqh{font-size:0.9em;padding:0.25em 0.5em;border-radius:0.25em}.import-message.uploading.svelte-nonyqh.svelte-nonyqh{color:var(--primary)}.import-message.success.svelte-nonyqh.svelte-nonyqh{color:#4caf50}.import-message.error.svelte-nonyqh.svelte-nonyqh{color:#f44336}.permission-denied.svelte-nonyqh.svelte-nonyqh,.login-prompt.svelte-nonyqh.svelte-nonyqh{text-align:center;padding:2em;background-color:var(--card-bg);border:0}.recovery-header.svelte-nonyqh.svelte-nonyqh{margin:0 0 1rem 0;color:var(--text-color);font-size:1.2rem;font-weight:600}.recovery-description.svelte-nonyqh.svelte-nonyqh{margin:0 0 1.5rem 0;color:var(--text-color);line-height:1.4}.login-btn.svelte-nonyqh.svelte-nonyqh{background-color:var(--primary);color:var(--text-color);border:none;padding:0.75em 1.5em;border:0;cursor:pointer;font-weight:bold;font-size:0.9em;transition:background-color 0.2s}.login-btn.svelte-nonyqh.svelte-nonyqh:hover{background-color:var(--accent-hover-color)}
+.filter-builder.svelte-1a1v6k0.svelte-1a1v6k0{padding:1em;background:var(--bg-color);border-bottom:1px solid var(--border-color);display:flex;gap:1em}.filter-content.svelte-1a1v6k0.svelte-1a1v6k0{flex:1;min-width:0}.clear-column.svelte-1a1v6k0.svelte-1a1v6k0{display:flex;flex-direction:column;gap:0.5em;flex-shrink:0;width:2.5em}.clear-column.svelte-1a1v6k0 .spacer.svelte-1a1v6k0{flex:1}.clear-all-btn.svelte-1a1v6k0.svelte-1a1v6k0,.json-toggle-btn.svelte-1a1v6k0.svelte-1a1v6k0{background:var(--secondary);color:var(--text-color);border:none;padding:0;border-radius:4px;cursor:pointer;font-size:1em;transition:filter 0.2s, background-color 0.2s;width:100%;aspect-ratio:1;display:flex;align-items:center;justify-content:center;box-sizing:border-box}.clear-all-btn.svelte-1a1v6k0.svelte-1a1v6k0{background:var(--danger)}.clear-all-btn.svelte-1a1v6k0.svelte-1a1v6k0:hover{filter:brightness(1.2)}.json-toggle-btn.svelte-1a1v6k0.svelte-1a1v6k0{font-family:monospace;font-weight:600;background:var(--primary)}.json-toggle-btn.svelte-1a1v6k0.svelte-1a1v6k0:hover{background:var(--accent-hover-color)}.json-toggle-btn.active.svelte-1a1v6k0.svelte-1a1v6k0{background:var(--accent-hover-color)}.filter-grid.svelte-1a1v6k0.svelte-1a1v6k0{display:grid;grid-template-columns:auto 1fr;gap:0.5em 1em;align-items:start}.filter-grid.svelte-1a1v6k0>label.svelte-1a1v6k0{font-weight:600;color:var(--text-color);font-size:0.9em;padding-top:0.6em;white-space:nowrap}.field-content.svelte-1a1v6k0.svelte-1a1v6k0{min-width:0}.filter-input.svelte-1a1v6k0.svelte-1a1v6k0{width:100%;padding:0.6em;border:1px solid var(--border-color);border-radius:4px;background:var(--input-bg);color:var(--input-text-color);font-size:0.9em;box-sizing:border-box}.filter-input.svelte-1a1v6k0.svelte-1a1v6k0:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 2px rgba(0, 123, 255, 0.15)}.picker-toggle-btn.svelte-1a1v6k0.svelte-1a1v6k0{width:100%;padding:0.6em;background:var(--secondary);color:var(--text-color);border:1px solid var(--border-color);border-radius:4px;cursor:pointer;font-size:0.9em;text-align:left;transition:background-color 0.2s}.picker-toggle-btn.svelte-1a1v6k0.svelte-1a1v6k0:hover{background:var(--accent-hover-color)}.kinds-picker.svelte-1a1v6k0.svelte-1a1v6k0{margin-top:0.5em;border:1px solid var(--border-color);border-radius:4px;padding:0.5em;background:var(--card-bg)}.kind-search.svelte-1a1v6k0.svelte-1a1v6k0{margin-bottom:0.5em}.kinds-list.svelte-1a1v6k0.svelte-1a1v6k0{max-height:300px;overflow-y:auto}.kind-checkbox.svelte-1a1v6k0.svelte-1a1v6k0{display:flex;align-items:center;padding:0.4em;cursor:pointer;border-radius:4px;transition:background-color 0.2s}.kind-checkbox.svelte-1a1v6k0.svelte-1a1v6k0:hover{background:var(--bg-color)}.kind-checkbox.svelte-1a1v6k0 input[type="checkbox"].svelte-1a1v6k0{margin-right:0.5em;cursor:pointer}.kind-number.svelte-1a1v6k0.svelte-1a1v6k0{background:var(--primary);color:var(--text-color);padding:0.1em 0.4em;border-radius:3px;font-size:0.8em;font-weight:600;font-family:monospace;margin-right:0.5em;min-width:40px;text-align:center;display:inline-block}.kind-name.svelte-1a1v6k0.svelte-1a1v6k0{font-size:0.85em;color:var(--text-color)}.chips-container.svelte-1a1v6k0.svelte-1a1v6k0{display:flex;flex-wrap:wrap;gap:0.5em;margin-top:0.5em}.chip.svelte-1a1v6k0.svelte-1a1v6k0{display:inline-flex;align-items:center;background:var(--primary);color:var(--text-color);padding:0.2em 0.5em;border-radius:0.5em;font-size:0.7em;font-weight:500;text-transform:uppercase;letter-spacing:0.5px;gap:0.4em}.chip-text.svelte-1a1v6k0.svelte-1a1v6k0{line-height:1}.chip-remove.svelte-1a1v6k0.svelte-1a1v6k0{background:transparent;border:none;color:var(--text-color);cursor:pointer;padding:0;font-size:1em;line-height:1;opacity:0.8;transition:opacity 0.2s}.chip-remove.svelte-1a1v6k0.svelte-1a1v6k0:hover{opacity:1}.input-group.svelte-1a1v6k0.svelte-1a1v6k0{display:flex;gap:0.5em}.input-group.svelte-1a1v6k0 .filter-input.svelte-1a1v6k0{flex:1}.add-btn.svelte-1a1v6k0.svelte-1a1v6k0{background:var(--primary);color:var(--text-color);border:none;padding:0.6em 1.2em;border-radius:4px;cursor:pointer;font-size:0.9em;font-weight:600;transition:background-color 0.2s;white-space:nowrap}.add-btn.svelte-1a1v6k0.svelte-1a1v6k0:hover{background:var(--accent-hover-color)}.error-message.svelte-1a1v6k0.svelte-1a1v6k0{color:var(--danger);font-size:0.85em;margin-top:0.25em}.list-items.svelte-1a1v6k0.svelte-1a1v6k0{margin-top:0.5em;display:flex;flex-direction:column;gap:0.5em}.list-item.svelte-1a1v6k0.svelte-1a1v6k0{display:flex;align-items:center;padding:0.5em;background:var(--card-bg);border:1px solid var(--border-color);border-radius:4px;gap:0.5em}.list-item-text.svelte-1a1v6k0.svelte-1a1v6k0{flex:1;font-family:monospace;font-size:0.85em;color:var(--text-color);word-break:break-all}.list-item-remove.svelte-1a1v6k0.svelte-1a1v6k0{background:var(--danger);color:var(--text-color);border:none;padding:0.25em 0.5em;border-radius:3px;cursor:pointer;font-size:1.2em;line-height:1;transition:background-color 0.2s}.list-item-remove.svelte-1a1v6k0.svelte-1a1v6k0:hover{filter:brightness(0.9)}.tag-input-group.svelte-1a1v6k0.svelte-1a1v6k0{display:flex;gap:0.5em;align-items:center}.hash-prefix.svelte-1a1v6k0.svelte-1a1v6k0{font-weight:700;font-size:1.2em;color:var(--text-color)}.tag-name-input.svelte-1a1v6k0.svelte-1a1v6k0{width:50px}.tag-value-input.svelte-1a1v6k0.svelte-1a1v6k0{flex:1}.timestamp-field.svelte-1a1v6k0.svelte-1a1v6k0{position:relative;display:flex;align-items:center;gap:0.5em}.timestamp-field.svelte-1a1v6k0 .filter-input.svelte-1a1v6k0{flex:1}.clear-timestamp-btn.svelte-1a1v6k0.svelte-1a1v6k0{background:var(--danger);color:var(--text-color);border:none;padding:0.25em 0.5em;border-radius:3px;cursor:pointer;font-size:1em;line-height:1;transition:background-color 0.2s;flex-shrink:0}.clear-timestamp-btn.svelte-1a1v6k0.svelte-1a1v6k0:hover{filter:brightness(0.9)}.json-editor-section.svelte-1a1v6k0.svelte-1a1v6k0{grid-column:1 / -1;margin-top:0.5em;padding-top:1em;border-top:1px solid var(--border-color)}.json-editor-section.svelte-1a1v6k0 label.svelte-1a1v6k0{display:block;font-weight:600;color:var(--text-color);font-size:0.9em;margin-bottom:0.5em}.json-editor.svelte-1a1v6k0.svelte-1a1v6k0{width:100%;padding:0.6em;border:1px solid var(--border-color);border-radius:4px;background:var(--input-bg);color:var(--input-text-color);font-family:monospace;font-size:0.85em;resize:vertical;box-sizing:border-box}.json-editor.svelte-1a1v6k0.svelte-1a1v6k0:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 2px rgba(0, 123, 255, 0.15)}.json-error.svelte-1a1v6k0.svelte-1a1v6k0{color:var(--danger);font-size:0.85em;margin-top:0.25em}.apply-json-btn.svelte-1a1v6k0.svelte-1a1v6k0{margin-top:0.5em;background:var(--primary);color:var(--text-color);border:none;padding:0.5em 1em;border-radius:4px;cursor:pointer;font-size:0.9em;font-weight:600;transition:background-color 0.2s}.apply-json-btn.svelte-1a1v6k0.svelte-1a1v6k0:hover{background:var(--accent-hover-color)}@media(max-width: 768px){.filter-grid.svelte-1a1v6k0.svelte-1a1v6k0{grid-template-columns:1fr}.filter-grid.svelte-1a1v6k0>label.svelte-1a1v6k0{padding-top:0;padding-bottom:0.25em}}
+.events-view-container.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{width:100%;height:100%;display:flex;flex-direction:column;box-sizing:border-box}.events-view-content.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{flex:1;overflow-y:auto;padding:0}.events-view-content.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec::-webkit-scrollbar{width:16px;background:var(--bg-color)}.events-view-content.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec::-webkit-scrollbar-track{background:var(--bg-color)}.events-view-content.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec::-webkit-scrollbar-thumb{background:var(--text-color);border-radius:9999px;border:4px solid var(--bg-color)}.events-view-content.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec::-webkit-scrollbar-thumb:hover{background:var(--text-color);filter:brightness(1.2)}.events-view-content.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec::-webkit-scrollbar-button{background:var(--text-color);height:8px;border:4px solid var(--bg-color);border-radius:9999px;background-clip:padding-box}.events-view-item.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{border:0;margin:0;transition:all 0.2s ease}.events-view-item.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec:hover{padding:0}.events-view-row.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{display:flex;align-items:center;padding:0.5em;cursor:pointer;gap:1em}.events-view-avatar.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{flex-shrink:0}.avatar-placeholder.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{width:40px;height:40px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:1.2em;border:0}.events-view-info.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{flex-shrink:0;min-width:120px}.events-view-author.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{font-weight:600;color:var(--text-color);font-size:0.9em;font-family:monospace}.events-view-kind.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{display:flex;align-items:center;gap:0.5em;margin-top:0.25em}.kind-number.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{background:var(--primary);color:var(--text-color);padding:0.1em 0.4em;border:0;font-size:0.7em;font-weight:600;font-family:monospace}.kind-number.delete-event.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{background:var(--danger)}.kind-name.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{font-size:0.8em;color:var(--text-color);opacity:0.8}.event-timestamp.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{font-size:0.8em;color:var(--text-color);opacity:0.6;margin-bottom:0.5em}.delete-event-info.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{background:var(--danger-bg);padding:0.5em;border-radius:4px;border:1px solid var(--danger)}.delete-event-label.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{font-weight:600;color:var(--danger);display:block;margin-bottom:0.25em}.delete-targets.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{display:flex;flex-wrap:wrap;gap:0.25em}.delete-target.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{background:var(--danger);color:var(--text-color);padding:0.1em 0.3em;border-radius:0.2rem;font-size:0.7em;font-family:monospace}.event-content-single-line.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{color:var(--text-color);line-height:1.4;word-wrap:break-word}.delete-btn.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{background:var(--danger);color:var(--text-color);border:none;padding:0.5em;border-radius:4px;cursor:pointer;font-size:0.9em;flex-shrink:0;transition:background-color 0.2s}.delete-btn.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec:hover{background:var(--danger);filter:brightness(0.9)}.events-view-details.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{padding:0;background:var(--bg-color)}.json-container.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{position:relative}.event-json.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{background:var(--code-bg);padding:1em;border:0;font-size:0.8em;line-height:1.4;overflow-x:auto;margin:0;color:var(--code-text)}.copy-json-btn.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{position:absolute;top:1em;right:1em;background:var(--primary);color:var(--text-color);border:none;padding:1em;cursor:pointer;font-size:0.8em;opacity:0.8;transition:opacity 0.2s}.copy-json-btn.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec:hover{opacity:1}.no-events.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{text-align:center;padding:2em;color:var(--text-color);opacity:0.7}.loading-events.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{text-align:center;padding:2em;color:var(--text-color)}.spinner.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{width:20px;height:20px;border:0;border-radius:50%;animation:svelte-5kb1ec-spin 1s linear infinite;margin:0 auto 1em}@keyframes svelte-5kb1ec-spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.permission-denied.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{text-align:center;padding:2em;background-color:var(--card-bg);border-radius:8px;border:1px solid var(--border-color);color:var(--text-color)}.events-view-footer.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{position:relative;flex-shrink:0}.events-view-header.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{display:flex;justify-content:space-between;align-items:center;padding:0.5em;border:0;background:var(--header-bg)}.events-view-toggle.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{display:flex;align-items:center}.toggle-container.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{display:flex;align-items:center;gap:0.5em;cursor:pointer}.toggle-container.svelte-5kb1ec input[type="checkbox"].svelte-5kb1ec.svelte-5kb1ec{display:none}.toggle-slider.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{width:40px;height:20px;background:var(--border-color);border-radius:10px;position:relative;transition:background 0.2s}.toggle-slider.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec::before{content:"";position:absolute;width:16px;height:16px;background:var(--text-color);border-radius:50%;top:2px;left:2px;transition:transform 0.2s}.toggle-container.svelte-5kb1ec input.svelte-5kb1ec:checked+.toggle-slider.svelte-5kb1ec{background:var(--primary)}.toggle-container.svelte-5kb1ec input.svelte-5kb1ec:checked+.toggle-slider.svelte-5kb1ec::before{transform:translateX(20px)}.toggle-label.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{font-size:0.9em;color:var(--text-color)}.events-view-buttons.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{display:flex;gap:0.5em}.refresh-btn.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec,.reload-btn.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{background:var(--primary);color:var(--text-color);border:none;padding:0.4em 1em;border-radius:4px;cursor:pointer;font-size:0.9em;transition:background-color 0.2s;display:flex;align-items:center;justify-content:center;gap:0.25em;box-sizing:border-box;line-height:1}.reload-btn.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{width:2.5em;padding:0.4em}.refresh-btn.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec:hover:not(:disabled),.reload-btn.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec:hover:not(:disabled){background:var(--accent-hover-color)}.refresh-btn.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec:disabled,.reload-btn.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec:disabled{background:var(--secondary);cursor:not-allowed;padding:0.4em 1em}.reload-btn.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec:disabled{padding:0.4em}.reload-btn.svelte-5kb1ec .spinner.svelte-5kb1ec.svelte-5kb1ec{width:0.8em;height:0.8em;border:1.5px solid var(--text-color);border-top-color:transparent;border-radius:50%;animation:svelte-5kb1ec-spin 1s linear infinite;margin:0;box-sizing:border-box}.events-view-left.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{display:flex;align-items:center;gap:0.75em}.filter-btn.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{background:var(--primary);color:var(--text-color);border:none;padding:0.4em;border-radius:4px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:background-color 0.2s;width:2.2em;height:2.2em;box-sizing:border-box}.filter-btn.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec:hover{background:var(--accent-hover-color)}.filter-btn.active.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{background:var(--accent-hover-color)}.filter-btn.svelte-5kb1ec svg.svelte-5kb1ec.svelte-5kb1ec{width:1em;height:1em}.filter-panel.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{position:absolute;bottom:100%;left:0;right:0;background:var(--bg-color);border-top:1px solid var(--border-color);max-height:0;overflow:hidden;transition:max-height 0.3s ease-out;z-index:100;padding-right:16px;box-sizing:border-box;display:flex;flex-direction:column-reverse}.filter-panel.open.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec{max-height:60vh;overflow-y:auto}.filter-panel.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec::-webkit-scrollbar{width:16px;background:var(--bg-color)}.filter-panel.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec::-webkit-scrollbar-track{background:var(--bg-color)}.filter-panel.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec::-webkit-scrollbar-thumb{background:var(--text-color);border-radius:9999px;border:4px solid var(--bg-color)}.filter-panel.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec::-webkit-scrollbar-thumb:hover{background:var(--text-color);filter:brightness(1.2)}.filter-panel.svelte-5kb1ec.svelte-5kb1ec.svelte-5kb1ec::-webkit-scrollbar-button{background:var(--text-color);height:8px;border:4px solid var(--bg-color);border-radius:9999px;background-clip:padding-box}
+.modal-backdrop.svelte-v55ls1.svelte-v55ls1{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0, 0, 0, 0.7);display:flex;align-items:center;justify-content:center;z-index:1000}.modal-content.svelte-v55ls1.svelte-v55ls1{background:var(--card-bg);border-radius:0.5rem;width:90%;max-width:800px;max-height:85vh;display:flex;flex-direction:column;box-shadow:0 4px 20px rgba(0, 0, 0, 0.3);border:1px solid var(--border-color)}.modal-header.svelte-v55ls1.svelte-v55ls1{display:flex;justify-content:space-between;align-items:center;padding:1rem 1.5rem;border-bottom:1px solid var(--border-color)}.modal-header.svelte-v55ls1 h2.svelte-v55ls1{margin:0;font-size:1.25rem;color:var(--text-color)}.close-btn.svelte-v55ls1.svelte-v55ls1{background:none;border:none;font-size:1.5rem;cursor:pointer;color:var(--text-color);padding:0;width:2rem;height:2rem;display:flex;align-items:center;justify-content:center;border-radius:0.25rem}.close-btn.svelte-v55ls1.svelte-v55ls1:hover{background:var(--button-hover-bg)}.modal-filters.svelte-v55ls1.svelte-v55ls1{padding:1rem 1.5rem;border-bottom:1px solid var(--border-color)}.search-box.svelte-v55ls1.svelte-v55ls1{margin-bottom:0.75rem}.search-input.svelte-v55ls1.svelte-v55ls1{width:100%;padding:0.75rem;border:1px solid var(--border-color);border-radius:0.25rem;background:var(--input-bg);color:var(--input-text-color);font-size:0.9rem}.search-input.svelte-v55ls1.svelte-v55ls1:focus{outline:none;border-color:var(--accent-color)}.category-tabs.svelte-v55ls1.svelte-v55ls1{display:flex;flex-wrap:wrap;gap:0.5rem}.category-tab.svelte-v55ls1.svelte-v55ls1{padding:0.4rem 0.75rem;border:1px solid var(--border-color);border-radius:1rem;background:transparent;color:var(--text-color);font-size:0.75rem;cursor:pointer;transition:all 0.2s}.category-tab.svelte-v55ls1.svelte-v55ls1:hover{background:var(--button-hover-bg)}.category-tab.active.svelte-v55ls1.svelte-v55ls1{background:var(--accent-color);border-color:var(--accent-color);color:white}.modal-body.svelte-v55ls1.svelte-v55ls1{flex:1;overflow-y:auto;padding:1rem 1.5rem}.kinds-list.svelte-v55ls1.svelte-v55ls1{display:flex;flex-direction:column;gap:0.5rem}.kind-item.svelte-v55ls1.svelte-v55ls1{display:block;width:100%;text-align:left;padding:0.75rem 1rem;border:1px solid var(--border-color);border-radius:0.375rem;background:var(--bg-color);cursor:pointer;transition:all 0.2s}.kind-item.svelte-v55ls1.svelte-v55ls1:hover{border-color:var(--accent-color);background:var(--button-hover-bg)}.kind-header.svelte-v55ls1.svelte-v55ls1{display:flex;align-items:center;gap:0.5rem;margin-bottom:0.25rem}.kind-number.svelte-v55ls1.svelte-v55ls1{font-family:monospace;font-size:0.8rem;color:var(--accent-color);font-weight:bold}.kind-badge.svelte-v55ls1.svelte-v55ls1{font-size:0.65rem;padding:0.15rem 0.4rem;border-radius:0.25rem;font-weight:500}.badge-regular.svelte-v55ls1.svelte-v55ls1{background:#6c757d;color:white}.badge-replaceable.svelte-v55ls1.svelte-v55ls1{background:#17a2b8;color:white}.badge-ephemeral.svelte-v55ls1.svelte-v55ls1{background:#ffc107;color:black}.badge-addressable.svelte-v55ls1.svelte-v55ls1{background:#28a745;color:white}.nip-badge.svelte-v55ls1.svelte-v55ls1{font-size:0.65rem;padding:0.15rem 0.4rem;border-radius:0.25rem;background:var(--primary);color:var(--text-color)}.kind-name.svelte-v55ls1.svelte-v55ls1{font-weight:600;color:var(--text-color);margin-bottom:0.25rem}.kind-description.svelte-v55ls1.svelte-v55ls1{font-size:0.85rem;color:var(--text-color);opacity:0.7}.no-results.svelte-v55ls1.svelte-v55ls1{text-align:center;padding:2rem;color:var(--text-color);opacity:0.6}.modal-footer.svelte-v55ls1.svelte-v55ls1{display:flex;justify-content:space-between;align-items:center;padding:1rem 1.5rem;border-top:1px solid var(--border-color)}.result-count.svelte-v55ls1.svelte-v55ls1{font-size:0.85rem;color:var(--text-color);opacity:0.7}.cancel-btn.svelte-v55ls1.svelte-v55ls1{padding:0.5rem 1rem;border:1px solid var(--border-color);border-radius:0.25rem;background:var(--button-bg);color:var(--button-text);cursor:pointer;font-size:0.9rem}.cancel-btn.svelte-v55ls1.svelte-v55ls1:hover{background:var(--button-hover-bg)}@media(max-width: 640px){.modal-content.svelte-v55ls1.svelte-v55ls1{width:95%;max-height:90vh}.category-tabs.svelte-v55ls1.svelte-v55ls1{overflow-x:auto;flex-wrap:nowrap;padding-bottom:0.5rem}.category-tab.svelte-v55ls1.svelte-v55ls1{white-space:nowrap}}
+.compose-view.svelte-46pmgb{position:fixed;top:3em;left:200px;right:0;bottom:0;display:flex;flex-direction:column;background:transparent}.compose-header.svelte-46pmgb{display:flex;gap:0.5em;padding:0.5em;background:transparent}.compose-btn.svelte-46pmgb{padding:0.5em 1em;border:1px solid var(--border-color);border-radius:0.25rem;background:var(--button-bg);color:var(--button-text);cursor:pointer;font-size:0.9rem;transition:background-color 0.2s}.compose-btn.svelte-46pmgb:hover{background:var(--button-hover-bg)}.template-btn.svelte-46pmgb{background:var(--primary);color:var(--text-color)}.template-btn.svelte-46pmgb:hover{background:var(--primary);filter:brightness(0.9)}.reformat-btn.svelte-46pmgb{background:var(--info);color:var(--text-color)}.reformat-btn.svelte-46pmgb:hover{background:var(--info);filter:brightness(0.9)}.sign-btn.svelte-46pmgb{background:var(--warning);color:var(--text-color)}.sign-btn.svelte-46pmgb:hover{background:var(--warning);filter:brightness(0.9)}.publish-btn.svelte-46pmgb{background:var(--success);color:var(--text-color)}.publish-btn.svelte-46pmgb:hover{background:var(--success);filter:brightness(0.9)}.error-banner.svelte-46pmgb{display:flex;align-items:center;justify-content:space-between;padding:0.75em 1em;margin:0 0.5em;background:#f8d7da;border:1px solid #f5c6cb;border-radius:0.25rem;color:#721c24}.dark-theme .error-banner.svelte-46pmgb{background:#4a1c24;border-color:#6a2c34;color:#f8d7da}.error-content.svelte-46pmgb{display:flex;align-items:center;gap:0.5em}.error-icon.svelte-46pmgb{font-size:1.2em}.error-message.svelte-46pmgb{font-size:0.9rem;line-height:1.4}.error-dismiss.svelte-46pmgb{background:none;border:none;font-size:1.25rem;cursor:pointer;color:inherit;padding:0 0.25em;opacity:0.7}.error-dismiss.svelte-46pmgb:hover{opacity:1}.compose-editor.svelte-46pmgb{flex:1;display:flex;flex-direction:column;padding:0}.compose-textarea.svelte-46pmgb{flex:1;width:100%;padding:1em;border-radius:0.5em;background:var(--input-bg);color:var(--input-text-color);font-family:monospace;font-size:0.9em;line-height:1.4;resize:vertical;outline:none}.compose-textarea.svelte-46pmgb:focus{border-color:var(--accent-color);box-shadow:0 0 0 2px rgba(0, 123, 255, 0.25)}@media(max-width: 1280px){.compose-view.svelte-46pmgb{left:60px}}@media(max-width: 640px){.compose-view.svelte-46pmgb{left:160px}.compose-header.svelte-46pmgb{flex-wrap:wrap}.compose-btn.svelte-46pmgb{flex:1;min-width:calc(50% - 0.5em)}}
+.recovery-tab.svelte-1e1mff9.svelte-1e1mff9{width:100%;max-width:1200px;margin:0;padding:20px;background:var(--header-bg);color:var(--text-color);border-radius:8px;box-sizing:border-box}.recovery-tab.svelte-1e1mff9 h3.svelte-1e1mff9{margin:0 0 0.5rem 0;color:var(--text-color);font-size:1.5rem;font-weight:600}.recovery-tab.svelte-1e1mff9 p.svelte-1e1mff9{margin:0 0 1.5rem 0;color:var(--text-color);opacity:0.8;line-height:1.4}.recovery-controls-card.svelte-1e1mff9.svelte-1e1mff9{background-color:var(--card-bg);border-radius:0.5em;padding:1em;margin-bottom:1.5rem}.recovery-controls.svelte-1e1mff9.svelte-1e1mff9{display:flex;flex-direction:column;gap:1em}.kind-selector.svelte-1e1mff9.svelte-1e1mff9,.custom-kind-input.svelte-1e1mff9.svelte-1e1mff9{display:flex;flex-direction:column;gap:0.5em}.kind-selector.svelte-1e1mff9 label.svelte-1e1mff9,.custom-kind-input.svelte-1e1mff9 label.svelte-1e1mff9{font-weight:600;color:var(--text-color)}.kind-selector.svelte-1e1mff9 select.svelte-1e1mff9,.custom-kind-input.svelte-1e1mff9 input.svelte-1e1mff9{padding:0.5em;border:1px solid var(--border-color);border-radius:4px;background:var(--input-bg);color:var(--input-text-color);font-size:0.9em}.recovery-results.svelte-1e1mff9.svelte-1e1mff9{margin-top:1.5rem}.loading.svelte-1e1mff9.svelte-1e1mff9,.no-events.svelte-1e1mff9.svelte-1e1mff9{text-align:center;padding:2em;color:var(--text-color);opacity:0.7}.events-list.svelte-1e1mff9.svelte-1e1mff9{display:flex;flex-direction:column;gap:1em}.event-item.svelte-1e1mff9.svelte-1e1mff9{background:var(--card-bg);border:1px solid var(--border-color);border-radius:8px;padding:1em}.event-item.old-version.svelte-1e1mff9.svelte-1e1mff9{border-color:var(--warning);background:var(--warning-bg)}.event-header.svelte-1e1mff9.svelte-1e1mff9{display:flex;justify-content:space-between;align-items:center;margin-bottom:1em;flex-wrap:wrap;gap:1em}.event-header-left.svelte-1e1mff9.svelte-1e1mff9{display:flex;flex-direction:column;gap:0.25em}.event-kind.svelte-1e1mff9.svelte-1e1mff9{font-weight:600;color:var(--primary)}.event-timestamp.svelte-1e1mff9.svelte-1e1mff9{font-size:0.9em;color:var(--text-color);opacity:0.7}.event-header-actions.svelte-1e1mff9.svelte-1e1mff9{display:flex;gap:0.5em;flex-wrap:wrap}.repost-all-button.svelte-1e1mff9.svelte-1e1mff9,.repost-button.svelte-1e1mff9.svelte-1e1mff9,.copy-json-btn.svelte-1e1mff9.svelte-1e1mff9{background:var(--accent-color);color:var(--accent-hover-color);border:none;padding:0.5em;border-radius:0.5em;cursor:pointer;font-size:0.8em;transition:background-color 0.2s}.repost-all-button.svelte-1e1mff9.svelte-1e1mff9:hover,.repost-button.svelte-1e1mff9.svelte-1e1mff9:hover,.copy-json-btn.svelte-1e1mff9.svelte-1e1mff9:hover{background:var(--accent-hover-color)}.event-content.svelte-1e1mff9.svelte-1e1mff9{margin-top:1em}.event-json.svelte-1e1mff9.svelte-1e1mff9{background:var(--code-bg);padding:1em;border:0;font-size:0.8em;line-height:1.4;overflow-x:auto;margin:0;color:var(--code-text)}.load-more.svelte-1e1mff9.svelte-1e1mff9{width:100%;padding:12px;background:var(--primary);color:var(--text-color);border:none;border-radius:4px;cursor:pointer;font-size:1em;margin-top:20px;transition:background 0.2s ease}.load-more.svelte-1e1mff9.svelte-1e1mff9:hover:not(:disabled){background:var(--accent-hover-color)}.load-more.svelte-1e1mff9.svelte-1e1mff9:disabled{opacity:0.6;cursor:not-allowed}
+.sprocket-view.svelte-fiaj1r.svelte-fiaj1r{width:100%;max-width:1200px;margin:0;padding:20px;background:var(--header-bg);color:var(--text-color);border-radius:8px}.sprocket-view.svelte-fiaj1r h2.svelte-fiaj1r{margin:0 0 1.5rem 0;color:var(--text-color);font-size:1.8rem;font-weight:600}.sprocket-section.svelte-fiaj1r.svelte-fiaj1r{background-color:var(--card-bg);border-radius:8px;padding:1em;margin-bottom:1.5rem;border:1px solid var(--border-color);width:32em}.sprocket-header.svelte-fiaj1r.svelte-fiaj1r{display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem}.sprocket-header.svelte-fiaj1r h3.svelte-fiaj1r{margin:0;color:var(--text-color);font-size:1.2rem;font-weight:600}.sprocket-controls.svelte-fiaj1r.svelte-fiaj1r{display:flex;gap:0.5rem}.sprocket-btn.svelte-fiaj1r.svelte-fiaj1r{background:var(--primary);color:var(--text-color);border:none;padding:0.5em 1em;border-radius:4px;cursor:pointer;font-size:0.9em;transition:background-color 0.2s;display:flex;align-items:center;gap:0.25em}.sprocket-btn.svelte-fiaj1r.svelte-fiaj1r:hover:not(:disabled){background:var(--accent-hover-color)}.sprocket-btn.svelte-fiaj1r.svelte-fiaj1r:disabled{background:var(--secondary);cursor:not-allowed}.restart-btn.svelte-fiaj1r.svelte-fiaj1r{background:var(--warning)}.restart-btn.svelte-fiaj1r.svelte-fiaj1r:hover:not(:disabled){background:var(--warning);filter:brightness(0.9)}.delete-btn.svelte-fiaj1r.svelte-fiaj1r{background:var(--danger)}.delete-btn.svelte-fiaj1r.svelte-fiaj1r:hover:not(:disabled){background:var(--danger);filter:brightness(0.9)}.sprocket-upload-section.svelte-fiaj1r.svelte-fiaj1r{margin-bottom:1.5rem}.sprocket-upload-section.svelte-fiaj1r h4.svelte-fiaj1r{margin:0 0 0.5rem 0;color:var(--text-color);font-size:1rem;font-weight:600}.upload-controls.svelte-fiaj1r.svelte-fiaj1r{display:flex;flex-direction:column;gap:0.5rem}#sprocket-upload-file.svelte-fiaj1r.svelte-fiaj1r{padding:0.5em;border:1px solid var(--border-color);border-radius:4px;background:var(--input-bg);color:var(--input-text-color)}.upload-btn.svelte-fiaj1r.svelte-fiaj1r{background:var(--success);align-self:flex-start}.upload-btn.svelte-fiaj1r.svelte-fiaj1r:hover:not(:disabled){background:var(--success);filter:brightness(0.9)}.sprocket-status.svelte-fiaj1r.svelte-fiaj1r{display:flex;flex-direction:column;gap:0.5rem;margin-bottom:1.5rem;padding:1rem;background:var(--bg-color);border-radius:4px;border:1px solid var(--border-color)}.status-item.svelte-fiaj1r.svelte-fiaj1r{display:flex;justify-content:space-between;align-items:center}.status-label.svelte-fiaj1r.svelte-fiaj1r{font-weight:600;color:var(--text-color)}.status-value.svelte-fiaj1r.svelte-fiaj1r{color:var(--text-color)}.status-value.running.svelte-fiaj1r.svelte-fiaj1r{color:var(--success)}.script-editor-container.svelte-fiaj1r.svelte-fiaj1r{margin-bottom:1.5rem}.script-editor.svelte-fiaj1r.svelte-fiaj1r{width:100%;height:300px;padding:1em;border:1px solid var(--border-color);border-radius:4px;background:var(--input-bg);color:var(--input-text-color);font-family:monospace;font-size:0.9em;line-height:1.4;resize:vertical}.script-editor.svelte-fiaj1r.svelte-fiaj1r:disabled{opacity:0.6;cursor:not-allowed}.script-actions.svelte-fiaj1r.svelte-fiaj1r{display:flex;gap:0.5rem;margin-bottom:1rem}.save-btn.svelte-fiaj1r.svelte-fiaj1r{background:var(--success)}.save-btn.svelte-fiaj1r.svelte-fiaj1r:hover:not(:disabled){background:var(--success);filter:brightness(0.9)}.load-btn.svelte-fiaj1r.svelte-fiaj1r{background:var(--info)}.load-btn.svelte-fiaj1r.svelte-fiaj1r:hover:not(:disabled){background:var(--info);filter:brightness(0.9)}.sprocket-message.svelte-fiaj1r.svelte-fiaj1r{padding:1rem;border-radius:4px;margin-top:1rem;background:var(--success-bg);color:var(--success-text);border:1px solid var(--success)}.sprocket-message.error.svelte-fiaj1r.svelte-fiaj1r{background:var(--danger-bg);color:var(--danger-text);border:1px solid var(--danger)}.versions-list.svelte-fiaj1r.svelte-fiaj1r{display:flex;flex-direction:column;gap:0.5rem;margin-bottom:1rem}.version-item.svelte-fiaj1r.svelte-fiaj1r{display:flex;justify-content:space-between;align-items:center;padding:0.75rem;background:var(--bg-color);border:1px solid var(--border-color);border-radius:4px}.version-item.current.svelte-fiaj1r.svelte-fiaj1r{border-color:var(--primary);background:var(--primary-bg)}.version-info.svelte-fiaj1r.svelte-fiaj1r{flex:1}.version-name.svelte-fiaj1r.svelte-fiaj1r{font-weight:600;color:var(--text-color);margin-bottom:0.25rem}.version-date.svelte-fiaj1r.svelte-fiaj1r{font-size:0.8em;color:var(--text-color);opacity:0.7;display:flex;align-items:center;gap:0.5rem}.current-badge.svelte-fiaj1r.svelte-fiaj1r{background:var(--primary);color:var(--text-color);padding:0.1em 0.4em;border-radius:0.25rem;font-size:0.7em;font-weight:600}.version-actions.svelte-fiaj1r.svelte-fiaj1r{display:flex;gap:0.25rem}.version-btn.svelte-fiaj1r.svelte-fiaj1r{background:var(--primary);color:var(--text-color);border:none;padding:0.25em 0.5em;border-radius:0.25rem;cursor:pointer;font-size:0.8em;transition:background-color 0.2s}.version-btn.svelte-fiaj1r.svelte-fiaj1r:hover:not(:disabled){background:var(--accent-hover-color)}.version-btn.svelte-fiaj1r.svelte-fiaj1r:disabled{background:var(--secondary);cursor:not-allowed}.version-btn.delete-btn.svelte-fiaj1r.svelte-fiaj1r{background:var(--danger)}.version-btn.delete-btn.svelte-fiaj1r.svelte-fiaj1r:hover:not(:disabled){background:var(--danger);filter:brightness(0.9)}.refresh-btn.svelte-fiaj1r.svelte-fiaj1r{background:var(--info)}.refresh-btn.svelte-fiaj1r.svelte-fiaj1r:hover:not(:disabled){background:var(--info);filter:brightness(0.9)}.permission-denied.svelte-fiaj1r.svelte-fiaj1r,.login-prompt.svelte-fiaj1r.svelte-fiaj1r{text-align:center;padding:2em;background-color:var(--card-bg);border-radius:8px;border:1px solid var(--border-color);color:var(--text-color)}.permission-denied.svelte-fiaj1r p.svelte-fiaj1r,.login-prompt.svelte-fiaj1r p.svelte-fiaj1r{margin:0 0 1rem 0;line-height:1.4}.permission-denied.svelte-fiaj1r code.svelte-fiaj1r{background:var(--code-bg);padding:0.2em 0.4em;border-radius:0.25rem;font-family:monospace;font-size:0.9em}.login-btn.svelte-fiaj1r.svelte-fiaj1r{background:var(--primary);color:var(--text-color);border:none;padding:0.75em 1.5em;border-radius:4px;cursor:pointer;font-weight:bold;font-size:0.9em;transition:background-color 0.2s}.login-btn.svelte-fiaj1r.svelte-fiaj1r:hover{background:var(--accent-hover-color)}
+.policy-view.svelte-gkxvxc.svelte-gkxvxc{width:100%;max-width:1200px;margin:0;padding:20px;background:var(--header-bg);color:var(--text-color);border-radius:8px;box-sizing:border-box}.policy-view.svelte-gkxvxc h2.svelte-gkxvxc{margin:0 0 1.5rem 0;color:var(--text-color);font-size:1.8rem;font-weight:600}.policy-section.svelte-gkxvxc.svelte-gkxvxc{background-color:var(--card-bg);border-radius:8px;padding:1.5em;margin-bottom:1.5rem;border:1px solid var(--border-color)}.policy-header.svelte-gkxvxc.svelte-gkxvxc{display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem}.policy-header.svelte-gkxvxc h3.svelte-gkxvxc{margin:0;color:var(--text-color);font-size:1.2rem;font-weight:600}.policy-status.svelte-gkxvxc.svelte-gkxvxc{display:flex;gap:0.5rem}.status-badge.svelte-gkxvxc.svelte-gkxvxc{padding:0.25em 0.75em;border-radius:1rem;font-size:0.8em;font-weight:600;background:var(--danger);color:white}.status-badge.enabled.svelte-gkxvxc.svelte-gkxvxc{background:var(--success)}.admin-badge.svelte-gkxvxc.svelte-gkxvxc{padding:0.25em 0.75em;border-radius:1rem;font-size:0.8em;font-weight:600;background:var(--primary);color:white}.policy-info.svelte-gkxvxc.svelte-gkxvxc{margin-bottom:1rem;padding:1rem;background:var(--bg-color);border-radius:4px;border:1px solid var(--border-color)}.policy-info.svelte-gkxvxc p.svelte-gkxvxc{margin:0 0 0.5rem 0;line-height:1.5}.policy-info.svelte-gkxvxc p.svelte-gkxvxc:last-child{margin-bottom:0}.info-note.svelte-gkxvxc.svelte-gkxvxc{font-size:0.9em;opacity:0.8}.editor-container.svelte-gkxvxc.svelte-gkxvxc{margin-bottom:1rem}.policy-editor.svelte-gkxvxc.svelte-gkxvxc{width:100%;height:400px;padding:1em;border:1px solid var(--border-color);border-radius:4px;background:var(--input-bg);color:var(--input-text-color);font-family:'Monaco', 'Menlo', 'Ubuntu Mono', monospace;font-size:0.85em;line-height:1.5;resize:vertical;tab-size:2}.policy-editor.svelte-gkxvxc.svelte-gkxvxc:disabled{opacity:0.6;cursor:not-allowed}.validation-errors.svelte-gkxvxc.svelte-gkxvxc{margin-bottom:1rem;padding:1rem;background:var(--danger-bg, rgba(220, 53, 69, 0.1));border:1px solid var(--danger);border-radius:4px}.validation-errors.svelte-gkxvxc h4.svelte-gkxvxc{margin:0 0 0.5rem 0;color:var(--danger);font-size:1rem}.validation-errors.svelte-gkxvxc ul.svelte-gkxvxc{margin:0;padding-left:1.5rem}.validation-errors.svelte-gkxvxc li.svelte-gkxvxc{color:var(--danger);margin-bottom:0.25rem}.policy-actions.svelte-gkxvxc.svelte-gkxvxc{display:flex;gap:0.5rem;flex-wrap:wrap}.policy-btn.svelte-gkxvxc.svelte-gkxvxc{background:var(--primary);color:white;border:none;padding:0.5em 1em;border-radius:4px;cursor:pointer;font-size:0.9em;transition:background-color 0.2s, filter 0.2s;display:flex;align-items:center;gap:0.25em}.policy-btn.svelte-gkxvxc.svelte-gkxvxc:hover:not(:disabled){filter:brightness(1.1)}.policy-btn.svelte-gkxvxc.svelte-gkxvxc:disabled{background:var(--secondary);cursor:not-allowed}.load-btn.svelte-gkxvxc.svelte-gkxvxc{background:var(--info)}.format-btn.svelte-gkxvxc.svelte-gkxvxc{background:var(--secondary)}.validate-btn.svelte-gkxvxc.svelte-gkxvxc{background:var(--warning)}.save-btn.svelte-gkxvxc.svelte-gkxvxc{background:var(--success)}.policy-message.svelte-gkxvxc.svelte-gkxvxc{padding:1rem;border-radius:4px;margin-top:1rem;background:var(--info-bg, rgba(23, 162, 184, 0.1));color:var(--info-text, var(--text-color));border:1px solid var(--info)}.policy-message.error.svelte-gkxvxc.svelte-gkxvxc{background:var(--danger-bg, rgba(220, 53, 69, 0.1));color:var(--danger-text, var(--danger));border:1px solid var(--danger)}.policy-message.success.svelte-gkxvxc.svelte-gkxvxc{background:var(--success-bg, rgba(40, 167, 69, 0.1));color:var(--success-text, var(--success));border:1px solid var(--success)}.reference-content.svelte-gkxvxc h4.svelte-gkxvxc{margin:1rem 0 0.5rem 0;color:var(--text-color);font-size:1rem}.reference-content.svelte-gkxvxc h4.svelte-gkxvxc:first-child{margin-top:0}.field-list.svelte-gkxvxc.svelte-gkxvxc{margin:0 0 1rem 0;padding-left:1.5rem}.field-list.svelte-gkxvxc li.svelte-gkxvxc{margin-bottom:0.25rem;line-height:1.5}.field-list.svelte-gkxvxc code.svelte-gkxvxc{background:var(--code-bg, rgba(0, 0, 0, 0.1));padding:0.1em 0.4em;border-radius:3px;font-family:'Monaco', 'Menlo', 'Ubuntu Mono', monospace;font-size:0.9em}.example-json.svelte-gkxvxc.svelte-gkxvxc{background:var(--input-bg);color:var(--input-text-color);padding:1rem;border-radius:4px;border:1px solid var(--border-color);font-family:'Monaco', 'Menlo', 'Ubuntu Mono', monospace;font-size:0.8em;line-height:1.4;overflow-x:auto;white-space:pre;margin:0}.permission-denied.svelte-gkxvxc.svelte-gkxvxc,.login-prompt.svelte-gkxvxc.svelte-gkxvxc{text-align:center;padding:2em;background-color:var(--card-bg);border-radius:8px;border:1px solid var(--border-color);color:var(--text-color)}.permission-denied.svelte-gkxvxc p.svelte-gkxvxc,.login-prompt.svelte-gkxvxc p.svelte-gkxvxc{margin:0 0 1rem 0;line-height:1.4}.permission-denied.svelte-gkxvxc code.svelte-gkxvxc{background:var(--code-bg, rgba(0, 0, 0, 0.1));padding:0.2em 0.4em;border-radius:0.25rem;font-family:monospace;font-size:0.9em}.login-btn.svelte-gkxvxc.svelte-gkxvxc{background:var(--primary);color:white;border:none;padding:0.75em 1.5em;border-radius:4px;cursor:pointer;font-weight:bold;font-size:0.9em;transition:background-color 0.2s}.login-btn.svelte-gkxvxc.svelte-gkxvxc:hover{filter:brightness(1.1)}.admin-list.svelte-gkxvxc.svelte-gkxvxc{margin-bottom:1rem}.admin-item.svelte-gkxvxc.svelte-gkxvxc{display:flex;justify-content:space-between;align-items:center;padding:0.5em 0.75em;background:var(--bg-color);border:1px solid var(--border-color);border-radius:4px;margin-bottom:0.5rem}.admin-pubkey.svelte-gkxvxc.svelte-gkxvxc{font-family:'Monaco', 'Menlo', 'Ubuntu Mono', monospace;font-size:0.85em;color:var(--text-color)}.remove-btn.svelte-gkxvxc.svelte-gkxvxc{background:var(--danger);color:white;border:none;width:24px;height:24px;border-radius:50%;cursor:pointer;font-size:0.8em;display:flex;align-items:center;justify-content:center;transition:filter 0.2s}.remove-btn.svelte-gkxvxc.svelte-gkxvxc:hover:not(:disabled){filter:brightness(0.9)}.remove-btn.svelte-gkxvxc.svelte-gkxvxc:disabled{opacity:0.5;cursor:not-allowed}.add-admin.svelte-gkxvxc.svelte-gkxvxc{display:flex;gap:0.5rem}.add-admin.svelte-gkxvxc input.svelte-gkxvxc{flex:1;padding:0.5em 0.75em;border:1px solid var(--border-color);border-radius:4px;background:var(--input-bg);color:var(--input-text-color);font-family:'Monaco', 'Menlo', 'Ubuntu Mono', monospace;font-size:0.85em}.add-btn.svelte-gkxvxc.svelte-gkxvxc{background:var(--success);white-space:nowrap}.no-items.svelte-gkxvxc.svelte-gkxvxc{color:var(--text-color);opacity:0.6;font-style:italic;padding:1rem;text-align:center}.follows-header.svelte-gkxvxc.svelte-gkxvxc{display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem}.follows-count.svelte-gkxvxc.svelte-gkxvxc{font-weight:600;color:var(--text-color)}.refresh-btn.svelte-gkxvxc.svelte-gkxvxc{background:var(--info)}.follows-list.svelte-gkxvxc.svelte-gkxvxc{max-height:300px;overflow-y:auto;border:1px solid var(--border-color);border-radius:4px;background:var(--bg-color)}.follows-grid.svelte-gkxvxc.svelte-gkxvxc{display:grid;grid-template-columns:repeat(auto-fill, minmax(200px, 1fr));gap:0.5rem;padding:0.75rem}.follow-item.svelte-gkxvxc.svelte-gkxvxc{padding:0.4em 0.6em;background:var(--card-bg);border:1px solid var(--border-color);border-radius:4px;font-family:'Monaco', 'Menlo', 'Ubuntu Mono', monospace;font-size:0.75em;color:var(--text-color);text-overflow:ellipsis;overflow:hidden;white-space:nowrap}
+.blossom-view.svelte-bz95vx.svelte-bz95vx{padding:1em;max-width:900px}.header-section.svelte-bz95vx.svelte-bz95vx{display:flex;justify-content:space-between;align-items:center;margin-bottom:1em}.header-section.svelte-bz95vx h3.svelte-bz95vx{margin:0;color:var(--text-color);flex:1}.header-buttons.svelte-bz95vx.svelte-bz95vx{display:flex;align-items:center;gap:0.5em}.back-btn.svelte-bz95vx.svelte-bz95vx{background:transparent;border:1px solid var(--border-color);color:var(--text-color);padding:0.5em 1em;border-radius:4px;cursor:pointer;font-size:0.9em;margin-right:0.5em}.back-btn.svelte-bz95vx.svelte-bz95vx:hover{background-color:var(--sidebar-bg)}.admin-btn.svelte-bz95vx.svelte-bz95vx{background-color:var(--primary);color:var(--text-color);border:none;padding:0.5em 1em;border-radius:4px;cursor:pointer;font-size:0.9em}.admin-btn.svelte-bz95vx.svelte-bz95vx:hover:not(:disabled){background-color:var(--accent-hover-color)}.admin-btn.svelte-bz95vx.svelte-bz95vx:disabled{opacity:0.6;cursor:not-allowed}.user-header.svelte-bz95vx.svelte-bz95vx{display:flex;align-items:center;gap:0.5em}.header-avatar.svelte-bz95vx.svelte-bz95vx{width:28px;height:28px;border-radius:50%;object-fit:cover}.refresh-btn.svelte-bz95vx.svelte-bz95vx{background-color:var(--primary);color:var(--text-color);border:none;padding:0.5em 1em;border-radius:4px;cursor:pointer;font-size:0.9em}.refresh-btn.svelte-bz95vx.svelte-bz95vx:hover:not(:disabled){background-color:var(--accent-hover-color)}.refresh-btn.svelte-bz95vx.svelte-bz95vx:disabled{opacity:0.6;cursor:not-allowed}.upload-section.svelte-bz95vx.svelte-bz95vx{display:flex;align-items:center;gap:0.75em;padding:0.75em 1em;background-color:var(--card-bg);border-radius:6px;margin-bottom:1em;flex-wrap:wrap}.file-input-hidden.svelte-bz95vx.svelte-bz95vx{display:none}.select-btn.svelte-bz95vx.svelte-bz95vx{background-color:var(--primary);color:var(--text-color);border:none;padding:0.5em 1em;border-radius:4px;cursor:pointer;font-size:0.9em}.select-btn.svelte-bz95vx.svelte-bz95vx:hover:not(:disabled){background-color:var(--accent-hover-color)}.select-btn.svelte-bz95vx.svelte-bz95vx:disabled{opacity:0.6;cursor:not-allowed}.selected-count.svelte-bz95vx.svelte-bz95vx{color:var(--text-color);font-size:0.9em}.upload-btn.svelte-bz95vx.svelte-bz95vx{background-color:var(--success, #28a745);color:white;border:none;padding:0.5em 1em;border-radius:4px;cursor:pointer;font-size:0.9em;font-weight:bold}.upload-btn.svelte-bz95vx.svelte-bz95vx:hover:not(:disabled){opacity:0.9}.upload-btn.svelte-bz95vx.svelte-bz95vx:disabled{opacity:0.7;cursor:not-allowed}.error-message.svelte-bz95vx.svelte-bz95vx{background-color:var(--warning);color:var(--text-color);padding:0.75em 1em;border-radius:4px;margin-bottom:1em}.loading.svelte-bz95vx.svelte-bz95vx,.empty-state.svelte-bz95vx.svelte-bz95vx{text-align:center;padding:2em;color:var(--text-color);opacity:0.7}.blob-list.svelte-bz95vx.svelte-bz95vx{display:flex;flex-direction:column;gap:0.5em}.blob-item.svelte-bz95vx.svelte-bz95vx{display:flex;align-items:center;gap:1em;padding:0.75em 1em;background-color:var(--card-bg);border-radius:6px;cursor:pointer;transition:background-color 0.2s}.blob-item.svelte-bz95vx.svelte-bz95vx:hover{background-color:var(--sidebar-bg)}.blob-icon.svelte-bz95vx.svelte-bz95vx{font-size:1.5em;width:2em;text-align:center}.blob-info.svelte-bz95vx.svelte-bz95vx{flex:1;min-width:0}.blob-hash.svelte-bz95vx.svelte-bz95vx{font-family:monospace;font-size:0.9em;color:var(--text-color)}.blob-meta.svelte-bz95vx.svelte-bz95vx{display:flex;gap:1em;font-size:0.8em;color:var(--text-color);opacity:0.7;margin-top:0.25em}.blob-date.svelte-bz95vx.svelte-bz95vx{font-size:0.85em;color:var(--text-color);opacity:0.6;white-space:nowrap}.delete-btn.svelte-bz95vx.svelte-bz95vx{background:transparent;border:1px solid var(--warning);color:var(--warning);width:1.75em;height:1.75em;border-radius:4px;cursor:pointer;font-size:0.85em;display:flex;align-items:center;justify-content:center}.delete-btn.svelte-bz95vx.svelte-bz95vx:hover{background-color:var(--warning);color:var(--text-color)}.admin-users-list.svelte-bz95vx.svelte-bz95vx{display:flex;flex-direction:column;gap:0.5em}.user-stat-item.svelte-bz95vx.svelte-bz95vx{display:flex;align-items:center;gap:1em;padding:0.75em 1em;background-color:var(--card-bg);border-radius:6px;cursor:pointer;transition:background-color 0.2s}.user-stat-item.svelte-bz95vx.svelte-bz95vx:hover{background-color:var(--sidebar-bg)}.user-avatar-container.svelte-bz95vx.svelte-bz95vx{flex-shrink:0}.user-avatar.svelte-bz95vx.svelte-bz95vx{width:40px;height:40px;border-radius:50%;object-fit:cover}.user-avatar-placeholder.svelte-bz95vx.svelte-bz95vx{width:40px;height:40px;border-radius:50%;background-color:var(--border-color)}.user-info.svelte-bz95vx.svelte-bz95vx{flex:1;min-width:0}.user-name.svelte-bz95vx.svelte-bz95vx{font-weight:500;color:var(--text-color)}.user-npub.svelte-bz95vx.svelte-bz95vx{font-family:monospace;font-size:0.8em;color:var(--text-color);opacity:0.6;overflow:hidden;text-overflow:ellipsis}.user-stats.svelte-bz95vx.svelte-bz95vx{display:flex;flex-direction:column;align-items:flex-end;gap:0.25em}.user-stats.svelte-bz95vx .blob-count.svelte-bz95vx,.user-stats.svelte-bz95vx .total-size.svelte-bz95vx{font-size:0.85em;color:var(--text-color);opacity:0.7}.login-prompt.svelte-bz95vx.svelte-bz95vx{text-align:center;padding:2em;background-color:var(--card-bg);border-radius:8px;border:1px solid var(--border-color);max-width:32em;margin:1em}.login-prompt.svelte-bz95vx p.svelte-bz95vx{margin:0 0 1.5rem 0;color:var(--text-color);font-size:1.1rem}.login-btn.svelte-bz95vx.svelte-bz95vx{background-color:var(--primary);color:var(--text-color);border:none;padding:0.75em 1.5em;border-radius:4px;cursor:pointer;font-weight:bold;font-size:0.9em}.login-btn.svelte-bz95vx.svelte-bz95vx:hover{background-color:var(--accent-hover-color)}.modal-overlay.svelte-bz95vx.svelte-bz95vx{position:fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(0, 0, 0, 0.8);display:flex;align-items:center;justify-content:center;z-index:1000}.modal-content.svelte-bz95vx.svelte-bz95vx{background-color:var(--bg-color);border-radius:8px;max-width:90vw;max-height:90vh;display:flex;flex-direction:column;overflow:hidden}.modal-header.svelte-bz95vx.svelte-bz95vx{display:flex;justify-content:space-between;align-items:center;padding:0.75em 1em;border-bottom:1px solid var(--border-color);background-color:var(--card-bg)}.modal-title.svelte-bz95vx.svelte-bz95vx{display:flex;align-items:center;gap:1em}.modal-hash.svelte-bz95vx.svelte-bz95vx{font-family:monospace;color:var(--text-color)}.modal-type.svelte-bz95vx.svelte-bz95vx{font-size:0.85em;color:var(--text-color);opacity:0.7}.modal-controls.svelte-bz95vx.svelte-bz95vx{display:flex;align-items:center;gap:0.5em}.zoom-btn.svelte-bz95vx.svelte-bz95vx{background-color:var(--primary);color:var(--text-color);border:none;width:2em;height:2em;border-radius:4px;cursor:pointer;font-size:1em;font-weight:bold}.zoom-btn.svelte-bz95vx.svelte-bz95vx:hover:not(:disabled){background-color:var(--accent-hover-color)}.zoom-btn.svelte-bz95vx.svelte-bz95vx:disabled{opacity:0.5;cursor:not-allowed}.zoom-level.svelte-bz95vx.svelte-bz95vx{font-size:0.85em;color:var(--text-color);min-width:3em;text-align:center}.close-btn.svelte-bz95vx.svelte-bz95vx{background:transparent;border:1px solid var(--border-color);color:var(--text-color);width:2em;height:2em;border-radius:4px;cursor:pointer;font-size:1em;margin-left:0.5em}.close-btn.svelte-bz95vx.svelte-bz95vx:hover{background-color:var(--warning);border-color:var(--warning)}.modal-body.svelte-bz95vx.svelte-bz95vx{flex:1;overflow:auto;display:flex;align-items:center;justify-content:center;padding:1em;min-height:200px}.media-container.svelte-bz95vx.svelte-bz95vx{transition:transform 0.2s ease;transform-origin:center center}.media-container.svelte-bz95vx img.svelte-bz95vx{max-width:80vw;max-height:70vh;object-fit:contain}.media-container.svelte-bz95vx video.svelte-bz95vx{max-width:80vw;max-height:70vh}.media-container.audio.svelte-bz95vx.svelte-bz95vx{width:100%;padding:2em}.media-container.svelte-bz95vx audio.svelte-bz95vx{width:100%}.file-preview.svelte-bz95vx.svelte-bz95vx{text-align:center;padding:2em;color:var(--text-color)}.file-icon.svelte-bz95vx.svelte-bz95vx{font-size:4em;margin-bottom:0.5em}.download-link.svelte-bz95vx.svelte-bz95vx{display:inline-block;margin-top:1em;padding:0.75em 1.5em;background-color:var(--primary);color:var(--text-color);text-decoration:none;border-radius:4px}.download-link.svelte-bz95vx.svelte-bz95vx:hover{background-color:var(--accent-hover-color)}.modal-footer.svelte-bz95vx.svelte-bz95vx{display:flex;flex-direction:column;gap:0.5em;padding:0.75em 1em;border-top:1px solid var(--border-color);background-color:var(--card-bg)}.blob-details.svelte-bz95vx.svelte-bz95vx{display:flex;gap:1.5em;font-size:0.85em;color:var(--text-color);opacity:0.7}.blob-url-section.svelte-bz95vx.svelte-bz95vx{display:flex;gap:0.5em;width:100%}.blob-url-input.svelte-bz95vx.svelte-bz95vx{flex:1;padding:0.4em 0.6em;font-family:monospace;font-size:0.85em;background-color:var(--bg-color);color:var(--text-color);border:1px solid var(--border-color);border-radius:4px;cursor:text}.blob-url-input.svelte-bz95vx.svelte-bz95vx:focus{outline:none;border-color:var(--primary)}.copy-btn.svelte-bz95vx.svelte-bz95vx{padding:0.4em 0.8em;background-color:var(--primary);color:var(--text-color);border:none;border-radius:4px;cursor:pointer;font-size:0.85em}.copy-btn.svelte-bz95vx.svelte-bz95vx:hover{background-color:var(--accent-hover-color)}.modal-actions.svelte-bz95vx.svelte-bz95vx{display:flex;gap:0.5em}.action-btn.svelte-bz95vx.svelte-bz95vx{padding:0.5em 1em;background-color:var(--primary);color:var(--text-color);border:none;border-radius:4px;cursor:pointer;text-decoration:none;font-size:0.9em}.action-btn.svelte-bz95vx.svelte-bz95vx:hover{background-color:var(--accent-hover-color)}.action-btn.danger.svelte-bz95vx.svelte-bz95vx{background-color:transparent;border:1px solid var(--warning);color:var(--warning)}.action-btn.danger.svelte-bz95vx.svelte-bz95vx:hover{background-color:var(--warning);color:var(--text-color)}@media(max-width: 600px){.blob-item.svelte-bz95vx.svelte-bz95vx{flex-wrap:wrap}.blob-date.svelte-bz95vx.svelte-bz95vx{width:100%;margin-top:0.5em;padding-left:3em}.modal-footer.svelte-bz95vx.svelte-bz95vx{flex-direction:column;gap:0.75em}.blob-details.svelte-bz95vx.svelte-bz95vx{flex-direction:column;gap:0.25em}}
+.search-results-view.svelte-porghq.svelte-porghq{width:100%;height:100%;display:flex;flex-direction:column}.search-results-header.svelte-porghq.svelte-porghq{display:flex;justify-content:space-between;align-items:center;padding:1em;border-bottom:1px solid var(--border-color);background:var(--header-bg)}.search-results-header.svelte-porghq h2.svelte-porghq{margin:0;color:var(--text-color);font-size:1.2rem;font-weight:600}.refresh-btn.svelte-porghq.svelte-porghq{background:var(--primary);color:var(--text-color);border:none;padding:0.5em 1em;border-radius:4px;cursor:pointer;font-size:0.9em;transition:background-color 0.2s}.refresh-btn.svelte-porghq.svelte-porghq:hover:not(:disabled){background:var(--accent-hover-color)}.refresh-btn.svelte-porghq.svelte-porghq:disabled{background:var(--secondary);cursor:not-allowed}.search-results-content.svelte-porghq.svelte-porghq{flex:1;overflow-y:auto;padding:1em}.search-result-item.svelte-porghq.svelte-porghq{border:1px solid var(--border-color);border-radius:8px;margin-bottom:0.5em;background:var(--card-bg);transition:all 0.2s ease}.search-result-item.svelte-porghq.svelte-porghq:hover{border-color:var(--primary);box-shadow:0 2px 8px rgba(0, 0, 0, 0.1)}.search-result-item.expanded.svelte-porghq.svelte-porghq{border-color:var(--primary);box-shadow:0 4px 12px rgba(0, 0, 0, 0.15)}.search-result-row.svelte-porghq.svelte-porghq{display:flex;align-items:center;padding:1em;cursor:pointer;gap:1em}.search-result-avatar.svelte-porghq.svelte-porghq{flex-shrink:0}.avatar-placeholder.svelte-porghq.svelte-porghq{width:40px;height:40px;border-radius:50%;background:var(--bg-color);display:flex;align-items:center;justify-content:center;font-size:1.2em;border:1px solid var(--border-color)}.search-result-info.svelte-porghq.svelte-porghq{flex-shrink:0;min-width:120px}.search-result-author.svelte-porghq.svelte-porghq{font-weight:600;color:var(--text-color);font-size:0.9em;font-family:monospace}.search-result-kind.svelte-porghq.svelte-porghq{display:flex;align-items:center;gap:0.5em;margin-top:0.25em}.kind-number.svelte-porghq.svelte-porghq{background:var(--primary);color:var(--text-color);padding:0.1em 0.4em;border-radius:0.25rem;font-size:0.7em;font-weight:600;font-family:monospace}.kind-name.svelte-porghq.svelte-porghq{font-size:0.8em;color:var(--text-color);opacity:0.8}.search-result-content.svelte-porghq.svelte-porghq{flex:1;min-width:0}.event-timestamp.svelte-porghq.svelte-porghq{font-size:0.8em;color:var(--text-color);opacity:0.6;margin-bottom:0.5em}.event-content-single-line.svelte-porghq.svelte-porghq{color:var(--text-color);line-height:1.4;word-wrap:break-word}.delete-btn.svelte-porghq.svelte-porghq{background:var(--danger);color:var(--text-color);border:none;padding:0.5em;border-radius:4px;cursor:pointer;font-size:0.9em;flex-shrink:0;transition:background-color 0.2s}.delete-btn.svelte-porghq.svelte-porghq:hover{background:var(--danger);filter:brightness(0.9)}.search-result-details.svelte-porghq.svelte-porghq{border-top:1px solid var(--border-color);padding:1em;background:var(--bg-color)}.json-container.svelte-porghq.svelte-porghq{position:relative}.event-json.svelte-porghq.svelte-porghq{background:var(--code-bg);padding:1em;border:0;font-size:0.8em;line-height:1.4;overflow-x:auto;margin:0;color:var(--code-text)}.copy-json-btn.svelte-porghq.svelte-porghq{position:absolute;top:0.5em;right:0.5em;background:var(--primary);color:var(--text-color);border:none;padding:0.25em 0.5em;border-radius:0.25rem;cursor:pointer;font-size:0.8em;opacity:0.8;transition:opacity 0.2s}.copy-json-btn.svelte-porghq.svelte-porghq:hover{opacity:1}.no-results.svelte-porghq.svelte-porghq{text-align:center;padding:2em;color:var(--text-color);opacity:0.7}.loading-search.svelte-porghq.svelte-porghq{text-align:center;padding:2em;color:var(--text-color)}.spinner.svelte-porghq.svelte-porghq{width:20px;height:20px;border:2px solid var(--border-color);border-top:2px solid var(--primary);border-radius:50%;animation:svelte-porghq-spin 1s linear infinite;margin:0 auto 1em}@keyframes svelte-porghq-spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}
+.filter-display.svelte-1tyqaa5.svelte-1tyqaa5{background:var(--card-bg);border:1px solid var(--border-color);border-radius:8px;margin:1em;overflow:hidden}.filter-display-header.svelte-1tyqaa5.svelte-1tyqaa5{display:flex;justify-content:space-between;align-items:center;padding:0.75em 1em;background:var(--bg-color);border-bottom:1px solid var(--border-color)}.filter-display-header.svelte-1tyqaa5 h3.svelte-1tyqaa5{margin:0;font-size:1em;font-weight:600;color:var(--text-color)}.sweep-btn.svelte-1tyqaa5.svelte-1tyqaa5{background:var(--danger);color:var(--text-color);border:none;padding:0.5em 1em;border-radius:4px;cursor:pointer;font-size:0.9em;font-weight:600;transition:all 0.2s}.sweep-btn.svelte-1tyqaa5.svelte-1tyqaa5:hover{filter:brightness(0.9);transform:translateY(-1px);box-shadow:0 2px 8px rgba(255, 0, 0, 0.3)}.filter-json-container.svelte-1tyqaa5.svelte-1tyqaa5{padding:1em;max-height:200px;overflow:auto}.filter-json.svelte-1tyqaa5.svelte-1tyqaa5{background:var(--code-bg);padding:1em;border-radius:4px;font-family:'Courier New', Courier, monospace;font-size:0.85em;line-height:1.5;color:var(--code-text);margin:0;white-space:pre-wrap;word-wrap:break-word;word-break:break-all;overflow-wrap:anywhere}.filter-json-container.svelte-1tyqaa5.svelte-1tyqaa5::-webkit-scrollbar{width:8px;height:8px}.filter-json-container.svelte-1tyqaa5.svelte-1tyqaa5::-webkit-scrollbar-track{background:var(--bg-color)}.filter-json-container.svelte-1tyqaa5.svelte-1tyqaa5::-webkit-scrollbar-thumb{background:var(--border-color);border-radius:4px}.filter-json-container.svelte-1tyqaa5.svelte-1tyqaa5::-webkit-scrollbar-thumb:hover{background:var(--primary)}
+html,body{margin:0;padding:0;overflow:hidden;height:100%;--bg-color:#ddd;--header-bg:#eee;--sidebar-bg:#eee;--card-bg:#f8f9fa;--panel-bg:#f8f9fa;--border-color:#dee2e6;--text-color:#444444;--text-muted:#6c757d;--input-border:#ccc;--input-bg:#ffffff;--input-text-color:#495057;--button-bg:#ddd;--button-hover-bg:#eee;--button-text:#444444;--button-hover-border:#adb5bd;--primary:#00bcd4;--primary-bg:rgba(0, 188, 212, 0.1);--secondary:#6c757d;--success:#28a745;--success-bg:#d4edda;--success-text:#155724;--info:#17a2b8;--warning:#ff3e00;--warning-bg:#fff3cd;--danger:#dc3545;--danger-bg:#f8d7da;--danger-text:#721c24;--error-bg:#f8d7da;--error-text:#721c24;--code-bg:#f8f9fa;--code-text:#495057;--tab-inactive-bg:#bbb;--accent-color:#007bff;--accent-hover-color:#0056b3}body.dark-theme{--bg-color:#263238;--header-bg:#1e272c;--sidebar-bg:#1e272c;--card-bg:#37474f;--panel-bg:#37474f;--border-color:#404040;--text-color:#ffffff;--text-muted:#adb5bd;--input-border:#555;--input-bg:#37474f;--input-text-color:#ffffff;--button-bg:#263238;--button-hover-bg:#1e272c;--button-text:#ffffff;--button-hover-border:#6c757d;--primary:#00bcd4;--primary-bg:rgba(0, 188, 212, 0.2);--secondary:#6c757d;--success:#28a745;--success-bg:#1e4620;--success-text:#d4edda;--info:#17a2b8;--warning:#ff3e00;--warning-bg:#4d1f00;--danger:#dc3545;--danger-bg:#4d1319;--danger-text:#f8d7da;--error-bg:#4d1319;--error-text:#f8d7da;--code-bg:#1e272c;--code-text:#ffffff;--tab-inactive-bg:#1a1a1a;--accent-color:#007bff;--accent-hover-color:#0056b3}.login-btn.svelte-u3u5mw.svelte-u3u5mw{padding:0.5em 1em;border:none;border-radius:6px;background-color:#4caf50;color:var(--text-color);cursor:pointer;font-size:1rem;font-weight:500;transition:background-color 0.2s;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;margin:0 auto;padding:0.5em 1em}.login-btn.svelte-u3u5mw.svelte-u3u5mw:hover{background-color:#45a049}.acl-mode-warning.svelte-u3u5mw.svelte-u3u5mw{padding:1em;background-color:#fff3cd;border:1px solid #ffeaa7;border-radius:8px;color:#856404;margin:20px 0}.acl-mode-warning.svelte-u3u5mw h3.svelte-u3u5mw{margin:0 0 15px 0;color:#856404}.acl-mode-warning.svelte-u3u5mw p.svelte-u3u5mw{margin:10px 0;line-height:1.5}.acl-mode-warning.svelte-u3u5mw code.svelte-u3u5mw{background-color:#f8f9fa;padding:2px 6px;border-radius:4px;font-family:monospace;color:#495057}.app-container.svelte-u3u5mw.svelte-u3u5mw{display:flex;margin-top:3em;height:calc(100vh - 3em)}.main-content.svelte-u3u5mw.svelte-u3u5mw{position:fixed;left:200px;top:3em;right:0;bottom:0;padding:0;overflow-y:auto;background-color:var(--bg-color);color:var(--text-color);display:flex;align-items:flex-start;justify-content:flex-start;flex-direction:column;display:flex}.welcome-message.svelte-u3u5mw.svelte-u3u5mw{text-align:center}.welcome-message.svelte-u3u5mw p.svelte-u3u5mw{font-size:1.2rem}@media(max-width: 640px){.main-content.svelte-u3u5mw.svelte-u3u5mw{left:160px;padding:1rem}}.logout-btn.svelte-u3u5mw.svelte-u3u5mw{padding:0.5rem 1rem;border:none;border-radius:6px;background-color:var(--warning);color:var(--text-color);cursor:pointer;font-size:1rem;font-weight:500;transition:background-color 0.2s;display:flex;align-items:center;justify-content:center;gap:0.5rem}.logout-btn.svelte-u3u5mw.svelte-u3u5mw:hover{background-color:#e53935}.logout-btn.floating.svelte-u3u5mw.svelte-u3u5mw{position:absolute;top:0.5em;right:0.5em;z-index:10;box-shadow:0 2px 8px rgba(0, 0, 0, 0.3)}.drawer-overlay.svelte-u3u5mw.svelte-u3u5mw{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0, 0, 0, 0.5);z-index:1000;display:flex;justify-content:flex-end}.settings-drawer.svelte-u3u5mw.svelte-u3u5mw{width:640px;height:100%;background:var(--bg-color);overflow-y:auto;animation:svelte-u3u5mw-slideIn 0.3s ease}@keyframes svelte-u3u5mw-slideIn{from{transform:translateX(100%)}to{transform:translateX(0)}}.drawer-header.svelte-u3u5mw.svelte-u3u5mw{display:flex;align-items:center;justify-content:space-between;background:var(--header-bg)}.drawer-header.svelte-u3u5mw h2.svelte-u3u5mw{margin:0;color:var(--text-color);font-size:1em;padding:1rem}.close-btn.svelte-u3u5mw.svelte-u3u5mw{background:none;border:none;font-size:1em;cursor:pointer;color:var(--text-color);padding:0.5em;transition:background-color 0.2s;align-items:center}.close-btn.svelte-u3u5mw.svelte-u3u5mw:hover{background:var(--button-hover-bg)}.profile-section.svelte-u3u5mw.svelte-u3u5mw{margin-bottom:2rem}.profile-hero.svelte-u3u5mw.svelte-u3u5mw{position:relative}.profile-banner.svelte-u3u5mw.svelte-u3u5mw{width:100%;height:160px;object-fit:cover;border-radius:0;display:block}.profile-avatar.svelte-u3u5mw.svelte-u3u5mw,.profile-avatar-placeholder.svelte-u3u5mw.svelte-u3u5mw{width:72px;height:72px;border-radius:50%;object-fit:cover;flex-shrink:0;box-shadow:0 2px 8px rgba(0, 0, 0, 0.25);border:2px solid var(--bg-color)}.overlap.svelte-u3u5mw.svelte-u3u5mw{position:absolute;left:12px;bottom:-36px;z-index:2;background:var(--button-hover-bg);display:flex;align-items:center;justify-content:center;font-size:1.5rem}.name-row.svelte-u3u5mw.svelte-u3u5mw{position:absolute;left:calc(12px + 72px + 12px);bottom:8px;right:12px;display:flex;align-items:baseline;gap:8px;z-index:1;background:var(--bg-color);padding:0.2em 0.5em;border-radius:0.5em;width:fit-content}.profile-username.svelte-u3u5mw.svelte-u3u5mw{margin:0;font-size:1.1rem;color:var(--text-color)}.profile-nip05-inline.svelte-u3u5mw.svelte-u3u5mw{font-size:0.85rem;color:var(--text-color);font-family:monospace;opacity:0.95}.about-card.svelte-u3u5mw.svelte-u3u5mw{background:var(--header-bg);padding:12px 12px 12px 96px;position:relative;word-break:auto-phrase}.profile-about.svelte-u3u5mw.svelte-u3u5mw{margin:0;color:var(--text-color);font-size:0.9rem;line-height:1.4}.profile-loading-section.svelte-u3u5mw.svelte-u3u5mw{padding:1rem;text-align:center;position:relative}.profile-loading-section.svelte-u3u5mw h3.svelte-u3u5mw{margin:0 0 1rem 0;color:var(--text-color);font-size:1.1rem}.profile-loading-section.svelte-u3u5mw p.svelte-u3u5mw{margin:0 0 1rem 0;color:var(--text-color);opacity:0.8}.retry-profile-btn.svelte-u3u5mw.svelte-u3u5mw{padding:0.5rem 1rem;background:var(--primary);color:var(--text-color);border:none;border-radius:4px;cursor:pointer;font-size:0.9rem;margin-bottom:1rem;transition:background-color 0.2s}.retry-profile-btn.svelte-u3u5mw.svelte-u3u5mw:hover{background:#00acc1}.user-pubkey-display.svelte-u3u5mw.svelte-u3u5mw{font-family:monospace;font-size:0.8rem;color:var(--text-color);opacity:0.7;background:var(--button-bg);padding:0.5rem;border-radius:4px;word-break:break-all}.managed-acl-view.svelte-u3u5mw.svelte-u3u5mw{padding:20px;max-width:1200px;margin:0;background:var(--header-bg);color:var(--text-color);border-radius:8px}.refresh-btn.svelte-u3u5mw.svelte-u3u5mw{padding:0.5rem 1rem;background:var(--primary);color:var(--text-color);border:none;border-radius:4px;cursor:pointer;font-size:0.875rem;font-weight:500;transition:background-color 0.2s;display:inline-flex;align-items:center;gap:0.25rem;height:2em;margin:1em}.refresh-btn.svelte-u3u5mw.svelte-u3u5mw:hover{background:#00acc1}@keyframes svelte-u3u5mw-spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.view-as-section.svelte-u3u5mw.svelte-u3u5mw{color:var(--text-color);padding:1rem;border-radius:0.5em;margin-bottom:1rem}.view-as-section.svelte-u3u5mw h3.svelte-u3u5mw{margin-top:0;margin-bottom:0.5rem;font-size:1rem;color:var(--primary)}.view-as-section.svelte-u3u5mw p.svelte-u3u5mw{margin:0.5rem 0;font-size:0.9rem;opacity:0.8}.radio-group.svelte-u3u5mw.svelte-u3u5mw{display:flex;flex-direction:column;gap:0.5rem}.radio-label.svelte-u3u5mw.svelte-u3u5mw{display:flex;align-items:center;gap:0.5rem;cursor:pointer;padding:0.25rem;border-radius:0.5em;transition:background 0.2s}.radio-label.svelte-u3u5mw.svelte-u3u5mw:hover{background:rgba(255, 255, 255, 0.1)}.radio-label.svelte-u3u5mw input.svelte-u3u5mw{margin:0}.avatar-placeholder.svelte-u3u5mw.svelte-u3u5mw{width:1.5rem;height:1.5rem;border-radius:50%;background:var(--button-bg);display:flex;align-items:center;justify-content:center;font-size:0.7rem}.kind-number.svelte-u3u5mw.svelte-u3u5mw{background:var(--primary);color:var(--text-color);padding:0.125rem 0.375rem;border-radius:0.5em;font-size:0.7rem;font-weight:500;font-family:monospace}.kind-name.svelte-u3u5mw.svelte-u3u5mw{font-size:0.75rem;color:var(--text-color);opacity:0.7;font-weight:500}.event-timestamp.svelte-u3u5mw.svelte-u3u5mw{font-size:0.75rem;color:var(--text-color);opacity:0.7;margin-bottom:0.25rem;font-weight:500}.event-content-single-line.svelte-u3u5mw.svelte-u3u5mw{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.2}.delete-btn.svelte-u3u5mw.svelte-u3u5mw{flex-shrink:0;background:none;border:none;cursor:pointer;padding:0.2rem;border-radius:0.5em;transition:background-color 0.2s;font-size:1.6rem;display:flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem}.delete-btn.svelte-u3u5mw.svelte-u3u5mw:hover{background:var(--warning);color:var(--text-color)}.json-container.svelte-u3u5mw.svelte-u3u5mw{position:relative}.copy-json-btn.svelte-u3u5mw.svelte-u3u5mw{color:var(--text-color);background:var(--accent-color);border:0;border-radius:0.5rem;padding:0.5rem;font-size:1rem;cursor:pointer;width:auto;height:auto;display:flex;align-items:center;justify-content:center}.copy-json-btn.svelte-u3u5mw.svelte-u3u5mw:hover{background:var(--accent-hover-color)}.event-json.svelte-u3u5mw.svelte-u3u5mw{background:var(--bg-color);padding:1rem;margin:0;font-family:"Courier New", monospace;font-size:0.8rem;line-height:1.4;color:var(--text-color);white-space:pre-wrap;word-break:break-word;overflow-x:auto}.no-events.svelte-u3u5mw.svelte-u3u5mw{padding:2rem;text-align:center;color:var(--text-color);opacity:0.7}.loading-spinner.svelte-u3u5mw.svelte-u3u5mw{width:2rem;height:2rem;border:3px solid var(--border-color);border-top:3px solid var(--primary);border-radius:50%;animation:svelte-u3u5mw-spin 1s linear infinite;margin:0 auto 1rem auto}@keyframes svelte-u3u5mw-spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.search-results-view.svelte-u3u5mw.svelte-u3u5mw{position:fixed;top:3em;left:200px;right:0;bottom:0;background:var(--bg-color);color:var(--text-color);display:flex;flex-direction:column;overflow:hidden}.search-results-header.svelte-u3u5mw.svelte-u3u5mw{padding:0.5rem 1rem;background:var(--header-bg);border-bottom:1px solid var(--border-color);flex-shrink:0;display:flex;justify-content:space-between;align-items:center;height:2.5em}.search-results-header.svelte-u3u5mw h2.svelte-u3u5mw{margin:0;font-size:1rem;font-weight:600;color:var(--text-color)}.search-results-content.svelte-u3u5mw.svelte-u3u5mw{flex:1;overflow-y:auto;padding:0}.search-result-item.svelte-u3u5mw.svelte-u3u5mw{border-bottom:1px solid var(--border-color);transition:background-color 0.2s}.search-result-item.svelte-u3u5mw.svelte-u3u5mw:hover{background:var(--button-hover-bg)}.search-result-item.expanded.svelte-u3u5mw.svelte-u3u5mw{background:var(--button-hover-bg)}.search-result-row.svelte-u3u5mw.svelte-u3u5mw{display:flex;align-items:center;padding:0.75rem 1rem;cursor:pointer;gap:0.75rem;min-height:3rem}.search-result-avatar.svelte-u3u5mw.svelte-u3u5mw{flex-shrink:0;width:2rem;height:2rem;display:flex;align-items:center;justify-content:center}.search-result-info.svelte-u3u5mw.svelte-u3u5mw{flex-shrink:0;width:12rem;display:flex;flex-direction:column;gap:0.25rem}.search-result-author.svelte-u3u5mw.svelte-u3u5mw{font-family:monospace;font-size:0.8rem;color:var(--text-color);opacity:0.8}.search-result-kind.svelte-u3u5mw.svelte-u3u5mw{display:flex;align-items:center;gap:0.5rem}.search-result-content.svelte-u3u5mw.svelte-u3u5mw{flex:1;color:var(--text-color);font-size:0.9rem;line-height:1.3;word-break:break-word}.search-result-content.svelte-u3u5mw .event-timestamp.svelte-u3u5mw{font-size:0.75rem;color:var(--text-color);opacity:0.7;margin-bottom:0.25rem;font-weight:500}.search-result-content.svelte-u3u5mw .event-content-single-line.svelte-u3u5mw{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.2}.search-result-details.svelte-u3u5mw.svelte-u3u5mw{border-top:1px solid var(--border-color);background:var(--header-bg);padding:1rem}.no-search-results.svelte-u3u5mw.svelte-u3u5mw{padding:2rem;text-align:center;color:var(--text-color);opacity:0.7}.no-search-results.svelte-u3u5mw p.svelte-u3u5mw{margin:0;font-size:1rem}.loading-search-results.svelte-u3u5mw.svelte-u3u5mw{padding:2rem;text-align:center;color:var(--text-color);opacity:0.7}.loading-search-results.svelte-u3u5mw p.svelte-u3u5mw{margin:0;font-size:0.9rem}.end-of-search-results.svelte-u3u5mw.svelte-u3u5mw{padding:1rem;text-align:center;color:var(--text-color);opacity:0.5;font-size:0.8rem;border-top:1px solid var(--border-color)}.end-of-search-results.svelte-u3u5mw p.svelte-u3u5mw{margin:0}@media(max-width: 1280px){.main-content.svelte-u3u5mw.svelte-u3u5mw{left:60px}.search-results-view.svelte-u3u5mw.svelte-u3u5mw{left:60px}}@media(max-width: 640px){.settings-drawer.svelte-u3u5mw.svelte-u3u5mw{width:100%}.name-row.svelte-u3u5mw.svelte-u3u5mw{left:calc(8px + 56px + 8px);bottom:6px;right:8px;gap:6px;background:var(--bg-color);padding:0.2em 0.5em;border-radius:0.5em;width:fit-content}.profile-username.svelte-u3u5mw.svelte-u3u5mw{font-size:1rem;color:var(--text-color)}.profile-nip05-inline.svelte-u3u5mw.svelte-u3u5mw{font-size:0.8rem;color:var(--text-color)}.managed-acl-view.svelte-u3u5mw.svelte-u3u5mw{padding:1rem}.kind-name.svelte-u3u5mw.svelte-u3u5mw{font-size:0.7rem}.search-results-view.svelte-u3u5mw.svelte-u3u5mw{left:160px}.search-result-info.svelte-u3u5mw.svelte-u3u5mw{width:8rem}.search-result-author.svelte-u3u5mw.svelte-u3u5mw{font-size:0.7rem}.search-result-content.svelte-u3u5mw.svelte-u3u5mw{font-size:0.8rem}}.recovery-tab.svelte-u3u5mw.svelte-u3u5mw{padding:20px;width:100%;max-width:1200px;margin:0;box-sizing:border-box}.recovery-tab.svelte-u3u5mw h3.svelte-u3u5mw{margin:0 0 10px 0;color:var(--text-color)}.recovery-tab.svelte-u3u5mw p.svelte-u3u5mw{margin:0;color:var(--text-color);opacity:0.7;padding:0.5em}.recovery-controls-card.svelte-u3u5mw.svelte-u3u5mw{background-color:transparent;border:none;border-radius:0.5em;padding:0}.recovery-controls.svelte-u3u5mw.svelte-u3u5mw{display:flex;gap:20px;align-items:center;flex-wrap:wrap}.kind-selector.svelte-u3u5mw.svelte-u3u5mw{display:flex;flex-direction:column;gap:5px}.kind-selector.svelte-u3u5mw label.svelte-u3u5mw{font-weight:500;color:var(--text-color)}.kind-selector.svelte-u3u5mw select.svelte-u3u5mw{padding:8px 12px;border:1px solid var(--border-color);border-radius:0.5em;background:var(--bg-color);color:var(--text-color);min-width:300px}.custom-kind-input.svelte-u3u5mw.svelte-u3u5mw{display:flex;flex-direction:column;gap:5px}.custom-kind-input.svelte-u3u5mw label.svelte-u3u5mw{font-weight:500;color:var(--text-color)}.custom-kind-input.svelte-u3u5mw input.svelte-u3u5mw{padding:8px 12px;border:1px solid var(--border-color);border-radius:0.5em;background:var(--bg-color);color:var(--text-color);min-width:200px}.custom-kind-input.svelte-u3u5mw input.svelte-u3u5mw::placeholder{color:var(--text-color);opacity:0.6}.recovery-results.svelte-u3u5mw.svelte-u3u5mw{margin-top:20px}.loading.svelte-u3u5mw.svelte-u3u5mw,.no-events.svelte-u3u5mw.svelte-u3u5mw{text-align:left;padding:40px 20px;color:var(--text-color);opacity:0.7}.events-list.svelte-u3u5mw.svelte-u3u5mw{display:flex;flex-direction:column;gap:15px}.event-item.svelte-u3u5mw.svelte-u3u5mw{background:var(--surface-bg);border:2px solid var(--primary);border-radius:0.5em;padding:20px;transition:all 0.2s ease;background:var(--header-bg)}.event-item.old-version.svelte-u3u5mw.svelte-u3u5mw{opacity:0.85;border:none;background:var(--header-bg)}.event-header.svelte-u3u5mw.svelte-u3u5mw{display:flex;justify-content:space-between;align-items:center;margin-bottom:15px;flex-wrap:wrap;gap:10px}.event-header-left.svelte-u3u5mw.svelte-u3u5mw{display:flex;align-items:center;gap:15px;flex-wrap:wrap}.event-header-actions.svelte-u3u5mw.svelte-u3u5mw{display:flex;align-items:center;gap:8px}.event-kind.svelte-u3u5mw.svelte-u3u5mw{font-weight:600;color:var(--primary)}.event-timestamp.svelte-u3u5mw.svelte-u3u5mw{color:var(--text-color);font-size:0.9em;opacity:0.7}.repost-all-button.svelte-u3u5mw.svelte-u3u5mw{background:#059669;color:var(--text-color);border:none;padding:6px 12px;border-radius:0.5em;cursor:pointer;font-size:0.9em;transition:background 0.2s ease;margin-right:8px}.repost-all-button.svelte-u3u5mw.svelte-u3u5mw:hover{background:#047857}.repost-button.svelte-u3u5mw.svelte-u3u5mw{background:var(--primary);color:var(--text-color);border:none;padding:6px 12px;border-radius:0.5em;cursor:pointer;font-size:0.9em;transition:background 0.2s ease}.repost-button.svelte-u3u5mw.svelte-u3u5mw:hover{background:#00acc1}.event-content.svelte-u3u5mw.svelte-u3u5mw{margin-bottom:15px}.load-more.svelte-u3u5mw.svelte-u3u5mw{width:100%;padding:12px;background:var(--primary);color:var(--text-color);border:none;border-radius:0.5em;cursor:pointer;font-size:1em;margin-top:20px;transition:background 0.2s ease}.load-more.svelte-u3u5mw.svelte-u3u5mw:hover:not(:disabled){background:#00acc1}.load-more.svelte-u3u5mw.svelte-u3u5mw:disabled{opacity:0.6;cursor:not-allowed}body.dark-theme .event-item.old-version.svelte-u3u5mw.svelte-u3u5mw{background:var(--header-bg);border:none}
+html,
+body {
+ position: relative;
+ width: 100%;
+ height: 100%;
+}
+
+body {
+ color: #333;
+ margin: 0;
+ padding: 8px;
+ box-sizing: border-box;
+ font-family:
+ -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu,
+ Cantarell, "Helvetica Neue", sans-serif;
+}
+
+a {
+ color: rgb(0, 100, 200);
+ text-decoration: none;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+a:visited {
+ color: rgb(0, 80, 160);
+}
+
+label {
+ display: block;
+}
+
+input,
+button,
+select,
+textarea {
+ font-family: inherit;
+ font-size: inherit;
+ -webkit-padding: 0.4em 0;
+ padding: 0.4em;
+ margin: 0 0 0.5em 0;
+ box-sizing: border-box;
+ border: 1px solid #ccc;
+ border-radius: 2px;
+}
+
+input:disabled {
+ color: #ccc;
+}
+
+button {
+ color: #333;
+ background-color: #f4f4f4;
+ outline: none;
+}
+
+button:disabled {
+ color: #999;
+}
+
+button:not(:disabled):active {
+ background-color: #ddd;
+}
+
+button:focus {
+ border-color: #666;
+}
+
diff --git a/app/web/dist/bundle.js b/app/web/dist/bundle.js
index 51d24f5..23d98da 100644
--- a/app/web/dist/bundle.js
+++ b/app/web/dist/bundle.js
@@ -20,5 +20,5 @@ Object.defineProperty(e,"__esModule",{value:!0}),e.bytes=e.stringToBytes=e.str=e
* hash-wasm (https://www.npmjs.com/package/hash-wasm)
* (c) Dani Biro
* @license MIT
- */function $p(e,t,n,r){return new(n||(n=Promise))(function(i,o){function s(e){try{l(r.next(e))}catch(e){o(e)}}function a(e){try{l(r.throw(e))}catch(e){o(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n(function(e){e(t)})).then(s,a)}l((r=r.apply(e,t||[])).next())})}"function"==typeof SuppressedError&&SuppressedError;class Up{constructor(){this.mutex=Promise.resolve()}lock(){let e=()=>{};return this.mutex=this.mutex.then(()=>new Promise(e)),new Promise(t=>{e=t})}dispatch(e){return $p(this,void 0,void 0,function*(){const t=yield this.lock();try{return yield Promise.resolve(e())}finally{t()}})}}var Pp;const Rp="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:global,Tp=null!==(Pp=Rp.Buffer)&&void 0!==Pp?Pp:null,Np=Rp.TextEncoder?new Rp.TextEncoder:null;function Op(e,t){return(15&e)+(e>>6|e>>3&8)<<4|(15&t)+(t>>6|t>>3&8)}function Mp(e,t){const n=t.length>>1;for(let r=0;r>>4;e[r++]=n>9?n+Lp:n+_p,n=15&t[i],e[r++]=n>9?n+Lp:n+_p}return String.fromCharCode.apply(null,e)}const jp=null!==Tp?e=>{if("string"==typeof e){const t=Tp.from(e,"utf8");return new Uint8Array(t.buffer,t.byteOffset,t.length)}if(Tp.isBuffer(e))return new Uint8Array(e.buffer,e.byteOffset,e.length);if(ArrayBuffer.isView(e))return new Uint8Array(e.buffer,e.byteOffset,e.byteLength);throw new Error("Invalid data type!")}:e=>{if("string"==typeof e)return Np.encode(e);if(ArrayBuffer.isView(e))return new Uint8Array(e.buffer,e.byteOffset,e.byteLength);throw new Error("Invalid data type!")},Gp="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",Jp=new Uint8Array(256);for(let e=0;e<64;e++)Jp[Gp.charCodeAt(e)]=e;function Kp(e,t=!0){const n=e.length,r=n%3,i=[],o=n-r;for(let t=0;t>18&63)+Gp.charAt(n>>12&63)+Gp.charAt(n>>6&63)+Gp.charAt(63&n);i.push(r)}if(1===r){const r=e[n-1],o=Gp.charAt(r>>2),s=Gp.charAt(r<<4&63);i.push(`${o}${s}`),t&&i.push("==")}else if(2===r){const r=(e[n-2]<<8)+e[n-1],o=Gp.charAt(r>>10),s=Gp.charAt(r>>4&63),a=Gp.charAt(r<<2&63);i.push(`${o}${s}${a}`),t&&i.push("=")}return i.join("")}function Vp(e){const t=function(e){let t=Math.floor(.75*e.length);const n=e.length;return"="===e[n-1]&&(t-=1,"="===e[n-2]&&(t-=1)),t}(e),n=e.length,r=new Uint8Array(t);let i=0;for(let t=0;t>4,i+=1,r[i]=(15&o)<<4|s>>2,i+=1,r[i]=(3&s)<<6|63&a,i+=1}return r}const zp=16384,qp=new Up,Yp=new Map;function Wp(e,t){return $p(this,void 0,void 0,function*(){let n=null,r=null,i=!1;if("undefined"==typeof WebAssembly)throw new Error("WebAssembly is not supported in this environment!");const o=()=>new DataView(n.exports.memory.buffer).getUint32(n.exports.STATE_SIZE,!0),s=qp.dispatch(()=>$p(this,void 0,void 0,function*(){if(!Yp.has(e.name)){const t=Vp(e.data),n=WebAssembly.compile(t);Yp.set(e.name,n)}const t=yield Yp.get(e.name);n=yield WebAssembly.instantiate(t,{})})),a=(e=null)=>{i=!0,n.exports.Hash_Init(e)},l=e=>{if(!i)throw new Error("update() called before init()");(e=>{let t=0;for(;t{if(!i)throw new Error("digest() called before init()");return i=!1,n.exports.Hash_Final(o),"binary"===e?r.slice(0,t):Hp(c,r,t)},d=e=>"string"==typeof e?e.length<4096:e.byteLength!0;break;case"blake2b":case"blake2s":f=(e,t)=>t<=512&&d(e);break;case"blake3":f=(e,t)=>0===t&&d(e);break;case"xxhash64":case"xxhash3":case"xxhash128":case"crc64":f=()=>!1}return yield(()=>$p(this,void 0,void 0,function*(){n||(yield s);const e=n.exports.Hash_GetBuffer(),t=n.exports.memory.buffer;r=new Uint8Array(t,e,zp)}))(),{getMemory:()=>r,writeMemory:(e,t=0)=>{r.set(e,t)},getExports:()=>n.exports,setMemorySize:e=>{n.exports.Hash_SetMemorySize(e);const t=n.exports.Hash_GetBuffer(),i=n.exports.memory.buffer;r=new Uint8Array(i,t,e)},init:a,update:l,digest:u,save:()=>{if(!i)throw new Error("save() can only be called after init() and before digest()");const t=n.exports.Hash_GetState(),r=o(),s=n.exports.memory.buffer,a=new Uint8Array(s,t,r),l=new Uint8Array(4+r);return Mp(l,e.hash),l.set(a,4),l},load:t=>{if(!(t instanceof Uint8Array))throw new Error("load() expects an Uint8Array generated by save()");const r=n.exports.Hash_GetState(),s=o(),a=4+s,l=n.exports.memory.buffer;if(t.length!==a)throw new Error(`Bad state length (expected ${a} bytes, got ${t.length})`);if(!function(e,t){if(e.length!==2*t.length)return!1;for(let n=0;n{if(!f(e,i))return a(i),l(e),u("hex",o);const s=jp(e);return r.set(s),n.exports.Hash_Calculate(s.length,i,o),Hp(c,r,t)},hashLength:t}})}new Up;var Zp={name:"argon2",data:"AGFzbQEAAAABKQVgAX8Bf2AAAX9gEH9/f39/f39/f39/f39/f38AYAR/f39/AGACf38AAwYFAAECAwQFBgEBAoCAAgYIAX8BQZCoBAsHQQQGbWVtb3J5AgASSGFzaF9TZXRNZW1vcnlTaXplAAAOSGFzaF9HZXRCdWZmZXIAAQ5IYXNoX0NhbGN1bGF0ZQAECvEyBVgBAn9BACEBAkAgAEEAKAKICCICRg0AAkAgACACayIAQRB2IABBgIB8cSAASWoiAEAAQX9HDQBB/wHADwtBACEBQQBBACkDiAggAEEQdK18NwOICAsgAcALcAECfwJAQQAoAoAIIgANAEEAPwBBEHQiADYCgAhBACgCiAgiAUGAgCBGDQACQEGAgCAgAWsiAEEQdiAAQYCAfHEgAElqIgBAAEF/Rw0AQQAPC0EAQQApA4gIIABBEHStfDcDiAhBACgCgAghAAsgAAvcDgECfiAAIAQpAwAiECAAKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAMIBAgDCkDAIVCIIkiEDcDACAIIBAgCCkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgBCAQIAQpAwCFQiiJIhA3AwAgACAQIAApAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIAwgECAMKQMAhUIwiSIQNwMAIAggECAIKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAEIBAgBCkDAIVCAYk3AwAgASAFKQMAIhAgASkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDSAQIA0pAwCFQiCJIhA3AwAgCSAQIAkpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAUgECAFKQMAhUIoiSIQNwMAIAEgECABKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACANIBAgDSkDAIVCMIkiEDcDACAJIBAgCSkDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgBSAQIAUpAwCFQgGJNwMAIAIgBikDACIQIAIpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIA4gECAOKQMAhUIgiSIQNwMAIAogECAKKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAGIBAgBikDAIVCKIkiEDcDACACIBAgAikDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgDiAQIA4pAwCFQjCJIhA3AwAgCiAQIAopAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIAYgECAGKQMAhUIBiTcDACADIAcpAwAiECADKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAPIBAgDykDAIVCIIkiEDcDACALIBAgCykDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgByAQIAcpAwCFQiiJIhA3AwAgAyAQIAMpAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIA8gECAPKQMAhUIwiSIQNwMAIAsgECALKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAHIBAgBykDAIVCAYk3AwAgACAFKQMAIhAgACkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDyAQIA8pAwCFQiCJIhA3AwAgCiAQIAopAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAUgECAFKQMAhUIoiSIQNwMAIAAgECAAKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAPIBAgDykDAIVCMIkiEDcDACAKIBAgCikDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgBSAQIAUpAwCFQgGJNwMAIAEgBikDACIQIAEpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAwgECAMKQMAhUIgiSIQNwMAIAsgECALKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAGIBAgBikDAIVCKIkiEDcDACABIBAgASkDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgDCAQIAwpAwCFQjCJIhA3AwAgCyAQIAspAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIAYgECAGKQMAhUIBiTcDACACIAcpAwAiECACKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACANIBAgDSkDAIVCIIkiEDcDACAIIBAgCCkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgByAQIAcpAwCFQiiJIhA3AwAgAiAQIAIpAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIA0gECANKQMAhUIwiSIQNwMAIAggECAIKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAHIBAgBykDAIVCAYk3AwAgAyAEKQMAIhAgAykDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDiAQIA4pAwCFQiCJIhA3AwAgCSAQIAkpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAQgECAEKQMAhUIoiSIQNwMAIAMgECADKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAOIBAgDikDAIVCMIkiEDcDACAJIBAgCSkDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgBCAQIAQpAwCFQgGJNwMAC98aAQN/QQAhBEEAIAIpAwAgASkDAIU3A5AIQQAgAikDCCABKQMIhTcDmAhBACACKQMQIAEpAxCFNwOgCEEAIAIpAxggASkDGIU3A6gIQQAgAikDICABKQMghTcDsAhBACACKQMoIAEpAyiFNwO4CEEAIAIpAzAgASkDMIU3A8AIQQAgAikDOCABKQM4hTcDyAhBACACKQNAIAEpA0CFNwPQCEEAIAIpA0ggASkDSIU3A9gIQQAgAikDUCABKQNQhTcD4AhBACACKQNYIAEpA1iFNwPoCEEAIAIpA2AgASkDYIU3A/AIQQAgAikDaCABKQNohTcD+AhBACACKQNwIAEpA3CFNwOACUEAIAIpA3ggASkDeIU3A4gJQQAgAikDgAEgASkDgAGFNwOQCUEAIAIpA4gBIAEpA4gBhTcDmAlBACACKQOQASABKQOQAYU3A6AJQQAgAikDmAEgASkDmAGFNwOoCUEAIAIpA6ABIAEpA6ABhTcDsAlBACACKQOoASABKQOoAYU3A7gJQQAgAikDsAEgASkDsAGFNwPACUEAIAIpA7gBIAEpA7gBhTcDyAlBACACKQPAASABKQPAAYU3A9AJQQAgAikDyAEgASkD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",hash:"e4cdc523"},Xp={name:"blake2b",data:"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",hash:"c6f286e6"};function eh(e){return!Number.isInteger(e)||e<8||e>512||e%8!=0?new Error("Invalid variant! Valid values: 8, 16, ..., 512"):null}function th(e=512,t=null){if(eh(e))return Promise.reject(eh(e));let n=null,r=e;if(null!==t){if(n=jp(t),n.length>64)return Promise.reject(new Error("Max key length is 64 bytes"));i=e,o=n.length,r=i|o<<16}var i,o;const s=e/8;return Wp(Xp,s).then(e=>{r>512&&e.writeMemory(n),e.init(r);const t={init:r>512?()=>(e.writeMemory(n),e.init(r),t):()=>(e.init(r),t),update:n=>(e.update(n),t),digest:t=>e.digest(t),save:()=>e.save(),load:n=>(e.load(n),t),blockSize:128,digestSize:s};return t})}new Up;const nh=new DataView(new ArrayBuffer(4));function rh(e){return nh.setInt32(0,e,!0),new Uint8Array(nh.buffer)}function ih(e,t,n){return $p(this,void 0,void 0,function*(){if(n<=64){const e=yield th(8*n);return e.update(rh(n)),e.update(t),e.digest("binary")}const r=Math.ceil(n/32)-2,i=new Uint8Array(n);e.init(),e.update(rh(n)),e.update(t);let o=e.digest("binary");i.set(o.subarray(0,32),0);for(let t=1;t{var t;if(!e||"object"!=typeof e)throw new Error("Invalid options parameter. It requires an object.");if(!e.password)throw new Error("Password must be specified");if(e.password=jp(e.password),e.password.length<1)throw new Error("Password must be specified");if(!e.salt)throw new Error("Salt must be specified");if(e.salt=jp(e.salt),e.salt.length<8)throw new Error("Salt should be at least 8 bytes long");if(e.secret=jp(null!==(t=e.secret)&&void 0!==t?t:""),!Number.isInteger(e.iterations)||e.iterations<1)throw new Error("Iterations should be a positive number");if(!Number.isInteger(e.parallelism)||e.parallelism<1)throw new Error("Parallelism should be a positive number");if(!Number.isInteger(e.hashLength)||e.hashLength<4)throw new Error("Hash length should be at least 4 bytes.");if(!Number.isInteger(e.memorySize))throw new Error("Memory size should be specified.");if(e.memorySize<8*e.parallelism)throw new Error("Memory size should be at least 8 * parallelism.");if(void 0===e.outputType&&(e.outputType="hex"),!["hex","binary","encoded"].includes(e.outputType))throw new Error(`Insupported output type ${e.outputType}. Valid values: ['hex', 'binary', 'encoded']`)})(e),oh(Object.assign(Object.assign({},e),{hashType:"id"}))})}new Up,new Up,new Up,new Up,new Up,new Up,new Up,new Up,new Up,new Up,new Up,new Up,new Up,new Up,new Up,new Up,new Up,new Up,new Up,new Up;const ah={parallelism:4,iterations:8,memorySize:262144,hashLength:32,outputType:"binary"};let lh=null,ch=0;const uh=new Map;async function dh(e,t){try{const n=function(){if(lh)return lh;const e=new Blob(["\n importScripts('https://cdn.jsdelivr.net/npm/hash-wasm@4.11.0/dist/argon2.umd.min.js');\n\n const ARGON2_CONFIG = {\n parallelism: 4,\n iterations: 8,\n memorySize: 262144,\n hashLength: 32,\n outputType: \"binary\"\n };\n\n self.onmessage = async function(e) {\n const { password, salt, id } = e.data;\n\n try {\n const result = await hashwasm.argon2id({\n password: password,\n salt: new Uint8Array(salt),\n ...ARGON2_CONFIG\n });\n\n self.postMessage({\n id,\n success: true,\n result: Array.from(result)\n });\n } catch (error) {\n self.postMessage({\n id,\n success: false,\n error: error.message\n });\n }\n };\n "],{type:"application/javascript"});return lh=new Worker(URL.createObjectURL(e)),lh.onmessage=function(e){const{id:t,success:n,result:r,error:i}=e.data,o=uh.get(t);o&&(uh.delete(t),n?o.resolve(new Uint8Array(r)):o.reject(new Error(i)))},lh.onerror=function(e){console.error("Argon2 worker error:",e)},lh}(),r=++ch;return new Promise((i,o)=>{uh.set(r,{resolve:i,reject:o}),n.postMessage({id:r,password:e,salt:Array.from(t)})})}catch(n){console.warn("Worker failed, falling back to main thread:",n);return await sh({password:e,salt:t,...ah})}}const{window:fh}=l;function ph(e){let t,n,i,o,s,a,l,f,h,g,y,b,k,I,C,E,B,S;function Q(e,t){return"extension"===e[2]?gh:hh}let F=Q(e),D=F(e),$=e[10]&&Bh(e),U=e[11]&&Sh(e);return{c(){t=p("div"),n=p("div"),i=p("div"),o=p("h2"),o.textContent="Login to Nostr",s=m(),a=p("button"),a.textContent="×",l=m(),f=p("div"),h=p("div"),g=p("button"),g.textContent="Extension",y=m(),b=p("button"),b.textContent="Nsec",k=m(),I=p("div"),D.c(),C=m(),$&&$.c(),E=m(),U&&U.c(),A(o,"class","svelte-4xpfbi"),A(a,"class","close-btn svelte-4xpfbi"),A(i,"class","modal-header svelte-4xpfbi"),A(g,"class","tab-btn svelte-4xpfbi"),x(g,"active","extension"===e[2]),A(b,"class","tab-btn svelte-4xpfbi"),x(b,"active","nsec"===e[2]),A(h,"class","tabs svelte-4xpfbi"),A(I,"class","tab-content svelte-4xpfbi"),A(f,"class","tab-container svelte-4xpfbi"),A(n,"class","modal svelte-4xpfbi"),x(n,"dark-theme",e[1]),A(t,"class","modal-overlay svelte-4xpfbi"),A(t,"role","button"),A(t,"tabindex","0")},m(r,d){u(r,t,d),c(t,n),c(n,i),c(i,o),c(i,s),c(i,a),c(n,l),c(n,f),c(f,h),c(h,g),c(h,y),c(h,b),c(f,k),c(f,I),D.m(I,null),c(I,C),$&&$.m(I,null),c(I,E),U&&U.m(I,null),B||(S=[v(a,"click",e[17]),v(g,"click",e[26]),v(b,"click",e[27]),v(n,"click",w(e[24])),v(n,"keydown",w(e[25])),v(t,"click",e[17]),v(t,"keydown",e[32])],B=!0)},p(e,t){4&t[0]&&x(g,"active","extension"===e[2]),4&t[0]&&x(b,"active","nsec"===e[2]),F===(F=Q(e))&&D?D.p(e,t):(D.d(1),D=F(e),D&&(D.c(),D.m(I,C))),e[10]?$?$.p(e,t):($=Bh(e),$.c(),$.m(I,E)):$&&($.d(1),$=null),e[11]?U?U.p(e,t):(U=Sh(e),U.c(),U.m(I,null)):U&&(U.d(1),U=null),2&t[0]&&x(n,"dark-theme",e[1])},d(e){e&&d(t),D.d(),$&&$.d(),U&&U.d(),B=!1,r(S)}}}function hh(e){let t;function n(e,t){return e[14]?yh:mh}let r=n(e),i=r(e);return{c(){t=p("div"),i.c(),A(t,"class","nsec-login svelte-4xpfbi")},m(e,n){u(e,t,n),i.m(t,null)},p(e,o){r===(r=n(e))&&i?i.p(e,o):(i.d(1),i=r(e),i&&(i.c(),i.m(t,null)))},d(e){e&&d(t),i.d()}}}function gh(e){let t,n,r,i,o,s,a,l=e[7]?"Connecting...":"Log in using extension";return{c(){t=p("div"),n=p("p"),n.textContent="Login using a NIP-07 compatible browser\n extension like nos2x or Alby.",r=m(),i=p("button"),o=g(l),A(n,"class","svelte-4xpfbi"),A(i,"class","login-extension-btn svelte-4xpfbi"),i.disabled=e[7],A(t,"class","extension-login svelte-4xpfbi")},m(l,d){u(l,t,d),c(t,n),c(t,r),c(t,i),c(i,o),s||(a=v(i,"click",e[21]),s=!0)},p(e,t){128&t[0]&&l!==(l=e[7]?"Connecting...":"Log in using extension")&&k(o,l),128&t[0]&&(i.disabled=e[7])},d(e){e&&d(t),s=!1,a()}}}function mh(e){let t,n,i,o,s,a,l,f,h,y,w,b,C,E,x,B,S,Q,F,D,$,U,P,R=e[8]?"Generating...":"Generate New Key",T=e[12]&&vh(e),N=e[4]&&wh(e);function O(e,t){return e[9]?kh:e[7]?bh:Ah}let M=O(e),L=M(e);return{c(){t=p("p"),t.textContent="Enter your nsec or generate a new one. Optionally\n set a password to encrypt it securely.",n=m(),i=p("button"),o=g(R),a=m(),T&&T.c(),l=m(),f=p("input"),y=m(),w=p("div"),b=p("label"),b.textContent="Encryption Password (optional but recommended):",C=m(),E=p("input"),B=m(),N&&N.c(),S=m(),Q=p("small"),Q.textContent="Password uses Argon2id with ~3 second derivation time for security.",F=m(),D=p("button"),L.c(),A(t,"class","svelte-4xpfbi"),A(i,"class","generate-btn svelte-4xpfbi"),i.disabled=s=e[7]||e[8],A(f,"type","password"),A(f,"placeholder","nsec1..."),f.disabled=h=e[7]||e[9],A(f,"class","nsec-input svelte-4xpfbi"),A(b,"class","svelte-4xpfbi"),A(E,"type","password"),A(E,"placeholder","Enter password (min 8 chars)"),E.disabled=x=e[7]||e[9],A(E,"class","password-input svelte-4xpfbi"),A(Q,"class","password-hint svelte-4xpfbi"),A(w,"class","password-section svelte-4xpfbi"),A(D,"class","login-nsec-btn svelte-4xpfbi"),D.disabled=$=e[7]||e[9]||!e[3].trim()},m(r,s){u(r,t,s),u(r,n,s),u(r,i,s),c(i,o),u(r,a,s),T&&T.m(r,s),u(r,l,s),u(r,f,s),I(f,e[3]),u(r,y,s),u(r,w,s),c(w,b),c(w,C),c(w,E),I(E,e[4]),c(w,B),N&&N.m(w,null),c(w,S),c(w,Q),u(r,F,s),u(r,D,s),L.m(D,null),U||(P=[v(i,"click",e[20]),v(f,"input",e[29]),v(E,"input",e[30]),v(D,"click",e[22])],U=!0)},p(e,t){256&t[0]&&R!==(R=e[8]?"Generating...":"Generate New Key")&&k(o,R),384&t[0]&&s!==(s=e[7]||e[8])&&(i.disabled=s),e[12]?T?T.p(e,t):(T=vh(e),T.c(),T.m(l.parentNode,l)):T&&(T.d(1),T=null),640&t[0]&&h!==(h=e[7]||e[9])&&(f.disabled=h),8&t[0]&&f.value!==e[3]&&I(f,e[3]),640&t[0]&&x!==(x=e[7]||e[9])&&(E.disabled=x),16&t[0]&&E.value!==e[4]&&I(E,e[4]),e[4]?N?N.p(e,t):(N=wh(e),N.c(),N.m(w,S)):N&&(N.d(1),N=null),M!==(M=O(e))&&(L.d(1),L=M(e),L&&(L.c(),L.m(D,null))),648&t[0]&&$!==($=e[7]||e[9]||!e[3].trim())&&(D.disabled=$)},d(e){e&&d(t),e&&d(n),e&&d(i),e&&d(a),T&&T.d(e),e&&d(l),e&&d(f),e&&d(y),e&&d(w),N&&N.d(),e&&d(F),e&&d(D),L.d(),U=!1,r(P)}}}function yh(e){let t,n,i,o,s,a,l,f,h,y,w,b,k,C,E=e[15]&&Ih(e);function x(e,t){return e[9]?xh:e[7]?Eh:Ch}let B=x(e),S=B(e);return{c(){t=p("p"),t.textContent="You have a stored encrypted key. Enter your\n password to unlock it.",n=m(),E&&E.c(),i=m(),o=p("input"),a=m(),l=p("button"),S.c(),h=m(),y=p("button"),w=g("Clear stored key & start fresh"),A(t,"class","svelte-4xpfbi"),A(o,"type","password"),A(o,"placeholder","Enter your password"),o.disabled=s=e[7]||e[9],A(o,"class","password-input svelte-4xpfbi"),A(l,"class","login-nsec-btn svelte-4xpfbi"),l.disabled=f=e[7]||e[9]||!e[6],A(y,"class","clear-btn svelte-4xpfbi"),y.disabled=b=e[7]||e[9]},m(r,s){u(r,t,s),u(r,n,s),E&&E.m(r,s),u(r,i,s),u(r,o,s),I(o,e[6]),u(r,a,s),u(r,l,s),S.m(l,null),u(r,h,s),u(r,y,s),c(y,w),k||(C=[v(o,"input",e[28]),v(l,"click",e[18]),v(y,"click",e[16])],k=!0)},p(e,t){e[15]?E?E.p(e,t):(E=Ih(e),E.c(),E.m(i.parentNode,i)):E&&(E.d(1),E=null),640&t[0]&&s!==(s=e[7]||e[9])&&(o.disabled=s),64&t[0]&&o.value!==e[6]&&I(o,e[6]),B!==(B=x(e))&&(S.d(1),S=B(e),S&&(S.c(),S.m(l,null))),704&t[0]&&f!==(f=e[7]||e[9]||!e[6])&&(l.disabled=f),640&t[0]&&b!==(b=e[7]||e[9])&&(y.disabled=b)},d(e){e&&d(t),e&&d(n),E&&E.d(e),e&&d(i),e&&d(o),e&&d(a),e&&d(l),S.d(),e&&d(h),e&&d(y),k=!1,r(C)}}}function vh(e){let t,n,r,i,o;return{c(){t=p("div"),n=p("label"),n.textContent="Your new public key (npub):",r=m(),i=p("code"),o=g(e[12]),A(n,"class","svelte-4xpfbi"),A(i,"class","npub-display svelte-4xpfbi"),A(t,"class","generated-info svelte-4xpfbi")},m(e,s){u(e,t,s),c(t,n),c(t,r),c(t,i),c(i,o)},p(e,t){4096&t[0]&&k(o,e[12])},d(e){e&&d(t)}}}function wh(e){let t,n,r,i;return{c(){t=p("input"),A(t,"type","password"),A(t,"placeholder","Confirm password"),t.disabled=n=e[7]||e[9],A(t,"class","password-input svelte-4xpfbi")},m(n,o){u(n,t,o),I(t,e[5]),r||(i=v(t,"input",e[31]),r=!0)},p(e,r){640&r[0]&&n!==(n=e[7]||e[9])&&(t.disabled=n),32&r[0]&&t.value!==e[5]&&I(t,e[5])},d(e){e&&d(t),r=!1,i()}}}function Ah(e){let t;return{c(){t=g("Log in with nsec")},m(e,n){u(e,t,n)},d(e){e&&d(t)}}}function bh(e){let t;return{c(){t=g("Logging in...")},m(e,n){u(e,t,n)},d(e){e&&d(t)}}}function kh(e){let t;return{c(){t=g("Deriving key...")},m(e,n){u(e,t,n)},d(e){e&&d(t)}}}function Ih(e){let t,n,r,i,o,s,a,l=e[15].slice(0,16)+"",f=e[15].slice(-8)+"";return{c(){t=p("div"),n=p("label"),n.textContent="Stored public key:",r=m(),i=p("code"),o=g(l),s=g("..."),a=g(f),A(n,"class","svelte-4xpfbi"),A(i,"class","npub-display svelte-4xpfbi"),A(t,"class","stored-info svelte-4xpfbi")},m(e,l){u(e,t,l),c(t,n),c(t,r),c(t,i),c(i,o),c(i,s),c(i,a)},p(e,t){32768&t[0]&&l!==(l=e[15].slice(0,16)+"")&&k(o,l),32768&t[0]&&f!==(f=e[15].slice(-8)+"")&&k(a,f)},d(e){e&&d(t)}}}function Ch(e){let t;return{c(){t=g("Unlock")},m(e,n){u(e,t,n)},d(e){e&&d(t)}}}function Eh(e){let t;return{c(){t=g("Unlocking...")},m(e,n){u(e,t,n)},d(e){e&&d(t)}}}function xh(e){let t;return{c(){t=g("Deriving key...")},m(e,n){u(e,t,n)},d(e){e&&d(t)}}}function Bh(e){let t,n;return{c(){t=p("div"),n=g(e[10]),A(t,"class","message error-message svelte-4xpfbi")},m(e,r){u(e,t,r),c(t,n)},p(e,t){1024&t[0]&&k(n,e[10])},d(e){e&&d(t)}}}function Sh(e){let t,n;return{c(){t=p("div"),n=g(e[11]),A(t,"class","message success-message svelte-4xpfbi")},m(e,r){u(e,t,r),c(t,n)},p(e,t){2048&t[0]&&k(n,e[11])},d(e){e&&d(t)}}}function Qh(e){let t,n,r,i,o,s,a,l,f,h,y,v=e[13].toFixed(1)+"";return{c(){t=p("div"),n=p("div"),r=p("div"),i=m(),o=p("h3"),o.textContent="Deriving encryption key",s=m(),a=p("div"),l=g(v),f=g("s"),h=m(),y=p("p"),y.textContent="This may take 3-6 seconds for security",A(r,"class","deriving-spinner svelte-4xpfbi"),A(o,"class","svelte-4xpfbi"),A(a,"class","deriving-timer svelte-4xpfbi"),A(y,"class","deriving-note svelte-4xpfbi"),A(n,"class","deriving-modal svelte-4xpfbi"),x(n,"dark-theme",e[1]),A(t,"class","deriving-overlay svelte-4xpfbi")},m(e,d){u(e,t,d),c(t,n),c(n,r),c(n,i),c(n,o),c(n,s),c(n,a),c(a,l),c(a,f),c(n,h),c(n,y)},p(e,t){8192&t[0]&&v!==(v=e[13].toFixed(1)+"")&&k(l,v),2&t[0]&&x(n,"dark-theme",e[1])},d(e){e&&d(t)}}}function Fh(t){let n,r,i,o,s=t[0]&&ph(t),a=t[9]&&Qh(t);return{c(){s&&s.c(),n=m(),a&&a.c(),r=y()},m(e,l){s&&s.m(e,l),u(e,n,l),a&&a.m(e,l),u(e,r,l),i||(o=v(fh,"keydown",t[23]),i=!0)},p(e,t){e[0]?s?s.p(e,t):(s=ph(e),s.c(),s.m(n.parentNode,n)):s&&(s.d(1),s=null),e[9]?a?a.p(e,t):(a=Qh(e),a.c(),a.m(r.parentNode,r)):a&&(a.d(1),a=null)},i:e,o:e,d(e){s&&s.d(e),e&&d(n),a&&a.d(e),e&&d(r),i=!1,o()}}}function Dh(e,t,n){const r=$();let{showModal:i=!1}=t,{isDarkTheme:o=!1}=t,s="extension",a="",l="",c="",u="",d=!1,f=!1,p=!1,h="",g="",m="",y="",v=0,w=null,A=null;function b(){n(13,v=0),w=performance.now(),k()}function k(){null!==w&&(n(13,v=(performance.now()-w)/1e3),A=requestAnimationFrame(k))}function I(){w=null,A&&(cancelAnimationFrame(A),A=null)}D(()=>{I()});let C=!1,E="";function x(){n(14,C=!!localStorage.getItem("nostr_privkey_encrypted")),n(15,E=localStorage.getItem("nostr_pubkey")||"")}function B(){n(0,i=!1),n(3,a=""),n(4,l=""),n(5,c=""),n(6,u=""),n(10,h=""),n(11,g=""),m="",n(12,y=""),r("close")}function S(e){n(2,s=e),n(10,h=""),n(11,g=""),m="",n(12,y="")}async function Q(){n(7,d=!0),n(10,h=""),n(11,g="");try{if(!a.trim())throw new Error("Please enter your nsec");if(!function(e){if(!e||!e.startsWith("nsec1"))return!1;try{return"nsec"===mu(e).type}catch{return!1}}(a.trim()))throw new Error("Invalid nsec format or checksum");if(l){if(l.length<8)throw new Error("Password must be at least 8 characters");if(l!==c)throw new Error("Passwords do not match")}const e=kf.fromKey(a.trim()),t=await e.getPublicKey();if(localStorage.setItem("nostr_auth_method","nsec"),localStorage.setItem("nostr_pubkey",t),l){n(9,p=!0),b();const e=await async function(e,t){if(!e.startsWith("nsec1"))throw new Error("Invalid nsec format - must start with nsec1");try{if("nsec"!==mu(e).type)throw new Error("Invalid nsec - wrong type")}catch(e){throw new Error("Invalid nsec - bech32 checksum failed")}const n=crypto.getRandomValues(new Uint8Array(32)),r=crypto.getRandomValues(new Uint8Array(12)),i=await dh(t,n),o=await crypto.subtle.importKey("raw",i,{name:"AES-GCM"},!1,["encrypt"]),s=new TextEncoder,a=await crypto.subtle.encrypt({name:"AES-GCM",iv:r},o,s.encode(e)),l=new Uint8Array(n.length+r.length+a.byteLength);return l.set(n,0),l.set(r,n.length),l.set(new Uint8Array(a),n.length+r.length),btoa(String.fromCharCode(...l))}(a.trim(),l);I(),n(9,p=!1),localStorage.setItem("nostr_privkey_encrypted",e),localStorage.removeItem("nostr_privkey")}else localStorage.setItem("nostr_privkey",a.trim()),localStorage.removeItem("nostr_privkey_encrypted"),n(11,g="Successfully logged in with nsec!");r("login",{method:"nsec",pubkey:t,privateKey:a.trim(),signer:e}),setTimeout(()=>{B()},1500)}catch(e){n(10,h=e.message)}finally{n(7,d=!1)}}F(()=>{x()});return e.$$set=e=>{"showModal"in e&&n(0,i=e.showModal),"isDarkTheme"in e&&n(1,o=e.isDarkTheme)},e.$$.update=()=>{1&e.$$.dirty[0]&&i&&x()},[i,o,s,a,l,c,u,d,f,p,h,g,y,v,C,E,function(){localStorage.removeItem("nostr_privkey_encrypted"),localStorage.removeItem("nostr_privkey"),localStorage.removeItem("nostr_pubkey"),localStorage.removeItem("nostr_auth_method"),n(14,C=!1),n(15,E=""),n(6,u=""),n(10,h=""),n(11,g="")},B,async function(){n(7,d=!0),n(9,p=!0),b(),n(10,h=""),n(11,g="");try{if(!u)throw new Error("Please enter your password");const e=localStorage.getItem("nostr_privkey_encrypted");if(!e)throw new Error("No encrypted key found");const t=await async function(e,t){const n=new Uint8Array(atob(e).split("").map(e=>e.charCodeAt(0)));if(n.length<60)throw new Error("Invalid encrypted data - too short");const r=n.slice(0,32),i=n.slice(32,44),o=n.slice(44),s=await dh(t,r),a=await crypto.subtle.importKey("raw",s,{name:"AES-GCM"},!1,["decrypt"]);let l;try{l=await crypto.subtle.decrypt({name:"AES-GCM",iv:i},a,o)}catch(e){throw new Error("Decryption failed - invalid password or corrupted data")}const c=(new TextDecoder).decode(l);if(!c.startsWith("nsec1"))throw new Error("Decryption produced invalid data - not an nsec");try{if("nsec"!==mu(c).type)throw new Error("Decryption produced invalid nsec type")}catch(e){throw new Error("Decryption produced invalid nsec - bech32 checksum failed")}return c}(e,u);I(),n(9,p=!1);const i=kf.fromKey(t),o=await i.getPublicKey();r("login",{method:"nsec",pubkey:o,privateKey:t,signer:i}),B()}catch(e){I(),e.message.includes("decrypt")||e.message.includes("tag")?n(10,h="Invalid password"):n(10,h=e.message)}finally{n(7,d=!1),n(9,p=!1),I()}},S,async function(){n(8,f=!0),n(10,h=""),n(11,g="");try{const e=Wc(),t=wu("nsec",e),r=vu(Zc(e));m=t,n(12,y=r),n(3,a=t),n(11,g="New key generated! Set an encryption password below to secure it.")}catch(e){n(10,h="Failed to generate key: "+e.message)}finally{n(8,f=!1)}},async function(){n(7,d=!0),n(10,h=""),n(11,g="");try{if(!window.nostr)throw new Error("No Nostr extension found. Please install a NIP-07 compatible extension like nos2x or Alby.");const e=await window.nostr.getPublicKey();e&&(localStorage.setItem("nostr_auth_method","extension"),localStorage.setItem("nostr_pubkey",e),n(11,g="Successfully logged in with extension!"),r("login",{method:"extension",pubkey:e,signer:window.nostr}),setTimeout(()=>{B()},1500))}catch(e){n(10,h=e.message)}finally{n(7,d=!1)}},Q,function(e){"Escape"===e.key&&B(),"Enter"===e.key&&"nsec"===s&&Q()},function(t){U.call(this,e,t)},function(t){U.call(this,e,t)},()=>S("extension"),()=>S("nsec"),function(){u=this.value,n(6,u)},function(){a=this.value,n(3,a)},function(){l=this.value,n(4,l)},function(){c=this.value,n(5,c)},e=>"Escape"===e.key&&B()]}class $h extends ie{constructor(e){super(),re(this,e,Dh,Fh,o,{showModal:0,isDarkTheme:1},null,[-1,-1])}}function Uh(e,t,n){const r=e.slice();return r[72]=t[n],r}function Ph(e,t,n){const r=e.slice();return r[75]=t[n],r}function Rh(e,t,n){const r=e.slice();return r[72]=t[n],r}function Th(e,t,n){const r=e.slice();return r[72]=t[n],r}function Nh(e,t,n){const r=e.slice();return r[72]=t[n],r}function Oh(e,t,n){const r=e.slice();return r[72]=t[n],r}function Mh(e,t,n){const r=e.slice();return r[72]=t[n],r}function Lh(e){let t,n,r;return{c(){t=p("div"),n=g(e[3]),A(t,"class",r="message "+e[4]+" svelte-1y8wjwc")},m(e,r){u(e,t,r),c(t,n)},p(e,i){8&i[0]&&k(n,e[3]),16&i[0]&&r!==(r="message "+e[4]+" svelte-1y8wjwc")&&A(t,"class",r)},d(e){e&&d(t)}}}function _h(e){let t,n,i,o,s,a,l,f,h,y,w,b,k,C,E,x,B,S,Q,F,D,$,U,P,R,T,N,O;function M(e,t){return e[5]&&e[5].length>0?jh:Hh}let L=M(e),_=L(e);function H(e,t){return e[8]&&e[8].length>0?Vh:Kh}let j=H(e),G=j(e);return{c(){t=p("div"),n=p("div"),i=p("h3"),i.textContent="Banned Pubkeys",o=m(),s=p("div"),a=p("input"),l=m(),f=p("input"),h=m(),y=p("button"),w=g("Ban Pubkey"),b=m(),k=p("div"),_.c(),C=m(),E=p("div"),x=p("h3"),x.textContent="Allowed Pubkeys",B=m(),S=p("div"),Q=p("input"),F=m(),D=p("input"),$=m(),U=p("button"),P=g("Allow Pubkey"),R=m(),T=p("div"),G.c(),A(i,"class","svelte-1y8wjwc"),A(a,"type","text"),A(a,"placeholder","Pubkey (64 hex chars)"),A(a,"class","svelte-1y8wjwc"),A(f,"type","text"),A(f,"placeholder","Reason (optional)"),A(f,"class","svelte-1y8wjwc"),y.disabled=e[2],A(y,"class","svelte-1y8wjwc"),A(s,"class","add-form svelte-1y8wjwc"),A(k,"class","list svelte-1y8wjwc"),A(n,"class","section svelte-1y8wjwc"),A(x,"class","svelte-1y8wjwc"),A(Q,"type","text"),A(Q,"placeholder","Pubkey (64 hex chars)"),A(Q,"class","svelte-1y8wjwc"),A(D,"type","text"),A(D,"placeholder","Reason (optional)"),A(D,"class","svelte-1y8wjwc"),U.disabled=e[2],A(U,"class","svelte-1y8wjwc"),A(S,"class","add-form svelte-1y8wjwc"),A(T,"class","list svelte-1y8wjwc"),A(E,"class","section svelte-1y8wjwc"),A(t,"class","pubkeys-section")},m(r,d){u(r,t,d),c(t,n),c(n,i),c(n,o),c(n,s),c(s,a),I(a,e[6]),c(s,l),c(s,f),I(f,e[7]),c(s,h),c(s,y),c(y,w),c(n,b),c(n,k),_.m(k,null),c(t,C),c(t,E),c(E,x),c(E,B),c(E,S),c(S,Q),I(Q,e[9]),c(S,F),c(S,D),I(D,e[10]),c(S,$),c(S,U),c(U,P),c(E,R),c(E,T),G.m(T,null),N||(O=[v(a,"input",e[43]),v(f,"input",e[44]),v(y,"click",e[25]),v(Q,"input",e[45]),v(D,"input",e[46]),v(U,"click",e[26])],N=!0)},p(e,t){64&t[0]&&a.value!==e[6]&&I(a,e[6]),128&t[0]&&f.value!==e[7]&&I(f,e[7]),4&t[0]&&(y.disabled=e[2]),L===(L=M(e))&&_?_.p(e,t):(_.d(1),_=L(e),_&&(_.c(),_.m(k,null))),512&t[0]&&Q.value!==e[9]&&I(Q,e[9]),1024&t[0]&&D.value!==e[10]&&I(D,e[10]),4&t[0]&&(U.disabled=e[2]),j===(j=H(e))&&G?G.p(e,t):(G.d(1),G=j(e),G&&(G.c(),G.m(T,null)))},d(e){e&&d(t),_.d(),G.d(),N=!1,r(O)}}}function Hh(t){let n;return{c(){n=p("div"),n.innerHTML="No banned pubkeys configured.
",A(n,"class","no-items svelte-1y8wjwc")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function jh(e){let t,n=e[5],r=[];for(let t=0;tNo allowed pubkeys configured.
",A(n,"class","no-items svelte-1y8wjwc")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function Vh(e){let t,n=e[8],r=[];for(let t=0;t0?Zh:Wh}let L=M(e),_=L(e);let H=function(e){return e[22]&&e[22].length>0?ng:tg}(e),j=H(e);return{c(){t=p("div"),n=p("div"),i=p("h3"),i.textContent="Banned Events",o=m(),s=p("div"),a=p("input"),l=m(),f=p("input"),h=m(),y=p("button"),w=g("Ban Event"),b=m(),k=p("div"),_.c(),C=m(),E=p("div"),x=p("h3"),x.textContent="Allowed Events",B=m(),S=p("div"),Q=p("input"),F=m(),D=p("input"),$=m(),U=p("button"),P=g("Allow Event"),R=m(),T=p("div"),j.c(),A(i,"class","svelte-1y8wjwc"),A(a,"type","text"),A(a,"placeholder","Event ID (64 hex chars)"),A(a,"class","svelte-1y8wjwc"),A(f,"type","text"),A(f,"placeholder","Reason (optional)"),A(f,"class","svelte-1y8wjwc"),y.disabled=e[2],A(y,"class","svelte-1y8wjwc"),A(s,"class","add-form svelte-1y8wjwc"),A(k,"class","list svelte-1y8wjwc"),A(n,"class","section svelte-1y8wjwc"),A(x,"class","svelte-1y8wjwc"),A(Q,"type","text"),A(Q,"placeholder","Event ID (64 hex chars)"),A(Q,"class","svelte-1y8wjwc"),A(D,"type","text"),A(D,"placeholder","Reason (optional)"),A(D,"class","svelte-1y8wjwc"),U.disabled=e[2],A(U,"class","svelte-1y8wjwc"),A(S,"class","add-form svelte-1y8wjwc"),A(T,"class","list svelte-1y8wjwc"),A(E,"class","section svelte-1y8wjwc"),A(t,"class","events-section")},m(r,d){u(r,t,d),c(t,n),c(n,i),c(n,o),c(n,s),c(s,a),I(a,e[12]),c(s,l),c(s,f),I(f,e[13]),c(s,h),c(s,y),c(y,w),c(n,b),c(n,k),_.m(k,null),c(t,C),c(t,E),c(E,x),c(E,B),c(E,S),c(S,Q),I(Q,e[14]),c(S,F),c(S,D),I(D,e[15]),c(S,$),c(S,U),c(U,P),c(E,R),c(E,T),j.m(T,null),N||(O=[v(a,"input",e[47]),v(f,"input",e[48]),v(y,"click",e[27]),v(Q,"input",e[49]),v(D,"input",e[50]),v(U,"click",e[28])],N=!0)},p(e,t){4096&t[0]&&a.value!==e[12]&&I(a,e[12]),8192&t[0]&&f.value!==e[13]&&I(f,e[13]),4&t[0]&&(y.disabled=e[2]),L===(L=M(e))&&_?_.p(e,t):(_.d(1),_=L(e),_&&(_.c(),_.m(k,null))),16384&t[0]&&Q.value!==e[14]&&I(Q,e[14]),32768&t[0]&&D.value!==e[15]&&I(D,e[15]),4&t[0]&&(U.disabled=e[2]),j.p(e,t)},d(e){e&&d(t),_.d(),j.d(),N=!1,r(O)}}}function Wh(t){let n;return{c(){n=p("div"),n.innerHTML="No banned events configured.
",A(n,"class","no-items svelte-1y8wjwc")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function Zh(e){let t,n=e[11],r=[];for(let t=0;tNo allowed events configured.",A(n,"class","no-items svelte-1y8wjwc")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function ng(e){let t,n=e[22],r=[];for(let t=0;t0?sg:og}let B=x(e),S=B(e);return{c(){t=p("div"),n=p("div"),i=p("h3"),i.textContent="Blocked IPs",o=m(),s=p("div"),a=p("input"),l=m(),f=p("input"),h=m(),y=p("button"),w=g("Block IP"),b=m(),k=p("div"),S.c(),A(i,"class","svelte-1y8wjwc"),A(a,"type","text"),A(a,"placeholder","IP Address"),A(a,"class","svelte-1y8wjwc"),A(f,"type","text"),A(f,"placeholder","Reason (optional)"),A(f,"class","svelte-1y8wjwc"),y.disabled=e[2],A(y,"class","svelte-1y8wjwc"),A(s,"class","add-form svelte-1y8wjwc"),A(k,"class","list svelte-1y8wjwc"),A(n,"class","section svelte-1y8wjwc"),A(t,"class","ips-section")},m(r,d){u(r,t,d),c(t,n),c(n,i),c(n,o),c(n,s),c(s,a),I(a,e[17]),c(s,l),c(s,f),I(f,e[18]),c(s,h),c(s,y),c(y,w),c(n,b),c(n,k),S.m(k,null),C||(E=[v(a,"input",e[51]),v(f,"input",e[52]),v(y,"click",e[29])],C=!0)},p(e,t){131072&t[0]&&a.value!==e[17]&&I(a,e[17]),262144&t[0]&&f.value!==e[18]&&I(f,e[18]),4&t[0]&&(y.disabled=e[2]),B===(B=x(e))&&S?S.p(e,t):(S.d(1),S=B(e),S&&(S.c(),S.m(k,null)))},d(e){e&&d(t),S.d(),C=!1,r(E)}}}function og(t){let n;return{c(){n=p("div"),n.innerHTML="No blocked IPs configured.
",A(n,"class","no-items svelte-1y8wjwc")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function sg(e){let t,n=e[16],r=[];for(let t=0;t0?dg:ug}let x=E(e),B=x(e);return{c(){t=p("div"),n=p("div"),i=p("h3"),i.textContent="Allowed Event Kinds",o=m(),s=p("div"),a=p("input"),l=m(),f=p("button"),h=g("Allow Kind"),y=m(),w=p("div"),B.c(),A(i,"class","svelte-1y8wjwc"),A(a,"type","number"),A(a,"placeholder","Kind number"),A(a,"class","svelte-1y8wjwc"),f.disabled=e[2],A(f,"class","svelte-1y8wjwc"),A(s,"class","add-form svelte-1y8wjwc"),A(w,"class","list svelte-1y8wjwc"),A(n,"class","section svelte-1y8wjwc"),A(t,"class","kinds-section")},m(r,d){u(r,t,d),c(t,n),c(n,i),c(n,o),c(n,s),c(s,a),I(a,e[20]),c(s,l),c(s,f),c(f,h),c(n,y),c(n,w),B.m(w,null),k||(C=[v(a,"input",e[53]),v(f,"click",e[30])],k=!0)},p(e,t){1048576&t[0]&&b(a.value)!==e[20]&&I(a,e[20]),4&t[0]&&(f.disabled=e[2]),x===(x=E(e))&&B?B.p(e,t):(B.d(1),B=x(e),B&&(B.c(),B.m(w,null)))},d(e){e&&d(t),B.d(),k=!1,r(C)}}}function ug(t){let n;return{c(){n=p("div"),n.innerHTML="No allowed kinds configured. All kinds are\n allowed by default.
",A(n,"class","no-items svelte-1y8wjwc")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function dg(e){let t,n=e[19],r=[];for(let t=0;t0?gg:hg}let w=y(e),b=w(e);return{c(){t=p("div"),n=p("div"),r=p("h3"),r.textContent="Events Needing Moderation",i=m(),o=p("button"),s=g("Refresh"),a=m(),l=p("div"),b.c(),A(r,"class","svelte-1y8wjwc"),o.disabled=e[2],A(l,"class","list svelte-1y8wjwc"),A(n,"class","section svelte-1y8wjwc"),A(t,"class","moderation-section")},m(d,p){u(d,t,p),c(t,n),c(n,r),c(n,i),c(n,o),c(o,s),c(n,a),c(n,l),b.m(l,null),f||(h=v(o,"click",e[24]),f=!0)},p(e,t){4&t[0]&&(o.disabled=e[2]),w===(w=y(e))&&b?b.p(e,t):(b.d(1),b=w(e),b&&(b.c(),b.m(l,null)))},d(e){e&&d(t),b.d(),f=!1,h()}}}function hg(t){let n;return{c(){n=p("div"),n.innerHTML="No events need moderation at this time.
",A(n,"class","no-items svelte-1y8wjwc")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function gg(e){let t,n=e[21],r=[];for(let t=0;tManaged ACL Configuration \n Configure access control using NIP-86 management API
\n Owner Only: This interface is restricted to relay owners\n only.
',o=m(),z&&z.c(),s=m(),a=p("div"),l=p("button"),f=g("Pubkeys"),y=m(),w=p("button"),b=g("Events"),I=m(),C=p("button"),E=g("IPs"),B=m(),S=p("button"),Q=g("Kinds"),D=m(),$=p("button"),U=g("Moderation"),R=m(),T=p("button"),N=g("Relay Config"),M=m(),L=p("div"),q&&q.c(),_=m(),Y&&Y.c(),H=m(),W&&W.c(),j=m(),Z&&Z.c(),G=m(),X&&X.c(),J=m(),ee&&ee.c(),A(i,"class","header svelte-1y8wjwc"),A(l,"class",h="tab "+("pubkeys"===t[1]?"active":"")+" svelte-1y8wjwc"),A(w,"class",k="tab "+("events"===t[1]?"active":"")+" svelte-1y8wjwc"),A(C,"class",x="tab "+("ips"===t[1]?"active":"")+" svelte-1y8wjwc"),A(S,"class",F="tab "+("kinds"===t[1]?"active":"")+" svelte-1y8wjwc"),A($,"class",P="tab "+("moderation"===t[1]?"active":"")+" svelte-1y8wjwc"),A(T,"class",O="tab "+("relay"===t[1]?"active":"")+" svelte-1y8wjwc"),A(a,"class","tabs svelte-1y8wjwc"),A(L,"class","tab-content svelte-1y8wjwc")},m(e,r){u(e,n,r),c(n,i),c(n,o),z&&z.m(n,null),c(n,s),c(n,a),c(a,l),c(l,f),c(a,y),c(a,w),c(w,b),c(a,I),c(a,C),c(C,E),c(a,B),c(a,S),c(S,Q),c(a,D),c(a,$),c($,U),c(a,R),c(a,T),c(T,N),c(n,M),c(n,L),q&&q.m(L,null),c(L,_),Y&&Y.m(L,null),c(L,H),W&&W.m(L,null),c(L,j),Z&&Z.m(L,null),c(L,G),X&&X.m(L,null),c(L,J),ee&&ee.m(L,null),K||(V=[v(l,"click",t[37]),v(w,"click",t[38]),v(C,"click",t[39]),v(S,"click",t[40]),v($,"click",t[41]),v(T,"click",t[42])],K=!0)},p(e,t){e[3]?z?z.p(e,t):(z=Lh(e),z.c(),z.m(n,s)):z&&(z.d(1),z=null),2&t[0]&&h!==(h="tab "+("pubkeys"===e[1]?"active":"")+" svelte-1y8wjwc")&&A(l,"class",h),2&t[0]&&k!==(k="tab "+("events"===e[1]?"active":"")+" svelte-1y8wjwc")&&A(w,"class",k),2&t[0]&&x!==(x="tab "+("ips"===e[1]?"active":"")+" svelte-1y8wjwc")&&A(C,"class",x),2&t[0]&&F!==(F="tab "+("kinds"===e[1]?"active":"")+" svelte-1y8wjwc")&&A(S,"class",F),2&t[0]&&P!==(P="tab "+("moderation"===e[1]?"active":"")+" svelte-1y8wjwc")&&A($,"class",P),2&t[0]&&O!==(O="tab "+("relay"===e[1]?"active":"")+" svelte-1y8wjwc")&&A(T,"class",O),"pubkeys"===e[1]?q?q.p(e,t):(q=_h(e),q.c(),q.m(L,_)):q&&(q.d(1),q=null),"events"===e[1]?Y?Y.p(e,t):(Y=Yh(e),Y.c(),Y.m(L,H)):Y&&(Y.d(1),Y=null),"ips"===e[1]?W?W.p(e,t):(W=ig(e),W.c(),W.m(L,j)):W&&(W.d(1),W=null),"kinds"===e[1]?Z?Z.p(e,t):(Z=cg(e),Z.c(),Z.m(L,G)):Z&&(Z.d(1),Z=null),"moderation"===e[1]?X?X.p(e,t):(X=pg(e),X.c(),X.m(L,J)):X&&(X.d(1),X=null),"relay"===e[1]?ee?ee.p(e,t):(ee=vg(e),ee.c(),ee.m(L,null)):ee&&(ee.d(1),ee=null)},i:e,o:e,d(e){e&&d(n),z&&z.d(),q&&q.d(),Y&&Y.d(),W&&W.d(),Z&&Z.d(),X&&X.d(),ee&&ee.d(),K=!1,r(V)}}}function kg(e,t,n){let{userSigner:r}=t,{userPubkey:i}=t,o="pubkeys",s=!1,a="",l="info",c=[],u="",d="",f=[],p="",h="",g=[],m="",y="",v="",w="",A=[],k="",I="",C=[],E="",x=[],B={relay_name:"",relay_description:"",relay_icon:""};async function S(){try{n(2,s=!0),console.log("Fetching relay info from /");const e=await fetch(window.location.origin+"/",{headers:{Accept:"application/nostr+json"}});if(console.log("Response status:",e.status),console.log("Response headers:",e.headers),e.ok){const t=await e.json();console.log("Raw relay info:",t),n(0,B={relay_name:t.name||"",relay_description:t.description||"",relay_icon:t.icon||""}),console.log("Updated relayConfig:",B),console.log("Loaded relay info:",t),n(3,a="Relay configuration loaded successfully"),n(4,l="success")}else console.error("Failed to fetch relay info, status:",e.status),n(3,a=`Failed to fetch relay info: ${e.status}`),n(4,l="error")}catch(e){console.error("Failed to fetch relay info:",e),n(3,a=`Failed to fetch relay info: ${e.message}`),n(4,l="error")}finally{n(2,s=!1)}}async function Q(e,t=[]){try{n(2,s=!0),n(3,a="");const o={method:e,params:t},l=await async function(e,t){if(!r)throw new Error("No signer available for authentication. Please log in with a Nostr extension.");if(!i)throw new Error("No user pubkey available for authentication.");const n=window.location.origin+t,o={kind:27235,created_at:Math.floor(Date.now()/1e3),tags:[["u",n],["method",e]],content:"",pubkey:i},s=await r.signEvent(o),a=JSON.stringify(s);return`Nostr ${btoa(a)}`}("POST","/api/nip86"),c=await fetch("/api/nip86",{method:"POST",headers:{"Content-Type":"application/nostr+json+rpc",Authorization:l},body:JSON.stringify(o)});if(!c.ok)throw new Error(`HTTP ${c.status}: ${c.statusText}`);const u=await c.json();if(u.error)throw new Error(u.error);return u.result}catch(e){throw console.error("NIP-86 API error:",e),n(3,a=e.message),n(4,l="error"),e}finally{n(2,s=!1)}}async function D(){try{n(5,c=await Q("listbannedpubkeys"))}catch(e){console.error("Failed to load banned pubkeys:",e)}}async function $(){try{n(8,f=await Q("listallowedpubkeys"))}catch(e){console.error("Failed to load allowed pubkeys:",e)}}async function U(){try{n(11,g=await Q("listbannedevents"))}catch(e){console.error("Failed to load banned events:",e)}}async function P(){try{n(16,A=await Q("listblockedips"))}catch(e){console.error("Failed to load blocked IPs:",e)}}async function R(){try{n(19,C=await Q("listallowedkinds"))}catch(e){console.error("Failed to load allowed kinds:",e)}}async function T(){try{n(2,s=!0),n(21,x=await Q("listeventsneedingmoderation")),console.log("Loaded events needing moderation:",x)}catch(e){console.error("Failed to load events needing moderation:",e),n(3,a=`Failed to load moderation events: ${e.message}`),n(4,l="error"),n(21,x=[])}finally{n(2,s=!1)}}async function N(e){try{await Q("disallowkind",[e]),n(3,a="Kind disallowed successfully"),n(4,l="success"),await R()}catch(e){console.error("Failed to disallow kind:",e)}}async function O(e){try{await Q("allowevent",[e,"Approved from moderation queue"]),n(3,a="Event allowed successfully"),n(4,l="success"),await T()}catch(e){console.error("Failed to allow event from moderation:",e)}}async function M(e){try{await Q("banevent",[e,"Banned from moderation queue"]),n(3,a="Event banned successfully"),n(4,l="success"),await T()}catch(e){console.error("Failed to ban event from moderation:",e)}}F(()=>{setTimeout(()=>{S()},100)}),async function(){await Promise.all([D(),$(),U(),P(),R()])}();return e.$$set=e=>{"userSigner"in e&&n(35,r=e.userSigner),"userPubkey"in e&&n(36,i=e.userPubkey)},e.$$.update=()=>{1&e.$$.dirty[0]&&console.log("relayConfig changed:",B)},[B,o,s,a,l,c,u,d,f,p,h,g,m,y,v,w,A,k,I,C,E,x,[],S,T,async function(){if(u)try{await Q("banpubkey",[u,d]),n(3,a="Pubkey banned successfully"),n(4,l="success"),n(6,u=""),n(7,d=""),await D()}catch(e){console.error("Failed to ban pubkey:",e)}},async function(){if(p)try{await Q("allowpubkey",[p,h]),n(3,a="Pubkey allowed successfully"),n(4,l="success"),n(9,p=""),n(10,h=""),await $()}catch(e){console.error("Failed to allow pubkey:",e)}},async function(){if(m)try{await Q("banevent",[m,y]),n(3,a="Event banned successfully"),n(4,l="success"),n(12,m=""),n(13,y=""),await U()}catch(e){console.error("Failed to ban event:",e)}},async function(){if(v)try{await Q("allowevent",[v,w]),n(3,a="Event allowed successfully"),n(4,l="success"),n(14,v=""),n(15,w="")}catch(e){console.error("Failed to allow event:",e)}},async function(){if(k)try{await Q("blockip",[k,I]),n(3,a="IP blocked successfully"),n(4,l="success"),n(17,k=""),n(18,I=""),await P()}catch(e){console.error("Failed to block IP:",e)}},async function(){if(!E)return;const e=parseInt(E);if(isNaN(e))return n(3,a="Invalid kind number"),void n(4,l="error");try{await Q("allowkind",[e]),n(3,a="Kind allowed successfully"),n(4,l="success"),n(20,E=""),await R()}catch(e){console.error("Failed to allow kind:",e)}},N,async function(){try{n(2,s=!0),n(3,a="");const e=[];if(B.relay_name&&e.push(Q("changerelayname",[B.relay_name])),B.relay_description&&e.push(Q("changerelaydescription",[B.relay_description])),B.relay_icon&&e.push(Q("changerelayicon",[B.relay_icon])),0===e.length)return n(3,a="No changes to update"),void n(4,l="info");await Promise.all(e),n(3,a="Relay configuration updated successfully"),n(4,l="success"),await S()}catch(e){console.error("Failed to update relay configuration:",e),n(3,a=`Failed to update relay configuration: ${e.message}`),n(4,l="error")}finally{n(2,s=!1)}},O,M,r,i,()=>n(1,o="pubkeys"),()=>n(1,o="events"),()=>n(1,o="ips"),()=>n(1,o="kinds"),()=>{n(1,o="moderation"),x&&0!==x.length||T()},()=>n(1,o="relay"),function(){u=this.value,n(6,u)},function(){d=this.value,n(7,d)},function(){p=this.value,n(9,p)},function(){h=this.value,n(10,h)},function(){m=this.value,n(12,m)},function(){y=this.value,n(13,y)},function(){v=this.value,n(14,v)},function(){w=this.value,n(15,w)},function(){k=this.value,n(17,k)},function(){I=this.value,n(18,I)},function(){E=b(this.value),n(20,E)},e=>N(e),e=>O(e.id),e=>M(e.id),function(){B.relay_name=this.value,n(0,B)},function(){B.relay_description=this.value,n(0,B)},function(){B.relay_icon=this.value,n(0,B)}]}class Ig extends ie{constructor(e){super(),re(this,e,kg,bg,o,{userSigner:35,userPubkey:36},null,[-1,-1,-1])}}function Cg(e){let t,n;return{c(){t=p("span"),n=g(e[3]),A(t,"class","permission-badge svelte-1qkhxam")},m(e,r){u(e,t,r),c(t,n)},p(e,t){8&t&&k(n,e[3])},d(e){e&&d(t)}}}function Eg(t){let n,r,i;return{c(){n=p("button"),n.textContent="Log in",A(n,"class","login-btn svelte-1qkhxam")},m(e,o){u(e,n,o),r||(i=v(n,"click",t[7]),r=!0)},p:e,d(e){e&&d(n),r=!1,i()}}}function xg(e){let t,n,r,i,o,s,a=(e[4]?.name||e[5])+"";function l(e,t){return e[4]?.picture?Sg:Bg}let f=l(e),h=f(e);return{c(){t=p("button"),h.c(),n=m(),r=p("span"),i=g(a),A(r,"class","user-name svelte-1qkhxam"),A(t,"class","user-profile-btn svelte-1qkhxam")},m(a,l){u(a,t,l),h.m(t,null),c(t,n),c(t,r),c(r,i),o||(s=v(t,"click",e[6]),o=!0)},p(e,r){f===(f=l(e))&&h?h.p(e,r):(h.d(1),h=f(e),h&&(h.c(),h.m(t,n))),48&r&&a!==(a=(e[4]?.name||e[5])+"")&&k(i,a)},d(e){e&&d(t),h.d(),o=!1,s()}}}function Bg(t){let n;return{c(){n=p("div"),n.textContent="👤",A(n,"class","user-avatar-placeholder svelte-1qkhxam")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function Sg(e){let t,n;return{c(){t=p("img"),a(t.src,n=e[4].picture)||A(t,"src",n),A(t,"alt","User avatar"),A(t,"class","user-avatar svelte-1qkhxam")},m(e,n){u(e,t,n)},p(e,r){16&r&&!a(t.src,n=e[4].picture)&&A(t,"src",n)},d(e){e&&d(t)}}}function Qg(t){let n,r,i,o,s,l,f,h,y,v,w=t[1]&&t[2]&&Cg(t);function b(e,t){return e[1]?xg:Eg}let k=b(t),I=k(t);return{c(){n=p("header"),r=p("div"),i=p("img"),s=m(),l=p("div"),f=p("span"),h=g("ORLY? dashboard\n "),w&&w.c(),y=m(),v=p("div"),I.c(),a(i.src,o="/orly.png")||A(i,"src","/orly.png"),A(i,"alt","ORLY Logo"),A(i,"class","logo svelte-1qkhxam"),A(f,"class","app-title svelte-1qkhxam"),A(l,"class","header-title svelte-1qkhxam"),A(v,"class","header-buttons svelte-1qkhxam"),A(r,"class","header-content svelte-1qkhxam"),A(n,"class","main-header svelte-1qkhxam"),x(n,"dark-theme",t[0])},m(e,t){u(e,n,t),c(n,r),c(r,i),c(r,s),c(r,l),c(l,f),c(f,h),w&&w.m(f,null),c(r,y),c(r,v),I.m(v,null)},p(e,[t]){e[1]&&e[2]?w?w.p(e,t):(w=Cg(e),w.c(),w.m(f,null)):w&&(w.d(1),w=null),k===(k=b(e))&&I?I.p(e,t):(I.d(1),I=k(e),I&&(I.c(),I.m(v,null))),1&t&&x(n,"dark-theme",e[0])},i:e,o:e,d(e){e&&d(n),w&&w.d(),I.d()}}}function Fg(e,t,n){let{isDarkTheme:r=!1}=t,{isLoggedIn:i=!1}=t,{userRole:o=""}=t,{currentEffectiveRole:s=""}=t,{userProfile:a=null}=t,{userPubkey:l=""}=t;const c=$();return e.$$set=e=>{"isDarkTheme"in e&&n(0,r=e.isDarkTheme),"isLoggedIn"in e&&n(1,i=e.isLoggedIn),"userRole"in e&&n(2,o=e.userRole),"currentEffectiveRole"in e&&n(3,s=e.currentEffectiveRole),"userProfile"in e&&n(4,a=e.userProfile),"userPubkey"in e&&n(5,l=e.userPubkey)},[r,i,o,s,a,l,function(){c("openSettingsDrawer")},function(){c("openLoginModal")}]}class Dg extends ie{constructor(e){super(),re(this,e,Fg,Qg,o,{isDarkTheme:0,isLoggedIn:1,userRole:2,currentEffectiveRole:3,userProfile:4,userPubkey:5})}}function $g(e,t,n){const r=e.slice();return r[10]=t[n],r}function Ug(e){let t,n,i;function o(){return e[6](e[10])}function s(...t){return e[7](e[10],...t)}return{c(){t=p("span"),t.textContent="✕",A(t,"class","tab-close-icon svelte-wfmuj"),A(t,"role","button"),A(t,"tabindex","0")},m(e,r){u(e,t,r),n||(i=[v(t,"click",w(o)),v(t,"keydown",s)],n=!0)},p(t,n){e=t},d(e){e&&d(t),n=!1,r(i)}}}function Pg(e){let t,n,r,i,o,s,a,l,f,h,y=e[10].icon+"",w=e[10].label+"",b=e[10].isSearchTab&&Ug(e);function I(){return e[8](e[10])}return{c(){t=p("button"),n=p("span"),r=g(y),i=m(),o=p("span"),s=g(w),a=m(),b&&b.c(),l=m(),A(n,"class","tab-icon svelte-wfmuj"),A(o,"class","tab-label svelte-wfmuj"),A(t,"class","tab svelte-wfmuj"),x(t,"active",e[2]===e[10].id)},m(e,d){u(e,t,d),c(t,n),c(n,r),c(t,i),c(t,o),c(o,s),c(t,a),b&&b.m(t,null),c(t,l),f||(h=v(t,"click",I),f=!0)},p(n,i){e=n,2&i&&y!==(y=e[10].icon+"")&&k(r,y),2&i&&w!==(w=e[10].label+"")&&k(s,w),e[10].isSearchTab?b?b.p(e,i):(b=Ug(e),b.c(),b.m(t,l)):b&&(b.d(1),b=null),6&i&&x(t,"active",e[2]===e[10].id)},d(e){e&&d(t),b&&b.d(),f=!1,h()}}}function Rg(e){let t,n,r,i,o,s,a,l;return{c(){t=p("a"),n=h("svg"),r=h("path"),i=h("path"),o=m(),s=p("span"),a=g("v"),l=g(e[3]),A(r,"d","M5 6h12v2h1.5c1.38 0 2.5 1.12 2.5 2.5v1c0 1.38-1.12 2.5-2.5 2.5H17v1c0 1.66-1.34 3-3 3H8c-1.66 0-3-1.34-3-3V6zm12 6h1.5c.28 0 .5-.22.5-.5v-1c0-.28-.22-.5-.5-.5H17v2z"),A(i,"d","M9 9c1.5 0 3 .5 3 2.5S10.5 14 9 14c0-1.5.5-3.5 2-4.5"),A(i,"stroke","currentColor"),A(i,"stroke-width","1"),A(i,"fill","none"),A(n,"class","version-icon svelte-wfmuj"),A(n,"viewBox","0 0 24 24"),A(n,"fill","currentColor"),A(n,"xmlns","http://www.w3.org/2000/svg"),A(s,"class","version-text svelte-wfmuj"),A(t,"href","https://next.orly.dev"),A(t,"target","_blank"),A(t,"rel","noopener noreferrer"),A(t,"class","version-link svelte-wfmuj")},m(e,d){u(e,t,d),c(t,n),c(n,r),c(n,i),c(t,o),c(t,s),c(s,a),c(s,l)},p(e,t){8&t&&k(l,e[3])},d(e){e&&d(t)}}}function Tg(t){let n,r,i,o,s=t[1],a=[];for(let e=0;e{"isDarkTheme"in e&&n(0,r=e.isDarkTheme),"tabs"in e&&n(1,i=e.tabs),"selectedTab"in e&&n(2,o=e.selectedTab),"version"in e&&n(3,s=e.version)},[r,i,o,s,l,c,e=>c(e.id),(e,t)=>"Enter"===t.key&&c(e.id),e=>l(e.id)]}class Og extends ie{constructor(e){super(),re(this,e,Ng,Tg,o,{isDarkTheme:0,tabs:1,selectedTab:2,version:3})}}function Mg(t){let n,r,i,o,s,a;return{c(){n=p("div"),r=p("p"),r.textContent="Please log in to access export functionality.",i=m(),o=p("button"),o.textContent="Log In",A(r,"class","svelte-jzrdtj"),A(o,"class","login-btn svelte-jzrdtj"),A(n,"class","login-prompt svelte-jzrdtj")},m(e,l){u(e,n,l),c(n,r),c(n,i),c(n,o),s||(a=v(o,"click",t[5]),s=!0)},p:e,d(e){e&&d(n),s=!1,a()}}}function Lg(e){let t,n,r=e[0]&&_g(e),i=e[1]&&Hg(e);return{c(){r&&r.c(),t=m(),i&&i.c(),n=y()},m(e,o){r&&r.m(e,o),u(e,t,o),i&&i.m(e,o),u(e,n,o)},p(e,o){e[0]?r?r.p(e,o):(r=_g(e),r.c(),r.m(t.parentNode,t)):r&&(r.d(1),r=null),e[1]?i?i.p(e,o):(i=Hg(e),i.c(),i.m(n.parentNode,n)):i&&(i.d(1),i=null)},d(e){r&&r.d(e),e&&d(t),i&&i.d(e),e&&d(n)}}}function _g(t){let n,r,i,o,s,a,l,f;return{c(){n=p("div"),r=p("h3"),r.textContent="Export My Events",i=m(),o=p("p"),o.textContent="Download your personal events as a JSONL file.",s=m(),a=p("button"),a.textContent="📤 Export My Events",A(r,"class","svelte-jzrdtj"),A(o,"class","svelte-jzrdtj"),A(a,"class","export-btn svelte-jzrdtj"),A(n,"class","export-section svelte-jzrdtj")},m(e,d){u(e,n,d),c(n,r),c(n,i),c(n,o),c(n,s),c(n,a),l||(f=v(a,"click",t[3]),l=!0)},p:e,d(e){e&&d(n),l=!1,f()}}}function Hg(t){let n,r,i,o,s,a,l,f;return{c(){n=p("div"),r=p("h3"),r.textContent="Export All Events",i=m(),o=p("p"),o.textContent="Download the complete database as a JSONL file. This includes\n all events from all users.",s=m(),a=p("button"),a.textContent="📤 Export All Events",A(r,"class","svelte-jzrdtj"),A(o,"class","svelte-jzrdtj"),A(a,"class","export-btn svelte-jzrdtj"),A(n,"class","export-section svelte-jzrdtj")},m(e,d){u(e,n,d),c(n,r),c(n,i),c(n,o),c(n,s),c(n,a),l||(f=v(a,"click",t[4]),l=!0)},p:e,d(e){e&&d(n),l=!1,f()}}}function jg(t){let n;function r(e,t){return e[2]?Lg:Mg}let i=r(t),o=i(t);return{c(){o.c(),n=y()},m(e,t){o.m(e,t),u(e,n,t)},p(e,[t]){i===(i=r(e))&&o?o.p(e,t):(o.d(1),o=i(e),o&&(o.c(),o.m(n.parentNode,n)))},i:e,o:e,d(e){o.d(e),e&&d(n)}}}function Gg(e,t,n){let r,i,{isLoggedIn:o=!1}=t,{currentEffectiveRole:s=""}=t,{aclMode:a=""}=t;const l=$();return e.$$set=e=>{"isLoggedIn"in e&&n(0,o=e.isLoggedIn),"currentEffectiveRole"in e&&n(6,s=e.currentEffectiveRole),"aclMode"in e&&n(7,a=e.aclMode)},e.$$.update=()=>{129&e.$$.dirty&&n(2,r="none"===a||o),192&e.$$.dirty&&n(1,i="none"===a||"admin"===s||"owner"===s)},[o,i,r,function(){l("exportMyEvents")},function(){l("exportAllEvents")},function(){l("openLoginModal")},s,a]}class Jg extends ie{constructor(e){super(),re(this,e,Gg,jg,o,{isLoggedIn:0,currentEffectiveRole:6,aclMode:7})}}function Kg(t){let n,r,i,o,s,a,l,f;return{c(){n=p("div"),r=p("h3"),r.textContent="Import Events",i=m(),o=p("p"),o.textContent="Please log in to access import functionality.",s=m(),a=p("button"),a.textContent="Log In",A(r,"class","recovery-header svelte-nonyqh"),A(o,"class","recovery-description svelte-nonyqh"),A(a,"class","login-btn svelte-nonyqh"),A(n,"class","login-prompt svelte-nonyqh")},m(e,d){u(e,n,d),c(n,r),c(n,i),c(n,o),c(n,s),c(n,a),l||(f=v(a,"click",t[6]),l=!0)},p:e,d(e){e&&d(n),l=!1,f()}}}function Vg(t){let n;return{c(){n=p("div"),n.innerHTML=' \n Admin or owner permission required for import functionality.
',A(n,"class","permission-denied svelte-nonyqh")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function zg(e){let t,n,i,o,s,a,l,f,h,y,w,b,k,I,C=e[2]&&qg(e);return{c(){t=p("h3"),t.textContent="Import Events",n=m(),i=p("p"),i.textContent="Upload a JSONL file to import events into the database.",o=m(),s=p("div"),a=p("input"),l=m(),f=p("div"),h=p("button"),y=g("Import Events"),b=m(),C&&C.c(),A(t,"class","svelte-nonyqh"),A(i,"class","svelte-nonyqh"),A(a,"type","file"),A(a,"id","import-file"),A(a,"accept",".jsonl,.txt"),A(a,"class","svelte-nonyqh"),A(h,"class","import-btn svelte-nonyqh"),h.disabled=w=!e[1]||"Uploading..."===e[2],A(f,"class","import-row svelte-nonyqh"),A(s,"class","recovery-controls-card svelte-nonyqh")},m(r,d){u(r,t,d),u(r,n,d),u(r,i,d),u(r,o,d),u(r,s,d),c(s,a),c(s,l),c(s,f),c(f,h),c(h,y),c(f,b),C&&C.m(f,null),k||(I=[v(a,"change",e[4]),v(h,"click",e[5])],k=!0)},p(e,t){6&t&&w!==(w=!e[1]||"Uploading..."===e[2])&&(h.disabled=w),e[2]?C?C.p(e,t):(C=qg(e),C.c(),C.m(f,null)):C&&(C.d(1),C=null)},d(e){e&&d(t),e&&d(n),e&&d(i),e&&d(o),e&&d(s),C&&C.d(),k=!1,r(I)}}}function qg(e){let t,n;return{c(){t=p("span"),n=g(e[2]),A(t,"class","import-message svelte-nonyqh"),x(t,"uploading","Uploading..."===e[2]),x(t,"success","Upload complete"===e[2]),x(t,"error",e[2].startsWith("Import failed")||e[2].startsWith("Admin")||e[2].startsWith("Please"))},m(e,r){u(e,t,r),c(t,n)},p(e,r){4&r&&k(n,e[2]),4&r&&x(t,"uploading","Uploading..."===e[2]),4&r&&x(t,"success","Upload complete"===e[2]),4&r&&x(t,"error",e[2].startsWith("Import failed")||e[2].startsWith("Admin")||e[2].startsWith("Please"))},d(e){e&&d(t)}}}function Yg(t){let n;function r(e,t){return e[3]?zg:e[0]?Vg:Kg}let i=r(t),o=i(t);return{c(){n=p("div"),o.c(),A(n,"class","import-section svelte-nonyqh")},m(e,t){u(e,n,t),o.m(n,null)},p(e,[t]){i===(i=r(e))&&o?o.p(e,t):(o.d(1),o=i(e),o&&(o.c(),o.m(n,null)))},i:e,o:e,d(e){e&&d(n),o.d()}}}function Wg(e,t,n){let r,{isLoggedIn:i=!1}=t,{currentEffectiveRole:o=""}=t,{selectedFile:s=null}=t,{aclMode:a=""}=t,{importMessage:l=""}=t;const c=$();return e.$$set=e=>{"isLoggedIn"in e&&n(0,i=e.isLoggedIn),"currentEffectiveRole"in e&&n(7,o=e.currentEffectiveRole),"selectedFile"in e&&n(1,s=e.selectedFile),"aclMode"in e&&n(8,a=e.aclMode),"importMessage"in e&&n(2,l=e.importMessage)},e.$$.update=()=>{385&e.$$.dirty&&n(3,r="none"===a||i&&("admin"===o||"owner"===o))},[i,s,l,r,function(e){c("fileSelect",e)},function(){c("importEvents")},function(){c("openLoginModal")},o,a]}class Zg extends ie{constructor(e){super(),re(this,e,Wg,Yg,o,{isLoggedIn:0,currentEffectiveRole:7,selectedFile:1,aclMode:8,importMessage:2})}}const Xg={0:"Profile Metadata",1:"Text Note",2:"Recommend Relay",3:"Contacts",4:"Encrypted DM",5:"Delete Request",6:"Repost",7:"Reaction",8:"Badge Award",16:"Generic Repost",40:"Channel Creation",41:"Channel Metadata",42:"Channel Message",43:"Channel Hide Message",44:"Channel Mute User",1063:"File Metadata",1311:"Live Chat Message",1984:"Reporting",1985:"Label",9734:"Zap Request",9735:"Zap Receipt",1e4:"Mute List",10001:"Pin List",10002:"Relay List Metadata",10003:"Bookmark List",10004:"Communities List",10005:"Public Chats List",10006:"Blocked Relays List",10007:"Search Relays List",10009:"User Groups",10015:"Interests List",10030:"User Emoji List",13194:"Wallet Info",22242:"Client Auth",23194:"Wallet Request",23195:"Wallet Response",24133:"Nostr Connect",27235:"HTTP Auth",3e4:"Categorized People List",30001:"Categorized Bookmarks",30002:"Categorized Relay List",30003:"Bookmark Sets",30004:"Curation Sets",30005:"Video Sets",30008:"Profile Badges",30009:"Badge Definition",30015:"Interest Sets",30017:"Create/Update Stall",30018:"Create/Update Product",30019:"Marketplace UI/UX",30020:"Product Sold As Auction",30023:"Long-form Content",30024:"Draft Long-form Content",30030:"Emoji Sets",30063:"Release Artifact Sets",30078:"Application-specific Data",30311:"Live Event",30315:"User Statuses",30388:"Slide Set",30402:"Classified Listing",30403:"Draft Classified Listing",30617:"Repository Announcement",30618:"Repository State Announcement",30818:"Wiki Article",30819:"Redirects",31922:"Date-Based Calendar Event",31923:"Time-Based Calendar Event",31924:"Calendar",31925:"Calendar Event RSVP",31989:"Handler Recommendation",31990:"Handler Information",34550:"Community Definition",34551:"Community Post Approval"};function em(e,t=null){if(!e||"string"!=typeof e)return!1;return!!/^[0-9a-fA-F]+$/.test(e)&&(!t||e.length===t)}function tm(e){const t=new Date(1e3*e);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")}T${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`}function nm(e){return Math.floor(new Date(e).getTime()/1e3)}function rm(e,t,n){const r=e.slice();return r[62]=t[n],r[64]=n,r}function im(e,t,n){const r=e.slice();return r[65]=t[n],r}function om(e,t,n){const r=e.slice();return r[68]=t[n],r}function sm(e,t,n){const r=e.slice();return r[71]=t[n],r}function am(e,t,n){const r=e.slice();return r[71]=t[n].kind,r[74]=t[n].name,r}function lm(e){let t,n,r,i,o,s,a=e[20],l=[];for(let t=0;t0&&um(t),Ge=t[17]&&fm(t),Je=t[2].length>0&&pm(t),Ke=t[18]&&gm(t),Ve=t[3].length>0&&mm(t),ze=t[19]&&vm(t),qe=t[4].length>0&&wm(t),Ye=t[5]&&bm(t),We=t[6]&&km(t),Ze=t[8]&&Im(t);return{c(){n=p("div"),i=p("div"),o=p("div"),s=p("label"),s.textContent="Search Text (NIP-50)",a=m(),l=p("div"),f=p("input"),h=m(),y=p("label"),y.textContent="Event Kinds",w=m(),C=p("div"),E=p("button"),B=g(Le),S=g(" Select Kinds ("),Q=g(_e),F=g(" selected)"),D=m(),He&&He.c(),$=m(),je&&je.c(),U=m(),P=p("label"),P.textContent="Authors (Pubkeys)",R=m(),T=p("div"),N=p("div"),O=p("input"),M=m(),L=p("button"),L.textContent="Add",_=m(),Ge&&Ge.c(),H=m(),Je&&Je.c(),j=m(),G=p("label"),G.textContent="Event IDs",J=m(),K=p("div"),V=p("div"),z=p("input"),q=m(),Y=p("button"),Y.textContent="Add",W=m(),Ke&&Ke.c(),Z=m(),Ve&&Ve.c(),X=m(),ee=p("label"),ee.textContent="Tags (#e, #p, #a)",te=m(),ne=p("div"),re=p("div"),ie=p("span"),ie.textContent="#",oe=m(),se=p("input"),ae=m(),le=p("input"),ce=m(),ue=p("button"),ue.textContent="Add",de=m(),ze&&ze.c(),fe=m(),qe&&qe.c(),pe=m(),he=p("label"),he.textContent="Since",ge=m(),me=p("div"),ye=p("input"),ve=m(),Ye&&Ye.c(),we=m(),Ae=p("label"),Ae.textContent="Until",be=m(),ke=p("div"),Ie=p("input"),Ce=m(),We&&We.c(),Ee=m(),xe=p("label"),xe.textContent="Limit",Be=m(),Se=p("div"),Qe=p("input"),Fe=m(),Ze&&Ze.c(),De=m(),$e=p("div"),Ue=p("button"),Ue.textContent="🧹",Pe=m(),Re=p("div"),Te=m(),Ne=p("button"),Ne.textContent=">",A(s,"for","search-text"),A(s,"class","svelte-1a1v6k0"),A(f,"id","search-text"),A(f,"type","text"),A(f,"placeholder","Search events..."),A(f,"class","filter-input svelte-1a1v6k0"),A(l,"class","field-content svelte-1a1v6k0"),A(y,"class","svelte-1a1v6k0"),A(E,"class","picker-toggle-btn svelte-1a1v6k0"),A(C,"class","field-content svelte-1a1v6k0"),A(P,"class","svelte-1a1v6k0"),A(O,"type","text"),A(O,"placeholder","64 character hex pubkey..."),A(O,"class","filter-input svelte-1a1v6k0"),A(O,"maxlength","64"),A(L,"class","add-btn svelte-1a1v6k0"),A(N,"class","input-group svelte-1a1v6k0"),A(T,"class","field-content svelte-1a1v6k0"),A(G,"class","svelte-1a1v6k0"),A(z,"type","text"),A(z,"placeholder","64 character hex event ID..."),A(z,"class","filter-input svelte-1a1v6k0"),A(z,"maxlength","64"),A(Y,"class","add-btn svelte-1a1v6k0"),A(V,"class","input-group svelte-1a1v6k0"),A(K,"class","field-content svelte-1a1v6k0"),A(ee,"class","svelte-1a1v6k0"),A(ie,"class","hash-prefix svelte-1a1v6k0"),A(se,"type","text"),A(se,"placeholder","Tag"),A(se,"class","filter-input tag-name-input svelte-1a1v6k0"),A(se,"maxlength","1"),A(le,"type","text"),A(le,"placeholder","Value..."),A(le,"class","filter-input tag-value-input svelte-1a1v6k0"),A(ue,"class","add-btn svelte-1a1v6k0"),A(re,"class","tag-input-group svelte-1a1v6k0"),A(ne,"class","field-content svelte-1a1v6k0"),A(he,"for","since-timestamp"),A(he,"class","svelte-1a1v6k0"),A(ye,"id","since-timestamp"),A(ye,"type","datetime-local"),ye.value=t[32](),A(ye,"class","filter-input svelte-1a1v6k0"),A(me,"class","field-content timestamp-field svelte-1a1v6k0"),A(Ae,"for","until-timestamp"),A(Ae,"class","svelte-1a1v6k0"),A(Ie,"id","until-timestamp"),A(Ie,"type","datetime-local"),Ie.value=t[33](),A(Ie,"class","filter-input svelte-1a1v6k0"),A(ke,"class","field-content timestamp-field svelte-1a1v6k0"),A(xe,"for","limit"),A(xe,"class","svelte-1a1v6k0"),A(Qe,"id","limit"),A(Qe,"type","number"),A(Qe,"placeholder","Max events to return"),A(Qe,"class","filter-input svelte-1a1v6k0"),A(Qe,"min","1"),A(Se,"class","field-content svelte-1a1v6k0"),A(o,"class","filter-grid svelte-1a1v6k0"),A(i,"class","filter-content svelte-1a1v6k0"),A(Ue,"class","clear-all-btn svelte-1a1v6k0"),A(Ue,"title","Clear all filters"),A(Re,"class","spacer svelte-1a1v6k0"),A(Ne,"class","json-toggle-btn svelte-1a1v6k0"),A(Ne,"title","Edit filter JSON"),x(Ne,"active",t[8]),A($e,"class","clear-column svelte-1a1v6k0"),A(n,"class","filter-builder svelte-1a1v6k0")},m(e,r){u(e,n,r),c(n,i),c(i,o),c(o,s),c(o,a),c(o,l),c(l,f),I(f,t[0]),c(o,h),c(o,y),c(o,w),c(o,C),c(C,E),c(E,B),c(E,S),c(E,Q),c(E,F),c(C,D),He&&He.m(C,null),c(C,$),je&&je.m(C,null),c(o,U),c(o,P),c(o,R),c(o,T),c(T,N),c(N,O),I(O,t[13]),c(N,M),c(N,L),c(T,_),Ge&&Ge.m(T,null),c(T,H),Je&&Je.m(T,null),c(o,j),c(o,G),c(o,J),c(o,K),c(K,V),c(V,z),I(z,t[14]),c(V,q),c(V,Y),c(K,W),Ke&&Ke.m(K,null),c(K,Z),Ve&&Ve.m(K,null),c(o,X),c(o,ee),c(o,te),c(o,ne),c(ne,re),c(re,ie),c(re,oe),c(re,se),I(se,t[15]),c(re,ae),c(re,le),I(le,t[16]),c(re,ce),c(re,ue),c(ne,de),ze&&ze.m(ne,null),c(ne,fe),qe&&qe.m(ne,null),c(o,pe),c(o,he),c(o,ge),c(o,me),c(me,ye),c(me,ve),Ye&&Ye.m(me,null),c(o,we),c(o,Ae),c(o,be),c(o,ke),c(ke,Ie),c(ke,Ce),We&&We.m(ke,null),c(o,Ee),c(o,xe),c(o,Be),c(o,Se),c(Se,Qe),I(Qe,t[7]),c(o,Fe),Ze&&Ze.m(o,null),c(n,De),c(n,$e),c($e,Ue),c($e,Pe),c($e,Re),c($e,Te),c($e,Ne),Oe||(Me=[v(f,"input",t[38]),v(E,"click",t[39]),v(O,"input",t[43]),v(O,"keydown",t[44]),v(L,"click",t[25]),v(z,"input",t[46]),v(z,"keydown",t[47]),v(Y,"click",t[27]),v(se,"input",t[49]),v(le,"input",t[50]),v(le,"keydown",t[51]),v(ue,"click",t[29]),v(ye,"change",t[34]),v(Ie,"change",t[35]),v(Qe,"input",t[55]),v(Ue,"click",t[31]),v(Ne,"click",t[57])],Oe=!0)},p(e,t){1&t[0]&&f.value!==e[0]&&I(f,e[0]),4096&t[0]&&Le!==(Le=e[12]?"▼":"▶")&&k(B,Le),2&t[0]&&_e!==(_e=e[1].length+"")&&k(Q,_e),e[12]?He?He.p(e,t):(He=lm(e),He.c(),He.m(C,$)):He&&(He.d(1),He=null),e[1].length>0?je?je.p(e,t):(je=um(e),je.c(),je.m(C,null)):je&&(je.d(1),je=null),8192&t[0]&&O.value!==e[13]&&I(O,e[13]),e[17]?Ge?Ge.p(e,t):(Ge=fm(e),Ge.c(),Ge.m(T,H)):Ge&&(Ge.d(1),Ge=null),e[2].length>0?Je?Je.p(e,t):(Je=pm(e),Je.c(),Je.m(T,null)):Je&&(Je.d(1),Je=null),16384&t[0]&&z.value!==e[14]&&I(z,e[14]),e[18]?Ke?Ke.p(e,t):(Ke=gm(e),Ke.c(),Ke.m(K,Z)):Ke&&(Ke.d(1),Ke=null),e[3].length>0?Ve?Ve.p(e,t):(Ve=mm(e),Ve.c(),Ve.m(K,null)):Ve&&(Ve.d(1),Ve=null),32768&t[0]&&se.value!==e[15]&&I(se,e[15]),65536&t[0]&&le.value!==e[16]&&I(le,e[16]),e[19]?ze?ze.p(e,t):(ze=vm(e),ze.c(),ze.m(ne,fe)):ze&&(ze.d(1),ze=null),e[4].length>0?qe?qe.p(e,t):(qe=wm(e),qe.c(),qe.m(ne,null)):qe&&(qe.d(1),qe=null),e[5]?Ye?Ye.p(e,t):(Ye=bm(e),Ye.c(),Ye.m(me,null)):Ye&&(Ye.d(1),Ye=null),e[6]?We?We.p(e,t):(We=km(e),We.c(),We.m(ke,null)):We&&(We.d(1),We=null),128&t[0]&&b(Qe.value)!==e[7]&&I(Qe,e[7]),e[8]?Ze?Ze.p(e,t):(Ze=Im(e),Ze.c(),Ze.m(o,null)):Ze&&(Ze.d(1),Ze=null),256&t[0]&&x(Ne,"active",e[8])},i:e,o:e,d(e){e&&d(n),He&&He.d(),je&&je.d(),Ge&&Ge.d(),Je&&Je.d(),Ke&&Ke.d(),Ve&&Ve.d(),ze&&ze.d(),qe&&qe.d(),Ye&&Ye.d(),We&&We.d(),Ze&&Ze.d(),Oe=!1,r(Me)}}}function xm(e,t,n){let r,i;const o=$();let{searchText:s=""}=t,{selectedKinds:a=[]}=t,{pubkeys:l=[]}=t,{eventIds:c=[]}=t,{tags:u=[]}=t,{sinceTimestamp:d=null}=t,{untilTimestamp:f=null}=t,{limit:p=null}=t,{showJsonEditor:h=!1}=t,g="",m="",y=!1,v="",w="",A="",k="",I="",C="",E="",x="",B=null,S=!1;function Q(e){a.includes(e)?n(1,a=a.filter(t=>t!==e)):n(1,a=[...a,e].sort((e,t)=>e-t))}function F(e){n(1,a=a.filter(t=>t!==e))}function U(){const e=w.trim();e&&(em(e,64)?l.includes(e)?n(17,C="Pubkey already added"):(n(2,l=[...l,e]),n(13,w=""),n(17,C="")):n(17,C="Invalid pubkey: must be 64 character hex string"))}function P(e){n(2,l=l.filter(t=>t!==e))}function R(){const e=A.trim();e&&(em(e,64)?c.includes(e)?n(18,E="Event ID already added"):(n(3,c=[...c,e]),n(14,A=""),n(18,E="")):n(18,E="Invalid event ID: must be 64 character hex string"))}function T(e){n(3,c=c.filter(t=>t!==e))}function N(){const e=k.trim(),t=I.trim();e&&t&&(/^[a-zA-Z]$/.test(e)?u.some(n=>n.name===e&&n.value===t)?n(19,x="Tag already added"):(n(4,u=[...u,{name:e,value:t}]),n(15,k=""),n(16,I=""),n(19,x="")):n(19,x="Invalid tag name: must be single letter a-z or A-Z"))}function O(e){n(4,u=u.filter((t,n)=>n!==e))}function M(){o("apply",{searchText:s,selectedKinds:a,pubkeys:l,eventIds:c,tags:u,sinceTimestamp:d,untilTimestamp:f,limit:p})}D(()=>{B&&clearTimeout(B)});return e.$$set=e=>{"searchText"in e&&n(0,s=e.searchText),"selectedKinds"in e&&n(1,a=e.selectedKinds),"pubkeys"in e&&n(2,l=e.pubkeys),"eventIds"in e&&n(3,c=e.eventIds),"tags"in e&&n(4,u=e.tags),"sinceTimestamp"in e&&n(5,d=e.sinceTimestamp),"untilTimestamp"in e&&n(6,f=e.untilTimestamp),"limit"in e&&n(7,p=e.limit),"showJsonEditor"in e&&n(8,h=e.showJsonEditor)},e.$$.update=()=>{if(256&e.$$.dirty[0]&&h){const e=function(){const e={};return a.length>0&&(e.kinds=a),l.length>0&&(e.authors=l),c.length>0&&(e.ids=c),d&&(e.since=d),f&&(e.until=f),p&&(e.limit=p),s&&(e.search=s),u.forEach(t=>{const n=`#${t.name}`;e[n]||(e[n]=[]),e[n].push(t.value)}),e}();n(10,g=JSON.stringify(e,null,2))}255&e.$$.dirty[0]|32&e.$$.dirty[1]&&(S?(B&&clearTimeout(B),B=setTimeout(()=>{M()},1e3)):n(36,S=!0)),512&e.$$.dirty[0]|64&e.$$.dirty[1]&&n(20,i=r.filter(e=>e.kind.toString().includes(v)||e.name.toLowerCase().includes(v.toLowerCase())))},n(37,r=Object.entries(Xg).map(([e,t])=>({kind:parseInt(e),name:t})).sort((e,t)=>e.kind-t.kind)),[s,a,l,c,u,d,f,p,h,v,g,m,y,w,A,k,I,C,E,x,i,o,function(){try{const e=JSON.parse(g);n(11,m=""),n(1,a=e.kinds||[]),n(2,l=e.authors||[]),n(3,c=e.ids||[]),n(5,d=e.since||null),n(6,f=e.until||null),n(7,p=e.limit||null),n(0,s=e.search||""),n(4,u=[]),Object.keys(e).forEach(t=>{if(t.startsWith("#")&&2===t.length){const n=t.slice(1);(Array.isArray(e[t])?e[t]:[e[t]]).forEach(e=>{u.push({name:n,value:String(e)})})}}),n(4,u),B&&clearTimeout(B),M()}catch(e){n(11,m="Invalid JSON: "+e.message)}},Q,F,U,P,R,T,N,O,function(){n(0,s=""),n(1,a=[]),n(2,l=[]),n(3,c=[]),n(4,u=[]),n(5,d=null),n(6,f=null),n(7,p=null),o("clear")},function(){return d?tm(d):""},function(){return f?tm(f):""},function(e){const t=e.target.value;n(5,d=t?nm(t):null)},function(e){const t=e.target.value;n(6,f=t?nm(t):null)},S,r,function(){s=this.value,n(0,s)},()=>n(12,y=!y),function(){v=this.value,n(9,v)},e=>Q(e),e=>F(e),function(){w=this.value,n(13,w)},e=>"Enter"===e.key&&U(),e=>P(e),function(){A=this.value,n(14,A)},e=>"Enter"===e.key&&R(),e=>T(e),function(){k=this.value,n(15,k)},function(){I=this.value,n(16,I)},e=>"Enter"===e.key&&N(),e=>O(e),()=>n(5,d=null),()=>n(6,f=null),function(){p=b(this.value),n(7,p)},function(){g=this.value,n(10,g),n(8,h)},()=>o("toggleJson")]}class Bm extends ie{constructor(e){super(),re(this,e,xm,Em,o,{searchText:0,selectedKinds:1,pubkeys:2,eventIds:3,tags:4,sinceTimestamp:5,untilTimestamp:6,limit:7,showJsonEditor:8},null,[-1,-1,-1])}}function Sm(e,t,n){const r=e.slice();return r[28]=t[n],r}function Qm(e,t,n){const r=e.slice();return r[31]=t[n],r}function Fm(t){let n;return{c(){n=p("div"),n.innerHTML="❌ Read, write, admin, or owner permission required to view all\n events.
",A(n,"class","permission-denied svelte-5kb1ec")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function Dm(e){let t,n,r,i;function o(e,t){return e[4].length>0?Um:e[6]?void 0:$m}let s=o(e),a=s&&s(e),l=e[6]&&_m();return{c(){t=p("div"),a&&a.c(),n=m(),l&&l.c(),A(t,"class","events-view-content svelte-5kb1ec")},m(o,s){u(o,t,s),a&&a.m(t,null),c(t,n),l&&l.m(t,null),r||(i=v(t,"scroll",e[9]),r=!0)},p(e,r){s===(s=o(e))&&a?a.p(e,r):(a&&a.d(1),a=s&&s(e),a&&(a.c(),a.m(t,n))),e[6]?l||(l=_m(),l.c(),l.m(t,null)):l&&(l.d(1),l=null)},d(e){e&&d(t),a&&a.d(),l&&l.d(),r=!1,i()}}}function $m(t){let n;return{c(){n=p("div"),n.innerHTML="No events found.
",A(n,"class","no-events svelte-5kb1ec")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function Um(e){let t,n=e[4],r=[];for(let t=0;t0&&Tm(e);return{c(){t=p("div"),n=p("span"),n.textContent="🗑️ Delete Event",r=m(),i&&i.c(),A(n,"class","delete-event-label svelte-5kb1ec"),A(t,"class","delete-event-info svelte-5kb1ec")},m(e,o){u(e,t,o),c(t,n),c(t,r),i&&i.m(t,null)},p(e,n){e[28].tags&&e[28].tags.length>0?i?i.p(e,n):(i=Tm(e),i.c(),i.m(t,null)):i&&(i.d(1),i=null)},d(e){e&&d(t),i&&i.d()}}}function Tm(e){let t,n=e[28].tags.filter(Ym),r=[];for(let t=0;t👤',o=m(),s=p("div"),a=p("div"),l=g(T),f=m(),h=p("div"),y=p("span"),w=g(N),b=m(),I=p("span"),C=g(O),E=m(),B=p("div"),S=p("div"),Q=g(M),F=m(),j.c(),D=m(),G&&G.c(),$=m(),V&&V.c(),U=m(),A(i,"class","events-view-avatar svelte-5kb1ec"),A(a,"class","events-view-author svelte-5kb1ec"),A(y,"class","kind-number svelte-5kb1ec"),x(y,"delete-event",5===e[28].kind),A(I,"class","kind-name svelte-5kb1ec"),A(h,"class","events-view-kind svelte-5kb1ec"),A(s,"class","events-view-info svelte-5kb1ec"),A(S,"class","event-timestamp svelte-5kb1ec"),A(B,"class","events-view-content svelte-5kb1ec"),A(n,"class","events-view-row svelte-5kb1ec"),A(n,"role","button"),A(n,"tabindex","0"),A(t,"class","events-view-item svelte-5kb1ec"),x(t,"expanded",e[5].has(e[28].id))},m(e,r){u(e,t,r),c(t,n),c(n,i),c(n,o),c(n,s),c(s,a),c(a,l),c(s,f),c(s,h),c(h,y),c(y,w),c(h,b),c(h,I),c(I,C),c(n,E),c(n,B),c(B,S),c(S,Q),c(B,F),j.m(B,null),c(n,D),G&&G.m(n,null),c(t,$),V&&V.m(t,null),c(t,U),P||(R=[v(n,"click",J),v(n,"keydown",K)],P=!0)},p(r,i){e=r,16&i[0]&&T!==(T=Km(e[28].pubkey)+"")&&k(l,T),16&i[0]&&N!==(N=e[28].kind+"")&&k(w,N),16&i[0]&&x(y,"delete-event",5===e[28].kind),16&i[0]&&O!==(O=Vm(e[28].kind)+"")&&k(C,O),16&i[0]&&M!==(M=zm(e[28].created_at)+"")&&k(Q,M),H===(H=_(e))&&j?j.p(e,i):(j.d(1),j=H(e),j&&(j.c(),j.m(B,null))),5!==e[28].kind&&("admin"===e[2]||"owner"===e[2]||"write"===e[2]&&e[28].pubkey&&e[28].pubkey===e[3])?G?G.p(e,i):(G=Om(e),G.c(),G.m(n,null)):G&&(G.d(1),G=null),48&i[0]&&(L=e[5].has(e[28].id)),L?V?V.p(e,i):(V=Mm(e),V.c(),V.m(t,U)):V&&(V.d(1),V=null),48&i[0]&&x(t,"expanded",e[5].has(e[28].id))},d(e){e&&d(t),j.d(),G&&G.d(),V&&V.d(),P=!1,r(R)}}}function _m(e){let t;return{c(){t=p("div"),t.innerHTML='
\n Loading events...
',A(t,"class","loading-events svelte-5kb1ec")},m(e,n){u(e,t,n)},d(e){e&&d(t)}}}function Hm(e){let t,n,i,o,s,a,l,f,h,y,w,b,k,I,C,E,B,S,Q,F,D,$,U,P;function R(e,t){return e[6]?Gm:jm}i=new Bm({props:{showJsonEditor:e[8]}}),i.$on("apply",e[17]),i.$on("clear",e[18]),i.$on("toggleJson",e[16]);let T=R(e),N=T(e);return{c(){t=p("div"),n=p("div"),X(i.$$.fragment),o=m(),s=p("div"),a=p("div"),l=p("button"),l.innerHTML=' ',f=m(),h=p("div"),y=p("label"),w=p("input"),b=m(),k=p("span"),I=m(),C=p("span"),C.textContent="Only show my events",E=m(),B=p("div"),S=p("button"),Q=g("🔄 Load More"),F=m(),D=p("button"),N.c(),A(n,"class","filter-panel svelte-5kb1ec"),x(n,"open",e[7]),A(l,"class","filter-btn svelte-5kb1ec"),A(l,"title","Filter events"),x(l,"active",e[7]),A(w,"type","checkbox"),A(w,"class","svelte-5kb1ec"),A(k,"class","toggle-slider svelte-5kb1ec"),A(C,"class","toggle-label svelte-5kb1ec"),A(y,"class","toggle-container svelte-5kb1ec"),A(h,"class","events-view-toggle svelte-5kb1ec"),A(a,"class","events-view-left svelte-5kb1ec"),A(S,"class","refresh-btn svelte-5kb1ec"),S.disabled=e[6],A(D,"class","reload-btn svelte-5kb1ec"),D.disabled=e[6],A(B,"class","events-view-buttons svelte-5kb1ec"),A(s,"class","events-view-header svelte-5kb1ec"),A(t,"class","events-view-footer svelte-5kb1ec")},m(r,d){u(r,t,d),c(t,n),ee(i,n,null),c(t,o),c(t,s),c(s,a),c(a,l),c(a,f),c(a,h),c(h,y),c(y,w),w.checked=e[0],c(y,b),c(y,k),c(y,I),c(y,C),c(s,E),c(s,B),c(B,S),c(S,Q),c(B,F),c(B,D),N.m(D,null),$=!0,U||(P=[v(l,"click",e[15]),v(w,"change",e[23]),v(w,"change",e[24]),v(S,"click",e[25]),v(D,"click",e[26])],U=!0)},p(e,t){const r={};256&t[0]&&(r.showJsonEditor=e[8]),i.$set(r),(!$||128&t[0])&&x(n,"open",e[7]),(!$||128&t[0])&&x(l,"active",e[7]),1&t[0]&&(w.checked=e[0]),(!$||64&t[0])&&(S.disabled=e[6]),T!==(T=R(e))&&(N.d(1),N=T(e),N&&(N.c(),N.m(D,null))),(!$||64&t[0])&&(D.disabled=e[6])},i(e){$||(Y(i.$$.fragment,e),$=!0)},o(e){W(i.$$.fragment,e),$=!1},d(e){e&&d(t),te(i),N.d(),U=!1,r(P)}}}function jm(e){let t;return{c(){t=g("🔄")},m(e,n){u(e,t,n)},d(e){e&&d(t)}}}function Gm(e){let t;return{c(){t=p("div"),A(t,"class","spinner svelte-5kb1ec")},m(e,n){u(e,t,n)},d(e){e&&d(t)}}}function Jm(e){let t,n,r;function i(e,t){return!e[1]||"read"!==e[2]&&"write"!==e[2]&&"admin"!==e[2]&&"owner"!==e[2]?Fm:Dm}let o=i(e),s=o(e),a=e[1]&&("read"===e[2]||"write"===e[2]||"admin"===e[2]||"owner"===e[2])&&Hm(e);return{c(){t=p("div"),s.c(),n=m(),a&&a.c(),A(t,"class","events-view-container svelte-5kb1ec")},m(e,i){u(e,t,i),s.m(t,null),c(t,n),a&&a.m(t,null),r=!0},p(e,r){o===(o=i(e))&&s?s.p(e,r):(s.d(1),s=o(e),s&&(s.c(),s.m(t,n))),!e[1]||"read"!==e[2]&&"write"!==e[2]&&"admin"!==e[2]&&"owner"!==e[2]?a&&(z(),W(a,1,1,()=>{a=null}),q()):a?(a.p(e,r),6&r[0]&&Y(a,1)):(a=Hm(e),a.c(),Y(a,1),a.m(t,null))},i(e){r||(Y(a),r=!0)},o(e){W(a),r=!1},d(e){e&&d(t),s.d(),a&&a.d()}}}function Km(e){return e?e.slice(0,8)+"..."+e.slice(-8):""}function Vm(e){return{0:"Profile",1:"Text Note",2:"Recommend Relay",3:"Contacts",4:"Encrypted DM",5:"Delete",6:"Repost",7:"Reaction",8:"Badge Award",16:"Generic Repost",40:"Channel Creation",41:"Channel Metadata",42:"Channel Message",43:"Channel Hide Message",44:"Channel Mute User",1984:"Reporting",9734:"Zap Request",9735:"Zap",1e4:"Mute List",10001:"Pin List",10002:"Relay List",22242:"Client Auth",24133:"Nostr Connect",27235:"HTTP Auth",3e4:"Categorized People",30001:"Categorized Bookmarks",30008:"Profile Badges",30009:"Badge Definition",30017:"Create or update a stall",30018:"Create or update a product",30023:"Long-form Content",30024:"Draft Long-form Content",30078:"Application-specific Data",30311:"Live Event",30315:"User Statuses",30402:"Classified Listing",30403:"Draft Classified Listing",31922:"Date-Based Calendar Event",31923:"Time-Based Calendar Event",31924:"Calendar",31925:"Calendar Event RSVP",31989:"Handler recommendation",31990:"Handler information",34550:"Community Definition"}[e]||`Kind ${e}`}function zm(e){return new Date(1e3*e).toLocaleString()}function qm(e){return e?e.length>100?e.slice(0,100)+"...":e:""}const Ym=e=>"e"===e[0];function Wm(e,t,n){let{isLoggedIn:r=!1}=t,{userRole:i=""}=t,{userPubkey:o=""}=t,{filteredEvents:s=[]}=t,{expandedEvents:a=new Set}=t,{isLoadingEvents:l=!1}=t,{showOnlyMyEvents:c=!1}=t,{showFilterBuilder:u=!1}=t;const d=$();let f=!1;function p(e){d("toggleEventExpansion",e)}function h(e){d("deleteEvent",e)}function g(e,t){d("copyEventToClipboard",{event:e,e:t})}function m(){d("toggleChange")}function y(e,t){d("loadAllEvents",{refresh:e,authors:t})}return e.$$set=e=>{"isLoggedIn"in e&&n(1,r=e.isLoggedIn),"userRole"in e&&n(2,i=e.userRole),"userPubkey"in e&&n(3,o=e.userPubkey),"filteredEvents"in e&&n(4,s=e.filteredEvents),"expandedEvents"in e&&n(5,a=e.expandedEvents),"isLoadingEvents"in e&&n(6,l=e.isLoadingEvents),"showOnlyMyEvents"in e&&n(0,c=e.showOnlyMyEvents),"showFilterBuilder"in e&&n(7,u=e.showFilterBuilder)},[c,r,i,o,s,a,l,u,f,function(e){d("scroll",e)},p,h,g,m,y,function(){d("toggleFilterBuilder")},function(){n(8,f=!f)},function(e){d("filterApply",e.detail)},function(){d("filterClear")},e=>h(e.id),e=>p(e.id),(e,t)=>"Enter"===t.key&&p(e.id),(e,t)=>g(e,t),function(){c=this.checked,n(0,c)},()=>m(),()=>{y(!1,c&&o?[o]:null)},()=>{y(!0,c&&o?[o]:null)}]}class Zm extends ie{constructor(e){super(),re(this,e,Wm,Jm,o,{isLoggedIn:1,userRole:2,userPubkey:3,filteredEvents:4,expandedEvents:5,isLoadingEvents:6,showOnlyMyEvents:0,showFilterBuilder:7},null,[-1,-1])}}const Xm=[{kind:0,name:"Metadata",description:"User profile information (name, about, picture, nip05, etc.)",nip:"01",isReplaceable:!0,template:{kind:0,content:"",tags:[]}},{kind:1,name:"Short Text Note",description:"Short-form text post (like a tweet)",nip:"01",template:{kind:1,content:"",tags:[]}},{kind:2,name:"Recommend Relay",description:"Relay recommendation",nip:"01",deprecated:!0,template:{kind:2,content:"",tags:[]}},{kind:3,name:"Follows",description:"Following list with optional relay hints",nip:"02",isReplaceable:!0,template:{kind:3,content:"",tags:[]}},{kind:4,name:"Encrypted Direct Message",description:"Private message using NIP-04 encryption",nip:"04",deprecated:!0,template:{kind:4,content:"",tags:[]}},{kind:5,name:"Event Deletion Request",description:"Request to delete events",nip:"09",template:{kind:5,content:"",tags:[]}},{kind:6,name:"Repost",description:"Share/repost another text note",nip:"18",template:{kind:6,content:"",tags:[]}},{kind:7,name:"Reaction",description:"Like, emoji reaction to an event",nip:"25",template:{kind:7,content:"",tags:[]}},{kind:8,name:"Badge Award",description:"Award a badge to someone",nip:"58",template:{kind:8,content:"",tags:[]}},{kind:9,name:"Chat Message",description:"Chat message",nip:"C7",template:{kind:9,content:"",tags:[]}},{kind:10,name:"Group Chat Threaded Reply",description:"Threaded reply in group chat",nip:"29",deprecated:!0,template:{kind:10,content:"",tags:[]}},{kind:11,name:"Thread",description:"Thread event",nip:"7D",template:{kind:11,content:"",tags:[]}},{kind:12,name:"Group Thread Reply",description:"Reply in group thread",nip:"29",deprecated:!0,template:{kind:12,content:"",tags:[]}},{kind:13,name:"Seal",description:"Sealed/encrypted event wrapper",nip:"59",template:{kind:13,content:"",tags:[]}},{kind:14,name:"Direct Message",description:"Private direct message using NIP-17",nip:"17",template:{kind:14,content:"",tags:[]}},{kind:15,name:"File Message",description:"File message in DMs",nip:"17",template:{kind:15,content:"",tags:[]}},{kind:16,name:"Generic Repost",description:"Repost any event kind",nip:"18",template:{kind:16,content:"",tags:[]}},{kind:17,name:"Reaction to Website",description:"Reaction to a website URL",nip:"25",template:{kind:17,content:"",tags:[]}},{kind:20,name:"Picture",description:"Picture-first feed post",nip:"68",template:{kind:20,content:"",tags:[]}},{kind:21,name:"Video Event",description:"Horizontal video event",nip:"71",template:{kind:21,content:"",tags:[]}},{kind:22,name:"Short-form Video",description:"Short-form portrait video (like TikTok)",nip:"71",template:{kind:22,content:"",tags:[]}},{kind:40,name:"Channel Creation",description:"Create a public chat channel",nip:"28",template:{kind:40,content:"",tags:[]}},{kind:41,name:"Channel Metadata",description:"Set channel name, about, picture",nip:"28",template:{kind:41,content:"",tags:[]}},{kind:42,name:"Channel Message",description:"Post message in channel",nip:"28",template:{kind:42,content:"",tags:[]}},{kind:43,name:"Channel Hide Message",description:"Hide a message in channel",nip:"28",template:{kind:43,content:"",tags:[]}},{kind:44,name:"Channel Mute User",description:"Mute a user in channel",nip:"28",template:{kind:44,content:"",tags:[]}},{kind:62,name:"Request to Vanish",description:"Request permanent deletion of all user data",nip:"62",template:{kind:62,content:"",tags:[]}},{kind:64,name:"Chess (PGN)",description:"Chess game in PGN format",nip:"64",template:{kind:64,content:"",tags:[]}},{kind:443,name:"KeyPackage",description:"Marmot protocol key package",nip:null,spec:"Marmot",template:{kind:443,content:"",tags:[]}},{kind:444,name:"Welcome Message",description:"Marmot protocol welcome message",nip:null,spec:"Marmot",template:{kind:444,content:"",tags:[]}},{kind:445,name:"Group Event",description:"Marmot protocol group event",nip:null,spec:"Marmot",template:{kind:445,content:"",tags:[]}},{kind:818,name:"Merge Requests",description:"Git merge request",nip:"54",template:{kind:818,content:"",tags:[]}},{kind:1018,name:"Poll Response",description:"Response to a poll",nip:"88",template:{kind:1018,content:"",tags:[]}},{kind:1021,name:"Bid",description:"Auction bid",nip:"15",template:{kind:1021,content:"",tags:[]}},{kind:1022,name:"Bid Confirmation",description:"Confirmation of auction bid",nip:"15",template:{kind:1022,content:"",tags:[]}},{kind:1040,name:"OpenTimestamps",description:"OpenTimestamps attestation",nip:"03",template:{kind:1040,content:"",tags:[]}},{kind:1059,name:"Gift Wrap",description:"Encrypted gift-wrapped event",nip:"59",template:{kind:1059,content:"",tags:[]}},{kind:1060,name:"Gift Wrap (Kind 4)",description:"Gift wrap variant for NIP-04 compatibility",nip:"59",template:{kind:1060,content:"",tags:[]}},{kind:1063,name:"File Metadata",description:"Metadata for shared files",nip:"94",template:{kind:1063,content:"",tags:[]}},{kind:1068,name:"Poll",description:"Create a poll",nip:"88",template:{kind:1068,content:"",tags:[]}},{kind:1111,name:"Comment",description:"Comment on events or external content",nip:"22",template:{kind:1111,content:"",tags:[]}},{kind:1222,name:"Voice Message",description:"Voice message",nip:"A0",template:{kind:1222,content:"",tags:[]}},{kind:1244,name:"Voice Message Comment",description:"Comment on voice message",nip:"A0",template:{kind:1244,content:"",tags:[]}},{kind:1311,name:"Live Chat Message",description:"Message in live stream chat",nip:"53",template:{kind:1311,content:"",tags:[]}},{kind:1337,name:"Code Snippet",description:"Code snippet post",nip:"C0",template:{kind:1337,content:"",tags:[]}},{kind:1517,name:"Bitcoin Block",description:"Bitcoin block data",nip:null,spec:"Nostrocket",template:{kind:1517,content:"",tags:[]}},{kind:1617,name:"Patches",description:"Git patches",nip:"34",template:{kind:1617,content:"",tags:[]}},{kind:1618,name:"Pull Requests",description:"Git pull request",nip:"34",template:{kind:1618,content:"",tags:[]}},{kind:1619,name:"Pull Request Updates",description:"Updates to git pull request",nip:"34",template:{kind:1619,content:"",tags:[]}},{kind:1621,name:"Issues",description:"Git issues",nip:"34",template:{kind:1621,content:"",tags:[]}},{kind:1622,name:"Git Replies",description:"Replies on git objects",nip:"34",deprecated:!0,template:{kind:1622,content:"",tags:[]}},{kind:1630,name:"Status",description:"Git status",nip:"34",template:{kind:1630,content:"",tags:[]}},{kind:1631,name:"Status",description:"Git status",nip:"34",template:{kind:1631,content:"",tags:[]}},{kind:1632,name:"Status",description:"Git status",nip:"34",template:{kind:1632,content:"",tags:[]}},{kind:1633,name:"Status",description:"Git status",nip:"34",template:{kind:1633,content:"",tags:[]}},{kind:1808,name:"Live Stream",description:"Live streaming event",nip:null,spec:"zap.stream",template:{kind:1808,content:"",tags:[]}},{kind:1971,name:"Problem Tracker",description:"Problem tracking",nip:null,spec:"Nostrocket",template:{kind:1971,content:"",tags:[]}},{kind:1984,name:"Reporting",description:"Report content or users",nip:"56",template:{kind:1984,content:"",tags:[]}},{kind:1985,name:"Label",description:"Label/tag content with namespace",nip:"32",template:{kind:1985,content:"",tags:[]}},{kind:1986,name:"Relay Reviews",description:"Reviews of relays",nip:null,template:{kind:1986,content:"",tags:[]}},{kind:1987,name:"AI Embeddings",description:"AI embeddings/vector lists",nip:null,spec:"NKBIP-02",template:{kind:1987,content:"",tags:[]}},{kind:2003,name:"Torrent",description:"Torrent magnet link",nip:"35",template:{kind:2003,content:"",tags:[]}},{kind:2004,name:"Torrent Comment",description:"Comment on torrent",nip:"35",template:{kind:2004,content:"",tags:[]}},{kind:2022,name:"Coinjoin Pool",description:"Coinjoin coordination",nip:null,spec:"joinstr",template:{kind:2022,content:"",tags:[]}},{kind:4550,name:"Community Post Approval",description:"Approve post in community",nip:"72",template:{kind:4550,content:"",tags:[]}},{kind:5e3,name:"Job Request",description:"Data vending machine job request (start of range)",nip:"90",template:{kind:5e3,content:"",tags:[]}},{kind:6e3,name:"Job Result",description:"Data vending machine job result (start of range)",nip:"90",template:{kind:6e3,content:"",tags:[]}},{kind:7e3,name:"Job Feedback",description:"Feedback on job request/result",nip:"90",template:{kind:7e3,content:"",tags:[]}},{kind:7374,name:"Reserved Cashu Wallet Tokens",description:"Reserved Cashu wallet tokens",nip:"60",template:{kind:7374,content:"",tags:[]}},{kind:7375,name:"Cashu Wallet Tokens",description:"Cashu wallet tokens",nip:"60",template:{kind:7375,content:"",tags:[]}},{kind:7376,name:"Cashu Wallet History",description:"Cashu wallet transaction history",nip:"60",template:{kind:7376,content:"",tags:[]}},{kind:7516,name:"Geocache Log",description:"Geocaching log entry",nip:null,spec:"geocaching",template:{kind:7516,content:"",tags:[]}},{kind:7517,name:"Geocache Proof of Find",description:"Proof of geocache find",nip:null,spec:"geocaching",template:{kind:7517,content:"",tags:[]}},{kind:8e3,name:"Add User",description:"Add user to group",nip:"43",template:{kind:8e3,content:"",tags:[]}},{kind:8001,name:"Remove User",description:"Remove user from group",nip:"43",template:{kind:8001,content:"",tags:[]}},{kind:9e3,name:"Group Control Events",description:"Group control events (start of range)",nip:"29",template:{kind:9e3,content:"",tags:[]}},{kind:9041,name:"Zap Goal",description:"Fundraising goal for zaps",nip:"75",template:{kind:9041,content:"",tags:[]}},{kind:9321,name:"Nutzap",description:"Cashu nutzap",nip:"61",template:{kind:9321,content:"",tags:[]}},{kind:9467,name:"Tidal Login",description:"Tidal streaming login",nip:null,spec:"Tidal-nostr",template:{kind:9467,content:"",tags:[]}},{kind:9734,name:"Zap Request",description:"Request Lightning payment",nip:"57",template:{kind:9734,content:"",tags:[]}},{kind:9735,name:"Zap",description:"Lightning payment receipt",nip:"57",template:{kind:9735,content:"",tags:[]}},{kind:9802,name:"Highlights",description:"Highlighted text selection",nip:"84",template:{kind:9802,content:"",tags:[]}},{kind:1e4,name:"Mute List",description:"List of muted users/content",nip:"51",isReplaceable:!0,template:{kind:1e4,content:"",tags:[]}},{kind:10001,name:"Pin List",description:"Pinned events",nip:"51",isReplaceable:!0,template:{kind:10001,content:"",tags:[]}},{kind:10002,name:"Relay List Metadata",description:"User's preferred relays for read/write",nip:"65",isReplaceable:!0,template:{kind:10002,content:"",tags:[]}},{kind:10003,name:"Bookmark List",description:"Bookmarked events",nip:"51",isReplaceable:!0,template:{kind:10003,content:"",tags:[]}},{kind:10004,name:"Communities List",description:"Communities user belongs to",nip:"51",isReplaceable:!0,template:{kind:10004,content:"",tags:[]}},{kind:10005,name:"Public Chats List",description:"Public chats user is in",nip:"51",isReplaceable:!0,template:{kind:10005,content:"",tags:[]}},{kind:10006,name:"Blocked Relays List",description:"Relays user has blocked",nip:"51",isReplaceable:!0,template:{kind:10006,content:"",tags:[]}},{kind:10007,name:"Search Relays List",description:"Preferred search relays",nip:"51",isReplaceable:!0,template:{kind:10007,content:"",tags:[]}},{kind:10008,name:"Relay Group Configuration",description:"Relay group configuration",nip:null,isReplaceable:!0,template:{kind:10008,content:"",tags:[]}},{kind:10009,name:"User Groups",description:"Groups user belongs to",nip:"29",isReplaceable:!0,template:{kind:10009,content:"",tags:[]}},{kind:10012,name:"Favorite Relays List",description:"User's favorite relays",nip:"51",isReplaceable:!0,template:{kind:10012,content:"",tags:[]}},{kind:10013,name:"Private Event Relay List",description:"Relays for private events",nip:"37",isReplaceable:!0,template:{kind:10013,content:"",tags:[]}},{kind:10015,name:"Interests List",description:"User interests/topics",nip:"51",isReplaceable:!0,template:{kind:10015,content:"",tags:[]}},{kind:10019,name:"Nutzap Mint Recommendation",description:"Recommended Cashu mints for nutzaps",nip:"61",isReplaceable:!0,template:{kind:10019,content:"",tags:[]}},{kind:10020,name:"Media Follows",description:"Followed media accounts",nip:"51",isReplaceable:!0,template:{kind:10020,content:"",tags:[]}},{kind:10030,name:"User Emoji List",description:"Custom emoji list",nip:"51",isReplaceable:!0,template:{kind:10030,content:"",tags:[]}},{kind:10050,name:"DM Relays List",description:"Relays to receive DMs on",nip:"17",isReplaceable:!0,template:{kind:10050,content:"",tags:[]}},{kind:10051,name:"KeyPackage Relays List",description:"Marmot key package relays",nip:null,isReplaceable:!0,spec:"Marmot",template:{kind:10051,content:"",tags:[]}},{kind:10063,name:"User Server List",description:"Blossom server list",nip:null,isReplaceable:!0,spec:"Blossom",template:{kind:10063,content:"",tags:[]}},{kind:10096,name:"File Storage Server List",description:"File storage servers",nip:"96",isReplaceable:!0,deprecated:!0,template:{kind:10096,content:"",tags:[]}},{kind:10166,name:"Relay Monitor Announcement",description:"Relay monitoring announcement",nip:"66",isReplaceable:!0,template:{kind:10166,content:"",tags:[]}},{kind:10312,name:"Room Presence",description:"Presence in live room",nip:"53",isReplaceable:!0,template:{kind:10312,content:"",tags:[]}},{kind:10377,name:"Proxy Announcement",description:"Nostr proxy announcement",nip:null,isReplaceable:!0,spec:"Nostr Epoxy",template:{kind:10377,content:"",tags:[]}},{kind:11111,name:"Transport Method Announcement",description:"Transport method announcement",nip:null,isReplaceable:!0,spec:"Nostr Epoxy",template:{kind:11111,content:"",tags:[]}},{kind:12345,name:"Relay Policy Configuration",description:"Relay-internal policy configuration (admin only)",nip:null,isReplaceable:!0,spec:"orly",template:{kind:12345,content:"",tags:[]}},{kind:13004,name:"JWT Binding",description:"Link between JWT certificate and pubkey",nip:null,isReplaceable:!0,template:{kind:13004,content:"",tags:[]}},{kind:13194,name:"Wallet Service Info",description:"NWC wallet service information",nip:"47",isReplaceable:!0,template:{kind:13194,content:"",tags:[]}},{kind:13534,name:"Membership Lists",description:"Group membership lists",nip:"43",isReplaceable:!0,template:{kind:13534,content:"",tags:[]}},{kind:14388,name:"User Sound Effect Lists",description:"Sound effect lists",nip:null,isReplaceable:!0,spec:"Corny Chat",template:{kind:14388,content:"",tags:[]}},{kind:17375,name:"Cashu Wallet Event",description:"Cashu wallet event",nip:"60",isReplaceable:!0,template:{kind:17375,content:"",tags:[]}},{kind:21e3,name:"Lightning Pub RPC",description:"Lightning.Pub RPC",nip:null,isEphemeral:!0,spec:"Lightning.Pub",template:{kind:21e3,content:"",tags:[]}},{kind:22242,name:"Client Authentication",description:"Authenticate to relay",nip:"42",isEphemeral:!0,template:{kind:22242,content:"",tags:[]}},{kind:23194,name:"Wallet Request",description:"NWC wallet request",nip:"47",isEphemeral:!0,template:{kind:23194,content:"",tags:[]}},{kind:23195,name:"Wallet Response",description:"NWC wallet response",nip:"47",isEphemeral:!0,template:{kind:23195,content:"",tags:[]}},{kind:23196,name:"Wallet Notification (NIP-04)",description:"NWC wallet notification (NIP-04 encrypted)",nip:"47",isEphemeral:!0,template:{kind:23196,content:"",tags:[]}},{kind:23197,name:"Wallet Notification",description:"NWC wallet notification",nip:"47",isEphemeral:!0,template:{kind:23197,content:"",tags:[]}},{kind:24133,name:"Nostr Connect",description:"Remote signer connection",nip:"46",isEphemeral:!0,template:{kind:24133,content:"",tags:[]}},{kind:24242,name:"Blobs Stored on Mediaservers",description:"Blossom blob storage",nip:null,isEphemeral:!0,spec:"Blossom",template:{kind:24242,content:"",tags:[]}},{kind:27235,name:"HTTP Auth",description:"Authenticate HTTP requests",nip:"98",isEphemeral:!0,template:{kind:27235,content:"",tags:[]}},{kind:28934,name:"Join Request",description:"Request to join group",nip:"43",isEphemeral:!0,template:{kind:28934,content:"",tags:[]}},{kind:28935,name:"Invite Request",description:"Invite to group",nip:"43",isEphemeral:!0,template:{kind:28935,content:"",tags:[]}},{kind:28936,name:"Leave Request",description:"Leave group request",nip:"43",isEphemeral:!0,template:{kind:28936,content:"",tags:[]}},{kind:3e4,name:"Follow Sets",description:"Categorized people lists",nip:"51",isAddressable:!0,template:{kind:3e4,content:"",tags:[["d","identifier"]]}},{kind:30001,name:"Generic Lists",description:"Generic categorized lists",nip:"51",isAddressable:!0,deprecated:!0,template:{kind:30001,content:"",tags:[["d","identifier"]]}},{kind:30002,name:"Relay Sets",description:"Categorized relay lists",nip:"51",isAddressable:!0,template:{kind:30002,content:"",tags:[["d","identifier"]]}},{kind:30003,name:"Bookmark Sets",description:"Categorized bookmark lists",nip:"51",isAddressable:!0,template:{kind:30003,content:"",tags:[["d","identifier"]]}},{kind:30004,name:"Curation Sets",description:"Curated content sets",nip:"51",isAddressable:!0,template:{kind:30004,content:"",tags:[["d","identifier"]]}},{kind:30005,name:"Video Sets",description:"Video playlists",nip:"51",isAddressable:!0,template:{kind:30005,content:"",tags:[["d","identifier"]]}},{kind:30007,name:"Kind Mute Sets",description:"Muted event kinds",nip:"51",isAddressable:!0,template:{kind:30007,content:"",tags:[["d","identifier"]]}},{kind:30008,name:"Profile Badges",description:"Badges displayed on profile",nip:"58",isAddressable:!0,template:{kind:30008,content:"",tags:[["d","identifier"]]}},{kind:30009,name:"Badge Definition",description:"Define a badge/achievement",nip:"58",isAddressable:!0,template:{kind:30009,content:"",tags:[["d","identifier"]]}},{kind:30015,name:"Interest Sets",description:"Interest/topic sets",nip:"51",isAddressable:!0,template:{kind:30015,content:"",tags:[["d","identifier"]]}},{kind:30017,name:"Stall",description:"Marketplace stall definition",nip:"15",isAddressable:!0,template:{kind:30017,content:"",tags:[["d","identifier"]]}},{kind:30018,name:"Product",description:"Marketplace product listing",nip:"15",isAddressable:!0,template:{kind:30018,content:"",tags:[["d","identifier"]]}},{kind:30019,name:"Marketplace UI/UX",description:"Marketplace interface settings",nip:"15",isAddressable:!0,template:{kind:30019,content:"",tags:[["d","identifier"]]}},{kind:30020,name:"Product Sold as Auction",description:"Auction product listing",nip:"15",isAddressable:!0,template:{kind:30020,content:"",tags:[["d","identifier"]]}},{kind:30023,name:"Long-form Content",description:"Blog post, article in markdown",nip:"23",isAddressable:!0,template:{kind:30023,content:"",tags:[["d","identifier"]]}},{kind:30024,name:"Draft Long-form Content",description:"Draft article",nip:"23",isAddressable:!0,template:{kind:30024,content:"",tags:[["d","identifier"]]}},{kind:30030,name:"Emoji Sets",description:"Custom emoji sets",nip:"51",isAddressable:!0,template:{kind:30030,content:"",tags:[["d","identifier"]]}},{kind:30040,name:"Curated Publication Index",description:"Publication index",nip:null,isAddressable:!0,spec:"NKBIP-01",template:{kind:30040,content:"",tags:[["d","identifier"]]}},{kind:30041,name:"Curated Publication Content",description:"Publication content",nip:null,isAddressable:!0,spec:"NKBIP-01",template:{kind:30041,content:"",tags:[["d","identifier"]]}},{kind:30063,name:"Release Artifact Sets",description:"Software release artifacts",nip:"51",isAddressable:!0,template:{kind:30063,content:"",tags:[["d","identifier"]]}},{kind:30078,name:"Application-specific Data",description:"App-specific key-value storage",nip:"78",isAddressable:!0,template:{kind:30078,content:"",tags:[["d","identifier"]]}},{kind:30166,name:"Relay Discovery",description:"Relay discovery/monitoring",nip:"66",isAddressable:!0,template:{kind:30166,content:"",tags:[["d","identifier"]]}},{kind:30267,name:"App Curation Sets",description:"Curated app sets",nip:"51",isAddressable:!0,template:{kind:30267,content:"",tags:[["d","identifier"]]}},{kind:30311,name:"Live Event",description:"Live streaming event",nip:"53",isAddressable:!0,template:{kind:30311,content:"",tags:[["d","identifier"]]}},{kind:30312,name:"Interactive Room",description:"Interactive live room",nip:"53",isAddressable:!0,template:{kind:30312,content:"",tags:[["d","identifier"]]}},{kind:30313,name:"Conference Event",description:"Conference/meetup event",nip:"53",isAddressable:!0,template:{kind:30313,content:"",tags:[["d","identifier"]]}},{kind:30315,name:"User Statuses",description:"User status updates",nip:"38",isAddressable:!0,template:{kind:30315,content:"",tags:[["d","identifier"]]}},{kind:30388,name:"Slide Set",description:"Presentation slides",nip:null,isAddressable:!0,spec:"Corny Chat",template:{kind:30388,content:"",tags:[["d","identifier"]]}},{kind:30402,name:"Classified Listing",description:"Classified ad listing",nip:"99",isAddressable:!0,template:{kind:30402,content:"",tags:[["d","identifier"]]}},{kind:30403,name:"Draft Classified Listing",description:"Draft classified ad",nip:"99",isAddressable:!0,template:{kind:30403,content:"",tags:[["d","identifier"]]}},{kind:30617,name:"Repository Announcements",description:"Git repository announcement",nip:"34",isAddressable:!0,template:{kind:30617,content:"",tags:[["d","identifier"]]}},{kind:30618,name:"Repository State Announcements",description:"Git repository state",nip:"34",isAddressable:!0,template:{kind:30618,content:"",tags:[["d","identifier"]]}},{kind:30818,name:"Wiki Article",description:"Wiki article",nip:"54",isAddressable:!0,template:{kind:30818,content:"",tags:[["d","identifier"]]}},{kind:30819,name:"Redirects",description:"URL redirects",nip:"54",isAddressable:!0,template:{kind:30819,content:"",tags:[["d","identifier"]]}},{kind:31234,name:"Draft Event",description:"Draft of any event",nip:"37",isAddressable:!0,template:{kind:31234,content:"",tags:[["d","identifier"]]}},{kind:31388,name:"Link Set",description:"Link collection",nip:null,isAddressable:!0,spec:"Corny Chat",template:{kind:31388,content:"",tags:[["d","identifier"]]}},{kind:31890,name:"Feed",description:"Custom feed definition",nip:null,isAddressable:!0,spec:"NUD: Custom Feeds",template:{kind:31890,content:"",tags:[["d","identifier"]]}},{kind:31922,name:"Date-Based Calendar Event",description:"All-day calendar event",nip:"52",isAddressable:!0,template:{kind:31922,content:"",tags:[["d","identifier"]]}},{kind:31923,name:"Time-Based Calendar Event",description:"Calendar event with time",nip:"52",isAddressable:!0,template:{kind:31923,content:"",tags:[["d","identifier"]]}},{kind:31924,name:"Calendar",description:"Calendar definition",nip:"52",isAddressable:!0,template:{kind:31924,content:"",tags:[["d","identifier"]]}},{kind:31925,name:"Calendar Event RSVP",description:"RSVP to calendar event",nip:"52",isAddressable:!0,template:{kind:31925,content:"",tags:[["d","identifier"]]}},{kind:31989,name:"Handler Recommendation",description:"Recommended app for event kind",nip:"89",isAddressable:!0,template:{kind:31989,content:"",tags:[["d","identifier"]]}},{kind:31990,name:"Handler Information",description:"App handler declaration",nip:"89",isAddressable:!0,template:{kind:31990,content:"",tags:[["d","identifier"]]}},{kind:32123,name:"WaveLake Track",description:"WaveLake music track",nip:null,isAddressable:!0,spec:"WaveLake",template:{kind:32123,content:"",tags:[["d","identifier"]]}},{kind:32267,name:"Software Application",description:"Software application listing",nip:null,isAddressable:!0,template:{kind:32267,content:"",tags:[["d","identifier"]]}},{kind:32388,name:"User Room Favorites",description:"Favorite rooms",nip:null,isAddressable:!0,spec:"Corny Chat",template:{kind:32388,content:"",tags:[["d","identifier"]]}},{kind:33388,name:"High Scores",description:"Game high scores",nip:null,isAddressable:!0,spec:"Corny Chat",template:{kind:33388,content:"",tags:[["d","identifier"]]}},{kind:34235,name:"Video Event Horizontal",description:"Horizontal video event",nip:"71",isAddressable:!0,template:{kind:34235,content:"",tags:[["d","identifier"]]}},{kind:34236,name:"Video Event Vertical",description:"Vertical video event",nip:"71",isAddressable:!0,template:{kind:34236,content:"",tags:[["d","identifier"]]}},{kind:34388,name:"Sound Effects",description:"Sound effect definitions",nip:null,isAddressable:!0,spec:"Corny Chat",template:{kind:34388,content:"",tags:[["d","identifier"]]}},{kind:34550,name:"Community Definition",description:"Define a community",nip:"72",isAddressable:!0,template:{kind:34550,content:"",tags:[["d","identifier"]]}},{kind:37516,name:"Geocache Listing",description:"Geocache location listing",nip:null,isAddressable:!0,spec:"geocaching",template:{kind:37516,content:"",tags:[["d","identifier"]]}},{kind:38172,name:"Cashu Mint Announcement",description:"Cashu mint announcement",nip:"87",isAddressable:!0,template:{kind:38172,content:"",tags:[["d","identifier"]]}},{kind:38173,name:"Fedimint Announcement",description:"Fedimint announcement",nip:"87",isAddressable:!0,template:{kind:38173,content:"",tags:[["d","identifier"]]}},{kind:38383,name:"Peer-to-peer Order Events",description:"P2P trading orders",nip:"69",isAddressable:!0,template:{kind:38383,content:"",tags:[["d","identifier"]]}},{kind:39e3,name:"Group Metadata Events",description:"Group metadata (start of range)",nip:"29",isAddressable:!0,template:{kind:39e3,content:"",tags:[["d","identifier"]]}},{kind:39089,name:"Starter Packs",description:"Starter pack lists",nip:"51",isAddressable:!0,template:{kind:39089,content:"",tags:[["d","identifier"]]}},{kind:39092,name:"Media Starter Packs",description:"Media starter packs",nip:"51",isAddressable:!0,template:{kind:39092,content:"",tags:[["d","identifier"]]}},{kind:39701,name:"Web Bookmarks",description:"Web URL bookmarks",nip:"B0",isAddressable:!0,template:{kind:39701,content:"",tags:[["d","identifier"]]}},{kind:39998,name:"ACL Event",description:"Access control list event",nip:null,isAddressable:!0,template:{kind:39998,content:"",tags:[["d","identifier"]]}}];function ey(e,t=null){const n=function(e){return Xm.find(t=>t.kind===e)}(e);return n?{...n.template,created_at:Math.floor(Date.now()/1e3),pubkey:t||""}:{kind:e,content:"",tags:[],created_at:Math.floor(Date.now()/1e3),pubkey:t||""}}const ty=[{id:"all",name:"All Kinds",filter:()=>!0},{id:"regular",name:"Regular Events (0-9999)",filter:e=>e.kind<1e4&&!e.isReplaceable},{id:"replaceable",name:"Replaceable (10000-19999)",filter:e=>e.isReplaceable},{id:"ephemeral",name:"Ephemeral (20000-29999)",filter:e=>e.isEphemeral},{id:"addressable",name:"Addressable (30000-39999)",filter:e=>e.isAddressable},{id:"social",name:"Social",filter:e=>[0,1,3,6,7].includes(e.kind)},{id:"messaging",name:"Messaging",filter:e=>[4,9,10,11,12,14,15,40,41,42].includes(e.kind)},{id:"lists",name:"Lists",filter:e=>e.name.toLowerCase().includes("list")||e.name.toLowerCase().includes("set")},{id:"marketplace",name:"Marketplace",filter:e=>[30017,30018,30019,30020,1021,1022,30402,30403].includes(e.kind)},{id:"lightning",name:"Lightning/Zaps",filter:e=>[9734,9735,9041,9321,7374,7375,7376].includes(e.kind)},{id:"media",name:"Media",filter:e=>[20,21,22,1063,1222,1244].includes(e.kind)},{id:"git",name:"Git/Code",filter:e=>[818,1337,1617,1618,1619,1621,1622,30617,30618].includes(e.kind)},{id:"calendar",name:"Calendar",filter:e=>[31922,31923,31924,31925].includes(e.kind)},{id:"groups",name:"Groups",filter:e=>e.kind>=9e3&&e.kind<=9030||e.kind>=39e3&&e.kind<=39009}];function ny(e,t,n){const r=e.slice();return r[13]=t[n],r}function ry(e,t,n){const r=e.slice();return r[16]=t[n],r}function iy(e){let t,n,i,o,s,a,l,h,y,w,b,C,E,x,B,S,Q,F,D,$,U,P,R,T,N,O=e[3].length+"",M=1!==e[3].length?"s":"",L=ty,_=[];for(let t=0;t=2e4&&e.kind<3e4?"badge-ephemeral":"badge-regular"}function fy(e){return e.isAddressable?"Addressable":e.isReplaceable?"Replaceable":e.kind>=2e4&&e.kind<3e4?"Ephemeral":"Regular"}function py(e,t,n){let{isOpen:r=!1}=t,{userPubkey:i=""}=t;const o=$();let s="",a="all",l=Xm;function c(e){const t=ey(e.kind,i);o("select",{kind:e,template:t}),u()}function u(){n(0,r=!1),n(1,s=""),n(2,a="all"),o("close")}return e.$$set=e=>{"isOpen"in e&&n(0,r=e.isOpen),"userPubkey"in e&&n(8,i=e.userPubkey)},e.$$.update=()=>{if(6&e.$$.dirty){let e=Xm;const t=ty.find(e=>e.id===a);if(t&&(e=e.filter(t.filter)),s.trim()){const t=s.toLowerCase();e=e.filter(e=>e.name.toLowerCase().includes(t)||e.description.toLowerCase().includes(t)||e.kind.toString().includes(t)||e.nip&&e.nip.includes(t))}n(3,l=e)}},[r,s,a,l,c,u,function(e){"Escape"===e.key&&u()},function(e){e.target===e.currentTarget&&u()},i,function(){s=this.value,n(1,s)},e=>n(2,a=e.id),e=>c(e)]}class hy extends ie{constructor(e){super(),re(this,e,py,uy,o,{isOpen:0,userPubkey:8})}}function gy(e){let t,n,r,i,o,s,a,l,f,h;return{c(){t=p("div"),n=p("div"),r=p("span"),r.textContent="⚠",i=m(),o=p("span"),s=g(e[1]),a=m(),l=p("button"),l.textContent="×",A(r,"class","error-icon svelte-46pmgb"),A(o,"class","error-message svelte-46pmgb"),A(n,"class","error-content svelte-46pmgb"),A(l,"class","error-dismiss svelte-46pmgb"),A(t,"class","error-banner svelte-46pmgb")},m(d,p){u(d,t,p),c(t,n),c(n,r),c(n,i),c(n,o),c(o,s),c(t,a),c(t,l),f||(h=v(l,"click",e[10]),f=!0)},p(e,t){2&t&&k(s,e[1])},d(e){e&&d(t),f=!1,h()}}}function my(e){let t,n,i,o,s,a,l,f,h,g,y,w,b,k,C,E,x,B,S,Q=e[1]&&gy(e);function F(t){e[14](t)}let D={userPubkey:e[2]};return void 0!==e[3]&&(D.isOpen=e[3]),C=new hy({props:D}),R.push(()=>Z(C,"isOpen",F)),C.$on("select",e[8]),C.$on("close",e[9]),{c(){t=p("div"),n=p("div"),i=p("button"),i.textContent="Generate Template",o=m(),s=p("button"),s.textContent="Reformat",a=m(),l=p("button"),l.textContent="Sign",f=m(),h=p("button"),h.textContent="Publish",g=m(),Q&&Q.c(),y=m(),w=p("div"),b=p("textarea"),k=m(),X(C.$$.fragment),A(i,"class","compose-btn template-btn svelte-46pmgb"),A(s,"class","compose-btn reformat-btn svelte-46pmgb"),A(l,"class","compose-btn sign-btn svelte-46pmgb"),A(h,"class","compose-btn publish-btn svelte-46pmgb"),A(n,"class","compose-header svelte-46pmgb"),A(b,"class","compose-textarea svelte-46pmgb"),A(b,"placeholder","Enter your Nostr event JSON here, or click 'Generate Template' to start with a template..."),A(b,"spellcheck","false"),A(w,"class","compose-editor svelte-46pmgb"),A(t,"class","compose-view svelte-46pmgb")},m(r,d){u(r,t,d),c(t,n),c(n,i),c(n,o),c(n,s),c(n,a),c(n,l),c(n,f),c(n,h),c(t,g),Q&&Q.m(t,null),c(t,y),c(t,w),c(w,b),I(b,e[0]),u(r,k,d),ee(C,r,d),x=!0,B||(S=[v(i,"click",e[7]),v(s,"click",e[4]),v(l,"click",e[5]),v(h,"click",e[6]),v(b,"input",e[13])],B=!0)},p(e,[n]){e[1]?Q?Q.p(e,n):(Q=gy(e),Q.c(),Q.m(t,y)):Q&&(Q.d(1),Q=null),1&n&&I(b,e[0]);const r={};4&n&&(r.userPubkey=e[2]),!E&&8&n&&(E=!0,r.isOpen=e[3],_(()=>E=!1)),C.$set(r)},i(e){x||(Y(C.$$.fragment,e),x=!0)},o(e){W(C.$$.fragment,e),x=!1},d(e){e&&d(t),Q&&Q.d(),e&&d(k),te(C,e),B=!1,r(S)}}}function yy(e,t,n){let{composeEventJson:r=""}=t,{userPubkey:i=""}=t,{userRole:o=""}=t,{policyEnabled:s=!1}=t,{publishError:a=""}=t;const l=$();let c=!1;return e.$$set=e=>{"composeEventJson"in e&&n(0,r=e.composeEventJson),"userPubkey"in e&&n(2,i=e.userPubkey),"userRole"in e&&n(11,o=e.userRole),"policyEnabled"in e&&n(12,s=e.policyEnabled),"publishError"in e&&n(1,a=e.publishError)},[r,a,i,c,function(){l("reformatJson")},function(){l("signEvent")},function(){l("publishEvent")},function(){n(3,c=!0)},function(e){const{kind:t,template:i}=e.detail;n(0,r=JSON.stringify(i,null,2)),l("templateSelected",{kind:t,template:i})},function(){n(3,c=!1)},function(){n(1,a=""),l("clearError")},o,s,function(){r=this.value,n(0,r)},function(e){c=e,n(3,c)}]}class vy extends ie{constructor(e){super(),re(this,e,yy,my,o,{composeEventJson:0,userPubkey:2,userRole:11,policyEnabled:12,publishError:1})}}function wy(e,t,n){const r=e.slice();return r[23]=t[n],r}function Ay(t){let n,r,i,o,s,a;return{c(){n=p("div"),r=p("p"),r.textContent="Please log in to access sprocket management.",i=m(),o=p("button"),o.textContent="Log In",A(r,"class","svelte-fiaj1r"),A(o,"class","login-btn svelte-fiaj1r"),A(n,"class","login-prompt svelte-fiaj1r")},m(e,l){u(e,n,l),c(n,r),c(n,i),c(n,o),s||(a=v(o,"click",t[18]),s=!0)},p:e,d(e){e&&d(n),s=!1,a()}}}function by(e){let t,n,r,i,o,s,a,l,f,h=(e[2]||"none")+"";return{c(){t=p("div"),n=p("p"),n.textContent="❌ Owner permission required for sprocket management.",r=m(),i=p("p"),i.innerHTML='To enable sprocket functionality, set the ORLY_OWNERS environment variable with your npub when starting the relay.',o=m(),s=p("p"),a=g("Current user role: "),l=p("strong"),f=g(h),A(n,"class","svelte-fiaj1r"),A(i,"class","svelte-fiaj1r"),A(s,"class","svelte-fiaj1r"),A(t,"class","permission-denied svelte-fiaj1r")},m(e,d){u(e,t,d),c(t,n),c(t,r),c(t,i),c(t,o),c(t,s),c(s,a),c(s,l),c(l,f)},p(e,t){4&t&&h!==(h=(e[2]||"none")+"")&&k(f,h)},d(e){e&&d(t)}}}function ky(e){let t,n,i,o,s,a,l,h,y,w,b,C,E,B,S,Q,F,D,$,U,P,R,T,N,O,M,L,_,H,j,G,J,K,V,z,q,Y,W,Z,X,ee,te,ne,re,ie,oe,se,ae,le,ce,ue,de,fe,pe,he,ge,me=e[3]?.is_running?"🟢 Running":"🔴 Stopped",ye=e[3]?.script_exists?"✅ Exists":"❌ Not found",ve=e[3]?.pid&&Iy(e),we=e[6]&&Cy(e),Ae=e[8],be=[];for(let t=0;t{"isLoggedIn"in e&&n(1,r=e.isLoggedIn),"userRole"in e&&n(2,i=e.userRole),"sprocketStatus"in e&&n(3,o=e.sprocketStatus),"isLoadingSprocket"in e&&n(4,s=e.isLoadingSprocket),"sprocketUploadFile"in e&&n(5,a=e.sprocketUploadFile),"sprocketScript"in e&&n(0,l=e.sprocketScript),"sprocketMessage"in e&&n(6,c=e.sprocketMessage),"sprocketMessageType"in e&&n(7,u=e.sprocketMessageType),"sprocketVersions"in e&&n(8,d=e.sprocketVersions)},[l,r,i,o,s,a,c,u,d,function(){f("restartSprocket")},function(){f("deleteSprocket")},function(e){f("sprocketFileSelect",e)},function(){f("uploadSprocketScript")},function(){f("saveSprocket")},function(){f("loadSprocket")},function(){f("loadVersions")},p,h,function(){f("openLoginModal")},function(){l=this.value,n(0,l)},e=>p(e),e=>h(e.name)]}class Fy extends ie{constructor(e){super(),re(this,e,Qy,Sy,o,{isLoggedIn:1,userRole:2,sprocketStatus:3,isLoadingSprocket:4,sprocketUploadFile:5,sprocketScript:0,sprocketMessage:6,sprocketMessageType:7,sprocketVersions:8})}}function Dy(e,t,n){const r=e.slice();return r[26]=t[n],r}function $y(e,t,n){const r=e.slice();return r[29]=t[n],r}function Uy(e,t,n){const r=e.slice();return r[32]=t[n],r}function Py(t){let n,r,i,o,s,a;return{c(){n=p("div"),r=p("p"),r.textContent="Please log in to access policy configuration.",i=m(),o=p("button"),o.textContent="Log In",A(r,"class","svelte-gkxvxc"),A(o,"class","login-btn svelte-gkxvxc"),A(n,"class","login-prompt svelte-gkxvxc")},m(e,l){u(e,n,l),c(n,r),c(n,i),c(n,o),s||(a=v(o,"click",t[16]),s=!0)},p:e,d(e){e&&d(n),s=!1,a()}}}function Ry(e){let t,n,r,i,o,s,a,l,f,h=(e[3]||"none")+"";return{c(){t=p("div"),n=p("p"),n.textContent="Policy configuration requires owner or policy admin permissions.",r=m(),i=p("p"),i.innerHTML='To become a policy admin, ask an existing policy admin to add your pubkey\n to the policy_admins list.',o=m(),s=p("p"),a=g("Current user role: "),l=p("strong"),f=g(h),A(n,"class","svelte-gkxvxc"),A(i,"class","svelte-gkxvxc"),A(s,"class","svelte-gkxvxc"),A(t,"class","permission-denied svelte-gkxvxc")},m(e,d){u(e,t,d),c(t,n),c(t,r),c(t,i),c(t,o),c(t,s),c(s,a),c(s,l),c(l,f)},p(e,t){8&t[0]&&h!==(h=(e[3]||"none")+"")&&k(f,h)},d(e){e&&d(t)}}}function Ty(e){let t,n,i,o,s,a,l,f,h,y,w,b,C,E,B,S,Q,F,D,$,U,P,R,T,N,O,M,L,_,H,j,G,J,K,V,z,q,Y,W,Z,X,ee,te,ne,re,ie,oe,se,ae,le,ce,ue,de,fe,pe,he,ge,me,ye,ve,we,Ae,be,ke,Ie,Ce,Ee,xe,Be,Se,Qe,Fe,De,$e,Ue,Pe=e[5]?"Policy Enabled":"Policy Disabled",Re=e[10].length+"",Te=e[4]&&Ny(),Ne=e[9].length>0&&Oy(e),Oe=e[7]&&Ly(e);function Me(e,t){return 0===e[1].length?Hy:_y}let Le=Me(e),_e=Le(e);function He(e,t){return 0===e[10].length?Jy:Gy}let je=He(e),Ge=je(e);return{c(){t=p("div"),n=p("div"),i=p("h3"),i.textContent="Policy Editor",o=m(),s=p("div"),a=p("span"),l=g(Pe),f=m(),Te&&Te.c(),h=m(),y=p("div"),y.innerHTML='Edit the policy JSON below and click "Save & Publish" to update the relay's policy configuration.\n Changes are applied immediately after validation.
\n Policy updates are published as kind 12345 events and require policy admin permissions.
',w=m(),b=p("div"),C=p("textarea"),E=m(),Ne&&Ne.c(),B=m(),S=p("div"),Q=p("button"),F=g("Load Current"),D=m(),$=p("button"),U=g("Format JSON"),P=m(),R=p("button"),T=g("Validate"),N=m(),O=p("button"),M=g("Save & Publish"),L=m(),Oe&&Oe.c(),_=m(),H=p("div"),j=p("h3"),j.textContent="Policy Administrators",G=m(),J=p("div"),J.innerHTML='Policy admins can update the relay's policy configuration via kind 12345 events.\n Their follows get whitelisted if policy_follow_whitelist_enabled is true in the policy.
\n Note: Policy admins are separate from relay admins (ORLY_ADMINS).\n Changes here update the JSON editor - click "Save & Publish" to apply.
',K=m(),V=p("div"),_e.c(),z=m(),q=p("div"),Y=p("input"),W=m(),Z=p("button"),X=g("+ Add Admin"),te=m(),ne=p("div"),re=p("h3"),re.textContent="Policy Follow Whitelist",ie=m(),oe=p("div"),oe.innerHTML='Pubkeys followed by policy admins (kind 3 events).\n These get automatic read+write access when rules have write_allow_follows: true.
',se=m(),ae=p("div"),le=p("span"),ce=g(Re),ue=g(" pubkey(s) in whitelist"),de=m(),fe=p("button"),pe=g("🔄 Refresh Follows"),he=m(),ge=p("div"),Ge.c(),me=m(),ye=p("div"),ve=p("h3"),ve.textContent="Policy Reference",we=m(),Ae=p("div"),be=p("h4"),be.textContent="Structure Overview",ke=m(),Ie=p("ul"),Ie.innerHTML='kind.whitelist - Only allow these event kinds (takes precedence) \n kind.blacklist - Deny these event kinds (if no whitelist) \n global - Rules applied to all events \n rules - Per-kind rules (keyed by kind number as string) \n default_policy - "allow" or "deny" when no rules match \n policy_admins - Hex pubkeys that can update policy \n policy_follow_whitelist_enabled - Enable follow-based access ',Ce=m(),Ee=p("h4"),Ee.textContent="Rule Fields",xe=m(),Be=p("ul"),Be.innerHTML='description - Human-readable rule description \n write_allow / write_deny - Pubkey lists for write access \n read_allow / read_deny - Pubkey lists for read access \n write_allow_follows - Grant access to policy admin follows \n size_limit - Max total event size in bytes \n content_limit - Max content field size in bytes \n max_expiry - Max expiry offset in seconds \n max_age_of_event - Max age of created_at in seconds \n max_age_event_in_future - Max future offset in seconds \n must_have_tags - Required tag letters (e.g., ["d", "t"]) \n tag_validation - Regex patterns for tag values \n script - Path to external validation script ',Se=m(),Qe=p("h4"),Qe.textContent="Example Policy",Fe=m(),De=p("pre"),De.textContent=`${e[20]}`,A(i,"class","svelte-gkxvxc"),A(a,"class","status-badge svelte-gkxvxc"),x(a,"enabled",e[5]),A(s,"class","policy-status svelte-gkxvxc"),A(n,"class","policy-header svelte-gkxvxc"),A(y,"class","policy-info svelte-gkxvxc"),A(C,"class","policy-editor svelte-gkxvxc"),A(C,"placeholder","Loading policy configuration..."),C.disabled=e[6],A(C,"spellcheck","false"),A(b,"class","editor-container svelte-gkxvxc"),A(Q,"class","policy-btn load-btn svelte-gkxvxc"),Q.disabled=e[6],A($,"class","policy-btn format-btn svelte-gkxvxc"),$.disabled=e[6],A(R,"class","policy-btn validate-btn svelte-gkxvxc"),R.disabled=e[6],A(O,"class","policy-btn save-btn svelte-gkxvxc"),O.disabled=e[6],A(S,"class","policy-actions svelte-gkxvxc"),A(t,"class","policy-section svelte-gkxvxc"),A(J,"class","policy-info svelte-gkxvxc"),A(V,"class","admin-list svelte-gkxvxc"),A(Y,"type","text"),A(Y,"placeholder","npub or hex pubkey"),Y.disabled=e[6],A(Y,"class","svelte-gkxvxc"),A(Z,"class","policy-btn add-btn svelte-gkxvxc"),Z.disabled=ee=e[6]||!e[11].trim(),A(q,"class","add-admin svelte-gkxvxc"),A(H,"class","policy-section svelte-gkxvxc"),A(oe,"class","policy-info svelte-gkxvxc"),A(le,"class","follows-count svelte-gkxvxc"),A(fe,"class","policy-btn refresh-btn svelte-gkxvxc"),fe.disabled=e[6],A(ae,"class","follows-header svelte-gkxvxc"),A(ge,"class","follows-list svelte-gkxvxc"),A(ne,"class","policy-section svelte-gkxvxc"),A(be,"class","svelte-gkxvxc"),A(Ie,"class","field-list svelte-gkxvxc"),A(Ee,"class","svelte-gkxvxc"),A(Be,"class","field-list svelte-gkxvxc"),A(Qe,"class","svelte-gkxvxc"),A(De,"class","example-json svelte-gkxvxc"),A(Ae,"class","reference-content svelte-gkxvxc"),A(ye,"class","policy-section svelte-gkxvxc")},m(r,d){u(r,t,d),c(t,n),c(n,i),c(n,o),c(n,s),c(s,a),c(a,l),c(s,f),Te&&Te.m(s,null),c(t,h),c(t,y),c(t,w),c(t,b),c(b,C),I(C,e[0]),c(t,E),Ne&&Ne.m(t,null),c(t,B),c(t,S),c(S,Q),c(Q,F),c(S,D),c(S,$),c($,U),c(S,P),c(S,R),c(R,T),c(S,N),c(S,O),c(O,M),c(t,L),Oe&&Oe.m(t,null),u(r,_,d),u(r,H,d),c(H,j),c(H,G),c(H,J),c(H,K),c(H,V),_e.m(V,null),c(H,z),c(H,q),c(q,Y),I(Y,e[11]),c(q,W),c(q,Z),c(Z,X),u(r,te,d),u(r,ne,d),c(ne,re),c(ne,ie),c(ne,oe),c(ne,se),c(ne,ae),c(ae,le),c(le,ce),c(le,ue),c(ae,de),c(ae,fe),c(fe,pe),c(ne,he),c(ne,ge),Ge.m(ge,null),u(r,me,d),u(r,ye,d),c(ye,ve),c(ye,we),c(ye,Ae),c(Ae,be),c(Ae,ke),c(Ae,Ie),c(Ae,Ce),c(Ae,Ee),c(Ae,xe),c(Ae,Be),c(Ae,Se),c(Ae,Qe),c(Ae,Fe),c(Ae,De),$e||(Ue=[v(C,"input",e[21]),v(Q,"click",e[12]),v($,"click",e[15]),v(R,"click",e[13]),v(O,"click",e[14]),v(Y,"input",e[23]),v(Y,"keydown",e[24]),v(Z,"click",e[18]),v(fe,"click",e[17])],$e=!0)},p(e,n){32&n[0]&&Pe!==(Pe=e[5]?"Policy Enabled":"Policy Disabled")&&k(l,Pe),32&n[0]&&x(a,"enabled",e[5]),e[4]?Te||(Te=Ny(),Te.c(),Te.m(s,null)):Te&&(Te.d(1),Te=null),64&n[0]&&(C.disabled=e[6]),1&n[0]&&I(C,e[0]),e[9].length>0?Ne?Ne.p(e,n):(Ne=Oy(e),Ne.c(),Ne.m(t,B)):Ne&&(Ne.d(1),Ne=null),64&n[0]&&(Q.disabled=e[6]),64&n[0]&&($.disabled=e[6]),64&n[0]&&(R.disabled=e[6]),64&n[0]&&(O.disabled=e[6]),e[7]?Oe?Oe.p(e,n):(Oe=Ly(e),Oe.c(),Oe.m(t,null)):Oe&&(Oe.d(1),Oe=null),Le===(Le=Me(e))&&_e?_e.p(e,n):(_e.d(1),_e=Le(e),_e&&(_e.c(),_e.m(V,null))),64&n[0]&&(Y.disabled=e[6]),2048&n[0]&&Y.value!==e[11]&&I(Y,e[11]),2112&n[0]&&ee!==(ee=e[6]||!e[11].trim())&&(Z.disabled=ee),1024&n[0]&&Re!==(Re=e[10].length+"")&&k(ce,Re),64&n[0]&&(fe.disabled=e[6]),je===(je=He(e))&&Ge?Ge.p(e,n):(Ge.d(1),Ge=je(e),Ge&&(Ge.c(),Ge.m(ge,null)))},d(e){e&&d(t),Te&&Te.d(),Ne&&Ne.d(),Oe&&Oe.d(),e&&d(_),e&&d(H),_e.d(),e&&d(te),e&&d(ne),Ge.d(),e&&d(me),e&&d(ye),$e=!1,r(Ue)}}}function Ny(e){let t;return{c(){t=p("span"),t.textContent="Policy Admin",A(t,"class","admin-badge svelte-gkxvxc")},m(e,n){u(e,t,n)},d(e){e&&d(t)}}}function Oy(e){let t,n,r,i,o=e[9],s=[];for(let t=0;t{"isLoggedIn"in e&&n(2,r=e.isLoggedIn),"userRole"in e&&n(3,i=e.userRole),"isPolicyAdmin"in e&&n(4,o=e.isPolicyAdmin),"policyEnabled"in e&&n(5,s=e.policyEnabled),"policyJson"in e&&n(0,a=e.policyJson),"isLoadingPolicy"in e&&n(6,l=e.isLoadingPolicy),"policyMessage"in e&&n(7,c=e.policyMessage),"policyMessageType"in e&&n(8,u=e.policyMessageType),"validationErrors"in e&&n(9,d=e.validationErrors),"policyAdmins"in e&&n(1,f=e.policyAdmins),"policyFollows"in e&&n(10,p=e.policyFollows)},e.$$.update=()=>{if(1&e.$$.dirty[0])try{if(a){const e=JSON.parse(a);n(1,f=e.policy_admins||[])}}catch(e){}},[a,f,r,i,o,s,l,c,u,d,p,g,function(){h("loadPolicy")},function(){h("validatePolicy")},function(){h("savePolicy")},function(){h("formatJson")},function(){h("openLoginModal")},function(){h("refreshFollows")},m,y,'{\n "kind": {\n "whitelist": [0, 1, 3, 6, 7, 10002],\n "blacklist": []\n },\n "global": {\n "description": "Global rules applied to all events",\n "size_limit": 65536,\n "max_age_of_event": 86400,\n "max_age_event_in_future": 300\n },\n "rules": {\n "1": {\n "description": "Kind 1 (short text notes)",\n "content_limit": 8192,\n "write_allow_follows": true\n },\n "30023": {\n "description": "Long-form articles",\n "content_limit": 100000,\n "tag_validation": {\n "d": "^[a-z0-9-]{1,64}$",\n "t": "^[a-z0-9-]{1,32}$"\n }\n }\n },\n "default_policy": "allow",\n "policy_admins": [""],\n "policy_follow_whitelist_enabled": true\n}',function(){a=this.value,n(0,a)},e=>y(e),function(){g=this.value,n(11,g)},e=>"Enter"===e.key&&m()]}class qy extends ie{constructor(e){super(),re(this,e,zy,Vy,o,{isLoggedIn:2,userRole:3,isPolicyAdmin:4,policyEnabled:5,policyJson:0,isLoadingPolicy:6,policyMessage:7,policyMessageType:8,validationErrors:9,policyAdmins:1,policyFollows:10},null,[-1,-1])}}const{window:Yy}=l;function Wy(e,t,n){const r=e.slice();return r[57]=t[n],r}function Zy(e,t,n){const r=e.slice();return r[54]=t[n],r}function Xy(t){let n,r,i,o,s,a;return{c(){n=p("div"),r=p("p"),r.textContent="Please log in to view your Blossom storage.",i=m(),o=p("button"),o.textContent="Log In",A(r,"class","svelte-bz95vx"),A(o,"class","login-btn svelte-bz95vx"),A(n,"class","login-prompt svelte-bz95vx")},m(e,l){u(e,n,l),c(n,r),c(n,i),c(n,o),s||(a=v(o,"click",t[21]),s=!0)},p:e,d(e){e&&d(n),s=!1,a()}}}function ev(e){let t,n,r,i,o,s,a,l,f,h,y,w,b,I,E,x,B,S,Q,F=e[1]||e[14]?"Loading...":"Refresh";function D(e,t){return e[15]?rv:e[12]?nv:tv}let $=D(e),U=$(e),P=e[3]&&!e[12]&&!e[15]&&ov(e),R=!e[12]&&!e[15]&&sv(e),T=e[4]&&lv(e);function N(e,t){return e[12]&&!e[15]?uv:cv}let O=N(e),M=O(e);return{c(){t=p("div"),n=p("div"),r=g('DEBUG: role="'),i=g(e[0]),o=g('" isAdmin='),s=g(e[3]),a=m(),l=p("div"),U.c(),f=m(),h=p("div"),P&&P.c(),y=m(),w=p("button"),b=g(F),E=m(),R&&R.c(),x=m(),T&&T.c(),B=m(),M.c(),C(n,"background","red"),C(n,"color","white"),C(n,"padding","4px"),C(n,"font-size","12px"),A(w,"class","refresh-btn svelte-bz95vx"),w.disabled=I=e[1]||e[14],A(h,"class","header-buttons svelte-bz95vx"),A(l,"class","header-section svelte-bz95vx"),A(t,"class","blossom-view svelte-bz95vx")},m(d,p){u(d,t,p),c(t,n),c(n,r),c(n,i),c(n,o),c(n,s),c(t,a),c(t,l),U.m(l,null),c(l,f),c(l,h),P&&P.m(h,null),c(h,y),c(h,w),c(w,b),c(t,E),R&&R.m(t,null),c(t,x),T&&T.m(t,null),c(t,B),M.m(t,null),S||(Q=v(w,"click",e[31]),S=!0)},p(e,n){1&n[0]&&k(i,e[0]),8&n[0]&&k(s,e[3]),$===($=D(e))&&U?U.p(e,n):(U.d(1),U=$(e),U&&(U.c(),U.m(l,f))),!e[3]||e[12]||e[15]?P&&(P.d(1),P=null):P?P.p(e,n):(P=ov(e),P.c(),P.m(h,y)),16386&n[0]&&F!==(F=e[1]||e[14]?"Loading...":"Refresh")&&k(b,F),16386&n[0]&&I!==(I=e[1]||e[14])&&(w.disabled=I),e[12]||e[15]?R&&(R.d(1),R=null):R?R.p(e,n):(R=sv(e),R.c(),R.m(t,x)),e[4]?T?T.p(e,n):(T=lv(e),T.c(),T.m(t,B)):T&&(T.d(1),T=null),O===(O=N(e))&&M?M.p(e,n):(M.d(1),M=O(e),M&&(M.c(),M.m(t,null)))},d(e){e&&d(t),U.d(),P&&P.d(),R&&R.d(),T&&T.d(),M.d(),S=!1,Q()}}}function tv(t){let n;return{c(){n=p("h3"),n.textContent="Blossom Media Storage",A(n,"class","svelte-bz95vx")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function nv(t){let n,r,i,o,s;return{c(){n=p("button"),n.textContent="← Back",r=m(),i=p("h3"),i.textContent="All Users Storage",A(n,"class","back-btn svelte-bz95vx"),A(i,"class","svelte-bz95vx")},m(e,a){u(e,n,a),u(e,r,a),u(e,i,a),o||(s=v(n,"click",t[28]),o=!0)},p:e,d(e){e&&d(n),e&&d(r),e&&d(i),o=!1,s()}}}function rv(e){let t,n,r,i,o,s,a,l=(e[15].profile?.name||Nv(e[26](e[15].pubkey)))+"",f=e[15].profile?.picture&&iv(e);return{c(){t=p("button"),t.textContent="← Back",n=m(),r=p("h3"),f&&f.c(),i=m(),o=g(l),A(t,"class","back-btn svelte-bz95vx"),A(r,"class","user-header svelte-bz95vx")},m(l,d){u(l,t,d),u(l,n,d),u(l,r,d),f&&f.m(r,null),c(r,i),c(r,o),s||(a=v(t,"click",e[30]),s=!0)},p(e,t){e[15].profile?.picture?f?f.p(e,t):(f=iv(e),f.c(),f.m(r,i)):f&&(f.d(1),f=null),32768&t[0]&&l!==(l=(e[15].profile?.name||Nv(e[26](e[15].pubkey)))+"")&&k(o,l)},d(e){e&&d(t),e&&d(n),e&&d(r),f&&f.d(),s=!1,a()}}}function iv(e){let t,n;return{c(){t=p("img"),a(t.src,n=e[15].profile.picture)||A(t,"src",n),A(t,"alt",""),A(t,"class","header-avatar svelte-bz95vx")},m(e,n){u(e,t,n)},p(e,r){32768&r[0]&&!a(t.src,n=e[15].profile.picture)&&A(t,"src",n)},d(e){e&&d(t)}}}function ov(e){let t,n,r,i;return{c(){t=p("button"),n=g("Admin"),A(t,"class","admin-btn svelte-bz95vx"),t.disabled=e[1]},m(o,s){u(o,t,s),c(t,n),r||(i=v(t,"click",e[27]),r=!0)},p(e,n){2&n[0]&&(t.disabled=e[1])},d(e){e&&d(t),r=!1,i()}}}function sv(e){let t,n,i,o,s,a,l,f,h=e[5].length>0&&av(e);return{c(){t=p("div"),n=p("input"),i=m(),o=p("button"),s=g("Select Files"),a=m(),h&&h.c(),A(n,"type","file"),n.multiple=!0,A(n,"class","file-input-hidden svelte-bz95vx"),A(o,"class","select-btn svelte-bz95vx"),o.disabled=e[6],A(t,"class","upload-section svelte-bz95vx")},m(r,d){u(r,t,d),c(t,n),e[39](n),c(t,i),c(t,o),c(o,s),c(t,a),h&&h.m(t,null),l||(f=[v(n,"change",e[23]),v(o,"click",e[24])],l=!0)},p(e,n){64&n[0]&&(o.disabled=e[6]),e[5].length>0?h?h.p(e,n):(h=av(e),h.c(),h.m(t,null)):h&&(h.d(1),h=null)},d(n){n&&d(t),e[39](null),h&&h.d(),l=!1,r(f)}}}function av(e){let t,n,r,i,o,s,a,l,f=e[5].length+"",h=(e[6]?e[7]:"Upload")+"";return{c(){t=p("span"),n=g(f),r=g(" file(s) selected"),i=m(),o=p("button"),s=g(h),A(t,"class","selected-count svelte-bz95vx"),A(o,"class","upload-btn svelte-bz95vx"),o.disabled=e[6]},m(d,f){u(d,t,f),c(t,n),c(t,r),u(d,i,f),u(d,o,f),c(o,s),a||(l=v(o,"click",e[25]),a=!0)},p(e,t){32&t[0]&&f!==(f=e[5].length+"")&&k(n,f),192&t[0]&&h!==(h=(e[6]?e[7]:"Upload")+"")&&k(s,h),64&t[0]&&(o.disabled=e[6])},d(e){e&&d(t),e&&d(i),e&&d(o),a=!1,l()}}}function lv(e){let t,n;return{c(){t=p("div"),n=g(e[4]),A(t,"class","error-message svelte-bz95vx")},m(e,r){u(e,t,r),c(t,n)},p(e,t){16&t[0]&&k(n,e[4])},d(e){e&&d(t)}}}function cv(e){let t,n,r;function i(e,r){return 2&r[0]&&(t=null),null==t&&(t=!(!e[1]||0!==e[32]().length)),t?pv:(null==n&&(n=!(0!==e[32]().length)),n?fv:dv)}let o=i(e,[-1,-1]),s=o(e);return{c(){s.c(),r=y()},m(e,t){s.m(e,t),u(e,r,t)},p(e,t){o===(o=i(e,t))&&s?s.p(e,t):(s.d(1),s=o(e),s&&(s.c(),s.m(r.parentNode,r)))},d(e){s.d(e),e&&d(r)}}}function uv(e){let t;function n(e,t){return e[14]?yv:0===e[13].length?mv:gv}let r=n(e),i=r(e);return{c(){i.c(),t=y()},m(e,n){i.m(e,n),u(e,t,n)},p(e,o){r===(r=n(e))&&i?i.p(e,o):(i.d(1),i=r(e),i&&(i.c(),i.m(t.parentNode,t)))},d(e){i.d(e),e&&d(t)}}}function dv(e){let t,n=e[32](),r=[];for(let t=0;tNo users have uploaded files yet.",A(n,"class","empty-state svelte-bz95vx")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function yv(t){let n;return{c(){n=p("div"),n.textContent="Loading user statistics...",A(n,"class","loading svelte-bz95vx")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function vv(t){let n;return{c(){n=p("div"),A(n,"class","user-avatar-placeholder svelte-bz95vx")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function wv(e){let t,n;return{c(){t=p("img"),a(t.src,n=e[54].profile.picture)||A(t,"src",n),A(t,"alt",""),A(t,"class","user-avatar svelte-bz95vx")},m(e,n){u(e,t,n)},p(e,r){8192&r[0]&&!a(t.src,n=e[54].profile.picture)&&A(t,"src",n)},d(e){e&&d(t)}}}function Av(e){let t,n,i,o,s,a,l,f,h,y,w,b,I,C,E,x,B,S,Q,F,D,$=(e[54].profile?.name||Nv(e[26](e[54].pubkey)))+"",U=Nv(e[26](e[54].pubkey))+"",P=e[54].blob_count+"",R=Dv(e[54].total_size_bytes)+"";function T(e,t){return e[54].profile?.picture?wv:vv}let N=T(e),O=N(e);function M(){return e[40](e[54])}function L(...t){return e[41](e[54],...t)}return{c(){t=p("div"),n=p("div"),O.c(),i=m(),o=p("div"),s=p("div"),a=g($),l=m(),f=p("div"),h=g(U),w=m(),b=p("div"),I=p("span"),C=g(P),E=g(" files"),x=m(),B=p("span"),S=g(R),Q=m(),A(n,"class","user-avatar-container svelte-bz95vx"),A(s,"class","user-name svelte-bz95vx"),A(f,"class","user-npub svelte-bz95vx"),A(f,"title",y=e[54].pubkey),A(o,"class","user-info svelte-bz95vx"),A(I,"class","blob-count svelte-bz95vx"),A(B,"class","total-size svelte-bz95vx"),A(b,"class","user-stats svelte-bz95vx"),A(t,"class","user-stat-item svelte-bz95vx"),A(t,"role","button"),A(t,"tabindex","0")},m(e,r){u(e,t,r),c(t,n),O.m(n,null),c(t,i),c(t,o),c(o,s),c(s,a),c(o,l),c(o,f),c(f,h),c(t,w),c(t,b),c(b,I),c(I,C),c(I,E),c(b,x),c(b,B),c(B,S),c(t,Q),F||(D=[v(t,"click",M),v(t,"keypress",L)],F=!0)},p(t,r){N===(N=T(e=t))&&O?O.p(e,r):(O.d(1),O=N(e),O&&(O.c(),O.m(n,null))),8192&r[0]&&$!==($=(e[54].profile?.name||Nv(e[26](e[54].pubkey)))+"")&&k(a,$),8192&r[0]&&U!==(U=Nv(e[26](e[54].pubkey))+"")&&k(h,U),8192&r[0]&&y!==(y=e[54].pubkey)&&A(f,"title",y),8192&r[0]&&P!==(P=e[54].blob_count+"")&&k(C,P),8192&r[0]&&R!==(R=Dv(e[54].total_size_bytes)+"")&&k(S,R)},d(e){e&&d(t),O.d(),F=!1,r(D)}}}function bv(e){let t,n,i,o,s,a,l,f,h,y,b,I,C,E,x,B,S,Q,F,D,$,U,P,R,T,N,O,M,L,_,H,j,G,J,K,V,z,q,Y,W,Z,X,ee,te=Uv(e[10].sha256)+"",ne=(e[10].type||"unknown")+"",re="image"===Pv(e[10].type),ie=Dv(e[10].size)+"",oe=$v(e[10].uploaded)+"",se=re&&kv(e);function ae(e,t){return 1024&t[0]&&(B=null),1024&t[0]&&(S=null),1024&t[0]&&(Q=null),null==B&&(B=!("image"!==Pv(e[10].type))),B?xv:(null==S&&(S=!("video"!==Pv(e[10].type))),S?Ev:(null==Q&&(Q=!("audio"!==Pv(e[10].type))),Q?Cv:Iv))}let le=ae(e,[-1,-1]),ce=le(e);return{c(){t=p("div"),n=p("div"),i=p("div"),o=p("div"),s=p("span"),a=g(te),l=m(),f=p("span"),h=g(ne),y=m(),b=p("div"),se&&se.c(),I=m(),C=p("button"),C.textContent="X",E=m(),x=p("div"),ce.c(),F=m(),D=p("div"),$=p("div"),U=p("span"),P=g("Size: "),R=g(ie),T=m(),N=p("span"),O=g("Uploaded: "),M=g(oe),L=m(),_=p("div"),H=p("input"),G=m(),J=p("button"),J.textContent="Copy",K=m(),V=p("div"),z=p("a"),q=g("Open in New Tab"),W=m(),Z=p("button"),Z.textContent="Delete",A(s,"class","modal-hash svelte-bz95vx"),A(f,"class","modal-type svelte-bz95vx"),A(o,"class","modal-title svelte-bz95vx"),A(C,"class","close-btn svelte-bz95vx"),A(b,"class","modal-controls svelte-bz95vx"),A(i,"class","modal-header svelte-bz95vx"),A(x,"class","modal-body svelte-bz95vx"),A($,"class","blob-details svelte-bz95vx"),A(H,"type","text"),H.readOnly=!0,H.value=j=Tv(e[10]),A(H,"class","blob-url-input svelte-bz95vx"),A(J,"class","copy-btn svelte-bz95vx"),A(_,"class","blob-url-section svelte-bz95vx"),A(z,"href",Y=Tv(e[10])),A(z,"target","_blank"),A(z,"rel","noopener noreferrer"),A(z,"class","action-btn svelte-bz95vx"),A(Z,"class","action-btn danger svelte-bz95vx"),A(V,"class","modal-actions svelte-bz95vx"),A(D,"class","modal-footer svelte-bz95vx"),A(n,"class","modal-content svelte-bz95vx"),A(n,"role","dialog"),A(t,"class","modal-overlay svelte-bz95vx"),A(t,"role","button"),A(t,"tabindex","0")},m(r,d){u(r,t,d),c(t,n),c(n,i),c(i,o),c(o,s),c(s,a),c(o,l),c(o,f),c(f,h),c(i,y),c(i,b),se&&se.m(b,null),c(b,I),c(b,C),c(n,E),c(n,x),ce.m(x,null),c(n,F),c(n,D),c(D,$),c($,U),c(U,P),c(U,R),c($,T),c($,N),c(N,O),c(N,M),c(D,L),c(D,_),c(_,H),c(_,G),c(_,J),c(D,K),c(D,V),c(V,z),c(z,q),c(V,W),c(V,Z),X||(ee=[v(C,"click",e[17]),v(H,"click",Ov),v(J,"click",e[45]),v(Z,"click",e[46]),v(n,"click",w(e[37])),v(n,"keypress",w(e[38])),v(t,"click",e[17]),v(t,"keypress",e[47])],X=!0)},p(e,t){1024&t[0]&&te!==(te=Uv(e[10].sha256)+"")&&k(a,te),1024&t[0]&&ne!==(ne=(e[10].type||"unknown")+"")&&k(h,ne),1024&t[0]&&(re="image"===Pv(e[10].type)),re?se?se.p(e,t):(se=kv(e),se.c(),se.m(b,I)):se&&(se.d(1),se=null),le===(le=ae(e,t))&&ce?ce.p(e,t):(ce.d(1),ce=le(e),ce&&(ce.c(),ce.m(x,null))),1024&t[0]&&ie!==(ie=Dv(e[10].size)+"")&&k(R,ie),1024&t[0]&&oe!==(oe=$v(e[10].uploaded)+"")&&k(M,oe),1024&t[0]&&j!==(j=Tv(e[10]))&&H.value!==j&&(H.value=j),1024&t[0]&&Y!==(Y=Tv(e[10]))&&A(z,"href",Y)},d(e){e&&d(t),se&&se.d(),ce.d(),X=!1,r(ee)}}}function kv(e){let t,n,i,o,s,a,l,f,h,y,w,b,I,C=Math.round(100*e[11])+"";return{c(){t=p("button"),n=g("-"),o=m(),s=p("span"),a=g(C),l=g("%"),f=m(),h=p("button"),y=g("+"),A(t,"class","zoom-btn svelte-bz95vx"),t.disabled=i=e[11]<=Sv,A(s,"class","zoom-level svelte-bz95vx"),A(h,"class","zoom-btn svelte-bz95vx"),h.disabled=w=e[11]>=Qv},m(r,i){u(r,t,i),c(t,n),u(r,o,i),u(r,s,i),c(s,a),c(s,l),u(r,f,i),u(r,h,i),c(h,y),b||(I=[v(t,"click",e[19]),v(h,"click",e[18])],b=!0)},p(e,n){2048&n[0]&&i!==(i=e[11]<=Sv)&&(t.disabled=i),2048&n[0]&&C!==(C=Math.round(100*e[11])+"")&&k(a,C),2048&n[0]&&w!==(w=e[11]>=Qv)&&(h.disabled=w)},d(e){e&&d(t),e&&d(o),e&&d(s),e&&d(f),e&&d(h),b=!1,r(I)}}}function Iv(e){let t,n,r,i,o,s,a,l,f,h=Rv(e[10].type)+"";return{c(){t=p("div"),n=p("div"),r=g(h),i=m(),o=p("p"),o.textContent="Preview not available for this file type.",s=m(),a=p("a"),l=g("Download File"),A(n,"class","file-icon svelte-bz95vx"),A(a,"href",f=Tv(e[10])),A(a,"target","_blank"),A(a,"rel","noopener noreferrer"),A(a,"class","download-link svelte-bz95vx"),A(t,"class","file-preview svelte-bz95vx")},m(e,d){u(e,t,d),c(t,n),c(n,r),c(t,i),c(t,o),c(t,s),c(t,a),c(a,l)},p(e,t){1024&t[0]&&h!==(h=Rv(e[10].type)+"")&&k(r,h),1024&t[0]&&f!==(f=Tv(e[10]))&&A(a,"href",f)},d(e){e&&d(t)}}}function Cv(e){let t,n,r;return{c(){t=p("div"),n=p("audio"),n.controls=!0,a(n.src,r=Tv(e[10]))||A(n,"src",r),A(n,"class","svelte-bz95vx"),A(t,"class","media-container audio svelte-bz95vx")},m(e,r){u(e,t,r),c(t,n)},p(e,t){1024&t[0]&&!a(n.src,r=Tv(e[10]))&&A(n,"src",r)},d(e){e&&d(t)}}}function Ev(e){let t,n,r,i;return{c(){t=p("div"),n=p("video"),r=p("track"),A(r,"kind","captions"),n.controls=!0,a(n.src,i=Tv(e[10]))||A(n,"src",i),A(n,"class","svelte-bz95vx"),A(t,"class","media-container svelte-bz95vx")},m(e,i){u(e,t,i),c(t,n),c(n,r)},p(e,t){1024&t[0]&&!a(n.src,i=Tv(e[10]))&&A(n,"src",i)},d(e){e&&d(t)}}}function xv(e){let t,n,r;return{c(){t=p("div"),n=p("img"),a(n.src,r=Tv(e[10]))||A(n,"src",r),A(n,"alt","Blob content"),A(n,"class","svelte-bz95vx"),A(t,"class","media-container svelte-bz95vx"),C(t,"transform","scale("+e[11]+")")},m(e,r){u(e,t,r),c(t,n)},p(e,i){1024&i[0]&&!a(n.src,r=Tv(e[10]))&&A(n,"src",r),2048&i[0]&&C(t,"transform","scale("+e[11]+")")},d(e){e&&d(t)}}}function Bv(t){let n,r,i,o;function s(e,t){return e[2]?ev:Xy}let a=s(t),l=a(t),c=t[9]&&t[10]&&bv(t);return{c(){l.c(),n=m(),c&&c.c(),r=y()},m(e,s){l.m(e,s),u(e,n,s),c&&c.m(e,s),u(e,r,s),i||(o=v(Yy,"keydown",t[20]),i=!0)},p(e,t){a===(a=s(e))&&l?l.p(e,t):(l.d(1),l=a(e),l&&(l.c(),l.m(n.parentNode,n))),e[9]&&e[10]?c?c.p(e,t):(c=bv(e),c.c(),c.m(r.parentNode,r)):c&&(c.d(1),c=null)},i:e,o:e,d(e){l.d(e),e&&d(n),c&&c.d(e),e&&d(r),i=!1,o()}}}const Sv=.25,Qv=4;async function Fv(e,t,n=null){if(!e)return console.log("No signer available for Blossom auth"),null;try{const r=Math.floor(Date.now()/1e3),i=[["t",t],["expiration",(r+60).toString()]];n&&i.push(["x",n]);const o={kind:24242,created_at:r,tags:i,content:`Blossom ${t} operation`},s=await e.signEvent(o);return btoa(JSON.stringify(s))}catch(e){return console.error("Error creating Blossom auth:",e),null}}function Dv(e){if(!e)return"0 B";const t=["B","KB","MB","GB"];let n=0,r=e;for(;r>=1024&&ne.target.select();function Mv(e,t,n){let r,i,{isLoggedIn:o=!1}=t,{userPubkey:s=""}=t,{userSigner:a=null}=t,{currentEffectiveRole:l=""}=t;const c=$();let u,d=[],f=!1,p="",h=[],g=!1,m="",y=!1,v=null,w=1,A=!1,b=[],k=!1,I=null,C=[],E=!1;async function x(){if(s){n(1,f=!0),n(4,p="");try{const e=`${window.location.origin}/blossom/list/${s}`,t=await Fv(a,"list"),n=await fetch(e,{headers:t?{Authorization:`Nostr ${t}`}:{}});if(!n.ok)throw new Error(`Failed to load blobs: ${n.statusText}`);const r=await n.json();d=Array.isArray(r)?r:[],d.sort((e,t)=>(t.uploaded||0)-(e.uploaded||0)),console.log("Loaded blobs:",d)}catch(e){console.error("Error loading blobs:",e),n(4,p=e.message||"Failed to load blobs")}finally{n(1,f=!1)}}}function B(e){n(10,v=e),n(11,w=1),n(9,y=!0)}function S(){n(9,y=!1),n(10,v=null),n(11,w=1)}function Q(){wSv&&n(11,w=Math.max(Sv,w-.25))}async function P(e){if(confirm(`Delete blob ${Uv(e.sha256)}?`))try{const t=`${window.location.origin}/blossom/${e.sha256}`,n=await Fv(a,"delete",e.sha256),r=await fetch(t,{method:"DELETE",headers:n?{Authorization:`Nostr ${n}`}:{}});if(!r.ok)throw new Error(`Failed to delete: ${r.statusText}`);d=d.filter(t=>t.sha256!==e.sha256),v?.sha256===e.sha256&&S()}catch(e){console.error("Error deleting blob:",e),alert(`Failed to delete blob: ${e.message}`)}}async function T(){n(14,k=!0),n(4,p="");try{const e=`${window.location.origin}/blossom/admin/users`,t=await Fv(a,"admin"),r=await fetch(e,{headers:t?{Authorization:`Nostr ${t}`}:{}});if(!r.ok)throw new Error(`Failed to load user stats: ${r.statusText}`);n(13,b=await r.json());for(const e of b)Cp(e.pubkey).then(t=>{e.profile=t||{name:"",picture:""},n(13,b)}).catch(()=>{e.profile={name:"",picture:""}})}catch(e){console.error("Error fetching admin user stats:",e),n(4,p=e.message||"Failed to load user stats")}finally{n(14,k=!1)}}async function N(e){n(1,f=!0),n(4,p="");try{const t=`${window.location.origin}/blossom/list/${e}`,n=await Fv(a,"list"),r=await fetch(t,{headers:n?{Authorization:`Nostr ${n}`}:{}});if(!r.ok)throw new Error(`Failed to load user blobs: ${r.statusText}`);C=await r.json(),C.sort((e,t)=>(t.uploaded||0)-(e.uploaded||0))}catch(e){console.error("Error loading user blobs:",e),n(4,p=e.message||"Failed to load user blobs")}finally{n(1,f=!1)}}async function O(e){n(15,I={pubkey:e.pubkey,profile:e.profile}),await N(e.pubkey)}F(()=>{r&&!E&&(n(36,E=!0),x())});return e.$$set=e=>{"isLoggedIn"in e&&n(33,o=e.isLoggedIn),"userPubkey"in e&&n(34,s=e.userPubkey),"userSigner"in e&&n(35,a=e.userSigner),"currentEffectiveRole"in e&&n(0,l=e.currentEffectiveRole)},e.$$.update=()=>{12&e.$$.dirty[1]&&n(2,r=o&&s),1&e.$$.dirty[0]&&n(3,i="admin"===l||"owner"===l),9&e.$$.dirty[0]&&console.log("BlossomView role:",l,"isAdmin:",i),6&e.$$.dirty[0]|32&e.$$.dirty[1]&&(!r||E||f||(n(36,E=!0),x()))},[l,f,r,i,p,h,g,m,u,y,v,w,A,b,k,I,B,S,Q,D,function(e){y&&("Escape"===e.key?S():"+"===e.key||"="===e.key?Q():"-"===e.key&&D())},function(){c("openLoginModal")},P,function(e){n(5,h=Array.from(e.target.files))},function(){u?.click()},async function(){if(0===h.length)return;n(6,g=!0),n(4,p="");const e=[],t=[];for(let r=0;r0&&await x(),t.length>0&&n(4,p=`Failed to upload: ${t.map(e=>e.name).join(", ")}`)},function(e){try{return vu(e)}catch(t){return Uv(e)}},function(){n(12,A=!0),T()},function(){n(12,A=!1),n(13,b=[]),n(15,I=null),C=[]},O,function(){n(15,I=null),C=[]},function(){I?N(I.pubkey):A?T():x()},function(){return I?C:d},o,s,a,E,function(t){U.call(this,e,t)},function(t){U.call(this,e,t)},function(e){R[e?"unshift":"push"](()=>{u=e,n(8,u)})},e=>O(e),(e,t)=>"Enter"===t.key&&O(e),e=>P(e),e=>B(e),(e,t)=>"Enter"===t.key&&B(e),()=>{navigator.clipboard.writeText(Tv(v))},()=>P(v),e=>"Enter"===e.key&&S()]}class Lv extends ie{constructor(e){super(),re(this,e,Mv,Bv,o,{isLoggedIn:33,userPubkey:34,userSigner:35,currentEffectiveRole:0},null,[-1,-1])}}function _v(e){let t,n,r,i,o,s,a,l,f,h,y;return{c(){t=p("div"),n=p("div"),r=p("h3"),r.textContent="Active Filter",i=m(),o=p("button"),o.textContent="🧹 Sweep",s=m(),a=p("div"),l=p("pre"),f=g(e[2]),A(r,"class","svelte-1tyqaa5"),A(o,"class","sweep-btn svelte-1tyqaa5"),A(o,"title","Clear filter"),A(n,"class","filter-display-header svelte-1tyqaa5"),A(l,"class","filter-json svelte-1tyqaa5"),A(a,"class","filter-json-container svelte-1tyqaa5"),A(t,"class","filter-display svelte-1tyqaa5")},m(d,p){u(d,t,p),c(t,n),c(n,r),c(n,i),c(n,o),c(t,s),c(t,a),c(a,l),c(l,f),h||(y=v(o,"click",e[3]),h=!0)},p(e,t){4&t&&k(f,e[2])},d(e){e&&d(t),h=!1,y()}}}function Hv(t){let n,r=t[0]&&t[1]&&_v(t);return{c(){r&&r.c(),n=y()},m(e,t){r&&r.m(e,t),u(e,n,t)},p(e,[t]){e[0]&&e[1]?r?r.p(e,t):(r=_v(e),r.c(),r.m(n.parentNode,n)):r&&(r.d(1),r=null)},i:e,o:e,d(e){r&&r.d(e),e&&d(n)}}}function jv(e,t,n){let r,i;const o=$();let{filter:s={}}=t,{showFilter:a=!0}=t;return e.$$set=e=>{"filter"in e&&n(4,s=e.filter),"showFilter"in e&&n(0,a=e.showFilter)},e.$$.update=()=>{16&e.$$.dirty&&n(2,r=function(e){return JSON.stringify(e,null,2)}(s)),16&e.$$.dirty&&n(1,i=Object.keys(s).length>0)},[a,i,r,function(){o("sweep")},s]}class Gv extends ie{constructor(e){super(),re(this,e,jv,Hv,o,{filter:4,showFilter:0})}}function Jv(e){return fp[e]||`Kind ${e}`}function Kv(e){return e?e.slice(0,8)+"..."+e.slice(-8):"unknown"}function Vv(e,t=100){return e?e.length>t?e.slice(0,t)+"...":e:""}function zv(e){return e?new Date(1e3*e).toLocaleString():""}class qv{constructor(e,t,n){this.relayUrl=e,this.userSigner=t,this.userPubkey=n,this.ws=null,this.challenge=null,this.isAuthenticated=!1,this.authPromise=null}async connect(){return new Promise((e,t)=>{this.ws=new WebSocket(this.relayUrl),this.ws.onopen=()=>{console.log("WebSocket connected to relay:",this.relayUrl),e()},this.ws.onmessage=async e=>{try{const t=JSON.parse(e.data);await this.handleMessage(t)}catch(e){console.error("Error parsing relay message:",e)}},this.ws.onerror=e=>{console.error("WebSocket error:",e),t(new Error("Failed to connect to relay"))},this.ws.onclose=()=>{console.log("WebSocket connection closed"),this.isAuthenticated=!1,this.challenge=null},setTimeout(()=>{this.ws.readyState!==WebSocket.OPEN&&t(new Error("Connection timeout"))},1e4)})}async handleMessage(e){const[t,...n]=e;switch(t){case"AUTH":this.challenge=n[0],console.log("Received AUTH challenge:",this.challenge),await this.authenticate();break;case"OK":const[e,r,i]=n;e&&r?(console.log("Authentication successful for event:",e),this.isAuthenticated=!0,this.authPromise&&(this.authPromise.resolve(),this.authPromise=null)):e&&!r&&(console.error("Authentication failed:",i),this.authPromise&&(this.authPromise.reject(new Error(i||"Authentication failed")),this.authPromise=null));break;case"NOTICE":console.log("Relay notice:",n[0]);break;default:console.log("Unhandled message type:",t,n)}}async authenticate(){if(!this.challenge)throw new Error("No challenge received from relay");if(!this.userSigner)throw new Error("No signer available for authentication");try{const e={kind:22242,created_at:Math.floor(Date.now()/1e3),tags:[["relay",this.relayUrl],["challenge",this.challenge]],content:"",pubkey:this.userPubkey},t=["AUTH",await this.userSigner.signEvent(e)];return this.ws.send(JSON.stringify(t)),console.log("Sent authentication event to relay"),new Promise((e,t)=>{this.authPromise={resolve:e,reject:t},setTimeout(()=>{this.authPromise&&(this.authPromise.reject(new Error("Authentication timeout")),this.authPromise=null)},1e4)})}catch(e){throw console.error("Authentication error:",e),e}}async publishEvent(e){if(!this.ws||this.ws.readyState!==WebSocket.OPEN)throw new Error("WebSocket not connected");return new Promise((t,n)=>{const r=["EVENT",e];this.ws.send(JSON.stringify(r));const i=this.ws.onmessage,o=setTimeout(()=>{this.ws.onmessage=i,n(new Error("Publish timeout"))},15e3);this.ws.onmessage=async r=>{try{const s=JSON.parse(r.data),[a,l,c,u]=s;if("OK"===a&&l===e.id)if(c)clearTimeout(o),this.ws.onmessage=i,console.log("Event published successfully:",l),t({success:!0,eventId:l,reason:u});else{if(console.error("Event publish failed:",u),u&&u.includes("auth-required"))return void console.log("Authentication required, waiting for AUTH challenge...");clearTimeout(o),this.ws.onmessage=i,n(new Error(`Publish failed: ${u}`))}else if("AUTH"===a){this.challenge=s[1],console.log("Received AUTH challenge during publish:",this.challenge);try{await this.authenticate(),console.log("Authentication successful, retrying event publish...");const t=["EVENT",e];this.ws.send(JSON.stringify(t))}catch(e){clearTimeout(o),this.ws.onmessage=i,n(new Error(`Authentication failed: ${e.message}`))}}else await this.handleMessage(s)}catch(e){clearTimeout(o),this.ws.onmessage=i,n(e)}}})}close(){this.ws&&(this.ws.close(),this.ws=null),this.isAuthenticated=!1,this.challenge=null}getAuthenticated(){return this.isAuthenticated}}async function Yv(e,t,n,r){const i=new qv(e,n,r);try{await i.connect();return await i.publishEvent(t)}finally{i.close()}}function Wv(e,t,n){const r=e.slice();return r[169]=t[n],r}function Zv(e,t,n){const r=e.slice();return r[179]=t[n],r}function Xv(e,t,n){const r=e.slice();return r[172]=t[n],r}function ew(e,t,n){const r=e.slice();r[172]=t[n];const i=r[52](r[172]);return r[173]=i,r}function tw(e,t,n){const r=e.slice();return r[176]=t[n],r}function nw(t){let n;function r(e,t){return e[1]?hw:pw}let i=r(t),o=i(t);return{c(){n=p("div"),o.c(),A(n,"class","welcome-message svelte-u3u5mw")},m(e,t){u(e,n,t),o.m(n,null)},p(e,t){i===(i=r(e))&&o?o.p(e,t):(o.d(1),o=i(e),o&&(o.c(),o.m(n,null)))},i:e,o:e,d(e){e&&d(n),o.d()}}}function rw(e){let t,n,r=e[6],i=[];for(let t=0;tW(i[e],1,1,()=>{i[e]=null});return{c(){for(let e=0;e=0||""!==t[36]&&parseInt(t[36])>=0,U=dp,P=[];for(let e=0;eEvent Recovery \n Search and recover old versions of replaceable events
',o=m(),s=p("div"),a=p("div"),l=p("div"),h=p("label"),h.textContent="Select Event Kind:",g=m(),y=p("select"),w=p("option"),w.textContent="Choose a replaceable kind...";for(let e=0;et[115].call(y)),A(l,"class","kind-selector svelte-u3u5mw"),A(x,"for","custom-kind"),A(x,"class","svelte-u3u5mw"),A(S,"id","custom-kind"),A(S,"type","number"),A(S,"placeholder","e.g., 10001"),A(S,"min","0"),A(S,"class","svelte-u3u5mw"),A(C,"class","custom-kind-input svelte-u3u5mw"),A(a,"class","recovery-controls svelte-u3u5mw"),A(s,"class","recovery-controls-card svelte-u3u5mw"),A(n,"class","recovery-tab svelte-u3u5mw")},m(e,r){u(e,n,r),c(n,i),c(n,o),c(n,s),c(s,a),c(a,l),c(l,h),c(l,g),c(l,y),c(y,w);for(let e=0;e=0||""!==e[36]&&parseInt(e[36])>=0),$?R?R.p(e,t):(R=Ew(e),R.c(),R.m(n,null)):R&&(R.d(1),R=null)},i:e,o:e,d(e){e&&d(n),f(P,e),R&&R.d(),F=!1,r(D)}}}function ow(e){let t,n,r;function i(t){e[114](t)}let o={isLoggedIn:e[1],userRole:e[4],isPolicyAdmin:qw,policyEnabled:e[8],isLoadingPolicy:e[27],policyMessage:e[28],policyMessageType:e[29],validationErrors:e[30],policyFollows:e[31]};return void 0!==e[26]&&(o.policyJson=e[26]),t=new qy({props:o}),R.push(()=>Z(t,"policyJson",i)),t.$on("loadPolicy",e[60]),t.$on("validatePolicy",e[61]),t.$on("savePolicy",e[62]),t.$on("formatJson",e[63]),t.$on("addPolicyAdmin",e[64]),t.$on("removePolicyAdmin",e[65]),t.$on("refreshFollows",e[66]),t.$on("openLoginModal",e[70]),{c(){X(t.$$.fragment)},m(e,n){ee(t,e,n),r=!0},p(e,r){const i={};2&r[0]&&(i.isLoggedIn=e[1]),16&r[0]&&(i.userRole=e[4]),256&r[0]&&(i.policyEnabled=e[8]),134217728&r[0]&&(i.isLoadingPolicy=e[27]),268435456&r[0]&&(i.policyMessage=e[28]),536870912&r[0]&&(i.policyMessageType=e[29]),1073741824&r[0]&&(i.validationErrors=e[30]),1&r[1]&&(i.policyFollows=e[31]),!n&&67108864&r[0]&&(n=!0,i.policyJson=e[26],_(()=>n=!1)),t.$set(i)},i(e){r||(Y(t.$$.fragment,e),r=!0)},o(e){W(t.$$.fragment,e),r=!1},d(e){te(t,e)}}}function sw(e){let t,n,r;function i(t){e[111](t)}let o={isLoggedIn:e[1],userRole:e[4],sprocketStatus:e[20],isLoadingSprocket:e[22],sprocketUploadFile:e[25],sprocketMessage:e[23],sprocketMessageType:e[24],sprocketVersions:e[21]};return void 0!==e[19]&&(o.sprocketScript=e[19]),t=new Fy({props:o}),R.push(()=>Z(t,"sprocketScript",i)),t.$on("restartSprocket",e[55]),t.$on("deleteSprocket",e[56]),t.$on("sprocketFileSelect",e[67]),t.$on("uploadSprocketScript",e[68]),t.$on("saveSprocket",e[54]),t.$on("loadSprocket",e[53]),t.$on("loadVersions",e[57]),t.$on("loadVersion",e[112]),t.$on("deleteVersion",e[113]),t.$on("openLoginModal",e[70]),{c(){X(t.$$.fragment)},m(e,n){ee(t,e,n),r=!0},p(e,r){const i={};2&r[0]&&(i.isLoggedIn=e[1]),16&r[0]&&(i.userRole=e[4]),1048576&r[0]&&(i.sprocketStatus=e[20]),4194304&r[0]&&(i.isLoadingSprocket=e[22]),33554432&r[0]&&(i.sprocketUploadFile=e[25]),8388608&r[0]&&(i.sprocketMessage=e[23]),16777216&r[0]&&(i.sprocketMessageType=e[24]),2097152&r[0]&&(i.sprocketVersions=e[21]),!n&&524288&r[0]&&(n=!0,i.sprocketScript=e[19],_(()=>n=!1)),t.$set(i)},i(e){r||(Y(t.$$.fragment,e),r=!0)},o(e){W(t.$$.fragment,e),r=!1},d(e){te(t,e)}}}function aw(e){let t,n,r,i;const o=[Tw,Rw,Pw],s=[];function a(e,t){return"managed"!==e[9]?0:e[1]&&"owner"===e[4]?1:2}return n=a(e),r=s[n]=o[n](e),{c(){t=p("div"),r.c(),A(t,"class","managed-acl-view svelte-u3u5mw")},m(e,r){u(e,t,r),s[n].m(t,null),i=!0},p(e,i){let l=n;n=a(e),n===l?s[n].p(e,i):(z(),W(s[l],1,1,()=>{s[l]=null}),q(),r=s[n],r?r.p(e,i):(r=s[n]=o[n](e),r.c()),Y(r,1),r.m(t,null))},i(e){i||(Y(r),i=!0)},o(e){W(r),i=!1},d(e){e&&d(t),s[n].d()}}}function lw(e){let t,n,r;function i(t){e[110](t)}let o={userPubkey:e[2],userRole:e[4],policyEnabled:e[8],publishError:e[34]};return void 0!==e[33]&&(o.composeEventJson=e[33]),t=new vy({props:o}),R.push(()=>Z(t,"composeEventJson",i)),t.$on("reformatJson",e[90]),t.$on("signEvent",e[91]),t.$on("publishEvent",e[92]),t.$on("clearError",e[93]),{c(){X(t.$$.fragment)},m(e,n){ee(t,e,n),r=!0},p(e,r){const i={};4&r[0]&&(i.userPubkey=e[2]),16&r[0]&&(i.userRole=e[4]),256&r[0]&&(i.policyEnabled=e[8]),8&r[1]&&(i.publishError=e[34]),!n&&4&r[1]&&(n=!0,i.composeEventJson=e[33],_(()=>n=!1)),t.$set(i)},i(e){r||(Y(t.$$.fragment,e),r=!0)},o(e){W(t.$$.fragment,e),r=!1},d(e){te(t,e)}}}function cw(e){let t,n;return t=new Lv({props:{isLoggedIn:e[1],userPubkey:e[2],userSigner:e[13],currentEffectiveRole:e[10]}}),t.$on("openLoginModal",e[70]),{c(){X(t.$$.fragment)},m(e,r){ee(t,e,r),n=!0},p(e,n){const r={};2&n[0]&&(r.isLoggedIn=e[1]),4&n[0]&&(r.userPubkey=e[2]),8192&n[0]&&(r.userSigner=e[13]),1024&n[0]&&(r.currentEffectiveRole=e[10]),t.$set(r)},i(e){n||(Y(t.$$.fragment,e),n=!0)},o(e){W(t.$$.fragment,e),n=!1},d(e){te(t,e)}}}function uw(e){let t,n;return t=new Zm({props:{isLoggedIn:e[1],userRole:e[4],userPubkey:e[2],filteredEvents:e[41],expandedEvents:e[18],isLoadingEvents:e[7],showOnlyMyEvents:zw,showFilterBuilder:e[15]}}),t.$on("scroll",e[89]),t.$on("toggleEventExpansion",e[106]),t.$on("deleteEvent",e[107]),t.$on("copyEventToClipboard",e[108]),t.$on("toggleChange",e[45]),t.$on("loadAllEvents",e[109]),t.$on("toggleFilterBuilder",e[76]),t.$on("filterApply",e[77]),t.$on("filterClear",e[78]),{c(){X(t.$$.fragment)},m(e,r){ee(t,e,r),n=!0},p(e,n){const r={};2&n[0]&&(r.isLoggedIn=e[1]),16&n[0]&&(r.userRole=e[4]),4&n[0]&&(r.userPubkey=e[2]),1024&n[1]&&(r.filteredEvents=e[41]),262144&n[0]&&(r.expandedEvents=e[18]),128&n[0]&&(r.isLoadingEvents=e[7]),32768&n[0]&&(r.showFilterBuilder=e[15]),t.$set(r)},i(e){n||(Y(t.$$.fragment,e),n=!0)},o(e){W(t.$$.fragment,e),n=!1},d(e){te(t,e)}}}function dw(e){let t,n;return t=new Zg({props:{isLoggedIn:e[1],currentEffectiveRole:e[10],selectedFile:e[16],aclMode:e[9],importMessage:e[17]}}),t.$on("fileSelect",e[86]),t.$on("importEvents",e[87]),t.$on("openLoginModal",e[70]),{c(){X(t.$$.fragment)},m(e,r){ee(t,e,r),n=!0},p(e,n){const r={};2&n[0]&&(r.isLoggedIn=e[1]),1024&n[0]&&(r.currentEffectiveRole=e[10]),65536&n[0]&&(r.selectedFile=e[16]),512&n[0]&&(r.aclMode=e[9]),131072&n[0]&&(r.importMessage=e[17]),t.$set(r)},i(e){n||(Y(t.$$.fragment,e),n=!0)},o(e){W(t.$$.fragment,e),n=!1},d(e){te(t,e)}}}function fw(e){let t,n;return t=new Jg({props:{isLoggedIn:e[1],currentEffectiveRole:e[10],aclMode:e[9]}}),t.$on("exportMyEvents",e[85]),t.$on("exportAllEvents",e[84]),t.$on("openLoginModal",e[70]),{c(){X(t.$$.fragment)},m(e,r){ee(t,e,r),n=!0},p(e,n){const r={};2&n[0]&&(r.isLoggedIn=e[1]),1024&n[0]&&(r.currentEffectiveRole=e[10]),512&n[0]&&(r.aclMode=e[9]),t.$set(r)},i(e){n||(Y(t.$$.fragment,e),n=!0)},o(e){W(t.$$.fragment,e),n=!1},d(e){te(t,e)}}}function pw(t){let n;return{c(){n=p("p"),n.textContent="Log in to access your user dashboard",A(n,"class","svelte-u3u5mw")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function hw(e){let t,n,r,i=(e[3]?.name||e[2].slice(0,8)+"...")+"";return{c(){t=p("p"),n=g("Welcome "),r=g(i),A(t,"class","svelte-u3u5mw")},m(e,i){u(e,t,i),c(t,n),c(t,r)},p(e,t){12&t[0]&&i!==(i=(e[3]?.name||e[2].slice(0,8)+"...")+"")&&k(r,i)},d(e){e&&d(t)}}}function gw(e){let t,n,i,o,s,a,l,f,h,y,w,b,I,C,E,x,B,S,Q,F,D,$=e[179].label+"",U=e[42].get(e[179].id)?.isLoading,P=!e[42].get(e[179].id)?.hasMore&&e[42].get(e[179].id)?.events?.length>0;function R(){return e[120](e[179])}function T(e,t){return 64&t[0]&&(C=null),64&t[0]&&(E=null),null==C&&(C=!!(e[42].get(e[179].id)?.events?.length>0)),C?yw:(null==E&&(E=!e[42].get(e[179].id)?.isLoading),E?mw:void 0)}w=new Gv({props:{filter:e[42].get(e[179].id)?.filter||{}}}),w.$on("sweep",function(){return e[121](e[179])});let N=T(e,[-1,-1,-1,-1,-1,-1]),O=N&&N(e),M=U&&bw(),L=P&&kw();function _(...t){return e[126](e[179],...t)}return{c(){t=p("div"),n=p("div"),i=p("h2"),o=g("🔍 "),s=g($),a=m(),l=p("button"),f=g("🔄 Refresh"),y=m(),X(w.$$.fragment),b=m(),I=p("div"),O&&O.c(),x=m(),M&&M.c(),B=m(),L&&L.c(),S=m(),A(i,"class","svelte-u3u5mw"),A(l,"class","refresh-btn svelte-u3u5mw"),l.disabled=h=e[42].get(e[179].id)?.isLoading,A(n,"class","search-results-header svelte-u3u5mw"),A(I,"class","search-results-content svelte-u3u5mw"),A(t,"class","search-results-view svelte-u3u5mw")},m(e,r){u(e,t,r),c(t,n),c(n,i),c(i,o),c(i,s),c(n,a),c(n,l),c(l,f),c(t,y),ee(w,t,null),c(t,b),c(t,I),O&&O.m(I,null),c(I,x),M&&M.m(I,null),c(I,B),L&&L.m(I,null),c(t,S),Q=!0,F||(D=[v(l,"click",R),v(I,"scroll",_)],F=!0)},p(t,n){e=t,(!Q||64&n[0])&&$!==($=e[179].label+"")&&k(s,$),(!Q||64&n[0]&&h!==(h=e[42].get(e[179].id)?.isLoading))&&(l.disabled=h);const r={};64&n[0]&&(r.filter=e[42].get(e[179].id)?.filter||{}),w.$set(r),N===(N=T(e,n))&&O?O.p(e,n):(O&&O.d(1),O=N&&N(e),O&&(O.c(),O.m(I,x))),64&n[0]&&(U=e[42].get(e[179].id)?.isLoading),U?M||(M=bw(),M.c(),M.m(I,B)):M&&(M.d(1),M=null),64&n[0]&&(P=!e[42].get(e[179].id)?.hasMore&&e[42].get(e[179].id)?.events?.length>0),P?L||(L=kw(),L.c(),L.m(I,null)):L&&(L.d(1),L=null)},i(e){Q||(Y(w.$$.fragment,e),Q=!0)},o(e){W(w.$$.fragment,e),Q=!1},d(e){e&&d(t),te(w),O&&O.d(),M&&M.d(),L&&L.d(),F=!1,r(D)}}}function mw(t){let n;return{c(){n=p("div"),n.innerHTML='No search results found.
',A(n,"class","no-search-results svelte-u3u5mw")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function yw(e){let t,n=e[42].get(e[179].id).events,r=[];for(let t=0;t👤',o=m(),s=p("div"),a=p("div"),l=g(O),f=m(),h=p("div"),y=p("span"),w=g(M),b=m(),I=p("span"),C=g(L),E=m(),B=p("div"),S=p("div"),Q=g(_),F=m(),D=p("div"),$=g(H),U=m(),G&&G.c(),P=m(),V&&V.c(),R=m(),A(i,"class","search-result-avatar svelte-u3u5mw"),A(a,"class","search-result-author svelte-u3u5mw"),A(y,"class","kind-number svelte-u3u5mw"),A(I,"class","kind-name svelte-u3u5mw"),A(h,"class","search-result-kind svelte-u3u5mw"),A(s,"class","search-result-info svelte-u3u5mw"),A(S,"class","event-timestamp svelte-u3u5mw"),A(D,"class","event-content-single-line svelte-u3u5mw"),A(B,"class","search-result-content svelte-u3u5mw"),A(n,"class","search-result-row svelte-u3u5mw"),A(n,"role","button"),A(n,"tabindex","0"),A(t,"class","search-result-item svelte-u3u5mw"),x(t,"expanded",e[18].has(e[172].id))},m(e,r){u(e,t,r),c(t,n),c(n,i),c(n,o),c(n,s),c(s,a),c(a,l),c(s,f),c(s,h),c(h,y),c(y,w),c(h,b),c(h,I),c(I,C),c(n,E),c(n,B),c(B,S),c(S,Q),c(B,F),c(B,D),c(D,$),c(n,U),G&&G.m(n,null),c(t,P),V&&V.m(t,null),c(t,R),T||(N=[v(n,"click",J),v(n,"keydown",K)],T=!0)},p(r,i){e=r,64&i[0]&&O!==(O=Kv(e[172].pubkey)+"")&&k(l,O),64&i[0]&&M!==(M=e[172].kind+"")&&k(w,M),64&i[0]&&L!==(L=Jv(e[172].kind)+"")&&k(C,L),64&i[0]&&_!==(_=zv(e[172].created_at)+"")&&k(Q,_),64&i[0]&&H!==(H=Vv(e[172].content)+"")&&k($,H),5!==e[172].kind&&("admin"===e[4]||"owner"===e[4]||"write"===e[4]&&e[172].pubkey&&e[172].pubkey===e[2])?G?G.p(e,i):(G=vw(e),G.c(),G.m(n,null)):G&&(G.d(1),G=null),262208&i[0]&&(j=e[18].has(e[172].id)),j?V?V.p(e,i):(V=ww(e),V.c(),V.m(t,R)):V&&(V.d(1),V=null),262208&i[0]|2048&i[1]&&x(t,"expanded",e[18].has(e[172].id))},d(e){e&&d(t),G&&G.d(),V&&V.d(),T=!1,r(N)}}}function bw(e){let t;return{c(){t=p("div"),t.innerHTML='
\n Searching...
',A(t,"class","loading-search-results svelte-u3u5mw")},m(e,n){u(e,t,n)},d(e){e&&d(t)}}}function kw(e){let t;return{c(){t=p("div"),t.innerHTML='No more search results to load.
',A(t,"class","end-of-search-results svelte-u3u5mw")},m(e,n){u(e,t,n)},d(e){e&&d(t)}}}function Iw(e){let t,n,r=e[179].id===e[5]&&gw(e);return{c(){r&&r.c(),t=y()},m(e,i){r&&r.m(e,i),u(e,t,i),n=!0},p(e,n){e[179].id===e[5]?r?(r.p(e,n),96&n[0]&&Y(r,1)):(r=gw(e),r.c(),Y(r,1),r.m(t.parentNode,t)):r&&(z(),W(r,1,1,()=>{r=null}),q())},i(e){n||(Y(r),n=!0)},o(e){W(r),n=!1},d(e){r&&r.d(e),e&&d(t)}}}function Cw(t){let n,r,i=t[176].label+"";return{c(){n=p("option"),r=g(i),n.__value=t[176].value,n.value=n.__value},m(e,t){u(e,n,t),c(n,r)},p:e,d(e){e&&d(n)}}}function Ew(e){let t;function n(e,t){return e[38]?Sw:0===e[37].length?Bw:xw}let r=n(e),i=r(e);return{c(){t=p("div"),i.c(),A(t,"class","recovery-results svelte-u3u5mw")},m(e,n){u(e,t,n),i.m(t,null)},p(e,o){r===(r=n(e))&&i?i.p(e,o):(i.d(1),i=r(e),i&&(i.c(),i.m(t,null)))},d(e){e&&d(t),i.d()}}}function xw(e){let t,n,r,i=e[37],o=[];for(let t=0;tORLY_ACL_MODE=managed in your\n environment variables and restart the relay.',A(r,"class","svelte-u3u5mw"),A(o,"class","svelte-u3u5mw"),A(a,"class","svelte-u3u5mw"),A(v,"class","svelte-u3u5mw"),A(n,"class","acl-mode-warning svelte-u3u5mw")},m(e,t){u(e,n,t),c(n,r),c(n,i),c(n,o),c(n,s),c(n,a),c(a,l),c(a,f),c(f,h),c(n,y),c(n,v)},p(e,t){512&t[0]&&w!==(w=(e[9]||"unknown")+"")&&k(h,w)},i:e,o:e,d(e){e&&d(n)}}}function Nw(e){let t,n,i,o,s,a,l,f,h,g;function y(e,t){return e[3]?Mw:e[1]&&e[2]?Ow:void 0}let b=y(e),k=b&&b(e);return{c(){t=p("div"),n=p("div"),i=p("div"),o=p("h2"),o.textContent="Settings",s=m(),a=p("button"),a.textContent="✕",l=m(),f=p("div"),k&&k.c(),A(o,"class","svelte-u3u5mw"),A(a,"class","close-btn svelte-u3u5mw"),A(i,"class","drawer-header svelte-u3u5mw"),A(f,"class","drawer-content"),A(n,"class","settings-drawer svelte-u3u5mw"),x(n,"dark-theme",e[0]),A(t,"class","drawer-overlay svelte-u3u5mw"),A(t,"role","button"),A(t,"tabindex","0")},m(r,d){u(r,t,d),c(t,n),c(n,i),c(i,o),c(i,s),c(i,a),c(n,l),c(n,f),k&&k.m(f,null),h||(g=[v(a,"click",e[75]),v(n,"click",w(e[101])),v(n,"keydown",w(e[102])),v(t,"click",e[75]),v(t,"keydown",e[128])],h=!0)},p(e,t){b===(b=y(e))&&k?k.p(e,t):(k&&k.d(1),k=b&&b(e),k&&(k.c(),k.m(f,null))),1&t[0]&&x(n,"dark-theme",e[0])},d(e){e&&d(t),k&&k.d(),h=!1,r(g)}}}function Ow(e){let t,n,i,o,s,a,l,f,h,y,w,b,I,C,E,x,B,S=e[2].slice(0,16)+"",Q=e[2].slice(-8)+"";return{c(){t=p("div"),n=p("button"),n.textContent="Log out",i=m(),o=p("h3"),o.textContent="Profile Loading",s=m(),a=p("p"),a.textContent="Your profile metadata is being loaded...",l=m(),f=p("button"),f.textContent="Retry Loading Profile",h=m(),y=p("div"),w=p("strong"),w.textContent="Public Key:",b=m(),I=g(S),C=g("..."),E=g(Q),A(n,"class","logout-btn floating svelte-u3u5mw"),A(o,"class","svelte-u3u5mw"),A(a,"class","svelte-u3u5mw"),A(f,"class","retry-profile-btn svelte-u3u5mw"),A(y,"class","user-pubkey-display svelte-u3u5mw"),A(t,"class","profile-loading-section svelte-u3u5mw")},m(r,d){u(r,t,d),c(t,n),c(t,i),c(t,o),c(t,s),c(t,a),c(t,l),c(t,f),c(t,h),c(t,y),c(y,w),c(y,b),c(y,I),c(y,C),c(y,E),x||(B=[v(n,"click",e[72]),v(f,"click",e[83])],x=!0)},p(e,t){4&t[0]&&S!==(S=e[2].slice(0,16)+"")&&k(I,S),4&t[0]&&Q!==(Q=e[2].slice(-8)+"")&&k(E,Q)},d(e){e&&d(t),x=!1,r(B)}}}function Mw(e){let t,n,r,i,o,s,a,l,f,h,w,b,I,C,E,x=(e[3].name||"Unknown User")+"",B=e[3].banner&&Lw(e);function S(e,t){return e[3].picture?Hw:_w}let Q=S(e),F=Q(e),D=e[3].nip05&&jw(e),$=e[3].about&&Gw(e),U=e[4]&&"read"!==e[4]&&Jw(e);return{c(){t=p("div"),n=p("div"),B&&B.c(),r=m(),i=p("button"),i.textContent="Log out",o=m(),F.c(),s=m(),a=p("div"),l=p("h3"),f=g(x),h=m(),D&&D.c(),w=m(),$&&$.c(),b=m(),U&&U.c(),I=y(),A(i,"class","logout-btn floating svelte-u3u5mw"),A(l,"class","profile-username svelte-u3u5mw"),A(a,"class","name-row svelte-u3u5mw"),A(n,"class","profile-hero svelte-u3u5mw"),A(t,"class","profile-section svelte-u3u5mw")},m(d,p){u(d,t,p),c(t,n),B&&B.m(n,null),c(n,r),c(n,i),c(n,o),F.m(n,null),c(n,s),c(n,a),c(a,l),c(l,f),c(a,h),D&&D.m(a,null),c(t,w),$&&$.m(t,null),u(d,b,p),U&&U.m(d,p),u(d,I,p),C||(E=v(i,"click",e[72]),C=!0)},p(e,i){e[3].banner?B?B.p(e,i):(B=Lw(e),B.c(),B.m(n,r)):B&&(B.d(1),B=null),Q===(Q=S(e))&&F?F.p(e,i):(F.d(1),F=Q(e),F&&(F.c(),F.m(n,s))),8&i[0]&&x!==(x=(e[3].name||"Unknown User")+"")&&k(f,x),e[3].nip05?D?D.p(e,i):(D=jw(e),D.c(),D.m(a,null)):D&&(D.d(1),D=null),e[3].about?$?$.p(e,i):($=Gw(e),$.c(),$.m(t,null)):$&&($.d(1),$=null),e[4]&&"read"!==e[4]?U?U.p(e,i):(U=Jw(e),U.c(),U.m(I.parentNode,I)):U&&(U.d(1),U=null)},d(e){e&&d(t),B&&B.d(),F.d(),D&&D.d(),$&&$.d(),e&&d(b),U&&U.d(e),e&&d(I),C=!1,E()}}}function Lw(e){let t,n;return{c(){t=p("img"),a(t.src,n=e[3].banner)||A(t,"src",n),A(t,"alt","Profile banner"),A(t,"class","profile-banner svelte-u3u5mw")},m(e,n){u(e,t,n)},p(e,r){8&r[0]&&!a(t.src,n=e[3].banner)&&A(t,"src",n)},d(e){e&&d(t)}}}function _w(t){let n;return{c(){n=p("div"),n.textContent="👤",A(n,"class","profile-avatar-placeholder overlap svelte-u3u5mw")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function Hw(e){let t,n;return{c(){t=p("img"),a(t.src,n=e[3].picture)||A(t,"src",n),A(t,"alt","User avatar"),A(t,"class","profile-avatar overlap svelte-u3u5mw")},m(e,n){u(e,t,n)},p(e,r){8&r[0]&&!a(t.src,n=e[3].picture)&&A(t,"src",n)},d(e){e&&d(t)}}}function jw(e){let t,n,r=e[3].nip05+"";return{c(){t=p("span"),n=g(r),A(t,"class","profile-nip05-inline svelte-u3u5mw")},m(e,r){u(e,t,r),c(t,n)},p(e,t){8&t[0]&&r!==(r=e[3].nip05+"")&&k(n,r)},d(e){e&&d(t)}}}function Gw(e){let t,n;return{c(){t=p("div"),n=p("p"),A(n,"class","profile-about svelte-u3u5mw"),A(t,"class","about-card svelte-u3u5mw")},m(r,i){u(r,t,i),c(t,n),n.innerHTML=e[40]},p(e,t){512&t[1]&&(n.innerHTML=e[40])},d(e){e&&d(t)}}}function Jw(e){let t,n,r,i,o,s,a=e[95](),l=[];for(let t=0;tZ(y,"showModal",E)),y.$on("login",e[71]),y.$on("close",e[73]),{c(){X(t.$$.fragment),n=m(),r=p("div"),X(i.$$.fragment),o=m(),s=p("main"),f.c(),h=m(),C&&C.c(),g=m(),X(y.$$.fragment),A(s,"class","main-content svelte-u3u5mw"),A(r,"class","app-container svelte-u3u5mw"),x(r,"dark-theme",e[0])},m(e,a){ee(t,e,a),u(e,n,a),u(e,r,a),ee(i,r,null),c(r,o),c(r,s),k[l].m(s,null),u(e,h,a),C&&C.m(e,a),u(e,g,a),ee(y,e,a),w=!0},p(e,n){const o={};1&n[0]&&(o.isDarkTheme=e[0]),2&n[0]&&(o.isLoggedIn=e[1]),16&n[0]&&(o.userRole=e[4]),1024&n[0]&&(o.currentEffectiveRole=e[10]),8&n[0]&&(o.userProfile=e[3]),4&n[0]&&(o.userPubkey=e[2]),t.$set(o);const a={};1&n[0]&&(a.isDarkTheme=e[0]),2048&n[0]&&(a.tabs=e[11]),32&n[0]&&(a.selectedTab=e[5]),2&n[1]&&(a.version=e[32]),i.$set(a);let c=l;l=I(e,n),l===c?k[l].p(e,n):(z(),W(k[c],1,1,()=>{k[c]=null}),q(),f=k[l],f?f.p(e,n):(f=k[l]=b[l](e),f.c()),Y(f,1),f.m(s,null)),(!w||1&n[0])&&x(r,"dark-theme",e[0]),e[14]?C?C.p(e,n):(C=Nw(e),C.c(),C.m(g.parentNode,g)):C&&(C.d(1),C=null);const u={};1&n[0]&&(u.isDarkTheme=e[0]),!v&&4096&n[0]&&(v=!0,u.showModal=e[12],_(()=>v=!1)),y.$set(u)},i(e){w||(Y(t.$$.fragment,e),Y(i.$$.fragment,e),Y(f),Y(y.$$.fragment,e),w=!0)},o(e){W(t.$$.fragment,e),W(i.$$.fragment,e),W(f),W(y.$$.fragment,e),w=!1},d(e){te(t,e),e&&d(n),e&&d(r),te(i),k[l].d(),e&&d(h),C&&C.d(e),e&&d(g),te(y,e)}}}let zw=!1,qw=!1;function Yw(e,t,n){let r,i,o,s,a;"undefined"!=typeof window&&(window.debugIndexedDB=Dp);let l=!1,c=!1,u=!1,d="",f="",p=null,h="",g=null,m=!1,y=localStorage.getItem("selectedTab")||"export",v=!1,w={},A=[],k=[],I=null,C="",E=new Set,x=!1,B=!0,S=null,Q="",F=new Map,D=[],$=0,P=[],R=!0,T=null,N="",O=null,M=[],L=!1,_="",H="info",j=!1,G=null,J="",K=!1,V=!1,z="",q="info",Y=[],W=[],Z="",X="",ee="",te="",ne=null,re="",ie=[],oe=!1,se=!0,ae=null;function le(e){E.has(e)?E.delete(e):E.add(e),n(18,E)}async function ce(e,t){const n=JSON.stringify(e),r=await async function(e){try{return await navigator.clipboard.writeText(e),!0}catch(t){console.error("Failed to copy to clipboard:",t);try{const t=document.createElement("textarea");return t.value=e,document.body.appendChild(t),t.select(),document.execCommand("copy"),document.body.removeChild(t),!0}catch(e){return console.error("Fallback copy also failed:",e),!1}}}(n);!function(e,t=!0){if(!e)return;const n=e.textContent,r=e.style.backgroundColor;t?(e.textContent="",e.style.backgroundColor="#4CAF50"):(e.textContent="L",e.style.backgroundColor="#f44336"),setTimeout(()=>{e.textContent=n,e.style.backgroundColor=r},2e3)}(t.target.closest(".copy-json-btn"),r),r||alert("Failed to copy to clipboard. Please copy manually.")}async function ue(e){if(!u)return void alert("Please log in first");const t=k.find(t=>t.id===e);if(!t)return void alert("Event not found");if("admin"===h||"owner"===h||"write"===h&&t.pubkey&&t.pubkey===d){if(confirm("Are you sure you want to delete this event?"))try{if(!g)throw new Error("Signer not available for signing");const r={kind:5,created_at:Math.floor(Date.now()/1e3),tags:[["e",e]],content:""};console.log("Created delete event template:",r),console.log("User pubkey:",d),console.log("Target event:",t),console.log("Target event pubkey:",t.pubkey);const i=await g.signEvent(r);console.log("Signed delete event:",i),console.log("Signed delete event pubkey:",i.pubkey),console.log("Delete event tags:",i.tags);const o=`${window.location.protocol.startsWith("https")?"wss:":"ws:"}//${window.location.host}/`;try{const e=await Yv(o,i,g,d);e.success?console.log("Delete event published successfully to ORLY relay"):console.error("Failed to publish delete event:",e.reason)}catch(e){console.error("Error publishing delete event:",e)}const s=t.pubkey&&t.pubkey===d;if(s){const t=await gp.publish(i);if(console.log("Delete event published:",t),!(t.success&&t.okCount>0))throw new Error("No relays accepted the delete event");{await new Promise(e=>setTimeout(e,2e3));try{const n=await Bp(e,{timeout:5e3});n?(console.warn("Event still exists after deletion attempt:",n),alert(`Warning: Delete event was accepted by ${t.okCount} relay(s), but the event still exists on the relay. This may indicate the relay does not properly handle delete events.`)):console.log("Event successfully deleted and verified")}catch(e){console.log("Could not fetch event after deletion (likely deleted):",e.message)}try{const t=await Sp(e,{timeout:5e3});if(t.length>0){console.log(`Delete event verification: Found ${t.length} delete event(s) targeting ${e}`);const n=t.find(e=>e.pubkey&&e.pubkey===d);n?console.log("Our delete event found in database:",n.id):console.warn("Our delete event not found in database, but other delete events exist")}else console.warn("No delete events found in database for target event:",e)}catch(e){console.log("Could not verify delete event in database:",e.message)}n(96,k=k.filter(t=>t.id!==e)),P=P.filter(t=>t.id!==e),D=D.filter(t=>t.id!==e);for(const[t,n]of F)n.events&&(n.events=n.events.filter(t=>t.id!==e),F.set(t,n));he(),console.log("Reloading events to show delete event...");const r=zw&&u&&d?[d]:null;await Pe(!0,r),alert(`Event deleted successfully (accepted by ${t.okCount} relay(s))`)}}else{const t=`${window.location.protocol.startsWith("https")?"wss:":"ws:"}//${window.location.host}/`,r=new hp;await r.connectToRelay(t);const o=await r.publish(i);if(console.log("Delete event published to local relay only:",o),!(o.success&&o.okCount>0))throw new Error("Local relay did not accept the delete event");{await new Promise(e=>setTimeout(e,2e3));try{const t=await Bp(e,{timeout:5e3});t?(console.warn("Event still exists after deletion attempt:",t),alert(`Warning: Delete event was accepted by ${o.okCount} relay(s), but the event still exists on the relay. This may indicate the relay does not properly handle delete events.`)):console.log("Event successfully deleted and verified")}catch(e){console.log("Could not fetch event after deletion (likely deleted):",e.message)}try{const t=await Sp(e,{timeout:5e3});if(t.length>0){console.log(`Delete event verification: Found ${t.length} delete event(s) targeting ${e}`);const n=t.find(e=>e.pubkey&&e.pubkey===d);n?console.log("Our delete event found in database:",n.id):console.warn("Our delete event not found in database, but other delete events exist")}else console.warn("No delete events found in database for target event:",e)}catch(e){console.log("Could not verify delete event in database:",e.message)}n(96,k=k.filter(t=>t.id!==e)),P=P.filter(t=>t.id!==e),D=D.filter(t=>t.id!==e);for(const[t,n]of F)n.events&&(n.events=n.events.filter(t=>t.id!==e),F.set(t,n));he(),console.log("Reloading events to show delete event...");const t=zw&&u&&d?[d]:null;await Pe(!0,t),alert("Event deleted successfully (local relay only - admin/owner deleting other user's event)")}}}catch(e){console.error("Failed to delete event:",e),alert("Failed to delete event: "+e.message)}}else alert("You do not have permission to delete this event")}async function de(){const e=re?parseInt(re):ne;if(null==e||isNaN(e))console.log("No valid kind to load, kindToUse:",e);else if(u){console.log("Loading recovery events for kind:",e,"user:",d),n(38,oe=!0);try{const t=[{kinds:[e],authors:[d],limit:100}];ae&&(t[0].until=ae),console.log("Recovery filters:",t);const r=await Fp(t,{timeout:3e4,cacheFirst:!0});console.log("Recovery events received:",r.length),console.log("Recovery events kinds:",r.map(e=>e.kind)),n(37,ie=ae?[...ie,...r]:r),r.length>0?(ae=Math.min(...r.map(e=>e.created_at)),n(39,se=100===r.length)):n(39,se=!1)}catch(e){console.error("Failed to load recovery events:",e)}finally{n(38,oe=!1)}}else console.log("Not logged in, cannot load recovery events")}async function fe(e){if(confirm("Are you sure you want to repost this event?"))try{const t=`${window.location.protocol.startsWith("https")?"wss:":"ws:"}//${window.location.host}/`;console.log("Reposting event to local relay:",t,e);const r={...e};if(r.created_at=Math.floor(Date.now()/1e3),r.id="",r.sig="",e.kind>=3e4&&e.kind<=39999){const t=e.tags.find(e=>"d"===e[0]);t&&(r.tags=r.tags.filter(e=>"d"!==e[0]),r.tags.push(t))}if(g){const e=await g.signEvent(r);console.log("Signed event for repost:",e);const i=await gp.publish(e,[t]);console.log("Repost publish result:",i),i.success&&i.okCount>0?(alert("Event reposted successfully!"),n(39,se=!1),await de()):alert("Failed to repost event. Check console for details.")}else alert("No signer available. Please log in.")}catch(e){console.error("Error reposting event:",e),alert("Error reposting event: "+e.message)}}async function pe(e){if(confirm("Are you sure you want to repost this event to all your write relays?"))try{const t=await async function(){if(!d)return[];try{const e=await kp([{kinds:[10002],authors:[d],limit:1}]);if(0===e.length)return console.log("No relay list event found for user"),[];const t=e[0];console.log("Found relay list event:",t);const n=[];for(const e of t.tags)if("r"===e[0]&&e.length>=2){const t=e[1],r=e.length>=3?e[2]:null;r&&"write"!==r||n.push(t)}return console.log("Found write relays:",n),n}catch(e){return console.error("Error fetching user write relays:",e),[]}}(),r=`${window.location.protocol.startsWith("https")?"wss:":"ws:"}//${window.location.host}/`,i=[r,...t.filter(e=>e!==r)];1===i.length&&alert("No write relays found in your relay list. Only posting to local relay."),console.log("Reposting event to all relays:",i,e);const o={...e};if(o.created_at=Math.floor(Date.now()/1e3),o.id="",o.sig="",e.kind>=3e4&&e.kind<=39999){const t=e.tags.find(e=>"d"===e[0]);t&&(o.tags=o.tags.filter(e=>"d"!==e[0]),o.tags.push(t))}if(g){const e=await g.signEvent(o);console.log("Signed event for repost to all:",e);const t=await gp.publish(e,i);console.log("Repost to all publish result:",t),t.success&&t.okCount>0?(alert(`Event reposted successfully to ${i.length} relays!`),n(39,se=!1),await de()):alert("Failed to repost event. Check console for details.")}else alert("No signer available. Please log in.")}catch(e){console.error("Error reposting event to all:",e),alert("Error reposting event to all: "+e.message)}}if("undefined"!=typeof window&&window.matchMedia){const e=window.matchMedia("(prefers-color-scheme: dark)");l=e.matches,e.addEventListener("change",e=>{n(0,l=e.matches)})}if("undefined"!=typeof localStorage){const e=localStorage.getItem("nostr_auth_method"),t=localStorage.getItem("nostr_pubkey");e&&t&&(u=!0,d=t,f=e,"extension"===e&&window.nostr&&(g=window.nostr),De(),$e()),function(){if("undefined"==typeof localStorage)return;try{const t=localStorage.getItem("app_state");if(t){const r=JSON.parse(t);r.selectedTab&&Ie.some(e=>e.id===r.selectedTab)&&n(5,y=r.selectedTab),r.expandedEvents&&n(18,E=new Set(r.expandedEvents)),r.globalEventsCache&&(D=r.globalEventsCache),r.globalCacheTimestamp&&($=r.globalCacheTimestamp),void 0!==r.hasMoreEvents&&(B=r.hasMoreEvents),r.oldestEventTimestamp&&(S=r.oldestEventTimestamp),void 0!==r.hasMoreMyEvents&&(R=r.hasMoreMyEvents),r.oldestMyEventTimestamp&&(T=r.oldestMyEventTimestamp),D.length>0&&((e=$)&&Date.now()-et.created_at-e.created_at),$=Date.now(),he()}async function me(){if(u&&"owner"===h&&j)try{n(22,L=!0);const e=await fetch("/api/sprocket/status",{method:"GET",headers:{Authorization:`Nostr ${await Oe("GET","/api/sprocket/status")}`,"Content-Type":"application/json"}});e.ok?n(20,O=await e.json()):Ae("Failed to load sprocket status","error")}catch(e){Ae(`Error loading sprocket status: ${e.message}`,"error")}finally{n(22,L=!1)}}async function ye(){if(u&&"owner"===h)try{n(22,L=!0);const e=await fetch("/api/sprocket/versions",{method:"GET",headers:{Authorization:`Nostr ${await Oe("GET","/api/sprocket/versions")}`,"Content-Type":"application/json"}});e.ok?n(21,M=await e.json()):Ae("Failed to load versions","error")}catch(e){Ae(`Error loading versions: ${e.message}`,"error")}finally{n(22,L=!1)}}async function ve(e){u&&"owner"===h&&(n(19,N=e.content),Ae(`Loaded version: ${e.name}`,"success"))}async function we(e){if(u&&"owner"===h&&confirm(`Are you sure you want to delete version ${e}?`))try{n(22,L=!0);const t=await fetch("/api/sprocket/delete-version",{method:"POST",headers:{Authorization:`Nostr ${await Oe("POST","/api/sprocket/delete-version")}`,"Content-Type":"application/json"},body:JSON.stringify({filename:e})});if(t.ok)Ae(`Version ${e} deleted successfully`,"success"),await ye();else{Ae(`Failed to delete version: ${await t.text()}`,"error")}}catch(e){Ae(`Error deleting version: ${e.message}`,"error")}finally{n(22,L=!1)}}function Ae(e,t="info"){n(23,_=e),n(24,H=t),setTimeout(()=>{n(23,_="")},5e3)}function be(e,t="info"){n(28,z=e),n(29,q=t),"error"!==t&&setTimeout(()=>{n(28,z="")},5e3)}async function ke(){if(n(30,Y=[]),!J.trim())return n(30,Y=["Policy JSON is empty"]),be("Validation failed","error"),!1;try{const e=JSON.parse(J);if("object"!=typeof e||null===e)return n(30,Y=["Policy must be a JSON object"]),be("Validation failed","error"),!1;if(e.policy_admins)if(Array.isArray(e.policy_admins))for(const t of e.policy_admins)"string"==typeof t&&/^[0-9a-fA-F]{64}$/.test(t)||Y.push(`Invalid policy_admin pubkey: ${t}`);else Y.push("policy_admins must be an array");if(e.rules)if("object"!=typeof e.rules)Y.push("rules must be an object");else for(const[t,n]of Object.entries(e.rules))if(/^\d+$/.test(t)||Y.push(`Invalid kind number: ${t}`),n.tag_validation&&"object"==typeof n.tag_validation)for(const[e,t]of Object.entries(n.tag_validation))try{new RegExp(t)}catch(n){Y.push(`Invalid regex for tag '${e}': ${t}`)}return e.default_policy&&!["allow","deny"].includes(e.default_policy)&&Y.push("default_policy must be 'allow' or 'deny'"),Y.length>0?(be("Validation failed - see errors below","error"),!1):(be("Validation passed","success"),!0)}catch(e){return n(30,Y=[`JSON parse error: ${e.message}`]),be("Invalid JSON syntax","error"),!1}}const Ie=[{id:"export",icon:"📤",label:"Export"},{id:"import",icon:"💾",label:"Import",requiresAdmin:!0},{id:"events",icon:"📡",label:"Events"},{id:"blossom",icon:"🌸",label:"Blossom"},{id:"compose",icon:"✏️",label:"Compose",requiresWrite:!0},{id:"recovery",icon:"🔄",label:"Recovery"},{id:"managed-acl",icon:"🛡️",label:"Managed ACL",requiresOwner:!0},{id:"sprocket",icon:"⚙️",label:"Sprocket",requiresOwner:!0},{id:"policy",icon:"📜",label:"Policy",requiresOwner:!0}];function Ce(e){n(5,y=e),"sprocket"===e&&u&&"owner"===h&&j&&(me(),ye()),he()}function Ee(){n(14,m=!1)}function xe(e){Be(e)}function Be(e){n(6,A=A.filter(t=>t.id!==e)),F.delete(e),y===e&&n(5,y="export")}async function Se(e,t=!0){const n=F.get(e);if(n&&!n.isLoading){n.isLoading=!0,F.set(e,n);try{const r={...n.filter};!t&&n.oldestTimestamp&&(r.until=n.oldestTimestamp),t||(r.limit=200),console.log("Loading search results with filter:",r);const i=await xp([r],{timeout:3e4});if(console.log("Received search results:",i.length,"events"),n.events=t?i.sort((e,t)=>t.created_at-e.created_at):[...n.events,...i].sort((e,t)=>t.created_at-e.created_at),i.length>0){const e=Math.min(...i.map(e=>e.created_at));(!n.oldestTimestamp||e0){const e=o.filter(e=>e.pubkey&&e.pubkey!==d);e.length>0&&console.warn("Server returned non-user events:",e.length,"out of",o.length)}if(e?(n(96,k=o.sort((e,t)=>t.created_at-e.created_at)),ge(o)):(n(96,k=[...k,...o].sort((e,t)=>t.created_at-e.created_at)),ge(k)),o.length>0){const e=Math.min(...o.map(e=>e.created_at));(!S||e{if("events"===y){const e=document.querySelectorAll(".events-view-content")[0];e&&e.scrollHeight<=e.clientHeight&&Re()}},100)}catch(e){console.error("Failed to load events:",e),alert("Failed to load events: "+e.message)}finally{n(7,x=!1)}}}async function Re(){await Pe(!1)}let Te=!1;async function Ne(e,t){if(!u||!d)throw new Error("Not logged in");const n={kind:27235,created_at:Math.floor(Date.now()/1e3),tags:[["u",window.location.origin+e],["method",t.toUpperCase()]],content:"",pubkey:d};let r;if(g&&"extension"===f)try{r=await g.signEvent(n)}catch(e){throw new Error("Failed to sign with extension: "+e.message)}else{if("nsec"!==f)throw new Error("No valid signer available");n.id="mock-id-"+Date.now(),n.sig="mock-signature-"+Date.now(),r=n}const i=JSON.stringify(r);return`Nostr ${btoa(i)}`}async function Oe(e,t){if(!u||!d)throw new Error("Not logged in");const n={kind:27235,created_at:Math.floor(Date.now()/1e3),tags:[["u",window.location.origin+t],["method",e.toUpperCase()]],content:"",pubkey:d};let r;if(g&&"extension"===f)try{r=await g.signEvent(n)}catch(e){throw new Error("Failed to sign with extension: "+e.message)}else{if("nsec"!==f)throw new Error("No valid signer available");n.id="mock-id-"+Date.now(),n.sig="mock-signature-"+Date.now(),r=n}const i=JSON.stringify(r);return btoa(i)}function Me(e,t){const n=e.toLowerCase();if(n.includes("policy")||n.includes("blocked")||n.includes("denied")){let n=`Policy Error: ${e}`;return null!==t&&(n+=`\n\nKind ${t} may be restricted by the relay's policy configuration.`),K&&(n+="\n\nThe relay has policy enforcement enabled. Contact a relay administrator to allow this event kind or adjust your permissions."),n}if(n.includes("auth")||n.includes("permission")||n.includes("unauthorized"))return`Permission Error: ${e}\n\nYour current permissions may not allow publishing this type of event. Current role: ${h||"unknown"}. Contact a relay administrator to upgrade your permissions.`;if(n.includes("kind")||n.includes("not allowed")||n.includes("restricted")){let n=`Event Type Error: ${e}`;return null!==t&&(n+=`\n\nKind ${t} is not currently allowed on this relay.`),n+="\n\nThe relay administrator may need to update the policy configuration to allow this event kind.",n}return n.includes("rate")||n.includes("limit")||n.includes("too many")?`Rate Limit Error: ${e}\n\nPlease wait a moment before trying again.`:n.includes("size")||n.includes("too large")||n.includes("content")?`Size Limit Error: ${e}\n\nThe event may exceed the relay's size limits. Try reducing the content length.`:`Publishing failed: ${e}`}function Le(e){n(97,Q=e),localStorage.setItem("viewAsRole",e),console.log("View as role changed to:",e,"Current effective role:",a)}Q=localStorage.getItem("viewAsRole")||"";return e.$$.update=()=>{var t;if(6&e.$$.dirty[0]|8&e.$$.dirty[3]&&n(41,r=k.sort((e,t)=>t.created_at-e.created_at)),8&e.$$.dirty[0]&&n(40,i=p?.about?(t=p.about,t?t.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'"):"").replace(/\n{2,}/g," "):""),16&e.$$.dirty[0]|16&e.$$.dirty[3]&&n(10,a=Q&&""!==Q?Q:h),1810&e.$$.dirty[0]|48&e.$$.dirty[3]&&n(100,o=Ie.filter(e=>{const t=a;return!(e.requiresAdmin&&(!u||"admin"!==t&&"owner"!==t))&&(!(e.requiresOwner&&(!u||"owner"!==t))&&(!(e.requiresWrite&&(!u||"read"===t))&&(!("sprocket"===e.id&&!j)&&(!("policy"===e.id&&!K)&&(("managed-acl"!==e.id||"managed"===Z)&&(console.log(`Tab ${e.id} filter check:`,{isLoggedIn:u,userRole:h,viewAsRole:Q,currentRole:t,requiresAdmin:e.requiresAdmin,requiresOwner:e.requiresOwner,requiresWrite:e.requiresWrite,visible:!0}),!0))))))})),64&e.$$.dirty[0]|128&e.$$.dirty[3]&&n(11,s=[...o,...A]),2578&e.$$.dirty[0]|128&e.$$.dirty[3]&&console.log("Tabs debug:",{isLoggedIn:u,userRole:h,aclMode:Z,filteredBaseTabs:o.map(e=>e.id),allTabs:s.map(e=>e.id)}),1&e.$$.dirty[0]&&"undefined"!=typeof document&&(l?document.body.classList.add("dark-theme"):document.body.classList.remove("dark-theme")),14&e.$$.dirty[0]&&u&&d&&!p&&Fe(),182&e.$$.dirty[0]|72&e.$$.dirty[3]&&"events"===y&&u&&("read"===h||"write"===h||"admin"===h||"owner"===h)&&0===k.length&&!Te&&!x){n(99,Te=!0);Pe(!0,null)}32&e.$$.dirty[0]|8&e.$$.dirty[3]&&("events"!==y||"events"===y&&k.length>0)&&n(99,Te=!1),32&e.$$.dirty[0]&&localStorage.setItem("selectedTab",y)},[l,u,d,p,h,y,A,x,K,Z,a,s,c,g,m,v,I,C,E,N,O,M,L,_,H,G,J,V,z,q,Y,W,X,ee,te,ne,re,ie,oe,se,i,r,F,le,ce,async function(){console.log("Toggle changed, showOnlyMyEvents:",zw),n(99,Te=!1),await Pe(!0,null)},ue,de,fe,pe,function(){console.log("selectRecoveryKind called, recoverySelectedKind:",ne),null!=ne?(n(36,re=""),n(37,ie=[]),ae=null,n(39,se=!0),de()):console.log("No kind selected, skipping load")},function(){console.log("handleCustomKindInput called, recoveryCustomKind:",re);const e=parseInt(re);""!==re&&!isNaN(e)&&e>=0&&(n(35,ne=null),n(37,ie=[]),ae=null,n(39,se=!0),de())},function(e){const t=ie.filter(t=>t.kind===e.kind&&t.pubkey===e.pubkey),n=Math.max(...t.map(e=>e.created_at));return e.created_at===n},async function(){if(u&&"owner"===h)try{n(22,L=!0);const e=await fetch("/api/sprocket/status",{method:"GET",headers:{Authorization:`Nostr ${await Oe("GET","/api/sprocket/status")}`,"Content-Type":"application/json"}});if(e.ok){const t=await e.json();n(19,N=t.script_content||""),n(20,O=t),Ae("Script loaded successfully","success")}else Ae("Failed to load script","error")}catch(e){Ae(`Error loading script: ${e.message}`,"error")}finally{n(22,L=!1)}},async function(){if(u&&"owner"===h)try{n(22,L=!0);const e=await fetch("/api/sprocket/update",{method:"POST",headers:{Authorization:`Nostr ${await Oe("POST","/api/sprocket/update")}`,"Content-Type":"text/plain"},body:N});if(e.ok)Ae("Script saved and updated successfully","success"),await me(),await ye();else{Ae(`Failed to save script: ${await e.text()}`,"error")}}catch(e){Ae(`Error saving script: ${e.message}`,"error")}finally{n(22,L=!1)}},async function(){if(u&&"owner"===h)try{n(22,L=!0);const e=await fetch("/api/sprocket/restart",{method:"POST",headers:{Authorization:`Nostr ${await Oe("POST","/api/sprocket/restart")}`,"Content-Type":"application/json"}});if(e.ok)Ae("Sprocket restarted successfully","success"),await me();else{Ae(`Failed to restart sprocket: ${await e.text()}`,"error")}}catch(e){Ae(`Error restarting sprocket: ${e.message}`,"error")}finally{n(22,L=!1)}},async function(){if(u&&"owner"===h&&confirm("Are you sure you want to delete the sprocket script? This will stop the current process."))try{n(22,L=!0);const e=await fetch("/api/sprocket/update",{method:"POST",headers:{Authorization:`Nostr ${await Oe("POST","/api/sprocket/update")}`,"Content-Type":"text/plain"},body:""});if(e.ok)n(19,N=""),Ae("Sprocket script deleted successfully","success"),await me(),await ye();else{Ae(`Failed to delete script: ${await e.text()}`,"error")}}catch(e){Ae(`Error deleting script: ${e.message}`,"error")}finally{n(22,L=!1)}},ye,ve,we,async function(){if(u&&("owner"===h||qw))try{n(27,V=!0),n(30,Y=[]);const e={kinds:[12345],limit:1},t=await Fp(e);if(t&&t.length>0){n(26,J=t[0].content);try{n(26,J=JSON.stringify(JSON.parse(J),null,2))}catch(e){}be("Policy loaded successfully","success")}else{const e=await fetch("/api/policy",{method:"GET",headers:{Authorization:`Nostr ${await Oe("GET","/api/policy")}`,"Content-Type":"application/json"}});if(e.ok){const t=await e.json();n(26,J=JSON.stringify(t,null,2)),be("Policy loaded from file","success")}else be("No policy configuration found","info"),n(26,J="")}}catch(e){be(`Error loading policy: ${e.message}`,"error")}finally{n(27,V=!1)}},ke,async function(){if(!u||"owner"!==h&&!qw)return;if(await ke())try{n(27,V=!0);const e={kind:12345,created_at:Math.floor(Date.now()/1e3),tags:[],content:J},t=await Yv(e,g);t.success?be("Policy updated successfully","success"):be(`Failed to publish policy: ${t.error||"Unknown error"}`,"error")}catch(e){be(`Error saving policy: ${e.message}`,"error")}finally{n(27,V=!1)}},function(){try{const e=JSON.parse(J);n(26,J=JSON.stringify(e,null,2)),be("JSON formatted","success")}catch(e){be(`Cannot format: ${e.message}`,"error")}},function(e){const t=e.detail;if(!t)return void be("Please enter a pubkey","error");const r=function(e){if(!e)return null;if(/^[0-9a-fA-F]{64}$/.test(e))return e.toLowerCase();if(e.startsWith("npub1"))try{const t="qpzry9x8gf2tvdw0s3jn54khce6mua7l",n=e.slice(5);let r=[];for(const e of n){const n=t.indexOf(e.toLowerCase());if(-1===n)throw new Error("Invalid character in npub");r.push(...[...Array(5)].map((e,t)=>n>>4-t&1))}r=r.slice(0,-30);const i=[];for(let e=0;e+8<=r.length;e+=8){let t=0;for(let n=0;n<8;n++)t=t<<1|r[e+n];i.push(t)}return i.map(e=>e.toString(16).padStart(2,"0")).join("")}catch(e){return console.error("Failed to decode npub:",e),null}return null}(t);if(r&&64===r.length)try{const e=JSON.parse(J||"{}");if(e.policy_admins||(e.policy_admins=[]),e.policy_admins.includes(r))return void be("Admin already in list","warning");e.policy_admins.push(r),n(26,J=JSON.stringify(e,null,2)),be("Admin added - click 'Save & Publish' to apply","info")}catch(e){be(`Error adding admin: ${e.message}`,"error")}else be("Invalid pubkey format. Use hex (64 chars) or npub","error")},function(e){const t=e.detail;try{const e=JSON.parse(J||"{}");e.policy_admins&&(e.policy_admins=e.policy_admins.filter(e=>e!==t),n(26,J=JSON.stringify(e,null,2)),be("Admin removed - click 'Save & Publish' to apply","info"))}catch(e){be(`Error removing admin: ${e.message}`,"error")}},async function(){if(u&&("owner"===h||qw))try{n(27,V=!0),n(31,W=[]);let e=[];try{e=JSON.parse(J||"{}").policy_admins||[]}catch(e){return void be("Cannot parse policy JSON to get admins","error")}if(0===e.length)return void be("No policy admins configured","warning");const t={kinds:[3],authors:e,limit:e.length},r=await Fp(t),i=new Set;for(const e of r)if(e.tags)for(const t of e.tags)"p"===t[0]&&t[1]&&64===t[1].length&&i.add(t[1]);n(31,W=Array.from(i)),be(`Loaded ${W.length} follows from ${r.length} admin(s)`,"success")}catch(e){be(`Error loading follows: ${e.message}`,"error")}finally{n(27,V=!1)}},function(e){n(25,G=e.target.files[0])},async function(){if(u&&"owner"===h&&G)try{n(22,L=!0);const e=await G.text(),t=await fetch("/api/sprocket/update",{method:"POST",headers:{Authorization:`Nostr ${await Oe("POST","/api/sprocket/update")}`,"Content-Type":"text/plain"},body:e});if(t.ok)n(19,N=e),Ae("Script uploaded and updated successfully","success"),await me(),await ye();else{Ae(`Failed to upload script: ${await t.text()}`,"error")}}catch(e){Ae(`Error uploading script: ${e.message}`,"error")}finally{n(22,L=!1),n(25,G=null);const e=document.getElementById("sprocket-upload-file");e&&(e.value="")}},Ce,function(){u||n(12,c=!0)},async function(e){const{method:t,pubkey:r,privateKey:i,signer:o}=e.detail;n(1,u=!0),n(2,d=r),f=t,n(13,g=o),n(12,c=!1);try{if(await Qp(),"extension"===t&&o)gp.setSigner(o);else if("nsec"===t&&i){const e=new kf(i);gp.setSigner(e)}n(3,p=await Cp(r)),console.log("Profile loaded:",p)}catch(e){console.error("Failed to load profile:",e)}await De(),await $e()},function(){n(1,u=!1),n(2,d=""),f="",n(3,p=null),n(4,h=""),n(13,g=null),n(14,m=!1),P=[],n(96,k=[]),D=[],$=0,he(),"undefined"!=typeof localStorage&&(localStorage.removeItem("nostr_auth_method"),localStorage.removeItem("nostr_pubkey"),localStorage.removeItem("nostr_privkey"))},function(){n(12,c=!1)},function(){n(14,m=!0)},Ee,function(){n(15,v=!v)},function(e){const{searchText:t,selectedKinds:n,pubkeys:r,eventIds:i,tags:o,sinceTimestamp:s,untilTimestamp:a,limit:l}=e.detail,c=function({searchText:e=null,kinds:t=[],authors:n=[],ids:r=[],tags:i=[],since:o=null,until:s=null,limit:a=null}){const l={};return e&&e.trim()&&(l.search=e.trim()),t&&t.length>0&&(l.kinds=t),n&&n.length>0&&(l.authors=n),r&&r.length>0&&(l.ids=r),i&&i.length>0&&i.forEach(e=>{if(e.name&&e.value){const t=`#${e.name}`;l[t]||(l[t]=[]),l[t].push(e.value)}}),o&&(l.since=o),s&&(l.until=s),a&&a>0&&(l.limit=a),l}({searchText:t,kinds:n,authors:r,ids:i,tags:o,since:s,until:a,limit:l||100});w=c,Pe(!0,null)},function(){w={},Pe(!0,null)},xe,Be,Se,Qe,Fe,async function(){await Ue([])},async function(){await Ue([d])},function(e){n(16,I=e.detail.target.files[0])},async function(){if("none"!==Z&&(!u||"admin"!==h&&"owner"!==h))return n(17,C="Admin or owner permission required"),void setTimeout(()=>{n(17,C="")},5e3);if(!I)return n(17,C="Please select a file"),void setTimeout(()=>{n(17,C="")},5e3);try{n(17,C="Uploading...");const e={};"none"!==Z&&u&&(e.Authorization=await Ne("/api/import","POST"));const t=new FormData;t.append("file",I);const r=await fetch("/api/import",{method:"POST",headers:e,body:t});if(!r.ok)throw new Error(`Import failed: ${r.status} ${r.statusText}`);await r.json();n(17,C="Upload complete"),n(16,I=null),document.getElementById("import-file").value="",setTimeout(()=>{n(17,C="")},5e3)}catch(e){console.error("Import failed:",e),n(17,C="Import failed: "+e.message),setTimeout(()=>{n(17,C="")},5e3)}},Pe,function(e){const{scrollTop:t,scrollHeight:n,clientHeight:r}=e.target;n-t-r<100&&Re()},function(){try{if(!ee.trim())return void alert("Please enter some JSON to reformat");const e=JSON.parse(ee);n(33,ee=JSON.stringify(e,null,2))}catch(e){alert("Invalid JSON: "+e.message)}},async function(){try{if(!ee.trim())return void alert("Please enter an event to sign");if(!u||!d)return void alert("Please log in to sign events");if(!g)return void alert("No signer available. Please log in with a valid authentication method.");const e=JSON.parse(ee);e.pubkey=d,e.created_at=Math.floor(Date.now()/1e3),delete e.id,delete e.sig;const t=await g.signEvent(e);n(33,ee=JSON.stringify(t,null,2)),alert("Event signed successfully!")}catch(e){console.error("Error signing event:",e),alert("Error signing event: "+e.message)}},async function(){n(34,te="");try{if(!ee.trim())return void n(34,te="Please enter an event to publish");if(!u)return void n(34,te="Please log in to publish events");if(!g)return void n(34,te="No signer available. Please log in with a valid authentication method.");let e;try{e=JSON.parse(ee)}catch(e){return void n(34,te=`Invalid JSON: ${e.message}`)}if(!e.id||!e.sig)return void n(34,te='Event must be signed before publishing. Please click "Sign" first.');if("read"===h)return void n(34,te=`Permission denied: Your current role is "${h}" which does not allow publishing events. Contact a relay administrator to upgrade your permissions.`);const t=`${window.location.protocol.startsWith("https")?"wss:":"ws:"}//${window.location.host}/`,r=await Yv(t,e,g,d);if(r.success)n(34,te=""),alert("Event published successfully to ORLY relay!");else{const t=r.reason||"Unknown error";n(34,te=Me(t,e.kind))}}catch(e){console.error("Error publishing event:",e);const t=e.message||"Unknown error";n(34,te=Me(t,null))}},function(){n(34,te="")},Le,function(){const e=["owner","admin","write","read"],t=e.indexOf(h);return-1===t?["read"]:e.slice(t)},k,Q,j,Te,o,function(t){U.call(this,e,t)},function(t){U.call(this,e,t)},e=>e.id===y,e=>Ce(e.detail),e=>Be(e.detail),e=>le(e.detail),e=>ue(e.detail),e=>ce(e.detail.event,e.detail.e),e=>Pe(e.detail.refresh,e.detail.authors),function(e){ee=e,n(33,ee)},function(e){N=e,n(19,N)},e=>ve(e.detail),e=>we(e.detail),function(e){J=e,n(26,J)},function(){ne=function(e){const t=e.querySelector(":checked");return t&&t.__value}(this),n(35,ne)},function(){re=b(this.value),n(36,re)},e=>pe(e),e=>fe(e),(e,t)=>ce(e,t),e=>Se(e.id,!0),e=>xe(e.id),e=>ue(e.id),e=>le(e.id),(e,t)=>"Enter"===t.key&&le(e.id),(e,t)=>ce(e,t),(e,t)=>Qe(t,e.id),e=>Le(e===h?"":e),e=>"Escape"===e.key&&Ee(),function(e){c=e,n(12,c)}]}return new class extends ie{constructor(e){super(),re(this,e,Yw,Vw,o,{},null,[-1,-1,-1,-1,-1,-1])}}({target:document.body,props:{name:"world"}})}();
+ */function $p(e,t,n,r){return new(n||(n=Promise))(function(i,o){function s(e){try{l(r.next(e))}catch(e){o(e)}}function a(e){try{l(r.throw(e))}catch(e){o(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n(function(e){e(t)})).then(s,a)}l((r=r.apply(e,t||[])).next())})}"function"==typeof SuppressedError&&SuppressedError;class Up{constructor(){this.mutex=Promise.resolve()}lock(){let e=()=>{};return this.mutex=this.mutex.then(()=>new Promise(e)),new Promise(t=>{e=t})}dispatch(e){return $p(this,void 0,void 0,function*(){const t=yield this.lock();try{return yield Promise.resolve(e())}finally{t()}})}}var Pp;const Rp="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:global,Tp=null!==(Pp=Rp.Buffer)&&void 0!==Pp?Pp:null,Np=Rp.TextEncoder?new Rp.TextEncoder:null;function Op(e,t){return(15&e)+(e>>6|e>>3&8)<<4|(15&t)+(t>>6|t>>3&8)}function Mp(e,t){const n=t.length>>1;for(let r=0;r>>4;e[r++]=n>9?n+Lp:n+_p,n=15&t[i],e[r++]=n>9?n+Lp:n+_p}return String.fromCharCode.apply(null,e)}const jp=null!==Tp?e=>{if("string"==typeof e){const t=Tp.from(e,"utf8");return new Uint8Array(t.buffer,t.byteOffset,t.length)}if(Tp.isBuffer(e))return new Uint8Array(e.buffer,e.byteOffset,e.length);if(ArrayBuffer.isView(e))return new Uint8Array(e.buffer,e.byteOffset,e.byteLength);throw new Error("Invalid data type!")}:e=>{if("string"==typeof e)return Np.encode(e);if(ArrayBuffer.isView(e))return new Uint8Array(e.buffer,e.byteOffset,e.byteLength);throw new Error("Invalid data type!")},Gp="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",Jp=new Uint8Array(256);for(let e=0;e<64;e++)Jp[Gp.charCodeAt(e)]=e;function Kp(e,t=!0){const n=e.length,r=n%3,i=[],o=n-r;for(let t=0;t>18&63)+Gp.charAt(n>>12&63)+Gp.charAt(n>>6&63)+Gp.charAt(63&n);i.push(r)}if(1===r){const r=e[n-1],o=Gp.charAt(r>>2),s=Gp.charAt(r<<4&63);i.push(`${o}${s}`),t&&i.push("==")}else if(2===r){const r=(e[n-2]<<8)+e[n-1],o=Gp.charAt(r>>10),s=Gp.charAt(r>>4&63),a=Gp.charAt(r<<2&63);i.push(`${o}${s}${a}`),t&&i.push("=")}return i.join("")}function Vp(e){const t=function(e){let t=Math.floor(.75*e.length);const n=e.length;return"="===e[n-1]&&(t-=1,"="===e[n-2]&&(t-=1)),t}(e),n=e.length,r=new Uint8Array(t);let i=0;for(let t=0;t>4,i+=1,r[i]=(15&o)<<4|s>>2,i+=1,r[i]=(3&s)<<6|63&a,i+=1}return r}const zp=16384,qp=new Up,Yp=new Map;function Wp(e,t){return $p(this,void 0,void 0,function*(){let n=null,r=null,i=!1;if("undefined"==typeof WebAssembly)throw new Error("WebAssembly is not supported in this environment!");const o=()=>new DataView(n.exports.memory.buffer).getUint32(n.exports.STATE_SIZE,!0),s=qp.dispatch(()=>$p(this,void 0,void 0,function*(){if(!Yp.has(e.name)){const t=Vp(e.data),n=WebAssembly.compile(t);Yp.set(e.name,n)}const t=yield Yp.get(e.name);n=yield WebAssembly.instantiate(t,{})})),a=(e=null)=>{i=!0,n.exports.Hash_Init(e)},l=e=>{if(!i)throw new Error("update() called before init()");(e=>{let t=0;for(;t{if(!i)throw new Error("digest() called before init()");return i=!1,n.exports.Hash_Final(o),"binary"===e?r.slice(0,t):Hp(c,r,t)},d=e=>"string"==typeof e?e.length<4096:e.byteLength!0;break;case"blake2b":case"blake2s":f=(e,t)=>t<=512&&d(e);break;case"blake3":f=(e,t)=>0===t&&d(e);break;case"xxhash64":case"xxhash3":case"xxhash128":case"crc64":f=()=>!1}return yield(()=>$p(this,void 0,void 0,function*(){n||(yield s);const e=n.exports.Hash_GetBuffer(),t=n.exports.memory.buffer;r=new Uint8Array(t,e,zp)}))(),{getMemory:()=>r,writeMemory:(e,t=0)=>{r.set(e,t)},getExports:()=>n.exports,setMemorySize:e=>{n.exports.Hash_SetMemorySize(e);const t=n.exports.Hash_GetBuffer(),i=n.exports.memory.buffer;r=new Uint8Array(i,t,e)},init:a,update:l,digest:u,save:()=>{if(!i)throw new Error("save() can only be called after init() and before digest()");const t=n.exports.Hash_GetState(),r=o(),s=n.exports.memory.buffer,a=new Uint8Array(s,t,r),l=new Uint8Array(4+r);return Mp(l,e.hash),l.set(a,4),l},load:t=>{if(!(t instanceof Uint8Array))throw new Error("load() expects an Uint8Array generated by save()");const r=n.exports.Hash_GetState(),s=o(),a=4+s,l=n.exports.memory.buffer;if(t.length!==a)throw new Error(`Bad state length (expected ${a} bytes, got ${t.length})`);if(!function(e,t){if(e.length!==2*t.length)return!1;for(let n=0;n{if(!f(e,i))return a(i),l(e),u("hex",o);const s=jp(e);return r.set(s),n.exports.Hash_Calculate(s.length,i,o),Hp(c,r,t)},hashLength:t}})}new Up;var Zp={name:"argon2",data:"AGFzbQEAAAABKQVgAX8Bf2AAAX9gEH9/f39/f39/f39/f39/f38AYAR/f39/AGACf38AAwYFAAECAwQFBgEBAoCAAgYIAX8BQZCoBAsHQQQGbWVtb3J5AgASSGFzaF9TZXRNZW1vcnlTaXplAAAOSGFzaF9HZXRCdWZmZXIAAQ5IYXNoX0NhbGN1bGF0ZQAECvEyBVgBAn9BACEBAkAgAEEAKAKICCICRg0AAkAgACACayIAQRB2IABBgIB8cSAASWoiAEAAQX9HDQBB/wHADwtBACEBQQBBACkDiAggAEEQdK18NwOICAsgAcALcAECfwJAQQAoAoAIIgANAEEAPwBBEHQiADYCgAhBACgCiAgiAUGAgCBGDQACQEGAgCAgAWsiAEEQdiAAQYCAfHEgAElqIgBAAEF/Rw0AQQAPC0EAQQApA4gIIABBEHStfDcDiAhBACgCgAghAAsgAAvcDgECfiAAIAQpAwAiECAAKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAMIBAgDCkDAIVCIIkiEDcDACAIIBAgCCkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgBCAQIAQpAwCFQiiJIhA3AwAgACAQIAApAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIAwgECAMKQMAhUIwiSIQNwMAIAggECAIKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAEIBAgBCkDAIVCAYk3AwAgASAFKQMAIhAgASkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDSAQIA0pAwCFQiCJIhA3AwAgCSAQIAkpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAUgECAFKQMAhUIoiSIQNwMAIAEgECABKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACANIBAgDSkDAIVCMIkiEDcDACAJIBAgCSkDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgBSAQIAUpAwCFQgGJNwMAIAIgBikDACIQIAIpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIA4gECAOKQMAhUIgiSIQNwMAIAogECAKKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAGIBAgBikDAIVCKIkiEDcDACACIBAgAikDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgDiAQIA4pAwCFQjCJIhA3AwAgCiAQIAopAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIAYgECAGKQMAhUIBiTcDACADIAcpAwAiECADKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAPIBAgDykDAIVCIIkiEDcDACALIBAgCykDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgByAQIAcpAwCFQiiJIhA3AwAgAyAQIAMpAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIA8gECAPKQMAhUIwiSIQNwMAIAsgECALKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAHIBAgBykDAIVCAYk3AwAgACAFKQMAIhAgACkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDyAQIA8pAwCFQiCJIhA3AwAgCiAQIAopAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAUgECAFKQMAhUIoiSIQNwMAIAAgECAAKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAPIBAgDykDAIVCMIkiEDcDACAKIBAgCikDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgBSAQIAUpAwCFQgGJNwMAIAEgBikDACIQIAEpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAwgECAMKQMAhUIgiSIQNwMAIAsgECALKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAGIBAgBikDAIVCKIkiEDcDACABIBAgASkDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgDCAQIAwpAwCFQjCJIhA3AwAgCyAQIAspAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIAYgECAGKQMAhUIBiTcDACACIAcpAwAiECACKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACANIBAgDSkDAIVCIIkiEDcDACAIIBAgCCkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgByAQIAcpAwCFQiiJIhA3AwAgAiAQIAIpAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIA0gECANKQMAhUIwiSIQNwMAIAggECAIKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAHIBAgBykDAIVCAYk3AwAgAyAEKQMAIhAgAykDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDiAQIA4pAwCFQiCJIhA3AwAgCSAQIAkpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAQgECAEKQMAhUIoiSIQNwMAIAMgECADKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAOIBAgDikDAIVCMIkiEDcDACAJIBAgCSkDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgBCAQIAQpAwCFQgGJNwMAC98aAQN/QQAhBEEAIAIpAwAgASkDAIU3A5AIQQAgAikDCCABKQMIhTcDmAhBACACKQMQIAEpAxCFNwOgCEEAIAIpAxggASkDGIU3A6gIQQAgAikDICABKQMghTcDsAhBACACKQMoIAEpAyiFNwO4CEEAIAIpAzAgASkDMIU3A8AIQQAgAikDOCABKQM4hTcDyAhBACACKQNAIAEpA0CFNwPQCEEAIAIpA0ggASkDSIU3A9gIQQAgAikDUCABKQNQhTcD4AhBACACKQNYIAEpA1iFNwPoCEEAIAIpA2AgASkDYIU3A/AIQQAgAikDaCABKQNohTcD+AhBACACKQNwIAEpA3CFNwOACUEAIAIpA3ggASkDeIU3A4gJQQAgAikDgAEgASkDgAGFNwOQCUEAIAIpA4gBIAEpA4gBhTcDmAlBACACKQOQASABKQOQAYU3A6AJQQAgAikDmAEgASkDmAGFNwOoCUEAIAIpA6ABIAEpA6ABhTcDsAlBACACKQOoASABKQOoAYU3A7gJQQAgAikDsAEgASkDsAGFNwPACUEAIAIpA7gBIAEpA7gBhTcDyAlBACACKQPAASABKQPAAYU3A9AJQQAgAikDyAEgASkD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",hash:"e4cdc523"},Xp={name:"blake2b",data:"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",hash:"c6f286e6"};function eh(e){return!Number.isInteger(e)||e<8||e>512||e%8!=0?new Error("Invalid variant! Valid values: 8, 16, ..., 512"):null}function th(e=512,t=null){if(eh(e))return Promise.reject(eh(e));let n=null,r=e;if(null!==t){if(n=jp(t),n.length>64)return Promise.reject(new Error("Max key length is 64 bytes"));i=e,o=n.length,r=i|o<<16}var i,o;const s=e/8;return Wp(Xp,s).then(e=>{r>512&&e.writeMemory(n),e.init(r);const t={init:r>512?()=>(e.writeMemory(n),e.init(r),t):()=>(e.init(r),t),update:n=>(e.update(n),t),digest:t=>e.digest(t),save:()=>e.save(),load:n=>(e.load(n),t),blockSize:128,digestSize:s};return t})}new Up;const nh=new DataView(new ArrayBuffer(4));function rh(e){return nh.setInt32(0,e,!0),new Uint8Array(nh.buffer)}function ih(e,t,n){return $p(this,void 0,void 0,function*(){if(n<=64){const e=yield th(8*n);return e.update(rh(n)),e.update(t),e.digest("binary")}const r=Math.ceil(n/32)-2,i=new Uint8Array(n);e.init(),e.update(rh(n)),e.update(t);let o=e.digest("binary");i.set(o.subarray(0,32),0);for(let t=1;t{var t;if(!e||"object"!=typeof e)throw new Error("Invalid options parameter. It requires an object.");if(!e.password)throw new Error("Password must be specified");if(e.password=jp(e.password),e.password.length<1)throw new Error("Password must be specified");if(!e.salt)throw new Error("Salt must be specified");if(e.salt=jp(e.salt),e.salt.length<8)throw new Error("Salt should be at least 8 bytes long");if(e.secret=jp(null!==(t=e.secret)&&void 0!==t?t:""),!Number.isInteger(e.iterations)||e.iterations<1)throw new Error("Iterations should be a positive number");if(!Number.isInteger(e.parallelism)||e.parallelism<1)throw new Error("Parallelism should be a positive number");if(!Number.isInteger(e.hashLength)||e.hashLength<4)throw new Error("Hash length should be at least 4 bytes.");if(!Number.isInteger(e.memorySize))throw new Error("Memory size should be specified.");if(e.memorySize<8*e.parallelism)throw new Error("Memory size should be at least 8 * parallelism.");if(void 0===e.outputType&&(e.outputType="hex"),!["hex","binary","encoded"].includes(e.outputType))throw new Error(`Insupported output type ${e.outputType}. Valid values: ['hex', 'binary', 'encoded']`)})(e),oh(Object.assign(Object.assign({},e),{hashType:"id"}))})}new Up,new Up,new Up,new Up,new Up,new Up,new Up,new Up,new Up,new Up,new Up,new Up,new Up,new Up,new Up,new Up,new Up,new Up,new Up,new Up;const ah={parallelism:4,iterations:8,memorySize:262144,hashLength:32,outputType:"binary"};let lh=null,ch=0;const uh=new Map;async function dh(e,t){try{const n=function(){if(lh)return lh;const e=new Blob(["\n importScripts('https://cdn.jsdelivr.net/npm/hash-wasm@4.11.0/dist/argon2.umd.min.js');\n\n const ARGON2_CONFIG = {\n parallelism: 4,\n iterations: 8,\n memorySize: 262144,\n hashLength: 32,\n outputType: \"binary\"\n };\n\n self.onmessage = async function(e) {\n const { password, salt, id } = e.data;\n\n try {\n const result = await hashwasm.argon2id({\n password: password,\n salt: new Uint8Array(salt),\n ...ARGON2_CONFIG\n });\n\n self.postMessage({\n id,\n success: true,\n result: Array.from(result)\n });\n } catch (error) {\n self.postMessage({\n id,\n success: false,\n error: error.message\n });\n }\n };\n "],{type:"application/javascript"});return lh=new Worker(URL.createObjectURL(e)),lh.onmessage=function(e){const{id:t,success:n,result:r,error:i}=e.data,o=uh.get(t);o&&(uh.delete(t),n?o.resolve(new Uint8Array(r)):o.reject(new Error(i)))},lh.onerror=function(e){console.error("Argon2 worker error:",e)},lh}(),r=++ch;return new Promise((i,o)=>{uh.set(r,{resolve:i,reject:o}),n.postMessage({id:r,password:e,salt:Array.from(t)})})}catch(n){console.warn("Worker failed, falling back to main thread:",n);return await sh({password:e,salt:t,...ah})}}const{window:fh}=l;function ph(e){let t,n,i,o,s,a,l,f,h,g,y,b,k,I,C,E,B,S;function Q(e,t){return"extension"===e[2]?gh:hh}let F=Q(e),D=F(e),$=e[10]&&Bh(e),U=e[11]&&Sh(e);return{c(){t=p("div"),n=p("div"),i=p("div"),o=p("h2"),o.textContent="Login to Nostr",s=m(),a=p("button"),a.textContent="×",l=m(),f=p("div"),h=p("div"),g=p("button"),g.textContent="Extension",y=m(),b=p("button"),b.textContent="Nsec",k=m(),I=p("div"),D.c(),C=m(),$&&$.c(),E=m(),U&&U.c(),A(o,"class","svelte-4xpfbi"),A(a,"class","close-btn svelte-4xpfbi"),A(i,"class","modal-header svelte-4xpfbi"),A(g,"class","tab-btn svelte-4xpfbi"),x(g,"active","extension"===e[2]),A(b,"class","tab-btn svelte-4xpfbi"),x(b,"active","nsec"===e[2]),A(h,"class","tabs svelte-4xpfbi"),A(I,"class","tab-content svelte-4xpfbi"),A(f,"class","tab-container svelte-4xpfbi"),A(n,"class","modal svelte-4xpfbi"),x(n,"dark-theme",e[1]),A(t,"class","modal-overlay svelte-4xpfbi"),A(t,"role","button"),A(t,"tabindex","0")},m(r,d){u(r,t,d),c(t,n),c(n,i),c(i,o),c(i,s),c(i,a),c(n,l),c(n,f),c(f,h),c(h,g),c(h,y),c(h,b),c(f,k),c(f,I),D.m(I,null),c(I,C),$&&$.m(I,null),c(I,E),U&&U.m(I,null),B||(S=[v(a,"click",e[17]),v(g,"click",e[26]),v(b,"click",e[27]),v(n,"click",w(e[24])),v(n,"keydown",w(e[25])),v(t,"click",e[17]),v(t,"keydown",e[32])],B=!0)},p(e,t){4&t[0]&&x(g,"active","extension"===e[2]),4&t[0]&&x(b,"active","nsec"===e[2]),F===(F=Q(e))&&D?D.p(e,t):(D.d(1),D=F(e),D&&(D.c(),D.m(I,C))),e[10]?$?$.p(e,t):($=Bh(e),$.c(),$.m(I,E)):$&&($.d(1),$=null),e[11]?U?U.p(e,t):(U=Sh(e),U.c(),U.m(I,null)):U&&(U.d(1),U=null),2&t[0]&&x(n,"dark-theme",e[1])},d(e){e&&d(t),D.d(),$&&$.d(),U&&U.d(),B=!1,r(S)}}}function hh(e){let t;function n(e,t){return e[14]?yh:mh}let r=n(e),i=r(e);return{c(){t=p("div"),i.c(),A(t,"class","nsec-login svelte-4xpfbi")},m(e,n){u(e,t,n),i.m(t,null)},p(e,o){r===(r=n(e))&&i?i.p(e,o):(i.d(1),i=r(e),i&&(i.c(),i.m(t,null)))},d(e){e&&d(t),i.d()}}}function gh(e){let t,n,r,i,o,s,a,l=e[7]?"Connecting...":"Log in using extension";return{c(){t=p("div"),n=p("p"),n.textContent="Login using a NIP-07 compatible browser\n extension like nos2x or Alby.",r=m(),i=p("button"),o=g(l),A(n,"class","svelte-4xpfbi"),A(i,"class","login-extension-btn svelte-4xpfbi"),i.disabled=e[7],A(t,"class","extension-login svelte-4xpfbi")},m(l,d){u(l,t,d),c(t,n),c(t,r),c(t,i),c(i,o),s||(a=v(i,"click",e[21]),s=!0)},p(e,t){128&t[0]&&l!==(l=e[7]?"Connecting...":"Log in using extension")&&k(o,l),128&t[0]&&(i.disabled=e[7])},d(e){e&&d(t),s=!1,a()}}}function mh(e){let t,n,i,o,s,a,l,f,h,y,w,b,C,E,x,B,S,Q,F,D,$,U,P,R=e[8]?"Generating...":"Generate New Key",T=e[12]&&vh(e),N=e[4]&&wh(e);function O(e,t){return e[9]?kh:e[7]?bh:Ah}let M=O(e),L=M(e);return{c(){t=p("p"),t.textContent="Enter your nsec or generate a new one. Optionally\n set a password to encrypt it securely.",n=m(),i=p("button"),o=g(R),a=m(),T&&T.c(),l=m(),f=p("input"),y=m(),w=p("div"),b=p("label"),b.textContent="Encryption Password (optional but recommended):",C=m(),E=p("input"),B=m(),N&&N.c(),S=m(),Q=p("small"),Q.textContent="Password uses Argon2id with ~3 second derivation time for security.",F=m(),D=p("button"),L.c(),A(t,"class","svelte-4xpfbi"),A(i,"class","generate-btn svelte-4xpfbi"),i.disabled=s=e[7]||e[8],A(f,"type","password"),A(f,"placeholder","nsec1..."),f.disabled=h=e[7]||e[9],A(f,"class","nsec-input svelte-4xpfbi"),A(b,"class","svelte-4xpfbi"),A(E,"type","password"),A(E,"placeholder","Enter password (min 8 chars)"),E.disabled=x=e[7]||e[9],A(E,"class","password-input svelte-4xpfbi"),A(Q,"class","password-hint svelte-4xpfbi"),A(w,"class","password-section svelte-4xpfbi"),A(D,"class","login-nsec-btn svelte-4xpfbi"),D.disabled=$=e[7]||e[9]||!e[3].trim()},m(r,s){u(r,t,s),u(r,n,s),u(r,i,s),c(i,o),u(r,a,s),T&&T.m(r,s),u(r,l,s),u(r,f,s),I(f,e[3]),u(r,y,s),u(r,w,s),c(w,b),c(w,C),c(w,E),I(E,e[4]),c(w,B),N&&N.m(w,null),c(w,S),c(w,Q),u(r,F,s),u(r,D,s),L.m(D,null),U||(P=[v(i,"click",e[20]),v(f,"input",e[29]),v(E,"input",e[30]),v(D,"click",e[22])],U=!0)},p(e,t){256&t[0]&&R!==(R=e[8]?"Generating...":"Generate New Key")&&k(o,R),384&t[0]&&s!==(s=e[7]||e[8])&&(i.disabled=s),e[12]?T?T.p(e,t):(T=vh(e),T.c(),T.m(l.parentNode,l)):T&&(T.d(1),T=null),640&t[0]&&h!==(h=e[7]||e[9])&&(f.disabled=h),8&t[0]&&f.value!==e[3]&&I(f,e[3]),640&t[0]&&x!==(x=e[7]||e[9])&&(E.disabled=x),16&t[0]&&E.value!==e[4]&&I(E,e[4]),e[4]?N?N.p(e,t):(N=wh(e),N.c(),N.m(w,S)):N&&(N.d(1),N=null),M!==(M=O(e))&&(L.d(1),L=M(e),L&&(L.c(),L.m(D,null))),648&t[0]&&$!==($=e[7]||e[9]||!e[3].trim())&&(D.disabled=$)},d(e){e&&d(t),e&&d(n),e&&d(i),e&&d(a),T&&T.d(e),e&&d(l),e&&d(f),e&&d(y),e&&d(w),N&&N.d(),e&&d(F),e&&d(D),L.d(),U=!1,r(P)}}}function yh(e){let t,n,i,o,s,a,l,f,h,y,w,b,k,C,E=e[15]&&Ih(e);function x(e,t){return e[9]?xh:e[7]?Eh:Ch}let B=x(e),S=B(e);return{c(){t=p("p"),t.textContent="You have a stored encrypted key. Enter your\n password to unlock it.",n=m(),E&&E.c(),i=m(),o=p("input"),a=m(),l=p("button"),S.c(),h=m(),y=p("button"),w=g("Clear stored key & start fresh"),A(t,"class","svelte-4xpfbi"),A(o,"type","password"),A(o,"placeholder","Enter your password"),o.disabled=s=e[7]||e[9],A(o,"class","password-input svelte-4xpfbi"),A(l,"class","login-nsec-btn svelte-4xpfbi"),l.disabled=f=e[7]||e[9]||!e[6],A(y,"class","clear-btn svelte-4xpfbi"),y.disabled=b=e[7]||e[9]},m(r,s){u(r,t,s),u(r,n,s),E&&E.m(r,s),u(r,i,s),u(r,o,s),I(o,e[6]),u(r,a,s),u(r,l,s),S.m(l,null),u(r,h,s),u(r,y,s),c(y,w),k||(C=[v(o,"input",e[28]),v(l,"click",e[18]),v(y,"click",e[16])],k=!0)},p(e,t){e[15]?E?E.p(e,t):(E=Ih(e),E.c(),E.m(i.parentNode,i)):E&&(E.d(1),E=null),640&t[0]&&s!==(s=e[7]||e[9])&&(o.disabled=s),64&t[0]&&o.value!==e[6]&&I(o,e[6]),B!==(B=x(e))&&(S.d(1),S=B(e),S&&(S.c(),S.m(l,null))),704&t[0]&&f!==(f=e[7]||e[9]||!e[6])&&(l.disabled=f),640&t[0]&&b!==(b=e[7]||e[9])&&(y.disabled=b)},d(e){e&&d(t),e&&d(n),E&&E.d(e),e&&d(i),e&&d(o),e&&d(a),e&&d(l),S.d(),e&&d(h),e&&d(y),k=!1,r(C)}}}function vh(e){let t,n,r,i,o;return{c(){t=p("div"),n=p("label"),n.textContent="Your new public key (npub):",r=m(),i=p("code"),o=g(e[12]),A(n,"class","svelte-4xpfbi"),A(i,"class","npub-display svelte-4xpfbi"),A(t,"class","generated-info svelte-4xpfbi")},m(e,s){u(e,t,s),c(t,n),c(t,r),c(t,i),c(i,o)},p(e,t){4096&t[0]&&k(o,e[12])},d(e){e&&d(t)}}}function wh(e){let t,n,r,i;return{c(){t=p("input"),A(t,"type","password"),A(t,"placeholder","Confirm password"),t.disabled=n=e[7]||e[9],A(t,"class","password-input svelte-4xpfbi")},m(n,o){u(n,t,o),I(t,e[5]),r||(i=v(t,"input",e[31]),r=!0)},p(e,r){640&r[0]&&n!==(n=e[7]||e[9])&&(t.disabled=n),32&r[0]&&t.value!==e[5]&&I(t,e[5])},d(e){e&&d(t),r=!1,i()}}}function Ah(e){let t;return{c(){t=g("Log in with nsec")},m(e,n){u(e,t,n)},d(e){e&&d(t)}}}function bh(e){let t;return{c(){t=g("Logging in...")},m(e,n){u(e,t,n)},d(e){e&&d(t)}}}function kh(e){let t;return{c(){t=g("Deriving key...")},m(e,n){u(e,t,n)},d(e){e&&d(t)}}}function Ih(e){let t,n,r,i,o,s,a,l=e[15].slice(0,16)+"",f=e[15].slice(-8)+"";return{c(){t=p("div"),n=p("label"),n.textContent="Stored public key:",r=m(),i=p("code"),o=g(l),s=g("..."),a=g(f),A(n,"class","svelte-4xpfbi"),A(i,"class","npub-display svelte-4xpfbi"),A(t,"class","stored-info svelte-4xpfbi")},m(e,l){u(e,t,l),c(t,n),c(t,r),c(t,i),c(i,o),c(i,s),c(i,a)},p(e,t){32768&t[0]&&l!==(l=e[15].slice(0,16)+"")&&k(o,l),32768&t[0]&&f!==(f=e[15].slice(-8)+"")&&k(a,f)},d(e){e&&d(t)}}}function Ch(e){let t;return{c(){t=g("Unlock")},m(e,n){u(e,t,n)},d(e){e&&d(t)}}}function Eh(e){let t;return{c(){t=g("Unlocking...")},m(e,n){u(e,t,n)},d(e){e&&d(t)}}}function xh(e){let t;return{c(){t=g("Deriving key...")},m(e,n){u(e,t,n)},d(e){e&&d(t)}}}function Bh(e){let t,n;return{c(){t=p("div"),n=g(e[10]),A(t,"class","message error-message svelte-4xpfbi")},m(e,r){u(e,t,r),c(t,n)},p(e,t){1024&t[0]&&k(n,e[10])},d(e){e&&d(t)}}}function Sh(e){let t,n;return{c(){t=p("div"),n=g(e[11]),A(t,"class","message success-message svelte-4xpfbi")},m(e,r){u(e,t,r),c(t,n)},p(e,t){2048&t[0]&&k(n,e[11])},d(e){e&&d(t)}}}function Qh(e){let t,n,r,i,o,s,a,l,f,h,y,v=e[13].toFixed(1)+"";return{c(){t=p("div"),n=p("div"),r=p("div"),i=m(),o=p("h3"),o.textContent="Deriving encryption key",s=m(),a=p("div"),l=g(v),f=g("s"),h=m(),y=p("p"),y.textContent="This may take 3-6 seconds for security",A(r,"class","deriving-spinner svelte-4xpfbi"),A(o,"class","svelte-4xpfbi"),A(a,"class","deriving-timer svelte-4xpfbi"),A(y,"class","deriving-note svelte-4xpfbi"),A(n,"class","deriving-modal svelte-4xpfbi"),x(n,"dark-theme",e[1]),A(t,"class","deriving-overlay svelte-4xpfbi")},m(e,d){u(e,t,d),c(t,n),c(n,r),c(n,i),c(n,o),c(n,s),c(n,a),c(a,l),c(a,f),c(n,h),c(n,y)},p(e,t){8192&t[0]&&v!==(v=e[13].toFixed(1)+"")&&k(l,v),2&t[0]&&x(n,"dark-theme",e[1])},d(e){e&&d(t)}}}function Fh(t){let n,r,i,o,s=t[0]&&ph(t),a=t[9]&&Qh(t);return{c(){s&&s.c(),n=m(),a&&a.c(),r=y()},m(e,l){s&&s.m(e,l),u(e,n,l),a&&a.m(e,l),u(e,r,l),i||(o=v(fh,"keydown",t[23]),i=!0)},p(e,t){e[0]?s?s.p(e,t):(s=ph(e),s.c(),s.m(n.parentNode,n)):s&&(s.d(1),s=null),e[9]?a?a.p(e,t):(a=Qh(e),a.c(),a.m(r.parentNode,r)):a&&(a.d(1),a=null)},i:e,o:e,d(e){s&&s.d(e),e&&d(n),a&&a.d(e),e&&d(r),i=!1,o()}}}function Dh(e,t,n){const r=$();let{showModal:i=!1}=t,{isDarkTheme:o=!1}=t,s="extension",a="",l="",c="",u="",d=!1,f=!1,p=!1,h="",g="",m="",y="",v=0,w=null,A=null;function b(){n(13,v=0),w=performance.now(),k()}function k(){null!==w&&(n(13,v=(performance.now()-w)/1e3),A=requestAnimationFrame(k))}function I(){w=null,A&&(cancelAnimationFrame(A),A=null)}D(()=>{I()});let C=!1,E="";function x(){n(14,C=!!localStorage.getItem("nostr_privkey_encrypted")),n(15,E=localStorage.getItem("nostr_pubkey")||"")}function B(){n(0,i=!1),n(3,a=""),n(4,l=""),n(5,c=""),n(6,u=""),n(10,h=""),n(11,g=""),m="",n(12,y=""),r("close")}function S(e){n(2,s=e),n(10,h=""),n(11,g=""),m="",n(12,y="")}async function Q(){n(7,d=!0),n(10,h=""),n(11,g="");try{if(!a.trim())throw new Error("Please enter your nsec");if(!function(e){if(!e||!e.startsWith("nsec1"))return!1;try{return"nsec"===mu(e).type}catch{return!1}}(a.trim()))throw new Error("Invalid nsec format or checksum");if(l){if(l.length<8)throw new Error("Password must be at least 8 characters");if(l!==c)throw new Error("Passwords do not match")}const e=kf.fromKey(a.trim()),t=await e.getPublicKey();if(localStorage.setItem("nostr_auth_method","nsec"),localStorage.setItem("nostr_pubkey",t),l){n(9,p=!0),b();const e=await async function(e,t){if(!e.startsWith("nsec1"))throw new Error("Invalid nsec format - must start with nsec1");try{if("nsec"!==mu(e).type)throw new Error("Invalid nsec - wrong type")}catch(e){throw new Error("Invalid nsec - bech32 checksum failed")}const n=crypto.getRandomValues(new Uint8Array(32)),r=crypto.getRandomValues(new Uint8Array(12)),i=await dh(t,n),o=await crypto.subtle.importKey("raw",i,{name:"AES-GCM"},!1,["encrypt"]),s=new TextEncoder,a=await crypto.subtle.encrypt({name:"AES-GCM",iv:r},o,s.encode(e)),l=new Uint8Array(n.length+r.length+a.byteLength);return l.set(n,0),l.set(r,n.length),l.set(new Uint8Array(a),n.length+r.length),btoa(String.fromCharCode(...l))}(a.trim(),l);I(),n(9,p=!1),localStorage.setItem("nostr_privkey_encrypted",e),localStorage.removeItem("nostr_privkey")}else localStorage.setItem("nostr_privkey",a.trim()),localStorage.removeItem("nostr_privkey_encrypted"),n(11,g="Successfully logged in with nsec!");r("login",{method:"nsec",pubkey:t,privateKey:a.trim(),signer:e}),setTimeout(()=>{B()},1500)}catch(e){n(10,h=e.message)}finally{n(7,d=!1)}}F(()=>{x()});return e.$$set=e=>{"showModal"in e&&n(0,i=e.showModal),"isDarkTheme"in e&&n(1,o=e.isDarkTheme)},e.$$.update=()=>{1&e.$$.dirty[0]&&i&&x()},[i,o,s,a,l,c,u,d,f,p,h,g,y,v,C,E,function(){localStorage.removeItem("nostr_privkey_encrypted"),localStorage.removeItem("nostr_privkey"),localStorage.removeItem("nostr_pubkey"),localStorage.removeItem("nostr_auth_method"),n(14,C=!1),n(15,E=""),n(6,u=""),n(10,h=""),n(11,g="")},B,async function(){n(7,d=!0),n(9,p=!0),b(),n(10,h=""),n(11,g="");try{if(!u)throw new Error("Please enter your password");const e=localStorage.getItem("nostr_privkey_encrypted");if(!e)throw new Error("No encrypted key found");const t=await async function(e,t){const n=new Uint8Array(atob(e).split("").map(e=>e.charCodeAt(0)));if(n.length<60)throw new Error("Invalid encrypted data - too short");const r=n.slice(0,32),i=n.slice(32,44),o=n.slice(44),s=await dh(t,r),a=await crypto.subtle.importKey("raw",s,{name:"AES-GCM"},!1,["decrypt"]);let l;try{l=await crypto.subtle.decrypt({name:"AES-GCM",iv:i},a,o)}catch(e){throw new Error("Decryption failed - invalid password or corrupted data")}const c=(new TextDecoder).decode(l);if(!c.startsWith("nsec1"))throw new Error("Decryption produced invalid data - not an nsec");try{if("nsec"!==mu(c).type)throw new Error("Decryption produced invalid nsec type")}catch(e){throw new Error("Decryption produced invalid nsec - bech32 checksum failed")}return c}(e,u);I(),n(9,p=!1);const i=kf.fromKey(t),o=await i.getPublicKey();r("login",{method:"nsec",pubkey:o,privateKey:t,signer:i}),B()}catch(e){I(),e.message.includes("decrypt")||e.message.includes("tag")?n(10,h="Invalid password"):n(10,h=e.message)}finally{n(7,d=!1),n(9,p=!1),I()}},S,async function(){n(8,f=!0),n(10,h=""),n(11,g="");try{const e=Wc(),t=wu("nsec",e),r=vu(Zc(e));m=t,n(12,y=r),n(3,a=t),n(11,g="New key generated! Set an encryption password below to secure it.")}catch(e){n(10,h="Failed to generate key: "+e.message)}finally{n(8,f=!1)}},async function(){n(7,d=!0),n(10,h=""),n(11,g="");try{if(!window.nostr)throw new Error("No Nostr extension found. Please install a NIP-07 compatible extension like nos2x or Alby.");const e=await window.nostr.getPublicKey();e&&(localStorage.setItem("nostr_auth_method","extension"),localStorage.setItem("nostr_pubkey",e),n(11,g="Successfully logged in with extension!"),r("login",{method:"extension",pubkey:e,signer:window.nostr}),setTimeout(()=>{B()},1500))}catch(e){n(10,h=e.message)}finally{n(7,d=!1)}},Q,function(e){"Escape"===e.key&&B(),"Enter"===e.key&&"nsec"===s&&Q()},function(t){U.call(this,e,t)},function(t){U.call(this,e,t)},()=>S("extension"),()=>S("nsec"),function(){u=this.value,n(6,u)},function(){a=this.value,n(3,a)},function(){l=this.value,n(4,l)},function(){c=this.value,n(5,c)},e=>"Escape"===e.key&&B()]}class $h extends ie{constructor(e){super(),re(this,e,Dh,Fh,o,{showModal:0,isDarkTheme:1},null,[-1,-1])}}function Uh(e,t,n){const r=e.slice();return r[72]=t[n],r}function Ph(e,t,n){const r=e.slice();return r[75]=t[n],r}function Rh(e,t,n){const r=e.slice();return r[72]=t[n],r}function Th(e,t,n){const r=e.slice();return r[72]=t[n],r}function Nh(e,t,n){const r=e.slice();return r[72]=t[n],r}function Oh(e,t,n){const r=e.slice();return r[72]=t[n],r}function Mh(e,t,n){const r=e.slice();return r[72]=t[n],r}function Lh(e){let t,n,r;return{c(){t=p("div"),n=g(e[3]),A(t,"class",r="message "+e[4]+" svelte-1y8wjwc")},m(e,r){u(e,t,r),c(t,n)},p(e,i){8&i[0]&&k(n,e[3]),16&i[0]&&r!==(r="message "+e[4]+" svelte-1y8wjwc")&&A(t,"class",r)},d(e){e&&d(t)}}}function _h(e){let t,n,i,o,s,a,l,f,h,y,w,b,k,C,E,x,B,S,Q,F,D,$,U,P,R,T,N,O;function M(e,t){return e[5]&&e[5].length>0?jh:Hh}let L=M(e),_=L(e);function H(e,t){return e[8]&&e[8].length>0?Vh:Kh}let j=H(e),G=j(e);return{c(){t=p("div"),n=p("div"),i=p("h3"),i.textContent="Banned Pubkeys",o=m(),s=p("div"),a=p("input"),l=m(),f=p("input"),h=m(),y=p("button"),w=g("Ban Pubkey"),b=m(),k=p("div"),_.c(),C=m(),E=p("div"),x=p("h3"),x.textContent="Allowed Pubkeys",B=m(),S=p("div"),Q=p("input"),F=m(),D=p("input"),$=m(),U=p("button"),P=g("Allow Pubkey"),R=m(),T=p("div"),G.c(),A(i,"class","svelte-1y8wjwc"),A(a,"type","text"),A(a,"placeholder","Pubkey (64 hex chars)"),A(a,"class","svelte-1y8wjwc"),A(f,"type","text"),A(f,"placeholder","Reason (optional)"),A(f,"class","svelte-1y8wjwc"),y.disabled=e[2],A(y,"class","svelte-1y8wjwc"),A(s,"class","add-form svelte-1y8wjwc"),A(k,"class","list svelte-1y8wjwc"),A(n,"class","section svelte-1y8wjwc"),A(x,"class","svelte-1y8wjwc"),A(Q,"type","text"),A(Q,"placeholder","Pubkey (64 hex chars)"),A(Q,"class","svelte-1y8wjwc"),A(D,"type","text"),A(D,"placeholder","Reason (optional)"),A(D,"class","svelte-1y8wjwc"),U.disabled=e[2],A(U,"class","svelte-1y8wjwc"),A(S,"class","add-form svelte-1y8wjwc"),A(T,"class","list svelte-1y8wjwc"),A(E,"class","section svelte-1y8wjwc"),A(t,"class","pubkeys-section")},m(r,d){u(r,t,d),c(t,n),c(n,i),c(n,o),c(n,s),c(s,a),I(a,e[6]),c(s,l),c(s,f),I(f,e[7]),c(s,h),c(s,y),c(y,w),c(n,b),c(n,k),_.m(k,null),c(t,C),c(t,E),c(E,x),c(E,B),c(E,S),c(S,Q),I(Q,e[9]),c(S,F),c(S,D),I(D,e[10]),c(S,$),c(S,U),c(U,P),c(E,R),c(E,T),G.m(T,null),N||(O=[v(a,"input",e[43]),v(f,"input",e[44]),v(y,"click",e[25]),v(Q,"input",e[45]),v(D,"input",e[46]),v(U,"click",e[26])],N=!0)},p(e,t){64&t[0]&&a.value!==e[6]&&I(a,e[6]),128&t[0]&&f.value!==e[7]&&I(f,e[7]),4&t[0]&&(y.disabled=e[2]),L===(L=M(e))&&_?_.p(e,t):(_.d(1),_=L(e),_&&(_.c(),_.m(k,null))),512&t[0]&&Q.value!==e[9]&&I(Q,e[9]),1024&t[0]&&D.value!==e[10]&&I(D,e[10]),4&t[0]&&(U.disabled=e[2]),j===(j=H(e))&&G?G.p(e,t):(G.d(1),G=j(e),G&&(G.c(),G.m(T,null)))},d(e){e&&d(t),_.d(),G.d(),N=!1,r(O)}}}function Hh(t){let n;return{c(){n=p("div"),n.innerHTML="No banned pubkeys configured.
",A(n,"class","no-items svelte-1y8wjwc")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function jh(e){let t,n=e[5],r=[];for(let t=0;tNo allowed pubkeys configured.",A(n,"class","no-items svelte-1y8wjwc")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function Vh(e){let t,n=e[8],r=[];for(let t=0;t0?Zh:Wh}let L=M(e),_=L(e);let H=function(e){return e[22]&&e[22].length>0?ng:tg}(e),j=H(e);return{c(){t=p("div"),n=p("div"),i=p("h3"),i.textContent="Banned Events",o=m(),s=p("div"),a=p("input"),l=m(),f=p("input"),h=m(),y=p("button"),w=g("Ban Event"),b=m(),k=p("div"),_.c(),C=m(),E=p("div"),x=p("h3"),x.textContent="Allowed Events",B=m(),S=p("div"),Q=p("input"),F=m(),D=p("input"),$=m(),U=p("button"),P=g("Allow Event"),R=m(),T=p("div"),j.c(),A(i,"class","svelte-1y8wjwc"),A(a,"type","text"),A(a,"placeholder","Event ID (64 hex chars)"),A(a,"class","svelte-1y8wjwc"),A(f,"type","text"),A(f,"placeholder","Reason (optional)"),A(f,"class","svelte-1y8wjwc"),y.disabled=e[2],A(y,"class","svelte-1y8wjwc"),A(s,"class","add-form svelte-1y8wjwc"),A(k,"class","list svelte-1y8wjwc"),A(n,"class","section svelte-1y8wjwc"),A(x,"class","svelte-1y8wjwc"),A(Q,"type","text"),A(Q,"placeholder","Event ID (64 hex chars)"),A(Q,"class","svelte-1y8wjwc"),A(D,"type","text"),A(D,"placeholder","Reason (optional)"),A(D,"class","svelte-1y8wjwc"),U.disabled=e[2],A(U,"class","svelte-1y8wjwc"),A(S,"class","add-form svelte-1y8wjwc"),A(T,"class","list svelte-1y8wjwc"),A(E,"class","section svelte-1y8wjwc"),A(t,"class","events-section")},m(r,d){u(r,t,d),c(t,n),c(n,i),c(n,o),c(n,s),c(s,a),I(a,e[12]),c(s,l),c(s,f),I(f,e[13]),c(s,h),c(s,y),c(y,w),c(n,b),c(n,k),_.m(k,null),c(t,C),c(t,E),c(E,x),c(E,B),c(E,S),c(S,Q),I(Q,e[14]),c(S,F),c(S,D),I(D,e[15]),c(S,$),c(S,U),c(U,P),c(E,R),c(E,T),j.m(T,null),N||(O=[v(a,"input",e[47]),v(f,"input",e[48]),v(y,"click",e[27]),v(Q,"input",e[49]),v(D,"input",e[50]),v(U,"click",e[28])],N=!0)},p(e,t){4096&t[0]&&a.value!==e[12]&&I(a,e[12]),8192&t[0]&&f.value!==e[13]&&I(f,e[13]),4&t[0]&&(y.disabled=e[2]),L===(L=M(e))&&_?_.p(e,t):(_.d(1),_=L(e),_&&(_.c(),_.m(k,null))),16384&t[0]&&Q.value!==e[14]&&I(Q,e[14]),32768&t[0]&&D.value!==e[15]&&I(D,e[15]),4&t[0]&&(U.disabled=e[2]),j.p(e,t)},d(e){e&&d(t),_.d(),j.d(),N=!1,r(O)}}}function Wh(t){let n;return{c(){n=p("div"),n.innerHTML="No banned events configured.
",A(n,"class","no-items svelte-1y8wjwc")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function Zh(e){let t,n=e[11],r=[];for(let t=0;tNo allowed events configured.",A(n,"class","no-items svelte-1y8wjwc")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function ng(e){let t,n=e[22],r=[];for(let t=0;t0?sg:og}let B=x(e),S=B(e);return{c(){t=p("div"),n=p("div"),i=p("h3"),i.textContent="Blocked IPs",o=m(),s=p("div"),a=p("input"),l=m(),f=p("input"),h=m(),y=p("button"),w=g("Block IP"),b=m(),k=p("div"),S.c(),A(i,"class","svelte-1y8wjwc"),A(a,"type","text"),A(a,"placeholder","IP Address"),A(a,"class","svelte-1y8wjwc"),A(f,"type","text"),A(f,"placeholder","Reason (optional)"),A(f,"class","svelte-1y8wjwc"),y.disabled=e[2],A(y,"class","svelte-1y8wjwc"),A(s,"class","add-form svelte-1y8wjwc"),A(k,"class","list svelte-1y8wjwc"),A(n,"class","section svelte-1y8wjwc"),A(t,"class","ips-section")},m(r,d){u(r,t,d),c(t,n),c(n,i),c(n,o),c(n,s),c(s,a),I(a,e[17]),c(s,l),c(s,f),I(f,e[18]),c(s,h),c(s,y),c(y,w),c(n,b),c(n,k),S.m(k,null),C||(E=[v(a,"input",e[51]),v(f,"input",e[52]),v(y,"click",e[29])],C=!0)},p(e,t){131072&t[0]&&a.value!==e[17]&&I(a,e[17]),262144&t[0]&&f.value!==e[18]&&I(f,e[18]),4&t[0]&&(y.disabled=e[2]),B===(B=x(e))&&S?S.p(e,t):(S.d(1),S=B(e),S&&(S.c(),S.m(k,null)))},d(e){e&&d(t),S.d(),C=!1,r(E)}}}function og(t){let n;return{c(){n=p("div"),n.innerHTML="No blocked IPs configured.
",A(n,"class","no-items svelte-1y8wjwc")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function sg(e){let t,n=e[16],r=[];for(let t=0;t0?dg:ug}let x=E(e),B=x(e);return{c(){t=p("div"),n=p("div"),i=p("h3"),i.textContent="Allowed Event Kinds",o=m(),s=p("div"),a=p("input"),l=m(),f=p("button"),h=g("Allow Kind"),y=m(),w=p("div"),B.c(),A(i,"class","svelte-1y8wjwc"),A(a,"type","number"),A(a,"placeholder","Kind number"),A(a,"class","svelte-1y8wjwc"),f.disabled=e[2],A(f,"class","svelte-1y8wjwc"),A(s,"class","add-form svelte-1y8wjwc"),A(w,"class","list svelte-1y8wjwc"),A(n,"class","section svelte-1y8wjwc"),A(t,"class","kinds-section")},m(r,d){u(r,t,d),c(t,n),c(n,i),c(n,o),c(n,s),c(s,a),I(a,e[20]),c(s,l),c(s,f),c(f,h),c(n,y),c(n,w),B.m(w,null),k||(C=[v(a,"input",e[53]),v(f,"click",e[30])],k=!0)},p(e,t){1048576&t[0]&&b(a.value)!==e[20]&&I(a,e[20]),4&t[0]&&(f.disabled=e[2]),x===(x=E(e))&&B?B.p(e,t):(B.d(1),B=x(e),B&&(B.c(),B.m(w,null)))},d(e){e&&d(t),B.d(),k=!1,r(C)}}}function ug(t){let n;return{c(){n=p("div"),n.innerHTML="No allowed kinds configured. All kinds are\n allowed by default.
",A(n,"class","no-items svelte-1y8wjwc")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function dg(e){let t,n=e[19],r=[];for(let t=0;t0?gg:hg}let w=y(e),b=w(e);return{c(){t=p("div"),n=p("div"),r=p("h3"),r.textContent="Events Needing Moderation",i=m(),o=p("button"),s=g("Refresh"),a=m(),l=p("div"),b.c(),A(r,"class","svelte-1y8wjwc"),o.disabled=e[2],A(l,"class","list svelte-1y8wjwc"),A(n,"class","section svelte-1y8wjwc"),A(t,"class","moderation-section")},m(d,p){u(d,t,p),c(t,n),c(n,r),c(n,i),c(n,o),c(o,s),c(n,a),c(n,l),b.m(l,null),f||(h=v(o,"click",e[24]),f=!0)},p(e,t){4&t[0]&&(o.disabled=e[2]),w===(w=y(e))&&b?b.p(e,t):(b.d(1),b=w(e),b&&(b.c(),b.m(l,null)))},d(e){e&&d(t),b.d(),f=!1,h()}}}function hg(t){let n;return{c(){n=p("div"),n.innerHTML="No events need moderation at this time.
",A(n,"class","no-items svelte-1y8wjwc")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function gg(e){let t,n=e[21],r=[];for(let t=0;tManaged ACL Configuration \n Configure access control using NIP-86 management API
\n Owner Only: This interface is restricted to relay owners\n only.
',o=m(),z&&z.c(),s=m(),a=p("div"),l=p("button"),f=g("Pubkeys"),y=m(),w=p("button"),b=g("Events"),I=m(),C=p("button"),E=g("IPs"),B=m(),S=p("button"),Q=g("Kinds"),D=m(),$=p("button"),U=g("Moderation"),R=m(),T=p("button"),N=g("Relay Config"),M=m(),L=p("div"),q&&q.c(),_=m(),Y&&Y.c(),H=m(),W&&W.c(),j=m(),Z&&Z.c(),G=m(),X&&X.c(),J=m(),ee&&ee.c(),A(i,"class","header svelte-1y8wjwc"),A(l,"class",h="tab "+("pubkeys"===t[1]?"active":"")+" svelte-1y8wjwc"),A(w,"class",k="tab "+("events"===t[1]?"active":"")+" svelte-1y8wjwc"),A(C,"class",x="tab "+("ips"===t[1]?"active":"")+" svelte-1y8wjwc"),A(S,"class",F="tab "+("kinds"===t[1]?"active":"")+" svelte-1y8wjwc"),A($,"class",P="tab "+("moderation"===t[1]?"active":"")+" svelte-1y8wjwc"),A(T,"class",O="tab "+("relay"===t[1]?"active":"")+" svelte-1y8wjwc"),A(a,"class","tabs svelte-1y8wjwc"),A(L,"class","tab-content svelte-1y8wjwc")},m(e,r){u(e,n,r),c(n,i),c(n,o),z&&z.m(n,null),c(n,s),c(n,a),c(a,l),c(l,f),c(a,y),c(a,w),c(w,b),c(a,I),c(a,C),c(C,E),c(a,B),c(a,S),c(S,Q),c(a,D),c(a,$),c($,U),c(a,R),c(a,T),c(T,N),c(n,M),c(n,L),q&&q.m(L,null),c(L,_),Y&&Y.m(L,null),c(L,H),W&&W.m(L,null),c(L,j),Z&&Z.m(L,null),c(L,G),X&&X.m(L,null),c(L,J),ee&&ee.m(L,null),K||(V=[v(l,"click",t[37]),v(w,"click",t[38]),v(C,"click",t[39]),v(S,"click",t[40]),v($,"click",t[41]),v(T,"click",t[42])],K=!0)},p(e,t){e[3]?z?z.p(e,t):(z=Lh(e),z.c(),z.m(n,s)):z&&(z.d(1),z=null),2&t[0]&&h!==(h="tab "+("pubkeys"===e[1]?"active":"")+" svelte-1y8wjwc")&&A(l,"class",h),2&t[0]&&k!==(k="tab "+("events"===e[1]?"active":"")+" svelte-1y8wjwc")&&A(w,"class",k),2&t[0]&&x!==(x="tab "+("ips"===e[1]?"active":"")+" svelte-1y8wjwc")&&A(C,"class",x),2&t[0]&&F!==(F="tab "+("kinds"===e[1]?"active":"")+" svelte-1y8wjwc")&&A(S,"class",F),2&t[0]&&P!==(P="tab "+("moderation"===e[1]?"active":"")+" svelte-1y8wjwc")&&A($,"class",P),2&t[0]&&O!==(O="tab "+("relay"===e[1]?"active":"")+" svelte-1y8wjwc")&&A(T,"class",O),"pubkeys"===e[1]?q?q.p(e,t):(q=_h(e),q.c(),q.m(L,_)):q&&(q.d(1),q=null),"events"===e[1]?Y?Y.p(e,t):(Y=Yh(e),Y.c(),Y.m(L,H)):Y&&(Y.d(1),Y=null),"ips"===e[1]?W?W.p(e,t):(W=ig(e),W.c(),W.m(L,j)):W&&(W.d(1),W=null),"kinds"===e[1]?Z?Z.p(e,t):(Z=cg(e),Z.c(),Z.m(L,G)):Z&&(Z.d(1),Z=null),"moderation"===e[1]?X?X.p(e,t):(X=pg(e),X.c(),X.m(L,J)):X&&(X.d(1),X=null),"relay"===e[1]?ee?ee.p(e,t):(ee=vg(e),ee.c(),ee.m(L,null)):ee&&(ee.d(1),ee=null)},i:e,o:e,d(e){e&&d(n),z&&z.d(),q&&q.d(),Y&&Y.d(),W&&W.d(),Z&&Z.d(),X&&X.d(),ee&&ee.d(),K=!1,r(V)}}}function kg(e,t,n){let{userSigner:r}=t,{userPubkey:i}=t,o="pubkeys",s=!1,a="",l="info",c=[],u="",d="",f=[],p="",h="",g=[],m="",y="",v="",w="",A=[],k="",I="",C=[],E="",x=[],B={relay_name:"",relay_description:"",relay_icon:""};async function S(){try{n(2,s=!0),console.log("Fetching relay info from /");const e=await fetch(window.location.origin+"/",{headers:{Accept:"application/nostr+json"}});if(console.log("Response status:",e.status),console.log("Response headers:",e.headers),e.ok){const t=await e.json();console.log("Raw relay info:",t),n(0,B={relay_name:t.name||"",relay_description:t.description||"",relay_icon:t.icon||""}),console.log("Updated relayConfig:",B),console.log("Loaded relay info:",t),n(3,a="Relay configuration loaded successfully"),n(4,l="success")}else console.error("Failed to fetch relay info, status:",e.status),n(3,a=`Failed to fetch relay info: ${e.status}`),n(4,l="error")}catch(e){console.error("Failed to fetch relay info:",e),n(3,a=`Failed to fetch relay info: ${e.message}`),n(4,l="error")}finally{n(2,s=!1)}}async function Q(e,t=[]){try{n(2,s=!0),n(3,a="");const o={method:e,params:t},l=await async function(e,t){if(!r)throw new Error("No signer available for authentication. Please log in with a Nostr extension.");if(!i)throw new Error("No user pubkey available for authentication.");const n=window.location.origin+t,o={kind:27235,created_at:Math.floor(Date.now()/1e3),tags:[["u",n],["method",e]],content:"",pubkey:i},s=await r.signEvent(o),a=JSON.stringify(s);return`Nostr ${btoa(a)}`}("POST","/api/nip86"),c=await fetch("/api/nip86",{method:"POST",headers:{"Content-Type":"application/nostr+json+rpc",Authorization:l},body:JSON.stringify(o)});if(!c.ok)throw new Error(`HTTP ${c.status}: ${c.statusText}`);const u=await c.json();if(u.error)throw new Error(u.error);return u.result}catch(e){throw console.error("NIP-86 API error:",e),n(3,a=e.message),n(4,l="error"),e}finally{n(2,s=!1)}}async function D(){try{n(5,c=await Q("listbannedpubkeys"))}catch(e){console.error("Failed to load banned pubkeys:",e)}}async function $(){try{n(8,f=await Q("listallowedpubkeys"))}catch(e){console.error("Failed to load allowed pubkeys:",e)}}async function U(){try{n(11,g=await Q("listbannedevents"))}catch(e){console.error("Failed to load banned events:",e)}}async function P(){try{n(16,A=await Q("listblockedips"))}catch(e){console.error("Failed to load blocked IPs:",e)}}async function R(){try{n(19,C=await Q("listallowedkinds"))}catch(e){console.error("Failed to load allowed kinds:",e)}}async function T(){try{n(2,s=!0),n(21,x=await Q("listeventsneedingmoderation")),console.log("Loaded events needing moderation:",x)}catch(e){console.error("Failed to load events needing moderation:",e),n(3,a=`Failed to load moderation events: ${e.message}`),n(4,l="error"),n(21,x=[])}finally{n(2,s=!1)}}async function N(e){try{await Q("disallowkind",[e]),n(3,a="Kind disallowed successfully"),n(4,l="success"),await R()}catch(e){console.error("Failed to disallow kind:",e)}}async function O(e){try{await Q("allowevent",[e,"Approved from moderation queue"]),n(3,a="Event allowed successfully"),n(4,l="success"),await T()}catch(e){console.error("Failed to allow event from moderation:",e)}}async function M(e){try{await Q("banevent",[e,"Banned from moderation queue"]),n(3,a="Event banned successfully"),n(4,l="success"),await T()}catch(e){console.error("Failed to ban event from moderation:",e)}}F(()=>{setTimeout(()=>{S()},100)}),async function(){await Promise.all([D(),$(),U(),P(),R()])}();return e.$$set=e=>{"userSigner"in e&&n(35,r=e.userSigner),"userPubkey"in e&&n(36,i=e.userPubkey)},e.$$.update=()=>{1&e.$$.dirty[0]&&console.log("relayConfig changed:",B)},[B,o,s,a,l,c,u,d,f,p,h,g,m,y,v,w,A,k,I,C,E,x,[],S,T,async function(){if(u)try{await Q("banpubkey",[u,d]),n(3,a="Pubkey banned successfully"),n(4,l="success"),n(6,u=""),n(7,d=""),await D()}catch(e){console.error("Failed to ban pubkey:",e)}},async function(){if(p)try{await Q("allowpubkey",[p,h]),n(3,a="Pubkey allowed successfully"),n(4,l="success"),n(9,p=""),n(10,h=""),await $()}catch(e){console.error("Failed to allow pubkey:",e)}},async function(){if(m)try{await Q("banevent",[m,y]),n(3,a="Event banned successfully"),n(4,l="success"),n(12,m=""),n(13,y=""),await U()}catch(e){console.error("Failed to ban event:",e)}},async function(){if(v)try{await Q("allowevent",[v,w]),n(3,a="Event allowed successfully"),n(4,l="success"),n(14,v=""),n(15,w="")}catch(e){console.error("Failed to allow event:",e)}},async function(){if(k)try{await Q("blockip",[k,I]),n(3,a="IP blocked successfully"),n(4,l="success"),n(17,k=""),n(18,I=""),await P()}catch(e){console.error("Failed to block IP:",e)}},async function(){if(!E)return;const e=parseInt(E);if(isNaN(e))return n(3,a="Invalid kind number"),void n(4,l="error");try{await Q("allowkind",[e]),n(3,a="Kind allowed successfully"),n(4,l="success"),n(20,E=""),await R()}catch(e){console.error("Failed to allow kind:",e)}},N,async function(){try{n(2,s=!0),n(3,a="");const e=[];if(B.relay_name&&e.push(Q("changerelayname",[B.relay_name])),B.relay_description&&e.push(Q("changerelaydescription",[B.relay_description])),B.relay_icon&&e.push(Q("changerelayicon",[B.relay_icon])),0===e.length)return n(3,a="No changes to update"),void n(4,l="info");await Promise.all(e),n(3,a="Relay configuration updated successfully"),n(4,l="success"),await S()}catch(e){console.error("Failed to update relay configuration:",e),n(3,a=`Failed to update relay configuration: ${e.message}`),n(4,l="error")}finally{n(2,s=!1)}},O,M,r,i,()=>n(1,o="pubkeys"),()=>n(1,o="events"),()=>n(1,o="ips"),()=>n(1,o="kinds"),()=>{n(1,o="moderation"),x&&0!==x.length||T()},()=>n(1,o="relay"),function(){u=this.value,n(6,u)},function(){d=this.value,n(7,d)},function(){p=this.value,n(9,p)},function(){h=this.value,n(10,h)},function(){m=this.value,n(12,m)},function(){y=this.value,n(13,y)},function(){v=this.value,n(14,v)},function(){w=this.value,n(15,w)},function(){k=this.value,n(17,k)},function(){I=this.value,n(18,I)},function(){E=b(this.value),n(20,E)},e=>N(e),e=>O(e.id),e=>M(e.id),function(){B.relay_name=this.value,n(0,B)},function(){B.relay_description=this.value,n(0,B)},function(){B.relay_icon=this.value,n(0,B)}]}class Ig extends ie{constructor(e){super(),re(this,e,kg,bg,o,{userSigner:35,userPubkey:36},null,[-1,-1,-1])}}function Cg(e){let t,n;return{c(){t=p("span"),n=g(e[3]),A(t,"class","permission-badge svelte-1qkhxam")},m(e,r){u(e,t,r),c(t,n)},p(e,t){8&t&&k(n,e[3])},d(e){e&&d(t)}}}function Eg(t){let n,r,i;return{c(){n=p("button"),n.textContent="Log in",A(n,"class","login-btn svelte-1qkhxam")},m(e,o){u(e,n,o),r||(i=v(n,"click",t[7]),r=!0)},p:e,d(e){e&&d(n),r=!1,i()}}}function xg(e){let t,n,r,i,o,s,a=(e[4]?.name||e[5])+"";function l(e,t){return e[4]?.picture?Sg:Bg}let f=l(e),h=f(e);return{c(){t=p("button"),h.c(),n=m(),r=p("span"),i=g(a),A(r,"class","user-name svelte-1qkhxam"),A(t,"class","user-profile-btn svelte-1qkhxam")},m(a,l){u(a,t,l),h.m(t,null),c(t,n),c(t,r),c(r,i),o||(s=v(t,"click",e[6]),o=!0)},p(e,r){f===(f=l(e))&&h?h.p(e,r):(h.d(1),h=f(e),h&&(h.c(),h.m(t,n))),48&r&&a!==(a=(e[4]?.name||e[5])+"")&&k(i,a)},d(e){e&&d(t),h.d(),o=!1,s()}}}function Bg(t){let n;return{c(){n=p("div"),n.textContent="👤",A(n,"class","user-avatar-placeholder svelte-1qkhxam")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function Sg(e){let t,n;return{c(){t=p("img"),a(t.src,n=e[4].picture)||A(t,"src",n),A(t,"alt","User avatar"),A(t,"class","user-avatar svelte-1qkhxam")},m(e,n){u(e,t,n)},p(e,r){16&r&&!a(t.src,n=e[4].picture)&&A(t,"src",n)},d(e){e&&d(t)}}}function Qg(t){let n,r,i,o,s,l,f,h,y,v,w=t[1]&&t[2]&&Cg(t);function b(e,t){return e[1]?xg:Eg}let k=b(t),I=k(t);return{c(){n=p("header"),r=p("div"),i=p("img"),s=m(),l=p("div"),f=p("span"),h=g("ORLY? dashboard\n "),w&&w.c(),y=m(),v=p("div"),I.c(),a(i.src,o="/orly.png")||A(i,"src","/orly.png"),A(i,"alt","ORLY Logo"),A(i,"class","logo svelte-1qkhxam"),A(f,"class","app-title svelte-1qkhxam"),A(l,"class","header-title svelte-1qkhxam"),A(v,"class","header-buttons svelte-1qkhxam"),A(r,"class","header-content svelte-1qkhxam"),A(n,"class","main-header svelte-1qkhxam"),x(n,"dark-theme",t[0])},m(e,t){u(e,n,t),c(n,r),c(r,i),c(r,s),c(r,l),c(l,f),c(f,h),w&&w.m(f,null),c(r,y),c(r,v),I.m(v,null)},p(e,[t]){e[1]&&e[2]?w?w.p(e,t):(w=Cg(e),w.c(),w.m(f,null)):w&&(w.d(1),w=null),k===(k=b(e))&&I?I.p(e,t):(I.d(1),I=k(e),I&&(I.c(),I.m(v,null))),1&t&&x(n,"dark-theme",e[0])},i:e,o:e,d(e){e&&d(n),w&&w.d(),I.d()}}}function Fg(e,t,n){let{isDarkTheme:r=!1}=t,{isLoggedIn:i=!1}=t,{userRole:o=""}=t,{currentEffectiveRole:s=""}=t,{userProfile:a=null}=t,{userPubkey:l=""}=t;const c=$();return e.$$set=e=>{"isDarkTheme"in e&&n(0,r=e.isDarkTheme),"isLoggedIn"in e&&n(1,i=e.isLoggedIn),"userRole"in e&&n(2,o=e.userRole),"currentEffectiveRole"in e&&n(3,s=e.currentEffectiveRole),"userProfile"in e&&n(4,a=e.userProfile),"userPubkey"in e&&n(5,l=e.userPubkey)},[r,i,o,s,a,l,function(){c("openSettingsDrawer")},function(){c("openLoginModal")}]}class Dg extends ie{constructor(e){super(),re(this,e,Fg,Qg,o,{isDarkTheme:0,isLoggedIn:1,userRole:2,currentEffectiveRole:3,userProfile:4,userPubkey:5})}}function $g(e,t,n){const r=e.slice();return r[10]=t[n],r}function Ug(e){let t,n,i;function o(){return e[6](e[10])}function s(...t){return e[7](e[10],...t)}return{c(){t=p("span"),t.textContent="✕",A(t,"class","tab-close-icon svelte-wfmuj"),A(t,"role","button"),A(t,"tabindex","0")},m(e,r){u(e,t,r),n||(i=[v(t,"click",w(o)),v(t,"keydown",s)],n=!0)},p(t,n){e=t},d(e){e&&d(t),n=!1,r(i)}}}function Pg(e){let t,n,r,i,o,s,a,l,f,h,y=e[10].icon+"",w=e[10].label+"",b=e[10].isSearchTab&&Ug(e);function I(){return e[8](e[10])}return{c(){t=p("button"),n=p("span"),r=g(y),i=m(),o=p("span"),s=g(w),a=m(),b&&b.c(),l=m(),A(n,"class","tab-icon svelte-wfmuj"),A(o,"class","tab-label svelte-wfmuj"),A(t,"class","tab svelte-wfmuj"),x(t,"active",e[2]===e[10].id)},m(e,d){u(e,t,d),c(t,n),c(n,r),c(t,i),c(t,o),c(o,s),c(t,a),b&&b.m(t,null),c(t,l),f||(h=v(t,"click",I),f=!0)},p(n,i){e=n,2&i&&y!==(y=e[10].icon+"")&&k(r,y),2&i&&w!==(w=e[10].label+"")&&k(s,w),e[10].isSearchTab?b?b.p(e,i):(b=Ug(e),b.c(),b.m(t,l)):b&&(b.d(1),b=null),6&i&&x(t,"active",e[2]===e[10].id)},d(e){e&&d(t),b&&b.d(),f=!1,h()}}}function Rg(e){let t,n,r,i,o,s,a,l;return{c(){t=p("a"),n=h("svg"),r=h("path"),i=h("path"),o=m(),s=p("span"),a=g("v"),l=g(e[3]),A(r,"d","M5 6h12v2h1.5c1.38 0 2.5 1.12 2.5 2.5v1c0 1.38-1.12 2.5-2.5 2.5H17v1c0 1.66-1.34 3-3 3H8c-1.66 0-3-1.34-3-3V6zm12 6h1.5c.28 0 .5-.22.5-.5v-1c0-.28-.22-.5-.5-.5H17v2z"),A(i,"d","M9 9c1.5 0 3 .5 3 2.5S10.5 14 9 14c0-1.5.5-3.5 2-4.5"),A(i,"stroke","currentColor"),A(i,"stroke-width","1"),A(i,"fill","none"),A(n,"class","version-icon svelte-wfmuj"),A(n,"viewBox","0 0 24 24"),A(n,"fill","currentColor"),A(n,"xmlns","http://www.w3.org/2000/svg"),A(s,"class","version-text svelte-wfmuj"),A(t,"href","https://next.orly.dev"),A(t,"target","_blank"),A(t,"rel","noopener noreferrer"),A(t,"class","version-link svelte-wfmuj")},m(e,d){u(e,t,d),c(t,n),c(n,r),c(n,i),c(t,o),c(t,s),c(s,a),c(s,l)},p(e,t){8&t&&k(l,e[3])},d(e){e&&d(t)}}}function Tg(t){let n,r,i,o,s=t[1],a=[];for(let e=0;e{"isDarkTheme"in e&&n(0,r=e.isDarkTheme),"tabs"in e&&n(1,i=e.tabs),"selectedTab"in e&&n(2,o=e.selectedTab),"version"in e&&n(3,s=e.version)},[r,i,o,s,l,c,e=>c(e.id),(e,t)=>"Enter"===t.key&&c(e.id),e=>l(e.id)]}class Og extends ie{constructor(e){super(),re(this,e,Ng,Tg,o,{isDarkTheme:0,tabs:1,selectedTab:2,version:3})}}function Mg(t){let n,r,i,o,s,a;return{c(){n=p("div"),r=p("p"),r.textContent="Please log in to access export functionality.",i=m(),o=p("button"),o.textContent="Log In",A(r,"class","svelte-jzrdtj"),A(o,"class","login-btn svelte-jzrdtj"),A(n,"class","login-prompt svelte-jzrdtj")},m(e,l){u(e,n,l),c(n,r),c(n,i),c(n,o),s||(a=v(o,"click",t[5]),s=!0)},p:e,d(e){e&&d(n),s=!1,a()}}}function Lg(e){let t,n,r=e[0]&&_g(e),i=e[1]&&Hg(e);return{c(){r&&r.c(),t=m(),i&&i.c(),n=y()},m(e,o){r&&r.m(e,o),u(e,t,o),i&&i.m(e,o),u(e,n,o)},p(e,o){e[0]?r?r.p(e,o):(r=_g(e),r.c(),r.m(t.parentNode,t)):r&&(r.d(1),r=null),e[1]?i?i.p(e,o):(i=Hg(e),i.c(),i.m(n.parentNode,n)):i&&(i.d(1),i=null)},d(e){r&&r.d(e),e&&d(t),i&&i.d(e),e&&d(n)}}}function _g(t){let n,r,i,o,s,a,l,f;return{c(){n=p("div"),r=p("h3"),r.textContent="Export My Events",i=m(),o=p("p"),o.textContent="Download your personal events as a JSONL file.",s=m(),a=p("button"),a.textContent="📤 Export My Events",A(r,"class","svelte-jzrdtj"),A(o,"class","svelte-jzrdtj"),A(a,"class","export-btn svelte-jzrdtj"),A(n,"class","export-section svelte-jzrdtj")},m(e,d){u(e,n,d),c(n,r),c(n,i),c(n,o),c(n,s),c(n,a),l||(f=v(a,"click",t[3]),l=!0)},p:e,d(e){e&&d(n),l=!1,f()}}}function Hg(t){let n,r,i,o,s,a,l,f;return{c(){n=p("div"),r=p("h3"),r.textContent="Export All Events",i=m(),o=p("p"),o.textContent="Download the complete database as a JSONL file. This includes\n all events from all users.",s=m(),a=p("button"),a.textContent="📤 Export All Events",A(r,"class","svelte-jzrdtj"),A(o,"class","svelte-jzrdtj"),A(a,"class","export-btn svelte-jzrdtj"),A(n,"class","export-section svelte-jzrdtj")},m(e,d){u(e,n,d),c(n,r),c(n,i),c(n,o),c(n,s),c(n,a),l||(f=v(a,"click",t[4]),l=!0)},p:e,d(e){e&&d(n),l=!1,f()}}}function jg(t){let n;function r(e,t){return e[2]?Lg:Mg}let i=r(t),o=i(t);return{c(){o.c(),n=y()},m(e,t){o.m(e,t),u(e,n,t)},p(e,[t]){i===(i=r(e))&&o?o.p(e,t):(o.d(1),o=i(e),o&&(o.c(),o.m(n.parentNode,n)))},i:e,o:e,d(e){o.d(e),e&&d(n)}}}function Gg(e,t,n){let r,i,{isLoggedIn:o=!1}=t,{currentEffectiveRole:s=""}=t,{aclMode:a=""}=t;const l=$();return e.$$set=e=>{"isLoggedIn"in e&&n(0,o=e.isLoggedIn),"currentEffectiveRole"in e&&n(6,s=e.currentEffectiveRole),"aclMode"in e&&n(7,a=e.aclMode)},e.$$.update=()=>{129&e.$$.dirty&&n(2,r="none"===a||o),192&e.$$.dirty&&n(1,i="none"===a||"admin"===s||"owner"===s)},[o,i,r,function(){l("exportMyEvents")},function(){l("exportAllEvents")},function(){l("openLoginModal")},s,a]}class Jg extends ie{constructor(e){super(),re(this,e,Gg,jg,o,{isLoggedIn:0,currentEffectiveRole:6,aclMode:7})}}function Kg(t){let n,r,i,o,s,a,l,f;return{c(){n=p("div"),r=p("h3"),r.textContent="Import Events",i=m(),o=p("p"),o.textContent="Please log in to access import functionality.",s=m(),a=p("button"),a.textContent="Log In",A(r,"class","recovery-header svelte-nonyqh"),A(o,"class","recovery-description svelte-nonyqh"),A(a,"class","login-btn svelte-nonyqh"),A(n,"class","login-prompt svelte-nonyqh")},m(e,d){u(e,n,d),c(n,r),c(n,i),c(n,o),c(n,s),c(n,a),l||(f=v(a,"click",t[6]),l=!0)},p:e,d(e){e&&d(n),l=!1,f()}}}function Vg(t){let n;return{c(){n=p("div"),n.innerHTML=' \n Admin or owner permission required for import functionality.
',A(n,"class","permission-denied svelte-nonyqh")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function zg(e){let t,n,i,o,s,a,l,f,h,y,w,b,k,I,C=e[2]&&qg(e);return{c(){t=p("h3"),t.textContent="Import Events",n=m(),i=p("p"),i.textContent="Upload a JSONL file to import events into the database.",o=m(),s=p("div"),a=p("input"),l=m(),f=p("div"),h=p("button"),y=g("Import Events"),b=m(),C&&C.c(),A(t,"class","svelte-nonyqh"),A(i,"class","svelte-nonyqh"),A(a,"type","file"),A(a,"id","import-file"),A(a,"accept",".jsonl,.txt"),A(a,"class","svelte-nonyqh"),A(h,"class","import-btn svelte-nonyqh"),h.disabled=w=!e[1]||"Uploading..."===e[2],A(f,"class","import-row svelte-nonyqh"),A(s,"class","recovery-controls-card svelte-nonyqh")},m(r,d){u(r,t,d),u(r,n,d),u(r,i,d),u(r,o,d),u(r,s,d),c(s,a),c(s,l),c(s,f),c(f,h),c(h,y),c(f,b),C&&C.m(f,null),k||(I=[v(a,"change",e[4]),v(h,"click",e[5])],k=!0)},p(e,t){6&t&&w!==(w=!e[1]||"Uploading..."===e[2])&&(h.disabled=w),e[2]?C?C.p(e,t):(C=qg(e),C.c(),C.m(f,null)):C&&(C.d(1),C=null)},d(e){e&&d(t),e&&d(n),e&&d(i),e&&d(o),e&&d(s),C&&C.d(),k=!1,r(I)}}}function qg(e){let t,n;return{c(){t=p("span"),n=g(e[2]),A(t,"class","import-message svelte-nonyqh"),x(t,"uploading","Uploading..."===e[2]),x(t,"success","Upload complete"===e[2]),x(t,"error",e[2].startsWith("Import failed")||e[2].startsWith("Admin")||e[2].startsWith("Please"))},m(e,r){u(e,t,r),c(t,n)},p(e,r){4&r&&k(n,e[2]),4&r&&x(t,"uploading","Uploading..."===e[2]),4&r&&x(t,"success","Upload complete"===e[2]),4&r&&x(t,"error",e[2].startsWith("Import failed")||e[2].startsWith("Admin")||e[2].startsWith("Please"))},d(e){e&&d(t)}}}function Yg(t){let n;function r(e,t){return e[3]?zg:e[0]?Vg:Kg}let i=r(t),o=i(t);return{c(){n=p("div"),o.c(),A(n,"class","import-section svelte-nonyqh")},m(e,t){u(e,n,t),o.m(n,null)},p(e,[t]){i===(i=r(e))&&o?o.p(e,t):(o.d(1),o=i(e),o&&(o.c(),o.m(n,null)))},i:e,o:e,d(e){e&&d(n),o.d()}}}function Wg(e,t,n){let r,{isLoggedIn:i=!1}=t,{currentEffectiveRole:o=""}=t,{selectedFile:s=null}=t,{aclMode:a=""}=t,{importMessage:l=""}=t;const c=$();return e.$$set=e=>{"isLoggedIn"in e&&n(0,i=e.isLoggedIn),"currentEffectiveRole"in e&&n(7,o=e.currentEffectiveRole),"selectedFile"in e&&n(1,s=e.selectedFile),"aclMode"in e&&n(8,a=e.aclMode),"importMessage"in e&&n(2,l=e.importMessage)},e.$$.update=()=>{385&e.$$.dirty&&n(3,r="none"===a||i&&("admin"===o||"owner"===o))},[i,s,l,r,function(e){c("fileSelect",e)},function(){c("importEvents")},function(){c("openLoginModal")},o,a]}class Zg extends ie{constructor(e){super(),re(this,e,Wg,Yg,o,{isLoggedIn:0,currentEffectiveRole:7,selectedFile:1,aclMode:8,importMessage:2})}}const Xg={0:"Profile Metadata",1:"Text Note",2:"Recommend Relay",3:"Contacts",4:"Encrypted DM",5:"Delete Request",6:"Repost",7:"Reaction",8:"Badge Award",16:"Generic Repost",40:"Channel Creation",41:"Channel Metadata",42:"Channel Message",43:"Channel Hide Message",44:"Channel Mute User",1063:"File Metadata",1311:"Live Chat Message",1984:"Reporting",1985:"Label",9734:"Zap Request",9735:"Zap Receipt",1e4:"Mute List",10001:"Pin List",10002:"Relay List Metadata",10003:"Bookmark List",10004:"Communities List",10005:"Public Chats List",10006:"Blocked Relays List",10007:"Search Relays List",10009:"User Groups",10015:"Interests List",10030:"User Emoji List",13194:"Wallet Info",22242:"Client Auth",23194:"Wallet Request",23195:"Wallet Response",24133:"Nostr Connect",27235:"HTTP Auth",3e4:"Categorized People List",30001:"Categorized Bookmarks",30002:"Categorized Relay List",30003:"Bookmark Sets",30004:"Curation Sets",30005:"Video Sets",30008:"Profile Badges",30009:"Badge Definition",30015:"Interest Sets",30017:"Create/Update Stall",30018:"Create/Update Product",30019:"Marketplace UI/UX",30020:"Product Sold As Auction",30023:"Long-form Content",30024:"Draft Long-form Content",30030:"Emoji Sets",30063:"Release Artifact Sets",30078:"Application-specific Data",30311:"Live Event",30315:"User Statuses",30388:"Slide Set",30402:"Classified Listing",30403:"Draft Classified Listing",30617:"Repository Announcement",30618:"Repository State Announcement",30818:"Wiki Article",30819:"Redirects",31922:"Date-Based Calendar Event",31923:"Time-Based Calendar Event",31924:"Calendar",31925:"Calendar Event RSVP",31989:"Handler Recommendation",31990:"Handler Information",34550:"Community Definition",34551:"Community Post Approval"};function em(e,t=null){if(!e||"string"!=typeof e)return!1;return!!/^[0-9a-fA-F]+$/.test(e)&&(!t||e.length===t)}function tm(e){const t=new Date(1e3*e);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")}T${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`}function nm(e){return Math.floor(new Date(e).getTime()/1e3)}function rm(e,t,n){const r=e.slice();return r[62]=t[n],r[64]=n,r}function im(e,t,n){const r=e.slice();return r[65]=t[n],r}function om(e,t,n){const r=e.slice();return r[68]=t[n],r}function sm(e,t,n){const r=e.slice();return r[71]=t[n],r}function am(e,t,n){const r=e.slice();return r[71]=t[n].kind,r[74]=t[n].name,r}function lm(e){let t,n,r,i,o,s,a=e[20],l=[];for(let t=0;t0&&um(t),Ge=t[17]&&fm(t),Je=t[2].length>0&&pm(t),Ke=t[18]&&gm(t),Ve=t[3].length>0&&mm(t),ze=t[19]&&vm(t),qe=t[4].length>0&&wm(t),Ye=t[5]&&bm(t),We=t[6]&&km(t),Ze=t[8]&&Im(t);return{c(){n=p("div"),i=p("div"),o=p("div"),s=p("label"),s.textContent="Search Text (NIP-50)",a=m(),l=p("div"),f=p("input"),h=m(),y=p("label"),y.textContent="Event Kinds",w=m(),C=p("div"),E=p("button"),B=g(Le),S=g(" Select Kinds ("),Q=g(_e),F=g(" selected)"),D=m(),He&&He.c(),$=m(),je&&je.c(),U=m(),P=p("label"),P.textContent="Authors (Pubkeys)",R=m(),T=p("div"),N=p("div"),O=p("input"),M=m(),L=p("button"),L.textContent="Add",_=m(),Ge&&Ge.c(),H=m(),Je&&Je.c(),j=m(),G=p("label"),G.textContent="Event IDs",J=m(),K=p("div"),V=p("div"),z=p("input"),q=m(),Y=p("button"),Y.textContent="Add",W=m(),Ke&&Ke.c(),Z=m(),Ve&&Ve.c(),X=m(),ee=p("label"),ee.textContent="Tags (#e, #p, #a)",te=m(),ne=p("div"),re=p("div"),ie=p("span"),ie.textContent="#",oe=m(),se=p("input"),ae=m(),le=p("input"),ce=m(),ue=p("button"),ue.textContent="Add",de=m(),ze&&ze.c(),fe=m(),qe&&qe.c(),pe=m(),he=p("label"),he.textContent="Since",ge=m(),me=p("div"),ye=p("input"),ve=m(),Ye&&Ye.c(),we=m(),Ae=p("label"),Ae.textContent="Until",be=m(),ke=p("div"),Ie=p("input"),Ce=m(),We&&We.c(),Ee=m(),xe=p("label"),xe.textContent="Limit",Be=m(),Se=p("div"),Qe=p("input"),Fe=m(),Ze&&Ze.c(),De=m(),$e=p("div"),Ue=p("button"),Ue.textContent="🧹",Pe=m(),Re=p("div"),Te=m(),Ne=p("button"),Ne.textContent=">",A(s,"for","search-text"),A(s,"class","svelte-1a1v6k0"),A(f,"id","search-text"),A(f,"type","text"),A(f,"placeholder","Search events..."),A(f,"class","filter-input svelte-1a1v6k0"),A(l,"class","field-content svelte-1a1v6k0"),A(y,"class","svelte-1a1v6k0"),A(E,"class","picker-toggle-btn svelte-1a1v6k0"),A(C,"class","field-content svelte-1a1v6k0"),A(P,"class","svelte-1a1v6k0"),A(O,"type","text"),A(O,"placeholder","64 character hex pubkey..."),A(O,"class","filter-input svelte-1a1v6k0"),A(O,"maxlength","64"),A(L,"class","add-btn svelte-1a1v6k0"),A(N,"class","input-group svelte-1a1v6k0"),A(T,"class","field-content svelte-1a1v6k0"),A(G,"class","svelte-1a1v6k0"),A(z,"type","text"),A(z,"placeholder","64 character hex event ID..."),A(z,"class","filter-input svelte-1a1v6k0"),A(z,"maxlength","64"),A(Y,"class","add-btn svelte-1a1v6k0"),A(V,"class","input-group svelte-1a1v6k0"),A(K,"class","field-content svelte-1a1v6k0"),A(ee,"class","svelte-1a1v6k0"),A(ie,"class","hash-prefix svelte-1a1v6k0"),A(se,"type","text"),A(se,"placeholder","Tag"),A(se,"class","filter-input tag-name-input svelte-1a1v6k0"),A(se,"maxlength","1"),A(le,"type","text"),A(le,"placeholder","Value..."),A(le,"class","filter-input tag-value-input svelte-1a1v6k0"),A(ue,"class","add-btn svelte-1a1v6k0"),A(re,"class","tag-input-group svelte-1a1v6k0"),A(ne,"class","field-content svelte-1a1v6k0"),A(he,"for","since-timestamp"),A(he,"class","svelte-1a1v6k0"),A(ye,"id","since-timestamp"),A(ye,"type","datetime-local"),ye.value=t[32](),A(ye,"class","filter-input svelte-1a1v6k0"),A(me,"class","field-content timestamp-field svelte-1a1v6k0"),A(Ae,"for","until-timestamp"),A(Ae,"class","svelte-1a1v6k0"),A(Ie,"id","until-timestamp"),A(Ie,"type","datetime-local"),Ie.value=t[33](),A(Ie,"class","filter-input svelte-1a1v6k0"),A(ke,"class","field-content timestamp-field svelte-1a1v6k0"),A(xe,"for","limit"),A(xe,"class","svelte-1a1v6k0"),A(Qe,"id","limit"),A(Qe,"type","number"),A(Qe,"placeholder","Max events to return"),A(Qe,"class","filter-input svelte-1a1v6k0"),A(Qe,"min","1"),A(Se,"class","field-content svelte-1a1v6k0"),A(o,"class","filter-grid svelte-1a1v6k0"),A(i,"class","filter-content svelte-1a1v6k0"),A(Ue,"class","clear-all-btn svelte-1a1v6k0"),A(Ue,"title","Clear all filters"),A(Re,"class","spacer svelte-1a1v6k0"),A(Ne,"class","json-toggle-btn svelte-1a1v6k0"),A(Ne,"title","Edit filter JSON"),x(Ne,"active",t[8]),A($e,"class","clear-column svelte-1a1v6k0"),A(n,"class","filter-builder svelte-1a1v6k0")},m(e,r){u(e,n,r),c(n,i),c(i,o),c(o,s),c(o,a),c(o,l),c(l,f),I(f,t[0]),c(o,h),c(o,y),c(o,w),c(o,C),c(C,E),c(E,B),c(E,S),c(E,Q),c(E,F),c(C,D),He&&He.m(C,null),c(C,$),je&&je.m(C,null),c(o,U),c(o,P),c(o,R),c(o,T),c(T,N),c(N,O),I(O,t[13]),c(N,M),c(N,L),c(T,_),Ge&&Ge.m(T,null),c(T,H),Je&&Je.m(T,null),c(o,j),c(o,G),c(o,J),c(o,K),c(K,V),c(V,z),I(z,t[14]),c(V,q),c(V,Y),c(K,W),Ke&&Ke.m(K,null),c(K,Z),Ve&&Ve.m(K,null),c(o,X),c(o,ee),c(o,te),c(o,ne),c(ne,re),c(re,ie),c(re,oe),c(re,se),I(se,t[15]),c(re,ae),c(re,le),I(le,t[16]),c(re,ce),c(re,ue),c(ne,de),ze&&ze.m(ne,null),c(ne,fe),qe&&qe.m(ne,null),c(o,pe),c(o,he),c(o,ge),c(o,me),c(me,ye),c(me,ve),Ye&&Ye.m(me,null),c(o,we),c(o,Ae),c(o,be),c(o,ke),c(ke,Ie),c(ke,Ce),We&&We.m(ke,null),c(o,Ee),c(o,xe),c(o,Be),c(o,Se),c(Se,Qe),I(Qe,t[7]),c(o,Fe),Ze&&Ze.m(o,null),c(n,De),c(n,$e),c($e,Ue),c($e,Pe),c($e,Re),c($e,Te),c($e,Ne),Oe||(Me=[v(f,"input",t[38]),v(E,"click",t[39]),v(O,"input",t[43]),v(O,"keydown",t[44]),v(L,"click",t[25]),v(z,"input",t[46]),v(z,"keydown",t[47]),v(Y,"click",t[27]),v(se,"input",t[49]),v(le,"input",t[50]),v(le,"keydown",t[51]),v(ue,"click",t[29]),v(ye,"change",t[34]),v(Ie,"change",t[35]),v(Qe,"input",t[55]),v(Ue,"click",t[31]),v(Ne,"click",t[57])],Oe=!0)},p(e,t){1&t[0]&&f.value!==e[0]&&I(f,e[0]),4096&t[0]&&Le!==(Le=e[12]?"▼":"▶")&&k(B,Le),2&t[0]&&_e!==(_e=e[1].length+"")&&k(Q,_e),e[12]?He?He.p(e,t):(He=lm(e),He.c(),He.m(C,$)):He&&(He.d(1),He=null),e[1].length>0?je?je.p(e,t):(je=um(e),je.c(),je.m(C,null)):je&&(je.d(1),je=null),8192&t[0]&&O.value!==e[13]&&I(O,e[13]),e[17]?Ge?Ge.p(e,t):(Ge=fm(e),Ge.c(),Ge.m(T,H)):Ge&&(Ge.d(1),Ge=null),e[2].length>0?Je?Je.p(e,t):(Je=pm(e),Je.c(),Je.m(T,null)):Je&&(Je.d(1),Je=null),16384&t[0]&&z.value!==e[14]&&I(z,e[14]),e[18]?Ke?Ke.p(e,t):(Ke=gm(e),Ke.c(),Ke.m(K,Z)):Ke&&(Ke.d(1),Ke=null),e[3].length>0?Ve?Ve.p(e,t):(Ve=mm(e),Ve.c(),Ve.m(K,null)):Ve&&(Ve.d(1),Ve=null),32768&t[0]&&se.value!==e[15]&&I(se,e[15]),65536&t[0]&&le.value!==e[16]&&I(le,e[16]),e[19]?ze?ze.p(e,t):(ze=vm(e),ze.c(),ze.m(ne,fe)):ze&&(ze.d(1),ze=null),e[4].length>0?qe?qe.p(e,t):(qe=wm(e),qe.c(),qe.m(ne,null)):qe&&(qe.d(1),qe=null),e[5]?Ye?Ye.p(e,t):(Ye=bm(e),Ye.c(),Ye.m(me,null)):Ye&&(Ye.d(1),Ye=null),e[6]?We?We.p(e,t):(We=km(e),We.c(),We.m(ke,null)):We&&(We.d(1),We=null),128&t[0]&&b(Qe.value)!==e[7]&&I(Qe,e[7]),e[8]?Ze?Ze.p(e,t):(Ze=Im(e),Ze.c(),Ze.m(o,null)):Ze&&(Ze.d(1),Ze=null),256&t[0]&&x(Ne,"active",e[8])},i:e,o:e,d(e){e&&d(n),He&&He.d(),je&&je.d(),Ge&&Ge.d(),Je&&Je.d(),Ke&&Ke.d(),Ve&&Ve.d(),ze&&ze.d(),qe&&qe.d(),Ye&&Ye.d(),We&&We.d(),Ze&&Ze.d(),Oe=!1,r(Me)}}}function xm(e,t,n){let r,i;const o=$();let{searchText:s=""}=t,{selectedKinds:a=[]}=t,{pubkeys:l=[]}=t,{eventIds:c=[]}=t,{tags:u=[]}=t,{sinceTimestamp:d=null}=t,{untilTimestamp:f=null}=t,{limit:p=null}=t,{showJsonEditor:h=!1}=t,g="",m="",y=!1,v="",w="",A="",k="",I="",C="",E="",x="",B=null,S=!1;function Q(e){a.includes(e)?n(1,a=a.filter(t=>t!==e)):n(1,a=[...a,e].sort((e,t)=>e-t))}function F(e){n(1,a=a.filter(t=>t!==e))}function U(){const e=w.trim();e&&(em(e,64)?l.includes(e)?n(17,C="Pubkey already added"):(n(2,l=[...l,e]),n(13,w=""),n(17,C="")):n(17,C="Invalid pubkey: must be 64 character hex string"))}function P(e){n(2,l=l.filter(t=>t!==e))}function R(){const e=A.trim();e&&(em(e,64)?c.includes(e)?n(18,E="Event ID already added"):(n(3,c=[...c,e]),n(14,A=""),n(18,E="")):n(18,E="Invalid event ID: must be 64 character hex string"))}function T(e){n(3,c=c.filter(t=>t!==e))}function N(){const e=k.trim(),t=I.trim();e&&t&&(/^[a-zA-Z]$/.test(e)?u.some(n=>n.name===e&&n.value===t)?n(19,x="Tag already added"):(n(4,u=[...u,{name:e,value:t}]),n(15,k=""),n(16,I=""),n(19,x="")):n(19,x="Invalid tag name: must be single letter a-z or A-Z"))}function O(e){n(4,u=u.filter((t,n)=>n!==e))}function M(){o("apply",{searchText:s,selectedKinds:a,pubkeys:l,eventIds:c,tags:u,sinceTimestamp:d,untilTimestamp:f,limit:p})}D(()=>{B&&clearTimeout(B)});return e.$$set=e=>{"searchText"in e&&n(0,s=e.searchText),"selectedKinds"in e&&n(1,a=e.selectedKinds),"pubkeys"in e&&n(2,l=e.pubkeys),"eventIds"in e&&n(3,c=e.eventIds),"tags"in e&&n(4,u=e.tags),"sinceTimestamp"in e&&n(5,d=e.sinceTimestamp),"untilTimestamp"in e&&n(6,f=e.untilTimestamp),"limit"in e&&n(7,p=e.limit),"showJsonEditor"in e&&n(8,h=e.showJsonEditor)},e.$$.update=()=>{if(256&e.$$.dirty[0]&&h){const e=function(){const e={};return a.length>0&&(e.kinds=a),l.length>0&&(e.authors=l),c.length>0&&(e.ids=c),d&&(e.since=d),f&&(e.until=f),p&&(e.limit=p),s&&(e.search=s),u.forEach(t=>{const n=`#${t.name}`;e[n]||(e[n]=[]),e[n].push(t.value)}),e}();n(10,g=JSON.stringify(e,null,2))}255&e.$$.dirty[0]|32&e.$$.dirty[1]&&(S?(B&&clearTimeout(B),B=setTimeout(()=>{M()},1e3)):n(36,S=!0)),512&e.$$.dirty[0]|64&e.$$.dirty[1]&&n(20,i=r.filter(e=>e.kind.toString().includes(v)||e.name.toLowerCase().includes(v.toLowerCase())))},n(37,r=Object.entries(Xg).map(([e,t])=>({kind:parseInt(e),name:t})).sort((e,t)=>e.kind-t.kind)),[s,a,l,c,u,d,f,p,h,v,g,m,y,w,A,k,I,C,E,x,i,o,function(){try{const e=JSON.parse(g);n(11,m=""),n(1,a=e.kinds||[]),n(2,l=e.authors||[]),n(3,c=e.ids||[]),n(5,d=e.since||null),n(6,f=e.until||null),n(7,p=e.limit||null),n(0,s=e.search||""),n(4,u=[]),Object.keys(e).forEach(t=>{if(t.startsWith("#")&&2===t.length){const n=t.slice(1);(Array.isArray(e[t])?e[t]:[e[t]]).forEach(e=>{u.push({name:n,value:String(e)})})}}),n(4,u),B&&clearTimeout(B),M()}catch(e){n(11,m="Invalid JSON: "+e.message)}},Q,F,U,P,R,T,N,O,function(){n(0,s=""),n(1,a=[]),n(2,l=[]),n(3,c=[]),n(4,u=[]),n(5,d=null),n(6,f=null),n(7,p=null),o("clear")},function(){return d?tm(d):""},function(){return f?tm(f):""},function(e){const t=e.target.value;n(5,d=t?nm(t):null)},function(e){const t=e.target.value;n(6,f=t?nm(t):null)},S,r,function(){s=this.value,n(0,s)},()=>n(12,y=!y),function(){v=this.value,n(9,v)},e=>Q(e),e=>F(e),function(){w=this.value,n(13,w)},e=>"Enter"===e.key&&U(),e=>P(e),function(){A=this.value,n(14,A)},e=>"Enter"===e.key&&R(),e=>T(e),function(){k=this.value,n(15,k)},function(){I=this.value,n(16,I)},e=>"Enter"===e.key&&N(),e=>O(e),()=>n(5,d=null),()=>n(6,f=null),function(){p=b(this.value),n(7,p)},function(){g=this.value,n(10,g),n(8,h)},()=>o("toggleJson")]}class Bm extends ie{constructor(e){super(),re(this,e,xm,Em,o,{searchText:0,selectedKinds:1,pubkeys:2,eventIds:3,tags:4,sinceTimestamp:5,untilTimestamp:6,limit:7,showJsonEditor:8},null,[-1,-1,-1])}}function Sm(e,t,n){const r=e.slice();return r[28]=t[n],r}function Qm(e,t,n){const r=e.slice();return r[31]=t[n],r}function Fm(t){let n;return{c(){n=p("div"),n.innerHTML="❌ Read, write, admin, or owner permission required to view all\n events.
",A(n,"class","permission-denied svelte-5kb1ec")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function Dm(e){let t,n,r,i;function o(e,t){return e[4].length>0?Um:e[6]?void 0:$m}let s=o(e),a=s&&s(e),l=e[6]&&_m();return{c(){t=p("div"),a&&a.c(),n=m(),l&&l.c(),A(t,"class","events-view-content svelte-5kb1ec")},m(o,s){u(o,t,s),a&&a.m(t,null),c(t,n),l&&l.m(t,null),r||(i=v(t,"scroll",e[9]),r=!0)},p(e,r){s===(s=o(e))&&a?a.p(e,r):(a&&a.d(1),a=s&&s(e),a&&(a.c(),a.m(t,n))),e[6]?l||(l=_m(),l.c(),l.m(t,null)):l&&(l.d(1),l=null)},d(e){e&&d(t),a&&a.d(),l&&l.d(),r=!1,i()}}}function $m(t){let n;return{c(){n=p("div"),n.innerHTML="No events found.
",A(n,"class","no-events svelte-5kb1ec")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function Um(e){let t,n=e[4],r=[];for(let t=0;t0&&Tm(e);return{c(){t=p("div"),n=p("span"),n.textContent="🗑️ Delete Event",r=m(),i&&i.c(),A(n,"class","delete-event-label svelte-5kb1ec"),A(t,"class","delete-event-info svelte-5kb1ec")},m(e,o){u(e,t,o),c(t,n),c(t,r),i&&i.m(t,null)},p(e,n){e[28].tags&&e[28].tags.length>0?i?i.p(e,n):(i=Tm(e),i.c(),i.m(t,null)):i&&(i.d(1),i=null)},d(e){e&&d(t),i&&i.d()}}}function Tm(e){let t,n=e[28].tags.filter(Ym),r=[];for(let t=0;t👤',o=m(),s=p("div"),a=p("div"),l=g(T),f=m(),h=p("div"),y=p("span"),w=g(N),b=m(),I=p("span"),C=g(O),E=m(),B=p("div"),S=p("div"),Q=g(M),F=m(),j.c(),D=m(),G&&G.c(),$=m(),V&&V.c(),U=m(),A(i,"class","events-view-avatar svelte-5kb1ec"),A(a,"class","events-view-author svelte-5kb1ec"),A(y,"class","kind-number svelte-5kb1ec"),x(y,"delete-event",5===e[28].kind),A(I,"class","kind-name svelte-5kb1ec"),A(h,"class","events-view-kind svelte-5kb1ec"),A(s,"class","events-view-info svelte-5kb1ec"),A(S,"class","event-timestamp svelte-5kb1ec"),A(B,"class","events-view-content svelte-5kb1ec"),A(n,"class","events-view-row svelte-5kb1ec"),A(n,"role","button"),A(n,"tabindex","0"),A(t,"class","events-view-item svelte-5kb1ec"),x(t,"expanded",e[5].has(e[28].id))},m(e,r){u(e,t,r),c(t,n),c(n,i),c(n,o),c(n,s),c(s,a),c(a,l),c(s,f),c(s,h),c(h,y),c(y,w),c(h,b),c(h,I),c(I,C),c(n,E),c(n,B),c(B,S),c(S,Q),c(B,F),j.m(B,null),c(n,D),G&&G.m(n,null),c(t,$),V&&V.m(t,null),c(t,U),P||(R=[v(n,"click",J),v(n,"keydown",K)],P=!0)},p(r,i){e=r,16&i[0]&&T!==(T=Km(e[28].pubkey)+"")&&k(l,T),16&i[0]&&N!==(N=e[28].kind+"")&&k(w,N),16&i[0]&&x(y,"delete-event",5===e[28].kind),16&i[0]&&O!==(O=Vm(e[28].kind)+"")&&k(C,O),16&i[0]&&M!==(M=zm(e[28].created_at)+"")&&k(Q,M),H===(H=_(e))&&j?j.p(e,i):(j.d(1),j=H(e),j&&(j.c(),j.m(B,null))),5!==e[28].kind&&("admin"===e[2]||"owner"===e[2]||"write"===e[2]&&e[28].pubkey&&e[28].pubkey===e[3])?G?G.p(e,i):(G=Om(e),G.c(),G.m(n,null)):G&&(G.d(1),G=null),48&i[0]&&(L=e[5].has(e[28].id)),L?V?V.p(e,i):(V=Mm(e),V.c(),V.m(t,U)):V&&(V.d(1),V=null),48&i[0]&&x(t,"expanded",e[5].has(e[28].id))},d(e){e&&d(t),j.d(),G&&G.d(),V&&V.d(),P=!1,r(R)}}}function _m(e){let t;return{c(){t=p("div"),t.innerHTML='
\n Loading events...
',A(t,"class","loading-events svelte-5kb1ec")},m(e,n){u(e,t,n)},d(e){e&&d(t)}}}function Hm(e){let t,n,i,o,s,a,l,f,h,y,w,b,k,I,C,E,B,S,Q,F,D,$,U,P;function R(e,t){return e[6]?Gm:jm}i=new Bm({props:{showJsonEditor:e[8]}}),i.$on("apply",e[17]),i.$on("clear",e[18]),i.$on("toggleJson",e[16]);let T=R(e),N=T(e);return{c(){t=p("div"),n=p("div"),X(i.$$.fragment),o=m(),s=p("div"),a=p("div"),l=p("button"),l.innerHTML=' ',f=m(),h=p("div"),y=p("label"),w=p("input"),b=m(),k=p("span"),I=m(),C=p("span"),C.textContent="Only show my events",E=m(),B=p("div"),S=p("button"),Q=g("🔄 Load More"),F=m(),D=p("button"),N.c(),A(n,"class","filter-panel svelte-5kb1ec"),x(n,"open",e[7]),A(l,"class","filter-btn svelte-5kb1ec"),A(l,"title","Filter events"),x(l,"active",e[7]),A(w,"type","checkbox"),A(w,"class","svelte-5kb1ec"),A(k,"class","toggle-slider svelte-5kb1ec"),A(C,"class","toggle-label svelte-5kb1ec"),A(y,"class","toggle-container svelte-5kb1ec"),A(h,"class","events-view-toggle svelte-5kb1ec"),A(a,"class","events-view-left svelte-5kb1ec"),A(S,"class","refresh-btn svelte-5kb1ec"),S.disabled=e[6],A(D,"class","reload-btn svelte-5kb1ec"),D.disabled=e[6],A(B,"class","events-view-buttons svelte-5kb1ec"),A(s,"class","events-view-header svelte-5kb1ec"),A(t,"class","events-view-footer svelte-5kb1ec")},m(r,d){u(r,t,d),c(t,n),ee(i,n,null),c(t,o),c(t,s),c(s,a),c(a,l),c(a,f),c(a,h),c(h,y),c(y,w),w.checked=e[0],c(y,b),c(y,k),c(y,I),c(y,C),c(s,E),c(s,B),c(B,S),c(S,Q),c(B,F),c(B,D),N.m(D,null),$=!0,U||(P=[v(l,"click",e[15]),v(w,"change",e[23]),v(w,"change",e[24]),v(S,"click",e[25]),v(D,"click",e[26])],U=!0)},p(e,t){const r={};256&t[0]&&(r.showJsonEditor=e[8]),i.$set(r),(!$||128&t[0])&&x(n,"open",e[7]),(!$||128&t[0])&&x(l,"active",e[7]),1&t[0]&&(w.checked=e[0]),(!$||64&t[0])&&(S.disabled=e[6]),T!==(T=R(e))&&(N.d(1),N=T(e),N&&(N.c(),N.m(D,null))),(!$||64&t[0])&&(D.disabled=e[6])},i(e){$||(Y(i.$$.fragment,e),$=!0)},o(e){W(i.$$.fragment,e),$=!1},d(e){e&&d(t),te(i),N.d(),U=!1,r(P)}}}function jm(e){let t;return{c(){t=g("🔄")},m(e,n){u(e,t,n)},d(e){e&&d(t)}}}function Gm(e){let t;return{c(){t=p("div"),A(t,"class","spinner svelte-5kb1ec")},m(e,n){u(e,t,n)},d(e){e&&d(t)}}}function Jm(e){let t,n,r;function i(e,t){return!e[1]||"read"!==e[2]&&"write"!==e[2]&&"admin"!==e[2]&&"owner"!==e[2]?Fm:Dm}let o=i(e),s=o(e),a=e[1]&&("read"===e[2]||"write"===e[2]||"admin"===e[2]||"owner"===e[2])&&Hm(e);return{c(){t=p("div"),s.c(),n=m(),a&&a.c(),A(t,"class","events-view-container svelte-5kb1ec")},m(e,i){u(e,t,i),s.m(t,null),c(t,n),a&&a.m(t,null),r=!0},p(e,r){o===(o=i(e))&&s?s.p(e,r):(s.d(1),s=o(e),s&&(s.c(),s.m(t,n))),!e[1]||"read"!==e[2]&&"write"!==e[2]&&"admin"!==e[2]&&"owner"!==e[2]?a&&(z(),W(a,1,1,()=>{a=null}),q()):a?(a.p(e,r),6&r[0]&&Y(a,1)):(a=Hm(e),a.c(),Y(a,1),a.m(t,null))},i(e){r||(Y(a),r=!0)},o(e){W(a),r=!1},d(e){e&&d(t),s.d(),a&&a.d()}}}function Km(e){return e?e.slice(0,8)+"..."+e.slice(-8):""}function Vm(e){return{0:"Profile",1:"Text Note",2:"Recommend Relay",3:"Contacts",4:"Encrypted DM",5:"Delete",6:"Repost",7:"Reaction",8:"Badge Award",16:"Generic Repost",40:"Channel Creation",41:"Channel Metadata",42:"Channel Message",43:"Channel Hide Message",44:"Channel Mute User",1984:"Reporting",9734:"Zap Request",9735:"Zap",1e4:"Mute List",10001:"Pin List",10002:"Relay List",22242:"Client Auth",24133:"Nostr Connect",27235:"HTTP Auth",3e4:"Categorized People",30001:"Categorized Bookmarks",30008:"Profile Badges",30009:"Badge Definition",30017:"Create or update a stall",30018:"Create or update a product",30023:"Long-form Content",30024:"Draft Long-form Content",30078:"Application-specific Data",30311:"Live Event",30315:"User Statuses",30402:"Classified Listing",30403:"Draft Classified Listing",31922:"Date-Based Calendar Event",31923:"Time-Based Calendar Event",31924:"Calendar",31925:"Calendar Event RSVP",31989:"Handler recommendation",31990:"Handler information",34550:"Community Definition"}[e]||`Kind ${e}`}function zm(e){return new Date(1e3*e).toLocaleString()}function qm(e){return e?e.length>100?e.slice(0,100)+"...":e:""}const Ym=e=>"e"===e[0];function Wm(e,t,n){let{isLoggedIn:r=!1}=t,{userRole:i=""}=t,{userPubkey:o=""}=t,{filteredEvents:s=[]}=t,{expandedEvents:a=new Set}=t,{isLoadingEvents:l=!1}=t,{showOnlyMyEvents:c=!1}=t,{showFilterBuilder:u=!1}=t;const d=$();let f=!1;function p(e){d("toggleEventExpansion",e)}function h(e){d("deleteEvent",e)}function g(e,t){d("copyEventToClipboard",{event:e,e:t})}function m(){d("toggleChange")}function y(e,t){d("loadAllEvents",{refresh:e,authors:t})}return e.$$set=e=>{"isLoggedIn"in e&&n(1,r=e.isLoggedIn),"userRole"in e&&n(2,i=e.userRole),"userPubkey"in e&&n(3,o=e.userPubkey),"filteredEvents"in e&&n(4,s=e.filteredEvents),"expandedEvents"in e&&n(5,a=e.expandedEvents),"isLoadingEvents"in e&&n(6,l=e.isLoadingEvents),"showOnlyMyEvents"in e&&n(0,c=e.showOnlyMyEvents),"showFilterBuilder"in e&&n(7,u=e.showFilterBuilder)},[c,r,i,o,s,a,l,u,f,function(e){d("scroll",e)},p,h,g,m,y,function(){d("toggleFilterBuilder")},function(){n(8,f=!f)},function(e){d("filterApply",e.detail)},function(){d("filterClear")},e=>h(e.id),e=>p(e.id),(e,t)=>"Enter"===t.key&&p(e.id),(e,t)=>g(e,t),function(){c=this.checked,n(0,c)},()=>m(),()=>{y(!1,c&&o?[o]:null)},()=>{y(!0,c&&o?[o]:null)}]}class Zm extends ie{constructor(e){super(),re(this,e,Wm,Jm,o,{isLoggedIn:1,userRole:2,userPubkey:3,filteredEvents:4,expandedEvents:5,isLoadingEvents:6,showOnlyMyEvents:0,showFilterBuilder:7},null,[-1,-1])}}const Xm=[{kind:0,name:"Metadata",description:"User profile information (name, about, picture, nip05, etc.)",nip:"01",isReplaceable:!0,template:{kind:0,content:"",tags:[]}},{kind:1,name:"Short Text Note",description:"Short-form text post (like a tweet)",nip:"01",template:{kind:1,content:"",tags:[]}},{kind:2,name:"Recommend Relay",description:"Relay recommendation",nip:"01",deprecated:!0,template:{kind:2,content:"",tags:[]}},{kind:3,name:"Follows",description:"Following list with optional relay hints",nip:"02",isReplaceable:!0,template:{kind:3,content:"",tags:[]}},{kind:4,name:"Encrypted Direct Message",description:"Private message using NIP-04 encryption",nip:"04",deprecated:!0,template:{kind:4,content:"",tags:[]}},{kind:5,name:"Event Deletion Request",description:"Request to delete events",nip:"09",template:{kind:5,content:"",tags:[]}},{kind:6,name:"Repost",description:"Share/repost another text note",nip:"18",template:{kind:6,content:"",tags:[]}},{kind:7,name:"Reaction",description:"Like, emoji reaction to an event",nip:"25",template:{kind:7,content:"",tags:[]}},{kind:8,name:"Badge Award",description:"Award a badge to someone",nip:"58",template:{kind:8,content:"",tags:[]}},{kind:9,name:"Chat Message",description:"Chat message",nip:"C7",template:{kind:9,content:"",tags:[]}},{kind:10,name:"Group Chat Threaded Reply",description:"Threaded reply in group chat",nip:"29",deprecated:!0,template:{kind:10,content:"",tags:[]}},{kind:11,name:"Thread",description:"Thread event",nip:"7D",template:{kind:11,content:"",tags:[]}},{kind:12,name:"Group Thread Reply",description:"Reply in group thread",nip:"29",deprecated:!0,template:{kind:12,content:"",tags:[]}},{kind:13,name:"Seal",description:"Sealed/encrypted event wrapper",nip:"59",template:{kind:13,content:"",tags:[]}},{kind:14,name:"Direct Message",description:"Private direct message using NIP-17",nip:"17",template:{kind:14,content:"",tags:[]}},{kind:15,name:"File Message",description:"File message in DMs",nip:"17",template:{kind:15,content:"",tags:[]}},{kind:16,name:"Generic Repost",description:"Repost any event kind",nip:"18",template:{kind:16,content:"",tags:[]}},{kind:17,name:"Reaction to Website",description:"Reaction to a website URL",nip:"25",template:{kind:17,content:"",tags:[]}},{kind:20,name:"Picture",description:"Picture-first feed post",nip:"68",template:{kind:20,content:"",tags:[]}},{kind:21,name:"Video Event",description:"Horizontal video event",nip:"71",template:{kind:21,content:"",tags:[]}},{kind:22,name:"Short-form Video",description:"Short-form portrait video (like TikTok)",nip:"71",template:{kind:22,content:"",tags:[]}},{kind:40,name:"Channel Creation",description:"Create a public chat channel",nip:"28",template:{kind:40,content:"",tags:[]}},{kind:41,name:"Channel Metadata",description:"Set channel name, about, picture",nip:"28",template:{kind:41,content:"",tags:[]}},{kind:42,name:"Channel Message",description:"Post message in channel",nip:"28",template:{kind:42,content:"",tags:[]}},{kind:43,name:"Channel Hide Message",description:"Hide a message in channel",nip:"28",template:{kind:43,content:"",tags:[]}},{kind:44,name:"Channel Mute User",description:"Mute a user in channel",nip:"28",template:{kind:44,content:"",tags:[]}},{kind:62,name:"Request to Vanish",description:"Request permanent deletion of all user data",nip:"62",template:{kind:62,content:"",tags:[]}},{kind:64,name:"Chess (PGN)",description:"Chess game in PGN format",nip:"64",template:{kind:64,content:"",tags:[]}},{kind:443,name:"KeyPackage",description:"Marmot protocol key package",nip:null,spec:"Marmot",template:{kind:443,content:"",tags:[]}},{kind:444,name:"Welcome Message",description:"Marmot protocol welcome message",nip:null,spec:"Marmot",template:{kind:444,content:"",tags:[]}},{kind:445,name:"Group Event",description:"Marmot protocol group event",nip:null,spec:"Marmot",template:{kind:445,content:"",tags:[]}},{kind:818,name:"Merge Requests",description:"Git merge request",nip:"54",template:{kind:818,content:"",tags:[]}},{kind:1018,name:"Poll Response",description:"Response to a poll",nip:"88",template:{kind:1018,content:"",tags:[]}},{kind:1021,name:"Bid",description:"Auction bid",nip:"15",template:{kind:1021,content:"",tags:[]}},{kind:1022,name:"Bid Confirmation",description:"Confirmation of auction bid",nip:"15",template:{kind:1022,content:"",tags:[]}},{kind:1040,name:"OpenTimestamps",description:"OpenTimestamps attestation",nip:"03",template:{kind:1040,content:"",tags:[]}},{kind:1059,name:"Gift Wrap",description:"Encrypted gift-wrapped event",nip:"59",template:{kind:1059,content:"",tags:[]}},{kind:1060,name:"Gift Wrap (Kind 4)",description:"Gift wrap variant for NIP-04 compatibility",nip:"59",template:{kind:1060,content:"",tags:[]}},{kind:1063,name:"File Metadata",description:"Metadata for shared files",nip:"94",template:{kind:1063,content:"",tags:[]}},{kind:1068,name:"Poll",description:"Create a poll",nip:"88",template:{kind:1068,content:"",tags:[]}},{kind:1111,name:"Comment",description:"Comment on events or external content",nip:"22",template:{kind:1111,content:"",tags:[]}},{kind:1222,name:"Voice Message",description:"Voice message",nip:"A0",template:{kind:1222,content:"",tags:[]}},{kind:1244,name:"Voice Message Comment",description:"Comment on voice message",nip:"A0",template:{kind:1244,content:"",tags:[]}},{kind:1311,name:"Live Chat Message",description:"Message in live stream chat",nip:"53",template:{kind:1311,content:"",tags:[]}},{kind:1337,name:"Code Snippet",description:"Code snippet post",nip:"C0",template:{kind:1337,content:"",tags:[]}},{kind:1517,name:"Bitcoin Block",description:"Bitcoin block data",nip:null,spec:"Nostrocket",template:{kind:1517,content:"",tags:[]}},{kind:1617,name:"Patches",description:"Git patches",nip:"34",template:{kind:1617,content:"",tags:[]}},{kind:1618,name:"Pull Requests",description:"Git pull request",nip:"34",template:{kind:1618,content:"",tags:[]}},{kind:1619,name:"Pull Request Updates",description:"Updates to git pull request",nip:"34",template:{kind:1619,content:"",tags:[]}},{kind:1621,name:"Issues",description:"Git issues",nip:"34",template:{kind:1621,content:"",tags:[]}},{kind:1622,name:"Git Replies",description:"Replies on git objects",nip:"34",deprecated:!0,template:{kind:1622,content:"",tags:[]}},{kind:1630,name:"Status",description:"Git status",nip:"34",template:{kind:1630,content:"",tags:[]}},{kind:1631,name:"Status",description:"Git status",nip:"34",template:{kind:1631,content:"",tags:[]}},{kind:1632,name:"Status",description:"Git status",nip:"34",template:{kind:1632,content:"",tags:[]}},{kind:1633,name:"Status",description:"Git status",nip:"34",template:{kind:1633,content:"",tags:[]}},{kind:1808,name:"Live Stream",description:"Live streaming event",nip:null,spec:"zap.stream",template:{kind:1808,content:"",tags:[]}},{kind:1971,name:"Problem Tracker",description:"Problem tracking",nip:null,spec:"Nostrocket",template:{kind:1971,content:"",tags:[]}},{kind:1984,name:"Reporting",description:"Report content or users",nip:"56",template:{kind:1984,content:"",tags:[]}},{kind:1985,name:"Label",description:"Label/tag content with namespace",nip:"32",template:{kind:1985,content:"",tags:[]}},{kind:1986,name:"Relay Reviews",description:"Reviews of relays",nip:null,template:{kind:1986,content:"",tags:[]}},{kind:1987,name:"AI Embeddings",description:"AI embeddings/vector lists",nip:null,spec:"NKBIP-02",template:{kind:1987,content:"",tags:[]}},{kind:2003,name:"Torrent",description:"Torrent magnet link",nip:"35",template:{kind:2003,content:"",tags:[]}},{kind:2004,name:"Torrent Comment",description:"Comment on torrent",nip:"35",template:{kind:2004,content:"",tags:[]}},{kind:2022,name:"Coinjoin Pool",description:"Coinjoin coordination",nip:null,spec:"joinstr",template:{kind:2022,content:"",tags:[]}},{kind:4550,name:"Community Post Approval",description:"Approve post in community",nip:"72",template:{kind:4550,content:"",tags:[]}},{kind:5e3,name:"Job Request",description:"Data vending machine job request (start of range)",nip:"90",template:{kind:5e3,content:"",tags:[]}},{kind:6e3,name:"Job Result",description:"Data vending machine job result (start of range)",nip:"90",template:{kind:6e3,content:"",tags:[]}},{kind:7e3,name:"Job Feedback",description:"Feedback on job request/result",nip:"90",template:{kind:7e3,content:"",tags:[]}},{kind:7374,name:"Reserved Cashu Wallet Tokens",description:"Reserved Cashu wallet tokens",nip:"60",template:{kind:7374,content:"",tags:[]}},{kind:7375,name:"Cashu Wallet Tokens",description:"Cashu wallet tokens",nip:"60",template:{kind:7375,content:"",tags:[]}},{kind:7376,name:"Cashu Wallet History",description:"Cashu wallet transaction history",nip:"60",template:{kind:7376,content:"",tags:[]}},{kind:7516,name:"Geocache Log",description:"Geocaching log entry",nip:null,spec:"geocaching",template:{kind:7516,content:"",tags:[]}},{kind:7517,name:"Geocache Proof of Find",description:"Proof of geocache find",nip:null,spec:"geocaching",template:{kind:7517,content:"",tags:[]}},{kind:8e3,name:"Add User",description:"Add user to group",nip:"43",template:{kind:8e3,content:"",tags:[]}},{kind:8001,name:"Remove User",description:"Remove user from group",nip:"43",template:{kind:8001,content:"",tags:[]}},{kind:9e3,name:"Group Control Events",description:"Group control events (start of range)",nip:"29",template:{kind:9e3,content:"",tags:[]}},{kind:9041,name:"Zap Goal",description:"Fundraising goal for zaps",nip:"75",template:{kind:9041,content:"",tags:[]}},{kind:9321,name:"Nutzap",description:"Cashu nutzap",nip:"61",template:{kind:9321,content:"",tags:[]}},{kind:9467,name:"Tidal Login",description:"Tidal streaming login",nip:null,spec:"Tidal-nostr",template:{kind:9467,content:"",tags:[]}},{kind:9734,name:"Zap Request",description:"Request Lightning payment",nip:"57",template:{kind:9734,content:"",tags:[]}},{kind:9735,name:"Zap",description:"Lightning payment receipt",nip:"57",template:{kind:9735,content:"",tags:[]}},{kind:9802,name:"Highlights",description:"Highlighted text selection",nip:"84",template:{kind:9802,content:"",tags:[]}},{kind:1e4,name:"Mute List",description:"List of muted users/content",nip:"51",isReplaceable:!0,template:{kind:1e4,content:"",tags:[]}},{kind:10001,name:"Pin List",description:"Pinned events",nip:"51",isReplaceable:!0,template:{kind:10001,content:"",tags:[]}},{kind:10002,name:"Relay List Metadata",description:"User's preferred relays for read/write",nip:"65",isReplaceable:!0,template:{kind:10002,content:"",tags:[]}},{kind:10003,name:"Bookmark List",description:"Bookmarked events",nip:"51",isReplaceable:!0,template:{kind:10003,content:"",tags:[]}},{kind:10004,name:"Communities List",description:"Communities user belongs to",nip:"51",isReplaceable:!0,template:{kind:10004,content:"",tags:[]}},{kind:10005,name:"Public Chats List",description:"Public chats user is in",nip:"51",isReplaceable:!0,template:{kind:10005,content:"",tags:[]}},{kind:10006,name:"Blocked Relays List",description:"Relays user has blocked",nip:"51",isReplaceable:!0,template:{kind:10006,content:"",tags:[]}},{kind:10007,name:"Search Relays List",description:"Preferred search relays",nip:"51",isReplaceable:!0,template:{kind:10007,content:"",tags:[]}},{kind:10008,name:"Relay Group Configuration",description:"Relay group configuration",nip:null,isReplaceable:!0,template:{kind:10008,content:"",tags:[]}},{kind:10009,name:"User Groups",description:"Groups user belongs to",nip:"29",isReplaceable:!0,template:{kind:10009,content:"",tags:[]}},{kind:10012,name:"Favorite Relays List",description:"User's favorite relays",nip:"51",isReplaceable:!0,template:{kind:10012,content:"",tags:[]}},{kind:10013,name:"Private Event Relay List",description:"Relays for private events",nip:"37",isReplaceable:!0,template:{kind:10013,content:"",tags:[]}},{kind:10015,name:"Interests List",description:"User interests/topics",nip:"51",isReplaceable:!0,template:{kind:10015,content:"",tags:[]}},{kind:10019,name:"Nutzap Mint Recommendation",description:"Recommended Cashu mints for nutzaps",nip:"61",isReplaceable:!0,template:{kind:10019,content:"",tags:[]}},{kind:10020,name:"Media Follows",description:"Followed media accounts",nip:"51",isReplaceable:!0,template:{kind:10020,content:"",tags:[]}},{kind:10030,name:"User Emoji List",description:"Custom emoji list",nip:"51",isReplaceable:!0,template:{kind:10030,content:"",tags:[]}},{kind:10050,name:"DM Relays List",description:"Relays to receive DMs on",nip:"17",isReplaceable:!0,template:{kind:10050,content:"",tags:[]}},{kind:10051,name:"KeyPackage Relays List",description:"Marmot key package relays",nip:null,isReplaceable:!0,spec:"Marmot",template:{kind:10051,content:"",tags:[]}},{kind:10063,name:"User Server List",description:"Blossom server list",nip:null,isReplaceable:!0,spec:"Blossom",template:{kind:10063,content:"",tags:[]}},{kind:10096,name:"File Storage Server List",description:"File storage servers",nip:"96",isReplaceable:!0,deprecated:!0,template:{kind:10096,content:"",tags:[]}},{kind:10166,name:"Relay Monitor Announcement",description:"Relay monitoring announcement",nip:"66",isReplaceable:!0,template:{kind:10166,content:"",tags:[]}},{kind:10312,name:"Room Presence",description:"Presence in live room",nip:"53",isReplaceable:!0,template:{kind:10312,content:"",tags:[]}},{kind:10377,name:"Proxy Announcement",description:"Nostr proxy announcement",nip:null,isReplaceable:!0,spec:"Nostr Epoxy",template:{kind:10377,content:"",tags:[]}},{kind:11111,name:"Transport Method Announcement",description:"Transport method announcement",nip:null,isReplaceable:!0,spec:"Nostr Epoxy",template:{kind:11111,content:"",tags:[]}},{kind:12345,name:"Relay Policy Configuration",description:"Relay-internal policy configuration (admin only)",nip:null,isReplaceable:!0,spec:"orly",template:{kind:12345,content:"",tags:[]}},{kind:13004,name:"JWT Binding",description:"Link between JWT certificate and pubkey",nip:null,isReplaceable:!0,template:{kind:13004,content:"",tags:[]}},{kind:13194,name:"Wallet Service Info",description:"NWC wallet service information",nip:"47",isReplaceable:!0,template:{kind:13194,content:"",tags:[]}},{kind:13534,name:"Membership Lists",description:"Group membership lists",nip:"43",isReplaceable:!0,template:{kind:13534,content:"",tags:[]}},{kind:14388,name:"User Sound Effect Lists",description:"Sound effect lists",nip:null,isReplaceable:!0,spec:"Corny Chat",template:{kind:14388,content:"",tags:[]}},{kind:17375,name:"Cashu Wallet Event",description:"Cashu wallet event",nip:"60",isReplaceable:!0,template:{kind:17375,content:"",tags:[]}},{kind:21e3,name:"Lightning Pub RPC",description:"Lightning.Pub RPC",nip:null,isEphemeral:!0,spec:"Lightning.Pub",template:{kind:21e3,content:"",tags:[]}},{kind:22242,name:"Client Authentication",description:"Authenticate to relay",nip:"42",isEphemeral:!0,template:{kind:22242,content:"",tags:[]}},{kind:23194,name:"Wallet Request",description:"NWC wallet request",nip:"47",isEphemeral:!0,template:{kind:23194,content:"",tags:[]}},{kind:23195,name:"Wallet Response",description:"NWC wallet response",nip:"47",isEphemeral:!0,template:{kind:23195,content:"",tags:[]}},{kind:23196,name:"Wallet Notification (NIP-04)",description:"NWC wallet notification (NIP-04 encrypted)",nip:"47",isEphemeral:!0,template:{kind:23196,content:"",tags:[]}},{kind:23197,name:"Wallet Notification",description:"NWC wallet notification",nip:"47",isEphemeral:!0,template:{kind:23197,content:"",tags:[]}},{kind:24133,name:"Nostr Connect",description:"Remote signer connection",nip:"46",isEphemeral:!0,template:{kind:24133,content:"",tags:[]}},{kind:24242,name:"Blobs Stored on Mediaservers",description:"Blossom blob storage",nip:null,isEphemeral:!0,spec:"Blossom",template:{kind:24242,content:"",tags:[]}},{kind:27235,name:"HTTP Auth",description:"Authenticate HTTP requests",nip:"98",isEphemeral:!0,template:{kind:27235,content:"",tags:[]}},{kind:28934,name:"Join Request",description:"Request to join group",nip:"43",isEphemeral:!0,template:{kind:28934,content:"",tags:[]}},{kind:28935,name:"Invite Request",description:"Invite to group",nip:"43",isEphemeral:!0,template:{kind:28935,content:"",tags:[]}},{kind:28936,name:"Leave Request",description:"Leave group request",nip:"43",isEphemeral:!0,template:{kind:28936,content:"",tags:[]}},{kind:3e4,name:"Follow Sets",description:"Categorized people lists",nip:"51",isAddressable:!0,template:{kind:3e4,content:"",tags:[["d","identifier"]]}},{kind:30001,name:"Generic Lists",description:"Generic categorized lists",nip:"51",isAddressable:!0,deprecated:!0,template:{kind:30001,content:"",tags:[["d","identifier"]]}},{kind:30002,name:"Relay Sets",description:"Categorized relay lists",nip:"51",isAddressable:!0,template:{kind:30002,content:"",tags:[["d","identifier"]]}},{kind:30003,name:"Bookmark Sets",description:"Categorized bookmark lists",nip:"51",isAddressable:!0,template:{kind:30003,content:"",tags:[["d","identifier"]]}},{kind:30004,name:"Curation Sets",description:"Curated content sets",nip:"51",isAddressable:!0,template:{kind:30004,content:"",tags:[["d","identifier"]]}},{kind:30005,name:"Video Sets",description:"Video playlists",nip:"51",isAddressable:!0,template:{kind:30005,content:"",tags:[["d","identifier"]]}},{kind:30007,name:"Kind Mute Sets",description:"Muted event kinds",nip:"51",isAddressable:!0,template:{kind:30007,content:"",tags:[["d","identifier"]]}},{kind:30008,name:"Profile Badges",description:"Badges displayed on profile",nip:"58",isAddressable:!0,template:{kind:30008,content:"",tags:[["d","identifier"]]}},{kind:30009,name:"Badge Definition",description:"Define a badge/achievement",nip:"58",isAddressable:!0,template:{kind:30009,content:"",tags:[["d","identifier"]]}},{kind:30015,name:"Interest Sets",description:"Interest/topic sets",nip:"51",isAddressable:!0,template:{kind:30015,content:"",tags:[["d","identifier"]]}},{kind:30017,name:"Stall",description:"Marketplace stall definition",nip:"15",isAddressable:!0,template:{kind:30017,content:"",tags:[["d","identifier"]]}},{kind:30018,name:"Product",description:"Marketplace product listing",nip:"15",isAddressable:!0,template:{kind:30018,content:"",tags:[["d","identifier"]]}},{kind:30019,name:"Marketplace UI/UX",description:"Marketplace interface settings",nip:"15",isAddressable:!0,template:{kind:30019,content:"",tags:[["d","identifier"]]}},{kind:30020,name:"Product Sold as Auction",description:"Auction product listing",nip:"15",isAddressable:!0,template:{kind:30020,content:"",tags:[["d","identifier"]]}},{kind:30023,name:"Long-form Content",description:"Blog post, article in markdown",nip:"23",isAddressable:!0,template:{kind:30023,content:"",tags:[["d","identifier"]]}},{kind:30024,name:"Draft Long-form Content",description:"Draft article",nip:"23",isAddressable:!0,template:{kind:30024,content:"",tags:[["d","identifier"]]}},{kind:30030,name:"Emoji Sets",description:"Custom emoji sets",nip:"51",isAddressable:!0,template:{kind:30030,content:"",tags:[["d","identifier"]]}},{kind:30040,name:"Curated Publication Index",description:"Publication index",nip:null,isAddressable:!0,spec:"NKBIP-01",template:{kind:30040,content:"",tags:[["d","identifier"]]}},{kind:30041,name:"Curated Publication Content",description:"Publication content",nip:null,isAddressable:!0,spec:"NKBIP-01",template:{kind:30041,content:"",tags:[["d","identifier"]]}},{kind:30063,name:"Release Artifact Sets",description:"Software release artifacts",nip:"51",isAddressable:!0,template:{kind:30063,content:"",tags:[["d","identifier"]]}},{kind:30078,name:"Application-specific Data",description:"App-specific key-value storage",nip:"78",isAddressable:!0,template:{kind:30078,content:"",tags:[["d","identifier"]]}},{kind:30166,name:"Relay Discovery",description:"Relay discovery/monitoring",nip:"66",isAddressable:!0,template:{kind:30166,content:"",tags:[["d","identifier"]]}},{kind:30267,name:"App Curation Sets",description:"Curated app sets",nip:"51",isAddressable:!0,template:{kind:30267,content:"",tags:[["d","identifier"]]}},{kind:30311,name:"Live Event",description:"Live streaming event",nip:"53",isAddressable:!0,template:{kind:30311,content:"",tags:[["d","identifier"]]}},{kind:30312,name:"Interactive Room",description:"Interactive live room",nip:"53",isAddressable:!0,template:{kind:30312,content:"",tags:[["d","identifier"]]}},{kind:30313,name:"Conference Event",description:"Conference/meetup event",nip:"53",isAddressable:!0,template:{kind:30313,content:"",tags:[["d","identifier"]]}},{kind:30315,name:"User Statuses",description:"User status updates",nip:"38",isAddressable:!0,template:{kind:30315,content:"",tags:[["d","identifier"]]}},{kind:30388,name:"Slide Set",description:"Presentation slides",nip:null,isAddressable:!0,spec:"Corny Chat",template:{kind:30388,content:"",tags:[["d","identifier"]]}},{kind:30402,name:"Classified Listing",description:"Classified ad listing",nip:"99",isAddressable:!0,template:{kind:30402,content:"",tags:[["d","identifier"]]}},{kind:30403,name:"Draft Classified Listing",description:"Draft classified ad",nip:"99",isAddressable:!0,template:{kind:30403,content:"",tags:[["d","identifier"]]}},{kind:30617,name:"Repository Announcements",description:"Git repository announcement",nip:"34",isAddressable:!0,template:{kind:30617,content:"",tags:[["d","identifier"]]}},{kind:30618,name:"Repository State Announcements",description:"Git repository state",nip:"34",isAddressable:!0,template:{kind:30618,content:"",tags:[["d","identifier"]]}},{kind:30818,name:"Wiki Article",description:"Wiki article",nip:"54",isAddressable:!0,template:{kind:30818,content:"",tags:[["d","identifier"]]}},{kind:30819,name:"Redirects",description:"URL redirects",nip:"54",isAddressable:!0,template:{kind:30819,content:"",tags:[["d","identifier"]]}},{kind:31234,name:"Draft Event",description:"Draft of any event",nip:"37",isAddressable:!0,template:{kind:31234,content:"",tags:[["d","identifier"]]}},{kind:31388,name:"Link Set",description:"Link collection",nip:null,isAddressable:!0,spec:"Corny Chat",template:{kind:31388,content:"",tags:[["d","identifier"]]}},{kind:31890,name:"Feed",description:"Custom feed definition",nip:null,isAddressable:!0,spec:"NUD: Custom Feeds",template:{kind:31890,content:"",tags:[["d","identifier"]]}},{kind:31922,name:"Date-Based Calendar Event",description:"All-day calendar event",nip:"52",isAddressable:!0,template:{kind:31922,content:"",tags:[["d","identifier"]]}},{kind:31923,name:"Time-Based Calendar Event",description:"Calendar event with time",nip:"52",isAddressable:!0,template:{kind:31923,content:"",tags:[["d","identifier"]]}},{kind:31924,name:"Calendar",description:"Calendar definition",nip:"52",isAddressable:!0,template:{kind:31924,content:"",tags:[["d","identifier"]]}},{kind:31925,name:"Calendar Event RSVP",description:"RSVP to calendar event",nip:"52",isAddressable:!0,template:{kind:31925,content:"",tags:[["d","identifier"]]}},{kind:31989,name:"Handler Recommendation",description:"Recommended app for event kind",nip:"89",isAddressable:!0,template:{kind:31989,content:"",tags:[["d","identifier"]]}},{kind:31990,name:"Handler Information",description:"App handler declaration",nip:"89",isAddressable:!0,template:{kind:31990,content:"",tags:[["d","identifier"]]}},{kind:32123,name:"WaveLake Track",description:"WaveLake music track",nip:null,isAddressable:!0,spec:"WaveLake",template:{kind:32123,content:"",tags:[["d","identifier"]]}},{kind:32267,name:"Software Application",description:"Software application listing",nip:null,isAddressable:!0,template:{kind:32267,content:"",tags:[["d","identifier"]]}},{kind:32388,name:"User Room Favorites",description:"Favorite rooms",nip:null,isAddressable:!0,spec:"Corny Chat",template:{kind:32388,content:"",tags:[["d","identifier"]]}},{kind:33388,name:"High Scores",description:"Game high scores",nip:null,isAddressable:!0,spec:"Corny Chat",template:{kind:33388,content:"",tags:[["d","identifier"]]}},{kind:34235,name:"Video Event Horizontal",description:"Horizontal video event",nip:"71",isAddressable:!0,template:{kind:34235,content:"",tags:[["d","identifier"]]}},{kind:34236,name:"Video Event Vertical",description:"Vertical video event",nip:"71",isAddressable:!0,template:{kind:34236,content:"",tags:[["d","identifier"]]}},{kind:34388,name:"Sound Effects",description:"Sound effect definitions",nip:null,isAddressable:!0,spec:"Corny Chat",template:{kind:34388,content:"",tags:[["d","identifier"]]}},{kind:34550,name:"Community Definition",description:"Define a community",nip:"72",isAddressable:!0,template:{kind:34550,content:"",tags:[["d","identifier"]]}},{kind:37516,name:"Geocache Listing",description:"Geocache location listing",nip:null,isAddressable:!0,spec:"geocaching",template:{kind:37516,content:"",tags:[["d","identifier"]]}},{kind:38172,name:"Cashu Mint Announcement",description:"Cashu mint announcement",nip:"87",isAddressable:!0,template:{kind:38172,content:"",tags:[["d","identifier"]]}},{kind:38173,name:"Fedimint Announcement",description:"Fedimint announcement",nip:"87",isAddressable:!0,template:{kind:38173,content:"",tags:[["d","identifier"]]}},{kind:38383,name:"Peer-to-peer Order Events",description:"P2P trading orders",nip:"69",isAddressable:!0,template:{kind:38383,content:"",tags:[["d","identifier"]]}},{kind:39e3,name:"Group Metadata Events",description:"Group metadata (start of range)",nip:"29",isAddressable:!0,template:{kind:39e3,content:"",tags:[["d","identifier"]]}},{kind:39089,name:"Starter Packs",description:"Starter pack lists",nip:"51",isAddressable:!0,template:{kind:39089,content:"",tags:[["d","identifier"]]}},{kind:39092,name:"Media Starter Packs",description:"Media starter packs",nip:"51",isAddressable:!0,template:{kind:39092,content:"",tags:[["d","identifier"]]}},{kind:39701,name:"Web Bookmarks",description:"Web URL bookmarks",nip:"B0",isAddressable:!0,template:{kind:39701,content:"",tags:[["d","identifier"]]}},{kind:39998,name:"ACL Event",description:"Access control list event",nip:null,isAddressable:!0,template:{kind:39998,content:"",tags:[["d","identifier"]]}}];function ey(e,t=null){const n=function(e){return Xm.find(t=>t.kind===e)}(e);return n?{...n.template,created_at:Math.floor(Date.now()/1e3),pubkey:t||""}:{kind:e,content:"",tags:[],created_at:Math.floor(Date.now()/1e3),pubkey:t||""}}const ty=[{id:"all",name:"All Kinds",filter:()=>!0},{id:"regular",name:"Regular Events (0-9999)",filter:e=>e.kind<1e4&&!e.isReplaceable},{id:"replaceable",name:"Replaceable (10000-19999)",filter:e=>e.isReplaceable},{id:"ephemeral",name:"Ephemeral (20000-29999)",filter:e=>e.isEphemeral},{id:"addressable",name:"Addressable (30000-39999)",filter:e=>e.isAddressable},{id:"social",name:"Social",filter:e=>[0,1,3,6,7].includes(e.kind)},{id:"messaging",name:"Messaging",filter:e=>[4,9,10,11,12,14,15,40,41,42].includes(e.kind)},{id:"lists",name:"Lists",filter:e=>e.name.toLowerCase().includes("list")||e.name.toLowerCase().includes("set")},{id:"marketplace",name:"Marketplace",filter:e=>[30017,30018,30019,30020,1021,1022,30402,30403].includes(e.kind)},{id:"lightning",name:"Lightning/Zaps",filter:e=>[9734,9735,9041,9321,7374,7375,7376].includes(e.kind)},{id:"media",name:"Media",filter:e=>[20,21,22,1063,1222,1244].includes(e.kind)},{id:"git",name:"Git/Code",filter:e=>[818,1337,1617,1618,1619,1621,1622,30617,30618].includes(e.kind)},{id:"calendar",name:"Calendar",filter:e=>[31922,31923,31924,31925].includes(e.kind)},{id:"groups",name:"Groups",filter:e=>e.kind>=9e3&&e.kind<=9030||e.kind>=39e3&&e.kind<=39009}];function ny(e,t,n){const r=e.slice();return r[13]=t[n],r}function ry(e,t,n){const r=e.slice();return r[16]=t[n],r}function iy(e){let t,n,i,o,s,a,l,h,y,w,b,C,E,x,B,S,Q,F,D,$,U,P,R,T,N,O=e[3].length+"",M=1!==e[3].length?"s":"",L=ty,_=[];for(let t=0;t=2e4&&e.kind<3e4?"badge-ephemeral":"badge-regular"}function fy(e){return e.isAddressable?"Addressable":e.isReplaceable?"Replaceable":e.kind>=2e4&&e.kind<3e4?"Ephemeral":"Regular"}function py(e,t,n){let{isOpen:r=!1}=t,{userPubkey:i=""}=t;const o=$();let s="",a="all",l=Xm;function c(e){const t=ey(e.kind,i);o("select",{kind:e,template:t}),u()}function u(){n(0,r=!1),n(1,s=""),n(2,a="all"),o("close")}return e.$$set=e=>{"isOpen"in e&&n(0,r=e.isOpen),"userPubkey"in e&&n(8,i=e.userPubkey)},e.$$.update=()=>{if(6&e.$$.dirty){let e=Xm;const t=ty.find(e=>e.id===a);if(t&&(e=e.filter(t.filter)),s.trim()){const t=s.toLowerCase();e=e.filter(e=>e.name.toLowerCase().includes(t)||e.description.toLowerCase().includes(t)||e.kind.toString().includes(t)||e.nip&&e.nip.includes(t))}n(3,l=e)}},[r,s,a,l,c,u,function(e){"Escape"===e.key&&u()},function(e){e.target===e.currentTarget&&u()},i,function(){s=this.value,n(1,s)},e=>n(2,a=e.id),e=>c(e)]}class hy extends ie{constructor(e){super(),re(this,e,py,uy,o,{isOpen:0,userPubkey:8})}}function gy(e){let t,n,r,i,o,s,a,l,f,h;return{c(){t=p("div"),n=p("div"),r=p("span"),r.textContent="⚠",i=m(),o=p("span"),s=g(e[1]),a=m(),l=p("button"),l.textContent="×",A(r,"class","error-icon svelte-46pmgb"),A(o,"class","error-message svelte-46pmgb"),A(n,"class","error-content svelte-46pmgb"),A(l,"class","error-dismiss svelte-46pmgb"),A(t,"class","error-banner svelte-46pmgb")},m(d,p){u(d,t,p),c(t,n),c(n,r),c(n,i),c(n,o),c(o,s),c(t,a),c(t,l),f||(h=v(l,"click",e[10]),f=!0)},p(e,t){2&t&&k(s,e[1])},d(e){e&&d(t),f=!1,h()}}}function my(e){let t,n,i,o,s,a,l,f,h,g,y,w,b,k,C,E,x,B,S,Q=e[1]&&gy(e);function F(t){e[14](t)}let D={userPubkey:e[2]};return void 0!==e[3]&&(D.isOpen=e[3]),C=new hy({props:D}),R.push(()=>Z(C,"isOpen",F)),C.$on("select",e[8]),C.$on("close",e[9]),{c(){t=p("div"),n=p("div"),i=p("button"),i.textContent="Generate Template",o=m(),s=p("button"),s.textContent="Reformat",a=m(),l=p("button"),l.textContent="Sign",f=m(),h=p("button"),h.textContent="Publish",g=m(),Q&&Q.c(),y=m(),w=p("div"),b=p("textarea"),k=m(),X(C.$$.fragment),A(i,"class","compose-btn template-btn svelte-46pmgb"),A(s,"class","compose-btn reformat-btn svelte-46pmgb"),A(l,"class","compose-btn sign-btn svelte-46pmgb"),A(h,"class","compose-btn publish-btn svelte-46pmgb"),A(n,"class","compose-header svelte-46pmgb"),A(b,"class","compose-textarea svelte-46pmgb"),A(b,"placeholder","Enter your Nostr event JSON here, or click 'Generate Template' to start with a template..."),A(b,"spellcheck","false"),A(w,"class","compose-editor svelte-46pmgb"),A(t,"class","compose-view svelte-46pmgb")},m(r,d){u(r,t,d),c(t,n),c(n,i),c(n,o),c(n,s),c(n,a),c(n,l),c(n,f),c(n,h),c(t,g),Q&&Q.m(t,null),c(t,y),c(t,w),c(w,b),I(b,e[0]),u(r,k,d),ee(C,r,d),x=!0,B||(S=[v(i,"click",e[7]),v(s,"click",e[4]),v(l,"click",e[5]),v(h,"click",e[6]),v(b,"input",e[13])],B=!0)},p(e,[n]){e[1]?Q?Q.p(e,n):(Q=gy(e),Q.c(),Q.m(t,y)):Q&&(Q.d(1),Q=null),1&n&&I(b,e[0]);const r={};4&n&&(r.userPubkey=e[2]),!E&&8&n&&(E=!0,r.isOpen=e[3],_(()=>E=!1)),C.$set(r)},i(e){x||(Y(C.$$.fragment,e),x=!0)},o(e){W(C.$$.fragment,e),x=!1},d(e){e&&d(t),Q&&Q.d(),e&&d(k),te(C,e),B=!1,r(S)}}}function yy(e,t,n){let{composeEventJson:r=""}=t,{userPubkey:i=""}=t,{userRole:o=""}=t,{policyEnabled:s=!1}=t,{publishError:a=""}=t;const l=$();let c=!1;return e.$$set=e=>{"composeEventJson"in e&&n(0,r=e.composeEventJson),"userPubkey"in e&&n(2,i=e.userPubkey),"userRole"in e&&n(11,o=e.userRole),"policyEnabled"in e&&n(12,s=e.policyEnabled),"publishError"in e&&n(1,a=e.publishError)},[r,a,i,c,function(){l("reformatJson")},function(){l("signEvent")},function(){l("publishEvent")},function(){n(3,c=!0)},function(e){const{kind:t,template:i}=e.detail;n(0,r=JSON.stringify(i,null,2)),l("templateSelected",{kind:t,template:i})},function(){n(3,c=!1)},function(){n(1,a=""),l("clearError")},o,s,function(){r=this.value,n(0,r)},function(e){c=e,n(3,c)}]}class vy extends ie{constructor(e){super(),re(this,e,yy,my,o,{composeEventJson:0,userPubkey:2,userRole:11,policyEnabled:12,publishError:1})}}function wy(e,t,n){const r=e.slice();return r[23]=t[n],r}function Ay(t){let n,r,i,o,s,a;return{c(){n=p("div"),r=p("p"),r.textContent="Please log in to access sprocket management.",i=m(),o=p("button"),o.textContent="Log In",A(r,"class","svelte-fiaj1r"),A(o,"class","login-btn svelte-fiaj1r"),A(n,"class","login-prompt svelte-fiaj1r")},m(e,l){u(e,n,l),c(n,r),c(n,i),c(n,o),s||(a=v(o,"click",t[18]),s=!0)},p:e,d(e){e&&d(n),s=!1,a()}}}function by(e){let t,n,r,i,o,s,a,l,f,h=(e[2]||"none")+"";return{c(){t=p("div"),n=p("p"),n.textContent="❌ Owner permission required for sprocket management.",r=m(),i=p("p"),i.innerHTML='To enable sprocket functionality, set the ORLY_OWNERS environment variable with your npub when starting the relay.',o=m(),s=p("p"),a=g("Current user role: "),l=p("strong"),f=g(h),A(n,"class","svelte-fiaj1r"),A(i,"class","svelte-fiaj1r"),A(s,"class","svelte-fiaj1r"),A(t,"class","permission-denied svelte-fiaj1r")},m(e,d){u(e,t,d),c(t,n),c(t,r),c(t,i),c(t,o),c(t,s),c(s,a),c(s,l),c(l,f)},p(e,t){4&t&&h!==(h=(e[2]||"none")+"")&&k(f,h)},d(e){e&&d(t)}}}function ky(e){let t,n,i,o,s,a,l,h,y,w,b,C,E,B,S,Q,F,D,$,U,P,R,T,N,O,M,L,_,H,j,G,J,K,V,z,q,Y,W,Z,X,ee,te,ne,re,ie,oe,se,ae,le,ce,ue,de,fe,pe,he,ge,me=e[3]?.is_running?"🟢 Running":"🔴 Stopped",ye=e[3]?.script_exists?"✅ Exists":"❌ Not found",ve=e[3]?.pid&&Iy(e),we=e[6]&&Cy(e),Ae=e[8],be=[];for(let t=0;t{"isLoggedIn"in e&&n(1,r=e.isLoggedIn),"userRole"in e&&n(2,i=e.userRole),"sprocketStatus"in e&&n(3,o=e.sprocketStatus),"isLoadingSprocket"in e&&n(4,s=e.isLoadingSprocket),"sprocketUploadFile"in e&&n(5,a=e.sprocketUploadFile),"sprocketScript"in e&&n(0,l=e.sprocketScript),"sprocketMessage"in e&&n(6,c=e.sprocketMessage),"sprocketMessageType"in e&&n(7,u=e.sprocketMessageType),"sprocketVersions"in e&&n(8,d=e.sprocketVersions)},[l,r,i,o,s,a,c,u,d,function(){f("restartSprocket")},function(){f("deleteSprocket")},function(e){f("sprocketFileSelect",e)},function(){f("uploadSprocketScript")},function(){f("saveSprocket")},function(){f("loadSprocket")},function(){f("loadVersions")},p,h,function(){f("openLoginModal")},function(){l=this.value,n(0,l)},e=>p(e),e=>h(e.name)]}class Fy extends ie{constructor(e){super(),re(this,e,Qy,Sy,o,{isLoggedIn:1,userRole:2,sprocketStatus:3,isLoadingSprocket:4,sprocketUploadFile:5,sprocketScript:0,sprocketMessage:6,sprocketMessageType:7,sprocketVersions:8})}}function Dy(e,t,n){const r=e.slice();return r[26]=t[n],r}function $y(e,t,n){const r=e.slice();return r[29]=t[n],r}function Uy(e,t,n){const r=e.slice();return r[32]=t[n],r}function Py(t){let n,r,i,o,s,a;return{c(){n=p("div"),r=p("p"),r.textContent="Please log in to access policy configuration.",i=m(),o=p("button"),o.textContent="Log In",A(r,"class","svelte-gkxvxc"),A(o,"class","login-btn svelte-gkxvxc"),A(n,"class","login-prompt svelte-gkxvxc")},m(e,l){u(e,n,l),c(n,r),c(n,i),c(n,o),s||(a=v(o,"click",t[16]),s=!0)},p:e,d(e){e&&d(n),s=!1,a()}}}function Ry(e){let t,n,r,i,o,s,a,l,f,h=(e[3]||"none")+"";return{c(){t=p("div"),n=p("p"),n.textContent="Policy configuration requires owner or policy admin permissions.",r=m(),i=p("p"),i.innerHTML='To become a policy admin, ask an existing policy admin to add your pubkey\n to the policy_admins list.',o=m(),s=p("p"),a=g("Current user role: "),l=p("strong"),f=g(h),A(n,"class","svelte-gkxvxc"),A(i,"class","svelte-gkxvxc"),A(s,"class","svelte-gkxvxc"),A(t,"class","permission-denied svelte-gkxvxc")},m(e,d){u(e,t,d),c(t,n),c(t,r),c(t,i),c(t,o),c(t,s),c(s,a),c(s,l),c(l,f)},p(e,t){8&t[0]&&h!==(h=(e[3]||"none")+"")&&k(f,h)},d(e){e&&d(t)}}}function Ty(e){let t,n,i,o,s,a,l,f,h,y,w,b,C,E,B,S,Q,F,D,$,U,P,R,T,N,O,M,L,_,H,j,G,J,K,V,z,q,Y,W,Z,X,ee,te,ne,re,ie,oe,se,ae,le,ce,ue,de,fe,pe,he,ge,me,ye,ve,we,Ae,be,ke,Ie,Ce,Ee,xe,Be,Se,Qe,Fe,De,$e,Ue,Pe=e[5]?"Policy Enabled":"Policy Disabled",Re=e[10].length+"",Te=e[4]&&Ny(),Ne=e[9].length>0&&Oy(e),Oe=e[7]&&Ly(e);function Me(e,t){return 0===e[1].length?Hy:_y}let Le=Me(e),_e=Le(e);function He(e,t){return 0===e[10].length?Jy:Gy}let je=He(e),Ge=je(e);return{c(){t=p("div"),n=p("div"),i=p("h3"),i.textContent="Policy Editor",o=m(),s=p("div"),a=p("span"),l=g(Pe),f=m(),Te&&Te.c(),h=m(),y=p("div"),y.innerHTML='Edit the policy JSON below and click "Save & Publish" to update the relay's policy configuration.\n Changes are applied immediately after validation.
\n Policy updates are published as kind 12345 events and require policy admin permissions.
',w=m(),b=p("div"),C=p("textarea"),E=m(),Ne&&Ne.c(),B=m(),S=p("div"),Q=p("button"),F=g("Load Current"),D=m(),$=p("button"),U=g("Format JSON"),P=m(),R=p("button"),T=g("Validate"),N=m(),O=p("button"),M=g("Save & Publish"),L=m(),Oe&&Oe.c(),_=m(),H=p("div"),j=p("h3"),j.textContent="Policy Administrators",G=m(),J=p("div"),J.innerHTML='Policy admins can update the relay's policy configuration via kind 12345 events.\n Their follows get whitelisted if policy_follow_whitelist_enabled is true in the policy.
\n Note: Policy admins are separate from relay admins (ORLY_ADMINS).\n Changes here update the JSON editor - click "Save & Publish" to apply.
',K=m(),V=p("div"),_e.c(),z=m(),q=p("div"),Y=p("input"),W=m(),Z=p("button"),X=g("+ Add Admin"),te=m(),ne=p("div"),re=p("h3"),re.textContent="Policy Follow Whitelist",ie=m(),oe=p("div"),oe.innerHTML='Pubkeys followed by policy admins (kind 3 events).\n These get automatic read+write access when rules have write_allow_follows: true.
',se=m(),ae=p("div"),le=p("span"),ce=g(Re),ue=g(" pubkey(s) in whitelist"),de=m(),fe=p("button"),pe=g("🔄 Refresh Follows"),he=m(),ge=p("div"),Ge.c(),me=m(),ye=p("div"),ve=p("h3"),ve.textContent="Policy Reference",we=m(),Ae=p("div"),be=p("h4"),be.textContent="Structure Overview",ke=m(),Ie=p("ul"),Ie.innerHTML='kind.whitelist - Only allow these event kinds (takes precedence) \n kind.blacklist - Deny these event kinds (if no whitelist) \n global - Rules applied to all events \n rules - Per-kind rules (keyed by kind number as string) \n default_policy - "allow" or "deny" when no rules match \n policy_admins - Hex pubkeys that can update policy \n policy_follow_whitelist_enabled - Enable follow-based access ',Ce=m(),Ee=p("h4"),Ee.textContent="Rule Fields",xe=m(),Be=p("ul"),Be.innerHTML='description - Human-readable rule description \n write_allow / write_deny - Pubkey lists for write access \n read_allow / read_deny - Pubkey lists for read access \n write_allow_follows - Grant access to policy admin follows \n size_limit - Max total event size in bytes \n content_limit - Max content field size in bytes \n max_expiry - Max expiry offset in seconds \n max_age_of_event - Max age of created_at in seconds \n max_age_event_in_future - Max future offset in seconds \n must_have_tags - Required tag letters (e.g., ["d", "t"]) \n tag_validation - Regex patterns for tag values \n script - Path to external validation script ',Se=m(),Qe=p("h4"),Qe.textContent="Example Policy",Fe=m(),De=p("pre"),De.textContent=`${e[20]}`,A(i,"class","svelte-gkxvxc"),A(a,"class","status-badge svelte-gkxvxc"),x(a,"enabled",e[5]),A(s,"class","policy-status svelte-gkxvxc"),A(n,"class","policy-header svelte-gkxvxc"),A(y,"class","policy-info svelte-gkxvxc"),A(C,"class","policy-editor svelte-gkxvxc"),A(C,"placeholder","Loading policy configuration..."),C.disabled=e[6],A(C,"spellcheck","false"),A(b,"class","editor-container svelte-gkxvxc"),A(Q,"class","policy-btn load-btn svelte-gkxvxc"),Q.disabled=e[6],A($,"class","policy-btn format-btn svelte-gkxvxc"),$.disabled=e[6],A(R,"class","policy-btn validate-btn svelte-gkxvxc"),R.disabled=e[6],A(O,"class","policy-btn save-btn svelte-gkxvxc"),O.disabled=e[6],A(S,"class","policy-actions svelte-gkxvxc"),A(t,"class","policy-section svelte-gkxvxc"),A(J,"class","policy-info svelte-gkxvxc"),A(V,"class","admin-list svelte-gkxvxc"),A(Y,"type","text"),A(Y,"placeholder","npub or hex pubkey"),Y.disabled=e[6],A(Y,"class","svelte-gkxvxc"),A(Z,"class","policy-btn add-btn svelte-gkxvxc"),Z.disabled=ee=e[6]||!e[11].trim(),A(q,"class","add-admin svelte-gkxvxc"),A(H,"class","policy-section svelte-gkxvxc"),A(oe,"class","policy-info svelte-gkxvxc"),A(le,"class","follows-count svelte-gkxvxc"),A(fe,"class","policy-btn refresh-btn svelte-gkxvxc"),fe.disabled=e[6],A(ae,"class","follows-header svelte-gkxvxc"),A(ge,"class","follows-list svelte-gkxvxc"),A(ne,"class","policy-section svelte-gkxvxc"),A(be,"class","svelte-gkxvxc"),A(Ie,"class","field-list svelte-gkxvxc"),A(Ee,"class","svelte-gkxvxc"),A(Be,"class","field-list svelte-gkxvxc"),A(Qe,"class","svelte-gkxvxc"),A(De,"class","example-json svelte-gkxvxc"),A(Ae,"class","reference-content svelte-gkxvxc"),A(ye,"class","policy-section svelte-gkxvxc")},m(r,d){u(r,t,d),c(t,n),c(n,i),c(n,o),c(n,s),c(s,a),c(a,l),c(s,f),Te&&Te.m(s,null),c(t,h),c(t,y),c(t,w),c(t,b),c(b,C),I(C,e[0]),c(t,E),Ne&&Ne.m(t,null),c(t,B),c(t,S),c(S,Q),c(Q,F),c(S,D),c(S,$),c($,U),c(S,P),c(S,R),c(R,T),c(S,N),c(S,O),c(O,M),c(t,L),Oe&&Oe.m(t,null),u(r,_,d),u(r,H,d),c(H,j),c(H,G),c(H,J),c(H,K),c(H,V),_e.m(V,null),c(H,z),c(H,q),c(q,Y),I(Y,e[11]),c(q,W),c(q,Z),c(Z,X),u(r,te,d),u(r,ne,d),c(ne,re),c(ne,ie),c(ne,oe),c(ne,se),c(ne,ae),c(ae,le),c(le,ce),c(le,ue),c(ae,de),c(ae,fe),c(fe,pe),c(ne,he),c(ne,ge),Ge.m(ge,null),u(r,me,d),u(r,ye,d),c(ye,ve),c(ye,we),c(ye,Ae),c(Ae,be),c(Ae,ke),c(Ae,Ie),c(Ae,Ce),c(Ae,Ee),c(Ae,xe),c(Ae,Be),c(Ae,Se),c(Ae,Qe),c(Ae,Fe),c(Ae,De),$e||(Ue=[v(C,"input",e[21]),v(Q,"click",e[12]),v($,"click",e[15]),v(R,"click",e[13]),v(O,"click",e[14]),v(Y,"input",e[23]),v(Y,"keydown",e[24]),v(Z,"click",e[18]),v(fe,"click",e[17])],$e=!0)},p(e,n){32&n[0]&&Pe!==(Pe=e[5]?"Policy Enabled":"Policy Disabled")&&k(l,Pe),32&n[0]&&x(a,"enabled",e[5]),e[4]?Te||(Te=Ny(),Te.c(),Te.m(s,null)):Te&&(Te.d(1),Te=null),64&n[0]&&(C.disabled=e[6]),1&n[0]&&I(C,e[0]),e[9].length>0?Ne?Ne.p(e,n):(Ne=Oy(e),Ne.c(),Ne.m(t,B)):Ne&&(Ne.d(1),Ne=null),64&n[0]&&(Q.disabled=e[6]),64&n[0]&&($.disabled=e[6]),64&n[0]&&(R.disabled=e[6]),64&n[0]&&(O.disabled=e[6]),e[7]?Oe?Oe.p(e,n):(Oe=Ly(e),Oe.c(),Oe.m(t,null)):Oe&&(Oe.d(1),Oe=null),Le===(Le=Me(e))&&_e?_e.p(e,n):(_e.d(1),_e=Le(e),_e&&(_e.c(),_e.m(V,null))),64&n[0]&&(Y.disabled=e[6]),2048&n[0]&&Y.value!==e[11]&&I(Y,e[11]),2112&n[0]&&ee!==(ee=e[6]||!e[11].trim())&&(Z.disabled=ee),1024&n[0]&&Re!==(Re=e[10].length+"")&&k(ce,Re),64&n[0]&&(fe.disabled=e[6]),je===(je=He(e))&&Ge?Ge.p(e,n):(Ge.d(1),Ge=je(e),Ge&&(Ge.c(),Ge.m(ge,null)))},d(e){e&&d(t),Te&&Te.d(),Ne&&Ne.d(),Oe&&Oe.d(),e&&d(_),e&&d(H),_e.d(),e&&d(te),e&&d(ne),Ge.d(),e&&d(me),e&&d(ye),$e=!1,r(Ue)}}}function Ny(e){let t;return{c(){t=p("span"),t.textContent="Policy Admin",A(t,"class","admin-badge svelte-gkxvxc")},m(e,n){u(e,t,n)},d(e){e&&d(t)}}}function Oy(e){let t,n,r,i,o=e[9],s=[];for(let t=0;t{"isLoggedIn"in e&&n(2,r=e.isLoggedIn),"userRole"in e&&n(3,i=e.userRole),"isPolicyAdmin"in e&&n(4,o=e.isPolicyAdmin),"policyEnabled"in e&&n(5,s=e.policyEnabled),"policyJson"in e&&n(0,a=e.policyJson),"isLoadingPolicy"in e&&n(6,l=e.isLoadingPolicy),"policyMessage"in e&&n(7,c=e.policyMessage),"policyMessageType"in e&&n(8,u=e.policyMessageType),"validationErrors"in e&&n(9,d=e.validationErrors),"policyAdmins"in e&&n(1,f=e.policyAdmins),"policyFollows"in e&&n(10,p=e.policyFollows)},e.$$.update=()=>{if(1&e.$$.dirty[0])try{if(a){const e=JSON.parse(a);n(1,f=e.policy_admins||[])}}catch(e){}},[a,f,r,i,o,s,l,c,u,d,p,g,function(){h("loadPolicy")},function(){h("validatePolicy")},function(){h("savePolicy")},function(){h("formatJson")},function(){h("openLoginModal")},function(){h("refreshFollows")},m,y,'{\n "kind": {\n "whitelist": [0, 1, 3, 6, 7, 10002],\n "blacklist": []\n },\n "global": {\n "description": "Global rules applied to all events",\n "size_limit": 65536,\n "max_age_of_event": 86400,\n "max_age_event_in_future": 300\n },\n "rules": {\n "1": {\n "description": "Kind 1 (short text notes)",\n "content_limit": 8192,\n "write_allow_follows": true\n },\n "30023": {\n "description": "Long-form articles",\n "content_limit": 100000,\n "tag_validation": {\n "d": "^[a-z0-9-]{1,64}$",\n "t": "^[a-z0-9-]{1,32}$"\n }\n }\n },\n "default_policy": "allow",\n "policy_admins": [""],\n "policy_follow_whitelist_enabled": true\n}',function(){a=this.value,n(0,a)},e=>y(e),function(){g=this.value,n(11,g)},e=>"Enter"===e.key&&m()]}class qy extends ie{constructor(e){super(),re(this,e,zy,Vy,o,{isLoggedIn:2,userRole:3,isPolicyAdmin:4,policyEnabled:5,policyJson:0,isLoadingPolicy:6,policyMessage:7,policyMessageType:8,validationErrors:9,policyAdmins:1,policyFollows:10},null,[-1,-1])}}const{window:Yy}=l;function Wy(e,t,n){const r=e.slice();return r[57]=t[n],r}function Zy(e,t,n){const r=e.slice();return r[54]=t[n],r}function Xy(t){let n,r,i,o,s,a;return{c(){n=p("div"),r=p("p"),r.textContent="Please log in to view your Blossom storage.",i=m(),o=p("button"),o.textContent="Log In",A(r,"class","svelte-bz95vx"),A(o,"class","login-btn svelte-bz95vx"),A(n,"class","login-prompt svelte-bz95vx")},m(e,l){u(e,n,l),c(n,r),c(n,i),c(n,o),s||(a=v(o,"click",t[20]),s=!0)},p:e,d(e){e&&d(n),s=!1,a()}}}function ev(e){let t,n,r,i,o,s,a,l,f,h,y,w,b,I=e[0]||e[12]?"Loading...":"Refresh";function C(e,t){return e[13]?rv:e[10]?nv:tv}let E=C(e),x=E(e),B=e[14]&&!e[10]&&!e[13]&&ov(e),S=!e[10]&&!e[13]&&sv(e),Q=e[2]&&lv(e);function F(e,t){return e[10]&&!e[13]?uv:cv}let D=F(e),$=D(e);return{c(){t=p("div"),n=p("div"),x.c(),r=m(),i=p("div"),B&&B.c(),o=m(),s=p("button"),a=g(I),f=m(),S&&S.c(),h=m(),Q&&Q.c(),y=m(),$.c(),A(s,"class","refresh-btn svelte-bz95vx"),s.disabled=l=e[0]||e[12],A(i,"class","header-buttons svelte-bz95vx"),A(n,"class","header-section svelte-bz95vx"),A(t,"class","blossom-view svelte-bz95vx")},m(l,d){u(l,t,d),c(t,n),x.m(n,null),c(n,r),c(n,i),B&&B.m(i,null),c(i,o),c(i,s),c(s,a),c(t,f),S&&S.m(t,null),c(t,h),Q&&Q.m(t,null),c(t,y),$.m(t,null),w||(b=v(s,"click",e[30]),w=!0)},p(e,c){E===(E=C(e))&&x?x.p(e,c):(x.d(1),x=E(e),x&&(x.c(),x.m(n,r))),!e[14]||e[10]||e[13]?B&&(B.d(1),B=null):B?B.p(e,c):(B=ov(e),B.c(),B.m(i,o)),4097&c[0]&&I!==(I=e[0]||e[12]?"Loading...":"Refresh")&&k(a,I),4097&c[0]&&l!==(l=e[0]||e[12])&&(s.disabled=l),e[10]||e[13]?S&&(S.d(1),S=null):S?S.p(e,c):(S=sv(e),S.c(),S.m(t,h)),e[2]?Q?Q.p(e,c):(Q=lv(e),Q.c(),Q.m(t,y)):Q&&(Q.d(1),Q=null),D===(D=F(e))&&$?$.p(e,c):($.d(1),$=D(e),$&&($.c(),$.m(t,null)))},d(e){e&&d(t),x.d(),B&&B.d(),S&&S.d(),Q&&Q.d(),$.d(),w=!1,b()}}}function tv(t){let n;return{c(){n=p("h3"),n.textContent="Blossom Media Storage",A(n,"class","svelte-bz95vx")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function nv(t){let n,r,i,o,s;return{c(){n=p("button"),n.textContent="← Back",r=m(),i=p("h3"),i.textContent="All Users Storage",A(n,"class","back-btn svelte-bz95vx"),A(i,"class","svelte-bz95vx")},m(e,a){u(e,n,a),u(e,r,a),u(e,i,a),o||(s=v(n,"click",t[27]),o=!0)},p:e,d(e){e&&d(n),e&&d(r),e&&d(i),o=!1,s()}}}function rv(e){let t,n,r,i,o,s,a,l=(e[13].profile?.name||Nv(e[25](e[13].pubkey)))+"",f=e[13].profile?.picture&&iv(e);return{c(){t=p("button"),t.textContent="← Back",n=m(),r=p("h3"),f&&f.c(),i=m(),o=g(l),A(t,"class","back-btn svelte-bz95vx"),A(r,"class","user-header svelte-bz95vx")},m(l,d){u(l,t,d),u(l,n,d),u(l,r,d),f&&f.m(r,null),c(r,i),c(r,o),s||(a=v(t,"click",e[29]),s=!0)},p(e,t){e[13].profile?.picture?f?f.p(e,t):(f=iv(e),f.c(),f.m(r,i)):f&&(f.d(1),f=null),8192&t[0]&&l!==(l=(e[13].profile?.name||Nv(e[25](e[13].pubkey)))+"")&&k(o,l)},d(e){e&&d(t),e&&d(n),e&&d(r),f&&f.d(),s=!1,a()}}}function iv(e){let t,n;return{c(){t=p("img"),a(t.src,n=e[13].profile.picture)||A(t,"src",n),A(t,"alt",""),A(t,"class","header-avatar svelte-bz95vx")},m(e,n){u(e,t,n)},p(e,r){8192&r[0]&&!a(t.src,n=e[13].profile.picture)&&A(t,"src",n)},d(e){e&&d(t)}}}function ov(e){let t,n,r,i;return{c(){t=p("button"),n=g("Admin"),A(t,"class","admin-btn svelte-bz95vx"),t.disabled=e[0]},m(o,s){u(o,t,s),c(t,n),r||(i=v(t,"click",e[26]),r=!0)},p(e,n){1&n[0]&&(t.disabled=e[0])},d(e){e&&d(t),r=!1,i()}}}function sv(e){let t,n,i,o,s,a,l,f,h=e[3].length>0&&av(e);return{c(){t=p("div"),n=p("input"),i=m(),o=p("button"),s=g("Select Files"),a=m(),h&&h.c(),A(n,"type","file"),n.multiple=!0,A(n,"class","file-input-hidden svelte-bz95vx"),A(o,"class","select-btn svelte-bz95vx"),o.disabled=e[4],A(t,"class","upload-section svelte-bz95vx")},m(r,d){u(r,t,d),c(t,n),e[39](n),c(t,i),c(t,o),c(o,s),c(t,a),h&&h.m(t,null),l||(f=[v(n,"change",e[22]),v(o,"click",e[23])],l=!0)},p(e,n){16&n[0]&&(o.disabled=e[4]),e[3].length>0?h?h.p(e,n):(h=av(e),h.c(),h.m(t,null)):h&&(h.d(1),h=null)},d(n){n&&d(t),e[39](null),h&&h.d(),l=!1,r(f)}}}function av(e){let t,n,r,i,o,s,a,l,f=e[3].length+"",h=(e[4]?e[5]:"Upload")+"";return{c(){t=p("span"),n=g(f),r=g(" file(s) selected"),i=m(),o=p("button"),s=g(h),A(t,"class","selected-count svelte-bz95vx"),A(o,"class","upload-btn svelte-bz95vx"),o.disabled=e[4]},m(d,f){u(d,t,f),c(t,n),c(t,r),u(d,i,f),u(d,o,f),c(o,s),a||(l=v(o,"click",e[24]),a=!0)},p(e,t){8&t[0]&&f!==(f=e[3].length+"")&&k(n,f),48&t[0]&&h!==(h=(e[4]?e[5]:"Upload")+"")&&k(s,h),16&t[0]&&(o.disabled=e[4])},d(e){e&&d(t),e&&d(i),e&&d(o),a=!1,l()}}}function lv(e){let t,n;return{c(){t=p("div"),n=g(e[2]),A(t,"class","error-message svelte-bz95vx")},m(e,r){u(e,t,r),c(t,n)},p(e,t){4&t[0]&&k(n,e[2])},d(e){e&&d(t)}}}function cv(e){let t,n,r;function i(e,r){return 1&r[0]&&(t=null),null==t&&(t=!(!e[0]||0!==e[31]().length)),t?pv:(null==n&&(n=!(0!==e[31]().length)),n?fv:dv)}let o=i(e,[-1,-1]),s=o(e);return{c(){s.c(),r=y()},m(e,t){s.m(e,t),u(e,r,t)},p(e,t){o===(o=i(e,t))&&s?s.p(e,t):(s.d(1),s=o(e),s&&(s.c(),s.m(r.parentNode,r)))},d(e){s.d(e),e&&d(r)}}}function uv(e){let t;function n(e,t){return e[12]?yv:0===e[11].length?mv:gv}let r=n(e),i=r(e);return{c(){i.c(),t=y()},m(e,n){i.m(e,n),u(e,t,n)},p(e,o){r===(r=n(e))&&i?i.p(e,o):(i.d(1),i=r(e),i&&(i.c(),i.m(t.parentNode,t)))},d(e){i.d(e),e&&d(t)}}}function dv(e){let t,n=e[31](),r=[];for(let t=0;tNo users have uploaded files yet.",A(n,"class","empty-state svelte-bz95vx")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function yv(t){let n;return{c(){n=p("div"),n.textContent="Loading user statistics...",A(n,"class","loading svelte-bz95vx")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function vv(t){let n;return{c(){n=p("div"),A(n,"class","user-avatar-placeholder svelte-bz95vx")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function wv(e){let t,n;return{c(){t=p("img"),a(t.src,n=e[54].profile.picture)||A(t,"src",n),A(t,"alt",""),A(t,"class","user-avatar svelte-bz95vx")},m(e,n){u(e,t,n)},p(e,r){2048&r[0]&&!a(t.src,n=e[54].profile.picture)&&A(t,"src",n)},d(e){e&&d(t)}}}function Av(e){let t,n,i,o,s,a,l,f,h,y,w,b,I,C,E,x,B,S,Q,F,D,$=(e[54].profile?.name||Nv(e[25](e[54].pubkey)))+"",U=Nv(e[25](e[54].pubkey))+"",P=e[54].blob_count+"",R=Dv(e[54].total_size_bytes)+"";function T(e,t){return e[54].profile?.picture?wv:vv}let N=T(e),O=N(e);function M(){return e[40](e[54])}function L(...t){return e[41](e[54],...t)}return{c(){t=p("div"),n=p("div"),O.c(),i=m(),o=p("div"),s=p("div"),a=g($),l=m(),f=p("div"),h=g(U),w=m(),b=p("div"),I=p("span"),C=g(P),E=g(" files"),x=m(),B=p("span"),S=g(R),Q=m(),A(n,"class","user-avatar-container svelte-bz95vx"),A(s,"class","user-name svelte-bz95vx"),A(f,"class","user-npub svelte-bz95vx"),A(f,"title",y=e[54].pubkey),A(o,"class","user-info svelte-bz95vx"),A(I,"class","blob-count svelte-bz95vx"),A(B,"class","total-size svelte-bz95vx"),A(b,"class","user-stats svelte-bz95vx"),A(t,"class","user-stat-item svelte-bz95vx"),A(t,"role","button"),A(t,"tabindex","0")},m(e,r){u(e,t,r),c(t,n),O.m(n,null),c(t,i),c(t,o),c(o,s),c(s,a),c(o,l),c(o,f),c(f,h),c(t,w),c(t,b),c(b,I),c(I,C),c(I,E),c(b,x),c(b,B),c(B,S),c(t,Q),F||(D=[v(t,"click",M),v(t,"keypress",L)],F=!0)},p(t,r){N===(N=T(e=t))&&O?O.p(e,r):(O.d(1),O=N(e),O&&(O.c(),O.m(n,null))),2048&r[0]&&$!==($=(e[54].profile?.name||Nv(e[25](e[54].pubkey)))+"")&&k(a,$),2048&r[0]&&U!==(U=Nv(e[25](e[54].pubkey))+"")&&k(h,U),2048&r[0]&&y!==(y=e[54].pubkey)&&A(f,"title",y),2048&r[0]&&P!==(P=e[54].blob_count+"")&&k(C,P),2048&r[0]&&R!==(R=Dv(e[54].total_size_bytes)+"")&&k(S,R)},d(e){e&&d(t),O.d(),F=!1,r(D)}}}function bv(e){let t,n,i,o,s,a,l,f,h,y,b,I,C,E,x,B,S,Q,F,D,$,U,P,R,T,N,O,M,L,_,H,j,G,J,K,V,z,q,Y,W,Z,X,ee,te=Uv(e[8].sha256)+"",ne=(e[8].type||"unknown")+"",re="image"===Pv(e[8].type),ie=Dv(e[8].size)+"",oe=$v(e[8].uploaded)+"",se=re&&kv(e);function ae(e,t){return 256&t[0]&&(B=null),256&t[0]&&(S=null),256&t[0]&&(Q=null),null==B&&(B=!("image"!==Pv(e[8].type))),B?xv:(null==S&&(S=!("video"!==Pv(e[8].type))),S?Ev:(null==Q&&(Q=!("audio"!==Pv(e[8].type))),Q?Cv:Iv))}let le=ae(e,[-1,-1]),ce=le(e);return{c(){t=p("div"),n=p("div"),i=p("div"),o=p("div"),s=p("span"),a=g(te),l=m(),f=p("span"),h=g(ne),y=m(),b=p("div"),se&&se.c(),I=m(),C=p("button"),C.textContent="X",E=m(),x=p("div"),ce.c(),F=m(),D=p("div"),$=p("div"),U=p("span"),P=g("Size: "),R=g(ie),T=m(),N=p("span"),O=g("Uploaded: "),M=g(oe),L=m(),_=p("div"),H=p("input"),G=m(),J=p("button"),J.textContent="Copy",K=m(),V=p("div"),z=p("a"),q=g("Open in New Tab"),W=m(),Z=p("button"),Z.textContent="Delete",A(s,"class","modal-hash svelte-bz95vx"),A(f,"class","modal-type svelte-bz95vx"),A(o,"class","modal-title svelte-bz95vx"),A(C,"class","close-btn svelte-bz95vx"),A(b,"class","modal-controls svelte-bz95vx"),A(i,"class","modal-header svelte-bz95vx"),A(x,"class","modal-body svelte-bz95vx"),A($,"class","blob-details svelte-bz95vx"),A(H,"type","text"),H.readOnly=!0,H.value=j=Tv(e[8]),A(H,"class","blob-url-input svelte-bz95vx"),A(J,"class","copy-btn svelte-bz95vx"),A(_,"class","blob-url-section svelte-bz95vx"),A(z,"href",Y=Tv(e[8])),A(z,"target","_blank"),A(z,"rel","noopener noreferrer"),A(z,"class","action-btn svelte-bz95vx"),A(Z,"class","action-btn danger svelte-bz95vx"),A(V,"class","modal-actions svelte-bz95vx"),A(D,"class","modal-footer svelte-bz95vx"),A(n,"class","modal-content svelte-bz95vx"),A(n,"role","dialog"),A(t,"class","modal-overlay svelte-bz95vx"),A(t,"role","button"),A(t,"tabindex","0")},m(r,d){u(r,t,d),c(t,n),c(n,i),c(i,o),c(o,s),c(s,a),c(o,l),c(o,f),c(f,h),c(i,y),c(i,b),se&&se.m(b,null),c(b,I),c(b,C),c(n,E),c(n,x),ce.m(x,null),c(n,F),c(n,D),c(D,$),c($,U),c(U,P),c(U,R),c($,T),c($,N),c(N,O),c(N,M),c(D,L),c(D,_),c(_,H),c(_,G),c(_,J),c(D,K),c(D,V),c(V,z),c(z,q),c(V,W),c(V,Z),X||(ee=[v(C,"click",e[16]),v(H,"click",Ov),v(J,"click",e[45]),v(Z,"click",e[46]),v(n,"click",w(e[37])),v(n,"keypress",w(e[38])),v(t,"click",e[16]),v(t,"keypress",e[47])],X=!0)},p(e,t){256&t[0]&&te!==(te=Uv(e[8].sha256)+"")&&k(a,te),256&t[0]&&ne!==(ne=(e[8].type||"unknown")+"")&&k(h,ne),256&t[0]&&(re="image"===Pv(e[8].type)),re?se?se.p(e,t):(se=kv(e),se.c(),se.m(b,I)):se&&(se.d(1),se=null),le===(le=ae(e,t))&&ce?ce.p(e,t):(ce.d(1),ce=le(e),ce&&(ce.c(),ce.m(x,null))),256&t[0]&&ie!==(ie=Dv(e[8].size)+"")&&k(R,ie),256&t[0]&&oe!==(oe=$v(e[8].uploaded)+"")&&k(M,oe),256&t[0]&&j!==(j=Tv(e[8]))&&H.value!==j&&(H.value=j),256&t[0]&&Y!==(Y=Tv(e[8]))&&A(z,"href",Y)},d(e){e&&d(t),se&&se.d(),ce.d(),X=!1,r(ee)}}}function kv(e){let t,n,i,o,s,a,l,f,h,y,w,b,I,C=Math.round(100*e[9])+"";return{c(){t=p("button"),n=g("-"),o=m(),s=p("span"),a=g(C),l=g("%"),f=m(),h=p("button"),y=g("+"),A(t,"class","zoom-btn svelte-bz95vx"),t.disabled=i=e[9]<=Sv,A(s,"class","zoom-level svelte-bz95vx"),A(h,"class","zoom-btn svelte-bz95vx"),h.disabled=w=e[9]>=Qv},m(r,i){u(r,t,i),c(t,n),u(r,o,i),u(r,s,i),c(s,a),c(s,l),u(r,f,i),u(r,h,i),c(h,y),b||(I=[v(t,"click",e[18]),v(h,"click",e[17])],b=!0)},p(e,n){512&n[0]&&i!==(i=e[9]<=Sv)&&(t.disabled=i),512&n[0]&&C!==(C=Math.round(100*e[9])+"")&&k(a,C),512&n[0]&&w!==(w=e[9]>=Qv)&&(h.disabled=w)},d(e){e&&d(t),e&&d(o),e&&d(s),e&&d(f),e&&d(h),b=!1,r(I)}}}function Iv(e){let t,n,r,i,o,s,a,l,f,h=Rv(e[8].type)+"";return{c(){t=p("div"),n=p("div"),r=g(h),i=m(),o=p("p"),o.textContent="Preview not available for this file type.",s=m(),a=p("a"),l=g("Download File"),A(n,"class","file-icon svelte-bz95vx"),A(a,"href",f=Tv(e[8])),A(a,"target","_blank"),A(a,"rel","noopener noreferrer"),A(a,"class","download-link svelte-bz95vx"),A(t,"class","file-preview svelte-bz95vx")},m(e,d){u(e,t,d),c(t,n),c(n,r),c(t,i),c(t,o),c(t,s),c(t,a),c(a,l)},p(e,t){256&t[0]&&h!==(h=Rv(e[8].type)+"")&&k(r,h),256&t[0]&&f!==(f=Tv(e[8]))&&A(a,"href",f)},d(e){e&&d(t)}}}function Cv(e){let t,n,r;return{c(){t=p("div"),n=p("audio"),n.controls=!0,a(n.src,r=Tv(e[8]))||A(n,"src",r),A(n,"class","svelte-bz95vx"),A(t,"class","media-container audio svelte-bz95vx")},m(e,r){u(e,t,r),c(t,n)},p(e,t){256&t[0]&&!a(n.src,r=Tv(e[8]))&&A(n,"src",r)},d(e){e&&d(t)}}}function Ev(e){let t,n,r,i;return{c(){t=p("div"),n=p("video"),r=p("track"),A(r,"kind","captions"),n.controls=!0,a(n.src,i=Tv(e[8]))||A(n,"src",i),A(n,"class","svelte-bz95vx"),A(t,"class","media-container svelte-bz95vx")},m(e,i){u(e,t,i),c(t,n),c(n,r)},p(e,t){256&t[0]&&!a(n.src,i=Tv(e[8]))&&A(n,"src",i)},d(e){e&&d(t)}}}function xv(e){let t,n,r;return{c(){t=p("div"),n=p("img"),a(n.src,r=Tv(e[8]))||A(n,"src",r),A(n,"alt","Blob content"),A(n,"class","svelte-bz95vx"),A(t,"class","media-container svelte-bz95vx"),C(t,"transform","scale("+e[9]+")")},m(e,r){u(e,t,r),c(t,n)},p(e,i){256&i[0]&&!a(n.src,r=Tv(e[8]))&&A(n,"src",r),512&i[0]&&C(t,"transform","scale("+e[9]+")")},d(e){e&&d(t)}}}function Bv(t){let n,r,i,o;function s(e,t){return e[1]?ev:Xy}let a=s(t),l=a(t),c=t[7]&&t[8]&&bv(t);return{c(){l.c(),n=m(),c&&c.c(),r=y()},m(e,s){l.m(e,s),u(e,n,s),c&&c.m(e,s),u(e,r,s),i||(o=v(Yy,"keydown",t[19]),i=!0)},p(e,t){a===(a=s(e))&&l?l.p(e,t):(l.d(1),l=a(e),l&&(l.c(),l.m(n.parentNode,n))),e[7]&&e[8]?c?c.p(e,t):(c=bv(e),c.c(),c.m(r.parentNode,r)):c&&(c.d(1),c=null)},i:e,o:e,d(e){l.d(e),e&&d(n),c&&c.d(e),e&&d(r),i=!1,o()}}}const Sv=.25,Qv=4;async function Fv(e,t,n=null){if(!e)return console.log("No signer available for Blossom auth"),null;try{const r=Math.floor(Date.now()/1e3),i=[["t",t],["expiration",(r+60).toString()]];n&&i.push(["x",n]);const o={kind:24242,created_at:r,tags:i,content:`Blossom ${t} operation`},s=await e.signEvent(o);return btoa(JSON.stringify(s))}catch(e){return console.error("Error creating Blossom auth:",e),null}}function Dv(e){if(!e)return"0 B";const t=["B","KB","MB","GB"];let n=0,r=e;for(;r>=1024&&ne.target.select();function Mv(e,t,n){let r,i,{isLoggedIn:o=!1}=t,{userPubkey:s=""}=t,{userSigner:a=null}=t,{currentEffectiveRole:l=""}=t;const c=$();let u,d=[],f=!1,p="",h=[],g=!1,m="",y=!1,v=null,w=1,A=!1,b=[],k=!1,I=null,C=[],E=!1;async function x(){if(s){n(0,f=!0),n(2,p="");try{const e=`${window.location.origin}/blossom/list/${s}`,t=await Fv(a,"list"),n=await fetch(e,{headers:t?{Authorization:`Nostr ${t}`}:{}});if(!n.ok)throw new Error(`Failed to load blobs: ${n.statusText}`);const r=await n.json();d=Array.isArray(r)?r:[],d.sort((e,t)=>(t.uploaded||0)-(e.uploaded||0)),console.log("Loaded blobs:",d)}catch(e){console.error("Error loading blobs:",e),n(2,p=e.message||"Failed to load blobs")}finally{n(0,f=!1)}}}function B(e){n(8,v=e),n(9,w=1),n(7,y=!0)}function S(){n(7,y=!1),n(8,v=null),n(9,w=1)}function Q(){wSv&&n(9,w=Math.max(Sv,w-.25))}async function P(e){if(confirm(`Delete blob ${Uv(e.sha256)}?`))try{const t=`${window.location.origin}/blossom/${e.sha256}`,n=await Fv(a,"delete",e.sha256),r=await fetch(t,{method:"DELETE",headers:n?{Authorization:`Nostr ${n}`}:{}});if(!r.ok)throw new Error(`Failed to delete: ${r.statusText}`);d=d.filter(t=>t.sha256!==e.sha256),v?.sha256===e.sha256&&S()}catch(e){console.error("Error deleting blob:",e),alert(`Failed to delete blob: ${e.message}`)}}async function T(){n(12,k=!0),n(2,p="");try{const e=`${window.location.origin}/blossom/admin/users`,t=await Fv(a,"admin"),r=await fetch(e,{headers:t?{Authorization:`Nostr ${t}`}:{}});if(!r.ok)throw new Error(`Failed to load user stats: ${r.statusText}`);n(11,b=await r.json());for(const e of b)Cp(e.pubkey).then(t=>{e.profile=t||{name:"",picture:""},n(11,b)}).catch(()=>{e.profile={name:"",picture:""}})}catch(e){console.error("Error fetching admin user stats:",e),n(2,p=e.message||"Failed to load user stats")}finally{n(12,k=!1)}}async function N(e){n(0,f=!0),n(2,p="");try{const t=`${window.location.origin}/blossom/list/${e}`,n=await Fv(a,"list"),r=await fetch(t,{headers:n?{Authorization:`Nostr ${n}`}:{}});if(!r.ok)throw new Error(`Failed to load user blobs: ${r.statusText}`);C=await r.json(),C.sort((e,t)=>(t.uploaded||0)-(e.uploaded||0))}catch(e){console.error("Error loading user blobs:",e),n(2,p=e.message||"Failed to load user blobs")}finally{n(0,f=!1)}}async function O(e){n(13,I={pubkey:e.pubkey,profile:e.profile}),await N(e.pubkey)}F(()=>{r&&!E&&(n(36,E=!0),x())});return e.$$set=e=>{"isLoggedIn"in e&&n(32,o=e.isLoggedIn),"userPubkey"in e&&n(33,s=e.userPubkey),"userSigner"in e&&n(34,a=e.userSigner),"currentEffectiveRole"in e&&n(35,l=e.currentEffectiveRole)},e.$$.update=()=>{6&e.$$.dirty[1]&&n(1,r=o&&s),16&e.$$.dirty[1]&&n(14,i="admin"===l||"owner"===l),3&e.$$.dirty[0]|32&e.$$.dirty[1]&&(!r||E||f||(n(36,E=!0),x()))},[f,r,p,h,g,m,u,y,v,w,A,b,k,I,i,B,S,Q,D,function(e){y&&("Escape"===e.key?S():"+"===e.key||"="===e.key?Q():"-"===e.key&&D())},function(){c("openLoginModal")},P,function(e){n(3,h=Array.from(e.target.files))},function(){u?.click()},async function(){if(0===h.length)return;n(4,g=!0),n(2,p="");const e=[],t=[];for(let r=0;r0&&await x(),t.length>0&&n(2,p=`Failed to upload: ${t.map(e=>e.name).join(", ")}`)},function(e){try{return vu(e)}catch(t){return Uv(e)}},function(){n(10,A=!0),T()},function(){n(10,A=!1),n(11,b=[]),n(13,I=null),C=[]},O,function(){n(13,I=null),C=[]},function(){I?N(I.pubkey):A?T():x()},function(){return I?C:d},o,s,a,l,E,function(t){U.call(this,e,t)},function(t){U.call(this,e,t)},function(e){R[e?"unshift":"push"](()=>{u=e,n(6,u)})},e=>O(e),(e,t)=>"Enter"===t.key&&O(e),e=>P(e),e=>B(e),(e,t)=>"Enter"===t.key&&B(e),()=>{navigator.clipboard.writeText(Tv(v))},()=>P(v),e=>"Enter"===e.key&&S()]}class Lv extends ie{constructor(e){super(),re(this,e,Mv,Bv,o,{isLoggedIn:32,userPubkey:33,userSigner:34,currentEffectiveRole:35},null,[-1,-1])}}function _v(e){let t,n,r,i,o,s,a,l,f,h,y;return{c(){t=p("div"),n=p("div"),r=p("h3"),r.textContent="Active Filter",i=m(),o=p("button"),o.textContent="🧹 Sweep",s=m(),a=p("div"),l=p("pre"),f=g(e[2]),A(r,"class","svelte-1tyqaa5"),A(o,"class","sweep-btn svelte-1tyqaa5"),A(o,"title","Clear filter"),A(n,"class","filter-display-header svelte-1tyqaa5"),A(l,"class","filter-json svelte-1tyqaa5"),A(a,"class","filter-json-container svelte-1tyqaa5"),A(t,"class","filter-display svelte-1tyqaa5")},m(d,p){u(d,t,p),c(t,n),c(n,r),c(n,i),c(n,o),c(t,s),c(t,a),c(a,l),c(l,f),h||(y=v(o,"click",e[3]),h=!0)},p(e,t){4&t&&k(f,e[2])},d(e){e&&d(t),h=!1,y()}}}function Hv(t){let n,r=t[0]&&t[1]&&_v(t);return{c(){r&&r.c(),n=y()},m(e,t){r&&r.m(e,t),u(e,n,t)},p(e,[t]){e[0]&&e[1]?r?r.p(e,t):(r=_v(e),r.c(),r.m(n.parentNode,n)):r&&(r.d(1),r=null)},i:e,o:e,d(e){r&&r.d(e),e&&d(n)}}}function jv(e,t,n){let r,i;const o=$();let{filter:s={}}=t,{showFilter:a=!0}=t;return e.$$set=e=>{"filter"in e&&n(4,s=e.filter),"showFilter"in e&&n(0,a=e.showFilter)},e.$$.update=()=>{16&e.$$.dirty&&n(2,r=function(e){return JSON.stringify(e,null,2)}(s)),16&e.$$.dirty&&n(1,i=Object.keys(s).length>0)},[a,i,r,function(){o("sweep")},s]}class Gv extends ie{constructor(e){super(),re(this,e,jv,Hv,o,{filter:4,showFilter:0})}}function Jv(e){return fp[e]||`Kind ${e}`}function Kv(e){return e?e.slice(0,8)+"..."+e.slice(-8):"unknown"}function Vv(e,t=100){return e?e.length>t?e.slice(0,t)+"...":e:""}function zv(e){return e?new Date(1e3*e).toLocaleString():""}class qv{constructor(e,t,n){this.relayUrl=e,this.userSigner=t,this.userPubkey=n,this.ws=null,this.challenge=null,this.isAuthenticated=!1,this.authPromise=null}async connect(){return new Promise((e,t)=>{this.ws=new WebSocket(this.relayUrl),this.ws.onopen=()=>{console.log("WebSocket connected to relay:",this.relayUrl),e()},this.ws.onmessage=async e=>{try{const t=JSON.parse(e.data);await this.handleMessage(t)}catch(e){console.error("Error parsing relay message:",e)}},this.ws.onerror=e=>{console.error("WebSocket error:",e),t(new Error("Failed to connect to relay"))},this.ws.onclose=()=>{console.log("WebSocket connection closed"),this.isAuthenticated=!1,this.challenge=null},setTimeout(()=>{this.ws.readyState!==WebSocket.OPEN&&t(new Error("Connection timeout"))},1e4)})}async handleMessage(e){const[t,...n]=e;switch(t){case"AUTH":this.challenge=n[0],console.log("Received AUTH challenge:",this.challenge),await this.authenticate();break;case"OK":const[e,r,i]=n;e&&r?(console.log("Authentication successful for event:",e),this.isAuthenticated=!0,this.authPromise&&(this.authPromise.resolve(),this.authPromise=null)):e&&!r&&(console.error("Authentication failed:",i),this.authPromise&&(this.authPromise.reject(new Error(i||"Authentication failed")),this.authPromise=null));break;case"NOTICE":console.log("Relay notice:",n[0]);break;default:console.log("Unhandled message type:",t,n)}}async authenticate(){if(!this.challenge)throw new Error("No challenge received from relay");if(!this.userSigner)throw new Error("No signer available for authentication");try{const e={kind:22242,created_at:Math.floor(Date.now()/1e3),tags:[["relay",this.relayUrl],["challenge",this.challenge]],content:"",pubkey:this.userPubkey},t=["AUTH",await this.userSigner.signEvent(e)];return this.ws.send(JSON.stringify(t)),console.log("Sent authentication event to relay"),new Promise((e,t)=>{this.authPromise={resolve:e,reject:t},setTimeout(()=>{this.authPromise&&(this.authPromise.reject(new Error("Authentication timeout")),this.authPromise=null)},1e4)})}catch(e){throw console.error("Authentication error:",e),e}}async publishEvent(e){if(!this.ws||this.ws.readyState!==WebSocket.OPEN)throw new Error("WebSocket not connected");return new Promise((t,n)=>{const r=["EVENT",e];this.ws.send(JSON.stringify(r));const i=this.ws.onmessage,o=setTimeout(()=>{this.ws.onmessage=i,n(new Error("Publish timeout"))},15e3);this.ws.onmessage=async r=>{try{const s=JSON.parse(r.data),[a,l,c,u]=s;if("OK"===a&&l===e.id)if(c)clearTimeout(o),this.ws.onmessage=i,console.log("Event published successfully:",l),t({success:!0,eventId:l,reason:u});else{if(console.error("Event publish failed:",u),u&&u.includes("auth-required"))return void console.log("Authentication required, waiting for AUTH challenge...");clearTimeout(o),this.ws.onmessage=i,n(new Error(`Publish failed: ${u}`))}else if("AUTH"===a){this.challenge=s[1],console.log("Received AUTH challenge during publish:",this.challenge);try{await this.authenticate(),console.log("Authentication successful, retrying event publish...");const t=["EVENT",e];this.ws.send(JSON.stringify(t))}catch(e){clearTimeout(o),this.ws.onmessage=i,n(new Error(`Authentication failed: ${e.message}`))}}else await this.handleMessage(s)}catch(e){clearTimeout(o),this.ws.onmessage=i,n(e)}}})}close(){this.ws&&(this.ws.close(),this.ws=null),this.isAuthenticated=!1,this.challenge=null}getAuthenticated(){return this.isAuthenticated}}async function Yv(e,t,n,r){const i=new qv(e,n,r);try{await i.connect();return await i.publishEvent(t)}finally{i.close()}}function Wv(e,t,n){const r=e.slice();return r[169]=t[n],r}function Zv(e,t,n){const r=e.slice();return r[179]=t[n],r}function Xv(e,t,n){const r=e.slice();return r[172]=t[n],r}function ew(e,t,n){const r=e.slice();r[172]=t[n];const i=r[52](r[172]);return r[173]=i,r}function tw(e,t,n){const r=e.slice();return r[176]=t[n],r}function nw(t){let n;function r(e,t){return e[1]?hw:pw}let i=r(t),o=i(t);return{c(){n=p("div"),o.c(),A(n,"class","welcome-message svelte-u3u5mw")},m(e,t){u(e,n,t),o.m(n,null)},p(e,t){i===(i=r(e))&&o?o.p(e,t):(o.d(1),o=i(e),o&&(o.c(),o.m(n,null)))},i:e,o:e,d(e){e&&d(n),o.d()}}}function rw(e){let t,n,r=e[6],i=[];for(let t=0;tW(i[e],1,1,()=>{i[e]=null});return{c(){for(let e=0;e=0||""!==t[36]&&parseInt(t[36])>=0,U=dp,P=[];for(let e=0;eEvent Recovery \n Search and recover old versions of replaceable events
',o=m(),s=p("div"),a=p("div"),l=p("div"),h=p("label"),h.textContent="Select Event Kind:",g=m(),y=p("select"),w=p("option"),w.textContent="Choose a replaceable kind...";for(let e=0;et[115].call(y)),A(l,"class","kind-selector svelte-u3u5mw"),A(x,"for","custom-kind"),A(x,"class","svelte-u3u5mw"),A(S,"id","custom-kind"),A(S,"type","number"),A(S,"placeholder","e.g., 10001"),A(S,"min","0"),A(S,"class","svelte-u3u5mw"),A(C,"class","custom-kind-input svelte-u3u5mw"),A(a,"class","recovery-controls svelte-u3u5mw"),A(s,"class","recovery-controls-card svelte-u3u5mw"),A(n,"class","recovery-tab svelte-u3u5mw")},m(e,r){u(e,n,r),c(n,i),c(n,o),c(n,s),c(s,a),c(a,l),c(l,h),c(l,g),c(l,y),c(y,w);for(let e=0;e=0||""!==e[36]&&parseInt(e[36])>=0),$?R?R.p(e,t):(R=Ew(e),R.c(),R.m(n,null)):R&&(R.d(1),R=null)},i:e,o:e,d(e){e&&d(n),f(P,e),R&&R.d(),F=!1,r(D)}}}function ow(e){let t,n,r;function i(t){e[114](t)}let o={isLoggedIn:e[1],userRole:e[4],isPolicyAdmin:qw,policyEnabled:e[8],isLoadingPolicy:e[27],policyMessage:e[28],policyMessageType:e[29],validationErrors:e[30],policyFollows:e[31]};return void 0!==e[26]&&(o.policyJson=e[26]),t=new qy({props:o}),R.push(()=>Z(t,"policyJson",i)),t.$on("loadPolicy",e[60]),t.$on("validatePolicy",e[61]),t.$on("savePolicy",e[62]),t.$on("formatJson",e[63]),t.$on("addPolicyAdmin",e[64]),t.$on("removePolicyAdmin",e[65]),t.$on("refreshFollows",e[66]),t.$on("openLoginModal",e[70]),{c(){X(t.$$.fragment)},m(e,n){ee(t,e,n),r=!0},p(e,r){const i={};2&r[0]&&(i.isLoggedIn=e[1]),16&r[0]&&(i.userRole=e[4]),256&r[0]&&(i.policyEnabled=e[8]),134217728&r[0]&&(i.isLoadingPolicy=e[27]),268435456&r[0]&&(i.policyMessage=e[28]),536870912&r[0]&&(i.policyMessageType=e[29]),1073741824&r[0]&&(i.validationErrors=e[30]),1&r[1]&&(i.policyFollows=e[31]),!n&&67108864&r[0]&&(n=!0,i.policyJson=e[26],_(()=>n=!1)),t.$set(i)},i(e){r||(Y(t.$$.fragment,e),r=!0)},o(e){W(t.$$.fragment,e),r=!1},d(e){te(t,e)}}}function sw(e){let t,n,r;function i(t){e[111](t)}let o={isLoggedIn:e[1],userRole:e[4],sprocketStatus:e[20],isLoadingSprocket:e[22],sprocketUploadFile:e[25],sprocketMessage:e[23],sprocketMessageType:e[24],sprocketVersions:e[21]};return void 0!==e[19]&&(o.sprocketScript=e[19]),t=new Fy({props:o}),R.push(()=>Z(t,"sprocketScript",i)),t.$on("restartSprocket",e[55]),t.$on("deleteSprocket",e[56]),t.$on("sprocketFileSelect",e[67]),t.$on("uploadSprocketScript",e[68]),t.$on("saveSprocket",e[54]),t.$on("loadSprocket",e[53]),t.$on("loadVersions",e[57]),t.$on("loadVersion",e[112]),t.$on("deleteVersion",e[113]),t.$on("openLoginModal",e[70]),{c(){X(t.$$.fragment)},m(e,n){ee(t,e,n),r=!0},p(e,r){const i={};2&r[0]&&(i.isLoggedIn=e[1]),16&r[0]&&(i.userRole=e[4]),1048576&r[0]&&(i.sprocketStatus=e[20]),4194304&r[0]&&(i.isLoadingSprocket=e[22]),33554432&r[0]&&(i.sprocketUploadFile=e[25]),8388608&r[0]&&(i.sprocketMessage=e[23]),16777216&r[0]&&(i.sprocketMessageType=e[24]),2097152&r[0]&&(i.sprocketVersions=e[21]),!n&&524288&r[0]&&(n=!0,i.sprocketScript=e[19],_(()=>n=!1)),t.$set(i)},i(e){r||(Y(t.$$.fragment,e),r=!0)},o(e){W(t.$$.fragment,e),r=!1},d(e){te(t,e)}}}function aw(e){let t,n,r,i;const o=[Tw,Rw,Pw],s=[];function a(e,t){return"managed"!==e[9]?0:e[1]&&"owner"===e[4]?1:2}return n=a(e),r=s[n]=o[n](e),{c(){t=p("div"),r.c(),A(t,"class","managed-acl-view svelte-u3u5mw")},m(e,r){u(e,t,r),s[n].m(t,null),i=!0},p(e,i){let l=n;n=a(e),n===l?s[n].p(e,i):(z(),W(s[l],1,1,()=>{s[l]=null}),q(),r=s[n],r?r.p(e,i):(r=s[n]=o[n](e),r.c()),Y(r,1),r.m(t,null))},i(e){i||(Y(r),i=!0)},o(e){W(r),i=!1},d(e){e&&d(t),s[n].d()}}}function lw(e){let t,n,r;function i(t){e[110](t)}let o={userPubkey:e[2],userRole:e[4],policyEnabled:e[8],publishError:e[34]};return void 0!==e[33]&&(o.composeEventJson=e[33]),t=new vy({props:o}),R.push(()=>Z(t,"composeEventJson",i)),t.$on("reformatJson",e[90]),t.$on("signEvent",e[91]),t.$on("publishEvent",e[92]),t.$on("clearError",e[93]),{c(){X(t.$$.fragment)},m(e,n){ee(t,e,n),r=!0},p(e,r){const i={};4&r[0]&&(i.userPubkey=e[2]),16&r[0]&&(i.userRole=e[4]),256&r[0]&&(i.policyEnabled=e[8]),8&r[1]&&(i.publishError=e[34]),!n&&4&r[1]&&(n=!0,i.composeEventJson=e[33],_(()=>n=!1)),t.$set(i)},i(e){r||(Y(t.$$.fragment,e),r=!0)},o(e){W(t.$$.fragment,e),r=!1},d(e){te(t,e)}}}function cw(e){let t,n;return t=new Lv({props:{isLoggedIn:e[1],userPubkey:e[2],userSigner:e[13],currentEffectiveRole:e[10]}}),t.$on("openLoginModal",e[70]),{c(){X(t.$$.fragment)},m(e,r){ee(t,e,r),n=!0},p(e,n){const r={};2&n[0]&&(r.isLoggedIn=e[1]),4&n[0]&&(r.userPubkey=e[2]),8192&n[0]&&(r.userSigner=e[13]),1024&n[0]&&(r.currentEffectiveRole=e[10]),t.$set(r)},i(e){n||(Y(t.$$.fragment,e),n=!0)},o(e){W(t.$$.fragment,e),n=!1},d(e){te(t,e)}}}function uw(e){let t,n;return t=new Zm({props:{isLoggedIn:e[1],userRole:e[4],userPubkey:e[2],filteredEvents:e[41],expandedEvents:e[18],isLoadingEvents:e[7],showOnlyMyEvents:zw,showFilterBuilder:e[15]}}),t.$on("scroll",e[89]),t.$on("toggleEventExpansion",e[106]),t.$on("deleteEvent",e[107]),t.$on("copyEventToClipboard",e[108]),t.$on("toggleChange",e[45]),t.$on("loadAllEvents",e[109]),t.$on("toggleFilterBuilder",e[76]),t.$on("filterApply",e[77]),t.$on("filterClear",e[78]),{c(){X(t.$$.fragment)},m(e,r){ee(t,e,r),n=!0},p(e,n){const r={};2&n[0]&&(r.isLoggedIn=e[1]),16&n[0]&&(r.userRole=e[4]),4&n[0]&&(r.userPubkey=e[2]),1024&n[1]&&(r.filteredEvents=e[41]),262144&n[0]&&(r.expandedEvents=e[18]),128&n[0]&&(r.isLoadingEvents=e[7]),32768&n[0]&&(r.showFilterBuilder=e[15]),t.$set(r)},i(e){n||(Y(t.$$.fragment,e),n=!0)},o(e){W(t.$$.fragment,e),n=!1},d(e){te(t,e)}}}function dw(e){let t,n;return t=new Zg({props:{isLoggedIn:e[1],currentEffectiveRole:e[10],selectedFile:e[16],aclMode:e[9],importMessage:e[17]}}),t.$on("fileSelect",e[86]),t.$on("importEvents",e[87]),t.$on("openLoginModal",e[70]),{c(){X(t.$$.fragment)},m(e,r){ee(t,e,r),n=!0},p(e,n){const r={};2&n[0]&&(r.isLoggedIn=e[1]),1024&n[0]&&(r.currentEffectiveRole=e[10]),65536&n[0]&&(r.selectedFile=e[16]),512&n[0]&&(r.aclMode=e[9]),131072&n[0]&&(r.importMessage=e[17]),t.$set(r)},i(e){n||(Y(t.$$.fragment,e),n=!0)},o(e){W(t.$$.fragment,e),n=!1},d(e){te(t,e)}}}function fw(e){let t,n;return t=new Jg({props:{isLoggedIn:e[1],currentEffectiveRole:e[10],aclMode:e[9]}}),t.$on("exportMyEvents",e[85]),t.$on("exportAllEvents",e[84]),t.$on("openLoginModal",e[70]),{c(){X(t.$$.fragment)},m(e,r){ee(t,e,r),n=!0},p(e,n){const r={};2&n[0]&&(r.isLoggedIn=e[1]),1024&n[0]&&(r.currentEffectiveRole=e[10]),512&n[0]&&(r.aclMode=e[9]),t.$set(r)},i(e){n||(Y(t.$$.fragment,e),n=!0)},o(e){W(t.$$.fragment,e),n=!1},d(e){te(t,e)}}}function pw(t){let n;return{c(){n=p("p"),n.textContent="Log in to access your user dashboard",A(n,"class","svelte-u3u5mw")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function hw(e){let t,n,r,i=(e[3]?.name||e[2].slice(0,8)+"...")+"";return{c(){t=p("p"),n=g("Welcome "),r=g(i),A(t,"class","svelte-u3u5mw")},m(e,i){u(e,t,i),c(t,n),c(t,r)},p(e,t){12&t[0]&&i!==(i=(e[3]?.name||e[2].slice(0,8)+"...")+"")&&k(r,i)},d(e){e&&d(t)}}}function gw(e){let t,n,i,o,s,a,l,f,h,y,w,b,I,C,E,x,B,S,Q,F,D,$=e[179].label+"",U=e[42].get(e[179].id)?.isLoading,P=!e[42].get(e[179].id)?.hasMore&&e[42].get(e[179].id)?.events?.length>0;function R(){return e[120](e[179])}function T(e,t){return 64&t[0]&&(C=null),64&t[0]&&(E=null),null==C&&(C=!!(e[42].get(e[179].id)?.events?.length>0)),C?yw:(null==E&&(E=!e[42].get(e[179].id)?.isLoading),E?mw:void 0)}w=new Gv({props:{filter:e[42].get(e[179].id)?.filter||{}}}),w.$on("sweep",function(){return e[121](e[179])});let N=T(e,[-1,-1,-1,-1,-1,-1]),O=N&&N(e),M=U&&bw(),L=P&&kw();function _(...t){return e[126](e[179],...t)}return{c(){t=p("div"),n=p("div"),i=p("h2"),o=g("🔍 "),s=g($),a=m(),l=p("button"),f=g("🔄 Refresh"),y=m(),X(w.$$.fragment),b=m(),I=p("div"),O&&O.c(),x=m(),M&&M.c(),B=m(),L&&L.c(),S=m(),A(i,"class","svelte-u3u5mw"),A(l,"class","refresh-btn svelte-u3u5mw"),l.disabled=h=e[42].get(e[179].id)?.isLoading,A(n,"class","search-results-header svelte-u3u5mw"),A(I,"class","search-results-content svelte-u3u5mw"),A(t,"class","search-results-view svelte-u3u5mw")},m(e,r){u(e,t,r),c(t,n),c(n,i),c(i,o),c(i,s),c(n,a),c(n,l),c(l,f),c(t,y),ee(w,t,null),c(t,b),c(t,I),O&&O.m(I,null),c(I,x),M&&M.m(I,null),c(I,B),L&&L.m(I,null),c(t,S),Q=!0,F||(D=[v(l,"click",R),v(I,"scroll",_)],F=!0)},p(t,n){e=t,(!Q||64&n[0])&&$!==($=e[179].label+"")&&k(s,$),(!Q||64&n[0]&&h!==(h=e[42].get(e[179].id)?.isLoading))&&(l.disabled=h);const r={};64&n[0]&&(r.filter=e[42].get(e[179].id)?.filter||{}),w.$set(r),N===(N=T(e,n))&&O?O.p(e,n):(O&&O.d(1),O=N&&N(e),O&&(O.c(),O.m(I,x))),64&n[0]&&(U=e[42].get(e[179].id)?.isLoading),U?M||(M=bw(),M.c(),M.m(I,B)):M&&(M.d(1),M=null),64&n[0]&&(P=!e[42].get(e[179].id)?.hasMore&&e[42].get(e[179].id)?.events?.length>0),P?L||(L=kw(),L.c(),L.m(I,null)):L&&(L.d(1),L=null)},i(e){Q||(Y(w.$$.fragment,e),Q=!0)},o(e){W(w.$$.fragment,e),Q=!1},d(e){e&&d(t),te(w),O&&O.d(),M&&M.d(),L&&L.d(),F=!1,r(D)}}}function mw(t){let n;return{c(){n=p("div"),n.innerHTML='No search results found.
',A(n,"class","no-search-results svelte-u3u5mw")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function yw(e){let t,n=e[42].get(e[179].id).events,r=[];for(let t=0;t👤',o=m(),s=p("div"),a=p("div"),l=g(O),f=m(),h=p("div"),y=p("span"),w=g(M),b=m(),I=p("span"),C=g(L),E=m(),B=p("div"),S=p("div"),Q=g(_),F=m(),D=p("div"),$=g(H),U=m(),G&&G.c(),P=m(),V&&V.c(),R=m(),A(i,"class","search-result-avatar svelte-u3u5mw"),A(a,"class","search-result-author svelte-u3u5mw"),A(y,"class","kind-number svelte-u3u5mw"),A(I,"class","kind-name svelte-u3u5mw"),A(h,"class","search-result-kind svelte-u3u5mw"),A(s,"class","search-result-info svelte-u3u5mw"),A(S,"class","event-timestamp svelte-u3u5mw"),A(D,"class","event-content-single-line svelte-u3u5mw"),A(B,"class","search-result-content svelte-u3u5mw"),A(n,"class","search-result-row svelte-u3u5mw"),A(n,"role","button"),A(n,"tabindex","0"),A(t,"class","search-result-item svelte-u3u5mw"),x(t,"expanded",e[18].has(e[172].id))},m(e,r){u(e,t,r),c(t,n),c(n,i),c(n,o),c(n,s),c(s,a),c(a,l),c(s,f),c(s,h),c(h,y),c(y,w),c(h,b),c(h,I),c(I,C),c(n,E),c(n,B),c(B,S),c(S,Q),c(B,F),c(B,D),c(D,$),c(n,U),G&&G.m(n,null),c(t,P),V&&V.m(t,null),c(t,R),T||(N=[v(n,"click",J),v(n,"keydown",K)],T=!0)},p(r,i){e=r,64&i[0]&&O!==(O=Kv(e[172].pubkey)+"")&&k(l,O),64&i[0]&&M!==(M=e[172].kind+"")&&k(w,M),64&i[0]&&L!==(L=Jv(e[172].kind)+"")&&k(C,L),64&i[0]&&_!==(_=zv(e[172].created_at)+"")&&k(Q,_),64&i[0]&&H!==(H=Vv(e[172].content)+"")&&k($,H),5!==e[172].kind&&("admin"===e[4]||"owner"===e[4]||"write"===e[4]&&e[172].pubkey&&e[172].pubkey===e[2])?G?G.p(e,i):(G=vw(e),G.c(),G.m(n,null)):G&&(G.d(1),G=null),262208&i[0]&&(j=e[18].has(e[172].id)),j?V?V.p(e,i):(V=ww(e),V.c(),V.m(t,R)):V&&(V.d(1),V=null),262208&i[0]|2048&i[1]&&x(t,"expanded",e[18].has(e[172].id))},d(e){e&&d(t),G&&G.d(),V&&V.d(),T=!1,r(N)}}}function bw(e){let t;return{c(){t=p("div"),t.innerHTML='
\n Searching...
',A(t,"class","loading-search-results svelte-u3u5mw")},m(e,n){u(e,t,n)},d(e){e&&d(t)}}}function kw(e){let t;return{c(){t=p("div"),t.innerHTML='No more search results to load.
',A(t,"class","end-of-search-results svelte-u3u5mw")},m(e,n){u(e,t,n)},d(e){e&&d(t)}}}function Iw(e){let t,n,r=e[179].id===e[5]&&gw(e);return{c(){r&&r.c(),t=y()},m(e,i){r&&r.m(e,i),u(e,t,i),n=!0},p(e,n){e[179].id===e[5]?r?(r.p(e,n),96&n[0]&&Y(r,1)):(r=gw(e),r.c(),Y(r,1),r.m(t.parentNode,t)):r&&(z(),W(r,1,1,()=>{r=null}),q())},i(e){n||(Y(r),n=!0)},o(e){W(r),n=!1},d(e){r&&r.d(e),e&&d(t)}}}function Cw(t){let n,r,i=t[176].label+"";return{c(){n=p("option"),r=g(i),n.__value=t[176].value,n.value=n.__value},m(e,t){u(e,n,t),c(n,r)},p:e,d(e){e&&d(n)}}}function Ew(e){let t;function n(e,t){return e[38]?Sw:0===e[37].length?Bw:xw}let r=n(e),i=r(e);return{c(){t=p("div"),i.c(),A(t,"class","recovery-results svelte-u3u5mw")},m(e,n){u(e,t,n),i.m(t,null)},p(e,o){r===(r=n(e))&&i?i.p(e,o):(i.d(1),i=r(e),i&&(i.c(),i.m(t,null)))},d(e){e&&d(t),i.d()}}}function xw(e){let t,n,r,i=e[37],o=[];for(let t=0;tORLY_ACL_MODE=managed in your\n environment variables and restart the relay.',A(r,"class","svelte-u3u5mw"),A(o,"class","svelte-u3u5mw"),A(a,"class","svelte-u3u5mw"),A(v,"class","svelte-u3u5mw"),A(n,"class","acl-mode-warning svelte-u3u5mw")},m(e,t){u(e,n,t),c(n,r),c(n,i),c(n,o),c(n,s),c(n,a),c(a,l),c(a,f),c(f,h),c(n,y),c(n,v)},p(e,t){512&t[0]&&w!==(w=(e[9]||"unknown")+"")&&k(h,w)},i:e,o:e,d(e){e&&d(n)}}}function Nw(e){let t,n,i,o,s,a,l,f,h,g;function y(e,t){return e[3]?Mw:e[1]&&e[2]?Ow:void 0}let b=y(e),k=b&&b(e);return{c(){t=p("div"),n=p("div"),i=p("div"),o=p("h2"),o.textContent="Settings",s=m(),a=p("button"),a.textContent="✕",l=m(),f=p("div"),k&&k.c(),A(o,"class","svelte-u3u5mw"),A(a,"class","close-btn svelte-u3u5mw"),A(i,"class","drawer-header svelte-u3u5mw"),A(f,"class","drawer-content"),A(n,"class","settings-drawer svelte-u3u5mw"),x(n,"dark-theme",e[0]),A(t,"class","drawer-overlay svelte-u3u5mw"),A(t,"role","button"),A(t,"tabindex","0")},m(r,d){u(r,t,d),c(t,n),c(n,i),c(i,o),c(i,s),c(i,a),c(n,l),c(n,f),k&&k.m(f,null),h||(g=[v(a,"click",e[75]),v(n,"click",w(e[101])),v(n,"keydown",w(e[102])),v(t,"click",e[75]),v(t,"keydown",e[128])],h=!0)},p(e,t){b===(b=y(e))&&k?k.p(e,t):(k&&k.d(1),k=b&&b(e),k&&(k.c(),k.m(f,null))),1&t[0]&&x(n,"dark-theme",e[0])},d(e){e&&d(t),k&&k.d(),h=!1,r(g)}}}function Ow(e){let t,n,i,o,s,a,l,f,h,y,w,b,I,C,E,x,B,S=e[2].slice(0,16)+"",Q=e[2].slice(-8)+"";return{c(){t=p("div"),n=p("button"),n.textContent="Log out",i=m(),o=p("h3"),o.textContent="Profile Loading",s=m(),a=p("p"),a.textContent="Your profile metadata is being loaded...",l=m(),f=p("button"),f.textContent="Retry Loading Profile",h=m(),y=p("div"),w=p("strong"),w.textContent="Public Key:",b=m(),I=g(S),C=g("..."),E=g(Q),A(n,"class","logout-btn floating svelte-u3u5mw"),A(o,"class","svelte-u3u5mw"),A(a,"class","svelte-u3u5mw"),A(f,"class","retry-profile-btn svelte-u3u5mw"),A(y,"class","user-pubkey-display svelte-u3u5mw"),A(t,"class","profile-loading-section svelte-u3u5mw")},m(r,d){u(r,t,d),c(t,n),c(t,i),c(t,o),c(t,s),c(t,a),c(t,l),c(t,f),c(t,h),c(t,y),c(y,w),c(y,b),c(y,I),c(y,C),c(y,E),x||(B=[v(n,"click",e[72]),v(f,"click",e[83])],x=!0)},p(e,t){4&t[0]&&S!==(S=e[2].slice(0,16)+"")&&k(I,S),4&t[0]&&Q!==(Q=e[2].slice(-8)+"")&&k(E,Q)},d(e){e&&d(t),x=!1,r(B)}}}function Mw(e){let t,n,r,i,o,s,a,l,f,h,w,b,I,C,E,x=(e[3].name||"Unknown User")+"",B=e[3].banner&&Lw(e);function S(e,t){return e[3].picture?Hw:_w}let Q=S(e),F=Q(e),D=e[3].nip05&&jw(e),$=e[3].about&&Gw(e),U=e[4]&&"read"!==e[4]&&Jw(e);return{c(){t=p("div"),n=p("div"),B&&B.c(),r=m(),i=p("button"),i.textContent="Log out",o=m(),F.c(),s=m(),a=p("div"),l=p("h3"),f=g(x),h=m(),D&&D.c(),w=m(),$&&$.c(),b=m(),U&&U.c(),I=y(),A(i,"class","logout-btn floating svelte-u3u5mw"),A(l,"class","profile-username svelte-u3u5mw"),A(a,"class","name-row svelte-u3u5mw"),A(n,"class","profile-hero svelte-u3u5mw"),A(t,"class","profile-section svelte-u3u5mw")},m(d,p){u(d,t,p),c(t,n),B&&B.m(n,null),c(n,r),c(n,i),c(n,o),F.m(n,null),c(n,s),c(n,a),c(a,l),c(l,f),c(a,h),D&&D.m(a,null),c(t,w),$&&$.m(t,null),u(d,b,p),U&&U.m(d,p),u(d,I,p),C||(E=v(i,"click",e[72]),C=!0)},p(e,i){e[3].banner?B?B.p(e,i):(B=Lw(e),B.c(),B.m(n,r)):B&&(B.d(1),B=null),Q===(Q=S(e))&&F?F.p(e,i):(F.d(1),F=Q(e),F&&(F.c(),F.m(n,s))),8&i[0]&&x!==(x=(e[3].name||"Unknown User")+"")&&k(f,x),e[3].nip05?D?D.p(e,i):(D=jw(e),D.c(),D.m(a,null)):D&&(D.d(1),D=null),e[3].about?$?$.p(e,i):($=Gw(e),$.c(),$.m(t,null)):$&&($.d(1),$=null),e[4]&&"read"!==e[4]?U?U.p(e,i):(U=Jw(e),U.c(),U.m(I.parentNode,I)):U&&(U.d(1),U=null)},d(e){e&&d(t),B&&B.d(),F.d(),D&&D.d(),$&&$.d(),e&&d(b),U&&U.d(e),e&&d(I),C=!1,E()}}}function Lw(e){let t,n;return{c(){t=p("img"),a(t.src,n=e[3].banner)||A(t,"src",n),A(t,"alt","Profile banner"),A(t,"class","profile-banner svelte-u3u5mw")},m(e,n){u(e,t,n)},p(e,r){8&r[0]&&!a(t.src,n=e[3].banner)&&A(t,"src",n)},d(e){e&&d(t)}}}function _w(t){let n;return{c(){n=p("div"),n.textContent="👤",A(n,"class","profile-avatar-placeholder overlap svelte-u3u5mw")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function Hw(e){let t,n;return{c(){t=p("img"),a(t.src,n=e[3].picture)||A(t,"src",n),A(t,"alt","User avatar"),A(t,"class","profile-avatar overlap svelte-u3u5mw")},m(e,n){u(e,t,n)},p(e,r){8&r[0]&&!a(t.src,n=e[3].picture)&&A(t,"src",n)},d(e){e&&d(t)}}}function jw(e){let t,n,r=e[3].nip05+"";return{c(){t=p("span"),n=g(r),A(t,"class","profile-nip05-inline svelte-u3u5mw")},m(e,r){u(e,t,r),c(t,n)},p(e,t){8&t[0]&&r!==(r=e[3].nip05+"")&&k(n,r)},d(e){e&&d(t)}}}function Gw(e){let t,n;return{c(){t=p("div"),n=p("p"),A(n,"class","profile-about svelte-u3u5mw"),A(t,"class","about-card svelte-u3u5mw")},m(r,i){u(r,t,i),c(t,n),n.innerHTML=e[40]},p(e,t){512&t[1]&&(n.innerHTML=e[40])},d(e){e&&d(t)}}}function Jw(e){let t,n,r,i,o,s,a=e[95](),l=[];for(let t=0;tZ(y,"showModal",E)),y.$on("login",e[71]),y.$on("close",e[73]),{c(){X(t.$$.fragment),n=m(),r=p("div"),X(i.$$.fragment),o=m(),s=p("main"),f.c(),h=m(),C&&C.c(),g=m(),X(y.$$.fragment),A(s,"class","main-content svelte-u3u5mw"),A(r,"class","app-container svelte-u3u5mw"),x(r,"dark-theme",e[0])},m(e,a){ee(t,e,a),u(e,n,a),u(e,r,a),ee(i,r,null),c(r,o),c(r,s),k[l].m(s,null),u(e,h,a),C&&C.m(e,a),u(e,g,a),ee(y,e,a),w=!0},p(e,n){const o={};1&n[0]&&(o.isDarkTheme=e[0]),2&n[0]&&(o.isLoggedIn=e[1]),16&n[0]&&(o.userRole=e[4]),1024&n[0]&&(o.currentEffectiveRole=e[10]),8&n[0]&&(o.userProfile=e[3]),4&n[0]&&(o.userPubkey=e[2]),t.$set(o);const a={};1&n[0]&&(a.isDarkTheme=e[0]),2048&n[0]&&(a.tabs=e[11]),32&n[0]&&(a.selectedTab=e[5]),2&n[1]&&(a.version=e[32]),i.$set(a);let c=l;l=I(e,n),l===c?k[l].p(e,n):(z(),W(k[c],1,1,()=>{k[c]=null}),q(),f=k[l],f?f.p(e,n):(f=k[l]=b[l](e),f.c()),Y(f,1),f.m(s,null)),(!w||1&n[0])&&x(r,"dark-theme",e[0]),e[14]?C?C.p(e,n):(C=Nw(e),C.c(),C.m(g.parentNode,g)):C&&(C.d(1),C=null);const u={};1&n[0]&&(u.isDarkTheme=e[0]),!v&&4096&n[0]&&(v=!0,u.showModal=e[12],_(()=>v=!1)),y.$set(u)},i(e){w||(Y(t.$$.fragment,e),Y(i.$$.fragment,e),Y(f),Y(y.$$.fragment,e),w=!0)},o(e){W(t.$$.fragment,e),W(i.$$.fragment,e),W(f),W(y.$$.fragment,e),w=!1},d(e){te(t,e),e&&d(n),e&&d(r),te(i),k[l].d(),e&&d(h),C&&C.d(e),e&&d(g),te(y,e)}}}let zw=!1,qw=!1;function Yw(e,t,n){let r,i,o,s,a;"undefined"!=typeof window&&(window.debugIndexedDB=Dp);let l=!1,c=!1,u=!1,d="",f="",p=null,h="",g=null,m=!1,y=localStorage.getItem("selectedTab")||"export",v=!1,w={},A=[],k=[],I=null,C="",E=new Set,x=!1,B=!0,S=null,Q="",F=new Map,D=[],$=0,P=[],R=!0,T=null,N="",O=null,M=[],L=!1,_="",H="info",j=!1,G=null,J="",K=!1,V=!1,z="",q="info",Y=[],W=[],Z="",X="",ee="",te="",ne=null,re="",ie=[],oe=!1,se=!0,ae=null;function le(e){E.has(e)?E.delete(e):E.add(e),n(18,E)}async function ce(e,t){const n=JSON.stringify(e),r=await async function(e){try{return await navigator.clipboard.writeText(e),!0}catch(t){console.error("Failed to copy to clipboard:",t);try{const t=document.createElement("textarea");return t.value=e,document.body.appendChild(t),t.select(),document.execCommand("copy"),document.body.removeChild(t),!0}catch(e){return console.error("Fallback copy also failed:",e),!1}}}(n);!function(e,t=!0){if(!e)return;const n=e.textContent,r=e.style.backgroundColor;t?(e.textContent="",e.style.backgroundColor="#4CAF50"):(e.textContent="L",e.style.backgroundColor="#f44336"),setTimeout(()=>{e.textContent=n,e.style.backgroundColor=r},2e3)}(t.target.closest(".copy-json-btn"),r),r||alert("Failed to copy to clipboard. Please copy manually.")}async function ue(e){if(!u)return void alert("Please log in first");const t=k.find(t=>t.id===e);if(!t)return void alert("Event not found");if("admin"===h||"owner"===h||"write"===h&&t.pubkey&&t.pubkey===d){if(confirm("Are you sure you want to delete this event?"))try{if(!g)throw new Error("Signer not available for signing");const r={kind:5,created_at:Math.floor(Date.now()/1e3),tags:[["e",e]],content:""};console.log("Created delete event template:",r),console.log("User pubkey:",d),console.log("Target event:",t),console.log("Target event pubkey:",t.pubkey);const i=await g.signEvent(r);console.log("Signed delete event:",i),console.log("Signed delete event pubkey:",i.pubkey),console.log("Delete event tags:",i.tags);const o=`${window.location.protocol.startsWith("https")?"wss:":"ws:"}//${window.location.host}/`;try{const e=await Yv(o,i,g,d);e.success?console.log("Delete event published successfully to ORLY relay"):console.error("Failed to publish delete event:",e.reason)}catch(e){console.error("Error publishing delete event:",e)}const s=t.pubkey&&t.pubkey===d;if(s){const t=await gp.publish(i);if(console.log("Delete event published:",t),!(t.success&&t.okCount>0))throw new Error("No relays accepted the delete event");{await new Promise(e=>setTimeout(e,2e3));try{const n=await Bp(e,{timeout:5e3});n?(console.warn("Event still exists after deletion attempt:",n),alert(`Warning: Delete event was accepted by ${t.okCount} relay(s), but the event still exists on the relay. This may indicate the relay does not properly handle delete events.`)):console.log("Event successfully deleted and verified")}catch(e){console.log("Could not fetch event after deletion (likely deleted):",e.message)}try{const t=await Sp(e,{timeout:5e3});if(t.length>0){console.log(`Delete event verification: Found ${t.length} delete event(s) targeting ${e}`);const n=t.find(e=>e.pubkey&&e.pubkey===d);n?console.log("Our delete event found in database:",n.id):console.warn("Our delete event not found in database, but other delete events exist")}else console.warn("No delete events found in database for target event:",e)}catch(e){console.log("Could not verify delete event in database:",e.message)}n(96,k=k.filter(t=>t.id!==e)),P=P.filter(t=>t.id!==e),D=D.filter(t=>t.id!==e);for(const[t,n]of F)n.events&&(n.events=n.events.filter(t=>t.id!==e),F.set(t,n));he(),console.log("Reloading events to show delete event...");const r=zw&&u&&d?[d]:null;await Pe(!0,r),alert(`Event deleted successfully (accepted by ${t.okCount} relay(s))`)}}else{const t=`${window.location.protocol.startsWith("https")?"wss:":"ws:"}//${window.location.host}/`,r=new hp;await r.connectToRelay(t);const o=await r.publish(i);if(console.log("Delete event published to local relay only:",o),!(o.success&&o.okCount>0))throw new Error("Local relay did not accept the delete event");{await new Promise(e=>setTimeout(e,2e3));try{const t=await Bp(e,{timeout:5e3});t?(console.warn("Event still exists after deletion attempt:",t),alert(`Warning: Delete event was accepted by ${o.okCount} relay(s), but the event still exists on the relay. This may indicate the relay does not properly handle delete events.`)):console.log("Event successfully deleted and verified")}catch(e){console.log("Could not fetch event after deletion (likely deleted):",e.message)}try{const t=await Sp(e,{timeout:5e3});if(t.length>0){console.log(`Delete event verification: Found ${t.length} delete event(s) targeting ${e}`);const n=t.find(e=>e.pubkey&&e.pubkey===d);n?console.log("Our delete event found in database:",n.id):console.warn("Our delete event not found in database, but other delete events exist")}else console.warn("No delete events found in database for target event:",e)}catch(e){console.log("Could not verify delete event in database:",e.message)}n(96,k=k.filter(t=>t.id!==e)),P=P.filter(t=>t.id!==e),D=D.filter(t=>t.id!==e);for(const[t,n]of F)n.events&&(n.events=n.events.filter(t=>t.id!==e),F.set(t,n));he(),console.log("Reloading events to show delete event...");const t=zw&&u&&d?[d]:null;await Pe(!0,t),alert("Event deleted successfully (local relay only - admin/owner deleting other user's event)")}}}catch(e){console.error("Failed to delete event:",e),alert("Failed to delete event: "+e.message)}}else alert("You do not have permission to delete this event")}async function de(){const e=re?parseInt(re):ne;if(null==e||isNaN(e))console.log("No valid kind to load, kindToUse:",e);else if(u){console.log("Loading recovery events for kind:",e,"user:",d),n(38,oe=!0);try{const t=[{kinds:[e],authors:[d],limit:100}];ae&&(t[0].until=ae),console.log("Recovery filters:",t);const r=await Fp(t,{timeout:3e4,cacheFirst:!0});console.log("Recovery events received:",r.length),console.log("Recovery events kinds:",r.map(e=>e.kind)),n(37,ie=ae?[...ie,...r]:r),r.length>0?(ae=Math.min(...r.map(e=>e.created_at)),n(39,se=100===r.length)):n(39,se=!1)}catch(e){console.error("Failed to load recovery events:",e)}finally{n(38,oe=!1)}}else console.log("Not logged in, cannot load recovery events")}async function fe(e){if(confirm("Are you sure you want to repost this event?"))try{const t=`${window.location.protocol.startsWith("https")?"wss:":"ws:"}//${window.location.host}/`;console.log("Reposting event to local relay:",t,e);const r={...e};if(r.created_at=Math.floor(Date.now()/1e3),r.id="",r.sig="",e.kind>=3e4&&e.kind<=39999){const t=e.tags.find(e=>"d"===e[0]);t&&(r.tags=r.tags.filter(e=>"d"!==e[0]),r.tags.push(t))}if(g){const e=await g.signEvent(r);console.log("Signed event for repost:",e);const i=await gp.publish(e,[t]);console.log("Repost publish result:",i),i.success&&i.okCount>0?(alert("Event reposted successfully!"),n(39,se=!1),await de()):alert("Failed to repost event. Check console for details.")}else alert("No signer available. Please log in.")}catch(e){console.error("Error reposting event:",e),alert("Error reposting event: "+e.message)}}async function pe(e){if(confirm("Are you sure you want to repost this event to all your write relays?"))try{const t=await async function(){if(!d)return[];try{const e=await kp([{kinds:[10002],authors:[d],limit:1}]);if(0===e.length)return console.log("No relay list event found for user"),[];const t=e[0];console.log("Found relay list event:",t);const n=[];for(const e of t.tags)if("r"===e[0]&&e.length>=2){const t=e[1],r=e.length>=3?e[2]:null;r&&"write"!==r||n.push(t)}return console.log("Found write relays:",n),n}catch(e){return console.error("Error fetching user write relays:",e),[]}}(),r=`${window.location.protocol.startsWith("https")?"wss:":"ws:"}//${window.location.host}/`,i=[r,...t.filter(e=>e!==r)];1===i.length&&alert("No write relays found in your relay list. Only posting to local relay."),console.log("Reposting event to all relays:",i,e);const o={...e};if(o.created_at=Math.floor(Date.now()/1e3),o.id="",o.sig="",e.kind>=3e4&&e.kind<=39999){const t=e.tags.find(e=>"d"===e[0]);t&&(o.tags=o.tags.filter(e=>"d"!==e[0]),o.tags.push(t))}if(g){const e=await g.signEvent(o);console.log("Signed event for repost to all:",e);const t=await gp.publish(e,i);console.log("Repost to all publish result:",t),t.success&&t.okCount>0?(alert(`Event reposted successfully to ${i.length} relays!`),n(39,se=!1),await de()):alert("Failed to repost event. Check console for details.")}else alert("No signer available. Please log in.")}catch(e){console.error("Error reposting event to all:",e),alert("Error reposting event to all: "+e.message)}}if("undefined"!=typeof window&&window.matchMedia){const e=window.matchMedia("(prefers-color-scheme: dark)");l=e.matches,e.addEventListener("change",e=>{n(0,l=e.matches)})}if("undefined"!=typeof localStorage){const e=localStorage.getItem("nostr_auth_method"),t=localStorage.getItem("nostr_pubkey");e&&t&&(u=!0,d=t,f=e,"extension"===e&&window.nostr&&(g=window.nostr),De(),$e()),function(){if("undefined"==typeof localStorage)return;try{const t=localStorage.getItem("app_state");if(t){const r=JSON.parse(t);r.selectedTab&&Ie.some(e=>e.id===r.selectedTab)&&n(5,y=r.selectedTab),r.expandedEvents&&n(18,E=new Set(r.expandedEvents)),r.globalEventsCache&&(D=r.globalEventsCache),r.globalCacheTimestamp&&($=r.globalCacheTimestamp),void 0!==r.hasMoreEvents&&(B=r.hasMoreEvents),r.oldestEventTimestamp&&(S=r.oldestEventTimestamp),void 0!==r.hasMoreMyEvents&&(R=r.hasMoreMyEvents),r.oldestMyEventTimestamp&&(T=r.oldestMyEventTimestamp),D.length>0&&((e=$)&&Date.now()-et.created_at-e.created_at),$=Date.now(),he()}async function me(){if(u&&"owner"===h&&j)try{n(22,L=!0);const e=await fetch("/api/sprocket/status",{method:"GET",headers:{Authorization:`Nostr ${await Oe("GET","/api/sprocket/status")}`,"Content-Type":"application/json"}});e.ok?n(20,O=await e.json()):Ae("Failed to load sprocket status","error")}catch(e){Ae(`Error loading sprocket status: ${e.message}`,"error")}finally{n(22,L=!1)}}async function ye(){if(u&&"owner"===h)try{n(22,L=!0);const e=await fetch("/api/sprocket/versions",{method:"GET",headers:{Authorization:`Nostr ${await Oe("GET","/api/sprocket/versions")}`,"Content-Type":"application/json"}});e.ok?n(21,M=await e.json()):Ae("Failed to load versions","error")}catch(e){Ae(`Error loading versions: ${e.message}`,"error")}finally{n(22,L=!1)}}async function ve(e){u&&"owner"===h&&(n(19,N=e.content),Ae(`Loaded version: ${e.name}`,"success"))}async function we(e){if(u&&"owner"===h&&confirm(`Are you sure you want to delete version ${e}?`))try{n(22,L=!0);const t=await fetch("/api/sprocket/delete-version",{method:"POST",headers:{Authorization:`Nostr ${await Oe("POST","/api/sprocket/delete-version")}`,"Content-Type":"application/json"},body:JSON.stringify({filename:e})});if(t.ok)Ae(`Version ${e} deleted successfully`,"success"),await ye();else{Ae(`Failed to delete version: ${await t.text()}`,"error")}}catch(e){Ae(`Error deleting version: ${e.message}`,"error")}finally{n(22,L=!1)}}function Ae(e,t="info"){n(23,_=e),n(24,H=t),setTimeout(()=>{n(23,_="")},5e3)}function be(e,t="info"){n(28,z=e),n(29,q=t),"error"!==t&&setTimeout(()=>{n(28,z="")},5e3)}async function ke(){if(n(30,Y=[]),!J.trim())return n(30,Y=["Policy JSON is empty"]),be("Validation failed","error"),!1;try{const e=JSON.parse(J);if("object"!=typeof e||null===e)return n(30,Y=["Policy must be a JSON object"]),be("Validation failed","error"),!1;if(e.policy_admins)if(Array.isArray(e.policy_admins))for(const t of e.policy_admins)"string"==typeof t&&/^[0-9a-fA-F]{64}$/.test(t)||Y.push(`Invalid policy_admin pubkey: ${t}`);else Y.push("policy_admins must be an array");if(e.rules)if("object"!=typeof e.rules)Y.push("rules must be an object");else for(const[t,n]of Object.entries(e.rules))if(/^\d+$/.test(t)||Y.push(`Invalid kind number: ${t}`),n.tag_validation&&"object"==typeof n.tag_validation)for(const[e,t]of Object.entries(n.tag_validation))try{new RegExp(t)}catch(n){Y.push(`Invalid regex for tag '${e}': ${t}`)}return e.default_policy&&!["allow","deny"].includes(e.default_policy)&&Y.push("default_policy must be 'allow' or 'deny'"),Y.length>0?(be("Validation failed - see errors below","error"),!1):(be("Validation passed","success"),!0)}catch(e){return n(30,Y=[`JSON parse error: ${e.message}`]),be("Invalid JSON syntax","error"),!1}}const Ie=[{id:"export",icon:"📤",label:"Export"},{id:"import",icon:"💾",label:"Import",requiresAdmin:!0},{id:"events",icon:"📡",label:"Events"},{id:"blossom",icon:"🌸",label:"Blossom"},{id:"compose",icon:"✏️",label:"Compose",requiresWrite:!0},{id:"recovery",icon:"🔄",label:"Recovery"},{id:"managed-acl",icon:"🛡️",label:"Managed ACL",requiresOwner:!0},{id:"sprocket",icon:"⚙️",label:"Sprocket",requiresOwner:!0},{id:"policy",icon:"📜",label:"Policy",requiresOwner:!0}];function Ce(e){n(5,y=e),"sprocket"===e&&u&&"owner"===h&&j&&(me(),ye()),he()}function Ee(){n(14,m=!1)}function xe(e){Be(e)}function Be(e){n(6,A=A.filter(t=>t.id!==e)),F.delete(e),y===e&&n(5,y="export")}async function Se(e,t=!0){const n=F.get(e);if(n&&!n.isLoading){n.isLoading=!0,F.set(e,n);try{const r={...n.filter};!t&&n.oldestTimestamp&&(r.until=n.oldestTimestamp),t||(r.limit=200),console.log("Loading search results with filter:",r);const i=await xp([r],{timeout:3e4});if(console.log("Received search results:",i.length,"events"),n.events=t?i.sort((e,t)=>t.created_at-e.created_at):[...n.events,...i].sort((e,t)=>t.created_at-e.created_at),i.length>0){const e=Math.min(...i.map(e=>e.created_at));(!n.oldestTimestamp||e0){const e=o.filter(e=>e.pubkey&&e.pubkey!==d);e.length>0&&console.warn("Server returned non-user events:",e.length,"out of",o.length)}if(e?(n(96,k=o.sort((e,t)=>t.created_at-e.created_at)),ge(o)):(n(96,k=[...k,...o].sort((e,t)=>t.created_at-e.created_at)),ge(k)),o.length>0){const e=Math.min(...o.map(e=>e.created_at));(!S||e{if("events"===y){const e=document.querySelectorAll(".events-view-content")[0];e&&e.scrollHeight<=e.clientHeight&&Re()}},100)}catch(e){console.error("Failed to load events:",e),alert("Failed to load events: "+e.message)}finally{n(7,x=!1)}}}async function Re(){await Pe(!1)}let Te=!1;async function Ne(e,t){if(!u||!d)throw new Error("Not logged in");const n={kind:27235,created_at:Math.floor(Date.now()/1e3),tags:[["u",window.location.origin+e],["method",t.toUpperCase()]],content:"",pubkey:d};let r;if(g&&"extension"===f)try{r=await g.signEvent(n)}catch(e){throw new Error("Failed to sign with extension: "+e.message)}else{if("nsec"!==f)throw new Error("No valid signer available");n.id="mock-id-"+Date.now(),n.sig="mock-signature-"+Date.now(),r=n}const i=JSON.stringify(r);return`Nostr ${btoa(i)}`}async function Oe(e,t){if(!u||!d)throw new Error("Not logged in");const n={kind:27235,created_at:Math.floor(Date.now()/1e3),tags:[["u",window.location.origin+t],["method",e.toUpperCase()]],content:"",pubkey:d};let r;if(g&&"extension"===f)try{r=await g.signEvent(n)}catch(e){throw new Error("Failed to sign with extension: "+e.message)}else{if("nsec"!==f)throw new Error("No valid signer available");n.id="mock-id-"+Date.now(),n.sig="mock-signature-"+Date.now(),r=n}const i=JSON.stringify(r);return btoa(i)}function Me(e,t){const n=e.toLowerCase();if(n.includes("policy")||n.includes("blocked")||n.includes("denied")){let n=`Policy Error: ${e}`;return null!==t&&(n+=`\n\nKind ${t} may be restricted by the relay's policy configuration.`),K&&(n+="\n\nThe relay has policy enforcement enabled. Contact a relay administrator to allow this event kind or adjust your permissions."),n}if(n.includes("auth")||n.includes("permission")||n.includes("unauthorized"))return`Permission Error: ${e}\n\nYour current permissions may not allow publishing this type of event. Current role: ${h||"unknown"}. Contact a relay administrator to upgrade your permissions.`;if(n.includes("kind")||n.includes("not allowed")||n.includes("restricted")){let n=`Event Type Error: ${e}`;return null!==t&&(n+=`\n\nKind ${t} is not currently allowed on this relay.`),n+="\n\nThe relay administrator may need to update the policy configuration to allow this event kind.",n}return n.includes("rate")||n.includes("limit")||n.includes("too many")?`Rate Limit Error: ${e}\n\nPlease wait a moment before trying again.`:n.includes("size")||n.includes("too large")||n.includes("content")?`Size Limit Error: ${e}\n\nThe event may exceed the relay's size limits. Try reducing the content length.`:`Publishing failed: ${e}`}function Le(e){n(97,Q=e),localStorage.setItem("viewAsRole",e),console.log("View as role changed to:",e,"Current effective role:",a)}Q=localStorage.getItem("viewAsRole")||"";return e.$$.update=()=>{var t;if(6&e.$$.dirty[0]|8&e.$$.dirty[3]&&n(41,r=k.sort((e,t)=>t.created_at-e.created_at)),8&e.$$.dirty[0]&&n(40,i=p?.about?(t=p.about,t?t.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'"):"").replace(/\n{2,}/g," "):""),16&e.$$.dirty[0]|16&e.$$.dirty[3]&&n(10,a=Q&&""!==Q?Q:h),1810&e.$$.dirty[0]|48&e.$$.dirty[3]&&n(100,o=Ie.filter(e=>{const t=a;return!(e.requiresAdmin&&(!u||"admin"!==t&&"owner"!==t))&&(!(e.requiresOwner&&(!u||"owner"!==t))&&(!(e.requiresWrite&&(!u||"read"===t))&&(!("sprocket"===e.id&&!j)&&(!("policy"===e.id&&!K)&&(("managed-acl"!==e.id||"managed"===Z)&&(console.log(`Tab ${e.id} filter check:`,{isLoggedIn:u,userRole:h,viewAsRole:Q,currentRole:t,requiresAdmin:e.requiresAdmin,requiresOwner:e.requiresOwner,requiresWrite:e.requiresWrite,visible:!0}),!0))))))})),64&e.$$.dirty[0]|128&e.$$.dirty[3]&&n(11,s=[...o,...A]),2578&e.$$.dirty[0]|128&e.$$.dirty[3]&&console.log("Tabs debug:",{isLoggedIn:u,userRole:h,aclMode:Z,filteredBaseTabs:o.map(e=>e.id),allTabs:s.map(e=>e.id)}),1&e.$$.dirty[0]&&"undefined"!=typeof document&&(l?document.body.classList.add("dark-theme"):document.body.classList.remove("dark-theme")),14&e.$$.dirty[0]&&u&&d&&!p&&Fe(),182&e.$$.dirty[0]|72&e.$$.dirty[3]&&"events"===y&&u&&("read"===h||"write"===h||"admin"===h||"owner"===h)&&0===k.length&&!Te&&!x){n(99,Te=!0);Pe(!0,null)}32&e.$$.dirty[0]|8&e.$$.dirty[3]&&("events"!==y||"events"===y&&k.length>0)&&n(99,Te=!1),32&e.$$.dirty[0]&&localStorage.setItem("selectedTab",y)},[l,u,d,p,h,y,A,x,K,Z,a,s,c,g,m,v,I,C,E,N,O,M,L,_,H,G,J,V,z,q,Y,W,X,ee,te,ne,re,ie,oe,se,i,r,F,le,ce,async function(){console.log("Toggle changed, showOnlyMyEvents:",zw),n(99,Te=!1),await Pe(!0,null)},ue,de,fe,pe,function(){console.log("selectRecoveryKind called, recoverySelectedKind:",ne),null!=ne?(n(36,re=""),n(37,ie=[]),ae=null,n(39,se=!0),de()):console.log("No kind selected, skipping load")},function(){console.log("handleCustomKindInput called, recoveryCustomKind:",re);const e=parseInt(re);""!==re&&!isNaN(e)&&e>=0&&(n(35,ne=null),n(37,ie=[]),ae=null,n(39,se=!0),de())},function(e){const t=ie.filter(t=>t.kind===e.kind&&t.pubkey===e.pubkey),n=Math.max(...t.map(e=>e.created_at));return e.created_at===n},async function(){if(u&&"owner"===h)try{n(22,L=!0);const e=await fetch("/api/sprocket/status",{method:"GET",headers:{Authorization:`Nostr ${await Oe("GET","/api/sprocket/status")}`,"Content-Type":"application/json"}});if(e.ok){const t=await e.json();n(19,N=t.script_content||""),n(20,O=t),Ae("Script loaded successfully","success")}else Ae("Failed to load script","error")}catch(e){Ae(`Error loading script: ${e.message}`,"error")}finally{n(22,L=!1)}},async function(){if(u&&"owner"===h)try{n(22,L=!0);const e=await fetch("/api/sprocket/update",{method:"POST",headers:{Authorization:`Nostr ${await Oe("POST","/api/sprocket/update")}`,"Content-Type":"text/plain"},body:N});if(e.ok)Ae("Script saved and updated successfully","success"),await me(),await ye();else{Ae(`Failed to save script: ${await e.text()}`,"error")}}catch(e){Ae(`Error saving script: ${e.message}`,"error")}finally{n(22,L=!1)}},async function(){if(u&&"owner"===h)try{n(22,L=!0);const e=await fetch("/api/sprocket/restart",{method:"POST",headers:{Authorization:`Nostr ${await Oe("POST","/api/sprocket/restart")}`,"Content-Type":"application/json"}});if(e.ok)Ae("Sprocket restarted successfully","success"),await me();else{Ae(`Failed to restart sprocket: ${await e.text()}`,"error")}}catch(e){Ae(`Error restarting sprocket: ${e.message}`,"error")}finally{n(22,L=!1)}},async function(){if(u&&"owner"===h&&confirm("Are you sure you want to delete the sprocket script? This will stop the current process."))try{n(22,L=!0);const e=await fetch("/api/sprocket/update",{method:"POST",headers:{Authorization:`Nostr ${await Oe("POST","/api/sprocket/update")}`,"Content-Type":"text/plain"},body:""});if(e.ok)n(19,N=""),Ae("Sprocket script deleted successfully","success"),await me(),await ye();else{Ae(`Failed to delete script: ${await e.text()}`,"error")}}catch(e){Ae(`Error deleting script: ${e.message}`,"error")}finally{n(22,L=!1)}},ye,ve,we,async function(){if(u&&("owner"===h||qw))try{n(27,V=!0),n(30,Y=[]);const e={kinds:[12345],limit:1},t=await Fp(e);if(t&&t.length>0){n(26,J=t[0].content);try{n(26,J=JSON.stringify(JSON.parse(J),null,2))}catch(e){}be("Policy loaded successfully","success")}else{const e=await fetch("/api/policy",{method:"GET",headers:{Authorization:`Nostr ${await Oe("GET","/api/policy")}`,"Content-Type":"application/json"}});if(e.ok){const t=await e.json();n(26,J=JSON.stringify(t,null,2)),be("Policy loaded from file","success")}else be("No policy configuration found","info"),n(26,J="")}}catch(e){be(`Error loading policy: ${e.message}`,"error")}finally{n(27,V=!1)}},ke,async function(){if(!u||"owner"!==h&&!qw)return;if(await ke())try{n(27,V=!0);const e={kind:12345,created_at:Math.floor(Date.now()/1e3),tags:[],content:J},t=await Yv(e,g);t.success?be("Policy updated successfully","success"):be(`Failed to publish policy: ${t.error||"Unknown error"}`,"error")}catch(e){be(`Error saving policy: ${e.message}`,"error")}finally{n(27,V=!1)}},function(){try{const e=JSON.parse(J);n(26,J=JSON.stringify(e,null,2)),be("JSON formatted","success")}catch(e){be(`Cannot format: ${e.message}`,"error")}},function(e){const t=e.detail;if(!t)return void be("Please enter a pubkey","error");const r=function(e){if(!e)return null;if(/^[0-9a-fA-F]{64}$/.test(e))return e.toLowerCase();if(e.startsWith("npub1"))try{const t="qpzry9x8gf2tvdw0s3jn54khce6mua7l",n=e.slice(5);let r=[];for(const e of n){const n=t.indexOf(e.toLowerCase());if(-1===n)throw new Error("Invalid character in npub");r.push(...[...Array(5)].map((e,t)=>n>>4-t&1))}r=r.slice(0,-30);const i=[];for(let e=0;e+8<=r.length;e+=8){let t=0;for(let n=0;n<8;n++)t=t<<1|r[e+n];i.push(t)}return i.map(e=>e.toString(16).padStart(2,"0")).join("")}catch(e){return console.error("Failed to decode npub:",e),null}return null}(t);if(r&&64===r.length)try{const e=JSON.parse(J||"{}");if(e.policy_admins||(e.policy_admins=[]),e.policy_admins.includes(r))return void be("Admin already in list","warning");e.policy_admins.push(r),n(26,J=JSON.stringify(e,null,2)),be("Admin added - click 'Save & Publish' to apply","info")}catch(e){be(`Error adding admin: ${e.message}`,"error")}else be("Invalid pubkey format. Use hex (64 chars) or npub","error")},function(e){const t=e.detail;try{const e=JSON.parse(J||"{}");e.policy_admins&&(e.policy_admins=e.policy_admins.filter(e=>e!==t),n(26,J=JSON.stringify(e,null,2)),be("Admin removed - click 'Save & Publish' to apply","info"))}catch(e){be(`Error removing admin: ${e.message}`,"error")}},async function(){if(u&&("owner"===h||qw))try{n(27,V=!0),n(31,W=[]);let e=[];try{e=JSON.parse(J||"{}").policy_admins||[]}catch(e){return void be("Cannot parse policy JSON to get admins","error")}if(0===e.length)return void be("No policy admins configured","warning");const t={kinds:[3],authors:e,limit:e.length},r=await Fp(t),i=new Set;for(const e of r)if(e.tags)for(const t of e.tags)"p"===t[0]&&t[1]&&64===t[1].length&&i.add(t[1]);n(31,W=Array.from(i)),be(`Loaded ${W.length} follows from ${r.length} admin(s)`,"success")}catch(e){be(`Error loading follows: ${e.message}`,"error")}finally{n(27,V=!1)}},function(e){n(25,G=e.target.files[0])},async function(){if(u&&"owner"===h&&G)try{n(22,L=!0);const e=await G.text(),t=await fetch("/api/sprocket/update",{method:"POST",headers:{Authorization:`Nostr ${await Oe("POST","/api/sprocket/update")}`,"Content-Type":"text/plain"},body:e});if(t.ok)n(19,N=e),Ae("Script uploaded and updated successfully","success"),await me(),await ye();else{Ae(`Failed to upload script: ${await t.text()}`,"error")}}catch(e){Ae(`Error uploading script: ${e.message}`,"error")}finally{n(22,L=!1),n(25,G=null);const e=document.getElementById("sprocket-upload-file");e&&(e.value="")}},Ce,function(){u||n(12,c=!0)},async function(e){const{method:t,pubkey:r,privateKey:i,signer:o}=e.detail;n(1,u=!0),n(2,d=r),f=t,n(13,g=o),n(12,c=!1);try{if(await Qp(),"extension"===t&&o)gp.setSigner(o);else if("nsec"===t&&i){const e=new kf(i);gp.setSigner(e)}n(3,p=await Cp(r)),console.log("Profile loaded:",p)}catch(e){console.error("Failed to load profile:",e)}await De(),await $e()},function(){n(1,u=!1),n(2,d=""),f="",n(3,p=null),n(4,h=""),n(13,g=null),n(14,m=!1),P=[],n(96,k=[]),D=[],$=0,he(),"undefined"!=typeof localStorage&&(localStorage.removeItem("nostr_auth_method"),localStorage.removeItem("nostr_pubkey"),localStorage.removeItem("nostr_privkey"))},function(){n(12,c=!1)},function(){n(14,m=!0)},Ee,function(){n(15,v=!v)},function(e){const{searchText:t,selectedKinds:n,pubkeys:r,eventIds:i,tags:o,sinceTimestamp:s,untilTimestamp:a,limit:l}=e.detail,c=function({searchText:e=null,kinds:t=[],authors:n=[],ids:r=[],tags:i=[],since:o=null,until:s=null,limit:a=null}){const l={};return e&&e.trim()&&(l.search=e.trim()),t&&t.length>0&&(l.kinds=t),n&&n.length>0&&(l.authors=n),r&&r.length>0&&(l.ids=r),i&&i.length>0&&i.forEach(e=>{if(e.name&&e.value){const t=`#${e.name}`;l[t]||(l[t]=[]),l[t].push(e.value)}}),o&&(l.since=o),s&&(l.until=s),a&&a>0&&(l.limit=a),l}({searchText:t,kinds:n,authors:r,ids:i,tags:o,since:s,until:a,limit:l||100});w=c,Pe(!0,null)},function(){w={},Pe(!0,null)},xe,Be,Se,Qe,Fe,async function(){await Ue([])},async function(){await Ue([d])},function(e){n(16,I=e.detail.target.files[0])},async function(){if("none"!==Z&&(!u||"admin"!==h&&"owner"!==h))return n(17,C="Admin or owner permission required"),void setTimeout(()=>{n(17,C="")},5e3);if(!I)return n(17,C="Please select a file"),void setTimeout(()=>{n(17,C="")},5e3);try{n(17,C="Uploading...");const e={};"none"!==Z&&u&&(e.Authorization=await Ne("/api/import","POST"));const t=new FormData;t.append("file",I);const r=await fetch("/api/import",{method:"POST",headers:e,body:t});if(!r.ok)throw new Error(`Import failed: ${r.status} ${r.statusText}`);await r.json();n(17,C="Upload complete"),n(16,I=null),document.getElementById("import-file").value="",setTimeout(()=>{n(17,C="")},5e3)}catch(e){console.error("Import failed:",e),n(17,C="Import failed: "+e.message),setTimeout(()=>{n(17,C="")},5e3)}},Pe,function(e){const{scrollTop:t,scrollHeight:n,clientHeight:r}=e.target;n-t-r<100&&Re()},function(){try{if(!ee.trim())return void alert("Please enter some JSON to reformat");const e=JSON.parse(ee);n(33,ee=JSON.stringify(e,null,2))}catch(e){alert("Invalid JSON: "+e.message)}},async function(){try{if(!ee.trim())return void alert("Please enter an event to sign");if(!u||!d)return void alert("Please log in to sign events");if(!g)return void alert("No signer available. Please log in with a valid authentication method.");const e=JSON.parse(ee);e.pubkey=d,e.created_at=Math.floor(Date.now()/1e3),delete e.id,delete e.sig;const t=await g.signEvent(e);n(33,ee=JSON.stringify(t,null,2)),alert("Event signed successfully!")}catch(e){console.error("Error signing event:",e),alert("Error signing event: "+e.message)}},async function(){n(34,te="");try{if(!ee.trim())return void n(34,te="Please enter an event to publish");if(!u)return void n(34,te="Please log in to publish events");if(!g)return void n(34,te="No signer available. Please log in with a valid authentication method.");let e;try{e=JSON.parse(ee)}catch(e){return void n(34,te=`Invalid JSON: ${e.message}`)}if(!e.id||!e.sig)return void n(34,te='Event must be signed before publishing. Please click "Sign" first.');if("read"===h)return void n(34,te=`Permission denied: Your current role is "${h}" which does not allow publishing events. Contact a relay administrator to upgrade your permissions.`);const t=`${window.location.protocol.startsWith("https")?"wss:":"ws:"}//${window.location.host}/`,r=await Yv(t,e,g,d);if(r.success)n(34,te=""),alert("Event published successfully to ORLY relay!");else{const t=r.reason||"Unknown error";n(34,te=Me(t,e.kind))}}catch(e){console.error("Error publishing event:",e);const t=e.message||"Unknown error";n(34,te=Me(t,null))}},function(){n(34,te="")},Le,function(){const e=["owner","admin","write","read"],t=e.indexOf(h);return-1===t?["read"]:e.slice(t)},k,Q,j,Te,o,function(t){U.call(this,e,t)},function(t){U.call(this,e,t)},e=>e.id===y,e=>Ce(e.detail),e=>Be(e.detail),e=>le(e.detail),e=>ue(e.detail),e=>ce(e.detail.event,e.detail.e),e=>Pe(e.detail.refresh,e.detail.authors),function(e){ee=e,n(33,ee)},function(e){N=e,n(19,N)},e=>ve(e.detail),e=>we(e.detail),function(e){J=e,n(26,J)},function(){ne=function(e){const t=e.querySelector(":checked");return t&&t.__value}(this),n(35,ne)},function(){re=b(this.value),n(36,re)},e=>pe(e),e=>fe(e),(e,t)=>ce(e,t),e=>Se(e.id,!0),e=>xe(e.id),e=>ue(e.id),e=>le(e.id),(e,t)=>"Enter"===t.key&&le(e.id),(e,t)=>ce(e,t),(e,t)=>Qe(t,e.id),e=>Le(e===h?"":e),e=>"Escape"===e.key&&Ee(),function(e){c=e,n(12,c)}]}return new class extends ie{constructor(e){super(),re(this,e,Yw,Vw,o,{},null,[-1,-1,-1,-1,-1,-1])}}({target:document.body,props:{name:"world"}})}();
//# sourceMappingURL=bundle.js.map
diff --git a/app/web/dist/bundle.js.map b/app/web/dist/bundle.js.map
new file mode 100644
index 0000000..4114ae6
--- /dev/null
+++ b/app/web/dist/bundle.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"bundle.js","sources":["../node_modules/svelte/internal/index.mjs","../node_modules/@noble/curves/node_modules/@noble/hashes/esm/_assert.js","../node_modules/@noble/curves/node_modules/@noble/hashes/esm/crypto.js","../node_modules/@noble/curves/node_modules/@noble/hashes/esm/utils.js","../node_modules/@noble/curves/node_modules/@noble/hashes/esm/_sha2.js","../node_modules/@noble/curves/node_modules/@noble/hashes/esm/sha256.js","../node_modules/@noble/curves/esm/abstract/utils.js","../node_modules/@noble/curves/esm/abstract/modular.js","../node_modules/@noble/curves/esm/abstract/curve.js","../node_modules/@noble/curves/esm/abstract/weierstrass.js","../node_modules/@noble/curves/node_modules/@noble/hashes/esm/hmac.js","../node_modules/@noble/curves/esm/_shortw_utils.js","../node_modules/@noble/curves/esm/secp256k1.js","../node_modules/nostr-tools/node_modules/@noble/hashes/esm/crypto.js","../node_modules/nostr-tools/node_modules/@noble/hashes/esm/utils.js","../node_modules/nostr-tools/node_modules/@noble/hashes/esm/_assert.js","../node_modules/nostr-tools/node_modules/@noble/hashes/esm/_sha2.js","../node_modules/nostr-tools/node_modules/@noble/hashes/esm/sha256.js","../node_modules/nostr-tools/lib/esm/pool.js","../node_modules/nostr-tools/node_modules/@scure/base/lib/esm/index.js","../node_modules/@noble/ciphers/esm/_assert.js","../node_modules/@noble/ciphers/esm/utils.js","../node_modules/@noble/ciphers/esm/aes.js","../node_modules/@noble/ciphers/esm/_arx.js","../node_modules/@noble/ciphers/esm/chacha.js","../node_modules/nostr-tools/node_modules/@noble/hashes/esm/hmac.js","../node_modules/nostr-tools/node_modules/@noble/hashes/esm/hkdf.js","../node_modules/nostr-tools/lib/esm/index.js","../node_modules/nostr-tools/lib/esm/kinds.js","../node_modules/tslib/tslib.es6.mjs","../node_modules/rxjs/dist/esm5/internal/util/isFunction.js","../node_modules/rxjs/dist/esm5/internal/util/createErrorClass.js","../node_modules/rxjs/dist/esm5/internal/util/UnsubscriptionError.js","../node_modules/rxjs/dist/esm5/internal/util/arrRemove.js","../node_modules/rxjs/dist/esm5/internal/Subscription.js","../node_modules/rxjs/dist/esm5/internal/config.js","../node_modules/rxjs/dist/esm5/internal/scheduler/timeoutProvider.js","../node_modules/rxjs/dist/esm5/internal/util/reportUnhandledError.js","../node_modules/rxjs/dist/esm5/internal/util/noop.js","../node_modules/rxjs/dist/esm5/internal/util/errorContext.js","../node_modules/rxjs/dist/esm5/internal/Subscriber.js","../node_modules/rxjs/dist/esm5/internal/symbol/observable.js","../node_modules/rxjs/dist/esm5/internal/util/identity.js","../node_modules/rxjs/dist/esm5/internal/Observable.js","../node_modules/rxjs/dist/esm5/internal/util/pipe.js","../node_modules/rxjs/dist/esm5/internal/util/lift.js","../node_modules/rxjs/dist/esm5/internal/operators/OperatorSubscriber.js","../node_modules/rxjs/dist/esm5/internal/util/ObjectUnsubscribedError.js","../node_modules/rxjs/dist/esm5/internal/Subject.js","../node_modules/rxjs/dist/esm5/internal/scheduler/dateTimestampProvider.js","../node_modules/rxjs/dist/esm5/internal/ReplaySubject.js","../node_modules/rxjs/dist/esm5/internal/scheduler/Action.js","../node_modules/rxjs/dist/esm5/internal/scheduler/intervalProvider.js","../node_modules/rxjs/dist/esm5/internal/scheduler/AsyncAction.js","../node_modules/rxjs/dist/esm5/internal/Scheduler.js","../node_modules/rxjs/dist/esm5/internal/scheduler/AsyncScheduler.js","../node_modules/rxjs/dist/esm5/internal/scheduler/async.js","../node_modules/rxjs/dist/esm5/internal/observable/empty.js","../node_modules/rxjs/dist/esm5/internal/util/isScheduler.js","../node_modules/rxjs/dist/esm5/internal/util/args.js","../node_modules/rxjs/dist/esm5/internal/util/isArrayLike.js","../node_modules/rxjs/dist/esm5/internal/util/isPromise.js","../node_modules/rxjs/dist/esm5/internal/util/isInteropObservable.js","../node_modules/rxjs/dist/esm5/internal/util/isAsyncIterable.js","../node_modules/rxjs/dist/esm5/internal/util/throwUnobservableError.js","../node_modules/rxjs/dist/esm5/internal/symbol/iterator.js","../node_modules/rxjs/dist/esm5/internal/util/isIterable.js","../node_modules/rxjs/dist/esm5/internal/util/isReadableStreamLike.js","../node_modules/rxjs/dist/esm5/internal/observable/innerFrom.js","../node_modules/rxjs/dist/esm5/internal/util/executeSchedule.js","../node_modules/rxjs/dist/esm5/internal/operators/observeOn.js","../node_modules/rxjs/dist/esm5/internal/operators/subscribeOn.js","../node_modules/rxjs/dist/esm5/internal/scheduled/scheduleAsyncIterable.js","../node_modules/rxjs/dist/esm5/internal/scheduled/scheduled.js","../node_modules/rxjs/dist/esm5/internal/scheduled/scheduleObservable.js","../node_modules/rxjs/dist/esm5/internal/scheduled/scheduleArray.js","../node_modules/rxjs/dist/esm5/internal/scheduled/schedulePromise.js","../node_modules/rxjs/dist/esm5/internal/scheduled/scheduleIterable.js","../node_modules/rxjs/dist/esm5/internal/scheduled/scheduleReadableStreamLike.js","../node_modules/rxjs/dist/esm5/internal/observable/from.js","../node_modules/rxjs/dist/esm5/internal/observable/of.js","../node_modules/rxjs/dist/esm5/internal/operators/map.js","../node_modules/rxjs/dist/esm5/internal/util/mapOneOrManyArgs.js","../node_modules/rxjs/dist/esm5/internal/util/argsArgArrayOrObject.js","../node_modules/rxjs/dist/esm5/internal/observable/combineLatest.js","../node_modules/rxjs/dist/esm5/internal/util/createObject.js","../node_modules/rxjs/dist/esm5/internal/operators/mergeMap.js","../node_modules/rxjs/dist/esm5/internal/operators/mergeInternals.js","../node_modules/rxjs/dist/esm5/internal/operators/mergeAll.js","../node_modules/rxjs/dist/esm5/internal/observable/concat.js","../node_modules/rxjs/dist/esm5/internal/operators/concatAll.js","../node_modules/rxjs/dist/esm5/internal/observable/defer.js","../node_modules/rxjs/dist/esm5/internal/observable/timer.js","../node_modules/rxjs/dist/esm5/internal/util/isDate.js","../node_modules/rxjs/dist/esm5/internal/observable/merge.js","../node_modules/rxjs/dist/esm5/internal/operators/filter.js","../node_modules/rxjs/dist/esm5/internal/operators/take.js","../node_modules/rxjs/dist/esm5/internal/operators/distinctUntilChanged.js","../node_modules/rxjs/dist/esm5/internal/operators/endWith.js","../node_modules/rxjs/dist/esm5/internal/operators/finalize.js","../node_modules/rxjs/dist/esm5/internal/operators/merge.js","../node_modules/rxjs/dist/esm5/internal/operators/mergeWith.js","../node_modules/rxjs/dist/esm5/internal/operators/scan.js","../node_modules/rxjs/dist/esm5/internal/operators/scanInternals.js","../node_modules/rxjs/dist/esm5/internal/operators/share.js","../node_modules/rxjs/dist/esm5/internal/operators/switchMap.js","../node_modules/rxjs/dist/esm5/internal/operators/tap.js","../node_modules/applesauce-core/dist/helpers/tags.js","../node_modules/nostr-tools/lib/esm/pure.js","../node_modules/applesauce-core/dist/helpers/cache.js","../node_modules/nostr-tools/lib/esm/utils.js","../node_modules/applesauce-core/dist/helpers/event.js","../node_modules/applesauce-core/dist/helpers/time.js","../node_modules/applesauce-core/dist/helpers/expiration.js","../node_modules/nostr-tools/lib/esm/nip19.js","../node_modules/applesauce-core/dist/helpers/url.js","../node_modules/applesauce-core/dist/helpers/relays.js","../node_modules/applesauce-core/dist/helpers/string.js","../node_modules/@noble/hashes/esm/crypto.js","../node_modules/@noble/hashes/esm/utils.js","../node_modules/applesauce-core/dist/helpers/pointers.js","../node_modules/applesauce-core/dist/helpers/groups.js","../node_modules/applesauce-core/dist/helpers/encrypted-content.js","../node_modules/applesauce-core/dist/helpers/hidden-content.js","../node_modules/applesauce-core/dist/helpers/hidden-tags.js","../node_modules/applesauce-core/dist/helpers/event-tags.js","../node_modules/applesauce-core/dist/helpers/lru.js","../node_modules/ms/index.js","../node_modules/debug/src/common.js","../node_modules/debug/src/browser.js","../node_modules/applesauce-core/dist/logger.js","../node_modules/applesauce-core/dist/event-store/event-memory.js","../node_modules/hash-sum/hash-sum.js","../node_modules/applesauce-core/dist/helpers/filter.js","../node_modules/applesauce-core/dist/models/blossom.js","../node_modules/applesauce-core/dist/helpers/blossom.js","../node_modules/applesauce-core/dist/helpers/profile.js","../node_modules/applesauce-core/dist/helpers/json.js","../node_modules/light-bolt11-decoder/node_modules/@scure/base/lib/index.js","../node_modules/light-bolt11-decoder/bolt11.js","../node_modules/applesauce-core/dist/helpers/comment.js","../node_modules/applesauce-core/dist/helpers/contacts.js","../node_modules/@scure/base/lib/esm/index.js","../node_modules/applesauce-core/dist/helpers/encrypted-content-cache.js","../node_modules/applesauce-core/dist/helpers/event-cache.js","../node_modules/applesauce-core/dist/helpers/lnurl.js","../node_modules/applesauce-core/dist/helpers/mailboxes.js","../node_modules/applesauce-core/dist/helpers/mutes.js","../node_modules/applesauce-core/dist/helpers/reports.js","../node_modules/applesauce-core/dist/helpers/threading.js","../node_modules/applesauce-core/dist/observable/claim-events.js","../node_modules/applesauce-core/dist/observable/claim-latest.js","../node_modules/applesauce-core/dist/observable/defined.js","../node_modules/applesauce-core/dist/observable/with-immediate-value.js","../node_modules/applesauce-core/dist/models/common.js","../node_modules/rxjs/dist/esm5/internal/operators/ignoreElements.js","../node_modules/rxjs/dist/esm5/internal/operators/takeUntil.js","../node_modules/rxjs/dist/esm5/internal/operators/repeat.js","../node_modules/applesauce-core/dist/observable/watch-event-updates.js","../node_modules/applesauce-core/dist/models/contacts.js","../node_modules/applesauce-core/dist/models/comments.js","../node_modules/applesauce-core/dist/models/mailboxes.js","../node_modules/applesauce-core/dist/models/mutes.js","../node_modules/applesauce-core/dist/models/profile.js","../node_modules/applesauce-core/dist/models/reactions.js","../node_modules/applesauce-core/dist/models/thread.js","../node_modules/applesauce-core/dist/event-store/model-mixin.js","../node_modules/applesauce-core/dist/event-store/event-store.js","../node_modules/applesauce-core/dist/helpers/delete.js","../node_modules/applesauce-core/dist/promise/deferred.js","../node_modules/applesauce-signers/dist/signers/amber-clipboard-signer.js","../node_modules/applesauce-signers/dist/helpers/nostr-connect.js","../node_modules/applesauce-signers/dist/signers/private-key-signer.js","../node_modules/@noble/secp256k1/lib/esm/index.js","../node_modules/applesauce-signers/dist/signers/serial-port-signer.js","../src/constants.js","../src/nostr.js","../node_modules/hash-wasm/dist/index.esm.js","../src/nsec-crypto.js","../src/LoginModal.svelte","../src/ManagedACL.svelte","../src/Header.svelte","../src/Sidebar.svelte","../src/ExportView.svelte","../src/ImportView.svelte","../src/helpers.tsx","../src/FilterBuilder.svelte","../src/EventsView.svelte","../src/eventKinds.js","../src/EventTemplateSelector.svelte","../src/ComposeView.svelte","../src/SprocketView.svelte","../src/PolicyView.svelte","../src/BlossomView.svelte","../src/FilterDisplay.svelte","../src/utils.js","../src/websocket-auth.js","../src/App.svelte","../src/api.js","../src/main.js"],"sourcesContent":["function noop() { }\nconst identity = x => x;\nfunction assign(tar, src) {\n // @ts-ignore\n for (const k in src)\n tar[k] = src[k];\n return tar;\n}\n// Adapted from https://github.com/then/is-promise/blob/master/index.js\n// Distributed under MIT License https://github.com/then/is-promise/blob/master/LICENSE\nfunction is_promise(value) {\n return !!value && (typeof value === 'object' || typeof value === 'function') && typeof value.then === 'function';\n}\nfunction add_location(element, file, line, column, char) {\n element.__svelte_meta = {\n loc: { file, line, column, char }\n };\n}\nfunction run(fn) {\n return fn();\n}\nfunction blank_object() {\n return Object.create(null);\n}\nfunction run_all(fns) {\n fns.forEach(run);\n}\nfunction is_function(thing) {\n return typeof thing === 'function';\n}\nfunction safe_not_equal(a, b) {\n return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');\n}\nlet src_url_equal_anchor;\nfunction src_url_equal(element_src, url) {\n if (!src_url_equal_anchor) {\n src_url_equal_anchor = document.createElement('a');\n }\n src_url_equal_anchor.href = url;\n return element_src === src_url_equal_anchor.href;\n}\nfunction not_equal(a, b) {\n return a != a ? b == b : a !== b;\n}\nfunction is_empty(obj) {\n return Object.keys(obj).length === 0;\n}\nfunction validate_store(store, name) {\n if (store != null && typeof store.subscribe !== 'function') {\n throw new Error(`'${name}' is not a store with a 'subscribe' method`);\n }\n}\nfunction subscribe(store, ...callbacks) {\n if (store == null) {\n return noop;\n }\n const unsub = store.subscribe(...callbacks);\n return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;\n}\nfunction get_store_value(store) {\n let value;\n subscribe(store, _ => value = _)();\n return value;\n}\nfunction component_subscribe(component, store, callback) {\n component.$$.on_destroy.push(subscribe(store, callback));\n}\nfunction create_slot(definition, ctx, $$scope, fn) {\n if (definition) {\n const slot_ctx = get_slot_context(definition, ctx, $$scope, fn);\n return definition[0](slot_ctx);\n }\n}\nfunction get_slot_context(definition, ctx, $$scope, fn) {\n return definition[1] && fn\n ? assign($$scope.ctx.slice(), definition[1](fn(ctx)))\n : $$scope.ctx;\n}\nfunction get_slot_changes(definition, $$scope, dirty, fn) {\n if (definition[2] && fn) {\n const lets = definition[2](fn(dirty));\n if ($$scope.dirty === undefined) {\n return lets;\n }\n if (typeof lets === 'object') {\n const merged = [];\n const len = Math.max($$scope.dirty.length, lets.length);\n for (let i = 0; i < len; i += 1) {\n merged[i] = $$scope.dirty[i] | lets[i];\n }\n return merged;\n }\n return $$scope.dirty | lets;\n }\n return $$scope.dirty;\n}\nfunction update_slot_base(slot, slot_definition, ctx, $$scope, slot_changes, get_slot_context_fn) {\n if (slot_changes) {\n const slot_context = get_slot_context(slot_definition, ctx, $$scope, get_slot_context_fn);\n slot.p(slot_context, slot_changes);\n }\n}\nfunction update_slot(slot, slot_definition, ctx, $$scope, dirty, get_slot_changes_fn, get_slot_context_fn) {\n const slot_changes = get_slot_changes(slot_definition, $$scope, dirty, get_slot_changes_fn);\n update_slot_base(slot, slot_definition, ctx, $$scope, slot_changes, get_slot_context_fn);\n}\nfunction get_all_dirty_from_scope($$scope) {\n if ($$scope.ctx.length > 32) {\n const dirty = [];\n const length = $$scope.ctx.length / 32;\n for (let i = 0; i < length; i++) {\n dirty[i] = -1;\n }\n return dirty;\n }\n return -1;\n}\nfunction exclude_internal_props(props) {\n const result = {};\n for (const k in props)\n if (k[0] !== '$')\n result[k] = props[k];\n return result;\n}\nfunction compute_rest_props(props, keys) {\n const rest = {};\n keys = new Set(keys);\n for (const k in props)\n if (!keys.has(k) && k[0] !== '$')\n rest[k] = props[k];\n return rest;\n}\nfunction compute_slots(slots) {\n const result = {};\n for (const key in slots) {\n result[key] = true;\n }\n return result;\n}\nfunction once(fn) {\n let ran = false;\n return function (...args) {\n if (ran)\n return;\n ran = true;\n fn.call(this, ...args);\n };\n}\nfunction null_to_empty(value) {\n return value == null ? '' : value;\n}\nfunction set_store_value(store, ret, value) {\n store.set(value);\n return ret;\n}\nconst has_prop = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);\nfunction action_destroyer(action_result) {\n return action_result && is_function(action_result.destroy) ? action_result.destroy : noop;\n}\nfunction split_css_unit(value) {\n const split = typeof value === 'string' && value.match(/^\\s*(-?[\\d.]+)([^\\s]*)\\s*$/);\n return split ? [parseFloat(split[1]), split[2] || 'px'] : [value, 'px'];\n}\nconst contenteditable_truthy_values = ['', true, 1, 'true', 'contenteditable'];\n\nconst is_client = typeof window !== 'undefined';\nlet now = is_client\n ? () => window.performance.now()\n : () => Date.now();\nlet raf = is_client ? cb => requestAnimationFrame(cb) : noop;\n// used internally for testing\nfunction set_now(fn) {\n now = fn;\n}\nfunction set_raf(fn) {\n raf = fn;\n}\n\nconst tasks = new Set();\nfunction run_tasks(now) {\n tasks.forEach(task => {\n if (!task.c(now)) {\n tasks.delete(task);\n task.f();\n }\n });\n if (tasks.size !== 0)\n raf(run_tasks);\n}\n/**\n * For testing purposes only!\n */\nfunction clear_loops() {\n tasks.clear();\n}\n/**\n * Creates a new task that runs on each raf frame\n * until it returns a falsy value or is aborted\n */\nfunction loop(callback) {\n let task;\n if (tasks.size === 0)\n raf(run_tasks);\n return {\n promise: new Promise(fulfill => {\n tasks.add(task = { c: callback, f: fulfill });\n }),\n abort() {\n tasks.delete(task);\n }\n };\n}\n\nconst globals = (typeof window !== 'undefined'\n ? window\n : typeof globalThis !== 'undefined'\n ? globalThis\n : global);\n\n/**\n * Resize observer singleton.\n * One listener per element only!\n * https://groups.google.com/a/chromium.org/g/blink-dev/c/z6ienONUb5A/m/F5-VcUZtBAAJ\n */\nclass ResizeObserverSingleton {\n constructor(options) {\n this.options = options;\n this._listeners = 'WeakMap' in globals ? new WeakMap() : undefined;\n }\n observe(element, listener) {\n this._listeners.set(element, listener);\n this._getObserver().observe(element, this.options);\n return () => {\n this._listeners.delete(element);\n this._observer.unobserve(element); // this line can probably be removed\n };\n }\n _getObserver() {\n var _a;\n return (_a = this._observer) !== null && _a !== void 0 ? _a : (this._observer = new ResizeObserver((entries) => {\n var _a;\n for (const entry of entries) {\n ResizeObserverSingleton.entries.set(entry.target, entry);\n (_a = this._listeners.get(entry.target)) === null || _a === void 0 ? void 0 : _a(entry);\n }\n }));\n }\n}\n// Needs to be written like this to pass the tree-shake-test\nResizeObserverSingleton.entries = 'WeakMap' in globals ? new WeakMap() : undefined;\n\n// Track which nodes are claimed during hydration. Unclaimed nodes can then be removed from the DOM\n// at the end of hydration without touching the remaining nodes.\nlet is_hydrating = false;\nfunction start_hydrating() {\n is_hydrating = true;\n}\nfunction end_hydrating() {\n is_hydrating = false;\n}\nfunction upper_bound(low, high, key, value) {\n // Return first index of value larger than input value in the range [low, high)\n while (low < high) {\n const mid = low + ((high - low) >> 1);\n if (key(mid) <= value) {\n low = mid + 1;\n }\n else {\n high = mid;\n }\n }\n return low;\n}\nfunction init_hydrate(target) {\n if (target.hydrate_init)\n return;\n target.hydrate_init = true;\n // We know that all children have claim_order values since the unclaimed have been detached if target is not \n let children = target.childNodes;\n // If target is , there may be children without claim_order\n if (target.nodeName === 'HEAD') {\n const myChildren = [];\n for (let i = 0; i < children.length; i++) {\n const node = children[i];\n if (node.claim_order !== undefined) {\n myChildren.push(node);\n }\n }\n children = myChildren;\n }\n /*\n * Reorder claimed children optimally.\n * We can reorder claimed children optimally by finding the longest subsequence of\n * nodes that are already claimed in order and only moving the rest. The longest\n * subsequence of nodes that are claimed in order can be found by\n * computing the longest increasing subsequence of .claim_order values.\n *\n * This algorithm is optimal in generating the least amount of reorder operations\n * possible.\n *\n * Proof:\n * We know that, given a set of reordering operations, the nodes that do not move\n * always form an increasing subsequence, since they do not move among each other\n * meaning that they must be already ordered among each other. Thus, the maximal\n * set of nodes that do not move form a longest increasing subsequence.\n */\n // Compute longest increasing subsequence\n // m: subsequence length j => index k of smallest value that ends an increasing subsequence of length j\n const m = new Int32Array(children.length + 1);\n // Predecessor indices + 1\n const p = new Int32Array(children.length);\n m[0] = -1;\n let longest = 0;\n for (let i = 0; i < children.length; i++) {\n const current = children[i].claim_order;\n // Find the largest subsequence length such that it ends in a value less than our current value\n // upper_bound returns first greater value, so we subtract one\n // with fast path for when we are on the current longest subsequence\n const seqLen = ((longest > 0 && children[m[longest]].claim_order <= current) ? longest + 1 : upper_bound(1, longest, idx => children[m[idx]].claim_order, current)) - 1;\n p[i] = m[seqLen] + 1;\n const newLen = seqLen + 1;\n // We can guarantee that current is the smallest value. Otherwise, we would have generated a longer sequence.\n m[newLen] = i;\n longest = Math.max(newLen, longest);\n }\n // The longest increasing subsequence of nodes (initially reversed)\n const lis = [];\n // The rest of the nodes, nodes that will be moved\n const toMove = [];\n let last = children.length - 1;\n for (let cur = m[longest] + 1; cur != 0; cur = p[cur - 1]) {\n lis.push(children[cur - 1]);\n for (; last >= cur; last--) {\n toMove.push(children[last]);\n }\n last--;\n }\n for (; last >= 0; last--) {\n toMove.push(children[last]);\n }\n lis.reverse();\n // We sort the nodes being moved to guarantee that their insertion order matches the claim order\n toMove.sort((a, b) => a.claim_order - b.claim_order);\n // Finally, we move the nodes\n for (let i = 0, j = 0; i < toMove.length; i++) {\n while (j < lis.length && toMove[i].claim_order >= lis[j].claim_order) {\n j++;\n }\n const anchor = j < lis.length ? lis[j] : null;\n target.insertBefore(toMove[i], anchor);\n }\n}\nfunction append(target, node) {\n target.appendChild(node);\n}\nfunction append_styles(target, style_sheet_id, styles) {\n const append_styles_to = get_root_for_style(target);\n if (!append_styles_to.getElementById(style_sheet_id)) {\n const style = element('style');\n style.id = style_sheet_id;\n style.textContent = styles;\n append_stylesheet(append_styles_to, style);\n }\n}\nfunction get_root_for_style(node) {\n if (!node)\n return document;\n const root = node.getRootNode ? node.getRootNode() : node.ownerDocument;\n if (root && root.host) {\n return root;\n }\n return node.ownerDocument;\n}\nfunction append_empty_stylesheet(node) {\n const style_element = element('style');\n append_stylesheet(get_root_for_style(node), style_element);\n return style_element.sheet;\n}\nfunction append_stylesheet(node, style) {\n append(node.head || node, style);\n return style.sheet;\n}\nfunction append_hydration(target, node) {\n if (is_hydrating) {\n init_hydrate(target);\n if ((target.actual_end_child === undefined) || ((target.actual_end_child !== null) && (target.actual_end_child.parentNode !== target))) {\n target.actual_end_child = target.firstChild;\n }\n // Skip nodes of undefined ordering\n while ((target.actual_end_child !== null) && (target.actual_end_child.claim_order === undefined)) {\n target.actual_end_child = target.actual_end_child.nextSibling;\n }\n if (node !== target.actual_end_child) {\n // We only insert if the ordering of this node should be modified or the parent node is not target\n if (node.claim_order !== undefined || node.parentNode !== target) {\n target.insertBefore(node, target.actual_end_child);\n }\n }\n else {\n target.actual_end_child = node.nextSibling;\n }\n }\n else if (node.parentNode !== target || node.nextSibling !== null) {\n target.appendChild(node);\n }\n}\nfunction insert(target, node, anchor) {\n target.insertBefore(node, anchor || null);\n}\nfunction insert_hydration(target, node, anchor) {\n if (is_hydrating && !anchor) {\n append_hydration(target, node);\n }\n else if (node.parentNode !== target || node.nextSibling != anchor) {\n target.insertBefore(node, anchor || null);\n }\n}\nfunction detach(node) {\n if (node.parentNode) {\n node.parentNode.removeChild(node);\n }\n}\nfunction destroy_each(iterations, detaching) {\n for (let i = 0; i < iterations.length; i += 1) {\n if (iterations[i])\n iterations[i].d(detaching);\n }\n}\nfunction element(name) {\n return document.createElement(name);\n}\nfunction element_is(name, is) {\n return document.createElement(name, { is });\n}\nfunction object_without_properties(obj, exclude) {\n const target = {};\n for (const k in obj) {\n if (has_prop(obj, k)\n // @ts-ignore\n && exclude.indexOf(k) === -1) {\n // @ts-ignore\n target[k] = obj[k];\n }\n }\n return target;\n}\nfunction svg_element(name) {\n return document.createElementNS('http://www.w3.org/2000/svg', name);\n}\nfunction text(data) {\n return document.createTextNode(data);\n}\nfunction space() {\n return text(' ');\n}\nfunction empty() {\n return text('');\n}\nfunction comment(content) {\n return document.createComment(content);\n}\nfunction listen(node, event, handler, options) {\n node.addEventListener(event, handler, options);\n return () => node.removeEventListener(event, handler, options);\n}\nfunction prevent_default(fn) {\n return function (event) {\n event.preventDefault();\n // @ts-ignore\n return fn.call(this, event);\n };\n}\nfunction stop_propagation(fn) {\n return function (event) {\n event.stopPropagation();\n // @ts-ignore\n return fn.call(this, event);\n };\n}\nfunction stop_immediate_propagation(fn) {\n return function (event) {\n event.stopImmediatePropagation();\n // @ts-ignore\n return fn.call(this, event);\n };\n}\nfunction self(fn) {\n return function (event) {\n // @ts-ignore\n if (event.target === this)\n fn.call(this, event);\n };\n}\nfunction trusted(fn) {\n return function (event) {\n // @ts-ignore\n if (event.isTrusted)\n fn.call(this, event);\n };\n}\nfunction attr(node, attribute, value) {\n if (value == null)\n node.removeAttribute(attribute);\n else if (node.getAttribute(attribute) !== value)\n node.setAttribute(attribute, value);\n}\n/**\n * List of attributes that should always be set through the attr method,\n * because updating them through the property setter doesn't work reliably.\n * In the example of `width`/`height`, the problem is that the setter only\n * accepts numeric values, but the attribute can also be set to a string like `50%`.\n * If this list becomes too big, rethink this approach.\n */\nconst always_set_through_set_attribute = ['width', 'height'];\nfunction set_attributes(node, attributes) {\n // @ts-ignore\n const descriptors = Object.getOwnPropertyDescriptors(node.__proto__);\n for (const key in attributes) {\n if (attributes[key] == null) {\n node.removeAttribute(key);\n }\n else if (key === 'style') {\n node.style.cssText = attributes[key];\n }\n else if (key === '__value') {\n node.value = node[key] = attributes[key];\n }\n else if (descriptors[key] && descriptors[key].set && always_set_through_set_attribute.indexOf(key) === -1) {\n node[key] = attributes[key];\n }\n else {\n attr(node, key, attributes[key]);\n }\n }\n}\nfunction set_svg_attributes(node, attributes) {\n for (const key in attributes) {\n attr(node, key, attributes[key]);\n }\n}\nfunction set_custom_element_data_map(node, data_map) {\n Object.keys(data_map).forEach((key) => {\n set_custom_element_data(node, key, data_map[key]);\n });\n}\nfunction set_custom_element_data(node, prop, value) {\n if (prop in node) {\n node[prop] = typeof node[prop] === 'boolean' && value === '' ? true : value;\n }\n else {\n attr(node, prop, value);\n }\n}\nfunction set_dynamic_element_data(tag) {\n return (/-/.test(tag)) ? set_custom_element_data_map : set_attributes;\n}\nfunction xlink_attr(node, attribute, value) {\n node.setAttributeNS('http://www.w3.org/1999/xlink', attribute, value);\n}\nfunction get_binding_group_value(group, __value, checked) {\n const value = new Set();\n for (let i = 0; i < group.length; i += 1) {\n if (group[i].checked)\n value.add(group[i].__value);\n }\n if (!checked) {\n value.delete(__value);\n }\n return Array.from(value);\n}\nfunction init_binding_group(group) {\n let _inputs;\n return {\n /* push */ p(...inputs) {\n _inputs = inputs;\n _inputs.forEach(input => group.push(input));\n },\n /* remove */ r() {\n _inputs.forEach(input => group.splice(group.indexOf(input), 1));\n }\n };\n}\nfunction init_binding_group_dynamic(group, indexes) {\n let _group = get_binding_group(group);\n let _inputs;\n function get_binding_group(group) {\n for (let i = 0; i < indexes.length; i++) {\n group = group[indexes[i]] = group[indexes[i]] || [];\n }\n return group;\n }\n function push() {\n _inputs.forEach(input => _group.push(input));\n }\n function remove() {\n _inputs.forEach(input => _group.splice(_group.indexOf(input), 1));\n }\n return {\n /* update */ u(new_indexes) {\n indexes = new_indexes;\n const new_group = get_binding_group(group);\n if (new_group !== _group) {\n remove();\n _group = new_group;\n push();\n }\n },\n /* push */ p(...inputs) {\n _inputs = inputs;\n push();\n },\n /* remove */ r: remove\n };\n}\nfunction to_number(value) {\n return value === '' ? null : +value;\n}\nfunction time_ranges_to_array(ranges) {\n const array = [];\n for (let i = 0; i < ranges.length; i += 1) {\n array.push({ start: ranges.start(i), end: ranges.end(i) });\n }\n return array;\n}\nfunction children(element) {\n return Array.from(element.childNodes);\n}\nfunction init_claim_info(nodes) {\n if (nodes.claim_info === undefined) {\n nodes.claim_info = { last_index: 0, total_claimed: 0 };\n }\n}\nfunction claim_node(nodes, predicate, processNode, createNode, dontUpdateLastIndex = false) {\n // Try to find nodes in an order such that we lengthen the longest increasing subsequence\n init_claim_info(nodes);\n const resultNode = (() => {\n // We first try to find an element after the previous one\n for (let i = nodes.claim_info.last_index; i < nodes.length; i++) {\n const node = nodes[i];\n if (predicate(node)) {\n const replacement = processNode(node);\n if (replacement === undefined) {\n nodes.splice(i, 1);\n }\n else {\n nodes[i] = replacement;\n }\n if (!dontUpdateLastIndex) {\n nodes.claim_info.last_index = i;\n }\n return node;\n }\n }\n // Otherwise, we try to find one before\n // We iterate in reverse so that we don't go too far back\n for (let i = nodes.claim_info.last_index - 1; i >= 0; i--) {\n const node = nodes[i];\n if (predicate(node)) {\n const replacement = processNode(node);\n if (replacement === undefined) {\n nodes.splice(i, 1);\n }\n else {\n nodes[i] = replacement;\n }\n if (!dontUpdateLastIndex) {\n nodes.claim_info.last_index = i;\n }\n else if (replacement === undefined) {\n // Since we spliced before the last_index, we decrease it\n nodes.claim_info.last_index--;\n }\n return node;\n }\n }\n // If we can't find any matching node, we create a new one\n return createNode();\n })();\n resultNode.claim_order = nodes.claim_info.total_claimed;\n nodes.claim_info.total_claimed += 1;\n return resultNode;\n}\nfunction claim_element_base(nodes, name, attributes, create_element) {\n return claim_node(nodes, (node) => node.nodeName === name, (node) => {\n const remove = [];\n for (let j = 0; j < node.attributes.length; j++) {\n const attribute = node.attributes[j];\n if (!attributes[attribute.name]) {\n remove.push(attribute.name);\n }\n }\n remove.forEach(v => node.removeAttribute(v));\n return undefined;\n }, () => create_element(name));\n}\nfunction claim_element(nodes, name, attributes) {\n return claim_element_base(nodes, name, attributes, element);\n}\nfunction claim_svg_element(nodes, name, attributes) {\n return claim_element_base(nodes, name, attributes, svg_element);\n}\nfunction claim_text(nodes, data) {\n return claim_node(nodes, (node) => node.nodeType === 3, (node) => {\n const dataStr = '' + data;\n if (node.data.startsWith(dataStr)) {\n if (node.data.length !== dataStr.length) {\n return node.splitText(dataStr.length);\n }\n }\n else {\n node.data = dataStr;\n }\n }, () => text(data), true // Text nodes should not update last index since it is likely not worth it to eliminate an increasing subsequence of actual elements\n );\n}\nfunction claim_space(nodes) {\n return claim_text(nodes, ' ');\n}\nfunction claim_comment(nodes, data) {\n return claim_node(nodes, (node) => node.nodeType === 8, (node) => {\n node.data = '' + data;\n return undefined;\n }, () => comment(data), true);\n}\nfunction find_comment(nodes, text, start) {\n for (let i = start; i < nodes.length; i += 1) {\n const node = nodes[i];\n if (node.nodeType === 8 /* comment node */ && node.textContent.trim() === text) {\n return i;\n }\n }\n return nodes.length;\n}\nfunction claim_html_tag(nodes, is_svg) {\n // find html opening tag\n const start_index = find_comment(nodes, 'HTML_TAG_START', 0);\n const end_index = find_comment(nodes, 'HTML_TAG_END', start_index);\n if (start_index === end_index) {\n return new HtmlTagHydration(undefined, is_svg);\n }\n init_claim_info(nodes);\n const html_tag_nodes = nodes.splice(start_index, end_index - start_index + 1);\n detach(html_tag_nodes[0]);\n detach(html_tag_nodes[html_tag_nodes.length - 1]);\n const claimed_nodes = html_tag_nodes.slice(1, html_tag_nodes.length - 1);\n for (const n of claimed_nodes) {\n n.claim_order = nodes.claim_info.total_claimed;\n nodes.claim_info.total_claimed += 1;\n }\n return new HtmlTagHydration(claimed_nodes, is_svg);\n}\nfunction set_data(text, data) {\n data = '' + data;\n if (text.data === data)\n return;\n text.data = data;\n}\nfunction set_data_contenteditable(text, data) {\n data = '' + data;\n if (text.wholeText === data)\n return;\n text.data = data;\n}\nfunction set_data_maybe_contenteditable(text, data, attr_value) {\n if (~contenteditable_truthy_values.indexOf(attr_value)) {\n set_data_contenteditable(text, data);\n }\n else {\n set_data(text, data);\n }\n}\nfunction set_input_value(input, value) {\n input.value = value == null ? '' : value;\n}\nfunction set_input_type(input, type) {\n try {\n input.type = type;\n }\n catch (e) {\n // do nothing\n }\n}\nfunction set_style(node, key, value, important) {\n if (value == null) {\n node.style.removeProperty(key);\n }\n else {\n node.style.setProperty(key, value, important ? 'important' : '');\n }\n}\nfunction select_option(select, value, mounting) {\n for (let i = 0; i < select.options.length; i += 1) {\n const option = select.options[i];\n if (option.__value === value) {\n option.selected = true;\n return;\n }\n }\n if (!mounting || value !== undefined) {\n select.selectedIndex = -1; // no option should be selected\n }\n}\nfunction select_options(select, value) {\n for (let i = 0; i < select.options.length; i += 1) {\n const option = select.options[i];\n option.selected = ~value.indexOf(option.__value);\n }\n}\nfunction select_value(select) {\n const selected_option = select.querySelector(':checked');\n return selected_option && selected_option.__value;\n}\nfunction select_multiple_value(select) {\n return [].map.call(select.querySelectorAll(':checked'), option => option.__value);\n}\n// unfortunately this can't be a constant as that wouldn't be tree-shakeable\n// so we cache the result instead\nlet crossorigin;\nfunction is_crossorigin() {\n if (crossorigin === undefined) {\n crossorigin = false;\n try {\n if (typeof window !== 'undefined' && window.parent) {\n void window.parent.document;\n }\n }\n catch (error) {\n crossorigin = true;\n }\n }\n return crossorigin;\n}\nfunction add_iframe_resize_listener(node, fn) {\n const computed_style = getComputedStyle(node);\n if (computed_style.position === 'static') {\n node.style.position = 'relative';\n }\n const iframe = element('iframe');\n iframe.setAttribute('style', 'display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; ' +\n 'overflow: hidden; border: 0; opacity: 0; pointer-events: none; z-index: -1;');\n iframe.setAttribute('aria-hidden', 'true');\n iframe.tabIndex = -1;\n const crossorigin = is_crossorigin();\n let unsubscribe;\n if (crossorigin) {\n iframe.src = \"data:text/html,\";\n unsubscribe = listen(window, 'message', (event) => {\n if (event.source === iframe.contentWindow)\n fn();\n });\n }\n else {\n iframe.src = 'about:blank';\n iframe.onload = () => {\n unsubscribe = listen(iframe.contentWindow, 'resize', fn);\n // make sure an initial resize event is fired _after_ the iframe is loaded (which is asynchronous)\n // see https://github.com/sveltejs/svelte/issues/4233\n fn();\n };\n }\n append(node, iframe);\n return () => {\n if (crossorigin) {\n unsubscribe();\n }\n else if (unsubscribe && iframe.contentWindow) {\n unsubscribe();\n }\n detach(iframe);\n };\n}\nconst resize_observer_content_box = /* @__PURE__ */ new ResizeObserverSingleton({ box: 'content-box' });\nconst resize_observer_border_box = /* @__PURE__ */ new ResizeObserverSingleton({ box: 'border-box' });\nconst resize_observer_device_pixel_content_box = /* @__PURE__ */ new ResizeObserverSingleton({ box: 'device-pixel-content-box' });\nfunction toggle_class(element, name, toggle) {\n element.classList[toggle ? 'add' : 'remove'](name);\n}\nfunction custom_event(type, detail, { bubbles = false, cancelable = false } = {}) {\n const e = document.createEvent('CustomEvent');\n e.initCustomEvent(type, bubbles, cancelable, detail);\n return e;\n}\nfunction query_selector_all(selector, parent = document.body) {\n return Array.from(parent.querySelectorAll(selector));\n}\nfunction head_selector(nodeId, head) {\n const result = [];\n let started = 0;\n for (const node of head.childNodes) {\n if (node.nodeType === 8 /* comment node */) {\n const comment = node.textContent.trim();\n if (comment === `HEAD_${nodeId}_END`) {\n started -= 1;\n result.push(node);\n }\n else if (comment === `HEAD_${nodeId}_START`) {\n started += 1;\n result.push(node);\n }\n }\n else if (started > 0) {\n result.push(node);\n }\n }\n return result;\n}\nclass HtmlTag {\n constructor(is_svg = false) {\n this.is_svg = false;\n this.is_svg = is_svg;\n this.e = this.n = null;\n }\n c(html) {\n this.h(html);\n }\n m(html, target, anchor = null) {\n if (!this.e) {\n if (this.is_svg)\n this.e = svg_element(target.nodeName);\n /** #7364 target for may be provided as #document-fragment(11) */\n else\n this.e = element((target.nodeType === 11 ? 'TEMPLATE' : target.nodeName));\n this.t = target.tagName !== 'TEMPLATE' ? target : target.content;\n this.c(html);\n }\n this.i(anchor);\n }\n h(html) {\n this.e.innerHTML = html;\n this.n = Array.from(this.e.nodeName === 'TEMPLATE' ? this.e.content.childNodes : this.e.childNodes);\n }\n i(anchor) {\n for (let i = 0; i < this.n.length; i += 1) {\n insert(this.t, this.n[i], anchor);\n }\n }\n p(html) {\n this.d();\n this.h(html);\n this.i(this.a);\n }\n d() {\n this.n.forEach(detach);\n }\n}\nclass HtmlTagHydration extends HtmlTag {\n constructor(claimed_nodes, is_svg = false) {\n super(is_svg);\n this.e = this.n = null;\n this.l = claimed_nodes;\n }\n c(html) {\n if (this.l) {\n this.n = this.l;\n }\n else {\n super.c(html);\n }\n }\n i(anchor) {\n for (let i = 0; i < this.n.length; i += 1) {\n insert_hydration(this.t, this.n[i], anchor);\n }\n }\n}\nfunction attribute_to_object(attributes) {\n const result = {};\n for (const attribute of attributes) {\n result[attribute.name] = attribute.value;\n }\n return result;\n}\nfunction get_custom_elements_slots(element) {\n const result = {};\n element.childNodes.forEach((node) => {\n result[node.slot || 'default'] = true;\n });\n return result;\n}\nfunction construct_svelte_component(component, props) {\n return new component(props);\n}\n\n// we need to store the information for multiple documents because a Svelte application could also contain iframes\n// https://github.com/sveltejs/svelte/issues/3624\nconst managed_styles = new Map();\nlet active = 0;\n// https://github.com/darkskyapp/string-hash/blob/master/index.js\nfunction hash(str) {\n let hash = 5381;\n let i = str.length;\n while (i--)\n hash = ((hash << 5) - hash) ^ str.charCodeAt(i);\n return hash >>> 0;\n}\nfunction create_style_information(doc, node) {\n const info = { stylesheet: append_empty_stylesheet(node), rules: {} };\n managed_styles.set(doc, info);\n return info;\n}\nfunction create_rule(node, a, b, duration, delay, ease, fn, uid = 0) {\n const step = 16.666 / duration;\n let keyframes = '{\\n';\n for (let p = 0; p <= 1; p += step) {\n const t = a + (b - a) * ease(p);\n keyframes += p * 100 + `%{${fn(t, 1 - t)}}\\n`;\n }\n const rule = keyframes + `100% {${fn(b, 1 - b)}}\\n}`;\n const name = `__svelte_${hash(rule)}_${uid}`;\n const doc = get_root_for_style(node);\n const { stylesheet, rules } = managed_styles.get(doc) || create_style_information(doc, node);\n if (!rules[name]) {\n rules[name] = true;\n stylesheet.insertRule(`@keyframes ${name} ${rule}`, stylesheet.cssRules.length);\n }\n const animation = node.style.animation || '';\n node.style.animation = `${animation ? `${animation}, ` : ''}${name} ${duration}ms linear ${delay}ms 1 both`;\n active += 1;\n return name;\n}\nfunction delete_rule(node, name) {\n const previous = (node.style.animation || '').split(', ');\n const next = previous.filter(name\n ? anim => anim.indexOf(name) < 0 // remove specific animation\n : anim => anim.indexOf('__svelte') === -1 // remove all Svelte animations\n );\n const deleted = previous.length - next.length;\n if (deleted) {\n node.style.animation = next.join(', ');\n active -= deleted;\n if (!active)\n clear_rules();\n }\n}\nfunction clear_rules() {\n raf(() => {\n if (active)\n return;\n managed_styles.forEach(info => {\n const { ownerNode } = info.stylesheet;\n // there is no ownerNode if it runs on jsdom.\n if (ownerNode)\n detach(ownerNode);\n });\n managed_styles.clear();\n });\n}\n\nfunction create_animation(node, from, fn, params) {\n if (!from)\n return noop;\n const to = node.getBoundingClientRect();\n if (from.left === to.left && from.right === to.right && from.top === to.top && from.bottom === to.bottom)\n return noop;\n const { delay = 0, duration = 300, easing = identity, \n // @ts-ignore todo: should this be separated from destructuring? Or start/end added to public api and documentation?\n start: start_time = now() + delay, \n // @ts-ignore todo:\n end = start_time + duration, tick = noop, css } = fn(node, { from, to }, params);\n let running = true;\n let started = false;\n let name;\n function start() {\n if (css) {\n name = create_rule(node, 0, 1, duration, delay, easing, css);\n }\n if (!delay) {\n started = true;\n }\n }\n function stop() {\n if (css)\n delete_rule(node, name);\n running = false;\n }\n loop(now => {\n if (!started && now >= start_time) {\n started = true;\n }\n if (started && now >= end) {\n tick(1, 0);\n stop();\n }\n if (!running) {\n return false;\n }\n if (started) {\n const p = now - start_time;\n const t = 0 + 1 * easing(p / duration);\n tick(t, 1 - t);\n }\n return true;\n });\n start();\n tick(0, 1);\n return stop;\n}\nfunction fix_position(node) {\n const style = getComputedStyle(node);\n if (style.position !== 'absolute' && style.position !== 'fixed') {\n const { width, height } = style;\n const a = node.getBoundingClientRect();\n node.style.position = 'absolute';\n node.style.width = width;\n node.style.height = height;\n add_transform(node, a);\n }\n}\nfunction add_transform(node, a) {\n const b = node.getBoundingClientRect();\n if (a.left !== b.left || a.top !== b.top) {\n const style = getComputedStyle(node);\n const transform = style.transform === 'none' ? '' : style.transform;\n node.style.transform = `${transform} translate(${a.left - b.left}px, ${a.top - b.top}px)`;\n }\n}\n\nlet current_component;\nfunction set_current_component(component) {\n current_component = component;\n}\nfunction get_current_component() {\n if (!current_component)\n throw new Error('Function called outside component initialization');\n return current_component;\n}\n/**\n * Schedules a callback to run immediately before the component is updated after any state change.\n *\n * The first time the callback runs will be before the initial `onMount`\n *\n * https://svelte.dev/docs#run-time-svelte-beforeupdate\n */\nfunction beforeUpdate(fn) {\n get_current_component().$$.before_update.push(fn);\n}\n/**\n * The `onMount` function schedules a callback to run as soon as the component has been mounted to the DOM.\n * It must be called during the component's initialisation (but doesn't need to live *inside* the component;\n * it can be called from an external module).\n *\n * `onMount` does not run inside a [server-side component](/docs#run-time-server-side-component-api).\n *\n * https://svelte.dev/docs#run-time-svelte-onmount\n */\nfunction onMount(fn) {\n get_current_component().$$.on_mount.push(fn);\n}\n/**\n * Schedules a callback to run immediately after the component has been updated.\n *\n * The first time the callback runs will be after the initial `onMount`\n */\nfunction afterUpdate(fn) {\n get_current_component().$$.after_update.push(fn);\n}\n/**\n * Schedules a callback to run immediately before the component is unmounted.\n *\n * Out of `onMount`, `beforeUpdate`, `afterUpdate` and `onDestroy`, this is the\n * only one that runs inside a server-side component.\n *\n * https://svelte.dev/docs#run-time-svelte-ondestroy\n */\nfunction onDestroy(fn) {\n get_current_component().$$.on_destroy.push(fn);\n}\n/**\n * Creates an event dispatcher that can be used to dispatch [component events](/docs#template-syntax-component-directives-on-eventname).\n * Event dispatchers are functions that can take two arguments: `name` and `detail`.\n *\n * Component events created with `createEventDispatcher` create a\n * [CustomEvent](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent).\n * These events do not [bubble](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_bubbling_and_capture).\n * The `detail` argument corresponds to the [CustomEvent.detail](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail)\n * property and can contain any type of data.\n *\n * https://svelte.dev/docs#run-time-svelte-createeventdispatcher\n */\nfunction createEventDispatcher() {\n const component = get_current_component();\n return (type, detail, { cancelable = false } = {}) => {\n const callbacks = component.$$.callbacks[type];\n if (callbacks) {\n // TODO are there situations where events could be dispatched\n // in a server (non-DOM) environment?\n const event = custom_event(type, detail, { cancelable });\n callbacks.slice().forEach(fn => {\n fn.call(component, event);\n });\n return !event.defaultPrevented;\n }\n return true;\n };\n}\n/**\n * Associates an arbitrary `context` object with the current component and the specified `key`\n * and returns that object. The context is then available to children of the component\n * (including slotted content) with `getContext`.\n *\n * Like lifecycle functions, this must be called during component initialisation.\n *\n * https://svelte.dev/docs#run-time-svelte-setcontext\n */\nfunction setContext(key, context) {\n get_current_component().$$.context.set(key, context);\n return context;\n}\n/**\n * Retrieves the context that belongs to the closest parent component with the specified `key`.\n * Must be called during component initialisation.\n *\n * https://svelte.dev/docs#run-time-svelte-getcontext\n */\nfunction getContext(key) {\n return get_current_component().$$.context.get(key);\n}\n/**\n * Retrieves the whole context map that belongs to the closest parent component.\n * Must be called during component initialisation. Useful, for example, if you\n * programmatically create a component and want to pass the existing context to it.\n *\n * https://svelte.dev/docs#run-time-svelte-getallcontexts\n */\nfunction getAllContexts() {\n return get_current_component().$$.context;\n}\n/**\n * Checks whether a given `key` has been set in the context of a parent component.\n * Must be called during component initialisation.\n *\n * https://svelte.dev/docs#run-time-svelte-hascontext\n */\nfunction hasContext(key) {\n return get_current_component().$$.context.has(key);\n}\n// TODO figure out if we still want to support\n// shorthand events, or if we want to implement\n// a real bubbling mechanism\nfunction bubble(component, event) {\n const callbacks = component.$$.callbacks[event.type];\n if (callbacks) {\n // @ts-ignore\n callbacks.slice().forEach(fn => fn.call(this, event));\n }\n}\n\nconst dirty_components = [];\nconst intros = { enabled: false };\nconst binding_callbacks = [];\nlet render_callbacks = [];\nconst flush_callbacks = [];\nconst resolved_promise = /* @__PURE__ */ Promise.resolve();\nlet update_scheduled = false;\nfunction schedule_update() {\n if (!update_scheduled) {\n update_scheduled = true;\n resolved_promise.then(flush);\n }\n}\nfunction tick() {\n schedule_update();\n return resolved_promise;\n}\nfunction add_render_callback(fn) {\n render_callbacks.push(fn);\n}\nfunction add_flush_callback(fn) {\n flush_callbacks.push(fn);\n}\n// flush() calls callbacks in this order:\n// 1. All beforeUpdate callbacks, in order: parents before children\n// 2. All bind:this callbacks, in reverse order: children before parents.\n// 3. All afterUpdate callbacks, in order: parents before children. EXCEPT\n// for afterUpdates called during the initial onMount, which are called in\n// reverse order: children before parents.\n// Since callbacks might update component values, which could trigger another\n// call to flush(), the following steps guard against this:\n// 1. During beforeUpdate, any updated components will be added to the\n// dirty_components array and will cause a reentrant call to flush(). Because\n// the flush index is kept outside the function, the reentrant call will pick\n// up where the earlier call left off and go through all dirty components. The\n// current_component value is saved and restored so that the reentrant call will\n// not interfere with the \"parent\" flush() call.\n// 2. bind:this callbacks cannot trigger new flush() calls.\n// 3. During afterUpdate, any updated components will NOT have their afterUpdate\n// callback called a second time; the seen_callbacks set, outside the flush()\n// function, guarantees this behavior.\nconst seen_callbacks = new Set();\nlet flushidx = 0; // Do *not* move this inside the flush() function\nfunction flush() {\n // Do not reenter flush while dirty components are updated, as this can\n // result in an infinite loop. Instead, let the inner flush handle it.\n // Reentrancy is ok afterwards for bindings etc.\n if (flushidx !== 0) {\n return;\n }\n const saved_component = current_component;\n do {\n // first, call beforeUpdate functions\n // and update components\n try {\n while (flushidx < dirty_components.length) {\n const component = dirty_components[flushidx];\n flushidx++;\n set_current_component(component);\n update(component.$$);\n }\n }\n catch (e) {\n // reset dirty state to not end up in a deadlocked state and then rethrow\n dirty_components.length = 0;\n flushidx = 0;\n throw e;\n }\n set_current_component(null);\n dirty_components.length = 0;\n flushidx = 0;\n while (binding_callbacks.length)\n binding_callbacks.pop()();\n // then, once components are updated, call\n // afterUpdate functions. This may cause\n // subsequent updates...\n for (let i = 0; i < render_callbacks.length; i += 1) {\n const callback = render_callbacks[i];\n if (!seen_callbacks.has(callback)) {\n // ...so guard against infinite loops\n seen_callbacks.add(callback);\n callback();\n }\n }\n render_callbacks.length = 0;\n } while (dirty_components.length);\n while (flush_callbacks.length) {\n flush_callbacks.pop()();\n }\n update_scheduled = false;\n seen_callbacks.clear();\n set_current_component(saved_component);\n}\nfunction update($$) {\n if ($$.fragment !== null) {\n $$.update();\n run_all($$.before_update);\n const dirty = $$.dirty;\n $$.dirty = [-1];\n $$.fragment && $$.fragment.p($$.ctx, dirty);\n $$.after_update.forEach(add_render_callback);\n }\n}\n/**\n * Useful for example to execute remaining `afterUpdate` callbacks before executing `destroy`.\n */\nfunction flush_render_callbacks(fns) {\n const filtered = [];\n const targets = [];\n render_callbacks.forEach((c) => fns.indexOf(c) === -1 ? filtered.push(c) : targets.push(c));\n targets.forEach((c) => c());\n render_callbacks = filtered;\n}\n\nlet promise;\nfunction wait() {\n if (!promise) {\n promise = Promise.resolve();\n promise.then(() => {\n promise = null;\n });\n }\n return promise;\n}\nfunction dispatch(node, direction, kind) {\n node.dispatchEvent(custom_event(`${direction ? 'intro' : 'outro'}${kind}`));\n}\nconst outroing = new Set();\nlet outros;\nfunction group_outros() {\n outros = {\n r: 0,\n c: [],\n p: outros // parent group\n };\n}\nfunction check_outros() {\n if (!outros.r) {\n run_all(outros.c);\n }\n outros = outros.p;\n}\nfunction transition_in(block, local) {\n if (block && block.i) {\n outroing.delete(block);\n block.i(local);\n }\n}\nfunction transition_out(block, local, detach, callback) {\n if (block && block.o) {\n if (outroing.has(block))\n return;\n outroing.add(block);\n outros.c.push(() => {\n outroing.delete(block);\n if (callback) {\n if (detach)\n block.d(1);\n callback();\n }\n });\n block.o(local);\n }\n else if (callback) {\n callback();\n }\n}\nconst null_transition = { duration: 0 };\nfunction create_in_transition(node, fn, params) {\n const options = { direction: 'in' };\n let config = fn(node, params, options);\n let running = false;\n let animation_name;\n let task;\n let uid = 0;\n function cleanup() {\n if (animation_name)\n delete_rule(node, animation_name);\n }\n function go() {\n const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition;\n if (css)\n animation_name = create_rule(node, 0, 1, duration, delay, easing, css, uid++);\n tick(0, 1);\n const start_time = now() + delay;\n const end_time = start_time + duration;\n if (task)\n task.abort();\n running = true;\n add_render_callback(() => dispatch(node, true, 'start'));\n task = loop(now => {\n if (running) {\n if (now >= end_time) {\n tick(1, 0);\n dispatch(node, true, 'end');\n cleanup();\n return running = false;\n }\n if (now >= start_time) {\n const t = easing((now - start_time) / duration);\n tick(t, 1 - t);\n }\n }\n return running;\n });\n }\n let started = false;\n return {\n start() {\n if (started)\n return;\n started = true;\n delete_rule(node);\n if (is_function(config)) {\n config = config(options);\n wait().then(go);\n }\n else {\n go();\n }\n },\n invalidate() {\n started = false;\n },\n end() {\n if (running) {\n cleanup();\n running = false;\n }\n }\n };\n}\nfunction create_out_transition(node, fn, params) {\n const options = { direction: 'out' };\n let config = fn(node, params, options);\n let running = true;\n let animation_name;\n const group = outros;\n group.r += 1;\n function go() {\n const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition;\n if (css)\n animation_name = create_rule(node, 1, 0, duration, delay, easing, css);\n const start_time = now() + delay;\n const end_time = start_time + duration;\n add_render_callback(() => dispatch(node, false, 'start'));\n loop(now => {\n if (running) {\n if (now >= end_time) {\n tick(0, 1);\n dispatch(node, false, 'end');\n if (!--group.r) {\n // this will result in `end()` being called,\n // so we don't need to clean up here\n run_all(group.c);\n }\n return false;\n }\n if (now >= start_time) {\n const t = easing((now - start_time) / duration);\n tick(1 - t, t);\n }\n }\n return running;\n });\n }\n if (is_function(config)) {\n wait().then(() => {\n // @ts-ignore\n config = config(options);\n go();\n });\n }\n else {\n go();\n }\n return {\n end(reset) {\n if (reset && config.tick) {\n config.tick(1, 0);\n }\n if (running) {\n if (animation_name)\n delete_rule(node, animation_name);\n running = false;\n }\n }\n };\n}\nfunction create_bidirectional_transition(node, fn, params, intro) {\n const options = { direction: 'both' };\n let config = fn(node, params, options);\n let t = intro ? 0 : 1;\n let running_program = null;\n let pending_program = null;\n let animation_name = null;\n function clear_animation() {\n if (animation_name)\n delete_rule(node, animation_name);\n }\n function init(program, duration) {\n const d = (program.b - t);\n duration *= Math.abs(d);\n return {\n a: t,\n b: program.b,\n d,\n duration,\n start: program.start,\n end: program.start + duration,\n group: program.group\n };\n }\n function go(b) {\n const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition;\n const program = {\n start: now() + delay,\n b\n };\n if (!b) {\n // @ts-ignore todo: improve typings\n program.group = outros;\n outros.r += 1;\n }\n if (running_program || pending_program) {\n pending_program = program;\n }\n else {\n // if this is an intro, and there's a delay, we need to do\n // an initial tick and/or apply CSS animation immediately\n if (css) {\n clear_animation();\n animation_name = create_rule(node, t, b, duration, delay, easing, css);\n }\n if (b)\n tick(0, 1);\n running_program = init(program, duration);\n add_render_callback(() => dispatch(node, b, 'start'));\n loop(now => {\n if (pending_program && now > pending_program.start) {\n running_program = init(pending_program, duration);\n pending_program = null;\n dispatch(node, running_program.b, 'start');\n if (css) {\n clear_animation();\n animation_name = create_rule(node, t, running_program.b, running_program.duration, 0, easing, config.css);\n }\n }\n if (running_program) {\n if (now >= running_program.end) {\n tick(t = running_program.b, 1 - t);\n dispatch(node, running_program.b, 'end');\n if (!pending_program) {\n // we're done\n if (running_program.b) {\n // intro — we can tidy up immediately\n clear_animation();\n }\n else {\n // outro — needs to be coordinated\n if (!--running_program.group.r)\n run_all(running_program.group.c);\n }\n }\n running_program = null;\n }\n else if (now >= running_program.start) {\n const p = now - running_program.start;\n t = running_program.a + running_program.d * easing(p / running_program.duration);\n tick(t, 1 - t);\n }\n }\n return !!(running_program || pending_program);\n });\n }\n }\n return {\n run(b) {\n if (is_function(config)) {\n wait().then(() => {\n // @ts-ignore\n config = config(options);\n go(b);\n });\n }\n else {\n go(b);\n }\n },\n end() {\n clear_animation();\n running_program = pending_program = null;\n }\n };\n}\n\nfunction handle_promise(promise, info) {\n const token = info.token = {};\n function update(type, index, key, value) {\n if (info.token !== token)\n return;\n info.resolved = value;\n let child_ctx = info.ctx;\n if (key !== undefined) {\n child_ctx = child_ctx.slice();\n child_ctx[key] = value;\n }\n const block = type && (info.current = type)(child_ctx);\n let needs_flush = false;\n if (info.block) {\n if (info.blocks) {\n info.blocks.forEach((block, i) => {\n if (i !== index && block) {\n group_outros();\n transition_out(block, 1, 1, () => {\n if (info.blocks[i] === block) {\n info.blocks[i] = null;\n }\n });\n check_outros();\n }\n });\n }\n else {\n info.block.d(1);\n }\n block.c();\n transition_in(block, 1);\n block.m(info.mount(), info.anchor);\n needs_flush = true;\n }\n info.block = block;\n if (info.blocks)\n info.blocks[index] = block;\n if (needs_flush) {\n flush();\n }\n }\n if (is_promise(promise)) {\n const current_component = get_current_component();\n promise.then(value => {\n set_current_component(current_component);\n update(info.then, 1, info.value, value);\n set_current_component(null);\n }, error => {\n set_current_component(current_component);\n update(info.catch, 2, info.error, error);\n set_current_component(null);\n if (!info.hasCatch) {\n throw error;\n }\n });\n // if we previously had a then/catch block, destroy it\n if (info.current !== info.pending) {\n update(info.pending, 0);\n return true;\n }\n }\n else {\n if (info.current !== info.then) {\n update(info.then, 1, info.value, promise);\n return true;\n }\n info.resolved = promise;\n }\n}\nfunction update_await_block_branch(info, ctx, dirty) {\n const child_ctx = ctx.slice();\n const { resolved } = info;\n if (info.current === info.then) {\n child_ctx[info.value] = resolved;\n }\n if (info.current === info.catch) {\n child_ctx[info.error] = resolved;\n }\n info.block.p(child_ctx, dirty);\n}\n\nfunction destroy_block(block, lookup) {\n block.d(1);\n lookup.delete(block.key);\n}\nfunction outro_and_destroy_block(block, lookup) {\n transition_out(block, 1, 1, () => {\n lookup.delete(block.key);\n });\n}\nfunction fix_and_destroy_block(block, lookup) {\n block.f();\n destroy_block(block, lookup);\n}\nfunction fix_and_outro_and_destroy_block(block, lookup) {\n block.f();\n outro_and_destroy_block(block, lookup);\n}\nfunction update_keyed_each(old_blocks, dirty, get_key, dynamic, ctx, list, lookup, node, destroy, create_each_block, next, get_context) {\n let o = old_blocks.length;\n let n = list.length;\n let i = o;\n const old_indexes = {};\n while (i--)\n old_indexes[old_blocks[i].key] = i;\n const new_blocks = [];\n const new_lookup = new Map();\n const deltas = new Map();\n const updates = [];\n i = n;\n while (i--) {\n const child_ctx = get_context(ctx, list, i);\n const key = get_key(child_ctx);\n let block = lookup.get(key);\n if (!block) {\n block = create_each_block(key, child_ctx);\n block.c();\n }\n else if (dynamic) {\n // defer updates until all the DOM shuffling is done\n updates.push(() => block.p(child_ctx, dirty));\n }\n new_lookup.set(key, new_blocks[i] = block);\n if (key in old_indexes)\n deltas.set(key, Math.abs(i - old_indexes[key]));\n }\n const will_move = new Set();\n const did_move = new Set();\n function insert(block) {\n transition_in(block, 1);\n block.m(node, next);\n lookup.set(block.key, block);\n next = block.first;\n n--;\n }\n while (o && n) {\n const new_block = new_blocks[n - 1];\n const old_block = old_blocks[o - 1];\n const new_key = new_block.key;\n const old_key = old_block.key;\n if (new_block === old_block) {\n // do nothing\n next = new_block.first;\n o--;\n n--;\n }\n else if (!new_lookup.has(old_key)) {\n // remove old block\n destroy(old_block, lookup);\n o--;\n }\n else if (!lookup.has(new_key) || will_move.has(new_key)) {\n insert(new_block);\n }\n else if (did_move.has(old_key)) {\n o--;\n }\n else if (deltas.get(new_key) > deltas.get(old_key)) {\n did_move.add(new_key);\n insert(new_block);\n }\n else {\n will_move.add(old_key);\n o--;\n }\n }\n while (o--) {\n const old_block = old_blocks[o];\n if (!new_lookup.has(old_block.key))\n destroy(old_block, lookup);\n }\n while (n)\n insert(new_blocks[n - 1]);\n run_all(updates);\n return new_blocks;\n}\nfunction validate_each_keys(ctx, list, get_context, get_key) {\n const keys = new Set();\n for (let i = 0; i < list.length; i++) {\n const key = get_key(get_context(ctx, list, i));\n if (keys.has(key)) {\n throw new Error('Cannot have duplicate keys in a keyed each');\n }\n keys.add(key);\n }\n}\n\nfunction get_spread_update(levels, updates) {\n const update = {};\n const to_null_out = {};\n const accounted_for = { $$scope: 1 };\n let i = levels.length;\n while (i--) {\n const o = levels[i];\n const n = updates[i];\n if (n) {\n for (const key in o) {\n if (!(key in n))\n to_null_out[key] = 1;\n }\n for (const key in n) {\n if (!accounted_for[key]) {\n update[key] = n[key];\n accounted_for[key] = 1;\n }\n }\n levels[i] = n;\n }\n else {\n for (const key in o) {\n accounted_for[key] = 1;\n }\n }\n }\n for (const key in to_null_out) {\n if (!(key in update))\n update[key] = undefined;\n }\n return update;\n}\nfunction get_spread_object(spread_props) {\n return typeof spread_props === 'object' && spread_props !== null ? spread_props : {};\n}\n\nconst _boolean_attributes = [\n 'allowfullscreen',\n 'allowpaymentrequest',\n 'async',\n 'autofocus',\n 'autoplay',\n 'checked',\n 'controls',\n 'default',\n 'defer',\n 'disabled',\n 'formnovalidate',\n 'hidden',\n 'inert',\n 'ismap',\n 'loop',\n 'multiple',\n 'muted',\n 'nomodule',\n 'novalidate',\n 'open',\n 'playsinline',\n 'readonly',\n 'required',\n 'reversed',\n 'selected'\n];\n/**\n * List of HTML boolean attributes (e.g. ` `).\n * Source: https://html.spec.whatwg.org/multipage/indices.html\n */\nconst boolean_attributes = new Set([..._boolean_attributes]);\n\n/** regex of all html void element names */\nconst void_element_names = /^(?:area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)$/;\nfunction is_void(name) {\n return void_element_names.test(name) || name.toLowerCase() === '!doctype';\n}\n\nconst invalid_attribute_name_character = /[\\s'\">/=\\u{FDD0}-\\u{FDEF}\\u{FFFE}\\u{FFFF}\\u{1FFFE}\\u{1FFFF}\\u{2FFFE}\\u{2FFFF}\\u{3FFFE}\\u{3FFFF}\\u{4FFFE}\\u{4FFFF}\\u{5FFFE}\\u{5FFFF}\\u{6FFFE}\\u{6FFFF}\\u{7FFFE}\\u{7FFFF}\\u{8FFFE}\\u{8FFFF}\\u{9FFFE}\\u{9FFFF}\\u{AFFFE}\\u{AFFFF}\\u{BFFFE}\\u{BFFFF}\\u{CFFFE}\\u{CFFFF}\\u{DFFFE}\\u{DFFFF}\\u{EFFFE}\\u{EFFFF}\\u{FFFFE}\\u{FFFFF}\\u{10FFFE}\\u{10FFFF}]/u;\n// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2\n// https://infra.spec.whatwg.org/#noncharacter\nfunction spread(args, attrs_to_add) {\n const attributes = Object.assign({}, ...args);\n if (attrs_to_add) {\n const classes_to_add = attrs_to_add.classes;\n const styles_to_add = attrs_to_add.styles;\n if (classes_to_add) {\n if (attributes.class == null) {\n attributes.class = classes_to_add;\n }\n else {\n attributes.class += ' ' + classes_to_add;\n }\n }\n if (styles_to_add) {\n if (attributes.style == null) {\n attributes.style = style_object_to_string(styles_to_add);\n }\n else {\n attributes.style = style_object_to_string(merge_ssr_styles(attributes.style, styles_to_add));\n }\n }\n }\n let str = '';\n Object.keys(attributes).forEach(name => {\n if (invalid_attribute_name_character.test(name))\n return;\n const value = attributes[name];\n if (value === true)\n str += ' ' + name;\n else if (boolean_attributes.has(name.toLowerCase())) {\n if (value)\n str += ' ' + name;\n }\n else if (value != null) {\n str += ` ${name}=\"${value}\"`;\n }\n });\n return str;\n}\nfunction merge_ssr_styles(style_attribute, style_directive) {\n const style_object = {};\n for (const individual_style of style_attribute.split(';')) {\n const colon_index = individual_style.indexOf(':');\n const name = individual_style.slice(0, colon_index).trim();\n const value = individual_style.slice(colon_index + 1).trim();\n if (!name)\n continue;\n style_object[name] = value;\n }\n for (const name in style_directive) {\n const value = style_directive[name];\n if (value) {\n style_object[name] = value;\n }\n else {\n delete style_object[name];\n }\n }\n return style_object;\n}\nconst ATTR_REGEX = /[&\"]/g;\nconst CONTENT_REGEX = /[&<]/g;\n/**\n * Note: this method is performance sensitive and has been optimized\n * https://github.com/sveltejs/svelte/pull/5701\n */\nfunction escape(value, is_attr = false) {\n const str = String(value);\n const pattern = is_attr ? ATTR_REGEX : CONTENT_REGEX;\n pattern.lastIndex = 0;\n let escaped = '';\n let last = 0;\n while (pattern.test(str)) {\n const i = pattern.lastIndex - 1;\n const ch = str[i];\n escaped += str.substring(last, i) + (ch === '&' ? '&' : (ch === '\"' ? '"' : '<'));\n last = i + 1;\n }\n return escaped + str.substring(last);\n}\nfunction escape_attribute_value(value) {\n // keep booleans, null, and undefined for the sake of `spread`\n const should_escape = typeof value === 'string' || (value && typeof value === 'object');\n return should_escape ? escape(value, true) : value;\n}\nfunction escape_object(obj) {\n const result = {};\n for (const key in obj) {\n result[key] = escape_attribute_value(obj[key]);\n }\n return result;\n}\nfunction each(items, fn) {\n let str = '';\n for (let i = 0; i < items.length; i += 1) {\n str += fn(items[i], i);\n }\n return str;\n}\nconst missing_component = {\n $$render: () => ''\n};\nfunction validate_component(component, name) {\n if (!component || !component.$$render) {\n if (name === 'svelte:component')\n name += ' this={...}';\n throw new Error(`<${name}> is not a valid SSR component. You may need to review your build config to ensure that dependencies are compiled, rather than imported as pre-compiled modules. Otherwise you may need to fix a <${name}>.`);\n }\n return component;\n}\nfunction debug(file, line, column, values) {\n console.log(`{@debug} ${file ? file + ' ' : ''}(${line}:${column})`); // eslint-disable-line no-console\n console.log(values); // eslint-disable-line no-console\n return '';\n}\nlet on_destroy;\nfunction create_ssr_component(fn) {\n function $$render(result, props, bindings, slots, context) {\n const parent_component = current_component;\n const $$ = {\n on_destroy,\n context: new Map(context || (parent_component ? parent_component.$$.context : [])),\n // these will be immediately discarded\n on_mount: [],\n before_update: [],\n after_update: [],\n callbacks: blank_object()\n };\n set_current_component({ $$ });\n const html = fn(result, props, bindings, slots);\n set_current_component(parent_component);\n return html;\n }\n return {\n render: (props = {}, { $$slots = {}, context = new Map() } = {}) => {\n on_destroy = [];\n const result = { title: '', head: '', css: new Set() };\n const html = $$render(result, props, {}, $$slots, context);\n run_all(on_destroy);\n return {\n html,\n css: {\n code: Array.from(result.css).map(css => css.code).join('\\n'),\n map: null // TODO\n },\n head: result.title + result.head\n };\n },\n $$render\n };\n}\nfunction add_attribute(name, value, boolean) {\n if (value == null || (boolean && !value))\n return '';\n const assignment = (boolean && value === true) ? '' : `=\"${escape(value, true)}\"`;\n return ` ${name}${assignment}`;\n}\nfunction add_classes(classes) {\n return classes ? ` class=\"${classes}\"` : '';\n}\nfunction style_object_to_string(style_object) {\n return Object.keys(style_object)\n .filter(key => style_object[key])\n .map(key => `${key}: ${escape_attribute_value(style_object[key])};`)\n .join(' ');\n}\nfunction add_styles(style_object) {\n const styles = style_object_to_string(style_object);\n return styles ? ` style=\"${styles}\"` : '';\n}\n\nfunction bind(component, name, callback) {\n const index = component.$$.props[name];\n if (index !== undefined) {\n component.$$.bound[index] = callback;\n callback(component.$$.ctx[index]);\n }\n}\nfunction create_component(block) {\n block && block.c();\n}\nfunction claim_component(block, parent_nodes) {\n block && block.l(parent_nodes);\n}\nfunction mount_component(component, target, anchor, customElement) {\n const { fragment, after_update } = component.$$;\n fragment && fragment.m(target, anchor);\n if (!customElement) {\n // onMount happens before the initial afterUpdate\n add_render_callback(() => {\n const new_on_destroy = component.$$.on_mount.map(run).filter(is_function);\n // if the component was destroyed immediately\n // it will update the `$$.on_destroy` reference to `null`.\n // the destructured on_destroy may still reference to the old array\n if (component.$$.on_destroy) {\n component.$$.on_destroy.push(...new_on_destroy);\n }\n else {\n // Edge case - component was destroyed immediately,\n // most likely as a result of a binding initialising\n run_all(new_on_destroy);\n }\n component.$$.on_mount = [];\n });\n }\n after_update.forEach(add_render_callback);\n}\nfunction destroy_component(component, detaching) {\n const $$ = component.$$;\n if ($$.fragment !== null) {\n flush_render_callbacks($$.after_update);\n run_all($$.on_destroy);\n $$.fragment && $$.fragment.d(detaching);\n // TODO null out other refs, including component.$$ (but need to\n // preserve final state?)\n $$.on_destroy = $$.fragment = null;\n $$.ctx = [];\n }\n}\nfunction make_dirty(component, i) {\n if (component.$$.dirty[0] === -1) {\n dirty_components.push(component);\n schedule_update();\n component.$$.dirty.fill(0);\n }\n component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31));\n}\nfunction init(component, options, instance, create_fragment, not_equal, props, append_styles, dirty = [-1]) {\n const parent_component = current_component;\n set_current_component(component);\n const $$ = component.$$ = {\n fragment: null,\n ctx: [],\n // state\n props,\n update: noop,\n not_equal,\n bound: blank_object(),\n // lifecycle\n on_mount: [],\n on_destroy: [],\n on_disconnect: [],\n before_update: [],\n after_update: [],\n context: new Map(options.context || (parent_component ? parent_component.$$.context : [])),\n // everything else\n callbacks: blank_object(),\n dirty,\n skip_bound: false,\n root: options.target || parent_component.$$.root\n };\n append_styles && append_styles($$.root);\n let ready = false;\n $$.ctx = instance\n ? instance(component, options.props || {}, (i, ret, ...rest) => {\n const value = rest.length ? rest[0] : ret;\n if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) {\n if (!$$.skip_bound && $$.bound[i])\n $$.bound[i](value);\n if (ready)\n make_dirty(component, i);\n }\n return ret;\n })\n : [];\n $$.update();\n ready = true;\n run_all($$.before_update);\n // `false` as a special case of no DOM component\n $$.fragment = create_fragment ? create_fragment($$.ctx) : false;\n if (options.target) {\n if (options.hydrate) {\n start_hydrating();\n const nodes = children(options.target);\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n $$.fragment && $$.fragment.l(nodes);\n nodes.forEach(detach);\n }\n else {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n $$.fragment && $$.fragment.c();\n }\n if (options.intro)\n transition_in(component.$$.fragment);\n mount_component(component, options.target, options.anchor, options.customElement);\n end_hydrating();\n flush();\n }\n set_current_component(parent_component);\n}\nlet SvelteElement;\nif (typeof HTMLElement === 'function') {\n SvelteElement = class extends HTMLElement {\n constructor() {\n super();\n this.attachShadow({ mode: 'open' });\n }\n connectedCallback() {\n const { on_mount } = this.$$;\n this.$$.on_disconnect = on_mount.map(run).filter(is_function);\n // @ts-ignore todo: improve typings\n for (const key in this.$$.slotted) {\n // @ts-ignore todo: improve typings\n this.appendChild(this.$$.slotted[key]);\n }\n }\n attributeChangedCallback(attr, _oldValue, newValue) {\n this[attr] = newValue;\n }\n disconnectedCallback() {\n run_all(this.$$.on_disconnect);\n }\n $destroy() {\n destroy_component(this, 1);\n this.$destroy = noop;\n }\n $on(type, callback) {\n // TODO should this delegate to addEventListener?\n if (!is_function(callback)) {\n return noop;\n }\n const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = []));\n callbacks.push(callback);\n return () => {\n const index = callbacks.indexOf(callback);\n if (index !== -1)\n callbacks.splice(index, 1);\n };\n }\n $set($$props) {\n if (this.$$set && !is_empty($$props)) {\n this.$$.skip_bound = true;\n this.$$set($$props);\n this.$$.skip_bound = false;\n }\n }\n };\n}\n/**\n * Base class for Svelte components. Used when dev=false.\n */\nclass SvelteComponent {\n $destroy() {\n destroy_component(this, 1);\n this.$destroy = noop;\n }\n $on(type, callback) {\n if (!is_function(callback)) {\n return noop;\n }\n const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = []));\n callbacks.push(callback);\n return () => {\n const index = callbacks.indexOf(callback);\n if (index !== -1)\n callbacks.splice(index, 1);\n };\n }\n $set($$props) {\n if (this.$$set && !is_empty($$props)) {\n this.$$.skip_bound = true;\n this.$$set($$props);\n this.$$.skip_bound = false;\n }\n }\n}\n\nfunction dispatch_dev(type, detail) {\n document.dispatchEvent(custom_event(type, Object.assign({ version: '3.59.2' }, detail), { bubbles: true }));\n}\nfunction append_dev(target, node) {\n dispatch_dev('SvelteDOMInsert', { target, node });\n append(target, node);\n}\nfunction append_hydration_dev(target, node) {\n dispatch_dev('SvelteDOMInsert', { target, node });\n append_hydration(target, node);\n}\nfunction insert_dev(target, node, anchor) {\n dispatch_dev('SvelteDOMInsert', { target, node, anchor });\n insert(target, node, anchor);\n}\nfunction insert_hydration_dev(target, node, anchor) {\n dispatch_dev('SvelteDOMInsert', { target, node, anchor });\n insert_hydration(target, node, anchor);\n}\nfunction detach_dev(node) {\n dispatch_dev('SvelteDOMRemove', { node });\n detach(node);\n}\nfunction detach_between_dev(before, after) {\n while (before.nextSibling && before.nextSibling !== after) {\n detach_dev(before.nextSibling);\n }\n}\nfunction detach_before_dev(after) {\n while (after.previousSibling) {\n detach_dev(after.previousSibling);\n }\n}\nfunction detach_after_dev(before) {\n while (before.nextSibling) {\n detach_dev(before.nextSibling);\n }\n}\nfunction listen_dev(node, event, handler, options, has_prevent_default, has_stop_propagation, has_stop_immediate_propagation) {\n const modifiers = options === true ? ['capture'] : options ? Array.from(Object.keys(options)) : [];\n if (has_prevent_default)\n modifiers.push('preventDefault');\n if (has_stop_propagation)\n modifiers.push('stopPropagation');\n if (has_stop_immediate_propagation)\n modifiers.push('stopImmediatePropagation');\n dispatch_dev('SvelteDOMAddEventListener', { node, event, handler, modifiers });\n const dispose = listen(node, event, handler, options);\n return () => {\n dispatch_dev('SvelteDOMRemoveEventListener', { node, event, handler, modifiers });\n dispose();\n };\n}\nfunction attr_dev(node, attribute, value) {\n attr(node, attribute, value);\n if (value == null)\n dispatch_dev('SvelteDOMRemoveAttribute', { node, attribute });\n else\n dispatch_dev('SvelteDOMSetAttribute', { node, attribute, value });\n}\nfunction prop_dev(node, property, value) {\n node[property] = value;\n dispatch_dev('SvelteDOMSetProperty', { node, property, value });\n}\nfunction dataset_dev(node, property, value) {\n node.dataset[property] = value;\n dispatch_dev('SvelteDOMSetDataset', { node, property, value });\n}\nfunction set_data_dev(text, data) {\n data = '' + data;\n if (text.data === data)\n return;\n dispatch_dev('SvelteDOMSetData', { node: text, data });\n text.data = data;\n}\nfunction set_data_contenteditable_dev(text, data) {\n data = '' + data;\n if (text.wholeText === data)\n return;\n dispatch_dev('SvelteDOMSetData', { node: text, data });\n text.data = data;\n}\nfunction set_data_maybe_contenteditable_dev(text, data, attr_value) {\n if (~contenteditable_truthy_values.indexOf(attr_value)) {\n set_data_contenteditable_dev(text, data);\n }\n else {\n set_data_dev(text, data);\n }\n}\nfunction validate_each_argument(arg) {\n if (typeof arg !== 'string' && !(arg && typeof arg === 'object' && 'length' in arg)) {\n let msg = '{#each} only iterates over array-like objects.';\n if (typeof Symbol === 'function' && arg && Symbol.iterator in arg) {\n msg += ' You can use a spread to convert this iterable into an array.';\n }\n throw new Error(msg);\n }\n}\nfunction validate_slots(name, slot, keys) {\n for (const slot_key of Object.keys(slot)) {\n if (!~keys.indexOf(slot_key)) {\n console.warn(`<${name}> received an unexpected slot \"${slot_key}\".`);\n }\n }\n}\nfunction validate_dynamic_element(tag) {\n const is_string = typeof tag === 'string';\n if (tag && !is_string) {\n throw new Error(' expects \"this\" attribute to be a string.');\n }\n}\nfunction validate_void_dynamic_element(tag) {\n if (tag && is_void(tag)) {\n console.warn(` is self-closing and cannot have content.`);\n }\n}\nfunction construct_svelte_component_dev(component, props) {\n const error_message = 'this={...} of should specify a Svelte component.';\n try {\n const instance = new component(props);\n if (!instance.$$ || !instance.$set || !instance.$on || !instance.$destroy) {\n throw new Error(error_message);\n }\n return instance;\n }\n catch (err) {\n const { message } = err;\n if (typeof message === 'string' && message.indexOf('is not a constructor') !== -1) {\n throw new Error(error_message);\n }\n else {\n throw err;\n }\n }\n}\n/**\n * Base class for Svelte components with some minor dev-enhancements. Used when dev=true.\n */\nclass SvelteComponentDev extends SvelteComponent {\n constructor(options) {\n if (!options || (!options.target && !options.$$inline)) {\n throw new Error(\"'target' is a required option\");\n }\n super();\n }\n $destroy() {\n super.$destroy();\n this.$destroy = () => {\n console.warn('Component was already destroyed'); // eslint-disable-line no-console\n };\n }\n $capture_state() { }\n $inject_state() { }\n}\n/**\n * Base class to create strongly typed Svelte components.\n * This only exists for typing purposes and should be used in `.d.ts` files.\n *\n * ### Example:\n *\n * You have component library on npm called `component-library`, from which\n * you export a component called `MyComponent`. For Svelte+TypeScript users,\n * you want to provide typings. Therefore you create a `index.d.ts`:\n * ```ts\n * import { SvelteComponentTyped } from \"svelte\";\n * export class MyComponent extends SvelteComponentTyped<{foo: string}> {}\n * ```\n * Typing this makes it possible for IDEs like VS Code with the Svelte extension\n * to provide intellisense and to use the component like this in a Svelte file\n * with TypeScript:\n * ```svelte\n * \n * \n * ```\n *\n * #### Why not make this part of `SvelteComponent(Dev)`?\n * Because\n * ```ts\n * class ASubclassOfSvelteComponent extends SvelteComponent<{foo: string}> {}\n * const component: typeof SvelteComponent = ASubclassOfSvelteComponent;\n * ```\n * will throw a type error, so we need to separate the more strictly typed class.\n */\nclass SvelteComponentTyped extends SvelteComponentDev {\n constructor(options) {\n super(options);\n }\n}\nfunction loop_guard(timeout) {\n const start = Date.now();\n return () => {\n if (Date.now() - start > timeout) {\n throw new Error('Infinite loop detected');\n }\n };\n}\n\nexport { HtmlTag, HtmlTagHydration, ResizeObserverSingleton, SvelteComponent, SvelteComponentDev, SvelteComponentTyped, SvelteElement, action_destroyer, add_attribute, add_classes, add_flush_callback, add_iframe_resize_listener, add_location, add_render_callback, add_styles, add_transform, afterUpdate, append, append_dev, append_empty_stylesheet, append_hydration, append_hydration_dev, append_styles, assign, attr, attr_dev, attribute_to_object, beforeUpdate, bind, binding_callbacks, blank_object, bubble, check_outros, children, claim_comment, claim_component, claim_element, claim_html_tag, claim_space, claim_svg_element, claim_text, clear_loops, comment, component_subscribe, compute_rest_props, compute_slots, construct_svelte_component, construct_svelte_component_dev, contenteditable_truthy_values, createEventDispatcher, create_animation, create_bidirectional_transition, create_component, create_in_transition, create_out_transition, create_slot, create_ssr_component, current_component, custom_event, dataset_dev, debug, destroy_block, destroy_component, destroy_each, detach, detach_after_dev, detach_before_dev, detach_between_dev, detach_dev, dirty_components, dispatch_dev, each, element, element_is, empty, end_hydrating, escape, escape_attribute_value, escape_object, exclude_internal_props, fix_and_destroy_block, fix_and_outro_and_destroy_block, fix_position, flush, flush_render_callbacks, getAllContexts, getContext, get_all_dirty_from_scope, get_binding_group_value, get_current_component, get_custom_elements_slots, get_root_for_style, get_slot_changes, get_spread_object, get_spread_update, get_store_value, globals, group_outros, handle_promise, hasContext, has_prop, head_selector, identity, init, init_binding_group, init_binding_group_dynamic, insert, insert_dev, insert_hydration, insert_hydration_dev, intros, invalid_attribute_name_character, is_client, is_crossorigin, is_empty, is_function, is_promise, is_void, listen, listen_dev, loop, loop_guard, merge_ssr_styles, missing_component, mount_component, noop, not_equal, now, null_to_empty, object_without_properties, onDestroy, onMount, once, outro_and_destroy_block, prevent_default, prop_dev, query_selector_all, raf, resize_observer_border_box, resize_observer_content_box, resize_observer_device_pixel_content_box, run, run_all, safe_not_equal, schedule_update, select_multiple_value, select_option, select_options, select_value, self, setContext, set_attributes, set_current_component, set_custom_element_data, set_custom_element_data_map, set_data, set_data_contenteditable, set_data_contenteditable_dev, set_data_dev, set_data_maybe_contenteditable, set_data_maybe_contenteditable_dev, set_dynamic_element_data, set_input_type, set_input_value, set_now, set_raf, set_store_value, set_style, set_svg_attributes, space, split_css_unit, spread, src_url_equal, start_hydrating, stop_immediate_propagation, stop_propagation, subscribe, svg_element, text, tick, time_ranges_to_array, to_number, toggle_class, transition_in, transition_out, trusted, update_await_block_branch, update_keyed_each, update_slot, update_slot_base, validate_component, validate_dynamic_element, validate_each_argument, validate_each_keys, validate_slots, validate_store, validate_void_dynamic_element, xlink_attr };\n","function number(n) {\n if (!Number.isSafeInteger(n) || n < 0)\n throw new Error(`Wrong positive integer: ${n}`);\n}\nfunction bool(b) {\n if (typeof b !== 'boolean')\n throw new Error(`Expected boolean, not ${b}`);\n}\nfunction bytes(b, ...lengths) {\n if (!(b instanceof Uint8Array))\n throw new Error('Expected Uint8Array');\n if (lengths.length > 0 && !lengths.includes(b.length))\n throw new Error(`Expected Uint8Array of length ${lengths}, not of length=${b.length}`);\n}\nfunction hash(hash) {\n if (typeof hash !== 'function' || typeof hash.create !== 'function')\n throw new Error('Hash should be wrapped by utils.wrapConstructor');\n number(hash.outputLen);\n number(hash.blockLen);\n}\nfunction exists(instance, checkFinished = true) {\n if (instance.destroyed)\n throw new Error('Hash instance has been destroyed');\n if (checkFinished && instance.finished)\n throw new Error('Hash#digest() has already been called');\n}\nfunction output(out, instance) {\n bytes(out);\n const min = instance.outputLen;\n if (out.length < min) {\n throw new Error(`digestInto() expects output buffer of length at least ${min}`);\n }\n}\nexport { number, bool, bytes, hash, exists, output };\nconst assert = { number, bool, bytes, hash, exists, output };\nexport default assert;\n//# sourceMappingURL=_assert.js.map","export const crypto = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;\n//# sourceMappingURL=crypto.js.map","/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */\n// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.\n// node.js versions earlier than v19 don't declare it in global scope.\n// For node.js, package.json#exports field mapping rewrites import\n// from `crypto` to `cryptoNode`, which imports native module.\n// Makes the utils un-importable in browsers without a bundler.\n// Once node.js 18 is deprecated, we can just drop the import.\nimport { crypto } from '@noble/hashes/crypto';\nconst u8a = (a) => a instanceof Uint8Array;\n// Cast array to different type\nexport const u8 = (arr) => new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);\nexport const u32 = (arr) => new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));\n// Cast array to view\nexport const createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength);\n// The rotate right (circular right shift) operation for uint32\nexport const rotr = (word, shift) => (word << (32 - shift)) | (word >>> shift);\n// big-endian hardware is rare. Just in case someone still decides to run hashes:\n// early-throw an error because we don't support BE yet.\nexport const isLE = new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44;\nif (!isLE)\n throw new Error('Non little-endian hardware is not supported');\nconst hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));\n/**\n * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'\n */\nexport function bytesToHex(bytes) {\n if (!u8a(bytes))\n throw new Error('Uint8Array expected');\n // pre-caching improves the speed 6x\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += hexes[bytes[i]];\n }\n return hex;\n}\n/**\n * @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])\n */\nexport function hexToBytes(hex) {\n if (typeof hex !== 'string')\n throw new Error('hex string expected, got ' + typeof hex);\n const len = hex.length;\n if (len % 2)\n throw new Error('padded hex string expected, got unpadded hex of length ' + len);\n const array = new Uint8Array(len / 2);\n for (let i = 0; i < array.length; i++) {\n const j = i * 2;\n const hexByte = hex.slice(j, j + 2);\n const byte = Number.parseInt(hexByte, 16);\n if (Number.isNaN(byte) || byte < 0)\n throw new Error('Invalid byte sequence');\n array[i] = byte;\n }\n return array;\n}\n// There is no setImmediate in browser and setTimeout is slow.\n// call of async fn will return Promise, which will be fullfiled only on\n// next scheduler queue processing step and this is exactly what we need.\nexport const nextTick = async () => { };\n// Returns control to thread each 'tick' ms to avoid blocking\nexport async function asyncLoop(iters, tick, cb) {\n let ts = Date.now();\n for (let i = 0; i < iters; i++) {\n cb(i);\n // Date.now() is not monotonic, so in case if clock goes backwards we return return control too\n const diff = Date.now() - ts;\n if (diff >= 0 && diff < tick)\n continue;\n await nextTick();\n ts += diff;\n }\n}\n/**\n * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])\n */\nexport function utf8ToBytes(str) {\n if (typeof str !== 'string')\n throw new Error(`utf8ToBytes expected string, got ${typeof str}`);\n return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809\n}\n/**\n * Normalizes (non-hex) string or Uint8Array to Uint8Array.\n * Warning: when Uint8Array is passed, it would NOT get copied.\n * Keep in mind for future mutable operations.\n */\nexport function toBytes(data) {\n if (typeof data === 'string')\n data = utf8ToBytes(data);\n if (!u8a(data))\n throw new Error(`expected Uint8Array, got ${typeof data}`);\n return data;\n}\n/**\n * Copies several Uint8Arrays into one.\n */\nexport function concatBytes(...arrays) {\n const r = new Uint8Array(arrays.reduce((sum, a) => sum + a.length, 0));\n let pad = 0; // walk through each item, ensure they have proper type\n arrays.forEach((a) => {\n if (!u8a(a))\n throw new Error('Uint8Array expected');\n r.set(a, pad);\n pad += a.length;\n });\n return r;\n}\n// For runtime check if class implements interface\nexport class Hash {\n // Safe version that clones internal state\n clone() {\n return this._cloneInto();\n }\n}\nconst toStr = {}.toString;\nexport function checkOpts(defaults, opts) {\n if (opts !== undefined && toStr.call(opts) !== '[object Object]')\n throw new Error('Options should be object or undefined');\n const merged = Object.assign(defaults, opts);\n return merged;\n}\nexport function wrapConstructor(hashCons) {\n const hashC = (msg) => hashCons().update(toBytes(msg)).digest();\n const tmp = hashCons();\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = () => hashCons();\n return hashC;\n}\nexport function wrapConstructorWithOpts(hashCons) {\n const hashC = (msg, opts) => hashCons(opts).update(toBytes(msg)).digest();\n const tmp = hashCons({});\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = (opts) => hashCons(opts);\n return hashC;\n}\nexport function wrapXOFConstructorWithOpts(hashCons) {\n const hashC = (msg, opts) => hashCons(opts).update(toBytes(msg)).digest();\n const tmp = hashCons({});\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = (opts) => hashCons(opts);\n return hashC;\n}\n/**\n * Secure PRNG. Uses `crypto.getRandomValues`, which defers to OS.\n */\nexport function randomBytes(bytesLength = 32) {\n if (crypto && typeof crypto.getRandomValues === 'function') {\n return crypto.getRandomValues(new Uint8Array(bytesLength));\n }\n throw new Error('crypto.getRandomValues must be defined');\n}\n//# sourceMappingURL=utils.js.map","import { exists, output } from './_assert.js';\nimport { Hash, createView, toBytes } from './utils.js';\n// Polyfill for Safari 14\nfunction setBigUint64(view, byteOffset, value, isLE) {\n if (typeof view.setBigUint64 === 'function')\n return view.setBigUint64(byteOffset, value, isLE);\n const _32n = BigInt(32);\n const _u32_max = BigInt(0xffffffff);\n const wh = Number((value >> _32n) & _u32_max);\n const wl = Number(value & _u32_max);\n const h = isLE ? 4 : 0;\n const l = isLE ? 0 : 4;\n view.setUint32(byteOffset + h, wh, isLE);\n view.setUint32(byteOffset + l, wl, isLE);\n}\n// Base SHA2 class (RFC 6234)\nexport class SHA2 extends Hash {\n constructor(blockLen, outputLen, padOffset, isLE) {\n super();\n this.blockLen = blockLen;\n this.outputLen = outputLen;\n this.padOffset = padOffset;\n this.isLE = isLE;\n this.finished = false;\n this.length = 0;\n this.pos = 0;\n this.destroyed = false;\n this.buffer = new Uint8Array(blockLen);\n this.view = createView(this.buffer);\n }\n update(data) {\n exists(this);\n const { view, buffer, blockLen } = this;\n data = toBytes(data);\n const len = data.length;\n for (let pos = 0; pos < len;) {\n const take = Math.min(blockLen - this.pos, len - pos);\n // Fast path: we have at least one block in input, cast it to view and process\n if (take === blockLen) {\n const dataView = createView(data);\n for (; blockLen <= len - pos; pos += blockLen)\n this.process(dataView, pos);\n continue;\n }\n buffer.set(data.subarray(pos, pos + take), this.pos);\n this.pos += take;\n pos += take;\n if (this.pos === blockLen) {\n this.process(view, 0);\n this.pos = 0;\n }\n }\n this.length += data.length;\n this.roundClean();\n return this;\n }\n digestInto(out) {\n exists(this);\n output(out, this);\n this.finished = true;\n // Padding\n // We can avoid allocation of buffer for padding completely if it\n // was previously not allocated here. But it won't change performance.\n const { buffer, view, blockLen, isLE } = this;\n let { pos } = this;\n // append the bit '1' to the message\n buffer[pos++] = 0b10000000;\n this.buffer.subarray(pos).fill(0);\n // we have less than padOffset left in buffer, so we cannot put length in current block, need process it and pad again\n if (this.padOffset > blockLen - pos) {\n this.process(view, 0);\n pos = 0;\n }\n // Pad until full block byte with zeros\n for (let i = pos; i < blockLen; i++)\n buffer[i] = 0;\n // Note: sha512 requires length to be 128bit integer, but length in JS will overflow before that\n // You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen.\n // So we just write lowest 64 bits of that value.\n setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE);\n this.process(view, 0);\n const oview = createView(out);\n const len = this.outputLen;\n // NOTE: we do division by 4 later, which should be fused in single op with modulo by JIT\n if (len % 4)\n throw new Error('_sha2: outputLen should be aligned to 32bit');\n const outLen = len / 4;\n const state = this.get();\n if (outLen > state.length)\n throw new Error('_sha2: outputLen bigger than state');\n for (let i = 0; i < outLen; i++)\n oview.setUint32(4 * i, state[i], isLE);\n }\n digest() {\n const { buffer, outputLen } = this;\n this.digestInto(buffer);\n const res = buffer.slice(0, outputLen);\n this.destroy();\n return res;\n }\n _cloneInto(to) {\n to || (to = new this.constructor());\n to.set(...this.get());\n const { blockLen, buffer, length, finished, destroyed, pos } = this;\n to.length = length;\n to.pos = pos;\n to.finished = finished;\n to.destroyed = destroyed;\n if (length % blockLen)\n to.buffer.set(buffer);\n return to;\n }\n}\n//# sourceMappingURL=_sha2.js.map","import { SHA2 } from './_sha2.js';\nimport { rotr, wrapConstructor } from './utils.js';\n// SHA2-256 need to try 2^128 hashes to execute birthday attack.\n// BTC network is doing 2^67 hashes/sec as per early 2023.\n// Choice: a ? b : c\nconst Chi = (a, b, c) => (a & b) ^ (~a & c);\n// Majority function, true if any two inpust is true\nconst Maj = (a, b, c) => (a & b) ^ (a & c) ^ (b & c);\n// Round constants:\n// first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)\n// prettier-ignore\nconst SHA256_K = /* @__PURE__ */ new Uint32Array([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n]);\n// Initial state (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):\n// prettier-ignore\nconst IV = /* @__PURE__ */ new Uint32Array([\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19\n]);\n// Temporary buffer, not used to store anything between runs\n// Named this way because it matches specification.\nconst SHA256_W = /* @__PURE__ */ new Uint32Array(64);\nclass SHA256 extends SHA2 {\n constructor() {\n super(64, 32, 8, false);\n // We cannot use array here since array allows indexing by variable\n // which means optimizer/compiler cannot use registers.\n this.A = IV[0] | 0;\n this.B = IV[1] | 0;\n this.C = IV[2] | 0;\n this.D = IV[3] | 0;\n this.E = IV[4] | 0;\n this.F = IV[5] | 0;\n this.G = IV[6] | 0;\n this.H = IV[7] | 0;\n }\n get() {\n const { A, B, C, D, E, F, G, H } = this;\n return [A, B, C, D, E, F, G, H];\n }\n // prettier-ignore\n set(A, B, C, D, E, F, G, H) {\n this.A = A | 0;\n this.B = B | 0;\n this.C = C | 0;\n this.D = D | 0;\n this.E = E | 0;\n this.F = F | 0;\n this.G = G | 0;\n this.H = H | 0;\n }\n process(view, offset) {\n // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array\n for (let i = 0; i < 16; i++, offset += 4)\n SHA256_W[i] = view.getUint32(offset, false);\n for (let i = 16; i < 64; i++) {\n const W15 = SHA256_W[i - 15];\n const W2 = SHA256_W[i - 2];\n const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3);\n const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10);\n SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0;\n }\n // Compression function main loop, 64 rounds\n let { A, B, C, D, E, F, G, H } = this;\n for (let i = 0; i < 64; i++) {\n const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);\n const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;\n const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);\n const T2 = (sigma0 + Maj(A, B, C)) | 0;\n H = G;\n G = F;\n F = E;\n E = (D + T1) | 0;\n D = C;\n C = B;\n B = A;\n A = (T1 + T2) | 0;\n }\n // Add the compressed chunk to the current hash value\n A = (A + this.A) | 0;\n B = (B + this.B) | 0;\n C = (C + this.C) | 0;\n D = (D + this.D) | 0;\n E = (E + this.E) | 0;\n F = (F + this.F) | 0;\n G = (G + this.G) | 0;\n H = (H + this.H) | 0;\n this.set(A, B, C, D, E, F, G, H);\n }\n roundClean() {\n SHA256_W.fill(0);\n }\n destroy() {\n this.set(0, 0, 0, 0, 0, 0, 0, 0);\n this.buffer.fill(0);\n }\n}\n// Constants from https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf\nclass SHA224 extends SHA256 {\n constructor() {\n super();\n this.A = 0xc1059ed8 | 0;\n this.B = 0x367cd507 | 0;\n this.C = 0x3070dd17 | 0;\n this.D = 0xf70e5939 | 0;\n this.E = 0xffc00b31 | 0;\n this.F = 0x68581511 | 0;\n this.G = 0x64f98fa7 | 0;\n this.H = 0xbefa4fa4 | 0;\n this.outputLen = 28;\n }\n}\n/**\n * SHA2-256 hash function\n * @param message - data that would be hashed\n */\nexport const sha256 = /* @__PURE__ */ wrapConstructor(() => new SHA256());\nexport const sha224 = /* @__PURE__ */ wrapConstructor(() => new SHA224());\n//# sourceMappingURL=sha256.js.map","/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\n// 100 lines of code in the file are duplicated from noble-hashes (utils).\n// This is OK: `abstract` directory does not use noble-hashes.\n// User may opt-in into using different hashing library. This way, noble-hashes\n// won't be included into their bundle.\nconst _0n = BigInt(0);\nconst _1n = BigInt(1);\nconst _2n = BigInt(2);\nconst u8a = (a) => a instanceof Uint8Array;\nconst hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));\n/**\n * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'\n */\nexport function bytesToHex(bytes) {\n if (!u8a(bytes))\n throw new Error('Uint8Array expected');\n // pre-caching improves the speed 6x\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += hexes[bytes[i]];\n }\n return hex;\n}\nexport function numberToHexUnpadded(num) {\n const hex = num.toString(16);\n return hex.length & 1 ? `0${hex}` : hex;\n}\nexport function hexToNumber(hex) {\n if (typeof hex !== 'string')\n throw new Error('hex string expected, got ' + typeof hex);\n // Big Endian\n return BigInt(hex === '' ? '0' : `0x${hex}`);\n}\n/**\n * @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])\n */\nexport function hexToBytes(hex) {\n if (typeof hex !== 'string')\n throw new Error('hex string expected, got ' + typeof hex);\n const len = hex.length;\n if (len % 2)\n throw new Error('padded hex string expected, got unpadded hex of length ' + len);\n const array = new Uint8Array(len / 2);\n for (let i = 0; i < array.length; i++) {\n const j = i * 2;\n const hexByte = hex.slice(j, j + 2);\n const byte = Number.parseInt(hexByte, 16);\n if (Number.isNaN(byte) || byte < 0)\n throw new Error('Invalid byte sequence');\n array[i] = byte;\n }\n return array;\n}\n// BE: Big Endian, LE: Little Endian\nexport function bytesToNumberBE(bytes) {\n return hexToNumber(bytesToHex(bytes));\n}\nexport function bytesToNumberLE(bytes) {\n if (!u8a(bytes))\n throw new Error('Uint8Array expected');\n return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse()));\n}\nexport function numberToBytesBE(n, len) {\n return hexToBytes(n.toString(16).padStart(len * 2, '0'));\n}\nexport function numberToBytesLE(n, len) {\n return numberToBytesBE(n, len).reverse();\n}\n// Unpadded, rarely used\nexport function numberToVarBytesBE(n) {\n return hexToBytes(numberToHexUnpadded(n));\n}\n/**\n * Takes hex string or Uint8Array, converts to Uint8Array.\n * Validates output length.\n * Will throw error for other types.\n * @param title descriptive title for an error e.g. 'private key'\n * @param hex hex string or Uint8Array\n * @param expectedLength optional, will compare to result array's length\n * @returns\n */\nexport function ensureBytes(title, hex, expectedLength) {\n let res;\n if (typeof hex === 'string') {\n try {\n res = hexToBytes(hex);\n }\n catch (e) {\n throw new Error(`${title} must be valid hex string, got \"${hex}\". Cause: ${e}`);\n }\n }\n else if (u8a(hex)) {\n // Uint8Array.from() instead of hash.slice() because node.js Buffer\n // is instance of Uint8Array, and its slice() creates **mutable** copy\n res = Uint8Array.from(hex);\n }\n else {\n throw new Error(`${title} must be hex string or Uint8Array`);\n }\n const len = res.length;\n if (typeof expectedLength === 'number' && len !== expectedLength)\n throw new Error(`${title} expected ${expectedLength} bytes, got ${len}`);\n return res;\n}\n/**\n * Copies several Uint8Arrays into one.\n */\nexport function concatBytes(...arrays) {\n const r = new Uint8Array(arrays.reduce((sum, a) => sum + a.length, 0));\n let pad = 0; // walk through each item, ensure they have proper type\n arrays.forEach((a) => {\n if (!u8a(a))\n throw new Error('Uint8Array expected');\n r.set(a, pad);\n pad += a.length;\n });\n return r;\n}\nexport function equalBytes(b1, b2) {\n // We don't care about timing attacks here\n if (b1.length !== b2.length)\n return false;\n for (let i = 0; i < b1.length; i++)\n if (b1[i] !== b2[i])\n return false;\n return true;\n}\n/**\n * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])\n */\nexport function utf8ToBytes(str) {\n if (typeof str !== 'string')\n throw new Error(`utf8ToBytes expected string, got ${typeof str}`);\n return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809\n}\n// Bit operations\n/**\n * Calculates amount of bits in a bigint.\n * Same as `n.toString(2).length`\n */\nexport function bitLen(n) {\n let len;\n for (len = 0; n > _0n; n >>= _1n, len += 1)\n ;\n return len;\n}\n/**\n * Gets single bit at position.\n * NOTE: first bit position is 0 (same as arrays)\n * Same as `!!+Array.from(n.toString(2)).reverse()[pos]`\n */\nexport function bitGet(n, pos) {\n return (n >> BigInt(pos)) & _1n;\n}\n/**\n * Sets single bit at position.\n */\nexport const bitSet = (n, pos, value) => {\n return n | ((value ? _1n : _0n) << BigInt(pos));\n};\n/**\n * Calculate mask for N bits. Not using ** operator with bigints because of old engines.\n * Same as BigInt(`0b${Array(i).fill('1').join('')}`)\n */\nexport const bitMask = (n) => (_2n << BigInt(n - 1)) - _1n;\n// DRBG\nconst u8n = (data) => new Uint8Array(data); // creates Uint8Array\nconst u8fr = (arr) => Uint8Array.from(arr); // another shortcut\n/**\n * Minimal HMAC-DRBG from NIST 800-90 for RFC6979 sigs.\n * @returns function that will call DRBG until 2nd arg returns something meaningful\n * @example\n * const drbg = createHmacDRBG(32, 32, hmac);\n * drbg(seed, bytesToKey); // bytesToKey must return Key or undefined\n */\nexport function createHmacDrbg(hashLen, qByteLen, hmacFn) {\n if (typeof hashLen !== 'number' || hashLen < 2)\n throw new Error('hashLen must be a number');\n if (typeof qByteLen !== 'number' || qByteLen < 2)\n throw new Error('qByteLen must be a number');\n if (typeof hmacFn !== 'function')\n throw new Error('hmacFn must be a function');\n // Step B, Step C: set hashLen to 8*ceil(hlen/8)\n let v = u8n(hashLen); // Minimal non-full-spec HMAC-DRBG from NIST 800-90 for RFC6979 sigs.\n let k = u8n(hashLen); // Steps B and C of RFC6979 3.2: set hashLen, in our case always same\n let i = 0; // Iterations counter, will throw when over 1000\n const reset = () => {\n v.fill(1);\n k.fill(0);\n i = 0;\n };\n const h = (...b) => hmacFn(k, v, ...b); // hmac(k)(v, ...values)\n const reseed = (seed = u8n()) => {\n // HMAC-DRBG reseed() function. Steps D-G\n k = h(u8fr([0x00]), seed); // k = hmac(k || v || 0x00 || seed)\n v = h(); // v = hmac(k || v)\n if (seed.length === 0)\n return;\n k = h(u8fr([0x01]), seed); // k = hmac(k || v || 0x01 || seed)\n v = h(); // v = hmac(k || v)\n };\n const gen = () => {\n // HMAC-DRBG generate() function\n if (i++ >= 1000)\n throw new Error('drbg: tried 1000 values');\n let len = 0;\n const out = [];\n while (len < qByteLen) {\n v = h();\n const sl = v.slice();\n out.push(sl);\n len += v.length;\n }\n return concatBytes(...out);\n };\n const genUntil = (seed, pred) => {\n reset();\n reseed(seed); // Steps D-G\n let res = undefined; // Step H: grind until k is in [1..n-1]\n while (!(res = pred(gen())))\n reseed();\n reset();\n return res;\n };\n return genUntil;\n}\n// Validating curves and fields\nconst validatorFns = {\n bigint: (val) => typeof val === 'bigint',\n function: (val) => typeof val === 'function',\n boolean: (val) => typeof val === 'boolean',\n string: (val) => typeof val === 'string',\n stringOrUint8Array: (val) => typeof val === 'string' || val instanceof Uint8Array,\n isSafeInteger: (val) => Number.isSafeInteger(val),\n array: (val) => Array.isArray(val),\n field: (val, object) => object.Fp.isValid(val),\n hash: (val) => typeof val === 'function' && Number.isSafeInteger(val.outputLen),\n};\n// type Record = { [P in K]: T; }\nexport function validateObject(object, validators, optValidators = {}) {\n const checkField = (fieldName, type, isOptional) => {\n const checkVal = validatorFns[type];\n if (typeof checkVal !== 'function')\n throw new Error(`Invalid validator \"${type}\", expected function`);\n const val = object[fieldName];\n if (isOptional && val === undefined)\n return;\n if (!checkVal(val, object)) {\n throw new Error(`Invalid param ${String(fieldName)}=${val} (${typeof val}), expected ${type}`);\n }\n };\n for (const [fieldName, type] of Object.entries(validators))\n checkField(fieldName, type, false);\n for (const [fieldName, type] of Object.entries(optValidators))\n checkField(fieldName, type, true);\n return object;\n}\n// validate type tests\n// const o: { a: number; b: number; c: number } = { a: 1, b: 5, c: 6 };\n// const z0 = validateObject(o, { a: 'isSafeInteger' }, { c: 'bigint' }); // Ok!\n// // Should fail type-check\n// const z1 = validateObject(o, { a: 'tmp' }, { c: 'zz' });\n// const z2 = validateObject(o, { a: 'isSafeInteger' }, { c: 'zz' });\n// const z3 = validateObject(o, { test: 'boolean', z: 'bug' });\n// const z4 = validateObject(o, { a: 'boolean', z: 'bug' });\n//# sourceMappingURL=utils.js.map","/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\n// Utilities for modular arithmetics and finite fields\nimport { bitMask, numberToBytesBE, numberToBytesLE, bytesToNumberBE, bytesToNumberLE, ensureBytes, validateObject, } from './utils.js';\n// prettier-ignore\nconst _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3);\n// prettier-ignore\nconst _4n = BigInt(4), _5n = BigInt(5), _8n = BigInt(8);\n// prettier-ignore\nconst _9n = BigInt(9), _16n = BigInt(16);\n// Calculates a modulo b\nexport function mod(a, b) {\n const result = a % b;\n return result >= _0n ? result : b + result;\n}\n/**\n * Efficiently raise num to power and do modular division.\n * Unsafe in some contexts: uses ladder, so can expose bigint bits.\n * @example\n * pow(2n, 6n, 11n) // 64n % 11n == 9n\n */\n// TODO: use field version && remove\nexport function pow(num, power, modulo) {\n if (modulo <= _0n || power < _0n)\n throw new Error('Expected power/modulo > 0');\n if (modulo === _1n)\n return _0n;\n let res = _1n;\n while (power > _0n) {\n if (power & _1n)\n res = (res * num) % modulo;\n num = (num * num) % modulo;\n power >>= _1n;\n }\n return res;\n}\n// Does x ^ (2 ^ power) mod p. pow2(30, 4) == 30 ^ (2 ^ 4)\nexport function pow2(x, power, modulo) {\n let res = x;\n while (power-- > _0n) {\n res *= res;\n res %= modulo;\n }\n return res;\n}\n// Inverses number over modulo\nexport function invert(number, modulo) {\n if (number === _0n || modulo <= _0n) {\n throw new Error(`invert: expected positive integers, got n=${number} mod=${modulo}`);\n }\n // Euclidean GCD https://brilliant.org/wiki/extended-euclidean-algorithm/\n // Fermat's little theorem \"CT-like\" version inv(n) = n^(m-2) mod m is 30x slower.\n let a = mod(number, modulo);\n let b = modulo;\n // prettier-ignore\n let x = _0n, y = _1n, u = _1n, v = _0n;\n while (a !== _0n) {\n // JIT applies optimization if those two lines follow each other\n const q = b / a;\n const r = b % a;\n const m = x - u * q;\n const n = y - v * q;\n // prettier-ignore\n b = a, a = r, x = u, y = v, u = m, v = n;\n }\n const gcd = b;\n if (gcd !== _1n)\n throw new Error('invert: does not exist');\n return mod(x, modulo);\n}\n/**\n * Tonelli-Shanks square root search algorithm.\n * 1. https://eprint.iacr.org/2012/685.pdf (page 12)\n * 2. Square Roots from 1; 24, 51, 10 to Dan Shanks\n * Will start an infinite loop if field order P is not prime.\n * @param P field order\n * @returns function that takes field Fp (created from P) and number n\n */\nexport function tonelliShanks(P) {\n // Legendre constant: used to calculate Legendre symbol (a | p),\n // which denotes the value of a^((p-1)/2) (mod p).\n // (a | p) ≡ 1 if a is a square (mod p)\n // (a | p) ≡ -1 if a is not a square (mod p)\n // (a | p) ≡ 0 if a ≡ 0 (mod p)\n const legendreC = (P - _1n) / _2n;\n let Q, S, Z;\n // Step 1: By factoring out powers of 2 from p - 1,\n // find q and s such that p - 1 = q*(2^s) with q odd\n for (Q = P - _1n, S = 0; Q % _2n === _0n; Q /= _2n, S++)\n ;\n // Step 2: Select a non-square z such that (z | p) ≡ -1 and set c ≡ zq\n for (Z = _2n; Z < P && pow(Z, legendreC, P) !== P - _1n; Z++)\n ;\n // Fast-path\n if (S === 1) {\n const p1div4 = (P + _1n) / _4n;\n return function tonelliFast(Fp, n) {\n const root = Fp.pow(n, p1div4);\n if (!Fp.eql(Fp.sqr(root), n))\n throw new Error('Cannot find square root');\n return root;\n };\n }\n // Slow-path\n const Q1div2 = (Q + _1n) / _2n;\n return function tonelliSlow(Fp, n) {\n // Step 0: Check that n is indeed a square: (n | p) should not be ≡ -1\n if (Fp.pow(n, legendreC) === Fp.neg(Fp.ONE))\n throw new Error('Cannot find square root');\n let r = S;\n // TODO: will fail at Fp2/etc\n let g = Fp.pow(Fp.mul(Fp.ONE, Z), Q); // will update both x and b\n let x = Fp.pow(n, Q1div2); // first guess at the square root\n let b = Fp.pow(n, Q); // first guess at the fudge factor\n while (!Fp.eql(b, Fp.ONE)) {\n if (Fp.eql(b, Fp.ZERO))\n return Fp.ZERO; // https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm (4. If t = 0, return r = 0)\n // Find m such b^(2^m)==1\n let m = 1;\n for (let t2 = Fp.sqr(b); m < r; m++) {\n if (Fp.eql(t2, Fp.ONE))\n break;\n t2 = Fp.sqr(t2); // t2 *= t2\n }\n // NOTE: r-m-1 can be bigger than 32, need to convert to bigint before shift, otherwise there will be overflow\n const ge = Fp.pow(g, _1n << BigInt(r - m - 1)); // ge = 2^(r-m-1)\n g = Fp.sqr(ge); // g = ge * ge\n x = Fp.mul(x, ge); // x *= ge\n b = Fp.mul(b, g); // b *= g\n r = m;\n }\n return x;\n };\n}\nexport function FpSqrt(P) {\n // NOTE: different algorithms can give different roots, it is up to user to decide which one they want.\n // For example there is FpSqrtOdd/FpSqrtEven to choice root based on oddness (used for hash-to-curve).\n // P ≡ 3 (mod 4)\n // √n = n^((P+1)/4)\n if (P % _4n === _3n) {\n // Not all roots possible!\n // const ORDER =\n // 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaabn;\n // const NUM = 72057594037927816n;\n const p1div4 = (P + _1n) / _4n;\n return function sqrt3mod4(Fp, n) {\n const root = Fp.pow(n, p1div4);\n // Throw if root**2 != n\n if (!Fp.eql(Fp.sqr(root), n))\n throw new Error('Cannot find square root');\n return root;\n };\n }\n // Atkin algorithm for q ≡ 5 (mod 8), https://eprint.iacr.org/2012/685.pdf (page 10)\n if (P % _8n === _5n) {\n const c1 = (P - _5n) / _8n;\n return function sqrt5mod8(Fp, n) {\n const n2 = Fp.mul(n, _2n);\n const v = Fp.pow(n2, c1);\n const nv = Fp.mul(n, v);\n const i = Fp.mul(Fp.mul(nv, _2n), v);\n const root = Fp.mul(nv, Fp.sub(i, Fp.ONE));\n if (!Fp.eql(Fp.sqr(root), n))\n throw new Error('Cannot find square root');\n return root;\n };\n }\n // P ≡ 9 (mod 16)\n if (P % _16n === _9n) {\n // NOTE: tonelli is too slow for bls-Fp2 calculations even on start\n // Means we cannot use sqrt for constants at all!\n //\n // const c1 = Fp.sqrt(Fp.negate(Fp.ONE)); // 1. c1 = sqrt(-1) in F, i.e., (c1^2) == -1 in F\n // const c2 = Fp.sqrt(c1); // 2. c2 = sqrt(c1) in F, i.e., (c2^2) == c1 in F\n // const c3 = Fp.sqrt(Fp.negate(c1)); // 3. c3 = sqrt(-c1) in F, i.e., (c3^2) == -c1 in F\n // const c4 = (P + _7n) / _16n; // 4. c4 = (q + 7) / 16 # Integer arithmetic\n // sqrt = (x) => {\n // let tv1 = Fp.pow(x, c4); // 1. tv1 = x^c4\n // let tv2 = Fp.mul(c1, tv1); // 2. tv2 = c1 * tv1\n // const tv3 = Fp.mul(c2, tv1); // 3. tv3 = c2 * tv1\n // let tv4 = Fp.mul(c3, tv1); // 4. tv4 = c3 * tv1\n // const e1 = Fp.equals(Fp.square(tv2), x); // 5. e1 = (tv2^2) == x\n // const e2 = Fp.equals(Fp.square(tv3), x); // 6. e2 = (tv3^2) == x\n // tv1 = Fp.cmov(tv1, tv2, e1); // 7. tv1 = CMOV(tv1, tv2, e1) # Select tv2 if (tv2^2) == x\n // tv2 = Fp.cmov(tv4, tv3, e2); // 8. tv2 = CMOV(tv4, tv3, e2) # Select tv3 if (tv3^2) == x\n // const e3 = Fp.equals(Fp.square(tv2), x); // 9. e3 = (tv2^2) == x\n // return Fp.cmov(tv1, tv2, e3); // 10. z = CMOV(tv1, tv2, e3) # Select the sqrt from tv1 and tv2\n // }\n }\n // Other cases: Tonelli-Shanks algorithm\n return tonelliShanks(P);\n}\n// Little-endian check for first LE bit (last BE bit);\nexport const isNegativeLE = (num, modulo) => (mod(num, modulo) & _1n) === _1n;\n// prettier-ignore\nconst FIELD_FIELDS = [\n 'create', 'isValid', 'is0', 'neg', 'inv', 'sqrt', 'sqr',\n 'eql', 'add', 'sub', 'mul', 'pow', 'div',\n 'addN', 'subN', 'mulN', 'sqrN'\n];\nexport function validateField(field) {\n const initial = {\n ORDER: 'bigint',\n MASK: 'bigint',\n BYTES: 'isSafeInteger',\n BITS: 'isSafeInteger',\n };\n const opts = FIELD_FIELDS.reduce((map, val) => {\n map[val] = 'function';\n return map;\n }, initial);\n return validateObject(field, opts);\n}\n// Generic field functions\n/**\n * Same as `pow` but for Fp: non-constant-time.\n * Unsafe in some contexts: uses ladder, so can expose bigint bits.\n */\nexport function FpPow(f, num, power) {\n // Should have same speed as pow for bigints\n // TODO: benchmark!\n if (power < _0n)\n throw new Error('Expected power > 0');\n if (power === _0n)\n return f.ONE;\n if (power === _1n)\n return num;\n let p = f.ONE;\n let d = num;\n while (power > _0n) {\n if (power & _1n)\n p = f.mul(p, d);\n d = f.sqr(d);\n power >>= _1n;\n }\n return p;\n}\n/**\n * Efficiently invert an array of Field elements.\n * `inv(0)` will return `undefined` here: make sure to throw an error.\n */\nexport function FpInvertBatch(f, nums) {\n const tmp = new Array(nums.length);\n // Walk from first to last, multiply them by each other MOD p\n const lastMultiplied = nums.reduce((acc, num, i) => {\n if (f.is0(num))\n return acc;\n tmp[i] = acc;\n return f.mul(acc, num);\n }, f.ONE);\n // Invert last element\n const inverted = f.inv(lastMultiplied);\n // Walk from last to first, multiply them by inverted each other MOD p\n nums.reduceRight((acc, num, i) => {\n if (f.is0(num))\n return acc;\n tmp[i] = f.mul(acc, tmp[i]);\n return f.mul(acc, num);\n }, inverted);\n return tmp;\n}\nexport function FpDiv(f, lhs, rhs) {\n return f.mul(lhs, typeof rhs === 'bigint' ? invert(rhs, f.ORDER) : f.inv(rhs));\n}\n// This function returns True whenever the value x is a square in the field F.\nexport function FpIsSquare(f) {\n const legendreConst = (f.ORDER - _1n) / _2n; // Integer arithmetic\n return (x) => {\n const p = f.pow(x, legendreConst);\n return f.eql(p, f.ZERO) || f.eql(p, f.ONE);\n };\n}\n// CURVE.n lengths\nexport function nLength(n, nBitLength) {\n // Bit size, byte size of CURVE.n\n const _nBitLength = nBitLength !== undefined ? nBitLength : n.toString(2).length;\n const nByteLength = Math.ceil(_nBitLength / 8);\n return { nBitLength: _nBitLength, nByteLength };\n}\n/**\n * Initializes a finite field over prime. **Non-primes are not supported.**\n * Do not init in loop: slow. Very fragile: always run a benchmark on a change.\n * Major performance optimizations:\n * * a) denormalized operations like mulN instead of mul\n * * b) same object shape: never add or remove keys\n * * c) Object.freeze\n * @param ORDER prime positive bigint\n * @param bitLen how many bits the field consumes\n * @param isLE (def: false) if encoding / decoding should be in little-endian\n * @param redef optional faster redefinitions of sqrt and other methods\n */\nexport function Field(ORDER, bitLen, isLE = false, redef = {}) {\n if (ORDER <= _0n)\n throw new Error(`Expected Field ORDER > 0, got ${ORDER}`);\n const { nBitLength: BITS, nByteLength: BYTES } = nLength(ORDER, bitLen);\n if (BYTES > 2048)\n throw new Error('Field lengths over 2048 bytes are not supported');\n const sqrtP = FpSqrt(ORDER);\n const f = Object.freeze({\n ORDER,\n BITS,\n BYTES,\n MASK: bitMask(BITS),\n ZERO: _0n,\n ONE: _1n,\n create: (num) => mod(num, ORDER),\n isValid: (num) => {\n if (typeof num !== 'bigint')\n throw new Error(`Invalid field element: expected bigint, got ${typeof num}`);\n return _0n <= num && num < ORDER; // 0 is valid element, but it's not invertible\n },\n is0: (num) => num === _0n,\n isOdd: (num) => (num & _1n) === _1n,\n neg: (num) => mod(-num, ORDER),\n eql: (lhs, rhs) => lhs === rhs,\n sqr: (num) => mod(num * num, ORDER),\n add: (lhs, rhs) => mod(lhs + rhs, ORDER),\n sub: (lhs, rhs) => mod(lhs - rhs, ORDER),\n mul: (lhs, rhs) => mod(lhs * rhs, ORDER),\n pow: (num, power) => FpPow(f, num, power),\n div: (lhs, rhs) => mod(lhs * invert(rhs, ORDER), ORDER),\n // Same as above, but doesn't normalize\n sqrN: (num) => num * num,\n addN: (lhs, rhs) => lhs + rhs,\n subN: (lhs, rhs) => lhs - rhs,\n mulN: (lhs, rhs) => lhs * rhs,\n inv: (num) => invert(num, ORDER),\n sqrt: redef.sqrt || ((n) => sqrtP(f, n)),\n invertBatch: (lst) => FpInvertBatch(f, lst),\n // TODO: do we really need constant cmov?\n // We don't have const-time bigints anyway, so probably will be not very useful\n cmov: (a, b, c) => (c ? b : a),\n toBytes: (num) => (isLE ? numberToBytesLE(num, BYTES) : numberToBytesBE(num, BYTES)),\n fromBytes: (bytes) => {\n if (bytes.length !== BYTES)\n throw new Error(`Fp.fromBytes: expected ${BYTES}, got ${bytes.length}`);\n return isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);\n },\n });\n return Object.freeze(f);\n}\nexport function FpSqrtOdd(Fp, elm) {\n if (!Fp.isOdd)\n throw new Error(`Field doesn't have isOdd`);\n const root = Fp.sqrt(elm);\n return Fp.isOdd(root) ? root : Fp.neg(root);\n}\nexport function FpSqrtEven(Fp, elm) {\n if (!Fp.isOdd)\n throw new Error(`Field doesn't have isOdd`);\n const root = Fp.sqrt(elm);\n return Fp.isOdd(root) ? Fp.neg(root) : root;\n}\n/**\n * \"Constant-time\" private key generation utility.\n * Same as mapKeyToField, but accepts less bytes (40 instead of 48 for 32-byte field).\n * Which makes it slightly more biased, less secure.\n * @deprecated use mapKeyToField instead\n */\nexport function hashToPrivateScalar(hash, groupOrder, isLE = false) {\n hash = ensureBytes('privateHash', hash);\n const hashLen = hash.length;\n const minLen = nLength(groupOrder).nByteLength + 8;\n if (minLen < 24 || hashLen < minLen || hashLen > 1024)\n throw new Error(`hashToPrivateScalar: expected ${minLen}-1024 bytes of input, got ${hashLen}`);\n const num = isLE ? bytesToNumberLE(hash) : bytesToNumberBE(hash);\n return mod(num, groupOrder - _1n) + _1n;\n}\n/**\n * Returns total number of bytes consumed by the field element.\n * For example, 32 bytes for usual 256-bit weierstrass curve.\n * @param fieldOrder number of field elements, usually CURVE.n\n * @returns byte length of field\n */\nexport function getFieldBytesLength(fieldOrder) {\n if (typeof fieldOrder !== 'bigint')\n throw new Error('field order must be bigint');\n const bitLength = fieldOrder.toString(2).length;\n return Math.ceil(bitLength / 8);\n}\n/**\n * Returns minimal amount of bytes that can be safely reduced\n * by field order.\n * Should be 2^-128 for 128-bit curve such as P256.\n * @param fieldOrder number of field elements, usually CURVE.n\n * @returns byte length of target hash\n */\nexport function getMinHashLength(fieldOrder) {\n const length = getFieldBytesLength(fieldOrder);\n return length + Math.ceil(length / 2);\n}\n/**\n * \"Constant-time\" private key generation utility.\n * Can take (n + n/2) or more bytes of uniform input e.g. from CSPRNG or KDF\n * and convert them into private scalar, with the modulo bias being negligible.\n * Needs at least 48 bytes of input for 32-byte private key.\n * https://research.kudelskisecurity.com/2020/07/28/the-definitive-guide-to-modulo-bias-and-how-to-avoid-it/\n * FIPS 186-5, A.2 https://csrc.nist.gov/publications/detail/fips/186/5/final\n * RFC 9380, https://www.rfc-editor.org/rfc/rfc9380#section-5\n * @param hash hash output from SHA3 or a similar function\n * @param groupOrder size of subgroup - (e.g. secp256k1.CURVE.n)\n * @param isLE interpret hash bytes as LE num\n * @returns valid private scalar\n */\nexport function mapHashToField(key, fieldOrder, isLE = false) {\n const len = key.length;\n const fieldLen = getFieldBytesLength(fieldOrder);\n const minLen = getMinHashLength(fieldOrder);\n // No small numbers: need to understand bias story. No huge numbers: easier to detect JS timings.\n if (len < 16 || len < minLen || len > 1024)\n throw new Error(`expected ${minLen}-1024 bytes of input, got ${len}`);\n const num = isLE ? bytesToNumberBE(key) : bytesToNumberLE(key);\n // `mod(x, 11)` can sometimes produce 0. `mod(x, 10) + 1` is the same, but no 0\n const reduced = mod(num, fieldOrder - _1n) + _1n;\n return isLE ? numberToBytesLE(reduced, fieldLen) : numberToBytesBE(reduced, fieldLen);\n}\n//# sourceMappingURL=modular.js.map","/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\n// Abelian group utilities\nimport { validateField, nLength } from './modular.js';\nimport { validateObject } from './utils.js';\nconst _0n = BigInt(0);\nconst _1n = BigInt(1);\n// Elliptic curve multiplication of Point by scalar. Fragile.\n// Scalars should always be less than curve order: this should be checked inside of a curve itself.\n// Creates precomputation tables for fast multiplication:\n// - private scalar is split by fixed size windows of W bits\n// - every window point is collected from window's table & added to accumulator\n// - since windows are different, same point inside tables won't be accessed more than once per calc\n// - each multiplication is 'Math.ceil(CURVE_ORDER / 𝑊) + 1' point additions (fixed for any scalar)\n// - +1 window is neccessary for wNAF\n// - wNAF reduces table size: 2x less memory + 2x faster generation, but 10% slower multiplication\n// TODO: Research returning 2d JS array of windows, instead of a single window. This would allow\n// windows to be in different memory locations\nexport function wNAF(c, bits) {\n const constTimeNegate = (condition, item) => {\n const neg = item.negate();\n return condition ? neg : item;\n };\n const opts = (W) => {\n const windows = Math.ceil(bits / W) + 1; // +1, because\n const windowSize = 2 ** (W - 1); // -1 because we skip zero\n return { windows, windowSize };\n };\n return {\n constTimeNegate,\n // non-const time multiplication ladder\n unsafeLadder(elm, n) {\n let p = c.ZERO;\n let d = elm;\n while (n > _0n) {\n if (n & _1n)\n p = p.add(d);\n d = d.double();\n n >>= _1n;\n }\n return p;\n },\n /**\n * Creates a wNAF precomputation window. Used for caching.\n * Default window size is set by `utils.precompute()` and is equal to 8.\n * Number of precomputed points depends on the curve size:\n * 2^(𝑊−1) * (Math.ceil(𝑛 / 𝑊) + 1), where:\n * - 𝑊 is the window size\n * - 𝑛 is the bitlength of the curve order.\n * For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.\n * @returns precomputed point tables flattened to a single array\n */\n precomputeWindow(elm, W) {\n const { windows, windowSize } = opts(W);\n const points = [];\n let p = elm;\n let base = p;\n for (let window = 0; window < windows; window++) {\n base = p;\n points.push(base);\n // =1, because we skip zero\n for (let i = 1; i < windowSize; i++) {\n base = base.add(p);\n points.push(base);\n }\n p = base.double();\n }\n return points;\n },\n /**\n * Implements ec multiplication using precomputed tables and w-ary non-adjacent form.\n * @param W window size\n * @param precomputes precomputed tables\n * @param n scalar (we don't check here, but should be less than curve order)\n * @returns real and fake (for const-time) points\n */\n wNAF(W, precomputes, n) {\n // TODO: maybe check that scalar is less than group order? wNAF behavious is undefined otherwise\n // But need to carefully remove other checks before wNAF. ORDER == bits here\n const { windows, windowSize } = opts(W);\n let p = c.ZERO;\n let f = c.BASE;\n const mask = BigInt(2 ** W - 1); // Create mask with W ones: 0b1111 for W=4 etc.\n const maxNumber = 2 ** W;\n const shiftBy = BigInt(W);\n for (let window = 0; window < windows; window++) {\n const offset = window * windowSize;\n // Extract W bits.\n let wbits = Number(n & mask);\n // Shift number by W bits.\n n >>= shiftBy;\n // If the bits are bigger than max size, we'll split those.\n // +224 => 256 - 32\n if (wbits > windowSize) {\n wbits -= maxNumber;\n n += _1n;\n }\n // This code was first written with assumption that 'f' and 'p' will never be infinity point:\n // since each addition is multiplied by 2 ** W, it cannot cancel each other. However,\n // there is negate now: it is possible that negated element from low value\n // would be the same as high element, which will create carry into next window.\n // It's not obvious how this can fail, but still worth investigating later.\n // Check if we're onto Zero point.\n // Add random point inside current window to f.\n const offset1 = offset;\n const offset2 = offset + Math.abs(wbits) - 1; // -1 because we skip zero\n const cond1 = window % 2 !== 0;\n const cond2 = wbits < 0;\n if (wbits === 0) {\n // The most important part for const-time getPublicKey\n f = f.add(constTimeNegate(cond1, precomputes[offset1]));\n }\n else {\n p = p.add(constTimeNegate(cond2, precomputes[offset2]));\n }\n }\n // JIT-compiler should not eliminate f here, since it will later be used in normalizeZ()\n // Even if the variable is still unused, there are some checks which will\n // throw an exception, so compiler needs to prove they won't happen, which is hard.\n // At this point there is a way to F be infinity-point even if p is not,\n // which makes it less const-time: around 1 bigint multiply.\n return { p, f };\n },\n wNAFCached(P, precomputesMap, n, transform) {\n // @ts-ignore\n const W = P._WINDOW_SIZE || 1;\n // Calculate precomputes on a first run, reuse them after\n let comp = precomputesMap.get(P);\n if (!comp) {\n comp = this.precomputeWindow(P, W);\n if (W !== 1) {\n precomputesMap.set(P, transform(comp));\n }\n }\n return this.wNAF(W, comp, n);\n },\n };\n}\nexport function validateBasic(curve) {\n validateField(curve.Fp);\n validateObject(curve, {\n n: 'bigint',\n h: 'bigint',\n Gx: 'field',\n Gy: 'field',\n }, {\n nBitLength: 'isSafeInteger',\n nByteLength: 'isSafeInteger',\n });\n // Set defaults\n return Object.freeze({\n ...nLength(curve.n, curve.nBitLength),\n ...curve,\n ...{ p: curve.Fp.ORDER },\n });\n}\n//# sourceMappingURL=curve.js.map","/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\n// Short Weierstrass curve. The formula is: y² = x³ + ax + b\nimport * as mod from './modular.js';\nimport * as ut from './utils.js';\nimport { ensureBytes } from './utils.js';\nimport { wNAF, validateBasic } from './curve.js';\nfunction validatePointOpts(curve) {\n const opts = validateBasic(curve);\n ut.validateObject(opts, {\n a: 'field',\n b: 'field',\n }, {\n allowedPrivateKeyLengths: 'array',\n wrapPrivateKey: 'boolean',\n isTorsionFree: 'function',\n clearCofactor: 'function',\n allowInfinityPoint: 'boolean',\n fromBytes: 'function',\n toBytes: 'function',\n });\n const { endo, Fp, a } = opts;\n if (endo) {\n if (!Fp.eql(a, Fp.ZERO)) {\n throw new Error('Endomorphism can only be defined for Koblitz curves that have a=0');\n }\n if (typeof endo !== 'object' ||\n typeof endo.beta !== 'bigint' ||\n typeof endo.splitScalar !== 'function') {\n throw new Error('Expected endomorphism with beta: bigint and splitScalar: function');\n }\n }\n return Object.freeze({ ...opts });\n}\n// ASN.1 DER encoding utilities\nconst { bytesToNumberBE: b2n, hexToBytes: h2b } = ut;\nexport const DER = {\n // asn.1 DER encoding utils\n Err: class DERErr extends Error {\n constructor(m = '') {\n super(m);\n }\n },\n _parseInt(data) {\n const { Err: E } = DER;\n if (data.length < 2 || data[0] !== 0x02)\n throw new E('Invalid signature integer tag');\n const len = data[1];\n const res = data.subarray(2, len + 2);\n if (!len || res.length !== len)\n throw new E('Invalid signature integer: wrong length');\n // https://crypto.stackexchange.com/a/57734 Leftmost bit of first byte is 'negative' flag,\n // since we always use positive integers here. It must always be empty:\n // - add zero byte if exists\n // - if next byte doesn't have a flag, leading zero is not allowed (minimal encoding)\n if (res[0] & 0b10000000)\n throw new E('Invalid signature integer: negative');\n if (res[0] === 0x00 && !(res[1] & 0b10000000))\n throw new E('Invalid signature integer: unnecessary leading zero');\n return { d: b2n(res), l: data.subarray(len + 2) }; // d is data, l is left\n },\n toSig(hex) {\n // parse DER signature\n const { Err: E } = DER;\n const data = typeof hex === 'string' ? h2b(hex) : hex;\n if (!(data instanceof Uint8Array))\n throw new Error('ui8a expected');\n let l = data.length;\n if (l < 2 || data[0] != 0x30)\n throw new E('Invalid signature tag');\n if (data[1] !== l - 2)\n throw new E('Invalid signature: incorrect length');\n const { d: r, l: sBytes } = DER._parseInt(data.subarray(2));\n const { d: s, l: rBytesLeft } = DER._parseInt(sBytes);\n if (rBytesLeft.length)\n throw new E('Invalid signature: left bytes after parsing');\n return { r, s };\n },\n hexFromSig(sig) {\n // Add leading zero if first byte has negative bit enabled. More details in '_parseInt'\n const slice = (s) => (Number.parseInt(s[0], 16) & 0b1000 ? '00' + s : s);\n const h = (num) => {\n const hex = num.toString(16);\n return hex.length & 1 ? `0${hex}` : hex;\n };\n const s = slice(h(sig.s));\n const r = slice(h(sig.r));\n const shl = s.length / 2;\n const rhl = r.length / 2;\n const sl = h(shl);\n const rl = h(rhl);\n return `30${h(rhl + shl + 4)}02${rl}${r}02${sl}${s}`;\n },\n};\n// Be friendly to bad ECMAScript parsers by not using bigint literals\n// prettier-ignore\nconst _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3), _4n = BigInt(4);\nexport function weierstrassPoints(opts) {\n const CURVE = validatePointOpts(opts);\n const { Fp } = CURVE; // All curves has same field / group length as for now, but they can differ\n const toBytes = CURVE.toBytes ||\n ((_c, point, _isCompressed) => {\n const a = point.toAffine();\n return ut.concatBytes(Uint8Array.from([0x04]), Fp.toBytes(a.x), Fp.toBytes(a.y));\n });\n const fromBytes = CURVE.fromBytes ||\n ((bytes) => {\n // const head = bytes[0];\n const tail = bytes.subarray(1);\n // if (head !== 0x04) throw new Error('Only non-compressed encoding is supported');\n const x = Fp.fromBytes(tail.subarray(0, Fp.BYTES));\n const y = Fp.fromBytes(tail.subarray(Fp.BYTES, 2 * Fp.BYTES));\n return { x, y };\n });\n /**\n * y² = x³ + ax + b: Short weierstrass curve formula\n * @returns y²\n */\n function weierstrassEquation(x) {\n const { a, b } = CURVE;\n const x2 = Fp.sqr(x); // x * x\n const x3 = Fp.mul(x2, x); // x2 * x\n return Fp.add(Fp.add(x3, Fp.mul(x, a)), b); // x3 + a * x + b\n }\n // Validate whether the passed curve params are valid.\n // We check if curve equation works for generator point.\n // `assertValidity()` won't work: `isTorsionFree()` is not available at this point in bls12-381.\n // ProjectivePoint class has not been initialized yet.\n if (!Fp.eql(Fp.sqr(CURVE.Gy), weierstrassEquation(CURVE.Gx)))\n throw new Error('bad generator point: equation left != right');\n // Valid group elements reside in range 1..n-1\n function isWithinCurveOrder(num) {\n return typeof num === 'bigint' && _0n < num && num < CURVE.n;\n }\n function assertGE(num) {\n if (!isWithinCurveOrder(num))\n throw new Error('Expected valid bigint: 0 < bigint < curve.n');\n }\n // Validates if priv key is valid and converts it to bigint.\n // Supports options allowedPrivateKeyLengths and wrapPrivateKey.\n function normPrivateKeyToScalar(key) {\n const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n } = CURVE;\n if (lengths && typeof key !== 'bigint') {\n if (key instanceof Uint8Array)\n key = ut.bytesToHex(key);\n // Normalize to hex string, pad. E.g. P521 would norm 130-132 char hex to 132-char bytes\n if (typeof key !== 'string' || !lengths.includes(key.length))\n throw new Error('Invalid key');\n key = key.padStart(nByteLength * 2, '0');\n }\n let num;\n try {\n num =\n typeof key === 'bigint'\n ? key\n : ut.bytesToNumberBE(ensureBytes('private key', key, nByteLength));\n }\n catch (error) {\n throw new Error(`private key must be ${nByteLength} bytes, hex or bigint, not ${typeof key}`);\n }\n if (wrapPrivateKey)\n num = mod.mod(num, n); // disabled by default, enabled for BLS\n assertGE(num); // num in range [1..N-1]\n return num;\n }\n const pointPrecomputes = new Map();\n function assertPrjPoint(other) {\n if (!(other instanceof Point))\n throw new Error('ProjectivePoint expected');\n }\n /**\n * Projective Point works in 3d / projective (homogeneous) coordinates: (x, y, z) ∋ (x=x/z, y=y/z)\n * Default Point works in 2d / affine coordinates: (x, y)\n * We're doing calculations in projective, because its operations don't require costly inversion.\n */\n class Point {\n constructor(px, py, pz) {\n this.px = px;\n this.py = py;\n this.pz = pz;\n if (px == null || !Fp.isValid(px))\n throw new Error('x required');\n if (py == null || !Fp.isValid(py))\n throw new Error('y required');\n if (pz == null || !Fp.isValid(pz))\n throw new Error('z required');\n }\n // Does not validate if the point is on-curve.\n // Use fromHex instead, or call assertValidity() later.\n static fromAffine(p) {\n const { x, y } = p || {};\n if (!p || !Fp.isValid(x) || !Fp.isValid(y))\n throw new Error('invalid affine point');\n if (p instanceof Point)\n throw new Error('projective point not allowed');\n const is0 = (i) => Fp.eql(i, Fp.ZERO);\n // fromAffine(x:0, y:0) would produce (x:0, y:0, z:1), but we need (x:0, y:1, z:0)\n if (is0(x) && is0(y))\n return Point.ZERO;\n return new Point(x, y, Fp.ONE);\n }\n get x() {\n return this.toAffine().x;\n }\n get y() {\n return this.toAffine().y;\n }\n /**\n * Takes a bunch of Projective Points but executes only one\n * inversion on all of them. Inversion is very slow operation,\n * so this improves performance massively.\n * Optimization: converts a list of projective points to a list of identical points with Z=1.\n */\n static normalizeZ(points) {\n const toInv = Fp.invertBatch(points.map((p) => p.pz));\n return points.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);\n }\n /**\n * Converts hash string or Uint8Array to Point.\n * @param hex short/long ECDSA hex\n */\n static fromHex(hex) {\n const P = Point.fromAffine(fromBytes(ensureBytes('pointHex', hex)));\n P.assertValidity();\n return P;\n }\n // Multiplies generator point by privateKey.\n static fromPrivateKey(privateKey) {\n return Point.BASE.multiply(normPrivateKeyToScalar(privateKey));\n }\n // \"Private method\", don't use it directly\n _setWindowSize(windowSize) {\n this._WINDOW_SIZE = windowSize;\n pointPrecomputes.delete(this);\n }\n // A point on curve is valid if it conforms to equation.\n assertValidity() {\n if (this.is0()) {\n // (0, 1, 0) aka ZERO is invalid in most contexts.\n // In BLS, ZERO can be serialized, so we allow it.\n // (0, 0, 0) is wrong representation of ZERO and is always invalid.\n if (CURVE.allowInfinityPoint && !Fp.is0(this.py))\n return;\n throw new Error('bad point: ZERO');\n }\n // Some 3rd-party test vectors require different wording between here & `fromCompressedHex`\n const { x, y } = this.toAffine();\n // Check if x, y are valid field elements\n if (!Fp.isValid(x) || !Fp.isValid(y))\n throw new Error('bad point: x or y not FE');\n const left = Fp.sqr(y); // y²\n const right = weierstrassEquation(x); // x³ + ax + b\n if (!Fp.eql(left, right))\n throw new Error('bad point: equation left != right');\n if (!this.isTorsionFree())\n throw new Error('bad point: not in prime-order subgroup');\n }\n hasEvenY() {\n const { y } = this.toAffine();\n if (Fp.isOdd)\n return !Fp.isOdd(y);\n throw new Error(\"Field doesn't support isOdd\");\n }\n /**\n * Compare one point to another.\n */\n equals(other) {\n assertPrjPoint(other);\n const { px: X1, py: Y1, pz: Z1 } = this;\n const { px: X2, py: Y2, pz: Z2 } = other;\n const U1 = Fp.eql(Fp.mul(X1, Z2), Fp.mul(X2, Z1));\n const U2 = Fp.eql(Fp.mul(Y1, Z2), Fp.mul(Y2, Z1));\n return U1 && U2;\n }\n /**\n * Flips point to one corresponding to (x, -y) in Affine coordinates.\n */\n negate() {\n return new Point(this.px, Fp.neg(this.py), this.pz);\n }\n // Renes-Costello-Batina exception-free doubling formula.\n // There is 30% faster Jacobian formula, but it is not complete.\n // https://eprint.iacr.org/2015/1060, algorithm 3\n // Cost: 8M + 3S + 3*a + 2*b3 + 15add.\n double() {\n const { a, b } = CURVE;\n const b3 = Fp.mul(b, _3n);\n const { px: X1, py: Y1, pz: Z1 } = this;\n let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; // prettier-ignore\n let t0 = Fp.mul(X1, X1); // step 1\n let t1 = Fp.mul(Y1, Y1);\n let t2 = Fp.mul(Z1, Z1);\n let t3 = Fp.mul(X1, Y1);\n t3 = Fp.add(t3, t3); // step 5\n Z3 = Fp.mul(X1, Z1);\n Z3 = Fp.add(Z3, Z3);\n X3 = Fp.mul(a, Z3);\n Y3 = Fp.mul(b3, t2);\n Y3 = Fp.add(X3, Y3); // step 10\n X3 = Fp.sub(t1, Y3);\n Y3 = Fp.add(t1, Y3);\n Y3 = Fp.mul(X3, Y3);\n X3 = Fp.mul(t3, X3);\n Z3 = Fp.mul(b3, Z3); // step 15\n t2 = Fp.mul(a, t2);\n t3 = Fp.sub(t0, t2);\n t3 = Fp.mul(a, t3);\n t3 = Fp.add(t3, Z3);\n Z3 = Fp.add(t0, t0); // step 20\n t0 = Fp.add(Z3, t0);\n t0 = Fp.add(t0, t2);\n t0 = Fp.mul(t0, t3);\n Y3 = Fp.add(Y3, t0);\n t2 = Fp.mul(Y1, Z1); // step 25\n t2 = Fp.add(t2, t2);\n t0 = Fp.mul(t2, t3);\n X3 = Fp.sub(X3, t0);\n Z3 = Fp.mul(t2, t1);\n Z3 = Fp.add(Z3, Z3); // step 30\n Z3 = Fp.add(Z3, Z3);\n return new Point(X3, Y3, Z3);\n }\n // Renes-Costello-Batina exception-free addition formula.\n // There is 30% faster Jacobian formula, but it is not complete.\n // https://eprint.iacr.org/2015/1060, algorithm 1\n // Cost: 12M + 0S + 3*a + 3*b3 + 23add.\n add(other) {\n assertPrjPoint(other);\n const { px: X1, py: Y1, pz: Z1 } = this;\n const { px: X2, py: Y2, pz: Z2 } = other;\n let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; // prettier-ignore\n const a = CURVE.a;\n const b3 = Fp.mul(CURVE.b, _3n);\n let t0 = Fp.mul(X1, X2); // step 1\n let t1 = Fp.mul(Y1, Y2);\n let t2 = Fp.mul(Z1, Z2);\n let t3 = Fp.add(X1, Y1);\n let t4 = Fp.add(X2, Y2); // step 5\n t3 = Fp.mul(t3, t4);\n t4 = Fp.add(t0, t1);\n t3 = Fp.sub(t3, t4);\n t4 = Fp.add(X1, Z1);\n let t5 = Fp.add(X2, Z2); // step 10\n t4 = Fp.mul(t4, t5);\n t5 = Fp.add(t0, t2);\n t4 = Fp.sub(t4, t5);\n t5 = Fp.add(Y1, Z1);\n X3 = Fp.add(Y2, Z2); // step 15\n t5 = Fp.mul(t5, X3);\n X3 = Fp.add(t1, t2);\n t5 = Fp.sub(t5, X3);\n Z3 = Fp.mul(a, t4);\n X3 = Fp.mul(b3, t2); // step 20\n Z3 = Fp.add(X3, Z3);\n X3 = Fp.sub(t1, Z3);\n Z3 = Fp.add(t1, Z3);\n Y3 = Fp.mul(X3, Z3);\n t1 = Fp.add(t0, t0); // step 25\n t1 = Fp.add(t1, t0);\n t2 = Fp.mul(a, t2);\n t4 = Fp.mul(b3, t4);\n t1 = Fp.add(t1, t2);\n t2 = Fp.sub(t0, t2); // step 30\n t2 = Fp.mul(a, t2);\n t4 = Fp.add(t4, t2);\n t0 = Fp.mul(t1, t4);\n Y3 = Fp.add(Y3, t0);\n t0 = Fp.mul(t5, t4); // step 35\n X3 = Fp.mul(t3, X3);\n X3 = Fp.sub(X3, t0);\n t0 = Fp.mul(t3, t1);\n Z3 = Fp.mul(t5, Z3);\n Z3 = Fp.add(Z3, t0); // step 40\n return new Point(X3, Y3, Z3);\n }\n subtract(other) {\n return this.add(other.negate());\n }\n is0() {\n return this.equals(Point.ZERO);\n }\n wNAF(n) {\n return wnaf.wNAFCached(this, pointPrecomputes, n, (comp) => {\n const toInv = Fp.invertBatch(comp.map((p) => p.pz));\n return comp.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);\n });\n }\n /**\n * Non-constant-time multiplication. Uses double-and-add algorithm.\n * It's faster, but should only be used when you don't care about\n * an exposed private key e.g. sig verification, which works over *public* keys.\n */\n multiplyUnsafe(n) {\n const I = Point.ZERO;\n if (n === _0n)\n return I;\n assertGE(n); // Will throw on 0\n if (n === _1n)\n return this;\n const { endo } = CURVE;\n if (!endo)\n return wnaf.unsafeLadder(this, n);\n // Apply endomorphism\n let { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);\n let k1p = I;\n let k2p = I;\n let d = this;\n while (k1 > _0n || k2 > _0n) {\n if (k1 & _1n)\n k1p = k1p.add(d);\n if (k2 & _1n)\n k2p = k2p.add(d);\n d = d.double();\n k1 >>= _1n;\n k2 >>= _1n;\n }\n if (k1neg)\n k1p = k1p.negate();\n if (k2neg)\n k2p = k2p.negate();\n k2p = new Point(Fp.mul(k2p.px, endo.beta), k2p.py, k2p.pz);\n return k1p.add(k2p);\n }\n /**\n * Constant time multiplication.\n * Uses wNAF method. Windowed method may be 10% faster,\n * but takes 2x longer to generate and consumes 2x memory.\n * Uses precomputes when available.\n * Uses endomorphism for Koblitz curves.\n * @param scalar by which the point would be multiplied\n * @returns New point\n */\n multiply(scalar) {\n assertGE(scalar);\n let n = scalar;\n let point, fake; // Fake point is used to const-time mult\n const { endo } = CURVE;\n if (endo) {\n const { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);\n let { p: k1p, f: f1p } = this.wNAF(k1);\n let { p: k2p, f: f2p } = this.wNAF(k2);\n k1p = wnaf.constTimeNegate(k1neg, k1p);\n k2p = wnaf.constTimeNegate(k2neg, k2p);\n k2p = new Point(Fp.mul(k2p.px, endo.beta), k2p.py, k2p.pz);\n point = k1p.add(k2p);\n fake = f1p.add(f2p);\n }\n else {\n const { p, f } = this.wNAF(n);\n point = p;\n fake = f;\n }\n // Normalize `z` for both points, but return only real one\n return Point.normalizeZ([point, fake])[0];\n }\n /**\n * Efficiently calculate `aP + bQ`. Unsafe, can expose private key, if used incorrectly.\n * Not using Strauss-Shamir trick: precomputation tables are faster.\n * The trick could be useful if both P and Q are not G (not in our case).\n * @returns non-zero affine point\n */\n multiplyAndAddUnsafe(Q, a, b) {\n const G = Point.BASE; // No Strauss-Shamir trick: we have 10% faster G precomputes\n const mul = (P, a // Select faster multiply() method\n ) => (a === _0n || a === _1n || !P.equals(G) ? P.multiplyUnsafe(a) : P.multiply(a));\n const sum = mul(this, a).add(mul(Q, b));\n return sum.is0() ? undefined : sum;\n }\n // Converts Projective point to affine (x, y) coordinates.\n // Can accept precomputed Z^-1 - for example, from invertBatch.\n // (x, y, z) ∋ (x=x/z, y=y/z)\n toAffine(iz) {\n const { px: x, py: y, pz: z } = this;\n const is0 = this.is0();\n // If invZ was 0, we return zero point. However we still want to execute\n // all operations, so we replace invZ with a random number, 1.\n if (iz == null)\n iz = is0 ? Fp.ONE : Fp.inv(z);\n const ax = Fp.mul(x, iz);\n const ay = Fp.mul(y, iz);\n const zz = Fp.mul(z, iz);\n if (is0)\n return { x: Fp.ZERO, y: Fp.ZERO };\n if (!Fp.eql(zz, Fp.ONE))\n throw new Error('invZ was invalid');\n return { x: ax, y: ay };\n }\n isTorsionFree() {\n const { h: cofactor, isTorsionFree } = CURVE;\n if (cofactor === _1n)\n return true; // No subgroups, always torsion-free\n if (isTorsionFree)\n return isTorsionFree(Point, this);\n throw new Error('isTorsionFree() has not been declared for the elliptic curve');\n }\n clearCofactor() {\n const { h: cofactor, clearCofactor } = CURVE;\n if (cofactor === _1n)\n return this; // Fast-path\n if (clearCofactor)\n return clearCofactor(Point, this);\n return this.multiplyUnsafe(CURVE.h);\n }\n toRawBytes(isCompressed = true) {\n this.assertValidity();\n return toBytes(Point, this, isCompressed);\n }\n toHex(isCompressed = true) {\n return ut.bytesToHex(this.toRawBytes(isCompressed));\n }\n }\n Point.BASE = new Point(CURVE.Gx, CURVE.Gy, Fp.ONE);\n Point.ZERO = new Point(Fp.ZERO, Fp.ONE, Fp.ZERO);\n const _bits = CURVE.nBitLength;\n const wnaf = wNAF(Point, CURVE.endo ? Math.ceil(_bits / 2) : _bits);\n // Validate if generator point is on curve\n return {\n CURVE,\n ProjectivePoint: Point,\n normPrivateKeyToScalar,\n weierstrassEquation,\n isWithinCurveOrder,\n };\n}\nfunction validateOpts(curve) {\n const opts = validateBasic(curve);\n ut.validateObject(opts, {\n hash: 'hash',\n hmac: 'function',\n randomBytes: 'function',\n }, {\n bits2int: 'function',\n bits2int_modN: 'function',\n lowS: 'boolean',\n });\n return Object.freeze({ lowS: true, ...opts });\n}\nexport function weierstrass(curveDef) {\n const CURVE = validateOpts(curveDef);\n const { Fp, n: CURVE_ORDER } = CURVE;\n const compressedLen = Fp.BYTES + 1; // e.g. 33 for 32\n const uncompressedLen = 2 * Fp.BYTES + 1; // e.g. 65 for 32\n function isValidFieldElement(num) {\n return _0n < num && num < Fp.ORDER; // 0 is banned since it's not invertible FE\n }\n function modN(a) {\n return mod.mod(a, CURVE_ORDER);\n }\n function invN(a) {\n return mod.invert(a, CURVE_ORDER);\n }\n const { ProjectivePoint: Point, normPrivateKeyToScalar, weierstrassEquation, isWithinCurveOrder, } = weierstrassPoints({\n ...CURVE,\n toBytes(_c, point, isCompressed) {\n const a = point.toAffine();\n const x = Fp.toBytes(a.x);\n const cat = ut.concatBytes;\n if (isCompressed) {\n return cat(Uint8Array.from([point.hasEvenY() ? 0x02 : 0x03]), x);\n }\n else {\n return cat(Uint8Array.from([0x04]), x, Fp.toBytes(a.y));\n }\n },\n fromBytes(bytes) {\n const len = bytes.length;\n const head = bytes[0];\n const tail = bytes.subarray(1);\n // this.assertValidity() is done inside of fromHex\n if (len === compressedLen && (head === 0x02 || head === 0x03)) {\n const x = ut.bytesToNumberBE(tail);\n if (!isValidFieldElement(x))\n throw new Error('Point is not on curve');\n const y2 = weierstrassEquation(x); // y² = x³ + ax + b\n let y = Fp.sqrt(y2); // y = y² ^ (p+1)/4\n const isYOdd = (y & _1n) === _1n;\n // ECDSA\n const isHeadOdd = (head & 1) === 1;\n if (isHeadOdd !== isYOdd)\n y = Fp.neg(y);\n return { x, y };\n }\n else if (len === uncompressedLen && head === 0x04) {\n const x = Fp.fromBytes(tail.subarray(0, Fp.BYTES));\n const y = Fp.fromBytes(tail.subarray(Fp.BYTES, 2 * Fp.BYTES));\n return { x, y };\n }\n else {\n throw new Error(`Point of length ${len} was invalid. Expected ${compressedLen} compressed bytes or ${uncompressedLen} uncompressed bytes`);\n }\n },\n });\n const numToNByteStr = (num) => ut.bytesToHex(ut.numberToBytesBE(num, CURVE.nByteLength));\n function isBiggerThanHalfOrder(number) {\n const HALF = CURVE_ORDER >> _1n;\n return number > HALF;\n }\n function normalizeS(s) {\n return isBiggerThanHalfOrder(s) ? modN(-s) : s;\n }\n // slice bytes num\n const slcNum = (b, from, to) => ut.bytesToNumberBE(b.slice(from, to));\n /**\n * ECDSA signature with its (r, s) properties. Supports DER & compact representations.\n */\n class Signature {\n constructor(r, s, recovery) {\n this.r = r;\n this.s = s;\n this.recovery = recovery;\n this.assertValidity();\n }\n // pair (bytes of r, bytes of s)\n static fromCompact(hex) {\n const l = CURVE.nByteLength;\n hex = ensureBytes('compactSignature', hex, l * 2);\n return new Signature(slcNum(hex, 0, l), slcNum(hex, l, 2 * l));\n }\n // DER encoded ECDSA signature\n // https://bitcoin.stackexchange.com/questions/57644/what-are-the-parts-of-a-bitcoin-transaction-input-script\n static fromDER(hex) {\n const { r, s } = DER.toSig(ensureBytes('DER', hex));\n return new Signature(r, s);\n }\n assertValidity() {\n // can use assertGE here\n if (!isWithinCurveOrder(this.r))\n throw new Error('r must be 0 < r < CURVE.n');\n if (!isWithinCurveOrder(this.s))\n throw new Error('s must be 0 < s < CURVE.n');\n }\n addRecoveryBit(recovery) {\n return new Signature(this.r, this.s, recovery);\n }\n recoverPublicKey(msgHash) {\n const { r, s, recovery: rec } = this;\n const h = bits2int_modN(ensureBytes('msgHash', msgHash)); // Truncate hash\n if (rec == null || ![0, 1, 2, 3].includes(rec))\n throw new Error('recovery id invalid');\n const radj = rec === 2 || rec === 3 ? r + CURVE.n : r;\n if (radj >= Fp.ORDER)\n throw new Error('recovery id 2 or 3 invalid');\n const prefix = (rec & 1) === 0 ? '02' : '03';\n const R = Point.fromHex(prefix + numToNByteStr(radj));\n const ir = invN(radj); // r^-1\n const u1 = modN(-h * ir); // -hr^-1\n const u2 = modN(s * ir); // sr^-1\n const Q = Point.BASE.multiplyAndAddUnsafe(R, u1, u2); // (sr^-1)R-(hr^-1)G = -(hr^-1)G + (sr^-1)\n if (!Q)\n throw new Error('point at infinify'); // unsafe is fine: no priv data leaked\n Q.assertValidity();\n return Q;\n }\n // Signatures should be low-s, to prevent malleability.\n hasHighS() {\n return isBiggerThanHalfOrder(this.s);\n }\n normalizeS() {\n return this.hasHighS() ? new Signature(this.r, modN(-this.s), this.recovery) : this;\n }\n // DER-encoded\n toDERRawBytes() {\n return ut.hexToBytes(this.toDERHex());\n }\n toDERHex() {\n return DER.hexFromSig({ r: this.r, s: this.s });\n }\n // padded bytes of r, then padded bytes of s\n toCompactRawBytes() {\n return ut.hexToBytes(this.toCompactHex());\n }\n toCompactHex() {\n return numToNByteStr(this.r) + numToNByteStr(this.s);\n }\n }\n const utils = {\n isValidPrivateKey(privateKey) {\n try {\n normPrivateKeyToScalar(privateKey);\n return true;\n }\n catch (error) {\n return false;\n }\n },\n normPrivateKeyToScalar: normPrivateKeyToScalar,\n /**\n * Produces cryptographically secure private key from random of size\n * (groupLen + ceil(groupLen / 2)) with modulo bias being negligible.\n */\n randomPrivateKey: () => {\n const length = mod.getMinHashLength(CURVE.n);\n return mod.mapHashToField(CURVE.randomBytes(length), CURVE.n);\n },\n /**\n * Creates precompute table for an arbitrary EC point. Makes point \"cached\".\n * Allows to massively speed-up `point.multiply(scalar)`.\n * @returns cached point\n * @example\n * const fast = utils.precompute(8, ProjectivePoint.fromHex(someonesPubKey));\n * fast.multiply(privKey); // much faster ECDH now\n */\n precompute(windowSize = 8, point = Point.BASE) {\n point._setWindowSize(windowSize);\n point.multiply(BigInt(3)); // 3 is arbitrary, just need any number here\n return point;\n },\n };\n /**\n * Computes public key for a private key. Checks for validity of the private key.\n * @param privateKey private key\n * @param isCompressed whether to return compact (default), or full key\n * @returns Public key, full when isCompressed=false; short when isCompressed=true\n */\n function getPublicKey(privateKey, isCompressed = true) {\n return Point.fromPrivateKey(privateKey).toRawBytes(isCompressed);\n }\n /**\n * Quick and dirty check for item being public key. Does not validate hex, or being on-curve.\n */\n function isProbPub(item) {\n const arr = item instanceof Uint8Array;\n const str = typeof item === 'string';\n const len = (arr || str) && item.length;\n if (arr)\n return len === compressedLen || len === uncompressedLen;\n if (str)\n return len === 2 * compressedLen || len === 2 * uncompressedLen;\n if (item instanceof Point)\n return true;\n return false;\n }\n /**\n * ECDH (Elliptic Curve Diffie Hellman).\n * Computes shared public key from private key and public key.\n * Checks: 1) private key validity 2) shared key is on-curve.\n * Does NOT hash the result.\n * @param privateA private key\n * @param publicB different public key\n * @param isCompressed whether to return compact (default), or full key\n * @returns shared public key\n */\n function getSharedSecret(privateA, publicB, isCompressed = true) {\n if (isProbPub(privateA))\n throw new Error('first arg must be private key');\n if (!isProbPub(publicB))\n throw new Error('second arg must be public key');\n const b = Point.fromHex(publicB); // check for being on-curve\n return b.multiply(normPrivateKeyToScalar(privateA)).toRawBytes(isCompressed);\n }\n // RFC6979: ensure ECDSA msg is X bytes and < N. RFC suggests optional truncating via bits2octets.\n // FIPS 186-4 4.6 suggests the leftmost min(nBitLen, outLen) bits, which matches bits2int.\n // bits2int can produce res>N, we can do mod(res, N) since the bitLen is the same.\n // int2octets can't be used; pads small msgs with 0: unacceptatble for trunc as per RFC vectors\n const bits2int = CURVE.bits2int ||\n function (bytes) {\n // For curves with nBitLength % 8 !== 0: bits2octets(bits2octets(m)) !== bits2octets(m)\n // for some cases, since bytes.length * 8 is not actual bitLength.\n const num = ut.bytesToNumberBE(bytes); // check for == u8 done here\n const delta = bytes.length * 8 - CURVE.nBitLength; // truncate to nBitLength leftmost bits\n return delta > 0 ? num >> BigInt(delta) : num;\n };\n const bits2int_modN = CURVE.bits2int_modN ||\n function (bytes) {\n return modN(bits2int(bytes)); // can't use bytesToNumberBE here\n };\n // NOTE: pads output with zero as per spec\n const ORDER_MASK = ut.bitMask(CURVE.nBitLength);\n /**\n * Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`.\n */\n function int2octets(num) {\n if (typeof num !== 'bigint')\n throw new Error('bigint expected');\n if (!(_0n <= num && num < ORDER_MASK))\n throw new Error(`bigint expected < 2^${CURVE.nBitLength}`);\n // works with order, can have different size than numToField!\n return ut.numberToBytesBE(num, CURVE.nByteLength);\n }\n // Steps A, D of RFC6979 3.2\n // Creates RFC6979 seed; converts msg/privKey to numbers.\n // Used only in sign, not in verify.\n // NOTE: we cannot assume here that msgHash has same amount of bytes as curve order, this will be wrong at least for P521.\n // Also it can be bigger for P224 + SHA256\n function prepSig(msgHash, privateKey, opts = defaultSigOpts) {\n if (['recovered', 'canonical'].some((k) => k in opts))\n throw new Error('sign() legacy options not supported');\n const { hash, randomBytes } = CURVE;\n let { lowS, prehash, extraEntropy: ent } = opts; // generates low-s sigs by default\n if (lowS == null)\n lowS = true; // RFC6979 3.2: we skip step A, because we already provide hash\n msgHash = ensureBytes('msgHash', msgHash);\n if (prehash)\n msgHash = ensureBytes('prehashed msgHash', hash(msgHash));\n // We can't later call bits2octets, since nested bits2int is broken for curves\n // with nBitLength % 8 !== 0. Because of that, we unwrap it here as int2octets call.\n // const bits2octets = (bits) => int2octets(bits2int_modN(bits))\n const h1int = bits2int_modN(msgHash);\n const d = normPrivateKeyToScalar(privateKey); // validate private key, convert to bigint\n const seedArgs = [int2octets(d), int2octets(h1int)];\n // extraEntropy. RFC6979 3.6: additional k' (optional).\n if (ent != null) {\n // K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1) || k')\n const e = ent === true ? randomBytes(Fp.BYTES) : ent; // generate random bytes OR pass as-is\n seedArgs.push(ensureBytes('extraEntropy', e)); // check for being bytes\n }\n const seed = ut.concatBytes(...seedArgs); // Step D of RFC6979 3.2\n const m = h1int; // NOTE: no need to call bits2int second time here, it is inside truncateHash!\n // Converts signature params into point w r/s, checks result for validity.\n function k2sig(kBytes) {\n // RFC 6979 Section 3.2, step 3: k = bits2int(T)\n const k = bits2int(kBytes); // Cannot use fields methods, since it is group element\n if (!isWithinCurveOrder(k))\n return; // Important: all mod() calls here must be done over N\n const ik = invN(k); // k^-1 mod n\n const q = Point.BASE.multiply(k).toAffine(); // q = Gk\n const r = modN(q.x); // r = q.x mod n\n if (r === _0n)\n return;\n // Can use scalar blinding b^-1(bm + bdr) where b ∈ [1,q−1] according to\n // https://tches.iacr.org/index.php/TCHES/article/view/7337/6509. We've decided against it:\n // a) dependency on CSPRNG b) 15% slowdown c) doesn't really help since bigints are not CT\n const s = modN(ik * modN(m + r * d)); // Not using blinding here\n if (s === _0n)\n return;\n let recovery = (q.x === r ? 0 : 2) | Number(q.y & _1n); // recovery bit (2 or 3, when q.x > n)\n let normS = s;\n if (lowS && isBiggerThanHalfOrder(s)) {\n normS = normalizeS(s); // if lowS was passed, ensure s is always\n recovery ^= 1; // // in the bottom half of N\n }\n return new Signature(r, normS, recovery); // use normS, not s\n }\n return { seed, k2sig };\n }\n const defaultSigOpts = { lowS: CURVE.lowS, prehash: false };\n const defaultVerOpts = { lowS: CURVE.lowS, prehash: false };\n /**\n * Signs message hash with a private key.\n * ```\n * sign(m, d, k) where\n * (x, y) = G × k\n * r = x mod n\n * s = (m + dr)/k mod n\n * ```\n * @param msgHash NOT message. msg needs to be hashed to `msgHash`, or use `prehash`.\n * @param privKey private key\n * @param opts lowS for non-malleable sigs. extraEntropy for mixing randomness into k. prehash will hash first arg.\n * @returns signature with recovery param\n */\n function sign(msgHash, privKey, opts = defaultSigOpts) {\n const { seed, k2sig } = prepSig(msgHash, privKey, opts); // Steps A, D of RFC6979 3.2.\n const C = CURVE;\n const drbg = ut.createHmacDrbg(C.hash.outputLen, C.nByteLength, C.hmac);\n return drbg(seed, k2sig); // Steps B, C, D, E, F, G\n }\n // Enable precomputes. Slows down first publicKey computation by 20ms.\n Point.BASE._setWindowSize(8);\n // utils.precompute(8, ProjectivePoint.BASE)\n /**\n * Verifies a signature against message hash and public key.\n * Rejects lowS signatures by default: to override,\n * specify option `{lowS: false}`. Implements section 4.1.4 from https://www.secg.org/sec1-v2.pdf:\n *\n * ```\n * verify(r, s, h, P) where\n * U1 = hs^-1 mod n\n * U2 = rs^-1 mod n\n * R = U1⋅G - U2⋅P\n * mod(R.x, n) == r\n * ```\n */\n function verify(signature, msgHash, publicKey, opts = defaultVerOpts) {\n const sg = signature;\n msgHash = ensureBytes('msgHash', msgHash);\n publicKey = ensureBytes('publicKey', publicKey);\n if ('strict' in opts)\n throw new Error('options.strict was renamed to lowS');\n const { lowS, prehash } = opts;\n let _sig = undefined;\n let P;\n try {\n if (typeof sg === 'string' || sg instanceof Uint8Array) {\n // Signature can be represented in 2 ways: compact (2*nByteLength) & DER (variable-length).\n // Since DER can also be 2*nByteLength bytes, we check for it first.\n try {\n _sig = Signature.fromDER(sg);\n }\n catch (derError) {\n if (!(derError instanceof DER.Err))\n throw derError;\n _sig = Signature.fromCompact(sg);\n }\n }\n else if (typeof sg === 'object' && typeof sg.r === 'bigint' && typeof sg.s === 'bigint') {\n const { r, s } = sg;\n _sig = new Signature(r, s);\n }\n else {\n throw new Error('PARSE');\n }\n P = Point.fromHex(publicKey);\n }\n catch (error) {\n if (error.message === 'PARSE')\n throw new Error(`signature must be Signature instance, Uint8Array or hex string`);\n return false;\n }\n if (lowS && _sig.hasHighS())\n return false;\n if (prehash)\n msgHash = CURVE.hash(msgHash);\n const { r, s } = _sig;\n const h = bits2int_modN(msgHash); // Cannot use fields methods, since it is group element\n const is = invN(s); // s^-1\n const u1 = modN(h * is); // u1 = hs^-1 mod n\n const u2 = modN(r * is); // u2 = rs^-1 mod n\n const R = Point.BASE.multiplyAndAddUnsafe(P, u1, u2)?.toAffine(); // R = u1⋅G + u2⋅P\n if (!R)\n return false;\n const v = modN(R.x);\n return v === r;\n }\n return {\n CURVE,\n getPublicKey,\n getSharedSecret,\n sign,\n verify,\n ProjectivePoint: Point,\n Signature,\n utils,\n };\n}\n/**\n * Implementation of the Shallue and van de Woestijne method for any weierstrass curve.\n * TODO: check if there is a way to merge this with uvRatio in Edwards; move to modular.\n * b = True and y = sqrt(u / v) if (u / v) is square in F, and\n * b = False and y = sqrt(Z * (u / v)) otherwise.\n * @param Fp\n * @param Z\n * @returns\n */\nexport function SWUFpSqrtRatio(Fp, Z) {\n // Generic implementation\n const q = Fp.ORDER;\n let l = _0n;\n for (let o = q - _1n; o % _2n === _0n; o /= _2n)\n l += _1n;\n const c1 = l; // 1. c1, the largest integer such that 2^c1 divides q - 1.\n // We need 2n ** c1 and 2n ** (c1-1). We can't use **; but we can use <<.\n // 2n ** c1 == 2n << (c1-1)\n const _2n_pow_c1_1 = _2n << (c1 - _1n - _1n);\n const _2n_pow_c1 = _2n_pow_c1_1 * _2n;\n const c2 = (q - _1n) / _2n_pow_c1; // 2. c2 = (q - 1) / (2^c1) # Integer arithmetic\n const c3 = (c2 - _1n) / _2n; // 3. c3 = (c2 - 1) / 2 # Integer arithmetic\n const c4 = _2n_pow_c1 - _1n; // 4. c4 = 2^c1 - 1 # Integer arithmetic\n const c5 = _2n_pow_c1_1; // 5. c5 = 2^(c1 - 1) # Integer arithmetic\n const c6 = Fp.pow(Z, c2); // 6. c6 = Z^c2\n const c7 = Fp.pow(Z, (c2 + _1n) / _2n); // 7. c7 = Z^((c2 + 1) / 2)\n let sqrtRatio = (u, v) => {\n let tv1 = c6; // 1. tv1 = c6\n let tv2 = Fp.pow(v, c4); // 2. tv2 = v^c4\n let tv3 = Fp.sqr(tv2); // 3. tv3 = tv2^2\n tv3 = Fp.mul(tv3, v); // 4. tv3 = tv3 * v\n let tv5 = Fp.mul(u, tv3); // 5. tv5 = u * tv3\n tv5 = Fp.pow(tv5, c3); // 6. tv5 = tv5^c3\n tv5 = Fp.mul(tv5, tv2); // 7. tv5 = tv5 * tv2\n tv2 = Fp.mul(tv5, v); // 8. tv2 = tv5 * v\n tv3 = Fp.mul(tv5, u); // 9. tv3 = tv5 * u\n let tv4 = Fp.mul(tv3, tv2); // 10. tv4 = tv3 * tv2\n tv5 = Fp.pow(tv4, c5); // 11. tv5 = tv4^c5\n let isQR = Fp.eql(tv5, Fp.ONE); // 12. isQR = tv5 == 1\n tv2 = Fp.mul(tv3, c7); // 13. tv2 = tv3 * c7\n tv5 = Fp.mul(tv4, tv1); // 14. tv5 = tv4 * tv1\n tv3 = Fp.cmov(tv2, tv3, isQR); // 15. tv3 = CMOV(tv2, tv3, isQR)\n tv4 = Fp.cmov(tv5, tv4, isQR); // 16. tv4 = CMOV(tv5, tv4, isQR)\n // 17. for i in (c1, c1 - 1, ..., 2):\n for (let i = c1; i > _1n; i--) {\n let tv5 = i - _2n; // 18. tv5 = i - 2\n tv5 = _2n << (tv5 - _1n); // 19. tv5 = 2^tv5\n let tvv5 = Fp.pow(tv4, tv5); // 20. tv5 = tv4^tv5\n const e1 = Fp.eql(tvv5, Fp.ONE); // 21. e1 = tv5 == 1\n tv2 = Fp.mul(tv3, tv1); // 22. tv2 = tv3 * tv1\n tv1 = Fp.mul(tv1, tv1); // 23. tv1 = tv1 * tv1\n tvv5 = Fp.mul(tv4, tv1); // 24. tv5 = tv4 * tv1\n tv3 = Fp.cmov(tv2, tv3, e1); // 25. tv3 = CMOV(tv2, tv3, e1)\n tv4 = Fp.cmov(tvv5, tv4, e1); // 26. tv4 = CMOV(tv5, tv4, e1)\n }\n return { isValid: isQR, value: tv3 };\n };\n if (Fp.ORDER % _4n === _3n) {\n // sqrt_ratio_3mod4(u, v)\n const c1 = (Fp.ORDER - _3n) / _4n; // 1. c1 = (q - 3) / 4 # Integer arithmetic\n const c2 = Fp.sqrt(Fp.neg(Z)); // 2. c2 = sqrt(-Z)\n sqrtRatio = (u, v) => {\n let tv1 = Fp.sqr(v); // 1. tv1 = v^2\n const tv2 = Fp.mul(u, v); // 2. tv2 = u * v\n tv1 = Fp.mul(tv1, tv2); // 3. tv1 = tv1 * tv2\n let y1 = Fp.pow(tv1, c1); // 4. y1 = tv1^c1\n y1 = Fp.mul(y1, tv2); // 5. y1 = y1 * tv2\n const y2 = Fp.mul(y1, c2); // 6. y2 = y1 * c2\n const tv3 = Fp.mul(Fp.sqr(y1), v); // 7. tv3 = y1^2; 8. tv3 = tv3 * v\n const isQR = Fp.eql(tv3, u); // 9. isQR = tv3 == u\n let y = Fp.cmov(y2, y1, isQR); // 10. y = CMOV(y2, y1, isQR)\n return { isValid: isQR, value: y }; // 11. return (isQR, y) isQR ? y : y*c2\n };\n }\n // No curves uses that\n // if (Fp.ORDER % _8n === _5n) // sqrt_ratio_5mod8\n return sqrtRatio;\n}\n/**\n * Simplified Shallue-van de Woestijne-Ulas Method\n * https://www.rfc-editor.org/rfc/rfc9380#section-6.6.2\n */\nexport function mapToCurveSimpleSWU(Fp, opts) {\n mod.validateField(Fp);\n if (!Fp.isValid(opts.A) || !Fp.isValid(opts.B) || !Fp.isValid(opts.Z))\n throw new Error('mapToCurveSimpleSWU: invalid opts');\n const sqrtRatio = SWUFpSqrtRatio(Fp, opts.Z);\n if (!Fp.isOdd)\n throw new Error('Fp.isOdd is not implemented!');\n // Input: u, an element of F.\n // Output: (x, y), a point on E.\n return (u) => {\n // prettier-ignore\n let tv1, tv2, tv3, tv4, tv5, tv6, x, y;\n tv1 = Fp.sqr(u); // 1. tv1 = u^2\n tv1 = Fp.mul(tv1, opts.Z); // 2. tv1 = Z * tv1\n tv2 = Fp.sqr(tv1); // 3. tv2 = tv1^2\n tv2 = Fp.add(tv2, tv1); // 4. tv2 = tv2 + tv1\n tv3 = Fp.add(tv2, Fp.ONE); // 5. tv3 = tv2 + 1\n tv3 = Fp.mul(tv3, opts.B); // 6. tv3 = B * tv3\n tv4 = Fp.cmov(opts.Z, Fp.neg(tv2), !Fp.eql(tv2, Fp.ZERO)); // 7. tv4 = CMOV(Z, -tv2, tv2 != 0)\n tv4 = Fp.mul(tv4, opts.A); // 8. tv4 = A * tv4\n tv2 = Fp.sqr(tv3); // 9. tv2 = tv3^2\n tv6 = Fp.sqr(tv4); // 10. tv6 = tv4^2\n tv5 = Fp.mul(tv6, opts.A); // 11. tv5 = A * tv6\n tv2 = Fp.add(tv2, tv5); // 12. tv2 = tv2 + tv5\n tv2 = Fp.mul(tv2, tv3); // 13. tv2 = tv2 * tv3\n tv6 = Fp.mul(tv6, tv4); // 14. tv6 = tv6 * tv4\n tv5 = Fp.mul(tv6, opts.B); // 15. tv5 = B * tv6\n tv2 = Fp.add(tv2, tv5); // 16. tv2 = tv2 + tv5\n x = Fp.mul(tv1, tv3); // 17. x = tv1 * tv3\n const { isValid, value } = sqrtRatio(tv2, tv6); // 18. (is_gx1_square, y1) = sqrt_ratio(tv2, tv6)\n y = Fp.mul(tv1, u); // 19. y = tv1 * u -> Z * u^3 * y1\n y = Fp.mul(y, value); // 20. y = y * y1\n x = Fp.cmov(x, tv3, isValid); // 21. x = CMOV(x, tv3, is_gx1_square)\n y = Fp.cmov(y, value, isValid); // 22. y = CMOV(y, y1, is_gx1_square)\n const e1 = Fp.isOdd(u) === Fp.isOdd(y); // 23. e1 = sgn0(u) == sgn0(y)\n y = Fp.cmov(Fp.neg(y), y, e1); // 24. y = CMOV(-y, y, e1)\n x = Fp.div(x, tv4); // 25. x = x / tv4\n return { x, y };\n };\n}\n//# sourceMappingURL=weierstrass.js.map","import { hash as assertHash, bytes as assertBytes, exists as assertExists } from './_assert.js';\nimport { Hash, toBytes } from './utils.js';\n// HMAC (RFC 2104)\nexport class HMAC extends Hash {\n constructor(hash, _key) {\n super();\n this.finished = false;\n this.destroyed = false;\n assertHash(hash);\n const key = toBytes(_key);\n this.iHash = hash.create();\n if (typeof this.iHash.update !== 'function')\n throw new Error('Expected instance of class which extends utils.Hash');\n this.blockLen = this.iHash.blockLen;\n this.outputLen = this.iHash.outputLen;\n const blockLen = this.blockLen;\n const pad = new Uint8Array(blockLen);\n // blockLen can be bigger than outputLen\n pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);\n for (let i = 0; i < pad.length; i++)\n pad[i] ^= 0x36;\n this.iHash.update(pad);\n // By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone\n this.oHash = hash.create();\n // Undo internal XOR && apply outer XOR\n for (let i = 0; i < pad.length; i++)\n pad[i] ^= 0x36 ^ 0x5c;\n this.oHash.update(pad);\n pad.fill(0);\n }\n update(buf) {\n assertExists(this);\n this.iHash.update(buf);\n return this;\n }\n digestInto(out) {\n assertExists(this);\n assertBytes(out, this.outputLen);\n this.finished = true;\n this.iHash.digestInto(out);\n this.oHash.update(out);\n this.oHash.digestInto(out);\n this.destroy();\n }\n digest() {\n const out = new Uint8Array(this.oHash.outputLen);\n this.digestInto(out);\n return out;\n }\n _cloneInto(to) {\n // Create new instance without calling constructor since key already in state and we don't know it.\n to || (to = Object.create(Object.getPrototypeOf(this), {}));\n const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;\n to = to;\n to.finished = finished;\n to.destroyed = destroyed;\n to.blockLen = blockLen;\n to.outputLen = outputLen;\n to.oHash = oHash._cloneInto(to.oHash);\n to.iHash = iHash._cloneInto(to.iHash);\n return to;\n }\n destroy() {\n this.destroyed = true;\n this.oHash.destroy();\n this.iHash.destroy();\n }\n}\n/**\n * HMAC: RFC2104 message authentication code.\n * @param hash - function that would be used e.g. sha256\n * @param key - message key\n * @param message - message data\n */\nexport const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();\nhmac.create = (hash, key) => new HMAC(hash, key);\n//# sourceMappingURL=hmac.js.map","/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nimport { hmac } from '@noble/hashes/hmac';\nimport { concatBytes, randomBytes } from '@noble/hashes/utils';\nimport { weierstrass } from './abstract/weierstrass.js';\n// connects noble-curves to noble-hashes\nexport function getHash(hash) {\n return {\n hash,\n hmac: (key, ...msgs) => hmac(hash, key, concatBytes(...msgs)),\n randomBytes,\n };\n}\nexport function createCurve(curveDef, defHash) {\n const create = (hash) => weierstrass({ ...curveDef, ...getHash(hash) });\n return Object.freeze({ ...create(defHash), create });\n}\n//# sourceMappingURL=_shortw_utils.js.map","/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nimport { sha256 } from '@noble/hashes/sha256';\nimport { randomBytes } from '@noble/hashes/utils';\nimport { Field, mod, pow2 } from './abstract/modular.js';\nimport { mapToCurveSimpleSWU } from './abstract/weierstrass.js';\nimport { bytesToNumberBE, concatBytes, ensureBytes, numberToBytesBE } from './abstract/utils.js';\nimport { createHasher, isogenyMap } from './abstract/hash-to-curve.js';\nimport { createCurve } from './_shortw_utils.js';\nconst secp256k1P = BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f');\nconst secp256k1N = BigInt('0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141');\nconst _1n = BigInt(1);\nconst _2n = BigInt(2);\nconst divNearest = (a, b) => (a + b / _2n) / b;\n/**\n * √n = n^((p+1)/4) for fields p = 3 mod 4. We unwrap the loop and multiply bit-by-bit.\n * (P+1n/4n).toString(2) would produce bits [223x 1, 0, 22x 1, 4x 0, 11, 00]\n */\nfunction sqrtMod(y) {\n const P = secp256k1P;\n // prettier-ignore\n const _3n = BigInt(3), _6n = BigInt(6), _11n = BigInt(11), _22n = BigInt(22);\n // prettier-ignore\n const _23n = BigInt(23), _44n = BigInt(44), _88n = BigInt(88);\n const b2 = (y * y * y) % P; // x^3, 11\n const b3 = (b2 * b2 * y) % P; // x^7\n const b6 = (pow2(b3, _3n, P) * b3) % P;\n const b9 = (pow2(b6, _3n, P) * b3) % P;\n const b11 = (pow2(b9, _2n, P) * b2) % P;\n const b22 = (pow2(b11, _11n, P) * b11) % P;\n const b44 = (pow2(b22, _22n, P) * b22) % P;\n const b88 = (pow2(b44, _44n, P) * b44) % P;\n const b176 = (pow2(b88, _88n, P) * b88) % P;\n const b220 = (pow2(b176, _44n, P) * b44) % P;\n const b223 = (pow2(b220, _3n, P) * b3) % P;\n const t1 = (pow2(b223, _23n, P) * b22) % P;\n const t2 = (pow2(t1, _6n, P) * b2) % P;\n const root = pow2(t2, _2n, P);\n if (!Fp.eql(Fp.sqr(root), y))\n throw new Error('Cannot find square root');\n return root;\n}\nconst Fp = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });\nexport const secp256k1 = createCurve({\n a: BigInt(0),\n b: BigInt(7),\n Fp,\n n: secp256k1N,\n // Base point (x, y) aka generator point\n Gx: BigInt('55066263022277343669578718895168534326250603453777594175500187360389116729240'),\n Gy: BigInt('32670510020758816978083085130507043184471273380659243275938904335757337482424'),\n h: BigInt(1),\n lowS: true,\n /**\n * secp256k1 belongs to Koblitz curves: it has efficiently computable endomorphism.\n * Endomorphism uses 2x less RAM, speeds up precomputation by 2x and ECDH / key recovery by 20%.\n * For precomputed wNAF it trades off 1/2 init time & 1/3 ram for 20% perf hit.\n * Explanation: https://gist.github.com/paulmillr/eb670806793e84df628a7c434a873066\n */\n endo: {\n beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),\n splitScalar: (k) => {\n const n = secp256k1N;\n const a1 = BigInt('0x3086d221a7d46bcde86c90e49284eb15');\n const b1 = -_1n * BigInt('0xe4437ed6010e88286f547fa90abfe4c3');\n const a2 = BigInt('0x114ca50f7a8e2f3f657c1108d9d44cfd8');\n const b2 = a1;\n const POW_2_128 = BigInt('0x100000000000000000000000000000000'); // (2n**128n).toString(16)\n const c1 = divNearest(b2 * k, n);\n const c2 = divNearest(-b1 * k, n);\n let k1 = mod(k - c1 * a1 - c2 * a2, n);\n let k2 = mod(-c1 * b1 - c2 * b2, n);\n const k1neg = k1 > POW_2_128;\n const k2neg = k2 > POW_2_128;\n if (k1neg)\n k1 = n - k1;\n if (k2neg)\n k2 = n - k2;\n if (k1 > POW_2_128 || k2 > POW_2_128) {\n throw new Error('splitScalar: Endomorphism failed, k=' + k);\n }\n return { k1neg, k1, k2neg, k2 };\n },\n },\n}, sha256);\n// Schnorr signatures are superior to ECDSA from above. Below is Schnorr-specific BIP0340 code.\n// https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki\nconst _0n = BigInt(0);\nconst fe = (x) => typeof x === 'bigint' && _0n < x && x < secp256k1P;\nconst ge = (x) => typeof x === 'bigint' && _0n < x && x < secp256k1N;\n/** An object mapping tags to their tagged hash prefix of [SHA256(tag) | SHA256(tag)] */\nconst TAGGED_HASH_PREFIXES = {};\nfunction taggedHash(tag, ...messages) {\n let tagP = TAGGED_HASH_PREFIXES[tag];\n if (tagP === undefined) {\n const tagH = sha256(Uint8Array.from(tag, (c) => c.charCodeAt(0)));\n tagP = concatBytes(tagH, tagH);\n TAGGED_HASH_PREFIXES[tag] = tagP;\n }\n return sha256(concatBytes(tagP, ...messages));\n}\n// ECDSA compact points are 33-byte. Schnorr is 32: we strip first byte 0x02 or 0x03\nconst pointToBytes = (point) => point.toRawBytes(true).slice(1);\nconst numTo32b = (n) => numberToBytesBE(n, 32);\nconst modP = (x) => mod(x, secp256k1P);\nconst modN = (x) => mod(x, secp256k1N);\nconst Point = secp256k1.ProjectivePoint;\nconst GmulAdd = (Q, a, b) => Point.BASE.multiplyAndAddUnsafe(Q, a, b);\n// Calculate point, scalar and bytes\nfunction schnorrGetExtPubKey(priv) {\n let d_ = secp256k1.utils.normPrivateKeyToScalar(priv); // same method executed in fromPrivateKey\n let p = Point.fromPrivateKey(d_); // P = d'⋅G; 0 < d' < n check is done inside\n const scalar = p.hasEvenY() ? d_ : modN(-d_);\n return { scalar: scalar, bytes: pointToBytes(p) };\n}\n/**\n * lift_x from BIP340. Convert 32-byte x coordinate to elliptic curve point.\n * @returns valid point checked for being on-curve\n */\nfunction lift_x(x) {\n if (!fe(x))\n throw new Error('bad x: need 0 < x < p'); // Fail if x ≥ p.\n const xx = modP(x * x);\n const c = modP(xx * x + BigInt(7)); // Let c = x³ + 7 mod p.\n let y = sqrtMod(c); // Let y = c^(p+1)/4 mod p.\n if (y % _2n !== _0n)\n y = modP(-y); // Return the unique point P such that x(P) = x and\n const p = new Point(x, y, _1n); // y(P) = y if y mod 2 = 0 or y(P) = p-y otherwise.\n p.assertValidity();\n return p;\n}\n/**\n * Create tagged hash, convert it to bigint, reduce modulo-n.\n */\nfunction challenge(...args) {\n return modN(bytesToNumberBE(taggedHash('BIP0340/challenge', ...args)));\n}\n/**\n * Schnorr public key is just `x` coordinate of Point as per BIP340.\n */\nfunction schnorrGetPublicKey(privateKey) {\n return schnorrGetExtPubKey(privateKey).bytes; // d'=int(sk). Fail if d'=0 or d'≥n. Ret bytes(d'⋅G)\n}\n/**\n * Creates Schnorr signature as per BIP340. Verifies itself before returning anything.\n * auxRand is optional and is not the sole source of k generation: bad CSPRNG won't be dangerous.\n */\nfunction schnorrSign(message, privateKey, auxRand = randomBytes(32)) {\n const m = ensureBytes('message', message);\n const { bytes: px, scalar: d } = schnorrGetExtPubKey(privateKey); // checks for isWithinCurveOrder\n const a = ensureBytes('auxRand', auxRand, 32); // Auxiliary random data a: a 32-byte array\n const t = numTo32b(d ^ bytesToNumberBE(taggedHash('BIP0340/aux', a))); // Let t be the byte-wise xor of bytes(d) and hash/aux(a)\n const rand = taggedHash('BIP0340/nonce', t, px, m); // Let rand = hash/nonce(t || bytes(P) || m)\n const k_ = modN(bytesToNumberBE(rand)); // Let k' = int(rand) mod n\n if (k_ === _0n)\n throw new Error('sign failed: k is zero'); // Fail if k' = 0.\n const { bytes: rx, scalar: k } = schnorrGetExtPubKey(k_); // Let R = k'⋅G.\n const e = challenge(rx, px, m); // Let e = int(hash/challenge(bytes(R) || bytes(P) || m)) mod n.\n const sig = new Uint8Array(64); // Let sig = bytes(R) || bytes((k + ed) mod n).\n sig.set(rx, 0);\n sig.set(numTo32b(modN(k + e * d)), 32);\n // If Verify(bytes(P), m, sig) (see below) returns failure, abort\n if (!schnorrVerify(sig, m, px))\n throw new Error('sign: Invalid signature produced');\n return sig;\n}\n/**\n * Verifies Schnorr signature.\n * Will swallow errors & return false except for initial type validation of arguments.\n */\nfunction schnorrVerify(signature, message, publicKey) {\n const sig = ensureBytes('signature', signature, 64);\n const m = ensureBytes('message', message);\n const pub = ensureBytes('publicKey', publicKey, 32);\n try {\n const P = lift_x(bytesToNumberBE(pub)); // P = lift_x(int(pk)); fail if that fails\n const r = bytesToNumberBE(sig.subarray(0, 32)); // Let r = int(sig[0:32]); fail if r ≥ p.\n if (!fe(r))\n return false;\n const s = bytesToNumberBE(sig.subarray(32, 64)); // Let s = int(sig[32:64]); fail if s ≥ n.\n if (!ge(s))\n return false;\n const e = challenge(numTo32b(r), pointToBytes(P), m); // int(challenge(bytes(r)||bytes(P)||m))%n\n const R = GmulAdd(P, s, modN(-e)); // R = s⋅G - e⋅P\n if (!R || !R.hasEvenY() || R.toAffine().x !== r)\n return false; // -eP == (n-e)P\n return true; // Fail if is_infinite(R) / not has_even_y(R) / x(R) ≠ r.\n }\n catch (error) {\n return false;\n }\n}\nexport const schnorr = /* @__PURE__ */ (() => ({\n getPublicKey: schnorrGetPublicKey,\n sign: schnorrSign,\n verify: schnorrVerify,\n utils: {\n randomPrivateKey: secp256k1.utils.randomPrivateKey,\n lift_x,\n pointToBytes,\n numberToBytesBE,\n bytesToNumberBE,\n taggedHash,\n mod,\n },\n}))();\nconst isoMap = /* @__PURE__ */ (() => isogenyMap(Fp, [\n // xNum\n [\n '0x8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38daaaaa8c7',\n '0x7d3d4c80bc321d5b9f315cea7fd44c5d595d2fc0bf63b92dfff1044f17c6581',\n '0x534c328d23f234e6e2a413deca25caece4506144037c40314ecbd0b53d9dd262',\n '0x8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38daaaaa88c',\n ],\n // xDen\n [\n '0xd35771193d94918a9ca34ccbb7b640dd86cd409542f8487d9fe6b745781eb49b',\n '0xedadc6f64383dc1df7c4b2d51b54225406d36b641f5e41bbc52a56612a8c6d14',\n '0x0000000000000000000000000000000000000000000000000000000000000001', // LAST 1\n ],\n // yNum\n [\n '0x4bda12f684bda12f684bda12f684bda12f684bda12f684bda12f684b8e38e23c',\n '0xc75e0c32d5cb7c0fa9d0a54b12a0a6d5647ab046d686da6fdffc90fc201d71a3',\n '0x29a6194691f91a73715209ef6512e576722830a201be2018a765e85a9ecee931',\n '0x2f684bda12f684bda12f684bda12f684bda12f684bda12f684bda12f38e38d84',\n ],\n // yDen\n [\n '0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffff93b',\n '0x7a06534bb8bdb49fd5e9e6632722c2989467c1bfc8e8d978dfb425d2685c2573',\n '0x6484aa716545ca2cf3a70c3fa8fe337e0a3d21162f0d6299a7bf8192bfd2a76f',\n '0x0000000000000000000000000000000000000000000000000000000000000001', // LAST 1\n ],\n].map((i) => i.map((j) => BigInt(j)))))();\nconst mapSWU = /* @__PURE__ */ (() => mapToCurveSimpleSWU(Fp, {\n A: BigInt('0x3f8731abdd661adca08a5558f0f5d272e953d363cb6f0e5d405447c01a444533'),\n B: BigInt('1771'),\n Z: Fp.create(BigInt('-11')),\n}))();\nconst htf = /* @__PURE__ */ (() => createHasher(secp256k1.ProjectivePoint, (scalars) => {\n const { x, y } = mapSWU(Fp.create(scalars[0]));\n return isoMap(x, y);\n}, {\n DST: 'secp256k1_XMD:SHA-256_SSWU_RO_',\n encodeDST: 'secp256k1_XMD:SHA-256_SSWU_NU_',\n p: Fp.ORDER,\n m: 1,\n k: 128,\n expand: 'xmd',\n hash: sha256,\n}))();\nexport const hashToCurve = /* @__PURE__ */ (() => htf.hashToCurve)();\nexport const encodeToCurve = /* @__PURE__ */ (() => htf.encodeToCurve)();\n//# sourceMappingURL=secp256k1.js.map","export const crypto = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;\n//# sourceMappingURL=crypto.js.map","/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */\n// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.\n// node.js versions earlier than v19 don't declare it in global scope.\n// For node.js, package.json#exports field mapping rewrites import\n// from `crypto` to `cryptoNode`, which imports native module.\n// Makes the utils un-importable in browsers without a bundler.\n// Once node.js 18 is deprecated, we can just drop the import.\nimport { crypto } from '@noble/hashes/crypto';\nconst u8a = (a) => a instanceof Uint8Array;\n// Cast array to different type\nexport const u8 = (arr) => new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);\nexport const u32 = (arr) => new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));\n// Cast array to view\nexport const createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength);\n// The rotate right (circular right shift) operation for uint32\nexport const rotr = (word, shift) => (word << (32 - shift)) | (word >>> shift);\n// big-endian hardware is rare. Just in case someone still decides to run hashes:\n// early-throw an error because we don't support BE yet.\nexport const isLE = new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44;\nif (!isLE)\n throw new Error('Non little-endian hardware is not supported');\nconst hexes = Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, '0'));\n/**\n * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'\n */\nexport function bytesToHex(bytes) {\n if (!u8a(bytes))\n throw new Error('Uint8Array expected');\n // pre-caching improves the speed 6x\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += hexes[bytes[i]];\n }\n return hex;\n}\n/**\n * @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])\n */\nexport function hexToBytes(hex) {\n if (typeof hex !== 'string')\n throw new Error('hex string expected, got ' + typeof hex);\n const len = hex.length;\n if (len % 2)\n throw new Error('padded hex string expected, got unpadded hex of length ' + len);\n const array = new Uint8Array(len / 2);\n for (let i = 0; i < array.length; i++) {\n const j = i * 2;\n const hexByte = hex.slice(j, j + 2);\n const byte = Number.parseInt(hexByte, 16);\n if (Number.isNaN(byte) || byte < 0)\n throw new Error('Invalid byte sequence');\n array[i] = byte;\n }\n return array;\n}\n// There is no setImmediate in browser and setTimeout is slow.\n// call of async fn will return Promise, which will be fullfiled only on\n// next scheduler queue processing step and this is exactly what we need.\nexport const nextTick = async () => { };\n// Returns control to thread each 'tick' ms to avoid blocking\nexport async function asyncLoop(iters, tick, cb) {\n let ts = Date.now();\n for (let i = 0; i < iters; i++) {\n cb(i);\n // Date.now() is not monotonic, so in case if clock goes backwards we return return control too\n const diff = Date.now() - ts;\n if (diff >= 0 && diff < tick)\n continue;\n await nextTick();\n ts += diff;\n }\n}\n/**\n * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])\n */\nexport function utf8ToBytes(str) {\n if (typeof str !== 'string')\n throw new Error(`utf8ToBytes expected string, got ${typeof str}`);\n return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809\n}\n/**\n * Normalizes (non-hex) string or Uint8Array to Uint8Array.\n * Warning: when Uint8Array is passed, it would NOT get copied.\n * Keep in mind for future mutable operations.\n */\nexport function toBytes(data) {\n if (typeof data === 'string')\n data = utf8ToBytes(data);\n if (!u8a(data))\n throw new Error(`expected Uint8Array, got ${typeof data}`);\n return data;\n}\n/**\n * Copies several Uint8Arrays into one.\n */\nexport function concatBytes(...arrays) {\n const r = new Uint8Array(arrays.reduce((sum, a) => sum + a.length, 0));\n let pad = 0; // walk through each item, ensure they have proper type\n arrays.forEach((a) => {\n if (!u8a(a))\n throw new Error('Uint8Array expected');\n r.set(a, pad);\n pad += a.length;\n });\n return r;\n}\n// For runtime check if class implements interface\nexport class Hash {\n // Safe version that clones internal state\n clone() {\n return this._cloneInto();\n }\n}\n// Check if object doens't have custom constructor (like Uint8Array/Array)\nconst isPlainObject = (obj) => Object.prototype.toString.call(obj) === '[object Object]' && obj.constructor === Object;\nexport function checkOpts(defaults, opts) {\n if (opts !== undefined && (typeof opts !== 'object' || !isPlainObject(opts)))\n throw new Error('Options should be object or undefined');\n const merged = Object.assign(defaults, opts);\n return merged;\n}\nexport function wrapConstructor(hashCons) {\n const hashC = (msg) => hashCons().update(toBytes(msg)).digest();\n const tmp = hashCons();\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = () => hashCons();\n return hashC;\n}\nexport function wrapConstructorWithOpts(hashCons) {\n const hashC = (msg, opts) => hashCons(opts).update(toBytes(msg)).digest();\n const tmp = hashCons({});\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = (opts) => hashCons(opts);\n return hashC;\n}\nexport function wrapXOFConstructorWithOpts(hashCons) {\n const hashC = (msg, opts) => hashCons(opts).update(toBytes(msg)).digest();\n const tmp = hashCons({});\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = (opts) => hashCons(opts);\n return hashC;\n}\n/**\n * Secure PRNG. Uses `crypto.getRandomValues`, which defers to OS.\n */\nexport function randomBytes(bytesLength = 32) {\n if (crypto && typeof crypto.getRandomValues === 'function') {\n return crypto.getRandomValues(new Uint8Array(bytesLength));\n }\n throw new Error('crypto.getRandomValues must be defined');\n}\n//# sourceMappingURL=utils.js.map","export function number(n) {\n if (!Number.isSafeInteger(n) || n < 0)\n throw new Error(`Wrong positive integer: ${n}`);\n}\nexport function bool(b) {\n if (typeof b !== 'boolean')\n throw new Error(`Expected boolean, not ${b}`);\n}\nexport function bytes(b, ...lengths) {\n if (!(b instanceof Uint8Array))\n throw new Error('Expected Uint8Array');\n if (lengths.length > 0 && !lengths.includes(b.length))\n throw new Error(`Expected Uint8Array of length ${lengths}, not of length=${b.length}`);\n}\nexport function hash(hash) {\n if (typeof hash !== 'function' || typeof hash.create !== 'function')\n throw new Error('Hash should be wrapped by utils.wrapConstructor');\n number(hash.outputLen);\n number(hash.blockLen);\n}\nexport function exists(instance, checkFinished = true) {\n if (instance.destroyed)\n throw new Error('Hash instance has been destroyed');\n if (checkFinished && instance.finished)\n throw new Error('Hash#digest() has already been called');\n}\nexport function output(out, instance) {\n bytes(out);\n const min = instance.outputLen;\n if (out.length < min) {\n throw new Error(`digestInto() expects output buffer of length at least ${min}`);\n }\n}\nconst assert = {\n number,\n bool,\n bytes,\n hash,\n exists,\n output,\n};\nexport default assert;\n//# sourceMappingURL=_assert.js.map","import assert from './_assert.js';\nimport { Hash, createView, toBytes } from './utils.js';\n// Polyfill for Safari 14\nfunction setBigUint64(view, byteOffset, value, isLE) {\n if (typeof view.setBigUint64 === 'function')\n return view.setBigUint64(byteOffset, value, isLE);\n const _32n = BigInt(32);\n const _u32_max = BigInt(0xffffffff);\n const wh = Number((value >> _32n) & _u32_max);\n const wl = Number(value & _u32_max);\n const h = isLE ? 4 : 0;\n const l = isLE ? 0 : 4;\n view.setUint32(byteOffset + h, wh, isLE);\n view.setUint32(byteOffset + l, wl, isLE);\n}\n// Base SHA2 class (RFC 6234)\nexport class SHA2 extends Hash {\n constructor(blockLen, outputLen, padOffset, isLE) {\n super();\n this.blockLen = blockLen;\n this.outputLen = outputLen;\n this.padOffset = padOffset;\n this.isLE = isLE;\n this.finished = false;\n this.length = 0;\n this.pos = 0;\n this.destroyed = false;\n this.buffer = new Uint8Array(blockLen);\n this.view = createView(this.buffer);\n }\n update(data) {\n assert.exists(this);\n const { view, buffer, blockLen } = this;\n data = toBytes(data);\n const len = data.length;\n for (let pos = 0; pos < len;) {\n const take = Math.min(blockLen - this.pos, len - pos);\n // Fast path: we have at least one block in input, cast it to view and process\n if (take === blockLen) {\n const dataView = createView(data);\n for (; blockLen <= len - pos; pos += blockLen)\n this.process(dataView, pos);\n continue;\n }\n buffer.set(data.subarray(pos, pos + take), this.pos);\n this.pos += take;\n pos += take;\n if (this.pos === blockLen) {\n this.process(view, 0);\n this.pos = 0;\n }\n }\n this.length += data.length;\n this.roundClean();\n return this;\n }\n digestInto(out) {\n assert.exists(this);\n assert.output(out, this);\n this.finished = true;\n // Padding\n // We can avoid allocation of buffer for padding completely if it\n // was previously not allocated here. But it won't change performance.\n const { buffer, view, blockLen, isLE } = this;\n let { pos } = this;\n // append the bit '1' to the message\n buffer[pos++] = 0b10000000;\n this.buffer.subarray(pos).fill(0);\n // we have less than padOffset left in buffer, so we cannot put length in current block, need process it and pad again\n if (this.padOffset > blockLen - pos) {\n this.process(view, 0);\n pos = 0;\n }\n // Pad until full block byte with zeros\n for (let i = pos; i < blockLen; i++)\n buffer[i] = 0;\n // Note: sha512 requires length to be 128bit integer, but length in JS will overflow before that\n // You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen.\n // So we just write lowest 64 bits of that value.\n setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE);\n this.process(view, 0);\n const oview = createView(out);\n const len = this.outputLen;\n // NOTE: we do division by 4 later, which should be fused in single op with modulo by JIT\n if (len % 4)\n throw new Error('_sha2: outputLen should be aligned to 32bit');\n const outLen = len / 4;\n const state = this.get();\n if (outLen > state.length)\n throw new Error('_sha2: outputLen bigger than state');\n for (let i = 0; i < outLen; i++)\n oview.setUint32(4 * i, state[i], isLE);\n }\n digest() {\n const { buffer, outputLen } = this;\n this.digestInto(buffer);\n const res = buffer.slice(0, outputLen);\n this.destroy();\n return res;\n }\n _cloneInto(to) {\n to || (to = new this.constructor());\n to.set(...this.get());\n const { blockLen, buffer, length, finished, destroyed, pos } = this;\n to.length = length;\n to.pos = pos;\n to.finished = finished;\n to.destroyed = destroyed;\n if (length % blockLen)\n to.buffer.set(buffer);\n return to;\n }\n}\n//# sourceMappingURL=_sha2.js.map","import { SHA2 } from './_sha2.js';\nimport { rotr, wrapConstructor } from './utils.js';\n// Choice: a ? b : c\nconst Chi = (a, b, c) => (a & b) ^ (~a & c);\n// Majority function, true if any two inpust is true\nconst Maj = (a, b, c) => (a & b) ^ (a & c) ^ (b & c);\n// Round constants:\n// first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)\n// prettier-ignore\nconst SHA256_K = new Uint32Array([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n]);\n// Initial state (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):\n// prettier-ignore\nconst IV = new Uint32Array([\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19\n]);\n// Temporary buffer, not used to store anything between runs\n// Named this way because it matches specification.\nconst SHA256_W = new Uint32Array(64);\nclass SHA256 extends SHA2 {\n constructor() {\n super(64, 32, 8, false);\n // We cannot use array here since array allows indexing by variable\n // which means optimizer/compiler cannot use registers.\n this.A = IV[0] | 0;\n this.B = IV[1] | 0;\n this.C = IV[2] | 0;\n this.D = IV[3] | 0;\n this.E = IV[4] | 0;\n this.F = IV[5] | 0;\n this.G = IV[6] | 0;\n this.H = IV[7] | 0;\n }\n get() {\n const { A, B, C, D, E, F, G, H } = this;\n return [A, B, C, D, E, F, G, H];\n }\n // prettier-ignore\n set(A, B, C, D, E, F, G, H) {\n this.A = A | 0;\n this.B = B | 0;\n this.C = C | 0;\n this.D = D | 0;\n this.E = E | 0;\n this.F = F | 0;\n this.G = G | 0;\n this.H = H | 0;\n }\n process(view, offset) {\n // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array\n for (let i = 0; i < 16; i++, offset += 4)\n SHA256_W[i] = view.getUint32(offset, false);\n for (let i = 16; i < 64; i++) {\n const W15 = SHA256_W[i - 15];\n const W2 = SHA256_W[i - 2];\n const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3);\n const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10);\n SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0;\n }\n // Compression function main loop, 64 rounds\n let { A, B, C, D, E, F, G, H } = this;\n for (let i = 0; i < 64; i++) {\n const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);\n const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;\n const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);\n const T2 = (sigma0 + Maj(A, B, C)) | 0;\n H = G;\n G = F;\n F = E;\n E = (D + T1) | 0;\n D = C;\n C = B;\n B = A;\n A = (T1 + T2) | 0;\n }\n // Add the compressed chunk to the current hash value\n A = (A + this.A) | 0;\n B = (B + this.B) | 0;\n C = (C + this.C) | 0;\n D = (D + this.D) | 0;\n E = (E + this.E) | 0;\n F = (F + this.F) | 0;\n G = (G + this.G) | 0;\n H = (H + this.H) | 0;\n this.set(A, B, C, D, E, F, G, H);\n }\n roundClean() {\n SHA256_W.fill(0);\n }\n destroy() {\n this.set(0, 0, 0, 0, 0, 0, 0, 0);\n this.buffer.fill(0);\n }\n}\n// Constants from https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf\nclass SHA224 extends SHA256 {\n constructor() {\n super();\n this.A = 0xc1059ed8 | 0;\n this.B = 0x367cd507 | 0;\n this.C = 0x3070dd17 | 0;\n this.D = 0xf70e5939 | 0;\n this.E = 0xffc00b31 | 0;\n this.F = 0x68581511 | 0;\n this.G = 0x64f98fa7 | 0;\n this.H = 0xbefa4fa4 | 0;\n this.outputLen = 28;\n }\n}\n/**\n * SHA2-256 hash function\n * @param message - data that would be hashed\n */\nexport const sha256 = wrapConstructor(() => new SHA256());\nexport const sha224 = wrapConstructor(() => new SHA224());\n//# sourceMappingURL=sha256.js.map","// pure.ts\nimport { schnorr } from \"@noble/curves/secp256k1\";\nimport { bytesToHex as bytesToHex2 } from \"@noble/hashes/utils\";\n\n// core.ts\nvar verifiedSymbol = Symbol(\"verified\");\nvar isRecord = (obj) => obj instanceof Object;\nfunction validateEvent(event) {\n if (!isRecord(event))\n return false;\n if (typeof event.kind !== \"number\")\n return false;\n if (typeof event.content !== \"string\")\n return false;\n if (typeof event.created_at !== \"number\")\n return false;\n if (typeof event.pubkey !== \"string\")\n return false;\n if (!event.pubkey.match(/^[a-f0-9]{64}$/))\n return false;\n if (!Array.isArray(event.tags))\n return false;\n for (let i2 = 0; i2 < event.tags.length; i2++) {\n let tag = event.tags[i2];\n if (!Array.isArray(tag))\n return false;\n for (let j = 0; j < tag.length; j++) {\n if (typeof tag[j] !== \"string\")\n return false;\n }\n }\n return true;\n}\n\n// pure.ts\nimport { sha256 } from \"@noble/hashes/sha256\";\n\n// utils.ts\nimport { bytesToHex, hexToBytes } from \"@noble/hashes/utils\";\nvar utf8Decoder = new TextDecoder(\"utf-8\");\nvar utf8Encoder = new TextEncoder();\nfunction normalizeURL(url) {\n try {\n if (url.indexOf(\"://\") === -1)\n url = \"wss://\" + url;\n let p = new URL(url);\n p.pathname = p.pathname.replace(/\\/+/g, \"/\");\n if (p.pathname.endsWith(\"/\"))\n p.pathname = p.pathname.slice(0, -1);\n if (p.port === \"80\" && p.protocol === \"ws:\" || p.port === \"443\" && p.protocol === \"wss:\")\n p.port = \"\";\n p.searchParams.sort();\n p.hash = \"\";\n return p.toString();\n } catch (e) {\n throw new Error(`Invalid URL: ${url}`);\n }\n}\nvar QueueNode = class {\n value;\n next = null;\n prev = null;\n constructor(message) {\n this.value = message;\n }\n};\nvar Queue = class {\n first;\n last;\n constructor() {\n this.first = null;\n this.last = null;\n }\n enqueue(value) {\n const newNode = new QueueNode(value);\n if (!this.last) {\n this.first = newNode;\n this.last = newNode;\n } else if (this.last === this.first) {\n this.last = newNode;\n this.last.prev = this.first;\n this.first.next = newNode;\n } else {\n newNode.prev = this.last;\n this.last.next = newNode;\n this.last = newNode;\n }\n return true;\n }\n dequeue() {\n if (!this.first)\n return null;\n if (this.first === this.last) {\n const target2 = this.first;\n this.first = null;\n this.last = null;\n return target2.value;\n }\n const target = this.first;\n this.first = target.next;\n if (this.first) {\n this.first.prev = null;\n }\n return target.value;\n }\n};\n\n// pure.ts\nvar JS = class {\n generateSecretKey() {\n return schnorr.utils.randomPrivateKey();\n }\n getPublicKey(secretKey) {\n return bytesToHex2(schnorr.getPublicKey(secretKey));\n }\n finalizeEvent(t, secretKey) {\n const event = t;\n event.pubkey = bytesToHex2(schnorr.getPublicKey(secretKey));\n event.id = getEventHash(event);\n event.sig = bytesToHex2(schnorr.sign(getEventHash(event), secretKey));\n event[verifiedSymbol] = true;\n return event;\n }\n verifyEvent(event) {\n if (typeof event[verifiedSymbol] === \"boolean\")\n return event[verifiedSymbol];\n const hash = getEventHash(event);\n if (hash !== event.id) {\n event[verifiedSymbol] = false;\n return false;\n }\n try {\n const valid = schnorr.verify(event.sig, hash, event.pubkey);\n event[verifiedSymbol] = valid;\n return valid;\n } catch (err) {\n event[verifiedSymbol] = false;\n return false;\n }\n }\n};\nfunction serializeEvent(evt) {\n if (!validateEvent(evt))\n throw new Error(\"can't serialize event with wrong or missing properties\");\n return JSON.stringify([0, evt.pubkey, evt.created_at, evt.kind, evt.tags, evt.content]);\n}\nfunction getEventHash(event) {\n let eventHash = sha256(utf8Encoder.encode(serializeEvent(event)));\n return bytesToHex2(eventHash);\n}\nvar i = new JS();\nvar generateSecretKey = i.generateSecretKey;\nvar getPublicKey = i.getPublicKey;\nvar finalizeEvent = i.finalizeEvent;\nvar verifyEvent = i.verifyEvent;\n\n// kinds.ts\nvar ClientAuth = 22242;\n\n// filter.ts\nfunction matchFilter(filter, event) {\n if (filter.ids && filter.ids.indexOf(event.id) === -1) {\n return false;\n }\n if (filter.kinds && filter.kinds.indexOf(event.kind) === -1) {\n return false;\n }\n if (filter.authors && filter.authors.indexOf(event.pubkey) === -1) {\n return false;\n }\n for (let f in filter) {\n if (f[0] === \"#\") {\n let tagName = f.slice(1);\n let values = filter[`#${tagName}`];\n if (values && !event.tags.find(([t, v]) => t === f.slice(1) && values.indexOf(v) !== -1))\n return false;\n }\n }\n if (filter.since && event.created_at < filter.since)\n return false;\n if (filter.until && event.created_at > filter.until)\n return false;\n return true;\n}\nfunction matchFilters(filters, event) {\n for (let i2 = 0; i2 < filters.length; i2++) {\n if (matchFilter(filters[i2], event)) {\n return true;\n }\n }\n return false;\n}\n\n// fakejson.ts\nfunction getHex64(json, field) {\n let len = field.length + 3;\n let idx = json.indexOf(`\"${field}\":`) + len;\n let s = json.slice(idx).indexOf(`\"`) + idx + 1;\n return json.slice(s, s + 64);\n}\nfunction getSubscriptionId(json) {\n let idx = json.slice(0, 22).indexOf(`\"EVENT\"`);\n if (idx === -1)\n return null;\n let pstart = json.slice(idx + 7 + 1).indexOf(`\"`);\n if (pstart === -1)\n return null;\n let start = idx + 7 + 1 + pstart;\n let pend = json.slice(start + 1, 80).indexOf(`\"`);\n if (pend === -1)\n return null;\n let end = start + 1 + pend;\n return json.slice(start + 1, end);\n}\n\n// nip42.ts\nfunction makeAuthEvent(relayURL, challenge) {\n return {\n kind: ClientAuth,\n created_at: Math.floor(Date.now() / 1e3),\n tags: [\n [\"relay\", relayURL],\n [\"challenge\", challenge]\n ],\n content: \"\"\n };\n}\n\n// helpers.ts\nasync function yieldThread() {\n return new Promise((resolve) => {\n const ch = new MessageChannel();\n const handler = () => {\n ch.port1.removeEventListener(\"message\", handler);\n resolve();\n };\n ch.port1.addEventListener(\"message\", handler);\n ch.port2.postMessage(0);\n ch.port1.start();\n });\n}\nvar alwaysTrue = (t) => {\n t[verifiedSymbol] = true;\n return true;\n};\n\n// abstract-relay.ts\nvar SendingOnClosedConnection = class extends Error {\n constructor(message, relay) {\n super(`Tried to send message '${message} on a closed connection to ${relay}.`);\n this.name = \"SendingOnClosedConnection\";\n }\n};\nvar AbstractRelay = class {\n url;\n _connected = false;\n onclose = null;\n onnotice = (msg) => console.debug(`NOTICE from ${this.url}: ${msg}`);\n baseEoseTimeout = 4400;\n connectionTimeout = 4400;\n publishTimeout = 4400;\n pingFrequency = 2e4;\n pingTimeout = 2e4;\n openSubs = /* @__PURE__ */ new Map();\n enablePing;\n connectionTimeoutHandle;\n connectionPromise;\n openCountRequests = /* @__PURE__ */ new Map();\n openEventPublishes = /* @__PURE__ */ new Map();\n ws;\n incomingMessageQueue = new Queue();\n queueRunning = false;\n challenge;\n authPromise;\n serial = 0;\n verifyEvent;\n _WebSocket;\n constructor(url, opts) {\n this.url = normalizeURL(url);\n this.verifyEvent = opts.verifyEvent;\n this._WebSocket = opts.websocketImplementation || WebSocket;\n this.enablePing = opts.enablePing;\n }\n static async connect(url, opts) {\n const relay = new AbstractRelay(url, opts);\n await relay.connect();\n return relay;\n }\n closeAllSubscriptions(reason) {\n for (let [_, sub] of this.openSubs) {\n sub.close(reason);\n }\n this.openSubs.clear();\n for (let [_, ep] of this.openEventPublishes) {\n ep.reject(new Error(reason));\n }\n this.openEventPublishes.clear();\n for (let [_, cr] of this.openCountRequests) {\n cr.reject(new Error(reason));\n }\n this.openCountRequests.clear();\n }\n get connected() {\n return this._connected;\n }\n async connect() {\n if (this.connectionPromise)\n return this.connectionPromise;\n this.challenge = void 0;\n this.authPromise = void 0;\n this.connectionPromise = new Promise((resolve, reject) => {\n this.connectionTimeoutHandle = setTimeout(() => {\n reject(\"connection timed out\");\n this.connectionPromise = void 0;\n this.onclose?.();\n this.closeAllSubscriptions(\"relay connection timed out\");\n }, this.connectionTimeout);\n try {\n this.ws = new this._WebSocket(this.url);\n } catch (err) {\n clearTimeout(this.connectionTimeoutHandle);\n reject(err);\n return;\n }\n this.ws.onopen = () => {\n clearTimeout(this.connectionTimeoutHandle);\n this._connected = true;\n if (this.enablePing) {\n this.pingpong();\n }\n resolve();\n };\n this.ws.onerror = (ev) => {\n clearTimeout(this.connectionTimeoutHandle);\n reject(ev.message || \"websocket error\");\n this._connected = false;\n this.connectionPromise = void 0;\n this.onclose?.();\n this.closeAllSubscriptions(\"relay connection errored\");\n };\n this.ws.onclose = (ev) => {\n clearTimeout(this.connectionTimeoutHandle);\n reject(ev.message || \"websocket closed\");\n this._connected = false;\n this.connectionPromise = void 0;\n this.onclose?.();\n this.closeAllSubscriptions(\"relay connection closed\");\n };\n this.ws.onmessage = this._onmessage.bind(this);\n });\n return this.connectionPromise;\n }\n async waitForPingPong() {\n return new Promise((res, err) => {\n ;\n this.ws && this.ws.on && this.ws.on(\"pong\", () => res(true)) || err(\"ws can't listen for pong\");\n this.ws && this.ws.ping && this.ws.ping();\n });\n }\n async waitForDummyReq() {\n return new Promise((resolve, _) => {\n const sub = this.subscribe([{ ids: [\"a\".repeat(64)] }], {\n oneose: () => {\n sub.close();\n resolve(true);\n },\n eoseTimeout: this.pingTimeout + 1e3\n });\n });\n }\n async pingpong() {\n if (this.ws?.readyState === 1) {\n const result = await Promise.any([\n this.ws && this.ws.ping && this.ws.on ? this.waitForPingPong() : this.waitForDummyReq(),\n new Promise((res) => setTimeout(() => res(false), this.pingTimeout))\n ]);\n if (result) {\n setTimeout(() => this.pingpong(), this.pingFrequency);\n } else {\n this.closeAllSubscriptions(\"pingpong timed out\");\n this._connected = false;\n this.onclose?.();\n this.ws?.close();\n }\n }\n }\n async runQueue() {\n this.queueRunning = true;\n while (true) {\n if (false === this.handleNext()) {\n break;\n }\n await yieldThread();\n }\n this.queueRunning = false;\n }\n handleNext() {\n const json = this.incomingMessageQueue.dequeue();\n if (!json) {\n return false;\n }\n const subid = getSubscriptionId(json);\n if (subid) {\n const so = this.openSubs.get(subid);\n if (!so) {\n return;\n }\n const id = getHex64(json, \"id\");\n const alreadyHave = so.alreadyHaveEvent?.(id);\n so.receivedEvent?.(this, id);\n if (alreadyHave) {\n return;\n }\n }\n try {\n let data = JSON.parse(json);\n switch (data[0]) {\n case \"EVENT\": {\n const so = this.openSubs.get(data[1]);\n const event = data[2];\n if (this.verifyEvent(event) && matchFilters(so.filters, event)) {\n so.onevent(event);\n }\n return;\n }\n case \"COUNT\": {\n const id = data[1];\n const payload = data[2];\n const cr = this.openCountRequests.get(id);\n if (cr) {\n cr.resolve(payload.count);\n this.openCountRequests.delete(id);\n }\n return;\n }\n case \"EOSE\": {\n const so = this.openSubs.get(data[1]);\n if (!so)\n return;\n so.receivedEose();\n return;\n }\n case \"OK\": {\n const id = data[1];\n const ok = data[2];\n const reason = data[3];\n const ep = this.openEventPublishes.get(id);\n if (ep) {\n clearTimeout(ep.timeout);\n if (ok)\n ep.resolve(reason);\n else\n ep.reject(new Error(reason));\n this.openEventPublishes.delete(id);\n }\n return;\n }\n case \"CLOSED\": {\n const id = data[1];\n const so = this.openSubs.get(id);\n if (!so)\n return;\n so.closed = true;\n so.close(data[2]);\n return;\n }\n case \"NOTICE\":\n this.onnotice(data[1]);\n return;\n case \"AUTH\": {\n this.challenge = data[1];\n return;\n }\n }\n } catch (err) {\n return;\n }\n }\n async send(message) {\n if (!this.connectionPromise)\n throw new SendingOnClosedConnection(message, this.url);\n this.connectionPromise.then(() => {\n this.ws?.send(message);\n });\n }\n async auth(signAuthEvent) {\n const challenge = this.challenge;\n if (!challenge)\n throw new Error(\"can't perform auth, no challenge was received\");\n if (this.authPromise)\n return this.authPromise;\n this.authPromise = new Promise(async (resolve, reject) => {\n try {\n let evt = await signAuthEvent(makeAuthEvent(this.url, challenge));\n let timeout = setTimeout(() => {\n let ep = this.openEventPublishes.get(evt.id);\n if (ep) {\n ep.reject(new Error(\"auth timed out\"));\n this.openEventPublishes.delete(evt.id);\n }\n }, this.publishTimeout);\n this.openEventPublishes.set(evt.id, { resolve, reject, timeout });\n this.send('[\"AUTH\",' + JSON.stringify(evt) + \"]\");\n } catch (err) {\n console.warn(\"subscribe auth function failed:\", err);\n }\n });\n return this.authPromise;\n }\n async publish(event) {\n const ret = new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n const ep = this.openEventPublishes.get(event.id);\n if (ep) {\n ep.reject(new Error(\"publish timed out\"));\n this.openEventPublishes.delete(event.id);\n }\n }, this.publishTimeout);\n this.openEventPublishes.set(event.id, { resolve, reject, timeout });\n });\n this.send('[\"EVENT\",' + JSON.stringify(event) + \"]\");\n return ret;\n }\n async count(filters, params) {\n this.serial++;\n const id = params?.id || \"count:\" + this.serial;\n const ret = new Promise((resolve, reject) => {\n this.openCountRequests.set(id, { resolve, reject });\n });\n this.send('[\"COUNT\",\"' + id + '\",' + JSON.stringify(filters).substring(1));\n return ret;\n }\n subscribe(filters, params) {\n const subscription = this.prepareSubscription(filters, params);\n subscription.fire();\n return subscription;\n }\n prepareSubscription(filters, params) {\n this.serial++;\n const id = params.id || (params.label ? params.label + \":\" : \"sub:\") + this.serial;\n const subscription = new Subscription(this, id, filters, params);\n this.openSubs.set(id, subscription);\n return subscription;\n }\n close() {\n this.closeAllSubscriptions(\"relay connection closed by us\");\n this._connected = false;\n this.onclose?.();\n this.ws?.close();\n }\n _onmessage(ev) {\n this.incomingMessageQueue.enqueue(ev.data);\n if (!this.queueRunning) {\n this.runQueue();\n }\n }\n};\nvar Subscription = class {\n relay;\n id;\n closed = false;\n eosed = false;\n filters;\n alreadyHaveEvent;\n receivedEvent;\n onevent;\n oneose;\n onclose;\n eoseTimeout;\n eoseTimeoutHandle;\n constructor(relay, id, filters, params) {\n this.relay = relay;\n this.filters = filters;\n this.id = id;\n this.alreadyHaveEvent = params.alreadyHaveEvent;\n this.receivedEvent = params.receivedEvent;\n this.eoseTimeout = params.eoseTimeout || relay.baseEoseTimeout;\n this.oneose = params.oneose;\n this.onclose = params.onclose;\n this.onevent = params.onevent || ((event) => {\n console.warn(\n `onevent() callback not defined for subscription '${this.id}' in relay ${this.relay.url}. event received:`,\n event\n );\n });\n }\n fire() {\n this.relay.send('[\"REQ\",\"' + this.id + '\",' + JSON.stringify(this.filters).substring(1));\n this.eoseTimeoutHandle = setTimeout(this.receivedEose.bind(this), this.eoseTimeout);\n }\n receivedEose() {\n if (this.eosed)\n return;\n clearTimeout(this.eoseTimeoutHandle);\n this.eosed = true;\n this.oneose?.();\n }\n close(reason = \"closed by caller\") {\n if (!this.closed && this.relay.connected) {\n try {\n this.relay.send('[\"CLOSE\",' + JSON.stringify(this.id) + \"]\");\n } catch (err) {\n if (err instanceof SendingOnClosedConnection) {\n } else {\n throw err;\n }\n }\n this.closed = true;\n }\n this.relay.openSubs.delete(this.id);\n this.onclose?.(reason);\n }\n};\n\n// abstract-pool.ts\nvar AbstractSimplePool = class {\n relays = /* @__PURE__ */ new Map();\n seenOn = /* @__PURE__ */ new Map();\n trackRelays = false;\n verifyEvent;\n enablePing;\n trustedRelayURLs = /* @__PURE__ */ new Set();\n _WebSocket;\n constructor(opts) {\n this.verifyEvent = opts.verifyEvent;\n this._WebSocket = opts.websocketImplementation;\n this.enablePing = opts.enablePing;\n }\n async ensureRelay(url, params) {\n url = normalizeURL(url);\n let relay = this.relays.get(url);\n if (!relay) {\n relay = new AbstractRelay(url, {\n verifyEvent: this.trustedRelayURLs.has(url) ? alwaysTrue : this.verifyEvent,\n websocketImplementation: this._WebSocket,\n enablePing: this.enablePing\n });\n relay.onclose = () => {\n this.relays.delete(url);\n };\n if (params?.connectionTimeout)\n relay.connectionTimeout = params.connectionTimeout;\n this.relays.set(url, relay);\n }\n await relay.connect();\n return relay;\n }\n close(relays) {\n relays.map(normalizeURL).forEach((url) => {\n this.relays.get(url)?.close();\n this.relays.delete(url);\n });\n }\n subscribe(relays, filter, params) {\n params.onauth = params.onauth || params.doauth;\n const request = [];\n for (let i2 = 0; i2 < relays.length; i2++) {\n const url = normalizeURL(relays[i2]);\n if (!request.find((r) => r.url === url)) {\n request.push({ url, filter });\n }\n }\n return this.subscribeMap(request, params);\n }\n subscribeMany(relays, filter, params) {\n params.onauth = params.onauth || params.doauth;\n const request = [];\n const uniqUrls = [];\n for (let i2 = 0; i2 < relays.length; i2++) {\n const url = normalizeURL(relays[i2]);\n if (uniqUrls.indexOf(url) === -1) {\n uniqUrls.push(url);\n request.push({ url, filter });\n }\n }\n return this.subscribeMap(request, params);\n }\n subscribeMap(requests, params) {\n params.onauth = params.onauth || params.doauth;\n const grouped = /* @__PURE__ */ new Map();\n for (const req of requests) {\n const { url, filter } = req;\n if (!grouped.has(url))\n grouped.set(url, []);\n grouped.get(url).push(filter);\n }\n const groupedRequests = Array.from(grouped.entries()).map(([url, filters]) => ({ url, filters }));\n if (this.trackRelays) {\n params.receivedEvent = (relay, id) => {\n let set = this.seenOn.get(id);\n if (!set) {\n set = /* @__PURE__ */ new Set();\n this.seenOn.set(id, set);\n }\n set.add(relay);\n };\n }\n const _knownIds = /* @__PURE__ */ new Set();\n const subs = [];\n const eosesReceived = [];\n let handleEose = (i2) => {\n if (eosesReceived[i2])\n return;\n eosesReceived[i2] = true;\n if (eosesReceived.filter((a) => a).length === requests.length) {\n params.oneose?.();\n handleEose = () => {\n };\n }\n };\n const closesReceived = [];\n let handleClose = (i2, reason) => {\n if (closesReceived[i2])\n return;\n handleEose(i2);\n closesReceived[i2] = reason;\n if (closesReceived.filter((a) => a).length === requests.length) {\n params.onclose?.(closesReceived);\n handleClose = () => {\n };\n }\n };\n const localAlreadyHaveEventHandler = (id) => {\n if (params.alreadyHaveEvent?.(id)) {\n return true;\n }\n const have = _knownIds.has(id);\n _knownIds.add(id);\n return have;\n };\n const allOpened = Promise.all(\n groupedRequests.map(async ({ url, filters }, i2) => {\n let relay;\n try {\n relay = await this.ensureRelay(url, {\n connectionTimeout: params.maxWait ? Math.max(params.maxWait * 0.8, params.maxWait - 1e3) : void 0\n });\n } catch (err) {\n handleClose(i2, err?.message || String(err));\n return;\n }\n let subscription = relay.subscribe(filters, {\n ...params,\n oneose: () => handleEose(i2),\n onclose: (reason) => {\n if (reason.startsWith(\"auth-required: \") && params.onauth) {\n relay.auth(params.onauth).then(() => {\n relay.subscribe(filters, {\n ...params,\n oneose: () => handleEose(i2),\n onclose: (reason2) => {\n handleClose(i2, reason2);\n },\n alreadyHaveEvent: localAlreadyHaveEventHandler,\n eoseTimeout: params.maxWait\n });\n }).catch((err) => {\n handleClose(i2, `auth was required and attempted, but failed with: ${err}`);\n });\n } else {\n handleClose(i2, reason);\n }\n },\n alreadyHaveEvent: localAlreadyHaveEventHandler,\n eoseTimeout: params.maxWait\n });\n subs.push(subscription);\n })\n );\n return {\n async close(reason) {\n await allOpened;\n subs.forEach((sub) => {\n sub.close(reason);\n });\n }\n };\n }\n subscribeEose(relays, filter, params) {\n params.onauth = params.onauth || params.doauth;\n const subcloser = this.subscribe(relays, filter, {\n ...params,\n oneose() {\n subcloser.close(\"closed automatically on eose\");\n }\n });\n return subcloser;\n }\n subscribeManyEose(relays, filter, params) {\n params.onauth = params.onauth || params.doauth;\n const subcloser = this.subscribeMany(relays, filter, {\n ...params,\n oneose() {\n subcloser.close(\"closed automatically on eose\");\n }\n });\n return subcloser;\n }\n async querySync(relays, filter, params) {\n return new Promise(async (resolve) => {\n const events = [];\n this.subscribeEose(relays, filter, {\n ...params,\n onevent(event) {\n events.push(event);\n },\n onclose(_) {\n resolve(events);\n }\n });\n });\n }\n async get(relays, filter, params) {\n filter.limit = 1;\n const events = await this.querySync(relays, filter, params);\n events.sort((a, b) => b.created_at - a.created_at);\n return events[0] || null;\n }\n publish(relays, event, options) {\n return relays.map(normalizeURL).map(async (url, i2, arr) => {\n if (arr.indexOf(url) !== i2) {\n return Promise.reject(\"duplicate url\");\n }\n let r = await this.ensureRelay(url);\n return r.publish(event).catch(async (err) => {\n if (err instanceof Error && err.message.startsWith(\"auth-required: \") && options?.onauth) {\n await r.auth(options.onauth);\n return r.publish(event);\n }\n throw err;\n }).then((reason) => {\n if (this.trackRelays) {\n let set = this.seenOn.get(event.id);\n if (!set) {\n set = /* @__PURE__ */ new Set();\n this.seenOn.set(event.id, set);\n }\n set.add(r);\n }\n return reason;\n });\n });\n }\n listConnectionStatus() {\n const map = /* @__PURE__ */ new Map();\n this.relays.forEach((relay, url) => map.set(url, relay.connected));\n return map;\n }\n destroy() {\n this.relays.forEach((conn) => conn.close());\n this.relays = /* @__PURE__ */ new Map();\n }\n};\n\n// pool.ts\nvar _WebSocket;\ntry {\n _WebSocket = WebSocket;\n} catch {\n}\nfunction useWebSocketImplementation(websocketImplementation) {\n _WebSocket = websocketImplementation;\n}\nvar SimplePool = class extends AbstractSimplePool {\n constructor(options) {\n super({ verifyEvent, websocketImplementation: _WebSocket, ...options });\n }\n};\nexport {\n AbstractSimplePool,\n SimplePool,\n useWebSocketImplementation\n};\n","/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nexport function assertNumber(n) {\n if (!Number.isSafeInteger(n))\n throw new Error(`Wrong integer: ${n}`);\n}\nfunction chain(...args) {\n const wrap = (a, b) => (c) => a(b(c));\n const encode = Array.from(args)\n .reverse()\n .reduce((acc, i) => (acc ? wrap(acc, i.encode) : i.encode), undefined);\n const decode = args.reduce((acc, i) => (acc ? wrap(acc, i.decode) : i.decode), undefined);\n return { encode, decode };\n}\nfunction alphabet(alphabet) {\n return {\n encode: (digits) => {\n if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))\n throw new Error('alphabet.encode input should be an array of numbers');\n return digits.map((i) => {\n assertNumber(i);\n if (i < 0 || i >= alphabet.length)\n throw new Error(`Digit index outside alphabet: ${i} (alphabet: ${alphabet.length})`);\n return alphabet[i];\n });\n },\n decode: (input) => {\n if (!Array.isArray(input) || (input.length && typeof input[0] !== 'string'))\n throw new Error('alphabet.decode input should be array of strings');\n return input.map((letter) => {\n if (typeof letter !== 'string')\n throw new Error(`alphabet.decode: not string element=${letter}`);\n const index = alphabet.indexOf(letter);\n if (index === -1)\n throw new Error(`Unknown letter: \"${letter}\". Allowed: ${alphabet}`);\n return index;\n });\n },\n };\n}\nfunction join(separator = '') {\n if (typeof separator !== 'string')\n throw new Error('join separator should be string');\n return {\n encode: (from) => {\n if (!Array.isArray(from) || (from.length && typeof from[0] !== 'string'))\n throw new Error('join.encode input should be array of strings');\n for (let i of from)\n if (typeof i !== 'string')\n throw new Error(`join.encode: non-string input=${i}`);\n return from.join(separator);\n },\n decode: (to) => {\n if (typeof to !== 'string')\n throw new Error('join.decode input should be string');\n return to.split(separator);\n },\n };\n}\nfunction padding(bits, chr = '=') {\n assertNumber(bits);\n if (typeof chr !== 'string')\n throw new Error('padding chr should be string');\n return {\n encode(data) {\n if (!Array.isArray(data) || (data.length && typeof data[0] !== 'string'))\n throw new Error('padding.encode input should be array of strings');\n for (let i of data)\n if (typeof i !== 'string')\n throw new Error(`padding.encode: non-string input=${i}`);\n while ((data.length * bits) % 8)\n data.push(chr);\n return data;\n },\n decode(input) {\n if (!Array.isArray(input) || (input.length && typeof input[0] !== 'string'))\n throw new Error('padding.encode input should be array of strings');\n for (let i of input)\n if (typeof i !== 'string')\n throw new Error(`padding.decode: non-string input=${i}`);\n let end = input.length;\n if ((end * bits) % 8)\n throw new Error('Invalid padding: string should have whole number of bytes');\n for (; end > 0 && input[end - 1] === chr; end--) {\n if (!(((end - 1) * bits) % 8))\n throw new Error('Invalid padding: string has too much padding');\n }\n return input.slice(0, end);\n },\n };\n}\nfunction normalize(fn) {\n if (typeof fn !== 'function')\n throw new Error('normalize fn should be function');\n return { encode: (from) => from, decode: (to) => fn(to) };\n}\nfunction convertRadix(data, from, to) {\n if (from < 2)\n throw new Error(`convertRadix: wrong from=${from}, base cannot be less than 2`);\n if (to < 2)\n throw new Error(`convertRadix: wrong to=${to}, base cannot be less than 2`);\n if (!Array.isArray(data))\n throw new Error('convertRadix: data should be array');\n if (!data.length)\n return [];\n let pos = 0;\n const res = [];\n const digits = Array.from(data);\n digits.forEach((d) => {\n assertNumber(d);\n if (d < 0 || d >= from)\n throw new Error(`Wrong integer: ${d}`);\n });\n while (true) {\n let carry = 0;\n let done = true;\n for (let i = pos; i < digits.length; i++) {\n const digit = digits[i];\n const digitBase = from * carry + digit;\n if (!Number.isSafeInteger(digitBase) ||\n (from * carry) / from !== carry ||\n digitBase - digit !== from * carry) {\n throw new Error('convertRadix: carry overflow');\n }\n carry = digitBase % to;\n digits[i] = Math.floor(digitBase / to);\n if (!Number.isSafeInteger(digits[i]) || digits[i] * to + carry !== digitBase)\n throw new Error('convertRadix: carry overflow');\n if (!done)\n continue;\n else if (!digits[i])\n pos = i;\n else\n done = false;\n }\n res.push(carry);\n if (done)\n break;\n }\n for (let i = 0; i < data.length - 1 && data[i] === 0; i++)\n res.push(0);\n return res.reverse();\n}\nconst gcd = (a, b) => (!b ? a : gcd(b, a % b));\nconst radix2carry = (from, to) => from + (to - gcd(from, to));\nfunction convertRadix2(data, from, to, padding) {\n if (!Array.isArray(data))\n throw new Error('convertRadix2: data should be array');\n if (from <= 0 || from > 32)\n throw new Error(`convertRadix2: wrong from=${from}`);\n if (to <= 0 || to > 32)\n throw new Error(`convertRadix2: wrong to=${to}`);\n if (radix2carry(from, to) > 32) {\n throw new Error(`convertRadix2: carry overflow from=${from} to=${to} carryBits=${radix2carry(from, to)}`);\n }\n let carry = 0;\n let pos = 0;\n const mask = 2 ** to - 1;\n const res = [];\n for (const n of data) {\n assertNumber(n);\n if (n >= 2 ** from)\n throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);\n carry = (carry << from) | n;\n if (pos + from > 32)\n throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from}`);\n pos += from;\n for (; pos >= to; pos -= to)\n res.push(((carry >> (pos - to)) & mask) >>> 0);\n carry &= 2 ** pos - 1;\n }\n carry = (carry << (to - pos)) & mask;\n if (!padding && pos >= from)\n throw new Error('Excess padding');\n if (!padding && carry)\n throw new Error(`Non-zero padding: ${carry}`);\n if (padding && pos > 0)\n res.push(carry >>> 0);\n return res;\n}\nfunction radix(num) {\n assertNumber(num);\n return {\n encode: (bytes) => {\n if (!(bytes instanceof Uint8Array))\n throw new Error('radix.encode input should be Uint8Array');\n return convertRadix(Array.from(bytes), 2 ** 8, num);\n },\n decode: (digits) => {\n if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))\n throw new Error('radix.decode input should be array of strings');\n return Uint8Array.from(convertRadix(digits, num, 2 ** 8));\n },\n };\n}\nfunction radix2(bits, revPadding = false) {\n assertNumber(bits);\n if (bits <= 0 || bits > 32)\n throw new Error('radix2: bits should be in (0..32]');\n if (radix2carry(8, bits) > 32 || radix2carry(bits, 8) > 32)\n throw new Error('radix2: carry overflow');\n return {\n encode: (bytes) => {\n if (!(bytes instanceof Uint8Array))\n throw new Error('radix2.encode input should be Uint8Array');\n return convertRadix2(Array.from(bytes), 8, bits, !revPadding);\n },\n decode: (digits) => {\n if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))\n throw new Error('radix2.decode input should be array of strings');\n return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding));\n },\n };\n}\nfunction unsafeWrapper(fn) {\n if (typeof fn !== 'function')\n throw new Error('unsafeWrapper fn should be function');\n return function (...args) {\n try {\n return fn.apply(null, args);\n }\n catch (e) { }\n };\n}\nfunction checksum(len, fn) {\n assertNumber(len);\n if (typeof fn !== 'function')\n throw new Error('checksum fn should be function');\n return {\n encode(data) {\n if (!(data instanceof Uint8Array))\n throw new Error('checksum.encode: input should be Uint8Array');\n const checksum = fn(data).slice(0, len);\n const res = new Uint8Array(data.length + len);\n res.set(data);\n res.set(checksum, data.length);\n return res;\n },\n decode(data) {\n if (!(data instanceof Uint8Array))\n throw new Error('checksum.decode: input should be Uint8Array');\n const payload = data.slice(0, -len);\n const newChecksum = fn(payload).slice(0, len);\n const oldChecksum = data.slice(-len);\n for (let i = 0; i < len; i++)\n if (newChecksum[i] !== oldChecksum[i])\n throw new Error('Invalid checksum');\n return payload;\n },\n };\n}\nexport const utils = { alphabet, chain, checksum, radix, radix2, join, padding };\nexport const base16 = chain(radix2(4), alphabet('0123456789ABCDEF'), join(''));\nexport const base32 = chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), padding(5), join(''));\nexport const base32hex = chain(radix2(5), alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'), padding(5), join(''));\nexport const base32crockford = chain(radix2(5), alphabet('0123456789ABCDEFGHJKMNPQRSTVWXYZ'), join(''), normalize((s) => s.toUpperCase().replace(/O/g, '0').replace(/[IL]/g, '1')));\nexport const base64 = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), padding(6), join(''));\nexport const base64url = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), padding(6), join(''));\nconst genBase58 = (abc) => chain(radix(58), alphabet(abc), join(''));\nexport const base58 = genBase58('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');\nexport const base58flickr = genBase58('123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ');\nexport const base58xrp = genBase58('rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz');\nconst XMR_BLOCK_LEN = [0, 2, 3, 5, 6, 7, 9, 10, 11];\nexport const base58xmr = {\n encode(data) {\n let res = '';\n for (let i = 0; i < data.length; i += 8) {\n const block = data.subarray(i, i + 8);\n res += base58.encode(block).padStart(XMR_BLOCK_LEN[block.length], '1');\n }\n return res;\n },\n decode(str) {\n let res = [];\n for (let i = 0; i < str.length; i += 11) {\n const slice = str.slice(i, i + 11);\n const blockLen = XMR_BLOCK_LEN.indexOf(slice.length);\n const block = base58.decode(slice);\n for (let j = 0; j < block.length - blockLen; j++) {\n if (block[j] !== 0)\n throw new Error('base58xmr: wrong padding');\n }\n res = res.concat(Array.from(block.slice(block.length - blockLen)));\n }\n return Uint8Array.from(res);\n },\n};\nexport const base58check = (sha256) => chain(checksum(4, (data) => sha256(sha256(data))), base58);\nconst BECH_ALPHABET = chain(alphabet('qpzry9x8gf2tvdw0s3jn54khce6mua7l'), join(''));\nconst POLYMOD_GENERATORS = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];\nfunction bech32Polymod(pre) {\n const b = pre >> 25;\n let chk = (pre & 0x1ffffff) << 5;\n for (let i = 0; i < POLYMOD_GENERATORS.length; i++) {\n if (((b >> i) & 1) === 1)\n chk ^= POLYMOD_GENERATORS[i];\n }\n return chk;\n}\nfunction bechChecksum(prefix, words, encodingConst = 1) {\n const len = prefix.length;\n let chk = 1;\n for (let i = 0; i < len; i++) {\n const c = prefix.charCodeAt(i);\n if (c < 33 || c > 126)\n throw new Error(`Invalid prefix (${prefix})`);\n chk = bech32Polymod(chk) ^ (c >> 5);\n }\n chk = bech32Polymod(chk);\n for (let i = 0; i < len; i++)\n chk = bech32Polymod(chk) ^ (prefix.charCodeAt(i) & 0x1f);\n for (let v of words)\n chk = bech32Polymod(chk) ^ v;\n for (let i = 0; i < 6; i++)\n chk = bech32Polymod(chk);\n chk ^= encodingConst;\n return BECH_ALPHABET.encode(convertRadix2([chk % 2 ** 30], 30, 5, false));\n}\nfunction genBech32(encoding) {\n const ENCODING_CONST = encoding === 'bech32' ? 1 : 0x2bc830a3;\n const _words = radix2(5);\n const fromWords = _words.decode;\n const toWords = _words.encode;\n const fromWordsUnsafe = unsafeWrapper(fromWords);\n function encode(prefix, words, limit = 90) {\n if (typeof prefix !== 'string')\n throw new Error(`bech32.encode prefix should be string, not ${typeof prefix}`);\n if (!Array.isArray(words) || (words.length && typeof words[0] !== 'number'))\n throw new Error(`bech32.encode words should be array of numbers, not ${typeof words}`);\n const actualLength = prefix.length + 7 + words.length;\n if (limit !== false && actualLength > limit)\n throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`);\n prefix = prefix.toLowerCase();\n return `${prefix}1${BECH_ALPHABET.encode(words)}${bechChecksum(prefix, words, ENCODING_CONST)}`;\n }\n function decode(str, limit = 90) {\n if (typeof str !== 'string')\n throw new Error(`bech32.decode input should be string, not ${typeof str}`);\n if (str.length < 8 || (limit !== false && str.length > limit))\n throw new TypeError(`Wrong string length: ${str.length} (${str}). Expected (8..${limit})`);\n const lowered = str.toLowerCase();\n if (str !== lowered && str !== str.toUpperCase())\n throw new Error(`String must be lowercase or uppercase`);\n str = lowered;\n const sepIndex = str.lastIndexOf('1');\n if (sepIndex === 0 || sepIndex === -1)\n throw new Error(`Letter \"1\" must be present between prefix and data only`);\n const prefix = str.slice(0, sepIndex);\n const _words = str.slice(sepIndex + 1);\n if (_words.length < 6)\n throw new Error('Data must be at least 6 characters long');\n const words = BECH_ALPHABET.decode(_words).slice(0, -6);\n const sum = bechChecksum(prefix, words, ENCODING_CONST);\n if (!_words.endsWith(sum))\n throw new Error(`Invalid checksum in ${str}: expected \"${sum}\"`);\n return { prefix, words };\n }\n const decodeUnsafe = unsafeWrapper(decode);\n function decodeToBytes(str) {\n const { prefix, words } = decode(str, false);\n return { prefix, words, bytes: fromWords(words) };\n }\n return { encode, decode, decodeToBytes, decodeUnsafe, fromWords, fromWordsUnsafe, toWords };\n}\nexport const bech32 = genBech32('bech32');\nexport const bech32m = genBech32('bech32m');\nexport const utf8 = {\n encode: (data) => new TextDecoder().decode(data),\n decode: (str) => new TextEncoder().encode(str),\n};\nexport const hex = chain(radix2(4), alphabet('0123456789abcdef'), join(''), normalize((s) => {\n if (typeof s !== 'string' || s.length % 2)\n throw new TypeError(`hex.decode: expected string, got ${typeof s} with length ${s.length}`);\n return s.toLowerCase();\n}));\nconst CODERS = {\n utf8, hex, base16, base32, base64, base64url, base58, base58xmr\n};\nconst coderTypeError = `Invalid encoding type. Available types: ${Object.keys(CODERS).join(', ')}`;\nexport const bytesToString = (type, bytes) => {\n if (typeof type !== 'string' || !CODERS.hasOwnProperty(type))\n throw new TypeError(coderTypeError);\n if (!(bytes instanceof Uint8Array))\n throw new TypeError('bytesToString() expects Uint8Array');\n return CODERS[type].encode(bytes);\n};\nexport const str = bytesToString;\nexport const stringToBytes = (type, str) => {\n if (!CODERS.hasOwnProperty(type))\n throw new TypeError(coderTypeError);\n if (typeof str !== 'string')\n throw new TypeError('stringToBytes() expects string');\n return CODERS[type].decode(str);\n};\nexport const bytes = stringToBytes;\n","function number(n) {\n if (!Number.isSafeInteger(n) || n < 0)\n throw new Error(`positive integer expected, not ${n}`);\n}\nfunction bool(b) {\n if (typeof b !== 'boolean')\n throw new Error(`boolean expected, not ${b}`);\n}\nexport function isBytes(a) {\n return (a instanceof Uint8Array ||\n (a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));\n}\nfunction bytes(b, ...lengths) {\n if (!isBytes(b))\n throw new Error('Uint8Array expected');\n if (lengths.length > 0 && !lengths.includes(b.length))\n throw new Error(`Uint8Array expected of length ${lengths}, not of length=${b.length}`);\n}\nfunction hash(hash) {\n if (typeof hash !== 'function' || typeof hash.create !== 'function')\n throw new Error('hash must be wrapped by utils.wrapConstructor');\n number(hash.outputLen);\n number(hash.blockLen);\n}\nfunction exists(instance, checkFinished = true) {\n if (instance.destroyed)\n throw new Error('Hash instance has been destroyed');\n if (checkFinished && instance.finished)\n throw new Error('Hash#digest() has already been called');\n}\nfunction output(out, instance) {\n bytes(out);\n const min = instance.outputLen;\n if (out.length < min) {\n throw new Error(`digestInto() expects output buffer of length at least ${min}`);\n }\n}\nexport { number, bool, bytes, hash, exists, output };\nconst assert = { number, bool, bytes, hash, exists, output };\nexport default assert;\n//# sourceMappingURL=_assert.js.map","/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */\nimport { bytes as abytes, isBytes } from './_assert.js';\n// Cast array to different type\nexport const u8 = (arr) => new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);\nexport const u16 = (arr) => new Uint16Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 2));\nexport const u32 = (arr) => new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));\n// Cast array to view\nexport const createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength);\n// big-endian hardware is rare. Just in case someone still decides to run ciphers:\n// early-throw an error because we don't support BE yet.\nexport const isLE = new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44;\nif (!isLE)\n throw new Error('Non little-endian hardware is not supported');\n// Array where index 0xf0 (240) is mapped to string 'f0'\nconst hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));\n/**\n * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'\n */\nexport function bytesToHex(bytes) {\n abytes(bytes);\n // pre-caching improves the speed 6x\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += hexes[bytes[i]];\n }\n return hex;\n}\n// We use optimized technique to convert hex string to byte array\nconst asciis = { _0: 48, _9: 57, _A: 65, _F: 70, _a: 97, _f: 102 };\nfunction asciiToBase16(char) {\n if (char >= asciis._0 && char <= asciis._9)\n return char - asciis._0;\n if (char >= asciis._A && char <= asciis._F)\n return char - (asciis._A - 10);\n if (char >= asciis._a && char <= asciis._f)\n return char - (asciis._a - 10);\n return;\n}\n/**\n * @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])\n */\nexport function hexToBytes(hex) {\n if (typeof hex !== 'string')\n throw new Error('hex string expected, got ' + typeof hex);\n const hl = hex.length;\n const al = hl / 2;\n if (hl % 2)\n throw new Error('padded hex string expected, got unpadded hex of length ' + hl);\n const array = new Uint8Array(al);\n for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {\n const n1 = asciiToBase16(hex.charCodeAt(hi));\n const n2 = asciiToBase16(hex.charCodeAt(hi + 1));\n if (n1 === undefined || n2 === undefined) {\n const char = hex[hi] + hex[hi + 1];\n throw new Error('hex string expected, got non-hex character \"' + char + '\" at index ' + hi);\n }\n array[ai] = n1 * 16 + n2;\n }\n return array;\n}\nexport function hexToNumber(hex) {\n if (typeof hex !== 'string')\n throw new Error('hex string expected, got ' + typeof hex);\n // Big Endian\n return BigInt(hex === '' ? '0' : `0x${hex}`);\n}\n// BE: Big Endian, LE: Little Endian\nexport function bytesToNumberBE(bytes) {\n return hexToNumber(bytesToHex(bytes));\n}\nexport function numberToBytesBE(n, len) {\n return hexToBytes(n.toString(16).padStart(len * 2, '0'));\n}\n// There is no setImmediate in browser and setTimeout is slow.\n// call of async fn will return Promise, which will be fullfiled only on\n// next scheduler queue processing step and this is exactly what we need.\nexport const nextTick = async () => { };\n// Returns control to thread each 'tick' ms to avoid blocking\nexport async function asyncLoop(iters, tick, cb) {\n let ts = Date.now();\n for (let i = 0; i < iters; i++) {\n cb(i);\n // Date.now() is not monotonic, so in case if clock goes backwards we return return control too\n const diff = Date.now() - ts;\n if (diff >= 0 && diff < tick)\n continue;\n await nextTick();\n ts += diff;\n }\n}\n/**\n * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])\n */\nexport function utf8ToBytes(str) {\n if (typeof str !== 'string')\n throw new Error(`string expected, got ${typeof str}`);\n return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809\n}\n/**\n * @example bytesToUtf8(new Uint8Array([97, 98, 99])) // 'abc'\n */\nexport function bytesToUtf8(bytes) {\n return new TextDecoder().decode(bytes);\n}\n/**\n * Normalizes (non-hex) string or Uint8Array to Uint8Array.\n * Warning: when Uint8Array is passed, it would NOT get copied.\n * Keep in mind for future mutable operations.\n */\nexport function toBytes(data) {\n if (typeof data === 'string')\n data = utf8ToBytes(data);\n else if (isBytes(data))\n data = data.slice();\n else\n throw new Error(`Uint8Array expected, got ${typeof data}`);\n return data;\n}\n/**\n * Copies several Uint8Arrays into one.\n */\nexport function concatBytes(...arrays) {\n let sum = 0;\n for (let i = 0; i < arrays.length; i++) {\n const a = arrays[i];\n abytes(a);\n sum += a.length;\n }\n const res = new Uint8Array(sum);\n for (let i = 0, pad = 0; i < arrays.length; i++) {\n const a = arrays[i];\n res.set(a, pad);\n pad += a.length;\n }\n return res;\n}\nexport function checkOpts(defaults, opts) {\n if (opts == null || typeof opts !== 'object')\n throw new Error('options must be defined');\n const merged = Object.assign(defaults, opts);\n return merged;\n}\n// Compares 2 u8a-s in kinda constant time\nexport function equalBytes(a, b) {\n if (a.length !== b.length)\n return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++)\n diff |= a[i] ^ b[i];\n return diff === 0;\n}\n// For runtime check if class implements interface\nexport class Hash {\n}\n/**\n * @__NO_SIDE_EFFECTS__\n */\nexport const wrapCipher = (params, c) => {\n Object.assign(c, params);\n return c;\n};\n// Polyfill for Safari 14\nexport function setBigUint64(view, byteOffset, value, isLE) {\n if (typeof view.setBigUint64 === 'function')\n return view.setBigUint64(byteOffset, value, isLE);\n const _32n = BigInt(32);\n const _u32_max = BigInt(0xffffffff);\n const wh = Number((value >> _32n) & _u32_max);\n const wl = Number(value & _u32_max);\n const h = isLE ? 4 : 0;\n const l = isLE ? 0 : 4;\n view.setUint32(byteOffset + h, wh, isLE);\n view.setUint32(byteOffset + l, wl, isLE);\n}\nexport function u64Lengths(ciphertext, AAD) {\n const num = new Uint8Array(16);\n const view = createView(num);\n setBigUint64(view, 0, BigInt(AAD ? AAD.length : 0), true);\n setBigUint64(view, 8, BigInt(ciphertext.length), true);\n return num;\n}\n//# sourceMappingURL=utils.js.map","// prettier-ignore\nimport { wrapCipher, createView, setBigUint64, equalBytes, u32, u8, } from './utils.js';\nimport { ghash, polyval } from './_polyval.js';\nimport { bytes as abytes } from './_assert.js';\n/*\nAES (Advanced Encryption Standard) aka Rijndael block cipher.\n\nData is split into 128-bit blocks. Encrypted in 10/12/14 rounds (128/192/256 bits). In every round:\n1. **S-box**, table substitution\n2. **Shift rows**, cyclic shift left of all rows of data array\n3. **Mix columns**, multiplying every column by fixed polynomial\n4. **Add round key**, round_key xor i-th column of array\n\nResources:\n- FIPS-197 https://csrc.nist.gov/files/pubs/fips/197/final/docs/fips-197.pdf\n- Original proposal: https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/aes-development/rijndael-ammended.pdf\n*/\nconst BLOCK_SIZE = 16;\nconst BLOCK_SIZE32 = 4;\nconst EMPTY_BLOCK = new Uint8Array(BLOCK_SIZE);\nconst POLY = 0x11b; // 1 + x + x**3 + x**4 + x**8\n// TODO: remove multiplication, binary ops only\nfunction mul2(n) {\n return (n << 1) ^ (POLY & -(n >> 7));\n}\nfunction mul(a, b) {\n let res = 0;\n for (; b > 0; b >>= 1) {\n // Montgomery ladder\n res ^= a & -(b & 1); // if (b&1) res ^=a (but const-time).\n a = mul2(a); // a = 2*a\n }\n return res;\n}\n// AES S-box is generated using finite field inversion,\n// an affine transform, and xor of a constant 0x63.\nconst sbox = /* @__PURE__ */ (() => {\n let t = new Uint8Array(256);\n for (let i = 0, x = 1; i < 256; i++, x ^= mul2(x))\n t[i] = x;\n const box = new Uint8Array(256);\n box[0] = 0x63; // first elm\n for (let i = 0; i < 255; i++) {\n let x = t[255 - i];\n x |= x << 8;\n box[t[i]] = (x ^ (x >> 4) ^ (x >> 5) ^ (x >> 6) ^ (x >> 7) ^ 0x63) & 0xff;\n }\n return box;\n})();\n// Inverted S-box\nconst invSbox = /* @__PURE__ */ sbox.map((_, j) => sbox.indexOf(j));\n// Rotate u32 by 8\nconst rotr32_8 = (n) => (n << 24) | (n >>> 8);\nconst rotl32_8 = (n) => (n << 8) | (n >>> 24);\n// T-table is optimization suggested in 5.2 of original proposal (missed from FIPS-197). Changes:\n// - LE instead of BE\n// - bigger tables: T0 and T1 are merged into T01 table and T2 & T3 into T23;\n// so index is u16, instead of u8. This speeds up things, unexpectedly\nfunction genTtable(sbox, fn) {\n if (sbox.length !== 256)\n throw new Error('Wrong sbox length');\n const T0 = new Uint32Array(256).map((_, j) => fn(sbox[j]));\n const T1 = T0.map(rotl32_8);\n const T2 = T1.map(rotl32_8);\n const T3 = T2.map(rotl32_8);\n const T01 = new Uint32Array(256 * 256);\n const T23 = new Uint32Array(256 * 256);\n const sbox2 = new Uint16Array(256 * 256);\n for (let i = 0; i < 256; i++) {\n for (let j = 0; j < 256; j++) {\n const idx = i * 256 + j;\n T01[idx] = T0[i] ^ T1[j];\n T23[idx] = T2[i] ^ T3[j];\n sbox2[idx] = (sbox[i] << 8) | sbox[j];\n }\n }\n return { sbox, sbox2, T0, T1, T2, T3, T01, T23 };\n}\nconst tableEncoding = /* @__PURE__ */ genTtable(sbox, (s) => (mul(s, 3) << 24) | (s << 16) | (s << 8) | mul(s, 2));\nconst tableDecoding = /* @__PURE__ */ genTtable(invSbox, (s) => (mul(s, 11) << 24) | (mul(s, 13) << 16) | (mul(s, 9) << 8) | mul(s, 14));\nconst xPowers = /* @__PURE__ */ (() => {\n const p = new Uint8Array(16);\n for (let i = 0, x = 1; i < 16; i++, x = mul2(x))\n p[i] = x;\n return p;\n})();\nexport function expandKeyLE(key) {\n abytes(key);\n const len = key.length;\n if (![16, 24, 32].includes(len))\n throw new Error(`aes: wrong key size: should be 16, 24 or 32, got: ${len}`);\n const { sbox2 } = tableEncoding;\n const k32 = u32(key);\n const Nk = k32.length;\n const subByte = (n) => applySbox(sbox2, n, n, n, n);\n const xk = new Uint32Array(len + 28); // expanded key\n xk.set(k32);\n // 4.3.1 Key expansion\n for (let i = Nk; i < xk.length; i++) {\n let t = xk[i - 1];\n if (i % Nk === 0)\n t = subByte(rotr32_8(t)) ^ xPowers[i / Nk - 1];\n else if (Nk > 6 && i % Nk === 4)\n t = subByte(t);\n xk[i] = xk[i - Nk] ^ t;\n }\n return xk;\n}\nexport function expandKeyDecLE(key) {\n const encKey = expandKeyLE(key);\n const xk = encKey.slice();\n const Nk = encKey.length;\n const { sbox2 } = tableEncoding;\n const { T0, T1, T2, T3 } = tableDecoding;\n // Inverse key by chunks of 4 (rounds)\n for (let i = 0; i < Nk; i += 4) {\n for (let j = 0; j < 4; j++)\n xk[i + j] = encKey[Nk - i - 4 + j];\n }\n encKey.fill(0);\n // apply InvMixColumn except first & last round\n for (let i = 4; i < Nk - 4; i++) {\n const x = xk[i];\n const w = applySbox(sbox2, x, x, x, x);\n xk[i] = T0[w & 0xff] ^ T1[(w >>> 8) & 0xff] ^ T2[(w >>> 16) & 0xff] ^ T3[w >>> 24];\n }\n return xk;\n}\n// Apply tables\nfunction apply0123(T01, T23, s0, s1, s2, s3) {\n return (T01[((s0 << 8) & 0xff00) | ((s1 >>> 8) & 0xff)] ^\n T23[((s2 >>> 8) & 0xff00) | ((s3 >>> 24) & 0xff)]);\n}\nfunction applySbox(sbox2, s0, s1, s2, s3) {\n return (sbox2[(s0 & 0xff) | (s1 & 0xff00)] |\n (sbox2[((s2 >>> 16) & 0xff) | ((s3 >>> 16) & 0xff00)] << 16));\n}\nfunction encrypt(xk, s0, s1, s2, s3) {\n const { sbox2, T01, T23 } = tableEncoding;\n let k = 0;\n (s0 ^= xk[k++]), (s1 ^= xk[k++]), (s2 ^= xk[k++]), (s3 ^= xk[k++]);\n const rounds = xk.length / 4 - 2;\n for (let i = 0; i < rounds; i++) {\n const t0 = xk[k++] ^ apply0123(T01, T23, s0, s1, s2, s3);\n const t1 = xk[k++] ^ apply0123(T01, T23, s1, s2, s3, s0);\n const t2 = xk[k++] ^ apply0123(T01, T23, s2, s3, s0, s1);\n const t3 = xk[k++] ^ apply0123(T01, T23, s3, s0, s1, s2);\n (s0 = t0), (s1 = t1), (s2 = t2), (s3 = t3);\n }\n // last round (without mixcolumns, so using SBOX2 table)\n const t0 = xk[k++] ^ applySbox(sbox2, s0, s1, s2, s3);\n const t1 = xk[k++] ^ applySbox(sbox2, s1, s2, s3, s0);\n const t2 = xk[k++] ^ applySbox(sbox2, s2, s3, s0, s1);\n const t3 = xk[k++] ^ applySbox(sbox2, s3, s0, s1, s2);\n return { s0: t0, s1: t1, s2: t2, s3: t3 };\n}\nfunction decrypt(xk, s0, s1, s2, s3) {\n const { sbox2, T01, T23 } = tableDecoding;\n let k = 0;\n (s0 ^= xk[k++]), (s1 ^= xk[k++]), (s2 ^= xk[k++]), (s3 ^= xk[k++]);\n const rounds = xk.length / 4 - 2;\n for (let i = 0; i < rounds; i++) {\n const t0 = xk[k++] ^ apply0123(T01, T23, s0, s3, s2, s1);\n const t1 = xk[k++] ^ apply0123(T01, T23, s1, s0, s3, s2);\n const t2 = xk[k++] ^ apply0123(T01, T23, s2, s1, s0, s3);\n const t3 = xk[k++] ^ apply0123(T01, T23, s3, s2, s1, s0);\n (s0 = t0), (s1 = t1), (s2 = t2), (s3 = t3);\n }\n // Last round\n const t0 = xk[k++] ^ applySbox(sbox2, s0, s3, s2, s1);\n const t1 = xk[k++] ^ applySbox(sbox2, s1, s0, s3, s2);\n const t2 = xk[k++] ^ applySbox(sbox2, s2, s1, s0, s3);\n const t3 = xk[k++] ^ applySbox(sbox2, s3, s2, s1, s0);\n return { s0: t0, s1: t1, s2: t2, s3: t3 };\n}\nfunction getDst(len, dst) {\n if (!dst)\n return new Uint8Array(len);\n abytes(dst);\n if (dst.length < len)\n throw new Error(`aes: wrong destination length, expected at least ${len}, got: ${dst.length}`);\n return dst;\n}\n// TODO: investigate merging with ctr32\nfunction ctrCounter(xk, nonce, src, dst) {\n abytes(nonce, BLOCK_SIZE);\n abytes(src);\n const srcLen = src.length;\n dst = getDst(srcLen, dst);\n const ctr = nonce;\n const c32 = u32(ctr);\n // Fill block (empty, ctr=0)\n let { s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]);\n const src32 = u32(src);\n const dst32 = u32(dst);\n // process blocks\n for (let i = 0; i + 4 <= src32.length; i += 4) {\n dst32[i + 0] = src32[i + 0] ^ s0;\n dst32[i + 1] = src32[i + 1] ^ s1;\n dst32[i + 2] = src32[i + 2] ^ s2;\n dst32[i + 3] = src32[i + 3] ^ s3;\n // Full 128 bit counter with wrap around\n let carry = 1;\n for (let i = ctr.length - 1; i >= 0; i--) {\n carry = (carry + (ctr[i] & 0xff)) | 0;\n ctr[i] = carry & 0xff;\n carry >>>= 8;\n }\n ({ s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]));\n }\n // leftovers (less than block)\n // It's possible to handle > u32 fast, but is it worth it?\n const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32);\n if (start < srcLen) {\n const b32 = new Uint32Array([s0, s1, s2, s3]);\n const buf = u8(b32);\n for (let i = start, pos = 0; i < srcLen; i++, pos++)\n dst[i] = src[i] ^ buf[pos];\n }\n return dst;\n}\n// AES CTR with overflowing 32 bit counter\n// It's possible to do 32le significantly simpler (and probably faster) by using u32.\n// But, we need both, and perf bottleneck is in ghash anyway.\nfunction ctr32(xk, isLE, nonce, src, dst) {\n abytes(nonce, BLOCK_SIZE);\n abytes(src);\n dst = getDst(src.length, dst);\n const ctr = nonce; // write new value to nonce, so it can be re-used\n const c32 = u32(ctr);\n const view = createView(ctr);\n const src32 = u32(src);\n const dst32 = u32(dst);\n const ctrPos = isLE ? 0 : 12;\n const srcLen = src.length;\n // Fill block (empty, ctr=0)\n let ctrNum = view.getUint32(ctrPos, isLE); // read current counter value\n let { s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]);\n // process blocks\n for (let i = 0; i + 4 <= src32.length; i += 4) {\n dst32[i + 0] = src32[i + 0] ^ s0;\n dst32[i + 1] = src32[i + 1] ^ s1;\n dst32[i + 2] = src32[i + 2] ^ s2;\n dst32[i + 3] = src32[i + 3] ^ s3;\n ctrNum = (ctrNum + 1) >>> 0; // u32 wrap\n view.setUint32(ctrPos, ctrNum, isLE);\n ({ s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]));\n }\n // leftovers (less than a block)\n const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32);\n if (start < srcLen) {\n const b32 = new Uint32Array([s0, s1, s2, s3]);\n const buf = u8(b32);\n for (let i = start, pos = 0; i < srcLen; i++, pos++)\n dst[i] = src[i] ^ buf[pos];\n }\n return dst;\n}\n/**\n * CTR: counter mode. Creates stream cipher.\n * Requires good IV. Parallelizable. OK, but no MAC.\n */\nexport const ctr = wrapCipher({ blockSize: 16, nonceLength: 16 }, function ctr(key, nonce) {\n abytes(key);\n abytes(nonce, BLOCK_SIZE);\n function processCtr(buf, dst) {\n const xk = expandKeyLE(key);\n const n = nonce.slice();\n const out = ctrCounter(xk, n, buf, dst);\n xk.fill(0);\n n.fill(0);\n return out;\n }\n return {\n encrypt: (plaintext, dst) => processCtr(plaintext, dst),\n decrypt: (ciphertext, dst) => processCtr(ciphertext, dst),\n };\n});\nfunction validateBlockDecrypt(data) {\n abytes(data);\n if (data.length % BLOCK_SIZE !== 0) {\n throw new Error(`aes/(cbc-ecb).decrypt ciphertext should consist of blocks with size ${BLOCK_SIZE}`);\n }\n}\nfunction validateBlockEncrypt(plaintext, pcks5, dst) {\n let outLen = plaintext.length;\n const remaining = outLen % BLOCK_SIZE;\n if (!pcks5 && remaining !== 0)\n throw new Error('aec/(cbc-ecb): unpadded plaintext with disabled padding');\n const b = u32(plaintext);\n if (pcks5) {\n let left = BLOCK_SIZE - remaining;\n if (!left)\n left = BLOCK_SIZE; // if no bytes left, create empty padding block\n outLen = outLen + left;\n }\n const out = getDst(outLen, dst);\n const o = u32(out);\n return { b, o, out };\n}\nfunction validatePCKS(data, pcks5) {\n if (!pcks5)\n return data;\n const len = data.length;\n if (!len)\n throw new Error(`aes/pcks5: empty ciphertext not allowed`);\n const lastByte = data[len - 1];\n if (lastByte <= 0 || lastByte > 16)\n throw new Error(`aes/pcks5: wrong padding byte: ${lastByte}`);\n const out = data.subarray(0, -lastByte);\n for (let i = 0; i < lastByte; i++)\n if (data[len - i - 1] !== lastByte)\n throw new Error(`aes/pcks5: wrong padding`);\n return out;\n}\nfunction padPCKS(left) {\n const tmp = new Uint8Array(16);\n const tmp32 = u32(tmp);\n tmp.set(left);\n const paddingByte = BLOCK_SIZE - left.length;\n for (let i = BLOCK_SIZE - paddingByte; i < BLOCK_SIZE; i++)\n tmp[i] = paddingByte;\n return tmp32;\n}\n/**\n * ECB: Electronic CodeBook. Simple deterministic replacement.\n * Dangerous: always map x to y. See [AES Penguin](https://words.filippo.io/the-ecb-penguin/).\n */\nexport const ecb = wrapCipher({ blockSize: 16 }, function ecb(key, opts = {}) {\n abytes(key);\n const pcks5 = !opts.disablePadding;\n return {\n encrypt: (plaintext, dst) => {\n abytes(plaintext);\n const { b, o, out: _out } = validateBlockEncrypt(plaintext, pcks5, dst);\n const xk = expandKeyLE(key);\n let i = 0;\n for (; i + 4 <= b.length;) {\n const { s0, s1, s2, s3 } = encrypt(xk, b[i + 0], b[i + 1], b[i + 2], b[i + 3]);\n (o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3);\n }\n if (pcks5) {\n const tmp32 = padPCKS(plaintext.subarray(i * 4));\n const { s0, s1, s2, s3 } = encrypt(xk, tmp32[0], tmp32[1], tmp32[2], tmp32[3]);\n (o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3);\n }\n xk.fill(0);\n return _out;\n },\n decrypt: (ciphertext, dst) => {\n validateBlockDecrypt(ciphertext);\n const xk = expandKeyDecLE(key);\n const out = getDst(ciphertext.length, dst);\n const b = u32(ciphertext);\n const o = u32(out);\n for (let i = 0; i + 4 <= b.length;) {\n const { s0, s1, s2, s3 } = decrypt(xk, b[i + 0], b[i + 1], b[i + 2], b[i + 3]);\n (o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3);\n }\n xk.fill(0);\n return validatePCKS(out, pcks5);\n },\n };\n});\n/**\n * CBC: Cipher-Block-Chaining. Key is previous round’s block.\n * Fragile: needs proper padding. Unauthenticated: needs MAC.\n */\nexport const cbc = wrapCipher({ blockSize: 16, nonceLength: 16 }, function cbc(key, iv, opts = {}) {\n abytes(key);\n abytes(iv, 16);\n const pcks5 = !opts.disablePadding;\n return {\n encrypt: (plaintext, dst) => {\n const xk = expandKeyLE(key);\n const { b, o, out: _out } = validateBlockEncrypt(plaintext, pcks5, dst);\n const n32 = u32(iv);\n // prettier-ignore\n let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3];\n let i = 0;\n for (; i + 4 <= b.length;) {\n (s0 ^= b[i + 0]), (s1 ^= b[i + 1]), (s2 ^= b[i + 2]), (s3 ^= b[i + 3]);\n ({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3));\n (o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3);\n }\n if (pcks5) {\n const tmp32 = padPCKS(plaintext.subarray(i * 4));\n (s0 ^= tmp32[0]), (s1 ^= tmp32[1]), (s2 ^= tmp32[2]), (s3 ^= tmp32[3]);\n ({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3));\n (o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3);\n }\n xk.fill(0);\n return _out;\n },\n decrypt: (ciphertext, dst) => {\n validateBlockDecrypt(ciphertext);\n const xk = expandKeyDecLE(key);\n const n32 = u32(iv);\n const out = getDst(ciphertext.length, dst);\n const b = u32(ciphertext);\n const o = u32(out);\n // prettier-ignore\n let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3];\n for (let i = 0; i + 4 <= b.length;) {\n // prettier-ignore\n const ps0 = s0, ps1 = s1, ps2 = s2, ps3 = s3;\n (s0 = b[i + 0]), (s1 = b[i + 1]), (s2 = b[i + 2]), (s3 = b[i + 3]);\n const { s0: o0, s1: o1, s2: o2, s3: o3 } = decrypt(xk, s0, s1, s2, s3);\n (o[i++] = o0 ^ ps0), (o[i++] = o1 ^ ps1), (o[i++] = o2 ^ ps2), (o[i++] = o3 ^ ps3);\n }\n xk.fill(0);\n return validatePCKS(out, pcks5);\n },\n };\n});\n/**\n * CFB: Cipher Feedback Mode. The input for the block cipher is the previous cipher output.\n * Unauthenticated: needs MAC.\n */\nexport const cfb = wrapCipher({ blockSize: 16, nonceLength: 16 }, function cfb(key, iv) {\n abytes(key);\n abytes(iv, 16);\n function processCfb(src, isEncrypt, dst) {\n const xk = expandKeyLE(key);\n const srcLen = src.length;\n dst = getDst(srcLen, dst);\n const src32 = u32(src);\n const dst32 = u32(dst);\n const next32 = isEncrypt ? dst32 : src32;\n const n32 = u32(iv);\n // prettier-ignore\n let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3];\n for (let i = 0; i + 4 <= src32.length;) {\n const { s0: e0, s1: e1, s2: e2, s3: e3 } = encrypt(xk, s0, s1, s2, s3);\n dst32[i + 0] = src32[i + 0] ^ e0;\n dst32[i + 1] = src32[i + 1] ^ e1;\n dst32[i + 2] = src32[i + 2] ^ e2;\n dst32[i + 3] = src32[i + 3] ^ e3;\n (s0 = next32[i++]), (s1 = next32[i++]), (s2 = next32[i++]), (s3 = next32[i++]);\n }\n // leftovers (less than block)\n const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32);\n if (start < srcLen) {\n ({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3));\n const buf = u8(new Uint32Array([s0, s1, s2, s3]));\n for (let i = start, pos = 0; i < srcLen; i++, pos++)\n dst[i] = src[i] ^ buf[pos];\n buf.fill(0);\n }\n xk.fill(0);\n return dst;\n }\n return {\n encrypt: (plaintext, dst) => processCfb(plaintext, true, dst),\n decrypt: (ciphertext, dst) => processCfb(ciphertext, false, dst),\n };\n});\n// TODO: merge with chacha, however gcm has bitLen while chacha has byteLen\nfunction computeTag(fn, isLE, key, data, AAD) {\n const h = fn.create(key, data.length + (AAD?.length || 0));\n if (AAD)\n h.update(AAD);\n h.update(data);\n const num = new Uint8Array(16);\n const view = createView(num);\n if (AAD)\n setBigUint64(view, 0, BigInt(AAD.length * 8), isLE);\n setBigUint64(view, 8, BigInt(data.length * 8), isLE);\n h.update(num);\n return h.digest();\n}\n/**\n * GCM: Galois/Counter Mode.\n * Good, modern version of CTR, parallel, with MAC.\n * Be careful: MACs can be forged.\n */\nexport const gcm = wrapCipher({ blockSize: 16, nonceLength: 12, tagLength: 16 }, function gcm(key, nonce, AAD) {\n abytes(nonce);\n // Nonce can be pretty much anything (even 1 byte). But smaller nonces less secure.\n if (nonce.length === 0)\n throw new Error('aes/gcm: empty nonce');\n const tagLength = 16;\n function _computeTag(authKey, tagMask, data) {\n const tag = computeTag(ghash, false, authKey, data, AAD);\n for (let i = 0; i < tagMask.length; i++)\n tag[i] ^= tagMask[i];\n return tag;\n }\n function deriveKeys() {\n const xk = expandKeyLE(key);\n const authKey = EMPTY_BLOCK.slice();\n const counter = EMPTY_BLOCK.slice();\n ctr32(xk, false, counter, counter, authKey);\n if (nonce.length === 12) {\n counter.set(nonce);\n }\n else {\n // Spec (NIST 800-38d) supports variable size nonce.\n // Not supported for now, but can be useful.\n const nonceLen = EMPTY_BLOCK.slice();\n const view = createView(nonceLen);\n setBigUint64(view, 8, BigInt(nonce.length * 8), false);\n // ghash(nonce || u64be(0) || u64be(nonceLen*8))\n ghash.create(authKey).update(nonce).update(nonceLen).digestInto(counter);\n }\n const tagMask = ctr32(xk, false, counter, EMPTY_BLOCK);\n return { xk, authKey, counter, tagMask };\n }\n return {\n encrypt: (plaintext) => {\n abytes(plaintext);\n const { xk, authKey, counter, tagMask } = deriveKeys();\n const out = new Uint8Array(plaintext.length + tagLength);\n ctr32(xk, false, counter, plaintext, out);\n const tag = _computeTag(authKey, tagMask, out.subarray(0, out.length - tagLength));\n out.set(tag, plaintext.length);\n xk.fill(0);\n return out;\n },\n decrypt: (ciphertext) => {\n abytes(ciphertext);\n if (ciphertext.length < tagLength)\n throw new Error(`aes/gcm: ciphertext less than tagLen (${tagLength})`);\n const { xk, authKey, counter, tagMask } = deriveKeys();\n const data = ciphertext.subarray(0, -tagLength);\n const passedTag = ciphertext.subarray(-tagLength);\n const tag = _computeTag(authKey, tagMask, data);\n if (!equalBytes(tag, passedTag))\n throw new Error('aes/gcm: invalid ghash tag');\n const out = ctr32(xk, false, counter, data);\n authKey.fill(0);\n tagMask.fill(0);\n xk.fill(0);\n return out;\n },\n };\n});\nconst limit = (name, min, max) => (value) => {\n if (!Number.isSafeInteger(value) || min > value || value > max)\n throw new Error(`${name}: invalid value=${value}, must be [${min}..${max}]`);\n};\n/**\n * AES-GCM-SIV: classic AES-GCM with nonce-misuse resistance.\n * Guarantees that, when a nonce is repeated, the only security loss is that identical\n * plaintexts will produce identical ciphertexts.\n * RFC 8452, https://datatracker.ietf.org/doc/html/rfc8452\n */\nexport const siv = wrapCipher({ blockSize: 16, nonceLength: 12, tagLength: 16 }, function siv(key, nonce, AAD) {\n const tagLength = 16;\n // From RFC 8452: Section 6\n const AAD_LIMIT = limit('AAD', 0, 2 ** 36);\n const PLAIN_LIMIT = limit('plaintext', 0, 2 ** 36);\n const NONCE_LIMIT = limit('nonce', 12, 12);\n const CIPHER_LIMIT = limit('ciphertext', 16, 2 ** 36 + 16);\n abytes(nonce);\n NONCE_LIMIT(nonce.length);\n if (AAD) {\n abytes(AAD);\n AAD_LIMIT(AAD.length);\n }\n function deriveKeys() {\n const len = key.length;\n if (len !== 16 && len !== 24 && len !== 32)\n throw new Error(`key length must be 16, 24 or 32 bytes, got: ${len} bytes`);\n const xk = expandKeyLE(key);\n const encKey = new Uint8Array(len);\n const authKey = new Uint8Array(16);\n const n32 = u32(nonce);\n // prettier-ignore\n let s0 = 0, s1 = n32[0], s2 = n32[1], s3 = n32[2];\n let counter = 0;\n for (const derivedKey of [authKey, encKey].map(u32)) {\n const d32 = u32(derivedKey);\n for (let i = 0; i < d32.length; i += 2) {\n // aes(u32le(0) || nonce)[:8] || aes(u32le(1) || nonce)[:8] ...\n const { s0: o0, s1: o1 } = encrypt(xk, s0, s1, s2, s3);\n d32[i + 0] = o0;\n d32[i + 1] = o1;\n s0 = ++counter; // increment counter inside state\n }\n }\n xk.fill(0);\n return { authKey, encKey: expandKeyLE(encKey) };\n }\n function _computeTag(encKey, authKey, data) {\n const tag = computeTag(polyval, true, authKey, data, AAD);\n // Compute the expected tag by XORing S_s and the nonce, clearing the\n // most significant bit of the last byte and encrypting with the\n // message-encryption key.\n for (let i = 0; i < 12; i++)\n tag[i] ^= nonce[i];\n tag[15] &= 0x7f; // Clear the highest bit\n // encrypt tag as block\n const t32 = u32(tag);\n // prettier-ignore\n let s0 = t32[0], s1 = t32[1], s2 = t32[2], s3 = t32[3];\n ({ s0, s1, s2, s3 } = encrypt(encKey, s0, s1, s2, s3));\n (t32[0] = s0), (t32[1] = s1), (t32[2] = s2), (t32[3] = s3);\n return tag;\n }\n // actual decrypt/encrypt of message.\n function processSiv(encKey, tag, input) {\n let block = tag.slice();\n block[15] |= 0x80; // Force highest bit\n return ctr32(encKey, true, block, input);\n }\n return {\n encrypt: (plaintext) => {\n abytes(plaintext);\n PLAIN_LIMIT(plaintext.length);\n const { encKey, authKey } = deriveKeys();\n const tag = _computeTag(encKey, authKey, plaintext);\n const out = new Uint8Array(plaintext.length + tagLength);\n out.set(tag, plaintext.length);\n out.set(processSiv(encKey, tag, plaintext));\n encKey.fill(0);\n authKey.fill(0);\n return out;\n },\n decrypt: (ciphertext) => {\n abytes(ciphertext);\n CIPHER_LIMIT(ciphertext.length);\n const tag = ciphertext.subarray(-tagLength);\n const { encKey, authKey } = deriveKeys();\n const plaintext = processSiv(encKey, tag, ciphertext.subarray(0, -tagLength));\n const expectedTag = _computeTag(encKey, authKey, plaintext);\n encKey.fill(0);\n authKey.fill(0);\n if (!equalBytes(tag, expectedTag))\n throw new Error('invalid polyval tag');\n return plaintext;\n },\n };\n});\nfunction isBytes32(a) {\n return (a != null &&\n typeof a === 'object' &&\n (a instanceof Uint32Array || a.constructor.name === 'Uint32Array'));\n}\nfunction encryptBlock(xk, block) {\n abytes(block, 16);\n if (!isBytes32(xk))\n throw new Error('_encryptBlock accepts result of expandKeyLE');\n const b32 = u32(block);\n let { s0, s1, s2, s3 } = encrypt(xk, b32[0], b32[1], b32[2], b32[3]);\n (b32[0] = s0), (b32[1] = s1), (b32[2] = s2), (b32[3] = s3);\n return block;\n}\nfunction decryptBlock(xk, block) {\n abytes(block, 16);\n if (!isBytes32(xk))\n throw new Error('_decryptBlock accepts result of expandKeyLE');\n const b32 = u32(block);\n let { s0, s1, s2, s3 } = decrypt(xk, b32[0], b32[1], b32[2], b32[3]);\n (b32[0] = s0), (b32[1] = s1), (b32[2] = s2), (b32[3] = s3);\n return block;\n}\n// Highly unsafe private functions for implementing new modes or ciphers based on AES\n// Can change at any time, no API guarantees\nexport const unsafe = {\n expandKeyLE,\n expandKeyDecLE,\n encrypt,\n decrypt,\n encryptBlock,\n decryptBlock,\n ctrCounter,\n ctr32,\n};\n//# sourceMappingURL=aes.js.map","// Basic utils for ARX (add-rotate-xor) salsa and chacha ciphers.\nimport { number as anumber, bytes as abytes, bool as abool } from './_assert.js';\nimport { checkOpts, u32 } from './utils.js';\n/*\nRFC8439 requires multi-step cipher stream, where\nauthKey starts with counter: 0, actual msg with counter: 1.\n\nFor this, we need a way to re-use nonce / counter:\n\n const counter = new Uint8Array(4);\n chacha(..., counter, ...); // counter is now 1\n chacha(..., counter, ...); // counter is now 2\n\nThis is complicated:\n\n- 32-bit counters are enough, no need for 64-bit: max ArrayBuffer size in JS is 4GB\n- Original papers don't allow mutating counters\n- Counter overflow is undefined [^1]\n- Idea A: allow providing (nonce | counter) instead of just nonce, re-use it\n- Caveat: Cannot be re-used through all cases:\n- * chacha has (counter | nonce)\n- * xchacha has (nonce16 | counter | nonce16)\n- Idea B: separate nonce / counter and provide separate API for counter re-use\n- Caveat: there are different counter sizes depending on an algorithm.\n- salsa & chacha also differ in structures of key & sigma:\n salsa20: s[0] | k(4) | s[1] | nonce(2) | ctr(2) | s[2] | k(4) | s[3]\n chacha: s(4) | k(8) | ctr(1) | nonce(3)\n chacha20orig: s(4) | k(8) | ctr(2) | nonce(2)\n- Idea C: helper method such as `setSalsaState(key, nonce, sigma, data)`\n- Caveat: we can't re-use counter array\n\nxchacha [^2] uses the subkey and remaining 8 byte nonce with ChaCha20 as normal\n(prefixed by 4 NUL bytes, since [RFC8439] specifies a 12-byte nonce).\n\n[^1]: https://mailarchive.ietf.org/arch/msg/cfrg/gsOnTJzcbgG6OqD8Sc0GO5aR_tU/\n[^2]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha#appendix-A.2\n*/\n// We can't make top-level var depend on utils.utf8ToBytes\n// because it's not present in all envs. Creating a similar fn here\nconst _utf8ToBytes = (str) => Uint8Array.from(str.split('').map((c) => c.charCodeAt(0)));\nconst sigma16 = _utf8ToBytes('expand 16-byte k');\nconst sigma32 = _utf8ToBytes('expand 32-byte k');\nconst sigma16_32 = u32(sigma16);\nconst sigma32_32 = u32(sigma32);\nexport const sigma = sigma32_32.slice();\nexport function rotl(a, b) {\n return (a << b) | (a >>> (32 - b));\n}\n// Is byte array aligned to 4 byte offset (u32)?\nfunction isAligned32(b) {\n return b.byteOffset % 4 === 0;\n}\n// Salsa and Chacha block length is always 512-bit\nconst BLOCK_LEN = 64;\nconst BLOCK_LEN32 = 16;\n// new Uint32Array([2**32]) // => Uint32Array(1) [ 0 ]\n// new Uint32Array([2**32-1]) // => Uint32Array(1) [ 4294967295 ]\nconst MAX_COUNTER = 2 ** 32 - 1;\nconst U32_EMPTY = new Uint32Array();\nfunction runCipher(core, sigma, key, nonce, data, output, counter, rounds) {\n const len = data.length;\n const block = new Uint8Array(BLOCK_LEN);\n const b32 = u32(block);\n // Make sure that buffers aligned to 4 bytes\n const isAligned = isAligned32(data) && isAligned32(output);\n const d32 = isAligned ? u32(data) : U32_EMPTY;\n const o32 = isAligned ? u32(output) : U32_EMPTY;\n for (let pos = 0; pos < len; counter++) {\n core(sigma, key, nonce, b32, counter, rounds);\n if (counter >= MAX_COUNTER)\n throw new Error('arx: counter overflow');\n const take = Math.min(BLOCK_LEN, len - pos);\n // aligned to 4 bytes\n if (isAligned && take === BLOCK_LEN) {\n const pos32 = pos / 4;\n if (pos % 4 !== 0)\n throw new Error('arx: invalid block position');\n for (let j = 0, posj; j < BLOCK_LEN32; j++) {\n posj = pos32 + j;\n o32[posj] = d32[posj] ^ b32[j];\n }\n pos += BLOCK_LEN;\n continue;\n }\n for (let j = 0, posj; j < take; j++) {\n posj = pos + j;\n output[posj] = data[posj] ^ block[j];\n }\n pos += take;\n }\n}\nexport function createCipher(core, opts) {\n const { allowShortKeys, extendNonceFn, counterLength, counterRight, rounds } = checkOpts({ allowShortKeys: false, counterLength: 8, counterRight: false, rounds: 20 }, opts);\n if (typeof core !== 'function')\n throw new Error('core must be a function');\n anumber(counterLength);\n anumber(rounds);\n abool(counterRight);\n abool(allowShortKeys);\n return (key, nonce, data, output, counter = 0) => {\n abytes(key);\n abytes(nonce);\n abytes(data);\n const len = data.length;\n if (!output)\n output = new Uint8Array(len);\n abytes(output);\n anumber(counter);\n if (counter < 0 || counter >= MAX_COUNTER)\n throw new Error('arx: counter overflow');\n if (output.length < len)\n throw new Error(`arx: output (${output.length}) is shorter than data (${len})`);\n const toClean = [];\n // Key & sigma\n // key=16 -> sigma16, k=key|key\n // key=32 -> sigma32, k=key\n let l = key.length, k, sigma;\n if (l === 32) {\n k = key.slice();\n toClean.push(k);\n sigma = sigma32_32;\n }\n else if (l === 16 && allowShortKeys) {\n k = new Uint8Array(32);\n k.set(key);\n k.set(key, 16);\n sigma = sigma16_32;\n toClean.push(k);\n }\n else {\n throw new Error(`arx: invalid 32-byte key, got length=${l}`);\n }\n // Nonce\n // salsa20: 8 (8-byte counter)\n // chacha20orig: 8 (8-byte counter)\n // chacha20: 12 (4-byte counter)\n // xsalsa20: 24 (16 -> hsalsa, 8 -> old nonce)\n // xchacha20: 24 (16 -> hchacha, 8 -> old nonce)\n // Align nonce to 4 bytes\n if (!isAligned32(nonce)) {\n nonce = nonce.slice();\n toClean.push(nonce);\n }\n const k32 = u32(k);\n // hsalsa & hchacha: handle extended nonce\n if (extendNonceFn) {\n if (nonce.length !== 24)\n throw new Error(`arx: extended nonce must be 24 bytes`);\n extendNonceFn(sigma, k32, u32(nonce.subarray(0, 16)), k32);\n nonce = nonce.subarray(16);\n }\n // Handle nonce counter\n const nonceNcLen = 16 - counterLength;\n if (nonceNcLen !== nonce.length)\n throw new Error(`arx: nonce must be ${nonceNcLen} or 16 bytes`);\n // Pad counter when nonce is 64 bit\n if (nonceNcLen !== 12) {\n const nc = new Uint8Array(12);\n nc.set(nonce, counterRight ? 0 : 12 - nonce.length);\n nonce = nc;\n toClean.push(nonce);\n }\n const n32 = u32(nonce);\n runCipher(core, sigma, k32, n32, data, output, counter, rounds);\n while (toClean.length > 0)\n toClean.pop().fill(0);\n return output;\n };\n}\n//# sourceMappingURL=_arx.js.map","// prettier-ignore\nimport { wrapCipher, createView, equalBytes, setBigUint64, } from './utils.js';\nimport { poly1305 } from './_poly1305.js';\nimport { createCipher, rotl } from './_arx.js';\nimport { bytes as abytes } from './_assert.js';\n// ChaCha20 stream cipher was released in 2008. ChaCha aims to increase\n// the diffusion per round, but had slightly less cryptanalysis.\n// https://cr.yp.to/chacha.html, http://cr.yp.to/chacha/chacha-20080128.pdf\n/**\n * ChaCha core function.\n */\n// prettier-ignore\nfunction chachaCore(s, k, n, out, cnt, rounds = 20) {\n let y00 = s[0], y01 = s[1], y02 = s[2], y03 = s[3], // \"expa\" \"nd 3\" \"2-by\" \"te k\"\n y04 = k[0], y05 = k[1], y06 = k[2], y07 = k[3], // Key Key Key Key\n y08 = k[4], y09 = k[5], y10 = k[6], y11 = k[7], // Key Key Key Key\n y12 = cnt, y13 = n[0], y14 = n[1], y15 = n[2]; // Counter Counter\tNonce Nonce\n // Save state to temporary variables\n let x00 = y00, x01 = y01, x02 = y02, x03 = y03, x04 = y04, x05 = y05, x06 = y06, x07 = y07, x08 = y08, x09 = y09, x10 = y10, x11 = y11, x12 = y12, x13 = y13, x14 = y14, x15 = y15;\n for (let r = 0; r < rounds; r += 2) {\n x00 = (x00 + x04) | 0;\n x12 = rotl(x12 ^ x00, 16);\n x08 = (x08 + x12) | 0;\n x04 = rotl(x04 ^ x08, 12);\n x00 = (x00 + x04) | 0;\n x12 = rotl(x12 ^ x00, 8);\n x08 = (x08 + x12) | 0;\n x04 = rotl(x04 ^ x08, 7);\n x01 = (x01 + x05) | 0;\n x13 = rotl(x13 ^ x01, 16);\n x09 = (x09 + x13) | 0;\n x05 = rotl(x05 ^ x09, 12);\n x01 = (x01 + x05) | 0;\n x13 = rotl(x13 ^ x01, 8);\n x09 = (x09 + x13) | 0;\n x05 = rotl(x05 ^ x09, 7);\n x02 = (x02 + x06) | 0;\n x14 = rotl(x14 ^ x02, 16);\n x10 = (x10 + x14) | 0;\n x06 = rotl(x06 ^ x10, 12);\n x02 = (x02 + x06) | 0;\n x14 = rotl(x14 ^ x02, 8);\n x10 = (x10 + x14) | 0;\n x06 = rotl(x06 ^ x10, 7);\n x03 = (x03 + x07) | 0;\n x15 = rotl(x15 ^ x03, 16);\n x11 = (x11 + x15) | 0;\n x07 = rotl(x07 ^ x11, 12);\n x03 = (x03 + x07) | 0;\n x15 = rotl(x15 ^ x03, 8);\n x11 = (x11 + x15) | 0;\n x07 = rotl(x07 ^ x11, 7);\n x00 = (x00 + x05) | 0;\n x15 = rotl(x15 ^ x00, 16);\n x10 = (x10 + x15) | 0;\n x05 = rotl(x05 ^ x10, 12);\n x00 = (x00 + x05) | 0;\n x15 = rotl(x15 ^ x00, 8);\n x10 = (x10 + x15) | 0;\n x05 = rotl(x05 ^ x10, 7);\n x01 = (x01 + x06) | 0;\n x12 = rotl(x12 ^ x01, 16);\n x11 = (x11 + x12) | 0;\n x06 = rotl(x06 ^ x11, 12);\n x01 = (x01 + x06) | 0;\n x12 = rotl(x12 ^ x01, 8);\n x11 = (x11 + x12) | 0;\n x06 = rotl(x06 ^ x11, 7);\n x02 = (x02 + x07) | 0;\n x13 = rotl(x13 ^ x02, 16);\n x08 = (x08 + x13) | 0;\n x07 = rotl(x07 ^ x08, 12);\n x02 = (x02 + x07) | 0;\n x13 = rotl(x13 ^ x02, 8);\n x08 = (x08 + x13) | 0;\n x07 = rotl(x07 ^ x08, 7);\n x03 = (x03 + x04) | 0;\n x14 = rotl(x14 ^ x03, 16);\n x09 = (x09 + x14) | 0;\n x04 = rotl(x04 ^ x09, 12);\n x03 = (x03 + x04) | 0;\n x14 = rotl(x14 ^ x03, 8);\n x09 = (x09 + x14) | 0;\n x04 = rotl(x04 ^ x09, 7);\n }\n // Write output\n let oi = 0;\n out[oi++] = (y00 + x00) | 0;\n out[oi++] = (y01 + x01) | 0;\n out[oi++] = (y02 + x02) | 0;\n out[oi++] = (y03 + x03) | 0;\n out[oi++] = (y04 + x04) | 0;\n out[oi++] = (y05 + x05) | 0;\n out[oi++] = (y06 + x06) | 0;\n out[oi++] = (y07 + x07) | 0;\n out[oi++] = (y08 + x08) | 0;\n out[oi++] = (y09 + x09) | 0;\n out[oi++] = (y10 + x10) | 0;\n out[oi++] = (y11 + x11) | 0;\n out[oi++] = (y12 + x12) | 0;\n out[oi++] = (y13 + x13) | 0;\n out[oi++] = (y14 + x14) | 0;\n out[oi++] = (y15 + x15) | 0;\n}\n/**\n * hchacha helper method, used primarily in xchacha, to hash\n * key and nonce into key' and nonce'.\n * Same as chachaCore, but there doesn't seem to be a way to move the block\n * out without 25% performance hit.\n */\n// prettier-ignore\nexport function hchacha(s, k, i, o32) {\n let x00 = s[0], x01 = s[1], x02 = s[2], x03 = s[3], x04 = k[0], x05 = k[1], x06 = k[2], x07 = k[3], x08 = k[4], x09 = k[5], x10 = k[6], x11 = k[7], x12 = i[0], x13 = i[1], x14 = i[2], x15 = i[3];\n for (let r = 0; r < 20; r += 2) {\n x00 = (x00 + x04) | 0;\n x12 = rotl(x12 ^ x00, 16);\n x08 = (x08 + x12) | 0;\n x04 = rotl(x04 ^ x08, 12);\n x00 = (x00 + x04) | 0;\n x12 = rotl(x12 ^ x00, 8);\n x08 = (x08 + x12) | 0;\n x04 = rotl(x04 ^ x08, 7);\n x01 = (x01 + x05) | 0;\n x13 = rotl(x13 ^ x01, 16);\n x09 = (x09 + x13) | 0;\n x05 = rotl(x05 ^ x09, 12);\n x01 = (x01 + x05) | 0;\n x13 = rotl(x13 ^ x01, 8);\n x09 = (x09 + x13) | 0;\n x05 = rotl(x05 ^ x09, 7);\n x02 = (x02 + x06) | 0;\n x14 = rotl(x14 ^ x02, 16);\n x10 = (x10 + x14) | 0;\n x06 = rotl(x06 ^ x10, 12);\n x02 = (x02 + x06) | 0;\n x14 = rotl(x14 ^ x02, 8);\n x10 = (x10 + x14) | 0;\n x06 = rotl(x06 ^ x10, 7);\n x03 = (x03 + x07) | 0;\n x15 = rotl(x15 ^ x03, 16);\n x11 = (x11 + x15) | 0;\n x07 = rotl(x07 ^ x11, 12);\n x03 = (x03 + x07) | 0;\n x15 = rotl(x15 ^ x03, 8);\n x11 = (x11 + x15) | 0;\n x07 = rotl(x07 ^ x11, 7);\n x00 = (x00 + x05) | 0;\n x15 = rotl(x15 ^ x00, 16);\n x10 = (x10 + x15) | 0;\n x05 = rotl(x05 ^ x10, 12);\n x00 = (x00 + x05) | 0;\n x15 = rotl(x15 ^ x00, 8);\n x10 = (x10 + x15) | 0;\n x05 = rotl(x05 ^ x10, 7);\n x01 = (x01 + x06) | 0;\n x12 = rotl(x12 ^ x01, 16);\n x11 = (x11 + x12) | 0;\n x06 = rotl(x06 ^ x11, 12);\n x01 = (x01 + x06) | 0;\n x12 = rotl(x12 ^ x01, 8);\n x11 = (x11 + x12) | 0;\n x06 = rotl(x06 ^ x11, 7);\n x02 = (x02 + x07) | 0;\n x13 = rotl(x13 ^ x02, 16);\n x08 = (x08 + x13) | 0;\n x07 = rotl(x07 ^ x08, 12);\n x02 = (x02 + x07) | 0;\n x13 = rotl(x13 ^ x02, 8);\n x08 = (x08 + x13) | 0;\n x07 = rotl(x07 ^ x08, 7);\n x03 = (x03 + x04) | 0;\n x14 = rotl(x14 ^ x03, 16);\n x09 = (x09 + x14) | 0;\n x04 = rotl(x04 ^ x09, 12);\n x03 = (x03 + x04) | 0;\n x14 = rotl(x14 ^ x03, 8);\n x09 = (x09 + x14) | 0;\n x04 = rotl(x04 ^ x09, 7);\n }\n let oi = 0;\n o32[oi++] = x00;\n o32[oi++] = x01;\n o32[oi++] = x02;\n o32[oi++] = x03;\n o32[oi++] = x12;\n o32[oi++] = x13;\n o32[oi++] = x14;\n o32[oi++] = x15;\n}\n/**\n * Original, non-RFC chacha20 from DJB. 8-byte nonce, 8-byte counter.\n */\nexport const chacha20orig = /* @__PURE__ */ createCipher(chachaCore, {\n counterRight: false,\n counterLength: 8,\n allowShortKeys: true,\n});\n/**\n * ChaCha stream cipher. Conforms to RFC 8439 (IETF, TLS). 12-byte nonce, 4-byte counter.\n * With 12-byte nonce, it's not safe to use fill it with random (CSPRNG), due to collision chance.\n */\nexport const chacha20 = /* @__PURE__ */ createCipher(chachaCore, {\n counterRight: false,\n counterLength: 4,\n allowShortKeys: false,\n});\n/**\n * XChaCha eXtended-nonce ChaCha. 24-byte nonce.\n * With 24-byte nonce, it's safe to use fill it with random (CSPRNG).\n * https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha\n */\nexport const xchacha20 = /* @__PURE__ */ createCipher(chachaCore, {\n counterRight: false,\n counterLength: 8,\n extendNonceFn: hchacha,\n allowShortKeys: false,\n});\n/**\n * Reduced 8-round chacha, described in original paper.\n */\nexport const chacha8 = /* @__PURE__ */ createCipher(chachaCore, {\n counterRight: false,\n counterLength: 4,\n rounds: 8,\n});\n/**\n * Reduced 12-round chacha, described in original paper.\n */\nexport const chacha12 = /* @__PURE__ */ createCipher(chachaCore, {\n counterRight: false,\n counterLength: 4,\n rounds: 12,\n});\nconst ZEROS16 = /* @__PURE__ */ new Uint8Array(16);\n// Pad to digest size with zeros\nconst updatePadded = (h, msg) => {\n h.update(msg);\n const left = msg.length % 16;\n if (left)\n h.update(ZEROS16.subarray(left));\n};\nconst ZEROS32 = /* @__PURE__ */ new Uint8Array(32);\nfunction computeTag(fn, key, nonce, data, AAD) {\n const authKey = fn(key, nonce, ZEROS32);\n const h = poly1305.create(authKey);\n if (AAD)\n updatePadded(h, AAD);\n updatePadded(h, data);\n const num = new Uint8Array(16);\n const view = createView(num);\n setBigUint64(view, 0, BigInt(AAD ? AAD.length : 0), true);\n setBigUint64(view, 8, BigInt(data.length), true);\n h.update(num);\n const res = h.digest();\n authKey.fill(0);\n return res;\n}\n/**\n * AEAD algorithm from RFC 8439.\n * Salsa20 and chacha (RFC 8439) use poly1305 differently.\n * We could have composed them similar to:\n * https://github.com/paulmillr/scure-base/blob/b266c73dde977b1dd7ef40ef7a23cc15aab526b3/index.ts#L250\n * But it's hard because of authKey:\n * In salsa20, authKey changes position in salsa stream.\n * In chacha, authKey can't be computed inside computeTag, it modifies the counter.\n */\nexport const _poly1305_aead = (xorStream) => (key, nonce, AAD) => {\n const tagLength = 16;\n abytes(key, 32);\n abytes(nonce);\n return {\n encrypt: (plaintext, output) => {\n const plength = plaintext.length;\n const clength = plength + tagLength;\n if (output) {\n abytes(output, clength);\n }\n else {\n output = new Uint8Array(clength);\n }\n xorStream(key, nonce, plaintext, output, 1);\n const tag = computeTag(xorStream, key, nonce, output.subarray(0, -tagLength), AAD);\n output.set(tag, plength); // append tag\n return output;\n },\n decrypt: (ciphertext, output) => {\n const clength = ciphertext.length;\n const plength = clength - tagLength;\n if (clength < tagLength)\n throw new Error(`encrypted data must be at least ${tagLength} bytes`);\n if (output) {\n abytes(output, plength);\n }\n else {\n output = new Uint8Array(plength);\n }\n const data = ciphertext.subarray(0, -tagLength);\n const passedTag = ciphertext.subarray(-tagLength);\n const tag = computeTag(xorStream, key, nonce, data, AAD);\n if (!equalBytes(passedTag, tag))\n throw new Error('invalid tag');\n xorStream(key, nonce, data, output, 1);\n return output;\n },\n };\n};\n/**\n * ChaCha20-Poly1305 from RFC 8439.\n * With 12-byte nonce, it's not safe to use fill it with random (CSPRNG), due to collision chance.\n */\nexport const chacha20poly1305 = /* @__PURE__ */ wrapCipher({ blockSize: 64, nonceLength: 12, tagLength: 16 }, _poly1305_aead(chacha20));\n/**\n * XChaCha20-Poly1305 extended-nonce chacha.\n * https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha\n * With 24-byte nonce, it's safe to use fill it with random (CSPRNG).\n */\nexport const xchacha20poly1305 = /* @__PURE__ */ wrapCipher({ blockSize: 64, nonceLength: 24, tagLength: 16 }, _poly1305_aead(xchacha20));\n//# sourceMappingURL=chacha.js.map","import assert from './_assert.js';\nimport { Hash, toBytes } from './utils.js';\n// HMAC (RFC 2104)\nexport class HMAC extends Hash {\n constructor(hash, _key) {\n super();\n this.finished = false;\n this.destroyed = false;\n assert.hash(hash);\n const key = toBytes(_key);\n this.iHash = hash.create();\n if (typeof this.iHash.update !== 'function')\n throw new Error('Expected instance of class which extends utils.Hash');\n this.blockLen = this.iHash.blockLen;\n this.outputLen = this.iHash.outputLen;\n const blockLen = this.blockLen;\n const pad = new Uint8Array(blockLen);\n // blockLen can be bigger than outputLen\n pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);\n for (let i = 0; i < pad.length; i++)\n pad[i] ^= 0x36;\n this.iHash.update(pad);\n // By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone\n this.oHash = hash.create();\n // Undo internal XOR && apply outer XOR\n for (let i = 0; i < pad.length; i++)\n pad[i] ^= 0x36 ^ 0x5c;\n this.oHash.update(pad);\n pad.fill(0);\n }\n update(buf) {\n assert.exists(this);\n this.iHash.update(buf);\n return this;\n }\n digestInto(out) {\n assert.exists(this);\n assert.bytes(out, this.outputLen);\n this.finished = true;\n this.iHash.digestInto(out);\n this.oHash.update(out);\n this.oHash.digestInto(out);\n this.destroy();\n }\n digest() {\n const out = new Uint8Array(this.oHash.outputLen);\n this.digestInto(out);\n return out;\n }\n _cloneInto(to) {\n // Create new instance without calling constructor since key already in state and we don't know it.\n to || (to = Object.create(Object.getPrototypeOf(this), {}));\n const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;\n to = to;\n to.finished = finished;\n to.destroyed = destroyed;\n to.blockLen = blockLen;\n to.outputLen = outputLen;\n to.oHash = oHash._cloneInto(to.oHash);\n to.iHash = iHash._cloneInto(to.iHash);\n return to;\n }\n destroy() {\n this.destroyed = true;\n this.oHash.destroy();\n this.iHash.destroy();\n }\n}\n/**\n * HMAC: RFC2104 message authentication code.\n * @param hash - function that would be used e.g. sha256\n * @param key - message key\n * @param message - message data\n */\nexport const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();\nhmac.create = (hash, key) => new HMAC(hash, key);\n//# sourceMappingURL=hmac.js.map","import assert from './_assert.js';\nimport { toBytes } from './utils.js';\nimport { hmac } from './hmac.js';\n// HKDF (RFC 5869)\n// https://soatok.blog/2021/11/17/understanding-hkdf/\n/**\n * HKDF-Extract(IKM, salt) -> PRK\n * Arguments position differs from spec (IKM is first one, since it is not optional)\n * @param hash\n * @param ikm\n * @param salt\n * @returns\n */\nexport function extract(hash, ikm, salt) {\n assert.hash(hash);\n // NOTE: some libraries treat zero-length array as 'not provided';\n // we don't, since we have undefined as 'not provided'\n // https://github.com/RustCrypto/KDFs/issues/15\n if (salt === undefined)\n salt = new Uint8Array(hash.outputLen); // if not provided, it is set to a string of HashLen zeros\n return hmac(hash, toBytes(salt), toBytes(ikm));\n}\n// HKDF-Expand(PRK, info, L) -> OKM\nconst HKDF_COUNTER = new Uint8Array([0]);\nconst EMPTY_BUFFER = new Uint8Array();\n/**\n * HKDF-expand from the spec.\n * @param prk - a pseudorandom key of at least HashLen octets (usually, the output from the extract step)\n * @param info - optional context and application specific information (can be a zero-length string)\n * @param length - length of output keying material in octets\n */\nexport function expand(hash, prk, info, length = 32) {\n assert.hash(hash);\n assert.number(length);\n if (length > 255 * hash.outputLen)\n throw new Error('Length should be <= 255*HashLen');\n const blocks = Math.ceil(length / hash.outputLen);\n if (info === undefined)\n info = EMPTY_BUFFER;\n // first L(ength) octets of T\n const okm = new Uint8Array(blocks * hash.outputLen);\n // Re-use HMAC instance between blocks\n const HMAC = hmac.create(hash, prk);\n const HMACTmp = HMAC._cloneInto();\n const T = new Uint8Array(HMAC.outputLen);\n for (let counter = 0; counter < blocks; counter++) {\n HKDF_COUNTER[0] = counter + 1;\n // T(0) = empty string (zero length)\n // T(N) = HMAC-Hash(PRK, T(N-1) | info | N)\n HMACTmp.update(counter === 0 ? EMPTY_BUFFER : T)\n .update(info)\n .update(HKDF_COUNTER)\n .digestInto(T);\n okm.set(T, hash.outputLen * counter);\n HMAC._cloneInto(HMACTmp);\n }\n HMAC.destroy();\n HMACTmp.destroy();\n T.fill(0);\n HKDF_COUNTER.fill(0);\n return okm.slice(0, length);\n}\n/**\n * HKDF (RFC 5869): extract + expand in one step.\n * @param hash - hash function that would be used (e.g. sha256)\n * @param ikm - input keying material, the initial key\n * @param salt - optional salt value (a non-secret random value)\n * @param info - optional context and application specific information\n * @param length - length of output keying material in octets\n */\nexport const hkdf = (hash, ikm, salt, info, length) => expand(hash, extract(hash, ikm, salt), info, length);\n//# sourceMappingURL=hkdf.js.map","var __defProp = Object.defineProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\n\n// pure.ts\nimport { schnorr } from \"@noble/curves/secp256k1\";\nimport { bytesToHex as bytesToHex2 } from \"@noble/hashes/utils\";\n\n// core.ts\nvar verifiedSymbol = Symbol(\"verified\");\nvar isRecord = (obj) => obj instanceof Object;\nfunction validateEvent(event) {\n if (!isRecord(event))\n return false;\n if (typeof event.kind !== \"number\")\n return false;\n if (typeof event.content !== \"string\")\n return false;\n if (typeof event.created_at !== \"number\")\n return false;\n if (typeof event.pubkey !== \"string\")\n return false;\n if (!event.pubkey.match(/^[a-f0-9]{64}$/))\n return false;\n if (!Array.isArray(event.tags))\n return false;\n for (let i2 = 0; i2 < event.tags.length; i2++) {\n let tag = event.tags[i2];\n if (!Array.isArray(tag))\n return false;\n for (let j = 0; j < tag.length; j++) {\n if (typeof tag[j] !== \"string\")\n return false;\n }\n }\n return true;\n}\nfunction sortEvents(events) {\n return events.sort((a, b) => {\n if (a.created_at !== b.created_at) {\n return b.created_at - a.created_at;\n }\n return a.id.localeCompare(b.id);\n });\n}\n\n// pure.ts\nimport { sha256 } from \"@noble/hashes/sha256\";\n\n// utils.ts\nvar utils_exports = {};\n__export(utils_exports, {\n Queue: () => Queue,\n QueueNode: () => QueueNode,\n binarySearch: () => binarySearch,\n bytesToHex: () => bytesToHex,\n hexToBytes: () => hexToBytes,\n insertEventIntoAscendingList: () => insertEventIntoAscendingList,\n insertEventIntoDescendingList: () => insertEventIntoDescendingList,\n normalizeURL: () => normalizeURL,\n utf8Decoder: () => utf8Decoder,\n utf8Encoder: () => utf8Encoder\n});\nimport { bytesToHex, hexToBytes } from \"@noble/hashes/utils\";\nvar utf8Decoder = new TextDecoder(\"utf-8\");\nvar utf8Encoder = new TextEncoder();\nfunction normalizeURL(url) {\n try {\n if (url.indexOf(\"://\") === -1)\n url = \"wss://\" + url;\n let p = new URL(url);\n p.pathname = p.pathname.replace(/\\/+/g, \"/\");\n if (p.pathname.endsWith(\"/\"))\n p.pathname = p.pathname.slice(0, -1);\n if (p.port === \"80\" && p.protocol === \"ws:\" || p.port === \"443\" && p.protocol === \"wss:\")\n p.port = \"\";\n p.searchParams.sort();\n p.hash = \"\";\n return p.toString();\n } catch (e) {\n throw new Error(`Invalid URL: ${url}`);\n }\n}\nfunction insertEventIntoDescendingList(sortedArray, event) {\n const [idx, found] = binarySearch(sortedArray, (b) => {\n if (event.id === b.id)\n return 0;\n if (event.created_at === b.created_at)\n return -1;\n return b.created_at - event.created_at;\n });\n if (!found) {\n sortedArray.splice(idx, 0, event);\n }\n return sortedArray;\n}\nfunction insertEventIntoAscendingList(sortedArray, event) {\n const [idx, found] = binarySearch(sortedArray, (b) => {\n if (event.id === b.id)\n return 0;\n if (event.created_at === b.created_at)\n return -1;\n return event.created_at - b.created_at;\n });\n if (!found) {\n sortedArray.splice(idx, 0, event);\n }\n return sortedArray;\n}\nfunction binarySearch(arr, compare) {\n let start = 0;\n let end = arr.length - 1;\n while (start <= end) {\n const mid = Math.floor((start + end) / 2);\n const cmp = compare(arr[mid]);\n if (cmp === 0) {\n return [mid, true];\n }\n if (cmp < 0) {\n end = mid - 1;\n } else {\n start = mid + 1;\n }\n }\n return [start, false];\n}\nvar QueueNode = class {\n value;\n next = null;\n prev = null;\n constructor(message) {\n this.value = message;\n }\n};\nvar Queue = class {\n first;\n last;\n constructor() {\n this.first = null;\n this.last = null;\n }\n enqueue(value) {\n const newNode = new QueueNode(value);\n if (!this.last) {\n this.first = newNode;\n this.last = newNode;\n } else if (this.last === this.first) {\n this.last = newNode;\n this.last.prev = this.first;\n this.first.next = newNode;\n } else {\n newNode.prev = this.last;\n this.last.next = newNode;\n this.last = newNode;\n }\n return true;\n }\n dequeue() {\n if (!this.first)\n return null;\n if (this.first === this.last) {\n const target2 = this.first;\n this.first = null;\n this.last = null;\n return target2.value;\n }\n const target = this.first;\n this.first = target.next;\n if (this.first) {\n this.first.prev = null;\n }\n return target.value;\n }\n};\n\n// pure.ts\nvar JS = class {\n generateSecretKey() {\n return schnorr.utils.randomPrivateKey();\n }\n getPublicKey(secretKey) {\n return bytesToHex2(schnorr.getPublicKey(secretKey));\n }\n finalizeEvent(t, secretKey) {\n const event = t;\n event.pubkey = bytesToHex2(schnorr.getPublicKey(secretKey));\n event.id = getEventHash(event);\n event.sig = bytesToHex2(schnorr.sign(getEventHash(event), secretKey));\n event[verifiedSymbol] = true;\n return event;\n }\n verifyEvent(event) {\n if (typeof event[verifiedSymbol] === \"boolean\")\n return event[verifiedSymbol];\n const hash = getEventHash(event);\n if (hash !== event.id) {\n event[verifiedSymbol] = false;\n return false;\n }\n try {\n const valid = schnorr.verify(event.sig, hash, event.pubkey);\n event[verifiedSymbol] = valid;\n return valid;\n } catch (err) {\n event[verifiedSymbol] = false;\n return false;\n }\n }\n};\nfunction serializeEvent(evt) {\n if (!validateEvent(evt))\n throw new Error(\"can't serialize event with wrong or missing properties\");\n return JSON.stringify([0, evt.pubkey, evt.created_at, evt.kind, evt.tags, evt.content]);\n}\nfunction getEventHash(event) {\n let eventHash = sha256(utf8Encoder.encode(serializeEvent(event)));\n return bytesToHex2(eventHash);\n}\nvar i = new JS();\nvar generateSecretKey = i.generateSecretKey;\nvar getPublicKey = i.getPublicKey;\nvar finalizeEvent = i.finalizeEvent;\nvar verifyEvent = i.verifyEvent;\n\n// kinds.ts\nvar kinds_exports = {};\n__export(kinds_exports, {\n Application: () => Application,\n BadgeAward: () => BadgeAward,\n BadgeDefinition: () => BadgeDefinition,\n BlockedRelaysList: () => BlockedRelaysList,\n BookmarkList: () => BookmarkList,\n Bookmarksets: () => Bookmarksets,\n Calendar: () => Calendar,\n CalendarEventRSVP: () => CalendarEventRSVP,\n ChannelCreation: () => ChannelCreation,\n ChannelHideMessage: () => ChannelHideMessage,\n ChannelMessage: () => ChannelMessage,\n ChannelMetadata: () => ChannelMetadata,\n ChannelMuteUser: () => ChannelMuteUser,\n ClassifiedListing: () => ClassifiedListing,\n ClientAuth: () => ClientAuth,\n CommunitiesList: () => CommunitiesList,\n CommunityDefinition: () => CommunityDefinition,\n CommunityPostApproval: () => CommunityPostApproval,\n Contacts: () => Contacts,\n CreateOrUpdateProduct: () => CreateOrUpdateProduct,\n CreateOrUpdateStall: () => CreateOrUpdateStall,\n Curationsets: () => Curationsets,\n Date: () => Date2,\n DirectMessageRelaysList: () => DirectMessageRelaysList,\n DraftClassifiedListing: () => DraftClassifiedListing,\n DraftLong: () => DraftLong,\n Emojisets: () => Emojisets,\n EncryptedDirectMessage: () => EncryptedDirectMessage,\n EventDeletion: () => EventDeletion,\n FileMetadata: () => FileMetadata,\n FileServerPreference: () => FileServerPreference,\n Followsets: () => Followsets,\n GenericRepost: () => GenericRepost,\n Genericlists: () => Genericlists,\n GiftWrap: () => GiftWrap,\n HTTPAuth: () => HTTPAuth,\n Handlerinformation: () => Handlerinformation,\n Handlerrecommendation: () => Handlerrecommendation,\n Highlights: () => Highlights,\n InterestsList: () => InterestsList,\n Interestsets: () => Interestsets,\n JobFeedback: () => JobFeedback,\n JobRequest: () => JobRequest,\n JobResult: () => JobResult,\n Label: () => Label,\n LightningPubRPC: () => LightningPubRPC,\n LiveChatMessage: () => LiveChatMessage,\n LiveEvent: () => LiveEvent,\n LongFormArticle: () => LongFormArticle,\n Metadata: () => Metadata,\n Mutelist: () => Mutelist,\n NWCWalletInfo: () => NWCWalletInfo,\n NWCWalletRequest: () => NWCWalletRequest,\n NWCWalletResponse: () => NWCWalletResponse,\n NostrConnect: () => NostrConnect,\n OpenTimestamps: () => OpenTimestamps,\n Pinlist: () => Pinlist,\n PrivateDirectMessage: () => PrivateDirectMessage,\n ProblemTracker: () => ProblemTracker,\n ProfileBadges: () => ProfileBadges,\n PublicChatsList: () => PublicChatsList,\n Reaction: () => Reaction,\n RecommendRelay: () => RecommendRelay,\n RelayList: () => RelayList,\n Relaysets: () => Relaysets,\n Report: () => Report,\n Reporting: () => Reporting,\n Repost: () => Repost,\n Seal: () => Seal,\n SearchRelaysList: () => SearchRelaysList,\n ShortTextNote: () => ShortTextNote,\n Time: () => Time,\n UserEmojiList: () => UserEmojiList,\n UserStatuses: () => UserStatuses,\n Zap: () => Zap,\n ZapGoal: () => ZapGoal,\n ZapRequest: () => ZapRequest,\n classifyKind: () => classifyKind,\n isAddressableKind: () => isAddressableKind,\n isEphemeralKind: () => isEphemeralKind,\n isKind: () => isKind,\n isRegularKind: () => isRegularKind,\n isReplaceableKind: () => isReplaceableKind\n});\nfunction isRegularKind(kind) {\n return 1e3 <= kind && kind < 1e4 || [1, 2, 4, 5, 6, 7, 8, 16, 40, 41, 42, 43, 44].includes(kind);\n}\nfunction isReplaceableKind(kind) {\n return [0, 3].includes(kind) || 1e4 <= kind && kind < 2e4;\n}\nfunction isEphemeralKind(kind) {\n return 2e4 <= kind && kind < 3e4;\n}\nfunction isAddressableKind(kind) {\n return 3e4 <= kind && kind < 4e4;\n}\nfunction classifyKind(kind) {\n if (isRegularKind(kind))\n return \"regular\";\n if (isReplaceableKind(kind))\n return \"replaceable\";\n if (isEphemeralKind(kind))\n return \"ephemeral\";\n if (isAddressableKind(kind))\n return \"parameterized\";\n return \"unknown\";\n}\nfunction isKind(event, kind) {\n const kindAsArray = kind instanceof Array ? kind : [kind];\n return validateEvent(event) && kindAsArray.includes(event.kind) || false;\n}\nvar Metadata = 0;\nvar ShortTextNote = 1;\nvar RecommendRelay = 2;\nvar Contacts = 3;\nvar EncryptedDirectMessage = 4;\nvar EventDeletion = 5;\nvar Repost = 6;\nvar Reaction = 7;\nvar BadgeAward = 8;\nvar Seal = 13;\nvar PrivateDirectMessage = 14;\nvar GenericRepost = 16;\nvar ChannelCreation = 40;\nvar ChannelMetadata = 41;\nvar ChannelMessage = 42;\nvar ChannelHideMessage = 43;\nvar ChannelMuteUser = 44;\nvar OpenTimestamps = 1040;\nvar GiftWrap = 1059;\nvar FileMetadata = 1063;\nvar LiveChatMessage = 1311;\nvar ProblemTracker = 1971;\nvar Report = 1984;\nvar Reporting = 1984;\nvar Label = 1985;\nvar CommunityPostApproval = 4550;\nvar JobRequest = 5999;\nvar JobResult = 6999;\nvar JobFeedback = 7e3;\nvar ZapGoal = 9041;\nvar ZapRequest = 9734;\nvar Zap = 9735;\nvar Highlights = 9802;\nvar Mutelist = 1e4;\nvar Pinlist = 10001;\nvar RelayList = 10002;\nvar BookmarkList = 10003;\nvar CommunitiesList = 10004;\nvar PublicChatsList = 10005;\nvar BlockedRelaysList = 10006;\nvar SearchRelaysList = 10007;\nvar InterestsList = 10015;\nvar UserEmojiList = 10030;\nvar DirectMessageRelaysList = 10050;\nvar FileServerPreference = 10096;\nvar NWCWalletInfo = 13194;\nvar LightningPubRPC = 21e3;\nvar ClientAuth = 22242;\nvar NWCWalletRequest = 23194;\nvar NWCWalletResponse = 23195;\nvar NostrConnect = 24133;\nvar HTTPAuth = 27235;\nvar Followsets = 3e4;\nvar Genericlists = 30001;\nvar Relaysets = 30002;\nvar Bookmarksets = 30003;\nvar Curationsets = 30004;\nvar ProfileBadges = 30008;\nvar BadgeDefinition = 30009;\nvar Interestsets = 30015;\nvar CreateOrUpdateStall = 30017;\nvar CreateOrUpdateProduct = 30018;\nvar LongFormArticle = 30023;\nvar DraftLong = 30024;\nvar Emojisets = 30030;\nvar Application = 30078;\nvar LiveEvent = 30311;\nvar UserStatuses = 30315;\nvar ClassifiedListing = 30402;\nvar DraftClassifiedListing = 30403;\nvar Date2 = 31922;\nvar Time = 31923;\nvar Calendar = 31924;\nvar CalendarEventRSVP = 31925;\nvar Handlerrecommendation = 31989;\nvar Handlerinformation = 31990;\nvar CommunityDefinition = 34550;\n\n// filter.ts\nfunction matchFilter(filter, event) {\n if (filter.ids && filter.ids.indexOf(event.id) === -1) {\n return false;\n }\n if (filter.kinds && filter.kinds.indexOf(event.kind) === -1) {\n return false;\n }\n if (filter.authors && filter.authors.indexOf(event.pubkey) === -1) {\n return false;\n }\n for (let f in filter) {\n if (f[0] === \"#\") {\n let tagName = f.slice(1);\n let values = filter[`#${tagName}`];\n if (values && !event.tags.find(([t, v]) => t === f.slice(1) && values.indexOf(v) !== -1))\n return false;\n }\n }\n if (filter.since && event.created_at < filter.since)\n return false;\n if (filter.until && event.created_at > filter.until)\n return false;\n return true;\n}\nfunction matchFilters(filters, event) {\n for (let i2 = 0; i2 < filters.length; i2++) {\n if (matchFilter(filters[i2], event)) {\n return true;\n }\n }\n return false;\n}\nfunction mergeFilters(...filters) {\n let result = {};\n for (let i2 = 0; i2 < filters.length; i2++) {\n let filter = filters[i2];\n Object.entries(filter).forEach(([property, values]) => {\n if (property === \"kinds\" || property === \"ids\" || property === \"authors\" || property[0] === \"#\") {\n result[property] = result[property] || [];\n for (let v = 0; v < values.length; v++) {\n let value = values[v];\n if (!result[property].includes(value))\n result[property].push(value);\n }\n }\n });\n if (filter.limit && (!result.limit || filter.limit > result.limit))\n result.limit = filter.limit;\n if (filter.until && (!result.until || filter.until > result.until))\n result.until = filter.until;\n if (filter.since && (!result.since || filter.since < result.since))\n result.since = filter.since;\n }\n return result;\n}\nfunction getFilterLimit(filter) {\n if (filter.ids && !filter.ids.length)\n return 0;\n if (filter.kinds && !filter.kinds.length)\n return 0;\n if (filter.authors && !filter.authors.length)\n return 0;\n for (const [key, value] of Object.entries(filter)) {\n if (key[0] === \"#\" && Array.isArray(value) && !value.length)\n return 0;\n }\n return Math.min(\n Math.max(0, filter.limit ?? Infinity),\n filter.ids?.length ?? Infinity,\n filter.authors?.length && filter.kinds?.every((kind) => isReplaceableKind(kind)) ? filter.authors.length * filter.kinds.length : Infinity,\n filter.authors?.length && filter.kinds?.every((kind) => isAddressableKind(kind)) && filter[\"#d\"]?.length ? filter.authors.length * filter.kinds.length * filter[\"#d\"].length : Infinity\n );\n}\n\n// fakejson.ts\nvar fakejson_exports = {};\n__export(fakejson_exports, {\n getHex64: () => getHex64,\n getInt: () => getInt,\n getSubscriptionId: () => getSubscriptionId,\n matchEventId: () => matchEventId,\n matchEventKind: () => matchEventKind,\n matchEventPubkey: () => matchEventPubkey\n});\nfunction getHex64(json, field) {\n let len = field.length + 3;\n let idx = json.indexOf(`\"${field}\":`) + len;\n let s = json.slice(idx).indexOf(`\"`) + idx + 1;\n return json.slice(s, s + 64);\n}\nfunction getInt(json, field) {\n let len = field.length;\n let idx = json.indexOf(`\"${field}\":`) + len + 3;\n let sliced = json.slice(idx);\n let end = Math.min(sliced.indexOf(\",\"), sliced.indexOf(\"}\"));\n return parseInt(sliced.slice(0, end), 10);\n}\nfunction getSubscriptionId(json) {\n let idx = json.slice(0, 22).indexOf(`\"EVENT\"`);\n if (idx === -1)\n return null;\n let pstart = json.slice(idx + 7 + 1).indexOf(`\"`);\n if (pstart === -1)\n return null;\n let start = idx + 7 + 1 + pstart;\n let pend = json.slice(start + 1, 80).indexOf(`\"`);\n if (pend === -1)\n return null;\n let end = start + 1 + pend;\n return json.slice(start + 1, end);\n}\nfunction matchEventId(json, id) {\n return id === getHex64(json, \"id\");\n}\nfunction matchEventPubkey(json, pubkey) {\n return pubkey === getHex64(json, \"pubkey\");\n}\nfunction matchEventKind(json, kind) {\n return kind === getInt(json, \"kind\");\n}\n\n// nip42.ts\nvar nip42_exports = {};\n__export(nip42_exports, {\n makeAuthEvent: () => makeAuthEvent\n});\nfunction makeAuthEvent(relayURL, challenge) {\n return {\n kind: ClientAuth,\n created_at: Math.floor(Date.now() / 1e3),\n tags: [\n [\"relay\", relayURL],\n [\"challenge\", challenge]\n ],\n content: \"\"\n };\n}\n\n// helpers.ts\nasync function yieldThread() {\n return new Promise((resolve) => {\n const ch = new MessageChannel();\n const handler = () => {\n ch.port1.removeEventListener(\"message\", handler);\n resolve();\n };\n ch.port1.addEventListener(\"message\", handler);\n ch.port2.postMessage(0);\n ch.port1.start();\n });\n}\nvar alwaysTrue = (t) => {\n t[verifiedSymbol] = true;\n return true;\n};\n\n// abstract-relay.ts\nvar SendingOnClosedConnection = class extends Error {\n constructor(message, relay) {\n super(`Tried to send message '${message} on a closed connection to ${relay}.`);\n this.name = \"SendingOnClosedConnection\";\n }\n};\nvar AbstractRelay = class {\n url;\n _connected = false;\n onclose = null;\n onnotice = (msg) => console.debug(`NOTICE from ${this.url}: ${msg}`);\n baseEoseTimeout = 4400;\n connectionTimeout = 4400;\n publishTimeout = 4400;\n pingFrequency = 2e4;\n pingTimeout = 2e4;\n openSubs = /* @__PURE__ */ new Map();\n enablePing;\n connectionTimeoutHandle;\n connectionPromise;\n openCountRequests = /* @__PURE__ */ new Map();\n openEventPublishes = /* @__PURE__ */ new Map();\n ws;\n incomingMessageQueue = new Queue();\n queueRunning = false;\n challenge;\n authPromise;\n serial = 0;\n verifyEvent;\n _WebSocket;\n constructor(url, opts) {\n this.url = normalizeURL(url);\n this.verifyEvent = opts.verifyEvent;\n this._WebSocket = opts.websocketImplementation || WebSocket;\n this.enablePing = opts.enablePing;\n }\n static async connect(url, opts) {\n const relay = new AbstractRelay(url, opts);\n await relay.connect();\n return relay;\n }\n closeAllSubscriptions(reason) {\n for (let [_, sub] of this.openSubs) {\n sub.close(reason);\n }\n this.openSubs.clear();\n for (let [_, ep] of this.openEventPublishes) {\n ep.reject(new Error(reason));\n }\n this.openEventPublishes.clear();\n for (let [_, cr] of this.openCountRequests) {\n cr.reject(new Error(reason));\n }\n this.openCountRequests.clear();\n }\n get connected() {\n return this._connected;\n }\n async connect() {\n if (this.connectionPromise)\n return this.connectionPromise;\n this.challenge = void 0;\n this.authPromise = void 0;\n this.connectionPromise = new Promise((resolve, reject) => {\n this.connectionTimeoutHandle = setTimeout(() => {\n reject(\"connection timed out\");\n this.connectionPromise = void 0;\n this.onclose?.();\n this.closeAllSubscriptions(\"relay connection timed out\");\n }, this.connectionTimeout);\n try {\n this.ws = new this._WebSocket(this.url);\n } catch (err) {\n clearTimeout(this.connectionTimeoutHandle);\n reject(err);\n return;\n }\n this.ws.onopen = () => {\n clearTimeout(this.connectionTimeoutHandle);\n this._connected = true;\n if (this.enablePing) {\n this.pingpong();\n }\n resolve();\n };\n this.ws.onerror = (ev) => {\n clearTimeout(this.connectionTimeoutHandle);\n reject(ev.message || \"websocket error\");\n this._connected = false;\n this.connectionPromise = void 0;\n this.onclose?.();\n this.closeAllSubscriptions(\"relay connection errored\");\n };\n this.ws.onclose = (ev) => {\n clearTimeout(this.connectionTimeoutHandle);\n reject(ev.message || \"websocket closed\");\n this._connected = false;\n this.connectionPromise = void 0;\n this.onclose?.();\n this.closeAllSubscriptions(\"relay connection closed\");\n };\n this.ws.onmessage = this._onmessage.bind(this);\n });\n return this.connectionPromise;\n }\n async waitForPingPong() {\n return new Promise((res, err) => {\n ;\n this.ws && this.ws.on && this.ws.on(\"pong\", () => res(true)) || err(\"ws can't listen for pong\");\n this.ws && this.ws.ping && this.ws.ping();\n });\n }\n async waitForDummyReq() {\n return new Promise((resolve, _) => {\n const sub = this.subscribe([{ ids: [\"a\".repeat(64)] }], {\n oneose: () => {\n sub.close();\n resolve(true);\n },\n eoseTimeout: this.pingTimeout + 1e3\n });\n });\n }\n async pingpong() {\n if (this.ws?.readyState === 1) {\n const result = await Promise.any([\n this.ws && this.ws.ping && this.ws.on ? this.waitForPingPong() : this.waitForDummyReq(),\n new Promise((res) => setTimeout(() => res(false), this.pingTimeout))\n ]);\n if (result) {\n setTimeout(() => this.pingpong(), this.pingFrequency);\n } else {\n this.closeAllSubscriptions(\"pingpong timed out\");\n this._connected = false;\n this.onclose?.();\n this.ws?.close();\n }\n }\n }\n async runQueue() {\n this.queueRunning = true;\n while (true) {\n if (false === this.handleNext()) {\n break;\n }\n await yieldThread();\n }\n this.queueRunning = false;\n }\n handleNext() {\n const json = this.incomingMessageQueue.dequeue();\n if (!json) {\n return false;\n }\n const subid = getSubscriptionId(json);\n if (subid) {\n const so = this.openSubs.get(subid);\n if (!so) {\n return;\n }\n const id = getHex64(json, \"id\");\n const alreadyHave = so.alreadyHaveEvent?.(id);\n so.receivedEvent?.(this, id);\n if (alreadyHave) {\n return;\n }\n }\n try {\n let data = JSON.parse(json);\n switch (data[0]) {\n case \"EVENT\": {\n const so = this.openSubs.get(data[1]);\n const event = data[2];\n if (this.verifyEvent(event) && matchFilters(so.filters, event)) {\n so.onevent(event);\n }\n return;\n }\n case \"COUNT\": {\n const id = data[1];\n const payload = data[2];\n const cr = this.openCountRequests.get(id);\n if (cr) {\n cr.resolve(payload.count);\n this.openCountRequests.delete(id);\n }\n return;\n }\n case \"EOSE\": {\n const so = this.openSubs.get(data[1]);\n if (!so)\n return;\n so.receivedEose();\n return;\n }\n case \"OK\": {\n const id = data[1];\n const ok = data[2];\n const reason = data[3];\n const ep = this.openEventPublishes.get(id);\n if (ep) {\n clearTimeout(ep.timeout);\n if (ok)\n ep.resolve(reason);\n else\n ep.reject(new Error(reason));\n this.openEventPublishes.delete(id);\n }\n return;\n }\n case \"CLOSED\": {\n const id = data[1];\n const so = this.openSubs.get(id);\n if (!so)\n return;\n so.closed = true;\n so.close(data[2]);\n return;\n }\n case \"NOTICE\":\n this.onnotice(data[1]);\n return;\n case \"AUTH\": {\n this.challenge = data[1];\n return;\n }\n }\n } catch (err) {\n return;\n }\n }\n async send(message) {\n if (!this.connectionPromise)\n throw new SendingOnClosedConnection(message, this.url);\n this.connectionPromise.then(() => {\n this.ws?.send(message);\n });\n }\n async auth(signAuthEvent) {\n const challenge = this.challenge;\n if (!challenge)\n throw new Error(\"can't perform auth, no challenge was received\");\n if (this.authPromise)\n return this.authPromise;\n this.authPromise = new Promise(async (resolve, reject) => {\n try {\n let evt = await signAuthEvent(makeAuthEvent(this.url, challenge));\n let timeout = setTimeout(() => {\n let ep = this.openEventPublishes.get(evt.id);\n if (ep) {\n ep.reject(new Error(\"auth timed out\"));\n this.openEventPublishes.delete(evt.id);\n }\n }, this.publishTimeout);\n this.openEventPublishes.set(evt.id, { resolve, reject, timeout });\n this.send('[\"AUTH\",' + JSON.stringify(evt) + \"]\");\n } catch (err) {\n console.warn(\"subscribe auth function failed:\", err);\n }\n });\n return this.authPromise;\n }\n async publish(event) {\n const ret = new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n const ep = this.openEventPublishes.get(event.id);\n if (ep) {\n ep.reject(new Error(\"publish timed out\"));\n this.openEventPublishes.delete(event.id);\n }\n }, this.publishTimeout);\n this.openEventPublishes.set(event.id, { resolve, reject, timeout });\n });\n this.send('[\"EVENT\",' + JSON.stringify(event) + \"]\");\n return ret;\n }\n async count(filters, params) {\n this.serial++;\n const id = params?.id || \"count:\" + this.serial;\n const ret = new Promise((resolve, reject) => {\n this.openCountRequests.set(id, { resolve, reject });\n });\n this.send('[\"COUNT\",\"' + id + '\",' + JSON.stringify(filters).substring(1));\n return ret;\n }\n subscribe(filters, params) {\n const subscription = this.prepareSubscription(filters, params);\n subscription.fire();\n return subscription;\n }\n prepareSubscription(filters, params) {\n this.serial++;\n const id = params.id || (params.label ? params.label + \":\" : \"sub:\") + this.serial;\n const subscription = new Subscription(this, id, filters, params);\n this.openSubs.set(id, subscription);\n return subscription;\n }\n close() {\n this.closeAllSubscriptions(\"relay connection closed by us\");\n this._connected = false;\n this.onclose?.();\n this.ws?.close();\n }\n _onmessage(ev) {\n this.incomingMessageQueue.enqueue(ev.data);\n if (!this.queueRunning) {\n this.runQueue();\n }\n }\n};\nvar Subscription = class {\n relay;\n id;\n closed = false;\n eosed = false;\n filters;\n alreadyHaveEvent;\n receivedEvent;\n onevent;\n oneose;\n onclose;\n eoseTimeout;\n eoseTimeoutHandle;\n constructor(relay, id, filters, params) {\n this.relay = relay;\n this.filters = filters;\n this.id = id;\n this.alreadyHaveEvent = params.alreadyHaveEvent;\n this.receivedEvent = params.receivedEvent;\n this.eoseTimeout = params.eoseTimeout || relay.baseEoseTimeout;\n this.oneose = params.oneose;\n this.onclose = params.onclose;\n this.onevent = params.onevent || ((event) => {\n console.warn(\n `onevent() callback not defined for subscription '${this.id}' in relay ${this.relay.url}. event received:`,\n event\n );\n });\n }\n fire() {\n this.relay.send('[\"REQ\",\"' + this.id + '\",' + JSON.stringify(this.filters).substring(1));\n this.eoseTimeoutHandle = setTimeout(this.receivedEose.bind(this), this.eoseTimeout);\n }\n receivedEose() {\n if (this.eosed)\n return;\n clearTimeout(this.eoseTimeoutHandle);\n this.eosed = true;\n this.oneose?.();\n }\n close(reason = \"closed by caller\") {\n if (!this.closed && this.relay.connected) {\n try {\n this.relay.send('[\"CLOSE\",' + JSON.stringify(this.id) + \"]\");\n } catch (err) {\n if (err instanceof SendingOnClosedConnection) {\n } else {\n throw err;\n }\n }\n this.closed = true;\n }\n this.relay.openSubs.delete(this.id);\n this.onclose?.(reason);\n }\n};\n\n// relay.ts\nvar _WebSocket;\ntry {\n _WebSocket = WebSocket;\n} catch {\n}\nvar Relay = class extends AbstractRelay {\n constructor(url) {\n super(url, { verifyEvent, websocketImplementation: _WebSocket });\n }\n static async connect(url) {\n const relay = new Relay(url);\n await relay.connect();\n return relay;\n }\n};\n\n// abstract-pool.ts\nvar AbstractSimplePool = class {\n relays = /* @__PURE__ */ new Map();\n seenOn = /* @__PURE__ */ new Map();\n trackRelays = false;\n verifyEvent;\n enablePing;\n trustedRelayURLs = /* @__PURE__ */ new Set();\n _WebSocket;\n constructor(opts) {\n this.verifyEvent = opts.verifyEvent;\n this._WebSocket = opts.websocketImplementation;\n this.enablePing = opts.enablePing;\n }\n async ensureRelay(url, params) {\n url = normalizeURL(url);\n let relay = this.relays.get(url);\n if (!relay) {\n relay = new AbstractRelay(url, {\n verifyEvent: this.trustedRelayURLs.has(url) ? alwaysTrue : this.verifyEvent,\n websocketImplementation: this._WebSocket,\n enablePing: this.enablePing\n });\n relay.onclose = () => {\n this.relays.delete(url);\n };\n if (params?.connectionTimeout)\n relay.connectionTimeout = params.connectionTimeout;\n this.relays.set(url, relay);\n }\n await relay.connect();\n return relay;\n }\n close(relays) {\n relays.map(normalizeURL).forEach((url) => {\n this.relays.get(url)?.close();\n this.relays.delete(url);\n });\n }\n subscribe(relays, filter, params) {\n params.onauth = params.onauth || params.doauth;\n const request = [];\n for (let i2 = 0; i2 < relays.length; i2++) {\n const url = normalizeURL(relays[i2]);\n if (!request.find((r) => r.url === url)) {\n request.push({ url, filter });\n }\n }\n return this.subscribeMap(request, params);\n }\n subscribeMany(relays, filter, params) {\n params.onauth = params.onauth || params.doauth;\n const request = [];\n const uniqUrls = [];\n for (let i2 = 0; i2 < relays.length; i2++) {\n const url = normalizeURL(relays[i2]);\n if (uniqUrls.indexOf(url) === -1) {\n uniqUrls.push(url);\n request.push({ url, filter });\n }\n }\n return this.subscribeMap(request, params);\n }\n subscribeMap(requests, params) {\n params.onauth = params.onauth || params.doauth;\n const grouped = /* @__PURE__ */ new Map();\n for (const req of requests) {\n const { url, filter } = req;\n if (!grouped.has(url))\n grouped.set(url, []);\n grouped.get(url).push(filter);\n }\n const groupedRequests = Array.from(grouped.entries()).map(([url, filters]) => ({ url, filters }));\n if (this.trackRelays) {\n params.receivedEvent = (relay, id) => {\n let set = this.seenOn.get(id);\n if (!set) {\n set = /* @__PURE__ */ new Set();\n this.seenOn.set(id, set);\n }\n set.add(relay);\n };\n }\n const _knownIds = /* @__PURE__ */ new Set();\n const subs = [];\n const eosesReceived = [];\n let handleEose = (i2) => {\n if (eosesReceived[i2])\n return;\n eosesReceived[i2] = true;\n if (eosesReceived.filter((a) => a).length === requests.length) {\n params.oneose?.();\n handleEose = () => {\n };\n }\n };\n const closesReceived = [];\n let handleClose = (i2, reason) => {\n if (closesReceived[i2])\n return;\n handleEose(i2);\n closesReceived[i2] = reason;\n if (closesReceived.filter((a) => a).length === requests.length) {\n params.onclose?.(closesReceived);\n handleClose = () => {\n };\n }\n };\n const localAlreadyHaveEventHandler = (id) => {\n if (params.alreadyHaveEvent?.(id)) {\n return true;\n }\n const have = _knownIds.has(id);\n _knownIds.add(id);\n return have;\n };\n const allOpened = Promise.all(\n groupedRequests.map(async ({ url, filters }, i2) => {\n let relay;\n try {\n relay = await this.ensureRelay(url, {\n connectionTimeout: params.maxWait ? Math.max(params.maxWait * 0.8, params.maxWait - 1e3) : void 0\n });\n } catch (err) {\n handleClose(i2, err?.message || String(err));\n return;\n }\n let subscription = relay.subscribe(filters, {\n ...params,\n oneose: () => handleEose(i2),\n onclose: (reason) => {\n if (reason.startsWith(\"auth-required: \") && params.onauth) {\n relay.auth(params.onauth).then(() => {\n relay.subscribe(filters, {\n ...params,\n oneose: () => handleEose(i2),\n onclose: (reason2) => {\n handleClose(i2, reason2);\n },\n alreadyHaveEvent: localAlreadyHaveEventHandler,\n eoseTimeout: params.maxWait\n });\n }).catch((err) => {\n handleClose(i2, `auth was required and attempted, but failed with: ${err}`);\n });\n } else {\n handleClose(i2, reason);\n }\n },\n alreadyHaveEvent: localAlreadyHaveEventHandler,\n eoseTimeout: params.maxWait\n });\n subs.push(subscription);\n })\n );\n return {\n async close(reason) {\n await allOpened;\n subs.forEach((sub) => {\n sub.close(reason);\n });\n }\n };\n }\n subscribeEose(relays, filter, params) {\n params.onauth = params.onauth || params.doauth;\n const subcloser = this.subscribe(relays, filter, {\n ...params,\n oneose() {\n subcloser.close(\"closed automatically on eose\");\n }\n });\n return subcloser;\n }\n subscribeManyEose(relays, filter, params) {\n params.onauth = params.onauth || params.doauth;\n const subcloser = this.subscribeMany(relays, filter, {\n ...params,\n oneose() {\n subcloser.close(\"closed automatically on eose\");\n }\n });\n return subcloser;\n }\n async querySync(relays, filter, params) {\n return new Promise(async (resolve) => {\n const events = [];\n this.subscribeEose(relays, filter, {\n ...params,\n onevent(event) {\n events.push(event);\n },\n onclose(_) {\n resolve(events);\n }\n });\n });\n }\n async get(relays, filter, params) {\n filter.limit = 1;\n const events = await this.querySync(relays, filter, params);\n events.sort((a, b) => b.created_at - a.created_at);\n return events[0] || null;\n }\n publish(relays, event, options) {\n return relays.map(normalizeURL).map(async (url, i2, arr) => {\n if (arr.indexOf(url) !== i2) {\n return Promise.reject(\"duplicate url\");\n }\n let r = await this.ensureRelay(url);\n return r.publish(event).catch(async (err) => {\n if (err instanceof Error && err.message.startsWith(\"auth-required: \") && options?.onauth) {\n await r.auth(options.onauth);\n return r.publish(event);\n }\n throw err;\n }).then((reason) => {\n if (this.trackRelays) {\n let set = this.seenOn.get(event.id);\n if (!set) {\n set = /* @__PURE__ */ new Set();\n this.seenOn.set(event.id, set);\n }\n set.add(r);\n }\n return reason;\n });\n });\n }\n listConnectionStatus() {\n const map = /* @__PURE__ */ new Map();\n this.relays.forEach((relay, url) => map.set(url, relay.connected));\n return map;\n }\n destroy() {\n this.relays.forEach((conn) => conn.close());\n this.relays = /* @__PURE__ */ new Map();\n }\n};\n\n// pool.ts\nvar _WebSocket2;\ntry {\n _WebSocket2 = WebSocket;\n} catch {\n}\nvar SimplePool = class extends AbstractSimplePool {\n constructor(options) {\n super({ verifyEvent, websocketImplementation: _WebSocket2, ...options });\n }\n};\n\n// nip19.ts\nvar nip19_exports = {};\n__export(nip19_exports, {\n BECH32_REGEX: () => BECH32_REGEX,\n Bech32MaxSize: () => Bech32MaxSize,\n NostrTypeGuard: () => NostrTypeGuard,\n decode: () => decode,\n decodeNostrURI: () => decodeNostrURI,\n encodeBytes: () => encodeBytes,\n naddrEncode: () => naddrEncode,\n neventEncode: () => neventEncode,\n noteEncode: () => noteEncode,\n nprofileEncode: () => nprofileEncode,\n npubEncode: () => npubEncode,\n nsecEncode: () => nsecEncode\n});\nimport { bytesToHex as bytesToHex3, concatBytes, hexToBytes as hexToBytes2 } from \"@noble/hashes/utils\";\nimport { bech32 } from \"@scure/base\";\nvar NostrTypeGuard = {\n isNProfile: (value) => /^nprofile1[a-z\\d]+$/.test(value || \"\"),\n isNEvent: (value) => /^nevent1[a-z\\d]+$/.test(value || \"\"),\n isNAddr: (value) => /^naddr1[a-z\\d]+$/.test(value || \"\"),\n isNSec: (value) => /^nsec1[a-z\\d]{58}$/.test(value || \"\"),\n isNPub: (value) => /^npub1[a-z\\d]{58}$/.test(value || \"\"),\n isNote: (value) => /^note1[a-z\\d]+$/.test(value || \"\"),\n isNcryptsec: (value) => /^ncryptsec1[a-z\\d]+$/.test(value || \"\")\n};\nvar Bech32MaxSize = 5e3;\nvar BECH32_REGEX = /[\\x21-\\x7E]{1,83}1[023456789acdefghjklmnpqrstuvwxyz]{6,}/;\nfunction integerToUint8Array(number) {\n const uint8Array = new Uint8Array(4);\n uint8Array[0] = number >> 24 & 255;\n uint8Array[1] = number >> 16 & 255;\n uint8Array[2] = number >> 8 & 255;\n uint8Array[3] = number & 255;\n return uint8Array;\n}\nfunction decodeNostrURI(nip19code) {\n try {\n if (nip19code.startsWith(\"nostr:\"))\n nip19code = nip19code.substring(6);\n return decode(nip19code);\n } catch (_err) {\n return { type: \"invalid\", data: null };\n }\n}\nfunction decode(code) {\n let { prefix, words } = bech32.decode(code, Bech32MaxSize);\n let data = new Uint8Array(bech32.fromWords(words));\n switch (prefix) {\n case \"nprofile\": {\n let tlv = parseTLV(data);\n if (!tlv[0]?.[0])\n throw new Error(\"missing TLV 0 for nprofile\");\n if (tlv[0][0].length !== 32)\n throw new Error(\"TLV 0 should be 32 bytes\");\n return {\n type: \"nprofile\",\n data: {\n pubkey: bytesToHex3(tlv[0][0]),\n relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : []\n }\n };\n }\n case \"nevent\": {\n let tlv = parseTLV(data);\n if (!tlv[0]?.[0])\n throw new Error(\"missing TLV 0 for nevent\");\n if (tlv[0][0].length !== 32)\n throw new Error(\"TLV 0 should be 32 bytes\");\n if (tlv[2] && tlv[2][0].length !== 32)\n throw new Error(\"TLV 2 should be 32 bytes\");\n if (tlv[3] && tlv[3][0].length !== 4)\n throw new Error(\"TLV 3 should be 4 bytes\");\n return {\n type: \"nevent\",\n data: {\n id: bytesToHex3(tlv[0][0]),\n relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [],\n author: tlv[2]?.[0] ? bytesToHex3(tlv[2][0]) : void 0,\n kind: tlv[3]?.[0] ? parseInt(bytesToHex3(tlv[3][0]), 16) : void 0\n }\n };\n }\n case \"naddr\": {\n let tlv = parseTLV(data);\n if (!tlv[0]?.[0])\n throw new Error(\"missing TLV 0 for naddr\");\n if (!tlv[2]?.[0])\n throw new Error(\"missing TLV 2 for naddr\");\n if (tlv[2][0].length !== 32)\n throw new Error(\"TLV 2 should be 32 bytes\");\n if (!tlv[3]?.[0])\n throw new Error(\"missing TLV 3 for naddr\");\n if (tlv[3][0].length !== 4)\n throw new Error(\"TLV 3 should be 4 bytes\");\n return {\n type: \"naddr\",\n data: {\n identifier: utf8Decoder.decode(tlv[0][0]),\n pubkey: bytesToHex3(tlv[2][0]),\n kind: parseInt(bytesToHex3(tlv[3][0]), 16),\n relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : []\n }\n };\n }\n case \"nsec\":\n return { type: prefix, data };\n case \"npub\":\n case \"note\":\n return { type: prefix, data: bytesToHex3(data) };\n default:\n throw new Error(`unknown prefix ${prefix}`);\n }\n}\nfunction parseTLV(data) {\n let result = {};\n let rest = data;\n while (rest.length > 0) {\n let t = rest[0];\n let l = rest[1];\n let v = rest.slice(2, 2 + l);\n rest = rest.slice(2 + l);\n if (v.length < l)\n throw new Error(`not enough data to read on TLV ${t}`);\n result[t] = result[t] || [];\n result[t].push(v);\n }\n return result;\n}\nfunction nsecEncode(key) {\n return encodeBytes(\"nsec\", key);\n}\nfunction npubEncode(hex) {\n return encodeBytes(\"npub\", hexToBytes2(hex));\n}\nfunction noteEncode(hex) {\n return encodeBytes(\"note\", hexToBytes2(hex));\n}\nfunction encodeBech32(prefix, data) {\n let words = bech32.toWords(data);\n return bech32.encode(prefix, words, Bech32MaxSize);\n}\nfunction encodeBytes(prefix, bytes) {\n return encodeBech32(prefix, bytes);\n}\nfunction nprofileEncode(profile) {\n let data = encodeTLV({\n 0: [hexToBytes2(profile.pubkey)],\n 1: (profile.relays || []).map((url) => utf8Encoder.encode(url))\n });\n return encodeBech32(\"nprofile\", data);\n}\nfunction neventEncode(event) {\n let kindArray;\n if (event.kind !== void 0) {\n kindArray = integerToUint8Array(event.kind);\n }\n let data = encodeTLV({\n 0: [hexToBytes2(event.id)],\n 1: (event.relays || []).map((url) => utf8Encoder.encode(url)),\n 2: event.author ? [hexToBytes2(event.author)] : [],\n 3: kindArray ? [new Uint8Array(kindArray)] : []\n });\n return encodeBech32(\"nevent\", data);\n}\nfunction naddrEncode(addr) {\n let kind = new ArrayBuffer(4);\n new DataView(kind).setUint32(0, addr.kind, false);\n let data = encodeTLV({\n 0: [utf8Encoder.encode(addr.identifier)],\n 1: (addr.relays || []).map((url) => utf8Encoder.encode(url)),\n 2: [hexToBytes2(addr.pubkey)],\n 3: [new Uint8Array(kind)]\n });\n return encodeBech32(\"naddr\", data);\n}\nfunction encodeTLV(tlv) {\n let entries = [];\n Object.entries(tlv).reverse().forEach(([t, vs]) => {\n vs.forEach((v) => {\n let entry = new Uint8Array(v.length + 2);\n entry.set([parseInt(t)], 0);\n entry.set([v.length], 1);\n entry.set(v, 2);\n entries.push(entry);\n });\n });\n return concatBytes(...entries);\n}\n\n// references.ts\nvar mentionRegex = /\\bnostr:((note|npub|naddr|nevent|nprofile)1\\w+)\\b|#\\[(\\d+)\\]/g;\nfunction parseReferences(evt) {\n let references = [];\n for (let ref of evt.content.matchAll(mentionRegex)) {\n if (ref[2]) {\n try {\n let { type, data } = decode(ref[1]);\n switch (type) {\n case \"npub\": {\n references.push({\n text: ref[0],\n profile: { pubkey: data, relays: [] }\n });\n break;\n }\n case \"nprofile\": {\n references.push({\n text: ref[0],\n profile: data\n });\n break;\n }\n case \"note\": {\n references.push({\n text: ref[0],\n event: { id: data, relays: [] }\n });\n break;\n }\n case \"nevent\": {\n references.push({\n text: ref[0],\n event: data\n });\n break;\n }\n case \"naddr\": {\n references.push({\n text: ref[0],\n address: data\n });\n break;\n }\n }\n } catch (err) {\n }\n } else if (ref[3]) {\n let idx = parseInt(ref[3], 10);\n let tag = evt.tags[idx];\n if (!tag)\n continue;\n switch (tag[0]) {\n case \"p\": {\n references.push({\n text: ref[0],\n profile: { pubkey: tag[1], relays: tag[2] ? [tag[2]] : [] }\n });\n break;\n }\n case \"e\": {\n references.push({\n text: ref[0],\n event: { id: tag[1], relays: tag[2] ? [tag[2]] : [] }\n });\n break;\n }\n case \"a\": {\n try {\n let [kind, pubkey, identifier] = tag[1].split(\":\");\n references.push({\n text: ref[0],\n address: {\n identifier,\n pubkey,\n kind: parseInt(kind, 10),\n relays: tag[2] ? [tag[2]] : []\n }\n });\n } catch (err) {\n }\n break;\n }\n }\n }\n }\n return references;\n}\n\n// nip04.ts\nvar nip04_exports = {};\n__export(nip04_exports, {\n decrypt: () => decrypt,\n encrypt: () => encrypt\n});\nimport { bytesToHex as bytesToHex4, randomBytes } from \"@noble/hashes/utils\";\nimport { secp256k1 } from \"@noble/curves/secp256k1\";\nimport { cbc } from \"@noble/ciphers/aes\";\nimport { base64 } from \"@scure/base\";\nfunction encrypt(secretKey, pubkey, text) {\n const privkey = secretKey instanceof Uint8Array ? bytesToHex4(secretKey) : secretKey;\n const key = secp256k1.getSharedSecret(privkey, \"02\" + pubkey);\n const normalizedKey = getNormalizedX(key);\n let iv = Uint8Array.from(randomBytes(16));\n let plaintext = utf8Encoder.encode(text);\n let ciphertext = cbc(normalizedKey, iv).encrypt(plaintext);\n let ctb64 = base64.encode(new Uint8Array(ciphertext));\n let ivb64 = base64.encode(new Uint8Array(iv.buffer));\n return `${ctb64}?iv=${ivb64}`;\n}\nfunction decrypt(secretKey, pubkey, data) {\n const privkey = secretKey instanceof Uint8Array ? bytesToHex4(secretKey) : secretKey;\n let [ctb64, ivb64] = data.split(\"?iv=\");\n let key = secp256k1.getSharedSecret(privkey, \"02\" + pubkey);\n let normalizedKey = getNormalizedX(key);\n let iv = base64.decode(ivb64);\n let ciphertext = base64.decode(ctb64);\n let plaintext = cbc(normalizedKey, iv).decrypt(ciphertext);\n return utf8Decoder.decode(plaintext);\n}\nfunction getNormalizedX(key) {\n return key.slice(1, 33);\n}\n\n// nip05.ts\nvar nip05_exports = {};\n__export(nip05_exports, {\n NIP05_REGEX: () => NIP05_REGEX,\n isNip05: () => isNip05,\n isValid: () => isValid,\n queryProfile: () => queryProfile,\n searchDomain: () => searchDomain,\n useFetchImplementation: () => useFetchImplementation\n});\nvar NIP05_REGEX = /^(?:([\\w.+-]+)@)?([\\w_-]+(\\.[\\w_-]+)+)$/;\nvar isNip05 = (value) => NIP05_REGEX.test(value || \"\");\nvar _fetch;\ntry {\n _fetch = fetch;\n} catch (_) {\n null;\n}\nfunction useFetchImplementation(fetchImplementation) {\n _fetch = fetchImplementation;\n}\nasync function searchDomain(domain, query = \"\") {\n try {\n const url = `https://${domain}/.well-known/nostr.json?name=${query}`;\n const res = await _fetch(url, { redirect: \"manual\" });\n if (res.status !== 200) {\n throw Error(\"Wrong response code\");\n }\n const json = await res.json();\n return json.names;\n } catch (_) {\n return {};\n }\n}\nasync function queryProfile(fullname) {\n const match = fullname.match(NIP05_REGEX);\n if (!match)\n return null;\n const [, name = \"_\", domain] = match;\n try {\n const url = `https://${domain}/.well-known/nostr.json?name=${name}`;\n const res = await _fetch(url, { redirect: \"manual\" });\n if (res.status !== 200) {\n throw Error(\"Wrong response code\");\n }\n const json = await res.json();\n const pubkey = json.names[name];\n return pubkey ? { pubkey, relays: json.relays?.[pubkey] } : null;\n } catch (_e) {\n return null;\n }\n}\nasync function isValid(pubkey, nip05) {\n const res = await queryProfile(nip05);\n return res ? res.pubkey === pubkey : false;\n}\n\n// nip10.ts\nvar nip10_exports = {};\n__export(nip10_exports, {\n parse: () => parse\n});\nfunction parse(event) {\n const result = {\n reply: void 0,\n root: void 0,\n mentions: [],\n profiles: [],\n quotes: []\n };\n let maybeParent;\n let maybeRoot;\n for (let i2 = event.tags.length - 1; i2 >= 0; i2--) {\n const tag = event.tags[i2];\n if (tag[0] === \"e\" && tag[1]) {\n const [_, eTagEventId, eTagRelayUrl, eTagMarker, eTagAuthor] = tag;\n const eventPointer = {\n id: eTagEventId,\n relays: eTagRelayUrl ? [eTagRelayUrl] : [],\n author: eTagAuthor\n };\n if (eTagMarker === \"root\") {\n result.root = eventPointer;\n continue;\n }\n if (eTagMarker === \"reply\") {\n result.reply = eventPointer;\n continue;\n }\n if (eTagMarker === \"mention\") {\n result.mentions.push(eventPointer);\n continue;\n }\n if (!maybeParent) {\n maybeParent = eventPointer;\n } else {\n maybeRoot = eventPointer;\n }\n result.mentions.push(eventPointer);\n continue;\n }\n if (tag[0] === \"q\" && tag[1]) {\n const [_, eTagEventId, eTagRelayUrl] = tag;\n result.quotes.push({\n id: eTagEventId,\n relays: eTagRelayUrl ? [eTagRelayUrl] : []\n });\n }\n if (tag[0] === \"p\" && tag[1]) {\n result.profiles.push({\n pubkey: tag[1],\n relays: tag[2] ? [tag[2]] : []\n });\n continue;\n }\n }\n if (!result.root) {\n result.root = maybeRoot || maybeParent || result.reply;\n }\n if (!result.reply) {\n result.reply = maybeParent || result.root;\n }\n ;\n [result.reply, result.root].forEach((ref) => {\n if (!ref)\n return;\n let idx = result.mentions.indexOf(ref);\n if (idx !== -1) {\n result.mentions.splice(idx, 1);\n }\n if (ref.author) {\n let author = result.profiles.find((p) => p.pubkey === ref.author);\n if (author && author.relays) {\n if (!ref.relays) {\n ref.relays = [];\n }\n author.relays.forEach((url) => {\n if (ref.relays?.indexOf(url) === -1)\n ref.relays.push(url);\n });\n author.relays = ref.relays;\n }\n }\n });\n result.mentions.forEach((ref) => {\n if (ref.author) {\n let author = result.profiles.find((p) => p.pubkey === ref.author);\n if (author && author.relays) {\n if (!ref.relays) {\n ref.relays = [];\n }\n author.relays.forEach((url) => {\n if (ref.relays.indexOf(url) === -1)\n ref.relays.push(url);\n });\n author.relays = ref.relays;\n }\n }\n });\n return result;\n}\n\n// nip11.ts\nvar nip11_exports = {};\n__export(nip11_exports, {\n fetchRelayInformation: () => fetchRelayInformation,\n useFetchImplementation: () => useFetchImplementation2\n});\nvar _fetch2;\ntry {\n _fetch2 = fetch;\n} catch {\n}\nfunction useFetchImplementation2(fetchImplementation) {\n _fetch2 = fetchImplementation;\n}\nasync function fetchRelayInformation(url) {\n return await (await fetch(url.replace(\"ws://\", \"http://\").replace(\"wss://\", \"https://\"), {\n headers: { Accept: \"application/nostr+json\" }\n })).json();\n}\n\n// nip13.ts\nvar nip13_exports = {};\n__export(nip13_exports, {\n fastEventHash: () => fastEventHash,\n getPow: () => getPow,\n minePow: () => minePow\n});\nimport { bytesToHex as bytesToHex5 } from \"@noble/hashes/utils\";\nimport { sha256 as sha2562 } from \"@noble/hashes/sha256\";\nfunction getPow(hex) {\n let count = 0;\n for (let i2 = 0; i2 < 64; i2 += 8) {\n const nibble = parseInt(hex.substring(i2, i2 + 8), 16);\n if (nibble === 0) {\n count += 32;\n } else {\n count += Math.clz32(nibble);\n break;\n }\n }\n return count;\n}\nfunction minePow(unsigned, difficulty) {\n let count = 0;\n const event = unsigned;\n const tag = [\"nonce\", count.toString(), difficulty.toString()];\n event.tags.push(tag);\n while (true) {\n const now2 = Math.floor(new Date().getTime() / 1e3);\n if (now2 !== event.created_at) {\n count = 0;\n event.created_at = now2;\n }\n tag[1] = (++count).toString();\n event.id = fastEventHash(event);\n if (getPow(event.id) >= difficulty) {\n break;\n }\n }\n return event;\n}\nfunction fastEventHash(evt) {\n return bytesToHex5(\n sha2562(utf8Encoder.encode(JSON.stringify([0, evt.pubkey, evt.created_at, evt.kind, evt.tags, evt.content])))\n );\n}\n\n// nip17.ts\nvar nip17_exports = {};\n__export(nip17_exports, {\n unwrapEvent: () => unwrapEvent2,\n unwrapManyEvents: () => unwrapManyEvents2,\n wrapEvent: () => wrapEvent2,\n wrapManyEvents: () => wrapManyEvents2\n});\n\n// nip59.ts\nvar nip59_exports = {};\n__export(nip59_exports, {\n createRumor: () => createRumor,\n createSeal: () => createSeal,\n createWrap: () => createWrap,\n unwrapEvent: () => unwrapEvent,\n unwrapManyEvents: () => unwrapManyEvents,\n wrapEvent: () => wrapEvent,\n wrapManyEvents: () => wrapManyEvents\n});\n\n// nip44.ts\nvar nip44_exports = {};\n__export(nip44_exports, {\n decrypt: () => decrypt2,\n encrypt: () => encrypt2,\n getConversationKey: () => getConversationKey,\n v2: () => v2\n});\nimport { chacha20 } from \"@noble/ciphers/chacha\";\nimport { equalBytes } from \"@noble/ciphers/utils\";\nimport { secp256k1 as secp256k12 } from \"@noble/curves/secp256k1\";\nimport { extract as hkdf_extract, expand as hkdf_expand } from \"@noble/hashes/hkdf\";\nimport { hmac } from \"@noble/hashes/hmac\";\nimport { sha256 as sha2563 } from \"@noble/hashes/sha256\";\nimport { concatBytes as concatBytes2, randomBytes as randomBytes2 } from \"@noble/hashes/utils\";\nimport { base64 as base642 } from \"@scure/base\";\nvar minPlaintextSize = 1;\nvar maxPlaintextSize = 65535;\nfunction getConversationKey(privkeyA, pubkeyB) {\n const sharedX = secp256k12.getSharedSecret(privkeyA, \"02\" + pubkeyB).subarray(1, 33);\n return hkdf_extract(sha2563, sharedX, \"nip44-v2\");\n}\nfunction getMessageKeys(conversationKey, nonce) {\n const keys = hkdf_expand(sha2563, conversationKey, nonce, 76);\n return {\n chacha_key: keys.subarray(0, 32),\n chacha_nonce: keys.subarray(32, 44),\n hmac_key: keys.subarray(44, 76)\n };\n}\nfunction calcPaddedLen(len) {\n if (!Number.isSafeInteger(len) || len < 1)\n throw new Error(\"expected positive integer\");\n if (len <= 32)\n return 32;\n const nextPower = 1 << Math.floor(Math.log2(len - 1)) + 1;\n const chunk = nextPower <= 256 ? 32 : nextPower / 8;\n return chunk * (Math.floor((len - 1) / chunk) + 1);\n}\nfunction writeU16BE(num) {\n if (!Number.isSafeInteger(num) || num < minPlaintextSize || num > maxPlaintextSize)\n throw new Error(\"invalid plaintext size: must be between 1 and 65535 bytes\");\n const arr = new Uint8Array(2);\n new DataView(arr.buffer).setUint16(0, num, false);\n return arr;\n}\nfunction pad(plaintext) {\n const unpadded = utf8Encoder.encode(plaintext);\n const unpaddedLen = unpadded.length;\n const prefix = writeU16BE(unpaddedLen);\n const suffix = new Uint8Array(calcPaddedLen(unpaddedLen) - unpaddedLen);\n return concatBytes2(prefix, unpadded, suffix);\n}\nfunction unpad(padded) {\n const unpaddedLen = new DataView(padded.buffer).getUint16(0);\n const unpadded = padded.subarray(2, 2 + unpaddedLen);\n if (unpaddedLen < minPlaintextSize || unpaddedLen > maxPlaintextSize || unpadded.length !== unpaddedLen || padded.length !== 2 + calcPaddedLen(unpaddedLen))\n throw new Error(\"invalid padding\");\n return utf8Decoder.decode(unpadded);\n}\nfunction hmacAad(key, message, aad) {\n if (aad.length !== 32)\n throw new Error(\"AAD associated data must be 32 bytes\");\n const combined = concatBytes2(aad, message);\n return hmac(sha2563, key, combined);\n}\nfunction decodePayload(payload) {\n if (typeof payload !== \"string\")\n throw new Error(\"payload must be a valid string\");\n const plen = payload.length;\n if (plen < 132 || plen > 87472)\n throw new Error(\"invalid payload length: \" + plen);\n if (payload[0] === \"#\")\n throw new Error(\"unknown encryption version\");\n let data;\n try {\n data = base642.decode(payload);\n } catch (error) {\n throw new Error(\"invalid base64: \" + error.message);\n }\n const dlen = data.length;\n if (dlen < 99 || dlen > 65603)\n throw new Error(\"invalid data length: \" + dlen);\n const vers = data[0];\n if (vers !== 2)\n throw new Error(\"unknown encryption version \" + vers);\n return {\n nonce: data.subarray(1, 33),\n ciphertext: data.subarray(33, -32),\n mac: data.subarray(-32)\n };\n}\nfunction encrypt2(plaintext, conversationKey, nonce = randomBytes2(32)) {\n const { chacha_key, chacha_nonce, hmac_key } = getMessageKeys(conversationKey, nonce);\n const padded = pad(plaintext);\n const ciphertext = chacha20(chacha_key, chacha_nonce, padded);\n const mac = hmacAad(hmac_key, ciphertext, nonce);\n return base642.encode(concatBytes2(new Uint8Array([2]), nonce, ciphertext, mac));\n}\nfunction decrypt2(payload, conversationKey) {\n const { nonce, ciphertext, mac } = decodePayload(payload);\n const { chacha_key, chacha_nonce, hmac_key } = getMessageKeys(conversationKey, nonce);\n const calculatedMac = hmacAad(hmac_key, ciphertext, nonce);\n if (!equalBytes(calculatedMac, mac))\n throw new Error(\"invalid MAC\");\n const padded = chacha20(chacha_key, chacha_nonce, ciphertext);\n return unpad(padded);\n}\nvar v2 = {\n utils: {\n getConversationKey,\n calcPaddedLen\n },\n encrypt: encrypt2,\n decrypt: decrypt2\n};\n\n// nip59.ts\nvar TWO_DAYS = 2 * 24 * 60 * 60;\nvar now = () => Math.round(Date.now() / 1e3);\nvar randomNow = () => Math.round(now() - Math.random() * TWO_DAYS);\nvar nip44ConversationKey = (privateKey, publicKey) => getConversationKey(privateKey, publicKey);\nvar nip44Encrypt = (data, privateKey, publicKey) => encrypt2(JSON.stringify(data), nip44ConversationKey(privateKey, publicKey));\nvar nip44Decrypt = (data, privateKey) => JSON.parse(decrypt2(data.content, nip44ConversationKey(privateKey, data.pubkey)));\nfunction createRumor(event, privateKey) {\n const rumor = {\n created_at: now(),\n content: \"\",\n tags: [],\n ...event,\n pubkey: getPublicKey(privateKey)\n };\n rumor.id = getEventHash(rumor);\n return rumor;\n}\nfunction createSeal(rumor, privateKey, recipientPublicKey) {\n return finalizeEvent(\n {\n kind: Seal,\n content: nip44Encrypt(rumor, privateKey, recipientPublicKey),\n created_at: randomNow(),\n tags: []\n },\n privateKey\n );\n}\nfunction createWrap(seal, recipientPublicKey) {\n const randomKey = generateSecretKey();\n return finalizeEvent(\n {\n kind: GiftWrap,\n content: nip44Encrypt(seal, randomKey, recipientPublicKey),\n created_at: randomNow(),\n tags: [[\"p\", recipientPublicKey]]\n },\n randomKey\n );\n}\nfunction wrapEvent(event, senderPrivateKey, recipientPublicKey) {\n const rumor = createRumor(event, senderPrivateKey);\n const seal = createSeal(rumor, senderPrivateKey, recipientPublicKey);\n return createWrap(seal, recipientPublicKey);\n}\nfunction wrapManyEvents(event, senderPrivateKey, recipientsPublicKeys) {\n if (!recipientsPublicKeys || recipientsPublicKeys.length === 0) {\n throw new Error(\"At least one recipient is required.\");\n }\n const senderPublicKey = getPublicKey(senderPrivateKey);\n const wrappeds = [wrapEvent(event, senderPrivateKey, senderPublicKey)];\n recipientsPublicKeys.forEach((recipientPublicKey) => {\n wrappeds.push(wrapEvent(event, senderPrivateKey, recipientPublicKey));\n });\n return wrappeds;\n}\nfunction unwrapEvent(wrap, recipientPrivateKey) {\n const unwrappedSeal = nip44Decrypt(wrap, recipientPrivateKey);\n return nip44Decrypt(unwrappedSeal, recipientPrivateKey);\n}\nfunction unwrapManyEvents(wrappedEvents, recipientPrivateKey) {\n let unwrappedEvents = [];\n wrappedEvents.forEach((e) => {\n unwrappedEvents.push(unwrapEvent(e, recipientPrivateKey));\n });\n unwrappedEvents.sort((a, b) => a.created_at - b.created_at);\n return unwrappedEvents;\n}\n\n// nip17.ts\nfunction createEvent(recipients, message, conversationTitle, replyTo) {\n const baseEvent = {\n created_at: Math.ceil(Date.now() / 1e3),\n kind: PrivateDirectMessage,\n tags: [],\n content: message\n };\n const recipientsArray = Array.isArray(recipients) ? recipients : [recipients];\n recipientsArray.forEach(({ publicKey, relayUrl }) => {\n baseEvent.tags.push(relayUrl ? [\"p\", publicKey, relayUrl] : [\"p\", publicKey]);\n });\n if (replyTo) {\n baseEvent.tags.push([\"e\", replyTo.eventId, replyTo.relayUrl || \"\", \"reply\"]);\n }\n if (conversationTitle) {\n baseEvent.tags.push([\"subject\", conversationTitle]);\n }\n return baseEvent;\n}\nfunction wrapEvent2(senderPrivateKey, recipient, message, conversationTitle, replyTo) {\n const event = createEvent(recipient, message, conversationTitle, replyTo);\n return wrapEvent(event, senderPrivateKey, recipient.publicKey);\n}\nfunction wrapManyEvents2(senderPrivateKey, recipients, message, conversationTitle, replyTo) {\n if (!recipients || recipients.length === 0) {\n throw new Error(\"At least one recipient is required.\");\n }\n const senderPublicKey = getPublicKey(senderPrivateKey);\n return [{ publicKey: senderPublicKey }, ...recipients].map(\n (recipient) => wrapEvent2(senderPrivateKey, recipient, message, conversationTitle, replyTo)\n );\n}\nvar unwrapEvent2 = unwrapEvent;\nvar unwrapManyEvents2 = unwrapManyEvents;\n\n// nip18.ts\nvar nip18_exports = {};\n__export(nip18_exports, {\n finishRepostEvent: () => finishRepostEvent,\n getRepostedEvent: () => getRepostedEvent,\n getRepostedEventPointer: () => getRepostedEventPointer\n});\nfunction finishRepostEvent(t, reposted, relayUrl, privateKey) {\n let kind;\n const tags = [...t.tags ?? [], [\"e\", reposted.id, relayUrl], [\"p\", reposted.pubkey]];\n if (reposted.kind === ShortTextNote) {\n kind = Repost;\n } else {\n kind = GenericRepost;\n tags.push([\"k\", String(reposted.kind)]);\n }\n return finalizeEvent(\n {\n kind,\n tags,\n content: t.content === \"\" || reposted.tags?.find((tag) => tag[0] === \"-\") ? \"\" : JSON.stringify(reposted),\n created_at: t.created_at\n },\n privateKey\n );\n}\nfunction getRepostedEventPointer(event) {\n if (![Repost, GenericRepost].includes(event.kind)) {\n return void 0;\n }\n let lastETag;\n let lastPTag;\n for (let i2 = event.tags.length - 1; i2 >= 0 && (lastETag === void 0 || lastPTag === void 0); i2--) {\n const tag = event.tags[i2];\n if (tag.length >= 2) {\n if (tag[0] === \"e\" && lastETag === void 0) {\n lastETag = tag;\n } else if (tag[0] === \"p\" && lastPTag === void 0) {\n lastPTag = tag;\n }\n }\n }\n if (lastETag === void 0) {\n return void 0;\n }\n return {\n id: lastETag[1],\n relays: [lastETag[2], lastPTag?.[2]].filter((x) => typeof x === \"string\"),\n author: lastPTag?.[1]\n };\n}\nfunction getRepostedEvent(event, { skipVerification } = {}) {\n const pointer = getRepostedEventPointer(event);\n if (pointer === void 0 || event.content === \"\") {\n return void 0;\n }\n let repostedEvent;\n try {\n repostedEvent = JSON.parse(event.content);\n } catch (error) {\n return void 0;\n }\n if (repostedEvent.id !== pointer.id) {\n return void 0;\n }\n if (!skipVerification && !verifyEvent(repostedEvent)) {\n return void 0;\n }\n return repostedEvent;\n}\n\n// nip21.ts\nvar nip21_exports = {};\n__export(nip21_exports, {\n NOSTR_URI_REGEX: () => NOSTR_URI_REGEX,\n parse: () => parse2,\n test: () => test\n});\nvar NOSTR_URI_REGEX = new RegExp(`nostr:(${BECH32_REGEX.source})`);\nfunction test(value) {\n return typeof value === \"string\" && new RegExp(`^${NOSTR_URI_REGEX.source}$`).test(value);\n}\nfunction parse2(uri) {\n const match = uri.match(new RegExp(`^${NOSTR_URI_REGEX.source}$`));\n if (!match)\n throw new Error(`Invalid Nostr URI: ${uri}`);\n return {\n uri: match[0],\n value: match[1],\n decoded: decode(match[1])\n };\n}\n\n// nip25.ts\nvar nip25_exports = {};\n__export(nip25_exports, {\n finishReactionEvent: () => finishReactionEvent,\n getReactedEventPointer: () => getReactedEventPointer\n});\nfunction finishReactionEvent(t, reacted, privateKey) {\n const inheritedTags = reacted.tags.filter((tag) => tag.length >= 2 && (tag[0] === \"e\" || tag[0] === \"p\"));\n return finalizeEvent(\n {\n ...t,\n kind: Reaction,\n tags: [...t.tags ?? [], ...inheritedTags, [\"e\", reacted.id], [\"p\", reacted.pubkey]],\n content: t.content ?? \"+\"\n },\n privateKey\n );\n}\nfunction getReactedEventPointer(event) {\n if (event.kind !== Reaction) {\n return void 0;\n }\n let lastETag;\n let lastPTag;\n for (let i2 = event.tags.length - 1; i2 >= 0 && (lastETag === void 0 || lastPTag === void 0); i2--) {\n const tag = event.tags[i2];\n if (tag.length >= 2) {\n if (tag[0] === \"e\" && lastETag === void 0) {\n lastETag = tag;\n } else if (tag[0] === \"p\" && lastPTag === void 0) {\n lastPTag = tag;\n }\n }\n }\n if (lastETag === void 0 || lastPTag === void 0) {\n return void 0;\n }\n return {\n id: lastETag[1],\n relays: [lastETag[2], lastPTag[2]].filter((x) => x !== void 0),\n author: lastPTag[1]\n };\n}\n\n// nip27.ts\nvar nip27_exports = {};\n__export(nip27_exports, {\n parse: () => parse3\n});\nvar noCharacter = /\\W/m;\nvar noURLCharacter = /\\W |\\W$|$|,| /m;\nfunction* parse3(content) {\n const max = content.length;\n let prevIndex = 0;\n let index = 0;\n while (index < max) {\n let u = content.indexOf(\":\", index);\n if (u === -1) {\n break;\n }\n if (content.substring(u - 5, u) === \"nostr\") {\n const m = content.substring(u + 60).match(noCharacter);\n const end = m ? u + 60 + m.index : max;\n try {\n let pointer;\n let { data, type } = decode(content.substring(u + 1, end));\n switch (type) {\n case \"npub\":\n pointer = { pubkey: data };\n break;\n case \"nsec\":\n case \"note\":\n index = end + 1;\n continue;\n default:\n pointer = data;\n }\n if (prevIndex !== u - 5) {\n yield { type: \"text\", text: content.substring(prevIndex, u - 5) };\n }\n yield { type: \"reference\", pointer };\n index = end;\n prevIndex = index;\n continue;\n } catch (_err) {\n index = u + 1;\n continue;\n }\n } else if (content.substring(u - 5, u) === \"https\" || content.substring(u - 4, u) === \"http\") {\n const m = content.substring(u + 4).match(noURLCharacter);\n const end = m ? u + 4 + m.index : max;\n const prefixLen = content[u - 1] === \"s\" ? 5 : 4;\n try {\n let url = new URL(content.substring(u - prefixLen, end));\n if (url.hostname.indexOf(\".\") === -1) {\n throw new Error(\"invalid url\");\n }\n if (prevIndex !== u - prefixLen) {\n yield { type: \"text\", text: content.substring(prevIndex, u - prefixLen) };\n }\n if (/\\.(png|jpe?g|gif|webp)$/i.test(url.pathname)) {\n yield { type: \"image\", url: url.toString() };\n index = end;\n prevIndex = index;\n continue;\n }\n if (/\\.(mp4|avi|webm|mkv)$/i.test(url.pathname)) {\n yield { type: \"video\", url: url.toString() };\n index = end;\n prevIndex = index;\n continue;\n }\n if (/\\.(mp3|aac|ogg|opus)$/i.test(url.pathname)) {\n yield { type: \"audio\", url: url.toString() };\n index = end;\n prevIndex = index;\n continue;\n }\n yield { type: \"url\", url: url.toString() };\n index = end;\n prevIndex = index;\n continue;\n } catch (_err) {\n index = end + 1;\n continue;\n }\n } else if (content.substring(u - 3, u) === \"wss\" || content.substring(u - 2, u) === \"ws\") {\n const m = content.substring(u + 4).match(noURLCharacter);\n const end = m ? u + 4 + m.index : max;\n const prefixLen = content[u - 1] === \"s\" ? 3 : 2;\n try {\n let url = new URL(content.substring(u - prefixLen, end));\n if (url.hostname.indexOf(\".\") === -1) {\n throw new Error(\"invalid ws url\");\n }\n if (prevIndex !== u - prefixLen) {\n yield { type: \"text\", text: content.substring(prevIndex, u - prefixLen) };\n }\n yield { type: \"relay\", url: url.toString() };\n index = end;\n prevIndex = index;\n continue;\n } catch (_err) {\n index = end + 1;\n continue;\n }\n } else {\n index = u + 1;\n continue;\n }\n }\n if (prevIndex !== max) {\n yield { type: \"text\", text: content.substring(prevIndex) };\n }\n}\n\n// nip28.ts\nvar nip28_exports = {};\n__export(nip28_exports, {\n channelCreateEvent: () => channelCreateEvent,\n channelHideMessageEvent: () => channelHideMessageEvent,\n channelMessageEvent: () => channelMessageEvent,\n channelMetadataEvent: () => channelMetadataEvent,\n channelMuteUserEvent: () => channelMuteUserEvent\n});\nvar channelCreateEvent = (t, privateKey) => {\n let content;\n if (typeof t.content === \"object\") {\n content = JSON.stringify(t.content);\n } else if (typeof t.content === \"string\") {\n content = t.content;\n } else {\n return void 0;\n }\n return finalizeEvent(\n {\n kind: ChannelCreation,\n tags: [...t.tags ?? []],\n content,\n created_at: t.created_at\n },\n privateKey\n );\n};\nvar channelMetadataEvent = (t, privateKey) => {\n let content;\n if (typeof t.content === \"object\") {\n content = JSON.stringify(t.content);\n } else if (typeof t.content === \"string\") {\n content = t.content;\n } else {\n return void 0;\n }\n return finalizeEvent(\n {\n kind: ChannelMetadata,\n tags: [[\"e\", t.channel_create_event_id], ...t.tags ?? []],\n content,\n created_at: t.created_at\n },\n privateKey\n );\n};\nvar channelMessageEvent = (t, privateKey) => {\n const tags = [[\"e\", t.channel_create_event_id, t.relay_url, \"root\"]];\n if (t.reply_to_channel_message_event_id) {\n tags.push([\"e\", t.reply_to_channel_message_event_id, t.relay_url, \"reply\"]);\n }\n return finalizeEvent(\n {\n kind: ChannelMessage,\n tags: [...tags, ...t.tags ?? []],\n content: t.content,\n created_at: t.created_at\n },\n privateKey\n );\n};\nvar channelHideMessageEvent = (t, privateKey) => {\n let content;\n if (typeof t.content === \"object\") {\n content = JSON.stringify(t.content);\n } else if (typeof t.content === \"string\") {\n content = t.content;\n } else {\n return void 0;\n }\n return finalizeEvent(\n {\n kind: ChannelHideMessage,\n tags: [[\"e\", t.channel_message_event_id], ...t.tags ?? []],\n content,\n created_at: t.created_at\n },\n privateKey\n );\n};\nvar channelMuteUserEvent = (t, privateKey) => {\n let content;\n if (typeof t.content === \"object\") {\n content = JSON.stringify(t.content);\n } else if (typeof t.content === \"string\") {\n content = t.content;\n } else {\n return void 0;\n }\n return finalizeEvent(\n {\n kind: ChannelMuteUser,\n tags: [[\"p\", t.pubkey_to_mute], ...t.tags ?? []],\n content,\n created_at: t.created_at\n },\n privateKey\n );\n};\n\n// nip30.ts\nvar nip30_exports = {};\n__export(nip30_exports, {\n EMOJI_SHORTCODE_REGEX: () => EMOJI_SHORTCODE_REGEX,\n matchAll: () => matchAll,\n regex: () => regex,\n replaceAll: () => replaceAll\n});\nvar EMOJI_SHORTCODE_REGEX = /:(\\w+):/;\nvar regex = () => new RegExp(`\\\\B${EMOJI_SHORTCODE_REGEX.source}\\\\B`, \"g\");\nfunction* matchAll(content) {\n const matches = content.matchAll(regex());\n for (const match of matches) {\n try {\n const [shortcode, name] = match;\n yield {\n shortcode,\n name,\n start: match.index,\n end: match.index + shortcode.length\n };\n } catch (_e) {\n }\n }\n}\nfunction replaceAll(content, replacer) {\n return content.replaceAll(regex(), (shortcode, name) => {\n return replacer({\n shortcode,\n name\n });\n });\n}\n\n// nip39.ts\nvar nip39_exports = {};\n__export(nip39_exports, {\n useFetchImplementation: () => useFetchImplementation3,\n validateGithub: () => validateGithub\n});\nvar _fetch3;\ntry {\n _fetch3 = fetch;\n} catch {\n}\nfunction useFetchImplementation3(fetchImplementation) {\n _fetch3 = fetchImplementation;\n}\nasync function validateGithub(pubkey, username, proof) {\n try {\n let res = await (await _fetch3(`https://gist.github.com/${username}/${proof}/raw`)).text();\n return res === `Verifying that I control the following Nostr public key: ${pubkey}`;\n } catch (_) {\n return false;\n }\n}\n\n// nip47.ts\nvar nip47_exports = {};\n__export(nip47_exports, {\n makeNwcRequestEvent: () => makeNwcRequestEvent,\n parseConnectionString: () => parseConnectionString\n});\nfunction parseConnectionString(connectionString) {\n const { host, pathname, searchParams } = new URL(connectionString);\n const pubkey = pathname || host;\n const relay = searchParams.get(\"relay\");\n const secret = searchParams.get(\"secret\");\n if (!pubkey || !relay || !secret) {\n throw new Error(\"invalid connection string\");\n }\n return { pubkey, relay, secret };\n}\nasync function makeNwcRequestEvent(pubkey, secretKey, invoice) {\n const content = {\n method: \"pay_invoice\",\n params: {\n invoice\n }\n };\n const encryptedContent = encrypt(secretKey, pubkey, JSON.stringify(content));\n const eventTemplate = {\n kind: NWCWalletRequest,\n created_at: Math.round(Date.now() / 1e3),\n content: encryptedContent,\n tags: [[\"p\", pubkey]]\n };\n return finalizeEvent(eventTemplate, secretKey);\n}\n\n// nip54.ts\nvar nip54_exports = {};\n__export(nip54_exports, {\n normalizeIdentifier: () => normalizeIdentifier\n});\nfunction normalizeIdentifier(name) {\n name = name.trim().toLowerCase();\n name = name.normalize(\"NFKC\");\n return Array.from(name).map((char) => {\n if (/\\p{Letter}/u.test(char) || /\\p{Number}/u.test(char)) {\n return char;\n }\n return \"-\";\n }).join(\"\");\n}\n\n// nip57.ts\nvar nip57_exports = {};\n__export(nip57_exports, {\n getSatoshisAmountFromBolt11: () => getSatoshisAmountFromBolt11,\n getZapEndpoint: () => getZapEndpoint,\n makeZapReceipt: () => makeZapReceipt,\n makeZapRequest: () => makeZapRequest,\n useFetchImplementation: () => useFetchImplementation4,\n validateZapRequest: () => validateZapRequest\n});\nimport { bech32 as bech322 } from \"@scure/base\";\nvar _fetch4;\ntry {\n _fetch4 = fetch;\n} catch {\n}\nfunction useFetchImplementation4(fetchImplementation) {\n _fetch4 = fetchImplementation;\n}\nasync function getZapEndpoint(metadata) {\n try {\n let lnurl = \"\";\n let { lud06, lud16 } = JSON.parse(metadata.content);\n if (lud06) {\n let { words } = bech322.decode(lud06, 1e3);\n let data = bech322.fromWords(words);\n lnurl = utf8Decoder.decode(data);\n } else if (lud16) {\n let [name, domain] = lud16.split(\"@\");\n lnurl = new URL(`/.well-known/lnurlp/${name}`, `https://${domain}`).toString();\n } else {\n return null;\n }\n let res = await _fetch4(lnurl);\n let body = await res.json();\n if (body.allowsNostr && body.nostrPubkey) {\n return body.callback;\n }\n } catch (err) {\n }\n return null;\n}\nfunction makeZapRequest(params) {\n let zr = {\n kind: 9734,\n created_at: Math.round(Date.now() / 1e3),\n content: params.comment || \"\",\n tags: [\n [\"p\", \"pubkey\" in params ? params.pubkey : params.event.pubkey],\n [\"amount\", params.amount.toString()],\n [\"relays\", ...params.relays]\n ]\n };\n if (\"event\" in params) {\n zr.tags.push([\"e\", params.event.id]);\n if (isReplaceableKind(params.event.kind)) {\n const a = [\"a\", `${params.event.kind}:${params.event.pubkey}:`];\n zr.tags.push(a);\n } else if (isAddressableKind(params.event.kind)) {\n let d = params.event.tags.find(([t, v]) => t === \"d\" && v);\n if (!d)\n throw new Error(\"d tag not found or is empty\");\n const a = [\"a\", `${params.event.kind}:${params.event.pubkey}:${d[1]}`];\n zr.tags.push(a);\n }\n zr.tags.push([\"k\", params.event.kind.toString()]);\n }\n return zr;\n}\nfunction validateZapRequest(zapRequestString) {\n let zapRequest;\n try {\n zapRequest = JSON.parse(zapRequestString);\n } catch (err) {\n return \"Invalid zap request JSON.\";\n }\n if (!validateEvent(zapRequest))\n return \"Zap request is not a valid Nostr event.\";\n if (!verifyEvent(zapRequest))\n return \"Invalid signature on zap request.\";\n let p = zapRequest.tags.find(([t, v]) => t === \"p\" && v);\n if (!p)\n return \"Zap request doesn't have a 'p' tag.\";\n if (!p[1].match(/^[a-f0-9]{64}$/))\n return \"Zap request 'p' tag is not valid hex.\";\n let e = zapRequest.tags.find(([t, v]) => t === \"e\" && v);\n if (e && !e[1].match(/^[a-f0-9]{64}$/))\n return \"Zap request 'e' tag is not valid hex.\";\n let relays = zapRequest.tags.find(([t, v]) => t === \"relays\" && v);\n if (!relays)\n return \"Zap request doesn't have a 'relays' tag.\";\n return null;\n}\nfunction makeZapReceipt({\n zapRequest,\n preimage,\n bolt11,\n paidAt\n}) {\n let zr = JSON.parse(zapRequest);\n let tagsFromZapRequest = zr.tags.filter(([t]) => t === \"e\" || t === \"p\" || t === \"a\");\n let zap = {\n kind: 9735,\n created_at: Math.round(paidAt.getTime() / 1e3),\n content: \"\",\n tags: [...tagsFromZapRequest, [\"P\", zr.pubkey], [\"bolt11\", bolt11], [\"description\", zapRequest]]\n };\n if (preimage) {\n zap.tags.push([\"preimage\", preimage]);\n }\n return zap;\n}\nfunction getSatoshisAmountFromBolt11(bolt11) {\n if (bolt11.length < 50) {\n return 0;\n }\n bolt11 = bolt11.substring(0, 50);\n const idx = bolt11.lastIndexOf(\"1\");\n if (idx === -1) {\n return 0;\n }\n const hrp = bolt11.substring(0, idx);\n if (!hrp.startsWith(\"lnbc\")) {\n return 0;\n }\n const amount = hrp.substring(4);\n if (amount.length < 1) {\n return 0;\n }\n const char = amount[amount.length - 1];\n const digit = char.charCodeAt(0) - \"0\".charCodeAt(0);\n const isDigit = digit >= 0 && digit <= 9;\n let cutPoint = amount.length - 1;\n if (isDigit) {\n cutPoint++;\n }\n if (cutPoint < 1) {\n return 0;\n }\n const num = parseInt(amount.substring(0, cutPoint));\n switch (char) {\n case \"m\":\n return num * 1e5;\n case \"u\":\n return num * 100;\n case \"n\":\n return num / 10;\n case \"p\":\n return num / 1e4;\n default:\n return num * 1e8;\n }\n}\n\n// nip98.ts\nvar nip98_exports = {};\n__export(nip98_exports, {\n getToken: () => getToken,\n hashPayload: () => hashPayload,\n unpackEventFromToken: () => unpackEventFromToken,\n validateEvent: () => validateEvent2,\n validateEventKind: () => validateEventKind,\n validateEventMethodTag: () => validateEventMethodTag,\n validateEventPayloadTag: () => validateEventPayloadTag,\n validateEventTimestamp: () => validateEventTimestamp,\n validateEventUrlTag: () => validateEventUrlTag,\n validateToken: () => validateToken\n});\nimport { sha256 as sha2564 } from \"@noble/hashes/sha256\";\nimport { bytesToHex as bytesToHex6 } from \"@noble/hashes/utils\";\nimport { base64 as base643 } from \"@scure/base\";\nvar _authorizationScheme = \"Nostr \";\nasync function getToken(loginUrl, httpMethod, sign, includeAuthorizationScheme = false, payload) {\n const event = {\n kind: HTTPAuth,\n tags: [\n [\"u\", loginUrl],\n [\"method\", httpMethod]\n ],\n created_at: Math.round(new Date().getTime() / 1e3),\n content: \"\"\n };\n if (payload) {\n event.tags.push([\"payload\", hashPayload(payload)]);\n }\n const signedEvent = await sign(event);\n const authorizationScheme = includeAuthorizationScheme ? _authorizationScheme : \"\";\n return authorizationScheme + base643.encode(utf8Encoder.encode(JSON.stringify(signedEvent)));\n}\nasync function validateToken(token, url, method) {\n const event = await unpackEventFromToken(token).catch((error) => {\n throw error;\n });\n const valid = await validateEvent2(event, url, method).catch((error) => {\n throw error;\n });\n return valid;\n}\nasync function unpackEventFromToken(token) {\n if (!token) {\n throw new Error(\"Missing token\");\n }\n token = token.replace(_authorizationScheme, \"\");\n const eventB64 = utf8Decoder.decode(base643.decode(token));\n if (!eventB64 || eventB64.length === 0 || !eventB64.startsWith(\"{\")) {\n throw new Error(\"Invalid token\");\n }\n const event = JSON.parse(eventB64);\n return event;\n}\nfunction validateEventTimestamp(event) {\n if (!event.created_at) {\n return false;\n }\n return Math.round(new Date().getTime() / 1e3) - event.created_at < 60;\n}\nfunction validateEventKind(event) {\n return event.kind === HTTPAuth;\n}\nfunction validateEventUrlTag(event, url) {\n const urlTag = event.tags.find((t) => t[0] === \"u\");\n if (!urlTag) {\n return false;\n }\n return urlTag.length > 0 && urlTag[1] === url;\n}\nfunction validateEventMethodTag(event, method) {\n const methodTag = event.tags.find((t) => t[0] === \"method\");\n if (!methodTag) {\n return false;\n }\n return methodTag.length > 0 && methodTag[1].toLowerCase() === method.toLowerCase();\n}\nfunction hashPayload(payload) {\n const hash = sha2564(utf8Encoder.encode(JSON.stringify(payload)));\n return bytesToHex6(hash);\n}\nfunction validateEventPayloadTag(event, payload) {\n const payloadTag = event.tags.find((t) => t[0] === \"payload\");\n if (!payloadTag) {\n return false;\n }\n const payloadHash = hashPayload(payload);\n return payloadTag.length > 0 && payloadTag[1] === payloadHash;\n}\nasync function validateEvent2(event, url, method, body) {\n if (!verifyEvent(event)) {\n throw new Error(\"Invalid nostr event, signature invalid\");\n }\n if (!validateEventKind(event)) {\n throw new Error(\"Invalid nostr event, kind invalid\");\n }\n if (!validateEventTimestamp(event)) {\n throw new Error(\"Invalid nostr event, created_at timestamp invalid\");\n }\n if (!validateEventUrlTag(event, url)) {\n throw new Error(\"Invalid nostr event, url tag invalid\");\n }\n if (!validateEventMethodTag(event, method)) {\n throw new Error(\"Invalid nostr event, method tag invalid\");\n }\n if (Boolean(body) && typeof body === \"object\" && Object.keys(body).length > 0) {\n if (!validateEventPayloadTag(event, body)) {\n throw new Error(\"Invalid nostr event, payload tag does not match request body hash\");\n }\n }\n return true;\n}\nexport {\n Relay,\n SimplePool,\n finalizeEvent,\n fakejson_exports as fj,\n generateSecretKey,\n getEventHash,\n getFilterLimit,\n getPublicKey,\n kinds_exports as kinds,\n matchFilter,\n matchFilters,\n mergeFilters,\n nip04_exports as nip04,\n nip05_exports as nip05,\n nip10_exports as nip10,\n nip11_exports as nip11,\n nip13_exports as nip13,\n nip17_exports as nip17,\n nip18_exports as nip18,\n nip19_exports as nip19,\n nip21_exports as nip21,\n nip25_exports as nip25,\n nip27_exports as nip27,\n nip28_exports as nip28,\n nip30_exports as nip30,\n nip39_exports as nip39,\n nip42_exports as nip42,\n nip44_exports as nip44,\n nip47_exports as nip47,\n nip54_exports as nip54,\n nip57_exports as nip57,\n nip59_exports as nip59,\n nip98_exports as nip98,\n parseReferences,\n serializeEvent,\n sortEvents,\n utils_exports as utils,\n validateEvent,\n verifiedSymbol,\n verifyEvent\n};\n","// core.ts\nvar verifiedSymbol = Symbol(\"verified\");\nvar isRecord = (obj) => obj instanceof Object;\nfunction validateEvent(event) {\n if (!isRecord(event))\n return false;\n if (typeof event.kind !== \"number\")\n return false;\n if (typeof event.content !== \"string\")\n return false;\n if (typeof event.created_at !== \"number\")\n return false;\n if (typeof event.pubkey !== \"string\")\n return false;\n if (!event.pubkey.match(/^[a-f0-9]{64}$/))\n return false;\n if (!Array.isArray(event.tags))\n return false;\n for (let i = 0; i < event.tags.length; i++) {\n let tag = event.tags[i];\n if (!Array.isArray(tag))\n return false;\n for (let j = 0; j < tag.length; j++) {\n if (typeof tag[j] !== \"string\")\n return false;\n }\n }\n return true;\n}\n\n// kinds.ts\nfunction isRegularKind(kind) {\n return 1e3 <= kind && kind < 1e4 || [1, 2, 4, 5, 6, 7, 8, 16, 40, 41, 42, 43, 44].includes(kind);\n}\nfunction isReplaceableKind(kind) {\n return [0, 3].includes(kind) || 1e4 <= kind && kind < 2e4;\n}\nfunction isEphemeralKind(kind) {\n return 2e4 <= kind && kind < 3e4;\n}\nfunction isAddressableKind(kind) {\n return 3e4 <= kind && kind < 4e4;\n}\nfunction classifyKind(kind) {\n if (isRegularKind(kind))\n return \"regular\";\n if (isReplaceableKind(kind))\n return \"replaceable\";\n if (isEphemeralKind(kind))\n return \"ephemeral\";\n if (isAddressableKind(kind))\n return \"parameterized\";\n return \"unknown\";\n}\nfunction isKind(event, kind) {\n const kindAsArray = kind instanceof Array ? kind : [kind];\n return validateEvent(event) && kindAsArray.includes(event.kind) || false;\n}\nvar Metadata = 0;\nvar ShortTextNote = 1;\nvar RecommendRelay = 2;\nvar Contacts = 3;\nvar EncryptedDirectMessage = 4;\nvar EventDeletion = 5;\nvar Repost = 6;\nvar Reaction = 7;\nvar BadgeAward = 8;\nvar Seal = 13;\nvar PrivateDirectMessage = 14;\nvar GenericRepost = 16;\nvar ChannelCreation = 40;\nvar ChannelMetadata = 41;\nvar ChannelMessage = 42;\nvar ChannelHideMessage = 43;\nvar ChannelMuteUser = 44;\nvar OpenTimestamps = 1040;\nvar GiftWrap = 1059;\nvar FileMetadata = 1063;\nvar LiveChatMessage = 1311;\nvar ProblemTracker = 1971;\nvar Report = 1984;\nvar Reporting = 1984;\nvar Label = 1985;\nvar CommunityPostApproval = 4550;\nvar JobRequest = 5999;\nvar JobResult = 6999;\nvar JobFeedback = 7e3;\nvar ZapGoal = 9041;\nvar ZapRequest = 9734;\nvar Zap = 9735;\nvar Highlights = 9802;\nvar Mutelist = 1e4;\nvar Pinlist = 10001;\nvar RelayList = 10002;\nvar BookmarkList = 10003;\nvar CommunitiesList = 10004;\nvar PublicChatsList = 10005;\nvar BlockedRelaysList = 10006;\nvar SearchRelaysList = 10007;\nvar InterestsList = 10015;\nvar UserEmojiList = 10030;\nvar DirectMessageRelaysList = 10050;\nvar FileServerPreference = 10096;\nvar NWCWalletInfo = 13194;\nvar LightningPubRPC = 21e3;\nvar ClientAuth = 22242;\nvar NWCWalletRequest = 23194;\nvar NWCWalletResponse = 23195;\nvar NostrConnect = 24133;\nvar HTTPAuth = 27235;\nvar Followsets = 3e4;\nvar Genericlists = 30001;\nvar Relaysets = 30002;\nvar Bookmarksets = 30003;\nvar Curationsets = 30004;\nvar ProfileBadges = 30008;\nvar BadgeDefinition = 30009;\nvar Interestsets = 30015;\nvar CreateOrUpdateStall = 30017;\nvar CreateOrUpdateProduct = 30018;\nvar LongFormArticle = 30023;\nvar DraftLong = 30024;\nvar Emojisets = 30030;\nvar Application = 30078;\nvar LiveEvent = 30311;\nvar UserStatuses = 30315;\nvar ClassifiedListing = 30402;\nvar DraftClassifiedListing = 30403;\nvar Date = 31922;\nvar Time = 31923;\nvar Calendar = 31924;\nvar CalendarEventRSVP = 31925;\nvar Handlerrecommendation = 31989;\nvar Handlerinformation = 31990;\nvar CommunityDefinition = 34550;\nexport {\n Application,\n BadgeAward,\n BadgeDefinition,\n BlockedRelaysList,\n BookmarkList,\n Bookmarksets,\n Calendar,\n CalendarEventRSVP,\n ChannelCreation,\n ChannelHideMessage,\n ChannelMessage,\n ChannelMetadata,\n ChannelMuteUser,\n ClassifiedListing,\n ClientAuth,\n CommunitiesList,\n CommunityDefinition,\n CommunityPostApproval,\n Contacts,\n CreateOrUpdateProduct,\n CreateOrUpdateStall,\n Curationsets,\n Date,\n DirectMessageRelaysList,\n DraftClassifiedListing,\n DraftLong,\n Emojisets,\n EncryptedDirectMessage,\n EventDeletion,\n FileMetadata,\n FileServerPreference,\n Followsets,\n GenericRepost,\n Genericlists,\n GiftWrap,\n HTTPAuth,\n Handlerinformation,\n Handlerrecommendation,\n Highlights,\n InterestsList,\n Interestsets,\n JobFeedback,\n JobRequest,\n JobResult,\n Label,\n LightningPubRPC,\n LiveChatMessage,\n LiveEvent,\n LongFormArticle,\n Metadata,\n Mutelist,\n NWCWalletInfo,\n NWCWalletRequest,\n NWCWalletResponse,\n NostrConnect,\n OpenTimestamps,\n Pinlist,\n PrivateDirectMessage,\n ProblemTracker,\n ProfileBadges,\n PublicChatsList,\n Reaction,\n RecommendRelay,\n RelayList,\n Relaysets,\n Report,\n Reporting,\n Repost,\n Seal,\n SearchRelaysList,\n ShortTextNote,\n Time,\n UserEmojiList,\n UserStatuses,\n Zap,\n ZapGoal,\n ZapRequest,\n classifyKind,\n isAddressableKind,\n isEphemeralKind,\n isKind,\n isRegularKind,\n isReplaceableKind\n};\n","/******************************************************************************\nCopyright (c) Microsoft Corporation.\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n***************************************************************************** */\n/* global Reflect, Promise, SuppressedError, Symbol, Iterator */\n\nvar extendStatics = function(d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n};\n\nexport function __extends(d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n}\n\nexport var __assign = function() {\n __assign = Object.assign || function __assign(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n }\n return t;\n }\n return __assign.apply(this, arguments);\n}\n\nexport function __rest(s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n}\n\nexport function __decorate(decorators, target, key, desc) {\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n return c > 3 && r && Object.defineProperty(target, key, r), r;\n}\n\nexport function __param(paramIndex, decorator) {\n return function (target, key) { decorator(target, key, paramIndex); }\n}\n\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\n var _, done = false;\n for (var i = decorators.length - 1; i >= 0; i--) {\n var context = {};\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\n if (kind === \"accessor\") {\n if (result === void 0) continue;\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\n if (_ = accept(result.get)) descriptor.get = _;\n if (_ = accept(result.set)) descriptor.set = _;\n if (_ = accept(result.init)) initializers.unshift(_);\n }\n else if (_ = accept(result)) {\n if (kind === \"field\") initializers.unshift(_);\n else descriptor[key] = _;\n }\n }\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\n done = true;\n};\n\nexport function __runInitializers(thisArg, initializers, value) {\n var useValue = arguments.length > 2;\n for (var i = 0; i < initializers.length; i++) {\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\n }\n return useValue ? value : void 0;\n};\n\nexport function __propKey(x) {\n return typeof x === \"symbol\" ? x : \"\".concat(x);\n};\n\nexport function __setFunctionName(f, name, prefix) {\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\n};\n\nexport function __metadata(metadataKey, metadataValue) {\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\n}\n\nexport function __awaiter(thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n}\n\nexport function __generator(thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === \"function\" ? Iterator : Object).prototype);\n return g.next = verb(0), g[\"throw\"] = verb(1), g[\"return\"] = verb(2), typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n}\n\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n});\n\nexport function __exportStar(m, o) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\n}\n\nexport function __values(o) {\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n if (m) return m.call(o);\n if (o && typeof o.length === \"number\") return {\n next: function () {\n if (o && i >= o.length) o = void 0;\n return { value: o && o[i++], done: !o };\n }\n };\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n}\n\nexport function __read(o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n }\n catch (error) { e = { error: error }; }\n finally {\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n }\n finally { if (e) throw e.error; }\n }\n return ar;\n}\n\n/** @deprecated */\nexport function __spread() {\n for (var ar = [], i = 0; i < arguments.length; i++)\n ar = ar.concat(__read(arguments[i]));\n return ar;\n}\n\n/** @deprecated */\nexport function __spreadArrays() {\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\n r[k] = a[j];\n return r;\n}\n\nexport function __spreadArray(to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n}\n\nexport function __await(v) {\n return this instanceof __await ? (this.v = v, this) : new __await(v);\n}\n\nexport function __asyncGenerator(thisArg, _arguments, generator) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\n return i = Object.create((typeof AsyncIterator === \"function\" ? AsyncIterator : Object).prototype), verb(\"next\"), verb(\"throw\"), verb(\"return\", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;\n function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }\n function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\n function fulfill(value) { resume(\"next\", value); }\n function reject(value) { resume(\"throw\", value); }\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n}\n\nexport function __asyncDelegator(o) {\n var i, p;\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\n}\n\nexport function __asyncValues(o) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var m = o[Symbol.asyncIterator], i;\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n}\n\nexport function __makeTemplateObject(cooked, raw) {\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n return cooked;\n};\n\nvar __setModuleDefault = Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n};\n\nvar ownKeys = function(o) {\n ownKeys = Object.getOwnPropertyNames || function (o) {\n var ar = [];\n for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;\n return ar;\n };\n return ownKeys(o);\n};\n\nexport function __importStar(mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== \"default\") __createBinding(result, mod, k[i]);\n __setModuleDefault(result, mod);\n return result;\n}\n\nexport function __importDefault(mod) {\n return (mod && mod.__esModule) ? mod : { default: mod };\n}\n\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n}\n\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\n}\n\nexport function __classPrivateFieldIn(state, receiver) {\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\n}\n\nexport function __addDisposableResource(env, value, async) {\n if (value !== null && value !== void 0) {\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\n var dispose, inner;\n if (async) {\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\n dispose = value[Symbol.asyncDispose];\n }\n if (dispose === void 0) {\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\n dispose = value[Symbol.dispose];\n if (async) inner = dispose;\n }\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\n if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };\n env.stack.push({ value: value, dispose: dispose, async: async });\n }\n else if (async) {\n env.stack.push({ async: true });\n }\n return value;\n}\n\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\n var e = new Error(message);\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\n};\n\nexport function __disposeResources(env) {\n function fail(e) {\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\n env.hasError = true;\n }\n var r, s = 0;\n function next() {\n while (r = env.stack.pop()) {\n try {\n if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);\n if (r.dispose) {\n var result = r.dispose.call(r.value);\n if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\n }\n else s |= 1;\n }\n catch (e) {\n fail(e);\n }\n }\n if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();\n if (env.hasError) throw env.error;\n }\n return next();\n}\n\nexport function __rewriteRelativeImportExtension(path, preserveJsx) {\n if (typeof path === \"string\" && /^\\.\\.?\\//.test(path)) {\n return path.replace(/\\.(tsx)$|((?:\\.d)?)((?:\\.[^./]+?)?)\\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {\n return tsx ? preserveJsx ? \".jsx\" : \".js\" : d && (!ext || !cm) ? m : (d + ext + \".\" + cm.toLowerCase() + \"js\");\n });\n }\n return path;\n}\n\nexport default {\n __extends,\n __assign,\n __rest,\n __decorate,\n __param,\n __esDecorate,\n __runInitializers,\n __propKey,\n __setFunctionName,\n __metadata,\n __awaiter,\n __generator,\n __createBinding,\n __exportStar,\n __values,\n __read,\n __spread,\n __spreadArrays,\n __spreadArray,\n __await,\n __asyncGenerator,\n __asyncDelegator,\n __asyncValues,\n __makeTemplateObject,\n __importStar,\n __importDefault,\n __classPrivateFieldGet,\n __classPrivateFieldSet,\n __classPrivateFieldIn,\n __addDisposableResource,\n __disposeResources,\n __rewriteRelativeImportExtension,\n};\n","export function isFunction(value) {\n return typeof value === 'function';\n}\n//# sourceMappingURL=isFunction.js.map","export function createErrorClass(createImpl) {\n var _super = function (instance) {\n Error.call(instance);\n instance.stack = new Error().stack;\n };\n var ctorFunc = createImpl(_super);\n ctorFunc.prototype = Object.create(Error.prototype);\n ctorFunc.prototype.constructor = ctorFunc;\n return ctorFunc;\n}\n//# sourceMappingURL=createErrorClass.js.map","import { createErrorClass } from './createErrorClass';\nexport var UnsubscriptionError = createErrorClass(function (_super) {\n return function UnsubscriptionErrorImpl(errors) {\n _super(this);\n this.message = errors\n ? errors.length + \" errors occurred during unsubscription:\\n\" + errors.map(function (err, i) { return i + 1 + \") \" + err.toString(); }).join('\\n ')\n : '';\n this.name = 'UnsubscriptionError';\n this.errors = errors;\n };\n});\n//# sourceMappingURL=UnsubscriptionError.js.map","export function arrRemove(arr, item) {\n if (arr) {\n var index = arr.indexOf(item);\n 0 <= index && arr.splice(index, 1);\n }\n}\n//# sourceMappingURL=arrRemove.js.map","import { __read, __spreadArray, __values } from \"tslib\";\nimport { isFunction } from './util/isFunction';\nimport { UnsubscriptionError } from './util/UnsubscriptionError';\nimport { arrRemove } from './util/arrRemove';\nvar Subscription = (function () {\n function Subscription(initialTeardown) {\n this.initialTeardown = initialTeardown;\n this.closed = false;\n this._parentage = null;\n this._finalizers = null;\n }\n Subscription.prototype.unsubscribe = function () {\n var e_1, _a, e_2, _b;\n var errors;\n if (!this.closed) {\n this.closed = true;\n var _parentage = this._parentage;\n if (_parentage) {\n this._parentage = null;\n if (Array.isArray(_parentage)) {\n try {\n for (var _parentage_1 = __values(_parentage), _parentage_1_1 = _parentage_1.next(); !_parentage_1_1.done; _parentage_1_1 = _parentage_1.next()) {\n var parent_1 = _parentage_1_1.value;\n parent_1.remove(this);\n }\n }\n catch (e_1_1) { e_1 = { error: e_1_1 }; }\n finally {\n try {\n if (_parentage_1_1 && !_parentage_1_1.done && (_a = _parentage_1.return)) _a.call(_parentage_1);\n }\n finally { if (e_1) throw e_1.error; }\n }\n }\n else {\n _parentage.remove(this);\n }\n }\n var initialFinalizer = this.initialTeardown;\n if (isFunction(initialFinalizer)) {\n try {\n initialFinalizer();\n }\n catch (e) {\n errors = e instanceof UnsubscriptionError ? e.errors : [e];\n }\n }\n var _finalizers = this._finalizers;\n if (_finalizers) {\n this._finalizers = null;\n try {\n for (var _finalizers_1 = __values(_finalizers), _finalizers_1_1 = _finalizers_1.next(); !_finalizers_1_1.done; _finalizers_1_1 = _finalizers_1.next()) {\n var finalizer = _finalizers_1_1.value;\n try {\n execFinalizer(finalizer);\n }\n catch (err) {\n errors = errors !== null && errors !== void 0 ? errors : [];\n if (err instanceof UnsubscriptionError) {\n errors = __spreadArray(__spreadArray([], __read(errors)), __read(err.errors));\n }\n else {\n errors.push(err);\n }\n }\n }\n }\n catch (e_2_1) { e_2 = { error: e_2_1 }; }\n finally {\n try {\n if (_finalizers_1_1 && !_finalizers_1_1.done && (_b = _finalizers_1.return)) _b.call(_finalizers_1);\n }\n finally { if (e_2) throw e_2.error; }\n }\n }\n if (errors) {\n throw new UnsubscriptionError(errors);\n }\n }\n };\n Subscription.prototype.add = function (teardown) {\n var _a;\n if (teardown && teardown !== this) {\n if (this.closed) {\n execFinalizer(teardown);\n }\n else {\n if (teardown instanceof Subscription) {\n if (teardown.closed || teardown._hasParent(this)) {\n return;\n }\n teardown._addParent(this);\n }\n (this._finalizers = (_a = this._finalizers) !== null && _a !== void 0 ? _a : []).push(teardown);\n }\n }\n };\n Subscription.prototype._hasParent = function (parent) {\n var _parentage = this._parentage;\n return _parentage === parent || (Array.isArray(_parentage) && _parentage.includes(parent));\n };\n Subscription.prototype._addParent = function (parent) {\n var _parentage = this._parentage;\n this._parentage = Array.isArray(_parentage) ? (_parentage.push(parent), _parentage) : _parentage ? [_parentage, parent] : parent;\n };\n Subscription.prototype._removeParent = function (parent) {\n var _parentage = this._parentage;\n if (_parentage === parent) {\n this._parentage = null;\n }\n else if (Array.isArray(_parentage)) {\n arrRemove(_parentage, parent);\n }\n };\n Subscription.prototype.remove = function (teardown) {\n var _finalizers = this._finalizers;\n _finalizers && arrRemove(_finalizers, teardown);\n if (teardown instanceof Subscription) {\n teardown._removeParent(this);\n }\n };\n Subscription.EMPTY = (function () {\n var empty = new Subscription();\n empty.closed = true;\n return empty;\n })();\n return Subscription;\n}());\nexport { Subscription };\nexport var EMPTY_SUBSCRIPTION = Subscription.EMPTY;\nexport function isSubscription(value) {\n return (value instanceof Subscription ||\n (value && 'closed' in value && isFunction(value.remove) && isFunction(value.add) && isFunction(value.unsubscribe)));\n}\nfunction execFinalizer(finalizer) {\n if (isFunction(finalizer)) {\n finalizer();\n }\n else {\n finalizer.unsubscribe();\n }\n}\n//# sourceMappingURL=Subscription.js.map","export var config = {\n onUnhandledError: null,\n onStoppedNotification: null,\n Promise: undefined,\n useDeprecatedSynchronousErrorHandling: false,\n useDeprecatedNextContext: false,\n};\n//# sourceMappingURL=config.js.map","import { __read, __spreadArray } from \"tslib\";\nexport var timeoutProvider = {\n setTimeout: function (handler, timeout) {\n var args = [];\n for (var _i = 2; _i < arguments.length; _i++) {\n args[_i - 2] = arguments[_i];\n }\n var delegate = timeoutProvider.delegate;\n if (delegate === null || delegate === void 0 ? void 0 : delegate.setTimeout) {\n return delegate.setTimeout.apply(delegate, __spreadArray([handler, timeout], __read(args)));\n }\n return setTimeout.apply(void 0, __spreadArray([handler, timeout], __read(args)));\n },\n clearTimeout: function (handle) {\n var delegate = timeoutProvider.delegate;\n return ((delegate === null || delegate === void 0 ? void 0 : delegate.clearTimeout) || clearTimeout)(handle);\n },\n delegate: undefined,\n};\n//# sourceMappingURL=timeoutProvider.js.map","import { config } from '../config';\nimport { timeoutProvider } from '../scheduler/timeoutProvider';\nexport function reportUnhandledError(err) {\n timeoutProvider.setTimeout(function () {\n var onUnhandledError = config.onUnhandledError;\n if (onUnhandledError) {\n onUnhandledError(err);\n }\n else {\n throw err;\n }\n });\n}\n//# sourceMappingURL=reportUnhandledError.js.map","export function noop() { }\n//# sourceMappingURL=noop.js.map","import { config } from '../config';\nvar context = null;\nexport function errorContext(cb) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n var isRoot = !context;\n if (isRoot) {\n context = { errorThrown: false, error: null };\n }\n cb();\n if (isRoot) {\n var _a = context, errorThrown = _a.errorThrown, error = _a.error;\n context = null;\n if (errorThrown) {\n throw error;\n }\n }\n }\n else {\n cb();\n }\n}\nexport function captureError(err) {\n if (config.useDeprecatedSynchronousErrorHandling && context) {\n context.errorThrown = true;\n context.error = err;\n }\n}\n//# sourceMappingURL=errorContext.js.map","import { __extends } from \"tslib\";\nimport { isFunction } from './util/isFunction';\nimport { isSubscription, Subscription } from './Subscription';\nimport { config } from './config';\nimport { reportUnhandledError } from './util/reportUnhandledError';\nimport { noop } from './util/noop';\nimport { nextNotification, errorNotification, COMPLETE_NOTIFICATION } from './NotificationFactories';\nimport { timeoutProvider } from './scheduler/timeoutProvider';\nimport { captureError } from './util/errorContext';\nvar Subscriber = (function (_super) {\n __extends(Subscriber, _super);\n function Subscriber(destination) {\n var _this = _super.call(this) || this;\n _this.isStopped = false;\n if (destination) {\n _this.destination = destination;\n if (isSubscription(destination)) {\n destination.add(_this);\n }\n }\n else {\n _this.destination = EMPTY_OBSERVER;\n }\n return _this;\n }\n Subscriber.create = function (next, error, complete) {\n return new SafeSubscriber(next, error, complete);\n };\n Subscriber.prototype.next = function (value) {\n if (this.isStopped) {\n handleStoppedNotification(nextNotification(value), this);\n }\n else {\n this._next(value);\n }\n };\n Subscriber.prototype.error = function (err) {\n if (this.isStopped) {\n handleStoppedNotification(errorNotification(err), this);\n }\n else {\n this.isStopped = true;\n this._error(err);\n }\n };\n Subscriber.prototype.complete = function () {\n if (this.isStopped) {\n handleStoppedNotification(COMPLETE_NOTIFICATION, this);\n }\n else {\n this.isStopped = true;\n this._complete();\n }\n };\n Subscriber.prototype.unsubscribe = function () {\n if (!this.closed) {\n this.isStopped = true;\n _super.prototype.unsubscribe.call(this);\n this.destination = null;\n }\n };\n Subscriber.prototype._next = function (value) {\n this.destination.next(value);\n };\n Subscriber.prototype._error = function (err) {\n try {\n this.destination.error(err);\n }\n finally {\n this.unsubscribe();\n }\n };\n Subscriber.prototype._complete = function () {\n try {\n this.destination.complete();\n }\n finally {\n this.unsubscribe();\n }\n };\n return Subscriber;\n}(Subscription));\nexport { Subscriber };\nvar _bind = Function.prototype.bind;\nfunction bind(fn, thisArg) {\n return _bind.call(fn, thisArg);\n}\nvar ConsumerObserver = (function () {\n function ConsumerObserver(partialObserver) {\n this.partialObserver = partialObserver;\n }\n ConsumerObserver.prototype.next = function (value) {\n var partialObserver = this.partialObserver;\n if (partialObserver.next) {\n try {\n partialObserver.next(value);\n }\n catch (error) {\n handleUnhandledError(error);\n }\n }\n };\n ConsumerObserver.prototype.error = function (err) {\n var partialObserver = this.partialObserver;\n if (partialObserver.error) {\n try {\n partialObserver.error(err);\n }\n catch (error) {\n handleUnhandledError(error);\n }\n }\n else {\n handleUnhandledError(err);\n }\n };\n ConsumerObserver.prototype.complete = function () {\n var partialObserver = this.partialObserver;\n if (partialObserver.complete) {\n try {\n partialObserver.complete();\n }\n catch (error) {\n handleUnhandledError(error);\n }\n }\n };\n return ConsumerObserver;\n}());\nvar SafeSubscriber = (function (_super) {\n __extends(SafeSubscriber, _super);\n function SafeSubscriber(observerOrNext, error, complete) {\n var _this = _super.call(this) || this;\n var partialObserver;\n if (isFunction(observerOrNext) || !observerOrNext) {\n partialObserver = {\n next: (observerOrNext !== null && observerOrNext !== void 0 ? observerOrNext : undefined),\n error: error !== null && error !== void 0 ? error : undefined,\n complete: complete !== null && complete !== void 0 ? complete : undefined,\n };\n }\n else {\n var context_1;\n if (_this && config.useDeprecatedNextContext) {\n context_1 = Object.create(observerOrNext);\n context_1.unsubscribe = function () { return _this.unsubscribe(); };\n partialObserver = {\n next: observerOrNext.next && bind(observerOrNext.next, context_1),\n error: observerOrNext.error && bind(observerOrNext.error, context_1),\n complete: observerOrNext.complete && bind(observerOrNext.complete, context_1),\n };\n }\n else {\n partialObserver = observerOrNext;\n }\n }\n _this.destination = new ConsumerObserver(partialObserver);\n return _this;\n }\n return SafeSubscriber;\n}(Subscriber));\nexport { SafeSubscriber };\nfunction handleUnhandledError(error) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n captureError(error);\n }\n else {\n reportUnhandledError(error);\n }\n}\nfunction defaultErrorHandler(err) {\n throw err;\n}\nfunction handleStoppedNotification(notification, subscriber) {\n var onStoppedNotification = config.onStoppedNotification;\n onStoppedNotification && timeoutProvider.setTimeout(function () { return onStoppedNotification(notification, subscriber); });\n}\nexport var EMPTY_OBSERVER = {\n closed: true,\n next: noop,\n error: defaultErrorHandler,\n complete: noop,\n};\n//# sourceMappingURL=Subscriber.js.map","export var observable = (function () { return (typeof Symbol === 'function' && Symbol.observable) || '@@observable'; })();\n//# sourceMappingURL=observable.js.map","export function identity(x) {\n return x;\n}\n//# sourceMappingURL=identity.js.map","import { SafeSubscriber, Subscriber } from './Subscriber';\nimport { isSubscription } from './Subscription';\nimport { observable as Symbol_observable } from './symbol/observable';\nimport { pipeFromArray } from './util/pipe';\nimport { config } from './config';\nimport { isFunction } from './util/isFunction';\nimport { errorContext } from './util/errorContext';\nvar Observable = (function () {\n function Observable(subscribe) {\n if (subscribe) {\n this._subscribe = subscribe;\n }\n }\n Observable.prototype.lift = function (operator) {\n var observable = new Observable();\n observable.source = this;\n observable.operator = operator;\n return observable;\n };\n Observable.prototype.subscribe = function (observerOrNext, error, complete) {\n var _this = this;\n var subscriber = isSubscriber(observerOrNext) ? observerOrNext : new SafeSubscriber(observerOrNext, error, complete);\n errorContext(function () {\n var _a = _this, operator = _a.operator, source = _a.source;\n subscriber.add(operator\n ?\n operator.call(subscriber, source)\n : source\n ?\n _this._subscribe(subscriber)\n :\n _this._trySubscribe(subscriber));\n });\n return subscriber;\n };\n Observable.prototype._trySubscribe = function (sink) {\n try {\n return this._subscribe(sink);\n }\n catch (err) {\n sink.error(err);\n }\n };\n Observable.prototype.forEach = function (next, promiseCtor) {\n var _this = this;\n promiseCtor = getPromiseCtor(promiseCtor);\n return new promiseCtor(function (resolve, reject) {\n var subscriber = new SafeSubscriber({\n next: function (value) {\n try {\n next(value);\n }\n catch (err) {\n reject(err);\n subscriber.unsubscribe();\n }\n },\n error: reject,\n complete: resolve,\n });\n _this.subscribe(subscriber);\n });\n };\n Observable.prototype._subscribe = function (subscriber) {\n var _a;\n return (_a = this.source) === null || _a === void 0 ? void 0 : _a.subscribe(subscriber);\n };\n Observable.prototype[Symbol_observable] = function () {\n return this;\n };\n Observable.prototype.pipe = function () {\n var operations = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n operations[_i] = arguments[_i];\n }\n return pipeFromArray(operations)(this);\n };\n Observable.prototype.toPromise = function (promiseCtor) {\n var _this = this;\n promiseCtor = getPromiseCtor(promiseCtor);\n return new promiseCtor(function (resolve, reject) {\n var value;\n _this.subscribe(function (x) { return (value = x); }, function (err) { return reject(err); }, function () { return resolve(value); });\n });\n };\n Observable.create = function (subscribe) {\n return new Observable(subscribe);\n };\n return Observable;\n}());\nexport { Observable };\nfunction getPromiseCtor(promiseCtor) {\n var _a;\n return (_a = promiseCtor !== null && promiseCtor !== void 0 ? promiseCtor : config.Promise) !== null && _a !== void 0 ? _a : Promise;\n}\nfunction isObserver(value) {\n return value && isFunction(value.next) && isFunction(value.error) && isFunction(value.complete);\n}\nfunction isSubscriber(value) {\n return (value && value instanceof Subscriber) || (isObserver(value) && isSubscription(value));\n}\n//# sourceMappingURL=Observable.js.map","import { identity } from './identity';\nexport function pipe() {\n var fns = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n fns[_i] = arguments[_i];\n }\n return pipeFromArray(fns);\n}\nexport function pipeFromArray(fns) {\n if (fns.length === 0) {\n return identity;\n }\n if (fns.length === 1) {\n return fns[0];\n }\n return function piped(input) {\n return fns.reduce(function (prev, fn) { return fn(prev); }, input);\n };\n}\n//# sourceMappingURL=pipe.js.map","import { isFunction } from './isFunction';\nexport function hasLift(source) {\n return isFunction(source === null || source === void 0 ? void 0 : source.lift);\n}\nexport function operate(init) {\n return function (source) {\n if (hasLift(source)) {\n return source.lift(function (liftedSource) {\n try {\n return init(liftedSource, this);\n }\n catch (err) {\n this.error(err);\n }\n });\n }\n throw new TypeError('Unable to lift unknown Observable type');\n };\n}\n//# sourceMappingURL=lift.js.map","import { __extends } from \"tslib\";\nimport { Subscriber } from '../Subscriber';\nexport function createOperatorSubscriber(destination, onNext, onComplete, onError, onFinalize) {\n return new OperatorSubscriber(destination, onNext, onComplete, onError, onFinalize);\n}\nvar OperatorSubscriber = (function (_super) {\n __extends(OperatorSubscriber, _super);\n function OperatorSubscriber(destination, onNext, onComplete, onError, onFinalize, shouldUnsubscribe) {\n var _this = _super.call(this, destination) || this;\n _this.onFinalize = onFinalize;\n _this.shouldUnsubscribe = shouldUnsubscribe;\n _this._next = onNext\n ? function (value) {\n try {\n onNext(value);\n }\n catch (err) {\n destination.error(err);\n }\n }\n : _super.prototype._next;\n _this._error = onError\n ? function (err) {\n try {\n onError(err);\n }\n catch (err) {\n destination.error(err);\n }\n finally {\n this.unsubscribe();\n }\n }\n : _super.prototype._error;\n _this._complete = onComplete\n ? function () {\n try {\n onComplete();\n }\n catch (err) {\n destination.error(err);\n }\n finally {\n this.unsubscribe();\n }\n }\n : _super.prototype._complete;\n return _this;\n }\n OperatorSubscriber.prototype.unsubscribe = function () {\n var _a;\n if (!this.shouldUnsubscribe || this.shouldUnsubscribe()) {\n var closed_1 = this.closed;\n _super.prototype.unsubscribe.call(this);\n !closed_1 && ((_a = this.onFinalize) === null || _a === void 0 ? void 0 : _a.call(this));\n }\n };\n return OperatorSubscriber;\n}(Subscriber));\nexport { OperatorSubscriber };\n//# sourceMappingURL=OperatorSubscriber.js.map","import { createErrorClass } from './createErrorClass';\nexport var ObjectUnsubscribedError = createErrorClass(function (_super) {\n return function ObjectUnsubscribedErrorImpl() {\n _super(this);\n this.name = 'ObjectUnsubscribedError';\n this.message = 'object unsubscribed';\n };\n});\n//# sourceMappingURL=ObjectUnsubscribedError.js.map","import { __extends, __values } from \"tslib\";\nimport { Observable } from './Observable';\nimport { Subscription, EMPTY_SUBSCRIPTION } from './Subscription';\nimport { ObjectUnsubscribedError } from './util/ObjectUnsubscribedError';\nimport { arrRemove } from './util/arrRemove';\nimport { errorContext } from './util/errorContext';\nvar Subject = (function (_super) {\n __extends(Subject, _super);\n function Subject() {\n var _this = _super.call(this) || this;\n _this.closed = false;\n _this.currentObservers = null;\n _this.observers = [];\n _this.isStopped = false;\n _this.hasError = false;\n _this.thrownError = null;\n return _this;\n }\n Subject.prototype.lift = function (operator) {\n var subject = new AnonymousSubject(this, this);\n subject.operator = operator;\n return subject;\n };\n Subject.prototype._throwIfClosed = function () {\n if (this.closed) {\n throw new ObjectUnsubscribedError();\n }\n };\n Subject.prototype.next = function (value) {\n var _this = this;\n errorContext(function () {\n var e_1, _a;\n _this._throwIfClosed();\n if (!_this.isStopped) {\n if (!_this.currentObservers) {\n _this.currentObservers = Array.from(_this.observers);\n }\n try {\n for (var _b = __values(_this.currentObservers), _c = _b.next(); !_c.done; _c = _b.next()) {\n var observer = _c.value;\n observer.next(value);\n }\n }\n catch (e_1_1) { e_1 = { error: e_1_1 }; }\n finally {\n try {\n if (_c && !_c.done && (_a = _b.return)) _a.call(_b);\n }\n finally { if (e_1) throw e_1.error; }\n }\n }\n });\n };\n Subject.prototype.error = function (err) {\n var _this = this;\n errorContext(function () {\n _this._throwIfClosed();\n if (!_this.isStopped) {\n _this.hasError = _this.isStopped = true;\n _this.thrownError = err;\n var observers = _this.observers;\n while (observers.length) {\n observers.shift().error(err);\n }\n }\n });\n };\n Subject.prototype.complete = function () {\n var _this = this;\n errorContext(function () {\n _this._throwIfClosed();\n if (!_this.isStopped) {\n _this.isStopped = true;\n var observers = _this.observers;\n while (observers.length) {\n observers.shift().complete();\n }\n }\n });\n };\n Subject.prototype.unsubscribe = function () {\n this.isStopped = this.closed = true;\n this.observers = this.currentObservers = null;\n };\n Object.defineProperty(Subject.prototype, \"observed\", {\n get: function () {\n var _a;\n return ((_a = this.observers) === null || _a === void 0 ? void 0 : _a.length) > 0;\n },\n enumerable: false,\n configurable: true\n });\n Subject.prototype._trySubscribe = function (subscriber) {\n this._throwIfClosed();\n return _super.prototype._trySubscribe.call(this, subscriber);\n };\n Subject.prototype._subscribe = function (subscriber) {\n this._throwIfClosed();\n this._checkFinalizedStatuses(subscriber);\n return this._innerSubscribe(subscriber);\n };\n Subject.prototype._innerSubscribe = function (subscriber) {\n var _this = this;\n var _a = this, hasError = _a.hasError, isStopped = _a.isStopped, observers = _a.observers;\n if (hasError || isStopped) {\n return EMPTY_SUBSCRIPTION;\n }\n this.currentObservers = null;\n observers.push(subscriber);\n return new Subscription(function () {\n _this.currentObservers = null;\n arrRemove(observers, subscriber);\n });\n };\n Subject.prototype._checkFinalizedStatuses = function (subscriber) {\n var _a = this, hasError = _a.hasError, thrownError = _a.thrownError, isStopped = _a.isStopped;\n if (hasError) {\n subscriber.error(thrownError);\n }\n else if (isStopped) {\n subscriber.complete();\n }\n };\n Subject.prototype.asObservable = function () {\n var observable = new Observable();\n observable.source = this;\n return observable;\n };\n Subject.create = function (destination, source) {\n return new AnonymousSubject(destination, source);\n };\n return Subject;\n}(Observable));\nexport { Subject };\nvar AnonymousSubject = (function (_super) {\n __extends(AnonymousSubject, _super);\n function AnonymousSubject(destination, source) {\n var _this = _super.call(this) || this;\n _this.destination = destination;\n _this.source = source;\n return _this;\n }\n AnonymousSubject.prototype.next = function (value) {\n var _a, _b;\n (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.next) === null || _b === void 0 ? void 0 : _b.call(_a, value);\n };\n AnonymousSubject.prototype.error = function (err) {\n var _a, _b;\n (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.error) === null || _b === void 0 ? void 0 : _b.call(_a, err);\n };\n AnonymousSubject.prototype.complete = function () {\n var _a, _b;\n (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.complete) === null || _b === void 0 ? void 0 : _b.call(_a);\n };\n AnonymousSubject.prototype._subscribe = function (subscriber) {\n var _a, _b;\n return (_b = (_a = this.source) === null || _a === void 0 ? void 0 : _a.subscribe(subscriber)) !== null && _b !== void 0 ? _b : EMPTY_SUBSCRIPTION;\n };\n return AnonymousSubject;\n}(Subject));\nexport { AnonymousSubject };\n//# sourceMappingURL=Subject.js.map","export var dateTimestampProvider = {\n now: function () {\n return (dateTimestampProvider.delegate || Date).now();\n },\n delegate: undefined,\n};\n//# sourceMappingURL=dateTimestampProvider.js.map","import { __extends } from \"tslib\";\nimport { Subject } from './Subject';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\nvar ReplaySubject = (function (_super) {\n __extends(ReplaySubject, _super);\n function ReplaySubject(_bufferSize, _windowTime, _timestampProvider) {\n if (_bufferSize === void 0) { _bufferSize = Infinity; }\n if (_windowTime === void 0) { _windowTime = Infinity; }\n if (_timestampProvider === void 0) { _timestampProvider = dateTimestampProvider; }\n var _this = _super.call(this) || this;\n _this._bufferSize = _bufferSize;\n _this._windowTime = _windowTime;\n _this._timestampProvider = _timestampProvider;\n _this._buffer = [];\n _this._infiniteTimeWindow = true;\n _this._infiniteTimeWindow = _windowTime === Infinity;\n _this._bufferSize = Math.max(1, _bufferSize);\n _this._windowTime = Math.max(1, _windowTime);\n return _this;\n }\n ReplaySubject.prototype.next = function (value) {\n var _a = this, isStopped = _a.isStopped, _buffer = _a._buffer, _infiniteTimeWindow = _a._infiniteTimeWindow, _timestampProvider = _a._timestampProvider, _windowTime = _a._windowTime;\n if (!isStopped) {\n _buffer.push(value);\n !_infiniteTimeWindow && _buffer.push(_timestampProvider.now() + _windowTime);\n }\n this._trimBuffer();\n _super.prototype.next.call(this, value);\n };\n ReplaySubject.prototype._subscribe = function (subscriber) {\n this._throwIfClosed();\n this._trimBuffer();\n var subscription = this._innerSubscribe(subscriber);\n var _a = this, _infiniteTimeWindow = _a._infiniteTimeWindow, _buffer = _a._buffer;\n var copy = _buffer.slice();\n for (var i = 0; i < copy.length && !subscriber.closed; i += _infiniteTimeWindow ? 1 : 2) {\n subscriber.next(copy[i]);\n }\n this._checkFinalizedStatuses(subscriber);\n return subscription;\n };\n ReplaySubject.prototype._trimBuffer = function () {\n var _a = this, _bufferSize = _a._bufferSize, _timestampProvider = _a._timestampProvider, _buffer = _a._buffer, _infiniteTimeWindow = _a._infiniteTimeWindow;\n var adjustedBufferSize = (_infiniteTimeWindow ? 1 : 2) * _bufferSize;\n _bufferSize < Infinity && adjustedBufferSize < _buffer.length && _buffer.splice(0, _buffer.length - adjustedBufferSize);\n if (!_infiniteTimeWindow) {\n var now = _timestampProvider.now();\n var last = 0;\n for (var i = 1; i < _buffer.length && _buffer[i] <= now; i += 2) {\n last = i;\n }\n last && _buffer.splice(0, last + 1);\n }\n };\n return ReplaySubject;\n}(Subject));\nexport { ReplaySubject };\n//# sourceMappingURL=ReplaySubject.js.map","import { __extends } from \"tslib\";\nimport { Subscription } from '../Subscription';\nvar Action = (function (_super) {\n __extends(Action, _super);\n function Action(scheduler, work) {\n return _super.call(this) || this;\n }\n Action.prototype.schedule = function (state, delay) {\n if (delay === void 0) { delay = 0; }\n return this;\n };\n return Action;\n}(Subscription));\nexport { Action };\n//# sourceMappingURL=Action.js.map","import { __read, __spreadArray } from \"tslib\";\nexport var intervalProvider = {\n setInterval: function (handler, timeout) {\n var args = [];\n for (var _i = 2; _i < arguments.length; _i++) {\n args[_i - 2] = arguments[_i];\n }\n var delegate = intervalProvider.delegate;\n if (delegate === null || delegate === void 0 ? void 0 : delegate.setInterval) {\n return delegate.setInterval.apply(delegate, __spreadArray([handler, timeout], __read(args)));\n }\n return setInterval.apply(void 0, __spreadArray([handler, timeout], __read(args)));\n },\n clearInterval: function (handle) {\n var delegate = intervalProvider.delegate;\n return ((delegate === null || delegate === void 0 ? void 0 : delegate.clearInterval) || clearInterval)(handle);\n },\n delegate: undefined,\n};\n//# sourceMappingURL=intervalProvider.js.map","import { __extends } from \"tslib\";\nimport { Action } from './Action';\nimport { intervalProvider } from './intervalProvider';\nimport { arrRemove } from '../util/arrRemove';\nvar AsyncAction = (function (_super) {\n __extends(AsyncAction, _super);\n function AsyncAction(scheduler, work) {\n var _this = _super.call(this, scheduler, work) || this;\n _this.scheduler = scheduler;\n _this.work = work;\n _this.pending = false;\n return _this;\n }\n AsyncAction.prototype.schedule = function (state, delay) {\n var _a;\n if (delay === void 0) { delay = 0; }\n if (this.closed) {\n return this;\n }\n this.state = state;\n var id = this.id;\n var scheduler = this.scheduler;\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, delay);\n }\n this.pending = true;\n this.delay = delay;\n this.id = (_a = this.id) !== null && _a !== void 0 ? _a : this.requestAsyncId(scheduler, this.id, delay);\n return this;\n };\n AsyncAction.prototype.requestAsyncId = function (scheduler, _id, delay) {\n if (delay === void 0) { delay = 0; }\n return intervalProvider.setInterval(scheduler.flush.bind(scheduler, this), delay);\n };\n AsyncAction.prototype.recycleAsyncId = function (_scheduler, id, delay) {\n if (delay === void 0) { delay = 0; }\n if (delay != null && this.delay === delay && this.pending === false) {\n return id;\n }\n if (id != null) {\n intervalProvider.clearInterval(id);\n }\n return undefined;\n };\n AsyncAction.prototype.execute = function (state, delay) {\n if (this.closed) {\n return new Error('executing a cancelled action');\n }\n this.pending = false;\n var error = this._execute(state, delay);\n if (error) {\n return error;\n }\n else if (this.pending === false && this.id != null) {\n this.id = this.recycleAsyncId(this.scheduler, this.id, null);\n }\n };\n AsyncAction.prototype._execute = function (state, _delay) {\n var errored = false;\n var errorValue;\n try {\n this.work(state);\n }\n catch (e) {\n errored = true;\n errorValue = e ? e : new Error('Scheduled action threw falsy error');\n }\n if (errored) {\n this.unsubscribe();\n return errorValue;\n }\n };\n AsyncAction.prototype.unsubscribe = function () {\n if (!this.closed) {\n var _a = this, id = _a.id, scheduler = _a.scheduler;\n var actions = scheduler.actions;\n this.work = this.state = this.scheduler = null;\n this.pending = false;\n arrRemove(actions, this);\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, null);\n }\n this.delay = null;\n _super.prototype.unsubscribe.call(this);\n }\n };\n return AsyncAction;\n}(Action));\nexport { AsyncAction };\n//# sourceMappingURL=AsyncAction.js.map","import { dateTimestampProvider } from './scheduler/dateTimestampProvider';\nvar Scheduler = (function () {\n function Scheduler(schedulerActionCtor, now) {\n if (now === void 0) { now = Scheduler.now; }\n this.schedulerActionCtor = schedulerActionCtor;\n this.now = now;\n }\n Scheduler.prototype.schedule = function (work, delay, state) {\n if (delay === void 0) { delay = 0; }\n return new this.schedulerActionCtor(this, work).schedule(state, delay);\n };\n Scheduler.now = dateTimestampProvider.now;\n return Scheduler;\n}());\nexport { Scheduler };\n//# sourceMappingURL=Scheduler.js.map","import { __extends } from \"tslib\";\nimport { Scheduler } from '../Scheduler';\nvar AsyncScheduler = (function (_super) {\n __extends(AsyncScheduler, _super);\n function AsyncScheduler(SchedulerAction, now) {\n if (now === void 0) { now = Scheduler.now; }\n var _this = _super.call(this, SchedulerAction, now) || this;\n _this.actions = [];\n _this._active = false;\n return _this;\n }\n AsyncScheduler.prototype.flush = function (action) {\n var actions = this.actions;\n if (this._active) {\n actions.push(action);\n return;\n }\n var error;\n this._active = true;\n do {\n if ((error = action.execute(action.state, action.delay))) {\n break;\n }\n } while ((action = actions.shift()));\n this._active = false;\n if (error) {\n while ((action = actions.shift())) {\n action.unsubscribe();\n }\n throw error;\n }\n };\n return AsyncScheduler;\n}(Scheduler));\nexport { AsyncScheduler };\n//# sourceMappingURL=AsyncScheduler.js.map","import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\nexport var asyncScheduler = new AsyncScheduler(AsyncAction);\nexport var async = asyncScheduler;\n//# sourceMappingURL=async.js.map","import { Observable } from '../Observable';\nexport var EMPTY = new Observable(function (subscriber) { return subscriber.complete(); });\nexport function empty(scheduler) {\n return scheduler ? emptyScheduled(scheduler) : EMPTY;\n}\nfunction emptyScheduled(scheduler) {\n return new Observable(function (subscriber) { return scheduler.schedule(function () { return subscriber.complete(); }); });\n}\n//# sourceMappingURL=empty.js.map","import { isFunction } from './isFunction';\nexport function isScheduler(value) {\n return value && isFunction(value.schedule);\n}\n//# sourceMappingURL=isScheduler.js.map","import { isFunction } from './isFunction';\nimport { isScheduler } from './isScheduler';\nfunction last(arr) {\n return arr[arr.length - 1];\n}\nexport function popResultSelector(args) {\n return isFunction(last(args)) ? args.pop() : undefined;\n}\nexport function popScheduler(args) {\n return isScheduler(last(args)) ? args.pop() : undefined;\n}\nexport function popNumber(args, defaultValue) {\n return typeof last(args) === 'number' ? args.pop() : defaultValue;\n}\n//# sourceMappingURL=args.js.map","export var isArrayLike = (function (x) { return x && typeof x.length === 'number' && typeof x !== 'function'; });\n//# sourceMappingURL=isArrayLike.js.map","import { isFunction } from \"./isFunction\";\nexport function isPromise(value) {\n return isFunction(value === null || value === void 0 ? void 0 : value.then);\n}\n//# sourceMappingURL=isPromise.js.map","import { observable as Symbol_observable } from '../symbol/observable';\nimport { isFunction } from './isFunction';\nexport function isInteropObservable(input) {\n return isFunction(input[Symbol_observable]);\n}\n//# sourceMappingURL=isInteropObservable.js.map","import { isFunction } from './isFunction';\nexport function isAsyncIterable(obj) {\n return Symbol.asyncIterator && isFunction(obj === null || obj === void 0 ? void 0 : obj[Symbol.asyncIterator]);\n}\n//# sourceMappingURL=isAsyncIterable.js.map","export function createInvalidObservableTypeError(input) {\n return new TypeError(\"You provided \" + (input !== null && typeof input === 'object' ? 'an invalid object' : \"'\" + input + \"'\") + \" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.\");\n}\n//# sourceMappingURL=throwUnobservableError.js.map","export function getSymbolIterator() {\n if (typeof Symbol !== 'function' || !Symbol.iterator) {\n return '@@iterator';\n }\n return Symbol.iterator;\n}\nexport var iterator = getSymbolIterator();\n//# sourceMappingURL=iterator.js.map","import { iterator as Symbol_iterator } from '../symbol/iterator';\nimport { isFunction } from './isFunction';\nexport function isIterable(input) {\n return isFunction(input === null || input === void 0 ? void 0 : input[Symbol_iterator]);\n}\n//# sourceMappingURL=isIterable.js.map","import { __asyncGenerator, __await, __generator } from \"tslib\";\nimport { isFunction } from './isFunction';\nexport function readableStreamLikeToAsyncGenerator(readableStream) {\n return __asyncGenerator(this, arguments, function readableStreamLikeToAsyncGenerator_1() {\n var reader, _a, value, done;\n return __generator(this, function (_b) {\n switch (_b.label) {\n case 0:\n reader = readableStream.getReader();\n _b.label = 1;\n case 1:\n _b.trys.push([1, , 9, 10]);\n _b.label = 2;\n case 2:\n if (!true) return [3, 8];\n return [4, __await(reader.read())];\n case 3:\n _a = _b.sent(), value = _a.value, done = _a.done;\n if (!done) return [3, 5];\n return [4, __await(void 0)];\n case 4: return [2, _b.sent()];\n case 5: return [4, __await(value)];\n case 6: return [4, _b.sent()];\n case 7:\n _b.sent();\n return [3, 2];\n case 8: return [3, 10];\n case 9:\n reader.releaseLock();\n return [7];\n case 10: return [2];\n }\n });\n });\n}\nexport function isReadableStreamLike(obj) {\n return isFunction(obj === null || obj === void 0 ? void 0 : obj.getReader);\n}\n//# sourceMappingURL=isReadableStreamLike.js.map","import { __asyncValues, __awaiter, __generator, __values } from \"tslib\";\nimport { isArrayLike } from '../util/isArrayLike';\nimport { isPromise } from '../util/isPromise';\nimport { Observable } from '../Observable';\nimport { isInteropObservable } from '../util/isInteropObservable';\nimport { isAsyncIterable } from '../util/isAsyncIterable';\nimport { createInvalidObservableTypeError } from '../util/throwUnobservableError';\nimport { isIterable } from '../util/isIterable';\nimport { isReadableStreamLike, readableStreamLikeToAsyncGenerator } from '../util/isReadableStreamLike';\nimport { isFunction } from '../util/isFunction';\nimport { reportUnhandledError } from '../util/reportUnhandledError';\nimport { observable as Symbol_observable } from '../symbol/observable';\nexport function innerFrom(input) {\n if (input instanceof Observable) {\n return input;\n }\n if (input != null) {\n if (isInteropObservable(input)) {\n return fromInteropObservable(input);\n }\n if (isArrayLike(input)) {\n return fromArrayLike(input);\n }\n if (isPromise(input)) {\n return fromPromise(input);\n }\n if (isAsyncIterable(input)) {\n return fromAsyncIterable(input);\n }\n if (isIterable(input)) {\n return fromIterable(input);\n }\n if (isReadableStreamLike(input)) {\n return fromReadableStreamLike(input);\n }\n }\n throw createInvalidObservableTypeError(input);\n}\nexport function fromInteropObservable(obj) {\n return new Observable(function (subscriber) {\n var obs = obj[Symbol_observable]();\n if (isFunction(obs.subscribe)) {\n return obs.subscribe(subscriber);\n }\n throw new TypeError('Provided object does not correctly implement Symbol.observable');\n });\n}\nexport function fromArrayLike(array) {\n return new Observable(function (subscriber) {\n for (var i = 0; i < array.length && !subscriber.closed; i++) {\n subscriber.next(array[i]);\n }\n subscriber.complete();\n });\n}\nexport function fromPromise(promise) {\n return new Observable(function (subscriber) {\n promise\n .then(function (value) {\n if (!subscriber.closed) {\n subscriber.next(value);\n subscriber.complete();\n }\n }, function (err) { return subscriber.error(err); })\n .then(null, reportUnhandledError);\n });\n}\nexport function fromIterable(iterable) {\n return new Observable(function (subscriber) {\n var e_1, _a;\n try {\n for (var iterable_1 = __values(iterable), iterable_1_1 = iterable_1.next(); !iterable_1_1.done; iterable_1_1 = iterable_1.next()) {\n var value = iterable_1_1.value;\n subscriber.next(value);\n if (subscriber.closed) {\n return;\n }\n }\n }\n catch (e_1_1) { e_1 = { error: e_1_1 }; }\n finally {\n try {\n if (iterable_1_1 && !iterable_1_1.done && (_a = iterable_1.return)) _a.call(iterable_1);\n }\n finally { if (e_1) throw e_1.error; }\n }\n subscriber.complete();\n });\n}\nexport function fromAsyncIterable(asyncIterable) {\n return new Observable(function (subscriber) {\n process(asyncIterable, subscriber).catch(function (err) { return subscriber.error(err); });\n });\n}\nexport function fromReadableStreamLike(readableStream) {\n return fromAsyncIterable(readableStreamLikeToAsyncGenerator(readableStream));\n}\nfunction process(asyncIterable, subscriber) {\n var asyncIterable_1, asyncIterable_1_1;\n var e_2, _a;\n return __awaiter(this, void 0, void 0, function () {\n var value, e_2_1;\n return __generator(this, function (_b) {\n switch (_b.label) {\n case 0:\n _b.trys.push([0, 5, 6, 11]);\n asyncIterable_1 = __asyncValues(asyncIterable);\n _b.label = 1;\n case 1: return [4, asyncIterable_1.next()];\n case 2:\n if (!(asyncIterable_1_1 = _b.sent(), !asyncIterable_1_1.done)) return [3, 4];\n value = asyncIterable_1_1.value;\n subscriber.next(value);\n if (subscriber.closed) {\n return [2];\n }\n _b.label = 3;\n case 3: return [3, 1];\n case 4: return [3, 11];\n case 5:\n e_2_1 = _b.sent();\n e_2 = { error: e_2_1 };\n return [3, 11];\n case 6:\n _b.trys.push([6, , 9, 10]);\n if (!(asyncIterable_1_1 && !asyncIterable_1_1.done && (_a = asyncIterable_1.return))) return [3, 8];\n return [4, _a.call(asyncIterable_1)];\n case 7:\n _b.sent();\n _b.label = 8;\n case 8: return [3, 10];\n case 9:\n if (e_2) throw e_2.error;\n return [7];\n case 10: return [7];\n case 11:\n subscriber.complete();\n return [2];\n }\n });\n });\n}\n//# sourceMappingURL=innerFrom.js.map","export function executeSchedule(parentSubscription, scheduler, work, delay, repeat) {\n if (delay === void 0) { delay = 0; }\n if (repeat === void 0) { repeat = false; }\n var scheduleSubscription = scheduler.schedule(function () {\n work();\n if (repeat) {\n parentSubscription.add(this.schedule(null, delay));\n }\n else {\n this.unsubscribe();\n }\n }, delay);\n parentSubscription.add(scheduleSubscription);\n if (!repeat) {\n return scheduleSubscription;\n }\n}\n//# sourceMappingURL=executeSchedule.js.map","import { executeSchedule } from '../util/executeSchedule';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nexport function observeOn(scheduler, delay) {\n if (delay === void 0) { delay = 0; }\n return operate(function (source, subscriber) {\n source.subscribe(createOperatorSubscriber(subscriber, function (value) { return executeSchedule(subscriber, scheduler, function () { return subscriber.next(value); }, delay); }, function () { return executeSchedule(subscriber, scheduler, function () { return subscriber.complete(); }, delay); }, function (err) { return executeSchedule(subscriber, scheduler, function () { return subscriber.error(err); }, delay); }));\n });\n}\n//# sourceMappingURL=observeOn.js.map","import { operate } from '../util/lift';\nexport function subscribeOn(scheduler, delay) {\n if (delay === void 0) { delay = 0; }\n return operate(function (source, subscriber) {\n subscriber.add(scheduler.schedule(function () { return source.subscribe(subscriber); }, delay));\n });\n}\n//# sourceMappingURL=subscribeOn.js.map","import { Observable } from '../Observable';\nimport { executeSchedule } from '../util/executeSchedule';\nexport function scheduleAsyncIterable(input, scheduler) {\n if (!input) {\n throw new Error('Iterable cannot be null');\n }\n return new Observable(function (subscriber) {\n executeSchedule(subscriber, scheduler, function () {\n var iterator = input[Symbol.asyncIterator]();\n executeSchedule(subscriber, scheduler, function () {\n iterator.next().then(function (result) {\n if (result.done) {\n subscriber.complete();\n }\n else {\n subscriber.next(result.value);\n }\n });\n }, 0, true);\n });\n });\n}\n//# sourceMappingURL=scheduleAsyncIterable.js.map","import { scheduleObservable } from './scheduleObservable';\nimport { schedulePromise } from './schedulePromise';\nimport { scheduleArray } from './scheduleArray';\nimport { scheduleIterable } from './scheduleIterable';\nimport { scheduleAsyncIterable } from './scheduleAsyncIterable';\nimport { isInteropObservable } from '../util/isInteropObservable';\nimport { isPromise } from '../util/isPromise';\nimport { isArrayLike } from '../util/isArrayLike';\nimport { isIterable } from '../util/isIterable';\nimport { isAsyncIterable } from '../util/isAsyncIterable';\nimport { createInvalidObservableTypeError } from '../util/throwUnobservableError';\nimport { isReadableStreamLike } from '../util/isReadableStreamLike';\nimport { scheduleReadableStreamLike } from './scheduleReadableStreamLike';\nexport function scheduled(input, scheduler) {\n if (input != null) {\n if (isInteropObservable(input)) {\n return scheduleObservable(input, scheduler);\n }\n if (isArrayLike(input)) {\n return scheduleArray(input, scheduler);\n }\n if (isPromise(input)) {\n return schedulePromise(input, scheduler);\n }\n if (isAsyncIterable(input)) {\n return scheduleAsyncIterable(input, scheduler);\n }\n if (isIterable(input)) {\n return scheduleIterable(input, scheduler);\n }\n if (isReadableStreamLike(input)) {\n return scheduleReadableStreamLike(input, scheduler);\n }\n }\n throw createInvalidObservableTypeError(input);\n}\n//# sourceMappingURL=scheduled.js.map","import { innerFrom } from '../observable/innerFrom';\nimport { observeOn } from '../operators/observeOn';\nimport { subscribeOn } from '../operators/subscribeOn';\nexport function scheduleObservable(input, scheduler) {\n return innerFrom(input).pipe(subscribeOn(scheduler), observeOn(scheduler));\n}\n//# sourceMappingURL=scheduleObservable.js.map","import { Observable } from '../Observable';\nexport function scheduleArray(input, scheduler) {\n return new Observable(function (subscriber) {\n var i = 0;\n return scheduler.schedule(function () {\n if (i === input.length) {\n subscriber.complete();\n }\n else {\n subscriber.next(input[i++]);\n if (!subscriber.closed) {\n this.schedule();\n }\n }\n });\n });\n}\n//# sourceMappingURL=scheduleArray.js.map","import { innerFrom } from '../observable/innerFrom';\nimport { observeOn } from '../operators/observeOn';\nimport { subscribeOn } from '../operators/subscribeOn';\nexport function schedulePromise(input, scheduler) {\n return innerFrom(input).pipe(subscribeOn(scheduler), observeOn(scheduler));\n}\n//# sourceMappingURL=schedulePromise.js.map","import { Observable } from '../Observable';\nimport { iterator as Symbol_iterator } from '../symbol/iterator';\nimport { isFunction } from '../util/isFunction';\nimport { executeSchedule } from '../util/executeSchedule';\nexport function scheduleIterable(input, scheduler) {\n return new Observable(function (subscriber) {\n var iterator;\n executeSchedule(subscriber, scheduler, function () {\n iterator = input[Symbol_iterator]();\n executeSchedule(subscriber, scheduler, function () {\n var _a;\n var value;\n var done;\n try {\n (_a = iterator.next(), value = _a.value, done = _a.done);\n }\n catch (err) {\n subscriber.error(err);\n return;\n }\n if (done) {\n subscriber.complete();\n }\n else {\n subscriber.next(value);\n }\n }, 0, true);\n });\n return function () { return isFunction(iterator === null || iterator === void 0 ? void 0 : iterator.return) && iterator.return(); };\n });\n}\n//# sourceMappingURL=scheduleIterable.js.map","import { scheduleAsyncIterable } from './scheduleAsyncIterable';\nimport { readableStreamLikeToAsyncGenerator } from '../util/isReadableStreamLike';\nexport function scheduleReadableStreamLike(input, scheduler) {\n return scheduleAsyncIterable(readableStreamLikeToAsyncGenerator(input), scheduler);\n}\n//# sourceMappingURL=scheduleReadableStreamLike.js.map","import { scheduled } from '../scheduled/scheduled';\nimport { innerFrom } from './innerFrom';\nexport function from(input, scheduler) {\n return scheduler ? scheduled(input, scheduler) : innerFrom(input);\n}\n//# sourceMappingURL=from.js.map","import { popScheduler } from '../util/args';\nimport { from } from './from';\nexport function of() {\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n var scheduler = popScheduler(args);\n return from(args, scheduler);\n}\n//# sourceMappingURL=of.js.map","import { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nexport function map(project, thisArg) {\n return operate(function (source, subscriber) {\n var index = 0;\n source.subscribe(createOperatorSubscriber(subscriber, function (value) {\n subscriber.next(project.call(thisArg, value, index++));\n }));\n });\n}\n//# sourceMappingURL=map.js.map","import { __read, __spreadArray } from \"tslib\";\nimport { map } from \"../operators/map\";\nvar isArray = Array.isArray;\nfunction callOrApply(fn, args) {\n return isArray(args) ? fn.apply(void 0, __spreadArray([], __read(args))) : fn(args);\n}\nexport function mapOneOrManyArgs(fn) {\n return map(function (args) { return callOrApply(fn, args); });\n}\n//# sourceMappingURL=mapOneOrManyArgs.js.map","var isArray = Array.isArray;\nvar getPrototypeOf = Object.getPrototypeOf, objectProto = Object.prototype, getKeys = Object.keys;\nexport function argsArgArrayOrObject(args) {\n if (args.length === 1) {\n var first_1 = args[0];\n if (isArray(first_1)) {\n return { args: first_1, keys: null };\n }\n if (isPOJO(first_1)) {\n var keys = getKeys(first_1);\n return {\n args: keys.map(function (key) { return first_1[key]; }),\n keys: keys,\n };\n }\n }\n return { args: args, keys: null };\n}\nfunction isPOJO(obj) {\n return obj && typeof obj === 'object' && getPrototypeOf(obj) === objectProto;\n}\n//# sourceMappingURL=argsArgArrayOrObject.js.map","import { Observable } from '../Observable';\nimport { argsArgArrayOrObject } from '../util/argsArgArrayOrObject';\nimport { from } from './from';\nimport { identity } from '../util/identity';\nimport { mapOneOrManyArgs } from '../util/mapOneOrManyArgs';\nimport { popResultSelector, popScheduler } from '../util/args';\nimport { createObject } from '../util/createObject';\nimport { createOperatorSubscriber } from '../operators/OperatorSubscriber';\nimport { executeSchedule } from '../util/executeSchedule';\nexport function combineLatest() {\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n var scheduler = popScheduler(args);\n var resultSelector = popResultSelector(args);\n var _a = argsArgArrayOrObject(args), observables = _a.args, keys = _a.keys;\n if (observables.length === 0) {\n return from([], scheduler);\n }\n var result = new Observable(combineLatestInit(observables, scheduler, keys\n ?\n function (values) { return createObject(keys, values); }\n :\n identity));\n return resultSelector ? result.pipe(mapOneOrManyArgs(resultSelector)) : result;\n}\nexport function combineLatestInit(observables, scheduler, valueTransform) {\n if (valueTransform === void 0) { valueTransform = identity; }\n return function (subscriber) {\n maybeSchedule(scheduler, function () {\n var length = observables.length;\n var values = new Array(length);\n var active = length;\n var remainingFirstValues = length;\n var _loop_1 = function (i) {\n maybeSchedule(scheduler, function () {\n var source = from(observables[i], scheduler);\n var hasFirstValue = false;\n source.subscribe(createOperatorSubscriber(subscriber, function (value) {\n values[i] = value;\n if (!hasFirstValue) {\n hasFirstValue = true;\n remainingFirstValues--;\n }\n if (!remainingFirstValues) {\n subscriber.next(valueTransform(values.slice()));\n }\n }, function () {\n if (!--active) {\n subscriber.complete();\n }\n }));\n }, subscriber);\n };\n for (var i = 0; i < length; i++) {\n _loop_1(i);\n }\n }, subscriber);\n };\n}\nfunction maybeSchedule(scheduler, execute, subscription) {\n if (scheduler) {\n executeSchedule(subscription, scheduler, execute);\n }\n else {\n execute();\n }\n}\n//# sourceMappingURL=combineLatest.js.map","export function createObject(keys, values) {\n return keys.reduce(function (result, key, i) { return ((result[key] = values[i]), result); }, {});\n}\n//# sourceMappingURL=createObject.js.map","import { map } from './map';\nimport { innerFrom } from '../observable/innerFrom';\nimport { operate } from '../util/lift';\nimport { mergeInternals } from './mergeInternals';\nimport { isFunction } from '../util/isFunction';\nexport function mergeMap(project, resultSelector, concurrent) {\n if (concurrent === void 0) { concurrent = Infinity; }\n if (isFunction(resultSelector)) {\n return mergeMap(function (a, i) { return map(function (b, ii) { return resultSelector(a, b, i, ii); })(innerFrom(project(a, i))); }, concurrent);\n }\n else if (typeof resultSelector === 'number') {\n concurrent = resultSelector;\n }\n return operate(function (source, subscriber) { return mergeInternals(source, subscriber, project, concurrent); });\n}\n//# sourceMappingURL=mergeMap.js.map","import { innerFrom } from '../observable/innerFrom';\nimport { executeSchedule } from '../util/executeSchedule';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nexport function mergeInternals(source, subscriber, project, concurrent, onBeforeNext, expand, innerSubScheduler, additionalFinalizer) {\n var buffer = [];\n var active = 0;\n var index = 0;\n var isComplete = false;\n var checkComplete = function () {\n if (isComplete && !buffer.length && !active) {\n subscriber.complete();\n }\n };\n var outerNext = function (value) { return (active < concurrent ? doInnerSub(value) : buffer.push(value)); };\n var doInnerSub = function (value) {\n expand && subscriber.next(value);\n active++;\n var innerComplete = false;\n innerFrom(project(value, index++)).subscribe(createOperatorSubscriber(subscriber, function (innerValue) {\n onBeforeNext === null || onBeforeNext === void 0 ? void 0 : onBeforeNext(innerValue);\n if (expand) {\n outerNext(innerValue);\n }\n else {\n subscriber.next(innerValue);\n }\n }, function () {\n innerComplete = true;\n }, undefined, function () {\n if (innerComplete) {\n try {\n active--;\n var _loop_1 = function () {\n var bufferedValue = buffer.shift();\n if (innerSubScheduler) {\n executeSchedule(subscriber, innerSubScheduler, function () { return doInnerSub(bufferedValue); });\n }\n else {\n doInnerSub(bufferedValue);\n }\n };\n while (buffer.length && active < concurrent) {\n _loop_1();\n }\n checkComplete();\n }\n catch (err) {\n subscriber.error(err);\n }\n }\n }));\n };\n source.subscribe(createOperatorSubscriber(subscriber, outerNext, function () {\n isComplete = true;\n checkComplete();\n }));\n return function () {\n additionalFinalizer === null || additionalFinalizer === void 0 ? void 0 : additionalFinalizer();\n };\n}\n//# sourceMappingURL=mergeInternals.js.map","import { mergeMap } from './mergeMap';\nimport { identity } from '../util/identity';\nexport function mergeAll(concurrent) {\n if (concurrent === void 0) { concurrent = Infinity; }\n return mergeMap(identity, concurrent);\n}\n//# sourceMappingURL=mergeAll.js.map","import { concatAll } from '../operators/concatAll';\nimport { popScheduler } from '../util/args';\nimport { from } from './from';\nexport function concat() {\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n return concatAll()(from(args, popScheduler(args)));\n}\n//# sourceMappingURL=concat.js.map","import { mergeAll } from './mergeAll';\nexport function concatAll() {\n return mergeAll(1);\n}\n//# sourceMappingURL=concatAll.js.map","import { Observable } from '../Observable';\nimport { innerFrom } from './innerFrom';\nexport function defer(observableFactory) {\n return new Observable(function (subscriber) {\n innerFrom(observableFactory()).subscribe(subscriber);\n });\n}\n//# sourceMappingURL=defer.js.map","import { Observable } from '../Observable';\nimport { async as asyncScheduler } from '../scheduler/async';\nimport { isScheduler } from '../util/isScheduler';\nimport { isValidDate } from '../util/isDate';\nexport function timer(dueTime, intervalOrScheduler, scheduler) {\n if (dueTime === void 0) { dueTime = 0; }\n if (scheduler === void 0) { scheduler = asyncScheduler; }\n var intervalDuration = -1;\n if (intervalOrScheduler != null) {\n if (isScheduler(intervalOrScheduler)) {\n scheduler = intervalOrScheduler;\n }\n else {\n intervalDuration = intervalOrScheduler;\n }\n }\n return new Observable(function (subscriber) {\n var due = isValidDate(dueTime) ? +dueTime - scheduler.now() : dueTime;\n if (due < 0) {\n due = 0;\n }\n var n = 0;\n return scheduler.schedule(function () {\n if (!subscriber.closed) {\n subscriber.next(n++);\n if (0 <= intervalDuration) {\n this.schedule(undefined, intervalDuration);\n }\n else {\n subscriber.complete();\n }\n }\n }, due);\n });\n}\n//# sourceMappingURL=timer.js.map","export function isValidDate(value) {\n return value instanceof Date && !isNaN(value);\n}\n//# sourceMappingURL=isDate.js.map","import { mergeAll } from '../operators/mergeAll';\nimport { innerFrom } from './innerFrom';\nimport { EMPTY } from './empty';\nimport { popNumber, popScheduler } from '../util/args';\nimport { from } from './from';\nexport function merge() {\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n var scheduler = popScheduler(args);\n var concurrent = popNumber(args, Infinity);\n var sources = args;\n return !sources.length\n ?\n EMPTY\n : sources.length === 1\n ?\n innerFrom(sources[0])\n :\n mergeAll(concurrent)(from(sources, scheduler));\n}\n//# sourceMappingURL=merge.js.map","import { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nexport function filter(predicate, thisArg) {\n return operate(function (source, subscriber) {\n var index = 0;\n source.subscribe(createOperatorSubscriber(subscriber, function (value) { return predicate.call(thisArg, value, index++) && subscriber.next(value); }));\n });\n}\n//# sourceMappingURL=filter.js.map","import { EMPTY } from '../observable/empty';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nexport function take(count) {\n return count <= 0\n ?\n function () { return EMPTY; }\n : operate(function (source, subscriber) {\n var seen = 0;\n source.subscribe(createOperatorSubscriber(subscriber, function (value) {\n if (++seen <= count) {\n subscriber.next(value);\n if (count <= seen) {\n subscriber.complete();\n }\n }\n }));\n });\n}\n//# sourceMappingURL=take.js.map","import { identity } from '../util/identity';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nexport function distinctUntilChanged(comparator, keySelector) {\n if (keySelector === void 0) { keySelector = identity; }\n comparator = comparator !== null && comparator !== void 0 ? comparator : defaultCompare;\n return operate(function (source, subscriber) {\n var previousKey;\n var first = true;\n source.subscribe(createOperatorSubscriber(subscriber, function (value) {\n var currentKey = keySelector(value);\n if (first || !comparator(previousKey, currentKey)) {\n first = false;\n previousKey = currentKey;\n subscriber.next(value);\n }\n }));\n });\n}\nfunction defaultCompare(a, b) {\n return a === b;\n}\n//# sourceMappingURL=distinctUntilChanged.js.map","import { __read, __spreadArray } from \"tslib\";\nimport { concat } from '../observable/concat';\nimport { of } from '../observable/of';\nexport function endWith() {\n var values = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n values[_i] = arguments[_i];\n }\n return function (source) { return concat(source, of.apply(void 0, __spreadArray([], __read(values)))); };\n}\n//# sourceMappingURL=endWith.js.map","import { operate } from '../util/lift';\nexport function finalize(callback) {\n return operate(function (source, subscriber) {\n try {\n source.subscribe(subscriber);\n }\n finally {\n subscriber.add(callback);\n }\n });\n}\n//# sourceMappingURL=finalize.js.map","import { __read, __spreadArray } from \"tslib\";\nimport { operate } from '../util/lift';\nimport { mergeAll } from './mergeAll';\nimport { popNumber, popScheduler } from '../util/args';\nimport { from } from '../observable/from';\nexport function merge() {\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n var scheduler = popScheduler(args);\n var concurrent = popNumber(args, Infinity);\n return operate(function (source, subscriber) {\n mergeAll(concurrent)(from(__spreadArray([source], __read(args)), scheduler)).subscribe(subscriber);\n });\n}\n//# sourceMappingURL=merge.js.map","import { __read, __spreadArray } from \"tslib\";\nimport { merge } from './merge';\nexport function mergeWith() {\n var otherSources = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n otherSources[_i] = arguments[_i];\n }\n return merge.apply(void 0, __spreadArray([], __read(otherSources)));\n}\n//# sourceMappingURL=mergeWith.js.map","import { operate } from '../util/lift';\nimport { scanInternals } from './scanInternals';\nexport function scan(accumulator, seed) {\n return operate(scanInternals(accumulator, seed, arguments.length >= 2, true));\n}\n//# sourceMappingURL=scan.js.map","import { createOperatorSubscriber } from './OperatorSubscriber';\nexport function scanInternals(accumulator, seed, hasSeed, emitOnNext, emitBeforeComplete) {\n return function (source, subscriber) {\n var hasState = hasSeed;\n var state = seed;\n var index = 0;\n source.subscribe(createOperatorSubscriber(subscriber, function (value) {\n var i = index++;\n state = hasState\n ?\n accumulator(state, value, i)\n :\n ((hasState = true), value);\n emitOnNext && subscriber.next(state);\n }, emitBeforeComplete &&\n (function () {\n hasState && subscriber.next(state);\n subscriber.complete();\n })));\n };\n}\n//# sourceMappingURL=scanInternals.js.map","import { __read, __spreadArray } from \"tslib\";\nimport { innerFrom } from '../observable/innerFrom';\nimport { Subject } from '../Subject';\nimport { SafeSubscriber } from '../Subscriber';\nimport { operate } from '../util/lift';\nexport function share(options) {\n if (options === void 0) { options = {}; }\n var _a = options.connector, connector = _a === void 0 ? function () { return new Subject(); } : _a, _b = options.resetOnError, resetOnError = _b === void 0 ? true : _b, _c = options.resetOnComplete, resetOnComplete = _c === void 0 ? true : _c, _d = options.resetOnRefCountZero, resetOnRefCountZero = _d === void 0 ? true : _d;\n return function (wrapperSource) {\n var connection;\n var resetConnection;\n var subject;\n var refCount = 0;\n var hasCompleted = false;\n var hasErrored = false;\n var cancelReset = function () {\n resetConnection === null || resetConnection === void 0 ? void 0 : resetConnection.unsubscribe();\n resetConnection = undefined;\n };\n var reset = function () {\n cancelReset();\n connection = subject = undefined;\n hasCompleted = hasErrored = false;\n };\n var resetAndUnsubscribe = function () {\n var conn = connection;\n reset();\n conn === null || conn === void 0 ? void 0 : conn.unsubscribe();\n };\n return operate(function (source, subscriber) {\n refCount++;\n if (!hasErrored && !hasCompleted) {\n cancelReset();\n }\n var dest = (subject = subject !== null && subject !== void 0 ? subject : connector());\n subscriber.add(function () {\n refCount--;\n if (refCount === 0 && !hasErrored && !hasCompleted) {\n resetConnection = handleReset(resetAndUnsubscribe, resetOnRefCountZero);\n }\n });\n dest.subscribe(subscriber);\n if (!connection &&\n refCount > 0) {\n connection = new SafeSubscriber({\n next: function (value) { return dest.next(value); },\n error: function (err) {\n hasErrored = true;\n cancelReset();\n resetConnection = handleReset(reset, resetOnError, err);\n dest.error(err);\n },\n complete: function () {\n hasCompleted = true;\n cancelReset();\n resetConnection = handleReset(reset, resetOnComplete);\n dest.complete();\n },\n });\n innerFrom(source).subscribe(connection);\n }\n })(wrapperSource);\n };\n}\nfunction handleReset(reset, on) {\n var args = [];\n for (var _i = 2; _i < arguments.length; _i++) {\n args[_i - 2] = arguments[_i];\n }\n if (on === true) {\n reset();\n return;\n }\n if (on === false) {\n return;\n }\n var onSubscriber = new SafeSubscriber({\n next: function () {\n onSubscriber.unsubscribe();\n reset();\n },\n });\n return innerFrom(on.apply(void 0, __spreadArray([], __read(args)))).subscribe(onSubscriber);\n}\n//# sourceMappingURL=share.js.map","import { innerFrom } from '../observable/innerFrom';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nexport function switchMap(project, resultSelector) {\n return operate(function (source, subscriber) {\n var innerSubscriber = null;\n var index = 0;\n var isComplete = false;\n var checkComplete = function () { return isComplete && !innerSubscriber && subscriber.complete(); };\n source.subscribe(createOperatorSubscriber(subscriber, function (value) {\n innerSubscriber === null || innerSubscriber === void 0 ? void 0 : innerSubscriber.unsubscribe();\n var innerIndex = 0;\n var outerIndex = index++;\n innerFrom(project(value, outerIndex)).subscribe((innerSubscriber = createOperatorSubscriber(subscriber, function (innerValue) { return subscriber.next(resultSelector ? resultSelector(value, innerValue, outerIndex, innerIndex++) : innerValue); }, function () {\n innerSubscriber = null;\n checkComplete();\n })));\n }, function () {\n isComplete = true;\n checkComplete();\n }));\n });\n}\n//# sourceMappingURL=switchMap.js.map","import { isFunction } from '../util/isFunction';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nimport { identity } from '../util/identity';\nexport function tap(observerOrNext, error, complete) {\n var tapObserver = isFunction(observerOrNext) || error || complete\n ?\n { next: observerOrNext, error: error, complete: complete }\n : observerOrNext;\n return tapObserver\n ? operate(function (source, subscriber) {\n var _a;\n (_a = tapObserver.subscribe) === null || _a === void 0 ? void 0 : _a.call(tapObserver);\n var isUnsub = true;\n source.subscribe(createOperatorSubscriber(subscriber, function (value) {\n var _a;\n (_a = tapObserver.next) === null || _a === void 0 ? void 0 : _a.call(tapObserver, value);\n subscriber.next(value);\n }, function () {\n var _a;\n isUnsub = false;\n (_a = tapObserver.complete) === null || _a === void 0 ? void 0 : _a.call(tapObserver);\n subscriber.complete();\n }, function (err) {\n var _a;\n isUnsub = false;\n (_a = tapObserver.error) === null || _a === void 0 ? void 0 : _a.call(tapObserver, err);\n subscriber.error(err);\n }, function () {\n var _a, _b;\n if (isUnsub) {\n (_a = tapObserver.unsubscribe) === null || _a === void 0 ? void 0 : _a.call(tapObserver);\n }\n (_b = tapObserver.finalize) === null || _b === void 0 ? void 0 : _b.call(tapObserver);\n }));\n })\n :\n identity;\n}\n//# sourceMappingURL=tap.js.map","/** Tests if a tag has at least two indexes, and optionally the value of the first */\nexport function isNameValueTag(tag, name) {\n return tag[0] !== undefined && tag[1] !== undefined && (name ? tag[0] === name : true);\n}\n/** Checks if tag is an \"e\" tag and has at least one value */\nexport function isETag(tag) {\n return isNameValueTag(tag, \"e\");\n}\n/** Checks if tag is an \"p\" tag and has at least one value */\nexport function isPTag(tag) {\n return isNameValueTag(tag, \"p\");\n}\n/** Checks if tag is an \"r\" tag and has at least one value */\nexport function isRTag(tag) {\n return isNameValueTag(tag, \"r\");\n}\n/** Checks if tag is an \"d\" tag and has at least one value */\nexport function isDTag(tag) {\n return isNameValueTag(tag, \"d\");\n}\n/** Checks if tag is an \"a\" tag and has at least one value */\nexport function isATag(tag) {\n return isNameValueTag(tag, \"a\");\n}\n/** Checks if tag is an \"a\" tag and has at least one value */\nexport function isTTag(tag) {\n return isNameValueTag(tag, \"t\");\n}\n/** Filter and transform tags */\nexport const processTags = (tags, ...fns) => {\n return fns.reduce((step, fn) => {\n const next = [];\n for (const value of step) {\n try {\n const result = fn(value);\n if (result === undefined)\n continue; // value is undefined, ignore\n next.push(result);\n }\n catch (error) {\n // failed to process value, ignore\n }\n }\n return next;\n }, tags);\n};\n","// pure.ts\nimport { schnorr } from \"@noble/curves/secp256k1\";\nimport { bytesToHex as bytesToHex2 } from \"@noble/hashes/utils\";\n\n// core.ts\nvar verifiedSymbol = Symbol(\"verified\");\nvar isRecord = (obj) => obj instanceof Object;\nfunction validateEvent(event) {\n if (!isRecord(event))\n return false;\n if (typeof event.kind !== \"number\")\n return false;\n if (typeof event.content !== \"string\")\n return false;\n if (typeof event.created_at !== \"number\")\n return false;\n if (typeof event.pubkey !== \"string\")\n return false;\n if (!event.pubkey.match(/^[a-f0-9]{64}$/))\n return false;\n if (!Array.isArray(event.tags))\n return false;\n for (let i2 = 0; i2 < event.tags.length; i2++) {\n let tag = event.tags[i2];\n if (!Array.isArray(tag))\n return false;\n for (let j = 0; j < tag.length; j++) {\n if (typeof tag[j] !== \"string\")\n return false;\n }\n }\n return true;\n}\nfunction sortEvents(events) {\n return events.sort((a, b) => {\n if (a.created_at !== b.created_at) {\n return b.created_at - a.created_at;\n }\n return a.id.localeCompare(b.id);\n });\n}\n\n// pure.ts\nimport { sha256 } from \"@noble/hashes/sha256\";\n\n// utils.ts\nimport { bytesToHex, hexToBytes } from \"@noble/hashes/utils\";\nvar utf8Decoder = new TextDecoder(\"utf-8\");\nvar utf8Encoder = new TextEncoder();\n\n// pure.ts\nvar JS = class {\n generateSecretKey() {\n return schnorr.utils.randomPrivateKey();\n }\n getPublicKey(secretKey) {\n return bytesToHex2(schnorr.getPublicKey(secretKey));\n }\n finalizeEvent(t, secretKey) {\n const event = t;\n event.pubkey = bytesToHex2(schnorr.getPublicKey(secretKey));\n event.id = getEventHash(event);\n event.sig = bytesToHex2(schnorr.sign(getEventHash(event), secretKey));\n event[verifiedSymbol] = true;\n return event;\n }\n verifyEvent(event) {\n if (typeof event[verifiedSymbol] === \"boolean\")\n return event[verifiedSymbol];\n const hash = getEventHash(event);\n if (hash !== event.id) {\n event[verifiedSymbol] = false;\n return false;\n }\n try {\n const valid = schnorr.verify(event.sig, hash, event.pubkey);\n event[verifiedSymbol] = valid;\n return valid;\n } catch (err) {\n event[verifiedSymbol] = false;\n return false;\n }\n }\n};\nfunction serializeEvent(evt) {\n if (!validateEvent(evt))\n throw new Error(\"can't serialize event with wrong or missing properties\");\n return JSON.stringify([0, evt.pubkey, evt.created_at, evt.kind, evt.tags, evt.content]);\n}\nfunction getEventHash(event) {\n let eventHash = sha256(utf8Encoder.encode(serializeEvent(event)));\n return bytesToHex2(eventHash);\n}\nvar i = new JS();\nvar generateSecretKey = i.generateSecretKey;\nvar getPublicKey = i.getPublicKey;\nvar finalizeEvent = i.finalizeEvent;\nvar verifyEvent = i.verifyEvent;\nexport {\n finalizeEvent,\n generateSecretKey,\n getEventHash,\n getPublicKey,\n serializeEvent,\n sortEvents,\n validateEvent,\n verifiedSymbol,\n verifyEvent\n};\n","export function getCachedValue(event, symbol) {\n return Reflect.get(event, symbol);\n}\nexport function setCachedValue(event, symbol, value) {\n Reflect.set(event, symbol, value);\n}\n/** Internal method used to cache computed values on events */\nexport function getOrComputeCachedValue(event, symbol, compute) {\n if (Reflect.has(event, symbol)) {\n return Reflect.get(event, symbol);\n }\n else {\n const value = compute();\n Reflect.set(event, symbol, value);\n return value;\n }\n}\n","// utils.ts\nimport { bytesToHex, hexToBytes } from \"@noble/hashes/utils\";\nvar utf8Decoder = new TextDecoder(\"utf-8\");\nvar utf8Encoder = new TextEncoder();\nfunction normalizeURL(url) {\n try {\n if (url.indexOf(\"://\") === -1)\n url = \"wss://\" + url;\n let p = new URL(url);\n p.pathname = p.pathname.replace(/\\/+/g, \"/\");\n if (p.pathname.endsWith(\"/\"))\n p.pathname = p.pathname.slice(0, -1);\n if (p.port === \"80\" && p.protocol === \"ws:\" || p.port === \"443\" && p.protocol === \"wss:\")\n p.port = \"\";\n p.searchParams.sort();\n p.hash = \"\";\n return p.toString();\n } catch (e) {\n throw new Error(`Invalid URL: ${url}`);\n }\n}\nfunction insertEventIntoDescendingList(sortedArray, event) {\n const [idx, found] = binarySearch(sortedArray, (b) => {\n if (event.id === b.id)\n return 0;\n if (event.created_at === b.created_at)\n return -1;\n return b.created_at - event.created_at;\n });\n if (!found) {\n sortedArray.splice(idx, 0, event);\n }\n return sortedArray;\n}\nfunction insertEventIntoAscendingList(sortedArray, event) {\n const [idx, found] = binarySearch(sortedArray, (b) => {\n if (event.id === b.id)\n return 0;\n if (event.created_at === b.created_at)\n return -1;\n return event.created_at - b.created_at;\n });\n if (!found) {\n sortedArray.splice(idx, 0, event);\n }\n return sortedArray;\n}\nfunction binarySearch(arr, compare) {\n let start = 0;\n let end = arr.length - 1;\n while (start <= end) {\n const mid = Math.floor((start + end) / 2);\n const cmp = compare(arr[mid]);\n if (cmp === 0) {\n return [mid, true];\n }\n if (cmp < 0) {\n end = mid - 1;\n } else {\n start = mid + 1;\n }\n }\n return [start, false];\n}\nvar QueueNode = class {\n value;\n next = null;\n prev = null;\n constructor(message) {\n this.value = message;\n }\n};\nvar Queue = class {\n first;\n last;\n constructor() {\n this.first = null;\n this.last = null;\n }\n enqueue(value) {\n const newNode = new QueueNode(value);\n if (!this.last) {\n this.first = newNode;\n this.last = newNode;\n } else if (this.last === this.first) {\n this.last = newNode;\n this.last.prev = this.first;\n this.first.next = newNode;\n } else {\n newNode.prev = this.last;\n this.last.next = newNode;\n this.last = newNode;\n }\n return true;\n }\n dequeue() {\n if (!this.first)\n return null;\n if (this.first === this.last) {\n const target2 = this.first;\n this.first = null;\n this.last = null;\n return target2.value;\n }\n const target = this.first;\n this.first = target.next;\n if (this.first) {\n this.first.prev = null;\n }\n return target.value;\n }\n};\nexport {\n Queue,\n QueueNode,\n binarySearch,\n bytesToHex,\n hexToBytes,\n insertEventIntoAscendingList,\n insertEventIntoDescendingList,\n normalizeURL,\n utf8Decoder,\n utf8Encoder\n};\n","import { verifiedSymbol, verifyEvent } from \"nostr-tools/pure\";\nimport { isAddressableKind, isReplaceableKind } from \"nostr-tools/kinds\";\nimport { getOrComputeCachedValue } from \"./cache.js\";\n// Re-export types from nostr-tools\nexport { verifiedSymbol, verifyEvent } from \"nostr-tools/pure\";\nexport { bytesToHex, hexToBytes, insertEventIntoAscendingList, insertEventIntoDescendingList, binarySearch, } from \"nostr-tools/utils\";\nexport * as kinds from \"nostr-tools/kinds\";\n/** A symbol on an event that marks which event store its part of */\nexport const EventStoreSymbol = Symbol.for(\"event-store\");\nexport const EventUIDSymbol = Symbol.for(\"event-uid\");\nexport const ReplaceableAddressSymbol = Symbol.for(\"replaceable-address\");\nexport const FromCacheSymbol = Symbol.for(\"from-cache\");\nexport const ReplaceableIdentifierSymbol = Symbol.for(\"replaceable-identifier\");\n/**\n * Checks if an object is a nostr event\n * NOTE: does not validate the signature on the event\n */\nexport function isEvent(event) {\n if (event === undefined || event === null)\n return false;\n return (event.id?.length === 64 &&\n typeof event.sig === \"string\" &&\n typeof event.pubkey === \"string\" &&\n event.pubkey.length === 64 &&\n typeof event.content === \"string\" &&\n Array.isArray(event.tags) &&\n typeof event.created_at === \"number\" &&\n event.created_at > 0);\n}\n/**\n * Returns if a kind is replaceable ( 10000 <= n < 20000 || n == 0 || n == 3 )\n * or parameterized replaceable ( 30000 <= n < 40000 )\n */\nexport function isReplaceable(kind) {\n return isReplaceableKind(kind) || isAddressableKind(kind);\n}\n/**\n * Returns the events Unique ID\n * For normal or ephemeral events this is ( event.id )\n * For replaceable events this is ( event.kind + \":\" + event.pubkey + \":\" )\n * For parametrized replaceable events this is ( event.kind + \":\" + event.pubkey + \":\" + event.tags.d )\n */\nexport function getEventUID(event) {\n let uid = Reflect.get(event, EventUIDSymbol);\n if (!uid) {\n if (isAddressableKind(event.kind) || isReplaceableKind(event.kind))\n uid = getReplaceableAddress(event);\n else\n uid = event.id;\n Reflect.set(event, EventUIDSymbol, uid);\n }\n return uid;\n}\n/** Returns the replaceable event address for an addressable event */\nexport function getReplaceableAddress(event) {\n if (!isAddressableKind(event.kind) && !isReplaceableKind(event.kind))\n throw new Error(\"Event is not replaceable or addressable\");\n return getOrComputeCachedValue(event, ReplaceableAddressSymbol, () => {\n return createReplaceableAddress(event.kind, event.pubkey, getReplaceableIdentifier(event));\n });\n}\n/** Creates a replaceable event address from a kind, pubkey, and identifier */\nexport function createReplaceableAddress(kind, pubkey, identifier) {\n return kind + \":\" + pubkey + \":\" + (identifier ?? \"\");\n}\n/** @deprecated use createReplaceableAddress instead */\nexport const getReplaceableUID = createReplaceableAddress;\n// Internal method for verifying events (used by zaps, gift-wraps, etc)\nlet verifyWrappedEventMethod = verifyEvent;\n/** Sets the internal method used to verify events in helpers (zaps, gift-wraps, etc) */\nexport function setVerifyWrappedEventMethod(method) {\n verifyWrappedEventMethod = method;\n}\n/** Verifies an internal (wrapped) event using the set internal verification method */\nexport function verifyWrappedEvent(event) {\n return verifyWrappedEventMethod(event);\n}\n/** Sets events verified flag without checking anything */\nexport function fakeVerifyEvent(event) {\n event[verifiedSymbol] = true;\n return true;\n}\n/** Marks an event as being from a cache */\nexport function markFromCache(event) {\n Reflect.set(event, FromCacheSymbol, true);\n}\n/** Returns if an event was from a cache */\nexport function isFromCache(event) {\n return Reflect.get(event, FromCacheSymbol) === true;\n}\n/** Returns the EventStore of an event if its been added to one */\nexport function getParentEventStore(event) {\n return Reflect.get(event, EventStoreSymbol);\n}\n/** Notifies the events parent store that an event has been updated */\nexport function notifyEventUpdate(event) {\n if (!isEvent(event))\n return;\n const eventStore = getParentEventStore(event);\n if (eventStore)\n eventStore.update(event);\n}\n/** Returns the replaceable identifier for a replaceable event */\nexport function getReplaceableIdentifier(event) {\n return getOrComputeCachedValue(event, ReplaceableIdentifierSymbol, () => {\n return event.tags.find((t) => t[0] === \"d\")?.[1] ?? \"\";\n });\n}\n/** Checks if an event is a NIP-70 protected event */\nexport function isProtectedEvent(event) {\n return event.tags.some((t) => t[0] === \"-\");\n}\n","/** Returns the current unix timestamp */\nexport function unixNow() {\n return Math.round(Date.now() / 1000);\n}\n","import { getOrComputeCachedValue } from \"./cache.js\";\nimport { unixNow } from \"./time.js\";\nexport const ExpirationTimestampSymbol = Symbol(\"expiration-timestamp\");\n/** Returns the NIP-40 expiration timestamp for an event */\nexport function getExpirationTimestamp(event) {\n return getOrComputeCachedValue(event, ExpirationTimestampSymbol, () => {\n const expiration = event.tags.find((t) => t[0] === \"expiration\")?.[1];\n return expiration ? parseInt(expiration) : undefined;\n });\n}\n/** Checks if an event has expired based on the NIP-40 expiration timestamp */\nexport function isExpired(event) {\n const expiration = getExpirationTimestamp(event);\n return expiration ? unixNow() > expiration : false;\n}\n","// nip19.ts\nimport { bytesToHex as bytesToHex2, concatBytes, hexToBytes as hexToBytes2 } from \"@noble/hashes/utils\";\nimport { bech32 } from \"@scure/base\";\n\n// utils.ts\nimport { bytesToHex, hexToBytes } from \"@noble/hashes/utils\";\nvar utf8Decoder = new TextDecoder(\"utf-8\");\nvar utf8Encoder = new TextEncoder();\n\n// nip19.ts\nvar NostrTypeGuard = {\n isNProfile: (value) => /^nprofile1[a-z\\d]+$/.test(value || \"\"),\n isNEvent: (value) => /^nevent1[a-z\\d]+$/.test(value || \"\"),\n isNAddr: (value) => /^naddr1[a-z\\d]+$/.test(value || \"\"),\n isNSec: (value) => /^nsec1[a-z\\d]{58}$/.test(value || \"\"),\n isNPub: (value) => /^npub1[a-z\\d]{58}$/.test(value || \"\"),\n isNote: (value) => /^note1[a-z\\d]+$/.test(value || \"\"),\n isNcryptsec: (value) => /^ncryptsec1[a-z\\d]+$/.test(value || \"\")\n};\nvar Bech32MaxSize = 5e3;\nvar BECH32_REGEX = /[\\x21-\\x7E]{1,83}1[023456789acdefghjklmnpqrstuvwxyz]{6,}/;\nfunction integerToUint8Array(number) {\n const uint8Array = new Uint8Array(4);\n uint8Array[0] = number >> 24 & 255;\n uint8Array[1] = number >> 16 & 255;\n uint8Array[2] = number >> 8 & 255;\n uint8Array[3] = number & 255;\n return uint8Array;\n}\nfunction decodeNostrURI(nip19code) {\n try {\n if (nip19code.startsWith(\"nostr:\"))\n nip19code = nip19code.substring(6);\n return decode(nip19code);\n } catch (_err) {\n return { type: \"invalid\", data: null };\n }\n}\nfunction decode(code) {\n let { prefix, words } = bech32.decode(code, Bech32MaxSize);\n let data = new Uint8Array(bech32.fromWords(words));\n switch (prefix) {\n case \"nprofile\": {\n let tlv = parseTLV(data);\n if (!tlv[0]?.[0])\n throw new Error(\"missing TLV 0 for nprofile\");\n if (tlv[0][0].length !== 32)\n throw new Error(\"TLV 0 should be 32 bytes\");\n return {\n type: \"nprofile\",\n data: {\n pubkey: bytesToHex2(tlv[0][0]),\n relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : []\n }\n };\n }\n case \"nevent\": {\n let tlv = parseTLV(data);\n if (!tlv[0]?.[0])\n throw new Error(\"missing TLV 0 for nevent\");\n if (tlv[0][0].length !== 32)\n throw new Error(\"TLV 0 should be 32 bytes\");\n if (tlv[2] && tlv[2][0].length !== 32)\n throw new Error(\"TLV 2 should be 32 bytes\");\n if (tlv[3] && tlv[3][0].length !== 4)\n throw new Error(\"TLV 3 should be 4 bytes\");\n return {\n type: \"nevent\",\n data: {\n id: bytesToHex2(tlv[0][0]),\n relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [],\n author: tlv[2]?.[0] ? bytesToHex2(tlv[2][0]) : void 0,\n kind: tlv[3]?.[0] ? parseInt(bytesToHex2(tlv[3][0]), 16) : void 0\n }\n };\n }\n case \"naddr\": {\n let tlv = parseTLV(data);\n if (!tlv[0]?.[0])\n throw new Error(\"missing TLV 0 for naddr\");\n if (!tlv[2]?.[0])\n throw new Error(\"missing TLV 2 for naddr\");\n if (tlv[2][0].length !== 32)\n throw new Error(\"TLV 2 should be 32 bytes\");\n if (!tlv[3]?.[0])\n throw new Error(\"missing TLV 3 for naddr\");\n if (tlv[3][0].length !== 4)\n throw new Error(\"TLV 3 should be 4 bytes\");\n return {\n type: \"naddr\",\n data: {\n identifier: utf8Decoder.decode(tlv[0][0]),\n pubkey: bytesToHex2(tlv[2][0]),\n kind: parseInt(bytesToHex2(tlv[3][0]), 16),\n relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : []\n }\n };\n }\n case \"nsec\":\n return { type: prefix, data };\n case \"npub\":\n case \"note\":\n return { type: prefix, data: bytesToHex2(data) };\n default:\n throw new Error(`unknown prefix ${prefix}`);\n }\n}\nfunction parseTLV(data) {\n let result = {};\n let rest = data;\n while (rest.length > 0) {\n let t = rest[0];\n let l = rest[1];\n let v = rest.slice(2, 2 + l);\n rest = rest.slice(2 + l);\n if (v.length < l)\n throw new Error(`not enough data to read on TLV ${t}`);\n result[t] = result[t] || [];\n result[t].push(v);\n }\n return result;\n}\nfunction nsecEncode(key) {\n return encodeBytes(\"nsec\", key);\n}\nfunction npubEncode(hex) {\n return encodeBytes(\"npub\", hexToBytes2(hex));\n}\nfunction noteEncode(hex) {\n return encodeBytes(\"note\", hexToBytes2(hex));\n}\nfunction encodeBech32(prefix, data) {\n let words = bech32.toWords(data);\n return bech32.encode(prefix, words, Bech32MaxSize);\n}\nfunction encodeBytes(prefix, bytes) {\n return encodeBech32(prefix, bytes);\n}\nfunction nprofileEncode(profile) {\n let data = encodeTLV({\n 0: [hexToBytes2(profile.pubkey)],\n 1: (profile.relays || []).map((url) => utf8Encoder.encode(url))\n });\n return encodeBech32(\"nprofile\", data);\n}\nfunction neventEncode(event) {\n let kindArray;\n if (event.kind !== void 0) {\n kindArray = integerToUint8Array(event.kind);\n }\n let data = encodeTLV({\n 0: [hexToBytes2(event.id)],\n 1: (event.relays || []).map((url) => utf8Encoder.encode(url)),\n 2: event.author ? [hexToBytes2(event.author)] : [],\n 3: kindArray ? [new Uint8Array(kindArray)] : []\n });\n return encodeBech32(\"nevent\", data);\n}\nfunction naddrEncode(addr) {\n let kind = new ArrayBuffer(4);\n new DataView(kind).setUint32(0, addr.kind, false);\n let data = encodeTLV({\n 0: [utf8Encoder.encode(addr.identifier)],\n 1: (addr.relays || []).map((url) => utf8Encoder.encode(url)),\n 2: [hexToBytes2(addr.pubkey)],\n 3: [new Uint8Array(kind)]\n });\n return encodeBech32(\"naddr\", data);\n}\nfunction encodeTLV(tlv) {\n let entries = [];\n Object.entries(tlv).reverse().forEach(([t, vs]) => {\n vs.forEach((v) => {\n let entry = new Uint8Array(v.length + 2);\n entry.set([parseInt(t)], 0);\n entry.set([v.length], 1);\n entry.set(v, 2);\n entries.push(entry);\n });\n });\n return concatBytes(...entries);\n}\nexport {\n BECH32_REGEX,\n Bech32MaxSize,\n NostrTypeGuard,\n decode,\n decodeNostrURI,\n encodeBytes,\n naddrEncode,\n neventEncode,\n noteEncode,\n nprofileEncode,\n npubEncode,\n nsecEncode\n};\n","export const convertToUrl = (url) => (url instanceof URL ? url : new URL(url));\nexport const getURLFilename = (url) => url.pathname.split(\"/\").pop()?.toLocaleLowerCase() || url.searchParams.get(\"filename\")?.toLocaleLowerCase();\nexport const IMAGE_EXT = [\".svg\", \".gif\", \".png\", \".jpg\", \".jpeg\", \".webp\", \".avif\"];\nexport const VIDEO_EXT = [\".mp4\", \".mkv\", \".webm\", \".mov\"];\nexport const STREAM_EXT = [\".m3u8\"];\nexport const AUDIO_EXT = [\".mp3\", \".wav\", \".ogg\", \".aac\", \".m4a\"];\n/** Checks if a url is a image URL */\nexport function isImageURL(url) {\n url = convertToUrl(url);\n const filename = getURLFilename(url);\n return !!filename && IMAGE_EXT.some((ext) => filename.endsWith(ext));\n}\n/** Checks if a url is a video URL */\nexport function isVideoURL(url) {\n url = convertToUrl(url);\n const filename = getURLFilename(url);\n return !!filename && VIDEO_EXT.some((ext) => filename.endsWith(ext));\n}\n/** Checks if a url is a stream URL */\nexport function isStreamURL(url) {\n url = convertToUrl(url);\n const filename = getURLFilename(url);\n return !!filename && STREAM_EXT.some((ext) => filename.endsWith(ext));\n}\n/** Checks if a url is a audio URL */\nexport function isAudioURL(url) {\n url = convertToUrl(url);\n const filename = getURLFilename(url);\n return !!filename && AUDIO_EXT.some((ext) => filename.endsWith(ext));\n}\n/** Tests if two URLs are the same */\nexport function isSameURL(a, b) {\n try {\n a = normalizeURL(a);\n b = normalizeURL(b);\n return a === b;\n }\n catch (error) {\n return false;\n }\n}\n/** Adds a protocol to a URL string if its missing one */\nexport function ensureProtocol(url, protocol = \"https:\") {\n // Check if the URL already has a protocol\n if (/^[a-zA-Z][a-zA-Z0-9+.-]+:/.test(url))\n return url;\n return protocol + \"//\" + url;\n}\n/** Converts a domain or HTTP URL to a WebSocket URL */\nexport function ensureWebSocketURL(url) {\n const p = typeof url === \"string\" ? new URL(ensureProtocol(url, \"wss:\")) : new URL(url);\n if (p.protocol === \"http:\")\n p.protocol = \"ws:\";\n else if (p.protocol === \"https:\")\n p.protocol = \"wss:\";\n else\n p.protocol = \"wss:\";\n // return a string if a string was passed in\n // @ts-expect-error\n return typeof url === \"string\" ? p.toString() : p;\n}\n/** Converts a domain or WS URL to a HTTP URL */\nexport function ensureHttpURL(url) {\n const p = typeof url === \"string\" ? new URL(ensureProtocol(url, \"http:\")) : new URL(url);\n if (p.protocol === \"ws:\")\n p.protocol = \"http:\";\n else if (p.protocol === \"wss:\")\n p.protocol = \"https:\";\n else\n p.protocol = \"https:\";\n // return a string if a string was passed in\n // @ts-expect-error\n return typeof url === \"string\" ? p.toString() : p;\n}\n/**\n * Normalizes a string into a relay URL\n * Does not remove the trailing slash\n */\nexport function normalizeURL(url) {\n let p = new URL(url);\n // Remove any double slashes\n p.pathname = p.pathname.replace(/\\/+/g, \"/\");\n // Remove the port if its not needed\n if ((p.port === \"80\" && (p.protocol === \"ws:\" || p.protocol === \"http:\")) ||\n (p.port === \"443\" && (p.protocol === \"wss:\" || p.protocol === \"https:\")))\n p.port = \"\";\n // Return a string if a string was passed in\n // @ts-expect-error\n return typeof url === \"string\" ? p.toString() : p;\n}\n","import { normalizeURL } from \"./url.js\";\nexport const SeenRelaysSymbol = Symbol.for(\"seen-relays\");\n/** Marks an event as being seen on a relay */\nexport function addSeenRelay(event, relay) {\n if (!event[SeenRelaysSymbol])\n event[SeenRelaysSymbol] = new Set();\n event[SeenRelaysSymbol].add(relay);\n return event[SeenRelaysSymbol];\n}\n/** Returns the set of relays this event was seen on */\nexport function getSeenRelays(event) {\n return event[SeenRelaysSymbol];\n}\nconst WEBSOCKET_URL_CHECK = /^wss?:\\/\\/([-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}|localhost)\\b([-a-zA-Z0-9()@:%_\\+.~#?&\\/\\/=]*)$/;\n/** A fast check to make sure relay hints are safe to connect to */\nexport function isSafeRelayURL(relay) {\n // anything smaller than 8 is not a URL\n return relay.length >= 8 && WEBSOCKET_URL_CHECK.test(relay);\n}\n/** Merge multiple sets of relays and remove duplicates (ignores invalid URLs) */\nexport function mergeRelaySets(...sources) {\n const set = new Set();\n for (const src of sources) {\n if (!src)\n continue;\n if (typeof src === \"string\") {\n // Source is a string\n try {\n const safe = normalizeURL(src).toString();\n if (safe)\n set.add(safe);\n }\n catch (error) {\n // failed to parse URL, ignore\n }\n }\n else {\n // Source is iterable\n for (const url of src) {\n try {\n const safe = normalizeURL(url).toString();\n if (safe)\n set.add(safe);\n }\n catch (error) {\n // failed to parse URL, ignore\n }\n }\n }\n }\n return Array.from(set);\n}\n/** Alias for {@link mergeRelaySets} */\nexport const relaySet = mergeRelaySets;\n","/** Tests if a string is hex */\nexport function isHex(str) {\n if (str?.match(/^[0-9a-f]+$/i))\n return true;\n return false;\n}\n/** Tests if a string is a 64 length hex string */\nexport function isHexKey(key) {\n if (key?.toLowerCase()?.match(/^[0-9a-f]{64}$/))\n return true;\n return false;\n}\nexport function stripInvisibleChar(str) {\n return str && str.replaceAll(/[\\p{Cf}\\p{Zs}]/gu, \"\");\n}\n","export const crypto = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;\n//# sourceMappingURL=crypto.js.map","/**\n * Utilities for hex, bytes, CSPRNG.\n * @module\n */\n/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */\n// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.\n// node.js versions earlier than v19 don't declare it in global scope.\n// For node.js, package.json#exports field mapping rewrites import\n// from `crypto` to `cryptoNode`, which imports native module.\n// Makes the utils un-importable in browsers without a bundler.\n// Once node.js 18 is deprecated (2025-04-30), we can just drop the import.\nimport { crypto } from '@noble/hashes/crypto';\n/** Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. */\nexport function isBytes(a) {\n return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');\n}\n/** Asserts something is positive integer. */\nexport function anumber(n) {\n if (!Number.isSafeInteger(n) || n < 0)\n throw new Error('positive integer expected, got ' + n);\n}\n/** Asserts something is Uint8Array. */\nexport function abytes(b, ...lengths) {\n if (!isBytes(b))\n throw new Error('Uint8Array expected');\n if (lengths.length > 0 && !lengths.includes(b.length))\n throw new Error('Uint8Array expected of length ' + lengths + ', got length=' + b.length);\n}\n/** Asserts something is hash */\nexport function ahash(h) {\n if (typeof h !== 'function' || typeof h.create !== 'function')\n throw new Error('Hash should be wrapped by utils.createHasher');\n anumber(h.outputLen);\n anumber(h.blockLen);\n}\n/** Asserts a hash instance has not been destroyed / finished */\nexport function aexists(instance, checkFinished = true) {\n if (instance.destroyed)\n throw new Error('Hash instance has been destroyed');\n if (checkFinished && instance.finished)\n throw new Error('Hash#digest() has already been called');\n}\n/** Asserts output is properly-sized byte array */\nexport function aoutput(out, instance) {\n abytes(out);\n const min = instance.outputLen;\n if (out.length < min) {\n throw new Error('digestInto() expects output buffer of length at least ' + min);\n }\n}\n/** Cast u8 / u16 / u32 to u8. */\nexport function u8(arr) {\n return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n/** Cast u8 / u16 / u32 to u32. */\nexport function u32(arr) {\n return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));\n}\n/** Zeroize a byte array. Warning: JS provides no guarantees. */\nexport function clean(...arrays) {\n for (let i = 0; i < arrays.length; i++) {\n arrays[i].fill(0);\n }\n}\n/** Create DataView of an array for easy byte-level manipulation. */\nexport function createView(arr) {\n return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n/** The rotate right (circular right shift) operation for uint32 */\nexport function rotr(word, shift) {\n return (word << (32 - shift)) | (word >>> shift);\n}\n/** The rotate left (circular left shift) operation for uint32 */\nexport function rotl(word, shift) {\n return (word << shift) | ((word >>> (32 - shift)) >>> 0);\n}\n/** Is current platform little-endian? Most are. Big-Endian platform: IBM */\nexport const isLE = /* @__PURE__ */ (() => new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)();\n/** The byte swap operation for uint32 */\nexport function byteSwap(word) {\n return (((word << 24) & 0xff000000) |\n ((word << 8) & 0xff0000) |\n ((word >>> 8) & 0xff00) |\n ((word >>> 24) & 0xff));\n}\n/** Conditionally byte swap if on a big-endian platform */\nexport const swap8IfBE = isLE\n ? (n) => n\n : (n) => byteSwap(n);\n/** @deprecated */\nexport const byteSwapIfBE = swap8IfBE;\n/** In place byte swap for Uint32Array */\nexport function byteSwap32(arr) {\n for (let i = 0; i < arr.length; i++) {\n arr[i] = byteSwap(arr[i]);\n }\n return arr;\n}\nexport const swap32IfBE = isLE\n ? (u) => u\n : byteSwap32;\n// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex\nconst hasHexBuiltin = /* @__PURE__ */ (() => \n// @ts-ignore\ntypeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')();\n// Array where index 0xf0 (240) is mapped to string 'f0'\nconst hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));\n/**\n * Convert byte array to hex string. Uses built-in function, when available.\n * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'\n */\nexport function bytesToHex(bytes) {\n abytes(bytes);\n // @ts-ignore\n if (hasHexBuiltin)\n return bytes.toHex();\n // pre-caching improves the speed 6x\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += hexes[bytes[i]];\n }\n return hex;\n}\n// We use optimized technique to convert hex string to byte array\nconst asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };\nfunction asciiToBase16(ch) {\n if (ch >= asciis._0 && ch <= asciis._9)\n return ch - asciis._0; // '2' => 50-48\n if (ch >= asciis.A && ch <= asciis.F)\n return ch - (asciis.A - 10); // 'B' => 66-(65-10)\n if (ch >= asciis.a && ch <= asciis.f)\n return ch - (asciis.a - 10); // 'b' => 98-(97-10)\n return;\n}\n/**\n * Convert hex string to byte array. Uses built-in function, when available.\n * @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])\n */\nexport function hexToBytes(hex) {\n if (typeof hex !== 'string')\n throw new Error('hex string expected, got ' + typeof hex);\n // @ts-ignore\n if (hasHexBuiltin)\n return Uint8Array.fromHex(hex);\n const hl = hex.length;\n const al = hl / 2;\n if (hl % 2)\n throw new Error('hex string expected, got unpadded hex of length ' + hl);\n const array = new Uint8Array(al);\n for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {\n const n1 = asciiToBase16(hex.charCodeAt(hi));\n const n2 = asciiToBase16(hex.charCodeAt(hi + 1));\n if (n1 === undefined || n2 === undefined) {\n const char = hex[hi] + hex[hi + 1];\n throw new Error('hex string expected, got non-hex character \"' + char + '\" at index ' + hi);\n }\n array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163\n }\n return array;\n}\n/**\n * There is no setImmediate in browser and setTimeout is slow.\n * Call of async fn will return Promise, which will be fullfiled only on\n * next scheduler queue processing step and this is exactly what we need.\n */\nexport const nextTick = async () => { };\n/** Returns control to thread each 'tick' ms to avoid blocking. */\nexport async function asyncLoop(iters, tick, cb) {\n let ts = Date.now();\n for (let i = 0; i < iters; i++) {\n cb(i);\n // Date.now() is not monotonic, so in case if clock goes backwards we return return control too\n const diff = Date.now() - ts;\n if (diff >= 0 && diff < tick)\n continue;\n await nextTick();\n ts += diff;\n }\n}\n/**\n * Converts string to bytes using UTF8 encoding.\n * @example utf8ToBytes('abc') // Uint8Array.from([97, 98, 99])\n */\nexport function utf8ToBytes(str) {\n if (typeof str !== 'string')\n throw new Error('string expected');\n return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809\n}\n/**\n * Converts bytes to string using UTF8 encoding.\n * @example bytesToUtf8(Uint8Array.from([97, 98, 99])) // 'abc'\n */\nexport function bytesToUtf8(bytes) {\n return new TextDecoder().decode(bytes);\n}\n/**\n * Normalizes (non-hex) string or Uint8Array to Uint8Array.\n * Warning: when Uint8Array is passed, it would NOT get copied.\n * Keep in mind for future mutable operations.\n */\nexport function toBytes(data) {\n if (typeof data === 'string')\n data = utf8ToBytes(data);\n abytes(data);\n return data;\n}\n/**\n * Helper for KDFs: consumes uint8array or string.\n * When string is passed, does utf8 decoding, using TextDecoder.\n */\nexport function kdfInputToBytes(data) {\n if (typeof data === 'string')\n data = utf8ToBytes(data);\n abytes(data);\n return data;\n}\n/** Copies several Uint8Arrays into one. */\nexport function concatBytes(...arrays) {\n let sum = 0;\n for (let i = 0; i < arrays.length; i++) {\n const a = arrays[i];\n abytes(a);\n sum += a.length;\n }\n const res = new Uint8Array(sum);\n for (let i = 0, pad = 0; i < arrays.length; i++) {\n const a = arrays[i];\n res.set(a, pad);\n pad += a.length;\n }\n return res;\n}\nexport function checkOpts(defaults, opts) {\n if (opts !== undefined && {}.toString.call(opts) !== '[object Object]')\n throw new Error('options should be object or undefined');\n const merged = Object.assign(defaults, opts);\n return merged;\n}\n/** For runtime check if class implements interface */\nexport class Hash {\n}\n/** Wraps hash function, creating an interface on top of it */\nexport function createHasher(hashCons) {\n const hashC = (msg) => hashCons().update(toBytes(msg)).digest();\n const tmp = hashCons();\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = () => hashCons();\n return hashC;\n}\nexport function createOptHasher(hashCons) {\n const hashC = (msg, opts) => hashCons(opts).update(toBytes(msg)).digest();\n const tmp = hashCons({});\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = (opts) => hashCons(opts);\n return hashC;\n}\nexport function createXOFer(hashCons) {\n const hashC = (msg, opts) => hashCons(opts).update(toBytes(msg)).digest();\n const tmp = hashCons({});\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = (opts) => hashCons(opts);\n return hashC;\n}\nexport const wrapConstructor = createHasher;\nexport const wrapConstructorWithOpts = createOptHasher;\nexport const wrapXOFConstructorWithOpts = createXOFer;\n/** Cryptographically secure PRNG. Uses internal OS-level `crypto.getRandomValues`. */\nexport function randomBytes(bytesLength = 32) {\n if (crypto && typeof crypto.getRandomValues === 'function') {\n return crypto.getRandomValues(new Uint8Array(bytesLength));\n }\n // Legacy Node.js compatibility\n if (crypto && typeof crypto.randomBytes === 'function') {\n return Uint8Array.from(crypto.randomBytes(bytesLength));\n }\n throw new Error('crypto.getRandomValues must be defined');\n}\n//# sourceMappingURL=utils.js.map","import { naddrEncode, neventEncode, noteEncode, nprofileEncode, npubEncode, nsecEncode, } from \"nostr-tools/nip19\";\nimport { getPublicKey, kinds, nip19 } from \"nostr-tools\";\n// export nip-19 helpers\nexport { naddrEncode, neventEncode, noteEncode, nprofileEncode, npubEncode, nsecEncode, decode as decodePointer, } from \"nostr-tools/nip19\";\nimport { getReplaceableIdentifier } from \"./event.js\";\nimport { isAddressableKind, isReplaceableKind } from \"nostr-tools/kinds\";\nimport { isSafeRelayURL, relaySet } from \"./relays.js\";\nimport { isHexKey } from \"./string.js\";\nimport { hexToBytes } from \"@noble/hashes/utils\";\nimport { normalizeURL } from \"./url.js\";\nexport function parseCoordinate(a, requireD = false, silent = true) {\n const parts = a.split(\":\");\n const kind = parts[0] ? parseInt(parts[0]) : undefined;\n const pubkey = parts[1];\n const d = parts[2];\n if (kind === undefined) {\n if (silent)\n return null;\n else\n throw new Error(\"Missing kind\");\n }\n if (pubkey === undefined || pubkey === \"\") {\n if (silent)\n return null;\n else\n throw new Error(\"Missing pubkey\");\n }\n if (requireD && d === undefined) {\n if (silent)\n return null;\n else\n throw new Error(\"Missing identifier\");\n }\n return {\n kind,\n pubkey,\n identifier: d,\n };\n}\n/** Extra a pubkey from the result of nip19.decode */\nexport function getPubkeyFromDecodeResult(result) {\n if (!result)\n return;\n switch (result.type) {\n case \"naddr\":\n case \"nprofile\":\n return result.data.pubkey;\n case \"npub\":\n return result.data;\n case \"nsec\":\n return getPublicKey(result.data);\n default:\n return undefined;\n }\n}\n/** Gets the relays from a decode result */\nexport function getRelaysFromDecodeResult(result) {\n if (!result)\n return;\n switch (result.type) {\n case \"naddr\":\n return result.data.relays;\n case \"nprofile\":\n return result.data.relays;\n case \"nevent\":\n return result.data.relays;\n }\n return undefined;\n}\n/** Encodes the result of nip19.decode */\nexport function encodeDecodeResult(result) {\n switch (result.type) {\n case \"naddr\":\n return naddrEncode(result.data);\n case \"nprofile\":\n return nprofileEncode(result.data);\n case \"nevent\":\n return neventEncode(result.data);\n case \"nsec\":\n return nsecEncode(result.data);\n case \"npub\":\n return npubEncode(result.data);\n case \"note\":\n return noteEncode(result.data);\n }\n return \"\";\n}\n/**\n * Gets an EventPointer form a common \"e\" tag\n * @throws\n */\nexport function getEventPointerFromETag(tag) {\n if (!tag[1])\n throw new Error(\"Missing event id in tag\");\n let pointer = { id: tag[1] };\n if (tag[2] && isSafeRelayURL(tag[2]))\n pointer.relays = [tag[2]];\n return pointer;\n}\n/**\n * Gets an EventPointer form a common \"q\" tag\n * @throws if the tag is invalid\n */\nexport function getEventPointerFromQTag(tag) {\n if (!tag[1])\n throw new Error(\"Missing event id in tag\");\n let pointer = { id: tag[1] };\n if (tag[2] && isSafeRelayURL(tag[2]))\n pointer.relays = [tag[2]];\n if (tag[3] && tag[3].length === 64)\n pointer.author = tag[3];\n return pointer;\n}\n/**\n * Get an AddressPointer from a common \"a\" tag\n * @throws if the tag is invalid\n */\nexport function getAddressPointerFromATag(tag) {\n if (!tag[1])\n throw new Error(\"Missing coordinate in tag\");\n const pointer = parseCoordinate(tag[1], true, false);\n if (tag[2] && isSafeRelayURL(tag[2]))\n pointer.relays = [tag[2]];\n return pointer;\n}\n/**\n * Gets a ProfilePointer from a common \"p\" tag\n * @throws if the tag is invalid\n */\nexport function getProfilePointerFromPTag(tag) {\n if (!tag[1])\n throw new Error(\"Missing pubkey in tag\");\n if (!isHexKey(tag[1]))\n throw new Error(\"Invalid pubkey\");\n const pointer = { pubkey: tag[1] };\n if (tag[2] && isSafeRelayURL(tag[2]))\n pointer.relays = [normalizeURL(tag[2])];\n return pointer;\n}\n/** Checks if a pointer is an AddressPointer */\nexport function isAddressPointer(pointer) {\n return (typeof pointer !== \"string\" &&\n Reflect.has(pointer, \"identifier\") &&\n Reflect.has(pointer, \"pubkey\") &&\n Reflect.has(pointer, \"kind\"));\n}\n/** Checks if a pointer is an EventPointer */\nexport function isEventPointer(pointer) {\n return typeof pointer !== \"string\" && Reflect.has(pointer, \"id\");\n}\n/** Returns the coordinate string for an AddressPointer */\nexport function getCoordinateFromAddressPointer(pointer) {\n return pointer.kind + \":\" + pointer.pubkey + \":\" + pointer.identifier;\n}\n/**\n * Returns an AddressPointer for a replaceable event\n * @throws if the event is not replaceable or addressable\n */\nexport function getAddressPointerForEvent(event, relays) {\n if (!isAddressableKind(event.kind) && !isReplaceableKind(event.kind))\n throw new Error(\"Cant get AddressPointer for non-replaceable event\");\n const d = getReplaceableIdentifier(event);\n return {\n identifier: d,\n kind: event.kind,\n pubkey: event.pubkey,\n relays,\n };\n}\n/** Returns an EventPointer for an event */\nexport function getEventPointerForEvent(event, relays) {\n return {\n id: event.id,\n kind: event.kind,\n author: event.pubkey,\n relays,\n };\n}\n/** Returns a pointer for a given event */\nexport function getPointerForEvent(event, relays) {\n if (kinds.isAddressableKind(event.kind) || kinds.isReplaceableKind(event.kind)) {\n return {\n type: \"naddr\",\n data: getAddressPointerForEvent(event, relays),\n };\n }\n else {\n return {\n type: \"nevent\",\n data: getEventPointerForEvent(event, relays),\n };\n }\n}\n/** Adds relay hints to a pointer object that has a relays array */\nexport function addRelayHintsToPointer(pointer, relays) {\n if (!relays)\n return pointer;\n else\n return { ...pointer, relays: relaySet(relays, pointer.relays) };\n}\n/** Gets the hex pubkey from any nip-19 encoded string */\nexport function normalizeToPubkey(str) {\n if (isHexKey(str))\n return str.toLowerCase();\n else {\n const decode = nip19.decode(str);\n const pubkey = getPubkeyFromDecodeResult(decode);\n if (!pubkey)\n throw new Error(`Cant find pubkey in ${decode.type}`);\n return pubkey;\n }\n}\n/** Gets a ProfilePointer from any nip-19 encoded string */\nexport function normalizeToProfilePointer(str) {\n if (isHexKey(str))\n return { pubkey: str.toLowerCase() };\n else {\n const decode = nip19.decode(str);\n // Return it if it's a profile pointer\n if (decode.type === \"nprofile\")\n return decode.data;\n // fallback to just getting the pubkey\n const pubkey = getPubkeyFromDecodeResult(decode);\n if (!pubkey)\n throw new Error(`Cant find pubkey in ${decode.type}`);\n const relays = getRelaysFromDecodeResult(decode);\n return { pubkey, relays };\n }\n}\n/** Converts hex to nsec strings into Uint8 secret keys */\nexport function normalizeToSecretKey(str) {\n if (str instanceof Uint8Array)\n return str;\n else if (isHexKey(str))\n return hexToBytes(str);\n else {\n const decode = nip19.decode(str);\n if (decode.type !== \"nsec\")\n throw new Error(`Cant get secret key from ${decode.type}`);\n return decode.data;\n }\n}\n/**\n * Merges two event points and keeps all relays\n * @throws if the ids are different\n */\nexport function mergeEventPointers(a, b) {\n if (a.id !== b.id)\n throw new Error(\"Cant merge event pointers with different ids\");\n const relays = relaySet(a.relays, b.relays);\n return { id: a.id, kind: a.kind ?? b.kind, author: a.author ?? b.author, relays };\n}\n/**\n * Merges two address pointers and keeps all relays\n * @throws if the kinds, pubkeys, or identifiers are different\n */\nexport function mergeAddressPointers(a, b) {\n if (a.kind !== b.kind || a.pubkey !== b.pubkey || a.identifier !== b.identifier)\n throw new Error(\"Cant merge address pointers with different kinds, pubkeys, or identifiers\");\n const relays = relaySet(a.relays, b.relays);\n return { ...a, relays };\n}\n/**\n * Merges two profile pointers and keeps all relays\n * @throws if the pubkeys are different\n */\nexport function mergeProfilePointers(a, b) {\n if (a.pubkey !== b.pubkey)\n throw new Error(\"Cant merge profile pointers with different pubkeys\");\n const relays = relaySet(a.relays, b.relays);\n return { ...a, relays };\n}\n","import { getOrComputeCachedValue } from \"./cache.js\";\nimport { getHiddenTags } from \"./hidden-tags.js\";\nimport { processTags } from \"./tags.js\";\nimport { normalizeURL } from \"./url.js\";\nexport const GROUPS_LIST_KIND = 10009;\nexport const GROUP_MESSAGE_KIND = 9;\n/** decodes a group identifier into a group pointer object */\nexport function decodeGroupPointer(str) {\n let [relay, id] = str.split(\"'\");\n if (!relay)\n return null;\n // Prepend wss:// if missing\n if (!relay.match(/^wss?:/))\n relay = `wss://${relay}`;\n // Normalize the relay url\n relay = normalizeURL(relay);\n return { relay, id: id || \"_\" };\n}\n/** Converts a group pointer into a group identifier */\nexport function encodeGroupPointer(pointer) {\n const hostname = URL.canParse(pointer.relay) ? new URL(pointer.relay).hostname : pointer.relay;\n return `${hostname}'${pointer.id}`;\n}\nexport const GroupsPublicSymbol = Symbol.for(\"groups-public\");\nexport const GroupsHiddenSymbol = Symbol.for(\"groups-hidden\");\n/** gets a {@link GroupPointer} from a \"h\" tag if it has a relay hint */\nexport function getGroupPointerFromHTag(tag) {\n const [_, id, relay] = tag;\n if (!id || !relay)\n return undefined;\n return { id, relay };\n}\n/** gets a {@link GroupPointer} from a \"group\" tag */\nexport function getGroupPointerFromGroupTag(tag) {\n const [_, id, relay, name] = tag;\n return { id, relay, name };\n}\n/** Returns all the public groups from a k:10009 list */\nexport function getPublicGroups(bookmark) {\n return getOrComputeCachedValue(bookmark, GroupsPublicSymbol, () => processTags(bookmark.tags.filter((t) => t[0] === \"group\"), getGroupPointerFromGroupTag));\n}\n/** Returns all the hidden groups from a k:10009 list */\nexport function getHiddenGroups(bookmark) {\n return getOrComputeCachedValue(bookmark, GroupsHiddenSymbol, () => {\n const tags = getHiddenTags(bookmark);\n return (tags &&\n processTags(bookmark.tags.filter((t) => t[0] === \"group\"), getGroupPointerFromGroupTag));\n });\n}\n","import { kinds } from \"nostr-tools\";\nimport { notifyEventUpdate } from \"./event.js\";\n/** A symbol use to store the encrypted content of an event in memory */\nexport const EncryptedContentSymbol = Symbol.for(\"encrypted-content\");\n/** Various event kinds that can have encrypted content and which encryption method they use */\nexport const EventContentEncryptionMethod = {\n [kinds.EncryptedDirectMessage]: \"nip04\",\n [kinds.Seal]: \"nip44\",\n [kinds.GiftWrap]: \"nip44\",\n};\n/** Sets the encryption method that is used for the contents of a specific event kind */\nexport function setEncryptedContentEncryptionMethod(kind, method) {\n EventContentEncryptionMethod[kind] = method;\n return kind;\n}\n/**\n * Returns either nip04 or nip44 encryption methods depending on event kind\n * @param kind The event kind to get the encryption method for\n * @param signer The signer to use to get the encryption methods\n * @param override The encryption method to use instead of the default\n * @throws If the event kind does not support encrypted content\n * @throws If the signer does not support the encryption method\n * @returns The encryption methods for the event kind\n */\nexport function getEncryptedContentEncryptionMethods(kind, signer, override) {\n const method = override ?? EventContentEncryptionMethod[kind];\n if (!method)\n throw new Error(`Event kind ${kind} does not support encrypted content`);\n const encryption = signer[method];\n if (!encryption)\n throw new Error(`Signer does not support ${method} encryption`);\n return encryption;\n}\n/** Checks if an event can have encrypted content */\nexport function canHaveEncryptedContent(kind) {\n return EventContentEncryptionMethod[kind] !== undefined;\n}\n/** Checks if an event has encrypted content */\nexport function hasEncryptedContent(event) {\n return event.content.length > 0;\n}\nexport function getEncryptedContent(event) {\n return Reflect.get(event, EncryptedContentSymbol);\n}\n/** Checks if the encrypted content is unlocked and casts it to the {@link UnlockedEncryptedContent} type */\nexport function isEncryptedContentUnlocked(event) {\n return Reflect.has(event, EncryptedContentSymbol) === true;\n}\n/**\n * Unlocks the encrypted content in an event and caches it\n * @param event The event with content to decrypt\n * @param pubkey The other pubkey that encrypted the content\n * @param signer A signer to use to decrypt the content\n * @throws If the event kind does not support encrypted content\n */\nexport async function unlockEncryptedContent(event, pubkey, signer) {\n if (!canHaveEncryptedContent(event.kind))\n throw new Error(\"Event kind does not support encrypted content\");\n // Get the encryption methods from the signer\n const encryption = getEncryptedContentEncryptionMethods(event.kind, signer);\n const plaintext = await encryption.decrypt(pubkey, event.content);\n // Set the cached value and trigger update\n setEncryptedContentCache(event, plaintext);\n // Return the decrypted content\n return plaintext;\n}\n/** Sets the encrypted content on an event and updates it if its part of an event store */\nexport function setEncryptedContentCache(event, plaintext) {\n Reflect.set(event, EncryptedContentSymbol, plaintext);\n // if the event has been added to an event store, notify it\n notifyEventUpdate(event);\n}\n/** Removes the encrypted content cache on an event */\nexport function lockEncryptedContent(event) {\n Reflect.deleteProperty(event, EncryptedContentSymbol);\n // if the event has been added to an event store, notify it\n notifyEventUpdate(event);\n}\n","import { kinds } from \"nostr-tools\";\nimport { canHaveEncryptedContent, EncryptedContentSymbol, getEncryptedContent, getEncryptedContentEncryptionMethods, hasEncryptedContent, isEncryptedContentUnlocked, lockEncryptedContent, setEncryptedContentCache, setEncryptedContentEncryptionMethod, } from \"./encrypted-content.js\";\n/** Symbol for caching hidden content. Alias for {@link EncryptedContentSymbol} */\nexport const HiddenContentSymbol = EncryptedContentSymbol;\n/** Alias for {@link getEncryptedContentEncryptionMethods} */\nexport const getHiddenContentEncryptionMethods = getEncryptedContentEncryptionMethods;\n/** Various event kinds that can have hidden content */\nexport const HiddenContentKinds = new Set([setEncryptedContentEncryptionMethod(kinds.DraftLong, \"nip04\")]);\n/** Sets the encryption method for hidden content on a kind */\nexport function setHiddenContentEncryptionMethod(kind, method) {\n HiddenContentKinds.add(setEncryptedContentEncryptionMethod(kind, method));\n return kind;\n}\n/** Checks if an event can have hidden content */\nexport function canHaveHiddenContent(kind) {\n return canHaveEncryptedContent(kind) && HiddenContentKinds.has(kind);\n}\n/** Checks if an event has hidden content */\nexport function hasHiddenContent(event) {\n return canHaveHiddenContent(event.kind) && hasEncryptedContent(event);\n}\n/** Checks if the hidden content is unlocked and casts it to the {@link UnlockedEncryptedContent} type */\nexport function isHiddenContentUnlocked(event) {\n if (!canHaveHiddenContent(event.kind))\n return false;\n return isEncryptedContentUnlocked(event) && Reflect.has(event, HiddenContentSymbol) === true;\n}\nexport function getHiddenContent(event) {\n if (!canHaveHiddenContent(event.kind))\n return undefined;\n if (isHiddenContentUnlocked(event))\n return event[EncryptedContentSymbol];\n return getEncryptedContent(event);\n}\n/**\n * Unlocks the hidden content in the event\n * @param event The event with content to decrypt\n * @param signer A signer to use to decrypt the content\n * @throws\n */\nexport async function unlockHiddenContent(event, signer, override) {\n if (!canHaveHiddenContent(event.kind))\n throw new Error(\"Event kind does not support hidden content\");\n // If the encrypted content is already unlocked, return the cached value\n if (isEncryptedContentUnlocked(event))\n return event[EncryptedContentSymbol];\n // Get the encryption method from the signer\n const encryption = getEncryptedContentEncryptionMethods(event.kind, signer, override);\n // Decrypt the content using the events pubkey\n const plaintext = await encryption.decrypt(event.pubkey, event.content);\n // Set the cached value\n setHiddenContentCache(event, plaintext);\n // Return the decrypted content\n return plaintext;\n}\n/**\n * Sets the hidden content on an event and updates it if its part of an event store\n * @throws If the event kind does not support hidden content\n */\nexport function setHiddenContentCache(event, plaintext) {\n if (!canHaveHiddenContent(event.kind))\n throw new Error(\"Event kind does not support hidden content\");\n // Set the encrypted content\n setEncryptedContentCache(event, plaintext);\n}\n/** Removes the unencrypted hidden content on an event */\nexport function lockHiddenContent(event) {\n lockEncryptedContent(event);\n}\n","import { kinds } from \"nostr-tools\";\nimport { GROUPS_LIST_KIND } from \"./groups.js\";\nimport { canHaveHiddenContent, getHiddenContent, getHiddenContentEncryptionMethods, hasHiddenContent, isHiddenContentUnlocked, lockHiddenContent, setHiddenContentCache, setHiddenContentEncryptionMethod, unlockHiddenContent, } from \"./hidden-content.js\";\n/** Symbol for caching hidden tags. */\nexport const HiddenTagsSymbol = Symbol.for(\"hidden-tags\");\n/** Various event kinds that can have hidden tags */\nexport const HiddenTagsKinds = new Set([\n // NIP-51 lists\n setHiddenContentEncryptionMethod(kinds.BookmarkList, \"nip04\"),\n setHiddenContentEncryptionMethod(kinds.InterestsList, \"nip04\"),\n setHiddenContentEncryptionMethod(kinds.Mutelist, \"nip04\"),\n setHiddenContentEncryptionMethod(kinds.CommunitiesList, \"nip04\"),\n setHiddenContentEncryptionMethod(kinds.PublicChatsList, \"nip04\"),\n setHiddenContentEncryptionMethod(kinds.SearchRelaysList, \"nip04\"),\n setHiddenContentEncryptionMethod(GROUPS_LIST_KIND, \"nip04\"),\n // NIP-51 sets\n setHiddenContentEncryptionMethod(kinds.Bookmarksets, \"nip04\"),\n setHiddenContentEncryptionMethod(kinds.Relaysets, \"nip04\"),\n setHiddenContentEncryptionMethod(kinds.Followsets, \"nip04\"),\n setHiddenContentEncryptionMethod(kinds.Curationsets, \"nip04\"),\n setHiddenContentEncryptionMethod(kinds.Interestsets, \"nip04\"),\n]);\n/** Checks if an event can have hidden tags */\nexport function canHaveHiddenTags(kind) {\n return canHaveHiddenContent(kind) && HiddenTagsKinds.has(kind);\n}\n/** Sets the type of encryption to use for hidden tags on a kind */\nexport function setHiddenTagsEncryptionMethod(kind, method) {\n HiddenTagsKinds.add(setHiddenContentEncryptionMethod(kind, method));\n return kind;\n}\n/** Checks if an event has hidden tags */\nexport function hasHiddenTags(event) {\n return canHaveHiddenTags(event.kind) && hasHiddenContent(event);\n}\n/** Returns either nip04 or nip44 encryption method depending on list kind */\nexport function getHiddenTagsEncryptionMethods(kind, signer) {\n return getHiddenContentEncryptionMethods(kind, signer);\n}\n/** Checks if the hidden tags are locked and casts it to the {@link UnlockedHiddenTags} type */\nexport function isHiddenTagsUnlocked(event) {\n if (!canHaveHiddenTags(event.kind))\n return false;\n return isHiddenContentUnlocked(event) && Reflect.has(event, `HiddenTagsSymbol`);\n}\nexport function getHiddenTags(event) {\n if (!canHaveHiddenTags(event.kind))\n return undefined;\n // If the hidden tags are already unlocked, return the cached value\n if (isHiddenTagsUnlocked(event))\n return event[HiddenTagsSymbol];\n // unlock hidden content is needed\n const content = getHiddenContent(event);\n // Return undefined if the hidden content is not unlocked\n if (content === undefined)\n return undefined;\n // Parse the hidden content as an array of tags\n const parsed = JSON.parse(content);\n // Throw error if content is not an array of tags\n if (!Array.isArray(parsed))\n throw new Error(\"Content is not an array of tags\");\n // Convert array to tags array string[][]\n const tags = parsed.filter((t) => Array.isArray(t)).map((t) => t.map((v) => String(v)));\n // Set the cached value\n Reflect.set(event, HiddenTagsSymbol, tags);\n return tags;\n}\n/**\n * Decrypts the private list\n * @param event The list event to decrypt\n * @param signer A signer to use to decrypt the tags\n * @param override The encryption method to use instead of the default\n * @throws\n */\nexport async function unlockHiddenTags(event, signer, override) {\n if (!canHaveHiddenTags(event.kind))\n throw new Error(\"Event kind does not support hidden tags\");\n // Return the cached value if the hidden tags are already unlocked\n if (isHiddenTagsUnlocked(event))\n return event[HiddenTagsSymbol];\n // Unlock hidden content\n await unlockHiddenContent(event, signer, override);\n // Parse the hidden tags\n const tags = getHiddenTags(event);\n if (tags === undefined)\n throw new Error(\"Failed to unlock hidden tags\");\n // Set cache an notify event store\n setHiddenTagsCache(event, tags);\n return tags;\n}\n/**\n * Sets the hidden tags on an event and updates it if its part of an event store\n * @throws If the event kind does not support hidden tags\n */\nexport function setHiddenTagsCache(event, tags) {\n if (!canHaveHiddenTags(event.kind))\n throw new Error(\"Event kind does not support hidden tags\");\n // Set the cached value\n Reflect.set(event, HiddenTagsSymbol, tags);\n // Set the cached content\n setHiddenContentCache(event, JSON.stringify(tags));\n}\n/** Clears the cached hidden tags on an event */\nexport function lockHiddenTags(event) {\n Reflect.deleteProperty(event, HiddenTagsSymbol);\n lockHiddenContent(event);\n}\n","import { getHiddenTags } from \"./hidden-tags.js\";\nconst LETTERS = \"abcdefghijklmnopqrstuvwxyz\";\nexport const INDEXABLE_TAGS = new Set((LETTERS + LETTERS.toUpperCase()).split(\"\"));\nexport const EventIndexableTagsSymbol = Symbol.for(\"indexable-tags\");\n/**\n * Returns the second index ( tag[1] ) of the first tag that matches the name\n * If the event has any hidden tags they will be searched first\n */\nexport function getTagValue(event, name) {\n const hidden = getHiddenTags(event);\n const hiddenValue = hidden?.find((t) => t[0] === name)?.[1];\n if (hiddenValue)\n return hiddenValue;\n return event.tags.find((t) => t[0] === name)?.[1];\n}\n/** Checks if an event has a public name / value tag*/\nexport function hasNameValueTag(event, name, value) {\n return event.tags.some((t) => t[0] === name && t[1] === value);\n}\n/** Returns a Set of tag names and values that are indexable */\nexport function getIndexableTags(event) {\n let indexable = Reflect.get(event, EventIndexableTagsSymbol);\n if (!indexable) {\n const tags = new Set();\n for (const tag of event.tags) {\n if (tag.length >= 2 && tag[0].length === 1 && INDEXABLE_TAGS.has(tag[0])) {\n tags.add(tag[0] + \":\" + tag[1]);\n }\n }\n indexable = tags;\n Reflect.set(event, EventIndexableTagsSymbol, tags);\n }\n return indexable;\n}\n","/**\n * Copied from tiny-lru and modified to support typescript\n * @see https://github.com/avoidwork/tiny-lru/blob/master/src/lru.js\n */\nexport class LRU {\n first = null;\n items = Object.create(null);\n last = null;\n max;\n resetTtl;\n size;\n ttl;\n constructor(max = 0, ttl = 0, resetTtl = false) {\n this.first = null;\n this.items = Object.create(null);\n this.last = null;\n this.max = max;\n this.resetTtl = resetTtl;\n this.size = 0;\n this.ttl = ttl;\n }\n clear() {\n this.first = null;\n this.items = Object.create(null);\n this.last = null;\n this.size = 0;\n return this;\n }\n delete(key) {\n if (this.has(key)) {\n const item = this.items[key];\n delete this.items[key];\n this.size--;\n if (item.prev !== null) {\n item.prev.next = item.next;\n }\n if (item.next !== null) {\n item.next.prev = item.prev;\n }\n if (this.first === item) {\n this.first = item.next;\n }\n if (this.last === item) {\n this.last = item.prev;\n }\n }\n return this;\n }\n entries(keys = this.keys()) {\n return keys.map((key) => [key, this.get(key)]);\n }\n evict(bypass = false) {\n if (bypass || this.size > 0) {\n const item = this.first;\n delete this.items[item.key];\n if (--this.size === 0) {\n this.first = null;\n this.last = null;\n }\n else {\n this.first = item.next;\n this.first.prev = null;\n }\n }\n return this;\n }\n expiresAt(key) {\n let result;\n if (this.has(key)) {\n result = this.items[key].expiry;\n }\n return result;\n }\n get(key) {\n let result;\n if (this.has(key)) {\n const item = this.items[key];\n if (this.ttl > 0 && item.expiry <= Date.now()) {\n this.delete(key);\n }\n else {\n result = item.value;\n this.set(key, result, true);\n }\n }\n return result;\n }\n has(key) {\n return key in this.items;\n }\n keys() {\n const result = [];\n let x = this.first;\n while (x !== null) {\n result.push(x.key);\n x = x.next;\n }\n return result;\n }\n set(key, value, bypass = false, resetTtl = this.resetTtl) {\n let item;\n if (bypass || this.has(key)) {\n item = this.items[key];\n item.value = value;\n if (bypass === false && resetTtl) {\n item.expiry = this.ttl > 0 ? Date.now() + this.ttl : this.ttl;\n }\n if (this.last !== item) {\n const last = this.last, next = item.next, prev = item.prev;\n if (this.first === item) {\n this.first = item.next;\n }\n item.next = null;\n item.prev = this.last;\n last.next = item;\n if (prev !== null) {\n prev.next = next;\n }\n if (next !== null) {\n next.prev = prev;\n }\n }\n }\n else {\n if (this.max > 0 && this.size === this.max) {\n this.evict(true);\n }\n item = this.items[key] = {\n expiry: this.ttl > 0 ? Date.now() + this.ttl : this.ttl,\n key: key,\n prev: this.last,\n next: null,\n value,\n };\n if (++this.size === 1) {\n this.first = item;\n }\n else {\n this.last.next = item;\n }\n }\n this.last = item;\n return this;\n }\n values(keys = this.keys()) {\n return keys.map((key) => this.get(key));\n }\n}\n","/**\n * Helpers.\n */\n\nvar s = 1000;\nvar m = s * 60;\nvar h = m * 60;\nvar d = h * 24;\nvar w = d * 7;\nvar y = d * 365.25;\n\n/**\n * Parse or format the given `val`.\n *\n * Options:\n *\n * - `long` verbose formatting [false]\n *\n * @param {String|Number} val\n * @param {Object} [options]\n * @throws {Error} throw an error if val is not a non-empty string or a number\n * @return {String|Number}\n * @api public\n */\n\nmodule.exports = function (val, options) {\n options = options || {};\n var type = typeof val;\n if (type === 'string' && val.length > 0) {\n return parse(val);\n } else if (type === 'number' && isFinite(val)) {\n return options.long ? fmtLong(val) : fmtShort(val);\n }\n throw new Error(\n 'val is not a non-empty string or a valid number. val=' +\n JSON.stringify(val)\n );\n};\n\n/**\n * Parse the given `str` and return milliseconds.\n *\n * @param {String} str\n * @return {Number}\n * @api private\n */\n\nfunction parse(str) {\n str = String(str);\n if (str.length > 100) {\n return;\n }\n var match = /^(-?(?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(\n str\n );\n if (!match) {\n return;\n }\n var n = parseFloat(match[1]);\n var type = (match[2] || 'ms').toLowerCase();\n switch (type) {\n case 'years':\n case 'year':\n case 'yrs':\n case 'yr':\n case 'y':\n return n * y;\n case 'weeks':\n case 'week':\n case 'w':\n return n * w;\n case 'days':\n case 'day':\n case 'd':\n return n * d;\n case 'hours':\n case 'hour':\n case 'hrs':\n case 'hr':\n case 'h':\n return n * h;\n case 'minutes':\n case 'minute':\n case 'mins':\n case 'min':\n case 'm':\n return n * m;\n case 'seconds':\n case 'second':\n case 'secs':\n case 'sec':\n case 's':\n return n * s;\n case 'milliseconds':\n case 'millisecond':\n case 'msecs':\n case 'msec':\n case 'ms':\n return n;\n default:\n return undefined;\n }\n}\n\n/**\n * Short format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction fmtShort(ms) {\n var msAbs = Math.abs(ms);\n if (msAbs >= d) {\n return Math.round(ms / d) + 'd';\n }\n if (msAbs >= h) {\n return Math.round(ms / h) + 'h';\n }\n if (msAbs >= m) {\n return Math.round(ms / m) + 'm';\n }\n if (msAbs >= s) {\n return Math.round(ms / s) + 's';\n }\n return ms + 'ms';\n}\n\n/**\n * Long format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction fmtLong(ms) {\n var msAbs = Math.abs(ms);\n if (msAbs >= d) {\n return plural(ms, msAbs, d, 'day');\n }\n if (msAbs >= h) {\n return plural(ms, msAbs, h, 'hour');\n }\n if (msAbs >= m) {\n return plural(ms, msAbs, m, 'minute');\n }\n if (msAbs >= s) {\n return plural(ms, msAbs, s, 'second');\n }\n return ms + ' ms';\n}\n\n/**\n * Pluralization helper.\n */\n\nfunction plural(ms, msAbs, n, name) {\n var isPlural = msAbs >= n * 1.5;\n return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');\n}\n","\n/**\n * This is the common logic for both the Node.js and web browser\n * implementations of `debug()`.\n */\n\nfunction setup(env) {\n\tcreateDebug.debug = createDebug;\n\tcreateDebug.default = createDebug;\n\tcreateDebug.coerce = coerce;\n\tcreateDebug.disable = disable;\n\tcreateDebug.enable = enable;\n\tcreateDebug.enabled = enabled;\n\tcreateDebug.humanize = require('ms');\n\tcreateDebug.destroy = destroy;\n\n\tObject.keys(env).forEach(key => {\n\t\tcreateDebug[key] = env[key];\n\t});\n\n\t/**\n\t* The currently active debug mode names, and names to skip.\n\t*/\n\n\tcreateDebug.names = [];\n\tcreateDebug.skips = [];\n\n\t/**\n\t* Map of special \"%n\" handling functions, for the debug \"format\" argument.\n\t*\n\t* Valid key names are a single, lower or upper-case letter, i.e. \"n\" and \"N\".\n\t*/\n\tcreateDebug.formatters = {};\n\n\t/**\n\t* Selects a color for a debug namespace\n\t* @param {String} namespace The namespace string for the debug instance to be colored\n\t* @return {Number|String} An ANSI color code for the given namespace\n\t* @api private\n\t*/\n\tfunction selectColor(namespace) {\n\t\tlet hash = 0;\n\n\t\tfor (let i = 0; i < namespace.length; i++) {\n\t\t\thash = ((hash << 5) - hash) + namespace.charCodeAt(i);\n\t\t\thash |= 0; // Convert to 32bit integer\n\t\t}\n\n\t\treturn createDebug.colors[Math.abs(hash) % createDebug.colors.length];\n\t}\n\tcreateDebug.selectColor = selectColor;\n\n\t/**\n\t* Create a debugger with the given `namespace`.\n\t*\n\t* @param {String} namespace\n\t* @return {Function}\n\t* @api public\n\t*/\n\tfunction createDebug(namespace) {\n\t\tlet prevTime;\n\t\tlet enableOverride = null;\n\t\tlet namespacesCache;\n\t\tlet enabledCache;\n\n\t\tfunction debug(...args) {\n\t\t\t// Disabled?\n\t\t\tif (!debug.enabled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst self = debug;\n\n\t\t\t// Set `diff` timestamp\n\t\t\tconst curr = Number(new Date());\n\t\t\tconst ms = curr - (prevTime || curr);\n\t\t\tself.diff = ms;\n\t\t\tself.prev = prevTime;\n\t\t\tself.curr = curr;\n\t\t\tprevTime = curr;\n\n\t\t\targs[0] = createDebug.coerce(args[0]);\n\n\t\t\tif (typeof args[0] !== 'string') {\n\t\t\t\t// Anything else let's inspect with %O\n\t\t\t\targs.unshift('%O');\n\t\t\t}\n\n\t\t\t// Apply any `formatters` transformations\n\t\t\tlet index = 0;\n\t\t\targs[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {\n\t\t\t\t// If we encounter an escaped % then don't increase the array index\n\t\t\t\tif (match === '%%') {\n\t\t\t\t\treturn '%';\n\t\t\t\t}\n\t\t\t\tindex++;\n\t\t\t\tconst formatter = createDebug.formatters[format];\n\t\t\t\tif (typeof formatter === 'function') {\n\t\t\t\t\tconst val = args[index];\n\t\t\t\t\tmatch = formatter.call(self, val);\n\n\t\t\t\t\t// Now we need to remove `args[index]` since it's inlined in the `format`\n\t\t\t\t\targs.splice(index, 1);\n\t\t\t\t\tindex--;\n\t\t\t\t}\n\t\t\t\treturn match;\n\t\t\t});\n\n\t\t\t// Apply env-specific formatting (colors, etc.)\n\t\t\tcreateDebug.formatArgs.call(self, args);\n\n\t\t\tconst logFn = self.log || createDebug.log;\n\t\t\tlogFn.apply(self, args);\n\t\t}\n\n\t\tdebug.namespace = namespace;\n\t\tdebug.useColors = createDebug.useColors();\n\t\tdebug.color = createDebug.selectColor(namespace);\n\t\tdebug.extend = extend;\n\t\tdebug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release.\n\n\t\tObject.defineProperty(debug, 'enabled', {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: false,\n\t\t\tget: () => {\n\t\t\t\tif (enableOverride !== null) {\n\t\t\t\t\treturn enableOverride;\n\t\t\t\t}\n\t\t\t\tif (namespacesCache !== createDebug.namespaces) {\n\t\t\t\t\tnamespacesCache = createDebug.namespaces;\n\t\t\t\t\tenabledCache = createDebug.enabled(namespace);\n\t\t\t\t}\n\n\t\t\t\treturn enabledCache;\n\t\t\t},\n\t\t\tset: v => {\n\t\t\t\tenableOverride = v;\n\t\t\t}\n\t\t});\n\n\t\t// Env-specific initialization logic for debug instances\n\t\tif (typeof createDebug.init === 'function') {\n\t\t\tcreateDebug.init(debug);\n\t\t}\n\n\t\treturn debug;\n\t}\n\n\tfunction extend(namespace, delimiter) {\n\t\tconst newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);\n\t\tnewDebug.log = this.log;\n\t\treturn newDebug;\n\t}\n\n\t/**\n\t* Enables a debug mode by namespaces. This can include modes\n\t* separated by a colon and wildcards.\n\t*\n\t* @param {String} namespaces\n\t* @api public\n\t*/\n\tfunction enable(namespaces) {\n\t\tcreateDebug.save(namespaces);\n\t\tcreateDebug.namespaces = namespaces;\n\n\t\tcreateDebug.names = [];\n\t\tcreateDebug.skips = [];\n\n\t\tconst split = (typeof namespaces === 'string' ? namespaces : '')\n\t\t\t.trim()\n\t\t\t.replace(/\\s+/g, ',')\n\t\t\t.split(',')\n\t\t\t.filter(Boolean);\n\n\t\tfor (const ns of split) {\n\t\t\tif (ns[0] === '-') {\n\t\t\t\tcreateDebug.skips.push(ns.slice(1));\n\t\t\t} else {\n\t\t\t\tcreateDebug.names.push(ns);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Checks if the given string matches a namespace template, honoring\n\t * asterisks as wildcards.\n\t *\n\t * @param {String} search\n\t * @param {String} template\n\t * @return {Boolean}\n\t */\n\tfunction matchesTemplate(search, template) {\n\t\tlet searchIndex = 0;\n\t\tlet templateIndex = 0;\n\t\tlet starIndex = -1;\n\t\tlet matchIndex = 0;\n\n\t\twhile (searchIndex < search.length) {\n\t\t\tif (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === '*')) {\n\t\t\t\t// Match character or proceed with wildcard\n\t\t\t\tif (template[templateIndex] === '*') {\n\t\t\t\t\tstarIndex = templateIndex;\n\t\t\t\t\tmatchIndex = searchIndex;\n\t\t\t\t\ttemplateIndex++; // Skip the '*'\n\t\t\t\t} else {\n\t\t\t\t\tsearchIndex++;\n\t\t\t\t\ttemplateIndex++;\n\t\t\t\t}\n\t\t\t} else if (starIndex !== -1) { // eslint-disable-line no-negated-condition\n\t\t\t\t// Backtrack to the last '*' and try to match more characters\n\t\t\t\ttemplateIndex = starIndex + 1;\n\t\t\t\tmatchIndex++;\n\t\t\t\tsearchIndex = matchIndex;\n\t\t\t} else {\n\t\t\t\treturn false; // No match\n\t\t\t}\n\t\t}\n\n\t\t// Handle trailing '*' in template\n\t\twhile (templateIndex < template.length && template[templateIndex] === '*') {\n\t\t\ttemplateIndex++;\n\t\t}\n\n\t\treturn templateIndex === template.length;\n\t}\n\n\t/**\n\t* Disable debug output.\n\t*\n\t* @return {String} namespaces\n\t* @api public\n\t*/\n\tfunction disable() {\n\t\tconst namespaces = [\n\t\t\t...createDebug.names,\n\t\t\t...createDebug.skips.map(namespace => '-' + namespace)\n\t\t].join(',');\n\t\tcreateDebug.enable('');\n\t\treturn namespaces;\n\t}\n\n\t/**\n\t* Returns true if the given mode name is enabled, false otherwise.\n\t*\n\t* @param {String} name\n\t* @return {Boolean}\n\t* @api public\n\t*/\n\tfunction enabled(name) {\n\t\tfor (const skip of createDebug.skips) {\n\t\t\tif (matchesTemplate(name, skip)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tfor (const ns of createDebug.names) {\n\t\t\tif (matchesTemplate(name, ns)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t* Coerce `val`.\n\t*\n\t* @param {Mixed} val\n\t* @return {Mixed}\n\t* @api private\n\t*/\n\tfunction coerce(val) {\n\t\tif (val instanceof Error) {\n\t\t\treturn val.stack || val.message;\n\t\t}\n\t\treturn val;\n\t}\n\n\t/**\n\t* XXX DO NOT USE. This is a temporary stub function.\n\t* XXX It WILL be removed in the next major release.\n\t*/\n\tfunction destroy() {\n\t\tconsole.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');\n\t}\n\n\tcreateDebug.enable(createDebug.load());\n\n\treturn createDebug;\n}\n\nmodule.exports = setup;\n","/* eslint-env browser */\n\n/**\n * This is the web browser implementation of `debug()`.\n */\n\nexports.formatArgs = formatArgs;\nexports.save = save;\nexports.load = load;\nexports.useColors = useColors;\nexports.storage = localstorage();\nexports.destroy = (() => {\n\tlet warned = false;\n\n\treturn () => {\n\t\tif (!warned) {\n\t\t\twarned = true;\n\t\t\tconsole.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');\n\t\t}\n\t};\n})();\n\n/**\n * Colors.\n */\n\nexports.colors = [\n\t'#0000CC',\n\t'#0000FF',\n\t'#0033CC',\n\t'#0033FF',\n\t'#0066CC',\n\t'#0066FF',\n\t'#0099CC',\n\t'#0099FF',\n\t'#00CC00',\n\t'#00CC33',\n\t'#00CC66',\n\t'#00CC99',\n\t'#00CCCC',\n\t'#00CCFF',\n\t'#3300CC',\n\t'#3300FF',\n\t'#3333CC',\n\t'#3333FF',\n\t'#3366CC',\n\t'#3366FF',\n\t'#3399CC',\n\t'#3399FF',\n\t'#33CC00',\n\t'#33CC33',\n\t'#33CC66',\n\t'#33CC99',\n\t'#33CCCC',\n\t'#33CCFF',\n\t'#6600CC',\n\t'#6600FF',\n\t'#6633CC',\n\t'#6633FF',\n\t'#66CC00',\n\t'#66CC33',\n\t'#9900CC',\n\t'#9900FF',\n\t'#9933CC',\n\t'#9933FF',\n\t'#99CC00',\n\t'#99CC33',\n\t'#CC0000',\n\t'#CC0033',\n\t'#CC0066',\n\t'#CC0099',\n\t'#CC00CC',\n\t'#CC00FF',\n\t'#CC3300',\n\t'#CC3333',\n\t'#CC3366',\n\t'#CC3399',\n\t'#CC33CC',\n\t'#CC33FF',\n\t'#CC6600',\n\t'#CC6633',\n\t'#CC9900',\n\t'#CC9933',\n\t'#CCCC00',\n\t'#CCCC33',\n\t'#FF0000',\n\t'#FF0033',\n\t'#FF0066',\n\t'#FF0099',\n\t'#FF00CC',\n\t'#FF00FF',\n\t'#FF3300',\n\t'#FF3333',\n\t'#FF3366',\n\t'#FF3399',\n\t'#FF33CC',\n\t'#FF33FF',\n\t'#FF6600',\n\t'#FF6633',\n\t'#FF9900',\n\t'#FF9933',\n\t'#FFCC00',\n\t'#FFCC33'\n];\n\n/**\n * Currently only WebKit-based Web Inspectors, Firefox >= v31,\n * and the Firebug extension (any Firefox version) are known\n * to support \"%c\" CSS customizations.\n *\n * TODO: add a `localStorage` variable to explicitly enable/disable colors\n */\n\n// eslint-disable-next-line complexity\nfunction useColors() {\n\t// NB: In an Electron preload script, document will be defined but not fully\n\t// initialized. Since we know we're in Chrome, we'll just detect this case\n\t// explicitly\n\tif (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {\n\t\treturn true;\n\t}\n\n\t// Internet Explorer and Edge do not support colors.\n\tif (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\\/(\\d+)/)) {\n\t\treturn false;\n\t}\n\n\tlet m;\n\n\t// Is webkit? http://stackoverflow.com/a/16459606/376773\n\t// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632\n\t// eslint-disable-next-line no-return-assign\n\treturn (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||\n\t\t// Is firebug? http://stackoverflow.com/a/398120/376773\n\t\t(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||\n\t\t// Is firefox >= v31?\n\t\t// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages\n\t\t(typeof navigator !== 'undefined' && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\\/(\\d+)/)) && parseInt(m[1], 10) >= 31) ||\n\t\t// Double check webkit in userAgent just in case we are in a worker\n\t\t(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\\/(\\d+)/));\n}\n\n/**\n * Colorize log arguments if enabled.\n *\n * @api public\n */\n\nfunction formatArgs(args) {\n\targs[0] = (this.useColors ? '%c' : '') +\n\t\tthis.namespace +\n\t\t(this.useColors ? ' %c' : ' ') +\n\t\targs[0] +\n\t\t(this.useColors ? '%c ' : ' ') +\n\t\t'+' + module.exports.humanize(this.diff);\n\n\tif (!this.useColors) {\n\t\treturn;\n\t}\n\n\tconst c = 'color: ' + this.color;\n\targs.splice(1, 0, c, 'color: inherit');\n\n\t// The final \"%c\" is somewhat tricky, because there could be other\n\t// arguments passed either before or after the %c, so we need to\n\t// figure out the correct index to insert the CSS into\n\tlet index = 0;\n\tlet lastC = 0;\n\targs[0].replace(/%[a-zA-Z%]/g, match => {\n\t\tif (match === '%%') {\n\t\t\treturn;\n\t\t}\n\t\tindex++;\n\t\tif (match === '%c') {\n\t\t\t// We only are interested in the *last* %c\n\t\t\t// (the user may have provided their own)\n\t\t\tlastC = index;\n\t\t}\n\t});\n\n\targs.splice(lastC, 0, c);\n}\n\n/**\n * Invokes `console.debug()` when available.\n * No-op when `console.debug` is not a \"function\".\n * If `console.debug` is not available, falls back\n * to `console.log`.\n *\n * @api public\n */\nexports.log = console.debug || console.log || (() => {});\n\n/**\n * Save `namespaces`.\n *\n * @param {String} namespaces\n * @api private\n */\nfunction save(namespaces) {\n\ttry {\n\t\tif (namespaces) {\n\t\t\texports.storage.setItem('debug', namespaces);\n\t\t} else {\n\t\t\texports.storage.removeItem('debug');\n\t\t}\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n}\n\n/**\n * Load `namespaces`.\n *\n * @return {String} returns the previously persisted debug modes\n * @api private\n */\nfunction load() {\n\tlet r;\n\ttry {\n\t\tr = exports.storage.getItem('debug') || exports.storage.getItem('DEBUG') ;\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n\n\t// If debug isn't set in LS, and we're in Electron, try to load $DEBUG\n\tif (!r && typeof process !== 'undefined' && 'env' in process) {\n\t\tr = process.env.DEBUG;\n\t}\n\n\treturn r;\n}\n\n/**\n * Localstorage attempts to return the localstorage.\n *\n * This is necessary because safari throws\n * when a user disables cookies/localstorage\n * and you attempt to access it.\n *\n * @return {LocalStorage}\n * @api private\n */\n\nfunction localstorage() {\n\ttry {\n\t\t// TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context\n\t\t// The Browser also has localStorage in the global context.\n\t\treturn localStorage;\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n}\n\nmodule.exports = require('./common')(exports);\n\nconst {formatters} = module.exports;\n\n/**\n * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.\n */\n\nformatters.j = function (v) {\n\ttry {\n\t\treturn JSON.stringify(v);\n\t} catch (error) {\n\t\treturn '[UnexpectedJSONParseError]: ' + error.message;\n\t}\n};\n","import debug from \"debug\";\n/** @hidden */\nexport const logger = debug(\"applesauce\");\n","import { binarySearch, insertEventIntoDescendingList } from \"nostr-tools/utils\";\nimport { getIndexableTags, INDEXABLE_TAGS } from \"../helpers/event-tags.js\";\nimport { createReplaceableAddress, isReplaceable } from \"../helpers/event.js\";\nimport { LRU } from \"../helpers/lru.js\";\nimport { logger } from \"../logger.js\";\n/** An in-memory database of events */\nexport class EventMemory {\n log = logger.extend(\"EventMemory\");\n /** Indexes */\n kinds = new Map();\n authors = new Map();\n tags = new LRU();\n created_at = [];\n /** Composite index for kind+author queries (common pattern) */\n kindAuthor = new Map();\n /** LRU cache of last events touched */\n events = new LRU();\n /** A sorted array of replaceable events by address */\n replaceable = new Map();\n /** The number of events in the database */\n get size() {\n return this.events.size;\n }\n /** Checks if the database contains an event without touching it */\n hasEvent(id) {\n return this.events.has(id);\n }\n /** Gets a single event based on id */\n getEvent(id) {\n return this.events.get(id);\n }\n /** Checks if the event set has a replaceable event */\n hasReplaceable(kind, pubkey, identifier) {\n const events = this.replaceable.get(createReplaceableAddress(kind, pubkey, identifier));\n return !!events && events.length > 0;\n }\n /** Gets the latest replaceable event */\n getReplaceable(kind, pubkey, identifier) {\n const address = createReplaceableAddress(kind, pubkey, identifier);\n const events = this.replaceable.get(address);\n return events?.[0];\n }\n /** Gets the history of a replaceable event */\n getReplaceableHistory(kind, pubkey, identifier) {\n const address = createReplaceableAddress(kind, pubkey, identifier);\n return this.replaceable.get(address);\n }\n /** Gets all events that match the filters */\n getByFilters(filters) {\n return Array.from(this.getEventsForFilters(Array.isArray(filters) ? filters : [filters]));\n }\n /** Gets a timeline of events that match the filters */\n getTimeline(filters) {\n const timeline = [];\n const events = this.getByFilters(filters);\n for (const event of events)\n insertEventIntoDescendingList(timeline, event);\n return timeline;\n }\n /** Inserts an event into the database and notifies all subscriptions */\n add(event) {\n const id = event.id;\n const current = this.events.get(id);\n if (current)\n return current;\n this.events.set(id, event);\n this.getKindIndex(event.kind).add(event);\n this.getAuthorsIndex(event.pubkey).add(event);\n this.getKindAuthorIndex(event.kind, event.pubkey).add(event);\n // Add the event to the tag indexes if they exist\n for (const tag of getIndexableTags(event)) {\n if (this.tags.has(tag))\n this.getTagIndex(tag).add(event);\n }\n // Insert into time index\n insertEventIntoDescendingList(this.created_at, event);\n // Insert into replaceable index\n if (isReplaceable(event.kind)) {\n const identifier = event.tags.find((t) => t[0] === \"d\")?.[1];\n const address = createReplaceableAddress(event.kind, event.pubkey, identifier);\n let array = this.replaceable.get(address);\n if (!this.replaceable.has(address)) {\n // add an empty array if there is no array\n array = [];\n this.replaceable.set(address, array);\n }\n // insert the event into the sorted array\n insertEventIntoDescendingList(array, event);\n }\n return event;\n }\n /** Removes an event from the database and notifies all subscriptions */\n remove(eventOrId) {\n let event = typeof eventOrId === \"string\" ? this.events.get(eventOrId) : eventOrId;\n if (!event)\n return false;\n const id = event.id;\n // only remove events that are known\n if (!this.events.has(id))\n return false;\n this.getAuthorsIndex(event.pubkey).delete(event);\n this.getKindIndex(event.kind).delete(event);\n // Remove from composite kind+author index\n const kindAuthorKey = `${event.kind}:${event.pubkey}`;\n if (this.kindAuthor.has(kindAuthorKey)) {\n this.kindAuthor.get(kindAuthorKey).delete(event);\n }\n for (const tag of getIndexableTags(event)) {\n if (this.tags.has(tag)) {\n this.getTagIndex(tag).delete(event);\n }\n }\n // remove from created_at index using binary search\n this.removeFromSortedArray(this.created_at, event);\n this.events.delete(id);\n // remove from replaceable index using binary search\n if (isReplaceable(event.kind)) {\n const identifier = event.tags.find((t) => t[0] === \"d\")?.[1];\n const address = createReplaceableAddress(event.kind, event.pubkey, identifier);\n const array = this.replaceable.get(address);\n if (array)\n this.removeFromSortedArray(array, event);\n }\n // remove any claims this event has\n this.claims.delete(event);\n return true;\n }\n /** Remove multiple events that match the given filters */\n removeByFilters(filters) {\n const eventsToRemove = this.getByFilters(filters);\n let removedCount = 0;\n for (const event of eventsToRemove) {\n if (this.remove(event)) {\n removedCount++;\n }\n }\n return removedCount;\n }\n /** Notify the database that an event has updated */\n update(_event) {\n // Do nothing\n }\n /** A weak map of events to claim reference counts */\n claims = new WeakMap();\n /** Moves an event to the top of the LRU cache */\n touch(event) {\n // Make sure the event is in the database before adding it to the LRU\n if (!this.events.has(event.id))\n return;\n // Move to the top of the LRU\n this.events.set(event.id, event);\n }\n /** Increments the claim count on the event and touches it */\n claim(event) {\n const currentCount = this.claims.get(event) || 0;\n this.claims.set(event, currentCount + 1);\n // always touch event\n this.touch(event);\n }\n /** Checks if an event is claimed by anything */\n isClaimed(event) {\n const count = this.claims.get(event);\n return count !== undefined && count > 0;\n }\n /** Decrements the claim count on an event */\n removeClaim(event) {\n const currentCount = this.claims.get(event);\n if (currentCount !== undefined && currentCount > 0) {\n const newCount = currentCount - 1;\n if (newCount === 0) {\n this.claims.delete(event);\n }\n else {\n this.claims.set(event, newCount);\n }\n }\n }\n /** Removes all claims on an event */\n clearClaim(event) {\n this.claims.delete(event);\n }\n /** Returns a generator of unclaimed events in order of least used */\n *unclaimed() {\n let removed = 0;\n let cursor = this.events.first;\n while (cursor) {\n const event = cursor.value;\n if (!this.isClaimed(event))\n yield event;\n cursor = cursor.next;\n }\n return removed;\n }\n /** Removes events that are not claimed (free up memory) */\n prune(limit) {\n let removed = 0;\n const unclaimed = this.unclaimed();\n for (const event of unclaimed) {\n this.remove(event);\n removed++;\n if (limit && removed >= limit)\n break;\n }\n return removed;\n }\n /** Index helper methods */\n getKindIndex(kind) {\n if (!this.kinds.has(kind))\n this.kinds.set(kind, new Set());\n return this.kinds.get(kind);\n }\n getAuthorsIndex(author) {\n if (!this.authors.has(author))\n this.authors.set(author, new Set());\n return this.authors.get(author);\n }\n getKindAuthorIndex(kind, pubkey) {\n const key = `${kind}:${pubkey}`;\n if (!this.kindAuthor.has(key))\n this.kindAuthor.set(key, new Set());\n return this.kindAuthor.get(key);\n }\n getTagIndex(tagAndValue) {\n if (!this.tags.has(tagAndValue)) {\n // build new tag index from existing events\n const events = new Set();\n const ts = Date.now();\n for (const event of this.events.values()) {\n if (getIndexableTags(event).has(tagAndValue)) {\n events.add(event);\n }\n }\n const took = Date.now() - ts;\n if (took > 100)\n this.log(`Built index ${tagAndValue} took ${took}ms`);\n this.tags.set(tagAndValue, events);\n }\n return this.tags.get(tagAndValue);\n }\n /**\n * Helper method to remove an event from a sorted array using binary search.\n * Falls back to indexOf if binary search doesn't find exact match.\n */\n removeFromSortedArray(array, event) {\n if (array.length === 0)\n return;\n // Use binary search to find the approximate position\n const result = binarySearch(array, (mid) => mid.created_at - event.created_at);\n if (result) {\n let index = result[0];\n // Binary search finds the position, but we need to find the exact event\n // since multiple events can have the same created_at timestamp.\n // Search backwards and forwards from the found position\n let found = false;\n // Check the found position first\n if (array[index] === event) {\n array.splice(index, 1);\n return;\n }\n // Search backwards\n for (let i = index - 1; i >= 0 && array[i].created_at === event.created_at; i--) {\n if (array[i] === event) {\n array.splice(i, 1);\n found = true;\n break;\n }\n }\n if (found)\n return;\n // Search forwards\n for (let i = index + 1; i < array.length && array[i].created_at === event.created_at; i++) {\n if (array[i] === event) {\n array.splice(i, 1);\n return;\n }\n }\n }\n // Fallback to indexOf if binary search doesn't find the event\n // This should rarely happen, but ensures correctness\n const idx = array.indexOf(event);\n if (idx !== -1)\n array.splice(idx, 1);\n }\n /** Iterates over all events by author */\n *iterateAuthors(authors) {\n for (const author of authors) {\n const events = this.authors.get(author);\n if (events) {\n for (const event of events)\n yield event;\n }\n }\n }\n /** Iterates over all events by indexable tag and value */\n *iterateTag(tag, values) {\n for (const value of values) {\n const events = this.getTagIndex(tag + \":\" + value);\n if (events) {\n for (const event of events)\n yield event;\n }\n }\n }\n /** Iterates over all events by kind */\n *iterateKinds(kinds) {\n for (const kind of kinds) {\n const events = this.kinds.get(kind);\n if (events) {\n for (const event of events)\n yield event;\n }\n }\n }\n /** Iterates over all events by time */\n *iterateTime(since, until) {\n let startIndex = 0;\n let endIndex = this.created_at.length - 1;\n // If until is set, use binary search to find better start index\n let start = until\n ? binarySearch(this.created_at, (mid) => {\n return mid.created_at - until;\n })\n : undefined;\n if (start)\n startIndex = start[0];\n // If since is set, use binary search to find better end index\n const end = since\n ? binarySearch(this.created_at, (mid) => {\n return mid.created_at - since;\n })\n : undefined;\n if (end)\n endIndex = end[0];\n // Yield events in the range, filtering by exact bounds\n for (let i = startIndex; i <= endIndex; i++) {\n const event = this.created_at[i];\n if (until !== undefined && event.created_at > until)\n continue;\n if (since !== undefined && event.created_at < since)\n break;\n yield event;\n }\n }\n /** Iterates over all events by id */\n *iterateIds(ids) {\n for (const id of ids) {\n if (this.events.has(id))\n yield this.events.get(id);\n }\n }\n /** Returns all events that match the filter */\n getEventsForFilter(filter) {\n // search is not supported, return an empty set\n if (filter.search)\n return new Set();\n let first = true;\n let events = new Set();\n const and = (iterable) => {\n const set = iterable instanceof Set ? iterable : new Set(iterable);\n if (first) {\n events = set;\n first = false;\n }\n else {\n for (const event of events) {\n if (!set.has(event))\n events.delete(event);\n }\n }\n return events;\n };\n if (filter.ids)\n and(this.iterateIds(filter.ids));\n let time = null;\n // query for time first if since is set\n if (filter.since !== undefined) {\n time = Array.from(this.iterateTime(filter.since, filter.until));\n and(time);\n }\n // Process AND tag filters (& prefix) first - NIP-ND\n // AND takes precedence and requires ALL values to be present\n for (const t of INDEXABLE_TAGS) {\n const key = `&${t}`;\n const values = filter[key];\n if (values?.length) {\n // For AND logic, we need to intersect events that have ALL the specified tag values\n // We do this by iterating through each value and intersecting the results\n for (const value of values) {\n and(this.iterateTag(t, [value]));\n }\n }\n }\n // Process OR tag filters (# prefix)\n // Skip values that are in AND tags (NIP-ND rule)\n for (const t of INDEXABLE_TAGS) {\n const key = `#${t}`;\n const values = filter[key];\n if (values?.length) {\n // Check if there's a corresponding AND filter for this tag\n const andKey = `&${t}`;\n const andValues = filter[andKey];\n // Filter out values that are in AND tags (NIP-ND rule)\n const filteredValues = andValues ? values.filter((v) => !andValues.includes(v)) : values;\n // Only apply OR filter if there are values left after filtering\n if (filteredValues.length > 0)\n and(this.iterateTag(t, filteredValues));\n }\n }\n // Optimize: Use composite kind+author index when both are present and the cross-product is small\n if (filter.authors && filter.kinds && filter.authors.length * filter.kinds.length <= 20) {\n const combined = new Set();\n for (const kind of filter.kinds) {\n for (const author of filter.authors) {\n const key = `${kind}:${author}`;\n const kindAuthorEvents = this.kindAuthor.get(key);\n if (kindAuthorEvents) {\n for (const event of kindAuthorEvents)\n combined.add(event);\n }\n }\n }\n and(combined);\n }\n else {\n // Use separate indexes\n if (filter.authors)\n and(this.iterateAuthors(filter.authors));\n if (filter.kinds)\n and(this.iterateKinds(filter.kinds));\n }\n // query for time last if only until is set\n if (filter.since === undefined && filter.until !== undefined) {\n time = Array.from(this.iterateTime(filter.since, filter.until));\n and(time);\n }\n // If no filters were applied (empty filter), return all events\n if (first) {\n return new Set(this.events.values());\n }\n // if the filter queried on time and has a limit. truncate the events now\n if (filter.limit && time) {\n const limited = new Set();\n for (const event of time) {\n if (limited.size >= filter.limit)\n break;\n if (events.has(event))\n limited.add(event);\n }\n return limited;\n }\n return events;\n }\n /** Returns all events that match the filters */\n getEventsForFilters(filters) {\n if (filters.length === 0)\n return new Set();\n let events = new Set();\n for (const filter of filters) {\n const filtered = this.getEventsForFilter(filter);\n for (const event of filtered)\n events.add(event);\n }\n return events;\n }\n /** Resets the event set */\n reset() {\n this.events.clear();\n this.kinds.clear();\n this.authors.clear();\n this.kindAuthor.clear();\n this.tags.clear();\n this.created_at = [];\n this.replaceable.clear();\n this.claims = new WeakMap();\n }\n}\n","'use strict';\n\nfunction pad (hash, len) {\n while (hash.length < len) {\n hash = '0' + hash;\n }\n return hash;\n}\n\nfunction fold (hash, text) {\n var i;\n var chr;\n var len;\n if (text.length === 0) {\n return hash;\n }\n for (i = 0, len = text.length; i < len; i++) {\n chr = text.charCodeAt(i);\n hash = ((hash << 5) - hash) + chr;\n hash |= 0;\n }\n return hash < 0 ? hash * -2 : hash;\n}\n\nfunction foldObject (hash, o, seen) {\n return Object.keys(o).sort().reduce(foldKey, hash);\n function foldKey (hash, key) {\n return foldValue(hash, o[key], key, seen);\n }\n}\n\nfunction foldValue (input, value, key, seen) {\n var hash = fold(fold(fold(input, key), toString(value)), typeof value);\n if (value === null) {\n return fold(hash, 'null');\n }\n if (value === undefined) {\n return fold(hash, 'undefined');\n }\n if (typeof value === 'object' || typeof value === 'function') {\n if (seen.indexOf(value) !== -1) {\n return fold(hash, '[Circular]' + key);\n }\n seen.push(value);\n\n var objHash = foldObject(hash, value, seen)\n\n if (!('valueOf' in value) || typeof value.valueOf !== 'function') {\n return objHash;\n }\n\n try {\n return fold(objHash, String(value.valueOf()))\n } catch (err) {\n return fold(objHash, '[valueOf exception]' + (err.stack || err.message))\n }\n }\n return fold(hash, value.toString());\n}\n\nfunction toString (o) {\n return Object.prototype.toString.call(o);\n}\n\nfunction sum (o) {\n return pad(foldValue(0, o, '', []).toString(16), 8);\n}\n\nmodule.exports = sum;\n","import equal from \"fast-deep-equal\";\nimport { getIndexableTags } from \"./event-tags.js\";\n/**\n * Copied from nostr-tools and modified to use {@link getIndexableTags}\n * Extended to support NIP-ND AND operator with `&` prefix\n * @see https://github.com/nbd-wtf/nostr-tools/blob/a61cde77eacc9518001f11d7f67f1a50ae05fd80/filter.ts\n */\nexport function matchFilter(filter, event) {\n if (filter.ids && filter.ids.indexOf(event.id) === -1)\n return false;\n if (filter.kinds && filter.kinds.indexOf(event.kind) === -1)\n return false;\n if (filter.authors && filter.authors.indexOf(event.pubkey) === -1)\n return false;\n if (filter.since && event.created_at < filter.since)\n return false;\n if (filter.until && event.created_at > filter.until)\n return false;\n // Process AND tag filters (& prefix) first - NIP-ND\n // AND takes precedence and requires ALL values to be present\n for (let f in filter) {\n if (f[0] === \"&\") {\n let tagName = f.slice(1);\n let values = filter[f];\n if (values && values.length > 0) {\n const tags = getIndexableTags(event);\n // ALL values must be present (AND logic)\n for (const value of values) {\n if (!tags.has(tagName + \":\" + value)) {\n return false;\n }\n }\n }\n }\n }\n // Process OR tag filters (# prefix)\n // Skip values that are in AND tags (NIP-ND rule)\n for (let f in filter) {\n if (f[0] === \"#\") {\n let tagName = f.slice(1);\n let values = filter[f];\n if (values) {\n // Check if there's a corresponding AND filter for this tag\n const andKey = `&${tagName}`;\n const andValues = filter[andKey];\n // Filter out values that are in AND tags (NIP-ND rule)\n const filteredValues = andValues ? values.filter((v) => !andValues.includes(v)) : values;\n // If there are no values left after filtering, skip this check\n if (filteredValues.length === 0)\n continue;\n const tags = getIndexableTags(event);\n if (filteredValues.some((v) => tags.has(tagName + \":\" + v)) === false)\n return false;\n }\n }\n }\n return true;\n}\n/** Copied from nostr-tools and modified to use {@link matchFilter} */\nexport function matchFilters(filters, event) {\n for (let i = 0; i < filters.length; i++) {\n if (matchFilter(filters[i], event))\n return true;\n }\n return false;\n}\n/** Copied from nostr-tools and modified to support undefined values and NIP-ND AND operator */\nexport function mergeFilters(...filters) {\n let result = {};\n for (let i = 0; i < filters.length; i++) {\n let filter = filters[i];\n Object.entries(filter).forEach(([property, values]) => {\n // skip undefined\n if (values === undefined)\n return;\n if (property === \"kinds\" ||\n property === \"ids\" ||\n property === \"authors\" ||\n property[0] === \"#\" ||\n property[0] === \"&\") {\n // @ts-ignore\n result[property] = result[property] || [];\n // @ts-ignore\n for (let v = 0; v < values.length; v++) {\n // @ts-ignore\n let value = values[v];\n // @ts-ignore\n if (!result[property].includes(value))\n result[property].push(value);\n }\n }\n });\n if (filter.limit && (!result.limit || filter.limit > result.limit))\n result.limit = filter.limit;\n if (filter.until && (!result.until || filter.until > result.until))\n result.until = filter.until;\n if (filter.since && (!result.since || filter.since < result.since))\n result.since = filter.since;\n }\n return result;\n}\n/** Check if two filters are equal */\nexport function isFilterEqual(a, b) {\n return equal(a, b);\n}\n","import { map } from \"rxjs/operators\";\nimport { BLOSSOM_SERVER_LIST_KIND, getBlossomServersFromList } from \"../helpers/blossom.js\";\n/** A model that returns a users blossom servers */\nexport function UserBlossomServersModel(user) {\n if (typeof user === \"string\")\n user = { pubkey: user };\n return (store) => store\n .replaceable({ kind: BLOSSOM_SERVER_LIST_KIND, pubkey: user.pubkey, relays: user.relays })\n .pipe(map((event) => (event ? getBlossomServersFromList(event) : [])));\n}\n","import { isNameValueTag, processTags } from \"./tags.js\";\nexport const BLOSSOM_SERVER_LIST_KIND = 10063;\n/** Check if two servers are the same */\nexport function areBlossomServersEqual(a, b) {\n const hostnameA = new URL(\"/\", a).toString();\n const hostnameB = new URL(\"/\", b).toString();\n return hostnameA === hostnameB;\n}\n/** Checks if a string is a sha256 hash */\nexport function isSha256(str) {\n return !!str.match(/^[0-9a-f]{64}$/);\n}\n/** Returns an ordered array of servers found in a server list event (10063) */\nexport function getBlossomServersFromList(event) {\n const tags = Array.isArray(event) ? event : event.tags;\n return processTags(tags, (tag) => {\n if (isNameValueTag(tag, \"server\") && URL.canParse(tag[1]))\n return new URL(\"/\", tag[1]);\n else\n return undefined;\n });\n}\n/** A method that merges multiple arrays of blossom servers into a single array of unique servers */\nexport function mergeBlossomServers(...servers) {\n let merged = [];\n const seen = new Set();\n for (const arg of servers) {\n let arr = Array.isArray(arg) ? arg : [arg];\n for (const s of arr) {\n if (s === null || s === undefined)\n continue;\n const key = new URL(\"/\", s).toString();\n if (seen.has(key))\n continue;\n seen.add(key);\n merged.push(s);\n }\n }\n return merged;\n}\n","import { kinds } from \"nostr-tools\";\nimport { npubEncode } from \"nostr-tools/nip19\";\nimport { getOrComputeCachedValue } from \"./cache.js\";\nimport { safeParse } from \"./index.js\";\nexport const ProfileContentSymbol = Symbol.for(\"profile-content\");\nexport function getProfileContent(event) {\n return getOrComputeCachedValue(event, ProfileContentSymbol, () => {\n const profile = safeParse(event.content);\n if (!profile)\n return undefined;\n // ensure nip05 is a string\n if (profile.nip05 && typeof profile.nip05 !== \"string\")\n profile.nip05 = String(profile.nip05);\n // add missing protocol to website\n if (profile.website && profile.website?.length > 0 && profile.website?.startsWith(\"http\") === false) {\n profile.website = \"https://\" + profile.website;\n }\n return profile;\n });\n}\n/** Checks if the content of the kind 0 event is valid JSON */\nexport function isValidProfile(profile) {\n if (!profile)\n return false;\n if (profile.kind !== kinds.Metadata && profile.kind !== kinds.Handlerinformation)\n return false;\n // Check if the profile content is valid\n if (!getProfileContent(profile))\n return false;\n return true;\n}\nexport function getProfilePicture(metadata, fallback) {\n if (!metadata)\n return fallback;\n // Get the metadata from the nostr event\n if (\"pubkey\" in metadata && \"id\" in metadata && \"sig\" in metadata) {\n if (isValidProfile(metadata))\n metadata = getProfileContent(metadata);\n else\n metadata = undefined;\n }\n // Return the display name or fallback\n return (metadata?.picture || metadata?.image || fallback)?.trim();\n}\nexport function getDisplayName(metadata, fallback) {\n if (!metadata)\n return fallback;\n // Get the metadata from the nostr event\n if (\"pubkey\" in metadata && \"id\" in metadata && \"sig\" in metadata) {\n // Set the fallback to the npub if not set\n if (!fallback) {\n const npub = npubEncode(metadata.pubkey);\n fallback = npub.slice(0, 5 + 4) + \"…\" + npub.slice(-4);\n }\n // Get the profile content\n if (isValidProfile(metadata))\n metadata = getProfileContent(metadata);\n else\n metadata = undefined;\n }\n // Return the display name or fallback\n return (metadata?.display_name || metadata?.displayName || metadata?.name || fallback)?.trim();\n}\n","/** Returns the parsed JSON or undefined if invalid */\nexport function safeParse(str) {\n try {\n return JSON.parse(str);\n }\n catch (error) {\n return undefined;\n }\n}\n","\"use strict\";\n/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.bytes = exports.stringToBytes = exports.str = exports.bytesToString = exports.hex = exports.utf8 = exports.bech32m = exports.bech32 = exports.base58check = exports.base58xmr = exports.base58xrp = exports.base58flickr = exports.base58 = exports.base64url = exports.base64 = exports.base32crockford = exports.base32hex = exports.base32 = exports.base16 = exports.utils = exports.assertNumber = void 0;\nfunction assertNumber(n) {\n if (!Number.isSafeInteger(n))\n throw new Error(`Wrong integer: ${n}`);\n}\nexports.assertNumber = assertNumber;\nfunction chain(...args) {\n const wrap = (a, b) => (c) => a(b(c));\n const encode = Array.from(args)\n .reverse()\n .reduce((acc, i) => (acc ? wrap(acc, i.encode) : i.encode), undefined);\n const decode = args.reduce((acc, i) => (acc ? wrap(acc, i.decode) : i.decode), undefined);\n return { encode, decode };\n}\nfunction alphabet(alphabet) {\n return {\n encode: (digits) => {\n if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))\n throw new Error('alphabet.encode input should be an array of numbers');\n return digits.map((i) => {\n assertNumber(i);\n if (i < 0 || i >= alphabet.length)\n throw new Error(`Digit index outside alphabet: ${i} (alphabet: ${alphabet.length})`);\n return alphabet[i];\n });\n },\n decode: (input) => {\n if (!Array.isArray(input) || (input.length && typeof input[0] !== 'string'))\n throw new Error('alphabet.decode input should be array of strings');\n return input.map((letter) => {\n if (typeof letter !== 'string')\n throw new Error(`alphabet.decode: not string element=${letter}`);\n const index = alphabet.indexOf(letter);\n if (index === -1)\n throw new Error(`Unknown letter: \"${letter}\". Allowed: ${alphabet}`);\n return index;\n });\n },\n };\n}\nfunction join(separator = '') {\n if (typeof separator !== 'string')\n throw new Error('join separator should be string');\n return {\n encode: (from) => {\n if (!Array.isArray(from) || (from.length && typeof from[0] !== 'string'))\n throw new Error('join.encode input should be array of strings');\n for (let i of from)\n if (typeof i !== 'string')\n throw new Error(`join.encode: non-string input=${i}`);\n return from.join(separator);\n },\n decode: (to) => {\n if (typeof to !== 'string')\n throw new Error('join.decode input should be string');\n return to.split(separator);\n },\n };\n}\nfunction padding(bits, chr = '=') {\n assertNumber(bits);\n if (typeof chr !== 'string')\n throw new Error('padding chr should be string');\n return {\n encode(data) {\n if (!Array.isArray(data) || (data.length && typeof data[0] !== 'string'))\n throw new Error('padding.encode input should be array of strings');\n for (let i of data)\n if (typeof i !== 'string')\n throw new Error(`padding.encode: non-string input=${i}`);\n while ((data.length * bits) % 8)\n data.push(chr);\n return data;\n },\n decode(input) {\n if (!Array.isArray(input) || (input.length && typeof input[0] !== 'string'))\n throw new Error('padding.encode input should be array of strings');\n for (let i of input)\n if (typeof i !== 'string')\n throw new Error(`padding.decode: non-string input=${i}`);\n let end = input.length;\n if ((end * bits) % 8)\n throw new Error('Invalid padding: string should have whole number of bytes');\n for (; end > 0 && input[end - 1] === chr; end--) {\n if (!(((end - 1) * bits) % 8))\n throw new Error('Invalid padding: string has too much padding');\n }\n return input.slice(0, end);\n },\n };\n}\nfunction normalize(fn) {\n if (typeof fn !== 'function')\n throw new Error('normalize fn should be function');\n return { encode: (from) => from, decode: (to) => fn(to) };\n}\nfunction convertRadix(data, from, to) {\n if (from < 2)\n throw new Error(`convertRadix: wrong from=${from}, base cannot be less than 2`);\n if (to < 2)\n throw new Error(`convertRadix: wrong to=${to}, base cannot be less than 2`);\n if (!Array.isArray(data))\n throw new Error('convertRadix: data should be array');\n if (!data.length)\n return [];\n let pos = 0;\n const res = [];\n const digits = Array.from(data);\n digits.forEach((d) => {\n assertNumber(d);\n if (d < 0 || d >= from)\n throw new Error(`Wrong integer: ${d}`);\n });\n while (true) {\n let carry = 0;\n let done = true;\n for (let i = pos; i < digits.length; i++) {\n const digit = digits[i];\n const digitBase = from * carry + digit;\n if (!Number.isSafeInteger(digitBase) ||\n (from * carry) / from !== carry ||\n digitBase - digit !== from * carry) {\n throw new Error('convertRadix: carry overflow');\n }\n carry = digitBase % to;\n digits[i] = Math.floor(digitBase / to);\n if (!Number.isSafeInteger(digits[i]) || digits[i] * to + carry !== digitBase)\n throw new Error('convertRadix: carry overflow');\n if (!done)\n continue;\n else if (!digits[i])\n pos = i;\n else\n done = false;\n }\n res.push(carry);\n if (done)\n break;\n }\n for (let i = 0; i < data.length - 1 && data[i] === 0; i++)\n res.push(0);\n return res.reverse();\n}\nconst gcd = (a, b) => (!b ? a : gcd(b, a % b));\nconst radix2carry = (from, to) => from + (to - gcd(from, to));\nfunction convertRadix2(data, from, to, padding) {\n if (!Array.isArray(data))\n throw new Error('convertRadix2: data should be array');\n if (from <= 0 || from > 32)\n throw new Error(`convertRadix2: wrong from=${from}`);\n if (to <= 0 || to > 32)\n throw new Error(`convertRadix2: wrong to=${to}`);\n if (radix2carry(from, to) > 32) {\n throw new Error(`convertRadix2: carry overflow from=${from} to=${to} carryBits=${radix2carry(from, to)}`);\n }\n let carry = 0;\n let pos = 0;\n const mask = 2 ** to - 1;\n const res = [];\n for (const n of data) {\n assertNumber(n);\n if (n >= 2 ** from)\n throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);\n carry = (carry << from) | n;\n if (pos + from > 32)\n throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from}`);\n pos += from;\n for (; pos >= to; pos -= to)\n res.push(((carry >> (pos - to)) & mask) >>> 0);\n carry &= 2 ** pos - 1;\n }\n carry = (carry << (to - pos)) & mask;\n if (!padding && pos >= from)\n throw new Error('Excess padding');\n if (!padding && carry)\n throw new Error(`Non-zero padding: ${carry}`);\n if (padding && pos > 0)\n res.push(carry >>> 0);\n return res;\n}\nfunction radix(num) {\n assertNumber(num);\n return {\n encode: (bytes) => {\n if (!(bytes instanceof Uint8Array))\n throw new Error('radix.encode input should be Uint8Array');\n return convertRadix(Array.from(bytes), 2 ** 8, num);\n },\n decode: (digits) => {\n if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))\n throw new Error('radix.decode input should be array of strings');\n return Uint8Array.from(convertRadix(digits, num, 2 ** 8));\n },\n };\n}\nfunction radix2(bits, revPadding = false) {\n assertNumber(bits);\n if (bits <= 0 || bits > 32)\n throw new Error('radix2: bits should be in (0..32]');\n if (radix2carry(8, bits) > 32 || radix2carry(bits, 8) > 32)\n throw new Error('radix2: carry overflow');\n return {\n encode: (bytes) => {\n if (!(bytes instanceof Uint8Array))\n throw new Error('radix2.encode input should be Uint8Array');\n return convertRadix2(Array.from(bytes), 8, bits, !revPadding);\n },\n decode: (digits) => {\n if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))\n throw new Error('radix2.decode input should be array of strings');\n return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding));\n },\n };\n}\nfunction unsafeWrapper(fn) {\n if (typeof fn !== 'function')\n throw new Error('unsafeWrapper fn should be function');\n return function (...args) {\n try {\n return fn.apply(null, args);\n }\n catch (e) { }\n };\n}\nfunction checksum(len, fn) {\n assertNumber(len);\n if (typeof fn !== 'function')\n throw new Error('checksum fn should be function');\n return {\n encode(data) {\n if (!(data instanceof Uint8Array))\n throw new Error('checksum.encode: input should be Uint8Array');\n const checksum = fn(data).slice(0, len);\n const res = new Uint8Array(data.length + len);\n res.set(data);\n res.set(checksum, data.length);\n return res;\n },\n decode(data) {\n if (!(data instanceof Uint8Array))\n throw new Error('checksum.decode: input should be Uint8Array');\n const payload = data.slice(0, -len);\n const newChecksum = fn(payload).slice(0, len);\n const oldChecksum = data.slice(-len);\n for (let i = 0; i < len; i++)\n if (newChecksum[i] !== oldChecksum[i])\n throw new Error('Invalid checksum');\n return payload;\n },\n };\n}\nexports.utils = { alphabet, chain, checksum, radix, radix2, join, padding };\nexports.base16 = chain(radix2(4), alphabet('0123456789ABCDEF'), join(''));\nexports.base32 = chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), padding(5), join(''));\nexports.base32hex = chain(radix2(5), alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'), padding(5), join(''));\nexports.base32crockford = chain(radix2(5), alphabet('0123456789ABCDEFGHJKMNPQRSTVWXYZ'), join(''), normalize((s) => s.toUpperCase().replace(/O/g, '0').replace(/[IL]/g, '1')));\nexports.base64 = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), padding(6), join(''));\nexports.base64url = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), padding(6), join(''));\nconst genBase58 = (abc) => chain(radix(58), alphabet(abc), join(''));\nexports.base58 = genBase58('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');\nexports.base58flickr = genBase58('123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ');\nexports.base58xrp = genBase58('rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz');\nconst XMR_BLOCK_LEN = [0, 2, 3, 5, 6, 7, 9, 10, 11];\nexports.base58xmr = {\n encode(data) {\n let res = '';\n for (let i = 0; i < data.length; i += 8) {\n const block = data.subarray(i, i + 8);\n res += exports.base58.encode(block).padStart(XMR_BLOCK_LEN[block.length], '1');\n }\n return res;\n },\n decode(str) {\n let res = [];\n for (let i = 0; i < str.length; i += 11) {\n const slice = str.slice(i, i + 11);\n const blockLen = XMR_BLOCK_LEN.indexOf(slice.length);\n const block = exports.base58.decode(slice);\n for (let j = 0; j < block.length - blockLen; j++) {\n if (block[j] !== 0)\n throw new Error('base58xmr: wrong padding');\n }\n res = res.concat(Array.from(block.slice(block.length - blockLen)));\n }\n return Uint8Array.from(res);\n },\n};\nconst base58check = (sha256) => chain(checksum(4, (data) => sha256(sha256(data))), exports.base58);\nexports.base58check = base58check;\nconst BECH_ALPHABET = chain(alphabet('qpzry9x8gf2tvdw0s3jn54khce6mua7l'), join(''));\nconst POLYMOD_GENERATORS = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];\nfunction bech32Polymod(pre) {\n const b = pre >> 25;\n let chk = (pre & 0x1ffffff) << 5;\n for (let i = 0; i < POLYMOD_GENERATORS.length; i++) {\n if (((b >> i) & 1) === 1)\n chk ^= POLYMOD_GENERATORS[i];\n }\n return chk;\n}\nfunction bechChecksum(prefix, words, encodingConst = 1) {\n const len = prefix.length;\n let chk = 1;\n for (let i = 0; i < len; i++) {\n const c = prefix.charCodeAt(i);\n if (c < 33 || c > 126)\n throw new Error(`Invalid prefix (${prefix})`);\n chk = bech32Polymod(chk) ^ (c >> 5);\n }\n chk = bech32Polymod(chk);\n for (let i = 0; i < len; i++)\n chk = bech32Polymod(chk) ^ (prefix.charCodeAt(i) & 0x1f);\n for (let v of words)\n chk = bech32Polymod(chk) ^ v;\n for (let i = 0; i < 6; i++)\n chk = bech32Polymod(chk);\n chk ^= encodingConst;\n return BECH_ALPHABET.encode(convertRadix2([chk % 2 ** 30], 30, 5, false));\n}\nfunction genBech32(encoding) {\n const ENCODING_CONST = encoding === 'bech32' ? 1 : 0x2bc830a3;\n const _words = radix2(5);\n const fromWords = _words.decode;\n const toWords = _words.encode;\n const fromWordsUnsafe = unsafeWrapper(fromWords);\n function encode(prefix, words, limit = 90) {\n if (typeof prefix !== 'string')\n throw new Error(`bech32.encode prefix should be string, not ${typeof prefix}`);\n if (!Array.isArray(words) || (words.length && typeof words[0] !== 'number'))\n throw new Error(`bech32.encode words should be array of numbers, not ${typeof words}`);\n const actualLength = prefix.length + 7 + words.length;\n if (limit !== false && actualLength > limit)\n throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`);\n prefix = prefix.toLowerCase();\n return `${prefix}1${BECH_ALPHABET.encode(words)}${bechChecksum(prefix, words, ENCODING_CONST)}`;\n }\n function decode(str, limit = 90) {\n if (typeof str !== 'string')\n throw new Error(`bech32.decode input should be string, not ${typeof str}`);\n if (str.length < 8 || (limit !== false && str.length > limit))\n throw new TypeError(`Wrong string length: ${str.length} (${str}). Expected (8..${limit})`);\n const lowered = str.toLowerCase();\n if (str !== lowered && str !== str.toUpperCase())\n throw new Error(`String must be lowercase or uppercase`);\n str = lowered;\n const sepIndex = str.lastIndexOf('1');\n if (sepIndex === 0 || sepIndex === -1)\n throw new Error(`Letter \"1\" must be present between prefix and data only`);\n const prefix = str.slice(0, sepIndex);\n const _words = str.slice(sepIndex + 1);\n if (_words.length < 6)\n throw new Error('Data must be at least 6 characters long');\n const words = BECH_ALPHABET.decode(_words).slice(0, -6);\n const sum = bechChecksum(prefix, words, ENCODING_CONST);\n if (!_words.endsWith(sum))\n throw new Error(`Invalid checksum in ${str}: expected \"${sum}\"`);\n return { prefix, words };\n }\n const decodeUnsafe = unsafeWrapper(decode);\n function decodeToBytes(str) {\n const { prefix, words } = decode(str, false);\n return { prefix, words, bytes: fromWords(words) };\n }\n return { encode, decode, decodeToBytes, decodeUnsafe, fromWords, fromWordsUnsafe, toWords };\n}\nexports.bech32 = genBech32('bech32');\nexports.bech32m = genBech32('bech32m');\nexports.utf8 = {\n encode: (data) => new TextDecoder().decode(data),\n decode: (str) => new TextEncoder().encode(str),\n};\nexports.hex = chain(radix2(4), alphabet('0123456789abcdef'), join(''), normalize((s) => {\n if (typeof s !== 'string' || s.length % 2)\n throw new TypeError(`hex.decode: expected string, got ${typeof s} with length ${s.length}`);\n return s.toLowerCase();\n}));\nconst CODERS = {\n utf8: exports.utf8, hex: exports.hex, base16: exports.base16, base32: exports.base32, base64: exports.base64, base64url: exports.base64url, base58: exports.base58, base58xmr: exports.base58xmr\n};\nconst coderTypeError = `Invalid encoding type. Available types: ${Object.keys(CODERS).join(', ')}`;\nconst bytesToString = (type, bytes) => {\n if (typeof type !== 'string' || !CODERS.hasOwnProperty(type))\n throw new TypeError(coderTypeError);\n if (!(bytes instanceof Uint8Array))\n throw new TypeError('bytesToString() expects Uint8Array');\n return CODERS[type].encode(bytes);\n};\nexports.bytesToString = bytesToString;\nexports.str = exports.bytesToString;\nconst stringToBytes = (type, str) => {\n if (!CODERS.hasOwnProperty(type))\n throw new TypeError(coderTypeError);\n if (typeof str !== 'string')\n throw new TypeError('stringToBytes() expects string');\n return CODERS[type].decode(str);\n};\nexports.stringToBytes = stringToBytes;\nexports.bytes = exports.stringToBytes;\n","const {bech32, hex, utf8} = require('@scure/base')\n\n// defaults for encode; default timestamp is current time at call\nconst DEFAULTNETWORK = {\n // default network is bitcoin\n bech32: 'bc',\n pubKeyHash: 0x00,\n scriptHash: 0x05,\n validWitnessVersions: [0]\n}\nconst TESTNETWORK = {\n bech32: 'tb',\n pubKeyHash: 0x6f,\n scriptHash: 0xc4,\n validWitnessVersions: [0]\n}\nconst SIGNETNETWORK = {\n bech32: 'tbs',\n pubKeyHash: 0x6f,\n scriptHash: 0xc4,\n validWitnessVersions: [0]\n}\nconst REGTESTNETWORK = {\n bech32: 'bcrt',\n pubKeyHash: 0x6f,\n scriptHash: 0xc4,\n validWitnessVersions: [0]\n}\nconst SIMNETWORK = {\n bech32: 'sb',\n pubKeyHash: 0x3f,\n scriptHash: 0x7b,\n validWitnessVersions: [0]\n}\n\nconst FEATUREBIT_ORDER = [\n 'option_data_loss_protect',\n 'initial_routing_sync',\n 'option_upfront_shutdown_script',\n 'gossip_queries',\n 'var_onion_optin',\n 'gossip_queries_ex',\n 'option_static_remotekey',\n 'payment_secret',\n 'basic_mpp',\n 'option_support_large_channel'\n]\n\nconst DIVISORS = {\n m: BigInt(1e3),\n u: BigInt(1e6),\n n: BigInt(1e9),\n p: BigInt(1e12)\n}\n\nconst MAX_MILLISATS = BigInt('2100000000000000000')\n\nconst MILLISATS_PER_BTC = BigInt(1e11)\n\nconst TAGCODES = {\n payment_hash: 1,\n payment_secret: 16,\n description: 13,\n payee: 19,\n description_hash: 23, // commit to longer descriptions (used by lnurl-pay)\n expiry: 6, // default: 3600 (1 hour)\n min_final_cltv_expiry: 24, // default: 9\n fallback_address: 9,\n route_hint: 3, // for extra routing info (private etc.)\n feature_bits: 5,\n metadata: 27\n}\n\n// reverse the keys and values of TAGCODES and insert into TAGNAMES\nconst TAGNAMES = {}\nfor (let i = 0, keys = Object.keys(TAGCODES); i < keys.length; i++) {\n const currentName = keys[i]\n const currentCode = TAGCODES[keys[i]].toString()\n TAGNAMES[currentCode] = currentName\n}\n\nconst TAGPARSERS = {\n 1: words => hex.encode(bech32.fromWordsUnsafe(words)), // 256 bits\n 16: words => hex.encode(bech32.fromWordsUnsafe(words)), // 256 bits\n 13: words => utf8.encode(bech32.fromWordsUnsafe(words)), // string variable length\n 19: words => hex.encode(bech32.fromWordsUnsafe(words)), // 264 bits\n 23: words => hex.encode(bech32.fromWordsUnsafe(words)), // 256 bits\n 27: words => hex.encode(bech32.fromWordsUnsafe(words)), // variable\n 6: wordsToIntBE, // default: 3600 (1 hour)\n 24: wordsToIntBE, // default: 9\n 3: routingInfoParser, // for extra routing info (private etc.)\n 5: featureBitsParser // keep feature bits as array of 5 bit words\n}\n\nfunction getUnknownParser(tagCode) {\n return words => ({\n tagCode: parseInt(tagCode),\n words: bech32.encode('unknown', words, Number.MAX_SAFE_INTEGER)\n })\n}\n\nfunction wordsToIntBE(words) {\n return words.reverse().reduce((total, item, index) => {\n return total + item * Math.pow(32, index)\n }, 0)\n}\n\n// first convert from words to buffer, trimming padding where necessary\n// parse in 51 byte chunks. See encoder for details.\nfunction routingInfoParser(words) {\n const routes = []\n let pubkey,\n shortChannelId,\n feeBaseMSats,\n feeProportionalMillionths,\n cltvExpiryDelta\n let routesBuffer = bech32.fromWordsUnsafe(words)\n while (routesBuffer.length > 0) {\n pubkey = hex.encode(routesBuffer.slice(0, 33)) // 33 bytes\n shortChannelId = hex.encode(routesBuffer.slice(33, 41)) // 8 bytes\n feeBaseMSats = parseInt(hex.encode(routesBuffer.slice(41, 45)), 16) // 4 bytes\n feeProportionalMillionths = parseInt(\n hex.encode(routesBuffer.slice(45, 49)),\n 16\n ) // 4 bytes\n cltvExpiryDelta = parseInt(hex.encode(routesBuffer.slice(49, 51)), 16) // 2 bytes\n\n routesBuffer = routesBuffer.slice(51)\n\n routes.push({\n pubkey,\n short_channel_id: shortChannelId,\n fee_base_msat: feeBaseMSats,\n fee_proportional_millionths: feeProportionalMillionths,\n cltv_expiry_delta: cltvExpiryDelta\n })\n }\n return routes\n}\n\nfunction featureBitsParser(words) {\n const bools = words\n .slice()\n .reverse()\n .map(word => [\n !!(word & 0b1),\n !!(word & 0b10),\n !!(word & 0b100),\n !!(word & 0b1000),\n !!(word & 0b10000)\n ])\n .reduce((finalArr, itemArr) => finalArr.concat(itemArr), [])\n while (bools.length < FEATUREBIT_ORDER.length * 2) {\n bools.push(false)\n }\n\n const featureBits = {}\n\n FEATUREBIT_ORDER.forEach((featureName, index) => {\n let status\n if (bools[index * 2]) {\n status = 'required'\n } else if (bools[index * 2 + 1]) {\n status = 'supported'\n } else {\n status = 'unsupported'\n }\n featureBits[featureName] = status\n })\n\n const extraBits = bools.slice(FEATUREBIT_ORDER.length * 2)\n featureBits.extra_bits = {\n start_bit: FEATUREBIT_ORDER.length * 2,\n bits: extraBits,\n has_required: extraBits.reduce(\n (result, bit, index) =>\n index % 2 !== 0 ? result || false : result || bit,\n false\n )\n }\n\n return featureBits\n}\n\nfunction hrpToMillisat(hrpString, outputString) {\n let divisor, value\n if (hrpString.slice(-1).match(/^[munp]$/)) {\n divisor = hrpString.slice(-1)\n value = hrpString.slice(0, -1)\n } else if (hrpString.slice(-1).match(/^[^munp0-9]$/)) {\n throw new Error('Not a valid multiplier for the amount')\n } else {\n value = hrpString\n }\n\n if (!value.match(/^\\d+$/))\n throw new Error('Not a valid human readable amount')\n\n const valueBN = BigInt(value)\n\n const millisatoshisBN = divisor\n ? (valueBN * MILLISATS_PER_BTC) / DIVISORS[divisor]\n : valueBN * MILLISATS_PER_BTC\n\n if (\n (divisor === 'p' && !(valueBN % BigInt(10) === BigInt(0))) ||\n millisatoshisBN > MAX_MILLISATS\n ) {\n throw new Error('Amount is outside of valid range')\n }\n\n return outputString ? millisatoshisBN.toString() : millisatoshisBN\n}\n\n// decode will only have extra comments that aren't covered in encode comments.\n// also if anything is hard to read I'll comment.\nfunction decode(paymentRequest, network) {\n if (typeof paymentRequest !== 'string')\n throw new Error('Lightning Payment Request must be string')\n if (paymentRequest.slice(0, 2).toLowerCase() !== 'ln')\n throw new Error('Not a proper lightning payment request')\n\n const sections = []\n const decoded = bech32.decode(paymentRequest, Number.MAX_SAFE_INTEGER)\n paymentRequest = paymentRequest.toLowerCase()\n const prefix = decoded.prefix\n let words = decoded.words\n let letters = paymentRequest.slice(prefix.length + 1)\n let sigWords = words.slice(-104)\n words = words.slice(0, -104)\n\n // Without reverse lookups, can't say that the multipier at the end must\n // have a number before it, so instead we parse, and if the second group\n // doesn't have anything, there's a good chance the last letter of the\n // coin type got captured by the third group, so just re-regex without\n // the number.\n let prefixMatches = prefix.match(/^ln(\\S+?)(\\d*)([a-zA-Z]?)$/)\n if (prefixMatches && !prefixMatches[2])\n prefixMatches = prefix.match(/^ln(\\S+)$/)\n if (!prefixMatches) {\n throw new Error('Not a proper lightning payment request')\n }\n\n // \"ln\" section\n sections.push({\n name: 'lightning_network',\n letters: 'ln'\n })\n\n // \"bc\" section\n const bech32Prefix = prefixMatches[1]\n let coinNetwork\n if (!network) {\n switch (bech32Prefix) {\n case DEFAULTNETWORK.bech32:\n coinNetwork = DEFAULTNETWORK\n break\n case TESTNETWORK.bech32:\n coinNetwork = TESTNETWORK\n break\n case SIGNETNETWORK.bech32:\n coinNetwork = SIGNETNETWORK\n break\n case REGTESTNETWORK.bech32:\n coinNetwork = REGTESTNETWORK\n break\n case SIMNETWORK.bech32:\n coinNetwork = SIMNETWORK\n break\n }\n } else {\n if (\n network.bech32 === undefined ||\n network.pubKeyHash === undefined ||\n network.scriptHash === undefined ||\n !Array.isArray(network.validWitnessVersions)\n )\n throw new Error('Invalid network')\n coinNetwork = network\n }\n if (!coinNetwork || coinNetwork.bech32 !== bech32Prefix) {\n throw new Error('Unknown coin bech32 prefix')\n }\n sections.push({\n name: 'coin_network',\n letters: bech32Prefix,\n value: coinNetwork\n })\n\n // amount section\n const value = prefixMatches[2]\n let millisatoshis\n if (value) {\n const divisor = prefixMatches[3]\n millisatoshis = hrpToMillisat(value + divisor, true)\n sections.push({\n name: 'amount',\n letters: prefixMatches[2] + prefixMatches[3],\n value: millisatoshis\n })\n } else {\n millisatoshis = null\n }\n\n // \"1\" separator\n sections.push({\n name: 'separator',\n letters: '1'\n })\n\n // timestamp\n const timestamp = wordsToIntBE(words.slice(0, 7))\n words = words.slice(7) // trim off the left 7 words\n sections.push({\n name: 'timestamp',\n letters: letters.slice(0, 7),\n value: timestamp\n })\n letters = letters.slice(7)\n\n let tagName, parser, tagLength, tagWords\n // we have no tag count to go on, so just keep hacking off words\n // until we have none.\n while (words.length > 0) {\n const tagCode = words[0].toString()\n tagName = TAGNAMES[tagCode] || 'unknown_tag'\n parser = TAGPARSERS[tagCode] || getUnknownParser(tagCode)\n words = words.slice(1)\n\n tagLength = wordsToIntBE(words.slice(0, 2))\n words = words.slice(2)\n\n tagWords = words.slice(0, tagLength)\n words = words.slice(tagLength)\n\n sections.push({\n name: tagName,\n tag: letters[0],\n letters: letters.slice(0, 1 + 2 + tagLength),\n value: parser(tagWords) // see: parsers for more comments\n })\n letters = letters.slice(1 + 2 + tagLength)\n }\n\n // signature\n sections.push({\n name: 'signature',\n letters: letters.slice(0, 104),\n value: hex.encode(bech32.fromWordsUnsafe(sigWords))\n })\n letters = letters.slice(104)\n\n // checksum\n sections.push({\n name: 'checksum',\n letters: letters\n })\n\n let result = {\n paymentRequest,\n sections,\n\n get expiry() {\n let exp = sections.find(s => s.name === 'expiry')\n if (exp) return getValue('timestamp') + exp.value\n },\n\n get route_hints() {\n return sections.filter(s => s.name === 'route_hint').map(s => s.value)\n }\n }\n\n for (let name in TAGCODES) {\n if (name === 'route_hint') {\n // route hints can be multiple, so this won't work for them\n continue\n }\n\n Object.defineProperty(result, name, {\n get() {\n return getValue(name)\n }\n })\n }\n\n return result\n\n function getValue(name) {\n let section = sections.find(s => s.name === name)\n return section ? section.value : undefined\n }\n}\n\nmodule.exports = {\n decode,\n hrpToMillisat\n}\n","import { getExternalPointerFromTag } from \"./external-id.js\";\nimport { getOrComputeCachedValue } from \"./cache.js\";\nimport { getAddressPointerFromATag } from \"./pointers.js\";\nimport { isSafeRelayURL } from \"./relays.js\";\nexport const COMMENT_KIND = 1111;\nexport const CommentRootPointerSymbol = Symbol.for(\"comment-root-pointer\");\nexport const CommentReplyPointerSymbol = Symbol.for(\"comment-reply-pointer\");\n/** Gets the EventPointer from an array of tags */\nexport function getCommentEventPointer(tags, root = false) {\n const eTag = tags.find((t) => t[0] === (root ? \"E\" : \"e\"));\n const kind = tags.find((t) => t[0] === (root ? \"K\" : \"k\"))?.[1];\n if (eTag) {\n // Missing kind tag, return null\n if (!kind)\n return null;\n // only the root pubkey can be gotten from the tags, since due to quotes and mentions there will be many \"p\" tags for replies\n const rootPubkey = root ? tags.find((t) => t[0] === \"P\")?.[1] : undefined;\n const pointer = {\n type: \"event\",\n id: eTag[1],\n kind: parseInt(kind),\n pubkey: eTag[3] || rootPubkey || undefined,\n relay: eTag[2] && isSafeRelayURL(eTag[2]) ? eTag[2] : undefined,\n };\n return pointer;\n }\n return null;\n}\n/** Gets the AddressPointer from an array of tags */\nexport function getCommentAddressPointer(tags, root = false) {\n const aTag = tags.find((t) => t[0] === (root ? \"A\" : \"a\"));\n const eTag = tags.find((t) => t[0] === (root ? \"E\" : \"e\"));\n const kind = tags.find((t) => t[0] === (root ? \"K\" : \"k\"))?.[1];\n if (aTag) {\n // Missing kind tag, return null\n if (!kind)\n return null;\n const addressPointer = getAddressPointerFromATag(aTag);\n const pointer = {\n type: \"address\",\n id: eTag?.[1],\n pubkey: addressPointer.pubkey,\n identifier: addressPointer.identifier,\n kind: addressPointer.kind || parseInt(kind),\n relay: addressPointer.relays?.[0] || eTag?.[2],\n };\n return pointer;\n }\n return null;\n}\n/** Gets the ExternalPointer from an array of tags */\nexport function getCommentExternalPointer(tags, root = false) {\n const iTag = tags.find((t) => t[0] === (root ? \"I\" : \"i\"));\n if (iTag) {\n return {\n type: \"external\",\n ...getExternalPointerFromTag(iTag),\n };\n }\n return null;\n}\nexport function getCommentRootPointer(comment) {\n if (comment.kind !== COMMENT_KIND)\n return null;\n return getOrComputeCachedValue(comment, CommentRootPointerSymbol, () => {\n // check for address pointer first since it can also have E tags\n const A = getCommentAddressPointer(comment.tags, true);\n if (A)\n return A;\n const E = getCommentEventPointer(comment.tags, true);\n if (E)\n return E;\n const I = getCommentExternalPointer(comment.tags, true);\n if (I)\n return I;\n return null;\n });\n}\n/** Returns the reply pointer for a comment */\nexport function getCommentReplyPointer(comment) {\n if (comment.kind !== COMMENT_KIND)\n return null;\n return getOrComputeCachedValue(comment, CommentReplyPointerSymbol, () => {\n // check for address pointer first since it can also have E tags\n const A = getCommentAddressPointer(comment.tags, false);\n if (A)\n return A;\n const E = getCommentEventPointer(comment.tags, false);\n if (E)\n return E;\n const I = getCommentExternalPointer(comment.tags, false);\n if (I)\n return I;\n return null;\n });\n}\n/** Checks if a pointer is a {@link CommentEventPointer} */\nexport function isCommentEventPointer(pointer) {\n return (Reflect.has(pointer, \"id\") &&\n Reflect.has(pointer, \"kind\") &&\n !Reflect.has(pointer, \"identifier\") &&\n typeof pointer.kind === \"number\");\n}\n/** Checks if a pointer is a {@link CommentAddressPointer} */\nexport function isCommentAddressPointer(pointer) {\n return (Reflect.has(pointer, \"identifier\") &&\n Reflect.has(pointer, \"pubkey\") &&\n Reflect.has(pointer, \"kind\") &&\n typeof pointer.kind === \"number\");\n}\n/** Checks if a comment event is valid */\nexport function isValidComment(comment) {\n return (comment.kind === COMMENT_KIND && getCommentRootPointer(comment) !== null && getCommentReplyPointer(comment) !== null);\n}\n","import { getOrComputeCachedValue } from \"./cache.js\";\nimport { isSafeRelayURL } from \"./relays.js\";\nimport { isPTag, processTags } from \"./tags.js\";\nimport { getProfilePointerFromPTag } from \"./pointers.js\";\nimport { getHiddenTags, isHiddenTagsUnlocked, unlockHiddenTags } from \"./hidden-tags.js\";\nimport { notifyEventUpdate } from \"./index.js\";\nexport const ContactsRelaysSymbol = Symbol.for(\"contacts-relays\");\nexport const PublicContactsSymbol = Symbol.for(\"public-contacts\");\nexport const HiddenContactsSymbol = Symbol.for(\"hidden-contacts\");\nexport function getRelaysFromContactsEvent(event) {\n return getOrComputeCachedValue(event, ContactsRelaysSymbol, () => {\n try {\n const relayJson = JSON.parse(event.content);\n const relays = new Map();\n for (const [url, opts] of Object.entries(relayJson)) {\n if (!isSafeRelayURL(url))\n continue;\n if (opts.write && opts.read)\n relays.set(url, \"all\");\n else if (opts.read)\n relays.set(url, \"inbox\");\n else if (opts.write)\n relays.set(url, \"outbox\");\n }\n return relays;\n }\n catch (error) {\n return null;\n }\n });\n}\n/** Merges any number of contact lists into a single list */\nexport function mergeContacts(...pointers) {\n const merged = new Map();\n for (const arr of pointers) {\n if (Array.isArray(arr)) {\n for (const pointer of arr)\n if (pointer)\n merged.set(pointer.pubkey, pointer);\n }\n else if (arr) {\n merged.set(arr.pubkey, arr);\n }\n }\n return Array.from(merged.values());\n}\n/** Returns all public and hidden contacts from a contacts list event */\nexport function getContacts(event) {\n return mergeContacts(getPublicContacts(event), getHiddenContacts(event));\n}\n/** Returns only the public contacts from a contacts list event */\nexport function getPublicContacts(event) {\n return getOrComputeCachedValue(event, PublicContactsSymbol, () => processTags(event.tags, (t) => (isPTag(t) ? t : undefined), getProfilePointerFromPTag));\n}\n/** Checks if the hidden contacts are unlocked */\nexport function isHiddenContactsUnlocked(event) {\n return isHiddenTagsUnlocked(event) && Reflect.has(event, HiddenContactsSymbol);\n}\n/** Returns only the hidden contacts from a contacts list event */\nexport function getHiddenContacts(event) {\n if (isHiddenContactsUnlocked(event))\n return event[HiddenContactsSymbol];\n // Get hidden tags\n const tags = getHiddenTags(event);\n if (!tags)\n return undefined;\n // Parse tags\n const contacts = processTags(tags, (t) => (isPTag(t) ? t : undefined), getProfilePointerFromPTag);\n // Set cache and notify event store\n Reflect.set(event, HiddenContactsSymbol, contacts);\n return contacts;\n}\n/** Unlocks the hidden contacts */\nexport async function unlockHiddenContacts(event, signer) {\n if (isHiddenContactsUnlocked(event))\n return event[HiddenContactsSymbol];\n // Unlock hidden tags\n await unlockHiddenTags(event, signer);\n // Get hidden contacts\n const contacts = getHiddenContacts(event);\n if (!contacts)\n throw new Error(\"Failed to unlock hidden contacts\");\n // Set cache and notify event store\n notifyEventUpdate(event);\n return contacts;\n}\n","/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nfunction isBytes(a) {\n return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');\n}\n/** Asserts something is Uint8Array. */\nfunction abytes(b, ...lengths) {\n if (!isBytes(b))\n throw new Error('Uint8Array expected');\n if (lengths.length > 0 && !lengths.includes(b.length))\n throw new Error('Uint8Array expected of length ' + lengths + ', got length=' + b.length);\n}\nfunction isArrayOf(isString, arr) {\n if (!Array.isArray(arr))\n return false;\n if (arr.length === 0)\n return true;\n if (isString) {\n return arr.every((item) => typeof item === 'string');\n }\n else {\n return arr.every((item) => Number.isSafeInteger(item));\n }\n}\n// no abytes: seems to have 10% slowdown. Why?!\nfunction afn(input) {\n if (typeof input !== 'function')\n throw new Error('function expected');\n return true;\n}\nfunction astr(label, input) {\n if (typeof input !== 'string')\n throw new Error(`${label}: string expected`);\n return true;\n}\nfunction anumber(n) {\n if (!Number.isSafeInteger(n))\n throw new Error(`invalid integer: ${n}`);\n}\nfunction aArr(input) {\n if (!Array.isArray(input))\n throw new Error('array expected');\n}\nfunction astrArr(label, input) {\n if (!isArrayOf(true, input))\n throw new Error(`${label}: array of strings expected`);\n}\nfunction anumArr(label, input) {\n if (!isArrayOf(false, input))\n throw new Error(`${label}: array of numbers expected`);\n}\n/**\n * @__NO_SIDE_EFFECTS__\n */\nfunction chain(...args) {\n const id = (a) => a;\n // Wrap call in closure so JIT can inline calls\n const wrap = (a, b) => (c) => a(b(c));\n // Construct chain of args[-1].encode(args[-2].encode([...]))\n const encode = args.map((x) => x.encode).reduceRight(wrap, id);\n // Construct chain of args[0].decode(args[1].decode(...))\n const decode = args.map((x) => x.decode).reduce(wrap, id);\n return { encode, decode };\n}\n/**\n * Encodes integer radix representation to array of strings using alphabet and back.\n * Could also be array of strings.\n * @__NO_SIDE_EFFECTS__\n */\nfunction alphabet(letters) {\n // mapping 1 to \"b\"\n const lettersA = typeof letters === 'string' ? letters.split('') : letters;\n const len = lettersA.length;\n astrArr('alphabet', lettersA);\n // mapping \"b\" to 1\n const indexes = new Map(lettersA.map((l, i) => [l, i]));\n return {\n encode: (digits) => {\n aArr(digits);\n return digits.map((i) => {\n if (!Number.isSafeInteger(i) || i < 0 || i >= len)\n throw new Error(`alphabet.encode: digit index outside alphabet \"${i}\". Allowed: ${letters}`);\n return lettersA[i];\n });\n },\n decode: (input) => {\n aArr(input);\n return input.map((letter) => {\n astr('alphabet.decode', letter);\n const i = indexes.get(letter);\n if (i === undefined)\n throw new Error(`Unknown letter: \"${letter}\". Allowed: ${letters}`);\n return i;\n });\n },\n };\n}\n/**\n * @__NO_SIDE_EFFECTS__\n */\nfunction join(separator = '') {\n astr('join', separator);\n return {\n encode: (from) => {\n astrArr('join.decode', from);\n return from.join(separator);\n },\n decode: (to) => {\n astr('join.decode', to);\n return to.split(separator);\n },\n };\n}\n/**\n * Pad strings array so it has integer number of bits\n * @__NO_SIDE_EFFECTS__\n */\nfunction padding(bits, chr = '=') {\n anumber(bits);\n astr('padding', chr);\n return {\n encode(data) {\n astrArr('padding.encode', data);\n while ((data.length * bits) % 8)\n data.push(chr);\n return data;\n },\n decode(input) {\n astrArr('padding.decode', input);\n let end = input.length;\n if ((end * bits) % 8)\n throw new Error('padding: invalid, string should have whole number of bytes');\n for (; end > 0 && input[end - 1] === chr; end--) {\n const last = end - 1;\n const byte = last * bits;\n if (byte % 8 === 0)\n throw new Error('padding: invalid, string has too much padding');\n }\n return input.slice(0, end);\n },\n };\n}\n/**\n * @__NO_SIDE_EFFECTS__\n */\nfunction normalize(fn) {\n afn(fn);\n return { encode: (from) => from, decode: (to) => fn(to) };\n}\n/**\n * Slow: O(n^2) time complexity\n */\nfunction convertRadix(data, from, to) {\n // base 1 is impossible\n if (from < 2)\n throw new Error(`convertRadix: invalid from=${from}, base cannot be less than 2`);\n if (to < 2)\n throw new Error(`convertRadix: invalid to=${to}, base cannot be less than 2`);\n aArr(data);\n if (!data.length)\n return [];\n let pos = 0;\n const res = [];\n const digits = Array.from(data, (d) => {\n anumber(d);\n if (d < 0 || d >= from)\n throw new Error(`invalid integer: ${d}`);\n return d;\n });\n const dlen = digits.length;\n while (true) {\n let carry = 0;\n let done = true;\n for (let i = pos; i < dlen; i++) {\n const digit = digits[i];\n const fromCarry = from * carry;\n const digitBase = fromCarry + digit;\n if (!Number.isSafeInteger(digitBase) ||\n fromCarry / from !== carry ||\n digitBase - digit !== fromCarry) {\n throw new Error('convertRadix: carry overflow');\n }\n const div = digitBase / to;\n carry = digitBase % to;\n const rounded = Math.floor(div);\n digits[i] = rounded;\n if (!Number.isSafeInteger(rounded) || rounded * to + carry !== digitBase)\n throw new Error('convertRadix: carry overflow');\n if (!done)\n continue;\n else if (!rounded)\n pos = i;\n else\n done = false;\n }\n res.push(carry);\n if (done)\n break;\n }\n for (let i = 0; i < data.length - 1 && data[i] === 0; i++)\n res.push(0);\n return res.reverse();\n}\nconst gcd = (a, b) => (b === 0 ? a : gcd(b, a % b));\nconst radix2carry = /* @__NO_SIDE_EFFECTS__ */ (from, to) => from + (to - gcd(from, to));\nconst powers = /* @__PURE__ */ (() => {\n let res = [];\n for (let i = 0; i < 40; i++)\n res.push(2 ** i);\n return res;\n})();\n/**\n * Implemented with numbers, because BigInt is 5x slower\n */\nfunction convertRadix2(data, from, to, padding) {\n aArr(data);\n if (from <= 0 || from > 32)\n throw new Error(`convertRadix2: wrong from=${from}`);\n if (to <= 0 || to > 32)\n throw new Error(`convertRadix2: wrong to=${to}`);\n if (radix2carry(from, to) > 32) {\n throw new Error(`convertRadix2: carry overflow from=${from} to=${to} carryBits=${radix2carry(from, to)}`);\n }\n let carry = 0;\n let pos = 0; // bitwise position in current element\n const max = powers[from];\n const mask = powers[to] - 1;\n const res = [];\n for (const n of data) {\n anumber(n);\n if (n >= max)\n throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);\n carry = (carry << from) | n;\n if (pos + from > 32)\n throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from}`);\n pos += from;\n for (; pos >= to; pos -= to)\n res.push(((carry >> (pos - to)) & mask) >>> 0);\n const pow = powers[pos];\n if (pow === undefined)\n throw new Error('invalid carry');\n carry &= pow - 1; // clean carry, otherwise it will cause overflow\n }\n carry = (carry << (to - pos)) & mask;\n if (!padding && pos >= from)\n throw new Error('Excess padding');\n if (!padding && carry > 0)\n throw new Error(`Non-zero padding: ${carry}`);\n if (padding && pos > 0)\n res.push(carry >>> 0);\n return res;\n}\n/**\n * @__NO_SIDE_EFFECTS__\n */\nfunction radix(num) {\n anumber(num);\n const _256 = 2 ** 8;\n return {\n encode: (bytes) => {\n if (!isBytes(bytes))\n throw new Error('radix.encode input should be Uint8Array');\n return convertRadix(Array.from(bytes), _256, num);\n },\n decode: (digits) => {\n anumArr('radix.decode', digits);\n return Uint8Array.from(convertRadix(digits, num, _256));\n },\n };\n}\n/**\n * If both bases are power of same number (like `2**8 <-> 2**64`),\n * there is a linear algorithm. For now we have implementation for power-of-two bases only.\n * @__NO_SIDE_EFFECTS__\n */\nfunction radix2(bits, revPadding = false) {\n anumber(bits);\n if (bits <= 0 || bits > 32)\n throw new Error('radix2: bits should be in (0..32]');\n if (radix2carry(8, bits) > 32 || radix2carry(bits, 8) > 32)\n throw new Error('radix2: carry overflow');\n return {\n encode: (bytes) => {\n if (!isBytes(bytes))\n throw new Error('radix2.encode input should be Uint8Array');\n return convertRadix2(Array.from(bytes), 8, bits, !revPadding);\n },\n decode: (digits) => {\n anumArr('radix2.decode', digits);\n return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding));\n },\n };\n}\nfunction unsafeWrapper(fn) {\n afn(fn);\n return function (...args) {\n try {\n return fn.apply(null, args);\n }\n catch (e) { }\n };\n}\nfunction checksum(len, fn) {\n anumber(len);\n afn(fn);\n return {\n encode(data) {\n if (!isBytes(data))\n throw new Error('checksum.encode: input should be Uint8Array');\n const sum = fn(data).slice(0, len);\n const res = new Uint8Array(data.length + len);\n res.set(data);\n res.set(sum, data.length);\n return res;\n },\n decode(data) {\n if (!isBytes(data))\n throw new Error('checksum.decode: input should be Uint8Array');\n const payload = data.slice(0, -len);\n const oldChecksum = data.slice(-len);\n const newChecksum = fn(payload).slice(0, len);\n for (let i = 0; i < len; i++)\n if (newChecksum[i] !== oldChecksum[i])\n throw new Error('Invalid checksum');\n return payload;\n },\n };\n}\n// prettier-ignore\nexport const utils = {\n alphabet, chain, checksum, convertRadix, convertRadix2, radix, radix2, join, padding,\n};\n// RFC 4648 aka RFC 3548\n// ---------------------\n/**\n * base16 encoding from RFC 4648.\n * @example\n * ```js\n * base16.encode(Uint8Array.from([0x12, 0xab]));\n * // => '12AB'\n * ```\n */\nexport const base16 = chain(radix2(4), alphabet('0123456789ABCDEF'), join(''));\n/**\n * base32 encoding from RFC 4648. Has padding.\n * Use `base32nopad` for unpadded version.\n * Also check out `base32hex`, `base32hexnopad`, `base32crockford`.\n * @example\n * ```js\n * base32.encode(Uint8Array.from([0x12, 0xab]));\n * // => 'CKVQ===='\n * base32.decode('CKVQ====');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base32 = chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), padding(5), join(''));\n/**\n * base32 encoding from RFC 4648. No padding.\n * Use `base32` for padded version.\n * Also check out `base32hex`, `base32hexnopad`, `base32crockford`.\n * @example\n * ```js\n * base32nopad.encode(Uint8Array.from([0x12, 0xab]));\n * // => 'CKVQ'\n * base32nopad.decode('CKVQ');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base32nopad = chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), join(''));\n/**\n * base32 encoding from RFC 4648. Padded. Compared to ordinary `base32`, slightly different alphabet.\n * Use `base32hexnopad` for unpadded version.\n * @example\n * ```js\n * base32hex.encode(Uint8Array.from([0x12, 0xab]));\n * // => '2ALG===='\n * base32hex.decode('2ALG====');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base32hex = chain(radix2(5), alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'), padding(5), join(''));\n/**\n * base32 encoding from RFC 4648. No padding. Compared to ordinary `base32`, slightly different alphabet.\n * Use `base32hex` for padded version.\n * @example\n * ```js\n * base32hexnopad.encode(Uint8Array.from([0x12, 0xab]));\n * // => '2ALG'\n * base32hexnopad.decode('2ALG');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base32hexnopad = chain(radix2(5), alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'), join(''));\n/**\n * base32 encoding from RFC 4648. Doug Crockford's version.\n * https://www.crockford.com/base32.html\n * @example\n * ```js\n * base32crockford.encode(Uint8Array.from([0x12, 0xab]));\n * // => '2ANG'\n * base32crockford.decode('2ANG');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base32crockford = chain(radix2(5), alphabet('0123456789ABCDEFGHJKMNPQRSTVWXYZ'), join(''), normalize((s) => s.toUpperCase().replace(/O/g, '0').replace(/[IL]/g, '1')));\n// Built-in base64 conversion https://caniuse.com/mdn-javascript_builtins_uint8array_frombase64\n// prettier-ignore\nconst hasBase64Builtin = /* @__PURE__ */ (() => typeof Uint8Array.from([]).toBase64 === 'function' &&\n typeof Uint8Array.fromBase64 === 'function')();\nconst decodeBase64Builtin = (s, isUrl) => {\n astr('base64', s);\n const re = isUrl ? /^[A-Za-z0-9=_-]+$/ : /^[A-Za-z0-9=+/]+$/;\n const alphabet = isUrl ? 'base64url' : 'base64';\n if (s.length > 0 && !re.test(s))\n throw new Error('invalid base64');\n return Uint8Array.fromBase64(s, { alphabet, lastChunkHandling: 'strict' });\n};\n/**\n * base64 from RFC 4648. Padded.\n * Use `base64nopad` for unpadded version.\n * Also check out `base64url`, `base64urlnopad`.\n * Falls back to built-in function, when available.\n * @example\n * ```js\n * base64.encode(Uint8Array.from([0x12, 0xab]));\n * // => 'Eqs='\n * base64.decode('Eqs=');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\n// prettier-ignore\nexport const base64 = hasBase64Builtin ? {\n encode(b) { abytes(b); return b.toBase64(); },\n decode(s) { return decodeBase64Builtin(s, false); },\n} : chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), padding(6), join(''));\n/**\n * base64 from RFC 4648. No padding.\n * Use `base64` for padded version.\n * @example\n * ```js\n * base64nopad.encode(Uint8Array.from([0x12, 0xab]));\n * // => 'Eqs'\n * base64nopad.decode('Eqs');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base64nopad = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), join(''));\n/**\n * base64 from RFC 4648, using URL-safe alphabet. Padded.\n * Use `base64urlnopad` for unpadded version.\n * Falls back to built-in function, when available.\n * @example\n * ```js\n * base64url.encode(Uint8Array.from([0x12, 0xab]));\n * // => 'Eqs='\n * base64url.decode('Eqs=');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\n// prettier-ignore\nexport const base64url = hasBase64Builtin ? {\n encode(b) { abytes(b); return b.toBase64({ alphabet: 'base64url' }); },\n decode(s) { return decodeBase64Builtin(s, true); },\n} : chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), padding(6), join(''));\n/**\n * base64 from RFC 4648, using URL-safe alphabet. No padding.\n * Use `base64url` for padded version.\n * @example\n * ```js\n * base64urlnopad.encode(Uint8Array.from([0x12, 0xab]));\n * // => 'Eqs'\n * base64urlnopad.decode('Eqs');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base64urlnopad = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), join(''));\n// base58 code\n// -----------\nconst genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => chain(radix(58), alphabet(abc), join(''));\n/**\n * base58: base64 without ambigous characters +, /, 0, O, I, l.\n * Quadratic (O(n^2)) - so, can't be used on large inputs.\n * @example\n * ```js\n * base58.decode('01abcdef');\n * // => '3UhJW'\n * ```\n */\nexport const base58 = genBase58('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');\n/**\n * base58: flickr version. Check out `base58`.\n */\nexport const base58flickr = genBase58('123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ');\n/**\n * base58: XRP version. Check out `base58`.\n */\nexport const base58xrp = genBase58('rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz');\n// Data len (index) -> encoded block len\nconst XMR_BLOCK_LEN = [0, 2, 3, 5, 6, 7, 9, 10, 11];\n/**\n * base58: XMR version. Check out `base58`.\n * Done in 8-byte blocks (which equals 11 chars in decoding). Last (non-full) block padded with '1' to size in XMR_BLOCK_LEN.\n * Block encoding significantly reduces quadratic complexity of base58.\n */\nexport const base58xmr = {\n encode(data) {\n let res = '';\n for (let i = 0; i < data.length; i += 8) {\n const block = data.subarray(i, i + 8);\n res += base58.encode(block).padStart(XMR_BLOCK_LEN[block.length], '1');\n }\n return res;\n },\n decode(str) {\n let res = [];\n for (let i = 0; i < str.length; i += 11) {\n const slice = str.slice(i, i + 11);\n const blockLen = XMR_BLOCK_LEN.indexOf(slice.length);\n const block = base58.decode(slice);\n for (let j = 0; j < block.length - blockLen; j++) {\n if (block[j] !== 0)\n throw new Error('base58xmr: wrong padding');\n }\n res = res.concat(Array.from(block.slice(block.length - blockLen)));\n }\n return Uint8Array.from(res);\n },\n};\n/**\n * Method, which creates base58check encoder.\n * Requires function, calculating sha256.\n */\nexport const createBase58check = (sha256) => chain(checksum(4, (data) => sha256(sha256(data))), base58);\n/**\n * Use `createBase58check` instead.\n * @deprecated\n */\nexport const base58check = createBase58check;\nconst BECH_ALPHABET = chain(alphabet('qpzry9x8gf2tvdw0s3jn54khce6mua7l'), join(''));\nconst POLYMOD_GENERATORS = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];\nfunction bech32Polymod(pre) {\n const b = pre >> 25;\n let chk = (pre & 0x1ffffff) << 5;\n for (let i = 0; i < POLYMOD_GENERATORS.length; i++) {\n if (((b >> i) & 1) === 1)\n chk ^= POLYMOD_GENERATORS[i];\n }\n return chk;\n}\nfunction bechChecksum(prefix, words, encodingConst = 1) {\n const len = prefix.length;\n let chk = 1;\n for (let i = 0; i < len; i++) {\n const c = prefix.charCodeAt(i);\n if (c < 33 || c > 126)\n throw new Error(`Invalid prefix (${prefix})`);\n chk = bech32Polymod(chk) ^ (c >> 5);\n }\n chk = bech32Polymod(chk);\n for (let i = 0; i < len; i++)\n chk = bech32Polymod(chk) ^ (prefix.charCodeAt(i) & 0x1f);\n for (let v of words)\n chk = bech32Polymod(chk) ^ v;\n for (let i = 0; i < 6; i++)\n chk = bech32Polymod(chk);\n chk ^= encodingConst;\n return BECH_ALPHABET.encode(convertRadix2([chk % powers[30]], 30, 5, false));\n}\n/**\n * @__NO_SIDE_EFFECTS__\n */\nfunction genBech32(encoding) {\n const ENCODING_CONST = encoding === 'bech32' ? 1 : 0x2bc830a3;\n const _words = radix2(5);\n const fromWords = _words.decode;\n const toWords = _words.encode;\n const fromWordsUnsafe = unsafeWrapper(fromWords);\n function encode(prefix, words, limit = 90) {\n astr('bech32.encode prefix', prefix);\n if (isBytes(words))\n words = Array.from(words);\n anumArr('bech32.encode', words);\n const plen = prefix.length;\n if (plen === 0)\n throw new TypeError(`Invalid prefix length ${plen}`);\n const actualLength = plen + 7 + words.length;\n if (limit !== false && actualLength > limit)\n throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`);\n const lowered = prefix.toLowerCase();\n const sum = bechChecksum(lowered, words, ENCODING_CONST);\n return `${lowered}1${BECH_ALPHABET.encode(words)}${sum}`;\n }\n function decode(str, limit = 90) {\n astr('bech32.decode input', str);\n const slen = str.length;\n if (slen < 8 || (limit !== false && slen > limit))\n throw new TypeError(`invalid string length: ${slen} (${str}). Expected (8..${limit})`);\n // don't allow mixed case\n const lowered = str.toLowerCase();\n if (str !== lowered && str !== str.toUpperCase())\n throw new Error(`String must be lowercase or uppercase`);\n const sepIndex = lowered.lastIndexOf('1');\n if (sepIndex === 0 || sepIndex === -1)\n throw new Error(`Letter \"1\" must be present between prefix and data only`);\n const prefix = lowered.slice(0, sepIndex);\n const data = lowered.slice(sepIndex + 1);\n if (data.length < 6)\n throw new Error('Data must be at least 6 characters long');\n const words = BECH_ALPHABET.decode(data).slice(0, -6);\n const sum = bechChecksum(prefix, words, ENCODING_CONST);\n if (!data.endsWith(sum))\n throw new Error(`Invalid checksum in ${str}: expected \"${sum}\"`);\n return { prefix, words };\n }\n const decodeUnsafe = unsafeWrapper(decode);\n function decodeToBytes(str) {\n const { prefix, words } = decode(str, false);\n return { prefix, words, bytes: fromWords(words) };\n }\n function encodeFromBytes(prefix, bytes) {\n return encode(prefix, toWords(bytes));\n }\n return {\n encode,\n decode,\n encodeFromBytes,\n decodeToBytes,\n decodeUnsafe,\n fromWords,\n fromWordsUnsafe,\n toWords,\n };\n}\n/**\n * bech32 from BIP 173. Operates on words.\n * For high-level, check out scure-btc-signer:\n * https://github.com/paulmillr/scure-btc-signer.\n */\nexport const bech32 = genBech32('bech32');\n/**\n * bech32m from BIP 350. Operates on words.\n * It was to mitigate `bech32` weaknesses.\n * For high-level, check out scure-btc-signer:\n * https://github.com/paulmillr/scure-btc-signer.\n */\nexport const bech32m = genBech32('bech32m');\n/**\n * UTF-8-to-byte decoder. Uses built-in TextDecoder / TextEncoder.\n * @example\n * ```js\n * const b = utf8.decode(\"hey\"); // => new Uint8Array([ 104, 101, 121 ])\n * const str = utf8.encode(b); // \"hey\"\n * ```\n */\nexport const utf8 = {\n encode: (data) => new TextDecoder().decode(data),\n decode: (str) => new TextEncoder().encode(str),\n};\n// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex\n// prettier-ignore\nconst hasHexBuiltin = /* @__PURE__ */ (() => typeof Uint8Array.from([]).toHex === 'function' &&\n typeof Uint8Array.fromHex === 'function')();\n// prettier-ignore\nconst hexBuiltin = {\n encode(data) { abytes(data); return data.toHex(); },\n decode(s) { astr('hex', s); return Uint8Array.fromHex(s); },\n};\n/**\n * hex string decoder. Uses built-in function, when available.\n * @example\n * ```js\n * const b = hex.decode(\"0102ff\"); // => new Uint8Array([ 1, 2, 255 ])\n * const str = hex.encode(b); // \"0102ff\"\n * ```\n */\nexport const hex = hasHexBuiltin\n ? hexBuiltin\n : chain(radix2(4), alphabet('0123456789abcdef'), join(''), normalize((s) => {\n if (typeof s !== 'string' || s.length % 2 !== 0)\n throw new TypeError(`hex.decode: expected string, got ${typeof s} with length ${s.length}`);\n return s.toLowerCase();\n }));\n// prettier-ignore\nconst CODERS = {\n utf8, hex, base16, base32, base64, base64url, base58, base58xmr\n};\nconst coderTypeError = 'Invalid encoding type. Available types: utf8, hex, base16, base32, base64, base64url, base58, base58xmr';\n/** @deprecated */\nexport const bytesToString = (type, bytes) => {\n if (typeof type !== 'string' || !CODERS.hasOwnProperty(type))\n throw new TypeError(coderTypeError);\n if (!isBytes(bytes))\n throw new TypeError('bytesToString() expects Uint8Array');\n return CODERS[type].encode(bytes);\n};\n/** @deprecated */\nexport const str = bytesToString; // as in python, but for bytes only\n/** @deprecated */\nexport const stringToBytes = (type, str) => {\n if (!CODERS.hasOwnProperty(type))\n throw new TypeError(coderTypeError);\n if (typeof str !== 'string')\n throw new TypeError('stringToBytes() expects string');\n return CODERS[type].decode(str);\n};\n/** @deprecated */\nexport const bytes = stringToBytes;\n//# sourceMappingURL=index.js.map","import { kinds } from \"nostr-tools\";\nimport { catchError, combineLatest, distinct, EMPTY, filter, isObservable, map, merge, mergeMap, of, switchMap, } from \"rxjs\";\nimport { logger } from \"../logger.js\";\nimport { canHaveEncryptedContent, getEncryptedContent, isEncryptedContentUnlocked, setEncryptedContentCache, } from \"./encrypted-content.js\";\nimport { notifyEventUpdate } from \"./event.js\";\nimport { getGiftWrapSeal, getSealGiftWrap, getSealRumor } from \"./gift-wraps.js\";\n/** A symbol that is used to mark encrypted content as being from a cache */\nexport const EncryptedContentFromCacheSymbol = Symbol.for(\"encrypted-content-from-cache\");\n/** Marks the encrypted content as being from a cache */\nexport function markEncryptedContentFromCache(event) {\n Reflect.set(event, EncryptedContentFromCacheSymbol, true);\n}\n/** Checks if the encrypted content is from a cache */\nexport function isEncryptedContentFromCache(event) {\n return Reflect.has(event, EncryptedContentFromCacheSymbol);\n}\nconst log = logger.extend(\"EncryptedContentCache\");\n/**\n * Starts a process that persists and restores all encrypted content\n * @param eventStore - The event store to listen to\n * @param storage - The storage to use\n * @param fallback - A function that will be called when the encrypted content is not found in storage\n * @returns A function that can be used to stop the process\n */\nexport function persistEncryptedContent(eventStore, storage, fallback) {\n const storage$ = isObservable(storage) ? storage : of(storage);\n // Get the encrypted content from storage or call the fallback\n const getItem = async (storage, event) => {\n return (await storage.getItem(event.id)) || (fallback ? await fallback(event) : null);\n };\n // Restore encrypted content when it is inserted\n const restore = eventStore.insert$\n .pipe(\n // Look for events that support encrypted content and are locked\n filter((e) => canHaveEncryptedContent(e.kind) && isEncryptedContentUnlocked(e) === false), \n // Get the encrypted content from storage\n mergeMap((event) => \n // Wait for storage to be available\n storage$.pipe(switchMap((storage) => combineLatest([of(event), getItem(storage, event)])), catchError((error) => {\n log(`Failed to restore encrypted content for ${event.id}`, error);\n return EMPTY;\n }))))\n .subscribe(async ([event, content]) => {\n if (!content)\n return;\n // Restore the encrypted content and set it as from a cache\n markEncryptedContentFromCache(event);\n setEncryptedContentCache(event, content);\n log(`Restored encrypted content for ${event.id}`);\n });\n // Restore seals when they are unlocked\n const restoreSeals = eventStore.update$\n .pipe(\n // Look for gift wraps that are unlocked\n filter((e) => e.kind === kinds.GiftWrap && isEncryptedContentUnlocked(e)), \n // Get the seal event\n map((gift) => getGiftWrapSeal(gift)), \n // Look for gift wraps with locked seals\n filter((seal) => seal !== undefined && isEncryptedContentUnlocked(seal) === false), \n // Only attempt to unlock seals once\n distinct((seal) => seal.id), \n // Get encrypted content from storage\n mergeMap((seal) => \n // Wait for storage to be available\n storage$.pipe(switchMap((storage) => combineLatest([of(seal), getItem(storage, seal)])), catchError((error) => {\n log(`Failed to restore encrypted content for ${seal.id}`, error);\n return EMPTY;\n }))))\n .subscribe(async ([seal, content]) => {\n if (!seal || !content)\n return;\n markEncryptedContentFromCache(seal);\n setEncryptedContentCache(seal, content);\n // Parse the rumor event\n getSealRumor(seal);\n // Trigger an update to the gift wrap event\n const gift = getSealGiftWrap(seal);\n if (gift)\n notifyEventUpdate(gift);\n log(`Restored encrypted content for ${seal.id}`);\n });\n // Persist encrypted content when it is updated or inserted\n const persist = combineLatest([merge(eventStore.update$, eventStore.insert$), storage$])\n .pipe(\n // Look for events that support encrypted content and are unlocked and not from the cache\n filter(([event]) => canHaveEncryptedContent(event.kind) &&\n isEncryptedContentUnlocked(event) &&\n !isEncryptedContentFromCache(event)), \n // Only persist the encrypted content once\n distinct(([event]) => event.id))\n .subscribe(async ([event, storage]) => {\n try {\n const content = getEncryptedContent(event);\n if (content) {\n await storage.setItem(event.id, content);\n log(`Persisted encrypted content for ${event.id}`);\n }\n }\n catch (error) {\n // Ignore errors when saving encrypted content\n log(`Failed to persist encrypted content for ${event.id}`, error);\n }\n });\n // Persist seals when the gift warp is unlocked or inserted unlocked\n // This relies on the gift wrap event being updated when a seal is unlocked\n const persistSeals = combineLatest([merge(eventStore.update$, eventStore.insert$), storage$])\n .pipe(\n // Look for gift wraps that are unlocked\n filter(([event]) => event.kind === kinds.GiftWrap && isEncryptedContentUnlocked(event)), \n // Get the seal event\n map(([gift, storage]) => [getGiftWrapSeal(gift), storage]), \n // Make sure the seal is defined\n filter(([seal]) => seal !== undefined), \n // Make sure seal is unlocked and not from cache\n filter(([seal]) => isEncryptedContentUnlocked(seal) && !isEncryptedContentFromCache(seal)), \n // Only persist the seal once\n distinct(([seal]) => seal.id))\n .subscribe(async ([seal, storage]) => {\n if (!seal)\n return;\n try {\n const content = getEncryptedContent(seal);\n if (content) {\n await storage.setItem(seal.id, content);\n log(`Persisted encrypted content for ${seal.id}`);\n }\n }\n catch (error) {\n // Ignore errors when saving encrypted content\n log(`Failed to persist encrypted content for ${seal.id}`, error);\n }\n });\n return () => {\n restore.unsubscribe();\n persist.unsubscribe();\n restoreSeals.unsubscribe();\n persistSeals.unsubscribe();\n };\n}\n","import { bufferTime, filter } from \"rxjs\";\nimport { logger } from \"../logger.js\";\nimport { isFromCache } from \"./index.js\";\nconst log = logger.extend(\"event-cache\");\n/**\n * Setups a process to write batches of new events from an event store to a cache\n * @param eventStore - The event store to read from\n * @param write - The function to write the events to the cache\n * @param opts - The options for the process\n * @param opts.batchTime - The time to wait before writing a batch (default: 5 seconds)\n * @param opts.maxBatchSize - The maximum number of events to write in a batch\n * @returns A function to stop the process\n */\nexport function persistEventsToCache(eventStore, write, opts) {\n const time = opts?.batchTime ?? 5_000;\n // Save all new events to the cache\n const sub = eventStore.insert$\n .pipe(\n // Only select events that are not from the cache\n filter((e) => !isFromCache(e)), \n // Buffer events for 5 seconds\n opts?.maxBatchSize ? bufferTime(time, undefined, opts?.maxBatchSize ?? 100) : bufferTime(time), \n // Only select buffers with events\n filter((b) => b.length > 0))\n .subscribe((events) => {\n // Save all new events to the cache\n write(events)\n .then(() => log(`Saved ${events.length} events to cache`))\n .catch((e) => log(`Failed to save ${events.length} events to cache`, e));\n });\n return () => sub.unsubscribe();\n}\n/** @deprecated Use persistEventsToCache instead */\nexport const presistEventsToCache = persistEventsToCache;\n","import { bech32 } from \"@scure/base\";\nimport { parseBolt11 } from \"./bolt11.js\";\nconst decoder = new TextDecoder();\n/** Parses a lightning address (lud16) into a LNURLp */\nexport function parseLightningAddress(address) {\n let [name, domain] = address.split(\"@\");\n if (!name || !domain)\n return;\n return new URL(`https://${domain}/.well-known/lnurlp/${name}`);\n}\n/** Parses a LNURLp into a URL */\nexport function decodeLNURL(lnurl) {\n try {\n const { words, prefix } = bech32.decode(lnurl);\n if (prefix !== \"lnurl\")\n return;\n const str = decoder.decode(bech32.fromWords(words));\n return new URL(str);\n }\n catch (error) { }\n return undefined;\n}\n/** Parses a lightning address or LNURLp into a URL */\nexport function parseLNURLOrAddress(addressOrLNURL) {\n if (addressOrLNURL.includes(\"@\"))\n return parseLightningAddress(addressOrLNURL);\n else\n return decodeLNURL(addressOrLNURL);\n}\n/** Requests a bolt11 invoice from a LNURLp callback URL */\nexport async function getInvoice(callback) {\n const { pr: payRequest } = await fetch(callback).then((res) => res.json());\n const amount = callback.searchParams.get(\"amount\");\n if (!amount)\n throw new Error(\"Missing amount\");\n if (payRequest) {\n const parsed = parseBolt11(payRequest);\n if (parsed.amount !== parseInt(amount))\n throw new Error(\"Incorrect amount\");\n return payRequest;\n }\n else\n throw new Error(\"Failed to get invoice\");\n}\n","import { getOrComputeCachedValue } from \"./cache.js\";\nimport { isSafeRelayURL } from \"./relays.js\";\nimport { isRTag } from \"./tags.js\";\nimport { normalizeURL } from \"./url.js\";\nexport const MailboxesInboxesSymbol = Symbol.for(\"mailboxes-inboxes\");\nexport const MailboxesOutboxesSymbol = Symbol.for(\"mailboxes-outboxes\");\n/** Parses a 10002 event and stores the inboxes in the event using the {@link MailboxesInboxesSymbol} symbol */\nexport function getInboxes(event) {\n return getOrComputeCachedValue(event, MailboxesInboxesSymbol, () => {\n const inboxes = [];\n for (const tag of event.tags) {\n if (!isRTag(tag))\n continue;\n try {\n const [, url, mode] = tag;\n if (url && isSafeRelayURL(url) && !inboxes.includes(url) && (mode === \"read\" || mode === undefined)) {\n inboxes.push(normalizeURL(url));\n }\n }\n catch {\n // Ignore invalid url tags\n }\n }\n return inboxes;\n });\n}\n/** Parses a 10002 event and stores the outboxes in the event using the {@link MailboxesOutboxesSymbol} symbol */\nexport function getOutboxes(event) {\n return getOrComputeCachedValue(event, MailboxesOutboxesSymbol, () => {\n const outboxes = [];\n for (const tag of event.tags) {\n if (!isRTag(tag))\n continue;\n try {\n const [name, url, mode] = tag;\n if (name === \"r\" &&\n isSafeRelayURL(url) &&\n !outboxes.includes(url) &&\n (mode === \"write\" || mode === undefined)) {\n outboxes.push(normalizeURL(url));\n }\n }\n catch {\n // Ignore invalid url tags\n }\n }\n return outboxes;\n });\n}\n","import { kinds } from \"nostr-tools\";\nimport { getOrComputeCachedValue } from \"./cache.js\";\nimport { getHiddenTags, isHiddenTagsUnlocked, unlockHiddenTags } from \"./hidden-tags.js\";\nimport { getIndexableTags, getNip10References, notifyEventUpdate } from \"./index.js\";\nimport { isETag, isPTag, isTTag } from \"./tags.js\";\nexport const MutePublicSymbol = Symbol.for(\"mute-public\");\nexport const MuteHiddenSymbol = Symbol.for(\"mute-hidden\");\n/** Merges any number of mute sets */\nexport function mergeMutes(...mutes) {\n const mute = { pubkeys: new Set(), threads: new Set(), hashtags: new Set(), words: new Set() };\n for (const m of mutes) {\n for (const pubkey of m.pubkeys)\n mute.pubkeys.add(pubkey);\n for (const thread of m.threads)\n mute.threads.add(thread);\n for (const hashtag of m.hashtags)\n mute.hashtags.add(hashtag);\n for (const word of m.words)\n mute.words.add(word);\n }\n return mute;\n}\n/** Parses mute tags */\nexport function parseMutedTags(tags) {\n const pubkeys = new Set(tags.filter(isPTag).map((t) => t[1]));\n const threads = new Set(tags.filter(isETag).map((t) => t[1]));\n const hashtags = new Set(tags.filter(isTTag).map((t) => t[1].toLocaleLowerCase()));\n const words = new Set(tags.filter((t) => t[0] === \"word\" && t[1]).map((t) => t[1].toLocaleLowerCase()));\n return { pubkeys, threads, hashtags, words };\n}\n/** Returns muted things */\nexport function getMutedThings(mute) {\n const hidden = getHiddenMutedThings(mute);\n const mutes = getPublicMutedThings(mute);\n if (hidden)\n return mergeMutes(hidden, mutes);\n return mutes;\n}\n/** Returns only the public muted things from a mute event */\nexport function getPublicMutedThings(mute) {\n return getOrComputeCachedValue(mute, MutePublicSymbol, () => parseMutedTags(mute.tags));\n}\n/** Checks if the hidden mutes are unlocked */\nexport function isHiddenMutesUnlocked(mute) {\n return isHiddenTagsUnlocked(mute) && Reflect.has(mute, MuteHiddenSymbol);\n}\nexport function getHiddenMutedThings(mute) {\n if (isHiddenMutesUnlocked(mute))\n return mute[MuteHiddenSymbol];\n // get hidden tags\n const tags = getHiddenTags(mute);\n if (!tags)\n return undefined;\n // parse muted tags\n const mutes = parseMutedTags(tags);\n // set cached value\n Reflect.set(mute, MuteHiddenSymbol, mutes);\n return mutes;\n}\n/** Unlocks the hidden mutes */\nexport async function unlockHiddenMutes(mute, signer) {\n if (isHiddenMutesUnlocked(mute))\n return mute[MuteHiddenSymbol];\n // Unlock hidden tags\n await unlockHiddenTags(mute, signer);\n // get hidden mutes\n const mutes = getHiddenMutedThings(mute);\n if (!mutes)\n throw new Error(\"Failed to unlock hidden mutes\");\n // Notify event store\n notifyEventUpdate(mute);\n return mutes;\n}\n/** Creates a RegExp for matching muted words */\nexport function createMutedWordsRegExp(mutedWords) {\n // Escape special characters and join with |\n const escapedWords = mutedWords.map((word) => word.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"));\n // Create the RegExp with word boundaries and case insensitive flag\n return new RegExp(`\\\\b(${escapedWords.join(\"|\")})\\\\b`, \"gi\");\n}\n/** Returns true if the event matches the mutes */\nexport function matchMutes(mutes, event) {\n // Filter on muted pubkeys\n if (mutes.pubkeys.size > 0) {\n if (mutes.pubkeys.has(event.pubkey))\n return true;\n }\n // Filter on muted hashtags`\n if (mutes.hashtags.size > 0) {\n const tags = getIndexableTags(event);\n for (let tag of mutes.hashtags) {\n if (tags.has(\"t:\" + tag))\n return true;\n }\n }\n // Filter on muted threads\n if (mutes.threads.size > 0 && event.kind === kinds.ShortTextNote) {\n const refs = getNip10References(event);\n if (refs.root?.e && mutes.threads.has(refs.root.e.id))\n return true;\n }\n // Filter on muted words\n if (mutes.words.size > 0) {\n const regExp = createMutedWordsRegExp(Array.from(mutes.words));\n if (regExp.test(event.content))\n return true;\n }\n // Event does not match any mutes\n return false;\n}\n","import { isETag, isPTag } from \"./tags.js\";\nimport { getOrComputeCachedValue } from \"./cache.js\";\nexport const ParsedReportSymbol = Symbol(\"parsed-report\");\nexport var ReportReason;\n(function (ReportReason) {\n ReportReason[\"nudity\"] = \"nudity\";\n ReportReason[\"malware\"] = \"malware\";\n ReportReason[\"profanity\"] = \"profanity\";\n ReportReason[\"illegal\"] = \"illegal\";\n ReportReason[\"spam\"] = \"spam\";\n ReportReason[\"impersonation\"] = \"impersonation\";\n ReportReason[\"other\"] = \"other\";\n})(ReportReason || (ReportReason = {}));\n/** Reads a report event as either a user or event report */\nexport function getReported(report) {\n return getOrComputeCachedValue(report, ParsedReportSymbol, () => {\n const p = report.tags.find(isPTag);\n if (!p)\n throw new Error(\"Report missing p tag\");\n const comment = report.content ? report.content.trim() : undefined;\n const e = report.tags.find(isETag);\n // Event report\n if (e) {\n const blobs = report.tags.filter((t) => t[0] === \"x\" && t[1]).map((t) => t[1]);\n return {\n type: \"event\",\n event: report,\n comment,\n id: e[1],\n pubkey: p[1],\n reason: e[2],\n blobs,\n };\n }\n // User report\n return { type: \"user\", event: report, comment, pubkey: p[1], reason: p[2] };\n });\n}\n","import { getAddressPointerFromATag } from \"./pointers.js\";\nimport { getOrComputeCachedValue } from \"./cache.js\";\nimport { isSafeRelayURL } from \"./relays.js\";\nexport const Nip10ThreadRefsSymbol = Symbol.for(\"nip10-thread-refs\");\n/**\n * Gets an EventPointer form a NIP-10 threading \"e\" tag\n * @throws\n */\nexport function getEventPointerFromThreadTag(tag) {\n if (!tag[1])\n throw new Error(\"Missing event id in tag\");\n let pointer = { id: tag[1] };\n if (tag[2] && isSafeRelayURL(tag[2]))\n pointer.relays = [tag[2]];\n // get author from NIP-18 quote tags, nip-22 comments tags, or nip-10 thread tags\n if (tag[0] === \"e\" &&\n (tag[3] === \"root\" || tag[3] === \"reply\" || tag[3] === \"mention\") &&\n tag[4] &&\n tag[4].length === 64) {\n // NIP-10 \"e\" tag\n pointer.author = tag[4];\n }\n return pointer;\n}\n/** Parses NIP-10 tags and handles legacy behavior */\nexport function interpretThreadTags(tags) {\n const eTags = tags.filter((t) => t[0] === \"e\" && t[1]);\n const aTags = tags.filter((t) => t[0] === \"a\" && t[1]);\n // find the root and reply tags.\n let rootETag = eTags.find((t) => t[3] === \"root\");\n let replyETag = eTags.find((t) => t[3] === \"reply\");\n let rootATag = aTags.find((t) => t[3] === \"root\");\n let replyATag = aTags.find((t) => t[3] === \"reply\");\n if (!rootETag || !replyETag) {\n // a direct reply does not need a \"reply\" reference\n // https://github.com/nostr-protocol/nips/blob/master/10.md\n // this is not necessarily to spec. but if there is only one id (root or reply) then assign it to both\n // this handles the cases where a client only set a \"reply\" tag and no root\n rootETag = replyETag = rootETag || replyETag;\n }\n if (!rootATag || !replyATag) {\n rootATag = replyATag = rootATag || replyATag;\n }\n if (!rootETag && !replyETag) {\n // legacy behavior\n // https://github.com/nostr-protocol/nips/blob/master/10.md#positional-e-tags-deprecated\n const legacyETags = eTags.filter((t) => {\n // ignore it if there is a marker\n if (t[3])\n return false;\n return true;\n });\n if (legacyETags.length >= 1) {\n // first tag is the root\n rootETag = legacyETags[0];\n // last tag is reply\n replyETag = legacyETags[legacyETags.length - 1] ?? rootETag;\n }\n }\n return {\n root: rootETag || rootATag ? { e: rootETag, a: rootATag } : undefined,\n reply: replyETag || replyATag ? { e: replyETag, a: replyATag } : undefined,\n };\n}\n/** Returns the parsed NIP-10 tags for an event */\nexport function getNip10References(event) {\n return getOrComputeCachedValue(event, Nip10ThreadRefsSymbol, () => {\n const tags = interpretThreadTags(event.tags);\n let root;\n if (tags.root) {\n try {\n root = {\n e: tags.root.e && getEventPointerFromThreadTag(tags.root.e),\n a: tags.root.a && getAddressPointerFromATag(tags.root.a),\n };\n }\n catch (error) { }\n }\n let reply;\n if (tags.reply) {\n try {\n reply = {\n e: tags.reply.e && getEventPointerFromThreadTag(tags.reply.e),\n a: tags.reply.a && getAddressPointerFromATag(tags.reply.a),\n };\n }\n catch (error) { }\n }\n return {\n root,\n reply,\n };\n });\n}\n","import { finalize, tap } from \"rxjs\";\n/** keep a claim on any event that goes through this observable, claims are removed when the observable is unsubscribed or completes */\nexport function claimEvents(claims) {\n return (source) => {\n const seen = new Set();\n return source.pipe(\n // claim all events\n tap((message) => {\n if (message === undefined)\n return;\n if (Array.isArray(message)) {\n for (const event of message) {\n if (seen.has(event))\n continue;\n seen.add(event);\n claims.claim(event);\n }\n }\n else if (!seen.has(message)) {\n seen.add(message);\n claims.claim(message);\n }\n }), \n // remove claims on cleanup\n finalize(() => {\n for (const e of seen)\n claims.removeClaim(e);\n }));\n };\n}\n","import { finalize, tap } from \"rxjs\";\n/** An operator that claims the latest event with the database */\nexport function claimLatest(claims) {\n return (source) => {\n let latest = undefined;\n return source.pipe(tap((event) => {\n // only update if the event changed\n if (latest !== event) {\n // remove old claim\n if (latest)\n claims.removeClaim(latest);\n // claim new event\n if (event)\n claims.claim(event);\n // update state\n latest = event;\n }\n }), finalize(() => {\n // remove latest claim\n if (latest)\n claims.removeClaim(latest);\n }));\n };\n}\n","import { filter } from \"rxjs\";\n/** Filters out undefined and null values */\nexport function defined() {\n return (source) => source.pipe(filter((v) => v !== undefined && v !== null));\n}\n","import { Observable } from \"rxjs\";\n/** if a synchronous value is not emitted, default is emitted */\nexport function withImmediateValueOrDefault(defaultValue) {\n return (source) => new Observable((observer) => {\n let seen = false;\n const sub = source.subscribe({\n next: (v) => {\n seen = true;\n observer.next(v);\n },\n error: (err) => observer.error(err),\n complete: () => observer.complete(),\n });\n // if a value is not emitted sync, emit default\n if (!seen)\n observer.next(defaultValue);\n return sub;\n });\n}\n","import { combineLatest, defer, distinctUntilChanged, EMPTY, endWith, filter, finalize, from, ignoreElements, map, merge, mergeWith, of, repeat, scan, switchMap, take, takeUntil, tap, } from \"rxjs\";\nimport { insertEventIntoDescendingList } from \"nostr-tools/utils\";\nimport { createReplaceableAddress, getEventUID, getReplaceableIdentifier, isReplaceable, matchFilters, } from \"../helpers/index.js\";\nimport { claimEvents } from \"../observable/claim-events.js\";\nimport { claimLatest } from \"../observable/claim-latest.js\";\nimport { defined } from \"../observable/defined.js\";\nimport { withImmediateValueOrDefault } from \"../observable/with-immediate-value.js\";\n/** Gets a single event from both types of event stores and returns an observable that completes */\nfunction getEventFromStores(store, pointer) {\n const r = store.getEvent(pointer.id);\n if (r instanceof Promise)\n return from(r);\n else\n return of(r);\n}\n/** Gets a single replaceable event from both types of event stores and returns an observable that completes */\nfunction getReplaceableFromStores(store, pointer) {\n const r = store.getReplaceable(pointer.kind, pointer.pubkey, pointer.identifier);\n if (r instanceof Promise)\n return from(r);\n else\n return of(r);\n}\n/** If event is undefined, attempt to load using the fallback loader */\nfunction loadEventUsingFallback(store, pointer) {\n return switchMap((event) => {\n if (event)\n return of(event);\n // If event was not found, attempt to load\n if (!store.eventLoader)\n return EMPTY;\n return from(store.eventLoader(pointer));\n });\n}\n/** If replaceable event is undefined, attempt to load using the fallback loader */\nfunction loadReplaceableUsingFallback(store, pointer) {\n return switchMap((event) => {\n if (event)\n return of(event);\n else if (pointer.identifier !== undefined) {\n if (!store.addressableLoader)\n return EMPTY;\n return from(store.addressableLoader(pointer)).pipe(filter((e) => !!e));\n }\n else {\n if (!store.replaceableLoader)\n return EMPTY;\n return from(store.replaceableLoader(pointer)).pipe(filter((e) => !!e));\n }\n });\n}\n/** A model that returns a single event or undefined when its removed */\nexport function EventModel(pointer) {\n if (typeof pointer === \"string\")\n pointer = { id: pointer };\n return (store) => merge(\n // get current event and ignore if there is none\n defer(() => getEventFromStores(store, pointer)).pipe(\n // If the event isn't found, attempt to load using the fallback loader\n loadEventUsingFallback(store, pointer), \n // Only emit found events\n defined()), \n // Listen for new events\n store.insert$.pipe(filter((e) => e.id === pointer.id)), \n // emit undefined when deleted\n store.remove$.pipe(filter((e) => e.id === pointer.id), take(1), ignoreElements(), \n // Emit undefined when deleted\n endWith(undefined))).pipe(\n // claim all events\n claimLatest(store), \n // ignore duplicate events\n distinctUntilChanged((a, b) => a?.id === b?.id), \n // always emit undefined so the observable is synchronous\n withImmediateValueOrDefault(undefined));\n}\n/** A model that returns the latest version of a replaceable event or undefined if its removed */\nexport function ReplaceableModel(pointer) {\n return (store) => {\n let current = undefined;\n return merge(\n // lazily get current event\n defer(() => getReplaceableFromStores(store, pointer)).pipe(\n // If the event isn't found, attempt to load using the fallback loader\n loadReplaceableUsingFallback(store, pointer), \n // Only emit found events\n defined()), \n // Subscribe to new events that match the pointer\n store.insert$.pipe(filter((e) => e.pubkey == pointer.pubkey &&\n e.kind === pointer.kind &&\n (pointer.identifier !== undefined ? getReplaceableIdentifier(e) === pointer.identifier : true)))).pipe(\n // only update if event is newer\n distinctUntilChanged((prev, event) => {\n // are the events the same? i.e. is the prev event older\n return prev.created_at >= event.created_at;\n }), \n // Hacky way to extract the current event so takeUntil can access it\n tap((event) => (current = event)), \n // complete when event is removed\n takeUntil(store.remove$.pipe(filter((e) => e.id === current?.id))), \n // emit undefined when removed\n endWith(undefined), \n // keep the observable hot\n repeat(), \n // claim latest event\n claimLatest(store), \n // always emit undefined so the observable is synchronous\n withImmediateValueOrDefault(undefined));\n };\n}\n/** A model that returns an array of sorted events matching the filters */\nexport function TimelineModel(filters, includeOldVersion) {\n filters = Array.isArray(filters) ? filters : [filters];\n return (store) => {\n const seen = new Map();\n // get current events\n return defer(() => {\n const r = store.getTimeline(filters);\n if (r instanceof Promise)\n return from(r);\n else\n return of(r);\n }).pipe(\n // claim existing events\n claimEvents(store), \n // subscribe to newer events\n mergeWith(store.insert$.pipe(filter((e) => matchFilters(filters, e)), \n // claim all new events\n claimEvents(store))), \n // subscribe to delete events\n mergeWith(store.remove$.pipe(filter((e) => matchFilters(filters, e)), map((e) => e.id))), \n // build a timeline\n scan((timeline, event) => {\n // filter out removed events from timeline\n if (typeof event === \"string\")\n return timeline.filter((e) => e.id !== event);\n // initial timeline array\n if (Array.isArray(event)) {\n if (!includeOldVersion) {\n for (const e of event)\n if (isReplaceable(e.kind))\n seen.set(getEventUID(e), e);\n }\n return event;\n }\n // create a new timeline and insert the event into it\n let newTimeline = [...timeline];\n // remove old replaceable events if enabled\n if (!includeOldVersion && isReplaceable(event.kind)) {\n const uid = getEventUID(event);\n const existing = seen.get(uid);\n // if this is an older replaceable event, exit\n if (existing && event.created_at < existing.created_at)\n return timeline;\n // update latest version\n seen.set(uid, event);\n // remove old event from timeline\n if (existing)\n newTimeline.slice(newTimeline.indexOf(existing), 1);\n }\n // add event into timeline\n insertEventIntoDescendingList(newTimeline, event);\n return newTimeline;\n }, []), \n // ignore changes that do not modify the timeline instance\n distinctUntilChanged(), \n // hacky hack to clear seen on unsubscribe\n finalize(() => seen.clear()));\n };\n}\n/**\n * A model that returns a multiple events in a map\n * @deprecated use multiple {@link EventModel} instead\n */\nexport function EventsModel(ids) {\n return (events) => combineLatest(Object.fromEntries(ids.map((id) => [id, events.model(EventModel, { id })])));\n}\n/**\n * A model that returns a directory of events by their UID\n * @deprecated use multiple {@link ReplaceableModel} instead\n */\nexport function ReplaceableSetModel(pointers) {\n return (events) => combineLatest(Object.fromEntries(pointers.map((pointer) => [\n createReplaceableAddress(pointer.kind, pointer.pubkey, pointer.identifier),\n events.model(ReplaceableModel, pointer),\n ])));\n}\n","import { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nimport { noop } from '../util/noop';\nexport function ignoreElements() {\n return operate(function (source, subscriber) {\n source.subscribe(createOperatorSubscriber(subscriber, noop));\n });\n}\n//# sourceMappingURL=ignoreElements.js.map","import { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nimport { innerFrom } from '../observable/innerFrom';\nimport { noop } from '../util/noop';\nexport function takeUntil(notifier) {\n return operate(function (source, subscriber) {\n innerFrom(notifier).subscribe(createOperatorSubscriber(subscriber, function () { return subscriber.complete(); }, noop));\n !subscriber.closed && source.subscribe(subscriber);\n });\n}\n//# sourceMappingURL=takeUntil.js.map","import { EMPTY } from '../observable/empty';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nimport { innerFrom } from '../observable/innerFrom';\nimport { timer } from '../observable/timer';\nexport function repeat(countOrConfig) {\n var _a;\n var count = Infinity;\n var delay;\n if (countOrConfig != null) {\n if (typeof countOrConfig === 'object') {\n (_a = countOrConfig.count, count = _a === void 0 ? Infinity : _a, delay = countOrConfig.delay);\n }\n else {\n count = countOrConfig;\n }\n }\n return count <= 0\n ? function () { return EMPTY; }\n : operate(function (source, subscriber) {\n var soFar = 0;\n var sourceSub;\n var resubscribe = function () {\n sourceSub === null || sourceSub === void 0 ? void 0 : sourceSub.unsubscribe();\n sourceSub = null;\n if (delay != null) {\n var notifier = typeof delay === 'number' ? timer(delay) : innerFrom(delay(soFar));\n var notifierSubscriber_1 = createOperatorSubscriber(subscriber, function () {\n notifierSubscriber_1.unsubscribe();\n subscribeToSource();\n });\n notifier.subscribe(notifierSubscriber_1);\n }\n else {\n subscribeToSource();\n }\n };\n var subscribeToSource = function () {\n var syncUnsub = false;\n sourceSub = source.subscribe(createOperatorSubscriber(subscriber, undefined, function () {\n if (++soFar < count) {\n if (sourceSub) {\n resubscribe();\n }\n else {\n syncUnsub = true;\n }\n }\n else {\n subscriber.complete();\n }\n }));\n if (syncUnsub) {\n resubscribe();\n }\n };\n subscribeToSource();\n });\n}\n//# sourceMappingURL=repeat.js.map","import { filter, map, merge, tap } from \"rxjs\";\n/** Watches for any updates to the latest event and remits the event when updated */\nexport function watchEventUpdates(eventStore) {\n return (source) => {\n let latest;\n return merge(\n // Get the latest event\n source.pipe(tap((value) => (latest = value))), \n // listen for updates\n eventStore.update$.pipe(filter((e) => e.id === latest?.id)));\n };\n}\n/** Watches for any updates to the latest array of events and remits the array of events when updated */\nexport function watchEventsUpdates(eventStore) {\n return (source) => {\n let latest = [];\n return merge(\n // Get the latest event\n source.pipe(tap((value) => (latest = value))), \n // listen for updates\n eventStore.update$.pipe(filter((e) => latest.includes(e)), \n // re-emit the array of events\n map(() => latest)));\n };\n}\n","import { kinds } from \"nostr-tools\";\nimport { map } from \"rxjs/operators\";\nimport { getContacts, getHiddenContacts, getPublicContacts } from \"../helpers/contacts.js\";\nimport { watchEventUpdates } from \"../observable/index.js\";\n/** A model that returns all contacts for a user */\nexport function ContactsModel(user) {\n if (typeof user === \"string\")\n user = { pubkey: user };\n return (events) => events.replaceable({ kind: kinds.Contacts, pubkey: user.pubkey, relays: user.relays }).pipe(\n // listen for event updates (hidden tags unlocked)\n watchEventUpdates(events), \n // Get all contacts\n map((e) => (e ? getContacts(e) : [])));\n}\n/** A model that returns all public contacts for a user */\nexport function PublicContactsModel(pubkey) {\n return (events) => events.replaceable(kinds.Contacts, pubkey).pipe(map((e) => e && getPublicContacts(e)));\n}\n/** A model that returns all hidden contacts for a user */\nexport function HiddenContactsModel(pubkey) {\n return (events) => events.replaceable(kinds.Contacts, pubkey).pipe(\n // listen for event updates (hidden tags unlocked)\n watchEventUpdates(events), \n // Get hidden contacts\n map((e) => e && (getHiddenContacts(e) ?? null)));\n}\n","import { isAddressableKind } from \"nostr-tools/kinds\";\nimport { COMMENT_KIND, getReplaceableAddress } from \"../helpers/index.js\";\n/** A model that returns all NIP-22 comment replies for the event */\nexport function CommentsModel(parent) {\n return (events) => {\n const filters = [{ kinds: [COMMENT_KIND], \"#e\": [parent.id] }];\n if (isAddressableKind(parent.kind))\n filters.push({ kinds: [COMMENT_KIND], \"#a\": [getReplaceableAddress(parent)] });\n return events.timeline(filters);\n };\n}\n","import { kinds } from \"nostr-tools\";\nimport { map } from \"rxjs/operators\";\nimport { getInboxes, getOutboxes } from \"../helpers/mailboxes.js\";\n/** A model that gets and parses the inbox and outbox relays for a pubkey */\nexport function MailboxesModel(user) {\n if (typeof user === \"string\")\n user = { pubkey: user };\n return (events) => events.replaceable({ kind: kinds.RelayList, pubkey: user.pubkey, relays: user.relays }).pipe(map((event) => event && {\n inboxes: getInboxes(event),\n outboxes: getOutboxes(event),\n }));\n}\n","import { kinds } from \"nostr-tools\";\nimport { map } from \"rxjs/operators\";\nimport { getHiddenMutedThings, getMutedThings, getPublicMutedThings } from \"../helpers/mutes.js\";\nimport { watchEventUpdates } from \"../observable/watch-event-updates.js\";\n/** A model that returns all a users muted things */\nexport function MuteModel(user) {\n if (typeof user === \"string\")\n user = { pubkey: user };\n return (events) => events.replaceable({ kind: kinds.Mutelist, pubkey: user.pubkey, relays: user.relays }).pipe(\n // listen for event updates (hidden tags unlocked)\n watchEventUpdates(events), \n // Get all muted things\n map((event) => event && getMutedThings(event)));\n}\n/** A model that returns all a users public muted things */\nexport function PublicMuteModel(pubkey) {\n return (events) => events.replaceable(kinds.Mutelist, pubkey).pipe(map((event) => event && getPublicMutedThings(event)));\n}\n/** A model that returns all a users hidden muted things */\nexport function HiddenMuteModel(pubkey) {\n return (events) => events.replaceable(kinds.Mutelist, pubkey).pipe(\n // listen for event updates (hidden tags unlocked)\n watchEventUpdates(events), \n // Get hidden muted things\n map((event) => event && getHiddenMutedThings(event)));\n}\n","import { kinds } from \"nostr-tools\";\nimport { filter, map } from \"rxjs/operators\";\nimport { getProfileContent, isValidProfile } from \"../helpers/profile.js\";\nimport { withImmediateValueOrDefault } from \"../observable/with-immediate-value.js\";\n/** A model that gets and parses the kind 0 metadata for a pubkey */\nexport function ProfileModel(user) {\n if (typeof user === \"string\")\n user = { pubkey: user };\n return (events) => events.replaceable({ kind: kinds.Metadata, pubkey: user.pubkey, relays: user.relays }).pipe(\n // Filter out invalid profile events\n filter(isValidProfile), \n // Parse the profile event into a ProfileContent\n map((event) => event && getProfileContent(event)), \n // Ensure the model is synchronous\n withImmediateValueOrDefault(undefined));\n}\n","import { kinds } from \"nostr-tools\";\nimport { getEventUID, isReplaceable } from \"../helpers/event.js\";\n/** A model that returns all reactions to an event (supports replaceable events) */\nexport function ReactionsModel(event) {\n return (events) => events.timeline(isReplaceable(event.kind)\n ? [\n { kinds: [kinds.Reaction], \"#e\": [event.id] },\n { kinds: [kinds.Reaction], \"#a\": [getEventUID(event)] },\n ]\n : [\n {\n kinds: [kinds.Reaction],\n \"#e\": [event.id],\n },\n ]);\n}\n","import { kinds } from \"nostr-tools\";\nimport { isAddressableKind } from \"nostr-tools/kinds\";\nimport { map } from \"rxjs/operators\";\nimport { COMMENT_KIND } from \"../helpers/comment.js\";\nimport { getTagValue } from \"../helpers/event-tags.js\";\nimport { createReplaceableAddress, getEventUID, isEvent } from \"../helpers/event.js\";\nimport { getCoordinateFromAddressPointer, isAddressPointer, isEventPointer } from \"../helpers/pointers.js\";\nimport { getNip10References, interpretThreadTags } from \"../helpers/threading.js\";\nconst defaultOptions = {\n kinds: [kinds.ShortTextNote],\n};\n/** A model that returns a NIP-10 thread of events */\nexport function ThreadModel(root, opts) {\n const parentReferences = new Map();\n const items = new Map();\n const { kinds } = { ...defaultOptions, ...opts };\n let rootUID = \"\";\n const rootFilter = {};\n const replyFilter = { kinds };\n if (isAddressPointer(root)) {\n rootUID = getCoordinateFromAddressPointer(root);\n rootFilter.kinds = [root.kind];\n rootFilter.authors = [root.pubkey];\n rootFilter[\"#d\"] = [root.identifier];\n replyFilter[\"#a\"] = [rootUID];\n }\n else if (typeof root === \"string\") {\n rootUID = root;\n rootFilter.ids = [root];\n replyFilter[\"#e\"] = [root];\n }\n else {\n rootUID = root.id;\n rootFilter.ids = [root.id];\n replyFilter[\"#e\"] = [root.id];\n }\n return (events) => events.filters([rootFilter, replyFilter]).pipe(map((event) => {\n if (!items.has(getEventUID(event))) {\n const refs = getNip10References(event);\n const replies = parentReferences.get(getEventUID(event)) || new Set();\n const item = { event, refs, replies };\n for (const child of replies) {\n child.parent = item;\n }\n // add item to parent\n if (refs.reply?.e || refs.reply?.a) {\n let uid = refs.reply.e ? refs.reply.e.id : getCoordinateFromAddressPointer(refs.reply.a);\n item.parent = items.get(uid);\n if (item.parent) {\n item.parent.replies.add(item);\n }\n else {\n // parent isn't created yet, store ref for later\n let set = parentReferences.get(uid);\n if (!set) {\n set = new Set();\n parentReferences.set(uid, set);\n }\n set.add(item);\n }\n }\n // add item to map\n items.set(getEventUID(event), item);\n }\n return { root: items.get(rootUID), all: items };\n }));\n}\n/** A model that gets all legacy and NIP-10, and NIP-22 replies for an event */\nexport function RepliesModel(event, overrideKinds) {\n return (events) => {\n const kinds = overrideKinds || event.kind === 1 ? [1, COMMENT_KIND] : [COMMENT_KIND];\n const filter = { kinds };\n if (isEvent(parent) || isEventPointer(event))\n filter[\"#e\"] = [event.id];\n const address = isAddressableKind(event.kind)\n ? createReplaceableAddress(event.kind, event.pubkey, getTagValue(event, \"d\"))\n : undefined;\n if (address) {\n filter[\"#a\"] = [address];\n }\n return events.timeline(filter).pipe(map((events) => {\n return events.filter((e) => {\n const refs = interpretThreadTags(e.tags);\n return refs.reply?.e?.[1] === event.id || refs.reply?.a?.[1] === address;\n });\n }));\n };\n}\n","import hash_sum from \"hash-sum\";\nimport { EMPTY, ReplaySubject, filter, finalize, from, merge, mergeMap, share, timer } from \"rxjs\";\nimport { matchFilters } from \"../helpers/filter.js\";\n// Model imports\nimport { UserBlossomServersModel } from \"../models/blossom.js\";\nimport { EventModel, EventsModel, ReplaceableModel, ReplaceableSetModel, TimelineModel } from \"../models/common.js\";\nimport { ContactsModel } from \"../models/contacts.js\";\nimport { CommentsModel, ThreadModel } from \"../models/index.js\";\nimport { MailboxesModel } from \"../models/mailboxes.js\";\nimport { MuteModel } from \"../models/mutes.js\";\nimport { ProfileModel } from \"../models/profile.js\";\nimport { ReactionsModel } from \"../models/reactions.js\";\n/** A mixin that provides model functionality for both sync and async event stores */\nexport function EventStoreModelMixin(Base) {\n return class extends Base {\n /** A directory of all active models */\n models = new Map();\n /** How long a model should be kept \"warm\" while nothing is subscribed to it */\n modelKeepWarm = 60_000;\n /** Get or create a model on the event store */\n model(constructor, ...args) {\n let models = this.models.get(constructor);\n if (!models) {\n models = new Map();\n this.models.set(constructor, models);\n }\n const key = constructor.getKey ? constructor.getKey(...args) : hash_sum(args);\n let model = models.get(key);\n // Create the model if it does not exist\n if (!model) {\n const cleanup = () => {\n // Remove the model from the cache if its the same one\n if (models.get(key) === model)\n models.delete(key);\n };\n model = constructor(...args)(this).pipe(\n // remove the model when its unsubscribed\n finalize(cleanup), \n // only subscribe to models once for all subscriptions\n share({\n connector: () => new ReplaySubject(1),\n resetOnComplete: () => timer(this.modelKeepWarm),\n resetOnRefCountZero: () => timer(this.modelKeepWarm),\n }));\n // Add the model to the cache\n models.set(key, model);\n }\n return model;\n }\n /**\n * Creates an observable that streams all events that match the filter\n * @param filters\n * @param [onlyNew=false] Only subscribe to new events\n */\n filters(filters, onlyNew = false) {\n filters = Array.isArray(filters) ? filters : [filters];\n const getByFiltersResult = this.getByFilters(filters);\n // Create the existing events observable\n const existingEvents$ = onlyNew\n ? EMPTY\n : // Check if result is a Promise (async) or direct Set (sync)\n getByFiltersResult && typeof getByFiltersResult.then === \"function\"\n ? from(getByFiltersResult).pipe(mergeMap((events) => from(Array.from(events))))\n : from(Array.from(getByFiltersResult));\n // Create the new events observable\n const newEvents$ = this.insert$.pipe(filter((e) => matchFilters(filters, e)));\n return merge(existingEvents$, newEvents$);\n }\n // Helper methods for creating models\n /** Creates a {@link EventModel} */\n event(pointer) {\n if (typeof pointer === \"string\")\n pointer = { id: pointer };\n return this.model(EventModel, pointer);\n }\n replaceable(...args) {\n let pointer;\n // Parse arguments\n if (args.length === 1) {\n pointer = args[0];\n }\n else if (args.length === 3 || args.length === 2) {\n let [kind, pubkey, identifier] = args;\n pointer = { kind, pubkey, identifier };\n }\n if (!pointer)\n throw new Error(\"Invalid arguments, expected address pointer or kind, pubkey, identifier\");\n return this.model(ReplaceableModel, pointer);\n }\n /** Subscribe to an addressable event by pointer */\n addressable(pointer) {\n return this.model(ReplaceableModel, pointer);\n }\n /** Creates a {@link TimelineModel} */\n timeline(filters, includeOldVersion = false) {\n return this.model(TimelineModel, filters, includeOldVersion);\n }\n /** Subscribe to a users profile */\n profile(user) {\n return this.model(ProfileModel, user);\n }\n /** Subscribe to a users contacts */\n contacts(user) {\n if (typeof user === \"string\")\n user = { pubkey: user };\n return this.model(ContactsModel, user);\n }\n /** Subscribe to a users mutes */\n mutes(user) {\n if (typeof user === \"string\")\n user = { pubkey: user };\n return this.model(MuteModel, user);\n }\n /** Subscribe to a users NIP-65 mailboxes */\n mailboxes(user) {\n if (typeof user === \"string\")\n user = { pubkey: user };\n return this.model(MailboxesModel, user);\n }\n /** Subscribe to a users blossom servers */\n blossomServers(user) {\n if (typeof user === \"string\")\n user = { pubkey: user };\n return this.model(UserBlossomServersModel, user);\n }\n /** Subscribe to an event's reactions */\n reactions(event) {\n return this.model(ReactionsModel, event);\n }\n /** Subscribe to a thread */\n thread(root) {\n return this.model(ThreadModel, root);\n }\n /** Subscribe to a event's comments */\n comments(event) {\n return this.model(CommentsModel, event);\n }\n /** @deprecated use multiple {@link EventModel} instead */\n events(ids) {\n return this.model(EventsModel, ids);\n }\n /** @deprecated use multiple {@link ReplaceableModel} instead */\n replaceableSet(pointers) {\n return this.model(ReplaceableSetModel, pointers);\n }\n };\n}\n","import { kinds } from \"nostr-tools\";\nimport { isAddressableKind } from \"nostr-tools/kinds\";\nimport { EMPTY, filter, mergeMap, Subject, take } from \"rxjs\";\nimport { getDeleteCoordinates, getDeleteIds } from \"../helpers/delete.js\";\nimport { createReplaceableAddress, EventStoreSymbol, FromCacheSymbol, isReplaceable } from \"../helpers/event.js\";\nimport { getExpirationTimestamp } from \"../helpers/expiration.js\";\nimport { parseCoordinate } from \"../helpers/pointers.js\";\nimport { addSeenRelay, getSeenRelays } from \"../helpers/relays.js\";\nimport { unixNow } from \"../helpers/time.js\";\nimport { EventMemory } from \"./event-memory.js\";\nimport { EventStoreModelMixin } from \"./model-mixin.js\";\n/** A wrapper around an event database that handles replaceable events, deletes, and models */\nexport class EventStore extends EventStoreModelMixin(class {\n}) {\n database;\n /** Optional memory database for ensuring single event instances */\n memory;\n /** Enable this to keep old versions of replaceable events */\n keepOldVersions = false;\n /** Enable this to keep expired events */\n keepExpired = false;\n /**\n * A method used to verify new events before added them\n * @returns true if the event is valid, false if it should be ignored\n */\n verifyEvent;\n /** A stream of new events added to the store */\n insert$ = new Subject();\n /** A stream of events that have been updated */\n update$ = new Subject();\n /** A stream of events that have been removed */\n remove$ = new Subject();\n /**\n * A method that will be called when an event isn't found in the store\n * @experimental\n */\n eventLoader;\n /**\n * A method that will be called when a replaceable event isn't found in the store\n * @experimental\n */\n replaceableLoader;\n /**\n * A method that will be called when an addressable event isn't found in the store\n * @experimental\n */\n addressableLoader;\n constructor(database = new EventMemory()) {\n super();\n if (database) {\n this.database = database;\n this.memory = new EventMemory();\n }\n else {\n // If no database is provided, its the same as having a memory database\n this.database = this.memory = new EventMemory();\n }\n // when events are added to the database, add the symbol\n this.insert$.subscribe((event) => {\n Reflect.set(event, EventStoreSymbol, this);\n });\n // when events are removed from the database, remove the symbol\n this.remove$.subscribe((event) => {\n Reflect.deleteProperty(event, EventStoreSymbol);\n });\n }\n mapToMemory(event) {\n if (event === undefined)\n return undefined;\n if (!this.memory)\n return event;\n return this.memory.add(event);\n }\n // delete state\n deletedIds = new Set();\n deletedCoords = new Map();\n checkDeleted(event) {\n if (typeof event === \"string\")\n return this.deletedIds.has(event);\n else {\n if (this.deletedIds.has(event.id))\n return true;\n if (isAddressableKind(event.kind)) {\n const identifier = event.tags.find((t) => t[0] === \"d\")?.[1];\n const deleted = this.deletedCoords.get(createReplaceableAddress(event.kind, event.pubkey, identifier));\n if (deleted)\n return deleted > event.created_at;\n }\n }\n return false;\n }\n expirations = new Map();\n /** Adds an event to the expiration map */\n addExpiration(event) {\n const expiration = getExpirationTimestamp(event);\n if (expiration && Number.isFinite(expiration))\n this.expirations.set(event.id, expiration);\n }\n expirationTimeout = null;\n nextExpirationCheck = null;\n handleExpiringEvent(event) {\n const expiration = getExpirationTimestamp(event);\n if (!expiration)\n return;\n // Add event to expiration map\n this.expirations.set(event.id, expiration);\n // Exit if the next check is already less than the next expiration\n if (this.expirationTimeout && this.nextExpirationCheck && this.nextExpirationCheck < expiration)\n return;\n // Set timeout to prune expired events\n if (this.expirationTimeout)\n clearTimeout(this.expirationTimeout);\n const timeout = expiration - unixNow();\n this.expirationTimeout = setTimeout(this.pruneExpired.bind(this), timeout * 1000 + 10);\n this.nextExpirationCheck = expiration;\n }\n /** Remove expired events from the store */\n pruneExpired() {\n const now = unixNow();\n for (const [id, expiration] of this.expirations) {\n if (expiration <= now) {\n this.expirations.delete(id);\n this.remove(id);\n }\n }\n // Cleanup timers\n if (this.expirationTimeout)\n clearTimeout(this.expirationTimeout);\n this.nextExpirationCheck = null;\n this.expirationTimeout = null;\n }\n // handling delete events\n handleDeleteEvent(deleteEvent) {\n const ids = getDeleteIds(deleteEvent);\n for (const id of ids) {\n this.deletedIds.add(id);\n // remove deleted events in the database\n this.remove(id);\n }\n const coords = getDeleteCoordinates(deleteEvent);\n for (const coord of coords) {\n this.deletedCoords.set(coord, Math.max(this.deletedCoords.get(coord) ?? 0, deleteEvent.created_at));\n // Parse the nostr address coordinate\n const parsed = parseCoordinate(coord);\n if (!parsed)\n continue;\n // Remove older versions of replaceable events\n const events = this.database.getReplaceableHistory(parsed.kind, parsed.pubkey, parsed.identifier) ?? [];\n for (const event of events) {\n if (event.created_at < deleteEvent.created_at)\n this.remove(event);\n }\n }\n }\n /** Copies important metadata from and identical event to another */\n static mergeDuplicateEvent(source, dest) {\n const relays = getSeenRelays(source);\n if (relays) {\n for (const relay of relays)\n addSeenRelay(dest, relay);\n }\n // copy the from cache symbol only if its true\n const fromCache = Reflect.get(source, FromCacheSymbol);\n if (fromCache && !Reflect.get(dest, FromCacheSymbol))\n Reflect.set(dest, FromCacheSymbol, fromCache);\n }\n /**\n * Adds an event to the store and update subscriptions\n * @returns The existing event or the event that was added, if it was ignored returns null\n */\n add(event, fromRelay) {\n // Handle delete events differently\n if (event.kind === kinds.EventDeletion)\n this.handleDeleteEvent(event);\n // Ignore if the event was deleted\n if (this.checkDeleted(event))\n return event;\n // Reject expired events if keepExpired is false\n const expiration = getExpirationTimestamp(event);\n if (this.keepExpired === false && expiration && expiration <= unixNow())\n return null;\n // Get the replaceable identifier\n const identifier = isReplaceable(event.kind) ? event.tags.find((t) => t[0] === \"d\")?.[1] : undefined;\n // Don't insert the event if there is already a newer version\n if (!this.keepOldVersions && isReplaceable(event.kind)) {\n const existing = this.database.getReplaceableHistory(event.kind, event.pubkey, identifier);\n // If there is already a newer version, copy cached symbols and return existing event\n if (existing && existing.length > 0 && existing[0].created_at >= event.created_at) {\n EventStore.mergeDuplicateEvent(event, existing[0]);\n return existing[0];\n }\n }\n // Verify event before inserting into the database\n if (this.verifyEvent && this.verifyEvent(event) === false)\n return null;\n // Always add event to memory\n const existing = this.memory?.add(event);\n // If the memory returned a different instance, this is a duplicate event\n if (existing && existing !== event) {\n // Copy cached symbols and return existing event\n EventStore.mergeDuplicateEvent(event, existing);\n // attach relay this event was from\n if (fromRelay)\n addSeenRelay(existing, fromRelay);\n return existing;\n }\n // Insert event into database\n const inserted = this.mapToMemory(this.database.add(event));\n // Copy cached data if its a duplicate event\n if (event !== inserted)\n EventStore.mergeDuplicateEvent(event, inserted);\n // attach relay this event was from\n if (fromRelay)\n addSeenRelay(inserted, fromRelay);\n // Emit insert$ signal\n if (inserted === event)\n this.insert$.next(inserted);\n // remove all old version of the replaceable event\n if (!this.keepOldVersions && isReplaceable(event.kind)) {\n const existing = this.database.getReplaceableHistory(event.kind, event.pubkey, identifier);\n if (existing && existing.length > 0) {\n const older = Array.from(existing).filter((e) => e.created_at < event.created_at);\n for (const old of older)\n this.remove(old);\n // return the newest version of the replaceable event\n // most of the time this will be === event, but not always\n if (existing.length !== older.length)\n return existing[0];\n }\n }\n // Add event to expiration map\n if (this.keepExpired === false && expiration)\n this.handleExpiringEvent(inserted);\n return inserted;\n }\n /** Removes an event from the store and updates subscriptions */\n remove(event) {\n let instance = this.memory?.getEvent(typeof event === \"string\" ? event : event.id);\n // Remove from memory if available\n if (this.memory)\n this.memory.remove(event);\n // Remove the event from the database\n const removed = this.database.remove(event);\n // If the event was removed, notify the subscriptions\n if (removed && instance) {\n this.remove$.next(instance);\n }\n return removed;\n }\n /** Remove multiple events that match the given filters */\n removeByFilters(filters) {\n // Get events that will be removed for notification\n const eventsToRemove = this.getByFilters(filters);\n // Remove from memory if available\n if (this.memory)\n this.memory.removeByFilters(filters);\n // Remove from database\n const removedCount = this.database.removeByFilters(filters);\n // Notify subscriptions for each removed event\n for (const event of eventsToRemove) {\n this.remove$.next(event);\n }\n return removedCount;\n }\n /** Add an event to the store and notifies all subscribes it has updated */\n update(event) {\n // Map the event to the current instance in the database\n const e = this.database.add(event);\n if (!e)\n return false;\n // Notify the database that the event has updated\n this.database.update?.(event);\n this.update$.next(event);\n return true;\n }\n /** Check if the store has an event by id */\n hasEvent(id) {\n // Check if the event exists in memory first, then in the database\n return this.memory?.hasEvent(id) || this.database.hasEvent(id);\n }\n /** Get an event by id from the store */\n getEvent(id) {\n // Get the event from memory first, then from the database\n return this.memory?.getEvent(id) ?? this.mapToMemory(this.database.getEvent(id));\n }\n /** Check if the store has a replaceable event */\n hasReplaceable(kind, pubkey, d) {\n // Check if the event exists in memory first, then in the database\n return this.memory?.hasReplaceable(kind, pubkey, d) || this.database.hasReplaceable(kind, pubkey, d);\n }\n /** Gets the latest version of a replaceable event */\n getReplaceable(kind, pubkey, identifier) {\n // Get the event from memory first, then from the database\n return (this.memory?.getReplaceable(kind, pubkey, identifier) ??\n this.mapToMemory(this.database.getReplaceable(kind, pubkey, identifier)));\n }\n /** Returns all versions of a replaceable event */\n getReplaceableHistory(kind, pubkey, identifier) {\n // Get the events from memory first, then from the database\n return (this.memory?.getReplaceableHistory(kind, pubkey, identifier) ??\n this.database.getReplaceableHistory(kind, pubkey, identifier)?.map((e) => this.mapToMemory(e) ?? e));\n }\n /** Get all events matching a filter */\n getByFilters(filters) {\n // NOTE: no way to read from memory since memory won't have the full set of events\n const events = this.database.getByFilters(filters);\n // Map events to memory if available for better performance\n if (this.memory)\n return events.map((e) => this.mapToMemory(e));\n else\n return events;\n }\n /** Returns a timeline of events that match filters */\n getTimeline(filters) {\n const events = this.database.getTimeline(filters);\n if (this.memory)\n return events.map((e) => this.mapToMemory(e));\n else\n return events;\n }\n /** Passthrough method for the database.touch */\n touch(event) {\n return this.memory?.touch(event);\n }\n /** Increments the claim count on the event and touches it */\n claim(event) {\n return this.memory?.claim(event);\n }\n /** Checks if an event is claimed by anything */\n isClaimed(event) {\n return this.memory?.isClaimed(event) ?? false;\n }\n /** Decrements the claim count on an event */\n removeClaim(event) {\n return this.memory?.removeClaim(event);\n }\n /** Removes all claims on an event */\n clearClaim(event) {\n return this.memory?.clearClaim(event);\n }\n /** Pass through method for the database.unclaimed */\n unclaimed() {\n return this.memory?.unclaimed() || (function* () { })();\n }\n /** Removes any event that is not being used by a subscription */\n prune(limit) {\n return this.memory?.prune(limit) ?? 0;\n }\n /** Returns an observable that completes when an event is removed */\n removed(id) {\n const deleted = this.checkDeleted(id);\n if (deleted)\n return EMPTY;\n return this.remove$.pipe(\n // listen for removed events\n filter((e) => e.id === id), \n // complete as soon as we find a matching removed event\n take(1), \n // switch to empty\n mergeMap(() => EMPTY));\n }\n /** Creates an observable that emits when event is updated */\n updated(event) {\n return this.update$.pipe(filter((e) => e.id === event || e === event));\n }\n}\n","import { isATag, isETag } from \"./tags.js\";\nexport function getDeleteIds(deleteEvent) {\n return deleteEvent.tags.filter(isETag).map((t) => t[1]);\n}\nexport function getDeleteCoordinates(deleteEvent) {\n return deleteEvent.tags.filter(isATag).map((t) => t[1]);\n}\n","/** Creates a controlled promise */\nexport function createDefer() {\n let _resolve;\n let _reject;\n const promise = new Promise((resolve, reject) => {\n // @ts-ignore\n _resolve = resolve;\n _reject = reject;\n });\n // @ts-ignore\n promise.resolve = _resolve;\n // @ts-ignore\n promise.reject = _reject;\n return promise;\n}\n","import { getEventHash, nip19, verifyEvent } from \"nostr-tools\";\nimport { getPubkeyFromDecodeResult, isHexKey, isHex } from \"applesauce-core/helpers\";\nimport { createDefer } from \"applesauce-core/promise\";\n/**\n * A Signer for [amber](https://github.com/greenart7c3/Amber) clipboard API\n * @see https://github.com/greenart7c3/Amber/blob/master/docs/web-apps.md\n */\nexport class AmberClipboardSigner {\n /** If the signer is supported on this platform */\n static SUPPORTED = `navigator` in globalThis &&\n navigator.userAgent.includes(\"Android\") &&\n navigator.clipboard &&\n navigator.clipboard.readText;\n pendingRequest = null;\n pubkey;\n verifyEvent = verifyEvent;\n nip04;\n nip44;\n constructor() {\n document.addEventListener(\"visibilitychange\", this.onVisibilityChange);\n this.nip04 = {\n encrypt: this.nip04Encrypt.bind(this),\n decrypt: this.nip04Decrypt.bind(this),\n };\n this.nip44 = {\n encrypt: this.nip44Encrypt.bind(this),\n decrypt: this.nip44Decrypt.bind(this),\n };\n }\n onVisibilityChange = () => {\n if (document.visibilityState === \"visible\") {\n if (!this.pendingRequest || !navigator.clipboard)\n return;\n // read the result from the clipboard\n setTimeout(() => {\n navigator.clipboard\n .readText()\n .then((result) => this.pendingRequest?.resolve(result))\n .catch((e) => this.pendingRequest?.reject(e));\n }, 200);\n }\n };\n async intentRequest(intent) {\n this.rejectPending();\n const request = createDefer();\n window.open(intent, \"_blank\");\n // NOTE: wait 500ms before setting the pending request since the visibilitychange event fires as soon as window.open is called\n setTimeout(() => {\n this.pendingRequest = request;\n }, 500);\n const result = await request;\n if (result.length === 0)\n throw new Error(\"Empty clipboard\");\n return result;\n }\n /** Reject the currently pending request */\n rejectPending() {\n if (this.pendingRequest) {\n this.pendingRequest.reject(\"Canceled\");\n this.pendingRequest = null;\n }\n }\n /** Removes any event listeners created */\n destroy() {\n document.removeEventListener(\"visibilitychange\", this.onVisibilityChange);\n }\n checkSupport() {\n if (!AmberClipboardSigner.SUPPORTED)\n throw new Error(\"Cant use Amber on non-Android device\");\n }\n async getPublicKey() {\n this.checkSupport();\n if (this.pubkey)\n return this.pubkey;\n const result = await this.intentRequest(AmberClipboardSigner.createGetPublicKeyIntent());\n if (isHexKey(result)) {\n this.pubkey = result;\n return result;\n }\n else if (result.startsWith(\"npub\") || result.startsWith(\"nprofile\")) {\n const decode = nip19.decode(result);\n const pubkey = getPubkeyFromDecodeResult(decode);\n if (!pubkey)\n throw new Error(\"Expected npub from clipboard\");\n this.pubkey = pubkey;\n return pubkey;\n }\n throw new Error(\"Expected clipboard to have pubkey\");\n }\n async signEvent(draft) {\n this.checkSupport();\n const pubkey = draft.pubkey || this.pubkey;\n if (!pubkey)\n throw new Error(\"Unknown signer pubkey\");\n const draftWithId = { ...draft, id: getEventHash({ ...draft, pubkey }) };\n const sig = await this.intentRequest(AmberClipboardSigner.createSignEventIntent(draftWithId));\n if (!isHex(sig))\n throw new Error(\"Expected hex signature\");\n const event = { ...draftWithId, sig, pubkey };\n if (!this.verifyEvent(event))\n throw new Error(\"Invalid signature\");\n return event;\n }\n // NIP-04\n async nip04Encrypt(pubkey, plaintext) {\n this.checkSupport();\n const data = await this.intentRequest(AmberClipboardSigner.createNip04EncryptIntent(pubkey, plaintext));\n return data;\n }\n async nip04Decrypt(pubkey, data) {\n this.checkSupport();\n const plaintext = await this.intentRequest(AmberClipboardSigner.createNip04DecryptIntent(pubkey, data));\n return plaintext;\n }\n // NIP-44\n async nip44Encrypt(pubkey, plaintext) {\n this.checkSupport();\n const data = await this.intentRequest(AmberClipboardSigner.createNip44EncryptIntent(pubkey, plaintext));\n return data;\n }\n async nip44Decrypt(pubkey, data) {\n this.checkSupport();\n const plaintext = await this.intentRequest(AmberClipboardSigner.createNip44DecryptIntent(pubkey, data));\n return plaintext;\n }\n // static methods\n static createGetPublicKeyIntent() {\n return `intent:#Intent;scheme=nostrsigner;S.compressionType=none;S.returnType=signature;S.type=get_public_key;end`;\n }\n static createSignEventIntent(draft) {\n return `intent:${encodeURIComponent(JSON.stringify(draft))}#Intent;scheme=nostrsigner;S.compressionType=none;S.returnType=signature;S.type=sign_event;end`;\n }\n static createNip04EncryptIntent(pubkey, plainText) {\n return `intent:${encodeURIComponent(plainText)}#Intent;scheme=nostrsigner;S.pubKey=${pubkey};S.compressionType=none;S.returnType=signature;S.type=nip04_encrypt;end`;\n }\n static createNip04DecryptIntent(pubkey, ciphertext) {\n return `intent:${encodeURIComponent(ciphertext)}#Intent;scheme=nostrsigner;S.pubKey=${pubkey};S.compressionType=none;S.returnType=signature;S.type=nip04_decrypt;end`;\n }\n static createNip44EncryptIntent(pubkey, plainText) {\n return `intent:${encodeURIComponent(plainText)}#Intent;scheme=nostrsigner;S.pubKey=${pubkey};S.compressionType=none;S.returnType=signature;S.type=nip44_encrypt;end`;\n }\n static createNip44DecryptIntent(pubkey, ciphertext) {\n return `intent:${encodeURIComponent(ciphertext)}#Intent;scheme=nostrsigner;S.pubKey=${pubkey};S.compressionType=none;S.returnType=signature;S.type=nip44_decrypt;end`;\n }\n}\n","import { setHiddenContentEncryptionMethod } from \"applesauce-core/helpers\";\nimport { isHexKey } from \"applesauce-core/helpers/string\";\nimport { kinds } from \"nostr-tools\";\n// Set encryption types for nostr connect events\nsetHiddenContentEncryptionMethod(kinds.NostrConnect, \"nip44\");\nexport function isErrorResponse(response) {\n return !!response.error;\n}\nexport var Permission;\n(function (Permission) {\n Permission[\"GetPublicKey\"] = \"get_pubic_key\";\n Permission[\"SignEvent\"] = \"sign_event\";\n Permission[\"Nip04Encrypt\"] = \"nip04_encrypt\";\n Permission[\"Nip04Decrypt\"] = \"nip04_decrypt\";\n Permission[\"Nip44Encrypt\"] = \"nip44_encrypt\";\n Permission[\"Nip44Decrypt\"] = \"nip44_decrypt\";\n})(Permission || (Permission = {}));\nexport var NostrConnectMethod;\n(function (NostrConnectMethod) {\n NostrConnectMethod[\"Connect\"] = \"connect\";\n NostrConnectMethod[\"CreateAccount\"] = \"create_account\";\n NostrConnectMethod[\"GetPublicKey\"] = \"get_public_key\";\n NostrConnectMethod[\"SignEvent\"] = \"sign_event\";\n NostrConnectMethod[\"Nip04Encrypt\"] = \"nip04_encrypt\";\n NostrConnectMethod[\"Nip04Decrypt\"] = \"nip04_decrypt\";\n NostrConnectMethod[\"Nip44Encrypt\"] = \"nip44_encrypt\";\n NostrConnectMethod[\"Nip44Decrypt\"] = \"nip44_decrypt\";\n})(NostrConnectMethod || (NostrConnectMethod = {}));\n/** Parse a bunker:// URI */\nexport function parseBunkerURI(uri) {\n const url = new URL(uri);\n // firefox puts pubkey part in host, chrome puts pubkey in pathname\n const remote = url.host || url.pathname.replace(\"//\", \"\");\n if (!isHexKey(remote))\n throw new Error(\"Invalid bunker URI: remote is not a valid hex key\");\n const relays = url.searchParams.getAll(\"relay\");\n if (relays.length === 0)\n throw new Error(\"Invalid bunker URI: missing relays\");\n const secret = url.searchParams.get(\"secret\") ?? undefined;\n return { remote, relays, secret };\n}\n/** Creates a bunker:// URI from a {@link BunkerURI} object */\nexport function createBunkerURI(data) {\n const url = new URL(`bunker://${data.remote}`);\n data.relays.forEach((relay) => url.searchParams.append(\"relay\", relay));\n if (data.secret)\n url.searchParams.set(\"secret\", data.secret);\n return url.toString();\n}\n/** Parse a nostrconnect:// URI */\nexport function parseNostrConnectURI(uri) {\n const url = new URL(uri);\n const client = url.host || url.pathname.replace(\"//\", \"\");\n if (!isHexKey(client))\n throw new Error(\"Invalid nostrconnect URI: client is not a valid hex key\");\n const secret = url.searchParams.get(\"secret\");\n const relays = url.searchParams.getAll(\"relay\");\n if (!secret)\n throw new Error(\"Invalid nostrconnect URI: missing secret\");\n if (relays.length === 0)\n throw new Error(\"Invalid nostrconnect URI: missing relays\");\n const metadata = {\n name: url.searchParams.get(\"name\") ?? undefined,\n image: url.searchParams.get(\"image\") ?? undefined,\n url: url.searchParams.get(\"url\") ?? undefined,\n permissions: url.searchParams.get(\"perms\")?.split(\",\") ?? undefined,\n };\n /** Omit metadata if all values are undefined */\n if (Object.values(metadata).every((v) => v === undefined))\n return { client, secret, relays };\n else\n return { client, secret, relays, metadata };\n}\n/** Create a nostrconnect:// URI from a {@link NostrConnectURI} object */\nexport function createNostrConnectURI(data) {\n const params = new URLSearchParams();\n params.set(\"secret\", data.secret);\n if (data.metadata?.name)\n params.set(\"name\", data.metadata.name);\n if (data.metadata?.url)\n params.set(\"url\", String(data.metadata.url));\n if (data.metadata?.image)\n params.set(\"image\", data.metadata.image);\n if (data.metadata?.permissions)\n params.set(\"perms\", data.metadata.permissions.join(\",\"));\n for (const relay of data.relays)\n params.append(\"relay\", relay);\n return `nostrconnect://${data.client}?` + params.toString();\n}\n/** Build an array of signing permissions for event kinds */\nexport function buildSigningPermissions(kinds) {\n return [Permission.GetPublicKey, ...kinds.map((k) => `${Permission.SignEvent}:${k}`)];\n}\n","import { normalizeToSecretKey } from \"applesauce-core/helpers\";\nimport { finalizeEvent, generateSecretKey, getPublicKey, nip04, nip44 } from \"nostr-tools\";\n/** A Simple signer that holds the private key in memory */\nexport class PrivateKeySigner {\n key;\n constructor(key) {\n this.key = key || generateSecretKey();\n }\n async getPublicKey() {\n return getPublicKey(this.key);\n }\n async signEvent(event) {\n return finalizeEvent(event, this.key);\n }\n nip04 = {\n encrypt: async (pubkey, plaintext) => nip04.encrypt(this.key, pubkey, plaintext),\n decrypt: async (pubkey, ciphertext) => nip04.decrypt(this.key, pubkey, ciphertext),\n };\n nip44 = {\n encrypt: async (pubkey, plaintext) => nip44.v2.encrypt(plaintext, nip44.v2.utils.getConversationKey(this.key, pubkey)),\n decrypt: async (pubkey, ciphertext) => nip44.v2.decrypt(ciphertext, nip44.v2.utils.getConversationKey(this.key, pubkey)),\n };\n /** Creates a PrivateKeySigner from a hex private key or NIP-19 nsec */\n static fromKey(privateKey) {\n return new PrivateKeySigner(normalizeToSecretKey(privateKey));\n }\n}\n","/*! noble-secp256k1 - MIT License (c) 2019 Paul Miller (paulmillr.com) */\nimport * as nodeCrypto from 'crypto';\nconst _0n = BigInt(0);\nconst _1n = BigInt(1);\nconst _2n = BigInt(2);\nconst _3n = BigInt(3);\nconst _8n = BigInt(8);\nconst CURVE = Object.freeze({\n a: _0n,\n b: BigInt(7),\n P: BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f'),\n n: BigInt('0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141'),\n h: _1n,\n Gx: BigInt('55066263022277343669578718895168534326250603453777594175500187360389116729240'),\n Gy: BigInt('32670510020758816978083085130507043184471273380659243275938904335757337482424'),\n beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),\n});\nconst divNearest = (a, b) => (a + b / _2n) / b;\nconst endo = {\n beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),\n splitScalar(k) {\n const { n } = CURVE;\n const a1 = BigInt('0x3086d221a7d46bcde86c90e49284eb15');\n const b1 = -_1n * BigInt('0xe4437ed6010e88286f547fa90abfe4c3');\n const a2 = BigInt('0x114ca50f7a8e2f3f657c1108d9d44cfd8');\n const b2 = a1;\n const POW_2_128 = BigInt('0x100000000000000000000000000000000');\n const c1 = divNearest(b2 * k, n);\n const c2 = divNearest(-b1 * k, n);\n let k1 = mod(k - c1 * a1 - c2 * a2, n);\n let k2 = mod(-c1 * b1 - c2 * b2, n);\n const k1neg = k1 > POW_2_128;\n const k2neg = k2 > POW_2_128;\n if (k1neg)\n k1 = n - k1;\n if (k2neg)\n k2 = n - k2;\n if (k1 > POW_2_128 || k2 > POW_2_128) {\n throw new Error('splitScalarEndo: Endomorphism failed, k=' + k);\n }\n return { k1neg, k1, k2neg, k2 };\n },\n};\nconst fieldLen = 32;\nconst groupLen = 32;\nconst hashLen = 32;\nconst compressedLen = fieldLen + 1;\nconst uncompressedLen = 2 * fieldLen + 1;\nexport { CURVE };\nfunction weierstrass(x) {\n const { a, b } = CURVE;\n const x2 = mod(x * x);\n const x3 = mod(x2 * x);\n return mod(x3 + a * x + b);\n}\nconst USE_ENDOMORPHISM = CURVE.a === _0n;\nclass ShaError extends Error {\n constructor(message) {\n super(message);\n }\n}\nfunction assertJacPoint(other) {\n if (!(other instanceof JacobianPoint))\n throw new TypeError('JacobianPoint expected');\n}\nclass JacobianPoint {\n constructor(x, y, z) {\n this.x = x;\n this.y = y;\n this.z = z;\n }\n static fromAffine(p) {\n if (!(p instanceof Point)) {\n throw new TypeError('JacobianPoint#fromAffine: expected Point');\n }\n if (p.equals(Point.ZERO))\n return JacobianPoint.ZERO;\n return new JacobianPoint(p.x, p.y, _1n);\n }\n static toAffineBatch(points) {\n const toInv = invertBatch(points.map((p) => p.z));\n return points.map((p, i) => p.toAffine(toInv[i]));\n }\n static normalizeZ(points) {\n return JacobianPoint.toAffineBatch(points).map(JacobianPoint.fromAffine);\n }\n equals(other) {\n assertJacPoint(other);\n const { x: X1, y: Y1, z: Z1 } = this;\n const { x: X2, y: Y2, z: Z2 } = other;\n const Z1Z1 = mod(Z1 * Z1);\n const Z2Z2 = mod(Z2 * Z2);\n const U1 = mod(X1 * Z2Z2);\n const U2 = mod(X2 * Z1Z1);\n const S1 = mod(mod(Y1 * Z2) * Z2Z2);\n const S2 = mod(mod(Y2 * Z1) * Z1Z1);\n return U1 === U2 && S1 === S2;\n }\n negate() {\n return new JacobianPoint(this.x, mod(-this.y), this.z);\n }\n double() {\n const { x: X1, y: Y1, z: Z1 } = this;\n const A = mod(X1 * X1);\n const B = mod(Y1 * Y1);\n const C = mod(B * B);\n const x1b = X1 + B;\n const D = mod(_2n * (mod(x1b * x1b) - A - C));\n const E = mod(_3n * A);\n const F = mod(E * E);\n const X3 = mod(F - _2n * D);\n const Y3 = mod(E * (D - X3) - _8n * C);\n const Z3 = mod(_2n * Y1 * Z1);\n return new JacobianPoint(X3, Y3, Z3);\n }\n add(other) {\n assertJacPoint(other);\n const { x: X1, y: Y1, z: Z1 } = this;\n const { x: X2, y: Y2, z: Z2 } = other;\n if (X2 === _0n || Y2 === _0n)\n return this;\n if (X1 === _0n || Y1 === _0n)\n return other;\n const Z1Z1 = mod(Z1 * Z1);\n const Z2Z2 = mod(Z2 * Z2);\n const U1 = mod(X1 * Z2Z2);\n const U2 = mod(X2 * Z1Z1);\n const S1 = mod(mod(Y1 * Z2) * Z2Z2);\n const S2 = mod(mod(Y2 * Z1) * Z1Z1);\n const H = mod(U2 - U1);\n const r = mod(S2 - S1);\n if (H === _0n) {\n if (r === _0n) {\n return this.double();\n }\n else {\n return JacobianPoint.ZERO;\n }\n }\n const HH = mod(H * H);\n const HHH = mod(H * HH);\n const V = mod(U1 * HH);\n const X3 = mod(r * r - HHH - _2n * V);\n const Y3 = mod(r * (V - X3) - S1 * HHH);\n const Z3 = mod(Z1 * Z2 * H);\n return new JacobianPoint(X3, Y3, Z3);\n }\n subtract(other) {\n return this.add(other.negate());\n }\n multiplyUnsafe(scalar) {\n const P0 = JacobianPoint.ZERO;\n if (typeof scalar === 'bigint' && scalar === _0n)\n return P0;\n let n = normalizeScalar(scalar);\n if (n === _1n)\n return this;\n if (!USE_ENDOMORPHISM) {\n let p = P0;\n let d = this;\n while (n > _0n) {\n if (n & _1n)\n p = p.add(d);\n d = d.double();\n n >>= _1n;\n }\n return p;\n }\n let { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);\n let k1p = P0;\n let k2p = P0;\n let d = this;\n while (k1 > _0n || k2 > _0n) {\n if (k1 & _1n)\n k1p = k1p.add(d);\n if (k2 & _1n)\n k2p = k2p.add(d);\n d = d.double();\n k1 >>= _1n;\n k2 >>= _1n;\n }\n if (k1neg)\n k1p = k1p.negate();\n if (k2neg)\n k2p = k2p.negate();\n k2p = new JacobianPoint(mod(k2p.x * endo.beta), k2p.y, k2p.z);\n return k1p.add(k2p);\n }\n precomputeWindow(W) {\n const windows = USE_ENDOMORPHISM ? 128 / W + 1 : 256 / W + 1;\n const points = [];\n let p = this;\n let base = p;\n for (let window = 0; window < windows; window++) {\n base = p;\n points.push(base);\n for (let i = 1; i < 2 ** (W - 1); i++) {\n base = base.add(p);\n points.push(base);\n }\n p = base.double();\n }\n return points;\n }\n wNAF(n, affinePoint) {\n if (!affinePoint && this.equals(JacobianPoint.BASE))\n affinePoint = Point.BASE;\n const W = (affinePoint && affinePoint._WINDOW_SIZE) || 1;\n if (256 % W) {\n throw new Error('Point#wNAF: Invalid precomputation window, must be power of 2');\n }\n let precomputes = affinePoint && pointPrecomputes.get(affinePoint);\n if (!precomputes) {\n precomputes = this.precomputeWindow(W);\n if (affinePoint && W !== 1) {\n precomputes = JacobianPoint.normalizeZ(precomputes);\n pointPrecomputes.set(affinePoint, precomputes);\n }\n }\n let p = JacobianPoint.ZERO;\n let f = JacobianPoint.BASE;\n const windows = 1 + (USE_ENDOMORPHISM ? 128 / W : 256 / W);\n const windowSize = 2 ** (W - 1);\n const mask = BigInt(2 ** W - 1);\n const maxNumber = 2 ** W;\n const shiftBy = BigInt(W);\n for (let window = 0; window < windows; window++) {\n const offset = window * windowSize;\n let wbits = Number(n & mask);\n n >>= shiftBy;\n if (wbits > windowSize) {\n wbits -= maxNumber;\n n += _1n;\n }\n const offset1 = offset;\n const offset2 = offset + Math.abs(wbits) - 1;\n const cond1 = window % 2 !== 0;\n const cond2 = wbits < 0;\n if (wbits === 0) {\n f = f.add(constTimeNegate(cond1, precomputes[offset1]));\n }\n else {\n p = p.add(constTimeNegate(cond2, precomputes[offset2]));\n }\n }\n return { p, f };\n }\n multiply(scalar, affinePoint) {\n let n = normalizeScalar(scalar);\n let point;\n let fake;\n if (USE_ENDOMORPHISM) {\n const { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);\n let { p: k1p, f: f1p } = this.wNAF(k1, affinePoint);\n let { p: k2p, f: f2p } = this.wNAF(k2, affinePoint);\n k1p = constTimeNegate(k1neg, k1p);\n k2p = constTimeNegate(k2neg, k2p);\n k2p = new JacobianPoint(mod(k2p.x * endo.beta), k2p.y, k2p.z);\n point = k1p.add(k2p);\n fake = f1p.add(f2p);\n }\n else {\n const { p, f } = this.wNAF(n, affinePoint);\n point = p;\n fake = f;\n }\n return JacobianPoint.normalizeZ([point, fake])[0];\n }\n toAffine(invZ) {\n const { x, y, z } = this;\n const is0 = this.equals(JacobianPoint.ZERO);\n if (invZ == null)\n invZ = is0 ? _8n : invert(z);\n const iz1 = invZ;\n const iz2 = mod(iz1 * iz1);\n const iz3 = mod(iz2 * iz1);\n const ax = mod(x * iz2);\n const ay = mod(y * iz3);\n const zz = mod(z * iz1);\n if (is0)\n return Point.ZERO;\n if (zz !== _1n)\n throw new Error('invZ was invalid');\n return new Point(ax, ay);\n }\n}\nJacobianPoint.BASE = new JacobianPoint(CURVE.Gx, CURVE.Gy, _1n);\nJacobianPoint.ZERO = new JacobianPoint(_0n, _1n, _0n);\nfunction constTimeNegate(condition, item) {\n const neg = item.negate();\n return condition ? neg : item;\n}\nconst pointPrecomputes = new WeakMap();\nexport class Point {\n constructor(x, y) {\n this.x = x;\n this.y = y;\n }\n _setWindowSize(windowSize) {\n this._WINDOW_SIZE = windowSize;\n pointPrecomputes.delete(this);\n }\n hasEvenY() {\n return this.y % _2n === _0n;\n }\n static fromCompressedHex(bytes) {\n const isShort = bytes.length === 32;\n const x = bytesToNumber(isShort ? bytes : bytes.subarray(1));\n if (!isValidFieldElement(x))\n throw new Error('Point is not on curve');\n const y2 = weierstrass(x);\n let y = sqrtMod(y2);\n const isYOdd = (y & _1n) === _1n;\n if (isShort) {\n if (isYOdd)\n y = mod(-y);\n }\n else {\n const isFirstByteOdd = (bytes[0] & 1) === 1;\n if (isFirstByteOdd !== isYOdd)\n y = mod(-y);\n }\n const point = new Point(x, y);\n point.assertValidity();\n return point;\n }\n static fromUncompressedHex(bytes) {\n const x = bytesToNumber(bytes.subarray(1, fieldLen + 1));\n const y = bytesToNumber(bytes.subarray(fieldLen + 1, fieldLen * 2 + 1));\n const point = new Point(x, y);\n point.assertValidity();\n return point;\n }\n static fromHex(hex) {\n const bytes = ensureBytes(hex);\n const len = bytes.length;\n const header = bytes[0];\n if (len === fieldLen)\n return this.fromCompressedHex(bytes);\n if (len === compressedLen && (header === 0x02 || header === 0x03)) {\n return this.fromCompressedHex(bytes);\n }\n if (len === uncompressedLen && header === 0x04)\n return this.fromUncompressedHex(bytes);\n throw new Error(`Point.fromHex: received invalid point. Expected 32-${compressedLen} compressed bytes or ${uncompressedLen} uncompressed bytes, not ${len}`);\n }\n static fromPrivateKey(privateKey) {\n return Point.BASE.multiply(normalizePrivateKey(privateKey));\n }\n static fromSignature(msgHash, signature, recovery) {\n const { r, s } = normalizeSignature(signature);\n if (![0, 1, 2, 3].includes(recovery))\n throw new Error('Cannot recover: invalid recovery bit');\n const h = truncateHash(ensureBytes(msgHash));\n const { n } = CURVE;\n const radj = recovery === 2 || recovery === 3 ? r + n : r;\n const rinv = invert(radj, n);\n const u1 = mod(-h * rinv, n);\n const u2 = mod(s * rinv, n);\n const prefix = recovery & 1 ? '03' : '02';\n const R = Point.fromHex(prefix + numTo32bStr(radj));\n const Q = Point.BASE.multiplyAndAddUnsafe(R, u1, u2);\n if (!Q)\n throw new Error('Cannot recover signature: point at infinify');\n Q.assertValidity();\n return Q;\n }\n toRawBytes(isCompressed = false) {\n return hexToBytes(this.toHex(isCompressed));\n }\n toHex(isCompressed = false) {\n const x = numTo32bStr(this.x);\n if (isCompressed) {\n const prefix = this.hasEvenY() ? '02' : '03';\n return `${prefix}${x}`;\n }\n else {\n return `04${x}${numTo32bStr(this.y)}`;\n }\n }\n toHexX() {\n return this.toHex(true).slice(2);\n }\n toRawX() {\n return this.toRawBytes(true).slice(1);\n }\n assertValidity() {\n const msg = 'Point is not on elliptic curve';\n const { x, y } = this;\n if (!isValidFieldElement(x) || !isValidFieldElement(y))\n throw new Error(msg);\n const left = mod(y * y);\n const right = weierstrass(x);\n if (mod(left - right) !== _0n)\n throw new Error(msg);\n }\n equals(other) {\n return this.x === other.x && this.y === other.y;\n }\n negate() {\n return new Point(this.x, mod(-this.y));\n }\n double() {\n return JacobianPoint.fromAffine(this).double().toAffine();\n }\n add(other) {\n return JacobianPoint.fromAffine(this).add(JacobianPoint.fromAffine(other)).toAffine();\n }\n subtract(other) {\n return this.add(other.negate());\n }\n multiply(scalar) {\n return JacobianPoint.fromAffine(this).multiply(scalar, this).toAffine();\n }\n multiplyAndAddUnsafe(Q, a, b) {\n const P = JacobianPoint.fromAffine(this);\n const aP = a === _0n || a === _1n || this !== Point.BASE ? P.multiplyUnsafe(a) : P.multiply(a);\n const bQ = JacobianPoint.fromAffine(Q).multiplyUnsafe(b);\n const sum = aP.add(bQ);\n return sum.equals(JacobianPoint.ZERO) ? undefined : sum.toAffine();\n }\n}\nPoint.BASE = new Point(CURVE.Gx, CURVE.Gy);\nPoint.ZERO = new Point(_0n, _0n);\nfunction sliceDER(s) {\n return Number.parseInt(s[0], 16) >= 8 ? '00' + s : s;\n}\nfunction parseDERInt(data) {\n if (data.length < 2 || data[0] !== 0x02) {\n throw new Error(`Invalid signature integer tag: ${bytesToHex(data)}`);\n }\n const len = data[1];\n const res = data.subarray(2, len + 2);\n if (!len || res.length !== len) {\n throw new Error(`Invalid signature integer: wrong length`);\n }\n if (res[0] === 0x00 && res[1] <= 0x7f) {\n throw new Error('Invalid signature integer: trailing length');\n }\n return { data: bytesToNumber(res), left: data.subarray(len + 2) };\n}\nfunction parseDERSignature(data) {\n if (data.length < 2 || data[0] != 0x30) {\n throw new Error(`Invalid signature tag: ${bytesToHex(data)}`);\n }\n if (data[1] !== data.length - 2) {\n throw new Error('Invalid signature: incorrect length');\n }\n const { data: r, left: sBytes } = parseDERInt(data.subarray(2));\n const { data: s, left: rBytesLeft } = parseDERInt(sBytes);\n if (rBytesLeft.length) {\n throw new Error(`Invalid signature: left bytes after parsing: ${bytesToHex(rBytesLeft)}`);\n }\n return { r, s };\n}\nexport class Signature {\n constructor(r, s) {\n this.r = r;\n this.s = s;\n this.assertValidity();\n }\n static fromCompact(hex) {\n const arr = isBytes(hex);\n const name = 'Signature.fromCompact';\n if (typeof hex !== 'string' && !arr)\n throw new TypeError(`${name}: Expected string or Uint8Array`);\n const str = arr ? bytesToHex(hex) : hex;\n if (str.length !== 128)\n throw new Error(`${name}: Expected 64-byte hex`);\n return new Signature(hexToNumber(str.slice(0, 64)), hexToNumber(str.slice(64, 128)));\n }\n static fromDER(hex) {\n const arr = isBytes(hex);\n if (typeof hex !== 'string' && !arr)\n throw new TypeError(`Signature.fromDER: Expected string or Uint8Array`);\n const { r, s } = parseDERSignature(arr ? hex : hexToBytes(hex));\n return new Signature(r, s);\n }\n static fromHex(hex) {\n return this.fromDER(hex);\n }\n assertValidity() {\n const { r, s } = this;\n if (!isWithinCurveOrder(r))\n throw new Error('Invalid Signature: r must be 0 < r < n');\n if (!isWithinCurveOrder(s))\n throw new Error('Invalid Signature: s must be 0 < s < n');\n }\n hasHighS() {\n const HALF = CURVE.n >> _1n;\n return this.s > HALF;\n }\n normalizeS() {\n return this.hasHighS() ? new Signature(this.r, mod(-this.s, CURVE.n)) : this;\n }\n toDERRawBytes() {\n return hexToBytes(this.toDERHex());\n }\n toDERHex() {\n const sHex = sliceDER(numberToHexUnpadded(this.s));\n const rHex = sliceDER(numberToHexUnpadded(this.r));\n const sHexL = sHex.length / 2;\n const rHexL = rHex.length / 2;\n const sLen = numberToHexUnpadded(sHexL);\n const rLen = numberToHexUnpadded(rHexL);\n const length = numberToHexUnpadded(rHexL + sHexL + 4);\n return `30${length}02${rLen}${rHex}02${sLen}${sHex}`;\n }\n toRawBytes() {\n return this.toDERRawBytes();\n }\n toHex() {\n return this.toDERHex();\n }\n toCompactRawBytes() {\n return hexToBytes(this.toCompactHex());\n }\n toCompactHex() {\n return numTo32bStr(this.r) + numTo32bStr(this.s);\n }\n}\nfunction isBytes(a) {\n return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');\n}\nfunction abytes(item) {\n if (!isBytes(item))\n throw new Error('Uint8Array expected');\n}\nfunction concatBytes(...arrays) {\n arrays.every(abytes);\n if (arrays.length === 1)\n return arrays[0];\n const length = arrays.reduce((a, arr) => a + arr.length, 0);\n const result = new Uint8Array(length);\n for (let i = 0, pad = 0; i < arrays.length; i++) {\n const arr = arrays[i];\n result.set(arr, pad);\n pad += arr.length;\n }\n return result;\n}\nconst hexes = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));\nexport function bytesToHex(bytes) {\n abytes(bytes);\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += hexes[bytes[i]];\n }\n return hex;\n}\nconst asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };\nfunction asciiToBase16(ch) {\n if (ch >= asciis._0 && ch <= asciis._9)\n return ch - asciis._0;\n if (ch >= asciis.A && ch <= asciis.F)\n return ch - (asciis.A - 10);\n if (ch >= asciis.a && ch <= asciis.f)\n return ch - (asciis.a - 10);\n return;\n}\nexport function hexToBytes(hex) {\n if (typeof hex !== 'string')\n throw new Error('hex string expected, got ' + typeof hex);\n const hl = hex.length;\n const al = hl / 2;\n if (hl % 2)\n throw new Error('hex string expected, got unpadded hex of length ' + hl);\n const array = new Uint8Array(al);\n for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {\n const n1 = asciiToBase16(hex.charCodeAt(hi));\n const n2 = asciiToBase16(hex.charCodeAt(hi + 1));\n if (n1 === undefined || n2 === undefined) {\n const char = hex[hi] + hex[hi + 1];\n throw new Error('hex string expected, got non-hex character \"' + char + '\" at index ' + hi);\n }\n array[ai] = n1 * 16 + n2;\n }\n return array;\n}\nconst POW_2_256 = BigInt('0x10000000000000000000000000000000000000000000000000000000000000000');\nfunction numTo32bStr(num) {\n if (typeof num !== 'bigint')\n throw new Error('Expected bigint');\n if (!(_0n <= num && num < POW_2_256))\n throw new Error('Expected number 0 <= n < 2^256');\n return num.toString(16).padStart(64, '0');\n}\nfunction numTo32b(num) {\n const b = hexToBytes(numTo32bStr(num));\n if (b.length !== 32)\n throw new Error('Error: expected 32 bytes');\n return b;\n}\nfunction numberToHexUnpadded(num) {\n const hex = num.toString(16);\n return hex.length & 1 ? `0${hex}` : hex;\n}\nfunction hexToNumber(hex) {\n if (typeof hex !== 'string') {\n throw new TypeError('hexToNumber: expected string, got ' + typeof hex);\n }\n return BigInt(`0x${hex}`);\n}\nfunction bytesToNumber(bytes) {\n return hexToNumber(bytesToHex(bytes));\n}\nfunction ensureBytes(hex) {\n return isBytes(hex) ? Uint8Array.from(hex) : hexToBytes(hex);\n}\nfunction normalizeScalar(num) {\n if (typeof num === 'number' && Number.isSafeInteger(num) && num > 0)\n return BigInt(num);\n if (typeof num === 'bigint' && isWithinCurveOrder(num))\n return num;\n throw new TypeError('Expected valid private scalar: 0 < scalar < curve.n');\n}\nfunction mod(a, b = CURVE.P) {\n const result = a % b;\n return result >= _0n ? result : b + result;\n}\nfunction pow2(x, power) {\n const { P } = CURVE;\n let res = x;\n while (power-- > _0n) {\n res *= res;\n res %= P;\n }\n return res;\n}\nfunction sqrtMod(x) {\n const { P } = CURVE;\n const _6n = BigInt(6);\n const _11n = BigInt(11);\n const _22n = BigInt(22);\n const _23n = BigInt(23);\n const _44n = BigInt(44);\n const _88n = BigInt(88);\n const b2 = (x * x * x) % P;\n const b3 = (b2 * b2 * x) % P;\n const b6 = (pow2(b3, _3n) * b3) % P;\n const b9 = (pow2(b6, _3n) * b3) % P;\n const b11 = (pow2(b9, _2n) * b2) % P;\n const b22 = (pow2(b11, _11n) * b11) % P;\n const b44 = (pow2(b22, _22n) * b22) % P;\n const b88 = (pow2(b44, _44n) * b44) % P;\n const b176 = (pow2(b88, _88n) * b88) % P;\n const b220 = (pow2(b176, _44n) * b44) % P;\n const b223 = (pow2(b220, _3n) * b3) % P;\n const t1 = (pow2(b223, _23n) * b22) % P;\n const t2 = (pow2(t1, _6n) * b2) % P;\n const rt = pow2(t2, _2n);\n const xc = (rt * rt) % P;\n if (xc !== x)\n throw new Error('Cannot find square root');\n return rt;\n}\nfunction invert(number, modulo = CURVE.P) {\n if (number === _0n || modulo <= _0n) {\n throw new Error(`invert: expected positive integers, got n=${number} mod=${modulo}`);\n }\n let a = mod(number, modulo);\n let b = modulo;\n let x = _0n, y = _1n, u = _1n, v = _0n;\n while (a !== _0n) {\n const q = b / a;\n const r = b % a;\n const m = x - u * q;\n const n = y - v * q;\n b = a, a = r, x = u, y = v, u = m, v = n;\n }\n const gcd = b;\n if (gcd !== _1n)\n throw new Error('invert: does not exist');\n return mod(x, modulo);\n}\nfunction invertBatch(nums, p = CURVE.P) {\n const scratch = new Array(nums.length);\n const lastMultiplied = nums.reduce((acc, num, i) => {\n if (num === _0n)\n return acc;\n scratch[i] = acc;\n return mod(acc * num, p);\n }, _1n);\n const inverted = invert(lastMultiplied, p);\n nums.reduceRight((acc, num, i) => {\n if (num === _0n)\n return acc;\n scratch[i] = mod(acc * scratch[i], p);\n return mod(acc * num, p);\n }, inverted);\n return scratch;\n}\nfunction bits2int_2(bytes) {\n const delta = bytes.length * 8 - groupLen * 8;\n const num = bytesToNumber(bytes);\n return delta > 0 ? num >> BigInt(delta) : num;\n}\nfunction truncateHash(hash, truncateOnly = false) {\n const h = bits2int_2(hash);\n if (truncateOnly)\n return h;\n const { n } = CURVE;\n return h >= n ? h - n : h;\n}\nlet _sha256Sync;\nlet _hmacSha256Sync;\nclass HmacDrbg {\n constructor(hashLen, qByteLen) {\n this.hashLen = hashLen;\n this.qByteLen = qByteLen;\n if (typeof hashLen !== 'number' || hashLen < 2)\n throw new Error('hashLen must be a number');\n if (typeof qByteLen !== 'number' || qByteLen < 2)\n throw new Error('qByteLen must be a number');\n this.v = new Uint8Array(hashLen).fill(1);\n this.k = new Uint8Array(hashLen).fill(0);\n this.counter = 0;\n }\n hmac(...values) {\n return utils.hmacSha256(this.k, ...values);\n }\n hmacSync(...values) {\n return _hmacSha256Sync(this.k, ...values);\n }\n checkSync() {\n if (typeof _hmacSha256Sync !== 'function')\n throw new ShaError('hmacSha256Sync needs to be set');\n }\n incr() {\n if (this.counter >= 1000)\n throw new Error('Tried 1,000 k values for sign(), all were invalid');\n this.counter += 1;\n }\n async reseed(seed = new Uint8Array()) {\n this.k = await this.hmac(this.v, Uint8Array.from([0x00]), seed);\n this.v = await this.hmac(this.v);\n if (seed.length === 0)\n return;\n this.k = await this.hmac(this.v, Uint8Array.from([0x01]), seed);\n this.v = await this.hmac(this.v);\n }\n reseedSync(seed = new Uint8Array()) {\n this.checkSync();\n this.k = this.hmacSync(this.v, Uint8Array.from([0x00]), seed);\n this.v = this.hmacSync(this.v);\n if (seed.length === 0)\n return;\n this.k = this.hmacSync(this.v, Uint8Array.from([0x01]), seed);\n this.v = this.hmacSync(this.v);\n }\n async generate() {\n this.incr();\n let len = 0;\n const out = [];\n while (len < this.qByteLen) {\n this.v = await this.hmac(this.v);\n const sl = this.v.slice();\n out.push(sl);\n len += this.v.length;\n }\n return concatBytes(...out);\n }\n generateSync() {\n this.checkSync();\n this.incr();\n let len = 0;\n const out = [];\n while (len < this.qByteLen) {\n this.v = this.hmacSync(this.v);\n const sl = this.v.slice();\n out.push(sl);\n len += this.v.length;\n }\n return concatBytes(...out);\n }\n}\nfunction isWithinCurveOrder(num) {\n return _0n < num && num < CURVE.n;\n}\nfunction isValidFieldElement(num) {\n return _0n < num && num < CURVE.P;\n}\nfunction kmdToSig(kBytes, m, d, lowS = true) {\n const { n } = CURVE;\n const k = truncateHash(kBytes, true);\n if (!isWithinCurveOrder(k))\n return;\n const kinv = invert(k, n);\n const q = Point.BASE.multiply(k);\n const r = mod(q.x, n);\n if (r === _0n)\n return;\n const s = mod(kinv * mod(m + d * r, n), n);\n if (s === _0n)\n return;\n let sig = new Signature(r, s);\n let recovery = (q.x === sig.r ? 0 : 2) | Number(q.y & _1n);\n if (lowS && sig.hasHighS()) {\n sig = sig.normalizeS();\n recovery ^= 1;\n }\n return { sig, recovery };\n}\nfunction normalizePrivateKey(key) {\n let num;\n if (typeof key === 'bigint') {\n num = key;\n }\n else if (typeof key === 'number' && Number.isSafeInteger(key) && key > 0) {\n num = BigInt(key);\n }\n else if (typeof key === 'string') {\n if (key.length !== 2 * groupLen)\n throw new Error('Expected 32 bytes of private key');\n num = hexToNumber(key);\n }\n else if (isBytes(key)) {\n if (key.length !== groupLen)\n throw new Error('Expected 32 bytes of private key');\n num = bytesToNumber(key);\n }\n else {\n throw new TypeError('Expected valid private key');\n }\n if (!isWithinCurveOrder(num))\n throw new Error('Expected private key: 0 < key < n');\n return num;\n}\nfunction normalizePublicKey(publicKey) {\n if (publicKey instanceof Point) {\n publicKey.assertValidity();\n return publicKey;\n }\n else {\n return Point.fromHex(publicKey);\n }\n}\nfunction normalizeSignature(signature) {\n if (signature instanceof Signature) {\n signature.assertValidity();\n return signature;\n }\n try {\n return Signature.fromDER(signature);\n }\n catch (error) {\n return Signature.fromCompact(signature);\n }\n}\nexport function getPublicKey(privateKey, isCompressed = false) {\n return Point.fromPrivateKey(privateKey).toRawBytes(isCompressed);\n}\nexport function recoverPublicKey(msgHash, signature, recovery, isCompressed = false) {\n return Point.fromSignature(msgHash, signature, recovery).toRawBytes(isCompressed);\n}\nfunction isProbPub(item) {\n const arr = isBytes(item);\n const str = typeof item === 'string';\n const len = (arr || str) && item.length;\n if (arr)\n return len === compressedLen || len === uncompressedLen;\n if (str)\n return len === compressedLen * 2 || len === uncompressedLen * 2;\n if (item instanceof Point)\n return true;\n return false;\n}\nexport function getSharedSecret(privateA, publicB, isCompressed = false) {\n if (isProbPub(privateA))\n throw new TypeError('getSharedSecret: first arg must be private key');\n if (!isProbPub(publicB))\n throw new TypeError('getSharedSecret: second arg must be public key');\n const b = normalizePublicKey(publicB);\n b.assertValidity();\n return b.multiply(normalizePrivateKey(privateA)).toRawBytes(isCompressed);\n}\nfunction bits2int(bytes) {\n const slice = bytes.length > fieldLen ? bytes.slice(0, fieldLen) : bytes;\n return bytesToNumber(slice);\n}\nfunction bits2octets(bytes) {\n const z1 = bits2int(bytes);\n const z2 = mod(z1, CURVE.n);\n return int2octets(z2 < _0n ? z1 : z2);\n}\nfunction int2octets(num) {\n return numTo32b(num);\n}\nfunction initSigArgs(msgHash, privateKey, extraEntropy) {\n if (msgHash == null)\n throw new Error(`sign: expected valid message hash, not \"${msgHash}\"`);\n const h1 = ensureBytes(msgHash);\n const d = normalizePrivateKey(privateKey);\n const seedArgs = [int2octets(d), bits2octets(h1)];\n if (extraEntropy != null) {\n if (extraEntropy === true)\n extraEntropy = utils.randomBytes(fieldLen);\n const e = ensureBytes(extraEntropy);\n if (e.length !== fieldLen)\n throw new Error(`sign: Expected ${fieldLen} bytes of extra data`);\n seedArgs.push(e);\n }\n const seed = concatBytes(...seedArgs);\n const m = bits2int(h1);\n return { seed, m, d };\n}\nfunction finalizeSig(recSig, opts) {\n const { sig, recovery } = recSig;\n const { der, recovered } = Object.assign({ canonical: true, der: true }, opts);\n const hashed = der ? sig.toDERRawBytes() : sig.toCompactRawBytes();\n return recovered ? [hashed, recovery] : hashed;\n}\nasync function sign(msgHash, privKey, opts = {}) {\n const { seed, m, d } = initSigArgs(msgHash, privKey, opts.extraEntropy);\n const drbg = new HmacDrbg(hashLen, groupLen);\n await drbg.reseed(seed);\n let sig;\n while (!(sig = kmdToSig(await drbg.generate(), m, d, opts.canonical)))\n await drbg.reseed();\n return finalizeSig(sig, opts);\n}\nfunction signSync(msgHash, privKey, opts = {}) {\n const { seed, m, d } = initSigArgs(msgHash, privKey, opts.extraEntropy);\n const drbg = new HmacDrbg(hashLen, groupLen);\n drbg.reseedSync(seed);\n let sig;\n while (!(sig = kmdToSig(drbg.generateSync(), m, d, opts.canonical)))\n drbg.reseedSync();\n return finalizeSig(sig, opts);\n}\nexport { sign, signSync };\nconst vopts = { strict: true };\nexport function verify(signature, msgHash, publicKey, opts = vopts) {\n let sig;\n try {\n sig = normalizeSignature(signature);\n msgHash = ensureBytes(msgHash);\n }\n catch (error) {\n return false;\n }\n const { r, s } = sig;\n if (opts.strict && sig.hasHighS())\n return false;\n const h = truncateHash(msgHash);\n let P;\n try {\n P = normalizePublicKey(publicKey);\n }\n catch (error) {\n return false;\n }\n const { n } = CURVE;\n const sinv = invert(s, n);\n const u1 = mod(h * sinv, n);\n const u2 = mod(r * sinv, n);\n const R = Point.BASE.multiplyAndAddUnsafe(P, u1, u2);\n if (!R)\n return false;\n const v = mod(R.x, n);\n return v === r;\n}\nfunction schnorrChallengeFinalize(ch) {\n return mod(bytesToNumber(ch), CURVE.n);\n}\nclass SchnorrSignature {\n constructor(r, s) {\n this.r = r;\n this.s = s;\n this.assertValidity();\n }\n static fromHex(hex) {\n const bytes = ensureBytes(hex);\n if (bytes.length !== 64)\n throw new TypeError(`SchnorrSignature.fromHex: expected 64 bytes, not ${bytes.length}`);\n const r = bytesToNumber(bytes.subarray(0, 32));\n const s = bytesToNumber(bytes.subarray(32, 64));\n return new SchnorrSignature(r, s);\n }\n assertValidity() {\n const { r, s } = this;\n if (!isValidFieldElement(r) || !isWithinCurveOrder(s))\n throw new Error('Invalid signature');\n }\n toHex() {\n return numTo32bStr(this.r) + numTo32bStr(this.s);\n }\n toRawBytes() {\n return hexToBytes(this.toHex());\n }\n}\nfunction schnorrGetPublicKey(privateKey) {\n return Point.fromPrivateKey(privateKey).toRawX();\n}\nclass InternalSchnorrSignature {\n constructor(message, privateKey, auxRand = utils.randomBytes()) {\n if (message == null)\n throw new TypeError(`sign: Expected valid message, not \"${message}\"`);\n this.m = ensureBytes(message);\n const { x, scalar } = this.getScalar(normalizePrivateKey(privateKey));\n this.px = x;\n this.d = scalar;\n this.rand = ensureBytes(auxRand);\n if (this.rand.length !== 32)\n throw new TypeError('sign: Expected 32 bytes of aux randomness');\n }\n getScalar(priv) {\n const point = Point.fromPrivateKey(priv);\n const scalar = point.hasEvenY() ? priv : CURVE.n - priv;\n return { point, scalar, x: point.toRawX() };\n }\n initNonce(d, t0h) {\n return numTo32b(d ^ bytesToNumber(t0h));\n }\n finalizeNonce(k0h) {\n const k0 = mod(bytesToNumber(k0h), CURVE.n);\n if (k0 === _0n)\n throw new Error('sign: Creation of signature failed. k is zero');\n const { point: R, x: rx, scalar: k } = this.getScalar(k0);\n return { R, rx, k };\n }\n finalizeSig(R, k, e, d) {\n return new SchnorrSignature(R.x, mod(k + e * d, CURVE.n)).toRawBytes();\n }\n error() {\n throw new Error('sign: Invalid signature produced');\n }\n async calc() {\n const { m, d, px, rand } = this;\n const tag = utils.taggedHash;\n const t = this.initNonce(d, await tag(TAGS.aux, rand));\n const { R, rx, k } = this.finalizeNonce(await tag(TAGS.nonce, t, px, m));\n const e = schnorrChallengeFinalize(await tag(TAGS.challenge, rx, px, m));\n const sig = this.finalizeSig(R, k, e, d);\n if (!(await schnorrVerify(sig, m, px)))\n this.error();\n return sig;\n }\n calcSync() {\n const { m, d, px, rand } = this;\n const tag = utils.taggedHashSync;\n const t = this.initNonce(d, tag(TAGS.aux, rand));\n const { R, rx, k } = this.finalizeNonce(tag(TAGS.nonce, t, px, m));\n const e = schnorrChallengeFinalize(tag(TAGS.challenge, rx, px, m));\n const sig = this.finalizeSig(R, k, e, d);\n if (!schnorrVerifySync(sig, m, px))\n this.error();\n return sig;\n }\n}\nasync function schnorrSign(msg, privKey, auxRand) {\n return new InternalSchnorrSignature(msg, privKey, auxRand).calc();\n}\nfunction schnorrSignSync(msg, privKey, auxRand) {\n return new InternalSchnorrSignature(msg, privKey, auxRand).calcSync();\n}\nfunction initSchnorrVerify(signature, message, publicKey) {\n const raw = signature instanceof SchnorrSignature;\n const sig = raw ? signature : SchnorrSignature.fromHex(signature);\n if (raw)\n sig.assertValidity();\n return {\n ...sig,\n m: ensureBytes(message),\n P: normalizePublicKey(publicKey),\n };\n}\nfunction finalizeSchnorrVerify(r, P, s, e) {\n const R = Point.BASE.multiplyAndAddUnsafe(P, normalizePrivateKey(s), mod(-e, CURVE.n));\n if (!R || !R.hasEvenY() || R.x !== r)\n return false;\n return true;\n}\nasync function schnorrVerify(signature, message, publicKey) {\n try {\n const { r, s, m, P } = initSchnorrVerify(signature, message, publicKey);\n const e = schnorrChallengeFinalize(await utils.taggedHash(TAGS.challenge, numTo32b(r), P.toRawX(), m));\n return finalizeSchnorrVerify(r, P, s, e);\n }\n catch (error) {\n return false;\n }\n}\nfunction schnorrVerifySync(signature, message, publicKey) {\n try {\n const { r, s, m, P } = initSchnorrVerify(signature, message, publicKey);\n const e = schnorrChallengeFinalize(utils.taggedHashSync(TAGS.challenge, numTo32b(r), P.toRawX(), m));\n return finalizeSchnorrVerify(r, P, s, e);\n }\n catch (error) {\n if (error instanceof ShaError)\n throw error;\n return false;\n }\n}\nexport const schnorr = {\n Signature: SchnorrSignature,\n getPublicKey: schnorrGetPublicKey,\n sign: schnorrSign,\n verify: schnorrVerify,\n signSync: schnorrSignSync,\n verifySync: schnorrVerifySync,\n};\nPoint.BASE._setWindowSize(8);\nconst crypto = {\n node: nodeCrypto,\n web: typeof self === 'object' && 'crypto' in self ? self.crypto : undefined,\n};\nconst TAGS = {\n challenge: 'BIP0340/challenge',\n aux: 'BIP0340/aux',\n nonce: 'BIP0340/nonce',\n};\nconst TAGGED_HASH_PREFIXES = {};\nexport const utils = {\n bytesToHex,\n hexToBytes,\n concatBytes,\n mod,\n invert,\n isValidPrivateKey(privateKey) {\n try {\n normalizePrivateKey(privateKey);\n return true;\n }\n catch (error) {\n return false;\n }\n },\n _bigintTo32Bytes: numTo32b,\n _normalizePrivateKey: normalizePrivateKey,\n hashToPrivateKey: (hash) => {\n hash = ensureBytes(hash);\n const minLen = groupLen + 8;\n if (hash.length < minLen || hash.length > 1024) {\n throw new Error(`Expected valid bytes of private key as per FIPS 186`);\n }\n const num = mod(bytesToNumber(hash), CURVE.n - _1n) + _1n;\n return numTo32b(num);\n },\n randomBytes: (bytesLength = 32) => {\n if (crypto.web) {\n return crypto.web.getRandomValues(new Uint8Array(bytesLength));\n }\n else if (crypto.node) {\n const { randomBytes } = crypto.node;\n return Uint8Array.from(randomBytes(bytesLength));\n }\n else {\n throw new Error(\"The environment doesn't have randomBytes function\");\n }\n },\n randomPrivateKey: () => utils.hashToPrivateKey(utils.randomBytes(groupLen + 8)),\n precompute(windowSize = 8, point = Point.BASE) {\n const cached = point === Point.BASE ? point : new Point(point.x, point.y);\n cached._setWindowSize(windowSize);\n cached.multiply(_3n);\n return cached;\n },\n sha256: async (...messages) => {\n if (crypto.web) {\n const buffer = await crypto.web.subtle.digest('SHA-256', concatBytes(...messages));\n return new Uint8Array(buffer);\n }\n else if (crypto.node) {\n const { createHash } = crypto.node;\n const hash = createHash('sha256');\n messages.forEach((m) => hash.update(m));\n return Uint8Array.from(hash.digest());\n }\n else {\n throw new Error(\"The environment doesn't have sha256 function\");\n }\n },\n hmacSha256: async (key, ...messages) => {\n if (crypto.web) {\n const ckey = await crypto.web.subtle.importKey('raw', key, { name: 'HMAC', hash: { name: 'SHA-256' } }, false, ['sign']);\n const message = concatBytes(...messages);\n const buffer = await crypto.web.subtle.sign('HMAC', ckey, message);\n return new Uint8Array(buffer);\n }\n else if (crypto.node) {\n const { createHmac } = crypto.node;\n const hash = createHmac('sha256', key);\n messages.forEach((m) => hash.update(m));\n return Uint8Array.from(hash.digest());\n }\n else {\n throw new Error(\"The environment doesn't have hmac-sha256 function\");\n }\n },\n sha256Sync: undefined,\n hmacSha256Sync: undefined,\n taggedHash: async (tag, ...messages) => {\n let tagP = TAGGED_HASH_PREFIXES[tag];\n if (tagP === undefined) {\n const tagH = await utils.sha256(Uint8Array.from(tag, (c) => c.charCodeAt(0)));\n tagP = concatBytes(tagH, tagH);\n TAGGED_HASH_PREFIXES[tag] = tagP;\n }\n return utils.sha256(tagP, ...messages);\n },\n taggedHashSync: (tag, ...messages) => {\n if (typeof _sha256Sync !== 'function')\n throw new ShaError('sha256Sync is undefined, you need to set it');\n let tagP = TAGGED_HASH_PREFIXES[tag];\n if (tagP === undefined) {\n const tagH = _sha256Sync(Uint8Array.from(tag, (c) => c.charCodeAt(0)));\n tagP = concatBytes(tagH, tagH);\n TAGGED_HASH_PREFIXES[tag] = tagP;\n }\n return _sha256Sync(tagP, ...messages);\n },\n _JacobianPoint: JacobianPoint,\n};\nObject.defineProperties(utils, {\n sha256Sync: {\n configurable: false,\n get() {\n return _sha256Sync;\n },\n set(val) {\n if (!_sha256Sync)\n _sha256Sync = val;\n },\n },\n hmacSha256Sync: {\n configurable: false,\n get() {\n return _hmacSha256Sync;\n },\n set(val) {\n if (!_hmacSha256Sync)\n _hmacSha256Sync = val;\n },\n },\n});\n","/// \nimport { bytesToHex, hexToBytes, randomBytes } from \"@noble/hashes/utils\";\nimport { Point } from \"@noble/secp256k1\";\nimport { base64 } from \"@scure/base\";\nimport { logger } from \"applesauce-core\";\nimport { createDefer } from \"applesauce-core/promise\";\nimport { getEventHash, verifyEvent } from \"nostr-tools\";\nconst sleep = (ms) => new Promise((r) => setTimeout(r, ms));\nfunction xOnlyToXY(p) {\n return Point.fromHex(p).toHex().substring(2);\n}\nconst utf8Decoder = new TextDecoder(\"utf-8\");\nconst utf8Encoder = new TextEncoder();\n/** A signer that works with [nostr-signing-device](https://github.com/lnbits/nostr-signing-device) */\nexport class SerialPortSigner {\n log = logger.extend(\"SerialPortSigner\");\n writer = null;\n pubkey;\n get isConnected() {\n return !!this.writer;\n }\n verifyEvent = verifyEvent;\n nip04;\n constructor() {\n this.nip04 = {\n encrypt: this.nip04Encrypt.bind(this),\n decrypt: this.nip04Decrypt.bind(this),\n };\n }\n lastCommand = null;\n async callMethodOnDevice(method, params, opts = {}) {\n if (!SerialPortSigner.SUPPORTED)\n throw new Error(\"Serial devices are not supported\");\n if (!this.writer)\n await this.connectToDevice(opts);\n // only one command can be pending at any time\n // but each will only wait 6 seconds\n if (this.lastCommand)\n throw new Error(\"Previous command to device still pending!\");\n const command = createDefer();\n this.lastCommand = command;\n // send actual command\n this.sendCommand(method, params);\n setTimeout(() => {\n command.reject(new Error(\"Device timeout\"));\n if (this.lastCommand === command)\n this.lastCommand = null;\n }, 6000);\n return this.lastCommand;\n }\n async connectToDevice({ onConnect, onDisconnect, onError, onDone }) {\n let port = await window.navigator.serial.requestPort();\n let reader;\n const startSerialPortReading = async () => {\n // reading responses\n while (port && port.readable) {\n const textDecoder = new window.TextDecoderStream();\n port.readable.pipeTo(textDecoder.writable);\n reader = textDecoder.readable.getReader();\n const readStringUntil = this.readFromSerialPort(reader);\n try {\n while (true) {\n const { value, done } = await readStringUntil(\"\\n\");\n if (value) {\n const { method, data } = this.parseResponse(value);\n // if (method === \"/log\") deviceLog(data);\n if (method === \"/ping\")\n this.log(\"Pong\");\n if (SerialPortSigner.PUBLIC_METHODS.indexOf(method) === -1) {\n // ignore /ping, /log responses\n continue;\n }\n this.log(\"Received: \", method, data);\n if (this.lastCommand) {\n this.lastCommand.resolve(data);\n this.lastCommand = null;\n }\n }\n if (done) {\n this.lastCommand = null;\n this.writer = null;\n if (onDone)\n onDone();\n return;\n }\n }\n }\n catch (error) {\n if (error instanceof Error) {\n this.writer = null;\n if (onError)\n onError(error);\n if (this.lastCommand) {\n this.lastCommand.reject(error);\n this.lastCommand = null;\n }\n throw error;\n }\n }\n }\n };\n await port.open({ baudRate: 9600 });\n // this `sleep()` is a hack, I know!\n // but `port.onconnect` is never called. I don't know why!\n await sleep(1000);\n startSerialPortReading();\n const textEncoder = new window.TextEncoderStream();\n textEncoder.readable.pipeTo(port.writable);\n this.writer = textEncoder.writable.getWriter();\n // send ping first\n await this.sendCommand(SerialPortSigner.METHOD_PING);\n await this.sendCommand(SerialPortSigner.METHOD_PING, [window.location.host]);\n if (onConnect)\n onConnect();\n port.addEventListener(\"disconnect\", () => {\n this.log(\"Disconnected\");\n this.lastCommand = null;\n this.writer = null;\n if (onDisconnect)\n onDisconnect();\n });\n }\n async sendCommand(method, params = []) {\n if (!this.writer)\n return;\n this.log(\"Send command\", method, params);\n const message = [method].concat(params).join(\" \");\n await this.writer.write(message + \"\\n\");\n }\n readFromSerialPort(reader) {\n let partialChunk;\n let fulliness = [];\n const readStringUntil = async (separator = \"\\n\") => {\n if (fulliness.length)\n return { value: fulliness.shift().trim(), done: false };\n const chunks = [];\n if (partialChunk) {\n // leftovers from previous read\n chunks.push(partialChunk);\n partialChunk = undefined;\n }\n while (true) {\n const { value, done } = await reader.read();\n if (value) {\n const values = value.split(separator);\n // found one or more separators\n if (values.length > 1) {\n chunks.push(values.shift()); // first element\n partialChunk = values.pop(); // last element\n fulliness = values; // full lines\n return { value: chunks.join(\"\").trim(), done: false };\n }\n chunks.push(value);\n }\n if (done)\n return { value: chunks.join(\"\").trim(), done: true };\n }\n };\n return readStringUntil;\n }\n parseResponse(value) {\n const method = value.split(\" \")[0];\n const data = value.substring(method.length).trim();\n return { method, data };\n }\n // NIP-04\n async nip04Encrypt(pubkey, text) {\n const sharedSecretStr = await this.callMethodOnDevice(SerialPortSigner.METHOD_SHARED_SECRET, [xOnlyToXY(pubkey)]);\n const sharedSecret = hexToBytes(sharedSecretStr);\n let iv = Uint8Array.from(randomBytes(16));\n let plaintext = utf8Encoder.encode(text);\n // @ts-ignore\n let cryptoKey = await crypto.subtle.importKey(\"raw\", sharedSecret, { name: \"AES-CBC\" }, false, [\"encrypt\"]);\n let ciphertext = await crypto.subtle.encrypt({ name: \"AES-CBC\", iv }, cryptoKey, plaintext);\n let ctb64 = base64.encode(new Uint8Array(ciphertext));\n let ivb64 = base64.encode(new Uint8Array(iv.buffer));\n return `${ctb64}?iv=${ivb64}`;\n }\n async nip04Decrypt(pubkey, data) {\n let [ctb64, ivb64] = data.split(\"?iv=\");\n const sharedSecretStr = await this.callMethodOnDevice(SerialPortSigner.METHOD_SHARED_SECRET, [xOnlyToXY(pubkey)]);\n const sharedSecret = hexToBytes(sharedSecretStr);\n // @ts-ignore\n let cryptoKey = await crypto.subtle.importKey(\"raw\", sharedSecret, { name: \"AES-CBC\" }, false, [\"decrypt\"]);\n let ciphertext = base64.decode(ctb64);\n let iv = base64.decode(ivb64);\n // @ts-ignore\n let plaintext = await crypto.subtle.decrypt({ name: \"AES-CBC\", iv }, cryptoKey, ciphertext);\n let text = utf8Decoder.decode(plaintext);\n return text;\n }\n /** Returns the public key on the device */\n async getPublicKey() {\n const pubkey = await this.callMethodOnDevice(SerialPortSigner.METHOD_PUBLIC_KEY, []);\n this.pubkey = pubkey;\n return pubkey;\n }\n /** Sets the secret key used on the device */\n async restore(secretKey) {\n await this.callMethodOnDevice(SerialPortSigner.METHOD_RESTORE, [bytesToHex(secretKey)]);\n }\n /** Requires the device to sign an event */\n async signEvent(draft) {\n const pubkey = draft.pubkey || this.pubkey;\n if (!pubkey)\n throw new Error(\"Unknown signer pubkey\");\n const draftWithId = { ...draft, id: getEventHash({ ...draft, pubkey }) };\n const sig = await this.callMethodOnDevice(SerialPortSigner.METHOD_SIGN_MESSAGE, [draftWithId.id]);\n const event = { ...draftWithId, sig, pubkey };\n if (!this.verifyEvent(event))\n throw new Error(\"Invalid signature\");\n return event;\n }\n /** Pings to device to see if the connection is open */\n ping() {\n this.sendCommand(SerialPortSigner.METHOD_PING, [window.location.host]);\n }\n // static const\n static SUPPORTED = \"navigator\" in globalThis && !!navigator.serial;\n static METHOD_PING = \"/ping\";\n static METHOD_LOG = \"/log\";\n static METHOD_SIGN_MESSAGE = \"/sign-message\";\n static METHOD_SHARED_SECRET = \"/shared-secret\";\n static METHOD_PUBLIC_KEY = \"/public-key\";\n static METHOD_RESTORE = \"/restore\";\n static PUBLIC_METHODS = [\n SerialPortSigner.METHOD_PUBLIC_KEY,\n SerialPortSigner.METHOD_SIGN_MESSAGE,\n SerialPortSigner.METHOD_SHARED_SECRET,\n SerialPortSigner.METHOD_RESTORE,\n ];\n}\n","// Default Nostr relays for searching\n// Use startsWith to avoid minifier optimization issues\nconst wsProtocol = window.location.protocol.startsWith('https') ? 'wss:' : 'ws:';\nexport const DEFAULT_RELAYS = [\n // Use the local relay WebSocket endpoint\n // Automatically use ws:// for http:// and wss:// for https://\n `${wsProtocol}//${window.location.host}/`,\n];\n\n// Replaceable kinds for the recovery dropdown\n// Based on NIP-01: kinds 0, 3, and 10000-19999 are replaceable\n// kinds 30000-39999 are addressable (parameterized replaceable)\nexport const replaceableKinds = [\n // Basic replaceable kinds (0, 3)\n { value: 0, label: \"User Metadata (0)\" },\n { value: 3, label: \"Follows (3)\" },\n\n // Replaceable range 10000-19999\n { value: 10000, label: \"Mute list (10000)\" },\n { value: 10001, label: \"Pin list (10001)\" },\n { value: 10002, label: \"Relay List Metadata (10002)\" },\n { value: 10003, label: \"Bookmark list (10003)\" },\n { value: 10004, label: \"Communities list (10004)\" },\n { value: 10005, label: \"Public chats list (10005)\" },\n { value: 10006, label: \"Blocked relays list (10006)\" },\n { value: 10007, label: \"Search relays list (10007)\" },\n { value: 10009, label: \"User groups (10009)\" },\n { value: 10012, label: \"Favorite relays list (10012)\" },\n { value: 10013, label: \"Private event relay list (10013)\" },\n { value: 10015, label: \"Interests list (10015)\" },\n { value: 10019, label: \"Nutzap Mint Recommendation (10019)\" },\n { value: 10020, label: \"Media follows (10020)\" },\n { value: 10030, label: \"User emoji list (10030)\" },\n { value: 10050, label: \"Relay list to receive DMs (10050)\" },\n { value: 10051, label: \"KeyPackage Relays List (10051)\" },\n { value: 10063, label: \"User server list (10063)\" },\n { value: 10096, label: \"File storage server list (10096)\" },\n { value: 10166, label: \"Relay Monitor Announcement (10166)\" },\n { value: 10312, label: \"Room Presence (10312)\" },\n { value: 10377, label: \"Proxy Announcement (10377)\" },\n { value: 11111, label: \"Transport Method Announcement (11111)\" },\n { value: 13194, label: \"Wallet Info (13194)\" },\n { value: 17375, label: \"Cashu Wallet Event (17375)\" },\n\n // Addressable range 30000-39999 (parameterized replaceable)\n { value: 30000, label: \"Follow sets (30000)\" },\n { value: 30001, label: \"Generic lists (30001)\" },\n { value: 30002, label: \"Relay sets (30002)\" },\n { value: 30003, label: \"Bookmark sets (30003)\" },\n { value: 30004, label: \"Curation sets (30004)\" },\n { value: 30005, label: \"Video sets (30005)\" },\n { value: 30007, label: \"Kind mute sets (30007)\" },\n { value: 30008, label: \"Profile Badges (30008)\" },\n { value: 30009, label: \"Badge Definition (30009)\" },\n { value: 30015, label: \"Interest sets (30015)\" },\n { value: 30017, label: \"Create or update a stall (30017)\" },\n { value: 30018, label: \"Create or update a product (30018)\" },\n { value: 30019, label: \"Marketplace UI/UX (30019)\" },\n { value: 30020, label: \"Product sold as an auction (30020)\" },\n { value: 30023, label: \"Long-form Content (30023)\" },\n { value: 30024, label: \"Draft Long-form Content (30024)\" },\n { value: 30030, label: \"Emoji sets (30030)\" },\n { value: 30040, label: \"Curated Publication Index (30040)\" },\n { value: 30041, label: \"Curated Publication Content (30041)\" },\n { value: 30063, label: \"Release artifact sets (30063)\" },\n { value: 30078, label: \"Application-specific Data (30078)\" },\n { value: 30166, label: \"Relay Discovery (30166)\" },\n { value: 30267, label: \"App curation sets (30267)\" },\n { value: 30311, label: \"Live Event (30311)\" },\n { value: 30312, label: \"Interactive Room (30312)\" },\n { value: 30313, label: \"Conference Event (30313)\" },\n { value: 30315, label: \"User Statuses (30315)\" },\n { value: 30388, label: \"Slide Set (30388)\" },\n { value: 30402, label: \"Classified Listing (30402)\" },\n { value: 30403, label: \"Draft Classified Listing (30403)\" },\n { value: 30617, label: \"Repository announcements (30617)\" },\n { value: 30618, label: \"Repository state announcements (30618)\" },\n { value: 30818, label: \"Wiki article (30818)\" },\n { value: 30819, label: \"Redirects (30819)\" },\n { value: 31234, label: \"Draft Event (31234)\" },\n { value: 31388, label: \"Link Set (31388)\" },\n { value: 31890, label: \"Feed (31890)\" },\n { value: 31922, label: \"Date-Based Calendar Event (31922)\" },\n { value: 31923, label: \"Time-Based Calendar Event (31923)\" },\n { value: 31924, label: \"Calendar (31924)\" },\n { value: 31925, label: \"Calendar Event RSVP (31925)\" },\n { value: 31989, label: \"Handler recommendation (31989)\" },\n { value: 31990, label: \"Handler information (31990)\" },\n { value: 32267, label: \"Software Application (32267)\" },\n { value: 34550, label: \"Community Definition (34550)\" },\n { value: 37516, label: \"Geocache listing (37516)\" },\n { value: 38172, label: \"Cashu Mint Announcement (38172)\" },\n { value: 38173, label: \"Fedimint Announcement (38173)\" },\n { value: 38383, label: \"Peer-to-peer Order events (38383)\" },\n { value: 39089, label: \"Starter packs (39089)\" },\n { value: 39092, label: \"Media starter packs (39092)\" },\n { value: 39701, label: \"Web bookmarks (39701)\" },\n];\n\n// Kind name mapping based on NIP specification\n// Matches official Nostr event kinds from https://github.com/nostr-protocol/nips\nexport const kindNames = {\n 0: \"User Metadata\",\n 1: \"Short Text Note\",\n 2: \"Recommend Relay\",\n 3: \"Follows\",\n 4: \"Encrypted Direct Messages\",\n 5: \"Event Deletion Request\",\n 6: \"Repost\",\n 7: \"Reaction\",\n 8: \"Badge Award\",\n 9: \"Chat Message\",\n 10: \"Group Chat Threaded Reply\",\n 11: \"Thread\",\n 12: \"Group Thread Reply\",\n 13: \"Seal\",\n 14: \"Direct Message\",\n 15: \"File Message\",\n 16: \"Generic Repost\",\n 17: \"Reaction to a website\",\n 20: \"Picture\",\n 40: \"Channel Creation\",\n 41: \"Channel Metadata\",\n 42: \"Channel Message\",\n 43: \"Channel Hide Message\",\n 44: \"Channel Mute User\",\n 1021: \"Bid\",\n 1022: \"Bid Confirmation\",\n 1040: \"OpenTimestamps\",\n 1063: \"File Metadata\",\n 1311: \"Live Chat Message\",\n 1971: \"Problem Tracker\",\n 1984: \"Reporting\",\n 1985: \"Label\",\n 4550: \"Community Post Approval\",\n 5000: \"Job Request\",\n 5999: \"Job Request\",\n 6000: \"Job Result\",\n 6999: \"Job Result\",\n 7000: \"Job Feedback\",\n 9041: \"Zap Goal\",\n 9734: \"Zap Request\",\n 9735: \"Zap\",\n 9882: \"Highlights\",\n 10000: \"Mute list\",\n 10001: \"Pin list\",\n 10002: \"Relay List Metadata\",\n 10003: \"Bookmarks list\",\n 10004: \"Communities list\",\n 10005: \"Public Chats list\",\n 10006: \"Blocked Relays list\",\n 10007: \"Search Relays list\",\n 10015: \"Interests\",\n 10030: \"User Emoji list\",\n 10050: \"DM relays\",\n 10096: \"File Storage Server List\",\n 13194: \"Wallet Service Info\",\n 21000: \"Lightning pub RPC\",\n 22242: \"Client Authentication\",\n 23194: \"Wallet Request\",\n 23195: \"Wallet Response\",\n 23196: \"Wallet Notification\",\n 23197: \"Wallet Notification\",\n 24133: \"Nostr Connect\",\n 27235: \"HTTP Auth\",\n 30000: \"Follow sets\",\n 30001: \"Generic lists\",\n 30002: \"Relay sets\",\n 30003: \"Bookmark sets\",\n 30004: \"Curation sets\",\n 30008: \"Profile Badges\",\n 30009: \"Badge Definition\",\n 30015: \"Interest sets\",\n 30017: \"Stall Definition\",\n 30018: \"Product Definition\",\n 30019: \"Marketplace UI/UX\",\n 30020: \"Product sold as an auction\",\n 30023: \"Long-form Content\",\n 30024: \"Draft Long-form Content\",\n 30030: \"Emoji sets\",\n 30078: \"Application-specific Data\",\n 30311: \"Live Event\",\n 30315: \"User Statuses\",\n 30402: \"Classified Listing\",\n 30403: \"Draft Classified Listing\",\n 31922: \"Date-Based Calendar Event\",\n 31923: \"Time-Based Calendar Event\",\n 31924: \"Calendar\",\n 31925: \"Calendar Event RSVP\",\n 31989: \"Handler recommendation\",\n 31990: \"Handler information\",\n 34235: \"Video Event Horizontal\",\n 34236: \"Video Event Vertical\",\n 34550: \"Community Definition\",\n};\n\n// Cache configuration\nexport const CACHE_DURATION = 5 * 60 * 1000; // 5 minutes\n","import { SimplePool } from 'nostr-tools/pool';\nimport { EventStore } from 'applesauce-core';\nimport { PrivateKeySigner } from 'applesauce-signers';\nimport { DEFAULT_RELAYS } from \"./constants.js\";\n\n// Nostr client wrapper using nostr-tools\nclass NostrClient {\n constructor() {\n this.pool = new SimplePool();\n this.eventStore = new EventStore();\n this.isConnected = false;\n this.signer = null;\n this.relays = [...DEFAULT_RELAYS];\n }\n\n async connect() {\n console.log(\"Starting connection to\", this.relays.length, \"relays...\");\n \n try {\n // SimplePool doesn't require explicit connect\n this.isConnected = true;\n console.log(\"✓ Successfully initialized relay pool\");\n \n // Wait a bit for connections to stabilize\n await new Promise((resolve) => setTimeout(resolve, 1000));\n } catch (error) {\n console.error(\"✗ Connection failed:\", error);\n throw error;\n }\n }\n\n async connectToRelay(relayUrl) {\n console.log(`Adding relay: ${relayUrl}`);\n \n try {\n if (!this.relays.includes(relayUrl)) {\n this.relays.push(relayUrl);\n }\n console.log(`✓ Successfully added relay ${relayUrl}`);\n return true;\n } catch (error) {\n console.error(`✗ Failed to add relay ${relayUrl}:`, error);\n return false;\n }\n }\n\n subscribe(filters, callback) {\n console.log(\"Creating subscription with filters:\", filters);\n \n const sub = this.pool.subscribeMany(\n this.relays,\n filters,\n {\n onevent(event) {\n console.log(\"Event received:\", event);\n callback(event);\n },\n oneose() {\n console.log(\"EOSE received\");\n window.dispatchEvent(new CustomEvent('nostr-eose', {\n detail: { subscriptionId: sub.id }\n }));\n }\n }\n );\n\n return sub;\n }\n\n unsubscribe(subscription) {\n console.log(`Closing subscription`);\n if (subscription && subscription.close) {\n subscription.close();\n }\n }\n\n disconnect() {\n console.log(\"Disconnecting relay pool\");\n if (this.pool) {\n this.pool.close(this.relays);\n }\n this.isConnected = false;\n }\n\n // Publish an event\n async publish(event, specificRelays = null) {\n if (!this.isConnected) {\n console.warn(\"Not connected to any relays, attempting to connect first\");\n await this.connect();\n }\n \n try {\n const relaysToUse = specificRelays || this.relays;\n const promises = this.pool.publish(relaysToUse, event);\n await Promise.allSettled(promises);\n console.log(\"✓ Event published successfully\");\n // Store the published event in IndexedDB\n await putEvents([event]);\n console.log(\"Event stored in IndexedDB\");\n return { success: true, okCount: 1, errorCount: 0 };\n } catch (error) {\n console.error(\"✗ Failed to publish event:\", error);\n throw error;\n }\n }\n\n // Get pool for advanced usage\n getPool() {\n return this.pool;\n }\n\n // Get event store\n getEventStore() {\n return this.eventStore;\n }\n\n // Get signer\n getSigner() {\n return this.signer;\n }\n\n // Set signer\n setSigner(signer) {\n this.signer = signer;\n }\n}\n\n// Create a global client instance\nexport const nostrClient = new NostrClient();\n\n// Export the class for creating new instances\nexport { NostrClient };\n\n// Export signer classes\nexport { PrivateKeySigner };\n\n// Export NIP-07 helper\nexport class Nip07Signer {\n async getPublicKey() {\n if (window.nostr) {\n return await window.nostr.getPublicKey();\n }\n throw new Error('NIP-07 extension not found');\n }\n\n async signEvent(event) {\n if (window.nostr) {\n return await window.nostr.signEvent(event);\n }\n throw new Error('NIP-07 extension not found');\n }\n\n async nip04Encrypt(pubkey, plaintext) {\n if (window.nostr && window.nostr.nip04) {\n return await window.nostr.nip04.encrypt(pubkey, plaintext);\n }\n throw new Error('NIP-07 extension does not support NIP-04');\n }\n\n async nip04Decrypt(pubkey, ciphertext) {\n if (window.nostr && window.nostr.nip04) {\n return await window.nostr.nip04.decrypt(pubkey, ciphertext);\n }\n throw new Error('NIP-07 extension does not support NIP-04');\n }\n\n async nip44Encrypt(pubkey, plaintext) {\n if (window.nostr && window.nostr.nip44) {\n return await window.nostr.nip44.encrypt(pubkey, plaintext);\n }\n throw new Error('NIP-07 extension does not support NIP-44');\n }\n\n async nip44Decrypt(pubkey, ciphertext) {\n if (window.nostr && window.nostr.nip44) {\n return await window.nostr.nip44.decrypt(pubkey, ciphertext);\n }\n throw new Error('NIP-07 extension does not support NIP-44');\n }\n}\n\n// IndexedDB helpers for unified event storage\n// This provides a local cache that all components can access\nconst DB_NAME = \"nostrCache\";\nconst DB_VERSION = 2; // Incremented for new indexes\nconst STORE_EVENTS = \"events\";\n\nfunction openDB() {\n return new Promise((resolve, reject) => {\n try {\n const req = indexedDB.open(DB_NAME, DB_VERSION);\n req.onupgradeneeded = (event) => {\n const db = req.result;\n const oldVersion = event.oldVersion;\n \n // Create or update the events store\n let store;\n if (!db.objectStoreNames.contains(STORE_EVENTS)) {\n store = db.createObjectStore(STORE_EVENTS, { keyPath: \"id\" });\n } else {\n // Get existing store during upgrade\n store = req.transaction.objectStore(STORE_EVENTS);\n }\n \n // Create indexes if they don't exist\n if (!store.indexNames.contains(\"byKindAuthor\")) {\n store.createIndex(\"byKindAuthor\", [\"kind\", \"pubkey\"], {\n unique: false,\n });\n }\n if (!store.indexNames.contains(\"byKindAuthorCreated\")) {\n store.createIndex(\n \"byKindAuthorCreated\",\n [\"kind\", \"pubkey\", \"created_at\"],\n { unique: false },\n );\n }\n if (!store.indexNames.contains(\"byKind\")) {\n store.createIndex(\"byKind\", \"kind\", { unique: false });\n }\n if (!store.indexNames.contains(\"byAuthor\")) {\n store.createIndex(\"byAuthor\", \"pubkey\", { unique: false });\n }\n if (!store.indexNames.contains(\"byCreatedAt\")) {\n store.createIndex(\"byCreatedAt\", \"created_at\", { unique: false });\n }\n };\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => reject(req.error);\n } catch (e) {\n console.error(\"Failed to open IndexedDB\", e);\n reject(e);\n }\n });\n}\n\nasync function getLatestProfileEvent(pubkey) {\n try {\n const db = await openDB();\n return await new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_EVENTS, \"readonly\");\n const idx = tx.objectStore(STORE_EVENTS).index(\"byKindAuthorCreated\");\n const range = IDBKeyRange.bound(\n [0, pubkey, -Infinity],\n [0, pubkey, Infinity],\n );\n const req = idx.openCursor(range, \"prev\"); // newest first\n req.onsuccess = () => {\n const cursor = req.result;\n resolve(cursor ? cursor.value : null);\n };\n req.onerror = () => reject(req.error);\n });\n } catch (e) {\n console.warn(\"IDB getLatestProfileEvent failed\", e);\n return null;\n }\n}\n\nasync function putEvent(event) {\n try {\n const db = await openDB();\n await new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_EVENTS, \"readwrite\");\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n tx.objectStore(STORE_EVENTS).put(event);\n });\n } catch (e) {\n console.warn(\"IDB putEvent failed\", e);\n }\n}\n\n// Store multiple events in IndexedDB\nasync function putEvents(events) {\n if (!events || events.length === 0) return;\n \n try {\n const db = await openDB();\n await new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_EVENTS, \"readwrite\");\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n \n const store = tx.objectStore(STORE_EVENTS);\n for (const event of events) {\n store.put(event);\n }\n });\n console.log(`Stored ${events.length} events in IndexedDB`);\n } catch (e) {\n console.warn(\"IDB putEvents failed\", e);\n }\n}\n\n// Query events from IndexedDB by filters\nasync function queryEventsFromDB(filters) {\n try {\n const db = await openDB();\n const results = [];\n \n console.log(\"QueryEventsFromDB: Starting query with filters:\", filters);\n \n for (const filter of filters) {\n console.log(\"QueryEventsFromDB: Processing filter:\", filter);\n \n const events = await new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_EVENTS, \"readonly\");\n const store = tx.objectStore(STORE_EVENTS);\n const allEvents = [];\n \n // Determine which index to use based on filter\n let req;\n if (filter.kinds && filter.kinds.length > 0 && filter.authors && filter.authors.length > 0) {\n // Use byKindAuthor index for the most specific query\n const kind = filter.kinds[0];\n const author = filter.authors[0];\n console.log(`QueryEventsFromDB: Using byKindAuthorCreated index for kind=${kind}, author=${author.substring(0, 8)}...`);\n \n const idx = store.index(\"byKindAuthorCreated\");\n const range = IDBKeyRange.bound(\n [kind, author, -Infinity],\n [kind, author, Infinity]\n );\n req = idx.openCursor(range, \"prev\"); // newest first\n } else if (filter.kinds && filter.kinds.length > 0) {\n // Use byKind index\n console.log(`QueryEventsFromDB: Using byKind index for kind=${filter.kinds[0]}`);\n const idx = store.index(\"byKind\");\n req = idx.openCursor(IDBKeyRange.only(filter.kinds[0]));\n } else if (filter.authors && filter.authors.length > 0) {\n // Use byAuthor index\n console.log(`QueryEventsFromDB: Using byAuthor index for author=${filter.authors[0].substring(0, 8)}...`);\n const idx = store.index(\"byAuthor\");\n req = idx.openCursor(IDBKeyRange.only(filter.authors[0]));\n } else {\n // Scan all events\n console.log(\"QueryEventsFromDB: Scanning all events (no specific index)\");\n req = store.openCursor();\n }\n \n req.onsuccess = (event) => {\n const cursor = event.target.result;\n if (cursor) {\n const evt = cursor.value;\n \n // Apply additional filters\n let matches = true;\n \n // Filter by kinds\n if (filter.kinds && filter.kinds.length > 0 && !filter.kinds.includes(evt.kind)) {\n matches = false;\n }\n \n // Filter by authors\n if (filter.authors && filter.authors.length > 0 && !filter.authors.includes(evt.pubkey)) {\n matches = false;\n }\n \n // Filter by since\n if (filter.since && evt.created_at < filter.since) {\n matches = false;\n }\n \n // Filter by until\n if (filter.until && evt.created_at > filter.until) {\n matches = false;\n }\n \n // Filter by IDs\n if (filter.ids && filter.ids.length > 0 && !filter.ids.includes(evt.id)) {\n matches = false;\n }\n \n if (matches) {\n allEvents.push(evt);\n }\n \n // Apply limit\n if (filter.limit && allEvents.length >= filter.limit) {\n console.log(`QueryEventsFromDB: Reached limit of ${filter.limit}, found ${allEvents.length} matching events`);\n resolve(allEvents);\n return;\n }\n \n cursor.continue();\n } else {\n console.log(`QueryEventsFromDB: Cursor exhausted, found ${allEvents.length} matching events`);\n resolve(allEvents);\n }\n };\n \n req.onerror = () => {\n console.error(\"QueryEventsFromDB: Cursor error:\", req.error);\n reject(req.error);\n };\n });\n \n console.log(`QueryEventsFromDB: Found ${events.length} events for this filter`);\n results.push(...events);\n }\n \n // Sort by created_at (newest first) and apply global limit\n results.sort((a, b) => b.created_at - a.created_at);\n \n console.log(`QueryEventsFromDB: Returning ${results.length} total events`);\n return results;\n } catch (e) {\n console.error(\"QueryEventsFromDB failed:\", e);\n return [];\n }\n}\n\nfunction parseProfileFromEvent(event) {\n try {\n const profile = JSON.parse(event.content || \"{}\");\n return {\n name: profile.name || profile.display_name || \"\",\n picture: profile.picture || \"\",\n banner: profile.banner || \"\",\n about: profile.about || \"\",\n nip05: profile.nip05 || \"\",\n lud16: profile.lud16 || profile.lud06 || \"\",\n };\n } catch (e) {\n return {\n name: \"\",\n picture: \"\",\n banner: \"\",\n about: \"\",\n nip05: \"\",\n lud16: \"\",\n };\n }\n}\n\n// Fetch user profile metadata (kind 0)\nexport async function fetchUserProfile(pubkey) {\n console.log(`Starting profile fetch for pubkey: ${pubkey}`);\n\n // 1) Try cached profile first and resolve immediately if present\n try {\n const cachedEvent = await getLatestProfileEvent(pubkey);\n if (cachedEvent) {\n console.log(\"Using cached profile event\");\n const profile = parseProfileFromEvent(cachedEvent);\n return profile;\n }\n } catch (e) {\n console.warn(\"Failed to load cached profile\", e);\n }\n\n // 2) Fetch profile from relays\n try {\n const filters = [{\n kinds: [0],\n authors: [pubkey],\n limit: 1\n }];\n \n const events = await fetchEvents(filters, { timeout: 10000 });\n \n if (events.length > 0) {\n const profileEvent = events[0];\n console.log(\"Profile fetched:\", profileEvent);\n \n // Cache the event\n await putEvent(profileEvent);\n \n // Publish the profile event to the local relay\n try {\n console.log(\"Publishing profile event to local relay:\", profileEvent.id);\n await nostrClient.publish(profileEvent);\n console.log(\"Profile event successfully saved to local relay\");\n } catch (publishError) {\n console.warn(\"Failed to publish profile to local relay:\", publishError);\n // Don't fail the whole operation if publishing fails\n }\n \n // Parse profile data\n const profile = parseProfileFromEvent(profileEvent);\n \n // Notify listeners that an updated profile is available\n try {\n if (typeof window !== \"undefined\" && window.dispatchEvent) {\n window.dispatchEvent(\n new CustomEvent(\"profile-updated\", {\n detail: { pubkey, profile, event: profileEvent },\n }),\n );\n }\n } catch (e) {\n console.warn(\"Failed to dispatch profile-updated event\", e);\n }\n \n return profile;\n } else {\n // No profile found - create a default profile for new users\n console.log(\"No profile found for pubkey, creating default:\", pubkey);\n return await createDefaultProfile(pubkey);\n }\n } catch (error) {\n console.error(\"Failed to fetch profile:\", error);\n // Try to create default profile on error too\n try {\n return await createDefaultProfile(pubkey);\n } catch (e) {\n console.error(\"Failed to create default profile:\", e);\n return null;\n }\n }\n}\n\n/**\n * Create a default profile for new users\n * @param {string} pubkey - The user's public key (hex)\n * @returns {Promise} - The created profile\n */\nasync function createDefaultProfile(pubkey) {\n // Generate name from first 6 chars of pubkey\n const shortId = pubkey.slice(0, 6);\n const defaultName = `testuser${shortId}`;\n\n // Get the current origin for the logo URL\n const logoUrl = `${window.location.origin}/orly.png`;\n\n const profileContent = {\n name: defaultName,\n display_name: defaultName,\n picture: logoUrl,\n about: \"New ORLY user\"\n };\n\n const profile = {\n name: defaultName,\n displayName: defaultName,\n picture: logoUrl,\n about: \"New ORLY user\",\n pubkey: pubkey\n };\n\n // Try to publish the profile if we have a signer\n if (nostrClient.signer) {\n try {\n const event = {\n kind: 0,\n content: JSON.stringify(profileContent),\n tags: [],\n created_at: Math.floor(Date.now() / 1000)\n };\n\n // Sign and publish using the websocket-auth client\n const signedEvent = await nostrClient.signer.signEvent(event);\n await nostrClient.publish(signedEvent);\n console.log(\"Default profile published:\", signedEvent.id);\n } catch (e) {\n console.warn(\"Failed to publish default profile:\", e);\n // Still return the profile even if publishing fails\n }\n }\n\n return profile;\n}\n\n// Fetch events\nexport async function fetchEvents(filters, options = {}) {\n console.log(`Starting event fetch with filters:`, JSON.stringify(filters, null, 2));\n console.log(`Current relays:`, nostrClient.relays);\n\n // Ensure client is connected\n if (!nostrClient.isConnected || nostrClient.relays.length === 0) {\n console.warn(\"Client not connected, initializing...\");\n await initializeNostrClient();\n }\n\n const {\n timeout = 30000,\n useCache = true, // Option to query from cache first\n } = options;\n\n // Try to get cached events first if requested\n if (useCache) {\n try {\n const cachedEvents = await queryEventsFromDB(filters);\n if (cachedEvents.length > 0) {\n console.log(`Found ${cachedEvents.length} cached events in IndexedDB`);\n }\n } catch (e) {\n console.warn(\"Failed to query cached events\", e);\n }\n }\n\n return new Promise((resolve, reject) => {\n const events = [];\n const timeoutId = setTimeout(() => {\n console.log(`Timeout reached after ${timeout}ms, returning ${events.length} events`);\n sub.close();\n \n // Store all received events in IndexedDB before resolving\n if (events.length > 0) {\n putEvents(events).catch(e => console.warn(\"Failed to cache events\", e));\n }\n \n resolve(events);\n }, timeout);\n\n try {\n // Generate a subscription ID for logging\n const subId = Math.random().toString(36).substring(7);\n console.log(`📤 REQ [${subId}]:`, JSON.stringify([\"REQ\", subId, ...filters], null, 2));\n \n const sub = nostrClient.pool.subscribeMany(\n nostrClient.relays,\n filters,\n {\n onevent(event) {\n console.log(`📥 EVENT received for REQ [${subId}]:`, {\n id: event.id?.substring(0, 8) + '...',\n kind: event.kind,\n pubkey: event.pubkey?.substring(0, 8) + '...',\n created_at: event.created_at,\n content_preview: event.content?.substring(0, 50)\n });\n events.push(event);\n \n // Store event immediately in IndexedDB\n putEvent(event).catch(e => console.warn(\"Failed to cache event\", e));\n },\n oneose() {\n console.log(`✅ EOSE received for REQ [${subId}], got ${events.length} events`);\n clearTimeout(timeoutId);\n sub.close();\n \n // Store all events in IndexedDB before resolving\n if (events.length > 0) {\n putEvents(events).catch(e => console.warn(\"Failed to cache events\", e));\n }\n \n resolve(events);\n }\n }\n );\n } catch (error) {\n clearTimeout(timeoutId);\n console.error(\"Failed to fetch events:\", error);\n reject(error);\n }\n });\n}\n\n// Fetch all events with timestamp-based pagination (including delete events)\nexport async function fetchAllEvents(options = {}) {\n const {\n limit = 100,\n since = null,\n until = null,\n authors = null,\n kinds = null,\n ...rest\n } = options;\n\n const filters = [{ ...rest }];\n \n if (since) filters[0].since = since;\n if (until) filters[0].until = until;\n if (authors) filters[0].authors = authors;\n if (kinds) filters[0].kinds = kinds;\n if (limit) filters[0].limit = limit;\n \n const events = await fetchEvents(filters, { \n timeout: 30000 \n });\n \n return events;\n}\n\n// Fetch user's events with timestamp-based pagination\nexport async function fetchUserEvents(pubkey, options = {}) {\n const {\n limit = 100,\n since = null,\n until = null\n } = options;\n\n const filters = [{\n authors: [pubkey]\n }];\n \n if (since) filters[0].since = since;\n if (until) filters[0].until = until;\n if (limit) filters[0].limit = limit;\n \n const events = await fetchEvents(filters, { \n timeout: 30000 \n });\n \n return events;\n}\n\n// NIP-50 search function\nexport async function searchEvents(searchQuery, options = {}) {\n const {\n limit = 100,\n since = null,\n until = null,\n kinds = null\n } = options;\n\n const filters = [{\n search: searchQuery\n }];\n \n if (since) filters[0].since = since;\n if (until) filters[0].until = until;\n if (kinds) filters[0].kinds = kinds;\n if (limit) filters[0].limit = limit;\n \n const events = await fetchEvents(filters, { \n timeout: 30000 \n });\n \n return events;\n}\n\n// Fetch a specific event by ID\nexport async function fetchEventById(eventId, options = {}) {\n const {\n timeout = 10000,\n } = options;\n\n console.log(`Fetching event by ID: ${eventId}`);\n\n try {\n const filters = [{\n ids: [eventId]\n }];\n\n console.log('Fetching event with filters:', filters);\n\n const events = await fetchEvents(filters, { timeout });\n\n console.log(`Fetched ${events.length} events`);\n \n // Return the first event if found, null otherwise\n return events.length > 0 ? events[0] : null;\n } catch (error) {\n console.error(\"Failed to fetch event by ID:\", error);\n throw error;\n }\n}\n\n// Fetch delete events that target a specific event ID\nexport async function fetchDeleteEventsByTarget(eventId, options = {}) {\n const {\n timeout = 10000\n } = options;\n\n console.log(`Fetching delete events for target: ${eventId}`);\n\n try {\n const filters = [{\n kinds: [5], // Kind 5 is deletion\n '#e': [eventId] // e-tag referencing the target event\n }];\n\n console.log('Fetching delete events with filters:', filters);\n\n const events = await fetchEvents(filters, { timeout });\n\n console.log(`Fetched ${events.length} delete events`);\n \n return events;\n } catch (error) {\n console.error(\"Failed to fetch delete events:\", error);\n throw error;\n }\n}\n\n// Initialize client connection\nexport async function initializeNostrClient() {\n await nostrClient.connect();\n}\n\n// Query events from cache and relay combined\n// This is the main function components should use\nexport async function queryEvents(filters, options = {}) {\n const {\n timeout = 30000,\n cacheFirst = true, // Try cache first before hitting relay\n cacheOnly = false, // Only use cache, don't query relay\n } = options;\n \n let cachedEvents = [];\n \n // Try cache first\n if (cacheFirst || cacheOnly) {\n try {\n cachedEvents = await queryEventsFromDB(filters);\n console.log(`Found ${cachedEvents.length} events in cache`);\n \n if (cacheOnly || cachedEvents.length > 0) {\n return cachedEvents;\n }\n } catch (e) {\n console.warn(\"Failed to query cache\", e);\n }\n }\n \n // If cache didn't have results and we're not cache-only, query relay\n if (!cacheOnly) {\n const relayEvents = await fetchEvents(filters, { timeout, useCache: false });\n console.log(`Fetched ${relayEvents.length} events from relay`);\n return relayEvents;\n }\n \n return cachedEvents;\n}\n\n// Export cache query function for direct access\nexport { queryEventsFromDB };\n\n// Debug function to check database contents\nexport async function debugIndexedDB() {\n try {\n const db = await openDB();\n const tx = db.transaction(STORE_EVENTS, \"readonly\");\n const store = tx.objectStore(STORE_EVENTS);\n \n const allEvents = await new Promise((resolve, reject) => {\n const req = store.getAll();\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => reject(req.error);\n });\n \n const byKind = allEvents.reduce((acc, e) => {\n acc[e.kind] = (acc[e.kind] || 0) + 1;\n return acc;\n }, {});\n \n console.log(\"===== IndexedDB Contents =====\");\n console.log(`Total events: ${allEvents.length}`);\n console.log(\"Events by kind:\", byKind);\n console.log(\"Kind 0 events:\", allEvents.filter(e => e.kind === 0));\n console.log(\"All event IDs:\", allEvents.map(e => ({ id: e.id.substring(0, 8), kind: e.kind, pubkey: e.pubkey.substring(0, 8) })));\n console.log(\"==============================\");\n \n return {\n total: allEvents.length,\n byKind,\n events: allEvents\n };\n } catch (e) {\n console.error(\"Failed to debug IndexedDB:\", e);\n return null;\n }\n}\n","/*!\n * hash-wasm (https://www.npmjs.com/package/hash-wasm)\n * (c) Dani Biro\n * @license MIT\n */\n\nvar name$l = \"adler32\";\nvar data$l = \"AGFzbQEAAAABDANgAAF/YAAAYAF/AAMHBgABAgEAAgUEAQECAgYOAn8BQYCJBQt/AEGACAsHcAgGbWVtb3J5AgAOSGFzaF9HZXRCdWZmZXIAAAlIYXNoX0luaXQAAQtIYXNoX1VwZGF0ZQACCkhhc2hfRmluYWwAAw1IYXNoX0dldFN0YXRlAAQOSGFzaF9DYWxjdWxhdGUABQpTVEFURV9TSVpFAwEK6wkGBQBBgAkLCgBBAEEBNgKECAvjCAEHf0EAKAKECCIBQf//A3EhAiABQRB2IQMCQAJAIABBAUcNACACQQAtAIAJaiIBQY+AfGogASABQfD/A0sbIgEgA2oiBEEQdCIFQYCAPGogBSAEQfD/A0sbIAFyIQEMAQsCQAJAAkACQAJAIABBEEkNAEGACSEGIABBsCtJDQFBgAkhBgNAQQAhBQNAIAYgBWoiASgCACIEQf8BcSACaiICIANqIAIgBEEIdkH/AXFqIgJqIAIgBEEQdkH/AXFqIgJqIAIgBEEYdmoiAmogAiABQQRqKAIAIgRB/wFxaiICaiACIARBCHZB/wFxaiICaiACIARBEHZB/wFxaiICaiACIARBGHZqIgJqIAIgAUEIaigCACIEQf8BcWoiAmogAiAEQQh2Qf8BcWoiAmogAiAEQRB2Qf8BcWoiAmogAiAEQRh2aiIEaiAEIAFBDGooAgAiAUH/AXFqIgRqIAQgAUEIdkH/AXFqIgRqIAQgAUEQdkH/AXFqIgRqIAQgAUEYdmoiAmohAyAFQRBqIgVBsCtHDQALIANB8f8DcCEDIAJB8f8DcCECIAZBsCtqIQYgAEHQVGoiAEGvK0sNAAsgAEUNBCAAQQ9LDQEMAgsCQCAARQ0AAkACQCAAQQNxIgUNAEGACSEBIAAhBAwBCyAAQXxxIQRBACEBA0AgAiABQYAJai0AAGoiAiADaiEDIAUgAUEBaiIBRw0ACyAFQYAJaiEBCyAAQQRJDQADQCACIAEtAABqIgUgAS0AAWoiBiABLQACaiIAIAFBA2otAABqIgIgACAGIAUgA2pqamohAyABQQRqIQEgBEF8aiIEDQALCyACQY+AfGogAiACQfD/A0sbIANB8f8DcEEQdHIhAQwECwNAIAYoAgAiAUH/AXEgAmoiBCADaiAEIAFBCHZB/wFxaiIEaiAEIAFBEHZB/wFxaiIEaiAEIAFBGHZqIgRqIAQgBkEEaigCACIBQf8BcWoiBGogBCABQQh2Qf8BcWoiBGogBCABQRB2Qf8BcWoiBGogBCABQRh2aiIEaiAEIAZBCGooAgAiAUH/AXFqIgRqIAQgAUEIdkH/AXFqIgRqIAQgAUEQdkH/AXFqIgRqIAQgAUEYdmoiBGogBCAGQQxqKAIAIgFB/wFxaiIEaiAEIAFBCHZB/wFxaiIEaiAEIAFBEHZB/wFxaiIEaiAEIAFBGHZqIgJqIQMgBkEQaiEGIABBcGoiAEEPSw0ACyAARQ0BCyAAQX9qIQcCQCAAQQNxIgVFDQAgAEF8cSEAIAUhBCAGIQEDQCACIAEtAABqIgIgA2ohAyABQQFqIQEgBEF/aiIEDQALIAYgBWohBgsgB0EDSQ0AA0AgAiAGLQAAaiIBIAYtAAFqIgQgBi0AAmoiBSAGQQNqLQAAaiICIAUgBCABIANqampqIQMgBkEEaiEGIABBfGoiAA0ACwsgA0Hx/wNwIQMgAkHx/wNwIQILIAIgA0EQdHIhAQtBACABNgKECAsxAQF/QQBBACgChAgiAEEYdCAAQYD+A3FBCHRyIABBCHZBgP4DcSAAQRh2cnI2AoAJCwUAQYQICzsAQQBBATYChAggABACQQBBACgChAgiAEEYdCAAQYD+A3FBCHRyIABBCHZBgP4DcSAAQRh2cnI2AoAJCwsVAgBBgAgLBAQAAAAAQYQICwQBAAAA\";\nvar hash$l = \"02ddbd17\";\nvar wasmJson$l = {\n\tname: name$l,\n\tdata: data$l,\n\thash: hash$l\n};\n\n/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise, SuppressedError, Symbol, Iterator */\r\n\r\n\r\nfunction __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\ntypeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\r\n var e = new Error(message);\r\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\r\n};\n\nclass Mutex {\n constructor() {\n this.mutex = Promise.resolve();\n }\n lock() {\n let begin = () => { };\n this.mutex = this.mutex.then(() => new Promise(begin));\n return new Promise((res) => {\n begin = res;\n });\n }\n dispatch(fn) {\n return __awaiter(this, void 0, void 0, function* () {\n const unlock = yield this.lock();\n try {\n return yield Promise.resolve(fn());\n }\n finally {\n unlock();\n }\n });\n }\n}\n\nvar _a;\nfunction getGlobal() {\n if (typeof globalThis !== \"undefined\")\n return globalThis;\n if (typeof self !== \"undefined\")\n return self;\n if (typeof window !== \"undefined\")\n return window;\n return global;\n}\nconst globalObject = getGlobal();\nconst nodeBuffer = (_a = globalObject.Buffer) !== null && _a !== void 0 ? _a : null;\nconst textEncoder = globalObject.TextEncoder\n ? new globalObject.TextEncoder()\n : null;\nfunction intArrayToString(arr, len) {\n return String.fromCharCode(...arr.subarray(0, len));\n}\nfunction hexCharCodesToInt(a, b) {\n return ((((a & 0xf) + ((a >> 6) | ((a >> 3) & 0x8))) << 4) |\n ((b & 0xf) + ((b >> 6) | ((b >> 3) & 0x8))));\n}\nfunction writeHexToUInt8(buf, str) {\n const size = str.length >> 1;\n for (let i = 0; i < size; i++) {\n const index = i << 1;\n buf[i] = hexCharCodesToInt(str.charCodeAt(index), str.charCodeAt(index + 1));\n }\n}\nfunction hexStringEqualsUInt8(str, buf) {\n if (str.length !== buf.length * 2) {\n return false;\n }\n for (let i = 0; i < buf.length; i++) {\n const strIndex = i << 1;\n if (buf[i] !==\n hexCharCodesToInt(str.charCodeAt(strIndex), str.charCodeAt(strIndex + 1))) {\n return false;\n }\n }\n return true;\n}\nconst alpha = \"a\".charCodeAt(0) - 10;\nconst digit = \"0\".charCodeAt(0);\nfunction getDigestHex(tmpBuffer, input, hashLength) {\n let p = 0;\n for (let i = 0; i < hashLength; i++) {\n let nibble = input[i] >>> 4;\n tmpBuffer[p++] = nibble > 9 ? nibble + alpha : nibble + digit;\n nibble = input[i] & 0xf;\n tmpBuffer[p++] = nibble > 9 ? nibble + alpha : nibble + digit;\n }\n return String.fromCharCode.apply(null, tmpBuffer);\n}\nconst getUInt8Buffer = nodeBuffer !== null\n ? (data) => {\n if (typeof data === \"string\") {\n const buf = nodeBuffer.from(data, \"utf8\");\n return new Uint8Array(buf.buffer, buf.byteOffset, buf.length);\n }\n if (nodeBuffer.isBuffer(data)) {\n return new Uint8Array(data.buffer, data.byteOffset, data.length);\n }\n if (ArrayBuffer.isView(data)) {\n return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n }\n throw new Error(\"Invalid data type!\");\n }\n : (data) => {\n if (typeof data === \"string\") {\n return textEncoder.encode(data);\n }\n if (ArrayBuffer.isView(data)) {\n return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n }\n throw new Error(\"Invalid data type!\");\n };\nconst base64Chars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\nconst base64Lookup = new Uint8Array(256);\nfor (let i = 0; i < base64Chars.length; i++) {\n base64Lookup[base64Chars.charCodeAt(i)] = i;\n}\nfunction encodeBase64(data, pad = true) {\n const len = data.length;\n const extraBytes = len % 3;\n const parts = [];\n const len2 = len - extraBytes;\n for (let i = 0; i < len2; i += 3) {\n const tmp = ((data[i] << 16) & 0xff0000) +\n ((data[i + 1] << 8) & 0xff00) +\n (data[i + 2] & 0xff);\n const triplet = base64Chars.charAt((tmp >> 18) & 0x3f) +\n base64Chars.charAt((tmp >> 12) & 0x3f) +\n base64Chars.charAt((tmp >> 6) & 0x3f) +\n base64Chars.charAt(tmp & 0x3f);\n parts.push(triplet);\n }\n if (extraBytes === 1) {\n const tmp = data[len - 1];\n const a = base64Chars.charAt(tmp >> 2);\n const b = base64Chars.charAt((tmp << 4) & 0x3f);\n parts.push(`${a}${b}`);\n if (pad) {\n parts.push(\"==\");\n }\n }\n else if (extraBytes === 2) {\n const tmp = (data[len - 2] << 8) + data[len - 1];\n const a = base64Chars.charAt(tmp >> 10);\n const b = base64Chars.charAt((tmp >> 4) & 0x3f);\n const c = base64Chars.charAt((tmp << 2) & 0x3f);\n parts.push(`${a}${b}${c}`);\n if (pad) {\n parts.push(\"=\");\n }\n }\n return parts.join(\"\");\n}\nfunction getDecodeBase64Length(data) {\n let bufferLength = Math.floor(data.length * 0.75);\n const len = data.length;\n if (data[len - 1] === \"=\") {\n bufferLength -= 1;\n if (data[len - 2] === \"=\") {\n bufferLength -= 1;\n }\n }\n return bufferLength;\n}\nfunction decodeBase64(data) {\n const bufferLength = getDecodeBase64Length(data);\n const len = data.length;\n const bytes = new Uint8Array(bufferLength);\n let p = 0;\n for (let i = 0; i < len; i += 4) {\n const encoded1 = base64Lookup[data.charCodeAt(i)];\n const encoded2 = base64Lookup[data.charCodeAt(i + 1)];\n const encoded3 = base64Lookup[data.charCodeAt(i + 2)];\n const encoded4 = base64Lookup[data.charCodeAt(i + 3)];\n bytes[p] = (encoded1 << 2) | (encoded2 >> 4);\n p += 1;\n bytes[p] = ((encoded2 & 15) << 4) | (encoded3 >> 2);\n p += 1;\n bytes[p] = ((encoded3 & 3) << 6) | (encoded4 & 63);\n p += 1;\n }\n return bytes;\n}\n\nconst MAX_HEAP = 16 * 1024;\nconst WASM_FUNC_HASH_LENGTH = 4;\nconst wasmMutex = new Mutex();\nconst wasmModuleCache = new Map();\nfunction WASMInterface(binary, hashLength) {\n return __awaiter(this, void 0, void 0, function* () {\n let wasmInstance = null;\n let memoryView = null;\n let initialized = false;\n if (typeof WebAssembly === \"undefined\") {\n throw new Error(\"WebAssembly is not supported in this environment!\");\n }\n const writeMemory = (data, offset = 0) => {\n memoryView.set(data, offset);\n };\n const getMemory = () => memoryView;\n const getExports = () => wasmInstance.exports;\n const setMemorySize = (totalSize) => {\n wasmInstance.exports.Hash_SetMemorySize(totalSize);\n const arrayOffset = wasmInstance.exports.Hash_GetBuffer();\n const memoryBuffer = wasmInstance.exports.memory.buffer;\n memoryView = new Uint8Array(memoryBuffer, arrayOffset, totalSize);\n };\n const getStateSize = () => {\n const view = new DataView(wasmInstance.exports.memory.buffer);\n const stateSize = view.getUint32(wasmInstance.exports.STATE_SIZE, true);\n return stateSize;\n };\n const loadWASMPromise = wasmMutex.dispatch(() => __awaiter(this, void 0, void 0, function* () {\n if (!wasmModuleCache.has(binary.name)) {\n const asm = decodeBase64(binary.data);\n const promise = WebAssembly.compile(asm);\n wasmModuleCache.set(binary.name, promise);\n }\n const module = yield wasmModuleCache.get(binary.name);\n wasmInstance = yield WebAssembly.instantiate(module, {\n // env: {\n // emscripten_memcpy_big: (dest, src, num) => {\n // const memoryBuffer = wasmInstance.exports.memory.buffer;\n // const memView = new Uint8Array(memoryBuffer, 0);\n // memView.set(memView.subarray(src, src + num), dest);\n // },\n // print_memory: (offset, len) => {\n // const memoryBuffer = wasmInstance.exports.memory.buffer;\n // const memView = new Uint8Array(memoryBuffer, 0);\n // console.log('print_int32', memView.subarray(offset, offset + len));\n // },\n // },\n });\n // wasmInstance.exports._start();\n }));\n const setupInterface = () => __awaiter(this, void 0, void 0, function* () {\n if (!wasmInstance) {\n yield loadWASMPromise;\n }\n const arrayOffset = wasmInstance.exports.Hash_GetBuffer();\n const memoryBuffer = wasmInstance.exports.memory.buffer;\n memoryView = new Uint8Array(memoryBuffer, arrayOffset, MAX_HEAP);\n });\n const init = (bits = null) => {\n initialized = true;\n wasmInstance.exports.Hash_Init(bits);\n };\n const updateUInt8Array = (data) => {\n let read = 0;\n while (read < data.length) {\n const chunk = data.subarray(read, read + MAX_HEAP);\n read += chunk.length;\n memoryView.set(chunk);\n wasmInstance.exports.Hash_Update(chunk.length);\n }\n };\n const update = (data) => {\n if (!initialized) {\n throw new Error(\"update() called before init()\");\n }\n const Uint8Buffer = getUInt8Buffer(data);\n updateUInt8Array(Uint8Buffer);\n };\n const digestChars = new Uint8Array(hashLength * 2);\n const digest = (outputType, padding = null) => {\n if (!initialized) {\n throw new Error(\"digest() called before init()\");\n }\n initialized = false;\n wasmInstance.exports.Hash_Final(padding);\n if (outputType === \"binary\") {\n // the data is copied to allow GC of the original memory object\n return memoryView.slice(0, hashLength);\n }\n return getDigestHex(digestChars, memoryView, hashLength);\n };\n const save = () => {\n if (!initialized) {\n throw new Error(\"save() can only be called after init() and before digest()\");\n }\n const stateOffset = wasmInstance.exports.Hash_GetState();\n const stateLength = getStateSize();\n const memoryBuffer = wasmInstance.exports.memory.buffer;\n const internalState = new Uint8Array(memoryBuffer, stateOffset, stateLength);\n // prefix is 4 bytes from SHA1 hash of the WASM binary\n // it is used to detect incompatible internal states between different versions of hash-wasm\n const prefixedState = new Uint8Array(WASM_FUNC_HASH_LENGTH + stateLength);\n writeHexToUInt8(prefixedState, binary.hash);\n prefixedState.set(internalState, WASM_FUNC_HASH_LENGTH);\n return prefixedState;\n };\n const load = (state) => {\n if (!(state instanceof Uint8Array)) {\n throw new Error(\"load() expects an Uint8Array generated by save()\");\n }\n const stateOffset = wasmInstance.exports.Hash_GetState();\n const stateLength = getStateSize();\n const overallLength = WASM_FUNC_HASH_LENGTH + stateLength;\n const memoryBuffer = wasmInstance.exports.memory.buffer;\n if (state.length !== overallLength) {\n throw new Error(`Bad state length (expected ${overallLength} bytes, got ${state.length})`);\n }\n if (!hexStringEqualsUInt8(binary.hash, state.subarray(0, WASM_FUNC_HASH_LENGTH))) {\n throw new Error(\"This state was written by an incompatible hash implementation\");\n }\n const internalState = state.subarray(WASM_FUNC_HASH_LENGTH);\n new Uint8Array(memoryBuffer, stateOffset, stateLength).set(internalState);\n initialized = true;\n };\n const isDataShort = (data) => {\n if (typeof data === \"string\") {\n // worst case is 4 bytes / char\n return data.length < MAX_HEAP / 4;\n }\n return data.byteLength < MAX_HEAP;\n };\n let canSimplify = isDataShort;\n switch (binary.name) {\n case \"argon2\":\n case \"scrypt\":\n canSimplify = () => true;\n break;\n case \"blake2b\":\n case \"blake2s\":\n // if there is a key at blake2 then cannot simplify\n canSimplify = (data, initParam) => initParam <= 512 && isDataShort(data);\n break;\n case \"blake3\":\n // if there is a key at blake3 then cannot simplify\n canSimplify = (data, initParam) => initParam === 0 && isDataShort(data);\n break;\n case \"xxhash64\": // cannot simplify\n case \"xxhash3\":\n case \"xxhash128\":\n case \"crc64\":\n canSimplify = () => false;\n break;\n }\n // shorthand for (init + update + digest) for better performance\n const calculate = (data, initParam = null, digestParam = null) => {\n if (!canSimplify(data, initParam)) {\n init(initParam);\n update(data);\n return digest(\"hex\", digestParam);\n }\n const buffer = getUInt8Buffer(data);\n memoryView.set(buffer);\n wasmInstance.exports.Hash_Calculate(buffer.length, initParam, digestParam);\n return getDigestHex(digestChars, memoryView, hashLength);\n };\n yield setupInterface();\n return {\n getMemory,\n writeMemory,\n getExports,\n setMemorySize,\n init,\n update,\n digest,\n save,\n load,\n calculate,\n hashLength,\n };\n });\n}\n\nfunction lockedCreate(mutex, binary, hashLength) {\n return __awaiter(this, void 0, void 0, function* () {\n const unlock = yield mutex.lock();\n const wasm = yield WASMInterface(binary, hashLength);\n unlock();\n return wasm;\n });\n}\n\nconst mutex$l = new Mutex();\nlet wasmCache$l = null;\n/**\n * Calculates Adler-32 hash. The resulting 32-bit hash is stored in\n * network byte order (big-endian).\n *\n * @param data Input data (string, Buffer or TypedArray)\n * @returns Computed hash as a hexadecimal string\n */\nfunction adler32(data) {\n if (wasmCache$l === null) {\n return lockedCreate(mutex$l, wasmJson$l, 4).then((wasm) => {\n wasmCache$l = wasm;\n return wasmCache$l.calculate(data);\n });\n }\n try {\n const hash = wasmCache$l.calculate(data);\n return Promise.resolve(hash);\n }\n catch (err) {\n return Promise.reject(err);\n }\n}\n/**\n * Creates a new Adler-32 hash instance\n */\nfunction createAdler32() {\n return WASMInterface(wasmJson$l, 4).then((wasm) => {\n wasm.init();\n const obj = {\n init: () => {\n wasm.init();\n return obj;\n },\n update: (data) => {\n wasm.update(data);\n return obj;\n },\n // biome-ignore lint/suspicious/noExplicitAny: Conflict with IHasher type\n digest: (outputType) => wasm.digest(outputType),\n save: () => wasm.save(),\n load: (data) => {\n wasm.load(data);\n return obj;\n },\n blockSize: 4,\n digestSize: 4,\n };\n return obj;\n });\n}\n\nvar name$k = \"argon2\";\nvar data$k = \"AGFzbQEAAAABKQVgAX8Bf2AAAX9gEH9/f39/f39/f39/f39/f38AYAR/f39/AGACf38AAwYFAAECAwQFBgEBAoCAAgYIAX8BQZCoBAsHQQQGbWVtb3J5AgASSGFzaF9TZXRNZW1vcnlTaXplAAAOSGFzaF9HZXRCdWZmZXIAAQ5IYXNoX0NhbGN1bGF0ZQAECvEyBVgBAn9BACEBAkAgAEEAKAKICCICRg0AAkAgACACayIAQRB2IABBgIB8cSAASWoiAEAAQX9HDQBB/wHADwtBACEBQQBBACkDiAggAEEQdK18NwOICAsgAcALcAECfwJAQQAoAoAIIgANAEEAPwBBEHQiADYCgAhBACgCiAgiAUGAgCBGDQACQEGAgCAgAWsiAEEQdiAAQYCAfHEgAElqIgBAAEF/Rw0AQQAPC0EAQQApA4gIIABBEHStfDcDiAhBACgCgAghAAsgAAvcDgECfiAAIAQpAwAiECAAKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAMIBAgDCkDAIVCIIkiEDcDACAIIBAgCCkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgBCAQIAQpAwCFQiiJIhA3AwAgACAQIAApAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIAwgECAMKQMAhUIwiSIQNwMAIAggECAIKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAEIBAgBCkDAIVCAYk3AwAgASAFKQMAIhAgASkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDSAQIA0pAwCFQiCJIhA3AwAgCSAQIAkpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAUgECAFKQMAhUIoiSIQNwMAIAEgECABKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACANIBAgDSkDAIVCMIkiEDcDACAJIBAgCSkDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgBSAQIAUpAwCFQgGJNwMAIAIgBikDACIQIAIpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIA4gECAOKQMAhUIgiSIQNwMAIAogECAKKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAGIBAgBikDAIVCKIkiEDcDACACIBAgAikDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgDiAQIA4pAwCFQjCJIhA3AwAgCiAQIAopAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIAYgECAGKQMAhUIBiTcDACADIAcpAwAiECADKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAPIBAgDykDAIVCIIkiEDcDACALIBAgCykDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgByAQIAcpAwCFQiiJIhA3AwAgAyAQIAMpAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIA8gECAPKQMAhUIwiSIQNwMAIAsgECALKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAHIBAgBykDAIVCAYk3AwAgACAFKQMAIhAgACkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDyAQIA8pAwCFQiCJIhA3AwAgCiAQIAopAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAUgECAFKQMAhUIoiSIQNwMAIAAgECAAKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAPIBAgDykDAIVCMIkiEDcDACAKIBAgCikDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgBSAQIAUpAwCFQgGJNwMAIAEgBikDACIQIAEpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAwgECAMKQMAhUIgiSIQNwMAIAsgECALKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAGIBAgBikDAIVCKIkiEDcDACABIBAgASkDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgDCAQIAwpAwCFQjCJIhA3AwAgCyAQIAspAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIAYgECAGKQMAhUIBiTcDACACIAcpAwAiECACKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACANIBAgDSkDAIVCIIkiEDcDACAIIBAgCCkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgByAQIAcpAwCFQiiJIhA3AwAgAiAQIAIpAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIA0gECANKQMAhUIwiSIQNwMAIAggECAIKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAHIBAgBykDAIVCAYk3AwAgAyAEKQMAIhAgAykDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDiAQIA4pAwCFQiCJIhA3AwAgCSAQIAkpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAQgECAEKQMAhUIoiSIQNwMAIAMgECADKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAOIBAgDikDAIVCMIkiEDcDACAJIBAgCSkDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgBCAQIAQpAwCFQgGJNwMAC98aAQN/QQAhBEEAIAIpAwAgASkDAIU3A5AIQQAgAikDCCABKQMIhTcDmAhBACACKQMQIAEpAxCFNwOgCEEAIAIpAxggASkDGIU3A6gIQQAgAikDICABKQMghTcDsAhBACACKQMoIAEpAyiFNwO4CEEAIAIpAzAgASkDMIU3A8AIQQAgAikDOCABKQM4hTcDyAhBACACKQNAIAEpA0CFNwPQCEEAIAIpA0ggASkDSIU3A9gIQQAgAikDUCABKQNQhTcD4AhBACACKQNYIAEpA1iFNwPoCEEAIAIpA2AgASkDYIU3A/AIQQAgAikDaCABKQNohTcD+AhBACACKQNwIAEpA3CFNwOACUEAIAIpA3ggASkDeIU3A4gJQQAgAikDgAEgASkDgAGFNwOQCUEAIAIpA4gBIAEpA4gBhTcDmAlBACACKQOQASABKQOQAYU3A6AJQQAgAikDmAEgASkDmAGFNwOoCUEAIAIpA6ABIAEpA6ABhTcDsAlBACACKQOoASABKQOoAYU3A7gJQQAgAikDsAEgASkDsAGFNwPACUEAIAIpA7gBIAEpA7gBhTcDyAlBACACKQPAASABKQPAAYU3A9AJQQAgAikDyAEgASkD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\";\nvar hash$k = \"e4cdc523\";\nvar wasmJson$k = {\n\tname: name$k,\n\tdata: data$k,\n\thash: hash$k\n};\n\nvar name$j = \"blake2b\";\nvar data$j = \"AGFzbQEAAAABEQRgAAF/YAJ/fwBgAX8AYAAAAwoJAAECAwECAgABBQQBAQICBg4CfwFBsIsFC38AQYAICwdwCAZtZW1vcnkCAA5IYXNoX0dldEJ1ZmZlcgAACkhhc2hfRmluYWwAAwlIYXNoX0luaXQABQtIYXNoX1VwZGF0ZQAGDUhhc2hfR2V0U3RhdGUABw5IYXNoX0NhbGN1bGF0ZQAIClNUQVRFX1NJWkUDAQrTOAkFAEGACQvrAgIFfwF+AkAgAUEBSA0AAkACQAJAIAFBgAFBACgC4IoBIgJrIgNKDQAgASEEDAELQQBBADYC4IoBAkAgAkH/AEoNACACQeCJAWohBSAAIQRBACEGA0AgBSAELQAAOgAAIARBAWohBCAFQQFqIQUgAyAGQQFqIgZB/wFxSg0ACwtBAEEAKQPAiQEiB0KAAXw3A8CJAUEAQQApA8iJASAHQv9+Vq18NwPIiQFB4IkBEAIgACADaiEAAkAgASADayIEQYEBSA0AIAIgAWohBQNAQQBBACkDwIkBIgdCgAF8NwPAiQFBAEEAKQPIiQEgB0L/flatfDcDyIkBIAAQAiAAQYABaiEAIAVBgH9qIgVBgAJLDQALIAVBgH9qIQQMAQsgBEEATA0BC0EAIQUDQCAFQQAoAuCKAWpB4IkBaiAAIAVqLQAAOgAAIAQgBUEBaiIFQf8BcUoNAAsLQQBBACgC4IoBIARqNgLgigELC78uASR+QQBBACkD0IkBQQApA7CJASIBQQApA5CJAXwgACkDICICfCIDhULr+obav7X2wR+FQiCJIgRCq/DT9K/uvLc8fCIFIAGFQiiJIgYgA3wgACkDKCIBfCIHIASFQjCJIgggBXwiCSAGhUIBiSIKQQApA8iJAUEAKQOoiQEiBEEAKQOIiQF8IAApAxAiA3wiBYVCn9j52cKR2oKbf4VCIIkiC0K7zqqm2NDrs7t/fCIMIASFQiiJIg0gBXwgACkDGCIEfCIOfCAAKQNQIgV8Ig9BACkDwIkBQQApA6CJASIQQQApA4CJASIRfCAAKQMAIgZ8IhKFQtGFmu/6z5SH0QCFQiCJIhNCiJLznf/M+YTqAHwiFCAQhUIoiSIVIBJ8IAApAwgiEHwiFiAThUIwiSIXhUIgiSIYQQApA9iJAUEAKQO4iQEiE0EAKQOYiQF8IAApAzAiEnwiGYVC+cL4m5Gjs/DbAIVCIIkiGkLx7fT4paf9p6V/fCIbIBOFQiiJIhwgGXwgACkDOCITfCIZIBqFQjCJIhogG3wiG3wiHSAKhUIoiSIeIA98IAApA1giCnwiDyAYhUIwiSIYIB18Ih0gDiALhUIwiSIOIAx8Ih8gDYVCAYkiDCAWfCAAKQNAIgt8Ig0gGoVCIIkiFiAJfCIaIAyFQiiJIiAgDXwgACkDSCIJfCIhIBaFQjCJIhYgGyAchUIBiSIMIAd8IAApA2AiB3wiDSAOhUIgiSIOIBcgFHwiFHwiFyAMhUIoiSIbIA18IAApA2giDHwiHCAOhUIwiSIOIBd8IhcgG4VCAYkiGyAZIBQgFYVCAYkiFHwgACkDcCINfCIVIAiFQiCJIhkgH3wiHyAUhUIoiSIUIBV8IAApA3giCHwiFXwgDHwiIoVCIIkiI3wiJCAbhUIoiSIbICJ8IBJ8IiIgFyAYIBUgGYVCMIkiFSAffCIZIBSFQgGJIhQgIXwgDXwiH4VCIIkiGHwiFyAUhUIoiSIUIB98IAV8Ih8gGIVCMIkiGCAXfCIXIBSFQgGJIhR8IAF8IiEgFiAafCIWIBUgHSAehUIBiSIaIBx8IAl8IhyFQiCJIhV8Ih0gGoVCKIkiGiAcfCAIfCIcIBWFQjCJIhWFQiCJIh4gGSAOIBYgIIVCAYkiFiAPfCACfCIPhUIgiSIOfCIZIBaFQiiJIhYgD3wgC3wiDyAOhUIwiSIOIBl8Ihl8IiAgFIVCKIkiFCAhfCAEfCIhIB6FQjCJIh4gIHwiICAiICOFQjCJIiIgJHwiIyAbhUIBiSIbIBx8IAp8IhwgDoVCIIkiDiAXfCIXIBuFQiiJIhsgHHwgE3wiHCAOhUIwiSIOIBkgFoVCAYkiFiAffCAQfCIZICKFQiCJIh8gFSAdfCIVfCIdIBaFQiiJIhYgGXwgB3wiGSAfhUIwiSIfIB18Ih0gFoVCAYkiFiAVIBqFQgGJIhUgD3wgBnwiDyAYhUIgiSIYICN8IhogFYVCKIkiFSAPfCADfCIPfCAHfCIihUIgiSIjfCIkIBaFQiiJIhYgInwgBnwiIiAjhUIwiSIjICR8IiQgFoVCAYkiFiAOIBd8Ig4gDyAYhUIwiSIPICAgFIVCAYkiFCAZfCAKfCIXhUIgiSIYfCIZIBSFQiiJIhQgF3wgC3wiF3wgBXwiICAPIBp8Ig8gHyAOIBuFQgGJIg4gIXwgCHwiGoVCIIkiG3wiHyAOhUIoiSIOIBp8IAx8IhogG4VCMIkiG4VCIIkiISAdIB4gDyAVhUIBiSIPIBx8IAF8IhWFQiCJIhx8Ih0gD4VCKIkiDyAVfCADfCIVIByFQjCJIhwgHXwiHXwiHiAWhUIoiSIWICB8IA18IiAgIYVCMIkiISAefCIeIBogFyAYhUIwiSIXIBl8IhggFIVCAYkiFHwgCXwiGSAchUIgiSIaICR8IhwgFIVCKIkiFCAZfCACfCIZIBqFQjCJIhogHSAPhUIBiSIPICJ8IAR8Ih0gF4VCIIkiFyAbIB98Iht8Ih8gD4VCKIkiDyAdfCASfCIdIBeFQjCJIhcgH3wiHyAPhUIBiSIPIBsgDoVCAYkiDiAVfCATfCIVICOFQiCJIhsgGHwiGCAOhUIoiSIOIBV8IBB8IhV8IAx8IiKFQiCJIiN8IiQgD4VCKIkiDyAifCAHfCIiICOFQjCJIiMgJHwiJCAPhUIBiSIPIBogHHwiGiAVIBuFQjCJIhUgHiAWhUIBiSIWIB18IAR8IhuFQiCJIhx8Ih0gFoVCKIkiFiAbfCAQfCIbfCABfCIeIBUgGHwiFSAXIBogFIVCAYkiFCAgfCATfCIYhUIgiSIXfCIaIBSFQiiJIhQgGHwgCXwiGCAXhUIwiSIXhUIgiSIgIB8gISAVIA6FQgGJIg4gGXwgCnwiFYVCIIkiGXwiHyAOhUIoiSIOIBV8IA18IhUgGYVCMIkiGSAffCIffCIhIA+FQiiJIg8gHnwgBXwiHiAghUIwiSIgICF8IiEgGyAchUIwiSIbIB18IhwgFoVCAYkiFiAYfCADfCIYIBmFQiCJIhkgJHwiHSAWhUIoiSIWIBh8IBJ8IhggGYVCMIkiGSAfIA6FQgGJIg4gInwgAnwiHyAbhUIgiSIbIBcgGnwiF3wiGiAOhUIoiSIOIB98IAZ8Ih8gG4VCMIkiGyAafCIaIA6FQgGJIg4gFSAXIBSFQgGJIhR8IAh8IhUgI4VCIIkiFyAcfCIcIBSFQiiJIhQgFXwgC3wiFXwgBXwiIoVCIIkiI3wiJCAOhUIoiSIOICJ8IAh8IiIgGiAgIBUgF4VCMIkiFSAcfCIXIBSFQgGJIhQgGHwgCXwiGIVCIIkiHHwiGiAUhUIoiSIUIBh8IAZ8IhggHIVCMIkiHCAafCIaIBSFQgGJIhR8IAR8IiAgGSAdfCIZIBUgISAPhUIBiSIPIB98IAN8Ih2FQiCJIhV8Ih8gD4VCKIkiDyAdfCACfCIdIBWFQjCJIhWFQiCJIiEgFyAbIBkgFoVCAYkiFiAefCABfCIZhUIgiSIbfCIXIBaFQiiJIhYgGXwgE3wiGSAbhUIwiSIbIBd8Ihd8Ih4gFIVCKIkiFCAgfCAMfCIgICGFQjCJIiEgHnwiHiAiICOFQjCJIiIgJHwiIyAOhUIBiSIOIB18IBJ8Ih0gG4VCIIkiGyAafCIaIA6FQiiJIg4gHXwgC3wiHSAbhUIwiSIbIBcgFoVCAYkiFiAYfCANfCIXICKFQiCJIhggFSAffCIVfCIfIBaFQiiJIhYgF3wgEHwiFyAYhUIwiSIYIB98Ih8gFoVCAYkiFiAVIA+FQgGJIg8gGXwgCnwiFSAchUIgiSIZICN8IhwgD4VCKIkiDyAVfCAHfCIVfCASfCIihUIgiSIjfCIkIBaFQiiJIhYgInwgBXwiIiAjhUIwiSIjICR8IiQgFoVCAYkiFiAbIBp8IhogFSAZhUIwiSIVIB4gFIVCAYkiFCAXfCADfCIXhUIgiSIZfCIbIBSFQiiJIhQgF3wgB3wiF3wgAnwiHiAVIBx8IhUgGCAaIA6FQgGJIg4gIHwgC3wiGoVCIIkiGHwiHCAOhUIoiSIOIBp8IAR8IhogGIVCMIkiGIVCIIkiICAfICEgFSAPhUIBiSIPIB18IAZ8IhWFQiCJIh18Ih8gD4VCKIkiDyAVfCAKfCIVIB2FQjCJIh0gH3wiH3wiISAWhUIoiSIWIB58IAx8Ih4gIIVCMIkiICAhfCIhIBogFyAZhUIwiSIXIBt8IhkgFIVCAYkiFHwgEHwiGiAdhUIgiSIbICR8Ih0gFIVCKIkiFCAafCAJfCIaIBuFQjCJIhsgHyAPhUIBiSIPICJ8IBN8Ih8gF4VCIIkiFyAYIBx8Ihh8IhwgD4VCKIkiDyAffCABfCIfIBeFQjCJIhcgHHwiHCAPhUIBiSIPIBggDoVCAYkiDiAVfCAIfCIVICOFQiCJIhggGXwiGSAOhUIoiSIOIBV8IA18IhV8IA18IiKFQiCJIiN8IiQgD4VCKIkiDyAifCAMfCIiICOFQjCJIiMgJHwiJCAPhUIBiSIPIBsgHXwiGyAVIBiFQjCJIhUgISAWhUIBiSIWIB98IBB8IhiFQiCJIh18Ih8gFoVCKIkiFiAYfCAIfCIYfCASfCIhIBUgGXwiFSAXIBsgFIVCAYkiFCAefCAHfCIZhUIgiSIXfCIbIBSFQiiJIhQgGXwgAXwiGSAXhUIwiSIXhUIgiSIeIBwgICAVIA6FQgGJIg4gGnwgAnwiFYVCIIkiGnwiHCAOhUIoiSIOIBV8IAV8IhUgGoVCMIkiGiAcfCIcfCIgIA+FQiiJIg8gIXwgBHwiISAehUIwiSIeICB8IiAgGCAdhUIwiSIYIB98Ih0gFoVCAYkiFiAZfCAGfCIZIBqFQiCJIhogJHwiHyAWhUIoiSIWIBl8IBN8IhkgGoVCMIkiGiAcIA6FQgGJIg4gInwgCXwiHCAYhUIgiSIYIBcgG3wiF3wiGyAOhUIoiSIOIBx8IAN8IhwgGIVCMIkiGCAbfCIbIA6FQgGJIg4gFSAXIBSFQgGJIhR8IAt8IhUgI4VCIIkiFyAdfCIdIBSFQiiJIhQgFXwgCnwiFXwgBHwiIoVCIIkiI3wiJCAOhUIoiSIOICJ8IAl8IiIgGyAeIBUgF4VCMIkiFSAdfCIXIBSFQgGJIhQgGXwgDHwiGYVCIIkiHXwiGyAUhUIoiSIUIBl8IAp8IhkgHYVCMIkiHSAbfCIbIBSFQgGJIhR8IAN8Ih4gGiAffCIaIBUgICAPhUIBiSIPIBx8IAd8IhyFQiCJIhV8Ih8gD4VCKIkiDyAcfCAQfCIcIBWFQjCJIhWFQiCJIiAgFyAYIBogFoVCAYkiFiAhfCATfCIahUIgiSIYfCIXIBaFQiiJIhYgGnwgDXwiGiAYhUIwiSIYIBd8Ihd8IiEgFIVCKIkiFCAefCAFfCIeICCFQjCJIiAgIXwiISAiICOFQjCJIiIgJHwiIyAOhUIBiSIOIBx8IAt8IhwgGIVCIIkiGCAbfCIbIA6FQiiJIg4gHHwgEnwiHCAYhUIwiSIYIBcgFoVCAYkiFiAZfCABfCIXICKFQiCJIhkgFSAffCIVfCIfIBaFQiiJIhYgF3wgBnwiFyAZhUIwiSIZIB98Ih8gFoVCAYkiFiAVIA+FQgGJIg8gGnwgCHwiFSAdhUIgiSIaICN8Ih0gD4VCKIkiDyAVfCACfCIVfCANfCIihUIgiSIjfCIkIBaFQiiJIhYgInwgCXwiIiAjhUIwiSIjICR8IiQgFoVCAYkiFiAYIBt8IhggFSAahUIwiSIVICEgFIVCAYkiFCAXfCASfCIXhUIgiSIafCIbIBSFQiiJIhQgF3wgCHwiF3wgB3wiISAVIB18IhUgGSAYIA6FQgGJIg4gHnwgBnwiGIVCIIkiGXwiHSAOhUIoiSIOIBh8IAt8IhggGYVCMIkiGYVCIIkiHiAfICAgFSAPhUIBiSIPIBx8IAp8IhWFQiCJIhx8Ih8gD4VCKIkiDyAVfCAEfCIVIByFQjCJIhwgH3wiH3wiICAWhUIoiSIWICF8IAN8IiEgHoVCMIkiHiAgfCIgIBggFyAahUIwiSIXIBt8IhogFIVCAYkiFHwgBXwiGCAchUIgiSIbICR8IhwgFIVCKIkiFCAYfCABfCIYIBuFQjCJIhsgHyAPhUIBiSIPICJ8IAx8Ih8gF4VCIIkiFyAZIB18Ihl8Ih0gD4VCKIkiDyAffCATfCIfIBeFQjCJIhcgHXwiHSAPhUIBiSIPIBkgDoVCAYkiDiAVfCAQfCIVICOFQiCJIhkgGnwiGiAOhUIoiSIOIBV8IAJ8IhV8IBN8IiKFQiCJIiN8IiQgD4VCKIkiDyAifCASfCIiICOFQjCJIiMgJHwiJCAPhUIBiSIPIBsgHHwiGyAVIBmFQjCJIhUgICAWhUIBiSIWIB98IAt8IhmFQiCJIhx8Ih8gFoVCKIkiFiAZfCACfCIZfCAJfCIgIBUgGnwiFSAXIBsgFIVCAYkiFCAhfCAFfCIahUIgiSIXfCIbIBSFQiiJIhQgGnwgA3wiGiAXhUIwiSIXhUIgiSIhIB0gHiAVIA6FQgGJIg4gGHwgEHwiFYVCIIkiGHwiHSAOhUIoiSIOIBV8IAF8IhUgGIVCMIkiGCAdfCIdfCIeIA+FQiiJIg8gIHwgDXwiICAhhUIwiSIhIB58Ih4gGSAchUIwiSIZIB98IhwgFoVCAYkiFiAafCAIfCIaIBiFQiCJIhggJHwiHyAWhUIoiSIWIBp8IAp8IhogGIVCMIkiGCAdIA6FQgGJIg4gInwgBHwiHSAZhUIgiSIZIBcgG3wiF3wiGyAOhUIoiSIOIB18IAd8Ih0gGYVCMIkiGSAbfCIbIA6FQgGJIg4gFSAXIBSFQgGJIhR8IAx8IhUgI4VCIIkiFyAcfCIcIBSFQiiJIhQgFXwgBnwiFXwgEnwiIoVCIIkiI3wiJCAOhUIoiSIOICJ8IBN8IiIgGyAhIBUgF4VCMIkiFSAcfCIXIBSFQgGJIhQgGnwgBnwiGoVCIIkiHHwiGyAUhUIoiSIUIBp8IBB8IhogHIVCMIkiHCAbfCIbIBSFQgGJIhR8IA18IiEgGCAffCIYIBUgHiAPhUIBiSIPIB18IAJ8Ih2FQiCJIhV8Ih4gD4VCKIkiDyAdfCABfCIdIBWFQjCJIhWFQiCJIh8gFyAZIBggFoVCAYkiFiAgfCADfCIYhUIgiSIZfCIXIBaFQiiJIhYgGHwgBHwiGCAZhUIwiSIZIBd8Ihd8IiAgFIVCKIkiFCAhfCAIfCIhIB+FQjCJIh8gIHwiICAiICOFQjCJIiIgJHwiIyAOhUIBiSIOIB18IAd8Ih0gGYVCIIkiGSAbfCIbIA6FQiiJIg4gHXwgDHwiHSAZhUIwiSIZIBcgFoVCAYkiFiAafCALfCIXICKFQiCJIhogFSAefCIVfCIeIBaFQiiJIhYgF3wgCXwiFyAahUIwiSIaIB58Ih4gFoVCAYkiFiAVIA+FQgGJIg8gGHwgBXwiFSAchUIgiSIYICN8IhwgD4VCKIkiDyAVfCAKfCIVfCACfCIChUIgiSIifCIjIBaFQiiJIhYgAnwgC3wiAiAihUIwiSILICN8IiIgFoVCAYkiFiAZIBt8IhkgFSAYhUIwiSIVICAgFIVCAYkiFCAXfCANfCINhUIgiSIXfCIYIBSFQiiJIhQgDXwgBXwiBXwgEHwiECAVIBx8Ig0gGiAZIA6FQgGJIg4gIXwgDHwiDIVCIIkiFXwiGSAOhUIoiSIOIAx8IBJ8IhIgFYVCMIkiDIVCIIkiFSAeIB8gDSAPhUIBiSINIB18IAl8IgmFQiCJIg98IhogDYVCKIkiDSAJfCAIfCIJIA+FQjCJIgggGnwiD3wiGiAWhUIoiSIWIBB8IAd8IhAgEYUgDCAZfCIHIA6FQgGJIgwgCXwgCnwiCiALhUIgiSILIAUgF4VCMIkiBSAYfCIJfCIOIAyFQiiJIgwgCnwgE3wiEyALhUIwiSIKIA58IguFNwOAiQFBACADIAYgDyANhUIBiSINIAJ8fCICIAWFQiCJIgUgB3wiBiANhUIoiSIHIAJ8fCICQQApA4iJAYUgBCABIBIgCSAUhUIBiSIDfHwiASAIhUIgiSISICJ8IgkgA4VCKIkiAyABfHwiASAShUIwiSIEIAl8IhKFNwOIiQFBACATQQApA5CJAYUgECAVhUIwiSIQIBp8IhOFNwOQiQFBACABQQApA5iJAYUgAiAFhUIwiSICIAZ8IgGFNwOYiQFBACASIAOFQgGJQQApA6CJAYUgAoU3A6CJAUEAIBMgFoVCAYlBACkDqIkBhSAKhTcDqIkBQQAgASAHhUIBiUEAKQOwiQGFIASFNwOwiQFBACALIAyFQgGJQQApA7iJAYUgEIU3A7iJAQvdAgUBfwF+AX8BfgJ/IwBBwABrIgAkAAJAQQApA9CJAUIAUg0AQQBBACkDwIkBIgFBACgC4IoBIgKsfCIDNwPAiQFBAEEAKQPIiQEgAyABVK18NwPIiQECQEEALQDoigFFDQBBAEJ/NwPYiQELQQBCfzcD0IkBAkAgAkH/AEoNAEEAIQQDQCACIARqQeCJAWpBADoAACAEQQFqIgRBgAFBACgC4IoBIgJrSA0ACwtB4IkBEAIgAEEAKQOAiQE3AwAgAEEAKQOIiQE3AwggAEEAKQOQiQE3AxAgAEEAKQOYiQE3AxggAEEAKQOgiQE3AyAgAEEAKQOoiQE3AyggAEEAKQOwiQE3AzAgAEEAKQO4iQE3AzhBACgC5IoBIgVBAUgNAEEAIQRBACECA0AgBEGACWogACAEai0AADoAACAEQQFqIQQgBSACQQFqIgJB/wFxSg0ACwsgAEHAAGokAAv9AwMBfwF+AX8jAEGAAWsiAiQAQQBBgQI7AfKKAUEAIAE6APGKAUEAIAA6APCKAUGQfiEAA0AgAEGAiwFqQgA3AAAgAEH4igFqQgA3AAAgAEHwigFqQgA3AAAgAEEYaiIADQALQQAhAEEAQQApA/CKASIDQoiS853/zPmE6gCFNwOAiQFBAEEAKQP4igFCu86qptjQ67O7f4U3A4iJAUEAQQApA4CLAUKr8NP0r+68tzyFNwOQiQFBAEEAKQOIiwFC8e30+KWn/aelf4U3A5iJAUEAQQApA5CLAULRhZrv+s+Uh9EAhTcDoIkBQQBBACkDmIsBQp/Y+dnCkdqCm3+FNwOoiQFBAEEAKQOgiwFC6/qG2r+19sEfhTcDsIkBQQBBACkDqIsBQvnC+JuRo7Pw2wCFNwO4iQFBACADp0H/AXE2AuSKAQJAIAFBAUgNACACQgA3A3ggAkIANwNwIAJCADcDaCACQgA3A2AgAkIANwNYIAJCADcDUCACQgA3A0ggAkIANwNAIAJCADcDOCACQgA3AzAgAkIANwMoIAJCADcDICACQgA3AxggAkIANwMQIAJCADcDCCACQgA3AwBBACEEA0AgAiAAaiAAQYAJai0AADoAACAAQQFqIQAgBEEBaiIEQf8BcSABSA0ACyACQYABEAELIAJBgAFqJAALEgAgAEEDdkH/P3EgAEEQdhAECwkAQYAJIAAQAQsGAEGAiQELGwAgAUEDdkH/P3EgAUEQdhAEQYAJIAAQARADCwsLAQBBgAgLBPAAAAA=\";\nvar hash$j = \"c6f286e6\";\nvar wasmJson$j = {\n\tname: name$j,\n\tdata: data$j,\n\thash: hash$j\n};\n\nconst mutex$k = new Mutex();\nlet wasmCache$k = null;\nfunction validateBits$4(bits) {\n if (!Number.isInteger(bits) || bits < 8 || bits > 512 || bits % 8 !== 0) {\n return new Error(\"Invalid variant! Valid values: 8, 16, ..., 512\");\n }\n return null;\n}\nfunction getInitParam$1(outputBits, keyBits) {\n return outputBits | (keyBits << 16);\n}\n/**\n * Calculates BLAKE2b hash\n * @param data Input data (string, Buffer or TypedArray)\n * @param bits Number of output bits, which has to be a number\n * divisible by 8, between 8 and 512. Defaults to 512.\n * @param key Optional key (string, Buffer or TypedArray). Maximum length is 64 bytes.\n * @returns Computed hash as a hexadecimal string\n */\nfunction blake2b(data, bits = 512, key = null) {\n if (validateBits$4(bits)) {\n return Promise.reject(validateBits$4(bits));\n }\n let keyBuffer = null;\n let initParam = bits;\n if (key !== null) {\n keyBuffer = getUInt8Buffer(key);\n if (keyBuffer.length > 64) {\n return Promise.reject(new Error(\"Max key length is 64 bytes\"));\n }\n initParam = getInitParam$1(bits, keyBuffer.length);\n }\n const hashLength = bits / 8;\n if (wasmCache$k === null || wasmCache$k.hashLength !== hashLength) {\n return lockedCreate(mutex$k, wasmJson$j, hashLength).then((wasm) => {\n wasmCache$k = wasm;\n if (initParam > 512) {\n wasmCache$k.writeMemory(keyBuffer);\n }\n return wasmCache$k.calculate(data, initParam);\n });\n }\n try {\n if (initParam > 512) {\n wasmCache$k.writeMemory(keyBuffer);\n }\n const hash = wasmCache$k.calculate(data, initParam);\n return Promise.resolve(hash);\n }\n catch (err) {\n return Promise.reject(err);\n }\n}\n/**\n * Creates a new BLAKE2b hash instance\n * @param bits Number of output bits, which has to be a number\n * divisible by 8, between 8 and 512. Defaults to 512.\n * @param key Optional key (string, Buffer or TypedArray). Maximum length is 64 bytes.\n */\nfunction createBLAKE2b(bits = 512, key = null) {\n if (validateBits$4(bits)) {\n return Promise.reject(validateBits$4(bits));\n }\n let keyBuffer = null;\n let initParam = bits;\n if (key !== null) {\n keyBuffer = getUInt8Buffer(key);\n if (keyBuffer.length > 64) {\n return Promise.reject(new Error(\"Max key length is 64 bytes\"));\n }\n initParam = getInitParam$1(bits, keyBuffer.length);\n }\n const outputSize = bits / 8;\n return WASMInterface(wasmJson$j, outputSize).then((wasm) => {\n if (initParam > 512) {\n wasm.writeMemory(keyBuffer);\n }\n wasm.init(initParam);\n const obj = {\n init: initParam > 512\n ? () => {\n wasm.writeMemory(keyBuffer);\n wasm.init(initParam);\n return obj;\n }\n : () => {\n wasm.init(initParam);\n return obj;\n },\n update: (data) => {\n wasm.update(data);\n return obj;\n },\n // biome-ignore lint/suspicious/noExplicitAny: Conflict with IHasher type\n digest: (outputType) => wasm.digest(outputType),\n save: () => wasm.save(),\n load: (data) => {\n wasm.load(data);\n return obj;\n },\n blockSize: 128,\n digestSize: outputSize,\n };\n return obj;\n });\n}\n\nfunction encodeResult(salt, options, res) {\n const parameters = [\n `m=${options.memorySize}`,\n `t=${options.iterations}`,\n `p=${options.parallelism}`,\n ].join(\",\");\n return `$argon2${options.hashType}$v=19$${parameters}$${encodeBase64(salt, false)}$${encodeBase64(res, false)}`;\n}\nconst uint32View = new DataView(new ArrayBuffer(4));\nfunction int32LE(x) {\n uint32View.setInt32(0, x, true);\n return new Uint8Array(uint32View.buffer);\n}\nfunction hashFunc(blake512, buf, len) {\n return __awaiter(this, void 0, void 0, function* () {\n if (len <= 64) {\n const blake = yield createBLAKE2b(len * 8);\n blake.update(int32LE(len));\n blake.update(buf);\n return blake.digest(\"binary\");\n }\n const r = Math.ceil(len / 32) - 2;\n const ret = new Uint8Array(len);\n blake512.init();\n blake512.update(int32LE(len));\n blake512.update(buf);\n let vp = blake512.digest(\"binary\");\n ret.set(vp.subarray(0, 32), 0);\n for (let i = 1; i < r; i++) {\n blake512.init();\n blake512.update(vp);\n vp = blake512.digest(\"binary\");\n ret.set(vp.subarray(0, 32), i * 32);\n }\n const partialBytesNeeded = len - 32 * r;\n let blakeSmall;\n if (partialBytesNeeded === 64) {\n blakeSmall = blake512;\n blakeSmall.init();\n }\n else {\n blakeSmall = yield createBLAKE2b(partialBytesNeeded * 8);\n }\n blakeSmall.update(vp);\n vp = blakeSmall.digest(\"binary\");\n ret.set(vp.subarray(0, partialBytesNeeded), r * 32);\n return ret;\n });\n}\nfunction getHashType(type) {\n switch (type) {\n case \"d\":\n return 0;\n case \"i\":\n return 1;\n default:\n return 2;\n }\n}\nfunction argon2Internal(options) {\n return __awaiter(this, void 0, void 0, function* () {\n var _a;\n const { parallelism, iterations, hashLength } = options;\n const password = getUInt8Buffer(options.password);\n const salt = getUInt8Buffer(options.salt);\n const version = 0x13;\n const hashType = getHashType(options.hashType);\n const { memorySize } = options; // in KB\n const secret = getUInt8Buffer((_a = options.secret) !== null && _a !== void 0 ? _a : \"\");\n const [argon2Interface, blake512] = yield Promise.all([\n WASMInterface(wasmJson$k, 1024),\n createBLAKE2b(512),\n ]);\n // last block is for storing the init vector\n argon2Interface.setMemorySize(memorySize * 1024 + 1024);\n const initVector = new Uint8Array(24);\n const initVectorView = new DataView(initVector.buffer);\n initVectorView.setInt32(0, parallelism, true);\n initVectorView.setInt32(4, hashLength, true);\n initVectorView.setInt32(8, memorySize, true);\n initVectorView.setInt32(12, iterations, true);\n initVectorView.setInt32(16, version, true);\n initVectorView.setInt32(20, hashType, true);\n argon2Interface.writeMemory(initVector, memorySize * 1024);\n blake512.init();\n blake512.update(initVector);\n blake512.update(int32LE(password.length));\n blake512.update(password);\n blake512.update(int32LE(salt.length));\n blake512.update(salt);\n blake512.update(int32LE(secret.length));\n blake512.update(secret);\n blake512.update(int32LE(0)); // associatedData length + associatedData\n const segments = Math.floor(memorySize / (parallelism * 4)); // length of each lane\n const lanes = segments * 4;\n const param = new Uint8Array(72);\n const H0 = blake512.digest(\"binary\");\n param.set(H0);\n for (let lane = 0; lane < parallelism; lane++) {\n param.set(int32LE(0), 64);\n param.set(int32LE(lane), 68);\n let position = lane * lanes;\n let chunk = yield hashFunc(blake512, param, 1024);\n argon2Interface.writeMemory(chunk, position * 1024);\n position += 1;\n param.set(int32LE(1), 64);\n chunk = yield hashFunc(blake512, param, 1024);\n argon2Interface.writeMemory(chunk, position * 1024);\n }\n const C = new Uint8Array(1024);\n writeHexToUInt8(C, argon2Interface.calculate(new Uint8Array([]), memorySize));\n const res = yield hashFunc(blake512, C, hashLength);\n if (options.outputType === \"hex\") {\n const digestChars = new Uint8Array(hashLength * 2);\n return getDigestHex(digestChars, res, hashLength);\n }\n if (options.outputType === \"encoded\") {\n return encodeResult(salt, options, res);\n }\n // return binary format\n return res;\n });\n}\nconst validateOptions$3 = (options) => {\n var _a;\n if (!options || typeof options !== \"object\") {\n throw new Error(\"Invalid options parameter. It requires an object.\");\n }\n if (!options.password) {\n throw new Error(\"Password must be specified\");\n }\n options.password = getUInt8Buffer(options.password);\n if (options.password.length < 1) {\n throw new Error(\"Password must be specified\");\n }\n if (!options.salt) {\n throw new Error(\"Salt must be specified\");\n }\n options.salt = getUInt8Buffer(options.salt);\n if (options.salt.length < 8) {\n throw new Error(\"Salt should be at least 8 bytes long\");\n }\n options.secret = getUInt8Buffer((_a = options.secret) !== null && _a !== void 0 ? _a : \"\");\n if (!Number.isInteger(options.iterations) || options.iterations < 1) {\n throw new Error(\"Iterations should be a positive number\");\n }\n if (!Number.isInteger(options.parallelism) || options.parallelism < 1) {\n throw new Error(\"Parallelism should be a positive number\");\n }\n if (!Number.isInteger(options.hashLength) || options.hashLength < 4) {\n throw new Error(\"Hash length should be at least 4 bytes.\");\n }\n if (!Number.isInteger(options.memorySize)) {\n throw new Error(\"Memory size should be specified.\");\n }\n if (options.memorySize < 8 * options.parallelism) {\n throw new Error(\"Memory size should be at least 8 * parallelism.\");\n }\n if (options.outputType === undefined) {\n options.outputType = \"hex\";\n }\n if (![\"hex\", \"binary\", \"encoded\"].includes(options.outputType)) {\n throw new Error(`Insupported output type ${options.outputType}. Valid values: ['hex', 'binary', 'encoded']`);\n }\n};\n/**\n * Calculates hash using the argon2i password-hashing function\n * @returns Computed hash\n */\nfunction argon2i(options) {\n return __awaiter(this, void 0, void 0, function* () {\n validateOptions$3(options);\n return argon2Internal(Object.assign(Object.assign({}, options), { hashType: \"i\" }));\n });\n}\n/**\n * Calculates hash using the argon2id password-hashing function\n * @returns Computed hash\n */\nfunction argon2id(options) {\n return __awaiter(this, void 0, void 0, function* () {\n validateOptions$3(options);\n return argon2Internal(Object.assign(Object.assign({}, options), { hashType: \"id\" }));\n });\n}\n/**\n * Calculates hash using the argon2d password-hashing function\n * @returns Computed hash\n */\nfunction argon2d(options) {\n return __awaiter(this, void 0, void 0, function* () {\n validateOptions$3(options);\n return argon2Internal(Object.assign(Object.assign({}, options), { hashType: \"d\" }));\n });\n}\nconst getHashParameters = (password, encoded, secret) => {\n const regex = /^\\$argon2(id|i|d)\\$v=([0-9]+)\\$((?:[mtp]=[0-9]+,){2}[mtp]=[0-9]+)\\$([A-Za-z0-9+/]+)\\$([A-Za-z0-9+/]+)$/;\n const match = encoded.match(regex);\n if (!match) {\n throw new Error(\"Invalid hash\");\n }\n const [, hashType, version, parameters, salt, hash] = match;\n if (version !== \"19\") {\n throw new Error(`Unsupported version: ${version}`);\n }\n const parsedParameters = {};\n const paramMap = { m: \"memorySize\", p: \"parallelism\", t: \"iterations\" };\n for (const x of parameters.split(\",\")) {\n const [n, v] = x.split(\"=\");\n parsedParameters[paramMap[n]] = Number(v);\n }\n return Object.assign(Object.assign({}, parsedParameters), { password,\n secret, hashType: hashType, salt: decodeBase64(salt), hashLength: getDecodeBase64Length(hash), outputType: \"encoded\" });\n};\nconst validateVerifyOptions$1 = (options) => {\n if (!options || typeof options !== \"object\") {\n throw new Error(\"Invalid options parameter. It requires an object.\");\n }\n if (options.hash === undefined || typeof options.hash !== \"string\") {\n throw new Error(\"Hash should be specified\");\n }\n};\n/**\n * Verifies password using the argon2 password-hashing function\n * @returns True if the encoded hash matches the password\n */\nfunction argon2Verify(options) {\n return __awaiter(this, void 0, void 0, function* () {\n validateVerifyOptions$1(options);\n const params = getHashParameters(options.password, options.hash, options.secret);\n validateOptions$3(params);\n const hashStart = options.hash.lastIndexOf(\"$\") + 1;\n const result = (yield argon2Internal(params));\n return result.substring(hashStart) === options.hash.substring(hashStart);\n });\n}\n\nvar name$i = \"blake2s\";\nvar data$i = \"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\";\nvar hash$i = \"5c0ff166\";\nvar wasmJson$i = {\n\tname: name$i,\n\tdata: data$i,\n\thash: hash$i\n};\n\nconst mutex$j = new Mutex();\nlet wasmCache$j = null;\nfunction validateBits$3(bits) {\n if (!Number.isInteger(bits) || bits < 8 || bits > 256 || bits % 8 !== 0) {\n return new Error(\"Invalid variant! Valid values: 8, 16, ..., 256\");\n }\n return null;\n}\nfunction getInitParam(outputBits, keyBits) {\n return outputBits | (keyBits << 16);\n}\n/**\n * Calculates BLAKE2s hash\n * @param data Input data (string, Buffer or TypedArray)\n * @param bits Number of output bits, which has to be a number\n * divisible by 8, between 8 and 256. Defaults to 256.\n * @param key Optional key (string, Buffer or TypedArray). Maximum length is 32 bytes.\n * @returns Computed hash as a hexadecimal string\n */\nfunction blake2s(data, bits = 256, key = null) {\n if (validateBits$3(bits)) {\n return Promise.reject(validateBits$3(bits));\n }\n let keyBuffer = null;\n let initParam = bits;\n if (key !== null) {\n keyBuffer = getUInt8Buffer(key);\n if (keyBuffer.length > 32) {\n return Promise.reject(new Error(\"Max key length is 32 bytes\"));\n }\n initParam = getInitParam(bits, keyBuffer.length);\n }\n const hashLength = bits / 8;\n if (wasmCache$j === null || wasmCache$j.hashLength !== hashLength) {\n return lockedCreate(mutex$j, wasmJson$i, hashLength).then((wasm) => {\n wasmCache$j = wasm;\n if (initParam > 512) {\n wasmCache$j.writeMemory(keyBuffer);\n }\n return wasmCache$j.calculate(data, initParam);\n });\n }\n try {\n if (initParam > 512) {\n wasmCache$j.writeMemory(keyBuffer);\n }\n const hash = wasmCache$j.calculate(data, initParam);\n return Promise.resolve(hash);\n }\n catch (err) {\n return Promise.reject(err);\n }\n}\n/**\n * Creates a new BLAKE2s hash instance\n * @param bits Number of output bits, which has to be a number\n * divisible by 8, between 8 and 256. Defaults to 256.\n * @param key Optional key (string, Buffer or TypedArray). Maximum length is 32 bytes.\n */\nfunction createBLAKE2s(bits = 256, key = null) {\n if (validateBits$3(bits)) {\n return Promise.reject(validateBits$3(bits));\n }\n let keyBuffer = null;\n let initParam = bits;\n if (key !== null) {\n keyBuffer = getUInt8Buffer(key);\n if (keyBuffer.length > 32) {\n return Promise.reject(new Error(\"Max key length is 32 bytes\"));\n }\n initParam = getInitParam(bits, keyBuffer.length);\n }\n const outputSize = bits / 8;\n return WASMInterface(wasmJson$i, outputSize).then((wasm) => {\n if (initParam > 512) {\n wasm.writeMemory(keyBuffer);\n }\n wasm.init(initParam);\n const obj = {\n init: initParam > 512\n ? () => {\n wasm.writeMemory(keyBuffer);\n wasm.init(initParam);\n return obj;\n }\n : () => {\n wasm.init(initParam);\n return obj;\n },\n update: (data) => {\n wasm.update(data);\n return obj;\n },\n // biome-ignore lint/suspicious/noExplicitAny: Conflict with IHasher type\n digest: (outputType) => wasm.digest(outputType),\n save: () => wasm.save(),\n load: (data) => {\n wasm.load(data);\n return obj;\n },\n blockSize: 64,\n digestSize: outputSize,\n };\n return obj;\n });\n}\n\nvar name$h = \"blake3\";\nvar data$h = \"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IQEgAkFAaiICQcAASw0ACwsCQEHAACAHQf8BcSIGayIFIAIgBSACSRsiCUUNACAJQQNxIQtBACEFAkAgCUEESQ0AIAAgBmohByAJQfwAcSEIQQAhBQNAIAcgBWoiAkEoaiABIAVqIgotAAA6AAAgAkEpaiAKQQFqLQAAOgAAIAJBKmogCkECai0AADoAACACQStqIApBA2otAAA6AAAgCCAFQQRqIgVHDQALCwJAIAtFDQAgASAFaiEBIAUgBmogAGpBKGohBQNAIAUgAS0AADoAACABQQFqIQEgBUEBaiEFIAtBf2oiCw0ACwsgAC0AaCEHCyAAIAcgCWo6AGggA0HAAGokAAveAwQFfwN+BX8GfiMAQdABayIBJAACQCAAe6ciAkEALQCQigEiA08NAEEALQCKigFBBHIhBCABQShqIQVBACkDmIkBIQBBACkDkIkBIQZBACkDiIkBIQdBACkDgIkBIQggAyEJA0AgASAANwMYIAEgBjcDECABIAc3AwggASAINwMAIAEgA0EFdCIDQdGJAWoiCikDADcDKCABIANB2YkBaiILKQMANwMwIAEgA0HhiQFqIgwpAwA3AzggASADQemJAWoiDSkDADcDQCABIANB8YkBaikDADcDSCABIANB+YkBaikDADcDUCABIANBgYoBaikDADcDWCADQYmKAWopAwAhDiABQcAAOgBoIAEgDjcDYCABQgA3AyAgASAEOgBpIAEgADcDiAEgASAGNwOAASABIAc3A3ggASAINwNwIAFBkAFqIAFB8ABqIAVBwABCACAEQf8BcRACIAEpA7ABIQ4gASkDkAEhDyABKQO4ASEQIAEpA5gBIREgASkDwAEhEiABKQOgASETIA0gASkDyAEgASkDqAGFNwMAIAwgEiAThTcDACALIBAgEYU3AwAgCiAOIA+FNwMAIAlBf2oiCUH/AXEiAyACSw0AC0EAIAk6AJCKAQsgAUHQAWokAAvHCQIKfwV+IwBB4AJrIgUkAAJAAkAgAUGACEsNACAFIAA2AvwBIAVB/AFqIAFBgAhGIgZBECACQQEgA0EBQQIgBBABIAZBCnQiByABTw0BIAVB4ABqIgZCADcDACAFQdgAaiIIQgA3AwAgBUHQAGoiCUIANwMAIAVByABqIgpCADcDACAFQcAAaiILQgA3AwAgBUE4aiIMQgA3AwAgBUEwaiINQgA3AwAgBSADOgBqIAVCADcDKCAFQQA7AWggBUEAKQOAiQE3AwAgBUEAKQOIiQE3AwggBUEAKQOQiQE3AxAgBUEAKQOYiQE3AxggBSABQYAIRiIOrSACfDcDICAFIAAgB2pBACABIA4bEAQgBUGIAWpBMGogDSkDADcDACAFQYgBakE4aiAMKQMANwMAIAUgBSkDACIPNwOIASAFIAUpAwgiEDcDkAEgBSAFKQMQIhE3A5gBIAUgBSkDGCISNwOgASAFIAUpAyg3A7ABIAUtAGohACAFLQBpIQcgBSkDICECIAUtAGghASAFQYgBakHAAGogCykDADcDACAFQYgBakHIAGogCikDADcDACAFQYgBakHQAGogCSkDADcDACAFQYgBakHYAGogCCkDADcDACAFQYgBakHgAGogBikDADcDACAFIAE6APABIAUgAjcDqAEgBSAAIAdFckECciIAOgDxASAFIBI3A5gCIAUgETcDkAIgBSAQNwOIAiAFIA83A4ACIAVBoAJqIAVBgAJqIAVBsAFqIAEgAiAAQf8BcRACIAUpA8ACIQIgBSkDoAIhDyAFKQPIAiEQIAUpA6gCIREgBSkD0AIhEiAFKQOwAiETIAQgDkEFdGoiASAFKQPYAiAFKQO4AoU3AxggASASIBOFNwMQIAEgECARhTcDCCABIAIgD4U3AwBBAkEBIA4bIQYMAQsgAEIBIAFBf2pBCnZBAXKteUI/hYYiD6dBCnQiDiACIAMgBRAGIQcgACAOaiABIA5rIA9C////AYMgAnwgAyAFQcAAQSAgDkGACEsbahAGIQECQCAHQQFHDQAgBCAFKQMANwMAIAQgBSkDCDcDCCAEIAUpAxA3AxAgBCAFKQMYNwMYIAQgBSkDIDcDICAEIAUpAyg3AyggBCAFKQMwNwMwIAQgBSkDODcDOEECIQYMAQtBACEGQQAhAAJAIAEgB2oiCUECSQ0AIAlBfmoiCkEBdkEBaiIGQQNxIQ5BACEHAkAgCkEGSQ0AIAZB/P///wdxIQhBACEHIAVBiAFqIQEgBSEAA0AgASAANgIAIAFBDGogAEHAAWo2AgAgAUEIaiAAQYABajYCACABQQRqIABBwABqNgIAIABBgAJqIQAgAUEQaiEBIAggB0EEaiIHRw0ACwsgCkF+cSEIAkAgDkUNACAFIAdBBnRqIQEgBUGIAWogB0ECdGohAANAIAAgATYCACABQcAAaiEBIABBBGohACAOQX9qIg4NAAsLIAhBAmohAAsgBUGIAWogBkEBQgBBACADQQRyQQBBACAEEAEgACAJTw0AIAQgBkEFdGoiASAFIAZBBnRqIgApAwA3AwAgASAAKQMINwMIIAEgACkDEDcDECABIAApAxg3AxggBkEBaiEGCyAFQeACaiQAIAYLrRAIAn8EfgF/AX4EfwR+BH8EfiMAQfABayIBJAACQCAARQ0AAkBBAC0AkIoBIgINACABQTBqQQApA9CJATcDACABQThqQQApA9iJATcDACABQQApA6CJASIDNwMAIAFBACkDqIkBIgQ3AwggAUEAKQOwiQEiBTcDECABQQApA7iJASIGNwMYIAFBACkDyIkBNwMoQQAtAIqKASECQQAtAImKASEHQQApA8CJASEIQQAtAIiKASEJIAFBwABqQQApA+CJATcDACABQcgAakEAKQPoiQE3AwAgAUHQAGpBACkD8IkBNwMAIAFB2ABqQQApA/iJATcDACABQeAAakEAKQOAigE3AwAgASAJOgBoIAEgCDcDICABIAIgB0VyIgJBAnI6AGkgAUEoaiEKQgAhCEGACSELIAJBCnJB/wFxIQwDQCABQbABaiABIAogCUH/AXEgCCAMEAIgASABKQPQASINIAEpA7ABhTcDcCABIAEpA9gBIg4gASkDuAGFNwN4IAEgASkD4AEiDyABKQPAAYU3A4ABIAEgASkD6AEiECAGhTcDqAEgASAPIAWFNwOgASABIA4gBIU3A5gBIAEgDSADhTcDkAEgASAQIAEpA8gBhTcDiAEgAEHAACAAQcAASRsiEUF/aiESAkACQCARQQdxIhMNACABQfAAaiECIAshByARIRQMAQsgEUH4AHEhFCABQfAAaiECIAshBwNAIAcgAi0AADoAACAHQQFqIQcgAkEBaiECIBNBf2oiEw0ACwsCQCASQQdJDQADQCAHIAIpAAA3AAAgB0EIaiEHIAJBCGohAiAUQXhqIhQNAAsLIAhCAXwhCCALIBFqIQsgACARayIADQAMAgsLAkACQAJAQQAtAImKASIHQQZ0QQBBAC0AiIoBIhFrRg0AIAEgEToAaCABQQApA4CKATcDYCABQQApA/iJATcDWCABQQApA/CJATcDUCABQQApA+iJATcDSCABQQApA+CJATcDQCABQQApA9iJATcDOCABQQApA9CJATcDMCABQQApA8iJATcDKCABQQApA8CJASIINwMgIAFBACkDuIkBIgM3AxggAUEAKQOwiQEiBDcDECABQQApA6iJASIFNwMIIAFBACkDoIkBIgY3AwAgAUEALQCKigEiEyAHRXJBAnIiCzoAaSATQQRyIRNBACkDmIkBIQ1BACkDkIkBIQ5BACkDiIkBIQ9BACkDgIkBIRAMAQtBwAAhESABQcAAOgBoQgAhCCABQgA3AyAgAUEAKQOYiQEiDTcDGCABQQApA5CJASIONwMQIAFBACkDiIkBIg83AwggAUEAKQOAiQEiEDcDACABQQAtAIqKAUEEciITOgBpIAEgAkF+aiICQQV0IgdByYoBaikDADcDYCABIAdBwYoBaikDADcDWCABIAdBuYoBaikDADcDUCABIAdBsYoBaikDADcDSCABIAdBqYoBaikDADcDQCABIAdBoYoBaikDADcDOCABIAdBmYoBaikDADcDMCABIAdBkYoBaikDADcDKCATIQsgECEGIA8hBSAOIQQgDSEDIAJFDQELIAJBf2oiB0EFdCIUQZGKAWopAwAhFSAUQZmKAWopAwAhFiAUQaGKAWopAwAhFyAUQamKAWopAwAhGCABIAM3A4gBIAEgBDcDgAEgASAFNwN4IAEgBjcDcCABQbABaiABQfAAaiABQShqIhQgESAIIAtB/wFxEAIgASATOgBpIAFBwAA6AGggASAYNwNAIAEgFzcDOCABIBY3AzAgASAVNwMoIAFCADcDICABIA03AxggASAONwMQIAEgDzcDCCABIBA3AwAgASABKQPoASABKQPIAYU3A2AgASABKQPgASABKQPAAYU3A1ggASABKQPYASABKQO4AYU3A1AgASABKQPQASABKQOwAYU3A0ggB0UNACACQQV0QemJAWohAiATQf8BcSERA0AgAkFoaikDACEIIAJBcGopAwAhAyACQXhqKQMAIQQgAikDACEFIAEgDTcDiAEgASAONwOAASABIA83A3ggASAQNwNwIAFBsAFqIAFB8ABqIBRBwABCACAREAIgASATOgBpIAFBwAA6AGggASAFNwNAIAEgBDcDOCABIAM3AzAgASAINwMoIAFCADcDICABIA03AxggASAONwMQIAEgDzcDCCABIBA3AwAgASABKQPoASABKQPIAYU3A2AgASABKQPgASABKQPAAYU3A1ggASABKQPYASABKQO4AYU3A1AgASABKQPQASABKQOwAYU3A0ggAkFgaiECIAdBf2oiBw0ACwsgAUEoaiEJQgAhCEGACSELIBNBCHJB/wFxIQoDQCABQbABaiABIAlBwAAgCCAKEAIgASABKQPQASIDIAEpA7ABhTcDcCABIAEpA9gBIgQgASkDuAGFNwN4IAEgASkD4AEiBSABKQPAAYU3A4ABIAEgDSABKQPoASIGhTcDqAEgASAOIAWFNwOgASABIA8gBIU3A5gBIAEgECADhTcDkAEgASAGIAEpA8gBhTcDiAEgAEHAACAAQcAASRsiEUF/aiESAkACQCARQQdxIhMNACABQfAAaiECIAshByARIRQMAQsgEUH4AHEhFCABQfAAaiECIAshBwNAIAcgAi0AADoAACAHQQFqIQcgAkEBaiECIBNBf2oiEw0ACwsCQCASQQdJDQADQCAHIAIpAAA3AAAgB0EIaiEHIAJBCGohAiAUQXhqIhQNAAsLIAhCAXwhCCALIBFqIQsgACARayIADQALCyABQfABaiQAC6MCAQR+AkACQCAAQSBGDQBCq7OP/JGjs/DbACEBQv+kuYjFkdqCm38hAkLy5rvjo6f9p6V/IQNC58yn0NbQ67O7fyEEQQAhAAwBC0EAKQOYCSEBQQApA5AJIQJBACkDiAkhA0EAKQOACSEEQRAhAAtBACAAOgCKigFBAEIANwOAigFBAEIANwP4iQFBAEIANwPwiQFBAEIANwPoiQFBAEIANwPgiQFBAEIANwPYiQFBAEIANwPQiQFBAEIANwPIiQFBAEIANwPAiQFBACABNwO4iQFBACACNwOwiQFBACADNwOoiQFBACAENwOgiQFBACABNwOYiQFBACACNwOQiQFBACADNwOIiQFBACAENwOAiQFBAEEAOgCQigFBAEEAOwGIigELBgAgABADCwYAIAAQBwsGAEGAiQELqwIBBH4CQAJAIAFBIEYNAEKrs4/8kaOz8NsAIQNC/6S5iMWR2oKbfyEEQvLmu+Ojp/2npX8hBULnzKfQ1tDrs7t/IQZBACEBDAELQQApA5gJIQNBACkDkAkhBEEAKQOICSEFQQApA4AJIQZBECEBC0EAIAE6AIqKAUEAQgA3A4CKAUEAQgA3A/iJAUEAQgA3A/CJAUEAQgA3A+iJAUEAQgA3A+CJAUEAQgA3A9iJAUEAQgA3A9CJAUEAQgA3A8iJAUEAQgA3A8CJAUEAIAM3A7iJAUEAIAQ3A7CJAUEAIAU3A6iJAUEAIAY3A6CJAUEAIAM3A5iJAUEAIAQ3A5CJAUEAIAU3A4iJAUEAIAY3A4CJAUEAQQA6AJCKAUEAQQA7AYiKASAAEAMgAhAHCwsLAQBBgAgLBHgHAAA=\";\nvar hash$h = \"215d875f\";\nvar wasmJson$h = {\n\tname: name$h,\n\tdata: data$h,\n\thash: hash$h\n};\n\nconst mutex$i = new Mutex();\nlet wasmCache$i = null;\nfunction validateBits$2(bits) {\n if (!Number.isInteger(bits) || bits < 8 || bits % 8 !== 0) {\n return new Error(\"Invalid variant! Valid values: 8, 16, ...\");\n }\n return null;\n}\n/**\n * Calculates BLAKE3 hash\n * @param data Input data (string, Buffer or TypedArray)\n * @param bits Number of output bits, which has to be a number\n * divisible by 8. Defaults to 256.\n * @param key Optional key (string, Buffer or TypedArray). Length should be 32 bytes.\n * @returns Computed hash as a hexadecimal string\n */\nfunction blake3(data, bits = 256, key = null) {\n if (validateBits$2(bits)) {\n return Promise.reject(validateBits$2(bits));\n }\n let keyBuffer = null;\n let initParam = 0; // key is empty by default\n if (key !== null) {\n keyBuffer = getUInt8Buffer(key);\n if (keyBuffer.length !== 32) {\n return Promise.reject(new Error(\"Key length must be exactly 32 bytes\"));\n }\n initParam = 32;\n }\n const hashLength = bits / 8;\n const digestParam = hashLength;\n if (wasmCache$i === null || wasmCache$i.hashLength !== hashLength) {\n return lockedCreate(mutex$i, wasmJson$h, hashLength).then((wasm) => {\n wasmCache$i = wasm;\n if (initParam === 32) {\n wasmCache$i.writeMemory(keyBuffer);\n }\n return wasmCache$i.calculate(data, initParam, digestParam);\n });\n }\n try {\n if (initParam === 32) {\n wasmCache$i.writeMemory(keyBuffer);\n }\n const hash = wasmCache$i.calculate(data, initParam, digestParam);\n return Promise.resolve(hash);\n }\n catch (err) {\n return Promise.reject(err);\n }\n}\n/**\n * Creates a new BLAKE3 hash instance\n * @param bits Number of output bits, which has to be a number\n * divisible by 8. Defaults to 256.\n * @param key Optional key (string, Buffer or TypedArray). Length should be 32 bytes.\n */\nfunction createBLAKE3(bits = 256, key = null) {\n if (validateBits$2(bits)) {\n return Promise.reject(validateBits$2(bits));\n }\n let keyBuffer = null;\n let initParam = 0; // key is empty by default\n if (key !== null) {\n keyBuffer = getUInt8Buffer(key);\n if (keyBuffer.length !== 32) {\n return Promise.reject(new Error(\"Key length must be exactly 32 bytes\"));\n }\n initParam = 32;\n }\n const outputSize = bits / 8;\n const digestParam = outputSize;\n return WASMInterface(wasmJson$h, outputSize).then((wasm) => {\n if (initParam === 32) {\n wasm.writeMemory(keyBuffer);\n }\n wasm.init(initParam);\n const obj = {\n init: initParam === 32\n ? () => {\n wasm.writeMemory(keyBuffer);\n wasm.init(initParam);\n return obj;\n }\n : () => {\n wasm.init(initParam);\n return obj;\n },\n update: (data) => {\n wasm.update(data);\n return obj;\n },\n // biome-ignore lint/suspicious/noExplicitAny: Conflict with IHasher type\n digest: (outputType) => wasm.digest(outputType, digestParam),\n save: () => wasm.save(),\n load: (data) => {\n wasm.load(data);\n return obj;\n },\n blockSize: 64,\n digestSize: outputSize,\n };\n return obj;\n });\n}\n\nvar name$g = \"crc32\";\nvar data$g = \"AGFzbQEAAAABEQRgAAF/YAF/AGAAAGACf38AAwgHAAEBAQIAAwUEAQECAgYOAn8BQZDJBQt/AEGACAsHcAgGbWVtb3J5AgAOSGFzaF9HZXRCdWZmZXIAAAlIYXNoX0luaXQAAgtIYXNoX1VwZGF0ZQADCkhhc2hfRmluYWwABA1IYXNoX0dldFN0YXRlAAUOSGFzaF9DYWxjdWxhdGUABgpTVEFURV9TSVpFAwEKkggHBQBBgAkLwwMBA39BgIkBIQFBACECA0AgAUEAQQBBAEEAQQBBAEEAQQAgAkEBcWsgAHEgAkEBdnMiA0EBcWsgAHEgA0EBdnMiA0EBcWsgAHEgA0EBdnMiA0EBcWsgAHEgA0EBdnMiA0EBcWsgAHEgA0EBdnMiA0EBcWsgAHEgA0EBdnMiA0EBcWsgAHEgA0EBdnMiA0EBcWsgAHEgA0EBdnM2AgAgAUEEaiEBIAJBAWoiAkGAAkcNAAtBACEAA0AgAEGEkQFqIABBhIkBaigCACICQf8BcUECdEGAiQFqKAIAIAJBCHZzIgI2AgAgAEGEmQFqIAJB/wFxQQJ0QYCJAWooAgAgAkEIdnMiAjYCACAAQYShAWogAkH/AXFBAnRBgIkBaigCACACQQh2cyICNgIAIABBhKkBaiACQf8BcUECdEGAiQFqKAIAIAJBCHZzIgI2AgAgAEGEsQFqIAJB/wFxQQJ0QYCJAWooAgAgAkEIdnMiAjYCACAAQYS5AWogAkH/AXFBAnRBgIkBaigCACACQQh2cyICNgIAIABBhMEBaiACQf8BcUECdEGAiQFqKAIAIAJBCHZzNgIAIABBBGoiAEH8B0cNAAsLJwACQEEAKAKAyQEgAEYNACAAEAFBACAANgKAyQELQQBBADYChMkBC4gDAQN/QQAoAoTJAUF/cyEBQYAJIQICQCAAQQhJDQBBgAkhAgNAIAJBBGooAgAiA0EOdkH8B3FBgJEBaigCACADQRZ2QfwHcUGAiQFqKAIAcyADQQZ2QfwHcUGAmQFqKAIAcyADQf8BcUECdEGAoQFqKAIAcyACKAIAIAFzIgFBFnZB/AdxQYCpAWooAgBzIAFBDnZB/AdxQYCxAWooAgBzIAFBBnZB/AdxQYC5AWooAgBzIAFB/wFxQQJ0QYDBAWooAgBzIQEgAkEIaiECIABBeGoiAEEHSw0ACwsCQCAARQ0AAkACQCAAQQFxDQAgACEDDAELIAFB/wFxIAItAABzQQJ0QYCJAWooAgAgAUEIdnMhASACQQFqIQIgAEF/aiEDCyAAQQFGDQADQCABQf8BcSACLQAAc0ECdEGAiQFqKAIAIAFBCHZzIgFB/wFxIAJBAWotAABzQQJ0QYCJAWooAgAgAUEIdnMhASACQQJqIQIgA0F+aiIDDQALC0EAIAFBf3M2AoTJAQsyAQF/QQBBACgChMkBIgBBGHQgAEGA/gNxQQh0ciAAQQh2QYD+A3EgAEEYdnJyNgKACQsGAEGEyQELWQACQEEAKAKAyQEgAUYNACABEAFBACABNgKAyQELQQBBADYChMkBIAAQA0EAQQAoAoTJASIBQRh0IAFBgP4DcUEIdHIgAUEIdkGA/gNxIAFBGHZycjYCgAkLCwsBAEGACAsEBAAAAA==\";\nvar hash$g = \"d2eba587\";\nvar wasmJson$g = {\n\tname: name$g,\n\tdata: data$g,\n\thash: hash$g\n};\n\nconst mutex$h = new Mutex();\nlet wasmCache$h = null;\nfunction validatePoly(poly) {\n if (!Number.isInteger(poly) || poly < 0 || poly > 0xffffffff) {\n return new Error(\"Polynomial must be a valid 32-bit long unsigned integer\");\n }\n return null;\n}\n/**\n * Calculates CRC-32 hash\n * @param data Input data (string, Buffer or TypedArray)\n * @param polynomial Input polynomial (defaults to 0xedb88320, for CRC32C use 0x82f63b78)\n * @returns Computed hash as a hexadecimal string\n */\nfunction crc32(data, polynomial = 0xedb88320) {\n if (validatePoly(polynomial)) {\n return Promise.reject(validatePoly(polynomial));\n }\n if (wasmCache$h === null) {\n return lockedCreate(mutex$h, wasmJson$g, 4).then((wasm) => {\n wasmCache$h = wasm;\n return wasmCache$h.calculate(data, polynomial);\n });\n }\n try {\n const hash = wasmCache$h.calculate(data, polynomial);\n return Promise.resolve(hash);\n }\n catch (err) {\n return Promise.reject(err);\n }\n}\n/**\n * Creates a new CRC-32 hash instance\n * @param polynomial Input polynomial (defaults to 0xedb88320, for CRC32C use 0x82f63b78)\n */\nfunction createCRC32(polynomial = 0xedb88320) {\n if (validatePoly(polynomial)) {\n return Promise.reject(validatePoly(polynomial));\n }\n return WASMInterface(wasmJson$g, 4).then((wasm) => {\n wasm.init(polynomial);\n const obj = {\n init: () => {\n wasm.init(polynomial);\n return obj;\n },\n update: (data) => {\n wasm.update(data);\n return obj;\n },\n // biome-ignore lint/suspicious/noExplicitAny: Conflict with IHasher type\n digest: (outputType) => wasm.digest(outputType),\n save: () => wasm.save(),\n load: (data) => {\n wasm.load(data);\n return obj;\n },\n blockSize: 4,\n digestSize: 4,\n };\n return obj;\n });\n}\n\nvar name$f = \"crc64\";\nvar data$f = \"AGFzbQEAAAABDANgAAF/YAAAYAF/AAMHBgABAgEAAQUEAQECAgYOAn8BQZCJBgt/AEGACAsHcAgGbWVtb3J5AgAOSGFzaF9HZXRCdWZmZXIAAAlIYXNoX0luaXQAAQtIYXNoX1VwZGF0ZQACCkhhc2hfRmluYWwAAw1IYXNoX0dldFN0YXRlAAQOSGFzaF9DYWxjdWxhdGUABQpTVEFURV9TSVpFAwEKgwgGBQBBgAkL9QMDAX4BfwJ+AkBBACkDgIkCQQApA4AJIgBRDQBBgIkBIQFCACECA0AgAUIAQgBCAEIAQgBCAEIAQgAgAkIBg30gAIMgAkIBiIUiA0IBg30gAIMgA0IBiIUiA0IBg30gAIMgA0IBiIUiA0IBg30gAIMgA0IBiIUiA0IBg30gAIMgA0IBiIUiA0IBg30gAIMgA0IBiIUiA0IBg30gAIMgA0IBiIUiA0IBg30gAIMgA0IBiIU3AwAgAUEIaiEBIAJCAXwiAkKAAlINAAtBACEBA0AgAUGImQFqIAFBiIkBaikDACICp0H/AXFBA3RBgIkBaikDACACQgiIhSICNwMAIAFBiKkBaiACp0H/AXFBA3RBgIkBaikDACACQgiIhSICNwMAIAFBiLkBaiACp0H/AXFBA3RBgIkBaikDACACQgiIhSICNwMAIAFBiMkBaiACp0H/AXFBA3RBgIkBaikDACACQgiIhSICNwMAIAFBiNkBaiACp0H/AXFBA3RBgIkBaikDACACQgiIhSICNwMAIAFBiOkBaiACp0H/AXFBA3RBgIkBaikDACACQgiIhSICNwMAIAFBiPkBaiACp0H/AXFBA3RBgIkBaikDACACQgiIhTcDACABQQhqIgFB+A9HDQALQQAgADcDgIkCC0EAQgA3A4iJAguUAwIBfgJ/QQApA4iJAkJ/hSEBQYAJIQICQCAAQQhJDQBBgAkhAgNAIAIpAwAgAYUiAUIwiKdB/wFxQQN0QYCZAWopAwAgAUI4iKdBA3RBgIkBaikDAIUgAUIoiKdB/wFxQQN0QYCpAWopAwCFIAFCIIinQf8BcUEDdEGAuQFqKQMAhSABpyIDQRV2QfgPcUGAyQFqKQMAhSADQQ12QfgPcUGA2QFqKQMAhSADQQV2QfgPcUGA6QFqKQMAhSADQf8BcUEDdEGA+QFqKQMAhSEBIAJBCGohAiAAQXhqIgBBB0sNAAsLAkAgAEUNAAJAAkAgAEEBcQ0AIAAhAwwBCyABQv8BgyACMQAAhadBA3RBgIkBaikDACABQgiIhSEBIAJBAWohAiAAQX9qIQMLIABBAUYNAANAIAFC/wGDIAIxAACFp0EDdEGAiQFqKQMAIAFCCIiFIgFC/wGDIAJBAWoxAACFp0EDdEGAiQFqKQMAIAFCCIiFIQEgAkECaiECIANBfmoiAw0ACwtBACABQn+FNwOIiQILZAEBfkEAQQApA4iJAiIAQjiGIABCgP4Dg0IohoQgAEKAgPwHg0IYhiAAQoCAgPgPg0IIhoSEIABCCIhCgICA+A+DIABCGIhCgID8B4OEIABCKIhCgP4DgyAAQjiIhISENwOACQsGAEGIiQILAgALCwsBAEGACAsECAAAAA==\";\nvar hash$f = \"c5ac6c16\";\nvar wasmJson$f = {\n\tname: name$f,\n\tdata: data$f,\n\thash: hash$f\n};\n\nconst mutex$g = new Mutex();\nlet wasmCache$g = null;\nconst polyBuffer = new Uint8Array(8);\nfunction parsePoly(poly) {\n const errText = \"Polynomial must be provided as a 16 char long hex string\";\n if (typeof poly !== \"string\" || poly.length !== 16) {\n return { hi: 0, lo: 0, err: new Error(errText) };\n }\n const hi = Number(`0x${poly.slice(0, 8)}`);\n const lo = Number(`0x${poly.slice(8)}`);\n if (Number.isNaN(hi) || Number.isNaN(lo)) {\n return { hi, lo, err: new Error(errText) };\n }\n return { hi, lo, err: null };\n}\nfunction writePoly(arr, lo, hi) {\n // write in little-endian format\n const buffer = new DataView(arr);\n buffer.setUint32(0, lo, true);\n buffer.setUint32(4, hi, true);\n}\n/**\n * Calculates CRC-64 hash\n * @param data Input data (string, Buffer or TypedArray)\n * @param polynomial Input polynomial (defaults to 'c96c5795d7870f42' - ECMA)\n * @returns Computed hash as a hexadecimal string\n */\nfunction crc64(data, polynomial = \"c96c5795d7870f42\") {\n const { hi, lo, err } = parsePoly(polynomial);\n if (err !== null) {\n return Promise.reject(err);\n }\n if (wasmCache$g === null) {\n return lockedCreate(mutex$g, wasmJson$f, 8).then((wasm) => {\n wasmCache$g = wasm;\n writePoly(polyBuffer.buffer, lo, hi);\n wasmCache$g.writeMemory(polyBuffer);\n return wasmCache$g.calculate(data);\n });\n }\n try {\n writePoly(polyBuffer.buffer, lo, hi);\n wasmCache$g.writeMemory(polyBuffer);\n const hash = wasmCache$g.calculate(data);\n return Promise.resolve(hash);\n }\n catch (err) {\n return Promise.reject(err);\n }\n}\n/**\n * Creates a new CRC-64 hash instance\n * @param polynomial Input polynomial (defaults to 'c96c5795d7870f42' - ECMA)\n */\nfunction createCRC64(polynomial = \"c96c5795d7870f42\") {\n const { hi, lo, err } = parsePoly(polynomial);\n if (err !== null) {\n return Promise.reject(err);\n }\n return WASMInterface(wasmJson$f, 8).then((wasm) => {\n const instanceBuffer = new Uint8Array(8);\n writePoly(instanceBuffer.buffer, lo, hi);\n wasm.writeMemory(instanceBuffer);\n wasm.init();\n const obj = {\n init: () => {\n wasm.writeMemory(instanceBuffer);\n wasm.init();\n return obj;\n },\n update: (data) => {\n wasm.update(data);\n return obj;\n },\n // biome-ignore lint/suspicious/noExplicitAny: Conflict with IHasher type\n digest: (outputType) => wasm.digest(outputType),\n save: () => wasm.save(),\n load: (data) => {\n wasm.load(data);\n return obj;\n },\n blockSize: 8,\n digestSize: 8,\n };\n return obj;\n });\n}\n\nvar name$e = \"md4\";\nvar data$e = \"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\";\nvar hash$e = \"bd8ce7c7\";\nvar wasmJson$e = {\n\tname: name$e,\n\tdata: data$e,\n\thash: hash$e\n};\n\nconst mutex$f = new Mutex();\nlet wasmCache$f = null;\n/**\n * Calculates MD4 hash\n * @param data Input data (string, Buffer or TypedArray)\n * @returns Computed hash as a hexadecimal string\n */\nfunction md4(data) {\n if (wasmCache$f === null) {\n return lockedCreate(mutex$f, wasmJson$e, 16).then((wasm) => {\n wasmCache$f = wasm;\n return wasmCache$f.calculate(data);\n });\n }\n try {\n const hash = wasmCache$f.calculate(data);\n return Promise.resolve(hash);\n }\n catch (err) {\n return Promise.reject(err);\n }\n}\n/**\n * Creates a new MD4 hash instance\n */\nfunction createMD4() {\n return WASMInterface(wasmJson$e, 16).then((wasm) => {\n wasm.init();\n const obj = {\n init: () => {\n wasm.init();\n return obj;\n },\n update: (data) => {\n wasm.update(data);\n return obj;\n },\n // biome-ignore lint/suspicious/noExplicitAny: Conflict with IHasher type\n digest: (outputType) => wasm.digest(outputType),\n save: () => wasm.save(),\n load: (data) => {\n wasm.load(data);\n return obj;\n },\n blockSize: 64,\n digestSize: 16,\n };\n return obj;\n });\n}\n\nvar name$d = \"md5\";\nvar data$d = \"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\";\nvar hash$d = \"e6508e4b\";\nvar wasmJson$d = {\n\tname: name$d,\n\tdata: data$d,\n\thash: hash$d\n};\n\nconst mutex$e = new Mutex();\nlet wasmCache$e = null;\n/**\n * Calculates MD5 hash\n * @param data Input data (string, Buffer or TypedArray)\n * @returns Computed hash as a hexadecimal string\n */\nfunction md5(data) {\n if (wasmCache$e === null) {\n return lockedCreate(mutex$e, wasmJson$d, 16).then((wasm) => {\n wasmCache$e = wasm;\n return wasmCache$e.calculate(data);\n });\n }\n try {\n const hash = wasmCache$e.calculate(data);\n return Promise.resolve(hash);\n }\n catch (err) {\n return Promise.reject(err);\n }\n}\n/**\n * Creates a new MD5 hash instance\n */\nfunction createMD5() {\n return WASMInterface(wasmJson$d, 16).then((wasm) => {\n wasm.init();\n const obj = {\n init: () => {\n wasm.init();\n return obj;\n },\n update: (data) => {\n wasm.update(data);\n return obj;\n },\n // biome-ignore lint/suspicious/noExplicitAny: Conflict with IHasher type\n digest: (outputType) => wasm.digest(outputType),\n save: () => wasm.save(),\n load: (data) => {\n wasm.load(data);\n return obj;\n },\n blockSize: 64,\n digestSize: 16,\n };\n return obj;\n });\n}\n\nvar name$c = \"sha1\";\nvar data$c = \"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\";\nvar hash$c = \"6b530c24\";\nvar wasmJson$c = {\n\tname: name$c,\n\tdata: data$c,\n\thash: hash$c\n};\n\nconst mutex$d = new Mutex();\nlet wasmCache$d = null;\n/**\n * Calculates SHA-1 hash\n * @param data Input data (string, Buffer or TypedArray)\n * @returns Computed hash as a hexadecimal string\n */\nfunction sha1(data) {\n if (wasmCache$d === null) {\n return lockedCreate(mutex$d, wasmJson$c, 20).then((wasm) => {\n wasmCache$d = wasm;\n return wasmCache$d.calculate(data);\n });\n }\n try {\n const hash = wasmCache$d.calculate(data);\n return Promise.resolve(hash);\n }\n catch (err) {\n return Promise.reject(err);\n }\n}\n/**\n * Creates a new SHA-1 hash instance\n */\nfunction createSHA1() {\n return WASMInterface(wasmJson$c, 20).then((wasm) => {\n wasm.init();\n const obj = {\n init: () => {\n wasm.init();\n return obj;\n },\n update: (data) => {\n wasm.update(data);\n return obj;\n },\n // biome-ignore lint/suspicious/noExplicitAny: Conflict with IHasher type\n digest: (outputType) => wasm.digest(outputType),\n save: () => wasm.save(),\n load: (data) => {\n wasm.load(data);\n return obj;\n },\n blockSize: 64,\n digestSize: 20,\n };\n return obj;\n });\n}\n\nvar name$b = \"sha3\";\nvar data$b = \"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\";\nvar hash$b = \"fb24e536\";\nvar wasmJson$b = {\n\tname: name$b,\n\tdata: data$b,\n\thash: hash$b\n};\n\nconst mutex$c = new Mutex();\nlet wasmCache$c = null;\nfunction validateBits$1(bits) {\n if (![224, 256, 384, 512].includes(bits)) {\n return new Error(\"Invalid variant! Valid values: 224, 256, 384, 512\");\n }\n return null;\n}\n/**\n * Calculates SHA-3 hash\n * @param data Input data (string, Buffer or TypedArray)\n * @param bits Number of output bits. Valid values: 224, 256, 384, 512\n * @returns Computed hash as a hexadecimal string\n */\nfunction sha3(data, bits = 512) {\n if (validateBits$1(bits)) {\n return Promise.reject(validateBits$1(bits));\n }\n const hashLength = bits / 8;\n if (wasmCache$c === null || wasmCache$c.hashLength !== hashLength) {\n return lockedCreate(mutex$c, wasmJson$b, hashLength).then((wasm) => {\n wasmCache$c = wasm;\n return wasmCache$c.calculate(data, bits, 0x06);\n });\n }\n try {\n const hash = wasmCache$c.calculate(data, bits, 0x06);\n return Promise.resolve(hash);\n }\n catch (err) {\n return Promise.reject(err);\n }\n}\n/**\n * Creates a new SHA-3 hash instance\n * @param bits Number of output bits. Valid values: 224, 256, 384, 512\n */\nfunction createSHA3(bits = 512) {\n if (validateBits$1(bits)) {\n return Promise.reject(validateBits$1(bits));\n }\n const outputSize = bits / 8;\n return WASMInterface(wasmJson$b, outputSize).then((wasm) => {\n wasm.init(bits);\n const obj = {\n init: () => {\n wasm.init(bits);\n return obj;\n },\n update: (data) => {\n wasm.update(data);\n return obj;\n },\n // biome-ignore lint/suspicious/noExplicitAny: Conflict with IHasher type\n digest: (outputType) => wasm.digest(outputType, 0x06),\n save: () => wasm.save(),\n load: (data) => {\n wasm.load(data);\n return obj;\n },\n blockSize: 200 - 2 * outputSize,\n digestSize: outputSize,\n };\n return obj;\n });\n}\n\nconst mutex$b = new Mutex();\nlet wasmCache$b = null;\nfunction validateBits(bits) {\n if (![224, 256, 384, 512].includes(bits)) {\n return new Error(\"Invalid variant! Valid values: 224, 256, 384, 512\");\n }\n return null;\n}\n/**\n * Calculates Keccak hash\n * @param data Input data (string, Buffer or TypedArray)\n * @param bits Number of output bits. Valid values: 224, 256, 384, 512\n * @returns Computed hash as a hexadecimal string\n */\nfunction keccak(data, bits = 512) {\n if (validateBits(bits)) {\n return Promise.reject(validateBits(bits));\n }\n const hashLength = bits / 8;\n if (wasmCache$b === null || wasmCache$b.hashLength !== hashLength) {\n return lockedCreate(mutex$b, wasmJson$b, hashLength).then((wasm) => {\n wasmCache$b = wasm;\n return wasmCache$b.calculate(data, bits, 0x01);\n });\n }\n try {\n const hash = wasmCache$b.calculate(data, bits, 0x01);\n return Promise.resolve(hash);\n }\n catch (err) {\n return Promise.reject(err);\n }\n}\n/**\n * Creates a new Keccak hash instance\n * @param bits Number of output bits. Valid values: 224, 256, 384, 512\n */\nfunction createKeccak(bits = 512) {\n if (validateBits(bits)) {\n return Promise.reject(validateBits(bits));\n }\n const outputSize = bits / 8;\n return WASMInterface(wasmJson$b, outputSize).then((wasm) => {\n wasm.init(bits);\n const obj = {\n init: () => {\n wasm.init(bits);\n return obj;\n },\n update: (data) => {\n wasm.update(data);\n return obj;\n },\n // biome-ignore lint/suspicious/noExplicitAny: Conflict with IHasher type\n digest: (outputType) => wasm.digest(outputType, 0x01),\n save: () => wasm.save(),\n load: (data) => {\n wasm.load(data);\n return obj;\n },\n blockSize: 200 - 2 * outputSize,\n digestSize: outputSize,\n };\n return obj;\n });\n}\n\nvar name$a = \"sha256\";\nvar data$a = \"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c2pBx6KerX1qIhkgASADcyACcSABIANxcyABQR53IAFBE3dzIAFBCndzaiAaaiICaiIJIBMgEnNxIBJzaiAJQRp3IAlBFXdzIAlBB3dzakHRxqk2aiIaIAIgAXMgA3EgAiABcXMgAkEedyACQRN3cyACQQp3c2ogGGoiA2oiESAJIBNzcSATc2ogEUEadyARQRV3cyARQQd3c2pB59KkoQFqIhggAyACcyABcSADIAJxcyADQR53IANBE3dzIANBCndzaiAUaiIBaiISIBEgCXNxIAlzaiASQRp3IBJBFXdzIBJBB3dzakGFldy9AmoiFCABIANzIAJxIAEgA3FzIAFBHncgAUETd3MgAUEKd3NqIBdqIgJqIhMgI2ogJiASaiAiIBFqICUgCWogEyASIBFzcSARc2ogE0EadyATQRV3cyATQQd3c2pBuMLs8AJqIhcgAiABcyADcSACIAFxcyACQR53IAJBE3dzIAJBCndzaiAZaiIDaiIJIBMgEnNxIBJzaiAJQRp3IAlBFXdzIAlBB3dzakH827HpBGoiGSADIAJzIAFxIAMgAnFzIANBHncgA0ETd3MgA0EKd3NqIBpqIgFqIhEgCSATc3EgE3NqIBFBGncgEUEVd3MgEUEHd3NqQZOa4JkFaiIaIAEgA3MgAnEgASADcXMgAUEedyABQRN3cyABQQp3c2ogGGoiAmoiEiARIAlzcSAJc2ogEkEadyASQRV3cyASQQd3c2pB1OapqAZqIhggAiABcyADcSACIAFxcyACQR53IAJBE3dzIAJBCndzaiAUaiIDaiITaiAoIBJqICQgEWogJyAJaiATIBIgEXNxIBFzaiATQRp3IBNBFXdzIBNBB3dzakG7laizB2oiFCADIAJzIAFxIAMgAnFzIANBHncgA0ETd3MgA0EKd3NqIBdqIgFqIgkgEyASc3EgEnNqIAlBGncgCUEVd3MgCUEHd3NqQa6Si454aiIXIAEgA3MgAnEgASADcXMgAUEedyABQRN3cyABQQp3c2ogGWoiAmoiESAJIBNzcSATc2ogEUEadyARQRV3cyARQQd3c2pBhdnIk3lqIhkgAiABcyADcSACIAFxcyACQR53IAJBE3dzIAJBCndzaiAaaiIDaiISIBEgCXNxIAlzaiASQRp3IBJBFXdzIBJBB3dzakGh0f+VemoiGiADIAJz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\";\nvar hash$a = \"8c18dd94\";\nvar wasmJson$a = {\n\tname: name$a,\n\tdata: data$a,\n\thash: hash$a\n};\n\nconst mutex$a = new Mutex();\nlet wasmCache$a = null;\n/**\n * Calculates SHA-2 (SHA-224) hash\n * @param data Input data (string, Buffer or TypedArray)\n * @returns Computed hash as a hexadecimal string\n */\nfunction sha224(data) {\n if (wasmCache$a === null) {\n return lockedCreate(mutex$a, wasmJson$a, 28).then((wasm) => {\n wasmCache$a = wasm;\n return wasmCache$a.calculate(data, 224);\n });\n }\n try {\n const hash = wasmCache$a.calculate(data, 224);\n return Promise.resolve(hash);\n }\n catch (err) {\n return Promise.reject(err);\n }\n}\n/**\n * Creates a new SHA-2 (SHA-224) hash instance\n */\nfunction createSHA224() {\n return WASMInterface(wasmJson$a, 28).then((wasm) => {\n wasm.init(224);\n const obj = {\n init: () => {\n wasm.init(224);\n return obj;\n },\n update: (data) => {\n wasm.update(data);\n return obj;\n },\n // biome-ignore lint/suspicious/noExplicitAny: Conflict with IHasher type\n digest: (outputType) => wasm.digest(outputType),\n save: () => wasm.save(),\n load: (data) => {\n wasm.load(data);\n return obj;\n },\n blockSize: 64,\n digestSize: 28,\n };\n return obj;\n });\n}\n\nconst mutex$9 = new Mutex();\nlet wasmCache$9 = null;\n/**\n * Calculates SHA-2 (SHA-256) hash\n * @param data Input data (string, Buffer or TypedArray)\n * @returns Computed hash as a hexadecimal string\n */\nfunction sha256(data) {\n if (wasmCache$9 === null) {\n return lockedCreate(mutex$9, wasmJson$a, 32).then((wasm) => {\n wasmCache$9 = wasm;\n return wasmCache$9.calculate(data, 256);\n });\n }\n try {\n const hash = wasmCache$9.calculate(data, 256);\n return Promise.resolve(hash);\n }\n catch (err) {\n return Promise.reject(err);\n }\n}\n/**\n * Creates a new SHA-2 (SHA-256) hash instance\n */\nfunction createSHA256() {\n return WASMInterface(wasmJson$a, 32).then((wasm) => {\n wasm.init(256);\n const obj = {\n init: () => {\n wasm.init(256);\n return obj;\n },\n update: (data) => {\n wasm.update(data);\n return obj;\n },\n // biome-ignore lint/suspicious/noExplicitAny: Conflict with IHasher type\n digest: (outputType) => wasm.digest(outputType),\n save: () => wasm.save(),\n load: (data) => {\n wasm.load(data);\n return obj;\n },\n blockSize: 64,\n digestSize: 32,\n };\n return obj;\n });\n}\n\nvar name$9 = \"sha512\";\nvar data$9 = \"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\";\nvar hash$9 = \"f2e40eb1\";\nvar wasmJson$9 = {\n\tname: name$9,\n\tdata: data$9,\n\thash: hash$9\n};\n\nconst mutex$8 = new Mutex();\nlet wasmCache$8 = null;\n/**\n * Calculates SHA-2 (SHA-384) hash\n * @param data Input data (string, Buffer or TypedArray)\n * @returns Computed hash as a hexadecimal string\n */\nfunction sha384(data) {\n if (wasmCache$8 === null) {\n return lockedCreate(mutex$8, wasmJson$9, 48).then((wasm) => {\n wasmCache$8 = wasm;\n return wasmCache$8.calculate(data, 384);\n });\n }\n try {\n const hash = wasmCache$8.calculate(data, 384);\n return Promise.resolve(hash);\n }\n catch (err) {\n return Promise.reject(err);\n }\n}\n/**\n * Creates a new SHA-2 (SHA-384) hash instance\n */\nfunction createSHA384() {\n return WASMInterface(wasmJson$9, 48).then((wasm) => {\n wasm.init(384);\n const obj = {\n init: () => {\n wasm.init(384);\n return obj;\n },\n update: (data) => {\n wasm.update(data);\n return obj;\n },\n // biome-ignore lint/suspicious/noExplicitAny: Conflict with IHasher type\n digest: (outputType) => wasm.digest(outputType),\n save: () => wasm.save(),\n load: (data) => {\n wasm.load(data);\n return obj;\n },\n blockSize: 128,\n digestSize: 48,\n };\n return obj;\n });\n}\n\nconst mutex$7 = new Mutex();\nlet wasmCache$7 = null;\n/**\n * Calculates SHA-2 (SHA-512) hash\n * @param data Input data (string, Buffer or TypedArray)\n * @returns Computed hash as a hexadecimal string\n */\nfunction sha512(data) {\n if (wasmCache$7 === null) {\n return lockedCreate(mutex$7, wasmJson$9, 64).then((wasm) => {\n wasmCache$7 = wasm;\n return wasmCache$7.calculate(data, 512);\n });\n }\n try {\n const hash = wasmCache$7.calculate(data, 512);\n return Promise.resolve(hash);\n }\n catch (err) {\n return Promise.reject(err);\n }\n}\n/**\n * Creates a new SHA-2 (SHA-512) hash instance\n */\nfunction createSHA512() {\n return WASMInterface(wasmJson$9, 64).then((wasm) => {\n wasm.init(512);\n const obj = {\n init: () => {\n wasm.init(512);\n return obj;\n },\n update: (data) => {\n wasm.update(data);\n return obj;\n },\n // biome-ignore lint/suspicious/noExplicitAny: Conflict with IHasher type\n digest: (outputType) => wasm.digest(outputType),\n save: () => wasm.save(),\n load: (data) => {\n wasm.load(data);\n return obj;\n },\n blockSize: 128,\n digestSize: 64,\n };\n return obj;\n });\n}\n\nvar name$8 = \"xxhash32\";\nvar data$8 = \"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\";\nvar hash$8 = \"4bb12485\";\nvar wasmJson$8 = {\n\tname: name$8,\n\tdata: data$8,\n\thash: hash$8\n};\n\nconst mutex$6 = new Mutex();\nlet wasmCache$6 = null;\nfunction validateSeed$3(seed) {\n if (!Number.isInteger(seed) || seed < 0 || seed > 0xffffffff) {\n return new Error(\"Seed must be a valid 32-bit long unsigned integer.\");\n }\n return null;\n}\n/**\n * Calculates xxHash32 hash\n * @param data Input data (string, Buffer or TypedArray)\n * @param seed Number used to initialize the internal state of the algorithm (defaults to 0)\n * @returns Computed hash as a hexadecimal string\n */\nfunction xxhash32(data, seed = 0) {\n if (validateSeed$3(seed)) {\n return Promise.reject(validateSeed$3(seed));\n }\n if (wasmCache$6 === null) {\n return lockedCreate(mutex$6, wasmJson$8, 4).then((wasm) => {\n wasmCache$6 = wasm;\n return wasmCache$6.calculate(data, seed);\n });\n }\n try {\n const hash = wasmCache$6.calculate(data, seed);\n return Promise.resolve(hash);\n }\n catch (err) {\n return Promise.reject(err);\n }\n}\n/**\n * Creates a new xxHash32 hash instance\n * @param data Input data (string, Buffer or TypedArray)\n * @param seed Number used to initialize the internal state of the algorithm (defaults to 0)\n */\nfunction createXXHash32(seed = 0) {\n if (validateSeed$3(seed)) {\n return Promise.reject(validateSeed$3(seed));\n }\n return WASMInterface(wasmJson$8, 4).then((wasm) => {\n wasm.init(seed);\n const obj = {\n init: () => {\n wasm.init(seed);\n return obj;\n },\n update: (data) => {\n wasm.update(data);\n return obj;\n },\n // biome-ignore lint/suspicious/noExplicitAny: Conflict with IHasher type\n digest: (outputType) => wasm.digest(outputType),\n save: () => wasm.save(),\n load: (data) => {\n wasm.load(data);\n return obj;\n },\n blockSize: 16,\n digestSize: 4,\n };\n return obj;\n });\n}\n\nvar name$7 = \"xxhash64\";\nvar data$7 = \"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\";\nvar hash$7 = \"177fbfa3\";\nvar wasmJson$7 = {\n\tname: name$7,\n\tdata: data$7,\n\thash: hash$7\n};\n\nconst mutex$5 = new Mutex();\nlet wasmCache$5 = null;\nconst seedBuffer$2 = new Uint8Array(8);\nfunction validateSeed$2(seed) {\n if (!Number.isInteger(seed) || seed < 0 || seed > 0xffffffff) {\n return new Error(\"Seed must be given as two valid 32-bit long unsigned integers (lo + high).\");\n }\n return null;\n}\nfunction writeSeed$2(arr, low, high) {\n // write in little-endian format\n const buffer = new DataView(arr);\n buffer.setUint32(0, low, true);\n buffer.setUint32(4, high, true);\n}\n/**\n * Calculates xxHash64 hash\n * @param data Input data (string, Buffer or TypedArray)\n * @param seedLow Lower 32 bits of the number used to\n * initialize the internal state of the algorithm (defaults to 0)\n * @param seedHigh Higher 32 bits of the number used to\n * initialize the internal state of the algorithm (defaults to 0)\n * @returns Computed hash as a hexadecimal string\n */\nfunction xxhash64(data, seedLow = 0, seedHigh = 0) {\n if (validateSeed$2(seedLow)) {\n return Promise.reject(validateSeed$2(seedLow));\n }\n if (validateSeed$2(seedHigh)) {\n return Promise.reject(validateSeed$2(seedHigh));\n }\n if (wasmCache$5 === null) {\n return lockedCreate(mutex$5, wasmJson$7, 8).then((wasm) => {\n wasmCache$5 = wasm;\n writeSeed$2(seedBuffer$2.buffer, seedLow, seedHigh);\n wasmCache$5.writeMemory(seedBuffer$2);\n return wasmCache$5.calculate(data);\n });\n }\n try {\n writeSeed$2(seedBuffer$2.buffer, seedLow, seedHigh);\n wasmCache$5.writeMemory(seedBuffer$2);\n const hash = wasmCache$5.calculate(data);\n return Promise.resolve(hash);\n }\n catch (err) {\n return Promise.reject(err);\n }\n}\n/**\n * Creates a new xxHash64 hash instance\n * @param seedLow Lower 32 bits of the number used to\n * initialize the internal state of the algorithm (defaults to 0)\n * @param seedHigh Higher 32 bits of the number used to\n * initialize the internal state of the algorithm (defaults to 0)\n */\nfunction createXXHash64(seedLow = 0, seedHigh = 0) {\n if (validateSeed$2(seedLow)) {\n return Promise.reject(validateSeed$2(seedLow));\n }\n if (validateSeed$2(seedHigh)) {\n return Promise.reject(validateSeed$2(seedHigh));\n }\n return WASMInterface(wasmJson$7, 8).then((wasm) => {\n const instanceBuffer = new Uint8Array(8);\n writeSeed$2(instanceBuffer.buffer, seedLow, seedHigh);\n wasm.writeMemory(instanceBuffer);\n wasm.init();\n const obj = {\n init: () => {\n wasm.writeMemory(instanceBuffer);\n wasm.init();\n return obj;\n },\n update: (data) => {\n wasm.update(data);\n return obj;\n },\n // biome-ignore lint/suspicious/noExplicitAny: Conflict with IHasher type\n digest: (outputType) => wasm.digest(outputType),\n save: () => wasm.save(),\n load: (data) => {\n wasm.load(data);\n return obj;\n },\n blockSize: 32,\n digestSize: 8,\n };\n return obj;\n });\n}\n\nvar name$6 = \"xxhash3\";\nvar data$6 = \"AGFzbQEAAAABNAhgAAF/YAR/f39/AGAHf39/f39/fwBgBH9+fn4BfmAEf39/fgF+YAN/f34BfmAAAGABfwADDg0AAQIDBAUFBQYHBgAGBQQBAQICBg4CfwFBwI4FC38AQcAJCwdwCAZtZW1vcnkCAA5IYXNoX0dldEJ1ZmZlcgAACUhhc2hfSW5pdAAIC0hhc2hfVXBkYXRlAAkKSGFzaF9GaW5hbAAKDUhhc2hfR2V0U3RhdGUACw5IYXNoX0NhbGN1bGF0ZQAMClNUQVRFX1NJWkUDAQr6QQ0FAEGACgvkAwMPfgF/AX4CQCADRQ0AIAApAzAhBCAAKQM4IQUgACkDICEGIAApAyghByAAKQMQIQggACkDGCEJIAApAwAhCiAAKQMIIQsDQCAFIAFBMGopAwAiDHwgAkE4aikDACABQThqKQMAIg2FIgVCIIggBUL/////D4N+fCEFIAcgAUEgaikDACIOfCACQShqKQMAIAFBKGopAwAiD4UiB0IgiCAHQv////8Pg358IQcgCSABQRBqKQMAIhB8IAJBGGopAwAgAUEYaikDACIRhSIJQiCIIAlC/////w+DfnwhCSALIAEpAwAiEnwgAkEIaiITKQMAIAFBCGopAwAiFIUiC0IgiCALQv////8Pg358IQsgAkEwaikDACAMhSIMQiCIIAxC/////w+DfiAEfCANfCEEIAJBIGopAwAgDoUiDEIgiCAMQv////8Pg34gBnwgD3whBiACQRBqKQMAIBCFIgxCIIggDEL/////D4N+IAh8IBF8IQggAikDACAShSIMQiCIIAxC/////w+DfiAKfCAUfCEKIAFBwABqIQEgEyECIANBf2oiAw0ACyAAIAk3AxggACAKNwMAIAAgCzcDCCAAIAc3AyggACAINwMQIAAgBTcDOCAAIAY3AyAgACAENwMwCwveAgIBfwF+AkAgBCACIAEoAgAiB2siAkkNACAAIAMgBSAHQQN0aiACEAEgACAFIAZqIgcpAwAgACkDACIIQi+IhSAIhUKx893xCX43AwAgACAHKQMIIAApAwgiCEIviIUgCIVCsfPd8Ql+NwMIIAAgBykDECAAKQMQIghCL4iFIAiFQrHz3fEJfjcDECAAIAcpAxggACkDGCIIQi+IhSAIhUKx893xCX43AxggACAHKQMgIAApAyAiCEIviIUgCIVCsfPd8Ql+NwMgIAAgBykDKCAAKQMoIghCL4iFIAiFQrHz3fEJfjcDKCAAIAcpAzAgACkDMCIIQi+IhSAIhUKx893xCX43AzAgACAHKQM4IAApAzgiCEIviIUgCIVCsfPd8Ql+NwM4IAAgAyACQQZ0aiAFIAQgAmsiBxABIAEgBzYCAA8LIAAgAyAFIAdBA3RqIAQQASABIAcgBGo2AgALhQEBAX8gAiABhSADpyIEQRh0IARBgP4DcUEIdHIgBEEIdkGA/gNxIARBGHZycq1CIIYgA4V9QQA1AoCMAUIghiAAQfyLAWo1AgCEhSIDQjGJIANCGImFIAOFQqW+4/TRjIfZn39+IgNCI4ggAK18IAOFQqW+4/TRjIfZn39+IgNCHIggA4ULZwAgAiABc60gA3wiA0IhiEEALQCAjAFBEHQgAEEIdHIgAEEBdkGAjAFqLQAAQRh0ciAAQf+LAWotAAByrYUgA4VCz9bTvtLHq9lCfiIDQh2IIAOFQvnz3fGZ9pmrFn4iA0IgiCADhQuJAwEEfgJAIABBCUkNAEEAKQOAjAEgASkDICABKQMYhSACfIUiA0I4hiADQoD+A4NCKIaEIANCgID8B4NCGIYgA0KAgID4D4NCCIaEhCADQgiIQoCAgPgPgyADQhiIQoCA/AeDhCADQiiIQoD+A4MgA0I4iISEhCAArXwgAEH4iwFqKQMAIAEpAzAgASkDKIUgAn2FIgJ8IAJC/////w+DIgQgA0IgiCIFfiIGQv////8PgyACQiCIIgIgA0L/////D4MiA358IAQgA34iA0IgiHwiBEIghiADQv////8Pg4QgBkIgiCACIAV+fCAEQiCIfIV8IgNCJYggA4VC+fPd8ZnymasWfiIDQiCIIAOFDwsCQCAAQQRJDQAgACABQQhqKQMAIAFBEGopAwAgAhADDwsCQCAARQ0AIAAgASgCACABQQRqKAIAIAIQBA8LIAEpAzggASkDQIUgAoUiA0IhiCADhULP1tO+0ser2UJ+IgNCHYggA4VC+fPd8Zn2masWfiIDQiCIIAOFC94IAQZ+IACtQoeVr6+Ytt6bnn9+IQMCQCAAQSFJDQACQCAAQcEASQ0AAkAgAEHhAEkNACABKQNoIAJ9QQApA7iMAYUiBEL/////D4MiBSABKQNgIAJ8QQApA7CMAYUiBkIgiCIHfiIIQv////8PgyAEQiCIIgQgBkL/////D4MiBn58IAUgBn4iBUIgiHwiBkIghiAFQv////8Pg4QgCEIgiCAEIAd+fCAGQiCIfIUgA3wgASkDeCACfSAAQciLAWopAwCFIgNC/////w+DIgQgASkDcCACfCAAQcCLAWopAwCFIgVCIIgiBn4iB0L/////D4MgA0IgiCIDIAVC/////w+DIgV+fCAEIAV+IgRCIIh8IgVCIIYgBEL/////D4OEIAdCIIggAyAGfnwgBUIgiHyFfCEDCyABKQNIIAJ9QQApA6iMAYUiBEL/////D4MiBSABKQNAIAJ8QQApA6CMAYUiBkIgiCIHfiIIQv////8PgyAEQiCIIgQgBkL/////D4MiBn58IAUgBn4iBUIgiHwiBkIghiAFQv////8Pg4QgCEIgiCAEIAd+fCAGQiCIfIUgA3wgASkDWCACfSAAQdiLAWopAwCFIgNC/////w+DIgQgASkDUCACfCAAQdCLAWopAwCFIgVCIIgiBn4iB0L/////D4MgA0IgiCIDIAVC/////w+DIgV+fCAEIAV+IgRCIIh8IgVCIIYgBEL/////D4OEIAdCIIggAyAGfnwgBUIgiHyFfCEDCyABKQMoIAJ9QQApA5iMAYUiBEL/////D4MiBSABKQMgIAJ8QQApA5CMAYUiBkIgiCIHfiIIQv////8PgyAEQiCIIgQgBkL/////D4MiBn58IAUgBn4iBUIgiHwiBkIghiAFQv////8Pg4QgCEIgiCAEIAd+fCAGQiCIfIUgA3wgASkDOCACfSAAQeiLAWopAwCFIgNC/////w+DIgQgASkDMCACfCAAQeCLAWopAwCFIgVCIIgiBn4iB0L/////D4MgA0IgiCIDIAVC/////w+DIgV+fCAEIAV+IgRCIIh8IgVCIIYgBEL/////D4OEIAdCIIggAyAGfnwgBUIgiHyFfCEDCyABKQMIIAJ9QQApA4iMAYUiBEL/////D4MiBSABKQMAIAJ8QQApA4CMAYUiBkIgiCIHfiIIQv////8PgyAEQiCIIgQgBkL/////D4MiBn58IAUgBn4iBUIgiHwiBkIghiAFQv////8Pg4QgCEIgiCAEIAd+fCAGQiCIfIUgA3wgASkDGCACfSAAQfiLAWopAwCFIgNC/////w+DIgQgASkDECACfCAAQfCLAWopAwCFIgJCIIgiBX4iBkL/////D4MgA0IgiCIDIAJC/////w+DIgJ+fCAEIAJ+IgJCIIh8IgRCIIYgAkL/////D4OEIAZCIIggAyAFfnwgBEIgiHyFfCICQiWIIAKFQvnz3fGZ8pmrFn4iAkIgiCAChQv8CgQBfwV+An8BfkEAIQMgASkDeCACfUEAKQP4jAGFIgRC/////w+DIgUgASkDcCACfEEAKQPwjAGFIgZCIIgiB34iCEL/////D4MgBEIgiCIEIAZC/////w+DIgZ+fCAFIAZ+IgVCIIh8IgZCIIYgBUL/////D4OEIAhCIIggBCAHfnwgBkIgiHyFIAEpA2ggAn1BACkD6IwBhSIEQv////8PgyIFIAEpA2AgAnxBACkD4IwBhSIGQiCIIgd+IghC/////w+DIARCIIgiBCAGQv////8PgyIGfnwgBSAGfiIFQiCIfCIGQiCGIAVC/////w+DhCAIQiCIIAQgB358IAZCIIh8hSABKQNYIAJ9QQApA9iMAYUiBEL/////D4MiBSABKQNQIAJ8QQApA9CMAYUiBkIgiCIHfiIIQv////8PgyAEQiCIIgQgBkL/////D4MiBn58IAUgBn4iBUIgiHwiBkIghiAFQv////8Pg4QgCEIgiCAEIAd+fCAGQiCIfIUgASkDSCACfUEAKQPIjAGFIgRC/////w+DIgUgASkDQCACfEEAKQPAjAGFIgZCIIgiB34iCEL/////D4MgBEIgiCIEIAZC/////w+DIgZ+fCAFIAZ+IgVCIIh8IgZCIIYgBUL/////D4OEIAhCIIggBCAHfnwgBkIgiHyFIAEpAzggAn1BACkDuIwBhSIEQv////8PgyIFIAEpAzAgAnxBACkDsIwBhSIGQiCIIgd+IghC/////w+DIARCIIgiBCAGQv////8PgyIGfnwgBSAGfiIFQiCIfCIGQiCGIAVC/////w+DhCAIQiCIIAQgB358IAZCIIh8hSABKQMoIAJ9QQApA6iMAYUiBEL/////D4MiBSABKQMgIAJ8QQApA6CMAYUiBkIgiCIHfiIIQv////8PgyAEQiCIIgQgBkL/////D4MiBn58IAUgBn4iBUIgiHwiBkIghiAFQv////8Pg4QgCEIgiCAEIAd+fCAGQiCIfIUgASkDGCACfUEAKQOYjAGFIgRC/////w+DIgUgASkDECACfEEAKQOQjAGFIgZCIIgiB34iCEL/////D4MgBEIgiCIEIAZC/////w+DIgZ+fCAFIAZ+IgVCIIh8IgZCIIYgBUL/////D4OEIAhCIIggBCAHfnwgBkIgiHyFIAEpAwggAn1BACkDiIwBhSIEQv////8PgyIFIAEpAwAgAnxBACkDgIwBhSIGQiCIIgd+IghC/////w+DIARCIIgiBCAGQv////8PgyIGfnwgBSAGfiIFQiCIfCIGQiCGIAVC/////w+DhCAIQiCIIAQgB358IAZCIIh8hSAArUKHla+vmLbem55/fnx8fHx8fHx8IgRCJYggBIVC+fPd8ZnymasWfiIEQiCIIASFIQQCQCAAQZABSA0AIABBBHZBeGohCQNAIAEgA2oiCkELaikDACACfSADQYiNAWopAwCFIgVC/////w+DIgYgCkEDaikDACACfCADQYCNAWopAwCFIgdCIIgiCH4iC0L/////D4MgBUIgiCIFIAdC/////w+DIgd+fCAGIAd+IgZCIIh8IgdCIIYgBkL/////D4OEIAtCIIggBSAIfnwgB0IgiHyFIAR8IQQgA0EQaiEDIAlBf2oiCQ0ACwsgASkDfyACfSAAQfiLAWopAwCFIgVC/////w+DIgYgASkDdyACfCAAQfCLAWopAwCFIgJCIIgiB34iCEL/////D4MgBUIgiCIFIAJC/////w+DIgJ+fCAGIAJ+IgJCIIh8IgZCIIYgAkL/////D4OEIAhCIIggBSAHfnwgBkIgiHyFIAR8IgJCJYggAoVC+fPd8ZnymasWfiICQiCIIAKFC98FAgF+AX8CQAJAQQApA4AKIgBQRQ0AQYAIIQFCACEADAELAkBBACkDoI4BIABSDQBBACEBDAELQQAhAUEAQq+v79e895Kg/gAgAH03A/iLAUEAIABCxZbr+djShYIofDcD8IsBQQBCj/Hjja2P9JhOIAB9NwPoiwFBACAAQqus+MXV79HQfHw3A+CLAUEAQtOt1LKShbW0nn8gAH03A9iLAUEAIABCl5r0jvWWvO3JAHw3A9CLAUEAQsWDgv2v/8SxayAAfTcDyIsBQQAgAELqi7OdyOb09UN8NwPAiwFBAELIv/rLnJveueQAIAB9NwO4iwFBACAAQoqjgd/Ume2sMXw3A7CLAUEAQvm57738+MKnHSAA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QQApA4CKATcDACACQQApA4iKATcDCCACQQApA5CKATcDECACQQApA5iKATcDGCACQQApA6CKATcDICACQQApA6iKATcDKCACQQApA7CKASIFNwMwIAJBACkDuIoBIgY3AzgCQAJAQQAoAoCOASIHQcAASQ0AIAJBACgCiI4BNgJAIAIgAkHAAGpBACgCmI4BQYCMASAHQX9qQQZ2IANBACgCnI4BIgAQAiADIABqIgBBeWopAwAhCCAAKQMJIQkgACkDGSEKIAApAykhCyAHQcCLAWopAwAhBSAAKQMBIQwgB0HIiwFqKQMAIQYgB0HQiwFqKQMAIQ0gACkDESEOIAdB2IsBaikDACEPIAdB4IsBaikDACEQIAApAyEhESAHQeiLAWopAwAhEiACKQMAIRMgAikDECEUIAIpAyAhFSACKQMwIRYgAikDCCEXIAIpAxghGCACKQMoIRkgAiACKQM4IAdB8IsBaikDACIafCAAKQMxIAdB+IsBaikDACIbhSIcQiCIIBxC/////w+Dfnw3AzggGSAQfCARIBKFIhFCIIggEUL/////D4N+fCERIBggDXwgDiAPhSIOQiCIIA5C/////w+DfnwhDiAXIAV8IAwgBoUiDEIgiCAMQv////8Pg358IQwgGyAWIAsgGoUiC0IgiCALQv////8Pg358fCELIBIgFSAKIBCFIhBCIIggEEL/////D4N+fHwhECAPIBQgCSANhSINQiCIIA1C/////w+Dfnx8IRIgBiATIAggBYUiBUIgiCAFQv////8Pg358fCEIDAELIAdBwI0BaiEdQcAAIAdrIR4gAkHAAGohAAJAAkACQCAHQThNDQAgHiEfDAELAkACQEE4IAdrQQN2QQFqQQdxIh8NACACQcAAaiEAIB4hHwwBCyACQcAAaiEAIB9BA3QiICEfA0AgACAdKQMANwMAIABBCGohACAdQQhqIR0gH0F4aiIfDQALQcAAIAcgIGprIR8LAkAgBw0AA0AgACAdKQMANwMAIABBCGogHUEIaikDADcDACAAQRBqIB1BEGopAwA3AwAgAEEYaiAdQRhqKQMANwMAIABBIGogHUEgaikDADcDACAAQShqIB1BKGopAwA3AwAgAEEwaiAdQTBqKQMANwMAIABBOGogHUE4aikDADcDACAAQcAAaiEAIB1BwABqIR0gH0FAaiIfQQdLDQALCyAfRQ0BCyAfQX9qISECQCAfQQdxIiBFDQAgH0F4cSEfA0AgACAdLQAAOgAAIABBAWohACAdQQFqIR0gIEF/aiIgDQALCyAhQQdJDQADQCAAIB0pAAA3AAAgAEEIaiEAIB1BCGohHSAfQXhqIh8NAAsLIAJBwABqIB5qIR1BgIwBIQACQAJAAkAgB0EISQ0AAkAgB0E4akEDdkEBakEHcSIfDQAMAgsgH0EDdCEgQYCMASEAA0AgHSAAKQMANwMAIB1BCGohHSAAQQhqIQAgH0F/aiIfDQALIAcgIGshBwsgB0UNAQJAAkAgB0EHcSIgDQAgByEfDAELIAdBeHEhHwNAIB0gAC0AADoAACAdQQFqIR0gAEEBaiEAICBBf2oiIA0ACwsgB0EISQ0BCwNAIB0gACkAADcAACAdQQhqIR0gAEEIaiEAIB9BeGoiHw0ACwsgA0EAKAKcjgFqIgBBeWopAwAhCiAAKQMJIRMgACkDGSEUIAApAykhCyAAKQMBIQwgACkDESEOIAApAyEhESACKQMAIRUgAikDECEWIAIpAyAhFyACKQMIIRggAikDQCENIAIpA0ghDyACKQMYIRkgAikDUCESIAIpA1ghCCACKQMoIRogAikDYCEQIAIpA2ghCSACIAYgAikDcCIbfCAAKQMxIAIpA3giBoUiHEIgiCAcQv////8Pg358NwM4IBogEHwgESAJhSIRQiCIIBFC/////w+DfnwhESAZIBJ8IA4gCIUiDkIgiCAOQv////8Pg358IQ4gGCANfCAMIA+FIgxCIIggDEL/////D4N+fCEMIAYgCyAbhSILQiCIIAtC/////w+DfiAFfHwhCyAJIBcgFCAQhSIFQiCIIAVC/////w+Dfnx8IRAgCCAWIBMgEoUiBUIgiCAFQv////8Pg358fCESIA8gFSAKIA2FIgVCIIggBUL/////D4N+fHwhCAsgAykDQyACKQM4hSIFQv////8PgyIGIAMpAzsgC4UiC0IgiCINfiIPQv////8PgyAFQiCIIgUgC0L/////D4MiC358IAYgC34iBkIgiHwiC0IghiAGQv////8Pg4QgD0IgiCAFIA1+fCALQiCIfIUgAykDMyARhSIFQv////8PgyIGIAMpAysgEIUiC0IgiCINfiIPQv////8PgyAFQiCIIgUgC0L/////D4MiC358IAYgC34iBkIgiHwiC0IghiAGQv////8Pg4QgD0IgiCAFIA1+fCALQiCIfIUgAykDIyAOhSIFQv////8PgyIGIAMpAxsgEoUiC0IgiCINfiIPQv////8PgyAFQiCIIgUgC0L/////D4MiC358IAYgC34iBkIgiHwiC0IghiAGQv////8Pg4QgD0IgiCAFIA1+fCALQiCIfIUgAykDEyAMhSIFQv////8PgyIGIAMpAwsgCIUiC0IgiCINfiIPQv////8PgyAFQiCIIgUgC0L/////D4MiC358IAYgC34iBkIgiHwiC0IghiAGQv////8Pg4QgD0IgiCAFIA1+fCALQiCIfIUgBEKHla+vmLbem55/fnx8fHwiBEIliCAEhUL5893xmfKZqxZ+IgRCIIggBIUhBAwBCyAEpyEAAkBBACkDoI4BIgRQDQACQCAAQRBLDQAgAEGACCAEEAUhBAwCCwJAIABBgAFLDQAgAEGACCAEEAYhBAwCCyAAQYAIIAQQByEEDAELAkAgAEEQSw0AIAAgA0IAEAUhBAwBCwJAIABBgAFLDQAgACADQgAQBiEEDAELIAAgA0IAEAchBAtBACAEQjiGIARCgP4Dg0IohoQgBEKAgPwHg0IYhiAEQoCAgPgPg0IIhoSEIARCCIhCgICA+A+DIARCGIhCgID8B4OEIARCKIhCgP4DgyAEQjiIhISENwOACiABJAALBgBBgIoBCwIACwvMAQEAQYAIC8QBuP5sOSOkS758AYEs9yGtHN7UbemDkJfbckCkpLezZx/LeeZOzMDleIJa0H3M/3IhuAhGdPdDJI7gNZDmgTomTDwoUruRwwDLiNBlixtTLqNxZEiXog35TjgZ70ap3qzYqPp2P+OcND/53LvHxwtPHYpR4EvNtFkxyJ9+ydl4c2TqxayDNNPrw8WBoP/6E2PrFw3dUbfw2knTFlUmKdRonisWvlh9R6H8j/i40XrQMc5FyzqPlRYEKK/X+8q7S0B+QAIAAA==\";\nvar hash$6 = \"5a2fbdbb\";\nvar wasmJson$6 = {\n\tname: name$6,\n\tdata: data$6,\n\thash: hash$6\n};\n\nconst mutex$4 = new Mutex();\nlet wasmCache$4 = null;\nconst seedBuffer$1 = new Uint8Array(8);\nfunction validateSeed$1(seed) {\n if (!Number.isInteger(seed) || seed < 0 || seed > 0xffffffff) {\n return new Error(\"Seed must be given as two valid 32-bit long unsigned integers (lo + high).\");\n }\n return null;\n}\nfunction writeSeed$1(arr, low, high) {\n // write in little-endian format\n const buffer = new DataView(arr);\n buffer.setUint32(0, low, true);\n buffer.setUint32(4, high, true);\n}\n/**\n * Calculates xxHash3 hash\n * @param data Input data (string, Buffer or TypedArray)\n * @param seedLow Lower 32 bits of the number used to\n * initialize the internal state of the algorithm (defaults to 0)\n * @param seedHigh Higher 32 bits of the number used to\n * initialize the internal state of the algorithm (defaults to 0)\n * @returns Computed hash as a hexadecimal string\n */\nfunction xxhash3(data, seedLow = 0, seedHigh = 0) {\n if (validateSeed$1(seedLow)) {\n return Promise.reject(validateSeed$1(seedLow));\n }\n if (validateSeed$1(seedHigh)) {\n return Promise.reject(validateSeed$1(seedHigh));\n }\n if (wasmCache$4 === null) {\n return lockedCreate(mutex$4, wasmJson$6, 8).then((wasm) => {\n wasmCache$4 = wasm;\n writeSeed$1(seedBuffer$1.buffer, seedLow, seedHigh);\n wasmCache$4.writeMemory(seedBuffer$1);\n return wasmCache$4.calculate(data);\n });\n }\n try {\n writeSeed$1(seedBuffer$1.buffer, seedLow, seedHigh);\n wasmCache$4.writeMemory(seedBuffer$1);\n const hash = wasmCache$4.calculate(data);\n return Promise.resolve(hash);\n }\n catch (err) {\n return Promise.reject(err);\n }\n}\n/**\n * Creates a new xxHash3 hash instance\n * @param seedLow Lower 32 bits of the number used to\n * initialize the internal state of the algorithm (defaults to 0)\n * @param seedHigh Higher 32 bits of the number used to\n * initialize the internal state of the algorithm (defaults to 0)\n */\nfunction createXXHash3(seedLow = 0, seedHigh = 0) {\n if (validateSeed$1(seedLow)) {\n return Promise.reject(validateSeed$1(seedLow));\n }\n if (validateSeed$1(seedHigh)) {\n return Promise.reject(validateSeed$1(seedHigh));\n }\n return WASMInterface(wasmJson$6, 8).then((wasm) => {\n const instanceBuffer = new Uint8Array(8);\n writeSeed$1(instanceBuffer.buffer, seedLow, seedHigh);\n wasm.writeMemory(instanceBuffer);\n wasm.init();\n const obj = {\n init: () => {\n wasm.writeMemory(instanceBuffer);\n wasm.init();\n return obj;\n },\n update: (data) => {\n wasm.update(data);\n return obj;\n },\n // biome-ignore lint/suspicious/noExplicitAny: Conflict with IHasher type\n digest: (outputType) => wasm.digest(outputType),\n save: () => wasm.save(),\n load: (data) => {\n wasm.load(data);\n return obj;\n },\n blockSize: 512,\n digestSize: 8,\n };\n return obj;\n });\n}\n\nvar name$5 = \"xxhash128\";\nvar data$5 = \"AGFzbQEAAAABKwdgAAF/YAR/f39/AGAHf39/f39/fwBgA39/fgF+YAR/f39+AGAAAGABfwADDQwAAQIDBAQEBQYFAAUFBAEBAgIGDgJ/AUHAjgULfwBBwAkLB3AIBm1lbW9yeQIADkhhc2hfR2V0QnVmZmVyAAAJSGFzaF9Jbml0AAcLSGFzaF9VcGRhdGUACApIYXNoX0ZpbmFsAAkNSGFzaF9HZXRTdGF0ZQAKDkhhc2hfQ2FsY3VsYXRlAAsKU1RBVEVfU0laRQMBCqBNDAUAQYAKC+QDAw9+AX8BfgJAIANFDQAgACkDMCEEIAApAzghBSAAKQMgIQYgACkDKCEHIAApAxAhCCAAKQMYIQkgACkDACEKIAApAwghCwNAIAUgAUEwaikDACIMfCACQThqKQMAIAFBOGopAwAiDYUiBUIgiCAFQv////8Pg358IQUgByABQSBqKQMAIg58IAJBKGopAwAgAUEoaikDACIPhSIHQiCIIAdC/////w+DfnwhByAJIAFBEGopAwAiEHwgAkEYaikDACABQRhqKQMAIhGFIglCIIggCUL/////D4N+fCEJIAsgASkDACISfCACQQhqIhMpAwAgAUEIaikDACIUhSILQiCIIAtC/////w+DfnwhCyACQTBqKQMAIAyFIgxCIIggDEL/////D4N+IAR8IA18IQQgAkEgaikDACAOhSIMQiCIIAxC/////w+DfiAGfCAPfCEGIAJBEGopAwAgEIUiDEIgiCAMQv////8Pg34gCHwgEXwhCCACKQMAIBKFIgxCIIggDEL/////D4N+IAp8IBR8IQogAUHAAGohASATIQIgA0F/aiIDDQALIAAgCTcDGCAAIAo3AwAgACALNwMIIAAgBzcDKCAAIAg3AxAgACAFNwM4IAAgBjcDICAAIAQ3AzALC94CAgF/AX4CQCAEIAIgASgCACIHayICSQ0AIAAgAyAFIAdBA3RqIAIQASAAIAUgBmoiBykDACAAKQMAIghCL4iFIAiFQrHz3fEJfjcDACAAIAcpAwggACkDCCIIQi+IhSAIhUKx893xCX43AwggACAHKQMQIAApAxAiCEIviIUgCIVCsfPd8Ql+NwMQIAAgBykDGCAAKQMYIghCL4iFIAiFQrHz3fEJfjcDGCAAIAcpAyAgACkDICIIQi+IhSAIhUKx893xCX43AyAgACAHKQMoIAApAygiCEIviIUgCIVCsfPd8Ql+NwMoIAAgBykDMCAAKQMwIghCL4iFIAiFQrHz3fEJfjcDMCAAIAcpAzggACkDOCIIQi+IhSAIhUKx893xCX43AzggACADIAJBBnRqIAUgBCACayIHEAEgASAHNgIADwsgACADIAUgB0EDdGogBBABIAEgByAEajYCAAvtAwEFfiABKQM4IAApAziFIgNC/////w+DIgQgASkDMCAAKQMwhSIFQiCIIgZ+IgdC/////w+DIANCIIgiAyAFQv////8PgyIFfnwgBCAFfiIEQiCIfCIFQiCGIARC/////w+DhCAHQiCIIAMgBn58IAVCIIh8hSABKQMoIAApAyiFIgNC/////w+DIgQgASkDICAAKQMghSIFQiCIIgZ+IgdC/////w+DIANCIIgiAyAFQv////8PgyIFfnwgBCAFfiIEQiCIfCIFQiCGIARC/////w+DhCAHQiCIIAMgBn58IAVCIIh8hSABKQMYIAApAxiFIgNC/////w+DIgQgASkDECAAKQMQhSIFQiCIIgZ+IgdC/////w+DIANCIIgiAyAFQv////8PgyIFfnwgBCAFfiIEQiCIfCIFQiCGIARC/////w+DhCAHQiCIIAMgBn58IAVCIIh8hSABKQMIIAApAwiFIgNC/////w+DIgQgASkDACAAKQMAhSIFQiCIIgZ+IgdC/////w+DIANCIIgiAyAFQv////8PgyIFfnwgBCAFfiIEQiCIfCIFQiCGIARC/////w+DhCAHQiCIIAMgBn58IAVCIIh8hSACfHx8fCICQiWIIAKFQvnz3fGZ8pmrFn4iAkIgiCAChQu6CAIFfgN/AkAgAUEJSQ0AIAAgAUH4iwFqKQMAIgQgAikDOCACKQMwhSADfIUiBUL/////D4NC95Svrwh+IAVCgICAgHCDfEEAKQOAjAEgAikDKCACKQMghSADfYUgBIUiA0IgiCIEQrHz3fEJfnwgBEKHla+vCH4iBEIgiHwgBEL/////D4MgA0L/////D4MiA0Kx893xCX58IANCh5Wvrwh+IgRCIIh8IgVCIIh8IgNCOIYgA0KA/gODQiiGhCADQoCA/AeDQhiGIANCgICA+A+DQgiGhIQgA0IIiEKAgID4D4MgA0IYiEKAgPwHg4QgA0IoiEKA/gODIANCOIiEhIQgBEL/////D4MgAUF/aq1CNoaEIAVCIIZ8hSIEQiCIIgVCz9bTvgJ+IgZC/////w+DIARC/////w+DIgRCvdzKlQx+fCAEQs/W074CfiIEQiCIfCIHQiCGIghCJYggCCAEQv////8Pg4SFQvnz3fGZ8pmrFn4iBEIgiCAEhTcDACAAIAVCvdzKlQx+IANCz9bTvtLHq9lCfnwgBkIgiHwgB0IgiHwiA0IliCADhUL5893xmfKZqxZ+IgNCIIggA4U3AwgPCwJAIAFBBEkNACAAIAIpAxggAikDEIUgA6ciAkEYdCACQYD+A3FBCHRyIAJBCHZBgP4DcSACQRh2cnKtQiCGIAOFfCABQfyLAWo1AgBCIIZBADUCgIwBhIUiA0IgiCIEIAFBAnRBh5Wvr3hqrSIFfiIGQiCIIARCsfPd8Ql+fCAGQv////8PgyADQv////8PgyIDQrHz3fEJfnwgAyAFfiIDQiCIfCIEQiCIfCAEQiCGIANC/////w+DhCIEQgGGfCIDQiWIIAOFQvnz3fGZ8pmrFn4iBUIgiCAFhTcDCCAAIANCA4ggBIUiA0IjiCADhUKlvuP00YyH2Z9/fiIDQhyIIAOFNwMADwsCQCABRQ0AIAAgAigCBCACKAIAc60gA3wiBEIhiEEALQCAjAFBEHQgAUEIdHIiCSABQQF2QYCMAWotAABBGHRyIgogAUH/iwFqLQAAIgFyIguthSAEhULP1tO+0ser2UJ+IgRCHYggBIVC+fPd8Zn2masWfiIEQiCIIASFNwMAIAAgAigCDCACKAIIc60gA30iA0IhiCABQRh0IAtBgP4DcUEIdHIgCUEIdkGA/gNxIApBGHZyckENd62FIAOFQs/W077Sx6vZQn4iA0IdiCADhUL5893xmfaZqxZ+IgNCIIggA4U3AwgPCyAAIAIpA1AgAikDWIUgA4UiBEIhiCAEhULP1tO+0ser2UJ+IgRCHYggBIVC+fPd8Zn2masWfiIEQiCIIASFNwMIIAAgAikDQCACKQNIhSADhSIDQiGIIAOFQs/W077Sx6vZQn4iA0IdiCADhUL5893xmfaZqxZ+IgNCIIggA4U3AwALwwoBCn4gAa0iBEKHla+vmLbem55/fiEFAkACQCABQSFPDQBCACEGDAELQgAhBwJAIAFBwQBJDQBCACEHAkAgAUHhAEkNACACQfgAaikDACADfSABQciLAWopAwAiCIUiB0L/////D4MiCSACKQNwIAN8IAFBwIsBaikDACIKhSILQiCIIgx+Ig1CIIggB0IgiCIHIAx+fCANQv////8PgyAHIAtC/////w+DIgt+fCAJIAt+IgdCIIh8IglCIIh8QQApA7iMASILQQApA7CMASIMfIUgCUIghiAHQv////8Pg4SFIQcgAkHoAGopAwAgA30gC4UiCUL/////D4MiCyACKQNgIAN8IAyFIgxCIIgiDX4iBkL/////D4MgCUIgiCIJIAxC/////w+DIgx+fCALIAx+IgtCIIh8IgxCIIYgC0L/////D4OEIAZCIIggCSANfnwgDEIgiHyFIAV8IAggCnyFIQULIAJB2ABqKQMAIAN9IAFB2IsBaikDACIIhSIJQv////8PgyIKIAIpA1AgA3wgAUHQiwFqKQMAIguFIgxCIIgiDX4iBkL/////D4MgCUIgiCIJIAxC/////w+DIgx+fCAKIAx+IgpCIIh8IgxCIIYgCkL/////D4OEIAZCIIggCSANfnwgDEIgiHyFIAd8QQApA6iMASIJQQApA6CMASIKfIUhByACQcgAaikDACADfSAJhSIJQv////8PgyIMIAIpA0AgA3wgCoUiCkIgiCINfiIGQv////8PgyAJQiCIIgkgCkL/////D4MiCn58IAwgCn4iCkIgiHwiDEIghiAKQv////8Pg4QgBkIgiCAJIA1+fCAMQiCIfIUgBXwgCCALfIUhBQsgAkE4aikDACADfSABQeiLAWopAwAiCIUiCUL/////D4MiCiACKQMwIAN8IAFB4IsBaikDACILhSIMQiCIIg1+IgZC/////w+DIAlCIIgiCSAMQv////8PgyIMfnwgCiAMfiIKQiCIfCIMQiCGIApC/////w+DhCAGQiCIIAkgDX58IAxCIIh8hSAHfEEAKQOYjAEiB0EAKQOQjAEiCXyFIQYgAkEoaikDACADfSAHhSIHQv////8PgyIKIAIpAyAgA3wgCYUiCUIgiCIMfiINQv////8PgyAHQiCIIgcgCUL/////D4MiCX58IAogCX4iCUIgiHwiCkIghiAJQv////8Pg4QgDUIgiCAHIAx+fCAKQiCIfIUgBXwgCCALfIUhBQsgACACQRhqKQMAIAN9IAFB+IsBaikDACIHhSIIQv////8PgyIJIAIpAxAgA3wgAUHwiwFqKQMAIgqFIgtCIIgiDH4iDUL/////D4MgCEIgiCIIIAtC/////w+DIgt+fCAJIAt+IglCIIh8IgtCIIYgCUL/////D4OEIA1CIIggCCAMfnwgC0IgiHyFIAZ8QQApA4iMASIIQQApA4CMASIJfIUiCyACQQhqKQMAIAN9IAiFIghC/////w+DIgwgAikDACADfCAJhSIJQiCIIg1+IgZC/////w+DIAhCIIgiCCAJQv////8PgyIJfnwgDCAJfiIJQiCIfCIMQiCGIAlC/////w+DhCAGQiCIIAggDX58IAxCIIh8hSAFfCAHIAp8hSIFfCIHQiWIIAeFQvnz3fGZ8pmrFn4iB0IgiCAHhTcDACAAQgAgBUKHla+vmLbem55/fiAEIAN9Qs/W077Sx6vZQn58IAtC49zKlfzO8vWFf358IgNCJYggA4VC+fPd8ZnymasWfiIDQiCIIAOFfTcDCAuhDwMBfxR+An9BACEEIAJB+ABqKQMAIAN9QQApA/iMASIFhSIGQv////8PgyIHIAIpA3AgA3xBACkD8IwBIgiFIglCIIgiCn4iC0L/////D4MgBkIgiCIGIAlC/////w+DIgl+fCAHIAl+IgdCIIh8IglCIIYgB0L/////D4OEIAtCIIggBiAKfnwgCUIgiHyFIAJB2ABqKQMAIAN9QQApA9iMASIHhSIGQv////8PgyIJIAIpA1AgA3xBACkD0IwBIgqFIgtCIIgiDH4iDUL/////D4MgBkIgiCIGIAtC/////w+DIgt+fCAJIAt+IglCIIh8IgtCIIYgCUL/////D4OEIA1CIIggBiAMfnwgC0IgiHyFIAJBOGopAwAgA31BACkDuIwBIgmFIgZC/////w+DIgsgAikDMCADfEEAKQOwjAEiDIUiDUIgiCIOfiIPQv////8PgyAGQiCIIgYgDUL/////D4MiDX58IAsgDX4iC0IgiHwiDUIghiALQv////8Pg4QgD0IgiCAGIA5+fCANQiCIfIUgAkEYaikDACADfUEAKQOYjAEiC4UiBkL/////D4MiDSACKQMQIAN8QQApA5CMASIOhSIPQiCIIhB+IhFC/////w+DIAZCIIgiBiAPQv////8PgyIPfnwgDSAPfiINQiCIfCIPQiCGIA1C/////w+DhCARQiCIIAYgEH58IA9CIIh8hUEAKQOIjAEiDUEAKQOAjAEiD3yFfEEAKQOojAEiEEEAKQOgjAEiEXyFfEEAKQPIjAEiEkEAKQPAjAEiE3yFfEEAKQPojAEiFEEAKQPgjAEiFXyFIgZCJYggBoVC+fPd8ZnymasWfiIGQiCIIAaFIQYgAkHoAGopAwAgA30gFIUiFEL/////D4MiFiACKQNgIAN8IBWFIhVCIIgiF34iGEL/////D4MgFEIgiCIUIBVC/////w+DIhV+fCAWIBV+IhVCIIh8IhZCIIYgFUL/////D4OEIBhCIIggFCAXfnwgFkIgiHyFIAJByABqKQMAIAN9IBKFIhJC/////w+DIhQgAikDQCADfCAThSITQiCIIhV+IhZC/////w+DIBJCIIgiEiATQv////8PgyITfnwgFCATfiITQiCIfCIUQiCGIBNC/////w+DhCAWQiCIIBIgFX58IBRCIIh8hSACQShqKQMAIAN9IBCFIhBC/////w+DIhIgAikDICADfCARhSIRQiCIIhN+IhRC/////w+DIBBCIIgiECARQv////8PgyIRfnwgEiARfiIRQiCIfCISQiCGIBFC/////w+DhCAUQiCIIBAgE358IBJCIIh8hSACQQhqKQMAIAN9IA2FIg1C/////w+DIhAgAikDACADfCAPhSIPQiCIIhF+IhJC/////w+DIA1CIIgiDSAPQv////8PgyIPfnwgECAPfiIPQiCIfCIQQiCGIA9C/////w+DhCASQiCIIA0gEX58IBBCIIh8hSABrSIPQoeVr6+Ytt6bnn9+fCALIA58hXwgCSAMfIV8IAcgCnyFfCAFIAh8hSIFQiWIIAWFQvnz3fGZ8pmrFn4iBUIgiCAFhSEFAkAgAUGgAUgNACABQQV2QXxqIRkDQCACIARqIhpBG2opAwAgA30gBEGYjQFqKQMAIgeFIghC/////w+DIgkgGkETaikDACADfCAEQZCNAWopAwAiCoUiC0IgiCIMfiINQv////8PgyAIQiCIIgggC0L/////D4MiC358IAkgC34iCUIgiHwiC0IghiAJQv////8Pg4QgDUIgiCAIIAx+fCALQiCIfIUgBnwgBEGIjQFqKQMAIgggBEGAjQFqKQMAIgl8hSEGIBpBC2opAwAgA30gCIUiCEL/////D4MiCyAaQQNqKQMAIAN8IAmFIglCIIgiDH4iDUL/////D4MgCEIgiCIIIAlC/////w+DIgl+fCALIAl+IglCIIh8IgtCIIYgCUL/////D4OEIA1CIIggCCAMfnwgC0IgiHyFIAV8IAcgCnyFIQUgBEEgaiEEIBlBf2oiGQ0ACwsgACACQf8AaikDACADfCABQeiLAWopAwAiB4UiCEL/////D4MiCSACKQN3IAN9IAFB4IsBaikDACIKhSILQiCIIgx+Ig1C/////w+DIAhCIIgiCCALQv////8PgyILfnwgCSALfiIJQiCIfCILQiCGIAlC/////w+DhCANQiCIIAggDH58IAtCIIh8hSAGfCABQfiLAWopAwAiBiABQfCLAWopAwAiCHyFIgkgAkHvAGopAwAgA3wgBoUiBkL/////D4MiCyACKQNnIAN9IAiFIghCIIgiDH4iDUL/////D4MgBkIgiCIGIAhC/////w+DIgh+fCALIAh+IghCIIh8IgtCIIYgCEL/////D4OEIA1CIIggBiAMfnwgC0IgiHyFIAV8IAcgCnyFIgZ8IgVCJYggBYVC+fPd8ZnymasWfiIFQiCIIAWFNwMAIABCACAGQoeVr6+Ytt6bnn9+IA8gA31Cz9bTvtLHq9lCfnwgCULj3MqV/M7y9YV/fnwiA0IliCADhUL5893xmfKZqxZ+IgNCIIggA4V9NwMIC98FAgF+AX8CQAJAQQApA4AKIgBQRQ0AQYAIIQFCACEADAELAkBBACkDoI4BIABSDQBBACEBDAELQQAhAUEAQq+v79e895Kg/gAgAH03A/iLAUEAIABCxZbr+djShYIofDcD8IsBQQBCj/Hjja2P9JhOIAB9NwPoiwFBACAAQqus+MXV79HQfHw3A+CLAUEAQtOt1LKShbW0nn8gAH03A9iLAUEAIABCl5r0jvWWvO3JAHw3A9CLAUEAQsWDgv2v/8SxayAAfTcDyIsBQQAgAELqi7OdyOb09UN8NwPAiwFBAELIv/rLnJveueQAIAB9NwO4iwFBACAAQoqjgd/Ume2sMXw3A7CLAUEAQvm57738+MKnHSAAfTcDqIsBQQAgAEKo9dv7s5ynmj98NwOgiwFBAEK4sry3lNW31lggAH03A5iLAUEAIABC8cihuqm0w/zOAHw3A5CLAUEAQoihl9u445SXo38gAH03A4iL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AkHAAGogDGohC0GAjAEhAAJAAkACQCAHQQhJDQACQCAHQThqQQN2QQFqQQdxIg0NAAwCCyANQQN0IQ5BgIwBIQADQCALIAApAwA3AwAgC0EIaiELIABBCGohACANQX9qIg0NAAsgByAOayEHCyAHRQ0BAkACQCAHQQdxIg4NACAHIQ0MAQsgB0F4cSENA0AgCyAALQAAOgAAIAtBAWohCyAAQQFqIQAgDkF/aiIODQALCyAHQQhJDQELA0AgCyAAKQAANwAAIAtBCGohCyAAQQhqIQAgDUF4aiINDQALCyACIAIpAwggAikDQCIIfCADQQAoApyOAWoiACkDASACKQNIIgmFIgpCIIggCkL/////D4N+fDcDCCACIAIpAxggAikDUCIKfCAAKQMRIAIpA1giEIUiEUIgiCARQv////8Pg358NwMYIAIgECAKIAApAwmFIgpCIIggCkL/////D4N+IAIpAxB8fDcDECACIAkgCCAAQXlqKQMAhSIIQiCIIAhC/////w+DfiACKQMAfHw3AwAgACkDGSEIIAIpAyAhCSACIAIpAyggAikDYCIKfCAAKQMhIAIpA2giEIUiEUIgiCARQv////8Pg358NwMoIAIgECAJIAggCoUiCEIgiCAIQv////8Pg358fDcDICACIAYgAikDcCIIfCAAKQMxIAIpA3giBoUiCUIgiCAJQv////8Pg358NwM4IAIgBiAIIAApAymFIghCIIggCEL/////D4N+IAV8fDcDMAsgAiACIANBC2ogBEKHla+vmLbem55/fhADNwNAIAIgAiADQQAoApyOAWpBdWogBELP1tO+0ser2UJ+Qn+FEAM3A0gMAQsgBKchAAJAQQApA6COASIEUA0AAkAgAEEQSw0AIAJBwABqIABBgAggBBAEDAILAkAgAEGAAUsNACACQcAAaiAAQYAIIAQQBQwCCyACQcAAaiAAQYAIIAQQBgwBCwJAIABBEEsNACACQcAAaiAAIANCABAEDAELAkAgAEGAAUsNACACQcAAaiAAIANCABAFDAELIAJBwABqIAAgA0IAEAYLQQAgAikDcDcDuApBACACKQNgNwOoCkEAIAIpA1A3A5gKQQAgAkH4AGopAwA3A8AKQQAgAkHoAGopAwA3A7AKQQAgAkHYAGopAwA3A6AKQQAgAikDSCIEQjiGIARCgP4Dg0IohoQgBEKAgPwHg0IYhiAEQoCAgPgPg0IIhoSEIARCCIhCgICA+A+DIARCGIhCgID8B4OEIARCKIhCgP4DgyAEQjiIhISEIgQ3A4AKQQAgBDcDkApBACACKQNAIgRCOIYgBEKA/gODQiiGhCAEQoCA/AeDQhiGIARCgICA+A+DQgiGhIQgBEIIiEKAgID4D4MgBEIYiEKAgPwHg4QgBEIoiEKA/gODIARCOIiEhIQ3A4gKIAEkAAsGAEGAigELAgALC8wBAQBBgAgLxAG4/mw5I6RLvnwBgSz3Ia0c3tRt6YOQl9tyQKSkt7NnH8t55k7MwOV4glrQfcz/ciG4CEZ090MkjuA1kOaBOiZMPChSu5HDAMuI0GWLG1Muo3FkSJeiDflOOBnvRqnerNio+nY/45w0P/ncu8fHC08dilHgS820WTHIn37J2XhzZOrFrIM00+vDxYGg//oTY+sXDd1Rt/DaSdMWVSYp1GieKxa+WH1HofyP+LjRetAxzkXLOo+VFgQor9f7yrtLQH5AAgAA\";\nvar hash$5 = \"b9ab74e2\";\nvar wasmJson$5 = {\n\tname: name$5,\n\tdata: data$5,\n\thash: hash$5\n};\n\nconst mutex$3 = new Mutex();\nlet wasmCache$3 = null;\nconst seedBuffer = new Uint8Array(8);\nfunction validateSeed(seed) {\n if (!Number.isInteger(seed) || seed < 0 || seed > 0xffffffff) {\n return new Error(\"Seed must be given as two valid 32-bit long unsigned integers (lo + high).\");\n }\n return null;\n}\nfunction writeSeed(arr, low, high) {\n // write in little-endian format\n const buffer = new DataView(arr);\n buffer.setUint32(0, low, true);\n buffer.setUint32(4, high, true);\n}\n/**\n * Calculates xxHash128 hash\n * @param data Input data (string, Buffer or TypedArray)\n * @param seedLow Lower 32 bits of the number used to\n * initialize the internal state of the algorithm (defaults to 0)\n * @param seedHigh Higher 32 bits of the number used to\n * initialize the internal state of the algorithm (defaults to 0)\n * @returns Computed hash as a hexadecimal string\n */\nfunction xxhash128(data, seedLow = 0, seedHigh = 0) {\n if (validateSeed(seedLow)) {\n return Promise.reject(validateSeed(seedLow));\n }\n if (validateSeed(seedHigh)) {\n return Promise.reject(validateSeed(seedHigh));\n }\n if (wasmCache$3 === null) {\n return lockedCreate(mutex$3, wasmJson$5, 16).then((wasm) => {\n wasmCache$3 = wasm;\n writeSeed(seedBuffer.buffer, seedLow, seedHigh);\n wasmCache$3.writeMemory(seedBuffer);\n return wasmCache$3.calculate(data);\n });\n }\n try {\n writeSeed(seedBuffer.buffer, seedLow, seedHigh);\n wasmCache$3.writeMemory(seedBuffer);\n const hash = wasmCache$3.calculate(data);\n return Promise.resolve(hash);\n }\n catch (err) {\n return Promise.reject(err);\n }\n}\n/**\n * Creates a new xxHash128 hash instance\n * @param seedLow Lower 32 bits of the number used to\n * initialize the internal state of the algorithm (defaults to 0)\n * @param seedHigh Higher 32 bits of the number used to\n * initialize the internal state of the algorithm (defaults to 0)\n */\nfunction createXXHash128(seedLow = 0, seedHigh = 0) {\n if (validateSeed(seedLow)) {\n return Promise.reject(validateSeed(seedLow));\n }\n if (validateSeed(seedHigh)) {\n return Promise.reject(validateSeed(seedHigh));\n }\n return WASMInterface(wasmJson$5, 16).then((wasm) => {\n const instanceBuffer = new Uint8Array(8);\n writeSeed(instanceBuffer.buffer, seedLow, seedHigh);\n wasm.writeMemory(instanceBuffer);\n wasm.init();\n const obj = {\n init: () => {\n wasm.writeMemory(instanceBuffer);\n wasm.init();\n return obj;\n },\n update: (data) => {\n wasm.update(data);\n return obj;\n },\n // biome-ignore lint/suspicious/noExplicitAny: Conflict with IHasher type\n digest: (outputType) => wasm.digest(outputType),\n save: () => wasm.save(),\n load: (data) => {\n wasm.load(data);\n return obj;\n },\n blockSize: 512,\n digestSize: 16,\n };\n return obj;\n });\n}\n\nvar name$4 = \"ripemd160\";\nvar data$4 = \"AGFzbQEAAAABEQRgAAF/YAAAYAF/AGACf38AAwkIAAECAwIBAAIFBAEBAgIGDgJ/AUHgiQULfwBBgAgLB4MBCQZtZW1vcnkCAA5IYXNoX0dldEJ1ZmZlcgAACUhhc2hfSW5pdAABEHJpcGVtZDE2MF91cGRhdGUAAwtIYXNoX1VwZGF0ZQAECkhhc2hfRmluYWwABQ1IYXNoX0dldFN0YXRlAAYOSGFzaF9DYWxjdWxhdGUABwpTVEFURV9TSVpFAwEKzzIIBQBBgAkLOgBBAEHww8uefDYCmIkBQQBC/rnrxemOlZkQNwKQiQFBAEKBxpS6lvHq5m83AoiJAUEAQgA3AoCJAQuPLAEhf0EAIAAoAiQiASAAKAIAIgIgACgCECIDIAIgACgCLCIEIAAoAgwiBSAAKAIEIgYgACgCPCIHIAIgACgCMCIIIAcgACgCCCIJQQAoAoiJASIKQQAoApCJASILQQAoApSJASIMQX9zckEAKAKMiQEiDXNqIAAoAhQiDmpB5peKhQVqQQh3QQAoApiJASIPaiIQQQp3IhFqIAEgDUEKdyISaiACIAtBCnciE2ogDCAAKAIcIhRqIA8gACgCOCIVaiAQIA0gE0F/c3JzakHml4qFBWpBCXcgDGoiFiAQIBJBf3Nyc2pB5peKhQVqQQl3IBNqIhAgFiARQX9zcnNqQeaXioUFakELdyASaiIXIBAgFkEKdyIWQX9zcnNqQeaXioUFakENdyARaiIYIBcgEEEKdyIZQX9zcnNqQeaXioUFakEPdyAWaiIaQQp3IhtqIAAoAhgiECAYQQp3IhxqIAAoAjQiESAXQQp3IhdqIAMgGWogBCAWaiAaIBggF0F/c3JzakHml4qFBWpBD3cgGWoiFiAaIBxBf3Nyc2pB5peKhQVqQQV3IBdqIhcgFiAbQX9zcnNqQeaXioUFakEHdyAcaiIYIBcgFkEKdyIZQX9zcnNqQeaXioUFakEHdyAbaiIaIBggF0EKdyIXQX9zcnNqQeaXioUFakEIdyAZaiIbQQp3IhxqIAUgGkEKdyIdaiAAKAIoIhYgGEEKdyIYaiAGIBdqIAAoAiAiACAZaiAbIBogGEF/c3JzakHml4qFBWpBC3cgF2oiFyAbIB1Bf3Nyc2pB5peKhQVqQQ53IBhqIhggFyAcQX9zcnNqQeaXioUFakEOdyAdaiIZIBggF0EKdyIaQX9zcnNqQeaXioUFakEMdyAcaiIbIBkgGEEKdyIcQX9zcnNqQeaXioUFakEGdyAaaiIdQQp3IhdqIAUgGUEKdyIYaiAQIBpqIBsgGEF/c3FqIB0gGHFqQaSit+IFakEJdyAcaiIaIBdBf3NxaiAEIBxqIB0gG0EKdyIZQX9zcWogGiAZcWpBpKK34gVqQQ13IBhqIhsgF3FqQaSit+IFakEPdyAZaiIcIBtBCnciGEF/c3FqIBQgGWogGyAaQQp3IhlBf3NxaiAcIBlxakGkorfiBWpBB3cgF2oiGyAYcWpBpKK34gVqQQx3IBlqIh1BCnciF2ogFiAcQQp3IhpqIBEgGWogGyAaQX9zcWogHSAacWpBpKK34gVqQQh3IBhqIhwgF0F/c3FqIA4gGGogHSAbQQp3IhhBf3NxaiAcIBhxakGkorfiBWpBCXcgGmoiGiAXcWpBpKK34gVqQQt3IBhqIhsgGkEKdyIZQX9zcWogFSAYaiAaIBxBCnciGEF/c3FqIBsgGHFqQaSit+IFakEHdyAXaiIcIBlxakGkorfiBWpBB3cgGGoiHUEKdyIXaiADIBtBCnciGmogACAYaiAcIBpBf3NxaiAdIBpxakGkorfiBWpBDHcgGWoiGyAXQX9zcWogCCAZaiAdIBxBCnciGEF/c3FqIBsgGHFqQaSit+IFakEHdyAaaiIaIBdxakGkorfiBWpBBncgGGoiHCAaQQp3IhlBf3NxaiABIBhqIBogG0EKdyIYQX9zcWogHCAYcWpBpKK34gVqQQ93IBdqIhogGXFqQaSit+IFakENdyAYaiIbQQp3Ih1qIAYgGkEKdyIeaiAOIBxBCnciF2ogByAZaiAJIBhqIBogF0F/c3FqIBsgF3FqQaSit+IFakELdyAZaiIYIBtBf3NyIB5zakHz/cDrBmpBCXcgF2oiFyAYQX9zciAdc2pB8/3A6wZqQQd3IB5qIhkgF0F/c3IgGEEKdyIYc2pB8/3A6wZqQQ93IB1qIhogGUF/c3IgF0EKdyIXc2pB8/3A6wZqQQt3IBhqIhtBCnciHGogASAaQQp3Ih1qIBAgGUEKdyIZaiAVIBdqIBQgGGogGyAaQX9zciAZc2pB8/3A6wZqQQh3IBdqIhcgG0F/c3IgHXNqQfP9wOsGakEGdyAZaiIYIBdBf3NyIBxzakHz/cDrBmpBBncgHWoiGSAYQX9zciAXQQp3IhdzakHz/cDrBmpBDncgHGoiGiAZQX9zciAYQQp3IhhzakHz/cDrBmpBDHcgF2oiG0EKdyIcaiAWIBpBCnciHWogCSAZQQp3IhlqIAggGGogACAXaiAbIBpBf3NyIBlzakHz/cDrBmpBDXcgGGoiFyAbQX9zciAdc2pB8/3A6wZqQQV3IBlqIhggF0F/c3IgHHNqQfP9wOsGakEOdyAdaiIZIBhBf3NyIBdBCnciF3NqQfP9wOsGakENdyAcaiIaIBlBf3NyIBhBCnciGHNqQfP9wOsGakENdyAXaiIbQQp3IhxqIBEgGGogAyAXaiAbIBpBf3NyIBlBCnciGXNqQfP9wOsGakEHdyAYaiIYIBtBf3NyIBpBCnciGnNqQfP9wOsGakEFdyAZaiIXQQp3IhsgECAaaiAYQQp3Ih0gACAZaiAcIBdBf3NxaiAXIBhxakHp7bXTB2pBD3cgGmoiGEF/c3FqIBggF3FqQenttdMHakEFdyAcaiIXQX9zcWogFyAYcWpB6e210wdqQQh3IB1qIhlBCnciGmogBSAbaiAXQQp3IhwgBiAdaiAYQQp3Ih0gGUF/c3FqIBkgF3FqQenttdMHakELdyAbaiIXQX9zcWogFyAZcWpB6e210wdqQQ53IB1qIhhBCnciGyAHIBxqIBdBCnciHiAEIB1qIBogGEF/c3FqIBggF3FqQenttdMHakEOdyAcaiIXQX9zcWogFyAYcWpB6e210wdqQQZ3IBpqIhhBf3NxaiAYIBdxakHp7bXTB2pBDncgHmoiGUEKdyIaaiAIIBtqIBhBCnciHCAOIB5qIBdBCnciHSAZQX9zcWogGSAYcWpB6e210wdqQQZ3IBtqIhdBf3NxaiAXIBlxakHp7bXTB2pBCXcgHWoiGEEKdyIbIBEgHGogF0EKdyIeIAkgHWogGiAYQX9zcWogGCAXcWpB6e210wdqQQx3IBxqIhdBf3NxaiAXIBhxakHp7bXTB2pBCXcgGmoiGEF/c3FqIBggF3FqQenttdMHakEMdyAeaiIZQQp3IhogB2ogFSAXQQp3IhxqIBogFiAbaiAYQQp3Ih0gFCAeaiAcIBlBf3NxaiAZIBhxakHp7bXTB2pBBXcgG2oiF0F/c3FqIBcgGXFqQenttdMHakEPdyAcaiIYQX9zcWogGCAXcWpB6e210wdqQQh3IB1qIhkgGEEKdyIbcyAdIAhqIBggF0EKdyIXcyAZc2pBCHcgGmoiGHNqQQV3IBdqIhpBCnciHCAAaiAZQQp3IhkgBmogFyAWaiAYIBlzIBpzakEMdyAbaiIXIBxzIBsgA2ogGiAYQQp3IhhzIBdzakEJdyAZaiIZc2pBDHcgGGoiGiAZQQp3IhtzIBggDmogGSAXQQp3IhdzIBpzakEFdyAcaiIYc2pBDncgF2oiGUEKdyIcIBVqIBpBCnciGiAJaiAXIBRqIBggGnMgGXNqQQZ3IBtqIhcgHHMgGyAQaiAZIBhBCnciGHMgF3NqQQh3IBpqIhlzakENdyAYaiIaIBlBCnciG3MgGCARaiAZIBdBCnciGHMgGnNqQQZ3IBxqIhlzakEFdyAYaiIcQQp3Ih0gDGogBCAWIA4gDiARIBYgDiAUIAEgACABIBAgFCAEIBAgBiAPaiATIA1zIAsgDXMgDHMgCmogAmpBC3cgD2oiF3NqQQ53IAxqIh5BCnciH2ogAyASaiAJIAxqIBcgEnMgHnNqQQ93IBNqIgwgH3MgBSATaiAeIBdBCnciE3MgDHNqQQx3IBJqIhJzakEFdyATaiIXIBJBCnciHnMgEyAOaiASIAxBCnciDHMgF3NqQQh3IB9qIhJzakEHdyAMaiITQQp3Ih9qIAEgF0EKdyIXaiAMIBRqIBIgF3MgE3NqQQl3IB5qIgwgH3MgHiAAaiATIBJBCnciEnMgDHNqQQt3IBdqIhNzakENdyASaiIXIBNBCnciHnMgEiAWaiATIAxBCnciDHMgF3NqQQ53IB9qIhJzakEPdyAMaiITQQp3Ih9qIB4gEWogEyASQQp3IiBzIAwgCGogEiAXQQp3IgxzIBNzakEGdyAeaiISc2pBB3cgDGoiE0EKdyIXICAgB2ogEyASQQp3Ih5zIAwgFWogEiAfcyATc2pBCXcgIGoiE3NqQQh3IB9qIgxBf3NxaiAMIBNxakGZ84nUBWpBB3cgHmoiEkEKdyIfaiARIBdqIAxBCnciICADIB5qIBNBCnciEyASQX9zcWogEiAMcWpBmfOJ1AVqQQZ3IBdqIgxBf3NxaiAMIBJxakGZ84nUBWpBCHcgE2oiEkEKdyIXIBYgIGogDEEKdyIeIAYgE2ogHyASQX9zcWogEiAMcWpBmfOJ1AVqQQ13ICBqIgxBf3NxaiAMIBJxakGZ84nUBWpBC3cgH2oiEkF/c3FqIBIgDHFqQZnzidQFakEJdyAeaiITQQp3Ih9qIAUgF2ogEkEKdyIgIAcgHmogDEEKdyIeIBNBf3NxaiATIBJxakGZ84nUBWpBB3cgF2oiDEF/c3FqIAwgE3FqQZnzidQFakEPdyAeaiISQQp3IhcgAiAgaiAMQQp3IiEgCCAeaiAfIBJBf3NxaiASIAxxakGZ84nUBWpBB3cgIGoiDEF/c3FqIAwgEnFqQZnzidQFakEMdyAfaiISQX9zcWogEiAMcWpBmfOJ1AVqQQ93ICFqIhNBCnciHmogCSAXaiASQQp3Ih8gDiAhaiAMQQp3IiAgE0F/c3FqIBMgEnFqQZnzidQFakEJdyAXaiIMQX9zcWogDCATcWpBmfOJ1AVqQQt3ICBqIhJBCnciEyAEIB9qIAxBCnciFyAVICBqIB4gEkF/c3FqIBIgDHFqQZnzidQFakEHdyAfaiIMQX9zcWogDCAScWpBmfOJ1AVqQQ13IB5qIhJBf3MiIHFqIBIgDHFqQZnzidQFakEMdyAXaiIeQQp3Ih9qIAMgEkEKdyISaiAVIAxBCnciDGogFiATaiAFIBdqIB4gIHIgDHNqQaHX5/YGakELdyATaiITIB5Bf3NyIBJzakGh1+f2BmpBDXcgDGoiDCATQX9zciAfc2pBodfn9gZqQQZ3IBJqIhIgDEF/c3IgE0EKdyITc2pBodfn9gZqQQd3IB9qIhcgEkF/c3IgDEEKdyIMc2pBodfn9gZqQQ53IBNqIh5BCnciH2ogCSAXQQp3IiBqIAYgEkEKdyISaiAAIAxqIAcgE2ogHiAXQX9zciASc2pBodfn9gZqQQl3IAxqIgwgHkF/c3IgIHNqQaHX5/YGakENdyASaiISIAxBf3NyIB9zakGh1+f2BmpBD3cgIGoiEyASQX9zciAMQQp3IgxzakGh1+f2BmpBDncgH2oiFyATQX9zciASQQp3IhJzakGh1+f2BmpBCHcgDGoiHkEKdyIfaiAEIBdBCnciIGogESATQQp3IhNqIBAgEmogAiAMaiAeIBdBf3NyIBNzakGh1+f2BmpBDXcgEmoiDCAeQX9zciAgc2pBodfn9gZqQQZ3IBNqIhIgDEF/c3IgH3NqQaHX5/YGakEFdyAgaiITIBJBf3NyIAxBCnciF3NqQaHX5/YGakEMdyAfaiIeIBNBf3NyIBJBCnciEnNqQaHX5/YGakEHdyAXaiIfQQp3IgxqIAEgE0EKdyITaiAIIBdqIB8gHkF/c3IgE3NqQaHX5/YGakEFdyASaiIXIAxBf3NxaiAGIBJqIB8gHkEKdyISQX9zcWogFyAScWpB3Pnu+HhqQQt3IBNqIh4gDHFqQdz57vh4akEMdyASaiIfIB5BCnciE0F/c3FqIAQgEmogHiAXQQp3IhJBf3NxaiAfIBJxakHc+e74eGpBDncgDGoiHiATcWpB3Pnu+HhqQQ93IBJqIiBBCnciDGogCCAfQQp3IhdqIAIgEmogHiAXQX9zcWogICAXcWpB3Pnu+HhqQQ53IBNqIh8gDEF/c3FqIAAgE2ogICAeQQp3IhJBf3NxaiAfIBJxakHc+e74eGpBD3cgF2oiFyAMcWpB3Pnu+HhqQQl3IBJqIh4gF0EKdyITQX9zcWogAyASaiAXIB9BCnciEkF/c3FqIB4gEnFqQdz57vh4akEIdyAMaiIfIBNxakHc+e74eGpBCXcgEmoiIEEKdyIMaiAHIB5BCnciF2ogBSASaiAfIBdBf3NxaiAgIBdxakHc+e74eGpBDncgE2oiHiAMQX9zcWogFCATaiAgIB9BCnciEkF/c3FqIB4gEnFqQdz57vh4akEFdyAXaiIXIAxxakHc+e74eGpBBncgEmoiHyAXQQp3IhNBf3NxaiAVIBJqIBcgHkEKdyISQX9zcWogHyAScWpB3Pnu+HhqQQh3IAxqIhcgE3FqQdz57vh4akEGdyASaiIeQQp3IiBqIAIgF0EKdyIOaiADIB9BCnciDGogCSATaiAeIA5Bf3NxaiAQIBJqIBcgDEF/c3FqIB4gDHFqQdz57vh4akEFdyATaiIDIA5xakHc+e74eGpBDHcgDGoiDCADICBBf3Nyc2pBzvrPynpqQQl3IA5qIg4gDCADQQp3IgNBf3Nyc2pBzvrPynpqQQ93ICBqIhIgDiAMQQp3IgxBf3Nyc2pBzvrPynpqQQV3IANqIhNBCnciF2ogCSASQQp3IhZqIAggDkEKdyIJaiAUIAxqIAEgA2ogEyASIAlBf3Nyc2pBzvrPynpqQQt3IAxqIgMgEyAWQX9zcnNqQc76z8p6akEGdyAJaiIIIAMgF0F/c3JzakHO+s/KempBCHcgFmoiCSAIIANBCnciA0F/c3JzakHO+s/KempBDXcgF2oiDiAJIAhBCnciCEF/c3JzakHO+s/KempBDHcgA2oiFEEKdyIWaiAAIA5BCnciDGogBSAJQQp3IgBqIAYgCGogFSADaiAUIA4gAEF/c3JzakHO+s/KempBBXcgCGoiAyAUIAxBf3Nyc2pBzvrPynpqQQx3IABqIgAgAyAWQX9zcnNqQc76z8p6akENdyAMaiIGIAAgA0EKdyIDQX9zcnNqQc76z8p6akEOdyAWaiIIIAYgAEEKdyIAQX9zcnNqQc76z8p6akELdyADaiIJQQp3IhVqNgKQiQFBACALIBggAmogGSAaQQp3IgJzIBxzakEPdyAbaiIOQQp3IhZqIBAgA2ogCSAIIAZBCnciA0F/c3JzakHO+s/KempBCHcgAGoiBkEKd2o2AoyJAUEAIA0gGyAFaiAcIBlBCnciBXMgDnNqQQ13IAJqIhRBCndqIAcgAGogBiAJIAhBCnciAEF/c3JzakHO+s/KempBBXcgA2oiB2o2AoiJAUEAIAAgCmogAiABaiAOIB1zIBRzakELdyAFaiIBaiARIANqIAcgBiAVQX9zcnNqQc76z8p6akEGd2o2ApiJAUEAIAAgD2ogHWogBSAEaiAUIBZzIAFzakELd2o2ApSJAQuiAwEIfwJAIAFFDQBBACECQQBBACgCgIkBIgMgAWoiBDYCgIkBIANBP3EhBQJAIAQgA08NAEEAQQAoAoSJAUEBajYChIkBCwJAIAVFDQACQCABQcAAIAVrIgZPDQAgBSECDAELIAZBA3EhB0EAIQMCQCAFQT9zQQNJDQAgBUGAiQFqIQggBkH8AHEhCUEAIQMDQCAIIANqIgJBHGogACADaiIELQAAOgAAIAJBHWogBEEBai0AADoAACACQR5qIARBAmotAAA6AAAgAkEfaiAEQQNqLQAAOgAAIAkgA0EEaiIDRw0ACwsCQCAHRQ0AIAAgA2ohAiADIAVqQZyJAWohAwNAIAMgAi0AADoAACACQQFqIQIgA0EBaiEDIAdBf2oiBw0ACwtBnIkBEAIgASAGayEBIAAgBmohAEEAIQILAkAgAUHAAEkNAANAIAAQAiAAQcAAaiEAIAFBQGoiAUE/Sw0ACwsgAUUNACACQZyJAWohA0EAIQIDQCADIAAtAAA6AAAgAEEBaiEAIANBAWohAyABIAJBAWoiAkH/AXFLDQALCwsJAEGACSAAEAMLggEBAn8jAEEQayIAJAAgAEEAKAKAiQEiAUEDdDYCCCAAQQAoAoSJAUEDdCABQR12cjYCDEGQCEE4QfgAIAFBP3EiAUE4SRsgAWsQAyAAQQhqQQgQA0EAQQAoAoiJATYCgAlBAEEAKQKMiQE3AoQJQQBBACkClIkBNwKMCSAAQRBqJAALBgBBgIkBC8EBAQF/IwBBEGsiASQAQQBB8MPLnnw2ApiJAUEAQv6568XpjpWZEDcCkIkBQQBCgcaUupbx6uZvNwKIiQFBAEIANwKAiQFBgAkgABADIAFBACgCgIkBIgBBA3Q2AgggAUEAKAKEiQFBA3QgAEEddnI2AgxBkAhBOEH4ACAAQT9xIgBBOEkbIABrEAMgAUEIakEIEANBAEEAKAKIiQE2AoAJQQBBACkCjIkBNwKECUEAQQApApSJATcCjAkgAUEQaiQACwtXAQBBgAgLUFwAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\";\nvar hash$4 = \"6abbce74\";\nvar wasmJson$4 = {\n\tname: name$4,\n\tdata: data$4,\n\thash: hash$4\n};\n\nconst mutex$2 = new Mutex();\nlet wasmCache$2 = null;\n/**\n * Calculates RIPEMD-160 hash\n * @param data Input data (string, Buffer or TypedArray)\n * @returns Computed hash as a hexadecimal string\n */\nfunction ripemd160(data) {\n if (wasmCache$2 === null) {\n return lockedCreate(mutex$2, wasmJson$4, 20).then((wasm) => {\n wasmCache$2 = wasm;\n return wasmCache$2.calculate(data);\n });\n }\n try {\n const hash = wasmCache$2.calculate(data);\n return Promise.resolve(hash);\n }\n catch (err) {\n return Promise.reject(err);\n }\n}\n/**\n * Creates a new RIPEMD-160 hash instance\n */\nfunction createRIPEMD160() {\n return WASMInterface(wasmJson$4, 20).then((wasm) => {\n wasm.init();\n const obj = {\n init: () => {\n wasm.init();\n return obj;\n },\n update: (data) => {\n wasm.update(data);\n return obj;\n },\n // biome-ignore lint/suspicious/noExplicitAny: Conflict with IHasher type\n digest: (outputType) => wasm.digest(outputType),\n save: () => wasm.save(),\n load: (data) => {\n wasm.load(data);\n return obj;\n },\n blockSize: 64,\n digestSize: 20,\n };\n return obj;\n });\n}\n\nfunction calculateKeyBuffer(hasher, key) {\n const { blockSize } = hasher;\n const buf = getUInt8Buffer(key);\n if (buf.length > blockSize) {\n hasher.update(buf);\n const uintArr = hasher.digest(\"binary\");\n hasher.init();\n return uintArr;\n }\n return new Uint8Array(buf.buffer, buf.byteOffset, buf.length);\n}\nfunction calculateHmac(hasher, key) {\n hasher.init();\n const { blockSize } = hasher;\n const keyBuf = calculateKeyBuffer(hasher, key);\n const keyBuffer = new Uint8Array(blockSize);\n keyBuffer.set(keyBuf);\n const opad = new Uint8Array(blockSize);\n for (let i = 0; i < blockSize; i++) {\n const v = keyBuffer[i];\n opad[i] = v ^ 0x5c;\n keyBuffer[i] = v ^ 0x36;\n }\n hasher.update(keyBuffer);\n const obj = {\n init: () => {\n hasher.init();\n hasher.update(keyBuffer);\n return obj;\n },\n update: (data) => {\n hasher.update(data);\n return obj;\n },\n digest: ((outputType) => {\n const uintArr = hasher.digest(\"binary\");\n hasher.init();\n hasher.update(opad);\n hasher.update(uintArr);\n return hasher.digest(outputType);\n // biome-ignore lint/suspicious/noExplicitAny: Conflict with IHasher type\n }),\n save: () => {\n throw new Error(\"save() not supported\");\n },\n load: () => {\n throw new Error(\"load() not supported\");\n },\n blockSize: hasher.blockSize,\n digestSize: hasher.digestSize,\n };\n return obj;\n}\n/**\n * Calculates HMAC hash\n * @param hash Hash algorithm to use. It has to be the return value of a function like createSHA1()\n * @param key Key (string, Buffer or TypedArray)\n */\nfunction createHMAC(hash, key) {\n if (!hash || !hash.then) {\n throw new Error('Invalid hash function is provided! Usage: createHMAC(createMD5(), \"key\").');\n }\n return hash.then((hasher) => calculateHmac(hasher, key));\n}\n\nfunction calculatePBKDF2(digest, salt, iterations, hashLength, outputType) {\n return __awaiter(this, void 0, void 0, function* () {\n const DK = new Uint8Array(hashLength);\n const block1 = new Uint8Array(salt.length + 4);\n const block1View = new DataView(block1.buffer);\n const saltBuffer = getUInt8Buffer(salt);\n const saltUIntBuffer = new Uint8Array(saltBuffer.buffer, saltBuffer.byteOffset, saltBuffer.length);\n block1.set(saltUIntBuffer);\n let destPos = 0;\n const hLen = digest.digestSize;\n const l = Math.ceil(hashLength / hLen);\n let T = null;\n let U = null;\n for (let i = 1; i <= l; i++) {\n block1View.setUint32(salt.length, i);\n digest.init();\n digest.update(block1);\n T = digest.digest(\"binary\");\n U = T.slice();\n for (let j = 1; j < iterations; j++) {\n digest.init();\n digest.update(U);\n U = digest.digest(\"binary\");\n for (let k = 0; k < hLen; k++) {\n T[k] ^= U[k];\n }\n }\n DK.set(T.subarray(0, hashLength - destPos), destPos);\n destPos += hLen;\n }\n if (outputType === \"binary\") {\n return DK;\n }\n const digestChars = new Uint8Array(hashLength * 2);\n return getDigestHex(digestChars, DK, hashLength);\n });\n}\nconst validateOptions$2 = (options) => {\n if (!options || typeof options !== \"object\") {\n throw new Error(\"Invalid options parameter. It requires an object.\");\n }\n if (!options.hashFunction || !options.hashFunction.then) {\n throw new Error('Invalid hash function is provided! Usage: pbkdf2(\"password\", \"salt\", 1000, 32, createSHA1()).');\n }\n if (!Number.isInteger(options.iterations) || options.iterations < 1) {\n throw new Error(\"Iterations should be a positive number\");\n }\n if (!Number.isInteger(options.hashLength) || options.hashLength < 1) {\n throw new Error(\"Hash length should be a positive number\");\n }\n if (options.outputType === undefined) {\n options.outputType = \"hex\";\n }\n if (![\"hex\", \"binary\"].includes(options.outputType)) {\n throw new Error(`Insupported output type ${options.outputType}. Valid values: ['hex', 'binary']`);\n }\n};\n/**\n * Generates a new PBKDF2 hash for the supplied password\n */\nfunction pbkdf2(options) {\n return __awaiter(this, void 0, void 0, function* () {\n validateOptions$2(options);\n const hmac = yield createHMAC(options.hashFunction, options.password);\n return calculatePBKDF2(hmac, options.salt, options.iterations, options.hashLength, options.outputType);\n });\n}\n\nvar name$3 = \"scrypt\";\nvar data$3 = \"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cyICajYCOCAAIAAoAjwgAiAKakESdyAGc2o2AjwLvxIDFX8Bfg5/AkAgAkUNACAAQQd0IgNBQGoiBEEAKAKACCIFIAMgAmwiBmogAyABbGoiByADaiIIaiEJIAAgAkEHdCIKIAFBB3RqIgtsIQwgACALQYABamwhDSAAQQV0IgtBASALQQFLGyILQWBxIQ4gC0EBcSEPIAdBeGohECAHQXBqIREgB0FoaiESIAdBYGohEyAHQVhqIRQgB0FQaiEVIAdBSGohFiAHQUBqIRcgAa1Cf3whGCAEIAdqIRkgByAAQQh0IhpqIRsgACAKQYABamwhHCALQQRJIR1BACEeQQAhHwNAQQAoAoAIIiAgAyAfbGohIQJAIABFDQBBACEiAkAgHQ0AICAgHmohI0EAIQtBACEiA0AgByALaiIEICMgC2oiJCgCADYCACAEQQRqICRBBGooAgA2AgAgBEEIaiAkQQhqKAIANgIAIARBDGogJEEMaigCADYCACALQRBqIQsgDiAiQQRqIiJHDQALCyAPRQ0AIAcgIkECdCILaiAhIAtqKAIANgIACwJAIAFFDQBBACElIBwhIyAGISYDQCAFISQgACEiAkACQCAADQAgGyAXKQMANwMAIBsgFikDADcDCCAbIBUpAwA3AxAgGyAUKQMANwMYIBsgEykDADcDICAbIBIpAwA3AyggGyARKQMANwMwIBsgECkDADcDOAwBCwNAICQgJmoiCyAkIAxqIgQpAwA3AwAgC0EIaiAEQQhqKQMANwMAIAtBEGogBEEQaikDADcDACALQRhqIARBGGopAwA3AwAgC0EgaiAEQSBqKQMANwMAIAtBKGogBEEoaikDADcDACALQTBqIARBMGopAwA3AwAgC0E4aiAEQThqKQMANwMAIAtBwABqIARBwABqKQMANwMAIAtByABqIARByABqKQMANwMAIAtB0ABqIARB0ABqKQMANwMAIAtB2ABqIARB2ABqKQMANwMAIAtB4ABqIARB4ABqKQMANwMAIAtB6ABqIARB6ABqKQMANwMAIAtB8ABqIARB8ABqKQMANwMAIAtB+ABqIARB+ABqKQMANwMAICRBgAFqISQgIkF/aiIiDQALIAcgCCAbIAAQAiAFISQgACEiA0AgJCAjaiILICQgDWoiBCkDADcDACALQQhqIARBCGopAwA3AwAgC0EQaiAEQRBqKQMANwMAIAtBGGogBEEYaikDADcDACALQSBqIARBIGopAwA3AwAgC0EoaiAEQShqKQMANwMAIAtBMGogBEEwaikDADcDACALQThqIARBOGopAwA3AwAgC0HAAGogBEHAAGopAwA3AwAgC0HIAGogBEHIAGopAwA3AwAgC0HQAGogBEHQAGopAwA3AwAgC0HYAGogBEHYAGopAwA3AwAgC0HgAGogBEHgAGopAwA3AwAgC0HoAGogBEHoAGopAwA3AwAgC0HwAGogBEHwAGopAwA3AwAgC0H4AGogBEH4AGopAwA3AwAgJEGAAWohJCAiQX9qIiINAAsLIAggByAbIAAQAiAjIBpqISMgJiAaaiEmICVBAmoiJSABSQ0AC0EAISUDQAJAAkAgAA0AIBsgFykDADcDACAbIBYpAwA3AwggGyAVKQMANwMQIBsgFCkDADcDGCAbIBMpAwA3AyAgGyASKQMANwMoIBsgESkDADcDMCAbIBApAwA3AzgMAQsgACAKIBkpAgAgGIOnQQd0amwhJiAFISQgACEiA0AgJCAMaiILIAspAwAgJCAmaiIEKQMAhTcDACALQQhqIiMgIykDACAEQQhqKQMAhTcDACALQRBqIiMgIykDACAEQRBqKQMAhTcDACALQRhqIiMgIykDACAEQRhqKQMAhTcDACALQSBqIiMgIykDACAEQSBqKQMAhTcDACALQShqIiMgIykDACAEQShqKQMAhTcDACALQTBqIiMgIykDACAEQTBqKQMAhTcDACALQThqIiMgIykDACAEQThqKQMAhTcDACALQcAAaiIjICMpAwAgBEHAAGopAwCFNwMAIAtByABqIiMgIykDACAEQcgAaikDAIU3AwAgC0HQAGoiIyAjKQMAIARB0ABqKQMAhTcDACALQdgAaiIjICMpAwAgBEHYAGopAwCFNwMAIAtB4ABqIiMgIykDACAEQeAAaikDAIU3AwAgC0HoAGoiIyAjKQMAIARB6ABqKQMAhTcDACALQfAAaiIjICMpAwAgBEHwAGopAwCFNwMAIAtB+ABqIgsgCykDACAEQfgAaikDAIU3AwAgJEGAAWohJCAiQX9qIiINAAsgByAIIBsgABACIAAgCiAJKQIAIBiDp0EHdGpsISYgBSEkIAAhIgNAICQgDWoiCyALKQMAICQgJmoiBCkDAIU3AwAgC0EIaiIjICMpAwAgBEEIaikDAIU3AwAgC0EQaiIjICMpAwAgBEEQaikDAIU3AwAgC0EYaiIjICMpAwAgBEEYaikDAIU3AwAgC0EgaiIjICMpAwAgBEEgaikDAIU3AwAgC0EoaiIjICMpAwAgBEEoaikDAIU3AwAgC0EwaiIjICMpAwAgBEEwaikDAIU3AwAgC0E4aiIjICMpAwAgBEE4aikDAIU3AwAgC0HAAGoiIyAjKQMAIARBwABqKQMAhTcDACALQcgAaiIjICMpAwAgBEHIAGopAwCFNwMAIAtB0ABqIiMgIykDACAEQdAAaikDAIU3AwAgC0HYAGoiIyAjKQMAIARB2ABqKQMAhTcDACALQeAAaiIjICMpAwAgBEHgAGopAwCFNwMAIAtB6ABqIiMgIykDACAEQegAaikDAIU3AwAgC0HwAGoiIyAjKQMAIARB8ABqKQMAhTcDACALQfgAaiILIAspAwAgBEH4AGopAwCFNwMAICRBgAFqISQgIkF/aiIiDQALCyAIIAcgGyAAEAIgJUECaiIlIAFJDQALCwJAIABFDQBBACEiAkAgHQ0AICAgHmohI0EAIQtBACEiA0AgIyALaiIEIAcgC2oiJCgCADYCACAEQQRqICRBBGooAgA2AgAgBEEIaiAkQQhqKAIANgIAIARBDGogJEEMaigCADYCACALQRBqIQsgDiAiQQRqIiJHDQALCyAPRQ0AICEgIkECdCILaiAHIAtqKAIANgIACyAeIANqIR4gH0EBaiIfIAJHDQALCws=\";\nvar hash$3 = \"b32721f8\";\nvar wasmJson$3 = {\n\tname: name$3,\n\tdata: data$3,\n\thash: hash$3\n};\n\nfunction scryptInternal(options) {\n return __awaiter(this, void 0, void 0, function* () {\n const { costFactor, blockSize, parallelism, hashLength } = options;\n const SHA256Hasher = createSHA256();\n const blockData = yield pbkdf2({\n password: options.password,\n salt: options.salt,\n iterations: 1,\n hashLength: 128 * blockSize * parallelism,\n hashFunction: SHA256Hasher,\n outputType: \"binary\",\n });\n const scryptInterface = yield WASMInterface(wasmJson$3, 0);\n // last block is for storing the temporary vectors\n const VSize = 128 * blockSize * costFactor;\n const XYSize = 256 * blockSize;\n scryptInterface.setMemorySize(blockData.length + VSize + XYSize);\n scryptInterface.writeMemory(blockData, 0);\n // mix blocks\n scryptInterface.getExports().scrypt(blockSize, costFactor, parallelism);\n const expensiveSalt = scryptInterface\n .getMemory()\n .subarray(0, 128 * blockSize * parallelism);\n const outputData = yield pbkdf2({\n password: options.password,\n salt: expensiveSalt,\n iterations: 1,\n hashLength,\n hashFunction: SHA256Hasher,\n outputType: \"binary\",\n });\n if (options.outputType === \"hex\") {\n const digestChars = new Uint8Array(hashLength * 2);\n return getDigestHex(digestChars, outputData, hashLength);\n }\n // return binary format\n return outputData;\n });\n}\nconst isPowerOfTwo = (v) => v && !(v & (v - 1));\nconst validateOptions$1 = (options) => {\n if (!options || typeof options !== \"object\") {\n throw new Error(\"Invalid options parameter. It requires an object.\");\n }\n if (!Number.isInteger(options.blockSize) || options.blockSize < 1) {\n throw new Error(\"Block size should be a positive number\");\n }\n if (!Number.isInteger(options.costFactor) ||\n options.costFactor < 2 ||\n !isPowerOfTwo(options.costFactor)) {\n throw new Error(\"Cost factor should be a power of 2, greater than 1\");\n }\n if (!Number.isInteger(options.parallelism) || options.parallelism < 1) {\n throw new Error(\"Parallelism should be a positive number\");\n }\n if (!Number.isInteger(options.hashLength) || options.hashLength < 1) {\n throw new Error(\"Hash length should be a positive number.\");\n }\n if (options.outputType === undefined) {\n options.outputType = \"hex\";\n }\n if (![\"hex\", \"binary\"].includes(options.outputType)) {\n throw new Error(`Insupported output type ${options.outputType}. Valid values: ['hex', 'binary']`);\n }\n};\n/**\n * Calculates hash using the scrypt password-based key derivation function\n * @returns Computed hash as a hexadecimal string or as\n * Uint8Array depending on the outputType option\n */\nfunction scrypt(options) {\n return __awaiter(this, void 0, void 0, function* () {\n validateOptions$1(options);\n return scryptInternal(options);\n });\n}\n\nvar name$2 = \"bcrypt\";\nvar data$2 = \"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\";\nvar hash$2 = \"8bd8822d\";\nvar wasmJson$2 = {\n\tname: name$2,\n\tdata: data$2,\n\thash: hash$2\n};\n\nfunction bcryptInternal(options) {\n return __awaiter(this, void 0, void 0, function* () {\n const { costFactor, password, salt } = options;\n const bcryptInterface = yield WASMInterface(wasmJson$2, 0);\n bcryptInterface.writeMemory(getUInt8Buffer(salt), 0);\n const passwordBuffer = getUInt8Buffer(password);\n bcryptInterface.writeMemory(passwordBuffer, 16);\n const shouldEncode = options.outputType === \"encoded\" ? 1 : 0;\n bcryptInterface\n .getExports()\n .bcrypt(passwordBuffer.length, costFactor, shouldEncode);\n const memory = bcryptInterface.getMemory();\n if (options.outputType === \"encoded\") {\n return intArrayToString(memory, 60);\n }\n if (options.outputType === \"hex\") {\n const digestChars = new Uint8Array(24 * 2);\n return getDigestHex(digestChars, memory, 24);\n }\n // return binary format\n // the data is copied to allow GC of the original memory buffer\n return memory.slice(0, 24);\n });\n}\nconst validateOptions = (options) => {\n if (!options || typeof options !== \"object\") {\n throw new Error(\"Invalid options parameter. It requires an object.\");\n }\n if (!Number.isInteger(options.costFactor) ||\n options.costFactor < 4 ||\n options.costFactor > 31) {\n throw new Error(\"Cost factor should be a number between 4 and 31\");\n }\n options.password = getUInt8Buffer(options.password);\n if (options.password.length < 1) {\n throw new Error(\"Password should be at least 1 byte long\");\n }\n if (options.password.length > 72) {\n throw new Error(\"Password should be at most 72 bytes long\");\n }\n options.salt = getUInt8Buffer(options.salt);\n if (options.salt.length !== 16) {\n throw new Error(\"Salt should be 16 bytes long\");\n }\n if (options.outputType === undefined) {\n options.outputType = \"encoded\";\n }\n if (![\"hex\", \"binary\", \"encoded\"].includes(options.outputType)) {\n throw new Error(`Insupported output type ${options.outputType}. Valid values: ['hex', 'binary', 'encoded']`);\n }\n};\n/**\n * Calculates hash using the bcrypt password-hashing function\n * @returns Computed hash\n */\nfunction bcrypt(options) {\n return __awaiter(this, void 0, void 0, function* () {\n validateOptions(options);\n return bcryptInternal(options);\n });\n}\nconst validateHashCharacters = (hash) => {\n if (!/^\\$2[axyb]\\$[0-3][0-9]\\$[./A-Za-z0-9]{53}$/.test(hash)) {\n return false;\n }\n if (hash[4] === \"0\" && Number(hash[5]) < 4) {\n return false;\n }\n if (hash[4] === \"3\" && Number(hash[5]) > 1) {\n return false;\n }\n return true;\n};\nconst validateVerifyOptions = (options) => {\n if (!options || typeof options !== \"object\") {\n throw new Error(\"Invalid options parameter. It requires an object.\");\n }\n if (options.hash === undefined || typeof options.hash !== \"string\") {\n throw new Error(\"Hash should be specified\");\n }\n if (options.hash.length !== 60) {\n throw new Error(\"Hash should be 60 bytes long\");\n }\n if (!validateHashCharacters(options.hash)) {\n throw new Error(\"Invalid hash\");\n }\n options.password = getUInt8Buffer(options.password);\n if (options.password.length < 1) {\n throw new Error(\"Password should be at least 1 byte long\");\n }\n if (options.password.length > 72) {\n throw new Error(\"Password should be at most 72 bytes long\");\n }\n};\n/**\n * Verifies password using bcrypt password-hashing function\n * @returns True if the encoded hash matches the password\n */\nfunction bcryptVerify(options) {\n return __awaiter(this, void 0, void 0, function* () {\n validateVerifyOptions(options);\n const { hash, password } = options;\n const bcryptInterface = yield WASMInterface(wasmJson$2, 0);\n bcryptInterface.writeMemory(getUInt8Buffer(hash), 0);\n const passwordBuffer = getUInt8Buffer(password);\n bcryptInterface.writeMemory(passwordBuffer, 60);\n return !!bcryptInterface.getExports().bcrypt_verify(passwordBuffer.length);\n });\n}\n\nvar name$1 = \"whirlpool\";\nvar data$1 = \"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\";\nvar hash$1 = \"8d8f6035\";\nvar wasmJson$1 = {\n\tname: name$1,\n\tdata: data$1,\n\thash: hash$1\n};\n\nconst mutex$1 = new Mutex();\nlet wasmCache$1 = null;\n/**\n * Calculates Whirlpool hash\n * @param data Input data (string, Buffer or TypedArray)\n * @returns Computed hash as a hexadecimal string\n */\nfunction whirlpool(data) {\n if (wasmCache$1 === null) {\n return lockedCreate(mutex$1, wasmJson$1, 64).then((wasm) => {\n wasmCache$1 = wasm;\n return wasmCache$1.calculate(data);\n });\n }\n try {\n const hash = wasmCache$1.calculate(data);\n return Promise.resolve(hash);\n }\n catch (err) {\n return Promise.reject(err);\n }\n}\n/**\n * Creates a new Whirlpool hash instance\n */\nfunction createWhirlpool() {\n return WASMInterface(wasmJson$1, 64).then((wasm) => {\n wasm.init();\n const obj = {\n init: () => {\n wasm.init();\n return obj;\n },\n update: (data) => {\n wasm.update(data);\n return obj;\n },\n // biome-ignore lint/suspicious/noExplicitAny: Conflict with IHasher type\n digest: (outputType) => wasm.digest(outputType),\n save: () => wasm.save(),\n load: (data) => {\n wasm.load(data);\n return obj;\n },\n blockSize: 64,\n digestSize: 64,\n };\n return obj;\n });\n}\n\nvar name = \"sm3\";\nvar data = \"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\";\nvar hash = \"b6fb4b8e\";\nvar wasmJson = {\n\tname: name,\n\tdata: data,\n\thash: hash\n};\n\nconst mutex = new Mutex();\nlet wasmCache = null;\n/**\n * Calculates SM3 hash\n * @param data Input data (string, Buffer or TypedArray)\n * @returns Computed hash as a hexadecimal string\n */\nfunction sm3(data) {\n if (wasmCache === null) {\n return lockedCreate(mutex, wasmJson, 32).then((wasm) => {\n wasmCache = wasm;\n return wasmCache.calculate(data);\n });\n }\n try {\n const hash = wasmCache.calculate(data);\n return Promise.resolve(hash);\n }\n catch (err) {\n return Promise.reject(err);\n }\n}\n/**\n * Creates a new SM3 hash instance\n */\nfunction createSM3() {\n return WASMInterface(wasmJson, 32).then((wasm) => {\n wasm.init();\n const obj = {\n init: () => {\n wasm.init();\n return obj;\n },\n update: (data) => {\n wasm.update(data);\n return obj;\n },\n // biome-ignore lint/suspicious/noExplicitAny: Conflict with IHasher type\n digest: (outputType) => wasm.digest(outputType),\n save: () => wasm.save(),\n load: (data) => {\n wasm.load(data);\n return obj;\n },\n blockSize: 64,\n digestSize: 32,\n };\n return obj;\n });\n}\n\nexport { adler32, argon2Verify, argon2d, argon2i, argon2id, bcrypt, bcryptVerify, blake2b, blake2s, blake3, crc32, crc64, createAdler32, createBLAKE2b, createBLAKE2s, createBLAKE3, createCRC32, createCRC64, createHMAC, createKeccak, createMD4, createMD5, createRIPEMD160, createSHA1, createSHA224, createSHA256, createSHA3, createSHA384, createSHA512, createSM3, createWhirlpool, createXXHash128, createXXHash3, createXXHash32, createXXHash64, keccak, md4, md5, pbkdf2, ripemd160, scrypt, sha1, sha224, sha256, sha3, sha384, sha512, sm3, whirlpool, xxhash128, xxhash3, xxhash32, xxhash64 };\n","/**\n * Secure nsec encryption/decryption using Argon2id + AES-GCM\n *\n * - Argon2id key derivation with ~3 second computation time (runs in Web Worker)\n * - AES-256-GCM authenticated encryption\n * - Validates bech32 nsec format and checksum on decryption\n */\n\nimport { argon2id } from \"hash-wasm\";\nimport { decode as nip19Decode } from \"nostr-tools/nip19\";\n\n// Argon2id parameters tuned for ~3 second derivation on typical hardware\nconst ARGON2_CONFIG = {\n parallelism: 4, // 4 threads\n iterations: 8, // Time cost\n memorySize: 262144, // 256 MB memory\n hashLength: 32, // 256-bit key for AES-256\n outputType: \"binary\"\n};\n\n// Worker singleton and message ID counter\nlet worker = null;\nlet messageId = 0;\nconst pendingRequests = new Map();\n\n/**\n * Get or create the Argon2 worker\n */\nfunction getWorker() {\n if (worker) return worker;\n\n // Inline worker code - includes hash-wasm import via importScripts alternative\n // Since we can't easily import ES modules in workers, we'll use a different approach\n // We'll run argon2id in chunks with yielding to allow UI updates\n\n const workerCode = `\n importScripts('https://cdn.jsdelivr.net/npm/hash-wasm@4.11.0/dist/argon2.umd.min.js');\n\n const ARGON2_CONFIG = {\n parallelism: 4,\n iterations: 8,\n memorySize: 262144,\n hashLength: 32,\n outputType: \"binary\"\n };\n\n self.onmessage = async function(e) {\n const { password, salt, id } = e.data;\n\n try {\n const result = await hashwasm.argon2id({\n password: password,\n salt: new Uint8Array(salt),\n ...ARGON2_CONFIG\n });\n\n self.postMessage({\n id,\n success: true,\n result: Array.from(result)\n });\n } catch (error) {\n self.postMessage({\n id,\n success: false,\n error: error.message\n });\n }\n };\n `;\n\n const blob = new Blob([workerCode], { type: 'application/javascript' });\n worker = new Worker(URL.createObjectURL(blob));\n\n worker.onmessage = function(e) {\n const { id, success, result, error } = e.data;\n const pending = pendingRequests.get(id);\n if (pending) {\n pendingRequests.delete(id);\n if (success) {\n pending.resolve(new Uint8Array(result));\n } else {\n pending.reject(new Error(error));\n }\n }\n };\n\n worker.onerror = function(e) {\n console.error('Argon2 worker error:', e);\n };\n\n return worker;\n}\n\n/**\n * Derive an encryption key from password using Argon2id (in Web Worker)\n * @param {string} password - User's password\n * @param {Uint8Array} salt - Random 32-byte salt\n * @returns {Promise} - 32-byte derived key\n */\nexport async function deriveKey(password, salt) {\n // Try to use worker, fall back to main thread if it fails\n try {\n const w = getWorker();\n const id = ++messageId;\n\n return new Promise((resolve, reject) => {\n pendingRequests.set(id, { resolve, reject });\n w.postMessage({\n id,\n password,\n salt: Array.from(salt)\n });\n });\n } catch (e) {\n // Fallback to main thread (will block UI but at least works)\n console.warn('Worker failed, falling back to main thread:', e);\n const result = await argon2id({\n password: password,\n salt: salt,\n ...ARGON2_CONFIG\n });\n return result;\n }\n}\n\n/**\n * Encrypt an nsec with a password\n * @param {string} nsec - The nsec in bech32 format (nsec1...)\n * @param {string} password - User's password\n * @returns {Promise} - Base64 encoded encrypted data (salt + iv + ciphertext)\n */\nexport async function encryptNsec(nsec, password) {\n // Validate nsec format first\n if (!nsec.startsWith(\"nsec1\")) {\n throw new Error(\"Invalid nsec format - must start with nsec1\");\n }\n\n // Validate bech32 checksum\n try {\n const decoded = nip19Decode(nsec);\n if (decoded.type !== \"nsec\") {\n throw new Error(\"Invalid nsec - wrong type\");\n }\n } catch (e) {\n throw new Error(\"Invalid nsec - bech32 checksum failed\");\n }\n\n // Generate random salt and IV\n const salt = crypto.getRandomValues(new Uint8Array(32));\n const iv = crypto.getRandomValues(new Uint8Array(12));\n\n // Derive key using Argon2id (~3 seconds, in worker)\n const keyBytes = await deriveKey(password, salt);\n\n // Import key for AES-GCM\n const key = await crypto.subtle.importKey(\n \"raw\",\n keyBytes,\n { name: \"AES-GCM\" },\n false,\n [\"encrypt\"]\n );\n\n // Encrypt the nsec\n const encoder = new TextEncoder();\n const encrypted = await crypto.subtle.encrypt(\n { name: \"AES-GCM\", iv: iv },\n key,\n encoder.encode(nsec)\n );\n\n // Combine salt + iv + ciphertext and encode as base64\n const combined = new Uint8Array(salt.length + iv.length + encrypted.byteLength);\n combined.set(salt, 0);\n combined.set(iv, salt.length);\n combined.set(new Uint8Array(encrypted), salt.length + iv.length);\n\n return btoa(String.fromCharCode(...combined));\n}\n\n/**\n * Decrypt an nsec with a password\n * @param {string} encryptedData - Base64 encoded encrypted data\n * @param {string} password - User's password\n * @returns {Promise} - The decrypted nsec in bech32 format\n * @throws {Error} - If password is wrong or data is corrupted\n */\nexport async function decryptNsec(encryptedData, password) {\n // Decode base64\n const combined = new Uint8Array(\n atob(encryptedData).split(\"\").map(c => c.charCodeAt(0))\n );\n\n // Validate minimum length (32 salt + 12 iv + 16 auth tag + some ciphertext)\n if (combined.length < 60) {\n throw new Error(\"Invalid encrypted data - too short\");\n }\n\n // Extract salt, iv, and ciphertext\n const salt = combined.slice(0, 32);\n const iv = combined.slice(32, 44);\n const ciphertext = combined.slice(44);\n\n // Derive key using Argon2id (~3 seconds, in worker)\n const keyBytes = await deriveKey(password, salt);\n\n // Import key for AES-GCM\n const key = await crypto.subtle.importKey(\n \"raw\",\n keyBytes,\n { name: \"AES-GCM\" },\n false,\n [\"decrypt\"]\n );\n\n // Decrypt\n let decrypted;\n try {\n decrypted = await crypto.subtle.decrypt(\n { name: \"AES-GCM\", iv: iv },\n key,\n ciphertext\n );\n } catch (e) {\n throw new Error(\"Decryption failed - invalid password or corrupted data\");\n }\n\n const decoder = new TextDecoder();\n const nsec = decoder.decode(decrypted);\n\n // Validate the decrypted nsec has correct bech32 format and checksum\n if (!nsec.startsWith(\"nsec1\")) {\n throw new Error(\"Decryption produced invalid data - not an nsec\");\n }\n\n try {\n const decoded = nip19Decode(nsec);\n if (decoded.type !== \"nsec\") {\n throw new Error(\"Decryption produced invalid nsec type\");\n }\n } catch (e) {\n throw new Error(\"Decryption produced invalid nsec - bech32 checksum failed\");\n }\n\n return nsec;\n}\n\n/**\n * Check if a string is a valid nsec (validates bech32 format and checksum)\n * @param {string} nsec - The string to validate\n * @returns {boolean} - True if valid nsec\n */\nexport function isValidNsec(nsec) {\n if (!nsec || !nsec.startsWith(\"nsec1\")) {\n return false;\n }\n try {\n const decoded = nip19Decode(nsec);\n return decoded.type === \"nsec\";\n } catch {\n return false;\n }\n}\n\n/**\n * Terminate the worker (call when done to free resources)\n */\nexport function terminateWorker() {\n if (worker) {\n worker.terminate();\n worker = null;\n }\n}\n","\n\n \n\n{#if showModal}\n e.key === \"Escape\" && closeModal()}\n role=\"button\"\n tabindex=\"0\"\n >\n
\n \n\n
\n
\n switchTab(\"extension\")}\n >\n Extension\n \n switchTab(\"nsec\")}\n >\n Nsec\n \n
\n\n
\n {#if activeTab === \"extension\"}\n
\n
\n Login using a NIP-07 compatible browser\n extension like nos2x or Alby.\n
\n
\n {isLoading\n ? \"Connecting...\"\n : \"Log in using extension\"}\n \n
\n {:else}\n
\n {#if hasEncryptedKey}\n \n
\n You have a stored encrypted key. Enter your\n password to unlock it.\n
\n\n {#if storedPubkey}\n
\n Stored public key: \n {storedPubkey.slice(0, 16)}...{storedPubkey.slice(-8)}\n
\n {/if}\n\n
\n\n
\n {#if isDeriving}\n Deriving key...\n {:else if isLoading}\n Unlocking...\n {:else}\n Unlock\n {/if}\n \n\n
\n Clear stored key & start fresh\n \n {:else}\n \n
\n Enter your nsec or generate a new one. Optionally\n set a password to encrypt it securely.\n
\n\n
\n {isGenerating\n ? \"Generating...\"\n : \"Generate New Key\"}\n \n\n {#if generatedNpub}\n
\n Your new public key (npub): \n {generatedNpub}\n
\n {/if}\n\n
\n\n
\n Encryption Password (optional but recommended): \n \n {#if encryptionPassword}\n \n {/if}\n \n Password uses Argon2id with ~3 second derivation time for security.\n \n
\n\n
\n {#if isDeriving}\n Deriving key...\n {:else if isLoading}\n Logging in...\n {:else}\n Log in with nsec\n {/if}\n \n {/if}\n
\n {/if}\n\n {#if errorMessage}\n
{errorMessage}
\n {/if}\n\n {#if successMessage}\n
\n {successMessage}\n
\n {/if}\n
\n
\n
\n
\n{/if}\n\n{#if isDeriving}\n \n
\n
\n
Deriving encryption key \n
{derivingElapsed.toFixed(1)}s
\n
This may take 3-6 seconds for security
\n
\n
\n{/if}\n\n\n","\n\n\n \n\n {#if message}\n
\n {message}\n
\n {/if}\n\n
\n (activeTab = \"pubkeys\")}\n >\n Pubkeys\n \n (activeTab = \"events\")}\n >\n Events\n \n (activeTab = \"ips\")}\n >\n IPs\n \n (activeTab = \"kinds\")}\n >\n Kinds\n \n {\n activeTab = \"moderation\";\n // Load moderation data only when tab is opened\n if (\n !eventsNeedingModeration ||\n eventsNeedingModeration.length === 0\n ) {\n loadEventsNeedingModeration();\n }\n }}\n >\n Moderation\n \n (activeTab = \"relay\")}\n >\n Relay Config\n \n
\n\n
\n {#if activeTab === \"pubkeys\"}\n
\n
\n
Banned Pubkeys \n
\n \n \n Ban Pubkey \n
\n
\n {#if bannedPubkeys && bannedPubkeys.length > 0}\n {#each bannedPubkeys as item}\n
\n {item.pubkey} \n {#if item.reason}\n {item.reason} \n {/if}\n
\n {/each}\n {:else}\n
\n
No banned pubkeys configured.
\n
\n {/if}\n
\n
\n\n
\n
Allowed Pubkeys \n
\n \n \n Allow Pubkey \n
\n
\n {#if allowedPubkeys && allowedPubkeys.length > 0}\n {#each allowedPubkeys as item}\n
\n {item.pubkey} \n {#if item.reason}\n {item.reason} \n {/if}\n
\n {/each}\n {:else}\n
\n
No allowed pubkeys configured.
\n
\n {/if}\n
\n
\n
\n {/if}\n\n {#if activeTab === \"events\"}\n
\n
\n
Banned Events \n
\n \n \n Ban Event \n
\n
\n {#if bannedEvents && bannedEvents.length > 0}\n {#each bannedEvents as item}\n
\n {item.id} \n {#if item.reason}\n {item.reason} \n {/if}\n
\n {/each}\n {:else}\n
\n
No banned events configured.
\n
\n {/if}\n
\n
\n\n
\n
Allowed Events \n
\n \n \n Allow Event \n
\n
\n {#if allowedEvents && allowedEvents.length > 0}\n {#each allowedEvents as item}\n
\n {item.id} \n {#if item.reason}\n {item.reason} \n {/if}\n
\n {/each}\n {:else}\n
\n
No allowed events configured.
\n
\n {/if}\n
\n
\n
\n {/if}\n\n {#if activeTab === \"ips\"}\n
\n
\n
Blocked IPs \n
\n \n \n Block IP \n
\n
\n {#if blockedIPs && blockedIPs.length > 0}\n {#each blockedIPs as item}\n
\n {item.ip} \n {#if item.reason}\n {item.reason} \n {/if}\n
\n {/each}\n {:else}\n
\n
No blocked IPs configured.
\n
\n {/if}\n
\n
\n
\n {/if}\n\n {#if activeTab === \"kinds\"}\n
\n
\n
Allowed Event Kinds \n
\n \n Allow Kind \n
\n
\n {#if allowedKinds && allowedKinds.length > 0}\n {#each allowedKinds as kind}\n
\n Kind {kind} \n disallowKind(kind)}\n >Remove \n
\n {/each}\n {:else}\n
\n
\n No allowed kinds configured. All kinds are\n allowed by default.\n
\n
\n {/if}\n
\n
\n
\n {/if}\n\n {#if activeTab === \"moderation\"}\n
\n
\n
Events Needing Moderation \n
Refresh \n
\n {#if eventsNeedingModeration && eventsNeedingModeration.length > 0}\n {#each eventsNeedingModeration as item}\n
\n
{item.id} \n {#if item.reason}\n
{item.reason} \n {/if}\n
\n \n allowEventFromModeration(\n item.id,\n )}>Allow \n \n banEventFromModeration(item.id)}\n >Ban \n
\n
\n {/each}\n {:else}\n
\n
No events need moderation at this time.
\n
\n {/if}\n
\n
\n
\n {/if}\n\n {#if activeTab === \"relay\"}\n
\n
\n
Relay Configuration \n
\n \n 🔄 Refresh from Relay Info\n \n
\n
\n
\n
\n {/if}\n
\n
\n\n\n","\n\n\n\n\n","\n\n\n\n\n","\n\n{#if canAccess}\n {#if isLoggedIn}\n \n
Export My Events \n
Download your personal events as a JSONL file.
\n
\n 📤 Export My Events\n \n
\n {/if}\n {#if canExportAll}\n \n
Export All Events \n
\n Download the complete database as a JSONL file. This includes\n all events from all users.\n
\n
\n 📤 Export All Events\n \n
\n {/if}\n{:else}\n \n
Please log in to access export functionality.
\n
Log In \n
\n{/if}\n\n\n","\n\n\n {#if canImport}\n
Import Events \n
Upload a JSONL file to import events into the database.
\n
\n
\n
\n \n Import Events\n \n {#if importMessage}\n {importMessage} \n {/if}\n
\n
\n {:else if isLoggedIn}\n
\n \n
\n Admin or owner permission required for import functionality.\n
\n
\n {:else}\n
\n \n
\n Please log in to access import functionality.\n
\n
Log In \n
\n {/if}\n
\n\n\n","// Helper functions and constants for the ORLY dashboard\n\n// Comprehensive kind names mapping\nexport const KIND_NAMES = {\n 0: \"Profile Metadata\",\n 1: \"Text Note\",\n 2: \"Recommend Relay\",\n 3: \"Contacts\",\n 4: \"Encrypted DM\",\n 5: \"Delete Request\",\n 6: \"Repost\",\n 7: \"Reaction\",\n 8: \"Badge Award\",\n 16: \"Generic Repost\",\n 40: \"Channel Creation\",\n 41: \"Channel Metadata\",\n 42: \"Channel Message\",\n 43: \"Channel Hide Message\",\n 44: \"Channel Mute User\",\n 1063: \"File Metadata\",\n 1311: \"Live Chat Message\",\n 1984: \"Reporting\",\n 1985: \"Label\",\n 9734: \"Zap Request\",\n 9735: \"Zap Receipt\",\n 10000: \"Mute List\",\n 10001: \"Pin List\",\n 10002: \"Relay List Metadata\",\n 10003: \"Bookmark List\",\n 10004: \"Communities List\",\n 10005: \"Public Chats List\",\n 10006: \"Blocked Relays List\",\n 10007: \"Search Relays List\",\n 10009: \"User Groups\",\n 10015: \"Interests List\",\n 10030: \"User Emoji List\",\n 13194: \"Wallet Info\",\n 22242: \"Client Auth\",\n 23194: \"Wallet Request\",\n 23195: \"Wallet Response\",\n 24133: \"Nostr Connect\",\n 27235: \"HTTP Auth\",\n 30000: \"Categorized People List\",\n 30001: \"Categorized Bookmarks\",\n 30002: \"Categorized Relay List\",\n 30003: \"Bookmark Sets\",\n 30004: \"Curation Sets\",\n 30005: \"Video Sets\",\n 30008: \"Profile Badges\",\n 30009: \"Badge Definition\",\n 30015: \"Interest Sets\",\n 30017: \"Create/Update Stall\",\n 30018: \"Create/Update Product\",\n 30019: \"Marketplace UI/UX\",\n 30020: \"Product Sold As Auction\",\n 30023: \"Long-form Content\",\n 30024: \"Draft Long-form Content\",\n 30030: \"Emoji Sets\",\n 30063: \"Release Artifact Sets\",\n 30078: \"Application-specific Data\",\n 30311: \"Live Event\",\n 30315: \"User Statuses\",\n 30388: \"Slide Set\",\n 30402: \"Classified Listing\",\n 30403: \"Draft Classified Listing\",\n 30617: \"Repository Announcement\",\n 30618: \"Repository State Announcement\",\n 30818: \"Wiki Article\",\n 30819: \"Redirects\",\n 31922: \"Date-Based Calendar Event\",\n 31923: \"Time-Based Calendar Event\",\n 31924: \"Calendar\",\n 31925: \"Calendar Event RSVP\",\n 31989: \"Handler Recommendation\",\n 31990: \"Handler Information\",\n 34550: \"Community Definition\",\n 34551: \"Community Post Approval\",\n};\n\n// Get human-readable kind name\nexport function getKindName(kind) {\n return KIND_NAMES[kind] || `Kind ${kind}`;\n}\n\n// Validate hex string (for pubkeys and event IDs)\nexport function isValidHex(str, length = null) {\n if (!str || typeof str !== \"string\") return false;\n const hexRegex = /^[0-9a-fA-F]+$/;\n if (!hexRegex.test(str)) return false;\n if (length && str.length !== length) return false;\n return true;\n}\n\n// Validate pubkey (64 character hex)\nexport function isValidPubkey(pubkey) {\n return isValidHex(pubkey, 64);\n}\n\n// Validate event ID (64 character hex)\nexport function isValidEventId(eventId) {\n return isValidHex(eventId, 64);\n}\n\n// Validate tag name (single letter a-zA-Z)\nexport function isValidTagName(tagName) {\n return /^[a-zA-Z]$/.test(tagName);\n}\n\n// Format timestamp to localized string\nexport function formatTimestamp(timestamp) {\n return new Date(timestamp * 1000).toLocaleString();\n}\n\n// Format timestamp for datetime-local input\nexport function formatDateTimeLocal(timestamp) {\n const date = new Date(timestamp * 1000);\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n const hours = String(date.getHours()).padStart(2, '0');\n const minutes = String(date.getMinutes()).padStart(2, '0');\n return `${year}-${month}-${day}T${hours}:${minutes}`;\n}\n\n// Parse datetime-local input to unix timestamp\nexport function parseDateTimeLocal(dateTimeString) {\n return Math.floor(new Date(dateTimeString).getTime() / 1000);\n}\n\n// Truncate pubkey for display\nexport function truncatePubkey(pubkey) {\n if (!pubkey) return \"\";\n return pubkey.slice(0, 8) + \"...\" + pubkey.slice(-8);\n}\n\n// Truncate content for display\nexport function truncateContent(content, maxLength = 100) {\n if (!content) return \"\";\n return content.length > maxLength ? content.slice(0, maxLength) + \"...\" : content;\n}\n\n// Build Nostr filter from form data\nexport function buildFilter({\n searchText = null,\n kinds = [],\n authors = [],\n ids = [],\n tags = [],\n since = null,\n until = null,\n limit = null,\n}) {\n const filter = {};\n \n if (searchText && searchText.trim()) {\n filter.search = searchText.trim();\n }\n \n if (kinds && kinds.length > 0) {\n filter.kinds = kinds;\n }\n \n if (authors && authors.length > 0) {\n filter.authors = authors;\n }\n \n if (ids && ids.length > 0) {\n filter.ids = ids;\n }\n \n // Add tag filters (e.g., #e, #p, #a)\n if (tags && tags.length > 0) {\n tags.forEach(tag => {\n if (tag.name && tag.value) {\n const tagKey = `#${tag.name}`;\n if (!filter[tagKey]) {\n filter[tagKey] = [];\n }\n filter[tagKey].push(tag.value);\n }\n });\n }\n \n if (since) {\n filter.since = since;\n }\n \n if (until) {\n filter.until = until;\n }\n \n if (limit && limit > 0) {\n filter.limit = limit;\n }\n \n return filter;\n}\n\n// Pretty print JSON with word breaking for long strings\nexport function prettyPrintFilter(filter) {\n return JSON.stringify(filter, null, 2);\n}\n\n","\n\n\n
\n
\n \n
Search Text (NIP-50) \n
\n \n
\n\n \n
Event Kinds \n
\n
showKindsPicker = !showKindsPicker}\n >\n {showKindsPicker ? \"▼\" : \"▶\"} Select Kinds ({selectedKinds.length} selected)\n \n\n {#if showKindsPicker}\n
\n {/if}\n\n {#if selectedKinds.length > 0}\n
\n {#each selectedKinds as kind}\n
\n {kind}: {KIND_NAMES[kind] || `Kind ${kind}`} \n removeKind(kind)}>× \n
\n {/each}\n
\n {/if}\n
\n\n \n
Authors (Pubkeys) \n
\n
\n e.key === 'Enter' && addPubkey()}\n />\n Add \n
\n {#if pubkeyError}\n
{pubkeyError}
\n {/if}\n {#if pubkeys.length > 0}\n
\n {#each pubkeys as pubkey}\n
\n {pubkey} \n removePubkey(pubkey)}>× \n
\n {/each}\n
\n {/if}\n
\n\n \n
Event IDs \n
\n
\n e.key === 'Enter' && addEventId()}\n />\n Add \n
\n {#if eventIdError}\n
{eventIdError}
\n {/if}\n {#if eventIds.length > 0}\n
\n {#each eventIds as eventId}\n
\n {eventId} \n removeEventId(eventId)}>× \n
\n {/each}\n
\n {/if}\n
\n\n \n
Tags (#e, #p, #a) \n
\n
\n # \n \n e.key === 'Enter' && addTag()}\n />\n Add \n
\n {#if tagNameError}\n
{tagNameError}
\n {/if}\n {#if tags.length > 0}\n
\n {#each tags as tag, index}\n
\n #{tag.name}: {tag.value} \n removeTag(index)}>× \n
\n {/each}\n
\n {/if}\n
\n\n \n
Since \n
\n \n {#if sinceTimestamp}\n sinceTimestamp = null}>× \n {/if}\n
\n\n \n
Until \n
\n \n {#if untilTimestamp}\n untilTimestamp = null}>× \n {/if}\n
\n\n \n
Limit \n
\n \n
\n\n \n {#if showJsonEditor}\n
\n
Filter JSON \n
\n {#if jsonError}\n
{jsonError}
\n {/if}\n
Apply JSON \n
\n {/if}\n
\n
\n
\n
🧹 \n
\n
dispatch(\"toggleJson\")}\n title=\"Edit filter JSON\"\n ></> \n
\n
\n\n\n\n","\n\n\n {#if isLoggedIn && (userRole === \"read\" || userRole === \"write\" || userRole === \"admin\" || userRole === \"owner\")}\n
\n {#if filteredEvents.length > 0}\n {#each filteredEvents as event}\n
\n
toggleEventExpansion(event.id)}\n on:keydown={(e) =>\n e.key === \"Enter\" &&\n toggleEventExpansion(event.id)}\n role=\"button\"\n tabindex=\"0\"\n >\n
\n
\n
\n {truncatePubkey(event.pubkey)}\n
\n
\n {event.kind} \n {getKindName(event.kind)} \n
\n
\n
\n
\n {formatTimestamp(event.created_at)}\n
\n {#if event.kind === 5}\n
\n
🗑️ Delete Event \n {#if event.tags && event.tags.length > 0}\n
\n {#each event.tags.filter((tag) => tag[0] === \"e\") as eTag}\n Target: {eTag[1].slice(\n 0,\n 8,\n )}...{eTag[1].slice(\n -8,\n )} \n {/each}\n
\n {/if}\n
\n {:else}\n
\n {truncateContent(event.content)}\n
\n {/if}\n
\n {#if event.kind !== 5 && (userRole === \"admin\" || userRole === \"owner\" || (userRole === \"write\" && event.pubkey && event.pubkey === userPubkey))}\n
\n deleteEvent(event.id)}\n >\n 🗑️\n \n {/if}\n
\n {#if expandedEvents.has(event.id)}\n
\n
\n
{JSON.stringify(\n event,\n null,\n 2,\n )} \n
\n copyEventToClipboard(event, e)}\n title=\"Copy minified JSON to clipboard\"\n >\n 📋\n \n
\n
\n {/if}\n
\n {/each}\n {:else if !isLoadingEvents}\n
\n {/if}\n\n {#if isLoadingEvents}\n
\n
\n
Loading events...
\n
\n {/if}\n
\n {:else}\n
\n
\n ❌ Read, write, admin, or owner permission required to view all\n events.\n
\n
\n {/if}\n {#if isLoggedIn && (userRole === \"read\" || userRole === \"write\" || userRole === \"admin\" || userRole === \"owner\")}\n \n {/if}\n
\n\n\n","/**\n * Nostr Event Kinds Database\n * Auto-generated from https://git.mleku.dev/mleku/nostr/raw/branch/main/encoders/kind/kinds.json\n * Version: 2025-12-21\n * Source: https://github.com/nostr-protocol/nips\n *\n * DO NOT EDIT - This file is auto-generated by scripts/fetch-kinds.js\n */\n\nexport const eventKinds = [\n {\n \"kind\": 0,\n \"name\": \"Metadata\",\n \"description\": \"User profile information (name, about, picture, nip05, etc.)\",\n \"nip\": \"01\",\n \"isReplaceable\": true,\n \"template\": {\n \"kind\": 0,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1,\n \"name\": \"Short Text Note\",\n \"description\": \"Short-form text post (like a tweet)\",\n \"nip\": \"01\",\n \"template\": {\n \"kind\": 1,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 2,\n \"name\": \"Recommend Relay\",\n \"description\": \"Relay recommendation\",\n \"nip\": \"01\",\n \"deprecated\": true,\n \"template\": {\n \"kind\": 2,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 3,\n \"name\": \"Follows\",\n \"description\": \"Following list with optional relay hints\",\n \"nip\": \"02\",\n \"isReplaceable\": true,\n \"template\": {\n \"kind\": 3,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 4,\n \"name\": \"Encrypted Direct Message\",\n \"description\": \"Private message using NIP-04 encryption\",\n \"nip\": \"04\",\n \"deprecated\": true,\n \"template\": {\n \"kind\": 4,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 5,\n \"name\": \"Event Deletion Request\",\n \"description\": \"Request to delete events\",\n \"nip\": \"09\",\n \"template\": {\n \"kind\": 5,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 6,\n \"name\": \"Repost\",\n \"description\": \"Share/repost another text note\",\n \"nip\": \"18\",\n \"template\": {\n \"kind\": 6,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 7,\n \"name\": \"Reaction\",\n \"description\": \"Like, emoji reaction to an event\",\n \"nip\": \"25\",\n \"template\": {\n \"kind\": 7,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 8,\n \"name\": \"Badge Award\",\n \"description\": \"Award a badge to someone\",\n \"nip\": \"58\",\n \"template\": {\n \"kind\": 8,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 9,\n \"name\": \"Chat Message\",\n \"description\": \"Chat message\",\n \"nip\": \"C7\",\n \"template\": {\n \"kind\": 9,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 10,\n \"name\": \"Group Chat Threaded Reply\",\n \"description\": \"Threaded reply in group chat\",\n \"nip\": \"29\",\n \"deprecated\": true,\n \"template\": {\n \"kind\": 10,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 11,\n \"name\": \"Thread\",\n \"description\": \"Thread event\",\n \"nip\": \"7D\",\n \"template\": {\n \"kind\": 11,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 12,\n \"name\": \"Group Thread Reply\",\n \"description\": \"Reply in group thread\",\n \"nip\": \"29\",\n \"deprecated\": true,\n \"template\": {\n \"kind\": 12,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 13,\n \"name\": \"Seal\",\n \"description\": \"Sealed/encrypted event wrapper\",\n \"nip\": \"59\",\n \"template\": {\n \"kind\": 13,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 14,\n \"name\": \"Direct Message\",\n \"description\": \"Private direct message using NIP-17\",\n \"nip\": \"17\",\n \"template\": {\n \"kind\": 14,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 15,\n \"name\": \"File Message\",\n \"description\": \"File message in DMs\",\n \"nip\": \"17\",\n \"template\": {\n \"kind\": 15,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 16,\n \"name\": \"Generic Repost\",\n \"description\": \"Repost any event kind\",\n \"nip\": \"18\",\n \"template\": {\n \"kind\": 16,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 17,\n \"name\": \"Reaction to Website\",\n \"description\": \"Reaction to a website URL\",\n \"nip\": \"25\",\n \"template\": {\n \"kind\": 17,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 20,\n \"name\": \"Picture\",\n \"description\": \"Picture-first feed post\",\n \"nip\": \"68\",\n \"template\": {\n \"kind\": 20,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 21,\n \"name\": \"Video Event\",\n \"description\": \"Horizontal video event\",\n \"nip\": \"71\",\n \"template\": {\n \"kind\": 21,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 22,\n \"name\": \"Short-form Video\",\n \"description\": \"Short-form portrait video (like TikTok)\",\n \"nip\": \"71\",\n \"template\": {\n \"kind\": 22,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 40,\n \"name\": \"Channel Creation\",\n \"description\": \"Create a public chat channel\",\n \"nip\": \"28\",\n \"template\": {\n \"kind\": 40,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 41,\n \"name\": \"Channel Metadata\",\n \"description\": \"Set channel name, about, picture\",\n \"nip\": \"28\",\n \"template\": {\n \"kind\": 41,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 42,\n \"name\": \"Channel Message\",\n \"description\": \"Post message in channel\",\n \"nip\": \"28\",\n \"template\": {\n \"kind\": 42,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 43,\n \"name\": \"Channel Hide Message\",\n \"description\": \"Hide a message in channel\",\n \"nip\": \"28\",\n \"template\": {\n \"kind\": 43,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 44,\n \"name\": \"Channel Mute User\",\n \"description\": \"Mute a user in channel\",\n \"nip\": \"28\",\n \"template\": {\n \"kind\": 44,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 62,\n \"name\": \"Request to Vanish\",\n \"description\": \"Request permanent deletion of all user data\",\n \"nip\": \"62\",\n \"template\": {\n \"kind\": 62,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 64,\n \"name\": \"Chess (PGN)\",\n \"description\": \"Chess game in PGN format\",\n \"nip\": \"64\",\n \"template\": {\n \"kind\": 64,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 443,\n \"name\": \"KeyPackage\",\n \"description\": \"Marmot protocol key package\",\n \"nip\": null,\n \"spec\": \"Marmot\",\n \"template\": {\n \"kind\": 443,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 444,\n \"name\": \"Welcome Message\",\n \"description\": \"Marmot protocol welcome message\",\n \"nip\": null,\n \"spec\": \"Marmot\",\n \"template\": {\n \"kind\": 444,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 445,\n \"name\": \"Group Event\",\n \"description\": \"Marmot protocol group event\",\n \"nip\": null,\n \"spec\": \"Marmot\",\n \"template\": {\n \"kind\": 445,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 818,\n \"name\": \"Merge Requests\",\n \"description\": \"Git merge request\",\n \"nip\": \"54\",\n \"template\": {\n \"kind\": 818,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1018,\n \"name\": \"Poll Response\",\n \"description\": \"Response to a poll\",\n \"nip\": \"88\",\n \"template\": {\n \"kind\": 1018,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1021,\n \"name\": \"Bid\",\n \"description\": \"Auction bid\",\n \"nip\": \"15\",\n \"template\": {\n \"kind\": 1021,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1022,\n \"name\": \"Bid Confirmation\",\n \"description\": \"Confirmation of auction bid\",\n \"nip\": \"15\",\n \"template\": {\n \"kind\": 1022,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1040,\n \"name\": \"OpenTimestamps\",\n \"description\": \"OpenTimestamps attestation\",\n \"nip\": \"03\",\n \"template\": {\n \"kind\": 1040,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1059,\n \"name\": \"Gift Wrap\",\n \"description\": \"Encrypted gift-wrapped event\",\n \"nip\": \"59\",\n \"template\": {\n \"kind\": 1059,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1060,\n \"name\": \"Gift Wrap (Kind 4)\",\n \"description\": \"Gift wrap variant for NIP-04 compatibility\",\n \"nip\": \"59\",\n \"template\": {\n \"kind\": 1060,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1063,\n \"name\": \"File Metadata\",\n \"description\": \"Metadata for shared files\",\n \"nip\": \"94\",\n \"template\": {\n \"kind\": 1063,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1068,\n \"name\": \"Poll\",\n \"description\": \"Create a poll\",\n \"nip\": \"88\",\n \"template\": {\n \"kind\": 1068,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1111,\n \"name\": \"Comment\",\n \"description\": \"Comment on events or external content\",\n \"nip\": \"22\",\n \"template\": {\n \"kind\": 1111,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1222,\n \"name\": \"Voice Message\",\n \"description\": \"Voice message\",\n \"nip\": \"A0\",\n \"template\": {\n \"kind\": 1222,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1244,\n \"name\": \"Voice Message Comment\",\n \"description\": \"Comment on voice message\",\n \"nip\": \"A0\",\n \"template\": {\n \"kind\": 1244,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1311,\n \"name\": \"Live Chat Message\",\n \"description\": \"Message in live stream chat\",\n \"nip\": \"53\",\n \"template\": {\n \"kind\": 1311,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1337,\n \"name\": \"Code Snippet\",\n \"description\": \"Code snippet post\",\n \"nip\": \"C0\",\n \"template\": {\n \"kind\": 1337,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1517,\n \"name\": \"Bitcoin Block\",\n \"description\": \"Bitcoin block data\",\n \"nip\": null,\n \"spec\": \"Nostrocket\",\n \"template\": {\n \"kind\": 1517,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1617,\n \"name\": \"Patches\",\n \"description\": \"Git patches\",\n \"nip\": \"34\",\n \"template\": {\n \"kind\": 1617,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1618,\n \"name\": \"Pull Requests\",\n \"description\": \"Git pull request\",\n \"nip\": \"34\",\n \"template\": {\n \"kind\": 1618,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1619,\n \"name\": \"Pull Request Updates\",\n \"description\": \"Updates to git pull request\",\n \"nip\": \"34\",\n \"template\": {\n \"kind\": 1619,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1621,\n \"name\": \"Issues\",\n \"description\": \"Git issues\",\n \"nip\": \"34\",\n \"template\": {\n \"kind\": 1621,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1622,\n \"name\": \"Git Replies\",\n \"description\": \"Replies on git objects\",\n \"nip\": \"34\",\n \"deprecated\": true,\n \"template\": {\n \"kind\": 1622,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1630,\n \"name\": \"Status\",\n \"description\": \"Git status\",\n \"nip\": \"34\",\n \"template\": {\n \"kind\": 1630,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1631,\n \"name\": \"Status\",\n \"description\": \"Git status\",\n \"nip\": \"34\",\n \"template\": {\n \"kind\": 1631,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1632,\n \"name\": \"Status\",\n \"description\": \"Git status\",\n \"nip\": \"34\",\n \"template\": {\n \"kind\": 1632,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1633,\n \"name\": \"Status\",\n \"description\": \"Git status\",\n \"nip\": \"34\",\n \"template\": {\n \"kind\": 1633,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1808,\n \"name\": \"Live Stream\",\n \"description\": \"Live streaming event\",\n \"nip\": null,\n \"spec\": \"zap.stream\",\n \"template\": {\n \"kind\": 1808,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1971,\n \"name\": \"Problem Tracker\",\n \"description\": \"Problem tracking\",\n \"nip\": null,\n \"spec\": \"Nostrocket\",\n \"template\": {\n \"kind\": 1971,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1984,\n \"name\": \"Reporting\",\n \"description\": \"Report content or users\",\n \"nip\": \"56\",\n \"template\": {\n \"kind\": 1984,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1985,\n \"name\": \"Label\",\n \"description\": \"Label/tag content with namespace\",\n \"nip\": \"32\",\n \"template\": {\n \"kind\": 1985,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1986,\n \"name\": \"Relay Reviews\",\n \"description\": \"Reviews of relays\",\n \"nip\": null,\n \"template\": {\n \"kind\": 1986,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 1987,\n \"name\": \"AI Embeddings\",\n \"description\": \"AI embeddings/vector lists\",\n \"nip\": null,\n \"spec\": \"NKBIP-02\",\n \"template\": {\n \"kind\": 1987,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 2003,\n \"name\": \"Torrent\",\n \"description\": \"Torrent magnet link\",\n \"nip\": \"35\",\n \"template\": {\n \"kind\": 2003,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 2004,\n \"name\": \"Torrent Comment\",\n \"description\": \"Comment on torrent\",\n \"nip\": \"35\",\n \"template\": {\n \"kind\": 2004,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 2022,\n \"name\": \"Coinjoin Pool\",\n \"description\": \"Coinjoin coordination\",\n \"nip\": null,\n \"spec\": \"joinstr\",\n \"template\": {\n \"kind\": 2022,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 4550,\n \"name\": \"Community Post Approval\",\n \"description\": \"Approve post in community\",\n \"nip\": \"72\",\n \"template\": {\n \"kind\": 4550,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 5000,\n \"name\": \"Job Request\",\n \"description\": \"Data vending machine job request (start of range)\",\n \"nip\": \"90\",\n \"template\": {\n \"kind\": 5000,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 6000,\n \"name\": \"Job Result\",\n \"description\": \"Data vending machine job result (start of range)\",\n \"nip\": \"90\",\n \"template\": {\n \"kind\": 6000,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 7000,\n \"name\": \"Job Feedback\",\n \"description\": \"Feedback on job request/result\",\n \"nip\": \"90\",\n \"template\": {\n \"kind\": 7000,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 7374,\n \"name\": \"Reserved Cashu Wallet Tokens\",\n \"description\": \"Reserved Cashu wallet tokens\",\n \"nip\": \"60\",\n \"template\": {\n \"kind\": 7374,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 7375,\n \"name\": \"Cashu Wallet Tokens\",\n \"description\": \"Cashu wallet tokens\",\n \"nip\": \"60\",\n \"template\": {\n \"kind\": 7375,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 7376,\n \"name\": \"Cashu Wallet History\",\n \"description\": \"Cashu wallet transaction history\",\n \"nip\": \"60\",\n \"template\": {\n \"kind\": 7376,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 7516,\n \"name\": \"Geocache Log\",\n \"description\": \"Geocaching log entry\",\n \"nip\": null,\n \"spec\": \"geocaching\",\n \"template\": {\n \"kind\": 7516,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 7517,\n \"name\": \"Geocache Proof of Find\",\n \"description\": \"Proof of geocache find\",\n \"nip\": null,\n \"spec\": \"geocaching\",\n \"template\": {\n \"kind\": 7517,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 8000,\n \"name\": \"Add User\",\n \"description\": \"Add user to group\",\n \"nip\": \"43\",\n \"template\": {\n \"kind\": 8000,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 8001,\n \"name\": \"Remove User\",\n \"description\": \"Remove user from group\",\n \"nip\": \"43\",\n \"template\": {\n \"kind\": 8001,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 9000,\n \"name\": \"Group Control Events\",\n \"description\": \"Group control events (start of range)\",\n \"nip\": \"29\",\n \"template\": {\n \"kind\": 9000,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 9041,\n \"name\": \"Zap Goal\",\n \"description\": \"Fundraising goal for zaps\",\n \"nip\": \"75\",\n \"template\": {\n \"kind\": 9041,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 9321,\n \"name\": \"Nutzap\",\n \"description\": \"Cashu nutzap\",\n \"nip\": \"61\",\n \"template\": {\n \"kind\": 9321,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 9467,\n \"name\": \"Tidal Login\",\n \"description\": \"Tidal streaming login\",\n \"nip\": null,\n \"spec\": \"Tidal-nostr\",\n \"template\": {\n \"kind\": 9467,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 9734,\n \"name\": \"Zap Request\",\n \"description\": \"Request Lightning payment\",\n \"nip\": \"57\",\n \"template\": {\n \"kind\": 9734,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 9735,\n \"name\": \"Zap\",\n \"description\": \"Lightning payment receipt\",\n \"nip\": \"57\",\n \"template\": {\n \"kind\": 9735,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 9802,\n \"name\": \"Highlights\",\n \"description\": \"Highlighted text selection\",\n \"nip\": \"84\",\n \"template\": {\n \"kind\": 9802,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 10000,\n \"name\": \"Mute List\",\n \"description\": \"List of muted users/content\",\n \"nip\": \"51\",\n \"isReplaceable\": true,\n \"template\": {\n \"kind\": 10000,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 10001,\n \"name\": \"Pin List\",\n \"description\": \"Pinned events\",\n \"nip\": \"51\",\n \"isReplaceable\": true,\n \"template\": {\n \"kind\": 10001,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 10002,\n \"name\": \"Relay List Metadata\",\n \"description\": \"User's preferred relays for read/write\",\n \"nip\": \"65\",\n \"isReplaceable\": true,\n \"template\": {\n \"kind\": 10002,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 10003,\n \"name\": \"Bookmark List\",\n \"description\": \"Bookmarked events\",\n \"nip\": \"51\",\n \"isReplaceable\": true,\n \"template\": {\n \"kind\": 10003,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 10004,\n \"name\": \"Communities List\",\n \"description\": \"Communities user belongs to\",\n \"nip\": \"51\",\n \"isReplaceable\": true,\n \"template\": {\n \"kind\": 10004,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 10005,\n \"name\": \"Public Chats List\",\n \"description\": \"Public chats user is in\",\n \"nip\": \"51\",\n \"isReplaceable\": true,\n \"template\": {\n \"kind\": 10005,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 10006,\n \"name\": \"Blocked Relays List\",\n \"description\": \"Relays user has blocked\",\n \"nip\": \"51\",\n \"isReplaceable\": true,\n \"template\": {\n \"kind\": 10006,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 10007,\n \"name\": \"Search Relays List\",\n \"description\": \"Preferred search relays\",\n \"nip\": \"51\",\n \"isReplaceable\": true,\n \"template\": {\n \"kind\": 10007,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 10008,\n \"name\": \"Relay Group Configuration\",\n \"description\": \"Relay group configuration\",\n \"nip\": null,\n \"isReplaceable\": true,\n \"template\": {\n \"kind\": 10008,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 10009,\n \"name\": \"User Groups\",\n \"description\": \"Groups user belongs to\",\n \"nip\": \"29\",\n \"isReplaceable\": true,\n \"template\": {\n \"kind\": 10009,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 10012,\n \"name\": \"Favorite Relays List\",\n \"description\": \"User's favorite relays\",\n \"nip\": \"51\",\n \"isReplaceable\": true,\n \"template\": {\n \"kind\": 10012,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 10013,\n \"name\": \"Private Event Relay List\",\n \"description\": \"Relays for private events\",\n \"nip\": \"37\",\n \"isReplaceable\": true,\n \"template\": {\n \"kind\": 10013,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 10015,\n \"name\": \"Interests List\",\n \"description\": \"User interests/topics\",\n \"nip\": \"51\",\n \"isReplaceable\": true,\n \"template\": {\n \"kind\": 10015,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 10019,\n \"name\": \"Nutzap Mint Recommendation\",\n \"description\": \"Recommended Cashu mints for nutzaps\",\n \"nip\": \"61\",\n \"isReplaceable\": true,\n \"template\": {\n \"kind\": 10019,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 10020,\n \"name\": \"Media Follows\",\n \"description\": \"Followed media accounts\",\n \"nip\": \"51\",\n \"isReplaceable\": true,\n \"template\": {\n \"kind\": 10020,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 10030,\n \"name\": \"User Emoji List\",\n \"description\": \"Custom emoji list\",\n \"nip\": \"51\",\n \"isReplaceable\": true,\n \"template\": {\n \"kind\": 10030,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 10050,\n \"name\": \"DM Relays List\",\n \"description\": \"Relays to receive DMs on\",\n \"nip\": \"17\",\n \"isReplaceable\": true,\n \"template\": {\n \"kind\": 10050,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 10051,\n \"name\": \"KeyPackage Relays List\",\n \"description\": \"Marmot key package relays\",\n \"nip\": null,\n \"isReplaceable\": true,\n \"spec\": \"Marmot\",\n \"template\": {\n \"kind\": 10051,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 10063,\n \"name\": \"User Server List\",\n \"description\": \"Blossom server list\",\n \"nip\": null,\n \"isReplaceable\": true,\n \"spec\": \"Blossom\",\n \"template\": {\n \"kind\": 10063,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 10096,\n \"name\": \"File Storage Server List\",\n \"description\": \"File storage servers\",\n \"nip\": \"96\",\n \"isReplaceable\": true,\n \"deprecated\": true,\n \"template\": {\n \"kind\": 10096,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 10166,\n \"name\": \"Relay Monitor Announcement\",\n \"description\": \"Relay monitoring announcement\",\n \"nip\": \"66\",\n \"isReplaceable\": true,\n \"template\": {\n \"kind\": 10166,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 10312,\n \"name\": \"Room Presence\",\n \"description\": \"Presence in live room\",\n \"nip\": \"53\",\n \"isReplaceable\": true,\n \"template\": {\n \"kind\": 10312,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 10377,\n \"name\": \"Proxy Announcement\",\n \"description\": \"Nostr proxy announcement\",\n \"nip\": null,\n \"isReplaceable\": true,\n \"spec\": \"Nostr Epoxy\",\n \"template\": {\n \"kind\": 10377,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 11111,\n \"name\": \"Transport Method Announcement\",\n \"description\": \"Transport method announcement\",\n \"nip\": null,\n \"isReplaceable\": true,\n \"spec\": \"Nostr Epoxy\",\n \"template\": {\n \"kind\": 11111,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 12345,\n \"name\": \"Relay Policy Configuration\",\n \"description\": \"Relay-internal policy configuration (admin only)\",\n \"nip\": null,\n \"isReplaceable\": true,\n \"spec\": \"orly\",\n \"template\": {\n \"kind\": 12345,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 13004,\n \"name\": \"JWT Binding\",\n \"description\": \"Link between JWT certificate and pubkey\",\n \"nip\": null,\n \"isReplaceable\": true,\n \"template\": {\n \"kind\": 13004,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 13194,\n \"name\": \"Wallet Service Info\",\n \"description\": \"NWC wallet service information\",\n \"nip\": \"47\",\n \"isReplaceable\": true,\n \"template\": {\n \"kind\": 13194,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 13534,\n \"name\": \"Membership Lists\",\n \"description\": \"Group membership lists\",\n \"nip\": \"43\",\n \"isReplaceable\": true,\n \"template\": {\n \"kind\": 13534,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 14388,\n \"name\": \"User Sound Effect Lists\",\n \"description\": \"Sound effect lists\",\n \"nip\": null,\n \"isReplaceable\": true,\n \"spec\": \"Corny Chat\",\n \"template\": {\n \"kind\": 14388,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 17375,\n \"name\": \"Cashu Wallet Event\",\n \"description\": \"Cashu wallet event\",\n \"nip\": \"60\",\n \"isReplaceable\": true,\n \"template\": {\n \"kind\": 17375,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 21000,\n \"name\": \"Lightning Pub RPC\",\n \"description\": \"Lightning.Pub RPC\",\n \"nip\": null,\n \"isEphemeral\": true,\n \"spec\": \"Lightning.Pub\",\n \"template\": {\n \"kind\": 21000,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 22242,\n \"name\": \"Client Authentication\",\n \"description\": \"Authenticate to relay\",\n \"nip\": \"42\",\n \"isEphemeral\": true,\n \"template\": {\n \"kind\": 22242,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 23194,\n \"name\": \"Wallet Request\",\n \"description\": \"NWC wallet request\",\n \"nip\": \"47\",\n \"isEphemeral\": true,\n \"template\": {\n \"kind\": 23194,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 23195,\n \"name\": \"Wallet Response\",\n \"description\": \"NWC wallet response\",\n \"nip\": \"47\",\n \"isEphemeral\": true,\n \"template\": {\n \"kind\": 23195,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 23196,\n \"name\": \"Wallet Notification (NIP-04)\",\n \"description\": \"NWC wallet notification (NIP-04 encrypted)\",\n \"nip\": \"47\",\n \"isEphemeral\": true,\n \"template\": {\n \"kind\": 23196,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 23197,\n \"name\": \"Wallet Notification\",\n \"description\": \"NWC wallet notification\",\n \"nip\": \"47\",\n \"isEphemeral\": true,\n \"template\": {\n \"kind\": 23197,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 24133,\n \"name\": \"Nostr Connect\",\n \"description\": \"Remote signer connection\",\n \"nip\": \"46\",\n \"isEphemeral\": true,\n \"template\": {\n \"kind\": 24133,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 24242,\n \"name\": \"Blobs Stored on Mediaservers\",\n \"description\": \"Blossom blob storage\",\n \"nip\": null,\n \"isEphemeral\": true,\n \"spec\": \"Blossom\",\n \"template\": {\n \"kind\": 24242,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 27235,\n \"name\": \"HTTP Auth\",\n \"description\": \"Authenticate HTTP requests\",\n \"nip\": \"98\",\n \"isEphemeral\": true,\n \"template\": {\n \"kind\": 27235,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 28934,\n \"name\": \"Join Request\",\n \"description\": \"Request to join group\",\n \"nip\": \"43\",\n \"isEphemeral\": true,\n \"template\": {\n \"kind\": 28934,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 28935,\n \"name\": \"Invite Request\",\n \"description\": \"Invite to group\",\n \"nip\": \"43\",\n \"isEphemeral\": true,\n \"template\": {\n \"kind\": 28935,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 28936,\n \"name\": \"Leave Request\",\n \"description\": \"Leave group request\",\n \"nip\": \"43\",\n \"isEphemeral\": true,\n \"template\": {\n \"kind\": 28936,\n \"content\": \"\",\n \"tags\": []\n }\n },\n {\n \"kind\": 30000,\n \"name\": \"Follow Sets\",\n \"description\": \"Categorized people lists\",\n \"nip\": \"51\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30000,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30001,\n \"name\": \"Generic Lists\",\n \"description\": \"Generic categorized lists\",\n \"nip\": \"51\",\n \"isAddressable\": true,\n \"deprecated\": true,\n \"template\": {\n \"kind\": 30001,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30002,\n \"name\": \"Relay Sets\",\n \"description\": \"Categorized relay lists\",\n \"nip\": \"51\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30002,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30003,\n \"name\": \"Bookmark Sets\",\n \"description\": \"Categorized bookmark lists\",\n \"nip\": \"51\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30003,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30004,\n \"name\": \"Curation Sets\",\n \"description\": \"Curated content sets\",\n \"nip\": \"51\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30004,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30005,\n \"name\": \"Video Sets\",\n \"description\": \"Video playlists\",\n \"nip\": \"51\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30005,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30007,\n \"name\": \"Kind Mute Sets\",\n \"description\": \"Muted event kinds\",\n \"nip\": \"51\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30007,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30008,\n \"name\": \"Profile Badges\",\n \"description\": \"Badges displayed on profile\",\n \"nip\": \"58\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30008,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30009,\n \"name\": \"Badge Definition\",\n \"description\": \"Define a badge/achievement\",\n \"nip\": \"58\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30009,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30015,\n \"name\": \"Interest Sets\",\n \"description\": \"Interest/topic sets\",\n \"nip\": \"51\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30015,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30017,\n \"name\": \"Stall\",\n \"description\": \"Marketplace stall definition\",\n \"nip\": \"15\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30017,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30018,\n \"name\": \"Product\",\n \"description\": \"Marketplace product listing\",\n \"nip\": \"15\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30018,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30019,\n \"name\": \"Marketplace UI/UX\",\n \"description\": \"Marketplace interface settings\",\n \"nip\": \"15\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30019,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30020,\n \"name\": \"Product Sold as Auction\",\n \"description\": \"Auction product listing\",\n \"nip\": \"15\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30020,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30023,\n \"name\": \"Long-form Content\",\n \"description\": \"Blog post, article in markdown\",\n \"nip\": \"23\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30023,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30024,\n \"name\": \"Draft Long-form Content\",\n \"description\": \"Draft article\",\n \"nip\": \"23\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30024,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30030,\n \"name\": \"Emoji Sets\",\n \"description\": \"Custom emoji sets\",\n \"nip\": \"51\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30030,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30040,\n \"name\": \"Curated Publication Index\",\n \"description\": \"Publication index\",\n \"nip\": null,\n \"isAddressable\": true,\n \"spec\": \"NKBIP-01\",\n \"template\": {\n \"kind\": 30040,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30041,\n \"name\": \"Curated Publication Content\",\n \"description\": \"Publication content\",\n \"nip\": null,\n \"isAddressable\": true,\n \"spec\": \"NKBIP-01\",\n \"template\": {\n \"kind\": 30041,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30063,\n \"name\": \"Release Artifact Sets\",\n \"description\": \"Software release artifacts\",\n \"nip\": \"51\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30063,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30078,\n \"name\": \"Application-specific Data\",\n \"description\": \"App-specific key-value storage\",\n \"nip\": \"78\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30078,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30166,\n \"name\": \"Relay Discovery\",\n \"description\": \"Relay discovery/monitoring\",\n \"nip\": \"66\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30166,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30267,\n \"name\": \"App Curation Sets\",\n \"description\": \"Curated app sets\",\n \"nip\": \"51\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30267,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30311,\n \"name\": \"Live Event\",\n \"description\": \"Live streaming event\",\n \"nip\": \"53\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30311,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30312,\n \"name\": \"Interactive Room\",\n \"description\": \"Interactive live room\",\n \"nip\": \"53\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30312,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30313,\n \"name\": \"Conference Event\",\n \"description\": \"Conference/meetup event\",\n \"nip\": \"53\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30313,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30315,\n \"name\": \"User Statuses\",\n \"description\": \"User status updates\",\n \"nip\": \"38\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30315,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30388,\n \"name\": \"Slide Set\",\n \"description\": \"Presentation slides\",\n \"nip\": null,\n \"isAddressable\": true,\n \"spec\": \"Corny Chat\",\n \"template\": {\n \"kind\": 30388,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30402,\n \"name\": \"Classified Listing\",\n \"description\": \"Classified ad listing\",\n \"nip\": \"99\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30402,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30403,\n \"name\": \"Draft Classified Listing\",\n \"description\": \"Draft classified ad\",\n \"nip\": \"99\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30403,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30617,\n \"name\": \"Repository Announcements\",\n \"description\": \"Git repository announcement\",\n \"nip\": \"34\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30617,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30618,\n \"name\": \"Repository State Announcements\",\n \"description\": \"Git repository state\",\n \"nip\": \"34\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30618,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30818,\n \"name\": \"Wiki Article\",\n \"description\": \"Wiki article\",\n \"nip\": \"54\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30818,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 30819,\n \"name\": \"Redirects\",\n \"description\": \"URL redirects\",\n \"nip\": \"54\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 30819,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 31234,\n \"name\": \"Draft Event\",\n \"description\": \"Draft of any event\",\n \"nip\": \"37\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 31234,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 31388,\n \"name\": \"Link Set\",\n \"description\": \"Link collection\",\n \"nip\": null,\n \"isAddressable\": true,\n \"spec\": \"Corny Chat\",\n \"template\": {\n \"kind\": 31388,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 31890,\n \"name\": \"Feed\",\n \"description\": \"Custom feed definition\",\n \"nip\": null,\n \"isAddressable\": true,\n \"spec\": \"NUD: Custom Feeds\",\n \"template\": {\n \"kind\": 31890,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 31922,\n \"name\": \"Date-Based Calendar Event\",\n \"description\": \"All-day calendar event\",\n \"nip\": \"52\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 31922,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 31923,\n \"name\": \"Time-Based Calendar Event\",\n \"description\": \"Calendar event with time\",\n \"nip\": \"52\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 31923,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 31924,\n \"name\": \"Calendar\",\n \"description\": \"Calendar definition\",\n \"nip\": \"52\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 31924,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 31925,\n \"name\": \"Calendar Event RSVP\",\n \"description\": \"RSVP to calendar event\",\n \"nip\": \"52\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 31925,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 31989,\n \"name\": \"Handler Recommendation\",\n \"description\": \"Recommended app for event kind\",\n \"nip\": \"89\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 31989,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 31990,\n \"name\": \"Handler Information\",\n \"description\": \"App handler declaration\",\n \"nip\": \"89\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 31990,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 32123,\n \"name\": \"WaveLake Track\",\n \"description\": \"WaveLake music track\",\n \"nip\": null,\n \"isAddressable\": true,\n \"spec\": \"WaveLake\",\n \"template\": {\n \"kind\": 32123,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 32267,\n \"name\": \"Software Application\",\n \"description\": \"Software application listing\",\n \"nip\": null,\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 32267,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 32388,\n \"name\": \"User Room Favorites\",\n \"description\": \"Favorite rooms\",\n \"nip\": null,\n \"isAddressable\": true,\n \"spec\": \"Corny Chat\",\n \"template\": {\n \"kind\": 32388,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 33388,\n \"name\": \"High Scores\",\n \"description\": \"Game high scores\",\n \"nip\": null,\n \"isAddressable\": true,\n \"spec\": \"Corny Chat\",\n \"template\": {\n \"kind\": 33388,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 34235,\n \"name\": \"Video Event Horizontal\",\n \"description\": \"Horizontal video event\",\n \"nip\": \"71\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 34235,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 34236,\n \"name\": \"Video Event Vertical\",\n \"description\": \"Vertical video event\",\n \"nip\": \"71\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 34236,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 34388,\n \"name\": \"Sound Effects\",\n \"description\": \"Sound effect definitions\",\n \"nip\": null,\n \"isAddressable\": true,\n \"spec\": \"Corny Chat\",\n \"template\": {\n \"kind\": 34388,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 34550,\n \"name\": \"Community Definition\",\n \"description\": \"Define a community\",\n \"nip\": \"72\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 34550,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 37516,\n \"name\": \"Geocache Listing\",\n \"description\": \"Geocache location listing\",\n \"nip\": null,\n \"isAddressable\": true,\n \"spec\": \"geocaching\",\n \"template\": {\n \"kind\": 37516,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 38172,\n \"name\": \"Cashu Mint Announcement\",\n \"description\": \"Cashu mint announcement\",\n \"nip\": \"87\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 38172,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 38173,\n \"name\": \"Fedimint Announcement\",\n \"description\": \"Fedimint announcement\",\n \"nip\": \"87\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 38173,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 38383,\n \"name\": \"Peer-to-peer Order Events\",\n \"description\": \"P2P trading orders\",\n \"nip\": \"69\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 38383,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 39000,\n \"name\": \"Group Metadata Events\",\n \"description\": \"Group metadata (start of range)\",\n \"nip\": \"29\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 39000,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 39089,\n \"name\": \"Starter Packs\",\n \"description\": \"Starter pack lists\",\n \"nip\": \"51\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 39089,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 39092,\n \"name\": \"Media Starter Packs\",\n \"description\": \"Media starter packs\",\n \"nip\": \"51\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 39092,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 39701,\n \"name\": \"Web Bookmarks\",\n \"description\": \"Web URL bookmarks\",\n \"nip\": \"B0\",\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 39701,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n },\n {\n \"kind\": 39998,\n \"name\": \"ACL Event\",\n \"description\": \"Access control list event\",\n \"nip\": null,\n \"isAddressable\": true,\n \"template\": {\n \"kind\": 39998,\n \"content\": \"\",\n \"tags\": [\n [\n \"d\",\n \"identifier\"\n ]\n ]\n }\n }\n];\n\n// Kind ranges for classification\nexport const kindRanges = {\n \"regular\": {\n \"start\": 1000,\n \"end\": 9999,\n \"description\": \"Regular events - all versions kept, never replaced\"\n },\n \"replaceable\": {\n \"start\": 10000,\n \"end\": 19999,\n \"description\": \"Replaceable events - only latest per pubkey kept\"\n },\n \"ephemeral\": {\n \"start\": 20000,\n \"end\": 29999,\n \"description\": \"Ephemeral events - forwarded but not stored\"\n },\n \"parameterized\": {\n \"start\": 30000,\n \"end\": 39999,\n \"description\": \"Parameterized replaceable - replaced by d tag value\"\n }\n};\n\n// Privileged kinds (require auth)\nexport const privilegedKinds = [4,13,14,15,1059,1060,30078];\n\n// Directory kinds (public discovery)\nexport const directoryKinds = [0,3,5,1984,10002,10000,10050];\n\n// Kind aliases\nexport const kindAliases = {\n \"SetMetadata\": 0,\n \"Follows\": 3,\n \"Contacts\": 3,\n \"Deletion\": 5,\n \"MemoryHole\": 1984,\n \"BlockList\": 10000,\n \"Article\": 30023,\n \"CategorizedPeopleList\": 30000,\n \"CategorizedBookmarksList\": 30001\n};\n\n// Helper function to get event kind by number\nexport function getEventKind(kindNumber) {\n return eventKinds.find(k => k.kind === kindNumber);\n}\n\n// Alias for compatibility\nexport function getKindInfo(kind) {\n return getEventKind(kind);\n}\n\nexport function getKindName(kind) {\n const info = getEventKind(kind);\n return info ? info.name : `Kind ${kind}`;\n}\n\n// Helper function to search event kinds by name or description\nexport function searchEventKinds(query) {\n const lowerQuery = query.toLowerCase();\n return eventKinds.filter(k =>\n k.name.toLowerCase().includes(lowerQuery) ||\n k.description.toLowerCase().includes(lowerQuery) ||\n k.kind.toString().includes(query)\n );\n}\n\n// Helper function to get all event kinds grouped by category\nexport function getEventKindsByCategory() {\n return {\n regular: eventKinds.filter(k => k.kind < 10000 && !k.isReplaceable),\n replaceable: eventKinds.filter(k => k.isReplaceable),\n ephemeral: eventKinds.filter(k => k.isEphemeral),\n addressable: eventKinds.filter(k => k.isAddressable)\n };\n}\n\n// Helper function to create a template event with current timestamp\nexport function createTemplateEvent(kindNumber, userPubkey = null) {\n const kindInfo = getEventKind(kindNumber);\n if (!kindInfo) {\n return {\n kind: kindNumber,\n content: \"\",\n tags: [],\n created_at: Math.floor(Date.now() / 1000),\n pubkey: userPubkey || \"\"\n };\n }\n\n return {\n ...kindInfo.template,\n created_at: Math.floor(Date.now() / 1000),\n pubkey: userPubkey || \"\"\n };\n}\n\nexport function isReplaceable(kind) {\n if (kind === 0 || kind === 3) return true;\n return kind >= 10000 && kind < 19999;\n}\n\nexport function isEphemeral(kind) {\n return kind >= 20000 && kind < 29999;\n}\n\nexport function isAddressable(kind) {\n return kind >= 30000 && kind <= 39999;\n}\n\nexport function isPrivileged(kind) {\n return privilegedKinds.includes(kind);\n}\n\n// Export kind categories for filtering in UI\nexport const kindCategories = [\n { id: \"all\", name: \"All Kinds\", filter: () => true },\n { id: \"regular\", name: \"Regular Events (0-9999)\", filter: k => k.kind < 10000 && !k.isReplaceable },\n { id: \"replaceable\", name: \"Replaceable (10000-19999)\", filter: k => k.isReplaceable },\n { id: \"ephemeral\", name: \"Ephemeral (20000-29999)\", filter: k => k.isEphemeral },\n { id: \"addressable\", name: \"Addressable (30000-39999)\", filter: k => k.isAddressable },\n { id: \"social\", name: \"Social\", filter: k => [0, 1, 3, 6, 7].includes(k.kind) },\n { id: \"messaging\", name: \"Messaging\", filter: k => [4, 9, 10, 11, 12, 14, 15, 40, 41, 42].includes(k.kind) },\n { id: \"lists\", name: \"Lists\", filter: k => k.name.toLowerCase().includes(\"list\") || k.name.toLowerCase().includes(\"set\") },\n { id: \"marketplace\", name: \"Marketplace\", filter: k => [30017, 30018, 30019, 30020, 1021, 1022, 30402, 30403].includes(k.kind) },\n { id: \"lightning\", name: \"Lightning/Zaps\", filter: k => [9734, 9735, 9041, 9321, 7374, 7375, 7376].includes(k.kind) },\n { id: \"media\", name: \"Media\", filter: k => [20, 21, 22, 1063, 1222, 1244].includes(k.kind) },\n { id: \"git\", name: \"Git/Code\", filter: k => [818, 1337, 1617, 1618, 1619, 1621, 1622, 30617, 30618].includes(k.kind) },\n { id: \"calendar\", name: \"Calendar\", filter: k => [31922, 31923, 31924, 31925].includes(k.kind) },\n { id: \"groups\", name: \"Groups\", filter: k => (k.kind >= 9000 && k.kind <= 9030) || (k.kind >= 39000 && k.kind <= 39009) },\n];\n","\n\n \n\n{#if isOpen}\n \n \n \n
\n \n\n
\n
\n \n
\n\n
\n {#each kindCategories as category}\n selectedCategory = category.id}\n >\n {category.name}\n \n {/each}\n
\n
\n\n
\n
\n {#if filteredKinds.length === 0}\n
\n No event kinds found matching \"{searchQuery}\"\n
\n {:else}\n {#each filteredKinds as kindInfo}\n
selectKind(kindInfo)}\n >\n \n {kindInfo.name}
\n {kindInfo.description}
\n \n {/each}\n {/if}\n
\n
\n\n \n
\n
\n{/if}\n\n\n","\n\n\n \n\n {#if publishError}\n
\n
\n ⚠ \n {publishError} \n
\n
× \n
\n {/if}\n\n
\n \n
\n
\n\n\n\n\n","\n\n\n
Sprocket Script Management \n {#if isLoggedIn && userRole === \"owner\"}\n
\n \n\n
\n
Upload Script \n
\n \n \n 📤 Upload & Update\n \n
\n
\n\n
\n
\n Status: \n \n {sprocketStatus?.is_running\n ? \"🟢 Running\"\n : \"🔴 Stopped\"}\n \n
\n {#if sprocketStatus?.pid}\n
\n PID: \n {sprocketStatus.pid} \n
\n {/if}\n
\n Script: \n {sprocketStatus?.script_exists\n ? \"✅ Exists\"\n : \"❌ Not found\"} \n
\n
\n\n
\n \n
\n\n
\n \n 💾 Save & Update\n \n \n 📥 Load Current\n \n
\n\n {#if sprocketMessage}\n
\n {sprocketMessage}\n
\n {/if}\n
\n\n
\n
Script Versions \n
\n {#each sprocketVersions as version}\n
\n
\n
\n {version.name}\n
\n
\n {new Date(version.modified).toLocaleString()}\n {#if version.is_current}\n Current \n {/if}\n
\n
\n
\n loadVersion(version)}\n disabled={isLoadingSprocket}\n >\n 📥 Load\n \n {#if !version.is_current}\n deleteVersion(version.name)}\n disabled={isLoadingSprocket}\n >\n 🗑️ Delete\n \n {/if}\n
\n
\n {/each}\n
\n\n
\n 🔄 Refresh Versions\n \n
\n {:else if isLoggedIn}\n
\n
❌ Owner permission required for sprocket management.
\n
\n To enable sprocket functionality, set the ORLY_OWNERS environment variable with your npub when starting the relay.\n
\n
\n Current user role: {userRole || \"none\"} \n
\n
\n {:else}\n
\n
Please log in to access sprocket management.
\n
Log In \n
\n {/if}\n
\n\n\n","\n\n\n
Policy Configuration \n {#if isLoggedIn && (userRole === \"owner\" || isPolicyAdmin)}\n
\n \n\n
\n
\n Edit the policy JSON below and click \"Save & Publish\" to update the relay's policy configuration.\n Changes are applied immediately after validation.\n
\n
\n Policy updates are published as kind 12345 events and require policy admin permissions.\n
\n
\n\n
\n \n
\n\n {#if validationErrors.length > 0}\n
\n
Validation Errors: \n
\n {#each validationErrors as error}\n {error} \n {/each}\n \n
\n {/if}\n\n
\n \n Load Current\n \n \n Format JSON\n \n \n Validate\n \n \n Save & Publish\n \n
\n\n {#if policyMessage}\n
\n {policyMessage}\n
\n {/if}\n
\n\n \n
\n
Policy Administrators \n
\n
\n Policy admins can update the relay's policy configuration via kind 12345 events.\n Their follows get whitelisted if policy_follow_whitelist_enabled is true in the policy.\n
\n
\n Note: Policy admins are separate from relay admins (ORLY_ADMINS).\n Changes here update the JSON editor - click \"Save & Publish\" to apply.\n
\n
\n\n
\n {#if policyAdmins.length === 0}\n
No policy admins configured
\n {:else}\n {#each policyAdmins as admin}\n
\n {admin.substring(0, 16)}...{admin.substring(admin.length - 8)} \n removePolicyAdmin(admin)}\n disabled={isLoadingPolicy}\n title=\"Remove admin\"\n >\n ✕\n \n
\n {/each}\n {/if}\n
\n\n
\n e.key === \"Enter\" && addPolicyAdmin()}\n />\n \n + Add Admin\n \n
\n
\n\n \n
\n
Policy Follow Whitelist \n
\n
\n Pubkeys followed by policy admins (kind 3 events).\n These get automatic read+write access when rules have write_allow_follows: true.\n
\n
\n\n \n\n
\n {#if policyFollows.length === 0}\n
No follows loaded. Click \"Refresh Follows\" to load from database.
\n {:else}\n
\n {#each policyFollows as follow}\n
\n {follow.substring(0, 12)}...{follow.substring(follow.length - 6)}\n
\n {/each}\n
\n {/if}\n
\n
\n\n
\n
Policy Reference \n
\n
Structure Overview \n
\n kind.whitelist - Only allow these event kinds (takes precedence) \n kind.blacklist - Deny these event kinds (if no whitelist) \n global - Rules applied to all events \n rules - Per-kind rules (keyed by kind number as string) \n default_policy - \"allow\" or \"deny\" when no rules match \n policy_admins - Hex pubkeys that can update policy \n policy_follow_whitelist_enabled - Enable follow-based access \n \n\n
Rule Fields \n
\n description - Human-readable rule description \n write_allow / write_deny - Pubkey lists for write access \n read_allow / read_deny - Pubkey lists for read access \n write_allow_follows - Grant access to policy admin follows \n size_limit - Max total event size in bytes \n content_limit - Max content field size in bytes \n max_expiry - Max expiry offset in seconds \n max_age_of_event - Max age of created_at in seconds \n max_age_event_in_future - Max future offset in seconds \n must_have_tags - Required tag letters (e.g., [\"d\", \"t\"]) \n tag_validation - Regex patterns for tag values \n script - Path to external validation script \n \n\n
Example Policy \n
{examplePolicy} \n
\n
\n {:else if isLoggedIn}\n
\n
Policy configuration requires owner or policy admin permissions.
\n
\n To become a policy admin, ask an existing policy admin to add your pubkey\n to the policy_admins list.\n
\n
\n Current user role: {userRole || \"none\"} \n
\n
\n {:else}\n
\n
Please log in to access policy configuration.
\n
Log In \n
\n {/if}\n
\n\n\n","\n\n \n\n{#if canAccess}\n \n \n\n {#if !isAdminView && !selectedAdminUser}\n
\n \n \n Select Files\n \n {#if selectedFiles.length > 0}\n {selectedFiles.length} file(s) selected \n \n {isUploading ? uploadProgress : \"Upload\"}\n \n {/if}\n
\n {/if}\n\n {#if error}\n
\n {error}\n
\n {/if}\n\n {#if isAdminView && !selectedAdminUser}\n \n {#if isLoadingAdmin}\n
Loading user statistics...
\n {:else if adminUserStats.length === 0}\n
\n
No users have uploaded files yet.
\n
\n {:else}\n
\n {#each adminUserStats as userStat}\n
selectUser(userStat)}\n on:keypress={(e) => e.key === \"Enter\" && selectUser(userStat)}\n role=\"button\"\n tabindex=\"0\"\n >\n
\n {#if userStat.profile?.picture}\n
\n {:else}\n
\n {/if}\n
\n
\n
\n {userStat.profile?.name || truncateNpub(hexToNpub(userStat.pubkey))}\n
\n
\n {truncateNpub(hexToNpub(userStat.pubkey))}\n
\n
\n
\n {userStat.blob_count} files \n {formatSize(userStat.total_size_bytes)} \n
\n
\n {/each}\n
\n {/if}\n {:else}\n \n {#if isLoading && getDisplayBlobs().length === 0}\n
Loading blobs...
\n {:else if getDisplayBlobs().length === 0}\n
\n
{selectedAdminUser ? \"No files found for this user.\" : \"No files found in your Blossom storage.\"}
\n
\n {:else}\n
\n {#each getDisplayBlobs() as blob}\n
openModal(blob)}\n on:keypress={(e) => e.key === \"Enter\" && openModal(blob)}\n role=\"button\"\n tabindex=\"0\"\n >\n
\n {getMimeIcon(blob.type)}\n
\n
\n
\n {truncateHash(blob.sha256)}\n
\n
\n {formatSize(blob.size)} \n {blob.type || \"unknown\"} \n
\n
\n
\n {formatDate(blob.uploaded)}\n
\n
deleteBlob(blob)}\n title=\"Delete\"\n >\n X\n \n
\n {/each}\n
\n {/if}\n {/if}\n
\n{:else}\n \n
Please log in to view your Blossom storage.
\n
Log In \n
\n{/if}\n\n{#if showModal && selectedBlob}\n e.key === \"Enter\" && closeModal()}\n role=\"button\"\n tabindex=\"0\"\n >\n
\n \n
\n {#if getMimeCategory(selectedBlob.type) === \"image\"}\n
\n {:else if getMimeCategory(selectedBlob.type) === \"video\"}\n
\n \n \n \n
\n {:else if getMimeCategory(selectedBlob.type) === \"audio\"}\n
\n {:else}\n
\n
{getMimeIcon(selectedBlob.type)}
\n
Preview not available for this file type.
\n
\n Download File\n \n
\n {/if}\n
\n \n
\n
\n{/if}\n\n\n","\n\n{#if showFilter && hasFilter}\n \n{/if}\n\n\n\n","import { kindNames } from './constants.js';\n\n/**\n * Get human-readable name for a Nostr event kind\n * @param {number} kind - The event kind number\n * @returns {string} Human readable kind name\n */\nexport function getKindName(kind) {\n return kindNames[kind] || `Kind ${kind}`;\n}\n\n/**\n * Truncate a pubkey for display\n * @param {string} pubkey - The full pubkey hex string\n * @returns {string} Truncated pubkey\n */\nexport function truncatePubkey(pubkey) {\n if (!pubkey) return \"unknown\";\n return pubkey.slice(0, 8) + \"...\" + pubkey.slice(-8);\n}\n\n/**\n * Truncate content for preview display\n * @param {string} content - The content to truncate\n * @param {number} maxLength - Maximum length before truncation\n * @returns {string} Truncated content\n */\nexport function truncateContent(content, maxLength = 100) {\n if (!content) return \"\";\n return content.length > maxLength\n ? content.slice(0, maxLength) + \"...\"\n : content;\n}\n\n/**\n * Format a Unix timestamp for display\n * @param {number} timestamp - Unix timestamp in seconds\n * @returns {string} Formatted date/time string\n */\nexport function formatTimestamp(timestamp) {\n if (!timestamp) return \"\";\n return new Date(timestamp * 1000).toLocaleString();\n}\n\n/**\n * Escape HTML special characters to prevent XSS\n * @param {string} str - String to escape\n * @returns {string} Escaped string\n */\nexport function escapeHtml(str) {\n if (!str) return \"\";\n return str\n .replace(/&/g, \"&\")\n .replace(//g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\n/**\n * Convert \"about\" text to safe HTML with line breaks\n * @param {string} text - The about text\n * @returns {string} HTML with line breaks\n */\nexport function aboutToHtml(text) {\n if (!text) return \"\";\n return escapeHtml(text).replace(/\\n\\n/g, \" \");\n}\n\n/**\n * Copy text to clipboard with fallback for older browsers\n * @param {string} text - Text to copy\n * @returns {Promise} Whether copy succeeded\n */\nexport async function copyToClipboard(text) {\n try {\n await navigator.clipboard.writeText(text);\n return true;\n } catch (error) {\n console.error(\"Failed to copy to clipboard:\", error);\n // Fallback for older browsers\n try {\n const textArea = document.createElement(\"textarea\");\n textArea.value = text;\n document.body.appendChild(textArea);\n textArea.select();\n document.execCommand(\"copy\");\n document.body.removeChild(textArea);\n return true;\n } catch (fallbackError) {\n console.error(\"Fallback copy also failed:\", fallbackError);\n return false;\n }\n }\n}\n\n/**\n * Show copy feedback on a button element\n * @param {HTMLElement} button - The button element\n * @param {boolean} success - Whether copy succeeded\n */\nexport function showCopyFeedback(button, success = true) {\n if (!button) return;\n const originalText = button.textContent;\n const originalBg = button.style.backgroundColor;\n\n if (success) {\n button.textContent = \"\u0005\";\n button.style.backgroundColor = \"#4CAF50\";\n } else {\n button.textContent = \"L\";\n button.style.backgroundColor = \"#f44336\";\n }\n\n setTimeout(() => {\n button.textContent = originalText;\n button.style.backgroundColor = originalBg;\n }, 2000);\n}\n","/**\n * WebSocket Authentication Module for Nostr Relays\n * Implements NIP-42 authentication with proper challenge handling\n */\n\nexport class NostrWebSocketAuth {\n constructor(relayUrl, userSigner, userPubkey) {\n this.relayUrl = relayUrl;\n this.userSigner = userSigner;\n this.userPubkey = userPubkey;\n this.ws = null;\n this.challenge = null;\n this.isAuthenticated = false;\n this.authPromise = null;\n }\n\n /**\n * Connect to relay and handle authentication\n */\n async connect() {\n return new Promise((resolve, reject) => {\n this.ws = new WebSocket(this.relayUrl);\n \n this.ws.onopen = () => {\n console.log('WebSocket connected to relay:', this.relayUrl);\n resolve();\n };\n \n this.ws.onmessage = async (message) => {\n try {\n const data = JSON.parse(message.data);\n await this.handleMessage(data);\n } catch (error) {\n console.error('Error parsing relay message:', error);\n }\n };\n \n this.ws.onerror = (error) => {\n console.error('WebSocket error:', error);\n reject(new Error('Failed to connect to relay'));\n };\n \n this.ws.onclose = () => {\n console.log('WebSocket connection closed');\n this.isAuthenticated = false;\n this.challenge = null;\n };\n \n // Timeout for connection\n setTimeout(() => {\n if (this.ws.readyState !== WebSocket.OPEN) {\n reject(new Error('Connection timeout'));\n }\n }, 10000);\n });\n }\n\n /**\n * Handle incoming messages from relay\n */\n async handleMessage(data) {\n const [messageType, ...params] = data;\n \n switch (messageType) {\n case 'AUTH':\n // Relay sent authentication challenge\n this.challenge = params[0];\n console.log('Received AUTH challenge:', this.challenge);\n await this.authenticate();\n break;\n \n case 'OK':\n const [eventId, success, reason] = params;\n if (eventId && success) {\n console.log('Authentication successful for event:', eventId);\n this.isAuthenticated = true;\n if (this.authPromise) {\n this.authPromise.resolve();\n this.authPromise = null;\n }\n } else if (eventId && !success) {\n console.error('Authentication failed:', reason);\n if (this.authPromise) {\n this.authPromise.reject(new Error(reason || 'Authentication failed'));\n this.authPromise = null;\n }\n }\n break;\n \n case 'NOTICE':\n console.log('Relay notice:', params[0]);\n break;\n \n default:\n console.log('Unhandled message type:', messageType, params);\n }\n }\n\n /**\n * Authenticate with the relay using NIP-42\n */\n async authenticate() {\n if (!this.challenge) {\n throw new Error('No challenge received from relay');\n }\n \n if (!this.userSigner) {\n throw new Error('No signer available for authentication');\n }\n \n try {\n // Create NIP-42 authentication event\n const authEvent = {\n kind: 22242, // ClientAuthentication kind\n created_at: Math.floor(Date.now() / 1000),\n tags: [\n ['relay', this.relayUrl],\n ['challenge', this.challenge]\n ],\n content: '',\n pubkey: this.userPubkey\n };\n \n // Sign the authentication event\n const signedAuthEvent = await this.userSigner.signEvent(authEvent);\n \n // Send AUTH message to relay\n const authMessage = [\"AUTH\", signedAuthEvent];\n this.ws.send(JSON.stringify(authMessage));\n \n console.log('Sent authentication event to relay');\n \n // Wait for authentication response\n return new Promise((resolve, reject) => {\n this.authPromise = { resolve, reject };\n \n // Timeout for authentication\n setTimeout(() => {\n if (this.authPromise) {\n this.authPromise.reject(new Error('Authentication timeout'));\n this.authPromise = null;\n }\n }, 10000);\n });\n \n } catch (error) {\n console.error('Authentication error:', error);\n throw error;\n }\n }\n\n /**\n * Publish an event to the relay\n */\n async publishEvent(event) {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n throw new Error('WebSocket not connected');\n }\n \n return new Promise((resolve, reject) => {\n // Send EVENT message\n const eventMessage = [\"EVENT\", event];\n this.ws.send(JSON.stringify(eventMessage));\n \n // Set up message handler for this specific event\n const originalOnMessage = this.ws.onmessage;\n const timeout = setTimeout(() => {\n this.ws.onmessage = originalOnMessage;\n reject(new Error('Publish timeout'));\n }, 15000);\n \n this.ws.onmessage = async (message) => {\n try {\n const data = JSON.parse(message.data);\n const [messageType, eventId, success, reason] = data;\n \n if (messageType === 'OK' && eventId === event.id) {\n if (success) {\n clearTimeout(timeout);\n this.ws.onmessage = originalOnMessage;\n console.log('Event published successfully:', eventId);\n resolve({ success: true, eventId, reason });\n } else {\n console.error('Event publish failed:', reason);\n\n // Check if authentication is required\n if (reason && reason.includes('auth-required')) {\n console.log('Authentication required, waiting for AUTH challenge...');\n // Don't restore original handler yet - we need to receive the AUTH challenge\n // The AUTH message will be handled by the else branch below\n return;\n }\n\n clearTimeout(timeout);\n this.ws.onmessage = originalOnMessage;\n reject(new Error(`Publish failed: ${reason}`));\n }\n } else if (messageType === 'AUTH') {\n // Handle AUTH challenge during publish flow\n this.challenge = data[1];\n console.log('Received AUTH challenge during publish:', this.challenge);\n\n try {\n await this.authenticate();\n console.log('Authentication successful, retrying event publish...');\n // Re-send the event after authentication\n const retryMessage = [\"EVENT\", event];\n this.ws.send(JSON.stringify(retryMessage));\n // Don't resolve yet, wait for the retry response\n } catch (authError) {\n clearTimeout(timeout);\n this.ws.onmessage = originalOnMessage;\n reject(new Error(`Authentication failed: ${authError.message}`));\n }\n } else {\n // Handle other messages normally\n await this.handleMessage(data);\n }\n } catch (error) {\n clearTimeout(timeout);\n this.ws.onmessage = originalOnMessage;\n reject(error);\n }\n };\n });\n }\n\n /**\n * Close the WebSocket connection\n */\n close() {\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n this.isAuthenticated = false;\n this.challenge = null;\n }\n\n /**\n * Check if currently authenticated\n */\n getAuthenticated() {\n return this.isAuthenticated;\n }\n}\n\n/**\n * Convenience function to publish an event with authentication\n */\nexport async function publishEventWithAuth(relayUrl, event, userSigner, userPubkey) {\n const auth = new NostrWebSocketAuth(relayUrl, userSigner, userPubkey);\n \n try {\n await auth.connect();\n const result = await auth.publishEvent(event);\n return result;\n } finally {\n auth.close();\n }\n}\n","\n\n\n