Back to A test napplet
SOURCE / PINNED RELEASE

Made of little things.

A test napplet

Release
7b2cb0547129…
Author-recorded commit
Not provided
License
Check the original source

The hash-verified playable HTML, which may contain bundled or minified code. This view does not execute it.

index.html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>A test napplet</title>
    <script type="module" crossorigin>(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))r(o);new MutationObserver(o=>{for(const i of o)if(i.type==="childList")for(const s of i.addedNodes)s.tagName==="LINK"&&s.rel==="modulepreload"&&r(s)}).observe(document,{childList:!0,subtree:!0});function n(o){const i={};return o.integrity&&(i.integrity=o.integrity),o.referrerPolicy&&(i.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?i.credentials="include":o.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function r(o){if(o.ep)return;o.ep=!0;const i=n(o);fetch(o.href,i)}})();var cn=["relay","identity","storage","inc","theme","keys","media","notify","config","resource","cvm","outbox","upload","intent","ble","webrtc","link","lists","serial","common","dm"];function ln(){const e=new Map;function t(o,i){if(e.has(o))throw new Error(`NAP domain "${o}" is already registered`);e.set(o,i)}function n(o){const i=o.type.indexOf(".");if(i<=0)return!1;const s=o.type.slice(0,i),c=e.get(s);return c?(c(o),!0):!1}function r(){return Array.from(e.keys())}return{registerNap:t,dispatch:n,getRegisteredDomains:r}}var dn=ln(),X=dn.registerNap,dt=new Set;function fn(e){if(e instanceof Date||e instanceof RegExp||e instanceof ArrayBuffer||ArrayBuffer.isView(e))return!0;const t=Object.prototype.toString.call(e);return t==="[object Blob]"||t==="[object File]"}function pn(e){return q(e,new WeakMap)}function q(e,t){if(e===null)return null;const n=typeof e;if(n==="function"||n==="symbol")throw new TypeError(`toCloneableSnapshot: a ${n} is not structured-cloneable and cannot be sent across the napplet boundary`);if(n!=="object")return e;const r=e,o=t.get(r);if(o!==void 0)return o;if(fn(r))return r;if(Array.isArray(r)){const s=[];t.set(r,s);for(const c of r)s.push(q(c,t));return s}if(r instanceof Map){const s=new Map;t.set(r,s);for(const[c,l]of r)s.set(q(c,t),q(l,t));return s}if(r instanceof Set){const s=new Set;t.set(r,s);for(const c of r)s.add(q(c,t));return s}const i={};t.set(r,i);for(const s of Object.keys(r))i[s]=q(r[s],t);return i}function yn(e){return e instanceof Error&&e.name==="DataCloneError"}function vn(e,t){const n=new Error(`napplet boundary: message "${e}" could not be sent -- an argument is not structured-cloneable (a reactive Proxy?). Svelte 5 $state / Vue reactive / Solid store values can't be postMessage'd. Pass a plain snapshot (e.g. $state.snapshot(x), toCloneableSnapshot(x) from @napplet/core), or call setCloneMode('snapshot') to normalize automatically.`);return n.name="NappletDataCloneError",n.cause=t,n}function bn(e,t,n="*"){try{e.postMessage(t,n);return}catch(r){if(!yn(r))throw r;try{e.postMessage(pn(t),n)}catch{throw vn(t.type,r)}dt.has(t.type)||(dt.add(t.type),console.warn(`napplet boundary: "${t.type}" received a non-cloneable argument (a reactive Proxy?) and was auto-snapshotted before sending. Pass a plain snapshot (e.g. $state.snapshot(x), toCloneableSnapshot(x)) to silence this, or call setCloneMode('strict') to make it throw.`))}}function u(e){bn(window.parent,e)}var G=new Map,E=new Map,W=new Map,Oe=!1,z=null,mn=new Set(["Tab","Shift+Tab","Escape"]);function _e(e,t){return e.type===t}function wn(e){if(!(e instanceof Element))return!1;const t=e.tagName;if(t==="TEXTAREA"||t==="SELECT")return!0;if(t==="INPUT"){const r=e.type?.toLowerCase()??"text";return new Set(["text","search","email","url","password","number","tel","date","datetime-local","month","time","week"]).has(r)||r===""}if(e.isContentEditable)return!0;const n=e.contentEditable;return n==="true"||n==="plaintext-only"}function hn(e){return e==="Control"||e==="Alt"||e==="Shift"||e==="Meta"}function gn(e){const t=[];return e.altKey&&t.push("Alt"),e.ctrlKey&&t.push("Ctrl"),e.metaKey&&t.push("Meta"),e.shiftKey&&t.push("Shift"),t.push(e.key),t.join("+")}function En(e){G.clear();for(const t of e.bindings)G.set(t.key,t.actionId)}function Mn(e){const t=W.get(e.id);if(t){if(W.delete(e.id),e.error){t.reject(new Error(e.error));return}t.resolve({actionId:e.actionId,binding:e.binding})}}function Un(e){const t=E.get(e.actionId);if(t)for(const n of t)n()}function ft(e){if(wn(e.target)||hn(e.key)||e.isComposing)return;const t=gn(e);if(!mn.has(t)&&G.has(t)){e.preventDefault();const r=G.get(t),o=E.get(r);if(o)for(const i of o)i();return}const n={type:"keys.forward",key:e.key,code:e.code,ctrl:e.ctrlKey,alt:e.altKey,shift:e.shiftKey,meta:e.metaKey};u(n)}function Sn(e){_e(e,"keys.bindings")?En(e):_e(e,"keys.registerAction.result")?Mn(e):_e(e,"keys.action")&&Un(e)}function Tn(e){const t=crypto.randomUUID();return new Promise((n,r)=>{W.set(t,{resolve:n,reject:r}),u({type:"keys.registerAction",id:t,action:e}),setTimeout(()=>{W.delete(t)&&r(new Error("keys.registerAction timed out"))},3e4)})}function In(e){u({type:"keys.unregisterAction",actionId:e})}function $n(e,t){return E.has(e)||E.set(e,new Set),E.get(e).add(t),{close(){const n=E.get(e);n&&(n.delete(t),n.size===0&&E.delete(e))}}}function Rn(){return Oe&&z||(document.addEventListener("keydown",ft,!0),Oe=!0,z=()=>{document.removeEventListener("keydown",ft,!0),G.clear(),E.clear(),W.clear(),Oe=!1,z=null}),z}var ue=new Map,$=new Map,R=new Map,D=new Map,P=new Map;function V(e,t){return e.type===t}function Dn(e){const t=ue.get(e.id);if(!t)return;ue.delete(e.id),clearTimeout(t.timeout);const n={};e.sessionId!==void 0&&(n.sessionId=e.sessionId),e.owner!==void 0&&(n.owner=e.owner),e.error!==void 0&&(n.error=e.error),t.resolve(n)}function Pn(e){const t=$.get(e.sessionId);if(t)for(const n of t)n(e.action,e.value)}function kn(e){const t=R.get(e.sessionId);if(t)for(const n of t)n(e.controls)}function Cn(e){const t=D.get(e.sessionId);if(!t)return;const n={status:e.status,position:e.position,duration:e.duration,volume:e.volume};for(const r of t)r(n)}function An(e){const t=P.get(e.sessionId);if(t)for(const n of t)n(e.actions)}function xn(e){V(e,"media.session.create.result")?Dn(e):V(e,"media.command")?Pn(e):V(e,"media.controls")?kn(e):V(e,"media.state")?Cn(e):V(e,"media.capabilities")&&An(e)}function Ln(e){const t=crypto.randomUUID();return new Promise((n,r)=>{const o=setTimeout(()=>{ue.delete(t)&&r(new Error("media.session.create timed out"))},3e4);ue.set(t,{resolve:n,reject:r,timeout:o});const i={type:"media.session.create",id:t,...e};u(i)})}function On(e,t){u({type:"media.session.update",sessionId:e,metadata:t})}function _n(e){u({type:"media.session.destroy",sessionId:e}),$.delete(e),R.delete(e),D.delete(e),P.delete(e)}function Nn(e,t){const n={type:"media.state",sessionId:e,...t};u(n)}function qn(e,t){u({type:"media.capabilities",sessionId:e,actions:t})}function Bn(e,t,n){const r={type:"media.command",sessionId:e,action:t,...n===void 0?{}:{value:n}};u(r)}function jn(e,t){return $.has(e)||$.set(e,new Set),$.get(e).add(t),{close(){const n=$.get(e);n&&(n.delete(t),n.size===0&&$.delete(e))}}}function Kn(e,t){return D.has(e)||D.set(e,new Set),D.get(e).add(t),{close(){const n=D.get(e);n&&(n.delete(t),n.size===0&&D.delete(e))}}}function Hn(e,t){return P.has(e)||P.set(e,new Set),P.get(e).add(t),{close(){const n=P.get(e);n&&(n.delete(t),n.size===0&&P.delete(e))}}}function Qn(e,t){return R.has(e)||R.set(e,new Set),R.get(e).add(t),{close(){const n=R.get(e);n&&(n.delete(t),n.size===0&&R.delete(e))}}}var Tt=3e4,ae=new Map,ce=new Map,je=new Set,Ke=new Set,He=new Set,Qe=new Set;function O(e,t){return e.type===t}function Fn(e){const t=ae.get(e.id);if(t){if(ae.delete(e.id),e.error){t.reject(new Error(e.error));return}e.notificationId?t.resolve({notificationId:e.notificationId}):t.reject(new Error("notify.send.result missing notificationId"))}}function zn(e){const t=ce.get(e.id);t&&(ce.delete(e.id),t.resolve({granted:e.granted}))}function Vn(e){for(const t of je)t(e.notificationId,e.actionId)}function Gn(e){for(const t of Ke)t(e.notificationId)}function Wn(e){for(const t of He)t(e.notificationId,e.reason)}function Zn(e){for(const t of Qe)t(e.controls)}function Yn(e){O(e,"notify.send.result")?Fn(e):O(e,"notify.permission.result")?zn(e):O(e,"notify.action")?Vn(e):O(e,"notify.clicked")?Gn(e):O(e,"notify.dismissed")?Wn(e):O(e,"notify.controls")&&Zn(e)}function Jn(e){const t=crypto.randomUUID();return new Promise((n,r)=>{ae.set(t,{resolve:n,reject:r});const o={type:"notify.send",id:t,...e};u(o),setTimeout(()=>{ae.delete(t)&&r(new Error("notify.send timed out"))},Tt)})}function Xn(e){u({type:"notify.dismiss",notificationId:e})}function er(e){u({type:"notify.badge",count:e})}function tr(e){const t={type:"notify.channel.register",...e};u(t)}function nr(e){const t=crypto.randomUUID();return new Promise((n,r)=>{ce.set(t,{resolve:n,reject:r}),u({type:"notify.permission.request",id:t,channel:e}),setTimeout(()=>{ce.delete(t)&&r(new Error("notify.permission.request timed out"))},Tt)})}function rr(e){return je.add(e),{close(){je.delete(e)}}}function or(e){return Ke.add(e),{close(){Ke.delete(e)}}}function ir(e){return He.add(e),{close(){He.delete(e)}}}function sr(e){return Qe.add(e),{close(){Qe.delete(e)}}}var Z=new Map,ur=5e3;function pt(e){if(e.source!==window.parent)return;const t=e.data;if(typeof t!="object"||t===null||typeof t.type!="string"||!t.type.startsWith("storage.")||!t.type.endsWith(".result"))return;const n=t.id;if(!n)return;const r=Z.get(n);if(r){if(Z.delete(n),t.error){r.reject(new Error(t.error));return}r.resolve(t)}}function Ae(e){return new Promise((t,n)=>{Z.set(e.id,{resolve:t,reject:n}),u(e),setTimeout(()=>{Z.delete(e.id)&&n(new Error("State request timed out"))},ur)})}async function yt(e,t){const n={type:"storage.get",id:crypto.randomUUID(),key:e,...t==="instance"?{scope:t}:{}};return(await Ae(n)).value}async function vt(e,t,n){const r={type:"storage.set",id:crypto.randomUUID(),key:e,value:t,...n==="instance"?{scope:n}:{}};await Ae(r)}async function bt(e,t){const n={type:"storage.remove",id:crypto.randomUUID(),key:e,...t==="instance"?{scope:t}:{}};await Ae(n)}async function mt(e){const t={type:"storage.keys",id:crypto.randomUUID(),...e==="instance"?{scope:e}:{}};return(await Ae(t)).keys}var f={getItem(e){return yt(e)},setItem(e,t){return vt(e,t)},removeItem(e){return bt(e)},keys(){return mt()},instance:{getItem(e){return yt(e,"instance")},setItem(e,t){return vt(e,t,"instance")},removeItem(e){return bt(e,"instance")},keys(){return mt("instance")}}};function ar(){return window.addEventListener("message",pt),()=>{window.removeEventListener("message",pt),Z.clear()}}var et=3e4,ie=new Map,M=new Map,j=new Map,U=new Map;function _(e,t){return e.type===t}function cr(e){if(_(e,"resource.info.result")){const t=e,n=j.get(t.id);if(!n)return;j.delete(t.id),clearTimeout(n.timeout),n.resolve(t.info)}else if(_(e,"resource.info.error")){const t=e,n=j.get(t.id);if(!n)return;j.delete(t.id),clearTimeout(n.timeout),n.reject(new Error(t.message?`${t.error}: ${t.message}`:t.error))}else if(_(e,"resource.bytes.result")){const t=e,n=M.get(t.id);if(!n)return;M.delete(t.id),clearTimeout(n.timeout),n.resolve(t.blob)}else if(_(e,"resource.bytes.error")){const t=e,n=M.get(t.id);if(!n)return;M.delete(t.id),clearTimeout(n.timeout),n.reject(new Error(t.message?`${t.error}: ${t.message}`:t.error))}else if(_(e,"resource.bytesMany.result")){const t=e,n=U.get(t.id);if(!n)return;U.delete(t.id),clearTimeout(n.timeout),n.resolve(t.items)}else if(_(e,"resource.bytesMany.error")){const t=e,n=U.get(t.id);if(!n)return;U.delete(t.id),clearTimeout(n.timeout),n.reject(new Error(t.message?`${t.error}: ${t.message}`:t.error))}}function lr(e){return new Promise((t,n)=>{const r=setTimeout(()=>{j.delete(e)&&n(new Error("resource.info timed out"))},et);j.set(e,{resolve:t,reject:n,timeout:r}),u({type:"resource.info",id:e})})}function dr(e,t){return new Promise((n,r)=>{const o=setTimeout(()=>{M.delete(t)&&r(new Error(`resource.bytes timed out for ${e}`))},et);M.set(t,{resolve:n,reject:r,timeout:o}),u({type:"resource.bytes",id:t,url:e})})}function fr(e,t){return new Promise((n,r)=>{const o=setTimeout(()=>{U.delete(t)&&r(new Error(`resource.bytesMany timed out for ${e.length} URLs`))},et);U.set(t,{resolve:n,reject:r,timeout:o}),u({type:"resource.bytesMany",id:t,urls:e})})}function le(e){u({type:"resource.cancel",id:e})}function pr(e){return fetch(e).then(t=>t.blob())}function wt(e,t,n=null,r){if(!t)return e;if(t.aborted){const o=new DOMException("Aborted","AbortError");return n&&le(n),r?.(o),Promise.reject(o)}return new Promise((o,i)=>{const s=()=>{const c=new DOMException("Aborted","AbortError");n&&le(n),r?.(c),i(c)};t.addEventListener("abort",s,{once:!0}),e.then(c=>{t.removeEventListener("abort",s),o(c)},c=>{t.removeEventListener("abort",s),i(c)})})}function yr(e,t){const n=M.get(e);n&&(M.delete(e),clearTimeout(n.timeout),n.reject(t))}function ht(e,t){const n=U.get(e);n&&(U.delete(e),clearTimeout(n.timeout),n.reject(t))}function vr(e,t,n=null){if(!t)return e;if(t.aborted){const r=new DOMException("Aborted","AbortError");return n&&le(n),n&&ht(n,r),Promise.reject(r)}return new Promise((r,o)=>{const i=()=>{const s=new DOMException("Aborted","AbortError");n&&le(n),n&&ht(n,s),o(s)};t.addEventListener("abort",i,{once:!0}),e.then(s=>{t.removeEventListener("abort",i),r(s)},s=>{t.removeEventListener("abort",i),o(s)})})}function br(){return lr(crypto.randomUUID())}function It(e,t){if(t?.signal?.aborted)return Promise.reject(new DOMException("Aborted","AbortError"));const n=ie.get(e);if(n)return wt(n,t?.signal);let r,o=null;try{new URL(e).protocol==="data:"?r=pr(e):(o=crypto.randomUUID(),r=dr(e,o))}catch{return Promise.reject(new Error(`invalid URL: ${e}`))}return r=r.finally(()=>{ie.delete(e)}),ie.set(e,r),wt(r,t?.signal,o,o?i=>yr(o,i):void 0)}function mr(e,t){if(e.length===0)return Promise.reject(new Error("invalid-request: urls must be non-empty"));if(t?.signal?.aborted)return Promise.reject(new DOMException("Aborted","AbortError"));const n=crypto.randomUUID(),r=fr(e,n);return vr(r,t?.signal,n)}function wr(e){const t={url:"",revoke:()=>{}};let n=null,r=!1;const o=It(e).then(i=>{if(!r)return n=URL.createObjectURL(i),t.url=n,n});return t.revoke=()=>{r||(r=!0,n&&(URL.revokeObjectURL(n),n=null))},Object.defineProperty(t,"ready",{value:o,enumerable:!1,writable:!1}),t}function hr(e){if(!(!e||e.length===0))for(const t of e)ie.set(t.url,Promise.resolve(t.blob))}function gr(e,t,n,r){const o=Array.isArray(e)?e:[e],i=crypto.randomUUID();function s(l){if(l.source!==window.parent)return;const d=l.data;if(typeof d!="object"||d===null||typeof d.type!="string"||!d.type.startsWith("relay."))return;const m=d;if(!(!("subId"in m)||m.subId!==i))if(d.type==="relay.event"){const lt=d;hr(lt.resources),t(lt.event)}else d.type==="relay.eose"?n():d.type==="relay.closed"&&window.removeEventListener("message",s)}window.addEventListener("message",s);const c={type:"relay.subscribe",id:crypto.randomUUID(),subId:i,filters:o,...r?.relay?{relay:r.relay}:{}};return u(c),{close(){const l={type:"relay.close",id:crypto.randomUUID(),subId:i};u(l),window.removeEventListener("message",s)}}}function Er(e,t){const n=crypto.randomUUID();return new Promise((r,o)=>{function i(c){if(c.source!==window.parent)return;const l=c.data;if(typeof l!="object"||l===null||typeof l.type!="string"||l.type!=="relay.publish.result"&&l.type!=="relay.publish.error")return;const d=l;d.id===n&&(window.removeEventListener("message",i),d.error||l.type==="relay.publish.error"?o(new Error(d.error||"relay:write denied")):d.event?r(d.event):o(new Error("relay.publish.result missing event")))}window.addEventListener("message",i),u({type:"relay.publish",id:n,event:e})})}function Mr(e,t,n="nip44"){const r=crypto.randomUUID();return new Promise((o,i)=>{function s(l){if(l.source!==window.parent)return;const d=l.data;if(typeof d!="object"||d===null||typeof d.type!="string"||d.type!=="relay.publishEncrypted.result")return;const m=d;m.id===r&&(window.removeEventListener("message",s),m.error?i(new Error(m.error)):m.event?o(m.event):i(new Error("relay.publishEncrypted.result missing event")))}window.addEventListener("message",s),u({type:"relay.publishEncrypted",id:r,event:e,recipient:t,encryption:n})})}function Ur(e){const t=Array.isArray(e)?e:[e],n=crypto.randomUUID();return new Promise((r,o)=>{function i(c){if(c.source!==window.parent)return;const l=c.data;if(typeof l!="object"||l===null||typeof l.type!="string"||l.type!=="relay.query.result")return;const d=l;d.id===n&&(window.removeEventListener("message",i),d.error?o(new Error(d.error)):r(Array.isArray(d.events)?d.events:[]))}window.addEventListener("message",i),u({type:"relay.query",id:n,filters:t})})}var Sr=3e4,K=new Map,Fe=new Set,Tr=new Set(["identity.getPublicKey.result","identity.getRelays.result","identity.getProfile.result","identity.getFollows.result","identity.getList.result","identity.getZaps.result","identity.getMutes.result","identity.getBlocked.result","identity.getBadges.result","identity.changed","identity.getPublicKey","identity.getRelays","identity.getProfile","identity.getFollows","identity.getList","identity.getZaps","identity.getMutes","identity.getBlocked","identity.getBadges"]);function Ir(e){return Tr.has(e.type)}function $r(e){if(Ir(e))switch(e.type){case"identity.getPublicKey.result":Rr(e.id,e.pubkey);return;case"identity.changed":Dr(e.pubkey);return;case"identity.getRelays.result":w(e.id,e.relays,e.error);return;case"identity.getProfile.result":w(e.id,e.profile,e.error);return;case"identity.getFollows.result":w(e.id,e.pubkeys,e.error);return;case"identity.getList.result":w(e.id,e.entries,e.error);return;case"identity.getZaps.result":w(e.id,e.zaps,e.error);return;case"identity.getMutes.result":w(e.id,e.pubkeys,e.error);return;case"identity.getBlocked.result":w(e.id,e.pubkeys,e.error);return;case"identity.getBadges.result":w(e.id,e.badges,e.error);return;case"identity.getPublicKey":case"identity.getRelays":case"identity.getProfile":case"identity.getFollows":case"identity.getList":case"identity.getZaps":case"identity.getMutes":case"identity.getBlocked":case"identity.getBadges":return;default:return}}function Rr(e,t){const n=K.get(e);n&&(K.delete(e),clearTimeout(n.timeout),n.resolve(t))}function w(e,t,n){const r=K.get(e);r&&(K.delete(e),clearTimeout(r.timeout),n?r.reject(new Error(n)):r.resolve(t))}function Dr(e){if(typeof e=="string")for(const t of Fe)t(e)}function b(e){return new Promise((t,n)=>{const r=setTimeout(()=>{K.delete(e.id)&&n(new Error(`${e.type} timed out`))},Sr);K.set(e.id,{resolve:t,reject:n,timeout:r}),u(e)})}function Pr(){const e={type:"identity.getPublicKey",id:crypto.randomUUID()};return b(e)}function kr(e){Fe.add(e);let t=!1;return{close(){t||(t=!0,Fe.delete(e))}}}function Cr(){const e={type:"identity.getRelays",id:crypto.randomUUID()};return b(e)}function Ar(){const e={type:"identity.getProfile",id:crypto.randomUUID()};return b(e)}function xr(){const e={type:"identity.getFollows",id:crypto.randomUUID()};return b(e)}function Lr(e){const t={type:"identity.getList",id:crypto.randomUUID(),listType:e};return b(t)}function Or(){const e={type:"identity.getZaps",id:crypto.randomUUID()};return b(e)}function _r(){const e={type:"identity.getMutes",id:crypto.randomUUID()};return b(e)}function Nr(){const e={type:"identity.getBlocked",id:crypto.randomUUID()};return b(e)}function qr(){const e={type:"identity.getBadges",id:crypto.randomUUID()};return b(e)}var Br=3e4,de=new Map,ze=new Set,jr=new Set(["theme.get.result","theme.changed","theme.get"]);function Kr(e){return jr.has(e.type)}function Hr(e){if(Kr(e))switch(e.type){case"theme.get.result":Qr(e.id,e.theme,e.error);return;case"theme.changed":Fr(e.theme);return;case"theme.get":return;default:return}}function Qr(e,t,n){const r=de.get(e);r&&(de.delete(e),clearTimeout(r.timeout),n?r.reject(new Error(n)):r.resolve(t))}function Fr(e){for(const t of ze)t(e)}function zr(e){return new Promise((t,n)=>{const r=setTimeout(()=>{de.delete(e.id)&&n(new Error(`${e.type} timed out`))},Br);de.set(e.id,{resolve:t,reject:n,timeout:r}),u(e)})}function Vr(){const e={type:"theme.get",id:crypto.randomUUID()};return zr(e)}function Gr(e){ze.add(e);let t=!1;return{close(){t||(t=!0,ze.delete(e))}}}var B=new Map;function Wr(e,t=[],n=""){let r;try{r=n?JSON.parse(n):void 0}catch{r=n||void 0}const o={type:"inc.emit",topic:e,...r!==void 0?{payload:r}:{}};u(o)}function Zr(e,t){const n=(o,i)=>{const s={id:"",pubkey:i,created_at:Math.floor(Date.now()/1e3),kind:0,tags:[["t",e]],content:typeof o=="string"?o:JSON.stringify(o??{}),sig:""};t(o,s)};B.has(e)||B.set(e,[]),B.get(e).push(n);const r={type:"inc.subscribe",id:crypto.randomUUID(),topic:e};return u(r),{close(){const o=B.get(e);if(o){const s=o.indexOf(n);s>=0&&o.splice(s,1),o.length===0&&B.delete(e)}u({type:"inc.unsubscribe",topic:e})}}}function Yr(e){const t=B.get(e.topic);if(t){const n=e.payload??{},r=e.sender??"";for(const o of t)o(n,r)}}function Ne(e,t){return e.type===t}var $t=3e4,Jr="napplet-config-schema",se=null,fe=null,k=new Set,pe=new Set,Y=new Map,J=new Map,qe=!1;function Xr(e){Ne(e,"config.registerSchema.result")?eo(e):Ne(e,"config.values")?to(e):Ne(e,"config.schemaError")&&no(e)}function eo(e){const t=J.get(e.id);if(t)if(J.delete(e.id),e.ok)se=t.schema,t.resolve();else{const n=e.code??"invalid-schema",r=e.error??"schema rejected";t.reject(new Error(`${n}: ${r}`))}}function to(e){if(fe=e.values,typeof e.id=="string"){const t=Y.get(e.id);if(!t)return;Y.delete(e.id),t.resolve(e.values);return}for(const t of k)try{t(e.values)}catch{}}function no(e){const t={code:e.code,error:e.error};for(const n of pe)try{n(t)}catch{}}function ro(){if(typeof document>"u")return null;const e=document.querySelector(`meta[name="${Jr}"]`);if(!e)return null;const t=e.getAttribute("content");if(!t)return null;try{return JSON.parse(t)}catch{return null}}function Rt(e,t){const n=crypto.randomUUID();return new Promise((r,o)=>{J.set(n,{resolve:r,reject:o,schema:e}),u(t===void 0?{type:"config.registerSchema",id:n,schema:e}:{type:"config.registerSchema",id:n,schema:e,version:t}),setTimeout(()=>{J.delete(n)&&o(new Error("config.registerSchema timed out"))},$t)})}function Dt(){const e=crypto.randomUUID();return new Promise((t,n)=>{Y.set(e,{resolve:t,reject:n}),u({type:"config.get",id:e}),setTimeout(()=>{Y.delete(e)&&n(new Error("config.get timed out"))},$t)})}function Pt(e){const t=k.size===0;if(k.add(e),t)u({type:"config.subscribe"});else if(fe!==null){const n=fe;queueMicrotask(()=>{if(k.has(e)&&n!==null)try{e(n)}catch{}})}return{close(){k.delete(e)&&k.size===0&&u({type:"config.unsubscribe"})}}}function kt(e){const t=e?.section;u(t===void 0?{type:"config.openSettings"}:{type:"config.openSettings",section:t})}function Ct(e){return pe.add(e),()=>{pe.delete(e)}}function oo(){if(qe)return()=>{};se=ro();const e=window,t=e.napplet??(e.napplet={}),n={registerSchema:Rt,get:Dt,subscribe:Pt,openSettings:kt,onSchemaError:Ct};return Object.defineProperty(n,"schema",{get:()=>se,enumerable:!0,configurable:!1}),t.config=n,qe=!0,()=>{k.clear(),pe.clear(),Y.clear(),J.clear(),fe=null,se=null,t.config===n&&delete t.config,qe=!1}}var tt=3e4,ye=new Map,ve=new Map,be=new Map,Ve=new Set;function te(e,t){return e.type===t}function io(e){const t=ye.get(e.id);if(t){if(ye.delete(e.id),clearTimeout(t.timeout),e.error!==void 0){t.reject(new Error(e.error));return}t.resolve(Array.isArray(e.servers)?e.servers:[])}}function so(e){const t=ve.get(e.id);if(t){if(ve.delete(e.id),clearTimeout(t.timeout),e.error!==void 0){t.reject(new Error(e.error));return}if(e.message===void 0){t.reject(new Error("cvm.request.result missing message"));return}t.resolve(e.message)}}function uo(e){const t=be.get(e.id);if(t){if(be.delete(e.id),clearTimeout(t.timeout),e.error!==void 0){t.reject(new Error(e.error));return}t.resolve()}}function ao(e){if(!(!e.server||!e.message))for(const t of Ve)t(e.server,e.message)}function co(e){te(e,"cvm.discover.result")?io(e):te(e,"cvm.request.result")?so(e):te(e,"cvm.close.result")?uo(e):te(e,"cvm.event")&&ao(e)}function lo(e){const t=crypto.randomUUID();return new Promise((n,r)=>{const o=setTimeout(()=>{ye.delete(t)&&r(new Error("cvm.discover timed out"))},tt);ye.set(t,{resolve:n,reject:r,timeout:o});const i={type:"cvm.discover",id:t,...e===void 0?{}:{query:e}};u(i)})}function At(e,t,n){const r=crypto.randomUUID(),o=n?.timeoutMs??tt;return new Promise((i,s)=>{const c=setTimeout(()=>{ve.delete(r)&&s(new Error("cvm.request timed out"))},o);ve.set(r,{resolve:i,reject:s,timeout:c});const l={type:"cvm.request",id:r,server:e,message:t,...n===void 0?{}:{options:n}};u(l)})}async function xe(e,t,n,r){const o=await At(e,{jsonrpc:"2.0",id:crypto.randomUUID(),method:t,...n===void 0?{}:{params:n}},r);if(o.error!==void 0){const i=o.error;throw new Error(i?.message?`${t}: ${i.message}`:`${t} failed`)}return o.result}async function fo(e,t){return(await xe(e,"tools/list",void 0,t))?.tools??[]}function po(e,t,n,r){return xe(e,"tools/call",{name:t,...n===void 0?{}:{arguments:n}},r)}async function yo(e,t){return(await xe(e,"resources/list",void 0,t))?.resources??[]}async function vo(e,t,n){const o=(await xe(e,"resources/read",{uri:t},n))?.contents?.[0];if(!o)throw new Error(`resources/read returned no contents for ${t}`);return o}function bo(e){const t=crypto.randomUUID();return new Promise((n,r)=>{const o=setTimeout(()=>{be.delete(t)&&r(new Error("cvm.close timed out"))},tt);be.set(t,{resolve:n,reject:r,timeout:o}),u({type:"cvm.close",id:t,server:e})})}function mo(e){return Ve.add(e),{close(){Ve.delete(e)}}}var Le=3e4,me=new Map,we=new Map,he=new Map,ge=new Map,H=new Map;function T(e,t){return e.type===t}function wo(e){const t=me.get(e.id);if(!t)return;me.delete(e.id),clearTimeout(t.timeout);const n={relays:Array.isArray(e.relays)?e.relays:[]};e.event!==void 0&&(n.event=e.event),e.incomplete!==void 0&&(n.incomplete=e.incomplete),e.error!==void 0&&(n.error=e.error),t.resolve(n)}function ho(e){const t=we.get(e.id);if(!t)return;we.delete(e.id),clearTimeout(t.timeout);const n={events:Array.isArray(e.events)?e.events:[],relays:e.relays??{}};e.incomplete!==void 0&&(n.incomplete=e.incomplete),e.error!==void 0&&(n.error=e.error),t.resolve(n)}function go(e){const t=he.get(e.id);if(!t)return;he.delete(e.id),clearTimeout(t.timeout);const n={ok:e.ok};e.event!==void 0&&(n.event=e.event),e.eventId!==void 0&&(n.eventId=e.eventId),e.relays!==void 0&&(n.relays=e.relays),e.error!==void 0&&(n.error=e.error),t.resolve(n)}function Eo(e){const t=ge.get(e.id);if(t){if(ge.delete(e.id),clearTimeout(t.timeout),e.error!==void 0){t.reject(new Error(e.error));return}if(!e.plan){t.reject(new Error("outbox.resolveRelays.result missing plan"));return}t.resolve(e.plan)}}function Mo(e){const t=H.get(e.subId);if(t)for(const n of t.event)n(e.event,e.relay)}function Uo(e){const t=H.get(e.subId);if(t)for(const n of t.eose)n()}function So(e){const t=H.get(e.subId);if(t){for(const n of t.closed)n(e.reason);H.delete(e.subId)}}function To(e){T(e,"outbox.getEvent.result")?wo(e):T(e,"outbox.query.result")?ho(e):T(e,"outbox.publish.result")?go(e):T(e,"outbox.resolveRelays.result")?Eo(e):T(e,"outbox.event")?Mo(e):T(e,"outbox.eose")?Uo(e):T(e,"outbox.closed")&&So(e)}function Io(e,t){const n=crypto.randomUUID(),r=t?.timeoutMs??Le;return new Promise((o,i)=>{const s=setTimeout(()=>{me.delete(n)&&i(new Error("outbox.getEvent timed out"))},r);me.set(n,{resolve:o,reject:i,timeout:s});const c={type:"outbox.getEvent",id:n,eventId:e,...t===void 0?{}:{options:t}};u(c)})}function $o(e,t){const n=crypto.randomUUID(),r=t?.timeoutMs??Le;return new Promise((o,i)=>{const s=setTimeout(()=>{we.delete(n)&&i(new Error("outbox.query timed out"))},r);we.set(n,{resolve:o,reject:i,timeout:s});const c={type:"outbox.query",id:n,filters:e,...t===void 0?{}:{options:t}};u(c)})}function Ro(e,t){const n=crypto.randomUUID(),r=crypto.randomUUID(),o={event:new Set,eose:new Set,closed:new Set};H.set(r,o);const i={type:"outbox.subscribe",id:n,subId:r,filters:e,...t===void 0?{}:{options:t}};u(i);function s(c,l){c==="event"?o.event.add(l):c==="eose"?o.eose.add(l):c==="closed"&&o.closed.add(l)}return{on:s,close(){if(!H.delete(r))return;const c={type:"outbox.close",id:crypto.randomUUID(),subId:r};u(c)}}}function Do(e,t){const n=crypto.randomUUID();return new Promise((r,o)=>{const i=setTimeout(()=>{he.delete(n)&&o(new Error("outbox.publish timed out"))},Le);he.set(n,{resolve:r,reject:o,timeout:i});const s={type:"outbox.publish",id:n,event:e,...t===void 0?{}:{options:t}};u(s)})}function Po(e){const t=crypto.randomUUID();return new Promise((n,r)=>{const o=setTimeout(()=>{ge.delete(t)&&r(new Error("outbox.resolveRelays timed out"))},Le);ge.set(t,{resolve:n,reject:r,timeout:o}),u({type:"outbox.resolveRelays",id:t,target:e})})}var nt=3e4,Ee=new Map,Me=new Map,Ue=new Map,Ge=new Set;function ne(e,t){return e.type===t}function ko(e){const t=Ee.get(e.id);if(t){if(Ee.delete(e.id),clearTimeout(t.timeout),e.info!==void 0){t.resolve(e.info);return}t.reject(new Error(e.error??"upload info unavailable"))}}function Co(e){const t=Me.get(e.id);if(t){if(Me.delete(e.id),clearTimeout(t.timeout),e.result!==void 0){t.resolve(e.result);return}t.reject(new Error(e.error??"upload failed"))}}function Ao(e){const t=Ue.get(e.id);if(t){if(Ue.delete(e.id),clearTimeout(t.timeout),e.status!==void 0){t.resolve(e.status);return}t.reject(new Error(e.error??"upload status unavailable"))}}function xo(e){if(e.status)for(const t of Ge)t(e.status)}function Lo(e){ne(e,"upload.info.result")?ko(e):ne(e,"upload.upload.result")?Co(e):ne(e,"upload.status.result")?Ao(e):ne(e,"upload.status.changed")&&xo(e)}function Oo(){const e=crypto.randomUUID();return new Promise((t,n)=>{const r=setTimeout(()=>{Ee.delete(e)&&n(new Error("upload.info timed out"))},nt);Ee.set(e,{resolve:t,reject:n,timeout:r}),u({type:"upload.info",id:e})})}function _o(e){const t=crypto.randomUUID();return new Promise((n,r)=>{const o=setTimeout(()=>{Me.delete(t)&&r(new Error("upload.upload timed out"))},nt);Me.set(t,{resolve:n,reject:r,timeout:o}),u({type:"upload.upload",id:t,request:e})})}function No(e){const t=crypto.randomUUID();return new Promise((n,r)=>{const o=setTimeout(()=>{Ue.delete(t)&&r(new Error("upload.status timed out"))},nt);Ue.set(t,{resolve:n,reject:r,timeout:o}),u({type:"upload.status",id:t,uploadId:e})})}function qo(e){return Ge.add(e),{close(){Ge.delete(e)}}}var rt=3e4,Se=new Map,Te=new Map,Ie=new Map,We=new Set;function re(e,t){return e.type===t}function Bo(e){const t=Se.get(e.id);if(t){if(Se.delete(e.id),clearTimeout(t.timeout),e.result!==void 0){t.resolve(e.result);return}t.reject(new Error(e.error??"invoke failed"))}}function jo(e){const t=Te.get(e.id);if(t){if(Te.delete(e.id),clearTimeout(t.timeout),e.availability!==void 0){t.resolve(e.availability);return}t.reject(new Error(e.error??"intent availability unavailable"))}}function Ko(e){const t=Ie.get(e.id);if(t){if(Ie.delete(e.id),clearTimeout(t.timeout),e.handlers!==void 0){t.resolve(e.handlers);return}t.reject(new Error(e.error??"intent handlers unavailable"))}}function Ho(e){if(e.availability)for(const t of We)t(e.availability)}function Qo(e){re(e,"intent.invoke.result")?Bo(e):re(e,"intent.available.result")?jo(e):re(e,"intent.handlers.result")?Ko(e):re(e,"intent.changed")&&Ho(e)}function xt(e){const t=crypto.randomUUID();return new Promise((n,r)=>{const o=setTimeout(()=>{Se.delete(t)&&r(new Error("intent.invoke timed out"))},rt);Se.set(t,{resolve:n,reject:r,timeout:o}),u({type:"intent.invoke",id:t,request:e})})}function Fo(e,t,n){return xt({archetype:e,action:"open",payload:t,...n})}function zo(e){const t=crypto.randomUUID();return new Promise((n,r)=>{const o=setTimeout(()=>{Te.delete(t)&&r(new Error("intent.available timed out"))},rt);Te.set(t,{resolve:n,reject:r,timeout:o}),u({type:"intent.available",id:t,archetype:e})})}function Vo(){const e=crypto.randomUUID();return new Promise((t,n)=>{const r=setTimeout(()=>{Ie.delete(e)&&n(new Error("intent.handlers timed out"))},rt);Ie.set(e,{resolve:t,reject:n,timeout:r}),u({type:"intent.handlers",id:e})})}function Go(e){return We.add(e),{close(){We.delete(e)}}}var Wo=3e4,$e=new Map,Ze=new Set,Zo=new Set(["webrtc.open","webrtc.open.result","webrtc.send","webrtc.send.result","webrtc.close","webrtc.close.result","webrtc.event"]);function Yo(e){return Zo.has(e.type)}function ot(e,t,n){return new Promise((r,o)=>{const i=setTimeout(()=>{$e.delete(e.id)&&o(new Error(`${e.type} timed out`))},Wo);$e.set(e.id,{resolve:r,reject:o,timeout:i,resultType:t,project:n}),u(e)})}function it(e,t){throw"error"in e&&e.error?new Error(e.error):new Error(t)}function Jo(e){for(const t of Ze)t(e)}function Xo(e){if(!Yo(e))return;if(e.type==="webrtc.event"){Jo(e.event);return}if(!("id"in e)||typeof e.id!="string")return;const t=$e.get(e.id);if(!(!t||e.type!==t.resultType)){$e.delete(e.id),clearTimeout(t.timeout);try{t.resolve(t.project(e))}catch(n){t.reject(n instanceof Error?n:new Error(String(n)))}}}function ei(e){return ot({type:"webrtc.open",id:crypto.randomUUID(),request:e},"webrtc.open.result",t=>{if(t.type==="webrtc.open.result"&&t.session)return{session:t.session};it(t,"webrtc open failed")})}function ti(e,t){return ot({type:"webrtc.send",id:crypto.randomUUID(),sessionId:e,payload:t},"webrtc.send.result",n=>{n.type==="webrtc.send.result"&&!n.error||it(n,"webrtc send failed")})}function ni(e,t){return ot({type:"webrtc.close",id:crypto.randomUUID(),sessionId:e,...t?{reason:t}:{}},"webrtc.close.result",n=>{n.type==="webrtc.close.result"&&!n.error||it(n,"webrtc close failed")})}function ri(e){return Ze.add(e),{close(){Ze.delete(e)}}}var oi=3e4,Re=new Map,Ye=new Set,ii=new Set(["ble.open","ble.open.result","ble.services","ble.services.result","ble.read","ble.read.result","ble.write","ble.write.result","ble.subscribe","ble.subscribe.result","ble.unsubscribe","ble.unsubscribe.result","ble.close","ble.close.result","ble.event"]);function si(e){return ii.has(e.type)}function A(e,t,n){return new Promise((r,o)=>{const i=setTimeout(()=>{Re.delete(e.id)&&o(new Error(`${e.type} timed out`))},oi);Re.set(e.id,{resolve:r,reject:o,timeout:i,resultType:t,project:n}),u(e)})}function x(e,t){throw"error"in e&&e.error?new Error(e.error):new Error(t)}function ui(e){for(const t of Ye)t(e)}function ai(e){if(!si(e))return;if(e.type==="ble.event"){ui(e.event);return}if(!("id"in e)||typeof e.id!="string")return;const t=Re.get(e.id);if(!(!t||e.type!==t.resultType)){Re.delete(e.id),clearTimeout(t.timeout);try{t.resolve(t.project(e))}catch(n){t.reject(n instanceof Error?n:new Error(String(n)))}}}function ci(e){return A({type:"ble.open",id:crypto.randomUUID(),request:e},"ble.open.result",t=>{if(t.type==="ble.open.result"&&t.session)return{session:t.session};x(t,"ble open failed")})}function li(e){return A({type:"ble.services",id:crypto.randomUUID(),sessionId:e},"ble.services.result",t=>{if(t.type==="ble.services.result"&&t.services!==void 0)return t.services;x(t,"ble services unavailable")})}function di(e,t){return A({type:"ble.read",id:crypto.randomUUID(),sessionId:e,target:t},"ble.read.result",n=>{if(n.type==="ble.read.result"&&n.data!==void 0)return n.data;x(n,"ble read failed")})}function fi(e,t,n,r){return A({type:"ble.write",id:crypto.randomUUID(),sessionId:e,target:t,data:n,...r?{options:r}:{}},"ble.write.result",o=>{o.type==="ble.write.result"&&!o.error||x(o,"ble write failed")})}function pi(e,t){return A({type:"ble.subscribe",id:crypto.randomUUID(),sessionId:e,target:t},"ble.subscribe.result",n=>{n.type==="ble.subscribe.result"&&!n.error||x(n,"ble subscribe failed")})}function yi(e,t){return A({type:"ble.unsubscribe",id:crypto.randomUUID(),sessionId:e,target:t},"ble.unsubscribe.result",n=>{n.type==="ble.unsubscribe.result"&&!n.error||x(n,"ble unsubscribe failed")})}function vi(e,t){return A({type:"ble.close",id:crypto.randomUUID(),sessionId:e,...t?{reason:t}:{}},"ble.close.result",n=>{n.type==="ble.close.result"&&!n.error||x(n,"ble close failed")})}function bi(e){return Ye.add(e),{close(){Ye.delete(e)}}}var mi=3e4,De=new Map;function wi(e,t){return e.type===t}function hi(e){const t=De.get(e.id);if(t){if(De.delete(e.id),clearTimeout(t.timeout),e.status==="opened"||e.status==="denied"){t.resolve({status:e.status});return}t.reject(new Error(e.error??"link open failed"))}}function gi(e){wi(e,"link.open.result")&&hi(e)}function Ei(e,t){const n=crypto.randomUUID();return new Promise((r,o)=>{const i=setTimeout(()=>{De.delete(n)&&o(new Error("link.open timed out"))},mi);De.set(n,{resolve:r,reject:o,timeout:i});const s={type:"link.open",id:n,url:e,...t?{options:t}:{}};u(s)})}var Mi=3e4,Lt=new Map,Ot=new Map,_t=new Map;function Be(e,t){return e.type===t}function st(e,t,n,r,o){const i=e.get(t);if(i){if(e.delete(t),clearTimeout(i.timeout),n!==void 0){i.resolve(n);return}i.reject(new Error(o??r))}}function Nt(e){const t={ok:e.ok};return e.eventId!==void 0&&(t.eventId=e.eventId),e.event!==void 0&&(t.event=e.event),e.added!==void 0&&(t.added=e.added),e.removed!==void 0&&(t.removed=e.removed),e.skipped!==void 0&&(t.skipped=e.skipped),e.error!==void 0&&(t.error=e.error),e.reason!==void 0&&(t.reason=e.reason),e.supported!==void 0&&(t.supported=e.supported),t}function Ui(e){st(Lt,e.id,e.lists,"lists.supported failed",e.error)}function Si(e){st(Ot,e.id,Nt(e),"lists.add failed")}function Ti(e){st(_t,e.id,Nt(e),"lists.remove failed")}function Ii(e){Be(e,"lists.supported.result")?Ui(e):Be(e,"lists.add.result")?Si(e):Be(e,"lists.remove.result")&&Ti(e)}function ut(e,t,n){const r=crypto.randomUUID();return new Promise((o,i)=>{const s=setTimeout(()=>{t.delete(r)&&i(new Error(`${e} timed out`))},Mi);t.set(r,{resolve:o,reject:i,timeout:s}),u({type:e,id:r,...n})})}function $i(){return ut("lists.supported",Lt,{})}function Ri(e,t,n){return ut("lists.add",Ot,{list:e,items:t,...n?{options:n}:{}})}function Di(e,t,n){return ut("lists.remove",_t,{list:e,items:t,...n?{options:n}:{}})}var Pi=3e4,qt=new Map,Bt=new Map,jt=new Map,Kt=new Map,Ht=new Map,Qt=new Map,Ft=new Map,zt=new Map;function h(e,t){return e.type===t}function ki(e){const{type:t,id:n,...r}=e;return r}function g(e,t,n){const r=e.get(t.id);if(r){if(e.delete(t.id),clearTimeout(r.timeout),typeof t.ok=="boolean"){r.resolve(ki(t));return}r.reject(new Error(t.error??n))}}function S(e,t,n){const r=crypto.randomUUID();return new Promise((o,i)=>{const s=setTimeout(()=>{e.delete(r)&&i(new Error(t))},Pi);e.set(r,{resolve:o,reject:i,timeout:s}),u(n(r))})}function Ci(e){h(e,"common.encodeNip19.result")?g(qt,e,"common.encodeNip19 failed"):h(e,"common.decodeNip19.result")?g(Bt,e,"common.decodeNip19 failed"):h(e,"common.getProfile.result")?g(jt,e,"common.getProfile failed"):h(e,"common.follows.result")?g(Kt,e,"common.follows failed"):h(e,"common.follow.result")?g(Ht,e,"common.follow failed"):h(e,"common.unfollow.result")?g(Qt,e,"common.unfollow failed"):h(e,"common.react.result")?g(Ft,e,"common.react failed"):h(e,"common.report.result")&&g(zt,e,"common.report failed")}function Ai(e){return S(qt,"common.encodeNip19 timed out",t=>({type:"common.encodeNip19",id:t,input:e}))}function xi(e){return S(Bt,"common.decodeNip19 timed out",t=>({type:"common.decodeNip19",id:t,value:e}))}function Li(e){return S(jt,"common.getProfile timed out",t=>({type:"common.getProfile",id:t,target:e}))}function Oi(){return S(Kt,"common.follows timed out",e=>({type:"common.follows",id:e}))}function _i(...e){return S(Ht,"common.follow timed out",t=>({type:"common.follow",id:t,pubkeys:e}))}function Ni(...e){return S(Qt,"common.unfollow timed out",t=>({type:"common.unfollow",id:t,pubkeys:e}))}function qi(e,t,n){return S(Ft,"common.react timed out",r=>({type:"common.react",id:r,targetEventId:e,reaction:t,...n===void 0?{}:{customEmojiHref:n}}))}function Bi(e,t,n){return S(zt,"common.report timed out",r=>({type:"common.report",id:r,target:e,reason:t,text:n}))}var at=3e4,Pe=new Map,ke=new Map,Ce=new Map,Je=new Set;function oe(e,t){return e.type===t}function ji(e){const t=Pe.get(e.id);if(t){if(Pe.delete(e.id),clearTimeout(t.timeout),e.session!==void 0){t.resolve({session:e.session});return}t.reject(new Error(e.error??"serial open failed"))}}function Ki(e){const t=ke.get(e.id);if(t){if(ke.delete(e.id),clearTimeout(t.timeout),e.error){t.reject(new Error(e.error));return}t.resolve()}}function Hi(e){const t=Ce.get(e.id);if(t){if(Ce.delete(e.id),clearTimeout(t.timeout),e.error){t.reject(new Error(e.error));return}t.resolve()}}function Qi(e){if(e.event)for(const t of Je)t(e.event)}function Fi(e){oe(e,"serial.open.result")?ji(e):oe(e,"serial.write.result")?Ki(e):oe(e,"serial.close.result")?Hi(e):oe(e,"serial.event")&&Qi(e)}function zi(e){const t=crypto.randomUUID();return new Promise((n,r)=>{const o=setTimeout(()=>{Pe.delete(t)&&r(new Error("serial.open timed out"))},at);Pe.set(t,{resolve:n,reject:r,timeout:o}),u({type:"serial.open",id:t,request:e})})}function Vi(e,t){const n=crypto.randomUUID();return new Promise((r,o)=>{const i=setTimeout(()=>{ke.delete(n)&&o(new Error("serial.write timed out"))},at);ke.set(n,{resolve:r,reject:o,timeout:i});const s={type:"serial.write",id:n,sessionId:e,data:Array.from(t)};u(s)})}function Gi(e,t){const n=crypto.randomUUID();return new Promise((r,o)=>{const i=setTimeout(()=>{Ce.delete(n)&&o(new Error("serial.close timed out"))},at);Ce.set(n,{resolve:r,reject:o,timeout:i});const s={type:"serial.close",id:n,sessionId:e,...t===void 0?{}:{reason:t}};u(s)})}function Wi(e){return Je.add(e),{close(){Je.delete(e)}}}var Zi=3e4,Vt=new Map,Gt=new Map,Wt=new Map,Zt=new Map,Yt=new Map,Jt=new Map,Xe=new Set;function I(e,t){return e.type===t}function Q(e,t,n){return new Promise((r,o)=>{const i=setTimeout(()=>{e.delete(t)&&o(new Error(`${n} timed out`))},Zi);e.set(t,{resolve:r,reject:o,timeout:i})})}function F(e,t,n,r,o){const i=e.get(t);if(!i)return;if(e.delete(t),clearTimeout(i.timeout),n){i.reject(new Error(n));return}const s=o();if(s===void 0){i.reject(new Error(r));return}i.resolve(s)}function Yi(e){F(Vt,e.id,e.error,"dm.status.result missing status",()=>{if(!(typeof e.available!="boolean"||!Array.isArray(e.implementations)||!Array.isArray(e.capabilities)))return{available:e.available,...e.ownerPubkey===void 0?{}:{ownerPubkey:e.ownerPubkey},implementations:e.implementations,capabilities:e.capabilities}})}function Ji(e){F(Gt,e.id,e.error,"dm.conversations.result missing conversations",()=>{if(Array.isArray(e.conversations))return{conversations:e.conversations,...e.cursor===void 0?{}:{cursor:e.cursor}}})}function Xi(e){F(Wt,e.id,e.error,"dm.messages.result missing messages",()=>{if(Array.isArray(e.messages))return{messages:e.messages,...e.cursor===void 0?{}:{cursor:e.cursor}}})}function es(e){F(Zt,e.id,e.error,"dm.send.result missing message",()=>{if(!(typeof e.ok!="boolean"||e.message===void 0))return{ok:e.ok,message:e.message}})}function ts(e){F(Yt,e.id,e.error,"dm.subscribe.result missing subscriptionId",()=>{if(typeof e.subscriptionId=="string")return{subscriptionId:e.subscriptionId}})}function ns(e){F(Jt,e.id,e.error,"dm.unsubscribe.result missing ok",()=>{if(typeof e.ok=="boolean")return{ok:e.ok}})}function rs(e){if(!(!e.message||typeof e.subscriptionId!="string"))for(const t of Xe)t(e.message,e.subscriptionId)}function os(e){I(e,"dm.status.result")?Yi(e):I(e,"dm.conversations.result")?Ji(e):I(e,"dm.messages.result")?Xi(e):I(e,"dm.send.result")?es(e):I(e,"dm.subscribe.result")?ts(e):I(e,"dm.unsubscribe.result")?ns(e):I(e,"dm.message")&&rs(e)}function is(){const e=crypto.randomUUID(),t=Q(Vt,e,"dm.status");return u({type:"dm.status",id:e}),t}function ss(e={}){const t=crypto.randomUUID(),n=Q(Gt,t,"dm.conversations"),r={type:"dm.conversations",id:t,...e};return u(r),n}function us(e){const t=crypto.randomUUID(),n=Q(Wt,t,"dm.messages"),r={type:"dm.messages",id:t,...e};return u(r),n}function as(e){const t=crypto.randomUUID(),n=Q(Zt,t,"dm.send"),r={type:"dm.send",id:t,...e};return u(r),n}function cs(e={}){const t=crypto.randomUUID(),n=Q(Yt,t,"dm.subscribe"),r={type:"dm.subscribe",id:t,...e};return u(r),n}function ls(e){const t=crypto.randomUUID(),n=Q(Jt,t,"dm.unsubscribe");return u({type:"dm.unsubscribe",id:t,subscriptionId:e}),n}function ds(e){return Xe.add(e),{close(){Xe.delete(e)}}}var gt=new Set(cn),Et=new Set,Mt=!1,fs=[["keys.",Sn],["media.",xn],["notify.",Yn],["resource.",cr],["cvm.",co],["outbox.",To],["upload.",Lo],["intent.",Qo],["ble.",ai],["webrtc.",Xo],["link.",gi],["lists.",Ii],["common.",Ci],["serial.",Fi],["dm.",os],["identity.",$r],["theme.",Hr],["config.",Xr]];function ps(e){if(e.source!==window.parent)return;const t=e.data;if(typeof t!="object"||t===null||typeof t.type!="string")return;const n=t.type;if(n==="inc.event"){Yr(t);return}const r=t;for(const[o,i]of fs)if(n.startsWith(o)){i(r);return}}function ys(e){const t={};return e.has("relay")&&(t.relay={subscribe:gr,publish:Er,publishEncrypted:Mr,query:Ur}),e.has("inc")&&(t.inc={emit:Wr,on:Zr}),e.has("storage")&&(t.storage={getItem:f.getItem.bind(f),setItem:f.setItem.bind(f),removeItem:f.removeItem.bind(f),keys:f.keys.bind(f),instance:{getItem:f.instance.getItem.bind(f.instance),setItem:f.instance.setItem.bind(f.instance),removeItem:f.instance.removeItem.bind(f.instance),keys:f.instance.keys.bind(f.instance)}}),e.has("keys")&&(t.keys={registerAction:Tn,unregisterAction:In,onAction:$n}),e.has("media")&&(t.media={createSession:Ln,updateSession:On,destroySession:_n,reportState:Nn,reportCapabilities:qn,sendCommand:Bn,onCommand:jn,onState:Kn,onCapabilities:Hn,onControls:Qn}),e.has("notify")&&(t.notify={send:Jn,dismiss:Xn,badge:er,registerChannel:tr,requestPermission:nr,onAction:rr,onClicked:or,onDismissed:ir,onControls:sr}),e.has("identity")&&(t.identity={getPublicKey:Pr,onChanged:kr,getRelays:Cr,getProfile:Ar,getFollows:xr,getList:Lr,getZaps:Or,getMutes:_r,getBlocked:Nr,getBadges:qr}),e.has("theme")&&(t.theme={get:Vr,onChanged:Gr}),e.has("config")&&(t.config={registerSchema:Rt,get:Dt,subscribe:Pt,openSettings:kt,onSchemaError:Ct,schema:null}),e.has("resource")&&(t.resource={info:br,bytes:It,bytesMany:mr,bytesAsObjectURL:wr}),e.has("cvm")&&(t.cvm={discover:lo,request:At,listTools:fo,callTool:po,listResources:yo,readResource:vo,close:bo,onEvent:mo}),e.has("outbox")&&(t.outbox={getEvent:Io,query:$o,subscribe:Ro,publish:Do,resolveRelays:Po}),e.has("upload")&&(t.upload={info:Oo,upload:_o,status:No,onStatus:qo}),e.has("intent")&&(t.intent={invoke:xt,open:Fo,available:zo,handlers:Vo,onChanged:Go}),e.has("webrtc")&&(t.webrtc={open:ei,send:ti,close:ni,onEvent:ri}),e.has("ble")&&(t.ble={open:ci,services:li,read:di,write:fi,subscribe:pi,unsubscribe:yi,close:vi,onEvent:bi}),e.has("link")&&(t.link={open:Ei}),e.has("lists")&&(t.lists={supported:$i,add:Ri,remove:Di}),e.has("common")&&(t.common={encodeNip19:Ai,decodeNip19:xi,getProfile:Li,follows:Oi,follow:_i,unfollow:Ni,react:qi,report:Bi}),e.has("serial")&&(t.serial={open:zi,write:Vi,close:Gi,onEvent:Wi}),e.has("dm")&&(t.dm={status:is,conversations:ss,messages:us,send:as,subscribe:cs,unsubscribe:ls,onMessage:ds}),t}function vs(e){return e?new Set(e.filter(t=>gt.has(t))):new Set(gt)}function bs(e){if(!Et.has(e))switch(Et.add(e),e){case"relay":return;case"inc":return;case"storage":ar();return;case"keys":Rn();return;case"media":return;case"notify":return;case"identity":return;case"theme":return;case"config":oo();return;case"resource":return;case"cvm":return;case"outbox":return;case"upload":return;case"intent":return;case"ble":return;case"webrtc":return;case"link":return;case"lists":return;case"serial":return;case"common":return;case"dm":return}}function ms(e={}){const t=vs(e.domains),n=ys(t);window.napplet=n,Mt||(window.addEventListener("message",ps),Mt=!0);for(const r of t)bs(r);return n}ms();var Xt="relay";X(Xt,e=>{});var en="identity";X(en,e=>{});var tn="storage";X(tn,e=>{});var nn="notify";X(nn,e=>{});var ws="config",rn="resource";X(rn,e=>{});function hs(){const e=window;if(!e.napplet)throw new Error("window.napplet is unavailable -- runtime did not inject the napplet namespace");return e.napplet}function a(e){const n=hs()[e];if(!n)throw new Error(`window.napplet.${String(e)} is unavailable -- runtime did not inject this domain`);return n}var gs={subscribe(e,t,n,r){return a("relay").subscribe(e,t,n,r)},publish(e,t){return a("relay").publish(e,t)},publishEncrypted(e,t,n="nip44"){return a("relay").publishEncrypted(e,t,n)},query(e){return a("relay").query(e)}},Ut={getItem(e){return a("storage").getItem(e)},setItem(e,t){return a("storage").setItem(e,t)},removeItem(e){return a("storage").removeItem(e)},keys(){return a("storage").keys()},instance:{getItem(e){return a("storage").instance.getItem(e)},setItem(e,t){return a("storage").instance.setItem(e,t)},removeItem(e){return a("storage").instance.removeItem(e)},keys(){return a("storage").instance.keys()}}},Es={send(e){return a("notify").send(e)},dismiss(e){a("notify").dismiss(e)},badge(e){a("notify").badge(e)},registerChannel(e){a("notify").registerChannel(e)},requestPermission(e){return a("notify").requestPermission(e)},onAction(e){return a("notify").onAction(e)},onClicked(e){return a("notify").onClicked(e)},onDismissed(e){return a("notify").onDismissed(e)},onControls(e){return a("notify").onControls(e)}},on={getPublicKey(){return a("identity").getPublicKey()},onChanged(e){return a("identity").onChanged(e)},getRelays(){return a("identity").getRelays()},getProfile(){return a("identity").getProfile()},getFollows(){return a("identity").getFollows()},getList(e){return a("identity").getList(e)},getZaps(){return a("identity").getZaps()},getMutes(){return a("identity").getMutes()},getBlocked(){return a("identity").getBlocked()},getBadges(){return a("identity").getBadges()}},ct={get(){return a("config").get()},subscribe(e){return a("config").subscribe(e)},openSettings(e){a("config").openSettings(e)},registerSchema(e,t){return a("config").registerSchema(e,t)},onSchemaError(e){return a("config").onSchemaError(e)},get schema(){return a("config").schema}},Ms={info(){return a("resource").info()},bytes(e,t){return a("resource").bytes(e,t)},bytesMany(e,t){return a("resource").bytesMany(e,t)},bytesAsObjectURL(e){return a("resource").bytesAsObjectURL(e)}};const p={status:v("#status"),capabilities:v("#capabilities"),identityValue:v("#identityValue"),noteInput:v("#noteInput"),storageValue:v("#storageValue"),output:v("#output"),identityButton:v("#identityButton"),storageButton:v("#storageButton"),relayButton:v("#relayButton"),resourceButton:v("#resourceButton"),notifyButton:v("#notifyButton"),settingsButton:v("#settingsButton")};let sn=null,un=null;function v(e){const t=document.querySelector(e);if(!t)throw new Error(`Missing required element: ${e}`);return t}function y(e,t){p.status.className=`status status-${e}`,p.status.textContent=t}function L(e){p.output.textContent=typeof e=="string"?e:JSON.stringify(e,null,2)}function St(e,t){const n=window.napplet?.shell;try{return!!n?.supports?.(e,t)}catch{return!1}}function N(e){return St(e)||St(`nap:${e}`)?"yes":"no"}function Us(){const e=[["relay",N(Xt)],["storage",N(tn)],["identity",N(en)],["config",N(ws)],["resource",N(rn)],["notify",N(nn)]];p.capabilities.replaceChildren(...e.flatMap(([t,n])=>{const r=document.createElement("dt");r.textContent=t;const o=document.createElement("dd");return o.textContent=n,o.dataset.state=n==="no"?"off":"on",[r,o]}))}async function C(e,t,n=5e3){let r=0;const o=new Promise((i,s)=>{r=window.setTimeout(()=>{s(new Error(`${t} did not resolve within ${n}ms`))},n)});try{return await Promise.race([e,o])}finally{window.clearTimeout(r)}}function Ss(e){return{id:e.id,kind:e.kind,created_at:e.created_at,content:e.content.slice(0,160)}}function an(e){return e?e.length<=16?e:`${e.slice(0,8)}...${e.slice(-8)}`:"not connected"}async function Ts(){y("idle","Reading identity");const e=await C(on.getPublicKey(),"identity.getPublicKey");p.identityValue.textContent=an(e),y(e?"ok":"warn",e?"Identity loaded":"No user identity")}async function Is(){y("idle","Saving note");const e=p.noteInput.value.trim();await C(Ut.setItem("draft-note",e),"storage.setItem");const t=await C(Ut.getItem("draft-note"),"storage.getItem");p.storageValue.textContent=t??"missing",y("ok","Note saved")}async function $s(){y("idle","Querying relay");const e=await Ps(),t=Number(e.defaultRelayLimit??5),n=Number.isFinite(t)?t:5,r=await C(gs.query({kinds:[1],limit:n}),"relay.query",8e3);L(r.map(Ss)),y("ok",`Loaded ${r.length} relay event${r.length===1?"":"s"}`)}async function Rs(){y("idle","Loading resource");const e=await C(Ms.bytes("data:text/plain;base64,TmFwcGxldCByZXNvdXJjZSBjaGVjaw=="),"resource.bytes"),t=await e.text();L({resource:t,bytes:e.size,type:e.type||"unknown"}),y("ok","Resource loaded")}async function Ds(){y("idle","Sending notification");const e=await C(Es.send({title:"Napplet ready",body:"The starter app can talk to the shell notification surface.",priority:"normal"}),"notify.send");L(e),y("ok","Notification sent")}async function Ps(){try{return await C(ct.get(),"config.get",3e3)}catch{return{}}}function ks(){try{sn=on.onChanged(e=>{p.identityValue.textContent=an(e),y(e?"ok":"warn",e?"Identity changed":"Identity cleared")})}catch(e){L(e instanceof Error?e.message:e)}}function Cs(){try{un=ct.subscribe(e=>{document.documentElement.dataset.accent=String(e.accentColor??"blue")})}catch{document.documentElement.dataset.accent="blue"}}function ee(e){e().catch(t=>{y("error","Action failed"),L(t instanceof Error?t.message:t)})}p.identityButton.addEventListener("click",()=>ee(Ts));p.storageButton.addEventListener("click",()=>ee(Is));p.relayButton.addEventListener("click",()=>ee($s));p.resourceButton.addEventListener("click",()=>ee(Rs));p.notifyButton.addEventListener("click",()=>ee(Ds));p.settingsButton.addEventListener("click",()=>{try{ct.openSettings({section:"appearance"}),y("ok","Settings requested")}catch(e){y("error","Settings failed"),L(e instanceof Error?e.message:e)}});window.addEventListener("beforeunload",()=>{sn?.close(),un?.close()});Us();ks();Cs();L("Napplet ready. Use the actions above to exercise each shell surface.");</script>
    <style rel="stylesheet" crossorigin>:root{color-scheme:light;font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;background:#f4f6f8;color:#17212b;--accent: #2563eb;--accent-strong: #1d4ed8;--surface: #ffffff;--surface-muted: #eef2f6;--border: #d7dee7;--muted: #647487;--danger: #b42318;--warning: #9a6700;--success: #16703b;--napplet-text-selection: none}:root[data-accent=green]{--accent: #178a52;--accent-strong: #116d40}:root[data-accent=amber]{--accent: #b45309;--accent-strong: #92400e}*{box-sizing:border-box}:where(html,body,body *){-webkit-user-select:var(--napplet-text-selection, none);user-select:var(--napplet-text-selection, none)}:where(input,textarea,select,[contenteditable],[data-napplet-select=text]){-webkit-user-select:text;user-select:text}:where([data-napplet-select=all]){-webkit-user-select:all;user-select:all}body{margin:0;min-width:320px}button,textarea{font:inherit}button{min-height:2.5rem;border:1px solid #1f2937;border-radius:6px;background:#1f2937;color:#fff;padding:.6rem .85rem;cursor:pointer}button:hover{background:#111827}button:focus-visible,textarea:focus-visible{outline:3px solid color-mix(in srgb,var(--accent) 35%,transparent);outline-offset:2px}.app-shell{min-height:100vh;padding:2rem}.workspace{width:min(1040px,100%);margin:0 auto;display:grid;gap:1rem}.masthead,.panel{background:var(--surface);border:1px solid var(--border);border-radius:8px}.masthead{display:flex;justify-content:space-between;align-items:start;gap:1rem;padding:1.25rem}.eyebrow{margin:0 0 .25rem;color:var(--accent);font-size:.78rem;font-weight:700;text-transform:uppercase;letter-spacing:0}h1,h2,p{margin-top:0}h1{margin-bottom:0;font-size:clamp(1.6rem,4vw,2.4rem);line-height:1.05}h2{margin-bottom:.8rem;font-size:1rem}.status{display:inline-flex;align-items:center;min-height:2rem;border-radius:999px;padding:.35rem .7rem;white-space:nowrap;font-size:.86rem;font-weight:700}.status-idle{color:#334155;background:#e2e8f0}.status-ok{color:var(--success);background:#ddf7e8}.status-warn{color:var(--warning);background:#fff3c4}.status-error{color:var(--danger);background:#fee4e2}.panel{padding:1rem}.capability-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.75rem;margin:0}.capability-grid dt,.capability-grid dd{margin:0}.capability-grid dt{color:var(--muted);font-size:.8rem}.capability-grid dd{min-height:2rem;border-radius:6px;background:var(--surface-muted);padding:.45rem .55rem;overflow-wrap:anywhere;font-weight:700}.capability-grid dd[data-state=on]{color:var(--success)}.capability-grid dd[data-state=off]{color:var(--muted)}.button-row{display:flex;flex-wrap:wrap;gap:.6rem}.split-panel{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,2fr);gap:1rem}.field{display:grid;gap:.4rem;color:var(--muted);font-weight:700}textarea{width:100%;resize:vertical;border:1px solid var(--border);border-radius:6px;padding:.7rem;color:#17212b}.mono{font-family:SFMono-Regular,Consolas,Liberation Mono,monospace}.muted{color:var(--muted)}.output{min-height:12rem;max-height:24rem;overflow:auto;margin:0;border-radius:6px;background:#0f172a;color:#e5edf7;padding:1rem;white-space:pre-wrap}@media(max-width:720px){.app-shell{padding:1rem}.masthead,.split-panel{grid-template-columns:1fr}.masthead{display:grid}.capability-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}</style>
    <meta name="napplet-type" content="test">
    <meta name="napplet-requires" content="config,identity,notify,relay,resource,storage">
    <meta name="napplet-config-schema" content="{&quot;type&quot;:&quot;object&quot;,&quot;properties&quot;:{&quot;accentColor&quot;:{&quot;type&quot;:&quot;string&quot;,&quot;enum&quot;:[&quot;blue&quot;,&quot;green&quot;,&quot;amber&quot;],&quot;default&quot;:&quot;blue&quot;,&quot;x-napplet-section&quot;:&quot;appearance&quot;,&quot;x-napplet-order&quot;:1},&quot;defaultRelayLimit&quot;:{&quot;type&quot;:&quot;integer&quot;,&quot;minimum&quot;:1,&quot;maximum&quot;:50,&quot;default&quot;:5,&quot;x-napplet-section&quot;:&quot;relay&quot;,&quot;x-napplet-order&quot;:1}},&quot;required&quot;:[&quot;accentColor&quot;]}">
  </head>
  <body>
    <main id="app" class="app-shell">
      <section class="workspace" aria-labelledby="app-title">
        <header class="masthead">
          <div>
            <p class="eyebrow">NIP-5D napplet</p>
            <h1 id="app-title">A test napplet</h1>
          </div>
          <output id="status" class="status status-idle">Ready</output>
        </header>

        <section class="panel capability-panel" aria-labelledby="capability-title">
          <h2 id="capability-title">Shell Surface</h2>
          <dl id="capabilities" class="capability-grid"></dl>
        </section>

        <section class="panel action-panel" aria-labelledby="actions-title">
          <h2 id="actions-title">Actions</h2>
          <div class="button-row">
            <button id="identityButton" type="button">Refresh identity</button>
            <button id="storageButton" type="button">Save note</button>
            <button id="relayButton" type="button">Query relay</button>
            <button id="resourceButton" type="button">Load resource</button>
            <button id="notifyButton" type="button">Notify</button>
            <button id="settingsButton" type="button">Settings</button>
          </div>
        </section>

        <section class="panel split-panel" aria-label="Napplet state">
          <article>
            <h2>Identity</h2>
            <p id="identityValue" class="mono muted">not loaded</p>
          </article>
          <article>
            <h2>Storage</h2>
            <label class="field">
              <span>Draft note</span>
              <textarea id="noteInput" rows="4">Hello from my napplet.</textarea>
            </label>
            <p id="storageValue" class="mono muted">not saved</p>
          </article>
        </section>

        <section class="panel output-panel" aria-labelledby="events-title">
          <h2 id="events-title">Output</h2>
          <pre id="output" class="output" aria-live="polite">No events yet.</pre>
        </section>
      </section>
    </main>
  </body>
</html>