nostr-components 0.2.7 → 0.3.0

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.
Files changed (140) hide show
  1. package/README.md +105 -185
  2. package/dist/assets/{base-styles-BSEzBDsk.js → base-styles-DC0ilu4S.js} +3 -3
  3. package/dist/assets/{base-styles-BSEzBDsk.js.map → base-styles-DC0ilu4S.js.map} +1 -1
  4. package/dist/assets/{copy-delegation-B7y2q5Kn.js → copy-delegation-CcagQMIW.js} +5 -5
  5. package/dist/assets/{copy-delegation-B7y2q5Kn.js.map → copy-delegation-CcagQMIW.js.map} +1 -1
  6. package/dist/assets/{dialog-component-Da1ZIYh9.js → dialog-component-Dqg0QU9I.js} +2 -7
  7. package/dist/assets/dialog-component-Dqg0QU9I.js.map +1 -0
  8. package/dist/assets/{dialog-likers-BqDn2P_3.js → dialog-likers-D3c7WIMp.js} +5 -5
  9. package/dist/assets/dialog-likers-D3c7WIMp.js.map +1 -0
  10. package/dist/assets/index.esm-ByUtE_cm.js +2159 -0
  11. package/dist/assets/index.esm-ByUtE_cm.js.map +1 -0
  12. package/dist/assets/nip05-utils-BNBHUmkr.js.map +1 -1
  13. package/dist/assets/nostr-login-service-D2FmscPI.js +2 -0
  14. package/dist/assets/nostr-login-service-D2FmscPI.js.map +1 -0
  15. package/dist/assets/nostr-service-m3Hgc5Xx.js +266 -0
  16. package/dist/assets/nostr-service-m3Hgc5Xx.js.map +1 -0
  17. package/dist/assets/nostr-user-component-XEnanH-d.js +2 -0
  18. package/dist/assets/nostr-user-component-XEnanH-d.js.map +1 -0
  19. package/dist/assets/{pure-DPo-pzxM.js → pure-laCRX9eG.js} +2 -2
  20. package/dist/assets/pure-laCRX9eG.js.map +1 -0
  21. package/dist/assets/{theme-BN1Bvweb.js → theme-C1r1Zw8r.js} +2 -2
  22. package/dist/assets/{theme-BN1Bvweb.js.map → theme-C1r1Zw8r.js.map} +1 -1
  23. package/dist/assets/{user-resolver-CMmbtY9Y.js → user-resolver-DqI5KGh6.js} +2 -2
  24. package/dist/assets/{user-resolver-CMmbtY9Y.js.map → user-resolver-DqI5KGh6.js.map} +1 -1
  25. package/dist/assets/utils--bxLbhGF.js.map +1 -1
  26. package/dist/assets/zap-utils-BZcaCsT_.js +2 -0
  27. package/dist/assets/zap-utils-BZcaCsT_.js.map +1 -0
  28. package/dist/components/nostr-comment.es.js +26 -26
  29. package/dist/components/nostr-comment.es.js.map +1 -1
  30. package/dist/components/nostr-dm.es.js +2 -2
  31. package/dist/components/nostr-dm.es.js.map +1 -1
  32. package/dist/components/nostr-follow-button.es.js +6 -7
  33. package/dist/components/nostr-follow-button.es.js.map +1 -1
  34. package/dist/components/nostr-like.es.js +16 -16
  35. package/dist/components/nostr-like.es.js.map +1 -1
  36. package/dist/components/nostr-live-chat.es.js +3 -3
  37. package/dist/components/nostr-live-chat.es.js.map +1 -1
  38. package/dist/components/nostr-post.es.js +19 -19
  39. package/dist/components/nostr-post.es.js.map +1 -1
  40. package/dist/components/nostr-profile-badge.es.js +3 -3
  41. package/dist/components/nostr-profile-badge.es.js.map +1 -1
  42. package/dist/components/nostr-profile.es.js +2 -2
  43. package/dist/components/nostr-profile.es.js.map +1 -1
  44. package/dist/components/nostr-zap.es.js +24 -24
  45. package/dist/components/nostr-zap.es.js.map +1 -1
  46. package/dist/nostr-components.es.js +1 -1
  47. package/dist/nostr-components.es.js.map +1 -1
  48. package/dist/nostr-components.umd.js +2644 -305
  49. package/dist/nostr-components.umd.js.map +1 -1
  50. package/package.json +5 -2
  51. package/dist/assets/dark-nostrich-running.gif +0 -0
  52. package/dist/assets/default_dp-NQ3TGrtT.png +0 -0
  53. package/dist/assets/default_dp.png +0 -0
  54. package/dist/assets/default_dp_32.png +0 -0
  55. package/dist/assets/dialog-component-Da1ZIYh9.js.map +0 -1
  56. package/dist/assets/dialog-likers-BqDn2P_3.js.map +0 -1
  57. package/dist/assets/light-nostrich-running.gif +0 -0
  58. package/dist/assets/nostr-service-CnaPxjc6.js +0 -78
  59. package/dist/assets/nostr-service-CnaPxjc6.js.map +0 -1
  60. package/dist/assets/nostr-user-component-Cbs97dlK.js +0 -2
  61. package/dist/assets/nostr-user-component-Cbs97dlK.js.map +0 -1
  62. package/dist/assets/pure-DPo-pzxM.js.map +0 -1
  63. package/dist/assets/zap-utils-KFUD_vTU.js +0 -2
  64. package/dist/assets/zap-utils-KFUD_vTU.js.map +0 -1
  65. package/dist/index.d.ts +0 -6
  66. package/dist/nostr-comment.d.ts +0 -4
  67. package/dist/nostr-dm.d.ts +0 -4
  68. package/dist/nostr-follow-button.d.ts +0 -4
  69. package/dist/nostr-like.d.ts +0 -4
  70. package/dist/nostr-live-chat.d.ts +0 -4
  71. package/dist/nostr-post.d.ts +0 -4
  72. package/dist/nostr-profile-badge.d.ts +0 -4
  73. package/dist/nostr-profile.d.ts +0 -4
  74. package/dist/nostr-zap.d.ts +0 -4
  75. package/dist/src/base/base-component/nostr-base-component.d.ts +0 -116
  76. package/dist/src/base/copy-delegation.d.ts +0 -5
  77. package/dist/src/base/dialog-component/dialog-component.d.ts +0 -67
  78. package/dist/src/base/dialog-component/style.d.ts +0 -5
  79. package/dist/src/base/event-component/nostr-event-component.d.ts +0 -53
  80. package/dist/src/base/render-options.d.ts +0 -5
  81. package/dist/src/base/resolvers/event-resolver.d.ts +0 -20
  82. package/dist/src/base/resolvers/user-resolver.d.ts +0 -19
  83. package/dist/src/base/text-row/render-name.d.ts +0 -7
  84. package/dist/src/base/text-row/render-nip05.d.ts +0 -1
  85. package/dist/src/base/text-row/render-npub.d.ts +0 -1
  86. package/dist/src/base/text-row/render-text-row.d.ts +0 -9
  87. package/dist/src/base/user-component/nostr-user-component.d.ts +0 -43
  88. package/dist/src/common/base-styles.d.ts +0 -44
  89. package/dist/src/common/constants.d.ts +0 -4
  90. package/dist/src/common/date-utils.d.ts +0 -9
  91. package/dist/src/common/icons.d.ts +0 -7
  92. package/dist/src/common/nip05-utils.d.ts +0 -13
  93. package/dist/src/common/nostr-service.d.ts +0 -40
  94. package/dist/src/common/theme.d.ts +0 -4
  95. package/dist/src/common/types.d.ts +0 -1
  96. package/dist/src/common/utils.d.ts +0 -34
  97. package/dist/src/index.d.ts +0 -32
  98. package/dist/src/nostr-comment/nostr-comment.d.ts +0 -60
  99. package/dist/src/nostr-comment/render.d.ts +0 -15
  100. package/dist/src/nostr-comment/utils.d.ts +0 -81
  101. package/dist/src/nostr-dm/nostr-dm.d.ts +0 -34
  102. package/dist/src/nostr-dm/render.d.ts +0 -15
  103. package/dist/src/nostr-follow-button/nostr-follow-button.d.ts +0 -24
  104. package/dist/src/nostr-follow-button/render.d.ts +0 -11
  105. package/dist/src/nostr-follow-button/style.d.ts +0 -1
  106. package/dist/src/nostr-like/dialog-help-style.d.ts +0 -1
  107. package/dist/src/nostr-like/dialog-help.d.ts +0 -2
  108. package/dist/src/nostr-like/dialog-likers-style.d.ts +0 -1
  109. package/dist/src/nostr-like/dialog-likers.d.ts +0 -24
  110. package/dist/src/nostr-like/like-utils.d.ts +0 -52
  111. package/dist/src/nostr-like/nostr-like.d.ts +0 -49
  112. package/dist/src/nostr-like/render.d.ts +0 -10
  113. package/dist/src/nostr-like/style.d.ts +0 -1
  114. package/dist/src/nostr-live-chat/nostr-live-chat.d.ts +0 -65
  115. package/dist/src/nostr-live-chat/render.d.ts +0 -31
  116. package/dist/src/nostr-post/nostr-post.d.ts +0 -25
  117. package/dist/src/nostr-post/parse-text.d.ts +0 -8
  118. package/dist/src/nostr-post/render-content.d.ts +0 -5
  119. package/dist/src/nostr-post/render.d.ts +0 -19
  120. package/dist/src/nostr-post/style.d.ts +0 -1
  121. package/dist/src/nostr-profile/nostr-profile.d.ts +0 -24
  122. package/dist/src/nostr-profile/render-stats.d.ts +0 -1
  123. package/dist/src/nostr-profile/render.d.ts +0 -22
  124. package/dist/src/nostr-profile/style.d.ts +0 -1
  125. package/dist/src/nostr-profile-badge/nostr-profile-badge.d.ts +0 -34
  126. package/dist/src/nostr-profile-badge/render.d.ts +0 -11
  127. package/dist/src/nostr-profile-badge/style.d.ts +0 -1
  128. package/dist/src/nostr-zap/dialog-help-style.d.ts +0 -5
  129. package/dist/src/nostr-zap/dialog-help.d.ts +0 -2
  130. package/dist/src/nostr-zap/dialog-zap-style.d.ts +0 -6
  131. package/dist/src/nostr-zap/dialog-zap.d.ts +0 -31
  132. package/dist/src/nostr-zap/dialog-zappers-style.d.ts +0 -1
  133. package/dist/src/nostr-zap/dialog-zappers.d.ts +0 -25
  134. package/dist/src/nostr-zap/nostr-zap.d.ts +0 -45
  135. package/dist/src/nostr-zap/render.d.ts +0 -9
  136. package/dist/src/nostr-zap/style.d.ts +0 -1
  137. package/dist/src/nostr-zap/zap-utils.d.ts +0 -53
  138. package/dist/vite.config.d.ts +0 -2
  139. package/dist/vite.config.esm.d.ts +0 -2
  140. package/dist/vite.config.umd.d.ts +0 -2
