Compare commits

..
Author SHA1 Message Date
raucao f0a19e30b8 Don't load actual map tiles in tests
CI / Lint (pull_request) Successful in 31s
CI / Test (pull_request) Failing after 1m6s
Release Drafter / Update release notes draft (pull_request) Successful in 4s
We don't need remote tiles for testing our functionality
2026-06-06 12:34:59 +04:00
57 changed files with 267 additions and 1906 deletions

No files matched your search

+3 -52
View File
@@ -9,7 +9,6 @@ import SearchBox from '#components/search-box';
import CategoryChips from '#components/category-chips'; import CategoryChips from '#components/category-chips';
import { and } from 'ember-truth-helpers'; import { and } from 'ember-truth-helpers';
import cachedImage from '../modifiers/cached-image'; import cachedImage from '../modifiers/cached-image';
import { POI_CATEGORIES } from '../utils/poi-categories';
export default class AppHeaderComponent extends Component { export default class AppHeaderComponent extends Component {
@service storage; @service storage;
@@ -17,59 +16,11 @@ export default class AppHeaderComponent extends Component {
@service nostrAuth; @service nostrAuth;
@service nostrData; @service nostrData;
@service mapUi; @service mapUi;
@service router;
@tracked isUserMenuOpen = false; @tracked isUserMenuOpen = false;
@tracked searchQuery = ''; @tracked searchQuery = '';
constructor() { get hasQuery() {
super(...arguments); return !!this.searchQuery;
if (this.router && typeof this.router.on === 'function') {
this.router.on('routeDidChange', this.syncSearchQuery);
}
this.syncSearchQuery();
}
willDestroy() {
if (this.router && typeof this.router.off === 'function') {
this.router.off('routeDidChange', this.syncSearchQuery);
}
super.willDestroy(...arguments);
}
@action
syncSearchQuery() {
const qp =
this.mapUi.currentSearch || this.router?.currentRoute?.queryParams;
if (qp?.q) {
this.searchQuery = qp.q;
} else if (qp?.category) {
const category = POI_CATEGORIES.find((c) => c.id === qp.category);
this.searchQuery = category ? category.label : qp.category;
} else {
this.searchQuery = '';
}
}
get isSearching() {
// 1. If we are actively focusing/typing in the search box with a query, hide pills
if (this.mapUi.searchBoxHasFocus && this.searchQuery) {
return true;
}
// 2. If we are on the search route, check loading and results status
if (this.router?.currentRouteName === 'search') {
if (this.mapUi.loadingState) {
return false; // Keep pills visible while loading
}
return this.mapUi.searchResults && this.mapUi.searchResults.length > 0;
}
// 3. Fallback for integration tests (non-search route with a query)
if (this.router?.currentRouteName !== 'search' && this.searchQuery) {
return true;
}
return false;
} }
get showQuickSearch() { get showQuickSearch() {
@@ -110,7 +61,7 @@ export default class AppHeaderComponent extends Component {
</div> </div>
{{#if this.showQuickSearch}} {{#if this.showQuickSearch}}
<div class="header-center {{if this.isSearching 'searching'}}"> <div class="header-center {{if this.hasQuery 'searching'}}">
<CategoryChips @onSelect={{this.handleChipSelect}} /> <CategoryChips @onSelect={{this.handleChipSelect}} />
</div> </div>
{{/if}} {{/if}}
+2 -2
View File
@@ -3,11 +3,11 @@ import Icon from '#components/icon';
<template> <template>
{{! template-lint-disable no-nested-interactive }} {{! template-lint-disable no-nested-interactive }}
<div class="sidebar-header has-back-btn"> <div class="sidebar-header">
<button type="button" class="back-btn" {{on "click" @onBack}}> <button type="button" class="back-btn" {{on "click" @onBack}}>
<Icon @name="arrow-left" @size={{20}} @color="#333" /> <Icon @name="arrow-left" @size={{20}} @color="#333" />
</button> </button>
<h2 class="sidebar-header-text-centered">About</h2> <h2>About</h2>
<button type="button" class="close-btn" {{on "click" @onClose}}> <button type="button" class="close-btn" {{on "click" @onClose}}>
<Icon @name="x" @size={{20}} @color="#333" /> <Icon @name="x" @size={{20}} @color="#333" />
</button> </button>
-6
View File
@@ -19,12 +19,6 @@ import iconRounded from '../../icons/icon-rounded.svg?raw';
<div class="sidebar-content"> <div class="sidebar-content">
<ul class="app-menu"> <ul class="app-menu">
<li>
<button type="button" {{on "click" @onSavedPlaces}}>
<Icon @name="bookmark" @size={{20}} />
<span>Collections</span>
</button>
</li>
<li> <li>
<button type="button" {{on "click" (fn @onNavigate "settings")}}> <button type="button" {{on "click" (fn @onNavigate "settings")}}>
<Icon @name="settings" @size={{20}} /> <Icon @name="settings" @size={{20}} />
+1 -12
View File
@@ -2,7 +2,6 @@ import Component from '@glimmer/component';
import { action } from '@ember/object'; import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking'; import { tracked } from '@glimmer/tracking';
import { fn } from '@ember/helper'; import { fn } from '@ember/helper';
import { service } from '@ember/service';
import eq from 'ember-truth-helpers/helpers/eq'; import eq from 'ember-truth-helpers/helpers/eq';
import AppMenuHome from './home'; import AppMenuHome from './home';
@@ -10,7 +9,6 @@ import AppMenuSettings from './settings';
import AppMenuAbout from './about'; import AppMenuAbout from './about';
export default class AppMenu extends Component { export default class AppMenu extends Component {
@service router;
@tracked currentView = 'menu'; // 'menu', 'settings', 'about' @tracked currentView = 'menu'; // 'menu', 'settings', 'about'
@action @action
@@ -18,19 +16,10 @@ export default class AppMenu extends Component {
this.currentView = view; this.currentView = view;
} }
@action
goToSavedPlaces() {
this.router.transitionTo('lists.index');
}
<template> <template>
<div class="sidebar app-menu-pane"> <div class="sidebar app-menu-pane">
{{#if (eq this.currentView "menu")}} {{#if (eq this.currentView "menu")}}
<AppMenuHome <AppMenuHome @onNavigate={{this.setView}} @onClose={{@onClose}} />
@onNavigate={{this.setView}}
@onClose={{@onClose}}
@onSavedPlaces={{this.goToSavedPlaces}}
/>
{{else if (eq this.currentView "settings")}} {{else if (eq this.currentView "settings")}}
<AppMenuSettings <AppMenuSettings
+2 -2
View File
@@ -21,11 +21,11 @@ export default class AppMenuSettings extends Component {
} }
<template> <template>
<div class="sidebar-header has-back-btn"> <div class="sidebar-header">
<button type="button" class="back-btn" {{on "click" @onBack}}> <button type="button" class="back-btn" {{on "click" @onBack}}>
<Icon @name="arrow-left" @size={{20}} @color="#333" /> <Icon @name="arrow-left" @size={{20}} @color="#333" />
</button> </button>
<h2 class="sidebar-header-text-centered">Settings</h2> <h2>Settings</h2>
<button type="button" class="close-btn" {{on "click" @onClose}}> <button type="button" class="close-btn" {{on "click" @onClose}}>
<Icon @name="x" @size={{20}} @color="#333" /> <Icon @name="x" @size={{20}} @color="#333" />
</button> </button>
+41 -183
View File
@@ -5,11 +5,7 @@ import { tracked } from '@glimmer/tracking';
import { service } from '@ember/service'; import { service } from '@ember/service';
import { fn } from '@ember/helper'; import { fn } from '@ember/helper';
import Icon from '#components/icon'; import Icon from '#components/icon';
import { import { normalizeRelayUrl } from '../../../utils/nostr';
excludeRequiredRelays,
mergeRequiredRelays,
normalizeRelayUrl,
} from '../../../utils/nostr';
const stripProtocol = (url) => (url ? url.replace(/^wss?:\/\//, '') : ''); const stripProtocol = (url) => (url ? url.replace(/^wss?:\/\//, '') : '');
@@ -21,74 +17,6 @@ export default class AppMenuSettingsNostr extends Component {
@tracked newReadRelay = ''; @tracked newReadRelay = '';
@tracked newWriteRelay = ''; @tracked newWriteRelay = '';
get customReadRelays() {
return excludeRequiredRelays(
this.settings.nostrReadRelays || [],
this.nostrData.requiredReadRelays
);
}
get customWriteRelays() {
return excludeRequiredRelays(
this.settings.nostrWriteRelays || [],
this.nostrData.requiredWriteRelays
);
}
get readRelayExclusions() {
return this.settings.nostrReadRelayExclusions || [];
}
get writeRelayExclusions() {
return this.settings.nostrWriteRelayExclusions || [];
}
get requiredReadRelaySet() {
return new Set(this.nostrData.requiredReadRelays.filter(Boolean));
}
get requiredWriteRelaySet() {
return new Set(this.nostrData.requiredWriteRelays.filter(Boolean));
}
get mailboxReadRelaySet() {
return new Set(this.nostrData.mailboxReadRelays);
}
get mailboxWriteRelaySet() {
return new Set(this.nostrData.mailboxWriteRelays);
}
get hasReadOverrides() {
return (
this.customReadRelays.length > 0 || this.readRelayExclusions.length > 0
);
}
get hasWriteOverrides() {
return (
this.customWriteRelays.length > 0 || this.writeRelayExclusions.length > 0
);
}
get readRelaysForDisplay() {
return this.nostrData.activeReadRelays.map((url) => {
return {
url,
isRequired: this.requiredReadRelaySet.has(url),
};
});
}
get writeRelaysForDisplay() {
return this.nostrData.activeWriteRelays.map((url) => {
return {
url,
isRequired: this.requiredWriteRelaySet.has(url),
};
});
}
@action @action
updateNewReadRelay(event) { updateNewReadRelay(event) {
this.newReadRelay = event.target.value; this.newReadRelay = event.target.value;
@@ -104,51 +32,19 @@ export default class AppMenuSettingsNostr extends Component {
const url = normalizeRelayUrl(this.newReadRelay); const url = normalizeRelayUrl(this.newReadRelay);
if (!url) return; if (!url) return;
const merged = mergeRequiredRelays(this.nostrData.requiredReadRelays, [ const current =
...this.customReadRelays, this.settings.nostrReadRelays || this.nostrData.defaultReadRelays;
url, const set = new Set([...current, url]);
]); this.settings.update('nostrReadRelays', Array.from(set));
const custom = excludeRequiredRelays(
merged,
this.nostrData.requiredReadRelays
);
const readExclusions = this.readRelayExclusions.filter((relay) => {
return normalizeRelayUrl(relay) !== url;
});
this.settings.update('nostrReadRelays', custom.length > 0 ? custom : null);
this.settings.update(
'nostrReadRelayExclusions',
readExclusions.length > 0 ? readExclusions : null
);
this.newReadRelay = ''; this.newReadRelay = '';
} }
@action @action
removeReadRelay(url) { removeReadRelay(url) {
if (this.requiredReadRelaySet.has(url)) { const current =
return; this.settings.nostrReadRelays || this.nostrData.defaultReadRelays;
} const filtered = current.filter((r) => r !== url);
this.settings.update('nostrReadRelays', filtered);
const normalizedUrl = normalizeRelayUrl(url);
const remainingCustom = this.customReadRelays.filter((relay) => {
return normalizeRelayUrl(relay) !== normalizedUrl;
});
const nextExclusions = this.mailboxReadRelaySet.has(normalizedUrl)
? Array.from(new Set([...this.readRelayExclusions, normalizedUrl]))
: this.readRelayExclusions;
this.settings.update(
'nostrReadRelays',
remainingCustom.length > 0 ? remainingCustom : null
);
this.settings.update(
'nostrReadRelayExclusions',
nextExclusions.length > 0 ? nextExclusions : null
);
} }
@action @action
@@ -168,7 +64,6 @@ export default class AppMenuSettingsNostr extends Component {
@action @action
resetReadRelays() { resetReadRelays() {
this.settings.update('nostrReadRelays', null); this.settings.update('nostrReadRelays', null);
this.settings.update('nostrReadRelayExclusions', null);
} }
@action @action
@@ -176,57 +71,24 @@ export default class AppMenuSettingsNostr extends Component {
const url = normalizeRelayUrl(this.newWriteRelay); const url = normalizeRelayUrl(this.newWriteRelay);
if (!url) return; if (!url) return;
const merged = mergeRequiredRelays(this.nostrData.requiredWriteRelays, [ const current =
...this.customWriteRelays, this.settings.nostrWriteRelays || this.nostrData.defaultWriteRelays;
url, const set = new Set([...current, url]);
]); this.settings.update('nostrWriteRelays', Array.from(set));
const custom = excludeRequiredRelays(
merged,
this.nostrData.requiredWriteRelays
);
const writeExclusions = this.writeRelayExclusions.filter((relay) => {
return normalizeRelayUrl(relay) !== url;
});
this.settings.update('nostrWriteRelays', custom.length > 0 ? custom : null);
this.settings.update(
'nostrWriteRelayExclusions',
writeExclusions.length > 0 ? writeExclusions : null
);
this.newWriteRelay = ''; this.newWriteRelay = '';
} }
@action @action
removeWriteRelay(url) { removeWriteRelay(url) {
if (this.requiredWriteRelaySet.has(url)) { const current =
return; this.settings.nostrWriteRelays || this.nostrData.defaultWriteRelays;
} const filtered = current.filter((r) => r !== url);
this.settings.update('nostrWriteRelays', filtered);
const normalizedUrl = normalizeRelayUrl(url);
const remainingCustom = this.customWriteRelays.filter((relay) => {
return normalizeRelayUrl(relay) !== normalizedUrl;
});
const nextExclusions = this.mailboxWriteRelaySet.has(normalizedUrl)
? Array.from(new Set([...this.writeRelayExclusions, normalizedUrl]))
: this.writeRelayExclusions;
this.settings.update(
'nostrWriteRelays',
remainingCustom.length > 0 ? remainingCustom : null
);
this.settings.update(
'nostrWriteRelayExclusions',
nextExclusions.length > 0 ? nextExclusions : null
);
} }
@action @action
resetWriteRelays() { resetWriteRelays() {
this.settings.update('nostrWriteRelays', null); this.settings.update('nostrWriteRelays', null);
this.settings.update('nostrWriteRelayExclusions', null);
} }
@action @action
@@ -250,20 +112,18 @@ export default class AppMenuSettingsNostr extends Component {
<div class="form-group"> <div class="form-group">
<label for="new-read-relay">Read Relays</label> <label for="new-read-relay">Read Relays</label>
<ul class="relay-list"> <ul class="relay-list">
{{#each this.readRelaysForDisplay as |relay|}} {{#each this.nostrData.activeReadRelays as |relay|}}
<li> <li>
<span>{{stripProtocol relay.url}}</span> <span>{{stripProtocol relay}}</span>
{{#unless relay.isRequired}} <button
<button type="button"
type="button" class="btn-remove-relay"
class="btn-remove-relay" title="Remove relay"
title="Remove relay" aria-label="Remove"
aria-label="Remove" {{on "click" (fn this.removeReadRelay relay)}}
{{on "click" (fn this.removeReadRelay relay.url)}} >
> <Icon @name="x" @size={{14}} @color="currentColor" />
<Icon @name="x" @size={{14}} @color="currentColor" /> </button>
</button>
{{/unless}}
</li> </li>
{{/each}} {{/each}}
</ul> </ul>
@@ -283,7 +143,7 @@ export default class AppMenuSettingsNostr extends Component {
{{on "click" this.addReadRelay}} {{on "click" this.addReadRelay}}
>Add</button> >Add</button>
</div> </div>
{{#if this.hasReadOverrides}} {{#if this.settings.nostrReadRelays}}
<button <button
type="button" type="button"
class="btn-link reset-relays" class="btn-link reset-relays"
@@ -297,20 +157,18 @@ export default class AppMenuSettingsNostr extends Component {
<div class="form-group"> <div class="form-group">
<label for="new-write-relay">Write Relays</label> <label for="new-write-relay">Write Relays</label>
<ul class="relay-list"> <ul class="relay-list">
{{#each this.writeRelaysForDisplay as |relay|}} {{#each this.nostrData.activeWriteRelays as |relay|}}
<li> <li>
<span>{{stripProtocol relay.url}}</span> <span>{{stripProtocol relay}}</span>
{{#unless relay.isRequired}} <button
<button type="button"
type="button" class="btn-remove-relay"
class="btn-remove-relay" title="Remove relay"
title="Remove relay" aria-label="Remove"
aria-label="Remove" {{on "click" (fn this.removeWriteRelay relay)}}
{{on "click" (fn this.removeWriteRelay relay.url)}} >
> <Icon @name="x" @size={{14}} @color="currentColor" />
<Icon @name="x" @size={{14}} @color="currentColor" /> </button>
</button>
{{/unless}}
</li> </li>
{{/each}} {{/each}}
</ul> </ul>
@@ -330,7 +188,7 @@ export default class AppMenuSettingsNostr extends Component {
{{on "click" this.addWriteRelay}} {{on "click" this.addWriteRelay}}
>Add</button> >Add</button>
</div> </div>
{{#if this.hasWriteOverrides}} {{#if this.settings.nostrWriteRelays}}
<button <button
type="button" type="button"
class="btn-link reset-relays" class="btn-link reset-relays"
+21 -10
View File
@@ -20,6 +20,7 @@ import { Style, Circle, Fill, Stroke, Icon } from 'ol/style.js';
import { apply } from 'ol-mapbox-style'; import { apply } from 'ol-mapbox-style';
import { getIcon } from '../utils/icons'; import { getIcon } from '../utils/icons';
import { getIconNameForTags } from '../utils/osm-icons'; import { getIconNameForTags } from '../utils/osm-icons';
import config from 'marco/config/environment';
export default class MapComponent extends Component { export default class MapComponent extends Component {
@service osm; @service osm;
@@ -286,9 +287,26 @@ export default class MapComponent extends Component {
this.mapUi.updateCenter(initialCenter[1], initialCenter[0]); this.mapUi.updateCenter(initialCenter[1], initialCenter[0]);
this.mapUi.updateZoom(view.getZoom()); this.mapUi.updateZoom(view.getZoom());
apply(this.mapInstance, 'https://tiles.openfreemap.org/styles/liberty', { if (config.environment === 'test') {
webfonts: 'data:text/css,', apply(this.mapInstance, {
}); version: 8,
name: 'Test Style',
sources: {},
layers: [
{
id: 'background',
type: 'background',
paint: {
'background-color': '#f8f4f0',
},
},
],
});
} else {
apply(this.mapInstance, 'https://tiles.openfreemap.org/styles/liberty', {
webfonts: 'data:text/css,',
});
}
this.searchOverlayElement = document.createElement('div'); this.searchOverlayElement = document.createElement('div');
this.searchOverlayElement.className = 'search-pulse'; this.searchOverlayElement.className = 'search-pulse';
@@ -1088,7 +1106,6 @@ export default class MapComponent extends Component {
const bbox = { minLat, minLon, maxLat, maxLon }; const bbox = { minLat, minLon, maxLat, maxLon };
this.mapUi.updateBounds(bbox); this.mapUi.updateBounds(bbox);
await this.storage.loadPlacesInBounds(bbox); await this.storage.loadPlacesInBounds(bbox);
if (this.isDestroying || this.isDestroyed) return;
this.nostrData.loadPlacesInBounds(bbox); this.nostrData.loadPlacesInBounds(bbox);
this.loadBookmarks(this.storage.placesInView); this.loadBookmarks(this.storage.placesInView);
@@ -1192,12 +1209,6 @@ export default class MapComponent extends Component {
return; return;
} }
if (this.mapUi.searchResults && this.mapUi.searchResults.length > 0) {
console.debug('Clearing active search and markers on map click');
this.router.transitionTo('index');
return;
}
// Require Zoom >= 17 for generic map searches // Require Zoom >= 17 for generic map searches
// This prevents accidental searches when interacting with the map at a high level // This prevents accidental searches when interacting with the map at a high level
const currentZoom = this.mapInstance.getView().getZoom(); const currentZoom = this.mapInstance.getView().getZoom();
+4 -17
View File
@@ -23,7 +23,6 @@ export default class PlaceDetails extends Component {
@service storage; @service storage;
@service nostrAuth; @service nostrAuth;
@service nostrData; @service nostrData;
@service mapUi;
@tracked isEditing = false; @tracked isEditing = false;
@tracked showLists = false; @tracked showLists = false;
@tracked isPhotoUploadActive = false; @tracked isPhotoUploadActive = false;
@@ -346,21 +345,9 @@ export default class PlaceDetails extends Component {
get osmUrl() { get osmUrl() {
const id = this.place.osmId; const id = this.place.osmId;
if (id) { if (!id) return null;
const type = this.place.osmType || 'node'; const type = this.place.osmType || 'node';
return `https://www.openstreetmap.org/${type}/${id}`; return `https://www.openstreetmap.org/${type}/${id}`;
}
const lat = this.place.lat;
const lon = this.place.lon;
if (!lat || !lon) return null;
const viewLat = this.mapUi.currentCenter?.lat ?? lat;
const viewLon = this.mapUi.currentCenter?.lon ?? lon;
const zoom = this.mapUi.currentZoom ?? 17;
const roundedZoom = Math.round(zoom);
return `https://www.openstreetmap.org/search?lat=${lat}&lon=${lon}&zoom=${roundedZoom}#map=${roundedZoom}/${Number(viewLat).toFixed(5)}/${Number(viewLon).toFixed(5)}`;
} }
get gmapsUrl() { get gmapsUrl() {
@@ -604,7 +591,7 @@ export default class PlaceDetails extends Component {
</div> </div>
{{#if this.place.osmId}} {{#if this.osmUrl}}
<div class="meta-info"> <div class="meta-info">
<p class="content-with-icon"> <p class="content-with-icon">
<Icon @name="feather-camera" /> <Icon @name="feather-camera" />
+2 -2
View File
@@ -103,7 +103,7 @@ export default class PlaceListsManager extends Component {
checked={{this.isSaved}} checked={{this.isSaved}}
{{on "change" this.toggleSaved}} {{on "change" this.toggleSaved}}
/> />
<span class="list-color-dot"></span> <span class="list-color"></span>
<span class="list-name">Saved places</span> <span class="list-name">Saved places</span>
</label> </label>
</div> </div>
@@ -122,7 +122,7 @@ export default class PlaceListsManager extends Component {
/> />
{{! template-lint-disable no-inline-styles }} {{! template-lint-disable no-inline-styles }}
<span <span
class="list-color-dot" class="list-color"
style={{this.styleFor list.color}} style={{this.styleFor list.color}}
></span> ></span>
<span class="list-name">{{list.title}}</span> <span class="list-name">{{list.title}}</span>
+49 -81
View File
@@ -5,13 +5,10 @@ import { on } from '@ember/modifier';
import { fn } from '@ember/helper'; import { fn } from '@ember/helper';
import or from 'ember-truth-helpers/helpers/or'; import or from 'ember-truth-helpers/helpers/or';
import eq from 'ember-truth-helpers/helpers/eq'; import eq from 'ember-truth-helpers/helpers/eq';
import and from 'ember-truth-helpers/helpers/and';
import not from 'ember-truth-helpers/helpers/not';
import PlaceDetails from './place-details'; import PlaceDetails from './place-details';
import Icon from './icon'; import Icon from './icon';
import humanizeOsmTag from '../helpers/humanize-osm-tag'; import humanizeOsmTag from '../helpers/humanize-osm-tag';
import { getLocalizedName, getPlaceType } from '../utils/osm'; import { getLocalizedName, getPlaceType } from '../utils/osm';
import restoreScroll from '../modifiers/restore-scroll';
export default class PlacesSidebar extends Component { export default class PlacesSidebar extends Component {
@service storage; @service storage;
@@ -163,11 +160,7 @@ export default class PlacesSidebar extends Component {
<template> <template>
<div class="sidebar"> <div class="sidebar">
<div <div class="sidebar-header {{if this.hasHeaderPhoto 'no-border'}}">
class="sidebar-header
{{if this.hasHeaderPhoto 'no-border'}}
{{if (and (not @selectedPlace) @onBack) 'has-back-btn'}}"
>
{{#if @selectedPlace}} {{#if @selectedPlace}}
<button <button
type="button" type="button"
@@ -175,32 +168,11 @@ export default class PlacesSidebar extends Component {
{{on "click" this.clearSelection}} {{on "click" this.clearSelection}}
><Icon @name="arrow-left" @size={{20}} @color="#333" /></button> ><Icon @name="arrow-left" @size={{20}} @color="#333" /></button>
{{else}} {{else}}
{{#if @onBack}} {{#if this.isNearbySearch}}
<button type="button" class="back-btn" {{on "click" @onBack}}><Icon <h2><Icon @name="target" @size={{20}} @color="#ea4335" />
@name="arrow-left" Nearby</h2>
@size={{20}}
@color="#333"
/></button>
{{/if}}
{{#if @onBack}}
<h2 class="sidebar-header-text-centered">
<span class="sidebar-header-icon-wrapper">
<Icon
@name="bookmark"
@size={{20}}
@color={{or @color "#898989"}}
/>
</span>
{{@title}}
</h2>
{{else}} {{else}}
{{#if this.isNearbySearch}} <h2><Icon @name="search" @size={{20}} @color="#333" /> Results</h2>
<h2><Icon @name="target" @size={{20}} @color="#ea4335" />
Nearby</h2>
{{else}}
<h2><Icon @name="search" @size={{20}} @color="#333" />
Results</h2>
{{/if}}
{{/if}} {{/if}}
{{/if}} {{/if}}
<button type="button" class="close-btn" {{on "click" @onClose}}><Icon <button type="button" class="close-btn" {{on "click" @onClose}}><Icon
@@ -210,7 +182,7 @@ export default class PlacesSidebar extends Component {
/></button> /></button>
</div> </div>
<div class="sidebar-content" {{restoreScroll @scrollTop}}> <div class="sidebar-content">
{{#if @selectedPlace}} {{#if @selectedPlace}}
<PlaceDetails <PlaceDetails
@place={{@selectedPlace}} @place={{@selectedPlace}}
@@ -218,58 +190,54 @@ export default class PlacesSidebar extends Component {
@onSave={{this.updateBookmark}} @onSave={{this.updateBookmark}}
/> />
{{else}} {{else}}
{{#if @isLoading}} {{#if @places}}
<div class="sidebar-loading"> <ul class="places-list">
<Icon @name="loading-ring" @size={{24}} @color="#898989" /> {{#each @places as |place|}}
</div> <li>
{{else}} <button
{{#if @places}} type="button"
<ul class="places-list"> class="place-item"
{{#each @places as |place|}} {{on "click" (fn this.selectPlace place)}}
<li> >
<button <div class="place-name">{{or
type="button" place.title
class="place-item" place.osmTags.name
{{on "click" (fn this.selectPlace place)}} place.osmTags.name:en
> "Unnamed Place"
<div class="place-name">{{or }}</div>
place.title <div class="place-type">
place.osmTags.name {{#if (eq place.source "osm")}}
place.osmTags.name:en {{humanizeOsmTag place.type}}
"Unnamed Place" {{else if (eq place.source "photon")}}
}}</div> {{place.description}}
<div class="place-type"> {{else}}
{{#if (eq place.source "osm")}} {{#if place.osmTags}}
{{humanizeOsmTag place.type}} {{humanizeOsmTag (getPlaceType place.osmTags)}}
{{else if (eq place.source "photon")}} {{else if place.description}}
{{place.description}} {{place.description}}
{{else if (getPlaceType place.osmTags)}}
{{getPlaceType place.osmTags}}
{{else}}
Saved place
{{/if}} {{/if}}
</div> {{/if}}
</button> </div>
</li> </button>
{{/each}} </li>
</ul> {{/each}}
</ul>
{{else}}
{{#if this.isNearbySearch}}
<p class="empty-state">No places found nearby.</p>
{{else}} {{else}}
{{#if this.isNearbySearch}} <p class="empty-state">No results found.</p>
<p class="empty-state">No places found nearby.</p>
{{else}}
<p class="empty-state">No results found.</p>
{{/if}}
{{/if}} {{/if}}
<button
type="button"
class="btn btn-outline create-place"
{{on "click" this.createNewPlace}}
>
<Icon @name="plus" @size={{18}} @color="var(--link-color)" />
Create new place
</button>
{{/if}} {{/if}}
<button
type="button"
class="btn btn-outline create-place"
{{on "click" this.createNewPlace}}
>
<Icon @name="plus" @size={{18}} @color="var(--link-color)" />
Create new place
</button>
{{/if}} {{/if}}
</div> </div>
</div> </div>
-118
View File
@@ -1,118 +0,0 @@
import Controller from '@ember/controller';
import { service } from '@ember/service';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import { task } from 'ember-concurrency';
function getPlaceTime(place) {
const dateVal = place.createdAt;
if (!dateVal) return 0;
if (typeof dateVal === 'number') {
return dateVal;
}
const parsed = Date.parse(dateVal);
return isNaN(parsed) ? 0 : parsed;
}
export default class ListsListController extends Controller {
@service router;
@service mapUi;
@service storage;
@tracked model;
@tracked loadedPlaces = [];
get listId() {
return this.model?.list_id;
}
loadPlacesTask = task({ restartable: true }, async (listId) => {
this.loadedPlaces = []; // Clear previous elements immediately to show fresh loader
try {
this.loadedPlaces = await this.storage.getPlacesInList(listId);
} catch (e) {
console.error('Failed to load places in list', listId, e);
this.loadedPlaces = [];
}
});
get scrollTop() {
return this.mapUi.getScrollPosition(`list-${this.listId}`);
}
get listColor() {
const list = this.storage.lists.find((l) => l.id === this.listId);
if (list && list.color) {
return list.color;
}
return getComputedStyle(document.documentElement)
.getPropertyValue('--default-list-color')
.trim();
}
get listTitle() {
const list = this.storage.lists.find((l) => l.id === this.listId);
return list ? list.title : 'Collections';
}
get places() {
const currentList = this.storage.lists.find((l) => l.id === this.listId);
const placeRefsIds = new Set(
currentList?.placeRefs?.map((ref) => ref.id) || []
);
// Filter live tracked savedPlaces that are in this list
const livePlaces = this.storage.savedPlaces.filter((p) =>
placeRefsIds.has(p.id)
);
const merged = [];
const seen = new Set();
// Process live state first to reflect deletions/edits immediately
livePlaces.forEach((p) => {
merged.push(p);
seen.add(p.id);
});
// Supplement with any background-fetched places that are still valid but not in live state yet
this.loadedPlaces.forEach((p) => {
if (placeRefsIds.has(p.id) && !seen.has(p.id)) {
merged.push(p);
seen.add(p.id);
}
});
return merged.sort((a, b) => getPlaceTime(b) - getPlaceTime(a));
}
@action
selectPlace(place) {
if (place) {
const sidebarContent = document.querySelector('.sidebar-content');
if (sidebarContent) {
this.mapUi.saveScrollPosition(
`list-${this.listId}`,
sidebarContent.scrollTop
);
}
this.mapUi.returnToRoute = {
name: 'lists.list',
model: this.listId,
};
this.mapUi.showSidebar();
this.mapUi.preventNextZoom = true;
this.router.transitionTo('place', place);
}
}
@action
close() {
this.router.transitionTo('index');
}
@action
backToLists() {
this.router.transitionTo('lists.index');
}
}
+1 -20
View File
@@ -20,26 +20,7 @@ export default class SearchController extends Controller {
category = null; category = null;
fetchResultsTask = task({ restartable: true }, async (params) => { fetchResultsTask = task({ restartable: true }, async (params) => {
// 1. Check if the incoming parameters match our currently loaded search // Hide sidebar and clear previous results immediately to signal a new search
const isSameSearch =
this.mapUi.currentSearch &&
params.q === this.mapUi.currentSearch.q &&
params.category === this.mapUi.currentSearch.category &&
params.lat === this.mapUi.currentSearch.lat &&
params.lon === this.mapUi.currentSearch.lon;
const hasResults =
this.mapUi.searchResults && this.mapUi.searchResults.length > 0;
// 2. If it's a back navigation to the exact same search, resolve instantly with no animation
if (isSameSearch && hasResults) {
if (this.mapUi.isSidebarVisible) {
this.mapUi.showSidebar();
}
return;
}
// 3. Otherwise, this is a brand new search: hide the sidebar and clear previous results immediately to signal a new search
this.mapUi.hideSidebar(); this.mapUi.hideSidebar();
this.mapUi.clearSearchResults(); this.mapUi.clearSearchResults();
-10
View File
@@ -1,10 +0,0 @@
import { modifier } from 'ember-modifier';
export default modifier((element, [scrollTop]) => {
if (element && typeof scrollTop === 'number' && scrollTop > 0) {
// Restore inside requestAnimationFrame to guarantee layout rendering is ready
requestAnimationFrame(() => {
element.scrollTop = scrollTop;
});
}
});
-4
View File
@@ -10,10 +10,6 @@ Router.map(function () {
this.route('place', { path: '/place/:place_id' }); this.route('place', { path: '/place/:place_id' });
this.route('place.new', { path: '/place/new' }); this.route('place.new', { path: '/place/new' });
this.route('search'); this.route('search');
this.route('menu');
this.route('lists', function () {
this.route('list', { path: '/:list_id' });
});
this.route('oauth', function () { this.route('oauth', function () {
this.route('osm-callback', { path: '/osm/callback' }); this.route('osm-callback', { path: '/osm/callback' });
}); });
-1
View File
@@ -6,6 +6,5 @@ export default class IndexRoute extends Route {
activate() { activate() {
this.mapUi.clearSearchResults(); this.mapUi.clearSearchResults();
this.mapUi.hideSidebar();
} }
} }
-10
View File
@@ -1,10 +0,0 @@
import Route from '@ember/routing/route';
import { service } from '@ember/service';
export default class ListsRoute extends Route {
@service mapUi;
activate() {
this.mapUi.showSidebar();
}
}
-3
View File
@@ -1,3 +0,0 @@
import Route from '@ember/routing/route';
export default class ListsIndexRoute extends Route {}
-26
View File
@@ -1,26 +0,0 @@
import Route from '@ember/routing/route';
import { service } from '@ember/service';
export default class ListsListRoute extends Route {
@service storage;
model(params) {
// Resolve instantly so transition happens in 0ms!
return { list_id: params.list_id };
}
setupController(controller, model) {
console.debug('DEBUG: setupController controller is:', controller);
console.debug(
'DEBUG: controller.loadPlacesTask is:',
controller?.loadPlacesTask
);
controller.model = model;
super.setupController(controller, model);
if (controller && controller.loadPlacesTask) {
controller.loadPlacesTask.perform(model.list_id);
} else {
console.error('DEBUG: ERROR! controller.loadPlacesTask is undefined!');
}
}
}
-10
View File
@@ -1,10 +0,0 @@
import Route from '@ember/routing/route';
import { service } from '@ember/service';
export default class MenuRoute extends Route {
@service mapUi;
activate() {
this.mapUi.showSidebar();
}
}
-1
View File
@@ -108,7 +108,6 @@ export default class PlaceRoute extends Route {
this.mapUi.clearSelection(); this.mapUi.clearSelection();
// Reset the "return to search" flag so it doesn't persist to subsequent navigations // Reset the "return to search" flag so it doesn't persist to subsequent navigations
this.mapUi.returnToSearch = false; this.mapUi.returnToSearch = false;
this.mapUi.returnToRoute = null;
} }
async loadOsmPlace(id, type = null) { async loadOsmPlace(id, type = null) {
+1 -23
View File
@@ -1,6 +1,5 @@
import Service, { service } from '@ember/service'; import Service, { service } from '@ember/service';
import { tracked } from '@glimmer/tracking'; import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
export default class MapUiService extends Service { export default class MapUiService extends Service {
@service nostrData; @service nostrData;
@@ -10,7 +9,6 @@ export default class MapUiService extends Service {
@tracked isCreating = false; @tracked isCreating = false;
@tracked creationCoordinates = null; @tracked creationCoordinates = null;
@tracked returnToSearch = false; @tracked returnToSearch = false;
@tracked returnToRoute = null;
@tracked currentCenter = null; @tracked currentCenter = null;
@tracked currentBounds = null; @tracked currentBounds = null;
@tracked currentZoom = null; @tracked currentZoom = null;
@@ -21,33 +19,13 @@ export default class MapUiService extends Service {
@tracked currentSearch = null; @tracked currentSearch = null;
@tracked loadingState = null; @tracked loadingState = null;
@tracked isSidebarVisible = false; @tracked isSidebarVisible = false;
@tracked isSidebarOpening = false;
scrollPositions = {};
@action
saveScrollPosition(key, value) {
this.scrollPositions[key] = value;
}
@action
getScrollPosition(key) {
return this.scrollPositions[key] || 0;
}
showSidebar() { showSidebar() {
if (!this.isSidebarVisible) { this.isSidebarVisible = true;
this.isSidebarVisible = true;
this.isSidebarOpening = true;
setTimeout(() => {
this.isSidebarOpening = false;
}, 250);
}
} }
hideSidebar() { hideSidebar() {
this.isSidebarVisible = false; this.isSidebarVisible = false;
this.isSidebarOpening = false;
} }
selectPlace(place, options = {}) { selectPlace(place, options = {}) {
+26 -50
View File
@@ -6,12 +6,7 @@ import { MailboxesModel } from 'applesauce-core/models/mailboxes';
import { npubEncode } from 'applesauce-core/helpers/pointers'; import { npubEncode } from 'applesauce-core/helpers/pointers';
import { persistEventsToCache } from 'applesauce-core/helpers/event-cache'; import { persistEventsToCache } from 'applesauce-core/helpers/event-cache';
import { NostrIDB, openDB } from 'nostr-idb'; import { NostrIDB, openDB } from 'nostr-idb';
import { import { normalizeRelayUrl } from '../utils/nostr';
excludeRequiredRelays,
mergeRequiredRelays,
normalizeRelayUrl,
uniqNormalizedRelays,
} from '../utils/nostr';
import { getGeohashPrefixesInBbox } from '../utils/geohash-coverage'; import { getGeohashPrefixesInBbox } from '../utils/geohash-coverage';
const DIRECTORY_RELAYS = [ const DIRECTORY_RELAYS = [
@@ -88,62 +83,43 @@ export default class NostrDataService extends Service {
}); });
} }
get requiredReadRelays() { get defaultReadRelays() {
return DEFAULT_READ_RELAYS; const mailboxes = (this.mailboxes?.inboxes || [])
}
get requiredWriteRelays() {
return DEFAULT_WRITE_RELAYS;
}
get mailboxReadRelays() {
return (this.mailboxes?.inboxes || [])
.map(normalizeRelayUrl) .map(normalizeRelayUrl)
.filter(Boolean); .filter(Boolean);
const defaults = DEFAULT_READ_RELAYS.map(normalizeRelayUrl).filter(Boolean);
return Array.from(new Set([...defaults, ...mailboxes]));
} }
get mailboxWriteRelays() { get defaultWriteRelays() {
return (this.mailboxes?.outboxes || []) const mailboxes = (this.mailboxes?.outboxes || [])
.map(normalizeRelayUrl) .map(normalizeRelayUrl)
.filter(Boolean); .filter(Boolean);
} const defaults =
DEFAULT_WRITE_RELAYS.map(normalizeRelayUrl).filter(Boolean);
get configuredReadRelays() { return Array.from(new Set([...defaults, ...mailboxes]));
const configured = uniqNormalizedRelays([
...this.mailboxReadRelays,
...(this.settings.nostrReadRelays || []),
]);
return excludeRequiredRelays(
configured,
this.settings.nostrReadRelayExclusions || []
);
}
get configuredWriteRelays() {
const configured = uniqNormalizedRelays([
...this.mailboxWriteRelays,
...(this.settings.nostrWriteRelays || []),
]);
return excludeRequiredRelays(
configured,
this.settings.nostrWriteRelayExclusions || []
);
} }
get activeReadRelays() { get activeReadRelays() {
return mergeRequiredRelays( if (this.settings.nostrReadRelays) {
this.requiredReadRelays, return Array.from(
this.configuredReadRelays new Set(
); this.settings.nostrReadRelays.map(normalizeRelayUrl).filter(Boolean)
)
);
}
return this.defaultReadRelays;
} }
get activeWriteRelays() { get activeWriteRelays() {
return mergeRequiredRelays( if (this.settings.nostrWriteRelays) {
this.requiredWriteRelays, return Array.from(
this.configuredWriteRelays new Set(
); this.settings.nostrWriteRelays.map(normalizeRelayUrl).filter(Boolean)
)
);
}
return this.defaultWriteRelays;
} }
async loadPlacesInBounds(bbox) { async loadPlacesInBounds(bbox) {
-9
View File
@@ -9,8 +9,6 @@ const DEFAULT_SETTINGS = {
nostrPhotoFallbackUploads: false, nostrPhotoFallbackUploads: false,
nostrReadRelays: null, nostrReadRelays: null,
nostrWriteRelays: null, nostrWriteRelays: null,
nostrReadRelayExclusions: null,
nostrWriteRelayExclusions: null,
experimentalEnablePhotoDeletion: false, experimentalEnablePhotoDeletion: false,
}; };
@@ -23,9 +21,6 @@ export default class SettingsService extends Service {
DEFAULT_SETTINGS.nostrPhotoFallbackUploads; DEFAULT_SETTINGS.nostrPhotoFallbackUploads;
@tracked nostrReadRelays = DEFAULT_SETTINGS.nostrReadRelays; @tracked nostrReadRelays = DEFAULT_SETTINGS.nostrReadRelays;
@tracked nostrWriteRelays = DEFAULT_SETTINGS.nostrWriteRelays; @tracked nostrWriteRelays = DEFAULT_SETTINGS.nostrWriteRelays;
@tracked nostrReadRelayExclusions = DEFAULT_SETTINGS.nostrReadRelayExclusions;
@tracked nostrWriteRelayExclusions =
DEFAULT_SETTINGS.nostrWriteRelayExclusions;
@tracked experimentalEnablePhotoDeletion = @tracked experimentalEnablePhotoDeletion =
DEFAULT_SETTINGS.experimentalEnablePhotoDeletion; DEFAULT_SETTINGS.experimentalEnablePhotoDeletion;
@@ -116,8 +111,6 @@ export default class SettingsService extends Service {
this.nostrPhotoFallbackUploads = finalSettings.nostrPhotoFallbackUploads; this.nostrPhotoFallbackUploads = finalSettings.nostrPhotoFallbackUploads;
this.nostrReadRelays = finalSettings.nostrReadRelays; this.nostrReadRelays = finalSettings.nostrReadRelays;
this.nostrWriteRelays = finalSettings.nostrWriteRelays; this.nostrWriteRelays = finalSettings.nostrWriteRelays;
this.nostrReadRelayExclusions = finalSettings.nostrReadRelayExclusions;
this.nostrWriteRelayExclusions = finalSettings.nostrWriteRelayExclusions;
this.experimentalEnablePhotoDeletion = this.experimentalEnablePhotoDeletion =
finalSettings.experimentalEnablePhotoDeletion; finalSettings.experimentalEnablePhotoDeletion;
@@ -134,8 +127,6 @@ export default class SettingsService extends Service {
nostrPhotoFallbackUploads: this.nostrPhotoFallbackUploads, nostrPhotoFallbackUploads: this.nostrPhotoFallbackUploads,
nostrReadRelays: this.nostrReadRelays, nostrReadRelays: this.nostrReadRelays,
nostrWriteRelays: this.nostrWriteRelays, nostrWriteRelays: this.nostrWriteRelays,
nostrReadRelayExclusions: this.nostrReadRelayExclusions,
nostrWriteRelayExclusions: this.nostrWriteRelayExclusions,
experimentalEnablePhotoDeletion: this.experimentalEnablePhotoDeletion, experimentalEnablePhotoDeletion: this.experimentalEnablePhotoDeletion,
}; };
localStorage.setItem('marco:settings', JSON.stringify(settings)); localStorage.setItem('marco:settings', JSON.stringify(settings));
-5
View File
@@ -270,11 +270,6 @@ export default class StorageService extends Service {
} }
} }
async getPlacesInList(listId) {
if (!this.places || !this.places.lists) return [];
return this.places.lists.getPlaces(listId);
}
async loadPlacesInBounds(bbox) { async loadPlacesInBounds(bbox) {
// 1. Calculate required prefixes // 1. Calculate required prefixes
const requiredPrefixes = getGeohashPrefixesInBbox(bbox); const requiredPrefixes = getGeohashPrefixesInBbox(bbox);
+40 -178
View File
@@ -1,10 +1,8 @@
/* Ember supports plain CSS out of the box. More info: https://cli.emberjs.com/release/advanced-use/stylesheets/ */ /* Ember supports plain CSS out of the box. More info: https://cli.emberjs.com/release/advanced-use/stylesheets/ */
:root { :root {
--body-text-color: #333; --default-list-color: #fc3;
--primary-background-color: #fff;
--hover-bg: #f8f9fa; --hover-bg: #f8f9fa;
--divider-color: #eee;
--sidebar-width: 350px; --sidebar-width: 350px;
--link-color: #2a7fff; --link-color: #2a7fff;
--link-color-visited: #6a4fbf; --link-color-visited: #6a4fbf;
@@ -12,7 +10,6 @@
--marker-color-dark: #b31412; --marker-color-dark: #b31412;
--danger-color: var(--marker-color-primary); --danger-color: var(--marker-color-primary);
--danger-color-dark: var(--marker-color-dark); --danger-color-dark: var(--marker-color-dark);
--default-list-color: #fc3;
} }
html, html,
@@ -34,7 +31,7 @@ body {
font-family: 'Noto Sans', sans-serif; font-family: 'Noto Sans', sans-serif;
font-size: 16px; font-size: 16px;
font-weight: normal; font-weight: normal;
color: var(--body-text-color); color: #333;
} }
#root, #root,
@@ -115,6 +112,8 @@ body {
display: flex; display: flex;
align-items: center; align-items: center;
grid-area: search; grid-area: search;
/* Ensure it sits at the start of its grid area */
justify-self: start; justify-self: start;
width: 100%; width: 100%;
} }
@@ -128,6 +127,7 @@ body {
@media (width > 768px) { @media (width > 768px) {
.header-left { .header-left {
/* Desktop: Ensure minimum width for search box so it's not squeezed */
min-width: 300px; min-width: 300px;
max-width: 350px; max-width: 350px;
} }
@@ -140,6 +140,8 @@ body {
.header-center { .header-center {
grid-area: chips; grid-area: chips;
/* Desktop: Center the chips block in the available space */
display: flex; display: flex;
justify-content: center; justify-content: center;
min-width: 0; /* Allow shrinking */ min-width: 0; /* Allow shrinking */
@@ -154,6 +156,7 @@ body {
} }
@media (width <= 768px) { @media (width <= 768px) {
/* No need to reset min-width/max-width since they are only set in media query above */
.header-center { .header-center {
width: 100%; width: 100%;
overflow: hidden; overflow: hidden;
@@ -380,7 +383,7 @@ body {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 1rem 0; padding: 1rem 0;
border-bottom: 1px solid var(--divider-color); border-bottom: 1px solid #eee;
} }
.account-item:last-child { .account-item:last-child {
@@ -457,11 +460,6 @@ body {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden; /* Ensure flex children are contained */ overflow: hidden; /* Ensure flex children are contained */
will-change: transform;
}
.sidebar-opening .sidebar {
animation: sidebar-slide-in-left 0.18s cubic-bezier(0.16, 1, 0.3, 1) forwards;
} }
.sidebar.app-menu-pane { .sidebar.app-menu-pane {
@@ -480,13 +478,11 @@ body {
} }
.sidebar-header { .sidebar-header {
height: 56px; /* Strictly enforce identical vertical height */ padding: 1rem;
padding: 0 1rem; /* Keep horizontal padding, remove vertical padding */ border-bottom: 1px solid #eee;
border-bottom: 1px solid var(--divider-color);
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
box-sizing: border-box; /* Guarantee strict height boundaries */
} }
.sidebar-header.no-border { .sidebar-header.no-border {
@@ -495,7 +491,7 @@ body {
.sidebar-header h2 { .sidebar-header h2 {
margin: 0; margin: 0;
font-size: 1.1rem; font-size: 1.2rem;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 0.5rem; gap: 0.5rem;
@@ -530,7 +526,7 @@ body {
padding-left: 1.4rem; padding-left: 1.4rem;
background: none; background: none;
border: none; border: none;
color: var(--body-text-color); color: #333;
cursor: pointer; cursor: pointer;
text-align: left; text-align: left;
font-size: 0.95rem; font-size: 0.95rem;
@@ -561,7 +557,7 @@ body {
padding-left: 1.4rem; padding-left: 1.4rem;
cursor: pointer; cursor: pointer;
font-size: 0.95rem; font-size: 0.95rem;
color: var(--body-text-color); color: #333;
transition: background-color 0.2s; transition: background-color 0.2s;
} }
@@ -632,7 +628,7 @@ body {
width: 24px; width: 24px;
height: 24px; height: 24px;
border-radius: 50%; border-radius: 50%;
background-color: var(--primary-background-color); background-color: #fff;
border: 1px solid var(--danger-color); border: 1px solid var(--danger-color);
color: var(--danger-color); color: var(--danger-color);
cursor: pointer; cursor: pointer;
@@ -648,7 +644,7 @@ body {
.btn-remove-relay:hover, .btn-remove-relay:hover,
.btn-remove-relay:active { .btn-remove-relay:active {
background-color: var(--danger-color); background-color: var(--danger-color);
color: var(--primary-background-color); color: #fff;
} }
.add-relay-input { .add-relay-input {
@@ -678,7 +674,7 @@ body {
margin-bottom: 1rem; margin-bottom: 1rem;
background: var(--hover-bg); background: var(--hover-bg);
padding: 1rem; padding: 1rem;
border-bottom: 1px solid var(--divider-color); border-bottom: 1px solid #eee;
} }
.form-group { .form-group {
@@ -700,8 +696,8 @@ body {
font-family: inherit; font-family: inherit;
font-size: 1rem; font-size: 1rem;
box-sizing: border-box; /* Ensure padding doesn't overflow width */ box-sizing: border-box; /* Ensure padding doesn't overflow width */
color: var(--body-text-color); color: #333;
background-color: var(--primary-background-color); background-color: #fff;
} }
.form-control:focus { .form-control:focus {
@@ -712,7 +708,7 @@ body {
select.form-control { select.form-control {
appearance: none; appearance: none;
background-color: var(--primary-background-color); background-color: #fff;
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23666' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E"); background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23666' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: right 0.75rem center; background-position: right 0.75rem center;
@@ -788,7 +784,7 @@ select.form-control {
.meta-info p:first-child { .meta-info p:first-child {
margin-top: 1.2rem; margin-top: 1.2rem;
padding-top: 1.2rem; padding-top: 1.2rem;
border-top: 1px solid var(--divider-color); border-top: 1px solid #eee;
} }
.meta-info a, .meta-info a,
@@ -847,9 +843,9 @@ abbr[title] {
width: 100%; width: 100%;
text-align: left; text-align: left;
border: none; border: none;
border-bottom: 1px solid var(--divider-color); border-bottom: 1px solid #eee;
background: var(--primary-background-color); background: #fff;
color: var(--body-text-color); color: #333;
padding: 1rem; padding: 1rem;
cursor: pointer; cursor: pointer;
transition: background 0.2s; transition: background 0.2s;
@@ -1020,7 +1016,7 @@ abbr[title] {
.photo-carousel.inline .photo-carousel-track { .photo-carousel.inline .photo-carousel-track {
scroll-snap-type: none; scroll-snap-type: none;
gap: 2px; gap: 2px;
background-color: var(--primary-background-color); background-color: #fff;
} }
.photo-carousel.inline .carousel-slide { .photo-carousel.inline .carousel-slide {
@@ -1099,7 +1095,7 @@ abbr[title] {
.btn-outline { .btn-outline {
background: transparent; background: transparent;
color: var(--body-text-color); color: #333;
border: 1px solid #ccc; border: 1px solid #ccc;
} }
@@ -1108,7 +1104,7 @@ abbr[title] {
} }
.btn-secondary { .btn-secondary {
color: var(--body-text-color); color: #333;
border: 1px solid rgb(255 204 51 / 20%); border: 1px solid rgb(255 204 51 / 20%);
background: rgb(255 204 51 / 30%); background: rgb(255 204 51 / 30%);
} }
@@ -1270,20 +1266,6 @@ span.icon {
gap: 0.5rem; gap: 0.5rem;
} }
.content-with-icon > span:not(.icon) {
min-width: 0;
flex: 1;
}
.content-with-icon > span:not(.icon) a {
display: inline-block;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
vertical-align: bottom;
}
.content-with-icon .icon { .content-with-icon .icon {
margin-top: 0.15rem; margin-top: 0.15rem;
} }
@@ -1365,7 +1347,7 @@ span.icon {
width: 24px; width: 24px;
height: 24px; height: 24px;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
color: var(--body-text-color); color: #333;
pointer-events: none; pointer-events: none;
z-index: 2000; z-index: 2000;
display: none; display: none;
@@ -1426,11 +1408,6 @@ button.create-place {
inset: auto 0 0; inset: auto 0 0;
} }
.sidebar-opening .sidebar {
animation: sidebar-slide-up-bottom 0.18s cubic-bezier(0.16, 1, 0.3, 1)
forwards;
}
.sidebar-content { .sidebar-content {
overflow-y: auto; overflow-y: auto;
@@ -1504,7 +1481,7 @@ button.create-place {
min-width: 0; min-width: 0;
height: 100%; height: 100%;
font-size: 1rem; font-size: 1rem;
color: var(--body-text-color); color: #333;
outline: none; outline: none;
width: 100%; width: 100%;
padding: 0 4px; padding: 0 4px;
@@ -1535,7 +1512,7 @@ button.create-place {
.search-submit-btn:hover { .search-submit-btn:hover {
background: rgb(0 0 0 / 5%); background: rgb(0 0 0 / 5%);
color: var(--body-text-color); color: #333;
} }
.search-clear-btn { .search-clear-btn {
@@ -1553,7 +1530,7 @@ button.create-place {
.search-clear-btn:hover { .search-clear-btn:hover {
background: rgb(0 0 0 / 5%); background: rgb(0 0 0 / 5%);
color: var(--body-text-color); color: #333;
} }
/* Search Results Popover */ /* Search Results Popover */
@@ -1622,7 +1599,7 @@ button.create-place {
.result-title { .result-title {
font-weight: 500; font-weight: 500;
color: var(--body-text-color); color: #333;
font-size: 0.95rem; font-size: 0.95rem;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
@@ -1674,7 +1651,7 @@ button.create-place {
cursor: pointer; cursor: pointer;
margin: 0; margin: 0;
font-size: 0.95rem; font-size: 0.95rem;
color: var(--body-text-color); color: #333;
} }
.place-lists-manager input[type='checkbox'] { .place-lists-manager input[type='checkbox'] {
@@ -1684,8 +1661,7 @@ button.create-place {
cursor: pointer; cursor: pointer;
} }
/* Shared List Color Dot */ .place-lists-manager .list-color {
.list-color-dot {
width: 12px; width: 12px;
height: 12px; height: 12px;
background-color: var(--default-list-color); background-color: var(--default-list-color);
@@ -1696,7 +1672,7 @@ button.create-place {
.place-lists-manager .divider { .place-lists-manager .divider {
height: 1px; height: 1px;
background: var(--divider-color); background: #eee;
margin: 0.5rem 0; margin: 0.5rem 0;
} }
@@ -1739,7 +1715,7 @@ button.create-place {
border: 1px solid #ddd; border: 1px solid #ddd;
border-radius: 16px; /* Pill shape */ border-radius: 16px; /* Pill shape */
font-size: 0.9rem; font-size: 0.9rem;
color: var(--body-text-color); color: #333;
cursor: pointer; cursor: pointer;
white-space: nowrap; white-space: nowrap;
box-shadow: 0 1px 3px rgb(0 0 0 / 10%); box-shadow: 0 1px 3px rgb(0 0 0 / 10%);
@@ -1751,7 +1727,7 @@ button.create-place {
} }
.category-chip:active { .category-chip:active {
background: var(--divider-color); background: #eee;
} }
.category-chip:disabled { .category-chip:disabled {
@@ -1886,7 +1862,7 @@ button.create-place {
.photo-tag-chip { .photo-tag-chip {
background: #f8f9fa; background: #f8f9fa;
color: var(--body-text-color); color: #333;
border: none; border: none;
border-radius: 16px; border-radius: 16px;
padding: 6px 12px; padding: 6px 12px;
@@ -1896,7 +1872,7 @@ button.create-place {
} }
.photo-tag-chip:hover { .photo-tag-chip:hover {
background: var(--divider-color); background: #eee;
} }
.photo-tag-chip.is-selected { .photo-tag-chip.is-selected {
@@ -2127,7 +2103,7 @@ button.create-place {
text-align: left; text-align: left;
cursor: pointer; cursor: pointer;
font-size: 0.95rem; font-size: 0.95rem;
color: var(--body-text-color); color: #333;
white-space: nowrap; white-space: nowrap;
} }
@@ -2147,117 +2123,3 @@ button.create-place {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
/* Snappy slide-in from left (Desktop) */
@keyframes sidebar-slide-in-left {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
}
}
/* Snappy slide-up from bottom (Mobile) */
@keyframes sidebar-slide-up-bottom {
from {
transform: translateY(100%);
}
to {
transform: translateY(0);
}
}
/* Lists Index Sidebar Menu */
.lists-index-item {
width: 100%;
text-align: left;
border: none;
border-bottom: 1px solid var(--divider-color);
background: var(--primary-background-color);
color: var(--body-text-color);
padding: 1rem;
cursor: pointer;
transition: background 0.2s;
font-family: inherit;
display: flex;
align-items: center;
justify-content: space-between;
}
.lists-index-item:hover {
background: var(--hover-bg);
}
.lists-index-item-left {
display: flex;
align-items: center;
gap: 12px;
min-width: 0;
}
.lists-index-name {
font-size: 0.95rem;
font-weight: normal;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.lists-index-count {
color: #666;
font-size: 0.85rem;
margin: 0;
white-space: nowrap;
flex-shrink: 0;
}
/* Centered layout when back button is present */
.sidebar-header.has-back-btn {
position: relative;
justify-content: center; /* Center horizontally */
}
/* Absolute positioning for buttons in centered header */
.sidebar-header.has-back-btn .back-btn {
position: absolute;
left: 1rem;
z-index: 10;
}
.sidebar-header.has-back-btn .close-btn {
position: absolute;
right: 1rem;
z-index: 10;
}
/* Centralized Title text */
.sidebar-header-text-centered {
position: relative;
margin: 0;
font-size: 1.2rem;
font-weight: bold;
display: inline-flex;
align-items: center;
justify-content: center;
text-align: center;
max-width: 60%;
}
.sidebar-header-icon-wrapper {
position: absolute;
right: 100%;
margin-right: 0.5rem;
display: flex;
align-items: center;
}
/* Sidebar Loading State */
.sidebar-loading {
display: flex;
align-items: center;
justify-content: center;
padding: 4rem 1rem;
}
+40 -47
View File
@@ -2,9 +2,12 @@ import Component from '@glimmer/component';
import { pageTitle } from 'ember-page-title'; import { pageTitle } from 'ember-page-title';
import Map from '#components/map'; import Map from '#components/map';
import AppHeader from '#components/app-header'; import AppHeader from '#components/app-header';
import AppMenu from '#components/app-menu/index';
import Toast from '#components/toast'; import Toast from '#components/toast';
import { service } from '@ember/service'; import { service } from '@ember/service';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object'; import { action } from '@ember/object';
import { or } from 'ember-truth-helpers';
import { on } from '@ember/modifier'; import { on } from '@ember/modifier';
export default class ApplicationComponent extends Component { export default class ApplicationComponent extends Component {
@@ -12,17 +15,16 @@ export default class ApplicationComponent extends Component {
@service mapUi; @service mapUi;
@service router; @service router;
@tracked isAppMenuOpen = false;
get isSidebarOpen() { get isSidebarOpen() {
// We consider the sidebar "open" if we are in search, menu, lists or place routes AND it's visible. // We consider the sidebar "open" if we are in search or place routes AND it's visible.
// This helps the map know if it should shift the center or adjust view. // This helps the map know if it should shift the center or adjust view.
const name = this.router.currentRouteName;
return ( return (
this.mapUi.isSidebarVisible && this.mapUi.isSidebarVisible &&
(name === 'place' || (this.router.currentRouteName === 'place' ||
name === 'place.new' || this.router.currentRouteName === 'place.new' ||
name === 'search' || this.router.currentRouteName === 'search')
name === 'menu' ||
name.startsWith('lists'))
); );
} }
@@ -35,35 +37,24 @@ export default class ApplicationComponent extends Component {
@action @action
toggleAppMenu() { toggleAppMenu() {
if (this.router.currentRouteName === 'menu') { this.isAppMenuOpen = !this.isAppMenuOpen;
this.router.transitionTo('index'); }
} else {
this.router.transitionTo('menu'); @action
} closeAppMenu() {
this.isAppMenuOpen = false;
} }
@action @action
handleOutsideClick() { handleOutsideClick() {
const name = this.router.currentRouteName; if (this.isAppMenuOpen) {
if ( this.closeAppMenu();
name === 'search' || } else if (
name === 'place' || this.router.currentRouteName === 'search' ||
name === 'menu' || this.router.currentRouteName === 'place'
name.startsWith('lists')
) { ) {
this.mapUi.clearSelection(); this.mapUi.clearSelection();
this.mapUi.hideSidebar(); this.mapUi.hideSidebar();
if (name === 'menu' || name.startsWith('lists')) {
this.router.transitionTo('index');
} else if (name === 'place') {
if (this.mapUi.returnToSearch && this.mapUi.currentSearch) {
this.router.transitionTo('search', {
queryParams: this.mapUi.currentSearch,
});
} else {
this.router.transitionTo('index');
}
}
} }
} }
@@ -75,30 +66,32 @@ export default class ApplicationComponent extends Component {
<template> <template>
{{pageTitle "Marco"}} {{pageTitle "Marco"}}
<div class={{if this.mapUi.isSidebarOpening "sidebar-opening"}}> <AppHeader @onToggleMenu={{this.toggleAppMenu}} />
<AppHeader @onToggleMenu={{this.toggleAppMenu}} />
<div
id="rs-widget-container"
class={{if this.storage.isWidgetOpen "visible"}}
></div>
{{#if this.storage.isWidgetOpen}}
<div <div
id="rs-widget-container" class="rs-backdrop"
class={{if this.storage.isWidgetOpen "visible"}} role="button"
{{on "click" this.storage.closeWidget}}
></div> ></div>
{{/if}}
{{#if this.storage.isWidgetOpen}} <Map
<div @isSidebarOpen={{or this.isSidebarOpen this.isAppMenuOpen}}
class="rs-backdrop" @onOutsideClick={{this.handleOutsideClick}}
role="button" />
{{on "click" this.storage.closeWidget}}
></div>
{{/if}}
<Map {{#if this.isAppMenuOpen}}
@isSidebarOpen={{this.isSidebarOpen}} <AppMenu @onClose={{this.closeAppMenu}} />
@onOutsideClick={{this.handleOutsideClick}} {{/if}}
/>
<Toast /> <Toast />
{{outlet}} {{outlet}}
</div>
</template> </template>
} }
-1
View File
@@ -1 +0,0 @@
<template>{{outlet}}</template>
-89
View File
@@ -1,89 +0,0 @@
import Component from '@glimmer/component';
import { service } from '@ember/service';
import { action } from '@ember/object';
import { fn } from '@ember/helper';
import { on } from '@ember/modifier';
import Icon from '#components/icon';
import { htmlSafe } from '@ember/template';
export default class ListsIndexTemplate extends Component {
@service storage;
@service router;
@service mapUi;
styleFor(color) {
const finalColor =
color ||
getComputedStyle(document.documentElement)
.getPropertyValue('--default-list-color')
.trim();
return htmlSafe(`background-color: ${finalColor}`);
}
@action
selectList(listId) {
this.router.transitionTo('lists.list', listId);
}
@action
close() {
this.router.transitionTo('index');
}
@action
backToMenu() {
this.router.transitionTo('menu');
}
<template>
{{#if this.mapUi.isSidebarVisible}}
<div class="sidebar">
<div class="sidebar-header has-back-btn">
<button type="button" class="back-btn" {{on "click" this.backToMenu}}>
<Icon @name="arrow-left" @size={{20}} @color="#333" />
</button>
<h2 class="sidebar-header-text-centered">
<span class="sidebar-header-icon-wrapper">
<Icon @name="bookmark" @size={{20}} @color="#898989" />
</span>
Collections
</h2>
<button type="button" class="close-btn" {{on "click" this.close}}>
<Icon @name="x" @size={{20}} @color="#333" />
</button>
</div>
<div class="sidebar-content">
<ul class="places-list">
{{#each this.storage.lists as |list|}}
<li>
<button
type="button"
class="lists-index-item"
{{on "click" (fn this.selectList list.id)}}
>
<div class="lists-index-item-left">
{{! template-lint-disable no-inline-styles }}
<span
class="list-color-dot"
style={{this.styleFor list.color}}
></span>
<div class="lists-index-name">{{list.title}}</div>
</div>
<div class="lists-index-count">
{{#if list.placeRefs.length}}
{{list.placeRefs.length}}
places
{{else}}
empty
{{/if}}
</div>
</button>
</li>
{{/each}}
</ul>
</div>
</div>
{{/if}}
</template>
}
-16
View File
@@ -1,16 +0,0 @@
import PlacesSidebar from '#components/places-sidebar';
<template>
{{#if @controller.mapUi.isSidebarVisible}}
<PlacesSidebar
@places={{@controller.places}}
@title={{@controller.listTitle}}
@color={{@controller.listColor}}
@scrollTop={{@controller.scrollTop}}
@isLoading={{@controller.loadPlacesTask.isRunning}}
@onSelect={{@controller.selectPlace}}
@onClose={{@controller.close}}
@onBack={{@controller.backToLists}}
/>
{{/if}}
</template>
-15
View File
@@ -1,15 +0,0 @@
import Component from '@glimmer/component';
import AppMenu from '#components/app-menu/index';
import { service } from '@ember/service';
import { action } from '@ember/object';
export default class MenuTemplate extends Component {
@service router;
@action
close() {
this.router.transitionTo('index');
}
<template><AppMenu @onClose={{this.close}} /></template>
}
+1 -14
View File
@@ -77,14 +77,8 @@ export default class PlaceTemplate extends Component {
navigateBack(place) { navigateBack(place) {
// The sidebar calls this with null when "Back" is clicked. // The sidebar calls this with null when "Back" is clicked.
if (place === null) { if (place === null) {
// If we have an active route context (e.g. lists), return to it
if (this.mapUi.returnToRoute) {
this.mapUi.showSidebar();
const { name, model } = this.mapUi.returnToRoute;
this.router.transitionTo(name, model);
}
// If we have an active search context, return to it (UP navigation) // If we have an active search context, return to it (UP navigation)
else if (this.mapUi.returnToSearch && this.mapUi.currentSearch) { if (this.mapUi.returnToSearch && this.mapUi.currentSearch) {
this.mapUi.showSidebar(); this.mapUi.showSidebar();
this.router.transitionTo('search', { this.router.transitionTo('search', {
queryParams: this.mapUi.currentSearch, queryParams: this.mapUi.currentSearch,
@@ -104,13 +98,6 @@ export default class PlaceTemplate extends Component {
close() { close() {
this.mapUi.clearSelection(); this.mapUi.clearSelection();
this.mapUi.hideSidebar(); this.mapUi.hideSidebar();
if (this.mapUi.returnToSearch && this.mapUi.currentSearch) {
this.router.transitionTo('search', {
queryParams: this.mapUi.currentSearch,
});
} else {
this.router.transitionTo('index');
}
} }
<template> <template>
-5
View File
@@ -10,10 +10,6 @@ export default class SearchTemplate extends Component {
@action @action
selectPlace(place) { selectPlace(place) {
if (place) { if (place) {
const sidebarContent = document.querySelector('.sidebar-content');
if (sidebarContent) {
this.mapUi.saveScrollPosition('search', sidebarContent.scrollTop);
}
this.mapUi.returnToSearch = true; this.mapUi.returnToSearch = true;
this.mapUi.showSidebar(); this.mapUi.showSidebar();
this.mapUi.preventNextZoom = true; this.mapUi.preventNextZoom = true;
@@ -32,7 +28,6 @@ export default class SearchTemplate extends Component {
{{#if this.mapUi.isSidebarVisible}} {{#if this.mapUi.isSidebarVisible}}
<PlacesSidebar <PlacesSidebar
@places={{this.mapUi.searchResults}} @places={{this.mapUi.searchResults}}
@scrollTop={{this.mapUi.getScrollPosition "search"}}
@onSelect={{this.selectPlace}} @onSelect={{this.selectPlace}}
@onClose={{this.close}} @onClose={{this.close}}
/> />
-27
View File
@@ -1,7 +1,4 @@
// AGENT: Keep imports sorted alphabetically, grouped by feather-icons → pinhead → custom/local // AGENT: Keep imports sorted alphabetically, grouped by feather-icons → pinhead → custom/local
/*
* Feather icons
*/
import activity from 'feather-icons/dist/icons/activity.svg?raw'; import activity from 'feather-icons/dist/icons/activity.svg?raw';
import arrowLeft from 'feather-icons/dist/icons/arrow-left.svg?raw'; import arrowLeft from 'feather-icons/dist/icons/arrow-left.svg?raw';
import bookmark from 'feather-icons/dist/icons/bookmark.svg?raw'; import bookmark from 'feather-icons/dist/icons/bookmark.svg?raw';
@@ -43,9 +40,6 @@ import check from 'feather-icons/dist/icons/check.svg?raw';
import alertCircle from 'feather-icons/dist/icons/alert-circle.svg?raw'; import alertCircle from 'feather-icons/dist/icons/alert-circle.svg?raw';
import zap from 'feather-icons/dist/icons/zap.svg?raw'; import zap from 'feather-icons/dist/icons/zap.svg?raw';
/*
* Pinhead icons
*/
import angelfish from '@waysidemapping/pinhead/dist/icons/angelfish.svg?raw'; import angelfish from '@waysidemapping/pinhead/dist/icons/angelfish.svg?raw';
import barbell from '@waysidemapping/pinhead/dist/icons/barbell.svg?raw'; import barbell from '@waysidemapping/pinhead/dist/icons/barbell.svg?raw';
import climbingWall from '@waysidemapping/pinhead/dist/icons/climbing_wall.svg?raw'; import climbingWall from '@waysidemapping/pinhead/dist/icons/climbing_wall.svg?raw';
@@ -59,12 +53,8 @@ import bus from '@waysidemapping/pinhead/dist/icons/bus.svg?raw';
import camera from '@waysidemapping/pinhead/dist/icons/camera.svg?raw'; import camera from '@waysidemapping/pinhead/dist/icons/camera.svg?raw';
import boxingGloveUp from '@waysidemapping/pinhead/dist/icons/boxing_glove_up.svg?raw'; import boxingGloveUp from '@waysidemapping/pinhead/dist/icons/boxing_glove_up.svg?raw';
import car from '@waysidemapping/pinhead/dist/icons/car.svg?raw'; import car from '@waysidemapping/pinhead/dist/icons/car.svg?raw';
import carAndWrench from '@waysidemapping/pinhead/dist/icons/car_and_wrench.svg?raw';
import castleKeep from '@waysidemapping/pinhead/dist/icons/castle_keep.svg?raw';
import cigaretteWithSmokeCurl from '@waysidemapping/pinhead/dist/icons/cigarette_with_smoke_curl.svg?raw'; import cigaretteWithSmokeCurl from '@waysidemapping/pinhead/dist/icons/cigarette_with_smoke_curl.svg?raw';
import cityGate from '@waysidemapping/pinhead/dist/icons/city_gate.svg?raw';
import classicalBuilding from '@waysidemapping/pinhead/dist/icons/classical_building.svg?raw'; import classicalBuilding from '@waysidemapping/pinhead/dist/icons/classical_building.svg?raw';
import classicalBuildingWithClock from '@waysidemapping/pinhead/dist/icons/classical_building_with_clock.svg?raw';
import classicalBuildingWithDomeAndFlag from '@waysidemapping/pinhead/dist/icons/classical_building_with_dome_and_flag.svg?raw'; import classicalBuildingWithDomeAndFlag from '@waysidemapping/pinhead/dist/icons/classical_building_with_dome_and_flag.svg?raw';
import classicalBuildingWithFlag from '@waysidemapping/pinhead/dist/icons/classical_building_with_flag.svg?raw'; import classicalBuildingWithFlag from '@waysidemapping/pinhead/dist/icons/classical_building_with_flag.svg?raw';
import commercialBuilding from '@waysidemapping/pinhead/dist/icons/commercial_building.svg?raw'; import commercialBuilding from '@waysidemapping/pinhead/dist/icons/commercial_building.svg?raw';
@@ -92,13 +82,8 @@ import grecianVase from '@waysidemapping/pinhead/dist/icons/grecian_vase.svg?raw
import greekCross from '@waysidemapping/pinhead/dist/icons/greek_cross.svg?raw'; import greekCross from '@waysidemapping/pinhead/dist/icons/greek_cross.svg?raw';
import iceCreamOnCone from '@waysidemapping/pinhead/dist/icons/ice_cream_on_cone.svg?raw'; import iceCreamOnCone from '@waysidemapping/pinhead/dist/icons/ice_cream_on_cone.svg?raw';
import industrialBuilding from '@waysidemapping/pinhead/dist/icons/industrial_building.svg?raw'; import industrialBuilding from '@waysidemapping/pinhead/dist/icons/industrial_building.svg?raw';
import infoI from '@waysidemapping/pinhead/dist/icons/info_i.svg?raw';
import jewel from '@waysidemapping/pinhead/dist/icons/jewel.svg?raw'; import jewel from '@waysidemapping/pinhead/dist/icons/jewel.svg?raw';
import lowriseBuilding from '@waysidemapping/pinhead/dist/icons/lowrise_building.svg?raw'; import lowriseBuilding from '@waysidemapping/pinhead/dist/icons/lowrise_building.svg?raw';
import marketStall from '@waysidemapping/pinhead/dist/icons/market_stall.svg?raw';
import memorialStoneWithInscription from '@waysidemapping/pinhead/dist/icons/memorial_stone_with_inscription.svg?raw';
import mobilePhoneWithKeypadAndAntenna from '@waysidemapping/pinhead/dist/icons/mobile_phone_with_keypad_and_antenna.svg?raw';
import molarTooth from '@waysidemapping/pinhead/dist/icons/molar_tooth.svg?raw';
import needleAndSpoolOfThread from '@waysidemapping/pinhead/dist/icons/needle_and_spool_of_thread.svg?raw'; import needleAndSpoolOfThread from '@waysidemapping/pinhead/dist/icons/needle_and_spool_of_thread.svg?raw';
import openBook from '@waysidemapping/pinhead/dist/icons/open_book.svg?raw'; import openBook from '@waysidemapping/pinhead/dist/icons/open_book.svg?raw';
import palace from '@waysidemapping/pinhead/dist/icons/palace.svg?raw'; import palace from '@waysidemapping/pinhead/dist/icons/palace.svg?raw';
@@ -133,9 +118,6 @@ import wallHangingWithMountainsAndSun from '@waysidemapping/pinhead/dist/icons/w
import windingWayWide from '@waysidemapping/pinhead/dist/icons/winding_way_wide.svg?raw'; import windingWayWide from '@waysidemapping/pinhead/dist/icons/winding_way_wide.svg?raw';
import womensAndMensRestroomSymbol from '@waysidemapping/pinhead/dist/icons/womens_and_mens_restroom_symbol.svg?raw'; import womensAndMensRestroomSymbol from '@waysidemapping/pinhead/dist/icons/womens_and_mens_restroom_symbol.svg?raw';
/*
* Custom/local icons
*/
import loadingRing from '../icons/270-ring.svg?raw'; import loadingRing from '../icons/270-ring.svg?raw';
import nostrich from '../icons/nostrich-2.svg?raw'; import nostrich from '../icons/nostrich-2.svg?raw';
import remotestorage from '../icons/remotestorage.svg?raw'; import remotestorage from '../icons/remotestorage.svg?raw';
@@ -162,13 +144,11 @@ const ICONS = {
'chevron-left': chevronLeft, 'chevron-left': chevronLeft,
'chevron-right': chevronRight, 'chevron-right': chevronRight,
'cigarette-with-smoke-curl': cigaretteWithSmokeCurl, 'cigarette-with-smoke-curl': cigaretteWithSmokeCurl,
'city-gate': cityGate,
climbing_wall: climbingWall, climbing_wall: climbingWall,
check, check,
'alert-circle': alertCircle, 'alert-circle': alertCircle,
'alert-triangle': alertTriangle, 'alert-triangle': alertTriangle,
'classical-building': classicalBuilding, 'classical-building': classicalBuilding,
'classical-building-with-clock': classicalBuildingWithClock,
'classical-building-with-dome-and-flag': classicalBuildingWithDomeAndFlag, 'classical-building-with-dome-and-flag': classicalBuildingWithDomeAndFlag,
'classical-building-with-flag': classicalBuildingWithFlag, 'classical-building-with-flag': classicalBuildingWithFlag,
'commercial-building': commercialBuilding, 'commercial-building': commercialBuilding,
@@ -205,7 +185,6 @@ const ICONS = {
'ice-cream-on-cone': iceCreamOnCone, 'ice-cream-on-cone': iceCreamOnCone,
'industrial-building': industrialBuilding, 'industrial-building': industrialBuilding,
info, info,
'info-i': infoI,
instagram, instagram,
jewel, jewel,
'log-in': logIn, 'log-in': logIn,
@@ -214,11 +193,7 @@ const ICONS = {
mail, mail,
map, map,
'map-pin': mapPin, 'map-pin': mapPin,
'market-stall': marketStall,
'memorial-stone-with-inscription': memorialStoneWithInscription,
menu, menu,
'mobile-phone-with-keypad-and-antenna': mobilePhoneWithKeypadAndAntenna,
'molar-tooth': molarTooth,
'more-horizontal': moreHorizontal, 'more-horizontal': moreHorizontal,
'more-vertical': moreVertical, 'more-vertical': moreVertical,
navigation, navigation,
@@ -270,8 +245,6 @@ const ICONS = {
winding_way_wide: windingWayWide, winding_way_wide: windingWayWide,
parking_p: parkingP, parking_p: parkingP,
car, car,
'car-and-wrench': carAndWrench,
'castle-keep': castleKeep,
x, x,
zap, zap,
'loading-ring': loadingRing, 'loading-ring': loadingRing,
-24
View File
@@ -14,30 +14,6 @@ export function normalizeRelayUrl(url) {
return normalized; return normalized;
} }
export function uniqNormalizedRelays(relays = []) {
return Array.from(new Set(relays.map(normalizeRelayUrl).filter(Boolean)));
}
export function mergeRequiredRelays(requiredRelays = [], customRelays = []) {
const requiredSet = new Set(requiredRelays.filter(Boolean));
const merged = [...requiredRelays.filter(Boolean)];
for (const relay of uniqNormalizedRelays(customRelays)) {
if (!requiredSet.has(relay)) {
merged.push(relay);
}
}
return merged;
}
export function excludeRequiredRelays(customRelays = [], requiredRelays = []) {
const requiredSet = new Set(requiredRelays.filter(Boolean));
return uniqNormalizedRelays(customRelays).filter((relay) => {
return !requiredSet.has(relay);
});
}
/** /**
* Extracts and normalizes photo data from NIP-360 (Place Photos) events. * Extracts and normalizes photo data from NIP-360 (Place Photos) events.
* Sorts chronologically and guarantees the first landscape photo (or first portrait) is at index 0. * Sorts chronologically and guarantees the first landscape photo (or first portrait) is at index 0.
-6
View File
@@ -27,8 +27,6 @@ export const POI_ICON_RULES = [
{ tags: { amenity: 'bank' }, icon: 'banknote' }, { tags: { amenity: 'bank' }, icon: 'banknote' },
{ tags: { amenity: 'place_of_worship' }, icon: 'place-of-worship-building' }, { tags: { amenity: 'place_of_worship' }, icon: 'place-of-worship-building' },
{ tags: { amenity: 'townhall' }, icon: 'classical-building-with-clock' },
{ tags: { building: 'townhall' }, icon: 'classical-building-with-clock' },
{ tags: { amenity: 'fire_station' }, icon: 'badge-shield-with-fire' }, { tags: { amenity: 'fire_station' }, icon: 'badge-shield-with-fire' },
{ tags: { amenity: 'police' }, icon: 'police-officer-with-stop-arm' }, { tags: { amenity: 'police' }, icon: 'police-officer-with-stop-arm' },
{ tags: { amenity: 'toilets' }, icon: 'womens-and-mens-restroom-symbol' }, { tags: { amenity: 'toilets' }, icon: 'womens-and-mens-restroom-symbol' },
@@ -74,7 +72,6 @@ export const POI_ICON_RULES = [
tags: { shop: 'beauty' }, tags: { shop: 'beauty' },
icon: 'fancy-mirror-with-reflection-and-stars', icon: 'fancy-mirror-with-reflection-and-stars',
}, },
{ tags: { shop: 'car_repair' }, icon: 'car-and-wrench' },
{ tags: { craft: 'tailor' }, icon: 'needle-and-spool-of-thread' }, { tags: { craft: 'tailor' }, icon: 'needle-and-spool-of-thread' },
{ tags: { office: 'estate_agent' }, icon: 'village-buildings' }, { tags: { office: 'estate_agent' }, icon: 'village-buildings' },
{ tags: { office: true }, icon: 'commercial-building' }, { tags: { office: true }, icon: 'commercial-building' },
@@ -106,7 +103,6 @@ export const POI_ICON_RULES = [
{ tags: { tourism: 'viewpoint' }, icon: 'camera' }, { tags: { tourism: 'viewpoint' }, icon: 'camera' },
{ tags: { tourism: 'zoo' }, icon: 'camera' }, { tags: { tourism: 'zoo' }, icon: 'camera' },
{ tags: { tourism: 'artwork' }, icon: 'camera' }, { tags: { tourism: 'artwork' }, icon: 'camera' },
{ tags: { tourism: 'information' }, icon: 'info-i' },
{ tags: { amenity: 'cinema' }, icon: 'film' }, { tags: { amenity: 'cinema' }, icon: 'film' },
{ tags: { amenity: 'theatre' }, icon: 'camera' }, { tags: { amenity: 'theatre' }, icon: 'camera' },
{ tags: { amenity: 'arts_centre' }, icon: 'comedy-mask-and-tragedy-mask' }, { tags: { amenity: 'arts_centre' }, icon: 'comedy-mask-and-tragedy-mask' },
@@ -117,9 +113,7 @@ export const POI_ICON_RULES = [
{ tags: { historic: 'bridge' }, icon: 'bridge' }, { tags: { historic: 'bridge' }, icon: 'bridge' },
{ tags: { historic: 'bridge_site' }, icon: 'bridge' }, { tags: { historic: 'bridge_site' }, icon: 'bridge' },
{ tags: { historic: 'fort' }, icon: 'fort' }, { tags: { historic: 'fort' }, icon: 'fort' },
{ tags: { historic: 'city_gate' }, icon: 'city-gate' },
{ tags: { historic: 'castle' }, icon: 'palace' }, { tags: { historic: 'castle' }, icon: 'palace' },
{ tags: { building: 'tower', historic: 'yes' }, icon: 'castle-keep' },
{ tags: { historic: 'building' }, icon: 'classical-building-with-flag' }, { tags: { historic: 'building' }, icon: 'classical-building-with-flag' },
{ tags: { historic: 'archaeological_site' }, icon: 'grecian-vase' }, { tags: { historic: 'archaeological_site' }, icon: 'grecian-vase' },
{ tags: { historic: 'memorial' }, icon: 'memorial-stone-with-inscription' }, { tags: { historic: 'memorial' }, icon: 'memorial-stone-with-inscription' },
+1 -10
View File
@@ -56,24 +56,15 @@ const PLACE_TYPE_KEYS = [
export function getPlaceType(tags) { export function getPlaceType(tags) {
if (!tags) return null; if (!tags) return null;
let fallbackKey = null;
for (const key of PLACE_TYPE_KEYS) { for (const key of PLACE_TYPE_KEYS) {
const value = tags[key]; const value = tags[key];
if (value) { if (value) {
if (value === 'yes') { if (value === 'yes') {
if (!fallbackKey) { return humanizeOsmTag(key);
fallbackKey = key;
}
continue;
} }
return humanizeOsmTag(value); return humanizeOsmTag(value);
} }
} }
if (fallbackKey) {
return humanizeOsmTag(fallbackKey);
}
return null; return null;
} }
+2 -2
View File
@@ -43,7 +43,7 @@ export const POI_CATEGORIES = [
label: 'Things to do', label: 'Things to do',
icon: 'feather-camera', icon: 'feather-camera',
filter: [ filter: [
'["tourism"~"^(museum|gallery|attraction|viewpoint|zoo|theme_park|aquarium|artwork|information)$"]', '["tourism"~"^(museum|gallery|attraction|viewpoint|zoo|theme_park|aquarium|artwork)$"]',
'["amenity"~"^(cinema|theatre|arts_centre|planetarium)$"]', '["amenity"~"^(cinema|theatre|arts_centre|planetarium)$"]',
'["leisure"~"^(sports_centre|stadium|water_park)$"]', '["leisure"~"^(sports_centre|stadium|water_park)$"]',
'["historic"]', '["historic"]',
@@ -55,7 +55,7 @@ export const POI_CATEGORIES = [
id: 'accommodation', id: 'accommodation',
label: 'Hotels', label: 'Hotels',
icon: 'person-sleeping-in-bed', icon: 'person-sleeping-in-bed',
filter: ['["tourism"~"^(hotel|hostel|motel|chalet|guest_house)$"]'], filter: ['["tourism"~"^(hotel|hostel|motel|chalet)$"]'],
types: ['node', 'way', 'relation'], types: ['node', 'way', 'relation'],
}, },
]; ];
+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "marco", "name": "marco",
"version": "1.25.1", "version": "1.24.0",
"private": true, "private": true,
"description": "Unhosted maps app", "description": "Unhosted maps app",
"repository": { "repository": {
@@ -52,7 +52,7 @@
"@embroider/vite": "^1.5.0", "@embroider/vite": "^1.5.0",
"@eslint/js": "^9.39.2", "@eslint/js": "^9.39.2",
"@glimmer/component": "^2.0.0", "@glimmer/component": "^2.0.0",
"@remotestorage/module-places": "~1.3.0", "@remotestorage/module-places": "~1.2.1",
"@rollup/plugin-babel": "^6.1.0", "@rollup/plugin-babel": "^6.1.0",
"@warp-drive/core": "~5.8.0", "@warp-drive/core": "~5.8.0",
"@warp-drive/ember": "~5.8.0", "@warp-drive/ember": "~5.8.0",
+5 -5
View File
@@ -88,8 +88,8 @@ importers:
specifier: ^2.0.0 specifier: ^2.0.0
version: 2.0.0 version: 2.0.0
'@remotestorage/module-places': '@remotestorage/module-places':
specifier: ~1.3.0 specifier: ~1.2.1
version: 1.3.0 version: 1.2.1
'@rollup/plugin-babel': '@rollup/plugin-babel':
specifier: ^6.1.0 specifier: ^6.1.0
version: 6.1.0(@babel/core@7.28.6)(rollup@4.55.1) version: 6.1.0(@babel/core@7.28.6)(rollup@4.55.1)
@@ -1468,8 +1468,8 @@ packages:
resolution: {integrity: sha512-4rdu8GPY9TeQwsYp5D2My74dC3dSVS3tghAvisG80ybK4lqa0gvlrglaSTBxogJbxqHRw/NjI/liEtb3+SD+Bw==} resolution: {integrity: sha512-4rdu8GPY9TeQwsYp5D2My74dC3dSVS3tghAvisG80ybK4lqa0gvlrglaSTBxogJbxqHRw/NjI/liEtb3+SD+Bw==}
engines: {node: '>=18.12'} engines: {node: '>=18.12'}
'@remotestorage/module-places@1.3.0': '@remotestorage/module-places@1.2.1':
resolution: {integrity: sha512-VM0CqkIP6IBEpjqJ2DyTrGDOQXc73aXoAFDLIoME5Lo033uTitgn+qKgTGPK/lD4H92mk1+D3W88ECtf9v3mWw==} resolution: {integrity: sha512-hNRuhGoG8RS+cieVvDVzXWBEuNPfyeFirhgNH3z1WoKw9ngHdPY6V0sT0vKbsxB8xaODReZfo2ZKHLTmdFunlw==}
'@rollup/plugin-babel@6.1.0': '@rollup/plugin-babel@6.1.0':
resolution: {integrity: sha512-dFZNuFD2YRcoomP4oYf+DvQNSUA9ih+A3vUqopQx5EdtPGo3WBnQcI/S8pwpz91UsGfL0HsMSOlaMld8HrbubA==} resolution: {integrity: sha512-dFZNuFD2YRcoomP4oYf+DvQNSUA9ih+A3vUqopQx5EdtPGo3WBnQcI/S8pwpz91UsGfL0HsMSOlaMld8HrbubA==}
@@ -7439,7 +7439,7 @@ snapshots:
'@pnpm/error': 1000.0.5 '@pnpm/error': 1000.0.5
find-up: 5.0.0 find-up: 5.0.0
'@remotestorage/module-places@1.3.0': '@remotestorage/module-places@1.2.1':
dependencies: dependencies:
latlon-geohash: 2.0.0 latlon-geohash: 2.0.0
ulid: 3.0.2 ulid: 3.0.2
-1
View File
@@ -1 +0,0 @@
:root{--body-text-color: #333;--primary-background-color: #fff;--hover-bg: #f8f9fa;--divider-color: #eee;--sidebar-width: 350px;--link-color: #2a7fff;--link-color-visited: #6a4fbf;--marker-color-primary: #ea4335;--marker-color-dark: #b31412;--danger-color: var(--marker-color-primary);--danger-color-dark: var(--marker-color-dark);--default-list-color: #fc3}html,body{height:100%;overscroll-behavior:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}button{-webkit-tap-highlight-color:transparent}body{margin:0;font-family:Noto Sans,sans-serif;font-size:16px;font-weight:400;color:var(--body-text-color)}#root,#ember-testing{height:100%}.map-container{background:#f8f9fa;-webkit-tap-highlight-color:transparent;outline:none;position:absolute;inset:0}#rs-widget-container{position:absolute;top:60px;right:10px;z-index:4000;display:none}#rs-widget-container.visible{display:block}.rs-backdrop{position:fixed;inset:0;z-index:3999}.app-header{position:absolute;top:0;left:0;right:0;height:60px;padding:.5rem 1rem;z-index:3000;pointer-events:none;display:grid;grid-template-columns:1fr auto 1fr;grid-template-areas:"search chips user";align-items:center;gap:1rem}@media(max-width:768px){.app-header{padding:.5rem .5rem 0;height:auto;grid-template-columns:1fr auto;grid-template-areas:"search user" "chips chips";row-gap:8px}}.header-left,.header-right,.header-center{pointer-events:auto}.header-left{display:flex;align-items:center;grid-area:search;justify-self:start;width:100%}@media not (max-width:768px){.header-left{min-width:300px;max-width:400px}}@media not (max-width:768px){.header-left{min-width:300px;max-width:350px}}.header-right{grid-area:user;justify-self:end}.header-center{grid-area:chips;display:flex;justify-content:center;min-width:0}@media not (max-width:768px){.header-center .category-chips-scroll{width:auto;max-width:100%}}@media(max-width:768px){.header-center{width:100%;overflow:hidden;justify-content:start}.header-center.searching{display:none}}.btn-press{transition:transform .1s}.btn-press:active{transform:scale(.95)}.user-btn{background:none;border:none;cursor:pointer;padding:0;display:flex;align-items:center;justify-content:center}.user-avatar-placeholder{width:40px;height:40px;background:#2a3743;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0}.user-avatar{width:40px;height:40px;border-radius:50%;object-fit:cover;flex-shrink:0;display:block}.photo-preview-img{max-width:100%;height:auto}.dropzone{border:2px dashed #ccc;border-radius:8px;text-align:center;transition:all .2s ease;margin:1.5rem 0 1rem;background-color:#ffffff05;cursor:pointer;aspect-ratio:4 / 3}.dropzone.is-dragging{border-color:#61afef;background-color:#61afef0d}.dropzone-label{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1rem;cursor:pointer;color:#898989;width:100%;height:100%}.dropzone-label p{margin:0}.file-input-hidden{display:none}.photo-grid{display:flex;flex-direction:column;gap:12px;margin-bottom:20px}.photo-upload-item{position:relative;aspect-ratio:4 / 3;border-radius:6px;overflow:hidden;background:#1e262e;width:100%}.photo-upload-item img{position:absolute;top:0;left:0;width:100%;height:100%;object-fit:contain;display:block;z-index:1}.photo-upload-item .overlay,.photo-upload-item .btn-remove-photo{z-index:2}.photo-upload-item .overlay{position:absolute;inset:0;background:#0009;display:flex;flex-direction:column;align-items:center;justify-content:center}.upload-status-text{color:#fff;margin-top:1rem;font-size:.9rem;text-shadow:0 1px 3px rgb(0 0 0 / 80%);text-align:center;padding:0 1rem}.photo-upload-item .error-overlay{background:#e06c75cc;cursor:pointer;border:none;padding:0;margin:0;width:100%}.photo-upload-item .btn-remove-photo{position:absolute;top:4px;right:4px;background:#000000b3;border:none;border-radius:50%;width:24px;height:24px;display:flex;align-items:center;justify-content:center;cursor:pointer;color:#fff;padding:0}.photo-upload-item .btn-remove-photo:hover{background:var(--danger-color)}.spin-animation{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.btn-publish{width:100%}.user-menu-container{position:relative}.user-menu-popover{position:absolute;top:100%;right:0;margin-top:10px;width:280px;background:#fff;border-radius:8px;box-shadow:0 4px 12px #00000026;padding:1rem;z-index:3001}.menu-backdrop{position:fixed;inset:0;z-index:3000}.account-list{list-style:none;padding:0;margin:0}.account-item{display:flex;flex-direction:column;padding:1rem 0;border-bottom:1px solid var(--divider-color)}.account-item:last-child{border-bottom:none;padding-bottom:0}.account-item:first-child{padding-top:0}.account-header{display:flex;justify-content:space-between;align-items:center}.account-status{font-size:.85rem;color:#898989;margin-top:.35rem;margin-left:calc(18px + .75rem);white-space:nowrap;overflow:hidden;text-overflowLine truncated
@@ -1,4 +1,4 @@
const amdModule0=Object.freeze(Object.defineProperty({__proto__:null,get default(){return App}},Symbol.toStringTag,{value:"Module"}));!function(){const e=document.createElement("link").relList;if(!(e&&e.supports&&e.supports("modulepreload"))){for(const e of document.querySelectorAll('link[rel="modulepreload"]'))t(e);new MutationObserver(e=>{for(const r of e)if("childList"===r.type)for(const e of r.addedNodes)"LINK"===e.tagName&&"modulepreload"===e.rel&&t(e)}).observe(document,{childList:!0,subtree:!0})}function t(e){if(e.ep)return;e.ep=!0;const t=function(e){const t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),"use-credentials"===e.crossOrigin?t.credentials="include":"anonymous"===e.crossOrigin?t.credentials="omit":t.credentials="same-origin",t}(e);fetch(e.href,t)}}();const hasDOM="object"==typeof self&&null!==self&&self.Object===Object&&"undefined"!=typeof Window&&self.constructor===Window&&"object"==typeof document&&null!==document&&self.document===document&&"object"==typeof location&&null!==location&&self.location===location&&"object"==typeof history&&null!==history&&self.history===history&&"object"==typeof navigator&&null!==navigator&&self.navigator===navigator&&"string"==typeof navigator.userAgent,window$1=hasDOM?self:null,location$1=hasDOM?self.location:null,history$1=hasDOM?self.history:null,userAgent=hasDOM?self.navigator.userAgent:"Lynx (textmode)",isChrome=!(!hasDOM||"object"!=typeof chrome||"object"==typeof opera),isFirefox=!!hasDOM&&/Firefox|FxiOS/.test(userAgent),environment=Object.freeze(Object.defineProperty({__proto__:null,hasDOM:hasDOM,history:history$1,isChrome:isChrome,isFirefox:isFirefox,location:location$1,userAgent:userAgent,window:window$1},Symbol.toStringTag,{value:"Module"}));function checkGlobal(e){return e&&e.Object===Object?e:void 0}function checkElementIdShadowing(e){return e&&void 0===e.nodeType?e:void 0}const global$1=checkGlobal(checkElementIdShadowing("object"==typeof global&&global))||checkGlobal("object"==typeof self&&self)||checkGlobal("object"==typeof window&&window)||"undefined"!=typeof mainContext&&mainContext||new Function("return this")(),context$1=function(e,t){return void 0===t?{imports:e,exports:e,lookup:e}:{imports:t.imports||e,exports:t.exports||e,lookup:t.lookup||e}}(global$1,global$1.Ember);function getLookup(){return context$1.lookup}function setLookup(e){context$1.lookup=e}const ENV$1={ENABLE_OPTIONAL_FEATURES:!1,EXTEND_PROTOTYPES:{Array:!1},LOG_STACKTRACE_ON_DEPRECATION:!0,LOG_VERSION:!0,RAISE_ON_DEPRECATION:!1,STRUCTURED_PROFILE:!1,_DEBUG_RENDER_TREE:!1,_ALL_DEPRECATIONS_ENABLED:!1,_OVERRIDE_DEPRECATION_VERSION:null,_DEFAULT_ASYNC_OBSERVERS:!1,_RERENDER_LOOP_LIMIT:1e3,EMBER_LOAD_HOOKS:{},FEATURES:{}};function getENV(){return ENV$1}(e=>{if("object"!=typeof e||null===e)return;for(let n in e){if(!Object.prototype.hasOwnProperty.call(e,n)||"EXTEND_PROTOTYPES"===n||"EMBER_LOAD_HOOKS"===n)continue;let t=ENV$1[n];ENV$1[n]=!0===t?!1!==e[n]:!1===t?!0===e[n]:e[n]}let{EMBER_LOAD_HOOKS:t}=e;if("object"==typeof t&&null!==t)for(let n in t){if(!Object.prototype.hasOwnProperty.call(t,n))continue;let e=t[n];Array.isArray(e)&&(ENV$1.EMBER_LOAD_HOOKS[n]=e.filter(e=>"function"==typeof e))}let{FEATURES:r}=e;if("object"==typeof r&&null!==r)for(let n in r)Object.prototype.hasOwnProperty.call(r,n)&&(ENV$1.FEATURES[n]=!0===r[n])})(global$1.EmberENV);let assert$3=()=>{},registerHandler$1=()=>{},deprecate$1=()=>{};const defaultDeprecate=deprecate$1;let testing=!1;function isTesting(){return testing}function setTesting(e){testing=Boolean(e)}let registerHandler=()=>{};const{toString:objectToString$1}=Object.prototype,{toString:functionToString}=Function.prototype,{isArray:isArray$6}=Array,{keys:objectKeys}=Object,{stringify:stringify}=JSON,LIST_LIMIT=100,DEPTH_LIMIT=4,SAFE_KEY=/^[\w$]+$/;function inspect(e){return"number"==typeof e&&2===arguments.length?this:inspectValue(e,0)}function inspectValue(e,t,r){let n=!1;switch(typeof e){case"undefined":return"undefined";case"object":if(null===e)return"null";if(isArray$6(e)){n=!0;break}if(e.toString===objectToString$1||void 0===e.toString)break;return e.toString();case"function":return e.toString===functionToString?e.name?`[Function:${e.name}]`:"[Function]":e.toString();case"string":return stringify(e);default:return e.toString()}if(void 0===r)r=new WeakSet;else if(r.has(e))return"[Circular]";return r.add(e),n?inspectArray(e,t+1,r):inspectObject(e,t+1,r)}function inspectKey(e){return SAFE_KEY.test(e)?e:stringify(e)}function inspectObject(e,t,r){if(t>DEPTH_LIMIT)return"[Object]";let n="{",i=objectKeys(e);for(let o=0;o<i.length;o++){if(n+=0===o?" ":", ",o>=LIST_LIMIT){n+=`... ${i.length-LIST_LIMIT} more keys`;break}let s=i[o];n+=`${inspectKey(String(s))}: ${inspectValue(e[s],t,r)}`}return n+=" }",n}function inspectArray(e,t,r){if(t>DEPTH_LIMIT)return"[Array]";let n="[";for(let i=0;i<e.length;i++){if(n+=0===i?" ":", ",i>=LIST_LIMIT){n+=`... ${e.length-LIST_LIMIT} more items`;break}n+=insLine truncated const amdModule0=Object.freeze(Object.defineProperty({__proto__:null,get default(){return App}},Symbol.toStringTag,{value:"Module"}));!function(){const e=document.createElement("link").relList;if(!(e&&e.supports&&e.supports("modulepreload"))){for(const e of document.querySelectorAll('link[rel="modulepreload"]'))t(e);new MutationObserver(e=>{for(const r of e)if("childList"===r.type)for(const e of r.addedNodes)"LINK"===e.tagName&&"modulepreload"===e.rel&&t(e)}).observe(document,{childList:!0,subtree:!0})}function t(e){if(e.ep)return;e.ep=!0;const t=function(e){const t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),"use-credentials"===e.crossOrigin?t.credentials="include":"anonymous"===e.crossOrigin?t.credentials="omit":t.credentials="same-origin",t}(e);fetch(e.href,t)}}();const hasDOM="object"==typeof self&&null!==self&&self.Object===Object&&"undefined"!=typeof Window&&self.constructor===Window&&"object"==typeof document&&null!==document&&self.document===document&&"object"==typeof location&&null!==location&&self.location===location&&"object"==typeof history&&null!==history&&self.history===history&&"object"==typeof navigator&&null!==navigator&&self.navigator===navigator&&"string"==typeof navigator.userAgent,window$1=hasDOM?self:null,location$1=hasDOM?self.location:null,history$1=hasDOM?self.history:null,userAgent=hasDOM?self.navigator.userAgent:"Lynx (textmode)",isChrome=!(!hasDOM||"object"!=typeof chrome||"object"==typeof opera),isFirefox=!!hasDOM&&/Firefox|FxiOS/.test(userAgent),environment=Object.freeze(Object.defineProperty({__proto__:null,hasDOM:hasDOM,history:history$1,isChrome:isChrome,isFirefox:isFirefox,location:location$1,userAgent:userAgent,window:window$1},Symbol.toStringTag,{value:"Module"}));function checkGlobal(e){return e&&e.Object===Object?e:void 0}function checkElementIdShadowing(e){return e&&void 0===e.nodeType?e:void 0}const global$1=checkGlobal(checkElementIdShadowing("object"==typeof global&&global))||checkGlobal("object"==typeof self&&self)||checkGlobal("object"==typeof window&&window)||"undefined"!=typeof mainContext&&mainContext||new Function("return this")(),context$1=function(e,t){return void 0===t?{imports:e,exports:e,lookup:e}:{imports:t.imports||e,exports:t.exports||e,lookup:t.lookup||e}}(global$1,global$1.Ember);function getLookup(){return context$1.lookup}function setLookup(e){context$1.lookup=e}const ENV$1={ENABLE_OPTIONAL_FEATURES:!1,EXTEND_PROTOTYPES:{Array:!1},LOG_STACKTRACE_ON_DEPRECATION:!0,LOG_VERSION:!0,RAISE_ON_DEPRECATION:!1,STRUCTURED_PROFILE:!1,_DEBUG_RENDER_TREE:!1,_ALL_DEPRECATIONS_ENABLED:!1,_OVERRIDE_DEPRECATION_VERSION:null,_DEFAULT_ASYNC_OBSERVERS:!1,_RERENDER_LOOP_LIMIT:1e3,EMBER_LOAD_HOOKS:{},FEATURES:{}};function getENV(){return ENV$1}(e=>{if("object"!=typeof e||null===e)return;for(let n in e){if(!Object.prototype.hasOwnProperty.call(e,n)||"EXTEND_PROTOTYPES"===n||"EMBER_LOAD_HOOKS"===n)continue;let t=ENV$1[n];ENV$1[n]=!0===t?!1!==e[n]:!1===t?!0===e[n]:e[n]}let{EMBER_LOAD_HOOKS:t}=e;if("object"==typeof t&&null!==t)for(let n in t){if(!Object.prototype.hasOwnProperty.call(t,n))continue;let e=t[n];Array.isArray(e)&&(ENV$1.EMBER_LOAD_HOOKS[n]=e.filter(e=>"function"==typeof e))}let{FEATURES:r}=e;if("object"==typeof r&&null!==r)for(let n in r)Object.prototype.hasOwnProperty.call(r,n)&&(ENV$1.FEATURES[n]=!0===r[n])})(global$1.EmberENV);let assert$3=()=>{},registerHandler$1=()=>{},deprecate$1=()=>{};const defaultDeprecate=deprecate$1;let testing=!1;function isTesting(){return testing}function setTesting(e){testing=Boolean(e)}let registerHandler=()=>{};const{toString:objectToString$1}=Object.prototype,{toString:functionToString}=Function.prototype,{isArray:isArray$6}=Array,{keys:objectKeys}=Object,{stringify:stringify}=JSON,LIST_LIMIT=100,DEPTH_LIMIT=4,SAFE_KEY=/^[\w$]+$/;function inspect(e){return"number"==typeof e&&2===arguments.length?this:inspectValue(e,0)}function inspectValue(e,t,r){let n=!1;switch(typeof e){case"undefined":return"undefined";case"object":if(null===e)return"null";if(isArray$6(e)){n=!0;break}if(e.toString===objectToString$1||void 0===e.toString)break;return e.toString();case"function":return e.toString===functionToString?e.name?`[Function:${e.name}]`:"[Function]":e.toString();case"string":return stringify(e);default:return e.toString()}if(void 0===r)r=new WeakSet;else if(r.has(e))return"[Circular]";return r.add(e),n?inspectArray(e,t+1,r):inspectObject(e,t+1,r)}function inspectKey(e){return SAFE_KEY.test(e)?e:stringify(e)}function inspectObject(e,t,r){if(t>DEPTH_LIMIT)return"[Object]";let n="{",i=objectKeys(e);for(let o=0;o<i.length;o++){if(n+=0===o?" ":", ",o>=LIST_LIMIT){n+=`... ${i.length-LIST_LIMIT} more keys`;break}let s=i[o];n+=`${inspectKey(String(s))}: ${inspectValue(e[s],t,r)}`}return n+=" }",n}function inspectArray(e,t,r){if(t>DEPTH_LIMIT)return"[Array]";let n="[";for(let i=0;i<e.length;i++){if(n+=0===i?" ":", ",i>=LIST_LIMIT){n+=`... ${e.length-LIST_LIMIT} more items`;break}n+=insLine truncated
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */if(!isLE$3)throw new Error("Non little-endian hardware is not supported");function utf8ToBytes$2(e){if("string"!=typeof e)throw new Error("utf8ToBytes expected string, got "+typeof e);return new Uint8Array((new TextEncoder).encode(e))}function toBytes$1(e){if("string"==typeof e&&(e=utf8ToBytes$2(e)),!u8a$2(e))throw new Error("expected Uint8Array, got "+typeof e);return e}function concatBytes$3(...e){const t=new Uint8Array(e.reduce((e,t)=>e+t.length,0));let r=0;return e.forEach(e=>{if(!u8a$2(e))throw new Error("Uint8Array expected");t.set(e,r),r+=e.length}),t}let Hash$1=class{clone(){return this._cloneInto()}};function wrapConstructor$1(e){const t=t=>e().update(toBytes$1(t)).digest(),r=e();return t.outputLen=r.outputLen,t.blockLen=r.blockLen,t.create=()=>e(),t}function randomBytes$2(e=32){if(crypto$2&&"function"==typeof crypto$2.getRandomValues)return crypto$2.getRandomValues(new Uint8Array(e));throw new Error("crypto.getRandomValues must be defined")}function setBigUint64$1(e,t,r,n){if("function"==typeof e.setBigUint64)return e.setBigUint64(t,r,n);const i=BigInt(32),o=BigInt(4294967295),s=Number(r>>i&o),a=Number(r&o),l=n?4:0,c=n?0:4;e.setUint32(t+l,s,n),e.setUint32(t+c,a,n)}let SHA2$1=class extends Hash$1{constructor(e,t,r,n){super(),this.blockLen=e,this.outputLen=t,this.padOffset=r,this.isLE=n,this.finished=!1,this.length=0,this.pos=0,this.destroyed=!1,this.buffer=new Uint8Array(e),this.view=createView$3(this.buffer)}update(e){exists$1(this);const{view:t,buffer:r,blockLen:n}=this,i=(e=toBytes$1(e)).length;for(let o=0;o<i;){const s=Math.min(n-this.pos,i-o);if(s===n){const t=createView$3(e);for(;n<=i-o;o+=n)this.process(t,o);continue}r.set(e.subarray(o,o+s),this.pos),this.pos+=s,o+=s,this.pos===n&&(this.process(t,0),this.pos=0)}return this.length+=e.length,this.roundClean(),this}digestInto(e){exists$1(this),output$1(e,this),this.finished=!0;const{buffer:t,view:r,blockLen:n,isLE:i}=this;let{pos:o}=this;t[o++]=128,this.buffer.subarray(o).fill(0),this.padOffset>n-o&&(this.process(r,0),o=0);for(let u=o;u<n;u++)t[u]=0;setBigUint64$1(r,n-8,BigInt(8*this.length),i),this.process(r,0);const s=createView$3(e),a=this.outputLen;if(a%4)throw new Error("_sha2: outputLen should be aligned to 32bit");const l=a/4,c=this.get();if(l>c.length)throw new Error("_sha2: outputLen bigger than state");for(let u=0;u<l;u++)s.setUint32(4*u,c[u],i)}digest(){const{buffer:e,outputLen:t}=this;this.digestInto(e);const r=e.slice(0,t);return this.destroy(),r}_cloneInto(e){e||(e=new this.constructor),e.set(...this.get());const{blockLen:t,buffer:r,length:n,finished:i,destroyed:o,pos:s}=this;return e.length=n,e.pos=s,e.finished=i,e.destroyed=o,n%t&&e.buffer.set(r),e}};const Chi$3=(e,t,r)=>e&t^~e&r,Maj$3=(e,t,r)=>e&t^e&r^t&r,SHA256_K$3=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),IV$1=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),SHA256_W$3=new Uint32Array(64);let SHA256$1=class extends SHA2$1{constructor(){super(64,32,8,!1),this.A=0|IV$1[0],this.B=0|IV$1[1],this.C=0|IV$1[2],this.D=0|IV$1[3],this.E=0|IV$1[4],this.F=0|IV$1[5],this.G=0|IV$1[6],this.H=0|IV$1[7]}get(){const{A:e,B:t,C:r,D:n,E:i,F:o,G:s,H:a}=this;return[e,t,r,n,i,o,s,a]}set(e,t,r,n,i,o,s,a){this.A=0|e,this.B=0|t,this.C=0|r,this.D=0|n,this.E=0|i,this.F=0|o,this.G=0|s,this.H=0|a}process(e,t){for(let u=0;u<16;u++,t+=4)SHA256_W$3[u]=e.getUint32(t,!1);for(let u=16;u<64;u++){const e=SHA256_W$3[u-15],t=SHA256_W$3[u-2],r=rotr$3(e,7)^rotr$3(e,18)^e>>>3,n=rotr$3(t,17)^rotr$3(t,19)^t>>>10;SHA256_W$3[u]=n+SHA256_W$3[u-7]+r+SHA256_W$3[u-16]|0}let{A:r,B:n,C:i,D:o,E:s,F:a,G:l,H:c}=this;for(let u=0;u<64;u++){const e=c+(rotr$3(s,6)^rotr$3(s,11)^rotr$3(s,25))+Chi$3(s,a,l)+SHA256_K$3[u]+SHA256_W$3[u]|0,t=(rotr$3(r,2)^rotr$3(r,13)^rotr$3(r,22))+Maj$3(r,n,i)|0;c=l,l=a,a=s,s=o+e|0,o=i,i=n,n=r,r=e+t|0}r=r+this.A|0,n=n+this.B|0,i=i+this.C|0,o=o+this.D|0,s=s+this.E|0,a=a+this.F|0,l=l+this.G|0,c=c+this.H|0,this.set(r,n,i,o,s,a,l,c)}roundClean(){SHA256_W$3.fill(0)}destroy(){this.set(0,0,0,0,0,0,0,0),this.buffer.fill(0)}};const sha256$3=wrapConstructor$1(()=>new SHA256$1),_0n$a=BigInt(0),_1n$9=BigInt(1),_2n$6=BigInt(2),u8a$1=e=>e instanceof Uint8Array,hexes$4=Array.from({length:256},(e,t)=>t.toString(16).padStart(2,"0")); /*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */if(!isLE$3)throw new Error("Non little-endian hardware is not supported");function utf8ToBytes$2(e){if("string"!=typeof e)throw new Error("utf8ToBytes expected string, got "+typeof e);return new Uint8Array((new TextEncoder).encode(e))}function toBytes$1(e){if("string"==typeof e&&(e=utf8ToBytes$2(e)),!u8a$2(e))throw new Error("expected Uint8Array, got "+typeof e);return e}function concatBytes$3(...e){const t=new Uint8Array(e.reduce((e,t)=>e+t.length,0));let r=0;return e.forEach(e=>{if(!u8a$2(e))throw new Error("Uint8Array expected");t.set(e,r),r+=e.length}),t}let Hash$1=class{clone(){return this._cloneInto()}};function wrapConstructor$1(e){const t=t=>e().update(toBytes$1(t)).digest(),r=e();return t.outputLen=r.outputLen,t.blockLen=r.blockLen,t.create=()=>e(),t}function randomBytes$2(e=32){if(crypto$2&&"function"==typeof crypto$2.getRandomValues)return crypto$2.getRandomValues(new Uint8Array(e));throw new Error("crypto.getRandomValues must be defined")}function setBigUint64$1(e,t,r,n){if("function"==typeof e.setBigUint64)return e.setBigUint64(t,r,n);const i=BigInt(32),o=BigInt(4294967295),s=Number(r>>i&o),a=Number(r&o),l=n?4:0,c=n?0:4;e.setUint32(t+l,s,n),e.setUint32(t+c,a,n)}let SHA2$1=class extends Hash$1{constructor(e,t,r,n){super(),this.blockLen=e,this.outputLen=t,this.padOffset=r,this.isLE=n,this.finished=!1,this.length=0,this.pos=0,this.destroyed=!1,this.buffer=new Uint8Array(e),this.view=createView$3(this.buffer)}update(e){exists$1(this);const{view:t,buffer:r,blockLen:n}=this,i=(e=toBytes$1(e)).length;for(let o=0;o<i;){const s=Math.min(n-this.pos,i-o);if(s===n){const t=createView$3(e);for(;n<=i-o;o+=n)this.process(t,o);continue}r.set(e.subarray(o,o+s),this.pos),this.pos+=s,o+=s,this.pos===n&&(this.process(t,0),this.pos=0)}return this.length+=e.length,this.roundClean(),this}digestInto(e){exists$1(this),output$1(e,this),this.finished=!0;const{buffer:t,view:r,blockLen:n,isLE:i}=this;let{pos:o}=this;t[o++]=128,this.buffer.subarray(o).fill(0),this.padOffset>n-o&&(this.process(r,0),o=0);for(let u=o;u<n;u++)t[u]=0;setBigUint64$1(r,n-8,BigInt(8*this.length),i),this.process(r,0);const s=createView$3(e),a=this.outputLen;if(a%4)throw new Error("_sha2: outputLen should be aligned to 32bit");const l=a/4,c=this.get();if(l>c.length)throw new Error("_sha2: outputLen bigger than state");for(let u=0;u<l;u++)s.setUint32(4*u,c[u],i)}digest(){const{buffer:e,outputLen:t}=this;this.digestInto(e);const r=e.slice(0,t);return this.destroy(),r}_cloneInto(e){e||(e=new this.constructor),e.set(...this.get());const{blockLen:t,buffer:r,length:n,finished:i,destroyed:o,pos:s}=this;return e.length=n,e.pos=s,e.finished=i,e.destroyed=o,n%t&&e.buffer.set(r),e}};const Chi$3=(e,t,r)=>e&t^~e&r,Maj$3=(e,t,r)=>e&t^e&r^t&r,SHA256_K$3=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),IV$1=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),SHA256_W$3=new Uint32Array(64);let SHA256$1=class extends SHA2$1{constructor(){super(64,32,8,!1),this.A=0|IV$1[0],this.B=0|IV$1[1],this.C=0|IV$1[2],this.D=0|IV$1[3],this.E=0|IV$1[4],this.F=0|IV$1[5],this.G=0|IV$1[6],this.H=0|IV$1[7]}get(){const{A:e,B:t,C:r,D:n,E:i,F:o,G:s,H:a}=this;return[e,t,r,n,i,o,s,a]}set(e,t,r,n,i,o,s,a){this.A=0|e,this.B=0|t,this.C=0|r,this.D=0|n,this.E=0|i,this.F=0|o,this.G=0|s,this.H=0|a}process(e,t){for(let u=0;u<16;u++,t+=4)SHA256_W$3[u]=e.getUint32(t,!1);for(let u=16;u<64;u++){const e=SHA256_W$3[u-15],t=SHA256_W$3[u-2],r=rotr$3(e,7)^rotr$3(e,18)^e>>>3,n=rotr$3(t,17)^rotr$3(t,19)^t>>>10;SHA256_W$3[u]=n+SHA256_W$3[u-7]+r+SHA256_W$3[u-16]|0}let{A:r,B:n,C:i,D:o,E:s,F:a,G:l,H:c}=this;for(let u=0;u<64;u++){const e=c+(rotr$3(s,6)^rotr$3(s,11)^rotr$3(s,25))+Chi$3(s,a,l)+SHA256_K$3[u]+SHA256_W$3[u]|0,t=(rotr$3(r,2)^rotr$3(r,13)^rotr$3(r,22))+Maj$3(r,n,i)|0;c=l,l=a,a=s,s=o+e|0,o=i,i=n,n=r,r=e+t|0}r=r+this.A|0,n=n+this.B|0,i=i+this.C|0,o=o+this.D|0,s=s+this.E|0,a=a+this.F|0,l=l+this.G|0,c=c+this.H|0,this.set(r,n,i,o,s,a,l,c)}roundClean(){SHA256_W$3.fill(0)}destroy(){this.set(0,0,0,0,0,0,0,0),this.buffer.fill(0)}};const sha256$3=wrapConstructor$1(()=>new SHA256$1),_0n$a=BigInt(0),_1n$9=BigInt(1),_2n$6=BigInt(2),u8a$1=e=>e instanceof Uint8Array,hexes$4=Array.from({length:256},(e,t)=>t.toString(16).padStart(2,"0"));
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */function bytesToHex$4(e){if(!u8a$1(e))throw new Error("Uint8Array expected");let t="";for(let r=0;r<e.length;r++)t+=hexes$4[e[r]];return t}function numberToHexUnpadded$2(e){const t=e.toString(16);return 1&t.length?`0${t}`:t}function hexToNumber$2(e){if("string"!=typeof e)throw new Error("hex string expected, got "+typeof e);return BigInt(""===e?"0":`0x${e}`)}function hexToBytes$4(e){if("string"!=typeof e)throw new Error("hex string expected, got "+typeof e);const t=e.length;if(t%2)throw new Error("padded hex string expected, got unpadded hex of length "+t);const r=new Uint8Array(t/2);for(let n=0;n<r.length;n++){const t=2*n,i=e.slice(t,t+2),o=Number.parseInt(i,16);if(Number.isNaN(o)||o<0)throw new Error("Invalid byte sequence");r[n]=o}return r}function bytesToNumberBE$1(e){return hexToNumber$2(bytesToHex$4(e))}function bytesToNumberLE$1(e){if(!u8a$1(e))throw new Error("Uint8Array expected");return hexToNumber$2(bytesToHex$4(Uint8Array.from(e).reverse()))}function numberToBytesBE$1(e,t){return hexToBytes$4(e.toString(16).padStart(2*t,"0"))}function numberToBytesLE$1(e,t){return numberToBytesBE$1(e,t).reverse()}function numberToVarBytesBE(e){return hexToBytes$4(numberToHexUnpadded$2(e))}function ensureBytes$1(e,t,r){let n;if("string"==typeof t)try{n=hexToBytes$4(t)}catch(o){throw new Error(`${e} must be valid hex string, got "${t}". Cause: ${o}`)}else{if(!u8a$1(t))throw new Error(`${e} must be hex string or Uint8Array`);n=Uint8Array.from(t)}const i=n.length;if("number"==typeof r&&i!==r)throw new Error(`${e} expected ${r} bytes, got ${i}`);return n}function concatBytes$2(...e){const t=new Uint8Array(e.reduce((e,t)=>e+t.length,0));let r=0;return e.forEach(e=>{if(!u8a$1(e))throw new Error("Uint8Array expected");t.set(e,r),r+=e.length}),t}function equalBytes$2(e,t){if(e.length!==t.length)return!1;for(let r=0;r<e.length;r++)if(e[r]!==t[r])return!1;return!0}function utf8ToBytes$1(e){if("string"!=typeof e)throw new Error("utf8ToBytes expected string, got "+typeof e);return new Uint8Array((new TextEncoder).encode(e))}function bitLen$1(e){let t;for(t=0;e>_0n$a;e>>=_1n$9,t+=1);return t}function bitGet(e,t){return e>>BigInt(t)&_1n$9}const bitSet=(e,t,r)=>e|(r?_1n$9:_0n$a)<<BigInt(t),bitMask$1=e=>(_2n$6<<BigInt(e-1))-_1n$9,u8n=e=>new Uint8Array(e),u8fr=e=>Uint8Array.from(e);function createHmacDrbg$1(e,t,r){if("number"!=typeof e||e<2)throw new Error("hashLen must be a number");if("number"!=typeof t||t<2)throw new Error("qByteLen must be a number");if("function"!=typeof r)throw new Error("hmacFn must be a function");let n=u8n(e),i=u8n(e),o=0;const s=()=>{n.fill(1),i.fill(0),o=0},a=(...e)=>r(i,n,...e),l=(e=u8n())=>{i=a(u8fr([0]),e),n=a(),0!==e.length&&(i=a(u8fr([1]),e),n=a())},c=()=>{if(o++>=1e3)throw new Error("drbg: tried 1000 values");let e=0;const r=[];for(;e<t;){n=a();const t=n.slice();r.push(t),e+=n.length}return concatBytes$2(...r)};return(e,t)=>{let r;for(s(),l(e);!(r=t(c()));)l();return s(),r}}const validatorFns={bigint:e=>"bigint"==typeof e,function:e=>"function"==typeof e,boolean:e=>"boolean"==typeof e,string:e=>"string"==typeof e,stringOrUint8Array:e=>"string"==typeof e||e instanceof Uint8Array,isSafeInteger:e=>Number.isSafeInteger(e),array:e=>Array.isArray(e),field:(e,t)=>t.Fp.isValid(e),hash:e=>"function"==typeof e&&Number.isSafeInteger(e.outputLen)};function validateObject$1(e,t,r={}){const n=(t,r,n)=>{const i=validatorFns[r];if("function"!=typeof i)throw new Error(`Invalid validator "${r}", expected function`);const o=e[t];if(!(n&&void 0===o||i(o,e)))throw new Error(`Invalid param ${String(t)}=${o} (${typeof o}), expected ${r}`)};for(const[i,o]of Object.entries(t))n(i,o,!1);for(const[i,o]of Object.entries(r))n(i,o,!0);return e}const ut=Object.freeze(Object.defineProperty({__proto__:null,bitGet:bitGet,bitLen:bitLen$1,bitMask:bitMask$1,bitSet:bitSet,bytesToHex:bytesToHex$4,bytesToNumberBE:bytesToNumberBE$1,bytesToNumberLE:bytesToNumberLE$1,concatBytes:concatBytes$2,createHmacDrbg:createHmacDrbg$1,ensureBytes:ensureBytes$1,equalBytes:equalBytes$2,hexToBytes:hexToBytes$4,hexToNumber:hexToNumber$2,numberToBytesBE:numberToBytesBE$1,numberToBytesLE:numberToBytesLE$1,numberToHexUnpadded:numberToHexUnpadded$2,numberToVarBytesBE:numberToVarBytesBE,utf8ToBytes:utf8ToBytes$1,validateObject:validateObject$1},Symbol.toStringTag,{value:"Module"})),_0n$9=BigInt(0),_1n$8=BigInt(1),_2n$5=BigInt(2),_3n$4=BigInt(3),_4n$2=BigInt(4),_5n$1=BigInt(5),_8n$2=BigInt(8); /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */function bytesToHex$4(e){if(!u8a$1(e))throw new Error("Uint8Array expected");let t="";for(let r=0;r<e.length;r++)t+=hexes$4[e[r]];return t}function numberToHexUnpadded$2(e){const t=e.toString(16);return 1&t.length?`0${t}`:t}function hexToNumber$2(e){if("string"!=typeof e)throw new Error("hex string expected, got "+typeof e);return BigInt(""===e?"0":`0x${e}`)}function hexToBytes$4(e){if("string"!=typeof e)throw new Error("hex string expected, got "+typeof e);const t=e.length;if(t%2)throw new Error("padded hex string expected, got unpadded hex of length "+t);const r=new Uint8Array(t/2);for(let n=0;n<r.length;n++){const t=2*n,i=e.slice(t,t+2),o=Number.parseInt(i,16);if(Number.isNaN(o)||o<0)throw new Error("Invalid byte sequence");r[n]=o}return r}function bytesToNumberBE$1(e){return hexToNumber$2(bytesToHex$4(e))}function bytesToNumberLE$1(e){if(!u8a$1(e))throw new Error("Uint8Array expected");return hexToNumber$2(bytesToHex$4(Uint8Array.from(e).reverse()))}function numberToBytesBE$1(e,t){return hexToBytes$4(e.toString(16).padStart(2*t,"0"))}function numberToBytesLE$1(e,t){return numberToBytesBE$1(e,t).reverse()}function numberToVarBytesBE(e){return hexToBytes$4(numberToHexUnpadded$2(e))}function ensureBytes$1(e,t,r){let n;if("string"==typeof t)try{n=hexToBytes$4(t)}catch(o){throw new Error(`${e} must be valid hex string, got "${t}". Cause: ${o}`)}else{if(!u8a$1(t))throw new Error(`${e} must be hex string or Uint8Array`);n=Uint8Array.from(t)}const i=n.length;if("number"==typeof r&&i!==r)throw new Error(`${e} expected ${r} bytes, got ${i}`);return n}function concatBytes$2(...e){const t=new Uint8Array(e.reduce((e,t)=>e+t.length,0));let r=0;return e.forEach(e=>{if(!u8a$1(e))throw new Error("Uint8Array expected");t.set(e,r),r+=e.length}),t}function equalBytes$2(e,t){if(e.length!==t.length)return!1;for(let r=0;r<e.length;r++)if(e[r]!==t[r])return!1;return!0}function utf8ToBytes$1(e){if("string"!=typeof e)throw new Error("utf8ToBytes expected string, got "+typeof e);return new Uint8Array((new TextEncoder).encode(e))}function bitLen$1(e){let t;for(t=0;e>_0n$a;e>>=_1n$9,t+=1);return t}function bitGet(e,t){return e>>BigInt(t)&_1n$9}const bitSet=(e,t,r)=>e|(r?_1n$9:_0n$a)<<BigInt(t),bitMask$1=e=>(_2n$6<<BigInt(e-1))-_1n$9,u8n=e=>new Uint8Array(e),u8fr=e=>Uint8Array.from(e);function createHmacDrbg$1(e,t,r){if("number"!=typeof e||e<2)throw new Error("hashLen must be a number");if("number"!=typeof t||t<2)throw new Error("qByteLen must be a number");if("function"!=typeof r)throw new Error("hmacFn must be a function");let n=u8n(e),i=u8n(e),o=0;const s=()=>{n.fill(1),i.fill(0),o=0},a=(...e)=>r(i,n,...e),l=(e=u8n())=>{i=a(u8fr([0]),e),n=a(),0!==e.length&&(i=a(u8fr([1]),e),n=a())},c=()=>{if(o++>=1e3)throw new Error("drbg: tried 1000 values");let e=0;const r=[];for(;e<t;){n=a();const t=n.slice();r.push(t),e+=n.length}return concatBytes$2(...r)};return(e,t)=>{let r;for(s(),l(e);!(r=t(c()));)l();return s(),r}}const validatorFns={bigint:e=>"bigint"==typeof e,function:e=>"function"==typeof e,boolean:e=>"boolean"==typeof e,string:e=>"string"==typeof e,stringOrUint8Array:e=>"string"==typeof e||e instanceof Uint8Array,isSafeInteger:e=>Number.isSafeInteger(e),array:e=>Array.isArray(e),field:(e,t)=>t.Fp.isValid(e),hash:e=>"function"==typeof e&&Number.isSafeInteger(e.outputLen)};function validateObject$1(e,t,r={}){const n=(t,r,n)=>{const i=validatorFns[r];if("function"!=typeof i)throw new Error(`Invalid validator "${r}", expected function`);const o=e[t];if(!(n&&void 0===o||i(o,e)))throw new Error(`Invalid param ${String(t)}=${o} (${typeof o}), expected ${r}`)};for(const[i,o]of Object.entries(t))n(i,o,!1);for(const[i,o]of Object.entries(r))n(i,o,!0);return e}const ut=Object.freeze(Object.defineProperty({__proto__:null,bitGet:bitGet,bitLen:bitLen$1,bitMask:bitMask$1,bitSet:bitSet,bytesToHex:bytesToHex$4,bytesToNumberBE:bytesToNumberBE$1,bytesToNumberLE:bytesToNumberLE$1,concatBytes:concatBytes$2,createHmacDrbg:createHmacDrbg$1,ensureBytes:ensureBytes$1,equalBytes:equalBytes$2,hexToBytes:hexToBytes$4,hexToNumber:hexToNumber$2,numberToBytesBE:numberToBytesBE$1,numberToBytesLE:numberToBytesLE$1,numberToHexUnpadded:numberToHexUnpadded$2,numberToVarBytesBE:numberToVarBytesBE,utf8ToBytes:utf8ToBytes$1,validateObject:validateObject$1},Symbol.toStringTag,{value:"Module"})),_0n$9=BigInt(0),_1n$8=BigInt(1),_2n$5=BigInt(2),_3n$4=BigInt(3),_4n$2=BigInt(4),_5n$1=BigInt(5),_8n$2=BigInt(8);
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */function mod$2(e,t){const r=e%t;return r>=_0n$9?r:t+r}function pow(e,t,r){if(r<=_0n$9||t<_0n$9)throw new Error("Expected power/modulo > 0");if(r===_1n$8)return _0n$9;let n=_1n$8;for(;t>_0n$9;)t&_1n$8&&(n=n*e%r),e=e*e%r,t>>=_1n$8;return n}function pow2$2(e,t,r){let n=e;for(;t-- >_0n$9;)n*=n,n%=r;return n}function invert$2(e,t){if(e===_0n$9||t<=_0n$9)throw new Error(`invert: expected positive integers, got n=${e} mod=${t}`);let r=mod$2(e,t),n=t,i=_0n$9,o=_1n$8;for(;r!==_0n$9;){const e=n%r,t=i-o*(n/r);n=r,r=e,i=o,o=t}if(n!==_1n$8)throw new Error("invert: does not exist");return mod$2(i,t)}function tonelliShanks$1(e){const t=(e-_1n$8)/_2n$5;let r,n,i;for(r=e-_1n$8,n=0;r%_2n$5===_0n$9;r/=_2n$5,n++);for(i=_2n$5;i<e&&pow(i,t,e)!==e-_1n$8;i++);if(1===n){const t=(e+_1n$8)/_4n$2;return function(e,r){const n=e.pow(r,t);if(!e.eql(e.sqr(n),r))throw new Error("Cannot find square root");return n}}const o=(r+_1n$8)/_2n$5;return function(e,s){if(e.pow(s,t)===e.neg(e.ONE))throw new Error("Cannot find square root");let a=n,l=e.pow(e.mul(e.ONE,i),r),c=e.pow(s,o),u=e.pow(s,r);for(;!e.eql(u,e.ONE);){if(e.eql(u,e.ZERO))return e.ZERO;let t=1;for(let n=e.sqr(u);t<a&&!e.eql(n,e.ONE);t++)n=e.sqr(n);const r=e.pow(l,_1n$8<<BigInt(a-t-1));l=e.sqr(r),c=e.mul(c,r),u=e.mul(u,l),a=t}return c}}function FpSqrt$1(e){if(e%_4n$2===_3n$4){const t=(e+_1n$8)/_4n$2;return function(e,r){const n=e.pow(r,t);if(!e.eql(e.sqr(n),r))throw new Error("Cannot find square root");return n}}if(e%_8n$2===_5n$1){const t=(e-_5n$1)/_8n$2;return function(e,r){const n=e.mul(r,_2n$5),i=e.pow(n,t),o=e.mul(r,i),s=e.mul(e.mul(o,_2n$5),i),a=e.mul(o,e.sub(s,e.ONE));if(!e.eql(e.sqr(a),r))throw new Error("Cannot find square root");return a}}return tonelliShanks$1(e)}BigInt(9),BigInt(16);const FIELD_FIELDS$1=["create","isValid","is0","neg","inv","sqrt","sqr","eql","add","sub","mul","pow","div","addN","subN","mulN","sqrN"];function validateField$1(e){const t=FIELD_FIELDS$1.reduce((e,t)=>(e[t]="function",e),{ORDER:"bigint",MASK:"bigint",BYTES:"isSafeInteger",BITS:"isSafeInteger"});return validateObject$1(e,t)}function FpPow$1(e,t,r){if(r<_0n$9)throw new Error("Expected power > 0");if(r===_0n$9)return e.ONE;if(r===_1n$8)return t;let n=e.ONE,i=t;for(;r>_0n$9;)r&_1n$8&&(n=e.mul(n,i)),i=e.sqr(i),r>>=_1n$8;return n}function FpInvertBatch$1(e,t){const r=new Array(t.length),n=t.reduce((t,n,i)=>e.is0(n)?t:(r[i]=t,e.mul(t,n)),e.ONE),i=e.inv(n);return t.reduceRight((t,n,i)=>e.is0(n)?t:(r[i]=e.mul(t,r[i]),e.mul(t,n)),i),r}function nLength$1(e,t){const r=void 0!==t?t:e.toString(2).length;return{nBitLength:r,nByteLength:Math.ceil(r/8)}}function Field$1(e,t,r=!1,n={}){if(e<=_0n$9)throw new Error(`Expected Field ORDER > 0, got ${e}`);const{nBitLength:i,nByteLength:o}=nLength$1(e,t);if(o>2048)throw new Error("Field lengths over 2048 bytes are not supported");const s=FpSqrt$1(e),a=Object.freeze({ORDER:e,BITS:i,BYTES:o,MASK:bitMask$1(i),ZERO:_0n$9,ONE:_1n$8,create:t=>mod$2(t,e),isValid:t=>{if("bigint"!=typeof t)throw new Error("Invalid field element: expected bigint, got "+typeof t);return _0n$9<=t&&t<e},is0:e=>e===_0n$9,isOdd:e=>(e&_1n$8)===_1n$8,neg:t=>mod$2(-t,e),eql:(e,t)=>e===t,sqr:t=>mod$2(t*t,e),add:(t,r)=>mod$2(t+r,e),sub:(t,r)=>mod$2(t-r,e),mul:(t,r)=>mod$2(t*r,e),pow:(e,t)=>FpPow$1(a,e,t),div:(t,r)=>mod$2(t*invert$2(r,e),e),sqrN:e=>e*e,addN:(e,t)=>e+t,subN:(e,t)=>e-t,mulN:(e,t)=>e*t,inv:t=>invert$2(t,e),sqrt:n.sqrt||(e=>s(a,e)),invertBatch:e=>FpInvertBatch$1(a,e),cmov:(e,t,r)=>r?t:e,toBytes:e=>r?numberToBytesLE$1(e,o):numberToBytesBE$1(e,o),fromBytes:e=>{if(e.length!==o)throw new Error(`Fp.fromBytes: expected ${o}, got ${e.length}`);return r?bytesToNumberLE$1(e):bytesToNumberBE$1(e)}});return Object.freeze(a)}function getFieldBytesLength$1(e){if("bigint"!=typeof e)throw new Error("field order must be bigint");const t=e.toString(2).length;return Math.ceil(t/8)}function getMinHashLength$1(e){const t=getFieldBytesLength$1(e);return t+Math.ceil(t/2)}function mapHashToField$1(e,t,r=!1){const n=e.length,i=getFieldBytesLength$1(t),o=getMinHashLength$1(t);if(n<16||n<o||n>1024)throw new Error(`expected ${o}-1024 bytes of input, got ${n}`);const s=mod$2(r?bytesToNumberBE$1(e):bytesToNumberLE$1(e),t-_1n$8)+_1n$8;return r?numberToBytesLE$1(s,i):numberToBytesBE$1(s,i)} /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */function mod$2(e,t){const r=e%t;return r>=_0n$9?r:t+r}function pow(e,t,r){if(r<=_0n$9||t<_0n$9)throw new Error("Expected power/modulo > 0");if(r===_1n$8)return _0n$9;let n=_1n$8;for(;t>_0n$9;)t&_1n$8&&(n=n*e%r),e=e*e%r,t>>=_1n$8;return n}function pow2$2(e,t,r){let n=e;for(;t-- >_0n$9;)n*=n,n%=r;return n}function invert$2(e,t){if(e===_0n$9||t<=_0n$9)throw new Error(`invert: expected positive integers, got n=${e} mod=${t}`);let r=mod$2(e,t),n=t,i=_0n$9,o=_1n$8;for(;r!==_0n$9;){const e=n%r,t=i-o*(n/r);n=r,r=e,i=o,o=t}if(n!==_1n$8)throw new Error("invert: does not exist");return mod$2(i,t)}function tonelliShanks$1(e){const t=(e-_1n$8)/_2n$5;let r,n,i;for(r=e-_1n$8,n=0;r%_2n$5===_0n$9;r/=_2n$5,n++);for(i=_2n$5;i<e&&pow(i,t,e)!==e-_1n$8;i++);if(1===n){const t=(e+_1n$8)/_4n$2;return function(e,r){const n=e.pow(r,t);if(!e.eql(e.sqr(n),r))throw new Error("Cannot find square root");return n}}const o=(r+_1n$8)/_2n$5;return function(e,s){if(e.pow(s,t)===e.neg(e.ONE))throw new Error("Cannot find square root");let a=n,l=e.pow(e.mul(e.ONE,i),r),c=e.pow(s,o),u=e.pow(s,r);for(;!e.eql(u,e.ONE);){if(e.eql(u,e.ZERO))return e.ZERO;let t=1;for(let n=e.sqr(u);t<a&&!e.eql(n,e.ONE);t++)n=e.sqr(n);const r=e.pow(l,_1n$8<<BigInt(a-t-1));l=e.sqr(r),c=e.mul(c,r),u=e.mul(u,l),a=t}return c}}function FpSqrt$1(e){if(e%_4n$2===_3n$4){const t=(e+_1n$8)/_4n$2;return function(e,r){const n=e.pow(r,t);if(!e.eql(e.sqr(n),r))throw new Error("Cannot find square root");return n}}if(e%_8n$2===_5n$1){const t=(e-_5n$1)/_8n$2;return function(e,r){const n=e.mul(r,_2n$5),i=e.pow(n,t),o=e.mul(r,i),s=e.mul(e.mul(o,_2n$5),i),a=e.mul(o,e.sub(s,e.ONE));if(!e.eql(e.sqr(a),r))throw new Error("Cannot find square root");return a}}return tonelliShanks$1(e)}BigInt(9),BigInt(16);const FIELD_FIELDS$1=["create","isValid","is0","neg","inv","sqrt","sqr","eql","add","sub","mul","pow","div","addN","subN","mulN","sqrN"];function validateField$1(e){const t=FIELD_FIELDS$1.reduce((e,t)=>(e[t]="function",e),{ORDER:"bigint",MASK:"bigint",BYTES:"isSafeInteger",BITS:"isSafeInteger"});return validateObject$1(e,t)}function FpPow$1(e,t,r){if(r<_0n$9)throw new Error("Expected power > 0");if(r===_0n$9)return e.ONE;if(r===_1n$8)return t;let n=e.ONE,i=t;for(;r>_0n$9;)r&_1n$8&&(n=e.mul(n,i)),i=e.sqr(i),r>>=_1n$8;return n}function FpInvertBatch$1(e,t){const r=new Array(t.length),n=t.reduce((t,n,i)=>e.is0(n)?t:(r[i]=t,e.mul(t,n)),e.ONE),i=e.inv(n);return t.reduceRight((t,n,i)=>e.is0(n)?t:(r[i]=e.mul(t,r[i]),e.mul(t,n)),i),r}function nLength$1(e,t){const r=void 0!==t?t:e.toString(2).length;return{nBitLength:r,nByteLength:Math.ceil(r/8)}}function Field$1(e,t,r=!1,n={}){if(e<=_0n$9)throw new Error(`Expected Field ORDER > 0, got ${e}`);const{nBitLength:i,nByteLength:o}=nLength$1(e,t);if(o>2048)throw new Error("Field lengths over 2048 bytes are not supported");const s=FpSqrt$1(e),a=Object.freeze({ORDER:e,BITS:i,BYTES:o,MASK:bitMask$1(i),ZERO:_0n$9,ONE:_1n$8,create:t=>mod$2(t,e),isValid:t=>{if("bigint"!=typeof t)throw new Error("Invalid field element: expected bigint, got "+typeof t);return _0n$9<=t&&t<e},is0:e=>e===_0n$9,isOdd:e=>(e&_1n$8)===_1n$8,neg:t=>mod$2(-t,e),eql:(e,t)=>e===t,sqr:t=>mod$2(t*t,e),add:(t,r)=>mod$2(t+r,e),sub:(t,r)=>mod$2(t-r,e),mul:(t,r)=>mod$2(t*r,e),pow:(e,t)=>FpPow$1(a,e,t),div:(t,r)=>mod$2(t*invert$2(r,e),e),sqrN:e=>e*e,addN:(e,t)=>e+t,subN:(e,t)=>e-t,mulN:(e,t)=>e*t,inv:t=>invert$2(t,e),sqrt:n.sqrt||(e=>s(a,e)),invertBatch:e=>FpInvertBatch$1(a,e),cmov:(e,t,r)=>r?t:e,toBytes:e=>r?numberToBytesLE$1(e,o):numberToBytesBE$1(e,o),fromBytes:e=>{if(e.length!==o)throw new Error(`Fp.fromBytes: expected ${o}, got ${e.length}`);return r?bytesToNumberLE$1(e):bytesToNumberBE$1(e)}});return Object.freeze(a)}function getFieldBytesLength$1(e){if("bigint"!=typeof e)throw new Error("field order must be bigint");const t=e.toString(2).length;return Math.ceil(t/8)}function getMinHashLength$1(e){const t=getFieldBytesLength$1(e);return t+Math.ceil(t/2)}function mapHashToField$1(e,t,r=!1){const n=e.length,i=getFieldBytesLength$1(t),o=getMinHashLength$1(t);if(n<16||n<o||n>1024)throw new Error(`expected ${o}-1024 bytes of input, got ${n}`);const s=mod$2(r?bytesToNumberBE$1(e):bytesToNumberLE$1(e),t-_1n$8)+_1n$8;return r?numberToBytesLE$1(s,i):numberToBytesBE$1(s,i)}
@@ -9,9 +9,9 @@ function getHash(e){return{hash:e,hmac:(t,...r)=>hmac$2(e,t,concatBytes$3(...r))
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */hmac$2.create=(e,t)=>new HMAC$1(e,t);const secp256k1P=BigInt("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"),secp256k1N=BigInt("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"),_1n$5=BigInt(1),_2n$4=BigInt(2),divNearest$2=(e,t)=>(e+t/_2n$4)/t;function sqrtMod$2(e){const t=secp256k1P,r=BigInt(3),n=BigInt(6),i=BigInt(11),o=BigInt(22),s=BigInt(23),a=BigInt(44),l=BigInt(88),c=e*e*e%t,u=c*c*e%t,h=pow2$2(u,r,t)*u%t,d=pow2$2(h,r,t)*u%t,p=pow2$2(d,_2n$4,t)*c%t,f=pow2$2(p,i,t)*p%t,g=pow2$2(f,o,t)*f%t,m=pow2$2(g,a,t)*g%t,y=pow2$2(m,l,t)*m%t,b=pow2$2(y,a,t)*g%t,v=pow2$2(b,r,t)*u%t,_=pow2$2(v,s,t)*f%t,E=pow2$2(_,n,t)*c%t,w=pow2$2(E,_2n$4,t);if(!Fp.eql(Fp.sqr(w),e))throw new Error("Cannot find square root");return w}const Fp=Field$1(secp256k1P,void 0,void 0,{sqrt:sqrtMod$2}),secp256k1$1=createCurve({a:BigInt(0),b:BigInt(7),Fp:Fp,n:secp256k1N,Gx:BigInt("55066263022277343669578718895168534326250603453777594175500187360389116729240"),Gy:BigInt("32670510020758816978083085130507043184471273380659243275938904335757337482424"),h:BigInt(1),lowS:!0,endo:{beta:BigInt("0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee"),splitScalar:e=>{const t=secp256k1N,r=BigInt("0x3086d221a7d46bcde86c90e49284eb15"),n=-_1n$5*BigInt("0xe4437ed6010e88286f547fa90abfe4c3"),i=BigInt("0x114ca50f7a8e2f3f657c1108d9d44cfd8"),o=r,s=BigInt("0x100000000000000000000000000000000"),a=divNearest$2(o*e,t),l=divNearest$2(-n*e,t);let c=mod$2(e-a*r-l*i,t),u=mod$2(-a*n-l*o,t);const h=c>s,d=u>s;if(h&&(c=t-c),d&&(u=t-u),c>s||u>s)throw new Error("splitScalar: Endomorphism failed, k="+e);return{k1neg:h,k1:c,k2neg:d,k2:u}}}},sha256$3),_0n$6=BigInt(0),fe=e=>"bigint"==typeof e&&_0n$6<e&&e<secp256k1P,ge=e=>"bigint"==typeof e&&_0n$6<e&&e<secp256k1N,TAGGED_HASH_PREFIXES$1={};function taggedHash$1(e,...t){let r=TAGGED_HASH_PREFIXES$1[e];if(void 0===r){const t=sha256$3(Uint8Array.from(e,e=>e.charCodeAt(0)));r=concatBytes$2(t,t),TAGGED_HASH_PREFIXES$1[e]=r}return sha256$3(concatBytes$2(r,...t))}const pointToBytes$1=e=>e.toRawBytes(!0).slice(1),numTo32b=e=>numberToBytesBE$1(e,32),modP=e=>mod$2(e,secp256k1P),modN=e=>mod$2(e,secp256k1N),Point$2=secp256k1$1.ProjectivePoint,GmulAdd=(e,t,r)=>Point$2.BASE.multiplyAndAddUnsafe(e,t,r);function schnorrGetExtPubKey$1(e){let t=secp256k1$1.utils.normPrivateKeyToScalar(e),r=Point$2.fromPrivateKey(t);return{scalar:r.hasEvenY()?t:modN(-t),bytes:pointToBytes$1(r)}}function lift_x$1(e){if(!fe(e))throw new Error("bad x: need 0 < x < p");const t=modP(e*e);let r=sqrtMod$2(modP(t*e+BigInt(7)));r%_2n$4!==_0n$6&&(r=modP(-r));const n=new Point$2(e,r,_1n$5);return n.assertValidity(),n}function challenge$1(...e){return modN(bytesToNumberBE$1(taggedHash$1("BIP0340/challenge",...e)))}function schnorrGetPublicKey$1(e){return schnorrGetExtPubKey$1(e).bytes}function schnorrSign$1(e,t,r=randomBytes$2(32)){const n=ensureBytes$1("message",e),{bytes:i,scalar:o}=schnorrGetExtPubKey$1(t),s=ensureBytes$1("auxRand",r,32),a=numTo32b(o^bytesToNumberBE$1(taggedHash$1("BIP0340/aux",s))),l=taggedHash$1("BIP0340/nonce",a,i,n),c=modN(bytesToNumberBE$1(l));if(c===_0n$6)throw new Error("sign failed: k is zero");const{bytes:u,scalar:h}=schnorrGetExtPubKey$1(c),d=challenge$1(u,i,n),p=new Uint8Array(64);if(p.set(u,0),p.set(numTo32b(modN(h+d*o)),32),!schnorrVerify$1(p,n,i))throw new Error("sign: Invalid signature produced");return p}function schnorrVerify$1(e,t,r){const n=ensureBytes$1("signature",e,64),i=ensureBytes$1("message",t),o=ensureBytes$1("publicKey",r,32);try{const e=lift_x$1(bytesToNumberBE$1(o)),t=bytesToNumberBE$1(n.subarray(0,32));if(!fe(t))return!1;const r=bytesToNumberBE$1(n.subarray(32,64));if(!ge(r))return!1;const s=challenge$1(numTo32b(t),pointToBytes$1(e),i),a=GmulAdd(e,r,modN(-s));return!(!a||!a.hasEvenY()||a.toAffine().x!==t)}catch(error){return!1}}const schnorr$1=(()=>({getPublicKey:schnorrGetPublicKey$1,sign:schnorrSign$1,verify:schnorrVerify$1,utils:{randomPrivateKey:secp256k1$1.utils.randomPrivateKey,lift_x:lift_x$1,pointToBytes:pointToBytes$1,numberToBytesBE:numberToBytesBE$1,bytesToNumberBE:bytesToNumberBE$1,taggedHash:taggedHash$1,mod:mod$2}}))(),crypto$1="object"==typeof globalThis&&"crypto"in globalThis?globalThis.crypto:void 0,u8a=e=>e instanceof Uint8Array,createView$2=e=>new DataView(e.buffer,e.byteOffset,e.byteLength),rotr$2=(e,t)=>e<<32-t|e>>>t,isLE$2=68===new Uint8Array(new Uint32Array([287454020]).buffer)[0];if(!isLE$2)throw new Error("Non little-endian hardware is not supported");const hexes$3=Array.from({length:256},(e,t)=>t.toString(16).padStart(2,"0"));function bytesToHex$3(e){if(!u8a(e))throw new Error("Uint8Array expected");let t="";for(let r=0;r<e.length;r++)t+=hexes$3[e[r]];return t}function hexToBytes$3(e){if("string"!=typeof e)throw new Error("hex string expected, got "+typeof e);const t=e.length;if(t%2)throw new Error("padded hex string expected, got unpadded hex of length "+t);const r=new Uint8Array(t/2);Line truncated /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */hmac$2.create=(e,t)=>new HMAC$1(e,t);const secp256k1P=BigInt("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"),secp256k1N=BigInt("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"),_1n$5=BigInt(1),_2n$4=BigInt(2),divNearest$2=(e,t)=>(e+t/_2n$4)/t;function sqrtMod$2(e){const t=secp256k1P,r=BigInt(3),n=BigInt(6),i=BigInt(11),o=BigInt(22),s=BigInt(23),a=BigInt(44),l=BigInt(88),c=e*e*e%t,u=c*c*e%t,h=pow2$2(u,r,t)*u%t,d=pow2$2(h,r,t)*u%t,p=pow2$2(d,_2n$4,t)*c%t,f=pow2$2(p,i,t)*p%t,g=pow2$2(f,o,t)*f%t,m=pow2$2(g,a,t)*g%t,y=pow2$2(m,l,t)*m%t,b=pow2$2(y,a,t)*g%t,v=pow2$2(b,r,t)*u%t,_=pow2$2(v,s,t)*f%t,E=pow2$2(_,n,t)*c%t,w=pow2$2(E,_2n$4,t);if(!Fp.eql(Fp.sqr(w),e))throw new Error("Cannot find square root");return w}const Fp=Field$1(secp256k1P,void 0,void 0,{sqrt:sqrtMod$2}),secp256k1$1=createCurve({a:BigInt(0),b:BigInt(7),Fp:Fp,n:secp256k1N,Gx:BigInt("55066263022277343669578718895168534326250603453777594175500187360389116729240"),Gy:BigInt("32670510020758816978083085130507043184471273380659243275938904335757337482424"),h:BigInt(1),lowS:!0,endo:{beta:BigInt("0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee"),splitScalar:e=>{const t=secp256k1N,r=BigInt("0x3086d221a7d46bcde86c90e49284eb15"),n=-_1n$5*BigInt("0xe4437ed6010e88286f547fa90abfe4c3"),i=BigInt("0x114ca50f7a8e2f3f657c1108d9d44cfd8"),o=r,s=BigInt("0x100000000000000000000000000000000"),a=divNearest$2(o*e,t),l=divNearest$2(-n*e,t);let c=mod$2(e-a*r-l*i,t),u=mod$2(-a*n-l*o,t);const h=c>s,d=u>s;if(h&&(c=t-c),d&&(u=t-u),c>s||u>s)throw new Error("splitScalar: Endomorphism failed, k="+e);return{k1neg:h,k1:c,k2neg:d,k2:u}}}},sha256$3),_0n$6=BigInt(0),fe=e=>"bigint"==typeof e&&_0n$6<e&&e<secp256k1P,ge=e=>"bigint"==typeof e&&_0n$6<e&&e<secp256k1N,TAGGED_HASH_PREFIXES$1={};function taggedHash$1(e,...t){let r=TAGGED_HASH_PREFIXES$1[e];if(void 0===r){const t=sha256$3(Uint8Array.from(e,e=>e.charCodeAt(0)));r=concatBytes$2(t,t),TAGGED_HASH_PREFIXES$1[e]=r}return sha256$3(concatBytes$2(r,...t))}const pointToBytes$1=e=>e.toRawBytes(!0).slice(1),numTo32b=e=>numberToBytesBE$1(e,32),modP=e=>mod$2(e,secp256k1P),modN=e=>mod$2(e,secp256k1N),Point$2=secp256k1$1.ProjectivePoint,GmulAdd=(e,t,r)=>Point$2.BASE.multiplyAndAddUnsafe(e,t,r);function schnorrGetExtPubKey$1(e){let t=secp256k1$1.utils.normPrivateKeyToScalar(e),r=Point$2.fromPrivateKey(t);return{scalar:r.hasEvenY()?t:modN(-t),bytes:pointToBytes$1(r)}}function lift_x$1(e){if(!fe(e))throw new Error("bad x: need 0 < x < p");const t=modP(e*e);let r=sqrtMod$2(modP(t*e+BigInt(7)));r%_2n$4!==_0n$6&&(r=modP(-r));const n=new Point$2(e,r,_1n$5);return n.assertValidity(),n}function challenge$1(...e){return modN(bytesToNumberBE$1(taggedHash$1("BIP0340/challenge",...e)))}function schnorrGetPublicKey$1(e){return schnorrGetExtPubKey$1(e).bytes}function schnorrSign$1(e,t,r=randomBytes$2(32)){const n=ensureBytes$1("message",e),{bytes:i,scalar:o}=schnorrGetExtPubKey$1(t),s=ensureBytes$1("auxRand",r,32),a=numTo32b(o^bytesToNumberBE$1(taggedHash$1("BIP0340/aux",s))),l=taggedHash$1("BIP0340/nonce",a,i,n),c=modN(bytesToNumberBE$1(l));if(c===_0n$6)throw new Error("sign failed: k is zero");const{bytes:u,scalar:h}=schnorrGetExtPubKey$1(c),d=challenge$1(u,i,n),p=new Uint8Array(64);if(p.set(u,0),p.set(numTo32b(modN(h+d*o)),32),!schnorrVerify$1(p,n,i))throw new Error("sign: Invalid signature produced");return p}function schnorrVerify$1(e,t,r){const n=ensureBytes$1("signature",e,64),i=ensureBytes$1("message",t),o=ensureBytes$1("publicKey",r,32);try{const e=lift_x$1(bytesToNumberBE$1(o)),t=bytesToNumberBE$1(n.subarray(0,32));if(!fe(t))return!1;const r=bytesToNumberBE$1(n.subarray(32,64));if(!ge(r))return!1;const s=challenge$1(numTo32b(t),pointToBytes$1(e),i),a=GmulAdd(e,r,modN(-s));return!(!a||!a.hasEvenY()||a.toAffine().x!==t)}catch(error){return!1}}const schnorr$1=(()=>({getPublicKey:schnorrGetPublicKey$1,sign:schnorrSign$1,verify:schnorrVerify$1,utils:{randomPrivateKey:secp256k1$1.utils.randomPrivateKey,lift_x:lift_x$1,pointToBytes:pointToBytes$1,numberToBytesBE:numberToBytesBE$1,bytesToNumberBE:bytesToNumberBE$1,taggedHash:taggedHash$1,mod:mod$2}}))(),crypto$1="object"==typeof globalThis&&"crypto"in globalThis?globalThis.crypto:void 0,u8a=e=>e instanceof Uint8Array,createView$2=e=>new DataView(e.buffer,e.byteOffset,e.byteLength),rotr$2=(e,t)=>e<<32-t|e>>>t,isLE$2=68===new Uint8Array(new Uint32Array([287454020]).buffer)[0];if(!isLE$2)throw new Error("Non little-endian hardware is not supported");const hexes$3=Array.from({length:256},(e,t)=>t.toString(16).padStart(2,"0"));function bytesToHex$3(e){if(!u8a(e))throw new Error("Uint8Array expected");let t="";for(let r=0;r<e.length;r++)t+=hexes$3[e[r]];return t}function hexToBytes$3(e){if("string"!=typeof e)throw new Error("hex string expected, got "+typeof e);const t=e.length;if(t%2)throw new Error("padded hex string expected, got unpadded hex of length "+t);const r=new Uint8Array(t/2);Line truncated
/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */ /*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */
function assertNumber(e){if(!Number.isSafeInteger(e))throw new Error(`Wrong integer: ${e}`)}function chain$1(...e){const t=(e,t)=>r=>e(t(r)),r=Array.from(e).reverse().reduce((e,r)=>e?t(e,r.encode):r.encode,void 0),n=e.reduce((e,r)=>e?t(e,r.decode):r.decode,void 0);return{encode:r,decode:n}}function alphabet$1(e){return{encode:t=>{if(!Array.isArray(t)||t.length&&"number"!=typeof t[0])throw new Error("alphabet.encode input should be an array of numbers");return t.map(t=>{if(assertNumber(t),t<0||t>=e.length)throw new Error(`Digit index outside alphabet: ${t} (alphabet: ${e.length})`);return e[t]})},decode:t=>{if(!Array.isArray(t)||t.length&&"string"!=typeof t[0])throw new Error("alphabet.decode input should be array of strings");return t.map(t=>{if("string"!=typeof t)throw new Error(`alphabet.decode: not string element=${t}`);const r=e.indexOf(t);if(-1===r)throw new Error(`Unknown letter: "${t}". Allowed: ${e}`);return r})}}}function join$1(e=""){if("string"!=typeof e)throw new Error("join separator should be string");return{encode:t=>{if(!Array.isArray(t)||t.length&&"string"!=typeof t[0])throw new Error("join.encode input should be array of strings");for(let e of t)if("string"!=typeof e)throw new Error(`join.encode: non-string input=${e}`);return t.join(e)},decode:t=>{if("string"!=typeof t)throw new Error("join.decode input should be string");return t.split(e)}}}function padding$1(e,t="="){if(assertNumber(e),"string"!=typeof t)throw new Error("padding chr should be string");return{encode(r){if(!Array.isArray(r)||r.length&&"string"!=typeof r[0])throw new Error("padding.encode input should be array of strings");for(let e of r)if("string"!=typeof e)throw new Error(`padding.encode: non-string input=${e}`);for(;r.length*e%8;)r.push(t);return r},decode(r){if(!Array.isArray(r)||r.length&&"string"!=typeof r[0])throw new Error("padding.encode input should be array of strings");for(let e of r)if("string"!=typeof e)throw new Error(`padding.decode: non-string input=${e}`);let n=r.length;if(n*e%8)throw new Error("Invalid padding: string should have whole number of bytes");for(;n>0&&r[n-1]===t;n--)if(!((n-1)*e%8))throw new Error("Invalid padding: string has too much padding");return r.slice(0,n)}}}function normalize(e){if("function"!=typeof e)throw new Error("normalize fn should be function");return{encode:e=>e,decode:t=>e(t)}}function convertRadix(e,t,r){if(t<2)throw new Error(`convertRadix: wrong from=${t}, base cannot be less than 2`);if(r<2)throw new Error(`convertRadix: wrong to=${r}, base cannot be less than 2`);if(!Array.isArray(e))throw new Error("convertRadix: data should be array");if(!e.length)return[];let n=0;const i=[],o=Array.from(e);for(o.forEach(e=>{if(assertNumber(e),e<0||e>=t)throw new Error(`Wrong integer: ${e}`)});;){let e=0,s=!0;for(let i=n;i<o.length;i++){const a=o[i],l=t*e+a;if(!Number.isSafeInteger(l)||t*e/t!==e||l-a!==t*e)throw new Error("convertRadix: carry overflow");if(e=l%r,o[i]=Math.floor(l/r),!Number.isSafeInteger(o[i])||o[i]*r+e!==l)throw new Error("convertRadix: carry overflow");s&&(o[i]?s=!1:n=i)}if(i.push(e),s)break}for(let s=0;s<e.length-1&&0===e[s];s++)i.push(0);return i.reverse()}wrapConstructor(()=>new SHA224);const gcd$1=(e,t)=>t?gcd$1(t,e%t):e,radix2carry$1=(e,t)=>e+(t-gcd$1(e,t));function convertRadix2$1(e,t,r,n){if(!Array.isArray(e))throw new Error("convertRadix2: data should be array");if(t<=0||t>32)throw new Error(`convertRadix2: wrong from=${t}`);if(r<=0||r>32)throw new Error(`convertRadix2: wrong to=${r}`);if(radix2carry$1(t,r)>32)throw new Error(`convertRadix2: carry overflow from=${t} to=${r} carryBits=${radix2carry$1(t,r)}`);let i=0,o=0;const s=2**r-1,a=[];for(const l of e){if(assertNumber(l),l>=2**t)throw new Error(`convertRadix2: invalid data word=${l} from=${t}`);if(i=i<<t|l,o+t>32)throw new Error(`convertRadix2: carry overflow pos=${o} from=${t}`);for(o+=t;o>=r;o-=r)a.push((i>>o-r&s)>>>0);i&=2**o-1}if(i=i<<r-o&s,!n&&o>=t)throw new Error("Excess padding");if(!n&&i)throw new Error(`Non-zero padding: ${i}`);return n&&o>0&&a.push(i>>>0),a}function radix(e){return assertNumber(e),{encode:t=>{if(!(t instanceof Uint8Array))throw new Error("radix.encode input should be Uint8Array");return convertRadix(Array.from(t),256,e)},decode:t=>{if(!Array.isArray(t)||t.length&&"number"!=typeof t[0])throw new Error("radix.decode input should be array of strings");return Uint8Array.from(convertRadix(t,e,256))}}}function radix2$1(e,t=!1){if(assertNumber(e),e<=0||e>32)throw new Error("radix2: bits should be in (0..32]");if(radix2carry$1(8,e)>32||radix2carry$1(e,8)>32)throw new Error("radix2: carry overflow");return{encode:r=>{if(!(r instanceof Uint8Array))throw new Error("radix2.encode input should be Uint8Array");return convertRadix2$1(Array.from(r),8,e,!t)},decode:r=>{if(!Array.isArray(r)||r.length&&"number"!=typeof r[0])throw new Error("radix2.decode input should be array of strings");return Uint8Array.from(convertRadix2$1(r,e,8,t))}}}function unsafeWrapper$1(e){if("function"!=typeof e)thrLine truncated function assertNumber(e){if(!Number.isSafeInteger(e))throw new Error(`Wrong integer: ${e}`)}function chain$1(...e){const t=(e,t)=>r=>e(t(r)),r=Array.from(e).reverse().reduce((e,r)=>e?t(e,r.encode):r.encode,void 0),n=e.reduce((e,r)=>e?t(e,r.decode):r.decode,void 0);return{encode:r,decode:n}}function alphabet$1(e){return{encode:t=>{if(!Array.isArray(t)||t.length&&"number"!=typeof t[0])throw new Error("alphabet.encode input should be an array of numbers");return t.map(t=>{if(assertNumber(t),t<0||t>=e.length)throw new Error(`Digit index outside alphabet: ${t} (alphabet: ${e.length})`);return e[t]})},decode:t=>{if(!Array.isArray(t)||t.length&&"string"!=typeof t[0])throw new Error("alphabet.decode input should be array of strings");return t.map(t=>{if("string"!=typeof t)throw new Error(`alphabet.decode: not string element=${t}`);const r=e.indexOf(t);if(-1===r)throw new Error(`Unknown letter: "${t}". Allowed: ${e}`);return r})}}}function join$1(e=""){if("string"!=typeof e)throw new Error("join separator should be string");return{encode:t=>{if(!Array.isArray(t)||t.length&&"string"!=typeof t[0])throw new Error("join.encode input should be array of strings");for(let e of t)if("string"!=typeof e)throw new Error(`join.encode: non-string input=${e}`);return t.join(e)},decode:t=>{if("string"!=typeof t)throw new Error("join.decode input should be string");return t.split(e)}}}function padding$1(e,t="="){if(assertNumber(e),"string"!=typeof t)throw new Error("padding chr should be string");return{encode(r){if(!Array.isArray(r)||r.length&&"string"!=typeof r[0])throw new Error("padding.encode input should be array of strings");for(let e of r)if("string"!=typeof e)throw new Error(`padding.encode: non-string input=${e}`);for(;r.length*e%8;)r.push(t);return r},decode(r){if(!Array.isArray(r)||r.length&&"string"!=typeof r[0])throw new Error("padding.encode input should be array of strings");for(let e of r)if("string"!=typeof e)throw new Error(`padding.decode: non-string input=${e}`);let n=r.length;if(n*e%8)throw new Error("Invalid padding: string should have whole number of bytes");for(;n>0&&r[n-1]===t;n--)if(!((n-1)*e%8))throw new Error("Invalid padding: string has too much padding");return r.slice(0,n)}}}function normalize(e){if("function"!=typeof e)throw new Error("normalize fn should be function");return{encode:e=>e,decode:t=>e(t)}}function convertRadix(e,t,r){if(t<2)throw new Error(`convertRadix: wrong from=${t}, base cannot be less than 2`);if(r<2)throw new Error(`convertRadix: wrong to=${r}, base cannot be less than 2`);if(!Array.isArray(e))throw new Error("convertRadix: data should be array");if(!e.length)return[];let n=0;const i=[],o=Array.from(e);for(o.forEach(e=>{if(assertNumber(e),e<0||e>=t)throw new Error(`Wrong integer: ${e}`)});;){let e=0,s=!0;for(let i=n;i<o.length;i++){const a=o[i],l=t*e+a;if(!Number.isSafeInteger(l)||t*e/t!==e||l-a!==t*e)throw new Error("convertRadix: carry overflow");if(e=l%r,o[i]=Math.floor(l/r),!Number.isSafeInteger(o[i])||o[i]*r+e!==l)throw new Error("convertRadix: carry overflow");s&&(o[i]?s=!1:n=i)}if(i.push(e),s)break}for(let s=0;s<e.length-1&&0===e[s];s++)i.push(0);return i.reverse()}wrapConstructor(()=>new SHA224);const gcd$1=(e,t)=>t?gcd$1(t,e%t):e,radix2carry$1=(e,t)=>e+(t-gcd$1(e,t));function convertRadix2$1(e,t,r,n){if(!Array.isArray(e))throw new Error("convertRadix2: data should be array");if(t<=0||t>32)throw new Error(`convertRadix2: wrong from=${t}`);if(r<=0||r>32)throw new Error(`convertRadix2: wrong to=${r}`);if(radix2carry$1(t,r)>32)throw new Error(`convertRadix2: carry overflow from=${t} to=${r} carryBits=${radix2carry$1(t,r)}`);let i=0,o=0;const s=2**r-1,a=[];for(const l of e){if(assertNumber(l),l>=2**t)throw new Error(`convertRadix2: invalid data word=${l} from=${t}`);if(i=i<<t|l,o+t>32)throw new Error(`convertRadix2: carry overflow pos=${o} from=${t}`);for(o+=t;o>=r;o-=r)a.push((i>>o-r&s)>>>0);i&=2**o-1}if(i=i<<r-o&s,!n&&o>=t)throw new Error("Excess padding");if(!n&&i)throw new Error(`Non-zero padding: ${i}`);return n&&o>0&&a.push(i>>>0),a}function radix(e){return assertNumber(e),{encode:t=>{if(!(t instanceof Uint8Array))throw new Error("radix.encode input should be Uint8Array");return convertRadix(Array.from(t),256,e)},decode:t=>{if(!Array.isArray(t)||t.length&&"number"!=typeof t[0])throw new Error("radix.decode input should be array of strings");return Uint8Array.from(convertRadix(t,e,256))}}}function radix2$1(e,t=!1){if(assertNumber(e),e<=0||e>32)throw new Error("radix2: bits should be in (0..32]");if(radix2carry$1(8,e)>32||radix2carry$1(e,8)>32)throw new Error("radix2: carry overflow");return{encode:r=>{if(!(r instanceof Uint8Array))throw new Error("radix2.encode input should be Uint8Array");return convertRadix2$1(Array.from(r),8,e,!t)},decode:r=>{if(!Array.isArray(r)||r.length&&"number"!=typeof r[0])throw new Error("radix2.decode input should be array of strings");return Uint8Array.from(convertRadix2$1(r,e,8,t))}}}function unsafeWrapper$1(e){if("function"!=typeof e)thrLine truncated
/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */Object.keys(CODERS).join(", ");const u32$1=e=>new Uint32Array(e.buffer,e.byteOffset,Math.floor(e.byteLength/4)),isLE$1=68===new Uint8Array(new Uint32Array([287454020]).buffer)[0];if(!isLE$1)throw new Error("Non little-endian hardware is not supported");const hexes$2=Array.from({length:256},(e,t)=>t.toString(16).padStart(2,"0"));function bytesToHex$2(e){bytes(e);let t="";for(let r=0;r<e.length;r++)t+=hexes$2[e[r]];return t}const asciis$2={_0:48,_9:57,_A:65,_F:70,_a:97,_f:102};function asciiToBase16$2(e){return e>=asciis$2._0&&e<=asciis$2._9?e-asciis$2._0:e>=asciis$2._A&&e<=asciis$2._F?e-(asciis$2._A-10):e>=asciis$2._a&&e<=asciis$2._f?e-(asciis$2._a-10):void 0}function hexToBytes$2(e){if("string"!=typeof e)throw new Error("hex string expected, got "+typeof e);const t=e.length,r=t/2;if(t%2)throw new Error("padded hex string expected, got unpadded hex of length "+t);const n=new Uint8Array(r);for(let i=0,o=0;i<r;i++,o+=2){const t=asciiToBase16$2(e.charCodeAt(o)),r=asciiToBase16$2(e.charCodeAt(o+1));if(void 0===t||void 0===r){const t=e[o]+e[o+1];throw new Error('hex string expected, got non-hex character "'+t+'" at index '+o)}n[i]=16*t+r}return n}function checkOpts$1(e,t){if(null==t||"object"!=typeof t)throw new Error("options must be defined");return Object.assign(e,t)}function equalBytes$1(e,t){if(e.length!==t.length)return!1;let r=0;for(let n=0;n<e.length;n++)r|=e[n]^t[n];return 0===r}const wrapCipher$1=(e,t)=>(Object.assign(t,e),t),BLOCK_SIZE$1=16,POLY$1=283;function mul2$1(e){return e<<1^POLY$1&-(e>>7)}function mul$1(e,t){let r=0;for(;t>0;t>>=1)r^=e&-(1&t),e=mul2$1(e);return r}const sbox$1=(()=>{let e=new Uint8Array(256);for(let r=0,n=1;r<256;r++,n^=mul2$1(n))e[r]=n;const t=new Uint8Array(256);t[0]=99;for(let r=0;r<255;r++){let n=e[255-r];n|=n<<8,t[e[r]]=255&(n^n>>4^n>>5^n>>6^n>>7^99)}return t})(),invSbox$1=sbox$1.map((e,t)=>sbox$1.indexOf(t)),rotr32_8$1=e=>e<<24|e>>>8,rotl32_8$1=e=>e<<8|e>>>24;function genTtable$1(e,t){if(256!==e.length)throw new Error("Wrong sbox length");const r=new Uint32Array(256).map((r,n)=>t(e[n])),n=r.map(rotl32_8$1),i=n.map(rotl32_8$1),o=i.map(rotl32_8$1),s=new Uint32Array(65536),a=new Uint32Array(65536),l=new Uint16Array(65536);for(let c=0;c<256;c++)for(let t=0;t<256;t++){const u=256*c+t;s[u]=r[c]^n[t],a[u]=i[c]^o[t],l[u]=e[c]<<8|e[t]}return{sbox:e,sbox2:l,T0:r,T1:n,T2:i,T3:o,T01:s,T23:a}}const tableEncoding$1=genTtable$1(sbox$1,e=>mul$1(e,3)<<24|e<<16|e<<8|mul$1(e,2)),tableDecoding$1=genTtable$1(invSbox$1,e=>mul$1(e,11)<<24|mul$1(e,13)<<16|mul$1(e,9)<<8|mul$1(e,14)),xPowers$1=(()=>{const e=new Uint8Array(16);for(let t=0,r=1;t<16;t++,r=mul2$1(r))e[t]=r;return e})();function expandKeyLE$1(e){bytes(e);const t=e.length;if(![16,24,32].includes(t))throw new Error(`aes: wrong key size: should be 16, 24 or 32, got: ${t}`);const{sbox2:r}=tableEncoding$1,n=u32$1(e),i=n.length,o=e=>applySbox$1(r,e,e,e,e),s=new Uint32Array(t+28);s.set(n);for(let a=i;a<s.length;a++){let e=s[a-1];a%i===0?e=o(rotr32_8$1(e))^xPowers$1[a/i-1]:i>6&&a%i===4&&(e=o(e)),s[a]=s[a-i]^e}return s}function expandKeyDecLE$1(e){const t=expandKeyLE$1(e),r=t.slice(),n=t.length,{sbox2:i}=tableEncoding$1,{T0:o,T1:s,T2:a,T3:l}=tableDecoding$1;for(let c=0;c<n;c+=4)for(let e=0;e<4;e++)r[c+e]=t[n-c-4+e];t.fill(0);for(let c=4;c<n-4;c++){const e=r[c],t=applySbox$1(i,e,e,e,e);r[c]=o[255&t]^s[t>>>8&255]^a[t>>>16&255]^l[t>>>24]}return r}function apply0123$1(e,t,r,n,i,o){return e[r<<8&65280|n>>>8&255]^t[i>>>8&65280|o>>>24&255]}function applySbox$1(e,t,r,n,i){return e[255&t|65280&r]|e[n>>>16&255|i>>>16&65280]<<16}function encrypt$4(e,t,r,n,i){const{sbox2:o,T01:s,T23:a}=tableEncoding$1;let l=0;t^=e[l++],r^=e[l++],n^=e[l++],i^=e[l++];const c=e.length/4-2;for(let u=0;u<c;u++){const o=e[l++]^apply0123$1(s,a,t,r,n,i),c=e[l++]^apply0123$1(s,a,r,n,i,t),u=e[l++]^apply0123$1(s,a,n,i,t,r),h=e[l++]^apply0123$1(s,a,i,t,r,n);t=o,r=c,n=u,i=h}return{s0:e[l++]^applySbox$1(o,t,r,n,i),s1:e[l++]^applySbox$1(o,r,n,i,t),s2:e[l++]^applySbox$1(o,n,i,t,r),s3:e[l++]^applySbox$1(o,i,t,r,n)}}function decrypt$4(e,t,r,n,i){const{sbox2:o,T01:s,T23:a}=tableDecoding$1;let l=0;t^=e[l++],r^=e[l++],n^=e[l++],i^=e[l++];const c=e.length/4-2;for(let u=0;u<c;u++){const o=e[l++]^apply0123$1(s,a,t,i,n,r),c=e[l++]^apply0123$1(s,a,r,t,i,n),u=e[l++]^apply0123$1(s,a,n,r,t,i),h=e[l++]^apply0123$1(s,a,i,n,r,t);t=o,r=c,n=u,i=h}return{s0:e[l++]^applySbox$1(o,t,i,n,r),s1:e[l++]^applySbox$1(o,r,t,i,n),s2:e[l++]^applySbox$1(o,n,r,t,i),s3:e[l++]^applySbox$1(o,i,n,r,t)}}function getDst(e,t){if(!t)return new Uint8Array(e);if(bytes(t),t.length<e)throw new Error(`aes: wrong destination length, expected at least ${e}, got: ${t.length}`);return t}function validateBlockDecrypt$1(e){if(bytes(e),e.length%BLOCK_SIZE$1!==0)throw new Error(`aes/(cbc-ecb).decrypt ciphertext should consist of blocks with size ${BLOCK_SIZE$1}`)}function validateBlockEncrypt$1(e,t,r){let n=e.length;const i=n%BLOCK_SIZE$1;if(!t&&0!==i)throw new Error("aecLine truncated /*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */Object.keys(CODERS).join(", ");const u32$1=e=>new Uint32Array(e.buffer,e.byteOffset,Math.floor(e.byteLength/4)),isLE$1=68===new Uint8Array(new Uint32Array([287454020]).buffer)[0];if(!isLE$1)throw new Error("Non little-endian hardware is not supported");const hexes$2=Array.from({length:256},(e,t)=>t.toString(16).padStart(2,"0"));function bytesToHex$2(e){bytes(e);let t="";for(let r=0;r<e.length;r++)t+=hexes$2[e[r]];return t}const asciis$2={_0:48,_9:57,_A:65,_F:70,_a:97,_f:102};function asciiToBase16$2(e){return e>=asciis$2._0&&e<=asciis$2._9?e-asciis$2._0:e>=asciis$2._A&&e<=asciis$2._F?e-(asciis$2._A-10):e>=asciis$2._a&&e<=asciis$2._f?e-(asciis$2._a-10):void 0}function hexToBytes$2(e){if("string"!=typeof e)throw new Error("hex string expected, got "+typeof e);const t=e.length,r=t/2;if(t%2)throw new Error("padded hex string expected, got unpadded hex of length "+t);const n=new Uint8Array(r);for(let i=0,o=0;i<r;i++,o+=2){const t=asciiToBase16$2(e.charCodeAt(o)),r=asciiToBase16$2(e.charCodeAt(o+1));if(void 0===t||void 0===r){const t=e[o]+e[o+1];throw new Error('hex string expected, got non-hex character "'+t+'" at index '+o)}n[i]=16*t+r}return n}function checkOpts$1(e,t){if(null==t||"object"!=typeof t)throw new Error("options must be defined");return Object.assign(e,t)}function equalBytes$1(e,t){if(e.length!==t.length)return!1;let r=0;for(let n=0;n<e.length;n++)r|=e[n]^t[n];return 0===r}const wrapCipher$1=(e,t)=>(Object.assign(t,e),t),BLOCK_SIZE$1=16,POLY$1=283;function mul2$1(e){return e<<1^POLY$1&-(e>>7)}function mul$1(e,t){let r=0;for(;t>0;t>>=1)r^=e&-(1&t),e=mul2$1(e);return r}const sbox$1=(()=>{let e=new Uint8Array(256);for(let r=0,n=1;r<256;r++,n^=mul2$1(n))e[r]=n;const t=new Uint8Array(256);t[0]=99;for(let r=0;r<255;r++){let n=e[255-r];n|=n<<8,t[e[r]]=255&(n^n>>4^n>>5^n>>6^n>>7^99)}return t})(),invSbox$1=sbox$1.map((e,t)=>sbox$1.indexOf(t)),rotr32_8$1=e=>e<<24|e>>>8,rotl32_8$1=e=>e<<8|e>>>24;function genTtable$1(e,t){if(256!==e.length)throw new Error("Wrong sbox length");const r=new Uint32Array(256).map((r,n)=>t(e[n])),n=r.map(rotl32_8$1),i=n.map(rotl32_8$1),o=i.map(rotl32_8$1),s=new Uint32Array(65536),a=new Uint32Array(65536),l=new Uint16Array(65536);for(let c=0;c<256;c++)for(let t=0;t<256;t++){const u=256*c+t;s[u]=r[c]^n[t],a[u]=i[c]^o[t],l[u]=e[c]<<8|e[t]}return{sbox:e,sbox2:l,T0:r,T1:n,T2:i,T3:o,T01:s,T23:a}}const tableEncoding$1=genTtable$1(sbox$1,e=>mul$1(e,3)<<24|e<<16|e<<8|mul$1(e,2)),tableDecoding$1=genTtable$1(invSbox$1,e=>mul$1(e,11)<<24|mul$1(e,13)<<16|mul$1(e,9)<<8|mul$1(e,14)),xPowers$1=(()=>{const e=new Uint8Array(16);for(let t=0,r=1;t<16;t++,r=mul2$1(r))e[t]=r;return e})();function expandKeyLE$1(e){bytes(e);const t=e.length;if(![16,24,32].includes(t))throw new Error(`aes: wrong key size: should be 16, 24 or 32, got: ${t}`);const{sbox2:r}=tableEncoding$1,n=u32$1(e),i=n.length,o=e=>applySbox$1(r,e,e,e,e),s=new Uint32Array(t+28);s.set(n);for(let a=i;a<s.length;a++){let e=s[a-1];a%i===0?e=o(rotr32_8$1(e))^xPowers$1[a/i-1]:i>6&&a%i===4&&(e=o(e)),s[a]=s[a-i]^e}return s}function expandKeyDecLE$1(e){const t=expandKeyLE$1(e),r=t.slice(),n=t.length,{sbox2:i}=tableEncoding$1,{T0:o,T1:s,T2:a,T3:l}=tableDecoding$1;for(let c=0;c<n;c+=4)for(let e=0;e<4;e++)r[c+e]=t[n-c-4+e];t.fill(0);for(let c=4;c<n-4;c++){const e=r[c],t=applySbox$1(i,e,e,e,e);r[c]=o[255&t]^s[t>>>8&255]^a[t>>>16&255]^l[t>>>24]}return r}function apply0123$1(e,t,r,n,i,o){return e[r<<8&65280|n>>>8&255]^t[i>>>8&65280|o>>>24&255]}function applySbox$1(e,t,r,n,i){return e[255&t|65280&r]|e[n>>>16&255|i>>>16&65280]<<16}function encrypt$4(e,t,r,n,i){const{sbox2:o,T01:s,T23:a}=tableEncoding$1;let l=0;t^=e[l++],r^=e[l++],n^=e[l++],i^=e[l++];const c=e.length/4-2;for(let u=0;u<c;u++){const o=e[l++]^apply0123$1(s,a,t,r,n,i),c=e[l++]^apply0123$1(s,a,r,n,i,t),u=e[l++]^apply0123$1(s,a,n,i,t,r),h=e[l++]^apply0123$1(s,a,i,t,r,n);t=o,r=c,n=u,i=h}return{s0:e[l++]^applySbox$1(o,t,r,n,i),s1:e[l++]^applySbox$1(o,r,n,i,t),s2:e[l++]^applySbox$1(o,n,i,t,r),s3:e[l++]^applySbox$1(o,i,t,r,n)}}function decrypt$4(e,t,r,n,i){const{sbox2:o,T01:s,T23:a}=tableDecoding$1;let l=0;t^=e[l++],r^=e[l++],n^=e[l++],i^=e[l++];const c=e.length/4-2;for(let u=0;u<c;u++){const o=e[l++]^apply0123$1(s,a,t,i,n,r),c=e[l++]^apply0123$1(s,a,r,t,i,n),u=e[l++]^apply0123$1(s,a,n,r,t,i),h=e[l++]^apply0123$1(s,a,i,n,r,t);t=o,r=c,n=u,i=h}return{s0:e[l++]^applySbox$1(o,t,i,n,r),s1:e[l++]^applySbox$1(o,r,t,i,n),s2:e[l++]^applySbox$1(o,n,r,t,i),s3:e[l++]^applySbox$1(o,i,n,r,t)}}function getDst(e,t){if(!t)return new Uint8Array(e);if(bytes(t),t.length<e)throw new Error(`aes: wrong destination length, expected at least ${e}, got: ${t.length}`);return t}function validateBlockDecrypt$1(e){if(bytes(e),e.length%BLOCK_SIZE$1!==0)throw new Error(`aes/(cbc-ecb).decrypt ciphertext should consist of blocks with size ${BLOCK_SIZE$1}`)}function validateBlockEncrypt$1(e,t,r){let n=e.length;const i=n%BLOCK_SIZE$1;if(!t&&0!==i)throw new Error("aecLine truncated
/*! noble-secp256k1 - MIT License (c) 2019 Paul Miller (paulmillr.com) */const _0n$5=BigInt(0),_1n$4=BigInt(1),_2n$3=BigInt(2),_3n$2=BigInt(3),_8n$1=BigInt(8),CURVE=Object.freeze({a:_0n$5,b:BigInt(7),P:BigInt("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"),n:BigInt("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"),h:_1n$4,Gx:BigInt("55066263022277343669578718895168534326250603453777594175500187360389116729240"),Gy:BigInt("32670510020758816978083085130507043184471273380659243275938904335757337482424"),beta:BigInt("0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee")}),divNearest$1=(e,t)=>(e+t/_2n$3)/t,endo={beta:BigInt("0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee"),splitScalar(e){const{n:t}=CURVE,r=BigInt("0x3086d221a7d46bcde86c90e49284eb15"),n=-_1n$4*BigInt("0xe4437ed6010e88286f547fa90abfe4c3"),i=BigInt("0x114ca50f7a8e2f3f657c1108d9d44cfd8"),o=r,s=BigInt("0x100000000000000000000000000000000"),a=divNearest$1(o*e,t),l=divNearest$1(-n*e,t);let c=mod$1(e-a*r-l*i,t),u=mod$1(-a*n-l*o,t);const h=c>s,d=u>s;if(h&&(c=t-c),d&&(u=t-u),c>s||u>s)throw new Error("splitScalarEndo: Endomorphism failed, k="+e);return{k1neg:h,k1:c,k2neg:d,k2:u}}},fieldLen=32,groupLen=32,compressedLen=fieldLen+1,uncompressedLen=2*fieldLen+1;function weierstrass$1(e){const{a:t,b:r}=CURVE,n=mod$1(e*e),i=mod$1(n*e);return mod$1(i+t*e+r)}const USE_ENDOMORPHISM=CURVE.a===_0n$5;function assertJacPoint(e){if(!(e instanceof JacobianPoint))throw new TypeError("JacobianPoint expected")}class JacobianPoint{constructor(e,t,r){this.x=e,this.y=t,this.z=r}static fromAffine(e){if(!(e instanceof Point$1))throw new TypeError("JacobianPoint#fromAffine: expected Point");return e.equals(Point$1.ZERO)?JacobianPoint.ZERO:new JacobianPoint(e.x,e.y,_1n$4)}static toAffineBatch(e){const t=invertBatch(e.map(e=>e.z));return e.map((e,r)=>e.toAffine(t[r]))}static normalizeZ(e){return JacobianPoint.toAffineBatch(e).map(JacobianPoint.fromAffine)}equals(e){assertJacPoint(e);const{x:t,y:r,z:n}=this,{x:i,y:o,z:s}=e,a=mod$1(n*n),l=mod$1(s*s),c=mod$1(t*l),u=mod$1(i*a),h=mod$1(mod$1(r*s)*l),d=mod$1(mod$1(o*n)*a);return c===u&&h===d}negate(){return new JacobianPoint(this.x,mod$1(-this.y),this.z)}double(){const{x:e,y:t,z:r}=this,n=mod$1(e*e),i=mod$1(t*t),o=mod$1(i*i),s=e+i,a=mod$1(_2n$3*(mod$1(s*s)-n-o)),l=mod$1(_3n$2*n),c=mod$1(l*l),u=mod$1(c-_2n$3*a),h=mod$1(l*(a-u)-_8n$1*o),d=mod$1(_2n$3*t*r);return new JacobianPoint(u,h,d)}add(e){assertJacPoint(e);const{x:t,y:r,z:n}=this,{x:i,y:o,z:s}=e;if(i===_0n$5||o===_0n$5)return this;if(t===_0n$5||r===_0n$5)return e;const a=mod$1(n*n),l=mod$1(s*s),c=mod$1(t*l),u=mod$1(i*a),h=mod$1(mod$1(r*s)*l),d=mod$1(mod$1(o*n)*a),p=mod$1(u-c),f=mod$1(d-h);if(p===_0n$5)return f===_0n$5?this.double():JacobianPoint.ZERO;const g=mod$1(p*p),m=mod$1(p*g),y=mod$1(c*g),b=mod$1(f*f-m-_2n$3*y),v=mod$1(f*(y-b)-h*m),_=mod$1(n*s*p);return new JacobianPoint(b,v,_)}subtract(e){return this.add(e.negate())}multiplyUnsafe(e){const t=JacobianPoint.ZERO;if("bigint"==typeof e&&e===_0n$5)return t;let r=normalizeScalar(e);if(r===_1n$4)return this;if(!USE_ENDOMORPHISM){let e=t,n=this;for(;r>_0n$5;)r&_1n$4&&(e=e.add(n)),n=n.double(),r>>=_1n$4;return e}let{k1neg:n,k1:i,k2neg:o,k2:s}=endo.splitScalar(r),a=t,l=t,c=this;for(;i>_0n$5||s>_0n$5;)i&_1n$4&&(a=a.add(c)),s&_1n$4&&(l=l.add(c)),c=c.double(),i>>=_1n$4,s>>=_1n$4;return n&&(a=a.negate()),o&&(l=l.negate()),l=new JacobianPoint(mod$1(l.x*endo.beta),l.y,l.z),a.add(l)}precomputeWindow(e){const t=USE_ENDOMORPHISM?128/e+1:256/e+1,r=[];let n=this,i=n;for(let o=0;o<t;o++){i=n,r.push(i);for(let t=1;t<2**(e-1);t++)i=i.add(n),r.push(i);n=i.double()}return r}wNAF(e,t){!t&&this.equals(JacobianPoint.BASE)&&(t=Point$1.BASE);const r=t&&t._WINDOW_SIZE||1;if(256%r)throw new Error("Point#wNAF: Invalid precomputation window, must be power of 2");let n=t&&pointPrecomputes$1.get(t);n||(n=this.precomputeWindow(r),t&&1!==r&&(n=JacobianPoint.normalizeZ(n),pointPrecomputes$1.set(t,n)));let i=JacobianPoint.ZERO,o=JacobianPoint.BASE;const s=1+(USE_ENDOMORPHISM?128/r:256/r),a=2**(r-1),l=BigInt(2**r-1),c=2**r,u=BigInt(r);for(let h=0;h<s;h++){const t=h*a;let r=Number(e&l);e>>=u,r>a&&(r-=c,e+=_1n$4);const s=t,d=t+Math.abs(r)-1,p=h%2!=0,f=r<0;0===r?o=o.add(constTimeNegate(p,n[s])):i=i.add(constTimeNegate(f,n[d]))}return{p:i,f:o}}multiply(e,t){let r,n,i=normalizeScalar(e);if(USE_ENDOMORPHISM){const{k1neg:e,k1:o,k2neg:s,k2:a}=endo.splitScalar(i);let{p:l,f:c}=this.wNAF(o,t),{p:u,f:h}=this.wNAF(a,t);l=constTimeNegate(e,l),u=constTimeNegate(s,u),u=new JacobianPoint(mod$1(u.x*endo.beta),u.y,u.z),r=l.add(u),n=c.add(h)}else{const{p:e,f:o}=this.wNAF(i,t);r=e,n=o}return JacobianPoint.normalizeZ([r,n])[0]}toAffine(e){const{x:t,y:r,z:n}=this,i=this.equals(JacobianPoint.ZERO);null==e&&(e=i?_8n$1:invert$1(n));const o=e,s=mod$1(o*o),a=mod$1(s*o),l=mod$1(t*s),c=mod$1(r*a),u=mod$1(n*o);if(i)return Point$1.ZERO;if(u!==_1n$4)throw new Error("invZ was invalid");return new Point$1(l,c)}}function constTLine truncated /*! noble-secp256k1 - MIT License (c) 2019 Paul Miller (paulmillr.com) */const _0n$5=BigInt(0),_1n$4=BigInt(1),_2n$3=BigInt(2),_3n$2=BigInt(3),_8n$1=BigInt(8),CURVE=Object.freeze({a:_0n$5,b:BigInt(7),P:BigInt("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"),n:BigInt("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"),h:_1n$4,Gx:BigInt("55066263022277343669578718895168534326250603453777594175500187360389116729240"),Gy:BigInt("32670510020758816978083085130507043184471273380659243275938904335757337482424"),beta:BigInt("0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee")}),divNearest$1=(e,t)=>(e+t/_2n$3)/t,endo={beta:BigInt("0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee"),splitScalar(e){const{n:t}=CURVE,r=BigInt("0x3086d221a7d46bcde86c90e49284eb15"),n=-_1n$4*BigInt("0xe4437ed6010e88286f547fa90abfe4c3"),i=BigInt("0x114ca50f7a8e2f3f657c1108d9d44cfd8"),o=r,s=BigInt("0x100000000000000000000000000000000"),a=divNearest$1(o*e,t),l=divNearest$1(-n*e,t);let c=mod$1(e-a*r-l*i,t),u=mod$1(-a*n-l*o,t);const h=c>s,d=u>s;if(h&&(c=t-c),d&&(u=t-u),c>s||u>s)throw new Error("splitScalarEndo: Endomorphism failed, k="+e);return{k1neg:h,k1:c,k2neg:d,k2:u}}},fieldLen=32,groupLen=32,compressedLen=fieldLen+1,uncompressedLen=2*fieldLen+1;function weierstrass$1(e){const{a:t,b:r}=CURVE,n=mod$1(e*e),i=mod$1(n*e);return mod$1(i+t*e+r)}const USE_ENDOMORPHISM=CURVE.a===_0n$5;function assertJacPoint(e){if(!(e instanceof JacobianPoint))throw new TypeError("JacobianPoint expected")}class JacobianPoint{constructor(e,t,r){this.x=e,this.y=t,this.z=r}static fromAffine(e){if(!(e instanceof Point$1))throw new TypeError("JacobianPoint#fromAffine: expected Point");return e.equals(Point$1.ZERO)?JacobianPoint.ZERO:new JacobianPoint(e.x,e.y,_1n$4)}static toAffineBatch(e){const t=invertBatch(e.map(e=>e.z));return e.map((e,r)=>e.toAffine(t[r]))}static normalizeZ(e){return JacobianPoint.toAffineBatch(e).map(JacobianPoint.fromAffine)}equals(e){assertJacPoint(e);const{x:t,y:r,z:n}=this,{x:i,y:o,z:s}=e,a=mod$1(n*n),l=mod$1(s*s),c=mod$1(t*l),u=mod$1(i*a),h=mod$1(mod$1(r*s)*l),d=mod$1(mod$1(o*n)*a);return c===u&&h===d}negate(){return new JacobianPoint(this.x,mod$1(-this.y),this.z)}double(){const{x:e,y:t,z:r}=this,n=mod$1(e*e),i=mod$1(t*t),o=mod$1(i*i),s=e+i,a=mod$1(_2n$3*(mod$1(s*s)-n-o)),l=mod$1(_3n$2*n),c=mod$1(l*l),u=mod$1(c-_2n$3*a),h=mod$1(l*(a-u)-_8n$1*o),d=mod$1(_2n$3*t*r);return new JacobianPoint(u,h,d)}add(e){assertJacPoint(e);const{x:t,y:r,z:n}=this,{x:i,y:o,z:s}=e;if(i===_0n$5||o===_0n$5)return this;if(t===_0n$5||r===_0n$5)return e;const a=mod$1(n*n),l=mod$1(s*s),c=mod$1(t*l),u=mod$1(i*a),h=mod$1(mod$1(r*s)*l),d=mod$1(mod$1(o*n)*a),p=mod$1(u-c),f=mod$1(d-h);if(p===_0n$5)return f===_0n$5?this.double():JacobianPoint.ZERO;const g=mod$1(p*p),m=mod$1(p*g),y=mod$1(c*g),b=mod$1(f*f-m-_2n$3*y),v=mod$1(f*(y-b)-h*m),_=mod$1(n*s*p);return new JacobianPoint(b,v,_)}subtract(e){return this.add(e.negate())}multiplyUnsafe(e){const t=JacobianPoint.ZERO;if("bigint"==typeof e&&e===_0n$5)return t;let r=normalizeScalar(e);if(r===_1n$4)return this;if(!USE_ENDOMORPHISM){let e=t,n=this;for(;r>_0n$5;)r&_1n$4&&(e=e.add(n)),n=n.double(),r>>=_1n$4;return e}let{k1neg:n,k1:i,k2neg:o,k2:s}=endo.splitScalar(r),a=t,l=t,c=this;for(;i>_0n$5||s>_0n$5;)i&_1n$4&&(a=a.add(c)),s&_1n$4&&(l=l.add(c)),c=c.double(),i>>=_1n$4,s>>=_1n$4;return n&&(a=a.negate()),o&&(l=l.negate()),l=new JacobianPoint(mod$1(l.x*endo.beta),l.y,l.z),a.add(l)}precomputeWindow(e){const t=USE_ENDOMORPHISM?128/e+1:256/e+1,r=[];let n=this,i=n;for(let o=0;o<t;o++){i=n,r.push(i);for(let t=1;t<2**(e-1);t++)i=i.add(n),r.push(i);n=i.double()}return r}wNAF(e,t){!t&&this.equals(JacobianPoint.BASE)&&(t=Point$1.BASE);const r=t&&t._WINDOW_SIZE||1;if(256%r)throw new Error("Point#wNAF: Invalid precomputation window, must be power of 2");let n=t&&pointPrecomputes$1.get(t);n||(n=this.precomputeWindow(r),t&&1!==r&&(n=JacobianPoint.normalizeZ(n),pointPrecomputes$1.set(t,n)));let i=JacobianPoint.ZERO,o=JacobianPoint.BASE;const s=1+(USE_ENDOMORPHISM?128/r:256/r),a=2**(r-1),l=BigInt(2**r-1),c=2**r,u=BigInt(r);for(let h=0;h<s;h++){const t=h*a;let r=Number(e&l);e>>=u,r>a&&(r-=c,e+=_1n$4);const s=t,d=t+Math.abs(r)-1,p=h%2!=0,f=r<0;0===r?o=o.add(constTimeNegate(p,n[s])):i=i.add(constTimeNegate(f,n[d]))}return{p:i,f:o}}multiply(e,t){let r,n,i=normalizeScalar(e);if(USE_ENDOMORPHISM){const{k1neg:e,k1:o,k2neg:s,k2:a}=endo.splitScalar(i);let{p:l,f:c}=this.wNAF(o,t),{p:u,f:h}=this.wNAF(a,t);l=constTimeNegate(e,l),u=constTimeNegate(s,u),u=new JacobianPoint(mod$1(u.x*endo.beta),u.y,u.z),r=l.add(u),n=c.add(h)}else{const{p:e,f:o}=this.wNAF(i,t);r=e,n=o}return JacobianPoint.normalizeZ([r,n])[0]}toAffine(e){const{x:t,y:r,z:n}=this,i=this.equals(JacobianPoint.ZERO);null==e&&(e=i?_8n$1:invert$1(n));const o=e,s=mod$1(o*o),a=mod$1(s*o),l=mod$1(t*s),c=mod$1(r*a),u=mod$1(n*o);if(i)return Point$1.ZERO;if(u!==_1n$4)throw new Error("invZ was invalid");return new Point$1(l,c)}}function constTLine truncated
/*! For license information please see remotestorage.js.LICENSE.txt */function requireRemotestorage(){return hasRequiredRemotestorage||(hasRequiredRemotestorage=1,function(module,exports$1){var t;t=function(){return function(){var __webpack_modules__={548:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.Access=void 0;class r{constructor(e){this.rs=e,this.reset(!1)}get scopes(){return Object.keys(this.scopeModeMap).map(e=>({name:e,mode:this.scopeModeMap[e]}))}get scopeParameter(){return this.scopes.map(e=>`${this._scopeNameForParameter(e)}:${e.mode}`).join(" ")}claim(e,t){if("string"!=typeof e||-1!==e.indexOf("/")||0===e.length)throw new Error("Scope should be a non-empty string without forward slashes");if("string"!=typeof t||!t.match(/^rw?$/))throw new Error("Mode should be either 'r' or 'rw'");this._adjustRootPaths(e),this.scopeModeMap[e]=t,this._notifyChange()}get(e){return this.scopeModeMap[e]}remove(e){const t={};for(const r in this.scopeModeMap)t[r]=this.scopeModeMap[r];this.reset(!1),delete t[e];for(const r in t)this._adjustRootPaths(r),this.scopeModeMap[r]=t[r];this._notifyChange()}checkPermission(e,t){const r=this.get(e);return r&&("r"===t||"rw"===r)}checkPathPermission(e,t){if(this.checkPermission("*",t))return!0;const r=this._getModuleName(e);return!!this.checkPermission(r,t)}reset(e=!0){this.rootPaths=[],this.scopeModeMap={},e&&this._notifyChange()}_getModuleName(e){if("/"!==e[0])throw new Error("Path should start with a slash");const t=e.replace(/^\/public/,"").match(/^\/([^/]*)\//);return t?t[1]:"*"}_adjustRootPaths(e){"*"in this.scopeModeMap||"*"===e?this.rootPaths=["/"]:e in this.scopeModeMap||(this.rootPaths.push("/"+e+"/"),this.rootPaths.push("/public/"+e+"/"))}_scopeNameForParameter(e){if("*"===e.name&&this.storageType){if("2012.04"===this.storageType)return"";if(this.storageType.match(/remotestorage-0[01]/))return"root"}return e.name}setStorageType(e){this.storageType=e}_notifyChange(){this.rs&&"function"==typeof this.rs._checkScopeChange&&this.rs._checkScopeChange()}static _rs_init(){}}t.Access=r,t.default=r},275:function(e,t,r){var n=this&&this.__awaiter||function(e,t,r,n){return new(r||(r=Promise))(function(i,o){function s(e){try{l(n.next(e))}catch(e){o(e)}}function a(e){try{l(n.throw(e))}catch(e){o(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r(function(e){e(t)})).then(s,a)}l((n=n.apply(e,t||[])).next())})},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.Authorize=void 0;const o=i(r(28)),s=i(r(334)),a=r(746),l=i(r(503)),c=r(368);let u;function h(e){const t=e||d.getLocation().href,r={};for(const[o,s]of new URL(t).searchParams)r[o]=s;const n=t.indexOf("#");if(-1===n)return r;const i=t.substring(n+1);return i.includes("=")?i.split("&").reduce(function(e,t){const r=t.split("=");if("state"===r[0]&&r[1].match(/rsDiscovery/)){let t=decodeURIComponent(r[1]);const n=t.substr(t.indexOf("rsDiscovery=")).split("&")[0].split("=")[1];e.rsDiscovery=JSON.parse(atob(n)),t=t.replace(new RegExp("&?rsDiscovery="+n),""),t.length>0&&(e.state=t)}else e[decodeURIComponent(r[0])]=decodeURIComponent(r[1]);return e},r):r}class d{static authorize(e,t){if((0,s.default)("[Authorize] authURL = ",t.authURL,"scope = ",t.scope,"redirectUri = ",t.redirectUri,"clientId = ",t.clientId,"response_type =",t.response_type),!t.scope)throw new Error("Cannot authorize due to undefined or empty scope; did you forget to access.claim()?");if("function"==typeof e._rememberPendingScope&&e._rememberPendingScope(t.scope),!(0,a.localStorageAvailable)()&&"remotestorage"===e.backend){t.redirectUri+=t.redirectUri.indexOf("#")>0?"&":"#";const r={userAddress:e.remote.userAddress,href:e.remote.href,storageApi:e.remote.storageApi,properties:e.remote.properties};t.redirectUri+="rsDiscovery="+(0,a.toBase64)(JSON.stringify(r))}const r=function(e){const t=new URL(e.redirectUri);e.state||(e.state=t.hash?t.hash.substring(1):""),e.response_type||(e.response_type="token");const r=new URL(e.authURL);r.searchParams.set("redirect_uri",e.redirectUri.replace(/#.*$/,"")),r.searchParams.set("scope",e.scope),r.searchParams.set("client_id",e.clientId);for(const n of["state","response_type","code_challenge","code_challenge_method","token_access_type"]){const t=e[n];t&&r.searchParams.set(n,t)}return r.href}(t);a.globalContext.cordova&&(d.getLocation().href.startsWith("file:")||"string"==typeof o.default.cordovaRedirectUri&&t.redirectUri===o.default.cordovaRedirectUri)?d.openWindow(r,t.redirectUri,"location=yes,clearsessioncache=yes,clearcache=yes").then(r=>{e.remote.configure({token:r.access_token}),"function"==typeof e._completeAuthorization&&e._completeAuthorization(r.scope||t.scope)}):d.setLocation(r)}static refreshAccessToken(e,t,r){return n(this,void 0,void 0,function*(){var e,n,i;yield t.configure({token:null,tokenType:null});const o=new URLSearchParams({grant_type:"refresh_token",client_id:t.clientId,refresh_token:r}),a=yield(Line truncated /*! For license information please see remotestorage.js.LICENSE.txt */function requireRemotestorage(){return hasRequiredRemotestorage||(hasRequiredRemotestorage=1,function(module,exports$1){var t;t=function(){return function(){var __webpack_modules__={548:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.Access=void 0;class r{constructor(e){this.rs=e,this.reset(!1)}get scopes(){return Object.keys(this.scopeModeMap).map(e=>({name:e,mode:this.scopeModeMap[e]}))}get scopeParameter(){return this.scopes.map(e=>`${this._scopeNameForParameter(e)}:${e.mode}`).join(" ")}claim(e,t){if("string"!=typeof e||-1!==e.indexOf("/")||0===e.length)throw new Error("Scope should be a non-empty string without forward slashes");if("string"!=typeof t||!t.match(/^rw?$/))throw new Error("Mode should be either 'r' or 'rw'");this._adjustRootPaths(e),this.scopeModeMap[e]=t,this._notifyChange()}get(e){return this.scopeModeMap[e]}remove(e){const t={};for(const r in this.scopeModeMap)t[r]=this.scopeModeMap[r];this.reset(!1),delete t[e];for(const r in t)this._adjustRootPaths(r),this.scopeModeMap[r]=t[r];this._notifyChange()}checkPermission(e,t){const r=this.get(e);return r&&("r"===t||"rw"===r)}checkPathPermission(e,t){if(this.checkPermission("*",t))return!0;const r=this._getModuleName(e);return!!this.checkPermission(r,t)}reset(e=!0){this.rootPaths=[],this.scopeModeMap={},e&&this._notifyChange()}_getModuleName(e){if("/"!==e[0])throw new Error("Path should start with a slash");const t=e.replace(/^\/public/,"").match(/^\/([^/]*)\//);return t?t[1]:"*"}_adjustRootPaths(e){"*"in this.scopeModeMap||"*"===e?this.rootPaths=["/"]:e in this.scopeModeMap||(this.rootPaths.push("/"+e+"/"),this.rootPaths.push("/public/"+e+"/"))}_scopeNameForParameter(e){if("*"===e.name&&this.storageType){if("2012.04"===this.storageType)return"";if(this.storageType.match(/remotestorage-0[01]/))return"root"}return e.name}setStorageType(e){this.storageType=e}_notifyChange(){this.rs&&"function"==typeof this.rs._checkScopeChange&&this.rs._checkScopeChange()}static _rs_init(){}}t.Access=r,t.default=r},275:function(e,t,r){var n=this&&this.__awaiter||function(e,t,r,n){return new(r||(r=Promise))(function(i,o){function s(e){try{l(n.next(e))}catch(e){o(e)}}function a(e){try{l(n.throw(e))}catch(e){o(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r(function(e){e(t)})).then(s,a)}l((n=n.apply(e,t||[])).next())})},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.Authorize=void 0;const o=i(r(28)),s=i(r(334)),a=r(746),l=i(r(503)),c=r(368);let u;function h(e){const t=e||d.getLocation().href,r={};for(const[o,s]of new URL(t).searchParams)r[o]=s;const n=t.indexOf("#");if(-1===n)return r;const i=t.substring(n+1);return i.includes("=")?i.split("&").reduce(function(e,t){const r=t.split("=");if("state"===r[0]&&r[1].match(/rsDiscovery/)){let t=decodeURIComponent(r[1]);const n=t.substr(t.indexOf("rsDiscovery=")).split("&")[0].split("=")[1];e.rsDiscovery=JSON.parse(atob(n)),t=t.replace(new RegExp("&?rsDiscovery="+n),""),t.length>0&&(e.state=t)}else e[decodeURIComponent(r[0])]=decodeURIComponent(r[1]);return e},r):r}class d{static authorize(e,t){if((0,s.default)("[Authorize] authURL = ",t.authURL,"scope = ",t.scope,"redirectUri = ",t.redirectUri,"clientId = ",t.clientId,"response_type =",t.response_type),!t.scope)throw new Error("Cannot authorize due to undefined or empty scope; did you forget to access.claim()?");if("function"==typeof e._rememberPendingScope&&e._rememberPendingScope(t.scope),!(0,a.localStorageAvailable)()&&"remotestorage"===e.backend){t.redirectUri+=t.redirectUri.indexOf("#")>0?"&":"#";const r={userAddress:e.remote.userAddress,href:e.remote.href,storageApi:e.remote.storageApi,properties:e.remote.properties};t.redirectUri+="rsDiscovery="+(0,a.toBase64)(JSON.stringify(r))}const r=function(e){const t=new URL(e.redirectUri);e.state||(e.state=t.hash?t.hash.substring(1):""),e.response_type||(e.response_type="token");const r=new URL(e.authURL);r.searchParams.set("redirect_uri",e.redirectUri.replace(/#.*$/,"")),r.searchParams.set("scope",e.scope),r.searchParams.set("client_id",e.clientId);for(const n of["state","response_type","code_challenge","code_challenge_method","token_access_type"]){const t=e[n];t&&r.searchParams.set(n,t)}return r.href}(t);a.globalContext.cordova&&(d.getLocation().href.startsWith("file:")||"string"==typeof o.default.cordovaRedirectUri&&t.redirectUri===o.default.cordovaRedirectUri)?d.openWindow(r,t.redirectUri,"location=yes,clearsessioncache=yes,clearcache=yes").then(r=>{e.remote.configure({token:r.access_token}),"function"==typeof e._completeAuthorization&&e._completeAuthorization(r.scope||t.scope)}):d.setLocation(r)}static refreshAccessToken(e,t,r){return n(this,void 0,void 0,function*(){var e,n,i;yield t.configure({token:null,tokenType:null});const o=new URLSearchParams({grant_type:"refresh_token",client_id:t.clientId,refresh_token:r}),a=yield(Line truncated
/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */ /*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */
Object.defineProperty(e,"__esModule",{value:!0}),e.bytes=e.stringToBytes=e.str=e.bytesToString=e.hex=e.utf8=e.bech32m=e.bech32=e.base58check=e.base58xmr=e.base58xrp=e.base58flickr=e.base58=e.base64url=e.base64=e.base32crockford=e.base32hex=e.base32=e.base16=e.utils=e.assertNumber=void 0,e.assertNumber=t;const l=(e,t)=>t?l(t,e%t):e,c=(e,t)=>e+(t-l(e,t));function u(e,r,n,i){if(!Array.isArray(e))throw new Error("convertRadix2: data should be array");if(r<=0||r>32)throw new Error(`convertRadix2: wrong from=${r}`);if(n<=0||n>32)throw new Error(`convertRadix2: wrong to=${n}`);if(c(r,n)>32)throw new Error(`convertRadix2: carry overflow from=${r} to=${n} carryBits=${c(r,n)}`);let o=0,s=0;const a=2**n-1,l=[];for(const c of e){if(t(c),c>=2**r)throw new Error(`convertRadix2: invalid data word=${c} from=${r}`);if(o=o<<r|c,s+r>32)throw new Error(`convertRadix2: carry overflow pos=${s} from=${r}`);for(s+=r;s>=n;s-=n)l.push((o>>s-n&a)>>>0);o&=2**s-1}if(o=o<<n-s&a,!i&&s>=r)throw new Error("Excess padding");if(!i&&o)throw new Error(`Non-zero padding: ${o}`);return i&&s>0&&l.push(o>>>0),l}function h(e){return t(e),{encode:t=>{if(!(t instanceof Uint8Array))throw new Error("radix.encode input should be Uint8Array");return a(Array.from(t),256,e)},decode:t=>{if(!Array.isArray(t)||t.length&&"number"!=typeof t[0])throw new Error("radix.decode input should be array of strings");return Uint8Array.from(a(t,e,256))}}}function d(e,r=!1){if(t(e),e<=0||e>32)throw new Error("radix2: bits should be in (0..32]");if(c(8,e)>32||c(e,8)>32)throw new Error("radix2: carry overflow");return{encode:t=>{if(!(t instanceof Uint8Array))throw new Error("radix2.encode input should be Uint8Array");return u(Array.from(t),8,e,!r)},decode:t=>{if(!Array.isArray(t)||t.length&&"number"!=typeof t[0])throw new Error("radix2.decode input should be array of strings");return Uint8Array.from(u(t,e,8,r))}}}function p(e){if("function"!=typeof e)throw new Error("unsafeWrapper fn should be function");return function(...t){try{return e.apply(null,t)}catch(r){}}}function f(e,r){if(t(e),"function"!=typeof r)throw new Error("checksum fn should be function");return{encode(t){if(!(t instanceof Uint8Array))throw new Error("checksum.encode: input should be Uint8Array");const n=r(t).slice(0,e),i=new Uint8Array(t.length+e);return i.set(t),i.set(n,t.length),i},decode(t){if(!(t instanceof Uint8Array))throw new Error("checksum.decode: input should be Uint8Array");const n=t.slice(0,-e),i=r(n).slice(0,e),o=t.slice(-e);for(let r=0;r<e;r++)if(i[r]!==o[r])throw new Error("Invalid checksum");return n}}}e.utils={alphabet:n,chain:r,checksum:f,radix:h,radix2:d,join:i,padding:o},e.base16=r(d(4),n("0123456789ABCDEF"),i("")),e.base32=r(d(5),n("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"),o(5),i("")),e.base32hex=r(d(5),n("0123456789ABCDEFGHIJKLMNOPQRSTUV"),o(5),i("")),e.base32crockford=r(d(5),n("0123456789ABCDEFGHJKMNPQRSTVWXYZ"),i(""),s(e=>e.toUpperCase().replace(/O/g,"0").replace(/[IL]/g,"1"))),e.base64=r(d(6),n("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"),o(6),i("")),e.base64url=r(d(6),n("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"),o(6),i(""));const g=e=>r(h(58),n(e),i(""));e.base58=g("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"),e.base58flickr=g("123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"),e.base58xrp=g("rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz");const m=[0,2,3,5,6,7,9,10,11];e.base58xmr={encode(t){let r="";for(let n=0;n<t.length;n+=8){const i=t.subarray(n,n+8);r+=e.base58.encode(i).padStart(m[i.length],"1")}return r},decode(t){let r=[];for(let n=0;n<t.length;n+=11){const i=t.slice(n,n+11),o=m.indexOf(i.length),s=e.base58.decode(i);for(let e=0;e<s.length-o;e++)if(0!==s[e])throw new Error("base58xmr: wrong padding");r=r.concat(Array.from(s.slice(s.length-o)))}return Uint8Array.from(r)}},e.base58check=t=>r(f(4,e=>t(t(e))),e.base58);const y=r(n("qpzry9x8gf2tvdw0s3jn54khce6mua7l"),i("")),b=[996825010,642813549,513874426,1027748829,705979059];function v(e){const t=e>>25;let r=(33554431&e)<<5;for(let n=0;n<b.length;n++)1==(t>>n&1)&&(r^=b[n]);return r}function _(e,t,r=1){const n=e.length;let i=1;for(let o=0;o<n;o++){const t=e.charCodeAt(o);if(t<33||t>126)throw new Error(`Invalid prefix (${e})`);i=v(i)^t>>5}i=v(i);for(let o=0;o<n;o++)i=v(i)^31&e.charCodeAt(o);for(let o of t)i=v(i)^o;for(let o=0;o<6;o++)i=v(i);return i^=r,y.encode(u([i%2**30],30,5,!1))}function E(e){const t="bech32"===e?1:734539939,r=d(5),n=r.decode,i=r.encode,o=p(n);function s(e,r=90){if("string"!=typeof e)throw new Error("bech32.decode input should be string, not "+typeof e);if(e.length<8||!1!==r&&e.length>r)throw new TypeError(`Wrong string length: ${e.length} (${e}). Expected (8..${r})`);const n=e.toLowerCase();if(e!==n&&e!==e.toUpperCase())throw new Error("String must be lowercase or uppercase");const i=(e=n).lastIndexOf("1");if(0===i||-1===i)throw new Error('Letter "1" must be present between prefix and data only');const o=e.slice(0,i),s=e.slLine truncated Object.defineProperty(e,"__esModule",{value:!0}),e.bytes=e.stringToBytes=e.str=e.bytesToString=e.hex=e.utf8=e.bech32m=e.bech32=e.base58check=e.base58xmr=e.base58xrp=e.base58flickr=e.base58=e.base64url=e.base64=e.base32crockford=e.base32hex=e.base32=e.base16=e.utils=e.assertNumber=void 0,e.assertNumber=t;const l=(e,t)=>t?l(t,e%t):e,c=(e,t)=>e+(t-l(e,t));function u(e,r,n,i){if(!Array.isArray(e))throw new Error("convertRadix2: data should be array");if(r<=0||r>32)throw new Error(`convertRadix2: wrong from=${r}`);if(n<=0||n>32)throw new Error(`convertRadix2: wrong to=${n}`);if(c(r,n)>32)throw new Error(`convertRadix2: carry overflow from=${r} to=${n} carryBits=${c(r,n)}`);let o=0,s=0;const a=2**n-1,l=[];for(const c of e){if(t(c),c>=2**r)throw new Error(`convertRadix2: invalid data word=${c} from=${r}`);if(o=o<<r|c,s+r>32)throw new Error(`convertRadix2: carry overflow pos=${s} from=${r}`);for(s+=r;s>=n;s-=n)l.push((o>>s-n&a)>>>0);o&=2**s-1}if(o=o<<n-s&a,!i&&s>=r)throw new Error("Excess padding");if(!i&&o)throw new Error(`Non-zero padding: ${o}`);return i&&s>0&&l.push(o>>>0),l}function h(e){return t(e),{encode:t=>{if(!(t instanceof Uint8Array))throw new Error("radix.encode input should be Uint8Array");return a(Array.from(t),256,e)},decode:t=>{if(!Array.isArray(t)||t.length&&"number"!=typeof t[0])throw new Error("radix.decode input should be array of strings");return Uint8Array.from(a(t,e,256))}}}function d(e,r=!1){if(t(e),e<=0||e>32)throw new Error("radix2: bits should be in (0..32]");if(c(8,e)>32||c(e,8)>32)throw new Error("radix2: carry overflow");return{encode:t=>{if(!(t instanceof Uint8Array))throw new Error("radix2.encode input should be Uint8Array");return u(Array.from(t),8,e,!r)},decode:t=>{if(!Array.isArray(t)||t.length&&"number"!=typeof t[0])throw new Error("radix2.decode input should be array of strings");return Uint8Array.from(u(t,e,8,r))}}}function p(e){if("function"!=typeof e)throw new Error("unsafeWrapper fn should be function");return function(...t){try{return e.apply(null,t)}catch(r){}}}function f(e,r){if(t(e),"function"!=typeof r)throw new Error("checksum fn should be function");return{encode(t){if(!(t instanceof Uint8Array))throw new Error("checksum.encode: input should be Uint8Array");const n=r(t).slice(0,e),i=new Uint8Array(t.length+e);return i.set(t),i.set(n,t.length),i},decode(t){if(!(t instanceof Uint8Array))throw new Error("checksum.decode: input should be Uint8Array");const n=t.slice(0,-e),i=r(n).slice(0,e),o=t.slice(-e);for(let r=0;r<e;r++)if(i[r]!==o[r])throw new Error("Invalid checksum");return n}}}e.utils={alphabet:n,chain:r,checksum:f,radix:h,radix2:d,join:i,padding:o},e.base16=r(d(4),n("0123456789ABCDEF"),i("")),e.base32=r(d(5),n("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"),o(5),i("")),e.base32hex=r(d(5),n("0123456789ABCDEFGHIJKLMNOPQRSTUV"),o(5),i("")),e.base32crockford=r(d(5),n("0123456789ABCDEFGHJKMNPQRSTVWXYZ"),i(""),s(e=>e.toUpperCase().replace(/O/g,"0").replace(/[IL]/g,"1"))),e.base64=r(d(6),n("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"),o(6),i("")),e.base64url=r(d(6),n("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"),o(6),i(""));const g=e=>r(h(58),n(e),i(""));e.base58=g("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"),e.base58flickr=g("123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"),e.base58xrp=g("rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz");const m=[0,2,3,5,6,7,9,10,11];e.base58xmr={encode(t){let r="";for(let n=0;n<t.length;n+=8){const i=t.subarray(n,n+8);r+=e.base58.encode(i).padStart(m[i.length],"1")}return r},decode(t){let r=[];for(let n=0;n<t.length;n+=11){const i=t.slice(n,n+11),o=m.indexOf(i.length),s=e.base58.decode(i);for(let e=0;e<s.length-o;e++)if(0!==s[e])throw new Error("base58xmr: wrong padding");r=r.concat(Array.from(s.slice(s.length-o)))}return Uint8Array.from(r)}},e.base58check=t=>r(f(4,e=>t(t(e))),e.base58);const y=r(n("qpzry9x8gf2tvdw0s3jn54khce6mua7l"),i("")),b=[996825010,642813549,513874426,1027748829,705979059];function v(e){const t=e>>25;let r=(33554431&e)<<5;for(let n=0;n<b.length;n++)1==(t>>n&1)&&(r^=b[n]);return r}function _(e,t,r=1){const n=e.length;let i=1;for(let o=0;o<n;o++){const t=e.charCodeAt(o);if(t<33||t>126)throw new Error(`Invalid prefix (${e})`);i=v(i)^t>>5}i=v(i);for(let o=0;o<n;o++)i=v(i)^31&e.charCodeAt(o);for(let o of t)i=v(i)^o;for(let o=0;o<6;o++)i=v(i);return i^=r,y.encode(u([i%2**30],30,5,!1))}function E(e){const t="bech32"===e?1:734539939,r=d(5),n=r.decode,i=r.encode,o=p(n);function s(e,r=90){if("string"!=typeof e)throw new Error("bech32.decode input should be string, not "+typeof e);if(e.length<8||!1!==r&&e.length>r)throw new TypeError(`Wrong string length: ${e.length} (${e}). Expected (8..${r})`);const n=e.toLowerCase();if(e!==n&&e!==e.toUpperCase())throw new Error("String must be lowercase or uppercase");const i=(e=n).lastIndexOf("1");if(0===i||-1===i)throw new Error('Letter "1" must be present between prefix and data only');const o=e.slice(0,i),s=e.slLine truncated
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */function isBytes$2(e){return e instanceof Uint8Array||ArrayBuffer.isView(e)&&"Uint8Array"===e.constructor.name}function anumber$2(e,t=""){if(!Number.isSafeInteger(e)||e<0)throw new Error(`${t&&`"${t}" `}expected integer >= 0, got ${e}`)}function abytes$2(e,t,r=""){const n=isBytes$2(e),i=e?.length,o=void 0!==t;if(!n||o&&i!==t)throw new Error((r&&`"${r}" `)+"expected Uint8Array"+(o?` of length ${t}`:"")+", got "+(n?`length=${i}`:"type="+typeof e));return e}function ahash(e){if("function"!=typeof e||"function"!=typeof e.create)throw new Error("Hash must wrapped by utils.createHasher");anumber$2(e.outputLen),anumber$2(e.blockLen)}function aexists(e,t=!0){if(e.destroyed)throw new Error("Hash instance has been destroyed");if(t&&e.finished)throw new Error("Hash#digest() has already been called")}function aoutput(e,t){abytes$2(e,void 0,"digestInto() output");const r=t.outputLen;if(e.length<r)throw new Error('"digestInto() output" expected to be of length >='+r)}function clean$1(...e){for(let t=0;t<e.length;t++)e[t].fill(0)}function createView(e){return new DataView(e.buffer,e.byteOffset,e.byteLength)}function rotr(e,t){return e<<32-t|e>>>t}const hasHexBuiltin=(()=>"function"==typeof Uint8Array.from([]).toHex&&"function"==typeof Uint8Array.fromHex)(),hexes=Array.from({length:256},(e,t)=>t.toString(16).padStart(2,"0"));function bytesToHex(e){if(abytes$2(e),hasHexBuiltin)return e.toHex();let t="";for(let r=0;r<e.length;r++)t+=hexes[e[r]];return t}const asciis={_0:48,_9:57,A:65,F:70,a:97,f:102};function asciiToBase16(e){return e>=asciis._0&&e<=asciis._9?e-asciis._0:e>=asciis.A&&e<=asciis.F?e-(asciis.A-10):e>=asciis.a&&e<=asciis.f?e-(asciis.a-10):void 0}function hexToBytes(e){if("string"!=typeof e)throw new Error("hex string expected, got "+typeof e);if(hasHexBuiltin)return Uint8Array.fromHex(e);const t=e.length,r=t/2;if(t%2)throw new Error("hex string expected, got unpadded hex of length "+t);const n=new Uint8Array(r);for(let i=0,o=0;i<r;i++,o+=2){const t=asciiToBase16(e.charCodeAt(o)),r=asciiToBase16(e.charCodeAt(o+1));if(void 0===t||void 0===r){const t=e[o]+e[o+1];throw new Error('hex string expected, got non-hex character "'+t+'" at index '+o)}n[i]=16*t+r}return n}function concatBytes(...e){let t=0;for(let n=0;n<e.length;n++){const r=e[n];abytes$2(r),t+=r.length}const r=new Uint8Array(t);for(let n=0,i=0;n<e.length;n++){const t=e[n];r.set(t,i),i+=t.length}return r}function createHasher(e,t={}){const r=(t,r)=>e(r).update(t).digest(),n=e(void 0);return r.outputLen=n.outputLen,r.blockLen=n.blockLen,r.create=t=>e(t),Object.assign(r,t),Object.freeze(r)}function randomBytes(e=32){const t="object"==typeof globalThis?globalThis.crypto:null;if("function"!=typeof t?.getRandomValues)throw new Error("crypto.getRandomValues must be defined");return t.getRandomValues(new Uint8Array(e))}const oidNist=e=>({oid:Uint8Array.from([6,9,96,134,72,1,101,3,4,2,e])});function Chi(e,t,r){return e&t^~e&r}function Maj(e,t,r){return e&t^e&r^t&r}class HashMD{blockLen;outputLen;padOffset;isLE;buffer;view;finished=!1;length=0;pos=0;destroyed=!1;constructor(e,t,r,n){this.blockLen=e,this.outputLen=t,this.padOffset=r,this.isLE=n,this.buffer=new Uint8Array(e),this.view=createView(this.buffer)}update(e){aexists(this),abytes$2(e);const{view:t,buffer:r,blockLen:n}=this,i=e.length;for(let o=0;o<i;){const s=Math.min(n-this.pos,i-o);if(s===n){const t=createView(e);for(;n<=i-o;o+=n)this.process(t,o);continue}r.set(e.subarray(o,o+s),this.pos),this.pos+=s,o+=s,this.pos===n&&(this.process(t,0),this.pos=0)}return this.length+=e.length,this.roundClean(),this}digestInto(e){aexists(this),aoutput(e,this),this.finished=!0;const{buffer:t,view:r,blockLen:n,isLE:i}=this;let{pos:o}=this;t[o++]=128,clean$1(this.buffer.subarray(o)),this.padOffset>n-o&&(this.process(r,0),o=0);for(let u=o;u<n;u++)t[u]=0;r.setBigUint64(n-8,BigInt(8*this.length),i),this.process(r,0);const s=createView(e),a=this.outputLen;if(a%4)throw new Error("_sha2: outputLen must be aligned to 32bit");const l=a/4,c=this.get();if(l>c.length)throw new Error("_sha2: outputLen bigger than state");for(let u=0;u<l;u++)s.setUint32(4*u,c[u],i)}digest(){const{buffer:e,outputLen:t}=this;this.digestInto(e);const r=e.slice(0,t);return this.destroy(),r}_cloneInto(e){e||=new this.constructor,e.set(...this.get());const{blockLen:t,buffer:r,length:n,finished:i,destroyed:o,pos:s}=this;return e.destroyed=o,e.finished=i,e.length=n,e.pos=s,n%t&&e.buffer.set(r),e}clone(){return this._cloneInto()}}const SHA256_IV=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),SHA256_K=Uint32Array.from([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,358452871Line truncated /*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */function isBytes$2(e){return e instanceof Uint8Array||ArrayBuffer.isView(e)&&"Uint8Array"===e.constructor.name}function anumber$2(e,t=""){if(!Number.isSafeInteger(e)||e<0)throw new Error(`${t&&`"${t}" `}expected integer >= 0, got ${e}`)}function abytes$2(e,t,r=""){const n=isBytes$2(e),i=e?.length,o=void 0!==t;if(!n||o&&i!==t)throw new Error((r&&`"${r}" `)+"expected Uint8Array"+(o?` of length ${t}`:"")+", got "+(n?`length=${i}`:"type="+typeof e));return e}function ahash(e){if("function"!=typeof e||"function"!=typeof e.create)throw new Error("Hash must wrapped by utils.createHasher");anumber$2(e.outputLen),anumber$2(e.blockLen)}function aexists(e,t=!0){if(e.destroyed)throw new Error("Hash instance has been destroyed");if(t&&e.finished)throw new Error("Hash#digest() has already been called")}function aoutput(e,t){abytes$2(e,void 0,"digestInto() output");const r=t.outputLen;if(e.length<r)throw new Error('"digestInto() output" expected to be of length >='+r)}function clean$1(...e){for(let t=0;t<e.length;t++)e[t].fill(0)}function createView(e){return new DataView(e.buffer,e.byteOffset,e.byteLength)}function rotr(e,t){return e<<32-t|e>>>t}const hasHexBuiltin=(()=>"function"==typeof Uint8Array.from([]).toHex&&"function"==typeof Uint8Array.fromHex)(),hexes=Array.from({length:256},(e,t)=>t.toString(16).padStart(2,"0"));function bytesToHex(e){if(abytes$2(e),hasHexBuiltin)return e.toHex();let t="";for(let r=0;r<e.length;r++)t+=hexes[e[r]];return t}const asciis={_0:48,_9:57,A:65,F:70,a:97,f:102};function asciiToBase16(e){return e>=asciis._0&&e<=asciis._9?e-asciis._0:e>=asciis.A&&e<=asciis.F?e-(asciis.A-10):e>=asciis.a&&e<=asciis.f?e-(asciis.a-10):void 0}function hexToBytes(e){if("string"!=typeof e)throw new Error("hex string expected, got "+typeof e);if(hasHexBuiltin)return Uint8Array.fromHex(e);const t=e.length,r=t/2;if(t%2)throw new Error("hex string expected, got unpadded hex of length "+t);const n=new Uint8Array(r);for(let i=0,o=0;i<r;i++,o+=2){const t=asciiToBase16(e.charCodeAt(o)),r=asciiToBase16(e.charCodeAt(o+1));if(void 0===t||void 0===r){const t=e[o]+e[o+1];throw new Error('hex string expected, got non-hex character "'+t+'" at index '+o)}n[i]=16*t+r}return n}function concatBytes(...e){let t=0;for(let n=0;n<e.length;n++){const r=e[n];abytes$2(r),t+=r.length}const r=new Uint8Array(t);for(let n=0,i=0;n<e.length;n++){const t=e[n];r.set(t,i),i+=t.length}return r}function createHasher(e,t={}){const r=(t,r)=>e(r).update(t).digest(),n=e(void 0);return r.outputLen=n.outputLen,r.blockLen=n.blockLen,r.create=t=>e(t),Object.assign(r,t),Object.freeze(r)}function randomBytes(e=32){const t="object"==typeof globalThis?globalThis.crypto:null;if("function"!=typeof t?.getRandomValues)throw new Error("crypto.getRandomValues must be defined");return t.getRandomValues(new Uint8Array(e))}const oidNist=e=>({oid:Uint8Array.from([6,9,96,134,72,1,101,3,4,2,e])});function Chi(e,t,r){return e&t^~e&r}function Maj(e,t,r){return e&t^e&r^t&r}class HashMD{blockLen;outputLen;padOffset;isLE;buffer;view;finished=!1;length=0;pos=0;destroyed=!1;constructor(e,t,r,n){this.blockLen=e,this.outputLen=t,this.padOffset=r,this.isLE=n,this.buffer=new Uint8Array(e),this.view=createView(this.buffer)}update(e){aexists(this),abytes$2(e);const{view:t,buffer:r,blockLen:n}=this,i=e.length;for(let o=0;o<i;){const s=Math.min(n-this.pos,i-o);if(s===n){const t=createView(e);for(;n<=i-o;o+=n)this.process(t,o);continue}r.set(e.subarray(o,o+s),this.pos),this.pos+=s,o+=s,this.pos===n&&(this.process(t,0),this.pos=0)}return this.length+=e.length,this.roundClean(),this}digestInto(e){aexists(this),aoutput(e,this),this.finished=!0;const{buffer:t,view:r,blockLen:n,isLE:i}=this;let{pos:o}=this;t[o++]=128,clean$1(this.buffer.subarray(o)),this.padOffset>n-o&&(this.process(r,0),o=0);for(let u=o;u<n;u++)t[u]=0;r.setBigUint64(n-8,BigInt(8*this.length),i),this.process(r,0);const s=createView(e),a=this.outputLen;if(a%4)throw new Error("_sha2: outputLen must be aligned to 32bit");const l=a/4,c=this.get();if(l>c.length)throw new Error("_sha2: outputLen bigger than state");for(let u=0;u<l;u++)s.setUint32(4*u,c[u],i)}digest(){const{buffer:e,outputLen:t}=this;this.digestInto(e);const r=e.slice(0,t);return this.destroy(),r}_cloneInto(e){e||=new this.constructor,e.set(...this.get());const{blockLen:t,buffer:r,length:n,finished:i,destroyed:o,pos:s}=this;return e.destroyed=o,e.finished=i,e.length=n,e.pos=s,n%t&&e.buffer.set(r),e}clone(){return this._cloneInto()}}const SHA256_IV=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),SHA256_K=Uint32Array.from([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,358452871Line truncated
@@ -22,4 +22,4 @@ Object.defineProperty(e,"__esModule",{value:!0}),e.bytes=e.stringToBytes=e.str=e
const divNearest=(e,t)=>(e+(e>=0?t:-t)/_2n$1)/t;function _splitEndoScalar(e,t,r){const[[n,i],[o,s]]=t,a=divNearest(s*e,r),l=divNearest(-i*e,r);let c=e-a*n-l*o,u=-a*i-l*s;const h=c<_0n$1,d=u<_0n$1;h&&(c=-c),d&&(u=-u);const p=bitMask(Math.ceil(bitLen(r)/2))+_1n;if(c<_0n$1||c>=p||u<_0n$1||u>=p)throw new Error("splitScalar (endomorphism): failed, k="+e);return{k1neg:h,k1:c,k2neg:d,k2:u}}function validateSigFormat(e){if(!["compact","recovered","der"].includes(e))throw new Error('Signature format must be "compact", "recovered", or "der"');return e}function validateSigOpts(e,t){const r={};for(let n of Object.keys(t))r[n]=void 0===e[n]?t[n]:e[n];return abool$1(r.lowS,"lowS"),abool$1(r.prehash,"prehash"),void 0!==r.format&&validateSigFormat(r.format),r}class DERErr extends Error{constructor(e=""){super(e)}}const DER={Err:DERErr,_tlv:{encode:(e,t)=>{const{Err:r}=DER;if(e<0||e>256)throw new r("tlv.encode: wrong tag");if(1&t.length)throw new r("tlv.encode: unpadded data");const n=t.length/2,i=numberToHexUnpadded(n);if(i.length/2&128)throw new r("tlv.encode: long form length too big");const o=n>127?numberToHexUnpadded(i.length/2|128):"";return numberToHexUnpadded(e)+o+i+t},decode(e,t){const{Err:r}=DER;let n=0;if(e<0||e>256)throw new r("tlv.encode: wrong tag");if(t.length<2||t[n++]!==e)throw new r("tlv.decode: wrong tlv");const i=t[n++];let o=0;if(128&i){const e=127&i;if(!e)throw new r("tlv.decode(long): indefinite length not supported");if(e>4)throw new r("tlv.decode(long): byte length is too big");const s=t.subarray(n,n+e);if(s.length!==e)throw new r("tlv.decode: length bytes not complete");if(0===s[0])throw new r("tlv.decode(long): zero leftmost byte");for(const t of s)o=o<<8|t;if(n+=e,o<128)throw new r("tlv.decode(long): not minimal encoding")}else o=i;const s=t.subarray(n,n+o);if(s.length!==o)throw new r("tlv.decode: wrong value length");return{v:s,l:t.subarray(n+o)}}},_int:{encode(e){const{Err:t}=DER;if(e<_0n$1)throw new t("integer: negative integers are not allowed");let r=numberToHexUnpadded(e);if(8&Number.parseInt(r[0],16)&&(r="00"+r),1&r.length)throw new t("unexpected DER parsing assertion: unpadded hex");return r},decode(e){const{Err:t}=DER;if(128&e[0])throw new t("invalid signature integer: negative");if(0===e[0]&&!(128&e[1]))throw new t("invalid signature integer: unnecessary leading zero");return bytesToNumberBE(e)}},toSig(e){const{Err:t,_int:r,_tlv:n}=DER,i=abytes$2(e,void 0,"signature"),{v:o,l:s}=n.decode(48,i);if(s.length)throw new t("invalid signature: left bytes after parsing");const{v:a,l:l}=n.decode(2,o),{v:c,l:u}=n.decode(2,l);if(u.length)throw new t("invalid signature: left bytes after parsing");return{r:r.decode(a),s:r.decode(c)}},hexFromSig(e){const{_tlv:t,_int:r}=DER,n=t.encode(2,r.encode(e.r))+t.encode(2,r.encode(e.s));return t.encode(48,n)}},_0n$1=BigInt(0),_1n=BigInt(1),_2n$1=BigInt(2),_3n=BigInt(3),_4n=BigInt(4);function weierstrass(e,t={}){const r=createCurveFields("weierstrass",e,t),{Fp:n,Fn:i}=r;let o=r.CURVE;const{h:s,n:a}=o;validateObject(t,{},{allowInfinityPoint:"boolean",clearCofactor:"function",isTorsionFree:"function",fromBytes:"function",toBytes:"function",endo:"object"});const{endo:l}=t;if(l&&(!n.is0(o.a)||"bigint"!=typeof l.beta||!Array.isArray(l.basises)))throw new Error('invalid endo: expected "beta": bigint and "basises": array');const c=getWLengths(n,i);function u(){if(!n.isOdd)throw new Error("compression is not supported: Field does not have .isOdd()")}const h=t.toBytes||function(e,t,r){const{x:i,y:o}=t.toAffine(),s=n.toBytes(i);return abool$1(r,"isCompressed"),r?(u(),concatBytes(pprefix(!n.isOdd(o)),s)):concatBytes(Uint8Array.of(4),s,n.toBytes(o))},d=t.fromBytes||function(e){abytes$2(e,void 0,"Point");const{publicKey:t,publicKeyUncompressed:r}=c,i=e.length,o=e[0],s=e.subarray(1);if(i!==t||2!==o&&3!==o){if(i===r&&4===o){const e=n.BYTES,t=n.fromBytes(s.subarray(0,e)),r=n.fromBytes(s.subarray(e,2*e));if(!f(t,r))throw new Error("bad point: is not on curve");return{x:t,y:r}}throw new Error(`bad point: got length ${i}, expected compressed=${t} or uncompressed=${r}`)}{const e=n.fromBytes(s);if(!n.isValid(e))throw new Error("bad point: is not on curve, wrong x");const t=p(e);let r;try{r=n.sqrt(t)}catch(a){const e=a instanceof Error?": "+a.message:"";throw new Error("bad point: is not on curve, sqrt error"+e)}return u(),!(1&~o)!==n.isOdd(r)&&(r=n.neg(r)),{x:e,y:r}}};function p(e){const t=n.sqr(e),r=n.mul(t,e);return n.add(n.add(r,n.mul(e,o.a)),o.b)}function f(e,t){const r=n.sqr(t),i=p(e);return n.eql(r,i)}if(!f(o.Gx,o.Gy))throw new Error("bad curve params: generator point");const g=n.mul(n.pow(o.a,_3n),_4n),m=n.mul(n.sqr(o.b),BigInt(27));if(n.is0(n.add(g,m)))throw new Error("bad curve params: a or b");function y(e,t,r=!1){if(!n.isValid(t)||r&&n.is0(t))throw new Error(`bad point coordinate ${e}`);return t}function b(e){if(!(e instanceof C))throw new Error("Weierstrass Point expected")}function v(e){if(!l||!l.basises)throw new Error("no endo");return _splitEndoScalar(e,l.basises,i.OLine truncated const divNearest=(e,t)=>(e+(e>=0?t:-t)/_2n$1)/t;function _splitEndoScalar(e,t,r){const[[n,i],[o,s]]=t,a=divNearest(s*e,r),l=divNearest(-i*e,r);let c=e-a*n-l*o,u=-a*i-l*s;const h=c<_0n$1,d=u<_0n$1;h&&(c=-c),d&&(u=-u);const p=bitMask(Math.ceil(bitLen(r)/2))+_1n;if(c<_0n$1||c>=p||u<_0n$1||u>=p)throw new Error("splitScalar (endomorphism): failed, k="+e);return{k1neg:h,k1:c,k2neg:d,k2:u}}function validateSigFormat(e){if(!["compact","recovered","der"].includes(e))throw new Error('Signature format must be "compact", "recovered", or "der"');return e}function validateSigOpts(e,t){const r={};for(let n of Object.keys(t))r[n]=void 0===e[n]?t[n]:e[n];return abool$1(r.lowS,"lowS"),abool$1(r.prehash,"prehash"),void 0!==r.format&&validateSigFormat(r.format),r}class DERErr extends Error{constructor(e=""){super(e)}}const DER={Err:DERErr,_tlv:{encode:(e,t)=>{const{Err:r}=DER;if(e<0||e>256)throw new r("tlv.encode: wrong tag");if(1&t.length)throw new r("tlv.encode: unpadded data");const n=t.length/2,i=numberToHexUnpadded(n);if(i.length/2&128)throw new r("tlv.encode: long form length too big");const o=n>127?numberToHexUnpadded(i.length/2|128):"";return numberToHexUnpadded(e)+o+i+t},decode(e,t){const{Err:r}=DER;let n=0;if(e<0||e>256)throw new r("tlv.encode: wrong tag");if(t.length<2||t[n++]!==e)throw new r("tlv.decode: wrong tlv");const i=t[n++];let o=0;if(128&i){const e=127&i;if(!e)throw new r("tlv.decode(long): indefinite length not supported");if(e>4)throw new r("tlv.decode(long): byte length is too big");const s=t.subarray(n,n+e);if(s.length!==e)throw new r("tlv.decode: length bytes not complete");if(0===s[0])throw new r("tlv.decode(long): zero leftmost byte");for(const t of s)o=o<<8|t;if(n+=e,o<128)throw new r("tlv.decode(long): not minimal encoding")}else o=i;const s=t.subarray(n,n+o);if(s.length!==o)throw new r("tlv.decode: wrong value length");return{v:s,l:t.subarray(n+o)}}},_int:{encode(e){const{Err:t}=DER;if(e<_0n$1)throw new t("integer: negative integers are not allowed");let r=numberToHexUnpadded(e);if(8&Number.parseInt(r[0],16)&&(r="00"+r),1&r.length)throw new t("unexpected DER parsing assertion: unpadded hex");return r},decode(e){const{Err:t}=DER;if(128&e[0])throw new t("invalid signature integer: negative");if(0===e[0]&&!(128&e[1]))throw new t("invalid signature integer: unnecessary leading zero");return bytesToNumberBE(e)}},toSig(e){const{Err:t,_int:r,_tlv:n}=DER,i=abytes$2(e,void 0,"signature"),{v:o,l:s}=n.decode(48,i);if(s.length)throw new t("invalid signature: left bytes after parsing");const{v:a,l:l}=n.decode(2,o),{v:c,l:u}=n.decode(2,l);if(u.length)throw new t("invalid signature: left bytes after parsing");return{r:r.decode(a),s:r.decode(c)}},hexFromSig(e){const{_tlv:t,_int:r}=DER,n=t.encode(2,r.encode(e.r))+t.encode(2,r.encode(e.s));return t.encode(48,n)}},_0n$1=BigInt(0),_1n=BigInt(1),_2n$1=BigInt(2),_3n=BigInt(3),_4n=BigInt(4);function weierstrass(e,t={}){const r=createCurveFields("weierstrass",e,t),{Fp:n,Fn:i}=r;let o=r.CURVE;const{h:s,n:a}=o;validateObject(t,{},{allowInfinityPoint:"boolean",clearCofactor:"function",isTorsionFree:"function",fromBytes:"function",toBytes:"function",endo:"object"});const{endo:l}=t;if(l&&(!n.is0(o.a)||"bigint"!=typeof l.beta||!Array.isArray(l.basises)))throw new Error('invalid endo: expected "beta": bigint and "basises": array');const c=getWLengths(n,i);function u(){if(!n.isOdd)throw new Error("compression is not supported: Field does not have .isOdd()")}const h=t.toBytes||function(e,t,r){const{x:i,y:o}=t.toAffine(),s=n.toBytes(i);return abool$1(r,"isCompressed"),r?(u(),concatBytes(pprefix(!n.isOdd(o)),s)):concatBytes(Uint8Array.of(4),s,n.toBytes(o))},d=t.fromBytes||function(e){abytes$2(e,void 0,"Point");const{publicKey:t,publicKeyUncompressed:r}=c,i=e.length,o=e[0],s=e.subarray(1);if(i!==t||2!==o&&3!==o){if(i===r&&4===o){const e=n.BYTES,t=n.fromBytes(s.subarray(0,e)),r=n.fromBytes(s.subarray(e,2*e));if(!f(t,r))throw new Error("bad point: is not on curve");return{x:t,y:r}}throw new Error(`bad point: got length ${i}, expected compressed=${t} or uncompressed=${r}`)}{const e=n.fromBytes(s);if(!n.isValid(e))throw new Error("bad point: is not on curve, wrong x");const t=p(e);let r;try{r=n.sqrt(t)}catch(a){const e=a instanceof Error?": "+a.message:"";throw new Error("bad point: is not on curve, sqrt error"+e)}return u(),!(1&~o)!==n.isOdd(r)&&(r=n.neg(r)),{x:e,y:r}}};function p(e){const t=n.sqr(e),r=n.mul(t,e);return n.add(n.add(r,n.mul(e,o.a)),o.b)}function f(e,t){const r=n.sqr(t),i=p(e);return n.eql(r,i)}if(!f(o.Gx,o.Gy))throw new Error("bad curve params: generator point");const g=n.mul(n.pow(o.a,_3n),_4n),m=n.mul(n.sqr(o.b),BigInt(27));if(n.is0(n.add(g,m)))throw new Error("bad curve params: a or b");function y(e,t,r=!1){if(!n.isValid(t)||r&&n.is0(t))throw new Error(`bad point coordinate ${e}`);return t}function b(e){if(!(e instanceof C))throw new Error("Weierstrass Point expected")}function v(e){if(!l||!l.basises)throw new Error("no endo");return _splitEndoScalar(e,l.basises,i.OLine truncated
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */const secp256k1_CURVE={p:BigInt("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"),n:BigInt("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"),h:BigInt(1),a:BigInt(0),b:BigInt(7),Gx:BigInt("0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"),Gy:BigInt("0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8")},secp256k1_ENDO={beta:BigInt("0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee"),basises:[[BigInt("0x3086d221a7d46bcde86c90e49284eb15"),-BigInt("0xe4437ed6010e88286f547fa90abfe4c3")],[BigInt("0x114ca50f7a8e2f3f657c1108d9d44cfd8"),BigInt("0x3086d221a7d46bcde86c90e49284eb15")]]},_0n=BigInt(0),_2n=BigInt(2);function sqrtMod(e){const t=secp256k1_CURVE.p,r=BigInt(3),n=BigInt(6),i=BigInt(11),o=BigInt(22),s=BigInt(23),a=BigInt(44),l=BigInt(88),c=e*e*e%t,u=c*c*e%t,h=pow2(u,r,t)*u%t,d=pow2(h,r,t)*u%t,p=pow2(d,_2n,t)*c%t,f=pow2(p,i,t)*p%t,g=pow2(f,o,t)*f%t,m=pow2(g,a,t)*g%t,y=pow2(m,l,t)*m%t,b=pow2(y,a,t)*g%t,v=pow2(b,r,t)*u%t,_=pow2(v,s,t)*f%t,E=pow2(_,n,t)*c%t,w=pow2(E,_2n,t);if(!Fpk1.eql(Fpk1.sqr(w),e))throw new Error("Cannot find square root");return w}const Fpk1=Field(secp256k1_CURVE.p,{sqrt:sqrtMod}),Pointk1=weierstrass(secp256k1_CURVE,{Fp:Fpk1,endo:secp256k1_ENDO}),secp256k1=ecdsa(Pointk1,sha256),TAGGED_HASH_PREFIXES={};function taggedHash(e,...t){let r=TAGGED_HASH_PREFIXES[e];if(void 0===r){const t=sha256(asciiToBytes(e));r=concatBytes(t,t),TAGGED_HASH_PREFIXES[e]=r}return sha256(concatBytes(r,...t))}const pointToBytes=e=>e.toBytes(!0).slice(1),hasEven=e=>e%_2n===_0n;function schnorrGetExtPubKey(e){const{Fn:t,BASE:r}=Pointk1,n=t.fromBytes(e),i=r.multiply(n);return{scalar:hasEven(i.y)?n:t.neg(n),bytes:pointToBytes(i)}}function lift_x(e){const t=Fpk1;if(!t.isValidNot0(e))throw new Error("invalid x: Fail if x ≥ p");const r=t.create(e*e),n=t.create(r*e+BigInt(7));let i=t.sqrt(n);hasEven(i)||(i=t.neg(i));const o=Pointk1.fromAffine({x:e,y:i});return o.assertValidity(),o}const num=bytesToNumberBE;function challenge(...e){return Pointk1.Fn.create(num(taggedHash("BIP0340/challenge",...e)))}function schnorrGetPublicKey(e){return schnorrGetExtPubKey(e).bytes}function schnorrSign(e,t,r=randomBytes(32)){const{Fn:n}=Pointk1,i=abytes$2(e,void 0,"message"),{bytes:o,scalar:s}=schnorrGetExtPubKey(t),a=abytes$2(r,32,"auxRand"),l=n.toBytes(s^num(taggedHash("BIP0340/aux",a))),c=taggedHash("BIP0340/nonce",l,o,i),{bytes:u,scalar:h}=schnorrGetExtPubKey(c),d=challenge(u,o,i),p=new Uint8Array(64);if(p.set(u,0),p.set(n.toBytes(n.create(h+d*s)),32),!schnorrVerify(p,i,o))throw new Error("sign: Invalid signature produced");return p}function schnorrVerify(e,t,r){const{Fp:n,Fn:i,BASE:o}=Pointk1,s=abytes$2(e,64,"signature"),a=abytes$2(t,void 0,"message"),l=abytes$2(r,32,"publicKey");try{const e=lift_x(num(l)),t=num(s.subarray(0,32));if(!n.isValidNot0(t))return!1;const r=num(s.subarray(32,64));if(!i.isValidNot0(r))return!1;const c=challenge(i.toBytes(t),pointToBytes(e),a),u=o.multiplyUnsafe(r).add(e.multiplyUnsafe(i.neg(c))),{x:h,y:d}=u.toAffine();return!(u.is0()||!hasEven(d)||h!==t)}catch(error){return!1}}const schnorr=(()=>{const e=(e=randomBytes(48))=>mapHashToField(e,secp256k1_CURVE.n);return{keygen:createKeygen(e,schnorrGetPublicKey),getPublicKey:schnorrGetPublicKey,sign:schnorrSign,verify:schnorrVerify,Point:Pointk1,utils:{randomSecretKey:e,taggedHash:taggedHash,lift_x:lift_x,pointToBytes:pointToBytes},lengths:{secretKey:32,publicKey:32,publicKeyHasPrefix:!1,signature:64,seed:48}}})(); /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */const secp256k1_CURVE={p:BigInt("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"),n:BigInt("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"),h:BigInt(1),a:BigInt(0),b:BigInt(7),Gx:BigInt("0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"),Gy:BigInt("0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8")},secp256k1_ENDO={beta:BigInt("0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee"),basises:[[BigInt("0x3086d221a7d46bcde86c90e49284eb15"),-BigInt("0xe4437ed6010e88286f547fa90abfe4c3")],[BigInt("0x114ca50f7a8e2f3f657c1108d9d44cfd8"),BigInt("0x3086d221a7d46bcde86c90e49284eb15")]]},_0n=BigInt(0),_2n=BigInt(2);function sqrtMod(e){const t=secp256k1_CURVE.p,r=BigInt(3),n=BigInt(6),i=BigInt(11),o=BigInt(22),s=BigInt(23),a=BigInt(44),l=BigInt(88),c=e*e*e%t,u=c*c*e%t,h=pow2(u,r,t)*u%t,d=pow2(h,r,t)*u%t,p=pow2(d,_2n,t)*c%t,f=pow2(p,i,t)*p%t,g=pow2(f,o,t)*f%t,m=pow2(g,a,t)*g%t,y=pow2(m,l,t)*m%t,b=pow2(y,a,t)*g%t,v=pow2(b,r,t)*u%t,_=pow2(v,s,t)*f%t,E=pow2(_,n,t)*c%t,w=pow2(E,_2n,t);if(!Fpk1.eql(Fpk1.sqr(w),e))throw new Error("Cannot find square root");return w}const Fpk1=Field(secp256k1_CURVE.p,{sqrt:sqrtMod}),Pointk1=weierstrass(secp256k1_CURVE,{Fp:Fpk1,endo:secp256k1_ENDO}),secp256k1=ecdsa(Pointk1,sha256),TAGGED_HASH_PREFIXES={};function taggedHash(e,...t){let r=TAGGED_HASH_PREFIXES[e];if(void 0===r){const t=sha256(asciiToBytes(e));r=concatBytes(t,t),TAGGED_HASH_PREFIXES[e]=r}return sha256(concatBytes(r,...t))}const pointToBytes=e=>e.toBytes(!0).slice(1),hasEven=e=>e%_2n===_0n;function schnorrGetExtPubKey(e){const{Fn:t,BASE:r}=Pointk1,n=t.fromBytes(e),i=r.multiply(n);return{scalar:hasEven(i.y)?n:t.neg(n),bytes:pointToBytes(i)}}function lift_x(e){const t=Fpk1;if(!t.isValidNot0(e))throw new Error("invalid x: Fail if x ≥ p");const r=t.create(e*e),n=t.create(r*e+BigInt(7));let i=t.sqrt(n);hasEven(i)||(i=t.neg(i));const o=Pointk1.fromAffine({x:e,y:i});return o.assertValidity(),o}const num=bytesToNumberBE;function challenge(...e){return Pointk1.Fn.create(num(taggedHash("BIP0340/challenge",...e)))}function schnorrGetPublicKey(e){return schnorrGetExtPubKey(e).bytes}function schnorrSign(e,t,r=randomBytes(32)){const{Fn:n}=Pointk1,i=abytes$2(e,void 0,"message"),{bytes:o,scalar:s}=schnorrGetExtPubKey(t),a=abytes$2(r,32,"auxRand"),l=n.toBytes(s^num(taggedHash("BIP0340/aux",a))),c=taggedHash("BIP0340/nonce",l,o,i),{bytes:u,scalar:h}=schnorrGetExtPubKey(c),d=challenge(u,o,i),p=new Uint8Array(64);if(p.set(u,0),p.set(n.toBytes(n.create(h+d*s)),32),!schnorrVerify(p,i,o))throw new Error("sign: Invalid signature produced");return p}function schnorrVerify(e,t,r){const{Fp:n,Fn:i,BASE:o}=Pointk1,s=abytes$2(e,64,"signature"),a=abytes$2(t,void 0,"message"),l=abytes$2(r,32,"publicKey");try{const e=lift_x(num(l)),t=num(s.subarray(0,32));if(!n.isValidNot0(t))return!1;const r=num(s.subarray(32,64));if(!i.isValidNot0(r))return!1;const c=challenge(i.toBytes(t),pointToBytes(e),a),u=o.multiplyUnsafe(r).add(e.multiplyUnsafe(i.neg(c))),{x:h,y:d}=u.toAffine();return!(u.is0()||!hasEven(d)||h!==t)}catch(error){return!1}}const schnorr=(()=>{const e=(e=randomBytes(48))=>mapHashToField(e,secp256k1_CURVE.n);return{keygen:createKeygen(e,schnorrGetPublicKey),getPublicKey:schnorrGetPublicKey,sign:schnorrSign,verify:schnorrVerify,Point:Pointk1,utils:{randomSecretKey:e,taggedHash:taggedHash,lift_x:lift_x,pointToBytes:pointToBytes},lengths:{secretKey:32,publicKey:32,publicKeyHasPrefix:!1,signature:64,seed:48}}})();
/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */function isBytes$1(e){return e instanceof Uint8Array||ArrayBuffer.isView(e)&&"Uint8Array"===e.constructor.name}function abytes$1(e){if(!isBytes$1(e))throw new Error("Uint8Array expected")}function isArrayOf(e,t){return!!Array.isArray(t)&&(0===t.length||(e?t.every(e=>"string"==typeof e):t.every(e=>Number.isSafeInteger(e))))}function afn(e){if("function"!=typeof e)throw new Error("function expected");return!0}function astr(e,t){if("string"!=typeof t)throw new Error(`${e}: string expected`);return!0}function anumber$1(e){if(!Number.isSafeInteger(e))throw new Error(`invalid integer: ${e}`)}function aArr(e){if(!Array.isArray(e))throw new Error("array expected")}function astrArr(e,t){if(!isArrayOf(!0,t))throw new Error(`${e}: array of strings expected`)}function anumArr(e,t){if(!isArrayOf(!1,t))throw new Error(`${e}: array of numbers expected`)}function chain(...e){const t=e=>e,r=(e,t)=>r=>e(t(r)),n=e.map(e=>e.encode).reduceRight(r,t),i=e.map(e=>e.decode).reduce(r,t);return{encode:n,decode:i}}function alphabet(e){const t="string"==typeof e?e.split(""):e,r=t.length;astrArr("alphabet",t);const n=new Map(t.map((e,t)=>[e,t]));return{encode:n=>(aArr(n),n.map(n=>{if(!Number.isSafeInteger(n)||n<0||n>=r)throw new Error(`alphabet.encode: digit index outside alphabet "${n}". Allowed: ${e}`);return t[n]})),decode:t=>(aArr(t),t.map(t=>{astr("alphabet.decode",t);const r=n.get(t);if(void 0===r)throw new Error(`Unknown letter: "${t}". Allowed: ${e}`);return r}))}}function join(e=""){return astr("join",e),{encode:t=>(astrArr("join.decode",t),t.join(e)),decode:t=>(astr("join.decode",t),t.split(e))}}function padding(e,t="="){return anumber$1(e),astr("padding",t),{encode(r){for(astrArr("padding.encode",r);r.length*e%8;)r.push(t);return r},decode(r){astrArr("padding.decode",r);let n=r.length;if(n*e%8)throw new Error("padding: invalid, string should have whole number of bytes");for(;n>0&&r[n-1]===t;n--)if((n-1)*e%8==0)throw new Error("padding: invalid, string has too much padding");return r.slice(0,n)}}}const gcd=(e,t)=>0===t?e:gcd(t,e%t),radix2carry=(e,t)=>e+(t-gcd(e,t)),powers=(()=>{let e=[];for(let t=0;t<40;t++)e.push(2**t);return e})();function convertRadix2(e,t,r,n){if(aArr(e),t<=0||t>32)throw new Error(`convertRadix2: wrong from=${t}`);if(r<=0||r>32)throw new Error(`convertRadix2: wrong to=${r}`);if(radix2carry(t,r)>32)throw new Error(`convertRadix2: carry overflow from=${t} to=${r} carryBits=${radix2carry(t,r)}`);let i=0,o=0;const s=powers[t],a=powers[r]-1,l=[];for(const c of e){if(anumber$1(c),c>=s)throw new Error(`convertRadix2: invalid data word=${c} from=${t}`);if(i=i<<t|c,o+t>32)throw new Error(`convertRadix2: carry overflow pos=${o} from=${t}`);for(o+=t;o>=r;o-=r)l.push((i>>o-r&a)>>>0);const e=powers[o];if(void 0===e)throw new Error("invalid carry");i&=e-1}if(i=i<<r-o&a,!n&&o>=t)throw new Error("Excess padding");if(!n&&i>0)throw new Error(`Non-zero padding: ${i}`);return n&&o>0&&l.push(i>>>0),l}function radix2(e,t=!1){if(anumber$1(e),e<=0||e>32)throw new Error("radix2: bits should be in (0..32]");if(radix2carry(8,e)>32||radix2carry(e,8)>32)throw new Error("radix2: carry overflow");return{encode:r=>{if(!isBytes$1(r))throw new Error("radix2.encode input should be Uint8Array");return convertRadix2(Array.from(r),8,e,!t)},decode:r=>(anumArr("radix2.decode",r),Uint8Array.from(convertRadix2(r,e,8,t)))}}function unsafeWrapper(e){return afn(e),function(...t){try{return e.apply(null,t)}catch(r){}}}const hasBase64Builtin=(()=>"function"==typeof Uint8Array.from([]).toBase64&&"function"==typeof Uint8Array.fromBase64)(),decodeBase64Builtin=e=>{if(astr("base64",e),e.length>0&&!/^[A-Za-z0-9=+/]+$/.test(e))throw new Error("invalid base64");return Uint8Array.fromBase64(e,{alphabet:"base64",lastChunkHandling:"strict"})},base64=hasBase64Builtin?{encode:e=>(abytes$1(e),e.toBase64()),decode:e=>decodeBase64Builtin(e)}:chain(radix2(6),alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"),padding(6),join("")),BECH_ALPHABET=chain(alphabet("qpzry9x8gf2tvdw0s3jn54khce6mua7l"),join("")),POLYMOD_GENERATORS=[996825010,642813549,513874426,1027748829,705979059];function bech32Polymod(e){const t=e>>25;let r=(33554431&e)<<5;for(let n=0;n<POLYMOD_GENERATORS.length;n++)1==(t>>n&1)&&(r^=POLYMOD_GENERATORS[n]);return r}function bechChecksum(e,t,r=1){const n=e.length;let i=1;for(let o=0;o<n;o++){const t=e.charCodeAt(o);if(t<33||t>126)throw new Error(`Invalid prefix (${e})`);i=bech32Polymod(i)^t>>5}i=bech32Polymod(i);for(let o=0;o<n;o++)i=bech32Polymod(i)^31&e.charCodeAt(o);for(let o of t)i=bech32Polymod(i)^o;for(let o=0;o<6;o++)i=bech32Polymod(i);return i^=r,BECH_ALPHABET.encode(convertRadix2([i%powers[30]],30,5,!1))}function genBech32(e){const t="bech32"===e?1:734539939,r=radix2(5),n=r.decode,i=r.encode,o=unsafeWrapper(n);function s(e,r,n=90){astr("bech32.encode prefix",e),isBytes$1(r)&&(r=Array.from(r)),anumArr("bech32.encode",r);const i=e.length;if(0===i)throw new TyLine truncated /*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */function isBytes$1(e){return e instanceof Uint8Array||ArrayBuffer.isView(e)&&"Uint8Array"===e.constructor.name}function abytes$1(e){if(!isBytes$1(e))throw new Error("Uint8Array expected")}function isArrayOf(e,t){return!!Array.isArray(t)&&(0===t.length||(e?t.every(e=>"string"==typeof e):t.every(e=>Number.isSafeInteger(e))))}function afn(e){if("function"!=typeof e)throw new Error("function expected");return!0}function astr(e,t){if("string"!=typeof t)throw new Error(`${e}: string expected`);return!0}function anumber$1(e){if(!Number.isSafeInteger(e))throw new Error(`invalid integer: ${e}`)}function aArr(e){if(!Array.isArray(e))throw new Error("array expected")}function astrArr(e,t){if(!isArrayOf(!0,t))throw new Error(`${e}: array of strings expected`)}function anumArr(e,t){if(!isArrayOf(!1,t))throw new Error(`${e}: array of numbers expected`)}function chain(...e){const t=e=>e,r=(e,t)=>r=>e(t(r)),n=e.map(e=>e.encode).reduceRight(r,t),i=e.map(e=>e.decode).reduce(r,t);return{encode:n,decode:i}}function alphabet(e){const t="string"==typeof e?e.split(""):e,r=t.length;astrArr("alphabet",t);const n=new Map(t.map((e,t)=>[e,t]));return{encode:n=>(aArr(n),n.map(n=>{if(!Number.isSafeInteger(n)||n<0||n>=r)throw new Error(`alphabet.encode: digit index outside alphabet "${n}". Allowed: ${e}`);return t[n]})),decode:t=>(aArr(t),t.map(t=>{astr("alphabet.decode",t);const r=n.get(t);if(void 0===r)throw new Error(`Unknown letter: "${t}". Allowed: ${e}`);return r}))}}function join(e=""){return astr("join",e),{encode:t=>(astrArr("join.decode",t),t.join(e)),decode:t=>(astr("join.decode",t),t.split(e))}}function padding(e,t="="){return anumber$1(e),astr("padding",t),{encode(r){for(astrArr("padding.encode",r);r.length*e%8;)r.push(t);return r},decode(r){astrArr("padding.decode",r);let n=r.length;if(n*e%8)throw new Error("padding: invalid, string should have whole number of bytes");for(;n>0&&r[n-1]===t;n--)if((n-1)*e%8==0)throw new Error("padding: invalid, string has too much padding");return r.slice(0,n)}}}const gcd=(e,t)=>0===t?e:gcd(t,e%t),radix2carry=(e,t)=>e+(t-gcd(e,t)),powers=(()=>{let e=[];for(let t=0;t<40;t++)e.push(2**t);return e})();function convertRadix2(e,t,r,n){if(aArr(e),t<=0||t>32)throw new Error(`convertRadix2: wrong from=${t}`);if(r<=0||r>32)throw new Error(`convertRadix2: wrong to=${r}`);if(radix2carry(t,r)>32)throw new Error(`convertRadix2: carry overflow from=${t} to=${r} carryBits=${radix2carry(t,r)}`);let i=0,o=0;const s=powers[t],a=powers[r]-1,l=[];for(const c of e){if(anumber$1(c),c>=s)throw new Error(`convertRadix2: invalid data word=${c} from=${t}`);if(i=i<<t|c,o+t>32)throw new Error(`convertRadix2: carry overflow pos=${o} from=${t}`);for(o+=t;o>=r;o-=r)l.push((i>>o-r&a)>>>0);const e=powers[o];if(void 0===e)throw new Error("invalid carry");i&=e-1}if(i=i<<r-o&a,!n&&o>=t)throw new Error("Excess padding");if(!n&&i>0)throw new Error(`Non-zero padding: ${i}`);return n&&o>0&&l.push(i>>>0),l}function radix2(e,t=!1){if(anumber$1(e),e<=0||e>32)throw new Error("radix2: bits should be in (0..32]");if(radix2carry(8,e)>32||radix2carry(e,8)>32)throw new Error("radix2: carry overflow");return{encode:r=>{if(!isBytes$1(r))throw new Error("radix2.encode input should be Uint8Array");return convertRadix2(Array.from(r),8,e,!t)},decode:r=>(anumArr("radix2.decode",r),Uint8Array.from(convertRadix2(r,e,8,t)))}}function unsafeWrapper(e){return afn(e),function(...t){try{return e.apply(null,t)}catch(r){}}}const hasBase64Builtin=(()=>"function"==typeof Uint8Array.from([]).toBase64&&"function"==typeof Uint8Array.fromBase64)(),decodeBase64Builtin=e=>{if(astr("base64",e),e.length>0&&!/^[A-Za-z0-9=+/]+$/.test(e))throw new Error("invalid base64");return Uint8Array.fromBase64(e,{alphabet:"base64",lastChunkHandling:"strict"})},base64=hasBase64Builtin?{encode:e=>(abytes$1(e),e.toBase64()),decode:e=>decodeBase64Builtin(e)}:chain(radix2(6),alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"),padding(6),join("")),BECH_ALPHABET=chain(alphabet("qpzry9x8gf2tvdw0s3jn54khce6mua7l"),join("")),POLYMOD_GENERATORS=[996825010,642813549,513874426,1027748829,705979059];function bech32Polymod(e){const t=e>>25;let r=(33554431&e)<<5;for(let n=0;n<POLYMOD_GENERATORS.length;n++)1==(t>>n&1)&&(r^=POLYMOD_GENERATORS[n]);return r}function bechChecksum(e,t,r=1){const n=e.length;let i=1;for(let o=0;o<n;o++){const t=e.charCodeAt(o);if(t<33||t>126)throw new Error(`Invalid prefix (${e})`);i=bech32Polymod(i)^t>>5}i=bech32Polymod(i);for(let o=0;o<n;o++)i=bech32Polymod(i)^31&e.charCodeAt(o);for(let o of t)i=bech32Polymod(i)^o;for(let o=0;o<6;o++)i=bech32Polymod(i);return i^=r,BECH_ALPHABET.encode(convertRadix2([i%powers[30]],30,5,!1))}function genBech32(e){const t="bech32"===e?1:734539939,r=radix2(5),n=r.decode,i=r.encode,o=unsafeWrapper(n);function s(e,r,n=90){astr("bech32.encode prefix",e),isBytes$1(r)&&(r=Array.from(r)),anumArr("bech32.encode",r);const i=e.length;if(0===i)throw new TyLine truncated
/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */function isBytes(e){return e instanceof Uint8Array||ArrayBuffer.isView(e)&&"Uint8Array"===e.constructor.name}function abool(e){if("boolean"!=typeof e)throw new Error(`boolean expected, not ${e}`)}function anumber(e){if(!Number.isSafeInteger(e)||e<0)throw new Error("positive integer expected, got "+e)}function abytes(e,t,r=""){const n=isBytes(e),i=e?.length,o=void 0!==t;if(!n||o&&i!==t)throw new Error((r&&`"${r}" `)+"expected Uint8Array"+(o?` of length ${t}`:"")+", got "+(n?`length=${i}`:"type="+typeof e));return e}function u32(e){return new Uint32Array(e.buffer,e.byteOffset,Math.floor(e.byteLength/4))}function clean(...e){for(let t=0;t<e.length;t++)e[t].fill(0)}const isLE=(()=>68===new Uint8Array(new Uint32Array([287454020]).buffer)[0])();function overlapBytes(e,t){return e.buffer===t.buffer&&e.byteOffset<t.byteOffset+t.byteLength&&t.byteOffset<e.byteOffset+e.byteLength}function complexOverlapBytes(e,t){if(overlapBytes(e,t)&&e.byteOffset<t.byteOffset)throw new Error("complex overlap of input and output is not supported")}function checkOpts(e,t){if(null==t||"object"!=typeof t)throw new Error("options must be defined");return Object.assign(e,t)}function equalBytes(e,t){if(e.length!==t.length)return!1;let r=0;for(let n=0;n<e.length;n++)r|=e[n]^t[n];return 0===r}const wrapCipher=(e,t)=>{function r(r,...n){if(abytes(r,void 0,"key"),!isLE)throw new Error("Non little-endian hardware is not yet supported");void 0!==e.nonceLength&&abytes(n[0],e.varSizeNonce?void 0:e.nonceLength,"nonce");const i=e.tagLength;i&&void 0!==n[1]&&abytes(n[1],void 0,"AAD");const o=t(r,...n),s=(e,t)=>{if(void 0!==t){if(2!==e)throw new Error("cipher output not supported");abytes(t,void 0,"output")}};let a=!1;const l={encrypt(e,t){if(a)throw new Error("cannot encrypt() twice with same key + nonce");return a=!0,abytes(e),s(o.encrypt.length,t),o.encrypt(e,t)},decrypt(e,t){if(abytes(e),i&&e.length<i)throw new Error('"ciphertext" expected length bigger than tagLength='+i);return s(o.decrypt.length,t),o.decrypt(e,t)}};return l}return Object.assign(r,e),r};function getOutput(e,t,r=!0){if(void 0===t)return new Uint8Array(e);if(t.length!==e)throw new Error('"output" expected Uint8Array of length '+e+", got: "+t.length);if(r&&!isAligned32$1(t))throw new Error("invalid output, must be aligned");return t}function isAligned32$1(e){return e.byteOffset%4==0}function copyBytes(e){return Uint8Array.from(e)}const BLOCK_SIZE=16,POLY=283;function validateKeyLength(e){if(![16,24,32].includes(e.length))throw new Error('"aes key" expected Uint8Array of length 16/24/32, got length='+e.length)}function mul2(e){return e<<1^POLY&-(e>>7)}function mul(e,t){let r=0;for(;t>0;t>>=1)r^=e&-(1&t),e=mul2(e);return r}const sbox=(()=>{const e=new Uint8Array(256);for(let r=0,n=1;r<256;r++,n^=mul2(n))e[r]=n;const t=new Uint8Array(256);t[0]=99;for(let r=0;r<255;r++){let n=e[255-r];n|=n<<8,t[e[r]]=255&(n^n>>4^n>>5^n>>6^n>>7^99)}return clean(e),t})(),invSbox=sbox.map((e,t)=>sbox.indexOf(t)),rotr32_8=e=>e<<24|e>>>8,rotl32_8=e=>e<<8|e>>>24;function genTtable(e,t){if(256!==e.length)throw new Error("Wrong sbox length");const r=new Uint32Array(256).map((r,n)=>t(e[n])),n=r.map(rotl32_8),i=n.map(rotl32_8),o=i.map(rotl32_8),s=new Uint32Array(65536),a=new Uint32Array(65536),l=new Uint16Array(65536);for(let c=0;c<256;c++)for(let t=0;t<256;t++){const u=256*c+t;s[u]=r[c]^n[t],a[u]=i[c]^o[t],l[u]=e[c]<<8|e[t]}return{sbox:e,sbox2:l,T0:r,T1:n,T2:i,T3:o,T01:s,T23:a}}const tableEncoding=genTtable(sbox,e=>mul(e,3)<<24|e<<16|e<<8|mul(e,2)),tableDecoding=genTtable(invSbox,e=>mul(e,11)<<24|mul(e,13)<<16|mul(e,9)<<8|mul(e,14)),xPowers=(()=>{const e=new Uint8Array(16);for(let t=0,r=1;t<16;t++,r=mul2(r))e[t]=r;return e})();function expandKeyLE(e){abytes(e);const t=e.length;validateKeyLength(e);const{sbox2:r}=tableEncoding,n=[];isAligned32$1(e)||n.push(e=copyBytes(e));const i=u32(e),o=i.length,s=e=>applySbox(r,e,e,e,e),a=new Uint32Array(t+28);a.set(i);for(let l=o;l<a.length;l++){let e=a[l-1];l%o===0?e=s(rotr32_8(e))^xPowers[l/o-1]:o>6&&l%o===4&&(e=s(e)),a[l]=a[l-o]^e}return clean(...n),a}function expandKeyDecLE(e){const t=expandKeyLE(e),r=t.slice(),n=t.length,{sbox2:i}=tableEncoding,{T0:o,T1:s,T2:a,T3:l}=tableDecoding;for(let c=0;c<n;c+=4)for(let e=0;e<4;e++)r[c+e]=t[n-c-4+e];clean(t);for(let c=4;c<n-4;c++){const e=r[c],t=applySbox(i,e,e,e,e);r[c]=o[255&t]^s[t>>>8&255]^a[t>>>16&255]^l[t>>>24]}return r}function apply0123(e,t,r,n,i,o){return e[r<<8&65280|n>>>8&255]^t[i>>>8&65280|o>>>24&255]}function applySbox(e,t,r,n,i){return e[255&t|65280&r]|e[n>>>16&255|i>>>16&65280]<<16}function encrypt$1(e,t,r,n,i){const{sbox2:o,T01:s,T23:a}=tableEncoding;let l=0;t^=e[l++],r^=e[l++],n^=e[l++],i^=e[l++];const c=e.length/4-2;for(let u=0;u<c;u++){const o=e[l++]^apply0123(s,a,t,r,n,i),c=e[l++]^apply0123(s,a,r,n,i,t),u=e[l++]^apply0123(s,a,n,i,t,r),h=e[l++]^apply0123(s,a,i,t,r,n);t=o,r=c,n=u,i=h}return{s0:e[l++]^applySbox(o,t,r,n,i),s1:e[l++]^applySbox(o,rLine truncated /*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */function isBytes(e){return e instanceof Uint8Array||ArrayBuffer.isView(e)&&"Uint8Array"===e.constructor.name}function abool(e){if("boolean"!=typeof e)throw new Error(`boolean expected, not ${e}`)}function anumber(e){if(!Number.isSafeInteger(e)||e<0)throw new Error("positive integer expected, got "+e)}function abytes(e,t,r=""){const n=isBytes(e),i=e?.length,o=void 0!==t;if(!n||o&&i!==t)throw new Error((r&&`"${r}" `)+"expected Uint8Array"+(o?` of length ${t}`:"")+", got "+(n?`length=${i}`:"type="+typeof e));return e}function u32(e){return new Uint32Array(e.buffer,e.byteOffset,Math.floor(e.byteLength/4))}function clean(...e){for(let t=0;t<e.length;t++)e[t].fill(0)}const isLE=(()=>68===new Uint8Array(new Uint32Array([287454020]).buffer)[0])();function overlapBytes(e,t){return e.buffer===t.buffer&&e.byteOffset<t.byteOffset+t.byteLength&&t.byteOffset<e.byteOffset+e.byteLength}function complexOverlapBytes(e,t){if(overlapBytes(e,t)&&e.byteOffset<t.byteOffset)throw new Error("complex overlap of input and output is not supported")}function checkOpts(e,t){if(null==t||"object"!=typeof t)throw new Error("options must be defined");return Object.assign(e,t)}function equalBytes(e,t){if(e.length!==t.length)return!1;let r=0;for(let n=0;n<e.length;n++)r|=e[n]^t[n];return 0===r}const wrapCipher=(e,t)=>{function r(r,...n){if(abytes(r,void 0,"key"),!isLE)throw new Error("Non little-endian hardware is not yet supported");void 0!==e.nonceLength&&abytes(n[0],e.varSizeNonce?void 0:e.nonceLength,"nonce");const i=e.tagLength;i&&void 0!==n[1]&&abytes(n[1],void 0,"AAD");const o=t(r,...n),s=(e,t)=>{if(void 0!==t){if(2!==e)throw new Error("cipher output not supported");abytes(t,void 0,"output")}};let a=!1;const l={encrypt(e,t){if(a)throw new Error("cannot encrypt() twice with same key + nonce");return a=!0,abytes(e),s(o.encrypt.length,t),o.encrypt(e,t)},decrypt(e,t){if(abytes(e),i&&e.length<i)throw new Error('"ciphertext" expected length bigger than tagLength='+i);return s(o.decrypt.length,t),o.decrypt(e,t)}};return l}return Object.assign(r,e),r};function getOutput(e,t,r=!0){if(void 0===t)return new Uint8Array(e);if(t.length!==e)throw new Error('"output" expected Uint8Array of length '+e+", got: "+t.length);if(r&&!isAligned32$1(t))throw new Error("invalid output, must be aligned");return t}function isAligned32$1(e){return e.byteOffset%4==0}function copyBytes(e){return Uint8Array.from(e)}const BLOCK_SIZE=16,POLY=283;function validateKeyLength(e){if(![16,24,32].includes(e.length))throw new Error('"aes key" expected Uint8Array of length 16/24/32, got length='+e.length)}function mul2(e){return e<<1^POLY&-(e>>7)}function mul(e,t){let r=0;for(;t>0;t>>=1)r^=e&-(1&t),e=mul2(e);return r}const sbox=(()=>{const e=new Uint8Array(256);for(let r=0,n=1;r<256;r++,n^=mul2(n))e[r]=n;const t=new Uint8Array(256);t[0]=99;for(let r=0;r<255;r++){let n=e[255-r];n|=n<<8,t[e[r]]=255&(n^n>>4^n>>5^n>>6^n>>7^99)}return clean(e),t})(),invSbox=sbox.map((e,t)=>sbox.indexOf(t)),rotr32_8=e=>e<<24|e>>>8,rotl32_8=e=>e<<8|e>>>24;function genTtable(e,t){if(256!==e.length)throw new Error("Wrong sbox length");const r=new Uint32Array(256).map((r,n)=>t(e[n])),n=r.map(rotl32_8),i=n.map(rotl32_8),o=i.map(rotl32_8),s=new Uint32Array(65536),a=new Uint32Array(65536),l=new Uint16Array(65536);for(let c=0;c<256;c++)for(let t=0;t<256;t++){const u=256*c+t;s[u]=r[c]^n[t],a[u]=i[c]^o[t],l[u]=e[c]<<8|e[t]}return{sbox:e,sbox2:l,T0:r,T1:n,T2:i,T3:o,T01:s,T23:a}}const tableEncoding=genTtable(sbox,e=>mul(e,3)<<24|e<<16|e<<8|mul(e,2)),tableDecoding=genTtable(invSbox,e=>mul(e,11)<<24|mul(e,13)<<16|mul(e,9)<<8|mul(e,14)),xPowers=(()=>{const e=new Uint8Array(16);for(let t=0,r=1;t<16;t++,r=mul2(r))e[t]=r;return e})();function expandKeyLE(e){abytes(e);const t=e.length;validateKeyLength(e);const{sbox2:r}=tableEncoding,n=[];isAligned32$1(e)||n.push(e=copyBytes(e));const i=u32(e),o=i.length,s=e=>applySbox(r,e,e,e,e),a=new Uint32Array(t+28);a.set(i);for(let l=o;l<a.length;l++){let e=a[l-1];l%o===0?e=s(rotr32_8(e))^xPowers[l/o-1]:o>6&&l%o===4&&(e=s(e)),a[l]=a[l-o]^e}return clean(...n),a}function expandKeyDecLE(e){const t=expandKeyLE(e),r=t.slice(),n=t.length,{sbox2:i}=tableEncoding,{T0:o,T1:s,T2:a,T3:l}=tableDecoding;for(let c=0;c<n;c+=4)for(let e=0;e<4;e++)r[c+e]=t[n-c-4+e];clean(t);for(let c=4;c<n-4;c++){const e=r[c],t=applySbox(i,e,e,e,e);r[c]=o[255&t]^s[t>>>8&255]^a[t>>>16&255]^l[t>>>24]}return r}function apply0123(e,t,r,n,i,o){return e[r<<8&65280|n>>>8&255]^t[i>>>8&65280|o>>>24&255]}function applySbox(e,t,r,n,i){return e[255&t|65280&r]|e[n>>>16&255|i>>>16&65280]<<16}function encrypt$1(e,t,r,n,i){const{sbox2:o,T01:s,T23:a}=tableEncoding;let l=0;t^=e[l++],r^=e[l++],n^=e[l++],i^=e[l++];const c=e.length/4-2;for(let u=0;u<c;u++){const o=e[l++]^apply0123(s,a,t,r,n,i),c=e[l++]^apply0123(s,a,r,n,i,t),u=e[l++]^apply0123(s,a,n,i,t,r),h=e[l++]^apply0123(s,a,i,t,r,n);t=o,r=c,n=u,i=h}return{s0:e[l++]^applySbox(o,t,r,n,i),s1:e[l++]^applySbox(o,rLine truncated
+1
View File
@@ -0,0 +1 @@
:root{--default-list-color: #fc3;--hover-bg: #f8f9fa;--sidebar-width: 350px;--link-color: #2a7fff;--link-color-visited: #6a4fbf;--marker-color-primary: #ea4335;--marker-color-dark: #b31412;--danger-color: var(--marker-color-primary);--danger-color-dark: var(--marker-color-dark)}html,body{height:100%;overscroll-behavior:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}button{-webkit-tap-highlight-color:transparent}body{margin:0;font-family:Noto Sans,sans-serif;font-size:16px;font-weight:400;color:#333}#root,#ember-testing{height:100%}.map-container{background:#f8f9fa;-webkit-tap-highlight-color:transparent;outline:none;position:absolute;inset:0}#rs-widget-container{position:absolute;top:60px;right:10px;z-index:4000;display:none}#rs-widget-container.visible{display:block}.rs-backdrop{position:fixed;inset:0;z-index:3999}.app-header{position:absolute;top:0;left:0;right:0;height:60px;padding:.5rem 1rem;z-index:3000;pointer-events:none;display:grid;grid-template-columns:1fr auto 1fr;grid-template-areas:"search chips user";align-items:center;gap:1rem}@media(max-width:768px){.app-header{padding:.5rem .5rem 0;height:auto;grid-template-columns:1fr auto;grid-template-areas:"search user" "chips chips";row-gap:8px}}.header-left,.header-right,.header-center{pointer-events:auto}.header-left{display:flex;align-items:center;grid-area:search;justify-self:start;width:100%}@media not (max-width:768px){.header-left{min-width:300px;max-width:400px}}@media not (max-width:768px){.header-left{min-width:300px;max-width:350px}}.header-right{grid-area:user;justify-self:end}.header-center{grid-area:chips;display:flex;justify-content:center;min-width:0}@media not (max-width:768px){.header-center .category-chips-scroll{width:auto;max-width:100%}}@media(max-width:768px){.header-center{width:100%;overflow:hidden;justify-content:start}.header-center.searching{display:none}}.btn-press{transition:transform .1s}.btn-press:active{transform:scale(.95)}.user-btn{background:none;border:none;cursor:pointer;padding:0;display:flex;align-items:center;justify-content:center}.user-avatar-placeholder{width:40px;height:40px;background:#2a3743;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0}.user-avatar{width:40px;height:40px;border-radius:50%;object-fit:cover;flex-shrink:0;display:block}.photo-preview-img{max-width:100%;height:auto}.dropzone{border:2px dashed #ccc;border-radius:8px;text-align:center;transition:all .2s ease;margin:1.5rem 0 1rem;background-color:#ffffff05;cursor:pointer;aspect-ratio:4 / 3}.dropzone.is-dragging{border-color:#61afef;background-color:#61afef0d}.dropzone-label{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1rem;cursor:pointer;color:#898989;width:100%;height:100%}.dropzone-label p{margin:0}.file-input-hidden{display:none}.photo-grid{display:flex;flex-direction:column;gap:12px;margin-bottom:20px}.photo-upload-item{position:relative;aspect-ratio:4 / 3;border-radius:6px;overflow:hidden;background:#1e262e;width:100%}.photo-upload-item img{position:absolute;top:0;left:0;width:100%;height:100%;object-fit:contain;display:block;z-index:1}.photo-upload-item .overlay,.photo-upload-item .btn-remove-photo{z-index:2}.photo-upload-item .overlay{position:absolute;inset:0;background:#0009;display:flex;flex-direction:column;align-items:center;justify-content:center}.upload-status-text{color:#fff;margin-top:1rem;font-size:.9rem;text-shadow:0 1px 3px rgb(0 0 0 / 80%);text-align:center;padding:0 1rem}.photo-upload-item .error-overlay{background:#e06c75cc;cursor:pointer;border:none;padding:0;margin:0;width:100%}.photo-upload-item .btn-remove-photo{position:absolute;top:4px;right:4px;background:#000000b3;border:none;border-radius:50%;width:24px;height:24px;display:flex;align-items:center;justify-content:center;cursor:pointer;color:#fff;padding:0}.photo-upload-item .btn-remove-photo:hover{background:var(--danger-color)}.spin-animation{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.btn-publish{width:100%}.user-menu-container{position:relative}.user-menu-popover{position:absolute;top:100%;right:0;margin-top:10px;width:280px;background:#fff;border-radius:8px;box-shadow:0 4px 12px #00000026;padding:1rem;z-index:3001}.menu-backdrop{position:fixed;inset:0;z-index:3000}.account-list{list-style:none;padding:0;margin:0}.account-item{display:flex;flex-direction:column;padding:1rem 0;border-bottom:1px solid #eee}.account-item:last-child{border-bottom:none;padding-bottom:0}.account-item:first-child{padding-top:0}.account-header{display:flex;justify-content:space-between;align-items:center}.account-status{font-size:.85rem;color:#898989;margin-top:.35rem;margin-left:calc(18px + .75rem);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.account-status strong{font-weight:600}.account-item.disabled{opacity:.5;pointer-events:none}.account-iLine truncated
@@ -1 +1 @@
import{c as e,g as a,a as s,s as t,A as r,C as o,b as n,D as i,L as l,N as b,d as c,P as p,e as d,S as m,T as u,_ as g,f as y,h as _,i as O,j as S,k as f,l as C,m as P,n as h,o as v,p as j,q as E,r as M,t as D,u as N,v as V,w as A,x as w,y as T,z as I,B as x,E as R,F as k,G as F,H as L,I as z,J as G,K as U,M as B,O as W,Q as Y,R as H,U as J,V as K,W as X,X as q,Y as Q,Z,$,a0 as ee,a1 as ae,a2 as se,a3 as te,a4 as re,a5 as oe,a6 as ne,a7 as ie,a8 as le,a9 as be,aa as pe,ab as de,ac as me,ad as ue,ae as ge,af as ye,ag as _e,ah as Oe,ai as Se,aj as fe,ak as Ce,al as Pe,am as he,an as ve,ao as je,ap as Ee,aq as Me,ar as De,as as Ne,at as Ve,au as Ae,av as we,aw as Te,ax as Ie,ay as xe,az as Re,aA as ke,aB as Fe,aC as Le,aD as ze,aE as Ge,aF as Ue,aG as Be,aH as We,aI as Ye,aJ as He,aK as Je,aL as Ke,aM as Xe,aN as qe,aO as Qe,aP as Ze,aQ as $e,aR as ea,aS as aa,aT as sa,aU as ta,aV as ra,aW as oa,aX as na,aY as ia,aZ as la,a_ as ba,a$ as pa,b0 as da,b1 as ma,b2 as ua,b3 as ga,b4 as ya,b5 as _a,b6 as Oa,b7 as Sa,b8 as fa,b9 as Ca,ba as Pa,bb as ha,bc as va,bd as ja,be as Ea,bf as Ma,bg as Da,bh as Na,bi as Va,bj as Aa,bk as wa,bl as Ta,bm as Ia,bn as xa,bo as Ra,bp as ka,bq as Fa,br as La,bs as za,bt as Ga,bu as Ua,bv as Ba,bw as Wa,bx as Ya,by as Ha,bz as Ja,bA as Ka,bB as Xa,bC as qa,bD as Qa,bE as Za,bF as $a,bG as es,bH as as,bI as ss,bJ as ts,bK as rs,bL as os,bM as ns,bN as is,bO as ls,bP as bs,bQ as cs,bR as ps,bS as ds,bT as ms,bU as us}from"./main-DNM-h3Gw.js";export{bV as Application,bW as ApplicationNamespace,bX as Array,bY as ArrayProxy,bZ as Controller,b_ as Debug,b$ as EmberDestroyable,c0 as EmberObject,c1 as EnumerableMutable,cc as GlimmerComponent,cd as GlimmerManager,ce as GlimmerReference,cf as GlimmerRuntime,cg as GlimmerUtil,ch as GlimmerValidator,c2 as Instrumentation,c0 as Object,c3 as ObjectCore,c4 as ObjectEvented,c5 as ObjectObservable,c6 as ObjectPromiseProxyMixin,c7 as ObjectProxy,ca as Owner,c8 as Runloop,c9 as Service,cb as VERSION}from"./main-DNM-h3Gw.js";const gs=new WeakMap,ys=Object.freeze(Object.defineProperty({__proto__:null,ASYNC_OBSERVERS:r,ComputedDescriptor:o,ComputedProperty:n,DEBUG_INJECTION_FUNCTIONS:i,Libraries:l,NAMESPACES:b,NAMESPACES_BY_ID:c,PROPERTY_DID_CHANGE:p,PROXY_CONTENT:d,SYNC_OBSERVERS:m,TrackedDescriptor:u,_getPath:g,_getProp:y,_setProp:_,activateObserver:O,addArrayObserver:S,addListener:f,addNamespace:C,addObserver:P,alias:h,arrayContentDidChange:v,arrayContentWillChange:j,autoComputed:E,beginPropertyChanges:M,cached:(...s)=>{const[t,r,o]=s,n=new WeakMap,i=o.get;o.get=function(){return n.has(this)||n.set(this,e(i.bind(this))),a(n.get(this))}},changeProperties:D,computed:N,createCache:e,defineDecorator:V,defineProperty:A,defineValue:w,deprecateProperty:function(e,a,r){Object.defineProperty(e,a,{configurable:!0,enumerable:!1,set(e){t(this,r,e)},get(){return s(this,r)}})},descriptorForDecorator:T,descriptorForProperty:I,eachProxyArrayDidChange:function(e,a,s,t){let r=gs.get(e);void 0!==r&&r.arrayDidChange(e,a,s,t)},eachProxyArrayWillChange:function(e,a,s,t){let r=gs.get(e);void 0!==r&&r.arrayWillChange(e,a,s,t)},endPropertyChanges:x,expandProperties:R,findNamespace:k,findNamespaces:F,flushAsyncObservers:L,get:s,getCachedValueFor:z,getProperties:G,getValue:a,hasListeners:U,hasUnknownProperty:B,inject:W,isClassicDecorator:Y,isComputed:H,isConst:J,isElementDescriptor:K,isNamespaceSearchDisabled:X,libraries:q,makeComputedDecorator:Q,markObjectAsDirty:Z,nativeDescDecorator:$,notifyPropertyChange:ee,objectAt:ae,on:se,processAllNamespaces:te,processNamespace:re,removeArrayObserver:oe,removeListener:ne,removeNamespace:ie,removeObserver:le,replace:be,replaceInNativeArray:pe,revalidateObservers:de,sendEvent:me,set:t,setClassicDecorator:ue,setNamespaceSearchDisabled:ge,setProperties:ye,setUnprocessedMixins:_e,tagForObject:Oe,tagForProperty:Se,tracked:fe,trySet:Ce},Symbol.toStringTag,{value:"Module"})),_s=Object.freeze(Object.defineProperty({__proto__:null,Input:Pe,Textarea:he,capabilities:ve,default:je,getComponentTemplate:Ee,setComponentManager:Me,setComponentTemplate:De},Symbol.toStringTag,{value:"Module"})),Os=Object.freeze(Object.defineProperty({__proto__:null,EventTarget:Ne,Promise:Ve,all:Ae,allSettled:we,asap:Te,async:Ie,cast:xe,configure:Re,default:ke,defer:Fe,denodeify:Le,filter:ze,hash:Ge,hashSettled:Ue,map:Be,off:We,on:Ye,race:He,reject:Je,resolve:Ke,rethrow:Xe},Symbol.toStringTag,{value:"Module"})),Ss=Object.freeze(Object.defineProperty({__proto__:null,cacheFor:z,guidFor:qe},Symbol.toStringTag,{value:"Module"})),fs=Object.freeze(Object.defineProperty({__proto__:null,default:Qe},Symbol.toStringTag,{value:"Module"})),Cs=Object.freeze(Object.defineProperty({__proto__:null,ENV:Ze,context:$e,getENV:ea,getLookup:aa,global:sa,setLookup:ta},Symbol.toStringTag,{value:"Module"})),Ps=Object.freeze(Object.defineProperty({__proto__:null,Meta:ra,UNDEFINED:oa,counters:na,meta:ia,peekMeta:la,setMeta:ba},Symbol.toStringTag,{value:"Module"})),hs=Object.freeze(Object.definePropLine truncated import{c as e,g as a,a as s,s as t,A as r,C as o,b as n,D as i,L as l,N as b,d as c,P as p,e as d,S as m,T as u,_ as g,f as y,h as _,i as O,j as S,k as f,l as C,m as P,n as h,o as v,p as j,q as E,r as M,t as D,u as N,v as V,w as A,x as w,y as T,z as I,B as x,E as R,F as k,G as F,H as L,I as z,J as G,K as U,M as B,O as W,Q as Y,R as H,U as J,V as K,W as X,X as q,Y as Q,Z,$,a0 as ee,a1 as ae,a2 as se,a3 as te,a4 as re,a5 as oe,a6 as ne,a7 as ie,a8 as le,a9 as be,aa as pe,ab as de,ac as me,ad as ue,ae as ge,af as ye,ag as _e,ah as Oe,ai as Se,aj as fe,ak as Ce,al as Pe,am as he,an as ve,ao as je,ap as Ee,aq as Me,ar as De,as as Ne,at as Ve,au as Ae,av as we,aw as Te,ax as Ie,ay as xe,az as Re,aA as ke,aB as Fe,aC as Le,aD as ze,aE as Ge,aF as Ue,aG as Be,aH as We,aI as Ye,aJ as He,aK as Je,aL as Ke,aM as Xe,aN as qe,aO as Qe,aP as Ze,aQ as $e,aR as ea,aS as aa,aT as sa,aU as ta,aV as ra,aW as oa,aX as na,aY as ia,aZ as la,a_ as ba,a$ as pa,b0 as da,b1 as ma,b2 as ua,b3 as ga,b4 as ya,b5 as _a,b6 as Oa,b7 as Sa,b8 as fa,b9 as Ca,ba as Pa,bb as ha,bc as va,bd as ja,be as Ea,bf as Ma,bg as Da,bh as Na,bi as Va,bj as Aa,bk as wa,bl as Ta,bm as Ia,bn as xa,bo as Ra,bp as ka,bq as Fa,br as La,bs as za,bt as Ga,bu as Ua,bv as Ba,bw as Wa,bx as Ya,by as Ha,bz as Ja,bA as Ka,bB as Xa,bC as qa,bD as Qa,bE as Za,bF as $a,bG as es,bH as as,bI as ss,bJ as ts,bK as rs,bL as os,bM as ns,bN as is,bO as ls,bP as bs,bQ as cs,bR as ps,bS as ds,bT as ms,bU as us}from"./main-CLZV93ov.js";export{bV as Application,bW as ApplicationNamespace,bX as Array,bY as ArrayProxy,bZ as Controller,b_ as Debug,b$ as EmberDestroyable,c0 as EmberObject,c1 as EnumerableMutable,cc as GlimmerComponent,cd as GlimmerManager,ce as GlimmerReference,cf as GlimmerRuntime,cg as GlimmerUtil,ch as GlimmerValidator,c2 as Instrumentation,c0 as Object,c3 as ObjectCore,c4 as ObjectEvented,c5 as ObjectObservable,c6 as ObjectPromiseProxyMixin,c7 as ObjectProxy,ca as Owner,c8 as Runloop,c9 as Service,cb as VERSION}from"./main-CLZV93ov.js";const gs=new WeakMap,ys=Object.freeze(Object.defineProperty({__proto__:null,ASYNC_OBSERVERS:r,ComputedDescriptor:o,ComputedProperty:n,DEBUG_INJECTION_FUNCTIONS:i,Libraries:l,NAMESPACES:b,NAMESPACES_BY_ID:c,PROPERTY_DID_CHANGE:p,PROXY_CONTENT:d,SYNC_OBSERVERS:m,TrackedDescriptor:u,_getPath:g,_getProp:y,_setProp:_,activateObserver:O,addArrayObserver:S,addListener:f,addNamespace:C,addObserver:P,alias:h,arrayContentDidChange:v,arrayContentWillChange:j,autoComputed:E,beginPropertyChanges:M,cached:(...s)=>{const[t,r,o]=s,n=new WeakMap,i=o.get;o.get=function(){return n.has(this)||n.set(this,e(i.bind(this))),a(n.get(this))}},changeProperties:D,computed:N,createCache:e,defineDecorator:V,defineProperty:A,defineValue:w,deprecateProperty:function(e,a,r){Object.defineProperty(e,a,{configurable:!0,enumerable:!1,set(e){t(this,r,e)},get(){return s(this,r)}})},descriptorForDecorator:T,descriptorForProperty:I,eachProxyArrayDidChange:function(e,a,s,t){let r=gs.get(e);void 0!==r&&r.arrayDidChange(e,a,s,t)},eachProxyArrayWillChange:function(e,a,s,t){let r=gs.get(e);void 0!==r&&r.arrayWillChange(e,a,s,t)},endPropertyChanges:x,expandProperties:R,findNamespace:k,findNamespaces:F,flushAsyncObservers:L,get:s,getCachedValueFor:z,getProperties:G,getValue:a,hasListeners:U,hasUnknownProperty:B,inject:W,isClassicDecorator:Y,isComputed:H,isConst:J,isElementDescriptor:K,isNamespaceSearchDisabled:X,libraries:q,makeComputedDecorator:Q,markObjectAsDirty:Z,nativeDescDecorator:$,notifyPropertyChange:ee,objectAt:ae,on:se,processAllNamespaces:te,processNamespace:re,removeArrayObserver:oe,removeListener:ne,removeNamespace:ie,removeObserver:le,replace:be,replaceInNativeArray:pe,revalidateObservers:de,sendEvent:me,set:t,setClassicDecorator:ue,setNamespaceSearchDisabled:ge,setProperties:ye,setUnprocessedMixins:_e,tagForObject:Oe,tagForProperty:Se,tracked:fe,trySet:Ce},Symbol.toStringTag,{value:"Module"})),_s=Object.freeze(Object.defineProperty({__proto__:null,Input:Pe,Textarea:he,capabilities:ve,default:je,getComponentTemplate:Ee,setComponentManager:Me,setComponentTemplate:De},Symbol.toStringTag,{value:"Module"})),Os=Object.freeze(Object.defineProperty({__proto__:null,EventTarget:Ne,Promise:Ve,all:Ae,allSettled:we,asap:Te,async:Ie,cast:xe,configure:Re,default:ke,defer:Fe,denodeify:Le,filter:ze,hash:Ge,hashSettled:Ue,map:Be,off:We,on:Ye,race:He,reject:Je,resolve:Ke,rethrow:Xe},Symbol.toStringTag,{value:"Module"})),Ss=Object.freeze(Object.defineProperty({__proto__:null,cacheFor:z,guidFor:qe},Symbol.toStringTag,{value:"Module"})),fs=Object.freeze(Object.defineProperty({__proto__:null,default:Qe},Symbol.toStringTag,{value:"Module"})),Cs=Object.freeze(Object.defineProperty({__proto__:null,ENV:Ze,context:$e,getENV:ea,getLookup:aa,global:sa,setLookup:ta},Symbol.toStringTag,{value:"Module"})),Ps=Object.freeze(Object.defineProperty({__proto__:null,Meta:ra,UNDEFINED:oa,counters:na,meta:ia,peekMeta:la,setMeta:ba},Symbol.toStringTag,{value:"Module"})),hs=Object.freeze(Object.definePropLine truncated
@@ -1,2 +1,2 @@
import{ci as t,cj as e,ck as i,cl as r,cm as n,cn as s,co as o,cp as a}from"./main-DNM-h3Gw.js";var h=Array.isArray;function u(){for(var r,n=[],s=0;s<arguments.length;s++)n[s]=arguments[s];return 1===(n=1===(r=n).length&&h(r[0])?r[0]:r).length?t(n[0]):new e(function(e){return function(r){for(var n=[],s=function(s){n.push(t(e[s]).subscribe(i(r,function(t){if(n){for(var e=0;e<n.length;e++)e!==s&&n[e].unsubscribe();n=null}r.next(t)})))},o=0;n&&!r.closed&&o<e.length;o++)s(o)}} import{ci as t,cj as e,ck as i,cl as r,cm as n,cn as s,co as o,cp as a}from"./main-CLZV93ov.js";var h=Array.isArray;function u(){for(var r,n=[],s=0;s<arguments.length;s++)n[s]=arguments[s];return 1===(n=1===(r=n).length&&h(r[0])?r[0]:r).length?t(n[0]):new e(function(e){return function(r){for(var n=[],s=function(s){n.push(t(e[s]).subscribe(i(r,function(t){if(n){for(var e=0;e<n.length;e++)e!==s&&n[e].unsubscribe();n=null}r.next(t)})))},o=0;n&&!r.closed&&o<e.length;o++)s(o)}}
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */(n))}function l(t,...e){if(!((i=t)instanceof Uint8Array||ArrayBuffer.isView(i)&&"Uint8Array"===i.constructor.name))throw new Error("Uint8Array expected");var i;if(e.length>0&&!e.includes(t.length))throw new Error("Uint8Array expected of length "+e+", got length="+t.length)}function c(t,e=!0){if(t.destroyed)throw new Error("Hash instance has been destroyed");if(e&&t.finished)throw new Error("Hash#digest() has already been called")}function d(...t){for(let e=0;e<t.length;e++)t[e].fill(0)}function f(t){return new DataView(t.buffer,t.byteOffset,t.byteLength)}function g(t,e){return t<<32-e|t>>>e}function p(t){return"string"==typeof t&&(t=function(t){if("string"!=typeof t)throw new Error("string expected");return new Uint8Array((new TextEncoder).encode(t))}(t)),l(t),t}class m{}function w(t){const e=e=>t().update(p(e)).digest(),i=t();return e.outputLen=i.outputLen,e.blockLen=i.blockLen,e.create=()=>t(),e}function b(t,e,i){return t&e^~t&i}function y(t,e,i){return t&e^t&i^e&i}class E extends m{constructor(t,e,i,r){super(),this.finished=!1,this.length=0,this.pos=0,this.destroyed=!1,this.blockLen=t,this.outputLen=e,this.padOffset=i,this.isLE=r,this.buffer=new Uint8Array(t),this.view=f(this.buffer)}update(t){c(this),l(t=p(t));const{view:e,buffer:i,blockLen:r}=this,n=t.length;for(let s=0;s<n;){const o=Math.min(r-this.pos,n-s);if(o===r){const e=f(t);for(;r<=n-s;s+=r)this.process(e,s);continue}i.set(t.subarray(s,s+o),this.pos),this.pos+=o,s+=o,this.pos===r&&(this.process(e,0),this.pos=0)}return this.length+=t.length,this.roundClean(),this}digestInto(t){c(this),function(t,e){l(t);const i=e.outputLen;if(t.length<i)throw new Error("digestInto() expects output buffer of length at least "+i)}(t,this),this.finished=!0;const{buffer:e,view:i,blockLen:r,isLE:n}=this;let{pos:s}=this;e[s++]=128,d(this.buffer.subarray(s)),this.padOffset>r-s&&(this.process(i,0),s=0);for(let l=s;l<r;l++)e[l]=0;!function(t,e,i,r){if("function"==typeof t.setBigUint64)return t.setBigUint64(e,i,r);const n=BigInt(32),s=BigInt(4294967295),o=Number(i>>n&s),a=Number(i&s),h=r?4:0,u=r?0:4;t.setUint32(e+h,o,r),t.setUint32(e+u,a,r)}(i,r-8,BigInt(8*this.length),n),this.process(i,0);const o=f(t),a=this.outputLen;if(a%4)throw new Error("_sha2: outputLen should be aligned to 32bit");const h=a/4,u=this.get();if(h>u.length)throw new Error("_sha2: outputLen bigger than state");for(let l=0;l<h;l++)o.setUint32(4*l,u[l],n)}digest(){const{buffer:t,outputLen:e}=this;this.digestInto(t);const i=t.slice(0,e);return this.destroy(),i}_cloneInto(t){t||(t=new this.constructor),t.set(...this.get());const{blockLen:e,buffer:i,length:r,finished:n,destroyed:s,pos:o}=this;return t.destroyed=s,t.finished=n,t.length=r,t.pos=o,r%e&&t.buffer.set(i),t}clone(){return this._cloneInto()}}const _=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),x=Uint32Array.from([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),A=new Uint32Array(64);class L extends E{constructor(t=32){super(64,t,8,!1),this.A=0|_[0],this.B=0|_[1],this.C=0|_[2],this.D=0|_[3],this.E=0|_[4],this.F=0|_[5],this.G=0|_[6],this.H=0|_[7]}get(){const{A:t,B:e,C:i,D:r,E:n,F:s,G:o,H:a}=this;return[t,e,i,r,n,s,o,a]}set(t,e,i,r,n,s,o,a){this.A=0|t,this.B=0|e,this.C=0|i,this.D=0|r,this.E=0|n,this.F=0|s,this.G=0|o,this.H=0|a}process(t,e){for(let l=0;l<16;l++,e+=4)A[l]=t.getUint32(e,!1);for(let l=16;l<64;l++){const t=A[l-15],e=A[l-2],i=g(t,7)^g(t,18)^t>>>3,r=g(e,17)^g(e,19)^e>>>10;A[l]=r+A[l-7]+i+A[l-16]|0}let{A:i,B:r,C:n,D:s,E:o,F:a,G:h,H:u}=this;for(let l=0;l<64;l++){const t=u+(g(o,6)^g(o,11)^g(o,25))+b(o,a,h)+x[l]+A[l]|0,e=(g(i,2)^g(i,13)^g(i,22))+y(i,r,n)|0;u=h,h=a,a=o,o=s+t|0,s=n,n=r,r=i,i=t+e|0}i=i+this.A|0,r=r+this.B|0,n=n+this.C|0,s=s+this.D|0,o=o+this.E|0,a=a+this.F|0,h=h+this.G|0,u=u+this.H|0,this.set(i,r,n,s,o,a,h,u)}roundClean(){d(A)}destroy(){this.set(0,0,0,0,0,0,0,0),d(this.buffer)}}const U=w(()=>new L),I=32;class B{_raw;length;constructor(t){this._raw=new Uint8Array(t||512),this.length=t?t.length:0}unwrap(){return this._raw.subarray(0,this.length)}get capacity(){return this._raw.byteLength}extend(t){if(t instanceof B&&(t=t.unwrap()),"number"!=typeof t.length)throw Error("bad length");const e=t.length+this.length;if(this.capacity<e){const t=this._raw,i=Math.max(2*this.capacity,e)Line truncated /*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */(n))}function l(t,...e){if(!((i=t)instanceof Uint8Array||ArrayBuffer.isView(i)&&"Uint8Array"===i.constructor.name))throw new Error("Uint8Array expected");var i;if(e.length>0&&!e.includes(t.length))throw new Error("Uint8Array expected of length "+e+", got length="+t.length)}function c(t,e=!0){if(t.destroyed)throw new Error("Hash instance has been destroyed");if(e&&t.finished)throw new Error("Hash#digest() has already been called")}function d(...t){for(let e=0;e<t.length;e++)t[e].fill(0)}function f(t){return new DataView(t.buffer,t.byteOffset,t.byteLength)}function g(t,e){return t<<32-e|t>>>e}function p(t){return"string"==typeof t&&(t=function(t){if("string"!=typeof t)throw new Error("string expected");return new Uint8Array((new TextEncoder).encode(t))}(t)),l(t),t}class m{}function w(t){const e=e=>t().update(p(e)).digest(),i=t();return e.outputLen=i.outputLen,e.blockLen=i.blockLen,e.create=()=>t(),e}function b(t,e,i){return t&e^~t&i}function y(t,e,i){return t&e^t&i^e&i}class E extends m{constructor(t,e,i,r){super(),this.finished=!1,this.length=0,this.pos=0,this.destroyed=!1,this.blockLen=t,this.outputLen=e,this.padOffset=i,this.isLE=r,this.buffer=new Uint8Array(t),this.view=f(this.buffer)}update(t){c(this),l(t=p(t));const{view:e,buffer:i,blockLen:r}=this,n=t.length;for(let s=0;s<n;){const o=Math.min(r-this.pos,n-s);if(o===r){const e=f(t);for(;r<=n-s;s+=r)this.process(e,s);continue}i.set(t.subarray(s,s+o),this.pos),this.pos+=o,s+=o,this.pos===r&&(this.process(e,0),this.pos=0)}return this.length+=t.length,this.roundClean(),this}digestInto(t){c(this),function(t,e){l(t);const i=e.outputLen;if(t.length<i)throw new Error("digestInto() expects output buffer of length at least "+i)}(t,this),this.finished=!0;const{buffer:e,view:i,blockLen:r,isLE:n}=this;let{pos:s}=this;e[s++]=128,d(this.buffer.subarray(s)),this.padOffset>r-s&&(this.process(i,0),s=0);for(let l=s;l<r;l++)e[l]=0;!function(t,e,i,r){if("function"==typeof t.setBigUint64)return t.setBigUint64(e,i,r);const n=BigInt(32),s=BigInt(4294967295),o=Number(i>>n&s),a=Number(i&s),h=r?4:0,u=r?0:4;t.setUint32(e+h,o,r),t.setUint32(e+u,a,r)}(i,r-8,BigInt(8*this.length),n),this.process(i,0);const o=f(t),a=this.outputLen;if(a%4)throw new Error("_sha2: outputLen should be aligned to 32bit");const h=a/4,u=this.get();if(h>u.length)throw new Error("_sha2: outputLen bigger than state");for(let l=0;l<h;l++)o.setUint32(4*l,u[l],n)}digest(){const{buffer:t,outputLen:e}=this;this.digestInto(t);const i=t.slice(0,e);return this.destroy(),i}_cloneInto(t){t||(t=new this.constructor),t.set(...this.get());const{blockLen:e,buffer:i,length:r,finished:n,destroyed:s,pos:o}=this;return t.destroyed=s,t.finished=n,t.length=r,t.pos=o,r%e&&t.buffer.set(i),t}clone(){return this._cloneInto()}}const _=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),x=Uint32Array.from([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),A=new Uint32Array(64);class L extends E{constructor(t=32){super(64,t,8,!1),this.A=0|_[0],this.B=0|_[1],this.C=0|_[2],this.D=0|_[3],this.E=0|_[4],this.F=0|_[5],this.G=0|_[6],this.H=0|_[7]}get(){const{A:t,B:e,C:i,D:r,E:n,F:s,G:o,H:a}=this;return[t,e,i,r,n,s,o,a]}set(t,e,i,r,n,s,o,a){this.A=0|t,this.B=0|e,this.C=0|i,this.D=0|r,this.E=0|n,this.F=0|s,this.G=0|o,this.H=0|a}process(t,e){for(let l=0;l<16;l++,e+=4)A[l]=t.getUint32(e,!1);for(let l=16;l<64;l++){const t=A[l-15],e=A[l-2],i=g(t,7)^g(t,18)^t>>>3,r=g(e,17)^g(e,19)^e>>>10;A[l]=r+A[l-7]+i+A[l-16]|0}let{A:i,B:r,C:n,D:s,E:o,F:a,G:h,H:u}=this;for(let l=0;l<64;l++){const t=u+(g(o,6)^g(o,11)^g(o,25))+b(o,a,h)+x[l]+A[l]|0,e=(g(i,2)^g(i,13)^g(i,22))+y(i,r,n)|0;u=h,h=a,a=o,o=s+t|0,s=n,n=r,r=i,i=t+e|0}i=i+this.A|0,r=r+this.B|0,n=n+this.C|0,s=s+this.D|0,o=o+this.E|0,a=a+this.F|0,h=h+this.G|0,u=u+this.H|0,this.set(i,r,n,s,o,a,h,u)}roundClean(){d(A)}destroy(){this.set(0,0,0,0,0,0,0,0),d(this.buffer)}}const U=w(()=>new L),I=32;class B{_raw;length;constructor(t){this._raw=new Uint8Array(t||512),this.length=t?t.length:0}unwrap(){return this._raw.subarray(0,this.length)}get capacity(){return this._raw.byteLength}extend(t){if(t instanceof B&&(t=t.unwrap()),"number"!=typeof t.length)throw Error("bad length");const e=t.length+this.length;if(this.capacity<e){const t=this._raw,i=Math.max(2*this.capacity,e)Line truncated
+2 -2
View File
@@ -39,8 +39,8 @@
<meta name="msapplication-TileColor" content="#F6E9A6"> <meta name="msapplication-TileColor" content="#F6E9A6">
<meta name="msapplication-TileImage" content="/icons/icon-144.png"> <meta name="msapplication-TileImage" content="/icons/icon-144.png">
<script type="module" crossorigin src="/assets/main-DNM-h3Gw.js"></script> <script type="module" crossorigin src="/assets/main-CLZV93ov.js"></script>
<link rel="stylesheet" crossorigin href="/assets/main-BGF-Udec.css"> <link rel="stylesheet" crossorigin href="/assets/main-COnSXoPt.css">
</head> </head>
<body> <body>
<div id="modal-portal"></div> <div id="modal-portal"></div>
-219
View File
@@ -1,219 +0,0 @@
import { module, test } from 'qunit';
import { visit, currentURL, click, waitFor } from '@ember/test-helpers';
import { setupApplicationTest } from 'marco/tests/helpers';
import Service from '@ember/service';
class MockOsmService extends Service {
async fetchOsmObject() {
return null;
}
}
class MockStorageService extends Service {
initialSyncDone = true;
savedPlaces = [
{
id: 'place-123',
title: 'Mountain Trail',
geohash: 'u33dc0',
osmTags: { name: 'Mountain Trail' },
},
];
lists = [
{
id: 'to-go',
title: 'Want to go',
color: '#2e9e4f',
placeRefs: [{ id: 'place-123', geohash: 'u33dc0' }],
},
{ id: 'to-do', title: 'To do', color: '#2a7fff', placeRefs: [] },
];
findPlaceById(id) {
if (id === 'place-123') {
return this.savedPlaces[0];
}
return null;
}
isPlaceSaved() {
return true;
}
loadPlacesInBounds() {
return [];
}
getPlacesInList(listId) {
if (listId === 'to-go') {
return Promise.resolve([this.savedPlaces[0]]);
}
return Promise.resolve([]);
}
rs = {
on: () => {},
};
}
module('Acceptance | collections navigation', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(function () {
this.owner.register('service:osm', MockOsmService);
this.owner.register('service:storage', MockStorageService);
});
test('navigating through the collections menu hierarchy, viewing list places, and going back', async function (assert) {
// 1. Visit Home Map
await visit('/');
assert.strictEqual(currentURL(), '/');
// 2. Open the App Menu overlay
await click('.menu-btn-integrated');
assert.dom('.sidebar.app-menu-pane').exists('App menu sidebar is open');
assert
.dom('.app-menu')
.includesText('Collections', 'Menu contains Collections link');
// 3. Transition to Collections Index (List of lists)
await click(document.querySelectorAll('.app-menu button')[0]); // Click "Collections"
assert.strictEqual(currentURL(), '/lists', 'Transitions to /lists index');
assert
.dom('.sidebar-header-text-centered')
.includesText('Collections', 'Header is centered and titled Collections');
assert
.dom('.lists-index-item')
.exists({ count: 2 }, 'Renders our 2 mocked list items');
// 4. Transition to a specific list (Want to go)
await click(document.querySelectorAll('.lists-index-item')[0]); // Click "Want to go"
assert.strictEqual(
currentURL(),
'/lists/to-go',
'Transitions instantly to /lists/to-go'
);
// 5. Verify background loading spinner shows up, then results populate
await waitFor('.places-list');
assert
.dom('.places-list .place-name')
.hasText('Mountain Trail', 'Renders the saved place from the list');
assert
.dom('.places-list .place-type')
.hasText('Saved place', 'Place type displays Saved place correctly');
// 6. Click back button in collection list header
await click('.sidebar-header .back-btn');
assert.strictEqual(currentURL(), '/lists', 'Goes back to /lists index');
// 7. Click back button in collections index header
await click('.sidebar-header .back-btn');
assert.strictEqual(currentURL(), '/menu', 'Goes back to main menu route');
// 8. Close sidebar
await click('.sidebar-header .close-btn');
assert.strictEqual(currentURL(), '/', 'Sidebar closed and returned home');
});
test('clicking a place inside a collection sets returnToRoute and returns gracefully on back click', async function (assert) {
await visit('/lists/to-go');
await waitFor('.places-list');
// Click on the place item to view details
await click('.place-item');
assert.ok(
currentURL().includes('/place/place-123'),
'Transitions to place details route'
);
// Click back from place details
await click('.back-btn');
assert.strictEqual(
currentURL(),
'/lists/to-go',
'Returns gracefully back to lists/to-go list view'
);
});
test('places inside a collection are sorted by createdAt descending', async function (assert) {
class SortedMockStorageService extends Service {
initialSyncDone = true;
savedPlaces = [
{
id: 'place-oldest',
title: 'Oldest Place',
geohash: 'u33dc0',
createdAt: '2023-01-01T12:00:00.000Z',
osmTags: { name: 'Oldest Place' },
},
{
id: 'place-newest',
title: 'Newest Place',
geohash: 'u33dc0',
createdAt: '2023-01-03T12:00:00.000Z',
osmTags: { name: 'Newest Place' },
},
{
id: 'place-middle',
title: 'Middle Place',
geohash: 'u33dc0',
createdAt: '2023-01-02T12:00:00.000Z',
updatedAt: '2023-01-04T12:00:00.000Z',
osmTags: { name: 'Middle Place' },
},
];
lists = [
{
id: 'to-go',
title: 'Want to go',
color: '#2e9e4f',
placeRefs: [
{ id: 'place-oldest', geohash: 'u33dc0' },
{ id: 'place-newest', geohash: 'u33dc0' },
{ id: 'place-middle', geohash: 'u33dc0' },
],
},
];
findPlaceById(id) {
return this.savedPlaces.find((p) => p.id === id) || null;
}
isPlaceSaved() {
return true;
}
loadPlacesInBounds() {
return [];
}
getPlacesInList(listId) {
if (listId === 'to-go') {
return Promise.resolve(this.savedPlaces);
}
return Promise.resolve([]);
}
rs = {
on: () => {},
};
}
this.owner.unregister('service:storage');
this.owner.register('service:storage', SortedMockStorageService);
await visit('/lists/to-go');
await waitFor('.places-list');
const placeNames = Array.from(
document.querySelectorAll('.places-list .place-name')
).map((el) => el.textContent.trim());
assert.deepEqual(
placeNames,
['Newest Place', 'Middle Place', 'Oldest Place'],
'Places are ordered by createdAt in descending order'
);
});
});
+7 -2
View File
@@ -101,7 +101,7 @@ module('Acceptance | map search reset', function (hooks) {
'Should have stayed on the search route with markers intact' 'Should have stayed on the search route with markers intact'
); );
// Second Click (Clear search and markers) // Second Click (Start new search)
// Click slightly differently to ensure fresh event // Click slightly differently to ensure fresh event
await triggerEvent(canvas, 'pointerdown', { await triggerEvent(canvas, 'pointerdown', {
clientX: 250, clientX: 250,
@@ -125,6 +125,11 @@ module('Acceptance | map search reset', function (hooks) {
// 3. Wait for transition // 3. Wait for transition
await new Promise((r) => setTimeout(r, 1000)); await new Promise((r) => setTimeout(r, 1000));
assert.strictEqual(currentURL(), '/', 'Should have transitioned to index'); const newUrl = currentURL();
assert.notOk(
newUrl.includes('category=coffee'),
`New URL ${newUrl} should not contain category param`
);
assert.ok(newUrl.includes('/search'), 'Should be on search route');
}); });
}); });
+2 -17
View File
@@ -85,7 +85,7 @@ module('Acceptance | navigation', function (hooks) {
); );
}); });
test('closing the sidebar transitions back to search route when opened from search results', async function (assert) { test('closing the sidebar resets the returnToSearch flag', async function (assert) {
const mapUi = this.owner.lookup('service:map-ui'); const mapUi = this.owner.lookup('service:map-ui');
await visit('/search?lat=1&lon=1'); await visit('/search?lat=1&lon=1');
@@ -97,22 +97,7 @@ module('Acceptance | navigation', function (hooks) {
await click('.close-btn'); await click('.close-btn');
assert.dom('.sidebar').doesNotExist('Sidebar should be closed'); assert.dom('.sidebar').doesNotExist('Sidebar should be closed');
assert.strictEqual( assert.ok(currentURL().includes('/place/'), 'Remains on place route');
currentURL(),
'/search?lat=1&lon=1',
'Should transition back to search route'
);
});
test('closing the sidebar when visiting a place directly transitions to index', async function (assert) {
await visit('/place/osm:node:123');
assert.ok(currentURL().includes('/place/'), 'Visited place directly');
// Click the Close (X) button
await click('.close-btn');
assert.dom('.sidebar').doesNotExist('Sidebar should be closed');
assert.strictEqual(currentURL(), '/', 'Should transition back to index');
}); });
test('navigating directly to place and back closes sidebar', async function (assert) { test('navigating directly to place and back closes sidebar', async function (assert) {
-73
View File
@@ -169,77 +169,4 @@ module('Acceptance | search loading', function (hooks) {
// Verify we are back on index (or at least query is gone) // Verify we are back on index (or at least query is gone)
assert.strictEqual(currentURL(), '/', 'Navigated to index'); assert.strictEqual(currentURL(), '/', 'Navigated to index');
}); });
test('quick search pills visibility during category search transition', async function (assert) {
const mapUi = this.owner.lookup('service:map-ui');
mapUi.currentZoom = 15;
// Seed localStorage with a high zoom level to ensure quick search buttons show
const highZoomState = {
center: [13.4, 52.5],
zoom: 18,
};
window.localStorage.setItem(
'marco:map-view',
JSON.stringify(highZoomState)
);
try {
// Make sure quick search buttons setting is enabled
const settings = this.owner.lookup('service:settings');
settings.showQuickSearchButtons = true;
// 1. Visit slowly loading category search
const catPromise = visit('/search?category=slow_category&lat=1&lon=1');
await new Promise((r) => setTimeout(r, 10));
// Verify loading state is set and pills are visible (i.e. header-center does NOT have .searching)
assert.ok(mapUi.loadingState, 'Search is loading');
assert
.dom('.header-center')
.doesNotHaveClass(
'searching',
'Pills remain visible while search is loading'
);
// Resolve the promise with empty results
osmResolve();
await catPromise;
await settled();
// Verify search completed and since results are empty, pills are still visible
assert.strictEqual(mapUi.searchResults.length, 0, 'No results found');
assert
.dom('.header-center')
.doesNotHaveClass(
'searching',
'Pills remain visible after search completes with no results'
);
// 2. Now simulate a fast category search that returns results
const osmService = this.owner.lookup('service:osm');
osmService.getCategoryPois = async () => [
{
title: 'Latte Art Cafe',
lat: 1,
lon: 1,
osmId: '101',
osmType: 'N',
},
];
await visit('/search?category=coffee&lat=1&lon=1');
// Verify search completed with results, so pills are hidden
assert.ok(mapUi.searchResults.length > 0, 'Results found');
assert
.dom('.header-center')
.hasClass(
'searching',
'Pills are hidden after search completes with results'
);
} finally {
window.localStorage.removeItem('marco:map-view');
}
});
}); });
-72
View File
@@ -270,76 +270,4 @@ module('Acceptance | search', function (hooks) {
.hasText('Search request failed. Please try again.'); .hasText('Search request failed. Please try again.');
assert.dom('.places-sidebar').doesNotExist('Results panel should not open'); assert.dom('.places-sidebar').doesNotExist('Results panel should not open');
}); });
test('search box query synchronized with active route query parameters', async function (assert) {
// Mock Osm Service
class MockOsmService extends Service {
async getCategoryPois() {
return [];
}
}
this.owner.register('service:osm', MockOsmService);
// Mock Photon Service
class MockPhotonService extends Service {
async search() {
return [];
}
}
this.owner.register('service:photon', MockPhotonService);
// Mock Storage Service
class MockStorageService extends Service {
savedPlaces = [];
findPlaceById() {
return null;
}
isPlaceSaved() {
return false;
}
rs = { on: () => {} };
placesInView = [];
loadPlacesInBounds() {
return Promise.resolve();
}
}
this.owner.register('service:storage', MockStorageService);
// Mock Map Service
class MockMapService extends Service {
getBounds() {
return {
minLat: 52.5,
minLon: 13.4,
maxLat: 52.6,
maxLon: 13.5,
};
}
}
this.owner.register('service:map', MockMapService);
// 1. Visit a search URL directly
await visit('/search?q=Berlin');
assert
.dom('.search-input')
.hasValue(
'Berlin',
'Search input is populated with search term on direct load'
);
// 2. Visit a category search URL
await visit('/search?category=coffee&lat=52.52&lon=13.405');
assert
.dom('.search-input')
.hasValue(
'Coffee',
'Search input is populated with mapped category label'
);
// 3. Go back to index
await visit('/');
assert
.dom('.search-input')
.hasValue('', 'Search input is cleared on transitioning to index');
});
}); });
-87
View File
@@ -4,92 +4,6 @@ import {
setupTest as upstreamSetupTest, setupTest as upstreamSetupTest,
} from 'ember-qunit'; } from 'ember-qunit';
import { setupNostrMocks } from './mock-nostr'; import { setupNostrMocks } from './mock-nostr';
import sinon from 'sinon';
function setupMapStyleMocks(hooks) {
hooks.beforeEach(function () {
// Stub window.fetch to capture map-style assets before they hit the network
this.fetchStub = sinon.stub(window, 'fetch');
this.fetchStub.callsFake(async (input, init) => {
let url = input;
if (typeof input === 'object' && input !== null && 'url' in input) {
url = input.url;
}
if (typeof url === 'string' && url.includes('tiles.openfreemap.org')) {
// A. Mock Style Sheet
if (url.includes('/styles/liberty')) {
return {
ok: true,
status: 200,
json: async () => ({
version: 8,
name: 'Mock Style',
sources: {
openmaptiles: {
type: 'vector',
tiles: [], // Empty tiles list prevents any map tile fetching completely!
},
},
sprite: 'https://tiles.openfreemap.org/sprites/liberty',
glyphs:
'https://tiles.openfreemap.org/fonts/{fontstack}/{range}.pbf',
layers: [
{
id: 'background',
type: 'background',
paint: { 'background-color': '#f8f9fa' },
},
],
}),
};
}
// B. Mock Sprite Atlas JSON
if (url.endsWith('.json') && url.includes('/sprites/')) {
return {
ok: true,
status: 200,
json: async () => ({}), // Empty sprite dictionary
};
}
// C. Mock Sprite Atlas PNG (Returns a valid 1x1 transparent PNG)
if (url.endsWith('.png') && url.includes('/sprites/')) {
const bytes = new Uint8Array([
137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0,
0, 1, 0, 0, 0, 1, 8, 6, 0, 0, 0, 31, 21, 196, 137, 0, 0, 0, 11, 73,
68, 65, 84, 120, 156, 99, 96, 0, 0, 0, 2, 0, 1, 226, 33, 188, 51, 0,
0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130,
]);
const blob = new Blob([bytes], { type: 'image/png' });
return {
ok: true,
status: 200,
blob: async () => blob,
};
}
// Catch-all mock for other openfreemap endpoints
return {
ok: true,
status: 200,
json: async () => ({}),
};
}
// Pass through to original fetch (e.g. Photon results, local mock APIs)
return this.fetchStub.wrappedMethod(input, init);
});
});
hooks.afterEach(function () {
if (this.fetchStub && typeof this.fetchStub.restore === 'function') {
this.fetchStub.restore();
}
});
}
// This file exists to provide wrappers around ember-qunit's // This file exists to provide wrappers around ember-qunit's
// test setup functions. This way, you can easily extend the setup that is // test setup functions. This way, you can easily extend the setup that is
@@ -98,7 +12,6 @@ function setupMapStyleMocks(hooks) {
function setupApplicationTest(hooks, options) { function setupApplicationTest(hooks, options) {
upstreamSetupApplicationTest(hooks, options); upstreamSetupApplicationTest(hooks, options);
setupNostrMocks(hooks); setupNostrMocks(hooks);
setupMapStyleMocks(hooks);
// Additional setup for application tests can be done here. // Additional setup for application tests can be done here.
// //
+2 -10
View File
@@ -49,19 +49,11 @@ export class MockNostrDataService extends Service {
return []; return [];
} }
get requiredReadRelays() { get defaultReadRelays() {
return []; return [];
} }
get requiredWriteRelays() { get defaultWriteRelays() {
return [];
}
get mailboxReadRelays() {
return [];
}
get mailboxWriteRelays() {
return []; return [];
} }
@@ -1,188 +0,0 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'marco/tests/helpers';
import { click, fillIn, render } from '@ember/test-helpers';
import Service, { service } from '@ember/service';
import AppMenuSettingsNostr from 'marco/components/app-menu/settings/nostr';
import {
excludeRequiredRelays,
mergeRequiredRelays,
uniqNormalizedRelays,
} from 'marco/utils/nostr';
class MockNostrDataService extends Service {
@service settings;
requiredReadRelays = ['wss://nostr.kosmos.org'];
requiredWriteRelays = [];
mailboxReadRelays = ['wss://mailbox.example.com'];
mailboxWriteRelays = ['wss://mailbox-write.example.com'];
get configuredReadRelays() {
const configured = uniqNormalizedRelays([
...this.mailboxReadRelays,
...(this.settings.nostrReadRelays || []),
]);
return excludeRequiredRelays(
configured,
this.settings.nostrReadRelayExclusions || []
);
}
get configuredWriteRelays() {
const configured = uniqNormalizedRelays([
...this.mailboxWriteRelays,
...(this.settings.nostrWriteRelays || []),
]);
return excludeRequiredRelays(
configured,
this.settings.nostrWriteRelayExclusions || []
);
}
get activeReadRelays() {
return mergeRequiredRelays(
this.requiredReadRelays,
this.configuredReadRelays
);
}
get activeWriteRelays() {
return mergeRequiredRelays(
this.requiredWriteRelays,
this.configuredWriteRelays
);
}
async clearCache() {}
}
function readRows(element) {
const list = element.querySelectorAll('.relay-list')[0];
return [...list.querySelectorAll('li')];
}
function writeRows(element) {
const list = element.querySelectorAll('.relay-list')[1];
return [...list.querySelectorAll('li')];
}
function rowByText(rows, text) {
return rows.find((row) => row.textContent.includes(text));
}
module('Integration | Component | app-menu/settings/nostr', function (hooks) {
setupRenderingTest(hooks);
hooks.beforeEach(function () {
localStorage.removeItem('marco:settings');
this.owner.register('service:nostrData', MockNostrDataService);
this.settings = this.owner.lookup('service:settings');
this.onChange = () => {};
});
hooks.afterEach(function () {
localStorage.removeItem('marco:settings');
});
async function renderAndOpenDetails(context) {
await render(
<template><AppMenuSettingsNostr @onChange={{this.onChange}} /></template>
);
await click('summary');
return context.element;
}
test('required read relay is first and non-removable', async function (assert) {
const element = await renderAndOpenDetails(this);
const rows = readRows(element);
assert.dom(rows[0]).includesText('nostr.kosmos.org');
const requiredRow = rowByText(rows, 'nostr.kosmos.org');
const mailboxRow = rowByText(rows, 'mailbox.example.com');
assert.dom(requiredRow.querySelector('.btn-remove-relay')).doesNotExist();
assert.dom(mailboxRow.querySelector('.btn-remove-relay')).exists();
});
test('removing mailbox read relay stores exclusion override', async function (assert) {
const element = await renderAndOpenDetails(this);
const mailboxRow = rowByText(readRows(element), 'mailbox.example.com');
await click(mailboxRow.querySelector('.btn-remove-relay'));
assert.deepEqual(this.settings.nostrReadRelayExclusions, [
'wss://mailbox.example.com',
]);
assert.strictEqual(this.settings.nostrReadRelays, null);
});
test('removing custom read relay updates custom list without exclusions', async function (assert) {
this.settings.update('nostrReadRelays', ['wss://custom.example.com']);
const element = await renderAndOpenDetails(this);
const customRow = rowByText(readRows(element), 'custom.example.com');
await click(customRow.querySelector('.btn-remove-relay'));
assert.strictEqual(this.settings.nostrReadRelays, null);
assert.strictEqual(this.settings.nostrReadRelayExclusions, null);
});
test('adding read relay clears existing exclusion for same relay', async function (assert) {
this.settings.update('nostrReadRelayExclusions', [
'wss://mailbox.example.com',
]);
const element = await renderAndOpenDetails(this);
await fillIn('#new-read-relay', 'Mailbox.EXAMPLE.com/');
await click(element.querySelector('#new-read-relay').nextElementSibling);
assert.deepEqual(this.settings.nostrReadRelays, [
'wss://mailbox.example.com',
]);
assert.strictEqual(this.settings.nostrReadRelayExclusions, null);
});
test('reset read relays clears additions and exclusions', async function (assert) {
this.settings.update('nostrReadRelays', ['wss://custom.example.com']);
this.settings.update('nostrReadRelayExclusions', [
'wss://mailbox.example.com',
]);
const element = await renderAndOpenDetails(this);
await click(element.querySelectorAll('.reset-relays')[0]);
assert.strictEqual(this.settings.nostrReadRelays, null);
assert.strictEqual(this.settings.nostrReadRelayExclusions, null);
const requiredRow = rowByText(readRows(element), 'nostr.kosmos.org');
assert.dom(requiredRow).exists();
});
test('write relays are removable and mailbox delete stores exclusion', async function (assert) {
this.settings.update('nostrWriteRelays', [
'wss://custom-write.example.com',
]);
const element = await renderAndOpenDetails(this);
const rows = writeRows(element);
assert.true(
rows.every((row) => row.querySelector('.btn-remove-relay')),
'all write relays can be removed'
);
const mailboxRow = rowByText(rows, 'mailbox-write.example.com');
await click(mailboxRow.querySelector('.btn-remove-relay'));
assert.deepEqual(this.settings.nostrWriteRelayExclusions, [
'wss://mailbox-write.example.com',
]);
});
});
@@ -334,54 +334,4 @@ module('Integration | Component | place-details', function (hooks) {
assert.dom(links[0]).hasText('+44 987 654 321'); assert.dom(links[0]).hasText('+44 987 654 321');
assert.dom(links[1]).hasText('+1 234-567 8900'); assert.dom(links[1]).hasText('+1 234-567 8900');
}); });
test('it renders correct OpenStreetMap link for an OSM place', async function (assert) {
const place = {
title: 'OSM Place',
osmId: '12345',
osmType: 'node',
lat: 52.520008,
lon: 13.404954,
};
await render(<template><PlaceDetails @place={{place}} /></template>);
const osmLink = this.element.querySelector(
'.meta-info a[href^="https://www.openstreetmap.org/node/12345"]'
);
assert.ok(osmLink, 'OpenStreetMap link is rendered');
assert.strictEqual(
osmLink.getAttribute('href'),
'https://www.openstreetmap.org/node/12345'
);
assert.dom('button.btn-link').hasText('Add a photo');
});
test('it renders correct search-based OpenStreetMap link for a custom saved place', async function (assert) {
class MockMapUi extends Service {
currentCenter = { lat: 52.5, lon: 13.4 };
currentZoom = 15.6;
}
this.owner.register('service:map-ui', MockMapUi);
const place = {
title: 'Custom Place',
lat: 52.520008,
lon: 13.404954,
};
await render(<template><PlaceDetails @place={{place}} /></template>);
const osmLink = this.element.querySelector(
'.meta-info a[href^="https://www.openstreetmap.org/search"]'
);
assert.ok(osmLink, 'OpenStreetMap search link is rendered');
assert.strictEqual(
osmLink.getAttribute('href'),
'https://www.openstreetmap.org/search?lat=52.520008&lon=13.404954&zoom=16#map=16/52.50000/13.40000'
);
assert.dom('button.btn-link').doesNotExist();
});
}); });
+1 -62
View File
@@ -1,11 +1,5 @@
import { module, test } from 'qunit'; import { module, test } from 'qunit';
import { import { normalizeRelayUrl, parsePlacePhotos } from 'marco/utils/nostr';
excludeRequiredRelays,
mergeRequiredRelays,
normalizeRelayUrl,
parsePlacePhotos,
uniqNormalizedRelays,
} from 'marco/utils/nostr';
module('Unit | Utility | nostr', function () { module('Unit | Utility | nostr', function () {
test('normalizeRelayUrl normalizes protocol, case, and slashes', function (assert) { test('normalizeRelayUrl normalizes protocol, case, and slashes', function (assert) {
@@ -147,59 +141,4 @@ module('Unit | Utility | nostr', function () {
assert.strictEqual(photos[0].placeIdentifier, 'osm:node:123'); assert.strictEqual(photos[0].placeIdentifier, 'osm:node:123');
assert.strictEqual(photos[1].placeIdentifier, 'osm:node:456'); assert.strictEqual(photos[1].placeIdentifier, 'osm:node:456');
}); });
test('uniqNormalizedRelays returns normalized unique relays', function (assert) {
const relays = uniqNormalizedRelays([
'Relay.example.com',
'wss://relay.example.com/',
'wss://other.example.com',
]);
assert.deepEqual(relays, [
'wss://relay.example.com',
'wss://other.example.com',
]);
});
test('mergeRequiredRelays keeps required relays as-is and merges normalized custom relays', function (assert) {
const relays = mergeRequiredRelays(
['wss://required.example.com', 'required-2.example.com'],
['required-2.example.com/', 'wss://custom.example.com']
);
assert.deepEqual(relays, [
'wss://required.example.com',
'required-2.example.com',
'wss://required-2.example.com',
'wss://custom.example.com',
]);
});
test('excludeRequiredRelays removes required relays from normalized custom list', function (assert) {
const relays = excludeRequiredRelays(
[
'wss://required.example.com',
'custom.example.com',
'ws://custom2.example.com',
],
['wss://required.example.com']
);
assert.deepEqual(relays, [
'wss://custom.example.com',
'ws://custom2.example.com',
]);
});
test('excludeRequiredRelays trusts required list without normalizing it', function (assert) {
const relays = excludeRequiredRelays(
['Required.example.com', 'custom.example.com'],
['required.example.com']
);
assert.deepEqual(relays, [
'wss://required.example.com',
'wss://custom.example.com',
]);
});
}); });
+1 -12
View File
@@ -1,5 +1,4 @@
import { getIconNameForTags, POI_ICON_RULES } from 'marco/utils/osm-icons'; import { getIconNameForTags } from 'marco/utils/osm-icons';
import { getIcon } from 'marco/utils/icons';
import { module, test } from 'qunit'; import { module, test } from 'qunit';
module('Unit | Utility | osm-icons', function () { module('Unit | Utility | osm-icons', function () {
@@ -37,14 +36,4 @@ module('Unit | Utility | osm-icons', function () {
let result = getIconNameForTags({ foo: 'bar' }); let result = getIconNameForTags({ foo: 'bar' });
assert.strictEqual(result, null); assert.strictEqual(result, null);
}); });
test('all icons used in POI_ICON_RULES exist in the icons utility', function (assert) {
for (let rule of POI_ICON_RULES) {
let icon = getIcon(rule.icon);
assert.ok(
icon,
`Icon "${rule.icon}" specified in POI_ICON_RULES should be imported and available in getIcon`
);
}
});
}); });
-6
View File
@@ -89,12 +89,6 @@ module('Unit | Utility | osm', function (hooks) {
assert.strictEqual(result, 'Building'); assert.strictEqual(result, 'Building');
}); });
test('getPlaceType ignores generic "yes" values if a more specific tag is present', function (assert) {
const tags = { historic: 'yes', building: 'tower' };
const result = getPlaceType(tags);
assert.strictEqual(result, 'Tower');
});
test('getPlaceType prioritizes order (amenity > shop > building)', function (assert) { test('getPlaceType prioritizes order (amenity > shop > building)', function (assert) {
// If something is both a shop and a building, it should be a shop // If something is both a shop and a building, it should be a shop
const tags = { building: 'yes', shop: 'supermarket' }; const tags = { building: 'yes', shop: 'supermarket' };