@napplet/conformance-cli 0.2.18 → 0.2.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/host-bundle.global.js +171 -103
- package/dist/ui/assets/index-DV1wZ-SF.js +116 -0
- package/dist/ui/index.html +1 -1
- package/package.json +3 -3
- package/dist/ui/assets/index-BRWua2-f.js +0 -113
|
@@ -136,7 +136,7 @@ var NappletConformanceHostBundle = (() => {
|
|
|
136
136
|
// ── resource ─────────────────────────────────────────────────────────────
|
|
137
137
|
"resource.info": { dir: "out", fields: { ...ID } },
|
|
138
138
|
"resource.bytes": { dir: "out", fields: { ...ID, url: "string" } },
|
|
139
|
-
"resource.bytesMany": { dir: "out", fields: { ...ID,
|
|
139
|
+
"resource.bytesMany": { dir: "out", fields: { ...ID, requests: "array" } },
|
|
140
140
|
"resource.cancel": { dir: "out", fields: { ...ID } },
|
|
141
141
|
"resource.info.result": { dir: "in" },
|
|
142
142
|
"resource.info.error": { dir: "in" },
|
|
@@ -185,7 +185,7 @@ var NappletConformanceHostBundle = (() => {
|
|
|
185
185
|
"intent.invoke": { dir: "out", fields: { ...ID, request: "object" } },
|
|
186
186
|
"intent.available": { dir: "out", fields: { ...ID, archetype: "string" } },
|
|
187
187
|
"intent.handlers": { dir: "out", fields: { ...ID } },
|
|
188
|
-
"intent.invoke.result": { dir: "in" },
|
|
188
|
+
"intent.invoke.result": { dir: "in", fields: { ...ID, result: "object" } },
|
|
189
189
|
"intent.available.result": { dir: "in" },
|
|
190
190
|
"intent.handlers.result": { dir: "in" },
|
|
191
191
|
"intent.changed": { dir: "in" },
|
|
@@ -336,6 +336,48 @@ var NappletConformanceHostBundle = (() => {
|
|
|
336
336
|
});
|
|
337
337
|
}
|
|
338
338
|
}
|
|
339
|
+
function validateServerHints(value, field, errors) {
|
|
340
|
+
if (Array.isArray(value) && value.every((server) => typeof server === "string")) return;
|
|
341
|
+
errors.push({
|
|
342
|
+
code: "wrong-type",
|
|
343
|
+
message: `Field "${field}" must be an array of strings`,
|
|
344
|
+
field
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
function validateResourceRequestFields(record, errors) {
|
|
348
|
+
if (record.servers !== void 0) validateServerHints(record.servers, "servers", errors);
|
|
349
|
+
}
|
|
350
|
+
function validateResourceBytesManyRequests(requests, errors) {
|
|
351
|
+
if (!Array.isArray(requests)) return;
|
|
352
|
+
if (requests.length === 0) {
|
|
353
|
+
errors.push({
|
|
354
|
+
code: "invalid-resource-request",
|
|
355
|
+
message: 'Field "requests" must contain at least one resource request',
|
|
356
|
+
field: "requests"
|
|
357
|
+
});
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
for (const [index, request] of requests.entries()) {
|
|
361
|
+
const field = `requests[${index}]`;
|
|
362
|
+
if (typeof request !== "object" || request === null || Array.isArray(request)) {
|
|
363
|
+
errors.push({
|
|
364
|
+
code: "invalid-resource-request",
|
|
365
|
+
message: `Field "${field}" must be a resource request object`,
|
|
366
|
+
field
|
|
367
|
+
});
|
|
368
|
+
continue;
|
|
369
|
+
}
|
|
370
|
+
const entry = request;
|
|
371
|
+
if (typeof entry.url !== "string") {
|
|
372
|
+
errors.push({
|
|
373
|
+
code: entry.url === void 0 ? "missing-field" : "wrong-type",
|
|
374
|
+
message: `Field "${field}.url" must be a string`,
|
|
375
|
+
field: `${field}.url`
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
if (entry.servers !== void 0) validateServerHints(entry.servers, `${field}.servers`, errors);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
339
381
|
function validateEnvelope(message) {
|
|
340
382
|
const errors = [];
|
|
341
383
|
if (typeof message !== "object" || message === null || Array.isArray(message)) {
|
|
@@ -396,6 +438,12 @@ var NappletConformanceHostBundle = (() => {
|
|
|
396
438
|
if (type === "intent.invoke") {
|
|
397
439
|
validateIntentInvokeRequest(record.request, errors);
|
|
398
440
|
}
|
|
441
|
+
if (type === "resource.bytes") {
|
|
442
|
+
validateResourceRequestFields(record, errors);
|
|
443
|
+
}
|
|
444
|
+
if (type === "resource.bytesMany") {
|
|
445
|
+
validateResourceBytesManyRequests(record.requests, errors);
|
|
446
|
+
}
|
|
399
447
|
return { ok: errors.length === 0, type, domain, direction: "out", errors };
|
|
400
448
|
}
|
|
401
449
|
var NAPPLET_KIND_SNAPSHOT = 5129;
|
|
@@ -587,10 +635,11 @@ var NappletConformanceHostBundle = (() => {
|
|
|
587
635
|
"resource.bytesMany": (e) => ok({
|
|
588
636
|
type: "resource.bytesMany.result",
|
|
589
637
|
id: e.id,
|
|
590
|
-
items: Array.isArray(e.
|
|
638
|
+
items: Array.isArray(e.requests) ? e.requests.map((request) => {
|
|
639
|
+
const url = typeof request === "object" && request !== null && !Array.isArray(request) ? request.url : void 0;
|
|
591
640
|
const decoded = dataUrlToBlob(url);
|
|
592
641
|
return {
|
|
593
|
-
url,
|
|
642
|
+
url: typeof url === "string" ? url : "",
|
|
594
643
|
ok: true,
|
|
595
644
|
blob: decoded?.blob ?? new Blob([]),
|
|
596
645
|
mime: decoded?.mime ?? "application/octet-stream"
|
|
@@ -604,7 +653,8 @@ var NappletConformanceHostBundle = (() => {
|
|
|
604
653
|
schemes: [
|
|
605
654
|
{ scheme: "data", enabled: true },
|
|
606
655
|
{ scheme: "https", enabled: true }
|
|
607
|
-
]
|
|
656
|
+
],
|
|
657
|
+
maxServers: 8
|
|
608
658
|
}
|
|
609
659
|
}),
|
|
610
660
|
"resource.cancel": none,
|
|
@@ -738,118 +788,133 @@ var NappletConformanceHostBundle = (() => {
|
|
|
738
788
|
"fs.watch": (e) => ok({ type: "fs.watch.result", id: e.id, watchId: `watch-${String(e.id)}` }),
|
|
739
789
|
"fs.unwatch": (e) => ok({ type: "fs.unwatch.result", id: e.id })
|
|
740
790
|
};
|
|
741
|
-
function
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
const targetQueues = /* @__PURE__ */ new Map();
|
|
745
|
-
function queueDelivery(target, delivery) {
|
|
746
|
-
const queue = targetQueues.get(target);
|
|
747
|
-
if (queue) {
|
|
748
|
-
queue.push(delivery);
|
|
749
|
-
return;
|
|
750
|
-
}
|
|
751
|
-
targetQueues.set(target, [delivery]);
|
|
752
|
-
}
|
|
753
|
-
function takeDeliveries(target) {
|
|
754
|
-
const queue = targetQueues.get(target) ?? [];
|
|
755
|
-
targetQueues.delete(target);
|
|
756
|
-
return queue;
|
|
757
|
-
}
|
|
758
|
-
function unavailableIntent(id, archetype, action, error) {
|
|
759
|
-
return ok({
|
|
760
|
-
type: "intent.invoke.result",
|
|
761
|
-
id,
|
|
762
|
-
result: { ok: false, archetype, action, handled: false, error }
|
|
763
|
-
});
|
|
764
|
-
}
|
|
765
|
-
function handleIntentInvoke(_endpoint, env) {
|
|
766
|
-
const request = env.request;
|
|
767
|
-
if (typeof request !== "object" || request === null || Array.isArray(request)) {
|
|
768
|
-
return unavailableIntent(env.id, "", "open", "invalid intent request");
|
|
769
|
-
}
|
|
770
|
-
const intent = request;
|
|
771
|
-
const archetype = typeof intent.archetype === "string" ? intent.archetype : "";
|
|
772
|
-
const action = typeof intent.action === "string" ? intent.action : "open";
|
|
773
|
-
if (!archetype) {
|
|
774
|
-
return unavailableIntent(env.id, archetype, action, "intent request requires an archetype");
|
|
775
|
-
}
|
|
776
|
-
if (archetype !== "note") {
|
|
777
|
-
return unavailableIntent(env.id, archetype, action, "no handler");
|
|
778
|
-
}
|
|
779
|
-
if (intent.convention !== void 0 && intent.convention !== REFERENCE_CONVENTION) {
|
|
780
|
-
return unavailableIntent(env.id, archetype, action, "unsupported convention");
|
|
781
|
-
}
|
|
782
|
-
return ok({
|
|
783
|
-
type: "intent.invoke.result",
|
|
784
|
-
id: env.id,
|
|
785
|
-
result: {
|
|
786
|
-
ok: true,
|
|
787
|
-
archetype,
|
|
788
|
-
action,
|
|
789
|
-
handled: true,
|
|
790
|
-
handler: REFERENCE_HANDLER,
|
|
791
|
-
windowId: "reference-window",
|
|
792
|
-
convention: typeof intent.convention === "string" ? intent.convention : REFERENCE_CONVENTION
|
|
793
|
-
}
|
|
794
|
-
});
|
|
795
|
-
}
|
|
796
|
-
function intentAvailability(archetype) {
|
|
797
|
-
if (archetype !== "note") {
|
|
798
|
-
return { archetype, available: false, candidates: [], hasDefault: false };
|
|
799
|
-
}
|
|
800
|
-
return {
|
|
801
|
-
archetype,
|
|
802
|
-
available: true,
|
|
803
|
-
candidates: [{
|
|
804
|
-
dTag: REFERENCE_HANDLER,
|
|
805
|
-
actions: ["open"],
|
|
806
|
-
conventions: [REFERENCE_CONVENTION],
|
|
807
|
-
isDefault: true
|
|
808
|
-
}],
|
|
809
|
-
hasDefault: true
|
|
810
|
-
};
|
|
811
|
-
}
|
|
812
|
-
function handleFrom(endpoint, envelope) {
|
|
813
|
-
const type = envelope && typeof envelope === "object" && typeof envelope.type === "string" ? envelope.type : void 0;
|
|
791
|
+
function createReferenceHandler(options) {
|
|
792
|
+
return (endpoint, envelope) => {
|
|
793
|
+
const type = getEnvelopeType(envelope);
|
|
814
794
|
const verdict = validateEnvelope(envelope);
|
|
815
|
-
records.push({ envelope, verdict, timestamp: now() });
|
|
795
|
+
options.records.push({ envelope, verdict, timestamp: options.now() });
|
|
816
796
|
if (!type || !verdict.ok) return [];
|
|
817
797
|
const env = envelope;
|
|
818
|
-
if (type === "intent.invoke") return
|
|
798
|
+
if (type === "intent.invoke") return options.intents.handleInvoke(endpoint, env);
|
|
819
799
|
if (type === "intent.available") {
|
|
820
|
-
return ok({ type: "intent.available.result", id: env.id, availability:
|
|
800
|
+
return ok({ type: "intent.available.result", id: env.id, availability: options.intents.availability(env.archetype) });
|
|
821
801
|
}
|
|
822
802
|
if (type === "intent.handlers") {
|
|
823
|
-
return ok({ type: "intent.handlers.result", id: env.id, handlers: [
|
|
824
|
-
}
|
|
825
|
-
if (type === "inc.emit") {
|
|
826
|
-
if (env.topic === REFERENCE_CONVENTION) {
|
|
827
|
-
const event = {
|
|
828
|
-
type: "inc.event",
|
|
829
|
-
topic: env.topic,
|
|
830
|
-
sender: endpoint.dTag
|
|
831
|
-
};
|
|
832
|
-
if ("payload" in env) event.payload = env.payload;
|
|
833
|
-
queueDelivery(REFERENCE_SUBSCRIBER, event);
|
|
834
|
-
}
|
|
835
|
-
return [];
|
|
803
|
+
return ok({ type: "intent.handlers.result", id: env.id, handlers: [options.intents.availability("note")] });
|
|
836
804
|
}
|
|
805
|
+
if (type === "inc.emit") return handleIncEmit(endpoint, env, options.queueDelivery);
|
|
837
806
|
const responder = RESPONDERS[type];
|
|
838
807
|
return responder ? responder(env) : [];
|
|
808
|
+
};
|
|
809
|
+
}
|
|
810
|
+
function getEnvelopeType(envelope) {
|
|
811
|
+
if (!envelope || typeof envelope !== "object") return void 0;
|
|
812
|
+
const type = envelope.type;
|
|
813
|
+
return typeof type === "string" ? type : void 0;
|
|
814
|
+
}
|
|
815
|
+
function handleIncEmit(endpoint, env, queueDelivery) {
|
|
816
|
+
if (env.topic !== REFERENCE_CONVENTION) return [];
|
|
817
|
+
const event = {
|
|
818
|
+
type: "inc.event",
|
|
819
|
+
topic: env.topic,
|
|
820
|
+
sender: endpoint.dTag
|
|
821
|
+
};
|
|
822
|
+
if ("payload" in env) event.payload = env.payload;
|
|
823
|
+
queueDelivery(REFERENCE_SUBSCRIBER, event);
|
|
824
|
+
return [];
|
|
825
|
+
}
|
|
826
|
+
function unavailableIntent(id, archetype, action, error) {
|
|
827
|
+
return ok({
|
|
828
|
+
type: "intent.invoke.result",
|
|
829
|
+
id,
|
|
830
|
+
result: { ok: false, archetype, action, handled: false, error }
|
|
831
|
+
});
|
|
832
|
+
}
|
|
833
|
+
function createIntentHandlers() {
|
|
834
|
+
return { handleInvoke, availability };
|
|
835
|
+
}
|
|
836
|
+
function handleInvoke(_endpoint, env) {
|
|
837
|
+
const request = env.request;
|
|
838
|
+
if (typeof request !== "object" || request === null || Array.isArray(request)) {
|
|
839
|
+
return unavailableIntent(env.id, "", "open", "invalid intent request");
|
|
840
|
+
}
|
|
841
|
+
const intent = request;
|
|
842
|
+
const archetype = typeof intent.archetype === "string" ? intent.archetype : "";
|
|
843
|
+
const action = typeof intent.action === "string" ? intent.action : "open";
|
|
844
|
+
if (!archetype) {
|
|
845
|
+
return unavailableIntent(env.id, archetype, action, "intent request requires an archetype");
|
|
839
846
|
}
|
|
840
|
-
|
|
841
|
-
|
|
847
|
+
if (archetype !== "note") return unavailableIntent(env.id, archetype, action, "no handler");
|
|
848
|
+
if (intent.convention !== void 0 && intent.convention !== REFERENCE_CONVENTION) {
|
|
849
|
+
return unavailableIntent(env.id, archetype, action, "unsupported convention");
|
|
842
850
|
}
|
|
851
|
+
return ok({
|
|
852
|
+
type: "intent.invoke.result",
|
|
853
|
+
id: env.id,
|
|
854
|
+
result: {
|
|
855
|
+
ok: true,
|
|
856
|
+
archetype,
|
|
857
|
+
action,
|
|
858
|
+
handled: true,
|
|
859
|
+
handler: REFERENCE_HANDLER,
|
|
860
|
+
windowId: "reference-window",
|
|
861
|
+
convention: typeof intent.convention === "string" ? intent.convention : REFERENCE_CONVENTION
|
|
862
|
+
}
|
|
863
|
+
});
|
|
864
|
+
}
|
|
865
|
+
function availability(archetype) {
|
|
866
|
+
if (archetype !== "note") {
|
|
867
|
+
return { archetype, available: false, candidates: [], hasDefault: false };
|
|
868
|
+
}
|
|
869
|
+
return {
|
|
870
|
+
archetype,
|
|
871
|
+
available: true,
|
|
872
|
+
candidates: [{
|
|
873
|
+
dTag: REFERENCE_HANDLER,
|
|
874
|
+
actions: ["open"],
|
|
875
|
+
conventions: [REFERENCE_CONVENTION],
|
|
876
|
+
isDefault: true
|
|
877
|
+
}],
|
|
878
|
+
hasDefault: true
|
|
879
|
+
};
|
|
880
|
+
}
|
|
881
|
+
function createReferenceShell(options = {}) {
|
|
882
|
+
const records = [];
|
|
883
|
+
const deliveries = createDeliveryQueue();
|
|
884
|
+
const handleFrom = createReferenceHandler({
|
|
885
|
+
now: options.now ?? Date.now,
|
|
886
|
+
records,
|
|
887
|
+
queueDelivery: deliveries.queue,
|
|
888
|
+
intents: createIntentHandlers()
|
|
889
|
+
});
|
|
843
890
|
return {
|
|
844
891
|
get records() {
|
|
845
892
|
return records;
|
|
846
893
|
},
|
|
847
|
-
handle,
|
|
894
|
+
handle: (envelope) => handleFrom(REFERENCE_ENDPOINT, envelope),
|
|
848
895
|
handleFrom,
|
|
849
|
-
takeDeliveries,
|
|
896
|
+
takeDeliveries: deliveries.take,
|
|
850
897
|
reset() {
|
|
851
898
|
records.length = 0;
|
|
852
|
-
|
|
899
|
+
deliveries.clear();
|
|
900
|
+
}
|
|
901
|
+
};
|
|
902
|
+
}
|
|
903
|
+
function createDeliveryQueue() {
|
|
904
|
+
const queues = /* @__PURE__ */ new Map();
|
|
905
|
+
return {
|
|
906
|
+
queue(target, delivery) {
|
|
907
|
+
const queue = queues.get(target);
|
|
908
|
+
if (queue) queue.push(delivery);
|
|
909
|
+
else queues.set(target, [delivery]);
|
|
910
|
+
},
|
|
911
|
+
take(target) {
|
|
912
|
+
const queue = queues.get(target) ?? [];
|
|
913
|
+
queues.delete(target);
|
|
914
|
+
return queue;
|
|
915
|
+
},
|
|
916
|
+
clear() {
|
|
917
|
+
queues.clear();
|
|
853
918
|
}
|
|
854
919
|
};
|
|
855
920
|
}
|
|
@@ -902,11 +967,14 @@ var NappletConformanceHostBundle = (() => {
|
|
|
902
967
|
napplet.resource.info = () =>
|
|
903
968
|
request({ type: 'resource.info' }, 'resource.info.result', 'resource.info.error')
|
|
904
969
|
.then((msg) => msg.info);
|
|
905
|
-
napplet.resource.bytes = (url) =>
|
|
906
|
-
|
|
970
|
+
napplet.resource.bytes = (url, options) => {
|
|
971
|
+
const message = { type: 'resource.bytes', url: String(url) };
|
|
972
|
+
if (options && options.servers !== undefined) message.servers = options.servers;
|
|
973
|
+
return request(message, 'resource.bytes.result', 'resource.bytes.error')
|
|
907
974
|
.then((msg) => msg.blob);
|
|
908
|
-
|
|
909
|
-
|
|
975
|
+
};
|
|
976
|
+
napplet.resource.bytesMany = (requests) =>
|
|
977
|
+
request({ type: 'resource.bytesMany', requests: Array.from(requests || []) }, 'resource.bytesMany.result', 'resource.bytesMany.error')
|
|
910
978
|
.then((msg) => msg.items);
|
|
911
979
|
napplet.resource.bytesAsObjectURL = (url) => {
|
|
912
980
|
const handle = { url: '', revoke: () => {} };
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))n(i);new MutationObserver(i=>{for(const s of i)if(s.type==="childList")for(const o of s.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&n(o)}).observe(document,{childList:!0,subtree:!0});function r(i){const s={};return i.integrity&&(s.integrity=i.integrity),i.referrerPolicy&&(s.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?s.credentials="include":i.crossOrigin==="anonymous"?s.credentials="omit":s.credentials="same-origin",s}function n(i){if(i.ep)return;i.ep=!0;const s=r(i);fetch(i.href,s)}})();var at=["relay","identity","storage","inc","theme","keys","media","notify","config","resource","cvm","outbox","upload","intent","ble","webrtc","link","count","lists","serial","fs","common","dm"],l={id:"string"},An={"relay.subscribe":{dir:"out",fields:{...l,subId:"string",filters:"array"}},"relay.close":{dir:"out",fields:{...l,subId:"string"}},"relay.publish":{dir:"out",fields:{...l,event:"object"}},"relay.publishEncrypted":{dir:"out",fields:{...l,event:"object",recipient:"string"}},"relay.query":{dir:"out",fields:{...l,filters:"array"}},"relay.event":{dir:"in"},"relay.eose":{dir:"in"},"relay.closed":{dir:"in"},"relay.publish.result":{dir:"in"},"relay.publishEncrypted.result":{dir:"in"},"relay.query.result":{dir:"in"},"identity.getPublicKey":{dir:"out",fields:{...l}},"identity.getRelays":{dir:"out",fields:{...l}},"identity.getProfile":{dir:"out",fields:{...l}},"identity.getFollows":{dir:"out",fields:{...l}},"identity.getList":{dir:"out",fields:{...l,listType:"string"}},"identity.getZaps":{dir:"out",fields:{...l}},"identity.getMutes":{dir:"out",fields:{...l}},"identity.getBlocked":{dir:"out",fields:{...l}},"identity.getBadges":{dir:"out",fields:{...l}},"identity.changed":{dir:"in"},"identity.getPublicKey.result":{dir:"in"},"identity.getRelays.result":{dir:"in"},"identity.getProfile.result":{dir:"in"},"identity.getFollows.result":{dir:"in"},"identity.getList.result":{dir:"in"},"identity.getZaps.result":{dir:"in"},"identity.getMutes.result":{dir:"in"},"identity.getBlocked.result":{dir:"in"},"identity.getBadges.result":{dir:"in"},"storage.get":{dir:"out",fields:{...l,key:"string"}},"storage.set":{dir:"out",fields:{...l,key:"string",value:"string"}},"storage.remove":{dir:"out",fields:{...l,key:"string"}},"storage.keys":{dir:"out",fields:{...l}},"storage.get.result":{dir:"in"},"storage.set.result":{dir:"in"},"storage.remove.result":{dir:"in"},"storage.keys.result":{dir:"in"},"inc.emit":{dir:"out",fields:{topic:"string"},forbiddenFields:["sender"]},"inc.subscribe":{dir:"out",fields:{...l,topic:"string"}},"inc.unsubscribe":{dir:"out",fields:{topic:"string"}},"inc.channel.open":{dir:"out",fields:{...l,target:"string"}},"inc.channel.emit":{dir:"out",fields:{channelId:"string"}},"inc.channel.broadcast":{dir:"out"},"inc.channel.list":{dir:"out",fields:{...l}},"inc.channel.close":{dir:"out",fields:{channelId:"string"}},"inc.subscribe.result":{dir:"in"},"inc.event":{dir:"in",fields:{topic:"string",sender:"string"}},"inc.channel.open.result":{dir:"in"},"inc.channel.opened":{dir:"in",fields:{channelId:"string",peer:"string"}},"inc.channel.event":{dir:"in"},"inc.channel.list.result":{dir:"in"},"inc.channel.closed":{dir:"in"},"theme.get":{dir:"out",fields:{...l}},"theme.get.result":{dir:"in"},"theme.changed":{dir:"in"},"keys.forward":{dir:"out",fields:{key:"string",code:"string",ctrl:"boolean",alt:"boolean",shift:"boolean",meta:"boolean"}},"keys.registerAction":{dir:"out",fields:{...l,action:"object"}},"keys.unregisterAction":{dir:"out",fields:{actionId:"string"}},"keys.registerAction.result":{dir:"in"},"keys.bindings":{dir:"in"},"keys.action":{dir:"in"},"media.session.create":{dir:"out",fields:{...l,owner:"object"}},"media.session.update":{dir:"out",fields:{sessionId:"string",metadata:"object"}},"media.session.destroy":{dir:"out",fields:{sessionId:"string"}},"media.state":{dir:"out",fields:{sessionId:"string",status:"string"}},"media.capabilities":{dir:"out",fields:{sessionId:"string",actions:"array"}},"media.session.create.result":{dir:"in"},"media.command":{dir:"in"},"media.controls":{dir:"in"},"notify.send":{dir:"out",fields:{...l,title:"string"}},"notify.dismiss":{dir:"out",fields:{notificationId:"string"}},"notify.badge":{dir:"out",fields:{count:"number"}},"notify.channel.register":{dir:"out",fields:{channelId:"string",label:"string"}},"notify.permission.request":{dir:"out",fields:{...l}},"notify.send.result":{dir:"in"},"notify.permission.result":{dir:"in"},"notify.action":{dir:"in"},"notify.clicked":{dir:"in"},"notify.dismissed":{dir:"in"},"notify.controls":{dir:"in"},"config.registerSchema":{dir:"out",fields:{...l,schema:"object"}},"config.get":{dir:"out",fields:{...l}},"config.subscribe":{dir:"out"},"config.unsubscribe":{dir:"out"},"config.openSettings":{dir:"out"},"config.registerSchema.result":{dir:"in"},"config.values":{dir:"in"},"config.schemaError":{dir:"in"},"resource.info":{dir:"out",fields:{...l}},"resource.bytes":{dir:"out",fields:{...l,url:"string"}},"resource.bytesMany":{dir:"out",fields:{...l,requests:"array"}},"resource.cancel":{dir:"out",fields:{...l}},"resource.info.result":{dir:"in"},"resource.info.error":{dir:"in"},"resource.bytes.result":{dir:"in"},"resource.bytes.error":{dir:"in"},"resource.bytesMany.result":{dir:"in"},"resource.bytesMany.error":{dir:"in"},"cvm.discover":{dir:"out",fields:{...l}},"cvm.request":{dir:"out",fields:{...l,server:"object",message:"object"}},"cvm.close":{dir:"out",fields:{...l,server:"object"}},"cvm.registry.list":{dir:"out",fields:{...l}},"cvm.registry.has":{dir:"out",fields:{...l,family:"string"}},"cvm.registry.describe":{dir:"out",fields:{...l,family:"string"}},"cvm.registry.call":{dir:"out",fields:{...l,family:"string",tool:"string"}},"cvm.discover.result":{dir:"in"},"cvm.request.result":{dir:"in"},"cvm.close.result":{dir:"in"},"cvm.event":{dir:"in"},"cvm.registry.list.result":{dir:"in"},"cvm.registry.has.result":{dir:"in"},"cvm.registry.describe.result":{dir:"in"},"cvm.registry.call.result":{dir:"in"},"outbox.getEvent":{dir:"out",fields:{...l,eventId:"string"}},"outbox.query":{dir:"out",fields:{...l,filters:"present"}},"outbox.subscribe":{dir:"out",fields:{...l,subId:"string",filters:"present"}},"outbox.close":{dir:"out",fields:{...l,subId:"string"}},"outbox.publish":{dir:"out",fields:{...l,event:"object"}},"outbox.resolveRelays":{dir:"out",fields:{...l,target:"present"}},"outbox.getEvent.result":{dir:"in"},"outbox.query.result":{dir:"in"},"outbox.event":{dir:"in"},"outbox.closed":{dir:"in"},"outbox.publish.result":{dir:"in"},"outbox.resolveRelays.result":{dir:"in"},"upload.info":{dir:"out",fields:{...l}},"upload.upload":{dir:"out",fields:{...l,request:"object"}},"upload.status":{dir:"out",fields:{...l,uploadId:"string"}},"upload.info.result":{dir:"in"},"upload.upload.result":{dir:"in"},"upload.status.result":{dir:"in"},"upload.status.changed":{dir:"in"},"intent.invoke":{dir:"out",fields:{...l,request:"object"}},"intent.available":{dir:"out",fields:{...l,archetype:"string"}},"intent.handlers":{dir:"out",fields:{...l}},"intent.invoke.result":{dir:"in",fields:{...l,result:"object"}},"intent.available.result":{dir:"in"},"intent.handlers.result":{dir:"in"},"intent.changed":{dir:"in"},"ble.open":{dir:"out",fields:{...l,request:"object"}},"ble.services":{dir:"out",fields:{...l,sessionId:"string"}},"ble.read":{dir:"out",fields:{...l,sessionId:"string",target:"object"}},"ble.write":{dir:"out",fields:{...l,sessionId:"string",target:"object",data:"array"}},"ble.subscribe":{dir:"out",fields:{...l,sessionId:"string",target:"object"}},"ble.unsubscribe":{dir:"out",fields:{...l,sessionId:"string",target:"object"}},"ble.close":{dir:"out",fields:{...l,sessionId:"string"}},"ble.open.result":{dir:"in"},"ble.services.result":{dir:"in"},"ble.read.result":{dir:"in"},"ble.write.result":{dir:"in"},"ble.subscribe.result":{dir:"in"},"ble.unsubscribe.result":{dir:"in"},"ble.close.result":{dir:"in"},"ble.event":{dir:"in"},"common.encodeNip19":{dir:"out",fields:{...l,input:"object"}},"common.decodeNip19":{dir:"out",fields:{...l,value:"string"}},"common.getProfile":{dir:"out",fields:{...l,target:"string"}},"common.follows":{dir:"out",fields:{...l}},"common.follow":{dir:"out",fields:{...l,pubkeys:"array"}},"common.unfollow":{dir:"out",fields:{...l,pubkeys:"array"}},"common.react":{dir:"out",fields:{...l,targetEventId:"string",reaction:"string"}},"common.report":{dir:"out",fields:{...l,target:"object",reason:"string",text:"string"}},"common.encodeNip19.result":{dir:"in"},"common.decodeNip19.result":{dir:"in"},"common.getProfile.result":{dir:"in"},"common.follows.result":{dir:"in"},"common.follow.result":{dir:"in"},"common.unfollow.result":{dir:"in"},"common.react.result":{dir:"in"},"common.report.result":{dir:"in"},"webrtc.open":{dir:"out",fields:{...l,request:"object"}},"webrtc.send":{dir:"out",fields:{...l,sessionId:"string",payload:"present"}},"webrtc.close":{dir:"out",fields:{...l,sessionId:"string"}},"webrtc.open.result":{dir:"in"},"webrtc.send.result":{dir:"in"},"webrtc.close.result":{dir:"in"},"webrtc.event":{dir:"in"},"link.open":{dir:"out",fields:{...l,url:"string"}},"link.open.result":{dir:"in"},"count.query":{dir:"out",fields:{...l,filters:"array"}},"count.query.result":{dir:"in"},"lists.supported":{dir:"out",fields:{...l}},"lists.add":{dir:"out",fields:{...l,list:"object",items:"array"}},"lists.remove":{dir:"out",fields:{...l,list:"object",items:"array"}},"lists.supported.result":{dir:"in"},"lists.add.result":{dir:"in"},"lists.remove.result":{dir:"in"},"serial.open":{dir:"out",fields:{...l,request:"object"}},"serial.write":{dir:"out",fields:{...l,sessionId:"string",data:"array"}},"serial.close":{dir:"out",fields:{...l,sessionId:"string"}},"serial.open.result":{dir:"in"},"serial.write.result":{dir:"in"},"serial.close.result":{dir:"in"},"serial.event":{dir:"in"},"fs.info":{dir:"out",fields:{...l}},"fs.pickFile":{dir:"out",fields:{...l}},"fs.pickFiles":{dir:"out",fields:{...l}},"fs.pickDirectory":{dir:"out",fields:{...l}},"fs.pickSaveFile":{dir:"out",fields:{...l}},"fs.stat":{dir:"out",fields:{...l,path:"string"}},"fs.list":{dir:"out",fields:{...l,path:"string"}},"fs.read":{dir:"out",fields:{...l,path:"string"}},"fs.write":{dir:"out",fields:{...l,path:"string",data:"string"}},"fs.mkdir":{dir:"out",fields:{...l,path:"string"}},"fs.remove":{dir:"out",fields:{...l,path:"string"}},"fs.move":{dir:"out",fields:{...l,fromPath:"string",toPath:"string"}},"fs.watch":{dir:"out",fields:{...l,path:"string"}},"fs.unwatch":{dir:"out",fields:{...l,watchId:"string"}},"fs.info.result":{dir:"in"},"fs.pickFile.result":{dir:"in"},"fs.pickFiles.result":{dir:"in"},"fs.pickDirectory.result":{dir:"in"},"fs.pickSaveFile.result":{dir:"in"},"fs.stat.result":{dir:"in"},"fs.list.result":{dir:"in"},"fs.read.result":{dir:"in"},"fs.write.result":{dir:"in"},"fs.mkdir.result":{dir:"in"},"fs.remove.result":{dir:"in"},"fs.move.result":{dir:"in"},"fs.watch.result":{dir:"in"},"fs.unwatch.result":{dir:"in"},"fs.changed":{dir:"in"},"dm.status":{dir:"out",fields:{...l}},"dm.conversations":{dir:"out",fields:{...l}},"dm.messages":{dir:"out",fields:{...l,conversationId:"string"}},"dm.send":{dir:"out",fields:{...l,recipients:"array",content:"string"}},"dm.subscribe":{dir:"out",fields:{...l}},"dm.unsubscribe":{dir:"out",fields:{...l,subscriptionId:"string"}},"dm.status.result":{dir:"in"},"dm.conversations.result":{dir:"in"},"dm.messages.result":{dir:"in"},"dm.send.result":{dir:"in"},"dm.subscribe.result":{dir:"in"},"dm.unsubscribe.result":{dir:"in"},"dm.message":{dir:"in"}};function Ht(e){if(e===void 0)return"undefined";if(e===null)return"null";if(Array.isArray(e))return"array";const t=typeof e;return t==="string"||t==="number"||t==="boolean"?t:t==="object"?"object":"present"}function Tn(e,t){return t==="present"?e!=null:Ht(e)===t}function Bn(e,t){if(typeof e!="object"||e===null||Array.isArray(e))return;const r=e;typeof r.archetype!="string"&&t.push({code:r.archetype===void 0?"missing-field":"wrong-type",message:'Intent request requires a string "archetype" field',field:"request.archetype"});for(const n of["action","convention"])r[n]!==void 0&&typeof r[n]!="string"&&t.push({code:"wrong-type",message:`Intent request field "${n}" must be a string`,field:`request.${n}`});"sender"in r&&t.push({code:"forbidden-field",message:"Intent request does not define a caller-supplied sender field",field:"request.sender"})}function jt(e,t,r){Array.isArray(e)&&e.every(n=>typeof n=="string")||r.push({code:"wrong-type",message:`Field "${t}" must be an array of strings`,field:t})}function On(e,t){e.servers!==void 0&&jt(e.servers,"servers",t)}function qn(e,t){if(Array.isArray(e)){if(e.length===0){t.push({code:"invalid-resource-request",message:'Field "requests" must contain at least one resource request',field:"requests"});return}for(const[r,n]of e.entries()){const i=`requests[${r}]`;if(typeof n!="object"||n===null||Array.isArray(n)){t.push({code:"invalid-resource-request",message:`Field "${i}" must be a resource request object`,field:i});continue}const s=n;typeof s.url!="string"&&t.push({code:s.url===void 0?"missing-field":"wrong-type",message:`Field "${i}.url" must be a string`,field:`${i}.url`}),s.servers!==void 0&&jt(s.servers,`${i}.servers`,t)}}}function Nn(e){const t=[];if(typeof e!="object"||e===null||Array.isArray(e))return{ok:!1,errors:[{code:"not-an-object",message:"Envelope must be a non-null object"}]};const r=e,n=r.type;if(typeof n!="string")return{ok:!1,errors:[{code:"missing-type",message:"Envelope is missing a string `type` field"}]};const i=n.indexOf(".");if(i<=0)return{ok:!1,type:n,errors:[{code:"malformed-type",message:`Envelope type "${n}" is not in domain.action form`}]};const s=n.slice(0,i);if(!at.includes(s))return{ok:!1,type:n,domain:s,errors:[{code:"unknown-domain",message:`"${s}" is not a known NAP domain`}]};const c=An[n];if(!c)return{ok:!1,type:n,domain:s,errors:[{code:"unknown-type",message:`"${n}" is not a known ${s} message type`}]};for(const[a,d]of Object.entries(c.fields??{})){if(!(a in r)||r[a]===void 0){t.push({code:"missing-field",message:`Required field "${a}" is missing`,field:a});continue}Tn(r[a],d)||t.push({code:"wrong-type",message:`Field "${a}" should be ${d} but is ${Ht(r[a])}`,field:a})}if(c.dir==="in")return{ok:!1,type:n,domain:s,direction:"in",errors:[{code:"inbound-type-emitted",message:`"${n}" is a shell→napplet message; a napplet must not emit it`},...t]};for(const a of c.forbiddenFields??[])a in r&&t.push({code:"forbidden-field",message:`Field "${a}" must be runtime-derived and cannot be emitted by a napplet`,field:a});return n==="intent.invoke"&&Bn(r.request,t),n==="resource.bytes"&&On(r,t),n==="resource.bytesMany"&&qn(r.requests,t),{ok:t.length===0,type:n,domain:s,direction:"out",errors:t}}var Dt=5129,Mt=15129,ge=35129,ct=[Dt,Mt,ge];function Ft(e,t){return e.tags.find(r=>r[0]===t)}function Ln(e){return ct.includes(e)}function Pn(e){return typeof e=="string"&&/^[0-9a-f]{64}$/i.test(e)}function Wt(e){return Ft(e,"d")?.[1]?.trim()||void 0}function _n(e){return e.tags.filter(t=>t[0]==="requires").map(t=>t[1]?.trim()??"").filter(Boolean)}function Zt(e){return Wt(e)??Ft(e,"title")?.[1]??e.id}function lt(e){const t=[],r=[];if(!e)return{ok:!1,requires:[],errors:[{code:"missing-manifest-event",message:"No NIP-5D manifest event was resolved"}],warnings:r};const n=Wt(e),i=_n(e);Ln(e.kind)||t.push({code:"invalid-napplet-kind",message:`Manifest event kind ${e.kind} is not a NIP-5D napplet kind`}),e.kind===ge&&!n?t.push({code:"missing-d-tag",message:"Named napplet manifest kind 35129 must include a non-empty d tag"}):(e.kind===Mt||e.kind===Dt)&&n&&t.push({code:"unexpected-d-tag",message:`Napplet manifest kind ${e.kind} must not include a d tag`});const s=e.tags.find(o=>o[0]==="path"&&o[1]==="/index.html");s?Pn(s[2])||t.push({code:"invalid-index-html-hash",message:"The /index.html path tag must carry a 64-character sha256 hash"}):t.push({code:"missing-index-html",message:"Napplet manifest must include a path tag for /index.html"});for(const o of i){if(o.startsWith("nap:")||o.startsWith("NAP-")){t.push({code:"invalid-required-nap",message:`requires tag "${o}" must be a bare NAP domain such as "relay"`});continue}at.includes(o)||t.push({code:"unknown-required-nap",message:`requires tag "${o}" is not a known NAP domain`})}return{ok:t.length===0,kind:e.kind,dTag:n,requires:i,errors:t,warnings:r}}var xe="f".repeat(64),Cn={dTag:"reference-source"},Un="https://reference.invalid/blob",Vt="reference-handler",Hn="reference-subscriber",Be="napplet:note/open";function ke(e,t,r){return u({type:e,id:t,result:{entries:[r]}})}var u=e=>[e],N=()=>[];function wt(e){if(typeof e!="string"||!e.startsWith("data:"))return null;const t=e.indexOf(",");if(t<0)return{blob:new Blob([],{type:"text/plain"}),mime:"text/plain"};const r=e.slice(5,t),n=e.slice(t+1),i=r.split(";").filter(Boolean),s=i.includes("base64"),o=i.find(c=>c.includes("/"))??"text/plain";try{if(s){const c=globalThis.atob(n),a=Uint8Array.from(c,d=>d.charCodeAt(0));return{blob:new Blob([a],{type:o}),mime:o}}return{blob:new Blob([decodeURIComponent(n)],{type:o}),mime:o}}catch{return null}}var jn={"relay.subscribe":e=>u({type:"relay.eose",subId:e.subId}),"relay.close":N,"relay.publish":e=>u({type:"relay.publish.result",id:e.id,ok:!0,event:e.event}),"relay.publishEncrypted":e=>u({type:"relay.publishEncrypted.result",id:e.id,ok:!0,event:e.event}),"relay.query":e=>u({type:"relay.query.result",id:e.id,events:[]}),"identity.getPublicKey":e=>u({type:"identity.getPublicKey.result",id:e.id,pubkey:xe}),"identity.getRelays":e=>u({type:"identity.getRelays.result",id:e.id,relays:{}}),"identity.getProfile":e=>u({type:"identity.getProfile.result",id:e.id,profile:null}),"identity.getFollows":e=>u({type:"identity.getFollows.result",id:e.id,pubkeys:[]}),"identity.getList":e=>u({type:"identity.getList.result",id:e.id,entries:[]}),"identity.getZaps":e=>u({type:"identity.getZaps.result",id:e.id,zaps:[]}),"identity.getMutes":e=>u({type:"identity.getMutes.result",id:e.id,pubkeys:[]}),"identity.getBlocked":e=>u({type:"identity.getBlocked.result",id:e.id,pubkeys:[]}),"identity.getBadges":e=>u({type:"identity.getBadges.result",id:e.id,badges:[]}),"storage.get":e=>u({type:"storage.get.result",id:e.id,value:null}),"storage.set":e=>u({type:"storage.set.result",id:e.id}),"storage.remove":e=>u({type:"storage.remove.result",id:e.id}),"storage.keys":e=>u({type:"storage.keys.result",id:e.id,keys:[]}),"inc.emit":N,"inc.subscribe":e=>u({type:"inc.subscribe.result",id:e.id}),"inc.unsubscribe":N,"inc.channel.open":e=>u({type:"inc.channel.open.result",id:e.id,channelId:`chan-${String(e.id)}`,peer:"reference-peer"}),"inc.channel.emit":N,"inc.channel.broadcast":N,"inc.channel.list":e=>u({type:"inc.channel.list.result",id:e.id,channels:[]}),"inc.channel.close":N,"theme.get":e=>u({type:"theme.get.result",id:e.id,theme:{colors:{},mode:"dark"}}),"keys.forward":N,"keys.registerAction":e=>u({type:"keys.registerAction.result",id:e.id,actionId:`action-${String(e.id)}`}),"keys.unregisterAction":N,"media.session.create":e=>u({type:"media.session.create.result",id:e.id,sessionId:`session-${String(e.id)}`,owner:e.owner}),"media.session.update":N,"media.session.destroy":N,"media.state":N,"media.capabilities":N,"notify.send":e=>u({type:"notify.send.result",id:e.id,notificationId:`notif-${String(e.id)}`}),"notify.dismiss":N,"notify.badge":N,"notify.channel.register":N,"notify.permission.request":e=>u({type:"notify.permission.result",id:e.id,granted:!0}),"config.registerSchema":e=>u({type:"config.registerSchema.result",id:e.id,ok:!0}),"config.get":e=>u({type:"config.values",id:e.id,values:{}}),"config.subscribe":()=>u({type:"config.values",values:{}}),"config.unsubscribe":N,"config.openSettings":N,"resource.bytes":e=>{const t=wt(e.url);return u(t?{type:"resource.bytes.result",id:e.id,blob:t.blob,mime:t.mime}:{type:"resource.bytes.result",id:e.id,blob:new Blob([]),mime:"application/octet-stream"})},"resource.bytesMany":e=>u({type:"resource.bytesMany.result",id:e.id,items:Array.isArray(e.requests)?e.requests.map(t=>{const r=typeof t=="object"&&t!==null&&!Array.isArray(t)?t.url:void 0,n=wt(r);return{url:typeof r=="string"?r:"",ok:!0,blob:n?.blob??new Blob([]),mime:n?.mime??"application/octet-stream"}}):[]}),"resource.info":e=>u({type:"resource.info.result",id:e.id,info:{schemes:[{scheme:"data",enabled:!0},{scheme:"https",enabled:!0}],maxServers:8}}),"resource.cancel":N,"cvm.discover":e=>u({type:"cvm.discover.result",id:e.id,servers:[]}),"cvm.request":e=>u({type:"cvm.request.result",id:e.id,message:{}}),"cvm.close":e=>u({type:"cvm.close.result",id:e.id}),"outbox.getEvent":e=>u({type:"outbox.getEvent.result",id:e.id}),"outbox.query":e=>u({type:"outbox.query.result",id:e.id,events:[]}),"outbox.subscribe":e=>u({type:"outbox.closed",subId:e.subId,reason:"reference shell complete"}),"outbox.close":N,"outbox.publish":e=>u({type:"outbox.publish.result",id:e.id,ok:!0}),"outbox.resolveRelays":e=>u({type:"outbox.resolveRelays.result",id:e.id,plan:{}}),"upload.info":e=>u({type:"upload.info.result",id:e.id,info:{rails:[{rail:"nip96",enabled:!0,returns:["https"]},{rail:"blossom",enabled:!0,returns:["https","blossom"]}]}}),"upload.upload":e=>u({type:"upload.upload.result",id:e.id,result:{url:Un}}),"upload.status":e=>u({type:"upload.status.result",id:e.id,status:{}}),"ble.open":e=>u({type:"ble.open.result",id:e.id,session:{id:"ble-reference",state:"open",device:{id:"reference-device",name:"Reference BLE"}}}),"ble.services":e=>u({type:"ble.services.result",id:e.id,services:[]}),"ble.read":e=>u({type:"ble.read.result",id:e.id,data:[]}),"ble.write":e=>u({type:"ble.write.result",id:e.id}),"ble.subscribe":e=>u({type:"ble.subscribe.result",id:e.id}),"ble.unsubscribe":e=>u({type:"ble.unsubscribe.result",id:e.id}),"ble.close":e=>u({type:"ble.close.result",id:e.id}),"common.encodeNip19":e=>u({type:"common.encodeNip19.result",id:e.id,ok:!0,value:"npub1reference",nip19Type:"npub"}),"common.decodeNip19":e=>u({type:"common.decodeNip19.result",id:e.id,ok:!0,nip19Type:"npub",hex:xe}),"common.getProfile":e=>u({type:"common.getProfile.result",id:e.id,ok:!0,pubkey:xe,profile:null}),"common.follows":e=>u({type:"common.follows.result",id:e.id,ok:!0,pubkeys:[]}),"common.follow":e=>u({type:"common.follow.result",id:e.id,ok:!0}),"common.unfollow":e=>u({type:"common.unfollow.result",id:e.id,ok:!0}),"common.react":e=>u({type:"common.react.result",id:e.id,ok:!0,eventId:"0".repeat(64)}),"common.report":e=>u({type:"common.report.result",id:e.id,ok:!0,eventId:"1".repeat(64)}),"webrtc.open":e=>u({type:"webrtc.open.result",id:e.id,session:{id:"webrtc-reference",scope:{type:"direct",pubkey:xe},channel:"default",state:"connecting"}}),"webrtc.send":e=>u({type:"webrtc.send.result",id:e.id}),"webrtc.close":e=>u({type:"webrtc.close.result",id:e.id}),"link.open":e=>u({type:"link.open.result",id:e.id,status:"opened"}),"count.query":e=>u({type:"count.query.result",id:e.id,ok:!0,count:0}),"lists.supported":e=>u({type:"lists.supported.result",id:e.id,lists:[]}),"lists.add":e=>u({type:"lists.add.result",id:e.id,ok:!0,added:0,skipped:0}),"lists.remove":e=>u({type:"lists.remove.result",id:e.id,ok:!0,removed:0,skipped:0}),"serial.open":e=>u({type:"serial.open.result",id:e.id,session:{id:`serial-${String(e.id)}`,state:"open"}}),"serial.write":e=>u({type:"serial.write.result",id:e.id}),"serial.close":e=>u({type:"serial.close.result",id:e.id}),"fs.info":e=>u({type:"fs.info.result",id:e.id,info:{roots:[{path:"/shared",name:"Shared files",permissions:["read","list","write","create","delete","watch"]}],limits:{maxReadBytes:1048576,maxWriteBytes:1048576,maxWatchCount:16}}}),"fs.pickFile":e=>ke("fs.pickFile.result",e.id,{path:"/picked/file.txt",kind:"file",name:"file.txt",permissions:["read"]}),"fs.pickFiles":e=>ke("fs.pickFiles.result",e.id,{path:"/picked/file.txt",kind:"file",name:"file.txt",permissions:["read"]}),"fs.pickDirectory":e=>ke("fs.pickDirectory.result",e.id,{path:"/picked",kind:"directory",name:"picked",permissions:["read","list"]}),"fs.pickSaveFile":e=>ke("fs.pickSaveFile.result",e.id,{path:"/picked/export.json",kind:"file",name:"export.json",permissions:["write","create"]}),"fs.stat":e=>u({type:"fs.stat.result",id:e.id,metadata:{path:e.path,kind:"file",size:0}}),"fs.list":e=>u({type:"fs.list.result",id:e.id,entries:[]}),"fs.read":e=>u({type:"fs.read.result",id:e.id,result:{data:"",offset:0,bytesRead:0,eof:!0,size:0}}),"fs.write":e=>u({type:"fs.write.result",id:e.id,result:{bytesWritten:0,size:0}}),"fs.mkdir":e=>u({type:"fs.mkdir.result",id:e.id}),"fs.remove":e=>u({type:"fs.remove.result",id:e.id}),"fs.move":e=>u({type:"fs.move.result",id:e.id}),"fs.watch":e=>u({type:"fs.watch.result",id:e.id,watchId:`watch-${String(e.id)}`}),"fs.unwatch":e=>u({type:"fs.unwatch.result",id:e.id})};function Dn(e){return(t,r)=>{const n=Mn(r),i=Nn(r);if(e.records.push({envelope:r,verdict:i,timestamp:e.now()}),!n||!i.ok)return[];const s=r;if(n==="intent.invoke")return e.intents.handleInvoke(t,s);if(n==="intent.available")return u({type:"intent.available.result",id:s.id,availability:e.intents.availability(s.archetype)});if(n==="intent.handlers")return u({type:"intent.handlers.result",id:s.id,handlers:[e.intents.availability("note")]});if(n==="inc.emit")return Fn(t,s,e.queueDelivery);const o=jn[n];return o?o(s):[]}}function Mn(e){if(!e||typeof e!="object")return;const t=e.type;return typeof t=="string"?t:void 0}function Fn(e,t,r){if(t.topic!==Be)return[];const n={type:"inc.event",topic:t.topic,sender:e.dTag};return"payload"in t&&(n.payload=t.payload),r(Hn,n),[]}function Se(e,t,r,n){return u({type:"intent.invoke.result",id:e,result:{ok:!1,archetype:t,action:r,handled:!1,error:n}})}function Wn(){return{handleInvoke:Zn,availability:Vn}}function Zn(e,t){const r=t.request;if(typeof r!="object"||r===null||Array.isArray(r))return Se(t.id,"","open","invalid intent request");const n=r,i=typeof n.archetype=="string"?n.archetype:"",s=typeof n.action=="string"?n.action:"open";return i?i!=="note"?Se(t.id,i,s,"no handler"):n.convention!==void 0&&n.convention!==Be?Se(t.id,i,s,"unsupported convention"):u({type:"intent.invoke.result",id:t.id,result:{ok:!0,archetype:i,action:s,handled:!0,handler:Vt,windowId:"reference-window",convention:typeof n.convention=="string"?n.convention:Be}}):Se(t.id,i,s,"intent request requires an archetype")}function Vn(e){return e!=="note"?{archetype:e,available:!1,candidates:[],hasDefault:!1}:{archetype:e,available:!0,candidates:[{dTag:Vt,actions:["open"],conventions:[Be],isDefault:!0}],hasDefault:!0}}function Kn(e={}){const t=[],r=Yn(),n=Dn({now:e.now??Date.now,records:t,queueDelivery:r.queue,intents:Wn()});return{get records(){return t},handle:i=>n(Cn,i),handleFrom:n,takeDeliveries:r.take,reset(){t.length=0,r.clear()}}}function Yn(){const e=new Map;return{queue(t,r){const n=e.get(t);n?n.push(r):e.set(t,[r])},take(t){const r=e.get(t)??[];return e.delete(t),r},clear(){e.clear()}}}function zn(e){return{manifestHtml:e.manifestHtml,manifestEvent:e.manifestEvent??null,sandbox:e.sandbox??{allowScripts:!0,allowSameOrigin:!1},installedGlobal:e.boot.installedGlobal,bootError:e.boot.bootError,emitted:e.boot.emitted,forbiddenGlobals:e.forbiddenGlobals??[],degraded:e.boot.degraded,lifecycle:e.lifecycle??null}}var Kt="__nappletConformance.error";function vt(e){return new Promise(t=>setTimeout(t,e))}function Gn(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}function Xn(e){return`
|
|
2
|
+
(() => {
|
|
3
|
+
const domains = ${JSON.stringify(e)};
|
|
4
|
+
const napplet = {};
|
|
5
|
+
for (const domain of domains) napplet[domain] = {};
|
|
6
|
+
const pending = new Map();
|
|
7
|
+
let seq = 0;
|
|
8
|
+
const nextId = () => {
|
|
9
|
+
try {
|
|
10
|
+
if (window.crypto && typeof window.crypto.randomUUID === 'function') return window.crypto.randomUUID();
|
|
11
|
+
} catch {}
|
|
12
|
+
seq += 1;
|
|
13
|
+
return 'conformance-' + Date.now().toString(36) + '-' + seq.toString(36);
|
|
14
|
+
};
|
|
15
|
+
const request = (message, resultType, errorType) => new Promise((resolve, reject) => {
|
|
16
|
+
const id = message.id || nextId();
|
|
17
|
+
const timeout = window.setTimeout(() => {
|
|
18
|
+
pending.delete(id);
|
|
19
|
+
reject(new Error(message.type + ' timed out'));
|
|
20
|
+
}, 5000);
|
|
21
|
+
pending.set(id, { resolve, reject, resultType, errorType, timeout });
|
|
22
|
+
window.parent.postMessage({ ...message, id }, '*');
|
|
23
|
+
});
|
|
24
|
+
window.addEventListener('message', (event) => {
|
|
25
|
+
const msg = event.data;
|
|
26
|
+
if (!msg || typeof msg !== 'object' || typeof msg.id !== 'string') return;
|
|
27
|
+
const slot = pending.get(msg.id);
|
|
28
|
+
if (!slot) return;
|
|
29
|
+
if (msg.type !== slot.resultType && msg.type !== slot.errorType) return;
|
|
30
|
+
pending.delete(msg.id);
|
|
31
|
+
window.clearTimeout(slot.timeout);
|
|
32
|
+
if (msg.type === slot.errorType) {
|
|
33
|
+
slot.reject(new Error(msg.message ? msg.error + ': ' + msg.message : String(msg.error || 'request failed')));
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
slot.resolve(msg);
|
|
37
|
+
});
|
|
38
|
+
if (napplet.resource) {
|
|
39
|
+
napplet.resource.info = () =>
|
|
40
|
+
request({ type: 'resource.info' }, 'resource.info.result', 'resource.info.error')
|
|
41
|
+
.then((msg) => msg.info);
|
|
42
|
+
napplet.resource.bytes = (url, options) => {
|
|
43
|
+
const message = { type: 'resource.bytes', url: String(url) };
|
|
44
|
+
if (options && options.servers !== undefined) message.servers = options.servers;
|
|
45
|
+
return request(message, 'resource.bytes.result', 'resource.bytes.error')
|
|
46
|
+
.then((msg) => msg.blob);
|
|
47
|
+
};
|
|
48
|
+
napplet.resource.bytesMany = (requests) =>
|
|
49
|
+
request({ type: 'resource.bytesMany', requests: Array.from(requests || []) }, 'resource.bytesMany.result', 'resource.bytesMany.error')
|
|
50
|
+
.then((msg) => msg.items);
|
|
51
|
+
napplet.resource.bytesAsObjectURL = (url) => {
|
|
52
|
+
const handle = { url: '', revoke: () => {} };
|
|
53
|
+
let objectUrl = '';
|
|
54
|
+
let revoked = false;
|
|
55
|
+
const ready = napplet.resource.bytes(url).then((blob) => {
|
|
56
|
+
if (revoked) return;
|
|
57
|
+
objectUrl = URL.createObjectURL(blob);
|
|
58
|
+
handle.url = objectUrl;
|
|
59
|
+
return objectUrl;
|
|
60
|
+
});
|
|
61
|
+
handle.revoke = () => {
|
|
62
|
+
if (revoked) return;
|
|
63
|
+
revoked = true;
|
|
64
|
+
if (objectUrl) URL.revokeObjectURL(objectUrl);
|
|
65
|
+
};
|
|
66
|
+
Object.defineProperty(handle, 'ready', { value: ready, enumerable: false });
|
|
67
|
+
return handle;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
window.napplet = napplet;
|
|
71
|
+
const report = (reason) => {
|
|
72
|
+
try {
|
|
73
|
+
window.parent.postMessage({ type: '${Kt}', reason: String(reason && reason.message || reason) }, '*');
|
|
74
|
+
} catch {}
|
|
75
|
+
};
|
|
76
|
+
window.addEventListener('error', (event) => report(event.error || event.message));
|
|
77
|
+
window.addEventListener('unhandledrejection', (event) => report(event.reason));
|
|
78
|
+
})();
|
|
79
|
+
`}function Jn(e,t,r){const n=`<base href="${Gn(t)}">`,i=`<script>${Xn(r)}<\/script>`,s=/<head(?:\s[^>]*)?>/i.exec(e);if(s){const o=s.index+s[0].length;return`${e.slice(0,o)}${n}${i}${e.slice(o)}`}return`${n}${i}${e}`}function Qn(e){if(!e.startsWith("data:"))return null;const t=e.indexOf(",");if(t<0)return"";const r=e.slice(0,t),n=e.slice(t+1);return r.endsWith(";base64")?atob(n):decodeURIComponent(n)}async function er(e){if(e==="about:blank")return"<!doctype html><html><head></head><body></body></html>";const t=Qn(e);if(t!==null)return t;const r=await fetch(e);if(!r.ok)throw new Error(`Failed to fetch napplet HTML: ${r.status} ${r.statusText}`);return r.text()}async function Et(e,t,r,n){const i=Kn(),s=r.createElement("iframe");s.setAttribute("sandbox",t.allowSameOrigin?"allow-scripts allow-same-origin":"allow-scripts"),s.setAttribute("aria-hidden","true"),s.style.position="absolute",s.style.width="1px",s.style.height="1px",s.style.left="-9999px";let o=null;const c=f=>{if(f.source!==s.contentWindow)return;const h=f.data;if(h&&typeof h=="object"&&h.type===Kt){o=`napplet boot error: ${String(h.reason??"unknown error")}`;return}const g=i.handle(f.data),y=f.source;for(const b of g)y?.postMessage(b,"*")};let a=!1;const d=new Promise(f=>{s.addEventListener("load",()=>{a=!0,f()},{once:!0})});n.addEventListener("message",c),(r.body??r.documentElement).appendChild(s);try{const f=await er(t.url);s.srcdoc=Jn(f,t.url,e)}catch(f){o=f instanceof Error?f.message:String(f)}if(!o){const f=Symbol("timeout");await Promise.race([d.then(()=>"loaded"),vt(t.readyTimeoutMs).then(()=>f)])===f||!a?o=`napplet did not boot (iframe did not load within ${t.readyTimeoutMs}ms; a conformant napplet must run under sandbox="allow-scripts" without allow-same-origin)`:await vt(t.settleMs)}n.removeEventListener("message",c);try{s.remove()}catch{}return{installedGlobal:o===null,bootError:o,emitted:[...i.records]}}async function tr(e){const t=e.document??document,r=e.window??window,n={url:e.url,readyTimeoutMs:e.readyTimeoutMs??5e3,settleMs:e.settleMs,allowSameOrigin:e.allowSameOrigin??!1},i=await Et(at,n,t,r);let s=null;{const o=await Et([],n,t,r);s={bootError:o.bootError,emitted:o.emitted}}return{installedGlobal:i.installedGlobal,bootError:i.bootError,emitted:i.emitted,degraded:s}}var nr=e=>({status:"pass",detail:e}),rr=(e,t)=>({status:"fail",detail:e,diagnostics:t}),ir=e=>({status:"skip",detail:e}),O={pass:nr,fail:rr,skip:ir};function sr(e,t){return lt(e.manifestEvent).errors.filter(r=>t.includes(r.code))}function Me(e,t,r){return{id:e,area:"manifest",severity:"error",title:t,run:n=>{if(!n.manifestEvent)return O.skip("No NIP-5D manifest event was resolved");const i=sr(n,r);return i.length?O.fail(i[0].message,i):O.pass()}}}var or=[Me("manifest/event-kind","Resolved event is a NIP-5D napplet manifest",["invalid-napplet-kind","missing-d-tag","unexpected-d-tag"]),Me("manifest/index-html","Manifest declares a hashed /index.html",["missing-index-html","invalid-index-html-hash"]),Me("manifest/requires","requires tags are bare known NAP domains",["invalid-required-nap","unknown-required-nap"]),{id:"boot/sandbox-allow-scripts",area:"boot",severity:"error",title:"Runs under allow-scripts without allow-same-origin",run:e=>e.sandbox.allowScripts?e.sandbox.allowSameOrigin?O.fail("Napplet relied on allow-same-origin, which a shell must not grant"):O.pass():O.fail("Napplet was not loaded with allow-scripts")},{id:"boot/installs-global",area:"boot",severity:"error",title:"Runs after runtime-injected window.napplet is installed",run:e=>e.installedGlobal?O.pass():O.fail("runtime did not inject window.napplet before load")},{id:"boot/no-boot-error",area:"boot",severity:"error",title:"Boots without an uncaught error",run:e=>e.bootError?O.fail(e.bootError):O.pass()},{id:"boot/no-forbidden-globals",area:"boot",severity:"error",title:"Does not access forbidden browser authority surfaces",run:e=>e.forbiddenGlobals.length?O.fail(`Accessed forbidden surface(s): ${e.forbiddenGlobals.join(", ")}`,e.forbiddenGlobals):O.pass()},{id:"wire/envelope-well-formed",area:"wire",severity:"error",title:"Every emitted envelope is well-formed",run:e=>{if(e.emitted.length===0)return O.skip("Napplet emitted no envelopes");const t=e.emitted.filter(n=>!n.verdict.ok);if(t.length===0)return O.pass(`${e.emitted.length} envelope(s) valid`);const r=t.map(n=>({envelope:n.envelope,errors:n.verdict.errors}));return O.fail(`${t.length}/${e.emitted.length} emitted envelope(s) invalid`,r)}},{id:"degrade/domain-absence",area:"degradation",severity:"error",title:"Does not crash when no NAP domains are injected",run:e=>e.degraded?e.degraded.bootError?O.fail(`Crashed with no injected domains: ${e.degraded.bootError}`):O.pass():O.skip("Host did not run the degraded (no-capabilities) pass")},{id:"lifecycle/clean-teardown",area:"lifecycle",severity:"warning",title:"Tears down listeners on unload",run:e=>e.lifecycle?e.lifecycle.listenerLeak?O.fail("Message listeners remained after unload"):O.pass():O.skip("Lifecycle not measured")}];function ar(e,t={}){const r=t.now??(()=>Date.now()),n=t.checks??or,i=r(),s=n.map(a=>{const d=a.run(e);return{id:a.id,area:a.area,severity:a.severity,title:a.title,status:d.status,detail:d.detail,diagnostics:d.diagnostics}}),o={total:s.length,passed:s.filter(a=>a.status==="pass").length,failed:s.filter(a=>a.status==="fail").length,skipped:s.filter(a=>a.status==="skip").length,errors:s.filter(a=>a.status==="fail"&&a.severity==="error").length,warnings:s.filter(a=>a.status==="fail"&&a.severity==="warning").length};return{napplet:e.manifestEvent?Zt(e.manifestEvent):void 0,startedAt:i,finishedAt:r(),checks:s,summary:o,ok:o.errors===0}}/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */function cr(e){return e instanceof Uint8Array||ArrayBuffer.isView(e)&&e.constructor.name==="Uint8Array"}function dt(e,t=""){if(!Number.isSafeInteger(e)||e<0){const r=t&&`"${t}" `;throw new Error(`${r}expected integer >= 0, got ${e}`)}}function D(e,t,r=""){const n=cr(e),i=e?.length,s=t!==void 0;if(!n||s&&i!==t){const o=r&&`"${r}" `,c=s?` of length ${t}`:"",a=n?`length=${i}`:`type=${typeof e}`;throw new Error(o+"expected Uint8Array"+c+", got "+a)}return e}function xt(e,t=!0){if(e.destroyed)throw new Error("Hash instance has been destroyed");if(t&&e.finished)throw new Error("Hash#digest() has already been called")}function lr(e,t){D(e,void 0,"digestInto() output");const r=t.outputLen;if(e.length<r)throw new Error('"digestInto() output" expected to be of length >='+r)}function Je(...e){for(let t=0;t<e.length;t++)e[t].fill(0)}function Fe(e){return new DataView(e.buffer,e.byteOffset,e.byteLength)}function z(e,t){return e<<32-t|e>>>t}const Yt=typeof Uint8Array.from([]).toHex=="function"&&typeof Uint8Array.fromHex=="function",dr=Array.from({length:256},(e,t)=>t.toString(16).padStart(2,"0"));function _(e){if(D(e),Yt)return e.toHex();let t="";for(let r=0;r<e.length;r++)t+=dr[e[r]];return t}const J={_0:48,_9:57,A:65,F:70,a:97,f:102};function kt(e){if(e>=J._0&&e<=J._9)return e-J._0;if(e>=J.A&&e<=J.F)return e-(J.A-10);if(e>=J.a&&e<=J.f)return e-(J.a-10)}function X(e){if(typeof e!="string")throw new Error("hex string expected, got "+typeof e);if(Yt)return Uint8Array.fromHex(e);const t=e.length,r=t/2;if(t%2)throw new Error("hex string expected, got unpadded hex of length "+t);const n=new Uint8Array(r);for(let i=0,s=0;i<r;i++,s+=2){const o=kt(e.charCodeAt(s)),c=kt(e.charCodeAt(s+1));if(o===void 0||c===void 0){const a=e[s]+e[s+1];throw new Error('hex string expected, got non-hex character "'+a+'" at index '+s)}n[i]=o*16+c}return n}function Oe(...e){let t=0;for(let n=0;n<e.length;n++){const i=e[n];D(i),t+=i.length}const r=new Uint8Array(t);for(let n=0,i=0;n<e.length;n++){const s=e[n];r.set(s,i),i+=s.length}return r}function ur(e,t={}){const r=(i,s)=>e(s).update(i).digest(),n=e(void 0);return r.outputLen=n.outputLen,r.blockLen=n.blockLen,r.create=i=>e(i),Object.assign(r,t),Object.freeze(r)}function zt(e=32){const t=typeof globalThis=="object"?globalThis.crypto:null;if(typeof t?.getRandomValues!="function")throw new Error("crypto.getRandomValues must be defined");return t.getRandomValues(new Uint8Array(e))}const fr=e=>({oid:Uint8Array.from([6,9,96,134,72,1,101,3,4,2,e])});/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */function Gt(e){return e instanceof Uint8Array||ArrayBuffer.isView(e)&&e.constructor.name==="Uint8Array"}function Xt(e,t){return Array.isArray(t)?t.length===0?!0:e?t.every(r=>typeof r=="string"):t.every(r=>Number.isSafeInteger(r)):!1}function hr(e){if(typeof e!="function")throw new Error("function expected");return!0}function me(e,t){if(typeof t!="string")throw new Error(`${e}: string expected`);return!0}function Jt(e){if(!Number.isSafeInteger(e))throw new Error(`invalid integer: ${e}`)}function Qe(e){if(!Array.isArray(e))throw new Error("array expected")}function Qt(e,t){if(!Xt(!0,t))throw new Error(`${e}: array of strings expected`)}function en(e,t){if(!Xt(!1,t))throw new Error(`${e}: array of numbers expected`)}function pr(...e){const t=s=>s,r=(s,o)=>c=>s(o(c)),n=e.map(s=>s.encode).reduceRight(r,t),i=e.map(s=>s.decode).reduce(r,t);return{encode:n,decode:i}}function gr(e){const t=typeof e=="string"?e.split(""):e,r=t.length;Qt("alphabet",t);const n=new Map(t.map((i,s)=>[i,s]));return{encode:i=>(Qe(i),i.map(s=>{if(!Number.isSafeInteger(s)||s<0||s>=r)throw new Error(`alphabet.encode: digit index outside alphabet "${s}". Allowed: ${e}`);return t[s]})),decode:i=>(Qe(i),i.map(s=>{me("alphabet.decode",s);const o=n.get(s);if(o===void 0)throw new Error(`Unknown letter: "${s}". Allowed: ${e}`);return o}))}}function yr(e=""){return me("join",e),{encode:t=>(Qt("join.decode",t),t.join(e)),decode:t=>(me("join.decode",t),t.split(e))}}const tn=(e,t)=>t===0?e:tn(t,e%t),qe=(e,t)=>e+(t-tn(e,t)),Ae=(()=>{let e=[];for(let t=0;t<40;t++)e.push(2**t);return e})();function et(e,t,r,n){if(Qe(e),t<=0||t>32)throw new Error(`convertRadix2: wrong from=${t}`);if(r<=0||r>32)throw new Error(`convertRadix2: wrong to=${r}`);if(qe(t,r)>32)throw new Error(`convertRadix2: carry overflow from=${t} to=${r} carryBits=${qe(t,r)}`);let i=0,s=0;const o=Ae[t],c=Ae[r]-1,a=[];for(const d of e){if(Jt(d),d>=o)throw new Error(`convertRadix2: invalid data word=${d} from=${t}`);if(i=i<<t|d,s+t>32)throw new Error(`convertRadix2: carry overflow pos=${s} from=${t}`);for(s+=t;s>=r;s-=r)a.push((i>>s-r&c)>>>0);const f=Ae[s];if(f===void 0)throw new Error("invalid carry");i&=f-1}if(i=i<<r-s&c,!n&&s>=t)throw new Error("Excess padding");if(!n&&i>0)throw new Error(`Non-zero padding: ${i}`);return n&&s>0&&a.push(i>>>0),a}function mr(e,t=!1){if(Jt(e),e<=0||e>32)throw new Error("radix2: bits should be in (0..32]");if(qe(8,e)>32||qe(e,8)>32)throw new Error("radix2: carry overflow");return{encode:r=>{if(!Gt(r))throw new Error("radix2.encode input should be Uint8Array");return et(Array.from(r),8,e,!t)},decode:r=>(en("radix2.decode",r),Uint8Array.from(et(r,e,8,t)))}}function St(e){return hr(e),function(...t){try{return e.apply(null,t)}catch{}}}const tt=pr(gr("qpzry9x8gf2tvdw0s3jn54khce6mua7l"),yr("")),Rt=[996825010,642813549,513874426,1027748829,705979059];function fe(e){const t=e>>25;let r=(e&33554431)<<5;for(let n=0;n<Rt.length;n++)(t>>n&1)===1&&(r^=Rt[n]);return r}function $t(e,t,r=1){const n=e.length;let i=1;for(let s=0;s<n;s++){const o=e.charCodeAt(s);if(o<33||o>126)throw new Error(`Invalid prefix (${e})`);i=fe(i)^o>>5}i=fe(i);for(let s=0;s<n;s++)i=fe(i)^e.charCodeAt(s)&31;for(let s of t)i=fe(i)^s;for(let s=0;s<6;s++)i=fe(i);return i^=r,tt.encode(et([i%Ae[30]],30,5,!1))}function br(e){const t=e==="bech32"?1:734539939,r=mr(5),n=r.decode,i=r.encode,s=St(n);function o(h,g,y=90){me("bech32.encode prefix",h),Gt(g)&&(g=Array.from(g)),en("bech32.encode",g);const b=h.length;if(b===0)throw new TypeError(`Invalid prefix length ${b}`);const E=b+7+g.length;if(y!==!1&&E>y)throw new TypeError(`Length ${E} exceeds limit ${y}`);const q=h.toLowerCase(),L=$t(q,g,t);return`${q}1${tt.encode(g)}${L}`}function c(h,g=90){me("bech32.decode input",h);const y=h.length;if(y<8||g!==!1&&y>g)throw new TypeError(`invalid string length: ${y} (${h}). Expected (8..${g})`);const b=h.toLowerCase();if(h!==b&&h!==h.toUpperCase())throw new Error("String must be lowercase or uppercase");const E=b.lastIndexOf("1");if(E===0||E===-1)throw new Error('Letter "1" must be present between prefix and data only');const q=b.slice(0,E),L=b.slice(E+1);if(L.length<6)throw new Error("Data must be at least 6 characters long");const K=tt.decode(L).slice(0,-6),Q=$t(q,K,t);if(!L.endsWith(Q))throw new Error(`Invalid checksum in ${h}: expected "${Q}"`);return{prefix:q,words:K}}const a=St(c);function d(h){const{prefix:g,words:y}=c(h,!1);return{prefix:g,words:y,bytes:n(y)}}function f(h,g){return o(h,i(g))}return{encode:o,decode:c,encodeFromBytes:f,decodeToBytes:d,decodeUnsafe:a,fromWords:n,fromWordsUnsafe:s,toWords:i}}const It=br("bech32");var Re=new TextDecoder("utf-8");new TextEncoder;var wr=5e3;function vr(e){try{return e.startsWith("nostr:")&&(e=e.substring(6)),Er(e)}catch{return{type:"invalid",data:null}}}function Er(e){let{prefix:t,words:r}=It.decode(e,wr),n=new Uint8Array(It.fromWords(r));switch(t){case"nprofile":{let i=We(n);if(!i[0]?.[0])throw new Error("missing TLV 0 for nprofile");if(i[0][0].length!==32)throw new Error("TLV 0 should be 32 bytes");return{type:"nprofile",data:{pubkey:_(i[0][0]),relays:i[1]?i[1].map(s=>Re.decode(s)):[]}}}case"nevent":{let i=We(n);if(!i[0]?.[0])throw new Error("missing TLV 0 for nevent");if(i[0][0].length!==32)throw new Error("TLV 0 should be 32 bytes");if(i[2]&&i[2][0].length!==32)throw new Error("TLV 2 should be 32 bytes");if(i[3]&&i[3][0].length!==4)throw new Error("TLV 3 should be 4 bytes");return{type:"nevent",data:{id:_(i[0][0]),relays:i[1]?i[1].map(s=>Re.decode(s)):[],author:i[2]?.[0]?_(i[2][0]):void 0,kind:i[3]?.[0]?parseInt(_(i[3][0]),16):void 0}}}case"naddr":{let i=We(n);if(!i[0]?.[0])throw new Error("missing TLV 0 for naddr");if(!i[2]?.[0])throw new Error("missing TLV 2 for naddr");if(i[2][0].length!==32)throw new Error("TLV 2 should be 32 bytes");if(!i[3]?.[0])throw new Error("missing TLV 3 for naddr");if(i[3][0].length!==4)throw new Error("TLV 3 should be 4 bytes");return{type:"naddr",data:{identifier:Re.decode(i[0][0]),pubkey:_(i[2][0]),kind:parseInt(_(i[3][0]),16),relays:i[1]?i[1].map(s=>Re.decode(s)):[]}}}case"nsec":return{type:t,data:n};case"npub":case"note":return{type:t,data:_(n)};default:throw new Error(`unknown prefix ${t}`)}}function We(e){let t={},r=e;for(;r.length>0;){let n=r[0],i=r[1],s=r.slice(2,2+i);if(r=r.slice(2+i),s.length<i)throw new Error(`not enough data to read on TLV ${n}`);t[n]=t[n]||[],t[n].push(s)}return t}function xr(e,t,r){return e&t^~e&r}function kr(e,t,r){return e&t^e&r^t&r}class Sr{blockLen;outputLen;padOffset;isLE;buffer;view;finished=!1;length=0;pos=0;destroyed=!1;constructor(t,r,n,i){this.blockLen=t,this.outputLen=r,this.padOffset=n,this.isLE=i,this.buffer=new Uint8Array(t),this.view=Fe(this.buffer)}update(t){xt(this),D(t);const{view:r,buffer:n,blockLen:i}=this,s=t.length;for(let o=0;o<s;){const c=Math.min(i-this.pos,s-o);if(c===i){const a=Fe(t);for(;i<=s-o;o+=i)this.process(a,o);continue}n.set(t.subarray(o,o+c),this.pos),this.pos+=c,o+=c,this.pos===i&&(this.process(r,0),this.pos=0)}return this.length+=t.length,this.roundClean(),this}digestInto(t){xt(this),lr(t,this),this.finished=!0;const{buffer:r,view:n,blockLen:i,isLE:s}=this;let{pos:o}=this;r[o++]=128,Je(this.buffer.subarray(o)),this.padOffset>i-o&&(this.process(n,0),o=0);for(let h=o;h<i;h++)r[h]=0;n.setBigUint64(i-8,BigInt(this.length*8),s),this.process(n,0);const c=Fe(t),a=this.outputLen;if(a%4)throw new Error("_sha2: outputLen must be aligned to 32bit");const d=a/4,f=this.get();if(d>f.length)throw new Error("_sha2: outputLen bigger than state");for(let h=0;h<d;h++)c.setUint32(4*h,f[h],s)}digest(){const{buffer:t,outputLen:r}=this;this.digestInto(t);const n=t.slice(0,r);return this.destroy(),n}_cloneInto(t){t||=new this.constructor,t.set(...this.get());const{blockLen:r,buffer:n,length:i,finished:s,destroyed:o,pos:c}=this;return t.destroyed=o,t.finished=s,t.length=i,t.pos=c,i%r&&t.buffer.set(n),t}clone(){return this._cloneInto()}}const ee=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),Rr=Uint32Array.from([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),te=new Uint32Array(64);class $r extends Sr{constructor(t){super(64,t,8,!1)}get(){const{A:t,B:r,C:n,D:i,E:s,F:o,G:c,H:a}=this;return[t,r,n,i,s,o,c,a]}set(t,r,n,i,s,o,c,a){this.A=t|0,this.B=r|0,this.C=n|0,this.D=i|0,this.E=s|0,this.F=o|0,this.G=c|0,this.H=a|0}process(t,r){for(let h=0;h<16;h++,r+=4)te[h]=t.getUint32(r,!1);for(let h=16;h<64;h++){const g=te[h-15],y=te[h-2],b=z(g,7)^z(g,18)^g>>>3,E=z(y,17)^z(y,19)^y>>>10;te[h]=E+te[h-7]+b+te[h-16]|0}let{A:n,B:i,C:s,D:o,E:c,F:a,G:d,H:f}=this;for(let h=0;h<64;h++){const g=z(c,6)^z(c,11)^z(c,25),y=f+g+xr(c,a,d)+Rr[h]+te[h]|0,E=(z(n,2)^z(n,13)^z(n,22))+kr(n,i,s)|0;f=d,d=a,a=c,c=o+y|0,o=s,s=i,i=n,n=y+E|0}n=n+this.A|0,i=i+this.B|0,s=s+this.C|0,o=o+this.D|0,c=c+this.E|0,a=a+this.F|0,d=d+this.G|0,f=f+this.H|0,this.set(n,i,s,o,c,a,d,f)}roundClean(){Je(te)}destroy(){this.set(0,0,0,0,0,0,0,0),Je(this.buffer)}}class Ir extends $r{A=ee[0]|0;B=ee[1]|0;C=ee[2]|0;D=ee[3]|0;E=ee[4]|0;F=ee[5]|0;G=ee[6]|0;H=ee[7]|0;constructor(){super(32)}}const Ne=ur(()=>new Ir,fr(1));/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */const ut=BigInt(0),nt=BigInt(1);function At(e,t=""){if(typeof e!="boolean"){const r=t&&`"${t}" `;throw new Error(r+"expected boolean, got type="+typeof e)}return e}function Ar(e){if(typeof e=="bigint"){if(!Or(e))throw new Error("positive bigint expected, got "+e)}else dt(e);return e}function nn(e){if(typeof e!="string")throw new Error("hex string expected, got "+typeof e);return e===""?ut:BigInt("0x"+e)}function ft(e){return nn(_(e))}function rn(e){return nn(_(Tr(D(e)).reverse()))}function ht(e,t){dt(t),e=Ar(e);const r=X(e.toString(16).padStart(t*2,"0"));if(r.length!==t)throw new Error("number too large");return r}function sn(e,t){return ht(e,t).reverse()}function Tr(e){return Uint8Array.from(e)}function Br(e){return Uint8Array.from(e,(t,r)=>{const n=t.charCodeAt(0);if(t.length!==1||n>127)throw new Error(`string contains non-ASCII character "${e[r]}" with code ${n} at position ${r}`);return n})}const Or=e=>typeof e=="bigint"&&ut<=e;function qr(e){let t;for(t=0;e>ut;e>>=nt,t+=1);return t}const on=e=>(nt<<BigInt(e))-nt;function an(e,t={},r={}){if(!e||typeof e!="object")throw new Error("expected valid options object");function n(s,o,c){const a=e[s];if(c&&a===void 0)return;const d=typeof a;if(d!==o||a===null)throw new Error(`param "${s}" is invalid: expected ${o}, got ${d}`)}const i=(s,o)=>Object.entries(s).forEach(([c,a])=>n(c,a,o));i(t,!1),i(r,!0)}function Tt(e){const t=new WeakMap;return(r,...n)=>{const i=t.get(r);if(i!==void 0)return i;const s=e(r,...n);return t.set(r,s),s}}/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */const j=BigInt(0),H=BigInt(1),se=BigInt(2),cn=BigInt(3),ln=BigInt(4),dn=BigInt(5),Nr=BigInt(7),un=BigInt(8),Lr=BigInt(9),fn=BigInt(16);function V(e,t){const r=e%t;return r>=j?r:t+r}function F(e,t,r){let n=e;for(;t-- >j;)n*=n,n%=r;return n}function Bt(e,t){if(e===j)throw new Error("invert: expected non-zero number");if(t<=j)throw new Error("invert: expected positive modulus, got "+t);let r=V(e,t),n=t,i=j,s=H;for(;r!==j;){const c=n/r,a=n%r,d=i-s*c;n=r,r=a,i=s,s=d}if(n!==H)throw new Error("invert: does not exist");return V(i,t)}function pt(e,t,r){if(!e.eql(e.sqr(t),r))throw new Error("Cannot find square root")}function hn(e,t){const r=(e.ORDER+H)/ln,n=e.pow(t,r);return pt(e,n,t),n}function Pr(e,t){const r=(e.ORDER-dn)/un,n=e.mul(t,se),i=e.pow(n,r),s=e.mul(t,i),o=e.mul(e.mul(s,se),i),c=e.mul(s,e.sub(o,e.ONE));return pt(e,c,t),c}function _r(e){const t=Ce(e),r=pn(e),n=r(t,t.neg(t.ONE)),i=r(t,n),s=r(t,t.neg(n)),o=(e+Nr)/fn;return(c,a)=>{let d=c.pow(a,o),f=c.mul(d,n);const h=c.mul(d,i),g=c.mul(d,s),y=c.eql(c.sqr(f),a),b=c.eql(c.sqr(h),a);d=c.cmov(d,f,y),f=c.cmov(g,h,b);const E=c.eql(c.sqr(f),a),q=c.cmov(d,f,E);return pt(c,q,a),q}}function pn(e){if(e<cn)throw new Error("sqrt is not defined for small field");let t=e-H,r=0;for(;t%se===j;)t/=se,r++;let n=se;const i=Ce(e);for(;Ot(i,n)===1;)if(n++>1e3)throw new Error("Cannot find square root: probably non-prime P");if(r===1)return hn;let s=i.pow(n,t);const o=(t+H)/se;return function(a,d){if(a.is0(d))return d;if(Ot(a,d)!==1)throw new Error("Cannot find square root");let f=r,h=a.mul(a.ONE,s),g=a.pow(d,t),y=a.pow(d,o);for(;!a.eql(g,a.ONE);){if(a.is0(g))return a.ZERO;let b=1,E=a.sqr(g);for(;!a.eql(E,a.ONE);)if(b++,E=a.sqr(E),b===f)throw new Error("Cannot find square root");const q=H<<BigInt(f-b-1),L=a.pow(h,q);f=b,h=a.sqr(L),g=a.mul(g,h),y=a.mul(y,L)}return y}}function Cr(e){return e%ln===cn?hn:e%un===dn?Pr:e%fn===Lr?_r(e):pn(e)}const Ur=["create","isValid","is0","neg","inv","sqrt","sqr","eql","add","sub","mul","pow","div","addN","subN","mulN","sqrN"];function Hr(e){const t={ORDER:"bigint",BYTES:"number",BITS:"number"},r=Ur.reduce((n,i)=>(n[i]="function",n),t);return an(e,r),e}function jr(e,t,r){if(r<j)throw new Error("invalid exponent, negatives unsupported");if(r===j)return e.ONE;if(r===H)return t;let n=e.ONE,i=t;for(;r>j;)r&H&&(n=e.mul(n,i)),i=e.sqr(i),r>>=H;return n}function gn(e,t,r=!1){const n=new Array(t.length).fill(r?e.ZERO:void 0),i=t.reduce((o,c,a)=>e.is0(c)?o:(n[a]=o,e.mul(o,c)),e.ONE),s=e.inv(i);return t.reduceRight((o,c,a)=>e.is0(c)?o:(n[a]=e.mul(o,n[a]),e.mul(o,c)),s),n}function Ot(e,t){const r=(e.ORDER-H)/se,n=e.pow(t,r),i=e.eql(n,e.ONE),s=e.eql(n,e.ZERO),o=e.eql(n,e.neg(e.ONE));if(!i&&!s&&!o)throw new Error("invalid Legendre symbol result");return i?1:s?0:-1}function Dr(e,t){t!==void 0&&dt(t);const r=t!==void 0?t:e.toString(2).length,n=Math.ceil(r/8);return{nBitLength:r,nByteLength:n}}class Mr{ORDER;BITS;BYTES;isLE;ZERO=j;ONE=H;_lengths;_sqrt;_mod;constructor(t,r={}){if(t<=j)throw new Error("invalid field: expected ORDER > 0, got "+t);let n;this.isLE=!1,r!=null&&typeof r=="object"&&(typeof r.BITS=="number"&&(n=r.BITS),typeof r.sqrt=="function"&&(this.sqrt=r.sqrt),typeof r.isLE=="boolean"&&(this.isLE=r.isLE),r.allowedLengths&&(this._lengths=r.allowedLengths?.slice()),typeof r.modFromBytes=="boolean"&&(this._mod=r.modFromBytes));const{nBitLength:i,nByteLength:s}=Dr(t,n);if(s>2048)throw new Error("invalid field: expected ORDER of <= 2048 bytes");this.ORDER=t,this.BITS=i,this.BYTES=s,this._sqrt=void 0,Object.preventExtensions(this)}create(t){return V(t,this.ORDER)}isValid(t){if(typeof t!="bigint")throw new Error("invalid field element: expected bigint, got "+typeof t);return j<=t&&t<this.ORDER}is0(t){return t===j}isValidNot0(t){return!this.is0(t)&&this.isValid(t)}isOdd(t){return(t&H)===H}neg(t){return V(-t,this.ORDER)}eql(t,r){return t===r}sqr(t){return V(t*t,this.ORDER)}add(t,r){return V(t+r,this.ORDER)}sub(t,r){return V(t-r,this.ORDER)}mul(t,r){return V(t*r,this.ORDER)}pow(t,r){return jr(this,t,r)}div(t,r){return V(t*Bt(r,this.ORDER),this.ORDER)}sqrN(t){return t*t}addN(t,r){return t+r}subN(t,r){return t-r}mulN(t,r){return t*r}inv(t){return Bt(t,this.ORDER)}sqrt(t){return this._sqrt||(this._sqrt=Cr(this.ORDER)),this._sqrt(this,t)}toBytes(t){return this.isLE?sn(t,this.BYTES):ht(t,this.BYTES)}fromBytes(t,r=!1){D(t);const{_lengths:n,BYTES:i,isLE:s,ORDER:o,_mod:c}=this;if(n){if(!n.includes(t.length)||t.length>i)throw new Error("Field.fromBytes: expected "+n+" bytes, got "+t.length);const d=new Uint8Array(i);d.set(t,s?0:d.length-t.length),t=d}if(t.length!==i)throw new Error("Field.fromBytes: expected "+i+" bytes, got "+t.length);let a=s?rn(t):ft(t);if(c&&(a=V(a,o)),!r&&!this.isValid(a))throw new Error("invalid field element: outside of range 0..ORDER");return a}invertBatch(t){return gn(this,t)}cmov(t,r,n){return n?r:t}}function Ce(e,t={}){return new Mr(e,t)}function yn(e){if(typeof e!="bigint")throw new Error("field order must be bigint");const t=e.toString(2).length;return Math.ceil(t/8)}function Fr(e){const t=yn(e);return t+Math.ceil(t/2)}function Wr(e,t,r=!1){D(e);const n=e.length,i=yn(t),s=Fr(t);if(n<16||n<s||n>1024)throw new Error("expected "+s+"-1024 bytes of input, got "+n);const o=r?rn(e):ft(e),c=V(o,t-H)+H;return r?sn(c,i):ht(c,i)}/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */const le=BigInt(0),oe=BigInt(1);function Le(e,t){const r=t.negate();return e?r:t}function qt(e,t){const r=gn(e.Fp,t.map(n=>n.Z));return t.map((n,i)=>e.fromAffine(n.toAffine(r[i])))}function mn(e,t){if(!Number.isSafeInteger(e)||e<=0||e>t)throw new Error("invalid window size, expected [1.."+t+"], got W="+e)}function Ze(e,t){mn(e,t);const r=Math.ceil(t/e)+1,n=2**(e-1),i=2**e,s=on(e),o=BigInt(e);return{windows:r,windowSize:n,mask:s,maxNumber:i,shiftBy:o}}function Nt(e,t,r){const{windowSize:n,mask:i,maxNumber:s,shiftBy:o}=r;let c=Number(e&i),a=e>>o;c>n&&(c-=s,a+=oe);const d=t*n,f=d+Math.abs(c)-1,h=c===0,g=c<0,y=t%2!==0;return{nextN:a,offset:f,isZero:h,isNeg:g,isNegF:y,offsetF:d}}const Ve=new WeakMap,bn=new WeakMap;function Ke(e){return bn.get(e)||1}function Lt(e){if(e!==le)throw new Error("invalid wNAF")}class Zr{BASE;ZERO;Fn;bits;constructor(t,r){this.BASE=t.BASE,this.ZERO=t.ZERO,this.Fn=t.Fn,this.bits=r}_unsafeLadder(t,r,n=this.ZERO){let i=t;for(;r>le;)r&oe&&(n=n.add(i)),i=i.double(),r>>=oe;return n}precomputeWindow(t,r){const{windows:n,windowSize:i}=Ze(r,this.bits),s=[];let o=t,c=o;for(let a=0;a<n;a++){c=o,s.push(c);for(let d=1;d<i;d++)c=c.add(o),s.push(c);o=c.double()}return s}wNAF(t,r,n){if(!this.Fn.isValid(n))throw new Error("invalid scalar");let i=this.ZERO,s=this.BASE;const o=Ze(t,this.bits);for(let c=0;c<o.windows;c++){const{nextN:a,offset:d,isZero:f,isNeg:h,isNegF:g,offsetF:y}=Nt(n,c,o);n=a,f?s=s.add(Le(g,r[y])):i=i.add(Le(h,r[d]))}return Lt(n),{p:i,f:s}}wNAFUnsafe(t,r,n,i=this.ZERO){const s=Ze(t,this.bits);for(let o=0;o<s.windows&&n!==le;o++){const{nextN:c,offset:a,isZero:d,isNeg:f}=Nt(n,o,s);if(n=c,!d){const h=r[a];i=i.add(f?h.negate():h)}}return Lt(n),i}getPrecomputes(t,r,n){let i=Ve.get(r);return i||(i=this.precomputeWindow(r,t),t!==1&&(typeof n=="function"&&(i=n(i)),Ve.set(r,i))),i}cached(t,r,n){const i=Ke(t);return this.wNAF(i,this.getPrecomputes(i,t,n),r)}unsafe(t,r,n,i){const s=Ke(t);return s===1?this._unsafeLadder(t,r,i):this.wNAFUnsafe(s,this.getPrecomputes(s,t,n),r,i)}createCache(t,r){mn(r,this.bits),bn.set(t,r),Ve.delete(t)}hasCache(t){return Ke(t)!==1}}function Vr(e,t,r,n){let i=t,s=e.ZERO,o=e.ZERO;for(;r>le||n>le;)r&oe&&(s=s.add(i)),n&oe&&(o=o.add(i)),i=i.double(),r>>=oe,n>>=oe;return{p1:s,p2:o}}function Pt(e,t,r){if(t){if(t.ORDER!==e)throw new Error("Field.ORDER must match order: Fp == p, Fn == n");return Hr(t),t}else return Ce(e,{isLE:r})}function Kr(e,t,r={},n){if(n===void 0&&(n=e==="edwards"),!t||typeof t!="object")throw new Error(`expected valid ${e} CURVE object`);for(const a of["p","n","h"]){const d=t[a];if(!(typeof d=="bigint"&&d>le))throw new Error(`CURVE.${a} must be positive bigint`)}const i=Pt(t.p,r.Fp,n),s=Pt(t.n,r.Fn,n),c=["Gx","Gy","a","b"];for(const a of c)if(!i.isValid(t[a]))throw new Error(`CURVE.${a} must be valid field element of CURVE.Fp`);return t=Object.freeze(Object.assign({},t)),{CURVE:t,Fp:i,Fn:s}}function Yr(e,t){return function(n){const i=e(n);return{secretKey:i,publicKey:t(i)}}}/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */const _t=(e,t)=>(e+(e>=0?t:-t)/Gr)/t;function zr(e,t,r){const[[n,i],[s,o]]=t,c=_t(o*e,r),a=_t(-i*e,r);let d=e-c*n-a*s,f=-c*i-a*o;const h=d<he,g=f<he;h&&(d=-d),g&&(f=-f);const y=on(Math.ceil(qr(r)/2))+Te;if(d<he||d>=y||f<he||f>=y)throw new Error("splitScalar (endomorphism): failed, k="+e);return{k1neg:h,k1:d,k2neg:g,k2:f}}const he=BigInt(0),Te=BigInt(1),Gr=BigInt(2),$e=BigInt(3),Xr=BigInt(4);function Jr(e,t={}){const r=Kr("weierstrass",e,t),{Fp:n,Fn:i}=r;let s=r.CURVE;const{h:o,n:c}=s;an(t,{},{allowInfinityPoint:"boolean",clearCofactor:"function",isTorsionFree:"function",fromBytes:"function",toBytes:"function",endo:"object"});const{endo:a}=t;if(a&&(!n.is0(s.a)||typeof a.beta!="bigint"||!Array.isArray(a.basises)))throw new Error('invalid endo: expected "beta": bigint and "basises": array');const d=ei(n,i);function f(){if(!n.isOdd)throw new Error("compression is not supported: Field does not have .isOdd()")}function h(I,p,m){const{x:v,y:x}=p.toAffine(),A=n.toBytes(v);if(At(m,"isCompressed"),m){f();const R=!n.isOdd(x);return Oe(Qr(R),A)}else return Oe(Uint8Array.of(4),A,n.toBytes(x))}function g(I){D(I,void 0,"Point");const{publicKey:p,publicKeyUncompressed:m}=d,v=I.length,x=I[0],A=I.subarray(1);if(v===p&&(x===2||x===3)){const R=n.fromBytes(A);if(!n.isValid(R))throw new Error("bad point: is not on curve, wrong x");const k=E(R);let w;try{w=n.sqrt(k)}catch(M){const P=M instanceof Error?": "+M.message:"";throw new Error("bad point: is not on curve, sqrt error"+P)}f();const S=n.isOdd(w);return(x&1)===1!==S&&(w=n.neg(w)),{x:R,y:w}}else if(v===m&&x===4){const R=n.BYTES,k=n.fromBytes(A.subarray(0,R)),w=n.fromBytes(A.subarray(R,R*2));if(!q(k,w))throw new Error("bad point: is not on curve");return{x:k,y:w}}else throw new Error(`bad point: got length ${v}, expected compressed=${p} or uncompressed=${m}`)}const y=t.toBytes||h,b=t.fromBytes||g;function E(I){const p=n.sqr(I),m=n.mul(p,I);return n.add(n.add(m,n.mul(I,s.a)),s.b)}function q(I,p){const m=n.sqr(p),v=E(I);return n.eql(m,v)}if(!q(s.Gx,s.Gy))throw new Error("bad curve params: generator point");const L=n.mul(n.pow(s.a,$e),Xr),K=n.mul(n.sqr(s.b),BigInt(27));if(n.is0(n.add(L,K)))throw new Error("bad curve params: a or b");function Q(I,p,m=!1){if(!n.isValid(p)||m&&n.is0(p))throw new Error(`bad point coordinate ${I}`);return p}function we(I){if(!(I instanceof B))throw new Error("Weierstrass Point expected")}function ve(I){if(!a||!a.basises)throw new Error("no endo");return zr(I,a.basises,i.ORDER)}const Ee=Tt((I,p)=>{const{X:m,Y:v,Z:x}=I;if(n.eql(x,n.ONE))return{x:m,y:v};const A=I.is0();p==null&&(p=A?n.ONE:n.inv(x));const R=n.mul(m,p),k=n.mul(v,p),w=n.mul(x,p);if(A)return{x:n.ZERO,y:n.ZERO};if(!n.eql(w,n.ONE))throw new Error("invZ was invalid");return{x:R,y:k}}),In=Tt(I=>{if(I.is0()){if(t.allowInfinityPoint&&!n.is0(I.Y))return;throw new Error("bad point: ZERO")}const{x:p,y:m}=I.toAffine();if(!n.isValid(p)||!n.isValid(m))throw new Error("bad point: x or y not field elements");if(!q(p,m))throw new Error("bad point: equation left != right");if(!I.isTorsionFree())throw new Error("bad point: not in prime-order subgroup");return!0});function mt(I,p,m,v,x){return m=new B(n.mul(m.X,I),m.Y,m.Z),p=Le(v,p),m=Le(x,m),p.add(m)}class B{static BASE=new B(s.Gx,s.Gy,n.ONE);static ZERO=new B(n.ZERO,n.ONE,n.ZERO);static Fp=n;static Fn=i;X;Y;Z;constructor(p,m,v){this.X=Q("x",p),this.Y=Q("y",m,!0),this.Z=Q("z",v),Object.freeze(this)}static CURVE(){return s}static fromAffine(p){const{x:m,y:v}=p||{};if(!p||!n.isValid(m)||!n.isValid(v))throw new Error("invalid affine point");if(p instanceof B)throw new Error("projective point not allowed");return n.is0(m)&&n.is0(v)?B.ZERO:new B(m,v,n.ONE)}static fromBytes(p){const m=B.fromAffine(b(D(p,void 0,"point")));return m.assertValidity(),m}static fromHex(p){return B.fromBytes(X(p))}get x(){return this.toAffine().x}get y(){return this.toAffine().y}precompute(p=8,m=!0){return ue.createCache(this,p),m||this.multiply($e),this}assertValidity(){In(this)}hasEvenY(){const{y:p}=this.toAffine();if(!n.isOdd)throw new Error("Field doesn't support isOdd");return!n.isOdd(p)}equals(p){we(p);const{X:m,Y:v,Z:x}=this,{X:A,Y:R,Z:k}=p,w=n.eql(n.mul(m,k),n.mul(A,x)),S=n.eql(n.mul(v,k),n.mul(R,x));return w&&S}negate(){return new B(this.X,n.neg(this.Y),this.Z)}double(){const{a:p,b:m}=s,v=n.mul(m,$e),{X:x,Y:A,Z:R}=this;let k=n.ZERO,w=n.ZERO,S=n.ZERO,$=n.mul(x,x),M=n.mul(A,A),P=n.mul(R,R),T=n.mul(x,A);return T=n.add(T,T),S=n.mul(x,R),S=n.add(S,S),k=n.mul(p,S),w=n.mul(v,P),w=n.add(k,w),k=n.sub(M,w),w=n.add(M,w),w=n.mul(k,w),k=n.mul(T,k),S=n.mul(v,S),P=n.mul(p,P),T=n.sub($,P),T=n.mul(p,T),T=n.add(T,S),S=n.add($,$),$=n.add(S,$),$=n.add($,P),$=n.mul($,T),w=n.add(w,$),P=n.mul(A,R),P=n.add(P,P),$=n.mul(P,T),k=n.sub(k,$),S=n.mul(P,M),S=n.add(S,S),S=n.add(S,S),new B(k,w,S)}add(p){we(p);const{X:m,Y:v,Z:x}=this,{X:A,Y:R,Z:k}=p;let w=n.ZERO,S=n.ZERO,$=n.ZERO;const M=s.a,P=n.mul(s.b,$e);let T=n.mul(m,A),W=n.mul(v,R),Z=n.mul(x,k),ae=n.add(m,v),U=n.add(A,R);ae=n.mul(ae,U),U=n.add(T,W),ae=n.sub(ae,U),U=n.add(m,x);let Y=n.add(A,k);return U=n.mul(U,Y),Y=n.add(T,Z),U=n.sub(U,Y),Y=n.add(v,x),w=n.add(R,k),Y=n.mul(Y,w),w=n.add(W,Z),Y=n.sub(Y,w),$=n.mul(M,U),w=n.mul(P,Z),$=n.add(w,$),w=n.sub(W,$),$=n.add(W,$),S=n.mul(w,$),W=n.add(T,T),W=n.add(W,T),Z=n.mul(M,Z),U=n.mul(P,U),W=n.add(W,Z),Z=n.sub(T,Z),Z=n.mul(M,Z),U=n.add(U,Z),T=n.mul(W,U),S=n.add(S,T),T=n.mul(Y,U),w=n.mul(ae,w),w=n.sub(w,T),T=n.mul(ae,W),$=n.mul(Y,$),$=n.add($,T),new B(w,S,$)}subtract(p){return this.add(p.negate())}is0(){return this.equals(B.ZERO)}multiply(p){const{endo:m}=t;if(!i.isValidNot0(p))throw new Error("invalid scalar: out of range");let v,x;const A=R=>ue.cached(this,R,k=>qt(B,k));if(m){const{k1neg:R,k1:k,k2neg:w,k2:S}=ve(p),{p:$,f:M}=A(k),{p:P,f:T}=A(S);x=M.add(T),v=mt(m.beta,$,P,R,w)}else{const{p:R,f:k}=A(p);v=R,x=k}return qt(B,[v,x])[0]}multiplyUnsafe(p){const{endo:m}=t,v=this;if(!i.isValid(p))throw new Error("invalid scalar: out of range");if(p===he||v.is0())return B.ZERO;if(p===Te)return v;if(ue.hasCache(this))return this.multiply(p);if(m){const{k1neg:x,k1:A,k2neg:R,k2:k}=ve(p),{p1:w,p2:S}=Vr(B,v,A,k);return mt(m.beta,w,S,x,R)}else return ue.unsafe(v,p)}toAffine(p){return Ee(this,p)}isTorsionFree(){const{isTorsionFree:p}=t;return o===Te?!0:p?p(B,this):ue.unsafe(this,c).is0()}clearCofactor(){const{clearCofactor:p}=t;return o===Te?this:p?p(B,this):this.multiplyUnsafe(o)}isSmallOrder(){return this.multiplyUnsafe(o).is0()}toBytes(p=!0){return At(p,"isCompressed"),this.assertValidity(),y(B,this,p)}toHex(p=!0){return _(this.toBytes(p))}toString(){return`<Point ${this.is0()?"ZERO":this.toHex()}>`}}const bt=i.BITS,ue=new Zr(B,t.endo?Math.ceil(bt/2):bt);return B.BASE.precompute(8),B}function Qr(e){return Uint8Array.of(e?2:3)}function ei(e,t){return{secretKey:t.BYTES,publicKey:1+e.BYTES,publicKeyUncompressed:1+2*e.BYTES,publicKeyHasPrefix:!0,signature:2*t.BYTES}}/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */const Ue={p:BigInt("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"),n:BigInt("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"),h:BigInt(1),a:BigInt(0),b:BigInt(7),Gx:BigInt("0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"),Gy:BigInt("0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8")},ti={beta:BigInt("0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee"),basises:[[BigInt("0x3086d221a7d46bcde86c90e49284eb15"),-BigInt("0xe4437ed6010e88286f547fa90abfe4c3")],[BigInt("0x114ca50f7a8e2f3f657c1108d9d44cfd8"),BigInt("0x3086d221a7d46bcde86c90e49284eb15")]]},ni=BigInt(0),rt=BigInt(2);function ri(e){const t=Ue.p,r=BigInt(3),n=BigInt(6),i=BigInt(11),s=BigInt(22),o=BigInt(23),c=BigInt(44),a=BigInt(88),d=e*e*e%t,f=d*d*e%t,h=F(f,r,t)*f%t,g=F(h,r,t)*f%t,y=F(g,rt,t)*d%t,b=F(y,i,t)*y%t,E=F(b,s,t)*b%t,q=F(E,c,t)*E%t,L=F(q,a,t)*q%t,K=F(L,c,t)*E%t,Q=F(K,r,t)*f%t,we=F(Q,o,t)*b%t,ve=F(we,n,t)*d%t,Ee=F(ve,rt,t);if(!Pe.eql(Pe.sqr(Ee),e))throw new Error("Cannot find square root");return Ee}const Pe=Ce(Ue.p,{sqrt:ri}),de=Jr(Ue,{Fp:Pe,endo:ti}),Ct={};function _e(e,...t){let r=Ct[e];if(r===void 0){const n=Ne(Br(e));r=Oe(n,n),Ct[e]=r}return Ne(Oe(r,...t))}const gt=e=>e.toBytes(!0).slice(1),yt=e=>e%rt===ni;function it(e){const{Fn:t,BASE:r}=de,n=t.fromBytes(e),i=r.multiply(n);return{scalar:yt(i.y)?n:t.neg(n),bytes:gt(i)}}function wn(e){const t=Pe;if(!t.isValidNot0(e))throw new Error("invalid x: Fail if x ≥ p");const r=t.create(e*e),n=t.create(r*e+BigInt(7));let i=t.sqrt(n);yt(i)||(i=t.neg(i));const s=de.fromAffine({x:e,y:i});return s.assertValidity(),s}const ye=ft;function vn(...e){return de.Fn.create(ye(_e("BIP0340/challenge",...e)))}function Ut(e){return it(e).bytes}function ii(e,t,r=zt(32)){const{Fn:n}=de,i=D(e,void 0,"message"),{bytes:s,scalar:o}=it(t),c=D(r,32,"auxRand"),a=n.toBytes(o^ye(_e("BIP0340/aux",c))),d=_e("BIP0340/nonce",a,s,i),{bytes:f,scalar:h}=it(d),g=vn(f,s,i),y=new Uint8Array(64);if(y.set(f,0),y.set(n.toBytes(n.create(h+g*o)),32),!En(y,i,s))throw new Error("sign: Invalid signature produced");return y}function En(e,t,r){const{Fp:n,Fn:i,BASE:s}=de,o=D(e,64,"signature"),c=D(t,void 0,"message"),a=D(r,32,"publicKey");try{const d=wn(ye(a)),f=ye(o.subarray(0,32));if(!n.isValidNot0(f))return!1;const h=ye(o.subarray(32,64));if(!i.isValidNot0(h))return!1;const g=vn(i.toBytes(f),gt(d),c),y=s.multiplyUnsafe(h).add(d.multiplyUnsafe(i.neg(g))),{x:b,y:E}=y.toAffine();return!(y.is0()||!yt(E)||b!==f)}catch{return!1}}const G=(()=>{const r=(n=zt(48))=>Wr(n,Ue.n);return{keygen:Yr(r,Ut),getPublicKey:Ut,sign:ii,verify:En,Point:de,utils:{randomSecretKey:r,taggedHash:_e,lift_x:wn,pointToBytes:gt},lengths:{secretKey:32,publicKey:32,publicKeyHasPrefix:!1,signature:64,seed:48}}})();var ie=Symbol("verified"),si=e=>e instanceof Object;function oi(e){if(!si(e)||typeof e.kind!="number"||typeof e.content!="string"||typeof e.created_at!="number"||typeof e.pubkey!="string"||!e.pubkey.match(/^[a-f0-9]{64}$/)||!Array.isArray(e.tags))return!1;for(let t=0;t<e.tags.length;t++){let r=e.tags[t];if(!Array.isArray(r))return!1;for(let n=0;n<r.length;n++)if(typeof r[n]!="string")return!1}return!0}new TextDecoder("utf-8");var ai=new TextEncoder;function pe(e){try{e.indexOf("://")===-1&&(e="wss://"+e);let t=new URL(e);return t.protocol==="http:"?t.protocol="ws:":t.protocol==="https:"&&(t.protocol="wss:"),t.pathname=t.pathname.replace(/\/+/g,"/"),t.pathname.endsWith("/")&&(t.pathname=t.pathname.slice(0,-1)),(t.port==="80"&&t.protocol==="ws:"||t.port==="443"&&t.protocol==="wss:")&&(t.port=""),t.searchParams.sort(),t.hash="",t.toString()}catch{throw new Error(`Invalid URL: ${e}`)}}var ci=class{generateSecretKey(){return G.utils.randomSecretKey()}getPublicKey(t){return _(G.getPublicKey(t))}finalizeEvent(t,r){const n=t;return n.pubkey=_(G.getPublicKey(r)),n.id=Ye(n),n.sig=_(G.sign(X(Ye(n)),r)),n[ie]=!0,n}verifyEvent(t){if(typeof t[ie]=="boolean")return t[ie];try{const r=Ye(t);if(r!==t.id)return t[ie]=!1,!1;const n=G.verify(X(t.sig),X(r),X(t.pubkey));return t[ie]=n,n}catch{return t[ie]=!1,!1}}};function li(e){if(!oi(e))throw new Error("can't serialize event with wrong or missing properties");return JSON.stringify([0,e.pubkey,e.created_at,e.kind,e.tags,e.content])}function Ye(e){let t=Ne(ai.encode(li(e)));return _(t)}var He=new ci;He.generateSecretKey;He.getPublicKey;He.finalizeEvent;var di=He.verifyEvent,ui=22242;function fi(e,t){if(e.ids&&e.ids.indexOf(t.id)===-1||e.kinds&&e.kinds.indexOf(t.kind)===-1||e.authors&&e.authors.indexOf(t.pubkey)===-1)return!1;for(let r in e)if(r[0]==="#"){let n=r.slice(1),i=e[`#${n}`];if(i&&!t.tags.find(([s,o])=>s===r.slice(1)&&i.indexOf(o)!==-1))return!1}return!(e.since&&t.created_at<e.since||e.until&&t.created_at>e.until)}function hi(e,t){for(let r=0;r<e.length;r++)if(fi(e[r],t))return!0;return!1}function pi(e,t){let r=t.length+3,n=e.indexOf(`"${t}":`)+r,i=e.slice(n).indexOf('"')+n+1;return e.slice(i,i+64)}function gi(e){let t=e.slice(0,22).indexOf('"EVENT"');if(t===-1)return null;let r=e.slice(t+7+1).indexOf('"');if(r===-1)return null;let n=t+7+1+r,i=e.slice(n+1,80).indexOf('"');if(i===-1)return null;let s=n+1+i;return e.slice(n+1,s)}function yi(e,t){return{kind:ui,created_at:Math.floor(Date.now()/1e3),tags:[["relay",e],["challenge",t]],content:""}}var xn=class extends Error{constructor(e,t){super(`Tried to send message '${e} on a closed connection to ${t}.`),this.name="SendingOnClosedConnection"}},kn=class{url;_connected=!1;onclose=null;onnotice=e=>console.debug(`NOTICE from ${this.url}: ${e}`);onauth;baseEoseTimeout=4400;publishTimeout=4400;pingFrequency=29e3;pingTimeout=2e4;resubscribeBackoff=[1e4,1e4,1e4,2e4,2e4,3e4,6e4];openSubs=new Map;enablePing;enableReconnect;idleSince=Date.now();ongoingOperations=0;reconnectTimeoutHandle;pingIntervalHandle;reconnectAttempts=0;skipReconnection=!1;connectionPromise;openCountRequests=new Map;openEventPublishes=new Map;ws;challenge;authPromise;serial=0;verifyEvent;_WebSocket;constructor(e,t){this.url=pe(e),this.verifyEvent=t.verifyEvent,this._WebSocket=t.websocketImplementation||WebSocket,this.enablePing=t.enablePing,this.enableReconnect=t.enableReconnect||!1}static async connect(e,t){const r=new kn(e,t);return await r.connect(t),r}closeAllSubscriptions(e){for(let[t,r]of this.openSubs)r.close(e);this.openSubs.clear();for(let[t,r]of this.openEventPublishes)r.reject(new Error(e));this.openEventPublishes.clear();for(let[t,r]of this.openCountRequests)r.reject(new Error(e));this.openCountRequests.clear()}get connected(){return this._connected}async reconnect(){const e=this.resubscribeBackoff[Math.min(this.reconnectAttempts,this.resubscribeBackoff.length-1)];this.reconnectAttempts++,this.reconnectTimeoutHandle=setTimeout(async()=>{try{await this.connect()}catch{}},e)}handleHardClose(e){this.pingIntervalHandle&&(clearInterval(this.pingIntervalHandle),this.pingIntervalHandle=void 0),this._connected=!1,this.connectionPromise=void 0,this.idleSince=void 0,this.enableReconnect&&!this.skipReconnection?this.reconnect():(this.onclose?.(),this.closeAllSubscriptions(e))}async connect(e){let t;return this.connectionPromise?this.connectionPromise:(this.challenge=void 0,this.authPromise=void 0,this.skipReconnection=!1,this.connectionPromise=new Promise((r,n)=>{e?.timeout&&(t=setTimeout(()=>{n("connection timed out"),this.connectionPromise=void 0,this.skipReconnection=!0,this.onclose?.(),this.handleHardClose("relay connection timed out")},e.timeout)),e?.abort&&(e.abort.onabort=n);try{this.ws=new this._WebSocket(this.url)}catch(i){clearTimeout(t),n(i);return}this.ws.onopen=()=>{this.reconnectTimeoutHandle&&(clearTimeout(this.reconnectTimeoutHandle),this.reconnectTimeoutHandle=void 0),clearTimeout(t),this._connected=!0;const i=this.reconnectAttempts>0;this.reconnectAttempts=0;for(const s of this.openSubs.values()){if(s.eosed=!1,i)for(let o=0;o<s.filters.length;o++)s.lastEmitted&&(s.filters[o].since=s.lastEmitted+1);s.fire()}this.enablePing&&(this.pingIntervalHandle=setInterval(()=>this.pingpong(),this.pingFrequency)),r()},this.ws.onerror=()=>{clearTimeout(t),n("connection failed"),this.connectionPromise=void 0,this.skipReconnection=!0,this.onclose?.(),this.handleHardClose("relay connection failed")},this.ws.onclose=i=>{clearTimeout(t),n(i.message||"websocket closed"),this.handleHardClose("relay connection closed")},this.ws.onmessage=this._onmessage.bind(this)}),this.connectionPromise)}waitForPingPong(){return new Promise(e=>{this.ws.once("pong",()=>e(!0)),this.ws.ping()})}waitForDummyReq(){return new Promise((e,t)=>{if(!this.connectionPromise)return t(new Error(`no connection to ${this.url}, can't ping`));try{const r=this.subscribe([{ids:["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"],limit:0}],{label:"<forced-ping>",oneose:()=>{e(!0),r.close()},onclose(){e(!0)},eoseTimeout:this.pingTimeout+1e3})}catch(r){t(r)}})}async pingpong(){this.ws?.readyState===1&&(await Promise.any([this.ws&&this.ws.ping&&this.ws.once?this.waitForPingPong():this.waitForDummyReq(),new Promise(t=>setTimeout(()=>t(!1),this.pingTimeout))])||this.ws?.readyState===this._WebSocket.OPEN&&this.ws?.close())}async send(e){if(!this.connectionPromise)throw new xn(e,this.url);this.connectionPromise.then(()=>{this.ws?.send(e)})}async auth(e){const t=this.challenge;if(!t)throw new Error("can't perform auth, no challenge was received");return this.authPromise?this.authPromise:(this.authPromise=new Promise(async(r,n)=>{try{let i=await e(yi(this.url,t)),s=setTimeout(()=>{let o=this.openEventPublishes.get(i.id);o&&(o.reject(new Error("auth timed out")),this.openEventPublishes.delete(i.id))},this.publishTimeout);this.openEventPublishes.set(i.id,{resolve:r,reject:n,timeout:s}),this.send('["AUTH",'+JSON.stringify(i)+"]")}catch(i){console.warn("subscribe auth function failed:",i)}}),this.authPromise)}async publish(e){this.idleSince=void 0,this.ongoingOperations++;const t=new Promise((r,n)=>{const i=setTimeout(()=>{const s=this.openEventPublishes.get(e.id);s&&(s.reject(new Error("publish timed out")),this.openEventPublishes.delete(e.id))},this.publishTimeout);this.openEventPublishes.set(e.id,{resolve:r,reject:n,timeout:i})});return this.send('["EVENT",'+JSON.stringify(e)+"]"),this.ongoingOperations--,this.ongoingOperations===0&&(this.idleSince=Date.now()),t}async count(e,t){this.serial++;const r=t?.id||"count:"+this.serial,n=new Promise((i,s)=>{this.openCountRequests.set(r,{resolve:i,reject:s})});return this.send('["COUNT","'+r+'",'+JSON.stringify(e).substring(1)),n}subscribe(e,t){t.label!=="<forced-ping>"&&(this.idleSince=void 0,this.ongoingOperations++);const r=this.prepareSubscription(e,t);return r.fire(),t.abort&&(t.abort.onabort=()=>r.close(String(t.abort.reason||"<aborted>"))),r}prepareSubscription(e,t){this.serial++;const r=t.id||(t.label?t.label+":":"sub:")+this.serial,n=new mi(this,r,e,t);return this.openSubs.set(r,n),n}close(){this.skipReconnection=!0,this.reconnectTimeoutHandle&&(clearTimeout(this.reconnectTimeoutHandle),this.reconnectTimeoutHandle=void 0),this.pingIntervalHandle&&(clearInterval(this.pingIntervalHandle),this.pingIntervalHandle=void 0),this.closeAllSubscriptions("relay connection closed by us"),this._connected=!1,this.idleSince=void 0,this.onclose?.(),this.ws?.readyState===this._WebSocket.OPEN&&this.ws?.close()}_onmessage(e){const t=e.data;if(!t)return;const r=gi(t);if(r){const n=this.openSubs.get(r);if(!n)return;const i=pi(t,"id"),s=n.alreadyHaveEvent?.(i);if(n.receivedEvent?.(this,i),s)return}try{let n=JSON.parse(t);switch(n[0]){case"EVENT":{const i=this.openSubs.get(n[1]),s=n[2];this.verifyEvent(s)&&hi(i.filters,s)?i.onevent(s):i.oninvalidevent?.(s),(!i.lastEmitted||i.lastEmitted<s.created_at)&&(i.lastEmitted=s.created_at);return}case"COUNT":{const i=n[1],s=n[2],o=this.openCountRequests.get(i);o&&(o.resolve(s.count),this.openCountRequests.delete(i));return}case"EOSE":{const i=this.openSubs.get(n[1]);if(!i)return;i.receivedEose();return}case"OK":{const i=n[1],s=n[2],o=n[3],c=this.openEventPublishes.get(i);c&&(clearTimeout(c.timeout),s?c.resolve(o):c.reject(new Error(o)),this.openEventPublishes.delete(i));return}case"CLOSED":{const i=n[1],s=this.openSubs.get(i);if(!s)return;s.closed=!0,s.close(n[2]);return}case"NOTICE":{this.onnotice(n[1]);return}case"AUTH":{this.challenge=n[1],this.onauth&&this.auth(this.onauth);return}default:{this.openSubs.get(n[1])?.oncustom?.(n);return}}}catch(n){try{const[i,s,o]=JSON.parse(t);console.warn(`[nostr] relay ${this.url} error processing message:`,n,o)}catch{console.warn(`[nostr] relay ${this.url} error processing message:`,n)}return}}},mi=class{relay;id;lastEmitted;closed=!1;eosed=!1;filters;alreadyHaveEvent;receivedEvent;onevent;oninvalidevent;oneose;onclose;oncustom;eoseTimeout;eoseTimeoutHandle;constructor(e,t,r,n){if(r.length===0)throw new Error("subscription can't be created with zero filters");this.relay=e,this.filters=r,this.id=t,this.alreadyHaveEvent=n.alreadyHaveEvent,this.receivedEvent=n.receivedEvent,this.eoseTimeout=n.eoseTimeout||e.baseEoseTimeout,this.oneose=n.oneose,this.onclose=n.onclose,this.oninvalidevent=n.oninvalidevent,this.onevent=n.onevent||(i=>{console.warn(`onevent() callback not defined for subscription '${this.id}' in relay ${this.relay.url}. event received:`,i)})}fire(){this.relay.send('["REQ","'+this.id+'",'+JSON.stringify(this.filters).substring(1)),this.eoseTimeoutHandle=setTimeout(this.receivedEose.bind(this),this.eoseTimeout)}receivedEose(){this.eosed||(clearTimeout(this.eoseTimeoutHandle),this.eosed=!0,this.oneose?.())}close(e="closed by caller"){if(!this.closed&&this.relay.connected){try{this.relay.send('["CLOSE",'+JSON.stringify(this.id)+"]")}catch(t){if(!(t instanceof xn))throw t}this.closed=!0}this.relay.openSubs.delete(this.id),this.relay.ongoingOperations--,this.relay.ongoingOperations===0&&(this.relay.idleSince=Date.now()),this.onclose?.(e)}},bi=e=>(e[ie]=!0,!0),wi=class{relays=new Map;seenOn=new Map;trackRelays=!1;verifyEvent;enablePing;enableReconnect;automaticallyAuth;trustedRelayURLs=new Set;onRelayConnectionFailure;onRelayConnectionSuccess;allowConnectingToRelay;maxWaitForConnection;_WebSocket;constructor(e){this.verifyEvent=e.verifyEvent,this._WebSocket=e.websocketImplementation,this.enablePing=e.enablePing,this.enableReconnect=e.enableReconnect||!1,this.automaticallyAuth=e.automaticallyAuth,this.onRelayConnectionFailure=e.onRelayConnectionFailure,this.onRelayConnectionSuccess=e.onRelayConnectionSuccess,this.allowConnectingToRelay=e.allowConnectingToRelay,this.maxWaitForConnection=e.maxWaitForConnection||3e3}async ensureRelay(e,t){e=pe(e);let r=this.relays.get(e);if(r||(r=new kn(e,{verifyEvent:this.trustedRelayURLs.has(e)?bi:this.verifyEvent,websocketImplementation:this._WebSocket,enablePing:this.enablePing,enableReconnect:this.enableReconnect}),r.onclose=()=>{this.relays.delete(e)},this.relays.set(e,r)),this.automaticallyAuth){const n=this.automaticallyAuth(e);n&&(r.onauth=n)}try{await r.connect({timeout:t?.connectionTimeout,abort:t?.abort})}catch(n){throw this.relays.delete(e),n}return r}close(e){e.map(pe).forEach(t=>{this.relays.get(t)?.close(),this.relays.delete(t)})}subscribe(e,t,r){const n=[],i=[];for(let s=0;s<e.length;s++){const o=pe(e[s]);n.find(c=>c.url===o)||i.indexOf(o)===-1&&(i.push(o),n.push({url:o,filter:t}))}return this.subscribeMap(n,r)}subscribeMany(e,t,r){return this.subscribe(e,t,r)}subscribeMap(e,t){const r=new Map;for(const g of e){const{url:y,filter:b}=g;r.has(y)||r.set(y,[]),r.get(y).push(b)}const n=Array.from(r.entries()).map(([g,y])=>({url:g,filters:y}));this.trackRelays&&(t.receivedEvent=(g,y)=>{let b=this.seenOn.get(y);b||(b=new Set,this.seenOn.set(y,b)),b.add(g)});const i=new Set,s=[],o=[];let c=g=>{o[g]||(o[g]=!0,o.filter(y=>y).length===n.length&&(t.oneose?.(),c=()=>{}))};const a=[];let d=(g,y)=>{a[g]||(c(g),a[g]=y,a.filter(b=>b).length===n.length&&(t.onclose?.(a),d=()=>{}))};const f=g=>{if(t.alreadyHaveEvent?.(g))return!0;const y=i.has(g);return i.add(g),y},h=Promise.all(n.map(async({url:g,filters:y},b)=>{if(this.allowConnectingToRelay?.(g,["read",y])===!1){d(b,"connection skipped by allowConnectingToRelay");return}let E;try{E=await this.ensureRelay(g,{connectionTimeout:this.maxWaitForConnection<(t.maxWait||0)?Math.max(t.maxWait*.8,t.maxWait-1e3):this.maxWaitForConnection,abort:t.abort})}catch(L){this.onRelayConnectionFailure?.(g),d(b,L?.message||String(L));return}this.onRelayConnectionSuccess?.(g);let q=E.subscribe(y,{...t,oneose:()=>c(b),onclose:L=>{L.startsWith("auth-required: ")&&t.onauth?E.auth(t.onauth).then(()=>{E.subscribe(y,{...t,oneose:()=>c(b),onclose:K=>{d(b,K)},alreadyHaveEvent:f,eoseTimeout:t.maxWait,abort:t.abort})}).catch(K=>{d(b,`auth was required and attempted, but failed with: ${K}`)}):d(b,L)},alreadyHaveEvent:f,eoseTimeout:t.maxWait,abort:t.abort});s.push(q)}));return{async close(g){await h,s.forEach(y=>{y.close(g)})}}}subscribeEose(e,t,r){let n;return n=this.subscribe(e,t,{...r,oneose(){const i="closed automatically on eose";n?n.close(i):r.onclose?.(e.map(s=>i))}}),n}subscribeManyEose(e,t,r){return this.subscribeEose(e,t,r)}async querySync(e,t,r){return new Promise(async n=>{const i=[];this.subscribeEose(e,t,{...r,onevent(s){i.push(s)},onclose(s){n(i)}})})}async get(e,t,r){t.limit=1;const n=await this.querySync(e,t,r);return n.sort((i,s)=>s.created_at-i.created_at),n[0]||null}publish(e,t,r){return e.map(pe).map(async(n,i,s)=>{if(s.indexOf(n)!==i)return Promise.reject("duplicate url");if(this.allowConnectingToRelay?.(n,["write",t])===!1)return Promise.reject("connection skipped by allowConnectingToRelay");let o;try{o=await this.ensureRelay(n,{connectionTimeout:this.maxWaitForConnection<(r?.maxWait||0)?Math.max(r.maxWait*.8,r.maxWait-1e3):this.maxWaitForConnection,abort:r?.abort})}catch(c){return this.onRelayConnectionFailure?.(n),"connection failure: "+String(c)}return o.publish(t).catch(async c=>{if(c instanceof Error&&c.message.startsWith("auth-required: ")&&r?.onauth)return await o.auth(r.onauth),o.publish(t);throw c}).then(c=>{if(this.trackRelays){let a=this.seenOn.get(t.id);a||(a=new Set,this.seenOn.set(t.id,a)),a.add(o)}return c})})}listConnectionStatus(){const e=new Map;return this.relays.forEach((t,r)=>e.set(r,t.connected)),e}destroy(){this.relays.forEach(e=>e.close()),this.relays=new Map}pruneIdleRelays(e=1e4){const t=[];for(const[r,n]of this.relays)n.idleSince&&Date.now()-n.idleSince>=e&&(this.relays.delete(r),t.push(r),n.close());return t}},Sn;try{Sn=WebSocket}catch{}var vi=class extends wi{constructor(e){super({verifyEvent:di,websocketImplementation:Sn,maxWaitForConnection:3e3,...e})}},ce=Symbol("verified"),Ei=e=>e instanceof Object;function xi(e){if(!Ei(e)||typeof e.kind!="number"||typeof e.content!="string"||typeof e.created_at!="number"||typeof e.pubkey!="string"||!e.pubkey.match(/^[a-f0-9]{64}$/)||!Array.isArray(e.tags))return!1;for(let t=0;t<e.tags.length;t++){let r=e.tags[t];if(!Array.isArray(r))return!1;for(let n=0;n<r.length;n++)if(typeof r[n]!="string")return!1}return!0}new TextDecoder("utf-8");var ki=new TextEncoder,Si=class{generateSecretKey(){return G.utils.randomSecretKey()}getPublicKey(e){return _(G.getPublicKey(e))}finalizeEvent(e,t){const r=e;return r.pubkey=_(G.getPublicKey(t)),r.id=ze(r),r.sig=_(G.sign(X(ze(r)),t)),r[ce]=!0,r}verifyEvent(e){if(typeof e[ce]=="boolean")return e[ce];try{const t=ze(e);if(t!==e.id)return e[ce]=!1,!1;const r=G.verify(X(e.sig),X(t),X(e.pubkey));return e[ce]=r,r}catch{return e[ce]=!1,!1}}};function Ri(e){if(!xi(e))throw new Error("can't serialize event with wrong or missing properties");return JSON.stringify([0,e.pubkey,e.created_at,e.kind,e.tags,e.content])}function ze(e){let t=Ne(ki.encode(Ri(e)));return _(t)}var je=new Si;je.generateSecretKey;je.getPublicKey;je.finalizeEvent;var $i=je.verifyEvent;const Ii=8e3;function Ai(e){return typeof e=="number"&&ct.includes(e)}function Ti(e){try{const t=new URL(e);return t.protocol==="http:"||t.protocol==="https:"}catch{return!1}}function Bi(e){const t=[];for(const r of e??[])try{const n=new URL(r);if(n.protocol!=="ws:"&&n.protocol!=="wss:")continue;t.push(n.href)}catch{}return[...new Set(t)]}function Oi(e){const t=vr(e.trim());if(t.type!=="nevent"&&t.type!=="naddr")throw new Error("Enter a NIP-19 nevent or naddr for a NIP-5D napplet manifest event");const r=Bi(t.data.relays);if(r.length===0)throw new Error("The pointer does not include relay hints; include at least one relay in the nevent/naddr");if(t.type==="nevent"){if(t.data.kind!==void 0&&!Ai(t.data.kind))throw new Error(`nevent points at kind ${t.data.kind}, not a NIP-5D napplet manifest kind`);return{type:"nevent",relays:r,filter:{ids:[t.data.id],kinds:t.data.kind===void 0?[...ct]:[t.data.kind],authors:t.data.author?[t.data.author]:void 0,limit:1}}}if(t.data.kind!==ge)throw new Error(`naddr kind ${t.data.kind} is not the named napplet kind ${ge}`);return{type:"naddr",relays:r,filter:{kinds:[ge],authors:[t.data.pubkey],"#d":[t.data.identifier],limit:1}}}function qi(e){return{id:e.id,pubkey:e.pubkey,kind:e.kind,tags:e.tags}}async function Rn(e){const t=typeof e=="string"?new TextEncoder().encode(e):e,r=new Uint8Array(t.byteLength);r.set(t);const n=await crypto.subtle.digest("SHA-256",r.buffer);return[...new Uint8Array(n)].map(i=>i.toString(16).padStart(2,"0")).join("")}function Ni(e){return e.tags.filter(t=>t[0]==="path"&&typeof t[1]=="string"&&typeof t[2]=="string")}async function Li(e){const t=Ni(e).map(r=>`${r[2]} ${r[1]}
|
|
80
|
+
`).sort().join("");return Rn(t)}async function Pi(e){const t=await Li(e);for(const r of e.tags.filter(n=>n[0]==="x"))if(r[2]!==t)throw new Error(`Manifest x tag does not match recomputed aggregate hash ${t}`)}function _i(e){return e.tags.find(t=>t[0]==="path"&&t[1]==="/index.html")}function Ci(e){const t=[];for(const r of e.tags)if(!(r[0]!=="server"||!r[1]))try{const n=new URL(r[1]);(n.protocol==="http:"||n.protocol==="https:")&&t.push(n.href)}catch{}return[...new Set(t)]}function Ui(e,t){const r=e.endsWith("/")?e:`${e}/`;return new URL(t,r).href}async function Hi(e,t=fetch){const n=_i(e)?.[2];if(!n)throw new Error("Manifest does not include a /index.html path hash");const i=Ci(e);if(i.length===0)throw new Error("Manifest does not include any usable Blossom server hints");const s=[];for(const o of i){const c=Ui(o,n);try{const a=await t(c,{mode:"cors"});if(!a.ok){s.push(`${c}: HTTP ${a.status}`);continue}const d=new Uint8Array(await a.arrayBuffer()),f=await Rn(d);if(f!==n){s.push(`${c}: sha256 ${f} did not match manifest ${n}`);continue}return new TextDecoder().decode(d)}catch(a){s.push(`${c}: ${a instanceof Error?a.message:String(a)}`)}}throw new Error(`Unable to fetch verified /index.html from Blossom servers: ${s.join("; ")}`)}async function ji(e,t){try{const n=await(await t(e,{mode:"cors"})).text();return{source:"url",input:e,label:e,bootUrl:e,html:n,fetched:!0,manifestEvent:null}}catch{return{source:"url",input:e,label:e,bootUrl:e,html:"",fetched:!1,manifestEvent:null}}}async function Di(e,t){const r=Oi(e),n=!t.pool,i=t.pool??new vi;try{const s=await i.get(r.relays,{...r.filter},{maxWait:t.maxRelayWaitMs??Ii});if(!s)throw new Error("No matching napplet manifest event was found on the pointer relay hints");if(!$i(s))throw new Error("Resolved manifest event signature is invalid");const o=qi(s),c=lt(o);if(!c.ok)throw new Error(`Resolved event is not a valid NIP-5D napplet manifest: ${c.errors[0]?.message}`);await Pi(o);const a=await Hi(o,t.fetcher??fetch),d=(t.createObjectUrl??URL.createObjectURL)(new Blob([a],{type:"text/html;charset=utf-8"})),f=()=>(t.revokeObjectUrl??URL.revokeObjectURL)(d);return{source:"nostr",input:e,label:o.id??e,bootUrl:d,html:a,fetched:!0,manifestEvent:o,revoke:f}}finally{n&&i.destroy()}}async function Mi(e,t={}){const r=e.trim();if(!r)throw new Error("Enter a NIP-19 nevent/naddr, or an HTTP URL for local dev");return Ti(r)?ji(r,t.fetcher??fetch):Di(r,t)}const Fi=/\bwindow\s*\.\s*nostr\b|\bglobalThis\s*\.\s*nostr\b/,Wi="/__conformance__/events",st=new URLSearchParams(location.search),$n=st.get("live")==="1";function ne(e){return String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}const re=document.getElementById("app");function Zi(){return re.innerHTML=`
|
|
81
|
+
<header class="masthead">
|
|
82
|
+
<h1>napplet conformance ${$n?'<span class="live-badge" id="live-badge">● live</span>':""}</h1>
|
|
83
|
+
<p>Load a napplet by <code>nevent</code> or <code>naddr</code> and run NAP protocol conformance live. Same engine as <code>napplet-conformance</code> CI.</p>
|
|
84
|
+
</header>
|
|
85
|
+
<form id="run-form" class="runbar">
|
|
86
|
+
<input id="target" type="text" placeholder="naddr1… or nevent1… for a NIP-5D napplet manifest" autocomplete="off" spellcheck="false" />
|
|
87
|
+
<button id="run" type="submit">Run conformance</button>
|
|
88
|
+
<button id="rerun" type="button" class="secondary" hidden>Re-run</button>
|
|
89
|
+
</form>
|
|
90
|
+
<p id="status" class="status" role="status"></p>
|
|
91
|
+
<section id="output" class="output"></section>
|
|
92
|
+
`,{targetInput:re.querySelector("#target"),runButton:re.querySelector("#run"),rerunButton:re.querySelector("#rerun"),liveBadge:re.querySelector("#live-badge")??document.createElement("span"),status:re.querySelector("#status"),output:re.querySelector("#output")}}const C=Zi();let be="",ot=0;function Ie(e,t="info"){C.status.textContent=e,C.status.dataset.kind=t}function Ge(e){return String(e).padStart(2,"0")}function Vi(e){const t=new Date(e);return`${Ge(t.getHours())}:${Ge(t.getMinutes())}:${Ge(t.getSeconds())}`}function Ki(e){const t=e.ok?"conformant":"non-conformant",n=[...new Set(e.checks.map(o=>o.area))].map(o=>{const c=e.checks.filter(a=>a.area===o).map(a=>{const d=a.severity==="warning"&&a.status==="fail"?' <span class="tag warn">warning</span>':"",f=a.detail?`<span class="detail">${ne(a.detail)}</span>`:"";return`<li class="check ${a.status}"><span class="badge ${a.status}">${a.status}</span><span class="id">${ne(a.id)}</span>${d}${f}</li>`}).join("");return`<div class="area"><h3>${ne(o)}</h3><ul>${c}</ul></div>`}).join(""),i=e.summary,s=ot>1?`<span class="run-stamp">run #${ot} · ${Vi(e.finishedAt)}</span>`:"";return`
|
|
93
|
+
<div class="verdict ${t}">
|
|
94
|
+
<span class="result">${e.ok?"CONFORMANT":"NON-CONFORMANT"}</span>
|
|
95
|
+
<span class="counts">${i.passed} passed · ${i.failed} failed · ${i.skipped} skipped${i.warnings?` · ${i.warnings} warning(s)`:""}</span>
|
|
96
|
+
${s}
|
|
97
|
+
</div>
|
|
98
|
+
<div class="checks">${n}</div>
|
|
99
|
+
`}function Yi(e){return e.length===0?'<p class="empty">No envelopes were emitted.</p>':`<ul class="envlog">${e.map(r=>{const n=r.verdict.ok?"ok":"bad",i=r.verdict.ok?"":`<div class="errs">${r.verdict.errors.map(s=>ne(`${s.code}: ${s.message}`)).join("<br>")}</div>`;return`<li class="env ${n}"><code>${ne(JSON.stringify(r.envelope))}</code>${i}</li>`}).join("")}</ul>`}function zi(e){const t=(r,n)=>`<tr><th>${ne(r)}</th><td>${n?ne(String(n)):"<em>—</em>"}</td></tr>`;if(e.manifestEvent){const r=e.manifestEvent,n=lt(r),i=r.tags.find(c=>c[0]==="d")?.[1],s=r.tags.find(c=>c[0]==="path"&&c[1]==="/index.html"),o=r.tags.filter(c=>c[0]==="server").map(c=>c[1]).filter(Boolean);return`
|
|
100
|
+
<table class="manifest">
|
|
101
|
+
${t("event",r.id)}
|
|
102
|
+
${t("kind",r.kind)}
|
|
103
|
+
${t("d",i)}
|
|
104
|
+
${t("name",Zt(r))}
|
|
105
|
+
${t("requires",n.requires.join(", "))}
|
|
106
|
+
${t("/index.html",s?.[2])}
|
|
107
|
+
${t("servers",o.join(", "))}
|
|
108
|
+
</table>
|
|
109
|
+
${n.errors.length?`<div class="errs">${n.errors.map(c=>ne(`${c.code}: ${c.message}`)).join("<br>")}</div>`:""}
|
|
110
|
+
`}return e.fetched?'<p class="empty">Local URL mode booted raw HTML. It does not include a signed NIP-5D manifest event, so manifest-event checks are skipped.</p>':`<p class="empty">Couldn't fetch the local URL HTML, likely because of CORS. Use a NIP-19 <code>nevent</code>/<code>naddr</code> for authoritative manifest checks, or use the CLI for local URL runs.</p>`}function Gi(e,t,r){C.output.innerHTML=`
|
|
111
|
+
${Ki(e)}
|
|
112
|
+
<div class="panels">
|
|
113
|
+
<section class="panel"><h2>Emitted envelopes (${t.length})</h2>${Yi(t)}</section>
|
|
114
|
+
<section class="panel"><h2>Manifest</h2>${zi(r)}</section>
|
|
115
|
+
</div>
|
|
116
|
+
`}async function De(e){be=e,C.runButton.disabled=!0,C.rerunButton.disabled=!0;let t=null;try{Ie(`Resolving ${e} …`),t=await Mi(e);const r=Fi.test(t.html)?["window.nostr"]:[];Ie("Booting napplet in a sandboxed iframe …");const n=await tr({url:t.bootUrl,readyTimeoutMs:5e3,settleMs:800,runDegraded:!0}),i=zn({manifestHtml:t.html,manifestEvent:t.manifestEvent,boot:n,forbiddenGlobals:r}),s=ar(i);ot+=1,Ie(s.ok?"Done — conformant.":"Done — non-conformant.",s.ok?"info":"error"),Gi(s,n.emitted,t),C.rerunButton.hidden=!1}catch(r){Ie(`Error: ${r instanceof Error?r.message:String(r)}`,"error")}finally{t?.revoke?.(),C.runButton.disabled=!1,C.rerunButton.disabled=!1}}function Xi(){if(!$n||typeof EventSource>"u")return;let e=!1;const t=new EventSource(Wi);t.addEventListener("rerun",()=>{!be||e||(e=!0,setTimeout(()=>{e=!1,De(be)},50))}),t.addEventListener("open",()=>{C.liveBadge&&(C.liveBadge.dataset.state="connected")}),t.addEventListener("error",()=>{C.liveBadge&&(C.liveBadge.dataset.state="disconnected")})}C.runButton.parentElement.addEventListener("submit",e=>{e.preventDefault();const t=C.targetInput.value.trim();if(t){const r=new URL(location.href);r.searchParams.set("target",t),r.searchParams.delete("url"),history.replaceState(null,"",r),De(t)}});C.rerunButton.addEventListener("click",()=>{be&&De(be)});Xi();const Xe=st.get("target")??st.get("url");Xe&&(C.targetInput.value=Xe,De(Xe));
|
package/dist/ui/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>napplet conformance runtime</title>
|
|
7
7
|
<meta name="description" content="Load a napplet and run NAP protocol conformance checks live in your browser." />
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-DV1wZ-SF.js"></script>
|
|
9
9
|
<link rel="stylesheet" crossorigin href="/assets/index-D4WUxbBl.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@napplet/conformance-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.19",
|
|
4
4
|
"description": "Headless CLI that runs @napplet/conformance against a napplet in real Chromium via Playwright — the `test:conformance` runner",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -15,14 +15,14 @@
|
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"playwright": "^1.59.1",
|
|
18
|
-
"@napplet/conformance": "^0.
|
|
18
|
+
"@napplet/conformance": "^0.17.0"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@types/node": "^22.15.0",
|
|
22
22
|
"tsup": "^8.5.0",
|
|
23
23
|
"typescript": "^5.9.3",
|
|
24
24
|
"vitest": "^4.1.2",
|
|
25
|
-
"@napplet/conformance-web": "0.0.
|
|
25
|
+
"@napplet/conformance-web": "0.0.18"
|
|
26
26
|
},
|
|
27
27
|
"license": "MIT",
|
|
28
28
|
"repository": {
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))n(i);new MutationObserver(i=>{for(const s of i)if(s.type==="childList")for(const o of s.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&n(o)}).observe(document,{childList:!0,subtree:!0});function r(i){const s={};return i.integrity&&(s.integrity=i.integrity),i.referrerPolicy&&(s.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?s.credentials="include":i.crossOrigin==="anonymous"?s.credentials="omit":s.credentials="same-origin",s}function n(i){if(i.ep)return;i.ep=!0;const s=r(i);fetch(i.href,s)}})();var ot=["relay","identity","storage","inc","theme","keys","media","notify","config","resource","cvm","outbox","upload","intent","ble","webrtc","link","count","lists","serial","fs","common","dm"],d={id:"string"},In={"relay.subscribe":{dir:"out",fields:{...d,subId:"string",filters:"array"}},"relay.close":{dir:"out",fields:{...d,subId:"string"}},"relay.publish":{dir:"out",fields:{...d,event:"object"}},"relay.publishEncrypted":{dir:"out",fields:{...d,event:"object",recipient:"string"}},"relay.query":{dir:"out",fields:{...d,filters:"array"}},"relay.event":{dir:"in"},"relay.eose":{dir:"in"},"relay.closed":{dir:"in"},"relay.publish.result":{dir:"in"},"relay.publishEncrypted.result":{dir:"in"},"relay.query.result":{dir:"in"},"identity.getPublicKey":{dir:"out",fields:{...d}},"identity.getRelays":{dir:"out",fields:{...d}},"identity.getProfile":{dir:"out",fields:{...d}},"identity.getFollows":{dir:"out",fields:{...d}},"identity.getList":{dir:"out",fields:{...d,listType:"string"}},"identity.getZaps":{dir:"out",fields:{...d}},"identity.getMutes":{dir:"out",fields:{...d}},"identity.getBlocked":{dir:"out",fields:{...d}},"identity.getBadges":{dir:"out",fields:{...d}},"identity.changed":{dir:"in"},"identity.getPublicKey.result":{dir:"in"},"identity.getRelays.result":{dir:"in"},"identity.getProfile.result":{dir:"in"},"identity.getFollows.result":{dir:"in"},"identity.getList.result":{dir:"in"},"identity.getZaps.result":{dir:"in"},"identity.getMutes.result":{dir:"in"},"identity.getBlocked.result":{dir:"in"},"identity.getBadges.result":{dir:"in"},"storage.get":{dir:"out",fields:{...d,key:"string"}},"storage.set":{dir:"out",fields:{...d,key:"string",value:"string"}},"storage.remove":{dir:"out",fields:{...d,key:"string"}},"storage.keys":{dir:"out",fields:{...d}},"storage.get.result":{dir:"in"},"storage.set.result":{dir:"in"},"storage.remove.result":{dir:"in"},"storage.keys.result":{dir:"in"},"inc.emit":{dir:"out",fields:{topic:"string"},forbiddenFields:["sender"]},"inc.subscribe":{dir:"out",fields:{...d,topic:"string"}},"inc.unsubscribe":{dir:"out",fields:{topic:"string"}},"inc.channel.open":{dir:"out",fields:{...d,target:"string"}},"inc.channel.emit":{dir:"out",fields:{channelId:"string"}},"inc.channel.broadcast":{dir:"out"},"inc.channel.list":{dir:"out",fields:{...d}},"inc.channel.close":{dir:"out",fields:{channelId:"string"}},"inc.subscribe.result":{dir:"in"},"inc.event":{dir:"in",fields:{topic:"string",sender:"string"}},"inc.channel.open.result":{dir:"in"},"inc.channel.opened":{dir:"in",fields:{channelId:"string",peer:"string"}},"inc.channel.event":{dir:"in"},"inc.channel.list.result":{dir:"in"},"inc.channel.closed":{dir:"in"},"theme.get":{dir:"out",fields:{...d}},"theme.get.result":{dir:"in"},"theme.changed":{dir:"in"},"keys.forward":{dir:"out",fields:{key:"string",code:"string",ctrl:"boolean",alt:"boolean",shift:"boolean",meta:"boolean"}},"keys.registerAction":{dir:"out",fields:{...d,action:"object"}},"keys.unregisterAction":{dir:"out",fields:{actionId:"string"}},"keys.registerAction.result":{dir:"in"},"keys.bindings":{dir:"in"},"keys.action":{dir:"in"},"media.session.create":{dir:"out",fields:{...d,owner:"object"}},"media.session.update":{dir:"out",fields:{sessionId:"string",metadata:"object"}},"media.session.destroy":{dir:"out",fields:{sessionId:"string"}},"media.state":{dir:"out",fields:{sessionId:"string",status:"string"}},"media.capabilities":{dir:"out",fields:{sessionId:"string",actions:"array"}},"media.session.create.result":{dir:"in"},"media.command":{dir:"in"},"media.controls":{dir:"in"},"notify.send":{dir:"out",fields:{...d,title:"string"}},"notify.dismiss":{dir:"out",fields:{notificationId:"string"}},"notify.badge":{dir:"out",fields:{count:"number"}},"notify.channel.register":{dir:"out",fields:{channelId:"string",label:"string"}},"notify.permission.request":{dir:"out",fields:{...d}},"notify.send.result":{dir:"in"},"notify.permission.result":{dir:"in"},"notify.action":{dir:"in"},"notify.clicked":{dir:"in"},"notify.dismissed":{dir:"in"},"notify.controls":{dir:"in"},"config.registerSchema":{dir:"out",fields:{...d,schema:"object"}},"config.get":{dir:"out",fields:{...d}},"config.subscribe":{dir:"out"},"config.unsubscribe":{dir:"out"},"config.openSettings":{dir:"out"},"config.registerSchema.result":{dir:"in"},"config.values":{dir:"in"},"config.schemaError":{dir:"in"},"resource.info":{dir:"out",fields:{...d}},"resource.bytes":{dir:"out",fields:{...d,url:"string"}},"resource.bytesMany":{dir:"out",fields:{...d,urls:"array"}},"resource.cancel":{dir:"out",fields:{...d}},"resource.info.result":{dir:"in"},"resource.info.error":{dir:"in"},"resource.bytes.result":{dir:"in"},"resource.bytes.error":{dir:"in"},"resource.bytesMany.result":{dir:"in"},"resource.bytesMany.error":{dir:"in"},"cvm.discover":{dir:"out",fields:{...d}},"cvm.request":{dir:"out",fields:{...d,server:"object",message:"object"}},"cvm.close":{dir:"out",fields:{...d,server:"object"}},"cvm.registry.list":{dir:"out",fields:{...d}},"cvm.registry.has":{dir:"out",fields:{...d,family:"string"}},"cvm.registry.describe":{dir:"out",fields:{...d,family:"string"}},"cvm.registry.call":{dir:"out",fields:{...d,family:"string",tool:"string"}},"cvm.discover.result":{dir:"in"},"cvm.request.result":{dir:"in"},"cvm.close.result":{dir:"in"},"cvm.event":{dir:"in"},"cvm.registry.list.result":{dir:"in"},"cvm.registry.has.result":{dir:"in"},"cvm.registry.describe.result":{dir:"in"},"cvm.registry.call.result":{dir:"in"},"outbox.getEvent":{dir:"out",fields:{...d,eventId:"string"}},"outbox.query":{dir:"out",fields:{...d,filters:"present"}},"outbox.subscribe":{dir:"out",fields:{...d,subId:"string",filters:"present"}},"outbox.close":{dir:"out",fields:{...d,subId:"string"}},"outbox.publish":{dir:"out",fields:{...d,event:"object"}},"outbox.resolveRelays":{dir:"out",fields:{...d,target:"present"}},"outbox.getEvent.result":{dir:"in"},"outbox.query.result":{dir:"in"},"outbox.event":{dir:"in"},"outbox.closed":{dir:"in"},"outbox.publish.result":{dir:"in"},"outbox.resolveRelays.result":{dir:"in"},"upload.info":{dir:"out",fields:{...d}},"upload.upload":{dir:"out",fields:{...d,request:"object"}},"upload.status":{dir:"out",fields:{...d,uploadId:"string"}},"upload.info.result":{dir:"in"},"upload.upload.result":{dir:"in"},"upload.status.result":{dir:"in"},"upload.status.changed":{dir:"in"},"intent.invoke":{dir:"out",fields:{...d,request:"object"}},"intent.available":{dir:"out",fields:{...d,archetype:"string"}},"intent.handlers":{dir:"out",fields:{...d}},"intent.invoke.result":{dir:"in"},"intent.available.result":{dir:"in"},"intent.handlers.result":{dir:"in"},"intent.changed":{dir:"in"},"ble.open":{dir:"out",fields:{...d,request:"object"}},"ble.services":{dir:"out",fields:{...d,sessionId:"string"}},"ble.read":{dir:"out",fields:{...d,sessionId:"string",target:"object"}},"ble.write":{dir:"out",fields:{...d,sessionId:"string",target:"object",data:"array"}},"ble.subscribe":{dir:"out",fields:{...d,sessionId:"string",target:"object"}},"ble.unsubscribe":{dir:"out",fields:{...d,sessionId:"string",target:"object"}},"ble.close":{dir:"out",fields:{...d,sessionId:"string"}},"ble.open.result":{dir:"in"},"ble.services.result":{dir:"in"},"ble.read.result":{dir:"in"},"ble.write.result":{dir:"in"},"ble.subscribe.result":{dir:"in"},"ble.unsubscribe.result":{dir:"in"},"ble.close.result":{dir:"in"},"ble.event":{dir:"in"},"common.encodeNip19":{dir:"out",fields:{...d,input:"object"}},"common.decodeNip19":{dir:"out",fields:{...d,value:"string"}},"common.getProfile":{dir:"out",fields:{...d,target:"string"}},"common.follows":{dir:"out",fields:{...d}},"common.follow":{dir:"out",fields:{...d,pubkeys:"array"}},"common.unfollow":{dir:"out",fields:{...d,pubkeys:"array"}},"common.react":{dir:"out",fields:{...d,targetEventId:"string",reaction:"string"}},"common.report":{dir:"out",fields:{...d,target:"object",reason:"string",text:"string"}},"common.encodeNip19.result":{dir:"in"},"common.decodeNip19.result":{dir:"in"},"common.getProfile.result":{dir:"in"},"common.follows.result":{dir:"in"},"common.follow.result":{dir:"in"},"common.unfollow.result":{dir:"in"},"common.react.result":{dir:"in"},"common.report.result":{dir:"in"},"webrtc.open":{dir:"out",fields:{...d,request:"object"}},"webrtc.send":{dir:"out",fields:{...d,sessionId:"string",payload:"present"}},"webrtc.close":{dir:"out",fields:{...d,sessionId:"string"}},"webrtc.open.result":{dir:"in"},"webrtc.send.result":{dir:"in"},"webrtc.close.result":{dir:"in"},"webrtc.event":{dir:"in"},"link.open":{dir:"out",fields:{...d,url:"string"}},"link.open.result":{dir:"in"},"count.query":{dir:"out",fields:{...d,filters:"array"}},"count.query.result":{dir:"in"},"lists.supported":{dir:"out",fields:{...d}},"lists.add":{dir:"out",fields:{...d,list:"object",items:"array"}},"lists.remove":{dir:"out",fields:{...d,list:"object",items:"array"}},"lists.supported.result":{dir:"in"},"lists.add.result":{dir:"in"},"lists.remove.result":{dir:"in"},"serial.open":{dir:"out",fields:{...d,request:"object"}},"serial.write":{dir:"out",fields:{...d,sessionId:"string",data:"array"}},"serial.close":{dir:"out",fields:{...d,sessionId:"string"}},"serial.open.result":{dir:"in"},"serial.write.result":{dir:"in"},"serial.close.result":{dir:"in"},"serial.event":{dir:"in"},"fs.info":{dir:"out",fields:{...d}},"fs.pickFile":{dir:"out",fields:{...d}},"fs.pickFiles":{dir:"out",fields:{...d}},"fs.pickDirectory":{dir:"out",fields:{...d}},"fs.pickSaveFile":{dir:"out",fields:{...d}},"fs.stat":{dir:"out",fields:{...d,path:"string"}},"fs.list":{dir:"out",fields:{...d,path:"string"}},"fs.read":{dir:"out",fields:{...d,path:"string"}},"fs.write":{dir:"out",fields:{...d,path:"string",data:"string"}},"fs.mkdir":{dir:"out",fields:{...d,path:"string"}},"fs.remove":{dir:"out",fields:{...d,path:"string"}},"fs.move":{dir:"out",fields:{...d,fromPath:"string",toPath:"string"}},"fs.watch":{dir:"out",fields:{...d,path:"string"}},"fs.unwatch":{dir:"out",fields:{...d,watchId:"string"}},"fs.info.result":{dir:"in"},"fs.pickFile.result":{dir:"in"},"fs.pickFiles.result":{dir:"in"},"fs.pickDirectory.result":{dir:"in"},"fs.pickSaveFile.result":{dir:"in"},"fs.stat.result":{dir:"in"},"fs.list.result":{dir:"in"},"fs.read.result":{dir:"in"},"fs.write.result":{dir:"in"},"fs.mkdir.result":{dir:"in"},"fs.remove.result":{dir:"in"},"fs.move.result":{dir:"in"},"fs.watch.result":{dir:"in"},"fs.unwatch.result":{dir:"in"},"fs.changed":{dir:"in"},"dm.status":{dir:"out",fields:{...d}},"dm.conversations":{dir:"out",fields:{...d}},"dm.messages":{dir:"out",fields:{...d,conversationId:"string"}},"dm.send":{dir:"out",fields:{...d,recipients:"array",content:"string"}},"dm.subscribe":{dir:"out",fields:{...d}},"dm.unsubscribe":{dir:"out",fields:{...d,subscriptionId:"string"}},"dm.status.result":{dir:"in"},"dm.conversations.result":{dir:"in"},"dm.messages.result":{dir:"in"},"dm.send.result":{dir:"in"},"dm.subscribe.result":{dir:"in"},"dm.unsubscribe.result":{dir:"in"},"dm.message":{dir:"in"}};function Ht(e){if(e===void 0)return"undefined";if(e===null)return"null";if(Array.isArray(e))return"array";const t=typeof e;return t==="string"||t==="number"||t==="boolean"?t:t==="object"?"object":"present"}function $n(e,t){return t==="present"?e!=null:Ht(e)===t}function Tn(e,t){if(typeof e!="object"||e===null||Array.isArray(e))return;const r=e;typeof r.archetype!="string"&&t.push({code:r.archetype===void 0?"missing-field":"wrong-type",message:'Intent request requires a string "archetype" field',field:"request.archetype"});for(const n of["action","convention"])r[n]!==void 0&&typeof r[n]!="string"&&t.push({code:"wrong-type",message:`Intent request field "${n}" must be a string`,field:`request.${n}`});"sender"in r&&t.push({code:"forbidden-field",message:"Intent request does not define a caller-supplied sender field",field:"request.sender"})}function Bn(e){const t=[];if(typeof e!="object"||e===null||Array.isArray(e))return{ok:!1,errors:[{code:"not-an-object",message:"Envelope must be a non-null object"}]};const r=e,n=r.type;if(typeof n!="string")return{ok:!1,errors:[{code:"missing-type",message:"Envelope is missing a string `type` field"}]};const i=n.indexOf(".");if(i<=0)return{ok:!1,type:n,errors:[{code:"malformed-type",message:`Envelope type "${n}" is not in domain.action form`}]};const s=n.slice(0,i);if(!ot.includes(s))return{ok:!1,type:n,domain:s,errors:[{code:"unknown-domain",message:`"${s}" is not a known NAP domain`}]};const c=In[n];if(!c)return{ok:!1,type:n,domain:s,errors:[{code:"unknown-type",message:`"${n}" is not a known ${s} message type`}]};for(const[a,l]of Object.entries(c.fields??{})){if(!(a in r)||r[a]===void 0){t.push({code:"missing-field",message:`Required field "${a}" is missing`,field:a});continue}$n(r[a],l)||t.push({code:"wrong-type",message:`Field "${a}" should be ${l} but is ${Ht(r[a])}`,field:a})}if(c.dir==="in")return{ok:!1,type:n,domain:s,direction:"in",errors:[{code:"inbound-type-emitted",message:`"${n}" is a shell→napplet message; a napplet must not emit it`},...t]};for(const a of c.forbiddenFields??[])a in r&&t.push({code:"forbidden-field",message:`Field "${a}" must be runtime-derived and cannot be emitted by a napplet`,field:a});return n==="intent.invoke"&&Tn(r.request,t),{ok:t.length===0,type:n,domain:s,direction:"out",errors:t}}var Dt=5129,jt=15129,ge=35129,at=[Dt,jt,ge];function Mt(e,t){return e.tags.find(r=>r[0]===t)}function An(e){return at.includes(e)}function On(e){return typeof e=="string"&&/^[0-9a-f]{64}$/i.test(e)}function Ft(e){return Mt(e,"d")?.[1]?.trim()||void 0}function Nn(e){return e.tags.filter(t=>t[0]==="requires").map(t=>t[1]?.trim()??"").filter(Boolean)}function Wt(e){return Ft(e)??Mt(e,"title")?.[1]??e.id}function ct(e){const t=[],r=[];if(!e)return{ok:!1,requires:[],errors:[{code:"missing-manifest-event",message:"No NIP-5D manifest event was resolved"}],warnings:r};const n=Ft(e),i=Nn(e);An(e.kind)||t.push({code:"invalid-napplet-kind",message:`Manifest event kind ${e.kind} is not a NIP-5D napplet kind`}),e.kind===ge&&!n?t.push({code:"missing-d-tag",message:"Named napplet manifest kind 35129 must include a non-empty d tag"}):(e.kind===jt||e.kind===Dt)&&n&&t.push({code:"unexpected-d-tag",message:`Napplet manifest kind ${e.kind} must not include a d tag`});const s=e.tags.find(o=>o[0]==="path"&&o[1]==="/index.html");s?On(s[2])||t.push({code:"invalid-index-html-hash",message:"The /index.html path tag must carry a 64-character sha256 hash"}):t.push({code:"missing-index-html",message:"Napplet manifest must include a path tag for /index.html"});for(const o of i){if(o.startsWith("nap:")||o.startsWith("NAP-")){t.push({code:"invalid-required-nap",message:`requires tag "${o}" must be a bare NAP domain such as "relay"`});continue}ot.includes(o)||t.push({code:"unknown-required-nap",message:`requires tag "${o}" is not a known NAP domain`})}return{ok:t.length===0,kind:e.kind,dTag:n,requires:i,errors:t,warnings:r}}var xe="f".repeat(64),qn={dTag:"reference-source"},Ln="https://reference.invalid/blob",bt="reference-handler",Pn="reference-subscriber",ke="napplet:note/open";function Se(e,t,r){return h({type:e,id:t,result:{entries:[r]}})}var h=e=>[e],L=()=>[];function wt(e){if(typeof e!="string"||!e.startsWith("data:"))return null;const t=e.indexOf(",");if(t<0)return{blob:new Blob([],{type:"text/plain"}),mime:"text/plain"};const r=e.slice(5,t),n=e.slice(t+1),i=r.split(";").filter(Boolean),s=i.includes("base64"),o=i.find(c=>c.includes("/"))??"text/plain";try{if(s){const c=globalThis.atob(n),a=Uint8Array.from(c,l=>l.charCodeAt(0));return{blob:new Blob([a],{type:o}),mime:o}}return{blob:new Blob([decodeURIComponent(n)],{type:o}),mime:o}}catch{return null}}var _n={"relay.subscribe":e=>h({type:"relay.eose",subId:e.subId}),"relay.close":L,"relay.publish":e=>h({type:"relay.publish.result",id:e.id,ok:!0,event:e.event}),"relay.publishEncrypted":e=>h({type:"relay.publishEncrypted.result",id:e.id,ok:!0,event:e.event}),"relay.query":e=>h({type:"relay.query.result",id:e.id,events:[]}),"identity.getPublicKey":e=>h({type:"identity.getPublicKey.result",id:e.id,pubkey:xe}),"identity.getRelays":e=>h({type:"identity.getRelays.result",id:e.id,relays:{}}),"identity.getProfile":e=>h({type:"identity.getProfile.result",id:e.id,profile:null}),"identity.getFollows":e=>h({type:"identity.getFollows.result",id:e.id,pubkeys:[]}),"identity.getList":e=>h({type:"identity.getList.result",id:e.id,entries:[]}),"identity.getZaps":e=>h({type:"identity.getZaps.result",id:e.id,zaps:[]}),"identity.getMutes":e=>h({type:"identity.getMutes.result",id:e.id,pubkeys:[]}),"identity.getBlocked":e=>h({type:"identity.getBlocked.result",id:e.id,pubkeys:[]}),"identity.getBadges":e=>h({type:"identity.getBadges.result",id:e.id,badges:[]}),"storage.get":e=>h({type:"storage.get.result",id:e.id,value:null}),"storage.set":e=>h({type:"storage.set.result",id:e.id}),"storage.remove":e=>h({type:"storage.remove.result",id:e.id}),"storage.keys":e=>h({type:"storage.keys.result",id:e.id,keys:[]}),"inc.emit":L,"inc.subscribe":e=>h({type:"inc.subscribe.result",id:e.id}),"inc.unsubscribe":L,"inc.channel.open":e=>h({type:"inc.channel.open.result",id:e.id,channelId:`chan-${String(e.id)}`,peer:"reference-peer"}),"inc.channel.emit":L,"inc.channel.broadcast":L,"inc.channel.list":e=>h({type:"inc.channel.list.result",id:e.id,channels:[]}),"inc.channel.close":L,"theme.get":e=>h({type:"theme.get.result",id:e.id,theme:{colors:{},mode:"dark"}}),"keys.forward":L,"keys.registerAction":e=>h({type:"keys.registerAction.result",id:e.id,actionId:`action-${String(e.id)}`}),"keys.unregisterAction":L,"media.session.create":e=>h({type:"media.session.create.result",id:e.id,sessionId:`session-${String(e.id)}`,owner:e.owner}),"media.session.update":L,"media.session.destroy":L,"media.state":L,"media.capabilities":L,"notify.send":e=>h({type:"notify.send.result",id:e.id,notificationId:`notif-${String(e.id)}`}),"notify.dismiss":L,"notify.badge":L,"notify.channel.register":L,"notify.permission.request":e=>h({type:"notify.permission.result",id:e.id,granted:!0}),"config.registerSchema":e=>h({type:"config.registerSchema.result",id:e.id,ok:!0}),"config.get":e=>h({type:"config.values",id:e.id,values:{}}),"config.subscribe":()=>h({type:"config.values",values:{}}),"config.unsubscribe":L,"config.openSettings":L,"resource.bytes":e=>{const t=wt(e.url);return h(t?{type:"resource.bytes.result",id:e.id,blob:t.blob,mime:t.mime}:{type:"resource.bytes.result",id:e.id,blob:new Blob([]),mime:"application/octet-stream"})},"resource.bytesMany":e=>h({type:"resource.bytesMany.result",id:e.id,items:Array.isArray(e.urls)?e.urls.map(t=>{const r=wt(t);return{url:t,ok:!0,blob:r?.blob??new Blob([]),mime:r?.mime??"application/octet-stream"}}):[]}),"resource.info":e=>h({type:"resource.info.result",id:e.id,info:{schemes:[{scheme:"data",enabled:!0},{scheme:"https",enabled:!0}]}}),"resource.cancel":L,"cvm.discover":e=>h({type:"cvm.discover.result",id:e.id,servers:[]}),"cvm.request":e=>h({type:"cvm.request.result",id:e.id,message:{}}),"cvm.close":e=>h({type:"cvm.close.result",id:e.id}),"outbox.getEvent":e=>h({type:"outbox.getEvent.result",id:e.id}),"outbox.query":e=>h({type:"outbox.query.result",id:e.id,events:[]}),"outbox.subscribe":e=>h({type:"outbox.closed",subId:e.subId,reason:"reference shell complete"}),"outbox.close":L,"outbox.publish":e=>h({type:"outbox.publish.result",id:e.id,ok:!0}),"outbox.resolveRelays":e=>h({type:"outbox.resolveRelays.result",id:e.id,plan:{}}),"upload.info":e=>h({type:"upload.info.result",id:e.id,info:{rails:[{rail:"nip96",enabled:!0,returns:["https"]},{rail:"blossom",enabled:!0,returns:["https","blossom"]}]}}),"upload.upload":e=>h({type:"upload.upload.result",id:e.id,result:{url:Ln}}),"upload.status":e=>h({type:"upload.status.result",id:e.id,status:{}}),"ble.open":e=>h({type:"ble.open.result",id:e.id,session:{id:"ble-reference",state:"open",device:{id:"reference-device",name:"Reference BLE"}}}),"ble.services":e=>h({type:"ble.services.result",id:e.id,services:[]}),"ble.read":e=>h({type:"ble.read.result",id:e.id,data:[]}),"ble.write":e=>h({type:"ble.write.result",id:e.id}),"ble.subscribe":e=>h({type:"ble.subscribe.result",id:e.id}),"ble.unsubscribe":e=>h({type:"ble.unsubscribe.result",id:e.id}),"ble.close":e=>h({type:"ble.close.result",id:e.id}),"common.encodeNip19":e=>h({type:"common.encodeNip19.result",id:e.id,ok:!0,value:"npub1reference",nip19Type:"npub"}),"common.decodeNip19":e=>h({type:"common.decodeNip19.result",id:e.id,ok:!0,nip19Type:"npub",hex:xe}),"common.getProfile":e=>h({type:"common.getProfile.result",id:e.id,ok:!0,pubkey:xe,profile:null}),"common.follows":e=>h({type:"common.follows.result",id:e.id,ok:!0,pubkeys:[]}),"common.follow":e=>h({type:"common.follow.result",id:e.id,ok:!0}),"common.unfollow":e=>h({type:"common.unfollow.result",id:e.id,ok:!0}),"common.react":e=>h({type:"common.react.result",id:e.id,ok:!0,eventId:"0".repeat(64)}),"common.report":e=>h({type:"common.report.result",id:e.id,ok:!0,eventId:"1".repeat(64)}),"webrtc.open":e=>h({type:"webrtc.open.result",id:e.id,session:{id:"webrtc-reference",scope:{type:"direct",pubkey:xe},channel:"default",state:"connecting"}}),"webrtc.send":e=>h({type:"webrtc.send.result",id:e.id}),"webrtc.close":e=>h({type:"webrtc.close.result",id:e.id}),"link.open":e=>h({type:"link.open.result",id:e.id,status:"opened"}),"count.query":e=>h({type:"count.query.result",id:e.id,ok:!0,count:0}),"lists.supported":e=>h({type:"lists.supported.result",id:e.id,lists:[]}),"lists.add":e=>h({type:"lists.add.result",id:e.id,ok:!0,added:0,skipped:0}),"lists.remove":e=>h({type:"lists.remove.result",id:e.id,ok:!0,removed:0,skipped:0}),"serial.open":e=>h({type:"serial.open.result",id:e.id,session:{id:`serial-${String(e.id)}`,state:"open"}}),"serial.write":e=>h({type:"serial.write.result",id:e.id}),"serial.close":e=>h({type:"serial.close.result",id:e.id}),"fs.info":e=>h({type:"fs.info.result",id:e.id,info:{roots:[{path:"/shared",name:"Shared files",permissions:["read","list","write","create","delete","watch"]}],limits:{maxReadBytes:1048576,maxWriteBytes:1048576,maxWatchCount:16}}}),"fs.pickFile":e=>Se("fs.pickFile.result",e.id,{path:"/picked/file.txt",kind:"file",name:"file.txt",permissions:["read"]}),"fs.pickFiles":e=>Se("fs.pickFiles.result",e.id,{path:"/picked/file.txt",kind:"file",name:"file.txt",permissions:["read"]}),"fs.pickDirectory":e=>Se("fs.pickDirectory.result",e.id,{path:"/picked",kind:"directory",name:"picked",permissions:["read","list"]}),"fs.pickSaveFile":e=>Se("fs.pickSaveFile.result",e.id,{path:"/picked/export.json",kind:"file",name:"export.json",permissions:["write","create"]}),"fs.stat":e=>h({type:"fs.stat.result",id:e.id,metadata:{path:e.path,kind:"file",size:0}}),"fs.list":e=>h({type:"fs.list.result",id:e.id,entries:[]}),"fs.read":e=>h({type:"fs.read.result",id:e.id,result:{data:"",offset:0,bytesRead:0,eof:!0,size:0}}),"fs.write":e=>h({type:"fs.write.result",id:e.id,result:{bytesWritten:0,size:0}}),"fs.mkdir":e=>h({type:"fs.mkdir.result",id:e.id}),"fs.remove":e=>h({type:"fs.remove.result",id:e.id}),"fs.move":e=>h({type:"fs.move.result",id:e.id}),"fs.watch":e=>h({type:"fs.watch.result",id:e.id,watchId:`watch-${String(e.id)}`}),"fs.unwatch":e=>h({type:"fs.unwatch.result",id:e.id})};function Cn(e={}){const t=e.now??(()=>Date.now()),r=[],n=new Map;function i(u,f){const p=n.get(u);if(p){p.push(f);return}n.set(u,[f])}function s(u){const f=n.get(u)??[];return n.delete(u),f}function o(u,f,p,y){return h({type:"intent.invoke.result",id:u,result:{ok:!1,archetype:f,action:p,handled:!1,error:y}})}function c(u,f){const p=f.request;if(typeof p!="object"||p===null||Array.isArray(p))return o(f.id,"","open","invalid intent request");const y=p,w=typeof y.archetype=="string"?y.archetype:"",$=typeof y.action=="string"?y.action:"open";return w?w!=="note"?o(f.id,w,$,"no handler"):y.convention!==void 0&&y.convention!==ke?o(f.id,w,$,"unsupported convention"):h({type:"intent.invoke.result",id:f.id,result:{ok:!0,archetype:w,action:$,handled:!0,handler:bt,windowId:"reference-window",convention:typeof y.convention=="string"?y.convention:ke}}):o(f.id,w,$,"intent request requires an archetype")}function a(u){return u!=="note"?{archetype:u,available:!1,candidates:[],hasDefault:!1}:{archetype:u,available:!0,candidates:[{dTag:bt,actions:["open"],conventions:[ke],isDefault:!0}],hasDefault:!0}}function l(u,f){const p=f&&typeof f=="object"&&typeof f.type=="string"?f.type:void 0,y=Bn(f);if(r.push({envelope:f,verdict:y,timestamp:t()}),!p||!y.ok)return[];const w=f;if(p==="intent.invoke")return c(u,w);if(p==="intent.available")return h({type:"intent.available.result",id:w.id,availability:a(w.archetype)});if(p==="intent.handlers")return h({type:"intent.handlers.result",id:w.id,handlers:[a("note")]});if(p==="inc.emit"){if(w.topic===ke){const N={type:"inc.event",topic:w.topic,sender:u.dTag};"payload"in w&&(N.payload=w.payload),i(Pn,N)}return[]}const $=_n[p];return $?$(w):[]}function g(u){return l(qn,u)}return{get records(){return r},handle:g,handleFrom:l,takeDeliveries:s,reset(){r.length=0,n.clear()}}}function Un(e){return{manifestHtml:e.manifestHtml,manifestEvent:e.manifestEvent??null,sandbox:e.sandbox??{allowScripts:!0,allowSameOrigin:!1},installedGlobal:e.boot.installedGlobal,bootError:e.boot.bootError,emitted:e.boot.emitted,forbiddenGlobals:e.forbiddenGlobals??[],degraded:e.boot.degraded,lifecycle:e.lifecycle??null}}var Zt="__nappletConformance.error";function vt(e){return new Promise(t=>setTimeout(t,e))}function Hn(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}function Dn(e){return`
|
|
2
|
-
(() => {
|
|
3
|
-
const domains = ${JSON.stringify(e)};
|
|
4
|
-
const napplet = {};
|
|
5
|
-
for (const domain of domains) napplet[domain] = {};
|
|
6
|
-
const pending = new Map();
|
|
7
|
-
let seq = 0;
|
|
8
|
-
const nextId = () => {
|
|
9
|
-
try {
|
|
10
|
-
if (window.crypto && typeof window.crypto.randomUUID === 'function') return window.crypto.randomUUID();
|
|
11
|
-
} catch {}
|
|
12
|
-
seq += 1;
|
|
13
|
-
return 'conformance-' + Date.now().toString(36) + '-' + seq.toString(36);
|
|
14
|
-
};
|
|
15
|
-
const request = (message, resultType, errorType) => new Promise((resolve, reject) => {
|
|
16
|
-
const id = message.id || nextId();
|
|
17
|
-
const timeout = window.setTimeout(() => {
|
|
18
|
-
pending.delete(id);
|
|
19
|
-
reject(new Error(message.type + ' timed out'));
|
|
20
|
-
}, 5000);
|
|
21
|
-
pending.set(id, { resolve, reject, resultType, errorType, timeout });
|
|
22
|
-
window.parent.postMessage({ ...message, id }, '*');
|
|
23
|
-
});
|
|
24
|
-
window.addEventListener('message', (event) => {
|
|
25
|
-
const msg = event.data;
|
|
26
|
-
if (!msg || typeof msg !== 'object' || typeof msg.id !== 'string') return;
|
|
27
|
-
const slot = pending.get(msg.id);
|
|
28
|
-
if (!slot) return;
|
|
29
|
-
if (msg.type !== slot.resultType && msg.type !== slot.errorType) return;
|
|
30
|
-
pending.delete(msg.id);
|
|
31
|
-
window.clearTimeout(slot.timeout);
|
|
32
|
-
if (msg.type === slot.errorType) {
|
|
33
|
-
slot.reject(new Error(msg.message ? msg.error + ': ' + msg.message : String(msg.error || 'request failed')));
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
slot.resolve(msg);
|
|
37
|
-
});
|
|
38
|
-
if (napplet.resource) {
|
|
39
|
-
napplet.resource.info = () =>
|
|
40
|
-
request({ type: 'resource.info' }, 'resource.info.result', 'resource.info.error')
|
|
41
|
-
.then((msg) => msg.info);
|
|
42
|
-
napplet.resource.bytes = (url) =>
|
|
43
|
-
request({ type: 'resource.bytes', url: String(url) }, 'resource.bytes.result', 'resource.bytes.error')
|
|
44
|
-
.then((msg) => msg.blob);
|
|
45
|
-
napplet.resource.bytesMany = (urls) =>
|
|
46
|
-
request({ type: 'resource.bytesMany', urls: Array.from(urls || []) }, 'resource.bytesMany.result', 'resource.bytesMany.error')
|
|
47
|
-
.then((msg) => msg.items);
|
|
48
|
-
napplet.resource.bytesAsObjectURL = (url) => {
|
|
49
|
-
const handle = { url: '', revoke: () => {} };
|
|
50
|
-
let objectUrl = '';
|
|
51
|
-
let revoked = false;
|
|
52
|
-
const ready = napplet.resource.bytes(url).then((blob) => {
|
|
53
|
-
if (revoked) return;
|
|
54
|
-
objectUrl = URL.createObjectURL(blob);
|
|
55
|
-
handle.url = objectUrl;
|
|
56
|
-
return objectUrl;
|
|
57
|
-
});
|
|
58
|
-
handle.revoke = () => {
|
|
59
|
-
if (revoked) return;
|
|
60
|
-
revoked = true;
|
|
61
|
-
if (objectUrl) URL.revokeObjectURL(objectUrl);
|
|
62
|
-
};
|
|
63
|
-
Object.defineProperty(handle, 'ready', { value: ready, enumerable: false });
|
|
64
|
-
return handle;
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
window.napplet = napplet;
|
|
68
|
-
const report = (reason) => {
|
|
69
|
-
try {
|
|
70
|
-
window.parent.postMessage({ type: '${Zt}', reason: String(reason && reason.message || reason) }, '*');
|
|
71
|
-
} catch {}
|
|
72
|
-
};
|
|
73
|
-
window.addEventListener('error', (event) => report(event.error || event.message));
|
|
74
|
-
window.addEventListener('unhandledrejection', (event) => report(event.reason));
|
|
75
|
-
})();
|
|
76
|
-
`}function jn(e,t,r){const n=`<base href="${Hn(t)}">`,i=`<script>${Dn(r)}<\/script>`,s=/<head(?:\s[^>]*)?>/i.exec(e);if(s){const o=s.index+s[0].length;return`${e.slice(0,o)}${n}${i}${e.slice(o)}`}return`${n}${i}${e}`}function Mn(e){if(!e.startsWith("data:"))return null;const t=e.indexOf(",");if(t<0)return"";const r=e.slice(0,t),n=e.slice(t+1);return r.endsWith(";base64")?atob(n):decodeURIComponent(n)}async function Fn(e){if(e==="about:blank")return"<!doctype html><html><head></head><body></body></html>";const t=Mn(e);if(t!==null)return t;const r=await fetch(e);if(!r.ok)throw new Error(`Failed to fetch napplet HTML: ${r.status} ${r.statusText}`);return r.text()}async function Et(e,t,r,n){const i=Cn(),s=r.createElement("iframe");s.setAttribute("sandbox",t.allowSameOrigin?"allow-scripts allow-same-origin":"allow-scripts"),s.setAttribute("aria-hidden","true"),s.style.position="absolute",s.style.width="1px",s.style.height="1px",s.style.left="-9999px";let o=null;const c=g=>{if(g.source!==s.contentWindow)return;const u=g.data;if(u&&typeof u=="object"&&u.type===Zt){o=`napplet boot error: ${String(u.reason??"unknown error")}`;return}const f=i.handle(g.data),p=g.source;for(const y of f)p?.postMessage(y,"*")};let a=!1;const l=new Promise(g=>{s.addEventListener("load",()=>{a=!0,g()},{once:!0})});n.addEventListener("message",c),(r.body??r.documentElement).appendChild(s);try{const g=await Fn(t.url);s.srcdoc=jn(g,t.url,e)}catch(g){o=g instanceof Error?g.message:String(g)}if(!o){const g=Symbol("timeout");await Promise.race([l.then(()=>"loaded"),vt(t.readyTimeoutMs).then(()=>g)])===g||!a?o=`napplet did not boot (iframe did not load within ${t.readyTimeoutMs}ms; a conformant napplet must run under sandbox="allow-scripts" without allow-same-origin)`:await vt(t.settleMs)}n.removeEventListener("message",c);try{s.remove()}catch{}return{installedGlobal:o===null,bootError:o,emitted:[...i.records]}}async function Wn(e){const t=e.document??document,r=e.window??window,n={url:e.url,readyTimeoutMs:e.readyTimeoutMs??5e3,settleMs:e.settleMs,allowSameOrigin:e.allowSameOrigin??!1},i=await Et(ot,n,t,r);let s=null;{const o=await Et([],n,t,r);s={bootError:o.bootError,emitted:o.emitted}}return{installedGlobal:i.installedGlobal,bootError:i.bootError,emitted:i.emitted,degraded:s}}var Zn=e=>({status:"pass",detail:e}),Vn=(e,t)=>({status:"fail",detail:e,diagnostics:t}),Kn=e=>({status:"skip",detail:e}),q={pass:Zn,fail:Vn,skip:Kn};function Yn(e,t){return ct(e.manifestEvent).errors.filter(r=>t.includes(r.code))}function je(e,t,r){return{id:e,area:"manifest",severity:"error",title:t,run:n=>{if(!n.manifestEvent)return q.skip("No NIP-5D manifest event was resolved");const i=Yn(n,r);return i.length?q.fail(i[0].message,i):q.pass()}}}var zn=[je("manifest/event-kind","Resolved event is a NIP-5D napplet manifest",["invalid-napplet-kind","missing-d-tag","unexpected-d-tag"]),je("manifest/index-html","Manifest declares a hashed /index.html",["missing-index-html","invalid-index-html-hash"]),je("manifest/requires","requires tags are bare known NAP domains",["invalid-required-nap","unknown-required-nap"]),{id:"boot/sandbox-allow-scripts",area:"boot",severity:"error",title:"Runs under allow-scripts without allow-same-origin",run:e=>e.sandbox.allowScripts?e.sandbox.allowSameOrigin?q.fail("Napplet relied on allow-same-origin, which a shell must not grant"):q.pass():q.fail("Napplet was not loaded with allow-scripts")},{id:"boot/installs-global",area:"boot",severity:"error",title:"Runs after runtime-injected window.napplet is installed",run:e=>e.installedGlobal?q.pass():q.fail("runtime did not inject window.napplet before load")},{id:"boot/no-boot-error",area:"boot",severity:"error",title:"Boots without an uncaught error",run:e=>e.bootError?q.fail(e.bootError):q.pass()},{id:"boot/no-forbidden-globals",area:"boot",severity:"error",title:"Does not access forbidden browser authority surfaces",run:e=>e.forbiddenGlobals.length?q.fail(`Accessed forbidden surface(s): ${e.forbiddenGlobals.join(", ")}`,e.forbiddenGlobals):q.pass()},{id:"wire/envelope-well-formed",area:"wire",severity:"error",title:"Every emitted envelope is well-formed",run:e=>{if(e.emitted.length===0)return q.skip("Napplet emitted no envelopes");const t=e.emitted.filter(n=>!n.verdict.ok);if(t.length===0)return q.pass(`${e.emitted.length} envelope(s) valid`);const r=t.map(n=>({envelope:n.envelope,errors:n.verdict.errors}));return q.fail(`${t.length}/${e.emitted.length} emitted envelope(s) invalid`,r)}},{id:"degrade/domain-absence",area:"degradation",severity:"error",title:"Does not crash when no NAP domains are injected",run:e=>e.degraded?e.degraded.bootError?q.fail(`Crashed with no injected domains: ${e.degraded.bootError}`):q.pass():q.skip("Host did not run the degraded (no-capabilities) pass")},{id:"lifecycle/clean-teardown",area:"lifecycle",severity:"warning",title:"Tears down listeners on unload",run:e=>e.lifecycle?e.lifecycle.listenerLeak?q.fail("Message listeners remained after unload"):q.pass():q.skip("Lifecycle not measured")}];function Gn(e,t={}){const r=t.now??(()=>Date.now()),n=t.checks??zn,i=r(),s=n.map(a=>{const l=a.run(e);return{id:a.id,area:a.area,severity:a.severity,title:a.title,status:l.status,detail:l.detail,diagnostics:l.diagnostics}}),o={total:s.length,passed:s.filter(a=>a.status==="pass").length,failed:s.filter(a=>a.status==="fail").length,skipped:s.filter(a=>a.status==="skip").length,errors:s.filter(a=>a.status==="fail"&&a.severity==="error").length,warnings:s.filter(a=>a.status==="fail"&&a.severity==="warning").length};return{napplet:e.manifestEvent?Wt(e.manifestEvent):void 0,startedAt:i,finishedAt:r(),checks:s,summary:o,ok:o.errors===0}}/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */function Xn(e){return e instanceof Uint8Array||ArrayBuffer.isView(e)&&e.constructor.name==="Uint8Array"}function lt(e,t=""){if(!Number.isSafeInteger(e)||e<0){const r=t&&`"${t}" `;throw new Error(`${r}expected integer >= 0, got ${e}`)}}function j(e,t,r=""){const n=Xn(e),i=e?.length,s=t!==void 0;if(!n||s&&i!==t){const o=r&&`"${r}" `,c=s?` of length ${t}`:"",a=n?`length=${i}`:`type=${typeof e}`;throw new Error(o+"expected Uint8Array"+c+", got "+a)}return e}function xt(e,t=!0){if(e.destroyed)throw new Error("Hash instance has been destroyed");if(t&&e.finished)throw new Error("Hash#digest() has already been called")}function Jn(e,t){j(e,void 0,"digestInto() output");const r=t.outputLen;if(e.length<r)throw new Error('"digestInto() output" expected to be of length >='+r)}function Xe(...e){for(let t=0;t<e.length;t++)e[t].fill(0)}function Me(e){return new DataView(e.buffer,e.byteOffset,e.byteLength)}function z(e,t){return e<<32-t|e>>>t}const Vt=typeof Uint8Array.from([]).toHex=="function"&&typeof Uint8Array.fromHex=="function",Qn=Array.from({length:256},(e,t)=>t.toString(16).padStart(2,"0"));function _(e){if(j(e),Vt)return e.toHex();let t="";for(let r=0;r<e.length;r++)t+=Qn[e[r]];return t}const J={_0:48,_9:57,A:65,F:70,a:97,f:102};function kt(e){if(e>=J._0&&e<=J._9)return e-J._0;if(e>=J.A&&e<=J.F)return e-(J.A-10);if(e>=J.a&&e<=J.f)return e-(J.a-10)}function X(e){if(typeof e!="string")throw new Error("hex string expected, got "+typeof e);if(Vt)return Uint8Array.fromHex(e);const t=e.length,r=t/2;if(t%2)throw new Error("hex string expected, got unpadded hex of length "+t);const n=new Uint8Array(r);for(let i=0,s=0;i<r;i++,s+=2){const o=kt(e.charCodeAt(s)),c=kt(e.charCodeAt(s+1));if(o===void 0||c===void 0){const a=e[s]+e[s+1];throw new Error('hex string expected, got non-hex character "'+a+'" at index '+s)}n[i]=o*16+c}return n}function Ae(...e){let t=0;for(let n=0;n<e.length;n++){const i=e[n];j(i),t+=i.length}const r=new Uint8Array(t);for(let n=0,i=0;n<e.length;n++){const s=e[n];r.set(s,i),i+=s.length}return r}function er(e,t={}){const r=(i,s)=>e(s).update(i).digest(),n=e(void 0);return r.outputLen=n.outputLen,r.blockLen=n.blockLen,r.create=i=>e(i),Object.assign(r,t),Object.freeze(r)}function Kt(e=32){const t=typeof globalThis=="object"?globalThis.crypto:null;if(typeof t?.getRandomValues!="function")throw new Error("crypto.getRandomValues must be defined");return t.getRandomValues(new Uint8Array(e))}const tr=e=>({oid:Uint8Array.from([6,9,96,134,72,1,101,3,4,2,e])});/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */function Yt(e){return e instanceof Uint8Array||ArrayBuffer.isView(e)&&e.constructor.name==="Uint8Array"}function zt(e,t){return Array.isArray(t)?t.length===0?!0:e?t.every(r=>typeof r=="string"):t.every(r=>Number.isSafeInteger(r)):!1}function nr(e){if(typeof e!="function")throw new Error("function expected");return!0}function ye(e,t){if(typeof t!="string")throw new Error(`${e}: string expected`);return!0}function Gt(e){if(!Number.isSafeInteger(e))throw new Error(`invalid integer: ${e}`)}function Je(e){if(!Array.isArray(e))throw new Error("array expected")}function Xt(e,t){if(!zt(!0,t))throw new Error(`${e}: array of strings expected`)}function Jt(e,t){if(!zt(!1,t))throw new Error(`${e}: array of numbers expected`)}function rr(...e){const t=s=>s,r=(s,o)=>c=>s(o(c)),n=e.map(s=>s.encode).reduceRight(r,t),i=e.map(s=>s.decode).reduce(r,t);return{encode:n,decode:i}}function ir(e){const t=typeof e=="string"?e.split(""):e,r=t.length;Xt("alphabet",t);const n=new Map(t.map((i,s)=>[i,s]));return{encode:i=>(Je(i),i.map(s=>{if(!Number.isSafeInteger(s)||s<0||s>=r)throw new Error(`alphabet.encode: digit index outside alphabet "${s}". Allowed: ${e}`);return t[s]})),decode:i=>(Je(i),i.map(s=>{ye("alphabet.decode",s);const o=n.get(s);if(o===void 0)throw new Error(`Unknown letter: "${s}". Allowed: ${e}`);return o}))}}function sr(e=""){return ye("join",e),{encode:t=>(Xt("join.decode",t),t.join(e)),decode:t=>(ye("join.decode",t),t.split(e))}}const Qt=(e,t)=>t===0?e:Qt(t,e%t),Oe=(e,t)=>e+(t-Qt(e,t)),Te=(()=>{let e=[];for(let t=0;t<40;t++)e.push(2**t);return e})();function Qe(e,t,r,n){if(Je(e),t<=0||t>32)throw new Error(`convertRadix2: wrong from=${t}`);if(r<=0||r>32)throw new Error(`convertRadix2: wrong to=${r}`);if(Oe(t,r)>32)throw new Error(`convertRadix2: carry overflow from=${t} to=${r} carryBits=${Oe(t,r)}`);let i=0,s=0;const o=Te[t],c=Te[r]-1,a=[];for(const l of e){if(Gt(l),l>=o)throw new Error(`convertRadix2: invalid data word=${l} from=${t}`);if(i=i<<t|l,s+t>32)throw new Error(`convertRadix2: carry overflow pos=${s} from=${t}`);for(s+=t;s>=r;s-=r)a.push((i>>s-r&c)>>>0);const g=Te[s];if(g===void 0)throw new Error("invalid carry");i&=g-1}if(i=i<<r-s&c,!n&&s>=t)throw new Error("Excess padding");if(!n&&i>0)throw new Error(`Non-zero padding: ${i}`);return n&&s>0&&a.push(i>>>0),a}function or(e,t=!1){if(Gt(e),e<=0||e>32)throw new Error("radix2: bits should be in (0..32]");if(Oe(8,e)>32||Oe(e,8)>32)throw new Error("radix2: carry overflow");return{encode:r=>{if(!Yt(r))throw new Error("radix2.encode input should be Uint8Array");return Qe(Array.from(r),8,e,!t)},decode:r=>(Jt("radix2.decode",r),Uint8Array.from(Qe(r,e,8,t)))}}function St(e){return nr(e),function(...t){try{return e.apply(null,t)}catch{}}}const et=rr(ir("qpzry9x8gf2tvdw0s3jn54khce6mua7l"),sr("")),Rt=[996825010,642813549,513874426,1027748829,705979059];function fe(e){const t=e>>25;let r=(e&33554431)<<5;for(let n=0;n<Rt.length;n++)(t>>n&1)===1&&(r^=Rt[n]);return r}function It(e,t,r=1){const n=e.length;let i=1;for(let s=0;s<n;s++){const o=e.charCodeAt(s);if(o<33||o>126)throw new Error(`Invalid prefix (${e})`);i=fe(i)^o>>5}i=fe(i);for(let s=0;s<n;s++)i=fe(i)^e.charCodeAt(s)&31;for(let s of t)i=fe(i)^s;for(let s=0;s<6;s++)i=fe(i);return i^=r,et.encode(Qe([i%Te[30]],30,5,!1))}function ar(e){const t=e==="bech32"?1:734539939,r=or(5),n=r.decode,i=r.encode,s=St(n);function o(u,f,p=90){ye("bech32.encode prefix",u),Yt(f)&&(f=Array.from(f)),Jt("bech32.encode",f);const y=u.length;if(y===0)throw new TypeError(`Invalid prefix length ${y}`);const w=y+7+f.length;if(p!==!1&&w>p)throw new TypeError(`Length ${w} exceeds limit ${p}`);const $=u.toLowerCase(),N=It($,f,t);return`${$}1${et.encode(f)}${N}`}function c(u,f=90){ye("bech32.decode input",u);const p=u.length;if(p<8||f!==!1&&p>f)throw new TypeError(`invalid string length: ${p} (${u}). Expected (8..${f})`);const y=u.toLowerCase();if(u!==y&&u!==u.toUpperCase())throw new Error("String must be lowercase or uppercase");const w=y.lastIndexOf("1");if(w===0||w===-1)throw new Error('Letter "1" must be present between prefix and data only');const $=y.slice(0,w),N=y.slice(w+1);if(N.length<6)throw new Error("Data must be at least 6 characters long");const K=et.decode(N).slice(0,-6),Q=It($,K,t);if(!N.endsWith(Q))throw new Error(`Invalid checksum in ${u}: expected "${Q}"`);return{prefix:$,words:K}}const a=St(c);function l(u){const{prefix:f,words:p}=c(u,!1);return{prefix:f,words:p,bytes:n(p)}}function g(u,f){return o(u,i(f))}return{encode:o,decode:c,encodeFromBytes:g,decodeToBytes:l,decodeUnsafe:a,fromWords:n,fromWordsUnsafe:s,toWords:i}}const $t=ar("bech32");var Re=new TextDecoder("utf-8");new TextEncoder;var cr=5e3;function lr(e){try{return e.startsWith("nostr:")&&(e=e.substring(6)),dr(e)}catch{return{type:"invalid",data:null}}}function dr(e){let{prefix:t,words:r}=$t.decode(e,cr),n=new Uint8Array($t.fromWords(r));switch(t){case"nprofile":{let i=Fe(n);if(!i[0]?.[0])throw new Error("missing TLV 0 for nprofile");if(i[0][0].length!==32)throw new Error("TLV 0 should be 32 bytes");return{type:"nprofile",data:{pubkey:_(i[0][0]),relays:i[1]?i[1].map(s=>Re.decode(s)):[]}}}case"nevent":{let i=Fe(n);if(!i[0]?.[0])throw new Error("missing TLV 0 for nevent");if(i[0][0].length!==32)throw new Error("TLV 0 should be 32 bytes");if(i[2]&&i[2][0].length!==32)throw new Error("TLV 2 should be 32 bytes");if(i[3]&&i[3][0].length!==4)throw new Error("TLV 3 should be 4 bytes");return{type:"nevent",data:{id:_(i[0][0]),relays:i[1]?i[1].map(s=>Re.decode(s)):[],author:i[2]?.[0]?_(i[2][0]):void 0,kind:i[3]?.[0]?parseInt(_(i[3][0]),16):void 0}}}case"naddr":{let i=Fe(n);if(!i[0]?.[0])throw new Error("missing TLV 0 for naddr");if(!i[2]?.[0])throw new Error("missing TLV 2 for naddr");if(i[2][0].length!==32)throw new Error("TLV 2 should be 32 bytes");if(!i[3]?.[0])throw new Error("missing TLV 3 for naddr");if(i[3][0].length!==4)throw new Error("TLV 3 should be 4 bytes");return{type:"naddr",data:{identifier:Re.decode(i[0][0]),pubkey:_(i[2][0]),kind:parseInt(_(i[3][0]),16),relays:i[1]?i[1].map(s=>Re.decode(s)):[]}}}case"nsec":return{type:t,data:n};case"npub":case"note":return{type:t,data:_(n)};default:throw new Error(`unknown prefix ${t}`)}}function Fe(e){let t={},r=e;for(;r.length>0;){let n=r[0],i=r[1],s=r.slice(2,2+i);if(r=r.slice(2+i),s.length<i)throw new Error(`not enough data to read on TLV ${n}`);t[n]=t[n]||[],t[n].push(s)}return t}function ur(e,t,r){return e&t^~e&r}function fr(e,t,r){return e&t^e&r^t&r}class hr{blockLen;outputLen;padOffset;isLE;buffer;view;finished=!1;length=0;pos=0;destroyed=!1;constructor(t,r,n,i){this.blockLen=t,this.outputLen=r,this.padOffset=n,this.isLE=i,this.buffer=new Uint8Array(t),this.view=Me(this.buffer)}update(t){xt(this),j(t);const{view:r,buffer:n,blockLen:i}=this,s=t.length;for(let o=0;o<s;){const c=Math.min(i-this.pos,s-o);if(c===i){const a=Me(t);for(;i<=s-o;o+=i)this.process(a,o);continue}n.set(t.subarray(o,o+c),this.pos),this.pos+=c,o+=c,this.pos===i&&(this.process(r,0),this.pos=0)}return this.length+=t.length,this.roundClean(),this}digestInto(t){xt(this),Jn(t,this),this.finished=!0;const{buffer:r,view:n,blockLen:i,isLE:s}=this;let{pos:o}=this;r[o++]=128,Xe(this.buffer.subarray(o)),this.padOffset>i-o&&(this.process(n,0),o=0);for(let u=o;u<i;u++)r[u]=0;n.setBigUint64(i-8,BigInt(this.length*8),s),this.process(n,0);const c=Me(t),a=this.outputLen;if(a%4)throw new Error("_sha2: outputLen must be aligned to 32bit");const l=a/4,g=this.get();if(l>g.length)throw new Error("_sha2: outputLen bigger than state");for(let u=0;u<l;u++)c.setUint32(4*u,g[u],s)}digest(){const{buffer:t,outputLen:r}=this;this.digestInto(t);const n=t.slice(0,r);return this.destroy(),n}_cloneInto(t){t||=new this.constructor,t.set(...this.get());const{blockLen:r,buffer:n,length:i,finished:s,destroyed:o,pos:c}=this;return t.destroyed=o,t.finished=s,t.length=i,t.pos=c,i%r&&t.buffer.set(n),t}clone(){return this._cloneInto()}}const ee=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),pr=Uint32Array.from([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),te=new Uint32Array(64);class gr extends hr{constructor(t){super(64,t,8,!1)}get(){const{A:t,B:r,C:n,D:i,E:s,F:o,G:c,H:a}=this;return[t,r,n,i,s,o,c,a]}set(t,r,n,i,s,o,c,a){this.A=t|0,this.B=r|0,this.C=n|0,this.D=i|0,this.E=s|0,this.F=o|0,this.G=c|0,this.H=a|0}process(t,r){for(let u=0;u<16;u++,r+=4)te[u]=t.getUint32(r,!1);for(let u=16;u<64;u++){const f=te[u-15],p=te[u-2],y=z(f,7)^z(f,18)^f>>>3,w=z(p,17)^z(p,19)^p>>>10;te[u]=w+te[u-7]+y+te[u-16]|0}let{A:n,B:i,C:s,D:o,E:c,F:a,G:l,H:g}=this;for(let u=0;u<64;u++){const f=z(c,6)^z(c,11)^z(c,25),p=g+f+ur(c,a,l)+pr[u]+te[u]|0,w=(z(n,2)^z(n,13)^z(n,22))+fr(n,i,s)|0;g=l,l=a,a=c,c=o+p|0,o=s,s=i,i=n,n=p+w|0}n=n+this.A|0,i=i+this.B|0,s=s+this.C|0,o=o+this.D|0,c=c+this.E|0,a=a+this.F|0,l=l+this.G|0,g=g+this.H|0,this.set(n,i,s,o,c,a,l,g)}roundClean(){Xe(te)}destroy(){this.set(0,0,0,0,0,0,0,0),Xe(this.buffer)}}class mr extends gr{A=ee[0]|0;B=ee[1]|0;C=ee[2]|0;D=ee[3]|0;E=ee[4]|0;F=ee[5]|0;G=ee[6]|0;H=ee[7]|0;constructor(){super(32)}}const Ne=er(()=>new mr,tr(1));/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */const dt=BigInt(0),tt=BigInt(1);function Tt(e,t=""){if(typeof e!="boolean"){const r=t&&`"${t}" `;throw new Error(r+"expected boolean, got type="+typeof e)}return e}function yr(e){if(typeof e=="bigint"){if(!vr(e))throw new Error("positive bigint expected, got "+e)}else lt(e);return e}function en(e){if(typeof e!="string")throw new Error("hex string expected, got "+typeof e);return e===""?dt:BigInt("0x"+e)}function ut(e){return en(_(e))}function tn(e){return en(_(br(j(e)).reverse()))}function ft(e,t){lt(t),e=yr(e);const r=X(e.toString(16).padStart(t*2,"0"));if(r.length!==t)throw new Error("number too large");return r}function nn(e,t){return ft(e,t).reverse()}function br(e){return Uint8Array.from(e)}function wr(e){return Uint8Array.from(e,(t,r)=>{const n=t.charCodeAt(0);if(t.length!==1||n>127)throw new Error(`string contains non-ASCII character "${e[r]}" with code ${n} at position ${r}`);return n})}const vr=e=>typeof e=="bigint"&&dt<=e;function Er(e){let t;for(t=0;e>dt;e>>=tt,t+=1);return t}const rn=e=>(tt<<BigInt(e))-tt;function sn(e,t={},r={}){if(!e||typeof e!="object")throw new Error("expected valid options object");function n(s,o,c){const a=e[s];if(c&&a===void 0)return;const l=typeof a;if(l!==o||a===null)throw new Error(`param "${s}" is invalid: expected ${o}, got ${l}`)}const i=(s,o)=>Object.entries(s).forEach(([c,a])=>n(c,a,o));i(t,!1),i(r,!0)}function Bt(e){const t=new WeakMap;return(r,...n)=>{const i=t.get(r);if(i!==void 0)return i;const s=e(r,...n);return t.set(r,s),s}}/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */const D=BigInt(0),H=BigInt(1),se=BigInt(2),on=BigInt(3),an=BigInt(4),cn=BigInt(5),xr=BigInt(7),ln=BigInt(8),kr=BigInt(9),dn=BigInt(16);function V(e,t){const r=e%t;return r>=D?r:t+r}function F(e,t,r){let n=e;for(;t-- >D;)n*=n,n%=r;return n}function At(e,t){if(e===D)throw new Error("invert: expected non-zero number");if(t<=D)throw new Error("invert: expected positive modulus, got "+t);let r=V(e,t),n=t,i=D,s=H;for(;r!==D;){const c=n/r,a=n%r,l=i-s*c;n=r,r=a,i=s,s=l}if(n!==H)throw new Error("invert: does not exist");return V(i,t)}function ht(e,t,r){if(!e.eql(e.sqr(t),r))throw new Error("Cannot find square root")}function un(e,t){const r=(e.ORDER+H)/an,n=e.pow(t,r);return ht(e,n,t),n}function Sr(e,t){const r=(e.ORDER-cn)/ln,n=e.mul(t,se),i=e.pow(n,r),s=e.mul(t,i),o=e.mul(e.mul(s,se),i),c=e.mul(s,e.sub(o,e.ONE));return ht(e,c,t),c}function Rr(e){const t=_e(e),r=fn(e),n=r(t,t.neg(t.ONE)),i=r(t,n),s=r(t,t.neg(n)),o=(e+xr)/dn;return(c,a)=>{let l=c.pow(a,o),g=c.mul(l,n);const u=c.mul(l,i),f=c.mul(l,s),p=c.eql(c.sqr(g),a),y=c.eql(c.sqr(u),a);l=c.cmov(l,g,p),g=c.cmov(f,u,y);const w=c.eql(c.sqr(g),a),$=c.cmov(l,g,w);return ht(c,$,a),$}}function fn(e){if(e<on)throw new Error("sqrt is not defined for small field");let t=e-H,r=0;for(;t%se===D;)t/=se,r++;let n=se;const i=_e(e);for(;Ot(i,n)===1;)if(n++>1e3)throw new Error("Cannot find square root: probably non-prime P");if(r===1)return un;let s=i.pow(n,t);const o=(t+H)/se;return function(a,l){if(a.is0(l))return l;if(Ot(a,l)!==1)throw new Error("Cannot find square root");let g=r,u=a.mul(a.ONE,s),f=a.pow(l,t),p=a.pow(l,o);for(;!a.eql(f,a.ONE);){if(a.is0(f))return a.ZERO;let y=1,w=a.sqr(f);for(;!a.eql(w,a.ONE);)if(y++,w=a.sqr(w),y===g)throw new Error("Cannot find square root");const $=H<<BigInt(g-y-1),N=a.pow(u,$);g=y,u=a.sqr(N),f=a.mul(f,u),p=a.mul(p,N)}return p}}function Ir(e){return e%an===on?un:e%ln===cn?Sr:e%dn===kr?Rr(e):fn(e)}const $r=["create","isValid","is0","neg","inv","sqrt","sqr","eql","add","sub","mul","pow","div","addN","subN","mulN","sqrN"];function Tr(e){const t={ORDER:"bigint",BYTES:"number",BITS:"number"},r=$r.reduce((n,i)=>(n[i]="function",n),t);return sn(e,r),e}function Br(e,t,r){if(r<D)throw new Error("invalid exponent, negatives unsupported");if(r===D)return e.ONE;if(r===H)return t;let n=e.ONE,i=t;for(;r>D;)r&H&&(n=e.mul(n,i)),i=e.sqr(i),r>>=H;return n}function hn(e,t,r=!1){const n=new Array(t.length).fill(r?e.ZERO:void 0),i=t.reduce((o,c,a)=>e.is0(c)?o:(n[a]=o,e.mul(o,c)),e.ONE),s=e.inv(i);return t.reduceRight((o,c,a)=>e.is0(c)?o:(n[a]=e.mul(o,n[a]),e.mul(o,c)),s),n}function Ot(e,t){const r=(e.ORDER-H)/se,n=e.pow(t,r),i=e.eql(n,e.ONE),s=e.eql(n,e.ZERO),o=e.eql(n,e.neg(e.ONE));if(!i&&!s&&!o)throw new Error("invalid Legendre symbol result");return i?1:s?0:-1}function Ar(e,t){t!==void 0&<(t);const r=t!==void 0?t:e.toString(2).length,n=Math.ceil(r/8);return{nBitLength:r,nByteLength:n}}class Or{ORDER;BITS;BYTES;isLE;ZERO=D;ONE=H;_lengths;_sqrt;_mod;constructor(t,r={}){if(t<=D)throw new Error("invalid field: expected ORDER > 0, got "+t);let n;this.isLE=!1,r!=null&&typeof r=="object"&&(typeof r.BITS=="number"&&(n=r.BITS),typeof r.sqrt=="function"&&(this.sqrt=r.sqrt),typeof r.isLE=="boolean"&&(this.isLE=r.isLE),r.allowedLengths&&(this._lengths=r.allowedLengths?.slice()),typeof r.modFromBytes=="boolean"&&(this._mod=r.modFromBytes));const{nBitLength:i,nByteLength:s}=Ar(t,n);if(s>2048)throw new Error("invalid field: expected ORDER of <= 2048 bytes");this.ORDER=t,this.BITS=i,this.BYTES=s,this._sqrt=void 0,Object.preventExtensions(this)}create(t){return V(t,this.ORDER)}isValid(t){if(typeof t!="bigint")throw new Error("invalid field element: expected bigint, got "+typeof t);return D<=t&&t<this.ORDER}is0(t){return t===D}isValidNot0(t){return!this.is0(t)&&this.isValid(t)}isOdd(t){return(t&H)===H}neg(t){return V(-t,this.ORDER)}eql(t,r){return t===r}sqr(t){return V(t*t,this.ORDER)}add(t,r){return V(t+r,this.ORDER)}sub(t,r){return V(t-r,this.ORDER)}mul(t,r){return V(t*r,this.ORDER)}pow(t,r){return Br(this,t,r)}div(t,r){return V(t*At(r,this.ORDER),this.ORDER)}sqrN(t){return t*t}addN(t,r){return t+r}subN(t,r){return t-r}mulN(t,r){return t*r}inv(t){return At(t,this.ORDER)}sqrt(t){return this._sqrt||(this._sqrt=Ir(this.ORDER)),this._sqrt(this,t)}toBytes(t){return this.isLE?nn(t,this.BYTES):ft(t,this.BYTES)}fromBytes(t,r=!1){j(t);const{_lengths:n,BYTES:i,isLE:s,ORDER:o,_mod:c}=this;if(n){if(!n.includes(t.length)||t.length>i)throw new Error("Field.fromBytes: expected "+n+" bytes, got "+t.length);const l=new Uint8Array(i);l.set(t,s?0:l.length-t.length),t=l}if(t.length!==i)throw new Error("Field.fromBytes: expected "+i+" bytes, got "+t.length);let a=s?tn(t):ut(t);if(c&&(a=V(a,o)),!r&&!this.isValid(a))throw new Error("invalid field element: outside of range 0..ORDER");return a}invertBatch(t){return hn(this,t)}cmov(t,r,n){return n?r:t}}function _e(e,t={}){return new Or(e,t)}function pn(e){if(typeof e!="bigint")throw new Error("field order must be bigint");const t=e.toString(2).length;return Math.ceil(t/8)}function Nr(e){const t=pn(e);return t+Math.ceil(t/2)}function qr(e,t,r=!1){j(e);const n=e.length,i=pn(t),s=Nr(t);if(n<16||n<s||n>1024)throw new Error("expected "+s+"-1024 bytes of input, got "+n);const o=r?tn(e):ut(e),c=V(o,t-H)+H;return r?nn(c,i):ft(c,i)}/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */const le=BigInt(0),oe=BigInt(1);function qe(e,t){const r=t.negate();return e?r:t}function Nt(e,t){const r=hn(e.Fp,t.map(n=>n.Z));return t.map((n,i)=>e.fromAffine(n.toAffine(r[i])))}function gn(e,t){if(!Number.isSafeInteger(e)||e<=0||e>t)throw new Error("invalid window size, expected [1.."+t+"], got W="+e)}function We(e,t){gn(e,t);const r=Math.ceil(t/e)+1,n=2**(e-1),i=2**e,s=rn(e),o=BigInt(e);return{windows:r,windowSize:n,mask:s,maxNumber:i,shiftBy:o}}function qt(e,t,r){const{windowSize:n,mask:i,maxNumber:s,shiftBy:o}=r;let c=Number(e&i),a=e>>o;c>n&&(c-=s,a+=oe);const l=t*n,g=l+Math.abs(c)-1,u=c===0,f=c<0,p=t%2!==0;return{nextN:a,offset:g,isZero:u,isNeg:f,isNegF:p,offsetF:l}}const Ze=new WeakMap,mn=new WeakMap;function Ve(e){return mn.get(e)||1}function Lt(e){if(e!==le)throw new Error("invalid wNAF")}class Lr{BASE;ZERO;Fn;bits;constructor(t,r){this.BASE=t.BASE,this.ZERO=t.ZERO,this.Fn=t.Fn,this.bits=r}_unsafeLadder(t,r,n=this.ZERO){let i=t;for(;r>le;)r&oe&&(n=n.add(i)),i=i.double(),r>>=oe;return n}precomputeWindow(t,r){const{windows:n,windowSize:i}=We(r,this.bits),s=[];let o=t,c=o;for(let a=0;a<n;a++){c=o,s.push(c);for(let l=1;l<i;l++)c=c.add(o),s.push(c);o=c.double()}return s}wNAF(t,r,n){if(!this.Fn.isValid(n))throw new Error("invalid scalar");let i=this.ZERO,s=this.BASE;const o=We(t,this.bits);for(let c=0;c<o.windows;c++){const{nextN:a,offset:l,isZero:g,isNeg:u,isNegF:f,offsetF:p}=qt(n,c,o);n=a,g?s=s.add(qe(f,r[p])):i=i.add(qe(u,r[l]))}return Lt(n),{p:i,f:s}}wNAFUnsafe(t,r,n,i=this.ZERO){const s=We(t,this.bits);for(let o=0;o<s.windows&&n!==le;o++){const{nextN:c,offset:a,isZero:l,isNeg:g}=qt(n,o,s);if(n=c,!l){const u=r[a];i=i.add(g?u.negate():u)}}return Lt(n),i}getPrecomputes(t,r,n){let i=Ze.get(r);return i||(i=this.precomputeWindow(r,t),t!==1&&(typeof n=="function"&&(i=n(i)),Ze.set(r,i))),i}cached(t,r,n){const i=Ve(t);return this.wNAF(i,this.getPrecomputes(i,t,n),r)}unsafe(t,r,n,i){const s=Ve(t);return s===1?this._unsafeLadder(t,r,i):this.wNAFUnsafe(s,this.getPrecomputes(s,t,n),r,i)}createCache(t,r){gn(r,this.bits),mn.set(t,r),Ze.delete(t)}hasCache(t){return Ve(t)!==1}}function Pr(e,t,r,n){let i=t,s=e.ZERO,o=e.ZERO;for(;r>le||n>le;)r&oe&&(s=s.add(i)),n&oe&&(o=o.add(i)),i=i.double(),r>>=oe,n>>=oe;return{p1:s,p2:o}}function Pt(e,t,r){if(t){if(t.ORDER!==e)throw new Error("Field.ORDER must match order: Fp == p, Fn == n");return Tr(t),t}else return _e(e,{isLE:r})}function _r(e,t,r={},n){if(n===void 0&&(n=e==="edwards"),!t||typeof t!="object")throw new Error(`expected valid ${e} CURVE object`);for(const a of["p","n","h"]){const l=t[a];if(!(typeof l=="bigint"&&l>le))throw new Error(`CURVE.${a} must be positive bigint`)}const i=Pt(t.p,r.Fp,n),s=Pt(t.n,r.Fn,n),c=["Gx","Gy","a","b"];for(const a of c)if(!i.isValid(t[a]))throw new Error(`CURVE.${a} must be valid field element of CURVE.Fp`);return t=Object.freeze(Object.assign({},t)),{CURVE:t,Fp:i,Fn:s}}function Cr(e,t){return function(n){const i=e(n);return{secretKey:i,publicKey:t(i)}}}/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */const _t=(e,t)=>(e+(e>=0?t:-t)/Hr)/t;function Ur(e,t,r){const[[n,i],[s,o]]=t,c=_t(o*e,r),a=_t(-i*e,r);let l=e-c*n-a*s,g=-c*i-a*o;const u=l<he,f=g<he;u&&(l=-l),f&&(g=-g);const p=rn(Math.ceil(Er(r)/2))+Be;if(l<he||l>=p||g<he||g>=p)throw new Error("splitScalar (endomorphism): failed, k="+e);return{k1neg:u,k1:l,k2neg:f,k2:g}}const he=BigInt(0),Be=BigInt(1),Hr=BigInt(2),Ie=BigInt(3),Dr=BigInt(4);function jr(e,t={}){const r=_r("weierstrass",e,t),{Fp:n,Fn:i}=r;let s=r.CURVE;const{h:o,n:c}=s;sn(t,{},{allowInfinityPoint:"boolean",clearCofactor:"function",isTorsionFree:"function",fromBytes:"function",toBytes:"function",endo:"object"});const{endo:a}=t;if(a&&(!n.is0(s.a)||typeof a.beta!="bigint"||!Array.isArray(a.basises)))throw new Error('invalid endo: expected "beta": bigint and "basises": array');const l=Fr(n,i);function g(){if(!n.isOdd)throw new Error("compression is not supported: Field does not have .isOdd()")}function u(T,m,b){const{x:E,y:x}=m.toAffine(),B=n.toBytes(E);if(Tt(b,"isCompressed"),b){g();const R=!n.isOdd(x);return Ae(Mr(R),B)}else return Ae(Uint8Array.of(4),B,n.toBytes(x))}function f(T){j(T,void 0,"Point");const{publicKey:m,publicKeyUncompressed:b}=l,E=T.length,x=T[0],B=T.subarray(1);if(E===m&&(x===2||x===3)){const R=n.fromBytes(B);if(!n.isValid(R))throw new Error("bad point: is not on curve, wrong x");const k=w(R);let v;try{v=n.sqrt(k)}catch(M){const P=M instanceof Error?": "+M.message:"";throw new Error("bad point: is not on curve, sqrt error"+P)}g();const S=n.isOdd(v);return(x&1)===1!==S&&(v=n.neg(v)),{x:R,y:v}}else if(E===b&&x===4){const R=n.BYTES,k=n.fromBytes(B.subarray(0,R)),v=n.fromBytes(B.subarray(R,R*2));if(!$(k,v))throw new Error("bad point: is not on curve");return{x:k,y:v}}else throw new Error(`bad point: got length ${E}, expected compressed=${m} or uncompressed=${b}`)}const p=t.toBytes||u,y=t.fromBytes||f;function w(T){const m=n.sqr(T),b=n.mul(m,T);return n.add(n.add(b,n.mul(T,s.a)),s.b)}function $(T,m){const b=n.sqr(m),E=w(T);return n.eql(b,E)}if(!$(s.Gx,s.Gy))throw new Error("bad curve params: generator point");const N=n.mul(n.pow(s.a,Ie),Dr),K=n.mul(n.sqr(s.b),BigInt(27));if(n.is0(n.add(N,K)))throw new Error("bad curve params: a or b");function Q(T,m,b=!1){if(!n.isValid(m)||b&&n.is0(m))throw new Error(`bad point coordinate ${T}`);return m}function we(T){if(!(T instanceof O))throw new Error("Weierstrass Point expected")}function ve(T){if(!a||!a.basises)throw new Error("no endo");return Ur(T,a.basises,i.ORDER)}const Ee=Bt((T,m)=>{const{X:b,Y:E,Z:x}=T;if(n.eql(x,n.ONE))return{x:b,y:E};const B=T.is0();m==null&&(m=B?n.ONE:n.inv(x));const R=n.mul(b,m),k=n.mul(E,m),v=n.mul(x,m);if(B)return{x:n.ZERO,y:n.ZERO};if(!n.eql(v,n.ONE))throw new Error("invZ was invalid");return{x:R,y:k}}),Rn=Bt(T=>{if(T.is0()){if(t.allowInfinityPoint&&!n.is0(T.Y))return;throw new Error("bad point: ZERO")}const{x:m,y:b}=T.toAffine();if(!n.isValid(m)||!n.isValid(b))throw new Error("bad point: x or y not field elements");if(!$(m,b))throw new Error("bad point: equation left != right");if(!T.isTorsionFree())throw new Error("bad point: not in prime-order subgroup");return!0});function mt(T,m,b,E,x){return b=new O(n.mul(b.X,T),b.Y,b.Z),m=qe(E,m),b=qe(x,b),m.add(b)}class O{static BASE=new O(s.Gx,s.Gy,n.ONE);static ZERO=new O(n.ZERO,n.ONE,n.ZERO);static Fp=n;static Fn=i;X;Y;Z;constructor(m,b,E){this.X=Q("x",m),this.Y=Q("y",b,!0),this.Z=Q("z",E),Object.freeze(this)}static CURVE(){return s}static fromAffine(m){const{x:b,y:E}=m||{};if(!m||!n.isValid(b)||!n.isValid(E))throw new Error("invalid affine point");if(m instanceof O)throw new Error("projective point not allowed");return n.is0(b)&&n.is0(E)?O.ZERO:new O(b,E,n.ONE)}static fromBytes(m){const b=O.fromAffine(y(j(m,void 0,"point")));return b.assertValidity(),b}static fromHex(m){return O.fromBytes(X(m))}get x(){return this.toAffine().x}get y(){return this.toAffine().y}precompute(m=8,b=!0){return ue.createCache(this,m),b||this.multiply(Ie),this}assertValidity(){Rn(this)}hasEvenY(){const{y:m}=this.toAffine();if(!n.isOdd)throw new Error("Field doesn't support isOdd");return!n.isOdd(m)}equals(m){we(m);const{X:b,Y:E,Z:x}=this,{X:B,Y:R,Z:k}=m,v=n.eql(n.mul(b,k),n.mul(B,x)),S=n.eql(n.mul(E,k),n.mul(R,x));return v&&S}negate(){return new O(this.X,n.neg(this.Y),this.Z)}double(){const{a:m,b}=s,E=n.mul(b,Ie),{X:x,Y:B,Z:R}=this;let k=n.ZERO,v=n.ZERO,S=n.ZERO,I=n.mul(x,x),M=n.mul(B,B),P=n.mul(R,R),A=n.mul(x,B);return A=n.add(A,A),S=n.mul(x,R),S=n.add(S,S),k=n.mul(m,S),v=n.mul(E,P),v=n.add(k,v),k=n.sub(M,v),v=n.add(M,v),v=n.mul(k,v),k=n.mul(A,k),S=n.mul(E,S),P=n.mul(m,P),A=n.sub(I,P),A=n.mul(m,A),A=n.add(A,S),S=n.add(I,I),I=n.add(S,I),I=n.add(I,P),I=n.mul(I,A),v=n.add(v,I),P=n.mul(B,R),P=n.add(P,P),I=n.mul(P,A),k=n.sub(k,I),S=n.mul(P,M),S=n.add(S,S),S=n.add(S,S),new O(k,v,S)}add(m){we(m);const{X:b,Y:E,Z:x}=this,{X:B,Y:R,Z:k}=m;let v=n.ZERO,S=n.ZERO,I=n.ZERO;const M=s.a,P=n.mul(s.b,Ie);let A=n.mul(b,B),W=n.mul(E,R),Z=n.mul(x,k),ae=n.add(b,E),U=n.add(B,R);ae=n.mul(ae,U),U=n.add(A,W),ae=n.sub(ae,U),U=n.add(b,x);let Y=n.add(B,k);return U=n.mul(U,Y),Y=n.add(A,Z),U=n.sub(U,Y),Y=n.add(E,x),v=n.add(R,k),Y=n.mul(Y,v),v=n.add(W,Z),Y=n.sub(Y,v),I=n.mul(M,U),v=n.mul(P,Z),I=n.add(v,I),v=n.sub(W,I),I=n.add(W,I),S=n.mul(v,I),W=n.add(A,A),W=n.add(W,A),Z=n.mul(M,Z),U=n.mul(P,U),W=n.add(W,Z),Z=n.sub(A,Z),Z=n.mul(M,Z),U=n.add(U,Z),A=n.mul(W,U),S=n.add(S,A),A=n.mul(Y,U),v=n.mul(ae,v),v=n.sub(v,A),A=n.mul(ae,W),I=n.mul(Y,I),I=n.add(I,A),new O(v,S,I)}subtract(m){return this.add(m.negate())}is0(){return this.equals(O.ZERO)}multiply(m){const{endo:b}=t;if(!i.isValidNot0(m))throw new Error("invalid scalar: out of range");let E,x;const B=R=>ue.cached(this,R,k=>Nt(O,k));if(b){const{k1neg:R,k1:k,k2neg:v,k2:S}=ve(m),{p:I,f:M}=B(k),{p:P,f:A}=B(S);x=M.add(A),E=mt(b.beta,I,P,R,v)}else{const{p:R,f:k}=B(m);E=R,x=k}return Nt(O,[E,x])[0]}multiplyUnsafe(m){const{endo:b}=t,E=this;if(!i.isValid(m))throw new Error("invalid scalar: out of range");if(m===he||E.is0())return O.ZERO;if(m===Be)return E;if(ue.hasCache(this))return this.multiply(m);if(b){const{k1neg:x,k1:B,k2neg:R,k2:k}=ve(m),{p1:v,p2:S}=Pr(O,E,B,k);return mt(b.beta,v,S,x,R)}else return ue.unsafe(E,m)}toAffine(m){return Ee(this,m)}isTorsionFree(){const{isTorsionFree:m}=t;return o===Be?!0:m?m(O,this):ue.unsafe(this,c).is0()}clearCofactor(){const{clearCofactor:m}=t;return o===Be?this:m?m(O,this):this.multiplyUnsafe(o)}isSmallOrder(){return this.multiplyUnsafe(o).is0()}toBytes(m=!0){return Tt(m,"isCompressed"),this.assertValidity(),p(O,this,m)}toHex(m=!0){return _(this.toBytes(m))}toString(){return`<Point ${this.is0()?"ZERO":this.toHex()}>`}}const yt=i.BITS,ue=new Lr(O,t.endo?Math.ceil(yt/2):yt);return O.BASE.precompute(8),O}function Mr(e){return Uint8Array.of(e?2:3)}function Fr(e,t){return{secretKey:t.BYTES,publicKey:1+e.BYTES,publicKeyUncompressed:1+2*e.BYTES,publicKeyHasPrefix:!0,signature:2*t.BYTES}}/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */const Ce={p:BigInt("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"),n:BigInt("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"),h:BigInt(1),a:BigInt(0),b:BigInt(7),Gx:BigInt("0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"),Gy:BigInt("0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8")},Wr={beta:BigInt("0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee"),basises:[[BigInt("0x3086d221a7d46bcde86c90e49284eb15"),-BigInt("0xe4437ed6010e88286f547fa90abfe4c3")],[BigInt("0x114ca50f7a8e2f3f657c1108d9d44cfd8"),BigInt("0x3086d221a7d46bcde86c90e49284eb15")]]},Zr=BigInt(0),nt=BigInt(2);function Vr(e){const t=Ce.p,r=BigInt(3),n=BigInt(6),i=BigInt(11),s=BigInt(22),o=BigInt(23),c=BigInt(44),a=BigInt(88),l=e*e*e%t,g=l*l*e%t,u=F(g,r,t)*g%t,f=F(u,r,t)*g%t,p=F(f,nt,t)*l%t,y=F(p,i,t)*p%t,w=F(y,s,t)*y%t,$=F(w,c,t)*w%t,N=F($,a,t)*$%t,K=F(N,c,t)*w%t,Q=F(K,r,t)*g%t,we=F(Q,o,t)*y%t,ve=F(we,n,t)*l%t,Ee=F(ve,nt,t);if(!Le.eql(Le.sqr(Ee),e))throw new Error("Cannot find square root");return Ee}const Le=_e(Ce.p,{sqrt:Vr}),de=jr(Ce,{Fp:Le,endo:Wr}),Ct={};function Pe(e,...t){let r=Ct[e];if(r===void 0){const n=Ne(wr(e));r=Ae(n,n),Ct[e]=r}return Ne(Ae(r,...t))}const pt=e=>e.toBytes(!0).slice(1),gt=e=>e%nt===Zr;function rt(e){const{Fn:t,BASE:r}=de,n=t.fromBytes(e),i=r.multiply(n);return{scalar:gt(i.y)?n:t.neg(n),bytes:pt(i)}}function yn(e){const t=Le;if(!t.isValidNot0(e))throw new Error("invalid x: Fail if x ≥ p");const r=t.create(e*e),n=t.create(r*e+BigInt(7));let i=t.sqrt(n);gt(i)||(i=t.neg(i));const s=de.fromAffine({x:e,y:i});return s.assertValidity(),s}const me=ut;function bn(...e){return de.Fn.create(me(Pe("BIP0340/challenge",...e)))}function Ut(e){return rt(e).bytes}function Kr(e,t,r=Kt(32)){const{Fn:n}=de,i=j(e,void 0,"message"),{bytes:s,scalar:o}=rt(t),c=j(r,32,"auxRand"),a=n.toBytes(o^me(Pe("BIP0340/aux",c))),l=Pe("BIP0340/nonce",a,s,i),{bytes:g,scalar:u}=rt(l),f=bn(g,s,i),p=new Uint8Array(64);if(p.set(g,0),p.set(n.toBytes(n.create(u+f*o)),32),!wn(p,i,s))throw new Error("sign: Invalid signature produced");return p}function wn(e,t,r){const{Fp:n,Fn:i,BASE:s}=de,o=j(e,64,"signature"),c=j(t,void 0,"message"),a=j(r,32,"publicKey");try{const l=yn(me(a)),g=me(o.subarray(0,32));if(!n.isValidNot0(g))return!1;const u=me(o.subarray(32,64));if(!i.isValidNot0(u))return!1;const f=bn(i.toBytes(g),pt(l),c),p=s.multiplyUnsafe(u).add(l.multiplyUnsafe(i.neg(f))),{x:y,y:w}=p.toAffine();return!(p.is0()||!gt(w)||y!==g)}catch{return!1}}const G=(()=>{const r=(n=Kt(48))=>qr(n,Ce.n);return{keygen:Cr(r,Ut),getPublicKey:Ut,sign:Kr,verify:wn,Point:de,utils:{randomSecretKey:r,taggedHash:Pe,lift_x:yn,pointToBytes:pt},lengths:{secretKey:32,publicKey:32,publicKeyHasPrefix:!1,signature:64,seed:48}}})();var ie=Symbol("verified"),Yr=e=>e instanceof Object;function zr(e){if(!Yr(e)||typeof e.kind!="number"||typeof e.content!="string"||typeof e.created_at!="number"||typeof e.pubkey!="string"||!e.pubkey.match(/^[a-f0-9]{64}$/)||!Array.isArray(e.tags))return!1;for(let t=0;t<e.tags.length;t++){let r=e.tags[t];if(!Array.isArray(r))return!1;for(let n=0;n<r.length;n++)if(typeof r[n]!="string")return!1}return!0}new TextDecoder("utf-8");var Gr=new TextEncoder;function pe(e){try{e.indexOf("://")===-1&&(e="wss://"+e);let t=new URL(e);return t.protocol==="http:"?t.protocol="ws:":t.protocol==="https:"&&(t.protocol="wss:"),t.pathname=t.pathname.replace(/\/+/g,"/"),t.pathname.endsWith("/")&&(t.pathname=t.pathname.slice(0,-1)),(t.port==="80"&&t.protocol==="ws:"||t.port==="443"&&t.protocol==="wss:")&&(t.port=""),t.searchParams.sort(),t.hash="",t.toString()}catch{throw new Error(`Invalid URL: ${e}`)}}var Xr=class{generateSecretKey(){return G.utils.randomSecretKey()}getPublicKey(t){return _(G.getPublicKey(t))}finalizeEvent(t,r){const n=t;return n.pubkey=_(G.getPublicKey(r)),n.id=Ke(n),n.sig=_(G.sign(X(Ke(n)),r)),n[ie]=!0,n}verifyEvent(t){if(typeof t[ie]=="boolean")return t[ie];try{const r=Ke(t);if(r!==t.id)return t[ie]=!1,!1;const n=G.verify(X(t.sig),X(r),X(t.pubkey));return t[ie]=n,n}catch{return t[ie]=!1,!1}}};function Jr(e){if(!zr(e))throw new Error("can't serialize event with wrong or missing properties");return JSON.stringify([0,e.pubkey,e.created_at,e.kind,e.tags,e.content])}function Ke(e){let t=Ne(Gr.encode(Jr(e)));return _(t)}var Ue=new Xr;Ue.generateSecretKey;Ue.getPublicKey;Ue.finalizeEvent;var Qr=Ue.verifyEvent,ei=22242;function ti(e,t){if(e.ids&&e.ids.indexOf(t.id)===-1||e.kinds&&e.kinds.indexOf(t.kind)===-1||e.authors&&e.authors.indexOf(t.pubkey)===-1)return!1;for(let r in e)if(r[0]==="#"){let n=r.slice(1),i=e[`#${n}`];if(i&&!t.tags.find(([s,o])=>s===r.slice(1)&&i.indexOf(o)!==-1))return!1}return!(e.since&&t.created_at<e.since||e.until&&t.created_at>e.until)}function ni(e,t){for(let r=0;r<e.length;r++)if(ti(e[r],t))return!0;return!1}function ri(e,t){let r=t.length+3,n=e.indexOf(`"${t}":`)+r,i=e.slice(n).indexOf('"')+n+1;return e.slice(i,i+64)}function ii(e){let t=e.slice(0,22).indexOf('"EVENT"');if(t===-1)return null;let r=e.slice(t+7+1).indexOf('"');if(r===-1)return null;let n=t+7+1+r,i=e.slice(n+1,80).indexOf('"');if(i===-1)return null;let s=n+1+i;return e.slice(n+1,s)}function si(e,t){return{kind:ei,created_at:Math.floor(Date.now()/1e3),tags:[["relay",e],["challenge",t]],content:""}}var vn=class extends Error{constructor(e,t){super(`Tried to send message '${e} on a closed connection to ${t}.`),this.name="SendingOnClosedConnection"}},En=class{url;_connected=!1;onclose=null;onnotice=e=>console.debug(`NOTICE from ${this.url}: ${e}`);onauth;baseEoseTimeout=4400;publishTimeout=4400;pingFrequency=29e3;pingTimeout=2e4;resubscribeBackoff=[1e4,1e4,1e4,2e4,2e4,3e4,6e4];openSubs=new Map;enablePing;enableReconnect;idleSince=Date.now();ongoingOperations=0;reconnectTimeoutHandle;pingIntervalHandle;reconnectAttempts=0;skipReconnection=!1;connectionPromise;openCountRequests=new Map;openEventPublishes=new Map;ws;challenge;authPromise;serial=0;verifyEvent;_WebSocket;constructor(e,t){this.url=pe(e),this.verifyEvent=t.verifyEvent,this._WebSocket=t.websocketImplementation||WebSocket,this.enablePing=t.enablePing,this.enableReconnect=t.enableReconnect||!1}static async connect(e,t){const r=new En(e,t);return await r.connect(t),r}closeAllSubscriptions(e){for(let[t,r]of this.openSubs)r.close(e);this.openSubs.clear();for(let[t,r]of this.openEventPublishes)r.reject(new Error(e));this.openEventPublishes.clear();for(let[t,r]of this.openCountRequests)r.reject(new Error(e));this.openCountRequests.clear()}get connected(){return this._connected}async reconnect(){const e=this.resubscribeBackoff[Math.min(this.reconnectAttempts,this.resubscribeBackoff.length-1)];this.reconnectAttempts++,this.reconnectTimeoutHandle=setTimeout(async()=>{try{await this.connect()}catch{}},e)}handleHardClose(e){this.pingIntervalHandle&&(clearInterval(this.pingIntervalHandle),this.pingIntervalHandle=void 0),this._connected=!1,this.connectionPromise=void 0,this.idleSince=void 0,this.enableReconnect&&!this.skipReconnection?this.reconnect():(this.onclose?.(),this.closeAllSubscriptions(e))}async connect(e){let t;return this.connectionPromise?this.connectionPromise:(this.challenge=void 0,this.authPromise=void 0,this.skipReconnection=!1,this.connectionPromise=new Promise((r,n)=>{e?.timeout&&(t=setTimeout(()=>{n("connection timed out"),this.connectionPromise=void 0,this.skipReconnection=!0,this.onclose?.(),this.handleHardClose("relay connection timed out")},e.timeout)),e?.abort&&(e.abort.onabort=n);try{this.ws=new this._WebSocket(this.url)}catch(i){clearTimeout(t),n(i);return}this.ws.onopen=()=>{this.reconnectTimeoutHandle&&(clearTimeout(this.reconnectTimeoutHandle),this.reconnectTimeoutHandle=void 0),clearTimeout(t),this._connected=!0;const i=this.reconnectAttempts>0;this.reconnectAttempts=0;for(const s of this.openSubs.values()){if(s.eosed=!1,i)for(let o=0;o<s.filters.length;o++)s.lastEmitted&&(s.filters[o].since=s.lastEmitted+1);s.fire()}this.enablePing&&(this.pingIntervalHandle=setInterval(()=>this.pingpong(),this.pingFrequency)),r()},this.ws.onerror=()=>{clearTimeout(t),n("connection failed"),this.connectionPromise=void 0,this.skipReconnection=!0,this.onclose?.(),this.handleHardClose("relay connection failed")},this.ws.onclose=i=>{clearTimeout(t),n(i.message||"websocket closed"),this.handleHardClose("relay connection closed")},this.ws.onmessage=this._onmessage.bind(this)}),this.connectionPromise)}waitForPingPong(){return new Promise(e=>{this.ws.once("pong",()=>e(!0)),this.ws.ping()})}waitForDummyReq(){return new Promise((e,t)=>{if(!this.connectionPromise)return t(new Error(`no connection to ${this.url}, can't ping`));try{const r=this.subscribe([{ids:["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"],limit:0}],{label:"<forced-ping>",oneose:()=>{e(!0),r.close()},onclose(){e(!0)},eoseTimeout:this.pingTimeout+1e3})}catch(r){t(r)}})}async pingpong(){this.ws?.readyState===1&&(await Promise.any([this.ws&&this.ws.ping&&this.ws.once?this.waitForPingPong():this.waitForDummyReq(),new Promise(t=>setTimeout(()=>t(!1),this.pingTimeout))])||this.ws?.readyState===this._WebSocket.OPEN&&this.ws?.close())}async send(e){if(!this.connectionPromise)throw new vn(e,this.url);this.connectionPromise.then(()=>{this.ws?.send(e)})}async auth(e){const t=this.challenge;if(!t)throw new Error("can't perform auth, no challenge was received");return this.authPromise?this.authPromise:(this.authPromise=new Promise(async(r,n)=>{try{let i=await e(si(this.url,t)),s=setTimeout(()=>{let o=this.openEventPublishes.get(i.id);o&&(o.reject(new Error("auth timed out")),this.openEventPublishes.delete(i.id))},this.publishTimeout);this.openEventPublishes.set(i.id,{resolve:r,reject:n,timeout:s}),this.send('["AUTH",'+JSON.stringify(i)+"]")}catch(i){console.warn("subscribe auth function failed:",i)}}),this.authPromise)}async publish(e){this.idleSince=void 0,this.ongoingOperations++;const t=new Promise((r,n)=>{const i=setTimeout(()=>{const s=this.openEventPublishes.get(e.id);s&&(s.reject(new Error("publish timed out")),this.openEventPublishes.delete(e.id))},this.publishTimeout);this.openEventPublishes.set(e.id,{resolve:r,reject:n,timeout:i})});return this.send('["EVENT",'+JSON.stringify(e)+"]"),this.ongoingOperations--,this.ongoingOperations===0&&(this.idleSince=Date.now()),t}async count(e,t){this.serial++;const r=t?.id||"count:"+this.serial,n=new Promise((i,s)=>{this.openCountRequests.set(r,{resolve:i,reject:s})});return this.send('["COUNT","'+r+'",'+JSON.stringify(e).substring(1)),n}subscribe(e,t){t.label!=="<forced-ping>"&&(this.idleSince=void 0,this.ongoingOperations++);const r=this.prepareSubscription(e,t);return r.fire(),t.abort&&(t.abort.onabort=()=>r.close(String(t.abort.reason||"<aborted>"))),r}prepareSubscription(e,t){this.serial++;const r=t.id||(t.label?t.label+":":"sub:")+this.serial,n=new oi(this,r,e,t);return this.openSubs.set(r,n),n}close(){this.skipReconnection=!0,this.reconnectTimeoutHandle&&(clearTimeout(this.reconnectTimeoutHandle),this.reconnectTimeoutHandle=void 0),this.pingIntervalHandle&&(clearInterval(this.pingIntervalHandle),this.pingIntervalHandle=void 0),this.closeAllSubscriptions("relay connection closed by us"),this._connected=!1,this.idleSince=void 0,this.onclose?.(),this.ws?.readyState===this._WebSocket.OPEN&&this.ws?.close()}_onmessage(e){const t=e.data;if(!t)return;const r=ii(t);if(r){const n=this.openSubs.get(r);if(!n)return;const i=ri(t,"id"),s=n.alreadyHaveEvent?.(i);if(n.receivedEvent?.(this,i),s)return}try{let n=JSON.parse(t);switch(n[0]){case"EVENT":{const i=this.openSubs.get(n[1]),s=n[2];this.verifyEvent(s)&&ni(i.filters,s)?i.onevent(s):i.oninvalidevent?.(s),(!i.lastEmitted||i.lastEmitted<s.created_at)&&(i.lastEmitted=s.created_at);return}case"COUNT":{const i=n[1],s=n[2],o=this.openCountRequests.get(i);o&&(o.resolve(s.count),this.openCountRequests.delete(i));return}case"EOSE":{const i=this.openSubs.get(n[1]);if(!i)return;i.receivedEose();return}case"OK":{const i=n[1],s=n[2],o=n[3],c=this.openEventPublishes.get(i);c&&(clearTimeout(c.timeout),s?c.resolve(o):c.reject(new Error(o)),this.openEventPublishes.delete(i));return}case"CLOSED":{const i=n[1],s=this.openSubs.get(i);if(!s)return;s.closed=!0,s.close(n[2]);return}case"NOTICE":{this.onnotice(n[1]);return}case"AUTH":{this.challenge=n[1],this.onauth&&this.auth(this.onauth);return}default:{this.openSubs.get(n[1])?.oncustom?.(n);return}}}catch(n){try{const[i,s,o]=JSON.parse(t);console.warn(`[nostr] relay ${this.url} error processing message:`,n,o)}catch{console.warn(`[nostr] relay ${this.url} error processing message:`,n)}return}}},oi=class{relay;id;lastEmitted;closed=!1;eosed=!1;filters;alreadyHaveEvent;receivedEvent;onevent;oninvalidevent;oneose;onclose;oncustom;eoseTimeout;eoseTimeoutHandle;constructor(e,t,r,n){if(r.length===0)throw new Error("subscription can't be created with zero filters");this.relay=e,this.filters=r,this.id=t,this.alreadyHaveEvent=n.alreadyHaveEvent,this.receivedEvent=n.receivedEvent,this.eoseTimeout=n.eoseTimeout||e.baseEoseTimeout,this.oneose=n.oneose,this.onclose=n.onclose,this.oninvalidevent=n.oninvalidevent,this.onevent=n.onevent||(i=>{console.warn(`onevent() callback not defined for subscription '${this.id}' in relay ${this.relay.url}. event received:`,i)})}fire(){this.relay.send('["REQ","'+this.id+'",'+JSON.stringify(this.filters).substring(1)),this.eoseTimeoutHandle=setTimeout(this.receivedEose.bind(this),this.eoseTimeout)}receivedEose(){this.eosed||(clearTimeout(this.eoseTimeoutHandle),this.eosed=!0,this.oneose?.())}close(e="closed by caller"){if(!this.closed&&this.relay.connected){try{this.relay.send('["CLOSE",'+JSON.stringify(this.id)+"]")}catch(t){if(!(t instanceof vn))throw t}this.closed=!0}this.relay.openSubs.delete(this.id),this.relay.ongoingOperations--,this.relay.ongoingOperations===0&&(this.relay.idleSince=Date.now()),this.onclose?.(e)}},ai=e=>(e[ie]=!0,!0),ci=class{relays=new Map;seenOn=new Map;trackRelays=!1;verifyEvent;enablePing;enableReconnect;automaticallyAuth;trustedRelayURLs=new Set;onRelayConnectionFailure;onRelayConnectionSuccess;allowConnectingToRelay;maxWaitForConnection;_WebSocket;constructor(e){this.verifyEvent=e.verifyEvent,this._WebSocket=e.websocketImplementation,this.enablePing=e.enablePing,this.enableReconnect=e.enableReconnect||!1,this.automaticallyAuth=e.automaticallyAuth,this.onRelayConnectionFailure=e.onRelayConnectionFailure,this.onRelayConnectionSuccess=e.onRelayConnectionSuccess,this.allowConnectingToRelay=e.allowConnectingToRelay,this.maxWaitForConnection=e.maxWaitForConnection||3e3}async ensureRelay(e,t){e=pe(e);let r=this.relays.get(e);if(r||(r=new En(e,{verifyEvent:this.trustedRelayURLs.has(e)?ai:this.verifyEvent,websocketImplementation:this._WebSocket,enablePing:this.enablePing,enableReconnect:this.enableReconnect}),r.onclose=()=>{this.relays.delete(e)},this.relays.set(e,r)),this.automaticallyAuth){const n=this.automaticallyAuth(e);n&&(r.onauth=n)}try{await r.connect({timeout:t?.connectionTimeout,abort:t?.abort})}catch(n){throw this.relays.delete(e),n}return r}close(e){e.map(pe).forEach(t=>{this.relays.get(t)?.close(),this.relays.delete(t)})}subscribe(e,t,r){const n=[],i=[];for(let s=0;s<e.length;s++){const o=pe(e[s]);n.find(c=>c.url===o)||i.indexOf(o)===-1&&(i.push(o),n.push({url:o,filter:t}))}return this.subscribeMap(n,r)}subscribeMany(e,t,r){return this.subscribe(e,t,r)}subscribeMap(e,t){const r=new Map;for(const f of e){const{url:p,filter:y}=f;r.has(p)||r.set(p,[]),r.get(p).push(y)}const n=Array.from(r.entries()).map(([f,p])=>({url:f,filters:p}));this.trackRelays&&(t.receivedEvent=(f,p)=>{let y=this.seenOn.get(p);y||(y=new Set,this.seenOn.set(p,y)),y.add(f)});const i=new Set,s=[],o=[];let c=f=>{o[f]||(o[f]=!0,o.filter(p=>p).length===n.length&&(t.oneose?.(),c=()=>{}))};const a=[];let l=(f,p)=>{a[f]||(c(f),a[f]=p,a.filter(y=>y).length===n.length&&(t.onclose?.(a),l=()=>{}))};const g=f=>{if(t.alreadyHaveEvent?.(f))return!0;const p=i.has(f);return i.add(f),p},u=Promise.all(n.map(async({url:f,filters:p},y)=>{if(this.allowConnectingToRelay?.(f,["read",p])===!1){l(y,"connection skipped by allowConnectingToRelay");return}let w;try{w=await this.ensureRelay(f,{connectionTimeout:this.maxWaitForConnection<(t.maxWait||0)?Math.max(t.maxWait*.8,t.maxWait-1e3):this.maxWaitForConnection,abort:t.abort})}catch(N){this.onRelayConnectionFailure?.(f),l(y,N?.message||String(N));return}this.onRelayConnectionSuccess?.(f);let $=w.subscribe(p,{...t,oneose:()=>c(y),onclose:N=>{N.startsWith("auth-required: ")&&t.onauth?w.auth(t.onauth).then(()=>{w.subscribe(p,{...t,oneose:()=>c(y),onclose:K=>{l(y,K)},alreadyHaveEvent:g,eoseTimeout:t.maxWait,abort:t.abort})}).catch(K=>{l(y,`auth was required and attempted, but failed with: ${K}`)}):l(y,N)},alreadyHaveEvent:g,eoseTimeout:t.maxWait,abort:t.abort});s.push($)}));return{async close(f){await u,s.forEach(p=>{p.close(f)})}}}subscribeEose(e,t,r){let n;return n=this.subscribe(e,t,{...r,oneose(){const i="closed automatically on eose";n?n.close(i):r.onclose?.(e.map(s=>i))}}),n}subscribeManyEose(e,t,r){return this.subscribeEose(e,t,r)}async querySync(e,t,r){return new Promise(async n=>{const i=[];this.subscribeEose(e,t,{...r,onevent(s){i.push(s)},onclose(s){n(i)}})})}async get(e,t,r){t.limit=1;const n=await this.querySync(e,t,r);return n.sort((i,s)=>s.created_at-i.created_at),n[0]||null}publish(e,t,r){return e.map(pe).map(async(n,i,s)=>{if(s.indexOf(n)!==i)return Promise.reject("duplicate url");if(this.allowConnectingToRelay?.(n,["write",t])===!1)return Promise.reject("connection skipped by allowConnectingToRelay");let o;try{o=await this.ensureRelay(n,{connectionTimeout:this.maxWaitForConnection<(r?.maxWait||0)?Math.max(r.maxWait*.8,r.maxWait-1e3):this.maxWaitForConnection,abort:r?.abort})}catch(c){return this.onRelayConnectionFailure?.(n),"connection failure: "+String(c)}return o.publish(t).catch(async c=>{if(c instanceof Error&&c.message.startsWith("auth-required: ")&&r?.onauth)return await o.auth(r.onauth),o.publish(t);throw c}).then(c=>{if(this.trackRelays){let a=this.seenOn.get(t.id);a||(a=new Set,this.seenOn.set(t.id,a)),a.add(o)}return c})})}listConnectionStatus(){const e=new Map;return this.relays.forEach((t,r)=>e.set(r,t.connected)),e}destroy(){this.relays.forEach(e=>e.close()),this.relays=new Map}pruneIdleRelays(e=1e4){const t=[];for(const[r,n]of this.relays)n.idleSince&&Date.now()-n.idleSince>=e&&(this.relays.delete(r),t.push(r),n.close());return t}},xn;try{xn=WebSocket}catch{}var li=class extends ci{constructor(e){super({verifyEvent:Qr,websocketImplementation:xn,maxWaitForConnection:3e3,...e})}},ce=Symbol("verified"),di=e=>e instanceof Object;function ui(e){if(!di(e)||typeof e.kind!="number"||typeof e.content!="string"||typeof e.created_at!="number"||typeof e.pubkey!="string"||!e.pubkey.match(/^[a-f0-9]{64}$/)||!Array.isArray(e.tags))return!1;for(let t=0;t<e.tags.length;t++){let r=e.tags[t];if(!Array.isArray(r))return!1;for(let n=0;n<r.length;n++)if(typeof r[n]!="string")return!1}return!0}new TextDecoder("utf-8");var fi=new TextEncoder,hi=class{generateSecretKey(){return G.utils.randomSecretKey()}getPublicKey(e){return _(G.getPublicKey(e))}finalizeEvent(e,t){const r=e;return r.pubkey=_(G.getPublicKey(t)),r.id=Ye(r),r.sig=_(G.sign(X(Ye(r)),t)),r[ce]=!0,r}verifyEvent(e){if(typeof e[ce]=="boolean")return e[ce];try{const t=Ye(e);if(t!==e.id)return e[ce]=!1,!1;const r=G.verify(X(e.sig),X(t),X(e.pubkey));return e[ce]=r,r}catch{return e[ce]=!1,!1}}};function pi(e){if(!ui(e))throw new Error("can't serialize event with wrong or missing properties");return JSON.stringify([0,e.pubkey,e.created_at,e.kind,e.tags,e.content])}function Ye(e){let t=Ne(fi.encode(pi(e)));return _(t)}var He=new hi;He.generateSecretKey;He.getPublicKey;He.finalizeEvent;var gi=He.verifyEvent;const mi=8e3;function yi(e){return typeof e=="number"&&at.includes(e)}function bi(e){try{const t=new URL(e);return t.protocol==="http:"||t.protocol==="https:"}catch{return!1}}function wi(e){const t=[];for(const r of e??[])try{const n=new URL(r);if(n.protocol!=="ws:"&&n.protocol!=="wss:")continue;t.push(n.href)}catch{}return[...new Set(t)]}function vi(e){const t=lr(e.trim());if(t.type!=="nevent"&&t.type!=="naddr")throw new Error("Enter a NIP-19 nevent or naddr for a NIP-5D napplet manifest event");const r=wi(t.data.relays);if(r.length===0)throw new Error("The pointer does not include relay hints; include at least one relay in the nevent/naddr");if(t.type==="nevent"){if(t.data.kind!==void 0&&!yi(t.data.kind))throw new Error(`nevent points at kind ${t.data.kind}, not a NIP-5D napplet manifest kind`);return{type:"nevent",relays:r,filter:{ids:[t.data.id],kinds:t.data.kind===void 0?[...at]:[t.data.kind],authors:t.data.author?[t.data.author]:void 0,limit:1}}}if(t.data.kind!==ge)throw new Error(`naddr kind ${t.data.kind} is not the named napplet kind ${ge}`);return{type:"naddr",relays:r,filter:{kinds:[ge],authors:[t.data.pubkey],"#d":[t.data.identifier],limit:1}}}function Ei(e){return{id:e.id,pubkey:e.pubkey,kind:e.kind,tags:e.tags}}async function kn(e){const t=typeof e=="string"?new TextEncoder().encode(e):e,r=new Uint8Array(t.byteLength);r.set(t);const n=await crypto.subtle.digest("SHA-256",r.buffer);return[...new Uint8Array(n)].map(i=>i.toString(16).padStart(2,"0")).join("")}function xi(e){return e.tags.filter(t=>t[0]==="path"&&typeof t[1]=="string"&&typeof t[2]=="string")}async function ki(e){const t=xi(e).map(r=>`${r[2]} ${r[1]}
|
|
77
|
-
`).sort().join("");return kn(t)}async function Si(e){const t=await ki(e);for(const r of e.tags.filter(n=>n[0]==="x"))if(r[2]!==t)throw new Error(`Manifest x tag does not match recomputed aggregate hash ${t}`)}function Ri(e){return e.tags.find(t=>t[0]==="path"&&t[1]==="/index.html")}function Ii(e){const t=[];for(const r of e.tags)if(!(r[0]!=="server"||!r[1]))try{const n=new URL(r[1]);(n.protocol==="http:"||n.protocol==="https:")&&t.push(n.href)}catch{}return[...new Set(t)]}function $i(e,t){const r=e.endsWith("/")?e:`${e}/`;return new URL(t,r).href}async function Ti(e,t=fetch){const n=Ri(e)?.[2];if(!n)throw new Error("Manifest does not include a /index.html path hash");const i=Ii(e);if(i.length===0)throw new Error("Manifest does not include any usable Blossom server hints");const s=[];for(const o of i){const c=$i(o,n);try{const a=await t(c,{mode:"cors"});if(!a.ok){s.push(`${c}: HTTP ${a.status}`);continue}const l=new Uint8Array(await a.arrayBuffer()),g=await kn(l);if(g!==n){s.push(`${c}: sha256 ${g} did not match manifest ${n}`);continue}return new TextDecoder().decode(l)}catch(a){s.push(`${c}: ${a instanceof Error?a.message:String(a)}`)}}throw new Error(`Unable to fetch verified /index.html from Blossom servers: ${s.join("; ")}`)}async function Bi(e,t){try{const n=await(await t(e,{mode:"cors"})).text();return{source:"url",input:e,label:e,bootUrl:e,html:n,fetched:!0,manifestEvent:null}}catch{return{source:"url",input:e,label:e,bootUrl:e,html:"",fetched:!1,manifestEvent:null}}}async function Ai(e,t){const r=vi(e),n=!t.pool,i=t.pool??new li;try{const s=await i.get(r.relays,{...r.filter},{maxWait:t.maxRelayWaitMs??mi});if(!s)throw new Error("No matching napplet manifest event was found on the pointer relay hints");if(!gi(s))throw new Error("Resolved manifest event signature is invalid");const o=Ei(s),c=ct(o);if(!c.ok)throw new Error(`Resolved event is not a valid NIP-5D napplet manifest: ${c.errors[0]?.message}`);await Si(o);const a=await Ti(o,t.fetcher??fetch),l=(t.createObjectUrl??URL.createObjectURL)(new Blob([a],{type:"text/html;charset=utf-8"})),g=()=>(t.revokeObjectUrl??URL.revokeObjectURL)(l);return{source:"nostr",input:e,label:o.id??e,bootUrl:l,html:a,fetched:!0,manifestEvent:o,revoke:g}}finally{n&&i.destroy()}}async function Oi(e,t={}){const r=e.trim();if(!r)throw new Error("Enter a NIP-19 nevent/naddr, or an HTTP URL for local dev");return bi(r)?Bi(r,t.fetcher??fetch):Ai(r,t)}const Ni=/\bwindow\s*\.\s*nostr\b|\bglobalThis\s*\.\s*nostr\b/,qi="/__conformance__/events",it=new URLSearchParams(location.search),Sn=it.get("live")==="1";function ne(e){return String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}const re=document.getElementById("app");function Li(){return re.innerHTML=`
|
|
78
|
-
<header class="masthead">
|
|
79
|
-
<h1>napplet conformance ${Sn?'<span class="live-badge" id="live-badge">● live</span>':""}</h1>
|
|
80
|
-
<p>Load a napplet by <code>nevent</code> or <code>naddr</code> and run NAP protocol conformance live. Same engine as <code>napplet-conformance</code> CI.</p>
|
|
81
|
-
</header>
|
|
82
|
-
<form id="run-form" class="runbar">
|
|
83
|
-
<input id="target" type="text" placeholder="naddr1… or nevent1… for a NIP-5D napplet manifest" autocomplete="off" spellcheck="false" />
|
|
84
|
-
<button id="run" type="submit">Run conformance</button>
|
|
85
|
-
<button id="rerun" type="button" class="secondary" hidden>Re-run</button>
|
|
86
|
-
</form>
|
|
87
|
-
<p id="status" class="status" role="status"></p>
|
|
88
|
-
<section id="output" class="output"></section>
|
|
89
|
-
`,{targetInput:re.querySelector("#target"),runButton:re.querySelector("#run"),rerunButton:re.querySelector("#rerun"),liveBadge:re.querySelector("#live-badge")??document.createElement("span"),status:re.querySelector("#status"),output:re.querySelector("#output")}}const C=Li();let be="",st=0;function $e(e,t="info"){C.status.textContent=e,C.status.dataset.kind=t}function ze(e){return String(e).padStart(2,"0")}function Pi(e){const t=new Date(e);return`${ze(t.getHours())}:${ze(t.getMinutes())}:${ze(t.getSeconds())}`}function _i(e){const t=e.ok?"conformant":"non-conformant",n=[...new Set(e.checks.map(o=>o.area))].map(o=>{const c=e.checks.filter(a=>a.area===o).map(a=>{const l=a.severity==="warning"&&a.status==="fail"?' <span class="tag warn">warning</span>':"",g=a.detail?`<span class="detail">${ne(a.detail)}</span>`:"";return`<li class="check ${a.status}"><span class="badge ${a.status}">${a.status}</span><span class="id">${ne(a.id)}</span>${l}${g}</li>`}).join("");return`<div class="area"><h3>${ne(o)}</h3><ul>${c}</ul></div>`}).join(""),i=e.summary,s=st>1?`<span class="run-stamp">run #${st} · ${Pi(e.finishedAt)}</span>`:"";return`
|
|
90
|
-
<div class="verdict ${t}">
|
|
91
|
-
<span class="result">${e.ok?"CONFORMANT":"NON-CONFORMANT"}</span>
|
|
92
|
-
<span class="counts">${i.passed} passed · ${i.failed} failed · ${i.skipped} skipped${i.warnings?` · ${i.warnings} warning(s)`:""}</span>
|
|
93
|
-
${s}
|
|
94
|
-
</div>
|
|
95
|
-
<div class="checks">${n}</div>
|
|
96
|
-
`}function Ci(e){return e.length===0?'<p class="empty">No envelopes were emitted.</p>':`<ul class="envlog">${e.map(r=>{const n=r.verdict.ok?"ok":"bad",i=r.verdict.ok?"":`<div class="errs">${r.verdict.errors.map(s=>ne(`${s.code}: ${s.message}`)).join("<br>")}</div>`;return`<li class="env ${n}"><code>${ne(JSON.stringify(r.envelope))}</code>${i}</li>`}).join("")}</ul>`}function Ui(e){const t=(r,n)=>`<tr><th>${ne(r)}</th><td>${n?ne(String(n)):"<em>—</em>"}</td></tr>`;if(e.manifestEvent){const r=e.manifestEvent,n=ct(r),i=r.tags.find(c=>c[0]==="d")?.[1],s=r.tags.find(c=>c[0]==="path"&&c[1]==="/index.html"),o=r.tags.filter(c=>c[0]==="server").map(c=>c[1]).filter(Boolean);return`
|
|
97
|
-
<table class="manifest">
|
|
98
|
-
${t("event",r.id)}
|
|
99
|
-
${t("kind",r.kind)}
|
|
100
|
-
${t("d",i)}
|
|
101
|
-
${t("name",Wt(r))}
|
|
102
|
-
${t("requires",n.requires.join(", "))}
|
|
103
|
-
${t("/index.html",s?.[2])}
|
|
104
|
-
${t("servers",o.join(", "))}
|
|
105
|
-
</table>
|
|
106
|
-
${n.errors.length?`<div class="errs">${n.errors.map(c=>ne(`${c.code}: ${c.message}`)).join("<br>")}</div>`:""}
|
|
107
|
-
`}return e.fetched?'<p class="empty">Local URL mode booted raw HTML. It does not include a signed NIP-5D manifest event, so manifest-event checks are skipped.</p>':`<p class="empty">Couldn't fetch the local URL HTML, likely because of CORS. Use a NIP-19 <code>nevent</code>/<code>naddr</code> for authoritative manifest checks, or use the CLI for local URL runs.</p>`}function Hi(e,t,r){C.output.innerHTML=`
|
|
108
|
-
${_i(e)}
|
|
109
|
-
<div class="panels">
|
|
110
|
-
<section class="panel"><h2>Emitted envelopes (${t.length})</h2>${Ci(t)}</section>
|
|
111
|
-
<section class="panel"><h2>Manifest</h2>${Ui(r)}</section>
|
|
112
|
-
</div>
|
|
113
|
-
`}async function De(e){be=e,C.runButton.disabled=!0,C.rerunButton.disabled=!0;let t=null;try{$e(`Resolving ${e} …`),t=await Oi(e);const r=Ni.test(t.html)?["window.nostr"]:[];$e("Booting napplet in a sandboxed iframe …");const n=await Wn({url:t.bootUrl,readyTimeoutMs:5e3,settleMs:800,runDegraded:!0}),i=Un({manifestHtml:t.html,manifestEvent:t.manifestEvent,boot:n,forbiddenGlobals:r}),s=Gn(i);st+=1,$e(s.ok?"Done — conformant.":"Done — non-conformant.",s.ok?"info":"error"),Hi(s,n.emitted,t),C.rerunButton.hidden=!1}catch(r){$e(`Error: ${r instanceof Error?r.message:String(r)}`,"error")}finally{t?.revoke?.(),C.runButton.disabled=!1,C.rerunButton.disabled=!1}}function Di(){if(!Sn||typeof EventSource>"u")return;let e=!1;const t=new EventSource(qi);t.addEventListener("rerun",()=>{!be||e||(e=!0,setTimeout(()=>{e=!1,De(be)},50))}),t.addEventListener("open",()=>{C.liveBadge&&(C.liveBadge.dataset.state="connected")}),t.addEventListener("error",()=>{C.liveBadge&&(C.liveBadge.dataset.state="disconnected")})}C.runButton.parentElement.addEventListener("submit",e=>{e.preventDefault();const t=C.targetInput.value.trim();if(t){const r=new URL(location.href);r.searchParams.set("target",t),r.searchParams.delete("url"),history.replaceState(null,"",r),De(t)}});C.rerunButton.addEventListener("click",()=>{be&&De(be)});Di();const Ge=it.get("target")??it.get("url");Ge&&(C.targetInput.value=Ge,De(Ge));
|