@@ -0,0 +1,2 @@
1
+ var l=Object.defineProperty;var p=(i,r,e)=>r in i?l(i,r,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[r]=e;var n=(i,r,e)=>p(i,typeof r!="symbol"?r+"":r,e);import{N as h,a as o}from"./base-styles-DC0ilu4S.js";import{U as c}from"./user-resolver-DqI5KGh6.js";const d="nc:user";class C extends h{constructor(e=!0){super(e);n(this,"user",null);n(this,"profile",null);n(this,"userStatus",this.channel("user"));n(this,"loadSeq",0);n(this,"resolver",new c(this.nostrService));this.initChannelStatus("user",o.Loading,{reflectOverall:!1})}static get observedAttributes(){return[...super.observedAttributes,"npub","pubkey","nip05"]}connectedCallback(){var e;(e=super.connectedCallback)==null||e.call(this),this.validateInputs()&&this.resolveUserAndProfile().catch(t=>{console.error("[NostrUserComponent] init failed:",t)})}attributeChangedCallback(e,t,s){var u;t!==s&&((u=super.attributeChangedCallback)==null||u.call(this,e,t,s),(e==="npub"||e==="nip05"||e==="pubkey")&&this.validateInputs()&&this.resolveUserAndProfile())}validateInputs(){if(!super.validateInputs())return this.userStatus.set(o.Idle),!1;const e=this.getAttribute("npub"),t=this.getAttribute("pubkey"),s=this.getAttribute("nip05"),u=this.tagName.toLowerCase(),a=this.resolver.validateInputs({npub:e,pubkey:t,nip05:s});return a?(this.userStatus.set(o.Error,a),console.error(`Nostr-Components: ${u}: ${a}`),!1):(this.errorMessage="",!0)}async resolveUserAndProfile(){const e=++this.loadSeq;try{await this.ensureNostrConnected()}catch(t){if(e!==this.loadSeq)return;console.error("[NostrUserComponent] Relay connect failed before user/profile load:",t);return}this.userStatus.set(o.Loading);try{const{user:t,profile:s}=await this.resolver.resolveUser({npub:this.getAttribute("npub"),pubkey:this.getAttribute("pubkey"),nip05:this.getAttribute("nip05")});if(e!==this.loadSeq)return;if(s==null){this.userStatus.set(o.Error,"Profile not found");return}this.user=t,this.profile=s,this.userStatus.set(o.Ready),this.dispatchEvent(new CustomEvent(d,{detail:{user:this.user,profile:this.profile},bubbles:!0,composed:!0})),this.onUserReady(this.user,this.profile)}catch(t){if(e!==this.loadSeq)return;const s=t instanceof Error?t.message:"Failed to load user/profile";console.error("[NostrUserComponent] "+s,t),this.userStatus.set(o.Error,s)}}renderContent(){}onUserReady(e,t){}}export{C as N};
2
+ //# sourceMappingURL=nostr-user-component-XEnanH-d.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nostr-user-component-XEnanH-d.js","sources":["../../src/base/user-component/nostr-user-component.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\n\nimport { NDKUser, NDKUserProfile } from '@nostr-dev-kit/ndk';\nimport { NostrBaseComponent, NCStatus } from '../base-component/nostr-base-component';\nimport { UserResolver } from '../resolvers/user-resolver';\n\nconst EVT_USER = 'nc:user';\n\n/**\n * NostrUserComponent\n * ==================\n * Extension of `NostrBaseComponent` that resolves and manages a Nostr user.\n *\n * Overview\n * - Accepts identity attributes (`npub`, `nip05`, or `pubkey`) and validates them.\n * - Resolves an `NDKUser` via the shared `nostrService` and fetches its profile.\n * - Exposes resolved `user` and `profile` to subclasses for rendering or logic.\n * - Emits lifecycle events for status and user readiness.\n *\n * Observed attributes\n * - `npub` — user's Nostr public key (bech32 npub)\n * - `nip05` — NIP-05 identifier (e.g. `alice@example.com`)\n * - `pubkey` — raw hex-encoded public key\n *\n * Events\n * - `nc:status` — from base, reflects connection and user/profile loading status\n * - `nc:user` — fired when a user and profile are successfully resolved\n */\n\nexport class NostrUserComponent extends NostrBaseComponent {\n\n protected user: NDKUser | null = null;\n protected profile: NDKUserProfile | null = null;\n\n protected userStatus = this.channel('user');\n\n // guard to ignore stale user fetches\n private loadSeq = 0;\n\n private resolver = new UserResolver(this.nostrService);\n\n constructor(shadow: boolean = true) {\n super(shadow);\n this.initChannelStatus('user', NCStatus.Loading, { reflectOverall: false });\n }\n\n /** Lifecycle methods */\n static get observedAttributes() {\n return [\n ...super.observedAttributes,\n 'npub',\n 'pubkey',\n 'nip05',\n ];\n }\n\n connectedCallback() {\n super.connectedCallback?.();\n\n if (this.validateInputs()) {\n this.resolveUserAndProfile().catch(e => {\n console.error('[NostrUserComponent] init failed:', e);\n });\n }\n }\n\n attributeChangedCallback(\n name: string,\n oldValue: string | null,\n newValue: string | null\n ) {\n if (oldValue === newValue) return;\n super.attributeChangedCallback?.(name, oldValue, newValue);\n\n if (name === 'npub' || name === 'nip05' || name === 'pubkey') {\n if (this.validateInputs()) {\n // Re-resolve user + profile on identity changes\n void this.resolveUserAndProfile();\n }\n }\n }\n\n /** Protected methods */\n protected validateInputs(): boolean {\n\n if (!super.validateInputs()) {\n this.userStatus.set(NCStatus.Idle);\n return false;\n }\n\n const npub = this.getAttribute(\"npub\");\n const pubkey = this.getAttribute(\"pubkey\");\n const nip05 = this.getAttribute(\"nip05\");\n const tagName = this.tagName.toLowerCase();\n\n const err = this.resolver.validateInputs({\n npub: npub,\n pubkey: pubkey,\n nip05: nip05,\n });\n\n if (err) {\n this.userStatus.set(NCStatus.Error, err);\n console.error(`Nostr-Components: ${tagName}: ${err}`);\n return false;\n }\n\n this.errorMessage = \"\";\n return true;\n\n }\n\n protected async resolveUserAndProfile(): Promise<void> {\n const seq = ++this.loadSeq; // token to prevent stale writes\n\n // Ensure relays are connected; handle failure inside to avoid unhandled rejection\n try {\n await this.ensureNostrConnected();\n } catch (e) {\n if (seq !== this.loadSeq) return; // stale\n // Base already set status=Error, but make the failure explicit here too\n console.error('[NostrUserComponent] Relay connect failed before user/profile load:', e);\n return;\n }\n\n this.userStatus.set(NCStatus.Loading);\n\n try {\n const { user, profile } = await this.resolver.resolveUser({\n npub: this.getAttribute('npub'),\n pubkey: this.getAttribute('pubkey'),\n nip05: this.getAttribute('nip05'),\n });\n\n // stale call check\n if (seq !== this.loadSeq) return;\n\n if (profile == null) {\n this.userStatus.set(NCStatus.Error, \"Profile not found\");\n return;\n }\n\n this.user = user;\n this.profile = profile;\n this.userStatus.set(NCStatus.Ready);\n // Notify listeners that user + profile are available\n this.dispatchEvent(new CustomEvent(EVT_USER, {\n detail: { user: this.user, profile: this.profile },\n bubbles: true,\n composed: true,\n }));\n this.onUserReady(this.user!, this.profile);\n } catch (err) {\n if (seq !== this.loadSeq) return; // stale\n const msg = err instanceof Error ? err.message : 'Failed to load user/profile';\n console.error('[NostrUserComponent] ' + msg, err);\n this.userStatus.set(NCStatus.Error, msg);\n }\n }\n\n protected renderContent() { }\n\n /** Hook for subclasses to react when user/profile are ready (e.g., render). */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n protected onUserReady(_user: NDKUser, _profile: NDKUserProfile | null) { }\n}\n"],"names":["EVT_USER","NostrUserComponent","NostrBaseComponent","shadow","__publicField","UserResolver","NCStatus","_a","e","name","oldValue","newValue","npub","pubkey","nip05","tagName","err","seq","user","profile","msg","_user","_profile"],"mappings":"yQAMA,MAAMA,EAAW,UAuBV,MAAMC,UAA2BC,CAAmB,CAYzD,YAAYC,EAAkB,GAAM,CAClC,MAAMA,CAAM,EAXJC,EAAA,YAAuB,MACvBA,EAAA,eAAiC,MAEjCA,EAAA,kBAAa,KAAK,QAAQ,MAAM,GAGlCA,EAAA,eAAU,GAEVA,EAAA,gBAAW,IAAIC,EAAa,KAAK,YAAY,GAInD,KAAK,kBAAkB,OAAQC,EAAS,QAAS,CAAE,eAAgB,GAAO,CAC5E,CAGA,WAAW,oBAAqB,CAC9B,MAAO,CACL,GAAG,MAAM,mBACT,OACA,SACA,OAAA,CAEJ,CAEA,mBAAoB,QAClBC,EAAA,MAAM,oBAAN,MAAAA,EAAA,WAEI,KAAK,kBACP,KAAK,sBAAA,EAAwB,MAAMC,GAAK,CACtC,QAAQ,MAAM,oCAAqCA,CAAC,CACtD,CAAC,CAEL,CAEA,yBACEC,EACAC,EACAC,EACA,OACID,IAAaC,KACjBJ,EAAA,MAAM,2BAAN,MAAAA,EAAA,UAAiCE,EAAMC,EAAUC,IAE7CF,IAAS,QAAUA,IAAS,SAAWA,IAAS,WAC9C,KAAK,kBAEF,KAAK,sBAAA,EAGhB,CAGU,gBAA0B,CAElC,GAAI,CAAC,MAAM,iBACT,YAAK,WAAW,IAAIH,EAAS,IAAI,EAC1B,GAGT,MAAMM,EAAU,KAAK,aAAa,MAAM,EAClCC,EAAU,KAAK,aAAa,QAAQ,EACpCC,EAAU,KAAK,aAAa,OAAO,EACnCC,EAAU,KAAK,QAAQ,YAAA,EAEvBC,EAAM,KAAK,SAAS,eAAe,CACvC,KAAAJ,EACA,OAAAC,EACA,MAAAC,CAAA,CACD,EAED,OAAIE,GACF,KAAK,WAAW,IAAIV,EAAS,MAAOU,CAAG,EACvC,QAAQ,MAAM,qBAAqBD,CAAO,KAAKC,CAAG,EAAE,EAC7C,KAGT,KAAK,aAAe,GACb,GAET,CAEA,MAAgB,uBAAuC,CACrD,MAAMC,EAAM,EAAE,KAAK,QAGnB,GAAI,CACF,MAAM,KAAK,qBAAA,CACb,OAAST,EAAG,CACV,GAAIS,IAAQ,KAAK,QAAS,OAE1B,QAAQ,MAAM,sEAAuET,CAAC,EACtF,MACF,CAEA,KAAK,WAAW,IAAIF,EAAS,OAAO,EAEpC,GAAI,CACF,KAAM,CAAE,KAAAY,EAAM,QAAAC,CAAA,EAAY,MAAM,KAAK,SAAS,YAAY,CACxD,KAAM,KAAK,aAAa,MAAM,EAC9B,OAAQ,KAAK,aAAa,QAAQ,EAClC,MAAO,KAAK,aAAa,OAAO,CAAA,CACjC,EAGD,GAAIF,IAAQ,KAAK,QAAS,OAE1B,GAAIE,GAAW,KAAM,CACnB,KAAK,WAAW,IAAIb,EAAS,MAAO,mBAAmB,EACvD,MACF,CAEA,KAAK,KAAOY,EACZ,KAAK,QAAUC,EACf,KAAK,WAAW,IAAIb,EAAS,KAAK,EAElC,KAAK,cAAc,IAAI,YAAYN,EAAU,CAC3C,OAAQ,CAAE,KAAM,KAAK,KAAM,QAAS,KAAK,OAAA,EACzC,QAAS,GACT,SAAU,EAAA,CACX,CAAC,EACF,KAAK,YAAY,KAAK,KAAO,KAAK,OAAO,CAC3C,OAASgB,EAAK,CACZ,GAAIC,IAAQ,KAAK,QAAS,OAC1B,MAAMG,EAAMJ,aAAe,MAAQA,EAAI,QAAU,8BACjD,QAAQ,MAAM,wBAA0BI,EAAKJ,CAAG,EAChD,KAAK,WAAW,IAAIV,EAAS,MAAOc,CAAG,CACzC,CACF,CAEU,eAAgB,CAAE,CAIlB,YAAYC,EAAgBC,EAAiC,CAAE,CAC3E"}
@@ -1,2 +1,2 @@
1
- import{s as a,f as n,g as o}from"./nostr-service-CnaPxjc6.js";var i=Symbol("verified"),l=e=>e instanceof Object;function c(e){if(!l(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 s=0;s<r.length;s++)if(typeof r[s]=="object")return!1}return!0}new TextDecoder("utf-8");var y=new TextEncoder,g=class{generateSecretKey(){return a.utils.randomPrivateKey()}getPublicKey(e){return n(a.getPublicKey(e))}finalizeEvent(e,t){const r=e;return r.pubkey=n(a.getPublicKey(t)),r.id=u(r),r.sig=n(a.sign(u(r),t)),r[i]=!0,r}verifyEvent(e){if(typeof e[i]=="boolean")return e[i];const t=u(e);if(t!==e.id)return e[i]=!1,!1;try{const r=a.verify(e.sig,t,e.pubkey);return e[i]=r,r}catch{return e[i]=!1,!1}}};function b(e){if(!c(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 u(e){let t=o(y.encode(b(e)));return n(t)}var f=new g,p=f.generateSecretKey,h=f.getPublicKey,E=f.finalizeEvent;f.verifyEvent;export{E as finalizeEvent,p as generateSecretKey,u as getEventHash,h as getPublicKey,b as serializeEvent,c as validateEvent,i as verifiedSymbol};
2
- //# sourceMappingURL=pure-DPo-pzxM.js.map
1
+ import{s as a,b as n,a as o}from"./nostr-service-m3Hgc5Xx.js";var i=Symbol("verified"),l=e=>e instanceof Object;function y(e){if(!l(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 s=0;s<r.length;s++)if(typeof r[s]!="string")return!1}return!0}new TextDecoder("utf-8");var c=new TextEncoder,g=class{generateSecretKey(){return a.utils.randomPrivateKey()}getPublicKey(e){return n(a.getPublicKey(e))}finalizeEvent(e,t){const r=e;return r.pubkey=n(a.getPublicKey(t)),r.id=u(r),r.sig=n(a.sign(u(r),t)),r[i]=!0,r}verifyEvent(e){if(typeof e[i]=="boolean")return e[i];const t=u(e);if(t!==e.id)return e[i]=!1,!1;try{const r=a.verify(e.sig,t,e.pubkey);return e[i]=r,r}catch{return e[i]=!1,!1}}};function b(e){if(!y(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 u(e){let t=o(c.encode(b(e)));return n(t)}var f=new g,p=f.generateSecretKey,h=f.getPublicKey,E=f.finalizeEvent;f.verifyEvent;export{E as finalizeEvent,p as generateSecretKey,u as getEventHash,h as getPublicKey,b as serializeEvent,y as validateEvent,i as verifiedSymbol};
2
+ //# sourceMappingURL=pure-laCRX9eG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pure-laCRX9eG.js","sources":["../../node_modules/nostr-tools/lib/esm/pure.js"],"sourcesContent":["// pure.ts\nimport { schnorr } from \"@noble/curves/secp256k1\";\nimport { bytesToHex as bytesToHex2 } from \"@noble/hashes/utils\";\n\n// core.ts\nvar verifiedSymbol = Symbol(\"verified\");\nvar isRecord = (obj) => obj instanceof Object;\nfunction validateEvent(event) {\n if (!isRecord(event))\n return false;\n if (typeof event.kind !== \"number\")\n return false;\n if (typeof event.content !== \"string\")\n return false;\n if (typeof event.created_at !== \"number\")\n return false;\n if (typeof event.pubkey !== \"string\")\n return false;\n if (!event.pubkey.match(/^[a-f0-9]{64}$/))\n return false;\n if (!Array.isArray(event.tags))\n return false;\n for (let i2 = 0; i2 < event.tags.length; i2++) {\n let tag = event.tags[i2];\n if (!Array.isArray(tag))\n return false;\n for (let j = 0; j < tag.length; j++) {\n if (typeof tag[j] !== \"string\")\n return false;\n }\n }\n return true;\n}\nfunction sortEvents(events) {\n return events.sort((a, b) => {\n if (a.created_at !== b.created_at) {\n return b.created_at - a.created_at;\n }\n return a.id.localeCompare(b.id);\n });\n}\n\n// pure.ts\nimport { sha256 } from \"@noble/hashes/sha256\";\n\n// utils.ts\nimport { bytesToHex, hexToBytes } from \"@noble/hashes/utils\";\nvar utf8Decoder = new TextDecoder(\"utf-8\");\nvar utf8Encoder = new TextEncoder();\n\n// pure.ts\nvar JS = class {\n generateSecretKey() {\n return schnorr.utils.randomPrivateKey();\n }\n getPublicKey(secretKey) {\n return bytesToHex2(schnorr.getPublicKey(secretKey));\n }\n finalizeEvent(t, secretKey) {\n const event = t;\n event.pubkey = bytesToHex2(schnorr.getPublicKey(secretKey));\n event.id = getEventHash(event);\n event.sig = bytesToHex2(schnorr.sign(getEventHash(event), secretKey));\n event[verifiedSymbol] = true;\n return event;\n }\n verifyEvent(event) {\n if (typeof event[verifiedSymbol] === \"boolean\")\n return event[verifiedSymbol];\n const hash = getEventHash(event);\n if (hash !== event.id) {\n event[verifiedSymbol] = false;\n return false;\n }\n try {\n const valid = schnorr.verify(event.sig, hash, event.pubkey);\n event[verifiedSymbol] = valid;\n return valid;\n } catch (err) {\n event[verifiedSymbol] = false;\n return false;\n }\n }\n};\nfunction serializeEvent(evt) {\n if (!validateEvent(evt))\n throw new Error(\"can't serialize event with wrong or missing properties\");\n return JSON.stringify([0, evt.pubkey, evt.created_at, evt.kind, evt.tags, evt.content]);\n}\nfunction getEventHash(event) {\n let eventHash = sha256(utf8Encoder.encode(serializeEvent(event)));\n return bytesToHex2(eventHash);\n}\nvar i = new JS();\nvar generateSecretKey = i.generateSecretKey;\nvar getPublicKey = i.getPublicKey;\nvar finalizeEvent = i.finalizeEvent;\nvar verifyEvent = i.verifyEvent;\nexport {\n finalizeEvent,\n generateSecretKey,\n getEventHash,\n getPublicKey,\n serializeEvent,\n sortEvents,\n validateEvent,\n verifiedSymbol,\n verifyEvent\n};\n"],"names":["verifiedSymbol","isRecord","obj","validateEvent","event","i2","tag","j","utf8Encoder","JS","schnorr","secretKey","bytesToHex2","t","getEventHash","hash","valid","serializeEvent","evt","eventHash","sha256","i","generateSecretKey","getPublicKey","finalizeEvent"],"mappings":"8DAKG,IAACA,EAAiB,OAAO,UAAU,EAClCC,EAAYC,GAAQA,aAAe,OACvC,SAASC,EAAcC,EAAO,CAa5B,GAZI,CAACH,EAASG,CAAK,GAEf,OAAOA,EAAM,MAAS,UAEtB,OAAOA,EAAM,SAAY,UAEzB,OAAOA,EAAM,YAAe,UAE5B,OAAOA,EAAM,QAAW,UAExB,CAACA,EAAM,OAAO,MAAM,gBAAgB,GAEpC,CAAC,MAAM,QAAQA,EAAM,IAAI,EAC3B,MAAO,GACT,QAASC,EAAK,EAAGA,EAAKD,EAAM,KAAK,OAAQC,IAAM,CAC7C,IAAIC,EAAMF,EAAM,KAAKC,CAAE,EACvB,GAAI,CAAC,MAAM,QAAQC,CAAG,EACpB,MAAO,GACT,QAASC,EAAI,EAAGA,EAAID,EAAI,OAAQC,IAC9B,GAAI,OAAOD,EAAIC,CAAC,GAAM,SACpB,MAAO,EAEb,CACA,MAAO,EACT,CAekB,IAAI,YAAY,OAAO,EACzC,IAAIC,EAAc,IAAI,YAGlBC,EAAK,KAAM,CACb,mBAAoB,CAClB,OAAOC,EAAQ,MAAM,iBAAgB,CACvC,CACA,aAAaC,EAAW,CACtB,OAAOC,EAAYF,EAAQ,aAAaC,CAAS,CAAC,CACpD,CACA,cAAcE,EAAGF,EAAW,CAC1B,MAAMP,EAAQS,EACd,OAAAT,EAAM,OAASQ,EAAYF,EAAQ,aAAaC,CAAS,CAAC,EAC1DP,EAAM,GAAKU,EAAaV,CAAK,EAC7BA,EAAM,IAAMQ,EAAYF,EAAQ,KAAKI,EAAaV,CAAK,EAAGO,CAAS,CAAC,EACpEP,EAAMJ,CAAc,EAAI,GACjBI,CACT,CACA,YAAYA,EAAO,CACjB,GAAI,OAAOA,EAAMJ,CAAc,GAAM,UACnC,OAAOI,EAAMJ,CAAc,EAC7B,MAAMe,EAAOD,EAAaV,CAAK,EAC/B,GAAIW,IAASX,EAAM,GACjB,OAAAA,EAAMJ,CAAc,EAAI,GACjB,GAET,GAAI,CACF,MAAMgB,EAAQN,EAAQ,OAAON,EAAM,IAAKW,EAAMX,EAAM,MAAM,EAC1D,OAAAA,EAAMJ,CAAc,EAAIgB,EACjBA,CACT,MAAc,CACZ,OAAAZ,EAAMJ,CAAc,EAAI,GACjB,EACT,CACF,CACF,EACA,SAASiB,EAAeC,EAAK,CAC3B,GAAI,CAACf,EAAce,CAAG,EACpB,MAAM,IAAI,MAAM,wDAAwD,EAC1E,OAAO,KAAK,UAAU,CAAC,EAAGA,EAAI,OAAQA,EAAI,WAAYA,EAAI,KAAMA,EAAI,KAAMA,EAAI,OAAO,CAAC,CACxF,CACA,SAASJ,EAAaV,EAAO,CAC3B,IAAIe,EAAYC,EAAOZ,EAAY,OAAOS,EAAeb,CAAK,CAAC,CAAC,EAChE,OAAOQ,EAAYO,CAAS,CAC9B,CACA,IAAIE,EAAI,IAAIZ,EACRa,EAAoBD,EAAE,kBACtBE,EAAeF,EAAE,aACjBG,EAAgBH,EAAE,cACJA,EAAE","x_google_ignoreList":[0]}
@@ -1,2 +1,2 @@
1
- import{c as t,n as r,l as a}from"./icons-Dr_d9MII.js";function c(o=21,n=24){return r(o,n)}function i(){return a()}function e(o="dark"){return t(o)}export{c as a,i as b,e as g};
2
- //# sourceMappingURL=theme-BN1Bvweb.js.map
1
+ import{c as t,n as r,l as a}from"./icons-Dr_d9MII.js";function c(o=21,n=24){return r(o,n)}function i(){return a()}function e(o="dark"){return t(o)}export{i as a,e as b,c as g};
2
+ //# sourceMappingURL=theme-C1r1Zw8r.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"theme-BN1Bvweb.js","sources":["../../src/common/theme.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\n\nimport { Theme } from './types';\nimport { checkmarkIcon, nostrLogo } from './icons';\n\nexport function getNostrLogo(width: number = 21, height: number = 24) {\n return nostrLogo(width, height);\n}\n\nimport { loadingNostrich } from './icons';\n\nexport function getLoadingNostrich(){\n return loadingNostrich();\n}\n\nexport function getSuccessAnimation(theme: Theme = 'dark') {\n return checkmarkIcon(theme);\n}"],"names":["getNostrLogo","width","height","nostrLogo","getLoadingNostrich","loadingNostrich","getSuccessAnimation","theme","checkmarkIcon"],"mappings":"sDAKO,SAASA,EAAaC,EAAgB,GAAIC,EAAiB,GAAI,CAC7D,OAAAC,EAAUF,EAAOC,CAAM,CAChC,CAIO,SAASE,GAAoB,CAClC,OAAOC,EAAgB,CACzB,CAEgB,SAAAC,EAAoBC,EAAe,OAAQ,CACzD,OAAOC,EAAcD,CAAK,CAC5B"}
1
+ {"version":3,"file":"theme-C1r1Zw8r.js","sources":["../../src/common/theme.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\n\nimport { Theme } from './types';\nimport { checkmarkIcon, nostrLogo } from './icons';\n\nexport function getNostrLogo(width: number = 21, height: number = 24) {\n return nostrLogo(width, height);\n}\n\nimport { loadingNostrich } from './icons';\n\nexport function getLoadingNostrich(){\n return loadingNostrich();\n}\n\nexport function getSuccessAnimation(theme: Theme = 'dark') {\n return checkmarkIcon(theme);\n}"],"names":["getNostrLogo","width","height","nostrLogo","getLoadingNostrich","loadingNostrich","getSuccessAnimation","theme","checkmarkIcon"],"mappings":"sDAKO,SAASA,EAAaC,EAAgB,GAAIC,EAAiB,GAAI,CACpE,OAAOC,EAAUF,EAAOC,CAAM,CAChC,CAIO,SAASE,GAAoB,CAClC,OAAOC,EAAA,CACT,CAEO,SAASC,EAAoBC,EAAe,OAAQ,CACzD,OAAOC,EAAcD,CAAK,CAC5B"}
@@ -1,2 +1,2 @@
1
- import{a as o,l as a,n as l}from"./base-styles-BSEzBDsk.js";class u{constructor(r){this.nostrService=r}validateInputs({npub:r,pubkey:e,nip05:i}){return!r&&!e&&!i?"Provide npub, nip05 or pubkey attribute":e&&!o(e)?`Invalid Pubkey: ${e}`:i&&!a(i)?`Invalid Nip05: ${i}`:r&&!l(r)?`Invalid Npub: ${r}`:null}async resolveUser({npub:r,pubkey:e,nip05:i}){const t=await this.nostrService.resolveNDKUser({npub:r,pubkey:e,nip05:i});if(!t)throw new Error("Unable to resolve user from provided identifier");const s=await this.nostrService.getProfile(t);return{user:t,profile:s??null}}}export{u as U};
2
- //# sourceMappingURL=user-resolver-CMmbtY9Y.js.map
1
+ import{i as o,v as a,b as l}from"./base-styles-DC0ilu4S.js";class u{constructor(r){this.nostrService=r}validateInputs({npub:r,pubkey:e,nip05:i}){return!r&&!e&&!i?"Provide npub, nip05 or pubkey attribute":e&&!o(e)?`Invalid Pubkey: ${e}`:i&&!a(i)?`Invalid Nip05: ${i}`:r&&!l(r)?`Invalid Npub: ${r}`:null}async resolveUser({npub:r,pubkey:e,nip05:i}){const t=await this.nostrService.resolveNDKUser({npub:r,pubkey:e,nip05:i});if(!t)throw new Error("Unable to resolve user from provided identifier");const s=await this.nostrService.getProfile(t);return{user:t,profile:s??null}}}export{u as U};
2
+ //# sourceMappingURL=user-resolver-DqI5KGh6.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"user-resolver-CMmbtY9Y.js","sources":["../../src/base/resolvers/user-resolver.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\n\nimport { NDKUser, NDKUserProfile } from '@nostr-dev-kit/ndk';\nimport { NostrService } from '../../common/nostr-service';\nimport { isValidHex, validateNpub, validateNip05 } from '../../common/utils'\n\nexport class UserResolver {\n constructor(private nostrService: NostrService) { }\n\n validateInputs({ npub, pubkey, nip05 }: { npub?: string | null; pubkey?: string | null; nip05?: string | null }): string | null {\n if (!npub && !pubkey && !nip05) {\n return \"Provide npub, nip05 or pubkey attribute\";\n }\n if (pubkey && !isValidHex(pubkey)) return `Invalid Pubkey: ${pubkey}`;\n if (nip05 && !validateNip05(nip05)) return `Invalid Nip05: ${nip05}`;\n if (npub && !validateNpub(npub)) return `Invalid Npub: ${npub}`;\n return null;\n }\n\n async resolveUser({ npub, pubkey, nip05 }: { npub?: string | null; pubkey?: string | null; nip05?: string | null }): Promise<{ user: NDKUser, profile: NDKUserProfile | null }> {\n const user = await this.nostrService.resolveNDKUser({ npub, pubkey, nip05 });\n if (!user) throw new Error(\"Unable to resolve user from provided identifier\");\n\n const profile = await this.nostrService.getProfile(user);\n\n return { user, profile: profile ?? null };\n }\n}\n"],"names":["UserResolver","nostrService","npub","pubkey","nip05","isValidHex","validateNip05","validateNpub","user","profile"],"mappings":"4DAMO,MAAMA,CAAa,CACxB,YAAoBC,EAA4B,CAA5B,KAAA,aAAAA,CAAA,CAEpB,eAAe,CAAE,KAAAC,EAAM,OAAAC,EAAQ,MAAAC,GAAiG,CAC9H,MAAI,CAACF,GAAQ,CAACC,GAAU,CAACC,EAChB,0CAELD,GAAU,CAACE,EAAWF,CAAM,EAAU,mBAAmBA,CAAM,GAC/DC,GAAS,CAACE,EAAcF,CAAK,EAAU,kBAAkBA,CAAK,GAC9DF,GAAQ,CAACK,EAAaL,CAAI,EAAU,iBAAiBA,CAAI,GACtD,IAAA,CAGT,MAAM,YAAY,CAAE,KAAAA,EAAM,OAAAC,EAAQ,MAAAC,GAA8I,CACxK,MAAAI,EAAO,MAAM,KAAK,aAAa,eAAe,CAAE,KAAAN,EAAM,OAAAC,EAAQ,MAAAC,EAAO,EAC3E,GAAI,CAACI,EAAY,MAAA,IAAI,MAAM,iDAAiD,EAE5E,MAAMC,EAAU,MAAM,KAAK,aAAa,WAAWD,CAAI,EAEvD,MAAO,CAAE,KAAAA,EAAM,QAASC,GAAW,IAAK,CAAA,CAE5C"}
1
+ {"version":3,"file":"user-resolver-DqI5KGh6.js","sources":["../../src/base/resolvers/user-resolver.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\n\nimport { NDKUser, NDKUserProfile } from '@nostr-dev-kit/ndk';\nimport { NostrService } from '../../common/nostr-service';\nimport { isValidHex, validateNpub, validateNip05 } from '../../common/utils'\n\nexport class UserResolver {\n constructor(private nostrService: NostrService) { }\n\n validateInputs({ npub, pubkey, nip05 }: { npub?: string | null; pubkey?: string | null; nip05?: string | null }): string | null {\n if (!npub && !pubkey && !nip05) {\n return \"Provide npub, nip05 or pubkey attribute\";\n }\n if (pubkey && !isValidHex(pubkey)) return `Invalid Pubkey: ${pubkey}`;\n if (nip05 && !validateNip05(nip05)) return `Invalid Nip05: ${nip05}`;\n if (npub && !validateNpub(npub)) return `Invalid Npub: ${npub}`;\n return null;\n }\n\n async resolveUser({ npub, pubkey, nip05 }: { npub?: string | null; pubkey?: string | null; nip05?: string | null }): Promise<{ user: NDKUser, profile: NDKUserProfile | null }> {\n const user = await this.nostrService.resolveNDKUser({ npub, pubkey, nip05 });\n if (!user) throw new Error(\"Unable to resolve user from provided identifier\");\n\n const profile = await this.nostrService.getProfile(user);\n\n return { user, profile: profile ?? null };\n }\n}\n"],"names":["UserResolver","nostrService","npub","pubkey","nip05","isValidHex","validateNip05","validateNpub","user","profile"],"mappings":"4DAMO,MAAMA,CAAa,CACxB,YAAoBC,EAA4B,CAA5B,KAAA,aAAAA,CAA8B,CAElD,eAAe,CAAE,KAAAC,EAAM,OAAAC,EAAQ,MAAAC,GAAiG,CAC9H,MAAI,CAACF,GAAQ,CAACC,GAAU,CAACC,EAChB,0CAELD,GAAU,CAACE,EAAWF,CAAM,EAAU,mBAAmBA,CAAM,GAC/DC,GAAS,CAACE,EAAcF,CAAK,EAAU,kBAAkBA,CAAK,GAC9DF,GAAQ,CAACK,EAAaL,CAAI,EAAU,iBAAiBA,CAAI,GACtD,IACT,CAEA,MAAM,YAAY,CAAE,KAAAA,EAAM,OAAAC,EAAQ,MAAAC,GAA8I,CAC9K,MAAMI,EAAO,MAAM,KAAK,aAAa,eAAe,CAAE,KAAAN,EAAM,OAAAC,EAAQ,MAAAC,EAAO,EAC3E,GAAI,CAACI,EAAM,MAAM,IAAI,MAAM,iDAAiD,EAE5E,MAAMC,EAAU,MAAM,KAAK,aAAa,WAAWD,CAAI,EAEvD,MAAO,CAAE,KAAAA,EAAM,QAASC,GAAW,IAAA,CACrC,CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils--bxLbhGF.js","sources":["../../src/nostr-comment/utils.ts"],"sourcesContent":["import { NDKEvent } from '@nostr-dev-kit/ndk';\n\nexport interface CommentEvent {\n id: string;\n pubkey: string;\n content: string;\n created_at: number;\n tags: string[][];\n sig: string;\n}\n\nexport interface ParsedComment {\n id: string;\n pubkey: string;\n content: string;\n created_at: number;\n replyTo?: string;\n rootUrl?: string;\n}\n\n/**\n * Normalize URL for consistent comment identification\n */\nexport function normalizeURL(raw: string): string {\n try {\n const url = new URL(raw);\n return (\n url.origin\n .replace('://m.', '://') // remove known 'mobile' subdomains\n .replace('://mobile.', '://')\n .replace('http://', 'https://') // default everything to https\n .replace(\n /:\\d+/,\n // remove 443 and 80 ports\n port => (port === ':443' || port === ':80' ? '' : port)\n ) +\n url.pathname\n .replace(/\\/+/g, '/') // remove duplicated slashes in the middle of the path\n .replace(/\\/*$/, '') // remove slashes from the end of path\n );\n } catch (error) {\n console.error('Invalid URL:', raw);\n return raw;\n }\n}\n\n/**\n * Parse Nostr event into comment structure\n */\nexport function parseCommentEvent(event: NDKEvent): ParsedComment | null {\n if (!event.id || !event.pubkey || !event.content || !event.created_at) {\n return null;\n }\n\n const comment: ParsedComment = {\n id: event.id,\n pubkey: event.pubkey,\n content: event.content,\n created_at: event.created_at\n };\n\n // Parse tags to find references\n for (const tag of event.tags || []) {\n if (tag[0] === 'I' && tag[1]) {\n comment.rootUrl = tag[1];\n } else if (tag[0] === 'e' && tag[1]) {\n comment.replyTo = tag[1];\n }\n }\n\n return comment;\n}\n\n/**\n * Create a comment event for publishing\n */\nexport function createCommentEvent(\n content: string,\n pubkey: string,\n url: string,\n replyTo?: string\n): Omit<CommentEvent, 'id' | 'sig'> {\n const tags: string[][] = [\n ['I', url], // URL reference\n ['client', 'nostr-components']\n ];\n\n if (replyTo) {\n tags.push(['e', replyTo, '', 'reply']);\n }\n\n return {\n pubkey,\n content: content.trim(),\n created_at: Math.floor(Date.now() / 1000),\n tags\n };\n}\n\n/**\n * Validate if a string is a valid Nostr public key\n */\nexport function isValidPublicKey(pubkey: string): boolean {\n return /^[a-f0-9]{64}$/.test(pubkey);\n}\n\n/**\n * Validate if a string is a valid Nostr event ID\n */\nexport function isValidEventId(eventId: string): boolean {\n return /^[a-f0-9]{64}$/.test(eventId);\n}\n\n/**\n * Truncate public key for display\n */\nexport function truncatePublicKey(pubkey: string, length: number = 8): string {\n if (pubkey.length <= length * 2) return pubkey;\n return `${pubkey.slice(0, length)}...${pubkey.slice(-length)}`;\n}\n\n/**\n * Format timestamp to relative time\n */\nexport function formatRelativeTime(timestamp: number): string {\n const now = Date.now() / 1000;\n const diff = now - timestamp;\n\n if (diff < 60) return 'just now';\n if (diff < 3600) return `${Math.floor(diff / 60)}m ago`;\n if (diff < 86400) return `${Math.floor(diff / 3600)}h ago`;\n if (diff < 2592000) return `${Math.floor(diff / 86400)}d ago`;\n\n const date = new Date(timestamp * 1000);\n return date.toLocaleDateString();\n}\n\n/**\n * Sanitize HTML content to prevent XSS\n */\nexport function sanitizeContent(content: string): string {\n return content\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#039;');\n}\n\n/**\n * Parse URLs in content and make them clickable\n */\nexport function linkifyContent(content: string): string {\n const urlRegex = /(https?:\\/\\/[^\\s]+)/g;\n return sanitizeContent(content).replace(urlRegex, '<a href=\"$1\" target=\"_blank\" rel=\"noopener noreferrer\">$1</a>');\n}\n\n/**\n * Generate a simple hash for content deduplication\n */\nexport function hashContent(content: string, pubkey: string): string {\n const combined = content + pubkey;\n let hash = 0;\n for (let i = 0; i < combined.length; i++) {\n const char = combined.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n return Math.abs(hash).toString(36);\n}\n\n/**\n * Check if user has a Nostr extension (NIP-07)\n */\nexport function hasNostrExtension(): boolean {\n return typeof (window as any).nostr !== 'undefined';\n}\n\n/**\n * Get stored private key from localStorage\n */\nexport function getStoredPrivateKey(): string | null {\n try {\n const key = localStorage.getItem('nostr-comment-private-key');\n if (key && isValidPrivateKey(key)) {\n return key;\n }\n } catch (error) {\n console.warn('Failed to access localStorage:', error);\n }\n return null;\n}\n\n/**\n * Store private key in localStorage\n */\nexport function storePrivateKey(privateKey: string): boolean {\n try {\n if (isValidPrivateKey(privateKey)) {\n localStorage.setItem('nostr-comment-private-key', privateKey);\n return true;\n }\n } catch (error) {\n console.warn('Failed to store private key:', error);\n }\n return false;\n}\n\n/**\n * Validate if a string is a valid private key\n */\nexport function isValidPrivateKey(privateKey: string): boolean {\n return /^[a-f0-9]{64}$/.test(privateKey);\n}\n\n/**\n * Clear stored private key (for logout functionality)\n */\nexport function clearStoredPrivateKey(): void {\n try {\n localStorage.removeItem('nostr-comment-private-key');\n } catch (error) {\n console.warn('Failed to clear stored private key:', error);\n }\n}\n\n/**\n * Debounce function for rate limiting\n */\nexport function debounce<T extends (...args: any[]) => any>(\n func: T,\n wait: number\n): (...args: Parameters<T>) => void {\n let timeout: ReturnType<typeof setTimeout> | undefined;\n return (...args: Parameters<T>) => {\n if (timeout) clearTimeout(timeout);\n timeout = setTimeout(() => func(...args), wait);\n };\n}\n"],"names":["normalizeURL","raw","url","port","isValidPublicKey","pubkey"],"mappings":"AAuBO,SAASA,EAAaC,EAAqB,CAC1C,GAAA,CACM,MAAAC,EAAM,IAAI,IAAID,CAAG,EACvB,OACIC,EAAI,OACC,QAAQ,QAAS,KAAK,EACtB,QAAQ,aAAc,KAAK,EAC3B,QAAQ,UAAW,UAAU,EAC7B,QACG,OAESC,GAAAA,IAAS,QAAUA,IAAS,MAAQ,GAAKA,CAAA,EAE1DD,EAAI,SACC,QAAQ,OAAQ,GAAG,EACnB,QAAQ,OAAQ,EAAE,OAEf,CACJ,eAAA,MAAM,eAAgBD,CAAG,EAC1BA,CAAA,CAEf,CA0DO,SAASG,EAAiBC,EAAyB,CAC/C,MAAA,iBAAiB,KAAKA,CAAM,CACvC"}
1
+ {"version":3,"file":"utils--bxLbhGF.js","sources":["../../src/nostr-comment/utils.ts"],"sourcesContent":["import { NDKEvent } from '@nostr-dev-kit/ndk';\n\nexport interface CommentEvent {\n id: string;\n pubkey: string;\n content: string;\n created_at: number;\n tags: string[][];\n sig: string;\n}\n\nexport interface ParsedComment {\n id: string;\n pubkey: string;\n content: string;\n created_at: number;\n replyTo?: string;\n rootUrl?: string;\n}\n\n/**\n * Normalize URL for consistent comment identification\n */\nexport function normalizeURL(raw: string): string {\n try {\n const url = new URL(raw);\n return (\n url.origin\n .replace('://m.', '://') // remove known 'mobile' subdomains\n .replace('://mobile.', '://')\n .replace('http://', 'https://') // default everything to https\n .replace(\n /:\\d+/,\n // remove 443 and 80 ports\n port => (port === ':443' || port === ':80' ? '' : port)\n ) +\n url.pathname\n .replace(/\\/+/g, '/') // remove duplicated slashes in the middle of the path\n .replace(/\\/*$/, '') // remove slashes from the end of path\n );\n } catch (error) {\n console.error('Invalid URL:', raw);\n return raw;\n }\n}\n\n/**\n * Parse Nostr event into comment structure\n */\nexport function parseCommentEvent(event: NDKEvent): ParsedComment | null {\n if (!event.id || !event.pubkey || !event.content || !event.created_at) {\n return null;\n }\n\n const comment: ParsedComment = {\n id: event.id,\n pubkey: event.pubkey,\n content: event.content,\n created_at: event.created_at\n };\n\n // Parse tags to find references\n for (const tag of event.tags || []) {\n if (tag[0] === 'I' && tag[1]) {\n comment.rootUrl = tag[1];\n } else if (tag[0] === 'e' && tag[1]) {\n comment.replyTo = tag[1];\n }\n }\n\n return comment;\n}\n\n/**\n * Create a comment event for publishing\n */\nexport function createCommentEvent(\n content: string,\n pubkey: string,\n url: string,\n replyTo?: string\n): Omit<CommentEvent, 'id' | 'sig'> {\n const tags: string[][] = [\n ['I', url], // URL reference\n ['client', 'nostr-components']\n ];\n\n if (replyTo) {\n tags.push(['e', replyTo, '', 'reply']);\n }\n\n return {\n pubkey,\n content: content.trim(),\n created_at: Math.floor(Date.now() / 1000),\n tags\n };\n}\n\n/**\n * Validate if a string is a valid Nostr public key\n */\nexport function isValidPublicKey(pubkey: string): boolean {\n return /^[a-f0-9]{64}$/.test(pubkey);\n}\n\n/**\n * Validate if a string is a valid Nostr event ID\n */\nexport function isValidEventId(eventId: string): boolean {\n return /^[a-f0-9]{64}$/.test(eventId);\n}\n\n/**\n * Truncate public key for display\n */\nexport function truncatePublicKey(pubkey: string, length: number = 8): string {\n if (pubkey.length <= length * 2) return pubkey;\n return `${pubkey.slice(0, length)}...${pubkey.slice(-length)}`;\n}\n\n/**\n * Format timestamp to relative time\n */\nexport function formatRelativeTime(timestamp: number): string {\n const now = Date.now() / 1000;\n const diff = now - timestamp;\n\n if (diff < 60) return 'just now';\n if (diff < 3600) return `${Math.floor(diff / 60)}m ago`;\n if (diff < 86400) return `${Math.floor(diff / 3600)}h ago`;\n if (diff < 2592000) return `${Math.floor(diff / 86400)}d ago`;\n\n const date = new Date(timestamp * 1000);\n return date.toLocaleDateString();\n}\n\n/**\n * Sanitize HTML content to prevent XSS\n */\nexport function sanitizeContent(content: string): string {\n return content\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#039;');\n}\n\n/**\n * Parse URLs in content and make them clickable\n */\nexport function linkifyContent(content: string): string {\n const urlRegex = /(https?:\\/\\/[^\\s]+)/g;\n return sanitizeContent(content).replace(urlRegex, '<a href=\"$1\" target=\"_blank\" rel=\"noopener noreferrer\">$1</a>');\n}\n\n/**\n * Generate a simple hash for content deduplication\n */\nexport function hashContent(content: string, pubkey: string): string {\n const combined = content + pubkey;\n let hash = 0;\n for (let i = 0; i < combined.length; i++) {\n const char = combined.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n return Math.abs(hash).toString(36);\n}\n\n/**\n * Check if user has a Nostr extension (NIP-07)\n */\nexport function hasNostrExtension(): boolean {\n return typeof (window as any).nostr !== 'undefined';\n}\n\n/**\n * Get stored private key from localStorage\n */\nexport function getStoredPrivateKey(): string | null {\n try {\n const key = localStorage.getItem('nostr-comment-private-key');\n if (key && isValidPrivateKey(key)) {\n return key;\n }\n } catch (error) {\n console.warn('Failed to access localStorage:', error);\n }\n return null;\n}\n\n/**\n * Store private key in localStorage\n */\nexport function storePrivateKey(privateKey: string): boolean {\n try {\n if (isValidPrivateKey(privateKey)) {\n localStorage.setItem('nostr-comment-private-key', privateKey);\n return true;\n }\n } catch (error) {\n console.warn('Failed to store private key:', error);\n }\n return false;\n}\n\n/**\n * Validate if a string is a valid private key\n */\nexport function isValidPrivateKey(privateKey: string): boolean {\n return /^[a-f0-9]{64}$/.test(privateKey);\n}\n\n/**\n * Clear stored private key (for logout functionality)\n */\nexport function clearStoredPrivateKey(): void {\n try {\n localStorage.removeItem('nostr-comment-private-key');\n } catch (error) {\n console.warn('Failed to clear stored private key:', error);\n }\n}\n\n/**\n * Debounce function for rate limiting\n */\nexport function debounce<T extends (...args: any[]) => any>(\n func: T,\n wait: number\n): (...args: Parameters<T>) => void {\n let timeout: ReturnType<typeof setTimeout> | undefined;\n return (...args: Parameters<T>) => {\n if (timeout) clearTimeout(timeout);\n timeout = setTimeout(() => func(...args), wait);\n };\n}\n"],"names":["normalizeURL","raw","url","port","isValidPublicKey","pubkey"],"mappings":"AAuBO,SAASA,EAAaC,EAAqB,CAC9C,GAAI,CACA,MAAMC,EAAM,IAAI,IAAID,CAAG,EACvB,OACIC,EAAI,OACC,QAAQ,QAAS,KAAK,EACtB,QAAQ,aAAc,KAAK,EAC3B,QAAQ,UAAW,UAAU,EAC7B,QACG,OAEAC,GAASA,IAAS,QAAUA,IAAS,MAAQ,GAAKA,CAAA,EAE1DD,EAAI,SACC,QAAQ,OAAQ,GAAG,EACnB,QAAQ,OAAQ,EAAE,CAE/B,MAAgB,CACZ,eAAQ,MAAM,eAAgBD,CAAG,EAC1BA,CACX,CACJ,CA0DO,SAASG,EAAiBC,EAAyB,CACtD,MAAO,iBAAiB,KAAKA,CAAM,CACvC"}
@@ -0,0 +1,2 @@
1
+ import{S as E,n as N,f as P}from"./nostr-service-m3Hgc5Xx.js";import{e as R,s as S}from"./nostr-login-service-D2FmscPI.js";import{n as k}from"./utils--bxLbhGF.js";import"./preload-helper-D7HrI6pR.js";const d={},x=async t=>{if(d[t])return d[t];const e=new E,s=["wss://relay.nostr.band","wss://purplepag.es","wss://relay.damus.io","wss://nostr.wine"];try{const a=await e.get(s,{authors:[t],kinds:[0]});return d[t]=a,a}finally{e.close(s)}},D=async t=>{const e=t.filter(r=>!d[r]);if(e.length===0)return t.map(r=>({id:r,profile:d[r]}));const s=new E,a=["wss://relay.nostr.band","wss://purplepag.es","wss://relay.damus.io","wss://nostr.wine"];try{return(await s.querySync(a,{authors:e,kinds:[0]})).forEach(n=>{d[n.pubkey]=n}),t.map(n=>({id:n,profile:d[n]||null}))}finally{s.close(a)}},J=t=>{try{return JSON.parse((t==null?void 0:t.content)||"{}")}catch{return{}}},I=async t=>{const e=await N.getZapEndpoint(t);if(!e)throw new Error("Failed to retrieve zap LNURL");return e},L=async(t,e)=>{try{return await R(),await S(t)}catch{}return P(t,C())},Z=async({profile:t,nip19Target:e,amount:s,relays:a,comment:r,anon:i,url:n})=>{const f={profile:t,amount:s,relays:a,comment:r||""},c=N.makeZapRequest(f);n&&(c.tags.push(["k","web"]),c.tags.push(["i",k(n)]));let l=!1;try{await R(),l=typeof window<"u"&&!!window.nostr}catch{l=!1}return(!l||i)&&c.tags.push(["anon"]),L(c)},M=async({zapEndpoint:t,amount:e,comment:s,authorId:a,nip19Target:r,normalizedRelays:i,anon:n,url:f})=>{const c=await Z({profile:a,nip19Target:r,amount:e,relays:i,comment:s??"",anon:n,url:f});let l=`${t}?amount=${e}&nostr=${encodeURIComponent(JSON.stringify(c))}`;s&&(l+=`&comment=${encodeURIComponent(s??"")}`);const p=await fetch(l,{method:"GET"});if(!p.ok)throw new Error(`LNURL request failed: ${p.status} ${p.statusText}`);let m;try{m=await p.json()}catch{throw new Error("Invalid JSON from LNURL endpoint")}const{pr:h,reason:b,status:g}=m||{};if(h)return h;throw g==="ERROR"?new Error(b??"Unable to fetch invoice"):new Error("Unable to fetch invoice")},C=()=>{const t=new Uint8Array(32);if(typeof crypto<"u"&&typeof crypto.getRandomValues=="function")crypto.getRandomValues(t);else{console.warn("crypto.getRandomValues not available, using Math.random as fallback");for(let e=0;e<32;e++)t[e]=Math.floor(Math.random()*256)}return t},V=async({pubkey:t,relays:e,url:s})=>{var f,c,l,p;const a=s?k(s):void 0,r=new E;let i=0;const n=[];try{const m={kinds:[9735],"#p":[t],limit:1e3},h=await r.querySync(e,m);for(const b of h){const g=(f=b.tags)==null?void 0:f.find(o=>o[0]==="description");if(g!=null&&g[1])try{const o=JSON.parse(g[1]),w=(c=o==null?void 0:o.tags)==null?void 0:c.find(u=>u[0]==="amount");if(a){const u=(l=o==null?void 0:o.tags)==null?void 0:l.find(y=>y[0]==="k"),v=(p=o==null?void 0:o.tags)==null?void 0:p.find(y=>y[0]==="i"),U=v!=null&&v[1]?k(v[1]):"";if((u==null?void 0:u[1])==="web"&&U===a&&(w!=null&&w[1])){const y=parseInt(w[1],10);y>0&&(i+=y,n.push({amount:y/1e3,date:new Date(b.created_at*1e3),authorPubkey:o.pubkey,comment:o.content}))}}else if(w!=null&&w[1]){const u=parseInt(w[1],10);u>0&&(i+=u,n.push({amount:u/1e3,date:new Date(b.created_at*1e3),authorPubkey:o.pubkey,comment:o.content}))}}catch(o){console.error("Nostr-Components: Zap button: Could not parse zap request from description tag",o)}}}catch(m){console.error("Nostr-Components: Zap button: Error fetching zap receipts",m)}finally{r.close(e)}return n.sort((m,h)=>h.date.getTime()-m.date.getTime()),{totalAmount:i/1e3,zapDetails:n}},_=({relays:t,receiversPubKey:e,invoice:s,onSuccess:a})=>{const r=new E,i=Array.from(new Set([...t,"wss://relay.nostr.band"])),n=Math.floor((Date.now()-24*60*60*1e3)/1e3);r.subscribe(i,{kinds:[9735],"#p":[e],since:n},{onevent(c){c.tags.some(p=>p[0]==="bolt11"&&p[1]===s)&&(a(),f())}});const f=()=>{r.close(i)};return f};export{J as extractProfileMetadataContent,M as fetchInvoice,V as fetchTotalZapAmount,D as getBatchedProfileMetadata,x as getProfileMetadata,I as getZapEndpoint,_ as listenForZapReceipt};
2
+ //# sourceMappingURL=zap-utils-BZcaCsT_.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zap-utils-BZcaCsT_.js","sources":["../../src/nostr-zap/zap-utils.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\n\nimport {\n nip57,\n nip05,\n finalizeEvent,\n SimplePool,\n} from 'nostr-tools';\nimport { decodeNip19Entity } from '../common/utils';\nimport { ensureInitialized, signEvent as signEventWithNostrLogin } from '../common/nostr-login-service';\n\n/**\n * Helper utilities for Nostr zap operations (adapted from the original `nostr-zap` repo).\n * These are deliberately kept self-contained so `nostr-zap` Web Component can import\n * everything from a single module without polluting the rest of the codebase.\n */\n\n// Basic in-memory cache – sufficient for component lifetime.\nconst profileCache: Record<string, any> = {};\n\nexport const getProfileMetadata = async (authorId: string) => {\n if (profileCache[authorId]) return profileCache[authorId];\n\n const pool = new SimplePool();\n const relays = [\n 'wss://relay.nostr.band',\n 'wss://purplepag.es',\n 'wss://relay.damus.io',\n 'wss://nostr.wine',\n ];\n\n try {\n const event = await pool.get(relays, {\n authors: [authorId],\n kinds: [0],\n });\n profileCache[authorId] = event;\n return event;\n } finally {\n pool.close(relays);\n }\n};\n\nexport const getBatchedProfileMetadata = async (authorIds: string[]) => {\n // Filter out already cached profiles\n const uncachedIds = authorIds.filter(id => !profileCache[id]);\n\n // If all profiles are cached, return them\n if (uncachedIds.length === 0) {\n return authorIds.map(id => ({ id, profile: profileCache[id] }));\n }\n\n const pool = new SimplePool();\n const relays = [\n 'wss://relay.nostr.band',\n 'wss://purplepag.es',\n 'wss://relay.damus.io',\n 'wss://nostr.wine',\n ];\n\n try {\n // Fetch all uncached profiles in a single query\n const events = await pool.querySync(relays, {\n authors: uncachedIds,\n kinds: [0],\n });\n\n // Cache the fetched profiles\n events.forEach(event => {\n profileCache[event.pubkey] = event;\n });\n\n // Combine cached and newly fetched profiles\n const allProfiles = authorIds.map(id => ({\n id,\n profile: profileCache[id] || null\n }));\n\n return allProfiles;\n } finally {\n pool.close(relays);\n }\n};\n\nexport const extractProfileMetadataContent = (profileMetadata: any) => {\n try {\n return JSON.parse(profileMetadata?.content || '{}');\n } catch {\n return {};\n }\n};\n\nexport const getZapEndpoint = async (profileMetadata: any) => {\n const endpoint = await nip57.getZapEndpoint(profileMetadata);\n if (!endpoint) throw new Error('Failed to retrieve zap LNURL');\n return endpoint;\n};\n\ninterface NostrExtension {\n signEvent(event: any): Promise<{\n id: string;\n sig: string;\n kind: number;\n tags: string[][];\n pubkey: string;\n content: string;\n created_at: number;\n }>;\n}\n\nconst signEvent = async (zapEvent: any, anon?: boolean) => {\n if (!anon) {\n try {\n await ensureInitialized();\n return await signEventWithNostrLogin(zapEvent);\n } catch {\n /* fall-through -> anonymous */\n }\n }\n return finalizeEvent(zapEvent, generateRandomPrivKey());\n};\n\nconst makeZapEvent = async ({\n profile,\n nip19Target,\n amount,\n relays,\n comment,\n anon,\n url,\n}: {\n profile: string;\n nip19Target?: string;\n amount: number;\n relays: string[];\n comment?: string;\n anon?: boolean;\n url?: string;\n}) => {\n const req: any = {\n profile,\n amount,\n relays,\n comment: comment || '',\n };\n if (nip19Target?.startsWith('note')) {\n req.event = decodeNip19Entity(nip19Target);\n }\n const event = nip57.makeZapRequest(req);\n\n if (nip19Target?.startsWith('naddr')) {\n const naddrData: any = decodeNip19Entity(nip19Target);\n const relayTag = naddrData?.relays?.join(',') ?? '';\n event.tags.push(['a', `${naddrData.kind}:${naddrData.pubkey}:${naddrData.identifier}`, relayTag]);\n }\n\n // Add URL-based zap tags if URL is provided\n if (url) {\n event.tags.push(['k', 'web']);\n event.tags.push(['i', normalizeURL(url)]);\n }\n\n // Check if NostrLogin is available (will initialize if needed)\n // Note: We check availability here to decide if we should add 'anon' tag\n // The actual signing happens in signEvent() which will ensure initialization\n let isNostrLoginAvailable = false;\n if (!anon) {\n try {\n await ensureInitialized();\n isNostrLoginAvailable = typeof window !== 'undefined' && !!(window as any).nostr;\n } catch {\n // If initialization fails, fall back to anonymous\n isNostrLoginAvailable = false;\n }\n }\n \n if (!isNostrLoginAvailable || anon) {\n event.tags.push(['anon']);\n }\n\n return signEvent(event, anon);\n};\n\nexport const fetchInvoice = async ({\n zapEndpoint,\n amount,\n comment,\n authorId,\n nip19Target,\n normalizedRelays,\n anon,\n url,\n}: {\n zapEndpoint: string;\n amount: number;\n comment?: string;\n authorId: string;\n nip19Target?: string;\n normalizedRelays: string[];\n anon?: boolean;\n url?: string;\n}): Promise<string> => {\n const zapEvent = await makeZapEvent({\n profile: authorId,\n nip19Target,\n amount,\n relays: normalizedRelays,\n comment: comment ?? '',\n anon,\n url,\n });\n\n\n let invoiceUrl = `${zapEndpoint}?amount=${amount}&nostr=${encodeURIComponent(\n JSON.stringify(zapEvent)\n )}`;\n if (comment) invoiceUrl += `&comment=${encodeURIComponent(comment ?? '')}`;\n\n const res = await fetch(invoiceUrl, { method: 'GET' });\n if (!res.ok) {\n throw new Error(`LNURL request failed: ${res.status} ${res.statusText}`);\n }\n let json: any;\n try {\n json = await res.json();\n } catch {\n throw new Error('Invalid JSON from LNURL endpoint');\n }\n const { pr: invoice, reason, status } = json || {};\n if (invoice) return invoice;\n if (status === 'ERROR') throw new Error(reason ?? 'Unable to fetch invoice');\n throw new Error('Unable to fetch invoice');\n};\n\nconst generateRandomPrivKey = (): Uint8Array => {\n const bytes = new Uint8Array(32);\n if (typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function') {\n crypto.getRandomValues(bytes);\n } else {\n // Node.js fallback during build – use Math.random (not cryptographically strong but acceptable for anon zaps)\n console.warn('crypto.getRandomValues not available, using Math.random as fallback');\n for (let i = 0; i < 32; i++) bytes[i] = Math.floor(Math.random() * 256);\n }\n return bytes;\n};\n\n/**\n * Check if NostrLogin is available\n * @deprecated Use ensureInitialized() instead - it will initialize NostrLogin if needed\n */\nexport const isNip07ExtAvailable = (): boolean => {\n // This function is kept for backward compatibility but will always return false\n // until ensureInitialized() is called. Components should use ensureInitialized() instead.\n return typeof window !== 'undefined' && !!(window as any).nostr;\n};\n\n// ---------------------------------------------------------------------------\n// nip05 resolution helper – very lightweight fetch to /.well-known/nostr.json\n// ---------------------------------------------------------------------------\n\n\n\nexport async function resolveNip05(nip05Identifier: string): Promise<string | null> {\n try {\n const profile = await nip05.queryProfile(nip05Identifier);\n return profile?.pubkey || null;\n } catch (error) {\n console.error(`Failed to resolve NIP-05 ${nip05Identifier}:`, error);\n return null;\n }\n}\n\n// Import necessary types from nostr-tools\nimport type { Filter, Event } from 'nostr-tools';\nimport { normalizeURL } from '../nostr-comment/utils';\n\n// Augment the SimplePool type to include our usage\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\ndeclare module 'nostr-tools' {\n interface SimplePool {\n subscribe(\n relays: string[],\n filter: Filter,\n params: {\n onevent: (event: Event) => void;\n onclose?: () => void;\n id?: string;\n maxWait?: number;\n }\n ): {\n close: () => void;\n };\n }\n}\n\nexport interface ZapDetails {\n amount: number;\n date: Date;\n authorPubkey: string;\n comment?: string;\n}\n\nexport interface ZapAmountResult {\n totalAmount: number;\n zapDetails: ZapDetails[];\n}\n\nexport const fetchTotalZapAmount = async ({\n pubkey,\n relays,\n url,\n}: {\n pubkey: string;\n relays: string[];\n url?: string;\n}): Promise<ZapAmountResult> => {\n // Normalize URL at the beginning for consistent comparison with tags\n const normalizedUrl = url ? normalizeURL(url) : undefined;\n \n const pool = new SimplePool();\n let totalAmount = 0;\n const zapDetails: ZapDetails[] = [];\n\n try {\n // Build filter for zap receipt events\n const filter: any = {\n kinds: [9735], // Zap receipt\n '#p': [pubkey],\n limit: 1000,\n };\n\n // Add URL-based filtering if URL is provided\n // TODO: These tags doesn't appear in zap receipt event.\n // They goes into the description tag, which has the zap request JSON.\n /*\n if (normalizedUrl) {\n filter['#k'] = ['web'];\n filter['#i'] = [normalizedUrl];\n }\n */\n\n // Use pool.querySync to fetch multiple zap receipt events\n const events = await pool.querySync(relays, filter);\n\n for (const event of events) {\n const descriptionTag = event.tags?.find((tag: string[]) => tag[0] === 'description');\n if (descriptionTag?.[1]) {\n try {\n const zapRequest = JSON.parse(descriptionTag[1]);\n const amountTag = zapRequest?.tags?.find((tag: string[]) => tag[0] === 'amount');\n \n // If URL is provided, check for URL-based zap tags\n // TODO: Too much work, since #k and #i tags doesn't appear in zap receipt event.\n // This is not a practical solution, but it's working for now!\n if (normalizedUrl) {\n const kTag = zapRequest?.tags?.find((tag: string[]) => tag[0] === 'k');\n const iTag = zapRequest?.tags?.find((tag: string[]) => tag[0] === 'i');\n \n const iTagNormalized = iTag?.[1] ? normalizeURL(iTag[1]) : '';\n if (kTag?.[1] === 'web' && iTagNormalized === normalizedUrl && amountTag?.[1]) {\n const amount = parseInt(amountTag[1], 10);\n if (amount > 0) {\n totalAmount += amount;\n zapDetails.push({\n amount: amount / 1000, // convert from msats to sats\n date: new Date(event.created_at * 1000),\n authorPubkey: zapRequest.pubkey,\n comment: zapRequest.content,\n });\n }\n }\n } else {\n // No URL filtering - count all zaps\n if (amountTag?.[1]) {\n const amount = parseInt(amountTag[1], 10);\n if (amount > 0) {\n totalAmount += amount;\n zapDetails.push({\n amount: amount / 1000, // convert from msats to sats\n date: new Date(event.created_at * 1000),\n authorPubkey: zapRequest.pubkey,\n comment: zapRequest.content,\n });\n }\n }\n }\n } catch (e) {\n console.error(\"Nostr-Components: Zap button: Could not parse zap request from description tag\", e);\n }\n }\n }\n } catch (error) {\n console.error(\"Nostr-Components: Zap button: Error fetching zap receipts\", error);\n } finally {\n pool.close(relays);\n }\n\n // Sort zap details by date (newest first)\n zapDetails.sort((a, b) => b.date.getTime() - a.date.getTime());\n\n return {\n totalAmount: totalAmount / 1000, // convert from msats to sats\n zapDetails,\n };\n};\n\nexport const listenForZapReceipt = ({\n relays,\n receiversPubKey,\n invoice,\n onSuccess,\n}: {\n relays: string[];\n receiversPubKey: string,\n invoice: string;\n onSuccess: () => void;\n}) => {\n const pool = new SimplePool();\n const normalizedRelays = Array.from(new Set([...relays, 'wss://relay.nostr.band']));\n const since = Math.floor((Date.now() - 24 * 60 * 60 * 1000) / 1000); // current time - 24 hours\n\n pool.subscribe(\n normalizedRelays,\n {\n kinds: [9735],\n '#p': [receiversPubKey],\n since,\n },\n {\n onevent(event: Event) {\n const tags = event.tags as [string, string][];\n if (tags.some(t => t[0] === 'bolt11' && t[1] === invoice)) {\n onSuccess();\n cleanup();\n }\n }\n }\n );\n\n const cleanup = () => {\n pool.close(normalizedRelays);\n };\n\n return cleanup;\n};\n"],"names":["profileCache","getProfileMetadata","authorId","pool","SimplePool","relays","event","getBatchedProfileMetadata","authorIds","uncachedIds","id","extractProfileMetadataContent","profileMetadata","getZapEndpoint","endpoint","nip57","signEvent","zapEvent","anon","ensureInitialized","signEventWithNostrLogin","finalizeEvent","generateRandomPrivKey","makeZapEvent","profile","nip19Target","amount","comment","url","req","normalizeURL","isNostrLoginAvailable","fetchInvoice","zapEndpoint","normalizedRelays","invoiceUrl","res","json","invoice","reason","status","bytes","i","fetchTotalZapAmount","pubkey","normalizedUrl","totalAmount","zapDetails","filter","events","descriptionTag","_a","tag","zapRequest","amountTag","_b","kTag","_c","iTag","_d","iTagNormalized","e","error","a","b","listenForZapReceipt","receiversPubKey","onSuccess","since","t","cleanup"],"mappings":"wMAkBA,MAAMA,EAAoC,CAAA,EAE7BC,EAAqB,MAAOC,GAAqB,CAC5D,GAAIF,EAAaE,CAAQ,EAAG,OAAOF,EAAaE,CAAQ,EAExD,MAAMC,EAAO,IAAIC,EACXC,EAAS,CACb,yBACA,qBACA,uBACA,kBAAA,EAGF,GAAI,CACF,MAAMC,EAAQ,MAAMH,EAAK,IAAIE,EAAQ,CACnC,QAAS,CAACH,CAAQ,EAClB,MAAO,CAAC,CAAC,CAAA,CACV,EACD,OAAAF,EAAaE,CAAQ,EAAII,EAClBA,CACT,QAAA,CACEH,EAAK,MAAME,CAAM,CACnB,CACF,EAEaE,EAA4B,MAAOC,GAAwB,CAEtE,MAAMC,EAAcD,EAAU,UAAa,CAACR,EAAaU,CAAE,CAAC,EAG5D,GAAID,EAAY,SAAW,EACzB,OAAOD,EAAU,IAAIE,IAAO,CAAE,GAAAA,EAAI,QAASV,EAAaU,CAAE,CAAA,EAAI,EAGhE,MAAMP,EAAO,IAAIC,EACXC,EAAS,CACb,yBACA,qBACA,uBACA,kBAAA,EAGF,GAAI,CAQF,OANe,MAAMF,EAAK,UAAUE,EAAQ,CAC1C,QAASI,EACT,MAAO,CAAC,CAAC,CAAA,CACV,GAGM,QAAQH,GAAS,CACtBN,EAAaM,EAAM,MAAM,EAAIA,CAC/B,CAAC,EAGmBE,EAAU,IAAIE,IAAO,CACvC,GAAAA,EACA,QAASV,EAAaU,CAAE,GAAK,IAAA,EAC7B,CAGJ,QAAA,CACEP,EAAK,MAAME,CAAM,CACnB,CACF,EAEaM,EAAiCC,GAAyB,CACrE,GAAI,CACF,OAAO,KAAK,OAAMA,GAAA,YAAAA,EAAiB,UAAW,IAAI,CACpD,MAAQ,CACN,MAAO,CAAA,CACT,CACF,EAEaC,EAAiB,MAAOD,GAAyB,CAC5D,MAAME,EAAW,MAAMC,EAAM,eAAeH,CAAe,EAC3D,GAAI,CAACE,EAAU,MAAM,IAAI,MAAM,8BAA8B,EAC7D,OAAOA,CACT,EAcME,EAAY,MAAOC,EAAeC,IAAmB,CAEvD,GAAI,CACF,aAAMC,EAAA,EACC,MAAMC,EAAwBH,CAAQ,CAC/C,MAAQ,CAER,CAEF,OAAOI,EAAcJ,EAAUK,GAAuB,CACxD,EAEMC,EAAe,MAAO,CAC1B,QAAAC,EACA,YAAAC,EACA,OAAAC,EACA,OAAArB,EACA,QAAAsB,EACA,KAAAT,EACA,IAAAU,CACF,IAQM,CACJ,MAAMC,EAAW,CACf,QAAAL,EACA,OAAAE,EACA,OAAArB,EACA,QAASsB,GAAW,EAAA,EAKhBrB,EAAQS,EAAM,eAAec,CAAG,EASlCD,IACFtB,EAAM,KAAK,KAAK,CAAC,IAAK,KAAK,CAAC,EAC5BA,EAAM,KAAK,KAAK,CAAC,IAAKwB,EAAaF,CAAG,CAAC,CAAC,GAM1C,IAAIG,EAAwB,GAE1B,GAAI,CACF,MAAMZ,EAAA,EACNY,EAAwB,OAAO,OAAW,KAAe,CAAC,CAAE,OAAe,KAC7E,MAAQ,CAENA,EAAwB,EAC1B,CAGF,OAAI,CAACA,GAAyBb,IAC5BZ,EAAM,KAAK,KAAK,CAAC,MAAM,CAAC,EAGnBU,EAAUV,CAAW,CAC9B,EAEa0B,EAAe,MAAO,CACjC,YAAAC,EACA,OAAAP,EACA,QAAAC,EACA,SAAAzB,EACA,YAAAuB,EACA,iBAAAS,EACA,KAAAhB,EACA,IAAAU,CACF,IASuB,CACrB,MAAMX,EAAW,MAAMM,EAAa,CAClC,QAASrB,EACT,YAAAuB,EACA,OAAAC,EACA,OAAQQ,EACR,QAASP,GAAW,GACpB,KAAAT,EACA,IAAAU,CAAA,CACD,EAGD,IAAIO,EAAa,GAAGF,CAAW,WAAWP,CAAM,UAAU,mBACxD,KAAK,UAAUT,CAAQ,CAAA,CACxB,GACGU,IAASQ,GAAc,YAAY,mBAAmBR,GAAW,EAAE,CAAC,IAExE,MAAMS,EAAM,MAAM,MAAMD,EAAY,CAAE,OAAQ,MAAO,EACrD,GAAI,CAACC,EAAI,GACP,MAAM,IAAI,MAAM,yBAAyBA,EAAI,MAAM,IAAIA,EAAI,UAAU,EAAE,EAEzE,IAAIC,EACJ,GAAI,CACFA,EAAO,MAAMD,EAAI,KAAA,CACnB,MAAQ,CACN,MAAM,IAAI,MAAM,kCAAkC,CACpD,CACA,KAAM,CAAE,GAAIE,EAAS,OAAAC,EAAQ,OAAAC,CAAA,EAAWH,GAAQ,CAAA,EAChD,GAAIC,EAAS,OAAOA,EACpB,MAAIE,IAAW,QAAe,IAAI,MAAMD,GAAU,yBAAyB,EACrE,IAAI,MAAM,yBAAyB,CAC3C,EAEMjB,EAAwB,IAAkB,CAC9C,MAAMmB,EAAQ,IAAI,WAAW,EAAE,EAC/B,GAAI,OAAO,OAAW,KAAe,OAAO,OAAO,iBAAoB,WACrE,OAAO,gBAAgBA,CAAK,MACvB,CAEL,QAAQ,KAAK,qEAAqE,EAClF,QAASC,EAAI,EAAGA,EAAI,GAAIA,IAAKD,EAAMC,CAAC,EAAI,KAAK,MAAM,KAAK,OAAA,EAAW,GAAG,CACxE,CACA,OAAOD,CACT,EA+DaE,EAAsB,MAAO,CACxC,OAAAC,EACA,OAAAvC,EACA,IAAAuB,CACF,IAIgC,aAE9B,MAAMiB,EAAgBjB,EAAME,EAAaF,CAAG,EAAI,OAE1CzB,EAAO,IAAIC,EACjB,IAAI0C,EAAc,EAClB,MAAMC,EAA2B,CAAA,EAEjC,GAAI,CAEF,MAAMC,EAAc,CAClB,MAAO,CAAC,IAAI,EACZ,KAAM,CAACJ,CAAM,EACb,MAAO,GAAA,EAcHK,EAAS,MAAM9C,EAAK,UAAUE,EAAQ2C,CAAM,EAElD,UAAW1C,KAAS2C,EAAQ,CAC1B,MAAMC,GAAiBC,EAAA7C,EAAM,OAAN,YAAA6C,EAAY,KAAMC,GAAkBA,EAAI,CAAC,IAAM,eACtE,GAAIF,GAAA,MAAAA,EAAiB,GACnB,GAAI,CACF,MAAMG,EAAa,KAAK,MAAMH,EAAe,CAAC,CAAC,EACzCI,GAAYC,EAAAF,GAAA,YAAAA,EAAY,OAAZ,YAAAE,EAAkB,KAAMH,GAAkBA,EAAI,CAAC,IAAM,UAKvE,GAAIP,EAAe,CACjB,MAAMW,GAAOC,EAAAJ,GAAA,YAAAA,EAAY,OAAZ,YAAAI,EAAkB,KAAML,GAAkBA,EAAI,CAAC,IAAM,KAC5DM,GAAOC,EAAAN,GAAA,YAAAA,EAAY,OAAZ,YAAAM,EAAkB,KAAMP,GAAkBA,EAAI,CAAC,IAAM,KAE5DQ,EAAiBF,GAAA,MAAAA,EAAO,GAAK5B,EAAa4B,EAAK,CAAC,CAAC,EAAI,GAC3D,IAAIF,GAAA,YAAAA,EAAO,MAAO,OAASI,IAAmBf,IAAiBS,GAAA,MAAAA,EAAY,IAAI,CAC7E,MAAM5B,EAAS,SAAS4B,EAAU,CAAC,EAAG,EAAE,EACpC5B,EAAS,IACXoB,GAAepB,EACfqB,EAAW,KAAK,CACd,OAAQrB,EAAS,IACjB,KAAM,IAAI,KAAKpB,EAAM,WAAa,GAAI,EACtC,aAAc+C,EAAW,OACzB,QAASA,EAAW,OAAA,CACrB,EAEL,CACF,SAEMC,GAAA,MAAAA,EAAY,GAAI,CAClB,MAAM5B,EAAS,SAAS4B,EAAU,CAAC,EAAG,EAAE,EACpC5B,EAAS,IACXoB,GAAepB,EACfqB,EAAW,KAAK,CACd,OAAQrB,EAAS,IACjB,KAAM,IAAI,KAAKpB,EAAM,WAAa,GAAI,EACtC,aAAc+C,EAAW,OACzB,QAASA,EAAW,OAAA,CACrB,EAEL,CAEJ,OAASQ,EAAG,CACV,QAAQ,MAAM,iFAAkFA,CAAC,CACnG,CAEJ,CACF,OAASC,EAAO,CACd,QAAQ,MAAM,4DAA6DA,CAAK,CAClF,QAAA,CACE3D,EAAK,MAAME,CAAM,CACnB,CAGA,OAAA0C,EAAW,KAAK,CAACgB,EAAGC,IAAMA,EAAE,KAAK,UAAYD,EAAE,KAAK,QAAA,CAAS,EAEtD,CACL,YAAajB,EAAc,IAC3B,WAAAC,CAAA,CAEJ,EAEakB,EAAsB,CAAC,CAClC,OAAA5D,EACA,gBAAA6D,EACA,QAAA5B,EACA,UAAA6B,CACF,IAKM,CACJ,MAAMhE,EAAO,IAAIC,EACX8B,EAAmB,MAAM,KAAK,IAAI,IAAI,CAAC,GAAG7B,EAAQ,wBAAwB,CAAC,CAAC,EAC5E+D,EAAQ,KAAK,OAAO,KAAK,MAAQ,GAAK,GAAK,GAAK,KAAQ,GAAI,EAElEjE,EAAK,UACH+B,EACA,CACE,MAAO,CAAC,IAAI,EACZ,KAAM,CAACgC,CAAe,EACtB,MAAAE,CAAA,EAEF,CACE,QAAQ9D,EAAc,CACPA,EAAM,KACV,KAAK+D,GAAKA,EAAE,CAAC,IAAM,UAAYA,EAAE,CAAC,IAAM/B,CAAO,IACtD6B,EAAA,EACAG,EAAA,EAEJ,CAAA,CACF,EAGF,MAAMA,EAAU,IAAM,CACpBnE,EAAK,MAAM+B,CAAgB,CAC7B,EAEA,OAAOoC,CACT"}
@@ -1,42 +1,42 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/pure-DPo-pzxM.js","assets/nostr-service-CnaPxjc6.js"])))=>i.map(i=>d[i]);
2
- var Xt=Object.defineProperty;var Zt=(o,r,t)=>r in o?Xt(o,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[r]=t;var f=(o,r,t)=>Zt(o,typeof r!="symbol"?r+"":r,t);import{_ as xe}from"../assets/preload-helper-D7HrI6pR.js";import{b as Qt,c as Jt,d as en}from"../assets/nostr-service-CnaPxjc6.js";import{n as gt}from"../assets/utils--bxLbhGF.js";function B(o){return o.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}function tn(o){const t=Date.now()/1e3-o;return t<60?"just now":t<3600?`${Math.floor(t/60)}m ago`:t<86400?`${Math.floor(t/3600)}h ago`:t<2592e3?`${Math.floor(t/86400)}d ago`:new Date(o*1e3).toLocaleDateString()}function kt(o){var r,t;return(r=o.userProfile)!=null&&r.displayName?o.userProfile.displayName:(t=o.userProfile)!=null&&t.name?o.userProfile.name:`${o.pubkey.slice(0,8)}...${o.pubkey.slice(-4)}`}function nn(o){var r,t;if((r=o.userProfile)!=null&&r.image&&o.userProfile.image.trim()!==""){let n=o.userProfile.image.trim();return console.log("Processing image URL:",n,"for user:",o.userProfile.name||o.pubkey),(n.startsWith("Qm")||n.startsWith("bafy"))&&(n=`https://ipfs.io/ipfs/${n}`,console.log("Converted IPFS to gateway URL:",n)),n.startsWith("//")&&(n="https:"+n,console.log("Added protocol to URL:",n)),console.log("Final image URL:",n),n}return console.log("No image found for user:",((t=o.userProfile)==null?void 0:t.name)||o.pubkey,"using default"),"../../assets/default_dp.png"}function St(o,r=!1,t=null,n=null,a="anon",s=!1){const c=kt(o),h=nn(o),g=tn(o.created_at),y=o.depth||0,d=6,E=t===o.id;return`
3
- <div class="modern-comment" data-comment-id="${B(o.id)}" data-depth="${y}">
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/pure-laCRX9eG.js","assets/nostr-service-m3Hgc5Xx.js"])))=>i.map(i=>d[i]);
2
+ var Zt=Object.defineProperty;var Qt=(o,r,t)=>r in o?Zt(o,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[r]=t;var f=(o,r,t)=>Qt(o,typeof r!="symbol"?r+"":r,t);import{_ as ve}from"../assets/preload-helper-D7HrI6pR.js";import{N as Jt,D as en,e as tn}from"../assets/nostr-service-m3Hgc5Xx.js";import{n as xt}from"../assets/utils--bxLbhGF.js";function Y(o){return o.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}function nn(o){const t=Date.now()/1e3-o;return t<60?"just now":t<3600?`${Math.floor(t/60)}m ago`:t<86400?`${Math.floor(t/3600)}h ago`:t<2592e3?`${Math.floor(t/86400)}d ago`:new Date(o*1e3).toLocaleDateString()}function Rt(o){var r,t;return(r=o.userProfile)!=null&&r.displayName?o.userProfile.displayName:(t=o.userProfile)!=null&&t.name?o.userProfile.name:`${o.pubkey.slice(0,8)}...${o.pubkey.slice(-4)}`}function on(o){var r,t;if((r=o.userProfile)!=null&&r.image&&o.userProfile.image.trim()!==""){let n=o.userProfile.image.trim();return console.log("Processing image URL:",n,"for user:",o.userProfile.name||o.pubkey),(n.startsWith("Qm")||n.startsWith("bafy"))&&(n=`https://ipfs.io/ipfs/${n}`,console.log("Converted IPFS to gateway URL:",n)),n.startsWith("//")&&(n="https:"+n,console.log("Added protocol to URL:",n)),console.log("Final image URL:",n),n}return console.log("No image found for user:",((t=o.userProfile)==null?void 0:t.name)||o.pubkey,"using default"),"./assets/default_dp.png"}function Lt(o,r=!1,t=null,n=null,i="anon",s=!1){const c=Rt(o),h=on(o),g=nn(o.created_at),y=o.depth||0,d=6,A=t===o.id;return`
3
+ <div class="modern-comment" data-comment-id="${Y(o.id)}" data-depth="${y}">
4
4
  <div class="comment-content-wrapper">
5
5
  <div class="comment-avatar-section">
6
6
  <img src="${h}" alt="Avatar" class="comment-avatar" />
7
7
  </div>
8
8
  <div class="comment-body">
9
9
  <div class="comment-header">
10
- <span class="comment-author">${B(c)}</span>
11
- <span class="comment-time">${B(g)}</span>
10
+ <span class="comment-author">${Y(c)}</span>
11
+ <span class="comment-time">${Y(g)}</span>
12
12
  </div>
13
13
  <div class="comment-text">
14
- ${B(o.content.trim())}
14
+ ${Y(o.content.trim())}
15
15
  </div>
16
16
  <div class="comment-actions">
17
- ${r?"":`<button class="reply-btn" data-comment-id="${B(o.id)}" aria-label="Reply to comment">
17
+ ${r?"":`<button class="reply-btn" data-comment-id="${Y(o.id)}" aria-label="Reply to comment">
18
18
  <span class="reply-icon">💬</span>
19
19
  <span class="reply-text">Reply</span>
20
20
  </button>`}
21
21
  </div>
22
- ${E?on(o,n,a,s):""}
22
+ ${A?rn(o,n,i,s):""}
23
23
  </div>
24
24
  </div>
25
25
  ${o.replies.length>0?`
26
26
  <div class="comment-replies" style="margin-left: ${Math.min(y+1,d)*24}px;">
27
- ${o.replies.map(D=>St(D,r,t,n,a,s)).join("")}
27
+ ${o.replies.map(D=>Lt(D,r,t,n,i,s)).join("")}
28
28
  </div>
29
29
  `:""}
30
30
  </div>
31
- `}function on(o,r,t="anon",n=!1){let a="../../assets/default_dp.png";if(console.log("renderInlineReplyForm - currentUserProfile:",r),r!=null&&r.image&&r.image.trim()!==""){let c=r.image.trim();console.log("Inline reply form - Processing image URL:",c),(c.startsWith("Qm")||c.startsWith("bafy"))&&(c=`https://ipfs.io/ipfs/${c}`,console.log("Inline reply form - Converted IPFS to gateway URL:",c)),c.startsWith("//")&&(c="https:"+c,console.log("Inline reply form - Added protocol to URL:",c)),console.log("Inline reply form - Final image URL:",c),a=c}else console.log("Inline reply form - No image found, using default");const s=kt(o);return`
31
+ `}function rn(o,r,t="anon",n=!1){let i="./assets/default_dp.png";if(console.log("renderInlineReplyForm - currentUserProfile:",r),r!=null&&r.image&&r.image.trim()!==""){let c=r.image.trim();console.log("Inline reply form - Processing image URL:",c),(c.startsWith("Qm")||c.startsWith("bafy"))&&(c=`https://ipfs.io/ipfs/${c}`,console.log("Inline reply form - Converted IPFS to gateway URL:",c)),c.startsWith("//")&&(c="https:"+c,console.log("Inline reply form - Added protocol to URL:",c)),console.log("Inline reply form - Final image URL:",c),i=c}else console.log("Inline reply form - No image found, using default");const s=Rt(o);return`
32
32
  <div class="inline-reply-form">
33
33
  <div class="reply-context">
34
- <span class="reply-context-text">💬 Replying to <strong>${B(s)}</strong></span>
34
+ <span class="reply-context-text">💬 Replying to <strong>${Y(s)}</strong></span>
35
35
  <button data-role="cancel-reply" class="cancel-reply-btn" aria-label="Cancel reply">✕</button>
36
36
  </div>
37
37
  <div class="reply-input-container">
38
38
  <div class="reply-input-avatar">
39
- <img src="${a}" alt="Your avatar" class="user-avatar" />
39
+ <img src="${i}" alt="Your avatar" class="user-avatar" />
40
40
  </div>
41
41
  <div class="reply-input-main">
42
42
  <textarea
@@ -67,13 +67,13 @@ var Xt=Object.defineProperty;var Zt=(o,r,t)=>r in o?Xt(o,r,{enumerable:!0,config
67
67
  </div>
68
68
  </div>
69
69
  </div>
70
- `}function rn(o,r,t,n,a,s="anon",c=!1){return o?"":(console.log("renderCommentForm - currentUserProfile:",n),`
70
+ `}function an(o,r,t,n,i,s="anon",c=!1){return o?"":(console.log("renderCommentForm - currentUserProfile:",n),`
71
71
  <div class="modern-comment-form">
72
72
  <div class="comment-input-container">
73
73
  <div class="comment-input-main">
74
74
  <textarea
75
75
  data-role="comment-input"
76
- placeholder="${B(r)}"
76
+ placeholder="${Y(r)}"
77
77
  rows="3"
78
78
  ${t?"disabled":""}
79
79
  class="modern-comment-textarea"
@@ -102,7 +102,7 @@ var Xt=Object.defineProperty;var Zt=(o,r,t)=>r in o?Xt(o,r,{enumerable:!0,config
102
102
  </div>
103
103
  </div>
104
104
  </div>
105
- `)}function an(o,r=!1,t=null,n=null,a="anon",s=!1){const c=Rt(o);return c===0?`
105
+ `)}function sn(o,r=!1,t=null,n=null,i="anon",s=!1){const c=Pt(o);return c===0?`
106
106
  <div class="no-comments">
107
107
  <p>No comments yet. Be the first to comment!</p>
108
108
  </div>
@@ -115,10 +115,10 @@ var Xt=Object.defineProperty;var Zt=(o,r,t)=>r in o?Xt(o,r,{enumerable:!0,config
115
115
  </div>
116
116
  </div>
117
117
  <div class="comments-container">
118
- ${o.map(h=>St(h,r,t,n,a,s)).join("")}
118
+ ${o.map(h=>Lt(h,r,t,n,i,s)).join("")}
119
119
  </div>
120
120
  </div>
121
- `}function Rt(o){let r=0;for(const t of o)r+=1+Rt(t.replies);return r}function sn(o,r,t,n,a,s,c,h=null,g=null,y="anon",d=!1){return o?`
121
+ `}function Pt(o){let r=0;for(const t of o)r+=1+Pt(t.replies);return r}function ln(o,r,t,n,i,s,c,h=null,g=null,y="anon",d=!1){return o?`
122
122
  <div class="comment-widget loading">
123
123
  <div class="loading-indicator">
124
124
  <div class="loading-spinner"></div>
@@ -129,18 +129,18 @@ var Xt=Object.defineProperty;var Zt=(o,r,t)=>r in o?Xt(o,r,{enumerable:!0,config
129
129
  <div class="comment-widget error">
130
130
  <div class="error-message">
131
131
  <p>❌ Failed to load comments</p>
132
- ${t?`<small>${B(t)}</small>`:""}
132
+ ${t?`<small>${Y(t)}</small>`:""}
133
133
  </div>
134
134
  </div>
135
135
  `:`
136
136
  <div class="comment-widget">
137
- ${rn(a,s,c,h,g,y,d)}
138
- ${an(n,a,g,h,y,d)}
137
+ ${an(i,s,c,h,g,y,d)}
138
+ ${sn(n,i,g,h,y,d)}
139
139
  <div class="powered-by">
140
140
  <small>Powered by <a href="https://nostr.org" target="_blank">Nostr</a></small>
141
141
  </div>
142
142
  </div>
143
- `}function ln(o){return`
143
+ `}function cn(o){return`
144
144
  <style>
145
145
  :host {
146
146
  /* Define CSS variables on the host element */
@@ -900,8 +900,8 @@ var Xt=Object.defineProperty;var Zt=(o,r,t)=>r in o?Xt(o,r,{enumerable:!0,config
900
900
  }
901
901
  }
902
902
  </style>
903
- `}/*! @license DOMPurify 3.2.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.6/LICENSE */const{entries:Lt,setPrototypeOf:bt,isFrozen:cn,getPrototypeOf:mn,getOwnPropertyDescriptor:dn}=Object;let{freeze:I,seal:M,create:Pt}=Object,{apply:We,construct:Ge}=typeof Reflect<"u"&&Reflect;I||(I=function(r){return r});M||(M=function(r){return r});We||(We=function(r,t,n){return r.apply(t,n)});Ge||(Ge=function(r,t){return new r(...t)});const ve=C(Array.prototype.forEach),pn=C(Array.prototype.lastIndexOf),yt=C(Array.prototype.pop),se=C(Array.prototype.push),un=C(Array.prototype.splice),Ee=C(String.prototype.toLowerCase),ze=C(String.prototype.toString),xt=C(String.prototype.match),le=C(String.prototype.replace),fn=C(String.prototype.indexOf),hn=C(String.prototype.trim),z=C(Object.prototype.hasOwnProperty),N=C(RegExp.prototype.test),ce=gn(TypeError);function C(o){return function(r){r instanceof RegExp&&(r.lastIndex=0);for(var t=arguments.length,n=new Array(t>1?t-1:0),a=1;a<t;a++)n[a-1]=arguments[a];return We(o,r,n)}}function gn(o){return function(){for(var r=arguments.length,t=new Array(r),n=0;n<r;n++)t[n]=arguments[n];return Ge(o,t)}}function u(o,r){let t=arguments.length>2&&arguments[2]!==void 0?arguments[2]:Ee;bt&&bt(o,null);let n=r.length;for(;n--;){let a=r[n];if(typeof a=="string"){const s=t(a);s!==a&&(cn(r)||(r[n]=s),a=s)}o[a]=!0}return o}function bn(o){for(let r=0;r<o.length;r++)z(o,r)||(o[r]=null);return o}function G(o){const r=Pt(null);for(const[t,n]of Lt(o))z(o,t)&&(Array.isArray(n)?r[t]=bn(n):n&&typeof n=="object"&&n.constructor===Object?r[t]=G(n):r[t]=n);return r}function me(o,r){for(;o!==null;){const n=dn(o,r);if(n){if(n.get)return C(n.get);if(typeof n.value=="function")return C(n.value)}o=mn(o)}function t(){return null}return t}const vt=I(["a","abbr","acronym","address","area","article","aside","audio","b","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dialog","dir","div","dl","dt","element","em","fieldset","figcaption","figure","font","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","img","input","ins","kbd","label","legend","li","main","map","mark","marquee","menu","menuitem","meter","nav","nobr","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","tr","track","tt","u","ul","var","video","wbr"]),Fe=I(["svg","a","altglyph","altglyphdef","altglyphitem","animatecolor","animatemotion","animatetransform","circle","clippath","defs","desc","ellipse","filter","font","g","glyph","glyphref","hkern","image","line","lineargradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialgradient","rect","stop","style","switch","symbol","text","textpath","title","tref","tspan","view","vkern"]),$e=I(["feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence"]),yn=I(["animate","color-profile","cursor","discard","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","foreignobject","hatch","hatchpath","mesh","meshgradient","meshpatch","meshrow","missing-glyph","script","set","solidcolor","unknown","use"]),He=I(["math","menclose","merror","mfenced","mfrac","mglyph","mi","mlabeledtr","mmultiscripts","mn","mo","mover","mpadded","mphantom","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msup","msubsup","mtable","mtd","mtext","mtr","munder","munderover","mprescripts"]),xn=I(["maction","maligngroup","malignmark","mlongdiv","mscarries","mscarry","msgroup","mstack","msline","msrow","semantics","annotation","annotation-xml","mprescripts","none"]),Tt=I(["#text"]),Et=I(["accept","action","align","alt","autocapitalize","autocomplete","autopictureinpicture","autoplay","background","bgcolor","border","capture","cellpadding","cellspacing","checked","cite","class","clear","color","cols","colspan","controls","controlslist","coords","crossorigin","datetime","decoding","default","dir","disabled","disablepictureinpicture","disableremoteplayback","download","draggable","enctype","enterkeyhint","face","for","headers","height","hidden","high","href","hreflang","id","inputmode","integrity","ismap","kind","label","lang","list","loading","loop","low","max","maxlength","media","method","min","minlength","multiple","muted","name","nonce","noshade","novalidate","nowrap","open","optimum","pattern","placeholder","playsinline","popover","popovertarget","popovertargetaction","poster","preload","pubdate","radiogroup","readonly","rel","required","rev","reversed","role","rows","rowspan","spellcheck","scope","selected","shape","size","sizes","span","srclang","start","src","srcset","step","style","summary","tabindex","title","translate","type","usemap","valign","value","width","wrap","xmlns","slot"]),Ke=I(["accent-height","accumulate","additive","alignment-baseline","amplitude","ascent","attributename","attributetype","azimuth","basefrequency","baseline-shift","begin","bias","by","class","clip","clippathunits","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cx","cy","d","dx","dy","diffuseconstant","direction","display","divisor","dur","edgemode","elevation","end","exponent","fill","fill-opacity","fill-rule","filter","filterunits","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","fx","fy","g1","g2","glyph-name","glyphref","gradientunits","gradienttransform","height","href","id","image-rendering","in","in2","intercept","k","k1","k2","k3","k4","kerning","keypoints","keysplines","keytimes","lang","lengthadjust","letter-spacing","kernelmatrix","kernelunitlength","lighting-color","local","marker-end","marker-mid","marker-start","markerheight","markerunits","markerwidth","maskcontentunits","maskunits","max","mask","media","method","mode","min","name","numoctaves","offset","operator","opacity","order","orient","orientation","origin","overflow","paint-order","path","pathlength","patterncontentunits","patterntransform","patternunits","points","preservealpha","preserveaspectratio","primitiveunits","r","rx","ry","radius","refx","refy","repeatcount","repeatdur","restart","result","rotate","scale","seed","shape-rendering","slope","specularconstant","specularexponent","spreadmethod","startoffset","stddeviation","stitchtiles","stop-color","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke","stroke-width","style","surfacescale","systemlanguage","tabindex","tablevalues","targetx","targety","transform","transform-origin","text-anchor","text-decoration","text-rendering","textlength","type","u1","u2","unicode","values","viewbox","visibility","version","vert-adv-y","vert-origin-x","vert-origin-y","width","word-spacing","wrap","writing-mode","xchannelselector","ychannelselector","x","x1","x2","xmlns","y","y1","y2","z","zoomandpan"]),At=I(["accent","accentunder","align","bevelled","close","columnsalign","columnlines","columnspan","denomalign","depth","dir","display","displaystyle","encoding","fence","frame","height","href","id","largeop","length","linethickness","lspace","lquote","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","rquote","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","voffset","width","xmlns"]),Te=I(["xlink:href","xml:id","xlink:title","xml:space","xmlns:xlink"]),vn=M(/\{\{[\w\W]*|[\w\W]*\}\}/gm),Tn=M(/<%[\w\W]*|[\w\W]*%>/gm),En=M(/\$\{[\w\W]*/gm),An=M(/^data-[\-\w.\u00B7-\uFFFF]+$/),wn=M(/^aria-[\-\w]+$/),Nt=M(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),_n=M(/^(?:\w+script|data):/i),kn=M(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),It=M(/^html$/i),Sn=M(/^[a-z][.\w]*(-[.\w]+)+$/i);var wt=Object.freeze({__proto__:null,ARIA_ATTR:wn,ATTR_WHITESPACE:kn,CUSTOM_ELEMENT:Sn,DATA_ATTR:An,DOCTYPE_NAME:It,ERB_EXPR:Tn,IS_ALLOWED_URI:Nt,IS_SCRIPT_OR_DATA:_n,MUSTACHE_EXPR:vn,TMPLIT_EXPR:En});const de={element:1,text:3,progressingInstruction:7,comment:8,document:9},Rn=function(){return typeof window>"u"?null:window},Ln=function(r,t){if(typeof r!="object"||typeof r.createPolicy!="function")return null;let n=null;const a="data-tt-policy-suffix";t&&t.hasAttribute(a)&&(n=t.getAttribute(a));const s="dompurify"+(n?"#"+n:"");try{return r.createPolicy(s,{createHTML(c){return c},createScriptURL(c){return c}})}catch{return console.warn("TrustedTypes policy "+s+" could not be created."),null}},_t=function(){return{afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]}};function Ct(){let o=arguments.length>0&&arguments[0]!==void 0?arguments[0]:Rn();const r=m=>Ct(m);if(r.version="3.2.6",r.removed=[],!o||!o.document||o.document.nodeType!==de.document||!o.Element)return r.isSupported=!1,r;let{document:t}=o;const n=t,a=n.currentScript,{DocumentFragment:s,HTMLTemplateElement:c,Node:h,Element:g,NodeFilter:y,NamedNodeMap:d=o.NamedNodeMap||o.MozNamedAttrMap,HTMLFormElement:E,DOMParser:D,trustedTypes:Y}=o,p=g.prototype,x=me(p,"cloneNode"),k=me(p,"remove"),te=me(p,"nextSibling"),U=me(p,"childNodes"),$=me(p,"parentNode");if(typeof c=="function"){const m=t.createElement("template");m.content&&m.content.ownerDocument&&(t=m.content.ownerDocument)}let L,ne="";const{implementation:Ae,createNodeIterator:Dt,createDocumentFragment:Ot,getElementsByTagName:Mt}=t,{importNode:Ut}=n;let P=_t();r.isSupported=typeof Lt=="function"&&typeof $=="function"&&Ae&&Ae.createHTMLDocument!==void 0;const{MUSTACHE_EXPR:we,ERB_EXPR:_e,TMPLIT_EXPR:ke,DATA_ATTR:zt,ARIA_ATTR:Ft,IS_SCRIPT_OR_DATA:$t,ATTR_WHITESPACE:Be,CUSTOM_ELEMENT:Ht}=wt;let{IS_ALLOWED_URI:Ye}=wt,A=null;const qe=u({},[...vt,...Fe,...$e,...He,...Tt]);let _=null;const Ve=u({},[...Et,...Ke,...At,...Te]);let v=Object.seal(Pt(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),oe=null,Se=null,je=!0,Re=!0,Xe=!1,Ze=!0,V=!1,pe=!0,q=!1,Le=!1,Pe=!1,j=!1,ue=!1,fe=!1,Qe=!0,Je=!1;const Kt="user-content-";let Ne=!0,re=!1,X={},Z=null;const et=u({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]);let tt=null;const nt=u({},["audio","video","img","source","image","track"]);let Ie=null;const ot=u({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),he="http://www.w3.org/1998/Math/MathML",ge="http://www.w3.org/2000/svg",H="http://www.w3.org/1999/xhtml";let Q=H,Ce=!1,De=null;const Wt=u({},[he,ge,H],ze);let be=u({},["mi","mo","mn","ms","mtext"]),ye=u({},["annotation-xml"]);const Gt=u({},["title","style","font","a","script"]);let ie=null;const Bt=["application/xhtml+xml","text/html"],Yt="text/html";let w=null,J=null;const qt=t.createElement("form"),rt=function(e){return e instanceof RegExp||e instanceof Function},Oe=function(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};if(!(J&&J===e)){if((!e||typeof e!="object")&&(e={}),e=G(e),ie=Bt.indexOf(e.PARSER_MEDIA_TYPE)===-1?Yt:e.PARSER_MEDIA_TYPE,w=ie==="application/xhtml+xml"?ze:Ee,A=z(e,"ALLOWED_TAGS")?u({},e.ALLOWED_TAGS,w):qe,_=z(e,"ALLOWED_ATTR")?u({},e.ALLOWED_ATTR,w):Ve,De=z(e,"ALLOWED_NAMESPACES")?u({},e.ALLOWED_NAMESPACES,ze):Wt,Ie=z(e,"ADD_URI_SAFE_ATTR")?u(G(ot),e.ADD_URI_SAFE_ATTR,w):ot,tt=z(e,"ADD_DATA_URI_TAGS")?u(G(nt),e.ADD_DATA_URI_TAGS,w):nt,Z=z(e,"FORBID_CONTENTS")?u({},e.FORBID_CONTENTS,w):et,oe=z(e,"FORBID_TAGS")?u({},e.FORBID_TAGS,w):G({}),Se=z(e,"FORBID_ATTR")?u({},e.FORBID_ATTR,w):G({}),X=z(e,"USE_PROFILES")?e.USE_PROFILES:!1,je=e.ALLOW_ARIA_ATTR!==!1,Re=e.ALLOW_DATA_ATTR!==!1,Xe=e.ALLOW_UNKNOWN_PROTOCOLS||!1,Ze=e.ALLOW_SELF_CLOSE_IN_ATTR!==!1,V=e.SAFE_FOR_TEMPLATES||!1,pe=e.SAFE_FOR_XML!==!1,q=e.WHOLE_DOCUMENT||!1,j=e.RETURN_DOM||!1,ue=e.RETURN_DOM_FRAGMENT||!1,fe=e.RETURN_TRUSTED_TYPE||!1,Pe=e.FORCE_BODY||!1,Qe=e.SANITIZE_DOM!==!1,Je=e.SANITIZE_NAMED_PROPS||!1,Ne=e.KEEP_CONTENT!==!1,re=e.IN_PLACE||!1,Ye=e.ALLOWED_URI_REGEXP||Nt,Q=e.NAMESPACE||H,be=e.MATHML_TEXT_INTEGRATION_POINTS||be,ye=e.HTML_INTEGRATION_POINTS||ye,v=e.CUSTOM_ELEMENT_HANDLING||{},e.CUSTOM_ELEMENT_HANDLING&&rt(e.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(v.tagNameCheck=e.CUSTOM_ELEMENT_HANDLING.tagNameCheck),e.CUSTOM_ELEMENT_HANDLING&&rt(e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(v.attributeNameCheck=e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),e.CUSTOM_ELEMENT_HANDLING&&typeof e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements=="boolean"&&(v.allowCustomizedBuiltInElements=e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),V&&(Re=!1),ue&&(j=!0),X&&(A=u({},Tt),_=[],X.html===!0&&(u(A,vt),u(_,Et)),X.svg===!0&&(u(A,Fe),u(_,Ke),u(_,Te)),X.svgFilters===!0&&(u(A,$e),u(_,Ke),u(_,Te)),X.mathMl===!0&&(u(A,He),u(_,At),u(_,Te))),e.ADD_TAGS&&(A===qe&&(A=G(A)),u(A,e.ADD_TAGS,w)),e.ADD_ATTR&&(_===Ve&&(_=G(_)),u(_,e.ADD_ATTR,w)),e.ADD_URI_SAFE_ATTR&&u(Ie,e.ADD_URI_SAFE_ATTR,w),e.FORBID_CONTENTS&&(Z===et&&(Z=G(Z)),u(Z,e.FORBID_CONTENTS,w)),Ne&&(A["#text"]=!0),q&&u(A,["html","head","body"]),A.table&&(u(A,["tbody"]),delete oe.tbody),e.TRUSTED_TYPES_POLICY){if(typeof e.TRUSTED_TYPES_POLICY.createHTML!="function")throw ce('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if(typeof e.TRUSTED_TYPES_POLICY.createScriptURL!="function")throw ce('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');L=e.TRUSTED_TYPES_POLICY,ne=L.createHTML("")}else L===void 0&&(L=Ln(Y,a)),L!==null&&typeof ne=="string"&&(ne=L.createHTML(""));I&&I(e),J=e}},it=u({},[...Fe,...$e,...yn]),at=u({},[...He,...xn]),Vt=function(e){let i=$(e);(!i||!i.tagName)&&(i={namespaceURI:Q,tagName:"template"});const l=Ee(e.tagName),b=Ee(i.tagName);return De[e.namespaceURI]?e.namespaceURI===ge?i.namespaceURI===H?l==="svg":i.namespaceURI===he?l==="svg"&&(b==="annotation-xml"||be[b]):!!it[l]:e.namespaceURI===he?i.namespaceURI===H?l==="math":i.namespaceURI===ge?l==="math"&&ye[b]:!!at[l]:e.namespaceURI===H?i.namespaceURI===ge&&!ye[b]||i.namespaceURI===he&&!be[b]?!1:!at[l]&&(Gt[l]||!it[l]):!!(ie==="application/xhtml+xml"&&De[e.namespaceURI]):!1},F=function(e){se(r.removed,{element:e});try{$(e).removeChild(e)}catch{k(e)}},ee=function(e,i){try{se(r.removed,{attribute:i.getAttributeNode(e),from:i})}catch{se(r.removed,{attribute:null,from:i})}if(i.removeAttribute(e),e==="is")if(j||ue)try{F(i)}catch{}else try{i.setAttribute(e,"")}catch{}},st=function(e){let i=null,l=null;if(Pe)e="<remove></remove>"+e;else{const T=xt(e,/^[\r\n\t ]+/);l=T&&T[0]}ie==="application/xhtml+xml"&&Q===H&&(e='<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>'+e+"</body></html>");const b=L?L.createHTML(e):e;if(Q===H)try{i=new D().parseFromString(b,ie)}catch{}if(!i||!i.documentElement){i=Ae.createDocument(Q,"template",null);try{i.documentElement.innerHTML=Ce?ne:b}catch{}}const S=i.body||i.documentElement;return e&&l&&S.insertBefore(t.createTextNode(l),S.childNodes[0]||null),Q===H?Mt.call(i,q?"html":"body")[0]:q?i.documentElement:S},lt=function(e){return Dt.call(e.ownerDocument||e,e,y.SHOW_ELEMENT|y.SHOW_COMMENT|y.SHOW_TEXT|y.SHOW_PROCESSING_INSTRUCTION|y.SHOW_CDATA_SECTION,null)},Me=function(e){return e instanceof E&&(typeof e.nodeName!="string"||typeof e.textContent!="string"||typeof e.removeChild!="function"||!(e.attributes instanceof d)||typeof e.removeAttribute!="function"||typeof e.setAttribute!="function"||typeof e.namespaceURI!="string"||typeof e.insertBefore!="function"||typeof e.hasChildNodes!="function")},ct=function(e){return typeof h=="function"&&e instanceof h};function K(m,e,i){ve(m,l=>{l.call(r,e,i,J)})}const mt=function(e){let i=null;if(K(P.beforeSanitizeElements,e,null),Me(e))return F(e),!0;const l=w(e.nodeName);if(K(P.uponSanitizeElement,e,{tagName:l,allowedTags:A}),pe&&e.hasChildNodes()&&!ct(e.firstElementChild)&&N(/<[/\w!]/g,e.innerHTML)&&N(/<[/\w!]/g,e.textContent)||e.nodeType===de.progressingInstruction||pe&&e.nodeType===de.comment&&N(/<[/\w]/g,e.data))return F(e),!0;if(!A[l]||oe[l]){if(!oe[l]&&pt(l)&&(v.tagNameCheck instanceof RegExp&&N(v.tagNameCheck,l)||v.tagNameCheck instanceof Function&&v.tagNameCheck(l)))return!1;if(Ne&&!Z[l]){const b=$(e)||e.parentNode,S=U(e)||e.childNodes;if(S&&b){const T=S.length;for(let O=T-1;O>=0;--O){const W=x(S[O],!0);W.__removalCount=(e.__removalCount||0)+1,b.insertBefore(W,te(e))}}}return F(e),!0}return e instanceof g&&!Vt(e)||(l==="noscript"||l==="noembed"||l==="noframes")&&N(/<\/no(script|embed|frames)/i,e.innerHTML)?(F(e),!0):(V&&e.nodeType===de.text&&(i=e.textContent,ve([we,_e,ke],b=>{i=le(i,b," ")}),e.textContent!==i&&(se(r.removed,{element:e.cloneNode()}),e.textContent=i)),K(P.afterSanitizeElements,e,null),!1)},dt=function(e,i,l){if(Qe&&(i==="id"||i==="name")&&(l in t||l in qt))return!1;if(!(Re&&!Se[i]&&N(zt,i))){if(!(je&&N(Ft,i))){if(!_[i]||Se[i]){if(!(pt(e)&&(v.tagNameCheck instanceof RegExp&&N(v.tagNameCheck,e)||v.tagNameCheck instanceof Function&&v.tagNameCheck(e))&&(v.attributeNameCheck instanceof RegExp&&N(v.attributeNameCheck,i)||v.attributeNameCheck instanceof Function&&v.attributeNameCheck(i))||i==="is"&&v.allowCustomizedBuiltInElements&&(v.tagNameCheck instanceof RegExp&&N(v.tagNameCheck,l)||v.tagNameCheck instanceof Function&&v.tagNameCheck(l))))return!1}else if(!Ie[i]){if(!N(Ye,le(l,Be,""))){if(!((i==="src"||i==="xlink:href"||i==="href")&&e!=="script"&&fn(l,"data:")===0&&tt[e])){if(!(Xe&&!N($t,le(l,Be,"")))){if(l)return!1}}}}}}return!0},pt=function(e){return e!=="annotation-xml"&&xt(e,Ht)},ut=function(e){K(P.beforeSanitizeAttributes,e,null);const{attributes:i}=e;if(!i||Me(e))return;const l={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:_,forceKeepAttr:void 0};let b=i.length;for(;b--;){const S=i[b],{name:T,namespaceURI:O,value:W}=S,ae=w(T),Ue=W;let R=T==="value"?Ue:hn(Ue);if(l.attrName=ae,l.attrValue=R,l.keepAttr=!0,l.forceKeepAttr=void 0,K(P.uponSanitizeAttribute,e,l),R=l.attrValue,Je&&(ae==="id"||ae==="name")&&(ee(T,e),R=Kt+R),pe&&N(/((--!?|])>)|<\/(style|title)/i,R)){ee(T,e);continue}if(l.forceKeepAttr)continue;if(!l.keepAttr){ee(T,e);continue}if(!Ze&&N(/\/>/i,R)){ee(T,e);continue}V&&ve([we,_e,ke],ht=>{R=le(R,ht," ")});const ft=w(e.nodeName);if(!dt(ft,ae,R)){ee(T,e);continue}if(L&&typeof Y=="object"&&typeof Y.getAttributeType=="function"&&!O)switch(Y.getAttributeType(ft,ae)){case"TrustedHTML":{R=L.createHTML(R);break}case"TrustedScriptURL":{R=L.createScriptURL(R);break}}if(R!==Ue)try{O?e.setAttributeNS(O,T,R):e.setAttribute(T,R),Me(e)?F(e):yt(r.removed)}catch{ee(T,e)}}K(P.afterSanitizeAttributes,e,null)},jt=function m(e){let i=null;const l=lt(e);for(K(P.beforeSanitizeShadowDOM,e,null);i=l.nextNode();)K(P.uponSanitizeShadowNode,i,null),mt(i),ut(i),i.content instanceof s&&m(i.content);K(P.afterSanitizeShadowDOM,e,null)};return r.sanitize=function(m){let e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},i=null,l=null,b=null,S=null;if(Ce=!m,Ce&&(m="<!-->"),typeof m!="string"&&!ct(m))if(typeof m.toString=="function"){if(m=m.toString(),typeof m!="string")throw ce("dirty is not a string, aborting")}else throw ce("toString is not a function");if(!r.isSupported)return m;if(Le||Oe(e),r.removed=[],typeof m=="string"&&(re=!1),re){if(m.nodeName){const W=w(m.nodeName);if(!A[W]||oe[W])throw ce("root node is forbidden and cannot be sanitized in-place")}}else if(m instanceof h)i=st("<!---->"),l=i.ownerDocument.importNode(m,!0),l.nodeType===de.element&&l.nodeName==="BODY"||l.nodeName==="HTML"?i=l:i.appendChild(l);else{if(!j&&!V&&!q&&m.indexOf("<")===-1)return L&&fe?L.createHTML(m):m;if(i=st(m),!i)return j?null:fe?ne:""}i&&Pe&&F(i.firstChild);const T=lt(re?m:i);for(;b=T.nextNode();)mt(b),ut(b),b.content instanceof s&&jt(b.content);if(re)return m;if(j){if(ue)for(S=Ot.call(i.ownerDocument);i.firstChild;)S.appendChild(i.firstChild);else S=i;return(_.shadowroot||_.shadowrootmode)&&(S=Ut.call(n,S,!0)),S}let O=q?i.outerHTML:i.innerHTML;return q&&A["!doctype"]&&i.ownerDocument&&i.ownerDocument.doctype&&i.ownerDocument.doctype.name&&N(It,i.ownerDocument.doctype.name)&&(O="<!DOCTYPE "+i.ownerDocument.doctype.name+`>
904
- `+O),V&&ve([we,_e,ke],W=>{O=le(O,W," ")}),L&&fe?L.createHTML(O):O},r.setConfig=function(){let m=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};Oe(m),Le=!0},r.clearConfig=function(){J=null,Le=!1},r.isValidAttribute=function(m,e,i){J||Oe({});const l=w(m),b=w(e);return dt(l,b,i)},r.addHook=function(m,e){typeof e=="function"&&se(P[m],e)},r.removeHook=function(m,e){if(e!==void 0){const i=pn(P[m],e);return i===-1?void 0:un(P[m],i,1)[0]}return yt(P[m])},r.removeHooks=function(m){P[m]=[]},r.removeAllHooks=function(){P=_t()},r}var Pn=Ct();class Nn extends HTMLElement{constructor(){super();f(this,"rendered",!1);f(this,"nostrService",Qt.getInstance());f(this,"shadow");f(this,"theme","light");f(this,"isLoading",!0);f(this,"isError",!1);f(this,"errorMessage","");f(this,"comments",[]);f(this,"baseUrl","");f(this,"userPublicKey",null);f(this,"userPrivateKey",null);f(this,"currentUserProfile",null);f(this,"isSubmitting",!1);f(this,"replyingToComment",null);f(this,"commentAs","user");f(this,"hasNip07",!1);f(this,"anonPrivateKeyHex",null);f(this,"eventListeners",[]);f(this,"nip07MonitoringInterval",null);f(this,"loadVersion",0);f(this,"getRelays",()=>{const t=this.getAttribute("relays");return t?t.split(",").map(n=>n.trim()):Jt});f(this,"getTheme",()=>{this.theme="light";const t=this.getAttribute("theme");t&&(["light","dark"].includes(t)?this.theme=t:console.warn(`Invalid theme '${t}'. Accepted values are 'light', 'dark'`))});f(this,"getBaseUrl",()=>{const t=this.getAttribute("url");return t?gt(t):gt(window.location.href)});f(this,"detectNip07Extension",()=>{const t=window.nostr;return t?typeof t.getPublicKey=="function"&&typeof t.signEvent=="function"?!0:(console.warn("NIP-07 extension detected but missing required methods"),!1):!1});f(this,"handleNip07StateChange",async()=>{const t=this.hasNip07,n=this.detectNip07Extension();if(t!==n&&(console.log("NIP-07 extension state changed:",n),this.hasNip07=n,n&&this.commentAs==="user"))try{await this.initializeUser(),this.render()}catch(a){console.warn("Failed to reconnect to NIP-07 extension:",a)}});f(this,"setupNip07StateMonitoring",()=>{const t=setInterval(async()=>{document.contains(this)&&await this.handleNip07StateChange()},2e3);this.nip07MonitoringInterval=t});f(this,"loadComments",async()=>{this.loadVersion++;const t=this.loadVersion;try{this.isLoading=!0,this.isError=!1,this.render();const n=this.getRelays();await this.nostrService.connectToNostr(n);const a={kinds:[1111],"#I":[this.baseUrl],limit:200},s=await this.nostrService.getNDK().fetchEvents(a),c=Array.from(s),h=new Map;c.forEach(p=>h.set(p.id,{content:p.content,id:p.id,tags:p.tags}));const g=[],y=new Set;for(const p of c){let x;const k=(p.tags||[]).filter(U=>U[0]==="e");for(let U=k.length-1;U>=0;U--){const $=k[U];if($[3]==="reply"){x=$[1];break}}if(!x&&k.length>0){const U=k.filter($=>$[3]!=="root");U.length>0?x=U[U.length-1][1]:x=k[k.length-1][1]}const te={id:p.id,pubkey:p.pubkey,content:p.content,created_at:p.created_at,replies:[],replyTo:x,depth:0};y.add(p.pubkey),g.push(te)}const d=Array.from(y).map(async p=>{try{console.log("Fetching profile for pubkey:",p);const x=await this.nostrService.getProfile({pubkey:p});return console.log("Profile fetched for",p,":",x),{pubkey:p,profile:x}}catch(x){return console.warn("Failed to fetch profile for:",p,x),{pubkey:p,profile:null}}}),E=await Promise.allSettled(d),D=new Map;if(E.forEach(p=>{if(p.status==="fulfilled"){const{pubkey:x,profile:k}=p.value;D.set(x,k)}}),g.forEach(p=>{p.userProfile=D.get(p.pubkey)||void 0,console.log("Attached profile to comment:",p.pubkey,"Profile:",p.userProfile)}),t!==this.loadVersion){console.log("Load operation superseded by newer request, aborting");return}this.comments=this.buildCommentTree(g);const Y=new Map;this.comments.forEach(p=>{const x=[p];for(;x.length;){const k=x.pop();Y.set(k.id,k),k.replies.forEach(te=>x.push(te))}}),g.forEach(p=>{const x=p.replyTo?Y.get(p.replyTo):void 0,k=x?x.content:"(no parent)";console.log(`[nostr-comment] recv: "${p.content}" -> parent: ${k}`)})}catch(n){if(t!==this.loadVersion){console.log("Load operation superseded by newer request, aborting error handling");return}this.isError=!0,this.errorMessage=n instanceof Error?n.message:"Failed to load comments",console.error("Error loading comments:",n)}finally{if(t!==this.loadVersion){console.log("Load operation superseded by newer request, aborting final state update");return}this.isLoading=!1,this.render()}});f(this,"buildCommentTree",t=>{const n=new Map,a=[];t.forEach(c=>{n.set(c.id,c)}),t.forEach(c=>{if(c.replyTo&&n.has(c.replyTo)){const h=n.get(c.replyTo);h.replies.push(c),h.replies.sort((g,y)=>g.created_at-y.created_at)}else a.push(c)});const s=(c,h)=>{for(const g of c)g.depth=h,g.replies&&g.replies.length&&s(g.replies,h+1)};return s(a,0),a.sort((c,h)=>h.created_at-c.created_at)});f(this,"initializeUser",async()=>{if(this.hasNip07=this.detectNip07Extension(),console.log("NIP-07 extension detected:",this.hasNip07),this.hasNip07&&this.commentAs==="user")try{this.userPublicKey=await window.nostr.getPublicKey(),console.log("Successfully connected to NIP-07 extension, public key:",this.userPublicKey),this.userPrivateKey=null,this.anonPrivateKeyHex=null}catch(t){console.warn("NIP-07 extension available but failed to get public key:",t),this.commentAs="anon",this.userPublicKey=null,this.userPrivateKey=null}if(!this.userPublicKey){const t=await this.ensureAnonKey();this.anonPrivateKeyHex=t,this.userPrivateKey=t;const{getPublicKey:n}=await xe(async()=>{const{getPublicKey:a}=await import("../assets/pure-DPo-pzxM.js");return{getPublicKey:a}},__vite__mapDeps([0,1]));this.userPublicKey=n(new Uint8Array(t.match(/.{1,2}/g).map(a=>parseInt(a,16)))),console.log("Using anonymous key for user:",this.userPublicKey)}if(this.commentAs==="anon"&&!this.anonPrivateKeyHex){const t=await this.ensureAnonKey();this.anonPrivateKeyHex=t,console.log("Ensured anonymous key is available")}if(this.userPublicKey){try{console.log("Fetching profile for user:",this.userPublicKey);const t=await this.nostrService.getProfile({pubkey:this.userPublicKey});console.log("Profile fetched for current user:",t),t?(this.currentUserProfile=t,console.log("Set currentUserProfile to:",this.currentUserProfile)):(this.currentUserProfile={name:this.commentAs==="anon"?"Anonymous":`User ${this.userPublicKey.slice(0,8)}`,displayName:this.commentAs==="anon"?"Anonymous":`User ${this.userPublicKey.slice(0,8)}`,image:"../../assets/default_dp.png"},console.log("Set fallback currentUserProfile to:",this.currentUserProfile))}catch(t){console.error("Error fetching current user profile:",t),this.currentUserProfile={name:this.commentAs==="anon"?"Anonymous":`User ${this.userPublicKey.slice(0,8)}`,displayName:this.commentAs==="anon"?"Anonymous":`User ${this.userPublicKey.slice(0,8)}`,image:"../../assets/default_dp.png"},console.log("Set error fallback currentUserProfile to:",this.currentUserProfile)}this.render()}});f(this,"submitComment",async t=>{if(t.trim()){this.userPublicKey||await this.initializeUser(),this.isSubmitting=!0,this.render();try{const n=[];if(n.push(["I",this.baseUrl]),this.replyingToComment){const{rootId:d}=this.findRootAndParent(this.replyingToComment);n.push(["e",d||this.replyingToComment,"","root"]),n.push(["e",this.replyingToComment,"","reply"]),n.push(["k","1111"])}const a={kind:1111,pubkey:this.userPublicKey,content:t.trim(),created_at:Math.floor(Date.now()/1e3),tags:n};let s;if(console.log(`[nostr-comment] Signing attempt - commentAs: ${this.commentAs}, hasNip07: ${!!window.nostr}, anonKey: ${!!this.anonPrivateKeyHex}, userKey: ${!!this.userPrivateKey}`),this.commentAs==="user"&&this.hasNip07&&window.nostr){console.log("[nostr-comment] Using NIP-07 extension to sign");try{s=await window.nostr.signEvent(a),console.log("[nostr-comment] Successfully signed with NIP-07 extension")}catch(d){throw console.error("[nostr-comment] Failed to sign with NIP-07 extension:",d),new Error("Failed to sign with NIP-07 extension. Please check if your extension is unlocked.")}}else if(this.commentAs==="anon"&&this.anonPrivateKeyHex){console.log("[nostr-comment] Using anonymous private key to sign");const{finalizeEvent:d}=await xe(async()=>{const{finalizeEvent:D}=await import("../assets/pure-DPo-pzxM.js");return{finalizeEvent:D}},__vite__mapDeps([0,1])),E=new Uint8Array(this.anonPrivateKeyHex.match(/.{1,2}/g).map(D=>parseInt(D,16)));s=d(a,E)}else if(this.userPrivateKey){console.log("[nostr-comment] Using local private key to sign (fallback)");const{finalizeEvent:d}=await xe(async()=>{const{finalizeEvent:D}=await import("../assets/pure-DPo-pzxM.js");return{finalizeEvent:D}},__vite__mapDeps([0,1])),E=new Uint8Array(this.userPrivateKey.match(/.{1,2}/g).map(D=>parseInt(D,16)));s=d(a,E)}else throw console.error("[nostr-comment] No signing method available - commentAs:",this.commentAs,"hasNip07:",this.hasNip07,"anonKey:",!!this.anonPrivateKeyHex,"userKey:",!!this.userPrivateKey),new Error("No signing method available. Please check your NIP-07 extension or switch to anonymous mode.");await new en(this.nostrService.getNDK(),s).publish();const h={id:s.id,pubkey:s.pubkey,content:s.content,created_at:s.created_at,replies:[],replyTo:this.replyingToComment||void 0,depth:0};if(this.currentUserProfile)h.userProfile=this.currentUserProfile;else{try{const d=await this.nostrService.getProfile({pubkey:s.pubkey});d&&(h.userProfile=d,this.currentUserProfile=d)}catch{console.warn("Could not fetch profile for new comment")}h.userProfile||(h.userProfile={name:this.commentAs==="anon"?"Anonymous":`User ${s.pubkey.slice(0,8)}`,displayName:this.commentAs==="anon"?"Anonymous":`User ${s.pubkey.slice(0,8)}`,image:"../../assets/default_dp.png"})}this.replyingToComment?this.addReplyToComment(h,this.replyingToComment):this.comments.unshift(h);const g=n.find(d=>d[0]==="e"&&d[3]==="root"),y=n.find(d=>d[0]==="e"&&d[3]==="reply");if(console.log(`[nostr-comment] send: "${a.content}" root=${g?g[1]:"(none)"} parent=${y?y[1]:"(none)"} `),this.replyingToComment){const d=this.shadow.querySelector(".inline-reply-form"),E=d==null?void 0:d.querySelector('[data-role="comment-input"]');E&&(E.value="")}else{const d=this.shadow.querySelector(".modern-comment-form"),E=d==null?void 0:d.querySelector('[data-role="comment-input"]');E&&(E.value="")}this.replyingToComment=null}catch(n){console.error("Failed to submit comment:",n);let a="Failed to submit comment: "+(n instanceof Error?n.message:"Unknown error");n instanceof Error&&n.message.includes("NIP-07")&&(n.message.includes("extension is unlocked")?a="Please unlock your Nostr extension (nos2x/Alby) and try again.":n.message.includes("getPublicKey")?a="Please authorize this website in your Nostr extension.":a="Nostr extension error. Please check if your extension is working properly."),this.showError(a)}finally{this.isSubmitting=!1,this.render()}}});f(this,"addReplyToComment",(t,n)=>{const a=s=>{for(const c of s){if(c.id===n)return t.depth=(c.depth||0)+1,c.replies.push(t),c.replies.sort((h,g)=>h.created_at-g.created_at),!0;if(c.replies.length>0&&a(c.replies))return!0}return!1};a(this.comments)});f(this,"startReply",t=>{this.replyingToComment=null,this.render(),setTimeout(()=>{this.replyingToComment=t,this.render(),setTimeout(()=>{const n=this.shadow.querySelector(".inline-reply-form"),a=n==null?void 0:n.querySelector('[data-role="comment-input"]');a&&a.focus()},100)},10)});f(this,"cancelReply",()=>{this.replyingToComment=null,this.render()});this.shadow=this.attachShadow({mode:"open"})}findRootAndParent(t){let n,a;const s=(c,h,g)=>{var y;for(const d of c){const E=h??d.id;if(d.id===t)return n=E,a=g,!0;if((y=d.replies)!=null&&y.length&&s(d.replies,E,d.id))return!0}return!1};return s(this.comments),{rootId:n,parentId:a}}async connectedCallback(){if(!this.rendered)try{this.getTheme(),this.baseUrl=this.getBaseUrl(),await this.initializeUser(),await this.loadComments(),this.setupNip07StateMonitoring(),this.rendered=!0}catch(t){console.error("Error in connectedCallback:",t),this.isError=!0,this.errorMessage="Failed to initialize comment component",this.render()}}static get observedAttributes(){return["relays","theme","url","readonly","placeholder"]}async attributeChangedCallback(t,n,a){t==="relays"&&(this.nostrService.connectToNostr(this.getRelays()),await this.loadComments()),t==="theme"&&(this.getTheme(),this.render()),t==="url"&&(this.baseUrl=this.getBaseUrl(),await this.loadComments()),["readonly","placeholder"].includes(t)&&this.render()}disconnectedCallback(){this.removeEventListeners(),this.nip07MonitoringInterval&&(clearInterval(this.nip07MonitoringInterval),this.nip07MonitoringInterval=null)}attachEventListeners(){this.removeEventListeners(),this.shadow.querySelectorAll('[data-role="submit-comment"]').forEach(t=>{const n=a=>{a.preventDefault();const s=a.target.closest(".modern-comment-form, .inline-reply-form"),c=s==null?void 0:s.querySelector('[data-role="comment-input"]');c&&this.submitComment(c.value)};t.addEventListener("click",n),this.eventListeners.push({element:t,type:"click",handler:n})}),this.shadow.querySelectorAll('[data-role="comment-input"]').forEach(t=>{const n=a=>{const s=a;s.key==="Enter"&&(s.ctrlKey||s.metaKey)&&(s.preventDefault(),this.submitComment(t.value))};t.addEventListener("keydown",n),this.eventListeners.push({element:t,type:"keydown",handler:n})}),this.shadow.querySelectorAll('[data-role="cancel-reply"]').forEach(t=>{const n=a=>{a.preventDefault(),this.cancelReply()};t.addEventListener("click",n),this.eventListeners.push({element:t,type:"click",handler:n})}),this.shadow.querySelectorAll(".reply-btn").forEach(t=>{const n=a=>{a.preventDefault();const s=a.currentTarget.getAttribute("data-comment-id");s&&this.startReply(s)};t.addEventListener("click",n),this.eventListeners.push({element:t,type:"click",handler:n})}),this.shadow.querySelectorAll('[data-role="toggle-as-user"]').forEach(t=>{if(!this.hasNip07)t.disabled=!0,t.title="NIP-07 extension not detected";else{const n=async a=>{a.preventDefault(),this.commentAs!=="user"&&(this.commentAs="user",this.userPrivateKey=null,this.anonPrivateKeyHex=null,await this.initializeUser())};t.addEventListener("click",n),this.eventListeners.push({element:t,type:"click",handler:n})}}),this.shadow.querySelectorAll('[data-role="toggle-as-anon"]').forEach(t=>{t.disabled=!1;const n=async a=>{a.preventDefault(),this.commentAs!=="anon"&&(this.commentAs="anon",this.userPublicKey=null,this.userPrivateKey=null,await this.initializeUser())};t.addEventListener("click",n),this.eventListeners.push({element:t,type:"click",handler:n})})}attachAvatarErrorHandlers(){this.shadow.querySelectorAll("img[src]").forEach(t=>{const n=a=>{const s=a.target;if(s.src===this.getDefaultAvatarUrl()){console.warn("Avatar fallback also failed, preventing infinite loop");return}s.src=this.getDefaultAvatarUrl()};t.addEventListener("error",n),this.eventListeners.push({element:t,type:"error",handler:n})})}removeEventListeners(){this.eventListeners.forEach(({element:t,type:n,handler:a})=>{t.removeEventListener(n,a)}),this.eventListeners=[]}showError(t){const n=document.createElement("div");n.className="nostr-comment-error",n.style.cssText=`
903
+ `}/*! @license DOMPurify 3.3.1 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.3.1/LICENSE */const{entries:Nt,setPrototypeOf:vt,isFrozen:mn,getPrototypeOf:dn,getOwnPropertyDescriptor:pn}=Object;let{freeze:C,seal:M,create:Ye}=Object,{apply:qe,construct:Ve}=typeof Reflect<"u"&&Reflect;C||(C=function(r){return r});M||(M=function(r){return r});qe||(qe=function(r,t){for(var n=arguments.length,i=new Array(n>2?n-2:0),s=2;s<n;s++)i[s-2]=arguments[s];return r.apply(t,i)});Ve||(Ve=function(r){for(var t=arguments.length,n=new Array(t>1?t-1:0),i=1;i<t;i++)n[i-1]=arguments[i];return new r(...n)});const Te=I(Array.prototype.forEach),un=I(Array.prototype.lastIndexOf),Tt=I(Array.prototype.pop),le=I(Array.prototype.push),fn=I(Array.prototype.splice),Ae=I(String.prototype.toLowerCase),$e=I(String.prototype.toString),He=I(String.prototype.match),ce=I(String.prototype.replace),hn=I(String.prototype.indexOf),gn=I(String.prototype.trim),z=I(Object.prototype.hasOwnProperty),N=I(RegExp.prototype.test),me=bn(TypeError);function I(o){return function(r){r instanceof RegExp&&(r.lastIndex=0);for(var t=arguments.length,n=new Array(t>1?t-1:0),i=1;i<t;i++)n[i-1]=arguments[i];return qe(o,r,n)}}function bn(o){return function(){for(var r=arguments.length,t=new Array(r),n=0;n<r;n++)t[n]=arguments[n];return Ve(o,t)}}function u(o,r){let t=arguments.length>2&&arguments[2]!==void 0?arguments[2]:Ae;vt&&vt(o,null);let n=r.length;for(;n--;){let i=r[n];if(typeof i=="string"){const s=t(i);s!==i&&(mn(r)||(r[n]=s),i=s)}o[i]=!0}return o}function yn(o){for(let r=0;r<o.length;r++)z(o,r)||(o[r]=null);return o}function H(o){const r=Ye(null);for(const[t,n]of Nt(o))z(o,t)&&(Array.isArray(n)?r[t]=yn(n):n&&typeof n=="object"&&n.constructor===Object?r[t]=H(n):r[t]=n);return r}function de(o,r){for(;o!==null;){const n=pn(o,r);if(n){if(n.get)return I(n.get);if(typeof n.value=="function")return I(n.value)}o=dn(o)}function t(){return null}return t}const Et=C(["a","abbr","acronym","address","area","article","aside","audio","b","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dialog","dir","div","dl","dt","element","em","fieldset","figcaption","figure","font","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","img","input","ins","kbd","label","legend","li","main","map","mark","marquee","menu","menuitem","meter","nav","nobr","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","search","section","select","shadow","slot","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","tr","track","tt","u","ul","var","video","wbr"]),Ke=C(["svg","a","altglyph","altglyphdef","altglyphitem","animatecolor","animatemotion","animatetransform","circle","clippath","defs","desc","ellipse","enterkeyhint","exportparts","filter","font","g","glyph","glyphref","hkern","image","inputmode","line","lineargradient","marker","mask","metadata","mpath","part","path","pattern","polygon","polyline","radialgradient","rect","stop","style","switch","symbol","text","textpath","title","tref","tspan","view","vkern"]),We=C(["feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence"]),xn=C(["animate","color-profile","cursor","discard","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","foreignobject","hatch","hatchpath","mesh","meshgradient","meshpatch","meshrow","missing-glyph","script","set","solidcolor","unknown","use"]),Ge=C(["math","menclose","merror","mfenced","mfrac","mglyph","mi","mlabeledtr","mmultiscripts","mn","mo","mover","mpadded","mphantom","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msup","msubsup","mtable","mtd","mtext","mtr","munder","munderover","mprescripts"]),vn=C(["maction","maligngroup","malignmark","mlongdiv","mscarries","mscarry","msgroup","mstack","msline","msrow","semantics","annotation","annotation-xml","mprescripts","none"]),At=C(["#text"]),wt=C(["accept","action","align","alt","autocapitalize","autocomplete","autopictureinpicture","autoplay","background","bgcolor","border","capture","cellpadding","cellspacing","checked","cite","class","clear","color","cols","colspan","controls","controlslist","coords","crossorigin","datetime","decoding","default","dir","disabled","disablepictureinpicture","disableremoteplayback","download","draggable","enctype","enterkeyhint","exportparts","face","for","headers","height","hidden","high","href","hreflang","id","inert","inputmode","integrity","ismap","kind","label","lang","list","loading","loop","low","max","maxlength","media","method","min","minlength","multiple","muted","name","nonce","noshade","novalidate","nowrap","open","optimum","part","pattern","placeholder","playsinline","popover","popovertarget","popovertargetaction","poster","preload","pubdate","radiogroup","readonly","rel","required","rev","reversed","role","rows","rowspan","spellcheck","scope","selected","shape","size","sizes","slot","span","srclang","start","src","srcset","step","style","summary","tabindex","title","translate","type","usemap","valign","value","width","wrap","xmlns","slot"]),Be=C(["accent-height","accumulate","additive","alignment-baseline","amplitude","ascent","attributename","attributetype","azimuth","basefrequency","baseline-shift","begin","bias","by","class","clip","clippathunits","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cx","cy","d","dx","dy","diffuseconstant","direction","display","divisor","dur","edgemode","elevation","end","exponent","fill","fill-opacity","fill-rule","filter","filterunits","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","fx","fy","g1","g2","glyph-name","glyphref","gradientunits","gradienttransform","height","href","id","image-rendering","in","in2","intercept","k","k1","k2","k3","k4","kerning","keypoints","keysplines","keytimes","lang","lengthadjust","letter-spacing","kernelmatrix","kernelunitlength","lighting-color","local","marker-end","marker-mid","marker-start","markerheight","markerunits","markerwidth","maskcontentunits","maskunits","max","mask","mask-type","media","method","mode","min","name","numoctaves","offset","operator","opacity","order","orient","orientation","origin","overflow","paint-order","path","pathlength","patterncontentunits","patterntransform","patternunits","points","preservealpha","preserveaspectratio","primitiveunits","r","rx","ry","radius","refx","refy","repeatcount","repeatdur","restart","result","rotate","scale","seed","shape-rendering","slope","specularconstant","specularexponent","spreadmethod","startoffset","stddeviation","stitchtiles","stop-color","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke","stroke-width","style","surfacescale","systemlanguage","tabindex","tablevalues","targetx","targety","transform","transform-origin","text-anchor","text-decoration","text-rendering","textlength","type","u1","u2","unicode","values","viewbox","visibility","version","vert-adv-y","vert-origin-x","vert-origin-y","width","word-spacing","wrap","writing-mode","xchannelselector","ychannelselector","x","x1","x2","xmlns","y","y1","y2","z","zoomandpan"]),_t=C(["accent","accentunder","align","bevelled","close","columnsalign","columnlines","columnspan","denomalign","depth","dir","display","displaystyle","encoding","fence","frame","height","href","id","largeop","length","linethickness","lspace","lquote","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","rquote","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","voffset","width","xmlns"]),Ee=C(["xlink:href","xml:id","xlink:title","xml:space","xmlns:xlink"]),Tn=M(/\{\{[\w\W]*|[\w\W]*\}\}/gm),En=M(/<%[\w\W]*|[\w\W]*%>/gm),An=M(/\$\{[\w\W]*/gm),wn=M(/^data-[\-\w.\u00B7-\uFFFF]+$/),_n=M(/^aria-[\-\w]+$/),Ct=M(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),kn=M(/^(?:\w+script|data):/i),Sn=M(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),It=M(/^html$/i),Rn=M(/^[a-z][.\w]*(-[.\w]+)+$/i);var kt=Object.freeze({__proto__:null,ARIA_ATTR:_n,ATTR_WHITESPACE:Sn,CUSTOM_ELEMENT:Rn,DATA_ATTR:wn,DOCTYPE_NAME:It,ERB_EXPR:En,IS_ALLOWED_URI:Ct,IS_SCRIPT_OR_DATA:kn,MUSTACHE_EXPR:Tn,TMPLIT_EXPR:An});const pe={element:1,text:3,progressingInstruction:7,comment:8,document:9},Ln=function(){return typeof window>"u"?null:window},Pn=function(r,t){if(typeof r!="object"||typeof r.createPolicy!="function")return null;let n=null;const i="data-tt-policy-suffix";t&&t.hasAttribute(i)&&(n=t.getAttribute(i));const s="dompurify"+(n?"#"+n:"");try{return r.createPolicy(s,{createHTML(c){return c},createScriptURL(c){return c}})}catch{return console.warn("TrustedTypes policy "+s+" could not be created."),null}},St=function(){return{afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]}};function Dt(){let o=arguments.length>0&&arguments[0]!==void 0?arguments[0]:Ln();const r=m=>Dt(m);if(r.version="3.3.1",r.removed=[],!o||!o.document||o.document.nodeType!==pe.document||!o.Element)return r.isSupported=!1,r;let{document:t}=o;const n=t,i=n.currentScript,{DocumentFragment:s,HTMLTemplateElement:c,Node:h,Element:g,NodeFilter:y,NamedNodeMap:d=o.NamedNodeMap||o.MozNamedAttrMap,HTMLFormElement:A,DOMParser:D,trustedTypes:q}=o,p=g.prototype,x=de(p,"cloneNode"),S=de(p,"remove"),oe=de(p,"nextSibling"),U=de(p,"childNodes"),K=de(p,"parentNode");if(typeof c=="function"){const m=t.createElement("template");m.content&&m.content.ownerDocument&&(t=m.content.ownerDocument)}let L,re="";const{implementation:we,createNodeIterator:Ot,createDocumentFragment:Mt,getElementsByTagName:Ut}=t,{importNode:zt}=n;let P=St();r.isSupported=typeof Nt=="function"&&typeof K=="function"&&we&&we.createHTMLDocument!==void 0;const{MUSTACHE_EXPR:_e,ERB_EXPR:ke,TMPLIT_EXPR:Se,DATA_ATTR:Ft,ARIA_ATTR:$t,IS_SCRIPT_OR_DATA:Ht,ATTR_WHITESPACE:je,CUSTOM_ELEMENT:Kt}=kt;let{IS_ALLOWED_URI:Xe}=kt,w=null;const Ze=u({},[...Et,...Ke,...We,...Ge,...At]);let _=null;const Qe=u({},[...wt,...Be,..._t,...Ee]);let v=Object.seal(Ye(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),ie=null,Re=null;const X=Object.seal(Ye(null,{tagCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeCheck:{writable:!0,configurable:!1,enumerable:!0,value:null}}));let Je=!0,Le=!0,et=!1,tt=!0,Z=!1,ue=!0,V=!1,Pe=!1,Ne=!1,Q=!1,fe=!1,he=!1,nt=!0,ot=!1;const Wt="user-content-";let Ce=!0,ae=!1,J={},F=null;const Ie=u({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]);let rt=null;const it=u({},["audio","video","img","source","image","track"]);let De=null;const at=u({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),ge="http://www.w3.org/1998/Math/MathML",be="http://www.w3.org/2000/svg",W="http://www.w3.org/1999/xhtml";let ee=W,Oe=!1,Me=null;const Gt=u({},[ge,be,W],$e);let ye=u({},["mi","mo","mn","ms","mtext"]),xe=u({},["annotation-xml"]);const Bt=u({},["title","style","font","a","script"]);let se=null;const Yt=["application/xhtml+xml","text/html"],qt="text/html";let E=null,te=null;const Vt=t.createElement("form"),st=function(e){return e instanceof RegExp||e instanceof Function},Ue=function(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};if(!(te&&te===e)){if((!e||typeof e!="object")&&(e={}),e=H(e),se=Yt.indexOf(e.PARSER_MEDIA_TYPE)===-1?qt:e.PARSER_MEDIA_TYPE,E=se==="application/xhtml+xml"?$e:Ae,w=z(e,"ALLOWED_TAGS")?u({},e.ALLOWED_TAGS,E):Ze,_=z(e,"ALLOWED_ATTR")?u({},e.ALLOWED_ATTR,E):Qe,Me=z(e,"ALLOWED_NAMESPACES")?u({},e.ALLOWED_NAMESPACES,$e):Gt,De=z(e,"ADD_URI_SAFE_ATTR")?u(H(at),e.ADD_URI_SAFE_ATTR,E):at,rt=z(e,"ADD_DATA_URI_TAGS")?u(H(it),e.ADD_DATA_URI_TAGS,E):it,F=z(e,"FORBID_CONTENTS")?u({},e.FORBID_CONTENTS,E):Ie,ie=z(e,"FORBID_TAGS")?u({},e.FORBID_TAGS,E):H({}),Re=z(e,"FORBID_ATTR")?u({},e.FORBID_ATTR,E):H({}),J=z(e,"USE_PROFILES")?e.USE_PROFILES:!1,Je=e.ALLOW_ARIA_ATTR!==!1,Le=e.ALLOW_DATA_ATTR!==!1,et=e.ALLOW_UNKNOWN_PROTOCOLS||!1,tt=e.ALLOW_SELF_CLOSE_IN_ATTR!==!1,Z=e.SAFE_FOR_TEMPLATES||!1,ue=e.SAFE_FOR_XML!==!1,V=e.WHOLE_DOCUMENT||!1,Q=e.RETURN_DOM||!1,fe=e.RETURN_DOM_FRAGMENT||!1,he=e.RETURN_TRUSTED_TYPE||!1,Ne=e.FORCE_BODY||!1,nt=e.SANITIZE_DOM!==!1,ot=e.SANITIZE_NAMED_PROPS||!1,Ce=e.KEEP_CONTENT!==!1,ae=e.IN_PLACE||!1,Xe=e.ALLOWED_URI_REGEXP||Ct,ee=e.NAMESPACE||W,ye=e.MATHML_TEXT_INTEGRATION_POINTS||ye,xe=e.HTML_INTEGRATION_POINTS||xe,v=e.CUSTOM_ELEMENT_HANDLING||{},e.CUSTOM_ELEMENT_HANDLING&&st(e.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(v.tagNameCheck=e.CUSTOM_ELEMENT_HANDLING.tagNameCheck),e.CUSTOM_ELEMENT_HANDLING&&st(e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(v.attributeNameCheck=e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),e.CUSTOM_ELEMENT_HANDLING&&typeof e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements=="boolean"&&(v.allowCustomizedBuiltInElements=e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),Z&&(Le=!1),fe&&(Q=!0),J&&(w=u({},At),_=[],J.html===!0&&(u(w,Et),u(_,wt)),J.svg===!0&&(u(w,Ke),u(_,Be),u(_,Ee)),J.svgFilters===!0&&(u(w,We),u(_,Be),u(_,Ee)),J.mathMl===!0&&(u(w,Ge),u(_,_t),u(_,Ee))),e.ADD_TAGS&&(typeof e.ADD_TAGS=="function"?X.tagCheck=e.ADD_TAGS:(w===Ze&&(w=H(w)),u(w,e.ADD_TAGS,E))),e.ADD_ATTR&&(typeof e.ADD_ATTR=="function"?X.attributeCheck=e.ADD_ATTR:(_===Qe&&(_=H(_)),u(_,e.ADD_ATTR,E))),e.ADD_URI_SAFE_ATTR&&u(De,e.ADD_URI_SAFE_ATTR,E),e.FORBID_CONTENTS&&(F===Ie&&(F=H(F)),u(F,e.FORBID_CONTENTS,E)),e.ADD_FORBID_CONTENTS&&(F===Ie&&(F=H(F)),u(F,e.ADD_FORBID_CONTENTS,E)),Ce&&(w["#text"]=!0),V&&u(w,["html","head","body"]),w.table&&(u(w,["tbody"]),delete ie.tbody),e.TRUSTED_TYPES_POLICY){if(typeof e.TRUSTED_TYPES_POLICY.createHTML!="function")throw me('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if(typeof e.TRUSTED_TYPES_POLICY.createScriptURL!="function")throw me('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');L=e.TRUSTED_TYPES_POLICY,re=L.createHTML("")}else L===void 0&&(L=Pn(q,i)),L!==null&&typeof re=="string"&&(re=L.createHTML(""));C&&C(e),te=e}},lt=u({},[...Ke,...We,...xn]),ct=u({},[...Ge,...vn]),jt=function(e){let a=K(e);(!a||!a.tagName)&&(a={namespaceURI:ee,tagName:"template"});const l=Ae(e.tagName),b=Ae(a.tagName);return Me[e.namespaceURI]?e.namespaceURI===be?a.namespaceURI===W?l==="svg":a.namespaceURI===ge?l==="svg"&&(b==="annotation-xml"||ye[b]):!!lt[l]:e.namespaceURI===ge?a.namespaceURI===W?l==="math":a.namespaceURI===be?l==="math"&&xe[b]:!!ct[l]:e.namespaceURI===W?a.namespaceURI===be&&!xe[b]||a.namespaceURI===ge&&!ye[b]?!1:!ct[l]&&(Bt[l]||!lt[l]):!!(se==="application/xhtml+xml"&&Me[e.namespaceURI]):!1},$=function(e){le(r.removed,{element:e});try{K(e).removeChild(e)}catch{S(e)}},j=function(e,a){try{le(r.removed,{attribute:a.getAttributeNode(e),from:a})}catch{le(r.removed,{attribute:null,from:a})}if(a.removeAttribute(e),e==="is")if(Q||fe)try{$(a)}catch{}else try{a.setAttribute(e,"")}catch{}},mt=function(e){let a=null,l=null;if(Ne)e="<remove></remove>"+e;else{const T=He(e,/^[\r\n\t ]+/);l=T&&T[0]}se==="application/xhtml+xml"&&ee===W&&(e='<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>'+e+"</body></html>");const b=L?L.createHTML(e):e;if(ee===W)try{a=new D().parseFromString(b,se)}catch{}if(!a||!a.documentElement){a=we.createDocument(ee,"template",null);try{a.documentElement.innerHTML=Oe?re:b}catch{}}const R=a.body||a.documentElement;return e&&l&&R.insertBefore(t.createTextNode(l),R.childNodes[0]||null),ee===W?Ut.call(a,V?"html":"body")[0]:V?a.documentElement:R},dt=function(e){return Ot.call(e.ownerDocument||e,e,y.SHOW_ELEMENT|y.SHOW_COMMENT|y.SHOW_TEXT|y.SHOW_PROCESSING_INSTRUCTION|y.SHOW_CDATA_SECTION,null)},ze=function(e){return e instanceof A&&(typeof e.nodeName!="string"||typeof e.textContent!="string"||typeof e.removeChild!="function"||!(e.attributes instanceof d)||typeof e.removeAttribute!="function"||typeof e.setAttribute!="function"||typeof e.namespaceURI!="string"||typeof e.insertBefore!="function"||typeof e.hasChildNodes!="function")},pt=function(e){return typeof h=="function"&&e instanceof h};function G(m,e,a){Te(m,l=>{l.call(r,e,a,te)})}const ut=function(e){let a=null;if(G(P.beforeSanitizeElements,e,null),ze(e))return $(e),!0;const l=E(e.nodeName);if(G(P.uponSanitizeElement,e,{tagName:l,allowedTags:w}),ue&&e.hasChildNodes()&&!pt(e.firstElementChild)&&N(/<[/\w!]/g,e.innerHTML)&&N(/<[/\w!]/g,e.textContent)||e.nodeType===pe.progressingInstruction||ue&&e.nodeType===pe.comment&&N(/<[/\w]/g,e.data))return $(e),!0;if(!(X.tagCheck instanceof Function&&X.tagCheck(l))&&(!w[l]||ie[l])){if(!ie[l]&&ht(l)&&(v.tagNameCheck instanceof RegExp&&N(v.tagNameCheck,l)||v.tagNameCheck instanceof Function&&v.tagNameCheck(l)))return!1;if(Ce&&!F[l]){const b=K(e)||e.parentNode,R=U(e)||e.childNodes;if(R&&b){const T=R.length;for(let O=T-1;O>=0;--O){const B=x(R[O],!0);B.__removalCount=(e.__removalCount||0)+1,b.insertBefore(B,oe(e))}}}return $(e),!0}return e instanceof g&&!jt(e)||(l==="noscript"||l==="noembed"||l==="noframes")&&N(/<\/no(script|embed|frames)/i,e.innerHTML)?($(e),!0):(Z&&e.nodeType===pe.text&&(a=e.textContent,Te([_e,ke,Se],b=>{a=ce(a,b," ")}),e.textContent!==a&&(le(r.removed,{element:e.cloneNode()}),e.textContent=a)),G(P.afterSanitizeElements,e,null),!1)},ft=function(e,a,l){if(nt&&(a==="id"||a==="name")&&(l in t||l in Vt))return!1;if(!(Le&&!Re[a]&&N(Ft,a))){if(!(Je&&N($t,a))){if(!(X.attributeCheck instanceof Function&&X.attributeCheck(a,e))){if(!_[a]||Re[a]){if(!(ht(e)&&(v.tagNameCheck instanceof RegExp&&N(v.tagNameCheck,e)||v.tagNameCheck instanceof Function&&v.tagNameCheck(e))&&(v.attributeNameCheck instanceof RegExp&&N(v.attributeNameCheck,a)||v.attributeNameCheck instanceof Function&&v.attributeNameCheck(a,e))||a==="is"&&v.allowCustomizedBuiltInElements&&(v.tagNameCheck instanceof RegExp&&N(v.tagNameCheck,l)||v.tagNameCheck instanceof Function&&v.tagNameCheck(l))))return!1}else if(!De[a]){if(!N(Xe,ce(l,je,""))){if(!((a==="src"||a==="xlink:href"||a==="href")&&e!=="script"&&hn(l,"data:")===0&&rt[e])){if(!(et&&!N(Ht,ce(l,je,"")))){if(l)return!1}}}}}}}return!0},ht=function(e){return e!=="annotation-xml"&&He(e,Kt)},gt=function(e){G(P.beforeSanitizeAttributes,e,null);const{attributes:a}=e;if(!a||ze(e))return;const l={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:_,forceKeepAttr:void 0};let b=a.length;for(;b--;){const R=a[b],{name:T,namespaceURI:O,value:B}=R,ne=E(T),Fe=B;let k=T==="value"?Fe:gn(Fe);if(l.attrName=ne,l.attrValue=k,l.keepAttr=!0,l.forceKeepAttr=void 0,G(P.uponSanitizeAttribute,e,l),k=l.attrValue,ot&&(ne==="id"||ne==="name")&&(j(T,e),k=Wt+k),ue&&N(/((--!?|])>)|<\/(style|title|textarea)/i,k)){j(T,e);continue}if(ne==="attributename"&&He(k,"href")){j(T,e);continue}if(l.forceKeepAttr)continue;if(!l.keepAttr){j(T,e);continue}if(!tt&&N(/\/>/i,k)){j(T,e);continue}Z&&Te([_e,ke,Se],yt=>{k=ce(k,yt," ")});const bt=E(e.nodeName);if(!ft(bt,ne,k)){j(T,e);continue}if(L&&typeof q=="object"&&typeof q.getAttributeType=="function"&&!O)switch(q.getAttributeType(bt,ne)){case"TrustedHTML":{k=L.createHTML(k);break}case"TrustedScriptURL":{k=L.createScriptURL(k);break}}if(k!==Fe)try{O?e.setAttributeNS(O,T,k):e.setAttribute(T,k),ze(e)?$(e):Tt(r.removed)}catch{j(T,e)}}G(P.afterSanitizeAttributes,e,null)},Xt=function m(e){let a=null;const l=dt(e);for(G(P.beforeSanitizeShadowDOM,e,null);a=l.nextNode();)G(P.uponSanitizeShadowNode,a,null),ut(a),gt(a),a.content instanceof s&&m(a.content);G(P.afterSanitizeShadowDOM,e,null)};return r.sanitize=function(m){let e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=null,l=null,b=null,R=null;if(Oe=!m,Oe&&(m="<!-->"),typeof m!="string"&&!pt(m))if(typeof m.toString=="function"){if(m=m.toString(),typeof m!="string")throw me("dirty is not a string, aborting")}else throw me("toString is not a function");if(!r.isSupported)return m;if(Pe||Ue(e),r.removed=[],typeof m=="string"&&(ae=!1),ae){if(m.nodeName){const B=E(m.nodeName);if(!w[B]||ie[B])throw me("root node is forbidden and cannot be sanitized in-place")}}else if(m instanceof h)a=mt("<!---->"),l=a.ownerDocument.importNode(m,!0),l.nodeType===pe.element&&l.nodeName==="BODY"||l.nodeName==="HTML"?a=l:a.appendChild(l);else{if(!Q&&!Z&&!V&&m.indexOf("<")===-1)return L&&he?L.createHTML(m):m;if(a=mt(m),!a)return Q?null:he?re:""}a&&Ne&&$(a.firstChild);const T=dt(ae?m:a);for(;b=T.nextNode();)ut(b),gt(b),b.content instanceof s&&Xt(b.content);if(ae)return m;if(Q){if(fe)for(R=Mt.call(a.ownerDocument);a.firstChild;)R.appendChild(a.firstChild);else R=a;return(_.shadowroot||_.shadowrootmode)&&(R=zt.call(n,R,!0)),R}let O=V?a.outerHTML:a.innerHTML;return V&&w["!doctype"]&&a.ownerDocument&&a.ownerDocument.doctype&&a.ownerDocument.doctype.name&&N(It,a.ownerDocument.doctype.name)&&(O="<!DOCTYPE "+a.ownerDocument.doctype.name+`>
904
+ `+O),Z&&Te([_e,ke,Se],B=>{O=ce(O,B," ")}),L&&he?L.createHTML(O):O},r.setConfig=function(){let m=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};Ue(m),Pe=!0},r.clearConfig=function(){te=null,Pe=!1},r.isValidAttribute=function(m,e,a){te||Ue({});const l=E(m),b=E(e);return ft(l,b,a)},r.addHook=function(m,e){typeof e=="function"&&le(P[m],e)},r.removeHook=function(m,e){if(e!==void 0){const a=un(P[m],e);return a===-1?void 0:fn(P[m],a,1)[0]}return Tt(P[m])},r.removeHooks=function(m){P[m]=[]},r.removeAllHooks=function(){P=St()},r}var Nn=Dt();class Cn extends HTMLElement{constructor(){super();f(this,"rendered",!1);f(this,"nostrService",Jt.getInstance());f(this,"shadow");f(this,"theme","light");f(this,"isLoading",!0);f(this,"isError",!1);f(this,"errorMessage","");f(this,"comments",[]);f(this,"baseUrl","");f(this,"userPublicKey",null);f(this,"userPrivateKey",null);f(this,"currentUserProfile",null);f(this,"isSubmitting",!1);f(this,"replyingToComment",null);f(this,"commentAs","user");f(this,"hasNip07",!1);f(this,"anonPrivateKeyHex",null);f(this,"eventListeners",[]);f(this,"nip07MonitoringInterval",null);f(this,"loadVersion",0);f(this,"getRelays",()=>{const t=this.getAttribute("relays");return t?t.split(",").map(n=>n.trim()):en});f(this,"getTheme",()=>{this.theme="light";const t=this.getAttribute("theme");t&&(["light","dark"].includes(t)?this.theme=t:console.warn(`Invalid theme '${t}'. Accepted values are 'light', 'dark'`))});f(this,"getBaseUrl",()=>{const t=this.getAttribute("url");return t?xt(t):xt(window.location.href)});f(this,"detectNip07Extension",()=>{const t=window.nostr;return t?typeof t.getPublicKey=="function"&&typeof t.signEvent=="function"?!0:(console.warn("NIP-07 extension detected but missing required methods"),!1):!1});f(this,"handleNip07StateChange",async()=>{const t=this.hasNip07,n=this.detectNip07Extension();if(t!==n&&(console.log("NIP-07 extension state changed:",n),this.hasNip07=n,n&&this.commentAs==="user"))try{await this.initializeUser(),this.render()}catch(i){console.warn("Failed to reconnect to NIP-07 extension:",i)}});f(this,"setupNip07StateMonitoring",()=>{const t=setInterval(async()=>{document.contains(this)&&await this.handleNip07StateChange()},2e3);this.nip07MonitoringInterval=t});f(this,"loadComments",async()=>{this.loadVersion++;const t=this.loadVersion;try{this.isLoading=!0,this.isError=!1,this.render();const n=this.getRelays();await this.nostrService.connectToNostr(n);const i={kinds:[1111],"#I":[this.baseUrl],limit:200},s=await this.nostrService.getNDK().fetchEvents(i),c=Array.from(s),h=new Map;c.forEach(p=>h.set(p.id,{content:p.content,id:p.id,tags:p.tags}));const g=[],y=new Set;for(const p of c){let x;const S=(p.tags||[]).filter(U=>U[0]==="e");for(let U=S.length-1;U>=0;U--){const K=S[U];if(K[3]==="reply"){x=K[1];break}}if(!x&&S.length>0){const U=S.filter(K=>K[3]!=="root");U.length>0?x=U[U.length-1][1]:x=S[S.length-1][1]}const oe={id:p.id,pubkey:p.pubkey,content:p.content,created_at:p.created_at,replies:[],replyTo:x,depth:0};y.add(p.pubkey),g.push(oe)}const d=Array.from(y).map(async p=>{try{console.log("Fetching profile for pubkey:",p);const x=await this.nostrService.getProfile({pubkey:p});return console.log("Profile fetched for",p,":",x),{pubkey:p,profile:x}}catch(x){return console.warn("Failed to fetch profile for:",p,x),{pubkey:p,profile:null}}}),A=await Promise.allSettled(d),D=new Map;if(A.forEach(p=>{if(p.status==="fulfilled"){const{pubkey:x,profile:S}=p.value;D.set(x,S)}}),g.forEach(p=>{p.userProfile=D.get(p.pubkey)||void 0,console.log("Attached profile to comment:",p.pubkey,"Profile:",p.userProfile)}),t!==this.loadVersion){console.log("Load operation superseded by newer request, aborting");return}this.comments=this.buildCommentTree(g);const q=new Map;this.comments.forEach(p=>{const x=[p];for(;x.length;){const S=x.pop();q.set(S.id,S),S.replies.forEach(oe=>x.push(oe))}}),g.forEach(p=>{const x=p.replyTo?q.get(p.replyTo):void 0,S=x?x.content:"(no parent)";console.log(`[nostr-comment] recv: "${p.content}" -> parent: ${S}`)})}catch(n){if(t!==this.loadVersion){console.log("Load operation superseded by newer request, aborting error handling");return}this.isError=!0,this.errorMessage=n instanceof Error?n.message:"Failed to load comments",console.error("Error loading comments:",n)}finally{if(t!==this.loadVersion){console.log("Load operation superseded by newer request, aborting final state update");return}this.isLoading=!1,this.render()}});f(this,"buildCommentTree",t=>{const n=new Map,i=[];t.forEach(c=>{n.set(c.id,c)}),t.forEach(c=>{if(c.replyTo&&n.has(c.replyTo)){const h=n.get(c.replyTo);h.replies.push(c),h.replies.sort((g,y)=>g.created_at-y.created_at)}else i.push(c)});const s=(c,h)=>{for(const g of c)g.depth=h,g.replies&&g.replies.length&&s(g.replies,h+1)};return s(i,0),i.sort((c,h)=>h.created_at-c.created_at)});f(this,"initializeUser",async()=>{if(this.hasNip07=this.detectNip07Extension(),console.log("NIP-07 extension detected:",this.hasNip07),this.hasNip07&&this.commentAs==="user")try{this.userPublicKey=await window.nostr.getPublicKey(),console.log("Successfully connected to NIP-07 extension, public key:",this.userPublicKey),this.userPrivateKey=null,this.anonPrivateKeyHex=null}catch(t){console.warn("NIP-07 extension available but failed to get public key:",t),this.commentAs="anon",this.userPublicKey=null,this.userPrivateKey=null}if(!this.userPublicKey){const t=await this.ensureAnonKey();this.anonPrivateKeyHex=t,this.userPrivateKey=t;const{getPublicKey:n}=await ve(async()=>{const{getPublicKey:i}=await import("../assets/pure-laCRX9eG.js");return{getPublicKey:i}},__vite__mapDeps([0,1]));this.userPublicKey=n(new Uint8Array(t.match(/.{1,2}/g).map(i=>parseInt(i,16)))),console.log("Using anonymous key for user:",this.userPublicKey)}if(this.commentAs==="anon"&&!this.anonPrivateKeyHex){const t=await this.ensureAnonKey();this.anonPrivateKeyHex=t,console.log("Ensured anonymous key is available")}if(this.userPublicKey){try{console.log("Fetching profile for user:",this.userPublicKey);const t=await this.nostrService.getProfile({pubkey:this.userPublicKey});console.log("Profile fetched for current user:",t),t?(this.currentUserProfile=t,console.log("Set currentUserProfile to:",this.currentUserProfile)):(this.currentUserProfile={name:this.commentAs==="anon"?"Anonymous":`User ${this.userPublicKey.slice(0,8)}`,displayName:this.commentAs==="anon"?"Anonymous":`User ${this.userPublicKey.slice(0,8)}`,image:"./assets/default_dp.png"},console.log("Set fallback currentUserProfile to:",this.currentUserProfile))}catch(t){console.error("Error fetching current user profile:",t),this.currentUserProfile={name:this.commentAs==="anon"?"Anonymous":`User ${this.userPublicKey.slice(0,8)}`,displayName:this.commentAs==="anon"?"Anonymous":`User ${this.userPublicKey.slice(0,8)}`,image:"./assets/default_dp.png"},console.log("Set error fallback currentUserProfile to:",this.currentUserProfile)}this.render()}});f(this,"submitComment",async t=>{if(t.trim()){this.userPublicKey||await this.initializeUser(),this.isSubmitting=!0,this.render();try{const n=[];if(n.push(["I",this.baseUrl]),this.replyingToComment){const{rootId:d}=this.findRootAndParent(this.replyingToComment);n.push(["e",d||this.replyingToComment,"","root"]),n.push(["e",this.replyingToComment,"","reply"]),n.push(["k","1111"])}const i={kind:1111,pubkey:this.userPublicKey,content:t.trim(),created_at:Math.floor(Date.now()/1e3),tags:n};let s;if(console.log(`[nostr-comment] Signing attempt - commentAs: ${this.commentAs}, hasNip07: ${!!window.nostr}, anonKey: ${!!this.anonPrivateKeyHex}, userKey: ${!!this.userPrivateKey}`),this.commentAs==="user"&&this.hasNip07&&window.nostr){console.log("[nostr-comment] Using NIP-07 extension to sign");try{s=await window.nostr.signEvent(i),console.log("[nostr-comment] Successfully signed with NIP-07 extension")}catch(d){throw console.error("[nostr-comment] Failed to sign with NIP-07 extension:",d),new Error("Failed to sign with NIP-07 extension. Please check if your extension is unlocked.")}}else if(this.commentAs==="anon"&&this.anonPrivateKeyHex){console.log("[nostr-comment] Using anonymous private key to sign");const{finalizeEvent:d}=await ve(async()=>{const{finalizeEvent:D}=await import("../assets/pure-laCRX9eG.js");return{finalizeEvent:D}},__vite__mapDeps([0,1])),A=new Uint8Array(this.anonPrivateKeyHex.match(/.{1,2}/g).map(D=>parseInt(D,16)));s=d(i,A)}else if(this.userPrivateKey){console.log("[nostr-comment] Using local private key to sign (fallback)");const{finalizeEvent:d}=await ve(async()=>{const{finalizeEvent:D}=await import("../assets/pure-laCRX9eG.js");return{finalizeEvent:D}},__vite__mapDeps([0,1])),A=new Uint8Array(this.userPrivateKey.match(/.{1,2}/g).map(D=>parseInt(D,16)));s=d(i,A)}else throw console.error("[nostr-comment] No signing method available - commentAs:",this.commentAs,"hasNip07:",this.hasNip07,"anonKey:",!!this.anonPrivateKeyHex,"userKey:",!!this.userPrivateKey),new Error("No signing method available. Please check your NIP-07 extension or switch to anonymous mode.");await new tn(this.nostrService.getNDK(),s).publish();const h={id:s.id,pubkey:s.pubkey,content:s.content,created_at:s.created_at,replies:[],replyTo:this.replyingToComment||void 0,depth:0};if(this.currentUserProfile)h.userProfile=this.currentUserProfile;else{try{const d=await this.nostrService.getProfile({pubkey:s.pubkey});d&&(h.userProfile=d,this.currentUserProfile=d)}catch{console.warn("Could not fetch profile for new comment")}h.userProfile||(h.userProfile={name:this.commentAs==="anon"?"Anonymous":`User ${s.pubkey.slice(0,8)}`,displayName:this.commentAs==="anon"?"Anonymous":`User ${s.pubkey.slice(0,8)}`,image:"./assets/default_dp.png"})}this.replyingToComment?this.addReplyToComment(h,this.replyingToComment):this.comments.unshift(h);const g=n.find(d=>d[0]==="e"&&d[3]==="root"),y=n.find(d=>d[0]==="e"&&d[3]==="reply");if(console.log(`[nostr-comment] send: "${i.content}" root=${g?g[1]:"(none)"} parent=${y?y[1]:"(none)"} `),this.replyingToComment){const d=this.shadow.querySelector(".inline-reply-form"),A=d==null?void 0:d.querySelector('[data-role="comment-input"]');A&&(A.value="")}else{const d=this.shadow.querySelector(".modern-comment-form"),A=d==null?void 0:d.querySelector('[data-role="comment-input"]');A&&(A.value="")}this.replyingToComment=null}catch(n){console.error("Failed to submit comment:",n);let i="Failed to submit comment: "+(n instanceof Error?n.message:"Unknown error");n instanceof Error&&n.message.includes("NIP-07")&&(n.message.includes("extension is unlocked")?i="Please unlock your Nostr extension (nos2x/Alby) and try again.":n.message.includes("getPublicKey")?i="Please authorize this website in your Nostr extension.":i="Nostr extension error. Please check if your extension is working properly."),this.showError(i)}finally{this.isSubmitting=!1,this.render()}}});f(this,"addReplyToComment",(t,n)=>{const i=s=>{for(const c of s){if(c.id===n)return t.depth=(c.depth||0)+1,c.replies.push(t),c.replies.sort((h,g)=>h.created_at-g.created_at),!0;if(c.replies.length>0&&i(c.replies))return!0}return!1};i(this.comments)});f(this,"startReply",t=>{this.replyingToComment=null,this.render(),setTimeout(()=>{this.replyingToComment=t,this.render(),setTimeout(()=>{const n=this.shadow.querySelector(".inline-reply-form"),i=n==null?void 0:n.querySelector('[data-role="comment-input"]');i&&i.focus()},100)},10)});f(this,"cancelReply",()=>{this.replyingToComment=null,this.render()});this.shadow=this.attachShadow({mode:"open"})}findRootAndParent(t){let n,i;const s=(c,h,g)=>{var y;for(const d of c){const A=h??d.id;if(d.id===t)return n=A,i=g,!0;if((y=d.replies)!=null&&y.length&&s(d.replies,A,d.id))return!0}return!1};return s(this.comments),{rootId:n,parentId:i}}async connectedCallback(){if(!this.rendered)try{this.getTheme(),this.baseUrl=this.getBaseUrl(),await this.initializeUser(),await this.loadComments(),this.setupNip07StateMonitoring(),this.rendered=!0}catch(t){console.error("Error in connectedCallback:",t),this.isError=!0,this.errorMessage="Failed to initialize comment component",this.render()}}static get observedAttributes(){return["relays","theme","url","readonly","placeholder"]}async attributeChangedCallback(t,n,i){t==="relays"&&(this.nostrService.connectToNostr(this.getRelays()),await this.loadComments()),t==="theme"&&(this.getTheme(),this.render()),t==="url"&&(this.baseUrl=this.getBaseUrl(),await this.loadComments()),["readonly","placeholder"].includes(t)&&this.render()}disconnectedCallback(){this.removeEventListeners(),this.nip07MonitoringInterval&&(clearInterval(this.nip07MonitoringInterval),this.nip07MonitoringInterval=null)}attachEventListeners(){this.removeEventListeners(),this.shadow.querySelectorAll('[data-role="submit-comment"]').forEach(t=>{const n=i=>{i.preventDefault();const s=i.target.closest(".modern-comment-form, .inline-reply-form"),c=s==null?void 0:s.querySelector('[data-role="comment-input"]');c&&this.submitComment(c.value)};t.addEventListener("click",n),this.eventListeners.push({element:t,type:"click",handler:n})}),this.shadow.querySelectorAll('[data-role="comment-input"]').forEach(t=>{const n=i=>{const s=i;s.key==="Enter"&&(s.ctrlKey||s.metaKey)&&(s.preventDefault(),this.submitComment(t.value))};t.addEventListener("keydown",n),this.eventListeners.push({element:t,type:"keydown",handler:n})}),this.shadow.querySelectorAll('[data-role="cancel-reply"]').forEach(t=>{const n=i=>{i.preventDefault(),this.cancelReply()};t.addEventListener("click",n),this.eventListeners.push({element:t,type:"click",handler:n})}),this.shadow.querySelectorAll(".reply-btn").forEach(t=>{const n=i=>{i.preventDefault();const s=i.currentTarget.getAttribute("data-comment-id");s&&this.startReply(s)};t.addEventListener("click",n),this.eventListeners.push({element:t,type:"click",handler:n})}),this.shadow.querySelectorAll('[data-role="toggle-as-user"]').forEach(t=>{if(!this.hasNip07)t.disabled=!0,t.title="NIP-07 extension not detected";else{const n=async i=>{i.preventDefault(),this.commentAs!=="user"&&(this.commentAs="user",this.userPrivateKey=null,this.anonPrivateKeyHex=null,await this.initializeUser())};t.addEventListener("click",n),this.eventListeners.push({element:t,type:"click",handler:n})}}),this.shadow.querySelectorAll('[data-role="toggle-as-anon"]').forEach(t=>{t.disabled=!1;const n=async i=>{i.preventDefault(),this.commentAs!=="anon"&&(this.commentAs="anon",this.userPublicKey=null,this.userPrivateKey=null,await this.initializeUser())};t.addEventListener("click",n),this.eventListeners.push({element:t,type:"click",handler:n})})}attachAvatarErrorHandlers(){this.shadow.querySelectorAll("img[src]").forEach(t=>{const n=i=>{const s=i.target;if(s.src===this.getDefaultAvatarUrl()){console.warn("Avatar fallback also failed, preventing infinite loop");return}s.src=this.getDefaultAvatarUrl()};t.addEventListener("error",n),this.eventListeners.push({element:t,type:"error",handler:n})})}removeEventListeners(){this.eventListeners.forEach(({element:t,type:n,handler:i})=>{t.removeEventListener(n,i)}),this.eventListeners=[]}showError(t){const n=document.createElement("div");n.className="nostr-comment-error",n.style.cssText=`
905
905
  position: fixed;
906
906
  top: 20px;
907
907
  right: 20px;
@@ -915,10 +915,10 @@ var Xt=Object.defineProperty;var Zt=(o,r,t)=>r in o?Xt(o,r,{enumerable:!0,config
915
915
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
916
916
  font-size: 14px;
917
917
  line-height: 1.4;
918
- `,n.textContent=t,document.body.appendChild(n);const a=t.includes("NIP-07")?8e3:5e3;setTimeout(()=>{n.parentNode&&n.parentNode.removeChild(n)},a)}getDefaultAvatarUrl(){try{return new URL("/assets/default_dp-NQ3TGrtT.png",import.meta.url).toString()}catch(t){return console.warn("Failed to resolve default avatar URL with import.meta.url, using relative path:",t),"../../assets/default_dp.png"}}async ensureAnonKey(){const t="nostr-comment-anon-private-key";try{const s=localStorage.getItem(t);if(s&&s.match(/^[a-f0-9]{64}$/))return s}catch(s){console.warn("Failed to read from localStorage:",s)}const{generateSecretKey:n}=await xe(async()=>{const{generateSecretKey:s}=await import("../assets/pure-DPo-pzxM.js");return{generateSecretKey:s}},__vite__mapDeps([0,1])),a=Array.from(n()).map(s=>s.toString(16).padStart(2,"0")).join("");try{localStorage.setItem(t,a)}catch(s){console.warn("Failed to write to localStorage, using ephemeral key:",s)}return a}render(){this.classList.toggle("dark",this.theme==="dark"),this.classList.toggle("loading",this.isLoading),this.classList.toggle("error-container",this.isError);const t=this.hasAttribute("readonly"),n=this.getAttribute("placeholder")||"Write a comment...",a=sn(this.isLoading,this.isError,this.errorMessage,this.comments,t,n,this.isSubmitting,this.currentUserProfile,this.replyingToComment,this.commentAs,this.hasNip07),s=Pn.sanitize(a,{ALLOWED_TAGS:["div","span","button","textarea","img","a","h3","h4","p","ul","li","small","strong","em"],ALLOWED_ATTR:["class","data-role","data-comment-id","data-depth","src","alt","href","target","rel","placeholder","rows","disabled"],ALLOW_DATA_ATTR:!1});this.shadow.innerHTML=`
919
- ${ln(this.theme)}
918
+ `,n.textContent=t,document.body.appendChild(n);const i=t.includes("NIP-07")?8e3:5e3;setTimeout(()=>{n.parentNode&&n.parentNode.removeChild(n)},i)}getDefaultAvatarUrl(){try{return new URL("./assets/default_dp.png",import.meta.url).toString()}catch(t){return console.warn("Failed to resolve default avatar URL with import.meta.url, using relative path:",t),"./assets/default_dp.png"}}async ensureAnonKey(){const t="nostr-comment-anon-private-key";try{const s=localStorage.getItem(t);if(s&&s.match(/^[a-f0-9]{64}$/))return s}catch(s){console.warn("Failed to read from localStorage:",s)}const{generateSecretKey:n}=await ve(async()=>{const{generateSecretKey:s}=await import("../assets/pure-laCRX9eG.js");return{generateSecretKey:s}},__vite__mapDeps([0,1])),i=Array.from(n()).map(s=>s.toString(16).padStart(2,"0")).join("");try{localStorage.setItem(t,i)}catch(s){console.warn("Failed to write to localStorage, using ephemeral key:",s)}return i}render(){this.classList.toggle("dark",this.theme==="dark"),this.classList.toggle("loading",this.isLoading),this.classList.toggle("error-container",this.isError);const t=this.hasAttribute("readonly"),n=this.getAttribute("placeholder")||"Write a comment...",i=ln(this.isLoading,this.isError,this.errorMessage,this.comments,t,n,this.isSubmitting,this.currentUserProfile,this.replyingToComment,this.commentAs,this.hasNip07),s=Nn.sanitize(i,{ALLOWED_TAGS:["div","span","button","textarea","img","a","h3","h4","p","ul","li","small","strong","em"],ALLOWED_ATTR:["class","data-role","data-comment-id","data-depth","src","alt","href","target","rel","placeholder","rows","disabled"],ALLOW_DATA_ATTR:!1});this.shadow.innerHTML=`
919
+ ${cn(this.theme)}
920
920
  <div class="nostr-comment-wrapper">
921
921
  ${s}
922
922
  </div>
923
- `,this.attachEventListeners(),this.attachAvatarErrorHandlers()}}customElements.get("nostr-comment")||customElements.define("nostr-comment",Nn);export{Nn as default};
923
+ `,this.attachEventListeners(),this.attachAvatarErrorHandlers()}}customElements.get("nostr-comment")||customElements.define("nostr-comment",Cn);
924
924
  //# sourceMappingURL=nostr-comment.es.js.map