diff --git a/app/Console/Commands/Einundzwanzig/SyncPlebs.php b/app/Console/Commands/Einundzwanzig/SyncPlebs.php
new file mode 100644
index 0000000..bbf7b03
--- /dev/null
+++ b/app/Console/Commands/Einundzwanzig/SyncPlebs.php
@@ -0,0 +1,43 @@
+json();
+
+ foreach ($plebs as $pleb) {
+ $npub = str($pleb)->trim();
+ EinundzwanzigPleb::updateOrCreate(
+ ['npub' => $npub],
+ ['pubkey' => (new Key())->convertToHex($npub)]
+ );
+ }
+ }
+}
diff --git a/app/Console/Commands/Nostr/FetchEvents.php b/app/Console/Commands/Nostr/FetchEvents.php
new file mode 100644
index 0000000..27c136f
--- /dev/null
+++ b/app/Console/Commands/Nostr/FetchEvents.php
@@ -0,0 +1,114 @@
+get();
+
+ $subscription = new Subscription();
+ $subscriptionId = $subscription->setId();
+
+ $filter1 = new Filter();
+ $filter1->setKinds([1]); // You can add multiple kind numbers
+ $filter1->setAuthors($plebs->pluck('pubkey')->toArray()); // You can add multiple authors
+ $filter1->setLimit(25); // Limit to fetch only a maximum of 25 events
+ $filters = [$filter1]; // You can add multiple filters.
+
+ $requestMessage = new RequestMessage($subscriptionId, $filters);
+
+ $relays = [
+ new Relay('wss://nostr.einundzwanzig.space'),
+ new Relay('wss://nostr.wine'),
+ new Relay('wss://nos.lol'),
+ ];
+ $relaySet = new RelaySet();
+ $relaySet->setRelays($relays);
+
+ $request = new Request($relaySet, $requestMessage);
+ $response = $request->send();
+
+ $uniqueEvents = [];
+
+ foreach ($response as $relay => $events) {
+ foreach ($events as $event) {
+ if (!isset($uniqueEvents[$event->event->id])) {
+ $uniqueEvents[$event->event->id] = $event;
+ }
+ }
+ }
+
+ foreach ($uniqueEvents as $id => $uniqueEvent) {
+ $type = $this->isReplyOrRoot($uniqueEvent->event);
+ $parentEventId = $this->getParentEventId($uniqueEvent->event);
+
+ $event = Event::query()->updateOrCreate(
+ ['event_id' => $id],
+ [
+ 'pubkey' => $uniqueEvent->event->pubkey,
+ 'parent_event_id' => $parentEventId,
+ 'json' => json_encode($uniqueEvent->event, JSON_THROW_ON_ERROR),
+ 'type' => $type,
+ ]
+ );
+
+ $this->renderContentToHtml($event);
+ }
+ }
+
+ private function getParentEventId($event)
+ {
+ foreach ($event->tags as $tag) {
+ if ($tag[0] === 'e') {
+ if ((isset($tag[2]) && $tag[2] === '') || (isset($tag[3]) && $tag[3] === 'reply')) {
+ return $tag[1];
+ }
+ }
+ }
+ return null;
+ }
+
+ private function isReplyOrRoot($event)
+ {
+ foreach ($event->tags as $tag) {
+ if ($tag[0] === 'e') {
+ if ((isset($tag[3]) && $tag[3] === 'reply') || (!isset($tag[3]) && isset($tag[2]) && $tag[2] === '')) {
+ return 'reply';
+ }
+ }
+ }
+ return 'root';
+ }
+}
diff --git a/app/Console/Commands/Nostr/RenderAllEvents.php b/app/Console/Commands/Nostr/RenderAllEvents.php
new file mode 100644
index 0000000..86d5d7d
--- /dev/null
+++ b/app/Console/Commands/Nostr/RenderAllEvents.php
@@ -0,0 +1,46 @@
+get();
+
+ foreach ($events as $event) {
+ $this->renderContentToHtml($event);
+ }
+
+ Broadcast::on('events')
+ ->as('newEvents')
+ ->with([
+ 'test' => 'test',
+ ])
+ ->sendNow();
+ }
+}
diff --git a/app/Console/Commands/Nostr/SyncProfiles.php b/app/Console/Commands/Nostr/SyncProfiles.php
new file mode 100644
index 0000000..bcddeb5
--- /dev/null
+++ b/app/Console/Commands/Nostr/SyncProfiles.php
@@ -0,0 +1,38 @@
+whereDoesntHave('profile')
+ ->get();
+ $this->fetchProfile($plebs->pluck('npub')->toArray());
+ }
+}
diff --git a/app/Livewire/MeetupTable.php b/app/Livewire/MeetupTable.php
new file mode 100644
index 0000000..5fd7998
--- /dev/null
+++ b/app/Livewire/MeetupTable.php
@@ -0,0 +1,97 @@
+showCheckBox();
+
+ return [
+ Exportable::make('export')
+ ->striped()
+ ->type(Exportable::TYPE_XLS, Exportable::TYPE_CSV),
+ Footer::make()
+ ->showPerPage(perPage: 25)
+ ->showRecordCount(),
+ ];
+ }
+
+ public function datasource(): Builder
+ {
+ return Meetup::query();
+ }
+
+ public function fields(): PowerGridFields
+ {
+ return PowerGrid::fields()
+ ->add('name')
+ ->add('name_lower', fn (Meetup $model) => strtolower(e($model->name)))
+ ->add('created_at')
+ ->add('created_at_formatted', fn (Meetup $model) => Carbon::parse($model->created_at)->format('d/m/Y H:i:s'));
+ }
+
+ public function columns(): array
+ {
+ return [
+ Column::make('Name', 'name')
+ ->searchable()
+ ->sortable(),
+
+ Column::action('Action')
+ ];
+ }
+
+ public function filters(): array
+ {
+ return [
+ Filter::inputText('name'),
+ Filter::datepicker('created_at_formatted', 'created_at'),
+ ];
+ }
+
+ #[\Livewire\Attributes\On('edit')]
+ public function edit($rowId): void
+ {
+ $this->js('alert('.$rowId.')');
+ }
+
+ public function actions(Meetup $row): array
+ {
+ return [
+ Button::add('edit')
+ ->slot('Edit: '.$row->id)
+ ->id()
+ ->class('pg-btn-white dark:ring-pg-primary-600 dark:border-pg-primary-600 dark:hover:bg-pg-primary-700 dark:ring-offset-pg-primary-800 dark:text-pg-primary-300 dark:bg-pg-primary-700')
+ ->dispatch('edit', ['rowId' => $row->id])
+ ];
+ }
+
+ /*
+ public function actionRules(Meetup $row): array
+ {
+ return [
+ // Hide button edit for ID 1
+ Rule::button('edit')
+ ->when(fn($row) => $row->id === 1)
+ ->hide(),
+ ];
+ }
+ */
+}
diff --git a/app/Models/Category.php b/app/Models/Category.php
new file mode 100644
index 0000000..fb03bec
--- /dev/null
+++ b/app/Models/Category.php
@@ -0,0 +1,32 @@
+ 'integer',
+ ];
+
+ public function courses(): BelongsToMany
+ {
+ return $this->belongsToMany(Course::class);
+ }
+}
diff --git a/app/Models/City.php b/app/Models/City.php
new file mode 100644
index 0000000..dc9a4d6
--- /dev/null
+++ b/app/Models/City.php
@@ -0,0 +1,83 @@
+ 'integer',
+ 'country_id' => 'integer',
+ 'osm_relation' => 'json',
+ 'simplified_geojson' => 'json',
+ ];
+
+ protected static function booted()
+ {
+ static::creating(function ($model) {
+ if (! $model->created_by) {
+ $model->created_by = auth()->id();
+ }
+ });
+ }
+
+ /**
+ * Get the options for generating the slug.
+ */
+ public function getSlugOptions(): SlugOptions
+ {
+ return SlugOptions::create()
+ ->generateSlugsFrom(['country.code', 'name'])
+ ->saveSlugsTo('slug')
+ ->usingLanguage(Cookie::get('lang', config('app.locale')));
+ }
+
+ public function createdBy(): BelongsTo
+ {
+ return $this->belongsTo(User::class, 'created_by');
+ }
+
+ public function country(): BelongsTo
+ {
+ return $this->belongsTo(Country::class);
+ }
+
+ public function venues(): HasMany
+ {
+ return $this->hasMany(Venue::class);
+ }
+
+ public function courseEvents()
+ {
+ return $this->hasManyThrough(CourseEvent::class, Venue::class);
+ }
+
+ public function meetups()
+ {
+ return $this->hasMany(Meetup::class);
+ }
+}
diff --git a/app/Models/Country.php b/app/Models/Country.php
new file mode 100644
index 0000000..a4f4898
--- /dev/null
+++ b/app/Models/Country.php
@@ -0,0 +1,33 @@
+ 'integer',
+ 'language_codes' => 'array',
+ ];
+
+ public function cities(): HasMany
+ {
+ return $this->hasMany(City::class);
+ }
+}
diff --git a/app/Models/Course.php b/app/Models/Course.php
new file mode 100644
index 0000000..7020360
--- /dev/null
+++ b/app/Models/Course.php
@@ -0,0 +1,89 @@
+ 'integer',
+ 'lecturer_id' => 'integer',
+ ];
+
+ protected static function booted()
+ {
+ static::creating(function ($model) {
+ if (! $model->created_by) {
+ $model->created_by = auth()->id();
+ }
+ });
+ }
+
+ public function registerMediaConversions(Media $media = null): void
+ {
+ $this
+ ->addMediaConversion('preview')
+ ->fit(Fit::Crop, 300, 300)
+ ->nonQueued();
+ $this->addMediaConversion('thumb')
+ ->fit(Fit::Crop, 130, 130)
+ ->width(130)
+ ->height(130);
+ }
+
+ public function registerMediaCollections(): void
+ {
+ $this->addMediaCollection('logo')
+ ->singleFile()
+ ->useFallbackUrl(asset('img/einundzwanzig.png'));
+ $this->addMediaCollection('images')
+ ->useFallbackUrl(asset('img/einundzwanzig.png'));
+ }
+
+ public function createdBy(): BelongsTo
+ {
+ return $this->belongsTo(User::class, 'created_by');
+ }
+
+ public function categories(): BelongsToMany
+ {
+ return $this->belongsToMany(Category::class);
+ }
+
+ public function lecturer(): BelongsTo
+ {
+ return $this->belongsTo(Lecturer::class);
+ }
+
+ public function courseEvents(): HasMany
+ {
+ return $this->hasMany(CourseEvent::class);
+ }
+}
diff --git a/app/Models/CourseEvent.php b/app/Models/CourseEvent.php
new file mode 100644
index 0000000..add5c0c
--- /dev/null
+++ b/app/Models/CourseEvent.php
@@ -0,0 +1,56 @@
+ 'integer',
+ 'course_id' => 'integer',
+ 'venue_id' => 'integer',
+ 'from' => 'datetime',
+ 'to' => 'datetime',
+ ];
+
+ protected static function booted()
+ {
+ static::creating(function ($model) {
+ if (! $model->created_by) {
+ $model->created_by = auth()->id();
+ }
+ });
+ }
+
+ public function createdBy(): BelongsTo
+ {
+ return $this->belongsTo(User::class, 'created_by');
+ }
+
+ public function course(): BelongsTo
+ {
+ return $this->belongsTo(Course::class);
+ }
+
+ public function venue(): BelongsTo
+ {
+ return $this->belongsTo(Venue::class);
+ }
+}
diff --git a/app/Models/EinundzwanzigPleb.php b/app/Models/EinundzwanzigPleb.php
new file mode 100644
index 0000000..7afe49e
--- /dev/null
+++ b/app/Models/EinundzwanzigPleb.php
@@ -0,0 +1,17 @@
+hasOne(Profile::class, 'pubkey', 'pubkey');
+ }
+
+}
diff --git a/app/Models/Event.php b/app/Models/Event.php
new file mode 100644
index 0000000..501a161
--- /dev/null
+++ b/app/Models/Event.php
@@ -0,0 +1,17 @@
+hasOne(RenderedEvent::class, 'event_id', 'event_id');
+ }
+
+}
diff --git a/app/Models/Lecturer.php b/app/Models/Lecturer.php
new file mode 100644
index 0000000..e0844e0
--- /dev/null
+++ b/app/Models/Lecturer.php
@@ -0,0 +1,99 @@
+ 'integer',
+ 'active' => 'boolean',
+ ];
+
+ protected static function booted()
+ {
+ static::creating(function ($model) {
+ if (!$model->created_by) {
+ $model->created_by = auth()->id();
+ }
+ });
+ }
+
+ public function registerMediaConversions(Media $media = null): void
+ {
+ $this
+ ->addMediaConversion('preview')
+ ->fit(Fit::Crop, 300, 300)
+ ->nonQueued();
+ $this->addMediaConversion('thumb')
+ ->fit(Fit::Crop, 130, 130)
+ ->width(130)
+ ->height(130);
+ }
+
+ public function registerMediaCollections(): void
+ {
+ $this->addMediaCollection('avatar')
+ ->singleFile()
+ ->useFallbackUrl(asset('img/einundzwanzig.png'));
+ $this->addMediaCollection('images')
+ ->useFallbackUrl(asset('img/einundzwanzig.png'));
+ }
+
+ /**
+ * Get the options for generating the slug.
+ */
+ public function getSlugOptions(): SlugOptions
+ {
+ return SlugOptions::create()
+ ->generateSlugsFrom(['name'])
+ ->saveSlugsTo('slug')
+ ->usingLanguage(Cookie::get('lang', config('app.locale')));
+ }
+
+ public function createdBy(): BelongsTo
+ {
+ return $this->belongsTo(User::class, 'created_by');
+ }
+
+ public function courses(): HasMany
+ {
+ return $this->hasMany(Course::class);
+ }
+
+ public function coursesEvents(): HasManyThrough
+ {
+ return $this->hasManyThrough(CourseEvent::class, Course::class);
+ }
+
+ public function libraryItems(): HasMany
+ {
+ return $this->hasMany(LibraryItem::class);
+ }
+}
diff --git a/app/Models/Meetup.php b/app/Models/Meetup.php
new file mode 100644
index 0000000..07c8f94
--- /dev/null
+++ b/app/Models/Meetup.php
@@ -0,0 +1,136 @@
+ 'integer',
+ 'city_id' => 'integer',
+ 'github_data' => 'json',
+ 'simplified_geojson' => 'array',
+ ];
+
+ protected static function booted()
+ {
+ static::creating(function ($model) {
+ if (!$model->created_by) {
+ $model->created_by = auth()->id();
+ }
+ });
+ }
+
+ public function getSlugOptions(): SlugOptions
+ {
+ return SlugOptions::create()
+ ->generateSlugsFrom(['name'])
+ ->saveSlugsTo('slug')
+ ->usingLanguage(Cookie::get('lang', config('app.locale')));
+ }
+
+ public function registerMediaConversions(Media $media = null): void
+ {
+ $this
+ ->addMediaConversion('preview')
+ ->fit(Fit::Crop, 300, 300)
+ ->nonQueued();
+ $this->addMediaConversion('thumb')
+ ->fit(Fit::Crop, 130, 130)
+ ->width(130)
+ ->height(130);
+ }
+
+ public function registerMediaCollections(): void
+ {
+ $this->addMediaCollection('logo')
+ ->singleFile()
+ ->useFallbackUrl(asset('img/einundzwanzig.png'));
+ }
+
+ public function createdBy(): BelongsTo
+ {
+ return $this->belongsTo(User::class, 'created_by');
+ }
+
+ public function users()
+ {
+ return $this->belongsToMany(User::class);
+ }
+
+ public function city(): BelongsTo
+ {
+ return $this->belongsTo(City::class);
+ }
+
+ protected function logoSquare(): Attribute
+ {
+ $media = $this->getFirstMedia('logo');
+ if ($media) {
+ $path = str($media->getPath())->after('storage/app/');
+ } else {
+ $path = 'img/einundzwanzig.png';
+ }
+
+ return Attribute::make(
+ get: fn() => url()->route('img',
+ [
+ 'path' => $path,
+ 'w' => 900,
+ 'h' => 900,
+ 'fit' => 'crop',
+ 'fm' => 'webp',
+ ]),
+ );
+ }
+
+ protected function nextEvent(): Attribute
+ {
+ $nextEvent = $this->meetupEvents()->where('start', '>=', now())->orderBy('start')->first();
+
+ return Attribute::make(
+ get: fn() => $nextEvent ? [
+ 'start' => $nextEvent->start->toDateTimeString(),
+ 'portalLink' => url()->route('meetup.event.landing', ['country' => $this->city->country, 'meetupEvent' => $nextEvent]),
+ 'location' => $nextEvent->location,
+ 'description' => $nextEvent->description,
+ 'link' => $nextEvent->link,
+ 'attendees' => count($nextEvent->attendees ?? []),
+ 'nostr_note' => str($nextEvent->nostr_status)->after('Sent event ')->before(' to '),
+ ] : null,
+ );
+ }
+
+ public function meetupEvents(): HasMany
+ {
+ return $this->hasMany(MeetupEvent::class);
+ }
+}
diff --git a/app/Models/MeetupEvent.php b/app/Models/MeetupEvent.php
new file mode 100644
index 0000000..52d1617
--- /dev/null
+++ b/app/Models/MeetupEvent.php
@@ -0,0 +1,50 @@
+ 'integer',
+ 'meetup_id' => 'integer',
+ 'start' => 'datetime',
+ 'attendees' => 'array',
+ 'might_attendees' => 'array',
+ ];
+
+ protected static function booted()
+ {
+ static::creating(function ($model) {
+ if (! $model->created_by) {
+ $model->created_by = auth()->id();
+ }
+ });
+ }
+
+ public function createdBy(): BelongsTo
+ {
+ return $this->belongsTo(User::class, 'created_by');
+ }
+
+ public function meetup(): BelongsTo
+ {
+ return $this->belongsTo(Meetup::class);
+ }
+}
diff --git a/app/Models/Profile.php b/app/Models/Profile.php
new file mode 100644
index 0000000..ec17416
--- /dev/null
+++ b/app/Models/Profile.php
@@ -0,0 +1,12 @@
+belongsTo(Event::class, 'event_id', 'event_id');
+ }
+}
diff --git a/app/Models/Venue.php b/app/Models/Venue.php
new file mode 100644
index 0000000..b0eeb1d
--- /dev/null
+++ b/app/Models/Venue.php
@@ -0,0 +1,104 @@
+ 'integer',
+ 'city_id' => 'integer',
+ ];
+
+ protected static function booted()
+ {
+ static::creating(function ($model) {
+ if (! $model->created_by) {
+ $model->created_by = auth()->id();
+ }
+ });
+ }
+
+ public function registerMediaConversions(Media $media = null): void
+ {
+ $this
+ ->addMediaConversion('preview')
+ ->fit(Fit::Crop, 300, 300)
+ ->nonQueued();
+ $this->addMediaConversion('thumb')
+ ->fit(Fit::Crop, 130, 130)
+ ->width(130)
+ ->height(130);
+ }
+
+ public function registerMediaCollections(): void
+ {
+ $this->addMediaCollection('images')
+ ->useFallbackUrl(asset('img/einundzwanzig.png'));
+ }
+
+ /**
+ * Get the options for generating the slug.
+ */
+ public function getSlugOptions(): SlugOptions
+ {
+ return SlugOptions::create()
+ ->generateSlugsFrom(['city.slug', 'name'])
+ ->saveSlugsTo('slug')
+ ->usingLanguage(Cookie::get('lang', config('app.locale')));
+ }
+
+ public function createdBy(): BelongsTo
+ {
+ return $this->belongsTo(User::class, 'created_by');
+ }
+
+ public function city(): BelongsTo
+ {
+ return $this->belongsTo(City::class);
+ }
+
+ public function lecturers()
+ {
+ return $this->hasManyDeepFromRelations($this->courses(), (new Course())->lecturer());
+ }
+
+ public function courses()
+ {
+ return $this->hasManyDeepFromRelations($this->events(), (new CourseEvent())->course());
+ }
+
+ public function courseEvents(): HasMany
+ {
+ return $this->hasMany(CourseEvent::class);
+ }
+}
diff --git a/app/Providers/FolioServiceProvider.php b/app/Providers/FolioServiceProvider.php
new file mode 100644
index 0000000..38b389a
--- /dev/null
+++ b/app/Providers/FolioServiceProvider.php
@@ -0,0 +1,29 @@
+middleware([
+ '*' => [
+ //
+ ],
+ ]);
+ }
+}
diff --git a/app/Providers/VoltServiceProvider.php b/app/Providers/VoltServiceProvider.php
new file mode 100644
index 0000000..e61d984
--- /dev/null
+++ b/app/Providers/VoltServiceProvider.php
@@ -0,0 +1,28 @@
+json, true, 512, JSON_THROW_ON_ERROR)['content'];
+ $profile = Profile::query()->where('pubkey', $event->pubkey)->first();
+ if ($profile && $profile->name) {
+ $name = $profile->name;
+ } elseif ($profile && !empty($profile->display_name)) {
+ $name = $profile->display_name;
+ } else {
+ $name = 'Anonymous';
+ }
+
+ $content = $this->nprofile1($content);
+ $content = $this->images($content);
+ $content = $this->youtube($content);
+ $content = $this->npub1($content);
+
+ RenderedEvent::query()->updateOrCreate([
+ 'event_id' => $event->event_id,
+ ], [
+ 'html' => $content,
+ 'profile_image' => $profile && $profile->picture !== '' ? $profile->picture : 'https://robohash.org/' . $profile->pubkey,
+ 'profile_name' => $name,
+ ]);
+ }
+
+ protected function images($content): string
+ {
+ // we need to find all image urls by looking for the extension
+ // and replace them with the img tag
+ $pattern = '/(https?:\/\/.*\.(?:png|jpg|jpeg|gif|webp))/';
+ $replacement = '

';
+
+ return preg_replace($pattern, $replacement, $content);
+ }
+
+ protected function npub1($content): string
+ {
+ // Pattern to match nostr:npub1 elements, optionally followed by a non-alphanumeric character
+ $pattern = '/(nostr:npub1[a-zA-Z0-9]+)(\W?)/';
+ // find all matches of the pattern
+ preg_match_all($pattern, $content, $matches);
+ // loop through all matches
+ foreach ($matches[1] as $match) {
+ $pubkey = (new Key)->convertToHex(str($match)->after('nostr:'));
+ $profile = Profile::query()->where('pubkey', $pubkey)->first();
+ if ($profile && $profile->name) {
+ $name = $profile->name;
+ } elseif ($profile && !empty($profile->display_name)) {
+ $name = $profile->display_name;
+ } else {
+ $name = 'Anonymous';
+ }
+ // replace the match with the profile name
+ $content = str_replace($match, $name, $content);
+ }
+
+ return $content;
+ }
+
+ protected function nprofile1($content): string
+ {
+ // todo: implement this
+
+ return $content;
+ }
+
+ protected function youtube($content): string
+ {
+ // Pattern to match YouTube short URLs like https://youtu.be/ddvHagjmRJY?feature=shared
+ $pattern1 = '/https:\/\/youtu.be\/([a-zA-Z0-9-_]+)\??.*/';
+ $replacement1 = '';
+
+ // Pattern to match YouTube long URLs like https://www.youtube.com/watch?v=tiNZoDBGhdo
+ $pattern2 = '/https:\/\/www.youtube.com\/watch\?v=([a-zA-Z0-9-_]+)\??.*/';
+ $replacement2 = '';
+
+ // Replace both patterns in the content
+ $content = preg_replace($pattern1, $replacement1, $content);
+ $content = preg_replace($pattern2, $replacement2, $content);
+
+ return $content;
+ }
+}
diff --git a/app/Traits/NostrFetcherTrait.php b/app/Traits/NostrFetcherTrait.php
new file mode 100644
index 0000000..340ca60
--- /dev/null
+++ b/app/Traits/NostrFetcherTrait.php
@@ -0,0 +1,68 @@
+push([
+ 'hex' => (new Key)->convertToHex($item),
+ 'npub' => $item,
+ ]);
+ }
+
+ $subscription = new Subscription();
+ $subscriptionId = $subscription->setId();
+
+ $filter1 = new Filter();
+ $filter1->setKinds([0]); // You can add multiple kind numbers
+ $filter1->setAuthors($hex->pluck('hex')->toArray()); // You can add multiple author ids
+ $filters = [$filter1]; // You can add multiple filters.
+
+ $requestMessage = new RequestMessage($subscriptionId, $filters);
+
+ $relayUrl = 'wss://relay.nostr.band/';
+ $relay = new Relay($relayUrl);
+ $relay->setMessage($requestMessage);
+
+ $request = new Request($relay, $requestMessage);
+ $response = $request->send();
+
+ foreach ($response['wss://relay.nostr.band/'] as $item) {
+ try {
+ $result = json_decode($item->event->content, true, 512, JSON_THROW_ON_ERROR);
+ } catch (\JsonException $e) {
+ throw new \RuntimeException('Error decoding JSON: ' . $e->getMessage());
+ }
+ Profile::query()->updateOrCreate(
+ ['pubkey' => $item->event->pubkey],
+ [
+ 'name' => $result['name'] ?? null,
+ 'display_name' => $result['display_name'] ?? null,
+ 'picture' => $result['picture'] ?? null,
+ 'banner' => $result['banner'] ?? null,
+ 'website' => $result['website'] ?? null,
+ 'about' => $result['about'] ?? null,
+ 'nip05' => $result['nip05'] ?? null,
+ 'lud16' => $result['lud16'] ?? null,
+ 'lud06' => $result['lud06'] ?? null,
+ 'deleted' => $result['deleted'] ?? false,
+ ]
+ );
+ }
+
+ }
+
+}
diff --git a/bootstrap/app.php b/bootstrap/app.php
index 7b162da..2e4d7c7 100644
--- a/bootstrap/app.php
+++ b/bootstrap/app.php
@@ -8,6 +8,7 @@ return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
+ channels: __DIR__.'/../routes/channels.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
diff --git a/bootstrap/providers.php b/bootstrap/providers.php
index 38b258d..90915e8 100644
--- a/bootstrap/providers.php
+++ b/bootstrap/providers.php
@@ -2,4 +2,6 @@
return [
App\Providers\AppServiceProvider::class,
+ App\Providers\FolioServiceProvider::class,
+ App\Providers\VoltServiceProvider::class,
];
diff --git a/composer.json b/composer.json
index 4bddd40..c6fde73 100644
--- a/composer.json
+++ b/composer.json
@@ -6,13 +6,29 @@
"license": "MIT",
"require": {
"php": "^8.2",
+ "akuechler/laravel-geoly": "^1.0",
+ "calebporzio/sushi": "^2.5",
+ "laravel/folio": "^1.1",
"laravel/framework": "^11.9",
- "laravel/tinker": "^2.9"
+ "laravel/pulse": "^1.2",
+ "laravel/reverb": "^1.0",
+ "laravel/sail": "^1.31",
+ "laravel/tinker": "^2.9",
+ "livewire/livewire": "^3.5",
+ "livewire/volt": "^1.6",
+ "openspout/openspout": "^4.24",
+ "power-components/livewire-powergrid": "^5.10",
+ "spatie/image": "^3.7",
+ "spatie/laravel-google-fonts": "^1.4",
+ "spatie/laravel-medialibrary": "^11.9",
+ "spatie/laravel-sluggable": "^3.6",
+ "spatie/laravel-tags": "^4.6",
+ "staudenmeir/eloquent-has-many-deep": "^1.7",
+ "swentel/nostr-php": "^1.4"
},
"require-dev": {
"fakerphp/faker": "^1.23",
"laravel/pint": "^1.13",
- "laravel/sail": "^1.26",
"mockery/mockery": "^1.6",
"nunomaduro/collision": "^8.0",
"pestphp/pest": "^2.35",
diff --git a/composer.lock b/composer.lock
index 5a89037..dd3878d 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,8 +4,112 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "24c05191d00f03d827cb3021060580ee",
+ "content-hash": "6e2e55d8f8eff735c8f3eafb06ad3c0b",
"packages": [
+ {
+ "name": "akuechler/laravel-geoly",
+ "version": "v1.0.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/akuechler/laravel-geoly.git",
+ "reference": "07b76c573abe1049d9a3f65ee870649443903dbf"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/akuechler/laravel-geoly/zipball/07b76c573abe1049d9a3f65ee870649443903dbf",
+ "reference": "07b76c573abe1049d9a3f65ee870649443903dbf",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "require-dev": {
+ "orchestra/testbench": "^6.0@dev",
+ "phpunit/phpunit": "^9.2@dev"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Akuechler\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Alexsander Küchler",
+ "email": "composer@alexsander-kuechler.com"
+ }
+ ],
+ "description": "Perform fast and efficient radius searches on your Laravel Eloquent models.",
+ "keywords": [
+ "distance",
+ "framework",
+ "geo",
+ "laravel",
+ "lat",
+ "latitude",
+ "lng",
+ "lon",
+ "longitude",
+ "models",
+ "radius",
+ "search"
+ ],
+ "support": {
+ "issues": "https://github.com/akuechler/laravel-geoly/issues",
+ "source": "https://github.com/akuechler/laravel-geoly/tree/v1.0.6"
+ },
+ "time": "2021-04-20T07:17:32+00:00"
+ },
+ {
+ "name": "bitwasp/bech32",
+ "version": "v0.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Bit-Wasp/bech32.git",
+ "reference": "e1ea58c848a4ec59d81b697b3dfe9cc99968d0e7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Bit-Wasp/bech32/zipball/e1ea58c848a4ec59d81b697b3dfe9cc99968d0e7",
+ "reference": "e1ea58c848a4ec59d81b697b3dfe9cc99968d0e7",
+ "shasum": ""
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.4.0",
+ "squizlabs/php_codesniffer": "^2.0.0"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "src/bech32.php"
+ ],
+ "psr-4": {
+ "BitWasp\\Bech32\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Unlicense"
+ ],
+ "authors": [
+ {
+ "name": "Thomas Kerin",
+ "homepage": "https://thomaskerin.io",
+ "role": "Author"
+ }
+ ],
+ "description": "Pure (no dependencies) implementation of bech32",
+ "homepage": "https://github.com/bit-wasp/bech32",
+ "support": {
+ "issues": "https://github.com/Bit-Wasp/bech32/issues",
+ "source": "https://github.com/Bit-Wasp/bech32/tree/more-tests"
+ },
+ "time": "2018-02-05T22:23:47+00:00"
+ },
{
"name": "brick/math",
"version": "0.12.1",
@@ -66,6 +170,60 @@
],
"time": "2023-11-29T23:19:16+00:00"
},
+ {
+ "name": "calebporzio/sushi",
+ "version": "v2.5.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/calebporzio/sushi.git",
+ "reference": "01dd34fe3374f5fb7ce63756c0419385e31cd532"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/calebporzio/sushi/zipball/01dd34fe3374f5fb7ce63756c0419385e31cd532",
+ "reference": "01dd34fe3374f5fb7ce63756c0419385e31cd532",
+ "shasum": ""
+ },
+ "require": {
+ "ext-pdo_sqlite": "*",
+ "ext-sqlite3": "*",
+ "illuminate/database": "^5.8 || ^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0 || ^11.0",
+ "illuminate/support": "^5.8 || ^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0 || ^11.0",
+ "php": "^7.1.3|^8.0"
+ },
+ "require-dev": {
+ "doctrine/dbal": "^2.9 || ^3.1.4",
+ "orchestra/testbench": "3.8.* || 3.9.* || ^4.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0",
+ "phpunit/phpunit": "^7.5 || ^8.4 || ^9.0 || ^10.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Sushi\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Caleb Porzio",
+ "email": "calebporzio@gmail.com"
+ }
+ ],
+ "description": "Eloquent's missing \"array\" driver.",
+ "support": {
+ "source": "https://github.com/calebporzio/sushi/tree/v2.5.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/calebporzio",
+ "type": "github"
+ }
+ ],
+ "time": "2024-04-24T15:23:03+00:00"
+ },
{
"name": "carbonphp/carbon-doctrine-types",
"version": "3.2.0",
@@ -135,6 +293,217 @@
],
"time": "2024-02-09T16:56:22+00:00"
},
+ {
+ "name": "clue/redis-protocol",
+ "version": "v0.3.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/clue/redis-protocol.git",
+ "reference": "6f565332f5531b7722d1e9c445314b91862f6d6c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/clue/redis-protocol/zipball/6f565332f5531b7722d1e9c445314b91862f6d6c",
+ "reference": "6f565332f5531b7722d1e9c445314b91862f6d6c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Clue\\Redis\\Protocol\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Christian Lück",
+ "email": "christian@lueck.tv"
+ }
+ ],
+ "description": "A streaming Redis protocol (RESP) parser and serializer written in pure PHP.",
+ "homepage": "https://github.com/clue/redis-protocol",
+ "keywords": [
+ "parser",
+ "protocol",
+ "redis",
+ "resp",
+ "serializer",
+ "streaming"
+ ],
+ "support": {
+ "issues": "https://github.com/clue/redis-protocol/issues",
+ "source": "https://github.com/clue/redis-protocol/tree/v0.3.2"
+ },
+ "funding": [
+ {
+ "url": "https://clue.engineering/support",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/clue",
+ "type": "github"
+ }
+ ],
+ "time": "2024-08-07T11:06:28+00:00"
+ },
+ {
+ "name": "clue/redis-react",
+ "version": "v2.7.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/clue/reactphp-redis.git",
+ "reference": "2283690f249e8d93342dd63b5285732d2654e077"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/clue/reactphp-redis/zipball/2283690f249e8d93342dd63b5285732d2654e077",
+ "reference": "2283690f249e8d93342dd63b5285732d2654e077",
+ "shasum": ""
+ },
+ "require": {
+ "clue/redis-protocol": "0.3.*",
+ "evenement/evenement": "^3.0 || ^2.0 || ^1.0",
+ "php": ">=5.3",
+ "react/event-loop": "^1.2",
+ "react/promise": "^3 || ^2.0 || ^1.1",
+ "react/promise-timer": "^1.9",
+ "react/socket": "^1.12"
+ },
+ "require-dev": {
+ "clue/block-react": "^1.5",
+ "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Clue\\React\\Redis\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Christian Lück",
+ "email": "christian@clue.engineering"
+ }
+ ],
+ "description": "Async Redis client implementation, built on top of ReactPHP.",
+ "homepage": "https://github.com/clue/reactphp-redis",
+ "keywords": [
+ "async",
+ "client",
+ "database",
+ "reactphp",
+ "redis"
+ ],
+ "support": {
+ "issues": "https://github.com/clue/reactphp-redis/issues",
+ "source": "https://github.com/clue/reactphp-redis/tree/v2.7.0"
+ },
+ "funding": [
+ {
+ "url": "https://clue.engineering/support",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/clue",
+ "type": "github"
+ }
+ ],
+ "time": "2024-01-05T15:54:20+00:00"
+ },
+ {
+ "name": "composer/semver",
+ "version": "3.4.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/semver.git",
+ "reference": "c51258e759afdb17f1fd1fe83bc12baaef6309d6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/semver/zipball/c51258e759afdb17f1fd1fe83bc12baaef6309d6",
+ "reference": "c51258e759afdb17f1fd1fe83bc12baaef6309d6",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.2 || ^7.0 || ^8.0"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "^1.4",
+ "symfony/phpunit-bridge": "^4.2 || ^5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Composer\\Semver\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nils Adermann",
+ "email": "naderman@naderman.de",
+ "homepage": "http://www.naderman.de"
+ },
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ },
+ {
+ "name": "Rob Bast",
+ "email": "rob.bast@gmail.com",
+ "homepage": "http://robbast.nl"
+ }
+ ],
+ "description": "Semver library that offers utilities, version constraint parsing and validation.",
+ "keywords": [
+ "semantic",
+ "semver",
+ "validation",
+ "versioning"
+ ],
+ "support": {
+ "irc": "ircs://irc.libera.chat:6697/composer",
+ "issues": "https://github.com/composer/semver/issues",
+ "source": "https://github.com/composer/semver/tree/3.4.2"
+ },
+ "funding": [
+ {
+ "url": "https://packagist.com",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/composer",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2024-07-12T11:35:52+00:00"
+ },
{
"name": "dflydev/dot-access-data",
"version": "v3.0.3",
@@ -378,6 +747,61 @@
],
"time": "2024-02-05T11:56:58+00:00"
},
+ {
+ "name": "doctrine/sql-formatter",
+ "version": "1.4.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/sql-formatter.git",
+ "reference": "7f83911cc5eba870de7ebb11283972483f7e2891"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/sql-formatter/zipball/7f83911cc5eba870de7ebb11283972483f7e2891",
+ "reference": "7f83911cc5eba870de7ebb11283972483f7e2891",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^8.1"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^12",
+ "phpstan/phpstan": "^1.10",
+ "phpunit/phpunit": "^10.5",
+ "vimeo/psalm": "^5.24"
+ },
+ "bin": [
+ "bin/sql-formatter"
+ ],
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\SqlFormatter\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jeremy Dorn",
+ "email": "jeremy@jeremydorn.com",
+ "homepage": "https://jeremydorn.com/"
+ }
+ ],
+ "description": "a PHP SQL highlighting library",
+ "homepage": "https://github.com/doctrine/sql-formatter/",
+ "keywords": [
+ "highlight",
+ "sql"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/sql-formatter/issues",
+ "source": "https://github.com/doctrine/sql-formatter/tree/1.4.1"
+ },
+ "time": "2024-08-05T20:32:22+00:00"
+ },
{
"name": "dragonmantank/cron-expression",
"version": "v3.3.3",
@@ -506,6 +930,129 @@
],
"time": "2023-10-06T06:47:41+00:00"
},
+ {
+ "name": "evenement/evenement",
+ "version": "v3.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/igorw/evenement.git",
+ "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/igorw/evenement/zipball/0a16b0d71ab13284339abb99d9d2bd813640efbc",
+ "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9 || ^6"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Evenement\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Igor Wiedler",
+ "email": "igor@wiedler.ch"
+ }
+ ],
+ "description": "Événement is a very simple event dispatching library for PHP",
+ "keywords": [
+ "event-dispatcher",
+ "event-emitter"
+ ],
+ "support": {
+ "issues": "https://github.com/igorw/evenement/issues",
+ "source": "https://github.com/igorw/evenement/tree/v3.0.2"
+ },
+ "time": "2023-08-08T05:53:35+00:00"
+ },
+ {
+ "name": "fgrosse/phpasn1",
+ "version": "v2.5.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/fgrosse/PHPASN1.git",
+ "reference": "42060ed45344789fb9f21f9f1864fc47b9e3507b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/fgrosse/PHPASN1/zipball/42060ed45344789fb9f21f9f1864fc47b9e3507b",
+ "reference": "42060ed45344789fb9f21f9f1864fc47b9e3507b",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1 || ^8.0"
+ },
+ "require-dev": {
+ "php-coveralls/php-coveralls": "~2.0",
+ "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
+ },
+ "suggest": {
+ "ext-bcmath": "BCmath is the fallback extension for big integer calculations",
+ "ext-curl": "For loading OID information from the web if they have not bee defined statically",
+ "ext-gmp": "GMP is the preferred extension for big integer calculations",
+ "phpseclib/bcmath_compat": "BCmath polyfill for servers where neither GMP nor BCmath is available"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "FG\\": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Friedrich Große",
+ "email": "friedrich.grosse@gmail.com",
+ "homepage": "https://github.com/FGrosse",
+ "role": "Author"
+ },
+ {
+ "name": "All contributors",
+ "homepage": "https://github.com/FGrosse/PHPASN1/contributors"
+ }
+ ],
+ "description": "A PHP Framework that allows you to encode and decode arbitrary ASN.1 structures using the ITU-T X.690 Encoding Rules.",
+ "homepage": "https://github.com/FGrosse/PHPASN1",
+ "keywords": [
+ "DER",
+ "asn.1",
+ "asn1",
+ "ber",
+ "binary",
+ "decoding",
+ "encoding",
+ "x.509",
+ "x.690",
+ "x509",
+ "x690"
+ ],
+ "support": {
+ "issues": "https://github.com/fgrosse/PHPASN1/issues",
+ "source": "https://github.com/fgrosse/PHPASN1/tree/v2.5.0"
+ },
+ "abandoned": true,
+ "time": "2022-12-19T11:08:26+00:00"
+ },
{
"name": "fruitcake/php-cors",
"version": "v1.3.0",
@@ -1051,17 +1598,90 @@
"time": "2023-12-03T19:50:20+00:00"
},
{
- "name": "laravel/framework",
- "version": "v11.21.0",
+ "name": "laravel/folio",
+ "version": "v1.1.8",
"source": {
"type": "git",
- "url": "https://github.com/laravel/framework.git",
- "reference": "9d9d36708d56665b12185493f684abce38ad2d30"
+ "url": "https://github.com/laravel/folio.git",
+ "reference": "3b6e8de60ca7487364d1cd35378069c111963f78"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/framework/zipball/9d9d36708d56665b12185493f684abce38ad2d30",
- "reference": "9d9d36708d56665b12185493f684abce38ad2d30",
+ "url": "https://api.github.com/repos/laravel/folio/zipball/3b6e8de60ca7487364d1cd35378069c111963f78",
+ "reference": "3b6e8de60ca7487364d1cd35378069c111963f78",
+ "shasum": ""
+ },
+ "require": {
+ "illuminate/console": "^10.19|^11.0",
+ "illuminate/container": "^10.19|^11.0",
+ "illuminate/contracts": "^10.19|^11.0",
+ "illuminate/filesystem": "^10.19|^11.0",
+ "illuminate/pipeline": "^10.19|^11.0",
+ "illuminate/routing": "^10.19|^11.0",
+ "illuminate/support": "^10.19|^11.0",
+ "illuminate/view": "^10.19|^11.0",
+ "php": "^8.1",
+ "spatie/once": "^3.1",
+ "symfony/console": "^6.0|^7.0"
+ },
+ "require-dev": {
+ "orchestra/testbench": "^8.6.0|^9.0",
+ "pestphp/pest": "^2.5",
+ "phpstan/phpstan": "^1.10"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.x-dev"
+ },
+ "laravel": {
+ "providers": [
+ "Laravel\\Folio\\FolioServiceProvider"
+ ]
+ }
+ },
+ "autoload": {
+ "files": [
+ "functions.php"
+ ],
+ "psr-4": {
+ "Laravel\\Folio\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
+ }
+ ],
+ "description": "Page based routing for Laravel.",
+ "homepage": "https://github.com/laravel/folio",
+ "keywords": [
+ "laravel",
+ "routing"
+ ],
+ "support": {
+ "issues": "https://github.com/laravel/folio/issues",
+ "source": "https://github.com/laravel/folio"
+ },
+ "time": "2024-05-07T13:37:42+00:00"
+ },
+ {
+ "name": "laravel/framework",
+ "version": "v11.22.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/laravel/framework.git",
+ "reference": "868c75beacc47d0f361b919bbc155c0b619bf3d5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/laravel/framework/zipball/868c75beacc47d0f361b919bbc155c0b619bf3d5",
+ "reference": "868c75beacc47d0f361b919bbc155c0b619bf3d5",
"shasum": ""
},
"require": {
@@ -1254,7 +1874,7 @@
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
- "time": "2024-08-20T15:00:52+00:00"
+ "time": "2024-09-03T15:27:15+00:00"
},
{
"name": "laravel/prompts",
@@ -1314,6 +1934,238 @@
},
"time": "2024-08-12T22:06:33+00:00"
},
+ {
+ "name": "laravel/pulse",
+ "version": "v1.2.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/laravel/pulse.git",
+ "reference": "0c0c91fd05acc537f6324b271709670ffc201e59"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/laravel/pulse/zipball/0c0c91fd05acc537f6324b271709670ffc201e59",
+ "reference": "0c0c91fd05acc537f6324b271709670ffc201e59",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/sql-formatter": "^1.4.1",
+ "guzzlehttp/promises": "^1.0|^2.0",
+ "illuminate/auth": "^10.48.4|^11.0.8",
+ "illuminate/cache": "^10.48.4|^11.0.8",
+ "illuminate/config": "^10.48.4|^11.0.8",
+ "illuminate/console": "^10.48.4|^11.0.8",
+ "illuminate/contracts": "^10.48.4|^11.0.8",
+ "illuminate/database": "^10.48.4|^11.0.8",
+ "illuminate/events": "^10.48.4|^11.0.8",
+ "illuminate/http": "^10.48.4|^11.0.8",
+ "illuminate/queue": "^10.48.4|^11.0.8",
+ "illuminate/redis": "^10.48.4|^11.0.8",
+ "illuminate/routing": "^10.48.4|^11.0.8",
+ "illuminate/support": "^10.48.4|^11.0.8",
+ "illuminate/view": "^10.48.4|^11.0.8",
+ "livewire/livewire": "^3.4.9",
+ "nesbot/carbon": "^2.67|^3.0",
+ "php": "^8.1",
+ "symfony/console": "^6.0|^7.0"
+ },
+ "conflict": {
+ "nunomaduro/collision": "<7.7.0"
+ },
+ "require-dev": {
+ "guzzlehttp/guzzle": "^7.7",
+ "mockery/mockery": "^1.0",
+ "orchestra/testbench": "^8.23.1|^9.0",
+ "pestphp/pest": "^2.0",
+ "pestphp/pest-plugin-laravel": "^2.2",
+ "phpstan/phpstan": "^1.11",
+ "predis/predis": "^1.0|^2.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.x-dev"
+ },
+ "laravel": {
+ "providers": [
+ "Laravel\\Pulse\\PulseServiceProvider"
+ ],
+ "aliases": {
+ "Pulse": "Laravel\\Pulse\\Facades\\Pulse"
+ }
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Laravel\\Pulse\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
+ }
+ ],
+ "description": "Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.",
+ "homepage": "https://github.com/laravel/pulse",
+ "keywords": [
+ "laravel"
+ ],
+ "support": {
+ "issues": "https://github.com/laravel/pulse/issues",
+ "source": "https://github.com/laravel/pulse"
+ },
+ "time": "2024-09-03T09:21:52+00:00"
+ },
+ {
+ "name": "laravel/reverb",
+ "version": "v1.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/laravel/reverb.git",
+ "reference": "46bb5dd0b14ba0ae9d3dd740e60bca279b689a63"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/laravel/reverb/zipball/46bb5dd0b14ba0ae9d3dd740e60bca279b689a63",
+ "reference": "46bb5dd0b14ba0ae9d3dd740e60bca279b689a63",
+ "shasum": ""
+ },
+ "require": {
+ "clue/redis-react": "^2.6",
+ "guzzlehttp/psr7": "^2.6",
+ "illuminate/console": "^10.47|^11.0",
+ "illuminate/contracts": "^10.47|^11.0",
+ "illuminate/http": "^10.47|^11.0",
+ "illuminate/support": "^10.47|^11.0",
+ "laravel/prompts": "^0.1.15",
+ "php": "^8.2",
+ "pusher/pusher-php-server": "^7.2",
+ "ratchet/rfc6455": "^0.3.1",
+ "react/promise-timer": "^1.10",
+ "react/socket": "^1.14",
+ "symfony/console": "^6.0|^7.0",
+ "symfony/http-foundation": "^6.3|^7.0"
+ },
+ "require-dev": {
+ "orchestra/testbench": "^8.0|^9.0",
+ "pestphp/pest": "^2.0",
+ "phpstan/phpstan": "^1.10",
+ "ratchet/pawl": "^0.4.1",
+ "react/async": "^4.2",
+ "react/http": "^1.9"
+ },
+ "type": "library",
+ "extra": {
+ "laravel": {
+ "providers": [
+ "Laravel\\Reverb\\ApplicationManagerServiceProvider",
+ "Laravel\\Reverb\\ReverbServiceProvider"
+ ],
+ "aliases": {
+ "Output": "Laravel\\Reverb\\Output"
+ }
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Laravel\\Reverb\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
+ },
+ {
+ "name": "Joe Dixon",
+ "email": "joe@laravel.com"
+ }
+ ],
+ "description": "Laravel Reverb provides a real-time WebSocket communication backend for Laravel applications.",
+ "keywords": [
+ "WebSockets",
+ "laravel",
+ "real-time",
+ "websocket"
+ ],
+ "support": {
+ "issues": "https://github.com/laravel/reverb/issues",
+ "source": "https://github.com/laravel/reverb/tree/v1.3.0"
+ },
+ "time": "2024-09-03T10:04:47+00:00"
+ },
+ {
+ "name": "laravel/sail",
+ "version": "v1.31.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/laravel/sail.git",
+ "reference": "0a7e2891a85eba2d448a9ffc6fc5ce367e924bc1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/laravel/sail/zipball/0a7e2891a85eba2d448a9ffc6fc5ce367e924bc1",
+ "reference": "0a7e2891a85eba2d448a9ffc6fc5ce367e924bc1",
+ "shasum": ""
+ },
+ "require": {
+ "illuminate/console": "^9.52.16|^10.0|^11.0",
+ "illuminate/contracts": "^9.52.16|^10.0|^11.0",
+ "illuminate/support": "^9.52.16|^10.0|^11.0",
+ "php": "^8.0",
+ "symfony/console": "^6.0|^7.0",
+ "symfony/yaml": "^6.0|^7.0"
+ },
+ "require-dev": {
+ "orchestra/testbench": "^7.0|^8.0|^9.0",
+ "phpstan/phpstan": "^1.10"
+ },
+ "bin": [
+ "bin/sail"
+ ],
+ "type": "library",
+ "extra": {
+ "laravel": {
+ "providers": [
+ "Laravel\\Sail\\SailServiceProvider"
+ ]
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Laravel\\Sail\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
+ }
+ ],
+ "description": "Docker files for running a basic Laravel application.",
+ "keywords": [
+ "docker",
+ "laravel"
+ ],
+ "support": {
+ "issues": "https://github.com/laravel/sail/issues",
+ "source": "https://github.com/laravel/sail"
+ },
+ "time": "2024-09-03T20:05:33+00:00"
+ },
{
"name": "laravel/serializable-closure",
"version": "v1.3.4",
@@ -1817,6 +2669,235 @@
],
"time": "2024-01-28T23:22:08+00:00"
},
+ {
+ "name": "livewire/livewire",
+ "version": "v3.5.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/livewire/livewire.git",
+ "reference": "597a2808d8d3001cc3ed5ce89a6ebab00f83b80f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/livewire/livewire/zipball/597a2808d8d3001cc3ed5ce89a6ebab00f83b80f",
+ "reference": "597a2808d8d3001cc3ed5ce89a6ebab00f83b80f",
+ "shasum": ""
+ },
+ "require": {
+ "illuminate/database": "^10.0|^11.0",
+ "illuminate/routing": "^10.0|^11.0",
+ "illuminate/support": "^10.0|^11.0",
+ "illuminate/validation": "^10.0|^11.0",
+ "laravel/prompts": "^0.1.24",
+ "league/mime-type-detection": "^1.9",
+ "php": "^8.1",
+ "symfony/console": "^6.0|^7.0",
+ "symfony/http-kernel": "^6.2|^7.0"
+ },
+ "require-dev": {
+ "calebporzio/sushi": "^2.1",
+ "laravel/framework": "^10.15.0|^11.0",
+ "mockery/mockery": "^1.3.1",
+ "orchestra/testbench": "^8.21.0|^9.0",
+ "orchestra/testbench-dusk": "^8.24|^9.1",
+ "phpunit/phpunit": "^10.4",
+ "psy/psysh": "^0.11.22|^0.12"
+ },
+ "type": "library",
+ "extra": {
+ "laravel": {
+ "providers": [
+ "Livewire\\LivewireServiceProvider"
+ ],
+ "aliases": {
+ "Livewire": "Livewire\\Livewire"
+ }
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/helpers.php"
+ ],
+ "psr-4": {
+ "Livewire\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Caleb Porzio",
+ "email": "calebporzio@gmail.com"
+ }
+ ],
+ "description": "A front-end framework for Laravel.",
+ "support": {
+ "issues": "https://github.com/livewire/livewire/issues",
+ "source": "https://github.com/livewire/livewire/tree/v3.5.6"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/livewire",
+ "type": "github"
+ }
+ ],
+ "time": "2024-08-19T11:52:18+00:00"
+ },
+ {
+ "name": "livewire/volt",
+ "version": "v1.6.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/livewire/volt.git",
+ "reference": "d09fdb4cb52c6ce821d255683195bb6d446fe141"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/livewire/volt/zipball/d09fdb4cb52c6ce821d255683195bb6d446fe141",
+ "reference": "d09fdb4cb52c6ce821d255683195bb6d446fe141",
+ "shasum": ""
+ },
+ "require": {
+ "laravel/framework": "^10.38.2|^11.0",
+ "livewire/livewire": "^3.0",
+ "php": "^8.1"
+ },
+ "require-dev": {
+ "laravel/folio": "^1.1",
+ "mockery/mockery": "^1.6",
+ "orchestra/testbench": "^8.15.0|^9.0",
+ "pestphp/pest": "^2.9.5",
+ "phpstan/phpstan": "^1.10"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.x-dev"
+ },
+ "laravel": {
+ "providers": [
+ "Livewire\\Volt\\VoltServiceProvider"
+ ]
+ }
+ },
+ "autoload": {
+ "files": [
+ "functions.php"
+ ],
+ "psr-4": {
+ "Livewire\\Volt\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
+ },
+ {
+ "name": "Nuno Maduro",
+ "email": "nuno@laravel.com"
+ }
+ ],
+ "description": "An elegantly crafted functional API for Laravel Livewire.",
+ "homepage": "https://github.com/livewire/volt",
+ "keywords": [
+ "laravel",
+ "livewire",
+ "volt"
+ ],
+ "support": {
+ "issues": "https://github.com/livewire/volt/issues",
+ "source": "https://github.com/livewire/volt"
+ },
+ "time": "2024-05-31T19:07:20+00:00"
+ },
+ {
+ "name": "maennchen/zipstream-php",
+ "version": "3.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/maennchen/ZipStream-PHP.git",
+ "reference": "b8174494eda667f7d13876b4a7bfef0f62a7c0d1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/b8174494eda667f7d13876b4a7bfef0f62a7c0d1",
+ "reference": "b8174494eda667f7d13876b4a7bfef0f62a7c0d1",
+ "shasum": ""
+ },
+ "require": {
+ "ext-mbstring": "*",
+ "ext-zlib": "*",
+ "php-64bit": "^8.1"
+ },
+ "require-dev": {
+ "ext-zip": "*",
+ "friendsofphp/php-cs-fixer": "^3.16",
+ "guzzlehttp/guzzle": "^7.5",
+ "mikey179/vfsstream": "^1.6",
+ "php-coveralls/php-coveralls": "^2.5",
+ "phpunit/phpunit": "^10.0",
+ "vimeo/psalm": "^5.0"
+ },
+ "suggest": {
+ "guzzlehttp/psr7": "^2.4",
+ "psr/http-message": "^2.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "ZipStream\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Paul Duncan",
+ "email": "pabs@pablotron.org"
+ },
+ {
+ "name": "Jonatan Männchen",
+ "email": "jonatan@maennchen.ch"
+ },
+ {
+ "name": "Jesse Donat",
+ "email": "donatj@gmail.com"
+ },
+ {
+ "name": "András Kolesár",
+ "email": "kolesar@kolesar.hu"
+ }
+ ],
+ "description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.",
+ "keywords": [
+ "stream",
+ "zip"
+ ],
+ "support": {
+ "issues": "https://github.com/maennchen/ZipStream-PHP/issues",
+ "source": "https://github.com/maennchen/ZipStream-PHP/tree/3.1.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/maennchen",
+ "type": "github"
+ },
+ {
+ "url": "https://opencollective.com/zipstream",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2023-06-21T14:59:35+00:00"
+ },
{
"name": "monolog/monolog",
"version": "3.7.0",
@@ -2318,6 +3399,235 @@
],
"time": "2024-03-06T16:17:14+00:00"
},
+ {
+ "name": "openspout/openspout",
+ "version": "v4.24.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/openspout/openspout.git",
+ "reference": "393299ae21153f042f48b185f2adeb4b157d1d93"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/openspout/openspout/zipball/393299ae21153f042f48b185f2adeb4b157d1d93",
+ "reference": "393299ae21153f042f48b185f2adeb4b157d1d93",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-fileinfo": "*",
+ "ext-filter": "*",
+ "ext-libxml": "*",
+ "ext-xmlreader": "*",
+ "ext-zip": "*",
+ "php": "~8.1.0 || ~8.2.0 || ~8.3.0"
+ },
+ "require-dev": {
+ "ext-zlib": "*",
+ "friendsofphp/php-cs-fixer": "^3.60.0",
+ "infection/infection": "^0.29.6",
+ "phpbench/phpbench": "^1.3.1",
+ "phpstan/phpstan": "^1.11.8",
+ "phpstan/phpstan-phpunit": "^1.4.0",
+ "phpstan/phpstan-strict-rules": "^1.6.0",
+ "phpunit/phpunit": "^10.5.20 || ^11.2.8"
+ },
+ "suggest": {
+ "ext-iconv": "To handle non UTF-8 CSV files (if \"php-mbstring\" is not already installed or is too limited)",
+ "ext-mbstring": "To handle non UTF-8 CSV files (if \"iconv\" is not already installed)"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.3.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "OpenSpout\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Adrien Loison",
+ "email": "adrien@box.com"
+ }
+ ],
+ "description": "PHP Library to read and write spreadsheet files (CSV, XLSX and ODS), in a fast and scalable way",
+ "homepage": "https://github.com/openspout/openspout",
+ "keywords": [
+ "OOXML",
+ "csv",
+ "excel",
+ "memory",
+ "odf",
+ "ods",
+ "office",
+ "open",
+ "php",
+ "read",
+ "scale",
+ "spreadsheet",
+ "stream",
+ "write",
+ "xlsx"
+ ],
+ "support": {
+ "issues": "https://github.com/openspout/openspout/issues",
+ "source": "https://github.com/openspout/openspout/tree/v4.24.5"
+ },
+ "funding": [
+ {
+ "url": "https://paypal.me/filippotessarotto",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/Slamdunk",
+ "type": "github"
+ }
+ ],
+ "time": "2024-07-26T05:48:04+00:00"
+ },
+ {
+ "name": "paragonie/random_compat",
+ "version": "v9.99.100",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/paragonie/random_compat.git",
+ "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a",
+ "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">= 7"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.*|5.*",
+ "vimeo/psalm": "^1"
+ },
+ "suggest": {
+ "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
+ },
+ "type": "library",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Paragon Initiative Enterprises",
+ "email": "security@paragonie.com",
+ "homepage": "https://paragonie.com"
+ }
+ ],
+ "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
+ "keywords": [
+ "csprng",
+ "polyfill",
+ "pseudorandom",
+ "random"
+ ],
+ "support": {
+ "email": "info@paragonie.com",
+ "issues": "https://github.com/paragonie/random_compat/issues",
+ "source": "https://github.com/paragonie/random_compat"
+ },
+ "time": "2020-10-15T08:29:30+00:00"
+ },
+ {
+ "name": "paragonie/sodium_compat",
+ "version": "v1.21.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/paragonie/sodium_compat.git",
+ "reference": "bb312875dcdd20680419564fe42ba1d9564b9e37"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/paragonie/sodium_compat/zipball/bb312875dcdd20680419564fe42ba1d9564b9e37",
+ "reference": "bb312875dcdd20680419564fe42ba1d9564b9e37",
+ "shasum": ""
+ },
+ "require": {
+ "paragonie/random_compat": ">=1",
+ "php": "^5.2.4|^5.3|^5.4|^5.5|^5.6|^7|^8"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^3|^4|^5|^6|^7|^8|^9"
+ },
+ "suggest": {
+ "ext-libsodium": "PHP < 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security.",
+ "ext-sodium": "PHP >= 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security."
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "autoload.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "ISC"
+ ],
+ "authors": [
+ {
+ "name": "Paragon Initiative Enterprises",
+ "email": "security@paragonie.com"
+ },
+ {
+ "name": "Frank Denis",
+ "email": "jedisct1@pureftpd.org"
+ }
+ ],
+ "description": "Pure PHP implementation of libsodium; uses the PHP extension if it exists",
+ "keywords": [
+ "Authentication",
+ "BLAKE2b",
+ "ChaCha20",
+ "ChaCha20-Poly1305",
+ "Chapoly",
+ "Curve25519",
+ "Ed25519",
+ "EdDSA",
+ "Edwards-curve Digital Signature Algorithm",
+ "Elliptic Curve Diffie-Hellman",
+ "Poly1305",
+ "Pure-PHP cryptography",
+ "RFC 7748",
+ "RFC 8032",
+ "Salpoly",
+ "Salsa20",
+ "X25519",
+ "XChaCha20-Poly1305",
+ "XSalsa20-Poly1305",
+ "Xchacha20",
+ "Xsalsa20",
+ "aead",
+ "cryptography",
+ "ecdh",
+ "elliptic curve",
+ "elliptic curve cryptography",
+ "encryption",
+ "libsodium",
+ "php",
+ "public-key cryptography",
+ "secret-key cryptography",
+ "side-channel resistant"
+ ],
+ "support": {
+ "issues": "https://github.com/paragonie/sodium_compat/issues",
+ "source": "https://github.com/paragonie/sodium_compat/tree/v1.21.1"
+ },
+ "time": "2024-04-22T22:05:04+00:00"
+ },
{
"name": "phpoption/phpoption",
"version": "1.9.3",
@@ -2393,6 +3703,319 @@
],
"time": "2024-07-20T21:41:07+00:00"
},
+ {
+ "name": "phrity/net-stream",
+ "version": "2.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sirn-se/phrity-net-stream.git",
+ "reference": "4a6704fae3ad2e7c1576f51f1b8425973ba77c63"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sirn-se/phrity-net-stream/zipball/4a6704fae3ad2e7c1576f51f1b8425973ba77c63",
+ "reference": "4a6704fae3ad2e7c1576f51f1b8425973ba77c63",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^8.0",
+ "phrity/util-errorhandler": "^1.1",
+ "psr/http-factory": "^1.0",
+ "psr/http-message": "^1.1 | ^2.0"
+ },
+ "require-dev": {
+ "php-coveralls/php-coveralls": "^2.0",
+ "phpunit/phpunit": "^9.0 | ^10.0 | ^11.0",
+ "phrity/net-uri": "^2.0",
+ "squizlabs/php_codesniffer": "^3.5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Phrity\\Net\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Sören Jensen",
+ "email": "sirn@sirn.se",
+ "homepage": "https://phrity.sirn.se"
+ }
+ ],
+ "description": "Socket stream classes implementing PSR-7 Stream and PSR-17 StreamFactory",
+ "homepage": "https://phrity.sirn.se/net-stream",
+ "keywords": [
+ "Socket",
+ "client",
+ "psr-17",
+ "psr-7",
+ "server",
+ "stream",
+ "stream factory"
+ ],
+ "support": {
+ "issues": "https://github.com/sirn-se/phrity-net-stream/issues",
+ "source": "https://github.com/sirn-se/phrity-net-stream/tree/2.0.1"
+ },
+ "time": "2024-06-30T10:44:58+00:00"
+ },
+ {
+ "name": "phrity/net-uri",
+ "version": "2.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sirn-se/phrity-net-uri.git",
+ "reference": "841190135af4fab18135226aaaf99ec5791377ac"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sirn-se/phrity-net-uri/zipball/841190135af4fab18135226aaaf99ec5791377ac",
+ "reference": "841190135af4fab18135226aaaf99ec5791377ac",
+ "shasum": ""
+ },
+ "require": {
+ "ext-mbstring": "*",
+ "php": "^8.0",
+ "psr/http-factory": "^1.0",
+ "psr/http-message": "^1.1 | ^2.0"
+ },
+ "require-dev": {
+ "php-coveralls/php-coveralls": "^2.0",
+ "phpunit/phpunit": "^9.0 | ^10.0 | ^11.0",
+ "phrity/util-errorhandler": "^1.1",
+ "squizlabs/php_codesniffer": "^3.5"
+ },
+ "suggest": {
+ "ext-intl": "Enables IDN conversion for non-ASCII domains"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Phrity\\Net\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Sören Jensen",
+ "email": "sirn@sirn.se",
+ "homepage": "https://phrity.sirn.se"
+ }
+ ],
+ "description": "PSR-7 Uri and PSR-17 UriFactory implementation",
+ "homepage": "https://phrity.sirn.se/net-uri",
+ "keywords": [
+ "psr-17",
+ "psr-7",
+ "uri",
+ "uri factory"
+ ],
+ "support": {
+ "issues": "https://github.com/sirn-se/phrity-net-uri/issues",
+ "source": "https://github.com/sirn-se/phrity-net-uri/tree/2.1.0"
+ },
+ "time": "2024-07-08T06:14:09+00:00"
+ },
+ {
+ "name": "phrity/util-errorhandler",
+ "version": "1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sirn-se/phrity-util-errorhandler.git",
+ "reference": "4016d9f9615a4c602f525b0542e4835e316a42e4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sirn-se/phrity-util-errorhandler/zipball/4016d9f9615a4c602f525b0542e4835e316a42e4",
+ "reference": "4016d9f9615a4c602f525b0542e4835e316a42e4",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.4 | ^8.0"
+ },
+ "require-dev": {
+ "php-coveralls/php-coveralls": "^2.0",
+ "phpunit/phpunit": "^9.0 | ^10.0 | ^11.0",
+ "squizlabs/php_codesniffer": "^3.5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Phrity\\Util\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Sören Jensen",
+ "email": "sirn@sirn.se",
+ "homepage": "https://phrity.sirn.se"
+ }
+ ],
+ "description": "Inline error handler; catch and resolve errors for code block.",
+ "homepage": "https://phrity.sirn.se/util-errorhandler",
+ "keywords": [
+ "error",
+ "warning"
+ ],
+ "support": {
+ "issues": "https://github.com/sirn-se/phrity-util-errorhandler/issues",
+ "source": "https://github.com/sirn-se/phrity-util-errorhandler/tree/1.1.0"
+ },
+ "time": "2024-03-05T19:32:14+00:00"
+ },
+ {
+ "name": "phrity/websocket",
+ "version": "3.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sirn-se/websocket-php.git",
+ "reference": "36a79edf2a00b93ff1fea3cbac1bd213f98d5ef9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sirn-se/websocket-php/zipball/36a79edf2a00b93ff1fea3cbac1bd213f98d5ef9",
+ "reference": "36a79edf2a00b93ff1fea3cbac1bd213f98d5ef9",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^8.1",
+ "phrity/net-stream": "^2.0",
+ "phrity/net-uri": "^2.1",
+ "phrity/util-errorhandler": "^1.1",
+ "psr/http-message": "^1.1 | ^2.0",
+ "psr/log": "^1.0 | ^2.0 | ^3.0"
+ },
+ "require-dev": {
+ "php-coveralls/php-coveralls": "^2.0",
+ "phpunit/phpunit": "^10.0 | ^11.0",
+ "phrity/net-mock": "^2.0",
+ "squizlabs/php_codesniffer": "^3.5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "WebSocket\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "ISC"
+ ],
+ "authors": [
+ {
+ "name": "Fredrik Liljegren"
+ },
+ {
+ "name": "Sören Jensen",
+ "email": "sirn@sirn.se",
+ "homepage": "https://phrity.sirn.se"
+ }
+ ],
+ "description": "WebSocket client and server",
+ "homepage": "https://phrity.sirn.se/websocket",
+ "keywords": [
+ "client",
+ "server",
+ "websocket"
+ ],
+ "support": {
+ "issues": "https://github.com/sirn-se/websocket-php/issues",
+ "source": "https://github.com/sirn-se/websocket-php/tree/3.1.0"
+ },
+ "time": "2024-07-09T11:00:42+00:00"
+ },
+ {
+ "name": "power-components/livewire-powergrid",
+ "version": "v5.10.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Power-Components/livewire-powergrid.git",
+ "reference": "180ca4a1056def54b19ea626f6f0e483848ccf65"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Power-Components/livewire-powergrid/zipball/180ca4a1056def54b19ea626f6f0e483848ccf65",
+ "reference": "180ca4a1056def54b19ea626f6f0e483848ccf65",
+ "shasum": ""
+ },
+ "require": {
+ "laravel/prompts": "^0.1.15",
+ "livewire/livewire": "^3.4.6",
+ "php": "^8.1"
+ },
+ "conflict": {
+ "laravel/framework": "10.40.0"
+ },
+ "require-dev": {
+ "composer/composer": "^2.7.1",
+ "laradumps/laradumps": "^3.1",
+ "laradumps/laradumps-core": "^2.0",
+ "larastan/larastan": "^2.9.0",
+ "laravel/pint": "^1.14.0",
+ "laravel/scout": "^10.9",
+ "orchestra/testbench": "8.19|^9.0",
+ "pestphp/pest": "^2.34.0"
+ },
+ "suggest": {
+ "openspout/openspout": "Required to export XLS and CSV"
+ },
+ "type": "library",
+ "extra": {
+ "laravel": {
+ "providers": [
+ "PowerComponents\\LivewirePowerGrid\\Providers\\PowerGridServiceProvider"
+ ]
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/functions.php"
+ ],
+ "psr-4": {
+ "PowerComponents\\LivewirePowerGrid\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Luan Freitas",
+ "email": "luanfreitas10@protonmail.com",
+ "role": "Developer"
+ },
+ {
+ "name": "DanSysAnalyst",
+ "email": "daniel@sysanalyst.eu",
+ "role": "Developer"
+ }
+ ],
+ "description": "PowerGrid generates Advanced Datatables using Laravel Livewire.",
+ "homepage": "https://github.com/power-components/livewire-powergrid",
+ "support": {
+ "issues": "https://github.com/Power-Components/livewire-powergrid/issues",
+ "source": "https://github.com/Power-Components/livewire-powergrid/tree/v5.10.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/luanfreitasdev",
+ "type": "github"
+ }
+ ],
+ "time": "2024-08-21T19:41:49+00:00"
+ },
{
"name": "psr/clock",
"version": "1.0.0",
@@ -2884,6 +4507,67 @@
},
"time": "2024-06-10T01:18:23+00:00"
},
+ {
+ "name": "pusher/pusher-php-server",
+ "version": "7.2.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/pusher/pusher-http-php.git",
+ "reference": "de2f72296808f9cafa6a4462b15a768ff130cddb"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/pusher/pusher-http-php/zipball/de2f72296808f9cafa6a4462b15a768ff130cddb",
+ "reference": "de2f72296808f9cafa6a4462b15a768ff130cddb",
+ "shasum": ""
+ },
+ "require": {
+ "ext-curl": "*",
+ "ext-json": "*",
+ "guzzlehttp/guzzle": "^7.2",
+ "paragonie/sodium_compat": "^1.6",
+ "php": "^7.3|^8.0",
+ "psr/log": "^1.0|^2.0|^3.0"
+ },
+ "require-dev": {
+ "overtrue/phplint": "^2.3",
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.0-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Pusher\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Library for interacting with the Pusher REST API",
+ "keywords": [
+ "events",
+ "messaging",
+ "php-pusher-server",
+ "publish",
+ "push",
+ "pusher",
+ "real time",
+ "real-time",
+ "realtime",
+ "rest",
+ "trigger"
+ ],
+ "support": {
+ "issues": "https://github.com/pusher/pusher-http-php/issues",
+ "source": "https://github.com/pusher/pusher-http-php/tree/7.2.4"
+ },
+ "time": "2023-12-15T10:58:53+00:00"
+ },
{
"name": "ralouphie/getallheaders",
"version": "3.0.3",
@@ -3109,6 +4793,1640 @@
],
"time": "2024-04-27T21:32:50+00:00"
},
+ {
+ "name": "ratchet/rfc6455",
+ "version": "v0.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/ratchetphp/RFC6455.git",
+ "reference": "7c964514e93456a52a99a20fcfa0de242a43ccdb"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/ratchetphp/RFC6455/zipball/7c964514e93456a52a99a20fcfa0de242a43ccdb",
+ "reference": "7c964514e93456a52a99a20fcfa0de242a43ccdb",
+ "shasum": ""
+ },
+ "require": {
+ "guzzlehttp/psr7": "^2 || ^1.7",
+ "php": ">=5.4.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.7",
+ "react/socket": "^1.3"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Ratchet\\RFC6455\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Chris Boden",
+ "email": "cboden@gmail.com",
+ "role": "Developer"
+ },
+ {
+ "name": "Matt Bonneau",
+ "role": "Developer"
+ }
+ ],
+ "description": "RFC6455 WebSocket protocol handler",
+ "homepage": "http://socketo.me",
+ "keywords": [
+ "WebSockets",
+ "rfc6455",
+ "websocket"
+ ],
+ "support": {
+ "chat": "https://gitter.im/reactphp/reactphp",
+ "issues": "https://github.com/ratchetphp/RFC6455/issues",
+ "source": "https://github.com/ratchetphp/RFC6455/tree/v0.3.1"
+ },
+ "time": "2021-12-09T23:20:49+00:00"
+ },
+ {
+ "name": "react/cache",
+ "version": "v1.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/reactphp/cache.git",
+ "reference": "d47c472b64aa5608225f47965a484b75c7817d5b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/reactphp/cache/zipball/d47c472b64aa5608225f47965a484b75c7817d5b",
+ "reference": "d47c472b64aa5608225f47965a484b75c7817d5b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0",
+ "react/promise": "^3.0 || ^2.0 || ^1.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "React\\Cache\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Christian Lück",
+ "email": "christian@clue.engineering",
+ "homepage": "https://clue.engineering/"
+ },
+ {
+ "name": "Cees-Jan Kiewiet",
+ "email": "reactphp@ceesjankiewiet.nl",
+ "homepage": "https://wyrihaximus.net/"
+ },
+ {
+ "name": "Jan Sorgalla",
+ "email": "jsorgalla@gmail.com",
+ "homepage": "https://sorgalla.com/"
+ },
+ {
+ "name": "Chris Boden",
+ "email": "cboden@gmail.com",
+ "homepage": "https://cboden.dev/"
+ }
+ ],
+ "description": "Async, Promise-based cache interface for ReactPHP",
+ "keywords": [
+ "cache",
+ "caching",
+ "promise",
+ "reactphp"
+ ],
+ "support": {
+ "issues": "https://github.com/reactphp/cache/issues",
+ "source": "https://github.com/reactphp/cache/tree/v1.2.0"
+ },
+ "funding": [
+ {
+ "url": "https://opencollective.com/reactphp",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2022-11-30T15:59:55+00:00"
+ },
+ {
+ "name": "react/dns",
+ "version": "v1.13.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/reactphp/dns.git",
+ "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/reactphp/dns/zipball/eb8ae001b5a455665c89c1df97f6fb682f8fb0f5",
+ "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0",
+ "react/cache": "^1.0 || ^0.6 || ^0.5",
+ "react/event-loop": "^1.2",
+ "react/promise": "^3.2 || ^2.7 || ^1.2.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36",
+ "react/async": "^4.3 || ^3 || ^2",
+ "react/promise-timer": "^1.11"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "React\\Dns\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Christian Lück",
+ "email": "christian@clue.engineering",
+ "homepage": "https://clue.engineering/"
+ },
+ {
+ "name": "Cees-Jan Kiewiet",
+ "email": "reactphp@ceesjankiewiet.nl",
+ "homepage": "https://wyrihaximus.net/"
+ },
+ {
+ "name": "Jan Sorgalla",
+ "email": "jsorgalla@gmail.com",
+ "homepage": "https://sorgalla.com/"
+ },
+ {
+ "name": "Chris Boden",
+ "email": "cboden@gmail.com",
+ "homepage": "https://cboden.dev/"
+ }
+ ],
+ "description": "Async DNS resolver for ReactPHP",
+ "keywords": [
+ "async",
+ "dns",
+ "dns-resolver",
+ "reactphp"
+ ],
+ "support": {
+ "issues": "https://github.com/reactphp/dns/issues",
+ "source": "https://github.com/reactphp/dns/tree/v1.13.0"
+ },
+ "funding": [
+ {
+ "url": "https://opencollective.com/reactphp",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2024-06-13T14:18:03+00:00"
+ },
+ {
+ "name": "react/event-loop",
+ "version": "v1.5.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/reactphp/event-loop.git",
+ "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/reactphp/event-loop/zipball/bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354",
+ "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36"
+ },
+ "suggest": {
+ "ext-pcntl": "For signal handling support when using the StreamSelectLoop"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "React\\EventLoop\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Christian Lück",
+ "email": "christian@clue.engineering",
+ "homepage": "https://clue.engineering/"
+ },
+ {
+ "name": "Cees-Jan Kiewiet",
+ "email": "reactphp@ceesjankiewiet.nl",
+ "homepage": "https://wyrihaximus.net/"
+ },
+ {
+ "name": "Jan Sorgalla",
+ "email": "jsorgalla@gmail.com",
+ "homepage": "https://sorgalla.com/"
+ },
+ {
+ "name": "Chris Boden",
+ "email": "cboden@gmail.com",
+ "homepage": "https://cboden.dev/"
+ }
+ ],
+ "description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.",
+ "keywords": [
+ "asynchronous",
+ "event-loop"
+ ],
+ "support": {
+ "issues": "https://github.com/reactphp/event-loop/issues",
+ "source": "https://github.com/reactphp/event-loop/tree/v1.5.0"
+ },
+ "funding": [
+ {
+ "url": "https://opencollective.com/reactphp",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2023-11-13T13:48:05+00:00"
+ },
+ {
+ "name": "react/promise",
+ "version": "v3.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/reactphp/promise.git",
+ "reference": "8a164643313c71354582dc850b42b33fa12a4b63"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/reactphp/promise/zipball/8a164643313c71354582dc850b42b33fa12a4b63",
+ "reference": "8a164643313c71354582dc850b42b33fa12a4b63",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1.0"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "1.10.39 || 1.4.10",
+ "phpunit/phpunit": "^9.6 || ^7.5"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "src/functions_include.php"
+ ],
+ "psr-4": {
+ "React\\Promise\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jan Sorgalla",
+ "email": "jsorgalla@gmail.com",
+ "homepage": "https://sorgalla.com/"
+ },
+ {
+ "name": "Christian Lück",
+ "email": "christian@clue.engineering",
+ "homepage": "https://clue.engineering/"
+ },
+ {
+ "name": "Cees-Jan Kiewiet",
+ "email": "reactphp@ceesjankiewiet.nl",
+ "homepage": "https://wyrihaximus.net/"
+ },
+ {
+ "name": "Chris Boden",
+ "email": "cboden@gmail.com",
+ "homepage": "https://cboden.dev/"
+ }
+ ],
+ "description": "A lightweight implementation of CommonJS Promises/A for PHP",
+ "keywords": [
+ "promise",
+ "promises"
+ ],
+ "support": {
+ "issues": "https://github.com/reactphp/promise/issues",
+ "source": "https://github.com/reactphp/promise/tree/v3.2.0"
+ },
+ "funding": [
+ {
+ "url": "https://opencollective.com/reactphp",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2024-05-24T10:39:05+00:00"
+ },
+ {
+ "name": "react/promise-timer",
+ "version": "v1.11.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/reactphp/promise-timer.git",
+ "reference": "4f70306ed66b8b44768941ca7f142092600fafc1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/reactphp/promise-timer/zipball/4f70306ed66b8b44768941ca7f142092600fafc1",
+ "reference": "4f70306ed66b8b44768941ca7f142092600fafc1",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3",
+ "react/event-loop": "^1.2",
+ "react/promise": "^3.2 || ^2.7.0 || ^1.2.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "src/functions_include.php"
+ ],
+ "psr-4": {
+ "React\\Promise\\Timer\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Christian Lück",
+ "email": "christian@clue.engineering",
+ "homepage": "https://clue.engineering/"
+ },
+ {
+ "name": "Cees-Jan Kiewiet",
+ "email": "reactphp@ceesjankiewiet.nl",
+ "homepage": "https://wyrihaximus.net/"
+ },
+ {
+ "name": "Jan Sorgalla",
+ "email": "jsorgalla@gmail.com",
+ "homepage": "https://sorgalla.com/"
+ },
+ {
+ "name": "Chris Boden",
+ "email": "cboden@gmail.com",
+ "homepage": "https://cboden.dev/"
+ }
+ ],
+ "description": "A trivial implementation of timeouts for Promises, built on top of ReactPHP.",
+ "homepage": "https://github.com/reactphp/promise-timer",
+ "keywords": [
+ "async",
+ "event-loop",
+ "promise",
+ "reactphp",
+ "timeout",
+ "timer"
+ ],
+ "support": {
+ "issues": "https://github.com/reactphp/promise-timer/issues",
+ "source": "https://github.com/reactphp/promise-timer/tree/v1.11.0"
+ },
+ "funding": [
+ {
+ "url": "https://opencollective.com/reactphp",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2024-06-04T14:27:45+00:00"
+ },
+ {
+ "name": "react/socket",
+ "version": "v1.16.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/reactphp/socket.git",
+ "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/reactphp/socket/zipball/23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1",
+ "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1",
+ "shasum": ""
+ },
+ "require": {
+ "evenement/evenement": "^3.0 || ^2.0 || ^1.0",
+ "php": ">=5.3.0",
+ "react/dns": "^1.13",
+ "react/event-loop": "^1.2",
+ "react/promise": "^3.2 || ^2.6 || ^1.2.1",
+ "react/stream": "^1.4"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36",
+ "react/async": "^4.3 || ^3.3 || ^2",
+ "react/promise-stream": "^1.4",
+ "react/promise-timer": "^1.11"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "React\\Socket\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Christian Lück",
+ "email": "christian@clue.engineering",
+ "homepage": "https://clue.engineering/"
+ },
+ {
+ "name": "Cees-Jan Kiewiet",
+ "email": "reactphp@ceesjankiewiet.nl",
+ "homepage": "https://wyrihaximus.net/"
+ },
+ {
+ "name": "Jan Sorgalla",
+ "email": "jsorgalla@gmail.com",
+ "homepage": "https://sorgalla.com/"
+ },
+ {
+ "name": "Chris Boden",
+ "email": "cboden@gmail.com",
+ "homepage": "https://cboden.dev/"
+ }
+ ],
+ "description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP",
+ "keywords": [
+ "Connection",
+ "Socket",
+ "async",
+ "reactphp",
+ "stream"
+ ],
+ "support": {
+ "issues": "https://github.com/reactphp/socket/issues",
+ "source": "https://github.com/reactphp/socket/tree/v1.16.0"
+ },
+ "funding": [
+ {
+ "url": "https://opencollective.com/reactphp",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2024-07-26T10:38:09+00:00"
+ },
+ {
+ "name": "react/stream",
+ "version": "v1.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/reactphp/stream.git",
+ "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/reactphp/stream/zipball/1e5b0acb8fe55143b5b426817155190eb6f5b18d",
+ "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d",
+ "shasum": ""
+ },
+ "require": {
+ "evenement/evenement": "^3.0 || ^2.0 || ^1.0",
+ "php": ">=5.3.8",
+ "react/event-loop": "^1.2"
+ },
+ "require-dev": {
+ "clue/stream-filter": "~1.2",
+ "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "React\\Stream\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Christian Lück",
+ "email": "christian@clue.engineering",
+ "homepage": "https://clue.engineering/"
+ },
+ {
+ "name": "Cees-Jan Kiewiet",
+ "email": "reactphp@ceesjankiewiet.nl",
+ "homepage": "https://wyrihaximus.net/"
+ },
+ {
+ "name": "Jan Sorgalla",
+ "email": "jsorgalla@gmail.com",
+ "homepage": "https://sorgalla.com/"
+ },
+ {
+ "name": "Chris Boden",
+ "email": "cboden@gmail.com",
+ "homepage": "https://cboden.dev/"
+ }
+ ],
+ "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP",
+ "keywords": [
+ "event-driven",
+ "io",
+ "non-blocking",
+ "pipe",
+ "reactphp",
+ "readable",
+ "stream",
+ "writable"
+ ],
+ "support": {
+ "issues": "https://github.com/reactphp/stream/issues",
+ "source": "https://github.com/reactphp/stream/tree/v1.4.0"
+ },
+ "funding": [
+ {
+ "url": "https://opencollective.com/reactphp",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2024-06-11T12:45:25+00:00"
+ },
+ {
+ "name": "simplito/bigint-wrapper-php",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/simplito/bigint-wrapper-php.git",
+ "reference": "cf21ec76d33f103add487b3eadbd9f5033a25930"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/simplito/bigint-wrapper-php/zipball/cf21ec76d33f103add487b3eadbd9f5033a25930",
+ "reference": "cf21ec76d33f103add487b3eadbd9f5033a25930",
+ "shasum": ""
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "BI\\": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Simplito Team",
+ "email": "s.smyczynski@simplito.com",
+ "homepage": "https://simplito.com"
+ }
+ ],
+ "description": "Common interface for php_gmp and php_bcmath modules",
+ "support": {
+ "issues": "https://github.com/simplito/bigint-wrapper-php/issues",
+ "source": "https://github.com/simplito/bigint-wrapper-php/tree/1.0.0"
+ },
+ "time": "2018-02-27T12:38:08+00:00"
+ },
+ {
+ "name": "simplito/bn-php",
+ "version": "1.1.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/simplito/bn-php.git",
+ "reference": "83446756a81720eacc2ffb87ff97958431451fd6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/simplito/bn-php/zipball/83446756a81720eacc2ffb87ff97958431451fd6",
+ "reference": "83446756a81720eacc2ffb87ff97958431451fd6",
+ "shasum": ""
+ },
+ "require": {
+ "simplito/bigint-wrapper-php": "~1.0.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "*"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "BN\\": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Simplito Team",
+ "email": "s.smyczynski@simplito.com",
+ "homepage": "https://simplito.com"
+ }
+ ],
+ "description": "Big number implementation compatible with bn.js",
+ "support": {
+ "issues": "https://github.com/simplito/bn-php/issues",
+ "source": "https://github.com/simplito/bn-php/tree/1.1.4"
+ },
+ "time": "2024-01-10T16:16:59+00:00"
+ },
+ {
+ "name": "simplito/elliptic-php",
+ "version": "1.0.12",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/simplito/elliptic-php.git",
+ "reference": "be321666781be2be2c89c79c43ffcac834bc8868"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/simplito/elliptic-php/zipball/be321666781be2be2c89c79c43ffcac834bc8868",
+ "reference": "be321666781be2be2c89c79c43ffcac834bc8868",
+ "shasum": ""
+ },
+ "require": {
+ "ext-gmp": "*",
+ "simplito/bn-php": "~1.1.0"
+ },
+ "require-dev": {
+ "phpbench/phpbench": "@dev",
+ "phpunit/phpunit": "*"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Elliptic\\": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Simplito Team",
+ "email": "s.smyczynski@simplito.com",
+ "homepage": "https://simplito.com"
+ }
+ ],
+ "description": "Fast elliptic curve cryptography",
+ "homepage": "https://github.com/simplito/elliptic-php",
+ "keywords": [
+ "Curve25519",
+ "ECDSA",
+ "Ed25519",
+ "EdDSA",
+ "cryptography",
+ "curve",
+ "curve25519-weier",
+ "ecc",
+ "ecdh",
+ "elliptic",
+ "nistp192",
+ "nistp224",
+ "nistp256",
+ "nistp384",
+ "nistp521",
+ "secp256k1"
+ ],
+ "support": {
+ "issues": "https://github.com/simplito/elliptic-php/issues",
+ "source": "https://github.com/simplito/elliptic-php/tree/1.0.12"
+ },
+ "time": "2024-01-09T14:57:04+00:00"
+ },
+ {
+ "name": "spatie/eloquent-sortable",
+ "version": "4.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/spatie/eloquent-sortable.git",
+ "reference": "7a460c775d29741f42744bac52f993cb5b84be0f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/spatie/eloquent-sortable/zipball/7a460c775d29741f42744bac52f993cb5b84be0f",
+ "reference": "7a460c775d29741f42744bac52f993cb5b84be0f",
+ "shasum": ""
+ },
+ "require": {
+ "illuminate/database": "^9.31|^10.0|^11.0",
+ "illuminate/support": "^9.31|^10.0|^11.0",
+ "nesbot/carbon": "^2.63|^3.0",
+ "php": "^8.1",
+ "spatie/laravel-package-tools": "^1.9"
+ },
+ "require-dev": {
+ "orchestra/testbench": "^7.0|^8.0|^9.0",
+ "phpunit/phpunit": "^9.5|^10.0"
+ },
+ "type": "library",
+ "extra": {
+ "laravel": {
+ "providers": [
+ "Spatie\\EloquentSortable\\EloquentSortableServiceProvider"
+ ]
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Spatie\\EloquentSortable\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Freek Van der Herten",
+ "email": "freek@spatie.be"
+ }
+ ],
+ "description": "Sortable behaviour for eloquent models",
+ "homepage": "https://github.com/spatie/eloquent-sortable",
+ "keywords": [
+ "behaviour",
+ "eloquent",
+ "laravel",
+ "model",
+ "sort",
+ "sortable"
+ ],
+ "support": {
+ "issues": "https://github.com/spatie/eloquent-sortable/issues",
+ "source": "https://github.com/spatie/eloquent-sortable/tree/4.4.0"
+ },
+ "funding": [
+ {
+ "url": "https://spatie.be/open-source/support-us",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/spatie",
+ "type": "github"
+ }
+ ],
+ "time": "2024-06-04T11:09:54+00:00"
+ },
+ {
+ "name": "spatie/image",
+ "version": "3.7.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/spatie/image.git",
+ "reference": "62897055045fa74efc6d1bf201c783841a679e99"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/spatie/image/zipball/62897055045fa74efc6d1bf201c783841a679e99",
+ "reference": "62897055045fa74efc6d1bf201c783841a679e99",
+ "shasum": ""
+ },
+ "require": {
+ "ext-exif": "*",
+ "ext-json": "*",
+ "ext-mbstring": "*",
+ "php": "^8.2",
+ "spatie/image-optimizer": "^1.7.5",
+ "spatie/temporary-directory": "^2.2",
+ "symfony/process": "^6.4|^7.0"
+ },
+ "require-dev": {
+ "ext-gd": "*",
+ "ext-imagick": "*",
+ "pestphp/pest": "^2.28",
+ "phpstan/phpstan": "^1.10.50",
+ "spatie/pest-plugin-snapshots": "^2.1",
+ "spatie/pixelmatch-php": "^1.0",
+ "spatie/ray": "^1.40.1",
+ "symfony/var-dumper": "^6.4|7.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Spatie\\Image\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Freek Van der Herten",
+ "email": "freek@spatie.be",
+ "homepage": "https://spatie.be",
+ "role": "Developer"
+ }
+ ],
+ "description": "Manipulate images with an expressive API",
+ "homepage": "https://github.com/spatie/image",
+ "keywords": [
+ "image",
+ "spatie"
+ ],
+ "support": {
+ "source": "https://github.com/spatie/image/tree/3.7.3"
+ },
+ "funding": [
+ {
+ "url": "https://spatie.be/open-source/support-us",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/spatie",
+ "type": "github"
+ }
+ ],
+ "time": "2024-08-06T12:32:33+00:00"
+ },
+ {
+ "name": "spatie/image-optimizer",
+ "version": "1.7.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/spatie/image-optimizer.git",
+ "reference": "43aff6725cd87bb78ccd8532633cfa8bdc962505"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/spatie/image-optimizer/zipball/43aff6725cd87bb78ccd8532633cfa8bdc962505",
+ "reference": "43aff6725cd87bb78ccd8532633cfa8bdc962505",
+ "shasum": ""
+ },
+ "require": {
+ "ext-fileinfo": "*",
+ "php": "^7.3|^8.0",
+ "psr/log": "^1.0 | ^2.0 | ^3.0",
+ "symfony/process": "^4.2|^5.0|^6.0|^7.0"
+ },
+ "require-dev": {
+ "pestphp/pest": "^1.21",
+ "phpunit/phpunit": "^8.5.21|^9.4.4",
+ "symfony/var-dumper": "^4.2|^5.0|^6.0|^7.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Spatie\\ImageOptimizer\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Freek Van der Herten",
+ "email": "freek@spatie.be",
+ "homepage": "https://spatie.be",
+ "role": "Developer"
+ }
+ ],
+ "description": "Easily optimize images using PHP",
+ "homepage": "https://github.com/spatie/image-optimizer",
+ "keywords": [
+ "image-optimizer",
+ "spatie"
+ ],
+ "support": {
+ "issues": "https://github.com/spatie/image-optimizer/issues",
+ "source": "https://github.com/spatie/image-optimizer/tree/1.7.5"
+ },
+ "time": "2024-05-16T08:48:33+00:00"
+ },
+ {
+ "name": "spatie/laravel-google-fonts",
+ "version": "1.4.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/spatie/laravel-google-fonts.git",
+ "reference": "2ddd1c05ad56434c44b529c14403b5f5262b38d0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/spatie/laravel-google-fonts/zipball/2ddd1c05ad56434c44b529c14403b5f5262b38d0",
+ "reference": "2ddd1c05ad56434c44b529c14403b5f5262b38d0",
+ "shasum": ""
+ },
+ "require": {
+ "guzzlehttp/guzzle": "^7.3|^7.2",
+ "illuminate/contracts": "^8.37|^9.0|^10.0|^11.0",
+ "php": "^8.0",
+ "spatie/laravel-package-tools": "^1.7.0"
+ },
+ "require-dev": {
+ "brianium/paratest": "^6.3|^7.4",
+ "nunomaduro/collision": "^5.4|^6.0|^8.0",
+ "orchestra/testbench": "^6.17|^7.0|^8.0|^9.0",
+ "pestphp/pest": "^1.22|^2.34",
+ "spatie/laravel-ray": "^1.17",
+ "spatie/pest-plugin-snapshots": "^1.1|^2.1",
+ "spatie/phpunit-snapshot-assertions": "^4.2|^5.1"
+ },
+ "type": "library",
+ "extra": {
+ "laravel": {
+ "providers": [
+ "Spatie\\GoogleFonts\\GoogleFontsServiceProvider"
+ ],
+ "aliases": {
+ "GoogleFonts": "Spatie\\GoogleFonts\\GoogleFontsFacade"
+ }
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Spatie\\GoogleFonts\\": "src",
+ "Spatie\\GoogleFonts\\Database\\Factories\\": "database/factories"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian De Deyne",
+ "email": "sebastian@spatie.be",
+ "role": "Developer"
+ },
+ {
+ "name": "Freek Van der herten",
+ "email": "freek@spatie.be",
+ "role": "Developer"
+ }
+ ],
+ "description": "Manage self-hosted Google Fonts in Laravel apps",
+ "homepage": "https://github.com/spatie/laravel-google-fonts",
+ "keywords": [
+ "google fonts",
+ "laravel",
+ "laravel-google-fonts",
+ "spatie"
+ ],
+ "support": {
+ "issues": "https://github.com/spatie/laravel-google-fonts/issues",
+ "source": "https://github.com/spatie/laravel-google-fonts/tree/1.4.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/spatie",
+ "type": "github"
+ }
+ ],
+ "time": "2024-03-14T09:50:35+00:00"
+ },
+ {
+ "name": "spatie/laravel-medialibrary",
+ "version": "11.9.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/spatie/laravel-medialibrary.git",
+ "reference": "ff589ea5532a33d84faeb64bfdfd59057b4148b8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/spatie/laravel-medialibrary/zipball/ff589ea5532a33d84faeb64bfdfd59057b4148b8",
+ "reference": "ff589ea5532a33d84faeb64bfdfd59057b4148b8",
+ "shasum": ""
+ },
+ "require": {
+ "composer/semver": "^3.4",
+ "ext-exif": "*",
+ "ext-fileinfo": "*",
+ "ext-json": "*",
+ "illuminate/bus": "^10.0|^11.0",
+ "illuminate/conditionable": "^10.0|^11.0",
+ "illuminate/console": "^10.0|^11.0",
+ "illuminate/database": "^10.0|^11.0",
+ "illuminate/pipeline": "^10.0|^11.0",
+ "illuminate/support": "^10.0|^11.0",
+ "maennchen/zipstream-php": "^3.1",
+ "php": "^8.2",
+ "spatie/image": "^3.3.2",
+ "spatie/laravel-package-tools": "^1.16.1",
+ "spatie/temporary-directory": "^2.2",
+ "symfony/console": "^6.4.1|^7.0"
+ },
+ "conflict": {
+ "php-ffmpeg/php-ffmpeg": "<0.6.1"
+ },
+ "require-dev": {
+ "aws/aws-sdk-php": "^3.293.10",
+ "ext-imagick": "*",
+ "ext-pdo_sqlite": "*",
+ "ext-zip": "*",
+ "guzzlehttp/guzzle": "^7.8.1",
+ "larastan/larastan": "^2.7",
+ "league/flysystem-aws-s3-v3": "^3.22",
+ "mockery/mockery": "^1.6.7",
+ "orchestra/testbench": "^7.0|^8.17|^9.0",
+ "pestphp/pest": "^2.28",
+ "phpstan/extension-installer": "^1.3.1",
+ "spatie/laravel-ray": "^1.33",
+ "spatie/pdf-to-image": "^2.2|^3.0",
+ "spatie/pest-plugin-snapshots": "^2.1"
+ },
+ "suggest": {
+ "league/flysystem-aws-s3-v3": "Required to use AWS S3 file storage",
+ "php-ffmpeg/php-ffmpeg": "Required for generating video thumbnails",
+ "spatie/pdf-to-image": "Required for generating thumbnails of PDFs and SVGs"
+ },
+ "type": "library",
+ "extra": {
+ "laravel": {
+ "providers": [
+ "Spatie\\MediaLibrary\\MediaLibraryServiceProvider"
+ ]
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Spatie\\MediaLibrary\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Freek Van der Herten",
+ "email": "freek@spatie.be",
+ "homepage": "https://spatie.be",
+ "role": "Developer"
+ }
+ ],
+ "description": "Associate files with Eloquent models",
+ "homepage": "https://github.com/spatie/laravel-medialibrary",
+ "keywords": [
+ "cms",
+ "conversion",
+ "downloads",
+ "images",
+ "laravel",
+ "laravel-medialibrary",
+ "media",
+ "spatie"
+ ],
+ "support": {
+ "issues": "https://github.com/spatie/laravel-medialibrary/issues",
+ "source": "https://github.com/spatie/laravel-medialibrary/tree/11.9.1"
+ },
+ "funding": [
+ {
+ "url": "https://spatie.be/open-source/support-us",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/spatie",
+ "type": "github"
+ }
+ ],
+ "time": "2024-09-02T06:32:15+00:00"
+ },
+ {
+ "name": "spatie/laravel-package-tools",
+ "version": "1.16.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/spatie/laravel-package-tools.git",
+ "reference": "c7413972cf22ffdff97b68499c22baa04eddb6a2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/c7413972cf22ffdff97b68499c22baa04eddb6a2",
+ "reference": "c7413972cf22ffdff97b68499c22baa04eddb6a2",
+ "shasum": ""
+ },
+ "require": {
+ "illuminate/contracts": "^9.28|^10.0|^11.0",
+ "php": "^8.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "^1.5",
+ "orchestra/testbench": "^7.7|^8.0",
+ "pestphp/pest": "^1.22",
+ "phpunit/phpunit": "^9.5.24",
+ "spatie/pest-plugin-test-time": "^1.1"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Spatie\\LaravelPackageTools\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Freek Van der Herten",
+ "email": "freek@spatie.be",
+ "role": "Developer"
+ }
+ ],
+ "description": "Tools for creating Laravel packages",
+ "homepage": "https://github.com/spatie/laravel-package-tools",
+ "keywords": [
+ "laravel-package-tools",
+ "spatie"
+ ],
+ "support": {
+ "issues": "https://github.com/spatie/laravel-package-tools/issues",
+ "source": "https://github.com/spatie/laravel-package-tools/tree/1.16.5"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/spatie",
+ "type": "github"
+ }
+ ],
+ "time": "2024-08-27T18:56:10+00:00"
+ },
+ {
+ "name": "spatie/laravel-sluggable",
+ "version": "3.6.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/spatie/laravel-sluggable.git",
+ "reference": "a44afe6f317959bcfdadcec3148486859fd5c1f5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/spatie/laravel-sluggable/zipball/a44afe6f317959bcfdadcec3148486859fd5c1f5",
+ "reference": "a44afe6f317959bcfdadcec3148486859fd5c1f5",
+ "shasum": ""
+ },
+ "require": {
+ "illuminate/database": "^8.0|^9.0|^10.0|^11.0",
+ "illuminate/support": "^8.0|^9.0|^10.0|^11.0",
+ "php": "^8.0"
+ },
+ "require-dev": {
+ "orchestra/testbench": "^6.23|^7.0|^8.0|^9.0",
+ "pestphp/pest": "^1.20|^2.0",
+ "spatie/laravel-translatable": "^5.0|^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Spatie\\Sluggable\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Freek Van der Herten",
+ "email": "freek@spatie.be",
+ "homepage": "https://spatie.be",
+ "role": "Developer"
+ }
+ ],
+ "description": "Generate slugs when saving Eloquent models",
+ "homepage": "https://github.com/spatie/laravel-sluggable",
+ "keywords": [
+ "laravel-sluggable",
+ "spatie"
+ ],
+ "support": {
+ "source": "https://github.com/spatie/laravel-sluggable/tree/3.6.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/spatie",
+ "type": "github"
+ }
+ ],
+ "time": "2024-02-26T08:33:29+00:00"
+ },
+ {
+ "name": "spatie/laravel-tags",
+ "version": "4.6.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/spatie/laravel-tags.git",
+ "reference": "73944e8bd7a341269c03959fe063d8714adbe5a6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/spatie/laravel-tags/zipball/73944e8bd7a341269c03959fe063d8714adbe5a6",
+ "reference": "73944e8bd7a341269c03959fe063d8714adbe5a6",
+ "shasum": ""
+ },
+ "require": {
+ "laravel/framework": "^8.67|^9.0|^10.0|^11.0",
+ "nesbot/carbon": "^2.63|^3.0",
+ "php": "^8.0",
+ "spatie/eloquent-sortable": "^3.10|^4.0",
+ "spatie/laravel-package-tools": "^1.4",
+ "spatie/laravel-translatable": "^4.6|^5.0|^6.0"
+ },
+ "require-dev": {
+ "orchestra/testbench": "^6.13|^7.0|^8.0|^9.0",
+ "pestphp/pest": "^1.22|^2.0",
+ "phpunit/phpunit": "^9.5.2"
+ },
+ "type": "library",
+ "extra": {
+ "laravel": {
+ "providers": [
+ "Spatie\\Tags\\TagsServiceProvider"
+ ]
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Spatie\\Tags\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Freek Van der Herten",
+ "email": "freek@spatie.be",
+ "homepage": "https://spatie.be",
+ "role": "Developer"
+ }
+ ],
+ "description": "Add tags and taggable behaviour to your Laravel app",
+ "homepage": "https://github.com/spatie/laravel-tags",
+ "keywords": [
+ "laravel-tags",
+ "spatie"
+ ],
+ "support": {
+ "issues": "https://github.com/spatie/laravel-tags/issues",
+ "source": "https://github.com/spatie/laravel-tags/tree/4.6.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/spatie",
+ "type": "github"
+ }
+ ],
+ "time": "2024-03-01T12:44:53+00:00"
+ },
+ {
+ "name": "spatie/laravel-translatable",
+ "version": "6.8.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/spatie/laravel-translatable.git",
+ "reference": "0ef7e8e9d65bb834b7c68f22ec362a6179f50381"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/spatie/laravel-translatable/zipball/0ef7e8e9d65bb834b7c68f22ec362a6179f50381",
+ "reference": "0ef7e8e9d65bb834b7c68f22ec362a6179f50381",
+ "shasum": ""
+ },
+ "require": {
+ "illuminate/database": "^9.0|^10.0|^11.0",
+ "illuminate/support": "^9.0|^10.0|^11.0",
+ "php": "^8.0",
+ "spatie/laravel-package-tools": "^1.11"
+ },
+ "require-dev": {
+ "mockery/mockery": "^1.4",
+ "orchestra/testbench": "^7.0|^8.0|^9.0",
+ "pestphp/pest": "^1.20|^2.0"
+ },
+ "type": "library",
+ "extra": {
+ "laravel": {
+ "providers": [
+ "Spatie\\Translatable\\TranslatableServiceProvider"
+ ]
+ },
+ "aliases": {
+ "Translatable": "Spatie\\Translatable\\Facades\\Translatable"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Spatie\\Translatable\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Freek Van der Herten",
+ "email": "freek@spatie.be",
+ "homepage": "https://spatie.be",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian De Deyne",
+ "email": "sebastian@spatie.be",
+ "homepage": "https://spatie.be",
+ "role": "Developer"
+ }
+ ],
+ "description": "A trait to make an Eloquent model hold translations",
+ "homepage": "https://github.com/spatie/laravel-translatable",
+ "keywords": [
+ "eloquent",
+ "i8n",
+ "laravel-translatable",
+ "model",
+ "multilingual",
+ "spatie",
+ "translate"
+ ],
+ "support": {
+ "issues": "https://github.com/spatie/laravel-translatable/issues",
+ "source": "https://github.com/spatie/laravel-translatable/tree/6.8.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/spatie",
+ "type": "github"
+ }
+ ],
+ "time": "2024-07-24T14:26:27+00:00"
+ },
+ {
+ "name": "spatie/temporary-directory",
+ "version": "2.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/spatie/temporary-directory.git",
+ "reference": "76949fa18f8e1a7f663fd2eaa1d00e0bcea0752a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/spatie/temporary-directory/zipball/76949fa18f8e1a7f663fd2eaa1d00e0bcea0752a",
+ "reference": "76949fa18f8e1a7f663fd2eaa1d00e0bcea0752a",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Spatie\\TemporaryDirectory\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Alex Vanderbist",
+ "email": "alex@spatie.be",
+ "homepage": "https://spatie.be",
+ "role": "Developer"
+ }
+ ],
+ "description": "Easily create, use and destroy temporary directories",
+ "homepage": "https://github.com/spatie/temporary-directory",
+ "keywords": [
+ "php",
+ "spatie",
+ "temporary-directory"
+ ],
+ "support": {
+ "issues": "https://github.com/spatie/temporary-directory/issues",
+ "source": "https://github.com/spatie/temporary-directory/tree/2.2.1"
+ },
+ "funding": [
+ {
+ "url": "https://spatie.be/open-source/support-us",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/spatie",
+ "type": "github"
+ }
+ ],
+ "time": "2023-12-25T11:46:58+00:00"
+ },
+ {
+ "name": "staudenmeir/eloquent-has-many-deep",
+ "version": "v1.20.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/staudenmeir/eloquent-has-many-deep.git",
+ "reference": "edcce8d8559d9559c997c177de06eb4bc173956d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/staudenmeir/eloquent-has-many-deep/zipball/edcce8d8559d9559c997c177de06eb4bc173956d",
+ "reference": "edcce8d8559d9559c997c177de06eb4bc173956d",
+ "shasum": ""
+ },
+ "require": {
+ "illuminate/database": "^11.0",
+ "php": "^8.2",
+ "staudenmeir/eloquent-has-many-deep-contracts": "^1.2"
+ },
+ "require-dev": {
+ "awobaz/compoships": "^2.3",
+ "barryvdh/laravel-ide-helper": "^3.0",
+ "illuminate/pagination": "^11.0",
+ "korridor/laravel-has-many-merged": "^1.1",
+ "mockery/mockery": "^1.6",
+ "orchestra/testbench": "^9.0",
+ "phpstan/phpstan": "^1.10",
+ "phpunit/phpunit": "^11.0",
+ "staudenmeir/eloquent-json-relations": "^1.11",
+ "staudenmeir/laravel-adjacency-list": "^1.21"
+ },
+ "type": "library",
+ "extra": {
+ "laravel": {
+ "providers": [
+ "Staudenmeir\\EloquentHasManyDeep\\IdeHelperServiceProvider"
+ ]
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Staudenmeir\\EloquentHasManyDeep\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jonas Staudenmeir",
+ "email": "mail@jonas-staudenmeir.de"
+ }
+ ],
+ "description": "Laravel Eloquent HasManyThrough relationships with unlimited levels",
+ "support": {
+ "issues": "https://github.com/staudenmeir/eloquent-has-many-deep/issues",
+ "source": "https://github.com/staudenmeir/eloquent-has-many-deep/tree/v1.20.2"
+ },
+ "funding": [
+ {
+ "url": "https://paypal.me/JonasStaudenmeir",
+ "type": "custom"
+ }
+ ],
+ "time": "2024-07-12T22:08:11+00:00"
+ },
+ {
+ "name": "staudenmeir/eloquent-has-many-deep-contracts",
+ "version": "v1.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/staudenmeir/eloquent-has-many-deep-contracts.git",
+ "reference": "bcbe1a921caad7201b324e297eddb696d4bd8647"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/staudenmeir/eloquent-has-many-deep-contracts/zipball/bcbe1a921caad7201b324e297eddb696d4bd8647",
+ "reference": "bcbe1a921caad7201b324e297eddb696d4bd8647",
+ "shasum": ""
+ },
+ "require": {
+ "illuminate/database": "^11.0",
+ "php": "^8.2"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Staudenmeir\\EloquentHasManyDeepContracts\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jonas Staudenmeir",
+ "email": "mail@jonas-staudenmeir.de"
+ }
+ ],
+ "description": "Contracts for staudenmeir/eloquent-has-many-deep",
+ "support": {
+ "issues": "https://github.com/staudenmeir/eloquent-has-many-deep-contracts/issues",
+ "source": "https://github.com/staudenmeir/eloquent-has-many-deep-contracts/tree/v1.2"
+ },
+ "time": "2024-01-18T01:20:44+00:00"
+ },
+ {
+ "name": "swentel/nostr-php",
+ "version": "1.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nostrver-se/nostr-php.git",
+ "reference": "ebdd3ce598eb62446f114f796c6f7bfad075594e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nostrver-se/nostr-php/zipball/ebdd3ce598eb62446f114f796c6f7bfad075594e",
+ "reference": "ebdd3ce598eb62446f114f796c6f7bfad075594e",
+ "shasum": ""
+ },
+ "require": {
+ "bitwasp/bech32": "^0.0.1",
+ "ext-gmp": "*",
+ "ext-xml": "*",
+ "php": ">=8.1 <8.4",
+ "phrity/websocket": "^3.0",
+ "simplito/elliptic-php": "^1.0",
+ "uma/phpecc": "^0.1.3"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "^3.51",
+ "phpunit/phpunit": "^10.5"
+ },
+ "bin": [
+ "bin/nostr-php"
+ ],
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "swentel\\nostr\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Hagens",
+ "email": "info@sebastix.nl",
+ "homepage": "https://sebastix.nl",
+ "role": "Developer & maintainer"
+ },
+ {
+ "name": "Kristof De Jaeger",
+ "homepage": "https://realize.be",
+ "role": "Original author"
+ }
+ ],
+ "description": "Nostr helper library for PHP",
+ "homepage": "https://nostr-php.dev",
+ "keywords": [
+ "dev",
+ "library",
+ "nostr"
+ ],
+ "support": {
+ "chat": "https://t.me/nostr_php",
+ "issue": "https://github.com/swentel/nostr-php/issues",
+ "issues": "https://github.com/nostrver-se/nostr-php/issues",
+ "source": "https://github.com/nostrver-se/nostr-php/tree/1.4.0"
+ },
+ "time": "2024-08-29T09:29:56+00:00"
+ },
{
"name": "symfony/clock",
"version": "v7.1.1",
@@ -3185,16 +6503,16 @@
},
{
"name": "symfony/console",
- "version": "v7.1.3",
+ "version": "v7.1.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9"
+ "reference": "1eed7af6961d763e7832e874d7f9b21c3ea9c111"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9",
- "reference": "cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9",
+ "url": "https://api.github.com/repos/symfony/console/zipball/1eed7af6961d763e7832e874d7f9b21c3ea9c111",
+ "reference": "1eed7af6961d763e7832e874d7f9b21c3ea9c111",
"shasum": ""
},
"require": {
@@ -3258,7 +6576,7 @@
"terminal"
],
"support": {
- "source": "https://github.com/symfony/console/tree/v7.1.3"
+ "source": "https://github.com/symfony/console/tree/v7.1.4"
},
"funding": [
{
@@ -3274,7 +6592,7 @@
"type": "tidelift"
}
],
- "time": "2024-07-26T12:41:01+00:00"
+ "time": "2024-08-15T22:48:53+00:00"
},
{
"name": "symfony/css-selector",
@@ -3641,16 +6959,16 @@
},
{
"name": "symfony/finder",
- "version": "v7.1.3",
+ "version": "v7.1.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
- "reference": "717c6329886f32dc65e27461f80f2a465412fdca"
+ "reference": "d95bbf319f7d052082fb7af147e0f835a695e823"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/finder/zipball/717c6329886f32dc65e27461f80f2a465412fdca",
- "reference": "717c6329886f32dc65e27461f80f2a465412fdca",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/d95bbf319f7d052082fb7af147e0f835a695e823",
+ "reference": "d95bbf319f7d052082fb7af147e0f835a695e823",
"shasum": ""
},
"require": {
@@ -3685,7 +7003,7 @@
"description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/finder/tree/v7.1.3"
+ "source": "https://github.com/symfony/finder/tree/v7.1.4"
},
"funding": [
{
@@ -3701,7 +7019,7 @@
"type": "tidelift"
}
],
- "time": "2024-07-24T07:08:44+00:00"
+ "time": "2024-08-13T14:28:19+00:00"
},
{
"name": "symfony/http-foundation",
@@ -3782,16 +7100,16 @@
},
{
"name": "symfony/http-kernel",
- "version": "v7.1.3",
+ "version": "v7.1.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
- "reference": "db9702f3a04cc471ec8c70e881825db26ac5f186"
+ "reference": "6efcbd1b3f444f631c386504fc83eeca25963747"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-kernel/zipball/db9702f3a04cc471ec8c70e881825db26ac5f186",
- "reference": "db9702f3a04cc471ec8c70e881825db26ac5f186",
+ "url": "https://api.github.com/repos/symfony/http-kernel/zipball/6efcbd1b3f444f631c386504fc83eeca25963747",
+ "reference": "6efcbd1b3f444f631c386504fc83eeca25963747",
"shasum": ""
},
"require": {
@@ -3876,7 +7194,7 @@
"description": "Provides a structured process for converting a Request into a Response",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/http-kernel/tree/v7.1.3"
+ "source": "https://github.com/symfony/http-kernel/tree/v7.1.4"
},
"funding": [
{
@@ -3892,7 +7210,7 @@
"type": "tidelift"
}
],
- "time": "2024-07-26T14:58:15+00:00"
+ "time": "2024-08-30T17:02:28+00:00"
},
{
"name": "symfony/mailer",
@@ -3976,16 +7294,16 @@
},
{
"name": "symfony/mime",
- "version": "v7.1.2",
+ "version": "v7.1.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/mime.git",
- "reference": "26a00b85477e69a4bab63b66c5dce64f18b0cbfc"
+ "reference": "ccaa6c2503db867f472a587291e764d6a1e58758"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/mime/zipball/26a00b85477e69a4bab63b66c5dce64f18b0cbfc",
- "reference": "26a00b85477e69a4bab63b66c5dce64f18b0cbfc",
+ "url": "https://api.github.com/repos/symfony/mime/zipball/ccaa6c2503db867f472a587291e764d6a1e58758",
+ "reference": "ccaa6c2503db867f472a587291e764d6a1e58758",
"shasum": ""
},
"require": {
@@ -4040,7 +7358,7 @@
"mime-type"
],
"support": {
- "source": "https://github.com/symfony/mime/tree/v7.1.2"
+ "source": "https://github.com/symfony/mime/tree/v7.1.4"
},
"funding": [
{
@@ -4056,7 +7374,7 @@
"type": "tidelift"
}
],
- "time": "2024-06-28T10:03:55+00:00"
+ "time": "2024-08-13T14:28:19+00:00"
},
{
"name": "symfony/polyfill-ctype",
@@ -4831,16 +8149,16 @@
},
{
"name": "symfony/routing",
- "version": "v7.1.3",
+ "version": "v7.1.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/routing.git",
- "reference": "8a908a3f22d5a1b5d297578c2ceb41b02fa916d0"
+ "reference": "1500aee0094a3ce1c92626ed8cf3c2037e86f5a7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/routing/zipball/8a908a3f22d5a1b5d297578c2ceb41b02fa916d0",
- "reference": "8a908a3f22d5a1b5d297578c2ceb41b02fa916d0",
+ "url": "https://api.github.com/repos/symfony/routing/zipball/1500aee0094a3ce1c92626ed8cf3c2037e86f5a7",
+ "reference": "1500aee0094a3ce1c92626ed8cf3c2037e86f5a7",
"shasum": ""
},
"require": {
@@ -4892,7 +8210,7 @@
"url"
],
"support": {
- "source": "https://github.com/symfony/routing/tree/v7.1.3"
+ "source": "https://github.com/symfony/routing/tree/v7.1.4"
},
"funding": [
{
@@ -4908,7 +8226,7 @@
"type": "tidelift"
}
],
- "time": "2024-07-17T06:10:24+00:00"
+ "time": "2024-08-29T08:16:25+00:00"
},
{
"name": "symfony/service-contracts",
@@ -4995,16 +8313,16 @@
},
{
"name": "symfony/string",
- "version": "v7.1.3",
+ "version": "v7.1.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
- "reference": "ea272a882be7f20cad58d5d78c215001617b7f07"
+ "reference": "6cd670a6d968eaeb1c77c2e76091c45c56bc367b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/string/zipball/ea272a882be7f20cad58d5d78c215001617b7f07",
- "reference": "ea272a882be7f20cad58d5d78c215001617b7f07",
+ "url": "https://api.github.com/repos/symfony/string/zipball/6cd670a6d968eaeb1c77c2e76091c45c56bc367b",
+ "reference": "6cd670a6d968eaeb1c77c2e76091c45c56bc367b",
"shasum": ""
},
"require": {
@@ -5062,7 +8380,7 @@
"utf8"
],
"support": {
- "source": "https://github.com/symfony/string/tree/v7.1.3"
+ "source": "https://github.com/symfony/string/tree/v7.1.4"
},
"funding": [
{
@@ -5078,7 +8396,7 @@
"type": "tidelift"
}
],
- "time": "2024-07-22T10:25:37+00:00"
+ "time": "2024-08-12T09:59:40+00:00"
},
{
"name": "symfony/translation",
@@ -5254,16 +8572,16 @@
},
{
"name": "symfony/uid",
- "version": "v7.1.1",
+ "version": "v7.1.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/uid.git",
- "reference": "bb59febeecc81528ff672fad5dab7f06db8c8277"
+ "reference": "82177535395109075cdb45a70533aa3d7a521cdf"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/uid/zipball/bb59febeecc81528ff672fad5dab7f06db8c8277",
- "reference": "bb59febeecc81528ff672fad5dab7f06db8c8277",
+ "url": "https://api.github.com/repos/symfony/uid/zipball/82177535395109075cdb45a70533aa3d7a521cdf",
+ "reference": "82177535395109075cdb45a70533aa3d7a521cdf",
"shasum": ""
},
"require": {
@@ -5308,7 +8626,7 @@
"uuid"
],
"support": {
- "source": "https://github.com/symfony/uid/tree/v7.1.1"
+ "source": "https://github.com/symfony/uid/tree/v7.1.4"
},
"funding": [
{
@@ -5324,20 +8642,20 @@
"type": "tidelift"
}
],
- "time": "2024-05-31T14:57:53+00:00"
+ "time": "2024-08-12T09:59:40+00:00"
},
{
"name": "symfony/var-dumper",
- "version": "v7.1.3",
+ "version": "v7.1.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
- "reference": "86af4617cca75a6e28598f49ae0690f3b9d4591f"
+ "reference": "a5fa7481b199090964d6fd5dab6294d5a870c7aa"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/var-dumper/zipball/86af4617cca75a6e28598f49ae0690f3b9d4591f",
- "reference": "86af4617cca75a6e28598f49ae0690f3b9d4591f",
+ "url": "https://api.github.com/repos/symfony/var-dumper/zipball/a5fa7481b199090964d6fd5dab6294d5a870c7aa",
+ "reference": "a5fa7481b199090964d6fd5dab6294d5a870c7aa",
"shasum": ""
},
"require": {
@@ -5391,7 +8709,7 @@
"dump"
],
"support": {
- "source": "https://github.com/symfony/var-dumper/tree/v7.1.3"
+ "source": "https://github.com/symfony/var-dumper/tree/v7.1.4"
},
"funding": [
{
@@ -5407,7 +8725,78 @@
"type": "tidelift"
}
],
- "time": "2024-07-26T12:41:01+00:00"
+ "time": "2024-08-30T16:12:47+00:00"
+ },
+ {
+ "name": "symfony/yaml",
+ "version": "v7.1.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/yaml.git",
+ "reference": "92e080b851c1c655c786a2da77f188f2dccd0f4b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/92e080b851c1c655c786a2da77f188f2dccd0f4b",
+ "reference": "92e080b851c1c655c786a2da77f188f2dccd0f4b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.2",
+ "symfony/polyfill-ctype": "^1.8"
+ },
+ "conflict": {
+ "symfony/console": "<6.4"
+ },
+ "require-dev": {
+ "symfony/console": "^6.4|^7.0"
+ },
+ "bin": [
+ "Resources/bin/yaml-lint"
+ ],
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Yaml\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Loads and dumps YAML files",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/yaml/tree/v7.1.4"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2024-08-12T09:59:40+00:00"
},
{
"name": "tijsverkoyen/css-to-inline-styles",
@@ -5462,6 +8851,91 @@
},
"time": "2023-12-08T13:03:43+00:00"
},
+ {
+ "name": "uma/phpecc",
+ "version": "v0.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/1ma/phpecc.git",
+ "reference": "a83dfa5fd6801fcc029364a555cec584d351c481"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/1ma/phpecc/zipball/a83dfa5fd6801fcc029364a555cec584d351c481",
+ "reference": "a83dfa5fd6801fcc029364a555cec584d351c481",
+ "shasum": ""
+ },
+ "require": {
+ "ext-gmp": "*",
+ "fgrosse/phpasn1": "^2.0",
+ "php": "^8.0"
+ },
+ "replace": {
+ "mdanter/ecc": "1.0.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.0||^8.0||^9.0",
+ "squizlabs/php_codesniffer": "^2.0",
+ "symfony/yaml": "^2.6|^3.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Mdanter\\Ecc\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Matyas Danter",
+ "homepage": "http://matejdanter.com/",
+ "role": "Author"
+ },
+ {
+ "name": "Thibaud Fabre",
+ "email": "thibaud@aztech.io",
+ "homepage": "http://aztech.io",
+ "role": "Maintainer"
+ },
+ {
+ "name": "Thomas Kerin",
+ "email": "afk11@users.noreply.github.com",
+ "role": "Maintainer"
+ },
+ {
+ "name": "Ology Newswire, Inc",
+ "email": "protocol@vpsqr.com",
+ "homepage": "https://vpsqr.com/",
+ "role": "Maintainer"
+ }
+ ],
+ "description": "Temporary fork of public-square/phpecc",
+ "homepage": "https://github.com/1ma/phpecc",
+ "keywords": [
+ "Diffie",
+ "ECDSA",
+ "Hellman",
+ "curve",
+ "ecdh",
+ "elliptic",
+ "nistp192",
+ "nistp224",
+ "nistp256",
+ "nistp384",
+ "nistp521",
+ "phpecc",
+ "schnorr",
+ "secp256k1",
+ "secp256r1"
+ ],
+ "support": {
+ "source": "https://github.com/1ma/phpecc/tree/v0.1.3"
+ },
+ "time": "2024-02-27T15:58:47+00:00"
+ },
{
"name": "vlucas/phpdotenv",
"version": "v5.6.1",
@@ -5886,16 +9360,16 @@
},
{
"name": "fidry/cpu-core-counter",
- "version": "1.1.0",
+ "version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/theofidry/cpu-core-counter.git",
- "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42"
+ "reference": "8520451a140d3f46ac33042715115e290cf5785f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/f92996c4d5c1a696a6a970e20f7c4216200fcc42",
- "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42",
+ "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/8520451a140d3f46ac33042715115e290cf5785f",
+ "reference": "8520451a140d3f46ac33042715115e290cf5785f",
"shasum": ""
},
"require": {
@@ -5935,7 +9409,7 @@
],
"support": {
"issues": "https://github.com/theofidry/cpu-core-counter/issues",
- "source": "https://github.com/theofidry/cpu-core-counter/tree/1.1.0"
+ "source": "https://github.com/theofidry/cpu-core-counter/tree/1.2.0"
},
"funding": [
{
@@ -5943,7 +9417,7 @@
"type": "github"
}
],
- "time": "2024-02-07T09:43:46+00:00"
+ "time": "2024-08-06T10:04:20+00:00"
},
{
"name": "filp/whoops",
@@ -6128,16 +9602,16 @@
},
{
"name": "laravel/pint",
- "version": "v1.17.2",
+ "version": "v1.17.3",
"source": {
"type": "git",
"url": "https://github.com/laravel/pint.git",
- "reference": "e8a88130a25e3f9d4d5785e6a1afca98268ab110"
+ "reference": "9d77be916e145864f10788bb94531d03e1f7b482"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/pint/zipball/e8a88130a25e3f9d4d5785e6a1afca98268ab110",
- "reference": "e8a88130a25e3f9d4d5785e6a1afca98268ab110",
+ "url": "https://api.github.com/repos/laravel/pint/zipball/9d77be916e145864f10788bb94531d03e1f7b482",
+ "reference": "9d77be916e145864f10788bb94531d03e1f7b482",
"shasum": ""
},
"require": {
@@ -6148,13 +9622,13 @@
"php": "^8.1.0"
},
"require-dev": {
- "friendsofphp/php-cs-fixer": "^3.61.1",
- "illuminate/view": "^10.48.18",
+ "friendsofphp/php-cs-fixer": "^3.64.0",
+ "illuminate/view": "^10.48.20",
"larastan/larastan": "^2.9.8",
"laravel-zero/framework": "^10.4.0",
"mockery/mockery": "^1.6.12",
"nunomaduro/termwind": "^1.15.1",
- "pestphp/pest": "^2.35.0"
+ "pestphp/pest": "^2.35.1"
},
"bin": [
"builds/pint"
@@ -6190,70 +9664,7 @@
"issues": "https://github.com/laravel/pint/issues",
"source": "https://github.com/laravel/pint"
},
- "time": "2024-08-06T15:11:54+00:00"
- },
- {
- "name": "laravel/sail",
- "version": "v1.31.1",
- "source": {
- "type": "git",
- "url": "https://github.com/laravel/sail.git",
- "reference": "3d06dd18cee8059baa7b388af00ba47f6d96bd85"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/laravel/sail/zipball/3d06dd18cee8059baa7b388af00ba47f6d96bd85",
- "reference": "3d06dd18cee8059baa7b388af00ba47f6d96bd85",
- "shasum": ""
- },
- "require": {
- "illuminate/console": "^9.52.16|^10.0|^11.0",
- "illuminate/contracts": "^9.52.16|^10.0|^11.0",
- "illuminate/support": "^9.52.16|^10.0|^11.0",
- "php": "^8.0",
- "symfony/console": "^6.0|^7.0",
- "symfony/yaml": "^6.0|^7.0"
- },
- "require-dev": {
- "orchestra/testbench": "^7.0|^8.0|^9.0",
- "phpstan/phpstan": "^1.10"
- },
- "bin": [
- "bin/sail"
- ],
- "type": "library",
- "extra": {
- "laravel": {
- "providers": [
- "Laravel\\Sail\\SailServiceProvider"
- ]
- }
- },
- "autoload": {
- "psr-4": {
- "Laravel\\Sail\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Taylor Otwell",
- "email": "taylor@laravel.com"
- }
- ],
- "description": "Docker files for running a basic Laravel application.",
- "keywords": [
- "docker",
- "laravel"
- ],
- "support": {
- "issues": "https://github.com/laravel/sail/issues",
- "source": "https://github.com/laravel/sail"
- },
- "time": "2024-08-02T07:45:47+00:00"
+ "time": "2024-09-03T15:00:28+00:00"
},
{
"name": "mockery/mockery",
@@ -8496,77 +11907,6 @@
],
"time": "2023-02-07T11:34:05+00:00"
},
- {
- "name": "symfony/yaml",
- "version": "v7.1.1",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/yaml.git",
- "reference": "fa34c77015aa6720469db7003567b9f772492bf2"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/fa34c77015aa6720469db7003567b9f772492bf2",
- "reference": "fa34c77015aa6720469db7003567b9f772492bf2",
- "shasum": ""
- },
- "require": {
- "php": ">=8.2",
- "symfony/polyfill-ctype": "^1.8"
- },
- "conflict": {
- "symfony/console": "<6.4"
- },
- "require-dev": {
- "symfony/console": "^6.4|^7.0"
- },
- "bin": [
- "Resources/bin/yaml-lint"
- ],
- "type": "library",
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\Yaml\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Loads and dumps YAML files",
- "homepage": "https://symfony.com",
- "support": {
- "source": "https://github.com/symfony/yaml/tree/v7.1.1"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2024-05-31T14:57:53+00:00"
- },
{
"name": "ta-tikoma/phpunit-architecture-test",
"version": "0.8.4",
diff --git a/config/broadcasting.php b/config/broadcasting.php
new file mode 100644
index 0000000..ebc3fb9
--- /dev/null
+++ b/config/broadcasting.php
@@ -0,0 +1,82 @@
+ env('BROADCAST_CONNECTION', 'null'),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Broadcast Connections
+ |--------------------------------------------------------------------------
+ |
+ | Here you may define all of the broadcast connections that will be used
+ | to broadcast events to other systems or over WebSockets. Samples of
+ | each available type of connection are provided inside this array.
+ |
+ */
+
+ 'connections' => [
+
+ 'reverb' => [
+ 'driver' => 'reverb',
+ 'key' => env('REVERB_APP_KEY'),
+ 'secret' => env('REVERB_APP_SECRET'),
+ 'app_id' => env('REVERB_APP_ID'),
+ 'options' => [
+ 'host' => env('REVERB_HOST'),
+ 'port' => env('REVERB_PORT', 443),
+ 'scheme' => env('REVERB_SCHEME', 'https'),
+ 'useTLS' => env('REVERB_SCHEME', 'https') === 'https',
+ ],
+ 'client_options' => [
+ // Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html
+ ],
+ ],
+
+ 'pusher' => [
+ 'driver' => 'pusher',
+ 'key' => env('PUSHER_APP_KEY'),
+ 'secret' => env('PUSHER_APP_SECRET'),
+ 'app_id' => env('PUSHER_APP_ID'),
+ 'options' => [
+ 'cluster' => env('PUSHER_APP_CLUSTER'),
+ 'host' => env('PUSHER_HOST') ?: 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com',
+ 'port' => env('PUSHER_PORT', 443),
+ 'scheme' => env('PUSHER_SCHEME', 'https'),
+ 'encrypted' => true,
+ 'useTLS' => env('PUSHER_SCHEME', 'https') === 'https',
+ ],
+ 'client_options' => [
+ // Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html
+ ],
+ ],
+
+ 'ably' => [
+ 'driver' => 'ably',
+ 'key' => env('ABLY_KEY'),
+ ],
+
+ 'log' => [
+ 'driver' => 'log',
+ ],
+
+ 'null' => [
+ 'driver' => 'null',
+ ],
+
+ ],
+
+];
diff --git a/config/database.php b/config/database.php
index 125949e..e51ba11 100644
--- a/config/database.php
+++ b/config/database.php
@@ -97,6 +97,21 @@ return [
'sslmode' => 'prefer',
],
+ 'einundzwanzig' => [
+ 'driver' => 'pgsql',
+ 'url' => env('DB_URL'),
+ 'host' => env('DB_HOST', '127.0.0.1'),
+ 'port' => env('DB_PORT', '5432'),
+ 'database' => 'einundzwanzig',
+ 'username' => env('DB_USERNAME', 'root'),
+ 'password' => env('DB_PASSWORD', ''),
+ 'charset' => env('DB_CHARSET', 'utf8'),
+ 'prefix' => '',
+ 'prefix_indexes' => true,
+ 'search_path' => 'public',
+ 'sslmode' => 'prefer',
+ ],
+
'sqlsrv' => [
'driver' => 'sqlsrv',
'url' => env('DB_URL'),
diff --git a/config/google-fonts.php b/config/google-fonts.php
new file mode 100644
index 0000000..8128a01
--- /dev/null
+++ b/config/google-fonts.php
@@ -0,0 +1,52 @@
+ [
+ 'default' => 'https://fonts.googleapis.com/css2?family=Inconsolata:ital,wght@0,400;0,700;1,400;1,700',
+ 'article' => 'https://fonts.googleapis.com/css2?family=Karla:ital,wght@0,400;0,700;1,400;1,700',
+ ],
+
+ /*
+ * This disk will be used to store local Google Fonts. The public disk
+ * is the default because it can be served over HTTP with storage:link.
+ */
+ 'disk' => 'public',
+
+ /*
+ * Prepend all files that are written to the selected disk with this path.
+ * This allows separating the fonts from other data in the public disk.
+ */
+ 'path' => 'fonts',
+
+ /*
+ * By default, CSS will be inlined to reduce the amount of round trips
+ * browsers need to make in order to load the requested font files.
+ */
+ 'inline' => true,
+
+ /*
+ * When preload is set to true, preload meta tags will be generated
+ * in the HTML output to instruct the browser to start fetching the
+ * font files as early as possible, even before the CSS is fully parsed.
+ */
+ 'preload' => false,
+
+ /*
+ * When something goes wrong fonts are loaded directly from Google.
+ * With fallback disabled, this package will throw an exception.
+ */
+ 'fallback' => ! env('APP_DEBUG'),
+
+ /*
+ * This user agent will be used to request the stylesheet from Google Fonts.
+ * This is the Safari 14 user agent that only targets modern browsers. If
+ * you want to target older browsers, use different user agent string.
+ */
+ 'user_agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15',
+
+];
diff --git a/config/livewire-powergrid.php b/config/livewire-powergrid.php
new file mode 100644
index 0000000..2d51c83
--- /dev/null
+++ b/config/livewire-powergrid.php
@@ -0,0 +1,156 @@
+ \PowerComponents\LivewirePowerGrid\Themes\Tailwind::class,
+ //'theme' => \PowerComponents\LivewirePowerGrid\Themes\Bootstrap5::class,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Plugins
+ |--------------------------------------------------------------------------
+ |
+ | Plugins used: flatpickr.js to datepicker.
+ |
+ */
+
+ 'plugins' => [
+ /*
+ * https://flatpickr.js.org
+ */
+ 'flatpickr' => [
+ 'locales' => [
+ 'de_DE' => [
+ 'locale' => 'de',
+ 'dateFormat' => 'd.m.Y H:i',
+ 'enableTime' => true,
+ 'time_24hr' => true,
+ ],
+ ],
+ ],
+
+ 'select' => [
+ 'default' => 'tom',
+
+ /*
+ * TomSelect Options
+ * https://tom-select.js.org
+ */
+ 'tom' => [
+ 'plugins' => [
+ 'clear_button' => [
+ 'title' => 'Remove all selected options',
+ ],
+ ],
+ ],
+
+ /*
+ * Slim Select options
+ * https://slimselectjs.com/
+ */
+ 'slim' => [
+ 'settings' => [
+ 'alwaysOpen' => false,
+ ],
+ ],
+ ],
+ ],
+
+ /*
+ |--------------------------------------------------------------------------
+ | Filters
+ |--------------------------------------------------------------------------
+ |
+ | PowerGrid supports inline and outside filters.
+ | 'inline': Filters data inside the table.
+ | 'outside': Filters data outside the table.
+ | 'null'
+ |
+ */
+
+ 'filter' => 'outside',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Persisting
+ |--------------------------------------------------------------------------
+ |
+ | PowerGrid supports persisting of the filters, columns and sorting.
+ | 'session': persist in the session.
+ | 'cache': persist with cache.
+ | 'cookies': persist with cookies (default).
+ |
+ */
+
+ 'persist_driver' => 'cookies',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Cache
+ |--------------------------------------------------------------------------
+ |
+ | Cache is enabled by default to improve search performance when using collections.
+ | When enabled, data is reloaded whenever the page is refreshed or a field is updated.
+ |
+ */
+
+ 'cached_data' => true,
+
+ /*
+ |--------------------------------------------------------------------------
+ | New Release Notification
+ |--------------------------------------------------------------------------
+ |
+ | PowerGrid can verify if a new release is available when you create a new PowerGrid Table.
+ |
+ | This feature depends on composer/composer.
+ | To install, run: `composer require composer/composer --dev`
+ |
+ */
+
+ 'check_version' => false,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Exportable class
+ |--------------------------------------------------------------------------
+ |
+ |
+ */
+
+ 'exportable' => [
+ 'default' => 'openspout_v4',
+ 'openspout_v4' => [
+ 'xlsx' => \PowerComponents\LivewirePowerGrid\Components\Exports\OpenSpout\v4\ExportToXLS::class,
+ 'csv' => \PowerComponents\LivewirePowerGrid\Components\Exports\OpenSpout\v4\ExportToCsv::class,
+ ],
+ 'openspout_v3' => [
+ 'xlsx' => \PowerComponents\LivewirePowerGrid\Components\Exports\OpenSpout\v3\ExportToXLS::class,
+ 'csv' => \PowerComponents\LivewirePowerGrid\Components\Exports\OpenSpout\v3\ExportToCsv::class,
+ ],
+ ],
+
+ /*
+ |--------------------------------------------------------------------------
+ | Auto-Discover Models
+ |--------------------------------------------------------------------------
+ |
+ | PowerGrid will search for Models in the directories listed below.
+ | These Models be listed as options when you run the
+ | "artisan powergrid:create" command.
+ |
+ */
+
+ 'auto_discover_models_paths' => [
+ app_path('Models'),
+ ],
+];
diff --git a/config/media-library.php b/config/media-library.php
new file mode 100644
index 0000000..22517c5
--- /dev/null
+++ b/config/media-library.php
@@ -0,0 +1,280 @@
+ env('MEDIA_DISK', 'public'),
+
+ /*
+ * The maximum file size of an item in bytes.
+ * Adding a larger file will result in an exception.
+ */
+ 'max_file_size' => 1024 * 1024 * 10, // 10MB
+
+ /*
+ * This queue connection will be used to generate derived and responsive images.
+ * Leave empty to use the default queue connection.
+ */
+ 'queue_connection_name' => env('QUEUE_CONNECTION', 'sync'),
+
+ /*
+ * This queue will be used to generate derived and responsive images.
+ * Leave empty to use the default queue.
+ */
+ 'queue_name' => env('MEDIA_QUEUE', ''),
+
+ /*
+ * By default all conversions will be performed on a queue.
+ */
+ 'queue_conversions_by_default' => env('QUEUE_CONVERSIONS_BY_DEFAULT', true),
+
+ /*
+ * Should database transactions be run after database commits?
+ */
+ 'queue_conversions_after_database_commit' => env('QUEUE_CONVERSIONS_AFTER_DB_COMMIT', true),
+
+ /*
+ * The fully qualified class name of the media model.
+ */
+ 'media_model' => Spatie\MediaLibrary\MediaCollections\Models\Media::class,
+
+ /*
+ * When enabled, media collections will be serialised using the default
+ * laravel model serialization behaviour.
+ *
+ * Keep this option disabled if using Media Library Pro components (https://medialibrary.pro)
+ */
+ 'use_default_collection_serialization' => false,
+
+ /*
+ * The fully qualified class name of the model used for temporary uploads.
+ *
+ * This model is only used in Media Library Pro (https://medialibrary.pro)
+ */
+ 'temporary_upload_model' => Spatie\MediaLibraryPro\Models\TemporaryUpload::class,
+
+ /*
+ * When enabled, Media Library Pro will only process temporary uploads that were uploaded
+ * in the same session. You can opt to disable this for stateless usage of
+ * the pro components.
+ */
+ 'enable_temporary_uploads_session_affinity' => true,
+
+ /*
+ * When enabled, Media Library pro will generate thumbnails for uploaded file.
+ */
+ 'generate_thumbnails_for_temporary_uploads' => true,
+
+ /*
+ * This is the class that is responsible for naming generated files.
+ */
+ 'file_namer' => Spatie\MediaLibrary\Support\FileNamer\DefaultFileNamer::class,
+
+ /*
+ * The class that contains the strategy for determining a media file's path.
+ */
+ 'path_generator' => Spatie\MediaLibrary\Support\PathGenerator\DefaultPathGenerator::class,
+
+ /*
+ * The class that contains the strategy for determining how to remove files.
+ */
+ 'file_remover_class' => Spatie\MediaLibrary\Support\FileRemover\DefaultFileRemover::class,
+
+ /*
+ * Here you can specify which path generator should be used for the given class.
+ */
+ 'custom_path_generators' => [
+ // Model::class => PathGenerator::class
+ // or
+ // 'model_morph_alias' => PathGenerator::class
+ ],
+
+ /*
+ * When urls to files get generated, this class will be called. Use the default
+ * if your files are stored locally above the site root or on s3.
+ */
+ 'url_generator' => Spatie\MediaLibrary\Support\UrlGenerator\DefaultUrlGenerator::class,
+
+ /*
+ * Moves media on updating to keep path consistent. Enable it only with a custom
+ * PathGenerator that uses, for example, the media UUID.
+ */
+ 'moves_media_on_update' => false,
+
+ /*
+ * Whether to activate versioning when urls to files get generated.
+ * When activated, this attaches a ?v=xx query string to the URL.
+ */
+ 'version_urls' => false,
+
+ /*
+ * The media library will try to optimize all converted images by removing
+ * metadata and applying a little bit of compression. These are
+ * the optimizers that will be used by default.
+ */
+ 'image_optimizers' => [
+ Spatie\ImageOptimizer\Optimizers\Jpegoptim::class => [
+ '-m85', // set maximum quality to 85%
+ '--force', // ensure that progressive generation is always done also if a little bigger
+ '--strip-all', // this strips out all text information such as comments and EXIF data
+ '--all-progressive', // this will make sure the resulting image is a progressive one
+ ],
+ Spatie\ImageOptimizer\Optimizers\Pngquant::class => [
+ '--force', // required parameter for this package
+ ],
+ Spatie\ImageOptimizer\Optimizers\Optipng::class => [
+ '-i0', // this will result in a non-interlaced, progressive scanned image
+ '-o2', // this set the optimization level to two (multiple IDAT compression trials)
+ '-quiet', // required parameter for this package
+ ],
+ Spatie\ImageOptimizer\Optimizers\Svgo::class => [
+ '--disable=cleanupIDs', // disabling because it is known to cause troubles
+ ],
+ Spatie\ImageOptimizer\Optimizers\Gifsicle::class => [
+ '-b', // required parameter for this package
+ '-O3', // this produces the slowest but best results
+ ],
+ Spatie\ImageOptimizer\Optimizers\Cwebp::class => [
+ '-m 6', // for the slowest compression method in order to get the best compression.
+ '-pass 10', // for maximizing the amount of analysis pass.
+ '-mt', // multithreading for some speed improvements.
+ '-q 90', //quality factor that brings the least noticeable changes.
+ ],
+ Spatie\ImageOptimizer\Optimizers\Avifenc::class => [
+ '-a cq-level=23', // constant quality level, lower values mean better quality and greater file size (0-63).
+ '-j all', // number of jobs (worker threads, "all" uses all available cores).
+ '--min 0', // min quantizer for color (0-63).
+ '--max 63', // max quantizer for color (0-63).
+ '--minalpha 0', // min quantizer for alpha (0-63).
+ '--maxalpha 63', // max quantizer for alpha (0-63).
+ '-a end-usage=q', // rate control mode set to Constant Quality mode.
+ '-a tune=ssim', // SSIM as tune the encoder for distortion metric.
+ ],
+ ],
+
+ /*
+ * These generators will be used to create an image of media files.
+ */
+ 'image_generators' => [
+ Spatie\MediaLibrary\Conversions\ImageGenerators\Image::class,
+ Spatie\MediaLibrary\Conversions\ImageGenerators\Webp::class,
+ Spatie\MediaLibrary\Conversions\ImageGenerators\Avif::class,
+ Spatie\MediaLibrary\Conversions\ImageGenerators\Pdf::class,
+ Spatie\MediaLibrary\Conversions\ImageGenerators\Svg::class,
+ Spatie\MediaLibrary\Conversions\ImageGenerators\Video::class,
+ ],
+
+ /*
+ * The path where to store temporary files while performing image conversions.
+ * If set to null, storage_path('media-library/temp') will be used.
+ */
+ 'temporary_directory_path' => null,
+
+ /*
+ * The engine that should perform the image conversions.
+ * Should be either `gd` or `imagick`.
+ */
+ 'image_driver' => env('IMAGE_DRIVER', 'gd'),
+
+ /*
+ * FFMPEG & FFProbe binaries paths, only used if you try to generate video
+ * thumbnails and have installed the php-ffmpeg/php-ffmpeg composer
+ * dependency.
+ */
+ 'ffmpeg_path' => env('FFMPEG_PATH', '/usr/bin/ffmpeg'),
+ 'ffprobe_path' => env('FFPROBE_PATH', '/usr/bin/ffprobe'),
+
+ /*
+ * Here you can override the class names of the jobs used by this package. Make sure
+ * your custom jobs extend the ones provided by the package.
+ */
+ 'jobs' => [
+ 'perform_conversions' => Spatie\MediaLibrary\Conversions\Jobs\PerformConversionsJob::class,
+ 'generate_responsive_images' => Spatie\MediaLibrary\ResponsiveImages\Jobs\GenerateResponsiveImagesJob::class,
+ ],
+
+ /*
+ * When using the addMediaFromUrl method you may want to replace the default downloader.
+ * This is particularly useful when the url of the image is behind a firewall and
+ * need to add additional flags, possibly using curl.
+ */
+ 'media_downloader' => Spatie\MediaLibrary\Downloaders\DefaultDownloader::class,
+
+ /*
+ * When using the addMediaFromUrl method the SSL is verified by default.
+ * This is option disables SSL verification when downloading remote media.
+ * Please note that this is a security risk and should only be false in a local environment.
+ */
+ 'media_downloader_ssl' => env('MEDIA_DOWNLOADER_SSL', true),
+
+ 'remote' => [
+ /*
+ * Any extra headers that should be included when uploading media to
+ * a remote disk. Even though supported headers may vary between
+ * different drivers, a sensible default has been provided.
+ *
+ * Supported by S3: CacheControl, Expires, StorageClass,
+ * ServerSideEncryption, Metadata, ACL, ContentEncoding
+ */
+ 'extra_headers' => [
+ 'CacheControl' => 'max-age=604800',
+ ],
+ ],
+
+ 'responsive_images' => [
+ /*
+ * This class is responsible for calculating the target widths of the responsive
+ * images. By default we optimize for filesize and create variations that each are 30%
+ * smaller than the previous one. More info in the documentation.
+ *
+ * https://docs.spatie.be/laravel-medialibrary/v9/advanced-usage/generating-responsive-images
+ */
+ 'width_calculator' => Spatie\MediaLibrary\ResponsiveImages\WidthCalculator\FileSizeOptimizedWidthCalculator::class,
+
+ /*
+ * By default rendering media to a responsive image will add some javascript and a tiny placeholder.
+ * This ensures that the browser can already determine the correct layout.
+ * When disabled, no tiny placeholder is generated.
+ */
+ 'use_tiny_placeholders' => true,
+
+ /*
+ * This class will generate the tiny placeholder used for progressive image loading. By default
+ * the media library will use a tiny blurred jpg image.
+ */
+ 'tiny_placeholder_generator' => Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\Blurred::class,
+ ],
+
+ /*
+ * When enabling this option, a route will be registered that will enable
+ * the Media Library Pro Vue and React components to move uploaded files
+ * in a S3 bucket to their right place.
+ */
+ 'enable_vapor_uploads' => env('ENABLE_MEDIA_LIBRARY_VAPOR_UPLOADS', false),
+
+ /*
+ * When converting Media instances to response the media library will add
+ * a `loading` attribute to the `img` tag. Here you can set the default
+ * value of that attribute.
+ *
+ * Possible values: 'lazy', 'eager', 'auto' or null if you don't want to set any loading instruction.
+ *
+ * More info: https://css-tricks.com/native-lazy-loading/
+ */
+ 'default_loading_attribute_value' => null,
+
+ /*
+ * You can specify a prefix for that is used for storing all media.
+ * If you set this to `/my-subdir`, all your media will be stored in a `/my-subdir` directory.
+ */
+ 'prefix' => env('MEDIA_PREFIX', ''),
+
+ /*
+ * When forcing lazy loading, media will be loaded even if you don't eager load media and you have
+ * disabled lazy loading globally in the service provider.
+ */
+ 'force_lazy_loading' => env('FORCE_MEDIA_LIBRARY_LAZY_LOADING', true),
+];
diff --git a/config/pulse.php b/config/pulse.php
new file mode 100644
index 0000000..7ffe0f5
--- /dev/null
+++ b/config/pulse.php
@@ -0,0 +1,242 @@
+ env('PULSE_DOMAIN'),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Pulse Path
+ |--------------------------------------------------------------------------
+ |
+ | This is the path which the Pulse dashboard will be accessible from. Feel
+ | free to change this path to anything you'd like. Note that this won't
+ | affect the path of the internal API that is never exposed to users.
+ |
+ */
+
+ 'path' => env('PULSE_PATH', 'pulse'),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Pulse Master Switch
+ |--------------------------------------------------------------------------
+ |
+ | This configuration option may be used to completely disable all Pulse
+ | data recorders regardless of their individual configurations. This
+ | provides a single option to quickly disable all Pulse recording.
+ |
+ */
+
+ 'enabled' => env('PULSE_ENABLED', true),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Pulse Storage Driver
+ |--------------------------------------------------------------------------
+ |
+ | This configuration option determines which storage driver will be used
+ | while storing entries from Pulse's recorders. In addition, you also
+ | may provide any options to configure the selected storage driver.
+ |
+ */
+
+ 'storage' => [
+ 'driver' => env('PULSE_STORAGE_DRIVER', 'database'),
+
+ 'database' => [
+ 'connection' => env('PULSE_DB_CONNECTION', null),
+ 'chunk' => 1000,
+ ],
+ ],
+
+ /*
+ |--------------------------------------------------------------------------
+ | Pulse Ingest Driver
+ |--------------------------------------------------------------------------
+ |
+ | This configuration options determines the ingest driver that will be used
+ | to capture entries from Pulse's recorders. Ingest drivers are great to
+ | free up your request workers quickly by offloading the data storage.
+ |
+ */
+
+ 'ingest' => [
+ 'driver' => env('PULSE_INGEST_DRIVER', 'storage'),
+
+ 'buffer' => env('PULSE_INGEST_BUFFER', 5_000),
+
+ 'trim' => [
+ 'lottery' => [1, 1_000],
+ 'keep' => '7 days',
+ ],
+
+ 'redis' => [
+ 'connection' => env('PULSE_REDIS_CONNECTION'),
+ 'chunk' => 1000,
+ ],
+ ],
+
+ /*
+ |--------------------------------------------------------------------------
+ | Pulse Cache Driver
+ |--------------------------------------------------------------------------
+ |
+ | This configuration option determines the cache driver that will be used
+ | for various tasks, including caching dashboard results, establishing
+ | locks for events that should only occur on one server and signals.
+ |
+ */
+
+ 'cache' => env('PULSE_CACHE_DRIVER'),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Pulse Route Middleware
+ |--------------------------------------------------------------------------
+ |
+ | These middleware will be assigned to every Pulse route, giving you the
+ | chance to add your own middleware to this list or change any of the
+ | existing middleware. Of course, reasonable defaults are provided.
+ |
+ */
+
+ 'middleware' => [
+ 'web',
+ Authorize::class,
+ ],
+
+ /*
+ |--------------------------------------------------------------------------
+ | Pulse Recorders
+ |--------------------------------------------------------------------------
+ |
+ | The following array lists the "recorders" that will be registered with
+ | Pulse, along with their configuration. Recorders gather application
+ | event data from requests and tasks to pass to your ingest driver.
+ |
+ */
+
+ 'recorders' => [
+ ReverbConnections::class => [
+ 'sample_rate' => 1,
+ ],
+
+ ReverbMessages::class => [
+ 'sample_rate' => 1,
+ ],
+
+ Recorders\CacheInteractions::class => [
+ 'enabled' => env('PULSE_CACHE_INTERACTIONS_ENABLED', true),
+ 'sample_rate' => env('PULSE_CACHE_INTERACTIONS_SAMPLE_RATE', 1),
+ 'ignore' => [
+ ...Pulse::defaultVendorCacheKeys(),
+ ],
+ 'groups' => [
+ '/^job-exceptions:.*/' => 'job-exceptions:*',
+ // '/:\d+/' => ':*',
+ ],
+ ],
+
+ Recorders\Exceptions::class => [
+ 'enabled' => env('PULSE_EXCEPTIONS_ENABLED', true),
+ 'sample_rate' => env('PULSE_EXCEPTIONS_SAMPLE_RATE', 1),
+ 'location' => env('PULSE_EXCEPTIONS_LOCATION', true),
+ 'ignore' => [
+ // '/^Package\\\\Exceptions\\\\/',
+ ],
+ ],
+
+ Recorders\Queues::class => [
+ 'enabled' => env('PULSE_QUEUES_ENABLED', true),
+ 'sample_rate' => env('PULSE_QUEUES_SAMPLE_RATE', 1),
+ 'ignore' => [
+ // '/^Package\\\\Jobs\\\\/',
+ ],
+ ],
+
+ Recorders\Servers::class => [
+ 'server_name' => env('PULSE_SERVER_NAME', gethostname()),
+ 'directories' => explode(':', env('PULSE_SERVER_DIRECTORIES', '/')),
+ ],
+
+ Recorders\SlowJobs::class => [
+ 'enabled' => env('PULSE_SLOW_JOBS_ENABLED', true),
+ 'sample_rate' => env('PULSE_SLOW_JOBS_SAMPLE_RATE', 1),
+ 'threshold' => env('PULSE_SLOW_JOBS_THRESHOLD', 1000),
+ 'ignore' => [
+ // '/^Package\\\\Jobs\\\\/',
+ ],
+ ],
+
+ Recorders\SlowOutgoingRequests::class => [
+ 'enabled' => env('PULSE_SLOW_OUTGOING_REQUESTS_ENABLED', true),
+ 'sample_rate' => env('PULSE_SLOW_OUTGOING_REQUESTS_SAMPLE_RATE', 1),
+ 'threshold' => env('PULSE_SLOW_OUTGOING_REQUESTS_THRESHOLD', 1000),
+ 'ignore' => [
+ // '#^http://127\.0\.0\.1:13714#', // Inertia SSR...
+ ],
+ 'groups' => [
+ // '#^https://api\.github\.com/repos/.*$#' => 'api.github.com/repos/*',
+ // '#^https?://([^/]*).*$#' => '\1',
+ // '#/\d+#' => '/*',
+ ],
+ ],
+
+ Recorders\SlowQueries::class => [
+ 'enabled' => env('PULSE_SLOW_QUERIES_ENABLED', true),
+ 'sample_rate' => env('PULSE_SLOW_QUERIES_SAMPLE_RATE', 1),
+ 'threshold' => env('PULSE_SLOW_QUERIES_THRESHOLD', 1000),
+ 'location' => env('PULSE_SLOW_QUERIES_LOCATION', true),
+ 'max_query_length' => env('PULSE_SLOW_QUERIES_MAX_QUERY_LENGTH', null),
+ 'ignore' => [
+ '/(["`])pulse_[\w]+?\1/', // Pulse tables...
+ '/(["`])telescope_[\w]+?\1/', // Telescope tables...
+ ],
+ ],
+
+ Recorders\SlowRequests::class => [
+ 'enabled' => env('PULSE_SLOW_REQUESTS_ENABLED', true),
+ 'sample_rate' => env('PULSE_SLOW_REQUESTS_SAMPLE_RATE', 1),
+ 'threshold' => env('PULSE_SLOW_REQUESTS_THRESHOLD', 1000),
+ 'ignore' => [
+ '#^/'.env('PULSE_PATH', 'pulse').'$#', // Pulse dashboard...
+ '#^/telescope#', // Telescope dashboard...
+ ],
+ ],
+
+ Recorders\UserJobs::class => [
+ 'enabled' => env('PULSE_USER_JOBS_ENABLED', true),
+ 'sample_rate' => env('PULSE_USER_JOBS_SAMPLE_RATE', 1),
+ 'ignore' => [
+ // '/^Package\\\\Jobs\\\\/',
+ ],
+ ],
+
+ Recorders\UserRequests::class => [
+ 'enabled' => env('PULSE_USER_REQUESTS_ENABLED', true),
+ 'sample_rate' => env('PULSE_USER_REQUESTS_SAMPLE_RATE', 1),
+ 'ignore' => [
+ '#^/'.env('PULSE_PATH', 'pulse').'$#', // Pulse dashboard...
+ '#^/telescope#', // Telescope dashboard...
+ ],
+ ],
+ ],
+];
diff --git a/config/reverb.php b/config/reverb.php
new file mode 100644
index 0000000..798ead6
--- /dev/null
+++ b/config/reverb.php
@@ -0,0 +1,91 @@
+ env('REVERB_SERVER', 'reverb'),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Reverb Servers
+ |--------------------------------------------------------------------------
+ |
+ | Here you may define details for each of the supported Reverb servers.
+ | Each server has its own configuration options that are defined in
+ | the array below. You should ensure all the options are present.
+ |
+ */
+
+ 'servers' => [
+
+ 'reverb' => [
+ 'host' => env('REVERB_SERVER_HOST', '0.0.0.0'),
+ 'port' => env('REVERB_SERVER_PORT', 8080),
+ 'hostname' => env('REVERB_HOST'),
+ 'options' => [
+ 'tls' => [],
+ ],
+ 'max_request_size' => env('REVERB_MAX_REQUEST_SIZE', 10_000),
+ 'scaling' => [
+ 'enabled' => env('REVERB_SCALING_ENABLED', false),
+ 'channel' => env('REVERB_SCALING_CHANNEL', 'reverb'),
+ 'server' => [
+ 'url' => env('REDIS_URL'),
+ 'host' => env('REDIS_HOST', '127.0.0.1'),
+ 'port' => env('REDIS_PORT', '6379'),
+ 'username' => env('REDIS_USERNAME'),
+ 'password' => env('REDIS_PASSWORD'),
+ 'database' => env('REDIS_DB', '0'),
+ ],
+ ],
+ 'pulse_ingest_interval' => env('REVERB_PULSE_INGEST_INTERVAL', 15),
+ 'telescope_ingest_interval' => env('REVERB_TELESCOPE_INGEST_INTERVAL', 15),
+ ],
+
+ ],
+
+ /*
+ |--------------------------------------------------------------------------
+ | Reverb Applications
+ |--------------------------------------------------------------------------
+ |
+ | Here you may define how Reverb applications are managed. If you choose
+ | to use the "config" provider, you may define an array of apps which
+ | your server will support, including their connection credentials.
+ |
+ */
+
+ 'apps' => [
+
+ 'provider' => 'config',
+
+ 'apps' => [
+ [
+ 'key' => env('REVERB_APP_KEY'),
+ 'secret' => env('REVERB_APP_SECRET'),
+ 'app_id' => env('REVERB_APP_ID'),
+ 'options' => [
+ 'host' => env('REVERB_HOST'),
+ 'port' => env('REVERB_PORT', 443),
+ 'scheme' => env('REVERB_SCHEME', 'https'),
+ 'useTLS' => env('REVERB_SCHEME', 'https') === 'https',
+ ],
+ 'allowed_origins' => ['*'],
+ 'ping_interval' => env('REVERB_APP_PING_INTERVAL', 60),
+ 'max_message_size' => env('REVERB_APP_MAX_MESSAGE_SIZE', 10_000),
+ ],
+ ],
+
+ ],
+
+];
diff --git a/database/migrations/2024_08_29_120928_create_einundzwanzig_plebs_table.php b/database/migrations/2024_08_29_120928_create_einundzwanzig_plebs_table.php
new file mode 100644
index 0000000..6671b79
--- /dev/null
+++ b/database/migrations/2024_08_29_120928_create_einundzwanzig_plebs_table.php
@@ -0,0 +1,28 @@
+id();
+ $table->string('npub', 63);
+ $table->string('pubkey', 64)->unique()->index();
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('einundzwanzig_plebs');
+ }
+};
diff --git a/database/migrations/2024_08_29_125457_create_profiles_table.php b/database/migrations/2024_08_29_125457_create_profiles_table.php
new file mode 100644
index 0000000..cab29a3
--- /dev/null
+++ b/database/migrations/2024_08_29_125457_create_profiles_table.php
@@ -0,0 +1,37 @@
+id();
+ $table->string('pubkey', 64)->unique()->index();
+ $table->string('name', 255 * 2)->nullable();
+ $table->string('display_name', 255 * 2)->nullable();
+ $table->text('picture')->nullable();
+ $table->text('banner')->nullable();
+ $table->string('website', 255 * 2)->nullable();
+ $table->text('about')->nullable();
+ $table->string('nip05', 255 * 2)->nullable();
+ $table->string('lud16', 255 * 2)->nullable();
+ $table->string('lud06', 255 * 2)->nullable();
+ $table->boolean('deleted')->nullable();
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('profiles');
+ }
+};
diff --git a/database/migrations/2024_08_29_141818_create_events_table.php b/database/migrations/2024_08_29_141818_create_events_table.php
new file mode 100644
index 0000000..b9e7d30
--- /dev/null
+++ b/database/migrations/2024_08_29_141818_create_events_table.php
@@ -0,0 +1,31 @@
+id();
+ $table->string('event_id', 64)->unique()->index();
+ $table->string('parent_event_id', 64)->index()->nullable();
+ $table->string('pubkey', 64)->index();
+ $table->json('json');
+ $table->string('type');
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('events');
+ }
+};
diff --git a/database/migrations/2024_08_29_143915_create_rendered_events_table.php b/database/migrations/2024_08_29_143915_create_rendered_events_table.php
new file mode 100644
index 0000000..14b706c
--- /dev/null
+++ b/database/migrations/2024_08_29_143915_create_rendered_events_table.php
@@ -0,0 +1,31 @@
+id();
+ $table->string('event_id', 64)->unique()->index();
+ $table->foreign('event_id')->references('event_id')->on('events')->cascadeOnDelete();
+ $table->text('html');
+ $table->string('profile_image');
+ $table->string('profile_name');
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('rendered_events');
+ }
+};
diff --git a/database/migrations/2024_08_29_190127_create_pulse_tables.php b/database/migrations/2024_08_29_190127_create_pulse_tables.php
new file mode 100644
index 0000000..5d194e2
--- /dev/null
+++ b/database/migrations/2024_08_29_190127_create_pulse_tables.php
@@ -0,0 +1,84 @@
+shouldRun()) {
+ return;
+ }
+
+ Schema::create('pulse_values', function (Blueprint $table) {
+ $table->id();
+ $table->unsignedInteger('timestamp');
+ $table->string('type');
+ $table->mediumText('key');
+ match ($this->driver()) {
+ 'mariadb', 'mysql' => $table->char('key_hash', 16)->charset('binary')->virtualAs('unhex(md5(`key`))'),
+ 'pgsql' => $table->uuid('key_hash')->storedAs('md5("key")::uuid'),
+ 'sqlite' => $table->string('key_hash'),
+ };
+ $table->mediumText('value');
+
+ $table->index('timestamp'); // For trimming...
+ $table->index('type'); // For fast lookups and purging...
+ $table->unique(['type', 'key_hash']); // For data integrity and upserts...
+ });
+
+ Schema::create('pulse_entries', function (Blueprint $table) {
+ $table->id();
+ $table->unsignedInteger('timestamp');
+ $table->string('type');
+ $table->mediumText('key');
+ match ($this->driver()) {
+ 'mariadb', 'mysql' => $table->char('key_hash', 16)->charset('binary')->virtualAs('unhex(md5(`key`))'),
+ 'pgsql' => $table->uuid('key_hash')->storedAs('md5("key")::uuid'),
+ 'sqlite' => $table->string('key_hash'),
+ };
+ $table->bigInteger('value')->nullable();
+
+ $table->index('timestamp'); // For trimming...
+ $table->index('type'); // For purging...
+ $table->index('key_hash'); // For mapping...
+ $table->index(['timestamp', 'type', 'key_hash', 'value']); // For aggregate queries...
+ });
+
+ Schema::create('pulse_aggregates', function (Blueprint $table) {
+ $table->id();
+ $table->unsignedInteger('bucket');
+ $table->unsignedMediumInteger('period');
+ $table->string('type');
+ $table->mediumText('key');
+ match ($this->driver()) {
+ 'mariadb', 'mysql' => $table->char('key_hash', 16)->charset('binary')->virtualAs('unhex(md5(`key`))'),
+ 'pgsql' => $table->uuid('key_hash')->storedAs('md5("key")::uuid'),
+ 'sqlite' => $table->string('key_hash'),
+ };
+ $table->string('aggregate');
+ $table->decimal('value', 20, 2);
+ $table->unsignedInteger('count')->nullable();
+
+ $table->unique(['bucket', 'period', 'type', 'aggregate', 'key_hash']); // Force "on duplicate update"...
+ $table->index(['period', 'bucket']); // For trimming...
+ $table->index('type'); // For purging...
+ $table->index(['period', 'type', 'aggregate', 'bucket']); // For aggregate queries...
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('pulse_values');
+ Schema::dropIfExists('pulse_entries');
+ Schema::dropIfExists('pulse_aggregates');
+ }
+};
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..914f77b
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,75 @@
+services:
+ laravel.test:
+ build:
+ context: ./docker/8.3
+ dockerfile: Dockerfile
+ args:
+ WWWGROUP: '${WWWGROUP}'
+ image: sail-8.3/app
+ extra_hosts:
+ - 'host.docker.internal:host-gateway'
+ ports:
+ - '${APP_PORT:-80}:80'
+ - '${VITE_PORT:-5173}:${VITE_PORT:-5173}'
+ - '${REVERB_SERVER_PORT:-8080}:8080'
+ environment:
+ WWWUSER: '${WWWUSER}'
+ LARAVEL_SAIL: 1
+ XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
+ XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
+ IGNITION_LOCAL_SITES_PATH: '${PWD}'
+ volumes:
+ - '.:/var/www/html'
+ networks:
+ - sail
+ depends_on:
+ - pgsql
+ - redis
+ pgsql:
+ image: 'postgres:15'
+ ports:
+ - '${FORWARD_DB_PORT:-5432}:5432'
+ environment:
+ PGPASSWORD: '${DB_PASSWORD:-secret}'
+ POSTGRES_DB: '${DB_DATABASE}'
+ POSTGRES_USER: '${DB_USERNAME}'
+ POSTGRES_PASSWORD: '${DB_PASSWORD:-secret}'
+ volumes:
+ - 'sail-pgsql:/var/lib/postgresql/data'
+ - './docker/pgsql/create-testing-database.sql:/docker-entrypoint-initdb.d/10-create-testing-database.sql'
+ networks:
+ - sail
+ healthcheck:
+ test:
+ - CMD
+ - pg_isready
+ - '-q'
+ - '-d'
+ - '${DB_DATABASE}'
+ - '-U'
+ - '${DB_USERNAME}'
+ retries: 3
+ timeout: 5s
+ redis:
+ image: 'redis:alpine'
+ ports:
+ - '${FORWARD_REDIS_PORT:-6379}:6379'
+ volumes:
+ - 'sail-redis:/data'
+ networks:
+ - sail
+ healthcheck:
+ test:
+ - CMD
+ - redis-cli
+ - ping
+ retries: 3
+ timeout: 5s
+networks:
+ sail:
+ driver: bridge
+volumes:
+ sail-pgsql:
+ driver: local
+ sail-redis:
+ driver: local
diff --git a/docker/8.3/Dockerfile b/docker/8.3/Dockerfile
new file mode 100644
index 0000000..ca0b0e7
--- /dev/null
+++ b/docker/8.3/Dockerfile
@@ -0,0 +1,67 @@
+FROM ubuntu:22.04
+
+LABEL maintainer="Taylor Otwell"
+
+ARG WWWGROUP
+ARG NODE_VERSION=20
+ARG MYSQL_CLIENT="mysql-client"
+ARG POSTGRES_VERSION=15
+
+WORKDIR /var/www/html
+
+ENV DEBIAN_FRONTEND noninteractive
+ENV TZ=UTC
+ENV SUPERVISOR_PHP_COMMAND="/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80"
+ENV SUPERVISOR_PHP_USER="sail"
+
+RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
+
+RUN apt-get update \
+ && mkdir -p /etc/apt/keyrings \
+ && apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python2 dnsutils librsvg2-bin fswatch ffmpeg nano \
+ && curl -sS 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x14aa40ec0831756756d7f66c4f4ea0aae5267a6c' | gpg --dearmor | tee /etc/apt/keyrings/ppa_ondrej_php.gpg > /dev/null \
+ && echo "deb [signed-by=/etc/apt/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu jammy main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \
+ && apt-get update \
+ && apt-get install -y php8.3-cli php8.3-dev \
+ php8.3-pgsql php8.3-sqlite3 php8.3-gd \
+ php8.3-curl \
+ php8.3-imap php8.3-mysql php8.3-mbstring \
+ php8.3-xml php8.3-zip php8.3-bcmath php8.3-soap \
+ php8.3-intl php8.3-readline \
+ php8.3-ldap \
+ php8.3-gmp \
+ php8.3-msgpack php8.3-igbinary php8.3-redis php8.3-swoole \
+ php8.3-memcached php8.3-pcov php8.3-imagick php8.3-xdebug \
+ && curl -sLS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer \
+ && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
+ && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_VERSION.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \
+ && apt-get update \
+ && apt-get install -y nodejs \
+ && npm install -g npm \
+ && npm install -g pnpm \
+ && npm install -g bun \
+ && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /etc/apt/keyrings/yarn.gpg >/dev/null \
+ && echo "deb [signed-by=/etc/apt/keyrings/yarn.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \
+ && curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /etc/apt/keyrings/pgdg.gpg >/dev/null \
+ && echo "deb [signed-by=/etc/apt/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt jammy-pgdg main" > /etc/apt/sources.list.d/pgdg.list \
+ && apt-get update \
+ && apt-get install -y yarn \
+ && apt-get install -y $MYSQL_CLIENT \
+ && apt-get install -y postgresql-client-$POSTGRES_VERSION \
+ && apt-get -y autoremove \
+ && apt-get clean \
+ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
+
+RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.3
+
+RUN groupadd --force -g $WWWGROUP sail
+RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail
+
+COPY start-container /usr/local/bin/start-container
+COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
+COPY php.ini /etc/php/8.3/cli/conf.d/99-sail.ini
+RUN chmod +x /usr/local/bin/start-container
+
+EXPOSE 80/tcp
+
+ENTRYPOINT ["start-container"]
diff --git a/docker/8.3/php.ini b/docker/8.3/php.ini
new file mode 100644
index 0000000..0d8ce9e
--- /dev/null
+++ b/docker/8.3/php.ini
@@ -0,0 +1,5 @@
+[PHP]
+post_max_size = 100M
+upload_max_filesize = 100M
+variables_order = EGPCS
+pcov.directory = .
diff --git a/docker/8.3/start-container b/docker/8.3/start-container
new file mode 100644
index 0000000..40c55df
--- /dev/null
+++ b/docker/8.3/start-container
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+
+if [ "$SUPERVISOR_PHP_USER" != "root" ] && [ "$SUPERVISOR_PHP_USER" != "sail" ]; then
+ echo "You should set SUPERVISOR_PHP_USER to either 'sail' or 'root'."
+ exit 1
+fi
+
+if [ ! -z "$WWWUSER" ]; then
+ usermod -u $WWWUSER sail
+fi
+
+if [ ! -d /.composer ]; then
+ mkdir /.composer
+fi
+
+chmod -R ugo+rw /.composer
+
+if [ $# -gt 0 ]; then
+ if [ "$SUPERVISOR_PHP_USER" = "root" ]; then
+ exec "$@"
+ else
+ exec gosu $WWWUSER "$@"
+ fi
+else
+ exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
+fi
diff --git a/docker/8.3/supervisord.conf b/docker/8.3/supervisord.conf
new file mode 100644
index 0000000..93d0ae9
--- /dev/null
+++ b/docker/8.3/supervisord.conf
@@ -0,0 +1,22 @@
+[supervisord]
+nodaemon=true
+user=root
+logfile=/var/log/supervisor/supervisord.log
+pidfile=/var/run/supervisord.pid
+
+[program:php]
+command=%(ENV_SUPERVISOR_PHP_COMMAND)s
+user=%(ENV_SUPERVISOR_PHP_USER)s
+environment=LARAVEL_SAIL="1"
+stdout_logfile=/dev/stdout
+stdout_logfile_maxbytes=0
+stderr_logfile=/dev/stderr
+stderr_logfile_maxbytes=0
+
+[program:reverb]
+command=php /var/www/html/artisan reverb:start --host="0.0.0.0" --port=8080
+autostart=true
+autorestart=true
+user=%(ENV_SUPERVISOR_PHP_USER)s
+redirect_stderr=true
+stdout_logfile=/var/www/html/storage/logs/reverb.log
diff --git a/docker/pgsql/create-testing-database.sql b/docker/pgsql/create-testing-database.sql
new file mode 100644
index 0000000..d84dc07
--- /dev/null
+++ b/docker/pgsql/create-testing-database.sql
@@ -0,0 +1,2 @@
+SELECT 'CREATE DATABASE testing'
+WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'testing')\gexec
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..b3a8764
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,2601 @@
+{
+ "name": "html",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "devDependencies": {
+ "autoprefixer": "^10.4.20",
+ "axios": "^1.6.4",
+ "laravel-echo": "^1.16.1",
+ "laravel-vite-plugin": "^1.0",
+ "postcss": "^8.4.41",
+ "pusher-js": "^8.4.0-rc2",
+ "tailwindcss": "^3.4.10",
+ "vite": "^5.0"
+ }
+ },
+ "node_modules/@alloc/quick-lru": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
+ "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
+ "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
+ "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
+ "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
+ "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
+ "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
+ "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
+ "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
+ "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
+ "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
+ "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
+ "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
+ "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
+ "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
+ "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
+ "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
+ "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
+ "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
+ "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
+ "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@isaacs/cliui": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
+ "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/set-array": "^1.2.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+ "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.25",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.21.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.1.tgz",
+ "integrity": "sha512-2thheikVEuU7ZxFXubPDOtspKn1x0yqaYQwvALVtEcvFhMifPADBrgRPyHV0TF3b+9BgvgjgagVyvA/UqPZHmg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.21.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.1.tgz",
+ "integrity": "sha512-t1lLYn4V9WgnIFHXy1d2Di/7gyzBWS8G5pQSXdZqfrdCGTwi1VasRMSS81DTYb+avDs/Zz4A6dzERki5oRYz1g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.21.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.1.tgz",
+ "integrity": "sha512-AH/wNWSEEHvs6t4iJ3RANxW5ZCK3fUnmf0gyMxWCesY1AlUj8jY7GC+rQE4wd3gwmZ9XDOpL0kcFnCjtN7FXlA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.21.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.1.tgz",
+ "integrity": "sha512-dO0BIz/+5ZdkLZrVgQrDdW7m2RkrLwYTh2YMFG9IpBtlC1x1NPNSXkfczhZieOlOLEqgXOFH3wYHB7PmBtf+Bg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.21.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.1.tgz",
+ "integrity": "sha512-sWWgdQ1fq+XKrlda8PsMCfut8caFwZBmhYeoehJ05FdI0YZXk6ZyUjWLrIgbR/VgiGycrFKMMgp7eJ69HOF2pQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.21.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.1.tgz",
+ "integrity": "sha512-9OIiSuj5EsYQlmwhmFRA0LRO0dRRjdCVZA3hnmZe1rEwRk11Jy3ECGGq3a7RrVEZ0/pCsYWx8jG3IvcrJ6RCew==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.21.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.1.tgz",
+ "integrity": "sha512-0kuAkRK4MeIUbzQYu63NrJmfoUVicajoRAL1bpwdYIYRcs57iyIV9NLcuyDyDXE2GiZCL4uhKSYAnyWpjZkWow==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.21.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.1.tgz",
+ "integrity": "sha512-/6dYC9fZtfEY0vozpc5bx1RP4VrtEOhNQGb0HwvYNwXD1BBbwQ5cKIbUVVU7G2d5WRE90NfB922elN8ASXAJEA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
+ "version": "4.21.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.1.tgz",
+ "integrity": "sha512-ltUWy+sHeAh3YZ91NUsV4Xg3uBXAlscQe8ZOXRCVAKLsivGuJsrkawYPUEyCV3DYa9urgJugMLn8Z3Z/6CeyRQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.21.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.1.tgz",
+ "integrity": "sha512-BggMndzI7Tlv4/abrgLwa/dxNEMn2gC61DCLrTzw8LkpSKel4o+O+gtjbnkevZ18SKkeN3ihRGPuBxjaetWzWg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.21.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.1.tgz",
+ "integrity": "sha512-z/9rtlGd/OMv+gb1mNSjElasMf9yXusAxnRDrBaYB+eS1shFm6/4/xDH1SAISO5729fFKUkJ88TkGPRUh8WSAA==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.21.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.1.tgz",
+ "integrity": "sha512-kXQVcWqDcDKw0S2E0TmhlTLlUgAmMVqPrJZR+KpH/1ZaZhLSl23GZpQVmawBQGVhyP5WXIsIQ/zqbDBBYmxm5w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.21.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.1.tgz",
+ "integrity": "sha512-CbFv/WMQsSdl+bpX6rVbzR4kAjSSBuDgCqb1l4J68UYsQNalz5wOqLGYj4ZI0thGpyX5kc+LLZ9CL+kpqDovZA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.21.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.1.tgz",
+ "integrity": "sha512-3Q3brDgA86gHXWHklrwdREKIrIbxC0ZgU8lwpj0eEKGBQH+31uPqr0P2v11pn0tSIxHvcdOWxa4j+YvLNx1i6g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.21.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.1.tgz",
+ "integrity": "sha512-tNg+jJcKR3Uwe4L0/wY3Ro0H+u3nrb04+tcq1GSYzBEmKLeOQF2emk1whxlzNqb6MMrQ2JOcQEpuuiPLyRcSIw==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.21.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.1.tgz",
+ "integrity": "sha512-xGiIH95H1zU7naUyTKEyOA/I0aexNMUdO9qRv0bLKN3qu25bBdrxZHqA3PTJ24YNN/GdMzG4xkDcd/GvjuhfLg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
+ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ansi-regex": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+ "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/any-promise": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/arg": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
+ "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/autoprefixer": {
+ "version": "10.4.20",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz",
+ "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/autoprefixer"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.23.3",
+ "caniuse-lite": "^1.0.30001646",
+ "fraction.js": "^4.3.7",
+ "normalize-range": "^0.1.2",
+ "picocolors": "^1.0.1",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "bin": {
+ "autoprefixer": "bin/autoprefixer"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/axios": {
+ "version": "1.7.5",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.5.tgz",
+ "integrity": "sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "follow-redirects": "^1.15.6",
+ "form-data": "^4.0.0",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.23.3",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz",
+ "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001646",
+ "electron-to-chromium": "^1.5.4",
+ "node-releases": "^2.0.18",
+ "update-browserslist-db": "^1.1.0"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/camelcase-css": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
+ "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001653",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001653.tgz",
+ "integrity": "sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/chokidar/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/commander": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/didyoumean": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
+ "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/dlv": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
+ "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.13",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz",
+ "integrity": "sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/esbuild": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
+ "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.21.5",
+ "@esbuild/android-arm": "0.21.5",
+ "@esbuild/android-arm64": "0.21.5",
+ "@esbuild/android-x64": "0.21.5",
+ "@esbuild/darwin-arm64": "0.21.5",
+ "@esbuild/darwin-x64": "0.21.5",
+ "@esbuild/freebsd-arm64": "0.21.5",
+ "@esbuild/freebsd-x64": "0.21.5",
+ "@esbuild/linux-arm": "0.21.5",
+ "@esbuild/linux-arm64": "0.21.5",
+ "@esbuild/linux-ia32": "0.21.5",
+ "@esbuild/linux-loong64": "0.21.5",
+ "@esbuild/linux-mips64el": "0.21.5",
+ "@esbuild/linux-ppc64": "0.21.5",
+ "@esbuild/linux-riscv64": "0.21.5",
+ "@esbuild/linux-s390x": "0.21.5",
+ "@esbuild/linux-x64": "0.21.5",
+ "@esbuild/netbsd-x64": "0.21.5",
+ "@esbuild/openbsd-x64": "0.21.5",
+ "@esbuild/sunos-x64": "0.21.5",
+ "@esbuild/win32-arm64": "0.21.5",
+ "@esbuild/win32-ia32": "0.21.5",
+ "@esbuild/win32-x64": "0.21.5"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
+ "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
+ "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fastq": {
+ "version": "1.17.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
+ "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.15.6",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
+ "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/foreground-child": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
+ "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "cross-spawn": "^7.0.0",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+ "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fraction.js": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
+ "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "type": "patreon",
+ "url": "https://github.com/sponsors/rawify"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/glob": {
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.15.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz",
+ "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/jackspeak": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
+ "node_modules/jiti": {
+ "version": "1.21.6",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz",
+ "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jiti": "bin/jiti.js"
+ }
+ },
+ "node_modules/laravel-echo": {
+ "version": "1.16.1",
+ "resolved": "https://registry.npmjs.org/laravel-echo/-/laravel-echo-1.16.1.tgz",
+ "integrity": "sha512-++Ylb6M3ariC9Rk5WE5gZjj6wcEV5kvLF8b+geJ5/rRIfdoOA+eG6b9qJPrarMD9rY28Apx+l3eelIrCc2skVg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/laravel-vite-plugin": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/laravel-vite-plugin/-/laravel-vite-plugin-1.0.5.tgz",
+ "integrity": "sha512-Zv+to82YLBknDCZ6g3iwOv9wZ7f6EWStb9pjSm7MGe9Mfoy5ynT2ssZbGsMr1udU6rDg9HOoYEVGw5Qf+p9zbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "picocolors": "^1.0.0",
+ "vite-plugin-full-reload": "^1.1.0"
+ },
+ "bin": {
+ "clean-orphaned-assets": "bin/clean.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^5.0.0"
+ }
+ },
+ "node_modules/lilconfig": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
+ "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/mz": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
+ "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "any-promise": "^1.0.0",
+ "object-assign": "^4.0.1",
+ "thenify-all": "^1.0.0"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.7",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
+ "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.18",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
+ "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/normalize-range": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+ "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-hash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
+ "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/package-json-from-dist": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz",
+ "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0"
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/path-scurry": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
+ "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/pirates": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
+ "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.4.41",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz",
+ "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.7",
+ "picocolors": "^1.0.1",
+ "source-map-js": "^1.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/postcss-import": {
+ "version": "15.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
+ "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.0.0",
+ "read-cache": "^1.0.0",
+ "resolve": "^1.1.7"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.0.0"
+ }
+ },
+ "node_modules/postcss-js": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
+ "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "camelcase-css": "^2.0.1"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >= 16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4.21"
+ }
+ },
+ "node_modules/postcss-load-config": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
+ "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "lilconfig": "^3.0.0",
+ "yaml": "^2.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ },
+ "peerDependencies": {
+ "postcss": ">=8.0.9",
+ "ts-node": ">=9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "postcss": {
+ "optional": true
+ },
+ "ts-node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/postcss-load-config/node_modules/lilconfig": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz",
+ "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antonk52"
+ }
+ },
+ "node_modules/postcss-nested": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
+ "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "postcss-selector-parser": "^6.1.1"
+ },
+ "engines": {
+ "node": ">=12.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.14"
+ }
+ },
+ "node_modules/postcss-selector-parser": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
+ "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-value-parser": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/pusher-js": {
+ "version": "8.4.0-rc2",
+ "resolved": "https://registry.npmjs.org/pusher-js/-/pusher-js-8.4.0-rc2.tgz",
+ "integrity": "sha512-d87GjOEEl9QgO5BWmViSqW0LOzPvybvX6WA9zLUstNdB57jVJuR27zHkRnrav2a3+zAMlHbP2Og8wug+rG8T+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tweetnacl": "^1.0.3"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/read-cache": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
+ "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pify": "^2.3.0"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.8",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
+ "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-core-module": "^2.13.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "4.21.1",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.1.tgz",
+ "integrity": "sha512-ZnYyKvscThhgd3M5+Qt3pmhO4jIRR5RGzaSovB6Q7rGNrK5cUncrtLmcTTJVSdcKXyZjW8X8MB0JMSuH9bcAJg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.5"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.21.1",
+ "@rollup/rollup-android-arm64": "4.21.1",
+ "@rollup/rollup-darwin-arm64": "4.21.1",
+ "@rollup/rollup-darwin-x64": "4.21.1",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.21.1",
+ "@rollup/rollup-linux-arm-musleabihf": "4.21.1",
+ "@rollup/rollup-linux-arm64-gnu": "4.21.1",
+ "@rollup/rollup-linux-arm64-musl": "4.21.1",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.21.1",
+ "@rollup/rollup-linux-riscv64-gnu": "4.21.1",
+ "@rollup/rollup-linux-s390x-gnu": "4.21.1",
+ "@rollup/rollup-linux-x64-gnu": "4.21.1",
+ "@rollup/rollup-linux-x64-musl": "4.21.1",
+ "@rollup/rollup-win32-arm64-msvc": "4.21.1",
+ "@rollup/rollup-win32-ia32-msvc": "4.21.1",
+ "@rollup/rollup-win32-x64-msvc": "4.21.1",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
+ "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/string-width-cjs": {
+ "name": "string-width",
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/string-width-cjs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/strip-ansi-cjs": {
+ "name": "strip-ansi",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/sucrase": {
+ "version": "3.35.0",
+ "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
+ "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "commander": "^4.0.0",
+ "glob": "^10.3.10",
+ "lines-and-columns": "^1.1.6",
+ "mz": "^2.7.0",
+ "pirates": "^4.0.1",
+ "ts-interface-checker": "^0.1.9"
+ },
+ "bin": {
+ "sucrase": "bin/sucrase",
+ "sucrase-node": "bin/sucrase-node"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/tailwindcss": {
+ "version": "3.4.10",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.10.tgz",
+ "integrity": "sha512-KWZkVPm7yJRhdu4SRSl9d4AK2wM3a50UsvgHZO7xY77NQr2V+fIrEuoDGQcbvswWvFGbS2f6e+jC/6WJm1Dl0w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@alloc/quick-lru": "^5.2.0",
+ "arg": "^5.0.2",
+ "chokidar": "^3.5.3",
+ "didyoumean": "^1.2.2",
+ "dlv": "^1.1.3",
+ "fast-glob": "^3.3.0",
+ "glob-parent": "^6.0.2",
+ "is-glob": "^4.0.3",
+ "jiti": "^1.21.0",
+ "lilconfig": "^2.1.0",
+ "micromatch": "^4.0.5",
+ "normalize-path": "^3.0.0",
+ "object-hash": "^3.0.0",
+ "picocolors": "^1.0.0",
+ "postcss": "^8.4.23",
+ "postcss-import": "^15.1.0",
+ "postcss-js": "^4.0.1",
+ "postcss-load-config": "^4.0.1",
+ "postcss-nested": "^6.0.1",
+ "postcss-selector-parser": "^6.0.11",
+ "resolve": "^1.22.2",
+ "sucrase": "^3.32.0"
+ },
+ "bin": {
+ "tailwind": "lib/cli.js",
+ "tailwindcss": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/thenify": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
+ "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "any-promise": "^1.0.0"
+ }
+ },
+ "node_modules/thenify-all": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
+ "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "thenify": ">= 3.1.0 < 4"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/ts-interface-checker": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
+ "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/tweetnacl": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz",
+ "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==",
+ "dev": true,
+ "license": "Unlicense"
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz",
+ "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.1.2",
+ "picocolors": "^1.0.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/vite": {
+ "version": "5.4.2",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.2.tgz",
+ "integrity": "sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.21.3",
+ "postcss": "^8.4.41",
+ "rollup": "^4.20.0"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || >=20.0.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "sass-embedded": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.4.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite-plugin-full-reload": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/vite-plugin-full-reload/-/vite-plugin-full-reload-1.2.0.tgz",
+ "integrity": "sha512-kz18NW79x0IHbxRSHm0jttP4zoO9P9gXh+n6UTwlNKnviTTEpOlum6oS9SmecrTtSr+muHEn5TUuC75UovQzcA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "picocolors": "^1.0.0",
+ "picomatch": "^2.3.1"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/wrap-ansi": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs": {
+ "name": "wrap-ansi",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yaml": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz",
+ "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "yaml": "bin.mjs"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
index 4e934ca..b1fe2ef 100644
--- a/package.json
+++ b/package.json
@@ -6,8 +6,14 @@
"build": "vite build"
},
"devDependencies": {
+ "autoprefixer": "^10.4.20",
"axios": "^1.6.4",
+ "flatpickr": "^4.6.13",
+ "laravel-echo": "^1.16.1",
"laravel-vite-plugin": "^1.0",
+ "postcss": "^8.4.41",
+ "pusher-js": "^8.4.0-rc2",
+ "tailwindcss": "^3.4.10",
"vite": "^5.0"
}
}
diff --git a/phpunit.xml b/phpunit.xml
index 506b9a3..c09b5bc 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -22,8 +22,7 @@
-
-
+
diff --git a/postcss.config.js b/postcss.config.js
new file mode 100644
index 0000000..2e7af2b
--- /dev/null
+++ b/postcss.config.js
@@ -0,0 +1,6 @@
+export default {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+}
diff --git a/public/dist/einundzwanzig.chat.css b/public/dist/einundzwanzig.chat.css
new file mode 100644
index 0000000..cefccb7
--- /dev/null
+++ b/public/dist/einundzwanzig.chat.css
@@ -0,0 +1,1568 @@
+.qr.svelte-2fcki1.svelte-2fcki1 {
+ display: block;
+ shape-rendering: crispEdges;
+ transform: translateZ(0)
+}
+
+.qr.svelte-2fcki1 rect.svelte-2fcki1 {
+ fill: var(--qr-color, 'currentColor')
+}
+
+.svelte-8015tc, .svelte-8015tc::before, .svelte-8015tc::after {
+ box-sizing: border-box;
+ border-width: 0;
+ border-style: solid;
+ border-color: #e5e7eb
+}
+
+.svelte-8015tc::before, .svelte-8015tc::after {
+ --tw-content: ''
+}
+
+h1.svelte-8015tc {
+ font-size: inherit;
+ font-weight: inherit
+}
+
+button.svelte-8015tc {
+ font-family: inherit;
+ font-size: 100%;
+ font-weight: inherit;
+ line-height: inherit;
+ color: inherit;
+ margin: 0;
+ padding: 0
+}
+
+button.svelte-8015tc {
+ text-transform: none
+}
+
+button.svelte-8015tc {
+ -webkit-appearance: button;
+ background-color: transparent;
+ background-image: none
+}
+
+.svelte-8015tc:-moz-focusring {
+ outline: auto
+}
+
+.svelte-8015tc:-moz-ui-invalid {
+ box-shadow: none
+}
+
+.svelte-8015tc::-webkit-inner-spin-button, .svelte-8015tc::-webkit-outer-spin-button {
+ height: auto
+}
+
+.svelte-8015tc::-webkit-search-decoration {
+ -webkit-appearance: none
+}
+
+.svelte-8015tc::-webkit-file-upload-button {
+ -webkit-appearance: button;
+ font: inherit
+}
+
+h1.svelte-8015tc, p.svelte-8015tc {
+ margin: 0
+}
+
+button.svelte-8015tc {
+ cursor: pointer
+}
+
+.svelte-8015tc:disabled {
+ cursor: default
+}
+
+.svelte-8015tc, .svelte-8015tc::before, .svelte-8015tc::after {
+ --tw-border-spacing-x: 0;
+ --tw-border-spacing-y: 0;
+ --tw-translate-x: 0;
+ --tw-translate-y: 0;
+ --tw-rotate: 0;
+ --tw-skew-x: 0;
+ --tw-skew-y: 0;
+ --tw-scale-x: 1;
+ --tw-scale-y: 1;
+ --tw-pan-x: ;
+ --tw-pan-y: ;
+ --tw-pinch-zoom: ;
+ --tw-scroll-snap-strictness: proximity;
+ --tw-ordinal: ;
+ --tw-slashed-zero: ;
+ --tw-numeric-figure: ;
+ --tw-numeric-spacing: ;
+ --tw-numeric-fraction: ;
+ --tw-ring-inset: ;
+ --tw-ring-offset-width: 0px;
+ --tw-ring-offset-color: #fff;
+ --tw-ring-color: rgb(59 130 246 / 0.5);
+ --tw-ring-offset-shadow: 0 0 #0000;
+ --tw-ring-shadow: 0 0 #0000;
+ --tw-shadow: 0 0 #0000;
+ --tw-shadow-colored: 0 0 #0000;
+ --tw-blur: ;
+ --tw-brightness: ;
+ --tw-contrast: ;
+ --tw-grayscale: ;
+ --tw-hue-rotate: ;
+ --tw-invert: ;
+ --tw-saturate: ;
+ --tw-sepia: ;
+ --tw-drop-shadow: ;
+ --tw-backdrop-blur: ;
+ --tw-backdrop-brightness: ;
+ --tw-backdrop-contrast: ;
+ --tw-backdrop-grayscale: ;
+ --tw-backdrop-hue-rotate: ;
+ --tw-backdrop-invert: ;
+ --tw-backdrop-opacity: ;
+ --tw-backdrop-saturate: ;
+ --tw-backdrop-sepia:
+}
+
+.svelte-8015tc::backdrop {
+ --tw-border-spacing-x: 0;
+ --tw-border-spacing-y: 0;
+ --tw-translate-x: 0;
+ --tw-translate-y: 0;
+ --tw-rotate: 0;
+ --tw-skew-x: 0;
+ --tw-skew-y: 0;
+ --tw-scale-x: 1;
+ --tw-scale-y: 1;
+ --tw-pan-x: ;
+ --tw-pan-y: ;
+ --tw-pinch-zoom: ;
+ --tw-scroll-snap-strictness: proximity;
+ --tw-ordinal: ;
+ --tw-slashed-zero: ;
+ --tw-numeric-figure: ;
+ --tw-numeric-spacing: ;
+ --tw-numeric-fraction: ;
+ --tw-ring-inset: ;
+ --tw-ring-offset-width: 0px;
+ --tw-ring-offset-color: #fff;
+ --tw-ring-color: rgb(59 130 246 / 0.5);
+ --tw-ring-offset-shadow: 0 0 #0000;
+ --tw-ring-shadow: 0 0 #0000;
+ --tw-shadow: 0 0 #0000;
+ --tw-shadow-colored: 0 0 #0000;
+ --tw-blur: ;
+ --tw-brightness: ;
+ --tw-contrast: ;
+ --tw-grayscale: ;
+ --tw-hue-rotate: ;
+ --tw-invert: ;
+ --tw-saturate: ;
+ --tw-sepia: ;
+ --tw-drop-shadow: ;
+ --tw-backdrop-blur: ;
+ --tw-backdrop-brightness: ;
+ --tw-backdrop-contrast: ;
+ --tw-backdrop-grayscale: ;
+ --tw-backdrop-hue-rotate: ;
+ --tw-backdrop-invert: ;
+ --tw-backdrop-opacity: ;
+ --tw-backdrop-saturate: ;
+ --tw-backdrop-sepia:
+}
+
+@media (min-width: 640px) {
+}
+
+@media (min-width: 768px) {
+}
+
+@media (min-width: 1024px) {
+}
+
+@media (min-width: 1280px) {
+}
+
+@media (min-width: 1536px) {
+}
+
+.mb-3.svelte-8015tc {
+ margin-bottom: 0.75rem
+}
+
+.flex.svelte-8015tc {
+ display: flex
+}
+
+.w-full.svelte-8015tc {
+ width: 100%
+}
+
+.flex-col.svelte-8015tc {
+ flex-direction: column
+}
+
+.gap-1.svelte-8015tc {
+ gap: 0.25rem
+}
+
+.rounded-xl.svelte-8015tc {
+ border-radius: 0.75rem
+}
+
+.bg-white.svelte-8015tc {
+ --tw-bg-opacity: 1;
+ background-color: rgb(255 255 255 / var(--tw-bg-opacity))
+}
+
+.bg-purple-900.svelte-8015tc {
+ --tw-bg-opacity: 1;
+ background-color: rgb(88 28 135 / var(--tw-bg-opacity))
+}
+
+.p-2.svelte-8015tc {
+ padding: 0.5rem
+}
+
+.p-3.svelte-8015tc {
+ padding: 0.75rem
+}
+
+.p-4.svelte-8015tc {
+ padding: 1rem
+}
+
+.text-center.svelte-8015tc {
+ text-align: center
+}
+
+.text-xs.svelte-8015tc {
+ font-size: 0.75rem;
+ line-height: 1rem
+}
+
+.text-xl.svelte-8015tc {
+ font-size: 1.25rem;
+ line-height: 1.75rem
+}
+
+.font-bold.svelte-8015tc {
+ font-weight: 700
+}
+
+.text-gray-600.svelte-8015tc {
+ --tw-text-opacity: 1;
+ color: rgb(75 85 99 / var(--tw-text-opacity))
+}
+
+.text-white.svelte-8015tc {
+ --tw-text-opacity: 1;
+ color: rgb(255 255 255 / var(--tw-text-opacity))
+}
+
+.text-gray-400.svelte-8015tc {
+ --tw-text-opacity: 1;
+ color: rgb(156 163 175 / var(--tw-text-opacity))
+}
+
+.text-gray-200.svelte-8015tc {
+ --tw-text-opacity: 1;
+ color: rgb(229 231 235 / var(--tw-text-opacity))
+}
+
+.text-gray-300.svelte-8015tc {
+ --tw-text-opacity: 1;
+ color: rgb(209 213 219 / var(--tw-text-opacity))
+}
+
+.hover\:bg-purple-700.svelte-8015tc:hover {
+ --tw-bg-opacity: 1;
+ background-color: rgb(126 34 206 / var(--tw-bg-opacity))
+}
+
+@media (prefers-color-scheme: dark) {
+}
+
+@media (min-width: 768px) {
+}
+
+@media (min-width: 1024px) {
+}
+
+@media (min-width: 1280px) {
+}
+
+.svelte-r5bhj7, .svelte-r5bhj7::before, .svelte-r5bhj7::after {
+ box-sizing: border-box;
+ border-width: 0;
+ border-style: solid;
+ border-color: #e5e7eb
+}
+
+.svelte-r5bhj7::before, .svelte-r5bhj7::after {
+ --tw-content: ''
+}
+
+.svelte-r5bhj7:-moz-focusring {
+ outline: auto
+}
+
+.svelte-r5bhj7:-moz-ui-invalid {
+ box-shadow: none
+}
+
+.svelte-r5bhj7::-webkit-inner-spin-button, .svelte-r5bhj7::-webkit-outer-spin-button {
+ height: auto
+}
+
+.svelte-r5bhj7::-webkit-search-decoration {
+ -webkit-appearance: none
+}
+
+.svelte-r5bhj7::-webkit-file-upload-button {
+ -webkit-appearance: button;
+ font: inherit
+}
+
+.svelte-r5bhj7:disabled {
+ cursor: default
+}
+
+img.svelte-r5bhj7 {
+ display: block;
+ vertical-align: middle
+}
+
+img.svelte-r5bhj7 {
+ max-width: 100%;
+ height: auto
+}
+
+.svelte-r5bhj7, .svelte-r5bhj7::before, .svelte-r5bhj7::after {
+ --tw-border-spacing-x: 0;
+ --tw-border-spacing-y: 0;
+ --tw-translate-x: 0;
+ --tw-translate-y: 0;
+ --tw-rotate: 0;
+ --tw-skew-x: 0;
+ --tw-skew-y: 0;
+ --tw-scale-x: 1;
+ --tw-scale-y: 1;
+ --tw-pan-x: ;
+ --tw-pan-y: ;
+ --tw-pinch-zoom: ;
+ --tw-scroll-snap-strictness: proximity;
+ --tw-ordinal: ;
+ --tw-slashed-zero: ;
+ --tw-numeric-figure: ;
+ --tw-numeric-spacing: ;
+ --tw-numeric-fraction: ;
+ --tw-ring-inset: ;
+ --tw-ring-offset-width: 0px;
+ --tw-ring-offset-color: #fff;
+ --tw-ring-color: rgb(59 130 246 / 0.5);
+ --tw-ring-offset-shadow: 0 0 #0000;
+ --tw-ring-shadow: 0 0 #0000;
+ --tw-shadow: 0 0 #0000;
+ --tw-shadow-colored: 0 0 #0000;
+ --tw-blur: ;
+ --tw-brightness: ;
+ --tw-contrast: ;
+ --tw-grayscale: ;
+ --tw-hue-rotate: ;
+ --tw-invert: ;
+ --tw-saturate: ;
+ --tw-sepia: ;
+ --tw-drop-shadow: ;
+ --tw-backdrop-blur: ;
+ --tw-backdrop-brightness: ;
+ --tw-backdrop-contrast: ;
+ --tw-backdrop-grayscale: ;
+ --tw-backdrop-hue-rotate: ;
+ --tw-backdrop-invert: ;
+ --tw-backdrop-opacity: ;
+ --tw-backdrop-saturate: ;
+ --tw-backdrop-sepia:
+}
+
+.svelte-r5bhj7::backdrop {
+ --tw-border-spacing-x: 0;
+ --tw-border-spacing-y: 0;
+ --tw-translate-x: 0;
+ --tw-translate-y: 0;
+ --tw-rotate: 0;
+ --tw-skew-x: 0;
+ --tw-skew-y: 0;
+ --tw-scale-x: 1;
+ --tw-scale-y: 1;
+ --tw-pan-x: ;
+ --tw-pan-y: ;
+ --tw-pinch-zoom: ;
+ --tw-scroll-snap-strictness: proximity;
+ --tw-ordinal: ;
+ --tw-slashed-zero: ;
+ --tw-numeric-figure: ;
+ --tw-numeric-spacing: ;
+ --tw-numeric-fraction: ;
+ --tw-ring-inset: ;
+ --tw-ring-offset-width: 0px;
+ --tw-ring-offset-color: #fff;
+ --tw-ring-color: rgb(59 130 246 / 0.5);
+ --tw-ring-offset-shadow: 0 0 #0000;
+ --tw-ring-shadow: 0 0 #0000;
+ --tw-shadow: 0 0 #0000;
+ --tw-shadow-colored: 0 0 #0000;
+ --tw-blur: ;
+ --tw-brightness: ;
+ --tw-contrast: ;
+ --tw-grayscale: ;
+ --tw-hue-rotate: ;
+ --tw-invert: ;
+ --tw-saturate: ;
+ --tw-sepia: ;
+ --tw-drop-shadow: ;
+ --tw-backdrop-blur: ;
+ --tw-backdrop-brightness: ;
+ --tw-backdrop-contrast: ;
+ --tw-backdrop-grayscale: ;
+ --tw-backdrop-hue-rotate: ;
+ --tw-backdrop-invert: ;
+ --tw-backdrop-opacity: ;
+ --tw-backdrop-saturate: ;
+ --tw-backdrop-sepia:
+}
+
+@media (min-width: 640px) {
+}
+
+@media (min-width: 768px) {
+}
+
+@media (min-width: 1024px) {
+}
+
+@media (min-width: 1280px) {
+}
+
+@media (min-width: 1536px) {
+}
+
+.mb-3.svelte-r5bhj7 {
+ margin-bottom: 0.75rem
+}
+
+.mt-1.svelte-r5bhj7 {
+ margin-top: 0.25rem
+}
+
+.mb-10.svelte-r5bhj7 {
+ margin-bottom: 2.5rem
+}
+
+.block.svelte-r5bhj7 {
+ display: block
+}
+
+.flex.svelte-r5bhj7 {
+ display: flex
+}
+
+.h-10.svelte-r5bhj7 {
+ height: 2.5rem
+}
+
+.max-h-64.svelte-r5bhj7 {
+ max-height: 16rem
+}
+
+.w-full.svelte-r5bhj7 {
+ width: 100%
+}
+
+.w-10.svelte-r5bhj7 {
+ width: 2.5rem
+}
+
+.min-w-fit.svelte-r5bhj7 {
+ min-width: -moz-fit-content;
+ min-width: fit-content
+}
+
+.cursor-pointer.svelte-r5bhj7 {
+ cursor: pointer
+}
+
+.flex-row.svelte-r5bhj7 {
+ flex-direction: row
+}
+
+.flex-row-reverse.svelte-r5bhj7 {
+ flex-direction: row-reverse
+}
+
+.items-center.svelte-r5bhj7 {
+ align-items: center
+}
+
+.justify-between.svelte-r5bhj7 {
+ justify-content: space-between
+}
+
+.gap-4.svelte-r5bhj7 {
+ gap: 1rem
+}
+
+.overflow-hidden.svelte-r5bhj7 {
+ overflow: hidden
+}
+
+.overflow-clip.svelte-r5bhj7 {
+ overflow: clip
+}
+
+.overflow-scroll.svelte-r5bhj7 {
+ overflow: scroll
+}
+
+.text-ellipsis.svelte-r5bhj7 {
+ text-overflow: ellipsis
+}
+
+.text-clip.svelte-r5bhj7 {
+ text-overflow: clip
+}
+
+.whitespace-nowrap.svelte-r5bhj7 {
+ white-space: nowrap
+}
+
+.rounded-full.svelte-r5bhj7 {
+ border-radius: 9999px
+}
+
+.rounded-2xl.svelte-r5bhj7 {
+ border-radius: 1rem
+}
+
+.border.svelte-r5bhj7 {
+ border-width: 1px
+}
+
+.border-l.svelte-r5bhj7 {
+ border-left-width: 1px
+}
+
+.border-slate-200.svelte-r5bhj7 {
+ --tw-border-opacity: 1;
+ border-color: rgb(226 232 240 / var(--tw-border-opacity))
+}
+
+.border-l-gray-400.svelte-r5bhj7 {
+ --tw-border-opacity: 1;
+ border-left-color: rgb(156 163 175 / var(--tw-border-opacity))
+}
+
+.bg-purple-700.svelte-r5bhj7 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(126 34 206 / var(--tw-bg-opacity))
+}
+
+.bg-slate-50.svelte-r5bhj7 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(248 250 252 / var(--tw-bg-opacity))
+}
+
+.p-4.svelte-r5bhj7 {
+ padding: 1rem
+}
+
+.py-2.svelte-r5bhj7 {
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem
+}
+
+.pl-5.svelte-r5bhj7 {
+ padding-left: 1.25rem
+}
+
+.text-center.svelte-r5bhj7 {
+ text-align: center
+}
+
+.text-xs.svelte-r5bhj7 {
+ font-size: 0.75rem;
+ line-height: 1rem
+}
+
+.text-base.svelte-r5bhj7 {
+ font-size: 1rem;
+ line-height: 1.5rem
+}
+
+.text-white.svelte-r5bhj7 {
+ --tw-text-opacity: 1;
+ color: rgb(255 255 255 / var(--tw-text-opacity))
+}
+
+.text-gray-400.svelte-r5bhj7 {
+ --tw-text-opacity: 1;
+ color: rgb(156 163 175 / var(--tw-text-opacity))
+}
+
+.text-gray-500.svelte-r5bhj7 {
+ --tw-text-opacity: 1;
+ color: rgb(107 114 128 / var(--tw-text-opacity))
+}
+
+.text-purple-500.svelte-r5bhj7 {
+ --tw-text-opacity: 1;
+ color: rgb(168 85 247 / var(--tw-text-opacity))
+}
+
+.ring-4.svelte-r5bhj7 {
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000)
+}
+
+.ring-2.svelte-r5bhj7 {
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000)
+}
+
+.ring-purple-700.svelte-r5bhj7 {
+ --tw-ring-opacity: 1;
+ --tw-ring-color: rgb(126 34 206 / var(--tw-ring-opacity))
+}
+
+.ring-gray-300.svelte-r5bhj7 {
+ --tw-ring-opacity: 1;
+ --tw-ring-color: rgb(209 213 219 / var(--tw-ring-opacity))
+}
+
+.hover\:bg-slate-100.svelte-r5bhj7:hover {
+ --tw-bg-opacity: 1;
+ background-color: rgb(241 245 249 / var(--tw-bg-opacity))
+}
+
+@media (prefers-color-scheme: dark) {
+}
+
+@media (min-width: 768px) {
+}
+
+@media (min-width: 1024px) {
+}
+
+@media (min-width: 1280px) {
+}
+
+.svelte-v3rae1, .svelte-v3rae1::before, .svelte-v3rae1::after {
+ box-sizing: border-box;
+ border-width: 0;
+ border-style: solid;
+ border-color: #e5e7eb
+}
+
+.svelte-v3rae1::before, .svelte-v3rae1::after {
+ --tw-content: ''
+}
+
+h1.svelte-v3rae1 {
+ font-size: inherit;
+ font-weight: inherit
+}
+
+a.svelte-v3rae1 {
+ color: inherit;
+ text-decoration: inherit
+}
+
+b.svelte-v3rae1 {
+ font-weight: bolder
+}
+
+button.svelte-v3rae1, textarea.svelte-v3rae1 {
+ font-family: inherit;
+ font-size: 100%;
+ font-weight: inherit;
+ line-height: inherit;
+ color: inherit;
+ margin: 0;
+ padding: 0
+}
+
+button.svelte-v3rae1 {
+ text-transform: none
+}
+
+button.svelte-v3rae1, [type='button'].svelte-v3rae1 {
+ -webkit-appearance: button;
+ background-color: transparent;
+ background-image: none
+}
+
+.svelte-v3rae1:-moz-focusring {
+ outline: auto
+}
+
+.svelte-v3rae1:-moz-ui-invalid {
+ box-shadow: none
+}
+
+.svelte-v3rae1::-webkit-inner-spin-button, .svelte-v3rae1::-webkit-outer-spin-button {
+ height: auto
+}
+
+.svelte-v3rae1::-webkit-search-decoration {
+ -webkit-appearance: none
+}
+
+.svelte-v3rae1::-webkit-file-upload-button {
+ -webkit-appearance: button;
+ font: inherit
+}
+
+h1.svelte-v3rae1 {
+ margin: 0
+}
+
+textarea.svelte-v3rae1 {
+ resize: vertical
+}
+
+textarea.svelte-v3rae1::-moz-placeholder {
+ opacity: 1;
+ color: #9ca3af
+}
+
+textarea.svelte-v3rae1::placeholder {
+ opacity: 1;
+ color: #9ca3af
+}
+
+button.svelte-v3rae1 {
+ cursor: pointer
+}
+
+.svelte-v3rae1:disabled {
+ cursor: default
+}
+
+svg.svelte-v3rae1 {
+ display: block;
+ vertical-align: middle
+}
+
+.svelte-v3rae1, .svelte-v3rae1::before, .svelte-v3rae1::after {
+ --tw-border-spacing-x: 0;
+ --tw-border-spacing-y: 0;
+ --tw-translate-x: 0;
+ --tw-translate-y: 0;
+ --tw-rotate: 0;
+ --tw-skew-x: 0;
+ --tw-skew-y: 0;
+ --tw-scale-x: 1;
+ --tw-scale-y: 1;
+ --tw-pan-x: ;
+ --tw-pan-y: ;
+ --tw-pinch-zoom: ;
+ --tw-scroll-snap-strictness: proximity;
+ --tw-ordinal: ;
+ --tw-slashed-zero: ;
+ --tw-numeric-figure: ;
+ --tw-numeric-spacing: ;
+ --tw-numeric-fraction: ;
+ --tw-ring-inset: ;
+ --tw-ring-offset-width: 0px;
+ --tw-ring-offset-color: #fff;
+ --tw-ring-color: rgb(59 130 246 / 0.5);
+ --tw-ring-offset-shadow: 0 0 #0000;
+ --tw-ring-shadow: 0 0 #0000;
+ --tw-shadow: 0 0 #0000;
+ --tw-shadow-colored: 0 0 #0000;
+ --tw-blur: ;
+ --tw-brightness: ;
+ --tw-contrast: ;
+ --tw-grayscale: ;
+ --tw-hue-rotate: ;
+ --tw-invert: ;
+ --tw-saturate: ;
+ --tw-sepia: ;
+ --tw-drop-shadow: ;
+ --tw-backdrop-blur: ;
+ --tw-backdrop-brightness: ;
+ --tw-backdrop-contrast: ;
+ --tw-backdrop-grayscale: ;
+ --tw-backdrop-hue-rotate: ;
+ --tw-backdrop-invert: ;
+ --tw-backdrop-opacity: ;
+ --tw-backdrop-saturate: ;
+ --tw-backdrop-sepia:
+}
+
+.svelte-v3rae1::backdrop {
+ --tw-border-spacing-x: 0;
+ --tw-border-spacing-y: 0;
+ --tw-translate-x: 0;
+ --tw-translate-y: 0;
+ --tw-rotate: 0;
+ --tw-skew-x: 0;
+ --tw-skew-y: 0;
+ --tw-scale-x: 1;
+ --tw-scale-y: 1;
+ --tw-pan-x: ;
+ --tw-pan-y: ;
+ --tw-pinch-zoom: ;
+ --tw-scroll-snap-strictness: proximity;
+ --tw-ordinal: ;
+ --tw-slashed-zero: ;
+ --tw-numeric-figure: ;
+ --tw-numeric-spacing: ;
+ --tw-numeric-fraction: ;
+ --tw-ring-inset: ;
+ --tw-ring-offset-width: 0px;
+ --tw-ring-offset-color: #fff;
+ --tw-ring-color: rgb(59 130 246 / 0.5);
+ --tw-ring-offset-shadow: 0 0 #0000;
+ --tw-ring-shadow: 0 0 #0000;
+ --tw-shadow: 0 0 #0000;
+ --tw-shadow-colored: 0 0 #0000;
+ --tw-blur: ;
+ --tw-brightness: ;
+ --tw-contrast: ;
+ --tw-grayscale: ;
+ --tw-hue-rotate: ;
+ --tw-invert: ;
+ --tw-saturate: ;
+ --tw-sepia: ;
+ --tw-drop-shadow: ;
+ --tw-backdrop-blur: ;
+ --tw-backdrop-brightness: ;
+ --tw-backdrop-contrast: ;
+ --tw-backdrop-grayscale: ;
+ --tw-backdrop-hue-rotate: ;
+ --tw-backdrop-invert: ;
+ --tw-backdrop-opacity: ;
+ --tw-backdrop-saturate: ;
+ --tw-backdrop-sepia:
+}
+
+@media (min-width: 640px) {
+}
+
+@media (min-width: 768px) {
+}
+
+@media (min-width: 1024px) {
+}
+
+@media (min-width: 1280px) {
+}
+
+@media (min-width: 1536px) {
+}
+
+.-m-5.svelte-v3rae1 {
+ margin: -1.25rem
+}
+
+.-mx-5.svelte-v3rae1 {
+ margin-left: -1.25rem;
+ margin-right: -1.25rem
+}
+
+.my-2.svelte-v3rae1 {
+ margin-top: 0.5rem;
+ margin-bottom: 0.5rem
+}
+
+.-mx-1.svelte-v3rae1 {
+ margin-left: -0.25rem;
+ margin-right: -0.25rem
+}
+
+.mb-3.svelte-v3rae1 {
+ margin-bottom: 0.75rem
+}
+
+.mt-2.svelte-v3rae1 {
+ margin-top: 0.5rem
+}
+
+.ml-2.svelte-v3rae1 {
+ margin-left: 0.5rem
+}
+
+.-mb-2.svelte-v3rae1 {
+ margin-bottom: -0.5rem
+}
+
+.inline-block.svelte-v3rae1 {
+ display: inline-block
+}
+
+.flex.svelte-v3rae1 {
+ display: flex
+}
+
+.inline-flex.svelte-v3rae1 {
+ display: inline-flex
+}
+
+.h-2.svelte-v3rae1 {
+ height: 0.5rem
+}
+
+.h-6.svelte-v3rae1 {
+ height: 1.5rem
+}
+
+.w-2.svelte-v3rae1 {
+ width: 0.5rem
+}
+
+.w-6.svelte-v3rae1 {
+ width: 1.5rem
+}
+
+.w-full.svelte-v3rae1 {
+ width: 100%
+}
+
+.rotate-90.svelte-v3rae1 {
+ --tw-rotate: 90deg;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))
+}
+
+.resize-none.svelte-v3rae1 {
+ resize: none
+}
+
+.flex-row.svelte-v3rae1 {
+ flex-direction: row
+}
+
+.flex-col.svelte-v3rae1 {
+ flex-direction: column
+}
+
+.items-end.svelte-v3rae1 {
+ align-items: flex-end
+}
+
+.items-center.svelte-v3rae1 {
+ align-items: center
+}
+
+.justify-between.svelte-v3rae1 {
+ justify-content: space-between
+}
+
+.gap-1.svelte-v3rae1 {
+ gap: 0.25rem
+}
+
+.gap-2.svelte-v3rae1 {
+ gap: 0.5rem
+}
+
+.overflow-hidden.svelte-v3rae1 {
+ overflow: hidden
+}
+
+.overflow-clip.svelte-v3rae1 {
+ overflow: clip
+}
+
+.overflow-scroll.svelte-v3rae1 {
+ overflow: scroll
+}
+
+.text-ellipsis.svelte-v3rae1 {
+ text-overflow: ellipsis
+}
+
+.whitespace-nowrap.svelte-v3rae1 {
+ white-space: nowrap
+}
+
+.rounded-full.svelte-v3rae1 {
+ border-radius: 9999px
+}
+
+.rounded-xl.svelte-v3rae1 {
+ border-radius: 0.75rem
+}
+
+.border.svelte-v3rae1 {
+ border-width: 1px
+}
+
+.border-y.svelte-v3rae1 {
+ border-top-width: 1px;
+ border-bottom-width: 1px
+}
+
+.border-transparent.svelte-v3rae1 {
+ border-color: transparent
+}
+
+.border-y-slate-200.svelte-v3rae1 {
+ --tw-border-opacity: 1;
+ border-top-color: rgb(226 232 240 / var(--tw-border-opacity));
+ border-bottom-color: rgb(226 232 240 / var(--tw-border-opacity))
+}
+
+.bg-purple-700.svelte-v3rae1 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(126 34 206 / var(--tw-bg-opacity))
+}
+
+.bg-green-500.svelte-v3rae1 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(34 197 94 / var(--tw-bg-opacity))
+}
+
+.bg-gray-300.svelte-v3rae1 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(209 213 219 / var(--tw-bg-opacity))
+}
+
+.bg-slate-100.svelte-v3rae1 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(241 245 249 / var(--tw-bg-opacity))
+}
+
+.p-2.svelte-v3rae1 {
+ padding: 0.5rem
+}
+
+.p-3.svelte-v3rae1 {
+ padding: 0.75rem
+}
+
+.px-5.svelte-v3rae1 {
+ padding-left: 1.25rem;
+ padding-right: 1.25rem
+}
+
+.py-3.svelte-v3rae1 {
+ padding-top: 0.75rem;
+ padding-bottom: 0.75rem
+}
+
+.py-2.svelte-v3rae1 {
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem
+}
+
+.text-lg.svelte-v3rae1 {
+ font-size: 1.125rem;
+ line-height: 1.75rem
+}
+
+.text-xs.svelte-v3rae1 {
+ font-size: 0.75rem;
+ line-height: 1rem
+}
+
+.text-sm.svelte-v3rae1 {
+ font-size: 0.875rem;
+ line-height: 1.25rem
+}
+
+.font-semibold.svelte-v3rae1 {
+ font-weight: 600
+}
+
+.text-white.svelte-v3rae1 {
+ --tw-text-opacity: 1;
+ color: rgb(255 255 255 / var(--tw-text-opacity))
+}
+
+.text-gray-200.svelte-v3rae1 {
+ --tw-text-opacity: 1;
+ color: rgb(229 231 235 / var(--tw-text-opacity))
+}
+
+.text-black.svelte-v3rae1 {
+ --tw-text-opacity: 1;
+ color: rgb(0 0 0 / var(--tw-text-opacity))
+}
+
+.text-gray-600.svelte-v3rae1 {
+ --tw-text-opacity: 1;
+ color: rgb(75 85 99 / var(--tw-text-opacity))
+}
+
+.shadow-sm.svelte-v3rae1 {
+ --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
+ --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow)
+}
+
+.hover\:bg-purple-600.svelte-v3rae1:hover {
+ --tw-bg-opacity: 1;
+ background-color: rgb(147 51 234 / var(--tw-bg-opacity))
+}
+
+.focus\:outline-none.svelte-v3rae1:focus {
+ outline: 2px solid transparent;
+ outline-offset: 2px
+}
+
+.focus\:ring-2.svelte-v3rae1:focus {
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000)
+}
+
+.focus\:ring-purple-500.svelte-v3rae1:focus {
+ --tw-ring-opacity: 1;
+ --tw-ring-color: rgb(168 85 247 / var(--tw-ring-opacity))
+}
+
+.focus\:ring-offset-2.svelte-v3rae1:focus {
+ --tw-ring-offset-width: 2px
+}
+
+@media (prefers-color-scheme: dark) {
+}
+
+@media (min-width: 768px) {
+}
+
+@media (min-width: 1024px) {
+}
+
+@media (min-width: 1280px) {
+}
+
+@media (min-width: 640px) {
+}
+
+@media (min-width: 768px) {
+}
+
+@media (min-width: 1024px) {
+}
+
+@media (min-width: 1280px) {
+}
+
+@media (min-width: 1536px) {
+}
+
+@media (prefers-color-scheme: dark) {
+}
+
+@media (min-width: 768px) {
+}
+
+@media (min-width: 1024px) {
+}
+
+@media (min-width: 1280px) {
+}
+
+.svelte-h3q7vr, .svelte-h3q7vr::before, .svelte-h3q7vr::after {
+ box-sizing: border-box;
+ border-width: 0;
+ border-style: solid;
+ border-color: #e5e7eb
+}
+
+.svelte-h3q7vr::before, .svelte-h3q7vr::after {
+ --tw-content: ''
+}
+
+h1.svelte-h3q7vr {
+ font-size: inherit;
+ font-weight: inherit
+}
+
+a.svelte-h3q7vr {
+ color: inherit;
+ text-decoration: inherit
+}
+
+button.svelte-h3q7vr {
+ font-family: inherit;
+ font-size: 100%;
+ font-weight: inherit;
+ line-height: inherit;
+ color: inherit;
+ margin: 0;
+ padding: 0
+}
+
+button.svelte-h3q7vr {
+ text-transform: none
+}
+
+button.svelte-h3q7vr {
+ -webkit-appearance: button;
+ background-color: transparent;
+ background-image: none
+}
+
+.svelte-h3q7vr:-moz-focusring {
+ outline: auto
+}
+
+.svelte-h3q7vr:-moz-ui-invalid {
+ box-shadow: none
+}
+
+.svelte-h3q7vr::-webkit-inner-spin-button, .svelte-h3q7vr::-webkit-outer-spin-button {
+ height: auto
+}
+
+.svelte-h3q7vr::-webkit-search-decoration {
+ -webkit-appearance: none
+}
+
+.svelte-h3q7vr::-webkit-file-upload-button {
+ -webkit-appearance: button;
+ font: inherit
+}
+
+h1.svelte-h3q7vr, p.svelte-h3q7vr {
+ margin: 0
+}
+
+button.svelte-h3q7vr {
+ cursor: pointer
+}
+
+.svelte-h3q7vr:disabled {
+ cursor: default
+}
+
+svg.svelte-h3q7vr {
+ display: block;
+ vertical-align: middle
+}
+
+.svelte-h3q7vr, .svelte-h3q7vr::before, .svelte-h3q7vr::after {
+ --tw-border-spacing-x: 0;
+ --tw-border-spacing-y: 0;
+ --tw-translate-x: 0;
+ --tw-translate-y: 0;
+ --tw-rotate: 0;
+ --tw-skew-x: 0;
+ --tw-skew-y: 0;
+ --tw-scale-x: 1;
+ --tw-scale-y: 1;
+ --tw-pan-x: ;
+ --tw-pan-y: ;
+ --tw-pinch-zoom: ;
+ --tw-scroll-snap-strictness: proximity;
+ --tw-ordinal: ;
+ --tw-slashed-zero: ;
+ --tw-numeric-figure: ;
+ --tw-numeric-spacing: ;
+ --tw-numeric-fraction: ;
+ --tw-ring-inset: ;
+ --tw-ring-offset-width: 0px;
+ --tw-ring-offset-color: #fff;
+ --tw-ring-color: rgb(59 130 246 / 0.5);
+ --tw-ring-offset-shadow: 0 0 #0000;
+ --tw-ring-shadow: 0 0 #0000;
+ --tw-shadow: 0 0 #0000;
+ --tw-shadow-colored: 0 0 #0000;
+ --tw-blur: ;
+ --tw-brightness: ;
+ --tw-contrast: ;
+ --tw-grayscale: ;
+ --tw-hue-rotate: ;
+ --tw-invert: ;
+ --tw-saturate: ;
+ --tw-sepia: ;
+ --tw-drop-shadow: ;
+ --tw-backdrop-blur: ;
+ --tw-backdrop-brightness: ;
+ --tw-backdrop-contrast: ;
+ --tw-backdrop-grayscale: ;
+ --tw-backdrop-hue-rotate: ;
+ --tw-backdrop-invert: ;
+ --tw-backdrop-opacity: ;
+ --tw-backdrop-saturate: ;
+ --tw-backdrop-sepia:
+}
+
+.svelte-h3q7vr::backdrop {
+ --tw-border-spacing-x: 0;
+ --tw-border-spacing-y: 0;
+ --tw-translate-x: 0;
+ --tw-translate-y: 0;
+ --tw-rotate: 0;
+ --tw-skew-x: 0;
+ --tw-skew-y: 0;
+ --tw-scale-x: 1;
+ --tw-scale-y: 1;
+ --tw-pan-x: ;
+ --tw-pan-y: ;
+ --tw-pinch-zoom: ;
+ --tw-scroll-snap-strictness: proximity;
+ --tw-ordinal: ;
+ --tw-slashed-zero: ;
+ --tw-numeric-figure: ;
+ --tw-numeric-spacing: ;
+ --tw-numeric-fraction: ;
+ --tw-ring-inset: ;
+ --tw-ring-offset-width: 0px;
+ --tw-ring-offset-color: #fff;
+ --tw-ring-color: rgb(59 130 246 / 0.5);
+ --tw-ring-offset-shadow: 0 0 #0000;
+ --tw-ring-shadow: 0 0 #0000;
+ --tw-shadow: 0 0 #0000;
+ --tw-shadow-colored: 0 0 #0000;
+ --tw-blur: ;
+ --tw-brightness: ;
+ --tw-contrast: ;
+ --tw-grayscale: ;
+ --tw-hue-rotate: ;
+ --tw-invert: ;
+ --tw-saturate: ;
+ --tw-sepia: ;
+ --tw-drop-shadow: ;
+ --tw-backdrop-blur: ;
+ --tw-backdrop-brightness: ;
+ --tw-backdrop-contrast: ;
+ --tw-backdrop-grayscale: ;
+ --tw-backdrop-hue-rotate: ;
+ --tw-backdrop-invert: ;
+ --tw-backdrop-opacity: ;
+ --tw-backdrop-saturate: ;
+ --tw-backdrop-sepia:
+}
+
+@media (min-width: 640px) {
+}
+
+@media (min-width: 768px) {
+}
+
+@media (min-width: 1024px) {
+}
+
+@media (min-width: 1280px) {
+}
+
+@media (min-width: 1536px) {
+}
+
+.fixed.svelte-h3q7vr {
+ position: fixed
+}
+
+.bottom-5.svelte-h3q7vr {
+ bottom: 1.25rem
+}
+
+.right-5.svelte-h3q7vr {
+ right: 1.25rem
+}
+
+.-mx-1.svelte-h3q7vr {
+ margin-left: -0.25rem;
+ margin-right: -0.25rem
+}
+
+.mb-3.svelte-h3q7vr {
+ margin-bottom: 0.75rem
+}
+
+.mb-5.svelte-h3q7vr {
+ margin-bottom: 1.25rem
+}
+
+.mt-3.svelte-h3q7vr {
+ margin-top: 0.75rem
+}
+
+.inline-block.svelte-h3q7vr {
+ display: inline-block
+}
+
+.flex.svelte-h3q7vr {
+ display: flex
+}
+
+.hidden.svelte-h3q7vr {
+ display: none
+}
+
+.h-6.svelte-h3q7vr {
+ height: 1.5rem
+}
+
+.w-6.svelte-h3q7vr {
+ width: 1.5rem
+}
+
+.w-full.svelte-h3q7vr {
+ width: 100%
+}
+
+.w-96.svelte-h3q7vr {
+ width: 24rem
+}
+
+.max-w-screen-sm.svelte-h3q7vr {
+ max-width: 640px
+}
+
+.flex-row.svelte-h3q7vr {
+ flex-direction: row
+}
+
+.flex-col.svelte-h3q7vr {
+ flex-direction: column
+}
+
+.items-center.svelte-h3q7vr {
+ align-items: center
+}
+
+.gap-4.svelte-h3q7vr {
+ gap: 1rem
+}
+
+.self-end.svelte-h3q7vr {
+ align-self: flex-end
+}
+
+.overflow-scroll.svelte-h3q7vr {
+ overflow: scroll
+}
+
+.rounded-full.svelte-h3q7vr {
+ border-radius: 9999px
+}
+
+.rounded-xl.svelte-h3q7vr {
+ border-radius: 0.75rem
+}
+
+.bg-white.svelte-h3q7vr {
+ --tw-bg-opacity: 1;
+ background-color: rgb(255 255 255 / var(--tw-bg-opacity))
+}
+
+.bg-purple-900.svelte-h3q7vr {
+ --tw-bg-opacity: 1;
+ background-color: rgb(88 28 135 / var(--tw-bg-opacity))
+}
+
+.p-2.svelte-h3q7vr {
+ padding: 0.5rem
+}
+
+.p-5.svelte-h3q7vr {
+ padding: 1.25rem
+}
+
+.py-4.svelte-h3q7vr {
+ padding-top: 1rem;
+ padding-bottom: 1rem
+}
+
+.text-center.svelte-h3q7vr {
+ text-align: center
+}
+
+.font-sans.svelte-h3q7vr {
+ font-family: Inconsolata, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"
+}
+
+.text-xl.svelte-h3q7vr {
+ font-size: 1.25rem;
+ line-height: 1.75rem
+}
+
+.text-2xl.svelte-h3q7vr {
+ font-size: 1.5rem;
+ line-height: 2rem
+}
+
+.text-6xl.svelte-h3q7vr {
+ font-size: 3.75rem;
+ line-height: 1
+}
+
+.font-semibold.svelte-h3q7vr {
+ font-weight: 600
+}
+
+.font-bold.svelte-h3q7vr {
+ font-weight: 700
+}
+
+.uppercase.svelte-h3q7vr {
+ text-transform: uppercase
+}
+
+.tracking-wide.svelte-h3q7vr {
+ letter-spacing: 0.025em
+}
+
+.tracking-wider.svelte-h3q7vr {
+ letter-spacing: 0.05em
+}
+
+.text-white.svelte-h3q7vr {
+ --tw-text-opacity: 1;
+ color: rgb(255 255 255 / var(--tw-text-opacity))
+}
+
+.text-black.svelte-h3q7vr {
+ --tw-text-opacity: 1;
+ color: rgb(0 0 0 / var(--tw-text-opacity))
+}
+
+.text-purple-700.svelte-h3q7vr {
+ --tw-text-opacity: 1;
+ color: rgb(126 34 206 / var(--tw-text-opacity))
+}
+
+.text-gray-700.svelte-h3q7vr {
+ --tw-text-opacity: 1;
+ color: rgb(55 65 81 / var(--tw-text-opacity))
+}
+
+.text-orange-400.svelte-h3q7vr {
+ --tw-text-opacity: 1;
+ color: rgb(251 146 60 / var(--tw-text-opacity))
+}
+
+.text-purple-300.svelte-h3q7vr {
+ --tw-text-opacity: 1;
+ color: rgb(216 180 254 / var(--tw-text-opacity))
+}
+
+.shadow-2xl.svelte-h3q7vr {
+ --tw-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);
+ --tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow)
+}
+
+.hover\:bg-purple-700.svelte-h3q7vr:hover {
+ --tw-bg-opacity: 1;
+ background-color: rgb(126 34 206 / var(--tw-bg-opacity))
+}
+
+@media (prefers-color-scheme: dark) {
+}
+
+@media (min-width: 768px) {
+}
+
+@media (min-width: 1024px) {
+}
+
+@media (min-width: 1280px) {
+}
diff --git a/public/dist/einundzwanzig.chat.js b/public/dist/einundzwanzig.chat.js
new file mode 100644
index 0000000..179c26c
--- /dev/null
+++ b/public/dist/einundzwanzig.chat.js
@@ -0,0 +1,14879 @@
+(function () {
+ 'use strict';
+
+ function noop() { }
+ function assign(tar, src) {
+ // @ts-ignore
+ for (const k in src)
+ tar[k] = src[k];
+ return tar;
+ }
+ function run(fn) {
+ return fn();
+ }
+ function blank_object() {
+ return Object.create(null);
+ }
+ function run_all(fns) {
+ fns.forEach(run);
+ }
+ function is_function(thing) {
+ return typeof thing === 'function';
+ }
+ function safe_not_equal(a, b) {
+ return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');
+ }
+ let src_url_equal_anchor;
+ function src_url_equal(element_src, url) {
+ if (!src_url_equal_anchor) {
+ src_url_equal_anchor = document.createElement('a');
+ }
+ src_url_equal_anchor.href = url;
+ return element_src === src_url_equal_anchor.href;
+ }
+ function is_empty(obj) {
+ return Object.keys(obj).length === 0;
+ }
+ function subscribe(store, ...callbacks) {
+ if (store == null) {
+ return noop;
+ }
+ const unsub = store.subscribe(...callbacks);
+ return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;
+ }
+ function component_subscribe(component, store, callback) {
+ component.$$.on_destroy.push(subscribe(store, callback));
+ }
+ function set_store_value(store, ret, value) {
+ store.set(value);
+ return ret;
+ }
+
+ const is_client = typeof window !== 'undefined';
+ let now$1 = is_client
+ ? () => window.performance.now()
+ : () => Date.now();
+ let raf = is_client ? cb => requestAnimationFrame(cb) : noop;
+
+ const tasks = new Set();
+ function run_tasks(now) {
+ tasks.forEach(task => {
+ if (!task.c(now)) {
+ tasks.delete(task);
+ task.f();
+ }
+ });
+ if (tasks.size !== 0)
+ raf(run_tasks);
+ }
+ /**
+ * Creates a new task that runs on each raf frame
+ * until it returns a falsy value or is aborted
+ */
+ function loop(callback) {
+ let task;
+ if (tasks.size === 0)
+ raf(run_tasks);
+ return {
+ promise: new Promise(fulfill => {
+ tasks.add(task = { c: callback, f: fulfill });
+ }),
+ abort() {
+ tasks.delete(task);
+ }
+ };
+ }
+ function append(target, node) {
+ target.appendChild(node);
+ }
+ function insert(target, node, anchor) {
+ target.insertBefore(node, anchor || null);
+ }
+ function detach(node) {
+ if (node.parentNode) {
+ node.parentNode.removeChild(node);
+ }
+ }
+ function destroy_each(iterations, detaching) {
+ for (let i = 0; i < iterations.length; i += 1) {
+ if (iterations[i])
+ iterations[i].d(detaching);
+ }
+ }
+ function element(name) {
+ return document.createElement(name);
+ }
+ function svg_element(name) {
+ return document.createElementNS('http://www.w3.org/2000/svg', name);
+ }
+ function text(data) {
+ return document.createTextNode(data);
+ }
+ function space() {
+ return text(' ');
+ }
+ function empty() {
+ return text('');
+ }
+ function listen(node, event, handler, options) {
+ node.addEventListener(event, handler, options);
+ return () => node.removeEventListener(event, handler, options);
+ }
+ function prevent_default(fn) {
+ return function (event) {
+ event.preventDefault();
+ // @ts-ignore
+ return fn.call(this, event);
+ };
+ }
+ function attr(node, attribute, value) {
+ if (value == null)
+ node.removeAttribute(attribute);
+ else if (node.getAttribute(attribute) !== value)
+ node.setAttribute(attribute, value);
+ }
+ function set_svg_attributes(node, attributes) {
+ for (const key in attributes) {
+ attr(node, key, attributes[key]);
+ }
+ }
+ function children(element) {
+ return Array.from(element.childNodes);
+ }
+ function set_data(text, data) {
+ data = '' + data;
+ if (text.wholeText !== data)
+ text.data = data;
+ }
+ function set_style(node, key, value, important) {
+ if (value === null) {
+ node.style.removeProperty(key);
+ }
+ else {
+ node.style.setProperty(key, value, important ? 'important' : '');
+ }
+ }
+ function toggle_class(element, name, toggle) {
+ element.classList[toggle ? 'add' : 'remove'](name);
+ }
+
+ let current_component;
+ function set_current_component(component) {
+ current_component = component;
+ }
+ function get_current_component() {
+ if (!current_component)
+ throw new Error('Function called outside component initialization');
+ return current_component;
+ }
+ /**
+ * The `onMount` function schedules a callback to run as soon as the component has been mounted to the DOM.
+ * It must be called during the component's initialisation (but doesn't need to live *inside* the component;
+ * it can be called from an external module).
+ *
+ * `onMount` does not run inside a [server-side component](/docs#run-time-server-side-component-api).
+ *
+ * https://svelte.dev/docs#run-time-svelte-onmount
+ */
+ function onMount(fn) {
+ get_current_component().$$.on_mount.push(fn);
+ }
+
+ const dirty_components = [];
+ const binding_callbacks = [];
+ const render_callbacks = [];
+ const flush_callbacks = [];
+ const resolved_promise = Promise.resolve();
+ let update_scheduled = false;
+ function schedule_update() {
+ if (!update_scheduled) {
+ update_scheduled = true;
+ resolved_promise.then(flush);
+ }
+ }
+ function add_render_callback(fn) {
+ render_callbacks.push(fn);
+ }
+ // flush() calls callbacks in this order:
+ // 1. All beforeUpdate callbacks, in order: parents before children
+ // 2. All bind:this callbacks, in reverse order: children before parents.
+ // 3. All afterUpdate callbacks, in order: parents before children. EXCEPT
+ // for afterUpdates called during the initial onMount, which are called in
+ // reverse order: children before parents.
+ // Since callbacks might update component values, which could trigger another
+ // call to flush(), the following steps guard against this:
+ // 1. During beforeUpdate, any updated components will be added to the
+ // dirty_components array and will cause a reentrant call to flush(). Because
+ // the flush index is kept outside the function, the reentrant call will pick
+ // up where the earlier call left off and go through all dirty components. The
+ // current_component value is saved and restored so that the reentrant call will
+ // not interfere with the "parent" flush() call.
+ // 2. bind:this callbacks cannot trigger new flush() calls.
+ // 3. During afterUpdate, any updated components will NOT have their afterUpdate
+ // callback called a second time; the seen_callbacks set, outside the flush()
+ // function, guarantees this behavior.
+ const seen_callbacks = new Set();
+ let flushidx = 0; // Do *not* move this inside the flush() function
+ function flush() {
+ // Do not reenter flush while dirty components are updated, as this can
+ // result in an infinite loop. Instead, let the inner flush handle it.
+ // Reentrancy is ok afterwards for bindings etc.
+ if (flushidx !== 0) {
+ return;
+ }
+ const saved_component = current_component;
+ do {
+ // first, call beforeUpdate functions
+ // and update components
+ try {
+ while (flushidx < dirty_components.length) {
+ const component = dirty_components[flushidx];
+ flushidx++;
+ set_current_component(component);
+ update(component.$$);
+ }
+ }
+ catch (e) {
+ // reset dirty state to not end up in a deadlocked state and then rethrow
+ dirty_components.length = 0;
+ flushidx = 0;
+ throw e;
+ }
+ set_current_component(null);
+ dirty_components.length = 0;
+ flushidx = 0;
+ while (binding_callbacks.length)
+ binding_callbacks.pop()();
+ // then, once components are updated, call
+ // afterUpdate functions. This may cause
+ // subsequent updates...
+ for (let i = 0; i < render_callbacks.length; i += 1) {
+ const callback = render_callbacks[i];
+ if (!seen_callbacks.has(callback)) {
+ // ...so guard against infinite loops
+ seen_callbacks.add(callback);
+ callback();
+ }
+ }
+ render_callbacks.length = 0;
+ } while (dirty_components.length);
+ while (flush_callbacks.length) {
+ flush_callbacks.pop()();
+ }
+ update_scheduled = false;
+ seen_callbacks.clear();
+ set_current_component(saved_component);
+ }
+ function update($$) {
+ if ($$.fragment !== null) {
+ $$.update();
+ run_all($$.before_update);
+ const dirty = $$.dirty;
+ $$.dirty = [-1];
+ $$.fragment && $$.fragment.p($$.ctx, dirty);
+ $$.after_update.forEach(add_render_callback);
+ }
+ }
+ const outroing = new Set();
+ let outros;
+ function group_outros() {
+ outros = {
+ r: 0,
+ c: [],
+ p: outros // parent group
+ };
+ }
+ function check_outros() {
+ if (!outros.r) {
+ run_all(outros.c);
+ }
+ outros = outros.p;
+ }
+ function transition_in(block, local) {
+ if (block && block.i) {
+ outroing.delete(block);
+ block.i(local);
+ }
+ }
+ function transition_out(block, local, detach, callback) {
+ if (block && block.o) {
+ if (outroing.has(block))
+ return;
+ outroing.add(block);
+ outros.c.push(() => {
+ outroing.delete(block);
+ if (callback) {
+ if (detach)
+ block.d(1);
+ callback();
+ }
+ });
+ block.o(local);
+ }
+ else if (callback) {
+ callback();
+ }
+ }
+
+ function get_spread_update(levels, updates) {
+ const update = {};
+ const to_null_out = {};
+ const accounted_for = { $$scope: 1 };
+ let i = levels.length;
+ while (i--) {
+ const o = levels[i];
+ const n = updates[i];
+ if (n) {
+ for (const key in o) {
+ if (!(key in n))
+ to_null_out[key] = 1;
+ }
+ for (const key in n) {
+ if (!accounted_for[key]) {
+ update[key] = n[key];
+ accounted_for[key] = 1;
+ }
+ }
+ levels[i] = n;
+ }
+ else {
+ for (const key in o) {
+ accounted_for[key] = 1;
+ }
+ }
+ }
+ for (const key in to_null_out) {
+ if (!(key in update))
+ update[key] = undefined;
+ }
+ return update;
+ }
+ function create_component(block) {
+ block && block.c();
+ }
+ function mount_component(component, target, anchor, customElement) {
+ const { fragment, after_update } = component.$$;
+ fragment && fragment.m(target, anchor);
+ if (!customElement) {
+ // onMount happens before the initial afterUpdate
+ add_render_callback(() => {
+ const new_on_destroy = component.$$.on_mount.map(run).filter(is_function);
+ // if the component was destroyed immediately
+ // it will update the `$$.on_destroy` reference to `null`.
+ // the destructured on_destroy may still reference to the old array
+ if (component.$$.on_destroy) {
+ component.$$.on_destroy.push(...new_on_destroy);
+ }
+ else {
+ // Edge case - component was destroyed immediately,
+ // most likely as a result of a binding initialising
+ run_all(new_on_destroy);
+ }
+ component.$$.on_mount = [];
+ });
+ }
+ after_update.forEach(add_render_callback);
+ }
+ function destroy_component(component, detaching) {
+ const $$ = component.$$;
+ if ($$.fragment !== null) {
+ run_all($$.on_destroy);
+ $$.fragment && $$.fragment.d(detaching);
+ // TODO null out other refs, including component.$$ (but need to
+ // preserve final state?)
+ $$.on_destroy = $$.fragment = null;
+ $$.ctx = [];
+ }
+ }
+ function make_dirty(component, i) {
+ if (component.$$.dirty[0] === -1) {
+ dirty_components.push(component);
+ schedule_update();
+ component.$$.dirty.fill(0);
+ }
+ component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31));
+ }
+ function init(component, options, instance, create_fragment, not_equal, props, append_styles, dirty = [-1]) {
+ const parent_component = current_component;
+ set_current_component(component);
+ const $$ = component.$$ = {
+ fragment: null,
+ ctx: [],
+ // state
+ props,
+ update: noop,
+ not_equal,
+ bound: blank_object(),
+ // lifecycle
+ on_mount: [],
+ on_destroy: [],
+ on_disconnect: [],
+ before_update: [],
+ after_update: [],
+ context: new Map(options.context || (parent_component ? parent_component.$$.context : [])),
+ // everything else
+ callbacks: blank_object(),
+ dirty,
+ skip_bound: false,
+ root: options.target || parent_component.$$.root
+ };
+ append_styles && append_styles($$.root);
+ let ready = false;
+ $$.ctx = instance
+ ? instance(component, options.props || {}, (i, ret, ...rest) => {
+ const value = rest.length ? rest[0] : ret;
+ if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) {
+ if (!$$.skip_bound && $$.bound[i])
+ $$.bound[i](value);
+ if (ready)
+ make_dirty(component, i);
+ }
+ return ret;
+ })
+ : [];
+ $$.update();
+ ready = true;
+ run_all($$.before_update);
+ // `false` as a special case of no DOM component
+ $$.fragment = create_fragment ? create_fragment($$.ctx) : false;
+ if (options.target) {
+ if (options.hydrate) {
+ const nodes = children(options.target);
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ $$.fragment && $$.fragment.l(nodes);
+ nodes.forEach(detach);
+ }
+ else {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ $$.fragment && $$.fragment.c();
+ }
+ if (options.intro)
+ transition_in(component.$$.fragment);
+ mount_component(component, options.target, options.anchor, options.customElement);
+ flush();
+ }
+ set_current_component(parent_component);
+ }
+ /**
+ * Base class for Svelte components. Used when dev=false.
+ */
+ class SvelteComponent {
+ $destroy() {
+ destroy_component(this, 1);
+ this.$destroy = noop;
+ }
+ $on(type, callback) {
+ if (!is_function(callback)) {
+ return noop;
+ }
+ const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = []));
+ callbacks.push(callback);
+ return () => {
+ const index = callbacks.indexOf(callback);
+ if (index !== -1)
+ callbacks.splice(index, 1);
+ };
+ }
+ $set($$props) {
+ if (this.$$set && !is_empty($$props)) {
+ this.$$.skip_bound = true;
+ this.$$set($$props);
+ this.$$.skip_bound = false;
+ }
+ }
+ }
+
+ const subscriber_queue = [];
+ /**
+ * Create a `Writable` store that allows both updating and reading by subscription.
+ * @param {*=}value initial value
+ * @param {StartStopNotifier=}start start and stop notifications for subscriptions
+ */
+ function writable(value, start = noop) {
+ let stop;
+ const subscribers = new Set();
+ function set(new_value) {
+ if (safe_not_equal(value, new_value)) {
+ value = new_value;
+ if (stop) { // store is ready
+ const run_queue = !subscriber_queue.length;
+ for (const subscriber of subscribers) {
+ subscriber[1]();
+ subscriber_queue.push(subscriber, value);
+ }
+ if (run_queue) {
+ for (let i = 0; i < subscriber_queue.length; i += 2) {
+ subscriber_queue[i][0](subscriber_queue[i + 1]);
+ }
+ subscriber_queue.length = 0;
+ }
+ }
+ }
+ }
+ function update(fn) {
+ set(fn(value));
+ }
+ function subscribe(run, invalidate = noop) {
+ const subscriber = [run, invalidate];
+ subscribers.add(subscriber);
+ if (subscribers.size === 1) {
+ stop = start(set) || noop;
+ }
+ run(value);
+ return () => {
+ subscribers.delete(subscriber);
+ if (subscribers.size === 0) {
+ stop();
+ stop = null;
+ }
+ };
+ }
+ return { set, update, subscribe };
+ }
+
+ const chatAdapter = writable(null);
+ const chatData = writable({ events: [], profiles: {}});
+ const selectedMessage = writable(null);
+
+ var Mode = {
+ MODE_NUMBER: 1 << 0,
+ MODE_ALPHA_NUM: 1 << 1,
+ MODE_8BIT_BYTE: 1 << 2,
+ MODE_KANJI: 1 << 3,
+ };
+
+ function QR8bitByte(data) {
+ this.mode = Mode.MODE_8BIT_BYTE;
+ this.data = data;
+ }
+
+ QR8bitByte.prototype = {
+ getLength: function () {
+ return this.data.length
+ },
+
+ write: function (buffer) {
+ for (var i = 0; i < this.data.length; i++) {
+ // not JIS ...
+ buffer.put(this.data.charCodeAt(i), 8);
+ }
+ },
+ };
+
+ var ErrorCorrectLevel = {
+ L: 1,
+ M: 0,
+ Q: 3,
+ H: 2,
+ };
+
+ // ErrorCorrectLevel
+
+ function QRRSBlock(totalCount, dataCount) {
+ this.totalCount = totalCount;
+ this.dataCount = dataCount;
+ }
+
+ QRRSBlock.RS_BLOCK_TABLE = [
+ // L
+ // M
+ // Q
+ // H
+
+ // 1
+ [1, 26, 19],
+ [1, 26, 16],
+ [1, 26, 13],
+ [1, 26, 9],
+
+ // 2
+ [1, 44, 34],
+ [1, 44, 28],
+ [1, 44, 22],
+ [1, 44, 16],
+
+ // 3
+ [1, 70, 55],
+ [1, 70, 44],
+ [2, 35, 17],
+ [2, 35, 13],
+
+ // 4
+ [1, 100, 80],
+ [2, 50, 32],
+ [2, 50, 24],
+ [4, 25, 9],
+
+ // 5
+ [1, 134, 108],
+ [2, 67, 43],
+ [2, 33, 15, 2, 34, 16],
+ [2, 33, 11, 2, 34, 12],
+
+ // 6
+ [2, 86, 68],
+ [4, 43, 27],
+ [4, 43, 19],
+ [4, 43, 15],
+
+ // 7
+ [2, 98, 78],
+ [4, 49, 31],
+ [2, 32, 14, 4, 33, 15],
+ [4, 39, 13, 1, 40, 14],
+
+ // 8
+ [2, 121, 97],
+ [2, 60, 38, 2, 61, 39],
+ [4, 40, 18, 2, 41, 19],
+ [4, 40, 14, 2, 41, 15],
+
+ // 9
+ [2, 146, 116],
+ [3, 58, 36, 2, 59, 37],
+ [4, 36, 16, 4, 37, 17],
+ [4, 36, 12, 4, 37, 13],
+
+ // 10
+ [2, 86, 68, 2, 87, 69],
+ [4, 69, 43, 1, 70, 44],
+ [6, 43, 19, 2, 44, 20],
+ [6, 43, 15, 2, 44, 16],
+
+ // 11
+ [4, 101, 81],
+ [1, 80, 50, 4, 81, 51],
+ [4, 50, 22, 4, 51, 23],
+ [3, 36, 12, 8, 37, 13],
+
+ // 12
+ [2, 116, 92, 2, 117, 93],
+ [6, 58, 36, 2, 59, 37],
+ [4, 46, 20, 6, 47, 21],
+ [7, 42, 14, 4, 43, 15],
+
+ // 13
+ [4, 133, 107],
+ [8, 59, 37, 1, 60, 38],
+ [8, 44, 20, 4, 45, 21],
+ [12, 33, 11, 4, 34, 12],
+
+ // 14
+ [3, 145, 115, 1, 146, 116],
+ [4, 64, 40, 5, 65, 41],
+ [11, 36, 16, 5, 37, 17],
+ [11, 36, 12, 5, 37, 13],
+
+ // 15
+ [5, 109, 87, 1, 110, 88],
+ [5, 65, 41, 5, 66, 42],
+ [5, 54, 24, 7, 55, 25],
+ [11, 36, 12],
+
+ // 16
+ [5, 122, 98, 1, 123, 99],
+ [7, 73, 45, 3, 74, 46],
+ [15, 43, 19, 2, 44, 20],
+ [3, 45, 15, 13, 46, 16],
+
+ // 17
+ [1, 135, 107, 5, 136, 108],
+ [10, 74, 46, 1, 75, 47],
+ [1, 50, 22, 15, 51, 23],
+ [2, 42, 14, 17, 43, 15],
+
+ // 18
+ [5, 150, 120, 1, 151, 121],
+ [9, 69, 43, 4, 70, 44],
+ [17, 50, 22, 1, 51, 23],
+ [2, 42, 14, 19, 43, 15],
+
+ // 19
+ [3, 141, 113, 4, 142, 114],
+ [3, 70, 44, 11, 71, 45],
+ [17, 47, 21, 4, 48, 22],
+ [9, 39, 13, 16, 40, 14],
+
+ // 20
+ [3, 135, 107, 5, 136, 108],
+ [3, 67, 41, 13, 68, 42],
+ [15, 54, 24, 5, 55, 25],
+ [15, 43, 15, 10, 44, 16],
+
+ // 21
+ [4, 144, 116, 4, 145, 117],
+ [17, 68, 42],
+ [17, 50, 22, 6, 51, 23],
+ [19, 46, 16, 6, 47, 17],
+
+ // 22
+ [2, 139, 111, 7, 140, 112],
+ [17, 74, 46],
+ [7, 54, 24, 16, 55, 25],
+ [34, 37, 13],
+
+ // 23
+ [4, 151, 121, 5, 152, 122],
+ [4, 75, 47, 14, 76, 48],
+ [11, 54, 24, 14, 55, 25],
+ [16, 45, 15, 14, 46, 16],
+
+ // 24
+ [6, 147, 117, 4, 148, 118],
+ [6, 73, 45, 14, 74, 46],
+ [11, 54, 24, 16, 55, 25],
+ [30, 46, 16, 2, 47, 17],
+
+ // 25
+ [8, 132, 106, 4, 133, 107],
+ [8, 75, 47, 13, 76, 48],
+ [7, 54, 24, 22, 55, 25],
+ [22, 45, 15, 13, 46, 16],
+
+ // 26
+ [10, 142, 114, 2, 143, 115],
+ [19, 74, 46, 4, 75, 47],
+ [28, 50, 22, 6, 51, 23],
+ [33, 46, 16, 4, 47, 17],
+
+ // 27
+ [8, 152, 122, 4, 153, 123],
+ [22, 73, 45, 3, 74, 46],
+ [8, 53, 23, 26, 54, 24],
+ [12, 45, 15, 28, 46, 16],
+
+ // 28
+ [3, 147, 117, 10, 148, 118],
+ [3, 73, 45, 23, 74, 46],
+ [4, 54, 24, 31, 55, 25],
+ [11, 45, 15, 31, 46, 16],
+
+ // 29
+ [7, 146, 116, 7, 147, 117],
+ [21, 73, 45, 7, 74, 46],
+ [1, 53, 23, 37, 54, 24],
+ [19, 45, 15, 26, 46, 16],
+
+ // 30
+ [5, 145, 115, 10, 146, 116],
+ [19, 75, 47, 10, 76, 48],
+ [15, 54, 24, 25, 55, 25],
+ [23, 45, 15, 25, 46, 16],
+
+ // 31
+ [13, 145, 115, 3, 146, 116],
+ [2, 74, 46, 29, 75, 47],
+ [42, 54, 24, 1, 55, 25],
+ [23, 45, 15, 28, 46, 16],
+
+ // 32
+ [17, 145, 115],
+ [10, 74, 46, 23, 75, 47],
+ [10, 54, 24, 35, 55, 25],
+ [19, 45, 15, 35, 46, 16],
+
+ // 33
+ [17, 145, 115, 1, 146, 116],
+ [14, 74, 46, 21, 75, 47],
+ [29, 54, 24, 19, 55, 25],
+ [11, 45, 15, 46, 46, 16],
+
+ // 34
+ [13, 145, 115, 6, 146, 116],
+ [14, 74, 46, 23, 75, 47],
+ [44, 54, 24, 7, 55, 25],
+ [59, 46, 16, 1, 47, 17],
+
+ // 35
+ [12, 151, 121, 7, 152, 122],
+ [12, 75, 47, 26, 76, 48],
+ [39, 54, 24, 14, 55, 25],
+ [22, 45, 15, 41, 46, 16],
+
+ // 36
+ [6, 151, 121, 14, 152, 122],
+ [6, 75, 47, 34, 76, 48],
+ [46, 54, 24, 10, 55, 25],
+ [2, 45, 15, 64, 46, 16],
+
+ // 37
+ [17, 152, 122, 4, 153, 123],
+ [29, 74, 46, 14, 75, 47],
+ [49, 54, 24, 10, 55, 25],
+ [24, 45, 15, 46, 46, 16],
+
+ // 38
+ [4, 152, 122, 18, 153, 123],
+ [13, 74, 46, 32, 75, 47],
+ [48, 54, 24, 14, 55, 25],
+ [42, 45, 15, 32, 46, 16],
+
+ // 39
+ [20, 147, 117, 4, 148, 118],
+ [40, 75, 47, 7, 76, 48],
+ [43, 54, 24, 22, 55, 25],
+ [10, 45, 15, 67, 46, 16],
+
+ // 40
+ [19, 148, 118, 6, 149, 119],
+ [18, 75, 47, 31, 76, 48],
+ [34, 54, 24, 34, 55, 25],
+ [20, 45, 15, 61, 46, 16],
+ ];
+
+ QRRSBlock.getRSBlocks = function (typeNumber, errorCorrectLevel) {
+ var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel);
+
+ if (rsBlock == undefined) {
+ throw new Error(
+ 'bad rs block @ typeNumber:' + typeNumber + '/errorCorrectLevel:' + errorCorrectLevel
+ )
+ }
+
+ var length = rsBlock.length / 3;
+
+ var list = new Array();
+
+ for (var i = 0; i < length; i++) {
+ var count = rsBlock[i * 3 + 0];
+ var totalCount = rsBlock[i * 3 + 1];
+ var dataCount = rsBlock[i * 3 + 2];
+
+ for (var j = 0; j < count; j++) {
+ list.push(new QRRSBlock(totalCount, dataCount));
+ }
+ }
+
+ return list
+ };
+
+ QRRSBlock.getRsBlockTable = function (typeNumber, errorCorrectLevel) {
+ switch (errorCorrectLevel) {
+ case ErrorCorrectLevel.L:
+ return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0]
+ case ErrorCorrectLevel.M:
+ return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1]
+ case ErrorCorrectLevel.Q:
+ return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2]
+ case ErrorCorrectLevel.H:
+ return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3]
+ default:
+ return undefined
+ }
+ };
+
+ function QRBitBuffer() {
+ this.buffer = new Array();
+ this.length = 0;
+ }
+
+ QRBitBuffer.prototype = {
+ get: function (index) {
+ var bufIndex = Math.floor(index / 8);
+ return ((this.buffer[bufIndex] >>> (7 - (index % 8))) & 1) == 1
+ },
+
+ put: function (num, length) {
+ for (var i = 0; i < length; i++) {
+ this.putBit(((num >>> (length - i - 1)) & 1) == 1);
+ }
+ },
+
+ getLengthInBits: function () {
+ return this.length
+ },
+
+ putBit: function (bit) {
+ var bufIndex = Math.floor(this.length / 8);
+ if (this.buffer.length <= bufIndex) {
+ this.buffer.push(0);
+ }
+
+ if (bit) {
+ this.buffer[bufIndex] |= 0x80 >>> this.length % 8;
+ }
+
+ this.length++;
+ },
+ };
+
+ const QRMath = {
+ glog: function (n) {
+ if (n < 1) {
+ throw new Error('glog(' + n + ')')
+ }
+
+ return QRMath.LOG_TABLE[n]
+ },
+
+ gexp: function (n) {
+ while (n < 0) {
+ n += 255;
+ }
+
+ while (n >= 256) {
+ n -= 255;
+ }
+
+ return QRMath.EXP_TABLE[n]
+ },
+
+ EXP_TABLE: new Array(256),
+
+ LOG_TABLE: new Array(256),
+ };
+
+ for (var i = 0; i < 8; i++) {
+ QRMath.EXP_TABLE[i] = 1 << i;
+ }
+ for (var i = 8; i < 256; i++) {
+ QRMath.EXP_TABLE[i] =
+ QRMath.EXP_TABLE[i - 4] ^
+ QRMath.EXP_TABLE[i - 5] ^
+ QRMath.EXP_TABLE[i - 6] ^
+ QRMath.EXP_TABLE[i - 8];
+ }
+ for (var i = 0; i < 255; i++) {
+ QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i;
+ }
+
+ function QRPolynomial(num, shift) {
+ if (num.length == undefined) {
+ throw new Error(num.length + '/' + shift)
+ }
+
+ var offset = 0;
+
+ while (offset < num.length && num[offset] == 0) {
+ offset++;
+ }
+
+ this.num = new Array(num.length - offset + shift);
+ for (var i = 0; i < num.length - offset; i++) {
+ this.num[i] = num[i + offset];
+ }
+ }
+
+ QRPolynomial.prototype = {
+ get: function (index) {
+ return this.num[index]
+ },
+
+ getLength: function () {
+ return this.num.length
+ },
+
+ multiply: function (e) {
+ var num = new Array(this.getLength() + e.getLength() - 1);
+
+ for (var i = 0; i < this.getLength(); i++) {
+ for (var j = 0; j < e.getLength(); j++) {
+ num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j)));
+ }
+ }
+
+ return new QRPolynomial(num, 0)
+ },
+
+ mod: function (e) {
+ if (this.getLength() - e.getLength() < 0) {
+ return this
+ }
+
+ var ratio = QRMath.glog(this.get(0)) - QRMath.glog(e.get(0));
+
+ var num = new Array(this.getLength());
+
+ for (var i = 0; i < this.getLength(); i++) {
+ num[i] = this.get(i);
+ }
+
+ for (var i = 0; i < e.getLength(); i++) {
+ num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio);
+ }
+
+ // recursive call
+ return new QRPolynomial(num, 0).mod(e)
+ },
+ };
+
+ const QRMaskPattern = {
+ PATTERN000: 0,
+ PATTERN001: 1,
+ PATTERN010: 2,
+ PATTERN011: 3,
+ PATTERN100: 4,
+ PATTERN101: 5,
+ PATTERN110: 6,
+ PATTERN111: 7,
+ };
+
+ const QRUtil = {
+ PATTERN_POSITION_TABLE: [
+ [],
+ [6, 18],
+ [6, 22],
+ [6, 26],
+ [6, 30],
+ [6, 34],
+ [6, 22, 38],
+ [6, 24, 42],
+ [6, 26, 46],
+ [6, 28, 50],
+ [6, 30, 54],
+ [6, 32, 58],
+ [6, 34, 62],
+ [6, 26, 46, 66],
+ [6, 26, 48, 70],
+ [6, 26, 50, 74],
+ [6, 30, 54, 78],
+ [6, 30, 56, 82],
+ [6, 30, 58, 86],
+ [6, 34, 62, 90],
+ [6, 28, 50, 72, 94],
+ [6, 26, 50, 74, 98],
+ [6, 30, 54, 78, 102],
+ [6, 28, 54, 80, 106],
+ [6, 32, 58, 84, 110],
+ [6, 30, 58, 86, 114],
+ [6, 34, 62, 90, 118],
+ [6, 26, 50, 74, 98, 122],
+ [6, 30, 54, 78, 102, 126],
+ [6, 26, 52, 78, 104, 130],
+ [6, 30, 56, 82, 108, 134],
+ [6, 34, 60, 86, 112, 138],
+ [6, 30, 58, 86, 114, 142],
+ [6, 34, 62, 90, 118, 146],
+ [6, 30, 54, 78, 102, 126, 150],
+ [6, 24, 50, 76, 102, 128, 154],
+ [6, 28, 54, 80, 106, 132, 158],
+ [6, 32, 58, 84, 110, 136, 162],
+ [6, 26, 54, 82, 110, 138, 166],
+ [6, 30, 58, 86, 114, 142, 170],
+ ],
+
+ G15: (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
+ G18: (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0),
+ G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
+
+ getBCHTypeInfo: function (data) {
+ var d = data << 10;
+ while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
+ d ^= QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15));
+ }
+ return ((data << 10) | d) ^ QRUtil.G15_MASK
+ },
+
+ getBCHTypeNumber: function (data) {
+ var d = data << 12;
+ while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
+ d ^= QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18));
+ }
+ return (data << 12) | d
+ },
+
+ getBCHDigit: function (data) {
+ var digit = 0;
+
+ while (data != 0) {
+ digit++;
+ data >>>= 1;
+ }
+
+ return digit
+ },
+
+ getPatternPosition: function (typeNumber) {
+ return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1]
+ },
+
+ getMask: function (maskPattern, i, j) {
+ switch (maskPattern) {
+ case QRMaskPattern.PATTERN000:
+ return (i + j) % 2 == 0
+ case QRMaskPattern.PATTERN001:
+ return i % 2 == 0
+ case QRMaskPattern.PATTERN010:
+ return j % 3 == 0
+ case QRMaskPattern.PATTERN011:
+ return (i + j) % 3 == 0
+ case QRMaskPattern.PATTERN100:
+ return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0
+ case QRMaskPattern.PATTERN101:
+ return ((i * j) % 2) + ((i * j) % 3) == 0
+ case QRMaskPattern.PATTERN110:
+ return (((i * j) % 2) + ((i * j) % 3)) % 2 == 0
+ case QRMaskPattern.PATTERN111:
+ return (((i * j) % 3) + ((i + j) % 2)) % 2 == 0
+
+ default:
+ throw new Error('bad maskPattern:' + maskPattern)
+ }
+ },
+
+ getErrorCorrectPolynomial: function (errorCorrectLength) {
+ var a = new QRPolynomial([1], 0);
+
+ for (var i = 0; i < errorCorrectLength; i++) {
+ a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0));
+ }
+
+ return a
+ },
+
+ getLengthInBits: function (mode, type) {
+ if (1 <= type && type < 10) {
+ // 1 - 9
+
+ switch (mode) {
+ case Mode.MODE_NUMBER:
+ return 10
+ case Mode.MODE_ALPHA_NUM:
+ return 9
+ case Mode.MODE_8BIT_BYTE:
+ return 8
+ case Mode.MODE_KANJI:
+ return 8
+ default:
+ throw new Error('mode:' + mode)
+ }
+ } else if (type < 27) {
+ // 10 - 26
+
+ switch (mode) {
+ case Mode.MODE_NUMBER:
+ return 12
+ case Mode.MODE_ALPHA_NUM:
+ return 11
+ case Mode.MODE_8BIT_BYTE:
+ return 16
+ case Mode.MODE_KANJI:
+ return 10
+ default:
+ throw new Error('mode:' + mode)
+ }
+ } else if (type < 41) {
+ // 27 - 40
+
+ switch (mode) {
+ case Mode.MODE_NUMBER:
+ return 14
+ case Mode.MODE_ALPHA_NUM:
+ return 13
+ case Mode.MODE_8BIT_BYTE:
+ return 16
+ case Mode.MODE_KANJI:
+ return 12
+ default:
+ throw new Error('mode:' + mode)
+ }
+ } else {
+ throw new Error('type:' + type)
+ }
+ },
+
+ getLostPoint: function (qrCode) {
+ var moduleCount = qrCode.getModuleCount();
+
+ var lostPoint = 0;
+
+ // LEVEL1
+
+ for (var row = 0; row < moduleCount; row++) {
+ for (var col = 0; col < moduleCount; col++) {
+ var sameCount = 0;
+ var dark = qrCode.isDark(row, col);
+
+ for (var r = -1; r <= 1; r++) {
+ if (row + r < 0 || moduleCount <= row + r) {
+ continue
+ }
+
+ for (var c = -1; c <= 1; c++) {
+ if (col + c < 0 || moduleCount <= col + c) {
+ continue
+ }
+
+ if (r == 0 && c == 0) {
+ continue
+ }
+
+ if (dark == qrCode.isDark(row + r, col + c)) {
+ sameCount++;
+ }
+ }
+ }
+
+ if (sameCount > 5) {
+ lostPoint += 3 + sameCount - 5;
+ }
+ }
+ }
+
+ // LEVEL2
+
+ for (var row = 0; row < moduleCount - 1; row++) {
+ for (var col = 0; col < moduleCount - 1; col++) {
+ var count = 0;
+ if (qrCode.isDark(row, col)) count++;
+ if (qrCode.isDark(row + 1, col)) count++;
+ if (qrCode.isDark(row, col + 1)) count++;
+ if (qrCode.isDark(row + 1, col + 1)) count++;
+ if (count == 0 || count == 4) {
+ lostPoint += 3;
+ }
+ }
+ }
+
+ // LEVEL3
+
+ for (var row = 0; row < moduleCount; row++) {
+ for (var col = 0; col < moduleCount - 6; col++) {
+ if (
+ qrCode.isDark(row, col) &&
+ !qrCode.isDark(row, col + 1) &&
+ qrCode.isDark(row, col + 2) &&
+ qrCode.isDark(row, col + 3) &&
+ qrCode.isDark(row, col + 4) &&
+ !qrCode.isDark(row, col + 5) &&
+ qrCode.isDark(row, col + 6)
+ ) {
+ lostPoint += 40;
+ }
+ }
+ }
+
+ for (var col = 0; col < moduleCount; col++) {
+ for (var row = 0; row < moduleCount - 6; row++) {
+ if (
+ qrCode.isDark(row, col) &&
+ !qrCode.isDark(row + 1, col) &&
+ qrCode.isDark(row + 2, col) &&
+ qrCode.isDark(row + 3, col) &&
+ qrCode.isDark(row + 4, col) &&
+ !qrCode.isDark(row + 5, col) &&
+ qrCode.isDark(row + 6, col)
+ ) {
+ lostPoint += 40;
+ }
+ }
+ }
+
+ // LEVEL4
+
+ var darkCount = 0;
+
+ for (var col = 0; col < moduleCount; col++) {
+ for (var row = 0; row < moduleCount; row++) {
+ if (qrCode.isDark(row, col)) {
+ darkCount++;
+ }
+ }
+ }
+
+ var ratio = Math.abs((100 * darkCount) / moduleCount / moduleCount - 50) / 5;
+ lostPoint += ratio * 10;
+
+ return lostPoint
+ },
+ };
+
+ function QRCode(typeNumber, errorCorrectLevel) {
+ this.typeNumber = typeNumber;
+ this.errorCorrectLevel = errorCorrectLevel;
+ this.modules = null;
+ this.moduleCount = 0;
+ this.dataCache = null;
+ this.dataList = [];
+ }
+
+ // for client side minification
+ var proto = QRCode.prototype;
+
+ proto.addData = function (data) {
+ var newData = new QR8bitByte(data);
+ this.dataList.push(newData);
+ this.dataCache = null;
+ };
+
+ proto.isDark = function (row, col) {
+ if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) {
+ throw new Error(row + ',' + col)
+ }
+ return this.modules[row][col]
+ };
+
+ proto.getModuleCount = function () {
+ return this.moduleCount
+ };
+
+ proto.make = function () {
+ // Calculate automatically typeNumber if provided is < 1
+ if (this.typeNumber < 1) {
+ var typeNumber = 1;
+ for (typeNumber = 1; typeNumber < 40; typeNumber++) {
+ var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, this.errorCorrectLevel);
+
+ var buffer = new QRBitBuffer();
+ var totalDataCount = 0;
+ for (var i = 0; i < rsBlocks.length; i++) {
+ totalDataCount += rsBlocks[i].dataCount;
+ }
+
+ for (var i = 0; i < this.dataList.length; i++) {
+ var data = this.dataList[i];
+ buffer.put(data.mode, 4);
+ buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber));
+ data.write(buffer);
+ }
+ if (buffer.getLengthInBits() <= totalDataCount * 8) break
+ }
+ this.typeNumber = typeNumber;
+ }
+ this.makeImpl(false, this.getBestMaskPattern());
+ };
+
+ proto.makeImpl = function (test, maskPattern) {
+ this.moduleCount = this.typeNumber * 4 + 17;
+ this.modules = new Array(this.moduleCount);
+
+ for (var row = 0; row < this.moduleCount; row++) {
+ this.modules[row] = new Array(this.moduleCount);
+
+ for (var col = 0; col < this.moduleCount; col++) {
+ this.modules[row][col] = null; //(col + row) % 3;
+ }
+ }
+
+ this.setupPositionProbePattern(0, 0);
+ this.setupPositionProbePattern(this.moduleCount - 7, 0);
+ this.setupPositionProbePattern(0, this.moduleCount - 7);
+ this.setupPositionAdjustPattern();
+ this.setupTimingPattern();
+ this.setupTypeInfo(test, maskPattern);
+
+ if (this.typeNumber >= 7) {
+ this.setupTypeNumber(test);
+ }
+
+ if (this.dataCache == null) {
+ this.dataCache = QRCode.createData(this.typeNumber, this.errorCorrectLevel, this.dataList);
+ }
+
+ this.mapData(this.dataCache, maskPattern);
+ };
+
+ proto.setupPositionProbePattern = function (row, col) {
+ for (var r = -1; r <= 7; r++) {
+ if (row + r <= -1 || this.moduleCount <= row + r) continue
+
+ for (var c = -1; c <= 7; c++) {
+ if (col + c <= -1 || this.moduleCount <= col + c) continue
+
+ if (
+ (0 <= r && r <= 6 && (c == 0 || c == 6)) ||
+ (0 <= c && c <= 6 && (r == 0 || r == 6)) ||
+ (2 <= r && r <= 4 && 2 <= c && c <= 4)
+ ) {
+ this.modules[row + r][col + c] = true;
+ } else {
+ this.modules[row + r][col + c] = false;
+ }
+ }
+ }
+ };
+
+ proto.getBestMaskPattern = function () {
+ var minLostPoint = 0;
+ var pattern = 0;
+
+ for (var i = 0; i < 8; i++) {
+ this.makeImpl(true, i);
+
+ var lostPoint = QRUtil.getLostPoint(this);
+
+ if (i == 0 || minLostPoint > lostPoint) {
+ minLostPoint = lostPoint;
+ pattern = i;
+ }
+ }
+
+ return pattern
+ };
+
+ proto.setupTimingPattern = function () {
+ for (var r = 8; r < this.moduleCount - 8; r++) {
+ if (this.modules[r][6] != null) {
+ continue
+ }
+ this.modules[r][6] = r % 2 == 0;
+ }
+
+ for (var c = 8; c < this.moduleCount - 8; c++) {
+ if (this.modules[6][c] != null) {
+ continue
+ }
+ this.modules[6][c] = c % 2 == 0;
+ }
+ };
+
+ proto.setupPositionAdjustPattern = function () {
+ var pos = QRUtil.getPatternPosition(this.typeNumber);
+
+ for (var i = 0; i < pos.length; i++) {
+ for (var j = 0; j < pos.length; j++) {
+ var row = pos[i];
+ var col = pos[j];
+
+ if (this.modules[row][col] != null) {
+ continue
+ }
+
+ for (var r = -2; r <= 2; r++) {
+ for (var c = -2; c <= 2; c++) {
+ if (r == -2 || r == 2 || c == -2 || c == 2 || (r == 0 && c == 0)) {
+ this.modules[row + r][col + c] = true;
+ } else {
+ this.modules[row + r][col + c] = false;
+ }
+ }
+ }
+ }
+ }
+ };
+
+ proto.setupTypeNumber = function (test) {
+ var bits = QRUtil.getBCHTypeNumber(this.typeNumber);
+
+ for (var i = 0; i < 18; i++) {
+ var mod = !test && ((bits >> i) & 1) == 1;
+ this.modules[Math.floor(i / 3)][(i % 3) + this.moduleCount - 8 - 3] = mod;
+ }
+
+ for (var i = 0; i < 18; i++) {
+ var mod = !test && ((bits >> i) & 1) == 1;
+ this.modules[(i % 3) + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
+ }
+ };
+
+ proto.setupTypeInfo = function (test, maskPattern) {
+ var data = (this.errorCorrectLevel << 3) | maskPattern;
+ var bits = QRUtil.getBCHTypeInfo(data);
+
+ // vertical
+ for (var i = 0; i < 15; i++) {
+ var mod = !test && ((bits >> i) & 1) == 1;
+
+ if (i < 6) {
+ this.modules[i][8] = mod;
+ } else if (i < 8) {
+ this.modules[i + 1][8] = mod;
+ } else {
+ this.modules[this.moduleCount - 15 + i][8] = mod;
+ }
+ }
+
+ // horizontal
+ for (var i = 0; i < 15; i++) {
+ var mod = !test && ((bits >> i) & 1) == 1;
+
+ if (i < 8) {
+ this.modules[8][this.moduleCount - i - 1] = mod;
+ } else if (i < 9) {
+ this.modules[8][15 - i - 1 + 1] = mod;
+ } else {
+ this.modules[8][15 - i - 1] = mod;
+ }
+ }
+
+ // fixed module
+ this.modules[this.moduleCount - 8][8] = !test;
+ };
+
+ proto.mapData = function (data, maskPattern) {
+ var inc = -1;
+ var row = this.moduleCount - 1;
+ var bitIndex = 7;
+ var byteIndex = 0;
+
+ for (var col = this.moduleCount - 1; col > 0; col -= 2) {
+ if (col == 6) col--;
+
+ while (true) {
+ for (var c = 0; c < 2; c++) {
+ if (this.modules[row][col - c] == null) {
+ var dark = false;
+
+ if (byteIndex < data.length) {
+ dark = ((data[byteIndex] >>> bitIndex) & 1) == 1;
+ }
+
+ var mask = QRUtil.getMask(maskPattern, row, col - c);
+
+ if (mask) {
+ dark = !dark;
+ }
+
+ this.modules[row][col - c] = dark;
+ bitIndex--;
+
+ if (bitIndex == -1) {
+ byteIndex++;
+ bitIndex = 7;
+ }
+ }
+ }
+
+ row += inc;
+
+ if (row < 0 || this.moduleCount <= row) {
+ row -= inc;
+ inc = -inc;
+ break
+ }
+ }
+ }
+ };
+
+ QRCode.PAD0 = 0xec;
+ QRCode.PAD1 = 0x11;
+
+ QRCode.createData = function (typeNumber, errorCorrectLevel, dataList) {
+ var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel);
+
+ var buffer = new QRBitBuffer();
+
+ for (var i = 0; i < dataList.length; i++) {
+ var data = dataList[i];
+ buffer.put(data.mode, 4);
+ buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber));
+ data.write(buffer);
+ }
+
+ // calc num max data.
+ var totalDataCount = 0;
+ for (var i = 0; i < rsBlocks.length; i++) {
+ totalDataCount += rsBlocks[i].dataCount;
+ }
+
+ if (buffer.getLengthInBits() > totalDataCount * 8) {
+ throw new Error(
+ 'code length overflow. (' + buffer.getLengthInBits() + '>' + totalDataCount * 8 + ')'
+ )
+ }
+
+ // end code
+ if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
+ buffer.put(0, 4);
+ }
+
+ // padding
+ while (buffer.getLengthInBits() % 8 != 0) {
+ buffer.putBit(false);
+ }
+
+ // padding
+ while (true) {
+ if (buffer.getLengthInBits() >= totalDataCount * 8) {
+ break
+ }
+ buffer.put(QRCode.PAD0, 8);
+
+ if (buffer.getLengthInBits() >= totalDataCount * 8) {
+ break
+ }
+ buffer.put(QRCode.PAD1, 8);
+ }
+
+ return QRCode.createBytes(buffer, rsBlocks)
+ };
+
+ QRCode.createBytes = function (buffer, rsBlocks) {
+ var offset = 0;
+
+ var maxDcCount = 0;
+ var maxEcCount = 0;
+
+ var dcdata = new Array(rsBlocks.length);
+ var ecdata = new Array(rsBlocks.length);
+
+ for (var r = 0; r < rsBlocks.length; r++) {
+ var dcCount = rsBlocks[r].dataCount;
+ var ecCount = rsBlocks[r].totalCount - dcCount;
+
+ maxDcCount = Math.max(maxDcCount, dcCount);
+ maxEcCount = Math.max(maxEcCount, ecCount);
+
+ dcdata[r] = new Array(dcCount);
+
+ for (var i = 0; i < dcdata[r].length; i++) {
+ dcdata[r][i] = 0xff & buffer.buffer[i + offset];
+ }
+ offset += dcCount;
+
+ var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
+ var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1);
+
+ var modPoly = rawPoly.mod(rsPoly);
+ ecdata[r] = new Array(rsPoly.getLength() - 1);
+ for (var i = 0; i < ecdata[r].length; i++) {
+ var modIndex = i + modPoly.getLength() - ecdata[r].length;
+ ecdata[r][i] = modIndex >= 0 ? modPoly.get(modIndex) : 0;
+ }
+ }
+
+ var totalCodeCount = 0;
+ for (var i = 0; i < rsBlocks.length; i++) {
+ totalCodeCount += rsBlocks[i].totalCount;
+ }
+
+ var data = new Array(totalCodeCount);
+ var index = 0;
+
+ for (var i = 0; i < maxDcCount; i++) {
+ for (var r = 0; r < rsBlocks.length; r++) {
+ if (i < dcdata[r].length) {
+ data[index++] = dcdata[r][i];
+ }
+ }
+ }
+
+ for (var i = 0; i < maxEcCount; i++) {
+ for (var r = 0; r < rsBlocks.length; r++) {
+ if (i < ecdata[r].length) {
+ data[index++] = ecdata[r][i];
+ }
+ }
+ }
+
+ return data
+ };
+
+ /* node_modules/svelte-qr/src/QR.svelte generated by Svelte v3.55.1 */
+
+ function get_each_context$2(ctx, list, i) {
+ const child_ctx = ctx.slice();
+ child_ctx[5] = list[i];
+ return child_ctx;
+ }
+
+ // (48:4) {#each rects as rect}
+ function create_each_block$2(ctx) {
+ let rect;
+ let rect_levels = [/*rect*/ ctx[5]];
+ let rect_data = {};
+
+ for (let i = 0; i < rect_levels.length; i += 1) {
+ rect_data = assign(rect_data, rect_levels[i]);
+ }
+
+ return {
+ c() {
+ rect = svg_element("rect");
+ set_svg_attributes(rect, rect_data);
+ toggle_class(rect, "svelte-2fcki1", true);
+ },
+ m(target, anchor) {
+ insert(target, rect, anchor);
+ },
+ p(ctx, dirty) {
+ set_svg_attributes(rect, rect_data = get_spread_update(rect_levels, [/*rect*/ ctx[5]]));
+ toggle_class(rect, "svelte-2fcki1", true);
+ },
+ d(detaching) {
+ if (detaching) detach(rect);
+ }
+ };
+ }
+
+ function create_fragment$5(ctx) {
+ let svg;
+ let svg_viewBox_value;
+ let each_value = /*rects*/ ctx[1];
+ let each_blocks = [];
+
+ for (let i = 0; i < each_value.length; i += 1) {
+ each_blocks[i] = create_each_block$2(get_each_context$2(ctx, each_value, i));
+ }
+
+ return {
+ c() {
+ svg = svg_element("svg");
+
+ for (let i = 0; i < each_blocks.length; i += 1) {
+ each_blocks[i].c();
+ }
+
+ attr(svg, "class", "qr svelte-2fcki1");
+ attr(svg, "xmlns", "http://www.w3.org/2000/svg");
+ attr(svg, "viewBox", svg_viewBox_value = "0 0 " + /*size*/ ctx[0] + " " + /*size*/ ctx[0]);
+ },
+ m(target, anchor) {
+ insert(target, svg, anchor);
+
+ for (let i = 0; i < each_blocks.length; i += 1) {
+ each_blocks[i].m(svg, null);
+ }
+ },
+ p(ctx, [dirty]) {
+ if (dirty & /*rects*/ 2) {
+ each_value = /*rects*/ ctx[1];
+ let i;
+
+ for (i = 0; i < each_value.length; i += 1) {
+ const child_ctx = get_each_context$2(ctx, each_value, i);
+
+ if (each_blocks[i]) {
+ each_blocks[i].p(child_ctx, dirty);
+ } else {
+ each_blocks[i] = create_each_block$2(child_ctx);
+ each_blocks[i].c();
+ each_blocks[i].m(svg, null);
+ }
+ }
+
+ for (; i < each_blocks.length; i += 1) {
+ each_blocks[i].d(1);
+ }
+
+ each_blocks.length = each_value.length;
+ }
+
+ if (dirty & /*size*/ 1 && svg_viewBox_value !== (svg_viewBox_value = "0 0 " + /*size*/ ctx[0] + " " + /*size*/ ctx[0])) {
+ attr(svg, "viewBox", svg_viewBox_value);
+ }
+ },
+ i: noop,
+ o: noop,
+ d(detaching) {
+ if (detaching) detach(svg);
+ destroy_each(each_blocks, detaching);
+ }
+ };
+ }
+
+ function instance$5($$self, $$props, $$invalidate) {
+ let { text } = $$props;
+ let { level = "L" } = $$props;
+ let { version = -1 } = $$props;
+ let size;
+ let rects = [];
+
+ $$self.$$set = $$props => {
+ if ('text' in $$props) $$invalidate(2, text = $$props.text);
+ if ('level' in $$props) $$invalidate(3, level = $$props.level);
+ if ('version' in $$props) $$invalidate(4, version = $$props.version);
+ };
+
+ $$self.$$.update = () => {
+ if ($$self.$$.dirty & /*version, level, text*/ 28) {
+ {
+ let qr = new QRCode(version, ErrorCorrectLevel[level]);
+ qr.addData(text);
+ qr.make();
+ const rows = qr.modules;
+ $$invalidate(0, size = rows.length);
+
+ for (const [y, row] of rows.entries()) {
+ let rect;
+
+ for (const [x, on] of row.entries()) {
+ if (on) {
+ if (!rect) rect = { x, y, width: 0, height: 1 };
+ rect.width++;
+ } else {
+ if (rect && rect.width > 0) {
+ rects.push(rect);
+ }
+
+ rect = void 0;
+ }
+ }
+
+ if (rect && rect.width > 0) {
+ rects.push(rect);
+ }
+ }
+ }
+ }
+ };
+
+ return [size, rects, text, level, version];
+ }
+
+ class QR extends SvelteComponent {
+ constructor(options) {
+ super();
+ init(this, options, instance$5, create_fragment$5, safe_not_equal, { text: 2, level: 3, version: 4 });
+ }
+ }
+
+ var _nodeResolve_empty = {};
+
+ var nodeCrypto = /*#__PURE__*/Object.freeze({
+ __proto__: null,
+ default: _nodeResolve_empty
+ });
+
+ /*! noble-secp256k1 - MIT License (c) 2019 Paul Miller (paulmillr.com) */
+ const _0n = BigInt(0);
+ const _1n = BigInt(1);
+ const _2n = BigInt(2);
+ const _3n = BigInt(3);
+ const _8n = BigInt(8);
+ const CURVE = Object.freeze({
+ a: _0n,
+ b: BigInt(7),
+ P: BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f'),
+ n: BigInt('0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141'),
+ h: _1n,
+ Gx: BigInt('55066263022277343669578718895168534326250603453777594175500187360389116729240'),
+ Gy: BigInt('32670510020758816978083085130507043184471273380659243275938904335757337482424'),
+ beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),
+ });
+ const divNearest = (a, b) => (a + b / _2n) / b;
+ const endo = {
+ beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),
+ splitScalar(k) {
+ const { n } = CURVE;
+ const a1 = BigInt('0x3086d221a7d46bcde86c90e49284eb15');
+ const b1 = -_1n * BigInt('0xe4437ed6010e88286f547fa90abfe4c3');
+ const a2 = BigInt('0x114ca50f7a8e2f3f657c1108d9d44cfd8');
+ const b2 = a1;
+ const POW_2_128 = BigInt('0x100000000000000000000000000000000');
+ const c1 = divNearest(b2 * k, n);
+ const c2 = divNearest(-b1 * k, n);
+ let k1 = mod(k - c1 * a1 - c2 * a2, n);
+ let k2 = mod(-c1 * b1 - c2 * b2, n);
+ const k1neg = k1 > POW_2_128;
+ const k2neg = k2 > POW_2_128;
+ if (k1neg)
+ k1 = n - k1;
+ if (k2neg)
+ k2 = n - k2;
+ if (k1 > POW_2_128 || k2 > POW_2_128) {
+ throw new Error('splitScalarEndo: Endomorphism failed, k=' + k);
+ }
+ return { k1neg, k1, k2neg, k2 };
+ },
+ };
+ const fieldLen = 32;
+ const groupLen = 32;
+ const hashLen = 32;
+ const compressedLen = fieldLen + 1;
+ const uncompressedLen = 2 * fieldLen + 1;
+ function weierstrass(x) {
+ const { a, b } = CURVE;
+ const x2 = mod(x * x);
+ const x3 = mod(x2 * x);
+ return mod(x3 + a * x + b);
+ }
+ const USE_ENDOMORPHISM = CURVE.a === _0n;
+ class ShaError extends Error {
+ constructor(message) {
+ super(message);
+ }
+ }
+ function assertJacPoint(other) {
+ if (!(other instanceof JacobianPoint))
+ throw new TypeError('JacobianPoint expected');
+ }
+ class JacobianPoint {
+ constructor(x, y, z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+ static fromAffine(p) {
+ if (!(p instanceof Point)) {
+ throw new TypeError('JacobianPoint#fromAffine: expected Point');
+ }
+ if (p.equals(Point.ZERO))
+ return JacobianPoint.ZERO;
+ return new JacobianPoint(p.x, p.y, _1n);
+ }
+ static toAffineBatch(points) {
+ const toInv = invertBatch(points.map((p) => p.z));
+ return points.map((p, i) => p.toAffine(toInv[i]));
+ }
+ static normalizeZ(points) {
+ return JacobianPoint.toAffineBatch(points).map(JacobianPoint.fromAffine);
+ }
+ equals(other) {
+ assertJacPoint(other);
+ const { x: X1, y: Y1, z: Z1 } = this;
+ const { x: X2, y: Y2, z: Z2 } = other;
+ const Z1Z1 = mod(Z1 * Z1);
+ const Z2Z2 = mod(Z2 * Z2);
+ const U1 = mod(X1 * Z2Z2);
+ const U2 = mod(X2 * Z1Z1);
+ const S1 = mod(mod(Y1 * Z2) * Z2Z2);
+ const S2 = mod(mod(Y2 * Z1) * Z1Z1);
+ return U1 === U2 && S1 === S2;
+ }
+ negate() {
+ return new JacobianPoint(this.x, mod(-this.y), this.z);
+ }
+ double() {
+ const { x: X1, y: Y1, z: Z1 } = this;
+ const A = mod(X1 * X1);
+ const B = mod(Y1 * Y1);
+ const C = mod(B * B);
+ const x1b = X1 + B;
+ const D = mod(_2n * (mod(x1b * x1b) - A - C));
+ const E = mod(_3n * A);
+ const F = mod(E * E);
+ const X3 = mod(F - _2n * D);
+ const Y3 = mod(E * (D - X3) - _8n * C);
+ const Z3 = mod(_2n * Y1 * Z1);
+ return new JacobianPoint(X3, Y3, Z3);
+ }
+ add(other) {
+ assertJacPoint(other);
+ const { x: X1, y: Y1, z: Z1 } = this;
+ const { x: X2, y: Y2, z: Z2 } = other;
+ if (X2 === _0n || Y2 === _0n)
+ return this;
+ if (X1 === _0n || Y1 === _0n)
+ return other;
+ const Z1Z1 = mod(Z1 * Z1);
+ const Z2Z2 = mod(Z2 * Z2);
+ const U1 = mod(X1 * Z2Z2);
+ const U2 = mod(X2 * Z1Z1);
+ const S1 = mod(mod(Y1 * Z2) * Z2Z2);
+ const S2 = mod(mod(Y2 * Z1) * Z1Z1);
+ const H = mod(U2 - U1);
+ const r = mod(S2 - S1);
+ if (H === _0n) {
+ if (r === _0n) {
+ return this.double();
+ }
+ else {
+ return JacobianPoint.ZERO;
+ }
+ }
+ const HH = mod(H * H);
+ const HHH = mod(H * HH);
+ const V = mod(U1 * HH);
+ const X3 = mod(r * r - HHH - _2n * V);
+ const Y3 = mod(r * (V - X3) - S1 * HHH);
+ const Z3 = mod(Z1 * Z2 * H);
+ return new JacobianPoint(X3, Y3, Z3);
+ }
+ subtract(other) {
+ return this.add(other.negate());
+ }
+ multiplyUnsafe(scalar) {
+ const P0 = JacobianPoint.ZERO;
+ if (typeof scalar === 'bigint' && scalar === _0n)
+ return P0;
+ let n = normalizeScalar(scalar);
+ if (n === _1n)
+ return this;
+ if (!USE_ENDOMORPHISM) {
+ let p = P0;
+ let d = this;
+ while (n > _0n) {
+ if (n & _1n)
+ p = p.add(d);
+ d = d.double();
+ n >>= _1n;
+ }
+ return p;
+ }
+ let { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
+ let k1p = P0;
+ let k2p = P0;
+ let d = this;
+ while (k1 > _0n || k2 > _0n) {
+ if (k1 & _1n)
+ k1p = k1p.add(d);
+ if (k2 & _1n)
+ k2p = k2p.add(d);
+ d = d.double();
+ k1 >>= _1n;
+ k2 >>= _1n;
+ }
+ if (k1neg)
+ k1p = k1p.negate();
+ if (k2neg)
+ k2p = k2p.negate();
+ k2p = new JacobianPoint(mod(k2p.x * endo.beta), k2p.y, k2p.z);
+ return k1p.add(k2p);
+ }
+ precomputeWindow(W) {
+ const windows = USE_ENDOMORPHISM ? 128 / W + 1 : 256 / W + 1;
+ const points = [];
+ let p = this;
+ let base = p;
+ for (let window = 0; window < windows; window++) {
+ base = p;
+ points.push(base);
+ for (let i = 1; i < 2 ** (W - 1); i++) {
+ base = base.add(p);
+ points.push(base);
+ }
+ p = base.double();
+ }
+ return points;
+ }
+ wNAF(n, affinePoint) {
+ if (!affinePoint && this.equals(JacobianPoint.BASE))
+ affinePoint = Point.BASE;
+ const W = (affinePoint && affinePoint._WINDOW_SIZE) || 1;
+ if (256 % W) {
+ throw new Error('Point#wNAF: Invalid precomputation window, must be power of 2');
+ }
+ let precomputes = affinePoint && pointPrecomputes.get(affinePoint);
+ if (!precomputes) {
+ precomputes = this.precomputeWindow(W);
+ if (affinePoint && W !== 1) {
+ precomputes = JacobianPoint.normalizeZ(precomputes);
+ pointPrecomputes.set(affinePoint, precomputes);
+ }
+ }
+ let p = JacobianPoint.ZERO;
+ let f = JacobianPoint.BASE;
+ const windows = 1 + (USE_ENDOMORPHISM ? 128 / W : 256 / W);
+ const windowSize = 2 ** (W - 1);
+ const mask = BigInt(2 ** W - 1);
+ const maxNumber = 2 ** W;
+ const shiftBy = BigInt(W);
+ for (let window = 0; window < windows; window++) {
+ const offset = window * windowSize;
+ let wbits = Number(n & mask);
+ n >>= shiftBy;
+ if (wbits > windowSize) {
+ wbits -= maxNumber;
+ n += _1n;
+ }
+ const offset1 = offset;
+ const offset2 = offset + Math.abs(wbits) - 1;
+ const cond1 = window % 2 !== 0;
+ const cond2 = wbits < 0;
+ if (wbits === 0) {
+ f = f.add(constTimeNegate(cond1, precomputes[offset1]));
+ }
+ else {
+ p = p.add(constTimeNegate(cond2, precomputes[offset2]));
+ }
+ }
+ return { p, f };
+ }
+ multiply(scalar, affinePoint) {
+ let n = normalizeScalar(scalar);
+ let point;
+ let fake;
+ if (USE_ENDOMORPHISM) {
+ const { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
+ let { p: k1p, f: f1p } = this.wNAF(k1, affinePoint);
+ let { p: k2p, f: f2p } = this.wNAF(k2, affinePoint);
+ k1p = constTimeNegate(k1neg, k1p);
+ k2p = constTimeNegate(k2neg, k2p);
+ k2p = new JacobianPoint(mod(k2p.x * endo.beta), k2p.y, k2p.z);
+ point = k1p.add(k2p);
+ fake = f1p.add(f2p);
+ }
+ else {
+ const { p, f } = this.wNAF(n, affinePoint);
+ point = p;
+ fake = f;
+ }
+ return JacobianPoint.normalizeZ([point, fake])[0];
+ }
+ toAffine(invZ) {
+ const { x, y, z } = this;
+ const is0 = this.equals(JacobianPoint.ZERO);
+ if (invZ == null)
+ invZ = is0 ? _8n : invert(z);
+ const iz1 = invZ;
+ const iz2 = mod(iz1 * iz1);
+ const iz3 = mod(iz2 * iz1);
+ const ax = mod(x * iz2);
+ const ay = mod(y * iz3);
+ const zz = mod(z * iz1);
+ if (is0)
+ return Point.ZERO;
+ if (zz !== _1n)
+ throw new Error('invZ was invalid');
+ return new Point(ax, ay);
+ }
+ }
+ JacobianPoint.BASE = new JacobianPoint(CURVE.Gx, CURVE.Gy, _1n);
+ JacobianPoint.ZERO = new JacobianPoint(_0n, _1n, _0n);
+ function constTimeNegate(condition, item) {
+ const neg = item.negate();
+ return condition ? neg : item;
+ }
+ const pointPrecomputes = new WeakMap();
+ class Point {
+ constructor(x, y) {
+ this.x = x;
+ this.y = y;
+ }
+ _setWindowSize(windowSize) {
+ this._WINDOW_SIZE = windowSize;
+ pointPrecomputes.delete(this);
+ }
+ hasEvenY() {
+ return this.y % _2n === _0n;
+ }
+ static fromCompressedHex(bytes) {
+ const isShort = bytes.length === 32;
+ const x = bytesToNumber$1(isShort ? bytes : bytes.subarray(1));
+ if (!isValidFieldElement(x))
+ throw new Error('Point is not on curve');
+ const y2 = weierstrass(x);
+ let y = sqrtMod(y2);
+ const isYOdd = (y & _1n) === _1n;
+ if (isShort) {
+ if (isYOdd)
+ y = mod(-y);
+ }
+ else {
+ const isFirstByteOdd = (bytes[0] & 1) === 1;
+ if (isFirstByteOdd !== isYOdd)
+ y = mod(-y);
+ }
+ const point = new Point(x, y);
+ point.assertValidity();
+ return point;
+ }
+ static fromUncompressedHex(bytes) {
+ const x = bytesToNumber$1(bytes.subarray(1, fieldLen + 1));
+ const y = bytesToNumber$1(bytes.subarray(fieldLen + 1, fieldLen * 2 + 1));
+ const point = new Point(x, y);
+ point.assertValidity();
+ return point;
+ }
+ static fromHex(hex) {
+ const bytes = ensureBytes(hex);
+ const len = bytes.length;
+ const header = bytes[0];
+ if (len === fieldLen)
+ return this.fromCompressedHex(bytes);
+ if (len === compressedLen && (header === 0x02 || header === 0x03)) {
+ return this.fromCompressedHex(bytes);
+ }
+ if (len === uncompressedLen && header === 0x04)
+ return this.fromUncompressedHex(bytes);
+ throw new Error(`Point.fromHex: received invalid point. Expected 32-${compressedLen} compressed bytes or ${uncompressedLen} uncompressed bytes, not ${len}`);
+ }
+ static fromPrivateKey(privateKey) {
+ return Point.BASE.multiply(normalizePrivateKey(privateKey));
+ }
+ static fromSignature(msgHash, signature, recovery) {
+ const { r, s } = normalizeSignature(signature);
+ if (![0, 1, 2, 3].includes(recovery))
+ throw new Error('Cannot recover: invalid recovery bit');
+ const h = truncateHash(ensureBytes(msgHash));
+ const { n } = CURVE;
+ const radj = recovery === 2 || recovery === 3 ? r + n : r;
+ const rinv = invert(radj, n);
+ const u1 = mod(-h * rinv, n);
+ const u2 = mod(s * rinv, n);
+ const prefix = recovery & 1 ? '03' : '02';
+ const R = Point.fromHex(prefix + numTo32bStr(radj));
+ const Q = Point.BASE.multiplyAndAddUnsafe(R, u1, u2);
+ if (!Q)
+ throw new Error('Cannot recover signature: point at infinify');
+ Q.assertValidity();
+ return Q;
+ }
+ toRawBytes(isCompressed = false) {
+ return hexToBytes$1(this.toHex(isCompressed));
+ }
+ toHex(isCompressed = false) {
+ const x = numTo32bStr(this.x);
+ if (isCompressed) {
+ const prefix = this.hasEvenY() ? '02' : '03';
+ return `${prefix}${x}`;
+ }
+ else {
+ return `04${x}${numTo32bStr(this.y)}`;
+ }
+ }
+ toHexX() {
+ return this.toHex(true).slice(2);
+ }
+ toRawX() {
+ return this.toRawBytes(true).slice(1);
+ }
+ assertValidity() {
+ const msg = 'Point is not on elliptic curve';
+ const { x, y } = this;
+ if (!isValidFieldElement(x) || !isValidFieldElement(y))
+ throw new Error(msg);
+ const left = mod(y * y);
+ const right = weierstrass(x);
+ if (mod(left - right) !== _0n)
+ throw new Error(msg);
+ }
+ equals(other) {
+ return this.x === other.x && this.y === other.y;
+ }
+ negate() {
+ return new Point(this.x, mod(-this.y));
+ }
+ double() {
+ return JacobianPoint.fromAffine(this).double().toAffine();
+ }
+ add(other) {
+ return JacobianPoint.fromAffine(this).add(JacobianPoint.fromAffine(other)).toAffine();
+ }
+ subtract(other) {
+ return this.add(other.negate());
+ }
+ multiply(scalar) {
+ return JacobianPoint.fromAffine(this).multiply(scalar, this).toAffine();
+ }
+ multiplyAndAddUnsafe(Q, a, b) {
+ const P = JacobianPoint.fromAffine(this);
+ const aP = a === _0n || a === _1n || this !== Point.BASE ? P.multiplyUnsafe(a) : P.multiply(a);
+ const bQ = JacobianPoint.fromAffine(Q).multiplyUnsafe(b);
+ const sum = aP.add(bQ);
+ return sum.equals(JacobianPoint.ZERO) ? undefined : sum.toAffine();
+ }
+ }
+ Point.BASE = new Point(CURVE.Gx, CURVE.Gy);
+ Point.ZERO = new Point(_0n, _0n);
+ function sliceDER(s) {
+ return Number.parseInt(s[0], 16) >= 8 ? '00' + s : s;
+ }
+ function parseDERInt(data) {
+ if (data.length < 2 || data[0] !== 0x02) {
+ throw new Error(`Invalid signature integer tag: ${bytesToHex$1(data)}`);
+ }
+ const len = data[1];
+ const res = data.subarray(2, len + 2);
+ if (!len || res.length !== len) {
+ throw new Error(`Invalid signature integer: wrong length`);
+ }
+ if (res[0] === 0x00 && res[1] <= 0x7f) {
+ throw new Error('Invalid signature integer: trailing length');
+ }
+ return { data: bytesToNumber$1(res), left: data.subarray(len + 2) };
+ }
+ function parseDERSignature(data) {
+ if (data.length < 2 || data[0] != 0x30) {
+ throw new Error(`Invalid signature tag: ${bytesToHex$1(data)}`);
+ }
+ if (data[1] !== data.length - 2) {
+ throw new Error('Invalid signature: incorrect length');
+ }
+ const { data: r, left: sBytes } = parseDERInt(data.subarray(2));
+ const { data: s, left: rBytesLeft } = parseDERInt(sBytes);
+ if (rBytesLeft.length) {
+ throw new Error(`Invalid signature: left bytes after parsing: ${bytesToHex$1(rBytesLeft)}`);
+ }
+ return { r, s };
+ }
+ class Signature {
+ constructor(r, s) {
+ this.r = r;
+ this.s = s;
+ this.assertValidity();
+ }
+ static fromCompact(hex) {
+ const arr = hex instanceof Uint8Array;
+ const name = 'Signature.fromCompact';
+ if (typeof hex !== 'string' && !arr)
+ throw new TypeError(`${name}: Expected string or Uint8Array`);
+ const str = arr ? bytesToHex$1(hex) : hex;
+ if (str.length !== 128)
+ throw new Error(`${name}: Expected 64-byte hex`);
+ return new Signature(hexToNumber(str.slice(0, 64)), hexToNumber(str.slice(64, 128)));
+ }
+ static fromDER(hex) {
+ const arr = hex instanceof Uint8Array;
+ if (typeof hex !== 'string' && !arr)
+ throw new TypeError(`Signature.fromDER: Expected string or Uint8Array`);
+ const { r, s } = parseDERSignature(arr ? hex : hexToBytes$1(hex));
+ return new Signature(r, s);
+ }
+ static fromHex(hex) {
+ return this.fromDER(hex);
+ }
+ assertValidity() {
+ const { r, s } = this;
+ if (!isWithinCurveOrder(r))
+ throw new Error('Invalid Signature: r must be 0 < r < n');
+ if (!isWithinCurveOrder(s))
+ throw new Error('Invalid Signature: s must be 0 < s < n');
+ }
+ hasHighS() {
+ const HALF = CURVE.n >> _1n;
+ return this.s > HALF;
+ }
+ normalizeS() {
+ return this.hasHighS() ? new Signature(this.r, mod(-this.s, CURVE.n)) : this;
+ }
+ toDERRawBytes() {
+ return hexToBytes$1(this.toDERHex());
+ }
+ toDERHex() {
+ const sHex = sliceDER(numberToHexUnpadded(this.s));
+ const rHex = sliceDER(numberToHexUnpadded(this.r));
+ const sHexL = sHex.length / 2;
+ const rHexL = rHex.length / 2;
+ const sLen = numberToHexUnpadded(sHexL);
+ const rLen = numberToHexUnpadded(rHexL);
+ const length = numberToHexUnpadded(rHexL + sHexL + 4);
+ return `30${length}02${rLen}${rHex}02${sLen}${sHex}`;
+ }
+ toRawBytes() {
+ return this.toDERRawBytes();
+ }
+ toHex() {
+ return this.toDERHex();
+ }
+ toCompactRawBytes() {
+ return hexToBytes$1(this.toCompactHex());
+ }
+ toCompactHex() {
+ return numTo32bStr(this.r) + numTo32bStr(this.s);
+ }
+ }
+ function concatBytes$1(...arrays) {
+ if (!arrays.every((b) => b instanceof Uint8Array))
+ throw new Error('Uint8Array list expected');
+ if (arrays.length === 1)
+ return arrays[0];
+ const length = arrays.reduce((a, arr) => a + arr.length, 0);
+ const result = new Uint8Array(length);
+ for (let i = 0, pad = 0; i < arrays.length; i++) {
+ const arr = arrays[i];
+ result.set(arr, pad);
+ pad += arr.length;
+ }
+ return result;
+ }
+ const hexes$1 = Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, '0'));
+ function bytesToHex$1(uint8a) {
+ if (!(uint8a instanceof Uint8Array))
+ throw new Error('Expected Uint8Array');
+ let hex = '';
+ for (let i = 0; i < uint8a.length; i++) {
+ hex += hexes$1[uint8a[i]];
+ }
+ return hex;
+ }
+ const POW_2_256 = BigInt('0x10000000000000000000000000000000000000000000000000000000000000000');
+ function numTo32bStr(num) {
+ if (typeof num !== 'bigint')
+ throw new Error('Expected bigint');
+ if (!(_0n <= num && num < POW_2_256))
+ throw new Error('Expected number 0 <= n < 2^256');
+ return num.toString(16).padStart(64, '0');
+ }
+ function numTo32b(num) {
+ const b = hexToBytes$1(numTo32bStr(num));
+ if (b.length !== 32)
+ throw new Error('Error: expected 32 bytes');
+ return b;
+ }
+ function numberToHexUnpadded(num) {
+ const hex = num.toString(16);
+ return hex.length & 1 ? `0${hex}` : hex;
+ }
+ function hexToNumber(hex) {
+ if (typeof hex !== 'string') {
+ throw new TypeError('hexToNumber: expected string, got ' + typeof hex);
+ }
+ return BigInt(`0x${hex}`);
+ }
+ function hexToBytes$1(hex) {
+ if (typeof hex !== 'string') {
+ throw new TypeError('hexToBytes: expected string, got ' + typeof hex);
+ }
+ if (hex.length % 2)
+ throw new Error('hexToBytes: received invalid unpadded hex' + hex.length);
+ const array = new Uint8Array(hex.length / 2);
+ for (let i = 0; i < array.length; i++) {
+ const j = i * 2;
+ const hexByte = hex.slice(j, j + 2);
+ const byte = Number.parseInt(hexByte, 16);
+ if (Number.isNaN(byte) || byte < 0)
+ throw new Error('Invalid byte sequence');
+ array[i] = byte;
+ }
+ return array;
+ }
+ function bytesToNumber$1(bytes) {
+ return hexToNumber(bytesToHex$1(bytes));
+ }
+ function ensureBytes(hex) {
+ return hex instanceof Uint8Array ? Uint8Array.from(hex) : hexToBytes$1(hex);
+ }
+ function normalizeScalar(num) {
+ if (typeof num === 'number' && Number.isSafeInteger(num) && num > 0)
+ return BigInt(num);
+ if (typeof num === 'bigint' && isWithinCurveOrder(num))
+ return num;
+ throw new TypeError('Expected valid private scalar: 0 < scalar < curve.n');
+ }
+ function mod(a, b = CURVE.P) {
+ const result = a % b;
+ return result >= _0n ? result : b + result;
+ }
+ function pow2(x, power) {
+ const { P } = CURVE;
+ let res = x;
+ while (power-- > _0n) {
+ res *= res;
+ res %= P;
+ }
+ return res;
+ }
+ function sqrtMod(x) {
+ const { P } = CURVE;
+ const _6n = BigInt(6);
+ const _11n = BigInt(11);
+ const _22n = BigInt(22);
+ const _23n = BigInt(23);
+ const _44n = BigInt(44);
+ const _88n = BigInt(88);
+ const b2 = (x * x * x) % P;
+ const b3 = (b2 * b2 * x) % P;
+ const b6 = (pow2(b3, _3n) * b3) % P;
+ const b9 = (pow2(b6, _3n) * b3) % P;
+ const b11 = (pow2(b9, _2n) * b2) % P;
+ const b22 = (pow2(b11, _11n) * b11) % P;
+ const b44 = (pow2(b22, _22n) * b22) % P;
+ const b88 = (pow2(b44, _44n) * b44) % P;
+ const b176 = (pow2(b88, _88n) * b88) % P;
+ const b220 = (pow2(b176, _44n) * b44) % P;
+ const b223 = (pow2(b220, _3n) * b3) % P;
+ const t1 = (pow2(b223, _23n) * b22) % P;
+ const t2 = (pow2(t1, _6n) * b2) % P;
+ const rt = pow2(t2, _2n);
+ const xc = (rt * rt) % P;
+ if (xc !== x)
+ throw new Error('Cannot find square root');
+ return rt;
+ }
+ function invert(number, modulo = CURVE.P) {
+ if (number === _0n || modulo <= _0n) {
+ throw new Error(`invert: expected positive integers, got n=${number} mod=${modulo}`);
+ }
+ let a = mod(number, modulo);
+ let b = modulo;
+ let x = _0n, u = _1n;
+ while (a !== _0n) {
+ const q = b / a;
+ const r = b % a;
+ const m = x - u * q;
+ b = a, a = r, x = u, u = m;
+ }
+ const gcd = b;
+ if (gcd !== _1n)
+ throw new Error('invert: does not exist');
+ return mod(x, modulo);
+ }
+ function invertBatch(nums, p = CURVE.P) {
+ const scratch = new Array(nums.length);
+ const lastMultiplied = nums.reduce((acc, num, i) => {
+ if (num === _0n)
+ return acc;
+ scratch[i] = acc;
+ return mod(acc * num, p);
+ }, _1n);
+ const inverted = invert(lastMultiplied, p);
+ nums.reduceRight((acc, num, i) => {
+ if (num === _0n)
+ return acc;
+ scratch[i] = mod(acc * scratch[i], p);
+ return mod(acc * num, p);
+ }, inverted);
+ return scratch;
+ }
+ function bits2int_2(bytes) {
+ const delta = bytes.length * 8 - groupLen * 8;
+ const num = bytesToNumber$1(bytes);
+ return delta > 0 ? num >> BigInt(delta) : num;
+ }
+ function truncateHash(hash, truncateOnly = false) {
+ const h = bits2int_2(hash);
+ if (truncateOnly)
+ return h;
+ const { n } = CURVE;
+ return h >= n ? h - n : h;
+ }
+ let _sha256Sync;
+ let _hmacSha256Sync;
+ class HmacDrbg {
+ constructor(hashLen, qByteLen) {
+ this.hashLen = hashLen;
+ this.qByteLen = qByteLen;
+ if (typeof hashLen !== 'number' || hashLen < 2)
+ throw new Error('hashLen must be a number');
+ if (typeof qByteLen !== 'number' || qByteLen < 2)
+ throw new Error('qByteLen must be a number');
+ this.v = new Uint8Array(hashLen).fill(1);
+ this.k = new Uint8Array(hashLen).fill(0);
+ this.counter = 0;
+ }
+ hmac(...values) {
+ return utils$1.hmacSha256(this.k, ...values);
+ }
+ hmacSync(...values) {
+ return _hmacSha256Sync(this.k, ...values);
+ }
+ checkSync() {
+ if (typeof _hmacSha256Sync !== 'function')
+ throw new ShaError('hmacSha256Sync needs to be set');
+ }
+ incr() {
+ if (this.counter >= 1000)
+ throw new Error('Tried 1,000 k values for sign(), all were invalid');
+ this.counter += 1;
+ }
+ async reseed(seed = new Uint8Array()) {
+ this.k = await this.hmac(this.v, Uint8Array.from([0x00]), seed);
+ this.v = await this.hmac(this.v);
+ if (seed.length === 0)
+ return;
+ this.k = await this.hmac(this.v, Uint8Array.from([0x01]), seed);
+ this.v = await this.hmac(this.v);
+ }
+ reseedSync(seed = new Uint8Array()) {
+ this.checkSync();
+ this.k = this.hmacSync(this.v, Uint8Array.from([0x00]), seed);
+ this.v = this.hmacSync(this.v);
+ if (seed.length === 0)
+ return;
+ this.k = this.hmacSync(this.v, Uint8Array.from([0x01]), seed);
+ this.v = this.hmacSync(this.v);
+ }
+ async generate() {
+ this.incr();
+ let len = 0;
+ const out = [];
+ while (len < this.qByteLen) {
+ this.v = await this.hmac(this.v);
+ const sl = this.v.slice();
+ out.push(sl);
+ len += this.v.length;
+ }
+ return concatBytes$1(...out);
+ }
+ generateSync() {
+ this.checkSync();
+ this.incr();
+ let len = 0;
+ const out = [];
+ while (len < this.qByteLen) {
+ this.v = this.hmacSync(this.v);
+ const sl = this.v.slice();
+ out.push(sl);
+ len += this.v.length;
+ }
+ return concatBytes$1(...out);
+ }
+ }
+ function isWithinCurveOrder(num) {
+ return _0n < num && num < CURVE.n;
+ }
+ function isValidFieldElement(num) {
+ return _0n < num && num < CURVE.P;
+ }
+ function kmdToSig(kBytes, m, d, lowS = true) {
+ const { n } = CURVE;
+ const k = truncateHash(kBytes, true);
+ if (!isWithinCurveOrder(k))
+ return;
+ const kinv = invert(k, n);
+ const q = Point.BASE.multiply(k);
+ const r = mod(q.x, n);
+ if (r === _0n)
+ return;
+ const s = mod(kinv * mod(m + d * r, n), n);
+ if (s === _0n)
+ return;
+ let sig = new Signature(r, s);
+ let recovery = (q.x === sig.r ? 0 : 2) | Number(q.y & _1n);
+ if (lowS && sig.hasHighS()) {
+ sig = sig.normalizeS();
+ recovery ^= 1;
+ }
+ return { sig, recovery };
+ }
+ function normalizePrivateKey(key) {
+ let num;
+ if (typeof key === 'bigint') {
+ num = key;
+ }
+ else if (typeof key === 'number' && Number.isSafeInteger(key) && key > 0) {
+ num = BigInt(key);
+ }
+ else if (typeof key === 'string') {
+ if (key.length !== 2 * groupLen)
+ throw new Error('Expected 32 bytes of private key');
+ num = hexToNumber(key);
+ }
+ else if (key instanceof Uint8Array) {
+ if (key.length !== groupLen)
+ throw new Error('Expected 32 bytes of private key');
+ num = bytesToNumber$1(key);
+ }
+ else {
+ throw new TypeError('Expected valid private key');
+ }
+ if (!isWithinCurveOrder(num))
+ throw new Error('Expected private key: 0 < key < n');
+ return num;
+ }
+ function normalizePublicKey(publicKey) {
+ if (publicKey instanceof Point) {
+ publicKey.assertValidity();
+ return publicKey;
+ }
+ else {
+ return Point.fromHex(publicKey);
+ }
+ }
+ function normalizeSignature(signature) {
+ if (signature instanceof Signature) {
+ signature.assertValidity();
+ return signature;
+ }
+ try {
+ return Signature.fromDER(signature);
+ }
+ catch (error) {
+ return Signature.fromCompact(signature);
+ }
+ }
+ function getPublicKey$1(privateKey, isCompressed = false) {
+ return Point.fromPrivateKey(privateKey).toRawBytes(isCompressed);
+ }
+ function isProbPub(item) {
+ const arr = item instanceof Uint8Array;
+ const str = typeof item === 'string';
+ const len = (arr || str) && item.length;
+ if (arr)
+ return len === compressedLen || len === uncompressedLen;
+ if (str)
+ return len === compressedLen * 2 || len === uncompressedLen * 2;
+ if (item instanceof Point)
+ return true;
+ return false;
+ }
+ function getSharedSecret(privateA, publicB, isCompressed = false) {
+ if (isProbPub(privateA))
+ throw new TypeError('getSharedSecret: first arg must be private key');
+ if (!isProbPub(publicB))
+ throw new TypeError('getSharedSecret: second arg must be public key');
+ const b = normalizePublicKey(publicB);
+ b.assertValidity();
+ return b.multiply(normalizePrivateKey(privateA)).toRawBytes(isCompressed);
+ }
+ function bits2int(bytes) {
+ const slice = bytes.length > fieldLen ? bytes.slice(0, fieldLen) : bytes;
+ return bytesToNumber$1(slice);
+ }
+ function bits2octets(bytes) {
+ const z1 = bits2int(bytes);
+ const z2 = mod(z1, CURVE.n);
+ return int2octets(z2 < _0n ? z1 : z2);
+ }
+ function int2octets(num) {
+ return numTo32b(num);
+ }
+ function initSigArgs(msgHash, privateKey, extraEntropy) {
+ if (msgHash == null)
+ throw new Error(`sign: expected valid message hash, not "${msgHash}"`);
+ const h1 = ensureBytes(msgHash);
+ const d = normalizePrivateKey(privateKey);
+ const seedArgs = [int2octets(d), bits2octets(h1)];
+ if (extraEntropy != null) {
+ if (extraEntropy === true)
+ extraEntropy = utils$1.randomBytes(fieldLen);
+ const e = ensureBytes(extraEntropy);
+ if (e.length !== fieldLen)
+ throw new Error(`sign: Expected ${fieldLen} bytes of extra data`);
+ seedArgs.push(e);
+ }
+ const seed = concatBytes$1(...seedArgs);
+ const m = bits2int(h1);
+ return { seed, m, d };
+ }
+ function finalizeSig(recSig, opts) {
+ const { sig, recovery } = recSig;
+ const { der, recovered } = Object.assign({ canonical: true, der: true }, opts);
+ const hashed = der ? sig.toDERRawBytes() : sig.toCompactRawBytes();
+ return recovered ? [hashed, recovery] : hashed;
+ }
+ function signSync(msgHash, privKey, opts = {}) {
+ const { seed, m, d } = initSigArgs(msgHash, privKey, opts.extraEntropy);
+ const drbg = new HmacDrbg(hashLen, groupLen);
+ drbg.reseedSync(seed);
+ let sig;
+ while (!(sig = kmdToSig(drbg.generateSync(), m, d, opts.canonical)))
+ drbg.reseedSync();
+ return finalizeSig(sig, opts);
+ }
+ const vopts = { strict: true };
+ function verify(signature, msgHash, publicKey, opts = vopts) {
+ let sig;
+ try {
+ sig = normalizeSignature(signature);
+ msgHash = ensureBytes(msgHash);
+ }
+ catch (error) {
+ return false;
+ }
+ const { r, s } = sig;
+ if (opts.strict && sig.hasHighS())
+ return false;
+ const h = truncateHash(msgHash);
+ let P;
+ try {
+ P = normalizePublicKey(publicKey);
+ }
+ catch (error) {
+ return false;
+ }
+ const { n } = CURVE;
+ const sinv = invert(s, n);
+ const u1 = mod(h * sinv, n);
+ const u2 = mod(r * sinv, n);
+ const R = Point.BASE.multiplyAndAddUnsafe(P, u1, u2);
+ if (!R)
+ return false;
+ const v = mod(R.x, n);
+ return v === r;
+ }
+ function schnorrChallengeFinalize(ch) {
+ return mod(bytesToNumber$1(ch), CURVE.n);
+ }
+ class SchnorrSignature {
+ constructor(r, s) {
+ this.r = r;
+ this.s = s;
+ this.assertValidity();
+ }
+ static fromHex(hex) {
+ const bytes = ensureBytes(hex);
+ if (bytes.length !== 64)
+ throw new TypeError(`SchnorrSignature.fromHex: expected 64 bytes, not ${bytes.length}`);
+ const r = bytesToNumber$1(bytes.subarray(0, 32));
+ const s = bytesToNumber$1(bytes.subarray(32, 64));
+ return new SchnorrSignature(r, s);
+ }
+ assertValidity() {
+ const { r, s } = this;
+ if (!isValidFieldElement(r) || !isWithinCurveOrder(s))
+ throw new Error('Invalid signature');
+ }
+ toHex() {
+ return numTo32bStr(this.r) + numTo32bStr(this.s);
+ }
+ toRawBytes() {
+ return hexToBytes$1(this.toHex());
+ }
+ }
+ function schnorrGetPublicKey(privateKey) {
+ return Point.fromPrivateKey(privateKey).toRawX();
+ }
+ class InternalSchnorrSignature {
+ constructor(message, privateKey, auxRand = utils$1.randomBytes()) {
+ if (message == null)
+ throw new TypeError(`sign: Expected valid message, not "${message}"`);
+ this.m = ensureBytes(message);
+ const { x, scalar } = this.getScalar(normalizePrivateKey(privateKey));
+ this.px = x;
+ this.d = scalar;
+ this.rand = ensureBytes(auxRand);
+ if (this.rand.length !== 32)
+ throw new TypeError('sign: Expected 32 bytes of aux randomness');
+ }
+ getScalar(priv) {
+ const point = Point.fromPrivateKey(priv);
+ const scalar = point.hasEvenY() ? priv : CURVE.n - priv;
+ return { point, scalar, x: point.toRawX() };
+ }
+ initNonce(d, t0h) {
+ return numTo32b(d ^ bytesToNumber$1(t0h));
+ }
+ finalizeNonce(k0h) {
+ const k0 = mod(bytesToNumber$1(k0h), CURVE.n);
+ if (k0 === _0n)
+ throw new Error('sign: Creation of signature failed. k is zero');
+ const { point: R, x: rx, scalar: k } = this.getScalar(k0);
+ return { R, rx, k };
+ }
+ finalizeSig(R, k, e, d) {
+ return new SchnorrSignature(R.x, mod(k + e * d, CURVE.n)).toRawBytes();
+ }
+ error() {
+ throw new Error('sign: Invalid signature produced');
+ }
+ async calc() {
+ const { m, d, px, rand } = this;
+ const tag = utils$1.taggedHash;
+ const t = this.initNonce(d, await tag(TAGS.aux, rand));
+ const { R, rx, k } = this.finalizeNonce(await tag(TAGS.nonce, t, px, m));
+ const e = schnorrChallengeFinalize(await tag(TAGS.challenge, rx, px, m));
+ const sig = this.finalizeSig(R, k, e, d);
+ if (!(await schnorrVerify(sig, m, px)))
+ this.error();
+ return sig;
+ }
+ calcSync() {
+ const { m, d, px, rand } = this;
+ const tag = utils$1.taggedHashSync;
+ const t = this.initNonce(d, tag(TAGS.aux, rand));
+ const { R, rx, k } = this.finalizeNonce(tag(TAGS.nonce, t, px, m));
+ const e = schnorrChallengeFinalize(tag(TAGS.challenge, rx, px, m));
+ const sig = this.finalizeSig(R, k, e, d);
+ if (!schnorrVerifySync(sig, m, px))
+ this.error();
+ return sig;
+ }
+ }
+ async function schnorrSign(msg, privKey, auxRand) {
+ return new InternalSchnorrSignature(msg, privKey, auxRand).calc();
+ }
+ function schnorrSignSync(msg, privKey, auxRand) {
+ return new InternalSchnorrSignature(msg, privKey, auxRand).calcSync();
+ }
+ function initSchnorrVerify(signature, message, publicKey) {
+ const raw = signature instanceof SchnorrSignature;
+ const sig = raw ? signature : SchnorrSignature.fromHex(signature);
+ if (raw)
+ sig.assertValidity();
+ return {
+ ...sig,
+ m: ensureBytes(message),
+ P: normalizePublicKey(publicKey),
+ };
+ }
+ function finalizeSchnorrVerify(r, P, s, e) {
+ const R = Point.BASE.multiplyAndAddUnsafe(P, normalizePrivateKey(s), mod(-e, CURVE.n));
+ if (!R || !R.hasEvenY() || R.x !== r)
+ return false;
+ return true;
+ }
+ async function schnorrVerify(signature, message, publicKey) {
+ try {
+ const { r, s, m, P } = initSchnorrVerify(signature, message, publicKey);
+ const e = schnorrChallengeFinalize(await utils$1.taggedHash(TAGS.challenge, numTo32b(r), P.toRawX(), m));
+ return finalizeSchnorrVerify(r, P, s, e);
+ }
+ catch (error) {
+ return false;
+ }
+ }
+ function schnorrVerifySync(signature, message, publicKey) {
+ try {
+ const { r, s, m, P } = initSchnorrVerify(signature, message, publicKey);
+ const e = schnorrChallengeFinalize(utils$1.taggedHashSync(TAGS.challenge, numTo32b(r), P.toRawX(), m));
+ return finalizeSchnorrVerify(r, P, s, e);
+ }
+ catch (error) {
+ if (error instanceof ShaError)
+ throw error;
+ return false;
+ }
+ }
+ const schnorr = {
+ Signature: SchnorrSignature,
+ getPublicKey: schnorrGetPublicKey,
+ sign: schnorrSign,
+ verify: schnorrVerify,
+ signSync: schnorrSignSync,
+ verifySync: schnorrVerifySync,
+ };
+ Point.BASE._setWindowSize(8);
+ const crypto$2 = {
+ node: nodeCrypto,
+ web: typeof self === 'object' && 'crypto' in self ? self.crypto : undefined,
+ };
+ const TAGS = {
+ challenge: 'BIP0340/challenge',
+ aux: 'BIP0340/aux',
+ nonce: 'BIP0340/nonce',
+ };
+ const TAGGED_HASH_PREFIXES = {};
+ const utils$1 = {
+ bytesToHex: bytesToHex$1,
+ hexToBytes: hexToBytes$1,
+ concatBytes: concatBytes$1,
+ mod,
+ invert,
+ isValidPrivateKey(privateKey) {
+ try {
+ normalizePrivateKey(privateKey);
+ return true;
+ }
+ catch (error) {
+ return false;
+ }
+ },
+ _bigintTo32Bytes: numTo32b,
+ _normalizePrivateKey: normalizePrivateKey,
+ hashToPrivateKey: (hash) => {
+ hash = ensureBytes(hash);
+ const minLen = groupLen + 8;
+ if (hash.length < minLen || hash.length > 1024) {
+ throw new Error(`Expected valid bytes of private key as per FIPS 186`);
+ }
+ const num = mod(bytesToNumber$1(hash), CURVE.n - _1n) + _1n;
+ return numTo32b(num);
+ },
+ randomBytes: (bytesLength = 32) => {
+ if (crypto$2.web) {
+ return crypto$2.web.getRandomValues(new Uint8Array(bytesLength));
+ }
+ else if (crypto$2.node) {
+ const { randomBytes } = crypto$2.node;
+ return Uint8Array.from(randomBytes(bytesLength));
+ }
+ else {
+ throw new Error("The environment doesn't have randomBytes function");
+ }
+ },
+ randomPrivateKey: () => utils$1.hashToPrivateKey(utils$1.randomBytes(groupLen + 8)),
+ precompute(windowSize = 8, point = Point.BASE) {
+ const cached = point === Point.BASE ? point : new Point(point.x, point.y);
+ cached._setWindowSize(windowSize);
+ cached.multiply(_3n);
+ return cached;
+ },
+ sha256: async (...messages) => {
+ if (crypto$2.web) {
+ const buffer = await crypto$2.web.subtle.digest('SHA-256', concatBytes$1(...messages));
+ return new Uint8Array(buffer);
+ }
+ else if (crypto$2.node) {
+ const { createHash } = crypto$2.node;
+ const hash = createHash('sha256');
+ messages.forEach((m) => hash.update(m));
+ return Uint8Array.from(hash.digest());
+ }
+ else {
+ throw new Error("The environment doesn't have sha256 function");
+ }
+ },
+ hmacSha256: async (key, ...messages) => {
+ if (crypto$2.web) {
+ const ckey = await crypto$2.web.subtle.importKey('raw', key, { name: 'HMAC', hash: { name: 'SHA-256' } }, false, ['sign']);
+ const message = concatBytes$1(...messages);
+ const buffer = await crypto$2.web.subtle.sign('HMAC', ckey, message);
+ return new Uint8Array(buffer);
+ }
+ else if (crypto$2.node) {
+ const { createHmac } = crypto$2.node;
+ const hash = createHmac('sha256', key);
+ messages.forEach((m) => hash.update(m));
+ return Uint8Array.from(hash.digest());
+ }
+ else {
+ throw new Error("The environment doesn't have hmac-sha256 function");
+ }
+ },
+ sha256Sync: undefined,
+ hmacSha256Sync: undefined,
+ taggedHash: async (tag, ...messages) => {
+ let tagP = TAGGED_HASH_PREFIXES[tag];
+ if (tagP === undefined) {
+ const tagH = await utils$1.sha256(Uint8Array.from(tag, (c) => c.charCodeAt(0)));
+ tagP = concatBytes$1(tagH, tagH);
+ TAGGED_HASH_PREFIXES[tag] = tagP;
+ }
+ return utils$1.sha256(tagP, ...messages);
+ },
+ taggedHashSync: (tag, ...messages) => {
+ if (typeof _sha256Sync !== 'function')
+ throw new ShaError('sha256Sync is undefined, you need to set it');
+ let tagP = TAGGED_HASH_PREFIXES[tag];
+ if (tagP === undefined) {
+ const tagH = _sha256Sync(Uint8Array.from(tag, (c) => c.charCodeAt(0)));
+ tagP = concatBytes$1(tagH, tagH);
+ TAGGED_HASH_PREFIXES[tag] = tagP;
+ }
+ return _sha256Sync(tagP, ...messages);
+ },
+ _JacobianPoint: JacobianPoint,
+ };
+ Object.defineProperties(utils$1, {
+ sha256Sync: {
+ configurable: false,
+ get() {
+ return _sha256Sync;
+ },
+ set(val) {
+ if (!_sha256Sync)
+ _sha256Sync = val;
+ },
+ },
+ hmacSha256Sync: {
+ configurable: false,
+ get() {
+ return _hmacSha256Sync;
+ },
+ set(val) {
+ if (!_hmacSha256Sync)
+ _hmacSha256Sync = val;
+ },
+ },
+ });
+
+ const crypto$1 = {
+ node: undefined,
+ web: typeof self === 'object' && 'crypto' in self ? self.crypto : undefined,
+ };
+
+ /*! noble-hashes - MIT License (c) 2021 Paul Miller (paulmillr.com) */
+ // Cast array to view
+ const createView$1 = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
+ // The rotate right (circular right shift) operation for uint32
+ const rotr$1 = (word, shift) => (word << (32 - shift)) | (word >>> shift);
+ const isLE$1 = new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44;
+ // There is almost no big endian hardware, but js typed arrays uses platform specific endianess.
+ // So, just to be sure not to corrupt anything.
+ if (!isLE$1)
+ throw new Error('Non little-endian hardware is not supported');
+ Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, '0'));
+ // Currently avoid insertion of polyfills with packers (browserify/webpack/etc)
+ // But setTimeout is pretty slow, maybe worth to investigate howto do minimal polyfill here
+ (() => {
+ const nodeRequire = typeof module !== 'undefined' &&
+ typeof module.require === 'function' &&
+ module.require.bind(module);
+ try {
+ if (nodeRequire) {
+ const { setImmediate } = nodeRequire('timers');
+ return () => new Promise((resolve) => setImmediate(resolve));
+ }
+ }
+ catch (e) { }
+ return () => new Promise((resolve) => setTimeout(resolve, 0));
+ })();
+ function utf8ToBytes$1(str) {
+ if (typeof str !== 'string') {
+ throw new TypeError(`utf8ToBytes expected string, got ${typeof str}`);
+ }
+ return new TextEncoder().encode(str);
+ }
+ function toBytes$1(data) {
+ if (typeof data === 'string')
+ data = utf8ToBytes$1(data);
+ if (!(data instanceof Uint8Array))
+ throw new TypeError(`Expected input type is Uint8Array (got ${typeof data})`);
+ return data;
+ }
+ function assertNumber$1(n) {
+ if (!Number.isSafeInteger(n) || n < 0)
+ throw new Error(`Wrong positive integer: ${n}`);
+ }
+ function assertHash(hash) {
+ if (typeof hash !== 'function' || typeof hash.init !== 'function')
+ throw new Error('Hash should be wrapped by utils.wrapConstructor');
+ assertNumber$1(hash.outputLen);
+ assertNumber$1(hash.blockLen);
+ }
+ // For runtime check if class implements interface
+ let Hash$1 = class Hash {
+ // Safe version that clones internal state
+ clone() {
+ return this._cloneInto();
+ }
+ };
+ function wrapConstructor$1(hashConstructor) {
+ const hashC = (message) => hashConstructor().update(toBytes$1(message)).digest();
+ const tmp = hashConstructor();
+ hashC.outputLen = tmp.outputLen;
+ hashC.blockLen = tmp.blockLen;
+ hashC.create = () => hashConstructor();
+ hashC.init = hashC.create;
+ return hashC;
+ }
+ function randomBytes(bytesLength = 32) {
+ if (crypto$1.web) {
+ return crypto$1.web.getRandomValues(new Uint8Array(bytesLength));
+ }
+ else {
+ throw new Error("The environment doesn't have randomBytes function");
+ }
+ }
+
+ // Polyfill for Safari 14
+ function setBigUint64$2(view, byteOffset, value, isLE) {
+ if (typeof view.setBigUint64 === 'function')
+ return view.setBigUint64(byteOffset, value, isLE);
+ const _32n = BigInt(32);
+ const _u32_max = BigInt(0xffffffff);
+ const wh = Number((value >> _32n) & _u32_max);
+ const wl = Number(value & _u32_max);
+ const h = isLE ? 4 : 0;
+ const l = isLE ? 0 : 4;
+ view.setUint32(byteOffset + h, wh, isLE);
+ view.setUint32(byteOffset + l, wl, isLE);
+ }
+ // Base SHA2 class (RFC 6234)
+ let SHA2$2 = class SHA2 extends Hash$1 {
+ constructor(blockLen, outputLen, padOffset, isLE) {
+ super();
+ this.blockLen = blockLen;
+ this.outputLen = outputLen;
+ this.padOffset = padOffset;
+ this.isLE = isLE;
+ this.finished = false;
+ this.length = 0;
+ this.pos = 0;
+ this.destroyed = false;
+ this.buffer = new Uint8Array(blockLen);
+ this.view = createView$1(this.buffer);
+ }
+ update(data) {
+ if (this.destroyed)
+ throw new Error('instance is destroyed');
+ const { view, buffer, blockLen, finished } = this;
+ if (finished)
+ throw new Error('digest() was already called');
+ data = toBytes$1(data);
+ const len = data.length;
+ for (let pos = 0; pos < len;) {
+ const take = Math.min(blockLen - this.pos, len - pos);
+ // Fast path: we have at least one block in input, cast it to view and process
+ if (take === blockLen) {
+ const dataView = createView$1(data);
+ for (; blockLen <= len - pos; pos += blockLen)
+ this.process(dataView, pos);
+ continue;
+ }
+ buffer.set(data.subarray(pos, pos + take), this.pos);
+ this.pos += take;
+ pos += take;
+ if (this.pos === blockLen) {
+ this.process(view, 0);
+ this.pos = 0;
+ }
+ }
+ this.length += data.length;
+ this.roundClean();
+ return this;
+ }
+ digestInto(out) {
+ if (this.destroyed)
+ throw new Error('instance is destroyed');
+ if (!(out instanceof Uint8Array) || out.length < this.outputLen)
+ throw new Error('_Sha2: Invalid output buffer');
+ if (this.finished)
+ throw new Error('digest() was already called');
+ this.finished = true;
+ // Padding
+ // We can avoid allocation of buffer for padding completely if it
+ // was previously not allocated here. But it won't change performance.
+ const { buffer, view, blockLen, isLE } = this;
+ let { pos } = this;
+ // append the bit '1' to the message
+ buffer[pos++] = 0b10000000;
+ this.buffer.subarray(pos).fill(0);
+ // we have less than padOffset left in buffer, so we cannot put length in current block, need process it and pad again
+ if (this.padOffset > blockLen - pos) {
+ this.process(view, 0);
+ pos = 0;
+ }
+ // Pad until full block byte with zeros
+ for (let i = pos; i < blockLen; i++)
+ buffer[i] = 0;
+ // NOTE: sha512 requires length to be 128bit integer, but length in JS will overflow before that
+ // You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen.
+ // So we just write lowest 64bit of that value.
+ setBigUint64$2(view, blockLen - 8, BigInt(this.length * 8), isLE);
+ this.process(view, 0);
+ const oview = createView$1(out);
+ this.get().forEach((v, i) => oview.setUint32(4 * i, v, isLE));
+ }
+ digest() {
+ const { buffer, outputLen } = this;
+ this.digestInto(buffer);
+ const res = buffer.slice(0, outputLen);
+ this.destroy();
+ return res;
+ }
+ _cloneInto(to) {
+ to || (to = new this.constructor());
+ to.set(...this.get());
+ const { blockLen, buffer, length, finished, destroyed, pos } = this;
+ to.length = length;
+ to.pos = pos;
+ to.finished = finished;
+ to.destroyed = destroyed;
+ if (length % blockLen)
+ to.buffer.set(buffer);
+ return to;
+ }
+ };
+
+ // Choice: a ? b : c
+ const Chi$2 = (a, b, c) => (a & b) ^ (~a & c);
+ // Majority function, true if any two inpust is true
+ const Maj$2 = (a, b, c) => (a & b) ^ (a & c) ^ (b & c);
+ // Round constants:
+ // first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
+ // prettier-ignore
+ const SHA256_K$2 = new Uint32Array([
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+ ]);
+ // Initial state (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
+ // prettier-ignore
+ const IV$2 = new Uint32Array([
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
+ ]);
+ // Temporary buffer, not used to store anything between runs
+ // Named this way because it matches specification.
+ const SHA256_W$2 = new Uint32Array(64);
+ let SHA256$2 = class SHA256 extends SHA2$2 {
+ constructor() {
+ super(64, 32, 8, false);
+ // We cannot use array here since array allows indexing by variable
+ // which means optimizer/compiler cannot use registers.
+ this.A = IV$2[0] | 0;
+ this.B = IV$2[1] | 0;
+ this.C = IV$2[2] | 0;
+ this.D = IV$2[3] | 0;
+ this.E = IV$2[4] | 0;
+ this.F = IV$2[5] | 0;
+ this.G = IV$2[6] | 0;
+ this.H = IV$2[7] | 0;
+ }
+ get() {
+ const { A, B, C, D, E, F, G, H } = this;
+ return [A, B, C, D, E, F, G, H];
+ }
+ // prettier-ignore
+ set(A, B, C, D, E, F, G, H) {
+ this.A = A | 0;
+ this.B = B | 0;
+ this.C = C | 0;
+ this.D = D | 0;
+ this.E = E | 0;
+ this.F = F | 0;
+ this.G = G | 0;
+ this.H = H | 0;
+ }
+ process(view, offset) {
+ // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array
+ for (let i = 0; i < 16; i++, offset += 4)
+ SHA256_W$2[i] = view.getUint32(offset, false);
+ for (let i = 16; i < 64; i++) {
+ const W15 = SHA256_W$2[i - 15];
+ const W2 = SHA256_W$2[i - 2];
+ const s0 = rotr$1(W15, 7) ^ rotr$1(W15, 18) ^ (W15 >>> 3);
+ const s1 = rotr$1(W2, 17) ^ rotr$1(W2, 19) ^ (W2 >>> 10);
+ SHA256_W$2[i] = (s1 + SHA256_W$2[i - 7] + s0 + SHA256_W$2[i - 16]) | 0;
+ }
+ // Compression function main loop, 64 rounds
+ let { A, B, C, D, E, F, G, H } = this;
+ for (let i = 0; i < 64; i++) {
+ const sigma1 = rotr$1(E, 6) ^ rotr$1(E, 11) ^ rotr$1(E, 25);
+ const T1 = (H + sigma1 + Chi$2(E, F, G) + SHA256_K$2[i] + SHA256_W$2[i]) | 0;
+ const sigma0 = rotr$1(A, 2) ^ rotr$1(A, 13) ^ rotr$1(A, 22);
+ const T2 = (sigma0 + Maj$2(A, B, C)) | 0;
+ H = G;
+ G = F;
+ F = E;
+ E = (D + T1) | 0;
+ D = C;
+ C = B;
+ B = A;
+ A = (T1 + T2) | 0;
+ }
+ // Add the compressed chunk to the current hash value
+ A = (A + this.A) | 0;
+ B = (B + this.B) | 0;
+ C = (C + this.C) | 0;
+ D = (D + this.D) | 0;
+ E = (E + this.E) | 0;
+ F = (F + this.F) | 0;
+ G = (G + this.G) | 0;
+ H = (H + this.H) | 0;
+ this.set(A, B, C, D, E, F, G, H);
+ }
+ roundClean() {
+ SHA256_W$2.fill(0);
+ }
+ destroy() {
+ this.set(0, 0, 0, 0, 0, 0, 0, 0);
+ this.buffer.fill(0);
+ }
+ };
+ const sha256$2 = wrapConstructor$1(() => new SHA256$2());
+
+ /*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */
+ function assertNumber(n) {
+ if (!Number.isSafeInteger(n))
+ throw new Error(`Wrong integer: ${n}`);
+ }
+ function chain(...args) {
+ const wrap = (a, b) => (c) => a(b(c));
+ const encode = Array.from(args)
+ .reverse()
+ .reduce((acc, i) => (acc ? wrap(acc, i.encode) : i.encode), undefined);
+ const decode = args.reduce((acc, i) => (acc ? wrap(acc, i.decode) : i.decode), undefined);
+ return { encode, decode };
+ }
+ function alphabet(alphabet) {
+ return {
+ encode: (digits) => {
+ if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
+ throw new Error('alphabet.encode input should be an array of numbers');
+ return digits.map((i) => {
+ assertNumber(i);
+ if (i < 0 || i >= alphabet.length)
+ throw new Error(`Digit index outside alphabet: ${i} (alphabet: ${alphabet.length})`);
+ return alphabet[i];
+ });
+ },
+ decode: (input) => {
+ if (!Array.isArray(input) || (input.length && typeof input[0] !== 'string'))
+ throw new Error('alphabet.decode input should be array of strings');
+ return input.map((letter) => {
+ if (typeof letter !== 'string')
+ throw new Error(`alphabet.decode: not string element=${letter}`);
+ const index = alphabet.indexOf(letter);
+ if (index === -1)
+ throw new Error(`Unknown letter: "${letter}". Allowed: ${alphabet}`);
+ return index;
+ });
+ },
+ };
+ }
+ function join(separator = '') {
+ if (typeof separator !== 'string')
+ throw new Error('join separator should be string');
+ return {
+ encode: (from) => {
+ if (!Array.isArray(from) || (from.length && typeof from[0] !== 'string'))
+ throw new Error('join.encode input should be array of strings');
+ for (let i of from)
+ if (typeof i !== 'string')
+ throw new Error(`join.encode: non-string input=${i}`);
+ return from.join(separator);
+ },
+ decode: (to) => {
+ if (typeof to !== 'string')
+ throw new Error('join.decode input should be string');
+ return to.split(separator);
+ },
+ };
+ }
+ function padding(bits, chr = '=') {
+ assertNumber(bits);
+ if (typeof chr !== 'string')
+ throw new Error('padding chr should be string');
+ return {
+ encode(data) {
+ if (!Array.isArray(data) || (data.length && typeof data[0] !== 'string'))
+ throw new Error('padding.encode input should be array of strings');
+ for (let i of data)
+ if (typeof i !== 'string')
+ throw new Error(`padding.encode: non-string input=${i}`);
+ while ((data.length * bits) % 8)
+ data.push(chr);
+ return data;
+ },
+ decode(input) {
+ if (!Array.isArray(input) || (input.length && typeof input[0] !== 'string'))
+ throw new Error('padding.encode input should be array of strings');
+ for (let i of input)
+ if (typeof i !== 'string')
+ throw new Error(`padding.decode: non-string input=${i}`);
+ let end = input.length;
+ if ((end * bits) % 8)
+ throw new Error('Invalid padding: string should have whole number of bytes');
+ for (; end > 0 && input[end - 1] === chr; end--) {
+ if (!(((end - 1) * bits) % 8))
+ throw new Error('Invalid padding: string has too much padding');
+ }
+ return input.slice(0, end);
+ },
+ };
+ }
+ function normalize$1(fn) {
+ if (typeof fn !== 'function')
+ throw new Error('normalize fn should be function');
+ return { encode: (from) => from, decode: (to) => fn(to) };
+ }
+ function convertRadix(data, from, to) {
+ if (from < 2)
+ throw new Error(`convertRadix: wrong from=${from}, base cannot be less than 2`);
+ if (to < 2)
+ throw new Error(`convertRadix: wrong to=${to}, base cannot be less than 2`);
+ if (!Array.isArray(data))
+ throw new Error('convertRadix: data should be array');
+ if (!data.length)
+ return [];
+ let pos = 0;
+ const res = [];
+ const digits = Array.from(data);
+ digits.forEach((d) => {
+ assertNumber(d);
+ if (d < 0 || d >= from)
+ throw new Error(`Wrong integer: ${d}`);
+ });
+ while (true) {
+ let carry = 0;
+ let done = true;
+ for (let i = pos; i < digits.length; i++) {
+ const digit = digits[i];
+ const digitBase = from * carry + digit;
+ if (!Number.isSafeInteger(digitBase) ||
+ (from * carry) / from !== carry ||
+ digitBase - digit !== from * carry) {
+ throw new Error('convertRadix: carry overflow');
+ }
+ carry = digitBase % to;
+ digits[i] = Math.floor(digitBase / to);
+ if (!Number.isSafeInteger(digits[i]) || digits[i] * to + carry !== digitBase)
+ throw new Error('convertRadix: carry overflow');
+ if (!done)
+ continue;
+ else if (!digits[i])
+ pos = i;
+ else
+ done = false;
+ }
+ res.push(carry);
+ if (done)
+ break;
+ }
+ for (let i = 0; i < data.length - 1 && data[i] === 0; i++)
+ res.push(0);
+ return res.reverse();
+ }
+ const gcd = (a, b) => (!b ? a : gcd(b, a % b));
+ const radix2carry = (from, to) => from + (to - gcd(from, to));
+ function convertRadix2(data, from, to, padding) {
+ if (!Array.isArray(data))
+ throw new Error('convertRadix2: data should be array');
+ if (from <= 0 || from > 32)
+ throw new Error(`convertRadix2: wrong from=${from}`);
+ if (to <= 0 || to > 32)
+ throw new Error(`convertRadix2: wrong to=${to}`);
+ if (radix2carry(from, to) > 32) {
+ throw new Error(`convertRadix2: carry overflow from=${from} to=${to} carryBits=${radix2carry(from, to)}`);
+ }
+ let carry = 0;
+ let pos = 0;
+ const mask = 2 ** to - 1;
+ const res = [];
+ for (const n of data) {
+ assertNumber(n);
+ if (n >= 2 ** from)
+ throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);
+ carry = (carry << from) | n;
+ if (pos + from > 32)
+ throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from}`);
+ pos += from;
+ for (; pos >= to; pos -= to)
+ res.push(((carry >> (pos - to)) & mask) >>> 0);
+ carry &= 2 ** pos - 1;
+ }
+ carry = (carry << (to - pos)) & mask;
+ if (!padding && pos >= from)
+ throw new Error('Excess padding');
+ if (!padding && carry)
+ throw new Error(`Non-zero padding: ${carry}`);
+ if (padding && pos > 0)
+ res.push(carry >>> 0);
+ return res;
+ }
+ function radix(num) {
+ assertNumber(num);
+ return {
+ encode: (bytes) => {
+ if (!(bytes instanceof Uint8Array))
+ throw new Error('radix.encode input should be Uint8Array');
+ return convertRadix(Array.from(bytes), 2 ** 8, num);
+ },
+ decode: (digits) => {
+ if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
+ throw new Error('radix.decode input should be array of strings');
+ return Uint8Array.from(convertRadix(digits, num, 2 ** 8));
+ },
+ };
+ }
+ function radix2(bits, revPadding = false) {
+ assertNumber(bits);
+ if (bits <= 0 || bits > 32)
+ throw new Error('radix2: bits should be in (0..32]');
+ if (radix2carry(8, bits) > 32 || radix2carry(bits, 8) > 32)
+ throw new Error('radix2: carry overflow');
+ return {
+ encode: (bytes) => {
+ if (!(bytes instanceof Uint8Array))
+ throw new Error('radix2.encode input should be Uint8Array');
+ return convertRadix2(Array.from(bytes), 8, bits, !revPadding);
+ },
+ decode: (digits) => {
+ if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
+ throw new Error('radix2.decode input should be array of strings');
+ return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding));
+ },
+ };
+ }
+ function unsafeWrapper(fn) {
+ if (typeof fn !== 'function')
+ throw new Error('unsafeWrapper fn should be function');
+ return function (...args) {
+ try {
+ return fn.apply(null, args);
+ }
+ catch (e) { }
+ };
+ }
+ function checksum(len, fn) {
+ assertNumber(len);
+ if (typeof fn !== 'function')
+ throw new Error('checksum fn should be function');
+ return {
+ encode(data) {
+ if (!(data instanceof Uint8Array))
+ throw new Error('checksum.encode: input should be Uint8Array');
+ const checksum = fn(data).slice(0, len);
+ const res = new Uint8Array(data.length + len);
+ res.set(data);
+ res.set(checksum, data.length);
+ return res;
+ },
+ decode(data) {
+ if (!(data instanceof Uint8Array))
+ throw new Error('checksum.decode: input should be Uint8Array');
+ const payload = data.slice(0, -len);
+ const newChecksum = fn(payload).slice(0, len);
+ const oldChecksum = data.slice(-len);
+ for (let i = 0; i < len; i++)
+ if (newChecksum[i] !== oldChecksum[i])
+ throw new Error('Invalid checksum');
+ return payload;
+ },
+ };
+ }
+ const base16 = chain(radix2(4), alphabet('0123456789ABCDEF'), join(''));
+ const base32 = chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), padding(5), join(''));
+ chain(radix2(5), alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'), padding(5), join(''));
+ chain(radix2(5), alphabet('0123456789ABCDEFGHJKMNPQRSTVWXYZ'), join(''), normalize$1((s) => s.toUpperCase().replace(/O/g, '0').replace(/[IL]/g, '1')));
+ const base64 = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), padding(6), join(''));
+ const base64url = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), padding(6), join(''));
+ const genBase58 = (abc) => chain(radix(58), alphabet(abc), join(''));
+ const base58 = genBase58('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
+ genBase58('123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ');
+ genBase58('rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz');
+ const XMR_BLOCK_LEN = [0, 2, 3, 5, 6, 7, 9, 10, 11];
+ const base58xmr = {
+ encode(data) {
+ let res = '';
+ for (let i = 0; i < data.length; i += 8) {
+ const block = data.subarray(i, i + 8);
+ res += base58.encode(block).padStart(XMR_BLOCK_LEN[block.length], '1');
+ }
+ return res;
+ },
+ decode(str) {
+ let res = [];
+ for (let i = 0; i < str.length; i += 11) {
+ const slice = str.slice(i, i + 11);
+ const blockLen = XMR_BLOCK_LEN.indexOf(slice.length);
+ const block = base58.decode(slice);
+ for (let j = 0; j < block.length - blockLen; j++) {
+ if (block[j] !== 0)
+ throw new Error('base58xmr: wrong padding');
+ }
+ res = res.concat(Array.from(block.slice(block.length - blockLen)));
+ }
+ return Uint8Array.from(res);
+ },
+ };
+ const base58check$1 = (sha256) => chain(checksum(4, (data) => sha256(sha256(data))), base58);
+ const BECH_ALPHABET = chain(alphabet('qpzry9x8gf2tvdw0s3jn54khce6mua7l'), join(''));
+ const POLYMOD_GENERATORS = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
+ function bech32Polymod(pre) {
+ const b = pre >> 25;
+ let chk = (pre & 0x1ffffff) << 5;
+ for (let i = 0; i < POLYMOD_GENERATORS.length; i++) {
+ if (((b >> i) & 1) === 1)
+ chk ^= POLYMOD_GENERATORS[i];
+ }
+ return chk;
+ }
+ function bechChecksum(prefix, words, encodingConst = 1) {
+ const len = prefix.length;
+ let chk = 1;
+ for (let i = 0; i < len; i++) {
+ const c = prefix.charCodeAt(i);
+ if (c < 33 || c > 126)
+ throw new Error(`Invalid prefix (${prefix})`);
+ chk = bech32Polymod(chk) ^ (c >> 5);
+ }
+ chk = bech32Polymod(chk);
+ for (let i = 0; i < len; i++)
+ chk = bech32Polymod(chk) ^ (prefix.charCodeAt(i) & 0x1f);
+ for (let v of words)
+ chk = bech32Polymod(chk) ^ v;
+ for (let i = 0; i < 6; i++)
+ chk = bech32Polymod(chk);
+ chk ^= encodingConst;
+ return BECH_ALPHABET.encode(convertRadix2([chk % 2 ** 30], 30, 5, false));
+ }
+ function genBech32(encoding) {
+ const ENCODING_CONST = encoding === 'bech32' ? 1 : 0x2bc830a3;
+ const _words = radix2(5);
+ const fromWords = _words.decode;
+ const toWords = _words.encode;
+ const fromWordsUnsafe = unsafeWrapper(fromWords);
+ function encode(prefix, words, limit = 90) {
+ if (typeof prefix !== 'string')
+ throw new Error(`bech32.encode prefix should be string, not ${typeof prefix}`);
+ if (!Array.isArray(words) || (words.length && typeof words[0] !== 'number'))
+ throw new Error(`bech32.encode words should be array of numbers, not ${typeof words}`);
+ const actualLength = prefix.length + 7 + words.length;
+ if (limit !== false && actualLength > limit)
+ throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`);
+ prefix = prefix.toLowerCase();
+ return `${prefix}1${BECH_ALPHABET.encode(words)}${bechChecksum(prefix, words, ENCODING_CONST)}`;
+ }
+ function decode(str, limit = 90) {
+ if (typeof str !== 'string')
+ throw new Error(`bech32.decode input should be string, not ${typeof str}`);
+ if (str.length < 8 || (limit !== false && str.length > limit))
+ throw new TypeError(`Wrong string length: ${str.length} (${str}). Expected (8..${limit})`);
+ const lowered = str.toLowerCase();
+ if (str !== lowered && str !== str.toUpperCase())
+ throw new Error(`String must be lowercase or uppercase`);
+ str = lowered;
+ const sepIndex = str.lastIndexOf('1');
+ if (sepIndex === 0 || sepIndex === -1)
+ throw new Error(`Letter "1" must be present between prefix and data only`);
+ const prefix = str.slice(0, sepIndex);
+ const _words = str.slice(sepIndex + 1);
+ if (_words.length < 6)
+ throw new Error('Data must be at least 6 characters long');
+ const words = BECH_ALPHABET.decode(_words).slice(0, -6);
+ const sum = bechChecksum(prefix, words, ENCODING_CONST);
+ if (!_words.endsWith(sum))
+ throw new Error(`Invalid checksum in ${str}: expected "${sum}"`);
+ return { prefix, words };
+ }
+ const decodeUnsafe = unsafeWrapper(decode);
+ function decodeToBytes(str) {
+ const { prefix, words } = decode(str, false);
+ return { prefix, words, bytes: fromWords(words) };
+ }
+ return { encode, decode, decodeToBytes, decodeUnsafe, fromWords, fromWordsUnsafe, toWords };
+ }
+ const bech32 = genBech32('bech32');
+ genBech32('bech32m');
+ const utf8 = {
+ encode: (data) => new TextDecoder().decode(data),
+ decode: (str) => new TextEncoder().encode(str),
+ };
+ const hex = chain(radix2(4), alphabet('0123456789abcdef'), join(''), normalize$1((s) => {
+ if (typeof s !== 'string' || s.length % 2)
+ throw new TypeError(`hex.decode: expected string, got ${typeof s} with length ${s.length}`);
+ return s.toLowerCase();
+ }));
+ const CODERS = {
+ utf8, hex, base16, base32, base64, base64url, base58, base58xmr
+ };
+ `Invalid encoding type. Available types: ${Object.keys(CODERS).join(', ')}`;
+
+ var english = {};
+
+ Object.defineProperty(english, "__esModule", { value: true });
+ var wordlist = english.wordlist = void 0;
+ wordlist = english.wordlist = `abandon
+ability
+able
+about
+above
+absent
+absorb
+abstract
+absurd
+abuse
+access
+accident
+account
+accuse
+achieve
+acid
+acoustic
+acquire
+across
+act
+action
+actor
+actress
+actual
+adapt
+add
+addict
+address
+adjust
+admit
+adult
+advance
+advice
+aerobic
+affair
+afford
+afraid
+again
+age
+agent
+agree
+ahead
+aim
+air
+airport
+aisle
+alarm
+album
+alcohol
+alert
+alien
+all
+alley
+allow
+almost
+alone
+alpha
+already
+also
+alter
+always
+amateur
+amazing
+among
+amount
+amused
+analyst
+anchor
+ancient
+anger
+angle
+angry
+animal
+ankle
+announce
+annual
+another
+answer
+antenna
+antique
+anxiety
+any
+apart
+apology
+appear
+apple
+approve
+april
+arch
+arctic
+area
+arena
+argue
+arm
+armed
+armor
+army
+around
+arrange
+arrest
+arrive
+arrow
+art
+artefact
+artist
+artwork
+ask
+aspect
+assault
+asset
+assist
+assume
+asthma
+athlete
+atom
+attack
+attend
+attitude
+attract
+auction
+audit
+august
+aunt
+author
+auto
+autumn
+average
+avocado
+avoid
+awake
+aware
+away
+awesome
+awful
+awkward
+axis
+baby
+bachelor
+bacon
+badge
+bag
+balance
+balcony
+ball
+bamboo
+banana
+banner
+bar
+barely
+bargain
+barrel
+base
+basic
+basket
+battle
+beach
+bean
+beauty
+because
+become
+beef
+before
+begin
+behave
+behind
+believe
+below
+belt
+bench
+benefit
+best
+betray
+better
+between
+beyond
+bicycle
+bid
+bike
+bind
+biology
+bird
+birth
+bitter
+black
+blade
+blame
+blanket
+blast
+bleak
+bless
+blind
+blood
+blossom
+blouse
+blue
+blur
+blush
+board
+boat
+body
+boil
+bomb
+bone
+bonus
+book
+boost
+border
+boring
+borrow
+boss
+bottom
+bounce
+box
+boy
+bracket
+brain
+brand
+brass
+brave
+bread
+breeze
+brick
+bridge
+brief
+bright
+bring
+brisk
+broccoli
+broken
+bronze
+broom
+brother
+brown
+brush
+bubble
+buddy
+budget
+buffalo
+build
+bulb
+bulk
+bullet
+bundle
+bunker
+burden
+burger
+burst
+bus
+business
+busy
+butter
+buyer
+buzz
+cabbage
+cabin
+cable
+cactus
+cage
+cake
+call
+calm
+camera
+camp
+can
+canal
+cancel
+candy
+cannon
+canoe
+canvas
+canyon
+capable
+capital
+captain
+car
+carbon
+card
+cargo
+carpet
+carry
+cart
+case
+cash
+casino
+castle
+casual
+cat
+catalog
+catch
+category
+cattle
+caught
+cause
+caution
+cave
+ceiling
+celery
+cement
+census
+century
+cereal
+certain
+chair
+chalk
+champion
+change
+chaos
+chapter
+charge
+chase
+chat
+cheap
+check
+cheese
+chef
+cherry
+chest
+chicken
+chief
+child
+chimney
+choice
+choose
+chronic
+chuckle
+chunk
+churn
+cigar
+cinnamon
+circle
+citizen
+city
+civil
+claim
+clap
+clarify
+claw
+clay
+clean
+clerk
+clever
+click
+client
+cliff
+climb
+clinic
+clip
+clock
+clog
+close
+cloth
+cloud
+clown
+club
+clump
+cluster
+clutch
+coach
+coast
+coconut
+code
+coffee
+coil
+coin
+collect
+color
+column
+combine
+come
+comfort
+comic
+common
+company
+concert
+conduct
+confirm
+congress
+connect
+consider
+control
+convince
+cook
+cool
+copper
+copy
+coral
+core
+corn
+correct
+cost
+cotton
+couch
+country
+couple
+course
+cousin
+cover
+coyote
+crack
+cradle
+craft
+cram
+crane
+crash
+crater
+crawl
+crazy
+cream
+credit
+creek
+crew
+cricket
+crime
+crisp
+critic
+crop
+cross
+crouch
+crowd
+crucial
+cruel
+cruise
+crumble
+crunch
+crush
+cry
+crystal
+cube
+culture
+cup
+cupboard
+curious
+current
+curtain
+curve
+cushion
+custom
+cute
+cycle
+dad
+damage
+damp
+dance
+danger
+daring
+dash
+daughter
+dawn
+day
+deal
+debate
+debris
+decade
+december
+decide
+decline
+decorate
+decrease
+deer
+defense
+define
+defy
+degree
+delay
+deliver
+demand
+demise
+denial
+dentist
+deny
+depart
+depend
+deposit
+depth
+deputy
+derive
+describe
+desert
+design
+desk
+despair
+destroy
+detail
+detect
+develop
+device
+devote
+diagram
+dial
+diamond
+diary
+dice
+diesel
+diet
+differ
+digital
+dignity
+dilemma
+dinner
+dinosaur
+direct
+dirt
+disagree
+discover
+disease
+dish
+dismiss
+disorder
+display
+distance
+divert
+divide
+divorce
+dizzy
+doctor
+document
+dog
+doll
+dolphin
+domain
+donate
+donkey
+donor
+door
+dose
+double
+dove
+draft
+dragon
+drama
+drastic
+draw
+dream
+dress
+drift
+drill
+drink
+drip
+drive
+drop
+drum
+dry
+duck
+dumb
+dune
+during
+dust
+dutch
+duty
+dwarf
+dynamic
+eager
+eagle
+early
+earn
+earth
+easily
+east
+easy
+echo
+ecology
+economy
+edge
+edit
+educate
+effort
+egg
+eight
+either
+elbow
+elder
+electric
+elegant
+element
+elephant
+elevator
+elite
+else
+embark
+embody
+embrace
+emerge
+emotion
+employ
+empower
+empty
+enable
+enact
+end
+endless
+endorse
+enemy
+energy
+enforce
+engage
+engine
+enhance
+enjoy
+enlist
+enough
+enrich
+enroll
+ensure
+enter
+entire
+entry
+envelope
+episode
+equal
+equip
+era
+erase
+erode
+erosion
+error
+erupt
+escape
+essay
+essence
+estate
+eternal
+ethics
+evidence
+evil
+evoke
+evolve
+exact
+example
+excess
+exchange
+excite
+exclude
+excuse
+execute
+exercise
+exhaust
+exhibit
+exile
+exist
+exit
+exotic
+expand
+expect
+expire
+explain
+expose
+express
+extend
+extra
+eye
+eyebrow
+fabric
+face
+faculty
+fade
+faint
+faith
+fall
+false
+fame
+family
+famous
+fan
+fancy
+fantasy
+farm
+fashion
+fat
+fatal
+father
+fatigue
+fault
+favorite
+feature
+february
+federal
+fee
+feed
+feel
+female
+fence
+festival
+fetch
+fever
+few
+fiber
+fiction
+field
+figure
+file
+film
+filter
+final
+find
+fine
+finger
+finish
+fire
+firm
+first
+fiscal
+fish
+fit
+fitness
+fix
+flag
+flame
+flash
+flat
+flavor
+flee
+flight
+flip
+float
+flock
+floor
+flower
+fluid
+flush
+fly
+foam
+focus
+fog
+foil
+fold
+follow
+food
+foot
+force
+forest
+forget
+fork
+fortune
+forum
+forward
+fossil
+foster
+found
+fox
+fragile
+frame
+frequent
+fresh
+friend
+fringe
+frog
+front
+frost
+frown
+frozen
+fruit
+fuel
+fun
+funny
+furnace
+fury
+future
+gadget
+gain
+galaxy
+gallery
+game
+gap
+garage
+garbage
+garden
+garlic
+garment
+gas
+gasp
+gate
+gather
+gauge
+gaze
+general
+genius
+genre
+gentle
+genuine
+gesture
+ghost
+giant
+gift
+giggle
+ginger
+giraffe
+girl
+give
+glad
+glance
+glare
+glass
+glide
+glimpse
+globe
+gloom
+glory
+glove
+glow
+glue
+goat
+goddess
+gold
+good
+goose
+gorilla
+gospel
+gossip
+govern
+gown
+grab
+grace
+grain
+grant
+grape
+grass
+gravity
+great
+green
+grid
+grief
+grit
+grocery
+group
+grow
+grunt
+guard
+guess
+guide
+guilt
+guitar
+gun
+gym
+habit
+hair
+half
+hammer
+hamster
+hand
+happy
+harbor
+hard
+harsh
+harvest
+hat
+have
+hawk
+hazard
+head
+health
+heart
+heavy
+hedgehog
+height
+hello
+helmet
+help
+hen
+hero
+hidden
+high
+hill
+hint
+hip
+hire
+history
+hobby
+hockey
+hold
+hole
+holiday
+hollow
+home
+honey
+hood
+hope
+horn
+horror
+horse
+hospital
+host
+hotel
+hour
+hover
+hub
+huge
+human
+humble
+humor
+hundred
+hungry
+hunt
+hurdle
+hurry
+hurt
+husband
+hybrid
+ice
+icon
+idea
+identify
+idle
+ignore
+ill
+illegal
+illness
+image
+imitate
+immense
+immune
+impact
+impose
+improve
+impulse
+inch
+include
+income
+increase
+index
+indicate
+indoor
+industry
+infant
+inflict
+inform
+inhale
+inherit
+initial
+inject
+injury
+inmate
+inner
+innocent
+input
+inquiry
+insane
+insect
+inside
+inspire
+install
+intact
+interest
+into
+invest
+invite
+involve
+iron
+island
+isolate
+issue
+item
+ivory
+jacket
+jaguar
+jar
+jazz
+jealous
+jeans
+jelly
+jewel
+job
+join
+joke
+journey
+joy
+judge
+juice
+jump
+jungle
+junior
+junk
+just
+kangaroo
+keen
+keep
+ketchup
+key
+kick
+kid
+kidney
+kind
+kingdom
+kiss
+kit
+kitchen
+kite
+kitten
+kiwi
+knee
+knife
+knock
+know
+lab
+label
+labor
+ladder
+lady
+lake
+lamp
+language
+laptop
+large
+later
+latin
+laugh
+laundry
+lava
+law
+lawn
+lawsuit
+layer
+lazy
+leader
+leaf
+learn
+leave
+lecture
+left
+leg
+legal
+legend
+leisure
+lemon
+lend
+length
+lens
+leopard
+lesson
+letter
+level
+liar
+liberty
+library
+license
+life
+lift
+light
+like
+limb
+limit
+link
+lion
+liquid
+list
+little
+live
+lizard
+load
+loan
+lobster
+local
+lock
+logic
+lonely
+long
+loop
+lottery
+loud
+lounge
+love
+loyal
+lucky
+luggage
+lumber
+lunar
+lunch
+luxury
+lyrics
+machine
+mad
+magic
+magnet
+maid
+mail
+main
+major
+make
+mammal
+man
+manage
+mandate
+mango
+mansion
+manual
+maple
+marble
+march
+margin
+marine
+market
+marriage
+mask
+mass
+master
+match
+material
+math
+matrix
+matter
+maximum
+maze
+meadow
+mean
+measure
+meat
+mechanic
+medal
+media
+melody
+melt
+member
+memory
+mention
+menu
+mercy
+merge
+merit
+merry
+mesh
+message
+metal
+method
+middle
+midnight
+milk
+million
+mimic
+mind
+minimum
+minor
+minute
+miracle
+mirror
+misery
+miss
+mistake
+mix
+mixed
+mixture
+mobile
+model
+modify
+mom
+moment
+monitor
+monkey
+monster
+month
+moon
+moral
+more
+morning
+mosquito
+mother
+motion
+motor
+mountain
+mouse
+move
+movie
+much
+muffin
+mule
+multiply
+muscle
+museum
+mushroom
+music
+must
+mutual
+myself
+mystery
+myth
+naive
+name
+napkin
+narrow
+nasty
+nation
+nature
+near
+neck
+need
+negative
+neglect
+neither
+nephew
+nerve
+nest
+net
+network
+neutral
+never
+news
+next
+nice
+night
+noble
+noise
+nominee
+noodle
+normal
+north
+nose
+notable
+note
+nothing
+notice
+novel
+now
+nuclear
+number
+nurse
+nut
+oak
+obey
+object
+oblige
+obscure
+observe
+obtain
+obvious
+occur
+ocean
+october
+odor
+off
+offer
+office
+often
+oil
+okay
+old
+olive
+olympic
+omit
+once
+one
+onion
+online
+only
+open
+opera
+opinion
+oppose
+option
+orange
+orbit
+orchard
+order
+ordinary
+organ
+orient
+original
+orphan
+ostrich
+other
+outdoor
+outer
+output
+outside
+oval
+oven
+over
+own
+owner
+oxygen
+oyster
+ozone
+pact
+paddle
+page
+pair
+palace
+palm
+panda
+panel
+panic
+panther
+paper
+parade
+parent
+park
+parrot
+party
+pass
+patch
+path
+patient
+patrol
+pattern
+pause
+pave
+payment
+peace
+peanut
+pear
+peasant
+pelican
+pen
+penalty
+pencil
+people
+pepper
+perfect
+permit
+person
+pet
+phone
+photo
+phrase
+physical
+piano
+picnic
+picture
+piece
+pig
+pigeon
+pill
+pilot
+pink
+pioneer
+pipe
+pistol
+pitch
+pizza
+place
+planet
+plastic
+plate
+play
+please
+pledge
+pluck
+plug
+plunge
+poem
+poet
+point
+polar
+pole
+police
+pond
+pony
+pool
+popular
+portion
+position
+possible
+post
+potato
+pottery
+poverty
+powder
+power
+practice
+praise
+predict
+prefer
+prepare
+present
+pretty
+prevent
+price
+pride
+primary
+print
+priority
+prison
+private
+prize
+problem
+process
+produce
+profit
+program
+project
+promote
+proof
+property
+prosper
+protect
+proud
+provide
+public
+pudding
+pull
+pulp
+pulse
+pumpkin
+punch
+pupil
+puppy
+purchase
+purity
+purpose
+purse
+push
+put
+puzzle
+pyramid
+quality
+quantum
+quarter
+question
+quick
+quit
+quiz
+quote
+rabbit
+raccoon
+race
+rack
+radar
+radio
+rail
+rain
+raise
+rally
+ramp
+ranch
+random
+range
+rapid
+rare
+rate
+rather
+raven
+raw
+razor
+ready
+real
+reason
+rebel
+rebuild
+recall
+receive
+recipe
+record
+recycle
+reduce
+reflect
+reform
+refuse
+region
+regret
+regular
+reject
+relax
+release
+relief
+rely
+remain
+remember
+remind
+remove
+render
+renew
+rent
+reopen
+repair
+repeat
+replace
+report
+require
+rescue
+resemble
+resist
+resource
+response
+result
+retire
+retreat
+return
+reunion
+reveal
+review
+reward
+rhythm
+rib
+ribbon
+rice
+rich
+ride
+ridge
+rifle
+right
+rigid
+ring
+riot
+ripple
+risk
+ritual
+rival
+river
+road
+roast
+robot
+robust
+rocket
+romance
+roof
+rookie
+room
+rose
+rotate
+rough
+round
+route
+royal
+rubber
+rude
+rug
+rule
+run
+runway
+rural
+sad
+saddle
+sadness
+safe
+sail
+salad
+salmon
+salon
+salt
+salute
+same
+sample
+sand
+satisfy
+satoshi
+sauce
+sausage
+save
+say
+scale
+scan
+scare
+scatter
+scene
+scheme
+school
+science
+scissors
+scorpion
+scout
+scrap
+screen
+script
+scrub
+sea
+search
+season
+seat
+second
+secret
+section
+security
+seed
+seek
+segment
+select
+sell
+seminar
+senior
+sense
+sentence
+series
+service
+session
+settle
+setup
+seven
+shadow
+shaft
+shallow
+share
+shed
+shell
+sheriff
+shield
+shift
+shine
+ship
+shiver
+shock
+shoe
+shoot
+shop
+short
+shoulder
+shove
+shrimp
+shrug
+shuffle
+shy
+sibling
+sick
+side
+siege
+sight
+sign
+silent
+silk
+silly
+silver
+similar
+simple
+since
+sing
+siren
+sister
+situate
+six
+size
+skate
+sketch
+ski
+skill
+skin
+skirt
+skull
+slab
+slam
+sleep
+slender
+slice
+slide
+slight
+slim
+slogan
+slot
+slow
+slush
+small
+smart
+smile
+smoke
+smooth
+snack
+snake
+snap
+sniff
+snow
+soap
+soccer
+social
+sock
+soda
+soft
+solar
+soldier
+solid
+solution
+solve
+someone
+song
+soon
+sorry
+sort
+soul
+sound
+soup
+source
+south
+space
+spare
+spatial
+spawn
+speak
+special
+speed
+spell
+spend
+sphere
+spice
+spider
+spike
+spin
+spirit
+split
+spoil
+sponsor
+spoon
+sport
+spot
+spray
+spread
+spring
+spy
+square
+squeeze
+squirrel
+stable
+stadium
+staff
+stage
+stairs
+stamp
+stand
+start
+state
+stay
+steak
+steel
+stem
+step
+stereo
+stick
+still
+sting
+stock
+stomach
+stone
+stool
+story
+stove
+strategy
+street
+strike
+strong
+struggle
+student
+stuff
+stumble
+style
+subject
+submit
+subway
+success
+such
+sudden
+suffer
+sugar
+suggest
+suit
+summer
+sun
+sunny
+sunset
+super
+supply
+supreme
+sure
+surface
+surge
+surprise
+surround
+survey
+suspect
+sustain
+swallow
+swamp
+swap
+swarm
+swear
+sweet
+swift
+swim
+swing
+switch
+sword
+symbol
+symptom
+syrup
+system
+table
+tackle
+tag
+tail
+talent
+talk
+tank
+tape
+target
+task
+taste
+tattoo
+taxi
+teach
+team
+tell
+ten
+tenant
+tennis
+tent
+term
+test
+text
+thank
+that
+theme
+then
+theory
+there
+they
+thing
+this
+thought
+three
+thrive
+throw
+thumb
+thunder
+ticket
+tide
+tiger
+tilt
+timber
+time
+tiny
+tip
+tired
+tissue
+title
+toast
+tobacco
+today
+toddler
+toe
+together
+toilet
+token
+tomato
+tomorrow
+tone
+tongue
+tonight
+tool
+tooth
+top
+topic
+topple
+torch
+tornado
+tortoise
+toss
+total
+tourist
+toward
+tower
+town
+toy
+track
+trade
+traffic
+tragic
+train
+transfer
+trap
+trash
+travel
+tray
+treat
+tree
+trend
+trial
+tribe
+trick
+trigger
+trim
+trip
+trophy
+trouble
+truck
+true
+truly
+trumpet
+trust
+truth
+try
+tube
+tuition
+tumble
+tuna
+tunnel
+turkey
+turn
+turtle
+twelve
+twenty
+twice
+twin
+twist
+two
+type
+typical
+ugly
+umbrella
+unable
+unaware
+uncle
+uncover
+under
+undo
+unfair
+unfold
+unhappy
+uniform
+unique
+unit
+universe
+unknown
+unlock
+until
+unusual
+unveil
+update
+upgrade
+uphold
+upon
+upper
+upset
+urban
+urge
+usage
+use
+used
+useful
+useless
+usual
+utility
+vacant
+vacuum
+vague
+valid
+valley
+valve
+van
+vanish
+vapor
+various
+vast
+vault
+vehicle
+velvet
+vendor
+venture
+venue
+verb
+verify
+version
+very
+vessel
+veteran
+viable
+vibrant
+vicious
+victory
+video
+view
+village
+vintage
+violin
+virtual
+virus
+visa
+visit
+visual
+vital
+vivid
+vocal
+voice
+void
+volcano
+volume
+vote
+voyage
+wage
+wagon
+wait
+walk
+wall
+walnut
+want
+warfare
+warm
+warrior
+wash
+wasp
+waste
+water
+wave
+way
+wealth
+weapon
+wear
+weasel
+weather
+web
+wedding
+weekend
+weird
+welcome
+west
+wet
+whale
+what
+wheat
+wheel
+when
+where
+whip
+whisper
+wide
+width
+wife
+wild
+will
+win
+window
+wine
+wing
+wink
+winner
+winter
+wire
+wisdom
+wise
+wish
+witness
+wolf
+woman
+wonder
+wood
+wool
+word
+work
+world
+worry
+worth
+wrap
+wreck
+wrestle
+wrist
+write
+wrong
+yard
+year
+yellow
+you
+young
+youth
+zebra
+zero
+zone
+zoo`.split('\n');
+
+ var bip39 = {};
+
+ var _assert = {};
+
+ Object.defineProperty(_assert, "__esModule", { value: true });
+ _assert.output = _assert.exists = _assert.hash = _assert.bytes = _assert.bool = _assert.number = void 0;
+ function number$1(n) {
+ if (!Number.isSafeInteger(n) || n < 0)
+ throw new Error(`Wrong positive integer: ${n}`);
+ }
+ _assert.number = number$1;
+ function bool$1(b) {
+ if (typeof b !== 'boolean')
+ throw new Error(`Expected boolean, not ${b}`);
+ }
+ _assert.bool = bool$1;
+ function bytes$1(b, ...lengths) {
+ if (!(b instanceof Uint8Array))
+ throw new TypeError('Expected Uint8Array');
+ if (lengths.length > 0 && !lengths.includes(b.length))
+ throw new TypeError(`Expected Uint8Array of length ${lengths}, not of length=${b.length}`);
+ }
+ _assert.bytes = bytes$1;
+ function hash$1(hash) {
+ if (typeof hash !== 'function' || typeof hash.create !== 'function')
+ throw new Error('Hash should be wrapped by utils.wrapConstructor');
+ number$1(hash.outputLen);
+ number$1(hash.blockLen);
+ }
+ _assert.hash = hash$1;
+ function exists$1(instance, checkFinished = true) {
+ if (instance.destroyed)
+ throw new Error('Hash instance has been destroyed');
+ if (checkFinished && instance.finished)
+ throw new Error('Hash#digest() has already been called');
+ }
+ _assert.exists = exists$1;
+ function output$1(out, instance) {
+ bytes$1(out);
+ const min = instance.outputLen;
+ if (out.length < min) {
+ throw new Error(`digestInto() expects output buffer of length at least ${min}`);
+ }
+ }
+ _assert.output = output$1;
+ const assert$1 = {
+ number: number$1,
+ bool: bool$1,
+ bytes: bytes$1,
+ hash: hash$1,
+ exists: exists$1,
+ output: output$1,
+ };
+ _assert.default = assert$1;
+
+ var pbkdf2$1 = {};
+
+ var hmac$2 = {};
+
+ var utils = {};
+
+ var cryptoBrowser = {};
+
+ Object.defineProperty(cryptoBrowser, "__esModule", { value: true });
+ cryptoBrowser.crypto = void 0;
+ cryptoBrowser.crypto = {
+ node: undefined,
+ web: typeof self === 'object' && 'crypto' in self ? self.crypto : undefined,
+ };
+
+ (function (exports) {
+ /*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.randomBytes = exports.wrapConstructorWithOpts = exports.wrapConstructor = exports.checkOpts = exports.Hash = exports.concatBytes = exports.toBytes = exports.utf8ToBytes = exports.asyncLoop = exports.nextTick = exports.hexToBytes = exports.bytesToHex = exports.isLE = exports.rotr = exports.createView = exports.u32 = exports.u8 = void 0;
+ // The import here is via the package name. This is to ensure
+ // that exports mapping/resolution does fall into place.
+ const crypto_1 = cryptoBrowser;
+ // Cast array to different type
+ const u8 = (arr) => new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);
+ exports.u8 = u8;
+ const u32 = (arr) => new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
+ exports.u32 = u32;
+ // Cast array to view
+ const createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
+ exports.createView = createView;
+ // The rotate right (circular right shift) operation for uint32
+ const rotr = (word, shift) => (word << (32 - shift)) | (word >>> shift);
+ exports.rotr = rotr;
+ exports.isLE = new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44;
+ // There is almost no big endian hardware, but js typed arrays uses platform specific endianness.
+ // So, just to be sure not to corrupt anything.
+ if (!exports.isLE)
+ throw new Error('Non little-endian hardware is not supported');
+ const hexes = Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, '0'));
+ /**
+ * @example bytesToHex(Uint8Array.from([0xde, 0xad, 0xbe, 0xef]))
+ */
+ function bytesToHex(uint8a) {
+ // pre-caching improves the speed 6x
+ if (!(uint8a instanceof Uint8Array))
+ throw new Error('Uint8Array expected');
+ let hex = '';
+ for (let i = 0; i < uint8a.length; i++) {
+ hex += hexes[uint8a[i]];
+ }
+ return hex;
+ }
+ exports.bytesToHex = bytesToHex;
+ /**
+ * @example hexToBytes('deadbeef')
+ */
+ function hexToBytes(hex) {
+ if (typeof hex !== 'string') {
+ throw new TypeError('hexToBytes: expected string, got ' + typeof hex);
+ }
+ if (hex.length % 2)
+ throw new Error('hexToBytes: received invalid unpadded hex');
+ const array = new Uint8Array(hex.length / 2);
+ for (let i = 0; i < array.length; i++) {
+ const j = i * 2;
+ const hexByte = hex.slice(j, j + 2);
+ const byte = Number.parseInt(hexByte, 16);
+ if (Number.isNaN(byte) || byte < 0)
+ throw new Error('Invalid byte sequence');
+ array[i] = byte;
+ }
+ return array;
+ }
+ exports.hexToBytes = hexToBytes;
+ // There is no setImmediate in browser and setTimeout is slow. However, call to async function will return Promise
+ // which will be fullfiled only on next scheduler queue processing step and this is exactly what we need.
+ const nextTick = async () => { };
+ exports.nextTick = nextTick;
+ // Returns control to thread each 'tick' ms to avoid blocking
+ async function asyncLoop(iters, tick, cb) {
+ let ts = Date.now();
+ for (let i = 0; i < iters; i++) {
+ cb(i);
+ // Date.now() is not monotonic, so in case if clock goes backwards we return return control too
+ const diff = Date.now() - ts;
+ if (diff >= 0 && diff < tick)
+ continue;
+ await (0, exports.nextTick)();
+ ts += diff;
+ }
+ }
+ exports.asyncLoop = asyncLoop;
+ function utf8ToBytes(str) {
+ if (typeof str !== 'string') {
+ throw new TypeError(`utf8ToBytes expected string, got ${typeof str}`);
+ }
+ return new TextEncoder().encode(str);
+ }
+ exports.utf8ToBytes = utf8ToBytes;
+ function toBytes(data) {
+ if (typeof data === 'string')
+ data = utf8ToBytes(data);
+ if (!(data instanceof Uint8Array))
+ throw new TypeError(`Expected input type is Uint8Array (got ${typeof data})`);
+ return data;
+ }
+ exports.toBytes = toBytes;
+ /**
+ * Concats Uint8Array-s into one; like `Buffer.concat([buf1, buf2])`
+ * @example concatBytes(buf1, buf2)
+ */
+ function concatBytes(...arrays) {
+ if (!arrays.every((a) => a instanceof Uint8Array))
+ throw new Error('Uint8Array list expected');
+ if (arrays.length === 1)
+ return arrays[0];
+ const length = arrays.reduce((a, arr) => a + arr.length, 0);
+ const result = new Uint8Array(length);
+ for (let i = 0, pad = 0; i < arrays.length; i++) {
+ const arr = arrays[i];
+ result.set(arr, pad);
+ pad += arr.length;
+ }
+ return result;
+ }
+ exports.concatBytes = concatBytes;
+ // For runtime check if class implements interface
+ class Hash {
+ // Safe version that clones internal state
+ clone() {
+ return this._cloneInto();
+ }
+ }
+ exports.Hash = Hash;
+ // Check if object doens't have custom constructor (like Uint8Array/Array)
+ const isPlainObject = (obj) => Object.prototype.toString.call(obj) === '[object Object]' && obj.constructor === Object;
+ function checkOpts(defaults, opts) {
+ if (opts !== undefined && (typeof opts !== 'object' || !isPlainObject(opts)))
+ throw new TypeError('Options should be object or undefined');
+ const merged = Object.assign(defaults, opts);
+ return merged;
+ }
+ exports.checkOpts = checkOpts;
+ function wrapConstructor(hashConstructor) {
+ const hashC = (message) => hashConstructor().update(toBytes(message)).digest();
+ const tmp = hashConstructor();
+ hashC.outputLen = tmp.outputLen;
+ hashC.blockLen = tmp.blockLen;
+ hashC.create = () => hashConstructor();
+ return hashC;
+ }
+ exports.wrapConstructor = wrapConstructor;
+ function wrapConstructorWithOpts(hashCons) {
+ const hashC = (msg, opts) => hashCons(opts).update(toBytes(msg)).digest();
+ const tmp = hashCons({});
+ hashC.outputLen = tmp.outputLen;
+ hashC.blockLen = tmp.blockLen;
+ hashC.create = (opts) => hashCons(opts);
+ return hashC;
+ }
+ exports.wrapConstructorWithOpts = wrapConstructorWithOpts;
+ /**
+ * Secure PRNG
+ */
+ function randomBytes(bytesLength = 32) {
+ if (crypto_1.crypto.web) {
+ return crypto_1.crypto.web.getRandomValues(new Uint8Array(bytesLength));
+ }
+ else if (crypto_1.crypto.node) {
+ return new Uint8Array(crypto_1.crypto.node.randomBytes(bytesLength).buffer);
+ }
+ else {
+ throw new Error("The environment doesn't have randomBytes function");
+ }
+ }
+ exports.randomBytes = randomBytes;
+
+ } (utils));
+
+ (function (exports) {
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.hmac = void 0;
+ const _assert_js_1 = _assert;
+ const utils_js_1 = utils;
+ // HMAC (RFC 2104)
+ class HMAC extends utils_js_1.Hash {
+ constructor(hash, _key) {
+ super();
+ this.finished = false;
+ this.destroyed = false;
+ _assert_js_1.default.hash(hash);
+ const key = (0, utils_js_1.toBytes)(_key);
+ this.iHash = hash.create();
+ if (typeof this.iHash.update !== 'function')
+ throw new TypeError('Expected instance of class which extends utils.Hash');
+ this.blockLen = this.iHash.blockLen;
+ this.outputLen = this.iHash.outputLen;
+ const blockLen = this.blockLen;
+ const pad = new Uint8Array(blockLen);
+ // blockLen can be bigger than outputLen
+ pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);
+ for (let i = 0; i < pad.length; i++)
+ pad[i] ^= 0x36;
+ this.iHash.update(pad);
+ // By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone
+ this.oHash = hash.create();
+ // Undo internal XOR && apply outer XOR
+ for (let i = 0; i < pad.length; i++)
+ pad[i] ^= 0x36 ^ 0x5c;
+ this.oHash.update(pad);
+ pad.fill(0);
+ }
+ update(buf) {
+ _assert_js_1.default.exists(this);
+ this.iHash.update(buf);
+ return this;
+ }
+ digestInto(out) {
+ _assert_js_1.default.exists(this);
+ _assert_js_1.default.bytes(out, this.outputLen);
+ this.finished = true;
+ this.iHash.digestInto(out);
+ this.oHash.update(out);
+ this.oHash.digestInto(out);
+ this.destroy();
+ }
+ digest() {
+ const out = new Uint8Array(this.oHash.outputLen);
+ this.digestInto(out);
+ return out;
+ }
+ _cloneInto(to) {
+ // Create new instance without calling constructor since key already in state and we don't know it.
+ to || (to = Object.create(Object.getPrototypeOf(this), {}));
+ const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
+ to = to;
+ to.finished = finished;
+ to.destroyed = destroyed;
+ to.blockLen = blockLen;
+ to.outputLen = outputLen;
+ to.oHash = oHash._cloneInto(to.oHash);
+ to.iHash = iHash._cloneInto(to.iHash);
+ return to;
+ }
+ destroy() {
+ this.destroyed = true;
+ this.oHash.destroy();
+ this.iHash.destroy();
+ }
+ }
+ /**
+ * HMAC: RFC2104 message authentication code.
+ * @param hash - function that would be used e.g. sha256
+ * @param key - message key
+ * @param message - message data
+ */
+ const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();
+ exports.hmac = hmac;
+ exports.hmac.create = (hash, key) => new HMAC(hash, key);
+
+ } (hmac$2));
+
+ Object.defineProperty(pbkdf2$1, "__esModule", { value: true });
+ pbkdf2$1.pbkdf2Async = pbkdf2$1.pbkdf2 = void 0;
+ const _assert_js_1$1 = _assert;
+ const hmac_js_1 = hmac$2;
+ const utils_js_1$3 = utils;
+ // Common prologue and epilogue for sync/async functions
+ function pbkdf2Init(hash, _password, _salt, _opts) {
+ _assert_js_1$1.default.hash(hash);
+ const opts = (0, utils_js_1$3.checkOpts)({ dkLen: 32, asyncTick: 10 }, _opts);
+ const { c, dkLen, asyncTick } = opts;
+ _assert_js_1$1.default.number(c);
+ _assert_js_1$1.default.number(dkLen);
+ _assert_js_1$1.default.number(asyncTick);
+ if (c < 1)
+ throw new Error('PBKDF2: iterations (c) should be >= 1');
+ const password = (0, utils_js_1$3.toBytes)(_password);
+ const salt = (0, utils_js_1$3.toBytes)(_salt);
+ // DK = PBKDF2(PRF, Password, Salt, c, dkLen);
+ const DK = new Uint8Array(dkLen);
+ // U1 = PRF(Password, Salt + INT_32_BE(i))
+ const PRF = hmac_js_1.hmac.create(hash, password);
+ const PRFSalt = PRF._cloneInto().update(salt);
+ return { c, dkLen, asyncTick, DK, PRF, PRFSalt };
+ }
+ function pbkdf2Output(PRF, PRFSalt, DK, prfW, u) {
+ PRF.destroy();
+ PRFSalt.destroy();
+ if (prfW)
+ prfW.destroy();
+ u.fill(0);
+ return DK;
+ }
+ /**
+ * PBKDF2-HMAC: RFC 2898 key derivation function
+ * @param hash - hash function that would be used e.g. sha256
+ * @param password - password from which a derived key is generated
+ * @param salt - cryptographic salt
+ * @param opts - {c, dkLen} where c is work factor and dkLen is output message size
+ */
+ function pbkdf2(hash, password, salt, opts) {
+ const { c, dkLen, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts);
+ let prfW; // Working copy
+ const arr = new Uint8Array(4);
+ const view = (0, utils_js_1$3.createView)(arr);
+ const u = new Uint8Array(PRF.outputLen);
+ // DK = T1 + T2 + ⋯ + Tdklen/hlen
+ for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) {
+ // Ti = F(Password, Salt, c, i)
+ const Ti = DK.subarray(pos, pos + PRF.outputLen);
+ view.setInt32(0, ti, false);
+ // F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc
+ // U1 = PRF(Password, Salt + INT_32_BE(i))
+ (prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u);
+ Ti.set(u.subarray(0, Ti.length));
+ for (let ui = 1; ui < c; ui++) {
+ // Uc = PRF(Password, Uc−1)
+ PRF._cloneInto(prfW).update(u).digestInto(u);
+ for (let i = 0; i < Ti.length; i++)
+ Ti[i] ^= u[i];
+ }
+ }
+ return pbkdf2Output(PRF, PRFSalt, DK, prfW, u);
+ }
+ pbkdf2$1.pbkdf2 = pbkdf2;
+ async function pbkdf2Async(hash, password, salt, opts) {
+ const { c, dkLen, asyncTick, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts);
+ let prfW; // Working copy
+ const arr = new Uint8Array(4);
+ const view = (0, utils_js_1$3.createView)(arr);
+ const u = new Uint8Array(PRF.outputLen);
+ // DK = T1 + T2 + ⋯ + Tdklen/hlen
+ for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) {
+ // Ti = F(Password, Salt, c, i)
+ const Ti = DK.subarray(pos, pos + PRF.outputLen);
+ view.setInt32(0, ti, false);
+ // F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc
+ // U1 = PRF(Password, Salt + INT_32_BE(i))
+ (prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u);
+ Ti.set(u.subarray(0, Ti.length));
+ await (0, utils_js_1$3.asyncLoop)(c - 1, asyncTick, (i) => {
+ // Uc = PRF(Password, Uc−1)
+ PRF._cloneInto(prfW).update(u).digestInto(u);
+ for (let i = 0; i < Ti.length; i++)
+ Ti[i] ^= u[i];
+ });
+ }
+ return pbkdf2Output(PRF, PRFSalt, DK, prfW, u);
+ }
+ pbkdf2$1.pbkdf2Async = pbkdf2Async;
+
+ var sha256$1 = {};
+
+ var _sha2 = {};
+
+ Object.defineProperty(_sha2, "__esModule", { value: true });
+ _sha2.SHA2 = void 0;
+ const _assert_js_1 = _assert;
+ const utils_js_1$2 = utils;
+ // Polyfill for Safari 14
+ function setBigUint64$1(view, byteOffset, value, isLE) {
+ if (typeof view.setBigUint64 === 'function')
+ return view.setBigUint64(byteOffset, value, isLE);
+ const _32n = BigInt(32);
+ const _u32_max = BigInt(0xffffffff);
+ const wh = Number((value >> _32n) & _u32_max);
+ const wl = Number(value & _u32_max);
+ const h = isLE ? 4 : 0;
+ const l = isLE ? 0 : 4;
+ view.setUint32(byteOffset + h, wh, isLE);
+ view.setUint32(byteOffset + l, wl, isLE);
+ }
+ // Base SHA2 class (RFC 6234)
+ let SHA2$1 = class SHA2 extends utils_js_1$2.Hash {
+ constructor(blockLen, outputLen, padOffset, isLE) {
+ super();
+ this.blockLen = blockLen;
+ this.outputLen = outputLen;
+ this.padOffset = padOffset;
+ this.isLE = isLE;
+ this.finished = false;
+ this.length = 0;
+ this.pos = 0;
+ this.destroyed = false;
+ this.buffer = new Uint8Array(blockLen);
+ this.view = (0, utils_js_1$2.createView)(this.buffer);
+ }
+ update(data) {
+ _assert_js_1.default.exists(this);
+ const { view, buffer, blockLen } = this;
+ data = (0, utils_js_1$2.toBytes)(data);
+ const len = data.length;
+ for (let pos = 0; pos < len;) {
+ const take = Math.min(blockLen - this.pos, len - pos);
+ // Fast path: we have at least one block in input, cast it to view and process
+ if (take === blockLen) {
+ const dataView = (0, utils_js_1$2.createView)(data);
+ for (; blockLen <= len - pos; pos += blockLen)
+ this.process(dataView, pos);
+ continue;
+ }
+ buffer.set(data.subarray(pos, pos + take), this.pos);
+ this.pos += take;
+ pos += take;
+ if (this.pos === blockLen) {
+ this.process(view, 0);
+ this.pos = 0;
+ }
+ }
+ this.length += data.length;
+ this.roundClean();
+ return this;
+ }
+ digestInto(out) {
+ _assert_js_1.default.exists(this);
+ _assert_js_1.default.output(out, this);
+ this.finished = true;
+ // Padding
+ // We can avoid allocation of buffer for padding completely if it
+ // was previously not allocated here. But it won't change performance.
+ const { buffer, view, blockLen, isLE } = this;
+ let { pos } = this;
+ // append the bit '1' to the message
+ buffer[pos++] = 0b10000000;
+ this.buffer.subarray(pos).fill(0);
+ // we have less than padOffset left in buffer, so we cannot put length in current block, need process it and pad again
+ if (this.padOffset > blockLen - pos) {
+ this.process(view, 0);
+ pos = 0;
+ }
+ // Pad until full block byte with zeros
+ for (let i = pos; i < blockLen; i++)
+ buffer[i] = 0;
+ // Note: sha512 requires length to be 128bit integer, but length in JS will overflow before that
+ // You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen.
+ // So we just write lowest 64 bits of that value.
+ setBigUint64$1(view, blockLen - 8, BigInt(this.length * 8), isLE);
+ this.process(view, 0);
+ const oview = (0, utils_js_1$2.createView)(out);
+ const len = this.outputLen;
+ // NOTE: we do division by 4 later, which should be fused in single op with modulo by JIT
+ if (len % 4)
+ throw new Error('_sha2: outputLen should be aligned to 32bit');
+ const outLen = len / 4;
+ const state = this.get();
+ if (outLen > state.length)
+ throw new Error('_sha2: outputLen bigger than state');
+ for (let i = 0; i < outLen; i++)
+ oview.setUint32(4 * i, state[i], isLE);
+ }
+ digest() {
+ const { buffer, outputLen } = this;
+ this.digestInto(buffer);
+ const res = buffer.slice(0, outputLen);
+ this.destroy();
+ return res;
+ }
+ _cloneInto(to) {
+ to || (to = new this.constructor());
+ to.set(...this.get());
+ const { blockLen, buffer, length, finished, destroyed, pos } = this;
+ to.length = length;
+ to.pos = pos;
+ to.finished = finished;
+ to.destroyed = destroyed;
+ if (length % blockLen)
+ to.buffer.set(buffer);
+ return to;
+ }
+ };
+ _sha2.SHA2 = SHA2$1;
+
+ Object.defineProperty(sha256$1, "__esModule", { value: true });
+ sha256$1.sha224 = sha256$1.sha256 = void 0;
+ const _sha2_js_1$1 = _sha2;
+ const utils_js_1$1 = utils;
+ // Choice: a ? b : c
+ const Chi$1 = (a, b, c) => (a & b) ^ (~a & c);
+ // Majority function, true if any two inpust is true
+ const Maj$1 = (a, b, c) => (a & b) ^ (a & c) ^ (b & c);
+ // Round constants:
+ // first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
+ // prettier-ignore
+ const SHA256_K$1 = new Uint32Array([
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+ ]);
+ // Initial state (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
+ // prettier-ignore
+ const IV$1 = new Uint32Array([
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
+ ]);
+ // Temporary buffer, not used to store anything between runs
+ // Named this way because it matches specification.
+ const SHA256_W$1 = new Uint32Array(64);
+ let SHA256$1 = class SHA256 extends _sha2_js_1$1.SHA2 {
+ constructor() {
+ super(64, 32, 8, false);
+ // We cannot use array here since array allows indexing by variable
+ // which means optimizer/compiler cannot use registers.
+ this.A = IV$1[0] | 0;
+ this.B = IV$1[1] | 0;
+ this.C = IV$1[2] | 0;
+ this.D = IV$1[3] | 0;
+ this.E = IV$1[4] | 0;
+ this.F = IV$1[5] | 0;
+ this.G = IV$1[6] | 0;
+ this.H = IV$1[7] | 0;
+ }
+ get() {
+ const { A, B, C, D, E, F, G, H } = this;
+ return [A, B, C, D, E, F, G, H];
+ }
+ // prettier-ignore
+ set(A, B, C, D, E, F, G, H) {
+ this.A = A | 0;
+ this.B = B | 0;
+ this.C = C | 0;
+ this.D = D | 0;
+ this.E = E | 0;
+ this.F = F | 0;
+ this.G = G | 0;
+ this.H = H | 0;
+ }
+ process(view, offset) {
+ // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array
+ for (let i = 0; i < 16; i++, offset += 4)
+ SHA256_W$1[i] = view.getUint32(offset, false);
+ for (let i = 16; i < 64; i++) {
+ const W15 = SHA256_W$1[i - 15];
+ const W2 = SHA256_W$1[i - 2];
+ const s0 = (0, utils_js_1$1.rotr)(W15, 7) ^ (0, utils_js_1$1.rotr)(W15, 18) ^ (W15 >>> 3);
+ const s1 = (0, utils_js_1$1.rotr)(W2, 17) ^ (0, utils_js_1$1.rotr)(W2, 19) ^ (W2 >>> 10);
+ SHA256_W$1[i] = (s1 + SHA256_W$1[i - 7] + s0 + SHA256_W$1[i - 16]) | 0;
+ }
+ // Compression function main loop, 64 rounds
+ let { A, B, C, D, E, F, G, H } = this;
+ for (let i = 0; i < 64; i++) {
+ const sigma1 = (0, utils_js_1$1.rotr)(E, 6) ^ (0, utils_js_1$1.rotr)(E, 11) ^ (0, utils_js_1$1.rotr)(E, 25);
+ const T1 = (H + sigma1 + Chi$1(E, F, G) + SHA256_K$1[i] + SHA256_W$1[i]) | 0;
+ const sigma0 = (0, utils_js_1$1.rotr)(A, 2) ^ (0, utils_js_1$1.rotr)(A, 13) ^ (0, utils_js_1$1.rotr)(A, 22);
+ const T2 = (sigma0 + Maj$1(A, B, C)) | 0;
+ H = G;
+ G = F;
+ F = E;
+ E = (D + T1) | 0;
+ D = C;
+ C = B;
+ B = A;
+ A = (T1 + T2) | 0;
+ }
+ // Add the compressed chunk to the current hash value
+ A = (A + this.A) | 0;
+ B = (B + this.B) | 0;
+ C = (C + this.C) | 0;
+ D = (D + this.D) | 0;
+ E = (E + this.E) | 0;
+ F = (F + this.F) | 0;
+ G = (G + this.G) | 0;
+ H = (H + this.H) | 0;
+ this.set(A, B, C, D, E, F, G, H);
+ }
+ roundClean() {
+ SHA256_W$1.fill(0);
+ }
+ destroy() {
+ this.set(0, 0, 0, 0, 0, 0, 0, 0);
+ this.buffer.fill(0);
+ }
+ };
+ // Constants from https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
+ let SHA224$1 = class SHA224 extends SHA256$1 {
+ constructor() {
+ super();
+ this.A = 0xc1059ed8 | 0;
+ this.B = 0x367cd507 | 0;
+ this.C = 0x3070dd17 | 0;
+ this.D = 0xf70e5939 | 0;
+ this.E = 0xffc00b31 | 0;
+ this.F = 0x68581511 | 0;
+ this.G = 0x64f98fa7 | 0;
+ this.H = 0xbefa4fa4 | 0;
+ this.outputLen = 28;
+ }
+ };
+ /**
+ * SHA2-256 hash function
+ * @param message - data that would be hashed
+ */
+ sha256$1.sha256 = (0, utils_js_1$1.wrapConstructor)(() => new SHA256$1());
+ sha256$1.sha224 = (0, utils_js_1$1.wrapConstructor)(() => new SHA224$1());
+
+ var sha512$1 = {};
+
+ var _u64 = {};
+
+ (function (exports) {
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.add = exports.toBig = exports.split = exports.fromBig = void 0;
+ const U32_MASK64 = BigInt(2 ** 32 - 1);
+ const _32n = BigInt(32);
+ // We are not using BigUint64Array, because they are extremely slow as per 2022
+ function fromBig(n, le = false) {
+ if (le)
+ return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
+ return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
+ }
+ exports.fromBig = fromBig;
+ function split(lst, le = false) {
+ let Ah = new Uint32Array(lst.length);
+ let Al = new Uint32Array(lst.length);
+ for (let i = 0; i < lst.length; i++) {
+ const { h, l } = fromBig(lst[i], le);
+ [Ah[i], Al[i]] = [h, l];
+ }
+ return [Ah, Al];
+ }
+ exports.split = split;
+ const toBig = (h, l) => (BigInt(h >>> 0) << _32n) | BigInt(l >>> 0);
+ exports.toBig = toBig;
+ // for Shift in [0, 32)
+ const shrSH = (h, l, s) => h >>> s;
+ const shrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
+ // Right rotate for Shift in [1, 32)
+ const rotrSH = (h, l, s) => (h >>> s) | (l << (32 - s));
+ const rotrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
+ // Right rotate for Shift in (32, 64), NOTE: 32 is special case.
+ const rotrBH = (h, l, s) => (h << (64 - s)) | (l >>> (s - 32));
+ const rotrBL = (h, l, s) => (h >>> (s - 32)) | (l << (64 - s));
+ // Right rotate for shift===32 (just swaps l&h)
+ const rotr32H = (h, l) => l;
+ const rotr32L = (h, l) => h;
+ // Left rotate for Shift in [1, 32)
+ const rotlSH = (h, l, s) => (h << s) | (l >>> (32 - s));
+ const rotlSL = (h, l, s) => (l << s) | (h >>> (32 - s));
+ // Left rotate for Shift in (32, 64), NOTE: 32 is special case.
+ const rotlBH = (h, l, s) => (l << (s - 32)) | (h >>> (64 - s));
+ const rotlBL = (h, l, s) => (h << (s - 32)) | (l >>> (64 - s));
+ // JS uses 32-bit signed integers for bitwise operations which means we cannot
+ // simple take carry out of low bit sum by shift, we need to use division.
+ // Removing "export" has 5% perf penalty -_-
+ function add(Ah, Al, Bh, Bl) {
+ const l = (Al >>> 0) + (Bl >>> 0);
+ return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 };
+ }
+ exports.add = add;
+ // Addition with more than 2 elements
+ const add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
+ const add3H = (low, Ah, Bh, Ch) => (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0;
+ const add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
+ const add4H = (low, Ah, Bh, Ch, Dh) => (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0;
+ const add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
+ const add5H = (low, Ah, Bh, Ch, Dh, Eh) => (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0;
+ // prettier-ignore
+ const u64 = {
+ fromBig, split, toBig: exports.toBig,
+ shrSH, shrSL,
+ rotrSH, rotrSL, rotrBH, rotrBL,
+ rotr32H, rotr32L,
+ rotlSH, rotlSL, rotlBH, rotlBL,
+ add, add3L, add3H, add4L, add4H, add5H, add5L,
+ };
+ exports.default = u64;
+
+ } (_u64));
+
+ Object.defineProperty(sha512$1, "__esModule", { value: true });
+ sha512$1.sha384 = sha512$1.sha512_256 = sha512$1.sha512_224 = sha512$1.sha512 = sha512$1.SHA512 = void 0;
+ const _sha2_js_1 = _sha2;
+ const _u64_js_1 = _u64;
+ const utils_js_1 = utils;
+ // Round contants (first 32 bits of the fractional parts of the cube roots of the first 80 primes 2..409):
+ // prettier-ignore
+ const [SHA512_Kh$1, SHA512_Kl$1] = _u64_js_1.default.split([
+ '0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc',
+ '0x3956c25bf348b538', '0x59f111f1b605d019', '0x923f82a4af194f9b', '0xab1c5ed5da6d8118',
+ '0xd807aa98a3030242', '0x12835b0145706fbe', '0x243185be4ee4b28c', '0x550c7dc3d5ffb4e2',
+ '0x72be5d74f27b896f', '0x80deb1fe3b1696b1', '0x9bdc06a725c71235', '0xc19bf174cf692694',
+ '0xe49b69c19ef14ad2', '0xefbe4786384f25e3', '0x0fc19dc68b8cd5b5', '0x240ca1cc77ac9c65',
+ '0x2de92c6f592b0275', '0x4a7484aa6ea6e483', '0x5cb0a9dcbd41fbd4', '0x76f988da831153b5',
+ '0x983e5152ee66dfab', '0xa831c66d2db43210', '0xb00327c898fb213f', '0xbf597fc7beef0ee4',
+ '0xc6e00bf33da88fc2', '0xd5a79147930aa725', '0x06ca6351e003826f', '0x142929670a0e6e70',
+ '0x27b70a8546d22ffc', '0x2e1b21385c26c926', '0x4d2c6dfc5ac42aed', '0x53380d139d95b3df',
+ '0x650a73548baf63de', '0x766a0abb3c77b2a8', '0x81c2c92e47edaee6', '0x92722c851482353b',
+ '0xa2bfe8a14cf10364', '0xa81a664bbc423001', '0xc24b8b70d0f89791', '0xc76c51a30654be30',
+ '0xd192e819d6ef5218', '0xd69906245565a910', '0xf40e35855771202a', '0x106aa07032bbd1b8',
+ '0x19a4c116b8d2d0c8', '0x1e376c085141ab53', '0x2748774cdf8eeb99', '0x34b0bcb5e19b48a8',
+ '0x391c0cb3c5c95a63', '0x4ed8aa4ae3418acb', '0x5b9cca4f7763e373', '0x682e6ff3d6b2b8a3',
+ '0x748f82ee5defb2fc', '0x78a5636f43172f60', '0x84c87814a1f0ab72', '0x8cc702081a6439ec',
+ '0x90befffa23631e28', '0xa4506cebde82bde9', '0xbef9a3f7b2c67915', '0xc67178f2e372532b',
+ '0xca273eceea26619c', '0xd186b8c721c0c207', '0xeada7dd6cde0eb1e', '0xf57d4f7fee6ed178',
+ '0x06f067aa72176fba', '0x0a637dc5a2c898a6', '0x113f9804bef90dae', '0x1b710b35131c471b',
+ '0x28db77f523047d84', '0x32caab7b40c72493', '0x3c9ebe0a15c9bebc', '0x431d67c49c100d4c',
+ '0x4cc5d4becb3e42b6', '0x597f299cfc657e2a', '0x5fcb6fab3ad6faec', '0x6c44198c4a475817'
+ ].map(n => BigInt(n)));
+ // Temporary buffer, not used to store anything between runs
+ const SHA512_W_H$1 = new Uint32Array(80);
+ const SHA512_W_L$1 = new Uint32Array(80);
+ let SHA512$1 = class SHA512 extends _sha2_js_1.SHA2 {
+ constructor() {
+ super(128, 64, 16, false);
+ // We cannot use array here since array allows indexing by variable which means optimizer/compiler cannot use registers.
+ // Also looks cleaner and easier to verify with spec.
+ // Initial state (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
+ // h -- high 32 bits, l -- low 32 bits
+ this.Ah = 0x6a09e667 | 0;
+ this.Al = 0xf3bcc908 | 0;
+ this.Bh = 0xbb67ae85 | 0;
+ this.Bl = 0x84caa73b | 0;
+ this.Ch = 0x3c6ef372 | 0;
+ this.Cl = 0xfe94f82b | 0;
+ this.Dh = 0xa54ff53a | 0;
+ this.Dl = 0x5f1d36f1 | 0;
+ this.Eh = 0x510e527f | 0;
+ this.El = 0xade682d1 | 0;
+ this.Fh = 0x9b05688c | 0;
+ this.Fl = 0x2b3e6c1f | 0;
+ this.Gh = 0x1f83d9ab | 0;
+ this.Gl = 0xfb41bd6b | 0;
+ this.Hh = 0x5be0cd19 | 0;
+ this.Hl = 0x137e2179 | 0;
+ }
+ // prettier-ignore
+ get() {
+ const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
+ return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl];
+ }
+ // prettier-ignore
+ set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl) {
+ this.Ah = Ah | 0;
+ this.Al = Al | 0;
+ this.Bh = Bh | 0;
+ this.Bl = Bl | 0;
+ this.Ch = Ch | 0;
+ this.Cl = Cl | 0;
+ this.Dh = Dh | 0;
+ this.Dl = Dl | 0;
+ this.Eh = Eh | 0;
+ this.El = El | 0;
+ this.Fh = Fh | 0;
+ this.Fl = Fl | 0;
+ this.Gh = Gh | 0;
+ this.Gl = Gl | 0;
+ this.Hh = Hh | 0;
+ this.Hl = Hl | 0;
+ }
+ process(view, offset) {
+ // Extend the first 16 words into the remaining 64 words w[16..79] of the message schedule array
+ for (let i = 0; i < 16; i++, offset += 4) {
+ SHA512_W_H$1[i] = view.getUint32(offset);
+ SHA512_W_L$1[i] = view.getUint32((offset += 4));
+ }
+ for (let i = 16; i < 80; i++) {
+ // s0 := (w[i-15] rightrotate 1) xor (w[i-15] rightrotate 8) xor (w[i-15] rightshift 7)
+ const W15h = SHA512_W_H$1[i - 15] | 0;
+ const W15l = SHA512_W_L$1[i - 15] | 0;
+ const s0h = _u64_js_1.default.rotrSH(W15h, W15l, 1) ^ _u64_js_1.default.rotrSH(W15h, W15l, 8) ^ _u64_js_1.default.shrSH(W15h, W15l, 7);
+ const s0l = _u64_js_1.default.rotrSL(W15h, W15l, 1) ^ _u64_js_1.default.rotrSL(W15h, W15l, 8) ^ _u64_js_1.default.shrSL(W15h, W15l, 7);
+ // s1 := (w[i-2] rightrotate 19) xor (w[i-2] rightrotate 61) xor (w[i-2] rightshift 6)
+ const W2h = SHA512_W_H$1[i - 2] | 0;
+ const W2l = SHA512_W_L$1[i - 2] | 0;
+ const s1h = _u64_js_1.default.rotrSH(W2h, W2l, 19) ^ _u64_js_1.default.rotrBH(W2h, W2l, 61) ^ _u64_js_1.default.shrSH(W2h, W2l, 6);
+ const s1l = _u64_js_1.default.rotrSL(W2h, W2l, 19) ^ _u64_js_1.default.rotrBL(W2h, W2l, 61) ^ _u64_js_1.default.shrSL(W2h, W2l, 6);
+ // SHA256_W[i] = s0 + s1 + SHA256_W[i - 7] + SHA256_W[i - 16];
+ const SUMl = _u64_js_1.default.add4L(s0l, s1l, SHA512_W_L$1[i - 7], SHA512_W_L$1[i - 16]);
+ const SUMh = _u64_js_1.default.add4H(SUMl, s0h, s1h, SHA512_W_H$1[i - 7], SHA512_W_H$1[i - 16]);
+ SHA512_W_H$1[i] = SUMh | 0;
+ SHA512_W_L$1[i] = SUMl | 0;
+ }
+ let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
+ // Compression function main loop, 80 rounds
+ for (let i = 0; i < 80; i++) {
+ // S1 := (e rightrotate 14) xor (e rightrotate 18) xor (e rightrotate 41)
+ const sigma1h = _u64_js_1.default.rotrSH(Eh, El, 14) ^ _u64_js_1.default.rotrSH(Eh, El, 18) ^ _u64_js_1.default.rotrBH(Eh, El, 41);
+ const sigma1l = _u64_js_1.default.rotrSL(Eh, El, 14) ^ _u64_js_1.default.rotrSL(Eh, El, 18) ^ _u64_js_1.default.rotrBL(Eh, El, 41);
+ //const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;
+ const CHIh = (Eh & Fh) ^ (~Eh & Gh);
+ const CHIl = (El & Fl) ^ (~El & Gl);
+ // T1 = H + sigma1 + Chi(E, F, G) + SHA512_K[i] + SHA512_W[i]
+ // prettier-ignore
+ const T1ll = _u64_js_1.default.add5L(Hl, sigma1l, CHIl, SHA512_Kl$1[i], SHA512_W_L$1[i]);
+ const T1h = _u64_js_1.default.add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh$1[i], SHA512_W_H$1[i]);
+ const T1l = T1ll | 0;
+ // S0 := (a rightrotate 28) xor (a rightrotate 34) xor (a rightrotate 39)
+ const sigma0h = _u64_js_1.default.rotrSH(Ah, Al, 28) ^ _u64_js_1.default.rotrBH(Ah, Al, 34) ^ _u64_js_1.default.rotrBH(Ah, Al, 39);
+ const sigma0l = _u64_js_1.default.rotrSL(Ah, Al, 28) ^ _u64_js_1.default.rotrBL(Ah, Al, 34) ^ _u64_js_1.default.rotrBL(Ah, Al, 39);
+ const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch);
+ const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl);
+ Hh = Gh | 0;
+ Hl = Gl | 0;
+ Gh = Fh | 0;
+ Gl = Fl | 0;
+ Fh = Eh | 0;
+ Fl = El | 0;
+ ({ h: Eh, l: El } = _u64_js_1.default.add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));
+ Dh = Ch | 0;
+ Dl = Cl | 0;
+ Ch = Bh | 0;
+ Cl = Bl | 0;
+ Bh = Ah | 0;
+ Bl = Al | 0;
+ const All = _u64_js_1.default.add3L(T1l, sigma0l, MAJl);
+ Ah = _u64_js_1.default.add3H(All, T1h, sigma0h, MAJh);
+ Al = All | 0;
+ }
+ // Add the compressed chunk to the current hash value
+ ({ h: Ah, l: Al } = _u64_js_1.default.add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));
+ ({ h: Bh, l: Bl } = _u64_js_1.default.add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));
+ ({ h: Ch, l: Cl } = _u64_js_1.default.add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));
+ ({ h: Dh, l: Dl } = _u64_js_1.default.add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));
+ ({ h: Eh, l: El } = _u64_js_1.default.add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));
+ ({ h: Fh, l: Fl } = _u64_js_1.default.add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));
+ ({ h: Gh, l: Gl } = _u64_js_1.default.add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));
+ ({ h: Hh, l: Hl } = _u64_js_1.default.add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));
+ this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);
+ }
+ roundClean() {
+ SHA512_W_H$1.fill(0);
+ SHA512_W_L$1.fill(0);
+ }
+ destroy() {
+ this.buffer.fill(0);
+ this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ }
+ };
+ sha512$1.SHA512 = SHA512$1;
+ let SHA512_224$1 = class SHA512_224 extends SHA512$1 {
+ constructor() {
+ super();
+ // h -- high 32 bits, l -- low 32 bits
+ this.Ah = 0x8c3d37c8 | 0;
+ this.Al = 0x19544da2 | 0;
+ this.Bh = 0x73e19966 | 0;
+ this.Bl = 0x89dcd4d6 | 0;
+ this.Ch = 0x1dfab7ae | 0;
+ this.Cl = 0x32ff9c82 | 0;
+ this.Dh = 0x679dd514 | 0;
+ this.Dl = 0x582f9fcf | 0;
+ this.Eh = 0x0f6d2b69 | 0;
+ this.El = 0x7bd44da8 | 0;
+ this.Fh = 0x77e36f73 | 0;
+ this.Fl = 0x04c48942 | 0;
+ this.Gh = 0x3f9d85a8 | 0;
+ this.Gl = 0x6a1d36c8 | 0;
+ this.Hh = 0x1112e6ad | 0;
+ this.Hl = 0x91d692a1 | 0;
+ this.outputLen = 28;
+ }
+ };
+ let SHA512_256$1 = class SHA512_256 extends SHA512$1 {
+ constructor() {
+ super();
+ // h -- high 32 bits, l -- low 32 bits
+ this.Ah = 0x22312194 | 0;
+ this.Al = 0xfc2bf72c | 0;
+ this.Bh = 0x9f555fa3 | 0;
+ this.Bl = 0xc84c64c2 | 0;
+ this.Ch = 0x2393b86b | 0;
+ this.Cl = 0x6f53b151 | 0;
+ this.Dh = 0x96387719 | 0;
+ this.Dl = 0x5940eabd | 0;
+ this.Eh = 0x96283ee2 | 0;
+ this.El = 0xa88effe3 | 0;
+ this.Fh = 0xbe5e1e25 | 0;
+ this.Fl = 0x53863992 | 0;
+ this.Gh = 0x2b0199fc | 0;
+ this.Gl = 0x2c85b8aa | 0;
+ this.Hh = 0x0eb72ddc | 0;
+ this.Hl = 0x81c52ca2 | 0;
+ this.outputLen = 32;
+ }
+ };
+ let SHA384$1 = class SHA384 extends SHA512$1 {
+ constructor() {
+ super();
+ // h -- high 32 bits, l -- low 32 bits
+ this.Ah = 0xcbbb9d5d | 0;
+ this.Al = 0xc1059ed8 | 0;
+ this.Bh = 0x629a292a | 0;
+ this.Bl = 0x367cd507 | 0;
+ this.Ch = 0x9159015a | 0;
+ this.Cl = 0x3070dd17 | 0;
+ this.Dh = 0x152fecd8 | 0;
+ this.Dl = 0xf70e5939 | 0;
+ this.Eh = 0x67332667 | 0;
+ this.El = 0xffc00b31 | 0;
+ this.Fh = 0x8eb44a87 | 0;
+ this.Fl = 0x68581511 | 0;
+ this.Gh = 0xdb0c2e0d | 0;
+ this.Gl = 0x64f98fa7 | 0;
+ this.Hh = 0x47b5481d | 0;
+ this.Hl = 0xbefa4fa4 | 0;
+ this.outputLen = 48;
+ }
+ };
+ sha512$1.sha512 = (0, utils_js_1.wrapConstructor)(() => new SHA512$1());
+ sha512$1.sha512_224 = (0, utils_js_1.wrapConstructor)(() => new SHA512_224$1());
+ sha512$1.sha512_256 = (0, utils_js_1.wrapConstructor)(() => new SHA512_256$1());
+ sha512$1.sha384 = (0, utils_js_1.wrapConstructor)(() => new SHA384$1());
+
+ var lib = {};
+
+ (function (exports) {
+ /*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.bytes = exports.stringToBytes = exports.str = exports.bytesToString = exports.hex = exports.utf8 = exports.bech32m = exports.bech32 = exports.base58check = exports.base58xmr = exports.base58xrp = exports.base58flickr = exports.base58 = exports.base64url = exports.base64 = exports.base32crockford = exports.base32hex = exports.base32 = exports.base16 = exports.utils = exports.assertNumber = void 0;
+ function assertNumber(n) {
+ if (!Number.isSafeInteger(n))
+ throw new Error(`Wrong integer: ${n}`);
+ }
+ exports.assertNumber = assertNumber;
+ function chain(...args) {
+ const wrap = (a, b) => (c) => a(b(c));
+ const encode = Array.from(args)
+ .reverse()
+ .reduce((acc, i) => (acc ? wrap(acc, i.encode) : i.encode), undefined);
+ const decode = args.reduce((acc, i) => (acc ? wrap(acc, i.decode) : i.decode), undefined);
+ return { encode, decode };
+ }
+ function alphabet(alphabet) {
+ return {
+ encode: (digits) => {
+ if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
+ throw new Error('alphabet.encode input should be an array of numbers');
+ return digits.map((i) => {
+ assertNumber(i);
+ if (i < 0 || i >= alphabet.length)
+ throw new Error(`Digit index outside alphabet: ${i} (alphabet: ${alphabet.length})`);
+ return alphabet[i];
+ });
+ },
+ decode: (input) => {
+ if (!Array.isArray(input) || (input.length && typeof input[0] !== 'string'))
+ throw new Error('alphabet.decode input should be array of strings');
+ return input.map((letter) => {
+ if (typeof letter !== 'string')
+ throw new Error(`alphabet.decode: not string element=${letter}`);
+ const index = alphabet.indexOf(letter);
+ if (index === -1)
+ throw new Error(`Unknown letter: "${letter}". Allowed: ${alphabet}`);
+ return index;
+ });
+ },
+ };
+ }
+ function join(separator = '') {
+ if (typeof separator !== 'string')
+ throw new Error('join separator should be string');
+ return {
+ encode: (from) => {
+ if (!Array.isArray(from) || (from.length && typeof from[0] !== 'string'))
+ throw new Error('join.encode input should be array of strings');
+ for (let i of from)
+ if (typeof i !== 'string')
+ throw new Error(`join.encode: non-string input=${i}`);
+ return from.join(separator);
+ },
+ decode: (to) => {
+ if (typeof to !== 'string')
+ throw new Error('join.decode input should be string');
+ return to.split(separator);
+ },
+ };
+ }
+ function padding(bits, chr = '=') {
+ assertNumber(bits);
+ if (typeof chr !== 'string')
+ throw new Error('padding chr should be string');
+ return {
+ encode(data) {
+ if (!Array.isArray(data) || (data.length && typeof data[0] !== 'string'))
+ throw new Error('padding.encode input should be array of strings');
+ for (let i of data)
+ if (typeof i !== 'string')
+ throw new Error(`padding.encode: non-string input=${i}`);
+ while ((data.length * bits) % 8)
+ data.push(chr);
+ return data;
+ },
+ decode(input) {
+ if (!Array.isArray(input) || (input.length && typeof input[0] !== 'string'))
+ throw new Error('padding.encode input should be array of strings');
+ for (let i of input)
+ if (typeof i !== 'string')
+ throw new Error(`padding.decode: non-string input=${i}`);
+ let end = input.length;
+ if ((end * bits) % 8)
+ throw new Error('Invalid padding: string should have whole number of bytes');
+ for (; end > 0 && input[end - 1] === chr; end--) {
+ if (!(((end - 1) * bits) % 8))
+ throw new Error('Invalid padding: string has too much padding');
+ }
+ return input.slice(0, end);
+ },
+ };
+ }
+ function normalize(fn) {
+ if (typeof fn !== 'function')
+ throw new Error('normalize fn should be function');
+ return { encode: (from) => from, decode: (to) => fn(to) };
+ }
+ function convertRadix(data, from, to) {
+ if (from < 2)
+ throw new Error(`convertRadix: wrong from=${from}, base cannot be less than 2`);
+ if (to < 2)
+ throw new Error(`convertRadix: wrong to=${to}, base cannot be less than 2`);
+ if (!Array.isArray(data))
+ throw new Error('convertRadix: data should be array');
+ if (!data.length)
+ return [];
+ let pos = 0;
+ const res = [];
+ const digits = Array.from(data);
+ digits.forEach((d) => {
+ assertNumber(d);
+ if (d < 0 || d >= from)
+ throw new Error(`Wrong integer: ${d}`);
+ });
+ while (true) {
+ let carry = 0;
+ let done = true;
+ for (let i = pos; i < digits.length; i++) {
+ const digit = digits[i];
+ const digitBase = from * carry + digit;
+ if (!Number.isSafeInteger(digitBase) ||
+ (from * carry) / from !== carry ||
+ digitBase - digit !== from * carry) {
+ throw new Error('convertRadix: carry overflow');
+ }
+ carry = digitBase % to;
+ digits[i] = Math.floor(digitBase / to);
+ if (!Number.isSafeInteger(digits[i]) || digits[i] * to + carry !== digitBase)
+ throw new Error('convertRadix: carry overflow');
+ if (!done)
+ continue;
+ else if (!digits[i])
+ pos = i;
+ else
+ done = false;
+ }
+ res.push(carry);
+ if (done)
+ break;
+ }
+ for (let i = 0; i < data.length - 1 && data[i] === 0; i++)
+ res.push(0);
+ return res.reverse();
+ }
+ const gcd = (a, b) => (!b ? a : gcd(b, a % b));
+ const radix2carry = (from, to) => from + (to - gcd(from, to));
+ function convertRadix2(data, from, to, padding) {
+ if (!Array.isArray(data))
+ throw new Error('convertRadix2: data should be array');
+ if (from <= 0 || from > 32)
+ throw new Error(`convertRadix2: wrong from=${from}`);
+ if (to <= 0 || to > 32)
+ throw new Error(`convertRadix2: wrong to=${to}`);
+ if (radix2carry(from, to) > 32) {
+ throw new Error(`convertRadix2: carry overflow from=${from} to=${to} carryBits=${radix2carry(from, to)}`);
+ }
+ let carry = 0;
+ let pos = 0;
+ const mask = 2 ** to - 1;
+ const res = [];
+ for (const n of data) {
+ assertNumber(n);
+ if (n >= 2 ** from)
+ throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);
+ carry = (carry << from) | n;
+ if (pos + from > 32)
+ throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from}`);
+ pos += from;
+ for (; pos >= to; pos -= to)
+ res.push(((carry >> (pos - to)) & mask) >>> 0);
+ carry &= 2 ** pos - 1;
+ }
+ carry = (carry << (to - pos)) & mask;
+ if (!padding && pos >= from)
+ throw new Error('Excess padding');
+ if (!padding && carry)
+ throw new Error(`Non-zero padding: ${carry}`);
+ if (padding && pos > 0)
+ res.push(carry >>> 0);
+ return res;
+ }
+ function radix(num) {
+ assertNumber(num);
+ return {
+ encode: (bytes) => {
+ if (!(bytes instanceof Uint8Array))
+ throw new Error('radix.encode input should be Uint8Array');
+ return convertRadix(Array.from(bytes), 2 ** 8, num);
+ },
+ decode: (digits) => {
+ if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
+ throw new Error('radix.decode input should be array of strings');
+ return Uint8Array.from(convertRadix(digits, num, 2 ** 8));
+ },
+ };
+ }
+ function radix2(bits, revPadding = false) {
+ assertNumber(bits);
+ if (bits <= 0 || bits > 32)
+ throw new Error('radix2: bits should be in (0..32]');
+ if (radix2carry(8, bits) > 32 || radix2carry(bits, 8) > 32)
+ throw new Error('radix2: carry overflow');
+ return {
+ encode: (bytes) => {
+ if (!(bytes instanceof Uint8Array))
+ throw new Error('radix2.encode input should be Uint8Array');
+ return convertRadix2(Array.from(bytes), 8, bits, !revPadding);
+ },
+ decode: (digits) => {
+ if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
+ throw new Error('radix2.decode input should be array of strings');
+ return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding));
+ },
+ };
+ }
+ function unsafeWrapper(fn) {
+ if (typeof fn !== 'function')
+ throw new Error('unsafeWrapper fn should be function');
+ return function (...args) {
+ try {
+ return fn.apply(null, args);
+ }
+ catch (e) { }
+ };
+ }
+ function checksum(len, fn) {
+ assertNumber(len);
+ if (typeof fn !== 'function')
+ throw new Error('checksum fn should be function');
+ return {
+ encode(data) {
+ if (!(data instanceof Uint8Array))
+ throw new Error('checksum.encode: input should be Uint8Array');
+ const checksum = fn(data).slice(0, len);
+ const res = new Uint8Array(data.length + len);
+ res.set(data);
+ res.set(checksum, data.length);
+ return res;
+ },
+ decode(data) {
+ if (!(data instanceof Uint8Array))
+ throw new Error('checksum.decode: input should be Uint8Array');
+ const payload = data.slice(0, -len);
+ const newChecksum = fn(payload).slice(0, len);
+ const oldChecksum = data.slice(-len);
+ for (let i = 0; i < len; i++)
+ if (newChecksum[i] !== oldChecksum[i])
+ throw new Error('Invalid checksum');
+ return payload;
+ },
+ };
+ }
+ exports.utils = { alphabet, chain, checksum, radix, radix2, join, padding };
+ exports.base16 = chain(radix2(4), alphabet('0123456789ABCDEF'), join(''));
+ exports.base32 = chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), padding(5), join(''));
+ exports.base32hex = chain(radix2(5), alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'), padding(5), join(''));
+ exports.base32crockford = chain(radix2(5), alphabet('0123456789ABCDEFGHJKMNPQRSTVWXYZ'), join(''), normalize((s) => s.toUpperCase().replace(/O/g, '0').replace(/[IL]/g, '1')));
+ exports.base64 = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), padding(6), join(''));
+ exports.base64url = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), padding(6), join(''));
+ const genBase58 = (abc) => chain(radix(58), alphabet(abc), join(''));
+ exports.base58 = genBase58('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
+ exports.base58flickr = genBase58('123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ');
+ exports.base58xrp = genBase58('rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz');
+ const XMR_BLOCK_LEN = [0, 2, 3, 5, 6, 7, 9, 10, 11];
+ exports.base58xmr = {
+ encode(data) {
+ let res = '';
+ for (let i = 0; i < data.length; i += 8) {
+ const block = data.subarray(i, i + 8);
+ res += exports.base58.encode(block).padStart(XMR_BLOCK_LEN[block.length], '1');
+ }
+ return res;
+ },
+ decode(str) {
+ let res = [];
+ for (let i = 0; i < str.length; i += 11) {
+ const slice = str.slice(i, i + 11);
+ const blockLen = XMR_BLOCK_LEN.indexOf(slice.length);
+ const block = exports.base58.decode(slice);
+ for (let j = 0; j < block.length - blockLen; j++) {
+ if (block[j] !== 0)
+ throw new Error('base58xmr: wrong padding');
+ }
+ res = res.concat(Array.from(block.slice(block.length - blockLen)));
+ }
+ return Uint8Array.from(res);
+ },
+ };
+ const base58check = (sha256) => chain(checksum(4, (data) => sha256(sha256(data))), exports.base58);
+ exports.base58check = base58check;
+ const BECH_ALPHABET = chain(alphabet('qpzry9x8gf2tvdw0s3jn54khce6mua7l'), join(''));
+ const POLYMOD_GENERATORS = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
+ function bech32Polymod(pre) {
+ const b = pre >> 25;
+ let chk = (pre & 0x1ffffff) << 5;
+ for (let i = 0; i < POLYMOD_GENERATORS.length; i++) {
+ if (((b >> i) & 1) === 1)
+ chk ^= POLYMOD_GENERATORS[i];
+ }
+ return chk;
+ }
+ function bechChecksum(prefix, words, encodingConst = 1) {
+ const len = prefix.length;
+ let chk = 1;
+ for (let i = 0; i < len; i++) {
+ const c = prefix.charCodeAt(i);
+ if (c < 33 || c > 126)
+ throw new Error(`Invalid prefix (${prefix})`);
+ chk = bech32Polymod(chk) ^ (c >> 5);
+ }
+ chk = bech32Polymod(chk);
+ for (let i = 0; i < len; i++)
+ chk = bech32Polymod(chk) ^ (prefix.charCodeAt(i) & 0x1f);
+ for (let v of words)
+ chk = bech32Polymod(chk) ^ v;
+ for (let i = 0; i < 6; i++)
+ chk = bech32Polymod(chk);
+ chk ^= encodingConst;
+ return BECH_ALPHABET.encode(convertRadix2([chk % 2 ** 30], 30, 5, false));
+ }
+ function genBech32(encoding) {
+ const ENCODING_CONST = encoding === 'bech32' ? 1 : 0x2bc830a3;
+ const _words = radix2(5);
+ const fromWords = _words.decode;
+ const toWords = _words.encode;
+ const fromWordsUnsafe = unsafeWrapper(fromWords);
+ function encode(prefix, words, limit = 90) {
+ if (typeof prefix !== 'string')
+ throw new Error(`bech32.encode prefix should be string, not ${typeof prefix}`);
+ if (!Array.isArray(words) || (words.length && typeof words[0] !== 'number'))
+ throw new Error(`bech32.encode words should be array of numbers, not ${typeof words}`);
+ const actualLength = prefix.length + 7 + words.length;
+ if (limit !== false && actualLength > limit)
+ throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`);
+ prefix = prefix.toLowerCase();
+ return `${prefix}1${BECH_ALPHABET.encode(words)}${bechChecksum(prefix, words, ENCODING_CONST)}`;
+ }
+ function decode(str, limit = 90) {
+ if (typeof str !== 'string')
+ throw new Error(`bech32.decode input should be string, not ${typeof str}`);
+ if (str.length < 8 || (limit !== false && str.length > limit))
+ throw new TypeError(`Wrong string length: ${str.length} (${str}). Expected (8..${limit})`);
+ const lowered = str.toLowerCase();
+ if (str !== lowered && str !== str.toUpperCase())
+ throw new Error(`String must be lowercase or uppercase`);
+ str = lowered;
+ const sepIndex = str.lastIndexOf('1');
+ if (sepIndex === 0 || sepIndex === -1)
+ throw new Error(`Letter "1" must be present between prefix and data only`);
+ const prefix = str.slice(0, sepIndex);
+ const _words = str.slice(sepIndex + 1);
+ if (_words.length < 6)
+ throw new Error('Data must be at least 6 characters long');
+ const words = BECH_ALPHABET.decode(_words).slice(0, -6);
+ const sum = bechChecksum(prefix, words, ENCODING_CONST);
+ if (!_words.endsWith(sum))
+ throw new Error(`Invalid checksum in ${str}: expected "${sum}"`);
+ return { prefix, words };
+ }
+ const decodeUnsafe = unsafeWrapper(decode);
+ function decodeToBytes(str) {
+ const { prefix, words } = decode(str, false);
+ return { prefix, words, bytes: fromWords(words) };
+ }
+ return { encode, decode, decodeToBytes, decodeUnsafe, fromWords, fromWordsUnsafe, toWords };
+ }
+ exports.bech32 = genBech32('bech32');
+ exports.bech32m = genBech32('bech32m');
+ exports.utf8 = {
+ encode: (data) => new TextDecoder().decode(data),
+ decode: (str) => new TextEncoder().encode(str),
+ };
+ exports.hex = chain(radix2(4), alphabet('0123456789abcdef'), join(''), normalize((s) => {
+ if (typeof s !== 'string' || s.length % 2)
+ throw new TypeError(`hex.decode: expected string, got ${typeof s} with length ${s.length}`);
+ return s.toLowerCase();
+ }));
+ const CODERS = {
+ utf8: exports.utf8, hex: exports.hex, base16: exports.base16, base32: exports.base32, base64: exports.base64, base64url: exports.base64url, base58: exports.base58, base58xmr: exports.base58xmr
+ };
+ const coderTypeError = `Invalid encoding type. Available types: ${Object.keys(CODERS).join(', ')}`;
+ const bytesToString = (type, bytes) => {
+ if (typeof type !== 'string' || !CODERS.hasOwnProperty(type))
+ throw new TypeError(coderTypeError);
+ if (!(bytes instanceof Uint8Array))
+ throw new TypeError('bytesToString() expects Uint8Array');
+ return CODERS[type].encode(bytes);
+ };
+ exports.bytesToString = bytesToString;
+ exports.str = exports.bytesToString;
+ const stringToBytes = (type, str) => {
+ if (!CODERS.hasOwnProperty(type))
+ throw new TypeError(coderTypeError);
+ if (typeof str !== 'string')
+ throw new TypeError('stringToBytes() expects string');
+ return CODERS[type].decode(str);
+ };
+ exports.stringToBytes = stringToBytes;
+ exports.bytes = exports.stringToBytes;
+ } (lib));
+
+ Object.defineProperty(bip39, "__esModule", { value: true });
+ var mnemonicToSeedSync_1 = bip39.mnemonicToSeedSync = bip39.mnemonicToSeed = validateMnemonic_1 = bip39.validateMnemonic = bip39.entropyToMnemonic = bip39.mnemonicToEntropy = generateMnemonic_1 = bip39.generateMnemonic = void 0;
+ /*! scure-bip39 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) */
+ const _assert_1 = _assert;
+ const pbkdf2_1 = pbkdf2$1;
+ const sha256_1 = sha256$1;
+ const sha512_1 = sha512$1;
+ const utils_1 = utils;
+ const base_1 = lib;
+ // Japanese wordlist
+ const isJapanese = (wordlist) => wordlist[0] === '\u3042\u3044\u3053\u304f\u3057\u3093';
+ // Normalization replaces equivalent sequences of characters
+ // so that any two texts that are equivalent will be reduced
+ // to the same sequence of code points, called the normal form of the original text.
+ function nfkd(str) {
+ if (typeof str !== 'string')
+ throw new TypeError(`Invalid mnemonic type: ${typeof str}`);
+ return str.normalize('NFKD');
+ }
+ function normalize(str) {
+ const norm = nfkd(str);
+ const words = norm.split(' ');
+ if (![12, 15, 18, 21, 24].includes(words.length))
+ throw new Error('Invalid mnemonic');
+ return { nfkd: norm, words };
+ }
+ function assertEntropy(entropy) {
+ _assert_1.default.bytes(entropy, 16, 20, 24, 28, 32);
+ }
+ /**
+ * Generate x random words. Uses Cryptographically-Secure Random Number Generator.
+ * @param wordlist imported wordlist for specific language
+ * @param strength mnemonic strength 128-256 bits
+ * @example
+ * generateMnemonic(wordlist, 128)
+ * // 'legal winner thank year wave sausage worth useful legal winner thank yellow'
+ */
+ function generateMnemonic(wordlist, strength = 128) {
+ _assert_1.default.number(strength);
+ if (strength % 32 !== 0 || strength > 256)
+ throw new TypeError('Invalid entropy');
+ return entropyToMnemonic((0, utils_1.randomBytes)(strength / 8), wordlist);
+ }
+ var generateMnemonic_1 = bip39.generateMnemonic = generateMnemonic;
+ const calcChecksum = (entropy) => {
+ // Checksum is ent.length/4 bits long
+ const bitsLeft = 8 - entropy.length / 4;
+ // Zero rightmost "bitsLeft" bits in byte
+ // For example: bitsLeft=4 val=10111101 -> 10110000
+ return new Uint8Array([((0, sha256_1.sha256)(entropy)[0] >> bitsLeft) << bitsLeft]);
+ };
+ function getCoder(wordlist) {
+ if (!Array.isArray(wordlist) || wordlist.length !== 2048 || typeof wordlist[0] !== 'string')
+ throw new Error('Worlist: expected array of 2048 strings');
+ wordlist.forEach((i) => {
+ if (typeof i !== 'string')
+ throw new Error(`Wordlist: non-string element: ${i}`);
+ });
+ return base_1.utils.chain(base_1.utils.checksum(1, calcChecksum), base_1.utils.radix2(11, true), base_1.utils.alphabet(wordlist));
+ }
+ /**
+ * Reversible: Converts mnemonic string to raw entropy in form of byte array.
+ * @param mnemonic 12-24 words
+ * @param wordlist imported wordlist for specific language
+ * @example
+ * const mnem = 'legal winner thank year wave sausage worth useful legal winner thank yellow';
+ * mnemonicToEntropy(mnem, wordlist)
+ * // Produces
+ * new Uint8Array([
+ * 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ * 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f
+ * ])
+ */
+ function mnemonicToEntropy(mnemonic, wordlist) {
+ const { words } = normalize(mnemonic);
+ const entropy = getCoder(wordlist).decode(words);
+ assertEntropy(entropy);
+ return entropy;
+ }
+ bip39.mnemonicToEntropy = mnemonicToEntropy;
+ /**
+ * Reversible: Converts raw entropy in form of byte array to mnemonic string.
+ * @param entropy byte array
+ * @param wordlist imported wordlist for specific language
+ * @returns 12-24 words
+ * @example
+ * const ent = new Uint8Array([
+ * 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ * 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f
+ * ]);
+ * entropyToMnemonic(ent, wordlist);
+ * // 'legal winner thank year wave sausage worth useful legal winner thank yellow'
+ */
+ function entropyToMnemonic(entropy, wordlist) {
+ assertEntropy(entropy);
+ const words = getCoder(wordlist).encode(entropy);
+ return words.join(isJapanese(wordlist) ? '\u3000' : ' ');
+ }
+ bip39.entropyToMnemonic = entropyToMnemonic;
+ /**
+ * Validates mnemonic for being 12-24 words contained in `wordlist`.
+ */
+ function validateMnemonic(mnemonic, wordlist) {
+ try {
+ mnemonicToEntropy(mnemonic, wordlist);
+ }
+ catch (e) {
+ return false;
+ }
+ return true;
+ }
+ var validateMnemonic_1 = bip39.validateMnemonic = validateMnemonic;
+ const salt = (passphrase) => nfkd(`mnemonic${passphrase}`);
+ /**
+ * Irreversible: Uses KDF to derive 64 bytes of key data from mnemonic + optional password.
+ * @param mnemonic 12-24 words
+ * @param passphrase string that will additionally protect the key
+ * @returns 64 bytes of key data
+ * @example
+ * const mnem = 'legal winner thank year wave sausage worth useful legal winner thank yellow';
+ * await mnemonicToSeed(mnem, 'password');
+ * // new Uint8Array([...64 bytes])
+ */
+ function mnemonicToSeed(mnemonic, passphrase = '') {
+ return (0, pbkdf2_1.pbkdf2Async)(sha512_1.sha512, normalize(mnemonic).nfkd, salt(passphrase), { c: 2048, dkLen: 64 });
+ }
+ bip39.mnemonicToSeed = mnemonicToSeed;
+ /**
+ * Irreversible: Uses KDF to derive 64 bytes of key data from mnemonic + optional password.
+ * @param mnemonic 12-24 words
+ * @param passphrase string that will additionally protect the key
+ * @returns 64 bytes of key data
+ * @example
+ * const mnem = 'legal winner thank year wave sausage worth useful legal winner thank yellow';
+ * mnemonicToSeedSync(mnem, 'password');
+ * // new Uint8Array([...64 bytes])
+ */
+ function mnemonicToSeedSync(mnemonic, passphrase = '') {
+ return (0, pbkdf2_1.pbkdf2)(sha512_1.sha512, normalize(mnemonic).nfkd, salt(passphrase), { c: 2048, dkLen: 64 });
+ }
+ mnemonicToSeedSync_1 = bip39.mnemonicToSeedSync = mnemonicToSeedSync;
+
+ function number(n) {
+ if (!Number.isSafeInteger(n) || n < 0)
+ throw new Error(`Wrong positive integer: ${n}`);
+ }
+ function bool(b) {
+ if (typeof b !== 'boolean')
+ throw new Error(`Expected boolean, not ${b}`);
+ }
+ function bytes(b, ...lengths) {
+ if (!(b instanceof Uint8Array))
+ throw new TypeError('Expected Uint8Array');
+ if (lengths.length > 0 && !lengths.includes(b.length))
+ throw new TypeError(`Expected Uint8Array of length ${lengths}, not of length=${b.length}`);
+ }
+ function hash(hash) {
+ if (typeof hash !== 'function' || typeof hash.create !== 'function')
+ throw new Error('Hash should be wrapped by utils.wrapConstructor');
+ number(hash.outputLen);
+ number(hash.blockLen);
+ }
+ function exists(instance, checkFinished = true) {
+ if (instance.destroyed)
+ throw new Error('Hash instance has been destroyed');
+ if (checkFinished && instance.finished)
+ throw new Error('Hash#digest() has already been called');
+ }
+ function output(out, instance) {
+ bytes(out);
+ const min = instance.outputLen;
+ if (out.length < min) {
+ throw new Error(`digestInto() expects output buffer of length at least ${min}`);
+ }
+ }
+ const assert = {
+ number,
+ bool,
+ bytes,
+ hash,
+ exists,
+ output,
+ };
+
+ /*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
+ // Cast array to view
+ const createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
+ // The rotate right (circular right shift) operation for uint32
+ const rotr = (word, shift) => (word << (32 - shift)) | (word >>> shift);
+ const isLE = new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44;
+ // There is almost no big endian hardware, but js typed arrays uses platform specific endianness.
+ // So, just to be sure not to corrupt anything.
+ if (!isLE)
+ throw new Error('Non little-endian hardware is not supported');
+ const hexes = Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, '0'));
+ /**
+ * @example bytesToHex(Uint8Array.from([0xde, 0xad, 0xbe, 0xef]))
+ */
+ function bytesToHex(uint8a) {
+ // pre-caching improves the speed 6x
+ if (!(uint8a instanceof Uint8Array))
+ throw new Error('Uint8Array expected');
+ let hex = '';
+ for (let i = 0; i < uint8a.length; i++) {
+ hex += hexes[uint8a[i]];
+ }
+ return hex;
+ }
+ /**
+ * @example hexToBytes('deadbeef')
+ */
+ function hexToBytes(hex) {
+ if (typeof hex !== 'string') {
+ throw new TypeError('hexToBytes: expected string, got ' + typeof hex);
+ }
+ if (hex.length % 2)
+ throw new Error('hexToBytes: received invalid unpadded hex');
+ const array = new Uint8Array(hex.length / 2);
+ for (let i = 0; i < array.length; i++) {
+ const j = i * 2;
+ const hexByte = hex.slice(j, j + 2);
+ const byte = Number.parseInt(hexByte, 16);
+ if (Number.isNaN(byte) || byte < 0)
+ throw new Error('Invalid byte sequence');
+ array[i] = byte;
+ }
+ return array;
+ }
+ function utf8ToBytes(str) {
+ if (typeof str !== 'string') {
+ throw new TypeError(`utf8ToBytes expected string, got ${typeof str}`);
+ }
+ return new TextEncoder().encode(str);
+ }
+ function toBytes(data) {
+ if (typeof data === 'string')
+ data = utf8ToBytes(data);
+ if (!(data instanceof Uint8Array))
+ throw new TypeError(`Expected input type is Uint8Array (got ${typeof data})`);
+ return data;
+ }
+ /**
+ * Concats Uint8Array-s into one; like `Buffer.concat([buf1, buf2])`
+ * @example concatBytes(buf1, buf2)
+ */
+ function concatBytes(...arrays) {
+ if (!arrays.every((a) => a instanceof Uint8Array))
+ throw new Error('Uint8Array list expected');
+ if (arrays.length === 1)
+ return arrays[0];
+ const length = arrays.reduce((a, arr) => a + arr.length, 0);
+ const result = new Uint8Array(length);
+ for (let i = 0, pad = 0; i < arrays.length; i++) {
+ const arr = arrays[i];
+ result.set(arr, pad);
+ pad += arr.length;
+ }
+ return result;
+ }
+ // For runtime check if class implements interface
+ class Hash {
+ // Safe version that clones internal state
+ clone() {
+ return this._cloneInto();
+ }
+ }
+ function wrapConstructor(hashConstructor) {
+ const hashC = (message) => hashConstructor().update(toBytes(message)).digest();
+ const tmp = hashConstructor();
+ hashC.outputLen = tmp.outputLen;
+ hashC.blockLen = tmp.blockLen;
+ hashC.create = () => hashConstructor();
+ return hashC;
+ }
+
+ // HMAC (RFC 2104)
+ let HMAC$1 = class HMAC extends Hash {
+ constructor(hash, _key) {
+ super();
+ this.finished = false;
+ this.destroyed = false;
+ assert.hash(hash);
+ const key = toBytes(_key);
+ this.iHash = hash.create();
+ if (typeof this.iHash.update !== 'function')
+ throw new TypeError('Expected instance of class which extends utils.Hash');
+ this.blockLen = this.iHash.blockLen;
+ this.outputLen = this.iHash.outputLen;
+ const blockLen = this.blockLen;
+ const pad = new Uint8Array(blockLen);
+ // blockLen can be bigger than outputLen
+ pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);
+ for (let i = 0; i < pad.length; i++)
+ pad[i] ^= 0x36;
+ this.iHash.update(pad);
+ // By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone
+ this.oHash = hash.create();
+ // Undo internal XOR && apply outer XOR
+ for (let i = 0; i < pad.length; i++)
+ pad[i] ^= 0x36 ^ 0x5c;
+ this.oHash.update(pad);
+ pad.fill(0);
+ }
+ update(buf) {
+ assert.exists(this);
+ this.iHash.update(buf);
+ return this;
+ }
+ digestInto(out) {
+ assert.exists(this);
+ assert.bytes(out, this.outputLen);
+ this.finished = true;
+ this.iHash.digestInto(out);
+ this.oHash.update(out);
+ this.oHash.digestInto(out);
+ this.destroy();
+ }
+ digest() {
+ const out = new Uint8Array(this.oHash.outputLen);
+ this.digestInto(out);
+ return out;
+ }
+ _cloneInto(to) {
+ // Create new instance without calling constructor since key already in state and we don't know it.
+ to || (to = Object.create(Object.getPrototypeOf(this), {}));
+ const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
+ to = to;
+ to.finished = finished;
+ to.destroyed = destroyed;
+ to.blockLen = blockLen;
+ to.outputLen = outputLen;
+ to.oHash = oHash._cloneInto(to.oHash);
+ to.iHash = iHash._cloneInto(to.iHash);
+ return to;
+ }
+ destroy() {
+ this.destroyed = true;
+ this.oHash.destroy();
+ this.iHash.destroy();
+ }
+ };
+ /**
+ * HMAC: RFC2104 message authentication code.
+ * @param hash - function that would be used e.g. sha256
+ * @param key - message key
+ * @param message - message data
+ */
+ const hmac$1 = (hash, key, message) => new HMAC$1(hash, key).update(message).digest();
+ hmac$1.create = (hash, key) => new HMAC$1(hash, key);
+
+ // Polyfill for Safari 14
+ function setBigUint64(view, byteOffset, value, isLE) {
+ if (typeof view.setBigUint64 === 'function')
+ return view.setBigUint64(byteOffset, value, isLE);
+ const _32n = BigInt(32);
+ const _u32_max = BigInt(0xffffffff);
+ const wh = Number((value >> _32n) & _u32_max);
+ const wl = Number(value & _u32_max);
+ const h = isLE ? 4 : 0;
+ const l = isLE ? 0 : 4;
+ view.setUint32(byteOffset + h, wh, isLE);
+ view.setUint32(byteOffset + l, wl, isLE);
+ }
+ // Base SHA2 class (RFC 6234)
+ class SHA2 extends Hash {
+ constructor(blockLen, outputLen, padOffset, isLE) {
+ super();
+ this.blockLen = blockLen;
+ this.outputLen = outputLen;
+ this.padOffset = padOffset;
+ this.isLE = isLE;
+ this.finished = false;
+ this.length = 0;
+ this.pos = 0;
+ this.destroyed = false;
+ this.buffer = new Uint8Array(blockLen);
+ this.view = createView(this.buffer);
+ }
+ update(data) {
+ assert.exists(this);
+ const { view, buffer, blockLen } = this;
+ data = toBytes(data);
+ const len = data.length;
+ for (let pos = 0; pos < len;) {
+ const take = Math.min(blockLen - this.pos, len - pos);
+ // Fast path: we have at least one block in input, cast it to view and process
+ if (take === blockLen) {
+ const dataView = createView(data);
+ for (; blockLen <= len - pos; pos += blockLen)
+ this.process(dataView, pos);
+ continue;
+ }
+ buffer.set(data.subarray(pos, pos + take), this.pos);
+ this.pos += take;
+ pos += take;
+ if (this.pos === blockLen) {
+ this.process(view, 0);
+ this.pos = 0;
+ }
+ }
+ this.length += data.length;
+ this.roundClean();
+ return this;
+ }
+ digestInto(out) {
+ assert.exists(this);
+ assert.output(out, this);
+ this.finished = true;
+ // Padding
+ // We can avoid allocation of buffer for padding completely if it
+ // was previously not allocated here. But it won't change performance.
+ const { buffer, view, blockLen, isLE } = this;
+ let { pos } = this;
+ // append the bit '1' to the message
+ buffer[pos++] = 0b10000000;
+ this.buffer.subarray(pos).fill(0);
+ // we have less than padOffset left in buffer, so we cannot put length in current block, need process it and pad again
+ if (this.padOffset > blockLen - pos) {
+ this.process(view, 0);
+ pos = 0;
+ }
+ // Pad until full block byte with zeros
+ for (let i = pos; i < blockLen; i++)
+ buffer[i] = 0;
+ // Note: sha512 requires length to be 128bit integer, but length in JS will overflow before that
+ // You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen.
+ // So we just write lowest 64 bits of that value.
+ setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE);
+ this.process(view, 0);
+ const oview = createView(out);
+ const len = this.outputLen;
+ // NOTE: we do division by 4 later, which should be fused in single op with modulo by JIT
+ if (len % 4)
+ throw new Error('_sha2: outputLen should be aligned to 32bit');
+ const outLen = len / 4;
+ const state = this.get();
+ if (outLen > state.length)
+ throw new Error('_sha2: outputLen bigger than state');
+ for (let i = 0; i < outLen; i++)
+ oview.setUint32(4 * i, state[i], isLE);
+ }
+ digest() {
+ const { buffer, outputLen } = this;
+ this.digestInto(buffer);
+ const res = buffer.slice(0, outputLen);
+ this.destroy();
+ return res;
+ }
+ _cloneInto(to) {
+ to || (to = new this.constructor());
+ to.set(...this.get());
+ const { blockLen, buffer, length, finished, destroyed, pos } = this;
+ to.length = length;
+ to.pos = pos;
+ to.finished = finished;
+ to.destroyed = destroyed;
+ if (length % blockLen)
+ to.buffer.set(buffer);
+ return to;
+ }
+ }
+
+ // https://homes.esat.kuleuven.be/~bosselae/ripemd160.html
+ // https://homes.esat.kuleuven.be/~bosselae/ripemd160/pdf/AB-9601/AB-9601.pdf
+ const Rho = new Uint8Array([7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8]);
+ const Id = Uint8Array.from({ length: 16 }, (_, i) => i);
+ const Pi = Id.map((i) => (9 * i + 5) % 16);
+ let idxL = [Id];
+ let idxR = [Pi];
+ for (let i = 0; i < 4; i++)
+ for (let j of [idxL, idxR])
+ j.push(j[i].map((k) => Rho[k]));
+ const shifts = [
+ [11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8],
+ [12, 13, 11, 15, 6, 9, 9, 7, 12, 15, 11, 13, 7, 8, 7, 7],
+ [13, 15, 14, 11, 7, 7, 6, 8, 13, 14, 13, 12, 5, 5, 6, 9],
+ [14, 11, 12, 14, 8, 6, 5, 5, 15, 12, 15, 14, 9, 9, 8, 6],
+ [15, 12, 13, 13, 9, 5, 8, 6, 14, 11, 12, 11, 8, 6, 5, 5],
+ ].map((i) => new Uint8Array(i));
+ const shiftsL = idxL.map((idx, i) => idx.map((j) => shifts[i][j]));
+ const shiftsR = idxR.map((idx, i) => idx.map((j) => shifts[i][j]));
+ const Kl = new Uint32Array([0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e]);
+ const Kr = new Uint32Array([0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000]);
+ // The rotate left (circular left shift) operation for uint32
+ const rotl = (word, shift) => (word << shift) | (word >>> (32 - shift));
+ // It's called f() in spec.
+ function f(group, x, y, z) {
+ if (group === 0)
+ return x ^ y ^ z;
+ else if (group === 1)
+ return (x & y) | (~x & z);
+ else if (group === 2)
+ return (x | ~y) ^ z;
+ else if (group === 3)
+ return (x & z) | (y & ~z);
+ else
+ return x ^ (y | ~z);
+ }
+ // Temporary buffer, not used to store anything between runs
+ const BUF = new Uint32Array(16);
+ class RIPEMD160 extends SHA2 {
+ constructor() {
+ super(64, 20, 8, true);
+ this.h0 = 0x67452301 | 0;
+ this.h1 = 0xefcdab89 | 0;
+ this.h2 = 0x98badcfe | 0;
+ this.h3 = 0x10325476 | 0;
+ this.h4 = 0xc3d2e1f0 | 0;
+ }
+ get() {
+ const { h0, h1, h2, h3, h4 } = this;
+ return [h0, h1, h2, h3, h4];
+ }
+ set(h0, h1, h2, h3, h4) {
+ this.h0 = h0 | 0;
+ this.h1 = h1 | 0;
+ this.h2 = h2 | 0;
+ this.h3 = h3 | 0;
+ this.h4 = h4 | 0;
+ }
+ process(view, offset) {
+ for (let i = 0; i < 16; i++, offset += 4)
+ BUF[i] = view.getUint32(offset, true);
+ // prettier-ignore
+ let al = this.h0 | 0, ar = al, bl = this.h1 | 0, br = bl, cl = this.h2 | 0, cr = cl, dl = this.h3 | 0, dr = dl, el = this.h4 | 0, er = el;
+ // Instead of iterating 0 to 80, we split it into 5 groups
+ // And use the groups in constants, functions, etc. Much simpler
+ for (let group = 0; group < 5; group++) {
+ const rGroup = 4 - group;
+ const hbl = Kl[group], hbr = Kr[group]; // prettier-ignore
+ const rl = idxL[group], rr = idxR[group]; // prettier-ignore
+ const sl = shiftsL[group], sr = shiftsR[group]; // prettier-ignore
+ for (let i = 0; i < 16; i++) {
+ const tl = (rotl(al + f(group, bl, cl, dl) + BUF[rl[i]] + hbl, sl[i]) + el) | 0;
+ al = el, el = dl, dl = rotl(cl, 10) | 0, cl = bl, bl = tl; // prettier-ignore
+ }
+ // 2 loops are 10% faster
+ for (let i = 0; i < 16; i++) {
+ const tr = (rotl(ar + f(rGroup, br, cr, dr) + BUF[rr[i]] + hbr, sr[i]) + er) | 0;
+ ar = er, er = dr, dr = rotl(cr, 10) | 0, cr = br, br = tr; // prettier-ignore
+ }
+ }
+ // Add the compressed chunk to the current hash value
+ this.set((this.h1 + cl + dr) | 0, (this.h2 + dl + er) | 0, (this.h3 + el + ar) | 0, (this.h4 + al + br) | 0, (this.h0 + bl + cr) | 0);
+ }
+ roundClean() {
+ BUF.fill(0);
+ }
+ destroy() {
+ this.destroyed = true;
+ this.buffer.fill(0);
+ this.set(0, 0, 0, 0, 0);
+ }
+ }
+ /**
+ * RIPEMD-160 - a hash function from 1990s.
+ * @param message - msg that would be hashed
+ */
+ const ripemd160 = wrapConstructor(() => new RIPEMD160());
+
+ // Choice: a ? b : c
+ const Chi = (a, b, c) => (a & b) ^ (~a & c);
+ // Majority function, true if any two inpust is true
+ const Maj = (a, b, c) => (a & b) ^ (a & c) ^ (b & c);
+ // Round constants:
+ // first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
+ // prettier-ignore
+ const SHA256_K = new Uint32Array([
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+ ]);
+ // Initial state (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
+ // prettier-ignore
+ const IV = new Uint32Array([
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
+ ]);
+ // Temporary buffer, not used to store anything between runs
+ // Named this way because it matches specification.
+ const SHA256_W = new Uint32Array(64);
+ class SHA256 extends SHA2 {
+ constructor() {
+ super(64, 32, 8, false);
+ // We cannot use array here since array allows indexing by variable
+ // which means optimizer/compiler cannot use registers.
+ this.A = IV[0] | 0;
+ this.B = IV[1] | 0;
+ this.C = IV[2] | 0;
+ this.D = IV[3] | 0;
+ this.E = IV[4] | 0;
+ this.F = IV[5] | 0;
+ this.G = IV[6] | 0;
+ this.H = IV[7] | 0;
+ }
+ get() {
+ const { A, B, C, D, E, F, G, H } = this;
+ return [A, B, C, D, E, F, G, H];
+ }
+ // prettier-ignore
+ set(A, B, C, D, E, F, G, H) {
+ this.A = A | 0;
+ this.B = B | 0;
+ this.C = C | 0;
+ this.D = D | 0;
+ this.E = E | 0;
+ this.F = F | 0;
+ this.G = G | 0;
+ this.H = H | 0;
+ }
+ process(view, offset) {
+ // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array
+ for (let i = 0; i < 16; i++, offset += 4)
+ SHA256_W[i] = view.getUint32(offset, false);
+ for (let i = 16; i < 64; i++) {
+ const W15 = SHA256_W[i - 15];
+ const W2 = SHA256_W[i - 2];
+ const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3);
+ const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10);
+ SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0;
+ }
+ // Compression function main loop, 64 rounds
+ let { A, B, C, D, E, F, G, H } = this;
+ for (let i = 0; i < 64; i++) {
+ const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);
+ const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;
+ const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);
+ const T2 = (sigma0 + Maj(A, B, C)) | 0;
+ H = G;
+ G = F;
+ F = E;
+ E = (D + T1) | 0;
+ D = C;
+ C = B;
+ B = A;
+ A = (T1 + T2) | 0;
+ }
+ // Add the compressed chunk to the current hash value
+ A = (A + this.A) | 0;
+ B = (B + this.B) | 0;
+ C = (C + this.C) | 0;
+ D = (D + this.D) | 0;
+ E = (E + this.E) | 0;
+ F = (F + this.F) | 0;
+ G = (G + this.G) | 0;
+ H = (H + this.H) | 0;
+ this.set(A, B, C, D, E, F, G, H);
+ }
+ roundClean() {
+ SHA256_W.fill(0);
+ }
+ destroy() {
+ this.set(0, 0, 0, 0, 0, 0, 0, 0);
+ this.buffer.fill(0);
+ }
+ }
+ // Constants from https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
+ class SHA224 extends SHA256 {
+ constructor() {
+ super();
+ this.A = 0xc1059ed8 | 0;
+ this.B = 0x367cd507 | 0;
+ this.C = 0x3070dd17 | 0;
+ this.D = 0xf70e5939 | 0;
+ this.E = 0xffc00b31 | 0;
+ this.F = 0x68581511 | 0;
+ this.G = 0x64f98fa7 | 0;
+ this.H = 0xbefa4fa4 | 0;
+ this.outputLen = 28;
+ }
+ }
+ /**
+ * SHA2-256 hash function
+ * @param message - data that would be hashed
+ */
+ const sha256 = wrapConstructor(() => new SHA256());
+ wrapConstructor(() => new SHA224());
+
+ const U32_MASK64 = BigInt(2 ** 32 - 1);
+ const _32n = BigInt(32);
+ // We are not using BigUint64Array, because they are extremely slow as per 2022
+ function fromBig(n, le = false) {
+ if (le)
+ return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
+ return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
+ }
+ function split(lst, le = false) {
+ let Ah = new Uint32Array(lst.length);
+ let Al = new Uint32Array(lst.length);
+ for (let i = 0; i < lst.length; i++) {
+ const { h, l } = fromBig(lst[i], le);
+ [Ah[i], Al[i]] = [h, l];
+ }
+ return [Ah, Al];
+ }
+ const toBig = (h, l) => (BigInt(h >>> 0) << _32n) | BigInt(l >>> 0);
+ // for Shift in [0, 32)
+ const shrSH = (h, l, s) => h >>> s;
+ const shrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
+ // Right rotate for Shift in [1, 32)
+ const rotrSH = (h, l, s) => (h >>> s) | (l << (32 - s));
+ const rotrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
+ // Right rotate for Shift in (32, 64), NOTE: 32 is special case.
+ const rotrBH = (h, l, s) => (h << (64 - s)) | (l >>> (s - 32));
+ const rotrBL = (h, l, s) => (h >>> (s - 32)) | (l << (64 - s));
+ // Right rotate for shift===32 (just swaps l&h)
+ const rotr32H = (h, l) => l;
+ const rotr32L = (h, l) => h;
+ // Left rotate for Shift in [1, 32)
+ const rotlSH = (h, l, s) => (h << s) | (l >>> (32 - s));
+ const rotlSL = (h, l, s) => (l << s) | (h >>> (32 - s));
+ // Left rotate for Shift in (32, 64), NOTE: 32 is special case.
+ const rotlBH = (h, l, s) => (l << (s - 32)) | (h >>> (64 - s));
+ const rotlBL = (h, l, s) => (h << (s - 32)) | (l >>> (64 - s));
+ // JS uses 32-bit signed integers for bitwise operations which means we cannot
+ // simple take carry out of low bit sum by shift, we need to use division.
+ // Removing "export" has 5% perf penalty -_-
+ function add(Ah, Al, Bh, Bl) {
+ const l = (Al >>> 0) + (Bl >>> 0);
+ return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 };
+ }
+ // Addition with more than 2 elements
+ const add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
+ const add3H = (low, Ah, Bh, Ch) => (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0;
+ const add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
+ const add4H = (low, Ah, Bh, Ch, Dh) => (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0;
+ const add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
+ const add5H = (low, Ah, Bh, Ch, Dh, Eh) => (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0;
+ // prettier-ignore
+ const u64 = {
+ fromBig, split, toBig,
+ shrSH, shrSL,
+ rotrSH, rotrSL, rotrBH, rotrBL,
+ rotr32H, rotr32L,
+ rotlSH, rotlSL, rotlBH, rotlBL,
+ add, add3L, add3H, add4L, add4H, add5H, add5L,
+ };
+
+ // Round contants (first 32 bits of the fractional parts of the cube roots of the first 80 primes 2..409):
+ // prettier-ignore
+ const [SHA512_Kh, SHA512_Kl] = u64.split([
+ '0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc',
+ '0x3956c25bf348b538', '0x59f111f1b605d019', '0x923f82a4af194f9b', '0xab1c5ed5da6d8118',
+ '0xd807aa98a3030242', '0x12835b0145706fbe', '0x243185be4ee4b28c', '0x550c7dc3d5ffb4e2',
+ '0x72be5d74f27b896f', '0x80deb1fe3b1696b1', '0x9bdc06a725c71235', '0xc19bf174cf692694',
+ '0xe49b69c19ef14ad2', '0xefbe4786384f25e3', '0x0fc19dc68b8cd5b5', '0x240ca1cc77ac9c65',
+ '0x2de92c6f592b0275', '0x4a7484aa6ea6e483', '0x5cb0a9dcbd41fbd4', '0x76f988da831153b5',
+ '0x983e5152ee66dfab', '0xa831c66d2db43210', '0xb00327c898fb213f', '0xbf597fc7beef0ee4',
+ '0xc6e00bf33da88fc2', '0xd5a79147930aa725', '0x06ca6351e003826f', '0x142929670a0e6e70',
+ '0x27b70a8546d22ffc', '0x2e1b21385c26c926', '0x4d2c6dfc5ac42aed', '0x53380d139d95b3df',
+ '0x650a73548baf63de', '0x766a0abb3c77b2a8', '0x81c2c92e47edaee6', '0x92722c851482353b',
+ '0xa2bfe8a14cf10364', '0xa81a664bbc423001', '0xc24b8b70d0f89791', '0xc76c51a30654be30',
+ '0xd192e819d6ef5218', '0xd69906245565a910', '0xf40e35855771202a', '0x106aa07032bbd1b8',
+ '0x19a4c116b8d2d0c8', '0x1e376c085141ab53', '0x2748774cdf8eeb99', '0x34b0bcb5e19b48a8',
+ '0x391c0cb3c5c95a63', '0x4ed8aa4ae3418acb', '0x5b9cca4f7763e373', '0x682e6ff3d6b2b8a3',
+ '0x748f82ee5defb2fc', '0x78a5636f43172f60', '0x84c87814a1f0ab72', '0x8cc702081a6439ec',
+ '0x90befffa23631e28', '0xa4506cebde82bde9', '0xbef9a3f7b2c67915', '0xc67178f2e372532b',
+ '0xca273eceea26619c', '0xd186b8c721c0c207', '0xeada7dd6cde0eb1e', '0xf57d4f7fee6ed178',
+ '0x06f067aa72176fba', '0x0a637dc5a2c898a6', '0x113f9804bef90dae', '0x1b710b35131c471b',
+ '0x28db77f523047d84', '0x32caab7b40c72493', '0x3c9ebe0a15c9bebc', '0x431d67c49c100d4c',
+ '0x4cc5d4becb3e42b6', '0x597f299cfc657e2a', '0x5fcb6fab3ad6faec', '0x6c44198c4a475817'
+ ].map(n => BigInt(n)));
+ // Temporary buffer, not used to store anything between runs
+ const SHA512_W_H = new Uint32Array(80);
+ const SHA512_W_L = new Uint32Array(80);
+ class SHA512 extends SHA2 {
+ constructor() {
+ super(128, 64, 16, false);
+ // We cannot use array here since array allows indexing by variable which means optimizer/compiler cannot use registers.
+ // Also looks cleaner and easier to verify with spec.
+ // Initial state (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
+ // h -- high 32 bits, l -- low 32 bits
+ this.Ah = 0x6a09e667 | 0;
+ this.Al = 0xf3bcc908 | 0;
+ this.Bh = 0xbb67ae85 | 0;
+ this.Bl = 0x84caa73b | 0;
+ this.Ch = 0x3c6ef372 | 0;
+ this.Cl = 0xfe94f82b | 0;
+ this.Dh = 0xa54ff53a | 0;
+ this.Dl = 0x5f1d36f1 | 0;
+ this.Eh = 0x510e527f | 0;
+ this.El = 0xade682d1 | 0;
+ this.Fh = 0x9b05688c | 0;
+ this.Fl = 0x2b3e6c1f | 0;
+ this.Gh = 0x1f83d9ab | 0;
+ this.Gl = 0xfb41bd6b | 0;
+ this.Hh = 0x5be0cd19 | 0;
+ this.Hl = 0x137e2179 | 0;
+ }
+ // prettier-ignore
+ get() {
+ const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
+ return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl];
+ }
+ // prettier-ignore
+ set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl) {
+ this.Ah = Ah | 0;
+ this.Al = Al | 0;
+ this.Bh = Bh | 0;
+ this.Bl = Bl | 0;
+ this.Ch = Ch | 0;
+ this.Cl = Cl | 0;
+ this.Dh = Dh | 0;
+ this.Dl = Dl | 0;
+ this.Eh = Eh | 0;
+ this.El = El | 0;
+ this.Fh = Fh | 0;
+ this.Fl = Fl | 0;
+ this.Gh = Gh | 0;
+ this.Gl = Gl | 0;
+ this.Hh = Hh | 0;
+ this.Hl = Hl | 0;
+ }
+ process(view, offset) {
+ // Extend the first 16 words into the remaining 64 words w[16..79] of the message schedule array
+ for (let i = 0; i < 16; i++, offset += 4) {
+ SHA512_W_H[i] = view.getUint32(offset);
+ SHA512_W_L[i] = view.getUint32((offset += 4));
+ }
+ for (let i = 16; i < 80; i++) {
+ // s0 := (w[i-15] rightrotate 1) xor (w[i-15] rightrotate 8) xor (w[i-15] rightshift 7)
+ const W15h = SHA512_W_H[i - 15] | 0;
+ const W15l = SHA512_W_L[i - 15] | 0;
+ const s0h = u64.rotrSH(W15h, W15l, 1) ^ u64.rotrSH(W15h, W15l, 8) ^ u64.shrSH(W15h, W15l, 7);
+ const s0l = u64.rotrSL(W15h, W15l, 1) ^ u64.rotrSL(W15h, W15l, 8) ^ u64.shrSL(W15h, W15l, 7);
+ // s1 := (w[i-2] rightrotate 19) xor (w[i-2] rightrotate 61) xor (w[i-2] rightshift 6)
+ const W2h = SHA512_W_H[i - 2] | 0;
+ const W2l = SHA512_W_L[i - 2] | 0;
+ const s1h = u64.rotrSH(W2h, W2l, 19) ^ u64.rotrBH(W2h, W2l, 61) ^ u64.shrSH(W2h, W2l, 6);
+ const s1l = u64.rotrSL(W2h, W2l, 19) ^ u64.rotrBL(W2h, W2l, 61) ^ u64.shrSL(W2h, W2l, 6);
+ // SHA256_W[i] = s0 + s1 + SHA256_W[i - 7] + SHA256_W[i - 16];
+ const SUMl = u64.add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);
+ const SUMh = u64.add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);
+ SHA512_W_H[i] = SUMh | 0;
+ SHA512_W_L[i] = SUMl | 0;
+ }
+ let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
+ // Compression function main loop, 80 rounds
+ for (let i = 0; i < 80; i++) {
+ // S1 := (e rightrotate 14) xor (e rightrotate 18) xor (e rightrotate 41)
+ const sigma1h = u64.rotrSH(Eh, El, 14) ^ u64.rotrSH(Eh, El, 18) ^ u64.rotrBH(Eh, El, 41);
+ const sigma1l = u64.rotrSL(Eh, El, 14) ^ u64.rotrSL(Eh, El, 18) ^ u64.rotrBL(Eh, El, 41);
+ //const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;
+ const CHIh = (Eh & Fh) ^ (~Eh & Gh);
+ const CHIl = (El & Fl) ^ (~El & Gl);
+ // T1 = H + sigma1 + Chi(E, F, G) + SHA512_K[i] + SHA512_W[i]
+ // prettier-ignore
+ const T1ll = u64.add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);
+ const T1h = u64.add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);
+ const T1l = T1ll | 0;
+ // S0 := (a rightrotate 28) xor (a rightrotate 34) xor (a rightrotate 39)
+ const sigma0h = u64.rotrSH(Ah, Al, 28) ^ u64.rotrBH(Ah, Al, 34) ^ u64.rotrBH(Ah, Al, 39);
+ const sigma0l = u64.rotrSL(Ah, Al, 28) ^ u64.rotrBL(Ah, Al, 34) ^ u64.rotrBL(Ah, Al, 39);
+ const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch);
+ const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl);
+ Hh = Gh | 0;
+ Hl = Gl | 0;
+ Gh = Fh | 0;
+ Gl = Fl | 0;
+ Fh = Eh | 0;
+ Fl = El | 0;
+ ({ h: Eh, l: El } = u64.add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));
+ Dh = Ch | 0;
+ Dl = Cl | 0;
+ Ch = Bh | 0;
+ Cl = Bl | 0;
+ Bh = Ah | 0;
+ Bl = Al | 0;
+ const All = u64.add3L(T1l, sigma0l, MAJl);
+ Ah = u64.add3H(All, T1h, sigma0h, MAJh);
+ Al = All | 0;
+ }
+ // Add the compressed chunk to the current hash value
+ ({ h: Ah, l: Al } = u64.add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));
+ ({ h: Bh, l: Bl } = u64.add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));
+ ({ h: Ch, l: Cl } = u64.add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));
+ ({ h: Dh, l: Dl } = u64.add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));
+ ({ h: Eh, l: El } = u64.add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));
+ ({ h: Fh, l: Fl } = u64.add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));
+ ({ h: Gh, l: Gl } = u64.add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));
+ ({ h: Hh, l: Hl } = u64.add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));
+ this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);
+ }
+ roundClean() {
+ SHA512_W_H.fill(0);
+ SHA512_W_L.fill(0);
+ }
+ destroy() {
+ this.buffer.fill(0);
+ this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ }
+ }
+ class SHA512_224 extends SHA512 {
+ constructor() {
+ super();
+ // h -- high 32 bits, l -- low 32 bits
+ this.Ah = 0x8c3d37c8 | 0;
+ this.Al = 0x19544da2 | 0;
+ this.Bh = 0x73e19966 | 0;
+ this.Bl = 0x89dcd4d6 | 0;
+ this.Ch = 0x1dfab7ae | 0;
+ this.Cl = 0x32ff9c82 | 0;
+ this.Dh = 0x679dd514 | 0;
+ this.Dl = 0x582f9fcf | 0;
+ this.Eh = 0x0f6d2b69 | 0;
+ this.El = 0x7bd44da8 | 0;
+ this.Fh = 0x77e36f73 | 0;
+ this.Fl = 0x04c48942 | 0;
+ this.Gh = 0x3f9d85a8 | 0;
+ this.Gl = 0x6a1d36c8 | 0;
+ this.Hh = 0x1112e6ad | 0;
+ this.Hl = 0x91d692a1 | 0;
+ this.outputLen = 28;
+ }
+ }
+ class SHA512_256 extends SHA512 {
+ constructor() {
+ super();
+ // h -- high 32 bits, l -- low 32 bits
+ this.Ah = 0x22312194 | 0;
+ this.Al = 0xfc2bf72c | 0;
+ this.Bh = 0x9f555fa3 | 0;
+ this.Bl = 0xc84c64c2 | 0;
+ this.Ch = 0x2393b86b | 0;
+ this.Cl = 0x6f53b151 | 0;
+ this.Dh = 0x96387719 | 0;
+ this.Dl = 0x5940eabd | 0;
+ this.Eh = 0x96283ee2 | 0;
+ this.El = 0xa88effe3 | 0;
+ this.Fh = 0xbe5e1e25 | 0;
+ this.Fl = 0x53863992 | 0;
+ this.Gh = 0x2b0199fc | 0;
+ this.Gl = 0x2c85b8aa | 0;
+ this.Hh = 0x0eb72ddc | 0;
+ this.Hl = 0x81c52ca2 | 0;
+ this.outputLen = 32;
+ }
+ }
+ class SHA384 extends SHA512 {
+ constructor() {
+ super();
+ // h -- high 32 bits, l -- low 32 bits
+ this.Ah = 0xcbbb9d5d | 0;
+ this.Al = 0xc1059ed8 | 0;
+ this.Bh = 0x629a292a | 0;
+ this.Bl = 0x367cd507 | 0;
+ this.Ch = 0x9159015a | 0;
+ this.Cl = 0x3070dd17 | 0;
+ this.Dh = 0x152fecd8 | 0;
+ this.Dl = 0xf70e5939 | 0;
+ this.Eh = 0x67332667 | 0;
+ this.El = 0xffc00b31 | 0;
+ this.Fh = 0x8eb44a87 | 0;
+ this.Fl = 0x68581511 | 0;
+ this.Gh = 0xdb0c2e0d | 0;
+ this.Gl = 0x64f98fa7 | 0;
+ this.Hh = 0x47b5481d | 0;
+ this.Hl = 0xbefa4fa4 | 0;
+ this.outputLen = 48;
+ }
+ }
+ const sha512 = wrapConstructor(() => new SHA512());
+ wrapConstructor(() => new SHA512_224());
+ wrapConstructor(() => new SHA512_256());
+ wrapConstructor(() => new SHA384());
+
+ utils$1.hmacSha256Sync = (key, ...msgs) => hmac$1(sha256, key, utils$1.concatBytes(...msgs));
+ const base58check = base58check$1(sha256);
+ function bytesToNumber(bytes) {
+ return BigInt(`0x${bytesToHex(bytes)}`);
+ }
+ function numberToBytes(num) {
+ return hexToBytes(num.toString(16).padStart(64, '0'));
+ }
+ const MASTER_SECRET = utf8ToBytes('Bitcoin seed');
+ const BITCOIN_VERSIONS = { private: 0x0488ade4, public: 0x0488b21e };
+ const HARDENED_OFFSET = 0x80000000;
+ const hash160 = (data) => ripemd160(sha256(data));
+ const fromU32 = (data) => createView(data).getUint32(0, false);
+ const toU32 = (n) => {
+ if (!Number.isSafeInteger(n) || n < 0 || n > 2 ** 32 - 1) {
+ throw new Error(`Invalid number=${n}. Should be from 0 to 2 ** 32 - 1`);
+ }
+ const buf = new Uint8Array(4);
+ createView(buf).setUint32(0, n, false);
+ return buf;
+ };
+ class HDKey {
+ constructor(opt) {
+ this.depth = 0;
+ this.index = 0;
+ this.chainCode = null;
+ this.parentFingerprint = 0;
+ if (!opt || typeof opt !== 'object') {
+ throw new Error('HDKey.constructor must not be called directly');
+ }
+ this.versions = opt.versions || BITCOIN_VERSIONS;
+ this.depth = opt.depth || 0;
+ this.chainCode = opt.chainCode;
+ this.index = opt.index || 0;
+ this.parentFingerprint = opt.parentFingerprint || 0;
+ if (!this.depth) {
+ if (this.parentFingerprint || this.index) {
+ throw new Error('HDKey: zero depth with non-zero index/parent fingerprint');
+ }
+ }
+ if (opt.publicKey && opt.privateKey) {
+ throw new Error('HDKey: publicKey and privateKey at same time.');
+ }
+ if (opt.privateKey) {
+ if (!utils$1.isValidPrivateKey(opt.privateKey)) {
+ throw new Error('Invalid private key');
+ }
+ this.privKey =
+ typeof opt.privateKey === 'bigint' ? opt.privateKey : bytesToNumber(opt.privateKey);
+ this.privKeyBytes = numberToBytes(this.privKey);
+ this.pubKey = getPublicKey$1(opt.privateKey, true);
+ }
+ else if (opt.publicKey) {
+ this.pubKey = Point.fromHex(opt.publicKey).toRawBytes(true);
+ }
+ else {
+ throw new Error('HDKey: no public or private key provided');
+ }
+ this.pubHash = hash160(this.pubKey);
+ }
+ get fingerprint() {
+ if (!this.pubHash) {
+ throw new Error('No publicKey set!');
+ }
+ return fromU32(this.pubHash);
+ }
+ get identifier() {
+ return this.pubHash;
+ }
+ get pubKeyHash() {
+ return this.pubHash;
+ }
+ get privateKey() {
+ return this.privKeyBytes || null;
+ }
+ get publicKey() {
+ return this.pubKey || null;
+ }
+ get privateExtendedKey() {
+ const priv = this.privateKey;
+ if (!priv) {
+ throw new Error('No private key');
+ }
+ return base58check.encode(this.serialize(this.versions.private, concatBytes(new Uint8Array([0]), priv)));
+ }
+ get publicExtendedKey() {
+ if (!this.pubKey) {
+ throw new Error('No public key');
+ }
+ return base58check.encode(this.serialize(this.versions.public, this.pubKey));
+ }
+ static fromMasterSeed(seed, versions = BITCOIN_VERSIONS) {
+ bytes(seed);
+ if (8 * seed.length < 128 || 8 * seed.length > 512) {
+ throw new Error(`HDKey: wrong seed length=${seed.length}. Should be between 128 and 512 bits; 256 bits is advised)`);
+ }
+ const I = hmac$1(sha512, MASTER_SECRET, seed);
+ return new HDKey({
+ versions,
+ chainCode: I.slice(32),
+ privateKey: I.slice(0, 32),
+ });
+ }
+ static fromExtendedKey(base58key, versions = BITCOIN_VERSIONS) {
+ const keyBuffer = base58check.decode(base58key);
+ const keyView = createView(keyBuffer);
+ const version = keyView.getUint32(0, false);
+ const opt = {
+ versions,
+ depth: keyBuffer[4],
+ parentFingerprint: keyView.getUint32(5, false),
+ index: keyView.getUint32(9, false),
+ chainCode: keyBuffer.slice(13, 45),
+ };
+ const key = keyBuffer.slice(45);
+ const isPriv = key[0] === 0;
+ if (version !== versions[isPriv ? 'private' : 'public']) {
+ throw new Error('Version mismatch');
+ }
+ if (isPriv) {
+ return new HDKey({ ...opt, privateKey: key.slice(1) });
+ }
+ else {
+ return new HDKey({ ...opt, publicKey: key });
+ }
+ }
+ static fromJSON(json) {
+ return HDKey.fromExtendedKey(json.xpriv);
+ }
+ derive(path) {
+ if (!/^[mM]'?/.test(path)) {
+ throw new Error('Path must start with "m" or "M"');
+ }
+ if (/^[mM]'?$/.test(path)) {
+ return this;
+ }
+ const parts = path.replace(/^[mM]'?\//, '').split('/');
+ let child = this;
+ for (const c of parts) {
+ const m = /^(\d+)('?)$/.exec(c);
+ if (!m || m.length !== 3) {
+ throw new Error(`Invalid child index: ${c}`);
+ }
+ let idx = +m[1];
+ if (!Number.isSafeInteger(idx) || idx >= HARDENED_OFFSET) {
+ throw new Error('Invalid index');
+ }
+ if (m[2] === "'") {
+ idx += HARDENED_OFFSET;
+ }
+ child = child.deriveChild(idx);
+ }
+ return child;
+ }
+ deriveChild(index) {
+ if (!this.pubKey || !this.chainCode) {
+ throw new Error('No publicKey or chainCode set');
+ }
+ let data = toU32(index);
+ if (index >= HARDENED_OFFSET) {
+ const priv = this.privateKey;
+ if (!priv) {
+ throw new Error('Could not derive hardened child key');
+ }
+ data = concatBytes(new Uint8Array([0]), priv, data);
+ }
+ else {
+ data = concatBytes(this.pubKey, data);
+ }
+ const I = hmac$1(sha512, this.chainCode, data);
+ const childTweak = bytesToNumber(I.slice(0, 32));
+ const chainCode = I.slice(32);
+ if (!utils$1.isValidPrivateKey(childTweak)) {
+ throw new Error('Tweak bigger than curve order');
+ }
+ const opt = {
+ versions: this.versions,
+ chainCode,
+ depth: this.depth + 1,
+ parentFingerprint: this.fingerprint,
+ index,
+ };
+ try {
+ if (this.privateKey) {
+ const added = utils$1.mod(this.privKey + childTweak, CURVE.n);
+ if (!utils$1.isValidPrivateKey(added)) {
+ throw new Error('The tweak was out of range or the resulted private key is invalid');
+ }
+ opt.privateKey = added;
+ }
+ else {
+ const added = Point.fromHex(this.pubKey).add(Point.fromPrivateKey(childTweak));
+ if (added.equals(Point.ZERO)) {
+ throw new Error('The tweak was equal to negative P, which made the result key invalid');
+ }
+ opt.publicKey = added.toRawBytes(true);
+ }
+ return new HDKey(opt);
+ }
+ catch (err) {
+ return this.deriveChild(index + 1);
+ }
+ }
+ sign(hash) {
+ if (!this.privateKey) {
+ throw new Error('No privateKey set!');
+ }
+ bytes(hash, 32);
+ return signSync(hash, this.privKey, {
+ canonical: true,
+ der: false,
+ });
+ }
+ verify(hash, signature) {
+ bytes(hash, 32);
+ bytes(signature, 64);
+ if (!this.publicKey) {
+ throw new Error('No publicKey set!');
+ }
+ let sig;
+ try {
+ sig = Signature.fromCompact(signature);
+ }
+ catch (error) {
+ return false;
+ }
+ return verify(sig, hash, this.publicKey);
+ }
+ wipePrivateData() {
+ this.privKey = undefined;
+ if (this.privKeyBytes) {
+ this.privKeyBytes.fill(0);
+ this.privKeyBytes = undefined;
+ }
+ return this;
+ }
+ toJSON() {
+ return {
+ xpriv: this.privateExtendedKey,
+ xpub: this.publicExtendedKey,
+ };
+ }
+ serialize(version, key) {
+ if (!this.chainCode) {
+ throw new Error('No chainCode set');
+ }
+ bytes(key, 33);
+ return concatBytes(toU32(version), new Uint8Array([this.depth]), toU32(this.parentFingerprint), toU32(this.index), this.chainCode, key);
+ }
+ }
+
+ // HMAC (RFC 2104)
+ class HMAC extends Hash$1 {
+ constructor(hash, _key) {
+ super();
+ this.finished = false;
+ this.destroyed = false;
+ assertHash(hash);
+ const key = toBytes$1(_key);
+ this.iHash = hash.create();
+ if (!(this.iHash instanceof Hash$1))
+ throw new TypeError('Expected instance of class which extends utils.Hash');
+ const blockLen = (this.blockLen = this.iHash.blockLen);
+ this.outputLen = this.iHash.outputLen;
+ const pad = new Uint8Array(blockLen);
+ // blockLen can be bigger than outputLen
+ pad.set(key.length > this.iHash.blockLen ? hash.create().update(key).digest() : key);
+ for (let i = 0; i < pad.length; i++)
+ pad[i] ^= 0x36;
+ this.iHash.update(pad);
+ // By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone
+ this.oHash = hash.create();
+ // Undo internal XOR && apply outer XOR
+ for (let i = 0; i < pad.length; i++)
+ pad[i] ^= 0x36 ^ 0x5c;
+ this.oHash.update(pad);
+ pad.fill(0);
+ }
+ update(buf) {
+ if (this.destroyed)
+ throw new Error('instance is destroyed');
+ this.iHash.update(buf);
+ return this;
+ }
+ digestInto(out) {
+ if (this.destroyed)
+ throw new Error('instance is destroyed');
+ if (!(out instanceof Uint8Array) || out.length !== this.outputLen)
+ throw new Error('HMAC: Invalid output buffer');
+ if (this.finished)
+ throw new Error('digest() was already called');
+ this.finished = true;
+ this.iHash.digestInto(out);
+ this.oHash.update(out);
+ this.oHash.digestInto(out);
+ this.destroy();
+ }
+ digest() {
+ const out = new Uint8Array(this.oHash.outputLen);
+ this.digestInto(out);
+ return out;
+ }
+ _cloneInto(to) {
+ // Create new instance without calling constructor since key already in state and we don't know it.
+ to || (to = Object.create(Object.getPrototypeOf(this), {}));
+ const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
+ to = to;
+ to.finished = finished;
+ to.destroyed = destroyed;
+ to.blockLen = blockLen;
+ to.outputLen = outputLen;
+ to.oHash = oHash._cloneInto(to.oHash);
+ to.iHash = iHash._cloneInto(to.iHash);
+ return to;
+ }
+ destroy() {
+ this.destroyed = true;
+ this.oHash.destroy();
+ this.iHash.destroy();
+ }
+ }
+ const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();
+ hmac.create = (hash, key) => new HMAC(hash, key);
+ hmac.init = hmac.create;
+
+ var __defProp = Object.defineProperty;
+ var __export = (target, all) => {
+ for (var name in all)
+ __defProp(target, name, { get: all[name], enumerable: true });
+ };
+ function generatePrivateKey() {
+ return utils$1.bytesToHex(utils$1.randomPrivateKey());
+ }
+ function getPublicKey(privateKey) {
+ return utils$1.bytesToHex(schnorr.getPublicKey(privateKey));
+ }
+
+ // utils.ts
+ var utils_exports = {};
+ __export(utils_exports, {
+ insertEventIntoAscendingList: () => insertEventIntoAscendingList,
+ insertEventIntoDescendingList: () => insertEventIntoDescendingList,
+ normalizeURL: () => normalizeURL,
+ utf8Decoder: () => utf8Decoder,
+ utf8Encoder: () => utf8Encoder
+ });
+ var utf8Decoder = new TextDecoder("utf-8");
+ var utf8Encoder = new TextEncoder();
+ function normalizeURL(url) {
+ let p = new URL(url);
+ p.pathname = p.pathname.replace(/\/+/g, "/");
+ if (p.pathname.endsWith("/"))
+ p.pathname = p.pathname.slice(0, -1);
+ if (p.port === "80" && p.protocol === "ws:" || p.port === "443" && p.protocol === "wss:")
+ p.port = "";
+ p.searchParams.sort();
+ p.hash = "";
+ return p.toString();
+ }
+ function insertEventIntoDescendingList(sortedArray, event) {
+ let start = 0;
+ let end = sortedArray.length - 1;
+ let midPoint;
+ let position = start;
+ if (end < 0) {
+ position = 0;
+ } else if (event.created_at < sortedArray[end].created_at) {
+ position = end + 1;
+ } else if (event.created_at >= sortedArray[start].created_at) {
+ position = start;
+ } else
+ while (true) {
+ if (end <= start + 1) {
+ position = end;
+ break;
+ }
+ midPoint = Math.floor(start + (end - start) / 2);
+ if (sortedArray[midPoint].created_at > event.created_at) {
+ start = midPoint;
+ } else if (sortedArray[midPoint].created_at < event.created_at) {
+ end = midPoint;
+ } else {
+ position = midPoint;
+ break;
+ }
+ }
+ if (sortedArray[position]?.id !== event.id) {
+ return [
+ ...sortedArray.slice(0, position),
+ event,
+ ...sortedArray.slice(position)
+ ];
+ }
+ return sortedArray;
+ }
+ function insertEventIntoAscendingList(sortedArray, event) {
+ let start = 0;
+ let end = sortedArray.length - 1;
+ let midPoint;
+ let position = start;
+ if (end < 0) {
+ position = 0;
+ } else if (event.created_at > sortedArray[end].created_at) {
+ position = end + 1;
+ } else if (event.created_at <= sortedArray[start].created_at) {
+ position = start;
+ } else
+ while (true) {
+ if (end <= start + 1) {
+ position = end;
+ break;
+ }
+ midPoint = Math.floor(start + (end - start) / 2);
+ if (sortedArray[midPoint].created_at < event.created_at) {
+ start = midPoint;
+ } else if (sortedArray[midPoint].created_at > event.created_at) {
+ end = midPoint;
+ } else {
+ position = midPoint;
+ break;
+ }
+ }
+ if (sortedArray[position]?.id !== event.id) {
+ return [
+ ...sortedArray.slice(0, position),
+ event,
+ ...sortedArray.slice(position)
+ ];
+ }
+ return sortedArray;
+ }
+ function serializeEvent(evt) {
+ if (!validateEvent(evt))
+ throw new Error("can't serialize event with wrong or missing properties");
+ return JSON.stringify([
+ 0,
+ evt.pubkey,
+ evt.created_at,
+ evt.kind,
+ evt.tags,
+ evt.content
+ ]);
+ }
+ function getEventHash(event) {
+ let eventHash = sha256$2(utf8Encoder.encode(serializeEvent(event)));
+ return utils$1.bytesToHex(eventHash);
+ }
+ function validateEvent(event) {
+ if (typeof event.content !== "string")
+ return false;
+ if (typeof event.created_at !== "number")
+ return false;
+ if (typeof event.pubkey !== "string")
+ return false;
+ if (!event.pubkey.match(/^[a-f0-9]{64}$/))
+ return false;
+ if (!Array.isArray(event.tags))
+ return false;
+ for (let i = 0; i < event.tags.length; i++) {
+ let tag = event.tags[i];
+ if (!Array.isArray(tag))
+ return false;
+ for (let j = 0; j < tag.length; j++) {
+ if (typeof tag[j] === "object")
+ return false;
+ }
+ }
+ return true;
+ }
+ function verifySignature(event) {
+ return schnorr.verifySync(
+ event.sig,
+ getEventHash(event),
+ event.pubkey
+ );
+ }
+ function signEvent(event, key) {
+ return utils$1.bytesToHex(
+ schnorr.signSync(getEventHash(event), key)
+ );
+ }
+
+ // filter.ts
+ function matchFilter(filter, event) {
+ if (filter.ids && filter.ids.indexOf(event.id) === -1)
+ return false;
+ if (filter.kinds && filter.kinds.indexOf(event.kind) === -1)
+ return false;
+ if (filter.authors && filter.authors.indexOf(event.pubkey) === -1)
+ return false;
+ for (let f in filter) {
+ if (f[0] === "#") {
+ let tagName = f.slice(1);
+ let values = filter[`#${tagName}`];
+ if (values && !event.tags.find(
+ ([t, v]) => t === f.slice(1) && values.indexOf(v) !== -1
+ ))
+ return false;
+ }
+ }
+ if (filter.since && event.created_at < filter.since)
+ return false;
+ if (filter.until && event.created_at >= filter.until)
+ return false;
+ return true;
+ }
+ function matchFilters(filters, event) {
+ for (let i = 0; i < filters.length; i++) {
+ if (matchFilter(filters[i], event))
+ return true;
+ }
+ return false;
+ }
+
+ // fakejson.ts
+ var fakejson_exports = {};
+ __export(fakejson_exports, {
+ getHex64: () => getHex64,
+ getInt: () => getInt,
+ getSubscriptionId: () => getSubscriptionId,
+ matchEventId: () => matchEventId,
+ matchEventKind: () => matchEventKind,
+ matchEventPubkey: () => matchEventPubkey
+ });
+ function getHex64(json, field) {
+ let len = field.length + 3;
+ let idx = json.indexOf(`"${field}":`) + len;
+ let s = json.slice(idx).indexOf(`"`) + idx + 1;
+ return json.slice(s, s + 64);
+ }
+ function getInt(json, field) {
+ let len = field.length;
+ let idx = json.indexOf(`"${field}":`) + len + 3;
+ let sliced = json.slice(idx);
+ let end = Math.min(sliced.indexOf(","), sliced.indexOf("}"));
+ return parseInt(sliced.slice(0, end), 10);
+ }
+ function getSubscriptionId(json) {
+ let idx = json.slice(0, 22).indexOf(`"EVENT"`);
+ if (idx === -1)
+ return null;
+ let pstart = json.slice(idx + 7 + 1).indexOf(`"`);
+ if (pstart === -1)
+ return null;
+ let start = idx + 7 + 1 + pstart;
+ let pend = json.slice(start + 1, 80).indexOf(`"`);
+ if (pend === -1)
+ return null;
+ let end = start + 1 + pend;
+ return json.slice(start + 1, end);
+ }
+ function matchEventId(json, id) {
+ return id === getHex64(json, "id");
+ }
+ function matchEventPubkey(json, pubkey) {
+ return pubkey === getHex64(json, "pubkey");
+ }
+ function matchEventKind(json, kind) {
+ return kind === getInt(json, "kind");
+ }
+
+ // relay.ts
+ function relayInit(url) {
+ var ws;
+ var resolveClose;
+ var setOpen;
+ var untilOpen = new Promise((resolve) => {
+ setOpen = resolve;
+ });
+ var openSubs = {};
+ var listeners = {
+ connect: [],
+ disconnect: [],
+ error: [],
+ notice: []
+ };
+ var subListeners = {};
+ var pubListeners = {};
+ async function connectRelay() {
+ return new Promise((resolve, reject) => {
+ ws = new WebSocket(url);
+ ws.onopen = () => {
+ listeners.connect.forEach((cb) => cb());
+ setOpen();
+ resolve();
+ };
+ ws.onerror = () => {
+ listeners.error.forEach((cb) => cb());
+ reject();
+ };
+ ws.onclose = async () => {
+ listeners.disconnect.forEach((cb) => cb());
+ resolveClose && resolveClose();
+ };
+ let incomingMessageQueue = [];
+ let handleNextInterval;
+ ws.onmessage = (e) => {
+ incomingMessageQueue.push(e.data);
+ if (!handleNextInterval) {
+ handleNextInterval = setInterval(handleNext, 0);
+ }
+ };
+ function handleNext() {
+ if (incomingMessageQueue.length === 0) {
+ clearInterval(handleNextInterval);
+ handleNextInterval = null;
+ return;
+ }
+ var json = incomingMessageQueue.shift();
+ if (!json)
+ return;
+ let subid = getSubscriptionId(json);
+ if (subid) {
+ let { alreadyHaveEvent } = openSubs[subid];
+ if (alreadyHaveEvent && alreadyHaveEvent(getHex64(json, "id"))) {
+ return;
+ }
+ }
+ try {
+ let data = JSON.parse(json);
+ switch (data[0]) {
+ case "EVENT":
+ let id = data[1];
+ let event = data[2];
+ if (validateEvent(event) && openSubs[id] && (openSubs[id].skipVerification || verifySignature(event)) && matchFilters(openSubs[id].filters, event)) {
+ openSubs[id];
+ (subListeners[id]?.event || []).forEach((cb) => cb(event));
+ }
+ return;
+ case "EOSE": {
+ let id2 = data[1];
+ (subListeners[id2]?.eose || []).forEach((cb) => cb());
+ return;
+ }
+ case "OK": {
+ let id2 = data[1];
+ let ok = data[2];
+ let reason = data[3] || "";
+ if (ok)
+ pubListeners[id2]?.ok.forEach((cb) => cb());
+ else
+ pubListeners[id2]?.failed.forEach((cb) => cb(reason));
+ return;
+ }
+ case "NOTICE":
+ let notice = data[1];
+ listeners.notice.forEach((cb) => cb(notice));
+ return;
+ }
+ } catch (err) {
+ return;
+ }
+ }
+ });
+ }
+ async function connect() {
+ if (ws?.readyState && ws.readyState === 1)
+ return;
+ await connectRelay();
+ }
+ async function trySend(params) {
+ let msg = JSON.stringify(params);
+ await untilOpen;
+ try {
+ ws.send(msg);
+ } catch (err) {
+ console.log(err);
+ }
+ }
+ const sub = (filters, {
+ skipVerification = false,
+ alreadyHaveEvent = null,
+ id = Math.random().toString().slice(2)
+ } = {}) => {
+ let subid = id;
+ openSubs[subid] = {
+ id: subid,
+ filters,
+ skipVerification,
+ alreadyHaveEvent
+ };
+ trySend(["REQ", subid, ...filters]);
+ return {
+ sub: (newFilters, newOpts = {}) => sub(newFilters || filters, {
+ skipVerification: newOpts.skipVerification || skipVerification,
+ alreadyHaveEvent: newOpts.alreadyHaveEvent || alreadyHaveEvent,
+ id: subid
+ }),
+ unsub: () => {
+ delete openSubs[subid];
+ delete subListeners[subid];
+ trySend(["CLOSE", subid]);
+ },
+ on: (type, cb) => {
+ subListeners[subid] = subListeners[subid] || {
+ event: [],
+ eose: []
+ };
+ subListeners[subid][type].push(cb);
+ },
+ off: (type, cb) => {
+ let listeners2 = subListeners[subid];
+ let idx = listeners2[type].indexOf(cb);
+ if (idx >= 0)
+ listeners2[type].splice(idx, 1);
+ }
+ };
+ };
+ return {
+ url,
+ sub,
+ on: (type, cb) => {
+ listeners[type].push(cb);
+ if (type === "connect" && ws?.readyState === 1) {
+ cb();
+ }
+ },
+ off: (type, cb) => {
+ let index = listeners[type].indexOf(cb);
+ if (index !== -1)
+ listeners[type].splice(index, 1);
+ },
+ list: (filters, opts) => new Promise((resolve) => {
+ let s = sub(filters, opts);
+ let events = [];
+ let timeout = setTimeout(() => {
+ s.unsub();
+ resolve(events);
+ }, 1500);
+ s.on("eose", () => {
+ s.unsub();
+ clearTimeout(timeout);
+ resolve(events);
+ });
+ s.on("event", (event) => {
+ events.push(event);
+ });
+ }),
+ get: (filter, opts) => new Promise((resolve) => {
+ let s = sub([filter], opts);
+ let timeout = setTimeout(() => {
+ s.unsub();
+ resolve(null);
+ }, 1500);
+ s.on("event", (event) => {
+ s.unsub();
+ clearTimeout(timeout);
+ resolve(event);
+ });
+ }),
+ publish(event) {
+ if (!event.id)
+ throw new Error(`event ${event} has no id`);
+ let id = event.id;
+ var sent = false;
+ var mustMonitor = false;
+ trySend(["EVENT", event]).then(() => {
+ sent = true;
+ if (mustMonitor) {
+ startMonitoring();
+ mustMonitor = false;
+ }
+ }).catch(() => {
+ });
+ const startMonitoring = () => {
+ let monitor = sub([{ ids: [id] }], {
+ id: `monitor-${id.slice(0, 5)}`
+ });
+ let willUnsub = setTimeout(() => {
+ (pubListeners[id]?.failed || []).forEach(
+ (cb) => cb("event not seen after 5 seconds")
+ );
+ monitor.unsub();
+ }, 5e3);
+ monitor.on("event", () => {
+ clearTimeout(willUnsub);
+ (pubListeners[id]?.seen || []).forEach((cb) => cb());
+ });
+ };
+ return {
+ on: (type, cb) => {
+ pubListeners[id] = pubListeners[id] || {
+ ok: [],
+ seen: [],
+ failed: []
+ };
+ pubListeners[id][type].push(cb);
+ if (type === "seen") {
+ if (sent)
+ startMonitoring();
+ else
+ mustMonitor = true;
+ }
+ },
+ off: (type, cb) => {
+ let listeners2 = pubListeners[id];
+ if (!listeners2)
+ return;
+ let idx = listeners2[type].indexOf(cb);
+ if (idx >= 0)
+ listeners2[type].splice(idx, 1);
+ }
+ };
+ },
+ connect,
+ close() {
+ ws.close();
+ return new Promise((resolve) => {
+ resolveClose = resolve;
+ });
+ },
+ get status() {
+ return ws?.readyState ?? 3;
+ }
+ };
+ }
+
+ // nip04.ts
+ var nip04_exports = {};
+ __export(nip04_exports, {
+ decrypt: () => decrypt,
+ encrypt: () => encrypt
+ });
+ async function encrypt(privkey, pubkey, text) {
+ const key = getSharedSecret(privkey, "02" + pubkey);
+ const normalizedKey = getNormalizedX(key);
+ let iv = Uint8Array.from(randomBytes(16));
+ let plaintext = utf8Encoder.encode(text);
+ let cryptoKey = await crypto.subtle.importKey(
+ "raw",
+ normalizedKey,
+ { name: "AES-CBC" },
+ false,
+ ["encrypt"]
+ );
+ let ciphertext = await crypto.subtle.encrypt(
+ { name: "AES-CBC", iv },
+ cryptoKey,
+ plaintext
+ );
+ let ctb64 = base64.encode(new Uint8Array(ciphertext));
+ let ivb64 = base64.encode(new Uint8Array(iv.buffer));
+ return `${ctb64}?iv=${ivb64}`;
+ }
+ async function decrypt(privkey, pubkey, data) {
+ let [ctb64, ivb64] = data.split("?iv=");
+ let key = getSharedSecret(privkey, "02" + pubkey);
+ let normalizedKey = getNormalizedX(key);
+ let cryptoKey = await crypto.subtle.importKey(
+ "raw",
+ normalizedKey,
+ { name: "AES-CBC" },
+ false,
+ ["decrypt"]
+ );
+ let ciphertext = base64.decode(ctb64);
+ let iv = base64.decode(ivb64);
+ let plaintext = await crypto.subtle.decrypt(
+ { name: "AES-CBC", iv },
+ cryptoKey,
+ ciphertext
+ );
+ let text = utf8Decoder.decode(plaintext);
+ return text;
+ }
+ function getNormalizedX(key) {
+ return key.slice(1, 33);
+ }
+
+ // nip05.ts
+ var nip05_exports = {};
+ __export(nip05_exports, {
+ queryProfile: () => queryProfile,
+ searchDomain: () => searchDomain,
+ useFetchImplementation: () => useFetchImplementation
+ });
+ var _fetch;
+ try {
+ _fetch = fetch;
+ } catch {
+ }
+ function useFetchImplementation(fetchImplementation) {
+ _fetch = fetchImplementation;
+ }
+ async function searchDomain(domain, query = "") {
+ try {
+ let res = await (await _fetch(`https://${domain}/.well-known/nostr.json?name=${query}`)).json();
+ return res.names;
+ } catch (_) {
+ return {};
+ }
+ }
+ async function queryProfile(fullname) {
+ let [name, domain] = fullname.split("@");
+ if (!domain) {
+ domain = name;
+ name = "_";
+ }
+ if (!name.match(/^[A-Za-z0-9-_]+$/))
+ return null;
+ let res = await (await _fetch(`https://${domain}/.well-known/nostr.json?name=${name}`)).json();
+ if (!res?.names?.[name])
+ return null;
+ let pubkey = res.names[name];
+ let relays = res.relays?.[pubkey] || [];
+ return {
+ pubkey,
+ relays
+ };
+ }
+
+ // nip06.ts
+ var nip06_exports = {};
+ __export(nip06_exports, {
+ generateSeedWords: () => generateSeedWords,
+ privateKeyFromSeedWords: () => privateKeyFromSeedWords,
+ validateWords: () => validateWords
+ });
+ function privateKeyFromSeedWords(mnemonic, passphrase) {
+ let root = HDKey.fromMasterSeed(mnemonicToSeedSync_1(mnemonic, passphrase));
+ let privateKey = root.derive(`m/44'/1237'/0'/0/0`).privateKey;
+ if (!privateKey)
+ throw new Error("could not derive private key");
+ return utils$1.bytesToHex(privateKey);
+ }
+ function generateSeedWords() {
+ return generateMnemonic_1(wordlist);
+ }
+ function validateWords(words) {
+ return validateMnemonic_1(words, wordlist);
+ }
+
+ // nip19.ts
+ var nip19_exports = {};
+ __export(nip19_exports, {
+ decode: () => decode,
+ neventEncode: () => neventEncode,
+ noteEncode: () => noteEncode,
+ nprofileEncode: () => nprofileEncode,
+ npubEncode: () => npubEncode,
+ nsecEncode: () => nsecEncode
+ });
+ var Bech32MaxSize = 5e3;
+ function decode(nip19) {
+ let { prefix, words } = bech32.decode(nip19, Bech32MaxSize);
+ let data = new Uint8Array(bech32.fromWords(words));
+ if (prefix === "nprofile") {
+ let tlv = parseTLV(data);
+ if (!tlv[0]?.[0])
+ throw new Error("missing TLV 0 for nprofile");
+ if (tlv[0][0].length !== 32)
+ throw new Error("TLV 0 should be 32 bytes");
+ return {
+ type: "nprofile",
+ data: {
+ pubkey: utils$1.bytesToHex(tlv[0][0]),
+ relays: tlv[1].map((d) => utf8Decoder.decode(d))
+ }
+ };
+ }
+ if (prefix === "nevent") {
+ let tlv = parseTLV(data);
+ if (!tlv[0]?.[0])
+ throw new Error("missing TLV 0 for nevent");
+ if (tlv[0][0].length !== 32)
+ throw new Error("TLV 0 should be 32 bytes");
+ return {
+ type: "nevent",
+ data: {
+ id: utils$1.bytesToHex(tlv[0][0]),
+ relays: tlv[1].map((d) => utf8Decoder.decode(d))
+ }
+ };
+ }
+ if (prefix === "nsec" || prefix === "npub" || prefix === "note") {
+ return { type: prefix, data: utils$1.bytesToHex(data) };
+ }
+ throw new Error(`unknown prefix ${prefix}`);
+ }
+ function parseTLV(data) {
+ let result = {};
+ let rest = data;
+ while (rest.length > 0) {
+ let t = rest[0];
+ let l = rest[1];
+ let v = rest.slice(2, 2 + l);
+ rest = rest.slice(2 + l);
+ if (v.length < l)
+ continue;
+ result[t] = result[t] || [];
+ result[t].push(v);
+ }
+ return result;
+ }
+ function nsecEncode(hex) {
+ return encodeBytes("nsec", hex);
+ }
+ function npubEncode(hex) {
+ return encodeBytes("npub", hex);
+ }
+ function noteEncode(hex) {
+ return encodeBytes("note", hex);
+ }
+ function encodeBytes(prefix, hex) {
+ let data = utils$1.hexToBytes(hex);
+ let words = bech32.toWords(data);
+ return bech32.encode(prefix, words, Bech32MaxSize);
+ }
+ function nprofileEncode(profile) {
+ let data = encodeTLV({
+ 0: [utils$1.hexToBytes(profile.pubkey)],
+ 1: (profile.relays || []).map((url) => utf8Encoder.encode(url))
+ });
+ let words = bech32.toWords(data);
+ return bech32.encode("nprofile", words, Bech32MaxSize);
+ }
+ function neventEncode(event) {
+ let data = encodeTLV({
+ 0: [utils$1.hexToBytes(event.id)],
+ 1: (event.relays || []).map((url) => utf8Encoder.encode(url))
+ });
+ let words = bech32.toWords(data);
+ return bech32.encode("nevent", words, Bech32MaxSize);
+ }
+ function encodeTLV(tlv) {
+ let entries = [];
+ Object.entries(tlv).forEach(([t, vs]) => {
+ vs.forEach((v) => {
+ let entry = new Uint8Array(v.length + 2);
+ entry.set([parseInt(t)], 0);
+ entry.set([v.length], 1);
+ entry.set(v, 2);
+ entries.push(entry);
+ });
+ });
+ return utils$1.concatBytes(...entries);
+ }
+
+ // nip26.ts
+ var nip26_exports = {};
+ __export(nip26_exports, {
+ createDelegation: () => createDelegation,
+ getDelegator: () => getDelegator
+ });
+ function createDelegation(privateKey, parameters) {
+ let conditions = [];
+ if ((parameters.kind || -1) >= 0)
+ conditions.push(`kind=${parameters.kind}`);
+ if (parameters.until)
+ conditions.push(`created_at<${parameters.until}`);
+ if (parameters.since)
+ conditions.push(`created_at>${parameters.since}`);
+ let cond = conditions.join("&");
+ if (cond === "")
+ throw new Error("refusing to create a delegation without any conditions");
+ let sighash = sha256$2(
+ utf8Encoder.encode(`nostr:delegation:${parameters.pubkey}:${cond}`)
+ );
+ let sig = utils$1.bytesToHex(
+ schnorr.signSync(sighash, privateKey)
+ );
+ return {
+ from: getPublicKey(privateKey),
+ to: parameters.pubkey,
+ cond,
+ sig
+ };
+ }
+ function getDelegator(event) {
+ let tag = event.tags.find((tag2) => tag2[0] === "delegation" && tag2.length >= 4);
+ if (!tag)
+ return null;
+ let pubkey = tag[1];
+ let cond = tag[2];
+ let sig = tag[3];
+ let conditions = cond.split("&");
+ for (let i = 0; i < conditions.length; i++) {
+ let [key, operator, value] = conditions[i].split(/\b/);
+ if (key === "kind" && operator === "=" && event.kind === parseInt(value))
+ continue;
+ else if (key === "created_at" && operator === "<" && event.created_at < parseInt(value))
+ continue;
+ else if (key === "created_at" && operator === ">" && event.created_at > parseInt(value))
+ continue;
+ else
+ return null;
+ }
+ let sighash = sha256$2(
+ utf8Encoder.encode(`nostr:delegation:${event.pubkey}:${cond}`)
+ );
+ if (!schnorr.verifySync(sig, sighash, pubkey))
+ return null;
+ return pubkey;
+ }
+ utils$1.hmacSha256Sync = (key, ...msgs) => hmac(sha256$2, key, utils$1.concatBytes(...msgs));
+ utils$1.sha256Sync = (...msgs) => sha256$2(utils$1.concatBytes(...msgs));
+
+ const WS = WebSocket;// typeof WebSocket !== 'undefined' ? WebSocket : require('ws')
+
+ Relay$1.prototype.wait_connected = async function relay_wait_connected(data) {
+ let retry = 1000;
+ while (true) {
+ if (this.ws.readyState !== 1) {
+ await sleep(retry);
+ retry *= 1.5;
+ }
+ else {
+ return
+ }
+ }
+ };
+
+
+ function Relay$1(relay, opts={})
+ {
+ if (!(this instanceof Relay$1))
+ return new Relay$1(relay, opts)
+
+ this.url = relay;
+ this.opts = opts;
+
+ if (opts.reconnect == null)
+ opts.reconnect = true;
+
+ const me = this;
+ me.onfn = {};
+
+ init_websocket(me)
+ .catch(e => {
+ if (me.onfn.error)
+ me.onfn.error(e);
+ });
+
+ return this
+ }
+
+ function init_websocket(me) {
+ return new Promise((resolve, reject) => {
+ const ws = me.ws = new WS(me.url);
+
+ let resolved = false;
+ ws.onmessage = (m) => {
+ handle_nostr_message(me, m);
+ if (me.onfn.message)
+ me.onfn.message(m);
+ };
+ ws.onclose = (e) => {
+ if (me.onfn.close)
+ me.onfn.close(e);
+ if (me.reconnecting)
+ return reject(new Error("close during reconnect"))
+ if (!me.manualClose && me.opts.reconnect)
+ reconnect(me);
+ };
+ ws.onerror = (e) => {
+ if (me.onfn.error)
+ me.onfn.error(e);
+ if (me.reconnecting)
+ return reject(new Error("error during reconnect"))
+ if (me.opts.reconnect)
+ reconnect(me);
+ };
+ ws.onopen = (e) => {
+ if (me.onfn.open)
+ me.onfn.open(e);
+
+ if (resolved) return
+
+ resolved = true;
+ resolve(me);
+ };
+ });
+ }
+
+ function sleep(ms) {
+ return new Promise(resolve => setTimeout(resolve, ms));
+ }
+
+ async function reconnect(me)
+ {
+ let n = 100;
+ try {
+ me.reconnecting = true;
+ await init_websocket(me);
+ me.reconnecting = false;
+ } catch {
+ //console.error(`error thrown during reconnect... trying again in ${n} ms`)
+ await sleep(n);
+ n *= 1.5;
+ }
+ }
+
+ Relay$1.prototype.on = function relayOn(method, fn) {
+ this.onfn[method] = fn;
+ return this
+ };
+
+ Relay$1.prototype.close = function relayClose() {
+ if (this.ws) {
+ this.manualClose = true;
+ this.ws.close();
+ }
+ };
+
+ Relay$1.prototype.subscribe = function relay_subscribe(sub_id, filters) {
+ if (Array.isArray(filters))
+ this.send(["REQ", sub_id, ...filters]);
+ else
+ this.send(["REQ", sub_id, filters]);
+ };
+
+ Relay$1.prototype.unsubscribe = function relay_unsubscribe(sub_id) {
+ this.send(["CLOSE", sub_id]);
+ };
+
+ Relay$1.prototype.send = async function relay_send(data) {
+ await this.wait_connected();
+ this.ws.send(JSON.stringify(data));
+ };
+
+ function handle_nostr_message(relay, msg)
+ {
+ let data;
+ try {
+ data = JSON.parse(msg.data);
+ } catch (e) {
+ console.error("handle_nostr_message", e);
+ return
+ }
+ if (data.length >= 2) {
+ switch (data[0]) {
+ case "EVENT":
+ if (data.length < 3)
+ return
+ return relay.onfn.event && relay.onfn.event(data[1], data[2])
+ case "EOSE":
+ return relay.onfn.eose && relay.onfn.eose(data[1])
+ case "NOTICE":
+ return relay.onfn.notice && relay.onfn.notice(...data.slice(1))
+ case "OK":
+ return relay.onfn.ok && relay.onfn.ok(...data.slice(1))
+ }
+ }
+ }
+
+ var relay = Relay$1;
+
+ const Relay = relay;
+
+ function RelayPool(relays, opts)
+ {
+ if (!(this instanceof RelayPool))
+ return new RelayPool(relays, opts)
+
+ this.onfn = {};
+ this.relays = [];
+ this.opts = opts;
+
+ for (const relay of relays) {
+ this.add(relay);
+ }
+
+ return this
+ }
+
+ RelayPool.prototype.close = function relayPoolClose() {
+ for (const relay of this.relays) {
+ relay.close();
+ }
+ };
+
+ RelayPool.prototype.on = function relayPoolOn(method, fn) {
+ for (const relay of this.relays) {
+ this.onfn[method] = fn;
+ relay.onfn[method] = fn.bind(null, relay);
+ }
+ return this
+ };
+
+ RelayPool.prototype.has = function relayPoolHas(relayUrl) {
+ for (const relay of this.relays) {
+ if (relay.url === relayUrl)
+ return true
+ }
+
+ return false
+ };
+
+ RelayPool.prototype.send = function relayPoolSend(payload, relay_ids) {
+ const relays = relay_ids ? this.find_relays(relay_ids) : this.relays;
+ for (const relay of relays) {
+ relay.send(payload);
+ }
+ };
+
+ RelayPool.prototype.setupHandlers = function relayPoolSetupHandlers()
+ {
+ // setup its message handlers with the ones we have already
+ const keys = Object.keys(this.onfn);
+ for (const handler of keys) {
+ for (const relay of this.relays) {
+ relay.onfn[handler] = this.onfn[handler].bind(null, relay);
+ }
+ }
+ };
+
+ RelayPool.prototype.remove = function relayPoolRemove(url) {
+ let i = 0;
+
+ for (const relay of this.relays) {
+ if (relay.url === url) {
+ relay.ws && relay.ws.close();
+ this.relays = this.replays.splice(i, 1);
+ return true
+ }
+
+ i += 1;
+ }
+
+ return false
+ };
+
+ RelayPool.prototype.subscribe = function relayPoolSubscribe(sub_id, filters, relay_ids) {
+ const relays = relay_ids ? this.find_relays(relay_ids) : this.relays;
+ for (const relay of relays) {
+ relay.subscribe(sub_id, filters);
+ }
+ };
+
+ RelayPool.prototype.unsubscribe = function relayPoolUnsubscibe(sub_id, relay_ids) {
+ const relays = relay_ids ? this.find_relays(relay_ids) : this.relays;
+ for (const relay of relays) {
+ relay.unsubscribe(sub_id);
+ }
+ };
+
+
+ RelayPool.prototype.add = function relayPoolAdd(relay) {
+ if (relay instanceof Relay) {
+ if (this.has(relay.url))
+ return false
+
+ this.relays.push(relay);
+ this.setupHandlers();
+ return true
+ }
+
+ if (this.has(relay))
+ return false
+
+ const r = Relay(relay, this.opts);
+ this.relays.push(r);
+ this.setupHandlers();
+ return true
+ };
+
+ RelayPool.prototype.find_relays = function relayPoolFindRelays(relay_ids) {
+ if (relay_ids instanceof Relay)
+ return [relay_ids]
+
+ if (relay_ids.length === 0)
+ return []
+
+ if (!relay_ids[0])
+ throw new Error("what!?")
+
+ if (relay_ids[0] instanceof Relay)
+ return relay_ids
+
+ return this.relays.reduce((acc, relay) => {
+ if (relay_ids.some((rid) => relay.url === rid))
+ acc.push(relay);
+ return acc
+ }, [])
+ };
+
+ var relayPool = RelayPool;
+
+ var eventsExports = {};
+ var events = {
+ get exports(){ return eventsExports; },
+ set exports(v){ eventsExports = v; },
+ };
+
+ var R = typeof Reflect === 'object' ? Reflect : null;
+ var ReflectApply = R && typeof R.apply === 'function'
+ ? R.apply
+ : function ReflectApply(target, receiver, args) {
+ return Function.prototype.apply.call(target, receiver, args);
+ };
+
+ var ReflectOwnKeys;
+ if (R && typeof R.ownKeys === 'function') {
+ ReflectOwnKeys = R.ownKeys;
+ } else if (Object.getOwnPropertySymbols) {
+ ReflectOwnKeys = function ReflectOwnKeys(target) {
+ return Object.getOwnPropertyNames(target)
+ .concat(Object.getOwnPropertySymbols(target));
+ };
+ } else {
+ ReflectOwnKeys = function ReflectOwnKeys(target) {
+ return Object.getOwnPropertyNames(target);
+ };
+ }
+
+ function ProcessEmitWarning(warning) {
+ if (console && console.warn) console.warn(warning);
+ }
+
+ var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {
+ return value !== value;
+ };
+
+ function EventEmitter() {
+ EventEmitter.init.call(this);
+ }
+ events.exports = EventEmitter;
+ eventsExports.once = once;
+
+ // Backwards-compat with node 0.10.x
+ EventEmitter.EventEmitter = EventEmitter;
+
+ EventEmitter.prototype._events = undefined;
+ EventEmitter.prototype._eventsCount = 0;
+ EventEmitter.prototype._maxListeners = undefined;
+
+ // By default EventEmitters will print a warning if more than 10 listeners are
+ // added to it. This is a useful default which helps finding memory leaks.
+ var defaultMaxListeners = 10;
+
+ function checkListener(listener) {
+ if (typeof listener !== 'function') {
+ throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
+ }
+ }
+
+ Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
+ enumerable: true,
+ get: function() {
+ return defaultMaxListeners;
+ },
+ set: function(arg) {
+ if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {
+ throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.');
+ }
+ defaultMaxListeners = arg;
+ }
+ });
+
+ EventEmitter.init = function() {
+
+ if (this._events === undefined ||
+ this._events === Object.getPrototypeOf(this)._events) {
+ this._events = Object.create(null);
+ this._eventsCount = 0;
+ }
+
+ this._maxListeners = this._maxListeners || undefined;
+ };
+
+ // Obviously not all Emitters should be limited to 10. This function allows
+ // that to be increased. Set to zero for unlimited.
+ EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
+ if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {
+ throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.');
+ }
+ this._maxListeners = n;
+ return this;
+ };
+
+ function _getMaxListeners(that) {
+ if (that._maxListeners === undefined)
+ return EventEmitter.defaultMaxListeners;
+ return that._maxListeners;
+ }
+
+ EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
+ return _getMaxListeners(this);
+ };
+
+ EventEmitter.prototype.emit = function emit(type) {
+ var args = [];
+ for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);
+ var doError = (type === 'error');
+
+ var events = this._events;
+ if (events !== undefined)
+ doError = (doError && events.error === undefined);
+ else if (!doError)
+ return false;
+
+ // If there is no 'error' event listener then throw.
+ if (doError) {
+ var er;
+ if (args.length > 0)
+ er = args[0];
+ if (er instanceof Error) {
+ // Note: The comments on the `throw` lines are intentional, they show
+ // up in Node's output if this results in an unhandled exception.
+ throw er; // Unhandled 'error' event
+ }
+ // At least give some kind of context to the user
+ var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));
+ err.context = er;
+ throw err; // Unhandled 'error' event
+ }
+
+ var handler = events[type];
+
+ if (handler === undefined)
+ return false;
+
+ if (typeof handler === 'function') {
+ ReflectApply(handler, this, args);
+ } else {
+ var len = handler.length;
+ var listeners = arrayClone(handler, len);
+ for (var i = 0; i < len; ++i)
+ ReflectApply(listeners[i], this, args);
+ }
+
+ return true;
+ };
+
+ function _addListener(target, type, listener, prepend) {
+ var m;
+ var events;
+ var existing;
+
+ checkListener(listener);
+
+ events = target._events;
+ if (events === undefined) {
+ events = target._events = Object.create(null);
+ target._eventsCount = 0;
+ } else {
+ // To avoid recursion in the case that type === "newListener"! Before
+ // adding it to the listeners, first emit "newListener".
+ if (events.newListener !== undefined) {
+ target.emit('newListener', type,
+ listener.listener ? listener.listener : listener);
+
+ // Re-assign `events` because a newListener handler could have caused the
+ // this._events to be assigned to a new object
+ events = target._events;
+ }
+ existing = events[type];
+ }
+
+ if (existing === undefined) {
+ // Optimize the case of one listener. Don't need the extra array object.
+ existing = events[type] = listener;
+ ++target._eventsCount;
+ } else {
+ if (typeof existing === 'function') {
+ // Adding the second element, need to change to array.
+ existing = events[type] =
+ prepend ? [listener, existing] : [existing, listener];
+ // If we've already got an array, just append.
+ } else if (prepend) {
+ existing.unshift(listener);
+ } else {
+ existing.push(listener);
+ }
+
+ // Check for listener leak
+ m = _getMaxListeners(target);
+ if (m > 0 && existing.length > m && !existing.warned) {
+ existing.warned = true;
+ // No error code for this since it is a Warning
+ // eslint-disable-next-line no-restricted-syntax
+ var w = new Error('Possible EventEmitter memory leak detected. ' +
+ existing.length + ' ' + String(type) + ' listeners ' +
+ 'added. Use emitter.setMaxListeners() to ' +
+ 'increase limit');
+ w.name = 'MaxListenersExceededWarning';
+ w.emitter = target;
+ w.type = type;
+ w.count = existing.length;
+ ProcessEmitWarning(w);
+ }
+ }
+
+ return target;
+ }
+
+ EventEmitter.prototype.addListener = function addListener(type, listener) {
+ return _addListener(this, type, listener, false);
+ };
+
+ EventEmitter.prototype.on = EventEmitter.prototype.addListener;
+
+ EventEmitter.prototype.prependListener =
+ function prependListener(type, listener) {
+ return _addListener(this, type, listener, true);
+ };
+
+ function onceWrapper() {
+ if (!this.fired) {
+ this.target.removeListener(this.type, this.wrapFn);
+ this.fired = true;
+ if (arguments.length === 0)
+ return this.listener.call(this.target);
+ return this.listener.apply(this.target, arguments);
+ }
+ }
+
+ function _onceWrap(target, type, listener) {
+ var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
+ var wrapped = onceWrapper.bind(state);
+ wrapped.listener = listener;
+ state.wrapFn = wrapped;
+ return wrapped;
+ }
+
+ EventEmitter.prototype.once = function once(type, listener) {
+ checkListener(listener);
+ this.on(type, _onceWrap(this, type, listener));
+ return this;
+ };
+
+ EventEmitter.prototype.prependOnceListener =
+ function prependOnceListener(type, listener) {
+ checkListener(listener);
+ this.prependListener(type, _onceWrap(this, type, listener));
+ return this;
+ };
+
+ // Emits a 'removeListener' event if and only if the listener was removed.
+ EventEmitter.prototype.removeListener =
+ function removeListener(type, listener) {
+ var list, events, position, i, originalListener;
+
+ checkListener(listener);
+
+ events = this._events;
+ if (events === undefined)
+ return this;
+
+ list = events[type];
+ if (list === undefined)
+ return this;
+
+ if (list === listener || list.listener === listener) {
+ if (--this._eventsCount === 0)
+ this._events = Object.create(null);
+ else {
+ delete events[type];
+ if (events.removeListener)
+ this.emit('removeListener', type, list.listener || listener);
+ }
+ } else if (typeof list !== 'function') {
+ position = -1;
+
+ for (i = list.length - 1; i >= 0; i--) {
+ if (list[i] === listener || list[i].listener === listener) {
+ originalListener = list[i].listener;
+ position = i;
+ break;
+ }
+ }
+
+ if (position < 0)
+ return this;
+
+ if (position === 0)
+ list.shift();
+ else {
+ spliceOne(list, position);
+ }
+
+ if (list.length === 1)
+ events[type] = list[0];
+
+ if (events.removeListener !== undefined)
+ this.emit('removeListener', type, originalListener || listener);
+ }
+
+ return this;
+ };
+
+ EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
+
+ EventEmitter.prototype.removeAllListeners =
+ function removeAllListeners(type) {
+ var listeners, events, i;
+
+ events = this._events;
+ if (events === undefined)
+ return this;
+
+ // not listening for removeListener, no need to emit
+ if (events.removeListener === undefined) {
+ if (arguments.length === 0) {
+ this._events = Object.create(null);
+ this._eventsCount = 0;
+ } else if (events[type] !== undefined) {
+ if (--this._eventsCount === 0)
+ this._events = Object.create(null);
+ else
+ delete events[type];
+ }
+ return this;
+ }
+
+ // emit removeListener for all listeners on all events
+ if (arguments.length === 0) {
+ var keys = Object.keys(events);
+ var key;
+ for (i = 0; i < keys.length; ++i) {
+ key = keys[i];
+ if (key === 'removeListener') continue;
+ this.removeAllListeners(key);
+ }
+ this.removeAllListeners('removeListener');
+ this._events = Object.create(null);
+ this._eventsCount = 0;
+ return this;
+ }
+
+ listeners = events[type];
+
+ if (typeof listeners === 'function') {
+ this.removeListener(type, listeners);
+ } else if (listeners !== undefined) {
+ // LIFO order
+ for (i = listeners.length - 1; i >= 0; i--) {
+ this.removeListener(type, listeners[i]);
+ }
+ }
+
+ return this;
+ };
+
+ function _listeners(target, type, unwrap) {
+ var events = target._events;
+
+ if (events === undefined)
+ return [];
+
+ var evlistener = events[type];
+ if (evlistener === undefined)
+ return [];
+
+ if (typeof evlistener === 'function')
+ return unwrap ? [evlistener.listener || evlistener] : [evlistener];
+
+ return unwrap ?
+ unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
+ }
+
+ EventEmitter.prototype.listeners = function listeners(type) {
+ return _listeners(this, type, true);
+ };
+
+ EventEmitter.prototype.rawListeners = function rawListeners(type) {
+ return _listeners(this, type, false);
+ };
+
+ EventEmitter.listenerCount = function(emitter, type) {
+ if (typeof emitter.listenerCount === 'function') {
+ return emitter.listenerCount(type);
+ } else {
+ return listenerCount.call(emitter, type);
+ }
+ };
+
+ EventEmitter.prototype.listenerCount = listenerCount;
+ function listenerCount(type) {
+ var events = this._events;
+
+ if (events !== undefined) {
+ var evlistener = events[type];
+
+ if (typeof evlistener === 'function') {
+ return 1;
+ } else if (evlistener !== undefined) {
+ return evlistener.length;
+ }
+ }
+
+ return 0;
+ }
+
+ EventEmitter.prototype.eventNames = function eventNames() {
+ return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
+ };
+
+ function arrayClone(arr, n) {
+ var copy = new Array(n);
+ for (var i = 0; i < n; ++i)
+ copy[i] = arr[i];
+ return copy;
+ }
+
+ function spliceOne(list, index) {
+ for (; index + 1 < list.length; index++)
+ list[index] = list[index + 1];
+ list.pop();
+ }
+
+ function unwrapListeners(arr) {
+ var ret = new Array(arr.length);
+ for (var i = 0; i < ret.length; ++i) {
+ ret[i] = arr[i].listener || arr[i];
+ }
+ return ret;
+ }
+
+ function once(emitter, name) {
+ return new Promise(function (resolve, reject) {
+ function errorListener(err) {
+ emitter.removeListener(name, resolver);
+ reject(err);
+ }
+
+ function resolver() {
+ if (typeof emitter.removeListener === 'function') {
+ emitter.removeListener('error', errorListener);
+ }
+ resolve([].slice.call(arguments));
+ }
+ eventTargetAgnosticAddListener(emitter, name, resolver, { once: true });
+ if (name !== 'error') {
+ addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true });
+ }
+ });
+ }
+
+ function addErrorHandlerIfEventEmitter(emitter, handler, flags) {
+ if (typeof emitter.on === 'function') {
+ eventTargetAgnosticAddListener(emitter, 'error', handler, flags);
+ }
+ }
+
+ function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
+ if (typeof emitter.on === 'function') {
+ if (flags.once) {
+ emitter.once(name, listener);
+ } else {
+ emitter.on(name, listener);
+ }
+ } else if (typeof emitter.addEventListener === 'function') {
+ // EventTarget does not have `error` event semantics like Node
+ // EventEmitters, we do not listen for `error` events here.
+ emitter.addEventListener(name, function wrapListener(arg) {
+ // IE does not have builtin `{ once: true }` support so we
+ // have to do it manually.
+ if (flags.once) {
+ emitter.removeEventListener(name, wrapListener);
+ }
+ listener(arg);
+ });
+ } else {
+ throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter);
+ }
+ }
+
+ // Unique ID creation requires a high quality random # generator. In the browser we therefore
+ // require the crypto API and do not support built-in fallback to lower quality random number
+ // generators (like Math.random()).
+ let getRandomValues;
+ const rnds8 = new Uint8Array(16);
+ function rng() {
+ // lazy load so that environments that need to polyfill have a chance to do so
+ if (!getRandomValues) {
+ // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation.
+ getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
+
+ if (!getRandomValues) {
+ throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
+ }
+ }
+
+ return getRandomValues(rnds8);
+ }
+
+ /**
+ * Convert array of 16 byte values to UUID string format of the form:
+ * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
+ */
+
+ const byteToHex = [];
+
+ for (let i = 0; i < 256; ++i) {
+ byteToHex.push((i + 0x100).toString(16).slice(1));
+ }
+
+ function unsafeStringify(arr, offset = 0) {
+ // Note: Be careful editing this code! It's been tuned for performance
+ // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
+ return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
+ }
+
+ const randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto);
+ var native = {
+ randomUUID
+ };
+
+ function v4(options, buf, offset) {
+ if (native.randomUUID && !buf && !options) {
+ return native.randomUUID();
+ }
+
+ options = options || {};
+ const rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
+
+ rnds[6] = rnds[6] & 0x0f | 0x40;
+ rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
+
+ if (buf) {
+ offset = offset || 0;
+
+ for (let i = 0; i < 16; ++i) {
+ buf[offset + i] = rnds[i];
+ }
+
+ return buf;
+ }
+
+ return unsafeStringify(rnds);
+ }
+
+ var browserExports = {};
+ var browser = {
+ get exports(){ return browserExports; },
+ set exports(v){ browserExports = v; },
+ };
+
+ /**
+ * Helpers.
+ */
+
+ var ms;
+ var hasRequiredMs;
+
+ function requireMs () {
+ if (hasRequiredMs) return ms;
+ hasRequiredMs = 1;
+ var s = 1000;
+ var m = s * 60;
+ var h = m * 60;
+ var d = h * 24;
+ var w = d * 7;
+ var y = d * 365.25;
+
+ /**
+ * Parse or format the given `val`.
+ *
+ * Options:
+ *
+ * - `long` verbose formatting [false]
+ *
+ * @param {String|Number} val
+ * @param {Object} [options]
+ * @throws {Error} throw an error if val is not a non-empty string or a number
+ * @return {String|Number}
+ * @api public
+ */
+
+ ms = function(val, options) {
+ options = options || {};
+ var type = typeof val;
+ if (type === 'string' && val.length > 0) {
+ return parse(val);
+ } else if (type === 'number' && isFinite(val)) {
+ return options.long ? fmtLong(val) : fmtShort(val);
+ }
+ throw new Error(
+ 'val is not a non-empty string or a valid number. val=' +
+ JSON.stringify(val)
+ );
+ };
+
+ /**
+ * Parse the given `str` and return milliseconds.
+ *
+ * @param {String} str
+ * @return {Number}
+ * @api private
+ */
+
+ function parse(str) {
+ str = String(str);
+ if (str.length > 100) {
+ return;
+ }
+ var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
+ str
+ );
+ if (!match) {
+ return;
+ }
+ var n = parseFloat(match[1]);
+ var type = (match[2] || 'ms').toLowerCase();
+ switch (type) {
+ case 'years':
+ case 'year':
+ case 'yrs':
+ case 'yr':
+ case 'y':
+ return n * y;
+ case 'weeks':
+ case 'week':
+ case 'w':
+ return n * w;
+ case 'days':
+ case 'day':
+ case 'd':
+ return n * d;
+ case 'hours':
+ case 'hour':
+ case 'hrs':
+ case 'hr':
+ case 'h':
+ return n * h;
+ case 'minutes':
+ case 'minute':
+ case 'mins':
+ case 'min':
+ case 'm':
+ return n * m;
+ case 'seconds':
+ case 'second':
+ case 'secs':
+ case 'sec':
+ case 's':
+ return n * s;
+ case 'milliseconds':
+ case 'millisecond':
+ case 'msecs':
+ case 'msec':
+ case 'ms':
+ return n;
+ default:
+ return undefined;
+ }
+ }
+
+ /**
+ * Short format for `ms`.
+ *
+ * @param {Number} ms
+ * @return {String}
+ * @api private
+ */
+
+ function fmtShort(ms) {
+ var msAbs = Math.abs(ms);
+ if (msAbs >= d) {
+ return Math.round(ms / d) + 'd';
+ }
+ if (msAbs >= h) {
+ return Math.round(ms / h) + 'h';
+ }
+ if (msAbs >= m) {
+ return Math.round(ms / m) + 'm';
+ }
+ if (msAbs >= s) {
+ return Math.round(ms / s) + 's';
+ }
+ return ms + 'ms';
+ }
+
+ /**
+ * Long format for `ms`.
+ *
+ * @param {Number} ms
+ * @return {String}
+ * @api private
+ */
+
+ function fmtLong(ms) {
+ var msAbs = Math.abs(ms);
+ if (msAbs >= d) {
+ return plural(ms, msAbs, d, 'day');
+ }
+ if (msAbs >= h) {
+ return plural(ms, msAbs, h, 'hour');
+ }
+ if (msAbs >= m) {
+ return plural(ms, msAbs, m, 'minute');
+ }
+ if (msAbs >= s) {
+ return plural(ms, msAbs, s, 'second');
+ }
+ return ms + ' ms';
+ }
+
+ /**
+ * Pluralization helper.
+ */
+
+ function plural(ms, msAbs, n, name) {
+ var isPlural = msAbs >= n * 1.5;
+ return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
+ }
+ return ms;
+ }
+
+ /**
+ * This is the common logic for both the Node.js and web browser
+ * implementations of `debug()`.
+ */
+
+ function setup(env) {
+ createDebug.debug = createDebug;
+ createDebug.default = createDebug;
+ createDebug.coerce = coerce;
+ createDebug.disable = disable;
+ createDebug.enable = enable;
+ createDebug.enabled = enabled;
+ createDebug.humanize = requireMs();
+ createDebug.destroy = destroy;
+
+ Object.keys(env).forEach(key => {
+ createDebug[key] = env[key];
+ });
+
+ /**
+ * The currently active debug mode names, and names to skip.
+ */
+
+ createDebug.names = [];
+ createDebug.skips = [];
+
+ /**
+ * Map of special "%n" handling functions, for the debug "format" argument.
+ *
+ * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
+ */
+ createDebug.formatters = {};
+
+ /**
+ * Selects a color for a debug namespace
+ * @param {String} namespace The namespace string for the debug instance to be colored
+ * @return {Number|String} An ANSI color code for the given namespace
+ * @api private
+ */
+ function selectColor(namespace) {
+ let hash = 0;
+
+ for (let i = 0; i < namespace.length; i++) {
+ hash = ((hash << 5) - hash) + namespace.charCodeAt(i);
+ hash |= 0; // Convert to 32bit integer
+ }
+
+ return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
+ }
+ createDebug.selectColor = selectColor;
+
+ /**
+ * Create a debugger with the given `namespace`.
+ *
+ * @param {String} namespace
+ * @return {Function}
+ * @api public
+ */
+ function createDebug(namespace) {
+ let prevTime;
+ let enableOverride = null;
+ let namespacesCache;
+ let enabledCache;
+
+ function debug(...args) {
+ // Disabled?
+ if (!debug.enabled) {
+ return;
+ }
+
+ const self = debug;
+
+ // Set `diff` timestamp
+ const curr = Number(new Date());
+ const ms = curr - (prevTime || curr);
+ self.diff = ms;
+ self.prev = prevTime;
+ self.curr = curr;
+ prevTime = curr;
+
+ args[0] = createDebug.coerce(args[0]);
+
+ if (typeof args[0] !== 'string') {
+ // Anything else let's inspect with %O
+ args.unshift('%O');
+ }
+
+ // Apply any `formatters` transformations
+ let index = 0;
+ args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {
+ // If we encounter an escaped % then don't increase the array index
+ if (match === '%%') {
+ return '%';
+ }
+ index++;
+ const formatter = createDebug.formatters[format];
+ if (typeof formatter === 'function') {
+ const val = args[index];
+ match = formatter.call(self, val);
+
+ // Now we need to remove `args[index]` since it's inlined in the `format`
+ args.splice(index, 1);
+ index--;
+ }
+ return match;
+ });
+
+ // Apply env-specific formatting (colors, etc.)
+ createDebug.formatArgs.call(self, args);
+
+ const logFn = self.log || createDebug.log;
+ logFn.apply(self, args);
+ }
+
+ debug.namespace = namespace;
+ debug.useColors = createDebug.useColors();
+ debug.color = createDebug.selectColor(namespace);
+ debug.extend = extend;
+ debug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release.
+
+ Object.defineProperty(debug, 'enabled', {
+ enumerable: true,
+ configurable: false,
+ get: () => {
+ if (enableOverride !== null) {
+ return enableOverride;
+ }
+ if (namespacesCache !== createDebug.namespaces) {
+ namespacesCache = createDebug.namespaces;
+ enabledCache = createDebug.enabled(namespace);
+ }
+
+ return enabledCache;
+ },
+ set: v => {
+ enableOverride = v;
+ }
+ });
+
+ // Env-specific initialization logic for debug instances
+ if (typeof createDebug.init === 'function') {
+ createDebug.init(debug);
+ }
+
+ return debug;
+ }
+
+ function extend(namespace, delimiter) {
+ const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);
+ newDebug.log = this.log;
+ return newDebug;
+ }
+
+ /**
+ * Enables a debug mode by namespaces. This can include modes
+ * separated by a colon and wildcards.
+ *
+ * @param {String} namespaces
+ * @api public
+ */
+ function enable(namespaces) {
+ createDebug.save(namespaces);
+ createDebug.namespaces = namespaces;
+
+ createDebug.names = [];
+ createDebug.skips = [];
+
+ let i;
+ const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
+ const len = split.length;
+
+ for (i = 0; i < len; i++) {
+ if (!split[i]) {
+ // ignore empty strings
+ continue;
+ }
+
+ namespaces = split[i].replace(/\*/g, '.*?');
+
+ if (namespaces[0] === '-') {
+ createDebug.skips.push(new RegExp('^' + namespaces.slice(1) + '$'));
+ } else {
+ createDebug.names.push(new RegExp('^' + namespaces + '$'));
+ }
+ }
+ }
+
+ /**
+ * Disable debug output.
+ *
+ * @return {String} namespaces
+ * @api public
+ */
+ function disable() {
+ const namespaces = [
+ ...createDebug.names.map(toNamespace),
+ ...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace)
+ ].join(',');
+ createDebug.enable('');
+ return namespaces;
+ }
+
+ /**
+ * Returns true if the given mode name is enabled, false otherwise.
+ *
+ * @param {String} name
+ * @return {Boolean}
+ * @api public
+ */
+ function enabled(name) {
+ if (name[name.length - 1] === '*') {
+ return true;
+ }
+
+ let i;
+ let len;
+
+ for (i = 0, len = createDebug.skips.length; i < len; i++) {
+ if (createDebug.skips[i].test(name)) {
+ return false;
+ }
+ }
+
+ for (i = 0, len = createDebug.names.length; i < len; i++) {
+ if (createDebug.names[i].test(name)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Convert regexp to namespace
+ *
+ * @param {RegExp} regxep
+ * @return {String} namespace
+ * @api private
+ */
+ function toNamespace(regexp) {
+ return regexp.toString()
+ .substring(2, regexp.toString().length - 2)
+ .replace(/\.\*\?$/, '*');
+ }
+
+ /**
+ * Coerce `val`.
+ *
+ * @param {Mixed} val
+ * @return {Mixed}
+ * @api private
+ */
+ function coerce(val) {
+ if (val instanceof Error) {
+ return val.stack || val.message;
+ }
+ return val;
+ }
+
+ /**
+ * XXX DO NOT USE. This is a temporary stub function.
+ * XXX It WILL be removed in the next major release.
+ */
+ function destroy() {
+ console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');
+ }
+
+ createDebug.enable(createDebug.load());
+
+ return createDebug;
+ }
+
+ var common = setup;
+
+ /* eslint-env browser */
+
+ (function (module, exports) {
+ /**
+ * This is the web browser implementation of `debug()`.
+ */
+
+ exports.formatArgs = formatArgs;
+ exports.save = save;
+ exports.load = load;
+ exports.useColors = useColors;
+ exports.storage = localstorage();
+ exports.destroy = (() => {
+ let warned = false;
+
+ return () => {
+ if (!warned) {
+ warned = true;
+ console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');
+ }
+ };
+ })();
+
+ /**
+ * Colors.
+ */
+
+ exports.colors = [
+ '#0000CC',
+ '#0000FF',
+ '#0033CC',
+ '#0033FF',
+ '#0066CC',
+ '#0066FF',
+ '#0099CC',
+ '#0099FF',
+ '#00CC00',
+ '#00CC33',
+ '#00CC66',
+ '#00CC99',
+ '#00CCCC',
+ '#00CCFF',
+ '#3300CC',
+ '#3300FF',
+ '#3333CC',
+ '#3333FF',
+ '#3366CC',
+ '#3366FF',
+ '#3399CC',
+ '#3399FF',
+ '#33CC00',
+ '#33CC33',
+ '#33CC66',
+ '#33CC99',
+ '#33CCCC',
+ '#33CCFF',
+ '#6600CC',
+ '#6600FF',
+ '#6633CC',
+ '#6633FF',
+ '#66CC00',
+ '#66CC33',
+ '#9900CC',
+ '#9900FF',
+ '#9933CC',
+ '#9933FF',
+ '#99CC00',
+ '#99CC33',
+ '#CC0000',
+ '#CC0033',
+ '#CC0066',
+ '#CC0099',
+ '#CC00CC',
+ '#CC00FF',
+ '#CC3300',
+ '#CC3333',
+ '#CC3366',
+ '#CC3399',
+ '#CC33CC',
+ '#CC33FF',
+ '#CC6600',
+ '#CC6633',
+ '#CC9900',
+ '#CC9933',
+ '#CCCC00',
+ '#CCCC33',
+ '#FF0000',
+ '#FF0033',
+ '#FF0066',
+ '#FF0099',
+ '#FF00CC',
+ '#FF00FF',
+ '#FF3300',
+ '#FF3333',
+ '#FF3366',
+ '#FF3399',
+ '#FF33CC',
+ '#FF33FF',
+ '#FF6600',
+ '#FF6633',
+ '#FF9900',
+ '#FF9933',
+ '#FFCC00',
+ '#FFCC33'
+ ];
+
+ /**
+ * Currently only WebKit-based Web Inspectors, Firefox >= v31,
+ * and the Firebug extension (any Firefox version) are known
+ * to support "%c" CSS customizations.
+ *
+ * TODO: add a `localStorage` variable to explicitly enable/disable colors
+ */
+
+ // eslint-disable-next-line complexity
+ function useColors() {
+ // NB: In an Electron preload script, document will be defined but not fully
+ // initialized. Since we know we're in Chrome, we'll just detect this case
+ // explicitly
+ if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {
+ return true;
+ }
+
+ // Internet Explorer and Edge do not support colors.
+ if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
+ return false;
+ }
+
+ // Is webkit? http://stackoverflow.com/a/16459606/376773
+ // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
+ return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
+ // Is firebug? http://stackoverflow.com/a/398120/376773
+ (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
+ // Is firefox >= v31?
+ // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
+ (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
+ // Double check webkit in userAgent just in case we are in a worker
+ (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
+ }
+
+ /**
+ * Colorize log arguments if enabled.
+ *
+ * @api public
+ */
+
+ function formatArgs(args) {
+ args[0] = (this.useColors ? '%c' : '') +
+ this.namespace +
+ (this.useColors ? ' %c' : ' ') +
+ args[0] +
+ (this.useColors ? '%c ' : ' ') +
+ '+' + module.exports.humanize(this.diff);
+
+ if (!this.useColors) {
+ return;
+ }
+
+ const c = 'color: ' + this.color;
+ args.splice(1, 0, c, 'color: inherit');
+
+ // The final "%c" is somewhat tricky, because there could be other
+ // arguments passed either before or after the %c, so we need to
+ // figure out the correct index to insert the CSS into
+ let index = 0;
+ let lastC = 0;
+ args[0].replace(/%[a-zA-Z%]/g, match => {
+ if (match === '%%') {
+ return;
+ }
+ index++;
+ if (match === '%c') {
+ // We only are interested in the *last* %c
+ // (the user may have provided their own)
+ lastC = index;
+ }
+ });
+
+ args.splice(lastC, 0, c);
+ }
+
+ /**
+ * Invokes `console.debug()` when available.
+ * No-op when `console.debug` is not a "function".
+ * If `console.debug` is not available, falls back
+ * to `console.log`.
+ *
+ * @api public
+ */
+ exports.log = console.debug || console.log || (() => {});
+
+ /**
+ * Save `namespaces`.
+ *
+ * @param {String} namespaces
+ * @api private
+ */
+ function save(namespaces) {
+ try {
+ if (namespaces) {
+ exports.storage.setItem('debug', namespaces);
+ } else {
+ exports.storage.removeItem('debug');
+ }
+ } catch (error) {
+ // Swallow
+ // XXX (@Qix-) should we be logging these?
+ }
+ }
+
+ /**
+ * Load `namespaces`.
+ *
+ * @return {String} returns the previously persisted debug modes
+ * @api private
+ */
+ function load() {
+ let r;
+ try {
+ r = exports.storage.getItem('debug');
+ } catch (error) {
+ // Swallow
+ // XXX (@Qix-) should we be logging these?
+ }
+
+ // If debug isn't set in LS, and we're in Electron, try to load $DEBUG
+ if (!r && typeof process !== 'undefined' && 'env' in process) {
+ r = process.env.DEBUG;
+ }
+
+ return r;
+ }
+
+ /**
+ * Localstorage attempts to return the localstorage.
+ *
+ * This is necessary because safari throws
+ * when a user disables cookies/localstorage
+ * and you attempt to access it.
+ *
+ * @return {LocalStorage}
+ * @api private
+ */
+
+ function localstorage() {
+ try {
+ // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context
+ // The Browser also has localStorage in the global context.
+ return localStorage;
+ } catch (error) {
+ // Swallow
+ // XXX (@Qix-) should we be logging these?
+ }
+ }
+
+ module.exports = common(exports);
+
+ const {formatters} = module.exports;
+
+ /**
+ * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
+ */
+
+ formatters.j = function (v) {
+ try {
+ return JSON.stringify(v);
+ } catch (error) {
+ return '[UnexpectedJSONParseError]: ' + error.message;
+ }
+ };
+ } (browser, browserExports));
+
+ var debug = browserExports;
+
+ const log = new debug('nostr:adapter');
+ const profilesLog = new debug('nostr:adapter:profiles');
+ const writeLog = new debug('nostr:adapter:write');
+
+ class NstrAdapter {
+ relayStatus = {};
+ #pool = null;
+ #messages = {};
+ #eventEmitter = new eventsExports();
+ #handlers = {}
+ tags;
+ referenceTags;
+ type;
+ #websiteOwnerPubkey;
+ relayUrls = [];
+
+ #profileRequestQueue = [];
+ #requestedProfiles = [];
+ #profileRequestTimer;
+
+ constructor(clientPubkey, {tags, referenceTags, type='DM', websiteOwnerPubkey, relays} = {}) {
+ this.pubkey = clientPubkey;
+ this.#websiteOwnerPubkey = websiteOwnerPubkey;
+ this.relayUrls = relays;
+
+ if (type) {
+ this.setChatConfiguration(type, tags, referenceTags);
+ }
+ }
+
+ setChatConfiguration(type, tags, referenceTags) {
+ log('chatConfiguration', {type, tags, referenceTags});
+ this.type = type;
+ this.tags = tags;
+ this.referenceTags = referenceTags;
+
+ // handle connection
+ if (this.#pool) { this.#disconnect(); }
+ this.#connect();
+
+ let filters = [];
+
+ console.log('this.tags', this.tags);
+ console.log('this.referenceTags', this.referenceTags);
+
+ // handle subscriptions
+ // if this is DM type then subscribe to chats with this website owner
+ switch (this.type) {
+ case 'DM':
+ filters.push({
+ kinds: [4],
+ '#p': [this.pubkey, this.#websiteOwnerPubkey],
+ 'authors': [this.pubkey, this.#websiteOwnerPubkey]
+ });
+ break;
+ case 'GLOBAL':
+ if (this.tags && this.tags.length > 0) {
+ filters.push({kinds: [1], '#t': this.tags, limit: 20});
+ }
+ if (this.referenceTags && this.referenceTags.length > 0) {
+ filters.push({kinds: [1], '#r': this.referenceTags, limit: 20});
+ }
+
+ break;
+ }
+
+ console.log('filters', filters);
+
+ if (filters && filters.length > 0) {
+ this.subscribe(filters, (e) => { this.#emitMessage(e); });
+ }
+ }
+
+ async getPubKey() {
+ return this.pubkey;
+ }
+
+ on(event, callback) {
+ this.#eventEmitter.on(event, callback);
+ }
+
+ /**
+ * Send a message to the relay
+ * @param {String} message - The message to send
+ */
+ async send(message, {tagPubKeys, tags} = {}) {
+ let event;
+
+ if (!tags) { tags = [];}
+
+ if (this.type === 'DM') {
+ event = await this.sendKind4(message, {tagPubKeys, tags});
+ } else {
+ event = await this.sendKind1(message, {tagPubKeys, tags});
+ }
+
+ event.id = getEventHash(event);
+ const signedEvent = await this.signEvent(event);
+
+ this.#_publish(signedEvent);
+
+ return event.id;
+ }
+
+ async sendKind4(message, {tagPubKeys, tags} = {}) {
+ let ciphertext = await this.encrypt(this.#websiteOwnerPubkey, message);
+ let event = {
+ kind: 4,
+ pubkey: this.pubkey,
+ created_at: Math.floor(Date.now() / 1000),
+ content: ciphertext,
+ tags: [
+ ['p', this.#websiteOwnerPubkey],
+ ...tags
+ ],
+ };
+
+ return event;
+ }
+
+ async sendKind1(message, {tagPubKeys, tags} = {}) {
+ if (!tags) { tags = []; }
+
+ if (this.tags) {
+ this.tags.forEach((t) => tags.push(['t', t]));
+ }
+
+ if (this.referenceTags) {
+ this.referenceTags.forEach((t) => tags.push(['r', t]));
+ }
+
+ let event = {
+ kind: 1,
+ created_at: Math.floor(Date.now() / 1000),
+ tags,
+ content: message,
+ pubkey: this.pubkey,
+ };
+
+ if (tagPubKeys) {
+ for (let pubkey of tagPubKeys) {
+ event.tags.push(['p', pubkey]);
+ }
+ }
+
+ event.id = getEventHash(event);
+ this.subscribeToEventAndResponses(event.id);
+
+ return event;
+ }
+
+ async #_publish(event) {
+ writeLog('publish', event);
+ this.#pool.send([ 'EVENT', event ]);
+ }
+
+ async onEvent(event, messageCallback) {
+ this.#addProfileRequest(event.pubkey);
+
+ messageCallback(event);
+ }
+
+ async subscribe(filters, messageCallback=null) {
+ if (!messageCallback) { messageCallback = (e) => { this.#emitMessage(e); }; }
+ return this.#_subscribe(filters, messageCallback)
+ }
+
+ async #_subscribe(filters, messageCallback) {
+ const subId = v4();
+ this.#handlers[subId] = messageCallback;
+ if (!Array.isArray(filters)) { filters = [filters]; }
+ this.#pool.subscribe(subId, filters);
+ this.#pool.on('event', (relay, recSubId, e) => {
+ this.onEvent(e, this.#handlers[recSubId]);
+ });
+
+ return subId;
+ }
+
+ async #emitMessage(event) {
+ // has already been emitted
+ if (this.#messages[event.id]) {
+ return;
+ }
+
+ this.#messages[event.id] = true;
+
+ // decrypt
+ if (event.kind === 4) {
+ event.content = await this.decrypt(this.#websiteOwnerPubkey, event.content);
+ }
+
+ // if we have tags we were filtering for, filter here in case the relay doesn't support filtering
+ if (this.tags && this.tags.length > 0) {
+ if (!event.tags.find(t => t[0] === 't' && this.tags.includes(t[1]))) {
+ console.log(`discarded event not tagged with [${this.tags.join(', ')}], tags: ${event.tags.filter(t => t[0] === 't').map(t => t[1]).join(', ')}`);
+ return;
+ }
+ }
+
+ if (event.kind === 1) {
+ if (!event.tags.find(t => t[0] === 'e')) {
+ // a top level message that we should subscribe to since responses won't tag the url
+ this.subscribe({ kinds: [1], '#e': [event.id] });
+ }
+ }
+
+ let deletedEvents = [];
+ if (event.kind === 5) {
+ deletedEvents = event.tags.filter(tag => tag[0] === 'e').map(tag => tag[1]);
+ }
+
+ switch (event.kind) {
+ case 1: this.#eventEmitter.emit('message', event); break;
+ case 4: this.#eventEmitter.emit('message', event); break;
+ case 5: this.#eventEmitter.emit('deleted', deletedEvents); break;
+ case 7: this.#eventEmitter.emit('reaction', event); break;
+ default:
+ // alert('unknown event kind ' + event.kind)
+ console.log('unknown event kind', event.kind, event);
+ }
+
+ }
+
+ subscribeToEventAndResponses(eventId) {
+ this.subscribe([
+ {ids: [eventId]},
+ {'#e': [eventId]},
+ ], (e) => {
+ this.#emitMessage(e);
+ // this.subscribeToResponses(e)
+ });
+ }
+
+ subscribeToResponses(event) {
+ this.subscribe([
+ {'#e': [event.id]},
+ ], (e) => {
+ this.#emitMessage(e);
+ this.subscribeToResponses(e);
+ });
+ }
+
+ /**
+ * Connect to the relay
+ */
+ #connect() {
+ this.relayUrls.forEach((url) => {
+ this.relayStatus[url] = 'disconnected';
+ });
+ this.#eventEmitter.emit('connectivity', this.relayStatus);
+
+ // console.log('connecting to relay', this.relayUrls);
+ this.#pool = new relayPool(this.relayUrls);
+ this.#pool.on('open', (relay) => {
+ // console.log(`connected to ${relay.url}`, new Date())
+ this.relayStatus[relay.url] = 'connected';
+ this.#eventEmitter.emit('connectivity', this.relayStatus);
+ });
+
+ this.#pool.on('error', (relay, r, e) => {
+ this.relayStatus[relay.url] = 'error';
+ this.#eventEmitter.emit('connectivity', this.relayStatus);
+ console.log('error from relay', relay.url, r, e);
+ });
+
+ this.#pool.on('close', (relay, r) => {
+ this.relayStatus[relay.url] = 'closed';
+ this.#eventEmitter.emit('connectivity', this.relayStatus);
+ console.log('error from relay', relay.url, r);
+ });
+
+ this.#pool.on('notice', (relay, r) => {
+ console.log('notice', relay.url, r);
+ });
+ }
+
+ #disconnect() {
+ this.relayUrls.forEach((url) => {
+ this.relayStatus[url] = 'disconnected';
+ });
+ this.#eventEmitter.emit('connectivity', this.relayStatus);
+ this.#pool.close();
+ this.#pool = null;
+ }
+
+ //
+ //
+ // Profiles
+ //
+ //
+ #addProfileRequest(pubkey, event=null) {
+ if (this.#profileRequestQueue.includes(pubkey)) { return; }
+ if (this.#requestedProfiles.includes(pubkey)) { return; }
+ this.#profileRequestQueue.push(pubkey);
+ this.#requestedProfiles.push(pubkey);
+
+ if (!this.#profileRequestTimer) {
+ this.#profileRequestTimer = setTimeout(() => {
+ this.#profileRequestTimer = null;
+ this.#requestProfiles();
+ }, 500);
+ }
+ }
+
+ /**
+ * Send request for all queued profiles
+ */
+ async #requestProfiles() {
+ if (this.#profileRequestQueue.length > 0) {
+ profilesLog('requesting profiles', this.#profileRequestQueue);
+
+ // send request
+ const subId = await this.subscribe({ kinds: [0], authors: this.#profileRequestQueue }, (e) => {
+ this.#processReceivedProfile(e);
+ });
+ profilesLog('subscribed to request', {subId});
+ this.#profileRequestQueue = [];
+
+ setTimeout(() => {
+ profilesLog('unsubscribing from request', {subId});
+ this.#pool.unsubscribe(subId);
+ }, 5000);
+ }
+ }
+
+ #processReceivedProfile(event) {
+ profilesLog('received profile', event);
+ let profile;
+ try {
+ profile = JSON.parse(event.content);
+ } catch (e) {
+ profilesLog('failed to parse profile', event);
+ return;
+ }
+ this.#eventEmitter.emit('profile', {pubkey: event.pubkey, profile});
+ }
+ }
+
+ class NstrAdapterNip07 extends NstrAdapter {
+ constructor(pubkey, adapterConfig={}) {
+ super(pubkey, adapterConfig);
+ }
+
+ async signEvent(event) {
+ return await window.nostr.signEvent(event);
+ }
+
+ async encrypt(destPubkey, message) {
+ return await window.nostr.nip04.encrypt(destPubkey, message);
+ }
+
+ async decrypt(destPubkey, message) {
+ return await window.nostr.nip04.decrypt(destPubkey, message);
+ }
+ }
+
+ function _regeneratorRuntime() {
+ _regeneratorRuntime = function () {
+ return exports;
+ };
+ var exports = {},
+ Op = Object.prototype,
+ hasOwn = Op.hasOwnProperty,
+ defineProperty = Object.defineProperty || function (obj, key, desc) {
+ obj[key] = desc.value;
+ },
+ $Symbol = "function" == typeof Symbol ? Symbol : {},
+ iteratorSymbol = $Symbol.iterator || "@@iterator",
+ asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator",
+ toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
+ function define(obj, key, value) {
+ return Object.defineProperty(obj, key, {
+ value: value,
+ enumerable: !0,
+ configurable: !0,
+ writable: !0
+ }), obj[key];
+ }
+ try {
+ define({}, "");
+ } catch (err) {
+ define = function (obj, key, value) {
+ return obj[key] = value;
+ };
+ }
+ function wrap(innerFn, outerFn, self, tryLocsList) {
+ var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator,
+ generator = Object.create(protoGenerator.prototype),
+ context = new Context(tryLocsList || []);
+ return defineProperty(generator, "_invoke", {
+ value: makeInvokeMethod(innerFn, self, context)
+ }), generator;
+ }
+ function tryCatch(fn, obj, arg) {
+ try {
+ return {
+ type: "normal",
+ arg: fn.call(obj, arg)
+ };
+ } catch (err) {
+ return {
+ type: "throw",
+ arg: err
+ };
+ }
+ }
+ exports.wrap = wrap;
+ var ContinueSentinel = {};
+ function Generator() {}
+ function GeneratorFunction() {}
+ function GeneratorFunctionPrototype() {}
+ var IteratorPrototype = {};
+ define(IteratorPrototype, iteratorSymbol, function () {
+ return this;
+ });
+ var getProto = Object.getPrototypeOf,
+ NativeIteratorPrototype = getProto && getProto(getProto(values([])));
+ NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype);
+ var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype);
+ function defineIteratorMethods(prototype) {
+ ["next", "throw", "return"].forEach(function (method) {
+ define(prototype, method, function (arg) {
+ return this._invoke(method, arg);
+ });
+ });
+ }
+ function AsyncIterator(generator, PromiseImpl) {
+ function invoke(method, arg, resolve, reject) {
+ var record = tryCatch(generator[method], generator, arg);
+ if ("throw" !== record.type) {
+ var result = record.arg,
+ value = result.value;
+ return value && "object" == typeof value && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) {
+ invoke("next", value, resolve, reject);
+ }, function (err) {
+ invoke("throw", err, resolve, reject);
+ }) : PromiseImpl.resolve(value).then(function (unwrapped) {
+ result.value = unwrapped, resolve(result);
+ }, function (error) {
+ return invoke("throw", error, resolve, reject);
+ });
+ }
+ reject(record.arg);
+ }
+ var previousPromise;
+ defineProperty(this, "_invoke", {
+ value: function (method, arg) {
+ function callInvokeWithMethodAndArg() {
+ return new PromiseImpl(function (resolve, reject) {
+ invoke(method, arg, resolve, reject);
+ });
+ }
+ return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
+ }
+ });
+ }
+ function makeInvokeMethod(innerFn, self, context) {
+ var state = "suspendedStart";
+ return function (method, arg) {
+ if ("executing" === state) throw new Error("Generator is already running");
+ if ("completed" === state) {
+ if ("throw" === method) throw arg;
+ return doneResult();
+ }
+ for (context.method = method, context.arg = arg;;) {
+ var delegate = context.delegate;
+ if (delegate) {
+ var delegateResult = maybeInvokeDelegate(delegate, context);
+ if (delegateResult) {
+ if (delegateResult === ContinueSentinel) continue;
+ return delegateResult;
+ }
+ }
+ if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) {
+ if ("suspendedStart" === state) throw state = "completed", context.arg;
+ context.dispatchException(context.arg);
+ } else "return" === context.method && context.abrupt("return", context.arg);
+ state = "executing";
+ var record = tryCatch(innerFn, self, context);
+ if ("normal" === record.type) {
+ if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue;
+ return {
+ value: record.arg,
+ done: context.done
+ };
+ }
+ "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg);
+ }
+ };
+ }
+ function maybeInvokeDelegate(delegate, context) {
+ var methodName = context.method,
+ method = delegate.iterator[methodName];
+ if (undefined === method) return context.delegate = null, "throw" === methodName && delegate.iterator.return && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method) || "return" !== methodName && (context.method = "throw", context.arg = new TypeError("The iterator does not provide a '" + methodName + "' method")), ContinueSentinel;
+ var record = tryCatch(method, delegate.iterator, context.arg);
+ if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel;
+ var info = record.arg;
+ return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel);
+ }
+ function pushTryEntry(locs) {
+ var entry = {
+ tryLoc: locs[0]
+ };
+ 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry);
+ }
+ function resetTryEntry(entry) {
+ var record = entry.completion || {};
+ record.type = "normal", delete record.arg, entry.completion = record;
+ }
+ function Context(tryLocsList) {
+ this.tryEntries = [{
+ tryLoc: "root"
+ }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0);
+ }
+ function values(iterable) {
+ if (iterable) {
+ var iteratorMethod = iterable[iteratorSymbol];
+ if (iteratorMethod) return iteratorMethod.call(iterable);
+ if ("function" == typeof iterable.next) return iterable;
+ if (!isNaN(iterable.length)) {
+ var i = -1,
+ next = function next() {
+ for (; ++i < iterable.length;) if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next;
+ return next.value = undefined, next.done = !0, next;
+ };
+ return next.next = next;
+ }
+ }
+ return {
+ next: doneResult
+ };
+ }
+ function doneResult() {
+ return {
+ value: undefined,
+ done: !0
+ };
+ }
+ return GeneratorFunction.prototype = GeneratorFunctionPrototype, defineProperty(Gp, "constructor", {
+ value: GeneratorFunctionPrototype,
+ configurable: !0
+ }), defineProperty(GeneratorFunctionPrototype, "constructor", {
+ value: GeneratorFunction,
+ configurable: !0
+ }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) {
+ var ctor = "function" == typeof genFun && genFun.constructor;
+ return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name));
+ }, exports.mark = function (genFun) {
+ return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun;
+ }, exports.awrap = function (arg) {
+ return {
+ __await: arg
+ };
+ }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () {
+ return this;
+ }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) {
+ void 0 === PromiseImpl && (PromiseImpl = Promise);
+ var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl);
+ return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) {
+ return result.done ? result.value : iter.next();
+ });
+ }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () {
+ return this;
+ }), define(Gp, "toString", function () {
+ return "[object Generator]";
+ }), exports.keys = function (val) {
+ var object = Object(val),
+ keys = [];
+ for (var key in object) keys.push(key);
+ return keys.reverse(), function next() {
+ for (; keys.length;) {
+ var key = keys.pop();
+ if (key in object) return next.value = key, next.done = !1, next;
+ }
+ return next.done = !0, next;
+ };
+ }, exports.values = values, Context.prototype = {
+ constructor: Context,
+ reset: function (skipTempReset) {
+ if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined);
+ },
+ stop: function () {
+ this.done = !0;
+ var rootRecord = this.tryEntries[0].completion;
+ if ("throw" === rootRecord.type) throw rootRecord.arg;
+ return this.rval;
+ },
+ dispatchException: function (exception) {
+ if (this.done) throw exception;
+ var context = this;
+ function handle(loc, caught) {
+ return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught;
+ }
+ for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+ var entry = this.tryEntries[i],
+ record = entry.completion;
+ if ("root" === entry.tryLoc) return handle("end");
+ if (entry.tryLoc <= this.prev) {
+ var hasCatch = hasOwn.call(entry, "catchLoc"),
+ hasFinally = hasOwn.call(entry, "finallyLoc");
+ if (hasCatch && hasFinally) {
+ if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);
+ if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);
+ } else if (hasCatch) {
+ if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);
+ } else {
+ if (!hasFinally) throw new Error("try statement without catch or finally");
+ if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);
+ }
+ }
+ }
+ },
+ abrupt: function (type, arg) {
+ for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+ var entry = this.tryEntries[i];
+ if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) {
+ var finallyEntry = entry;
+ break;
+ }
+ }
+ finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null);
+ var record = finallyEntry ? finallyEntry.completion : {};
+ return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record);
+ },
+ complete: function (record, afterLoc) {
+ if ("throw" === record.type) throw record.arg;
+ return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel;
+ },
+ finish: function (finallyLoc) {
+ for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+ var entry = this.tryEntries[i];
+ if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel;
+ }
+ },
+ catch: function (tryLoc) {
+ for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+ var entry = this.tryEntries[i];
+ if (entry.tryLoc === tryLoc) {
+ var record = entry.completion;
+ if ("throw" === record.type) {
+ var thrown = record.arg;
+ resetTryEntry(entry);
+ }
+ return thrown;
+ }
+ }
+ throw new Error("illegal catch attempt");
+ },
+ delegateYield: function (iterable, resultName, nextLoc) {
+ return this.delegate = {
+ iterator: values(iterable),
+ resultName: resultName,
+ nextLoc: nextLoc
+ }, "next" === this.method && (this.arg = undefined), ContinueSentinel;
+ }
+ }, exports;
+ }
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
+ try {
+ var info = gen[key](arg);
+ var value = info.value;
+ } catch (error) {
+ reject(error);
+ return;
+ }
+ if (info.done) {
+ resolve(value);
+ } else {
+ Promise.resolve(value).then(_next, _throw);
+ }
+ }
+ function _asyncToGenerator(fn) {
+ return function () {
+ var self = this,
+ args = arguments;
+ return new Promise(function (resolve, reject) {
+ var gen = fn.apply(self, args);
+ function _next(value) {
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
+ }
+ function _throw(err) {
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
+ }
+ _next(undefined);
+ });
+ };
+ }
+ function _extends() {
+ _extends = Object.assign ? Object.assign.bind() : function (target) {
+ for (var i = 1; i < arguments.length; i++) {
+ var source = arguments[i];
+ for (var key in source) {
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
+ target[key] = source[key];
+ }
+ }
+ }
+ return target;
+ };
+ return _extends.apply(this, arguments);
+ }
+
+ var NostrRPC = /*#__PURE__*/function () {
+ function NostrRPC(opts) {
+ // events
+ this.events = new eventsExports();
+ this.relay = opts.relay || 'wss://nostr.vulpem.com';
+ this.self = {
+ pubkey: getPublicKey(opts.secretKey),
+ secret: opts.secretKey
+ };
+ }
+ var _proto = NostrRPC.prototype;
+ _proto.call = /*#__PURE__*/function () {
+ var _call = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(_ref, opts) {
+ var _this = this;
+ var target, _ref$request, _ref$request$id, id, method, _ref$request$params, params, relay, request, event;
+ return _regeneratorRuntime().wrap(function _callee3$(_context3) {
+ while (1) switch (_context3.prev = _context3.next) {
+ case 0:
+ target = _ref.target, _ref$request = _ref.request, _ref$request$id = _ref$request.id, id = _ref$request$id === void 0 ? /*#__PURE__*/randomID() : _ref$request$id, method = _ref$request.method, _ref$request$params = _ref$request.params, params = _ref$request$params === void 0 ? [] : _ref$request$params;
+ _context3.next = 3;
+ return connectToRelay(this.relay);
+ case 3:
+ relay = _context3.sent;
+ // prepare request to be sent
+ request = prepareRequest(id, method, params);
+ _context3.next = 7;
+ return prepareEvent(this.self.secret, target, request);
+ case 7:
+ event = _context3.sent;
+ return _context3.abrupt("return", new Promise( /*#__PURE__*/function () {
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(resolve, reject) {
+ var sub;
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
+ while (1) switch (_context2.prev = _context2.next) {
+ case 0:
+ sub = relay.sub([{
+ kinds: [24133],
+ authors: [target],
+ '#p': [_this.self.pubkey],
+ limit: 1
+ }]);
+ _context2.next = 3;
+ return broadcastToRelay(relay, event, true);
+ case 3:
+ // skip waiting for response from remote
+ if (opts && opts.skipResponse === true) resolve();
+ sub.on('event', /*#__PURE__*/function () {
+ var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(event) {
+ var payload, plaintext;
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
+ while (1) switch (_context.prev = _context.next) {
+ case 0:
+ _context.prev = 0;
+ _context.next = 3;
+ return nip04_exports.decrypt(_this.self.secret, event.pubkey, event.content);
+ case 3:
+ plaintext = _context.sent;
+ if (plaintext) {
+ _context.next = 6;
+ break;
+ }
+ throw new Error('failed to decrypt event');
+ case 6:
+ payload = JSON.parse(plaintext);
+ _context.next = 12;
+ break;
+ case 9:
+ _context.prev = 9;
+ _context.t0 = _context["catch"](0);
+ return _context.abrupt("return");
+ case 12:
+ if (isValidResponse(payload)) {
+ _context.next = 14;
+ break;
+ }
+ return _context.abrupt("return");
+ case 14:
+ if (!(payload.id !== id)) {
+ _context.next = 16;
+ break;
+ }
+ return _context.abrupt("return");
+ case 16:
+ // if the response is an error, reject the promise
+ if (payload.error) {
+ reject(payload.error);
+ }
+ // if the response is a result, resolve the promise
+ if (payload.result) {
+ resolve(payload.result);
+ }
+ case 18:
+ case "end":
+ return _context.stop();
+ }
+ }, _callee, null, [[0, 9]]);
+ }));
+ return function (_x5) {
+ return _ref3.apply(this, arguments);
+ };
+ }());
+ case 5:
+ case "end":
+ return _context2.stop();
+ }
+ }, _callee2);
+ }));
+ return function (_x3, _x4) {
+ return _ref2.apply(this, arguments);
+ };
+ }()));
+ case 9:
+ case "end":
+ return _context3.stop();
+ }
+ }, _callee3, this);
+ }));
+ function call(_x, _x2) {
+ return _call.apply(this, arguments);
+ }
+ return call;
+ }();
+ _proto.listen = /*#__PURE__*/function () {
+ var _listen = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5() {
+ var _this2 = this;
+ var relay, sub;
+ return _regeneratorRuntime().wrap(function _callee5$(_context5) {
+ while (1) switch (_context5.prev = _context5.next) {
+ case 0:
+ _context5.next = 2;
+ return connectToRelay(this.relay);
+ case 2:
+ relay = _context5.sent;
+ sub = relay.sub([{
+ kinds: [24133],
+ '#p': [this.self.pubkey],
+ since: now()
+ }]);
+ sub.on('event', /*#__PURE__*/function () {
+ var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(event) {
+ var payload, plaintext, response, body, responseEvent;
+ return _regeneratorRuntime().wrap(function _callee4$(_context4) {
+ while (1) switch (_context4.prev = _context4.next) {
+ case 0:
+ _context4.prev = 0;
+ _context4.next = 3;
+ return nip04_exports.decrypt(_this2.self.secret, event.pubkey, event.content);
+ case 3:
+ plaintext = _context4.sent;
+ if (plaintext) {
+ _context4.next = 6;
+ break;
+ }
+ throw new Error('failed to decrypt event');
+ case 6:
+ payload = JSON.parse(plaintext);
+ _context4.next = 12;
+ break;
+ case 9:
+ _context4.prev = 9;
+ _context4.t0 = _context4["catch"](0);
+ return _context4.abrupt("return");
+ case 12:
+ if (isValidRequest(payload)) {
+ _context4.next = 14;
+ break;
+ }
+ return _context4.abrupt("return");
+ case 14:
+ _context4.next = 17;
+ return _this2.handleRequest(payload, event);
+ case 17:
+ response = _context4.sent;
+ body = prepareResponse(response.id, response.result, response.error);
+ _context4.next = 21;
+ return prepareEvent(_this2.self.secret, event.pubkey, body);
+ case 21:
+ responseEvent = _context4.sent;
+ // send response via relay
+ relay.publish(responseEvent);
+ case 23:
+ case "end":
+ return _context4.stop();
+ }
+ }, _callee4, null, [[0, 9]]);
+ }));
+ return function (_x6) {
+ return _ref4.apply(this, arguments);
+ };
+ }());
+ return _context5.abrupt("return", sub);
+ case 6:
+ case "end":
+ return _context5.stop();
+ }
+ }, _callee5, this);
+ }));
+ function listen() {
+ return _listen.apply(this, arguments);
+ }
+ return listen;
+ }();
+ _proto.handleRequest = /*#__PURE__*/function () {
+ var _handleRequest = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(request, event) {
+ var id, method, params, result, error;
+ return _regeneratorRuntime().wrap(function _callee6$(_context6) {
+ while (1) switch (_context6.prev = _context6.next) {
+ case 0:
+ id = request.id, method = request.method, params = request.params;
+ result = null;
+ error = null;
+ _context6.prev = 3;
+ this.event = event;
+ _context6.next = 7;
+ return this[method].apply(this, params);
+ case 7:
+ result = _context6.sent;
+ this.event = undefined;
+ _context6.next = 14;
+ break;
+ case 11:
+ _context6.prev = 11;
+ _context6.t0 = _context6["catch"](3);
+ if (_context6.t0 instanceof Error) {
+ error = _context6.t0.message;
+ } else {
+ error = 'unknown error';
+ }
+ case 14:
+ return _context6.abrupt("return", {
+ id: id,
+ result: result,
+ error: error
+ });
+ case 15:
+ case "end":
+ return _context6.stop();
+ }
+ }, _callee6, this, [[3, 11]]);
+ }));
+ function handleRequest(_x7, _x8) {
+ return _handleRequest.apply(this, arguments);
+ }
+ return handleRequest;
+ }();
+ return NostrRPC;
+ }();
+ function now() {
+ return Math.floor(Date.now() / 1000);
+ }
+ function randomID() {
+ return Math.random().toString().slice(2);
+ }
+ function prepareRequest(id, method, params) {
+ return JSON.stringify({
+ id: id,
+ method: method,
+ params: params
+ });
+ }
+ function prepareResponse(id, result, error) {
+ return JSON.stringify({
+ id: id,
+ result: result,
+ error: error
+ });
+ }
+ function prepareEvent(_x9, _x10, _x11) {
+ return _prepareEvent.apply(this, arguments);
+ }
+ function _prepareEvent() {
+ _prepareEvent = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7(secretKey, pubkey, content) {
+ var cipherText, event, id, sig, signedEvent, ok, veryOk;
+ return _regeneratorRuntime().wrap(function _callee7$(_context7) {
+ while (1) switch (_context7.prev = _context7.next) {
+ case 0:
+ _context7.next = 2;
+ return nip04_exports.encrypt(secretKey, pubkey, content);
+ case 2:
+ cipherText = _context7.sent;
+ event = {
+ kind: 24133,
+ created_at: now(),
+ pubkey: getPublicKey(secretKey),
+ tags: [['p', pubkey]],
+ content: cipherText
+ };
+ id = getEventHash(event);
+ sig = signEvent(event, secretKey);
+ signedEvent = _extends({}, event, {
+ id: id,
+ sig: sig
+ });
+ ok = validateEvent(signedEvent);
+ veryOk = verifySignature(signedEvent);
+ if (!(!ok || !veryOk)) {
+ _context7.next = 11;
+ break;
+ }
+ throw new Error('Event is not valid');
+ case 11:
+ return _context7.abrupt("return", signedEvent);
+ case 12:
+ case "end":
+ return _context7.stop();
+ }
+ }, _callee7);
+ }));
+ return _prepareEvent.apply(this, arguments);
+ }
+ function isValidRequest(payload) {
+ if (!payload) return false;
+ var keys = Object.keys(payload);
+ if (!keys.includes('id') || !keys.includes('method') || !keys.includes('params')) return false;
+ return true;
+ }
+ function isValidResponse(payload) {
+ if (!payload) return false;
+ var keys = Object.keys(payload);
+ if (!keys.includes('id') || !keys.includes('result') || !keys.includes('error')) return false;
+ return true;
+ }
+ function connectToRelay(_x12) {
+ return _connectToRelay.apply(this, arguments);
+ }
+ function _connectToRelay() {
+ _connectToRelay = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee8(realayURL) {
+ var relay;
+ return _regeneratorRuntime().wrap(function _callee8$(_context8) {
+ while (1) switch (_context8.prev = _context8.next) {
+ case 0:
+ relay = relayInit(realayURL);
+ _context8.next = 3;
+ return relay.connect();
+ case 3:
+ _context8.next = 5;
+ return new Promise(function (resolve, reject) {
+ relay.on('connect', function () {
+ resolve();
+ });
+ relay.on('error', function () {
+ reject(new Error("not possible to connect to " + relay.url));
+ });
+ });
+ case 5:
+ return _context8.abrupt("return", relay);
+ case 6:
+ case "end":
+ return _context8.stop();
+ }
+ }, _callee8);
+ }));
+ return _connectToRelay.apply(this, arguments);
+ }
+ function broadcastToRelay(_x13, _x14, _x15) {
+ return _broadcastToRelay.apply(this, arguments);
+ }
+ function _broadcastToRelay() {
+ _broadcastToRelay = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee9(relay, event, skipSeen) {
+ return _regeneratorRuntime().wrap(function _callee9$(_context9) {
+ while (1) switch (_context9.prev = _context9.next) {
+ case 0:
+ if (skipSeen === void 0) {
+ skipSeen = false;
+ }
+ _context9.next = 3;
+ return new Promise(function (resolve, reject) {
+ relay.on('error', function () {
+ reject(new Error("failed to connect to " + relay.url));
+ });
+ var pub = relay.publish(event);
+ if (skipSeen) resolve();
+ pub.on('failed', function (reason) {
+ reject(reason);
+ });
+ pub.on('seen', function () {
+ resolve();
+ });
+ });
+ case 3:
+ return _context9.abrupt("return", _context9.sent);
+ case 4:
+ case "end":
+ return _context9.stop();
+ }
+ }, _callee9);
+ }));
+ return _broadcastToRelay.apply(this, arguments);
+ }
+
+ var ConnectURI = /*#__PURE__*/function () {
+ function ConnectURI(_ref) {
+ var target = _ref.target,
+ metadata = _ref.metadata,
+ relay = _ref.relay;
+ this.target = target;
+ this.metadata = metadata;
+ this.relay = relay;
+ }
+ ConnectURI.fromURI = function fromURI(uri) {
+ var url = new URL(uri);
+ var target = url.hostname || url.pathname.substring(2);
+ if (!target) throw new Error('Invalid connect URI: missing target');
+ var relay = url.searchParams.get('relay');
+ if (!relay) {
+ throw new Error('Invalid connect URI: missing relay');
+ }
+ var metadata = url.searchParams.get('metadata');
+ if (!metadata) {
+ throw new Error('Invalid connect URI: missing metadata');
+ }
+ /* eslint-disable @typescript-eslint/no-unused-vars */
+ try {
+ var md = JSON.parse(metadata);
+ return new ConnectURI({
+ target: target,
+ metadata: md,
+ relay: relay
+ });
+ } catch (ignore) {
+ throw new Error('Invalid connect URI: metadata is not valid JSON');
+ }
+ };
+ var _proto = ConnectURI.prototype;
+ _proto.toString = function toString() {
+ return "nostrconnect://" + this.target + "?metadata=" + encodeURIComponent(JSON.stringify(this.metadata)) + "&relay=" + encodeURIComponent(this.relay);
+ };
+ _proto.approve = /*#__PURE__*/function () {
+ var _approve = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(secretKey) {
+ var rpc;
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
+ while (1) switch (_context.prev = _context.next) {
+ case 0:
+ rpc = new NostrRPC({
+ relay: this.relay,
+ secretKey: secretKey
+ });
+ _context.next = 3;
+ return rpc.call({
+ target: this.target,
+ request: {
+ method: 'connect',
+ params: [getPublicKey(secretKey)]
+ }
+ }, {
+ skipResponse: true
+ });
+ case 3:
+ case "end":
+ return _context.stop();
+ }
+ }, _callee, this);
+ }));
+ function approve(_x) {
+ return _approve.apply(this, arguments);
+ }
+ return approve;
+ }();
+ _proto.reject = /*#__PURE__*/function () {
+ var _reject = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(secretKey) {
+ var rpc;
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
+ while (1) switch (_context2.prev = _context2.next) {
+ case 0:
+ rpc = new NostrRPC({
+ relay: this.relay,
+ secretKey: secretKey
+ });
+ _context2.next = 3;
+ return rpc.call({
+ target: this.target,
+ request: {
+ method: 'disconnect',
+ params: []
+ }
+ }, {
+ skipResponse: true
+ });
+ case 3:
+ case "end":
+ return _context2.stop();
+ }
+ }, _callee2, this);
+ }));
+ function reject(_x2) {
+ return _reject.apply(this, arguments);
+ }
+ return reject;
+ }();
+ return ConnectURI;
+ }();
+ var Connect = /*#__PURE__*/function () {
+ function Connect(_ref2) {
+ var target = _ref2.target,
+ relay = _ref2.relay,
+ secretKey = _ref2.secretKey;
+ this.events = new eventsExports();
+ this.nip04 = {
+ encrypt: function () {
+ var _encrypt = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(_pubkey, _plaintext) {
+ return _regeneratorRuntime().wrap(function _callee3$(_context3) {
+ while (1) switch (_context3.prev = _context3.next) {
+ case 0:
+ throw new Error('Not implemented');
+ case 1:
+ case "end":
+ return _context3.stop();
+ }
+ }, _callee3);
+ }));
+ function encrypt(_x3, _x4) {
+ return _encrypt.apply(this, arguments);
+ }
+ return encrypt;
+ }(),
+ decrypt: function () {
+ var _decrypt = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(_pubkey, _ciphertext) {
+ return _regeneratorRuntime().wrap(function _callee4$(_context4) {
+ while (1) switch (_context4.prev = _context4.next) {
+ case 0:
+ throw new Error('Not implemented');
+ case 1:
+ case "end":
+ return _context4.stop();
+ }
+ }, _callee4);
+ }));
+ function decrypt(_x5, _x6) {
+ return _decrypt.apply(this, arguments);
+ }
+ return decrypt;
+ }()
+ };
+ this.rpc = new NostrRPC({
+ relay: relay,
+ secretKey: secretKey
+ });
+ if (target) {
+ this.target = target;
+ }
+ }
+ var _proto2 = Connect.prototype;
+ _proto2.init = /*#__PURE__*/function () {
+ var _init = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6() {
+ var _this = this;
+ var sub;
+ return _regeneratorRuntime().wrap(function _callee6$(_context6) {
+ while (1) switch (_context6.prev = _context6.next) {
+ case 0:
+ _context6.next = 2;
+ return this.rpc.listen();
+ case 2:
+ sub = _context6.sent;
+ sub.on('event', /*#__PURE__*/function () {
+ var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(event) {
+ var payload, plaintext, _payload$params, pubkey;
+ return _regeneratorRuntime().wrap(function _callee5$(_context5) {
+ while (1) switch (_context5.prev = _context5.next) {
+ case 0:
+ _context5.prev = 0;
+ _context5.next = 3;
+ return nip04_exports.decrypt(_this.rpc.self.secret, event.pubkey, event.content);
+ case 3:
+ plaintext = _context5.sent;
+ if (plaintext) {
+ _context5.next = 6;
+ break;
+ }
+ throw new Error('failed to decrypt event');
+ case 6:
+ payload = JSON.parse(plaintext);
+ _context5.next = 12;
+ break;
+ case 9:
+ _context5.prev = 9;
+ _context5.t0 = _context5["catch"](0);
+ return _context5.abrupt("return");
+ case 12:
+ if (isValidRequest(payload)) {
+ _context5.next = 14;
+ break;
+ }
+ return _context5.abrupt("return");
+ case 14:
+ _context5.t1 = payload.method;
+ _context5.next = _context5.t1 === 'connect' ? 17 : _context5.t1 === 'disconnect' ? 23 : 26;
+ break;
+ case 17:
+ if (!(!payload.params || payload.params.length !== 1)) {
+ _context5.next = 19;
+ break;
+ }
+ throw new Error('connect: missing pubkey');
+ case 19:
+ _payload$params = payload.params, pubkey = _payload$params[0];
+ _this.target = pubkey;
+ _this.events.emit('connect', pubkey);
+ return _context5.abrupt("break", 26);
+ case 23:
+ _this.target = undefined;
+ _this.events.emit('disconnect');
+ return _context5.abrupt("break", 26);
+ case 26:
+ case "end":
+ return _context5.stop();
+ }
+ }, _callee5, null, [[0, 9]]);
+ }));
+ return function (_x7) {
+ return _ref3.apply(this, arguments);
+ };
+ }());
+ case 4:
+ case "end":
+ return _context6.stop();
+ }
+ }, _callee6, this);
+ }));
+ function init() {
+ return _init.apply(this, arguments);
+ }
+ return init;
+ }();
+ _proto2.on = function on(evt, cb) {
+ this.events.on(evt, cb);
+ };
+ _proto2.off = function off(evt, cb) {
+ this.events.off(evt, cb);
+ };
+ _proto2.disconnect = /*#__PURE__*/function () {
+ var _disconnect = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7() {
+ return _regeneratorRuntime().wrap(function _callee7$(_context7) {
+ while (1) switch (_context7.prev = _context7.next) {
+ case 0:
+ if (this.target) {
+ _context7.next = 2;
+ break;
+ }
+ throw new Error('Not connected');
+ case 2:
+ // notify the UI that we are disconnecting
+ this.events.emit('disconnect');
+ _context7.prev = 3;
+ _context7.next = 6;
+ return this.rpc.call({
+ target: this.target,
+ request: {
+ method: 'disconnect',
+ params: []
+ }
+ }, {
+ skipResponse: true
+ });
+ case 6:
+ _context7.next = 11;
+ break;
+ case 8:
+ _context7.prev = 8;
+ _context7.t0 = _context7["catch"](3);
+ throw new Error('Failed to disconnect');
+ case 11:
+ this.target = undefined;
+ case 12:
+ case "end":
+ return _context7.stop();
+ }
+ }, _callee7, this, [[3, 8]]);
+ }));
+ function disconnect() {
+ return _disconnect.apply(this, arguments);
+ }
+ return disconnect;
+ }();
+ _proto2.getPublicKey = /*#__PURE__*/function () {
+ var _getPublicKey = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee8() {
+ var response;
+ return _regeneratorRuntime().wrap(function _callee8$(_context8) {
+ while (1) switch (_context8.prev = _context8.next) {
+ case 0:
+ if (this.target) {
+ _context8.next = 2;
+ break;
+ }
+ throw new Error('Not connected');
+ case 2:
+ _context8.next = 4;
+ return this.rpc.call({
+ target: this.target,
+ request: {
+ method: 'get_public_key',
+ params: []
+ }
+ });
+ case 4:
+ response = _context8.sent;
+ return _context8.abrupt("return", response);
+ case 6:
+ case "end":
+ return _context8.stop();
+ }
+ }, _callee8, this);
+ }));
+ function getPublicKey() {
+ return _getPublicKey.apply(this, arguments);
+ }
+ return getPublicKey;
+ }();
+ _proto2.signEvent = /*#__PURE__*/function () {
+ var _signEvent = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee9(event) {
+ var signature;
+ return _regeneratorRuntime().wrap(function _callee9$(_context9) {
+ while (1) switch (_context9.prev = _context9.next) {
+ case 0:
+ if (this.target) {
+ _context9.next = 2;
+ break;
+ }
+ throw new Error('Not connected');
+ case 2:
+ _context9.next = 4;
+ return this.rpc.call({
+ target: this.target,
+ request: {
+ method: 'sign_event',
+ params: [event]
+ }
+ });
+ case 4:
+ signature = _context9.sent;
+ return _context9.abrupt("return", signature);
+ case 6:
+ case "end":
+ return _context9.stop();
+ }
+ }, _callee9, this);
+ }));
+ function signEvent(_x8) {
+ return _signEvent.apply(this, arguments);
+ }
+ return signEvent;
+ }();
+ _proto2.getRelays = /*#__PURE__*/function () {
+ var _getRelays = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee10() {
+ return _regeneratorRuntime().wrap(function _callee10$(_context10) {
+ while (1) switch (_context10.prev = _context10.next) {
+ case 0:
+ throw new Error('Not implemented');
+ case 1:
+ case "end":
+ return _context10.stop();
+ }
+ }, _callee10);
+ }));
+ function getRelays() {
+ return _getRelays.apply(this, arguments);
+ }
+ return getRelays;
+ }();
+ return Connect;
+ }();
+
+ class NstrAdapterNip46 extends NstrAdapter {
+ #secretKey = null;
+
+ constructor(pubkey, secretKey, adapterConfig = {}) {
+ super(pubkey, adapterConfig);
+ this.#secretKey = secretKey;
+ }
+
+ async signEvent(event) {
+ const connect = new Connect({
+ secretKey: this.#secretKey,
+ target: this.pubkey,
+ });
+ await connect.init();
+
+ event.sig = await connect.signEvent('12323423434');
+ return event;
+ }
+ }
+
+ class NstrAdapterDiscadableKeys extends NstrAdapter {
+ #privateKey;
+
+ constructor(adapterConfig={}) {
+ let key = localStorage.getItem('nostrichat-discardable-key');
+ let publicKey = localStorage.getItem('nostrichat-discardable-public-key');
+
+ if (!key) {
+ key = generatePrivateKey();
+ console.log('generated key', key);
+ publicKey = getPublicKey(key);
+ }
+
+ localStorage.setItem('nostrichat-discardable-key', key);
+ localStorage.setItem('nostrichat-discardable-public-key', publicKey);
+
+ super(publicKey, adapterConfig);
+
+ this.#privateKey = key;
+ console.log(key);
+ }
+
+ async signEvent(event) {
+ event.sig = await signEvent(event, this.#privateKey);
+ return event;
+ }
+
+ async encrypt(destPubkey, message) {
+ console.log(this.#privateKey);
+ return await nip04_exports.encrypt(this.#privateKey, destPubkey, message);
+ }
+
+ async decrypt(destPubkey, message) {
+ return await nip04_exports.decrypt(this.#privateKey, destPubkey, message);
+ }
+ }
+
+ /* src/KeyPrompt.svelte generated by Svelte v3.55.1 */
+
+ // (136:21)
+ function create_if_block_1$3(ctx) {
+ let div;
+ let t0;
+ let button0;
+ let t2;
+ let button1;
+ let mounted;
+ let dispose;
+ let if_block = create_if_block_2$1(ctx);
+
+ return {
+ c() {
+ div = element("div");
+ if (if_block) if_block.c();
+ t0 = space();
+ button0 = element("button");
+ button0.textContent = "Nostr Connect (NIP-46)";
+ t2 = space();
+ button1 = element("button");
+
+ button1.innerHTML = `Anonymous
+ (Ephemeral Keys)`;
+
+ attr(button0, "class", "bg-purple-900 hover:bg-purple-700 w-full p-4 rounded-xl text-center font-regular text-gray-200 svelte-8015tc");
+ attr(button1, "class", "bg-purple-900 hover:bg-purple-700 w-full p-4 rounded-xl text-center font-regular text-gray-200 svelte-8015tc");
+ attr(div, "class", "flex flex-col gap-1 svelte-8015tc");
+ },
+ m(target, anchor) {
+ insert(target, div, anchor);
+ if (if_block) if_block.m(div, null);
+ append(div, t0);
+ append(div, button0);
+ append(div, t2);
+ append(div, button1);
+
+ if (!mounted) {
+ dispose = [
+ listen(button0, "click", prevent_default(/*useNip46*/ ctx[3])),
+ listen(button1, "click", prevent_default(/*useDiscardableKeys*/ ctx[2]))
+ ];
+
+ mounted = true;
+ }
+ },
+ p(ctx, dirty) {
+ },
+ i: noop,
+ o: noop,
+ d(detaching) {
+ if (detaching) detach(div);
+ if (if_block) if_block.d();
+ mounted = false;
+ run_all(dispose);
+ }
+ };
+ }
+
+ // (114:0) {#if nip46URI}
+ function create_if_block$4(ctx) {
+ let p;
+ let t1;
+ let div;
+ let qr;
+ let t2;
+ let button;
+ let current;
+ let mounted;
+ let dispose;
+ qr = new QR({ props: { text: /*nip46URI*/ ctx[0] } });
+
+ return {
+ c() {
+ p = element("p");
+ p.textContent = "Scan this with your Nostr Connect (click to copy to clipboard)";
+ t1 = space();
+ div = element("div");
+ create_component(qr.$$.fragment);
+ t2 = space();
+ button = element("button");
+ button.textContent = "Cancel";
+ attr(p, "class", "text-gray-600 mb-3 svelte-8015tc");
+ attr(div, "class", "bg-white w-full p-3 svelte-8015tc");
+ attr(button, "class", "bg-purple-900 hover:bg-purple-700 w-full p-2 rounded-xl text-center font-regular text-white svelte-8015tc");
+ },
+ m(target, anchor) {
+ insert(target, p, anchor);
+ insert(target, t1, anchor);
+ insert(target, div, anchor);
+ mount_component(qr, div, null);
+ insert(target, t2, anchor);
+ insert(target, button, anchor);
+ current = true;
+
+ if (!mounted) {
+ dispose = [
+ listen(div, "click", prevent_default(/*Nip46Copy*/ ctx[4])),
+ listen(button, "click", prevent_default(/*click_handler*/ ctx[8]))
+ ];
+
+ mounted = true;
+ }
+ },
+ p(ctx, dirty) {
+ const qr_changes = {};
+ if (dirty & /*nip46URI*/ 1) qr_changes.text = /*nip46URI*/ ctx[0];
+ qr.$set(qr_changes);
+ },
+ i(local) {
+ if (current) return;
+ transition_in(qr.$$.fragment, local);
+ current = true;
+ },
+ o(local) {
+ transition_out(qr.$$.fragment, local);
+ current = false;
+ },
+ d(detaching) {
+ if (detaching) detach(p);
+ if (detaching) detach(t1);
+ if (detaching) detach(div);
+ destroy_component(qr);
+ if (detaching) detach(t2);
+ if (detaching) detach(button);
+ mounted = false;
+ run_all(dispose);
+ }
+ };
+ }
+
+ // (138:8) {#if hasNostrNip07}
+ function create_if_block_2$1(ctx) {
+ let button;
+ let mounted;
+ let dispose;
+
+ return {
+ c() {
+ button = element("button");
+ button.textContent = "Browser Extension (NIP-07)";
+ attr(button, "class", "bg-purple-900 hover:bg-purple-700 w-full p-4 rounded-xl text-center font-regular text-gray-200 svelte-8015tc");
+ },
+ m(target, anchor) {
+ insert(target, button, anchor);
+
+ if (!mounted) {
+ dispose = listen(button, "click", prevent_default(/*useNip07*/ ctx[1]));
+ mounted = true;
+ }
+ },
+ p: noop,
+ d(detaching) {
+ if (detaching) detach(button);
+ mounted = false;
+ dispose();
+ }
+ };
+ }
+
+ function create_fragment$4(ctx) {
+ let h1;
+ let t1;
+ let t2;
+ let current_block_type_index;
+ let if_block1;
+ let if_block1_anchor;
+ let current;
+ const if_block_creators = [create_if_block$4, create_if_block_1$3];
+ const if_blocks = [];
+
+ function select_block_type(ctx, dirty) {
+ if (/*nip46URI*/ ctx[0]) return 0;
+ return 1;
+ }
+
+ if (~(current_block_type_index = select_block_type(ctx))) {
+ if_block1 = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
+ }
+
+ return {
+ c() {
+ h1 = element("h1");
+ h1.textContent = "How would you like to connect?";
+ t1 = space();
+ t2 = space();
+ if (if_block1) if_block1.c();
+ if_block1_anchor = empty();
+ attr(h1, "class", "font-bold text-xl mb-3 svelte-8015tc");
+ },
+ m(target, anchor) {
+ insert(target, h1, anchor);
+ insert(target, t1, anchor);
+ insert(target, t2, anchor);
+
+ if (~current_block_type_index) {
+ if_blocks[current_block_type_index].m(target, anchor);
+ }
+
+ insert(target, if_block1_anchor, anchor);
+ current = true;
+ },
+ p(ctx, [dirty]) {
+ let previous_block_index = current_block_type_index;
+ current_block_type_index = select_block_type(ctx);
+
+ if (current_block_type_index === previous_block_index) {
+ if (~current_block_type_index) {
+ if_blocks[current_block_type_index].p(ctx, dirty);
+ }
+ } else {
+ if (if_block1) {
+ group_outros();
+
+ transition_out(if_blocks[previous_block_index], 1, 1, () => {
+ if_blocks[previous_block_index] = null;
+ });
+
+ check_outros();
+ }
+
+ if (~current_block_type_index) {
+ if_block1 = if_blocks[current_block_type_index];
+
+ if (!if_block1) {
+ if_block1 = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
+ if_block1.c();
+ } else {
+ if_block1.p(ctx, dirty);
+ }
+
+ transition_in(if_block1, 1);
+ if_block1.m(if_block1_anchor.parentNode, if_block1_anchor);
+ } else {
+ if_block1 = null;
+ }
+ }
+ },
+ i(local) {
+ if (current) return;
+ transition_in(if_block1);
+ current = true;
+ },
+ o(local) {
+ transition_out(if_block1);
+ current = false;
+ },
+ d(detaching) {
+ if (detaching) detach(h1);
+ if (detaching) detach(t1);
+ if (detaching) detach(t2);
+
+ if (~current_block_type_index) {
+ if_blocks[current_block_type_index].d(detaching);
+ }
+
+ if (detaching) detach(if_block1_anchor);
+ }
+ };
+ }
+
+ function instance$4($$self, $$props, $$invalidate) {
+ let { websiteOwnerPubkey } = $$props;
+ let { chatConfiguration } = $$props;
+ let { relays } = $$props;
+ let nip46URI;
+ let adapterConfig;
+
+ onMount(() => {
+ // hasNostrNip07 = !!window.nostr;
+ const type = localStorage.getItem('nostrichat-type');
+
+ if (type === 'nip07') {
+ useNip07();
+ } else if (type === 'nip-46') {
+ useNip46();
+ }
+
+ adapterConfig = {
+ type: chatConfiguration.chatType,
+ tags: chatConfiguration.chatTags,
+ referenceTags: chatConfiguration.chatReferenceTags,
+ websiteOwnerPubkey,
+ relays
+ };
+ });
+
+ function useNip07() {
+ window.nostr.getPublicKey().then(pubkey => {
+ localStorage.setItem('nostrichat-type', 'nip07');
+ chatAdapter.set(new NstrAdapterNip07(pubkey, adapterConfig));
+ });
+ }
+
+ async function useDiscardableKeys() {
+ chatAdapter.set(new NstrAdapterDiscadableKeys(adapterConfig));
+ }
+
+ async function useNip46() {
+ let key = localStorage.getItem('nostrichat-nostr-connect-key');
+ let publicKey = localStorage.getItem('nostrichat-nostr-connect-public-key');
+
+ if (key) {
+ chatAdapter.set(new NstrAdapterNip46(publicKey, key, adapterConfig));
+ return;
+ }
+
+ key = generatePrivateKey();
+
+ const connect = new Connect({
+ secretKey: key,
+ relay: 'wss://nostr.vulpem.com'
+ });
+
+ connect.events.on('connect', connectedPubKey => {
+ localStorage.setItem('nostrichat-nostr-connect-key', key);
+ localStorage.setItem('nostrichat-nostr-connect-public-key', connectedPubKey);
+ localStorage.setItem('nostrichat-type', 'nip-46');
+ console.log('connected to nostr connect relay');
+ publicKey = connectedPubKey;
+ chatAdapter.set(new NstrAdapterNip46(publicKey, key));
+ $$invalidate(0, nip46URI = null);
+ });
+
+ connect.events.on('disconnect', () => {
+ console.log('disconnected from nostr connect relay');
+ });
+
+ await connect.init();
+
+ const connectURI = new ConnectURI({
+ target: getPublicKey(key),
+ relay: 'wss://nostr.vulpem.com',
+ metadata: {
+ name: 'PSBT.io',
+ description: '🔉🔉🔉',
+ url: 'https://psbt.io',
+ icons: ['https://example.com/icon.png']
+ }
+ });
+
+ $$invalidate(0, nip46URI = connectURI.toString());
+ }
+
+ function Nip46Copy() {
+ navigator.clipboard.writeText(nip46URI);
+ }
+
+ const click_handler = () => {
+ $$invalidate(0, nip46URI = null);
+ };
+
+ $$self.$$set = $$props => {
+ if ('websiteOwnerPubkey' in $$props) $$invalidate(5, websiteOwnerPubkey = $$props.websiteOwnerPubkey);
+ if ('chatConfiguration' in $$props) $$invalidate(6, chatConfiguration = $$props.chatConfiguration);
+ if ('relays' in $$props) $$invalidate(7, relays = $$props.relays);
+ };
+
+ return [
+ nip46URI,
+ useNip07,
+ useDiscardableKeys,
+ useNip46,
+ Nip46Copy,
+ websiteOwnerPubkey,
+ chatConfiguration,
+ relays,
+ click_handler
+ ];
+ }
+
+ class KeyPrompt extends SvelteComponent {
+ constructor(options) {
+ super();
+
+ init(this, options, instance$4, create_fragment$4, safe_not_equal, {
+ websiteOwnerPubkey: 5,
+ chatConfiguration: 6,
+ relays: 7
+ });
+ }
+ }
+
+ /* src/NostrNote.svelte generated by Svelte v3.55.1 */
+
+ function get_each_context$1(ctx, list, i) {
+ const child_ctx = ctx.slice();
+ child_ctx[14] = list[i];
+ return child_ctx;
+ }
+
+ // (75:16) {:else}
+ function create_else_block$3(ctx) {
+ let div;
+ let t;
+
+ return {
+ c() {
+ div = element("div");
+ t = text(/*displayName*/ ctx[4]);
+ attr(div, "class", "text-xs text-gray-400 svelte-r5bhj7");
+ },
+ m(target, anchor) {
+ insert(target, div, anchor);
+ append(div, t);
+ },
+ p(ctx, dirty) {
+ if (dirty & /*displayName*/ 16) set_data(t, /*displayName*/ ctx[4]);
+ },
+ d(detaching) {
+ if (detaching) detach(div);
+ }
+ };
+ }
+
+ // (71:16) {#if byWebsiteOwner}
+ function create_if_block_1$2(ctx) {
+ let div;
+
+ return {
+ c() {
+ div = element("div");
+ div.textContent = "Website owner";
+ attr(div, "class", "text-purple-500 text-xs svelte-r5bhj7");
+ },
+ m(target, anchor) {
+ insert(target, div, anchor);
+ },
+ p: noop,
+ d(detaching) {
+ if (detaching) detach(div);
+ }
+ };
+ }
+
+ // (85:0) {#if responses[event.id].length > 0}
+ function create_if_block$3(ctx) {
+ let div;
+ let current;
+ let each_value = /*responses*/ ctx[1][/*event*/ ctx[0].id];
+ let each_blocks = [];
+
+ for (let i = 0; i < each_value.length; i += 1) {
+ each_blocks[i] = create_each_block$1(get_each_context$1(ctx, each_value, i));
+ }
+
+ const out = i => transition_out(each_blocks[i], 1, 1, () => {
+ each_blocks[i] = null;
+ });
+
+ return {
+ c() {
+ div = element("div");
+
+ for (let i = 0; i < each_blocks.length; i += 1) {
+ each_blocks[i].c();
+ }
+
+ attr(div, "class", "pl-5 border-l border-l-gray-400 mb-10 svelte-r5bhj7");
+ },
+ m(target, anchor) {
+ insert(target, div, anchor);
+
+ for (let i = 0; i < each_blocks.length; i += 1) {
+ each_blocks[i].m(div, null);
+ }
+
+ current = true;
+ },
+ p(ctx, dirty) {
+ if (dirty & /*websiteOwnerPubkey, responses, event*/ 7) {
+ each_value = /*responses*/ ctx[1][/*event*/ ctx[0].id];
+ let i;
+
+ for (i = 0; i < each_value.length; i += 1) {
+ const child_ctx = get_each_context$1(ctx, each_value, i);
+
+ if (each_blocks[i]) {
+ each_blocks[i].p(child_ctx, dirty);
+ transition_in(each_blocks[i], 1);
+ } else {
+ each_blocks[i] = create_each_block$1(child_ctx);
+ each_blocks[i].c();
+ transition_in(each_blocks[i], 1);
+ each_blocks[i].m(div, null);
+ }
+ }
+
+ group_outros();
+
+ for (i = each_value.length; i < each_blocks.length; i += 1) {
+ out(i);
+ }
+
+ check_outros();
+ }
+ },
+ i(local) {
+ if (current) return;
+
+ for (let i = 0; i < each_value.length; i += 1) {
+ transition_in(each_blocks[i]);
+ }
+
+ current = true;
+ },
+ o(local) {
+ each_blocks = each_blocks.filter(Boolean);
+
+ for (let i = 0; i < each_blocks.length; i += 1) {
+ transition_out(each_blocks[i]);
+ }
+
+ current = false;
+ },
+ d(detaching) {
+ if (detaching) detach(div);
+ destroy_each(each_blocks, detaching);
+ }
+ };
+ }
+
+ // (87:8) {#each responses[event.id] as response}
+ function create_each_block$1(ctx) {
+ let nostrnote;
+ let current;
+
+ nostrnote = new NostrNote({
+ props: {
+ websiteOwnerPubkey: /*websiteOwnerPubkey*/ ctx[2],
+ event: /*response*/ ctx[14],
+ responses: /*responses*/ ctx[1]
+ }
+ });
+
+ return {
+ c() {
+ create_component(nostrnote.$$.fragment);
+ },
+ m(target, anchor) {
+ mount_component(nostrnote, target, anchor);
+ current = true;
+ },
+ p(ctx, dirty) {
+ const nostrnote_changes = {};
+ if (dirty & /*websiteOwnerPubkey*/ 4) nostrnote_changes.websiteOwnerPubkey = /*websiteOwnerPubkey*/ ctx[2];
+ if (dirty & /*responses, event*/ 3) nostrnote_changes.event = /*response*/ ctx[14];
+ if (dirty & /*responses*/ 2) nostrnote_changes.responses = /*responses*/ ctx[1];
+ nostrnote.$set(nostrnote_changes);
+ },
+ i(local) {
+ if (current) return;
+ transition_in(nostrnote.$$.fragment, local);
+ current = true;
+ },
+ o(local) {
+ transition_out(nostrnote.$$.fragment, local);
+ current = false;
+ },
+ d(detaching) {
+ destroy_component(nostrnote, detaching);
+ }
+ };
+ }
+
+ function create_fragment$3(ctx) {
+ let div7;
+ let div6;
+ let div0;
+ let img;
+ let img_src_value;
+ let t0;
+ let div5;
+ let div1;
+ let t1;
+ let div2;
+ let t2_value = /*event*/ ctx[0].content + "";
+ let t2;
+ let div2_class_value;
+ let t3;
+ let div4;
+ let div3;
+ let span;
+ let t5;
+ let t6;
+ let if_block1_anchor;
+ let current;
+ let mounted;
+ let dispose;
+
+ function select_block_type(ctx, dirty) {
+ if (/*byWebsiteOwner*/ ctx[7]) return create_if_block_1$2;
+ return create_else_block$3;
+ }
+
+ let current_block_type = select_block_type(ctx);
+ let if_block0 = current_block_type(ctx);
+ let if_block1 = /*responses*/ ctx[1][/*event*/ ctx[0].id].length > 0 && create_if_block$3(ctx);
+
+ return {
+ c() {
+ div7 = element("div");
+ div6 = element("div");
+ div0 = element("div");
+ img = element("img");
+ t0 = space();
+ div5 = element("div");
+ div1 = element("div");
+ t1 = space();
+ div2 = element("div");
+ t2 = text(t2_value);
+ t3 = space();
+ div4 = element("div");
+ div3 = element("div");
+ span = element("span");
+ span.textContent = `${/*timestamp*/ ctx[8].toLocaleString()}`;
+ t5 = space();
+ if_block0.c();
+ t6 = space();
+ if (if_block1) if_block1.c();
+ if_block1_anchor = empty();
+ if (!src_url_equal(img.src, img_src_value = /*profilePicture*/ ctx[3])) attr(img, "src", img_src_value);
+
+ attr(img, "class", "block w-10 h-10 rounded-full " + (/*byWebsiteOwner*/ ctx[7]
+ ? 'ring-purple-700 ring-4'
+ : 'ring-gray-300 ring-2') + "" + " svelte-r5bhj7");
+
+ attr(img, "alt", "");
+ attr(div0, "class", "min-w-fit svelte-r5bhj7");
+ attr(div1, "class", "flex flex-row justify-between text-center overflow-clip text-clip w-full svelte-r5bhj7");
+
+ attr(div2, "class", div2_class_value = "max-h-64 text-base cursor-pointer border border-slate-200 " + (/*$selectedMessage*/ ctx[5] === /*event*/ ctx[0].id
+ ? 'bg-purple-700 text-white'
+ : 'bg-slate-50 text-gray-500 hover:bg-slate-100') + " p-4 py-2 overflow-scroll rounded-2xl" + " svelte-r5bhj7");
+
+ attr(span, "class", "py-2 svelte-r5bhj7");
+ attr(div3, "class", "text-xs text-gray-400 text-ellipsis overflow-clip whitespace-nowrap svelte-r5bhj7");
+ attr(div4, "class", "flex flex-row-reverse justify-between mt-1 overflow-clip items-center svelte-r5bhj7");
+ attr(div5, "class", "w-full overflow-hidden svelte-r5bhj7");
+ attr(div6, "class", "flex flex-row gap-4 svelte-r5bhj7");
+ attr(div7, "class", "block p-2-lg mb-3 text-wrap svelte-r5bhj7");
+ },
+ m(target, anchor) {
+ insert(target, div7, anchor);
+ append(div7, div6);
+ append(div6, div0);
+ append(div0, img);
+ append(div6, t0);
+ append(div6, div5);
+ append(div5, div1);
+ append(div5, t1);
+ append(div5, div2);
+ append(div2, t2);
+ append(div5, t3);
+ append(div5, div4);
+ append(div4, div3);
+ append(div3, span);
+ append(div4, t5);
+ if_block0.m(div4, null);
+ insert(target, t6, anchor);
+ if (if_block1) if_block1.m(target, anchor);
+ insert(target, if_block1_anchor, anchor);
+ current = true;
+
+ if (!mounted) {
+ dispose = listen(div2, "click", prevent_default(/*click_handler*/ ctx[11]));
+ mounted = true;
+ }
+ },
+ p(ctx, [dirty]) {
+ if (!current || dirty & /*profilePicture*/ 8 && !src_url_equal(img.src, img_src_value = /*profilePicture*/ ctx[3])) {
+ attr(img, "src", img_src_value);
+ }
+
+ if ((!current || dirty & /*event*/ 1) && t2_value !== (t2_value = /*event*/ ctx[0].content + "")) set_data(t2, t2_value);
+
+ if (!current || dirty & /*$selectedMessage, event*/ 33 && div2_class_value !== (div2_class_value = "max-h-64 text-base cursor-pointer border border-slate-200 " + (/*$selectedMessage*/ ctx[5] === /*event*/ ctx[0].id
+ ? 'bg-purple-700 text-white'
+ : 'bg-slate-50 text-gray-500 hover:bg-slate-100') + " p-4 py-2 overflow-scroll rounded-2xl" + " svelte-r5bhj7")) {
+ attr(div2, "class", div2_class_value);
+ }
+
+ if_block0.p(ctx, dirty);
+
+ if (/*responses*/ ctx[1][/*event*/ ctx[0].id].length > 0) {
+ if (if_block1) {
+ if_block1.p(ctx, dirty);
+
+ if (dirty & /*responses, event*/ 3) {
+ transition_in(if_block1, 1);
+ }
+ } else {
+ if_block1 = create_if_block$3(ctx);
+ if_block1.c();
+ transition_in(if_block1, 1);
+ if_block1.m(if_block1_anchor.parentNode, if_block1_anchor);
+ }
+ } else if (if_block1) {
+ group_outros();
+
+ transition_out(if_block1, 1, 1, () => {
+ if_block1 = null;
+ });
+
+ check_outros();
+ }
+ },
+ i(local) {
+ if (current) return;
+ transition_in(if_block1);
+ current = true;
+ },
+ o(local) {
+ transition_out(if_block1);
+ current = false;
+ },
+ d(detaching) {
+ if (detaching) detach(div7);
+ if_block0.d();
+ if (detaching) detach(t6);
+ if (if_block1) if_block1.d(detaching);
+ if (detaching) detach(if_block1_anchor);
+ mounted = false;
+ dispose();
+ }
+ };
+ }
+
+ function instance$3($$self, $$props, $$invalidate) {
+ let displayName;
+ let $chatData;
+ let $selectedMessage;
+ component_subscribe($$self, chatData, $$value => $$invalidate(10, $chatData = $$value));
+ component_subscribe($$self, selectedMessage, $$value => $$invalidate(5, $selectedMessage = $$value));
+ let { event } = $$props;
+ let { responses } = $$props;
+ let { websiteOwnerPubkey } = $$props;
+ let profiles = {};
+ let profilePicture;
+
+ function selectMessage() {
+ if ($selectedMessage === event.id) {
+ set_store_value(selectedMessage, $selectedMessage = null, $selectedMessage);
+ } else {
+ set_store_value(selectedMessage, $selectedMessage = event.id, $selectedMessage);
+ }
+ }
+
+ const byWebsiteOwner = !!websiteOwnerPubkey === event.pubkey;
+ event.tags.filter(e => e[0] === 'e').map(e => e[1]);
+ let timestamp = new Date(event.created_at * 1000);
+
+ const click_handler = () => {
+ selectMessage(event.id);
+ };
+
+ $$self.$$set = $$props => {
+ if ('event' in $$props) $$invalidate(0, event = $$props.event);
+ if ('responses' in $$props) $$invalidate(1, responses = $$props.responses);
+ if ('websiteOwnerPubkey' in $$props) $$invalidate(2, websiteOwnerPubkey = $$props.websiteOwnerPubkey);
+ };
+
+ $$self.$$.update = () => {
+ if ($$self.$$.dirty & /*$chatData*/ 1024) {
+ $$invalidate(9, profiles = $chatData.profiles);
+ }
+
+ if ($$self.$$.dirty & /*profiles, event*/ 513) {
+ $$invalidate(4, displayName = profiles[event.pubkey] && profiles[event.pubkey].display_name || event.pubkey);
+ }
+
+ if ($$self.$$.dirty & /*profiles, event*/ 513) {
+ profiles[event.pubkey] && profiles[event.pubkey].nip05;
+ }
+
+ if ($$self.$$.dirty & /*profiles, event*/ 513) {
+ $$invalidate(3, profilePicture = profiles[event.pubkey] && profiles[event.pubkey].picture || `https://robohash.org/${event.pubkey}.png?set=set1`);
+ }
+ };
+
+ return [
+ event,
+ responses,
+ websiteOwnerPubkey,
+ profilePicture,
+ displayName,
+ $selectedMessage,
+ selectMessage,
+ byWebsiteOwner,
+ timestamp,
+ profiles,
+ $chatData,
+ click_handler
+ ];
+ }
+
+ class NostrNote extends SvelteComponent {
+ constructor(options) {
+ super();
+
+ init(this, options, instance$3, create_fragment$3, safe_not_equal, {
+ event: 0,
+ responses: 1,
+ websiteOwnerPubkey: 2
+ });
+ }
+ }
+
+ function cubicInOut(t) {
+ return t < 0.5 ? 4.0 * t * t * t : 0.5 * Math.pow(2.0 * t - 2.0, 3.0) + 1.0;
+ }
+
+ var _ = {
+ $(selector) {
+ if (typeof selector === "string") {
+ return document.querySelector(selector);
+ }
+ return selector;
+ },
+ extend(...args) {
+ return Object.assign(...args);
+ },
+ cumulativeOffset(element) {
+ let top = 0;
+ let left = 0;
+
+ do {
+ top += element.offsetTop || 0;
+ left += element.offsetLeft || 0;
+ element = element.offsetParent;
+ } while (element);
+
+ return {
+ top: top,
+ left: left
+ };
+ },
+ directScroll(element) {
+ return element && element !== document && element !== document.body;
+ },
+ scrollTop(element, value) {
+ let inSetter = value !== undefined;
+ if (this.directScroll(element)) {
+ return inSetter ? (element.scrollTop = value) : element.scrollTop;
+ } else {
+ return inSetter
+ ? (document.documentElement.scrollTop = document.body.scrollTop = value)
+ : window.pageYOffset ||
+ document.documentElement.scrollTop ||
+ document.body.scrollTop ||
+ 0;
+ }
+ },
+ scrollLeft(element, value) {
+ let inSetter = value !== undefined;
+ if (this.directScroll(element)) {
+ return inSetter ? (element.scrollLeft = value) : element.scrollLeft;
+ } else {
+ return inSetter
+ ? (document.documentElement.scrollLeft = document.body.scrollLeft = value)
+ : window.pageXOffset ||
+ document.documentElement.scrollLeft ||
+ document.body.scrollLeft ||
+ 0;
+ }
+ }
+ };
+
+ const defaultOptions = {
+ container: "body",
+ duration: 500,
+ delay: 0,
+ offset: 0,
+ easing: cubicInOut,
+ onStart: noop,
+ onDone: noop,
+ onAborting: noop,
+ scrollX: false,
+ scrollY: true
+ };
+
+ const _scrollTo = options => {
+ let {
+ offset,
+ duration,
+ delay,
+ easing,
+ x=0,
+ y=0,
+ scrollX,
+ scrollY,
+ onStart,
+ onDone,
+ container,
+ onAborting,
+ element
+ } = options;
+
+ if (typeof offset === "function") {
+ offset = offset();
+ }
+
+ var cumulativeOffsetContainer = _.cumulativeOffset(container);
+ var cumulativeOffsetTarget = element
+ ? _.cumulativeOffset(element)
+ : { top: y, left: x };
+
+ var initialX = _.scrollLeft(container);
+ var initialY = _.scrollTop(container);
+
+ var targetX =
+ cumulativeOffsetTarget.left - cumulativeOffsetContainer.left + offset;
+ var targetY =
+ cumulativeOffsetTarget.top - cumulativeOffsetContainer.top + offset;
+
+ var diffX = targetX - initialX;
+ var diffY = targetY - initialY;
+
+ let scrolling = true;
+ let started = false;
+ let start_time = now$1() + delay;
+ let end_time = start_time + duration;
+
+ function scrollToTopLeft(element, top, left) {
+ if (scrollX) _.scrollLeft(element, left);
+ if (scrollY) _.scrollTop(element, top);
+ }
+
+ function start(delayStart) {
+ if (!delayStart) {
+ started = true;
+ onStart(element, {x, y});
+ }
+ }
+
+ function tick(progress) {
+ scrollToTopLeft(
+ container,
+ initialY + diffY * progress,
+ initialX + diffX * progress
+ );
+ }
+
+ function stop() {
+ scrolling = false;
+ }
+
+ loop(now => {
+ if (!started && now >= start_time) {
+ start(false);
+ }
+
+ if (started && now >= end_time) {
+ tick(1);
+ stop();
+ onDone(element, {x, y});
+ }
+
+ if (!scrolling) {
+ onAborting(element, {x, y});
+ return false;
+ }
+ if (started) {
+ const p = now - start_time;
+ const t = 0 + 1 * easing(p / duration);
+ tick(t);
+ }
+
+ return true;
+ });
+
+ start(delay);
+
+ tick(0);
+
+ return stop;
+ };
+
+ const proceedOptions = options => {
+ let opts = _.extend({}, defaultOptions, options);
+ opts.container = _.$(opts.container);
+ opts.element = _.$(opts.element);
+ return opts;
+ };
+
+ const scrollContainerHeight = containerElement => {
+ if (
+ containerElement &&
+ containerElement !== document &&
+ containerElement !== document.body
+ ) {
+ return containerElement.scrollHeight - containerElement.offsetHeight;
+ } else {
+ let body = document.body;
+ let html = document.documentElement;
+
+ return Math.max(
+ body.scrollHeight,
+ body.offsetHeight,
+ html.clientHeight,
+ html.scrollHeight,
+ html.offsetHeight
+ );
+ }
+ };
+
+ const scrollToBottom = options => {
+ options = proceedOptions(options);
+
+ return _scrollTo(
+ _.extend(options, {
+ element: null,
+ y: scrollContainerHeight(options.container)
+ })
+ );
+ };
+
+ /* src/ConnectedWidget.svelte generated by Svelte v3.55.1 */
+
+ function get_each_context(ctx, list, i) {
+ const child_ctx = ctx.slice();
+ child_ctx[21] = list[i];
+ return child_ctx;
+ }
+
+ function get_each_context_1(ctx, list, i) {
+ const child_ctx = ctx.slice();
+ child_ctx[24] = list[i];
+ child_ctx[26] = i;
+ return child_ctx;
+ }
+
+ // (196:8) {#if $chatAdapter?.pubkey}
+ function create_if_block_5(ctx) {
+ let t_value = (/*profiles*/ ctx[5][/*$chatAdapter*/ ctx[2].pubkey]?.display_name || /*$chatAdapter*/ ctx[2].pubkey) + "";
+ let t;
+
+ return {
+ c() {
+ t = text(t_value);
+ },
+ m(target, anchor) {
+ insert(target, t, anchor);
+ },
+ p(ctx, dirty) {
+ if (dirty & /*profiles, $chatAdapter*/ 36 && t_value !== (t_value = (/*profiles*/ ctx[5][/*$chatAdapter*/ ctx[2].pubkey]?.display_name || /*$chatAdapter*/ ctx[2].pubkey) + "")) set_data(t, t_value);
+ },
+ d(detaching) {
+ if (detaching) detach(t);
+ }
+ };
+ }
+
+ // (203:12) {#each Array(totalRelays) as _, i}
+ function create_each_block_1(ctx) {
+ let span;
+ let span_class_value;
+
+ return {
+ c() {
+ span = element("span");
+
+ attr(span, "class", span_class_value = "inline-block rounded-full " + (/*connectedRelays*/ ctx[6] > /*i*/ ctx[26]
+ ? 'bg-green-500'
+ : 'bg-gray-300') + " w-2 h-2" + " svelte-v3rae1");
+ },
+ m(target, anchor) {
+ insert(target, span, anchor);
+ },
+ p(ctx, dirty) {
+ if (dirty & /*connectedRelays*/ 64 && span_class_value !== (span_class_value = "inline-block rounded-full " + (/*connectedRelays*/ ctx[6] > /*i*/ ctx[26]
+ ? 'bg-green-500'
+ : 'bg-gray-300') + " w-2 h-2" + " svelte-v3rae1")) {
+ attr(span, "class", span_class_value);
+ }
+ },
+ d(detaching) {
+ if (detaching) detach(span);
+ }
+ };
+ }
+
+ // (217:0) {#if $selectedMessage}
+ function create_if_block_3(ctx) {
+ let show_if;
+ let if_block_anchor;
+
+ function select_block_type(ctx, dirty) {
+ if (dirty & /*$selectedMessage*/ 256) show_if = null;
+ if (show_if == null) show_if = !!!/*getEventById*/ ctx[9](/*$selectedMessage*/ ctx[8]);
+ if (show_if) return create_if_block_4;
+ return create_else_block_2;
+ }
+
+ let current_block_type = select_block_type(ctx, -1);
+ let if_block = current_block_type(ctx);
+
+ return {
+ c() {
+ if_block.c();
+ if_block_anchor = empty();
+ },
+ m(target, anchor) {
+ if_block.m(target, anchor);
+ insert(target, if_block_anchor, anchor);
+ },
+ p(ctx, dirty) {
+ if (current_block_type === (current_block_type = select_block_type(ctx, dirty)) && if_block) {
+ if_block.p(ctx, dirty);
+ } else {
+ if_block.d(1);
+ if_block = current_block_type(ctx);
+
+ if (if_block) {
+ if_block.c();
+ if_block.m(if_block_anchor.parentNode, if_block_anchor);
+ }
+ }
+ },
+ d(detaching) {
+ if_block.d(detaching);
+ if (detaching) detach(if_block_anchor);
+ }
+ };
+ }
+
+ // (220:4) {:else}
+ function create_else_block_2(ctx) {
+ let div1;
+ let a;
+ let t0;
+ let div0;
+ let span;
+ let t1_value = /*getEventById*/ ctx[9](/*$selectedMessage*/ ctx[8]).content + "";
+ let t1;
+ let mounted;
+ let dispose;
+
+ return {
+ c() {
+ div1 = element("div");
+ a = element("a");
+ a.innerHTML = ``;
+ t0 = space();
+ div0 = element("div");
+ span = element("span");
+ t1 = text(t1_value);
+ attr(a, "href", "#");
+ attr(a, "class", "svelte-v3rae1");
+ attr(span, "class", "text-lg text-black overflow-hidden whitespace-nowrap text-ellipsis svelte-v3rae1");
+ attr(div0, "class", "flex flex-col ml-2 svelte-v3rae1");
+ attr(div1, "class", "flex flex-row mb-3 svelte-v3rae1");
+ },
+ m(target, anchor) {
+ insert(target, div1, anchor);
+ append(div1, a);
+ append(div1, t0);
+ append(div1, div0);
+ append(div0, span);
+ append(span, t1);
+
+ if (!mounted) {
+ dispose = listen(a, "click", prevent_default(/*selectParent*/ ctx[12]));
+ mounted = true;
+ }
+ },
+ p(ctx, dirty) {
+ if (dirty & /*$selectedMessage*/ 256 && t1_value !== (t1_value = /*getEventById*/ ctx[9](/*$selectedMessage*/ ctx[8]).content + "")) set_data(t1, t1_value);
+ },
+ d(detaching) {
+ if (detaching) detach(div1);
+ mounted = false;
+ dispose();
+ }
+ };
+ }
+
+ // (218:4) {#if !getEventById($selectedMessage)}
+ function create_if_block_4(ctx) {
+ let h1;
+ let t0;
+ let t1;
+
+ return {
+ c() {
+ h1 = element("h1");
+ t0 = text("Couldn't find event with ID ");
+ t1 = text(/*$selectedMessage*/ ctx[8]);
+ attr(h1, "class", "svelte-v3rae1");
+ },
+ m(target, anchor) {
+ insert(target, h1, anchor);
+ append(h1, t0);
+ append(h1, t1);
+ },
+ p(ctx, dirty) {
+ if (dirty & /*$selectedMessage*/ 256) set_data(t1, /*$selectedMessage*/ ctx[8]);
+ },
+ d(detaching) {
+ if (detaching) detach(h1);
+ }
+ };
+ }
+
+ // (240:4) {:else}
+ function create_else_block_1(ctx) {
+ let each_1_anchor;
+ let current;
+ let each_value = /*events*/ ctx[3];
+ let each_blocks = [];
+
+ for (let i = 0; i < each_value.length; i += 1) {
+ each_blocks[i] = create_each_block(get_each_context(ctx, each_value, i));
+ }
+
+ const out = i => transition_out(each_blocks[i], 1, 1, () => {
+ each_blocks[i] = null;
+ });
+
+ return {
+ c() {
+ for (let i = 0; i < each_blocks.length; i += 1) {
+ each_blocks[i].c();
+ }
+
+ each_1_anchor = empty();
+ },
+ m(target, anchor) {
+ for (let i = 0; i < each_blocks.length; i += 1) {
+ each_blocks[i].m(target, anchor);
+ }
+
+ insert(target, each_1_anchor, anchor);
+ current = true;
+ },
+ p(ctx, dirty) {
+ if (dirty & /*events, responses, websiteOwnerPubkey*/ 25) {
+ each_value = /*events*/ ctx[3];
+ let i;
+
+ for (i = 0; i < each_value.length; i += 1) {
+ const child_ctx = get_each_context(ctx, each_value, i);
+
+ if (each_blocks[i]) {
+ each_blocks[i].p(child_ctx, dirty);
+ transition_in(each_blocks[i], 1);
+ } else {
+ each_blocks[i] = create_each_block(child_ctx);
+ each_blocks[i].c();
+ transition_in(each_blocks[i], 1);
+ each_blocks[i].m(each_1_anchor.parentNode, each_1_anchor);
+ }
+ }
+
+ group_outros();
+
+ for (i = each_value.length; i < each_blocks.length; i += 1) {
+ out(i);
+ }
+
+ check_outros();
+ }
+ },
+ i(local) {
+ if (current) return;
+
+ for (let i = 0; i < each_value.length; i += 1) {
+ transition_in(each_blocks[i]);
+ }
+
+ current = true;
+ },
+ o(local) {
+ each_blocks = each_blocks.filter(Boolean);
+
+ for (let i = 0; i < each_blocks.length; i += 1) {
+ transition_out(each_blocks[i]);
+ }
+
+ current = false;
+ },
+ d(detaching) {
+ destroy_each(each_blocks, detaching);
+ if (detaching) detach(each_1_anchor);
+ }
+ };
+ }
+
+ // (238:4) {#if $selectedMessage}
+ function create_if_block_1$1(ctx) {
+ let nostrnote;
+ let current;
+
+ nostrnote = new NostrNote({
+ props: {
+ event: /*getEventById*/ ctx[9](/*$selectedMessage*/ ctx[8]),
+ responses: /*responses*/ ctx[4],
+ websiteOwnerPubkey: /*websiteOwnerPubkey*/ ctx[0]
+ }
+ });
+
+ return {
+ c() {
+ create_component(nostrnote.$$.fragment);
+ },
+ m(target, anchor) {
+ mount_component(nostrnote, target, anchor);
+ current = true;
+ },
+ p(ctx, dirty) {
+ const nostrnote_changes = {};
+ if (dirty & /*$selectedMessage*/ 256) nostrnote_changes.event = /*getEventById*/ ctx[9](/*$selectedMessage*/ ctx[8]);
+ if (dirty & /*responses*/ 16) nostrnote_changes.responses = /*responses*/ ctx[4];
+ if (dirty & /*websiteOwnerPubkey*/ 1) nostrnote_changes.websiteOwnerPubkey = /*websiteOwnerPubkey*/ ctx[0];
+ nostrnote.$set(nostrnote_changes);
+ },
+ i(local) {
+ if (current) return;
+ transition_in(nostrnote.$$.fragment, local);
+ current = true;
+ },
+ o(local) {
+ transition_out(nostrnote.$$.fragment, local);
+ current = false;
+ },
+ d(detaching) {
+ destroy_component(nostrnote, detaching);
+ }
+ };
+ }
+
+ // (243:12) {#if event.deleted}
+ function create_if_block_2(ctx) {
+ let t;
+
+ return {
+ c() {
+ t = text("👆 deleted");
+ },
+ m(target, anchor) {
+ insert(target, t, anchor);
+ },
+ d(detaching) {
+ if (detaching) detach(t);
+ }
+ };
+ }
+
+ // (241:8) {#each events as event}
+ function create_each_block(ctx) {
+ let nostrnote;
+ let t;
+ let if_block_anchor;
+ let current;
+
+ nostrnote = new NostrNote({
+ props: {
+ event: /*event*/ ctx[21],
+ responses: /*responses*/ ctx[4],
+ websiteOwnerPubkey: /*websiteOwnerPubkey*/ ctx[0]
+ }
+ });
+
+ let if_block = /*event*/ ctx[21].deleted && create_if_block_2();
+
+ return {
+ c() {
+ create_component(nostrnote.$$.fragment);
+ t = space();
+ if (if_block) if_block.c();
+ if_block_anchor = empty();
+ },
+ m(target, anchor) {
+ mount_component(nostrnote, target, anchor);
+ insert(target, t, anchor);
+ if (if_block) if_block.m(target, anchor);
+ insert(target, if_block_anchor, anchor);
+ current = true;
+ },
+ p(ctx, dirty) {
+ const nostrnote_changes = {};
+ if (dirty & /*events*/ 8) nostrnote_changes.event = /*event*/ ctx[21];
+ if (dirty & /*responses*/ 16) nostrnote_changes.responses = /*responses*/ ctx[4];
+ if (dirty & /*websiteOwnerPubkey*/ 1) nostrnote_changes.websiteOwnerPubkey = /*websiteOwnerPubkey*/ ctx[0];
+ nostrnote.$set(nostrnote_changes);
+
+ if (/*event*/ ctx[21].deleted) {
+ if (if_block) ; else {
+ if_block = create_if_block_2();
+ if_block.c();
+ if_block.m(if_block_anchor.parentNode, if_block_anchor);
+ }
+ } else if (if_block) {
+ if_block.d(1);
+ if_block = null;
+ }
+ },
+ i(local) {
+ if (current) return;
+ transition_in(nostrnote.$$.fragment, local);
+ current = true;
+ },
+ o(local) {
+ transition_out(nostrnote.$$.fragment, local);
+ current = false;
+ },
+ d(detaching) {
+ destroy_component(nostrnote, detaching);
+ if (detaching) detach(t);
+ if (if_block) if_block.d(detaching);
+ if (detaching) detach(if_block_anchor);
+ }
+ };
+ }
+
+ // (260:8) {:else}
+ function create_else_block$2(ctx) {
+ let b;
+ let t1;
+
+ return {
+ c() {
+ b = element("b");
+ b.textContent = "Public chat:";
+ t1 = text("\n anyone can see these messages.");
+ attr(b, "class", "svelte-v3rae1");
+ },
+ m(target, anchor) {
+ insert(target, b, anchor);
+ insert(target, t1, anchor);
+ },
+ d(detaching) {
+ if (detaching) detach(b);
+ if (detaching) detach(t1);
+ }
+ };
+ }
+
+ // (257:8) {#if chatConfiguration.chatType === 'DM'}
+ function create_if_block$2(ctx) {
+ let b;
+ let t1;
+
+ return {
+ c() {
+ b = element("b");
+ b.textContent = "Encrypted chat:";
+ t1 = text("\n only your chat partner can see these messages.");
+ attr(b, "class", "svelte-v3rae1");
+ },
+ m(target, anchor) {
+ insert(target, b, anchor);
+ insert(target, t1, anchor);
+ },
+ d(detaching) {
+ if (detaching) detach(b);
+ if (detaching) detach(t1);
+ }
+ };
+ }
+
+ function create_fragment$2(ctx) {
+ let div2;
+ let div0;
+ let t0;
+ let span;
+ let div1;
+ let t1;
+ let t2;
+ let t3;
+ let t4;
+ let t5;
+ let t6;
+ let t7;
+ let div3;
+ let current_block_type_index;
+ let if_block2;
+ let t8;
+ let div6;
+ let div4;
+ let t9;
+ let div5;
+ let textarea;
+ let t10;
+ let button;
+ let current;
+ let mounted;
+ let dispose;
+ let if_block0 = /*$chatAdapter*/ ctx[2]?.pubkey && create_if_block_5(ctx);
+ let each_value_1 = Array(/*totalRelays*/ ctx[7]);
+ let each_blocks = [];
+
+ for (let i = 0; i < each_value_1.length; i += 1) {
+ each_blocks[i] = create_each_block_1(get_each_context_1(ctx, each_value_1, i));
+ }
+
+ let if_block1 = /*$selectedMessage*/ ctx[8] && create_if_block_3(ctx);
+ const if_block_creators = [create_if_block_1$1, create_else_block_1];
+ const if_blocks = [];
+
+ function select_block_type_1(ctx, dirty) {
+ if (/*$selectedMessage*/ ctx[8]) return 0;
+ return 1;
+ }
+
+ current_block_type_index = select_block_type_1(ctx);
+ if_block2 = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
+
+ function select_block_type_2(ctx, dirty) {
+ if (/*chatConfiguration*/ ctx[1].chatType === 'DM') return create_if_block$2;
+ return create_else_block$2;
+ }
+
+ let current_block_type = select_block_type_2(ctx);
+ let if_block3 = current_block_type(ctx);
+
+ return {
+ c() {
+ div2 = element("div");
+ div0 = element("div");
+ if (if_block0) if_block0.c();
+ t0 = space();
+ span = element("span");
+ div1 = element("div");
+
+ for (let i = 0; i < each_blocks.length; i += 1) {
+ each_blocks[i].c();
+ }
+
+ t1 = space();
+ t2 = text(/*connectedRelays*/ ctx[6]);
+ t3 = text("/");
+ t4 = text(/*totalRelays*/ ctx[7]);
+ t5 = text(" relays");
+ t6 = space();
+ if (if_block1) if_block1.c();
+ t7 = space();
+ div3 = element("div");
+ if_block2.c();
+ t8 = space();
+ div6 = element("div");
+ div4 = element("div");
+ if_block3.c();
+ t9 = space();
+ div5 = element("div");
+ textarea = element("textarea");
+ t10 = space();
+ button = element("button");
+ button.innerHTML = ``;
+ attr(div0, "class", "text-lg font-semibold svelte-v3rae1");
+ attr(div1, "class", "flex flex-row gap-1 overflow-clip svelte-v3rae1");
+ attr(span, "class", "text-xs flex flex-col items-end mt-2 text-gray-200 gap-1 svelte-v3rae1");
+ attr(div2, "class", "bg-purple-700 text-white -m-5 mb-3 px-5 py-3 overflow-clip flex flex-row justify-between items-center svelte-v3rae1");
+ attr(div3, "id", "messages-container");
+ attr(div3, "class", "overflow-scroll svelte-v3rae1");
+ attr(div4, "class", "border-y border-y-slate-200 -mx-5 my-2 bg-slate-100 text-black text-sm px-5 py-2 svelte-v3rae1");
+ attr(textarea, "type", "text");
+ attr(textarea, "id", "message-input");
+ attr(textarea, "class", "-mb-2 p-2 w-full resize-none rounded-xl text-gray-600 border svelte-v3rae1");
+ attr(textarea, "placeholder", "Say hello!");
+ attr(textarea, "rows", "1");
+ attr(button, "type", "button");
+ attr(button, "class", "inline-flex items-center rounded-full border border-transparent bg-purple-700 p-3 text-white shadow-sm hover:bg-purple-600 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2 svelte-v3rae1");
+ attr(div5, "class", "flex flex-row gap-2 -mx-1 svelte-v3rae1");
+ attr(div6, "class", "flex flex-col svelte-v3rae1");
+ },
+ m(target, anchor) {
+ insert(target, div2, anchor);
+ append(div2, div0);
+ if (if_block0) if_block0.m(div0, null);
+ append(div2, t0);
+ append(div2, span);
+ append(span, div1);
+
+ for (let i = 0; i < each_blocks.length; i += 1) {
+ each_blocks[i].m(div1, null);
+ }
+
+ append(span, t1);
+ append(span, t2);
+ append(span, t3);
+ append(span, t4);
+ append(span, t5);
+ insert(target, t6, anchor);
+ if (if_block1) if_block1.m(target, anchor);
+ insert(target, t7, anchor);
+ insert(target, div3, anchor);
+ if_blocks[current_block_type_index].m(div3, null);
+ insert(target, t8, anchor);
+ insert(target, div6, anchor);
+ append(div6, div4);
+ if_block3.m(div4, null);
+ append(div6, t9);
+ append(div6, div5);
+ append(div5, textarea);
+ append(div5, t10);
+ append(div5, button);
+ current = true;
+
+ if (!mounted) {
+ dispose = [
+ listen(textarea, "keydown", /*inputKeyDown*/ ctx[11]),
+ listen(button, "click", prevent_default(/*sendMessage*/ ctx[10]))
+ ];
+
+ mounted = true;
+ }
+ },
+ p(ctx, [dirty]) {
+ if (/*$chatAdapter*/ ctx[2]?.pubkey) {
+ if (if_block0) {
+ if_block0.p(ctx, dirty);
+ } else {
+ if_block0 = create_if_block_5(ctx);
+ if_block0.c();
+ if_block0.m(div0, null);
+ }
+ } else if (if_block0) {
+ if_block0.d(1);
+ if_block0 = null;
+ }
+
+ if (dirty & /*connectedRelays, totalRelays*/ 192) {
+ each_value_1 = Array(/*totalRelays*/ ctx[7]);
+ let i;
+
+ for (i = 0; i < each_value_1.length; i += 1) {
+ const child_ctx = get_each_context_1(ctx, each_value_1, i);
+
+ if (each_blocks[i]) {
+ each_blocks[i].p(child_ctx, dirty);
+ } else {
+ each_blocks[i] = create_each_block_1(child_ctx);
+ each_blocks[i].c();
+ each_blocks[i].m(div1, null);
+ }
+ }
+
+ for (; i < each_blocks.length; i += 1) {
+ each_blocks[i].d(1);
+ }
+
+ each_blocks.length = each_value_1.length;
+ }
+
+ if (!current || dirty & /*connectedRelays*/ 64) set_data(t2, /*connectedRelays*/ ctx[6]);
+ if (!current || dirty & /*totalRelays*/ 128) set_data(t4, /*totalRelays*/ ctx[7]);
+
+ if (/*$selectedMessage*/ ctx[8]) {
+ if (if_block1) {
+ if_block1.p(ctx, dirty);
+ } else {
+ if_block1 = create_if_block_3(ctx);
+ if_block1.c();
+ if_block1.m(t7.parentNode, t7);
+ }
+ } else if (if_block1) {
+ if_block1.d(1);
+ if_block1 = null;
+ }
+
+ let previous_block_index = current_block_type_index;
+ current_block_type_index = select_block_type_1(ctx);
+
+ if (current_block_type_index === previous_block_index) {
+ if_blocks[current_block_type_index].p(ctx, dirty);
+ } else {
+ group_outros();
+
+ transition_out(if_blocks[previous_block_index], 1, 1, () => {
+ if_blocks[previous_block_index] = null;
+ });
+
+ check_outros();
+ if_block2 = if_blocks[current_block_type_index];
+
+ if (!if_block2) {
+ if_block2 = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
+ if_block2.c();
+ } else {
+ if_block2.p(ctx, dirty);
+ }
+
+ transition_in(if_block2, 1);
+ if_block2.m(div3, null);
+ }
+
+ if (current_block_type !== (current_block_type = select_block_type_2(ctx))) {
+ if_block3.d(1);
+ if_block3 = current_block_type(ctx);
+
+ if (if_block3) {
+ if_block3.c();
+ if_block3.m(div4, null);
+ }
+ }
+ },
+ i(local) {
+ if (current) return;
+ transition_in(if_block2);
+ current = true;
+ },
+ o(local) {
+ transition_out(if_block2);
+ current = false;
+ },
+ d(detaching) {
+ if (detaching) detach(div2);
+ if (if_block0) if_block0.d();
+ destroy_each(each_blocks, detaching);
+ if (detaching) detach(t6);
+ if (if_block1) if_block1.d(detaching);
+ if (detaching) detach(t7);
+ if (detaching) detach(div3);
+ if_blocks[current_block_type_index].d();
+ if (detaching) detach(t8);
+ if (detaching) detach(div6);
+ if_block3.d();
+ mounted = false;
+ run_all(dispose);
+ }
+ };
+ }
+
+ function instance$2($$self, $$props, $$invalidate) {
+ let $selectedMessage;
+ let $chatData;
+ let $chatAdapter;
+ component_subscribe($$self, selectedMessage, $$value => $$invalidate(8, $selectedMessage = $$value));
+ component_subscribe($$self, chatData, $$value => $$invalidate(15, $chatData = $$value));
+ component_subscribe($$self, chatAdapter, $$value => $$invalidate(2, $chatAdapter = $$value));
+ let events = [];
+ let responseEvents = [];
+ let responses = {};
+ let profiles = {};
+ let { websiteOwnerPubkey } = $$props;
+ let { chatConfiguration } = $$props;
+ let prevChatConfiguration;
+
+ function getEventById(eventId) {
+ let event = events.find(e => e.id === eventId);
+ event = event || responseEvents.find(e => e.id === eventId);
+ return event;
+ }
+
+ async function sendMessage() {
+ const input = document.getElementById('message-input');
+ let message = input.value;
+ input.value = '';
+ let extraParams = { tags: [] };
+
+ // if this is the rootLevel we want to tag the owner of the site's pubkey
+ if (!rootNoteId) {
+ extraParams.tagPubKeys = [websiteOwnerPubkey];
+ }
+
+ // if we are responding to an event, we want to tag the event and the pubkey
+ if ($selectedMessage) {
+ extraParams.tags.push(['e', $selectedMessage]);
+ extraParams.tagPubKeys.push(getEventById($selectedMessage).pubkey);
+ } else {
+ message = message + '\n\n' + chatConfiguration.chatTags.join(' ') + '\n\n' + document.location.href;
+ }
+
+ // if (rootNoteId) {
+ // // mark it as a response to the most recent event
+ // const mostRecentEvent = events[events.length - 1];
+ // // go through all the tags and add them to the new message
+ // if (mostRecentEvent) {
+ // mostRecentEvent.tags.forEach(tag => {
+ // if (tag[0] === 'e') {
+ // extraParams.tags.push(tag);
+ // }
+ // })
+ // extraParams.tags.push(['e', mostRecentEvent.id]);
+ // extraParams.tags.push(['p', mostRecentEvent.pubkey]);
+ // }
+ // }
+ const noteId = await $chatAdapter.send(message, extraParams);
+
+ if (!rootNoteId) {
+ rootNoteId = noteId;
+ localStorage.setItem('rootNoteId', rootNoteId);
+ }
+ }
+
+ async function inputKeyDown(event) {
+ if (event.key === 'Enter') {
+ sendMessage();
+ event.preventDefault();
+ }
+ }
+
+ function messageReceived(message) {
+ message.tags.filter(tag => tag[0] === 'e').pop();
+ let isThread;
+
+ if (chatConfiguration.chatType === 'GLOBAL') {
+ isThread = message.tags.filter(tag => tag[0] === 'e').length >= 1;
+ } else {
+ const pubkeysTagged = message.tags.filter(tag => tag[0] === 'p').map(tag => tag[1]);
+ isThread = new Set(pubkeysTagged).size >= 2;
+ }
+
+ $$invalidate(4, responses[message.id] = [], responses);
+
+ if (isThread) {
+ const lastETag = message.tags.filter(tag => tag[0] === 'e').pop();
+
+ if (lastETag && lastETag[1] && responses[lastETag[1]]) {
+ responses[lastETag[1]].push(message);
+ }
+
+ responseEvents.push(message);
+ responseEvents = responseEvents;
+ } else {
+ // insert message so that it's chronologically ordered by created_at
+ let index = 0;
+
+ while (index < events.length && events[index].created_at < message.created_at) {
+ index++;
+ }
+
+ events.splice(index, 0, message);
+ ((($$invalidate(3, events), $$invalidate(1, chatConfiguration)), $$invalidate(13, prevChatConfiguration)), $$invalidate(2, $chatAdapter));
+ }
+
+ ((($$invalidate(4, responses), $$invalidate(1, chatConfiguration)), $$invalidate(13, prevChatConfiguration)), $$invalidate(2, $chatAdapter));
+ scrollDown();
+ }
+
+ function scrollDown() {
+ scrollToBottom({
+ container: document.getElementById('messages-container'),
+ offset: 500,
+ duration: 50
+ });
+ }
+
+ function reactionReceived(reaction) {
+ const event = events.find(event => event.id === reaction.id);
+
+ if (!event) {
+ return;
+ }
+
+ event.reactions = event.reactions || [];
+ event.reactions.push(reaction);
+ ((($$invalidate(3, events), $$invalidate(1, chatConfiguration)), $$invalidate(13, prevChatConfiguration)), $$invalidate(2, $chatAdapter));
+ }
+
+ let rootNoteId;
+
+ onMount(() => {
+ $chatAdapter.on('message', messageReceived);
+
+ $chatAdapter.on('connectivity', e => {
+ $$invalidate(14, connectivityStatus = e);
+ });
+
+ $chatAdapter.on('reaction', reactionReceived);
+
+ $chatAdapter.on('deleted', deletedEvents => {
+ deletedEvents.forEach(deletedEventId => {
+ const index = events.findIndex(event => event.id === deletedEventId);
+
+ if (index !== -1) {
+ $$invalidate(3, events[index].deleted = true, events);
+ ((($$invalidate(3, events), $$invalidate(1, chatConfiguration)), $$invalidate(13, prevChatConfiguration)), $$invalidate(2, $chatAdapter));
+ }
+ });
+ });
+
+ $chatAdapter.on('profile', ({ pubkey, profile }) => {
+ let profiles = $chatData.profiles;
+ profiles[pubkey] = profile;
+ chatData.set({ profiles, ...$chatData });
+ });
+ });
+
+ let connectivityStatus = {};
+ let connectedRelays = 0;
+ let totalRelays = 0;
+
+ function selectParent() {
+ // get the last tagged event in the tags array of the current $selectedMessage
+ const lastETag = getEventById($selectedMessage).tags.filter(tag => tag[0] === 'e').pop();
+
+ const lastETagId = lastETag && lastETag[1];
+ set_store_value(selectedMessage, $selectedMessage = lastETagId, $selectedMessage);
+ scrollDown();
+ }
+
+ $$self.$$set = $$props => {
+ if ('websiteOwnerPubkey' in $$props) $$invalidate(0, websiteOwnerPubkey = $$props.websiteOwnerPubkey);
+ if ('chatConfiguration' in $$props) $$invalidate(1, chatConfiguration = $$props.chatConfiguration);
+ };
+
+ $$self.$$.update = () => {
+ if ($$self.$$.dirty & /*chatConfiguration, prevChatConfiguration, $chatAdapter*/ 8198) {
+ {
+ if (chatConfiguration !== prevChatConfiguration && prevChatConfiguration && $chatAdapter) {
+ $chatAdapter.setChatConfiguration(chatConfiguration.chatType, chatConfiguration.chatTags, chatConfiguration.chatReferenceTags);
+ $$invalidate(3, events = []);
+ $$invalidate(4, responses = {});
+ rootNoteId = null;
+ localStorage.removeItem('rootNoteId');
+ } // rootNoteId = localStorage.getItem('rootNoteId');
+ // if (rootNoteId) {
+
+ // $chatAdapter.subscribeToEventAndResponses(rootNoteId);
+ // }
+ $$invalidate(13, prevChatConfiguration = chatConfiguration);
+ }
+ }
+
+ if ($$self.$$.dirty & /*connectivityStatus*/ 16384) {
+ {
+ $$invalidate(6, connectedRelays = Object.values(connectivityStatus).filter(status => status === 'connected').length);
+ $$invalidate(7, totalRelays = Object.values(connectivityStatus).length);
+ }
+ }
+
+ if ($$self.$$.dirty & /*$chatData*/ 32768) {
+ $$invalidate(5, profiles = $chatData.profiles);
+ }
+ };
+
+ return [
+ websiteOwnerPubkey,
+ chatConfiguration,
+ $chatAdapter,
+ events,
+ responses,
+ profiles,
+ connectedRelays,
+ totalRelays,
+ $selectedMessage,
+ getEventById,
+ sendMessage,
+ inputKeyDown,
+ selectParent,
+ prevChatConfiguration,
+ connectivityStatus,
+ $chatData
+ ];
+ }
+
+ class ConnectedWidget extends SvelteComponent {
+ constructor(options) {
+ super();
+
+ init(this, options, instance$2, create_fragment$2, safe_not_equal, {
+ websiteOwnerPubkey: 0,
+ chatConfiguration: 1
+ });
+ }
+ }
+
+ /* src/Container.svelte generated by Svelte v3.55.1 */
+
+ function create_else_block$1(ctx) {
+ let connectedwidget;
+ let current;
+
+ connectedwidget = new ConnectedWidget({
+ props: {
+ websiteOwnerPubkey: /*websiteOwnerPubkey*/ ctx[1],
+ chatConfiguration: /*chatConfiguration*/ ctx[2],
+ relays: /*relays*/ ctx[3]
+ }
+ });
+
+ return {
+ c() {
+ create_component(connectedwidget.$$.fragment);
+ },
+ m(target, anchor) {
+ mount_component(connectedwidget, target, anchor);
+ current = true;
+ },
+ p(ctx, dirty) {
+ const connectedwidget_changes = {};
+ if (dirty & /*websiteOwnerPubkey*/ 2) connectedwidget_changes.websiteOwnerPubkey = /*websiteOwnerPubkey*/ ctx[1];
+ if (dirty & /*chatConfiguration*/ 4) connectedwidget_changes.chatConfiguration = /*chatConfiguration*/ ctx[2];
+ if (dirty & /*relays*/ 8) connectedwidget_changes.relays = /*relays*/ ctx[3];
+ connectedwidget.$set(connectedwidget_changes);
+ },
+ i(local) {
+ if (current) return;
+ transition_in(connectedwidget.$$.fragment, local);
+ current = true;
+ },
+ o(local) {
+ transition_out(connectedwidget.$$.fragment, local);
+ current = false;
+ },
+ d(detaching) {
+ destroy_component(connectedwidget, detaching);
+ }
+ };
+ }
+
+ // (14:0) {#if !chatStarted}
+ function create_if_block$1(ctx) {
+ let keyprompt;
+ let current;
+
+ keyprompt = new KeyPrompt({
+ props: {
+ websiteOwnerPubkey: /*websiteOwnerPubkey*/ ctx[1],
+ chatConfiguration: /*chatConfiguration*/ ctx[2],
+ relays: /*relays*/ ctx[3]
+ }
+ });
+
+ return {
+ c() {
+ create_component(keyprompt.$$.fragment);
+ },
+ m(target, anchor) {
+ mount_component(keyprompt, target, anchor);
+ current = true;
+ },
+ p(ctx, dirty) {
+ const keyprompt_changes = {};
+ if (dirty & /*websiteOwnerPubkey*/ 2) keyprompt_changes.websiteOwnerPubkey = /*websiteOwnerPubkey*/ ctx[1];
+ if (dirty & /*chatConfiguration*/ 4) keyprompt_changes.chatConfiguration = /*chatConfiguration*/ ctx[2];
+ if (dirty & /*relays*/ 8) keyprompt_changes.relays = /*relays*/ ctx[3];
+ keyprompt.$set(keyprompt_changes);
+ },
+ i(local) {
+ if (current) return;
+ transition_in(keyprompt.$$.fragment, local);
+ current = true;
+ },
+ o(local) {
+ transition_out(keyprompt.$$.fragment, local);
+ current = false;
+ },
+ d(detaching) {
+ destroy_component(keyprompt, detaching);
+ }
+ };
+ }
+
+ function create_fragment$1(ctx) {
+ let current_block_type_index;
+ let if_block;
+ let if_block_anchor;
+ let current;
+ const if_block_creators = [create_if_block$1, create_else_block$1];
+ const if_blocks = [];
+
+ function select_block_type(ctx, dirty) {
+ if (!/*chatStarted*/ ctx[0]) return 0;
+ return 1;
+ }
+
+ current_block_type_index = select_block_type(ctx);
+ if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
+
+ return {
+ c() {
+ if_block.c();
+ if_block_anchor = empty();
+ },
+ m(target, anchor) {
+ if_blocks[current_block_type_index].m(target, anchor);
+ insert(target, if_block_anchor, anchor);
+ current = true;
+ },
+ p(ctx, [dirty]) {
+ let previous_block_index = current_block_type_index;
+ current_block_type_index = select_block_type(ctx);
+
+ if (current_block_type_index === previous_block_index) {
+ if_blocks[current_block_type_index].p(ctx, dirty);
+ } else {
+ group_outros();
+
+ transition_out(if_blocks[previous_block_index], 1, 1, () => {
+ if_blocks[previous_block_index] = null;
+ });
+
+ check_outros();
+ if_block = if_blocks[current_block_type_index];
+
+ if (!if_block) {
+ if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
+ if_block.c();
+ } else {
+ if_block.p(ctx, dirty);
+ }
+
+ transition_in(if_block, 1);
+ if_block.m(if_block_anchor.parentNode, if_block_anchor);
+ }
+ },
+ i(local) {
+ if (current) return;
+ transition_in(if_block);
+ current = true;
+ },
+ o(local) {
+ transition_out(if_block);
+ current = false;
+ },
+ d(detaching) {
+ if_blocks[current_block_type_index].d(detaching);
+ if (detaching) detach(if_block_anchor);
+ }
+ };
+ }
+
+ function instance$1($$self, $$props, $$invalidate) {
+ let $chatAdapter;
+ component_subscribe($$self, chatAdapter, $$value => $$invalidate(4, $chatAdapter = $$value));
+ let { websiteOwnerPubkey } = $$props;
+ let { chatStarted } = $$props;
+ let { chatConfiguration } = $$props;
+ let { relays } = $$props;
+
+ $$self.$$set = $$props => {
+ if ('websiteOwnerPubkey' in $$props) $$invalidate(1, websiteOwnerPubkey = $$props.websiteOwnerPubkey);
+ if ('chatStarted' in $$props) $$invalidate(0, chatStarted = $$props.chatStarted);
+ if ('chatConfiguration' in $$props) $$invalidate(2, chatConfiguration = $$props.chatConfiguration);
+ if ('relays' in $$props) $$invalidate(3, relays = $$props.relays);
+ };
+
+ $$self.$$.update = () => {
+ if ($$self.$$.dirty & /*$chatAdapter*/ 16) {
+ $$invalidate(0, chatStarted = !!$chatAdapter);
+ }
+ };
+
+ return [chatStarted, websiteOwnerPubkey, chatConfiguration, relays, $chatAdapter];
+ }
+
+ class Container extends SvelteComponent {
+ constructor(options) {
+ super();
+
+ init(this, options, instance$1, create_fragment$1, safe_not_equal, {
+ websiteOwnerPubkey: 1,
+ chatStarted: 0,
+ chatConfiguration: 2,
+ relays: 3
+ });
+ }
+ }
+
+ /* src/Widget.svelte generated by Svelte v3.55.1 */
+
+ function create_if_block(ctx) {
+ let div;
+ let current_block_type_index;
+ let if_block;
+ let div_class_value;
+ let current;
+ const if_block_creators = [create_if_block_1, create_else_block];
+ const if_blocks = [];
+
+ function select_block_type(ctx, dirty) {
+ if (!/*dismissedIntro*/ ctx[6]) return 0;
+ return 1;
+ }
+
+ current_block_type_index = select_block_type(ctx);
+ if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
+
+ return {
+ c() {
+ div = element("div");
+ if_block.c();
+ attr(div, "class", div_class_value = "shadow-2xl bg-white mb-5 w-96 max-w-screen-sm text-black rounded-xl p-5 overflow-scroll " + (/*minimizeChat*/ ctx[7] ? 'hidden' : '') + "" + " svelte-h3q7vr");
+ set_style(div, "max-height", "80vh");
+ },
+ m(target, anchor) {
+ insert(target, div, anchor);
+ if_blocks[current_block_type_index].m(div, null);
+ current = true;
+ },
+ p(ctx, dirty) {
+ let previous_block_index = current_block_type_index;
+ current_block_type_index = select_block_type(ctx);
+
+ if (current_block_type_index === previous_block_index) {
+ if_blocks[current_block_type_index].p(ctx, dirty);
+ } else {
+ group_outros();
+
+ transition_out(if_blocks[previous_block_index], 1, 1, () => {
+ if_blocks[previous_block_index] = null;
+ });
+
+ check_outros();
+ if_block = if_blocks[current_block_type_index];
+
+ if (!if_block) {
+ if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
+ if_block.c();
+ } else {
+ if_block.p(ctx, dirty);
+ }
+
+ transition_in(if_block, 1);
+ if_block.m(div, null);
+ }
+
+ if (!current || dirty & /*minimizeChat*/ 128 && div_class_value !== (div_class_value = "shadow-2xl bg-white mb-5 w-96 max-w-screen-sm text-black rounded-xl p-5 overflow-scroll " + (/*minimizeChat*/ ctx[7] ? 'hidden' : '') + "" + " svelte-h3q7vr")) {
+ attr(div, "class", div_class_value);
+ }
+ },
+ i(local) {
+ if (current) return;
+ transition_in(if_block);
+ current = true;
+ },
+ o(local) {
+ transition_out(if_block);
+ current = false;
+ },
+ d(detaching) {
+ if (detaching) detach(div);
+ if_blocks[current_block_type_index].d();
+ }
+ };
+ }
+
+ // (80:12) {:else}
+ function create_else_block(ctx) {
+ let container;
+ let current;
+
+ container = new Container({
+ props: {
+ websiteOwnerPubkey: /*websiteOwnerPubkey*/ ctx[0],
+ chatConfiguration: {
+ chatType: /*chatType*/ ctx[1],
+ chatTags: /*chatTags*/ ctx[2],
+ chatReferenceTags: /*chatReferenceTags*/ ctx[3]
+ },
+ relays: /*relays*/ ctx[4]
+ }
+ });
+
+ return {
+ c() {
+ create_component(container.$$.fragment);
+ },
+ m(target, anchor) {
+ mount_component(container, target, anchor);
+ current = true;
+ },
+ p(ctx, dirty) {
+ const container_changes = {};
+ if (dirty & /*websiteOwnerPubkey*/ 1) container_changes.websiteOwnerPubkey = /*websiteOwnerPubkey*/ ctx[0];
+
+ if (dirty & /*chatType, chatTags, chatReferenceTags*/ 14) container_changes.chatConfiguration = {
+ chatType: /*chatType*/ ctx[1],
+ chatTags: /*chatTags*/ ctx[2],
+ chatReferenceTags: /*chatReferenceTags*/ ctx[3]
+ };
+
+ if (dirty & /*relays*/ 16) container_changes.relays = /*relays*/ ctx[4];
+ container.$set(container_changes);
+ },
+ i(local) {
+ if (current) return;
+ transition_in(container.$$.fragment, local);
+ current = true;
+ },
+ o(local) {
+ transition_out(container.$$.fragment, local);
+ current = false;
+ },
+ d(detaching) {
+ destroy_component(container, detaching);
+ }
+ };
+ }
+
+ // (34:12) {#if !dismissedIntro}
+ function create_if_block_1(ctx) {
+ let h1;
+ let t1;
+ let p0;
+ let t3;
+ let p1;
+ let t5;
+ let p2;
+ let t9;
+ let p3;
+ let t11;
+ let button;
+ let mounted;
+ let dispose;
+
+ return {
+ c() {
+ h1 = element("h1");
+ h1.textContent = "EinundzwanzigNostr";
+ t1 = space();
+ p0 = element("p");
+ p0.textContent = "This is a FOSS chat app built on top of the Nostr protocol.";
+ t3 = space();
+ p1 = element("p");
+ p1.textContent = "Choose how you would like to chat:";
+ t5 = space();
+ p2 = element("p");
+
+ p2.innerHTML = `You can use it to ask for help
+ PSBT.io
+ to the creators of this site or to
+ anyone willing to help.`;
+
+ t9 = space();
+ p3 = element("p");
+ p3.textContent = "Keep in mind that this chat is public,\n anyone can read it, so don't exchange\n private information and use common-sense.";
+ t11 = space();
+ button = element("button");
+ button.textContent = "Continue";
+ attr(h1, "class", "font-bold text-2xl text-purple-700 svelte-h3q7vr");
+ attr(p0, "class", "text-gray-700 mb-3 svelte-h3q7vr");
+ attr(p1, "class", "text-gray-700 mb-3 svelte-h3q7vr");
+ attr(p2, "class", "text-gray-700 mb-3 svelte-h3q7vr");
+ attr(p3, "class", "text-gray-700 mb-3 svelte-h3q7vr");
+ attr(button, "class", "bg-purple-900 hover:bg-purple-700 w-full p-2 py-4 text-xl mt-3 rounded-xl text-center font-semibold tracking-wide uppercase text-white svelte-h3q7vr");
+ },
+ m(target, anchor) {
+ insert(target, h1, anchor);
+ insert(target, t1, anchor);
+ insert(target, p0, anchor);
+ insert(target, t3, anchor);
+ insert(target, p1, anchor);
+ insert(target, t5, anchor);
+ insert(target, p2, anchor);
+ insert(target, t9, anchor);
+ insert(target, p3, anchor);
+ insert(target, t11, anchor);
+ insert(target, button, anchor);
+
+ if (!mounted) {
+ dispose = listen(button, "click", /*dismissIntro*/ ctx[9]);
+ mounted = true;
+ }
+ },
+ p: noop,
+ i: noop,
+ o: noop,
+ d(detaching) {
+ if (detaching) detach(h1);
+ if (detaching) detach(t1);
+ if (detaching) detach(p0);
+ if (detaching) detach(t3);
+ if (detaching) detach(p1);
+ if (detaching) detach(t5);
+ if (detaching) detach(p2);
+ if (detaching) detach(t9);
+ if (detaching) detach(p3);
+ if (detaching) detach(t11);
+ if (detaching) detach(button);
+ mounted = false;
+ dispose();
+ }
+ };
+ }
+
+ function create_fragment(ctx) {
+ let div1;
+ let t0;
+ let div0;
+ let a;
+ let current;
+ let mounted;
+ let dispose;
+ let if_block = /*showChat*/ ctx[5] && create_if_block(ctx);
+
+ return {
+ c() {
+ div1 = element("div");
+ if (if_block) if_block.c();
+ t0 = space();
+ div0 = element("div");
+ a = element("a");
+
+ a.innerHTML = `Einundzwanzig.Nostr
+ `;
+
+ attr(a, "href", "#");
+ attr(a, "class", "text-white bg-purple-900 hover:bg-purple-700 w-full p-5 rounded-full flex-shrink-1 text-center font-semibold flex flex-row items-center gap-4 svelte-h3q7vr");
+ attr(div0, "class", "self-end svelte-h3q7vr");
+ attr(div1, "class", "fixed bottom-5 right-5 mb-5 flex flex-col item-end font-sans svelte-h3q7vr");
+ },
+ m(target, anchor) {
+ insert(target, div1, anchor);
+ if (if_block) if_block.m(div1, null);
+ append(div1, t0);
+ append(div1, div0);
+ append(div0, a);
+ current = true;
+
+ if (!mounted) {
+ dispose = listen(a, "click", prevent_default(/*toggleChat*/ ctx[8]));
+ mounted = true;
+ }
+ },
+ p(ctx, [dirty]) {
+ if (/*showChat*/ ctx[5]) {
+ if (if_block) {
+ if_block.p(ctx, dirty);
+
+ if (dirty & /*showChat*/ 32) {
+ transition_in(if_block, 1);
+ }
+ } else {
+ if_block = create_if_block(ctx);
+ if_block.c();
+ transition_in(if_block, 1);
+ if_block.m(div1, t0);
+ }
+ } else if (if_block) {
+ group_outros();
+
+ transition_out(if_block, 1, 1, () => {
+ if_block = null;
+ });
+
+ check_outros();
+ }
+ },
+ i(local) {
+ if (current) return;
+ transition_in(if_block);
+ current = true;
+ },
+ o(local) {
+ transition_out(if_block);
+ current = false;
+ },
+ d(detaching) {
+ if (detaching) detach(div1);
+ if (if_block) if_block.d();
+ mounted = false;
+ dispose();
+ }
+ };
+ }
+
+ function instance($$self, $$props, $$invalidate) {
+ let { websiteOwnerPubkey } = $$props;
+ let { chatType } = $$props;
+ let { chatTags } = $$props;
+ let { chatReferenceTags } = $$props;
+ let { relays } = $$props;
+ let showChat = false;
+ let dismissedIntro = true;
+ let minimizeChat = false;
+
+ function toggleChat() {
+ if (showChat) {
+ $$invalidate(7, minimizeChat = !minimizeChat);
+ } else {
+ $$invalidate(5, showChat = !showChat);
+ }
+ }
+
+ function dismissIntro() {
+ $$invalidate(6, dismissedIntro = true);
+ }
+
+ $$self.$$set = $$props => {
+ if ('websiteOwnerPubkey' in $$props) $$invalidate(0, websiteOwnerPubkey = $$props.websiteOwnerPubkey);
+ if ('chatType' in $$props) $$invalidate(1, chatType = $$props.chatType);
+ if ('chatTags' in $$props) $$invalidate(2, chatTags = $$props.chatTags);
+ if ('chatReferenceTags' in $$props) $$invalidate(3, chatReferenceTags = $$props.chatReferenceTags);
+ if ('relays' in $$props) $$invalidate(4, relays = $$props.relays);
+ };
+
+ return [
+ websiteOwnerPubkey,
+ chatType,
+ chatTags,
+ chatReferenceTags,
+ relays,
+ showChat,
+ dismissedIntro,
+ minimizeChat,
+ toggleChat,
+ dismissIntro
+ ];
+ }
+
+ class Widget extends SvelteComponent {
+ constructor(options) {
+ super();
+
+ init(this, options, instance, create_fragment, safe_not_equal, {
+ websiteOwnerPubkey: 0,
+ chatType: 1,
+ chatTags: 2,
+ chatReferenceTags: 3,
+ relays: 4
+ });
+ }
+ }
+
+ var div = document.createElement('DIV');
+ var script = document.currentScript;
+ const websiteOwnerPubkey = script.getAttribute('data-website-owner-pubkey');
+ const chatType = script.getAttribute('data-chat-type');
+ let chatTags = script.getAttribute('data-chat-tags');
+ let chatReferenceTags = script.getAttribute('data-chat-reference-tags');
+ let relays = script.getAttribute('data-relays');
+ script.parentNode.insertBefore(div, script);
+
+ if (!relays) {
+ relays = 'wss://relay.f7z.io,wss://nos.lol,wss://relay.nostr.info,wss://nostr-pub.wellorder.net,wss://relay.current.fyi,wss://relay.nostr.band';
+ }
+
+ relays = relays.split(',');
+ chatTags = chatTags ? chatTags.split(',') : [];
+ chatReferenceTags = chatReferenceTags ? chatReferenceTags.split(',') : [];
+
+ new Widget({
+ target: div,
+ props: {
+ websiteOwnerPubkey,
+ chatType,
+ chatTags,
+ chatReferenceTags,
+ relays
+ },
+ });
+
+})();
+//# sourceMappingURL=bundle.js.map
diff --git a/public/dist/filepond-plugin-image-edit.css b/public/dist/filepond-plugin-image-edit.css
new file mode 100644
index 0000000..52ffb6d
--- /dev/null
+++ b/public/dist/filepond-plugin-image-edit.css
@@ -0,0 +1,47 @@
+/*!
+ * FilePondPluginImageEdit 1.6.3
+ * Licensed under MIT, https://opensource.org/licenses/MIT/
+ * Please visit https://pqina.nl/filepond/ for details.
+ */
+
+/* eslint-disable */
+.filepond--action-edit-item.filepond--action-edit-item {
+ width: 2em;
+ height: 2em;
+ padding: 0.1875em;
+}
+
+.filepond--action-edit-item.filepond--action-edit-item[data-align*='center'] {
+ margin-left: -0.1875em;
+}
+
+.filepond--action-edit-item.filepond--action-edit-item[data-align*='bottom'] {
+ margin-bottom: -0.1875em;
+}
+
+.filepond--action-edit-item-alt {
+ border: none;
+ line-height: inherit;
+ background: transparent;
+ font-family: inherit;
+ color: inherit;
+ outline: none;
+ padding: 0;
+ margin: 0 0 0 0.25em;
+ pointer-events: all;
+ position: absolute;
+}
+
+.filepond--action-edit-item-alt svg {
+ width: 1.3125em;
+ height: 1.3125em;
+}
+
+.filepond--action-edit-item-alt span {
+ font-size: 0;
+ opacity: 0;
+}
+.filepond--root[data-style-panel-layout~='circle'] .filepond--action-edit-item {
+ opacity: 1 !important;
+ visibility: visible !important;
+}
diff --git a/public/dist/filepond.css b/public/dist/filepond.css
new file mode 100644
index 0000000..a53b54e
--- /dev/null
+++ b/public/dist/filepond.css
@@ -0,0 +1,1047 @@
+/*!
+ * FilePond 4.30.4
+ * Licensed under MIT, https://opensource.org/licenses/MIT/
+ * Please visit https://pqina.nl/filepond/ for details.
+ */
+
+/* eslint-disable */
+.filepond--assistant {
+ position: absolute;
+ overflow: hidden;
+ height: 1px;
+ width: 1px;
+ padding: 0;
+ border: 0;
+ clip: rect(1px, 1px, 1px, 1px);
+ -webkit-clip-path: inset(50%);
+ clip-path: inset(50%);
+ white-space: nowrap;
+}
+/* Hard to override styles */
+.filepond--browser.filepond--browser {
+ /* is positioned absolute so it is focusable for form validation errors */
+ position: absolute;
+ margin: 0;
+ padding: 0;
+
+ /* is positioned ~behind drop label */
+ left: 1em;
+ top: 1.75em;
+ width: calc(100% - 2em);
+
+ /* hide visually */
+ opacity: 0;
+ font-size: 0; /* removes text cursor in Internet Explorer 11 */
+}
+.filepond--data {
+ position: absolute;
+ width: 0;
+ height: 0;
+ padding: 0;
+ margin: 0;
+ border: none;
+ visibility: hidden;
+ pointer-events: none;
+ contain: strict;
+}
+.filepond--drip {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ overflow: hidden;
+ opacity: 0.1;
+
+ /* can't interact with this element */
+ pointer-events: none;
+
+ /* inherit border radius from parent (needed for drip-blob cut of) */
+ border-radius: 0.5em;
+
+ /* this seems to prevent Chrome from redrawing this layer constantly */
+ background: rgba(0, 0, 0, 0.01);
+}
+.filepond--drip-blob {
+ position: absolute;
+ -webkit-transform-origin: center center;
+ transform-origin: center center;
+ top: 0;
+ left: 0;
+ width: 8em;
+ height: 8em;
+ margin-left: -4em;
+ margin-top: -4em;
+ background: #292625;
+ border-radius: 50%;
+
+ /* will be animated */
+ will-change: transform, opacity;
+}
+.filepond--drop-label {
+ position: absolute;
+ left: 0;
+ right: 0;
+ top: 0;
+ margin: 0;
+ color: #4f4f4f;
+
+ /* center contents */
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ /* fixes IE11 centering problems (is overruled by label min-height) */
+ height: 0px;
+
+ /* dont allow selection */
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+
+ /* will be animated */
+ will-change: transform, opacity;
+}
+/* Hard to override styles on purpose */
+.filepond--drop-label.filepond--drop-label label {
+ display: block;
+ margin: 0;
+ padding: 0.5em; /* use padding instead of margin so click area is not impacted */
+}
+.filepond--drop-label label {
+ cursor: default;
+ font-size: 0.875em;
+ font-weight: normal;
+ text-align: center;
+ line-height: 1.5;
+}
+.filepond--label-action {
+ text-decoration: underline;
+ -webkit-text-decoration-skip: ink;
+ text-decoration-skip-ink: auto;
+ -webkit-text-decoration-color: #a7a4a4;
+ text-decoration-color: #a7a4a4;
+ cursor: pointer;
+}
+.filepond--root[data-disabled] .filepond--drop-label label {
+ opacity: 0.5;
+}
+/* Hard to override styles */
+.filepond--file-action-button.filepond--file-action-button {
+ font-size: 1em;
+ width: 1.625em;
+ height: 1.625em;
+
+ font-family: inherit;
+ line-height: inherit;
+
+ margin: 0;
+ padding: 0;
+ border: none;
+ outline: none;
+
+ will-change: transform, opacity;
+
+ /* hidden label */
+}
+.filepond--file-action-button.filepond--file-action-button span {
+ position: absolute;
+ overflow: hidden;
+ height: 1px;
+ width: 1px;
+ padding: 0;
+ border: 0;
+ clip: rect(1px, 1px, 1px, 1px);
+ -webkit-clip-path: inset(50%);
+ clip-path: inset(50%);
+ white-space: nowrap;
+}
+.filepond--file-action-button.filepond--file-action-button {
+ /* scale SVG to fill button */
+}
+.filepond--file-action-button.filepond--file-action-button svg {
+ width: 100%;
+ height: 100%;
+}
+.filepond--file-action-button.filepond--file-action-button {
+ /* bigger touch area */
+}
+.filepond--file-action-button.filepond--file-action-button::after {
+ position: absolute;
+ left: -0.75em;
+ right: -0.75em;
+ top: -0.75em;
+ bottom: -0.75em;
+ content: '';
+}
+/* Soft styles */
+.filepond--file-action-button {
+ /* use default arrow cursor */
+ cursor: auto;
+
+ /* reset default button styles */
+ color: #fff;
+
+ /* set default look n feel */
+ border-radius: 50%;
+ background-color: rgba(0, 0, 0, 0.5);
+ background-image: none;
+
+ /* we animate box shadow on focus */
+ /* it's only slightly slower than animating */
+ /* a pseudo-element with transforms and renders */
+ /* a lot better on chrome */
+ box-shadow: 0 0 0 0 rgba(255, 255, 255, 0);
+ transition: box-shadow 0.25s ease-in;
+}
+.filepond--file-action-button:hover,
+.filepond--file-action-button:focus {
+ box-shadow: 0 0 0 0.125em rgba(255, 255, 255, 0.9);
+}
+.filepond--file-action-button[disabled] {
+ color: rgba(255, 255, 255, 0.5);
+ background-color: rgba(0, 0, 0, 0.25);
+}
+.filepond--file-action-button[hidden] {
+ display: none;
+}
+/* edit button */
+.filepond--action-edit-item.filepond--action-edit-item {
+ width: 2em;
+ height: 2em;
+ padding: 0.1875em;
+}
+.filepond--action-edit-item.filepond--action-edit-item[data-align*='center'] {
+ margin-left: -0.1875em;
+}
+.filepond--action-edit-item.filepond--action-edit-item[data-align*='bottom'] {
+ margin-bottom: -0.1875em;
+}
+.filepond--action-edit-item-alt {
+ border: none;
+ line-height: inherit;
+ background: transparent;
+ font-family: inherit;
+ color: inherit;
+ outline: none;
+ padding: 0;
+ margin: 0 0 0 0.25em;
+ pointer-events: all;
+ position: absolute;
+}
+.filepond--action-edit-item-alt svg {
+ width: 1.3125em;
+ height: 1.3125em;
+}
+.filepond--action-edit-item-alt span {
+ font-size: 0;
+ opacity: 0;
+}
+.filepond--file-info {
+ position: static;
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ flex: 1;
+ margin: 0 0.5em 0 0;
+ min-width: 0;
+
+ /* will be animated */
+ will-change: transform, opacity;
+
+ /* can't do anything with this info */
+ pointer-events: none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+
+ /* no margins on children */
+}
+.filepond--file-info * {
+ margin: 0;
+}
+.filepond--file-info {
+ /* we don't want to have these overrules so these selectors are a bit more specific */
+}
+.filepond--file-info .filepond--file-info-main {
+ font-size: 0.75em;
+ line-height: 1.2;
+
+ /* we want ellipsis if this bar gets too wide */
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ width: 100%;
+}
+.filepond--file-info .filepond--file-info-sub {
+ font-size: 0.625em;
+ opacity: 0.5;
+ transition: opacity 0.25s ease-in-out;
+ white-space: nowrap;
+}
+.filepond--file-info .filepond--file-info-sub:empty {
+ display: none;
+}
+.filepond--file-status {
+ position: static;
+ display: flex;
+ flex-direction: column;
+ align-items: flex-end;
+ flex-grow: 0;
+ flex-shrink: 0;
+
+ margin: 0;
+ min-width: 2.25em;
+ text-align: right;
+
+ /* will be animated */
+ will-change: transform, opacity;
+
+ /* can't do anything with this info */
+ pointer-events: none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+
+ /* no margins on children */
+}
+.filepond--file-status * {
+ margin: 0;
+ white-space: nowrap;
+}
+.filepond--file-status {
+ /* font sizes */
+}
+.filepond--file-status .filepond--file-status-main {
+ font-size: 0.75em;
+ line-height: 1.2;
+}
+.filepond--file-status .filepond--file-status-sub {
+ font-size: 0.625em;
+ opacity: 0.5;
+ transition: opacity 0.25s ease-in-out;
+}
+/* Hard to override styles */
+.filepond--file-wrapper.filepond--file-wrapper {
+ border: none;
+ margin: 0;
+ padding: 0;
+ min-width: 0;
+ height: 100%;
+
+ /* hide legend for visual users */
+}
+.filepond--file-wrapper.filepond--file-wrapper > legend {
+ position: absolute;
+ overflow: hidden;
+ height: 1px;
+ width: 1px;
+ padding: 0;
+ border: 0;
+ clip: rect(1px, 1px, 1px, 1px);
+ -webkit-clip-path: inset(50%);
+ clip-path: inset(50%);
+ white-space: nowrap;
+}
+.filepond--file {
+ position: static;
+ display: flex;
+ height: 100%;
+ align-items: flex-start;
+
+ padding: 0.5625em 0.5625em;
+
+ color: #fff;
+ border-radius: 0.5em;
+
+ /* control positions */
+}
+.filepond--file .filepond--file-status {
+ margin-left: auto;
+ margin-right: 2.25em;
+}
+.filepond--file .filepond--processing-complete-indicator {
+ pointer-events: none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ z-index: 3;
+}
+.filepond--file .filepond--processing-complete-indicator,
+.filepond--file .filepond--progress-indicator,
+.filepond--file .filepond--file-action-button {
+ position: absolute;
+}
+.filepond--file {
+ /* .filepond--file-action-button */
+}
+.filepond--file [data-align*='left'] {
+ left: 0.5625em;
+}
+.filepond--file [data-align*='right'] {
+ right: 0.5625em;
+}
+.filepond--file [data-align*='center'] {
+ left: calc(50% - 0.8125em); /* .8125 is half of button width */
+}
+.filepond--file [data-align*='bottom'] {
+ bottom: 1.125em;
+}
+.filepond--file [data-align='center'] {
+ top: calc(50% - 0.8125em);
+}
+.filepond--file .filepond--progress-indicator {
+ margin-top: 0.1875em;
+}
+.filepond--file .filepond--progress-indicator[data-align*='right'] {
+ margin-right: 0.1875em;
+}
+.filepond--file .filepond--progress-indicator[data-align*='left'] {
+ margin-left: 0.1875em;
+}
+/* make sure text does not overlap */
+[data-filepond-item-state='cancelled'] .filepond--file-info,
+[data-filepond-item-state*='invalid'] .filepond--file-info,
+[data-filepond-item-state*='error'] .filepond--file-info {
+ margin-right: 2.25em;
+}
+[data-filepond-item-state~='processing'] .filepond--file-status-sub {
+ opacity: 0;
+}
+[data-filepond-item-state~='processing']
+ .filepond--action-abort-item-processing
+ ~ .filepond--file-status
+ .filepond--file-status-sub {
+ opacity: 0.5;
+}
+[data-filepond-item-state='processing-error'] .filepond--file-status-sub {
+ opacity: 0;
+}
+[data-filepond-item-state='processing-error']
+ .filepond--action-retry-item-processing
+ ~ .filepond--file-status
+ .filepond--file-status-sub {
+ opacity: 0.5;
+}
+[data-filepond-item-state='processing-complete'] {
+ /* busy state */
+}
+[data-filepond-item-state='processing-complete'] .filepond--action-revert-item-processing svg {
+ -webkit-animation: fall 0.5s 0.125s linear both;
+ animation: fall 0.5s 0.125s linear both;
+}
+[data-filepond-item-state='processing-complete'] {
+ /* hide details by default, only show when can revert */
+}
+[data-filepond-item-state='processing-complete'] .filepond--file-status-sub {
+ opacity: 0.5;
+}
+[data-filepond-item-state='processing-complete']
+ .filepond--processing-complete-indicator:not([style*='hidden'])
+ ~ .filepond--file-status
+ .filepond--file-status-sub {
+ opacity: 0;
+}
+[data-filepond-item-state='processing-complete'] .filepond--file-info-sub {
+ opacity: 0;
+}
+[data-filepond-item-state='processing-complete']
+ .filepond--action-revert-item-processing
+ ~ .filepond--file-info
+ .filepond--file-info-sub {
+ opacity: 0.5;
+}
+/* file state can be invalid or error, both are visually similar but */
+/* having them as separate states might be useful */
+[data-filepond-item-state*='invalid'] .filepond--panel,
+[data-filepond-item-state*='invalid'] .filepond--file-wrapper,
+[data-filepond-item-state*='error'] .filepond--panel,
+[data-filepond-item-state*='error'] .filepond--file-wrapper {
+ -webkit-animation: shake 0.65s linear both;
+ animation: shake 0.65s linear both;
+}
+/* spins progress indicator when file is marked as busy */
+[data-filepond-item-state*='busy'] .filepond--progress-indicator svg {
+ -webkit-animation: spin 1s linear infinite;
+ animation: spin 1s linear infinite;
+}
+/**
+ * States
+ */
+@-webkit-keyframes spin {
+ 0% {
+ -webkit-transform: rotateZ(0deg);
+ transform: rotateZ(0deg);
+ }
+
+ 100% {
+ -webkit-transform: rotateZ(360deg);
+ transform: rotateZ(360deg);
+ }
+}
+@keyframes spin {
+ 0% {
+ -webkit-transform: rotateZ(0deg);
+ transform: rotateZ(0deg);
+ }
+
+ 100% {
+ -webkit-transform: rotateZ(360deg);
+ transform: rotateZ(360deg);
+ }
+}
+@-webkit-keyframes shake {
+ 10%,
+ 90% {
+ -webkit-transform: translateX(-0.0625em);
+ transform: translateX(-0.0625em);
+ }
+
+ 20%,
+ 80% {
+ -webkit-transform: translateX(0.125em);
+ transform: translateX(0.125em);
+ }
+
+ 30%,
+ 50%,
+ 70% {
+ -webkit-transform: translateX(-0.25em);
+ transform: translateX(-0.25em);
+ }
+
+ 40%,
+ 60% {
+ -webkit-transform: translateX(0.25em);
+ transform: translateX(0.25em);
+ }
+}
+@keyframes shake {
+ 10%,
+ 90% {
+ -webkit-transform: translateX(-0.0625em);
+ transform: translateX(-0.0625em);
+ }
+
+ 20%,
+ 80% {
+ -webkit-transform: translateX(0.125em);
+ transform: translateX(0.125em);
+ }
+
+ 30%,
+ 50%,
+ 70% {
+ -webkit-transform: translateX(-0.25em);
+ transform: translateX(-0.25em);
+ }
+
+ 40%,
+ 60% {
+ -webkit-transform: translateX(0.25em);
+ transform: translateX(0.25em);
+ }
+}
+@-webkit-keyframes fall {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale(0.5);
+ transform: scale(0.5);
+ -webkit-animation-timing-function: ease-out;
+ animation-timing-function: ease-out;
+ }
+
+ 70% {
+ opacity: 1;
+ -webkit-transform: scale(1.1);
+ transform: scale(1.1);
+ -webkit-animation-timing-function: ease-in-out;
+ animation-timing-function: ease-in-out;
+ }
+
+ 100% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ -webkit-animation-timing-function: ease-out;
+ animation-timing-function: ease-out;
+ }
+}
+@keyframes fall {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale(0.5);
+ transform: scale(0.5);
+ -webkit-animation-timing-function: ease-out;
+ animation-timing-function: ease-out;
+ }
+
+ 70% {
+ opacity: 1;
+ -webkit-transform: scale(1.1);
+ transform: scale(1.1);
+ -webkit-animation-timing-function: ease-in-out;
+ animation-timing-function: ease-in-out;
+ }
+
+ 100% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ -webkit-animation-timing-function: ease-out;
+ animation-timing-function: ease-out;
+ }
+}
+/* ignore all other interaction elements while dragging a file */
+.filepond--hopper[data-hopper-state='drag-over'] > * {
+ pointer-events: none;
+}
+/* capture all hit tests using a hidden layer, this speeds up the event flow */
+.filepond--hopper[data-hopper-state='drag-over']::after {
+ content: '';
+ position: absolute;
+ left: 0;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ z-index: 100;
+}
+.filepond--progress-indicator {
+ z-index: 103;
+}
+.filepond--file-action-button {
+ z-index: 102;
+}
+.filepond--file-status {
+ z-index: 101;
+}
+.filepond--file-info {
+ z-index: 100;
+}
+.filepond--item {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ z-index: 1;
+
+ padding: 0;
+ margin: 0.25em;
+
+ will-change: transform, opacity;
+
+ /* item children order */
+}
+.filepond--item > .filepond--panel {
+ z-index: -1;
+}
+/* has a slight shadow */
+.filepond--item > .filepond--panel .filepond--panel-bottom {
+ box-shadow: 0 0.0625em 0.125em -0.0625em rgba(0, 0, 0, 0.25);
+}
+.filepond--item {
+ /* drag related */
+}
+.filepond--item > .filepond--file-wrapper,
+.filepond--item > .filepond--panel {
+ transition: opacity 0.15s ease-out;
+}
+.filepond--item[data-drag-state] {
+ cursor: -webkit-grab;
+ cursor: grab;
+}
+.filepond--item[data-drag-state] > .filepond--panel {
+ transition: box-shadow 0.125s ease-in-out;
+ box-shadow: 0 0 0 rgba(0, 0, 0, 0);
+}
+.filepond--item[data-drag-state='drag'] {
+ cursor: -webkit-grabbing;
+ cursor: grabbing;
+}
+.filepond--item[data-drag-state='drag'] > .filepond--panel {
+ box-shadow: 0 0.125em 0.3125em rgba(0, 0, 0, 0.325);
+}
+.filepond--item[data-drag-state]:not([data-drag-state='idle']) {
+ z-index: 2;
+}
+/* states */
+.filepond--item-panel {
+ background-color: #64605e;
+}
+[data-filepond-item-state='processing-complete'] .filepond--item-panel {
+ background-color: #369763;
+}
+[data-filepond-item-state*='invalid'] .filepond--item-panel,
+[data-filepond-item-state*='error'] .filepond--item-panel {
+ background-color: #c44e47;
+}
+/* style of item panel */
+.filepond--item-panel {
+ border-radius: 0.5em;
+ transition: background-color 0.25s;
+}
+/* normal mode */
+.filepond--list-scroller {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ margin: 0;
+ will-change: transform;
+}
+/* scroll mode */
+.filepond--list-scroller[data-state='overflow'] .filepond--list {
+ bottom: 0;
+ right: 0;
+}
+.filepond--list-scroller[data-state='overflow'] {
+ overflow-y: scroll;
+ overflow-x: hidden;
+ -webkit-overflow-scrolling: touch;
+ -webkit-mask: linear-gradient(to bottom, #000 calc(100% - 0.5em), transparent 100%);
+ mask: linear-gradient(to bottom, #000 calc(100% - 0.5em), transparent 100%);
+}
+/* style scrollbar */
+.filepond--list-scroller::-webkit-scrollbar {
+ background: transparent;
+}
+.filepond--list-scroller::-webkit-scrollbar:vertical {
+ width: 1em;
+}
+.filepond--list-scroller::-webkit-scrollbar:horizontal {
+ height: 0;
+}
+.filepond--list-scroller::-webkit-scrollbar-thumb {
+ background-color: rgba(0, 0, 0, 0.3);
+ border-radius: 99999px;
+ border: 0.3125em solid transparent;
+ background-clip: content-box;
+}
+/* hard to overide styles on purpose */
+.filepond--list.filepond--list {
+ position: absolute;
+ top: 0;
+ margin: 0;
+ padding: 0;
+ list-style-type: none;
+
+ /* prevents endless paint calls on filepond--list-scroller */
+ will-change: transform;
+}
+/* used for padding so allowed to be restyled */
+.filepond--list {
+ left: 0.75em;
+ right: 0.75em;
+}
+.filepond--root[data-style-panel-layout~='integrated'] {
+ width: 100%;
+ height: 100%;
+ max-width: none;
+ margin: 0;
+}
+.filepond--root[data-style-panel-layout~='circle'] .filepond--panel-root,
+.filepond--root[data-style-panel-layout~='integrated'] .filepond--panel-root {
+ border-radius: 0;
+}
+.filepond--root[data-style-panel-layout~='circle'] .filepond--panel-root > *,
+.filepond--root[data-style-panel-layout~='integrated'] .filepond--panel-root > * {
+ display: none;
+}
+.filepond--root[data-style-panel-layout~='circle'] .filepond--drop-label,
+.filepond--root[data-style-panel-layout~='integrated'] .filepond--drop-label {
+ bottom: 0;
+ height: auto;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 7;
+}
+.filepond--root[data-style-panel-layout~='circle'],
+.filepond--root[data-style-panel-layout~='integrated'] {
+ /* we're only loading one item, this makes the intro animation a bit nicer */
+}
+.filepond--root[data-style-panel-layout~='circle'] .filepond--item-panel,
+.filepond--root[data-style-panel-layout~='integrated'] .filepond--item-panel {
+ display: none;
+}
+.filepond--root[data-style-panel-layout~='compact'] .filepond--list-scroller,
+.filepond--root[data-style-panel-layout~='integrated'] .filepond--list-scroller {
+ overflow: hidden;
+ height: 100%;
+ margin-top: 0;
+ margin-bottom: 0;
+}
+.filepond--root[data-style-panel-layout~='compact'] .filepond--list,
+.filepond--root[data-style-panel-layout~='integrated'] .filepond--list {
+ left: 0;
+ right: 0;
+ height: 100%;
+}
+.filepond--root[data-style-panel-layout~='compact'] .filepond--item,
+.filepond--root[data-style-panel-layout~='integrated'] .filepond--item {
+ margin: 0;
+}
+.filepond--root[data-style-panel-layout~='compact'] .filepond--file-wrapper,
+.filepond--root[data-style-panel-layout~='integrated'] .filepond--file-wrapper {
+ height: 100%;
+}
+.filepond--root[data-style-panel-layout~='compact'] .filepond--drop-label,
+.filepond--root[data-style-panel-layout~='integrated'] .filepond--drop-label {
+ z-index: 7;
+}
+.filepond--root[data-style-panel-layout~='circle'] {
+ border-radius: 99999rem;
+ overflow: hidden;
+}
+.filepond--root[data-style-panel-layout~='circle'] > .filepond--panel {
+ border-radius: inherit;
+}
+.filepond--root[data-style-panel-layout~='circle'] > .filepond--panel > * {
+ display: none;
+}
+.filepond--root[data-style-panel-layout~='circle'] {
+ /* circle cuts of this info, so best to hide it */
+}
+.filepond--root[data-style-panel-layout~='circle'] .filepond--file-info {
+ display: none;
+}
+.filepond--root[data-style-panel-layout~='circle'] .filepond--file-status {
+ display: none;
+}
+.filepond--root[data-style-panel-layout~='circle'] .filepond--action-edit-item {
+ opacity: 1 !important;
+ visibility: visible !important;
+}
+/* dirfty way to fix circular overflow issue on safari 11+ */
+@media not all and (min-resolution: 0.001dpcm) {
+ @supports (-webkit-appearance: none) and (stroke-color: transparent) {
+ .filepond--root[data-style-panel-layout~='circle'] {
+ will-change: transform;
+ }
+ }
+}
+.filepond--panel-root {
+ border-radius: 0.5em;
+ background-color: #f1f0ef;
+}
+.filepond--panel {
+ position: absolute;
+ left: 0;
+ top: 0;
+ right: 0;
+ margin: 0;
+
+ /* defaults to 100% height (fixed height mode) this fixes problem with panel height in IE11 */
+ height: 100% !important;
+
+ /* no interaction possible with panel */
+ pointer-events: none;
+}
+.filepond-panel:not([data-scalable='false']) {
+ height: auto !important;
+}
+.filepond--panel[data-scalable='false'] > div {
+ display: none;
+}
+.filepond--panel[data-scalable='true'] {
+ /* this seems to fix Chrome performance issues */
+ /* - when box-shadow is enabled */
+ /* - when multiple ponds are active on the same page */
+ -webkit-transform-style: preserve-3d;
+ transform-style: preserve-3d;
+
+ /* prevent borders and backgrounds */
+ background-color: transparent !important;
+ border: none !important;
+}
+.filepond--panel-top,
+.filepond--panel-bottom,
+.filepond--panel-center {
+ position: absolute;
+ left: 0;
+ top: 0;
+ right: 0;
+ margin: 0;
+ padding: 0;
+}
+.filepond--panel-top,
+.filepond--panel-bottom {
+ height: 0.5em;
+}
+.filepond--panel-top {
+ border-bottom-left-radius: 0 !important;
+ border-bottom-right-radius: 0 !important;
+ border-bottom: none !important;
+
+ /* fixes tiny transparant line between top and center panel */
+}
+.filepond--panel-top::after {
+ content: '';
+ position: absolute;
+ height: 2px;
+ left: 0;
+ right: 0;
+ bottom: -1px;
+ background-color: inherit;
+}
+.filepond--panel-center,
+.filepond--panel-bottom {
+ will-change: transform;
+ -webkit-backface-visibility: hidden;
+ backface-visibility: hidden;
+ -webkit-transform-origin: left top;
+ transform-origin: left top;
+ -webkit-transform: translate3d(0, 0.5em, 0);
+ transform: translate3d(0, 0.5em, 0);
+}
+.filepond--panel-bottom {
+ border-top-left-radius: 0 !important;
+ border-top-right-radius: 0 !important;
+ border-top: none !important;
+
+ /* fixes tiny transparant line between bottom and center of panel */
+}
+.filepond--panel-bottom::before {
+ content: '';
+ position: absolute;
+ height: 2px;
+ left: 0;
+ right: 0;
+ top: -1px;
+ background-color: inherit;
+}
+.filepond--panel-center {
+ /* the center panel is scaled using scale3d to fit the correct height */
+ /* we use 100px instead of 1px as scaling 1px to a huge height is really laggy on chrome */
+ height: 100px !important;
+ border-top: none !important;
+ border-bottom: none !important;
+ border-radius: 0 !important;
+
+ /* hide if not transformed, prevents a little flash when the panel is at 100px height while attached for first time */
+}
+.filepond--panel-center:not([style]) {
+ visibility: hidden;
+}
+.filepond--progress-indicator {
+ position: static;
+ width: 1.25em;
+ height: 1.25em;
+
+ color: #fff;
+
+ /* can't have margins */
+ margin: 0;
+
+ /* no interaction possible with progress indicator */
+ pointer-events: none;
+
+ /* will be animated */
+ will-change: transform, opacity;
+}
+.filepond--progress-indicator svg {
+ width: 100%;
+ height: 100%;
+ vertical-align: top;
+ transform-box: fill-box; /* should center the animation correctly when zoomed in */
+}
+.filepond--progress-indicator path {
+ fill: none;
+ stroke: currentColor;
+}
+.filepond--list-scroller {
+ z-index: 6;
+}
+.filepond--drop-label {
+ z-index: 5;
+}
+.filepond--drip {
+ z-index: 3;
+}
+.filepond--root > .filepond--panel {
+ z-index: 2;
+}
+.filepond--browser {
+ z-index: 1;
+}
+.filepond--root {
+ /* layout*/
+ box-sizing: border-box;
+ position: relative;
+ margin-bottom: 1em;
+
+ /* base font size for whole component */
+ font-size: 1rem;
+
+ /* base line height */
+ line-height: normal;
+
+ /* up uses default system font family */
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif,
+ 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
+
+ /* will increase font weight a bit on Safari */
+ font-weight: 450;
+
+ /* default text alignment */
+ text-align: left;
+
+ /* better text rendering on Safari */
+ text-rendering: optimizeLegibility;
+
+ /* text direction is ltr for now */
+ direction: ltr;
+
+ /* optimize rendering */
+ /* https://developer.mozilla.org/en-US/docs/Web/CSS/contain */
+ contain: layout style size;
+
+ /* correct box sizing, line-height and positioning on child elements */
+}
+.filepond--root * {
+ box-sizing: inherit;
+ line-height: inherit;
+}
+.filepond--root *:not(text) {
+ font-size: inherit;
+}
+.filepond--root {
+ /* block everything */
+}
+.filepond--root[data-disabled] {
+ pointer-events: none;
+}
+.filepond--root[data-disabled] .filepond--list-scroller {
+ pointer-events: all;
+}
+.filepond--root[data-disabled] .filepond--list {
+ pointer-events: none;
+}
+/**
+ * Root element children layout
+ */
+.filepond--root .filepond--drop-label {
+ min-height: 4.75em;
+}
+.filepond--root .filepond--list-scroller {
+ margin-top: 1em;
+ margin-bottom: 1em;
+}
+.filepond--root .filepond--credits {
+ position: absolute;
+ right: 0;
+ opacity: 0.175;
+ line-height: 0.85;
+ font-size: 11px;
+ color: inherit;
+ text-decoration: none;
+ z-index: 3;
+ bottom: -14px;
+}
+.filepond--root .filepond--credits[style] {
+ top: 0;
+ bottom: auto;
+ margin-top: 14px;
+}
diff --git a/public/dist/heatmap.min.js b/public/dist/heatmap.min.js
new file mode 100644
index 0000000..9004bb3
--- /dev/null
+++ b/public/dist/heatmap.min.js
@@ -0,0 +1,9 @@
+/*
+ * heatmap.js v2.0.2 | JavaScript Heatmap Library
+ *
+ * Copyright 2008-2016 Patrick Wied - All rights reserved.
+ * Dual licensed under MIT and Beerware license
+ *
+ * :: 2016-02-04 21:25
+ */
+(function(a,b,c){if(typeof module!=="undefined"&&module.exports){module.exports=c()}else if(typeof define==="function"&&define.amd){define(c)}else{b[a]=c()}})("h337",this,function(){var a={defaultRadius:40,defaultRenderer:"canvas2d",defaultGradient:{.25:"rgb(0,0,255)",.55:"rgb(0,255,0)",.85:"yellow",1:"rgb(255,0,0)"},defaultMaxOpacity:1,defaultMinOpacity:0,defaultBlur:.85,defaultXField:"x",defaultYField:"y",defaultValueField:"value",plugins:{}};var b=function h(){var b=function d(a){this._coordinator={};this._data=[];this._radi=[];this._min=0;this._max=1;this._xField=a["xField"]||a.defaultXField;this._yField=a["yField"]||a.defaultYField;this._valueField=a["valueField"]||a.defaultValueField;if(a["radius"]){this._cfgRadius=a["radius"]}};var c=a.defaultRadius;b.prototype={_organiseData:function(a,b){var d=a[this._xField];var e=a[this._yField];var f=this._radi;var g=this._data;var h=this._max;var i=this._min;var j=a[this._valueField]||1;var k=a.radius||this._cfgRadius||c;if(!g[d]){g[d]=[];f[d]=[]}if(!g[d][e]){g[d][e]=j;f[d][e]=k}else{g[d][e]+=j}if(g[d][e]>h){if(!b){this._max=g[d][e]}else{this.setDataMax(g[d][e])}return false}else{return{x:d,y:e,value:j,radius:k,min:i,max:h}}},_unOrganizeData:function(){var a=[];var b=this._data;var c=this._radi;for(var d in b){for(var e in b[d]){a.push({x:d,y:e,radius:c[d][e],value:b[d][e]})}}return{min:this._min,max:this._max,data:a}},_onExtremaChange:function(){this._coordinator.emit("extremachange",{min:this._min,max:this._max})},addData:function(){if(arguments[0].length>0){var a=arguments[0];var b=a.length;while(b--){this.addData.call(this,a[b])}}else{var c=this._organiseData(arguments[0],true);if(c){this._coordinator.emit("renderpartial",{min:this._min,max:this._max,data:[c]})}}return this},setData:function(a){var b=a.data;var c=b.length;this._data=[];this._radi=[];for(var d=0;d0){this._drawAlpha(a);this._colorize()}},renderAll:function(a){this._clear();if(a.data.length>0){this._drawAlpha(c(a));this._colorize()}},_updateGradient:function(b){this._palette=a(b)},updateConfig:function(a){if(a["gradient"]){this._updateGradient(a)}this._setStyles(a)},setDimensions:function(a,b){this._width=a;this._height=b;this.canvas.width=this.shadowCanvas.width=a;this.canvas.height=this.shadowCanvas.height=b},_clear:function(){this.shadowCtx.clearRect(0,0,this._width,this._height);this.ctx.clearRect(0,0,this._width,this._height)},_setStyles:function(a){this._blur=a.blur==0?0:a.blur||a.defaultBlur;if(a.backgroundColor){this.canvas.style.backgroundColor=a.backgroundColor}this._width=this.canvas.width=this.shadowCanvas.width=a.width||this._width;this._height=this.canvas.height=this.shadowCanvas.height=a.height||this._height;this._opacity=(a.opacity||0)*255;this._maxOpacity=(a.maxOpacity||a.defaultMaxOpacity)*255;this._minOpacity=(a.minOpacity||a.defaultMinOpacity)*255;this._useGradientOpacity=!!a.useGradientOpacity},_drawAlpha:function(a){var c=this._min=a.min;var d=this._max=a.max;var a=a.data||[];var e=a.length;var f=1-this._blur;while(e--){var g=a[e];var h=g.x;var i=g.y;var j=g.radius;var k=Math.min(g.value,d);var l=h-j;var m=i-j;var n=this.shadowCtx;var o;if(!this._templates[j]){this._templates[j]=o=b(j,f)}else{o=this._templates[j]}var p=(k-c)/(d-c);n.globalAlpha=p<.01?.01:p;n.drawImage(o,l,m);if(lthis._renderBoundaries[2]){this._renderBoundaries[2]=l+2*j}if(m+2*j>this._renderBoundaries[3]){this._renderBoundaries[3]=m+2*j}}},_colorize:function(){var a=this._renderBoundaries[0];var b=this._renderBoundaries[1];var c=this._renderBoundaries[2]-a;var d=this._renderBoundaries[3]-b;var e=this._width;var f=this._height;var g=this._opacity;var h=this._maxOpacity;var i=this._minOpacity;var j=this._useGradientOpacity;if(a<0){a=0}if(b<0){b=0}if(a+c>e){c=e-a}if(b+d>f){d=f-b}var k=this.shadowCtx.getImageData(a,b,c,d);var l=k.data;var m=l.length;var n=this._palette;for(var o=3;o0){r=g}else{if(p>0;return b},getDataURL:function(){return this.canvas.toDataURL()}};return d}();var d=function j(){var b=false;if(a["defaultRenderer"]==="canvas2d"){b=c}return b}();var e={merge:function(){var a={};var b=arguments.length;for(var c=0;c elements
+ // (i.e., `typeof document.createElement( "object" ) === "function"`).
+ // We don't want to classify *any* DOM node as a function.
+ // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5
+ // Plus for old WebKit, typeof returns "function" for HTML collections
+ // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756)
+ return typeof obj === "function" && typeof obj.nodeType !== "number" &&
+ typeof obj.item !== "function";
+ };
+
+
+ var isWindow = function isWindow( obj ) {
+ return obj != null && obj === obj.window;
+ };
+
+
+ var document = window.document;
+
+
+
+ var preservedScriptAttributes = {
+ type: true,
+ src: true,
+ nonce: true,
+ noModule: true
+ };
+
+ function DOMEval( code, node, doc ) {
+ doc = doc || document;
+
+ var i, val,
+ script = doc.createElement( "script" );
+
+ script.text = code;
+ if ( node ) {
+ for ( i in preservedScriptAttributes ) {
+
+ // Support: Firefox 64+, Edge 18+
+ // Some browsers don't support the "nonce" property on scripts.
+ // On the other hand, just using `getAttribute` is not enough as
+ // the `nonce` attribute is reset to an empty string whenever it
+ // becomes browsing-context connected.
+ // See https://github.com/whatwg/html/issues/2369
+ // See https://html.spec.whatwg.org/#nonce-attributes
+ // The `node.getAttribute` check was added for the sake of
+ // `jQuery.globalEval` so that it can fake a nonce-containing node
+ // via an object.
+ val = node[ i ] || node.getAttribute && node.getAttribute( i );
+ if ( val ) {
+ script.setAttribute( i, val );
+ }
+ }
+ }
+ doc.head.appendChild( script ).parentNode.removeChild( script );
+ }
+
+
+ function toType( obj ) {
+ if ( obj == null ) {
+ return obj + "";
+ }
+
+ // Support: Android <=2.3 only (functionish RegExp)
+ return typeof obj === "object" || typeof obj === "function" ?
+ class2type[ toString.call( obj ) ] || "object" :
+ typeof obj;
+ }
+ /* global Symbol */
+ // Defining this global in .eslintrc.json would create a danger of using the global
+ // unguarded in another place, it seems safer to define global only for this module
+
+
+
+ var
+ version = "3.6.3",
+
+ // Define a local copy of jQuery
+ jQuery = function( selector, context ) {
+
+ // The jQuery object is actually just the init constructor 'enhanced'
+ // Need init if jQuery is called (just allow error to be thrown if not included)
+ return new jQuery.fn.init( selector, context );
+ };
+
+ jQuery.fn = jQuery.prototype = {
+
+ // The current version of jQuery being used
+ jquery: version,
+
+ constructor: jQuery,
+
+ // The default length of a jQuery object is 0
+ length: 0,
+
+ toArray: function() {
+ return slice.call( this );
+ },
+
+ // Get the Nth element in the matched element set OR
+ // Get the whole matched element set as a clean array
+ get: function( num ) {
+
+ // Return all the elements in a clean array
+ if ( num == null ) {
+ return slice.call( this );
+ }
+
+ // Return just the one element from the set
+ return num < 0 ? this[ num + this.length ] : this[ num ];
+ },
+
+ // Take an array of elements and push it onto the stack
+ // (returning the new matched element set)
+ pushStack: function( elems ) {
+
+ // Build a new jQuery matched element set
+ var ret = jQuery.merge( this.constructor(), elems );
+
+ // Add the old object onto the stack (as a reference)
+ ret.prevObject = this;
+
+ // Return the newly-formed element set
+ return ret;
+ },
+
+ // Execute a callback for every element in the matched set.
+ each: function( callback ) {
+ return jQuery.each( this, callback );
+ },
+
+ map: function( callback ) {
+ return this.pushStack( jQuery.map( this, function( elem, i ) {
+ return callback.call( elem, i, elem );
+ } ) );
+ },
+
+ slice: function() {
+ return this.pushStack( slice.apply( this, arguments ) );
+ },
+
+ first: function() {
+ return this.eq( 0 );
+ },
+
+ last: function() {
+ return this.eq( -1 );
+ },
+
+ even: function() {
+ return this.pushStack( jQuery.grep( this, function( _elem, i ) {
+ return ( i + 1 ) % 2;
+ } ) );
+ },
+
+ odd: function() {
+ return this.pushStack( jQuery.grep( this, function( _elem, i ) {
+ return i % 2;
+ } ) );
+ },
+
+ eq: function( i ) {
+ var len = this.length,
+ j = +i + ( i < 0 ? len : 0 );
+ return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
+ },
+
+ end: function() {
+ return this.prevObject || this.constructor();
+ },
+
+ // For internal use only.
+ // Behaves like an Array's method, not like a jQuery method.
+ push: push,
+ sort: arr.sort,
+ splice: arr.splice
+ };
+
+ jQuery.extend = jQuery.fn.extend = function() {
+ var options, name, src, copy, copyIsArray, clone,
+ target = arguments[ 0 ] || {},
+ i = 1,
+ length = arguments.length,
+ deep = false;
+
+ // Handle a deep copy situation
+ if ( typeof target === "boolean" ) {
+ deep = target;
+
+ // Skip the boolean and the target
+ target = arguments[ i ] || {};
+ i++;
+ }
+
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target !== "object" && !isFunction( target ) ) {
+ target = {};
+ }
+
+ // Extend jQuery itself if only one argument is passed
+ if ( i === length ) {
+ target = this;
+ i--;
+ }
+
+ for ( ; i < length; i++ ) {
+
+ // Only deal with non-null/undefined values
+ if ( ( options = arguments[ i ] ) != null ) {
+
+ // Extend the base object
+ for ( name in options ) {
+ copy = options[ name ];
+
+ // Prevent Object.prototype pollution
+ // Prevent never-ending loop
+ if ( name === "__proto__" || target === copy ) {
+ continue;
+ }
+
+ // Recurse if we're merging plain objects or arrays
+ if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
+ ( copyIsArray = Array.isArray( copy ) ) ) ) {
+ src = target[ name ];
+
+ // Ensure proper type for the source value
+ if ( copyIsArray && !Array.isArray( src ) ) {
+ clone = [];
+ } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {
+ clone = {};
+ } else {
+ clone = src;
+ }
+ copyIsArray = false;
+
+ // Never move original objects, clone them
+ target[ name ] = jQuery.extend( deep, clone, copy );
+
+ // Don't bring in undefined values
+ } else if ( copy !== undefined ) {
+ target[ name ] = copy;
+ }
+ }
+ }
+ }
+
+ // Return the modified object
+ return target;
+ };
+
+ jQuery.extend( {
+
+ // Unique for each copy of jQuery on the page
+ expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
+
+ // Assume jQuery is ready without the ready module
+ isReady: true,
+
+ error: function( msg ) {
+ throw new Error( msg );
+ },
+
+ noop: function() {},
+
+ isPlainObject: function( obj ) {
+ var proto, Ctor;
+
+ // Detect obvious negatives
+ // Use toString instead of jQuery.type to catch host objects
+ if ( !obj || toString.call( obj ) !== "[object Object]" ) {
+ return false;
+ }
+
+ proto = getProto( obj );
+
+ // Objects with no prototype (e.g., `Object.create( null )`) are plain
+ if ( !proto ) {
+ return true;
+ }
+
+ // Objects with prototype are plain iff they were constructed by a global Object function
+ Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
+ return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
+ },
+
+ isEmptyObject: function( obj ) {
+ var name;
+
+ for ( name in obj ) {
+ return false;
+ }
+ return true;
+ },
+
+ // Evaluates a script in a provided context; falls back to the global one
+ // if not specified.
+ globalEval: function( code, options, doc ) {
+ DOMEval( code, { nonce: options && options.nonce }, doc );
+ },
+
+ each: function( obj, callback ) {
+ var length, i = 0;
+
+ if ( isArrayLike( obj ) ) {
+ length = obj.length;
+ for ( ; i < length; i++ ) {
+ if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( i in obj ) {
+ if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
+ break;
+ }
+ }
+ }
+
+ return obj;
+ },
+
+ // results is for internal usage only
+ makeArray: function( arr, results ) {
+ var ret = results || [];
+
+ if ( arr != null ) {
+ if ( isArrayLike( Object( arr ) ) ) {
+ jQuery.merge( ret,
+ typeof arr === "string" ?
+ [ arr ] : arr
+ );
+ } else {
+ push.call( ret, arr );
+ }
+ }
+
+ return ret;
+ },
+
+ inArray: function( elem, arr, i ) {
+ return arr == null ? -1 : indexOf.call( arr, elem, i );
+ },
+
+ // Support: Android <=4.0 only, PhantomJS 1 only
+ // push.apply(_, arraylike) throws on ancient WebKit
+ merge: function( first, second ) {
+ var len = +second.length,
+ j = 0,
+ i = first.length;
+
+ for ( ; j < len; j++ ) {
+ first[ i++ ] = second[ j ];
+ }
+
+ first.length = i;
+
+ return first;
+ },
+
+ grep: function( elems, callback, invert ) {
+ var callbackInverse,
+ matches = [],
+ i = 0,
+ length = elems.length,
+ callbackExpect = !invert;
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( ; i < length; i++ ) {
+ callbackInverse = !callback( elems[ i ], i );
+ if ( callbackInverse !== callbackExpect ) {
+ matches.push( elems[ i ] );
+ }
+ }
+
+ return matches;
+ },
+
+ // arg is for internal usage only
+ map: function( elems, callback, arg ) {
+ var length, value,
+ i = 0,
+ ret = [];
+
+ // Go through the array, translating each of the items to their new values
+ if ( isArrayLike( elems ) ) {
+ length = elems.length;
+ for ( ; i < length; i++ ) {
+ value = callback( elems[ i ], i, arg );
+
+ if ( value != null ) {
+ ret.push( value );
+ }
+ }
+
+ // Go through every key on the object,
+ } else {
+ for ( i in elems ) {
+ value = callback( elems[ i ], i, arg );
+
+ if ( value != null ) {
+ ret.push( value );
+ }
+ }
+ }
+
+ // Flatten any nested arrays
+ return flat( ret );
+ },
+
+ // A global GUID counter for objects
+ guid: 1,
+
+ // jQuery.support is not used in Core but other projects attach their
+ // properties to it so it needs to exist.
+ support: support
+ } );
+
+ if ( typeof Symbol === "function" ) {
+ jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
+ }
+
+ // Populate the class2type map
+ jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
+ function( _i, name ) {
+ class2type[ "[object " + name + "]" ] = name.toLowerCase();
+ } );
+
+ function isArrayLike( obj ) {
+
+ // Support: real iOS 8.2 only (not reproducible in simulator)
+ // `in` check used to prevent JIT error (gh-2145)
+ // hasOwn isn't used here due to false negatives
+ // regarding Nodelist length in IE
+ var length = !!obj && "length" in obj && obj.length,
+ type = toType( obj );
+
+ if ( isFunction( obj ) || isWindow( obj ) ) {
+ return false;
+ }
+
+ return type === "array" || length === 0 ||
+ typeof length === "number" && length > 0 && ( length - 1 ) in obj;
+ }
+ var Sizzle =
+ /*!
+ * Sizzle CSS Selector Engine v2.3.9
+ * https://sizzlejs.com/
+ *
+ * Copyright JS Foundation and other contributors
+ * Released under the MIT license
+ * https://js.foundation/
+ *
+ * Date: 2022-12-19
+ */
+ ( function( window ) {
+ var i,
+ support,
+ Expr,
+ getText,
+ isXML,
+ tokenize,
+ compile,
+ select,
+ outermostContext,
+ sortInput,
+ hasDuplicate,
+
+ // Local document vars
+ setDocument,
+ document,
+ docElem,
+ documentIsHTML,
+ rbuggyQSA,
+ rbuggyMatches,
+ matches,
+ contains,
+
+ // Instance-specific data
+ expando = "sizzle" + 1 * new Date(),
+ preferredDoc = window.document,
+ dirruns = 0,
+ done = 0,
+ classCache = createCache(),
+ tokenCache = createCache(),
+ compilerCache = createCache(),
+ nonnativeSelectorCache = createCache(),
+ sortOrder = function( a, b ) {
+ if ( a === b ) {
+ hasDuplicate = true;
+ }
+ return 0;
+ },
+
+ // Instance methods
+ hasOwn = ( {} ).hasOwnProperty,
+ arr = [],
+ pop = arr.pop,
+ pushNative = arr.push,
+ push = arr.push,
+ slice = arr.slice,
+
+ // Use a stripped-down indexOf as it's faster than native
+ // https://jsperf.com/thor-indexof-vs-for/5
+ indexOf = function( list, elem ) {
+ var i = 0,
+ len = list.length;
+ for ( ; i < len; i++ ) {
+ if ( list[ i ] === elem ) {
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" +
+ "ismap|loop|multiple|open|readonly|required|scoped",
+
+ // Regular expressions
+
+ // http://www.w3.org/TR/css3-selectors/#whitespace
+ whitespace = "[\\x20\\t\\r\\n\\f]",
+
+ // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram
+ identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace +
+ "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",
+
+ // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
+ attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
+
+ // Operator (capture 2)
+ "*([*^$|!~]?=)" + whitespace +
+
+ // "Attribute values must be CSS identifiers [capture 5]
+ // or strings [capture 3 or capture 4]"
+ "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" +
+ whitespace + "*\\]",
+
+ pseudos = ":(" + identifier + ")(?:\\((" +
+
+ // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
+ // 1. quoted (capture 3; capture 4 or capture 5)
+ "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
+
+ // 2. simple (capture 6)
+ "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
+
+ // 3. anything else (capture 2)
+ ".*" +
+ ")\\)|)",
+
+ // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
+ rwhitespace = new RegExp( whitespace + "+", "g" ),
+ rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" +
+ whitespace + "+$", "g" ),
+
+ rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
+ rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace +
+ "*" ),
+ rdescend = new RegExp( whitespace + "|>" ),
+
+ rpseudo = new RegExp( pseudos ),
+ ridentifier = new RegExp( "^" + identifier + "$" ),
+
+ matchExpr = {
+ "ID": new RegExp( "^#(" + identifier + ")" ),
+ "CLASS": new RegExp( "^\\.(" + identifier + ")" ),
+ "TAG": new RegExp( "^(" + identifier + "|[*])" ),
+ "ATTR": new RegExp( "^" + attributes ),
+ "PSEUDO": new RegExp( "^" + pseudos ),
+ "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" +
+ whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" +
+ whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
+ "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
+
+ // For use in libraries implementing .is()
+ // We use this for POS matching in `select`
+ "needsContext": new RegExp( "^" + whitespace +
+ "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
+ "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
+ },
+
+ rhtml = /HTML$/i,
+ rinputs = /^(?:input|select|textarea|button)$/i,
+ rheader = /^h\d$/i,
+
+ rnative = /^[^{]+\{\s*\[native \w/,
+
+ // Easily-parseable/retrievable ID or TAG or CLASS selectors
+ rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
+
+ rsibling = /[+~]/,
+
+ // CSS escapes
+ // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
+ runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ),
+ funescape = function( escape, nonHex ) {
+ var high = "0x" + escape.slice( 1 ) - 0x10000;
+
+ return nonHex ?
+
+ // Strip the backslash prefix from a non-hex escape sequence
+ nonHex :
+
+ // Replace a hexadecimal escape sequence with the encoded Unicode code point
+ // Support: IE <=11+
+ // For values outside the Basic Multilingual Plane (BMP), manually construct a
+ // surrogate pair
+ high < 0 ?
+ String.fromCharCode( high + 0x10000 ) :
+ String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
+ },
+
+ // CSS string/identifier serialization
+ // https://drafts.csswg.org/cssom/#common-serializing-idioms
+ rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
+ fcssescape = function( ch, asCodePoint ) {
+ if ( asCodePoint ) {
+
+ // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
+ if ( ch === "\0" ) {
+ return "\uFFFD";
+ }
+
+ // Control characters and (dependent upon position) numbers get escaped as code points
+ return ch.slice( 0, -1 ) + "\\" +
+ ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
+ }
+
+ // Other potentially-special ASCII characters get backslash-escaped
+ return "\\" + ch;
+ },
+
+ // Used for iframes
+ // See setDocument()
+ // Removing the function wrapper causes a "Permission Denied"
+ // error in IE
+ unloadHandler = function() {
+ setDocument();
+ },
+
+ inDisabledFieldset = addCombinator(
+ function( elem ) {
+ return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset";
+ },
+ { dir: "parentNode", next: "legend" }
+ );
+
+ // Optimize for push.apply( _, NodeList )
+ try {
+ push.apply(
+ ( arr = slice.call( preferredDoc.childNodes ) ),
+ preferredDoc.childNodes
+ );
+
+ // Support: Android<4.0
+ // Detect silently failing push.apply
+ // eslint-disable-next-line no-unused-expressions
+ arr[ preferredDoc.childNodes.length ].nodeType;
+ } catch ( e ) {
+ push = { apply: arr.length ?
+
+ // Leverage slice if possible
+ function( target, els ) {
+ pushNative.apply( target, slice.call( els ) );
+ } :
+
+ // Support: IE<9
+ // Otherwise append directly
+ function( target, els ) {
+ var j = target.length,
+ i = 0;
+
+ // Can't trust NodeList.length
+ while ( ( target[ j++ ] = els[ i++ ] ) ) {}
+ target.length = j - 1;
+ }
+ };
+ }
+
+ function Sizzle( selector, context, results, seed ) {
+ var m, i, elem, nid, match, groups, newSelector,
+ newContext = context && context.ownerDocument,
+
+ // nodeType defaults to 9, since context defaults to document
+ nodeType = context ? context.nodeType : 9;
+
+ results = results || [];
+
+ // Return early from calls with invalid selector or context
+ if ( typeof selector !== "string" || !selector ||
+ nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
+
+ return results;
+ }
+
+ // Try to shortcut find operations (as opposed to filters) in HTML documents
+ if ( !seed ) {
+ setDocument( context );
+ context = context || document;
+
+ if ( documentIsHTML ) {
+
+ // If the selector is sufficiently simple, try using a "get*By*" DOM method
+ // (excepting DocumentFragment context, where the methods don't exist)
+ if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) {
+
+ // ID selector
+ if ( ( m = match[ 1 ] ) ) {
+
+ // Document context
+ if ( nodeType === 9 ) {
+ if ( ( elem = context.getElementById( m ) ) ) {
+
+ // Support: IE, Opera, Webkit
+ // TODO: identify versions
+ // getElementById can match elements by name instead of ID
+ if ( elem.id === m ) {
+ results.push( elem );
+ return results;
+ }
+ } else {
+ return results;
+ }
+
+ // Element context
+ } else {
+
+ // Support: IE, Opera, Webkit
+ // TODO: identify versions
+ // getElementById can match elements by name instead of ID
+ if ( newContext && ( elem = newContext.getElementById( m ) ) &&
+ contains( context, elem ) &&
+ elem.id === m ) {
+
+ results.push( elem );
+ return results;
+ }
+ }
+
+ // Type selector
+ } else if ( match[ 2 ] ) {
+ push.apply( results, context.getElementsByTagName( selector ) );
+ return results;
+
+ // Class selector
+ } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName &&
+ context.getElementsByClassName ) {
+
+ push.apply( results, context.getElementsByClassName( m ) );
+ return results;
+ }
+ }
+
+ // Take advantage of querySelectorAll
+ if ( support.qsa &&
+ !nonnativeSelectorCache[ selector + " " ] &&
+ ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) &&
+
+ // Support: IE 8 only
+ // Exclude object elements
+ ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) {
+
+ newSelector = selector;
+ newContext = context;
+
+ // qSA considers elements outside a scoping root when evaluating child or
+ // descendant combinators, which is not what we want.
+ // In such cases, we work around the behavior by prefixing every selector in the
+ // list with an ID selector referencing the scope context.
+ // The technique has to be used as well when a leading combinator is used
+ // as such selectors are not recognized by querySelectorAll.
+ // Thanks to Andrew Dupont for this technique.
+ if ( nodeType === 1 &&
+ ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) {
+
+ // Expand context for sibling selectors
+ newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
+ context;
+
+ // We can use :scope instead of the ID hack if the browser
+ // supports it & if we're not changing the context.
+ if ( newContext !== context || !support.scope ) {
+
+ // Capture the context ID, setting it first if necessary
+ if ( ( nid = context.getAttribute( "id" ) ) ) {
+ nid = nid.replace( rcssescape, fcssescape );
+ } else {
+ context.setAttribute( "id", ( nid = expando ) );
+ }
+ }
+
+ // Prefix every selector in the list
+ groups = tokenize( selector );
+ i = groups.length;
+ while ( i-- ) {
+ groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " +
+ toSelector( groups[ i ] );
+ }
+ newSelector = groups.join( "," );
+ }
+
+ try {
+
+ // `qSA` may not throw for unrecognized parts using forgiving parsing:
+ // https://drafts.csswg.org/selectors/#forgiving-selector
+ // like the `:has()` pseudo-class:
+ // https://drafts.csswg.org/selectors/#relational
+ // `CSS.supports` is still expected to return `false` then:
+ // https://drafts.csswg.org/css-conditional-4/#typedef-supports-selector-fn
+ // https://drafts.csswg.org/css-conditional-4/#dfn-support-selector
+ if ( support.cssSupportsSelector &&
+
+ // eslint-disable-next-line no-undef
+ !CSS.supports( "selector(:is(" + newSelector + "))" ) ) {
+
+ // Support: IE 11+
+ // Throw to get to the same code path as an error directly in qSA.
+ // Note: once we only support browser supporting
+ // `CSS.supports('selector(...)')`, we can most likely drop
+ // the `try-catch`. IE doesn't implement the API.
+ throw new Error();
+ }
+
+ push.apply( results,
+ newContext.querySelectorAll( newSelector )
+ );
+ return results;
+ } catch ( qsaError ) {
+ nonnativeSelectorCache( selector, true );
+ } finally {
+ if ( nid === expando ) {
+ context.removeAttribute( "id" );
+ }
+ }
+ }
+ }
+ }
+
+ // All others
+ return select( selector.replace( rtrim, "$1" ), context, results, seed );
+ }
+
+ /**
+ * Create key-value caches of limited size
+ * @returns {function(string, object)} Returns the Object data after storing it on itself with
+ * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
+ * deleting the oldest entry
+ */
+ function createCache() {
+ var keys = [];
+
+ function cache( key, value ) {
+
+ // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
+ if ( keys.push( key + " " ) > Expr.cacheLength ) {
+
+ // Only keep the most recent entries
+ delete cache[ keys.shift() ];
+ }
+ return ( cache[ key + " " ] = value );
+ }
+ return cache;
+ }
+
+ /**
+ * Mark a function for special use by Sizzle
+ * @param {Function} fn The function to mark
+ */
+ function markFunction( fn ) {
+ fn[ expando ] = true;
+ return fn;
+ }
+
+ /**
+ * Support testing using an element
+ * @param {Function} fn Passed the created element and returns a boolean result
+ */
+ function assert( fn ) {
+ var el = document.createElement( "fieldset" );
+
+ try {
+ return !!fn( el );
+ } catch ( e ) {
+ return false;
+ } finally {
+
+ // Remove from its parent by default
+ if ( el.parentNode ) {
+ el.parentNode.removeChild( el );
+ }
+
+ // release memory in IE
+ el = null;
+ }
+ }
+
+ /**
+ * Adds the same handler for all of the specified attrs
+ * @param {String} attrs Pipe-separated list of attributes
+ * @param {Function} handler The method that will be applied
+ */
+ function addHandle( attrs, handler ) {
+ var arr = attrs.split( "|" ),
+ i = arr.length;
+
+ while ( i-- ) {
+ Expr.attrHandle[ arr[ i ] ] = handler;
+ }
+ }
+
+ /**
+ * Checks document order of two siblings
+ * @param {Element} a
+ * @param {Element} b
+ * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
+ */
+ function siblingCheck( a, b ) {
+ var cur = b && a,
+ diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
+ a.sourceIndex - b.sourceIndex;
+
+ // Use IE sourceIndex if available on both nodes
+ if ( diff ) {
+ return diff;
+ }
+
+ // Check if b follows a
+ if ( cur ) {
+ while ( ( cur = cur.nextSibling ) ) {
+ if ( cur === b ) {
+ return -1;
+ }
+ }
+ }
+
+ return a ? 1 : -1;
+ }
+
+ /**
+ * Returns a function to use in pseudos for input types
+ * @param {String} type
+ */
+ function createInputPseudo( type ) {
+ return function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && elem.type === type;
+ };
+ }
+
+ /**
+ * Returns a function to use in pseudos for buttons
+ * @param {String} type
+ */
+ function createButtonPseudo( type ) {
+ return function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return ( name === "input" || name === "button" ) && elem.type === type;
+ };
+ }
+
+ /**
+ * Returns a function to use in pseudos for :enabled/:disabled
+ * @param {Boolean} disabled true for :disabled; false for :enabled
+ */
+ function createDisabledPseudo( disabled ) {
+
+ // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
+ return function( elem ) {
+
+ // Only certain elements can match :enabled or :disabled
+ // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
+ // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
+ if ( "form" in elem ) {
+
+ // Check for inherited disabledness on relevant non-disabled elements:
+ // * listed form-associated elements in a disabled fieldset
+ // https://html.spec.whatwg.org/multipage/forms.html#category-listed
+ // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
+ // * option elements in a disabled optgroup
+ // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
+ // All such elements have a "form" property.
+ if ( elem.parentNode && elem.disabled === false ) {
+
+ // Option elements defer to a parent optgroup if present
+ if ( "label" in elem ) {
+ if ( "label" in elem.parentNode ) {
+ return elem.parentNode.disabled === disabled;
+ } else {
+ return elem.disabled === disabled;
+ }
+ }
+
+ // Support: IE 6 - 11
+ // Use the isDisabled shortcut property to check for disabled fieldset ancestors
+ return elem.isDisabled === disabled ||
+
+ // Where there is no isDisabled, check manually
+ /* jshint -W018 */
+ elem.isDisabled !== !disabled &&
+ inDisabledFieldset( elem ) === disabled;
+ }
+
+ return elem.disabled === disabled;
+
+ // Try to winnow out elements that can't be disabled before trusting the disabled property.
+ // Some victims get caught in our net (label, legend, menu, track), but it shouldn't
+ // even exist on them, let alone have a boolean value.
+ } else if ( "label" in elem ) {
+ return elem.disabled === disabled;
+ }
+
+ // Remaining elements are neither :enabled nor :disabled
+ return false;
+ };
+ }
+
+ /**
+ * Returns a function to use in pseudos for positionals
+ * @param {Function} fn
+ */
+ function createPositionalPseudo( fn ) {
+ return markFunction( function( argument ) {
+ argument = +argument;
+ return markFunction( function( seed, matches ) {
+ var j,
+ matchIndexes = fn( [], seed.length, argument ),
+ i = matchIndexes.length;
+
+ // Match elements found at the specified indexes
+ while ( i-- ) {
+ if ( seed[ ( j = matchIndexes[ i ] ) ] ) {
+ seed[ j ] = !( matches[ j ] = seed[ j ] );
+ }
+ }
+ } );
+ } );
+ }
+
+ /**
+ * Checks a node for validity as a Sizzle context
+ * @param {Element|Object=} context
+ * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
+ */
+ function testContext( context ) {
+ return context && typeof context.getElementsByTagName !== "undefined" && context;
+ }
+
+ // Expose support vars for convenience
+ support = Sizzle.support = {};
+
+ /**
+ * Detects XML nodes
+ * @param {Element|Object} elem An element or a document
+ * @returns {Boolean} True iff elem is a non-HTML XML node
+ */
+ isXML = Sizzle.isXML = function( elem ) {
+ var namespace = elem && elem.namespaceURI,
+ docElem = elem && ( elem.ownerDocument || elem ).documentElement;
+
+ // Support: IE <=8
+ // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes
+ // https://bugs.jquery.com/ticket/4833
+ return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" );
+ };
+
+ /**
+ * Sets document-related variables once based on the current document
+ * @param {Element|Object} [doc] An element or document object to use to set the document
+ * @returns {Object} Returns the current document
+ */
+ setDocument = Sizzle.setDocument = function( node ) {
+ var hasCompare, subWindow,
+ doc = node ? node.ownerDocument || node : preferredDoc;
+
+ // Return early if doc is invalid or already selected
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) {
+ return document;
+ }
+
+ // Update global variables
+ document = doc;
+ docElem = document.documentElement;
+ documentIsHTML = !isXML( document );
+
+ // Support: IE 9 - 11+, Edge 12 - 18+
+ // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ if ( preferredDoc != document &&
+ ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {
+
+ // Support: IE 11, Edge
+ if ( subWindow.addEventListener ) {
+ subWindow.addEventListener( "unload", unloadHandler, false );
+
+ // Support: IE 9 - 10 only
+ } else if ( subWindow.attachEvent ) {
+ subWindow.attachEvent( "onunload", unloadHandler );
+ }
+ }
+
+ // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only,
+ // Safari 4 - 5 only, Opera <=11.6 - 12.x only
+ // IE/Edge & older browsers don't support the :scope pseudo-class.
+ // Support: Safari 6.0 only
+ // Safari 6.0 supports :scope but it's an alias of :root there.
+ support.scope = assert( function( el ) {
+ docElem.appendChild( el ).appendChild( document.createElement( "div" ) );
+ return typeof el.querySelectorAll !== "undefined" &&
+ !el.querySelectorAll( ":scope fieldset div" ).length;
+ } );
+
+ // Support: Chrome 105+, Firefox 104+, Safari 15.4+
+ // Make sure forgiving mode is not used in `CSS.supports( "selector(...)" )`.
+ //
+ // `:is()` uses a forgiving selector list as an argument and is widely
+ // implemented, so it's a good one to test against.
+ support.cssSupportsSelector = assert( function() {
+ /* eslint-disable no-undef */
+
+ return CSS.supports( "selector(*)" ) &&
+
+ // Support: Firefox 78-81 only
+ // In old Firefox, `:is()` didn't use forgiving parsing. In that case,
+ // fail this test as there's no selector to test against that.
+ // `CSS.supports` uses unforgiving parsing
+ document.querySelectorAll( ":is(:jqfake)" ) &&
+
+ // `*` is needed as Safari & newer Chrome implemented something in between
+ // for `:has()` - it throws in `qSA` if it only contains an unsupported
+ // argument but multiple ones, one of which is supported, are fine.
+ // We want to play safe in case `:is()` gets the same treatment.
+ !CSS.supports( "selector(:is(*,:jqfake))" );
+
+ /* eslint-enable */
+ } );
+
+ /* Attributes
+ ---------------------------------------------------------------------- */
+
+ // Support: IE<8
+ // Verify that getAttribute really returns attributes and not properties
+ // (excepting IE8 booleans)
+ support.attributes = assert( function( el ) {
+ el.className = "i";
+ return !el.getAttribute( "className" );
+ } );
+
+ /* getElement(s)By*
+ ---------------------------------------------------------------------- */
+
+ // Check if getElementsByTagName("*") returns only elements
+ support.getElementsByTagName = assert( function( el ) {
+ el.appendChild( document.createComment( "" ) );
+ return !el.getElementsByTagName( "*" ).length;
+ } );
+
+ // Support: IE<9
+ support.getElementsByClassName = rnative.test( document.getElementsByClassName );
+
+ // Support: IE<10
+ // Check if getElementById returns elements by name
+ // The broken getElementById methods don't pick up programmatically-set names,
+ // so use a roundabout getElementsByName test
+ support.getById = assert( function( el ) {
+ docElem.appendChild( el ).id = expando;
+ return !document.getElementsByName || !document.getElementsByName( expando ).length;
+ } );
+
+ // ID filter and find
+ if ( support.getById ) {
+ Expr.filter[ "ID" ] = function( id ) {
+ var attrId = id.replace( runescape, funescape );
+ return function( elem ) {
+ return elem.getAttribute( "id" ) === attrId;
+ };
+ };
+ Expr.find[ "ID" ] = function( id, context ) {
+ if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
+ var elem = context.getElementById( id );
+ return elem ? [ elem ] : [];
+ }
+ };
+ } else {
+ Expr.filter[ "ID" ] = function( id ) {
+ var attrId = id.replace( runescape, funescape );
+ return function( elem ) {
+ var node = typeof elem.getAttributeNode !== "undefined" &&
+ elem.getAttributeNode( "id" );
+ return node && node.value === attrId;
+ };
+ };
+
+ // Support: IE 6 - 7 only
+ // getElementById is not reliable as a find shortcut
+ Expr.find[ "ID" ] = function( id, context ) {
+ if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
+ var node, i, elems,
+ elem = context.getElementById( id );
+
+ if ( elem ) {
+
+ // Verify the id attribute
+ node = elem.getAttributeNode( "id" );
+ if ( node && node.value === id ) {
+ return [ elem ];
+ }
+
+ // Fall back on getElementsByName
+ elems = context.getElementsByName( id );
+ i = 0;
+ while ( ( elem = elems[ i++ ] ) ) {
+ node = elem.getAttributeNode( "id" );
+ if ( node && node.value === id ) {
+ return [ elem ];
+ }
+ }
+ }
+
+ return [];
+ }
+ };
+ }
+
+ // Tag
+ Expr.find[ "TAG" ] = support.getElementsByTagName ?
+ function( tag, context ) {
+ if ( typeof context.getElementsByTagName !== "undefined" ) {
+ return context.getElementsByTagName( tag );
+
+ // DocumentFragment nodes don't have gEBTN
+ } else if ( support.qsa ) {
+ return context.querySelectorAll( tag );
+ }
+ } :
+
+ function( tag, context ) {
+ var elem,
+ tmp = [],
+ i = 0,
+
+ // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
+ results = context.getElementsByTagName( tag );
+
+ // Filter out possible comments
+ if ( tag === "*" ) {
+ while ( ( elem = results[ i++ ] ) ) {
+ if ( elem.nodeType === 1 ) {
+ tmp.push( elem );
+ }
+ }
+
+ return tmp;
+ }
+ return results;
+ };
+
+ // Class
+ Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) {
+ if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
+ return context.getElementsByClassName( className );
+ }
+ };
+
+ /* QSA/matchesSelector
+ ---------------------------------------------------------------------- */
+
+ // QSA and matchesSelector support
+
+ // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
+ rbuggyMatches = [];
+
+ // qSa(:focus) reports false when true (Chrome 21)
+ // We allow this because of a bug in IE8/9 that throws an error
+ // whenever `document.activeElement` is accessed on an iframe
+ // So, we allow :focus to pass through QSA all the time to avoid the IE error
+ // See https://bugs.jquery.com/ticket/13378
+ rbuggyQSA = [];
+
+ if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) {
+
+ // Build QSA regex
+ // Regex strategy adopted from Diego Perini
+ assert( function( el ) {
+
+ var input;
+
+ // Select is set to empty string on purpose
+ // This is to test IE's treatment of not explicitly
+ // setting a boolean content attribute,
+ // since its presence should be enough
+ // https://bugs.jquery.com/ticket/12359
+ docElem.appendChild( el ).innerHTML = "" +
+ "";
+
+ // Support: IE8, Opera 11-12.16
+ // Nothing should be selected when empty strings follow ^= or $= or *=
+ // The test attribute must be unknown in Opera but "safe" for WinRT
+ // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
+ if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) {
+ rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
+ }
+
+ // Support: IE8
+ // Boolean attributes and "value" are not treated correctly
+ if ( !el.querySelectorAll( "[selected]" ).length ) {
+ rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
+ }
+
+ // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
+ if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
+ rbuggyQSA.push( "~=" );
+ }
+
+ // Support: IE 11+, Edge 15 - 18+
+ // IE 11/Edge don't find elements on a `[name='']` query in some cases.
+ // Adding a temporary attribute to the document before the selection works
+ // around the issue.
+ // Interestingly, IE 10 & older don't seem to have the issue.
+ input = document.createElement( "input" );
+ input.setAttribute( "name", "" );
+ el.appendChild( input );
+ if ( !el.querySelectorAll( "[name='']" ).length ) {
+ rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" +
+ whitespace + "*(?:''|\"\")" );
+ }
+
+ // Webkit/Opera - :checked should return selected option elements
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+ // IE8 throws error here and will not see later tests
+ if ( !el.querySelectorAll( ":checked" ).length ) {
+ rbuggyQSA.push( ":checked" );
+ }
+
+ // Support: Safari 8+, iOS 8+
+ // https://bugs.webkit.org/show_bug.cgi?id=136851
+ // In-page `selector#id sibling-combinator selector` fails
+ if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
+ rbuggyQSA.push( ".#.+[+~]" );
+ }
+
+ // Support: Firefox <=3.6 - 5 only
+ // Old Firefox doesn't throw on a badly-escaped identifier.
+ el.querySelectorAll( "\\\f" );
+ rbuggyQSA.push( "[\\r\\n\\f]" );
+ } );
+
+ assert( function( el ) {
+ el.innerHTML = "" +
+ "";
+
+ // Support: Windows 8 Native Apps
+ // The type and name attributes are restricted during .innerHTML assignment
+ var input = document.createElement( "input" );
+ input.setAttribute( "type", "hidden" );
+ el.appendChild( input ).setAttribute( "name", "D" );
+
+ // Support: IE8
+ // Enforce case-sensitivity of name attribute
+ if ( el.querySelectorAll( "[name=d]" ).length ) {
+ rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
+ }
+
+ // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
+ // IE8 throws error here and will not see later tests
+ if ( el.querySelectorAll( ":enabled" ).length !== 2 ) {
+ rbuggyQSA.push( ":enabled", ":disabled" );
+ }
+
+ // Support: IE9-11+
+ // IE's :disabled selector does not pick up the children of disabled fieldsets
+ docElem.appendChild( el ).disabled = true;
+ if ( el.querySelectorAll( ":disabled" ).length !== 2 ) {
+ rbuggyQSA.push( ":enabled", ":disabled" );
+ }
+
+ // Support: Opera 10 - 11 only
+ // Opera 10-11 does not throw on post-comma invalid pseudos
+ el.querySelectorAll( "*,:x" );
+ rbuggyQSA.push( ",.*:" );
+ } );
+ }
+
+ if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches ||
+ docElem.webkitMatchesSelector ||
+ docElem.mozMatchesSelector ||
+ docElem.oMatchesSelector ||
+ docElem.msMatchesSelector ) ) ) ) {
+
+ assert( function( el ) {
+
+ // Check to see if it's possible to do matchesSelector
+ // on a disconnected node (IE 9)
+ support.disconnectedMatch = matches.call( el, "*" );
+
+ // This should fail with an exception
+ // Gecko does not error, returns false instead
+ matches.call( el, "[s!='']:x" );
+ rbuggyMatches.push( "!=", pseudos );
+ } );
+ }
+
+ if ( !support.cssSupportsSelector ) {
+
+ // Support: Chrome 105+, Safari 15.4+
+ // `:has()` uses a forgiving selector list as an argument so our regular
+ // `try-catch` mechanism fails to catch `:has()` with arguments not supported
+ // natively like `:has(:contains("Foo"))`. Where supported & spec-compliant,
+ // we now use `CSS.supports("selector(:is(SELECTOR_TO_BE_TESTED))")`, but
+ // outside that we mark `:has` as buggy.
+ rbuggyQSA.push( ":has" );
+ }
+
+ rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) );
+ rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) );
+
+ /* Contains
+ ---------------------------------------------------------------------- */
+ hasCompare = rnative.test( docElem.compareDocumentPosition );
+
+ // Element contains another
+ // Purposefully self-exclusive
+ // As in, an element does not contain itself
+ contains = hasCompare || rnative.test( docElem.contains ) ?
+ function( a, b ) {
+
+ // Support: IE <9 only
+ // IE doesn't have `contains` on `document` so we need to check for
+ // `documentElement` presence.
+ // We need to fall back to `a` when `documentElement` is missing
+ // as `ownerDocument` of elements within `` may have
+ // a null one - a default behavior of all modern browsers.
+ var adown = a.nodeType === 9 && a.documentElement || a,
+ bup = b && b.parentNode;
+ return a === bup || !!( bup && bup.nodeType === 1 && (
+ adown.contains ?
+ adown.contains( bup ) :
+ a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
+ ) );
+ } :
+ function( a, b ) {
+ if ( b ) {
+ while ( ( b = b.parentNode ) ) {
+ if ( b === a ) {
+ return true;
+ }
+ }
+ }
+ return false;
+ };
+
+ /* Sorting
+ ---------------------------------------------------------------------- */
+
+ // Document order sorting
+ sortOrder = hasCompare ?
+ function( a, b ) {
+
+ // Flag for duplicate removal
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+ }
+
+ // Sort on method existence if only one input has compareDocumentPosition
+ var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
+ if ( compare ) {
+ return compare;
+ }
+
+ // Calculate position if both inputs belong to the same document
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?
+ a.compareDocumentPosition( b ) :
+
+ // Otherwise we know they are disconnected
+ 1;
+
+ // Disconnected nodes
+ if ( compare & 1 ||
+ ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) {
+
+ // Choose the first element that is related to our preferred document
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ if ( a == document || a.ownerDocument == preferredDoc &&
+ contains( preferredDoc, a ) ) {
+ return -1;
+ }
+
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ if ( b == document || b.ownerDocument == preferredDoc &&
+ contains( preferredDoc, b ) ) {
+ return 1;
+ }
+
+ // Maintain original order
+ return sortInput ?
+ ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
+ 0;
+ }
+
+ return compare & 4 ? -1 : 1;
+ } :
+ function( a, b ) {
+
+ // Exit early if the nodes are identical
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+ }
+
+ var cur,
+ i = 0,
+ aup = a.parentNode,
+ bup = b.parentNode,
+ ap = [ a ],
+ bp = [ b ];
+
+ // Parentless nodes are either documents or disconnected
+ if ( !aup || !bup ) {
+
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ /* eslint-disable eqeqeq */
+ return a == document ? -1 :
+ b == document ? 1 :
+ /* eslint-enable eqeqeq */
+ aup ? -1 :
+ bup ? 1 :
+ sortInput ?
+ ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
+ 0;
+
+ // If the nodes are siblings, we can do a quick check
+ } else if ( aup === bup ) {
+ return siblingCheck( a, b );
+ }
+
+ // Otherwise we need full lists of their ancestors for comparison
+ cur = a;
+ while ( ( cur = cur.parentNode ) ) {
+ ap.unshift( cur );
+ }
+ cur = b;
+ while ( ( cur = cur.parentNode ) ) {
+ bp.unshift( cur );
+ }
+
+ // Walk down the tree looking for a discrepancy
+ while ( ap[ i ] === bp[ i ] ) {
+ i++;
+ }
+
+ return i ?
+
+ // Do a sibling check if the nodes have a common ancestor
+ siblingCheck( ap[ i ], bp[ i ] ) :
+
+ // Otherwise nodes in our document sort first
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ /* eslint-disable eqeqeq */
+ ap[ i ] == preferredDoc ? -1 :
+ bp[ i ] == preferredDoc ? 1 :
+ /* eslint-enable eqeqeq */
+ 0;
+ };
+
+ return document;
+ };
+
+ Sizzle.matches = function( expr, elements ) {
+ return Sizzle( expr, null, null, elements );
+ };
+
+ Sizzle.matchesSelector = function( elem, expr ) {
+ setDocument( elem );
+
+ if ( support.matchesSelector && documentIsHTML &&
+ !nonnativeSelectorCache[ expr + " " ] &&
+ ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
+ ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
+
+ try {
+ var ret = matches.call( elem, expr );
+
+ // IE 9's matchesSelector returns false on disconnected nodes
+ if ( ret || support.disconnectedMatch ||
+
+ // As well, disconnected nodes are said to be in a document
+ // fragment in IE 9
+ elem.document && elem.document.nodeType !== 11 ) {
+ return ret;
+ }
+ } catch ( e ) {
+ nonnativeSelectorCache( expr, true );
+ }
+ }
+
+ return Sizzle( expr, document, null, [ elem ] ).length > 0;
+ };
+
+ Sizzle.contains = function( context, elem ) {
+
+ // Set document vars if needed
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ if ( ( context.ownerDocument || context ) != document ) {
+ setDocument( context );
+ }
+ return contains( context, elem );
+ };
+
+ Sizzle.attr = function( elem, name ) {
+
+ // Set document vars if needed
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ if ( ( elem.ownerDocument || elem ) != document ) {
+ setDocument( elem );
+ }
+
+ var fn = Expr.attrHandle[ name.toLowerCase() ],
+
+ // Don't get fooled by Object.prototype properties (jQuery #13807)
+ val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
+ fn( elem, name, !documentIsHTML ) :
+ undefined;
+
+ return val !== undefined ?
+ val :
+ support.attributes || !documentIsHTML ?
+ elem.getAttribute( name ) :
+ ( val = elem.getAttributeNode( name ) ) && val.specified ?
+ val.value :
+ null;
+ };
+
+ Sizzle.escape = function( sel ) {
+ return ( sel + "" ).replace( rcssescape, fcssescape );
+ };
+
+ Sizzle.error = function( msg ) {
+ throw new Error( "Syntax error, unrecognized expression: " + msg );
+ };
+
+ /**
+ * Document sorting and removing duplicates
+ * @param {ArrayLike} results
+ */
+ Sizzle.uniqueSort = function( results ) {
+ var elem,
+ duplicates = [],
+ j = 0,
+ i = 0;
+
+ // Unless we *know* we can detect duplicates, assume their presence
+ hasDuplicate = !support.detectDuplicates;
+ sortInput = !support.sortStable && results.slice( 0 );
+ results.sort( sortOrder );
+
+ if ( hasDuplicate ) {
+ while ( ( elem = results[ i++ ] ) ) {
+ if ( elem === results[ i ] ) {
+ j = duplicates.push( i );
+ }
+ }
+ while ( j-- ) {
+ results.splice( duplicates[ j ], 1 );
+ }
+ }
+
+ // Clear input after sorting to release objects
+ // See https://github.com/jquery/sizzle/pull/225
+ sortInput = null;
+
+ return results;
+ };
+
+ /**
+ * Utility function for retrieving the text value of an array of DOM nodes
+ * @param {Array|Element} elem
+ */
+ getText = Sizzle.getText = function( elem ) {
+ var node,
+ ret = "",
+ i = 0,
+ nodeType = elem.nodeType;
+
+ if ( !nodeType ) {
+
+ // If no nodeType, this is expected to be an array
+ while ( ( node = elem[ i++ ] ) ) {
+
+ // Do not traverse comment nodes
+ ret += getText( node );
+ }
+ } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
+
+ // Use textContent for elements
+ // innerText usage removed for consistency of new lines (jQuery #11153)
+ if ( typeof elem.textContent === "string" ) {
+ return elem.textContent;
+ } else {
+
+ // Traverse its children
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+ ret += getText( elem );
+ }
+ }
+ } else if ( nodeType === 3 || nodeType === 4 ) {
+ return elem.nodeValue;
+ }
+
+ // Do not include comment or processing instruction nodes
+
+ return ret;
+ };
+
+ Expr = Sizzle.selectors = {
+
+ // Can be adjusted by the user
+ cacheLength: 50,
+
+ createPseudo: markFunction,
+
+ match: matchExpr,
+
+ attrHandle: {},
+
+ find: {},
+
+ relative: {
+ ">": { dir: "parentNode", first: true },
+ " ": { dir: "parentNode" },
+ "+": { dir: "previousSibling", first: true },
+ "~": { dir: "previousSibling" }
+ },
+
+ preFilter: {
+ "ATTR": function( match ) {
+ match[ 1 ] = match[ 1 ].replace( runescape, funescape );
+
+ // Move the given value to match[3] whether quoted or unquoted
+ match[ 3 ] = ( match[ 3 ] || match[ 4 ] ||
+ match[ 5 ] || "" ).replace( runescape, funescape );
+
+ if ( match[ 2 ] === "~=" ) {
+ match[ 3 ] = " " + match[ 3 ] + " ";
+ }
+
+ return match.slice( 0, 4 );
+ },
+
+ "CHILD": function( match ) {
+
+ /* matches from matchExpr["CHILD"]
+ 1 type (only|nth|...)
+ 2 what (child|of-type)
+ 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
+ 4 xn-component of xn+y argument ([+-]?\d*n|)
+ 5 sign of xn-component
+ 6 x of xn-component
+ 7 sign of y-component
+ 8 y of y-component
+ */
+ match[ 1 ] = match[ 1 ].toLowerCase();
+
+ if ( match[ 1 ].slice( 0, 3 ) === "nth" ) {
+
+ // nth-* requires argument
+ if ( !match[ 3 ] ) {
+ Sizzle.error( match[ 0 ] );
+ }
+
+ // numeric x and y parameters for Expr.filter.CHILD
+ // remember that false/true cast respectively to 0/1
+ match[ 4 ] = +( match[ 4 ] ?
+ match[ 5 ] + ( match[ 6 ] || 1 ) :
+ 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) );
+ match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" );
+
+ // other types prohibit arguments
+ } else if ( match[ 3 ] ) {
+ Sizzle.error( match[ 0 ] );
+ }
+
+ return match;
+ },
+
+ "PSEUDO": function( match ) {
+ var excess,
+ unquoted = !match[ 6 ] && match[ 2 ];
+
+ if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) {
+ return null;
+ }
+
+ // Accept quoted arguments as-is
+ if ( match[ 3 ] ) {
+ match[ 2 ] = match[ 4 ] || match[ 5 ] || "";
+
+ // Strip excess characters from unquoted arguments
+ } else if ( unquoted && rpseudo.test( unquoted ) &&
+
+ // Get excess from tokenize (recursively)
+ ( excess = tokenize( unquoted, true ) ) &&
+
+ // advance to the next closing parenthesis
+ ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) {
+
+ // excess is a negative index
+ match[ 0 ] = match[ 0 ].slice( 0, excess );
+ match[ 2 ] = unquoted.slice( 0, excess );
+ }
+
+ // Return only captures needed by the pseudo filter method (type and argument)
+ return match.slice( 0, 3 );
+ }
+ },
+
+ filter: {
+
+ "TAG": function( nodeNameSelector ) {
+ var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
+ return nodeNameSelector === "*" ?
+ function() {
+ return true;
+ } :
+ function( elem ) {
+ return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
+ };
+ },
+
+ "CLASS": function( className ) {
+ var pattern = classCache[ className + " " ];
+
+ return pattern ||
+ ( pattern = new RegExp( "(^|" + whitespace +
+ ")" + className + "(" + whitespace + "|$)" ) ) && classCache(
+ className, function( elem ) {
+ return pattern.test(
+ typeof elem.className === "string" && elem.className ||
+ typeof elem.getAttribute !== "undefined" &&
+ elem.getAttribute( "class" ) ||
+ ""
+ );
+ } );
+ },
+
+ "ATTR": function( name, operator, check ) {
+ return function( elem ) {
+ var result = Sizzle.attr( elem, name );
+
+ if ( result == null ) {
+ return operator === "!=";
+ }
+ if ( !operator ) {
+ return true;
+ }
+
+ result += "";
+
+ /* eslint-disable max-len */
+
+ return operator === "=" ? result === check :
+ operator === "!=" ? result !== check :
+ operator === "^=" ? check && result.indexOf( check ) === 0 :
+ operator === "*=" ? check && result.indexOf( check ) > -1 :
+ operator === "$=" ? check && result.slice( -check.length ) === check :
+ operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
+ operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
+ false;
+ /* eslint-enable max-len */
+
+ };
+ },
+
+ "CHILD": function( type, what, _argument, first, last ) {
+ var simple = type.slice( 0, 3 ) !== "nth",
+ forward = type.slice( -4 ) !== "last",
+ ofType = what === "of-type";
+
+ return first === 1 && last === 0 ?
+
+ // Shortcut for :nth-*(n)
+ function( elem ) {
+ return !!elem.parentNode;
+ } :
+
+ function( elem, _context, xml ) {
+ var cache, uniqueCache, outerCache, node, nodeIndex, start,
+ dir = simple !== forward ? "nextSibling" : "previousSibling",
+ parent = elem.parentNode,
+ name = ofType && elem.nodeName.toLowerCase(),
+ useCache = !xml && !ofType,
+ diff = false;
+
+ if ( parent ) {
+
+ // :(first|last|only)-(child|of-type)
+ if ( simple ) {
+ while ( dir ) {
+ node = elem;
+ while ( ( node = node[ dir ] ) ) {
+ if ( ofType ?
+ node.nodeName.toLowerCase() === name :
+ node.nodeType === 1 ) {
+
+ return false;
+ }
+ }
+
+ // Reverse direction for :only-* (if we haven't yet done so)
+ start = dir = type === "only" && !start && "nextSibling";
+ }
+ return true;
+ }
+
+ start = [ forward ? parent.firstChild : parent.lastChild ];
+
+ // non-xml :nth-child(...) stores cache data on `parent`
+ if ( forward && useCache ) {
+
+ // Seek `elem` from a previously-cached index
+
+ // ...in a gzip-friendly way
+ node = parent;
+ outerCache = node[ expando ] || ( node[ expando ] = {} );
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ node.uniqueID ] ||
+ ( outerCache[ node.uniqueID ] = {} );
+
+ cache = uniqueCache[ type ] || [];
+ nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
+ diff = nodeIndex && cache[ 2 ];
+ node = nodeIndex && parent.childNodes[ nodeIndex ];
+
+ while ( ( node = ++nodeIndex && node && node[ dir ] ||
+
+ // Fallback to seeking `elem` from the start
+ ( diff = nodeIndex = 0 ) || start.pop() ) ) {
+
+ // When found, cache indexes on `parent` and break
+ if ( node.nodeType === 1 && ++diff && node === elem ) {
+ uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
+ break;
+ }
+ }
+
+ } else {
+
+ // Use previously-cached element index if available
+ if ( useCache ) {
+
+ // ...in a gzip-friendly way
+ node = elem;
+ outerCache = node[ expando ] || ( node[ expando ] = {} );
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ node.uniqueID ] ||
+ ( outerCache[ node.uniqueID ] = {} );
+
+ cache = uniqueCache[ type ] || [];
+ nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
+ diff = nodeIndex;
+ }
+
+ // xml :nth-child(...)
+ // or :nth-last-child(...) or :nth(-last)?-of-type(...)
+ if ( diff === false ) {
+
+ // Use the same loop as above to seek `elem` from the start
+ while ( ( node = ++nodeIndex && node && node[ dir ] ||
+ ( diff = nodeIndex = 0 ) || start.pop() ) ) {
+
+ if ( ( ofType ?
+ node.nodeName.toLowerCase() === name :
+ node.nodeType === 1 ) &&
+ ++diff ) {
+
+ // Cache the index of each encountered element
+ if ( useCache ) {
+ outerCache = node[ expando ] ||
+ ( node[ expando ] = {} );
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ node.uniqueID ] ||
+ ( outerCache[ node.uniqueID ] = {} );
+
+ uniqueCache[ type ] = [ dirruns, diff ];
+ }
+
+ if ( node === elem ) {
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // Incorporate the offset, then check against cycle size
+ diff -= last;
+ return diff === first || ( diff % first === 0 && diff / first >= 0 );
+ }
+ };
+ },
+
+ "PSEUDO": function( pseudo, argument ) {
+
+ // pseudo-class names are case-insensitive
+ // http://www.w3.org/TR/selectors/#pseudo-classes
+ // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
+ // Remember that setFilters inherits from pseudos
+ var args,
+ fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
+ Sizzle.error( "unsupported pseudo: " + pseudo );
+
+ // The user may use createPseudo to indicate that
+ // arguments are needed to create the filter function
+ // just as Sizzle does
+ if ( fn[ expando ] ) {
+ return fn( argument );
+ }
+
+ // But maintain support for old signatures
+ if ( fn.length > 1 ) {
+ args = [ pseudo, pseudo, "", argument ];
+ return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
+ markFunction( function( seed, matches ) {
+ var idx,
+ matched = fn( seed, argument ),
+ i = matched.length;
+ while ( i-- ) {
+ idx = indexOf( seed, matched[ i ] );
+ seed[ idx ] = !( matches[ idx ] = matched[ i ] );
+ }
+ } ) :
+ function( elem ) {
+ return fn( elem, 0, args );
+ };
+ }
+
+ return fn;
+ }
+ },
+
+ pseudos: {
+
+ // Potentially complex pseudos
+ "not": markFunction( function( selector ) {
+
+ // Trim the selector passed to compile
+ // to avoid treating leading and trailing
+ // spaces as combinators
+ var input = [],
+ results = [],
+ matcher = compile( selector.replace( rtrim, "$1" ) );
+
+ return matcher[ expando ] ?
+ markFunction( function( seed, matches, _context, xml ) {
+ var elem,
+ unmatched = matcher( seed, null, xml, [] ),
+ i = seed.length;
+
+ // Match elements unmatched by `matcher`
+ while ( i-- ) {
+ if ( ( elem = unmatched[ i ] ) ) {
+ seed[ i ] = !( matches[ i ] = elem );
+ }
+ }
+ } ) :
+ function( elem, _context, xml ) {
+ input[ 0 ] = elem;
+ matcher( input, null, xml, results );
+
+ // Don't keep the element (issue #299)
+ input[ 0 ] = null;
+ return !results.pop();
+ };
+ } ),
+
+ "has": markFunction( function( selector ) {
+ return function( elem ) {
+ return Sizzle( selector, elem ).length > 0;
+ };
+ } ),
+
+ "contains": markFunction( function( text ) {
+ text = text.replace( runescape, funescape );
+ return function( elem ) {
+ return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1;
+ };
+ } ),
+
+ // "Whether an element is represented by a :lang() selector
+ // is based solely on the element's language value
+ // being equal to the identifier C,
+ // or beginning with the identifier C immediately followed by "-".
+ // The matching of C against the element's language value is performed case-insensitively.
+ // The identifier C does not have to be a valid language name."
+ // http://www.w3.org/TR/selectors/#lang-pseudo
+ "lang": markFunction( function( lang ) {
+
+ // lang value must be a valid identifier
+ if ( !ridentifier.test( lang || "" ) ) {
+ Sizzle.error( "unsupported lang: " + lang );
+ }
+ lang = lang.replace( runescape, funescape ).toLowerCase();
+ return function( elem ) {
+ var elemLang;
+ do {
+ if ( ( elemLang = documentIsHTML ?
+ elem.lang :
+ elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) {
+
+ elemLang = elemLang.toLowerCase();
+ return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
+ }
+ } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );
+ return false;
+ };
+ } ),
+
+ // Miscellaneous
+ "target": function( elem ) {
+ var hash = window.location && window.location.hash;
+ return hash && hash.slice( 1 ) === elem.id;
+ },
+
+ "root": function( elem ) {
+ return elem === docElem;
+ },
+
+ "focus": function( elem ) {
+ return elem === document.activeElement &&
+ ( !document.hasFocus || document.hasFocus() ) &&
+ !!( elem.type || elem.href || ~elem.tabIndex );
+ },
+
+ // Boolean properties
+ "enabled": createDisabledPseudo( false ),
+ "disabled": createDisabledPseudo( true ),
+
+ "checked": function( elem ) {
+
+ // In CSS3, :checked should return both checked and selected elements
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+ var nodeName = elem.nodeName.toLowerCase();
+ return ( nodeName === "input" && !!elem.checked ) ||
+ ( nodeName === "option" && !!elem.selected );
+ },
+
+ "selected": function( elem ) {
+
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ if ( elem.parentNode ) {
+ // eslint-disable-next-line no-unused-expressions
+ elem.parentNode.selectedIndex;
+ }
+
+ return elem.selected === true;
+ },
+
+ // Contents
+ "empty": function( elem ) {
+
+ // http://www.w3.org/TR/selectors/#empty-pseudo
+ // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
+ // but not by others (comment: 8; processing instruction: 7; etc.)
+ // nodeType < 6 works because attributes (2) do not appear as children
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+ if ( elem.nodeType < 6 ) {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ "parent": function( elem ) {
+ return !Expr.pseudos[ "empty" ]( elem );
+ },
+
+ // Element/input types
+ "header": function( elem ) {
+ return rheader.test( elem.nodeName );
+ },
+
+ "input": function( elem ) {
+ return rinputs.test( elem.nodeName );
+ },
+
+ "button": function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && elem.type === "button" || name === "button";
+ },
+
+ "text": function( elem ) {
+ var attr;
+ return elem.nodeName.toLowerCase() === "input" &&
+ elem.type === "text" &&
+
+ // Support: IE <10 only
+ // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
+ ( ( attr = elem.getAttribute( "type" ) ) == null ||
+ attr.toLowerCase() === "text" );
+ },
+
+ // Position-in-collection
+ "first": createPositionalPseudo( function() {
+ return [ 0 ];
+ } ),
+
+ "last": createPositionalPseudo( function( _matchIndexes, length ) {
+ return [ length - 1 ];
+ } ),
+
+ "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) {
+ return [ argument < 0 ? argument + length : argument ];
+ } ),
+
+ "even": createPositionalPseudo( function( matchIndexes, length ) {
+ var i = 0;
+ for ( ; i < length; i += 2 ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ } ),
+
+ "odd": createPositionalPseudo( function( matchIndexes, length ) {
+ var i = 1;
+ for ( ; i < length; i += 2 ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ } ),
+
+ "lt": createPositionalPseudo( function( matchIndexes, length, argument ) {
+ var i = argument < 0 ?
+ argument + length :
+ argument > length ?
+ length :
+ argument;
+ for ( ; --i >= 0; ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ } ),
+
+ "gt": createPositionalPseudo( function( matchIndexes, length, argument ) {
+ var i = argument < 0 ? argument + length : argument;
+ for ( ; ++i < length; ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ } )
+ }
+ };
+
+ Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ];
+
+ // Add button/input type pseudos
+ for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
+ Expr.pseudos[ i ] = createInputPseudo( i );
+ }
+ for ( i in { submit: true, reset: true } ) {
+ Expr.pseudos[ i ] = createButtonPseudo( i );
+ }
+
+ // Easy API for creating new setFilters
+ function setFilters() {}
+ setFilters.prototype = Expr.filters = Expr.pseudos;
+ Expr.setFilters = new setFilters();
+
+ tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
+ var matched, match, tokens, type,
+ soFar, groups, preFilters,
+ cached = tokenCache[ selector + " " ];
+
+ if ( cached ) {
+ return parseOnly ? 0 : cached.slice( 0 );
+ }
+
+ soFar = selector;
+ groups = [];
+ preFilters = Expr.preFilter;
+
+ while ( soFar ) {
+
+ // Comma and first run
+ if ( !matched || ( match = rcomma.exec( soFar ) ) ) {
+ if ( match ) {
+
+ // Don't consume trailing commas as valid
+ soFar = soFar.slice( match[ 0 ].length ) || soFar;
+ }
+ groups.push( ( tokens = [] ) );
+ }
+
+ matched = false;
+
+ // Combinators
+ if ( ( match = rcombinators.exec( soFar ) ) ) {
+ matched = match.shift();
+ tokens.push( {
+ value: matched,
+
+ // Cast descendant combinators to space
+ type: match[ 0 ].replace( rtrim, " " )
+ } );
+ soFar = soFar.slice( matched.length );
+ }
+
+ // Filters
+ for ( type in Expr.filter ) {
+ if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||
+ ( match = preFilters[ type ]( match ) ) ) ) {
+ matched = match.shift();
+ tokens.push( {
+ value: matched,
+ type: type,
+ matches: match
+ } );
+ soFar = soFar.slice( matched.length );
+ }
+ }
+
+ if ( !matched ) {
+ break;
+ }
+ }
+
+ // Return the length of the invalid excess
+ // if we're just parsing
+ // Otherwise, throw an error or return tokens
+ return parseOnly ?
+ soFar.length :
+ soFar ?
+ Sizzle.error( selector ) :
+
+ // Cache the tokens
+ tokenCache( selector, groups ).slice( 0 );
+ };
+
+ function toSelector( tokens ) {
+ var i = 0,
+ len = tokens.length,
+ selector = "";
+ for ( ; i < len; i++ ) {
+ selector += tokens[ i ].value;
+ }
+ return selector;
+ }
+
+ function addCombinator( matcher, combinator, base ) {
+ var dir = combinator.dir,
+ skip = combinator.next,
+ key = skip || dir,
+ checkNonElements = base && key === "parentNode",
+ doneName = done++;
+
+ return combinator.first ?
+
+ // Check against closest ancestor/preceding element
+ function( elem, context, xml ) {
+ while ( ( elem = elem[ dir ] ) ) {
+ if ( elem.nodeType === 1 || checkNonElements ) {
+ return matcher( elem, context, xml );
+ }
+ }
+ return false;
+ } :
+
+ // Check against all ancestor/preceding elements
+ function( elem, context, xml ) {
+ var oldCache, uniqueCache, outerCache,
+ newCache = [ dirruns, doneName ];
+
+ // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
+ if ( xml ) {
+ while ( ( elem = elem[ dir ] ) ) {
+ if ( elem.nodeType === 1 || checkNonElements ) {
+ if ( matcher( elem, context, xml ) ) {
+ return true;
+ }
+ }
+ }
+ } else {
+ while ( ( elem = elem[ dir ] ) ) {
+ if ( elem.nodeType === 1 || checkNonElements ) {
+ outerCache = elem[ expando ] || ( elem[ expando ] = {} );
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ elem.uniqueID ] ||
+ ( outerCache[ elem.uniqueID ] = {} );
+
+ if ( skip && skip === elem.nodeName.toLowerCase() ) {
+ elem = elem[ dir ] || elem;
+ } else if ( ( oldCache = uniqueCache[ key ] ) &&
+ oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
+
+ // Assign to newCache so results back-propagate to previous elements
+ return ( newCache[ 2 ] = oldCache[ 2 ] );
+ } else {
+
+ // Reuse newcache so results back-propagate to previous elements
+ uniqueCache[ key ] = newCache;
+
+ // A match means we're done; a fail means we have to keep checking
+ if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ };
+ }
+
+ function elementMatcher( matchers ) {
+ return matchers.length > 1 ?
+ function( elem, context, xml ) {
+ var i = matchers.length;
+ while ( i-- ) {
+ if ( !matchers[ i ]( elem, context, xml ) ) {
+ return false;
+ }
+ }
+ return true;
+ } :
+ matchers[ 0 ];
+ }
+
+ function multipleContexts( selector, contexts, results ) {
+ var i = 0,
+ len = contexts.length;
+ for ( ; i < len; i++ ) {
+ Sizzle( selector, contexts[ i ], results );
+ }
+ return results;
+ }
+
+ function condense( unmatched, map, filter, context, xml ) {
+ var elem,
+ newUnmatched = [],
+ i = 0,
+ len = unmatched.length,
+ mapped = map != null;
+
+ for ( ; i < len; i++ ) {
+ if ( ( elem = unmatched[ i ] ) ) {
+ if ( !filter || filter( elem, context, xml ) ) {
+ newUnmatched.push( elem );
+ if ( mapped ) {
+ map.push( i );
+ }
+ }
+ }
+ }
+
+ return newUnmatched;
+ }
+
+ function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
+ if ( postFilter && !postFilter[ expando ] ) {
+ postFilter = setMatcher( postFilter );
+ }
+ if ( postFinder && !postFinder[ expando ] ) {
+ postFinder = setMatcher( postFinder, postSelector );
+ }
+ return markFunction( function( seed, results, context, xml ) {
+ var temp, i, elem,
+ preMap = [],
+ postMap = [],
+ preexisting = results.length,
+
+ // Get initial elements from seed or context
+ elems = seed || multipleContexts(
+ selector || "*",
+ context.nodeType ? [ context ] : context,
+ []
+ ),
+
+ // Prefilter to get matcher input, preserving a map for seed-results synchronization
+ matcherIn = preFilter && ( seed || !selector ) ?
+ condense( elems, preMap, preFilter, context, xml ) :
+ elems,
+
+ matcherOut = matcher ?
+
+ // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
+ postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
+
+ // ...intermediate processing is necessary
+ [] :
+
+ // ...otherwise use results directly
+ results :
+ matcherIn;
+
+ // Find primary matches
+ if ( matcher ) {
+ matcher( matcherIn, matcherOut, context, xml );
+ }
+
+ // Apply postFilter
+ if ( postFilter ) {
+ temp = condense( matcherOut, postMap );
+ postFilter( temp, [], context, xml );
+
+ // Un-match failing elements by moving them back to matcherIn
+ i = temp.length;
+ while ( i-- ) {
+ if ( ( elem = temp[ i ] ) ) {
+ matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem );
+ }
+ }
+ }
+
+ if ( seed ) {
+ if ( postFinder || preFilter ) {
+ if ( postFinder ) {
+
+ // Get the final matcherOut by condensing this intermediate into postFinder contexts
+ temp = [];
+ i = matcherOut.length;
+ while ( i-- ) {
+ if ( ( elem = matcherOut[ i ] ) ) {
+
+ // Restore matcherIn since elem is not yet a final match
+ temp.push( ( matcherIn[ i ] = elem ) );
+ }
+ }
+ postFinder( null, ( matcherOut = [] ), temp, xml );
+ }
+
+ // Move matched elements from seed to results to keep them synchronized
+ i = matcherOut.length;
+ while ( i-- ) {
+ if ( ( elem = matcherOut[ i ] ) &&
+ ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) {
+
+ seed[ temp ] = !( results[ temp ] = elem );
+ }
+ }
+ }
+
+ // Add elements to results, through postFinder if defined
+ } else {
+ matcherOut = condense(
+ matcherOut === results ?
+ matcherOut.splice( preexisting, matcherOut.length ) :
+ matcherOut
+ );
+ if ( postFinder ) {
+ postFinder( null, results, matcherOut, xml );
+ } else {
+ push.apply( results, matcherOut );
+ }
+ }
+ } );
+ }
+
+ function matcherFromTokens( tokens ) {
+ var checkContext, matcher, j,
+ len = tokens.length,
+ leadingRelative = Expr.relative[ tokens[ 0 ].type ],
+ implicitRelative = leadingRelative || Expr.relative[ " " ],
+ i = leadingRelative ? 1 : 0,
+
+ // The foundational matcher ensures that elements are reachable from top-level context(s)
+ matchContext = addCombinator( function( elem ) {
+ return elem === checkContext;
+ }, implicitRelative, true ),
+ matchAnyContext = addCombinator( function( elem ) {
+ return indexOf( checkContext, elem ) > -1;
+ }, implicitRelative, true ),
+ matchers = [ function( elem, context, xml ) {
+ var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
+ ( checkContext = context ).nodeType ?
+ matchContext( elem, context, xml ) :
+ matchAnyContext( elem, context, xml ) );
+
+ // Avoid hanging onto element (issue #299)
+ checkContext = null;
+ return ret;
+ } ];
+
+ for ( ; i < len; i++ ) {
+ if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) {
+ matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
+ } else {
+ matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );
+
+ // Return special upon seeing a positional matcher
+ if ( matcher[ expando ] ) {
+
+ // Find the next relative operator (if any) for proper handling
+ j = ++i;
+ for ( ; j < len; j++ ) {
+ if ( Expr.relative[ tokens[ j ].type ] ) {
+ break;
+ }
+ }
+ return setMatcher(
+ i > 1 && elementMatcher( matchers ),
+ i > 1 && toSelector(
+
+ // If the preceding token was a descendant combinator, insert an implicit any-element `*`
+ tokens
+ .slice( 0, i - 1 )
+ .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } )
+ ).replace( rtrim, "$1" ),
+ matcher,
+ i < j && matcherFromTokens( tokens.slice( i, j ) ),
+ j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),
+ j < len && toSelector( tokens )
+ );
+ }
+ matchers.push( matcher );
+ }
+ }
+
+ return elementMatcher( matchers );
+ }
+
+ function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
+ var bySet = setMatchers.length > 0,
+ byElement = elementMatchers.length > 0,
+ superMatcher = function( seed, context, xml, results, outermost ) {
+ var elem, j, matcher,
+ matchedCount = 0,
+ i = "0",
+ unmatched = seed && [],
+ setMatched = [],
+ contextBackup = outermostContext,
+
+ // We must always have either seed elements or outermost context
+ elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ),
+
+ // Use integer dirruns iff this is the outermost matcher
+ dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ),
+ len = elems.length;
+
+ if ( outermost ) {
+
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ outermostContext = context == document || context || outermost;
+ }
+
+ // Add elements passing elementMatchers directly to results
+ // Support: IE<9, Safari
+ // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id
+ for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {
+ if ( byElement && elem ) {
+ j = 0;
+
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ if ( !context && elem.ownerDocument != document ) {
+ setDocument( elem );
+ xml = !documentIsHTML;
+ }
+ while ( ( matcher = elementMatchers[ j++ ] ) ) {
+ if ( matcher( elem, context || document, xml ) ) {
+ results.push( elem );
+ break;
+ }
+ }
+ if ( outermost ) {
+ dirruns = dirrunsUnique;
+ }
+ }
+
+ // Track unmatched elements for set filters
+ if ( bySet ) {
+
+ // They will have gone through all possible matchers
+ if ( ( elem = !matcher && elem ) ) {
+ matchedCount--;
+ }
+
+ // Lengthen the array for every element, matched or not
+ if ( seed ) {
+ unmatched.push( elem );
+ }
+ }
+ }
+
+ // `i` is now the count of elements visited above, and adding it to `matchedCount`
+ // makes the latter nonnegative.
+ matchedCount += i;
+
+ // Apply set filters to unmatched elements
+ // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
+ // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
+ // no element matchers and no seed.
+ // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
+ // case, which will result in a "00" `matchedCount` that differs from `i` but is also
+ // numerically zero.
+ if ( bySet && i !== matchedCount ) {
+ j = 0;
+ while ( ( matcher = setMatchers[ j++ ] ) ) {
+ matcher( unmatched, setMatched, context, xml );
+ }
+
+ if ( seed ) {
+
+ // Reintegrate element matches to eliminate the need for sorting
+ if ( matchedCount > 0 ) {
+ while ( i-- ) {
+ if ( !( unmatched[ i ] || setMatched[ i ] ) ) {
+ setMatched[ i ] = pop.call( results );
+ }
+ }
+ }
+
+ // Discard index placeholder values to get only actual matches
+ setMatched = condense( setMatched );
+ }
+
+ // Add matches to results
+ push.apply( results, setMatched );
+
+ // Seedless set matches succeeding multiple successful matchers stipulate sorting
+ if ( outermost && !seed && setMatched.length > 0 &&
+ ( matchedCount + setMatchers.length ) > 1 ) {
+
+ Sizzle.uniqueSort( results );
+ }
+ }
+
+ // Override manipulation of globals by nested matchers
+ if ( outermost ) {
+ dirruns = dirrunsUnique;
+ outermostContext = contextBackup;
+ }
+
+ return unmatched;
+ };
+
+ return bySet ?
+ markFunction( superMatcher ) :
+ superMatcher;
+ }
+
+ compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
+ var i,
+ setMatchers = [],
+ elementMatchers = [],
+ cached = compilerCache[ selector + " " ];
+
+ if ( !cached ) {
+
+ // Generate a function of recursive functions that can be used to check each element
+ if ( !match ) {
+ match = tokenize( selector );
+ }
+ i = match.length;
+ while ( i-- ) {
+ cached = matcherFromTokens( match[ i ] );
+ if ( cached[ expando ] ) {
+ setMatchers.push( cached );
+ } else {
+ elementMatchers.push( cached );
+ }
+ }
+
+ // Cache the compiled function
+ cached = compilerCache(
+ selector,
+ matcherFromGroupMatchers( elementMatchers, setMatchers )
+ );
+
+ // Save selector and tokenization
+ cached.selector = selector;
+ }
+ return cached;
+ };
+
+ /**
+ * A low-level selection function that works with Sizzle's compiled
+ * selector functions
+ * @param {String|Function} selector A selector or a pre-compiled
+ * selector function built with Sizzle.compile
+ * @param {Element} context
+ * @param {Array} [results]
+ * @param {Array} [seed] A set of elements to match against
+ */
+ select = Sizzle.select = function( selector, context, results, seed ) {
+ var i, tokens, token, type, find,
+ compiled = typeof selector === "function" && selector,
+ match = !seed && tokenize( ( selector = compiled.selector || selector ) );
+
+ results = results || [];
+
+ // Try to minimize operations if there is only one selector in the list and no seed
+ // (the latter of which guarantees us context)
+ if ( match.length === 1 ) {
+
+ // Reduce context if the leading compound selector is an ID
+ tokens = match[ 0 ] = match[ 0 ].slice( 0 );
+ if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" &&
+ context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) {
+
+ context = ( Expr.find[ "ID" ]( token.matches[ 0 ]
+ .replace( runescape, funescape ), context ) || [] )[ 0 ];
+ if ( !context ) {
+ return results;
+
+ // Precompiled matchers will still verify ancestry, so step up a level
+ } else if ( compiled ) {
+ context = context.parentNode;
+ }
+
+ selector = selector.slice( tokens.shift().value.length );
+ }
+
+ // Fetch a seed set for right-to-left matching
+ i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length;
+ while ( i-- ) {
+ token = tokens[ i ];
+
+ // Abort if we hit a combinator
+ if ( Expr.relative[ ( type = token.type ) ] ) {
+ break;
+ }
+ if ( ( find = Expr.find[ type ] ) ) {
+
+ // Search, expanding context for leading sibling combinators
+ if ( ( seed = find(
+ token.matches[ 0 ].replace( runescape, funescape ),
+ rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) ||
+ context
+ ) ) ) {
+
+ // If seed is empty or no tokens remain, we can return early
+ tokens.splice( i, 1 );
+ selector = seed.length && toSelector( tokens );
+ if ( !selector ) {
+ push.apply( results, seed );
+ return results;
+ }
+
+ break;
+ }
+ }
+ }
+ }
+
+ // Compile and execute a filtering function if one is not provided
+ // Provide `match` to avoid retokenization if we modified the selector above
+ ( compiled || compile( selector, match ) )(
+ seed,
+ context,
+ !documentIsHTML,
+ results,
+ !context || rsibling.test( selector ) && testContext( context.parentNode ) || context
+ );
+ return results;
+ };
+
+ // One-time assignments
+
+ // Sort stability
+ support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando;
+
+ // Support: Chrome 14-35+
+ // Always assume duplicates if they aren't passed to the comparison function
+ support.detectDuplicates = !!hasDuplicate;
+
+ // Initialize against the default document
+ setDocument();
+
+ // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
+ // Detached nodes confoundingly follow *each other*
+ support.sortDetached = assert( function( el ) {
+
+ // Should return 1, but returns 4 (following)
+ return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1;
+ } );
+
+ // Support: IE<8
+ // Prevent attribute/property "interpolation"
+ // https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+ if ( !assert( function( el ) {
+ el.innerHTML = "";
+ return el.firstChild.getAttribute( "href" ) === "#";
+ } ) ) {
+ addHandle( "type|href|height|width", function( elem, name, isXML ) {
+ if ( !isXML ) {
+ return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
+ }
+ } );
+ }
+
+ // Support: IE<9
+ // Use defaultValue in place of getAttribute("value")
+ if ( !support.attributes || !assert( function( el ) {
+ el.innerHTML = "";
+ el.firstChild.setAttribute( "value", "" );
+ return el.firstChild.getAttribute( "value" ) === "";
+ } ) ) {
+ addHandle( "value", function( elem, _name, isXML ) {
+ if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
+ return elem.defaultValue;
+ }
+ } );
+ }
+
+ // Support: IE<9
+ // Use getAttributeNode to fetch booleans when getAttribute lies
+ if ( !assert( function( el ) {
+ return el.getAttribute( "disabled" ) == null;
+ } ) ) {
+ addHandle( booleans, function( elem, name, isXML ) {
+ var val;
+ if ( !isXML ) {
+ return elem[ name ] === true ? name.toLowerCase() :
+ ( val = elem.getAttributeNode( name ) ) && val.specified ?
+ val.value :
+ null;
+ }
+ } );
+ }
+
+ return Sizzle;
+
+ } )( window );
+
+
+
+ jQuery.find = Sizzle;
+ jQuery.expr = Sizzle.selectors;
+
+ // Deprecated
+ jQuery.expr[ ":" ] = jQuery.expr.pseudos;
+ jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
+ jQuery.text = Sizzle.getText;
+ jQuery.isXMLDoc = Sizzle.isXML;
+ jQuery.contains = Sizzle.contains;
+ jQuery.escapeSelector = Sizzle.escape;
+
+
+
+
+ var dir = function( elem, dir, until ) {
+ var matched = [],
+ truncate = until !== undefined;
+
+ while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
+ if ( elem.nodeType === 1 ) {
+ if ( truncate && jQuery( elem ).is( until ) ) {
+ break;
+ }
+ matched.push( elem );
+ }
+ }
+ return matched;
+ };
+
+
+ var siblings = function( n, elem ) {
+ var matched = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType === 1 && n !== elem ) {
+ matched.push( n );
+ }
+ }
+
+ return matched;
+ };
+
+
+ var rneedsContext = jQuery.expr.match.needsContext;
+
+
+
+ function nodeName( elem, name ) {
+
+ return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
+
+ }
+ var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
+
+
+
+ // Implement the identical functionality for filter and not
+ function winnow( elements, qualifier, not ) {
+ if ( isFunction( qualifier ) ) {
+ return jQuery.grep( elements, function( elem, i ) {
+ return !!qualifier.call( elem, i, elem ) !== not;
+ } );
+ }
+
+ // Single element
+ if ( qualifier.nodeType ) {
+ return jQuery.grep( elements, function( elem ) {
+ return ( elem === qualifier ) !== not;
+ } );
+ }
+
+ // Arraylike of elements (jQuery, arguments, Array)
+ if ( typeof qualifier !== "string" ) {
+ return jQuery.grep( elements, function( elem ) {
+ return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
+ } );
+ }
+
+ // Filtered directly for both simple and complex selectors
+ return jQuery.filter( qualifier, elements, not );
+ }
+
+ jQuery.filter = function( expr, elems, not ) {
+ var elem = elems[ 0 ];
+
+ if ( not ) {
+ expr = ":not(" + expr + ")";
+ }
+
+ if ( elems.length === 1 && elem.nodeType === 1 ) {
+ return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
+ }
+
+ return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
+ return elem.nodeType === 1;
+ } ) );
+ };
+
+ jQuery.fn.extend( {
+ find: function( selector ) {
+ var i, ret,
+ len = this.length,
+ self = this;
+
+ if ( typeof selector !== "string" ) {
+ return this.pushStack( jQuery( selector ).filter( function() {
+ for ( i = 0; i < len; i++ ) {
+ if ( jQuery.contains( self[ i ], this ) ) {
+ return true;
+ }
+ }
+ } ) );
+ }
+
+ ret = this.pushStack( [] );
+
+ for ( i = 0; i < len; i++ ) {
+ jQuery.find( selector, self[ i ], ret );
+ }
+
+ return len > 1 ? jQuery.uniqueSort( ret ) : ret;
+ },
+ filter: function( selector ) {
+ return this.pushStack( winnow( this, selector || [], false ) );
+ },
+ not: function( selector ) {
+ return this.pushStack( winnow( this, selector || [], true ) );
+ },
+ is: function( selector ) {
+ return !!winnow(
+ this,
+
+ // If this is a positional/relative selector, check membership in the returned set
+ // so $("p:first").is("p:last") won't return true for a doc with two "p".
+ typeof selector === "string" && rneedsContext.test( selector ) ?
+ jQuery( selector ) :
+ selector || [],
+ false
+ ).length;
+ }
+ } );
+
+
+ // Initialize a jQuery object
+
+
+ // A central reference to the root jQuery(document)
+ var rootjQuery,
+
+ // A simple way to check for HTML strings
+ // Prioritize #id over to avoid XSS via location.hash (trac-9521)
+ // Strict HTML recognition (trac-11290: must start with <)
+ // Shortcut simple #id case for speed
+ rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
+
+ init = jQuery.fn.init = function( selector, context, root ) {
+ var match, elem;
+
+ // HANDLE: $(""), $(null), $(undefined), $(false)
+ if ( !selector ) {
+ return this;
+ }
+
+ // Method init() accepts an alternate rootjQuery
+ // so migrate can support jQuery.sub (gh-2101)
+ root = root || rootjQuery;
+
+ // Handle HTML strings
+ if ( typeof selector === "string" ) {
+ if ( selector[ 0 ] === "<" &&
+ selector[ selector.length - 1 ] === ">" &&
+ selector.length >= 3 ) {
+
+ // Assume that strings that start and end with <> are HTML and skip the regex check
+ match = [ null, selector, null ];
+
+ } else {
+ match = rquickExpr.exec( selector );
+ }
+
+ // Match html or make sure no context is specified for #id
+ if ( match && ( match[ 1 ] || !context ) ) {
+
+ // HANDLE: $(html) -> $(array)
+ if ( match[ 1 ] ) {
+ context = context instanceof jQuery ? context[ 0 ] : context;
+
+ // Option to run scripts is true for back-compat
+ // Intentionally let the error be thrown if parseHTML is not present
+ jQuery.merge( this, jQuery.parseHTML(
+ match[ 1 ],
+ context && context.nodeType ? context.ownerDocument || context : document,
+ true
+ ) );
+
+ // HANDLE: $(html, props)
+ if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
+ for ( match in context ) {
+
+ // Properties of context are called as methods if possible
+ if ( isFunction( this[ match ] ) ) {
+ this[ match ]( context[ match ] );
+
+ // ...and otherwise set as attributes
+ } else {
+ this.attr( match, context[ match ] );
+ }
+ }
+ }
+
+ return this;
+
+ // HANDLE: $(#id)
+ } else {
+ elem = document.getElementById( match[ 2 ] );
+
+ if ( elem ) {
+
+ // Inject the element directly into the jQuery object
+ this[ 0 ] = elem;
+ this.length = 1;
+ }
+ return this;
+ }
+
+ // HANDLE: $(expr, $(...))
+ } else if ( !context || context.jquery ) {
+ return ( context || root ).find( selector );
+
+ // HANDLE: $(expr, context)
+ // (which is just equivalent to: $(context).find(expr)
+ } else {
+ return this.constructor( context ).find( selector );
+ }
+
+ // HANDLE: $(DOMElement)
+ } else if ( selector.nodeType ) {
+ this[ 0 ] = selector;
+ this.length = 1;
+ return this;
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( isFunction( selector ) ) {
+ return root.ready !== undefined ?
+ root.ready( selector ) :
+
+ // Execute immediately if ready is not present
+ selector( jQuery );
+ }
+
+ return jQuery.makeArray( selector, this );
+ };
+
+ // Give the init function the jQuery prototype for later instantiation
+ init.prototype = jQuery.fn;
+
+ // Initialize central reference
+ rootjQuery = jQuery( document );
+
+
+ var rparentsprev = /^(?:parents|prev(?:Until|All))/,
+
+ // Methods guaranteed to produce a unique set when starting from a unique set
+ guaranteedUnique = {
+ children: true,
+ contents: true,
+ next: true,
+ prev: true
+ };
+
+ jQuery.fn.extend( {
+ has: function( target ) {
+ var targets = jQuery( target, this ),
+ l = targets.length;
+
+ return this.filter( function() {
+ var i = 0;
+ for ( ; i < l; i++ ) {
+ if ( jQuery.contains( this, targets[ i ] ) ) {
+ return true;
+ }
+ }
+ } );
+ },
+
+ closest: function( selectors, context ) {
+ var cur,
+ i = 0,
+ l = this.length,
+ matched = [],
+ targets = typeof selectors !== "string" && jQuery( selectors );
+
+ // Positional selectors never match, since there's no _selection_ context
+ if ( !rneedsContext.test( selectors ) ) {
+ for ( ; i < l; i++ ) {
+ for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
+
+ // Always skip document fragments
+ if ( cur.nodeType < 11 && ( targets ?
+ targets.index( cur ) > -1 :
+
+ // Don't pass non-elements to Sizzle
+ cur.nodeType === 1 &&
+ jQuery.find.matchesSelector( cur, selectors ) ) ) {
+
+ matched.push( cur );
+ break;
+ }
+ }
+ }
+ }
+
+ return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
+ },
+
+ // Determine the position of an element within the set
+ index: function( elem ) {
+
+ // No argument, return index in parent
+ if ( !elem ) {
+ return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
+ }
+
+ // Index in selector
+ if ( typeof elem === "string" ) {
+ return indexOf.call( jQuery( elem ), this[ 0 ] );
+ }
+
+ // Locate the position of the desired element
+ return indexOf.call( this,
+
+ // If it receives a jQuery object, the first element is used
+ elem.jquery ? elem[ 0 ] : elem
+ );
+ },
+
+ add: function( selector, context ) {
+ return this.pushStack(
+ jQuery.uniqueSort(
+ jQuery.merge( this.get(), jQuery( selector, context ) )
+ )
+ );
+ },
+
+ addBack: function( selector ) {
+ return this.add( selector == null ?
+ this.prevObject : this.prevObject.filter( selector )
+ );
+ }
+ } );
+
+ function sibling( cur, dir ) {
+ while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
+ return cur;
+ }
+
+ jQuery.each( {
+ parent: function( elem ) {
+ var parent = elem.parentNode;
+ return parent && parent.nodeType !== 11 ? parent : null;
+ },
+ parents: function( elem ) {
+ return dir( elem, "parentNode" );
+ },
+ parentsUntil: function( elem, _i, until ) {
+ return dir( elem, "parentNode", until );
+ },
+ next: function( elem ) {
+ return sibling( elem, "nextSibling" );
+ },
+ prev: function( elem ) {
+ return sibling( elem, "previousSibling" );
+ },
+ nextAll: function( elem ) {
+ return dir( elem, "nextSibling" );
+ },
+ prevAll: function( elem ) {
+ return dir( elem, "previousSibling" );
+ },
+ nextUntil: function( elem, _i, until ) {
+ return dir( elem, "nextSibling", until );
+ },
+ prevUntil: function( elem, _i, until ) {
+ return dir( elem, "previousSibling", until );
+ },
+ siblings: function( elem ) {
+ return siblings( ( elem.parentNode || {} ).firstChild, elem );
+ },
+ children: function( elem ) {
+ return siblings( elem.firstChild );
+ },
+ contents: function( elem ) {
+ if ( elem.contentDocument != null &&
+
+ // Support: IE 11+
+ //