diff --git a/.gitignore b/.gitignore index a77e4d7..9b4ae14 100644 --- a/.gitignore +++ b/.gitignore @@ -1,32 +1,26 @@ +# Dependencies node_modules/ +nostr-tools/ -packages/auth/dist/ -packages/components/dist/ -packages/components/www/ -packages/components/loader/ +# IDE and OS files +.idea/ +.vscode/ +.DS_Store +Thumbs.db -packages/components/*~ -packages/components/*.sw[mnpcod] -packages/components/*.log -packages/components/*.lock -packages/components/*.tmp -packages/components/*.tmp.* -packages/components/log.txt -packages/components/*.sublime-project -packages/components/*.sublime-workspace +# Temporary files +*.log +*.tmp +*.tmp.* +*~ +*.sw[mnpcod] +*.lock +log.txt +Trash/ -packages/components/.stencil/ -packages/components/.idea/ -packages/components/.vscode/ -packages/components/.sass-cache/ -packages/components/.versions/ +# Environment files +.env -packages/components/$RECYCLE.BIN/ - -packages/components/.DS_Store -packages/components/Thumbs.db -packages/components/UserInterfaceState.xcuserstate -packages/components/.env # Aider files .aider.chat.history.md .aider.input.history diff --git a/17.md b/17.md new file mode 100644 index 0000000..e9e97ba --- /dev/null +++ b/17.md @@ -0,0 +1,211 @@ +NIP-17 +====== + +Private Direct Messages +----------------------- + +`draft` `optional` + +This NIP defines an encrypted direct messaging scheme using [NIP-44](44.md) encryption and [NIP-59](59.md) seals and gift wraps. + +## Direct Message Kind + +Kind `14` is a chat message. `p` tags identify one or more receivers of the message. + +```jsonc +{ + "id": "", + "pubkey": "", + "created_at": "", + "kind": 14, + "tags": [ + ["p", "", ""], + ["p", "", ""], + ["e", "", ""] // if this is a reply + ["subject", ""], + // rest of tags... + ], + "content": "", +} +``` + +`.content` MUST be plain text. Fields `id` and `created_at` are required. + +An `e` tag denotes the direct parent message this post is replying to. + +`q` tags MAY be used when citing events in the `.content` with [NIP-21](21.md). + +```json +["q", " or ", "", ""] +``` + +Kind `14`s MUST never be signed. If it is signed, the message might leak to relays and become **fully public**. + +## File Message Kind + +```jsonc +{ + "id": "", + "pubkey": "", + "created_at": "", + "kind": 15, + "tags": [ + ["p", "", ""], + ["p", "", ""], + ["e", "", "", "reply"], // if this is a reply + ["subject", ""], + ["file-type", ""], + ["encryption-algorithm", ""], + ["decryption-key", ""], + ["decryption-nonce", ""], + ["x", ""], + // rest of tags... + ], + "content": "" +} +``` + +Kind `15` is used for sending encrypted file event messages: + +- `file-type`: Specifies the MIME type of the attached file (e.g., `image/jpeg`, `audio/mpeg`, etc.) before encryption. +- `encryption-algorithm`: Indicates the encryption algorithm used for encrypting the file. Supported algorithms: `aes-gcm`. +- `decryption-key`: The decryption key that will be used by the recipient to decrypt the file. +- `decryption-nonce`: The decryption nonce that will be used by the recipient to decrypt the file. +- `content`: The URL of the file (``). +- `x` containing the SHA-256 hexencoded string of the encrypted file. +- `ox` containing the SHA-256 hexencoded string of the file before encryption. +- `size` (optional) size of the encrypted file in bytes +- `dim` (optional) size in pixels in the form `x` +- `blurhash`(optional) the [blurhash](https://github.com/woltapp/blurhash) to show while the client is loading the file +- `thumb` (optional) URL of thumbnail with same aspect ratio (encrypted with the same key, nonce) +- `fallback` (optional) zero or more fallback file sources in case `url` fails (encrypted with the same key, nonce) + +Just like kind `14`, kind `15`s MUST never be signed. + +## Chat Rooms + +The set of `pubkey` + `p` tags defines a chat room. If a new `p` tag is added or a current one is removed, a new room is created with a clean message history. + +Clients SHOULD render messages of the same room in a continuous thread. + +An optional `subject` tag defines the current name/topic of the conversation. Any member can change the topic by simply submitting a new `subject` to an existing `pubkey` + `p` tags room. There is no need to send `subject` in every message. The newest `subject` in the chat room is the subject of the conversation. + +## Encrypting + +Following [NIP-59](59.md), the **unsigned** `kind:14` & `kind:15` chat messages must be sealed (`kind:13`) and then gift-wrapped (`kind:1059`) to each receiver and the sender individually. + +```js +{ + "id": "", + "pubkey": randomPublicKey, + "created_at": randomTimeUpTo2DaysInThePast(), + "kind": 1059, // gift wrap + "tags": [ + ["p", receiverPublicKey, ""] // receiver + ], + "content": nip44Encrypt( + { + "id": "", + "pubkey": senderPublicKey, + "created_at": randomTimeUpTo2DaysInThePast(), + "kind": 13, // seal + "tags": [], // no tags + "content": nip44Encrypt(unsignedKind14, senderPrivateKey, receiverPublicKey), + "sig": "" + }, + randomPrivateKey, receiverPublicKey + ), + "sig": "" +} +``` + +The encryption algorithm MUST use the latest version of [NIP-44](44.md). + +Clients MUST verify if pubkey of the `kind:13` is the same pubkey on the `kind:14`, otherwise any sender can impersonate others by simply changing the pubkey on `kind:14`. + +Clients SHOULD randomize `created_at` in up to two days in the past in both the seal and the gift wrap to make sure grouping by `created_at` doesn't reveal any metadata. + +The gift wrap's `p` tag can be the receiver's main pubkey or an alias key created to receive DMs without exposing the receiver's identity. + +Clients CAN offer disappearing messages by setting an `expiration` tag in the gift wrap of each receiver or by not generating a gift wrap to the sender's public key + +## Publishing + +Kind `10050` indicates the user's preferred relays to receive DMs. The event MUST include a list of `relay` tags with relay URIs. + +```jsonc +{ + "kind": 10050, + "tags": [ + ["relay", "wss://inbox.nostr.wine"], + ["relay", "wss://myrelay.nostr1.com"], + ], + "content": "", + // other fields... +} +``` + +Clients SHOULD publish kind `14` events to the `10050`-listed relays. If that is not found that indicates the user is not ready to receive messages under this NIP and clients shouldn't try. + +## Relays + +It's advisable that relays do not serve `kind:1059` to clients other than the ones tagged in them. + +It's advisable that users choose relays that conform to these practices. + +Clients SHOULD guide users to keep `kind:10050` lists small (1-3 relays) and SHOULD spread it to as many relays as viable. + +## Benefits & Limitations + +This NIP offers the following privacy and security features: + +1. **No Metadata Leak**: Participant identities, each message's real date and time, event kinds, and other event tags are all hidden from the public. Senders and receivers cannot be linked with public information alone. +2. **No Public Group Identifiers**: There is no public central queue, channel or otherwise converging identifier to correlate or count all messages in the same group. +3. **No Moderation**: There are no group admins: no invitations or bans. +4. **No Shared Secrets**: No secret must be known to all members that can leak or be mistakenly shared +5. **Fully Recoverable**: Messages can be fully recoverable by any client with the user's private key +6. **Optional Forward Secrecy**: Users and clients can opt-in for "disappearing messages". +7. **Uses Public Relays**: Messages can flow through public relays without loss of privacy. Private relays can increase privacy further, but they are not required. +8. **Cold Storage**: Users can unilaterally opt-in to sharing their messages with a separate key that is exclusive for DM backup and recovery. + +The main limitation of this approach is having to send a separate encrypted event to each receiver. Group chats with more than 100 participants should find a more suitable messaging scheme. + +## Implementation + +Clients implementing this NIP should by default only connect to the set of relays found in their `kind:10050` list. From that they should be able to load all messages both sent and received as well as get new live updates, making it for a very simple and lightweight implementation that should be fast. + +When sending a message to anyone, clients must then connect to the relays in the receiver's `kind:10050` and send the events there but can disconnect right after unless more messages are expected to be sent (e.g. the chat tab is still selected). Clients should also send a copy of their outgoing messages to their own `kind:10050` relay set. + +## Examples + +This example sends the message `Hola, que tal?` from `nsec1w8udu59ydjvedgs3yv5qccshcj8k05fh3l60k9x57asjrqdpa00qkmr89m` to `nsec12ywtkplvyq5t6twdqwwygavp5lm4fhuang89c943nf2z92eez43szvn4dt`. + +The two final GiftWraps, one to the receiver and the other to the sender, respectively, are: + +```json +{ + "id":"2886780f7349afc1344047524540ee716f7bdc1b64191699855662330bf235d8", + "pubkey":"8f8a7ec43b77d25799281207e1a47f7a654755055788f7482653f9c9661c6d51", + "created_at":1703128320, + "kind":1059, + "tags":[ + ["p", "918e2da906df4ccd12c8ac672d8335add131a4cf9d27ce42b3bb3625755f0788"] + ], + "content":"AsqzdlMsG304G8h08bE67dhAR1gFTzTckUUyuvndZ8LrGCvwI4pgC3d6hyAK0Wo9gtkLqSr2rT2RyHlE5wRqbCOlQ8WvJEKwqwIJwT5PO3l2RxvGCHDbd1b1o40ZgIVwwLCfOWJ86I5upXe8K5AgpxYTOM1BD+SbgI5jOMA8tgpRoitJedVSvBZsmwAxXM7o7sbOON4MXHzOqOZpALpS2zgBDXSAaYAsTdEM4qqFeik+zTk3+L6NYuftGidqVluicwSGS2viYWr5OiJ1zrj1ERhYSGLpQnPKrqDaDi7R1KrHGFGyLgkJveY/45y0rv9aVIw9IWF11u53cf2CP7akACel2WvZdl1htEwFu/v9cFXD06fNVZjfx3OssKM/uHPE9XvZttQboAvP5UoK6lv9o3d+0GM4/3zP+yO3C0NExz1ZgFmbGFz703YJzM+zpKCOXaZyzPjADXp8qBBeVc5lmJqiCL4solZpxA1865yPigPAZcc9acSUlg23J1dptFK4n3Tl5HfSHP+oZ/QS/SHWbVFCtq7ZMQSRxLgEitfglTNz9P1CnpMwmW/Y4Gm5zdkv0JrdUVrn2UO9ARdHlPsW5ARgDmzaxnJypkfoHXNfxGGXWRk0sKLbz/ipnaQP/eFJv/ibNuSfqL6E4BnN/tHJSHYEaTQ/PdrA2i9laG3vJti3kAl5Ih87ct0w/tzYfp4SRPhEF1zzue9G/16eJEMzwmhQ5Ec7jJVcVGa4RltqnuF8unUu3iSRTQ+/MNNUkK6Mk+YuaJJs6Fjw6tRHuWi57SdKKv7GGkr0zlBUU2Dyo1MwpAqzsCcCTeQSv+8qt4wLf4uhU9Br7F/L0ZY9bFgh6iLDCdB+4iABXyZwT7Ufn762195hrSHcU4Okt0Zns9EeiBOFxnmpXEslYkYBpXw70GmymQfJlFOfoEp93QKCMS2DAEVeI51dJV1e+6t3pCSsQN69Vg6jUCsm1TMxSs2VX4BRbq562+VffchvW2BB4gMjsvHVUSRl8i5/ZSDlfzSPXcSGALLHBRzy+gn0oXXJ/447VHYZJDL3Ig8+QW5oFMgnWYhuwI5QSLEyflUrfSz+Pdwn/5eyjybXKJftePBD9Q+8NQ8zulU5sqvsMeIx/bBUx0fmOXsS3vjqCXW5IjkmSUV7q54GewZqTQBlcx+90xh/LSUxXex7UwZwRnifvyCbZ+zwNTHNb12chYeNjMV7kAIr3cGQv8vlOMM8ajyaZ5KVy7HpSXQjz4PGT2/nXbL5jKt8Lx0erGXsSsazkdoYDG3U", + "sig":"a3c6ce632b145c0869423c1afaff4a6d764a9b64dedaf15f170b944ead67227518a72e455567ca1c2a0d187832cecbde7ed478395ec4c95dd3e71749ed66c480" +} +``` + +```json +{ + "id":"162b0611a1911cfcb30f8a5502792b346e535a45658b3a31ae5c178465509721", + "pubkey":"626be2af274b29ea4816ad672ee452b7cf96bbb4836815a55699ae402183f512", + "created_at":1702711587, + "kind":1059, + "tags":[ + ["p", "44900586091b284416a0c001f677f9c49f7639a55c3f1e2ec130a8e1a7998e1b"] + ], + "content":"AsTClTzr0gzXXji7uye5UB6LYrx3HDjWGdkNaBS6BAX9CpHa+Vvtt5oI2xJrmWLen+Fo2NBOFazvl285Gb3HSM82gVycrzx1HUAaQDUG6HI7XBEGqBhQMUNwNMiN2dnilBMFC3Yc8ehCJT/gkbiNKOpwd2rFibMFRMDKai2mq2lBtPJF18oszKOjA+XlOJV8JRbmcAanTbEK5nA/GnG3eGUiUzhiYBoHomj3vztYYxc0QYHOx0WxiHY8dsC6jPsXC7f6k4P+Hv5ZiyTfzvjkSJOckel1lZuE5SfeZ0nduqTlxREGeBJ8amOykgEIKdH2VZBZB+qtOMc7ez9dz4wffGwBDA7912NFS2dPBr6txHNxBUkDZKFbuD5wijvonZDvfWq43tZspO4NutSokZB99uEiRH8NAUdGTiNb25m9JcDhVfdmABqTg5fIwwTwlem5aXIy8b66lmqqz2LBzJtnJDu36bDwkILph3kmvaKPD8qJXmPQ4yGpxIbYSTCohgt2/I0TKJNmqNvSN+IVoUuC7ZOfUV9lOV8Ri0AMfSr2YsdZ9ofV5o82ClZWlWiSWZwy6ypa7CuT1PEGHzywB4CZ5ucpO60Z7hnBQxHLiAQIO/QhiBp1rmrdQZFN6PUEjFDloykoeHe345Yqy9Ke95HIKUCS9yJurD+nZjjgOxZjoFCsB1hQAwINTIS3FbYOibZnQwv8PXvcSOqVZxC9U0+WuagK7IwxzhGZY3vLRrX01oujiRrevB4xbW7Oxi/Agp7CQGlJXCgmRE8Rhm+Vj2s+wc/4VLNZRHDcwtfejogjrjdi8p6nfUyqoQRRPARzRGUnnCbh+LqhigT6gQf3sVilnydMRScEc0/YYNLWnaw9nbyBa7wFBAiGbJwO40k39wj+xT6HTSbSUgFZzopxroO3f/o4+ubx2+IL3fkev22mEN38+dFmYF3zE+hpE7jVxrJpC3EP9PLoFgFPKCuctMnjXmeHoiGs756N5r1Mm1ffZu4H19MSuALJlxQR7VXE/LzxRXDuaB2u9days/6muP6gbGX1ASxbJd/ou8+viHmSC/ioHzNjItVCPaJjDyc6bv+gs1NPCt0qZ69G+JmgHW/PsMMeL4n5bh74g0fJSHqiI9ewEmOG/8bedSREv2XXtKV39STxPweceIOh0k23s3N6+wvuSUAJE7u1LkDo14cobtZ/MCw/QhimYPd1u5HnEJvRhPxz0nVPz0QqL/YQeOkAYk7uzgeb2yPzJ6DBtnTnGDkglekhVzQBFRJdk740LEj6swkJ", + "sig":"c94e74533b482aa8eeeb54ae72a5303e0b21f62909ca43c8ef06b0357412d6f8a92f96e1a205102753777fd25321a58fba3fb384eee114bd53ce6c06a1c22bab" +} +``` diff --git a/44.md b/44.md new file mode 100644 index 0000000..a7c13f1 --- /dev/null +++ b/44.md @@ -0,0 +1,297 @@ +NIP-44 +====== + +Encrypted Payloads (Versioned) +------------------------------ + +`optional` + +The NIP introduces a new data format for keypair-based encryption. This NIP is versioned +to allow multiple algorithm choices to exist simultaneously. This format may be used for +many things, but MUST be used in the context of a signed event as described in NIP-01. + +*Note*: this format DOES NOT define any `kind`s related to a new direct messaging standard, +only the encryption required to define one. It SHOULD NOT be used as a drop-in replacement +for NIP-04 payloads. + +## Versions + +Currently defined encryption algorithms: + +- `0x00` - Reserved +- `0x01` - Deprecated and undefined +- `0x02` - secp256k1 ECDH, HKDF, padding, ChaCha20, HMAC-SHA256, base64 + +## Limitations + +Every nostr user has their own public key, which solves key distribution problems present +in other solutions. However, nostr's relay-based architecture makes it difficult to implement +more robust private messaging protocols with things like metadata hiding, forward secrecy, +and post compromise secrecy. + +The goal of this NIP is to have a _simple_ way to encrypt payloads used in the context of a signed +event. When applying this NIP to any use case, it's important to keep in mind your users' threat +model and this NIP's limitations. For high-risk situations, users should chat in specialized E2EE +messaging software and limit use of nostr to exchanging contacts. + +On its own, messages sent using this scheme have a number of important shortcomings: + +- No deniability: it is possible to prove an event was signed by a particular key +- No forward secrecy: when a key is compromised, it is possible to decrypt all previous conversations +- No post-compromise security: when a key is compromised, it is possible to decrypt all future conversations +- No post-quantum security: a powerful quantum computer would be able to decrypt the messages +- IP address leak: user IP may be seen by relays and all intermediaries between user and relay +- Date leak: `created_at` is public, since it is a part of NIP-01 event +- Limited message size leak: padding only partially obscures true message length +- No attachments: they are not supported + +Lack of forward secrecy may be partially mitigated by only sending messages to trusted relays, and asking +relays to delete stored messages after a certain duration has elapsed. + +## Version 2 + +NIP-44 version 2 has the following design characteristics: + +- Payloads are authenticated using a MAC before signing rather than afterwards because events are assumed + to be signed as specified in NIP-01. The outer signature serves to authenticate the full payload, and MUST + be validated before decrypting. +- ChaCha is used instead of AES because it's faster and has + [better security against multi-key attacks](https://datatracker.ietf.org/doc/draft-irtf-cfrg-aead-limits/). +- ChaCha is used instead of XChaCha because XChaCha has not been standardized. Also, xChaCha's improved collision + resistance of nonces isn't necessary since every message has a new (key, nonce) pair. +- HMAC-SHA256 is used instead of Poly1305 because polynomial MACs are much easier to forge. +- SHA256 is used instead of SHA3 or BLAKE because it is already used in nostr. Also BLAKE's speed advantage + is smaller in non-parallel environments. +- A custom padding scheme is used instead of padmé because it provides better leakage reduction for small messages. +- Base64 encoding is used instead of another encoding algorithm because it is widely available, and is already used in nostr. + +### Encryption + +1. Calculate a conversation key + - Execute ECDH (scalar multiplication) of public key B by private key A + Output `shared_x` must be unhashed, 32-byte encoded x coordinate of the shared point + - Use HKDF-extract with sha256, `IKM=shared_x` and `salt=utf8_encode('nip44-v2')` + - HKDF output will be a `conversation_key` between two users. + - It is always the same, when key roles are swapped: `conv(a, B) == conv(b, A)` +2. Generate a random 32-byte nonce + - Always use [CSPRNG](https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator) + - Don't generate a nonce from message content + - Don't re-use the same nonce between messages: doing so would make them decryptable, + but won't leak the long-term key +3. Calculate message keys + - The keys are generated from `conversation_key` and `nonce`. Validate that both are 32 bytes long + - Use HKDF-expand, with sha256, `PRK=conversation_key`, `info=nonce` and `L=76` + - Slice 76-byte HKDF output into: `chacha_key` (bytes 0..32), `chacha_nonce` (bytes 32..44), `hmac_key` (bytes 44..76) +4. Add padding + - Content must be encoded from UTF-8 into byte array + - Validate plaintext length. Minimum is 1 byte, maximum is 65535 bytes + - Padding format is: `[plaintext_length: u16][plaintext][zero_bytes]` + - Padding algorithm is related to powers-of-two, with min padded msg size of 32 bytes + - Plaintext length is encoded in big-endian as first 2 bytes of the padded blob +5. Encrypt padded content + - Use ChaCha20, with key and nonce from step 3 +6. Calculate MAC (message authentication code) + - AAD (additional authenticated data) is used - instead of calculating MAC on ciphertext, + it's calculated over a concatenation of `nonce` and `ciphertext` + - Validate that AAD (nonce) is 32 bytes +7. Base64-encode (with padding) params using `concat(version, nonce, ciphertext, mac)` + +Encrypted payloads MUST be included in an event's payload, hashed, and signed as defined in NIP 01, using schnorr +signature scheme over secp256k1. + +### Decryption + +Before decryption, the event's pubkey and signature MUST be validated as defined in NIP 01. The public key MUST be +a valid non-zero secp256k1 curve point, and the signature must be valid secp256k1 schnorr signature. For exact +validation rules, refer to BIP-340. + +1. Check if first payload's character is `#` + - `#` is an optional future-proof flag that means non-base64 encoding is used + - The `#` is not present in base64 alphabet, but, instead of throwing `base64 is invalid`, + implementations MUST indicate that the encryption version is not yet supported +2. Decode base64 + - Base64 is decoded into `version, nonce, ciphertext, mac` + - If the version is unknown, implementations must indicate that the encryption version is not supported + - Validate length of base64 message to prevent DoS on base64 decoder: it can be in range from 132 to 87472 chars + - Validate length of decoded message to verify output of the decoder: it can be in range from 99 to 65603 bytes +3. Calculate conversation key + - See step 1 of [encryption](#Encryption) +4. Calculate message keys + - See step 3 of [encryption](#Encryption) +5. Calculate MAC (message authentication code) with AAD and compare + - Stop and throw an error if MAC doesn't match the decoded one from step 2 + - Use constant-time comparison algorithm +6. Decrypt ciphertext + - Use ChaCha20 with key and nonce from step 3 +7. Remove padding + - Read the first two BE bytes of plaintext that correspond to plaintext length + - Verify that the length of sliced plaintext matches the value of the two BE bytes + - Verify that calculated padding from step 3 of the [encryption](#Encryption) process matches the actual padding + +### Details + +- Cryptographic methods + - `secure_random_bytes(length)` fetches randomness from CSPRNG. + - `hkdf(IKM, salt, info, L)` represents HKDF [(RFC 5869)](https://datatracker.ietf.org/doc/html/rfc5869) + with SHA256 hash function comprised of methods `hkdf_extract(IKM, salt)` and `hkdf_expand(OKM, info, L)`. + - `chacha20(key, nonce, data)` is ChaCha20 [(RFC 8439)](https://datatracker.ietf.org/doc/html/rfc8439) with + starting counter set to 0. + - `hmac_sha256(key, message)` is HMAC [(RFC 2104)](https://datatracker.ietf.org/doc/html/rfc2104). + - `secp256k1_ecdh(priv_a, pub_b)` is multiplication of point B by scalar a (`a ⋅ B`), defined in + [BIP340](https://github.com/bitcoin/bips/blob/e918b50731397872ad2922a1b08a5a4cd1d6d546/bip-0340.mediawiki). + The operation produces a shared point, and we encode the shared point's 32-byte x coordinate, using method + `bytes(P)` from BIP340. Private and public keys must be validated as per BIP340: pubkey must be a valid, + on-curve point, and private key must be a scalar in range `[1, secp256k1_order - 1]`. + NIP44 doesn't do hashing of the output: keep this in mind, because some libraries hash it using sha256. + As an example, in libsecp256k1, unhashed version is available in `secp256k1_ec_pubkey_tweak_mul` +- Operators + - `x[i:j]`, where `x` is a byte array and `i, j <= 0` returns a `(j - i)`-byte array with a copy of the + `i`-th byte (inclusive) to the `j`-th byte (exclusive) of `x`. +- Constants `c`: + - `min_plaintext_size` is 1. 1 byte msg is padded to 32 bytes. + - `max_plaintext_size` is 65535 (64kB - 1). It is padded to 65536 bytes. +- Functions + - `base64_encode(string)` and `base64_decode(bytes)` are Base64 ([RFC 4648](https://datatracker.ietf.org/doc/html/rfc4648), with padding) + - `concat` refers to byte array concatenation + - `is_equal_ct(a, b)` is constant-time equality check of 2 byte arrays + - `utf8_encode(string)` and `utf8_decode(bytes)` transform string to byte array and back + - `write_u8(number)` restricts number to values 0..255 and encodes into Big-Endian uint8 byte array + - `write_u16_be(number)` restricts number to values 0..65535 and encodes into Big-Endian uint16 byte array + - `zeros(length)` creates byte array of length `length >= 0`, filled with zeros + - `floor(number)` and `log2(number)` are well-known mathematical methods + +### Implementation pseudocode + +The following is a collection of python-like pseudocode functions which implement the above primitives, +intended to guide implementers. A collection of implementations in different languages is available at https://github.com/paulmillr/nip44. + +```py +# Calculates length of the padded byte array. +def calc_padded_len(unpadded_len): + next_power = 1 << (floor(log2(unpadded_len - 1))) + 1 + if next_power <= 256: + chunk = 32 + else: + chunk = next_power / 8 + if unpadded_len <= 32: + return 32 + else: + return chunk * (floor((len - 1) / chunk) + 1) + +# Converts unpadded plaintext to padded bytearray +def pad(plaintext): + unpadded = utf8_encode(plaintext) + unpadded_len = len(plaintext) + if (unpadded_len < c.min_plaintext_size or + unpadded_len > c.max_plaintext_size): raise Exception('invalid plaintext length') + prefix = write_u16_be(unpadded_len) + suffix = zeros(calc_padded_len(unpadded_len) - unpadded_len) + return concat(prefix, unpadded, suffix) + +# Converts padded bytearray to unpadded plaintext +def unpad(padded): + unpadded_len = read_uint16_be(padded[0:2]) + unpadded = padded[2:2+unpadded_len] + if (unpadded_len == 0 or + len(unpadded) != unpadded_len or + len(padded) != 2 + calc_padded_len(unpadded_len)): raise Exception('invalid padding') + return utf8_decode(unpadded) + +# metadata: always 65b (version: 1b, nonce: 32b, max: 32b) +# plaintext: 1b to 0xffff +# padded plaintext: 32b to 0xffff +# ciphertext: 32b+2 to 0xffff+2 +# raw payload: 99 (65+32+2) to 65603 (65+0xffff+2) +# compressed payload (base64): 132b to 87472b +def decode_payload(payload): + plen = len(payload) + if plen == 0 or payload[0] == '#': raise Exception('unknown version') + if plen < 132 or plen > 87472: raise Exception('invalid payload size') + data = base64_decode(payload) + dlen = len(d) + if dlen < 99 or dlen > 65603: raise Exception('invalid data size'); + vers = data[0] + if vers != 2: raise Exception('unknown version ' + vers) + nonce = data[1:33] + ciphertext = data[33:dlen - 32] + mac = data[dlen - 32:dlen] + return (nonce, ciphertext, mac) + +def hmac_aad(key, message, aad): + if len(aad) != 32: raise Exception('AAD associated data must be 32 bytes'); + return hmac(sha256, key, concat(aad, message)); + +# Calculates long-term key between users A and B: `get_key(Apriv, Bpub) == get_key(Bpriv, Apub)` +def get_conversation_key(private_key_a, public_key_b): + shared_x = secp256k1_ecdh(private_key_a, public_key_b) + return hkdf_extract(IKM=shared_x, salt=utf8_encode('nip44-v2')) + +# Calculates unique per-message key +def get_message_keys(conversation_key, nonce): + if len(conversation_key) != 32: raise Exception('invalid conversation_key length') + if len(nonce) != 32: raise Exception('invalid nonce length') + keys = hkdf_expand(OKM=conversation_key, info=nonce, L=76) + chacha_key = keys[0:32] + chacha_nonce = keys[32:44] + hmac_key = keys[44:76] + return (chacha_key, chacha_nonce, hmac_key) + +def encrypt(plaintext, conversation_key, nonce): + (chacha_key, chacha_nonce, hmac_key) = get_message_keys(conversation_key, nonce) + padded = pad(plaintext) + ciphertext = chacha20(key=chacha_key, nonce=chacha_nonce, data=padded) + mac = hmac_aad(key=hmac_key, message=ciphertext, aad=nonce) + return base64_encode(concat(write_u8(2), nonce, ciphertext, mac)) + +def decrypt(payload, conversation_key): + (nonce, ciphertext, mac) = decode_payload(payload) + (chacha_key, chacha_nonce, hmac_key) = get_message_keys(conversation_key, nonce) + calculated_mac = hmac_aad(key=hmac_key, message=ciphertext, aad=nonce) + if not is_equal_ct(calculated_mac, mac): raise Exception('invalid MAC') + padded_plaintext = chacha20(key=chacha_key, nonce=chacha_nonce, data=ciphertext) + return unpad(padded_plaintext) + +# Usage: +# conversation_key = get_conversation_key(sender_privkey, recipient_pubkey) +# nonce = secure_random_bytes(32) +# payload = encrypt('hello world', conversation_key, nonce) +# 'hello world' == decrypt(payload, conversation_key) +``` + +### Audit + +The v2 of the standard was audited by [Cure53](https://cure53.de) in December 2023. +Check out [audit-2023.12.pdf](https://github.com/paulmillr/nip44/blob/ce63c2eaf345e9f7f93b48f829e6bdeb7e7d7964/audit-2023.12.pdf) +and [auditor's website](https://cure53.de/audit-report_nip44-implementations.pdf). + +### Tests and code + +A collection of implementations in different languages is available at https://github.com/paulmillr/nip44. + +We publish extensive test vectors. Instead of having it in the document directly, a sha256 checksum of vectors is provided: + + 269ed0f69e4c192512cc779e78c555090cebc7c785b609e338a62afc3ce25040 nip44.vectors.json + +Example of a test vector from the file: + +```json +{ + "sec1": "0000000000000000000000000000000000000000000000000000000000000001", + "sec2": "0000000000000000000000000000000000000000000000000000000000000002", + "conversation_key": "c41c775356fd92eadc63ff5a0dc1da211b268cbea22316767095b2871ea1412d", + "nonce": "0000000000000000000000000000000000000000000000000000000000000001", + "plaintext": "a", + "payload": "AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABee0G5VSK0/9YypIObAtDKfYEAjD35uVkHyB0F4DwrcNaCXlCWZKaArsGrY6M9wnuTMxWfp1RTN9Xga8no+kF5Vsb" +} +``` + +The file also contains intermediate values. A quick guidance with regards to its usage: + +- `valid.get_conversation_key`: calculate conversation_key from secret key sec1 and public key pub2 +- `valid.get_message_keys`: calculate chacha_key, chacha_nonce, hmac_key from conversation_key and nonce +- `valid.calc_padded_len`: take unpadded length (first value), calculate padded length (second value) +- `valid.encrypt_decrypt`: emulate real conversation. Calculate pub2 from sec2, verify conversation_key from (sec1, pub2), encrypt, verify payload, then calculate pub1 from sec1, verify conversation_key from (sec2, pub1), decrypt, verify plaintext. +- `valid.encrypt_decrypt_long_msg`: same as previous step, but instead of a full plaintext and payload, their checksum is provided. +- `invalid.encrypt_msg_lengths` +- `invalid.get_conversation_key`: calculating conversation_key must throw an error +- `invalid.decrypt`: decrypting message content must throw an error diff --git a/NOSTR_LOGIN_LITE.md b/NOSTR_LOGIN_LITE.md deleted file mode 100644 index 34bdc46..0000000 --- a/NOSTR_LOGIN_LITE.md +++ /dev/null @@ -1,318 +0,0 @@ -# NOSTR_LOGIN_LITE - -Objective -- Deliver a minimal, dependency-light replacement for the current auth/UI stack that: - - Preserves all login methods: Nostr Connect (nip46), Extension, Local key, Read-only, OTP/DM. - - Exposes the same window.nostr surface: [getPublicKey()](lite/nostr-login-lite.js:1), [signEvent(event)](lite/nostr-login-lite.js:1), [nip04.encrypt(pubkey, plaintext)](lite/nostr-login-lite.js:1), [nip04.decrypt(pubkey, ciphertext)](lite/nostr-login-lite.js:1), [nip44.encrypt(pubkey, plaintext)](lite/nostr-login-lite.js:1), [nip44.decrypt(pubkey, ciphertext)](lite/nostr-login-lite.js:1). - - Dispatches identical nlAuth/nlLaunch/nlLogout/nlDarkMode events and accepts setAuth calls for compatibility. - -Key differences vs current project -- UI: replace Stencil/Tailwind component library with a single vanilla-JS modal and minimal CSS. -- Transport: remove NDK; implement NIP-46 RPC using nostr-tools SimplePool. -- Crypto: rely on nostr-tools (via CDN global window.NostrTools) for keygen/signing (finalizeEvent), nip04, nip19, and SimplePool; embed a small NIP-44 codec if window.NostrTools.nip44 is not available. The current project’s codec is in [packages/auth/src/utils/nip44.ts](packages/auth/src/utils/nip44.ts). - -Nostr Tools via CDN (global window.NostrTools) -- Include the bundle once in the page: - -- Access APIs via window.NostrTools inside the lite build: - - [NostrTools.generateSecretKey()](lite/nostr-login-lite.js:1) or [NostrTools.generatePrivateKey()](lite/nostr-login-lite.js:1) (depending on CDN version) - - [NostrTools.getPublicKey()](lite/nostr-login-lite.js:1) - - [NostrTools.finalizeEvent()](lite/nostr-login-lite.js:1) - - [NostrTools.nip04](lite/nostr-login-lite.js:1) encrypt/decrypt - - [NostrTools.nip19](lite/nostr-login-lite.js:1) npub/nsec encode/decode - - [NostrTools.SimplePool](lite/nostr-login-lite.js:1) relay connectivity - -Supported login methods and crypto summary -- Connect (nip46): secp256k1 Schnorr for event signing/hash; nip44 (ChaCha20/HKDF/HMAC) for RPC payloads, with nip04 fallback. Requires relay connectivity (via [NostrTools.SimplePool](lite/nostr-login-lite.js:1)). -- Extension: crypto handled by the extension; we bridge calls. -- Local key: secp256k1 Schnorr signing ([NostrTools.finalizeEvent()](lite/nostr-login-lite.js:1)) and nip04/nip44 encrypt/decrypt locally. -- Read-only: no client crypto. -- OTP/DM: no client crypto beyond state persistence; server sends DM and verifies via HTTP. - -Minimal file layout -- Single file drop-in (script tag friendly): - - [lite/nostr-login-lite.js](lite/nostr-login-lite.js) -- Optional split during development (bundled later): - - [lite/core/nostr-lite.js](lite/core/nostr-lite.js) - - [lite/core/nip46-client.js](lite/core/nip46-client.js) - - [lite/core/extension-bridge.js](lite/core/extension-bridge.js) - - [lite/core/store.js](lite/core/store.js) - - [lite/ui/modal.js](lite/ui/modal.js) - -External dependencies strategy -- Use the CDN bundle to provide [window.NostrTools](lite/nostr-login-lite.js:1) at runtime. No npm installs required. -- Prefer built-ins from window.NostrTools: - - Keys/sign: [generateSecretKey()](lite/nostr-login-lite.js:1)/[generatePrivateKey()](lite/nostr-login-lite.js:1), [getPublicKey()](lite/nostr-login-lite.js:1), [finalizeEvent()](lite/nostr-login-lite.js:1). - - Encoding: [nip19](lite/nostr-login-lite.js:1). - - Encryption: [nip04](lite/nostr-login-lite.js:1). - - Relays: [SimplePool](lite/nostr-login-lite.js:1). -- Nip44 choice: - - If window.NostrTools.nip44 is available, use it directly. - - Otherwise embed the existing lightweight codec adapted from [packages/auth/src/utils/nip44.ts](packages/auth/src/utils/nip44.ts) as [Nip44](lite/nostr-login-lite.js:1). - -Compatibility requirements -- Provide the same exports: [init(opts)](lite/nostr-login-lite.js:1), [launch(startScreen)](lite/nostr-login-lite.js:1), [logout()](lite/nostr-login-lite.js:1), [setDarkMode(dark)](lite/nostr-login-lite.js:1), [setAuth(o)](lite/nostr-login-lite.js:1), [cancelNeedAuth()](lite/nostr-login-lite.js:1). -- Dispatch identical events and payload shapes as in [onAuth()](packages/auth/src/modules/AuthNostrService.ts:347). - -Architecture overview -- NostrLite: window.nostr facade mirroring current behavior, invokes auth UI when needed. -- Auth: manages methods (connect/extension/local/readOnly/otp), state, storage, event dispatch. -- NIP46Client: minimal RPC over [NostrTools.SimplePool](lite/nostr-login-lite.js:1) (subscribe, send request, parse/decrypt, dedupe auth_url). -- ExtensionBridge: safely handle window.nostr detection, guard against overwrites, switch to extension mode when requested. -- Store: localStorage helpers for accounts/current/recents and misc values. -- UI: single vanilla modal that lists options and drives flow, with optional inline iframe starter for providers that publish iframe_url. - -Function-level TODO checklist (execution order) - -Bootstrap and API surface -- [ ] [Deps.ensureNostrToolsLoaded()](lite/nostr-login-lite.js:1) - - Verify window.NostrTools presence; throw with actionable message if missing. - -- [ ] [NostrLite.init(options: NostrLoginOptions)](lite/nostr-login-lite.js:1) - - Call [Deps.ensureNostrToolsLoaded()](lite/nostr-login-lite.js:1). - - Bind window.nostr to the facade. - - Initialize ExtensionBridge checking loop. - - Mount modal UI, persist options (theme, perms, bunkers, methods, otp URLs, default relays). - - Wire nlLaunch/nlLogout/nlDarkMode/nlSetAuth listeners. - -- [ ] [NostrLite.launch(startScreen?: string)](lite/nostr-login-lite.js:1) - - Open modal with selected start screen or switch-account if accounts exist. - -- [ ] [NostrLite.logout()](lite/nostr-login-lite.js:1) - - Clear current account; dispatch nlAuth logout; reset signer/client state. - -- [ ] [NostrLite.setDarkMode(dark: boolean)](lite/nostr-login-lite.js:1) - - Persist and apply theme to modal. - -- [ ] [NostrLite.setAuth(o: NostrLoginAuthOptions)](lite/nostr-login-lite.js:1) - - Validate o.type in {login, signup, logout}; o.method in {connect, extension, local, otp, readOnly}. - - Delegate to [Auth.switchAccount()](lite/nostr-login-lite.js:1); dispatch consistent nlAuth. - -- [ ] [NostrLite.cancelNeedAuth()](lite/nostr-login-lite.js:1) - - Cancel current connect/listen flow and close modal section if waiting. - -window.nostr facade -- [ ] [NostrLite.ensureAuth()](lite/nostr-login-lite.js:1) - - If no user, open modal; await until authenticated or rejected. - -- [ ] [NostrLite.getPublicKey()](lite/nostr-login-lite.js:1) - - Ensure auth, return current pubkey or throw. - -- [ ] [NostrLite.signEvent(event: NostrEvent)](lite/nostr-login-lite.js:1) - - Ensure auth; if local key then sign locally via [NostrTools.finalizeEvent()](lite/nostr-login-lite.js:1); else sign via [NIP46Client.sendRequest()](lite/nostr-login-lite.js:1). - -- [ ] [NostrLite.nip04.encrypt(pubkey, plaintext)](lite/nostr-login-lite.js:1) -- [ ] [NostrLite.nip04.decrypt(pubkey, ciphertext)](lite/nostr-login-lite.js:1) - - Ensure auth; route to local ([NostrTools.nip04](lite/nostr-login-lite.js:1)) or remote signer via NIP-46 nip04_{encrypt|decrypt}. - -- [ ] [NostrLite.nip44.encrypt(pubkey, plaintext)](lite/nostr-login-lite.js:1) -- [ ] [NostrLite.nip44.decrypt(pubkey, ciphertext)](lite/nostr-login-lite.js:1) - - Ensure auth; use window.NostrTools.nip44 if present or local [Nip44](lite/nostr-login-lite.js:1); remote via nip44_{encrypt|decrypt}. - -Auth module -- [ ] [Auth.startAuthSession()](lite/nostr-login-lite.js:1) - - Create a promise used by ensureAuth/waitReady; allows Connect flow to resolve or be cancelled. - -- [ ] [Auth.endAuthSession()](lite/nostr-login-lite.js:1) - - Resolve session; if iframeUrl present, bind iframe port to NIP46Client before resolving. - -- [ ] [Auth.resetAuthSession()](lite/nostr-login-lite.js:1) - - Cancel current session safely. - -- [ ] [Auth.onAuth(type: "login" | "signup" | "logout", info?: Info)](lite/nostr-login-lite.js:1) - - Update state, persist, dispatch nlAuth; fetch profile asynchronously and update name/picture when fetched; preserve nip05 semantics. - -- [ ] [Auth.switchAccount(info: Info, signup = false)](lite/nostr-login-lite.js:1) - - Branch to [Auth.setReadOnly()](lite/nostr-login-lite.js:1)/[Auth.setOTP()](lite/nostr-login-lite.js:1)/[Auth.setLocal()](lite/nostr-login-lite.js:1)/[Auth.trySetExtensionForPubkey()](lite/nostr-login-lite.js:1)/[Auth.setConnect()](lite/nostr-login-lite.js:1). - -- [ ] [Auth.setReadOnly(pubkey: string)](lite/nostr-login-lite.js:1) - -- [ ] [Auth.setOTP(pubkey: string, data: string)](lite/nostr-login-lite.js:1) - -- [ ] [Auth.localSignup(name: string, sk?: string)](lite/nostr-login-lite.js:1) - - Generate sk via [NostrTools.generateSecretKey()](lite/nostr-login-lite.js:1)/[generatePrivateKey()](lite/nostr-login-lite.js:1) if missing; [Auth.setLocal(signup=true)](lite/nostr-login-lite.js:1). - -- [ ] [Auth.setLocal(info: Info, signup?: boolean)](lite/nostr-login-lite.js:1) - - Instantiate [LocalSigner](lite/nostr-login-lite.js:1); call [Auth.onAuth()](lite/nostr-login-lite.js:1). - -- [ ] [Auth.trySetExtensionForPubkey(pubkey: string)](lite/nostr-login-lite.js:1) - - Use [ExtensionBridge.setExtensionReadPubkey()](lite/nostr-login-lite.js:1) and reconcile. - -- [ ] [Auth.setConnect(info: Info)](lite/nostr-login-lite.js:1) - - Initialize NIP46Client with existing token/relays via [NIP46Client.init()](lite/nostr-login-lite.js:1) and [NIP46Client.connect()](lite/nostr-login-lite.js:1); call [Auth.onAuth()](lite/nostr-login-lite.js:1); [Auth.endAuthSession()](lite/nostr-login-lite.js:1). - -- [ ] [Auth.authNip46(type, { name, bunkerUrl, sk, domain, iframeUrl })](lite/nostr-login-lite.js:1) - - Parse bunkerUrl/nip05; [NIP46Client.init()](lite/nostr-login-lite.js:1) + [NIP46Client.connect()](lite/nostr-login-lite.js:1); [Auth.onAuth()](lite/nostr-login-lite.js:1). - -- [ ] [Auth.nostrConnect(relay?: string, opts?: { domain?: string; link?: string; importConnect?: boolean; iframeUrl?: string })](lite/nostr-login-lite.js:1) - - Create local keypair and secret; open provider link or show iframe starter; [NIP46Client.listen()](lite/nostr-login-lite.js:1) to learn signerPubkey, then [NIP46Client.initUserPubkey()](lite/nostr-login-lite.js:1); set bunkerUrl; [Auth.onAuth()](lite/nostr-login-lite.js:1) unless importConnect. - -- [ ] [Auth.createNostrConnect(relay?: string)](lite/nostr-login-lite.js:1) - - Build nostrconnect:// URL with meta (icon/url/name/perms). - -- [ ] [Auth.getNostrConnectServices(): Promise<[string, ConnectionString[]]>](lite/nostr-login-lite.js:1) - - Return nostrconnect URL and preconfigured providers; query .well-known/nostr.json for relays and iframe_url. - -- [ ] [Auth.importAndConnect(cs: ConnectionString)](lite/nostr-login-lite.js:1) - - nostrConnect(..., importConnect=true) → logout keep signer → onAuth(login, connect info). - -- [ ] [Auth.createAccount(nip05: string)](lite/nostr-login-lite.js:1) (optional parity) - - Use bunker provider to create account; return bunkerUrl and sk. - -NIP46Client (transport over NostrTools.SimplePool) -- [ ] [NIP46Client.init(localSk: string, remotePubkey?: string, relays: string[], iframeOrigin?: string)](lite/nostr-login-lite.js:1) - - Create [this.pool = new NostrTools.SimplePool()](lite/nostr-login-lite.js:1). - - Cache relays; initialize local signer state (seckey, pubkey via [NostrTools.getPublicKey()](lite/nostr-login-lite.js:1)). - - If remotePubkey provided, set it; cache iframeOrigin. - -- [ ] [NIP46Client.setUseNip44(use: boolean)](lite/nostr-login-lite.js:1) - -- [ ] [NIP46Client.subscribeReplies()](lite/nostr-login-lite.js:1) - - sub = pool.sub(relays, [{ kinds:[24133], '#p':[localPubkey] }]) - - sub.on('event', (ev) => [NIP46Client.onEvent(ev)](lite/nostr-login-lite.js:1)); sub.on('eose', () => {/* keep alive */}) - -- [ ] [NIP46Client.onEvent(ev: NostrEvent)](lite/nostr-login-lite.js:1) - - Parse/decrypt via [NIP46Client.parseEvent()](lite/nostr-login-lite.js:1); route to response handlers. - -- [ ] [NIP46Client.listen(nostrConnectSecret: string): Promise](lite/nostr-login-lite.js:1) - - Await unsolicited reply to local pubkey; accept "ack" or exact secret; return signer’s pubkey; unsubscribe this one-shot subscription. - -- [ ] [NIP46Client.connect(token?: string, perms?: string)](lite/nostr-login-lite.js:1) - - [NIP46Client.sendRequest()](lite/nostr-login-lite.js:1) with method "connect" and params [userPubkey, token||'', perms||'']; resolve on ack. - -- [ ] [NIP46Client.initUserPubkey(hint?: string): Promise](lite/nostr-login-lite.js:1) - - If hint present, set and return; else call "get_public_key" RPC and store result. - -- [ ] [NIP46Client.sendRequest(remotePubkey: string, method: string, params: string[], kind = 24133, cb?: (res) => void)](lite/nostr-login-lite.js:1) - - id = random string - - ev = [NIP46Client.createRequestEvent(id, remotePubkey, method, params, kind)](lite/nostr-login-lite.js:1) - - pool.publish(relays, ev) - - [NIP46Client.setResponseHandler(id, cb)](lite/nostr-login-lite.js:1) - -- [ ] [NIP46Client.createRequestEvent(id, remotePubkey, method, params, kind)](lite/nostr-login-lite.js:1) - - content = JSON.stringify({ id, method, params }) - - encrypt content using nip44 unless method==='create_account', otherwise nip04 fallback - - tags: [ ['p', remotePubkey] ] - - sign via [NostrTools.finalizeEvent()](lite/nostr-login-lite.js:1) - - return event object - -- [ ] [NIP46Client.parseEvent(event)](lite/nostr-login-lite.js:1) - - Detect nip04 vs nip44 by ciphertext shape; decrypt using local seckey and remote pubkey (nip04 or [Nip44](lite/nostr-login-lite.js:1)/window.NostrTools.nip44). - - Return { id, method, params, event } or { id, result, error, event }. - -- [ ] [NIP46Client.setResponseHandler(id, cb)](lite/nostr-login-lite.js:1) - - Deduplicate 'auth_url' emissions; ensure only one resolution per id; log elapsed; cleanup map entries. - -- [ ] [NIP46Client.setWorkerIframePort(port: MessagePort)](lite/nostr-login-lite.js:1) - - When iframe is present, forward signed events via postMessage and map request id↔event.id; send keepalive pings. - -- [ ] [NIP46Client.teardown()](lite/nostr-login-lite.js:1) - - Unsubscribe; clear timers/ports; pool.close(relays). - -Iframe handshake -- [ ] [IframeReadyListener.start(messages: string[], origin: string)](lite/nostr-login-lite.js:1) - - Listen for ["workerReady","workerError"] and ["starterDone","starterError"]; origin-check by host or subdomain. - -- [ ] [IframeReadyListener.wait(): Promise](lite/nostr-login-lite.js:1) - -ExtensionBridge -- [ ] [ExtensionBridge.startChecking(nostrLite: NostrLite)](lite/nostr-login-lite.js:1) - - Poll window.nostr until found; then call [ExtensionBridge.initExtension()](lite/nostr-login-lite.js:1) once; retry after a delay to capture last extension. - -- [ ] [ExtensionBridge.initExtension(nostrLite: NostrLite, lastTry?: boolean)](lite/nostr-login-lite.js:1) - - Cache extension, reassign window.nostr to nostrLite; if currently authed as extension, reconcile; schedule a final late check. - -- [ ] [ExtensionBridge.setExtensionReadPubkey(expectedPubkey?: string)](lite/nostr-login-lite.js:1) - - Temporarily set window.nostr = extension; read pubkey; compare to expected; emit extensionLogin/extensionLogout. - -- [ ] [ExtensionBridge.trySetForPubkey(expectedPubkey: string)](lite/nostr-login-lite.js:1) -- [ ] [ExtensionBridge.setExtension()](lite/nostr-login-lite.js:1) -- [ ] [ExtensionBridge.unset(nostrLite: NostrLite)](lite/nostr-login-lite.js:1) -- [ ] [ExtensionBridge.hasExtension(): boolean](lite/nostr-login-lite.js:1) - -Local signer (wrapping window.NostrTools) -- [ ] [LocalSigner.constructor(sk: string)](lite/nostr-login-lite.js:1) - - Cache public key on construct via [NostrTools.getPublicKey()](lite/nostr-login-lite.js:1). - -- [ ] [LocalSigner.pubkey(): string](lite/nostr-login-lite.js:1) - -- [ ] [LocalSigner.sign(event: NostrEvent): Promise](lite/nostr-login-lite.js:1) - - Use [NostrTools.finalizeEvent()](lite/nostr-login-lite.js:1), set id/sig/pubkey. - -- [ ] [LocalSigner.encrypt04(pubkey: string, plaintext: string): Promise](lite/nostr-login-lite.js:1) - - Use [NostrTools.nip04.encrypt()](lite/nostr-login-lite.js:1). - -- [ ] [LocalSigner.decrypt04(pubkey: string, ciphertext: string): Promise](lite/nostr-login-lite.js:1) - - Use [NostrTools.nip04.decrypt()](lite/nostr-login-lite.js:1). - -- [ ] [LocalSigner.encrypt44(pubkey: string, plaintext: string): Promise](lite/nostr-login-lite.js:1) - - Use window.NostrTools.nip44 if available, else [Nip44.encrypt()](lite/nostr-login-lite.js:1). - -- [ ] [LocalSigner.decrypt44(pubkey: string, ciphertext: string): Promise](lite/nostr-login-lite.js:1) - - Use window.NostrTools.nip44 if available, else [Nip44.decrypt()](lite/nostr-login-lite.js:1). - -Store (localStorage helpers) -- [ ] [Store.addAccount(info: Info)](lite/nostr-login-lite.js:1) -- [ ] [Store.removeCurrentAccount()](lite/nostr-login-lite.js:1) -- [ ] [Store.getCurrent(): Info | null](lite/nostr-login-lite.js:1) -- [ ] [Store.getAccounts(): Info[]](lite/nostr-login-lite.js:1) -- [ ] [Store.getRecents(): Info[]](lite/nostr-login-lite.js:1) -- [ ] [Store.setItem(key: string, value: string)](lite/nostr-login-lite.js:1) -- [ ] [Store.getIcon(): Promise](lite/nostr-login-lite.js:1) - -UI (single modal) -- [ ] [Modal.init(options)](lite/nostr-login-lite.js:1) - - Create modal container; inject minimal CSS; set theme and RTL if required. - -- [ ] [Modal.open(opts: { startScreen?: string })](lite/nostr-login-lite.js:1) - - Render options: Connect (with provider list/QR), Extension, Local (Create/Import), Read-only, OTP (if server URLs configured), Switch Account if prior accounts. - -- [ ] [Modal.close()](lite/nostr-login-lite.js:1) - -- [ ] [Modal.showAuthUrl(url: string)](lite/nostr-login-lite.js:1) - - For connect OAuth-like prompt; present link/QR; if iframeUrl is used, show embedded iframe. - -- [ ] [Modal.showIframeUrl(url: string)](lite/nostr-login-lite.js:1) - -- [ ] [Modal.onSwitchAccount(info: Info)](lite/nostr-login-lite.js:1) - -- [ ] [Modal.onLogoutConfirm()](lite/nostr-login-lite.js:1) - -- [ ] [Modal.onImportConnectionString(cs: ConnectionString)](lite/nostr-login-lite.js:1) - - Import-and-connect flow: calls [Auth.importAndConnect()](lite/nostr-login-lite.js:1). - -Event bus -- [ ] [Bus.on(event: string, handler: Function)](lite/nostr-login-lite.js:1) -- [ ] [Bus.off(event: string, handler: Function)](lite/nostr-login-lite.js:1) -- [ ] [Bus.emit(event: string, payload?: any)](lite/nostr-login-lite.js:1) - -Relay configuration helpers -- [ ] [Relays.getDefaultRelays(options): string[]](lite/nostr-login-lite.js:1) - - From options or sensible defaults. - -- [ ] [Relays.normalize(relays: string[]): string[]](lite/nostr-login-lite.js:1) - - Ensure proper wss:// and deduping. - -Parity acceptance criteria -- Same external API names and events exported as current initializer: [init](packages/auth/src/index.ts:333), [launch](packages/auth/src/index.ts:333), [logout](packages/auth/src/index.ts:333), [setDarkMode](packages/auth/src/index.ts:333), [setAuth](packages/auth/src/index.ts:333), [cancelNeedAuth](packages/auth/src/index.ts:333). -- Same nlAuth payload shape as [onAuth()](packages/auth/src/modules/AuthNostrService.ts:347-418). -- window.nostr behavior matches [class Nostr](packages/auth/src/modules/Nostr.ts:23). - -Notes and implementation tips -- Load order: [Deps.ensureNostrToolsLoaded()](lite/nostr-login-lite.js:1) must guard all usages of window.NostrTools. -- Request de-duplication: mirror [setResponseHandler()](packages/auth/src/modules/Nip46.ts:150-173) behavior to avoid auth_url flooding. -- NIP-44 selection: use nip44 for all methods except "create_account". -- Iframe origin checks: follow [ReadyListener](packages/auth/src/modules/Nip46.ts:291-338) host/subdomain verification. -- Secret handling in nostrconnect: accept 'ack' or exact secret; see [listen](packages/auth/src/modules/Nip46.ts:71-107). -- Profile fetch is optional; keep it async and non-blocking, update UI/state when complete. - -Out of scope for initial lite version -- Complex banners/popups and multi-window flows. -- Full NDK feature parity beyond the minimum for NIP-46 RPC. -- Advanced error telemetry; keep console logs minimal. - -Deliverables -- Single distributable [lite/nostr-login-lite.js](lite/nostr-login-lite.js) usable via: - - with window.nostr present after [init()](lite/nostr-login-lite.js:1). - - Optional ESM import with same API. -- Minimal HTML example showing each auth method path is functional. \ No newline at end of file diff --git a/README.md b/README.md index 6ab1ac5..1d03f47 100644 --- a/README.md +++ b/README.md @@ -1,167 +1,2 @@ Nostr_Login_Lite =========== - -This library is a powerful `window.nostr` provider. - -``` - -``` - -Just add the above script to your HTML and -get a nice UI for users to login with Nostr Connect (nip46), with an extension, read-only login, -account switching, OAuth-like sign up, etc. Your app just talks to the `window.nostr`, the rest is handled by `nostr-login`. - -See it in action on [nostr.band](https://nostr.band). - -## Options - -You can set these attributes to the `script` tag to customize the behavior: -- `data-dark-mode` - `true`/`false`, default will use the browser's color theme -- `data-bunkers` - the comma-separated list of domain names of Nostr Connect (nip46) providers for sign up, i.e. `nsec.app,highlighter.com` -- `data-perms` - the comma-separated list of [permissions](https://github.com/nostr-protocol/nips/blob/master/46.md#requested-permissions) requested by the app over Nostr Connect, i.e. `sign_event:1,nip04_encrypt` -- `data-theme` - color themes, one of `default`, `ocean`, `lemonade`, `purple` -- `data-no-banner` - if `true`, do not show the `nostr-login` banner, will need to launch the modals using event dispatch, see below -- `data-methods` - comma-separated list of allowed auth methods, method names: `connect`, `extension`, `readOnly`, `local`, all allowed by default. -- `data-otp-request-url` - URL for requesting OTP code -- `data-otp-reply-url` - URL for replying with OTP code -- `data-title` - title for the welcome screen -- `data-description` - description for the welcome screen -- `data-start-screen` - screen shown by default (banner click, window.nostr.* call), options: `welcome`, `welcome-login`, `welcome-signup`, `signup`, `local-signup`, `login`, `otp`, `connect`, `login-bunker-url`, `login-read-only`, `connection-string`, `switch-account`, `import` -- `data-signup-relays` - comma-separated list of relays where nip65 event will be published on local signup -- `data-outbox-relays` - comma-separated list of relays that will be added to nip65 event on local signup -- `data-signup-nstart` - "true" to use start.njump.me instead of local signup -- `data-follow-npubs` - comma-separated list of npubs to follow if njump.me signup is used - -Example: -``` - -``` - -## Updating the UI - -Whenever user performs an auth-related action using `nostr-login`, a `nlAuth` event will be dispatched on the `document`, which you can listen -to in order to update your UI (show user profile, etc): - -``` -document.addEventListener('nlAuth', (e) => { - // type is login, signup or logout - if (e.detail.type === 'login' || e.detail.type === 'signup') { - onLogin(); // get pubkey with window.nostr and show user profile - } else { - onLogout() // clear local user data, hide profile info - } -}) -``` - -## Launching, logout, etc - -The `nostr-login` auth modals will be automatically launched whenever you -make a call to `window.nostr` if user isn't authed yet. However, you can also launch the auth flow by dispatching a custom `nlLaunch` event: - -``` -document.dispatchEvent(new CustomEvent('nlLaunch', { detail: 'welcome' })); -``` - -The `detail` event payload can be empty, or can be one of `welcome`, `signup`, `login`, `login-bunker-url`, `login-read-only`, `switch-account`. - -To trigger logout in the `nostr-login`, you can dispatch a `nlLogout` event: - -``` -document.dispatchEvent(new Event("nlLogout")); -``` - -To change dark mode in the `nostr-login`, you can dispatch a `nlDarkMode` event, with detail as `darkMode` boolean: - -``` -document.dispatchEvent(new CustomEvent("nlDarkMode", { detail: true })); -``` - -## Use as a package - -Install `nostr-login` package with `npm` and then: - -``` -import { init as initNostrLogin } from "nostr-login" - -// make sure this is called before any -// window.nostr calls are made -initNostrLogin({/*options*/}) - -``` - -Now the `window.nostr` will be initialized and on your first call -to it the auth flow will be launched if user isn't authed yet. - -You can also launch the auth flow yourself: - -``` -import { launch as launchNostrLoginDialog } from "nostr-login" - -// make sure init() was called - -// on your signup button click -function onSignupClick() { - // launch signup screen - launchNostrLoginDialog({ - startScreen: 'signup' - }) -} -``` - -### Next.js Fix for Server Side Rendering (SSR) - -`nostr-login` calls `document` which is unavailable for server-side rendering. You will have build errors. To fix this, you can import `nostr-login` on the client side in your component with a `useEffect` like this: - -```javascript - useEffect(() => { - import('nostr-login') - .then(async ({ init }) => { - init({ - // options - }) - }) - .catch((error) => console.log('Failed to load nostr-login', error)); - }, []); -``` -Note: even if your component has `"use client"` in the first line, this fix still may be necessary. - ---- - -API: -- `init(opts)` - set mapping of window.nostr to nostr-login -- `launch(startScreen)` - launch nostr-login UI -- `logout()` - drop the current nip46 connection - -Options: -- `theme` - same as `data-theme` above -- `startScreen` - same as `startScreen` for `nlLaunch` event above -- `bunkers` - same as `data-bunkers` above -- `devOverrideBunkerOrigin` - for testing, overrides the bunker origin for local setup -- `onAuth: (npub: string, options: NostrLoginAuthOptions)` - a callback to provide instead of listening to `nlAuth` event -- `perms` - same as `data-perms` above -- `darkMode` - same as `data-dark-mode` above -- `noBanner` - same as `data-no-banner` above -- `isSignInWithExtension` - `true` to bring the *Sign in with exception* button into main list of options, `false` to hide to the *Advanced*, default will behave as `true` if extension is detected. - -## OTP login - -If you supply both `data-otp-request-url` and `data-otp-reply-url` then "Login with DM" button will appear on the welcome screen. - -When user enters their nip05 or npub, a GET request is made to `[?&]pubkey=`. Server should send -a DM with one-time code to that pubkey and should return 200. - -After user enters the code, a GET request is made to `[?&]pubkey=&code=`. Server should check that code matches the pubkey and hasn't expired, and should return 200 status and an optional payload. Nostr-login will deliver the payload as `otpData` field in `nlAuth` event, and will save the payload in localstore and will deliver it again as `nlAuth` on page reload. - -The reply payload may be used to supply the session token. If token is sent by the server as a cookie then payload might be empty, otherwise the payload should be used by the app to extract the token and use it in future API calls to the server. - -## Examples - -* [Basic HTML Example](./examples/usage.html) - -## TODO - -- fetch bunker list using NIP-89 -- Amber support -- allow use without the UIs -- add timeout handling -- more at [issues](https://github.com/nostrband/nostr-login/issues) diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..a9fed21 --- /dev/null +++ b/examples/README.md @@ -0,0 +1,50 @@ +# NOSTR_LOGIN_LITE Examples + +This directory contains examples and tests for NOSTR_LOGIN_LITE using the local bundle setup. + +## Files + +### 🔬 comprehensive-test.html +**The main diagnostic and testing tool** +- Comprehensive test suite with extensive debugging output +- Tests all library functions, dependencies, crypto, storage, etc. +- Results displayed on webpage for easy copying and debugging +- Run this when you need to diagnose issues or verify functionality + +### 📱 simple-demo.html +Basic demonstration of NOSTR_LOGIN_LITE integration +- Minimal setup example +- Good starting point for new implementations + +### 🎨 modal-login-demo.html +Demonstrates modal-based login flow +- Shows how to trigger and handle the login modal +- Example of auth event handling + +### 👤 login-and-profile.html +Login and user profile demonstration +- Shows authentication flow +- Displays user profile information after login + +### 🔗 nip46-bunker-demo.html +NIP-46 remote signing demonstration +- Shows how to connect to remote signers/bunkers +- Advanced use case example + +## Usage + +1. Start a local web server (e.g., `python -m http.server 5501` or Live Server in VS Code) +2. Navigate to any HTML file +3. For comprehensive testing and debugging, use `comprehensive-test.html` + +All examples use the local bundle setup with two files: +1. `../lite/nostr.bundle.js` - Official nostr-tools bundle +2. `../lite/nostr-lite.js` - NOSTR_LOGIN_LITE library with embedded NIP-46 extension + +## Architecture Update (2025-09-13) + +The library has been simplified from a three-file to a two-file architecture: +- ✅ **Before:** `nostr.bundle.js` + `nip46-extension.js` + `nostr-lite.js` +- ✅ **Now:** `nostr.bundle.js` + `nostr-lite.js` (with embedded NIP-46) + +All functionality remains identical - NIP-46 remote signing, all auth methods, and full compatibility are preserved. \ No newline at end of file diff --git a/examples/comprehensive-test.html b/examples/comprehensive-test.html new file mode 100644 index 0000000..c468e72 --- /dev/null +++ b/examples/comprehensive-test.html @@ -0,0 +1,1134 @@ + + + + + + 🔬 NOSTR_LOGIN_LITE Comprehensive Test & Debug + + + +
+

🔬 NOSTR_LOGIN_LITE Comprehensive Test

+ +
+

Test Controls

+ + + + +
+ +
+
+

Test Environment

+
Loading...
+
+
+

Bundle Status

+
Checking...
+
+
+

Window.nostr

+
Checking...
+
+
+

Current User

+
None
+
+
+ +
+
+

+ + 📚 Dependencies +

+
Testing dependencies...
+ +
+ +
+

+ + 🔌 Extension Detection +

+
Extension detection pending...
+ + +
+ +
+

+ + ⚙️ Initialization +

+
Ready to initialize...
+ +
+ +
+

+ + 🔐 API Tests +

+
API tests pending...
+ + +
+ +
+

+ + 🎨 Modal & UI +

+ + + +
+ +
+

+ + 🔒 Cryptography +

+
Crypto tests pending...
+ +
+ +
+

+ + 💾 Storage & State +

+
Storage tests pending...
+ +
+
+ +
+

+ 📊 Complete Debug Output + +

+
+
[${new Date().toLocaleTimeString()}]
Debug output will appear here... + + Click "Run All Tests" to begin comprehensive testing. + All results will be displayed here for easy copying and debugging. +
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/examples/login-and-profile.html b/examples/login-and-profile.html new file mode 100644 index 0000000..fd5a47f --- /dev/null +++ b/examples/login-and-profile.html @@ -0,0 +1,459 @@ + + + + + + 🔐 NOSTR_LOGIN_LITE - All Login Methods Test + + + +
+

🔐 NOSTR_LOGIN_LITE - All Login Methods Test

+ +
+ ⏳ Initializing NOSTR_LOGIN_LITE... +
+ +
+ +

+ Click to open the NOSTR_LOGIN_LITE modal and test all available login methods: +

+ +
+

Available Login Methods

+
    +
  • Browser Extension: Alby, nos2x, etc. (if installed)
  • +
  • Local Key: Generate new keys or import existing private key/nsec
  • +
  • Read Only: Access public content without authentication
  • +
  • Nostr Connect (NIP-46): Connect to remote signing services
  • +
  • DM/OTP: Secure local accounts with one-time passwords
  • +
+
+
+ + + +
+
+ [Console] Ready for testing +
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/examples/minimal-test-remote.html b/examples/minimal-test-remote.html deleted file mode 100644 index 4592147..0000000 --- a/examples/minimal-test-remote.html +++ /dev/null @@ -1,121 +0,0 @@ - - - - - - Minimal Nostr Login Test (Remote) - - - - - - - diff --git a/examples/minimal-test.html b/examples/minimal-test.html deleted file mode 100644 index 047b61a..0000000 --- a/examples/minimal-test.html +++ /dev/null @@ -1,121 +0,0 @@ - - - - - - Minimal Nostr Login Test - - - - - - - diff --git a/examples/modal-login-demo.html b/examples/modal-login-demo.html new file mode 100644 index 0000000..07c5a11 --- /dev/null +++ b/examples/modal-login-demo.html @@ -0,0 +1,411 @@ + + + + + + 🔐 NOSTR_LOGIN_LITE - Full Modal Login Demo + + + +
+

🔐 NOSTR_LOGIN_LITE Full Modal Login Demo

+ +
+

📚 Available Login Methods

+

This demo showcases all login methods provided by NOSTR_LOGIN_LITE:

+ +
+
+
📱
+

Extension Login

+

Use browser extensions like Alby, nos2x, or other Nostr-compatible extensions

+
+
+
💾
+

Local Account

+

Create and manage local Nostr keypairs stored in browser storage

+
+
+
👁️
+

Read-Only Account

+

Access public content without authentication (limited functionality)

+
+
+
🔗
+

NIP-46 Remote

+

Connect to remote signers for secure key management

+
+
+
🔐
+

OTP Backup

+

Secure local accounts with time-based one-time passwords

+
+
+
+ + +
+

⚙️ Library Status

+
Loading nostr-tools...
+
Loading NOSTR_LOGIN_LITE...
+
+ + +
+

🎯 Launch Full Login Modal

+

Click the button below to launch the complete authentication modal with all available login options:

+ + +
Ready to authenticate...
+
+ The modal will show all available login methods based on your browser setup and library configuration. +
+
+ + + + + +
+
+ [Demo] Modal Login Demo initialized +
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/examples/rtl-test.html b/examples/rtl-test.html deleted file mode 100644 index 462d6de..0000000 --- a/examples/rtl-test.html +++ /dev/null @@ -1,838 +0,0 @@ - - - - - - من الجميل في نوستر هي قدرة… - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- -
- - -
- - - -
- -
-
-
- -
-
-
-
-

- من الجميل في نوستر هي قدرة التطبيقات على - التخاطر.

إذا بتفضلوا استخدام - مساحة مثل الDiscord، ضيفوا صفحتنا على - flotilla.social للتواصل بصيغة التشات. -

اضغط إضافة مساحة Add Space،
ثم - الدخول على مساحة Join a space،
وضيفوا - ريلاي relay.nostrarabia.com

نراكم. - 🫡

#nostrarabia -

-
- - - - -
-

- من الجميل في نوستر هي قدرة… -

-
- -
- - -
-
-
- -
-
- - - -
-
-
- - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - diff --git a/examples/test_options.html b/examples/test_options.html deleted file mode 100644 index 94cc0c8..0000000 --- a/examples/test_options.html +++ /dev/null @@ -1,343 +0,0 @@ - - - - - - Nostr Login Interactive Test - - - -
-

Nostr Login Interactive Test

- - -
-

Configuration Options

- -
- - -
- -
- - -
- -
- - -
- -
- -
- - - - -
-
- -
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
- - - - -
- Note: Configuration changes will be applied by reloading the page with new settings. -
-
- - -
-

Current Configuration:

-

-        
- - - -
- - - - - - - diff --git a/examples/usage.html b/examples/usage.html deleted file mode 100644 index 8154131..0000000 --- a/examples/usage.html +++ /dev/null @@ -1,135 +0,0 @@ - - - - - - Input and Output Fields - - - - -
-

Try Nostr-Login

- - - - - -
- - - - -
- -
- -
- - - -
- - - - - - diff --git a/lerna.json b/lerna.json deleted file mode 100644 index 6e6dfa6..0000000 --- a/lerna.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "$schema": "node_modules/lerna/schemas/lerna-schema.json", - "version": "1.0.1", - "npmClient": "npm" -} diff --git a/lite/build.js b/lite/build.js new file mode 100644 index 0000000..5eb186d --- /dev/null +++ b/lite/build.js @@ -0,0 +1,315 @@ +/** + * Simple script to create NOSTR_LOGIN_LITE bundle + * For the new two-file architecture: + * 1. nostr.bundle.js (official nostr-tools bundle - static file) + * 2. nip46-extension.js (NIP-46 extension - static file) + * 3. nostr-lite.js (NOSTR_LOGIN_LITE library - built by this script) + */ + +const fs = require('fs'); +const path = require('path'); + +function createNostrLoginLiteBundle() { + console.log('🔧 Creating NOSTR_LOGIN_LITE bundle for two-file architecture...'); + + const outputPath = path.join(__dirname, 'nostr-lite.js'); + + // Remove old bundle + try { + if (fs.existsSync(outputPath)) { + fs.unlinkSync(outputPath); + } + } catch (e) { + console.log('No old bundle to remove'); + } + + // Start with the bundle header + let bundle = `/** + * NOSTR_LOGIN_LITE - Authentication Library + * Two-file architecture: + * 1. Load nostr.bundle.js (official nostr-tools bundle) + * 2. Load nip46-extension.js (extends NostrTools with NIP-46) + * 3. Load nostr-lite.js (this file - NOSTR_LOGIN_LITE library) + * Generated on: ${new Date().toISOString()} + */ + +// Verify dependencies are loaded +if (typeof window !== 'undefined') { + if (!window.NostrTools) { + console.error('NOSTR_LOGIN_LITE: nostr.bundle.js must be loaded first'); + throw new Error('Missing dependency: nostr.bundle.js'); + } + + if (!window.NostrTools.nip46) { + console.error('NOSTR_LOGIN_LITE: nip46-extension.js must be loaded after nostr.bundle.js'); + throw new Error('Missing dependency: nip46-extension.js'); + } + + console.log('NOSTR_LOGIN_LITE: Dependencies verified ✓'); + console.log('NOSTR_LOGIN_LITE: NostrTools available with keys:', Object.keys(window.NostrTools)); + console.log('NOSTR_LOGIN_LITE: NIP-46 available:', !!window.NostrTools.nip46); +} + +// ====================================== +// NOSTR_LOGIN_LITE Components +// ====================================== + +`; + + // Add Modal UI + const modalPath = path.join(__dirname, 'ui/modal.js'); + if (fs.existsSync(modalPath)) { + console.log('📄 Adding Modal UI...'); + + let modalContent = fs.readFileSync(modalPath, 'utf8'); + + // Skip header comments + let lines = modalContent.split('\n'); + let contentStartIndex = 0; + + for (let i = 0; i < Math.min(15, lines.length); i++) { + const line = lines[i].trim(); + if (line.startsWith('/**') || line.startsWith('*') || + line.startsWith('/*') || line.startsWith('//')) { + contentStartIndex = i + 1; + } else if (line && !line.startsWith('*') && !line.startsWith('//')) { + break; + } + } + + if (contentStartIndex > 0) { + lines = lines.slice(contentStartIndex); + } + + bundle += `// ======================================\n`; + bundle += `// Modal UI Component\n`; + bundle += `// ======================================\n\n`; + bundle += lines.join('\n'); + bundle += '\n\n'; + } else { + console.warn('⚠️ Modal UI not found: ui/modal.js'); + } + + // Add main library code + console.log('📄 Adding Main Library...'); + bundle += ` +// ====================================== +// Main NOSTR_LOGIN_LITE Library +// ====================================== + +// Extension Bridge for managing browser extensions +class ExtensionBridge { + constructor() { + this.extensions = new Map(); + this.primaryExtension = null; + this._detectExtensions(); + } + + _detectExtensions() { + // Common extension locations + const locations = [ + { path: 'window.nostr', name: 'Generic' }, + { path: 'window.alby?.nostr', name: 'Alby' }, + { path: 'window.nos2x?.nostr', name: 'nos2x' }, + { path: 'window.flamingo?.nostr', name: 'Flamingo' }, + { path: 'window.getAlby?.nostr', name: 'Alby Legacy' }, + { path: 'window.mutiny?.nostr', name: 'Mutiny' } + ]; + + for (const location of locations) { + try { + const obj = eval(location.path); + if (obj && typeof obj.getPublicKey === 'function') { + this.extensions.set(location.name, { + name: location.name, + extension: obj, + constructor: obj.constructor?.name || 'Unknown' + }); + + if (!this.primaryExtension) { + this.primaryExtension = this.extensions.get(location.name); + } + } + } catch (e) { + // Extension not available + } + } + } + + getAllExtensions() { + return Array.from(this.extensions.values()); + } + + getExtensionCount() { + return this.extensions.size; + } +} + +// Main NostrLite class +class NostrLite { + constructor() { + this.options = {}; + this.extensionBridge = new ExtensionBridge(); + this.initialized = false; + } + + async init(options = {}) { + console.log('NOSTR_LOGIN_LITE: Initializing with options:', options); + + this.options = { + theme: 'light', + darkMode: false, + relays: ['wss://relay.damus.io', 'wss://nos.lol'], + methods: { + extension: true, + local: true, + readonly: true, + connect: false, + otp: false + }, + ...options + }; + + // Set up window.nostr facade if no extension detected + if (this.extensionBridge.getExtensionCount() === 0) { + this._setupWindowNostrFacade(); + } + + this.initialized = true; + console.log('NOSTR_LOGIN_LITE: Initialization complete'); + + return this; + } + + _setupWindowNostrFacade() { + if (typeof window !== 'undefined' && !window.nostr) { + window.nostr = new WindowNostr(this); + console.log('NOSTR_LOGIN_LITE: window.nostr facade installed'); + } + } + + launch(startScreen = 'login') { + console.log('NOSTR_LOGIN_LITE: Launching with screen:', startScreen); + + if (typeof Modal !== 'undefined') { + const modal = new Modal(this.options); + modal.open({ startScreen }); + } else { + console.error('NOSTR_LOGIN_LITE: Modal component not available'); + } + } + + logout() { + console.log('NOSTR_LOGIN_LITE: Logout called'); + + // Clear stored data + if (typeof localStorage !== 'undefined') { + localStorage.removeItem('nl_current'); + } + + // Dispatch logout event + if (typeof window !== 'undefined') { + window.dispatchEvent(new CustomEvent('nlLogout', { + detail: { timestamp: Date.now() } + })); + } + } +} + +// Window.nostr facade for when no extension is available +class WindowNostr { + constructor(nostrLite) { + this.nostrLite = nostrLite; + } + + async getPublicKey() { + throw new Error('Authentication required - use NOSTR_LOGIN_LITE.launch()'); + } + + async signEvent(event) { + throw new Error('Authentication required - use NOSTR_LOGIN_LITE.launch()'); + } + + async getRelays() { + throw new Error('Authentication required - use NOSTR_LOGIN_LITE.launch()'); + } + + get nip04() { + return { + async encrypt(pubkey, plaintext) { + throw new Error('Authentication required - use NOSTR_LOGIN_LITE.launch()'); + }, + async decrypt(pubkey, ciphertext) { + throw new Error('Authentication required - use NOSTR_LOGIN_LITE.launch()'); + } + }; + } + + get nip44() { + return { + async encrypt(pubkey, plaintext) { + throw new Error('Authentication required - use NOSTR_LOGIN_LITE.launch()'); + }, + async decrypt(pubkey, ciphertext) { + throw new Error('Authentication required - use NOSTR_LOGIN_LITE.launch()'); + } + }; + } +} + +// Initialize and export +if (typeof window !== 'undefined') { + const nostrLite = new NostrLite(); + + // Export main API + window.NOSTR_LOGIN_LITE = { + init: (options) => nostrLite.init(options), + launch: (startScreen) => nostrLite.launch(startScreen), + logout: () => nostrLite.logout(), + + // Expose for debugging + _extensionBridge: nostrLite.extensionBridge, + _instance: nostrLite + }; + + console.log('NOSTR_LOGIN_LITE: Library loaded and ready'); + console.log('NOSTR_LOGIN_LITE: Use window.NOSTR_LOGIN_LITE.init(options) to initialize'); + console.log('NOSTR_LOGIN_LITE: Detected', nostrLite.extensionBridge.getExtensionCount(), 'browser extensions'); +} else { + // Node.js environment + module.exports = { NostrLite }; +} +`; + + // Write the complete bundle + fs.writeFileSync(outputPath, bundle, 'utf8'); + + const sizeKB = (bundle.length / 1024).toFixed(2); + console.log(`\n✅ nostr-lite.js bundle created: ${outputPath}`); + console.log(`📏 Bundle size: ${sizeKB} KB`); + console.log(`📄 Total lines: ${bundle.split('\n').length}`); + + // Check what's included + const hasModal = bundle.includes('class Modal'); + const hasNostrLite = bundle.includes('NOSTR_LOGIN_LITE'); + + console.log('\n📋 Bundle contents:'); + console.log(` Modal UI: ${hasModal ? '✅ Included' : '❌ Missing'}`); + console.log(` NOSTR_LOGIN_LITE: ${hasNostrLite ? '✅ Included' : '❌ Missing'}`); + console.log(` Extension Bridge: ✅ Included`); + console.log(` Window.nostr facade: ✅ Included`); + + console.log('\n📋 Two-file architecture:'); + console.log(' 1. nostr.bundle.js (official nostr-tools - 220KB)'); + console.log(' 2. nip46-extension.js (NIP-46 support - ~15KB)'); + console.log(` 3. nostr-lite.js (NOSTR_LOGIN_LITE - ${sizeKB}KB)`); + + return bundle; +} + +// Run if called directly +if (typeof require !== 'undefined' && require.main === module) { + createNostrLoginLiteBundle(); +} + +module.exports = { createNostrLoginLiteBundle }; \ No newline at end of file diff --git a/lite/bundler-clean.js b/lite/bundler-clean.js deleted file mode 100644 index b7388c9..0000000 --- a/lite/bundler-clean.js +++ /dev/null @@ -1,97 +0,0 @@ -/** - * Clean bundler for NOSTR_LOGIN_LITE - * Removes problematic files and recreates bundle - */ - -const fs = require('fs'); -const path = require('path'); - -async function createCleanBundle() { - // First, remove the old bundle if it exists - const outputPath = path.join(__dirname, 'nostr-login-lite.bundle.js'); - try { - if (fs.existsSync(outputPath)) { - fs.unlinkSync(outputPath); - } - } catch (e) { - console.log('No old bundle to remove'); - } - - const mainFile = path.join(__dirname, 'nostr-login-lite.js'); - const nip46File = path.join(__dirname, 'core/nip46-client.js'); - const modalFile = path.join(__dirname, 'ui/modal.js'); - - // Start with a clean header - let bundle = `/** - * NOSTR_LOGIN_LITE - * Single-file Nostr authentication library - * Generated on: ${new Date().toISOString()} - */ - -`; - - // Add section markers and combine files - const files = [ - { path: modalFile, name: 'modal.js' }, - { path: nip46File, name: 'nip46-client.js' }, - { path: mainFile, name: 'nostr-login-lite.js' } - ]; - - for (const file of files) { - if (fs.existsSync(file.path)) { - const content = fs.readFileSync(file.path, 'utf8'); - - bundle += `\n// ======================================\n`; - bundle += `// ${file.name}\n`; - bundle += `// ======================================\n\n`; - - // Clean the content by removing initial header comments - let lines = content.split('\n'); - let contentStartIndex = 0; - - // Skip the first 10 lines if they contain file headers - for (let i = 0; i < Math.min(10, lines.length); i++) { - const line = lines[i].trim(); - if (line.startsWith('/**') || line.startsWith('*') || line.startsWith('/*') || line.startsWith('//') || - line.includes('Copyright') || line.includes('@license') || line.includes('Licensed') || line.includes('©')) { - contentStartIndex = i + 1; - } - } - - if (contentStartIndex > 0) { - lines = lines.slice(contentStartIndex); - } - - bundle += lines.join('\n'); - bundle += '\n\n'; - - console.log(`Added ${file.name}`); - } else { - console.warn(`File not found: ${file.path}`); - } - } - - // Write the bundled file - fs.writeFileSync(outputPath, bundle, 'utf8'); - - const sizeKB = (bundle.length / 1024).toFixed(2); - console.log(`\n✅ Clean bundle created: ${outputPath}`); - console.log(`📏 Bundle size: ${sizeKB} KB`); - console.log(`📄 Total lines: ${bundle.split('\n').length}`); - - // Verify the bundle starts correctly - const firstLines = bundle.split('\n').slice(0, 20).join('\n'); - console.log('\n📋 First 20 lines:'); - console.log(firstLines); - - return bundle; -} - -if (typeof module !== 'undefined' && module.exports) { - module.exports = { createCleanBundle }; -} - -// Run if called directly -if (typeof require !== 'undefined' && require.main === module) { - createCleanBundle().catch(console.error); -} \ No newline at end of file diff --git a/lite/bundler.js b/lite/bundler.js deleted file mode 100644 index 8069c05..0000000 --- a/lite/bundler.js +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Simple bundler for NOSTR_LOGIN_LITE - * Combines all files into a single distributable script - */ - -const fs = require('fs'); -const path = require('path'); - -async function bundleLite() { - const mainFile = path.join(__dirname, 'nostr-login-lite.js'); - const nip46File = path.join(__dirname, 'core/nip46-client.js'); - const modalFile = path.join(__dirname, 'ui/modal.js'); - - let bundle = `/** - * NOSTR_LOGIN_LITE - * Single-file Nostr authentication library - * Generated on: ${new Date().toISOString()} - */ - -// ====================================== -// Core Classes and Components -// ====================================== -`; - - // Read and combine files - const files = [modalFile, nip46File, mainFile]; - - for (const file of files) { - if (fs.existsSync(file)) { - let content = fs.readFileSync(file, 'utf8'); - - // Skip the initial comment and license if present - let lines = content.split('\n'); - - // Find and skip complete JSDoc blocks at the beginning - let skipUntil = 0; - let inJSDocBlock = false; - for (let i = 0; i < lines.length; i++) { - const line = lines[i].trim(); - - if (line.startsWith('/**')) { - inJSDocBlock = true; - skipUntil = i; - } else if (inJSDocBlock && line.startsWith('*/')) { - skipUntil = i; - break; - } else if (i < 10 && (line.startsWith('const') || line.startsWith('class') || line.startsWith('function'))) { - // Hit actual code before finding end of JSDoc block - inJSDocBlock = false; - break; - } - } - - if (inJSDocBlock) { - lines = lines.slice(skipUntil + 1); // Skip the entire JSDoc block - } else { - // Fallback to old filtering (skip comment-like lines in first 10) - lines = lines.filter((line, index) => { - return index >= 10 || !line.trim().startsWith('*') && !line.trim().startsWith('//'); - }); - } - - bundle += '\n// ======================================\n'; - bundle += `// ${path.basename(file)}\n`; - bundle += '// ======================================\n\n'; - bundle += lines.join('\n'); - bundle += '\n\n'; - } - } - - // Write the bundled file - const outputPath = path.join(__dirname, 'nostr-login-lite.bundle.js'); - fs.writeFileSync(outputPath, bundle); - - console.log('Bundle created:', outputPath); - console.log('Bundle size:', (bundle.length / 1024).toFixed(2), 'KB'); -} - -if (typeof module !== 'undefined' && module.exports) { - module.exports = { bundleLite }; -} - -// Run if called directly -if (typeof require !== 'undefined' && require.main === module) { - bundleLite().catch(console.error); -} \ No newline at end of file diff --git a/lite/core/nip46-client.js b/lite/core/nip46-client.js deleted file mode 100644 index 208f1c0..0000000 --- a/lite/core/nip46-client.js +++ /dev/null @@ -1,398 +0,0 @@ -/** - * NOSTR NIP-46 Client Implementation - * Minimal RPC over NostrTools.SimplePool for NOSTR_LOGIN_LITE - */ - -class NIP46Client { - constructor() { - this.pool = null; - this.localSk = null; - this.localPk = null; - this.remotePk = null; - this.relays = []; - this.sub = null; - this.pendingRequests = {}; - this.useNip44 = false; - this.iframeOrigin = null; - this.iframePort = null; - } - - init(localSk, remotePk, relays, iframeOrigin) { - // Create SimplePool - this.pool = new window.NostrTools.SimplePool(); - - // Setup keys - this.localSk = localSk; - if (this.localSk) { - this.localPk = window.NostrTools.getPublicKey(this.localSk); - } - - this.remotePk = remotePk; - this.relays = [...relays]; - - // Store iframe origin for future use - this.iframeOrigin = iframeOrigin; - - console.log('NIP46Client initialized for', this.remotePk ? 'remote signer' : 'listening mode'); - } - - setUseNip44(use) { - this.useNip44 = use; - } - - subscribeReplies() { - if (!this.pool || !this.localPk) return; - - // Subscribe to replies to our pubkey on kind 24133 (NIP-46 methods) - this.sub = this.pool.sub(this.relays, [{ - kinds: [24133], - '#p': [this.localPk] - }]); - - this.sub.on('event', (event) => this.onEvent(event)); - this.sub.on('eose', () => { - console.log('NIP-46 subscription caught up'); - }); - - console.log('Subscribed to NIP-46 replies on relays:', this.relays); - } - - unsubscribe() { - if (this.sub) { - this.sub.unsub(); - this.sub = null; - } - } - - async onEvent(event) { - console.log('NIP-46 event received:', event); - - try { - const parsed = await this.parseEvent(event); - if (parsed) { - if (parsed.id && this.pendingRequests[parsed.id]) { - // Handle response - const handler = this.pendingRequests[parsed.id]; - delete this.pendingRequests[parsed.id]; - - if (parsed.result !== undefined) { - handler.resolve(parsed.result); - } else if (parsed.error) { - handler.reject(new Error(parsed.error)); - } else { - handler.reject(new Error('Invalid response format')); - } - } else if (parsed.method === 'auth_url') { - // Handle auth_url emissions (deduplication required) - this.emitAuthUrlIfNeeded(parsed.params[0]); - } - } - } catch (error) { - console.error('Error processing NIP-46 event:', error); - } - } - - emitAuthUrlIfNeeded(url) { - // Deduplicate auth_url emissions - only emit if not recently shown - const lastUrl = sessionStorage.getItem('nl-last-auth-url'); - if (lastUrl === url) { - console.log('Auth URL already shown, skipping duplicate:', url); - return; - } - - sessionStorage.setItem('nl-last-auth-url', url); - console.log('New auth URL:', url); - - // Emit event for UI - window.dispatchEvent(new CustomEvent('nlAuthUrl', { detail: { url } })); - } - - async parseEvent(event) { - try { - let content = event.content; - - // Determine encryption method based on content structure - if (content.length > 44) { - // Likely NIP-44 (encrypted) - if (this.localSk && event.pubkey) { - try { - content = window.NostrTools.nip44?.decrypt(this.localSk, event.pubkey, content); - } catch (e) { - console.warn('NIP-44 decryption failed, trying NIP-04...'); - content = await window.NostrTools.nip04.decrypt(this.localSk, event.pubkey, content); - } - } - } else { - // Likely NIP-04 - if (this.localSk && event.pubkey) { - content = await window.NostrTools.nip04.decrypt(this.localSk, event.pubkey, content); - } - } - - const payload = JSON.parse(content); - console.log('Decrypted NIP-46 payload:', payload); - - return { - id: payload.id, - method: payload.method, - params: payload.params, - result: payload.result, - error: payload.error, - event: event - }; - - } catch (e) { - console.error('Failed to parse event:', e); - return null; - } - } - - async listen(nostrConnectSecret) { - return new Promise((resolve, reject) => { - if (!this.localPk) { - reject(new Error('No local pubkey available for listening')); - return; - } - - // Subscribe to unsolicited events to our pubkey - let foundSecretOrAck = false; - - const listenSub = this.pool.sub(this.relays, [{ - kinds: [24133], - '#p': [this.localPk] - }]); - - listenSub.on('event', async (event) => { - try { - const parsed = await this.parseEvent(event); - if (parsed && parsed.method === 'connect') { - // Accept if it's an ack or matches our secret - const [userPubkey, token] = parsed.params || []; - - if (token === '' && parsed.result === 'ack') { - // Ack received - foundSecretOrAck = true; - listenSub.unsub(); - resolve(event.pubkey); - } else if (token === nostrConnectSecret) { - // Secret match - foundSecretOrAck = true; - listenSub.unsub(); - resolve(event.pubkey); - } - } - } catch (error) { - console.error('Error in listen mode:', error); - } - }); - - // Timeout after 5 minutes - setTimeout(() => { - if (!foundSecretOrAck) { - listenSub.unsub(); - reject(new Error('Listen timeout - no signer connected')); - } - }, 300000); - }); - } - - async connect(token, perms) { - return new Promise(async (resolve, reject) => { - try { - const result = await this.sendRequest( - this.remotePk, - 'connect', - [this.localPk, token || '', perms || ''], - 24133, - (response) => { - if (response === 'ack') { - resolve(true); - } else { - reject(new Error('Connection not acknowledged')); - } - } - ); - - // Set 30 second timeout - setTimeout(() => reject(new Error('Connection timeout')), 30000); - - } catch (error) { - reject(error); - } - }); - } - - async initUserPubkey(hint) { - if (hint) { - this.remotePk = hint; - return hint; - } - - if (!this.remotePk) { - // Request get_public_key - return new Promise(async (resolve, reject) => { - try { - const pubkey = await this.sendRequest( - this.remotePk, - 'get_public_key', - [], - 24133 - ); - this.remotePk = pubkey; - resolve(pubkey); - } catch (error) { - reject(error); - } - }); - } - - return this.remotePk; - } - - async sendRequest(remotePubkey, method, params, kind = 24133, cb) { - if (!this.pool || !this.localSk || !this.localPk) { - throw new Error('NIP46Client not properly initialized'); - } - - if (!remotePubkey) { - throw new Error('No remote pubkey specified'); - } - - const id = this._generateId(); - - // Create request event - const event = await this.createRequestEvent(id, remotePubkey, method, params, kind); - - console.log('Sending NIP-46 request:', { id, method, params }); - - // Publish to relays - const pubs = await this.pool.publish(this.relays, event); - console.log('Published to relays, waiting for response...'); - - return new Promise((resolve, reject) => { - // Set timeout - const timeout = setTimeout(() => { - console.error('NIP-46 request timeout for id:', id); - delete this.pendingRequests[id]; - reject(new Error(`Request timeout for ${method}`)); - }, 60000); // 1 minute timeout - - // Store handler - this.pendingRequests[id] = { - resolve: (result) => { - clearTimeout(timeout); - resolve(result); - }, - reject: (error) => { - clearTimeout(timeout); - reject(error); - }, - timestamp: Date.now() - }; - - // If callback provided, override resolve - if (cb) { - const originalResolve = this.pendingRequests[id].resolve; - this.pendingRequests[id].resolve = (result) => { - cb(result); - originalResolve(result); - }; - } - }); - } - - async createRequestEvent(id, remotePubkey, method, params, kind = 24133) { - let content = JSON.stringify({ - id, - method, - params - }); - - // Choose encryption method - let encrypted = content; - if (method !== 'create_account') { - // Use NIP-44 for non-account creation methods if available - if (this.useNip44 && window.NostrTools.nip44) { - encrypted = window.NostrTools.nip44.encrypt(this.localSk, remotePubkey, content); - } else { - // Fallback to NIP-04 - encrypted = await window.NostrTools.nip04.encrypt(this.localSk, remotePubkey, content); - } - } - - // Create event structure - const event = { - kind: kind, - content: encrypted, - tags: [ - ['p', remotePubkey] - ], - created_at: Math.floor(Date.now() / 1000), - pubkey: this.localPk, - id: '', // Will be set by finalizeEvent - sig: '' // Will be set by finalizeEvent - }; - - // Sign the event - const signedEvent = window.NostrTools.finalizeEvent(event, this.localSk); - - return signedEvent; - } - - _generateId() { - return 'nl-' + Date.now() + '-' + Math.random().toString(36).substring(2, 15); - } - - setWorkerIframePort(port) { - this.iframePort = port; - - // Set up postMessage routing if needed - if (this.iframePort && this.iframeOrigin) { - this.iframePort.onmessage = (event) => { - if (event.origin !== this.iframeOrigin) { - console.warn('Ignoring message from unknown origin:', event.origin); - return; - } - - console.log('Received iframe message:', event.data); - // Handle iframe messages - }; - - // Send keepalive - setInterval(() => { - if (this.iframePort) { - try { - this.iframePort.postMessage({ type: 'ping' }); - } catch (e) { - console.warn('Iframe port closed'); - this.iframePort = null; - } - } - }, 30000); // 30 seconds - } - } - - teardown() { - this.unsubscribe(); - - if (this.iframePort) { - try { - this.iframePort.close(); - } catch (e) { - console.warn('Error closing iframe port:', e); - } - this.iframePort = null; - } - - if (this.pool) { - this.pool.close(this.relays); - this.pool = null; - } - - // Clear all pending requests - for (const id in this.pendingRequests) { - this.pendingRequests[id].reject(new Error('Client teardown')); - } - this.pendingRequests = {}; - } -} \ No newline at end of file diff --git a/lite/nostr-lite.js b/lite/nostr-lite.js new file mode 100644 index 0000000..d5025dc --- /dev/null +++ b/lite/nostr-lite.js @@ -0,0 +1,2379 @@ +/** + * NOSTR_LOGIN_LITE - Authentication Library + * Two-file architecture: + * 1. Load nostr.bundle.js (official nostr-tools bundle) + * 2. Load nostr-lite.js (this file - consolidated NOSTR_LOGIN_LITE library with NIP-46) + * Generated on: 2025-09-13T18:23:00.000Z + */ + +// Verify dependencies are loaded +if (typeof window !== 'undefined') { + if (!window.NostrTools) { + console.error('NOSTR_LOGIN_LITE: nostr.bundle.js must be loaded first'); + throw new Error('Missing dependency: nostr.bundle.js'); + } + + console.log('NOSTR_LOGIN_LITE: Dependencies verified ✓'); + console.log('NOSTR_LOGIN_LITE: NostrTools available with keys:', Object.keys(window.NostrTools)); +} + +// ====================================== +// NIP-46 Extension (formerly nip46-extension.js) +// ====================================== + +(function() { + 'use strict'; + + // Check if NostrTools is available + if (typeof window.NostrTools === 'undefined') { + console.error('NIP-46 Extension requires nostr-tools to be loaded first'); + return; + } + + const { nip44, generateSecretKey, getPublicKey, finalizeEvent, verifyEvent, utils } = window.NostrTools; + + // NIP-05 regex for parsing + const NIP05_REGEX = /^(?:([\w.+-]+)@)?([\w_-]+(\.[\w_-]+)+)$/; + const BUNKER_REGEX = /^bunker:\/\/([0-9a-f]{64})\??([?\/\w:.=&%-]*)$/; + const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + + // Event kinds + const NostrConnect = 24133; + const ClientAuth = 22242; + const Handlerinformation = 31990; + + // Fetch implementation + let _fetch; + try { + _fetch = fetch; + } catch { + _fetch = null; + } + + function useFetchImplementation(fetchImplementation) { + _fetch = fetchImplementation; + } + + // Simple Pool implementation for NIP-46 + class SimplePool { + constructor() { + this.relays = new Map(); + this.subscriptions = new Map(); + } + + async ensureRelay(url) { + if (!this.relays.has(url)) { + console.log(`NIP-46: Connecting to relay ${url}`); + const ws = new WebSocket(url); + const relay = { + ws, + connected: false, + subscriptions: new Map() + }; + + this.relays.set(url, relay); + + // Wait for connection with proper event handlers + await new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + console.error(`NIP-46: Connection timeout for ${url}`); + reject(new Error(`Connection timeout to ${url}`)); + }, 10000); // 10 second timeout + + ws.onopen = () => { + console.log(`NIP-46: Successfully connected to relay ${url}, WebSocket state: ${ws.readyState}`); + relay.connected = true; + clearTimeout(timeout); + resolve(); + }; + + ws.onerror = (error) => { + console.error(`NIP-46: Failed to connect to ${url}:`, error); + clearTimeout(timeout); + reject(new Error(`Failed to connect to ${url}: ${error.message || 'Connection failed'}`)); + }; + + ws.onclose = (event) => { + console.log(`NIP-46: Disconnected from relay ${url}:`, event.code, event.reason); + relay.connected = false; + if (this.relays.has(url)) { + this.relays.delete(url); + } + clearTimeout(timeout); + reject(new Error(`Connection closed during setup: ${event.reason || 'Unknown reason'}`)); + }; + }); + } else { + const relay = this.relays.get(url); + // Verify the existing connection is still open + if (!relay.connected || relay.ws.readyState !== WebSocket.OPEN) { + console.log(`NIP-46: Reconnecting to relay ${url}`); + this.relays.delete(url); + return await this.ensureRelay(url); // Recursively reconnect + } + } + + const relay = this.relays.get(url); + console.log(`NIP-46: Relay ${url} ready, WebSocket state: ${relay.ws.readyState}`); + return relay; + } + + subscribe(relays, filters, params = {}) { + const subId = Math.random().toString(36).substring(7); + + relays.forEach(async (url) => { + try { + const relay = await this.ensureRelay(url); + + relay.ws.onmessage = (event) => { + try { + const data = JSON.parse(event.data); + if (data[0] === 'EVENT' && data[1] === subId) { + params.onevent?.(data[2]); + } else if (data[0] === 'EOSE' && data[1] === subId) { + params.oneose?.(); + } + } catch (err) { + console.warn('Failed to parse message:', err); + } + }; + + // Ensure filters is an array + const filtersArray = Array.isArray(filters) ? filters : [filters]; + const reqMsg = JSON.stringify(['REQ', subId, ...filtersArray]); + relay.ws.send(reqMsg); + + } catch (err) { + console.warn('Failed to connect to relay:', url, err); + } + }); + + return { + close: () => { + relays.forEach(async (url) => { + const relay = this.relays.get(url); + if (relay?.connected) { + relay.ws.send(JSON.stringify(['CLOSE', subId])); + } + }); + } + }; + } + + async publish(relays, event) { + console.log(`NIP-46: Publishing event to ${relays.length} relays:`, event); + + const promises = relays.map(async (url) => { + try { + console.log(`NIP-46: Attempting to publish to ${url}`); + const relay = await this.ensureRelay(url); + + return new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + console.error(`NIP-46: Publish timeout to ${url}`); + reject(new Error(`Publish timeout to ${url}`)); + }, 10000); // Increased timeout to 10 seconds + + // Set up message handler for this specific event + const messageHandler = (msg) => { + try { + const data = JSON.parse(msg.data); + if (data[0] === 'OK' && data[1] === event.id) { + clearTimeout(timeout); + relay.ws.removeEventListener('message', messageHandler); + if (data[2]) { + console.log(`NIP-46: Publish success to ${url}:`, data[3]); + resolve(data[3]); + } else { + console.error(`NIP-46: Publish rejected by ${url}:`, data[3]); + reject(new Error(`Publish rejected: ${data[3]}`)); + } + } + } catch (err) { + console.error(`NIP-46: Error parsing message from ${url}:`, err); + clearTimeout(timeout); + relay.ws.removeEventListener('message', messageHandler); + reject(err); + } + }; + + relay.ws.addEventListener('message', messageHandler); + + // Double-check WebSocket state before sending + console.log(`NIP-46: About to publish to ${url}, WebSocket state: ${relay.ws.readyState} (0=CONNECTING, 1=OPEN, 2=CLOSING, 3=CLOSED)`); + if (relay.ws.readyState === WebSocket.OPEN) { + console.log(`NIP-46: Sending event to ${url}`); + relay.ws.send(JSON.stringify(['EVENT', event])); + } else { + console.error(`NIP-46: WebSocket not ready for ${url}, state: ${relay.ws.readyState}`); + clearTimeout(timeout); + relay.ws.removeEventListener('message', messageHandler); + reject(new Error(`WebSocket not ready for ${url}, state: ${relay.ws.readyState}`)); + } + }); + } catch (err) { + console.error(`NIP-46: Failed to publish to ${url}:`, err); + return Promise.reject(new Error(`Failed to publish to ${url}: ${err.message}`)); + } + }); + + const results = await Promise.allSettled(promises); + console.log(`NIP-46: Publish results:`, results); + return results; + } + + async querySync(relays, filter, params = {}) { + return new Promise((resolve) => { + const events = []; + this.subscribe(relays, [filter], { + ...params, + onevent: (event) => events.push(event), + oneose: () => resolve(events) + }); + }); + } + } + + // Bunker URL utilities + function toBunkerURL(bunkerPointer) { + let bunkerURL = new URL(`bunker://${bunkerPointer.pubkey}`); + bunkerPointer.relays.forEach((relay) => { + bunkerURL.searchParams.append('relay', relay); + }); + if (bunkerPointer.secret) { + bunkerURL.searchParams.set('secret', bunkerPointer.secret); + } + return bunkerURL.toString(); + } + + async function parseBunkerInput(input) { + let match = input.match(BUNKER_REGEX); + if (match) { + try { + const pubkey = match[1]; + const qs = new URLSearchParams(match[2]); + return { + pubkey, + relays: qs.getAll('relay'), + secret: qs.get('secret') + }; + } catch (_err) { + // Continue to NIP-05 parsing + } + } + return queryBunkerProfile(input); + } + + async function queryBunkerProfile(nip05) { + if (!_fetch) { + throw new Error('Fetch implementation not available'); + } + + const match = nip05.match(NIP05_REGEX); + if (!match) return null; + + const [_, name = '_', domain] = match; + try { + const url = `https://${domain}/.well-known/nostr.json?name=${name}`; + const res = await (await _fetch(url, { redirect: 'error' })).json(); + let pubkey = res.names[name]; + let relays = res.nip46[pubkey] || []; + return { pubkey, relays, secret: null }; + } catch (_err) { + return null; + } + } + + // BunkerSigner class + class BunkerSigner { + constructor(clientSecretKey, bp, params = {}) { + if (bp.relays.length === 0) { + throw new Error('no relays are specified for this bunker'); + } + + this.params = params; + this.pool = params.pool || new SimplePool(); + this.secretKey = clientSecretKey; + this.conversationKey = nip44.getConversationKey(clientSecretKey, bp.pubkey); + this.bp = bp; + this.isOpen = false; + this.idPrefix = Math.random().toString(36).substring(7); + this.serial = 0; + this.listeners = {}; + this.waitingForAuth = {}; + this.ready = false; + this.readyPromise = this.setupSubscription(params); + } + + async setupSubscription(params) { + console.log('NIP-46: Setting up subscription to relays:', this.bp.relays); + const listeners = this.listeners; + const waitingForAuth = this.waitingForAuth; + const convKey = this.conversationKey; + + // Ensure all relays are connected first + await Promise.all(this.bp.relays.map(url => this.pool.ensureRelay(url))); + console.log('NIP-46: All relays connected, setting up subscription'); + + this.subCloser = this.pool.subscribe( + this.bp.relays, + [{ kinds: [NostrConnect], authors: [this.bp.pubkey], '#p': [getPublicKey(this.secretKey)] }], + { + onevent: async (event) => { + const o = JSON.parse(nip44.decrypt(event.content, convKey)); + const { id, result, error } = o; + + if (result === 'auth_url' && waitingForAuth[id]) { + delete waitingForAuth[id]; + if (params.onauth) { + params.onauth(error); + } else { + console.warn( + `NIP-46: remote signer ${this.bp.pubkey} tried to send an "auth_url"='${error}' but there was no onauth() callback configured.` + ); + } + return; + } + + let handler = listeners[id]; + if (handler) { + if (error) handler.reject(error); + else if (result) handler.resolve(result); + delete listeners[id]; + } + }, + onclose: () => { + this.subCloser = undefined; + } + } + ); + + this.isOpen = true; + this.ready = true; + console.log('NIP-46: BunkerSigner setup complete and ready'); + } + + async ensureReady() { + if (!this.ready) { + console.log('NIP-46: Waiting for BunkerSigner to be ready...'); + await this.readyPromise; + } + } + + async close() { + this.isOpen = false; + this.subCloser?.close(); + } + + async sendRequest(method, params) { + return new Promise(async (resolve, reject) => { + try { + await this.ensureReady(); // Wait for BunkerSigner to be ready + + if (!this.isOpen) { + throw new Error('this signer is not open anymore, create a new one'); + } + if (!this.subCloser) { + await this.setupSubscription(this.params); + } + + this.serial++; + const id = `${this.idPrefix}-${this.serial}`; + const encryptedContent = nip44.encrypt(JSON.stringify({ id, method, params }), this.conversationKey); + + const verifiedEvent = finalizeEvent( + { + kind: NostrConnect, + tags: [['p', this.bp.pubkey]], + content: encryptedContent, + created_at: Math.floor(Date.now() / 1000) + }, + this.secretKey + ); + + this.listeners[id] = { resolve, reject }; + this.waitingForAuth[id] = true; + + console.log(`NIP-46: Sending ${method} request with id ${id}`); + const publishResults = await this.pool.publish(this.bp.relays, verifiedEvent); + // Check if at least one publish succeeded + const hasSuccess = publishResults.some(result => result.status === 'fulfilled'); + if (!hasSuccess) { + throw new Error('Failed to publish to any relay'); + } + console.log(`NIP-46: ${method} request sent successfully`); + } catch (err) { + console.error(`NIP-46: sendRequest ${method} failed:`, err); + reject(err); + } + }); + } + + async ping() { + let resp = await this.sendRequest('ping', []); + if (resp !== 'pong') { + throw new Error(`result is not pong: ${resp}`); + } + } + + async connect() { + await this.sendRequest('connect', [this.bp.pubkey, this.bp.secret || '']); + } + + async getPublicKey() { + if (!this.cachedPubKey) { + this.cachedPubKey = await this.sendRequest('get_public_key', []); + } + return this.cachedPubKey; + } + + async signEvent(event) { + let resp = await this.sendRequest('sign_event', [JSON.stringify(event)]); + let signed = JSON.parse(resp); + if (verifyEvent(signed)) { + return signed; + } else { + throw new Error(`event returned from bunker is improperly signed: ${JSON.stringify(signed)}`); + } + } + + async nip04Encrypt(thirdPartyPubkey, plaintext) { + return await this.sendRequest('nip04_encrypt', [thirdPartyPubkey, plaintext]); + } + + async nip04Decrypt(thirdPartyPubkey, ciphertext) { + return await this.sendRequest('nip04_decrypt', [thirdPartyPubkey, ciphertext]); + } + + async nip44Encrypt(thirdPartyPubkey, plaintext) { + return await this.sendRequest('nip44_encrypt', [thirdPartyPubkey, plaintext]); + } + + async nip44Decrypt(thirdPartyPubkey, ciphertext) { + return await this.sendRequest('nip44_decrypt', [thirdPartyPubkey, ciphertext]); + } + } + + async function createAccount(bunker, params, username, domain, email, localSecretKey = generateSecretKey()) { + if (email && !EMAIL_REGEX.test(email)) { + throw new Error('Invalid email'); + } + + let rpc = new BunkerSigner(localSecretKey, bunker.bunkerPointer, params); + let pubkey = await rpc.sendRequest('create_account', [username, domain, email || '']); + rpc.bp.pubkey = pubkey; + await rpc.connect(); + return rpc; + } + + async function fetchBunkerProviders(pool, relays) { + const events = await pool.querySync(relays, { + kinds: [Handlerinformation], + '#k': [NostrConnect.toString()] + }); + + events.sort((a, b) => b.created_at - a.created_at); + + const validatedBunkers = await Promise.all( + events.map(async (event, i) => { + try { + const content = JSON.parse(event.content); + try { + if (events.findIndex((ev) => JSON.parse(ev.content).nip05 === content.nip05) !== i) { + return undefined; + } + } catch (err) { + // Continue processing + } + + const bp = await queryBunkerProfile(content.nip05); + if (bp && bp.pubkey === event.pubkey && bp.relays.length) { + return { + bunkerPointer: bp, + nip05: content.nip05, + domain: content.nip05.split('@')[1], + name: content.name || content.display_name, + picture: content.picture, + about: content.about, + website: content.website, + local: false + }; + } + } catch (err) { + return undefined; + } + }) + ); + + return validatedBunkers.filter((b) => b !== undefined); + } + + // Extend NostrTools with NIP-46 functionality + window.NostrTools.nip46 = { + BunkerSigner, + parseBunkerInput, + toBunkerURL, + queryBunkerProfile, + createAccount, + fetchBunkerProviders, + useFetchImplementation, + BUNKER_REGEX, + SimplePool + }; + + console.log('NIP-46 extension loaded successfully (embedded)'); + console.log('Available: NostrTools.nip46'); + +})(); + +// Verify NIP-46 extension is now available +if (typeof window !== 'undefined') { + console.log('NOSTR_LOGIN_LITE: NIP-46 available:', !!window.NostrTools.nip46); +} + +// ====================================== +// NOSTR_LOGIN_LITE Components +// ====================================== + +// ====================================== +// Modal UI Component +// ====================================== + + +class Modal { + constructor(options) { + this.options = options; + this.container = null; + this.isVisible = false; + this.currentScreen = null; + + // Initialize modal container and styles + this._initModal(); + } + + _initModal() { + // Create modal container + this.container = document.createElement('div'); + this.container.id = 'nl-modal'; + this.container.style.cssText = ` + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.75); + display: none; + z-index: 10000; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + `; + + // Create modal content + const modalContent = document.createElement('div'); + modalContent.style.cssText = ` + position: relative; + background: white; + width: 90%; + max-width: 400px; + margin: 50px auto; + border-radius: 12px; + box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); + max-height: 600px; + overflow: hidden; + `; + + // Header + const modalHeader = document.createElement('div'); + modalHeader.style.cssText = ` + padding: 20px 24px 0 24px; + display: flex; + justify-content: space-between; + align-items: center; + `; + + const modalTitle = document.createElement('h2'); + modalTitle.textContent = 'Nostr Login'; + modalTitle.style.cssText = ` + margin: 0; + font-size: 24px; + font-weight: 600; + color: #1f2937; + `; + + const closeButton = document.createElement('button'); + closeButton.innerHTML = '×'; + closeButton.onclick = () => this.close(); + closeButton.style.cssText = ` + background: none; + border: none; + font-size: 28px; + color: #6b7280; + cursor: pointer; + padding: 0; + width: 32px; + height: 32px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 6px; + `; + closeButton.onmouseover = () => closeButton.style.background = '#f3f4f6'; + closeButton.onmouseout = () => closeButton.style.background = 'none'; + + modalHeader.appendChild(modalTitle); + modalHeader.appendChild(closeButton); + + // Body + this.modalBody = document.createElement('div'); + this.modalBody.style.cssText = ` + padding: 24px; + overflow-y: auto; + max-height: 500px; + `; + + modalContent.appendChild(modalHeader); + modalContent.appendChild(this.modalBody); + this.container.appendChild(modalContent); + + // Add to body + document.body.appendChild(this.container); + + // Click outside to close + this.container.onclick = (e) => { + if (e.target === this.container) { + this.close(); + } + }; + + // Update theme + this.updateTheme(); + } + + updateTheme() { + const isDark = this.options?.darkMode; + const modalContent = this.container.querySelector(':nth-child(1)'); + const title = this.container.querySelector('h2'); + + if (isDark) { + modalContent.style.background = '#1f2937'; + title.style.color = 'white'; + } else { + modalContent.style.background = 'white'; + title.style.color = '#1f2937'; + } + } + + open(opts = {}) { + this.currentScreen = opts.startScreen; + this.isVisible = true; + this.container.style.display = 'block'; + + // Render login options + this._renderLoginOptions(); + } + + close() { + this.isVisible = false; + this.container.style.display = 'none'; + this.modalBody.innerHTML = ''; + } + + _renderLoginOptions() { + this.modalBody.innerHTML = ''; + + const options = []; + + // Extension option + if (this.options?.methods?.extension !== false) { + options.push({ + type: 'extension', + title: 'Browser Extension', + description: 'Use your browser extension', + icon: '🔌' + }); + } + + // Local key option + if (this.options?.methods?.local !== false) { + options.push({ + type: 'local', + title: 'Local Key', + description: 'Create or import your own key', + icon: '🔑' + }); + } + + // Nostr Connect option (check both 'connect' and 'remote' for compatibility) + if (this.options?.methods?.connect !== false && this.options?.methods?.remote !== false) { + options.push({ + type: 'connect', + title: 'Nostr Connect', + description: 'Connect with external signer', + icon: '🌐' + }); + } + + // Read-only option + if (this.options?.methods?.readonly !== false) { + options.push({ + type: 'readonly', + title: 'Read Only', + description: 'Browse without signing', + icon: '👁️' + }); + } + + // OTP/DM option + if (this.options?.methods?.otp !== false) { + options.push({ + type: 'otp', + title: 'DM/OTP', + description: 'Receive OTP via DM', + icon: '📱' + }); + } + + // Render each option + options.forEach(option => { + const button = document.createElement('button'); + button.onclick = () => this._handleOptionClick(option.type); + button.style.cssText = ` + display: flex; + align-items: center; + width: 100%; + padding: 16px; + margin-bottom: 12px; + background: ${this.options?.darkMode ? '#374151' : 'white'}; + border: 1px solid ${this.options?.darkMode ? '#4b5563' : '#d1d5db'}; + border-radius: 8px; + cursor: pointer; + transition: all 0.2s; + `; + button.onmouseover = () => { + button.style.boxShadow = '0 4px 6px -1px rgba(0, 0, 0, 0.1)'; + }; + button.onmouseout = () => { + button.style.boxShadow = 'none'; + }; + + const iconDiv = document.createElement('div'); + iconDiv.textContent = option.icon; + iconDiv.style.cssText = ` + font-size: 24px; + margin-right: 16px; + width: 24px; + text-align: center; + `; + + const contentDiv = document.createElement('div'); + contentDiv.style.cssText = 'flex: 1; text-align: left;'; + + const titleDiv = document.createElement('div'); + titleDiv.textContent = option.title; + titleDiv.style.cssText = ` + font-weight: 600; + margin-bottom: 4px; + color: ${this.options?.darkMode ? 'white' : '#1f2937'}; + `; + + const descDiv = document.createElement('div'); + descDiv.textContent = option.description; + descDiv.style.cssText = ` + font-size: 14px; + color: ${this.options?.darkMode ? '#9ca3af' : '#6b7280'}; + `; + + contentDiv.appendChild(titleDiv); + contentDiv.appendChild(descDiv); + + button.appendChild(iconDiv); + button.appendChild(contentDiv); + this.modalBody.appendChild(button); + }); + } + + _handleOptionClick(type) { + console.log('Selected login type:', type); + + // Handle different login types + switch (type) { + case 'extension': + this._handleExtension(); + break; + case 'local': + this._showLocalKeyScreen(); + break; + case 'connect': + this._showConnectScreen(); + break; + case 'readonly': + this._handleReadonly(); + break; + case 'otp': + this._showOtpScreen(); + break; + } + } + + _handleExtension() { + // Detect all available real extensions + const availableExtensions = this._detectAllExtensions(); + + console.log(`Modal: Found ${availableExtensions.length} extensions:`, availableExtensions.map(e => e.displayName)); + + if (availableExtensions.length === 0) { + console.log('Modal: No real extensions found'); + this._showExtensionRequired(); + } else if (availableExtensions.length === 1) { + // Single extension - use it directly without showing choice UI + console.log('Modal: Single extension detected, using it directly:', availableExtensions[0].displayName); + this._tryExtensionLogin(availableExtensions[0].extension); + } else { + // Multiple extensions - show choice UI + console.log('Modal: Multiple extensions detected, showing choice UI for', availableExtensions.length, 'extensions'); + this._showExtensionChoice(availableExtensions); + } + } + + _detectAllExtensions() { + const extensions = []; + const seenExtensions = new Set(); // Track extensions by object reference to avoid duplicates + + // Extension locations to check (in priority order) + const locations = [ + { path: 'window.navigator?.nostr', name: 'navigator.nostr', displayName: 'Standard Extension (navigator.nostr)', icon: '🌐', getter: () => window.navigator?.nostr }, + { path: 'window.webln?.nostr', name: 'webln.nostr', displayName: 'Alby WebLN Extension', icon: '⚡', getter: () => window.webln?.nostr }, + { path: 'window.alby?.nostr', name: 'alby.nostr', displayName: 'Alby Extension (Direct)', icon: '🐝', getter: () => window.alby?.nostr }, + { path: 'window.nos2x', name: 'nos2x', displayName: 'nos2x Extension', icon: '🔌', getter: () => window.nos2x }, + { path: 'window.flamingo?.nostr', name: 'flamingo.nostr', displayName: 'Flamingo Extension', icon: '🦩', getter: () => window.flamingo?.nostr }, + { path: 'window.mutiny?.nostr', name: 'mutiny.nostr', displayName: 'Mutiny Extension', icon: '⚔️', getter: () => window.mutiny?.nostr }, + { path: 'window.nostrich?.nostr', name: 'nostrich.nostr', displayName: 'Nostrich Extension', icon: '🐦', getter: () => window.nostrich?.nostr }, + { path: 'window.getAlby?.nostr', name: 'getAlby.nostr', displayName: 'getAlby Extension', icon: '🔧', getter: () => window.getAlby?.nostr } + ]; + + // Check each location + for (const location of locations) { + try { + const obj = location.getter(); + + console.log(`Modal: Checking ${location.name}:`, !!obj, obj?.constructor?.name); + + if (obj && this._isRealExtension(obj) && !seenExtensions.has(obj)) { + extensions.push({ + name: location.name, + displayName: location.displayName, + icon: location.icon, + extension: obj + }); + seenExtensions.add(obj); + console.log(`Modal: ✓ Detected extension at ${location.name} (${obj.constructor?.name})`); + } else if (obj) { + console.log(`Modal: ✗ Filtered out ${location.name} (${obj.constructor?.name})`); + } + } catch (e) { + // Location doesn't exist or can't be accessed + console.log(`Modal: ${location.name} not accessible:`, e.message); + } + } + + // Also check window.nostr but be extra careful to avoid our library + console.log('Modal: Checking window.nostr:', !!window.nostr, window.nostr?.constructor?.name); + if (window.nostr && this._isRealExtension(window.nostr) && !seenExtensions.has(window.nostr)) { + extensions.push({ + name: 'window.nostr', + displayName: 'Extension (window.nostr)', + icon: '🔑', + extension: window.nostr + }); + seenExtensions.add(window.nostr); + console.log(`Modal: ✓ Detected extension at window.nostr: ${window.nostr.constructor?.name}`); + } else if (window.nostr) { + console.log(`Modal: ✗ Filtered out window.nostr (${window.nostr.constructor?.name}) - likely our library`); + } + + return extensions; + } + + _isRealExtension(obj) { + console.log(`Modal: EXTENSIVE DEBUG - _isRealExtension called with:`, obj); + console.log(`Modal: Object type: ${typeof obj}`); + console.log(`Modal: Object truthy: ${!!obj}`); + + if (!obj || typeof obj !== 'object') { + console.log(`Modal: REJECT - Not an object`); + return false; + } + + console.log(`Modal: getPublicKey type: ${typeof obj.getPublicKey}`); + console.log(`Modal: signEvent type: ${typeof obj.signEvent}`); + + // Must have required Nostr methods + if (typeof obj.getPublicKey !== 'function' || typeof obj.signEvent !== 'function') { + console.log(`Modal: REJECT - Missing required methods`); + return false; + } + + // Exclude NostrTools library object + if (obj === window.NostrTools) { + console.log(`Modal: REJECT - Is NostrTools object`); + return false; + } + + // Use the EXACT SAME logic as the comprehensive test (lines 804-809) + // This is the key fix - match the comprehensive test's successful detection logic + const constructorName = obj.constructor?.name; + const objectKeys = Object.keys(obj); + + console.log(`Modal: Constructor name: "${constructorName}"`); + console.log(`Modal: Object keys: [${objectKeys.join(', ')}]`); + + // COMPREHENSIVE TEST LOGIC - Accept anything with required methods that's not our specific library classes + const isRealExtension = ( + typeof obj.getPublicKey === 'function' && + typeof obj.signEvent === 'function' && + constructorName !== 'WindowNostr' && // Our library class + constructorName !== 'NostrLite' // Our main class + ); + + console.log(`Modal: Using comprehensive test logic:`); + console.log(` Has getPublicKey: ${typeof obj.getPublicKey === 'function'}`); + console.log(` Has signEvent: ${typeof obj.signEvent === 'function'}`); + console.log(` Not WindowNostr: ${constructorName !== 'WindowNostr'}`); + console.log(` Not NostrLite: ${constructorName !== 'NostrLite'}`); + console.log(` Constructor: "${constructorName}"`); + + // Additional debugging for comparison + const extensionPropChecks = { + _isEnabled: !!obj._isEnabled, + enabled: !!obj.enabled, + kind: !!obj.kind, + _eventEmitter: !!obj._eventEmitter, + _scope: !!obj._scope, + _requests: !!obj._requests, + _pubkey: !!obj._pubkey, + name: !!obj.name, + version: !!obj.version, + description: !!obj.description + }; + + console.log(`Modal: Extension property analysis:`, extensionPropChecks); + + const hasExtensionProps = !!( + obj._isEnabled || obj.enabled || obj.kind || + obj._eventEmitter || obj._scope || obj._requests || obj._pubkey || + obj.name || obj.version || obj.description + ); + + const underscoreKeys = objectKeys.filter(key => key.startsWith('_')); + const hexToUint8Keys = objectKeys.filter(key => key.startsWith('_hex')); + console.log(`Modal: Underscore keys: [${underscoreKeys.join(', ')}]`); + console.log(`Modal: _hex* keys: [${hexToUint8Keys.join(', ')}]`); + + console.log(`Modal: Additional analysis:`); + console.log(` hasExtensionProps: ${hasExtensionProps}`); + console.log(` hasLibraryMethod (_hexToUint8Array): ${objectKeys.includes('_hexToUint8Array')}`); + + console.log(`Modal: COMPREHENSIVE TEST LOGIC RESULT: ${isRealExtension ? 'ACCEPT' : 'REJECT'}`); + console.log(`Modal: FINAL DECISION for ${constructorName}: ${isRealExtension ? 'ACCEPT' : 'REJECT'}`); + + return isRealExtension; + } + + _showExtensionChoice(extensions) { + this.modalBody.innerHTML = ''; + + const title = document.createElement('h3'); + title.textContent = 'Choose Browser Extension'; + title.style.cssText = 'margin: 0 0 16px 0; font-size: 18px; font-weight: 600;'; + + const description = document.createElement('p'); + description.textContent = `Found ${extensions.length} Nostr extensions. Choose which one to use:`; + description.style.cssText = 'margin-bottom: 20px; color: #6b7280; font-size: 14px;'; + + this.modalBody.appendChild(title); + this.modalBody.appendChild(description); + + // Create button for each extension + extensions.forEach((ext, index) => { + const button = document.createElement('button'); + button.onclick = () => this._tryExtensionLogin(ext.extension); + button.style.cssText = ` + display: flex; + align-items: center; + width: 100%; + padding: 16px; + margin-bottom: 12px; + background: ${this.options?.darkMode ? '#374151' : 'white'}; + border: 1px solid ${this.options?.darkMode ? '#4b5563' : '#d1d5db'}; + border-radius: 8px; + cursor: pointer; + transition: all 0.2s; + text-align: left; + `; + + button.onmouseover = () => { + button.style.boxShadow = '0 4px 6px -1px rgba(0, 0, 0, 0.1)'; + button.style.transform = 'translateY(-1px)'; + }; + button.onmouseout = () => { + button.style.boxShadow = 'none'; + button.style.transform = 'none'; + }; + + const iconDiv = document.createElement('div'); + iconDiv.textContent = ext.icon; + iconDiv.style.cssText = ` + font-size: 24px; + margin-right: 16px; + width: 24px; + text-align: center; + `; + + const contentDiv = document.createElement('div'); + contentDiv.style.cssText = 'flex: 1;'; + + const nameDiv = document.createElement('div'); + nameDiv.textContent = ext.displayName; + nameDiv.style.cssText = ` + font-weight: 600; + margin-bottom: 4px; + color: ${this.options?.darkMode ? 'white' : '#1f2937'}; + `; + + const pathDiv = document.createElement('div'); + pathDiv.textContent = ext.name; + pathDiv.style.cssText = ` + font-size: 12px; + color: ${this.options?.darkMode ? '#9ca3af' : '#6b7280'}; + font-family: monospace; + `; + + contentDiv.appendChild(nameDiv); + contentDiv.appendChild(pathDiv); + + button.appendChild(iconDiv); + button.appendChild(contentDiv); + this.modalBody.appendChild(button); + }); + + // Add back button + const backButton = document.createElement('button'); + backButton.textContent = 'Back to Login Options'; + backButton.onclick = () => this._renderLoginOptions(); + backButton.style.cssText = this._getButtonStyle('secondary') + 'margin-top: 20px;'; + + this.modalBody.appendChild(backButton); + } + + async _tryExtensionLogin(extensionObj) { + try { + // Show loading state + this.modalBody.innerHTML = '
🔄 Connecting to extension...
'; + + // Get pubkey from extension + const pubkey = await extensionObj.getPublicKey(); + console.log('Extension provided pubkey:', pubkey); + + // Set extension method with the extension object + this._setAuthMethod('extension', { pubkey, extension: extensionObj }); + + } catch (error) { + console.error('Extension login failed:', error); + this._showError(`Extension login failed: ${error.message}`); + } + } + + _showLocalKeyScreen() { + this.modalBody.innerHTML = ''; + + const title = document.createElement('h3'); + title.textContent = 'Local Key'; + title.style.cssText = 'margin: 0 0 20px 0; font-size: 18px; font-weight: 600;'; + + const createButton = document.createElement('button'); + createButton.textContent = 'Create New Key'; + createButton.onclick = () => this._createLocalKey(); + createButton.style.cssText = this._getButtonStyle(); + + const importButton = document.createElement('button'); + importButton.textContent = 'Import Existing Key'; + importButton.onclick = () => this._showImportKeyForm(); + importButton.style.cssText = this._getButtonStyle() + 'margin-top: 12px;'; + + const backButton = document.createElement('button'); + backButton.textContent = 'Back'; + backButton.onclick = () => this._renderLoginOptions(); + backButton.style.cssText = ` + display: block; + margin-top: 20px; + padding: 12px; + background: #6b7280; + color: white; + border: none; + border-radius: 6px; + cursor: pointer; + `; + + this.modalBody.appendChild(title); + this.modalBody.appendChild(createButton); + this.modalBody.appendChild(importButton); + this.modalBody.appendChild(backButton); + } + + _createLocalKey() { + try { + const sk = window.NostrTools.generateSecretKey(); + const pk = window.NostrTools.getPublicKey(sk); + const nsec = window.NostrTools.nip19.nsecEncode(sk); + const npub = window.NostrTools.nip19.npubEncode(pk); + + this._showKeyDisplay(pk, nsec, 'created'); + } catch (error) { + this._showError('Failed to create key: ' + error.message); + } + } + + _showImportKeyForm() { + this.modalBody.innerHTML = ''; + + const title = document.createElement('h3'); + title.textContent = 'Import Local Key'; + title.style.cssText = 'margin: 0 0 16px 0; font-size: 18px; font-weight: 600;'; + + const description = document.createElement('p'); + description.textContent = 'Enter your secret key in either nsec or hex format:'; + description.style.cssText = 'margin-bottom: 12px; color: #6b7280; font-size: 14px;'; + + const textarea = document.createElement('textarea'); + textarea.placeholder = 'Enter your secret key:\n• nsec1... (bech32 format)\n• 64-character hex string'; + textarea.style.cssText = ` + width: 100%; + height: 100px; + padding: 12px; + border: 1px solid #d1d5db; + border-radius: 6px; + margin-bottom: 12px; + resize: none; + font-family: monospace; + font-size: 14px; + box-sizing: border-box; + `; + + // Add real-time format detection + const formatHint = document.createElement('div'); + formatHint.style.cssText = 'margin-bottom: 16px; font-size: 12px; color: #6b7280; min-height: 16px;'; + + textarea.oninput = () => { + const value = textarea.value.trim(); + if (!value) { + formatHint.textContent = ''; + return; + } + + const format = this._detectKeyFormat(value); + if (format === 'nsec') { + formatHint.textContent = '✅ Valid nsec format detected'; + formatHint.style.color = '#059669'; + } else if (format === 'hex') { + formatHint.textContent = '✅ Valid hex format detected'; + formatHint.style.color = '#059669'; + } else { + formatHint.textContent = '❌ Invalid key format - must be nsec1... or 64-character hex'; + formatHint.style.color = '#dc2626'; + } + }; + + const importButton = document.createElement('button'); + importButton.textContent = 'Import Key'; + importButton.onclick = () => this._importLocalKey(textarea.value); + importButton.style.cssText = this._getButtonStyle(); + + const backButton = document.createElement('button'); + backButton.textContent = 'Back'; + backButton.onclick = () => this._showLocalKeyScreen(); + backButton.style.cssText = this._getButtonStyle('secondary') + 'margin-top: 12px;'; + + this.modalBody.appendChild(title); + this.modalBody.appendChild(description); + this.modalBody.appendChild(textarea); + this.modalBody.appendChild(formatHint); + this.modalBody.appendChild(importButton); + this.modalBody.appendChild(backButton); + } + + _detectKeyFormat(keyValue) { + const trimmed = keyValue.trim(); + + // Check for nsec format + if (trimmed.startsWith('nsec1') && trimmed.length === 63) { + try { + window.NostrTools.nip19.decode(trimmed); + return 'nsec'; + } catch { + return 'invalid'; + } + } + + // Check for hex format (64 characters, valid hex) + if (trimmed.length === 64 && /^[a-fA-F0-9]{64}$/.test(trimmed)) { + return 'hex'; + } + + return 'invalid'; + } + + _importLocalKey(keyValue) { + try { + const trimmed = keyValue.trim(); + if (!trimmed) { + throw new Error('Please enter a secret key'); + } + + const format = this._detectKeyFormat(trimmed); + let sk; + + if (format === 'nsec') { + // Decode nsec format - this returns Uint8Array + const decoded = window.NostrTools.nip19.decode(trimmed); + if (decoded.type !== 'nsec') { + throw new Error('Invalid nsec format'); + } + sk = decoded.data; // This is already Uint8Array + } else if (format === 'hex') { + // Convert hex string to Uint8Array + sk = this._hexToUint8Array(trimmed); + // Test that it's a valid secret key by trying to get public key + window.NostrTools.getPublicKey(sk); + } else { + throw new Error('Invalid key format. Please enter either nsec1... or 64-character hex string'); + } + + // Generate public key and encoded formats + const pk = window.NostrTools.getPublicKey(sk); + const nsec = window.NostrTools.nip19.nsecEncode(sk); + const npub = window.NostrTools.nip19.npubEncode(pk); + + this._showKeyDisplay(pk, nsec, 'imported'); + } catch (error) { + this._showError('Invalid key: ' + error.message); + } + } + + _hexToUint8Array(hex) { + // Convert hex string to Uint8Array + if (hex.length % 2 !== 0) { + throw new Error('Invalid hex string length'); + } + const bytes = new Uint8Array(hex.length / 2); + for (let i = 0; i < bytes.length; i++) { + bytes[i] = parseInt(hex.substr(i * 2, 2), 16); + } + return bytes; + } + + _showKeyDisplay(pubkey, nsec, action) { + this.modalBody.innerHTML = ''; + + const title = document.createElement('h3'); + title.textContent = `Key ${action} successfully!`; + title.style.cssText = 'margin: 0 0 16px 0; font-size: 18px; font-weight: 600; color: #059669;'; + + const warningDiv = document.createElement('div'); + warningDiv.textContent = '⚠️ Save your secret key securely!'; + warningDiv.style.cssText = 'background: #fef3c7; color: #92400e; padding: 12px; border-radius: 6px; margin-bottom: 16px; font-size: 14px;'; + + const nsecDiv = document.createElement('div'); + nsecDiv.innerHTML = `Your Secret Key:
${nsec}`; + nsecDiv.style.cssText = 'margin-bottom: 16px; font-size: 14px;'; + + const npubDiv = document.createElement('div'); + npubDiv.innerHTML = `Your Public Key:
${window.NostrTools.nip19.npubEncode(pubkey)}`; + npubDiv.style.cssText = 'margin-bottom: 16px; font-size: 14px;'; + + const continueButton = document.createElement('button'); + continueButton.textContent = 'Continue'; + continueButton.onclick = () => this._setAuthMethod('local', { secret: nsec, pubkey }); + continueButton.style.cssText = this._getButtonStyle(); + + this.modalBody.appendChild(title); + this.modalBody.appendChild(warningDiv); + this.modalBody.appendChild(nsecDiv); + this.modalBody.appendChild(npubDiv); + this.modalBody.appendChild(continueButton); + } + + _setAuthMethod(method, options = {}) { + // Emit auth method selection + const event = new CustomEvent('nlMethodSelected', { + detail: { method, ...options } + }); + window.dispatchEvent(event); + + this.close(); + } + + _showError(message) { + this.modalBody.innerHTML = ''; + + const errorDiv = document.createElement('div'); + errorDiv.style.cssText = 'background: #fee2e2; color: #dc2626; padding: 16px; border-radius: 6px; margin-bottom: 16px;'; + errorDiv.innerHTML = `Error: ${message}`; + + const backButton = document.createElement('button'); + backButton.textContent = 'Back'; + backButton.onclick = () => this._renderLoginOptions(); + backButton.style.cssText = this._getButtonStyle('secondary'); + + this.modalBody.appendChild(errorDiv); + this.modalBody.appendChild(backButton); + } + + _showExtensionRequired() { + this.modalBody.innerHTML = ''; + + const title = document.createElement('h3'); + title.textContent = 'Browser Extension Required'; + title.style.cssText = 'margin: 0 0 16px 0; font-size: 18px; font-weight: 600;'; + + const message = document.createElement('p'); + message.textContent = 'Please install a Nostr browser extension like Alby or getflattr and refresh the page.'; + message.style.cssText = 'margin-bottom: 20px; color: #6b7280;'; + + const backButton = document.createElement('button'); + backButton.textContent = 'Back'; + backButton.onclick = () => this._renderLoginOptions(); + backButton.style.cssText = this._getButtonStyle('secondary'); + + this.modalBody.appendChild(title); + this.modalBody.appendChild(message); + this.modalBody.appendChild(backButton); + } + + _showConnectScreen() { + this.modalBody.innerHTML = ''; + + const title = document.createElement('h3'); + title.textContent = 'Nostr Connect'; + title.style.cssText = 'margin: 0 0 20px 0; font-size: 18px; font-weight: 600;'; + + const formGroup = document.createElement('div'); + formGroup.style.cssText = 'margin-bottom: 20px;'; + + const label = document.createElement('label'); + label.textContent = 'Connection String:'; + label.style.cssText = 'display: block; margin-bottom: 8px; font-weight: 500;'; + + const pubkeyInput = document.createElement('input'); + pubkeyInput.type = 'text'; + pubkeyInput.placeholder = 'bunker://...'; + pubkeyInput.style.cssText = ` + width: 100%; + padding: 12px; + border: 1px solid #d1d5db; + border-radius: 6px; + margin-bottom: 16px; + font-family: monospace; + box-sizing: border-box; + `; + + const connectButton = document.createElement('button'); + connectButton.textContent = 'Connect'; + connectButton.onclick = () => this._handleNip46Connect(pubkeyInput.value, null); + connectButton.style.cssText = this._getButtonStyle(); + + const backButton = document.createElement('button'); + backButton.textContent = 'Back'; + backButton.onclick = () => this._renderLoginOptions(); + backButton.style.cssText = this._getButtonStyle('secondary') + 'margin-top: 12px;'; + + formGroup.appendChild(label); + formGroup.appendChild(pubkeyInput); + + this.modalBody.appendChild(title); + this.modalBody.appendChild(formGroup); + this.modalBody.appendChild(connectButton); + this.modalBody.appendChild(backButton); + } + + _handleNip46Connect(bunkerPubkey, bunkerUrl) { + if (!bunkerPubkey || !bunkerPubkey.length) { + this._showError('Bunker connection string is required'); + return; + } + + this._showNip46Connecting(bunkerPubkey); + this._performNip46Connect(bunkerPubkey, null); + } + + _showNip46Connecting(bunkerPubkey) { + this.modalBody.innerHTML = ''; + + const title = document.createElement('h3'); + title.textContent = 'Connecting to Remote Signer...'; + title.style.cssText = 'margin: 0 0 16px 0; font-size: 18px; font-weight: 600; color: #059669;'; + + const description = document.createElement('p'); + description.textContent = 'Establishing secure connection to your remote signer via Nostr relays.'; + description.style.cssText = 'margin-bottom: 20px; color: #6b7280;'; + + // Show the connection string being used + const connectionString = bunkerPubkey.length > 60 ? + `${bunkerPubkey.substring(0, 30)}...${bunkerPubkey.substring(bunkerPubkey.length - 30)}` : + bunkerPubkey; + + const bunkerInfo = document.createElement('div'); + bunkerInfo.style.cssText = 'background: #f1f5f9; padding: 12px; border-radius: 6px; margin-bottom: 20px; font-size: 14px;'; + bunkerInfo.innerHTML = ` + Connecting via:
+ ${connectionString}
+ Using NIP-46 protocol over Nostr relays for secure communication. + `; + + const connectingDiv = document.createElement('div'); + connectingDiv.style.cssText = 'text-align: center; color: #6b7280;'; + connectingDiv.innerHTML = ` +
+
Please wait while we establish the connection...
+
This may take a few seconds
+ `; + + this.modalBody.appendChild(title); + this.modalBody.appendChild(description); + this.modalBody.appendChild(bunkerInfo); + this.modalBody.appendChild(connectingDiv); + } + + async _performNip46Connect(bunkerPubkey, bunkerUrl) { + try { + console.log('Starting NIP-46 connection to bunker:', bunkerPubkey, bunkerUrl); + + // Check if nostr-tools NIP-46 is available + if (!window.NostrTools?.nip46) { + throw new Error('nostr-tools NIP-46 module not available'); + } + + // Use nostr-tools to parse bunker input - this handles all formats correctly + console.log('Parsing bunker input with nostr-tools...'); + const bunkerPointer = await window.NostrTools.nip46.parseBunkerInput(bunkerPubkey); + + if (!bunkerPointer) { + throw new Error('Unable to parse bunker connection string or resolve NIP-05 identifier'); + } + + console.log('Parsed bunker pointer:', bunkerPointer); + + // Create local client keypair for this session + const localSecretKey = window.NostrTools.generateSecretKey(); + console.log('Generated local client keypair for NIP-46 session'); + + // Use nostr-tools BunkerSigner constructor + console.log('Creating nip46 BunkerSigner...'); + const signer = new window.NostrTools.nip46.BunkerSigner(localSecretKey, bunkerPointer, { + onauth: (url) => { + console.log('Received auth URL from bunker:', url); + // Open auth URL in popup or redirect + window.open(url, '_blank', 'width=600,height=800'); + } + }); + + console.log('NIP-46 BunkerSigner created successfully'); + + // Skip ping test - NIP-46 works through relays, not direct connection + // Try to connect directly (this may trigger auth flow) + console.log('Attempting NIP-46 connect...'); + await signer.connect(); + console.log('NIP-46 connect successful'); + + // Get the user's public key from the bunker + console.log('Getting public key from bunker...'); + const userPubkey = await signer.getPublicKey(); + console.log('NIP-46 user public key:', userPubkey); + + // Store the NIP-46 authentication info + const nip46Info = { + pubkey: userPubkey, + signer: { + method: 'nip46', + remotePubkey: bunkerPointer.pubkey, + bunkerSigner: signer, + secret: bunkerPointer.secret, + relays: bunkerPointer.relays + } + }; + + console.log('NOSTR_LOGIN_LITE NIP-46 connection established successfully!'); + + // Set as current auth method + this._setAuthMethod('nip46', nip46Info); + return; + + } catch (error) { + console.error('NIP-46 connection failed:', error); + this._showNip46Error(error.message); + } + } + + _showNip46Error(message) { + this.modalBody.innerHTML = ''; + + const title = document.createElement('h3'); + title.textContent = 'Connection Failed'; + title.style.cssText = 'margin: 0 0 16px 0; font-size: 18px; font-weight: 600; color: #dc2626;'; + + const errorMsg = document.createElement('p'); + errorMsg.textContent = `Unable to connect to remote signer: ${message}`; + errorMsg.style.cssText = 'margin-bottom: 20px; color: #6b7280;'; + + const retryButton = document.createElement('button'); + retryButton.textContent = 'Try Again'; + retryButton.onclick = () => this._showConnectScreen(); + retryButton.style.cssText = this._getButtonStyle(); + + const backButton = document.createElement('button'); + backButton.textContent = 'Back to Options'; + backButton.onclick = () => this._renderLoginOptions(); + backButton.style.cssText = this._getButtonStyle('secondary') + 'margin-top: 12px;'; + + this.modalBody.appendChild(title); + this.modalBody.appendChild(errorMsg); + this.modalBody.appendChild(retryButton); + this.modalBody.appendChild(backButton); + } + + _handleReadonly() { + // Set read-only mode + this._setAuthMethod('readonly'); + } + + _showOtpScreen() { + this.modalBody.innerHTML = ''; + + const title = document.createElement('h3'); + title.textContent = 'DM/OTP Login'; + title.style.cssText = 'margin: 0 0 16px 0; font-size: 18px; font-weight: 600;'; + + const description = document.createElement('p'); + description.textContent = 'Enter your public key to receive a login code via direct message.'; + description.style.cssText = 'margin-bottom: 12px; color: #6b7280; font-size: 14px;'; + + const pubkeyInput = document.createElement('input'); + pubkeyInput.type = 'text'; + pubkeyInput.placeholder = 'Enter your public key:\n• npub1... (bech32 format)\n• 64-character hex string'; + pubkeyInput.style.cssText = ` + width: 100%; + padding: 12px; + border: 1px solid #d1d5db; + border-radius: 6px; + margin-bottom: 12px; + font-family: monospace; + font-size: 14px; + box-sizing: border-box; + `; + + // Add real-time format detection (reusing logic from local key) + const formatHint = document.createElement('div'); + formatHint.style.cssText = 'margin-bottom: 16px; font-size: 12px; color: #6b7280; min-height: 16px;'; + + pubkeyInput.oninput = () => { + const value = pubkeyInput.value.trim(); + if (!value) { + formatHint.textContent = ''; + return; + } + + const format = this._detectPubkeyFormat(value); + if (format === 'npub') { + formatHint.textContent = '✅ Valid npub format detected'; + formatHint.style.color = '#059669'; + } else if (format === 'hex') { + formatHint.textContent = '✅ Valid hex format detected'; + formatHint.style.color = '#059669'; + } else { + formatHint.textContent = '❌ Invalid public key format - must be npub1... or 64-character hex'; + formatHint.style.color = '#dc2626'; + } + }; + + const sendButton = document.createElement('button'); + sendButton.textContent = 'Send Login Code'; + sendButton.onclick = () => this._handleOtpRequest(pubkeyInput.value); + sendButton.style.cssText = this._getButtonStyle(); + + const backButton = document.createElement('button'); + backButton.textContent = 'Back'; + backButton.onclick = () => this._renderLoginOptions(); + backButton.style.cssText = this._getButtonStyle('secondary') + 'margin-top: 12px;'; + + this.modalBody.appendChild(title); + this.modalBody.appendChild(description); + this.modalBody.appendChild(pubkeyInput); + this.modalBody.appendChild(formatHint); + this.modalBody.appendChild(sendButton); + this.modalBody.appendChild(backButton); + } + + _detectPubkeyFormat(keyValue) { + const trimmed = keyValue.trim(); + + // Check for npub format + if (trimmed.startsWith('npub1') && trimmed.length === 63) { + try { + const decoded = window.NostrTools.nip19.decode(trimmed); + if (decoded.type === 'npub') { + return 'npub'; + } + } catch { + return 'invalid'; + } + } + + // Check for hex format (64 characters, valid hex) + if (trimmed.length === 64 && /^[a-fA-F0-9]{64}$/.test(trimmed)) { + return 'hex'; + } + + return 'invalid'; + } + + _handleOtpRequest(pubkeyValue) { + try { + const trimmed = pubkeyValue.trim(); + if (!trimmed) { + throw new Error('Please enter a public key'); + } + + const format = this._detectPubkeyFormat(trimmed); + let pubkey, displayKey; + + if (format === 'npub') { + // Decode npub format + const decoded = window.NostrTools.nip19.decode(trimmed); + if (decoded.type !== 'npub') { + throw new Error('Invalid npub format'); + } + pubkey = decoded.data; // This is the hex pubkey + displayKey = trimmed; // Keep the original npub for display + } else if (format === 'hex') { + // Use hex directly as pubkey + pubkey = trimmed; + // Generate npub for display + displayKey = window.NostrTools.nip19.npubEncode(pubkey); + } else { + throw new Error('Invalid public key format. Please enter either npub1... or 64-character hex string'); + } + + this._showOtpCodeScreen(pubkey, displayKey); + } catch (error) { + this._showError('Invalid public key: ' + error.message); + } + } + + _showOtpCodeScreen(pubkey, npub) { + this.modalBody.innerHTML = ''; + + const title = document.createElement('h3'); + title.textContent = 'Enter Login Code'; + title.style.cssText = 'margin: 0 0 16px 0; font-size: 18px; font-weight: 600;'; + + const description = document.createElement('p'); + description.innerHTML = `Check your DMs for a login code sent to:
${npub}`; + description.style.cssText = 'margin-bottom: 20px; color: #6b7280; font-size: 14px;'; + + const formGroup = document.createElement('div'); + formGroup.style.cssText = 'margin-bottom: 20px;'; + + const label = document.createElement('label'); + label.textContent = 'Login Code:'; + label.style.cssText = 'display: block; margin-bottom: 8px; font-weight: 500;'; + + const codeInput = document.createElement('input'); + codeInput.type = 'text'; + codeInput.placeholder = 'Enter 6-digit code'; + codeInput.maxLength = 6; + codeInput.style.cssText = ` + width: 100%; + padding: 12px; + border: 1px solid #d1d5db; + border-radius: 6px; + margin-bottom: 16px; + font-family: monospace; + box-sizing: border-box; + text-align: center; + font-size: 18px; + letter-spacing: 2px; + `; + + const verifyButton = document.createElement('button'); + verifyButton.textContent = 'Verify Code'; + verifyButton.onclick = () => this._handleOtpVerification(pubkey, codeInput.value); + verifyButton.style.cssText = this._getButtonStyle(); + + const resendButton = document.createElement('button'); + resendButton.textContent = 'Resend Code'; + resendButton.onclick = () => this._handleOtpRequest(npub); + resendButton.style.cssText = this._getButtonStyle('secondary') + 'margin-top: 12px; margin-right: 8px;'; + + const backButton = document.createElement('button'); + backButton.textContent = 'Back'; + backButton.onclick = () => this._showOtpScreen(); + backButton.style.cssText = this._getButtonStyle('secondary') + 'margin-top: 12px;'; + + formGroup.appendChild(label); + formGroup.appendChild(codeInput); + + this.modalBody.appendChild(title); + this.modalBody.appendChild(description); + this.modalBody.appendChild(formGroup); + this.modalBody.appendChild(verifyButton); + + const buttonRow = document.createElement('div'); + buttonRow.style.cssText = 'display: flex; gap: 8px;'; + buttonRow.appendChild(resendButton); + buttonRow.appendChild(backButton); + this.modalBody.appendChild(buttonRow); + + // Simulate sending DM (in a real implementation, this would send a DM) + this._simulateOtpSend(pubkey); + } + + async _simulateOtpSend(pubkey) { + // Generate a random 6-digit code + const code = Math.floor(100000 + Math.random() * 900000).toString(); + + // Store the code temporarily (in a real implementation, this would be server-side) + sessionStorage.setItem(`otp_${pubkey}`, code); + sessionStorage.setItem(`otp_${pubkey}_timestamp`, Date.now().toString()); + + console.log(`OTP/DM: Generated code ${code} for pubkey ${pubkey}`); + + // Actually send the DM + await this._sendOtpDm(pubkey, code); + } + + async _sendOtpDm(recipientPubkey, code) { + try { + console.log('🚀 OTP/DM: Starting modern NIP-17 DM send process...'); + + // Generate a temporary key pair for sending the DM + const senderSecretKey = window.NostrTools.generateSecretKey(); + const senderPubkey = window.NostrTools.getPublicKey(senderSecretKey); + + console.log('🔑 OTP/DM: Generated temporary sender pubkey:', senderPubkey); + console.log('👤 OTP/DM: Sending DM to recipient pubkey:', recipientPubkey); + + // Create the DM content + const dmContent = `Your NOSTR_LOGIN_LITE login code: ${code}\n\nThis code expires in 5 minutes.`; + + console.log('💬 OTP/DM: Original message:', dmContent); + + // Check if NIP-17 is available in nostr-tools + if (!window.NostrTools?.nip17) { + console.warn('⚠️ OTP/DM: NIP-17 not available in nostr-tools, falling back to NIP-44'); + return await this._sendLegacyNip44Dm(senderSecretKey, recipientPubkey, dmContent, code); + } + + // Create recipient object for NIP-17 + const recipient = { + publicKey: recipientPubkey, + relayUrl: undefined // Will use default relays + }; + + console.log('🔄 OTP/DM: Creating NIP-17 gift-wrapped DM using nostr-tools...'); + + // Use nostr-tools NIP-17 to create properly wrapped DM + const wrappedEvent = window.NostrTools.nip17.wrapEvent( + senderSecretKey, + recipient, + dmContent, + undefined, // no conversation title + undefined // no reply + ); + + console.log('📝 OTP/DM: Created NIP-17 gift wrap (kind 1059):', JSON.stringify(wrappedEvent, null, 2)); + + // Get relays to send to + const relays = this.options.relays || [ + 'wss://relay.damus.io', + 'wss://relay.primal.net', + 'wss://relay.laantungir.net', + 'wss://nostr.mom' + ]; + + console.log('🌐 OTP/DM: Sending NIP-17 DM to relays:', relays); + + // Create a pool using our enhanced SimplePool from NIP-46 extension + const pool = new window.NostrTools.nip46.SimplePool(); + + // Send the gift-wrapped event to all relays + console.log('📡 OTP/DM: === Sending NIP-17 Gift-Wrapped DM ==='); + const publishPromises = relays.map(async (relay, index) => { + console.log(`📡 OTP/DM: NIP-17 [${index + 1}/${relays.length}] Connecting to relay ${relay}...`); + + try { + const results = await pool.publish([relay], wrappedEvent); + console.log(`📡 OTP/DM: NIP-17 Raw JSON response from ${relay}:`, JSON.stringify(results, null, 2)); + + // Check if the result status is fulfilled (successful) + const success = results.length > 0 && results[0].status === 'fulfilled'; + if (!success && results.length > 0 && results[0].status === 'rejected') { + console.warn(`⚠️ OTP/DM: NIP-17 rejected by ${relay}:`, results[0].reason); + } + return { relay, success, results, type: 'nip17' }; + } catch (error) { + console.error(`❌ OTP/DM: NIP-17 Failed to publish to ${relay}:`, error); + return { relay, success: false, error: error.message, type: 'nip17' }; + } + }); + + // Wait for all publish attempts + const results = await Promise.allSettled(publishPromises); + + const successfulResults = results.filter(result => + result.status === 'fulfilled' && result.value.success + ); + + console.log('📊 OTP/DM: Publishing summary:'); + console.log(` - Total relays attempted: ${relays.length}`); + console.log(` - NIP-17 successful publishes: ${successfulResults.length}/${relays.length}`); + console.log(` - Overall success rate: ${Math.round((successfulResults.length / relays.length) * 100)}%`); + + if (successfulResults.length > 0) { + console.log('✅ OTP/DM: NIP-17 DM sent successfully to at least one relay'); + console.log('📱 OTP/DM: Check your Nostr client for the encrypted DM'); + console.log('🔐 OTP/DM: Message uses modern NIP-44 encryption with NIP-17 gift wrapping'); + console.log('🎯 OTP/DM: This should work with all modern Nostr clients and relays'); + } else { + console.error('❌ OTP/DM: Failed to send DM to any relays'); + console.log('💡 OTP/DM: This might indicate relay connectivity issues or client compatibility problems'); + } + + // Clean up the pool safely + try { + console.log('🧹 OTP/DM: Cleaning up relay connections...'); + pool.close(relays); + console.log('🧹 OTP/DM: Pool cleanup completed'); + } catch (cleanupError) { + console.warn('⚠️ OTP/DM: Pool cleanup warning (non-critical):', cleanupError.message); + } + + // For demo purposes, also show the code in console + setTimeout(() => { + console.log(`🔐 OTP/DM: Demo - Login code sent was: ${code}`); + console.log('💡 OTP/DM: Check your Nostr DMs or use the code above for testing'); + }, 2000); + + return successfulResults.length > 0; + + } catch (error) { + console.error('💥 OTP/DM: NIP-17 implementation error:', error); + console.log('💡 OTP/DM: This might indicate a problem with the nostr-tools NIP-17 implementation'); + console.log(`🔐 OTP/DM: Fallback - Login code for testing: ${code}`); + return false; + } + } + + async _sendLegacyNip44Dm(senderSecretKey, recipientPubkey, dmContent, code) { + console.log('🔄 OTP/DM: Using legacy NIP-44 direct message format'); + + try { + // Encrypt with NIP-44 + const conversationKey = window.NostrTools.nip44.getConversationKey(senderSecretKey, recipientPubkey); + const nip44Content = window.NostrTools.nip44.encrypt(dmContent, conversationKey); + console.log('🔒 OTP/DM: NIP-44 encrypted length:', nip44Content.length, 'chars'); + + // Create NIP-44 DM event (modern approach - no custom tags) + const nip44Event = { + kind: 4, + created_at: Math.floor(Date.now() / 1000), + tags: [ + ['p', recipientPubkey] + ], + content: nip44Content + }; + + // Sign the event + const signedEvent = window.NostrTools.finalizeEvent(nip44Event, senderSecretKey); + console.log('📝 OTP/DM: NIP-44 signed event:', JSON.stringify(signedEvent, null, 2)); + + // Get relays to send to + const relays = this.options.relays || [ + 'wss://relay.damus.io', + 'wss://relay.primal.net', + 'wss://relay.laantungir.net', + 'wss://nostr.mom' + ]; + + // Create a pool and send + const pool = new window.NostrTools.nip46.SimplePool(); + const publishPromises = relays.map(async (relay, index) => { + console.log(`📡 OTP/DM: Legacy NIP-44 [${index + 1}/${relays.length}] Connecting to relay ${relay}...`); + + try { + const results = await pool.publish([relay], signedEvent); + console.log(`📡 OTP/DM: Legacy NIP-44 Raw JSON response from ${relay}:`, JSON.stringify(results, null, 2)); + + const success = results.length > 0 && results[0].status === 'fulfilled'; + if (!success && results.length > 0 && results[0].status === 'rejected') { + console.warn(`⚠️ OTP/DM: Legacy NIP-44 rejected by ${relay}:`, results[0].reason); + } + return { relay, success, results, type: 'legacy-nip44' }; + } catch (error) { + console.error(`❌ OTP/DM: Legacy NIP-44 Failed to publish to ${relay}:`, error); + return { relay, success: false, error: error.message, type: 'legacy-nip44' }; + } + }); + + const results = await Promise.allSettled(publishPromises); + const successfulResults = results.filter(result => + result.status === 'fulfilled' && result.value.success + ); + + console.log('📊 OTP/DM: Legacy publishing summary:'); + console.log(` - Legacy NIP-44 successful publishes: ${successfulResults.length}/${relays.length}`); + + pool.close(relays); + return successfulResults.length > 0; + + } catch (error) { + console.error('💥 OTP/DM: Legacy NIP-44 error:', error); + console.log(`🔐 OTP/DM: Fallback - Login code for testing: ${code}`); + return false; + } + } + + _handleOtpVerification(pubkey, enteredCode) { + if (!enteredCode || enteredCode.length !== 6) { + this._showError('Please enter a 6-digit code'); + return; + } + + const storedCode = sessionStorage.getItem(`otp_${pubkey}`); + const timestamp = parseInt(sessionStorage.getItem(`otp_${pubkey}_timestamp`) || '0'); + + // Check if code is expired (5 minutes) + if (Date.now() - timestamp > 5 * 60 * 1000) { + sessionStorage.removeItem(`otp_${pubkey}`); + sessionStorage.removeItem(`otp_${pubkey}_timestamp`); + this._showError('Login code has expired. Please request a new one.'); + return; + } + + if (enteredCode === storedCode) { + // Clean up stored code + sessionStorage.removeItem(`otp_${pubkey}`); + sessionStorage.removeItem(`otp_${pubkey}_timestamp`); + + console.log('OTP/DM: Code verified successfully'); + + // Set as read-only authentication (since we don't have the private key) + this._setAuthMethod('readonly', { pubkey }); + } else { + this._showError('Invalid login code. Please check and try again.'); + } + } + + _getButtonStyle(type = 'primary') { + const baseStyle = ` + display: block; + width: 100%; + padding: 12px; + border: none; + border-radius: 8px; + font-size: 16px; + font-weight: 500; + cursor: pointer; + transition: all 0.2s; + `; + + if (type === 'primary') { + return baseStyle + ` + background: #3b82f6; + color: white; + `; + } else { + return baseStyle + ` + background: #6b7280; + color: white; + `; + } + } + + // Public API + static init(options) { + if (Modal.instance) return Modal.instance; + Modal.instance = new Modal(options); + return Modal.instance; + } + + static getInstance() { + return Modal.instance; + } +} + +// Initialize global instance +let modalInstance = null; + +window.addEventListener('load', () => { + modalInstance = new Modal(); +}); + + +// ====================================== +// Main NOSTR_LOGIN_LITE Library +// ====================================== + +// Extension Bridge for managing browser extensions +class ExtensionBridge { + constructor() { + this.extensions = new Map(); + this.primaryExtension = null; + this._detectExtensions(); + } + + _detectExtensions() { + // Common extension locations + const locations = [ + { path: 'window.nostr', name: 'Generic' }, + { path: 'window.alby?.nostr', name: 'Alby' }, + { path: 'window.nos2x?.nostr', name: 'nos2x' }, + { path: 'window.flamingo?.nostr', name: 'Flamingo' }, + { path: 'window.getAlby?.nostr', name: 'Alby Legacy' }, + { path: 'window.mutiny?.nostr', name: 'Mutiny' } + ]; + + for (const location of locations) { + try { + const obj = eval(location.path); + if (obj && typeof obj.getPublicKey === 'function') { + this.extensions.set(location.name, { + name: location.name, + extension: obj, + constructor: obj.constructor?.name || 'Unknown' + }); + + if (!this.primaryExtension) { + this.primaryExtension = this.extensions.get(location.name); + } + } + } catch (e) { + // Extension not available + } + } + } + + getAllExtensions() { + return Array.from(this.extensions.values()); + } + + getExtensionCount() { + return this.extensions.size; + } +} + +// Main NostrLite class +class NostrLite { + constructor() { + this.options = {}; + this.extensionBridge = new ExtensionBridge(); + this.initialized = false; + } + + async init(options = {}) { + console.log('NOSTR_LOGIN_LITE: Initializing with options:', options); + + this.options = { + theme: 'light', + darkMode: false, + relays: ['wss://relay.damus.io', 'wss://nos.lol'], + methods: { + extension: true, + local: true, + readonly: true, + connect: false, + otp: false + }, + ...options + }; + + // Set up window.nostr facade if no extension detected + if (this.extensionBridge.getExtensionCount() === 0) { + this._setupWindowNostrFacade(); + } + + this.initialized = true; + console.log('NOSTR_LOGIN_LITE: Initialization complete'); + + // Set up event listeners for authentication flow + this._setupAuthEventHandlers(); + + return this; + } + + _setupWindowNostrFacade() { + if (typeof window !== 'undefined' && !window.nostr) { + window.nostr = new WindowNostr(this); + console.log('NOSTR_LOGIN_LITE: window.nostr facade installed'); + } + } + + _setupAuthEventHandlers() { + if (typeof window === 'undefined') return; + + // Listen for authentication method selection + window.addEventListener('nlMethodSelected', async (event) => { + console.log('NOSTR_LOGIN_LITE: Authentication method selected:', event.detail); + + const { method, pubkey, signer, extension, secret } = event.detail; + + try { + // Complete the authentication flow + await this._completeAuthentication(method, event.detail); + } catch (error) { + console.error('NOSTR_LOGIN_LITE: Authentication completion failed:', error); + this._dispatchAuthEvent('nlAuthFailed', { error: error.message }); + } + }); + } + + async _completeAuthentication(method, authData) { + console.log('NOSTR_LOGIN_LITE: Completing authentication for method:', method); + + const authResult = { + method, + pubkey: authData.pubkey, + timestamp: Date.now() + }; + + // Add method-specific data + switch (method) { + case 'extension': + authResult.extension = authData.extension; + break; + case 'local': + authResult.secret = authData.secret; + break; + case 'nip46': + authResult.signer = authData.signer; + authResult.remotePubkey = authData.signer.remotePubkey; + break; + case 'readonly': + // No additional data needed + break; + } + + // Store authentication state + if (typeof localStorage !== 'undefined') { + localStorage.setItem('nl_current', JSON.stringify({ + method, + pubkey: authData.pubkey, + timestamp: Date.now() + })); + } + + console.log('NOSTR_LOGIN_LITE: Authentication completed successfully'); + console.log('NOSTR_LOGIN_LITE: User pubkey:', authData.pubkey); + + // Fetch and display profile information + await this._fetchAndDisplayProfile(authData.pubkey); + + // Dispatch success event + this._dispatchAuthEvent('nlAuth', authResult); + } + + async _fetchAndDisplayProfile(pubkey) { + console.log('NOSTR_LOGIN_LITE: Fetching profile for pubkey:', pubkey); + + try { + // Create a simple pool for fetching profile + const pool = new window.NostrTools.SimplePool(); + const relays = this.options.relays || ['wss://relay.damus.io', 'wss://nos.lol']; + + console.log('NOSTR_LOGIN_LITE: Querying relays for profile:', relays); + + // Fetch profile metadata (kind 0) + const profileEvents = await pool.querySync(relays, { + kinds: [0], + authors: [pubkey], + limit: 1 + }); + + pool.close(relays); + + if (profileEvents && profileEvents.length > 0) { + const profileEvent = profileEvents[0]; + const profile = JSON.parse(profileEvent.content); + + console.log('NOSTR_LOGIN_LITE: Profile fetched successfully:', profile); + + // Display profile information + this._displayProfileInfo(pubkey, profile); + } else { + console.log('NOSTR_LOGIN_LITE: No profile found, displaying pubkey only'); + this._displayProfileInfo(pubkey, null); + } + + } catch (error) { + console.error('NOSTR_LOGIN_LITE: Failed to fetch profile:', error); + this._displayProfileInfo(pubkey, null); + } + } + + _displayProfileInfo(pubkey, profile) { + console.log('NOSTR_LOGIN_LITE: Displaying profile info'); + + // Create or update profile display + let profileDiv = document.getElementById('nl-profile-info'); + if (!profileDiv) { + profileDiv = document.createElement('div'); + profileDiv.id = 'nl-profile-info'; + profileDiv.style.cssText = ` + position: fixed; + top: 20px; + right: 20px; + background: white; + border: 1px solid #d1d5db; + border-radius: 8px; + padding: 16px; + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); + z-index: 9999; + max-width: 300px; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + `; + document.body.appendChild(profileDiv); + } + + const npub = window.NostrTools.nip19.npubEncode(pubkey); + const shortPubkey = `${pubkey.slice(0, 8)}...${pubkey.slice(-8)}`; + + profileDiv.innerHTML = ` +
+
+
+
Logged In
+
NOSTR_LOGIN_LITE
+
+
+ + ${profile ? ` +
+
${profile.name || 'Anonymous'}
+ ${profile.about ? `
${profile.about.slice(0, 100)}${profile.about.length > 100 ? '...' : ''}
` : ''} +
+ ` : ''} + +
+ Pubkey: ${shortPubkey} +
+ +
+ npub: ${npub.slice(0, 12)}...${npub.slice(-8)} +
+ + + `; + + console.log('NOSTR_LOGIN_LITE: Profile display updated'); + } + + _dispatchAuthEvent(eventName, data) { + if (typeof window !== 'undefined') { + window.dispatchEvent(new CustomEvent(eventName, { + detail: data + })); + console.log('NOSTR_LOGIN_LITE: Dispatched event:', eventName, data); + } + } + + launch(startScreen = 'login') { + console.log('NOSTR_LOGIN_LITE: Launching with screen:', startScreen); + + if (typeof Modal !== 'undefined') { + const modal = new Modal(this.options); + modal.open({ startScreen }); + } else { + console.error('NOSTR_LOGIN_LITE: Modal component not available'); + } + } + + logout() { + console.log('NOSTR_LOGIN_LITE: Logout called'); + + // Clear stored data + if (typeof localStorage !== 'undefined') { + localStorage.removeItem('nl_current'); + } + + // Dispatch logout event + if (typeof window !== 'undefined') { + window.dispatchEvent(new CustomEvent('nlLogout', { + detail: { timestamp: Date.now() } + })); + } + } +} + +// Window.nostr facade for when no extension is available +class WindowNostr { + constructor(nostrLite) { + this.nostrLite = nostrLite; + } + + async getPublicKey() { + throw new Error('Authentication required - use NOSTR_LOGIN_LITE.launch()'); + } + + async signEvent(event) { + throw new Error('Authentication required - use NOSTR_LOGIN_LITE.launch()'); + } + + async getRelays() { + throw new Error('Authentication required - use NOSTR_LOGIN_LITE.launch()'); + } + + get nip04() { + return { + async encrypt(pubkey, plaintext) { + throw new Error('Authentication required - use NOSTR_LOGIN_LITE.launch()'); + }, + async decrypt(pubkey, ciphertext) { + throw new Error('Authentication required - use NOSTR_LOGIN_LITE.launch()'); + } + }; + } + + get nip44() { + return { + async encrypt(pubkey, plaintext) { + throw new Error('Authentication required - use NOSTR_LOGIN_LITE.launch()'); + }, + async decrypt(pubkey, ciphertext) { + throw new Error('Authentication required - use NOSTR_LOGIN_LITE.launch()'); + } + }; + } +} + +// Initialize and export +if (typeof window !== 'undefined') { + const nostrLite = new NostrLite(); + + // Export main API + window.NOSTR_LOGIN_LITE = { + init: (options) => nostrLite.init(options), + launch: (startScreen) => nostrLite.launch(startScreen), + logout: () => nostrLite.logout(), + + // Expose for debugging + _extensionBridge: nostrLite.extensionBridge, + _instance: nostrLite + }; + + console.log('NOSTR_LOGIN_LITE: Library loaded and ready'); + console.log('NOSTR_LOGIN_LITE: Use window.NOSTR_LOGIN_LITE.init(options) to initialize'); + console.log('NOSTR_LOGIN_LITE: Detected', nostrLite.extensionBridge.getExtensionCount(), 'browser extensions'); +} else { + // Node.js environment + module.exports = { NostrLite }; +} diff --git a/lite/nostr-login-lite.bundle.js b/lite/nostr-login-lite.bundle.js deleted file mode 100644 index e5274e2..0000000 --- a/lite/nostr-login-lite.bundle.js +++ /dev/null @@ -1,2541 +0,0 @@ -/** - * NOSTR_LOGIN_LITE - * Single-file Nostr authentication library - * Generated on: 2025-09-13T13:54:03.650Z - */ - -// ====================================== -// Core Classes and Components -// ====================================== - -// ====================================== -// modal.js -// ====================================== - - -class Modal { - constructor(options) { - this.options = options; - this.container = null; - this.isVisible = false; - this.currentScreen = null; - - // Initialize modal container and styles - this._initModal(); - } - - _initModal() { - // Create modal container - this.container = document.createElement('div'); - this.container.id = 'nl-modal'; - this.container.style.cssText = ` - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: rgba(0, 0, 0, 0.75); - display: none; - z-index: 10000; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; - `; - - // Create modal content - const modalContent = document.createElement('div'); - modalContent.style.cssText = ` - position: relative; - background: white; - width: 90%; - max-width: 400px; - margin: 50px auto; - border-radius: 12px; - box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); - max-height: 600px; - overflow: hidden; - `; - - // Header - const modalHeader = document.createElement('div'); - modalHeader.style.cssText = ` - padding: 20px 24px 0 24px; - display: flex; - justify-content: space-between; - align-items: center; - `; - - const modalTitle = document.createElement('h2'); - modalTitle.textContent = 'Nostr Login'; - modalTitle.style.cssText = ` - margin: 0; - font-size: 24px; - font-weight: 600; - color: #1f2937; - `; - - const closeButton = document.createElement('button'); - closeButton.innerHTML = '×'; - closeButton.onclick = () => this.close(); - closeButton.style.cssText = ` - background: none; - border: none; - font-size: 28px; - color: #6b7280; - cursor: pointer; - padding: 0; - width: 32px; - height: 32px; - display: flex; - align-items: center; - justify-content: center; - border-radius: 6px; - `; - closeButton.onmouseover = () => closeButton.style.background = '#f3f4f6'; - closeButton.onmouseout = () => closeButton.style.background = 'none'; - - modalHeader.appendChild(modalTitle); - modalHeader.appendChild(closeButton); - - // Body - this.modalBody = document.createElement('div'); - this.modalBody.style.cssText = ` - padding: 24px; - overflow-y: auto; - max-height: 500px; - `; - - modalContent.appendChild(modalHeader); - modalContent.appendChild(this.modalBody); - this.container.appendChild(modalContent); - - // Add to body - document.body.appendChild(this.container); - - // Click outside to close - this.container.onclick = (e) => { - if (e.target === this.container) { - this.close(); - } - }; - - // Update theme - this.updateTheme(); - } - - updateTheme() { - const isDark = this.options?.darkMode; - const modalContent = this.container.querySelector(':nth-child(1)'); - const title = this.container.querySelector('h2'); - - if (isDark) { - modalContent.style.background = '#1f2937'; - title.style.color = 'white'; - } else { - modalContent.style.background = 'white'; - title.style.color = '#1f2937'; - } - } - - open(opts = {}) { - this.currentScreen = opts.startScreen; - this.isVisible = true; - this.container.style.display = 'block'; - - // Render login options - this._renderLoginOptions(); - } - - close() { - this.isVisible = false; - this.container.style.display = 'none'; - this.modalBody.innerHTML = ''; - } - - _renderLoginOptions() { - this.modalBody.innerHTML = ''; - - const options = []; - - // Extension option - if (this.options?.methods?.extension !== false) { - options.push({ - type: 'extension', - title: 'Browser Extension', - description: 'Use your browser extension', - icon: '🔌' - }); - } - - // Local key option - if (this.options?.methods?.local !== false) { - options.push({ - type: 'local', - title: 'Local Key', - description: 'Create or import your own key', - icon: '🔑' - }); - } - - // Nostr Connect option - if (this.options?.methods?.connect !== false) { - options.push({ - type: 'connect', - title: 'Nostr Connect', - description: 'Connect with external signer', - icon: '🌐' - }); - } - - // Read-only option - if (this.options?.methods?.readonly !== false) { - options.push({ - type: 'readonly', - title: 'Read Only', - description: 'Browse without signing', - icon: '👁️' - }); - } - - // OTP/DM option - if (this.options?.methods?.otp !== false && this.options?.otp) { - options.push({ - type: 'otp', - title: 'DM/OTP', - description: 'Receive OTP via DM', - icon: '📱' - }); - } - - // Render each option - options.forEach(option => { - const button = document.createElement('button'); - button.onclick = () => this._handleOptionClick(option.type); - button.style.cssText = ` - display: flex; - align-items: center; - width: 100%; - padding: 16px; - margin-bottom: 12px; - background: ${this.options?.darkMode ? '#374151' : 'white'}; - border: 1px solid ${this.options?.darkMode ? '#4b5563' : '#d1d5db'}; - border-radius: 8px; - cursor: pointer; - transition: all 0.2s; - `; - button.onmouseover = () => { - button.style.boxShadow = '0 4px 6px -1px rgba(0, 0, 0, 0.1)'; - }; - button.onmouseout = () => { - button.style.boxShadow = 'none'; - }; - - const iconDiv = document.createElement('div'); - iconDiv.textContent = option.icon; - iconDiv.style.cssText = ` - font-size: 24px; - margin-right: 16px; - width: 24px; - text-align: center; - `; - - const contentDiv = document.createElement('div'); - contentDiv.style.cssText = 'flex: 1; text-align: left;'; - - const titleDiv = document.createElement('div'); - titleDiv.textContent = option.title; - titleDiv.style.cssText = ` - font-weight: 600; - margin-bottom: 4px; - color: ${this.options?.darkMode ? 'white' : '#1f2937'}; - `; - - const descDiv = document.createElement('div'); - descDiv.textContent = option.description; - descDiv.style.cssText = ` - font-size: 14px; - color: ${this.options?.darkMode ? '#9ca3af' : '#6b7280'}; - `; - - contentDiv.appendChild(titleDiv); - contentDiv.appendChild(descDiv); - - button.appendChild(iconDiv); - button.appendChild(contentDiv); - this.modalBody.appendChild(button); - }); - } - - _handleOptionClick(type) { - console.log('Selected login type:', type); - - // Handle different login types - switch (type) { - case 'extension': - this._handleExtension(); - break; - case 'local': - this._showLocalKeyScreen(); - break; - case 'connect': - this._showConnectScreen(); - break; - case 'readonly': - this._handleReadonly(); - break; - case 'otp': - this._showOtpScreen(); - break; - } - } - - _handleExtension() { - // Detect all available real extensions - const availableExtensions = this._detectAllExtensions(); - - console.log(`Modal: Found ${availableExtensions.length} extensions:`, availableExtensions.map(e => e.displayName)); - - if (availableExtensions.length === 0) { - console.log('Modal: No real extensions found'); - this._showExtensionRequired(); - } else if (availableExtensions.length === 1) { - // Single extension - use it directly without showing choice UI - console.log('Modal: Single extension detected, using it directly:', availableExtensions[0].displayName); - this._tryExtensionLogin(availableExtensions[0].extension); - } else { - // Multiple extensions - show choice UI - console.log('Modal: Multiple extensions detected, showing choice UI for', availableExtensions.length, 'extensions'); - this._showExtensionChoice(availableExtensions); - } - } - - _detectAllExtensions() { - const extensions = []; - const seenExtensions = new Set(); // Track extensions by object reference to avoid duplicates - - // Extension locations to check (in priority order) - const locations = [ - { path: 'window.navigator?.nostr', name: 'navigator.nostr', displayName: 'Standard Extension (navigator.nostr)', icon: '🌐', getter: () => window.navigator?.nostr }, - { path: 'window.webln?.nostr', name: 'webln.nostr', displayName: 'Alby WebLN Extension', icon: '⚡', getter: () => window.webln?.nostr }, - { path: 'window.alby?.nostr', name: 'alby.nostr', displayName: 'Alby Extension (Direct)', icon: '🐝', getter: () => window.alby?.nostr }, - { path: 'window.nos2x', name: 'nos2x', displayName: 'nos2x Extension', icon: '🔌', getter: () => window.nos2x }, - { path: 'window.flamingo?.nostr', name: 'flamingo.nostr', displayName: 'Flamingo Extension', icon: '🦩', getter: () => window.flamingo?.nostr }, - { path: 'window.mutiny?.nostr', name: 'mutiny.nostr', displayName: 'Mutiny Extension', icon: '⚔️', getter: () => window.mutiny?.nostr }, - { path: 'window.nostrich?.nostr', name: 'nostrich.nostr', displayName: 'Nostrich Extension', icon: '🐦', getter: () => window.nostrich?.nostr }, - { path: 'window.getAlby?.nostr', name: 'getAlby.nostr', displayName: 'getAlby Extension', icon: '🔧', getter: () => window.getAlby?.nostr } - ]; - - // Check each location - for (const location of locations) { - try { - const obj = location.getter(); - - console.log(`Modal: Checking ${location.name}:`, !!obj, obj?.constructor?.name); - - if (obj && this._isRealExtension(obj) && !seenExtensions.has(obj)) { - extensions.push({ - name: location.name, - displayName: location.displayName, - icon: location.icon, - extension: obj - }); - seenExtensions.add(obj); - console.log(`Modal: ✓ Detected extension at ${location.name} (${obj.constructor?.name})`); - } else if (obj) { - console.log(`Modal: ✗ Filtered out ${location.name} (${obj.constructor?.name})`); - } - } catch (e) { - // Location doesn't exist or can't be accessed - console.log(`Modal: ${location.name} not accessible:`, e.message); - } - } - - // Also check window.nostr but be extra careful to avoid our library - console.log('Modal: Checking window.nostr:', !!window.nostr, window.nostr?.constructor?.name); - if (window.nostr && this._isRealExtension(window.nostr) && !seenExtensions.has(window.nostr)) { - extensions.push({ - name: 'window.nostr', - displayName: 'Extension (window.nostr)', - icon: '🔑', - extension: window.nostr - }); - seenExtensions.add(window.nostr); - console.log(`Modal: ✓ Detected extension at window.nostr: ${window.nostr.constructor?.name}`); - } else if (window.nostr) { - console.log(`Modal: ✗ Filtered out window.nostr (${window.nostr.constructor?.name}) - likely our library`); - } - - return extensions; - } - - _isRealExtension(obj) { - console.log(`Modal: EXTENSIVE DEBUG - _isRealExtension called with:`, obj); - console.log(`Modal: Object type: ${typeof obj}`); - console.log(`Modal: Object truthy: ${!!obj}`); - - if (!obj || typeof obj !== 'object') { - console.log(`Modal: REJECT - Not an object`); - return false; - } - - console.log(`Modal: getPublicKey type: ${typeof obj.getPublicKey}`); - console.log(`Modal: signEvent type: ${typeof obj.signEvent}`); - - // Must have required Nostr methods - if (typeof obj.getPublicKey !== 'function' || typeof obj.signEvent !== 'function') { - console.log(`Modal: REJECT - Missing required methods`); - return false; - } - - // Exclude NostrTools library object - if (obj === window.NostrTools) { - console.log(`Modal: REJECT - Is NostrTools object`); - return false; - } - - // Use the EXACT SAME logic as the comprehensive test (lines 804-809) - // This is the key fix - match the comprehensive test's successful detection logic - const constructorName = obj.constructor?.name; - const objectKeys = Object.keys(obj); - - console.log(`Modal: Constructor name: "${constructorName}"`); - console.log(`Modal: Object keys: [${objectKeys.join(', ')}]`); - - // COMPREHENSIVE TEST LOGIC - Accept anything with required methods that's not our specific library classes - const isRealExtension = ( - typeof obj.getPublicKey === 'function' && - typeof obj.signEvent === 'function' && - constructorName !== 'WindowNostr' && // Our library class - constructorName !== 'NostrLite' // Our main class - ); - - console.log(`Modal: Using comprehensive test logic:`); - console.log(` Has getPublicKey: ${typeof obj.getPublicKey === 'function'}`); - console.log(` Has signEvent: ${typeof obj.signEvent === 'function'}`); - console.log(` Not WindowNostr: ${constructorName !== 'WindowNostr'}`); - console.log(` Not NostrLite: ${constructorName !== 'NostrLite'}`); - console.log(` Constructor: "${constructorName}"`); - - // Additional debugging for comparison - const extensionPropChecks = { - _isEnabled: !!obj._isEnabled, - enabled: !!obj.enabled, - kind: !!obj.kind, - _eventEmitter: !!obj._eventEmitter, - _scope: !!obj._scope, - _requests: !!obj._requests, - _pubkey: !!obj._pubkey, - name: !!obj.name, - version: !!obj.version, - description: !!obj.description - }; - - console.log(`Modal: Extension property analysis:`, extensionPropChecks); - - const hasExtensionProps = !!( - obj._isEnabled || obj.enabled || obj.kind || - obj._eventEmitter || obj._scope || obj._requests || obj._pubkey || - obj.name || obj.version || obj.description - ); - - const underscoreKeys = objectKeys.filter(key => key.startsWith('_')); - const hexToUint8Keys = objectKeys.filter(key => key.startsWith('_hex')); - console.log(`Modal: Underscore keys: [${underscoreKeys.join(', ')}]`); - console.log(`Modal: _hex* keys: [${hexToUint8Keys.join(', ')}]`); - - console.log(`Modal: Additional analysis:`); - console.log(` hasExtensionProps: ${hasExtensionProps}`); - console.log(` hasLibraryMethod (_hexToUint8Array): ${objectKeys.includes('_hexToUint8Array')}`); - - console.log(`Modal: COMPREHENSIVE TEST LOGIC RESULT: ${isRealExtension ? 'ACCEPT' : 'REJECT'}`); - console.log(`Modal: FINAL DECISION for ${constructorName}: ${isRealExtension ? 'ACCEPT' : 'REJECT'}`); - - return isRealExtension; - } - - _showExtensionChoice(extensions) { - this.modalBody.innerHTML = ''; - - const title = document.createElement('h3'); - title.textContent = 'Choose Browser Extension'; - title.style.cssText = 'margin: 0 0 16px 0; font-size: 18px; font-weight: 600;'; - - const description = document.createElement('p'); - description.textContent = `Found ${extensions.length} Nostr extensions. Choose which one to use:`; - description.style.cssText = 'margin-bottom: 20px; color: #6b7280; font-size: 14px;'; - - this.modalBody.appendChild(title); - this.modalBody.appendChild(description); - - // Create button for each extension - extensions.forEach((ext, index) => { - const button = document.createElement('button'); - button.onclick = () => this._tryExtensionLogin(ext.extension); - button.style.cssText = ` - display: flex; - align-items: center; - width: 100%; - padding: 16px; - margin-bottom: 12px; - background: ${this.options?.darkMode ? '#374151' : 'white'}; - border: 1px solid ${this.options?.darkMode ? '#4b5563' : '#d1d5db'}; - border-radius: 8px; - cursor: pointer; - transition: all 0.2s; - text-align: left; - `; - - button.onmouseover = () => { - button.style.boxShadow = '0 4px 6px -1px rgba(0, 0, 0, 0.1)'; - button.style.transform = 'translateY(-1px)'; - }; - button.onmouseout = () => { - button.style.boxShadow = 'none'; - button.style.transform = 'none'; - }; - - const iconDiv = document.createElement('div'); - iconDiv.textContent = ext.icon; - iconDiv.style.cssText = ` - font-size: 24px; - margin-right: 16px; - width: 24px; - text-align: center; - `; - - const contentDiv = document.createElement('div'); - contentDiv.style.cssText = 'flex: 1;'; - - const nameDiv = document.createElement('div'); - nameDiv.textContent = ext.displayName; - nameDiv.style.cssText = ` - font-weight: 600; - margin-bottom: 4px; - color: ${this.options?.darkMode ? 'white' : '#1f2937'}; - `; - - const pathDiv = document.createElement('div'); - pathDiv.textContent = ext.name; - pathDiv.style.cssText = ` - font-size: 12px; - color: ${this.options?.darkMode ? '#9ca3af' : '#6b7280'}; - font-family: monospace; - `; - - contentDiv.appendChild(nameDiv); - contentDiv.appendChild(pathDiv); - - button.appendChild(iconDiv); - button.appendChild(contentDiv); - this.modalBody.appendChild(button); - }); - - // Add back button - const backButton = document.createElement('button'); - backButton.textContent = 'Back to Login Options'; - backButton.onclick = () => this._renderLoginOptions(); - backButton.style.cssText = this._getButtonStyle('secondary') + 'margin-top: 20px;'; - - this.modalBody.appendChild(backButton); - } - - async _tryExtensionLogin(extensionObj) { - try { - // Show loading state - this.modalBody.innerHTML = '
🔄 Connecting to extension...
'; - - // Get pubkey from extension - const pubkey = await extensionObj.getPublicKey(); - console.log('Extension provided pubkey:', pubkey); - - // Set extension method with the extension object - this._setAuthMethod('extension', { pubkey, extension: extensionObj }); - - } catch (error) { - console.error('Extension login failed:', error); - this._showError(`Extension login failed: ${error.message}`); - } - } - - _showLocalKeyScreen() { - this.modalBody.innerHTML = ''; - - const title = document.createElement('h3'); - title.textContent = 'Local Key'; - title.style.cssText = 'margin: 0 0 20px 0; font-size: 18px; font-weight: 600;'; - - const createButton = document.createElement('button'); - createButton.textContent = 'Create New Key'; - createButton.onclick = () => this._createLocalKey(); - createButton.style.cssText = this._getButtonStyle(); - - const importButton = document.createElement('button'); - importButton.textContent = 'Import Existing Key'; - importButton.onclick = () => this._showImportKeyForm(); - importButton.style.cssText = this._getButtonStyle() + 'margin-top: 12px;'; - - const backButton = document.createElement('button'); - backButton.textContent = 'Back'; - backButton.onclick = () => this._renderLoginOptions(); - backButton.style.cssText = ` - display: block; - margin-top: 20px; - padding: 12px; - background: #6b7280; - color: white; - border: none; - border-radius: 6px; - cursor: pointer; - `; - - this.modalBody.appendChild(title); - this.modalBody.appendChild(createButton); - this.modalBody.appendChild(importButton); - this.modalBody.appendChild(backButton); - } - - _createLocalKey() { - try { - const sk = window.NostrTools.generateSecretKey(); - const pk = window.NostrTools.getPublicKey(sk); - const nsec = window.NostrTools.nip19.nsecEncode(sk); - const npub = window.NostrTools.nip19.npubEncode(pk); - - this._showKeyDisplay(pk, nsec, 'created'); - } catch (error) { - this._showError('Failed to create key: ' + error.message); - } - } - - _showImportKeyForm() { - this.modalBody.innerHTML = ''; - - const title = document.createElement('h3'); - title.textContent = 'Import Local Key'; - title.style.cssText = 'margin: 0 0 16px 0; font-size: 18px; font-weight: 600;'; - - const description = document.createElement('p'); - description.textContent = 'Enter your secret key in either nsec or hex format:'; - description.style.cssText = 'margin-bottom: 12px; color: #6b7280; font-size: 14px;'; - - const textarea = document.createElement('textarea'); - textarea.placeholder = 'Enter your secret key:\n• nsec1... (bech32 format)\n• 64-character hex string'; - textarea.style.cssText = ` - width: 100%; - height: 100px; - padding: 12px; - border: 1px solid #d1d5db; - border-radius: 6px; - margin-bottom: 12px; - resize: none; - font-family: monospace; - font-size: 14px; - box-sizing: border-box; - `; - - // Add real-time format detection - const formatHint = document.createElement('div'); - formatHint.style.cssText = 'margin-bottom: 16px; font-size: 12px; color: #6b7280; min-height: 16px;'; - - textarea.oninput = () => { - const value = textarea.value.trim(); - if (!value) { - formatHint.textContent = ''; - return; - } - - const format = this._detectKeyFormat(value); - if (format === 'nsec') { - formatHint.textContent = '✅ Valid nsec format detected'; - formatHint.style.color = '#059669'; - } else if (format === 'hex') { - formatHint.textContent = '✅ Valid hex format detected'; - formatHint.style.color = '#059669'; - } else { - formatHint.textContent = '❌ Invalid key format - must be nsec1... or 64-character hex'; - formatHint.style.color = '#dc2626'; - } - }; - - const importButton = document.createElement('button'); - importButton.textContent = 'Import Key'; - importButton.onclick = () => this._importLocalKey(textarea.value); - importButton.style.cssText = this._getButtonStyle(); - - const backButton = document.createElement('button'); - backButton.textContent = 'Back'; - backButton.onclick = () => this._showLocalKeyScreen(); - backButton.style.cssText = this._getButtonStyle('secondary') + 'margin-top: 12px;'; - - this.modalBody.appendChild(title); - this.modalBody.appendChild(description); - this.modalBody.appendChild(textarea); - this.modalBody.appendChild(formatHint); - this.modalBody.appendChild(importButton); - this.modalBody.appendChild(backButton); - } - - _detectKeyFormat(keyValue) { - const trimmed = keyValue.trim(); - - // Check for nsec format - if (trimmed.startsWith('nsec1') && trimmed.length === 63) { - try { - window.NostrTools.nip19.decode(trimmed); - return 'nsec'; - } catch { - return 'invalid'; - } - } - - // Check for hex format (64 characters, valid hex) - if (trimmed.length === 64 && /^[a-fA-F0-9]{64}$/.test(trimmed)) { - return 'hex'; - } - - return 'invalid'; - } - - _importLocalKey(keyValue) { - try { - const trimmed = keyValue.trim(); - if (!trimmed) { - throw new Error('Please enter a secret key'); - } - - const format = this._detectKeyFormat(trimmed); - let sk; - - if (format === 'nsec') { - // Decode nsec format - this returns Uint8Array - const decoded = window.NostrTools.nip19.decode(trimmed); - if (decoded.type !== 'nsec') { - throw new Error('Invalid nsec format'); - } - sk = decoded.data; // This is already Uint8Array - } else if (format === 'hex') { - // Convert hex string to Uint8Array - sk = this._hexToUint8Array(trimmed); - // Test that it's a valid secret key by trying to get public key - window.NostrTools.getPublicKey(sk); - } else { - throw new Error('Invalid key format. Please enter either nsec1... or 64-character hex string'); - } - - // Generate public key and encoded formats - const pk = window.NostrTools.getPublicKey(sk); - const nsec = window.NostrTools.nip19.nsecEncode(sk); - const npub = window.NostrTools.nip19.npubEncode(pk); - - this._showKeyDisplay(pk, nsec, 'imported'); - } catch (error) { - this._showError('Invalid key: ' + error.message); - } - } - - _hexToUint8Array(hex) { - // Convert hex string to Uint8Array - if (hex.length % 2 !== 0) { - throw new Error('Invalid hex string length'); - } - const bytes = new Uint8Array(hex.length / 2); - for (let i = 0; i < bytes.length; i++) { - bytes[i] = parseInt(hex.substr(i * 2, 2), 16); - } - return bytes; - } - - _showKeyDisplay(pubkey, nsec, action) { - this.modalBody.innerHTML = ''; - - const title = document.createElement('h3'); - title.textContent = `Key ${action} successfully!`; - title.style.cssText = 'margin: 0 0 16px 0; font-size: 18px; font-weight: 600; color: #059669;'; - - const warningDiv = document.createElement('div'); - warningDiv.textContent = '⚠️ Save your secret key securely!'; - warningDiv.style.cssText = 'background: #fef3c7; color: #92400e; padding: 12px; border-radius: 6px; margin-bottom: 16px; font-size: 14px;'; - - const nsecDiv = document.createElement('div'); - nsecDiv.innerHTML = `Your Secret Key:
${nsec}`; - nsecDiv.style.cssText = 'margin-bottom: 16px; font-size: 14px;'; - - const npubDiv = document.createElement('div'); - npubDiv.innerHTML = `Your Public Key:
${window.NostrTools.nip19.npubEncode(pubkey)}`; - npubDiv.style.cssText = 'margin-bottom: 16px; font-size: 14px;'; - - const continueButton = document.createElement('button'); - continueButton.textContent = 'Continue'; - continueButton.onclick = () => this._setAuthMethod('local', { secret: nsec, pubkey }); - continueButton.style.cssText = this._getButtonStyle(); - - this.modalBody.appendChild(title); - this.modalBody.appendChild(warningDiv); - this.modalBody.appendChild(nsecDiv); - this.modalBody.appendChild(npubDiv); - this.modalBody.appendChild(continueButton); - } - - _setAuthMethod(method, options = {}) { - // Emit auth method selection - const event = new CustomEvent('nlMethodSelected', { - detail: { method, ...options } - }); - window.dispatchEvent(event); - - this.close(); - } - - _showError(message) { - this.modalBody.innerHTML = ''; - - const errorDiv = document.createElement('div'); - errorDiv.style.cssText = 'background: #fee2e2; color: #dc2626; padding: 16px; border-radius: 6px; margin-bottom: 16px;'; - errorDiv.innerHTML = `Error: ${message}`; - - const backButton = document.createElement('button'); - backButton.textContent = 'Back'; - backButton.onclick = () => this._renderLoginOptions(); - backButton.style.cssText = this._getButtonStyle('secondary'); - - this.modalBody.appendChild(errorDiv); - this.modalBody.appendChild(backButton); - } - - _showExtensionRequired() { - this.modalBody.innerHTML = ''; - - const title = document.createElement('h3'); - title.textContent = 'Browser Extension Required'; - title.style.cssText = 'margin: 0 0 16px 0; font-size: 18px; font-weight: 600;'; - - const message = document.createElement('p'); - message.textContent = 'Please install a Nostr browser extension like Alby or getflattr and refresh the page.'; - message.style.cssText = 'margin-bottom: 20px; color: #6b7280;'; - - const backButton = document.createElement('button'); - backButton.textContent = 'Back'; - backButton.onclick = () => this._renderLoginOptions(); - backButton.style.cssText = this._getButtonStyle('secondary'); - - this.modalBody.appendChild(title); - this.modalBody.appendChild(message); - this.modalBody.appendChild(backButton); - } - - _showConnectScreen() { - this.modalBody.innerHTML = ''; - - const title = document.createElement('h3'); - title.textContent = 'Connect to NIP-46 Remote Signer'; - title.style.cssText = 'margin: 0 0 16px 0; font-size: 18px; font-weight: 600;'; - - const description = document.createElement('p'); - description.textContent = 'Connect to a remote signer (bunker) server to use its keys for signing.'; - description.style.cssText = 'margin-bottom: 20px; color: #6b7280; font-size: 14px;'; - - const formGroup = document.createElement('div'); - formGroup.style.cssText = 'margin-bottom: 20px;'; - - const label = document.createElement('label'); - label.textContent = 'Bunker Public Key:'; - label.style.cssText = 'display: block; margin-bottom: 8px; font-weight: 500;'; - - const pubkeyInput = document.createElement('input'); - pubkeyInput.type = 'text'; - pubkeyInput.placeholder = 'bunker://pubkey?relay=..., bunker:hex, hex, or npub...'; - pubkeyInput.style.cssText = ` - width: 100%; - padding: 12px; - border: 1px solid #d1d5db; - border-radius: 6px; - margin-bottom: 12px; - font-family: monospace; - box-sizing: border-box; - `; - - const urlLabel = document.createElement('label'); - urlLabel.textContent = 'Remote URL (optional):'; - urlLabel.style.cssText = 'display: block; margin-bottom: 8px; font-weight: 500;'; - - const urlInput = document.createElement('input'); - urlInput.type = 'url'; - urlInput.placeholder = 'ws://localhost:8080 (default)'; - urlInput.style.cssText = ` - width: 100%; - padding: 12px; - border: 1px solid #d1d5db; - border-radius: 6px; - margin-bottom: 16px; - box-sizing: border-box; - `; - - // Pre-fill with our bunker config if available - if (window.NIP46_BUNKER_CONFIG) { - pubkeyInput.value = window.NIP46_BUNKER_CONFIG.remoteSigner.pubkey; - urlInput.value = window.NIP46_BUNKER_CONFIG.remoteSigner.url; - } - - const connectButton = document.createElement('button'); - connectButton.textContent = 'Connect to Bunker'; - connectButton.onclick = () => this._handleNip46Connect(pubkeyInput.value, urlInput.value); - connectButton.style.cssText = this._getButtonStyle(); - - const backButton = document.createElement('button'); - backButton.textContent = 'Back'; - backButton.onclick = () => this._renderLoginOptions(); - backButton.style.cssText = this._getButtonStyle('secondary') + 'margin-top: 12px;'; - - formGroup.appendChild(label); - formGroup.appendChild(pubkeyInput); - formGroup.appendChild(urlLabel); - formGroup.appendChild(urlInput); - - this.modalBody.appendChild(title); - this.modalBody.appendChild(description); - this.modalBody.appendChild(formGroup); - this.modalBody.appendChild(connectButton); - this.modalBody.appendChild(backButton); - } - - _handleNip46Connect(bunkerPubkey, bunkerUrl) { - if (!bunkerPubkey || !bunkerPubkey.length) { - this._showError('Bunker pubkey is required'); - return; - } - - this._showNip46Connecting(bunkerPubkey, bunkerUrl); - this._performNip46Connect(bunkerPubkey, bunkerUrl); - } - - _showNip46Connecting(bunkerPubkey, bunkerUrl) { - this.modalBody.innerHTML = ''; - - const title = document.createElement('h3'); - title.textContent = 'Connecting to Remote Signer...'; - title.style.cssText = 'margin: 0 0 16px 0; font-size: 18px; font-weight: 600; color: #059669;'; - - const description = document.createElement('p'); - description.textContent = 'Establishing secure connection to your remote signer.'; - description.style.cssText = 'margin-bottom: 20px; color: #6b7280;'; - - // Normalize bunker pubkey for display (= show original format if bunker: prefix) - const displayPubkey = bunkerPubkey.startsWith('bunker:') || bunkerPubkey.startsWith('npub') || bunkerPubkey.length === 64 ? bunkerPubkey : bunkerPubkey; - - const bunkerInfo = document.createElement('div'); - bunkerInfo.style.cssText = 'background: #f1f5f9; padding: 12px; border-radius: 6px; margin-bottom: 20px; font-size: 14px;'; - bunkerInfo.innerHTML = ` - Connecting to bunker:
- Pubkey: ${displayPubkey}
- Relay: ${bunkerUrl || 'ws://localhost:8080'}
- If this relay is offline, the bunker server may be unavailable. - `; - - const connectingDiv = document.createElement('div'); - connectingDiv.style.cssText = 'text-align: center; color: #6b7280;'; - connectingDiv.innerHTML = ` -
-
Please wait while we establish the connection...
-
This may take a few seconds
- `; - - this.modalBody.appendChild(title); - this.modalBody.appendChild(description); - this.modalBody.appendChild(bunkerInfo); - this.modalBody.appendChild(connectingDiv); - } - - async _performNip46Connect(bunkerPubkey, bunkerUrl) { - try { - console.log('Starting NIP-46 connection to bunker:', bunkerPubkey, bunkerUrl); - - // Check if nostr-tools NIP-46 is available - if (!window.NostrTools?.nip46) { - throw new Error('nostr-tools NIP-46 module not available'); - } - - // Use nostr-tools to parse bunker input - this handles all formats correctly - console.log('Parsing bunker input with nostr-tools...'); - const bunkerPointer = await window.NostrTools.nip46.parseBunkerInput(bunkerPubkey); - - if (!bunkerPointer) { - throw new Error('Unable to parse bunker connection string or resolve NIP-05 identifier'); - } - - console.log('Parsed bunker pointer:', bunkerPointer); - - // Create local client keypair for this session - const localSecretKey = window.NostrTools.generateSecretKey(); - console.log('Generated local client keypair for NIP-46 session'); - - // Use nostr-tools BunkerSigner.fromBunker() for bunker:// connections - console.log('Creating nip46 BunkerSigner...'); - const signer = window.NostrTools.nip46.BunkerSigner.fromBunker(localSecretKey, bunkerPointer, { - onauth: (url) => { - console.log('Received auth URL from bunker:', url); - // Open auth URL in popup or redirect - window.open(url, '_blank', 'width=600,height=800'); - } - }); - - console.log('NIP-46 BunkerSigner created successfully'); - - // Attempt initial ping to verify connection - console.log('Testing bunker connection with ping...'); - await signer.ping(); - console.log('NIP-46 ping successful - bunker is reachable'); - - // Try to connect (this may trigger auth flow) - console.log('Attempting NIP-46 connect...'); - await signer.connect(); - console.log('NIP-46 connect successful'); - - // Get the user's public key from the bunker - console.log('Getting public key from bunker...'); - const userPubkey = await signer.getPublicKey(); - console.log('NIP-46 user public key:', userPubkey); - - // Store the NIP-46 authentication info - const nip46Info = { - pubkey: userPubkey, - signer: { - method: 'nip46', - remotePubkey: bunkerPointer.pubkey, - bunkerSigner: signer, - secret: bunkerPointer.secret, - relays: bunkerPointer.relays - } - }; - - console.log('NOSTR_LOGIN_LITE NIP-46 connection established successfully!'); - - // Set as current auth method - this._setAuthMethod('nip46', nip46Info); - return; - - } catch (error) { - console.error('NIP-46 connection failed:', error); - this._showNip46Error(error.message); - } - } - - _showNip46Error(message) { - this.modalBody.innerHTML = ''; - - const title = document.createElement('h3'); - title.textContent = 'Connection Failed'; - title.style.cssText = 'margin: 0 0 16px 0; font-size: 18px; font-weight: 600; color: #dc2626;'; - - const errorMsg = document.createElement('p'); - errorMsg.textContent = `Unable to connect to remote signer: ${message}`; - errorMsg.style.cssText = 'margin-bottom: 20px; color: #6b7280;'; - - const retryButton = document.createElement('button'); - retryButton.textContent = 'Try Again'; - retryButton.onclick = () => this._showConnectScreen(); - retryButton.style.cssText = this._getButtonStyle(); - - const backButton = document.createElement('button'); - backButton.textContent = 'Back to Options'; - backButton.onclick = () => this._renderLoginOptions(); - backButton.style.cssText = this._getButtonStyle('secondary') + 'margin-top: 12px;'; - - this.modalBody.appendChild(title); - this.modalBody.appendChild(errorMsg); - this.modalBody.appendChild(retryButton); - this.modalBody.appendChild(backButton); - } - - _handleReadonly() { - // Set read-only mode - this._setAuthMethod('readonly'); - } - - _showOtpScreen() { - // Placeholder for OTP functionality - this._showError('OTP/DM not yet implemented - coming soon!'); - } - - _getButtonStyle(type = 'primary') { - const baseStyle = ` - display: block; - width: 100%; - padding: 12px; - border: none; - border-radius: 8px; - font-size: 16px; - font-weight: 500; - cursor: pointer; - transition: all 0.2s; - `; - - if (type === 'primary') { - return baseStyle + ` - background: #3b82f6; - color: white; - `; - } else { - return baseStyle + ` - background: #6b7280; - color: white; - `; - } - } - - // Public API - static init(options) { - if (Modal.instance) return Modal.instance; - Modal.instance = new Modal(options); - return Modal.instance; - } - - static getInstance() { - return Modal.instance; - } -} - -// Initialize global instance -let modalInstance = null; - -window.addEventListener('load', () => { - modalInstance = new Modal(); -}); - - -// ====================================== -// nip46-client.js -// ====================================== - - -class NIP46Client { - constructor() { - this.pool = null; - this.localSk = null; - this.localPk = null; - this.remotePk = null; - this.relays = []; - this.sub = null; - this.pendingRequests = {}; - this.useNip44 = false; - this.iframeOrigin = null; - this.iframePort = null; - } - - init(localSk, remotePk, relays, iframeOrigin) { - // Create SimplePool - this.pool = new window.NostrTools.SimplePool(); - - // Setup keys - this.localSk = localSk; - if (this.localSk) { - this.localPk = window.NostrTools.getPublicKey(this.localSk); - } - - this.remotePk = remotePk; - this.relays = [...relays]; - - // Store iframe origin for future use - this.iframeOrigin = iframeOrigin; - - console.log('NIP46Client initialized for', this.remotePk ? 'remote signer' : 'listening mode'); - } - - setUseNip44(use) { - this.useNip44 = use; - } - - subscribeReplies() { - if (!this.pool || !this.localPk) return; - - // Subscribe to replies to our pubkey on kind 24133 (NIP-46 methods) - this.sub = this.pool.sub(this.relays, [{ - kinds: [24133], - '#p': [this.localPk] - }]); - - this.sub.on('event', (event) => this.onEvent(event)); - this.sub.on('eose', () => { - console.log('NIP-46 subscription caught up'); - }); - - console.log('Subscribed to NIP-46 replies on relays:', this.relays); - } - - unsubscribe() { - if (this.sub) { - this.sub.unsub(); - this.sub = null; - } - } - - async onEvent(event) { - console.log('NIP-46 event received:', event); - - try { - const parsed = await this.parseEvent(event); - if (parsed) { - if (parsed.id && this.pendingRequests[parsed.id]) { - // Handle response - const handler = this.pendingRequests[parsed.id]; - delete this.pendingRequests[parsed.id]; - - if (parsed.result !== undefined) { - handler.resolve(parsed.result); - } else if (parsed.error) { - handler.reject(new Error(parsed.error)); - } else { - handler.reject(new Error('Invalid response format')); - } - } else if (parsed.method === 'auth_url') { - // Handle auth_url emissions (deduplication required) - this.emitAuthUrlIfNeeded(parsed.params[0]); - } - } - } catch (error) { - console.error('Error processing NIP-46 event:', error); - } - } - - emitAuthUrlIfNeeded(url) { - // Deduplicate auth_url emissions - only emit if not recently shown - const lastUrl = sessionStorage.getItem('nl-last-auth-url'); - if (lastUrl === url) { - console.log('Auth URL already shown, skipping duplicate:', url); - return; - } - - sessionStorage.setItem('nl-last-auth-url', url); - console.log('New auth URL:', url); - - // Emit event for UI - window.dispatchEvent(new CustomEvent('nlAuthUrl', { detail: { url } })); - } - - async parseEvent(event) { - try { - let content = event.content; - - // Determine encryption method based on content structure - if (content.length > 44) { - // Likely NIP-44 (encrypted) - if (this.localSk && event.pubkey) { - try { - content = window.NostrTools.nip44?.decrypt(this.localSk, event.pubkey, content); - } catch (e) { - console.warn('NIP-44 decryption failed, trying NIP-04...'); - content = await window.NostrTools.nip04.decrypt(this.localSk, event.pubkey, content); - } - } - } else { - // Likely NIP-04 - if (this.localSk && event.pubkey) { - content = await window.NostrTools.nip04.decrypt(this.localSk, event.pubkey, content); - } - } - - const payload = JSON.parse(content); - console.log('Decrypted NIP-46 payload:', payload); - - return { - id: payload.id, - method: payload.method, - params: payload.params, - result: payload.result, - error: payload.error, - event: event - }; - - } catch (e) { - console.error('Failed to parse event:', e); - return null; - } - } - - async listen(nostrConnectSecret) { - return new Promise((resolve, reject) => { - if (!this.localPk) { - reject(new Error('No local pubkey available for listening')); - return; - } - - // Subscribe to unsolicited events to our pubkey - let foundSecretOrAck = false; - - const listenSub = this.pool.sub(this.relays, [{ - kinds: [24133], - '#p': [this.localPk] - }]); - - listenSub.on('event', async (event) => { - try { - const parsed = await this.parseEvent(event); - if (parsed && parsed.method === 'connect') { - // Accept if it's an ack or matches our secret - const [userPubkey, token] = parsed.params || []; - - if (token === '' && parsed.result === 'ack') { - // Ack received - foundSecretOrAck = true; - listenSub.unsub(); - resolve(event.pubkey); - } else if (token === nostrConnectSecret) { - // Secret match - foundSecretOrAck = true; - listenSub.unsub(); - resolve(event.pubkey); - } - } - } catch (error) { - console.error('Error in listen mode:', error); - } - }); - - // Timeout after 5 minutes - setTimeout(() => { - if (!foundSecretOrAck) { - listenSub.unsub(); - reject(new Error('Listen timeout - no signer connected')); - } - }, 300000); - }); - } - - async connect(token, perms) { - return new Promise(async (resolve, reject) => { - try { - const result = await this.sendRequest( - this.remotePk, - 'connect', - [this.localPk, token || '', perms || ''], - 24133, - (response) => { - if (response === 'ack') { - resolve(true); - } else { - reject(new Error('Connection not acknowledged')); - } - } - ); - - // Set 30 second timeout - setTimeout(() => reject(new Error('Connection timeout')), 30000); - - } catch (error) { - reject(error); - } - }); - } - - async initUserPubkey(hint) { - if (hint) { - this.remotePk = hint; - return hint; - } - - if (!this.remotePk) { - // Request get_public_key - return new Promise(async (resolve, reject) => { - try { - const pubkey = await this.sendRequest( - this.remotePk, - 'get_public_key', - [], - 24133 - ); - this.remotePk = pubkey; - resolve(pubkey); - } catch (error) { - reject(error); - } - }); - } - - return this.remotePk; - } - - async sendRequest(remotePubkey, method, params, kind = 24133, cb) { - if (!this.pool || !this.localSk || !this.localPk) { - throw new Error('NIP46Client not properly initialized'); - } - - if (!remotePubkey) { - throw new Error('No remote pubkey specified'); - } - - const id = this._generateId(); - - // Create request event - const event = await this.createRequestEvent(id, remotePubkey, method, params, kind); - - console.log('Sending NIP-46 request:', { id, method, params }); - - // Publish to relays - const pubs = await this.pool.publish(this.relays, event); - console.log('Published to relays, waiting for response...'); - - return new Promise((resolve, reject) => { - // Set timeout - const timeout = setTimeout(() => { - console.error('NIP-46 request timeout for id:', id); - delete this.pendingRequests[id]; - reject(new Error(`Request timeout for ${method}`)); - }, 60000); // 1 minute timeout - - // Store handler - this.pendingRequests[id] = { - resolve: (result) => { - clearTimeout(timeout); - resolve(result); - }, - reject: (error) => { - clearTimeout(timeout); - reject(error); - }, - timestamp: Date.now() - }; - - // If callback provided, override resolve - if (cb) { - const originalResolve = this.pendingRequests[id].resolve; - this.pendingRequests[id].resolve = (result) => { - cb(result); - originalResolve(result); - }; - } - }); - } - - async createRequestEvent(id, remotePubkey, method, params, kind = 24133) { - let content = JSON.stringify({ - id, - method, - params - }); - - // Choose encryption method - let encrypted = content; - if (method !== 'create_account') { - // Use NIP-44 for non-account creation methods if available - if (this.useNip44 && window.NostrTools.nip44) { - encrypted = window.NostrTools.nip44.encrypt(this.localSk, remotePubkey, content); - } else { - // Fallback to NIP-04 - encrypted = await window.NostrTools.nip04.encrypt(this.localSk, remotePubkey, content); - } - } - - // Create event structure - const event = { - kind: kind, - content: encrypted, - tags: [ - ['p', remotePubkey] - ], - created_at: Math.floor(Date.now() / 1000), - pubkey: this.localPk, - id: '', // Will be set by finalizeEvent - sig: '' // Will be set by finalizeEvent - }; - - // Sign the event - const signedEvent = window.NostrTools.finalizeEvent(event, this.localSk); - - return signedEvent; - } - - _generateId() { - return 'nl-' + Date.now() + '-' + Math.random().toString(36).substring(2, 15); - } - - setWorkerIframePort(port) { - this.iframePort = port; - - // Set up postMessage routing if needed - if (this.iframePort && this.iframeOrigin) { - this.iframePort.onmessage = (event) => { - if (event.origin !== this.iframeOrigin) { - console.warn('Ignoring message from unknown origin:', event.origin); - return; - } - - console.log('Received iframe message:', event.data); - // Handle iframe messages - }; - - // Send keepalive - setInterval(() => { - if (this.iframePort) { - try { - this.iframePort.postMessage({ type: 'ping' }); - } catch (e) { - console.warn('Iframe port closed'); - this.iframePort = null; - } - } - }, 30000); // 30 seconds - } - } - - teardown() { - this.unsubscribe(); - - if (this.iframePort) { - try { - this.iframePort.close(); - } catch (e) { - console.warn('Error closing iframe port:', e); - } - this.iframePort = null; - } - - if (this.pool) { - this.pool.close(this.relays); - this.pool = null; - } - - // Clear all pending requests - for (const id in this.pendingRequests) { - this.pendingRequests[id].reject(new Error('Client teardown')); - } - this.pendingRequests = {}; - } -} - - -// ====================================== -// nostr-login-lite.js -// ====================================== - - -// Import NIP-46 client -if (typeof NIP46Client === 'undefined') { - // Load NIP46Client if not already available (for non-bundled version) - const script = document.createElement('script'); - script.src = './core/nip46-client.js'; - document.head.appendChild(script); -} - -// Global state -const LiteState = { - initialized: false, - windowNostr: null, - options: null, - auth: null, - modal: null, - bus: null, - pool: null, - nip44Codec: null, - extensionBridge: null, - nip46Client: null -}; - -// Dependencies verification -class Deps { - static ensureNostrToolsLoaded() { - if (typeof window === 'undefined') { - throw new Error('NOSTR_LOGIN_LITE must run in browser environment'); - } - - if (!window.NostrTools) { - throw new Error( - 'window.NostrTools is required but not loaded. ' + - 'Please include: ' - ); - } - - // Verify required APIs - const required = ['SimplePool', 'getPublicKey', 'finalizeEvent', 'nip04']; - for (const api of required) { - if (!window.NostrTools[api]) { - throw new Error(`window.NostrTools.${api} is required but missing`); - } - } - - // Check for key generation function (might be generateSecretKey or generatePrivateKey) - if (!window.NostrTools.generateSecretKey && !window.NostrTools.generatePrivateKey) { - throw new Error('window.NostrTools must have either generateSecretKey or generatePrivateKey'); - } - - return true; - } -} - -// Event Bus for internal communication -class Bus { - constructor() { - this.handlers = {}; - } - - on(event, handler) { - if (!this.handlers[event]) { - this.handlers[event] = []; - } - this.handlers[event].push(handler); - } - - off(event, handler) { - if (!this.handlers[event]) return; - this.handlers[event] = this.handlers[event].filter(h => h !== handler); - } - - emit(event, payload) { - if (!this.handlers[event]) return; - this.handlers[event].forEach(handler => { - try { - handler(payload); - } catch (e) { - console.error(`Error in event handler for ${event}:`, e); - } - }); - } -} - -// Storage helpers -class Store { - static addAccount(info) { - const accounts = this.getAccounts(); - // Remove existing account with same pubkey if present - const filtered = accounts.filter(acc => acc.pubkey !== info.pubkey); - filtered.push(info); - localStorage.setItem('nl_accounts', JSON.stringify(filtered)); - } - - static removeCurrentAccount() { - const current = this.getCurrent(); - if (current && current.pubkey) { - const accounts = this.getAccounts(); - const filtered = accounts.filter(acc => acc.pubkey !== current.pubkey); - localStorage.setItem('nl_accounts', JSON.stringify(filtered)); - localStorage.removeItem('nl_current'); - } - } - - static getCurrent() { - try { - const stored = localStorage.getItem('nl_current'); - return stored ? JSON.parse(stored) : null; - } catch (e) { - console.error('Error parsing current account:', e); - return null; - } - } - - static setCurrent(info) { - localStorage.setItem('nl_current', JSON.stringify(info)); - } - - static getAccounts() { - try { - const stored = localStorage.getItem('nl_accounts'); - return stored ? JSON.parse(stored) : []; - } catch (e) { - console.error('Error parsing accounts:', e); - return []; - } - } - - static getRecents() { - // Return last 5 used accounts in reverse chronological order - const accounts = this.getAccounts().slice(-5).reverse(); - return accounts; - } - - static setItem(key, value) { - localStorage.setItem(`nl-${key}`, value); - } - - static getItem(key) { - return localStorage.getItem(`nl-${key}`); - } - - static async getIcon() { - // Simple default icon - could be extended to fetch from profile - return '🔑'; - } -} - -// Relay configuration helpers -class Relays { - static getDefaultRelays(options) { - if (options?.relays) { - return this.normalize(options.relays); - } - - // Default relays for fallbacks - return [ - 'wss://relay.damus.io', - 'wss://relay.snort.social', - 'wss://nos.lol' - ]; - } - - static normalize(relays) { - return relays.map(relay => { - // Ensure wss:// prefix - if (relay.startsWith('ws://')) { - return relay.replace('ws://', 'wss://'); - } else if (!relay.startsWith('wss://')) { - return `wss://${relay}`; - } - return relay; - }).filter(relay => { - // Remove duplicates and validate URLs - try { - new URL(relay); - return true; - } catch { - return false; - } - }).filter((relay, index, self) => self.indexOf(relay) === index); // dedupe - } -} - -// Minimal NIP-44 codec fallback -class Nip44 { - constructor() { - this.Nip44 = null; - // Initialize with existing codec if available - this.nip44Available = window.NostrTools?.nip44; - } - - static encrypt(ourSk, theirPk, plaintext) { - if (window.NostrTools?.nip44?.encrypt) { - return window.NostrTools.nip44.encrypt(ourSk, theirPk, plaintext); - } - - throw new Error('NIP-44 encryption not available. Please use nostr-tools@>=2.x or provide codec implementation.'); - } - - static decrypt(ourSk, theirPk, ciphertext) { - if (window.NostrTools?.nip44?.decrypt) { - return window.NostrTools.nip44.decrypt(ourSk, theirPk, ciphertext); - } - - throw new Error('NIP-44 decryption not available. Please use nostr-tools@>=2.x or provide codec implementation.'); - } -} - -// LocalSigner wrapping window.NostrTools -class LocalSigner { - constructor(sk) { - this.sk = sk; - // Generate pubkey from secret key - this.pk = this._getPubKey(); - } - - _getPubKey() { - const seckey = this.sk.startsWith('nsec') ? - window.NostrTools.nip19.decode(this.sk).data : - this.sk; - return window.NostrTools.getPublicKey(seckey); - } - - pubkey() { - return this.pk; - } - - async sign(event) { - // Prepare event for signing - const ev = { ...event }; - ev.pubkey = this.pk; - - // Generate event ID and sign - const signedEvent = await window.NostrTools.finalizeEvent(ev, this.sk); - return signedEvent; - } - - async encrypt04(pubkey, plaintext) { - return await window.NostrTools.nip04.encrypt(this.sk, pubkey, plaintext); - } - - async decrypt04(pubkey, ciphertext) { - return await window.NostrTools.nip04.decrypt(this.sk, pubkey, ciphertext); - } - - async encrypt44(pubkey, plaintext) { - return Nip44.encrypt(this.sk, pubkey, plaintext); - } - - async decrypt44(pubkey, ciphertext) { - return Nip44.decrypt(this.sk, pubkey, ciphertext); - } -} - -// ExtensionBridge for detecting and managing browser extensions -class ExtensionBridge { - constructor() { - this.checking = false; - this.checkInterval = null; - this.originalNostr = null; - this.foundExtensions = new Map(); // Store multiple extensions by location - this.primaryExtension = null; // The currently selected extension - } - - startChecking(nostrLite) { - if (this.checking) return; - this.checking = true; - - const check = () => { - this.detectAllExtensions(nostrLite); - }; - - // Check immediately - check(); - - // Then check every 200ms for 30 seconds - this.checkInterval = setInterval(check, 200); - - // Stop checking after 30 seconds - setTimeout(() => { - clearInterval(this.checkInterval); - this.checkInterval = null; - }, 30000); - } - - detectAllExtensions(nostrLite) { - // Extension locations to check (in priority order) - const locations = [ - { path: 'window.navigator?.nostr', name: 'navigator.nostr', getter: () => window.navigator?.nostr }, - { path: 'window.webln?.nostr', name: 'webln.nostr', getter: () => window.webln?.nostr }, - { path: 'window.alby?.nostr', name: 'alby.nostr', getter: () => window.alby?.nostr }, - { path: 'window.nos2x', name: 'nos2x', getter: () => window.nos2x }, - { path: 'window.flamingo?.nostr', name: 'flamingo.nostr', getter: () => window.flamingo?.nostr }, - { path: 'window.mutiny?.nostr', name: 'mutiny.nostr', getter: () => window.mutiny?.nostr }, - { path: 'window.nostrich?.nostr', name: 'nostrich.nostr', getter: () => window.nostrich?.nostr }, - { path: 'window.getAlby?.nostr', name: 'getAlby.nostr', getter: () => window.getAlby?.nostr } - ]; - - let foundNew = false; - - // Check each location - for (const location of locations) { - try { - const obj = location.getter(); - - if (obj && this.isRealExtension(obj, nostrLite)) { - if (!this.foundExtensions.has(location.name)) { - this.foundExtensions.set(location.name, { - name: location.name, - path: location.path, - extension: obj, - constructor: obj.constructor?.name || 'Unknown' - }); - console.log(`Real Nostr extension detected: ${location.name} (${obj.constructor?.name})`); - foundNew = true; - } - } - } catch (e) { - // Location doesn't exist or can't be accessed - } - } - - // Also check window.nostr but be extra careful to avoid our library - if (window.nostr && this.isRealExtension(window.nostr, nostrLite)) { - // Make sure we haven't already detected this extension via another path - const existingExtension = Array.from(this.foundExtensions.values()).find( - ext => ext.extension === window.nostr - ); - - if (!existingExtension && !this.foundExtensions.has('window.nostr')) { - this.foundExtensions.set('window.nostr', { - name: 'window.nostr', - path: 'window.nostr', - extension: window.nostr, - constructor: window.nostr.constructor?.name || 'Unknown' - }); - console.log(`Real Nostr extension detected at window.nostr: ${window.nostr.constructor?.name}`); - foundNew = true; - } - } - - // Set primary extension if we don't have one and found extensions - if (!this.primaryExtension && this.foundExtensions.size > 0) { - // Prefer navigator.nostr if available, otherwise use first found - this.primaryExtension = this.foundExtensions.get('navigator.nostr') || - Array.from(this.foundExtensions.values())[0]; - - // Cache the extension and reassign window.nostr to our lite version - this.originalNostr = this.primaryExtension.extension; - if (window.nostr !== nostrLite) { - window.nostr = nostrLite; - } - - console.log(`Primary extension set: ${this.primaryExtension.name}`); - - // If currently authenticated, reconcile state - if (LiteState.auth?.signer?.method === 'extension') { - this.reconcileExtension(); - } - } - } - - isRealExtension(obj, nostrLite) { - if (!obj || typeof obj !== 'object') return false; - - // Must have required Nostr methods - if (typeof obj.getPublicKey !== 'function' || typeof obj.signEvent !== 'function') { - return false; - } - - // Exclude our own library objects - if (obj === nostrLite || obj === windowNostr) { - return false; - } - - // Exclude objects with our library's internal methods - if (typeof obj._hexToUint8Array === 'function' || typeof obj._call === 'function') { - return false; - } - - // Exclude NostrTools library object - if (obj === window.NostrTools) { - return false; - } - - // Real extensions typically have proper constructors (not plain Object) - const constructorName = obj.constructor?.name; - if (constructorName === 'Object' && !obj._isEnabled && !obj.enabled) { - // Plain objects without extension-specific properties are likely our library - return false; - } - - return true; - } - - getAllExtensions() { - return Array.from(this.foundExtensions.values()); - } - - getExtensionCount() { - return this.foundExtensions.size; - } - - hasExtension() { - return this.foundExtensions.size > 0; - } - - // Legacy compatibility - return primary extension - get foundExtension() { - return this.primaryExtension?.extension || null; - } - - // Method to properly set primary extension - setPrimaryExtension(extension, name = 'selected') { - // Find the extension in our map or create new entry - let extensionInfo = null; - - // Check if this extension is already in our map - for (const [key, info] of this.foundExtensions) { - if (info.extension === extension) { - extensionInfo = info; - break; - } - } - - // If not found, create a new entry - if (!extensionInfo) { - extensionInfo = { - name: name, - path: name, - extension: extension, - constructor: extension?.constructor?.name || 'Unknown' - }; - this.foundExtensions.set(name, extensionInfo); - } - - this.primaryExtension = extensionInfo; - console.log(`Primary extension set to: ${extensionInfo.name}`); - } - - async setExtensionReadPubkey(expectedPubkey = null) { - if (!this.primaryExtension) return false; - - try { - // Temporarily set window.nostr to extension - const temp = window.nostr; - window.nostr = this.primaryExtension.extension; - - const pubkey = await this.primaryExtension.extension.getPublicKey(); - - // Restore our lite implementation - window.nostr = temp; - - if (expectedPubkey && pubkey !== expectedPubkey) { - console.warn(`Extension pubkey ${pubkey} does not match expected ${expectedPubkey}`); - } - - return pubkey; - } catch (e) { - console.error('Error reading extension pubkey:', e); - return null; - } - } - - trySetForPubkey(expectedPubkey) { - if (!this.hasExtension()) return false; - - this.setExtensionReadPubkey(expectedPubkey).then(pubkey => { - if (pubkey) { - LiteState.bus?.emit('extensionLogin', { pubkey }); - } - }); - - return true; - } - - setExtension() { - if (!this.primaryExtension) return; - window.nostr = this.primaryExtension.extension; - this.setExtensionReadPubkey().then(pubkey => { - if (pubkey) { - LiteState.bus?.emit('extensionSet', { pubkey }); - } - }); - } - - unset(nostrLite) { - window.nostr = nostrLite; - } - - reconcileExtension() { - // Handle extension state changes - this.setExtensionReadPubkey().then(pubkey => { - if (pubkey) { - // Update current account if extension is the signer - const current = Store.getCurrent(); - if (current && current.signer?.method === 'extension') { - const info = { - ...current, - pubkey, - signer: { method: 'extension' } - }; - Store.setCurrent(info); - LiteState.bus?.emit('authStateUpdate', info); - } - } - }); - } -} - -// Main API surface -class NostrLite { - static async init(options = {}) { - // Ensure dependencies are loaded - Deps.ensureNostrToolsLoaded(); - - // Prevent double initialization - if (LiteState.initialized) { - console.warn('NOSTR_LOGIN_LITE already initialized'); - return; - } - - // Initialize components - LiteState.bus = new Bus(); - LiteState.extensionBridge = new ExtensionBridge(); - - // Initialize NIP-46 client - LiteState.nip46Client = new NIP46Client(); - - // Store options - LiteState.options = { - theme: 'light', - darkMode: false, - relays: Relays.getDefaultRelays(options), - methods: { - connect: true, - extension: true, - local: true, - readonly: true, - otp: true - }, - otp: {}, - ...options - }; - - // Start extension detection - LiteState.extensionBridge.startChecking(windowNostr); - - // Setup auth methods - this._setupAuth(); - - // Initialize modal UI - // this._initModal(); - - console.log('NOSTR_LOGIN_LITE initialized with options:', LiteState.options); - LiteState.initialized = true; - } - - static _setupAuth() { - // Set up event listeners for modal interactions - window.addEventListener('nlMethodSelected', (event) => { - this._handleMethodSelected(event.detail); - }); - - // Set up other auth-related event listeners - this._setupAuthEventListeners(); - - console.log('Auth system setup loaded'); - } - - static _setupAuthEventListeners() { - // Handle extension detection - this.bus?.on('extensionDetected', (extension) => { - console.log('Extension detected'); - LiteState.extensionBridge.setPrimaryExtension(extension, 'detected'); - }); - - // Handle auth URL from NIP-46 - window.addEventListener('nlAuthUrl', (event) => { - console.log('Auth URL received:', event.detail.url); - // Could show URL in modal or trigger external flow - }); - - // Handle logout events - window.addEventListener('nlLogout', () => { - console.log('Logout event received'); - this.logout(); - }); - } - - static _handleMethodSelected(detail) { - console.log('Method selected:', detail); - - const { method, pubkey, secret, extension } = detail; - - switch (method) { - case 'local': - if (secret && pubkey) { - // Set up local key authentication - const info = { - pubkey, - signer: { method: 'local', secret } - }; - Store.setCurrent(info); - LiteState.bus?.emit('authStateUpdate', info); - this._dispatchAuthEvent('login', info); - } - break; - - case 'extension': - if (pubkey && extension) { - // Store the extension object in the ExtensionBridge for future use - LiteState.extensionBridge.setPrimaryExtension(extension, 'modal-selected'); - LiteState.extensionBridge.originalNostr = extension; - - // Set up extension authentication - const info = { - pubkey, - signer: { method: 'extension' } - }; - Store.setCurrent(info); - LiteState.bus?.emit('authStateUpdate', info); - this._dispatchAuthEvent('login', info); - - console.log('Extension authentication set up successfully'); - } else { - // Fallback to extension bridge detection - LiteState.bus?.emit('authMethodSelected', { method: 'extension' }); - } - break; - - case 'readonly': - // Set read-only mode - const readonlyInfo = { - pubkey: '', - signer: { method: 'readonly' } - }; - Store.setCurrent(readonlyInfo); - LiteState.bus?.emit('authStateUpdate', readonlyInfo); - this._dispatchAuthEvent('login', readonlyInfo); - break; - - case 'nip46': - if (secret && pubkey) { - // Set up NIP-46 remote signing - const info = { - pubkey, - signer: { method: 'nip46', ...secret } - }; - Store.setCurrent(info); - LiteState.bus?.emit('authStateUpdate', info); - this._dispatchAuthEvent('login', info); - } - break; - - default: - console.warn('Unhandled auth method:', method); - } - } - - static _dispatchAuthEvent(type, info) { - const eventPayload = { - type, - info, - pubkey: info?.pubkey || '', - method: info?.signer?.method || '', - ...info - }; - - // Dispatch the event - window.dispatchEvent(new CustomEvent('nlAuth', { detail: eventPayload })); - - this.bus?.emit('nlAuth', eventPayload); - } - - static launch(startScreen) { - if (!LiteState.initialized) { - throw new Error('NOSTR_LOGIN_LITE not initialized. Call init() first.'); - } - - console.log('Launch requested with screen:', startScreen); - - // Initialize modal if needed - if (!LiteState.modal) { - // Import modal lazily - if (typeof Modal !== 'undefined') { - LiteState.modal = Modal.init(LiteState.options); - } else { - console.error('Modal component not available'); - return; - } - } - - // Open modal with specified screen - LiteState.modal.open({ startScreen }); - } - - static logout() { - if (!LiteState.initialized) return; - - // Clear current account and state - Store.removeCurrentAccount(); - - // Reset internal state - LiteState.auth = null; - - // Emit logout event - window.dispatchEvent(new CustomEvent('nlLogout')); - LiteState.bus?.emit('logout'); - - console.log('Logged out'); - } - - static setDarkMode(dark) { - if (!LiteState.options) return; - - LiteState.options.darkMode = dark; - Store.setItem('darkMode', dark.toString()); - - // Update modal theme if initialized - if (LiteState.modal) { - // LiteState.modal.updateTheme(); - } - - window.dispatchEvent(new CustomEvent('nlDarkMode', { detail: { dark } })); - } - - static setAuth(o) { - if (!o || !o.type) return; - - console.log('setAuth called:', o); - - // Validate request - if (!['login', 'signup', 'logout'].includes(o.type)) { - throw new Error(`Invalid auth type: ${o.type}`); - } - - if (['login', 'signup'].includes(o.type) && !['connect', 'extension', 'local', 'otp', 'readOnly'].includes(o.method)) { - throw new Error(`Invalid auth method: ${o.method}`); - } - - // Handle based on type - switch (o.type) { - case 'logout': - this.logout(); - break; - default: - // Delegate to auth system - will be implemented - console.log('Auth delegation not yet implemented'); - } - } - - static cancelNeedAuth() { - // Cancel any ongoing auth flows - LiteState.bus?.emit('cancelAuth'); - console.log('Auth flow cancelled'); - } -} - -// Initialize the window.nostr facade -const windowNostr = { - async getPublicKey() { - if (!LiteState.initialized) { - throw new Error('NOSTR_LOGIN_LITE not initialized'); - } - - const current = Store.getCurrent(); - if (current && current.pubkey) { - return current.pubkey; - } - - // Trigger auth flow - const authPromise = new Promise((resolve, reject) => { - const handleAuth = (event) => { - window.removeEventListener('nlAuth', handleAuth); - if (event.detail.type === 'login' && event.detail.pubkey) { - resolve(event.detail.pubkey); - } else { - reject(new Error('Authentication cancelled')); - } - }; - - window.addEventListener('nlAuth', handleAuth); - - // Set timeout - setTimeout(() => { - window.removeEventListener('nlAuth', handleAuth); - reject(new Error('Authentication timeout')); - }, 300000); // 5 minutes - }); - - // Launch auth modal - NostrLite.launch('login'); - - return authPromise; - }, - - async signEvent(event) { - if (!LiteState.initialized) { - throw new Error('NOSTR_LOGIN_LITE not initialized'); - } - - let current = Store.getCurrent(); - - // If no current account, trigger auth - if (!current) { - await window.nostr.getPublicKey(); // This will trigger auth - current = Store.getCurrent(); - if (!current) { - throw new Error('Authentication failed'); - } - } - - // Route to appropriate signer - if (current.signer?.method === 'local' && current.signer.secret) { - const signer = new LocalSigner(this._hexToUint8Array(current.signer.secret)); - return await signer.sign(event); - } else if (current.signer?.method === 'nip46' && current.signer.bunkerSigner) { - // Route to NIP-46 remote signer - try { - const bunkerSigner = current.signer.bunkerSigner; - const signedEvent = await bunkerSigner.signEvent(event); - return signedEvent; - } catch (error) { - console.error('NIP-46 signEvent failed:', error); - throw new Error(`NIP-46 signing failed: ${error.message}`); - } - } else if (current.signer?.method === 'readonly') { - throw new Error('Cannot sign events in read-only mode'); - } else if (current.signer?.method === 'extension' && LiteState.extensionBridge?.hasExtension()) { - // Route to extension - const temp = window.nostr; - window.nostr = LiteState.extensionBridge.foundExtension; - try { - const signedEvent = await window.nostr.signEvent(event); - return signedEvent; - } finally { - window.nostr = temp; - } - } - - throw new Error('No suitable signer available for current account'); - }, - - _hexToUint8Array(hex) { - // Convert hex string to Uint8Array - const bytes = new Uint8Array(hex.length / 2); - for (let i = 0; i < bytes.length; i++) { - bytes[i] = parseInt(hex.substr(i * 2, 2), 16); - } - return bytes; - }, - - nip04: { - async encrypt(pubkey, plaintext) { - if (!LiteState.initialized) { - throw new Error('NOSTR_LOGIN_LITE not initialized'); - } - - const current = Store.getCurrent(); - if (!current) { - throw new Error('No authenticated user'); - } - - if (current.signer?.method === 'nip46' && current.signer.bunkerSigner) { - // Route to NIP-46 remote signer - try { - const bunkerSigner = current.signer.bunkerSigner; - return await bunkerSigner.nip04Encrypt(pubkey, plaintext); - } catch (error) { - console.error('NIP-46 nip04 encrypt failed:', error); - throw new Error(`NIP-46 encrypting failed: ${error.message}`); - } - } else if (current.signer?.method === 'local' && current.signer.secret) { - const signer = new LocalSigner(current.signer.secret); - return await signer.encrypt04(pubkey, plaintext); - } else if (current.signer?.method === 'extension' && LiteState.extensionBridge?.hasExtension()) { - const temp = window.nostr; - window.nostr = LiteState.extensionBridge.foundExtension; - try { - return await window.nostr.nip04.encrypt(pubkey, plaintext); - } finally { - window.nostr = temp; - } - } - - throw new Error('No suitable signer available for NIP-04 encryption'); - }, - - async decrypt(pubkey, ciphertext) { - if (!LiteState.initialized) { - throw new Error('NOSTR_LOGIN_LITE not initialized'); - } - - const current = Store.getCurrent(); - if (!current) { - throw new Error('No authenticated user'); - } - - if (current.signer?.method === 'nip46' && current.signer.bunkerSigner) { - // Route to NIP-46 remote signer - try { - const bunkerSigner = current.signer.bunkerSigner; - return await bunkerSigner.nip04Decrypt(pubkey, ciphertext); - } catch (error) { - console.error('NIP-46 nip04 decrypt failed:', error); - throw new Error(`NIP-46 decrypting failed: ${error.message}`); - } - } else if (current.signer?.method === 'local' && current.signer.secret) { - const signer = new LocalSigner(current.signer.secret); - return await signer.decrypt04(pubkey, ciphertext); - } else if (current.signer?.method === 'extension' && LiteState.extensionBridge?.hasExtension()) { - const temp = window.nostr; - window.nostr = LiteState.extensionBridge.foundExtension; - try { - return await window.nostr.nip04.decrypt(pubkey, ciphertext); - } finally { - window.nostr = temp; - } - } - - throw new Error('No suitable signer available for NIP-04 decryption'); - } - }, - - nip44: { - async encrypt(pubkey, plaintext) { - if (!LiteState.initialized) { - throw new Error('NOSTR_LOGIN_LITE not initialized'); - } - - const current = Store.getCurrent(); - if (!current) { - throw new Error('No authenticated user'); - } - - if (current.signer?.method === 'nip46' && current.signer.bunkerSigner) { - // Route to NIP-46 remote signer - try { - const bunkerSigner = current.signer.bunkerSigner; - return await bunkerSigner.nip44Encrypt(pubkey, plaintext); - } catch (error) { - console.error('NIP-46 nip44 encrypt failed:', error); - throw new Error(`NIP-46 encrypting failed: ${error.message}`); - } - } else if (current.signer?.method === 'local' && current.signer.secret) { - const signer = new LocalSigner(current.signer.secret); - return await signer.encrypt44(pubkey, plaintext); - } else if (current.signer?.method === 'extension' && LiteState.extensionBridge?.hasExtension()) { - // Use extension if it supports nip44 - const temp = window.nostr; - window.nostr = LiteState.extensionBridge.foundExtension; - try { - if (window.nostr.nip44) { - return await window.nostr.nip44.encrypt(pubkey, plaintext); - } else { - throw new Error('Extension does not support NIP-44'); - } - } finally { - window.nostr = temp; - } - } - - throw new Error('No suitable signer available for NIP-44 encryption'); - }, - - async decrypt(pubkey, ciphertext) { - if (!LiteState.initialized) { - throw new Error('NOSTR_LOGIN_LITE not initialized'); - } - - const current = Store.getCurrent(); - if (!current) { - throw new Error('No authenticated user'); - } - - if (current.signer?.method === 'nip46' && current.signer.bunkerSigner) { - // Route to NIP-46 remote signer - try { - const bunkerSigner = current.signer.bunkerSigner; - return await bunkerSigner.nip44Decrypt(pubkey, ciphertext); - } catch (error) { - console.error('NIP-46 nip44 decrypt failed:', error); - throw new Error(`NIP-46 decrypting failed: ${error.message}`); - } - } else if (current.signer?.method === 'local' && current.signer.secret) { - const signer = new LocalSigner(current.signer.secret); - return await signer.decrypt44(pubkey, ciphertext); - } else if (current.signer?.method === 'extension' && LiteState.extensionBridge?.hasExtension()) { - const temp = window.nostr; - window.nostr = LiteState.extensionBridge.foundExtension; - try { - if (window.nostr.nip44) { - return await window.nostr.nip44.decrypt(pubkey, ciphertext); - } else { - throw new Error('Extension does not support NIP-44'); - } - } finally { - window.nostr = temp; - } - } - - throw new Error('No suitable signer available for NIP-44 decryption'); - } - } -}; - -// Export the API -window.NOSTR_LOGIN_LITE = { - init: NostrLite.init.bind(NostrLite), - launch: NostrLite.launch.bind(NostrLite), - logout: NostrLite.logout.bind(NostrLite), - setDarkMode: NostrLite.setDarkMode.bind(NostrLite), - setAuth: NostrLite.setAuth.bind(NostrLite), - cancelNeedAuth: NostrLite.cancelNeedAuth.bind(NostrLite), - // Expose internal components for debugging - get _extensionBridge() { - return LiteState.extensionBridge; - }, - get _state() { - return LiteState; - } -}; - -// Set window.nostr facade properly (extensions will be handled by ExtensionBridge) -if (typeof window !== 'undefined') { - window.nostr = windowNostr; - - // Ensure all methods are properly exposed - console.log('NOSTR_LOGIN_LITE: window.nostr facade installed with methods:', Object.keys(windowNostr)); -} - -console.log('NOSTR_LOGIN_LITE loaded - use window.NOSTR_LOGIN_LITE.init(options) to initialize'); - diff --git a/lite/nostr-login-lite.js b/lite/nostr-login-lite.js deleted file mode 100644 index c2a6fee..0000000 --- a/lite/nostr-login-lite.js +++ /dev/null @@ -1,1039 +0,0 @@ -/** - * NOSTR_LOGIN_LITE - * A minimal, dependency-light replacement for the current auth/UI stack - * Preserves all login methods and window.nostr surface - */ - -// Import NIP-46 client -if (typeof NIP46Client === 'undefined') { - // Load NIP46Client if not already available (for non-bundled version) - const script = document.createElement('script'); - script.src = './core/nip46-client.js'; - document.head.appendChild(script); -} - -// Global state -const LiteState = { - initialized: false, - windowNostr: null, - options: null, - auth: null, - modal: null, - bus: null, - pool: null, - nip44Codec: null, - extensionBridge: null, - nip46Client: null -}; - -// Dependencies verification -class Deps { - static ensureNostrToolsLoaded() { - if (typeof window === 'undefined') { - throw new Error('NOSTR_LOGIN_LITE must run in browser environment'); - } - - if (!window.NostrTools) { - throw new Error( - 'window.NostrTools is required but not loaded. ' + - 'Please include: ' - ); - } - - // Verify required APIs - const required = ['SimplePool', 'getPublicKey', 'finalizeEvent', 'nip04']; - for (const api of required) { - if (!window.NostrTools[api]) { - throw new Error(`window.NostrTools.${api} is required but missing`); - } - } - - // Check for key generation function (might be generateSecretKey or generatePrivateKey) - if (!window.NostrTools.generateSecretKey && !window.NostrTools.generatePrivateKey) { - throw new Error('window.NostrTools must have either generateSecretKey or generatePrivateKey'); - } - - return true; - } -} - -// Event Bus for internal communication -class Bus { - constructor() { - this.handlers = {}; - } - - on(event, handler) { - if (!this.handlers[event]) { - this.handlers[event] = []; - } - this.handlers[event].push(handler); - } - - off(event, handler) { - if (!this.handlers[event]) return; - this.handlers[event] = this.handlers[event].filter(h => h !== handler); - } - - emit(event, payload) { - if (!this.handlers[event]) return; - this.handlers[event].forEach(handler => { - try { - handler(payload); - } catch (e) { - console.error(`Error in event handler for ${event}:`, e); - } - }); - } -} - -// Storage helpers -class Store { - static addAccount(info) { - const accounts = this.getAccounts(); - // Remove existing account with same pubkey if present - const filtered = accounts.filter(acc => acc.pubkey !== info.pubkey); - filtered.push(info); - localStorage.setItem('nl_accounts', JSON.stringify(filtered)); - } - - static removeCurrentAccount() { - const current = this.getCurrent(); - if (current && current.pubkey) { - const accounts = this.getAccounts(); - const filtered = accounts.filter(acc => acc.pubkey !== current.pubkey); - localStorage.setItem('nl_accounts', JSON.stringify(filtered)); - localStorage.removeItem('nl_current'); - } - } - - static getCurrent() { - try { - const stored = localStorage.getItem('nl_current'); - return stored ? JSON.parse(stored) : null; - } catch (e) { - console.error('Error parsing current account:', e); - return null; - } - } - - static setCurrent(info) { - localStorage.setItem('nl_current', JSON.stringify(info)); - } - - static getAccounts() { - try { - const stored = localStorage.getItem('nl_accounts'); - return stored ? JSON.parse(stored) : []; - } catch (e) { - console.error('Error parsing accounts:', e); - return []; - } - } - - static getRecents() { - // Return last 5 used accounts in reverse chronological order - const accounts = this.getAccounts().slice(-5).reverse(); - return accounts; - } - - static setItem(key, value) { - localStorage.setItem(`nl-${key}`, value); - } - - static getItem(key) { - return localStorage.getItem(`nl-${key}`); - } - - static async getIcon() { - // Simple default icon - could be extended to fetch from profile - return '🔑'; - } -} - -// Relay configuration helpers -class Relays { - static getDefaultRelays(options) { - if (options?.relays) { - return this.normalize(options.relays); - } - - // Default relays for fallbacks - return [ - 'wss://relay.damus.io', - 'wss://relay.snort.social', - 'wss://nos.lol' - ]; - } - - static normalize(relays) { - return relays.map(relay => { - // Ensure wss:// prefix - if (relay.startsWith('ws://')) { - return relay.replace('ws://', 'wss://'); - } else if (!relay.startsWith('wss://')) { - return `wss://${relay}`; - } - return relay; - }).filter(relay => { - // Remove duplicates and validate URLs - try { - new URL(relay); - return true; - } catch { - return false; - } - }).filter((relay, index, self) => self.indexOf(relay) === index); // dedupe - } -} - -// Minimal NIP-44 codec fallback -class Nip44 { - constructor() { - this.Nip44 = null; - // Initialize with existing codec if available - this.nip44Available = window.NostrTools?.nip44; - } - - static encrypt(ourSk, theirPk, plaintext) { - if (window.NostrTools?.nip44?.encrypt) { - return window.NostrTools.nip44.encrypt(ourSk, theirPk, plaintext); - } - - throw new Error('NIP-44 encryption not available. Please use nostr-tools@>=2.x or provide codec implementation.'); - } - - static decrypt(ourSk, theirPk, ciphertext) { - if (window.NostrTools?.nip44?.decrypt) { - return window.NostrTools.nip44.decrypt(ourSk, theirPk, ciphertext); - } - - throw new Error('NIP-44 decryption not available. Please use nostr-tools@>=2.x or provide codec implementation.'); - } -} - -// LocalSigner wrapping window.NostrTools -class LocalSigner { - constructor(sk) { - this.sk = sk; - // Generate pubkey from secret key - this.pk = this._getPubKey(); - } - - _getPubKey() { - const seckey = this.sk.startsWith('nsec') ? - window.NostrTools.nip19.decode(this.sk).data : - this.sk; - return window.NostrTools.getPublicKey(seckey); - } - - pubkey() { - return this.pk; - } - - async sign(event) { - // Prepare event for signing - const ev = { ...event }; - ev.pubkey = this.pk; - - // Generate event ID and sign - const signedEvent = await window.NostrTools.finalizeEvent(ev, this.sk); - return signedEvent; - } - - async encrypt04(pubkey, plaintext) { - return await window.NostrTools.nip04.encrypt(this.sk, pubkey, plaintext); - } - - async decrypt04(pubkey, ciphertext) { - return await window.NostrTools.nip04.decrypt(this.sk, pubkey, ciphertext); - } - - async encrypt44(pubkey, plaintext) { - return Nip44.encrypt(this.sk, pubkey, plaintext); - } - - async decrypt44(pubkey, ciphertext) { - return Nip44.decrypt(this.sk, pubkey, ciphertext); - } -} - -// ExtensionBridge for detecting and managing browser extensions -class ExtensionBridge { - constructor() { - this.checking = false; - this.checkInterval = null; - this.originalNostr = null; - this.foundExtensions = new Map(); // Store multiple extensions by location - this.primaryExtension = null; // The currently selected extension - } - - startChecking(nostrLite) { - if (this.checking) return; - this.checking = true; - - const check = () => { - this.detectAllExtensions(nostrLite); - }; - - // Check immediately - check(); - - // Then check every 200ms for 30 seconds - this.checkInterval = setInterval(check, 200); - - // Stop checking after 30 seconds - setTimeout(() => { - clearInterval(this.checkInterval); - this.checkInterval = null; - }, 30000); - } - - detectAllExtensions(nostrLite) { - // Extension locations to check (in priority order) - const locations = [ - { path: 'window.navigator?.nostr', name: 'navigator.nostr', getter: () => window.navigator?.nostr }, - { path: 'window.webln?.nostr', name: 'webln.nostr', getter: () => window.webln?.nostr }, - { path: 'window.alby?.nostr', name: 'alby.nostr', getter: () => window.alby?.nostr }, - { path: 'window.nos2x', name: 'nos2x', getter: () => window.nos2x }, - { path: 'window.flamingo?.nostr', name: 'flamingo.nostr', getter: () => window.flamingo?.nostr }, - { path: 'window.mutiny?.nostr', name: 'mutiny.nostr', getter: () => window.mutiny?.nostr }, - { path: 'window.nostrich?.nostr', name: 'nostrich.nostr', getter: () => window.nostrich?.nostr }, - { path: 'window.getAlby?.nostr', name: 'getAlby.nostr', getter: () => window.getAlby?.nostr } - ]; - - let foundNew = false; - - // Check each location - for (const location of locations) { - try { - const obj = location.getter(); - - if (obj && this.isRealExtension(obj, nostrLite)) { - if (!this.foundExtensions.has(location.name)) { - this.foundExtensions.set(location.name, { - name: location.name, - path: location.path, - extension: obj, - constructor: obj.constructor?.name || 'Unknown' - }); - console.log(`Real Nostr extension detected: ${location.name} (${obj.constructor?.name})`); - foundNew = true; - } - } - } catch (e) { - // Location doesn't exist or can't be accessed - } - } - - // Also check window.nostr but be extra careful to avoid our library - if (window.nostr && this.isRealExtension(window.nostr, nostrLite)) { - // Make sure we haven't already detected this extension via another path - const existingExtension = Array.from(this.foundExtensions.values()).find( - ext => ext.extension === window.nostr - ); - - if (!existingExtension && !this.foundExtensions.has('window.nostr')) { - this.foundExtensions.set('window.nostr', { - name: 'window.nostr', - path: 'window.nostr', - extension: window.nostr, - constructor: window.nostr.constructor?.name || 'Unknown' - }); - console.log(`Real Nostr extension detected at window.nostr: ${window.nostr.constructor?.name}`); - foundNew = true; - } - } - - // Set primary extension if we don't have one and found extensions - if (!this.primaryExtension && this.foundExtensions.size > 0) { - // Prefer navigator.nostr if available, otherwise use first found - this.primaryExtension = this.foundExtensions.get('navigator.nostr') || - Array.from(this.foundExtensions.values())[0]; - - // Cache the extension and reassign window.nostr to our lite version - this.originalNostr = this.primaryExtension.extension; - if (window.nostr !== nostrLite) { - window.nostr = nostrLite; - } - - console.log(`Primary extension set: ${this.primaryExtension.name}`); - - // If currently authenticated, reconcile state - if (LiteState.auth?.signer?.method === 'extension') { - this.reconcileExtension(); - } - } - } - - isRealExtension(obj, nostrLite) { - if (!obj || typeof obj !== 'object') return false; - - // Must have required Nostr methods - if (typeof obj.getPublicKey !== 'function' || typeof obj.signEvent !== 'function') { - return false; - } - - // Exclude our own library objects - if (obj === nostrLite || obj === windowNostr) { - return false; - } - - // Exclude objects with our library's internal methods - if (typeof obj._hexToUint8Array === 'function' || typeof obj._call === 'function') { - return false; - } - - // Exclude NostrTools library object - if (obj === window.NostrTools) { - return false; - } - - // Real extensions typically have proper constructors (not plain Object) - const constructorName = obj.constructor?.name; - if (constructorName === 'Object' && !obj._isEnabled && !obj.enabled) { - // Plain objects without extension-specific properties are likely our library - return false; - } - - return true; - } - - getAllExtensions() { - return Array.from(this.foundExtensions.values()); - } - - getExtensionCount() { - return this.foundExtensions.size; - } - - hasExtension() { - return this.foundExtensions.size > 0; - } - - // Legacy compatibility - return primary extension - get foundExtension() { - return this.primaryExtension?.extension || null; - } - - // Method to properly set primary extension - setPrimaryExtension(extension, name = 'selected') { - // Find the extension in our map or create new entry - let extensionInfo = null; - - // Check if this extension is already in our map - for (const [key, info] of this.foundExtensions) { - if (info.extension === extension) { - extensionInfo = info; - break; - } - } - - // If not found, create a new entry - if (!extensionInfo) { - extensionInfo = { - name: name, - path: name, - extension: extension, - constructor: extension?.constructor?.name || 'Unknown' - }; - this.foundExtensions.set(name, extensionInfo); - } - - this.primaryExtension = extensionInfo; - console.log(`Primary extension set to: ${extensionInfo.name}`); - } - - async setExtensionReadPubkey(expectedPubkey = null) { - if (!this.primaryExtension) return false; - - try { - // Temporarily set window.nostr to extension - const temp = window.nostr; - window.nostr = this.primaryExtension.extension; - - const pubkey = await this.primaryExtension.extension.getPublicKey(); - - // Restore our lite implementation - window.nostr = temp; - - if (expectedPubkey && pubkey !== expectedPubkey) { - console.warn(`Extension pubkey ${pubkey} does not match expected ${expectedPubkey}`); - } - - return pubkey; - } catch (e) { - console.error('Error reading extension pubkey:', e); - return null; - } - } - - trySetForPubkey(expectedPubkey) { - if (!this.hasExtension()) return false; - - this.setExtensionReadPubkey(expectedPubkey).then(pubkey => { - if (pubkey) { - LiteState.bus?.emit('extensionLogin', { pubkey }); - } - }); - - return true; - } - - setExtension() { - if (!this.primaryExtension) return; - window.nostr = this.primaryExtension.extension; - this.setExtensionReadPubkey().then(pubkey => { - if (pubkey) { - LiteState.bus?.emit('extensionSet', { pubkey }); - } - }); - } - - unset(nostrLite) { - window.nostr = nostrLite; - } - - reconcileExtension() { - // Handle extension state changes - this.setExtensionReadPubkey().then(pubkey => { - if (pubkey) { - // Update current account if extension is the signer - const current = Store.getCurrent(); - if (current && current.signer?.method === 'extension') { - const info = { - ...current, - pubkey, - signer: { method: 'extension' } - }; - Store.setCurrent(info); - LiteState.bus?.emit('authStateUpdate', info); - } - } - }); - } -} - -// Main API surface -class NostrLite { - static async init(options = {}) { - // Ensure dependencies are loaded - Deps.ensureNostrToolsLoaded(); - - // Prevent double initialization - if (LiteState.initialized) { - console.warn('NOSTR_LOGIN_LITE already initialized'); - return; - } - - // Initialize components - LiteState.bus = new Bus(); - LiteState.extensionBridge = new ExtensionBridge(); - - // Initialize NIP-46 client - LiteState.nip46Client = new NIP46Client(); - - // Store options - LiteState.options = { - theme: 'light', - darkMode: false, - relays: Relays.getDefaultRelays(options), - methods: { - connect: true, - extension: true, - local: true, - readonly: true, - otp: true - }, - otp: {}, - ...options - }; - - // Start extension detection - LiteState.extensionBridge.startChecking(windowNostr); - - // Setup auth methods - this._setupAuth(); - - // Initialize modal UI - // this._initModal(); - - console.log('NOSTR_LOGIN_LITE initialized with options:', LiteState.options); - LiteState.initialized = true; - } - - static _setupAuth() { - // Set up event listeners for modal interactions - window.addEventListener('nlMethodSelected', (event) => { - this._handleMethodSelected(event.detail); - }); - - // Set up other auth-related event listeners - this._setupAuthEventListeners(); - - console.log('Auth system setup loaded'); - } - - static _setupAuthEventListeners() { - // Handle extension detection - this.bus?.on('extensionDetected', (extension) => { - console.log('Extension detected'); - LiteState.extensionBridge.setPrimaryExtension(extension, 'detected'); - }); - - // Handle auth URL from NIP-46 - window.addEventListener('nlAuthUrl', (event) => { - console.log('Auth URL received:', event.detail.url); - // Could show URL in modal or trigger external flow - }); - - // Handle logout events - window.addEventListener('nlLogout', () => { - console.log('Logout event received'); - this.logout(); - }); - } - - static _handleMethodSelected(detail) { - console.log('Method selected:', detail); - - const { method, pubkey, secret, extension } = detail; - - switch (method) { - case 'local': - if (secret && pubkey) { - // Set up local key authentication - const info = { - pubkey, - signer: { method: 'local', secret } - }; - Store.setCurrent(info); - LiteState.bus?.emit('authStateUpdate', info); - this._dispatchAuthEvent('login', info); - } - break; - - case 'extension': - if (pubkey && extension) { - // Store the extension object in the ExtensionBridge for future use - LiteState.extensionBridge.setPrimaryExtension(extension, 'modal-selected'); - LiteState.extensionBridge.originalNostr = extension; - - // Set up extension authentication - const info = { - pubkey, - signer: { method: 'extension' } - }; - Store.setCurrent(info); - LiteState.bus?.emit('authStateUpdate', info); - this._dispatchAuthEvent('login', info); - - console.log('Extension authentication set up successfully'); - } else { - // Fallback to extension bridge detection - LiteState.bus?.emit('authMethodSelected', { method: 'extension' }); - } - break; - - case 'readonly': - // Set read-only mode - const readonlyInfo = { - pubkey: '', - signer: { method: 'readonly' } - }; - Store.setCurrent(readonlyInfo); - LiteState.bus?.emit('authStateUpdate', readonlyInfo); - this._dispatchAuthEvent('login', readonlyInfo); - break; - - case 'nip46': - if (secret && pubkey) { - // Set up NIP-46 remote signing - const info = { - pubkey, - signer: { method: 'nip46', ...secret } - }; - Store.setCurrent(info); - LiteState.bus?.emit('authStateUpdate', info); - this._dispatchAuthEvent('login', info); - } - break; - - default: - console.warn('Unhandled auth method:', method); - } - } - - static _dispatchAuthEvent(type, info) { - const eventPayload = { - type, - info, - pubkey: info?.pubkey || '', - method: info?.signer?.method || '', - ...info - }; - - // Dispatch the event - window.dispatchEvent(new CustomEvent('nlAuth', { detail: eventPayload })); - - this.bus?.emit('nlAuth', eventPayload); - } - - static launch(startScreen) { - if (!LiteState.initialized) { - throw new Error('NOSTR_LOGIN_LITE not initialized. Call init() first.'); - } - - console.log('Launch requested with screen:', startScreen); - - // Initialize modal if needed - if (!LiteState.modal) { - // Import modal lazily - if (typeof Modal !== 'undefined') { - LiteState.modal = Modal.init(LiteState.options); - } else { - console.error('Modal component not available'); - return; - } - } - - // Open modal with specified screen - LiteState.modal.open({ startScreen }); - } - - static logout() { - if (!LiteState.initialized) return; - - // Clear current account and state - Store.removeCurrentAccount(); - - // Reset internal state - LiteState.auth = null; - - // Emit logout event - window.dispatchEvent(new CustomEvent('nlLogout')); - LiteState.bus?.emit('logout'); - - console.log('Logged out'); - } - - static setDarkMode(dark) { - if (!LiteState.options) return; - - LiteState.options.darkMode = dark; - Store.setItem('darkMode', dark.toString()); - - // Update modal theme if initialized - if (LiteState.modal) { - // LiteState.modal.updateTheme(); - } - - window.dispatchEvent(new CustomEvent('nlDarkMode', { detail: { dark } })); - } - - static setAuth(o) { - if (!o || !o.type) return; - - console.log('setAuth called:', o); - - // Validate request - if (!['login', 'signup', 'logout'].includes(o.type)) { - throw new Error(`Invalid auth type: ${o.type}`); - } - - if (['login', 'signup'].includes(o.type) && !['connect', 'extension', 'local', 'otp', 'readOnly'].includes(o.method)) { - throw new Error(`Invalid auth method: ${o.method}`); - } - - // Handle based on type - switch (o.type) { - case 'logout': - this.logout(); - break; - default: - // Delegate to auth system - will be implemented - console.log('Auth delegation not yet implemented'); - } - } - - static cancelNeedAuth() { - // Cancel any ongoing auth flows - LiteState.bus?.emit('cancelAuth'); - console.log('Auth flow cancelled'); - } -} - -// Initialize the window.nostr facade -const windowNostr = { - async getPublicKey() { - if (!LiteState.initialized) { - throw new Error('NOSTR_LOGIN_LITE not initialized'); - } - - const current = Store.getCurrent(); - if (current && current.pubkey) { - return current.pubkey; - } - - // Trigger auth flow - const authPromise = new Promise((resolve, reject) => { - const handleAuth = (event) => { - window.removeEventListener('nlAuth', handleAuth); - if (event.detail.type === 'login' && event.detail.pubkey) { - resolve(event.detail.pubkey); - } else { - reject(new Error('Authentication cancelled')); - } - }; - - window.addEventListener('nlAuth', handleAuth); - - // Set timeout - setTimeout(() => { - window.removeEventListener('nlAuth', handleAuth); - reject(new Error('Authentication timeout')); - }, 300000); // 5 minutes - }); - - // Launch auth modal - NostrLite.launch('login'); - - return authPromise; - }, - - async signEvent(event) { - if (!LiteState.initialized) { - throw new Error('NOSTR_LOGIN_LITE not initialized'); - } - - let current = Store.getCurrent(); - - // If no current account, trigger auth - if (!current) { - await window.nostr.getPublicKey(); // This will trigger auth - current = Store.getCurrent(); - if (!current) { - throw new Error('Authentication failed'); - } - } - - // Route to appropriate signer - if (current.signer?.method === 'local' && current.signer.secret) { - const signer = new LocalSigner(this._hexToUint8Array(current.signer.secret)); - return await signer.sign(event); - } else if (current.signer?.method === 'nip46' && current.signer.bunkerSigner) { - // Route to NIP-46 remote signer - try { - const bunkerSigner = current.signer.bunkerSigner; - const signedEvent = await bunkerSigner.signEvent(event); - return signedEvent; - } catch (error) { - console.error('NIP-46 signEvent failed:', error); - throw new Error(`NIP-46 signing failed: ${error.message}`); - } - } else if (current.signer?.method === 'readonly') { - throw new Error('Cannot sign events in read-only mode'); - } else if (current.signer?.method === 'extension' && LiteState.extensionBridge?.hasExtension()) { - // Route to extension - const temp = window.nostr; - window.nostr = LiteState.extensionBridge.foundExtension; - try { - const signedEvent = await window.nostr.signEvent(event); - return signedEvent; - } finally { - window.nostr = temp; - } - } - - throw new Error('No suitable signer available for current account'); - }, - - _hexToUint8Array(hex) { - // Convert hex string to Uint8Array - const bytes = new Uint8Array(hex.length / 2); - for (let i = 0; i < bytes.length; i++) { - bytes[i] = parseInt(hex.substr(i * 2, 2), 16); - } - return bytes; - }, - - nip04: { - async encrypt(pubkey, plaintext) { - if (!LiteState.initialized) { - throw new Error('NOSTR_LOGIN_LITE not initialized'); - } - - const current = Store.getCurrent(); - if (!current) { - throw new Error('No authenticated user'); - } - - if (current.signer?.method === 'nip46' && current.signer.bunkerSigner) { - // Route to NIP-46 remote signer - try { - const bunkerSigner = current.signer.bunkerSigner; - return await bunkerSigner.nip04Encrypt(pubkey, plaintext); - } catch (error) { - console.error('NIP-46 nip04 encrypt failed:', error); - throw new Error(`NIP-46 encrypting failed: ${error.message}`); - } - } else if (current.signer?.method === 'local' && current.signer.secret) { - const signer = new LocalSigner(current.signer.secret); - return await signer.encrypt04(pubkey, plaintext); - } else if (current.signer?.method === 'extension' && LiteState.extensionBridge?.hasExtension()) { - const temp = window.nostr; - window.nostr = LiteState.extensionBridge.foundExtension; - try { - return await window.nostr.nip04.encrypt(pubkey, plaintext); - } finally { - window.nostr = temp; - } - } - - throw new Error('No suitable signer available for NIP-04 encryption'); - }, - - async decrypt(pubkey, ciphertext) { - if (!LiteState.initialized) { - throw new Error('NOSTR_LOGIN_LITE not initialized'); - } - - const current = Store.getCurrent(); - if (!current) { - throw new Error('No authenticated user'); - } - - if (current.signer?.method === 'nip46' && current.signer.bunkerSigner) { - // Route to NIP-46 remote signer - try { - const bunkerSigner = current.signer.bunkerSigner; - return await bunkerSigner.nip04Decrypt(pubkey, ciphertext); - } catch (error) { - console.error('NIP-46 nip04 decrypt failed:', error); - throw new Error(`NIP-46 decrypting failed: ${error.message}`); - } - } else if (current.signer?.method === 'local' && current.signer.secret) { - const signer = new LocalSigner(current.signer.secret); - return await signer.decrypt04(pubkey, ciphertext); - } else if (current.signer?.method === 'extension' && LiteState.extensionBridge?.hasExtension()) { - const temp = window.nostr; - window.nostr = LiteState.extensionBridge.foundExtension; - try { - return await window.nostr.nip04.decrypt(pubkey, ciphertext); - } finally { - window.nostr = temp; - } - } - - throw new Error('No suitable signer available for NIP-04 decryption'); - } - }, - - nip44: { - async encrypt(pubkey, plaintext) { - if (!LiteState.initialized) { - throw new Error('NOSTR_LOGIN_LITE not initialized'); - } - - const current = Store.getCurrent(); - if (!current) { - throw new Error('No authenticated user'); - } - - if (current.signer?.method === 'nip46' && current.signer.bunkerSigner) { - // Route to NIP-46 remote signer - try { - const bunkerSigner = current.signer.bunkerSigner; - return await bunkerSigner.nip44Encrypt(pubkey, plaintext); - } catch (error) { - console.error('NIP-46 nip44 encrypt failed:', error); - throw new Error(`NIP-46 encrypting failed: ${error.message}`); - } - } else if (current.signer?.method === 'local' && current.signer.secret) { - const signer = new LocalSigner(current.signer.secret); - return await signer.encrypt44(pubkey, plaintext); - } else if (current.signer?.method === 'extension' && LiteState.extensionBridge?.hasExtension()) { - // Use extension if it supports nip44 - const temp = window.nostr; - window.nostr = LiteState.extensionBridge.foundExtension; - try { - if (window.nostr.nip44) { - return await window.nostr.nip44.encrypt(pubkey, plaintext); - } else { - throw new Error('Extension does not support NIP-44'); - } - } finally { - window.nostr = temp; - } - } - - throw new Error('No suitable signer available for NIP-44 encryption'); - }, - - async decrypt(pubkey, ciphertext) { - if (!LiteState.initialized) { - throw new Error('NOSTR_LOGIN_LITE not initialized'); - } - - const current = Store.getCurrent(); - if (!current) { - throw new Error('No authenticated user'); - } - - if (current.signer?.method === 'nip46' && current.signer.bunkerSigner) { - // Route to NIP-46 remote signer - try { - const bunkerSigner = current.signer.bunkerSigner; - return await bunkerSigner.nip44Decrypt(pubkey, ciphertext); - } catch (error) { - console.error('NIP-46 nip44 decrypt failed:', error); - throw new Error(`NIP-46 decrypting failed: ${error.message}`); - } - } else if (current.signer?.method === 'local' && current.signer.secret) { - const signer = new LocalSigner(current.signer.secret); - return await signer.decrypt44(pubkey, ciphertext); - } else if (current.signer?.method === 'extension' && LiteState.extensionBridge?.hasExtension()) { - const temp = window.nostr; - window.nostr = LiteState.extensionBridge.foundExtension; - try { - if (window.nostr.nip44) { - return await window.nostr.nip44.decrypt(pubkey, ciphertext); - } else { - throw new Error('Extension does not support NIP-44'); - } - } finally { - window.nostr = temp; - } - } - - throw new Error('No suitable signer available for NIP-44 decryption'); - } - } -}; - -// Export the API -window.NOSTR_LOGIN_LITE = { - init: NostrLite.init.bind(NostrLite), - launch: NostrLite.launch.bind(NostrLite), - logout: NostrLite.logout.bind(NostrLite), - setDarkMode: NostrLite.setDarkMode.bind(NostrLite), - setAuth: NostrLite.setAuth.bind(NostrLite), - cancelNeedAuth: NostrLite.cancelNeedAuth.bind(NostrLite), - // Expose internal components for debugging - get _extensionBridge() { - return LiteState.extensionBridge; - }, - get _state() { - return LiteState; - } -}; - -// Set window.nostr facade properly (extensions will be handled by ExtensionBridge) -if (typeof window !== 'undefined') { - window.nostr = windowNostr; - - // Ensure all methods are properly exposed - console.log('NOSTR_LOGIN_LITE: window.nostr facade installed with methods:', Object.keys(windowNostr)); -} - -console.log('NOSTR_LOGIN_LITE loaded - use window.NOSTR_LOGIN_LITE.init(options) to initialize'); \ No newline at end of file diff --git a/lite/ui/modal.js b/lite/ui/modal.js index 6951eae..8297c54 100644 --- a/lite/ui/modal.js +++ b/lite/ui/modal.js @@ -165,8 +165,8 @@ class Modal { }); } - // Nostr Connect option - if (this.options?.methods?.connect !== false) { + // Nostr Connect option (check both 'connect' and 'remote' for compatibility) + if (this.options?.methods?.connect !== false && this.options?.methods?.remote !== false) { options.push({ type: 'connect', title: 'Nostr Connect', @@ -186,7 +186,7 @@ class Modal { } // OTP/DM option - if (this.options?.methods?.otp !== false && this.options?.otp) { + if (this.options?.methods?.otp !== false) { options.push({ type: 'otp', title: 'DM/OTP', @@ -858,11 +858,7 @@ class Modal { box-sizing: border-box; `; - // Pre-fill with our bunker config if available - if (window.NIP46_BUNKER_CONFIG) { - pubkeyInput.value = window.NIP46_BUNKER_CONFIG.remoteSigner.pubkey; - urlInput.value = window.NIP46_BUNKER_CONFIG.remoteSigner.url; - } + // Users will enter the bunker URL manually from their bunker setup const connectButton = document.createElement('button'); connectButton.textContent = 'Connect to Bunker'; @@ -956,9 +952,9 @@ class Modal { const localSecretKey = window.NostrTools.generateSecretKey(); console.log('Generated local client keypair for NIP-46 session'); - // Use nostr-tools BunkerSigner.fromBunker() for bunker:// connections + // Use nostr-tools BunkerSigner constructor console.log('Creating nip46 BunkerSigner...'); - const signer = window.NostrTools.nip46.BunkerSigner.fromBunker(localSecretKey, bunkerPointer, { + const signer = new window.NostrTools.nip46.BunkerSigner(localSecretKey, bunkerPointer, { onauth: (url) => { console.log('Received auth URL from bunker:', url); // Open auth URL in popup or redirect @@ -968,12 +964,8 @@ class Modal { console.log('NIP-46 BunkerSigner created successfully'); - // Attempt initial ping to verify connection - console.log('Testing bunker connection with ping...'); - await signer.ping(); - console.log('NIP-46 ping successful - bunker is reachable'); - - // Try to connect (this may trigger auth flow) + // Skip ping test - NIP-46 works through relays, not direct connection + // Try to connect directly (this may trigger auth flow) console.log('Attempting NIP-46 connect...'); await signer.connect(); console.log('NIP-46 connect successful'); diff --git a/nip46-test/README.md b/nip46-test/README.md new file mode 100644 index 0000000..7855d14 --- /dev/null +++ b/nip46-test/README.md @@ -0,0 +1,139 @@ +# 🏰 NIP-46 Remote Signer (Bunker) Test Setup + +This directory contains a complete NIP-46 remote signing setup for testing NOSTR_LOGIN_LITE. + +## 🔧 Setup Overview + +**Bunker**: A remote signer daemon that holds your private keys securely +**Client**: Browser client that connects to the bunker to request signatures +**NOSTR_LOGIN_LITE**: Connects to bunker for remote signing capability + +## 🔑 Generated Keys + +``` +Bunker Secret Key: a33767c3bd05bda47880119d6665b79e6f0eecdf8d025966b0b59a9366379d01 +Bunker Public Key: 7566048aa9df5b36428f2ce364797f7ac6f6d4a17ee566f0cd3fefcf35146b90 +``` + +## 🚀 Testing NIP-46 Remote Signing + +### Step 1: Start the Bunker + +```bash +# Open a new terminal and run: +./nip46-test/start-bunker.sh +``` + +You'll see output like: +``` +🔐 Starting NIP-46 Bunker Remote Signer... +============================================== +Bunker Public Key: 7566048aa9df5b36428f2ce364797f7ac6f6d4a17ee566f0cd3fefcf35146b90 +Secret key is securely held by bunker + +🚀 Starting bunker daemon... +{"time":"202X-XX-XXTXX:XX:XX.XXXZ","level":"info","msg":"starting bunker on ws://localhost:8080"} +{"time":"202X-XX-XXTXX:XX:XX.XXXZ","level":"info","msg":"bunker ready to handle NIP-46 requests"} +``` + +### Step 2: Test with NOSTR_LOGIN_LITE + +Navigate to: +``` +http://localhost:8000/examples/modal-login-demo.html +``` + +Click "🚀 Launch Authentication Modal" and select **"NIP-46 Remote"** option. + +The browser will connect to the bunker running on `ws://localhost:8080` and request signatures remotely. + +## 🔄 How NIP-46 Works + +``` +Browser (NOSTR_LOGIN_LITE) → WebSocket → Bunker (NAK on localhost:8080) + ↓ ↓ + Requests signature Holds private key + ↓ ↓ + Receives signed event Signs & returns result +``` + +## 📁 Files in this Directory + +- `start-bunker.sh` - Script to start the remote signer daemon +- `bunker-config.js` - Configuration for NOSTR_LOGIN_LITE +- `README.md` - This documentation + +## 🧪 Testing Scenarios + +### ✅ Successful Connection +- Bunker runs on localhost:8080 +- Browser connects and requests pubkey +- Bunker responds with `7566048aa9df5b36428f2ce364797f7ac6f6d4a17ee566f0cd3fefcf35146b90` + +### 🔧 Signature Requests +- Browser sends event to sign +- Bunker signs with private key +- Signed event returned to browser +- Browser publishes signed event to relay + +### 🐛 Debug Issues +- Check bunker logs for connection errors +- Verify WebSocket connection in browser dev tools +- Look for NIP-46 protocol errors + +## 📝 NOSTR_LOGIN_LITE Configuration + +In your app, configure remote signing like this: + +```javascript +const nip46Config = { + type: "nip46", + bunker: { + pubkey: "7566048aa9df5b36428f2ce364797f7ac6f6d4a17ee566f0cd3fefcf35146b90", + url: "ws://your-bunker-server:8080" // Production URL + } +}; + +await window.NOSTR_LOGIN_LITE.init(nip46Config); +``` + +## ⚠️ Production Notes + +- **This setup uses localhost** - replace with real server URL in production +- **Private key is shown for testing** - production bunkers should be secured +- **WebSocket URL should be secure** (wss://) in production +- **Consider authentication** for your bunker to prevent unauthorized access + +## 🎯 Common Testing Commands + +### Check NAK version +```bash +nak --version +``` + +### Generate new keys (if needed) +```bash +nak key generate # Secret key +echo "your_secret_key_here" | nak key public # Public key +``` + +### Manual bunker test +```bash +nak bunker --sec "your_secret_key" --port 8080 --relay "wss://relay.damus.io" +``` + +## 🐛 Troubleshooting + +**Bunker won't start:** +- Check if port 8080 is free +- Verify NAK is installed correctly + +**Browser can't connect:** +- Check firewall settings +- Verify bunker is running (`ps aux | grep nak`) +- Check browser console for WebSocket errors + +**Signing fails:** +- Verify keys are correct +- Check bunker logs for errors +- Ensure event format is valid \ No newline at end of file diff --git a/nip46-test/start-bunker.sh b/nip46-test/start-bunker.sh new file mode 100755 index 0000000..4194734 --- /dev/null +++ b/nip46-test/start-bunker.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# NIP-46 Remote Signer Bunker Setup +# Self-contained script to run a test bunker for NOSTR_LOGIN_LITE + +echo "🔐 Starting NIP-46 Bunker Remote Signer..." +echo "==============================================" + +# NIP-46 Keys (Generated with NAK for testing) + +BUNKER_SECRET_KEY="a33767c3bd05bda47880119d6665b79e6f0eecdf8d025966b0b59a9366379d01" +BUNKER_PUB_KEY="7566048aa9df5b36428f2ce364797f7ac6f6d4a17ee566f0cd3fefcf35146b90" + + + +RELAY_URL="wss://relay.laantungir.net" +# RELAY_URL="wss://nostr.mom" + +echo "Bunker Configuration:" +echo " Public Key: $BUNKER_PUB_KEY" +echo " Relay URL: $RELAY_URL" +echo " Secret key securely held by bunker process" +echo "" + +# Check if nak is installed +if ! command -v nak &> /dev/null; then + echo "❌ Error: 'nak' command not found" + echo "Please install nak from: https://github.com/fiatjaf/nak" + echo "Or run: go install github.com/fiatjaf/nak@latest" + exit 1 +fi + +echo "🚀 Starting bunker daemon..." +echo "The bunker will display a QR code with the connection URL" +echo "Copy the bunker:// URL and paste it into the NOSTR_LOGIN_LITE modal" +echo "" +echo "Press Ctrl+C to stop the bunker" +echo "==============================================" + +# Start the NAK bunker daemon +# This listens for NIP-46 requests via the relay and handles signing operations +nak bunker --sec "$BUNKER_SECRET_KEY" --qrcode --verbose "$RELAY_URL" \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 937e17e..79e3f20 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,8 @@ "": { "name": "nostr-login-workspace", "dependencies": { - "@nostr-dev-kit/ndk": "^2.4.0" + "@nostr-dev-kit/ndk": "^2.4.0", + "nostr-tools": "^2.16.2" }, "devDependencies": { "lerna": "^8.0.2" @@ -17,30 +18,6 @@ ] } }, - "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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@babel/code-frame": { "version": "7.23.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", @@ -116,216 +93,6 @@ "node": ">=4" } }, - "node_modules/@babel/compat-data": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", - "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz", - "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.9", - "@babel/parser": "^7.23.9", - "@babel/template": "^7.23.9", - "@babel/traverse": "^7.23.9", - "@babel/types": "^7.23.9", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.23.6", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", - "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-validator-option": "^7.23.5", - "browserslist": "^4.22.2", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dev": true, - "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-validator-identifier": { "version": "7.22.20", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", @@ -335,29 +102,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-validator-option": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.9.tgz", - "integrity": "sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==", - "dev": true, - "dependencies": { - "@babel/template": "^7.23.9", - "@babel/traverse": "^7.23.9", - "@babel/types": "^7.23.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/highlight": { "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", @@ -434,306 +178,6 @@ "node": ">=4" } }, - "node_modules/@babel/parser": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", - "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", - "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", - "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz", - "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==", - "dev": true, - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz", - "integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.23.9", - "@babel/types": "^7.23.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz", - "integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.9", - "@babel/types": "^7.23.9", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz", - "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "node_modules/@hapi/address": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", - "integrity": "sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==", - "deprecated": "Moved to 'npm install @sideway/address'", - "dev": true - }, - "node_modules/@hapi/bourne": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz", - "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==", - "deprecated": "This version has been deprecated and is no longer supported or maintained", - "dev": true - }, - "node_modules/@hapi/hoek": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz", - "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==", - "deprecated": "This version has been deprecated and is no longer supported or maintained", - "dev": true - }, - "node_modules/@hapi/joi": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz", - "integrity": "sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==", - "deprecated": "Switch to 'npm install joi'", - "dev": true, - "dependencies": { - "@hapi/address": "2.x.x", - "@hapi/bourne": "1.x.x", - "@hapi/hoek": "8.x.x", - "@hapi/topo": "3.x.x" - } - }, - "node_modules/@hapi/topo": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz", - "integrity": "sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==", - "deprecated": "This version has been deprecated and is no longer supported or maintained", - "dev": true, - "dependencies": { - "@hapi/hoek": "^8.3.0" - } - }, "node_modules/@hutson/parse-repository-url": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", @@ -747,6 +191,7 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -763,6 +208,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, "engines": { "node": ">=12" }, @@ -774,6 +220,7 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, "engines": { "node": ">=12" }, @@ -784,12 +231,14 @@ "node_modules/@isaacs/cliui/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==" + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true }, "node_modules/@isaacs/cliui/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, "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -806,6 +255,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, "dependencies": { "ansi-regex": "^6.0.1" }, @@ -820,6 +270,7 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -832,264 +283,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", - "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/core": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", - "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", - "dev": true, - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/reporters": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.7.0", - "jest-config": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-resolve-dependencies": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "jest-watcher": "^29.7.0", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/environment": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", - "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", - "dev": true, - "dependencies": { - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", - "dev": true, - "dependencies": { - "expect": "^29.7.0", - "jest-snapshot": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/expect-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", - "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", - "dev": true, - "dependencies": { - "jest-get-type": "^29.6.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/fake-timers": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", - "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "@sinonjs/fake-timers": "^10.0.2", - "@types/node": "*", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/globals": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", - "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/types": "^29.6.3", - "jest-mock": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/reporters": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", - "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", - "dev": true, - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^6.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "v8-to-istanbul": "^9.0.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/reporters/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@jest/reporters/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -1102,159 +295,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/source-map": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", - "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.18", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/test-result": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", - "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", - "dev": true, - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/test-sequencer": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", - "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", - "dev": true, - "dependencies": { - "@jest/test-result": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/transform": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", - "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", - "dev": true, - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/transform/node_modules/write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "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==", - "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.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "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==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" - }, - "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==", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, "node_modules/@lerna/create": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@lerna/create/-/create-8.0.2.tgz", @@ -1331,9 +371,10 @@ } }, "node_modules/@noble/ciphers": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.2.0.tgz", - "integrity": "sha512-6YBxJDAapHSdd3bLDv6x2wRPwq4QFMUaB3HvljNBUTThDd12eSm7/3F+2lnfzx2jvM+S6Nsy0jEt9QbPqSwqRw==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.5.3.tgz", + "integrity": "sha512-B0+6IIHiqEs3BPMT0hcRmHvEj2QHOLu+uwt+tqDDeVd0oyVzh7BPrDcPjRnV1PV/5LaknXJJQvOuRGR0zQJz+w==", + "license": "MIT", "funding": { "url": "https://paulmillr.com/funding/" } @@ -1386,6 +427,7 @@ "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, "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -1398,6 +440,7 @@ "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, "engines": { "node": ">= 8" } @@ -1406,6 +449,7 @@ "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, "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -1432,6 +476,39 @@ "websocket-polyfill": "^0.0.3" } }, + "node_modules/@nostr-dev-kit/ndk/node_modules/@noble/ciphers": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.2.0.tgz", + "integrity": "sha512-6YBxJDAapHSdd3bLDv6x2wRPwq4QFMUaB3HvljNBUTThDd12eSm7/3F+2lnfzx2jvM+S6Nsy0jEt9QbPqSwqRw==", + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nostr-dev-kit/ndk/node_modules/@noble/hashes": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", + "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nostr-dev-kit/ndk/node_modules/@scure/base": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", + "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT" + }, "node_modules/@nostr-dev-kit/ndk/node_modules/data-uri-to-buffer": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", @@ -1457,6 +534,28 @@ "url": "https://opencollective.com/node-fetch" } }, + "node_modules/@nostr-dev-kit/ndk/node_modules/nostr-tools": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/nostr-tools/-/nostr-tools-1.17.0.tgz", + "integrity": "sha512-LZmR8GEWKZeElbFV5Xte75dOeE9EFUW/QLI1Ncn3JKn0kFddDKEfBbFN8Mu4TMs+L4HR/WTPha2l+PPuRnJcMw==", + "license": "Unlicense", + "dependencies": { + "@noble/ciphers": "0.2.0", + "@noble/curves": "1.1.0", + "@noble/hashes": "1.3.1", + "@scure/base": "1.1.1", + "@scure/bip32": "1.3.1", + "@scure/bip39": "1.2.1" + }, + "peerDependencies": { + "typescript": ">=5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/@npmcli/agent": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.2.0.tgz", @@ -1992,375 +1091,12 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, "optional": true, "engines": { "node": ">=14" } }, - "node_modules/@puppeteer/browsers": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.7.0.tgz", - "integrity": "sha512-sl7zI0IkbQGak/+IE3VEEZab5SSOlI5F6558WvzWGC1n3+C722rfewC1ZIkcF9dsoGSsxhsONoseVlNQG4wWvQ==", - "dev": true, - "dependencies": { - "debug": "4.3.4", - "extract-zip": "2.0.1", - "progress": "2.0.3", - "proxy-agent": "6.3.0", - "tar-fs": "3.0.4", - "unbzip2-stream": "1.4.3", - "yargs": "17.7.1" - }, - "bin": { - "browsers": "lib/cjs/main-cli.js" - }, - "engines": { - "node": ">=16.3.0" - } - }, - "node_modules/@puppeteer/browsers/node_modules/yargs": { - "version": "17.7.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", - "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", - "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@rollup/plugin-commonjs": { - "version": "25.0.7", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.7.tgz", - "integrity": "sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "commondir": "^1.0.1", - "estree-walker": "^2.0.2", - "glob": "^8.0.3", - "is-reference": "1.2.1", - "magic-string": "^0.30.3" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.68.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-commonjs/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, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@rollup/plugin-commonjs/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@rollup/plugin-commonjs/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@rollup/plugin-node-resolve": { - "version": "15.2.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", - "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "@types/resolve": "1.20.2", - "deepmerge": "^4.2.2", - "is-builtin-module": "^3.2.1", - "is-module": "^1.0.0", - "resolve": "^1.22.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.78.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-terser": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", - "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", - "dev": true, - "dependencies": { - "serialize-javascript": "^6.0.1", - "smob": "^1.0.0", - "terser": "^5.17.4" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-terser/node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/@rollup/pluginutils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", - "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", - "dev": true, - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.1.tgz", - "integrity": "sha512-4C4UERETjXpC4WpBXDbkgNVgHyWfG3B/NKY46e7w5H134UDOFqUJKpsLm0UYmuupW+aJmRgeScrDNfvZ5WV80A==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.1.tgz", - "integrity": "sha512-TrTaFJ9pXgfXEiJKQ3yQRelpQFqgRzVR9it8DbeRzG0RX7mKUy0bqhCFsgevwXLJepQKTnLl95TnPGf9T9AMOA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.1.tgz", - "integrity": "sha512-fz7jN6ahTI3cKzDO2otQuybts5cyu0feymg0bjvYCBrZQ8tSgE8pc0sSNEuGvifrQJWiwx9F05BowihmLxeQKw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.1.tgz", - "integrity": "sha512-WTvdz7SLMlJpektdrnWRUN9C0N2qNHwNbWpNo0a3Tod3gb9leX+yrYdCeB7VV36OtoyiPAivl7/xZ3G1z5h20g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.1.tgz", - "integrity": "sha512-dBHQl+7wZzBYcIF6o4k2XkAfwP2ks1mYW2q/Gzv9n39uDcDiAGDqEyml08OdY0BIct0yLSPkDTqn4i6czpBLLw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.1.tgz", - "integrity": "sha512-bur4JOxvYxfrAmocRJIW0SADs3QdEYK6TQ7dTNz6Z4/lySeu3Z1H/+tl0a4qDYv0bCdBpUYM0sYa/X+9ZqgfSQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.1.tgz", - "integrity": "sha512-ssp77SjcDIUSoUyj7DU7/5iwM4ZEluY+N8umtCT9nBRs3u045t0KkW02LTyHouHDomnMXaXSZcCSr2bdMK63kA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.1.tgz", - "integrity": "sha512-Jv1DkIvwEPAb+v25/Unrnnq9BO3F5cbFPT821n3S5litkz+O5NuXuNhqtPx5KtcwOTtaqkTsO+IVzJOsxd11aQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.13.1.tgz", - "integrity": "sha512-U564BrhEfaNChdATQaEODtquCC7Ez+8Hxz1h5MAdMYj0AqD0GA9rHCpElajb/sQcaFL6NXmHc5O+7FXpWMa73Q==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.1.tgz", - "integrity": "sha512-zGRDulLTeDemR8DFYyFIQ8kMP02xpUsX4IBikc7lwL9PrwR3gWmX2NopqiGlI2ZVWMl15qZeUjumTwpv18N7sQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.1.tgz", - "integrity": "sha512-VTk/MveyPdMFkYJJPCkYBw07KcTkGU2hLEyqYMsU4NjiOfzoaDTW9PWGRsNwiOA3qI0k/JQPjkl/4FCK1smskQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.1.tgz", - "integrity": "sha512-L+hX8Dtibb02r/OYCsp4sQQIi3ldZkFI0EUkMTDwRfFykXBPptoz/tuuGqEd3bThBSLRWPR6wsixDSgOx/U3Zw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.1.tgz", - "integrity": "sha512-+dI2jVPfM5A8zme8riEoNC7UKk0Lzc7jCj/U89cQIrOjrZTCWZl/+IXUeRT2rEZ5j25lnSA9G9H1Ob9azaF/KQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.1.tgz", - "integrity": "sha512-YY1Exxo2viZ/O2dMHuwQvimJ0SqvL+OAWQLLY6rvXavgQKjhQUzn7nc1Dd29gjB5Fqi00nrBWctJBOyfVMIVxw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@scure/base": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.5.tgz", @@ -2639,71 +1375,6 @@ "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", "dev": true }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^3.0.0" - } - }, - "node_modules/@stencil/core": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.20.0.tgz", - "integrity": "sha512-WPrTHFngvN081RY+dJPneKQLwnOFD60OMCOQGmmSHfCW0f4ujPMzzhwWU1gcSwXPWXz5O+8cBiiCaxAbJU7kAg==", - "bin": { - "stencil": "bin/stencil" - }, - "engines": { - "node": ">=16.0.0", - "npm": ">=7.10.0" - } - }, - "node_modules/@stencil/sass": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/@stencil/sass/-/sass-3.0.12.tgz", - "integrity": "sha512-aXMgpG13ftxLYo2dDauapvE9gKzSxTAqCMOfTqbPhKUCZ43JsknkLx+PArRaFtfYeVGSQ8eTS4ck7/Nlec+PNA==", - "engines": { - "node": ">=12.0.0", - "npm": ">=6.0.0" - }, - "peerDependencies": { - "@stencil/core": ">=2.0.0 || >=3.0.0-beta.0 || >= 4.0.0-beta.0 || >= 4.0.0" - } - }, - "node_modules/@stencil/store": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/@stencil/store/-/store-2.0.16.tgz", - "integrity": "sha512-ET3EByKlmNyTA8O+tcp5YWePOiVnPIiuoiIaxTrf3zFFVo7JWVsVoak9IE0UTn3MkIM0ubR9lgxvi70uN588/A==", - "engines": { - "node": ">=12.0.0", - "npm": ">=6.0.0" - }, - "peerDependencies": { - "@stencil/core": ">=2.0.0 || >=3.0.0 || >= 4.0.0-beta.0 || >= 4.0.0" - } - }, - "node_modules/@tailwindcss/forms": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.7.tgz", - "integrity": "sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw==", - "dependencies": { - "mini-svg-data-uri": "^1.2.3" - }, - "peerDependencies": { - "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1" - } - }, "node_modules/@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", @@ -2713,21 +1384,6 @@ "node": ">= 10" } }, - "node_modules/@tootallnate/quickjs-emscripten": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", - "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", - "dev": true - }, - "node_modules/@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/@tufjs/canonical-json": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-1.0.0.tgz", @@ -2774,96 +1430,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz", - "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.20.7" - } - }, - "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 - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", - "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "29.5.12", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", - "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", - "dev": true, - "dependencies": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" - } - }, "node_modules/@types/minimatch": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", @@ -2876,64 +1442,12 @@ "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", "dev": true }, - "node_modules/@types/node": { - "version": "16.18.76", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.76.tgz", - "integrity": "sha512-/GsO2uv1Z6R42lBr59dtem56gVF/yHKQaScggwU+gLU6DXE25sDmOar4c4IfWb3h+X/7OYZznPOFk7oGF3jQSA==", - "dev": true - }, "node_modules/@types/normalize-package-data": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", "dev": true }, - "node_modules/@types/qrcode": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@types/qrcode/-/qrcode-1.5.5.tgz", - "integrity": "sha512-CdfBi/e3Qk+3Z/fXYShipBT13OJ2fDO2Q2w5CIP5anLTLIndQG9z6P1cnm+8zCWSpm5dnxMFd/uREtb0EXuQzg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/resolve": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", - "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", - "dev": true - }, - "node_modules/@types/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "dev": true - }, - "node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true - }, - "node_modules/@types/yauzl": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", - "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", - "dev": true, - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@yarnpkg/lockfile": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", @@ -2996,18 +1510,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/add-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", @@ -3079,6 +1581,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "engines": { "node": ">=8" } @@ -3087,6 +1590,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -3097,23 +1601,6 @@ "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==" - }, - "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==", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", @@ -3133,11 +1620,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "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==" - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -3177,18 +1659,6 @@ "node": ">=0.10.0" } }, - "node_modules/ast-types": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", - "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", - "dev": true, - "dependencies": { - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/async": { "version": "3.2.5", "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", @@ -3201,43 +1671,6 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "dev": true }, - "node_modules/autoprefixer": { - "version": "10.4.17", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.17.tgz", - "integrity": "sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==", - "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" - } - ], - "dependencies": { - "browserslist": "^4.22.2", - "caniuse-lite": "^1.0.30001578", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "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.6.7", "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", @@ -3249,185 +1682,11 @@ "proxy-from-env": "^1.1.0" } }, - "node_modules/b4a": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", - "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==", - "dev": true - }, - "node_modules/babel-extract-comments": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/babel-extract-comments/-/babel-extract-comments-1.0.0.tgz", - "integrity": "sha512-qWWzi4TlddohA91bFwgt6zO/J0X+io7Qp184Fw0m2JYRSTZnJbFR8+07KmzudHCZgOiKRCrjhylwv9Xd8gfhVQ==", - "dev": true, - "dependencies": { - "babylon": "^6.18.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/babel-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", - "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", - "dev": true, - "dependencies": { - "@jest/transform": "^29.7.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.6.3", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-istanbul/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", - "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", - "dev": true, - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/babel-plugin-syntax-object-rest-spread": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", - "integrity": "sha512-C4Aq+GaAj83pRQ0EFgTvw5YO6T3Qz2KGrNRwIj9mSoNHVvdZY4KO2uA6HNtNXCw993iSZnckY1aLW8nOi8i4+w==", - "dev": true - }, - "node_modules/babel-plugin-transform-object-rest-spread": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", - "integrity": "sha512-ocgA9VJvyxwt+qJB0ncxV8kb/CjfTcECUY4tQ5VT7nP6Aohzobm8CDFaQ5FHdvZQzLmf0sgDxB8iRXZXxwZcyA==", - "dev": true, - "dependencies": { - "babel-plugin-syntax-object-rest-spread": "^6.8.0", - "babel-runtime": "^6.26.0" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-jest": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", - "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", - "dev": true, - "dependencies": { - "babel-plugin-jest-hoist": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", - "dev": true, - "dependencies": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "node_modules/babel-runtime/node_modules/regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "node_modules/babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true, - "bin": { - "babylon": "bin/babylon.js" - } - }, "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==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "node_modules/base64-js": { "version": "1.5.1", @@ -3449,29 +1708,12 @@ } ] }, - "node_modules/basic-ftp": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.4.tgz", - "integrity": "sha512-8PzkB0arJFV4jJWSGOYR+OEic6aeKMu/osRhBULN6RY0ykby6LKhbmuQ5ublvaas5BOwboah5D87nrHyuh8PPA==", - "dev": true, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/before-after-hook": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", "dev": true }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "engines": { - "node": ">=8" - } - }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -3483,12 +1725,6 @@ "readable-stream": "^3.4.0" } }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3503,6 +1739,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, "dependencies": { "fill-range": "^7.1.1" }, @@ -3510,47 +1747,6 @@ "node": ">=8" } }, - "node_modules/browserslist": { - "version": "4.22.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.3.tgz", - "integrity": "sha512-UAp55yfwNv0klWNapjs/ktHoguxuQNGnOzxYmfnXIS+8AsRDZkSDxg7R1AX3GKzn078SBI5dzwzj/Yx0Or0e3A==", - "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" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001580", - "electron-to-chromium": "^1.4.648", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "dependencies": { - "node-int64": "^0.4.0" - } - }, "node_modules/buffer": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", @@ -3575,15 +1771,6 @@ "ieee754": "^1.1.13" } }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -3602,18 +1789,6 @@ "node": ">=6.14.2" } }, - "node_modules/builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/builtins": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", @@ -3689,18 +1864,11 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, "engines": { "node": ">=6" } }, - "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==", - "engines": { - "node": ">= 6" - } - }, "node_modules/camelcase-keys": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", @@ -3718,38 +1886,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "dev": true, - "dependencies": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001581", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001581.tgz", - "integrity": "sha512-whlTkwhqV2tUmP3oYhtNfaWGYHDdS3JYFQBKXxcUR9qqPWsRhFHhoISO2Xnl/g0xyKzht9mI1LZpiNWfMzHixQ==", - "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" - } - ] - }, "node_modules/chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -3766,47 +1902,12 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "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" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, "node_modules/chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", @@ -3816,18 +1917,6 @@ "node": ">=10" } }, - "node_modules/chromium-bidi": { - "version": "0.4.22", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.22.tgz", - "integrity": "sha512-wR7Y9Ioez+cNXT4ZP7VNM1HRTljpNnMSLw4/RnwhhZUP4yCU7kIQND00YiktuHekch68jklGPK1q9Jkb29+fQg==", - "dev": true, - "dependencies": { - "mitt": "3.0.1" - }, - "peerDependencies": { - "devtools-protocol": "*" - } - }, "node_modules/ci-info": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", @@ -3843,12 +1932,6 @@ "node": ">=8" } }, - "node_modules/cjs-module-lexer": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", - "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", - "dev": true - }, "node_modules/clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -3966,26 +2049,11 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true, - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/collect-v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", - "dev": true - }, "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, "dependencies": { "color-name": "~1.1.4" }, @@ -3996,7 +2064,8 @@ "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==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/color-support": { "version": "1.1.3", @@ -4007,12 +2076,6 @@ "color-support": "bin.js" } }, - "node_modules/colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", - "dev": true - }, "node_modules/columnify": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.6.0.tgz", @@ -4038,30 +2101,6 @@ "node": ">= 0.8" } }, - "node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/common-tags": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", - "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", - "dev": true, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true - }, "node_modules/compare-func": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", @@ -4215,20 +2254,6 @@ "node": ">=14" } }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "node_modules/core-js": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", - "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", - "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", - "dev": true, - "hasInstallScript": true - }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", @@ -4261,60 +2286,11 @@ } } }, - "node_modules/create-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", - "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "prompts": "^2.0.1" - }, - "bin": { - "create-jest": "bin/create-jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/cross-fetch": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", - "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", - "dev": true, - "dependencies": { - "node-fetch": "^2.6.12" - } - }, - "node_modules/cross-fetch/node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dev": true, - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, "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, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -4327,12 +2303,14 @@ "node_modules/cross-spawn/node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, "node_modules/cross-spawn/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, "dependencies": { "isexe": "^2.0.0" }, @@ -4343,158 +2321,6 @@ "node": ">= 8" } }, - "node_modules/css-declaration-sorter": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", - "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.0.9" - } - }, - "node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dev": true, - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "dev": true, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "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==", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cssnano": { - "version": "5.1.15", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", - "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", - "dev": true, - "dependencies": { - "cssnano-preset-default": "^5.2.14", - "lilconfig": "^2.0.3", - "yaml": "^1.10.2" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/cssnano" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/cssnano-preset-default": { - "version": "5.2.14", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", - "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", - "dev": true, - "dependencies": { - "css-declaration-sorter": "^6.3.1", - "cssnano-utils": "^3.1.0", - "postcss-calc": "^8.2.3", - "postcss-colormin": "^5.3.1", - "postcss-convert-values": "^5.1.3", - "postcss-discard-comments": "^5.1.2", - "postcss-discard-duplicates": "^5.1.0", - "postcss-discard-empty": "^5.1.1", - "postcss-discard-overridden": "^5.1.0", - "postcss-merge-longhand": "^5.1.7", - "postcss-merge-rules": "^5.1.4", - "postcss-minify-font-values": "^5.1.0", - "postcss-minify-gradients": "^5.1.1", - "postcss-minify-params": "^5.1.4", - "postcss-minify-selectors": "^5.2.1", - "postcss-normalize-charset": "^5.1.0", - "postcss-normalize-display-values": "^5.1.0", - "postcss-normalize-positions": "^5.1.1", - "postcss-normalize-repeat-style": "^5.1.1", - "postcss-normalize-string": "^5.1.0", - "postcss-normalize-timing-functions": "^5.1.0", - "postcss-normalize-unicode": "^5.1.1", - "postcss-normalize-url": "^5.1.0", - "postcss-normalize-whitespace": "^5.1.1", - "postcss-ordered-values": "^5.1.3", - "postcss-reduce-initial": "^5.1.2", - "postcss-reduce-transforms": "^5.1.0", - "postcss-svgo": "^5.1.0", - "postcss-unique-selectors": "^5.1.1" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/cssnano-utils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", - "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "dev": true, - "dependencies": { - "css-tree": "^1.1.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/d": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", @@ -4513,15 +2339,6 @@ "node": ">=8" } }, - "node_modules/data-uri-to-buffer": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.1.tgz", - "integrity": "sha512-MZd3VlchQkp8rdend6vrx7MmVDJzSNTBvghvKjirLkD+WTChA3KUf0jkE68Q4UyctNqI11zZO9/x2Yx+ub5Cvg==", - "dev": true, - "engines": { - "node": ">= 14" - } - }, "node_modules/dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", @@ -4551,6 +2368,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -4586,15 +2404,6 @@ "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", "dev": true }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/defaults": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", @@ -4616,20 +2425,6 @@ "node": ">=8" } }, - "node_modules/degenerator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", - "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", - "dev": true, - "dependencies": { - "ast-types": "^0.13.4", - "escodegen": "^2.1.0", - "esprima": "^4.0.1" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -4660,26 +2455,6 @@ "node": ">=4" } }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/devtools-protocol": { - "version": "0.0.1159816", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1159816.tgz", - "integrity": "sha512-2cZlHxC5IlgkIWe2pSDmCrDiTzbSJWywjbDDnupOImEBcG31CQgBLV8wWE+5t+C4rimcjHsbzy7CBzf9oFjboA==", - "dev": true - }, - "node_modules/didyoumean": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" - }, "node_modules/diff-sequences": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", @@ -4689,11 +2464,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/dijkstrajs": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz", - "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==" - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -4706,66 +2476,6 @@ "node": ">=8" } }, - "node_modules/dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" - }, - "node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "dev": true, - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dev": true, - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dev": true, - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, "node_modules/dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", @@ -4808,7 +2518,8 @@ "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true }, "node_modules/ejs": { "version": "3.1.9", @@ -4825,28 +2536,11 @@ "node": ">=0.10.0" } }, - "node_modules/electron-to-chromium": { - "version": "1.4.648", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.648.tgz", - "integrity": "sha512-EmFMarXeqJp9cUKu/QEciEApn0S/xRcpZWuAm32U7NgoZCimjsilKXHRO9saeEW55eHZagIDg6XTUOv32w9pjg==", - "dev": true - }, - "node_modules/emittery": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", - "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, "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==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/encoding": { "version": "0.1.13", @@ -4892,15 +2586,6 @@ "node": ">=8.6" } }, - "node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", @@ -4988,27 +2673,6 @@ "node": ">=0.8.0" } }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "dev": true, - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -5022,30 +2686,6 @@ "node": ">=4" } }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", @@ -5075,31 +2715,6 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", - "dev": true, - "dependencies": { - "@jest/expect-utils": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/exponential-backoff": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", @@ -5145,51 +2760,11 @@ "node": ">=0.6.0" } }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" - } - }, - "node_modules/extract-zip/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/fast-fifo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", - "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "dev": true - }, "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, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -5201,38 +2776,15 @@ "node": ">=8.6.0" } }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, "node_modules/fastq": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.0.tgz", "integrity": "sha512-zGygtijUMT7jnk3h26kUms3BkSDp4IfIKjmnqI2tvx6nuBfiF1UqOxbnLfzdv+apBy+53oaImsKtMw/xYbW+1w==", + "dev": true, "dependencies": { "reusify": "^1.0.4" } }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dev": true, - "dependencies": { - "bser": "2.1.1" - } - }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dev": true, - "dependencies": { - "pend": "~1.2.0" - } - }, "node_modules/fetch-blob": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", @@ -5304,6 +2856,7 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -5311,51 +2864,11 @@ "node": ">=8" } }, - "node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dev": true, - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" - } - }, - "node_modules/find-cache-dir/node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/find-cache-dir/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -5397,6 +2910,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -5412,6 +2926,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, "engines": { "node": ">=14" }, @@ -5444,19 +2959,6 @@ "node": ">=12.20.0" } }, - "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, - "engines": { - "node": "*" - }, - "funding": { - "type": "patreon", - "url": "https://github.com/sponsors/rawify" - } - }, "node_modules/fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", @@ -5495,23 +2997,11 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "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, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -5535,36 +3025,13 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", - "dev": true - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true, "engines": { - "node": ">=8.0.0" + "node": "6.* || 8.* || >= 10.*" } }, "node_modules/get-pkg-repo": { @@ -5664,53 +3131,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-uri": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.2.tgz", - "integrity": "sha512-5KLucCJobh8vBY1K07EFV4+cPZH3mrV9YeAruUseCQKHB58SGjjT2l9/eA9LD082IiuMjSlFJEcdJ27TXvbZNw==", - "dev": true, - "dependencies": { - "basic-ftp": "^5.0.2", - "data-uri-to-buffer": "^6.0.0", - "debug": "^4.3.4", - "fs-extra": "^8.1.0" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/get-uri/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/get-uri/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/get-uri/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/git-raw-commits": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-3.0.0.tgz", @@ -5798,6 +3218,7 @@ "version": "10.3.10", "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^2.3.5", @@ -5819,6 +3240,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -5830,6 +3252,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -5838,6 +3261,7 @@ "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -5848,15 +3272,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", @@ -5932,6 +3347,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -5951,12 +3367,6 @@ "node": ">=10" } }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, "node_modules/http-cache-semantics": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", @@ -6286,32 +3696,6 @@ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, - "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==", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-builtin-module": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", - "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", - "dev": true, - "dependencies": { - "builtin-modules": "^3.3.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-ci": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", @@ -6328,6 +3712,7 @@ "version": "2.13.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, "dependencies": { "hasown": "^2.0.0" }, @@ -6354,6 +3739,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -6362,23 +3748,16 @@ "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true, "engines": { - "node": ">=6" + "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, "dependencies": { "is-extglob": "^2.1.1" }, @@ -6401,16 +3780,11 @@ "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", "dev": true }, - "node_modules/is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", - "dev": true - }, "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, "engines": { "node": ">=0.12.0" } @@ -6442,24 +3816,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-reference": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "dev": true, - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-ssh": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.0.tgz", @@ -6543,76 +3899,11 @@ "node": ">=0.10.0" } }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz", - "integrity": "sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==", - "dev": true, - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jackspeak": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, "dependencies": { "@isaacs/cliui": "^8.0.2" }, @@ -6656,231 +3947,6 @@ "node": "*" } }, - "node_modules/jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", - "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", - "dev": true, - "dependencies": { - "@jest/core": "^29.7.0", - "@jest/types": "^29.6.3", - "import-local": "^3.0.2", - "jest-cli": "^29.7.0" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-changed-files": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", - "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", - "dev": true, - "dependencies": { - "execa": "^5.0.0", - "jest-util": "^29.7.0", - "p-limit": "^3.1.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-changed-files/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-circus": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", - "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^1.0.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^29.7.0", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "p-limit": "^3.1.0", - "pretty-format": "^29.7.0", - "pure-rand": "^6.0.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-circus/node_modules/dedent": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", - "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", - "dev": true, - "peerDependencies": { - "babel-plugin-macros": "^3.1.0" - }, - "peerDependenciesMeta": { - "babel-plugin-macros": { - "optional": true - } - } - }, - "node_modules/jest-circus/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-cli": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", - "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", - "dev": true, - "dependencies": { - "@jest/core": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "create-jest": "^29.7.0", - "exit": "^0.1.2", - "import-local": "^3.0.2", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "yargs": "^17.3.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-config": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", - "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", - "dev": true, - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-jest": "^29.7.0", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-circus": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@types/node": "*", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-config/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/jest-config/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/jest-diff": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", @@ -6896,51 +3962,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-docblock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", - "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", - "dev": true, - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-each": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", - "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "jest-util": "^29.7.0", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-environment-node": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", - "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/jest-get-type": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", @@ -6950,398 +3971,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-haste-map": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", - "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "node_modules/jest-leak-detector": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", - "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", - "dev": true, - "dependencies": { - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-matcher-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", - "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-message-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", - "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.6.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-mock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", - "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "dev": true, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "node_modules/jest-regex-util": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", - "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-resolve": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", - "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "resolve": "^1.20.0", - "resolve.exports": "^2.0.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", - "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", - "dev": true, - "dependencies": { - "jest-regex-util": "^29.6.3", - "jest-snapshot": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-runner": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", - "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", - "dev": true, - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/environment": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-leak-detector": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-resolve": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-util": "^29.7.0", - "jest-watcher": "^29.7.0", - "jest-worker": "^29.7.0", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-runner/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-runtime": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", - "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/globals": "^29.7.0", - "@jest/source-map": "^29.6.3", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-runtime/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/jest-runtime/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/jest-snapshot": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", - "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", - "dev": true, - "dependencies": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.7.0", - "semver": "^7.5.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-validate": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", - "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "leven": "^3.1.0", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-watcher": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", - "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", - "dev": true, - "dependencies": { - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "jest-util": "^29.7.0", - "string-length": "^4.0.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", - "dev": true, - "dependencies": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/jiti": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", - "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", - "bin": { - "jiti": "bin/jiti.js" - } - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -7366,18 +3995,6 @@ "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", "dev": true }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -7460,15 +4077,6 @@ "node": ">=0.10.0" } }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/lerna": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/lerna/-/lerna-8.0.2.tgz", @@ -7557,15 +4165,6 @@ "node": ">=18.0.0" } }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/libnpmaccess": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/libnpmaccess/-/libnpmaccess-7.0.2.tgz", @@ -7716,14 +4315,6 @@ } ] }, - "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "engines": { - "node": ">=10" - } - }, "node_modules/lines-and-columns": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.4.tgz", @@ -7761,6 +4352,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, "dependencies": { "p-locate": "^4.1.0" }, @@ -7774,49 +4366,12 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "node_modules/lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==", - "dev": true - }, "node_modules/lodash.ismatch": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", "dev": true }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true - }, - "node_modules/lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "dev": true, - "dependencies": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "node_modules/lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "dev": true, - "dependencies": { - "lodash._reinterpolate": "^3.0.0" - } - }, - "node_modules/lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", - "dev": true - }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -7845,18 +4400,6 @@ "node": ">=10" } }, - "node_modules/magic-string": { - "version": "0.30.5", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", - "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", @@ -7906,15 +4449,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "dependencies": { - "tmpl": "1.0.5" - } - }, "node_modules/map-obj": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", @@ -7927,12 +4461,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "dev": true - }, "node_modules/meow": { "version": "8.1.2", "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", @@ -8066,6 +4594,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, "engines": { "node": ">= 8" } @@ -8074,6 +4603,7 @@ "version": "4.0.7", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -8121,14 +4651,6 @@ "node": ">=4" } }, - "node_modules/mini-svg-data-uri": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", - "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", - "bin": { - "mini-svg-data-uri": "cli.js" - } - }, "node_modules/minimatch": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", @@ -8168,6 +4690,7 @@ "version": "7.0.4", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, "engines": { "node": ">=16 || 14 >=14.17" } @@ -8320,12 +4843,6 @@ "node": ">=8" } }, - "node_modules/mitt": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", - "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", - "dev": true - }, "node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -8338,12 +4855,6 @@ "node": ">=10" } }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, "node_modules/modify-values": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", @@ -8392,39 +4903,6 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "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==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -8440,15 +4918,6 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, - "node_modules/netmask": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", - "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/next-tick": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", @@ -8526,24 +4995,12 @@ "node-gyp-build-test": "build-test.js" } }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true - }, "node_modules/node-machine-id": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/node-machine-id/-/node-machine-id-1.1.12.tgz", "integrity": "sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==", "dev": true }, - "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true - }, "node_modules/nopt": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.0.tgz", @@ -8574,54 +5031,19 @@ "node": ">=10" } }, - "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==", - "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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/nostr-login": { - "resolved": "packages/auth", - "link": true - }, - "node_modules/nostr-login-components": { - "resolved": "packages/components", - "link": true - }, "node_modules/nostr-tools": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/nostr-tools/-/nostr-tools-1.17.0.tgz", - "integrity": "sha512-LZmR8GEWKZeElbFV5Xte75dOeE9EFUW/QLI1Ncn3JKn0kFddDKEfBbFN8Mu4TMs+L4HR/WTPha2l+PPuRnJcMw==", + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/nostr-tools/-/nostr-tools-2.16.2.tgz", + "integrity": "sha512-ZxH9EbSt5ypURZj2TGNJxZd0Omb5ag5KZSu8IyJMCdLyg2KKz+2GA0sP/cSawCQEkyviIN4eRT4G2gB/t9lMRw==", + "license": "Unlicense", "dependencies": { - "@noble/ciphers": "0.2.0", - "@noble/curves": "1.1.0", + "@noble/ciphers": "^0.5.1", + "@noble/curves": "1.2.0", "@noble/hashes": "1.3.1", "@scure/base": "1.1.1", "@scure/bip32": "1.3.1", - "@scure/bip39": "1.2.1" + "@scure/bip39": "1.2.1", + "nostr-wasm": "0.1.0" }, "peerDependencies": { "typescript": ">=5.0.0" @@ -8632,6 +5054,30 @@ } } }, + "node_modules/nostr-tools/node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/nostr-tools/node_modules/@noble/curves/node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/nostr-tools/node_modules/@noble/hashes": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", @@ -8654,6 +5100,12 @@ } ] }, + "node_modules/nostr-wasm": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/nostr-wasm/-/nostr-wasm-0.1.0.tgz", + "integrity": "sha512-78BTryCLcLYv96ONU8Ws3Q1JzjlAt+43pWQhIl86xZmWeegYCNLPml7yQ+gG3vR6V5h4XGj+TxO+SS5dsThQIA==", + "license": "MIT" + }, "node_modules/npm-bundled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz", @@ -9086,18 +5538,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, "node_modules/nx": { "version": "17.2.8", "resolved": "https://registry.npmjs.org/nx/-/nx-17.2.8.tgz", @@ -9201,22 +5641,6 @@ "node": ">=10" } }, - "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==", - "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==", - "engines": { - "node": ">= 6" - } - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -9303,6 +5727,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, "dependencies": { "p-try": "^2.0.0" }, @@ -9317,6 +5742,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, "dependencies": { "p-limit": "^2.2.0" }, @@ -9401,6 +5827,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, "engines": { "node": ">=6" } @@ -9420,38 +5847,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pac-proxy-agent": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.1.tgz", - "integrity": "sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==", - "dev": true, - "dependencies": { - "@tootallnate/quickjs-emscripten": "^0.23.0", - "agent-base": "^7.0.2", - "debug": "^4.3.4", - "get-uri": "^6.0.1", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.2", - "pac-resolver": "^7.0.0", - "socks-proxy-agent": "^8.0.2" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/pac-resolver": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", - "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", - "dev": true, - "dependencies": { - "degenerator": "^5.0.0", - "netmask": "^2.0.2" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/pacote": { "version": "17.0.6", "resolved": "https://registry.npmjs.org/pacote/-/pacote-17.0.6.tgz", @@ -9797,6 +6192,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, "engines": { "node": ">=8" } @@ -9814,6 +6210,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, "engines": { "node": ">=8" } @@ -9821,12 +6218,14 @@ "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==" + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true }, "node_modules/path-scurry": { "version": "1.10.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, "dependencies": { "lru-cache": "^9.1.1 || ^10.0.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" @@ -9842,6 +6241,7 @@ "version": "10.2.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "dev": true, "engines": { "node": "14 || >=16.14" } @@ -9855,21 +6255,11 @@ "node": ">=8" } }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" - }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, "engines": { "node": ">=8.6" }, @@ -9889,14 +6279,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", - "engines": { - "node": ">= 6" - } - }, "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -9909,607 +6291,6 @@ "node": ">=8" } }, - "node_modules/pngjs": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", - "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/postcss": { - "version": "8.4.33", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz", - "integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==", - "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" - } - ], - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-calc": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", - "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", - "dev": true, - "dependencies": { - "postcss-selector-parser": "^6.0.9", - "postcss-value-parser": "^4.2.0" - }, - "peerDependencies": { - "postcss": "^8.2.2" - } - }, - "node_modules/postcss-colormin": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", - "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", - "dev": true, - "dependencies": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0", - "colord": "^2.9.1", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-combine-duplicated-selectors": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/postcss-combine-duplicated-selectors/-/postcss-combine-duplicated-selectors-10.0.3.tgz", - "integrity": "sha512-IP0BmwFloCskv7DV7xqvzDXqMHpwdczJa6ZvIW8abgHdcIHs9mCJX2ltFhu3EwA51ozp13DByng30+Ke+eIExA==", - "dev": true, - "dependencies": { - "postcss-selector-parser": "^6.0.4" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >=14.0.0" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-convert-values": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", - "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", - "dev": true, - "dependencies": { - "browserslist": "^4.21.4", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-comments": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", - "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-duplicates": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", - "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-empty": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", - "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-overridden": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", - "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "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==", - "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==", - "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==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "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.0.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", - "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==", - "engines": { - "node": ">=14" - } - }, - "node_modules/postcss-load-config/node_modules/yaml": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", - "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", - "engines": { - "node": ">= 14" - } - }, - "node_modules/postcss-merge-longhand": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", - "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0", - "stylehacks": "^5.1.1" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-merge-rules": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", - "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", - "dev": true, - "dependencies": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^3.1.0", - "postcss-selector-parser": "^6.0.5" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-font-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", - "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-gradients": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", - "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", - "dev": true, - "dependencies": { - "colord": "^2.9.1", - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-params": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", - "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", - "dev": true, - "dependencies": { - "browserslist": "^4.21.4", - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-selectors": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", - "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", - "dev": true, - "dependencies": { - "postcss-selector-parser": "^6.0.5" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-nested": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", - "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.11" - }, - "engines": { - "node": ">=12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.2.14" - } - }, - "node_modules/postcss-normalize-charset": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", - "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-display-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", - "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-positions": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", - "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-repeat-style": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", - "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-string": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", - "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-timing-functions": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", - "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-unicode": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", - "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", - "dev": true, - "dependencies": { - "browserslist": "^4.21.4", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", - "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", - "dev": true, - "dependencies": { - "normalize-url": "^6.0.1", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-whitespace": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", - "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-ordered-values": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", - "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", - "dev": true, - "dependencies": { - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-reduce-initial": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", - "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", - "dev": true, - "dependencies": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-reduce-transforms": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", - "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.0.15", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz", - "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-svgo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", - "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0", - "svgo": "^2.7.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-unique-selectors": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", - "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", - "dev": true, - "dependencies": { - "postcss-selector-parser": "^6.0.5" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "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==" - }, - "node_modules/prettier": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.4.tgz", - "integrity": "sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==", - "dev": true, - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/pretty-format": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", @@ -10551,15 +6332,6 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", @@ -10579,19 +6351,6 @@ "node": ">=10" } }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/promzard": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/promzard/-/promzard-1.0.0.tgz", @@ -10610,185 +6369,17 @@ "integrity": "sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==", "dev": true }, - "node_modules/proxy-agent": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.0.tgz", - "integrity": "sha512-0LdR757eTj/JfuU7TL2YCuAZnxWXu3tkJbg4Oq3geW/qFNT/32T0sp2HnZ9O0lMR4q3vwAt0+xCA8SR0WAD0og==", - "dev": true, - "dependencies": { - "agent-base": "^7.0.2", - "debug": "^4.3.4", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.0", - "lru-cache": "^7.14.1", - "pac-proxy-agent": "^7.0.0", - "proxy-from-env": "^1.1.0", - "socks-proxy-agent": "^8.0.1" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/proxy-agent/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, "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 }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/puppeteer": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-21.1.1.tgz", - "integrity": "sha512-2TLntjGA4qLrI9/8N0UK/5OoZJ2Ue7QgphN2SD+RsaHiha12AEiVyMGsB+i6LY1IoPAtEgYIjblQ7lw3kWDNRw==", - "deprecated": "< 21.5.0 is no longer supported", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@puppeteer/browsers": "1.7.0", - "cosmiconfig": "8.2.0", - "puppeteer-core": "21.1.1" - }, - "engines": { - "node": ">=16.3.0" - } - }, - "node_modules/puppeteer-core": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-21.1.1.tgz", - "integrity": "sha512-Tlcajcf44zwfa9Sbwv3T8BtaNMJ69wtpHIxwl2NOBTyTK3D1wppQovXTjfw0TDOm3a16eCfQ+5BMi3vRQ4kuAQ==", - "dev": true, - "dependencies": { - "@puppeteer/browsers": "1.7.0", - "chromium-bidi": "0.4.22", - "cross-fetch": "4.0.0", - "debug": "4.3.4", - "devtools-protocol": "0.0.1159816", - "ws": "8.13.0" - }, - "engines": { - "node": ">=16.3.0" - } - }, - "node_modules/puppeteer/node_modules/cosmiconfig": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz", - "integrity": "sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==", - "dev": true, - "dependencies": { - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - } - }, - "node_modules/pure-rand": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", - "integrity": "sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ] - }, - "node_modules/qrcode": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.4.tgz", - "integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==", - "dependencies": { - "dijkstrajs": "^1.0.1", - "pngjs": "^5.0.0", - "yargs": "^15.3.1" - }, - "bin": { - "qrcode": "bin/qrcode" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/qrcode/node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/qrcode/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" - }, - "node_modules/qrcode/node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/qrcode/node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, "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", @@ -10804,12 +6395,6 @@ } ] }, - "node_modules/queue-tick": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", - "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", - "dev": true - }, "node_modules/quick-lru": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", @@ -10819,15 +6404,6 @@ "node": ">=8" } }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, "node_modules/react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", @@ -10846,22 +6422,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "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==", - "dependencies": { - "pify": "^2.3.0" - } - }, - "node_modules/read-cache/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/read-cmd-shim": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-4.0.0.tgz", @@ -11173,17 +6733,6 @@ "node": ">= 6" } }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -11197,29 +6746,20 @@ "node": ">=8" } }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, "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, "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -11253,15 +6793,6 @@ "node": ">=8" } }, - "node_modules/resolve.exports": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", - "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", @@ -11288,6 +6819,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -11362,66 +6894,6 @@ "node": ">=8" } }, - "node_modules/rollup": { - "version": "2.79.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", - "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", - "dev": true, - "peer": true, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=10.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/rollup-plugin-typescript2": { - "version": "0.36.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.36.0.tgz", - "integrity": "sha512-NB2CSQDxSe9+Oe2ahZbf+B4bh7pHwjV5L+RSYpCu7Q5ROuN94F9b6ioWwKfz3ueL3KTtmX4o2MUH2cgHDIEUsw==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^4.1.2", - "find-cache-dir": "^3.3.2", - "fs-extra": "^10.0.0", - "semver": "^7.5.4", - "tslib": "^2.6.2" - }, - "peerDependencies": { - "rollup": ">=1.26.3", - "typescript": ">=2.4.0" - } - }, - "node_modules/rollup-plugin-typescript2/node_modules/@rollup/pluginutils": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", - "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", - "dev": true, - "dependencies": { - "estree-walker": "^2.0.1", - "picomatch": "^2.2.2" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/rollup-plugin-typescript2/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", @@ -11435,6 +6907,7 @@ "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", @@ -11506,7 +6979,8 @@ "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true }, "node_modules/shallow-clone": { "version": "3.0.1", @@ -11524,6 +6998,7 @@ "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, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -11535,6 +7010,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, "engines": { "node": ">=8" } @@ -11720,12 +7196,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -11745,12 +7215,6 @@ "npm": ">= 3.0.0" } }, - "node_modules/smob": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/smob/-/smob-1.4.1.tgz", - "integrity": "sha512-9LK+E7Hv5R9u4g4C3p+jjLstaLe11MDsL21UpYaCNmapvMkYhqCV4A/f/3gyH8QjMyh6l68q9xC85vihY9ahMQ==", - "dev": true - }, "node_modules/socks": { "version": "2.8.3", "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", @@ -11800,24 +7264,6 @@ "node": ">=0.10.0" } }, - "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", @@ -11901,95 +7347,6 @@ "node": ">=8" } }, - "node_modules/stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility", - "dev": true - }, - "node_modules/stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/stencil-tailwind-plugin": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/stencil-tailwind-plugin/-/stencil-tailwind-plugin-1.8.0.tgz", - "integrity": "sha512-39vFtvTy+Pi5leroD6pY9H1DMKKCpYDPInTSwKJrOkgfT0v9K+KWOG9NSuO4G0eJfF27R7G6NIjP3Bsi10iLsg==", - "dev": true, - "dependencies": { - "autoprefixer": "^10.4.7", - "chalk": "^4.1.2", - "cssnano": "^5.1.12", - "fs-extra": "^10.0.0", - "p-queue": "^6.6.2", - "postcss": "^8.4.14", - "postcss-combine-duplicated-selectors": "^10.0.3", - "postcss-discard-comments": "^5.1.2", - "postcss-load-config": "^4.0.1" - }, - "peerDependencies": { - "tailwindcss": ">=3.0.7", - "typescript": ">=4.4.2" - } - }, - "node_modules/stencil-tailwind-plugin/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/stencil-tailwind-plugin/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/streamx": { - "version": "2.15.6", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.6.tgz", - "integrity": "sha512-q+vQL4AAz+FdfT137VF69Cc/APqUbxy+MDOImRrMvchJpigHj9GksgDU2LYbO9rx7RX6osWgxJB2WxhYv4SZAw==", - "dev": true, - "dependencies": { - "fast-fifo": "^1.1.0", - "queue-tick": "^1.0.1" - } - }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -11999,23 +7356,11 @@ "safe-buffer": "~5.2.0" } }, - "node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, "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, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -12030,6 +7375,7 @@ "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, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -12039,33 +7385,11 @@ "node": ">=8" } }, - "node_modules/stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "dev": true, - "dependencies": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/stringify-object/node_modules/is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "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, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -12078,6 +7402,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -12094,19 +7419,6 @@ "node": ">=8" } }, - "node_modules/strip-comments": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-1.0.2.tgz", - "integrity": "sha512-kL97alc47hoyIQSV165tTt9rG5dn4w1dNnBhOQ3bOU1Nc1hel09jnXANaHJ7vzHLd4Ju8kseDGzlev96pghLFw==", - "dev": true, - "dependencies": { - "babel-extract-comments": "^1.0.0", - "babel-plugin-transform-object-rest-spread": "^6.26.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -12128,18 +7440,6 @@ "node": ">=8" } }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/strong-log-transformer": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz", @@ -12157,56 +7457,6 @@ "node": ">=4" } }, - "node_modules/stylehacks": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", - "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", - "dev": true, - "dependencies": { - "browserslist": "^4.21.4", - "postcss-selector-parser": "^6.0.4" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "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==", - "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/sucrase/node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/sucrase/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==" - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -12223,6 +7473,7 @@ "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, "engines": { "node": ">= 0.4" }, @@ -12230,79 +7481,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/svgo": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", - "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", - "dev": true, - "dependencies": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^4.1.3", - "css-tree": "^1.1.3", - "csso": "^4.2.0", - "picocolors": "^1.0.0", - "stable": "^0.1.8" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/tailwindcss": { - "version": "3.4.10", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.10.tgz", - "integrity": "sha512-KWZkVPm7yJRhdu4SRSl9d4AK2wM3a50UsvgHZO7xY77NQr2V+fIrEuoDGQcbvswWvFGbS2f6e+jC/6WJm1Dl0w==", - "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/tailwindcss-rtl": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/tailwindcss-rtl/-/tailwindcss-rtl-0.9.0.tgz", - "integrity": "sha512-y7yC8QXjluDBEFMSX33tV6xMYrf0B3sa+tOB5JSQb6/G6laBU313a+Z+qxu55M1Qyn8tDMttjomsA8IsJD+k+w==" - }, - "node_modules/tailwindcss/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==", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/tar": { "version": "6.1.11", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", @@ -12320,28 +7498,6 @@ "node": ">= 10" } }, - "node_modules/tar-fs": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", - "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", - "dev": true, - "dependencies": { - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - } - }, - "node_modules/tar-fs/node_modules/tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", - "dev": true, - "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, "node_modules/tar-stream": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", @@ -12391,86 +7547,6 @@ "node": ">=4" } }, - "node_modules/terser": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.30.0.tgz", - "integrity": "sha512-Y/SblUl5kEyEFzhMAQdsxVHh+utAxd4IuRNJzKywY/4uzSogh3G219jqbDDxYu4MXO9CzY3tSEqmZvW6AoEDJw==", - "dev": true, - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/terser/node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/test-exclude/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/test-exclude/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/text-extensions": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", @@ -12480,25 +7556,6 @@ "node": ">=0.10" } }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "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==", - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -12604,25 +7661,11 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "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, "dependencies": { "is-number": "^7.0.0" }, @@ -12645,11 +7688,6 @@ "node": ">=8" } }, - "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==" - }, "node_modules/tsconfig-paths": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", @@ -12864,15 +7902,6 @@ "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/type-fest": { "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", @@ -12930,16 +7959,6 @@ "node": ">=0.8.0" } }, - "node_modules/unbzip2-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", - "dev": true, - "dependencies": { - "buffer": "^5.2.1", - "through": "^2.3.8" - } - }, "node_modules/unique-filename": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", @@ -12989,36 +8008,6 @@ "yarn": "*" } }, - "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", - "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" - } - ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, "node_modules/utf-8-validate": { "version": "5.0.10", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", @@ -13042,7 +8031,8 @@ "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==" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true }, "node_modules/uuid": { "version": "9.0.1", @@ -13057,20 +8047,6 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/v8-to-istanbul": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", - "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^2.0.0" - }, - "engines": { - "node": ">=10.12.0" - } - }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -13093,15 +8069,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "dependencies": { - "makeerror": "1.0.12" - } - }, "node_modules/wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", @@ -13188,11 +8155,6 @@ "node": "^16.13.0 || >=18.0.0" } }, - "node_modules/which-module": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==" - }, "node_modules/wide-align": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", @@ -13208,228 +8170,11 @@ "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", "dev": true }, - "node_modules/workbox-background-sync": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-4.3.1.tgz", - "integrity": "sha512-1uFkvU8JXi7L7fCHVBEEnc3asPpiAL33kO495UMcD5+arew9IbKW2rV5lpzhoWcm/qhGB89YfO4PmB/0hQwPRg==", - "dev": true, - "dependencies": { - "workbox-core": "^4.3.1" - } - }, - "node_modules/workbox-broadcast-update": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-4.3.1.tgz", - "integrity": "sha512-MTSfgzIljpKLTBPROo4IpKjESD86pPFlZwlvVG32Kb70hW+aob4Jxpblud8EhNb1/L5m43DUM4q7C+W6eQMMbA==", - "dev": true, - "dependencies": { - "workbox-core": "^4.3.1" - } - }, - "node_modules/workbox-build": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-4.3.1.tgz", - "integrity": "sha512-UHdwrN3FrDvicM3AqJS/J07X0KXj67R8Cg0waq1MKEOqzo89ap6zh6LmaLnRAjpB+bDIz+7OlPye9iii9KBnxw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.3.4", - "@hapi/joi": "^15.0.0", - "common-tags": "^1.8.0", - "fs-extra": "^4.0.2", - "glob": "^7.1.3", - "lodash.template": "^4.4.0", - "pretty-bytes": "^5.1.0", - "stringify-object": "^3.3.0", - "strip-comments": "^1.0.2", - "workbox-background-sync": "^4.3.1", - "workbox-broadcast-update": "^4.3.1", - "workbox-cacheable-response": "^4.3.1", - "workbox-core": "^4.3.1", - "workbox-expiration": "^4.3.1", - "workbox-google-analytics": "^4.3.1", - "workbox-navigation-preload": "^4.3.1", - "workbox-precaching": "^4.3.1", - "workbox-range-requests": "^4.3.1", - "workbox-routing": "^4.3.1", - "workbox-strategies": "^4.3.1", - "workbox-streams": "^4.3.1", - "workbox-sw": "^4.3.1", - "workbox-window": "^4.3.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/workbox-build/node_modules/fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "node_modules/workbox-build/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/workbox-build/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/workbox-build/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/workbox-build/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/workbox-cacheable-response": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-4.3.1.tgz", - "integrity": "sha512-Rp5qlzm6z8IOvnQNkCdO9qrDgDpoPNguovs0H8C+wswLuPgSzSp9p2afb5maUt9R1uTIwOXrVQMmPfPypv+npw==", - "dev": true, - "dependencies": { - "workbox-core": "^4.3.1" - } - }, - "node_modules/workbox-core": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-4.3.1.tgz", - "integrity": "sha512-I3C9jlLmMKPxAC1t0ExCq+QoAMd0vAAHULEgRZ7kieCdUd919n53WC0AfvokHNwqRhGn+tIIj7vcb5duCjs2Kg==", - "dev": true - }, - "node_modules/workbox-expiration": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-4.3.1.tgz", - "integrity": "sha512-vsJLhgQsQouv9m0rpbXubT5jw0jMQdjpkum0uT+d9tTwhXcEZks7qLfQ9dGSaufTD2eimxbUOJfWLbNQpIDMPw==", - "dev": true, - "dependencies": { - "workbox-core": "^4.3.1" - } - }, - "node_modules/workbox-google-analytics": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-4.3.1.tgz", - "integrity": "sha512-xzCjAoKuOb55CBSwQrbyWBKqp35yg1vw9ohIlU2wTy06ZrYfJ8rKochb1MSGlnoBfXGWss3UPzxR5QL5guIFdg==", - "dev": true, - "dependencies": { - "workbox-background-sync": "^4.3.1", - "workbox-core": "^4.3.1", - "workbox-routing": "^4.3.1", - "workbox-strategies": "^4.3.1" - } - }, - "node_modules/workbox-navigation-preload": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-4.3.1.tgz", - "integrity": "sha512-K076n3oFHYp16/C+F8CwrRqD25GitA6Rkd6+qAmLmMv1QHPI2jfDwYqrytOfKfYq42bYtW8Pr21ejZX7GvALOw==", - "dev": true, - "dependencies": { - "workbox-core": "^4.3.1" - } - }, - "node_modules/workbox-precaching": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-4.3.1.tgz", - "integrity": "sha512-piSg/2csPoIi/vPpp48t1q5JLYjMkmg5gsXBQkh/QYapCdVwwmKlU9mHdmy52KsDGIjVaqEUMFvEzn2LRaigqQ==", - "dev": true, - "dependencies": { - "workbox-core": "^4.3.1" - } - }, - "node_modules/workbox-range-requests": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-4.3.1.tgz", - "integrity": "sha512-S+HhL9+iTFypJZ/yQSl/x2Bf5pWnbXdd3j57xnb0V60FW1LVn9LRZkPtneODklzYuFZv7qK6riZ5BNyc0R0jZA==", - "dev": true, - "dependencies": { - "workbox-core": "^4.3.1" - } - }, - "node_modules/workbox-routing": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-4.3.1.tgz", - "integrity": "sha512-FkbtrODA4Imsi0p7TW9u9MXuQ5P4pVs1sWHK4dJMMChVROsbEltuE79fBoIk/BCztvOJ7yUpErMKa4z3uQLX+g==", - "dev": true, - "dependencies": { - "workbox-core": "^4.3.1" - } - }, - "node_modules/workbox-strategies": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-4.3.1.tgz", - "integrity": "sha512-F/+E57BmVG8dX6dCCopBlkDvvhg/zj6VDs0PigYwSN23L8hseSRwljrceU2WzTvk/+BSYICsWmRq5qHS2UYzhw==", - "dev": true, - "dependencies": { - "workbox-core": "^4.3.1" - } - }, - "node_modules/workbox-streams": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-4.3.1.tgz", - "integrity": "sha512-4Kisis1f/y0ihf4l3u/+ndMkJkIT4/6UOacU3A4BwZSAC9pQ9vSvJpIi/WFGQRH/uPXvuVjF5c2RfIPQFSS2uA==", - "dev": true, - "dependencies": { - "workbox-core": "^4.3.1" - } - }, - "node_modules/workbox-sw": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-4.3.1.tgz", - "integrity": "sha512-0jXdusCL2uC5gM3yYFT6QMBzKfBr2XTk0g5TPAV4y8IZDyVNDyj1a8uSXy3/XrvkVTmQvLN4O5k3JawGReXr9w==", - "dev": true - }, - "node_modules/workbox-window": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-4.3.1.tgz", - "integrity": "sha512-C5gWKh6I58w3GeSc0wp2Ne+rqVw8qwcmZnQGpjiek8A2wpbxSJb1FdCoQVO+jDJs35bFgo/WETgl1fqgsxN0Hg==", - "dev": true, - "dependencies": { - "workbox-core": "^4.3.1" - } - }, "node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -13444,6 +8189,7 @@ "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, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -13569,27 +8315,6 @@ "node": ">=6" } }, - "node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -13622,15 +8347,6 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", @@ -13658,31 +8374,10 @@ "node": ">=12" } }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "packages/auth": { "name": "nostr-login", "version": "1.7.11", + "extraneous": true, "license": "MIT", "dependencies": { "@nostr-dev-kit/ndk": "^2.3.1", @@ -13699,42 +8394,10 @@ "rollup-plugin-typescript2": "^0.36.0" } }, - "packages/auth/node_modules/rollup": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.1.tgz", - "integrity": "sha512-hFi+fU132IvJ2ZuihN56dwgpltpmLZHZWsx27rMCTZ2sYwrqlgL5sECGy1eeV2lAihD8EzChBVVhsXci0wD4Tg==", - "dev": true, - "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.13.1", - "@rollup/rollup-android-arm64": "4.13.1", - "@rollup/rollup-darwin-arm64": "4.13.1", - "@rollup/rollup-darwin-x64": "4.13.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.13.1", - "@rollup/rollup-linux-arm64-gnu": "4.13.1", - "@rollup/rollup-linux-arm64-musl": "4.13.1", - "@rollup/rollup-linux-riscv64-gnu": "4.13.1", - "@rollup/rollup-linux-s390x-gnu": "4.13.1", - "@rollup/rollup-linux-x64-gnu": "4.13.1", - "@rollup/rollup-linux-x64-musl": "4.13.1", - "@rollup/rollup-win32-arm64-msvc": "4.13.1", - "@rollup/rollup-win32-ia32-msvc": "4.13.1", - "@rollup/rollup-win32-x64-msvc": "4.13.1", - "fsevents": "~2.3.2" - } - }, "packages/components": { "name": "nostr-login-components", "version": "1.0.3", + "extraneous": true, "license": "MIT", "dependencies": { "@stencil/core": "^4.20.0", @@ -13760,21 +8423,6 @@ } }, "dependencies": { - "@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==" - }, - "@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, "@babel/code-frame": { "version": "7.23.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", @@ -13837,191 +8485,12 @@ } } }, - "@babel/compat-data": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", - "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", - "dev": true - }, - "@babel/core": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz", - "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==", - "dev": true, - "requires": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.9", - "@babel/parser": "^7.23.9", - "@babel/template": "^7.23.9", - "@babel/traverse": "^7.23.9", - "@babel/types": "^7.23.9", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", - "dev": true, - "requires": { - "@babel/types": "^7.23.6", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", - "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-validator-option": "^7.23.5", - "browserslist": "^4.22.2", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "dependencies": { - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - } - } - }, - "@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true - }, - "@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dev": true, - "requires": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dev": true, - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", - "dev": true, - "requires": { - "@babel/types": "^7.22.15" - } - }, - "@babel/helper-module-transforms": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.20" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", - "dev": true - }, - "@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", - "dev": true, - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "dev": true, - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", - "dev": true - }, "@babel/helper-validator-identifier": { "version": "7.22.20", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true }, - "@babel/helper-validator-option": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", - "dev": true - }, - "@babel/helpers": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.9.tgz", - "integrity": "sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==", - "dev": true, - "requires": { - "@babel/template": "^7.23.9", - "@babel/traverse": "^7.23.9", - "@babel/types": "^7.23.9" - } - }, "@babel/highlight": { "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", @@ -14085,232 +8554,6 @@ } } }, - "@babel/parser": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", - "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", - "dev": true - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", - "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-typescript": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", - "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/runtime": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz", - "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.14.0" - } - }, - "@babel/template": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz", - "integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.23.9", - "@babel/types": "^7.23.9" - } - }, - "@babel/traverse": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz", - "integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.9", - "@babel/types": "^7.23.9", - "debug": "^4.3.1", - "globals": "^11.1.0" - } - }, - "@babel/types": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz", - "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" - } - }, - "@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "@hapi/address": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", - "integrity": "sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==", - "dev": true - }, - "@hapi/bourne": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz", - "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==", - "dev": true - }, - "@hapi/hoek": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz", - "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==", - "dev": true - }, - "@hapi/joi": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz", - "integrity": "sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==", - "dev": true, - "requires": { - "@hapi/address": "2.x.x", - "@hapi/bourne": "1.x.x", - "@hapi/hoek": "8.x.x", - "@hapi/topo": "3.x.x" - } - }, - "@hapi/topo": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz", - "integrity": "sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==", - "dev": true, - "requires": { - "@hapi/hoek": "^8.3.0" - } - }, "@hutson/parse-repository-url": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", @@ -14321,6 +8564,7 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, "requires": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -14333,22 +8577,26 @@ "ansi-regex": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true }, "ansi-styles": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==" + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true }, "emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true }, "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, "requires": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -14359,6 +8607,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, "requires": { "ansi-regex": "^6.0.1" } @@ -14367,6 +8616,7 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, "requires": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -14375,210 +8625,6 @@ } } }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - } - } - }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true - }, - "@jest/console": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", - "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", - "dev": true, - "requires": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0" - } - }, - "@jest/core": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", - "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", - "dev": true, - "requires": { - "@jest/console": "^29.7.0", - "@jest/reporters": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.7.0", - "jest-config": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-resolve-dependencies": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "jest-watcher": "^29.7.0", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "@jest/environment": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", - "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", - "dev": true, - "requires": { - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0" - } - }, - "@jest/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", - "dev": true, - "requires": { - "expect": "^29.7.0", - "jest-snapshot": "^29.7.0" - } - }, - "@jest/expect-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", - "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", - "dev": true, - "requires": { - "jest-get-type": "^29.6.3" - } - }, - "@jest/fake-timers": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", - "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", - "dev": true, - "requires": { - "@jest/types": "^29.6.3", - "@sinonjs/fake-timers": "^10.0.2", - "@types/node": "*", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - } - }, - "@jest/globals": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", - "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", - "dev": true, - "requires": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/types": "^29.6.3", - "jest-mock": "^29.7.0" - } - }, - "@jest/reporters": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", - "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^6.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "v8-to-istanbul": "^9.0.1" - }, - "dependencies": { - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, "@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -14588,134 +8634,6 @@ "@sinclair/typebox": "^0.27.8" } }, - "@jest/source-map": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", - "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.18", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - } - }, - "@jest/test-result": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", - "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", - "dev": true, - "requires": { - "@jest/console": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", - "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", - "dev": true, - "requires": { - "@jest/test-result": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "slash": "^3.0.0" - } - }, - "@jest/transform": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", - "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" - }, - "dependencies": { - "write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - } - } - } - }, - "@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", - "dev": true, - "requires": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@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==", - "requires": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==" - }, - "@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==" - }, - "@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" - }, - "@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==", - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, "@lerna/create": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@lerna/create/-/create-8.0.2.tgz", @@ -14789,9 +8707,9 @@ } }, "@noble/ciphers": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.2.0.tgz", - "integrity": "sha512-6YBxJDAapHSdd3bLDv6x2wRPwq4QFMUaB3HvljNBUTThDd12eSm7/3F+2lnfzx2jvM+S6Nsy0jEt9QbPqSwqRw==" + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.5.3.tgz", + "integrity": "sha512-B0+6IIHiqEs3BPMT0hcRmHvEj2QHOLu+uwt+tqDDeVd0oyVzh7BPrDcPjRnV1PV/5LaknXJJQvOuRGR0zQJz+w==" }, "@noble/curves": { "version": "1.1.0", @@ -14822,6 +8740,7 @@ "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, "requires": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -14830,12 +8749,14 @@ "@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==" + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true }, "@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, "requires": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -14859,6 +8780,21 @@ "websocket-polyfill": "^0.0.3" }, "dependencies": { + "@noble/ciphers": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.2.0.tgz", + "integrity": "sha512-6YBxJDAapHSdd3bLDv6x2wRPwq4QFMUaB3HvljNBUTThDd12eSm7/3F+2lnfzx2jvM+S6Nsy0jEt9QbPqSwqRw==" + }, + "@noble/hashes": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", + "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==" + }, + "@scure/base": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", + "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==" + }, "data-uri-to-buffer": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", @@ -14873,6 +8809,19 @@ "fetch-blob": "^3.1.4", "formdata-polyfill": "^4.0.10" } + }, + "nostr-tools": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/nostr-tools/-/nostr-tools-1.17.0.tgz", + "integrity": "sha512-LZmR8GEWKZeElbFV5Xte75dOeE9EFUW/QLI1Ncn3JKn0kFddDKEfBbFN8Mu4TMs+L4HR/WTPha2l+PPuRnJcMw==", + "requires": { + "@noble/ciphers": "0.2.0", + "@noble/curves": "1.1.0", + "@noble/hashes": "1.3.1", + "@scure/base": "1.1.1", + "@scure/bip32": "1.3.1", + "@scure/bip39": "1.2.1" + } } } }, @@ -15248,229 +9197,6 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "optional": true - }, - "@puppeteer/browsers": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.7.0.tgz", - "integrity": "sha512-sl7zI0IkbQGak/+IE3VEEZab5SSOlI5F6558WvzWGC1n3+C722rfewC1ZIkcF9dsoGSsxhsONoseVlNQG4wWvQ==", - "dev": true, - "requires": { - "debug": "4.3.4", - "extract-zip": "2.0.1", - "progress": "2.0.3", - "proxy-agent": "6.3.0", - "tar-fs": "3.0.4", - "unbzip2-stream": "1.4.3", - "yargs": "17.7.1" - }, - "dependencies": { - "yargs": { - "version": "17.7.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", - "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", - "dev": true, - "requires": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - } - } - } - }, - "@rollup/plugin-commonjs": { - "version": "25.0.7", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.7.tgz", - "integrity": "sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^5.0.1", - "commondir": "^1.0.1", - "estree-walker": "^2.0.2", - "glob": "^8.0.3", - "is-reference": "1.2.1", - "magic-string": "^0.30.3" - }, - "dependencies": { - "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, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - } - }, - "minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "@rollup/plugin-node-resolve": { - "version": "15.2.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", - "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^5.0.1", - "@types/resolve": "1.20.2", - "deepmerge": "^4.2.2", - "is-builtin-module": "^3.2.1", - "is-module": "^1.0.0", - "resolve": "^1.22.1" - } - }, - "@rollup/plugin-terser": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", - "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", - "dev": true, - "requires": { - "serialize-javascript": "^6.0.1", - "smob": "^1.0.0", - "terser": "^5.17.4" - }, - "dependencies": { - "serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - } - } - }, - "@rollup/pluginutils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", - "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", - "dev": true, - "requires": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - } - }, - "@rollup/rollup-android-arm-eabi": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.1.tgz", - "integrity": "sha512-4C4UERETjXpC4WpBXDbkgNVgHyWfG3B/NKY46e7w5H134UDOFqUJKpsLm0UYmuupW+aJmRgeScrDNfvZ5WV80A==", - "dev": true, - "optional": true - }, - "@rollup/rollup-android-arm64": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.1.tgz", - "integrity": "sha512-TrTaFJ9pXgfXEiJKQ3yQRelpQFqgRzVR9it8DbeRzG0RX7mKUy0bqhCFsgevwXLJepQKTnLl95TnPGf9T9AMOA==", - "dev": true, - "optional": true - }, - "@rollup/rollup-darwin-arm64": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.1.tgz", - "integrity": "sha512-fz7jN6ahTI3cKzDO2otQuybts5cyu0feymg0bjvYCBrZQ8tSgE8pc0sSNEuGvifrQJWiwx9F05BowihmLxeQKw==", - "dev": true, - "optional": true - }, - "@rollup/rollup-darwin-x64": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.1.tgz", - "integrity": "sha512-WTvdz7SLMlJpektdrnWRUN9C0N2qNHwNbWpNo0a3Tod3gb9leX+yrYdCeB7VV36OtoyiPAivl7/xZ3G1z5h20g==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.1.tgz", - "integrity": "sha512-dBHQl+7wZzBYcIF6o4k2XkAfwP2ks1mYW2q/Gzv9n39uDcDiAGDqEyml08OdY0BIct0yLSPkDTqn4i6czpBLLw==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-arm64-gnu": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.1.tgz", - "integrity": "sha512-bur4JOxvYxfrAmocRJIW0SADs3QdEYK6TQ7dTNz6Z4/lySeu3Z1H/+tl0a4qDYv0bCdBpUYM0sYa/X+9ZqgfSQ==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-arm64-musl": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.1.tgz", - "integrity": "sha512-ssp77SjcDIUSoUyj7DU7/5iwM4ZEluY+N8umtCT9nBRs3u045t0KkW02LTyHouHDomnMXaXSZcCSr2bdMK63kA==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-riscv64-gnu": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.1.tgz", - "integrity": "sha512-Jv1DkIvwEPAb+v25/Unrnnq9BO3F5cbFPT821n3S5litkz+O5NuXuNhqtPx5KtcwOTtaqkTsO+IVzJOsxd11aQ==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-s390x-gnu": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.13.1.tgz", - "integrity": "sha512-U564BrhEfaNChdATQaEODtquCC7Ez+8Hxz1h5MAdMYj0AqD0GA9rHCpElajb/sQcaFL6NXmHc5O+7FXpWMa73Q==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-x64-gnu": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.1.tgz", - "integrity": "sha512-zGRDulLTeDemR8DFYyFIQ8kMP02xpUsX4IBikc7lwL9PrwR3gWmX2NopqiGlI2ZVWMl15qZeUjumTwpv18N7sQ==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-x64-musl": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.1.tgz", - "integrity": "sha512-VTk/MveyPdMFkYJJPCkYBw07KcTkGU2hLEyqYMsU4NjiOfzoaDTW9PWGRsNwiOA3qI0k/JQPjkl/4FCK1smskQ==", - "dev": true, - "optional": true - }, - "@rollup/rollup-win32-arm64-msvc": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.1.tgz", - "integrity": "sha512-L+hX8Dtibb02r/OYCsp4sQQIi3ldZkFI0EUkMTDwRfFykXBPptoz/tuuGqEd3bThBSLRWPR6wsixDSgOx/U3Zw==", - "dev": true, - "optional": true - }, - "@rollup/rollup-win32-ia32-msvc": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.1.tgz", - "integrity": "sha512-+dI2jVPfM5A8zme8riEoNC7UKk0Lzc7jCj/U89cQIrOjrZTCWZl/+IXUeRT2rEZ5j25lnSA9G9H1Ob9azaF/KQ==", - "dev": true, - "optional": true - }, - "@rollup/rollup-win32-x64-msvc": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.1.tgz", - "integrity": "sha512-YY1Exxo2viZ/O2dMHuwQvimJ0SqvL+OAWQLLY6rvXavgQKjhQUzn7nc1Dd29gjB5Fqi00nrBWctJBOyfVMIVxw==", "dev": true, "optional": true }, @@ -15697,67 +9423,12 @@ "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", "dev": true }, - "@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", - "dev": true, - "requires": { - "@sinonjs/commons": "^3.0.0" - } - }, - "@stencil/core": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.20.0.tgz", - "integrity": "sha512-WPrTHFngvN081RY+dJPneKQLwnOFD60OMCOQGmmSHfCW0f4ujPMzzhwWU1gcSwXPWXz5O+8cBiiCaxAbJU7kAg==" - }, - "@stencil/sass": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/@stencil/sass/-/sass-3.0.12.tgz", - "integrity": "sha512-aXMgpG13ftxLYo2dDauapvE9gKzSxTAqCMOfTqbPhKUCZ43JsknkLx+PArRaFtfYeVGSQ8eTS4ck7/Nlec+PNA==", - "requires": {} - }, - "@stencil/store": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/@stencil/store/-/store-2.0.16.tgz", - "integrity": "sha512-ET3EByKlmNyTA8O+tcp5YWePOiVnPIiuoiIaxTrf3zFFVo7JWVsVoak9IE0UTn3MkIM0ubR9lgxvi70uN588/A==", - "requires": {} - }, - "@tailwindcss/forms": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.7.tgz", - "integrity": "sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw==", - "requires": { - "mini-svg-data-uri": "^1.2.3" - } - }, "@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", "dev": true }, - "@tootallnate/quickjs-emscripten": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", - "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", - "dev": true - }, - "@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "dev": true - }, "@tufjs/canonical-json": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-1.0.0.tgz", @@ -15794,96 +9465,6 @@ } } }, - "@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, - "requires": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@types/babel__traverse": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz", - "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==", - "dev": true, - "requires": { - "@babel/types": "^7.20.7" - } - }, - "@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 - }, - "@types/graceful-fs": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", - "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true - }, - "@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/jest": { - "version": "29.5.12", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", - "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", - "dev": true, - "requires": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" - } - }, "@types/minimatch": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", @@ -15896,64 +9477,12 @@ "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", "dev": true }, - "@types/node": { - "version": "16.18.76", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.76.tgz", - "integrity": "sha512-/GsO2uv1Z6R42lBr59dtem56gVF/yHKQaScggwU+gLU6DXE25sDmOar4c4IfWb3h+X/7OYZznPOFk7oGF3jQSA==", - "dev": true - }, "@types/normalize-package-data": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", "dev": true }, - "@types/qrcode": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@types/qrcode/-/qrcode-1.5.5.tgz", - "integrity": "sha512-CdfBi/e3Qk+3Z/fXYShipBT13OJ2fDO2Q2w5CIP5anLTLIndQG9z6P1cnm+8zCWSpm5dnxMFd/uREtb0EXuQzg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/resolve": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", - "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", - "dev": true - }, - "@types/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "dev": true - }, - "@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true - }, - "@types/yauzl": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", - "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", - "dev": true, - "optional": true, - "requires": { - "@types/node": "*" - } - }, "@yarnpkg/lockfile": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", @@ -16006,12 +9535,6 @@ "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", "dev": true }, - "acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true - }, "add-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", @@ -16064,30 +9587,18 @@ "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true }, "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, "requires": { "color-convert": "^2.0.1" } }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" - }, - "anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, "aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", @@ -16104,11 +9615,6 @@ "readable-stream": "^3.6.0" } }, - "arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" - }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -16139,15 +9645,6 @@ "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", "dev": true }, - "ast-types": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", - "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", - "dev": true, - "requires": { - "tslib": "^2.0.1" - } - }, "async": { "version": "3.2.5", "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", @@ -16160,20 +9657,6 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "dev": true }, - "autoprefixer": { - "version": "10.4.17", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.17.tgz", - "integrity": "sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==", - "dev": true, - "requires": { - "browserslist": "^4.22.2", - "caniuse-lite": "^1.0.30001578", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "postcss-value-parser": "^4.2.0" - } - }, "axios": { "version": "1.6.7", "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", @@ -16185,156 +9668,11 @@ "proxy-from-env": "^1.1.0" } }, - "b4a": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", - "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==", - "dev": true - }, - "babel-extract-comments": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/babel-extract-comments/-/babel-extract-comments-1.0.0.tgz", - "integrity": "sha512-qWWzi4TlddohA91bFwgt6zO/J0X+io7Qp184Fw0m2JYRSTZnJbFR8+07KmzudHCZgOiKRCrjhylwv9Xd8gfhVQ==", - "dev": true, - "requires": { - "babylon": "^6.18.0" - } - }, - "babel-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", - "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", - "dev": true, - "requires": { - "@jest/transform": "^29.7.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.6.3", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - } - }, - "babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "dependencies": { - "istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, - "requires": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - } - }, - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "babel-plugin-jest-hoist": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", - "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", - "dev": true, - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-plugin-syntax-object-rest-spread": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", - "integrity": "sha512-C4Aq+GaAj83pRQ0EFgTvw5YO6T3Qz2KGrNRwIj9mSoNHVvdZY4KO2uA6HNtNXCw993iSZnckY1aLW8nOi8i4+w==", - "dev": true - }, - "babel-plugin-transform-object-rest-spread": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", - "integrity": "sha512-ocgA9VJvyxwt+qJB0ncxV8kb/CjfTcECUY4tQ5VT7nP6Aohzobm8CDFaQ5FHdvZQzLmf0sgDxB8iRXZXxwZcyA==", - "dev": true, - "requires": { - "babel-plugin-syntax-object-rest-spread": "^6.8.0", - "babel-runtime": "^6.26.0" - } - }, - "babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "requires": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - } - }, - "babel-preset-jest": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", - "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", - "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0" - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - } - } - }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true - }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "base64-js": { "version": "1.5.1", @@ -16342,23 +9680,12 @@ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true }, - "basic-ftp": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.4.tgz", - "integrity": "sha512-8PzkB0arJFV4jJWSGOYR+OEic6aeKMu/osRhBULN6RY0ykby6LKhbmuQ5ublvaas5BOwboah5D87nrHyuh8PPA==", - "dev": true - }, "before-after-hook": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", "dev": true }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" - }, "bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -16370,12 +9697,6 @@ "readable-stream": "^3.4.0" } }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -16390,31 +9711,11 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, "requires": { "fill-range": "^7.1.1" } }, - "browserslist": { - "version": "4.22.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.3.tgz", - "integrity": "sha512-UAp55yfwNv0klWNapjs/ktHoguxuQNGnOzxYmfnXIS+8AsRDZkSDxg7R1AX3GKzn078SBI5dzwzj/Yx0Or0e3A==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001580", - "electron-to-chromium": "^1.4.648", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" - } - }, - "bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "requires": { - "node-int64": "^0.4.0" - } - }, "buffer": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", @@ -16425,12 +9726,6 @@ "ieee754": "^1.1.13" } }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true - }, "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -16445,12 +9740,6 @@ "node-gyp-build": "^4.3.0" } }, - "builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "dev": true - }, "builtins": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", @@ -16512,12 +9801,8 @@ "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, - "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==" + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true }, "camelcase-keys": { "version": "6.2.2", @@ -16530,24 +9815,6 @@ "quick-lru": "^4.0.1" } }, - "caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "caniuse-lite": { - "version": "1.0.30001581", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001581.tgz", - "integrity": "sha512-whlTkwhqV2tUmP3oYhtNfaWGYHDdS3JYFQBKXxcUR9qqPWsRhFHhoISO2Xnl/g0xyKzht9mI1LZpiNWfMzHixQ==", - "dev": true - }, "chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -16558,60 +9825,24 @@ "supports-color": "^7.1.0" } }, - "char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true - }, "chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.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" - } - }, "chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", "dev": true }, - "chromium-bidi": { - "version": "0.4.22", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.22.tgz", - "integrity": "sha512-wR7Y9Ioez+cNXT4ZP7VNM1HRTljpNnMSLw4/RnwhhZUP4yCU7kIQND00YiktuHekch68jklGPK1q9Jkb29+fQg==", - "dev": true, - "requires": { - "mitt": "3.0.1" - } - }, "ci-info": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", "dev": true }, - "cjs-module-lexer": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", - "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", - "dev": true - }, "clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -16697,22 +9928,11 @@ "integrity": "sha512-S9iI9y0nKR4hwEQsVWpyxld/6kRfGepGfzff83FcaiEBpmvlbA2nnGe7Cylgrx2f/p1P5S5wpRm9oL8z1PbS3Q==", "dev": true }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true - }, - "collect-v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", - "dev": true - }, "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, "requires": { "color-name": "~1.1.4" } @@ -16720,7 +9940,8 @@ "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==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "color-support": { "version": "1.1.3", @@ -16728,12 +9949,6 @@ "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "dev": true }, - "colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", - "dev": true - }, "columnify": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.6.0.tgz", @@ -16753,24 +9968,6 @@ "delayed-stream": "~1.0.0" } }, - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true - }, - "common-tags": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", - "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true - }, "compare-func": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", @@ -16891,18 +10088,6 @@ "meow": "^8.1.2" } }, - "convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "core-js": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", - "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", - "dev": true - }, "core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", @@ -16921,45 +10106,11 @@ "path-type": "^4.0.0" } }, - "create-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", - "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", - "dev": true, - "requires": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "prompts": "^2.0.1" - } - }, - "cross-fetch": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", - "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", - "dev": true, - "requires": { - "node-fetch": "^2.6.12" - }, - "dependencies": { - "node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dev": true, - "requires": { - "whatwg-url": "^5.0.0" - } - } - } - }, "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, "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -16969,123 +10120,20 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, "requires": { "isexe": "^2.0.0" } } } }, - "css-declaration-sorter": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", - "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", - "dev": true, - "requires": {} - }, - "css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dev": true, - "requires": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - } - }, - "css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dev": true, - "requires": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - } - }, - "css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "dev": true - }, - "cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" - }, - "cssnano": { - "version": "5.1.15", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", - "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", - "dev": true, - "requires": { - "cssnano-preset-default": "^5.2.14", - "lilconfig": "^2.0.3", - "yaml": "^1.10.2" - } - }, - "cssnano-preset-default": { - "version": "5.2.14", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", - "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", - "dev": true, - "requires": { - "css-declaration-sorter": "^6.3.1", - "cssnano-utils": "^3.1.0", - "postcss-calc": "^8.2.3", - "postcss-colormin": "^5.3.1", - "postcss-convert-values": "^5.1.3", - "postcss-discard-comments": "^5.1.2", - "postcss-discard-duplicates": "^5.1.0", - "postcss-discard-empty": "^5.1.1", - "postcss-discard-overridden": "^5.1.0", - "postcss-merge-longhand": "^5.1.7", - "postcss-merge-rules": "^5.1.4", - "postcss-minify-font-values": "^5.1.0", - "postcss-minify-gradients": "^5.1.1", - "postcss-minify-params": "^5.1.4", - "postcss-minify-selectors": "^5.2.1", - "postcss-normalize-charset": "^5.1.0", - "postcss-normalize-display-values": "^5.1.0", - "postcss-normalize-positions": "^5.1.1", - "postcss-normalize-repeat-style": "^5.1.1", - "postcss-normalize-string": "^5.1.0", - "postcss-normalize-timing-functions": "^5.1.0", - "postcss-normalize-unicode": "^5.1.1", - "postcss-normalize-url": "^5.1.0", - "postcss-normalize-whitespace": "^5.1.1", - "postcss-ordered-values": "^5.1.3", - "postcss-reduce-initial": "^5.1.2", - "postcss-reduce-transforms": "^5.1.0", - "postcss-svgo": "^5.1.0", - "postcss-unique-selectors": "^5.1.1" - } - }, - "cssnano-utils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", - "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", - "dev": true, - "requires": {} - }, - "csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "dev": true, - "requires": { - "css-tree": "^1.1.2" - } - }, "d": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", @@ -17101,12 +10149,6 @@ "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", "dev": true }, - "data-uri-to-buffer": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.1.tgz", - "integrity": "sha512-MZd3VlchQkp8rdend6vrx7MmVDJzSNTBvghvKjirLkD+WTChA3KUf0jkE68Q4UyctNqI11zZO9/x2Yx+ub5Cvg==", - "dev": true - }, "dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", @@ -17124,7 +10166,8 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==" + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true }, "decamelize-keys": { "version": "1.1.1", @@ -17150,12 +10193,6 @@ "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", "dev": true }, - "deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true - }, "defaults": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", @@ -17171,17 +10208,6 @@ "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "dev": true }, - "degenerator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", - "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", - "dev": true, - "requires": { - "ast-types": "^0.13.4", - "escodegen": "^2.1.0", - "esprima": "^4.0.1" - } - }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -17206,34 +10232,12 @@ "integrity": "sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==", "dev": true }, - "detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true - }, - "devtools-protocol": { - "version": "0.0.1159816", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1159816.tgz", - "integrity": "sha512-2cZlHxC5IlgkIWe2pSDmCrDiTzbSJWywjbDDnupOImEBcG31CQgBLV8wWE+5t+C4rimcjHsbzy7CBzf9oFjboA==", - "dev": true - }, - "didyoumean": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" - }, "diff-sequences": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true }, - "dijkstrajs": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz", - "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==" - }, "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -17243,48 +10247,6 @@ "path-type": "^4.0.0" } }, - "dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" - }, - "dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "dev": true, - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - } - }, - "domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true - }, - "domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dev": true, - "requires": { - "domelementtype": "^2.2.0" - } - }, - "domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dev": true, - "requires": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - } - }, "dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", @@ -17315,7 +10277,8 @@ "eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true }, "ejs": { "version": "3.1.9", @@ -17326,22 +10289,11 @@ "jake": "^10.8.5" } }, - "electron-to-chromium": { - "version": "1.4.648", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.648.tgz", - "integrity": "sha512-EmFMarXeqJp9cUKu/QEciEApn0S/xRcpZWuAm32U7NgoZCimjsilKXHRO9saeEW55eHZagIDg6XTUOv32w9pjg==", - "dev": true - }, - "emittery": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", - "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", - "dev": true - }, "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==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "encoding": { "version": "0.1.13", @@ -17383,12 +10335,6 @@ "ansi-colors": "^4.1.1" } }, - "entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true - }, "env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", @@ -17457,42 +10403,12 @@ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true }, - "escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "dev": true, - "requires": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "source-map": "~0.6.1" - } - }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, "eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", @@ -17516,25 +10432,6 @@ "strip-final-newline": "^2.0.0" } }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true - }, - "expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", - "dev": true, - "requires": { - "@jest/expect-utils": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0" - } - }, "exponential-backoff": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", @@ -17578,39 +10475,11 @@ } } }, - "extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "requires": { - "@types/yauzl": "^2.9.1", - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - } - } - }, - "fast-fifo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", - "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "dev": true - }, "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, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -17619,38 +10488,15 @@ "micromatch": "^4.0.4" } }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, "fastq": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.0.tgz", "integrity": "sha512-zGygtijUMT7jnk3h26kUms3BkSDp4IfIKjmnqI2tvx6nuBfiF1UqOxbnLfzdv+apBy+53oaImsKtMw/xYbW+1w==", + "dev": true, "requires": { "reusify": "^1.0.4" } }, - "fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dev": true, - "requires": { - "bser": "2.1.1" - } - }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dev": true, - "requires": { - "pend": "~1.2.0" - } - }, "fetch-blob": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", @@ -17702,42 +10548,16 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "dependencies": { - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - } - }, - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } + "to-regex-range": "^5.0.1" } }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, "requires": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -17759,6 +10579,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, "requires": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -17767,7 +10588,8 @@ "signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true } } }, @@ -17790,12 +10612,6 @@ "fetch-blob": "^3.1.2" } }, - "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 - }, "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", @@ -17828,16 +10644,11 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, - "fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "optional": true - }, "function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true }, "gauge": { "version": "4.0.4", @@ -17855,27 +10666,10 @@ "wide-align": "^1.1.5" } }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true - }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", - "dev": true - }, - "get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, "get-pkg-repo": { @@ -17947,46 +10741,6 @@ "integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==", "dev": true }, - "get-uri": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.2.tgz", - "integrity": "sha512-5KLucCJobh8vBY1K07EFV4+cPZH3mrV9YeAruUseCQKHB58SGjjT2l9/eA9LD082IiuMjSlFJEcdJ27TXvbZNw==", - "dev": true, - "requires": { - "basic-ftp": "^5.0.2", - "data-uri-to-buffer": "^6.0.0", - "debug": "^4.3.4", - "fs-extra": "^8.1.0" - }, - "dependencies": { - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - } - } - }, "git-raw-commits": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-3.0.0.tgz", @@ -18058,6 +10812,7 @@ "version": "10.3.10", "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, "requires": { "foreground-child": "^3.1.0", "jackspeak": "^2.3.5", @@ -18070,6 +10825,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, "requires": { "balanced-match": "^1.0.0" } @@ -18078,6 +10834,7 @@ "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, "requires": { "brace-expansion": "^2.0.1" } @@ -18088,16 +10845,11 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, "requires": { "is-glob": "^4.0.1" } }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, "globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", @@ -18153,6 +10905,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, "requires": { "function-bind": "^1.1.2" } @@ -18166,12 +10919,6 @@ "lru-cache": "^6.0.0" } }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, "http-cache-semantics": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", @@ -18428,23 +11175,6 @@ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, - "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==", - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-builtin-module": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", - "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", - "dev": true, - "requires": { - "builtin-modules": "^3.3.0" - } - }, "is-ci": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", @@ -18458,6 +11188,7 @@ "version": "2.13.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, "requires": { "hasown": "^2.0.0" } @@ -18471,23 +11202,20 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true }, "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==" - }, - "is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "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, "requires": { "is-extglob": "^2.1.1" } @@ -18504,16 +11232,11 @@ "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", "dev": true }, - "is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", - "dev": true - }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true }, "is-obj": { "version": "2.0.0", @@ -18533,21 +11256,6 @@ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true }, - "is-reference": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "dev": true, - "requires": { - "@types/estree": "*" - } - }, - "is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", - "dev": true - }, "is-ssh": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.0.tgz", @@ -18610,61 +11318,11 @@ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true }, - "istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz", - "integrity": "sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==", - "dev": true, - "requires": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" - } - }, - "istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - } - }, - "istanbul-reports": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, "jackspeak": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, "requires": { "@isaacs/cliui": "^8.0.2", "@pkgjs/parseargs": "^0.11.0" @@ -18693,160 +11351,6 @@ } } }, - "jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", - "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", - "dev": true, - "requires": { - "@jest/core": "^29.7.0", - "@jest/types": "^29.6.3", - "import-local": "^3.0.2", - "jest-cli": "^29.7.0" - } - }, - "jest-changed-files": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", - "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", - "dev": true, - "requires": { - "execa": "^5.0.0", - "jest-util": "^29.7.0", - "p-limit": "^3.1.0" - }, - "dependencies": { - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - } - } - }, - "jest-circus": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", - "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", - "dev": true, - "requires": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^1.0.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^29.7.0", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "p-limit": "^3.1.0", - "pretty-format": "^29.7.0", - "pure-rand": "^6.0.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "dependencies": { - "dedent": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", - "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", - "dev": true, - "requires": {} - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - } - } - }, - "jest-cli": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", - "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", - "dev": true, - "requires": { - "@jest/core": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "create-jest": "^29.7.0", - "exit": "^0.1.2", - "import-local": "^3.0.2", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "yargs": "^17.3.1" - } - }, - "jest-config": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", - "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-jest": "^29.7.0", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-circus": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, "jest-diff": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", @@ -18859,361 +11363,12 @@ "pretty-format": "^29.7.0" } }, - "jest-docblock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", - "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", - "dev": true, - "requires": { - "detect-newline": "^3.0.0" - } - }, - "jest-each": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", - "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", - "dev": true, - "requires": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "jest-util": "^29.7.0", - "pretty-format": "^29.7.0" - } - }, - "jest-environment-node": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", - "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", - "dev": true, - "requires": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - } - }, "jest-get-type": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", "dev": true }, - "jest-haste-map": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", - "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", - "dev": true, - "requires": { - "@jest/types": "^29.6.3", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.3.2", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - } - }, - "jest-leak-detector": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", - "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", - "dev": true, - "requires": { - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - } - }, - "jest-matcher-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", - "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - } - }, - "jest-message-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", - "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.6.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-mock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", - "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", - "dev": true, - "requires": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-util": "^29.7.0" - } - }, - "jest-pnp-resolver": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "dev": true, - "requires": {} - }, - "jest-regex-util": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", - "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", - "dev": true - }, - "jest-resolve": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", - "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "resolve": "^1.20.0", - "resolve.exports": "^2.0.0", - "slash": "^3.0.0" - } - }, - "jest-resolve-dependencies": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", - "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", - "dev": true, - "requires": { - "jest-regex-util": "^29.6.3", - "jest-snapshot": "^29.7.0" - } - }, - "jest-runner": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", - "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", - "dev": true, - "requires": { - "@jest/console": "^29.7.0", - "@jest/environment": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-leak-detector": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-resolve": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-util": "^29.7.0", - "jest-watcher": "^29.7.0", - "jest-worker": "^29.7.0", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" - }, - "dependencies": { - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - } - } - }, - "jest-runtime": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", - "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", - "dev": true, - "requires": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/globals": "^29.7.0", - "@jest/source-map": "^29.6.3", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "jest-snapshot": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", - "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.7.0", - "semver": "^7.5.3" - } - }, - "jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", - "dev": true, - "requires": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - }, - "jest-validate": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", - "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", - "dev": true, - "requires": { - "@jest/types": "^29.6.3", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "leven": "^3.1.0", - "pretty-format": "^29.7.0" - }, - "dependencies": { - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - } - } - }, - "jest-watcher": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", - "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", - "dev": true, - "requires": { - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "jest-util": "^29.7.0", - "string-length": "^4.0.1" - } - }, - "jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", - "dev": true, - "requires": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "dependencies": { - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jiti": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", - "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==" - }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -19235,12 +11390,6 @@ "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", "dev": true }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -19303,12 +11452,6 @@ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true }, - "kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true - }, "lerna": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/lerna/-/lerna-8.0.2.tgz", @@ -19391,12 +11534,6 @@ "yargs-parser": "21.1.1" } }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true - }, "libnpmaccess": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/libnpmaccess/-/libnpmaccess-7.0.2.tgz", @@ -19517,11 +11654,6 @@ } } }, - "lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==" - }, "lines-and-columns": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.4.tgz", @@ -19552,6 +11684,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, "requires": { "p-locate": "^4.1.0" } @@ -19562,49 +11695,12 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==", - "dev": true - }, "lodash.ismatch": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", "dev": true }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true - }, - "lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0" - } - }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", - "dev": true - }, "log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -19624,15 +11720,6 @@ "yallist": "^4.0.0" } }, - "magic-string": { - "version": "0.30.5", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", - "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", - "dev": true, - "requires": { - "@jridgewell/sourcemap-codec": "^1.4.15" - } - }, "make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", @@ -19672,27 +11759,12 @@ } } }, - "makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "requires": { - "tmpl": "1.0.5" - } - }, "map-obj": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", "dev": true }, - "mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "dev": true - }, "meow": { "version": "8.1.2", "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", @@ -19798,12 +11870,14 @@ "merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true }, "micromatch": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, "requires": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -19836,11 +11910,6 @@ "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true }, - "mini-svg-data-uri": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", - "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==" - }, "minimatch": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", @@ -19870,7 +11939,8 @@ "minipass": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==" + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true }, "minipass-collect": { "version": "2.0.1", @@ -19995,24 +12065,12 @@ } } }, - "mitt": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", - "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", - "dev": true - }, "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true }, - "mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, "modify-values": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", @@ -20051,27 +12109,6 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, - "mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "requires": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, - "nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==" - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, "negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -20084,12 +12121,6 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, - "netmask": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", - "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", - "dev": true - }, "next-tick": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", @@ -20132,24 +12163,12 @@ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.0.tgz", "integrity": "sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==" }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true - }, "node-machine-id": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/node-machine-id/-/node-machine-id-1.1.12.tgz", "integrity": "sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==", "dev": true }, - "node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true - }, "nopt": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.0.tgz", @@ -20171,99 +12190,35 @@ "validate-npm-package-license": "^3.0.1" } }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, - "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 - }, - "normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true - }, - "nostr-login": { - "version": "file:packages/auth", - "requires": { - "@nostr-dev-kit/ndk": "^2.3.1", - "@rollup/plugin-commonjs": "^25.0.7", - "@rollup/plugin-node-resolve": "^15.2.3", - "@rollup/plugin-terser": "^0.4.4", - "nostr-login-components": "^1.0.3", - "nostr-tools": "^1.17.0", - "prettier": "^3.2.2", - "rollup": "^4.9.6", - "rollup-plugin-typescript2": "^0.36.0", - "tseep": "^1.2.1" - }, - "dependencies": { - "rollup": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.1.tgz", - "integrity": "sha512-hFi+fU132IvJ2ZuihN56dwgpltpmLZHZWsx27rMCTZ2sYwrqlgL5sECGy1eeV2lAihD8EzChBVVhsXci0wD4Tg==", - "dev": true, - "requires": { - "@rollup/rollup-android-arm-eabi": "4.13.1", - "@rollup/rollup-android-arm64": "4.13.1", - "@rollup/rollup-darwin-arm64": "4.13.1", - "@rollup/rollup-darwin-x64": "4.13.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.13.1", - "@rollup/rollup-linux-arm64-gnu": "4.13.1", - "@rollup/rollup-linux-arm64-musl": "4.13.1", - "@rollup/rollup-linux-riscv64-gnu": "4.13.1", - "@rollup/rollup-linux-s390x-gnu": "4.13.1", - "@rollup/rollup-linux-x64-gnu": "4.13.1", - "@rollup/rollup-linux-x64-musl": "4.13.1", - "@rollup/rollup-win32-arm64-msvc": "4.13.1", - "@rollup/rollup-win32-ia32-msvc": "4.13.1", - "@rollup/rollup-win32-x64-msvc": "4.13.1", - "@types/estree": "1.0.5", - "fsevents": "~2.3.2" - } - } - } - }, - "nostr-login-components": { - "version": "file:packages/components", - "requires": { - "@stencil/core": "^4.20.0", - "@stencil/sass": "^3.0.12", - "@stencil/store": "^2.0.16", - "@tailwindcss/forms": "^0.5.7", - "@types/jest": "^29.5.6", - "@types/node": "^16.18.11", - "@types/qrcode": "^1.5.5", - "jest": "^29.7.0", - "jest-cli": "^29.7.0", - "prettier": "^3.2.2", - "puppeteer": "21.1.1", - "qrcode": "^1.5.4", - "stencil-tailwind-plugin": "^1.8.0", - "tailwindcss": "^3.4.0", - "tailwindcss-rtl": "^0.9.0", - "typescript": "^5.3.3", - "workbox-build": "^4.3.1" - } - }, "nostr-tools": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/nostr-tools/-/nostr-tools-1.17.0.tgz", - "integrity": "sha512-LZmR8GEWKZeElbFV5Xte75dOeE9EFUW/QLI1Ncn3JKn0kFddDKEfBbFN8Mu4TMs+L4HR/WTPha2l+PPuRnJcMw==", + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/nostr-tools/-/nostr-tools-2.16.2.tgz", + "integrity": "sha512-ZxH9EbSt5ypURZj2TGNJxZd0Omb5ag5KZSu8IyJMCdLyg2KKz+2GA0sP/cSawCQEkyviIN4eRT4G2gB/t9lMRw==", "requires": { - "@noble/ciphers": "0.2.0", - "@noble/curves": "1.1.0", + "@noble/ciphers": "^0.5.1", + "@noble/curves": "1.2.0", "@noble/hashes": "1.3.1", "@scure/base": "1.1.1", "@scure/bip32": "1.3.1", - "@scure/bip39": "1.2.1" + "@scure/bip39": "1.2.1", + "nostr-wasm": "0.1.0" }, "dependencies": { + "@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "requires": { + "@noble/hashes": "1.3.2" + }, + "dependencies": { + "@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==" + } + } + }, "@noble/hashes": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", @@ -20276,6 +12231,11 @@ } } }, + "nostr-wasm": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/nostr-wasm/-/nostr-wasm-0.1.0.tgz", + "integrity": "sha512-78BTryCLcLYv96ONU8Ws3Q1JzjlAt+43pWQhIl86xZmWeegYCNLPml7yQ+gG3vR6V5h4XGj+TxO+SS5dsThQIA==" + }, "npm-bundled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz", @@ -20629,15 +12589,6 @@ "set-blocking": "^2.0.0" } }, - "nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dev": true, - "requires": { - "boolbase": "^1.0.0" - } - }, "nx": { "version": "17.2.8", "resolved": "https://registry.npmjs.org/nx/-/nx-17.2.8.tgz", @@ -20715,16 +12666,6 @@ } } }, - "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==" - }, - "object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==" - }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -20787,6 +12728,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, "requires": { "p-try": "^2.0.0" } @@ -20795,6 +12737,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, "requires": { "p-limit": "^2.2.0" } @@ -20848,7 +12791,8 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true }, "p-waterfall": { "version": "2.1.1", @@ -20859,32 +12803,6 @@ "p-reduce": "^2.0.0" } }, - "pac-proxy-agent": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.1.tgz", - "integrity": "sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==", - "dev": true, - "requires": { - "@tootallnate/quickjs-emscripten": "^0.23.0", - "agent-base": "^7.0.2", - "debug": "^4.3.4", - "get-uri": "^6.0.1", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.2", - "pac-resolver": "^7.0.0", - "socks-proxy-agent": "^8.0.2" - } - }, - "pac-resolver": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", - "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", - "dev": true, - "requires": { - "degenerator": "^5.0.0", - "netmask": "^2.0.2" - } - }, "pacote": { "version": "17.0.6", "resolved": "https://registry.npmjs.org/pacote/-/pacote-17.0.6.tgz", @@ -21158,7 +13076,8 @@ "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true }, "path-is-absolute": { "version": "1.0.1", @@ -21169,17 +13088,20 @@ "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true }, "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==" + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true }, "path-scurry": { "version": "1.10.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, "requires": { "lru-cache": "^9.1.1 || ^10.0.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" @@ -21188,7 +13110,8 @@ "lru-cache": { "version": "10.2.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", - "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==" + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "dev": true } } }, @@ -21198,21 +13121,11 @@ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" - }, "picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true }, "pify": { "version": "5.0.0", @@ -21220,11 +13133,6 @@ "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", "dev": true }, - "pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==" - }, "pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -21234,354 +13142,6 @@ "find-up": "^4.0.0" } }, - "pngjs": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", - "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==" - }, - "postcss": { - "version": "8.4.33", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz", - "integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==", - "requires": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - } - }, - "postcss-calc": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", - "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", - "dev": true, - "requires": { - "postcss-selector-parser": "^6.0.9", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-colormin": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", - "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", - "dev": true, - "requires": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0", - "colord": "^2.9.1", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-combine-duplicated-selectors": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/postcss-combine-duplicated-selectors/-/postcss-combine-duplicated-selectors-10.0.3.tgz", - "integrity": "sha512-IP0BmwFloCskv7DV7xqvzDXqMHpwdczJa6ZvIW8abgHdcIHs9mCJX2ltFhu3EwA51ozp13DByng30+Ke+eIExA==", - "dev": true, - "requires": { - "postcss-selector-parser": "^6.0.4" - } - }, - "postcss-convert-values": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", - "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", - "dev": true, - "requires": { - "browserslist": "^4.21.4", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-discard-comments": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", - "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", - "dev": true, - "requires": {} - }, - "postcss-discard-duplicates": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", - "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", - "dev": true, - "requires": {} - }, - "postcss-discard-empty": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", - "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", - "dev": true, - "requires": {} - }, - "postcss-discard-overridden": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", - "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", - "dev": true, - "requires": {} - }, - "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==", - "requires": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - } - }, - "postcss-js": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", - "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", - "requires": { - "camelcase-css": "^2.0.1" - } - }, - "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==", - "requires": { - "lilconfig": "^3.0.0", - "yaml": "^2.3.4" - }, - "dependencies": { - "lilconfig": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", - "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==" - }, - "yaml": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", - "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==" - } - } - }, - "postcss-merge-longhand": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", - "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0", - "stylehacks": "^5.1.1" - } - }, - "postcss-merge-rules": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", - "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", - "dev": true, - "requires": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^3.1.0", - "postcss-selector-parser": "^6.0.5" - } - }, - "postcss-minify-font-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", - "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-minify-gradients": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", - "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", - "dev": true, - "requires": { - "colord": "^2.9.1", - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-minify-params": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", - "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", - "dev": true, - "requires": { - "browserslist": "^4.21.4", - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-minify-selectors": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", - "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", - "dev": true, - "requires": { - "postcss-selector-parser": "^6.0.5" - } - }, - "postcss-nested": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", - "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", - "requires": { - "postcss-selector-parser": "^6.0.11" - } - }, - "postcss-normalize-charset": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", - "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", - "dev": true, - "requires": {} - }, - "postcss-normalize-display-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", - "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-positions": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", - "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-repeat-style": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", - "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-string": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", - "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-timing-functions": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", - "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-unicode": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", - "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", - "dev": true, - "requires": { - "browserslist": "^4.21.4", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", - "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", - "dev": true, - "requires": { - "normalize-url": "^6.0.1", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-whitespace": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", - "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-ordered-values": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", - "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", - "dev": true, - "requires": { - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-reduce-initial": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", - "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", - "dev": true, - "requires": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0" - } - }, - "postcss-reduce-transforms": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", - "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-selector-parser": { - "version": "6.0.15", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz", - "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==", - "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - } - }, - "postcss-svgo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", - "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0", - "svgo": "^2.7.0" - } - }, - "postcss-unique-selectors": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", - "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", - "dev": true, - "requires": { - "postcss-selector-parser": "^6.0.5" - } - }, - "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==" - }, - "prettier": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.4.tgz", - "integrity": "sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==", - "dev": true - }, - "pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "dev": true - }, "pretty-format": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", @@ -21613,12 +13173,6 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, "promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", @@ -21635,16 +13189,6 @@ "retry": "^0.12.0" } }, - "prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "requires": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - } - }, "promzard": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/promzard/-/promzard-1.0.0.tgz", @@ -21660,154 +13204,16 @@ "integrity": "sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==", "dev": true }, - "proxy-agent": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.0.tgz", - "integrity": "sha512-0LdR757eTj/JfuU7TL2YCuAZnxWXu3tkJbg4Oq3geW/qFNT/32T0sp2HnZ9O0lMR4q3vwAt0+xCA8SR0WAD0og==", - "dev": true, - "requires": { - "agent-base": "^7.0.2", - "debug": "^4.3.4", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.0", - "lru-cache": "^7.14.1", - "pac-proxy-agent": "^7.0.0", - "proxy-from-env": "^1.1.0", - "socks-proxy-agent": "^8.0.1" - }, - "dependencies": { - "lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true - } - } - }, "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 }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "puppeteer": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-21.1.1.tgz", - "integrity": "sha512-2TLntjGA4qLrI9/8N0UK/5OoZJ2Ue7QgphN2SD+RsaHiha12AEiVyMGsB+i6LY1IoPAtEgYIjblQ7lw3kWDNRw==", - "dev": true, - "requires": { - "@puppeteer/browsers": "1.7.0", - "cosmiconfig": "8.2.0", - "puppeteer-core": "21.1.1" - }, - "dependencies": { - "cosmiconfig": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz", - "integrity": "sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==", - "dev": true, - "requires": { - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0" - } - } - } - }, - "puppeteer-core": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-21.1.1.tgz", - "integrity": "sha512-Tlcajcf44zwfa9Sbwv3T8BtaNMJ69wtpHIxwl2NOBTyTK3D1wppQovXTjfw0TDOm3a16eCfQ+5BMi3vRQ4kuAQ==", - "dev": true, - "requires": { - "@puppeteer/browsers": "1.7.0", - "chromium-bidi": "0.4.22", - "cross-fetch": "4.0.0", - "debug": "4.3.4", - "devtools-protocol": "0.0.1159816", - "ws": "8.13.0" - } - }, - "pure-rand": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", - "integrity": "sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==", - "dev": true - }, - "qrcode": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.4.tgz", - "integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==", - "requires": { - "dijkstrajs": "^1.0.1", - "pngjs": "^5.0.0", - "yargs": "^15.3.1" - }, - "dependencies": { - "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" - }, - "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - } - }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" - }, - "queue-tick": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", - "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, "quick-lru": { @@ -21816,15 +13222,6 @@ "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, "react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", @@ -21848,21 +13245,6 @@ } } }, - "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==", - "requires": { - "pify": "^2.3.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==" - } - } - }, "read-cmd-shim": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-4.0.0.tgz", @@ -22098,14 +13480,6 @@ "util-deprecate": "^1.0.1" } }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "requires": { - "picomatch": "^2.2.1" - } - }, "redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -22116,26 +13490,17 @@ "strip-indent": "^3.0.0" } }, - "regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true }, "resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, "requires": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -22157,12 +13522,6 @@ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, - "resolve.exports": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", - "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", - "dev": true - }, "restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", @@ -22182,7 +13541,8 @@ "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true }, "rimraf": { "version": "4.4.1", @@ -22231,52 +13591,6 @@ } } }, - "rollup": { - "version": "2.79.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", - "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", - "dev": true, - "peer": true, - "requires": { - "fsevents": "~2.3.2" - } - }, - "rollup-plugin-typescript2": { - "version": "0.36.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.36.0.tgz", - "integrity": "sha512-NB2CSQDxSe9+Oe2ahZbf+B4bh7pHwjV5L+RSYpCu7Q5ROuN94F9b6ioWwKfz3ueL3KTtmX4o2MUH2cgHDIEUsw==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^4.1.2", - "find-cache-dir": "^3.3.2", - "fs-extra": "^10.0.0", - "semver": "^7.5.4", - "tslib": "^2.6.2" - }, - "dependencies": { - "@rollup/pluginutils": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", - "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", - "dev": true, - "requires": { - "estree-walker": "^2.0.1", - "picomatch": "^2.2.2" - } - }, - "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - } - } - }, "run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", @@ -22287,6 +13601,7 @@ "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, "requires": { "queue-microtask": "^1.2.2" } @@ -22324,7 +13639,8 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true }, "shallow-clone": { "version": "3.0.1", @@ -22339,6 +13655,7 @@ "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, "requires": { "shebang-regex": "^3.0.0" } @@ -22346,7 +13663,8 @@ "shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true }, "signal-exit": { "version": "3.0.7", @@ -22496,12 +13814,6 @@ } } }, - "sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -22514,12 +13826,6 @@ "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", "dev": true }, - "smob": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/smob/-/smob-1.4.1.tgz", - "integrity": "sha512-9LK+E7Hv5R9u4g4C3p+jjLstaLe11MDsL21UpYaCNmapvMkYhqCV4A/f/3gyH8QjMyh6l68q9xC85vihY9ahMQ==", - "dev": true - }, "socks": { "version": "2.8.3", "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", @@ -22556,21 +13862,6 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, - "source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, "spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", @@ -22647,79 +13938,6 @@ } } }, - "stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "dev": true - }, - "stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - } - } - }, - "stencil-tailwind-plugin": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/stencil-tailwind-plugin/-/stencil-tailwind-plugin-1.8.0.tgz", - "integrity": "sha512-39vFtvTy+Pi5leroD6pY9H1DMKKCpYDPInTSwKJrOkgfT0v9K+KWOG9NSuO4G0eJfF27R7G6NIjP3Bsi10iLsg==", - "dev": true, - "requires": { - "autoprefixer": "^10.4.7", - "chalk": "^4.1.2", - "cssnano": "^5.1.12", - "fs-extra": "^10.0.0", - "p-queue": "^6.6.2", - "postcss": "^8.4.14", - "postcss-combine-duplicated-selectors": "^10.0.3", - "postcss-discard-comments": "^5.1.2", - "postcss-load-config": "^4.0.1" - }, - "dependencies": { - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - } - } - }, - "streamx": { - "version": "2.15.6", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.6.tgz", - "integrity": "sha512-q+vQL4AAz+FdfT137VF69Cc/APqUbxy+MDOImRrMvchJpigHj9GksgDU2LYbO9rx7RX6osWgxJB2WxhYv4SZAw==", - "dev": true, - "requires": { - "fast-fifo": "^1.1.0", - "queue-tick": "^1.0.1" - } - }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -22729,20 +13947,11 @@ "safe-buffer": "~5.2.0" } }, - "string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "requires": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - } - }, "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, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -22753,35 +13962,18 @@ "version": "npm:string-width@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, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, - "stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "dev": true, - "requires": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - }, - "dependencies": { - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", - "dev": true - } - } - }, "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, "requires": { "ansi-regex": "^5.0.1" } @@ -22790,6 +13982,7 @@ "version": "npm:strip-ansi@6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "requires": { "ansi-regex": "^5.0.1" } @@ -22800,16 +13993,6 @@ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true }, - "strip-comments": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-1.0.2.tgz", - "integrity": "sha512-kL97alc47hoyIQSV165tTt9rG5dn4w1dNnBhOQ3bOU1Nc1hel09jnXANaHJ7vzHLd4Ju8kseDGzlev96pghLFw==", - "dev": true, - "requires": { - "babel-extract-comments": "^1.0.0", - "babel-plugin-transform-object-rest-spread": "^6.26.0" - } - }, "strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -22825,12 +14008,6 @@ "min-indent": "^1.0.0" } }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, "strong-log-transformer": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz", @@ -22842,42 +14019,6 @@ "through": "^2.3.4" } }, - "stylehacks": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", - "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", - "dev": true, - "requires": { - "browserslist": "^4.21.4", - "postcss-selector-parser": "^6.0.4" - } - }, - "sucrase": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", - "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", - "requires": { - "@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" - }, - "dependencies": { - "commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==" - }, - "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==" - } - } - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -22890,66 +14031,8 @@ "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==" - }, - "svgo": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", - "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", - "dev": true, - "requires": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^4.1.3", - "css-tree": "^1.1.3", - "csso": "^4.2.0", - "picocolors": "^1.0.0", - "stable": "^0.1.8" - } - }, - "tailwindcss": { - "version": "3.4.10", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.10.tgz", - "integrity": "sha512-KWZkVPm7yJRhdu4SRSl9d4AK2wM3a50UsvgHZO7xY77NQr2V+fIrEuoDGQcbvswWvFGbS2f6e+jC/6WJm1Dl0w==", - "requires": { - "@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" - }, - "dependencies": { - "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==", - "requires": { - "is-glob": "^4.0.3" - } - } - } - }, - "tailwindcss-rtl": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/tailwindcss-rtl/-/tailwindcss-rtl-0.9.0.tgz", - "integrity": "sha512-y7yC8QXjluDBEFMSX33tV6xMYrf0B3sa+tOB5JSQb6/G6laBU313a+Z+qxu55M1Qyn8tDMttjomsA8IsJD+k+w==" + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true }, "tar": { "version": "6.1.11", @@ -22985,30 +14068,6 @@ } } }, - "tar-fs": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", - "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", - "dev": true, - "requires": { - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - }, - "dependencies": { - "tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", - "dev": true, - "requires": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - } - } - }, "tar-stream": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", @@ -23028,94 +14087,12 @@ "integrity": "sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ==", "dev": true }, - "terser": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.30.0.tgz", - "integrity": "sha512-Y/SblUl5kEyEFzhMAQdsxVHh+utAxd4IuRNJzKywY/4uzSogh3G219jqbDDxYu4MXO9CzY3tSEqmZvW6AoEDJw==", - "dev": true, - "requires": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - } - } - }, - "test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "dependencies": { - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, "text-extensions": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", "dev": true }, - "thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "requires": { - "any-promise": "^1.0.0" - } - }, - "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==", - "requires": { - "thenify": ">= 3.1.0 < 4" - } - }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -23207,22 +14184,11 @@ } } }, - "tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true - }, "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, "requires": { "is-number": "^7.0.0" } @@ -23239,11 +14205,6 @@ "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", "dev": true }, - "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==" - }, "tsconfig-paths": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", @@ -23424,12 +14385,6 @@ "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, "type-fest": { "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", @@ -23468,16 +14423,6 @@ "dev": true, "optional": true }, - "unbzip2-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", - "dev": true, - "requires": { - "buffer": "^5.2.1", - "through": "^2.3.8" - } - }, "unique-filename": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", @@ -23514,16 +14459,6 @@ "integrity": "sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==", "dev": true }, - "update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", - "dev": true, - "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - } - }, "utf-8-validate": { "version": "5.0.10", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", @@ -23540,7 +14475,8 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true }, "uuid": { "version": "9.0.1", @@ -23548,17 +14484,6 @@ "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", "dev": true }, - "v8-to-istanbul": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", - "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^2.0.0" - } - }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -23578,15 +14503,6 @@ "builtins": "^5.0.0" } }, - "walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "requires": { - "makeerror": "1.0.12" - } - }, "wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", @@ -23663,11 +14579,6 @@ "isexe": "^3.1.1" } }, - "which-module": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==" - }, "wide-align": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", @@ -23683,215 +14594,11 @@ "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", "dev": true }, - "workbox-background-sync": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-4.3.1.tgz", - "integrity": "sha512-1uFkvU8JXi7L7fCHVBEEnc3asPpiAL33kO495UMcD5+arew9IbKW2rV5lpzhoWcm/qhGB89YfO4PmB/0hQwPRg==", - "dev": true, - "requires": { - "workbox-core": "^4.3.1" - } - }, - "workbox-broadcast-update": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-4.3.1.tgz", - "integrity": "sha512-MTSfgzIljpKLTBPROo4IpKjESD86pPFlZwlvVG32Kb70hW+aob4Jxpblud8EhNb1/L5m43DUM4q7C+W6eQMMbA==", - "dev": true, - "requires": { - "workbox-core": "^4.3.1" - } - }, - "workbox-build": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-4.3.1.tgz", - "integrity": "sha512-UHdwrN3FrDvicM3AqJS/J07X0KXj67R8Cg0waq1MKEOqzo89ap6zh6LmaLnRAjpB+bDIz+7OlPye9iii9KBnxw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.3.4", - "@hapi/joi": "^15.0.0", - "common-tags": "^1.8.0", - "fs-extra": "^4.0.2", - "glob": "^7.1.3", - "lodash.template": "^4.4.0", - "pretty-bytes": "^5.1.0", - "stringify-object": "^3.3.0", - "strip-comments": "^1.0.2", - "workbox-background-sync": "^4.3.1", - "workbox-broadcast-update": "^4.3.1", - "workbox-cacheable-response": "^4.3.1", - "workbox-core": "^4.3.1", - "workbox-expiration": "^4.3.1", - "workbox-google-analytics": "^4.3.1", - "workbox-navigation-preload": "^4.3.1", - "workbox-precaching": "^4.3.1", - "workbox-range-requests": "^4.3.1", - "workbox-routing": "^4.3.1", - "workbox-strategies": "^4.3.1", - "workbox-streams": "^4.3.1", - "workbox-sw": "^4.3.1", - "workbox-window": "^4.3.1" - }, - "dependencies": { - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - } - } - }, - "workbox-cacheable-response": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-4.3.1.tgz", - "integrity": "sha512-Rp5qlzm6z8IOvnQNkCdO9qrDgDpoPNguovs0H8C+wswLuPgSzSp9p2afb5maUt9R1uTIwOXrVQMmPfPypv+npw==", - "dev": true, - "requires": { - "workbox-core": "^4.3.1" - } - }, - "workbox-core": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-4.3.1.tgz", - "integrity": "sha512-I3C9jlLmMKPxAC1t0ExCq+QoAMd0vAAHULEgRZ7kieCdUd919n53WC0AfvokHNwqRhGn+tIIj7vcb5duCjs2Kg==", - "dev": true - }, - "workbox-expiration": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-4.3.1.tgz", - "integrity": "sha512-vsJLhgQsQouv9m0rpbXubT5jw0jMQdjpkum0uT+d9tTwhXcEZks7qLfQ9dGSaufTD2eimxbUOJfWLbNQpIDMPw==", - "dev": true, - "requires": { - "workbox-core": "^4.3.1" - } - }, - "workbox-google-analytics": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-4.3.1.tgz", - "integrity": "sha512-xzCjAoKuOb55CBSwQrbyWBKqp35yg1vw9ohIlU2wTy06ZrYfJ8rKochb1MSGlnoBfXGWss3UPzxR5QL5guIFdg==", - "dev": true, - "requires": { - "workbox-background-sync": "^4.3.1", - "workbox-core": "^4.3.1", - "workbox-routing": "^4.3.1", - "workbox-strategies": "^4.3.1" - } - }, - "workbox-navigation-preload": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-4.3.1.tgz", - "integrity": "sha512-K076n3oFHYp16/C+F8CwrRqD25GitA6Rkd6+qAmLmMv1QHPI2jfDwYqrytOfKfYq42bYtW8Pr21ejZX7GvALOw==", - "dev": true, - "requires": { - "workbox-core": "^4.3.1" - } - }, - "workbox-precaching": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-4.3.1.tgz", - "integrity": "sha512-piSg/2csPoIi/vPpp48t1q5JLYjMkmg5gsXBQkh/QYapCdVwwmKlU9mHdmy52KsDGIjVaqEUMFvEzn2LRaigqQ==", - "dev": true, - "requires": { - "workbox-core": "^4.3.1" - } - }, - "workbox-range-requests": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-4.3.1.tgz", - "integrity": "sha512-S+HhL9+iTFypJZ/yQSl/x2Bf5pWnbXdd3j57xnb0V60FW1LVn9LRZkPtneODklzYuFZv7qK6riZ5BNyc0R0jZA==", - "dev": true, - "requires": { - "workbox-core": "^4.3.1" - } - }, - "workbox-routing": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-4.3.1.tgz", - "integrity": "sha512-FkbtrODA4Imsi0p7TW9u9MXuQ5P4pVs1sWHK4dJMMChVROsbEltuE79fBoIk/BCztvOJ7yUpErMKa4z3uQLX+g==", - "dev": true, - "requires": { - "workbox-core": "^4.3.1" - } - }, - "workbox-strategies": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-4.3.1.tgz", - "integrity": "sha512-F/+E57BmVG8dX6dCCopBlkDvvhg/zj6VDs0PigYwSN23L8hseSRwljrceU2WzTvk/+BSYICsWmRq5qHS2UYzhw==", - "dev": true, - "requires": { - "workbox-core": "^4.3.1" - } - }, - "workbox-streams": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-4.3.1.tgz", - "integrity": "sha512-4Kisis1f/y0ihf4l3u/+ndMkJkIT4/6UOacU3A4BwZSAC9pQ9vSvJpIi/WFGQRH/uPXvuVjF5c2RfIPQFSS2uA==", - "dev": true, - "requires": { - "workbox-core": "^4.3.1" - } - }, - "workbox-sw": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-4.3.1.tgz", - "integrity": "sha512-0jXdusCL2uC5gM3yYFT6QMBzKfBr2XTk0g5TPAV4y8IZDyVNDyj1a8uSXy3/XrvkVTmQvLN4O5k3JawGReXr9w==", - "dev": true - }, - "workbox-window": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-4.3.1.tgz", - "integrity": "sha512-C5gWKh6I58w3GeSc0wp2Ne+rqVw8qwcmZnQGpjiek8A2wpbxSJb1FdCoQVO+jDJs35bFgo/WETgl1fqgsxN0Hg==", - "dev": true, - "requires": { - "workbox-core": "^4.3.1" - } - }, "wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -23902,6 +14609,7 @@ "version": "npm:wrap-ansi@7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -24000,13 +14708,6 @@ } } }, - "ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", - "dev": true, - "requires": {} - }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -24030,12 +14731,6 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true - }, "yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", @@ -24056,22 +14751,6 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true - }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true } } } diff --git a/package.json b/package.json index e329fe8..fe7a461 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "publish": "lerna publish --no-private" }, "dependencies": { - "@nostr-dev-kit/ndk": "^2.4.0" + "@nostr-dev-kit/ndk": "^2.4.0", + "nostr-tools": "^2.16.2" }, "devDependencies": { "lerna": "^8.0.2" diff --git a/packages/auth/.prettierrc.json b/packages/auth/.prettierrc.json deleted file mode 100644 index 7ca3a28..0000000 --- a/packages/auth/.prettierrc.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "arrowParens": "avoid", - "bracketSpacing": true, - "jsxBracketSameLine": false, - "jsxSingleQuote": false, - "quoteProps": "consistent", - "printWidth": 180, - "semi": true, - "singleQuote": true, - "tabWidth": 2, - "trailingComma": "all", - "useTabs": false -} diff --git a/packages/auth/README.md b/packages/auth/README.md deleted file mode 100644 index 4286897..0000000 --- a/packages/auth/README.md +++ /dev/null @@ -1,167 +0,0 @@ -Nostr-Login -=========== - -This library is a powerful `window.nostr` provider. - -``` - -``` - -Just add the above script to your HTML and -get a nice UI for users to login with Nostr Connect (nip46), with an extension, read-only login, -account switching, OAuth-like sign up, etc. Your app just talks to the `window.nostr`, the rest is handled by `nostr-login`. - -See it in action on [nostr.band](https://nostr.band). - -## Options - -You can set these attributes to the `script` tag to customize the behavior: -- `data-dark-mode` - `true`/`false`, default will use the browser's color theme -- `data-bunkers` - the comma-separated list of domain names of Nostr Connect (nip46) providers for sign up, i.e. `nsec.app,highlighter.com` -- `data-perms` - the comma-separated list of [permissions](https://github.com/nostr-protocol/nips/blob/master/46.md#requested-permissions) requested by the app over Nostr Connect, i.e. `sign_event:1,nip04_encrypt` -- `data-theme` - color themes, one of `default`, `ocean`, `lemonade`, `purple` -- `data-no-banner` - if `true`, do not show the `nostr-login` banner, will need to launch the modals using event dispatch, see below -- `data-methods` - comma-separated list of allowed auth methods, method names: `connect`, `extension`, `readOnly`, `local`, all allowed by default. -- `data-otp-request-url` - URL for requesting OTP code -- `data-otp-reply-url` - URL for replying with OTP code -- `data-title` - title for the welcome screen -- `data-description` - description for the welcome screen -- `data-start-screen` - screen shown by default (banner click, window.nostr.* call), options: `welcome`, `welcome-login`, `welcome-signup`, `signup`, `local-signup`, `login`, `otp`, `connect`, `login-bunker-url`, `login-read-only`, `connection-string`, `switch-account`, `import` -- `data-signup-relays` - comma-separated list of relays where nip65 event will be published on local signup -- `data-outbox-relays` - comma-separated list of relays that will be added to nip65 event on local signup -- `data-signup-nstart` - "true" to use start.njump.me instead of local signup -- `data-follow-npubs` - comma-separated list of npubs to follow if njump.me signup is used - -Example: -``` - -``` - -## Updating the UI - -Whenever user performs an auth-related action using `nostr-login`, a `nlAuth` event will be dispatched on the `document`, which you can listen -to in order to update your UI (show user profile, etc): - -``` -document.addEventListener('nlAuth', (e) => { - // type is login, signup or logout - if (e.detail.type === 'login' || e.detail.type === 'signup') { - onLogin(); // get pubkey with window.nostr and show user profile - } else { - onLogout() // clear local user data, hide profile info - } -}) -``` - -## Launching, logout, etc - -The `nostr-login` auth modals will be automatically launched whenever you -make a call to `window.nostr` if user isn't authed yet. However, you can also launch the auth flow by dispatching a custom `nlLaunch` event: - -``` -document.dispatchEvent(new CustomEvent('nlLaunch', { detail: 'welcome' })); -``` - -The `detail` event payload can be empty, or can be one of `welcome`, `signup`, `login`, `login-bunker-url`, `login-read-only`, `switch-account`. - -To trigger logout in the `nostr-login`, you can dispatch a `nlLogout` event: - -``` -document.dispatchEvent(new Event("nlLogout")); -``` - -To change dark mode in the `nostr-login`, you can dispatch a `nlDarkMode` event, with detail as `darkMode` boolean: - -``` -document.dispatchEvent(new CustomEvent("nlDarkMode", { detail: true })); -``` - -## Use as a package - -Install `nostr-login` package with `npm` and then: - -``` -import { init as initNostrLogin } from "nostr-login" - -// make sure this is called before any -// window.nostr calls are made -initNostrLogin({/*options*/}) - -``` - -Now the `window.nostr` will be initialized and on your first call -to it the auth flow will be launched if user isn't authed yet. - -You can also launch the auth flow yourself: - -``` -import { launch as launchNostrLoginDialog } from "nostr-login" - -// make sure init() was called - -// on your signup button click -function onSignupClick() { - // launch signup screen - launchNostrLoginDialog({ - startScreen: 'signup' - }) -} -``` - -### Next.js Fix for Server Side Rendering (SSR) - -`nostr-login` calls `document` which is unavailable for server-side rendering. You will have build errors. To fix this, you can import `nostr-login` on the client side in your component with a `useEffect` like this: - -```javascript - useEffect(() => { - import('nostr-login') - .then(async ({ init }) => { - init({ - // options - }) - }) - .catch((error) => console.log('Failed to load nostr-login', error)); - }, []); -``` -Note: even if your component has `"use client"` in the first line, this fix still may be necessary. - ---- - -API: -- `init(opts)` - set mapping of window.nostr to nostr-login -- `launch(startScreen)` - launch nostr-login UI -- `logout()` - drop the current nip46 connection - -Options: -- `theme` - same as `data-theme` above -- `startScreen` - same as `startScreen` for `nlLaunch` event above -- `bunkers` - same as `data-bunkers` above -- `devOverrideBunkerOrigin` - for testing, overrides the bunker origin for local setup -- `onAuth: (npub: string, options: NostrLoginAuthOptions)` - a callback to provide instead of listening to `nlAuth` event -- `perms` - same as `data-perms` above -- `darkMode` - same as `data-dark-mode` above -- `noBanner` - same as `data-no-banner` above -- `isSignInWithExtension` - `true` to bring the *Sign in with exception* button into main list of options, `false` to hide to the *Advanced*, default will behave as `true` if extension is detected. - -## OTP login - -If you supply both `data-otp-request-url` and `data-otp-reply-url` then "Login with DM" button will appear on the welcome screen. - -When user enters their nip05 or npub, a GET request is made to `[?&]pubkey=`. Server should send -a DM with one-time code to that pubkey and should return 200. - -After user enters the code, a GET request is made to `[?&]pubkey=&code=`. Server should check that code matches the pubkey and hasn't expired, and should return 200 status and an optional payload. Nostr-login will deliver the payload as `otpData` field in `nlAuth` event, and will save the payload in localstore and will deliver it again as `nlAuth` on page reload. - -The reply payload may be used to supply the session token. If token is sent by the server as a cookie then payload might be empty, otherwise the payload should be used by the app to extract the token and use it in future API calls to the server. - -## Examples - -* [Basic HTML Example](./examples/usage.html) - -## TODO - -- fetch bunker list using NIP-89 -- Amber support -- allow use without the UIs -- add timeout handling -- more at [issues](https://github.com/nostrband/nostr-login/issues) diff --git a/packages/auth/index.html b/packages/auth/index.html deleted file mode 100644 index 04365df..0000000 --- a/packages/auth/index.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - Modal Auth Demo - - - - - - - - - - - - diff --git a/packages/auth/package.json b/packages/auth/package.json deleted file mode 100644 index 3a9e621..0000000 --- a/packages/auth/package.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "nostr-login", - "version": "1.7.11", - "description": "", - "main": "./dist/index.esm.js", - "types": "./dist/index.d.ts", - "type": "module", - "scripts": { - "build": "rollup -c", - "format": "npx prettier --write src" - }, - "author": "a-fralou", - "dependencies": { - "@nostr-dev-kit/ndk": "^2.3.1", - "nostr-tools": "^1.17.0", - "tseep": "^1.2.1" - }, - "devDependencies": { - "@rollup/plugin-commonjs": "^25.0.7", - "@rollup/plugin-node-resolve": "^15.2.3", - "@rollup/plugin-terser": "^0.4.4", - "nostr-login-components": "^1.0.3", - "prettier": "^3.2.2", - "rollup": "^4.9.6", - "rollup-plugin-typescript2": "^0.36.0" - }, - "license": "MIT" -} diff --git a/packages/auth/rollup.config.js b/packages/auth/rollup.config.js deleted file mode 100644 index a13e0e3..0000000 --- a/packages/auth/rollup.config.js +++ /dev/null @@ -1,55 +0,0 @@ -import commonjs from '@rollup/plugin-commonjs'; -import resolve from '@rollup/plugin-node-resolve'; -import typescript from 'rollup-plugin-typescript2'; -import terser from '@rollup/plugin-terser'; - -export default [ - { - input: 'src/index.ts', - output: [ - { - file: 'dist/index.esm.js', - format: 'esm', - sourcemap: true, - }, - ], - plugins: [ - typescript({ - tsconfig: 'tsconfig.json', - }), - resolve({ - browser: true - }), - commonjs(), - terser({ - compress: { - toplevel: true, - } - }) - ], - }, - { - input: 'src/iife-module.ts', - output: [ - { - file: 'dist/unpkg.js', - format: 'iife', - } - ], - plugins: [ - typescript({ - tsconfig: 'tsconfig.json', - }), - resolve({ - browser: true - }), - commonjs(), - terser({ - compress: { - toplevel: true, - }, - }) - ], - } -]; - diff --git a/packages/auth/src/const/index.ts b/packages/auth/src/const/index.ts deleted file mode 100644 index 10b6ecf..0000000 --- a/packages/auth/src/const/index.ts +++ /dev/null @@ -1 +0,0 @@ -export const CALL_TIMEOUT = 5000; diff --git a/packages/auth/src/iife-module.ts b/packages/auth/src/iife-module.ts deleted file mode 100644 index ff2c87c..0000000 --- a/packages/auth/src/iife-module.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { init } from './index'; -import { NostrLoginOptions, StartScreens } from './types'; - -// wrap to hide local vars -(() => { - // currentScript only visible in global scope code, not event handlers - const cs = document.currentScript; - const start = async () => { - const options: NostrLoginOptions = {}; - - if (cs) { - const dm = cs.getAttribute('data-dark-mode'); - if (dm) options.darkMode = dm === 'true'; - - const bunkers = cs.getAttribute('data-bunkers'); - if (bunkers) options.bunkers = bunkers; - - const startScreen = cs.getAttribute('data-start-screen'); - if (startScreen) options.startScreen = startScreen as StartScreens; - - const perms = cs.getAttribute('data-perms'); - if (perms) options.perms = perms; - - const theme = cs.getAttribute('data-theme'); - if (theme) options.theme = theme; - - const noBanner = cs.getAttribute('data-no-banner'); - if (noBanner) options.noBanner = noBanner === 'true'; - - const localSignup = cs.getAttribute('data-local-signup'); - if (localSignup) options.localSignup = localSignup === 'true'; - - const signupNjump = cs.getAttribute('data-signup-nstart') || cs.getAttribute('data-signup-njump'); - if (signupNjump) options.signupNstart = signupNjump === 'true'; - - const followNpubs = cs.getAttribute('data-follow-npubs'); - if (followNpubs) options.followNpubs = followNpubs; - - const otpRequestUrl = cs.getAttribute('data-otp-request-url'); - if (otpRequestUrl) options.otpRequestUrl = otpRequestUrl; - - const otpReplyUrl = cs.getAttribute('data-otp-reply-url'); - if (otpReplyUrl) options.otpReplyUrl = otpReplyUrl; - - if (!!otpRequestUrl !== !!otpReplyUrl) console.warn('nostr-login: need request and reply urls for OTP auth'); - - const methods = cs.getAttribute('data-methods'); - if (methods) { - // @ts-ignore - options.methods = methods - .trim() - .split(',') - .filter(m => !!m); - } - - const title = cs.getAttribute('data-title'); - if (title) options.title = title; - - const description = cs.getAttribute('data-description'); - if (description) options.description = description; - - const signupRelays = cs.getAttribute('data-signup-relays'); - if (signupRelays) options.signupRelays = signupRelays; - - const outboxRelays = cs.getAttribute('data-outbox-relays'); - if (outboxRelays) options.outboxRelays = outboxRelays.split(','); - - const dev = cs.getAttribute('data-dev') === 'true'; - if (dev) options.dev = dev; - - const custom = cs.getAttribute('data-custom-nostr-connect') === 'true'; - if (custom) options.customNostrConnect = custom; - - console.log('nostr-login options', options); - } - - init(options); - }; - if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', start); - else start(); -})(); diff --git a/packages/auth/src/index.ts b/packages/auth/src/index.ts deleted file mode 100644 index 7c3fcbf..0000000 --- a/packages/auth/src/index.ts +++ /dev/null @@ -1,347 +0,0 @@ -import 'nostr-login-components'; -import { AuthNostrService, NostrExtensionService, Popup, NostrParams, Nostr, ProcessManager, BannerManager, ModalManager } from './modules'; -import { NostrLoginAuthOptions, NostrLoginOptions, StartScreens } from './types'; -import { localStorageGetAccounts, localStorageGetCurrent, localStorageGetRecents, localStorageSetItem } from './utils'; -import { Info } from 'nostr-login-components/dist/types/types'; -import { NostrObjectParams } from './modules/Nostr'; - -export class NostrLoginInitializer { - public extensionService: NostrExtensionService; - public params: NostrParams; - public authNostrService: AuthNostrService; - public nostr: Nostr; - public processManager: ProcessManager; - public popupManager: Popup; - public bannerManager: BannerManager; - public modalManager: ModalManager; - - private customLaunchCallback?: () => void; - - constructor() { - this.params = new NostrParams(); - this.processManager = new ProcessManager(); - this.popupManager = new Popup(); - this.bannerManager = new BannerManager(this.params); - this.authNostrService = new AuthNostrService(this.params); - this.extensionService = new NostrExtensionService(this.params); - this.modalManager = new ModalManager(this.params, this.authNostrService, this.extensionService); - - const nostrApi: NostrObjectParams = { - waitReady: async () => { - await this.authNostrService.waitReady(); - await this.modalManager.waitReady(); - }, - getUserInfo: () => this.params.userInfo, - getSigner: () => { - if (this.params.userInfo!.authMethod === 'readOnly') throw new Error('Read only'); - return this.params.userInfo!.authMethod === 'extension' ? this.extensionService.getExtension() : this.authNostrService; - }, - launch: () => { - return this.launch(); - }, - wait: cb => this.processManager.wait(cb), - }; - - this.nostr = new Nostr(nostrApi); - - this.processManager.on('onCallTimeout', () => { - this.bannerManager.onCallTimeout(); - }); - - this.processManager.on('onCallEnd', () => { - this.bannerManager.onCallEnd(); - this.modalManager.onCallEnd(); - }); - - this.processManager.on('onCallStart', () => { - this.bannerManager.onCallStart(); - }); - - this.authNostrService.on('onIframeUrl', url => { - this.modalManager.onIframeUrl(url); - }); - - this.authNostrService.on('iframeRestart', ({ iframeUrl }) => { - this.processManager.onIframeUrl(); - this.bannerManager.onIframeRestart(iframeUrl); - }); - - this.authNostrService.on('onAuthUrl', ({ url, iframeUrl, eventToAddAccount }) => { - this.processManager.onAuthUrl(); - - if (eventToAddAccount) { - this.modalManager.onAuthUrl(url); - return; - } - - if (this.params.userInfo) { - // show the 'Please confirm' banner - this.bannerManager.onAuthUrl(url, iframeUrl); - } else { - // if it fails we will either return 'failed' - // to the window.nostr caller, or show proper error - // in our modal - this.modalManager.onAuthUrl(url); - } - }); - - this.authNostrService.on('updateAccounts', () => { - this.updateAccounts(); - }); - - this.authNostrService.on('onUserInfo', info => { - this.bannerManager.onUserInfo(info); - }); - - this.modalManager.on('onAuthUrlClick', url => { - this.openPopup(url); - }); - - this.bannerManager.on('onIframeAuthUrlClick', url => { - this.modalManager.showIframeUrl(url); - }); - - this.modalManager.on('onSwitchAccount', async (info: Info) => { - this.switchAccount(info); - }); - - this.modalManager.on('onLogoutBanner', async (info: Info) => { - logout(); - }); - - this.bannerManager.on('onConfirmLogout', async () => { - // @ts-ignore - this.launch('confirm-logout'); - }); - - this.modalManager.on('updateAccounts', () => { - this.updateAccounts(); - }); - - this.bannerManager.on('logout', () => { - logout(); - }); - - this.bannerManager.on('onAuthUrlClick', url => { - this.openPopup(url); - }); - - this.bannerManager.on('onSwitchAccount', async (info: Info) => { - this.switchAccount(info); - }); - - this.bannerManager.on('import', () => { - this.launch('import'); - }); - - this.extensionService.on('extensionLogin', (pubkey: string) => { - this.authNostrService.setExtension(pubkey); - }); - - this.extensionService.on('extensionLogout', () => { - logout(); - }); - - this.bannerManager.on('launch', (startScreen?: StartScreens) => { - this.launch(startScreen); - }); - } - - private openPopup(url: string) { - this.popupManager.openPopup(url); - } - - private async switchAccount(info: Info, signup = false) { - console.log('nostr login switch to info', info); - - // make sure extension is unlinked - this.extensionService.unsetExtension(this.nostr); - - if (info.authMethod === 'readOnly') { - this.authNostrService.setReadOnly(info.pubkey); - } else if (info.authMethod === 'otp') { - this.authNostrService.setOTP(info.pubkey, info.otpData || ''); - } else if (info.authMethod === 'local' && info.sk) { - this.authNostrService.setLocal(info, signup); - } else if (info.authMethod === 'extension') { - // trySetExtensionForPubkey will check if - // we still have the extension and it's the same pubkey - await this.extensionService.trySetExtensionForPubkey(info.pubkey); - } else if (info.authMethod === 'connect' && info.sk && info.relays && info.relays[0]) { - this.authNostrService.setConnect(info); - } else { - throw new Error('Bad auth info'); - } - } - - private updateAccounts() { - const accounts = localStorageGetAccounts(); - const recents = localStorageGetRecents(); - this.bannerManager.onUpdateAccounts(accounts); - this.modalManager.onUpdateAccounts(accounts, recents); - } - - public async launchCustomNostrConnect() { - try { - if (this.authNostrService.isAuthing()) this.authNostrService.cancelNostrConnect(); - - const customLaunchPromise = new Promise(ok => (this.customLaunchCallback = ok)); - await this.authNostrService.startAuth(); - await this.authNostrService.sendNeedAuth(); - - try { - await this.authNostrService.nostrConnect(); - await this.authNostrService.endAuth(); - } catch (e) { - // if client manually launches the UI we'll - // have cancelled error from the nostrConnect call, - // and that's when we should block on the customLaunchPromise - if (e === 'cancelled') await customLaunchPromise; - } - } catch (e) { - console.error('launchCustomNostrConnect', e); - } - } - - private fulfillCustomLaunchPromise() { - if (this.customLaunchCallback) { - const cb = this.customLaunchCallback; - this.customLaunchCallback = undefined; - cb(); - } - } - - public launch = async (startScreen?: StartScreens | 'default') => { - if (!startScreen) { - if (this.params.optionsModal.customNostrConnect) { - return this.launchCustomNostrConnect(); - } - } - - const recent = localStorageGetRecents(); - const accounts = localStorageGetAccounts(); - - const options = { ...this.params.optionsModal }; - if (startScreen && startScreen !== 'default') options.startScreen = startScreen; - else if (Boolean(recent?.length) || Boolean(accounts?.length)) { - options.startScreen = 'switch-account'; - } - - // if we're being manually called in the middle of customNostrConnect - // flow then we'll reset the current auth session and launch - // our manual flow and then release the customNostrConnect session - // as if it finished properly - if (this.customLaunchCallback) this.authNostrService.cancelNostrConnect(); - try { - await this.modalManager.launch(options); - - // if custom launch was interrupted by manual - // launch then we unlock the custom launch to make - // it proceed - this.fulfillCustomLaunchPromise(); - } catch (e) { - // don't throw if cancelled - console.log('nostr-login failed', e); - } - }; - - public init = async (opt: NostrLoginOptions) => { - // watch for extension trying to overwrite our window.nostr - this.extensionService.startCheckingExtension(this.nostr); - - // set ourselves as nostr - - // @ts-ignore - window.nostr = this.nostr; - - // connect launching of our modals to nl-button elements - this.modalManager.connectModals(opt); - - // launch - this.bannerManager.launchAuthBanner(opt); - - // store options - if (opt) { - this.params.optionsModal = { ...opt }; - } - - try { - // read conf from localstore - const info = localStorageGetCurrent(); - - // have current session? - if (info) { - // wtf? - if (!info.pubkey) throw new Error('Bad stored info'); - - // switch to it - await this.switchAccount(info); - } - } catch (e) { - console.log('nostr login init error', e); - - await logout(); - } - - // ensure current state - this.updateAccounts(); - }; - - public logout = async () => { - // replace back - this.extensionService.unsetExtension(this.nostr); - - await this.authNostrService.logout(); - }; - - public setDarkMode = (dark: boolean) => { - localStorageSetItem('nl-dark-mode', `${dark}`); - this.bannerManager.onDarkMode(dark); - this.modalManager.onDarkMode(dark); - }; - - public setAuth = async (o: NostrLoginAuthOptions) => { - if (!o.type) throw new Error('Invalid auth event'); - if (o.type !== 'login' && o.type !== 'logout' && o.type !== 'signup') throw new Error('Invalid auth event'); - if (o.method && o.method !== 'connect' && o.method !== 'extension' && o.method !== 'local' && o.method !== 'otp' && o.method !== 'readOnly') - throw new Error('Invalid auth event'); - - if (o.type === 'logout') return this.logout(); - - if (!o.method || !o.pubkey) throw new Error('Invalid pubkey'); - - const info: Info = { - authMethod: o.method, - pubkey: o.pubkey, - relays: o.relays, - sk: o.localNsec, - otpData: o.otpData, - name: o.name, - }; - await this.switchAccount(info, o.type === 'signup'); - }; - - public cancelNeedAuth = () => { - console.log("cancelNeedAuth"); - this.fulfillCustomLaunchPromise(); - this.authNostrService.cancelNostrConnect(); - }; -} - -const initializer = new NostrLoginInitializer(); - -export const { init, launch, logout, setDarkMode, setAuth, cancelNeedAuth } = initializer; - -document.addEventListener('nlLogout', logout); -document.addEventListener('nlLaunch', (event: any) => { - launch(event.detail || ''); -}); -document.addEventListener('nlNeedAuthCancel', () => { - cancelNeedAuth(); -}); -document.addEventListener('nlDarkMode', (event: any) => { - setDarkMode(!!event.detail); -}); -document.addEventListener('nlSetAuth', (event: any) => { - setAuth(event.detail as NostrLoginAuthOptions); -}); diff --git a/packages/auth/src/modules/AuthNostrService.ts b/packages/auth/src/modules/AuthNostrService.ts deleted file mode 100644 index 0ac3302..0000000 --- a/packages/auth/src/modules/AuthNostrService.ts +++ /dev/null @@ -1,718 +0,0 @@ -import { localStorageAddAccount, bunkerUrlToInfo, isBunkerUrl, fetchProfile, getBunkerUrl, localStorageRemoveCurrentAccount, createProfile, getIcon } from '../utils'; -import { ConnectionString, Info } from 'nostr-login-components/dist/types/types'; -import { generatePrivateKey, getEventHash, getPublicKey, nip19 } from 'nostr-tools'; -import { NostrLoginAuthOptions, Response } from '../types'; -import NDK, { NDKEvent, NDKNip46Signer, NDKRpcResponse, NDKUser, NostrEvent } from '@nostr-dev-kit/ndk'; -import { NostrParams } from './'; -import { EventEmitter } from 'tseep'; -import { Signer } from './Nostr'; -import { Nip44 } from '../utils/nip44'; -import { IframeNostrRpc, Nip46Signer, ReadyListener } from './Nip46'; -import { PrivateKeySigner } from './Signer'; - -const OUTBOX_RELAYS = ['wss://user.kindpag.es', 'wss://purplepag.es', 'wss://relay.nos.social']; -const DEFAULT_NOSTRCONNECT_RELAY = 'wss://relay.nsec.app/'; -const NOSTRCONNECT_APPS: ConnectionString[] = [ - { - name: 'Nsec.app', - domain: 'nsec.app', - canImport: true, - img: 'https://nsec.app/assets/favicon.ico', - link: 'https://use.nsec.app/', - relay: 'wss://relay.nsec.app/', - }, - { - name: 'Amber', - img: 'https://raw.githubusercontent.com/greenart7c3/Amber/refs/heads/master/assets/android-icon.svg', - link: '', - relay: 'wss://relay.nsec.app/', - }, - { - name: 'Other key stores', - img: '', - link: '', - relay: 'wss://relay.nsec.app/', - }, -]; - -class AuthNostrService extends EventEmitter implements Signer { - private ndk: NDK; - private profileNdk: NDK; - private signer: Nip46Signer | null = null; - private localSigner: PrivateKeySigner | null = null; - private params: NostrParams; - private signerPromise?: Promise; - private signerErrCallback?: (err: string) => void; - private readyPromise?: Promise; - private readyCallback?: () => void; - private nip44Codec = new Nip44(); - private nostrConnectKey: string = ''; - private nostrConnectSecret: string = ''; - private iframe?: HTMLIFrameElement; - private starterReady?: ReadyListener; - - nip04: { - encrypt: (pubkey: string, plaintext: string) => Promise; - decrypt: (pubkey: string, ciphertext: string) => Promise; - }; - nip44: { - encrypt: (pubkey: string, plaintext: string) => Promise; - decrypt: (pubkey: string, ciphertext: string) => Promise; - }; - - constructor(params: NostrParams) { - super(); - this.params = params; - this.ndk = new NDK({ - enableOutboxModel: false, - }); - - this.profileNdk = new NDK({ - enableOutboxModel: true, - explicitRelayUrls: OUTBOX_RELAYS, - }); - this.profileNdk.connect(); - - this.nip04 = { - encrypt: this.encrypt04.bind(this), - decrypt: this.decrypt04.bind(this), - }; - this.nip44 = { - encrypt: this.encrypt44.bind(this), - decrypt: this.decrypt44.bind(this), - }; - } - - public isIframe() { - return !!this.iframe; - } - - public async waitReady() { - if (this.signerPromise) { - try { - await this.signerPromise; - } catch {} - } - - if (this.readyPromise) { - try { - await this.readyPromise; - } catch {} - } - } - - public cancelNostrConnect() { - this.releaseSigner(); - this.resetAuth(); - } - - public async nostrConnect( - relay?: string, - { - domain = '', - link = '', - iframeUrl = '', - importConnect = false, - }: { - domain?: string; - link?: string; - importConnect?: boolean; - iframeUrl?: string; - } = {}, - ) { - relay = relay || DEFAULT_NOSTRCONNECT_RELAY; - - const info: Info = { - authMethod: 'connect', - pubkey: '', // unknown yet! - signerPubkey: '', // unknown too! - sk: this.nostrConnectKey, - domain: domain, - relays: [relay], - iframeUrl, - }; - - console.log('nostrconnect info', info, link); - - // non-iframe flow - if (link && !iframeUrl) window.open(link, '_blank', 'width=400,height=700'); - - // init nip46 signer - await this.initSigner(info, { listen: true }); - - // signer learns the remote pubkey - if (!info.pubkey || !info.signerPubkey) throw new Error('Bad remote pubkey'); - - info.bunkerUrl = `bunker://${info.signerPubkey}?relay=${relay}`; - - // callback - if (!importConnect) this.onAuth('login', info); - - return info; - } - - public async createNostrConnect(relay?: string) { - this.nostrConnectKey = generatePrivateKey(); - this.nostrConnectSecret = Math.random().toString(36).substring(7); - - const pubkey = getPublicKey(this.nostrConnectKey); - const meta = { - name: encodeURIComponent(document.location.host), - url: encodeURIComponent(document.location.origin), - icon: encodeURIComponent(await getIcon()), - perms: encodeURIComponent(this.params.optionsModal.perms || ''), - }; - - return `nostrconnect://${pubkey}?image=${meta.icon}&url=${meta.url}&name=${meta.name}&perms=${meta.perms}&secret=${this.nostrConnectSecret}${relay ? `&relay=${relay}` : ''}`; - } - - public async getNostrConnectServices(): Promise<[string, ConnectionString[]]> { - const nostrconnect = await this.createNostrConnect(); - - // copy defaults - const apps = NOSTRCONNECT_APPS.map(a => ({ ...a })); - // if (this.params.optionsModal.dev) { - // apps.push({ - // name: 'Dev.Nsec.app', - // domain: 'new.nsec.app', - // canImport: true, - // img: 'https://new.nsec.app/assets/favicon.ico', - // link: 'https://dev.nsec.app/', - // relay: 'wss://relay.nsec.app/', - // }); - // } - - for (const a of apps) { - let relay = DEFAULT_NOSTRCONNECT_RELAY; - if (a.link.startsWith('https://')) { - let domain = a.domain || new URL(a.link).hostname; - try { - const info = await (await fetch(`https://${domain}/.well-known/nostr.json`)).json(); - const pubkey = info.names['_']; - const relays = info.nip46[pubkey] as string[]; - if (relays && relays.length) relay = relays[0]; - a.iframeUrl = info.nip46.iframe_url || ''; - } catch (e) { - console.log('Bad app info', e, a); - } - } - const nc = nostrconnect + '&relay=' + relay; - if (a.iframeUrl) { - // pass plain nc url for iframe-based flow - a.link = nc; - } else { - // we will open popup ourselves - a.link = a.link.replace('', nc); - } - } - - return [nostrconnect, apps]; - } - - public async localSignup(name: string, sk?: string) { - const signup = !sk; - sk = sk || generatePrivateKey(); - const pubkey = getPublicKey(sk); - const info: Info = { - pubkey, - sk, - name, - authMethod: 'local', - }; - console.log(`localSignup name: ${name}`); - await this.setLocal(info, signup); - } - - public async setLocal(info: Info, signup?: boolean) { - this.releaseSigner(); - this.localSigner = new PrivateKeySigner(info.sk!); - - if (signup) await createProfile(info, this.profileNdk, this.localSigner, this.params.optionsModal.signupRelays, this.params.optionsModal.outboxRelays); - - this.onAuth(signup ? 'signup' : 'login', info); - } - - public prepareImportUrl(url: string) { - // for OTP we choose interactive import - if (this.params.userInfo?.authMethod === 'otp') return url + '&import=true'; - - // for local we export our existing key - if (!this.localSigner || this.params.userInfo?.authMethod !== 'local') throw new Error('Most be local keys'); - return url + '#import=' + nip19.nsecEncode(this.localSigner.privateKey!); - } - - public async importAndConnect(cs: ConnectionString) { - const { relay, domain, link, iframeUrl } = cs; - if (!domain) throw new Error('Domain required'); - - const info = await this.nostrConnect(relay, { domain, link, importConnect: true, iframeUrl }); - - // logout to remove local keys from storage - // but keep the connect signer - await this.logout(/*keepSigner*/ true); - - // release local one - this.localSigner = null; - - // notify app that we've switched to 'connect' keys - this.onAuth('login', info); - } - - public setReadOnly(pubkey: string) { - const info: Info = { pubkey, authMethod: 'readOnly' }; - this.onAuth('login', info); - } - - public setExtension(pubkey: string) { - const info: Info = { pubkey, authMethod: 'extension' }; - this.onAuth('login', info); - } - - public setOTP(pubkey: string, data: string) { - const info: Info = { pubkey, authMethod: 'otp', otpData: data }; - this.onAuth('login', info); - } - - public async setConnect(info: Info) { - this.releaseSigner(); - await this.startAuth(); - await this.initSigner(info); - this.onAuth('login', info); - await this.endAuth(); - } - - public async createAccount(nip05: string) { - const [name, domain] = nip05.split('@'); - - // bunker's own url - const bunkerUrl = await getBunkerUrl(`_@${domain}`, this.params.optionsModal); - console.log("create account bunker's url", bunkerUrl); - - // parse bunker url and generate local nsec - const info = bunkerUrlToInfo(bunkerUrl); - if (!info.signerPubkey) throw new Error('Bad bunker url'); - - const eventToAddAccount = Boolean(this.params.userInfo); - - // init signer to talk to the bunker (not the user!) - await this.initSigner(info, { eventToAddAccount }); - - const userPubkey = await this.signer!.createAccount2({ bunkerPubkey: info.signerPubkey!, name, domain, perms: this.params.optionsModal.perms }); - - return { - bunkerUrl: `bunker://${userPubkey}?relay=${info.relays?.[0]}`, - sk: info.sk, // reuse the same local key - }; - } - - private releaseSigner() { - this.signer = null; - this.signerErrCallback?.('cancelled'); - this.localSigner = null; - - // disconnect from signer relays - for (const r of this.ndk.pool.relays.keys()) { - this.ndk.pool.removeRelay(r); - } - } - - public async logout(keepSigner = false) { - if (!keepSigner) this.releaseSigner(); - - // move current to recent - localStorageRemoveCurrentAccount(); - - // notify everyone - this.onAuth('logout'); - - this.emit('updateAccounts'); - } - - private setUserInfo(userInfo: Info | null) { - this.params.userInfo = userInfo; - this.emit('onUserInfo', userInfo); - - if (userInfo) { - localStorageAddAccount(userInfo); - this.emit('updateAccounts'); - } - } - - public exportKeys() { - if (!this.params.userInfo) return ''; - if (this.params.userInfo.authMethod !== 'local') return ''; - return nip19.nsecEncode(this.params.userInfo.sk!); - } - - private onAuth(type: 'login' | 'signup' | 'logout', info: Info | null = null) { - if (type !== 'logout' && !info) throw new Error('No user info in onAuth'); - - // make sure we emulate logout first - if (info && this.params.userInfo && (info.pubkey !== this.params.userInfo.pubkey || info.authMethod !== this.params.userInfo.authMethod)) { - const event = new CustomEvent('nlAuth', { detail: { type: 'logout' } }); - console.log('nostr-login auth', event.detail); - document.dispatchEvent(event) - } - - this.setUserInfo(info); - - if (info) { - // async profile fetch - fetchProfile(info, this.profileNdk).then(p => { - if (this.params.userInfo !== info) return; - - const userInfo = { - ...this.params.userInfo, - picture: p?.image || p?.picture, - name: p?.name || p?.displayName || p?.nip05 || nip19.npubEncode(info.pubkey), - // NOTE: do not overwrite info.nip05 with the one from profile! - // info.nip05 refers to nip46 provider, - // profile.nip05 is just a fancy name that user has chosen - // nip05: p?.nip05 - }; - - this.setUserInfo(userInfo); - }); - } - - try { - const npub = info ? nip19.npubEncode(info.pubkey) : ''; - - const options: NostrLoginAuthOptions = { - type, - }; - - if (type === 'logout') { - // reset - if (this.iframe) this.iframe.remove(); - this.iframe = undefined; - } else { - options.pubkey = info!.pubkey; - options.name = info!.name; - - if (info!.sk) { - options.localNsec = nip19.nsecEncode(info!.sk); - } - - if (info!.relays) { - options.relays = info!.relays; - } - - if (info!.otpData) { - options.otpData = info!.otpData; - } - - options.method = info!.authMethod || 'connect'; - } - - const event = new CustomEvent('nlAuth', { detail: options }); - console.log('nostr-login auth', options); - document.dispatchEvent(event); - - if (this.params.optionsModal.onAuth) { - this.params.optionsModal.onAuth(npub, options); - } - } catch (e) { - console.log('onAuth error', e); - } - } - - private async createIframe(iframeUrl?: string) { - if (!iframeUrl) return undefined; - - // ensure iframe - const url = new URL(iframeUrl); - const domain = url.hostname; - let iframe: HTMLIFrameElement | undefined; - - // one iframe per domain - const did = domain.replaceAll('.', '-'); - const id = '__nostr-login-worker-iframe-' + did; - iframe = document.querySelector(`#${id}`) as HTMLIFrameElement; - console.log('iframe', id, iframe); - if (!iframe) { - iframe = document.createElement('iframe'); - iframe.setAttribute('width', '0'); - iframe.setAttribute('height', '0'); - iframe.setAttribute('border', '0'); - iframe.style.display = 'none'; - // iframe.setAttribute('sandbox', 'allow-forms allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts'); - iframe.id = id; - document.body.append(iframe); - } - - // wait until loaded - iframe.setAttribute('src', iframeUrl); - - // we start listening right now to avoid races - // with 'load' event below - const ready = new ReadyListener(['workerReady', 'workerError'], url.origin); - - await new Promise(ok => { - iframe!.addEventListener('load', ok); - }); - - // now make sure the iframe is ready, - // timeout timer starts here - const r = await ready.wait(); - - // FIXME wait until the iframe is ready to accept requests, - // maybe it should send us some message? - - console.log('nostr-login iframe ready', iframeUrl, r); - - return { iframe, port: r[1] as MessagePort }; - } - - // private async getIframeUrl(domain?: string) { - // if (!domain) return ''; - // try { - // const r = await fetch(`https://${domain}/.well-known/nostr.json`); - // const data = await r.json(); - // return data.nip46?.iframe_url || ''; - // } catch (e) { - // console.log('failed to fetch iframe url', e, domain); - // return ''; - // } - // } - - public async sendNeedAuth() { - const [nostrconnect] = await this.getNostrConnectServices(); - const event = new CustomEvent('nlNeedAuth', { detail: { nostrconnect } }); - console.log('nostr-login need auth', nostrconnect); - document.dispatchEvent(event); - } - - public isAuthing() { - return !!this.readyCallback; - } - - public async startAuth() { - console.log("startAuth"); - if (this.readyCallback) throw new Error('Already started'); - - // start the new promise - this.readyPromise = new Promise(ok => (this.readyCallback = ok)); - } - - public async endAuth() { - console.log('endAuth', this.params.userInfo); - if (this.params.userInfo && this.params.userInfo.iframeUrl) { - // create iframe - const { iframe, port } = (await this.createIframe(this.params.userInfo.iframeUrl)) || {}; - this.iframe = iframe; - if (!this.iframe || !port) return; - - // assign iframe to RPC object - (this.signer!.rpc as IframeNostrRpc).setWorkerIframePort(port); - } - - this.readyCallback!(); - this.readyCallback = undefined; - } - - public resetAuth() { - if (this.readyCallback) this.readyCallback(); - this.readyCallback = undefined; - } - - private async listen(info: Info) { - if (!info.iframeUrl) return this.signer!.listen(this.nostrConnectSecret); - const r = await this.starterReady!.wait(); - if (r[0] === 'starterError') throw new Error(r[1]); - return this.signer!.setListenReply(r[1], this.nostrConnectSecret); - } - - public async connect(info: Info, perms?: string) { - return this.signer!.connect(info.token, perms); - } - - public async initSigner(info: Info, { listen = false, connect = false, eventToAddAccount = false } = {}) { - // mutex - if (this.signerPromise) { - try { - await this.signerPromise; - } catch {} - } - - // we remove support for iframe from nip05 and bunker-url methods, - // only nostrconnect flow will use it. - // info.iframeUrl = info.iframeUrl || (await this.getIframeUrl(info.domain)); - console.log('initSigner info', info); - - // start listening for the ready signal - const iframeOrigin = info.iframeUrl ? new URL(info.iframeUrl!).origin : undefined; - if (iframeOrigin) this.starterReady = new ReadyListener(['starterDone', 'starterError'], iframeOrigin); - - // notify modals so they could show the starter iframe, - // FIXME shouldn't this come from nostrconnect service list? - this.emit('onIframeUrl', info.iframeUrl); - - this.signerPromise = new Promise(async (ok, err) => { - this.signerErrCallback = err; - try { - // pre-connect if we're creating the connection (listen|connect) or - // not iframe mode - if (info.relays && !info.iframeUrl) { - for (const r of info.relays) { - this.ndk.addExplicitRelay(r, undefined); - } - } - - // wait until we connect, otherwise - // signer won't start properly - await this.ndk.connect(); - - // create and prepare the signer - const localSigner = new PrivateKeySigner(info.sk!); - this.signer = new Nip46Signer(this.ndk, localSigner, info.signerPubkey!, iframeOrigin); - - // we should notify the banner the same way as - // the onAuthUrl does - this.signer.on(`iframeRestart`, async () => { - const iframeUrl = info.iframeUrl + (info.iframeUrl!.includes('?') ? '&' : '?') + 'pubkey=' + info.pubkey + '&rebind=' + localSigner.pubkey; - this.emit('iframeRestart', { pubkey: info.pubkey, iframeUrl }); - }); - - // OAuth flow - // if (!listen) { - this.signer.on('authUrl', (url: string) => { - console.log('nostr login auth url', url); - - // notify our UI - this.emit('onAuthUrl', { url, iframeUrl: info.iframeUrl, eventToAddAccount }); - }); - // } - - if (listen) { - // nostrconnect: flow - // wait for the incoming message from signer - await this.listen(info); - } else if (connect) { - // bunker: flow - // send 'connect' message to signer - await this.connect(info, this.params.optionsModal.perms); - } else { - // provide saved pubkey as a hint - await this.signer!.initUserPubkey(info.pubkey); - } - - // ensure, we're using it in callbacks above - // and expect info to be valid after this call - info.pubkey = this.signer!.userPubkey; - // learned after nostrconnect flow - info.signerPubkey = this.signer!.remotePubkey; - - ok(); - } catch (e) { - console.log('initSigner failure', e); - // make sure signer isn't set - this.signer = null; - err(e); - } - }); - - return this.signerPromise; - } - - public async authNip46( - type: 'login' | 'signup', - { name, bunkerUrl, sk = '', domain = '', iframeUrl = '' }: { name: string; bunkerUrl: string; sk?: string; domain?: string; iframeUrl?: string }, - ) { - try { - const info = bunkerUrlToInfo(bunkerUrl, sk); - if (isBunkerUrl(name)) info.bunkerUrl = name; - else { - info.nip05 = name; - info.domain = name.split('@')[1]; - } - if (domain) info.domain = domain; - if (iframeUrl) info.iframeUrl = iframeUrl; - - // console.log('nostr login auth info', info); - if (!info.signerPubkey || !info.sk || !info.relays?.[0]) { - throw new Error(`Bad bunker url ${bunkerUrl}`); - } - - const eventToAddAccount = Boolean(this.params.userInfo); - console.log('authNip46', type, info); - - // updates the info - await this.initSigner(info, { connect: true, eventToAddAccount }); - - // callback - this.onAuth(type, info); - } catch (e) { - console.log('nostr login auth failed', e); - // make ure it's closed - // this.popupManager.closePopup(); - throw e; - } - } - - public async signEvent(event: any) { - if (this.localSigner) { - event.pubkey = getPublicKey(this.localSigner.privateKey!); - event.id = getEventHash(event); - event.sig = await this.localSigner.sign(event); - } else { - event.pubkey = this.signer?.remotePubkey; - event.id = getEventHash(event); - event.sig = await this.signer?.sign(event); - } - console.log('signed', { event }); - return event; - } - - private async codec_call(method: string, pubkey: string, param: string) { - return new Promise((resolve, reject) => { - this.signer!.rpc.sendRequest(this.signer!.remotePubkey!, method, [pubkey, param], 24133, (response: NDKRpcResponse) => { - if (!response.error) { - resolve(response.result); - } else { - reject(response.error); - } - }); - }); - } - - public async encrypt04(pubkey: string, plaintext: string) { - if (this.localSigner) { - return this.localSigner.encrypt(new NDKUser({ pubkey }), plaintext); - } else { - return this.signer!.encrypt(new NDKUser({ pubkey }), plaintext); - } - } - - public async decrypt04(pubkey: string, ciphertext: string) { - if (this.localSigner) { - return this.localSigner.decrypt(new NDKUser({ pubkey }), ciphertext); - } else { - // decrypt is broken in ndk v2.3.1, and latest - // ndk v2.8.1 doesn't allow to override connect easily, - // so we reimplement and fix decrypt here as a temporary fix - - return this.codec_call('nip04_decrypt', pubkey, ciphertext); - } - } - - public async encrypt44(pubkey: string, plaintext: string) { - if (this.localSigner) { - return this.nip44Codec.encrypt(this.localSigner.privateKey!, pubkey, plaintext); - } else { - // no support of nip44 in ndk yet - return this.codec_call('nip44_encrypt', pubkey, plaintext); - } - } - - public async decrypt44(pubkey: string, ciphertext: string) { - if (this.localSigner) { - return this.nip44Codec.decrypt(this.localSigner.privateKey!, pubkey, ciphertext); - } else { - // no support of nip44 in ndk yet - return this.codec_call('nip44_decrypt', pubkey, ciphertext); - } - } -} - -export default AuthNostrService; diff --git a/packages/auth/src/modules/BannerManager.ts b/packages/auth/src/modules/BannerManager.ts deleted file mode 100644 index 8d9d3de..0000000 --- a/packages/auth/src/modules/BannerManager.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { NostrLoginOptions, TypeBanner } from '../types'; -import { NostrParams } from '.'; -import { Info } from 'nostr-login-components/dist/types/types'; -import { EventEmitter } from 'tseep'; -import { getDarkMode } from '../utils'; -import { ReadyListener } from './Nip46'; - -class BannerManager extends EventEmitter { - private banner: TypeBanner | null = null; - private iframeReady?: ReadyListener; - - private params: NostrParams; - - constructor(params: NostrParams) { - super(); - this.params = params; - } - - public onAuthUrl(url: string, iframeUrl: string) { - if (this.banner) { - if (url) - this.banner.notify = { - mode: iframeUrl ? 'iframeAuthUrl' : 'authUrl', - url, - }; - else - this.banner.notify = { - mode: '', - }; - } - } - - public onIframeRestart(iframeUrl: string) { - if (this.banner) { - this.iframeReady = new ReadyListener(['rebinderDone', 'rebinderError'], new URL(iframeUrl).origin); - this.banner.notify = { - mode: 'rebind', - url: iframeUrl, - }; - } - } - - public onUserInfo(info: Info | null) { - if (this.banner) { - this.banner.userInfo = info; - } - } - - public onCallTimeout() { - if (this.banner) { - this.banner.notify = { - mode: 'timeout', - }; - } - } - - public onCallStart() { - if (this.banner) { - this.banner.isLoading = true; - } - } - - public async onCallEnd() { - if (this.banner) { - if (this.iframeReady) { - await this.iframeReady.wait(); - this.iframeReady = undefined; - } - this.banner.isLoading = false; - this.banner.notify = { mode: '' }; - } - } - - public onUpdateAccounts(accounts: Info[]) { - if (this.banner) { - this.banner.accounts = accounts; - } - } - - public onDarkMode(dark: boolean) { - if (this.banner) this.banner.darkMode = dark; - } - - public launchAuthBanner(opt: NostrLoginOptions) { - this.banner = document.createElement('nl-banner'); - - this.banner.setAttribute('dark-mode', String(getDarkMode(opt))); - - if (opt.theme) this.banner.setAttribute('theme', opt.theme); - if (opt.noBanner) this.banner.setAttribute('hidden-mode', 'true'); - - this.banner.addEventListener('handleLoginBanner', (event: any) => { - this.emit('launch', event.detail); - }); - - this.banner.addEventListener('handleConfirmLogout', () => { - this.emit('onConfirmLogout'); - }); - - this.banner.addEventListener('handleLogoutBanner', async () => { - this.emit('logout'); - }); - - this.banner.addEventListener('handleImportModal', (event: any) => { - this.emit('import'); - }); - - this.banner.addEventListener('handleNotifyConfirmBanner', (event: any) => { - this.emit('onAuthUrlClick', event.detail); - }); - - this.banner.addEventListener('handleNotifyConfirmBannerIframe', (event: any) => { - this.emit('onIframeAuthUrlClick', event.detail); - }); - - this.banner.addEventListener('handleSwitchAccount', (event: any) => { - this.emit('onSwitchAccount', event.detail); - }); - - this.banner.addEventListener('handleOpenWelcomeModal', () => { - this.emit('launch'); - - if (this.banner) { - this.banner.isOpen = false; - } - }); - - // this.banner.addEventListener('handleRetryConfirmBanner', () => { - // const url = this.listNotifies.pop(); - // // FIXME go to nip05 domain? - // if (!url) { - // return; - // } - - // if (this.banner) { - // this.banner.listNotifies = this.listNotifies; - // } - - // this.emit('onAuthUrlClick', url); - // }); - - document.body.appendChild(this.banner); - } -} - -export default BannerManager; diff --git a/packages/auth/src/modules/ModalManager.ts b/packages/auth/src/modules/ModalManager.ts deleted file mode 100644 index acc1362..0000000 --- a/packages/auth/src/modules/ModalManager.ts +++ /dev/null @@ -1,635 +0,0 @@ -import { NostrLoginOptions, StartScreens, TypeModal } from '../types'; -import { checkNip05, getBunkerUrl, getDarkMode, localStorageRemoveRecent, localStorageSetItem, prepareSignupRelays } from '../utils'; -import { AuthNostrService, NostrExtensionService, NostrParams } from '.'; -import { EventEmitter } from 'tseep'; -import { ConnectionString, Info, RecentType } from 'nostr-login-components/dist/types/types'; -import { nip19 } from 'nostr-tools'; -import { setDarkMode } from '..'; - -class ModalManager extends EventEmitter { - private modal: TypeModal | null = null; - private params: NostrParams; - private extensionService: NostrExtensionService; - private authNostrService: AuthNostrService; - private launcherPromise?: Promise; - private accounts: Info[] = []; - private recents: RecentType[] = []; - private opt?: NostrLoginOptions; - - constructor(params: NostrParams, authNostrService: AuthNostrService, extensionManager: NostrExtensionService) { - super(); - this.params = params; - this.extensionService = extensionManager; - this.authNostrService = authNostrService; - } - - public async waitReady() { - if (this.launcherPromise) { - try { - await this.launcherPromise; - } catch {} - this.launcherPromise = undefined; - } - } - - public async launch(opt: NostrLoginOptions) { - console.log('nostr-login launch', opt); - // mutex - if (this.launcherPromise) await this.waitReady(); - - // hmm?! - if (this.authNostrService.isAuthing()) this.authNostrService.resetAuth(); - - this.opt = opt; - - const dialog = document.createElement('dialog'); - this.modal = document.createElement('nl-auth'); - this.modal.accounts = this.accounts; - this.modal.recents = this.recents; - - this.modal.setAttribute('dark-mode', String(getDarkMode(opt))); - - if (opt.theme) { - this.modal.setAttribute('theme', opt.theme); - } - - if (opt.startScreen) { - this.modal.setAttribute('start-screen', opt.startScreen); - } - - if (opt.bunkers) { - this.modal.setAttribute('bunkers', opt.bunkers); - } else { - let bunkers = 'nsec.app,highlighter.com'; - // if (opt.dev) bunkers += ',new.nsec.app'; - this.modal.setAttribute('bunkers', bunkers); - } - - if (opt.methods !== undefined) { - this.modal.authMethods = opt.methods; - } - - if (opt.localSignup !== undefined) { - this.modal.localSignup = opt.localSignup; - } - - if (opt.signupNstart !== undefined) { - this.modal.signupNjump = opt.signupNstart; - } - - if (opt.title) { - this.modal.welcomeTitle = opt.title; - } - - if (opt.description) { - this.modal.welcomeDescription = opt.description; - } - - this.modal.hasExtension = this.extensionService.hasExtension(); - this.modal.hasOTP = !!opt.otpRequestUrl && !!opt.otpReplyUrl; - - this.modal.isLoadingExtension = false; - this.modal.isLoading = false; - - [this.modal.connectionString, this.modal.connectionStringServices] = await this.authNostrService.getNostrConnectServices(); - - dialog.appendChild(this.modal); - document.body.appendChild(dialog); - - let otpPubkey = ''; - - this.launcherPromise = new Promise((ok, err) => { - dialog.addEventListener('close', () => { - // noop if already resolved - err(new Error('Closed')); - - this.authNostrService.resetAuth(); - - if (this.modal) { - // it's reset on modal creation - // // reset state - // this.modal.isLoading = false; - // this.modal.authUrl = ''; - // this.modal.iframeUrl = ''; - // this.modal.error = ''; - // this.modal.isLoadingExtension = false; - - // drop it - // @ts-ignore - document.body.removeChild(this.modal.parentNode); - this.modal = null; - } - }); - - const done = async (ok: () => void) => { - if (this.modal) this.modal.isLoading = false; - await this.authNostrService.endAuth(); - dialog.close(); - this.modal = null; - ok(); - }; - - const exec = async ( - body: () => Promise, - options?: { - start?: boolean; - end?: boolean; - }, - ) => { - if (this.modal) { - this.modal.isLoading = true; - } - - try { - if (!options || options.start) await this.authNostrService.startAuth(); - await body(); - if (!options || options.end) await done(ok); - } catch (e: any) { - console.log('error', e); - if (this.modal) { - this.modal.isLoading = false; - this.modal.authUrl = ''; - this.modal.iframeUrl = ''; - if (e !== 'cancelled') this.modal.error = e.toString(); - } - } - }; - - const login = async (name: string, domain?: string) => { - await exec(async () => { - // convert name to bunker url - const bunkerUrl = await getBunkerUrl(name, this.params.optionsModal); - - // connect to bunker by url - await this.authNostrService.authNip46('login', { name, bunkerUrl, domain }); - }); - }; - - const signup = async (name: string) => { - await exec(async () => { - // create acc on service and get bunker url - const { bunkerUrl, sk } = await this.authNostrService.createAccount(name); - - // connect to bunker by url - await this.authNostrService.authNip46('signup', { name, bunkerUrl, sk }); - }); - }; - - const exportKeys = async () => { - try { - await navigator.clipboard.writeText(this.authNostrService.exportKeys()); - localStorageSetItem('backupKey', 'true'); - } catch (err) { - console.error('Failed to copy to clipboard: ', err); - } - }; - - const importKeys = async (cs: ConnectionString) => { - await exec(async () => { - const { iframeUrl } = cs; - cs.link = this.authNostrService.prepareImportUrl(cs.link); - - if (this.modal && iframeUrl) { - // we pass the link down to iframe so it could open it - this.modal.authUrl = cs.link; - this.modal.iframeUrl = iframeUrl; - this.modal.isLoading = false; - console.log('nostrconnect authUrl', this.modal.authUrl, this.modal.iframeUrl); - } - - await this.authNostrService.importAndConnect(cs); - }); - }; - - const nostrConnect = async (cs?: ConnectionString) => { - await exec(async () => { - const { relay, domain, link, iframeUrl } = cs || {}; - console.log('nostrConnect', cs, relay, domain, link, iframeUrl); - - if (this.modal) { - if (iframeUrl) { - // we pass the link down to iframe so it could open it - this.modal.authUrl = link; - this.modal.iframeUrl = iframeUrl; - this.modal.isLoading = false; - console.log('nostrconnect authUrl', this.modal.authUrl, this.modal.iframeUrl); - } - - if (!cs) this.modal.isLoading = false; - } - - await this.authNostrService.nostrConnect(relay, { domain, link, iframeUrl }); - }); - }; - - const localSignup = async (name?: string) => { - await exec(async () => { - if (!name) throw new Error('Please enter some nickname'); - await this.authNostrService.localSignup(name); - }); - }; - - const signupNjump = async () => { - await exec(async () => { - const self = new URL(window.location.href); - const name = - self.hostname - .toLocaleLowerCase() - .replace(/^www\./i, '') - .charAt(0) - .toUpperCase() + self.hostname.slice(1); - const relays = prepareSignupRelays(this.params.optionsModal.signupRelays); - // const url = `https://start.njump.me/?an=${name}&at=popup&ac=${window.location.href}&s=${this.opt!.followNpubs || ''}&arr=${relays}&awr=${relays}`; - // console.log('njump url', url); - - this.modal!.njumpIframe = ` - - - - - `.replaceAll('&', '&'); // needed? - - return new Promise((ok, err) => { - const process = async (nsecOrBunker: string) => { - // process the returned value - console.log('nsecOrBunker', nsecOrBunker); - if (nsecOrBunker.startsWith('nsec1')) { - let decoded; - try { - decoded = nip19.decode(nsecOrBunker); - } catch (e) { - throw new Error('Bad nsec value'); - } - if (decoded.type !== 'nsec') throw new Error('Bad bech32 type'); - await this.authNostrService.localSignup('', decoded.data); - ok(); - } else if (nsecOrBunker.startsWith('bunker:')) { - await this.authNostrService.authNip46('login', { name: '', bunkerUrl: nsecOrBunker }); - ok(); - } else if (nsecOrBunker === 'null') { - err('Cancelled'); - } else { - err('Unknown return value'); - } - }; - - const onOpen = async () => { - if (window.location.hash.startsWith('#nostr-login=')) { - const nsecOrBunker = window.location.hash.split('#nostr-login=')[1]; - - // clear hash from history - const url = new URL(window.location.toString()); - url.hash = ''; - window.history.replaceState({}, '', url.toString()); - - process(nsecOrBunker); - } - }; - - // // use random 'target' to make sure window.opener is - // // accessible to the popup - // window.open(url, '' + Date.now(), 'popup=true,width=600,height=950'); - window.addEventListener('hashchange', onOpen); - }); - }); - }; - - if (!this.modal) throw new Error('WTH?'); - - this.modal.addEventListener('handleContinue', () => { - if (this.modal) { - this.modal.isLoading = true; - this.emit('onAuthUrlClick', this.modal.authUrl); - } - }); - - this.modal.addEventListener('nlLogin', (event: any) => { - login(event.detail); - }); - - this.modal.addEventListener('nlSignup', (event: any) => { - signup(event.detail); - }); - - this.modal.addEventListener('nlLocalSignup', (event: any) => { - localSignup(event.detail); - }); - - this.modal.addEventListener('nlSignupNjump', (event: any) => { - signupNjump(); - }); - - this.modal.addEventListener('nlImportAccount', (event: any) => { - importKeys(event.detail); - }); - - this.modal.addEventListener('nlExportKeys', (event: any) => { - exportKeys(); - }); - - this.modal.addEventListener('handleLogoutBanner', () => { - this.emit('onLogoutBanner'); - }); - - this.modal.addEventListener('nlNostrConnect', (event: any) => { - nostrConnect(event.detail); - }); - - this.modal.addEventListener('nlNostrConnectDefault', () => { - // dedup the calls - if (!this.authNostrService.isAuthing()) nostrConnect(); - }); - - this.modal.addEventListener('nlNostrConnectDefaultCancel', () => { - console.log('nlNostrConnectDefaultCancel'); - this.authNostrService.cancelNostrConnect(); - }); - - this.modal.addEventListener('nlSwitchAccount', (event: any) => { - const eventInfo: Info = event.detail as Info; - - this.emit('onSwitchAccount', eventInfo); - - // wait a bit, if dialog closes before - // switching finishes then launched promise rejects - - // FIXME this calls resetAuth which then prevents - // endAuth from getting properly called. 300 is not - // enough to init iframe, so there should be a - // feedback from switchAccount here - setTimeout(() => dialog.close(), 300); - }); - - this.modal.addEventListener('nlLoginRecentAccount', async (event: any) => { - const userInfo: Info = event.detail as Info; - - if (userInfo.authMethod === 'readOnly') { - this.authNostrService.setReadOnly(userInfo.pubkey); - dialog.close(); - } else if (userInfo.authMethod === 'otp') { - try { - this.modal!.dispatchEvent( - new CustomEvent('nlLoginOTPUser', { - detail: userInfo.nip05 || userInfo.pubkey, - }), - ); - } catch (e) { - console.error(e); - } - } else if (userInfo.authMethod === 'extension') { - await this.extensionService.trySetExtensionForPubkey(userInfo.pubkey); - dialog.close(); - } else { - const input = userInfo.bunkerUrl || userInfo.nip05; - if (!input) throw new Error('Bad connect info'); - login(input, userInfo.domain); - } - }); - - this.modal.addEventListener('nlRemoveRecent', (event: any) => { - localStorageRemoveRecent(event.detail as RecentType); - this.emit('updateAccounts'); - }); - - const nameToPubkey = async (nameNpub: string) => { - let pubkey = ''; - if (nameNpub.includes('@')) { - const { error, pubkey: nip05pubkey } = await checkNip05(nameNpub); - if (nip05pubkey) pubkey = nip05pubkey; - else throw new Error(error); - } else if (nameNpub.startsWith('npub')) { - const { type, data } = nip19.decode(nameNpub); - if (type === 'npub') pubkey = data as string; - else throw new Error('Bad npub'); - } else if (nameNpub.trim().length === 64) { - pubkey = nameNpub.trim(); - nip19.npubEncode(pubkey); // check - } - return pubkey; - }; - - this.modal.addEventListener('nlLoginReadOnly', async (event: any) => { - await exec(async () => { - const nameNpub = event.detail; - const pubkey = await nameToPubkey(nameNpub); - this.authNostrService.setReadOnly(pubkey); - }); - }); - - this.modal.addEventListener('nlLoginExtension', async () => { - if (!this.extensionService.hasExtension()) { - throw new Error('No extension'); - } - - await exec(async () => { - if (!this.modal) return; - this.modal.isLoadingExtension = true; - await this.extensionService.setExtension(); - this.modal.isLoadingExtension = false; - }); - }); - - this.modal.addEventListener('nlLoginOTPUser', async (event: any) => { - await exec( - async () => { - if (!this.modal) return; - - const nameNpub = event.detail; - const pubkey = await nameToPubkey(nameNpub); - const url = this.opt!.otpRequestUrl! + (this.opt!.otpRequestUrl!.includes('?') ? '&' : '?') + 'pubkey=' + pubkey; - const r = await fetch(url); - if (r.status !== 200) { - console.warn('nostr-login: bad otp reply', r); - throw new Error('Failed to send DM'); - } - - // switch to 'enter code' mode - this.modal.isOTP = true; - - // remember for code handler below - otpPubkey = pubkey; - - // spinner off - this.modal.isLoading = false; - }, - { start: true }, - ); - }); - - this.modal.addEventListener('nlLoginOTPCode', async (event: any) => { - await exec( - async () => { - if (!this.modal) return; - const code = event.detail; - const url = this.opt!.otpReplyUrl! + (this.opt!.otpRequestUrl!.includes('?') ? '&' : '?') + 'pubkey=' + otpPubkey + '&code=' + code; - const r = await fetch(url); - if (r.status !== 200) { - console.warn('nostr-login: bad otp reply', r); - throw new Error('Invalid code'); - } - - const data = await r.text(); - this.authNostrService.setOTP(otpPubkey, data); - - this.modal.isOTP = false; - }, - { end: true }, - ); - }); - - this.modal.addEventListener('nlCheckSignup', async (event: any) => { - const { available, taken, error } = await checkNip05(event.detail); - if (this.modal) { - this.modal.error = String(error); - - if (!error && taken) { - this.modal.error = 'Already taken'; - } - - this.modal.signupNameIsAvailable = available; - } - }); - - this.modal.addEventListener('nlCheckLogin', async (event: any) => { - const { available, taken, error } = await checkNip05(event.detail); - if (this.modal) { - this.modal.error = String(error); - if (available) { - this.modal.error = 'Name not found'; - } - this.modal.loginIsGood = taken; - } - }); - - const cancel = () => { - if (this.modal) { - this.modal.isLoading = false; - } - - // this.authNostrService.cancelListenNostrConnect(); - - dialog.close(); - err(new Error('Cancelled')); - }; - this.modal.addEventListener('stopFetchHandler', cancel); - this.modal.addEventListener('nlCloseModal', cancel); - - this.modal.addEventListener('nlChangeDarkMode', (event: any) => { - setDarkMode(event.detail); - document.dispatchEvent(new CustomEvent('nlDarkMode', { detail: event.detail })); - }); - - this.on('onIframeAuthUrlCallEnd', () => { - dialog.close(); - this.modal = null; - ok(); - }); - - dialog.showModal(); - }); - - return this.launcherPromise; - } - - public async showIframeUrl(url: string) { - // make sure we consume the previous promise, - // otherwise launch will start await-ing - // before modal is created and setting iframeUrl will fail - await this.waitReady(); - - this.launch({ - startScreen: 'iframe' as StartScreens, - }).catch(() => console.log('closed auth iframe')); - - this.modal!.authUrl = url; - } - - public connectModals(defaultOpt: NostrLoginOptions) { - const initialModals = async (opt: NostrLoginOptions) => { - await this.launch(opt); - }; - - const nlElements = document.getElementsByTagName('nl-button'); - - for (let i = 0; i < nlElements.length; i++) { - const theme = nlElements[i].getAttribute('nl-theme'); - const startScreen = nlElements[i].getAttribute('start-screen'); - - const elementOpt = { - ...defaultOpt, - }; - if (theme) elementOpt.theme = theme; - - switch (startScreen as StartScreens) { - case 'login': - case 'login-bunker-url': - case 'login-read-only': - case 'signup': - case 'switch-account': - case 'welcome': - elementOpt.startScreen = startScreen as StartScreens; - } - - nlElements[i].addEventListener('click', function () { - initialModals(elementOpt); - }); - } - } - - public onAuthUrl(url: string) { - if (this.modal) { - this.modal.authUrl = url; - this.modal.isLoading = false; - } - } - - public onIframeUrl(url: string) { - if (this.modal) { - console.log('modal iframe url', url); - this.modal.iframeUrl = url; - } - } - - public onCallEnd() { - if (this.modal && this.modal.authUrl && this.params.userInfo?.iframeUrl) { - this.emit('onIframeAuthUrlCallEnd'); - } - } - - public onUpdateAccounts(accounts: Info[], recents: RecentType[]) { - this.accounts = accounts; - this.recents = recents; - if (!this.modal) return; - this.modal.accounts = accounts; - this.modal.recents = recents; - } - - public onDarkMode(dark: boolean) { - if (this.modal) this.modal.darkMode = dark; - } -} - -export default ModalManager; diff --git a/packages/auth/src/modules/Nip46.ts b/packages/auth/src/modules/Nip46.ts deleted file mode 100644 index 6d9ef1e..0000000 --- a/packages/auth/src/modules/Nip46.ts +++ /dev/null @@ -1,429 +0,0 @@ -import NDK, { NDKEvent, NDKFilter, NDKNip46Signer, NDKNostrRpc, NDKRpcRequest, NDKRpcResponse, NDKSubscription, NDKSubscriptionCacheUsage, NostrEvent } from '@nostr-dev-kit/ndk'; -import { validateEvent, verifySignature } from 'nostr-tools'; -import { PrivateKeySigner } from './Signer'; - -class NostrRpc extends NDKNostrRpc { - protected _ndk: NDK; - protected _signer: PrivateKeySigner; - protected requests: Set = new Set(); - private sub?: NDKSubscription; - protected _useNip44: boolean = false; - - public constructor(ndk: NDK, signer: PrivateKeySigner) { - super(ndk, signer, ndk.debug.extend('nip46:signer:rpc')); - this._ndk = ndk; - this._signer = signer; - } - - public async subscribe(filter: NDKFilter): Promise { - // NOTE: fixing ndk - filter.kinds = filter.kinds?.filter(k => k === 24133); - this.sub = await super.subscribe(filter); - return this.sub; - } - - public stop() { - if (this.sub) { - this.sub.stop(); - this.sub = undefined; - } - } - - public setUseNip44(useNip44: boolean) { - this._useNip44 = useNip44; - } - - private isNip04(ciphertext: string) { - const l = ciphertext.length; - if (l < 28) return false; - return ciphertext[l - 28] === '?' && ciphertext[l - 27] === 'i' && ciphertext[l - 26] === 'v' && ciphertext[l - 25] === '='; - } - - // override to auto-decrypt nip04/nip44 - public async parseEvent(event: NDKEvent): Promise { - const remoteUser = this._ndk.getUser({ pubkey: event.pubkey }); - remoteUser.ndk = this._ndk; - const decrypt = this.isNip04(event.content) ? this._signer.decrypt : this._signer.decryptNip44; - const decryptedContent = await decrypt.call(this._signer, remoteUser, event.content); - const parsedContent = JSON.parse(decryptedContent); - const { id, method, params, result, error } = parsedContent; - - if (method) { - return { id, pubkey: event.pubkey, method, params, event }; - } else { - return { id, result, error, event }; - } - } - - public async parseNostrConnectReply(reply: any, secret: string) { - const event = new NDKEvent(this._ndk, reply); - const parsedEvent = await this.parseEvent(event); - console.log('nostr connect parsedEvent', parsedEvent); - if (!(parsedEvent as NDKRpcRequest).method) { - const response = parsedEvent as NDKRpcResponse; - if (response.result !== secret) throw new Error(response.error); - return event.pubkey; - } else { - throw new Error('Bad nostr connect reply'); - } - } - - // ndk doesn't support nostrconnect: - // we just listed to an unsolicited reply to - // our pubkey and if it's ack/secret - we're fine - public async listen(nostrConnectSecret: string): Promise { - const pubkey = this._signer.pubkey; - console.log('nostr-login listening for conn to', pubkey); - const sub = await this.subscribe({ - 'kinds': [24133], - '#p': [pubkey], - }); - return new Promise((ok, err) => { - sub.on('event', async (event: NDKEvent) => { - try { - const parsedEvent = await this.parseEvent(event); - // console.log('ack parsedEvent', parsedEvent); - if (!(parsedEvent as NDKRpcRequest).method) { - const response = parsedEvent as NDKRpcResponse; - - // ignore - if (response.result === 'auth_url') return; - - // FIXME for now accept 'ack' replies, later on only - // accept secrets - if (response.result === 'ack' || response.result === nostrConnectSecret) { - ok(event.pubkey); - } else { - err(response.error); - } - } - } catch (e) { - console.log('error parsing event', e, event.rawEvent()); - } - // done - this.stop(); - }); - }); - } - - // since ndk doesn't yet support perms param - // we reimplement the 'connect' call here - // instead of await signer.blockUntilReady(); - public async connect(pubkey: string, token?: string, perms?: string) { - return new Promise((ok, err) => { - const connectParams = [pubkey!, token || '', perms || '']; - this.sendRequest(pubkey!, 'connect', connectParams, 24133, (response: NDKRpcResponse) => { - if (response.result === 'ack') { - ok(); - } else { - err(response.error); - } - }); - }); - } - - protected getId(): string { - return Math.random().toString(36).substring(7); - } - - public async sendRequest(remotePubkey: string, method: string, params: string[] = [], kind = 24133, cb?: (res: NDKRpcResponse) => void): Promise { - const id = this.getId(); - - // response handler will deduplicate auth urls and responses - this.setResponseHandler(id, cb); - - // create and sign request - const event = await this.createRequestEvent(id, remotePubkey, method, params, kind); - console.log("sendRequest", { event, method, remotePubkey, params }); - - // send to relays - await event.publish(); - - // NOTE: ndk returns a promise that never resolves and - // in fact REQUIRES cb to be provided (otherwise no way - // to consume the result), we've already stepped on the bug - // of waiting for this unresolvable result, so now we return - // undefined to make sure waiters fail, not hang. - // @ts-ignore - return undefined as NDKRpcResponse; - } - - protected setResponseHandler(id: string, cb?: (res: NDKRpcResponse) => void) { - let authUrlSent = false; - const now = Date.now(); - return new Promise(() => { - const responseHandler = (response: NDKRpcResponse) => { - if (response.result === 'auth_url') { - this.once(`response-${id}`, responseHandler); - if (!authUrlSent) { - authUrlSent = true; - this.emit('authUrl', response.error); - } - } else if (cb) { - if (this.requests.has(id)) { - this.requests.delete(id); - console.log('nostr-login processed nip46 request in', Date.now() - now, 'ms'); - cb(response); - } - } - }; - - this.once(`response-${id}`, responseHandler); - }); - } - - protected async createRequestEvent(id: string, remotePubkey: string, method: string, params: string[] = [], kind = 24133) { - this.requests.add(id); - const localUser = await this._signer.user(); - const remoteUser = this._ndk.getUser({ pubkey: remotePubkey }); - const request = { id, method, params }; - - const event = new NDKEvent(this._ndk, { - kind, - content: JSON.stringify(request), - tags: [['p', remotePubkey]], - pubkey: localUser.pubkey, - } as NostrEvent); - - const useNip44 = this._useNip44 && method !== 'create_account'; - const encrypt = useNip44 ? this._signer.encryptNip44 : this._signer.encrypt; - event.content = await encrypt.call(this._signer, remoteUser, event.content); - await event.sign(this._signer); - - return event; - } -} - -export class IframeNostrRpc extends NostrRpc { - private peerOrigin?: string; - private iframePort?: MessagePort; - private iframeRequests = new Map(); - - public constructor(ndk: NDK, localSigner: PrivateKeySigner, iframePeerOrigin?: string) { - super(ndk, localSigner); - this._ndk = ndk; - this.peerOrigin = iframePeerOrigin; - } - - public async subscribe(filter: NDKFilter): Promise { - if (!this.peerOrigin) return super.subscribe(filter); - return new NDKSubscription( - this._ndk, - {}, - { - // don't send to relay - closeOnEose: true, - cacheUsage: NDKSubscriptionCacheUsage.ONLY_CACHE, - }, - ); - } - - public setWorkerIframePort(port: MessagePort) { - if (!this.peerOrigin) throw new Error('Unexpected iframe port'); - - this.iframePort = port; - - // to make sure Chrome doesn't terminate the channel - setInterval(() => { - console.log('iframe-nip46 ping'); - this.iframePort!.postMessage('ping'); - }, 5000); - - port.onmessage = async ev => { - console.log('iframe-nip46 got response', ev.data); - if (typeof ev.data === 'string' && ev.data.startsWith('errorNoKey')) { - const event_id = ev.data.split(':')[1]; - const { id = '', pubkey = '' } = this.iframeRequests.get(event_id) || {}; - if (id && pubkey && this.requests.has(id)) this.emit(`iframeRestart-${pubkey}`); - return; - } - - // a copy-paste from rpc.subscribe - try { - const event = ev.data; - - if (!validateEvent(event)) throw new Error('Invalid event from iframe'); - if (!verifySignature(event)) throw new Error('Invalid event signature from iframe'); - const nevent = new NDKEvent(this._ndk, event); - const parsedEvent = await this.parseEvent(nevent); - // we're only implementing client-side rpc - if (!(parsedEvent as NDKRpcRequest).method) { - console.log('parsed response', parsedEvent); - this.emit(`response-${parsedEvent.id}`, parsedEvent); - } - } catch (e) { - console.log('error parsing event', e, ev.data); - } - }; - } - - public async sendRequest(remotePubkey: string, method: string, params: string[] = [], kind = 24133, cb?: (res: NDKRpcResponse) => void): Promise { - const id = this.getId(); - - // create and sign request event - const event = await this.createRequestEvent(id, remotePubkey, method, params, kind); - - // set response handler, it will dedup auth urls, - // and also dedup response handlers - we're sending - // to relays and to iframe - this.setResponseHandler(id, cb); - - if (this.iframePort) { - // map request event id to request id, if iframe - // has no key it will reply with error:event_id (it can't - // decrypt the request id without keys) - this.iframeRequests.set(event.id, { id, pubkey: remotePubkey }); - - // send to iframe - console.log('iframe-nip46 sending request to', this.peerOrigin, event.rawEvent()); - this.iframePort.postMessage(event.rawEvent()); - } else { - // send to relays - await event.publish(); - } - - // see notes in 'super' - // @ts-ignore - return undefined as NDKRpcResponse; - } -} - -export class ReadyListener { - origin: string; - messages: string[]; - promise: Promise; - - constructor(messages: string[], origin: string) { - this.origin = origin; - this.messages = messages; - this.promise = new Promise(ok => { - console.log(new Date(), 'started listener for', this.messages); - - // ready message handler - const onReady = async (e: MessageEvent) => { - const originHostname = new URL(origin!).hostname; - const messageHostname = new URL(e.origin).hostname; - // same host or subdomain - const validHost = messageHostname === originHostname || messageHostname.endsWith('.' + originHostname); - if (!validHost || !Array.isArray(e.data) || !e.data.length || !this.messages.includes(e.data[0])) { - // console.log(new Date(), 'got invalid ready message', e.origin, e.data); - return; - } - - console.log(new Date(), 'got ready message from', e.origin, e.data); - window.removeEventListener('message', onReady); - ok(e.data); - }; - window.addEventListener('message', onReady); - }); - } - - async wait(): Promise { - console.log(new Date(), 'waiting for', this.messages); - const r = await this.promise; - // NOTE: timer here doesn't help bcs it must be activated when - // user "confirms", but that's happening on a different - // origin and we can't really know. - // await new Promise((ok, err) => { - // // 10 sec should be more than enough - // setTimeout(() => err(new Date() + ' timeout for ' + this.message), 10000); - - // // if promise already resolved or will resolve in the future - // this.promise.then(ok); - // }); - - console.log(new Date(), 'finished waiting for', this.messages, r); - return r; - } -} - -export class Nip46Signer extends NDKNip46Signer { - private _userPubkey: string = ''; - private _rpc: IframeNostrRpc; - - constructor(ndk: NDK, localSigner: PrivateKeySigner, signerPubkey: string, iframeOrigin?: string) { - super(ndk, signerPubkey, localSigner); - - // override with our own rpc implementation - this._rpc = new IframeNostrRpc(ndk, localSigner, iframeOrigin); - this._rpc.setUseNip44(true); // !!this.params.optionsModal.dev); - this._rpc.on('authUrl', (url: string) => { - this.emit('authUrl', url); - }); - - this.rpc = this._rpc; - } - - get userPubkey() { - return this._userPubkey; - } - - private async setSignerPubkey(signerPubkey: string, sameAsUser: boolean = false) { - console.log("setSignerPubkey", signerPubkey); - - // ensure it's set - this.remotePubkey = signerPubkey; - - // when we're sure it's known - this._rpc.on(`iframeRestart-${signerPubkey}`, () => { - this.emit('iframeRestart'); - }); - - // now call getPublicKey and swap remotePubkey w/ that - await this.initUserPubkey(sameAsUser ? signerPubkey : ''); - } - - public async initUserPubkey(hintPubkey?: string) { - if (this._userPubkey) throw new Error('Already called initUserPubkey'); - - if (hintPubkey) { - this._userPubkey = hintPubkey; - return; - } - - this._userPubkey = await new Promise((ok, err) => { - if (!this.remotePubkey) throw new Error('Signer pubkey not set'); - - console.log("get_public_key", this.remotePubkey); - this._rpc.sendRequest(this.remotePubkey, 'get_public_key', [], 24133, (response: NDKRpcResponse) => { - ok(response.result); - }); - }); - } - - public async listen(nostrConnectSecret: string) { - const signerPubkey = await (this.rpc as IframeNostrRpc).listen(nostrConnectSecret); - await this.setSignerPubkey(signerPubkey); - } - - public async connect(token?: string, perms?: string) { - if (!this.remotePubkey) throw new Error('No signer pubkey'); - await this._rpc.connect(this.remotePubkey, token, perms); - await this.setSignerPubkey(this.remotePubkey); - } - - public async setListenReply(reply: any, nostrConnectSecret: string) { - const signerPubkey = await this._rpc.parseNostrConnectReply(reply, nostrConnectSecret); - await this.setSignerPubkey(signerPubkey, true); - } - - public async createAccount2({ bunkerPubkey, name, domain, perms = '' }: { bunkerPubkey: string; name: string; domain: string; perms?: string }) { - const params = [ - name, - domain, - '', // email - perms, - ]; - - const r = await new Promise(ok => { - this.rpc.sendRequest(bunkerPubkey, 'create_account', params, undefined, ok); - }); - - console.log('create_account pubkey', r); - if (r.result === 'error') { - throw new Error(r.error); - } - - return r.result; - } -} diff --git a/packages/auth/src/modules/Nostr.ts b/packages/auth/src/modules/Nostr.ts deleted file mode 100644 index 745fb86..0000000 --- a/packages/auth/src/modules/Nostr.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { Info } from 'nostr-login-components/dist/types/types'; - -export interface Signer { - signEvent: (event: any) => Promise; - nip04: { - encrypt: (pubkey: string, plaintext: string) => Promise; - decrypt: (pubkey: string, ciphertext: string) => Promise; - }; - nip44: { - encrypt: (pubkey: string, plaintext: string) => Promise; - decrypt: (pubkey: string, ciphertext: string) => Promise; - }; -} - -export interface NostrObjectParams { - waitReady(): Promise; - getUserInfo(): Info | null; - launch(): Promise; - getSigner(): Signer; - wait(cb: () => Promise): Promise; -} - -class Nostr { - #params: NostrObjectParams; - private nip04: { - encrypt: (pubkey: string, plaintext: string) => Promise; - decrypt: (pubkey: string, ciphertext: string) => Promise; - }; - private nip44: { - encrypt: (pubkey: string, plaintext: string) => Promise; - decrypt: (pubkey: string, ciphertext: string) => Promise; - }; - - constructor(params: NostrObjectParams) { - this.#params = params; - - this.getPublicKey = this.getPublicKey.bind(this); - this.signEvent = this.signEvent.bind(this); - this.getRelays = this.getRelays.bind(this); - this.nip04 = { - encrypt: this.encrypt04.bind(this), - decrypt: this.decrypt04.bind(this), - }; - this.nip44 = { - encrypt: this.encrypt44.bind(this), - decrypt: this.decrypt44.bind(this), - }; - } - - private async ensureAuth() { - await this.#params.waitReady(); - - // authed? - if (this.#params.getUserInfo()) return; - - // launch auth flow - await this.#params.launch(); - - // give up - if (!this.#params.getUserInfo()) { - throw new Error('Rejected by user'); - } - } - - async getPublicKey() { - await this.ensureAuth(); - const userInfo = this.#params.getUserInfo(); - if (userInfo) { - return userInfo.pubkey; - } else { - throw new Error('No user'); - } - } - - // @ts-ignore - async signEvent(event) { - await this.ensureAuth(); - return this.#params.wait(async () => await this.#params.getSigner().signEvent(event)); - } - - async getRelays() { - // FIXME implement! - return {}; - } - - async encrypt04(pubkey: string, plaintext: string) { - await this.ensureAuth(); - return this.#params.wait(async () => await this.#params.getSigner().nip04.encrypt(pubkey, plaintext)); - } - - async decrypt04(pubkey: string, ciphertext: string) { - await this.ensureAuth(); - return this.#params.wait(async () => await this.#params.getSigner().nip04.decrypt(pubkey, ciphertext)); - } - - async encrypt44(pubkey: string, plaintext: string) { - await this.ensureAuth(); - return this.#params.wait(async () => await this.#params.getSigner().nip44.encrypt(pubkey, plaintext)); - } - - async decrypt44(pubkey: string, ciphertext: string) { - await this.ensureAuth(); - return this.#params.wait(async () => await this.#params.getSigner().nip44.decrypt(pubkey, ciphertext)); - } -} - -export default Nostr; diff --git a/packages/auth/src/modules/NostrExtensionService.ts b/packages/auth/src/modules/NostrExtensionService.ts deleted file mode 100644 index f5bf919..0000000 --- a/packages/auth/src/modules/NostrExtensionService.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { Nostr, NostrParams } from './'; -import { EventEmitter } from 'tseep'; - -class NostrExtensionService extends EventEmitter { - private params: NostrParams; - private nostrExtension: any | undefined; - - constructor(params: NostrParams) { - super(); - this.params = params; - } - - public startCheckingExtension(nostr: Nostr) { - if (this.checkExtension(nostr)) return; - - // watch out for extension trying to overwrite us - const to = setInterval(() => { - if (this.checkExtension(nostr)) clearTimeout(to); - }, 100); - } - - private checkExtension(nostr: Nostr) { - // @ts-ignore - if (!this.nostrExtension && window.nostr && window.nostr !== nostr) { - this.initExtension(nostr); - return true; - } - return false; - } - - private async initExtension(nostr: Nostr, lastTry?: boolean) { - // @ts-ignore - this.nostrExtension = window.nostr; - // @ts-ignore - window.nostr = nostr; - // we're signed in with extesions? well execute that - if (this.params.userInfo?.authMethod === 'extension') { - await this.trySetExtensionForPubkey(this.params.userInfo.pubkey); - } - - // schedule another check - if (!lastTry) { - setTimeout(() => { - // NOTE: we can't know if user has >1 extension and thus - // if the current one we detected is the actual 'last one' - // that will set the window.nostr. So the simplest - // solution is to wait a bit more, hoping that if one - // extension started then the rest are likely to start soon, - // and then just capture the most recent one - - // @ts-ignore - if (window.nostr !== nostr && this.nostrExtension !== window.nostr) { - this.initExtension(nostr, true); - } - }, 300); - } - - // in the worst case of app saving the nostrExtension reference - // it will be calling it directly, not a big deal - } - - private async setExtensionReadPubkey(expectedPubkey?: string) { - window.nostr = this.nostrExtension; - // @ts-ignore - const pubkey = await window.nostr.getPublicKey(); - if (expectedPubkey && expectedPubkey !== pubkey) { - this.emit('extensionLogout'); - } else { - this.emit('extensionLogin', pubkey); - } - } - - public async trySetExtensionForPubkey(expectedPubkey: string) { - if (this.nostrExtension) { - return this.setExtensionReadPubkey(expectedPubkey); - } - } - - public async setExtension() { - return this.setExtensionReadPubkey(); - } - - public unsetExtension(nostr: Nostr) { - if (window.nostr === this.nostrExtension) { - // @ts-ignore - window.nostr = nostr; - } - } - - public getExtension() { - return this.nostrExtension; - } - - public hasExtension() { - return !!this.nostrExtension; - } -} - -export default NostrExtensionService; diff --git a/packages/auth/src/modules/NostrParams.ts b/packages/auth/src/modules/NostrParams.ts deleted file mode 100644 index 9b61ec6..0000000 --- a/packages/auth/src/modules/NostrParams.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Info } from 'nostr-login-components/dist/types/types'; -import { NostrLoginOptions } from '../types'; - -class NostrParams { - public userInfo: Info | null; - public optionsModal: NostrLoginOptions; - constructor() { - this.userInfo = null; - - this.optionsModal = { - theme: 'default', - startScreen: 'welcome', - devOverrideBunkerOrigin: '', - }; - } -} - -export default NostrParams; diff --git a/packages/auth/src/modules/Popup.ts b/packages/auth/src/modules/Popup.ts deleted file mode 100644 index 284614d..0000000 --- a/packages/auth/src/modules/Popup.ts +++ /dev/null @@ -1,27 +0,0 @@ -class Popup { - private popup: Window | null = null; - - constructor() {} - - public openPopup(url: string) { - // user might have closed it already - if (!this.popup || this.popup.closed) { - // NOTE: do not set noreferrer, bunker might use referrer to - // simplify the naming of the connected app. - // NOTE: do not pass noopener, otherwise null is returned - this.popup = window.open(url, '_blank', 'width=400,height=700'); - console.log('popup', this.popup); - if (!this.popup) throw new Error('Popup blocked. Try again, please!'); - } - } - - public closePopup() { - // make sure we release the popup - try { - this.popup?.close(); - this.popup = null; - } catch {} - } -} - -export default Popup; diff --git a/packages/auth/src/modules/ProcessManager.ts b/packages/auth/src/modules/ProcessManager.ts deleted file mode 100644 index 0676925..0000000 --- a/packages/auth/src/modules/ProcessManager.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { EventEmitter } from 'tseep'; -import { CALL_TIMEOUT } from '../const'; - -class ProcessManager extends EventEmitter { - private callCount: number = 0; - private callTimer: NodeJS.Timeout | undefined; - - constructor() { - super(); - } - - public onAuthUrl() { - if (Boolean(this.callTimer)) { - clearTimeout(this.callTimer); - } - } - - public onIframeUrl() { - if (Boolean(this.callTimer)) { - clearTimeout(this.callTimer); - } - } - - public async wait(cb: () => Promise): Promise { - // FIXME only allow 1 parallel req - - if (!this.callTimer) { - this.callTimer = setTimeout(() => this.emit('onCallTimeout'), CALL_TIMEOUT); - } - - if (!this.callCount) { - this.emit('onCallStart'); - } - - this.callCount++; - - let error; - let result; - - try { - result = await cb(); - } catch (e) { - error = e; - } - - this.callCount--; - - this.emit('onCallEnd'); - - if (this.callTimer) { - clearTimeout(this.callTimer); - } - - this.callTimer = undefined; - - if (error) { - throw error; - } - - // we can't return undefined bcs an exception is - // thrown above on error - // @ts-ignore - return result; - } -} - -export default ProcessManager; diff --git a/packages/auth/src/modules/Signer.ts b/packages/auth/src/modules/Signer.ts deleted file mode 100644 index f854799..0000000 --- a/packages/auth/src/modules/Signer.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { NDKPrivateKeySigner, NDKUser } from '@nostr-dev-kit/ndk'; -import { Nip44 } from '../utils/nip44'; -import { getPublicKey } from 'nostr-tools'; - -export class PrivateKeySigner extends NDKPrivateKeySigner { - private nip44: Nip44 = new Nip44(); - private _pubkey: string; - - constructor(privateKey: string) { - super(privateKey); - this._pubkey = getPublicKey(privateKey); - } - - get pubkey() { - return this._pubkey; - } - - encryptNip44(recipient: NDKUser, value: string): Promise { - return Promise.resolve(this.nip44.encrypt(this.privateKey!, recipient.pubkey, value)); - } - - decryptNip44(sender: NDKUser, value: string): Promise { - return Promise.resolve(this.nip44.decrypt(this.privateKey!, sender.pubkey, value)); - } -} diff --git a/packages/auth/src/modules/index.ts b/packages/auth/src/modules/index.ts deleted file mode 100644 index 1132f0a..0000000 --- a/packages/auth/src/modules/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -export { default as BannerManager } from './BannerManager'; -export { default as AuthNostrService } from './AuthNostrService'; -export { default as ModalManager } from './ModalManager'; -export { default as Nostr } from './Nostr'; -export { default as NostrExtensionService } from './NostrExtensionService'; -export { default as NostrParams } from './NostrParams'; -export { default as Popup } from './Popup'; -export { default as ProcessManager } from './ProcessManager'; diff --git a/packages/auth/src/types.ts b/packages/auth/src/types.ts deleted file mode 100644 index d62581f..0000000 --- a/packages/auth/src/types.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { Info, AuthMethod, ConnectionString, RecentType, BannerNotify } from 'nostr-login-components/dist/types/types'; - -export interface NostrLoginAuthOptions { - localNsec?: string; - relays?: string[]; - type: 'login' | 'signup' | 'logout'; - method?: AuthMethod; - pubkey?: string; - otpData?: string; - name?: string; -} - -// NOTE: must be a subset of CURRENT_MODULE enum -export type StartScreens = - | 'welcome' - | 'welcome-login' - | 'welcome-signup' - | 'signup' - | 'local-signup' - | 'login' - | 'otp' - | 'connect' - | 'login-bunker-url' - | 'login-read-only' - | 'connection-string' - | 'switch-account' - | 'import'; - -export interface NostrLoginOptions { - // optional - theme?: string; - startScreen?: StartScreens; - bunkers?: string; - onAuth?: (npub: string, options: NostrLoginAuthOptions) => void; - perms?: string; - darkMode?: boolean; - - // do not show the banner, modals must be `launch`-ed - noBanner?: boolean; - - // forward reqs to this bunker origin for testing - devOverrideBunkerOrigin?: string; - - // deprecated, use methods=['local'] - // use local signup instead of nostr connect - localSignup?: boolean; - - // allowed auth methods - methods?: AuthMethod[]; - - // otp endpoints - otpRequestUrl?: string; - otpReplyUrl?: string; - - // welcome screen's title/desc - title?: string; - description?: string; - - // comma-separated list of relays added - // to relay list of new profiles created with local signup - signupRelays?: string; - - // relay list to override hardcoded `OUTBOX_RELAYS` constant - outboxRelays?: string[]; - - // dev mode - dev?: boolean; - - // use start.njump.me instead of local signup - signupNstart?: boolean; - - // list of npubs to auto/suggest-follow on signup - followNpubs?: string; - - // when method call auth needed, instead of showing - // the modal, we start waiting for incoming nip46 - // connection and send the nostrconnect string using - // nlNeedAuth event - customNostrConnect?: boolean; -} - -export interface IBanner { - userInfo?: Info | null; - titleBanner?: string; - isLoading?: boolean; - listNotifies?: string[]; - accounts?: Info[]; - isOpen?: boolean; - darkMode?: boolean; - notify?: BannerNotify; -} - -export type TypeBanner = IBanner & HTMLElement; - -export interface IModal { - authUrl?: string; - iframeUrl?: string; - isLoading?: boolean; - isOTP?: boolean; - isLoadingExtension?: boolean; - localSignup?: boolean; - signupNjump?: boolean; - njumpIframe?: string; - authMethods?: AuthMethod[]; - hasExtension?: boolean; - hasOTP?: boolean; - error?: string; - signupNameIsAvailable?: string | boolean; - loginIsGood?: string | boolean; - recents?: RecentType[]; - accounts?: Info[]; - darkMode?: boolean; - welcomeTitle?: string; - welcomeDescription?: string; - connectionString?: string; - connectionStringServices?: ConnectionString[]; -} - -export type TypeModal = IModal & HTMLElement; - -export interface Response { - result?: string; - error?: string; -} diff --git a/packages/auth/src/utils/index.ts b/packages/auth/src/utils/index.ts deleted file mode 100644 index 69e009d..0000000 --- a/packages/auth/src/utils/index.ts +++ /dev/null @@ -1,326 +0,0 @@ -import { Info, RecentType } from 'nostr-login-components/dist/types/types'; -import NDK, { NDKEvent, NDKRelaySet, NDKSigner, NDKUser } from '@nostr-dev-kit/ndk'; -import { generatePrivateKey } from 'nostr-tools'; -import { NostrLoginOptions } from '../types'; - -const LOCAL_STORE_KEY = '__nostrlogin_nip46'; -const LOGGED_IN_ACCOUNTS = '__nostrlogin_accounts'; -const RECENT_ACCOUNTS = '__nostrlogin_recent'; -const OUTBOX_RELAYS = ['wss://purplepag.es', 'wss://relay.nos.social', 'wss://user.kindpag.es', 'wss://relay.damus.io', 'wss://nos.lol']; -const DEFAULT_SIGNUP_RELAYS = ['wss://relay.damus.io/', 'wss://nos.lol/', 'wss://relay.primal.net/']; - -export const localStorageSetItem = (key: string, value: string) => { - localStorage.setItem(key, value); -}; - -export const localStorageGetItem = (key: string) => { - const value = window.localStorage.getItem(key); - - if (value) { - try { - return JSON.parse(value); - } catch {} - } - - return null; -}; - -export const localStorageRemoveItem = (key: string) => { - localStorage.removeItem(key); -}; - -export const fetchProfile = async (info: Info, profileNdk: NDK) => { - const user = new NDKUser({ pubkey: info.pubkey }); - - user.ndk = profileNdk; - - return await user.fetchProfile(); -}; - -export const prepareSignupRelays = (signupRelays?: string) => { - const relays = (signupRelays || '') - .split(',') - .map(r => r.trim()) - .filter(r => r.startsWith('ws')); - if (!relays.length) relays.push(...DEFAULT_SIGNUP_RELAYS); - return relays; -}; - -export const createProfile = async (info: Info, profileNdk: NDK, signer: NDKSigner, signupRelays?: string, outboxRelays?: string[]) => { - const meta = { - name: info.name, - }; - - const profileEvent = new NDKEvent(profileNdk, { - kind: 0, - created_at: Math.floor(Date.now() / 1000), - pubkey: info.pubkey, - content: JSON.stringify(meta), - tags: [], - }); - if (window.location.hostname) profileEvent.tags.push(['client', window.location.hostname]); - - const relaysEvent = new NDKEvent(profileNdk, { - kind: 10002, - created_at: Math.floor(Date.now() / 1000), - pubkey: info.pubkey, - content: '', - tags: [], - }); - - const relays = prepareSignupRelays(signupRelays) - for (const r of relays) { - relaysEvent.tags.push(['r', r]); - } - - await profileEvent.sign(signer); - console.log('signed profile', profileEvent); - await relaysEvent.sign(signer); - console.log('signed relays', relaysEvent); - - const outboxRelaysFinal = outboxRelays && outboxRelays.length ? outboxRelays : OUTBOX_RELAYS; - - await profileEvent.publish(NDKRelaySet.fromRelayUrls(outboxRelaysFinal, profileNdk)); - console.log('published profile', profileEvent); - await relaysEvent.publish(NDKRelaySet.fromRelayUrls(outboxRelaysFinal, profileNdk)); - console.log('published relays', relaysEvent); -}; - -export const bunkerUrlToInfo = (bunkerUrl: string, sk = ''): Info => { - const url = new URL(bunkerUrl); - - return { - pubkey: '', - signerPubkey: url.hostname || url.pathname.split('//')[1], - sk: sk || generatePrivateKey(), - relays: url.searchParams.getAll('relay'), - token: url.searchParams.get('secret') || '', - authMethod: 'connect', - }; -}; - -export const isBunkerUrl = (value: string) => value.startsWith('bunker://'); - -export const getBunkerUrl = async (value: string, optionsModal: NostrLoginOptions) => { - if (!value) { - return ''; - } - - if (isBunkerUrl(value)) { - return value; - } - - if (value.includes('@')) { - const [name, domain] = value.toLocaleLowerCase().split('@'); - const origin = optionsModal.devOverrideBunkerOrigin || `https://${domain}`; - const bunkerUrl = `${origin}/.well-known/nostr.json?name=_`; - const userUrl = `${origin}/.well-known/nostr.json?name=${name}`; - const bunker = await fetch(bunkerUrl); - const bunkerData = await bunker.json(); - const bunkerPubkey = bunkerData.names['_']; - const bunkerRelays = bunkerData.nip46[bunkerPubkey]; - const user = await fetch(userUrl); - const userData = await user.json(); - const userPubkey = userData.names[name]; - // console.log({ - // bunkerData, userData, bunkerPubkey, bunkerRelays, userPubkey, - // name, domain, origin - // }) - if (!bunkerRelays.length) { - throw new Error('Bunker relay not provided'); - } - - return `bunker://${userPubkey}?relay=${bunkerRelays[0]}`; - } - - throw new Error('Invalid user name or bunker url'); -}; - -export const checkNip05 = async (nip05: string) => { - let available = false; - let error = ''; - let pubkey = ''; - await (async () => { - if (!nip05 || !nip05.includes('@')) return; - - const [name, domain] = nip05.toLocaleLowerCase().split('@'); - if (!name) return; - - const REGEXP = new RegExp(/^[\w-.]+@([\w-]+\.)+[\w-]{2,8}$/g); - if (!REGEXP.test(nip05)) { - error = 'Invalid name'; - return; - } - - if (!domain) { - error = 'Select service'; - return; - } - - const url = `https://${domain}/.well-known/nostr.json?name=${name.toLowerCase()}`; - try { - const r = await fetch(url); - const d = await r.json(); - if (d.names[name]) { - pubkey = d.names[name]; - return; - } - } catch {} - - available = true; - })(); - - return { - available, - taken: pubkey != '', - error, - pubkey, - }; -}; - -const upgradeInfo = (info: Info | RecentType) => { - if ('typeAuthMethod' in info) delete info['typeAuthMethod']; - - if (!info.authMethod) { - if ('extension' in info && info['extension']) info.authMethod = 'extension'; - else if ('readOnly' in info && info['readOnly']) info.authMethod = 'readOnly'; - else info.authMethod = 'connect'; - } - - if (info.nip05 && isBunkerUrl(info.nip05)) { - info.bunkerUrl = info.nip05; - info.nip05 = ''; - } - - if (info.authMethod === 'connect' && !info.signerPubkey) { - info.signerPubkey = info.pubkey; - } -}; - -export const localStorageAddAccount = (info: Info) => { - // make current - localStorageSetItem(LOCAL_STORE_KEY, JSON.stringify(info)); - - const loggedInAccounts: Info[] = localStorageGetItem(LOGGED_IN_ACCOUNTS) || []; - const recentAccounts: RecentType[] = localStorageGetItem(RECENT_ACCOUNTS) || []; - - // upgrade first - loggedInAccounts.forEach(a => upgradeInfo(a)); - recentAccounts.forEach(a => upgradeInfo(a)); - - // upsert new info into accounts - const accounts: Info[] = loggedInAccounts; - const index = loggedInAccounts.findIndex((el: Info) => el.pubkey === info.pubkey && el.authMethod === info.authMethod); - if (index !== -1) { - accounts[index] = info; - } else { - accounts.push(info); - } - - // remove new info from recent - const recents = recentAccounts.filter(el => el.pubkey !== info.pubkey || el.authMethod !== info.authMethod); - - localStorageSetItem(RECENT_ACCOUNTS, JSON.stringify(recents)); - localStorageSetItem(LOGGED_IN_ACCOUNTS, JSON.stringify(accounts)); -}; - -export const localStorageRemoveCurrentAccount = () => { - const user: Info = localStorageGetItem(LOCAL_STORE_KEY); - if (!user) return; - - // make sure it's valid - upgradeInfo(user); - - // remove secret fields - const recentUser: RecentType = { ...user }; - - // make sure session keys are dropped - // @ts-ignore - delete recentUser['sk']; - // @ts-ignore - delete recentUser['otpData']; - - // get accounts and recent - const loggedInAccounts: Info[] = localStorageGetItem(LOGGED_IN_ACCOUNTS) || []; - const recentsAccounts: RecentType[] = localStorageGetItem(RECENT_ACCOUNTS) || []; - - // upgrade first - loggedInAccounts.forEach(a => upgradeInfo(a)); - recentsAccounts.forEach(a => upgradeInfo(a)); - - const recents: RecentType[] = recentsAccounts; - if (recentUser.authMethod === 'connect' && recentUser.bunkerUrl && recentUser.bunkerUrl.includes('secret=')) { - console.log('nostr login bunker conn with a secret not saved to recent'); - } else if (recentUser.authMethod === 'local') { - console.log('nostr login temporary local keys not save to recent'); - } else { - // upsert to recent - const index = recentsAccounts.findIndex((el: RecentType) => el.pubkey === recentUser.pubkey && el.authMethod === recentUser.authMethod); - if (index !== -1) { - recents[index] = recentUser; - } else { - recents.push(recentUser); - } - } - - // remove from accounts - const accounts = loggedInAccounts.filter(el => el.pubkey !== user.pubkey || el.authMethod !== user.authMethod); - - // update accounts and recent, clear current - localStorageSetItem(RECENT_ACCOUNTS, JSON.stringify(recents)); - localStorageSetItem(LOGGED_IN_ACCOUNTS, JSON.stringify(accounts)); - localStorageRemoveItem(LOCAL_STORE_KEY); -}; - -export const localStorageRemoveRecent = (user: RecentType) => { - const recentsAccounts: RecentType[] = localStorageGetItem(RECENT_ACCOUNTS) || []; - recentsAccounts.forEach(a => upgradeInfo(a)); - const recents = recentsAccounts.filter(el => el.pubkey !== user.pubkey || el.authMethod !== user.authMethod); - localStorageSetItem(RECENT_ACCOUNTS, JSON.stringify(recents)); -}; - -export const localStorageGetRecents = (): RecentType[] => { - const recents: RecentType[] = localStorageGetItem(RECENT_ACCOUNTS) || []; - recents.forEach(r => upgradeInfo(r)); - return recents; -}; - -export const localStorageGetAccounts = (): Info[] => { - const accounts: Info[] = localStorageGetItem(LOGGED_IN_ACCOUNTS) || []; - accounts.forEach(a => upgradeInfo(a)); - return accounts; -}; - -export const localStorageGetCurrent = (): Info | null => { - const info = localStorageGetItem(LOCAL_STORE_KEY); - if (info) upgradeInfo(info); - return info; -}; - -export const setDarkMode = (dark: boolean) => { - localStorageSetItem('nl-dark-mode', dark ? 'true' : 'false'); -}; - -export const getDarkMode = (opt: NostrLoginOptions) => { - const getDarkModeLocal = localStorage.getItem('nl-dark-mode'); - - if (getDarkModeLocal) { - // user already changed it - return Boolean(JSON.parse(getDarkModeLocal)); - } else if (opt.darkMode !== undefined) { - // app provided an option - return opt.darkMode; - } else { - // auto-detect - if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { - return true; - } else { - return false; - } - } -}; - -export const getIcon = async () => { - // FIXME look at meta tags or manifest - return document.location.origin + '/favicon.ico'; -}; diff --git a/packages/auth/src/utils/nip44.ts b/packages/auth/src/utils/nip44.ts deleted file mode 100644 index c597a85..0000000 --- a/packages/auth/src/utils/nip44.ts +++ /dev/null @@ -1,185 +0,0 @@ -import { chacha20 } from "@noble/ciphers/chacha" -import { concatBytes, randomBytes, utf8ToBytes } from "@noble/hashes/utils" -import { equalBytes } from "@noble/ciphers/utils"; -import { secp256k1 } from "@noble/curves/secp256k1" -import { - expand as hkdf_expand, - extract as hkdf_extract, -} from "@noble/hashes/hkdf" -import { sha256 } from "@noble/hashes/sha256" -import { hmac } from "@noble/hashes/hmac"; -import { base64 } from "@scure/base"; -import { getPublicKey } from 'nostr-tools' - -// from https://github.com/nbd-wtf/nostr-tools - -const decoder = new TextDecoder() - -const u = { - minPlaintextSize: 0x0001, // 1b msg => padded to 32b - maxPlaintextSize: 0xffff, // 65535 (64kb-1) => padded to 64kb - - utf8Encode: utf8ToBytes, - utf8Decode(bytes: Uint8Array): string { - return decoder.decode(bytes); - }, - - getConversationKey(privkeyA: string, pubkeyB: string): Uint8Array { - const sharedX = secp256k1 - .getSharedSecret(privkeyA, "02" + pubkeyB) - .subarray(1, 33); - return hkdf_extract(sha256, sharedX, "nip44-v2"); - }, - - getMessageKeys(conversationKey: Uint8Array, nonce: Uint8Array) { - const keys = hkdf_expand(sha256, conversationKey, nonce, 76); - return { - chacha_key: keys.subarray(0, 32), - chacha_nonce: keys.subarray(32, 44), - hmac_key: keys.subarray(44, 76), - }; - }, - - calcPaddedLen(len: number): number { - if (!Number.isSafeInteger(len) || len < 1) - throw new Error("expected positive integer"); - if (len <= 32) return 32; - const nextPower = 1 << (Math.floor(Math.log2(len - 1)) + 1); - const chunk = nextPower <= 256 ? 32 : nextPower / 8; - return chunk * (Math.floor((len - 1) / chunk) + 1); - }, - - writeU16BE(num: number): Uint8Array { - if ( - !Number.isSafeInteger(num) || - num < u.minPlaintextSize || - num > u.maxPlaintextSize - ) - throw new Error( - "invalid plaintext size: must be between 1 and 65535 bytes" - ); - const arr = new Uint8Array(2); - new DataView(arr.buffer).setUint16(0, num, false); - return arr; - }, - - pad(plaintext: string): Uint8Array { - const unpadded = u.utf8Encode(plaintext); - const unpaddedLen = unpadded.length; - const prefix = u.writeU16BE(unpaddedLen); - const suffix = new Uint8Array(u.calcPaddedLen(unpaddedLen) - unpaddedLen); - return concatBytes(prefix, unpadded, suffix); - }, - - unpad(padded: Uint8Array): string { - const unpaddedLen = new DataView(padded.buffer).getUint16(0); - const unpadded = padded.subarray(2, 2 + unpaddedLen); - if ( - unpaddedLen < u.minPlaintextSize || - unpaddedLen > u.maxPlaintextSize || - unpadded.length !== unpaddedLen || - padded.length !== 2 + u.calcPaddedLen(unpaddedLen) - ) - throw new Error("invalid padding"); - return u.utf8Decode(unpadded); - }, - - hmacAad(key: Uint8Array, message: Uint8Array, aad: Uint8Array): Uint8Array { - if (aad.length !== 32) - throw new Error("AAD associated data must be 32 bytes"); - const combined = concatBytes(aad, message); - return hmac(sha256, key, combined); - }, - - // metadata: always 65b (version: 1b, nonce: 32b, max: 32b) - // plaintext: 1b to 0xffff - // padded plaintext: 32b to 0xffff - // ciphertext: 32b+2 to 0xffff+2 - // raw payload: 99 (65+32+2) to 65603 (65+0xffff+2) - // compressed payload (base64): 132b to 87472b - decodePayload(payload: string): { - nonce: Uint8Array; - ciphertext: Uint8Array; - mac: Uint8Array; - } { - if (typeof payload !== "string") - throw new Error("payload must be a valid string"); - const plen = payload.length; - if (plen < 132 || plen > 87472) - throw new Error("invalid payload length: " + plen); - if (payload[0] === "#") throw new Error("unknown encryption version"); - let data: Uint8Array; - try { - data = base64.decode(payload); - } catch (error) { - throw new Error("invalid base64: " + (error as Error).message); - } - const dlen = data.length; - if (dlen < 99 || dlen > 65603) - throw new Error("invalid data length: " + dlen); - const vers = data[0]; - if (vers !== 2) throw new Error("unknown encryption version " + vers); - return { - nonce: data.subarray(1, 33), - ciphertext: data.subarray(33, -32), - mac: data.subarray(-32), - }; - }, -}; - -export function encryptNip44( - plaintext: string, - conversationKey: Uint8Array, - nonce: Uint8Array = randomBytes(32) -): string { - const { chacha_key, chacha_nonce, hmac_key } = u.getMessageKeys( - conversationKey, - nonce - ); - const padded = u.pad(plaintext); - const ciphertext = chacha20(chacha_key, chacha_nonce, padded); - const mac = u.hmacAad(hmac_key, ciphertext, nonce); - return base64.encode( - concatBytes(new Uint8Array([2]), nonce, ciphertext, mac) - ); -} - -export function decryptNip44(payload: string, conversationKey: Uint8Array): string { - const { nonce, ciphertext, mac } = u.decodePayload(payload); - const { chacha_key, chacha_nonce, hmac_key } = u.getMessageKeys( - conversationKey, - nonce - ); - const calculatedMac = u.hmacAad(hmac_key, ciphertext, nonce); - if (!equalBytes(calculatedMac, mac)) throw new Error("invalid MAC"); - const padded = chacha20(chacha_key, chacha_nonce, ciphertext); - return u.unpad(padded); -} - -export class Nip44 { - private cache = new Map() - - public createKey(privkey: string, pubkey: string) { - return u.getConversationKey(privkey, pubkey) - } - - private getKey(privkey: string, pubkey: string, extractable?: boolean) { - const id = getPublicKey(privkey) + pubkey - let cryptoKey = this.cache.get(id) - if (cryptoKey) return cryptoKey - - const key = this.createKey(privkey, pubkey) - this.cache.set(id, key) - return key - } - - public encrypt(privkey: string, pubkey: string, text: string): string { - const key = this.getKey(privkey, pubkey) - return encryptNip44(text, key) - } - - public decrypt(privkey: string, pubkey: string, data: string): string { - const key = this.getKey(privkey, pubkey) - return decryptNip44(data, key) - } -} diff --git a/packages/auth/tsconfig.json b/packages/auth/tsconfig.json deleted file mode 100644 index e560193..0000000 --- a/packages/auth/tsconfig.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "compilerOptions": { - "target": "esnext", - "module": "esnext", - "moduleResolution": "node", - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "strict": true, - "declaration": true, - "outDir": "./dist", - }, - "include": ["src/**/*.ts"], - "exclude": ["node_modules"], -} \ No newline at end of file diff --git a/packages/components/.editorconfig b/packages/components/.editorconfig deleted file mode 100644 index f1cc3ad..0000000 --- a/packages/components/.editorconfig +++ /dev/null @@ -1,15 +0,0 @@ -# http://editorconfig.org - -root = true - -[*] -charset = utf-8 -indent_style = space -indent_size = 2 -end_of_line = lf -insert_final_newline = true -trim_trailing_whitespace = true - -[*.md] -insert_final_newline = false -trim_trailing_whitespace = false diff --git a/packages/components/.gitignore b/packages/components/.gitignore deleted file mode 100644 index c3ea58a..0000000 --- a/packages/components/.gitignore +++ /dev/null @@ -1,26 +0,0 @@ -dist/ -www/ -loader/ - -*~ -*.sw[mnpcod] -*.log -*.lock -*.tmp -*.tmp.* -log.txt -*.sublime-project -*.sublime-workspace - -.stencil/ -.idea/ -.vscode/ -.sass-cache/ -.versions/ -node_modules/ -$RECYCLE.BIN/ - -.DS_Store -Thumbs.db -UserInterfaceState.xcuserstate -.env diff --git a/packages/components/.prettierrc.json b/packages/components/.prettierrc.json deleted file mode 100644 index 7ca3a28..0000000 --- a/packages/components/.prettierrc.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "arrowParens": "avoid", - "bracketSpacing": true, - "jsxBracketSameLine": false, - "jsxSingleQuote": false, - "quoteProps": "consistent", - "printWidth": 180, - "semi": true, - "singleQuote": true, - "tabWidth": 2, - "trailingComma": "all", - "useTabs": false -} diff --git a/packages/components/package.json b/packages/components/package.json deleted file mode 100644 index 77ea017..0000000 --- a/packages/components/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "nostr-login-components", - "version": "1.0.3", - "main": "dist/index.cjs.js", - "module": "dist/index.js", - "es2015": "dist/esm/index.js", - "es2017": "dist/esm/index.js", - "types": "dist/types/index.d.ts", - "collection": "dist/collection/collection-manifest.json", - "collection:main": "dist/collection/index.js", - "author": "a-fralou", - "files": [ - "dist/", - "loader/" - ], - "exports": { - ".": "./dist/components/index.js" - }, - "scripts": { - "build": "stencil build --docs --prod && node post-build-plugin.js", - "dev": "stencil build --dev --watch --serve", - "test": "stencil test --spec --e2e", - "test.watch": "stencil test --spec --e2e --watchAll", - "generate": "stencil generate", - "format": "npx prettier --write src" - }, - "dependencies": { - "@stencil/core": "^4.20.0", - "@stencil/sass": "^3.0.12", - "@stencil/store": "^2.0.16", - "@tailwindcss/forms": "^0.5.7", - "qrcode": "^1.5.4", - "tailwindcss": "^3.4.0", - "tailwindcss-rtl": "^0.9.0" - }, - "devDependencies": { - "@types/jest": "^29.5.6", - "@types/node": "^16.18.11", - "@types/qrcode": "^1.5.5", - "jest": "^29.7.0", - "jest-cli": "^29.7.0", - "prettier": "^3.2.2", - "puppeteer": "21.1.1", - "stencil-tailwind-plugin": "^1.8.0", - "typescript": "^5.3.3", - "workbox-build": "^4.3.1" - }, - "license": "MIT" -} diff --git a/packages/components/post-build-plugin.js b/packages/components/post-build-plugin.js deleted file mode 100644 index 082fc7e..0000000 --- a/packages/components/post-build-plugin.js +++ /dev/null @@ -1,48 +0,0 @@ -const fs = require('fs'); -const path = require('path'); - -const folderPath = './dist/components'; -const cssFilePath = './dist/components/css.js'; -let countFileRead = 0; - -// Function to get all JavaScript files in the directory -function getFilesInDirectory(dir) { - const files = fs.readdirSync(dir); - return files.filter(file => file.endsWith('.js')); // Filter out only .js files -} - -// Function to process a single file -function processFile(filePath, cssContent) { - const fileContent = fs.readFileSync(filePath, 'utf8'); - - // Replace the CSS variable declarations and import them from css.js - const updatedContent = fileContent.replace(/const\s+(\w+Css)\s*=\s*(`[^`]*`|".*?"|'.*?')(?:\s*;|(\s*\/\/.*?))?(?=\s*const|$)/g, (match, varName, varValue) => { - // Save CSS variables and their values in cssContent - if (countFileRead === 0) { - cssContent.push(`export const baseCss = ${varValue};`); - countFileRead = countFileRead + 1; - } - // Return the string with the import from css.js - return `import { baseCss } from './css.js';\nconst ${varName} = baseCss;\n`; - }); - - // Write the modified content back to the file - fs.writeFileSync(filePath, updatedContent, 'utf8'); -} - -// Main function to process all files -function main() { - const cssContent = []; - const files = getFilesInDirectory(folderPath); - - files.forEach(file => { - const filePath = path.join(folderPath, file); - processFile(filePath, cssContent); - }); - - // Write collected CSS variables to css.js - fs.writeFileSync(cssFilePath, cssContent.join('\n'), 'utf8'); - console.log('Done! All CSS variables have been moved to css.js.'); -} - -main(); diff --git a/packages/components/src/components.d.ts b/packages/components/src/components.d.ts deleted file mode 100644 index a6d3ec5..0000000 --- a/packages/components/src/components.d.ts +++ /dev/null @@ -1,929 +0,0 @@ -/* eslint-disable */ -/* tslint:disable */ -/** - * This is an autogenerated file created by the Stencil compiler. - * It contains typing information for all components that exist in this project. - */ -import { HTMLStencilElement, JSXBase } from "@stencil/core/internal"; -import { AuthMethod, BannerNotify, ConnectionString, Info, NlTheme, RecentType } from "./types/index"; -import { OptionType } from "./components/nl-select/nl-select"; -export { AuthMethod, BannerNotify, ConnectionString, Info, NlTheme, RecentType } from "./types/index"; -export { OptionType } from "./components/nl-select/nl-select"; -export namespace Components { - interface ButtonBase { - "darkMode": boolean; - "disabled": boolean; - "theme": NlTheme; - "titleBtn": string; - } - interface NlAuth { - "accounts": Info[]; - "authMethods": AuthMethod[]; - "authUrl": string; - "bunkers": string; - "connectionString": string; - "connectionStringServices": ConnectionString[]; - "darkMode": boolean; - "error": string; - "hasExtension": boolean; - "hasOTP": boolean; - "iframeUrl": string; - "isLoading": boolean; - "isLoadingExtension": boolean; - "isOTP": boolean; - "localSignup": boolean; - "njumpIframe": string; - "recents": RecentType[]; - "signupNjump": boolean; - "startScreen": string; - "theme": NlTheme; - "welcomeDescription": string; - "welcomeTitle": string; - } - interface NlBanner { - "accounts": Info[]; - "darkMode": boolean; - "hiddenMode": boolean; - "isLoading": boolean; - "isOpen": boolean; - "notify": BannerNotify | null; - "theme": NlTheme; - "titleBanner": string; - "userInfo": Info | null; - } - interface NlButton { - "darkMode": boolean; - "disabled": boolean; - "theme": NlTheme; - "titleBtn": string; - } - interface NlChangeAccount { - "accounts": Info[]; - "currentAccount": Info; - "darkMode": boolean; - "theme": 'default' | 'ocean' | 'lemonade' | 'purple'; - } - interface NlConfirmLogout { - "description": string; - "titleModal": string; - } - interface NlConnect { - "authMethods": AuthMethod[]; - "connectionStringServices": ConnectionString[]; - "hasOTP": boolean; - "titleWelcome": string; - } - interface NlDialog { - } - interface NlIframe { - "description": string; - "iframeUrl": string; - "titleModal": string; - } - interface NlImportFlow { - "services": ConnectionString[]; - "titleImport": string; - "titleInfo": string; - } - interface NlInfo { - "darkMode": boolean; - "theme": NlTheme; - } - interface NlInfoExtension { - } - interface NlLoading { - "path": string; - } - interface NlLocalSignup { - "description": string; - "descriptionNjump": string; - "signupNjump": boolean; - "titleSignup": string; - } - interface NlLoginStatus { - "info": RecentType | Info | undefined; - } - interface NlOtpMigrate { - "services": ConnectionString[]; - "textImport": string; - "titleImport": string; - "titleInfo": string; - } - interface NlPreviouslyLogged { - "accounts": Info[]; - "description": string; - "recents": RecentType[]; - "titlePage": string; - } - interface NlSelect { - "darkMode": boolean; - "options": OptionType[]; - "selected": number; - "theme": 'default' | 'ocean' | 'lemonade' | 'purple'; - } - interface NlSignin { - "description": string; - "titleLogin": string; - } - interface NlSigninBunkerUrl { - "description": string; - "titleLogin": string; - } - interface NlSigninConnectionString { - "connectionString": string; - "description": string; - "titleLogin": string; - } - interface NlSigninOtp { - "description": string; - "descriptionOTP": string; - "titleLogin": string; - "titleLoginOTP": string; - } - interface NlSigninReadOnly { - "description": string; - "titleLogin": string; - } - interface NlSignup { - "bunkers": string; - "description": string; - "titleSignup": string; - } - interface NlWelcome { - "description": string; - "titleWelcome": string; - } - interface NlWelcomeSignin { - "authMethods": AuthMethod[]; - "hasExtension": boolean; - "hasOTP": boolean; - "titleWelcome": string; - } - interface NlWelcomeSignup { - "description": string; - "titleWelcome": string; - } -} -export interface NlAuthCustomEvent extends CustomEvent { - detail: T; - target: HTMLNlAuthElement; -} -export interface NlBannerCustomEvent extends CustomEvent { - detail: T; - target: HTMLNlBannerElement; -} -export interface NlChangeAccountCustomEvent extends CustomEvent { - detail: T; - target: HTMLNlChangeAccountElement; -} -export interface NlConfirmLogoutCustomEvent extends CustomEvent { - detail: T; - target: HTMLNlConfirmLogoutElement; -} -export interface NlConnectCustomEvent extends CustomEvent { - detail: T; - target: HTMLNlConnectElement; -} -export interface NlIframeCustomEvent extends CustomEvent { - detail: T; - target: HTMLNlIframeElement; -} -export interface NlImportFlowCustomEvent extends CustomEvent { - detail: T; - target: HTMLNlImportFlowElement; -} -export interface NlLoadingCustomEvent extends CustomEvent { - detail: T; - target: HTMLNlLoadingElement; -} -export interface NlLocalSignupCustomEvent extends CustomEvent { - detail: T; - target: HTMLNlLocalSignupElement; -} -export interface NlOtpMigrateCustomEvent extends CustomEvent { - detail: T; - target: HTMLNlOtpMigrateElement; -} -export interface NlPreviouslyLoggedCustomEvent extends CustomEvent { - detail: T; - target: HTMLNlPreviouslyLoggedElement; -} -export interface NlSelectCustomEvent extends CustomEvent { - detail: T; - target: HTMLNlSelectElement; -} -export interface NlSigninCustomEvent extends CustomEvent { - detail: T; - target: HTMLNlSigninElement; -} -export interface NlSigninBunkerUrlCustomEvent extends CustomEvent { - detail: T; - target: HTMLNlSigninBunkerUrlElement; -} -export interface NlSigninConnectionStringCustomEvent extends CustomEvent { - detail: T; - target: HTMLNlSigninConnectionStringElement; -} -export interface NlSigninOtpCustomEvent extends CustomEvent { - detail: T; - target: HTMLNlSigninOtpElement; -} -export interface NlSigninReadOnlyCustomEvent extends CustomEvent { - detail: T; - target: HTMLNlSigninReadOnlyElement; -} -export interface NlSignupCustomEvent extends CustomEvent { - detail: T; - target: HTMLNlSignupElement; -} -export interface NlWelcomeSigninCustomEvent extends CustomEvent { - detail: T; - target: HTMLNlWelcomeSigninElement; -} -declare global { - interface HTMLButtonBaseElement extends Components.ButtonBase, HTMLStencilElement { - } - var HTMLButtonBaseElement: { - prototype: HTMLButtonBaseElement; - new (): HTMLButtonBaseElement; - }; - interface HTMLNlAuthElementEventMap { - "nlCloseModal": any; - "nlChangeDarkMode": boolean; - "nlNostrConnectDefaultCancel": void; - } - interface HTMLNlAuthElement extends Components.NlAuth, HTMLStencilElement { - addEventListener(type: K, listener: (this: HTMLNlAuthElement, ev: NlAuthCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLNlAuthElement, ev: NlAuthCustomEvent) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; - } - var HTMLNlAuthElement: { - prototype: HTMLNlAuthElement; - new (): HTMLNlAuthElement; - }; - interface HTMLNlBannerElementEventMap { - "handleNotifyConfirmBanner": string; - "handleNotifyConfirmBannerIframe": string; - "handleLoginBanner": string; - "handleLogoutBanner": string; - "handleOpenWelcomeModal": string; - "handleConfirmLogout": string; - "handleImportModal": string; - } - interface HTMLNlBannerElement extends Components.NlBanner, HTMLStencilElement { - addEventListener(type: K, listener: (this: HTMLNlBannerElement, ev: NlBannerCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLNlBannerElement, ev: NlBannerCustomEvent) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; - } - var HTMLNlBannerElement: { - prototype: HTMLNlBannerElement; - new (): HTMLNlBannerElement; - }; - interface HTMLNlButtonElement extends Components.NlButton, HTMLStencilElement { - } - var HTMLNlButtonElement: { - prototype: HTMLNlButtonElement; - new (): HTMLNlButtonElement; - }; - interface HTMLNlChangeAccountElementEventMap { - "handleOpenWelcomeModal": string; - "handleSwitchAccount": Info; - } - interface HTMLNlChangeAccountElement extends Components.NlChangeAccount, HTMLStencilElement { - addEventListener(type: K, listener: (this: HTMLNlChangeAccountElement, ev: NlChangeAccountCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLNlChangeAccountElement, ev: NlChangeAccountCustomEvent) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; - } - var HTMLNlChangeAccountElement: { - prototype: HTMLNlChangeAccountElement; - new (): HTMLNlChangeAccountElement; - }; - interface HTMLNlConfirmLogoutElementEventMap { - "handleLogoutBanner": string; - "handleBackUpModal": string; - "nlCloseModal": any; - } - interface HTMLNlConfirmLogoutElement extends Components.NlConfirmLogout, HTMLStencilElement { - addEventListener(type: K, listener: (this: HTMLNlConfirmLogoutElement, ev: NlConfirmLogoutCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLNlConfirmLogoutElement, ev: NlConfirmLogoutCustomEvent) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; - } - var HTMLNlConfirmLogoutElement: { - prototype: HTMLNlConfirmLogoutElement; - new (): HTMLNlConfirmLogoutElement; - }; - interface HTMLNlConnectElementEventMap { - "nlNostrConnect": ConnectionString; - } - interface HTMLNlConnectElement extends Components.NlConnect, HTMLStencilElement { - addEventListener(type: K, listener: (this: HTMLNlConnectElement, ev: NlConnectCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLNlConnectElement, ev: NlConnectCustomEvent) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; - } - var HTMLNlConnectElement: { - prototype: HTMLNlConnectElement; - new (): HTMLNlConnectElement; - }; - interface HTMLNlDialogElement extends Components.NlDialog, HTMLStencilElement { - } - var HTMLNlDialogElement: { - prototype: HTMLNlDialogElement; - new (): HTMLNlDialogElement; - }; - interface HTMLNlIframeElementEventMap { - "nlCloseModal": any; - } - interface HTMLNlIframeElement extends Components.NlIframe, HTMLStencilElement { - addEventListener(type: K, listener: (this: HTMLNlIframeElement, ev: NlIframeCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLNlIframeElement, ev: NlIframeCustomEvent) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; - } - var HTMLNlIframeElement: { - prototype: HTMLNlIframeElement; - new (): HTMLNlIframeElement; - }; - interface HTMLNlImportFlowElementEventMap { - "nlImportAccount": ConnectionString; - "nlExportKeys": void; - } - interface HTMLNlImportFlowElement extends Components.NlImportFlow, HTMLStencilElement { - addEventListener(type: K, listener: (this: HTMLNlImportFlowElement, ev: NlImportFlowCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLNlImportFlowElement, ev: NlImportFlowCustomEvent) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; - } - var HTMLNlImportFlowElement: { - prototype: HTMLNlImportFlowElement; - new (): HTMLNlImportFlowElement; - }; - interface HTMLNlInfoElement extends Components.NlInfo, HTMLStencilElement { - } - var HTMLNlInfoElement: { - prototype: HTMLNlInfoElement; - new (): HTMLNlInfoElement; - }; - interface HTMLNlInfoExtensionElement extends Components.NlInfoExtension, HTMLStencilElement { - } - var HTMLNlInfoExtensionElement: { - prototype: HTMLNlInfoExtensionElement; - new (): HTMLNlInfoExtensionElement; - }; - interface HTMLNlLoadingElementEventMap { - "stopFetchHandler": boolean; - "handleContinue": boolean; - } - interface HTMLNlLoadingElement extends Components.NlLoading, HTMLStencilElement { - addEventListener(type: K, listener: (this: HTMLNlLoadingElement, ev: NlLoadingCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLNlLoadingElement, ev: NlLoadingCustomEvent) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; - } - var HTMLNlLoadingElement: { - prototype: HTMLNlLoadingElement; - new (): HTMLNlLoadingElement; - }; - interface HTMLNlLocalSignupElementEventMap { - "nlLocalSignup": string; - "nlSignupNjump": void; - "fetchHandler": boolean; - } - interface HTMLNlLocalSignupElement extends Components.NlLocalSignup, HTMLStencilElement { - addEventListener(type: K, listener: (this: HTMLNlLocalSignupElement, ev: NlLocalSignupCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLNlLocalSignupElement, ev: NlLocalSignupCustomEvent) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; - } - var HTMLNlLocalSignupElement: { - prototype: HTMLNlLocalSignupElement; - new (): HTMLNlLocalSignupElement; - }; - interface HTMLNlLoginStatusElement extends Components.NlLoginStatus, HTMLStencilElement { - } - var HTMLNlLoginStatusElement: { - prototype: HTMLNlLoginStatusElement; - new (): HTMLNlLoginStatusElement; - }; - interface HTMLNlOtpMigrateElementEventMap { - "nlImportAccount": ConnectionString; - } - interface HTMLNlOtpMigrateElement extends Components.NlOtpMigrate, HTMLStencilElement { - addEventListener(type: K, listener: (this: HTMLNlOtpMigrateElement, ev: NlOtpMigrateCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLNlOtpMigrateElement, ev: NlOtpMigrateCustomEvent) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; - } - var HTMLNlOtpMigrateElement: { - prototype: HTMLNlOtpMigrateElement; - new (): HTMLNlOtpMigrateElement; - }; - interface HTMLNlPreviouslyLoggedElementEventMap { - "nlSwitchAccount": Info; - "nlLoginRecentAccount": RecentType; - "nlRemoveRecent": RecentType; - } - interface HTMLNlPreviouslyLoggedElement extends Components.NlPreviouslyLogged, HTMLStencilElement { - addEventListener(type: K, listener: (this: HTMLNlPreviouslyLoggedElement, ev: NlPreviouslyLoggedCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLNlPreviouslyLoggedElement, ev: NlPreviouslyLoggedCustomEvent) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; - } - var HTMLNlPreviouslyLoggedElement: { - prototype: HTMLNlPreviouslyLoggedElement; - new (): HTMLNlPreviouslyLoggedElement; - }; - interface HTMLNlSelectElementEventMap { - "selectDomain": string; - } - interface HTMLNlSelectElement extends Components.NlSelect, HTMLStencilElement { - addEventListener(type: K, listener: (this: HTMLNlSelectElement, ev: NlSelectCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLNlSelectElement, ev: NlSelectCustomEvent) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; - } - var HTMLNlSelectElement: { - prototype: HTMLNlSelectElement; - new (): HTMLNlSelectElement; - }; - interface HTMLNlSigninElementEventMap { - "nlLogin": string; - "nlCheckLogin": string; - } - interface HTMLNlSigninElement extends Components.NlSignin, HTMLStencilElement { - addEventListener(type: K, listener: (this: HTMLNlSigninElement, ev: NlSigninCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLNlSigninElement, ev: NlSigninCustomEvent) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; - } - var HTMLNlSigninElement: { - prototype: HTMLNlSigninElement; - new (): HTMLNlSigninElement; - }; - interface HTMLNlSigninBunkerUrlElementEventMap { - "nlLogin": string; - "nlCheckLogin": string; - } - interface HTMLNlSigninBunkerUrlElement extends Components.NlSigninBunkerUrl, HTMLStencilElement { - addEventListener(type: K, listener: (this: HTMLNlSigninBunkerUrlElement, ev: NlSigninBunkerUrlCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLNlSigninBunkerUrlElement, ev: NlSigninBunkerUrlCustomEvent) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; - } - var HTMLNlSigninBunkerUrlElement: { - prototype: HTMLNlSigninBunkerUrlElement; - new (): HTMLNlSigninBunkerUrlElement; - }; - interface HTMLNlSigninConnectionStringElementEventMap { - "nlNostrConnectDefault": void; - } - interface HTMLNlSigninConnectionStringElement extends Components.NlSigninConnectionString, HTMLStencilElement { - addEventListener(type: K, listener: (this: HTMLNlSigninConnectionStringElement, ev: NlSigninConnectionStringCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLNlSigninConnectionStringElement, ev: NlSigninConnectionStringCustomEvent) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; - } - var HTMLNlSigninConnectionStringElement: { - prototype: HTMLNlSigninConnectionStringElement; - new (): HTMLNlSigninConnectionStringElement; - }; - interface HTMLNlSigninOtpElementEventMap { - "nlLoginOTPUser": string; - "nlLoginOTPCode": string; - "nlCheckLogin": string; - } - interface HTMLNlSigninOtpElement extends Components.NlSigninOtp, HTMLStencilElement { - addEventListener(type: K, listener: (this: HTMLNlSigninOtpElement, ev: NlSigninOtpCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLNlSigninOtpElement, ev: NlSigninOtpCustomEvent) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; - } - var HTMLNlSigninOtpElement: { - prototype: HTMLNlSigninOtpElement; - new (): HTMLNlSigninOtpElement; - }; - interface HTMLNlSigninReadOnlyElementEventMap { - "nlLoginReadOnly": string; - "nlCheckLogin": string; - } - interface HTMLNlSigninReadOnlyElement extends Components.NlSigninReadOnly, HTMLStencilElement { - addEventListener(type: K, listener: (this: HTMLNlSigninReadOnlyElement, ev: NlSigninReadOnlyCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLNlSigninReadOnlyElement, ev: NlSigninReadOnlyCustomEvent) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; - } - var HTMLNlSigninReadOnlyElement: { - prototype: HTMLNlSigninReadOnlyElement; - new (): HTMLNlSigninReadOnlyElement; - }; - interface HTMLNlSignupElementEventMap { - "nlSignup": string; - "nlCheckSignup": string; - "fetchHandler": boolean; - } - interface HTMLNlSignupElement extends Components.NlSignup, HTMLStencilElement { - addEventListener(type: K, listener: (this: HTMLNlSignupElement, ev: NlSignupCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLNlSignupElement, ev: NlSignupCustomEvent) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; - } - var HTMLNlSignupElement: { - prototype: HTMLNlSignupElement; - new (): HTMLNlSignupElement; - }; - interface HTMLNlWelcomeElement extends Components.NlWelcome, HTMLStencilElement { - } - var HTMLNlWelcomeElement: { - prototype: HTMLNlWelcomeElement; - new (): HTMLNlWelcomeElement; - }; - interface HTMLNlWelcomeSigninElementEventMap { - "nlLoginExtension": void; - } - interface HTMLNlWelcomeSigninElement extends Components.NlWelcomeSignin, HTMLStencilElement { - addEventListener(type: K, listener: (this: HTMLNlWelcomeSigninElement, ev: NlWelcomeSigninCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLNlWelcomeSigninElement, ev: NlWelcomeSigninCustomEvent) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; - } - var HTMLNlWelcomeSigninElement: { - prototype: HTMLNlWelcomeSigninElement; - new (): HTMLNlWelcomeSigninElement; - }; - interface HTMLNlWelcomeSignupElement extends Components.NlWelcomeSignup, HTMLStencilElement { - } - var HTMLNlWelcomeSignupElement: { - prototype: HTMLNlWelcomeSignupElement; - new (): HTMLNlWelcomeSignupElement; - }; - interface HTMLElementTagNameMap { - "button-base": HTMLButtonBaseElement; - "nl-auth": HTMLNlAuthElement; - "nl-banner": HTMLNlBannerElement; - "nl-button": HTMLNlButtonElement; - "nl-change-account": HTMLNlChangeAccountElement; - "nl-confirm-logout": HTMLNlConfirmLogoutElement; - "nl-connect": HTMLNlConnectElement; - "nl-dialog": HTMLNlDialogElement; - "nl-iframe": HTMLNlIframeElement; - "nl-import-flow": HTMLNlImportFlowElement; - "nl-info": HTMLNlInfoElement; - "nl-info-extension": HTMLNlInfoExtensionElement; - "nl-loading": HTMLNlLoadingElement; - "nl-local-signup": HTMLNlLocalSignupElement; - "nl-login-status": HTMLNlLoginStatusElement; - "nl-otp-migrate": HTMLNlOtpMigrateElement; - "nl-previously-logged": HTMLNlPreviouslyLoggedElement; - "nl-select": HTMLNlSelectElement; - "nl-signin": HTMLNlSigninElement; - "nl-signin-bunker-url": HTMLNlSigninBunkerUrlElement; - "nl-signin-connection-string": HTMLNlSigninConnectionStringElement; - "nl-signin-otp": HTMLNlSigninOtpElement; - "nl-signin-read-only": HTMLNlSigninReadOnlyElement; - "nl-signup": HTMLNlSignupElement; - "nl-welcome": HTMLNlWelcomeElement; - "nl-welcome-signin": HTMLNlWelcomeSigninElement; - "nl-welcome-signup": HTMLNlWelcomeSignupElement; - } -} -declare namespace LocalJSX { - interface ButtonBase { - "darkMode"?: boolean; - "disabled"?: boolean; - "theme"?: NlTheme; - "titleBtn"?: string; - } - interface NlAuth { - "accounts"?: Info[]; - "authMethods"?: AuthMethod[]; - "authUrl"?: string; - "bunkers"?: string; - "connectionString"?: string; - "connectionStringServices"?: ConnectionString[]; - "darkMode"?: boolean; - "error"?: string; - "hasExtension"?: boolean; - "hasOTP"?: boolean; - "iframeUrl"?: string; - "isLoading"?: boolean; - "isLoadingExtension"?: boolean; - "isOTP"?: boolean; - "localSignup"?: boolean; - "njumpIframe"?: string; - "onNlChangeDarkMode"?: (event: NlAuthCustomEvent) => void; - "onNlCloseModal"?: (event: NlAuthCustomEvent) => void; - "onNlNostrConnectDefaultCancel"?: (event: NlAuthCustomEvent) => void; - "recents"?: RecentType[]; - "signupNjump"?: boolean; - "startScreen"?: string; - "theme"?: NlTheme; - "welcomeDescription"?: string; - "welcomeTitle"?: string; - } - interface NlBanner { - "accounts"?: Info[]; - "darkMode"?: boolean; - "hiddenMode"?: boolean; - "isLoading"?: boolean; - "isOpen"?: boolean; - "notify"?: BannerNotify | null; - "onHandleConfirmLogout"?: (event: NlBannerCustomEvent) => void; - "onHandleImportModal"?: (event: NlBannerCustomEvent) => void; - "onHandleLoginBanner"?: (event: NlBannerCustomEvent) => void; - "onHandleLogoutBanner"?: (event: NlBannerCustomEvent) => void; - "onHandleNotifyConfirmBanner"?: (event: NlBannerCustomEvent) => void; - "onHandleNotifyConfirmBannerIframe"?: (event: NlBannerCustomEvent) => void; - "onHandleOpenWelcomeModal"?: (event: NlBannerCustomEvent) => void; - "theme"?: NlTheme; - "titleBanner"?: string; - "userInfo"?: Info | null; - } - interface NlButton { - "darkMode"?: boolean; - "disabled"?: boolean; - "theme"?: NlTheme; - "titleBtn"?: string; - } - interface NlChangeAccount { - "accounts"?: Info[]; - "currentAccount"?: Info; - "darkMode"?: boolean; - "onHandleOpenWelcomeModal"?: (event: NlChangeAccountCustomEvent) => void; - "onHandleSwitchAccount"?: (event: NlChangeAccountCustomEvent) => void; - "theme"?: 'default' | 'ocean' | 'lemonade' | 'purple'; - } - interface NlConfirmLogout { - "description"?: string; - "onHandleBackUpModal"?: (event: NlConfirmLogoutCustomEvent) => void; - "onHandleLogoutBanner"?: (event: NlConfirmLogoutCustomEvent) => void; - "onNlCloseModal"?: (event: NlConfirmLogoutCustomEvent) => void; - "titleModal"?: string; - } - interface NlConnect { - "authMethods"?: AuthMethod[]; - "connectionStringServices"?: ConnectionString[]; - "hasOTP"?: boolean; - "onNlNostrConnect"?: (event: NlConnectCustomEvent) => void; - "titleWelcome"?: string; - } - interface NlDialog { - } - interface NlIframe { - "description"?: string; - "iframeUrl"?: string; - "onNlCloseModal"?: (event: NlIframeCustomEvent) => void; - "titleModal"?: string; - } - interface NlImportFlow { - "onNlExportKeys"?: (event: NlImportFlowCustomEvent) => void; - "onNlImportAccount"?: (event: NlImportFlowCustomEvent) => void; - "services"?: ConnectionString[]; - "titleImport"?: string; - "titleInfo"?: string; - } - interface NlInfo { - "darkMode"?: boolean; - "theme"?: NlTheme; - } - interface NlInfoExtension { - } - interface NlLoading { - "onHandleContinue"?: (event: NlLoadingCustomEvent) => void; - "onStopFetchHandler"?: (event: NlLoadingCustomEvent) => void; - "path"?: string; - } - interface NlLocalSignup { - "description"?: string; - "descriptionNjump"?: string; - "onFetchHandler"?: (event: NlLocalSignupCustomEvent) => void; - "onNlLocalSignup"?: (event: NlLocalSignupCustomEvent) => void; - "onNlSignupNjump"?: (event: NlLocalSignupCustomEvent) => void; - "signupNjump"?: boolean; - "titleSignup"?: string; - } - interface NlLoginStatus { - "info"?: RecentType | Info | undefined; - } - interface NlOtpMigrate { - "onNlImportAccount"?: (event: NlOtpMigrateCustomEvent) => void; - "services"?: ConnectionString[]; - "textImport"?: string; - "titleImport"?: string; - "titleInfo"?: string; - } - interface NlPreviouslyLogged { - "accounts"?: Info[]; - "description"?: string; - "onNlLoginRecentAccount"?: (event: NlPreviouslyLoggedCustomEvent) => void; - "onNlRemoveRecent"?: (event: NlPreviouslyLoggedCustomEvent) => void; - "onNlSwitchAccount"?: (event: NlPreviouslyLoggedCustomEvent) => void; - "recents"?: RecentType[]; - "titlePage"?: string; - } - interface NlSelect { - "darkMode"?: boolean; - "onSelectDomain"?: (event: NlSelectCustomEvent) => void; - "options"?: OptionType[]; - "selected"?: number; - "theme"?: 'default' | 'ocean' | 'lemonade' | 'purple'; - } - interface NlSignin { - "description"?: string; - "onNlCheckLogin"?: (event: NlSigninCustomEvent) => void; - "onNlLogin"?: (event: NlSigninCustomEvent) => void; - "titleLogin"?: string; - } - interface NlSigninBunkerUrl { - "description"?: string; - "onNlCheckLogin"?: (event: NlSigninBunkerUrlCustomEvent) => void; - "onNlLogin"?: (event: NlSigninBunkerUrlCustomEvent) => void; - "titleLogin"?: string; - } - interface NlSigninConnectionString { - "connectionString"?: string; - "description"?: string; - "onNlNostrConnectDefault"?: (event: NlSigninConnectionStringCustomEvent) => void; - "titleLogin"?: string; - } - interface NlSigninOtp { - "description"?: string; - "descriptionOTP"?: string; - "onNlCheckLogin"?: (event: NlSigninOtpCustomEvent) => void; - "onNlLoginOTPCode"?: (event: NlSigninOtpCustomEvent) => void; - "onNlLoginOTPUser"?: (event: NlSigninOtpCustomEvent) => void; - "titleLogin"?: string; - "titleLoginOTP"?: string; - } - interface NlSigninReadOnly { - "description"?: string; - "onNlCheckLogin"?: (event: NlSigninReadOnlyCustomEvent) => void; - "onNlLoginReadOnly"?: (event: NlSigninReadOnlyCustomEvent) => void; - "titleLogin"?: string; - } - interface NlSignup { - "bunkers"?: string; - "description"?: string; - "onFetchHandler"?: (event: NlSignupCustomEvent) => void; - "onNlCheckSignup"?: (event: NlSignupCustomEvent) => void; - "onNlSignup"?: (event: NlSignupCustomEvent) => void; - "titleSignup"?: string; - } - interface NlWelcome { - "description"?: string; - "titleWelcome"?: string; - } - interface NlWelcomeSignin { - "authMethods"?: AuthMethod[]; - "hasExtension"?: boolean; - "hasOTP"?: boolean; - "onNlLoginExtension"?: (event: NlWelcomeSigninCustomEvent) => void; - "titleWelcome"?: string; - } - interface NlWelcomeSignup { - "description"?: string; - "titleWelcome"?: string; - } - interface IntrinsicElements { - "button-base": ButtonBase; - "nl-auth": NlAuth; - "nl-banner": NlBanner; - "nl-button": NlButton; - "nl-change-account": NlChangeAccount; - "nl-confirm-logout": NlConfirmLogout; - "nl-connect": NlConnect; - "nl-dialog": NlDialog; - "nl-iframe": NlIframe; - "nl-import-flow": NlImportFlow; - "nl-info": NlInfo; - "nl-info-extension": NlInfoExtension; - "nl-loading": NlLoading; - "nl-local-signup": NlLocalSignup; - "nl-login-status": NlLoginStatus; - "nl-otp-migrate": NlOtpMigrate; - "nl-previously-logged": NlPreviouslyLogged; - "nl-select": NlSelect; - "nl-signin": NlSignin; - "nl-signin-bunker-url": NlSigninBunkerUrl; - "nl-signin-connection-string": NlSigninConnectionString; - "nl-signin-otp": NlSigninOtp; - "nl-signin-read-only": NlSigninReadOnly; - "nl-signup": NlSignup; - "nl-welcome": NlWelcome; - "nl-welcome-signin": NlWelcomeSignin; - "nl-welcome-signup": NlWelcomeSignup; - } -} -export { LocalJSX as JSX }; -declare module "@stencil/core" { - export namespace JSX { - interface IntrinsicElements { - "button-base": LocalJSX.ButtonBase & JSXBase.HTMLAttributes; - "nl-auth": LocalJSX.NlAuth & JSXBase.HTMLAttributes; - "nl-banner": LocalJSX.NlBanner & JSXBase.HTMLAttributes; - "nl-button": LocalJSX.NlButton & JSXBase.HTMLAttributes; - "nl-change-account": LocalJSX.NlChangeAccount & JSXBase.HTMLAttributes; - "nl-confirm-logout": LocalJSX.NlConfirmLogout & JSXBase.HTMLAttributes; - "nl-connect": LocalJSX.NlConnect & JSXBase.HTMLAttributes; - "nl-dialog": LocalJSX.NlDialog & JSXBase.HTMLAttributes; - "nl-iframe": LocalJSX.NlIframe & JSXBase.HTMLAttributes; - "nl-import-flow": LocalJSX.NlImportFlow & JSXBase.HTMLAttributes; - "nl-info": LocalJSX.NlInfo & JSXBase.HTMLAttributes; - "nl-info-extension": LocalJSX.NlInfoExtension & JSXBase.HTMLAttributes; - "nl-loading": LocalJSX.NlLoading & JSXBase.HTMLAttributes; - "nl-local-signup": LocalJSX.NlLocalSignup & JSXBase.HTMLAttributes; - "nl-login-status": LocalJSX.NlLoginStatus & JSXBase.HTMLAttributes; - "nl-otp-migrate": LocalJSX.NlOtpMigrate & JSXBase.HTMLAttributes; - "nl-previously-logged": LocalJSX.NlPreviouslyLogged & JSXBase.HTMLAttributes; - "nl-select": LocalJSX.NlSelect & JSXBase.HTMLAttributes; - "nl-signin": LocalJSX.NlSignin & JSXBase.HTMLAttributes; - "nl-signin-bunker-url": LocalJSX.NlSigninBunkerUrl & JSXBase.HTMLAttributes; - "nl-signin-connection-string": LocalJSX.NlSigninConnectionString & JSXBase.HTMLAttributes; - "nl-signin-otp": LocalJSX.NlSigninOtp & JSXBase.HTMLAttributes; - "nl-signin-read-only": LocalJSX.NlSigninReadOnly & JSXBase.HTMLAttributes; - "nl-signup": LocalJSX.NlSignup & JSXBase.HTMLAttributes; - "nl-welcome": LocalJSX.NlWelcome & JSXBase.HTMLAttributes; - "nl-welcome-signin": LocalJSX.NlWelcomeSignin & JSXBase.HTMLAttributes; - "nl-welcome-signup": LocalJSX.NlWelcomeSignup & JSXBase.HTMLAttributes; - } - } -} diff --git a/packages/components/src/components/button-base/button-base.css b/packages/components/src/components/button-base/button-base.css deleted file mode 100644 index 86cf585..0000000 --- a/packages/components/src/components/button-base/button-base.css +++ /dev/null @@ -1,27 +0,0 @@ -:host { - display: block; -} - -.animate-spin-loading { - background: var(--qa-dark-color); - animation: spin2 1s linear infinite; -} - -@keyframes spin2 { - to { - transform: rotate(360deg); - } -} - -.active { - animation: blink 0.7s infinite alternate; -} - -@keyframes blink { - 0% { - opacity: 1; - } - 100% { - opacity: 0; - } -} \ No newline at end of file diff --git a/packages/components/src/components/button-base/button-base.tsx b/packages/components/src/components/button-base/button-base.tsx deleted file mode 100644 index 33e4ea4..0000000 --- a/packages/components/src/components/button-base/button-base.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { Component, h, Prop, Element } from '@stencil/core'; -import { NlTheme } from '@/types'; -import { IButton } from '@/types/button'; - -@Component({ - tag: 'button-base', - styleUrl: 'button-base.css', - shadow: false, -}) -export class ButtonBase implements IButton { - @Element() element: HTMLElement; - @Prop({ mutable: true }) theme: NlTheme = 'default'; - @Prop({ mutable: true }) darkMode: boolean = false; - @Prop() titleBtn = 'Open modal'; - @Prop() disabled = false; - - componentDidRender() { - const svgElement = this.element.querySelector('svg'); - - if (svgElement) { - svgElement.classList.add('flex-shrink-0', 'w-4', 'h-4', 'block'); - svgElement.removeAttribute('style'); // hack frieze svg - } - } - - render() { - return ( -
-
- -
- ); - } -} diff --git a/packages/components/src/components/button-base/readme.md b/packages/components/src/components/button-base/readme.md deleted file mode 100644 index c859c67..0000000 --- a/packages/components/src/components/button-base/readme.md +++ /dev/null @@ -1,61 +0,0 @@ -# button-base - - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| ---------- | ----------- | ----------- | -------------------------------------------------------------------- | -------------- | -| `darkMode` | `dark-mode` | | `boolean` | `false` | -| `disabled` | `disabled` | | `boolean` | `false` | -| `theme` | `theme` | | `"crab" \| "default" \| "laan" \| "lemonade" \| "ocean" \| "purple"` | `'default'` | -| `titleBtn` | `title-btn` | | `string` | `'Open modal'` | - - -## Dependencies - -### Used by - - - [nl-banner](../nl-banner) - - [nl-button](../nl-button) - - [nl-confirm-logout](../nl-confirm-logout) - - [nl-connect](../nl-connect) - - [nl-import-flow](../nl-import-flow) - - [nl-loading](../nl-loading) - - [nl-local-signup](../nl-local-signup) - - [nl-otp-migrate](../nl-otp-migrate) - - [nl-signin](../nl-signin) - - [nl-signin-bunker-url](../nl-signin-bunker-url) - - [nl-signin-otp](../nl-signin-otp) - - [nl-signin-read-only](../nl-signin-read-only) - - [nl-signup](../nl-signup) - - [nl-welcome](../nl-welcome) - - [nl-welcome-signin](../nl-welcome-signin) - - [nl-welcome-signup](../nl-welcome-signup) - -### Graph -```mermaid -graph TD; - nl-banner --> button-base - nl-button --> button-base - nl-confirm-logout --> button-base - nl-connect --> button-base - nl-import-flow --> button-base - nl-loading --> button-base - nl-local-signup --> button-base - nl-otp-migrate --> button-base - nl-signin --> button-base - nl-signin-bunker-url --> button-base - nl-signin-otp --> button-base - nl-signin-read-only --> button-base - nl-signup --> button-base - nl-welcome --> button-base - nl-welcome-signin --> button-base - nl-welcome-signup --> button-base - style button-base fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/components/nl-auth/nl-auth.css b/packages/components/src/components/nl-auth/nl-auth.css deleted file mode 100644 index 5d4e87f..0000000 --- a/packages/components/src/components/nl-auth/nl-auth.css +++ /dev/null @@ -1,3 +0,0 @@ -:host { - display: block; -} diff --git a/packages/components/src/components/nl-auth/nl-auth.tsx b/packages/components/src/components/nl-auth/nl-auth.tsx deleted file mode 100644 index 74d04ad..0000000 --- a/packages/components/src/components/nl-auth/nl-auth.tsx +++ /dev/null @@ -1,332 +0,0 @@ -import { Component, Event, EventEmitter, Fragment, h, Prop, Watch } from '@stencil/core'; -import { AuthMethod, ConnectionString, CURRENT_MODULE, Info, NlTheme, RecentType } from '@/types'; -import { state } from '@/store'; - -@Component({ - tag: 'nl-auth', - styleUrl: 'nl-auth.css', - shadow: true, -}) -export class NlAuth { - @Prop({ mutable: true }) theme: NlTheme = 'default'; - @Prop() bunkers: string = ''; - @Prop() startScreen: string = CURRENT_MODULE.WELCOME; - @Prop() authMethods: AuthMethod[] = []; - @Prop() hasExtension: boolean = false; - @Prop() hasOTP: boolean = false; - @Prop() isLoading: boolean = false; - @Prop() isLoadingExtension: boolean = false; - @Prop() isOTP: boolean = false; - @Prop() authUrl: string = ''; - @Prop() iframeUrl: string = ''; - @Prop() error: string = ''; - @Prop() localSignup: boolean = false; - @Prop() signupNjump: boolean = false; - @Prop() njumpIframe: string = ''; - @Prop({ mutable: true }) accounts: Info[] = []; - @Prop({ mutable: true }) recents: RecentType[] = []; - @Prop({ mutable: true }) darkMode: boolean = false; - @Prop() welcomeTitle: string = ''; - @Prop() welcomeDescription: string = ''; - @Prop() connectionString: string = ''; - @Prop() connectionStringServices: ConnectionString[] = []; - - @Event() nlCloseModal: EventEmitter; - @Event() nlChangeDarkMode: EventEmitter; - @Event() nlNostrConnectDefaultCancel: EventEmitter; - - prevPath: string = ''; - - @Watch('isLoading') - watchLoadingHandler(newValue: boolean) { - state.isLoading = newValue; - } - - @Watch('isLoadingExtension') - watchLoadingExtensionHandler(newValue: boolean) { - state.isLoadingExtension = newValue; - } - - @Watch('isOTP') - watchOTPHandler(newValue: boolean) { - state.isOTP = newValue; - } - - @Watch('authUrl') - watchAuthUrlHandler(newValue: string) { - state.authUrl = newValue; - } - - @Watch('iframeUrl') - watchIframeUrlHandler(newValue: string) { - state.iframeUrl = newValue; - } - - @Watch('njumpIframe') - watchNjumpIframeHandler(newValue: string) { - state.njumpIframe = newValue; - } - - @Watch('error') - watchErrorHandler(newValue: string) { - state.error = newValue; - } - - handleClose() { - this.nlCloseModal.emit(); - } - - handleChangeDarkMode() { - this.nlChangeDarkMode.emit(!this.darkMode); - } - - componentWillLoad() { - // init state - state.path = [this.startScreen as CURRENT_MODULE]; - state.error = ''; - state.iframeUrl = ''; - state.authUrl = ''; - state.isLoading = false; - state.isLoadingExtension = false; - state.isOTP = false; - - console.log('path', state.path); - } - - handleClickToBack() { - state.path.pop(); - state.path = [...state.path]; - - // reset - state.isLoading = false; - state.isLoadingExtension = false; - state.authUrl = ''; - state.isOTP = false; - } - - switchSignSignUpStrategy(str: CURRENT_MODULE) { - if (CURRENT_MODULE.LOCAL_SIGNUP === str) { - state.path = [CURRENT_MODULE.WELCOME, CURRENT_MODULE.WELCOME_SIGNUP, str]; - - return; - } - - state.path = [CURRENT_MODULE.WELCOME, str]; - } - - render() { - const classWrapper = `w-full h-full fixed top-0 start-0 z-[80] overflow-x-hidden overflow-y-auto flex items-center ${this.darkMode ? 'dark' : ''}`; - const currentModule = state.path.at(-1); - - if (currentModule !== this.prevPath && this.prevPath === CURRENT_MODULE.CONNECTION_STRING) { - this.nlNostrConnectDefaultCancel.emit(); - } - this.prevPath = currentModule; - - const renderModule = () => { - if (state.isOTP) return ; - - // @ts-ignore - // const t: CURRENT_MODULE = 'import' // lastValuePath - - switch (currentModule) { - case CURRENT_MODULE.WELCOME: - return ; - case CURRENT_MODULE.LOGIN: - return ; - case CURRENT_MODULE.SIGNUP: - return ; - case CURRENT_MODULE.LOCAL_SIGNUP: - return ; - case CURRENT_MODULE.CONFIRM_LOGOUT: - return ; - case CURRENT_MODULE.IMPORT_FLOW: - return ; - case CURRENT_MODULE.IMPORT_OTP: - return ; - case CURRENT_MODULE.INFO: - return ; - case CURRENT_MODULE.EXTENSION: - return ; - case CURRENT_MODULE.LOGIN_READ_ONLY: - return ; - case CURRENT_MODULE.LOGIN_BUNKER_URL: - return ; - case CURRENT_MODULE.LOGIN_OTP: - return ; - case CURRENT_MODULE.WELCOME_LOGIN: - return ; - case CURRENT_MODULE.WELCOME_SIGNUP: - return ; - case CURRENT_MODULE.CONNECTION_STRING: - return ; - case CURRENT_MODULE.CONNECT: - return ; - case CURRENT_MODULE.PREVIOUSLY_LOGGED: - return ; - case CURRENT_MODULE.IFRAME: - return ; - default: - return ; - } - }; - - const showLogin = - state.isOTP || - (currentModule !== CURRENT_MODULE.INFO && - currentModule !== CURRENT_MODULE.CONFIRM_LOGOUT && - currentModule !== CURRENT_MODULE.IMPORT_FLOW && - currentModule !== CURRENT_MODULE.WELCOME && - currentModule !== CURRENT_MODULE.EXTENSION && - currentModule !== CURRENT_MODULE.IFRAME && - currentModule !== CURRENT_MODULE.PREVIOUSLY_LOGGED); - - const showSignup = - currentModule !== CURRENT_MODULE.IFRAME && - (!this.authMethods.length || (!this.localSignup && this.authMethods.includes('connect')) || (this.localSignup && this.authMethods.includes('local'))); - - return ( -
-
-
this.handleClose()} class="absolute top-0 left-0 w-full h-full bg-gray-500 bg-opacity-75 z-[80]" /> - -
-
-
- - - - - -
- -
- - {!state.isLoading && ( - - )} - -
-
- {state.path.length > 1 && !state.isLoading && ( -
- -
- )} - {state.isLoading || state.authUrl ? ( - - ) : ( - - {renderModule()} - {showLogin && ( - - {currentModule === CURRENT_MODULE.WELCOME_SIGNUP || currentModule === CURRENT_MODULE.SIGNUP || currentModule === CURRENT_MODULE.LOCAL_SIGNUP ? ( -
- -
- ) : ( - showSignup && ( -
- -
- ) - )} -
- )} -
- )} -
-
-
- ); - } -} diff --git a/packages/components/src/components/nl-auth/readme.md b/packages/components/src/components/nl-auth/readme.md deleted file mode 100644 index 648f3c0..0000000 --- a/packages/components/src/components/nl-auth/readme.md +++ /dev/null @@ -1,112 +0,0 @@ -# nl-auth - - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| -------------------------- | ---------------------- | ----------- | -------------------------------------------------------------------- | ------------------------ | -| `accounts` | -- | | `Info[]` | `[]` | -| `authMethods` | -- | | `AuthMethod[]` | `[]` | -| `authUrl` | `auth-url` | | `string` | `''` | -| `bunkers` | `bunkers` | | `string` | `''` | -| `connectionString` | `connection-string` | | `string` | `''` | -| `connectionStringServices` | -- | | `ConnectionString[]` | `[]` | -| `darkMode` | `dark-mode` | | `boolean` | `false` | -| `error` | `error` | | `string` | `''` | -| `hasExtension` | `has-extension` | | `boolean` | `false` | -| `hasOTP` | `has-o-t-p` | | `boolean` | `false` | -| `iframeUrl` | `iframe-url` | | `string` | `''` | -| `isLoading` | `is-loading` | | `boolean` | `false` | -| `isLoadingExtension` | `is-loading-extension` | | `boolean` | `false` | -| `isOTP` | `is-o-t-p` | | `boolean` | `false` | -| `localSignup` | `local-signup` | | `boolean` | `false` | -| `njumpIframe` | `njump-iframe` | | `string` | `''` | -| `recents` | -- | | `RecentType[]` | `[]` | -| `signupNjump` | `signup-njump` | | `boolean` | `false` | -| `startScreen` | `start-screen` | | `string` | `CURRENT_MODULE.WELCOME` | -| `theme` | `theme` | | `"crab" \| "default" \| "laan" \| "lemonade" \| "ocean" \| "purple"` | `'default'` | -| `welcomeDescription` | `welcome-description` | | `string` | `''` | -| `welcomeTitle` | `welcome-title` | | `string` | `''` | - - -## Events - -| Event | Description | Type | -| ----------------------------- | ----------- | ---------------------- | -| `nlChangeDarkMode` | | `CustomEvent` | -| `nlCloseModal` | | `CustomEvent` | -| `nlNostrConnectDefaultCancel` | | `CustomEvent` | - - -## Dependencies - -### Depends on - -- [nl-signin-otp](../nl-signin-otp) -- [nl-welcome](../nl-welcome) -- [nl-signin](../nl-signin) -- [nl-signup](../nl-signup) -- [nl-local-signup](../nl-local-signup) -- [nl-confirm-logout](../nl-confirm-logout) -- [nl-import-flow](../nl-import-flow) -- [nl-otp-migrate](../nl-otp-migrate) -- [nl-info](../nl-info) -- [nl-info-extension](../nl-info-extension) -- [nl-signin-read-only](../nl-signin-read-only) -- [nl-signin-bunker-url](../nl-signin-bunker-url) -- [nl-welcome-signin](../nl-welcome-signin) -- [nl-welcome-signup](../nl-welcome-signup) -- [nl-signin-connection-string](../nl-signin-connection-string) -- [nl-connect](../nl-connect) -- [nl-previously-logged](../nl-previously-logged) -- [nl-iframe](../nl-iframe) -- [nl-loading](../nl-loading) - -### Graph -```mermaid -graph TD; - nl-auth --> nl-signin-otp - nl-auth --> nl-welcome - nl-auth --> nl-signin - nl-auth --> nl-signup - nl-auth --> nl-local-signup - nl-auth --> nl-confirm-logout - nl-auth --> nl-import-flow - nl-auth --> nl-otp-migrate - nl-auth --> nl-info - nl-auth --> nl-info-extension - nl-auth --> nl-signin-read-only - nl-auth --> nl-signin-bunker-url - nl-auth --> nl-welcome-signin - nl-auth --> nl-welcome-signup - nl-auth --> nl-signin-connection-string - nl-auth --> nl-connect - nl-auth --> nl-previously-logged - nl-auth --> nl-iframe - nl-auth --> nl-loading - nl-signin-otp --> button-base - nl-welcome --> button-base - nl-signin --> button-base - nl-signup --> nl-select - nl-signup --> button-base - nl-local-signup --> button-base - nl-confirm-logout --> button-base - nl-import-flow --> button-base - nl-import-flow --> nl-select - nl-otp-migrate --> nl-select - nl-otp-migrate --> button-base - nl-signin-read-only --> button-base - nl-signin-bunker-url --> button-base - nl-welcome-signin --> button-base - nl-welcome-signup --> button-base - nl-connect --> button-base - nl-previously-logged --> nl-login-status - nl-loading --> button-base - style nl-auth fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/components/nl-banner/nl-banner.css b/packages/components/src/components/nl-banner/nl-banner.css deleted file mode 100644 index db89229..0000000 --- a/packages/components/src/components/nl-banner/nl-banner.css +++ /dev/null @@ -1,4 +0,0 @@ -:host { - display: block; -} - diff --git a/packages/components/src/components/nl-banner/nl-banner.tsx b/packages/components/src/components/nl-banner/nl-banner.tsx deleted file mode 100644 index f1a7faa..0000000 --- a/packages/components/src/components/nl-banner/nl-banner.tsx +++ /dev/null @@ -1,345 +0,0 @@ -import { Component, Event, EventEmitter, Fragment, h, Prop, State, Watch } from '@stencil/core'; -import { BannerNotify, BannerNotifyMode, Info, METHOD_MODULE, NlTheme } from '@/types'; - -@Component({ - tag: 'nl-banner', - styleUrl: 'nl-banner.css', - shadow: true, -}) -export class NlBanner { - @Prop({ mutable: true }) theme: NlTheme = 'default'; - @Prop({ mutable: true }) darkMode: boolean = false; - @Prop({ mutable: true }) hiddenMode: boolean = false; - @Prop() titleBanner: string = ''; - @Prop({ mutable: true }) isOpen: boolean = false; - - @Prop() isLoading: boolean = false; - @Prop() notify: BannerNotify | null = null; - @Prop() userInfo: Info | null = null; - @Prop({ mutable: true }) accounts: Info[] = []; - - @State() isUserImgError = false; - - @State() domain: string = ''; - @State() mode: BannerNotifyMode = ''; - @State() url: string = ''; - @State() isOpenConfirm: boolean = false; - - @Event() handleNotifyConfirmBanner: EventEmitter; - @Event() handleNotifyConfirmBannerIframe: EventEmitter; - @Event() handleLoginBanner: EventEmitter; - @Event() handleLogoutBanner: EventEmitter; - @Event() handleOpenWelcomeModal: EventEmitter; - @Event() handleConfirmLogout: EventEmitter; - @Event() handleImportModal: EventEmitter; - - @Watch('notify') - watchNotifyHandler(notify: BannerNotify) { - this.isOpen = true; - this.isOpenConfirm = true; - this.domain = this.userInfo?.domain || this.userInfo?.nip05?.split('@')?.[1] || ''; - - this.mode = notify.mode; - this.url = notify.url; - if (!this.mode) { - this.isOpenConfirm = false; - this.isOpen = false; - } - } - - handleOpen() { - if (this.userInfo) { - this.isOpen = true; - } else { - this.handleOpenWelcomeModal.emit(); - } - } - - handleClose() { - this.isOpen = false; - } - - handleLogin() { - this.handleLoginBanner.emit(METHOD_MODULE.LOGIN); - this.handleClose(); - } - - handleSignup() { - this.handleLoginBanner.emit(METHOD_MODULE.SIGNUP); - this.handleClose(); - } - - handleImport() { - this.handleImportModal.emit(); - this.handleClose(); - } - - handleLogout() { - const isBackupKey = localStorage.getItem('backupKey'); - - if (isBackupKey) { - this.handleLogoutBanner.emit(METHOD_MODULE.LOGOUT); - this.handleClose(); - localStorage.removeItem('backupKey'); - - return; - } - - if (this.userInfo.authMethod === 'local') { - this.handleConfirmLogout.emit(); - } else { - this.handleLogoutBanner.emit(METHOD_MODULE.LOGOUT); - } - - this.handleClose(); - } - - handleConfirm() { - switch (this.mode) { - case 'authUrl': - this.handleNotifyConfirmBanner.emit(this.url); - break; - case 'iframeAuthUrl': - this.handleNotifyConfirmBannerIframe.emit(this.url); - break; - } - this.handleClose(); - } - - render() { - const isShowImg = Boolean(this.userInfo?.picture); - const userName = this.userInfo?.name || this.userInfo?.nip05?.split('@')?.[0] || this.userInfo?.pubkey || ''; - const isShowUserName = Boolean(userName); - const isTemporary = this.userInfo && this.userInfo.authMethod === 'local'; - const isBackupKey = localStorage.getItem('backupKey'); - - const defaultUserAvatar = ( - - - - ); - - const content = ( - -
-
this.handleOpen()} class={`flex w-52 h-[46px] items-center pl-[11px]`}> - - - {this.userInfo ? ( -
- {isShowImg ? ( - this.isUserImgError ? ( - defaultUserAvatar - ) : ( - Logo (this.isUserImgError = true)} /> - ) - ) : isShowUserName ? ( - userName[0] - ) : ( - defaultUserAvatar - )} -
- ) : ( -
- - - - - {this.isOpen && ( - - Nostr Login - - )} -
- )} - - {this.isOpen && isShowUserName &&
{userName}
} - {this.isOpen && isShowUserName && } -
-
- - - -
- {this.isOpenConfirm ? ( -
-
- - - -
-

- {this.mode === 'timeout' ? 'Keys not responding, check your key storage app' : `Confirmation required at ${this.domain}`} -

- - {this.mode === 'timeout' ? ( - this.handleClose()} - href={`https://${this.domain}`} - target="_blank" - class="nl-button text-nowrap py-2.5 px-3 w-full inline-flex justify-center items-center gap-x-2 text-sm font-medium rounded-lg disabled:opacity-50 disabled:pointer-events-none dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600" - > - Go to {this.domain} - - ) : this.mode === 'rebind' ? ( - - ) : ( - this.handleConfirm()} titleBtn="Confirm" /> - )} -
- ) : ( -
-
- {this.titleBanner &&

{this.titleBanner}

} - {isTemporary && ( - - {!isBackupKey &&

Your profile may be lost if you close this tab

} -
- this.handleImport()} theme="lemonade" titleBtn="Back up profile" /> -
-
- )} -
- -
- {/* {Boolean(this.listNotifies.length) && ( -
this.handleRetryConfirm()} - class="show-slow border border-yellow-600 text-yellow-600 bg-yellow-100 p-2 rounded-lg mb-2 cursor-pointer w-44 text-xs m-auto text-center" - > - Requests: {this.listNotifies.length} -
- )} */} - {!this.userInfo ? ( -
- this.handleLogin()} titleBtn="Log in"> - - - - - this.handleSignup()} titleBtn="Sign up"> - - - - -
- ) : ( - this.handleLogout()} titleBtn="Log out" /> - )} -
-
- )} -
-
- ); - - // https://gist.github.com/Haprog/848fc451c25da00b540e6d34c301e96a - function deepQuerySelectorAll(selector: string, root?: Element) { - root = root || document.body; - const results = Array.from(root.querySelectorAll(selector)); - const pushNestedResults = function (root) { - deepQuerySelectorAll(selector, root).forEach(elem => { - if (!results.includes(elem)) { - results.push(elem); - } - }); - }; - if (root.shadowRoot) { - pushNestedResults(root.shadowRoot); - } - for (const elem of Array.from(root.querySelectorAll('*'))) { - if (elem.shadowRoot) { - pushNestedResults(elem.shadowRoot); - } - } - return results; - } - - const dialogs = deepQuerySelectorAll('dialog'); - const needDialog = !!dialogs.find(d => (d as HTMLDialogElement).open && !d.classList.contains('nl-banner-dialog')); - - return ( -
-
- {this.isOpenConfirm && needDialog ? ( - -
- {content} -
-
- ) : ( -
- {content} -
- )} -
-
- ); - } -} diff --git a/packages/components/src/components/nl-banner/readme.md b/packages/components/src/components/nl-banner/readme.md deleted file mode 100644 index f04b8f8..0000000 --- a/packages/components/src/components/nl-banner/readme.md +++ /dev/null @@ -1,56 +0,0 @@ -# nl-banner - - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| ------------- | -------------- | ----------- | -------------------------------------------------------------------- | ----------- | -| `accounts` | -- | | `Info[]` | `[]` | -| `darkMode` | `dark-mode` | | `boolean` | `false` | -| `hiddenMode` | `hidden-mode` | | `boolean` | `false` | -| `isLoading` | `is-loading` | | `boolean` | `false` | -| `isOpen` | `is-open` | | `boolean` | `false` | -| `notify` | -- | | `BannerNotify` | `null` | -| `theme` | `theme` | | `"crab" \| "default" \| "laan" \| "lemonade" \| "ocean" \| "purple"` | `'default'` | -| `titleBanner` | `title-banner` | | `string` | `''` | -| `userInfo` | -- | | `Info` | `null` | - - -## Events - -| Event | Description | Type | -| --------------------------------- | ----------- | --------------------- | -| `handleConfirmLogout` | | `CustomEvent` | -| `handleImportModal` | | `CustomEvent` | -| `handleLoginBanner` | | `CustomEvent` | -| `handleLogoutBanner` | | `CustomEvent` | -| `handleNotifyConfirmBanner` | | `CustomEvent` | -| `handleNotifyConfirmBannerIframe` | | `CustomEvent` | -| `handleOpenWelcomeModal` | | `CustomEvent` | - - -## Dependencies - -### Depends on - -- [nl-login-status](../nl-login-status) -- [button-base](../button-base) -- [nl-change-account](../nl-change-account) -- [nl-dialog](../nl-dialog) - -### Graph -```mermaid -graph TD; - nl-banner --> nl-login-status - nl-banner --> button-base - nl-banner --> nl-change-account - nl-banner --> nl-dialog - nl-change-account --> nl-login-status - style nl-banner fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/components/nl-button/nl-button.tsx b/packages/components/src/components/nl-button/nl-button.tsx deleted file mode 100644 index 616c00e..0000000 --- a/packages/components/src/components/nl-button/nl-button.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { Component, h, Prop } from '@stencil/core'; -import { NlTheme } from '@/types'; -import { IButton } from '@/types/button'; - -@Component({ - tag: 'nl-button', - shadow: true, -}) -export class NlButton implements IButton { - @Prop() theme: NlTheme = 'default'; - @Prop() darkMode: boolean = false; - @Prop() titleBtn = 'Open modal'; - @Prop() disabled = false; - - render() { - return ; - } -} diff --git a/packages/components/src/components/nl-button/readme.md b/packages/components/src/components/nl-button/readme.md deleted file mode 100644 index 2e0c06e..0000000 --- a/packages/components/src/components/nl-button/readme.md +++ /dev/null @@ -1,31 +0,0 @@ -# nl-button - - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| ---------- | ----------- | ----------- | -------------------------------------------------------------------- | -------------- | -| `darkMode` | `dark-mode` | | `boolean` | `false` | -| `disabled` | `disabled` | | `boolean` | `false` | -| `theme` | `theme` | | `"crab" \| "default" \| "laan" \| "lemonade" \| "ocean" \| "purple"` | `'default'` | -| `titleBtn` | `title-btn` | | `string` | `'Open modal'` | - - -## Dependencies - -### Depends on - -- [button-base](../button-base) - -### Graph -```mermaid -graph TD; - nl-button --> button-base - style nl-button fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/components/nl-change-account/nl-change-account.css b/packages/components/src/components/nl-change-account/nl-change-account.css deleted file mode 100644 index 5d4e87f..0000000 --- a/packages/components/src/components/nl-change-account/nl-change-account.css +++ /dev/null @@ -1,3 +0,0 @@ -:host { - display: block; -} diff --git a/packages/components/src/components/nl-change-account/nl-change-account.tsx b/packages/components/src/components/nl-change-account/nl-change-account.tsx deleted file mode 100644 index 632f868..0000000 --- a/packages/components/src/components/nl-change-account/nl-change-account.tsx +++ /dev/null @@ -1,154 +0,0 @@ -import { Component, h, Listen, Prop, State, Watch, Element, Event, EventEmitter } from '@stencil/core'; -import { Info } from '@/types'; - -@Component({ - tag: 'nl-change-account', - styleUrl: 'nl-change-account.css', - shadow: false, -}) -export class NLChangeAccount { - @State() isOpen: boolean = false; - @State() options: Info[] = []; - @Prop() accounts: Info[] = []; - @Prop() currentAccount: Info = null; - - @Element() element: HTMLElement; - @Event() handleOpenWelcomeModal: EventEmitter; - @Event() handleSwitchAccount: EventEmitter; - - buttonRef: HTMLButtonElement; - ulRef: HTMLUListElement; - wrapperRef: HTMLDivElement; - - @Listen('click', { target: 'window' }) - handleWindowClick() { - if (this.wrapperRef.querySelector('.listClass')) { - this.isOpen = false; - } - } - - toggleDropdown() { - this.isOpen = !this.isOpen; - this.calculateDropdownPosition(); - } - - @State() mode: boolean = false; - @Prop() darkMode: boolean = false; - @State() themeState: 'default' | 'ocean' | 'lemonade' | 'purple' = 'default'; - @Prop() theme: 'default' | 'ocean' | 'lemonade' | 'purple' = 'default'; - @Watch('theme') - watchPropHandler(newValue: 'default' | 'ocean' | 'lemonade' | 'purple') { - this.themeState = newValue; - } - - @Watch('darkMode') - watchModeHandler(newValue: boolean) { - this.mode = newValue; - } - - @Watch('accounts') - watchAccountsHandler(newValue: Info[]) { - this.options = newValue; - } - - connectedCallback() { - this.themeState = this.theme; - this.mode = this.darkMode; - } - - calculateDropdownPosition() { - if (this.isOpen && this.buttonRef) { - const buttonRect = this.buttonRef.getBoundingClientRect(); - this.ulRef.style.top = `${buttonRect.height}px`; - } - } - - handleChange(el: Info) { - this.handleSwitchAccount.emit(el); - } - - handleOpenModal() { - this.handleOpenWelcomeModal.emit(); - } - - render() { - const listClass = `${this.isOpen ? 'listClass flex flex-col gap-2' : 'hidden'} w-full nl-select-list absolute z-10 left-0 shadow-md rounded-lg p-2 mt-1 after:h-4 after:absolute after:-bottom-4 after:start-0 after:w-full before:h-4 before:absolute before:-top-4 before:start-0 before:w-full`; - const arrowClass = `${this.isOpen ? 'rotate-180' : 'rotate-0'} duration-300 flex-shrink-0 w-4 h-4 text-gray-500`; - const filteredOptions = - this.options && this.currentAccount ? this.options.filter(el => el.pubkey !== this.currentAccount.pubkey || el.authMethod !== this.currentAccount.authMethod) : []; - - return ( -
-
(this.wrapperRef = el)}> - - -
    (this.ulRef = el)} class={listClass}> - {this.options && - filteredOptions.map(el => { - const isShowImg = Boolean(el?.picture); - const userName = el.name || el.nip05 || el.pubkey; - const isShowUserName = Boolean(userName); - - return ( -
  • this.handleChange(el)} class="nl-select-option flex cursor-pointer items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm"> -
    - {isShowImg ? ( - Logo - ) : isShowUserName ? ( - userName[0] - ) : ( - - - - )} -
    - {/*
    {userName}
    */} - -
    -
    {userName}
    - -
    -
  • - ); - })} -
  • -
    this.handleOpenModal()} class="nl-select-option flex cursor-pointer items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm"> -
    - - - -
    - Add profile -
    -
  • -
-
-
- ); - } -} diff --git a/packages/components/src/components/nl-change-account/readme.md b/packages/components/src/components/nl-change-account/readme.md deleted file mode 100644 index fe688f0..0000000 --- a/packages/components/src/components/nl-change-account/readme.md +++ /dev/null @@ -1,44 +0,0 @@ -# nl-change-account - - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| ---------------- | ----------- | ----------- | ------------------------------------------------ | ----------- | -| `accounts` | -- | | `Info[]` | `[]` | -| `currentAccount` | -- | | `Info` | `null` | -| `darkMode` | `dark-mode` | | `boolean` | `false` | -| `theme` | `theme` | | `"default" \| "lemonade" \| "ocean" \| "purple"` | `'default'` | - - -## Events - -| Event | Description | Type | -| ------------------------ | ----------- | --------------------- | -| `handleOpenWelcomeModal` | | `CustomEvent` | -| `handleSwitchAccount` | | `CustomEvent` | - - -## Dependencies - -### Used by - - - [nl-banner](../nl-banner) - -### Depends on - -- [nl-login-status](../nl-login-status) - -### Graph -```mermaid -graph TD; - nl-change-account --> nl-login-status - nl-banner --> nl-change-account - style nl-change-account fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/components/nl-confirm-logout/nl-confirm-logout.css b/packages/components/src/components/nl-confirm-logout/nl-confirm-logout.css deleted file mode 100644 index 5d4e87f..0000000 --- a/packages/components/src/components/nl-confirm-logout/nl-confirm-logout.css +++ /dev/null @@ -1,3 +0,0 @@ -:host { - display: block; -} diff --git a/packages/components/src/components/nl-confirm-logout/nl-confirm-logout.tsx b/packages/components/src/components/nl-confirm-logout/nl-confirm-logout.tsx deleted file mode 100644 index 2b2dc97..0000000 --- a/packages/components/src/components/nl-confirm-logout/nl-confirm-logout.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { Component, Event, EventEmitter, Prop, h } from '@stencil/core'; -import { CURRENT_MODULE, METHOD_MODULE } from '@/types'; -import { state } from '@/store'; - -@Component({ - tag: 'nl-confirm-logout', - styleUrl: 'nl-confirm-logout.css', - shadow: false, -}) -export class NlConfirmLogout { - @Prop() titleModal = "Delete keys?"; - @Prop() description = "Your profile keys are stored in this browser tab and will be deleted if you log out, and your profile will be inaccessible."; - @Event() handleLogoutBanner: EventEmitter; - @Event() handleBackUpModal: EventEmitter; - @Event() nlCloseModal: EventEmitter; - - handleLogout() { - this.handleLogoutBanner.emit(METHOD_MODULE.LOGOUT); - this.nlCloseModal.emit(); - } - - handleCancel() { - this.nlCloseModal.emit(); - } - - handleBackUp() { - state.path = [CURRENT_MODULE.IMPORT_FLOW]; - } - - render() { - return ( -
-

{this.titleModal}

-

{this.description}

- -
- {/* this.handleCancel()} titleBtn="Cancel" /> */} - this.handleBackUp()} titleBtn="Backup keys" theme="lemonade" /> - this.handleLogout()} theme="crab" titleBtn="Logout and delete keys" /> -
-
- ); - } -} diff --git a/packages/components/src/components/nl-confirm-logout/readme.md b/packages/components/src/components/nl-confirm-logout/readme.md deleted file mode 100644 index c2a6507..0000000 --- a/packages/components/src/components/nl-confirm-logout/readme.md +++ /dev/null @@ -1,43 +0,0 @@ -# nl-confirm-logout - - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| ------------- | ------------- | ----------- | -------- | ------------------------------------------------------------------------------------------------------------------------------- | -| `description` | `description` | | `string` | `"Your profile keys are stored in this browser tab and will be deleted if you log out, and your profile will be inaccessible."` | -| `titleModal` | `title-modal` | | `string` | `"Delete keys?"` | - - -## Events - -| Event | Description | Type | -| -------------------- | ----------- | --------------------- | -| `handleBackUpModal` | | `CustomEvent` | -| `handleLogoutBanner` | | `CustomEvent` | -| `nlCloseModal` | | `CustomEvent` | - - -## Dependencies - -### Used by - - - [nl-auth](../nl-auth) - -### Depends on - -- [button-base](../button-base) - -### Graph -```mermaid -graph TD; - nl-confirm-logout --> button-base - nl-auth --> nl-confirm-logout - style nl-confirm-logout fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/components/nl-connect/nl-connect.css b/packages/components/src/components/nl-connect/nl-connect.css deleted file mode 100644 index 5d4e87f..0000000 --- a/packages/components/src/components/nl-connect/nl-connect.css +++ /dev/null @@ -1,3 +0,0 @@ -:host { - display: block; -} diff --git a/packages/components/src/components/nl-connect/nl-connect.tsx b/packages/components/src/components/nl-connect/nl-connect.tsx deleted file mode 100644 index 2061533..0000000 --- a/packages/components/src/components/nl-connect/nl-connect.tsx +++ /dev/null @@ -1,178 +0,0 @@ -import { Component, Event, EventEmitter, Fragment, h, Prop, State } from '@stencil/core'; -import { AuthMethod, ConnectionString, CURRENT_MODULE } from '@/types'; -import { state } from '@/store'; - -@Component({ - tag: 'nl-connect', - styleUrl: 'nl-connect.css', - shadow: false, -}) -export class NlConnect { - @Prop() titleWelcome = 'Connect to key store'; - @Prop() authMethods: AuthMethod[] = []; - @Prop() hasOTP: boolean = false; - @Prop() connectionStringServices: ConnectionString[] = []; - - @State() isOpenAdvancedLogin: boolean = false; - @Event() nlNostrConnect: EventEmitter; - - handleChangeScreen(screen) { - state.path = [...state.path, screen]; - } - - handleOpenAdvanced() { - this.isOpenAdvancedLogin = !this.isOpenAdvancedLogin; - } - - allowAuthMethod(m: AuthMethod) { - return !this.authMethods.length || this.authMethods.includes(m); - } - - componentWillLoad() {} - - handleOpenLink(e: Event, cs: ConnectionString) { - e.preventDefault(); - this.nlNostrConnect.emit(cs); - } - - handleConnectionString() { - this.handleChangeScreen(CURRENT_MODULE.CONNECTION_STRING) - } - - render() { - const arrowClass = `${this.isOpenAdvancedLogin ? 'rotate-180' : 'rotate-0'} duration-300 flex-shrink-0 w-4 h-4 text-blue-500`; - - return ( - -
-

{this.titleWelcome}

-
- - -
-

{state.error}

-
-
- {(this.allowAuthMethod('connect') || this.allowAuthMethod('readOnly')) && ( -
-
this.handleOpenAdvanced()} - class="text-blue-500 mt-3 decoration-dashed cursor-pointer inline-flex gap-2 items-center pb-1 border-dashed border-b-[1px] border-blue-500 text-sm font-light" - > - Advanced - - - -
-
- )} - -
- {/* {this.hasExtension && !this.allowAuthMethod('extension') && this.renderSignInWithExtension()} */} - {this.allowAuthMethod('connect') && ( - this.handleChangeScreen(CURRENT_MODULE.LOGIN)}> - - - - - )} - - {this.allowAuthMethod('connect') && ( - this.handleConnectionString()}> - - - - - - )} - - {this.allowAuthMethod('connect') && ( - this.handleChangeScreen(CURRENT_MODULE.LOGIN_BUNKER_URL)} titleBtn="Bunker URL"> - - - - - )} -
-
-
- ); - } -} diff --git a/packages/components/src/components/nl-connect/readme.md b/packages/components/src/components/nl-connect/readme.md deleted file mode 100644 index 387d56c..0000000 --- a/packages/components/src/components/nl-connect/readme.md +++ /dev/null @@ -1,43 +0,0 @@ -# nl-connect - - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| -------------------------- | --------------- | ----------- | -------------------- | ------------------------ | -| `authMethods` | -- | | `AuthMethod[]` | `[]` | -| `connectionStringServices` | -- | | `ConnectionString[]` | `[]` | -| `hasOTP` | `has-o-t-p` | | `boolean` | `false` | -| `titleWelcome` | `title-welcome` | | `string` | `'Connect to key store'` | - - -## Events - -| Event | Description | Type | -| ---------------- | ----------- | ------------------------------- | -| `nlNostrConnect` | | `CustomEvent` | - - -## Dependencies - -### Used by - - - [nl-auth](../nl-auth) - -### Depends on - -- [button-base](../button-base) - -### Graph -```mermaid -graph TD; - nl-connect --> button-base - nl-auth --> nl-connect - style nl-connect fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/components/nl-dialog/nl-dialog.css b/packages/components/src/components/nl-dialog/nl-dialog.css deleted file mode 100644 index 5d4e87f..0000000 --- a/packages/components/src/components/nl-dialog/nl-dialog.css +++ /dev/null @@ -1,3 +0,0 @@ -:host { - display: block; -} diff --git a/packages/components/src/components/nl-dialog/nl-dialog.tsx b/packages/components/src/components/nl-dialog/nl-dialog.tsx deleted file mode 100644 index 8118ccd..0000000 --- a/packages/components/src/components/nl-dialog/nl-dialog.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { Component, h } from '@stencil/core'; - -@Component({ - tag: 'nl-dialog', - styleUrl: 'nl-dialog.css', - shadow: true, -}) -export class NlDialog { - private dialogElement?: HTMLDialogElement; - - componentDidLoad() { - this.dialogElement?.showModal(); - } - - disconnectedCallback() { - this.dialogElement?.close(); - } - - render() { - return ( - (this.dialogElement = el as HTMLDialogElement)} class={'m-auto nl-banner-dialog'} style={{ border: '0', backgroundColor: 'transparent' }}> - - - ); - } -} diff --git a/packages/components/src/components/nl-dialog/readme.md b/packages/components/src/components/nl-dialog/readme.md deleted file mode 100644 index 0cdc155..0000000 --- a/packages/components/src/components/nl-dialog/readme.md +++ /dev/null @@ -1,23 +0,0 @@ -# nl-dialog - - - - - - -## Dependencies - -### Used by - - - [nl-banner](../nl-banner) - -### Graph -```mermaid -graph TD; - nl-banner --> nl-dialog - style nl-dialog fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/components/nl-iframe/nl-iframe.css b/packages/components/src/components/nl-iframe/nl-iframe.css deleted file mode 100644 index 5d4e87f..0000000 --- a/packages/components/src/components/nl-iframe/nl-iframe.css +++ /dev/null @@ -1,3 +0,0 @@ -:host { - display: block; -} diff --git a/packages/components/src/components/nl-iframe/nl-iframe.tsx b/packages/components/src/components/nl-iframe/nl-iframe.tsx deleted file mode 100644 index 2a17229..0000000 --- a/packages/components/src/components/nl-iframe/nl-iframe.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { Component, Event, EventEmitter, Prop, h } from '@stencil/core'; - -@Component({ - tag: 'nl-iframe', - styleUrl: 'nl-iframe.css', - shadow: false, -}) -export class NlConfirmLogout { - @Prop() titleModal = 'Confirm'; - @Prop() description = 'Your profile keys are stored in this browser tab and will be deleted if you log out, and your profile will be inaccessible.'; - @Prop() iframeUrl = ''; - @Event() nlCloseModal: EventEmitter; - - handleCancel() { - this.nlCloseModal.emit(); - } - - render() { - return ( -
- {/*

{this.titleModal}

-

{this.description}

*/} - -
- {this.iframeUrl && ( - - )} -
-
- ); - } -} diff --git a/packages/components/src/components/nl-iframe/readme.md b/packages/components/src/components/nl-iframe/readme.md deleted file mode 100644 index 440d822..0000000 --- a/packages/components/src/components/nl-iframe/readme.md +++ /dev/null @@ -1,39 +0,0 @@ -# nl-iframe - - - - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| ------------- | ------------- | ----------- | -------- | ------------------------------------------------------------------------------------------------------------------------------- | -| `description` | `description` | | `string` | `'Your profile keys are stored in this browser tab and will be deleted if you log out, and your profile will be inaccessible.'` | -| `iframeUrl` | `iframe-url` | | `string` | `''` | -| `titleModal` | `title-modal` | | `string` | `'Confirm'` | - - -## Events - -| Event | Description | Type | -| -------------- | ----------- | ------------------ | -| `nlCloseModal` | | `CustomEvent` | - - -## Dependencies - -### Used by - - - [nl-auth](../nl-auth) - -### Graph -```mermaid -graph TD; - nl-auth --> nl-iframe - style nl-iframe fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/components/nl-import-flow/nl-import-flow.css b/packages/components/src/components/nl-import-flow/nl-import-flow.css deleted file mode 100644 index 5d4e87f..0000000 --- a/packages/components/src/components/nl-import-flow/nl-import-flow.css +++ /dev/null @@ -1,3 +0,0 @@ -:host { - display: block; -} diff --git a/packages/components/src/components/nl-import-flow/nl-import-flow.tsx b/packages/components/src/components/nl-import-flow/nl-import-flow.tsx deleted file mode 100644 index 34e8caa..0000000 --- a/packages/components/src/components/nl-import-flow/nl-import-flow.tsx +++ /dev/null @@ -1,145 +0,0 @@ -import { Component, h, Fragment, State, Prop, Event, EventEmitter } from '@stencil/core'; -import { state } from '@/store'; -import { ConnectionString } from '@/types'; - -@Component({ - tag: 'nl-import-flow', - styleUrl: 'nl-import-flow.css', - shadow: false, -}) -export class NlImportFlow { - @Prop({ mutable: true }) titleInfo = 'Back up your keys'; - @Prop() titleImport = 'Choose a service'; - @Prop() services: ConnectionString[] = []; - - @State() isContinued = false; - @State() isKeyBackup = false; - - @State() isCopy = false; - - @Event() nlImportAccount: EventEmitter; - @Event() nlExportKeys: EventEmitter; - - handleDomainSelect(event: CustomEvent) { - const s = this.services.find(s => s.domain === event.detail); - state.nlImport = s; - } - - handleCreateAccount(e: MouseEvent) { - e.preventDefault(); - this.nlImportAccount.emit(state.nlImport); - } - - handleContinue() { - this.isContinued = true; - } - - handleContinueKeyBackup() { - this.isKeyBackup = true; - } - - async copyToClipboard() { - this.nlExportKeys.emit(); - this.isCopy = true; - - setTimeout(() => { - this.isCopy = false; - }, 1500); - } - - render() { - if (!this.isContinued && !this.isKeyBackup) { - return ( -
-

{this.titleInfo}

-

- Nostr profiles are controlled by cryptographic keys. -
-
- Your keys are currently only stored in this browser tab, and may be lost if you close it. -
-
- You should backup your keys. -
-
- We recommend to import your keys into a key store service, to protect them and to use with other apps. - {/*
-
- You can also export your keys and save them in your password manager. */} -

-
- this.handleContinue()} titleBtn="Import to key store" /> -
-
- this.handleContinueKeyBackup()} titleBtn="Export keys" /> -
-
- ); - } - - if (this.isKeyBackup) { - return ( -
-

Key export

-

- Copy your keys and store them in a safe place, like a password manager. -
-
- You can sign into other Nostr apps by pasting your keys into them. -
-
- Your keys must be kept secret, never share them with anyone. -

-
-
- this.copyToClipboard()} titleBtn={this.isCopy ? 'Copied!' : 'Copy to clipboard'} /> -
-
-
- ); - } - - const options = this.services.filter(s => s.canImport).map(s => ({ name: s.domain!, value: s.domain! })); - - return ( - -
-

{this.titleImport}

-

- Your Nostr keys will be imported into the service you choose. You will manage your keys on their website. -

-
- -
-
- this.handleDomainSelect(e)} selected={0} options={options}> -
-

Default provider is a fine choice to start with.

- -
-

{state.error}

-
- - this.handleCreateAccount(e)} titleBtn="Start importing"> - {state.isLoading ? ( - - ) : ( - - - - )} - -
-
- ); - } -} diff --git a/packages/components/src/components/nl-import-flow/readme.md b/packages/components/src/components/nl-import-flow/readme.md deleted file mode 100644 index 2786b9a..0000000 --- a/packages/components/src/components/nl-import-flow/readme.md +++ /dev/null @@ -1,45 +0,0 @@ -# nl-import-flow - - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| ------------- | -------------- | ----------- | -------------------- | --------------------- | -| `services` | -- | | `ConnectionString[]` | `[]` | -| `titleImport` | `title-import` | | `string` | `'Choose a service'` | -| `titleInfo` | `title-info` | | `string` | `'Back up your keys'` | - - -## Events - -| Event | Description | Type | -| ----------------- | ----------- | ------------------------------- | -| `nlExportKeys` | | `CustomEvent` | -| `nlImportAccount` | | `CustomEvent` | - - -## Dependencies - -### Used by - - - [nl-auth](../nl-auth) - -### Depends on - -- [button-base](../button-base) -- [nl-select](../nl-select) - -### Graph -```mermaid -graph TD; - nl-import-flow --> button-base - nl-import-flow --> nl-select - nl-auth --> nl-import-flow - style nl-import-flow fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/components/nl-info-extension/nl-info-extension.css b/packages/components/src/components/nl-info-extension/nl-info-extension.css deleted file mode 100644 index 5d4e87f..0000000 --- a/packages/components/src/components/nl-info-extension/nl-info-extension.css +++ /dev/null @@ -1,3 +0,0 @@ -:host { - display: block; -} diff --git a/packages/components/src/components/nl-info-extension/nl-info-extension.tsx b/packages/components/src/components/nl-info-extension/nl-info-extension.tsx deleted file mode 100644 index cf0a3c1..0000000 --- a/packages/components/src/components/nl-info-extension/nl-info-extension.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { Component, h } from '@stencil/core'; -import { state } from '@/store'; - -@Component({ - tag: 'nl-info-extension', - styleUrl: 'nl-info-extension.css', - shadow: false, -}) -export class NlInfoExtension { - render() { - return ( -
- {state.isLoadingExtension ? ( -
-

Signing in...

-
- -
-
-

{state.error}

-
-
- ) : ( -
-

Install browser extension!

-

- Try{' '} - - Alby - - ,{' '} - - nos2x - {' '} - or{' '} - - Nostore - -

-
- )} -
- ); - } -} diff --git a/packages/components/src/components/nl-info-extension/readme.md b/packages/components/src/components/nl-info-extension/readme.md deleted file mode 100644 index 9c83eef..0000000 --- a/packages/components/src/components/nl-info-extension/readme.md +++ /dev/null @@ -1,21 +0,0 @@ -# nl-info-extension - - - - -## Dependencies - -### Used by - - - [nl-auth](../nl-auth) - -### Graph -```mermaid -graph TD; - nl-auth --> nl-info-extension - style nl-info-extension fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/components/nl-info/nl-info.css b/packages/components/src/components/nl-info/nl-info.css deleted file mode 100644 index 5d4e87f..0000000 --- a/packages/components/src/components/nl-info/nl-info.css +++ /dev/null @@ -1,3 +0,0 @@ -:host { - display: block; -} diff --git a/packages/components/src/components/nl-info/nl-info.tsx b/packages/components/src/components/nl-info/nl-info.tsx deleted file mode 100644 index eeaf9b8..0000000 --- a/packages/components/src/components/nl-info/nl-info.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { Component, h, Prop } from '@stencil/core'; -import { NlTheme } from '@/types'; - -@Component({ - tag: 'nl-info', - styleUrl: 'nl-info.css', - shadow: false, -}) -export class NlInfo { - @Prop() theme: NlTheme = 'default'; - @Prop() darkMode: boolean = false; - - render() { - return ( -
- - - - -

- Nostr Login -

-

Version: 1.7.11

-

- Learn more about Nostr{' '} - - here - - .
- This is an{' '} - - open-source - {' '} - tool by{' '} - - Nostr.Band - - . -

-
- ); - } -} diff --git a/packages/components/src/components/nl-info/readme.md b/packages/components/src/components/nl-info/readme.md deleted file mode 100644 index d595d28..0000000 --- a/packages/components/src/components/nl-info/readme.md +++ /dev/null @@ -1,29 +0,0 @@ -# nl-info - - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| ---------- | ----------- | ----------- | -------------------------------------------------------------------- | ----------- | -| `darkMode` | `dark-mode` | | `boolean` | `false` | -| `theme` | `theme` | | `"crab" \| "default" \| "laan" \| "lemonade" \| "ocean" \| "purple"` | `'default'` | - - -## Dependencies - -### Used by - - - [nl-auth](../nl-auth) - -### Graph -```mermaid -graph TD; - nl-auth --> nl-info - style nl-info fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/components/nl-loading/nl-loading.css b/packages/components/src/components/nl-loading/nl-loading.css deleted file mode 100644 index 5d4e87f..0000000 --- a/packages/components/src/components/nl-loading/nl-loading.css +++ /dev/null @@ -1,3 +0,0 @@ -:host { - display: block; -} diff --git a/packages/components/src/components/nl-loading/nl-loading.tsx b/packages/components/src/components/nl-loading/nl-loading.tsx deleted file mode 100644 index 427431a..0000000 --- a/packages/components/src/components/nl-loading/nl-loading.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import { Component, Event, EventEmitter, Prop, h } from '@stencil/core'; -import { state } from '@/store'; -import { CURRENT_MODULE } from '@/types'; - -@Component({ - tag: 'nl-loading', - styleUrl: 'nl-loading.css', - shadow: false, -}) -export class NlLoading { - @Event() stopFetchHandler: EventEmitter; - @Event() handleContinue: EventEmitter; - @Prop() path: string; - - handleStop(e) { - e.preventDefault(); - this.stopFetchHandler.emit(); - } - - handleContinueClick(e) { - e.preventDefault(); - // reset(); - this.handleContinue.emit(); - } - - render() { - let title = 'Connecting...'; - let text = 'Establishing connection to your key storage.'; - if (state.njumpIframe) { - title = ''; - text = ''; - } else if (this.path === CURRENT_MODULE.LOCAL_SIGNUP) { - title = 'Creating...'; - text = 'Publishing your profile on Nostr.'; - } else if (state.authUrl) { - if (state.isLoading) { - title = 'Confirming...'; - text = 'Please confirm the connection in your key storage app.'; - } else { - title = 'Almost ready!'; - text = 'Continue to confirm the connection to your key storage.'; - } - } - - const showButton = this.path !== CURRENT_MODULE.LOCAL_SIGNUP; - const showIframe = !state.isLoading && state.iframeUrl && state.authUrl; - const iframeUrl = state.iframeUrl ? `${state.iframeUrl}?connect=${encodeURIComponent(state.authUrl)}` : ''; - - return ( -
- {title && (

{title}

)} - {text && (

{text}

)} - {!state.njumpIframe && !state.authUrl && state.isLoading && ( -
- -
- )} -
-

{state.error}

-
- {iframeUrl && ( -
- -
- )} - {state.njumpIframe && ( -
- -
- )} - {!showIframe && showButton && ( -
- { - if (state.authUrl && !state.isLoading) { - this.handleContinueClick(e); - } else { - this.handleStop(e); - } - }} - titleBtn={!state.isLoading ? 'Continue' : 'Cancel'} - /> -
- )} -
- ); - } -} diff --git a/packages/components/src/components/nl-loading/readme.md b/packages/components/src/components/nl-loading/readme.md deleted file mode 100644 index c2a6d3a..0000000 --- a/packages/components/src/components/nl-loading/readme.md +++ /dev/null @@ -1,41 +0,0 @@ -# nl-loading - - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| -------- | --------- | ----------- | -------- | ----------- | -| `path` | `path` | | `string` | `undefined` | - - -## Events - -| Event | Description | Type | -| ------------------ | ----------- | ---------------------- | -| `handleContinue` | | `CustomEvent` | -| `stopFetchHandler` | | `CustomEvent` | - - -## Dependencies - -### Used by - - - [nl-auth](../nl-auth) - -### Depends on - -- [button-base](../button-base) - -### Graph -```mermaid -graph TD; - nl-loading --> button-base - nl-auth --> nl-loading - style nl-loading fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/components/nl-local-signup/nl-local-signup.css b/packages/components/src/components/nl-local-signup/nl-local-signup.css deleted file mode 100644 index 5d4e87f..0000000 --- a/packages/components/src/components/nl-local-signup/nl-local-signup.css +++ /dev/null @@ -1,3 +0,0 @@ -:host { - display: block; -} diff --git a/packages/components/src/components/nl-local-signup/nl-local-signup.tsx b/packages/components/src/components/nl-local-signup/nl-local-signup.tsx deleted file mode 100644 index 361dcae..0000000 --- a/packages/components/src/components/nl-local-signup/nl-local-signup.tsx +++ /dev/null @@ -1,100 +0,0 @@ -import { Component, h, Fragment, State, Prop, Event, EventEmitter } from '@stencil/core'; -import { state } from '@/store'; - -@Component({ - tag: 'nl-local-signup', - styleUrl: 'nl-local-signup.css', - shadow: false, -}) -export class NlLocalSignup { - @Prop() titleSignup = 'Create Nostr profile'; - @Prop() description = 'Choose any username, you can always change it later.'; - @Prop() descriptionNjump = 'Proceed to creating your Nostr profile in a new tab.'; - @Prop() signupNjump = false; - - @State() isAvailable = false; - - @Event() nlLocalSignup: EventEmitter; - @Event() nlSignupNjump: EventEmitter; - // @Event() nlCheckSignup: EventEmitter; - @Event() fetchHandler: EventEmitter; - - handleInputChange(event: Event) { - state.nlSignup.signupName = (event.target as HTMLInputElement).value; - // this.nlCheckSignup.emit(`${(event.target as HTMLInputElement).value}@${state.nlSignup.domain}`); - } - - handleCreateAccount(e: MouseEvent) { - e.preventDefault(); - - if (this.signupNjump) { - this.nlSignupNjump.emit(); - } else { - this.nlLocalSignup.emit(`${state.nlSignup.signupName}`); - } - } - - render() { - return ( - -
-

{this.titleSignup}

-

{this.signupNjump ? this.descriptionNjump : this.description}

-
- -
- {!this.signupNjump && ( -
- this.handleInputChange(e)} - type="text" - class="nl-input peer py-3 px-4 ps-11 block w-full border-transparent rounded-lg text-sm disabled:opacity-50 disabled:pointer-events-none dark:border-transparent" - placeholder="Enter username" - value={state.nlSignup.signupName} - /> -
- - - -
-
- )} - -
-

{state.error}

-
- - this.handleCreateAccount(e)} titleBtn={this.signupNjump ? 'Get started' : 'Create profile'}> - {state.isLoading ? ( - - ) : ( - - - - )} - -
-
- ); - } -} diff --git a/packages/components/src/components/nl-local-signup/readme.md b/packages/components/src/components/nl-local-signup/readme.md deleted file mode 100644 index 2774b63..0000000 --- a/packages/components/src/components/nl-local-signup/readme.md +++ /dev/null @@ -1,45 +0,0 @@ -# nl-local-signup - - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| ------------------ | ------------------- | ----------- | --------- | -------------------------------------------------------- | -| `description` | `description` | | `string` | `'Choose any username, you can always change it later.'` | -| `descriptionNjump` | `description-njump` | | `string` | `'Proceed to creating your Nostr profile in a new tab.'` | -| `signupNjump` | `signup-njump` | | `boolean` | `false` | -| `titleSignup` | `title-signup` | | `string` | `'Create Nostr profile'` | - - -## Events - -| Event | Description | Type | -| --------------- | ----------- | ---------------------- | -| `fetchHandler` | | `CustomEvent` | -| `nlLocalSignup` | | `CustomEvent` | -| `nlSignupNjump` | | `CustomEvent` | - - -## Dependencies - -### Used by - - - [nl-auth](../nl-auth) - -### Depends on - -- [button-base](../button-base) - -### Graph -```mermaid -graph TD; - nl-local-signup --> button-base - nl-auth --> nl-local-signup - style nl-local-signup fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/components/nl-login-status/ns-login-status.tsx b/packages/components/src/components/nl-login-status/ns-login-status.tsx deleted file mode 100644 index 9f9994a..0000000 --- a/packages/components/src/components/nl-login-status/ns-login-status.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { Info, RecentType } from '@/types'; -import { Component, h, Prop } from '@stencil/core'; - -@Component({ - tag: 'nl-login-status', - // styleUrl: 'nl-login-status.css', - shadow: false, -}) -export class NlLoginStatus { - @Prop() info: RecentType | Info | undefined; - - render() { - let text = ''; - let color = ''; - if (this.info.authMethod === 'extension') { - text = 'Extension'; - color = 'border-yellow-300 text-yellow-500 bg-yellow-100'; - } else if (this.info.authMethod === 'readOnly') { - text = 'Read only'; - color = 'border-gray-300 text-gray-400 bg-gray-100'; - } else if (this.info.authMethod === 'connect') { - text = 'Connect'; - color = 'border-teal-300 text-teal-600 bg-teal-100'; - } else if (this.info.authMethod === 'local') { - text = 'Temporary'; - color = 'border-red-300 text-red-600 bg-red-100'; - } else if (this.info.authMethod === 'otp') { - text = 'Delegated'; - color = 'border-orange-300 text-orange-600 bg-orange-100'; - } else { - console.log('unknown auth method', this.info); - throw new Error('Unknown auth method'); - } - - return ( -
- {text} -
- ); - } -} diff --git a/packages/components/src/components/nl-login-status/readme.md b/packages/components/src/components/nl-login-status/readme.md deleted file mode 100644 index b07d0c0..0000000 --- a/packages/components/src/components/nl-login-status/readme.md +++ /dev/null @@ -1,32 +0,0 @@ -# nl-login-status - - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| -------- | --------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- | -| `info` | -- | | `Info \| { name?: string; picture?: string; nip05?: string; pubkey: string; bunkerUrl?: string; authMethod: AuthMethod; domain?: string; signerPubkey?: string; }` | `undefined` | - - -## Dependencies - -### Used by - - - [nl-banner](../nl-banner) - - [nl-change-account](../nl-change-account) - - [nl-previously-logged](../nl-previously-logged) - -### Graph -```mermaid -graph TD; - nl-banner --> nl-login-status - nl-change-account --> nl-login-status - nl-previously-logged --> nl-login-status - style nl-login-status fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/components/nl-otp-migrate/nl-otp-migrate.css b/packages/components/src/components/nl-otp-migrate/nl-otp-migrate.css deleted file mode 100644 index 5d4e87f..0000000 --- a/packages/components/src/components/nl-otp-migrate/nl-otp-migrate.css +++ /dev/null @@ -1,3 +0,0 @@ -:host { - display: block; -} diff --git a/packages/components/src/components/nl-otp-migrate/nl-otp-migrate.tsx b/packages/components/src/components/nl-otp-migrate/nl-otp-migrate.tsx deleted file mode 100644 index 7f35dff..0000000 --- a/packages/components/src/components/nl-otp-migrate/nl-otp-migrate.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import { Component, h, Fragment, Prop, Event, EventEmitter } from '@stencil/core'; -import { state } from '@/store'; -import { ConnectionString } from '@/types'; - -@Component({ - tag: 'nl-otp-migrate', - styleUrl: 'nl-otp-migrate.css', - shadow: false, -}) -export class NlImportFlow { - @Prop({ mutable: true }) titleInfo = 'Import keys to storage service'; - @Prop() titleImport = 'Choose a service'; - @Prop() textImport = 'You will be prompted to import keys to the chosen service, and this website will connect to your keys.'; - @Prop() services: ConnectionString[] = []; - - @Event() nlImportAccount: EventEmitter; - - handleDomainSelect(event: CustomEvent) { - const s = this.services.find(s => s.domain === event.detail); - state.nlImport = s; - } - - handleCreateAccount(e: MouseEvent) { - e.preventDefault(); - this.nlImportAccount.emit(state.nlImport); - } - - render() { - const options = this.services.filter(s => s.canImport).map(s => ({ name: s.domain!, value: s.domain! })); - - return ( - -
-

{this.titleImport}

-

{this.textImport}

-
- -
-
- this.handleDomainSelect(e)} selected={0} options={options}> -
-

Default provider is a fine choice to start with.

- -
-

{state.error}

-
- - this.handleCreateAccount(e)} titleBtn="Start importing"> - {state.isLoading ? ( - - ) : ( - - - - )} - -
-
- ); - } -} diff --git a/packages/components/src/components/nl-otp-migrate/readme.md b/packages/components/src/components/nl-otp-migrate/readme.md deleted file mode 100644 index e64a761..0000000 --- a/packages/components/src/components/nl-otp-migrate/readme.md +++ /dev/null @@ -1,47 +0,0 @@ -# nl-otp-migrate - - - - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| ------------- | -------------- | ----------- | -------------------- | ---------------------------------------------------------------------------------------------------------- | -| `services` | -- | | `ConnectionString[]` | `[]` | -| `textImport` | `text-import` | | `string` | `'You will be prompted to import keys to the chosen service, and this website will connect to your keys.'` | -| `titleImport` | `title-import` | | `string` | `'Choose a service'` | -| `titleInfo` | `title-info` | | `string` | `'Import keys to storage service'` | - - -## Events - -| Event | Description | Type | -| ----------------- | ----------- | ------------------------------- | -| `nlImportAccount` | | `CustomEvent` | - - -## Dependencies - -### Used by - - - [nl-auth](../nl-auth) - -### Depends on - -- [nl-select](../nl-select) -- [button-base](../button-base) - -### Graph -```mermaid -graph TD; - nl-otp-migrate --> nl-select - nl-otp-migrate --> button-base - nl-auth --> nl-otp-migrate - style nl-otp-migrate fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/components/nl-previously-logged/nl-previously-logged.css b/packages/components/src/components/nl-previously-logged/nl-previously-logged.css deleted file mode 100644 index db89229..0000000 --- a/packages/components/src/components/nl-previously-logged/nl-previously-logged.css +++ /dev/null @@ -1,4 +0,0 @@ -:host { - display: block; -} - diff --git a/packages/components/src/components/nl-previously-logged/nl-previously-logged.tsx b/packages/components/src/components/nl-previously-logged/nl-previously-logged.tsx deleted file mode 100644 index 73d372b..0000000 --- a/packages/components/src/components/nl-previously-logged/nl-previously-logged.tsx +++ /dev/null @@ -1,191 +0,0 @@ -import { Component, h, Fragment, Prop, Event, EventEmitter, Watch } from '@stencil/core'; -import { CURRENT_MODULE, Info, RecentType } from '@/types'; -import { state } from '@/store'; - -@Component({ - tag: 'nl-previously-logged', - styleUrl: 'nl-previously-logged.css', - shadow: false, -}) -export class NlPreviouslyLogged { - @Prop() titlePage = 'Your profiles'; - @Prop() description = 'Switch between active profiles or choose a recent one for fast login.'; - - @Prop() accounts: Info[] = []; - @Prop() recents: RecentType[] = []; - - @Event() nlSwitchAccount: EventEmitter; - @Event() nlLoginRecentAccount: EventEmitter; - @Event() nlRemoveRecent: EventEmitter; - - handleGoToWelcome() { - state.path = [CURRENT_MODULE.WELCOME]; - } - - switchToWelcomeIfEmpty() { - if (!this.recents.length && !this.accounts.length) { - state.path = [CURRENT_MODULE.WELCOME]; - } - } - - @Watch('accounts') - watchAccounts() { - this.switchToWelcomeIfEmpty(); - } - - @Watch('recents') - watchRecents() { - this.switchToWelcomeIfEmpty(); - } - - handleRemoveRecent(user: Info) { - this.nlRemoveRecent.emit(user); - } - - handleSwitch(el: Info) { - this.nlSwitchAccount.emit(el); - } - - handleLoginRecentAccount(el: RecentType) { - this.nlLoginRecentAccount.emit(el); - } - - render() { - return ( - -
-

{this.titlePage}

-

{this.description}

-
-
- {Boolean(this.accounts.length) && ( -
-

Active profiles

-
    - {this.accounts.map(el => { - const isShowImg = Boolean(el?.picture); - const userName = el.name || el.nip05 || el.pubkey; - const isShowUserName = Boolean(userName); - - return ( -
  • this.handleSwitch(el)} class="group hover:bg-gray-400 flex cursor-pointer gap-x-3.5 py-2 px-3 rounded-lg text-sm items-center justify-between"> -
    -
    -
    -
    -
    -
    - {isShowImg ? ( - Logo - ) : isShowUserName ? ( - userName[0] - ) : ( - - - - )} -
    -
    - -
    -
    {userName}
    - -
    -
    - {/*
    - - - -
    */} -
  • - ); - })} -
-
- )} - - {Boolean(this.recents.length) && ( -
-

Recent profiles

-
    - {this.recents.map(el => { - const isShowImg = Boolean(el?.picture); - const userName = el.name || el.nip05 || el.pubkey; - const isShowUserName = Boolean(userName); - - return ( -
  • this.handleLoginRecentAccount(el)} - class="flex items-center gap-x-3.5 w-full hover:bg-gray-400 flex cursor-pointer items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm justify-between" - > -
    -
    - - - -
    -
    - {isShowImg ? ( - Logo - ) : isShowUserName ? ( - userName[0] - ) : ( - - - - )} -
    -
    -
    -
    {userName}
    - -
    - { - e.stopPropagation(); - this.handleRemoveRecent(el); - }} - xmlns="http://www.w3.org/2000/svg" - fill="none" - viewBox="0 0 24 24" - stroke-width="1.5" - stroke="currentColor" - class="w-full max-w-6 h-6 text-red-500 hover:text-red-600 ml-auto" - > - - -
  • - ); - })} -
-
- )} -
-
- -
-
- ); - } -} diff --git a/packages/components/src/components/nl-previously-logged/readme.md b/packages/components/src/components/nl-previously-logged/readme.md deleted file mode 100644 index 31cf002..0000000 --- a/packages/components/src/components/nl-previously-logged/readme.md +++ /dev/null @@ -1,45 +0,0 @@ -# nl-previously-logged - - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| ------------- | ------------- | ----------- | -------------- | ------------------------------------------------------------------------- | -| `accounts` | -- | | `Info[]` | `[]` | -| `description` | `description` | | `string` | `'Switch between active profiles or choose a recent one for fast login.'` | -| `recents` | -- | | `RecentType[]` | `[]` | -| `titlePage` | `title-page` | | `string` | `'Your profiles'` | - - -## Events - -| Event | Description | Type | -| ---------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `nlLoginRecentAccount` | | `CustomEvent<{ name?: string; picture?: string; nip05?: string; pubkey: string; bunkerUrl?: string; authMethod: AuthMethod; domain?: string; signerPubkey?: string; }>` | -| `nlRemoveRecent` | | `CustomEvent<{ name?: string; picture?: string; nip05?: string; pubkey: string; bunkerUrl?: string; authMethod: AuthMethod; domain?: string; signerPubkey?: string; }>` | -| `nlSwitchAccount` | | `CustomEvent` | - - -## Dependencies - -### Used by - - - [nl-auth](../nl-auth) - -### Depends on - -- [nl-login-status](../nl-login-status) - -### Graph -```mermaid -graph TD; - nl-previously-logged --> nl-login-status - nl-auth --> nl-previously-logged - style nl-previously-logged fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/components/nl-select/nl-select.css b/packages/components/src/components/nl-select/nl-select.css deleted file mode 100644 index 5d4e87f..0000000 --- a/packages/components/src/components/nl-select/nl-select.css +++ /dev/null @@ -1,3 +0,0 @@ -:host { - display: block; -} diff --git a/packages/components/src/components/nl-select/nl-select.tsx b/packages/components/src/components/nl-select/nl-select.tsx deleted file mode 100644 index 27542f7..0000000 --- a/packages/components/src/components/nl-select/nl-select.tsx +++ /dev/null @@ -1,118 +0,0 @@ -import { Component, h, Listen, Prop, State, Watch, Element, Event, EventEmitter } from '@stencil/core'; - -export type OptionType = { - name: string; - value: string; -}; - -@Component({ - tag: 'nl-select', - styleUrl: 'nl-select.css', - shadow: false, -}) -export class NlSelect { - @State() isOpen: boolean = false; - @State() value: OptionType = null; - @Prop() options: OptionType[]; - @Prop() selected: number; - - @Element() element: HTMLElement; - - @Event() selectDomain: EventEmitter; - - buttonRef: HTMLButtonElement; - ulRef: HTMLUListElement; - wrapperRef: HTMLDivElement; - - @Listen('click', { target: 'window' }) - handleWindowClick() { - if (this.wrapperRef.querySelector('.listClass')) { - this.isOpen = false; - } - } - - toggleDropdown() { - this.isOpen = !this.isOpen; - this.calculateDropdownPosition(); - } - - @State() mode: boolean = false; - @Prop() darkMode: boolean = false; - @State() themeState: 'default' | 'ocean' | 'lemonade' | 'purple' = 'default'; - @Prop() theme: 'default' | 'ocean' | 'lemonade' | 'purple' = 'default'; - @Watch('theme') - watchPropHandler(newValue: 'default' | 'ocean' | 'lemonade' | 'purple') { - this.themeState = newValue; - } - - @Watch('darkMode') - watchModeHandler(newValue: boolean) { - this.mode = newValue; - } - - connectedCallback() { - this.themeState = this.theme; - this.mode = this.darkMode; - - this.value = this.options[this.selected]; - this.selectDomain.emit(this.value.value); - } - - calculateDropdownPosition() { - if (this.isOpen && this.buttonRef) { - const buttonRect = this.buttonRef.getBoundingClientRect(); - this.ulRef.style.top = `${buttonRect.height}px`; - } - } - - handleChange(el: OptionType) { - this.value = el; - this.isOpen = false; - - this.selectDomain.emit(this.value.value); - } - - render() { - const listClass = `${this.isOpen ? 'listClass' : 'hidden'} min-w-[15rem] nl-select-list absolute left-0 shadow-md rounded-lg p-2 mt-1 after:h-4 after:absolute after:-bottom-4 after:start-0 after:w-full before:h-4 before:absolute before:-top-4 before:start-0 before:w-full`; - const arrowClass = `${this.isOpen ? 'rotate-180' : 'rotate-0'} duration-300 flex-shrink-0 w-4 h-4 text-gray-500`; - - return ( -
-
(this.wrapperRef = el)}> - - -
    (this.ulRef = el)} class={listClass}> - {this.options.map(el => { - return ( -
  • this.handleChange(el)} class="nl-select-option flex cursor-pointer items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm"> - {el.name} -
  • - ); - })} -
-
-
- ); - } -} diff --git a/packages/components/src/components/nl-select/readme.md b/packages/components/src/components/nl-select/readme.md deleted file mode 100644 index c3131a8..0000000 --- a/packages/components/src/components/nl-select/readme.md +++ /dev/null @@ -1,42 +0,0 @@ -# nl-select - - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| ---------- | ----------- | ----------- | ------------------------------------------------ | ----------- | -| `darkMode` | `dark-mode` | | `boolean` | `false` | -| `options` | -- | | `OptionType[]` | `undefined` | -| `selected` | `selected` | | `number` | `undefined` | -| `theme` | `theme` | | `"default" \| "lemonade" \| "ocean" \| "purple"` | `'default'` | - - -## Events - -| Event | Description | Type | -| -------------- | ----------- | --------------------- | -| `selectDomain` | | `CustomEvent` | - - -## Dependencies - -### Used by - - - [nl-import-flow](../nl-import-flow) - - [nl-otp-migrate](../nl-otp-migrate) - - [nl-signup](../nl-signup) - -### Graph -```mermaid -graph TD; - nl-import-flow --> nl-select - nl-otp-migrate --> nl-select - nl-signup --> nl-select - style nl-select fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/components/nl-signin-bunker-url/nl-signin-bunker-url.css b/packages/components/src/components/nl-signin-bunker-url/nl-signin-bunker-url.css deleted file mode 100644 index 5d4e87f..0000000 --- a/packages/components/src/components/nl-signin-bunker-url/nl-signin-bunker-url.css +++ /dev/null @@ -1,3 +0,0 @@ -:host { - display: block; -} diff --git a/packages/components/src/components/nl-signin-bunker-url/nl-signin-bunker-url.tsx b/packages/components/src/components/nl-signin-bunker-url/nl-signin-bunker-url.tsx deleted file mode 100644 index 36a69c9..0000000 --- a/packages/components/src/components/nl-signin-bunker-url/nl-signin-bunker-url.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import { Component, h, State, Prop, Fragment, Event, EventEmitter } from '@stencil/core'; -import { state } from '@/store'; - -@Component({ - tag: 'nl-signin-bunker-url', - styleUrl: 'nl-signin-bunker-url.css', - shadow: false, -}) -export class NlSigninBunkerUrl { - @Prop() titleLogin = 'Connect with bunker url'; - @Prop() description = 'Please enter a bunker url provided by key store.'; - @State() isGood = false; - - @Event() nlLogin: EventEmitter; - @Event() nlCheckLogin: EventEmitter; - - handleInputChange(event: Event) { - state.nlSigninBunkerUrl.loginName = (event.target as HTMLInputElement).value; - - this.nlCheckLogin.emit((event.target as HTMLInputElement).value); - } - - handleLogin(e: MouseEvent) { - e.preventDefault(); - - this.nlLogin.emit(state.nlSigninBunkerUrl.loginName); - } - - render() { - return ( - -
-

{this.titleLogin}

-

{this.description}

-
- -
-
- this.handleInputChange(e)} - type="text" - class="nl-input peer py-3 px-4 ps-11 block w-full border-transparent rounded-lg text-sm disabled:opacity-50 disabled:pointer-events-none dark:border-transparent" - placeholder="bunker://..." - value={state.nlSigninBunkerUrl.loginName} - /> -
- - - -
-
- -
-

{state.error}

-
- - this.handleLogin(e)}> - {state.isLoading ? ( - - ) : ( - - - - )} - -
-
- ); - } -} diff --git a/packages/components/src/components/nl-signin-bunker-url/readme.md b/packages/components/src/components/nl-signin-bunker-url/readme.md deleted file mode 100644 index 3887f98..0000000 --- a/packages/components/src/components/nl-signin-bunker-url/readme.md +++ /dev/null @@ -1,42 +0,0 @@ -# nl-signin-bunker-url - - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| ------------- | ------------- | ----------- | -------- | ---------------------------------------------------- | -| `description` | `description` | | `string` | `'Please enter a bunker url provided by key store.'` | -| `titleLogin` | `title-login` | | `string` | `'Connect with bunker url'` | - - -## Events - -| Event | Description | Type | -| -------------- | ----------- | --------------------- | -| `nlCheckLogin` | | `CustomEvent` | -| `nlLogin` | | `CustomEvent` | - - -## Dependencies - -### Used by - - - [nl-auth](../nl-auth) - -### Depends on - -- [button-base](../button-base) - -### Graph -```mermaid -graph TD; - nl-signin-bunker-url --> button-base - nl-auth --> nl-signin-bunker-url - style nl-signin-bunker-url fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/components/nl-signin-connection-string/nl-signin-connection-string.css b/packages/components/src/components/nl-signin-connection-string/nl-signin-connection-string.css deleted file mode 100644 index 5d4e87f..0000000 --- a/packages/components/src/components/nl-signin-connection-string/nl-signin-connection-string.css +++ /dev/null @@ -1,3 +0,0 @@ -:host { - display: block; -} diff --git a/packages/components/src/components/nl-signin-connection-string/nl-signin-connection-string.tsx b/packages/components/src/components/nl-signin-connection-string/nl-signin-connection-string.tsx deleted file mode 100644 index 7f25149..0000000 --- a/packages/components/src/components/nl-signin-connection-string/nl-signin-connection-string.tsx +++ /dev/null @@ -1,111 +0,0 @@ -import { Component, h, Prop, Fragment, State, Event, EventEmitter } from '@stencil/core'; -import QRCode from 'qrcode'; - -@Component({ - tag: 'nl-signin-connection-string', - styleUrl: 'nl-signin-connection-string.css', - shadow: false, -}) -export class NlSigninConnectionString { - @Prop() titleLogin = 'Connection string'; - @Prop() description = 'Scan or copy the connection string with key store app'; - @Prop() connectionString = ''; - @State() isCopy = false; - @Event() nlNostrConnectDefault: EventEmitter; - - private canvasElement: HTMLCanvasElement; - - componentDidLoad() { - this.nlNostrConnectDefault.emit(); - this.generateQRCode(); - } - - async generateQRCode() { - if (this.connectionString && this.canvasElement) { - try { - await QRCode.toCanvas(this.canvasElement, this.connectionString); - } catch (error) { - console.error('Error generating QR Code:', error); - } - } - } - - async copyToClipboard() { - try { - await navigator.clipboard.writeText(this.connectionString); - - this.isCopy = true; - - setTimeout(() => { - this.isCopy = false; - }, 1500); - } catch (err) { - console.error('Failed to copy connectionString: ', err); - } - } - - render() { - return ( - -
-

{this.titleLogin}

-

{this.description}

-
- - (this.canvasElement = el as HTMLCanvasElement)}> - -
-
-
- -
- - - - -
- - {this.isCopy ? ( -
- - - -
- ) : ( -
this.copyToClipboard()}> - - - -
- )} -
- -
- - Waiting for connection -
-
-
-
- ); - } -} diff --git a/packages/components/src/components/nl-signin-connection-string/readme.md b/packages/components/src/components/nl-signin-connection-string/readme.md deleted file mode 100644 index 9d161d3..0000000 --- a/packages/components/src/components/nl-signin-connection-string/readme.md +++ /dev/null @@ -1,37 +0,0 @@ -# nl-signin-connection-string - - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| ------------------ | ------------------- | ----------- | -------- | --------------------------------------------------------- | -| `connectionString` | `connection-string` | | `string` | `''` | -| `description` | `description` | | `string` | `'Scan or copy the connection string with key store app'` | -| `titleLogin` | `title-login` | | `string` | `'Connection string'` | - - -## Events - -| Event | Description | Type | -| ----------------------- | ----------- | ------------------- | -| `nlNostrConnectDefault` | | `CustomEvent` | - - -## Dependencies - -### Used by - - - [nl-auth](../nl-auth) - -### Graph -```mermaid -graph TD; - nl-auth --> nl-signin-connection-string - style nl-signin-connection-string fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/components/nl-signin-otp/nl-signin-otp.css b/packages/components/src/components/nl-signin-otp/nl-signin-otp.css deleted file mode 100644 index 5d4e87f..0000000 --- a/packages/components/src/components/nl-signin-otp/nl-signin-otp.css +++ /dev/null @@ -1,3 +0,0 @@ -:host { - display: block; -} diff --git a/packages/components/src/components/nl-signin-otp/nl-signin-otp.tsx b/packages/components/src/components/nl-signin-otp/nl-signin-otp.tsx deleted file mode 100644 index 3cfe047..0000000 --- a/packages/components/src/components/nl-signin-otp/nl-signin-otp.tsx +++ /dev/null @@ -1,89 +0,0 @@ -import { Component, h, State, Prop, Fragment, Event, EventEmitter } from '@stencil/core'; -import { state } from '@/store'; - -@Component({ - tag: 'nl-signin-otp', - styleUrl: 'nl-signin-otp.css', - shadow: false, -}) -export class NlSigninOtp { - @Prop() titleLogin = 'Log in with DM'; - @Prop() description = 'Please enter your user name or npub, and we will send you a direct message with a one-time code.'; - @Prop() titleLoginOTP = 'Enter the code'; - @Prop() descriptionOTP = 'Please enter the one-time code we sent to you as a direct message on Nostr.'; - @State() isGood = false; - - @Event() nlLoginOTPUser: EventEmitter; - @Event() nlLoginOTPCode: EventEmitter; - @Event() nlCheckLogin: EventEmitter; - - handleInputChange(event: Event) { - if (!state.isOTP) { - state.nlSigninOTP.loginName = (event.target as HTMLInputElement).value; - this.nlCheckLogin.emit(state.nlSigninOTP.loginName); - } else { - state.nlSigninOTP.code = (event.target as HTMLInputElement).value; - } - } - - handleLogin(e: MouseEvent) { - e.preventDefault(); - if (state.isOTP) this.nlLoginOTPCode.emit(state.nlSigninOTP.code); - else this.nlLoginOTPUser.emit(state.nlSigninOTP.loginName); - } - - render() { - return ( - -
-

{state.isOTP ? this.titleLoginOTP : this.titleLogin}

-

{state.isOTP ? this.descriptionOTP : this.description}

-
- -
-
- this.handleInputChange(e)} - type="text" - class="nl-input peer py-3 px-4 ps-11 block w-full border-transparent rounded-lg text-sm disabled:opacity-50 disabled:pointer-events-none dark:border-transparent" - placeholder={state.isOTP ? 'code from direct message' : 'npub or name@domain'} - value={state.isOTP ? state.nlSigninOTP.code : state.nlSigninOTP.loginName} - /> -
- - - - -
-
- -
-

{state.error}

-
- - this.handleLogin(e)}> - {state.isLoading && ( - - )} - -
-
- ); - } -} diff --git a/packages/components/src/components/nl-signin-otp/readme.md b/packages/components/src/components/nl-signin-otp/readme.md deleted file mode 100644 index 7c1c7d4..0000000 --- a/packages/components/src/components/nl-signin-otp/readme.md +++ /dev/null @@ -1,45 +0,0 @@ -# nl-signin-otp - - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| ---------------- | ------------------- | ----------- | -------- | ---------------------------------------------------------------------------------------------------- | -| `description` | `description` | | `string` | `'Please enter your user name or npub, and we will send you a direct message with a one-time code.'` | -| `descriptionOTP` | `description-o-t-p` | | `string` | `'Please enter the one-time code we sent to you as a direct message on Nostr.'` | -| `titleLogin` | `title-login` | | `string` | `'Log in with DM'` | -| `titleLoginOTP` | `title-login-o-t-p` | | `string` | `'Enter the code'` | - - -## Events - -| Event | Description | Type | -| ---------------- | ----------- | --------------------- | -| `nlCheckLogin` | | `CustomEvent` | -| `nlLoginOTPCode` | | `CustomEvent` | -| `nlLoginOTPUser` | | `CustomEvent` | - - -## Dependencies - -### Used by - - - [nl-auth](../nl-auth) - -### Depends on - -- [button-base](../button-base) - -### Graph -```mermaid -graph TD; - nl-signin-otp --> button-base - nl-auth --> nl-signin-otp - style nl-signin-otp fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/components/nl-signin-read-only/nl-signin-read-only.css b/packages/components/src/components/nl-signin-read-only/nl-signin-read-only.css deleted file mode 100644 index 5d4e87f..0000000 --- a/packages/components/src/components/nl-signin-read-only/nl-signin-read-only.css +++ /dev/null @@ -1,3 +0,0 @@ -:host { - display: block; -} diff --git a/packages/components/src/components/nl-signin-read-only/nl-signin-read-only.tsx b/packages/components/src/components/nl-signin-read-only/nl-signin-read-only.tsx deleted file mode 100644 index 183926e..0000000 --- a/packages/components/src/components/nl-signin-read-only/nl-signin-read-only.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import { Component, h, State, Prop, Fragment, Event, EventEmitter } from '@stencil/core'; -import { state } from '@/store'; - -@Component({ - tag: 'nl-signin-read-only', - styleUrl: 'nl-signin-read-only.css', - shadow: false, -}) -export class NlSigninReadOnly { - @Prop() titleLogin = 'Log in to read only'; - @Prop() description = 'Please enter the user name or npub of any Nostr user.'; - @State() isGood = false; - - @Event() nlLoginReadOnly: EventEmitter; - @Event() nlCheckLogin: EventEmitter; - - handleInputChange(event: Event) { - state.nlSigninReadOnly.loginName = (event.target as HTMLInputElement).value; - this.nlCheckLogin.emit((event.target as HTMLInputElement).value); // .emit(this.loginName); - } - - handleLogin(e: MouseEvent) { - e.preventDefault(); - this.nlLoginReadOnly.emit(state.nlSigninReadOnly.loginName); - } - - render() { - return ( - -
-

{this.titleLogin}

-

{this.description}

-
- -
-
- this.handleInputChange(e)} - type="text" - class="nl-input peer py-3 px-4 ps-11 block w-full border-transparent rounded-lg text-sm disabled:opacity-50 disabled:pointer-events-none dark:border-transparent" - placeholder="npub or name@domain" - value={state.nlSigninReadOnly.loginName} - /> -
- - - - -
-
- -
-

{state.error}

-
- - this.handleLogin(e)}> - {state.isLoading && ( - - )} - -
-
- ); - } -} diff --git a/packages/components/src/components/nl-signin-read-only/readme.md b/packages/components/src/components/nl-signin-read-only/readme.md deleted file mode 100644 index a0dd20f..0000000 --- a/packages/components/src/components/nl-signin-read-only/readme.md +++ /dev/null @@ -1,42 +0,0 @@ -# nl-signin-read-only - - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| ------------- | ------------- | ----------- | -------- | --------------------------------------------------------- | -| `description` | `description` | | `string` | `'Please enter the user name or npub of any Nostr user.'` | -| `titleLogin` | `title-login` | | `string` | `'Log in to read only'` | - - -## Events - -| Event | Description | Type | -| ----------------- | ----------- | --------------------- | -| `nlCheckLogin` | | `CustomEvent` | -| `nlLoginReadOnly` | | `CustomEvent` | - - -## Dependencies - -### Used by - - - [nl-auth](../nl-auth) - -### Depends on - -- [button-base](../button-base) - -### Graph -```mermaid -graph TD; - nl-signin-read-only --> button-base - nl-auth --> nl-signin-read-only - style nl-signin-read-only fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/components/nl-signin/nl-signin.css b/packages/components/src/components/nl-signin/nl-signin.css deleted file mode 100644 index 5d4e87f..0000000 --- a/packages/components/src/components/nl-signin/nl-signin.css +++ /dev/null @@ -1,3 +0,0 @@ -:host { - display: block; -} diff --git a/packages/components/src/components/nl-signin/nl-signin.tsx b/packages/components/src/components/nl-signin/nl-signin.tsx deleted file mode 100644 index ead4a6a..0000000 --- a/packages/components/src/components/nl-signin/nl-signin.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import { Component, h, State, Prop, Fragment, Event, EventEmitter } from '@stencil/core'; -import { state } from '@/store'; - -@Component({ - tag: 'nl-signin', - styleUrl: 'nl-signin.css', - shadow: false, -}) -export class NlSignin { - @Prop() titleLogin = 'Connect to key store'; - @Prop() description = 'Please enter your user name.'; - @State() isGood = false; - - @Event() nlLogin: EventEmitter; - @Event() nlCheckLogin: EventEmitter; - - handleInputChange(event: Event) { - state.nlSignin.loginName = (event.target as HTMLInputElement).value; - this.nlCheckLogin.emit((event.target as HTMLInputElement).value); - } - - handleLogin(e: MouseEvent) { - e.preventDefault(); - - this.nlLogin.emit(state.nlSignin.loginName); - } - - render() { - return ( - -
-

{this.titleLogin}

-

{this.description}

-
- -
-
- this.handleInputChange(e)} - type="text" - class="nl-input peer py-3 px-4 ps-11 block w-full border-transparent rounded-lg text-sm disabled:opacity-50 disabled:pointer-events-none dark:border-transparent" - placeholder="name@domain.com" - value={state.nlSignin.loginName} - /> -
- {/* - - */} - - - -
-
- -
-

{state.error}

-
- - this.handleLogin(e)}> - {state.isLoading ? ( - - ) : ( - - - - )} - -
-
- ); - } -} diff --git a/packages/components/src/components/nl-signin/readme.md b/packages/components/src/components/nl-signin/readme.md deleted file mode 100644 index 2fd282c..0000000 --- a/packages/components/src/components/nl-signin/readme.md +++ /dev/null @@ -1,42 +0,0 @@ -# nl-signin - - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| ------------- | ------------- | ----------- | -------- | -------------------------------- | -| `description` | `description` | | `string` | `'Please enter your user name.'` | -| `titleLogin` | `title-login` | | `string` | `'Connect to key store'` | - - -## Events - -| Event | Description | Type | -| -------------- | ----------- | --------------------- | -| `nlCheckLogin` | | `CustomEvent` | -| `nlLogin` | | `CustomEvent` | - - -## Dependencies - -### Used by - - - [nl-auth](../nl-auth) - -### Depends on - -- [button-base](../button-base) - -### Graph -```mermaid -graph TD; - nl-signin --> button-base - nl-auth --> nl-signin - style nl-signin fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/components/nl-signup/nl-signup.css b/packages/components/src/components/nl-signup/nl-signup.css deleted file mode 100644 index 5d4e87f..0000000 --- a/packages/components/src/components/nl-signup/nl-signup.css +++ /dev/null @@ -1,3 +0,0 @@ -:host { - display: block; -} diff --git a/packages/components/src/components/nl-signup/nl-signup.tsx b/packages/components/src/components/nl-signup/nl-signup.tsx deleted file mode 100644 index 62812c9..0000000 --- a/packages/components/src/components/nl-signup/nl-signup.tsx +++ /dev/null @@ -1,125 +0,0 @@ -import { Component, h, Fragment, State, Prop, Event, EventEmitter, Watch } from '@stencil/core'; -import { state } from '@/store'; - -@Component({ - tag: 'nl-signup', - styleUrl: 'nl-signup.css', - shadow: false, -}) -export class NlSignup { - @Prop() titleSignup = 'Create keys with key store'; - @Prop() description = 'Choose some username and a key store service.'; - @Prop() bunkers: string = 'nsec.app,highlighter.com'; - - @State() isAvailable = false; - - @Event() nlSignup: EventEmitter; - @Event() nlCheckSignup: EventEmitter; - @Event() fetchHandler: EventEmitter; - - formatServers(bunkers: string) { - return bunkers.split(',').map(d => ({ - name: '@' + d, - value: d, - })); - } - - handleInputChange(event: Event) { - state.nlSignup.signupName = (event.target as HTMLInputElement).value; - this.nlCheckSignup.emit(`${(event.target as HTMLInputElement).value}@${state.nlSignup.domain}`); - } - - handleDomainSelect(event: CustomEvent) { - state.nlSignup.domain = event.detail; - this.nlCheckSignup.emit(`${state.nlSignup.signupName}@${event.detail}`); - } - - handleCreateAccount(e: MouseEvent) { - e.preventDefault(); - - this.nlSignup.emit(`${state.nlSignup.signupName}@${state.nlSignup.domain}`); - } - - @Watch('bunkers') - watchBunkersHandler(newValue: string) { - state.nlSignup.servers = this.formatServers(newValue); - } - - componentWillLoad() { - state.nlSignup.servers = this.formatServers(this.bunkers); - } - - render() { - return ( - -
-

{this.titleSignup}

-

{this.description}

-
- -
-
- this.handleInputChange(e)} - type="text" - class="nl-input peer py-3 px-4 ps-11 block w-full border-transparent rounded-lg text-sm disabled:opacity-50 disabled:pointer-events-none dark:border-transparent" - placeholder="Name" - value={state.nlSignup.signupName} - /> -
- - - -
-
- {/* {inputStatus && ( -

{textError}

- )} */} -
- {/**/} - this.handleDomainSelect(e)} selected={0} options={state.nlSignup.servers}> -
- {/*

Choose a service to manage your Nostr keys.

*/} - -
-

{state.error}

-
- - this.handleCreateAccount(e)} titleBtn="Create profile"> - {state.isLoading ? ( - - ) : ( - - - - )} - -
-
- ); - } -} diff --git a/packages/components/src/components/nl-signup/readme.md b/packages/components/src/components/nl-signup/readme.md deleted file mode 100644 index 882ba93..0000000 --- a/packages/components/src/components/nl-signup/readme.md +++ /dev/null @@ -1,46 +0,0 @@ -# nl-signup - - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| ------------- | -------------- | ----------- | -------- | ------------------------------------------------- | -| `bunkers` | `bunkers` | | `string` | `'nsec.app,highlighter.com'` | -| `description` | `description` | | `string` | `'Choose some username and a key store service.'` | -| `titleSignup` | `title-signup` | | `string` | `'Create keys with key store'` | - - -## Events - -| Event | Description | Type | -| --------------- | ----------- | ---------------------- | -| `fetchHandler` | | `CustomEvent` | -| `nlCheckSignup` | | `CustomEvent` | -| `nlSignup` | | `CustomEvent` | - - -## Dependencies - -### Used by - - - [nl-auth](../nl-auth) - -### Depends on - -- [nl-select](../nl-select) -- [button-base](../button-base) - -### Graph -```mermaid -graph TD; - nl-signup --> nl-select - nl-signup --> button-base - nl-auth --> nl-signup - style nl-signup fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/components/nl-welcome-signin/nl-welcome-signin.css b/packages/components/src/components/nl-welcome-signin/nl-welcome-signin.css deleted file mode 100644 index 5d4e87f..0000000 --- a/packages/components/src/components/nl-welcome-signin/nl-welcome-signin.css +++ /dev/null @@ -1,3 +0,0 @@ -:host { - display: block; -} diff --git a/packages/components/src/components/nl-welcome-signin/nl-welcome-signin.tsx b/packages/components/src/components/nl-welcome-signin/nl-welcome-signin.tsx deleted file mode 100644 index b2998ce..0000000 --- a/packages/components/src/components/nl-welcome-signin/nl-welcome-signin.tsx +++ /dev/null @@ -1,92 +0,0 @@ -import { Component, Event, EventEmitter, Fragment, h, Prop } from '@stencil/core'; -import { AuthMethod, CURRENT_MODULE } from '@/types'; -import { state } from '@/store'; - -@Component({ - tag: 'nl-welcome-signin', - styleUrl: 'nl-welcome-signin.css', - shadow: false, -}) -export class NlWelcomeSignIn { - @Prop() titleWelcome = 'Log in'; - @Prop() hasExtension: boolean = false; - @Prop() authMethods: AuthMethod[] = []; - @Prop() hasOTP: boolean = false; - @Event() nlLoginExtension: EventEmitter; - - handleChangeScreen(screen) { - state.path = [...state.path, screen]; - if (screen === CURRENT_MODULE.EXTENSION) this.nlLoginExtension.emit(); - } - - allowAuthMethod(m: AuthMethod) { - return !this.authMethods.length || this.authMethods.includes(m); - } - - renderSignInWithExtension() { - return ( - this.handleChangeScreen(CURRENT_MODULE.EXTENSION)} titleBtn="With extension"> - - - - - ); - } - - render() { - return ( - -
-

{this.titleWelcome}

-
- -
-
- {this.allowAuthMethod('connect') && ( - this.handleChangeScreen(CURRENT_MODULE.CONNECT)}> - - - - - )} - - {this.allowAuthMethod('readOnly') && ( - this.handleChangeScreen(CURRENT_MODULE.LOGIN_READ_ONLY)} titleBtn="Read only"> - - - - - - )} - - {this.hasOTP && this.allowAuthMethod('otp') && ( - this.handleChangeScreen(CURRENT_MODULE.LOGIN_OTP)}> - - - - - )} - - {this.hasExtension && this.allowAuthMethod('extension') && this.renderSignInWithExtension()} - {!this.allowAuthMethod('connect') && !this.hasExtension &&

No Nostr extension!

} - {!this.allowAuthMethod('connect') && this.hasExtension && !this.allowAuthMethod('extension') && ( -

Use advanced options.

- )} -
-
-
- ); - } -} diff --git a/packages/components/src/components/nl-welcome-signin/readme.md b/packages/components/src/components/nl-welcome-signin/readme.md deleted file mode 100644 index 873d3b0..0000000 --- a/packages/components/src/components/nl-welcome-signin/readme.md +++ /dev/null @@ -1,43 +0,0 @@ -# nl-welcome-signin - - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| -------------- | --------------- | ----------- | -------------- | ---------- | -| `authMethods` | -- | | `AuthMethod[]` | `[]` | -| `hasExtension` | `has-extension` | | `boolean` | `false` | -| `hasOTP` | `has-o-t-p` | | `boolean` | `false` | -| `titleWelcome` | `title-welcome` | | `string` | `'Log in'` | - - -## Events - -| Event | Description | Type | -| ------------------ | ----------- | ------------------- | -| `nlLoginExtension` | | `CustomEvent` | - - -## Dependencies - -### Used by - - - [nl-auth](../nl-auth) - -### Depends on - -- [button-base](../button-base) - -### Graph -```mermaid -graph TD; - nl-welcome-signin --> button-base - nl-auth --> nl-welcome-signin - style nl-welcome-signin fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/components/nl-welcome-signup/nl-welcome-signup.css b/packages/components/src/components/nl-welcome-signup/nl-welcome-signup.css deleted file mode 100644 index 5d4e87f..0000000 --- a/packages/components/src/components/nl-welcome-signup/nl-welcome-signup.css +++ /dev/null @@ -1,3 +0,0 @@ -:host { - display: block; -} diff --git a/packages/components/src/components/nl-welcome-signup/nl-welcome-signup.tsx b/packages/components/src/components/nl-welcome-signup/nl-welcome-signup.tsx deleted file mode 100644 index 2e07d04..0000000 --- a/packages/components/src/components/nl-welcome-signup/nl-welcome-signup.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import { Component, Fragment, h, Prop } from '@stencil/core'; -import { CURRENT_MODULE } from '@/types'; -import { state } from '@/store'; - -@Component({ - tag: 'nl-welcome-signup', - styleUrl: 'nl-welcome-signup.css', - shadow: false, -}) -export class NlWelcomeSignUp { - @Prop() titleWelcome = 'Sign up'; - @Prop() description = 'Nostr profiles are based on cryptographic keys. You can create keys right here, or with a key storage app.'; - - handleChangeScreen(screen) { - state.path = [...state.path, screen]; - } - - render() { - return ( - -
-

{this.titleWelcome}

-

{this.description}

-
- -
-
- this.handleChangeScreen(CURRENT_MODULE.LOCAL_SIGNUP)} titleBtn="Create keys"> - - - - - - this.handleChangeScreen(CURRENT_MODULE.SIGNUP)} titleBtn="With key store"> - - - - -
-
-
- ); - } -} diff --git a/packages/components/src/components/nl-welcome-signup/readme.md b/packages/components/src/components/nl-welcome-signup/readme.md deleted file mode 100644 index 700cca4..0000000 --- a/packages/components/src/components/nl-welcome-signup/readme.md +++ /dev/null @@ -1,34 +0,0 @@ -# nl-welcome-signup - - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| -------------- | --------------- | ----------- | -------- | -------------------------------------------------------------------------------------------------------------- | -| `description` | `description` | | `string` | `'Nostr profiles are based on cryptographic keys. You can create keys right here, or with a key storage app.'` | -| `titleWelcome` | `title-welcome` | | `string` | `'Sign up'` | - - -## Dependencies - -### Used by - - - [nl-auth](../nl-auth) - -### Depends on - -- [button-base](../button-base) - -### Graph -```mermaid -graph TD; - nl-welcome-signup --> button-base - nl-auth --> nl-welcome-signup - style nl-welcome-signup fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/components/nl-welcome/nl-welcome.css b/packages/components/src/components/nl-welcome/nl-welcome.css deleted file mode 100644 index 5d4e87f..0000000 --- a/packages/components/src/components/nl-welcome/nl-welcome.css +++ /dev/null @@ -1,3 +0,0 @@ -:host { - display: block; -} diff --git a/packages/components/src/components/nl-welcome/nl-welcome.tsx b/packages/components/src/components/nl-welcome/nl-welcome.tsx deleted file mode 100644 index 81502bc..0000000 --- a/packages/components/src/components/nl-welcome/nl-welcome.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import { Component, Fragment, h, Prop } from '@stencil/core'; -import { CURRENT_MODULE } from '@/types'; -import { state } from '@/store'; - -@Component({ - tag: 'nl-welcome', - styleUrl: 'nl-welcome.css', - shadow: false, -}) -export class NlWelcome { - @Prop() titleWelcome = 'Welcome to Nostr!'; - @Prop() description = 'This website is part of the Nostr network. Log in with your Nostr profile or sign up to join.'; - - handleChangeScreen(screen) { - state.path = [...state.path, screen]; - } - - render() { - return ( - -
-

{this.titleWelcome}

-

{this.description}

-
- -
-
- this.handleChangeScreen(CURRENT_MODULE.WELCOME_LOGIN)}> - - - - -
- - {/*
Or
*/} - - this.handleChangeScreen(CURRENT_MODULE.WELCOME_SIGNUP)} titleBtn="Sign up"> - - - - -
-
- ); - } -} diff --git a/packages/components/src/components/nl-welcome/readme.md b/packages/components/src/components/nl-welcome/readme.md deleted file mode 100644 index 1a3b2fe..0000000 --- a/packages/components/src/components/nl-welcome/readme.md +++ /dev/null @@ -1,34 +0,0 @@ -# nl-welcome - - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| -------------- | --------------- | ----------- | -------- | ------------------------------------------------------------------------------------------------- | -| `description` | `description` | | `string` | `'This website is part of the Nostr network. Log in with your Nostr profile or sign up to join.'` | -| `titleWelcome` | `title-welcome` | | `string` | `'Welcome to Nostr!'` | - - -## Dependencies - -### Used by - - - [nl-auth](../nl-auth) - -### Depends on - -- [button-base](../button-base) - -### Graph -```mermaid -graph TD; - nl-welcome --> button-base - nl-auth --> nl-welcome - style nl-welcome fill:#f9f,stroke:#333,stroke-width:4px -``` - ----------------------------------------------- - -*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/components/src/index.html b/packages/components/src/index.html deleted file mode 100644 index 5359fb0..0000000 --- a/packages/components/src/index.html +++ /dev/null @@ -1,315 +0,0 @@ - - - - - - Modal Auth Develop - - - - - - - - - - - - -
- - -
- - - - - - - - - - - - - - diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts deleted file mode 100644 index 738f191..0000000 --- a/packages/components/src/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { NlAuth } from './components/nl-auth/nl-auth'; -export { NlButton } from './components/nl-button/nl-button'; -export { NlBanner } from './components/nl-banner/nl-banner'; -export { ButtonBase } from './components/button-base/button-base'; diff --git a/packages/components/src/store/index.ts b/packages/components/src/store/index.ts deleted file mode 100644 index 54f5ea8..0000000 --- a/packages/components/src/store/index.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { createStore } from '@stencil/store'; -import { CURRENT_MODULE, ConnectionString } from '@/types'; - -const { state, onChange, reset } = createStore({ - screen: CURRENT_MODULE.WELCOME, - prevScreen: CURRENT_MODULE.WELCOME, - path: [CURRENT_MODULE.WELCOME], - error: '', - isLoading: false, - isLoadingExtension: false, - isOTP: false, - authUrl: '', - iframeUrl: '', - njumpIframe: '', - - // State NlSignin - nlSignin: { - loginName: '', - }, - - // State NlSignup - nlSignup: { - signupName: '', - domain: '', - servers: [ - { name: '@nsec.app', value: 'nsec.app' }, - { name: '@highlighter.com', value: 'highlighter.com' }, - ], - }, - - // State NlSigninBunkerUrl - nlSigninBunkerUrl: { - loginName: '', - }, - - // State NlSigninReadOnly - nlSigninReadOnly: { - loginName: '', - }, - - // State NlSigninOTP - nlSigninOTP: { - loginName: '', - code: '', - }, - - nlImport: null as (ConnectionString | null), -}); - -// control show screens & manage history (like as router) -// ??? edit to better solution -onChange('screen', () => { - state.error = ''; - state.nlSignin.loginName = ''; - state.nlSignup.signupName = ''; - state.nlSignup.domain = ''; - - // if (value === CURRENT_MODULE.LOGIN || value === CURRENT_MODULE.SIGNUP || value === CURRENT_MODULE.LOGIN_BUNKER_URL || value === CURRENT_MODULE.LOGIN_READ_ONLY) { - // state.prevScreen = CURRENT_MODULE.WELCOME; - // } -}); - -// on('set', (_, value, oldValue) => { -// if (value === CURRENT_MODULE.INFO) { -// state.prevScreen = oldValue; -// } -// }); - -export { state, reset }; diff --git a/packages/components/src/styles/tailwind.css b/packages/components/src/styles/tailwind.css deleted file mode 100644 index 0938fbb..0000000 --- a/packages/components/src/styles/tailwind.css +++ /dev/null @@ -1,753 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - -/*Theme default*/ -.theme-default .nl-bg { - @apply bg-white shadow-sm; -} - -.theme-default .dark .nl-bg { - @apply bg-gray-800 shadow-slate-700/[.7]; -} - -.theme-default .nl-logo, -.theme-default .nl-title, -.theme-default .nl-description { - @apply text-gray-800; -} - -.theme-default .dark .nl-logo, -.theme-default .dark .nl-title, -.theme-default .dark .nl-description { - @apply text-white; -} - -.theme-default .nl-description a { - @apply underline text-blue-800; -} - -.theme-default .dark .nl-description a { - @apply underline text-blue-200; -} - -.theme-default .nl-action-button { - @apply text-gray-800 hover:bg-gray-100 outline-none; -} - -.theme-default .dark .nl-action-button { - @apply text-white hover:bg-gray-700 outline-none; -} - -.theme-default .nl-title { - @apply text-gray-800; -} - -.theme-default .dark .nl-title { - @apply text-gray-200; -} - -.theme-default .nl-button { - @apply border border-gray-200 bg-white text-gray-800 shadow-sm hover:bg-gray-50; -} - -.theme-default .dark .nl-button { - @apply bg-slate-900 border-gray-700 text-gray-300 hover:bg-gray-800; -} - -.theme-default .nl-divider { - @apply text-gray-400 before:border-t before:border-gray-200 after:border-gray-200; -} - -.theme-default .dark .nl-divider { - @apply text-gray-500 before:border-gray-600 after:border-gray-600; -} - -.theme-default .nl-footer { - @apply text-gray-800; -} - -.theme-default .dark .nl-footer { - @apply text-gray-200; -} - -.theme-default .nl-error { - @apply text-red-800; -} - -.theme-default .dark .nl-error { - @apply text-red-200; -} - -.theme-default .nl-input { - @apply bg-gray-100 focus:border-purple-500 focus:ring-purple-500; -} - -.theme-default .dark .nl-input { - @apply bg-gray-700 text-gray-400 focus:ring-gray-600; -} - -.theme-default .nl-select { - @apply bg-gray-100 focus:border-purple-500 focus:ring-purple-500; -} - -.theme-default .dark .nl-select { - @apply bg-gray-700 text-gray-400 focus:ring-gray-600; -} - -.theme-default .nl-select-list { - @apply bg-gray-100; -} - -.theme-default .dark .nl-select-list { - @apply bg-gray-700; -} - -.theme-default .nl-select-option { - @apply text-gray-800 hover:bg-gray-200; -} - -.theme-default .nl-select-option.active-option { - @apply text-blue-900 bg-gray-300; -} - -.theme-default .dark .nl-select-option { - @apply text-gray-400 hover:bg-gray-800 hover:text-gray-300; -} - -.theme-default .nl-text-error { - @apply text-red-400; -} - -.theme-default .nl-text-success { - @apply text-teal-400; -} - -.theme-default .nl-banner { - @apply border border-gray-200 bg-white text-gray-800 shadow-sm; -} - -.theme-default .dark .nl-banner { - @apply bg-slate-900 border-gray-700 text-gray-300; -} - -/*Theme ocean*/ -.theme-ocean .nl-bg { - @apply bg-blue-200 shadow-sm; -} - -.theme-ocean .dark .nl-bg { - @apply bg-sky-950 shadow-slate-700/[.7]; -} - -.theme-ocean .nl-logo, -.theme-ocean .nl-title, -.theme-ocean .nl-description { - @apply text-sky-950; -} - -.theme-ocean .dark .nl-logo, -.theme-ocean .dark .nl-title, -.theme-ocean .dark .nl-description { - @apply text-sky-200; -} - -.theme-ocean .nl-action-button { - @apply text-sky-950 hover:bg-sky-100 outline-none; -} - -.theme-ocean .dark .nl-action-button { - @apply text-sky-200 hover:bg-sky-900 outline-none; -} - -.theme-ocean .nl-button { - @apply border border-sky-200 bg-sky-100 text-sky-950 shadow-sm hover:bg-sky-50; -} - -.theme-ocean .dark .nl-button { - @apply bg-sky-800 border-sky-950 text-sky-200 hover:bg-sky-900; -} - -.theme-ocean .nl-divider { - @apply text-sky-950 after:border-sky-950 before:border-sky-950; -} - -.theme-ocean .dark .nl-divider { - @apply text-sky-200 before:border-sky-200 after:border-sky-200; -} - -.theme-ocean .nl-footer { - @apply text-sky-950; -} - -.theme-ocean .dark .nl-footer { - @apply text-sky-200; -} - -.theme-ocean .nl-error { - @apply text-red-800; -} - -.theme-ocean .dark .nl-error { - @apply text-red-200; -} - -.theme-ocean .nl-input { - @apply bg-sky-100 focus:border-sky-500 focus:ring-sky-500; -} - -.theme-ocean .dark .nl-input { - @apply bg-sky-900 text-sky-400 focus:ring-sky-600; -} - -.theme-ocean .nl-select { - @apply bg-sky-100 focus:border-sky-500 focus:ring-sky-500; -} - -.theme-ocean .dark .nl-select { - @apply bg-sky-900 text-sky-400 focus:ring-sky-600; -} - -.theme-ocean .nl-select-list { - @apply bg-sky-100; -} - -.theme-ocean .dark .nl-select-list { - @apply bg-sky-700; -} - -.theme-ocean .nl-select-option { - @apply text-sky-800 hover:bg-sky-200; -} - -.theme-ocean .dark .nl-select-option { - @apply text-sky-400 hover:bg-sky-800 hover:text-sky-300; -} - -.theme-ocean .nl-text-error { - @apply text-red-600; -} - -.theme-ocean .dark .nl-text-error { - @apply text-red-400; -} - -.theme-ocean .nl-text-success { - @apply text-teal-600; -} - -.theme-ocean .dark .nl-text-success { - @apply text-teal-400; -} - -/*Theme lemonade*/ -.theme-lemonade .nl-bg { - @apply bg-green-200 shadow-sm; -} - -.theme-lemonade .dark .nl-bg { - @apply bg-green-950 shadow-slate-700/[.7]; -} - -.theme-lemonade .nl-logo, -.theme-lemonade .nl-title, -.theme-lemonade .nl-description { - @apply text-green-950; -} - -.theme-lemonade .dark .nl-logo, -.theme-lemonade .dark .nl-title, -.theme-lemonade .dark .nl-description { - @apply text-green-200; -} - -.theme-lemonade .nl-action-button { - @apply text-green-950 hover:bg-green-100 outline-none; -} - -.theme-lemonade .dark .nl-action-button { - @apply text-green-200 hover:bg-green-900 outline-none; -} - -.theme-lemonade .nl-button { - @apply border border-green-200 bg-green-100 text-green-950 shadow-sm hover:bg-green-50; -} - -.theme-lemonade .dark .nl-button { - @apply bg-green-800 border-green-950 text-green-200 hover:bg-green-900; -} - -.theme-lemonade .nl-divider { - @apply text-green-950 after:border-green-950 before:border-green-950; -} - -.theme-lemonade .dark .nl-divider { - @apply text-green-200 before:border-green-200 after:border-green-200; -} - -.theme-lemonade .nl-footer { - @apply text-green-950; -} - -.theme-lemonade .dark .nl-footer { - @apply text-green-200; -} - -.theme-lemonade .nl-error { - @apply text-red-800; -} - -.theme-lemonade .dark .nl-error { - @apply text-red-200; -} - -.theme-lemonade .nl-input { - @apply bg-green-100 focus:border-green-500 focus:ring-green-500; -} - -.theme-lemonade .dark .nl-input { - @apply bg-green-900 text-green-400 focus:ring-green-600; -} - -.theme-lemonade .nl-select { - @apply bg-green-100 focus:border-green-500 focus:ring-green-500; -} - -.theme-lemonade .dark .nl-select { - @apply bg-green-900 text-green-400 focus:ring-green-600; -} - -.theme-lemonade .nl-select-list { - @apply bg-green-100; -} - -.theme-lemonade .dark .nl-select-list { - @apply bg-green-700; -} - -.theme-lemonade .nl-select-option { - @apply text-green-800 hover:bg-green-200; -} - -.theme-lemonade .dark .nl-select-option { - @apply text-green-400 hover:bg-green-800 hover:text-green-300; -} - -.theme-lemonade .nl-text-error { - @apply text-red-600; -} - -.theme-lemonade .dark .nl-text-error { - @apply text-red-400; -} - -.theme-lemonade .nl-text-success { - @apply text-teal-600; -} - -.theme-lemonade .dark .nl-text-success { - @apply text-teal-400; -} - -/*Theme purple*/ -.theme-purple .nl-bg { - @apply bg-purple-200 shadow-sm; -} - -.theme-purple .dark .nl-bg { - @apply bg-purple-950 shadow-slate-700/[.7]; -} - -.theme-purple .nl-logo, -.theme-purple .nl-title, -.theme-purple .nl-description { - @apply text-purple-950; -} - -.theme-purple .dark .nl-logo, -.theme-purple .dark .nl-title, -.theme-purple .dark .nl-description { - @apply text-purple-200; -} - -.theme-purple .nl-action-button { - @apply text-purple-950 hover:bg-purple-100 outline-none; -} - -.theme-purple .dark .nl-action-button { - @apply text-purple-200 hover:bg-purple-900 outline-none; -} - -.theme-purple .nl-button { - @apply border border-purple-200 bg-purple-100 text-purple-950 shadow-sm hover:bg-purple-50; -} - -.theme-purple .dark .nl-button { - @apply bg-purple-800 border-purple-950 text-purple-200 hover:bg-purple-900; -} - -.theme-purple .nl-divider { - @apply text-purple-950 after:border-purple-950 before:border-purple-950; -} - -.theme-purple .dark .nl-divider { - @apply text-purple-200 before:border-purple-200 after:border-purple-200; -} - -.theme-purple .nl-footer { - @apply text-purple-950; -} - -.theme-purple .dark .nl-footer { - @apply text-purple-200; -} - -.theme-purple .nl-error { - @apply text-red-800; -} - -.theme-purple .dark .nl-error { - @apply text-red-200; -} - -.theme-purple .nl-input { - @apply bg-purple-100 focus:border-purple-500 focus:ring-purple-500; -} - -.theme-purple .dark .nl-input { - @apply bg-purple-900 text-purple-400 focus:ring-purple-600; -} - -.theme-purple .nl-select { - @apply bg-purple-100 focus:border-purple-500 focus:ring-purple-500; -} - -.theme-purple .dark .nl-select { - @apply bg-purple-900 text-purple-400 focus:ring-purple-600; -} - -.theme-purple .nl-select-list { - @apply bg-purple-100; -} - -.theme-purple .dark .nl-select-list { - @apply bg-purple-700; -} - -.theme-purple .nl-select-option { - @apply text-purple-800 hover:bg-purple-200; -} - -.theme-purple .dark .nl-select-option { - @apply text-purple-400 hover:bg-purple-800 hover:text-purple-300; -} - -.theme-purple .nl-text-error { - @apply text-red-600; -} - -.theme-purple .dark .nl-text-error { - @apply text-red-400; -} - -.theme-purple .nl-text-success { - @apply text-teal-600; -} - -.theme-purple .dark .nl-text-success { - @apply text-teal-400; -} - -/*Theme crab*/ -.theme-crab .nl-button { - @apply border border-red-200 bg-red-100 text-red-950 shadow-sm hover:bg-red-50; -} - -.theme-crab .dark .nl-button { - @apply bg-red-800 border-red-950 text-red-200 hover:bg-red-900; -} - -/*Theme laan*/ -.theme-laan { - @apply font-mono; -} - -.theme-laan .nl-bg { - @apply bg-white shadow-sm; -} - -.theme-laan .dark .nl-bg { - @apply bg-black shadow-gray-700; -} - -.theme-laan .nl-logo, -.theme-laan .nl-title, -.theme-laan .nl-description { - @apply text-black font-mono; -} - -.theme-laan .dark .nl-logo, -.theme-laan .dark .nl-title, -.theme-laan .dark .nl-description { - @apply text-white font-mono; -} - -.theme-laan .nl-description a { - @apply underline; - color: rgb(255, 0, 0); -} - -.theme-laan .dark .nl-description a { - @apply underline; - color: rgb(255, 0, 0); -} - -.theme-laan .nl-action-button { - @apply text-black hover:bg-gray-100 outline-none font-mono; -} - -.theme-laan .dark .nl-action-button { - @apply text-white hover:bg-gray-900 outline-none font-mono; -} - -.theme-laan .nl-title { - @apply text-black font-mono; -} - -.theme-laan .dark .nl-title { - @apply text-white font-mono; -} - -.theme-laan .nl-button { - @apply border-2 border-black bg-transparent text-black shadow-none font-mono; - border-color: rgb(255, 0, 0); - color: rgb(255, 0, 0); -} - -.theme-laan .nl-button:hover { - @apply bg-gray-100; - border-color: rgb(255, 0, 0); - color: rgb(255, 0, 0); -} - -.theme-laan .dark .nl-button { - @apply border-2 bg-transparent text-white shadow-none font-mono; - border-color: rgb(255, 0, 0); - color: rgb(255, 0, 0); -} - -.theme-laan .dark .nl-button:hover { - @apply bg-gray-900; - border-color: rgb(255, 0, 0); - color: rgb(255, 0, 0); -} - -.theme-laan .nl-divider { - @apply text-gray-500 before:border-t before:border-gray-400 after:border-gray-400 font-mono; -} - -.theme-laan .dark .nl-divider { - @apply text-gray-400 before:border-gray-600 after:border-gray-600 font-mono; -} - -.theme-laan .nl-footer { - @apply text-black font-mono; -} - -.theme-laan .dark .nl-footer { - @apply text-white font-mono; -} - -.theme-laan .nl-error { - @apply font-mono; - color: rgb(255, 0, 0); -} - -.theme-laan .dark .nl-error { - @apply font-mono; - color: rgb(255, 0, 0); -} - -.theme-laan .nl-input { - @apply bg-gray-100 border-gray-400 text-black font-mono; - border-color: rgb(255, 0, 0); -} - -.theme-laan .nl-input:focus { - border-color: rgb(255, 0, 0); - box-shadow: 0 0 0 1px rgb(255, 0, 0); -} - -.theme-laan .dark .nl-input { - @apply bg-gray-900 border-gray-600 text-white font-mono; - border-color: rgb(255, 0, 0); -} - -.theme-laan .dark .nl-input:focus { - border-color: rgb(255, 0, 0); - box-shadow: 0 0 0 1px rgb(255, 0, 0); -} - -.theme-laan .nl-select { - @apply bg-gray-100 border-gray-400 text-black font-mono; - border-color: rgb(255, 0, 0); -} - -.theme-laan .nl-select:focus { - border-color: rgb(255, 0, 0); - box-shadow: 0 0 0 1px rgb(255, 0, 0); -} - -.theme-laan .dark .nl-select { - @apply bg-gray-900 border-gray-600 text-white font-mono; - border-color: rgb(255, 0, 0); -} - -.theme-laan .dark .nl-select:focus { - border-color: rgb(255, 0, 0); - box-shadow: 0 0 0 1px rgb(255, 0, 0); -} - -.theme-laan .nl-select-list { - @apply bg-white border border-gray-400 font-mono; -} - -.theme-laan .dark .nl-select-list { - @apply bg-black border-gray-600 font-mono; -} - -.theme-laan .nl-select-option { - @apply text-black hover:bg-gray-100 font-mono; -} - -.theme-laan .nl-select-option.active-option { - @apply bg-gray-200; - color: rgb(255, 0, 0); -} - -.theme-laan .dark .nl-select-option { - @apply text-white hover:bg-gray-900 font-mono; -} - -.theme-laan .dark .nl-select-option.active-option { - @apply bg-gray-800; - color: rgb(255, 0, 0); -} - -.theme-laan .nl-text-error { - @apply font-mono; - color: rgb(255, 0, 0); -} - -.theme-laan .nl-text-success { - @apply font-mono; - color: rgb(255, 0, 0); -} - -.theme-laan .nl-banner { - @apply border border-gray-400 bg-white text-black shadow-sm font-mono; -} - -.theme-laan .dark .nl-banner { - @apply bg-black border-gray-600 text-white font-mono; -} - -/* Override ALL non-compliant colors for Laan theme */ -/* Blue colors -> Red */ -.theme-laan .text-blue-400, -.theme-laan .text-blue-500, -.theme-laan .text-blue-600 { - color: rgb(255, 0, 0) !important; -} - -.theme-laan .hover\:text-blue-600:hover { - color: rgb(255, 0, 0) !important; -} - -.theme-laan .border-blue-200, -.theme-laan .border-blue-400 { - border-color: rgb(255, 0, 0) !important; -} - -.theme-laan .group-hover\:border-blue-400:hover { - border-color: rgb(255, 0, 0) !important; -} - -/* Teal colors -> Red */ -.theme-laan .border-teal-300, -.theme-laan .text-teal-600, -.theme-laan .bg-teal-100 { - border-color: rgb(255, 0, 0) !important; - color: rgb(255, 0, 0) !important; - background-color: rgba(255, 0, 0, 0.1) !important; -} - -/* Yellow colors -> Red */ -.theme-laan .border-yellow-300, -.theme-laan .border-yellow-600, -.theme-laan .text-yellow-500, -.theme-laan .text-yellow-600, -.theme-laan .bg-yellow-100 { - border-color: rgb(255, 0, 0) !important; - color: rgb(255, 0, 0) !important; - background-color: rgba(255, 0, 0, 0.1) !important; -} - -/* Orange colors -> Red */ -.theme-laan .border-orange-300, -.theme-laan .text-orange-600, -.theme-laan .bg-orange-100 { - border-color: rgb(255, 0, 0) !important; - color: rgb(255, 0, 0) !important; - background-color: rgba(255, 0, 0, 0.1) !important; -} - -/* Green colors -> Red */ -.theme-laan .bg-green-500, -.theme-laan .text-green-800, -.theme-laan .text-green-200 { - background-color: rgb(255, 0, 0) !important; - color: rgb(255, 0, 0) !important; -} - -/* Slate colors -> Grey/Black/White */ -.theme-laan .text-slate-900 { - color: rgb(0, 0, 0) !important; -} - -.theme-laan .dark .text-slate-900 { - color: rgb(255, 255, 255) !important; -} - -/* Cursor pointer with red hover */ -.theme-laan .cursor-pointer { - color: rgb(255, 0, 0) !important; -} - -.theme-laan .cursor-pointer:hover { - color: rgb(200, 0, 0) !important; -} - -/* All links should be red */ -.theme-laan a, -.theme-laan [class*="text-blue"] { - color: rgb(255, 0, 0) !important; -} - -.theme-laan a:hover, -.theme-laan [class*="text-blue"]:hover { - color: rgb(200, 0, 0) !important; -} - -.show-slow { - opacity: 0; - display: none; - transition: 0.1s; -} - -.isOpen .show-slow { - opacity: 1; - display: block; - transition: 0.2s; - transition-delay: 0.2s; -} diff --git a/packages/components/src/types/button.ts b/packages/components/src/types/button.ts deleted file mode 100644 index f74f9ad..0000000 --- a/packages/components/src/types/button.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { NlTheme } from './index'; - -export interface IButton { - theme: NlTheme; - titleBtn: string; - disabled: boolean; -} diff --git a/packages/components/src/types/index.ts b/packages/components/src/types/index.ts deleted file mode 100644 index a42c5e7..0000000 --- a/packages/components/src/types/index.ts +++ /dev/null @@ -1,90 +0,0 @@ -export enum CURRENT_MODULE { - WELCOME = 'welcome', - WELCOME_LOGIN = 'welcome-login', - WELCOME_SIGNUP = 'welcome-signup', - INFO = 'info', - LOGIN_BUNKER_URL = 'login-bunker-url', - LOGIN_READ_ONLY = 'login-read-only', - CONFIRM_LOGOUT = 'confirm-logout', - IMPORT_FLOW = 'import', - IMPORT_OTP = 'import-otp', - LOGIN = 'login', - SIGNUP = 'signup', - LOCAL_SIGNUP = 'local-signup', - EXTENSION = 'extension', - LOADING = 'loading', - PREVIOUSLY_LOGGED = 'switch-account', - LOGIN_OTP = 'otp', - CONNECT = 'connect', - CONNECTION_STRING = 'connection-string', - IFRAME = 'iframe', -} - -export enum METHOD_MODULE { - LOGIN = 'login', - SIGNUP = 'signup', - LOGOUT = 'logout', - CONFIRM = 'confirm', -} - -export type AuthMethod = 'connect' | 'readOnly' | 'extension' | 'local' | 'otp'; - -export interface Info { - // must be present - pubkey: string; - - // new nip46 - signerPubkey?: string; - - // connect or local methods - sk?: string; - - // connect method only - relays?: string[]; - - // connect/readOnly - nip05?: string; - domain?: string; - - // connect w/ bunkerUrl - bunkerUrl?: string; - - // from kind:0 profile - picture?: string; - name?: string; - - // nip46 bunker URL secret - token?: string; - - // session type - authMethod: AuthMethod; - - // what otp auth reply returned, - // may be empty if cookies are used, or may contain session - // token to be used for future api calls - otpData?: string; - - // for iframe comms - iframeUrl?: string; -} - -export type RecentType = Pick; - -export type NlTheme = 'default' | 'ocean' | 'lemonade' | 'purple' | 'crab' | 'laan'; - -export interface ConnectionString { - name: string; - img: string; - link: string; - relay: string; - domain?: string; - canImport?: boolean; - iframeUrl?: string; -} - -export type BannerNotifyMode = '' | 'timeout' | 'authUrl' | 'iframeAuthUrl' | 'rebind'; - -export interface BannerNotify { - mode: BannerNotifyMode; - url?: string; -} diff --git a/packages/components/stencil.config.ts b/packages/components/stencil.config.ts deleted file mode 100644 index 426133a..0000000 --- a/packages/components/stencil.config.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Config } from '@stencil/core'; -import { sass } from '@stencil/sass'; -import tailwind, { tailwindHMR, setPluginConfigurationDefaults } from 'stencil-tailwind-plugin'; -import tailwindcss from 'tailwindcss'; -import tailwindConf from './tailwind.config'; -import autoprefixer from 'autoprefixer'; - -setPluginConfigurationDefaults({ - tailwindConf, - tailwindCssPath: './src/styles/tailwind.css', - postcss: { - plugins: [ - tailwindcss(), - autoprefixer() - ] - } -}); - -export const config: Config = { - namespace: 'components', - globalStyle: 'src/styles/tailwind.css', - outputTargets: [ - { - type: 'dist-custom-elements', - customElementsExportBehavior: 'auto-define-custom-elements', - }, - { - type: "www", - buildDir: 'build' - } - ], - testing: { - browserHeadless: "new", - }, - plugins: [ - sass(), - tailwind(), - tailwindHMR() - ], -}; diff --git a/packages/components/tailwind.config.js b/packages/components/tailwind.config.js deleted file mode 100644 index 87c2c6e..0000000 --- a/packages/components/tailwind.config.js +++ /dev/null @@ -1,68 +0,0 @@ -/** @type {import('tailwindcss').Config} */ - -module.exports = { - content: ['./src/components/**/*.{ts,tsx,html}'], - darkMode: 'class', - plugins: [ - require('@tailwindcss/forms') - ], - theme: { - fontSize: { - sm: ['14px', '20px'], - xs: ['12px', '16px'], - base: ['16px', '24px'], - lg: ['18px', '28px'], - xl: ['20px', '28px'], - "2xl": ['24px', '32px'], - "3xl": ['30px', '36px'], - "4xl": ['36px', '40px'], - "5xl": ['48px', '1'], - "6xl": ['60px', '1'], - "7xl": ['72px', '1'], - "8xl": ['96px', '1'], - "9xl": ['128px', '1'], - }, - extend: { - maxWidth: { - "lg": "512px", - }, - spacing: { - "0": "0px", - "1": "4px", - "2": "8px", - "3": "12px", - "4": "16px", - "5": "20px", - "6": "24px", - "7": "28px", - "8": "32px", - "9": "36px", - "10": "40px", - "11": "44px", - "12": "48px", - "14": "56px", - "16": "64px", - "20": "80px", - "24": "96px", - "28": "112px", - "32": "128px", - "36": "144px", - "40": "160px", - "44": "176px", - "48": "192px", - "52": "208px", - "56": "224px", - "60": "240px", - "64": "256px", - "72": "288px", - "80": "320px", - "96": "384px", - "px": "1px", - "0.5": "2px", - "1.5": "6px", - "2.5": "10px", - "3.5": "14px" - } - } - } -} diff --git a/packages/components/tsconfig.json b/packages/components/tsconfig.json deleted file mode 100644 index fe940b1..0000000 --- a/packages/components/tsconfig.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "compilerOptions": { - "allowSyntheticDefaultImports": true, - "allowUnreachableCode": false, - "declaration": false, - "experimentalDecorators": true, - "lib": [ - "dom", - "es2017" - ], - "moduleResolution": "node", - "module": "esnext", - "target": "es2017", - "noUnusedLocals": true, - "noUnusedParameters": true, - "jsx": "react", - "jsxFactory": "h", - "baseUrl": ".", - "paths": { - "@/*": ["src/*"], - } - }, - "include": [ - "src" - ], - "exclude": [ - "node_modules" - ] -}