@sonordev/site-kit 5.8.2 → 6.0.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 (545) hide show
  1. package/README.md +11 -11
  2. package/agent-manifest.json +22 -11
  3. package/dist/{AnalyticsProvider-LUEUDZZC.mjs → AnalyticsProvider-6QVM2B6O.mjs} +6 -6
  4. package/dist/{AnalyticsProvider-LUEUDZZC.mjs.map → AnalyticsProvider-6QVM2B6O.mjs.map} +1 -1
  5. package/dist/{AnalyticsProvider-4JV3OFCG.js → AnalyticsProvider-AZQXLRWN.js} +10 -10
  6. package/dist/{AnalyticsProvider-4JV3OFCG.js.map → AnalyticsProvider-AZQXLRWN.js.map} +1 -1
  7. package/dist/ArticleFaqSection-3KZ24MFS.js +13 -0
  8. package/dist/ArticleFaqSection-3KZ24MFS.js.map +1 -0
  9. package/dist/ArticleFaqSection-XZPXJVH4.mjs +11 -0
  10. package/dist/ArticleFaqSection-XZPXJVH4.mjs.map +1 -0
  11. package/dist/{BlogViewTracker-YQMTEGYZ.mjs → ArticleViewTracker-AEWJMXQQ.mjs} +13 -13
  12. package/dist/ArticleViewTracker-AEWJMXQQ.mjs.map +1 -0
  13. package/dist/{BlogViewTracker-32C4SCHA.js → ArticleViewTracker-CFBTQ46B.js} +16 -16
  14. package/dist/ArticleViewTracker-CFBTQ46B.js.map +1 -0
  15. package/dist/ChatWidget-6626OPXO.mjs +15 -0
  16. package/dist/{ChatWidget-IRTAMRQS.mjs.map → ChatWidget-6626OPXO.mjs.map} +1 -1
  17. package/dist/ChatWidget-U24AYLXF.js +24 -0
  18. package/dist/{ChatWidget-KCXQXNUF.js.map → ChatWidget-U24AYLXF.js.map} +1 -1
  19. package/dist/EngageWidget-TR47W2ZI.mjs +12 -0
  20. package/dist/{EngageWidget-7AIUJRXV.mjs.map → EngageWidget-TR47W2ZI.mjs.map} +1 -1
  21. package/dist/EngageWidget-XUTDFRF3.js +21 -0
  22. package/dist/{EngageWidget-EUUZHQOU.js.map → EngageWidget-XUTDFRF3.js.map} +1 -1
  23. package/dist/{FileField-XJYJO5HE.mjs → FileField-DNNC5IPS.mjs} +5 -5
  24. package/dist/{FileField-XJYJO5HE.mjs.map → FileField-DNNC5IPS.mjs.map} +1 -1
  25. package/dist/{FileField-SNI5XCHQ.js → FileField-R4RQG77G.js} +6 -6
  26. package/dist/{FileField-SNI5XCHQ.js.map → FileField-R4RQG77G.js.map} +1 -1
  27. package/dist/{FormSpotlight-S64G4CMM.js → FormSpotlight-7ILRAD3W.js} +9 -9
  28. package/dist/{FormSpotlight-S64G4CMM.js.map → FormSpotlight-7ILRAD3W.js.map} +1 -1
  29. package/dist/{FormSpotlight-BCXI4A4R.mjs → FormSpotlight-MXY4I46H.mjs} +3 -3
  30. package/dist/{FormSpotlight-BCXI4A4R.mjs.map → FormSpotlight-MXY4I46H.mjs.map} +1 -1
  31. package/dist/{FormStage-PX5TVY25.js → FormStage-CVD3I3SE.js} +9 -9
  32. package/dist/{FormStage-PX5TVY25.js.map → FormStage-CVD3I3SE.js.map} +1 -1
  33. package/dist/{FormStage-RHARCSPS.mjs → FormStage-FDJGRGEU.mjs} +3 -3
  34. package/dist/{FormStage-RHARCSPS.mjs.map → FormStage-FDJGRGEU.mjs.map} +1 -1
  35. package/dist/ManagedForm-5675CLWS.mjs +16 -0
  36. package/dist/{ManagedForm-7IDXBQS6.mjs.map → ManagedForm-5675CLWS.mjs.map} +1 -1
  37. package/dist/ManagedForm-KYIK54SL.js +25 -0
  38. package/dist/{ManagedForm-RI2TSUZD.js.map → ManagedForm-KYIK54SL.js.map} +1 -1
  39. package/dist/{ManagedNewsletterForm-UXBJ5OJB.mjs → ManagedNewsletterForm-DFLDGNQU.mjs} +11 -11
  40. package/dist/ManagedNewsletterForm-DFLDGNQU.mjs.map +1 -0
  41. package/dist/{ManagedNewsletterForm-IAGIHBNT.js → ManagedNewsletterForm-IH3MRJOD.js} +13 -13
  42. package/dist/ManagedNewsletterForm-IH3MRJOD.js.map +1 -0
  43. package/dist/{SignalCore-Q2BQMPCJ.js → SignalCore-6LYIZFXK.js} +11 -11
  44. package/dist/{SignalCore-Q2BQMPCJ.js.map → SignalCore-6LYIZFXK.js.map} +1 -1
  45. package/dist/{SignalCore-37WGILFY.mjs → SignalCore-ZH3R6XD3.mjs} +5 -5
  46. package/dist/{SignalCore-37WGILFY.mjs.map → SignalCore-ZH3R6XD3.mjs.map} +1 -1
  47. package/dist/SitemapSync-PKBXWVI6.mjs +9 -0
  48. package/dist/{SitemapSync-YIAI7PMT.mjs.map → SitemapSync-PKBXWVI6.mjs.map} +1 -1
  49. package/dist/SitemapSync-PZ76V5MX.js +18 -0
  50. package/dist/{SitemapSync-DWEL7HTB.js.map → SitemapSync-PZ76V5MX.js.map} +1 -1
  51. package/dist/analytics/index.js +9 -9
  52. package/dist/analytics/index.mjs +4 -4
  53. package/dist/{blog-styles-7AKRUMV7.mjs → article-styles-DACUAOVT.mjs} +124 -124
  54. package/dist/article-styles-DACUAOVT.mjs.map +1 -0
  55. package/dist/{blog-styles-6EY3BS5Y.js → article-styles-JHHTNHOK.js} +125 -125
  56. package/dist/article-styles-JHHTNHOK.js.map +1 -0
  57. package/dist/article-tables-EWXG4LNP.js +17 -0
  58. package/dist/article-tables-EWXG4LNP.js.map +1 -0
  59. package/dist/article-tables-OGE52LNT.mjs +4 -0
  60. package/dist/article-tables-OGE52LNT.mjs.map +1 -0
  61. package/dist/{blog/BlogPost.d.ts → articles/Article.d.ts} +18 -16
  62. package/dist/articles/Article.d.ts.map +1 -0
  63. package/dist/{blog/BlogFAQ.d.ts → articles/ArticleFAQ.d.ts} +6 -6
  64. package/dist/articles/ArticleFAQ.d.ts.map +1 -0
  65. package/dist/articles/ArticleFaqSection.d.ts +3 -0
  66. package/dist/articles/ArticleFaqSection.d.ts.map +1 -0
  67. package/dist/{blog/BlogList.d.ts → articles/ArticleList.d.ts} +16 -16
  68. package/dist/articles/ArticleList.d.ts.map +1 -0
  69. package/dist/{blog/BlogViewTracker.d.ts → articles/ArticleViewTracker.d.ts} +4 -4
  70. package/dist/articles/ArticleViewTracker.d.ts.map +1 -0
  71. package/dist/{blog → articles}/AuthorCard.d.ts +3 -3
  72. package/dist/articles/AuthorCard.d.ts.map +1 -0
  73. package/dist/{blog → articles}/AuthorPage.d.ts +1 -1
  74. package/dist/articles/AuthorPage.d.ts.map +1 -0
  75. package/dist/{blog → articles}/ClusterLandingPage.d.ts +6 -6
  76. package/dist/articles/ClusterLandingPage.d.ts.map +1 -0
  77. package/dist/{blog → articles}/ClusterNavigation.d.ts +5 -5
  78. package/dist/articles/ClusterNavigation.d.ts.map +1 -0
  79. package/dist/{blog → articles}/ManagedNewsletterForm.d.ts +1 -1
  80. package/dist/articles/ManagedNewsletterForm.d.ts.map +1 -0
  81. package/dist/{blog → articles}/NewsletterShell.d.ts +1 -1
  82. package/dist/articles/NewsletterShell.d.ts.map +1 -0
  83. package/dist/{blog → articles}/NewsletterWidget.d.ts +4 -4
  84. package/dist/articles/NewsletterWidget.d.ts.map +1 -0
  85. package/dist/{blog/BlogLayout.d.ts → articles/PublicationLayout.d.ts} +18 -18
  86. package/dist/articles/PublicationLayout.d.ts.map +1 -0
  87. package/dist/{blog/BlogSidebar.d.ts → articles/PublicationSidebar.d.ts} +8 -8
  88. package/dist/articles/PublicationSidebar.d.ts.map +1 -0
  89. package/dist/{blog → articles}/RelatedPosts.d.ts +6 -6
  90. package/dist/articles/RelatedPosts.d.ts.map +1 -0
  91. package/dist/{blog → articles}/ServiceCallout.d.ts +4 -4
  92. package/dist/articles/ServiceCallout.d.ts.map +1 -0
  93. package/dist/{blog → articles}/TableOfContents.d.ts +1 -1
  94. package/dist/articles/TableOfContents.d.ts.map +1 -0
  95. package/dist/{blog/blog-styles.d.ts → articles/article-styles.d.ts} +5 -5
  96. package/dist/articles/article-styles.d.ts.map +1 -0
  97. package/dist/{blog/blog-tables.d.ts → articles/article-tables.d.ts} +4 -4
  98. package/dist/articles/article-tables.d.ts.map +1 -0
  99. package/dist/articles/artwork.d.ts +14 -0
  100. package/dist/articles/artwork.d.ts.map +1 -0
  101. package/dist/{blog → articles}/author-schema.d.ts +6 -5
  102. package/dist/articles/author-schema.d.ts.map +1 -0
  103. package/dist/{blog → articles}/author-social.d.ts +2 -2
  104. package/dist/articles/author-social.d.ts.map +1 -0
  105. package/dist/{blog → articles}/excerpt.d.ts +2 -2
  106. package/dist/articles/excerpt.d.ts.map +1 -0
  107. package/dist/{blog → articles}/index.d.ts +26 -31
  108. package/dist/articles/index.d.ts.map +1 -0
  109. package/dist/{blog → articles}/index.js +39 -73
  110. package/dist/articles/index.js.map +1 -0
  111. package/dist/{blog → articles}/index.mjs +16 -17
  112. package/dist/articles/index.mjs.map +1 -0
  113. package/dist/articles/news-sitemap.d.ts +47 -0
  114. package/dist/articles/news-sitemap.d.ts.map +1 -0
  115. package/dist/{blog/processBlogHtml.d.ts → articles/processArticleHtml.d.ts} +4 -4
  116. package/dist/articles/processArticleHtml.d.ts.map +1 -0
  117. package/dist/articles/public-reads.d.ts +27 -0
  118. package/dist/articles/public-reads.d.ts.map +1 -0
  119. package/dist/{blog → articles}/reading-time.d.ts +2 -2
  120. package/dist/articles/reading-time.d.ts.map +1 -0
  121. package/dist/{blog → articles}/routes.d.ts +16 -12
  122. package/dist/articles/routes.d.ts.map +1 -0
  123. package/dist/{blog → articles}/server-core.d.ts +94 -81
  124. package/dist/articles/server-core.d.ts.map +1 -0
  125. package/dist/articles/server-ui.d.ts +29 -0
  126. package/dist/articles/server-ui.d.ts.map +1 -0
  127. package/dist/{chunk-KPWK23G7.js → articles/server-ui.js} +378 -499
  128. package/dist/articles/server-ui.js.map +1 -0
  129. package/dist/{chunk-RA4DCRMR.mjs → articles/server-ui.mjs} +328 -474
  130. package/dist/articles/server-ui.mjs.map +1 -0
  131. package/dist/{blog → articles}/server.d.ts +94 -81
  132. package/dist/articles/server.d.ts.map +1 -0
  133. package/dist/articles/server.js +236 -0
  134. package/dist/articles/server.mjs +11 -0
  135. package/dist/{blog → articles}/types.d.ts +34 -34
  136. package/dist/articles/types.d.ts.map +1 -0
  137. package/dist/articles/widget-styles.d.ts +9 -0
  138. package/dist/articles/widget-styles.d.ts.map +1 -0
  139. package/dist/brand/extract-brand-profile.d.ts +1 -1
  140. package/dist/{chunk-DTWR7VRQ.js → chunk-254IW4FC.js} +9 -9
  141. package/dist/{chunk-DTWR7VRQ.js.map → chunk-254IW4FC.js.map} +1 -1
  142. package/dist/chunk-2KRAY5NC.mjs +6 -0
  143. package/dist/{chunk-TAPCWMBV.mjs.map → chunk-2KRAY5NC.mjs.map} +1 -1
  144. package/dist/{chunk-X6NPTILR.mjs → chunk-2WEBUZNP.mjs} +3 -3
  145. package/dist/{chunk-X6NPTILR.mjs.map → chunk-2WEBUZNP.mjs.map} +1 -1
  146. package/dist/{chunk-3EXBBFXX.mjs → chunk-2YSB4FIC.mjs} +4 -4
  147. package/dist/{chunk-3EXBBFXX.mjs.map → chunk-2YSB4FIC.mjs.map} +1 -1
  148. package/dist/{chunk-GDH42JAS.js → chunk-3GHPFLEH.js} +15 -15
  149. package/dist/{chunk-GDH42JAS.js.map → chunk-3GHPFLEH.js.map} +1 -1
  150. package/dist/{chunk-QWXTQC3N.js → chunk-3LCJJ6Y6.js} +3 -3
  151. package/dist/{chunk-QWXTQC3N.js.map → chunk-3LCJJ6Y6.js.map} +1 -1
  152. package/dist/{chunk-YVQNOB3Q.mjs → chunk-3OCXVTN5.mjs} +3 -3
  153. package/dist/{chunk-YVQNOB3Q.mjs.map → chunk-3OCXVTN5.mjs.map} +1 -1
  154. package/dist/chunk-3T2CVHFO.mjs +453 -0
  155. package/dist/chunk-3T2CVHFO.mjs.map +1 -0
  156. package/dist/{chunk-ZDXY44FH.js → chunk-3U5SVB4W.js} +4 -4
  157. package/dist/{chunk-ZDXY44FH.js.map → chunk-3U5SVB4W.js.map} +1 -1
  158. package/dist/{chunk-I3ND4XYW.js → chunk-4BEGKFMN.js} +8 -8
  159. package/dist/{chunk-I3ND4XYW.js.map → chunk-4BEGKFMN.js.map} +1 -1
  160. package/dist/{chunk-YFX3Q56O.mjs → chunk-4KAMU5HD.mjs} +3 -3
  161. package/dist/chunk-4KAMU5HD.mjs.map +1 -0
  162. package/dist/{chunk-ZPLN537Q.mjs → chunk-4WCA2HM6.mjs} +2 -2
  163. package/dist/chunk-4WCA2HM6.mjs.map +1 -0
  164. package/dist/{chunk-PXWYMOZY.js → chunk-5DSUPTBU.js} +13 -13
  165. package/dist/{chunk-PXWYMOZY.js.map → chunk-5DSUPTBU.js.map} +1 -1
  166. package/dist/{chunk-GHECYDSZ.mjs → chunk-5F2FIM5A.mjs} +16 -15
  167. package/dist/chunk-5F2FIM5A.mjs.map +1 -0
  168. package/dist/{chunk-Y5QZPUL3.mjs → chunk-5YVQWLSQ.mjs} +5 -5
  169. package/dist/chunk-5YVQWLSQ.mjs.map +1 -0
  170. package/dist/chunk-6DCAMW62.mjs +55 -0
  171. package/dist/chunk-6DCAMW62.mjs.map +1 -0
  172. package/dist/{chunk-Q2NBD54V.js → chunk-7THQ4UW3.js} +2 -2
  173. package/dist/chunk-7THQ4UW3.js.map +1 -0
  174. package/dist/{chunk-6FTC6EYD.mjs → chunk-7TKSRUQU.mjs} +7 -7
  175. package/dist/{chunk-6FTC6EYD.mjs.map → chunk-7TKSRUQU.mjs.map} +1 -1
  176. package/dist/{chunk-4TLFZ6NR.mjs → chunk-AS2HUIDW.mjs} +3 -3
  177. package/dist/chunk-AS2HUIDW.mjs.map +1 -0
  178. package/dist/{chunk-YN7QHLWF.js → chunk-BBBJHYPH.js} +5 -5
  179. package/dist/chunk-BBBJHYPH.js.map +1 -0
  180. package/dist/{chunk-3Y7IKQDD.js → chunk-BZG34WHF.js} +14 -14
  181. package/dist/{chunk-3Y7IKQDD.js.map → chunk-BZG34WHF.js.map} +1 -1
  182. package/dist/{chunk-4LYW6PMU.mjs → chunk-C2CTLLIO.mjs} +3 -3
  183. package/dist/chunk-C2CTLLIO.mjs.map +1 -0
  184. package/dist/{chunk-O237KKCX.mjs → chunk-C5VITBN7.mjs} +5 -5
  185. package/dist/chunk-C5VITBN7.mjs.map +1 -0
  186. package/dist/{chunk-75A4KY4X.mjs → chunk-CFRJ2MK5.mjs} +2 -2
  187. package/dist/chunk-CFRJ2MK5.mjs.map +1 -0
  188. package/dist/{chunk-G2WC3CXW.js → chunk-CLO3K7PF.js} +2 -2
  189. package/dist/chunk-CLO3K7PF.js.map +1 -0
  190. package/dist/{chunk-ALVQOG4M.mjs → chunk-CSSNZGTU.mjs} +4 -4
  191. package/dist/{chunk-ALVQOG4M.mjs.map → chunk-CSSNZGTU.mjs.map} +1 -1
  192. package/dist/{chunk-U6O5NG56.js → chunk-CZGGUPPQ.js} +15 -15
  193. package/dist/{chunk-U6O5NG56.js.map → chunk-CZGGUPPQ.js.map} +1 -1
  194. package/dist/{chunk-U5WMGUDV.js → chunk-D47W5DE4.js} +4 -4
  195. package/dist/{chunk-U5WMGUDV.js.map → chunk-D47W5DE4.js.map} +1 -1
  196. package/dist/{chunk-AK6JZ3OE.mjs → chunk-EDLNMGQC.mjs} +3 -3
  197. package/dist/{chunk-DO6ATNLN.js.map → chunk-EDLNMGQC.mjs.map} +1 -1
  198. package/dist/chunk-EL74YDNX.js +8 -0
  199. package/dist/{chunk-TJVZEDE3.js.map → chunk-EL74YDNX.js.map} +1 -1
  200. package/dist/{chunk-HX6ZG3PP.js → chunk-EMHSHAVW.js} +3 -3
  201. package/dist/chunk-EMHSHAVW.js.map +1 -0
  202. package/dist/{chunk-7TC3GRXQ.js → chunk-G6KQ3C3W.js} +25 -23
  203. package/dist/chunk-G6KQ3C3W.js.map +1 -0
  204. package/dist/{chunk-4PXUMDHL.mjs → chunk-GQ3SDRL6.mjs} +4 -4
  205. package/dist/{chunk-4PXUMDHL.mjs.map → chunk-GQ3SDRL6.mjs.map} +1 -1
  206. package/dist/{chunk-73EBIAF3.js → chunk-HFCQGSD2.js} +18 -18
  207. package/dist/{chunk-73EBIAF3.js.map → chunk-HFCQGSD2.js.map} +1 -1
  208. package/dist/{chunk-XZO5I4RS.mjs → chunk-HIZJD7TU.mjs} +3 -3
  209. package/dist/{chunk-XZO5I4RS.mjs.map → chunk-HIZJD7TU.mjs.map} +1 -1
  210. package/dist/{chunk-AUTJQGZ2.mjs → chunk-HOOVYWTO.mjs} +4 -4
  211. package/dist/{chunk-AUTJQGZ2.mjs.map → chunk-HOOVYWTO.mjs.map} +1 -1
  212. package/dist/{chunk-LUF22UGR.js → chunk-HX5JPNMN.js} +8 -8
  213. package/dist/{chunk-LUF22UGR.js.map → chunk-HX5JPNMN.js.map} +1 -1
  214. package/dist/chunk-HXHRS3PX.mjs +349 -0
  215. package/dist/chunk-HXHRS3PX.mjs.map +1 -0
  216. package/dist/{chunk-XBX2K3GA.js → chunk-IBJOGXQI.js} +4 -4
  217. package/dist/{chunk-XBX2K3GA.js.map → chunk-IBJOGXQI.js.map} +1 -1
  218. package/dist/{chunk-NHX6YJ7G.mjs → chunk-JMNBU2RG.mjs} +9 -9
  219. package/dist/{chunk-NHX6YJ7G.mjs.map → chunk-JMNBU2RG.mjs.map} +1 -1
  220. package/dist/{chunk-R7GHP3FY.js → chunk-JONWE26J.js} +3 -3
  221. package/dist/chunk-JONWE26J.js.map +1 -0
  222. package/dist/{chunk-HOJ4J4X2.mjs → chunk-JSXLTZUP.mjs} +6 -6
  223. package/dist/{chunk-HOJ4J4X2.mjs.map → chunk-JSXLTZUP.mjs.map} +1 -1
  224. package/dist/{chunk-5BZNVKNK.mjs → chunk-JXCMCASE.mjs} +3 -3
  225. package/dist/{chunk-5BZNVKNK.mjs.map → chunk-JXCMCASE.mjs.map} +1 -1
  226. package/dist/{chunk-F2ZFMPW4.js → chunk-KA4NNWOK.js} +10 -10
  227. package/dist/{chunk-F2ZFMPW4.js.map → chunk-KA4NNWOK.js.map} +1 -1
  228. package/dist/{chunk-K4TCEAUX.js → chunk-KR7ATPAN.js} +5 -5
  229. package/dist/chunk-KR7ATPAN.js.map +1 -0
  230. package/dist/{chunk-JLVCWC6A.mjs → chunk-KZVSB5WE.mjs} +2 -2
  231. package/dist/chunk-KZVSB5WE.mjs.map +1 -0
  232. package/dist/chunk-LWCAZDY2.js +355 -0
  233. package/dist/chunk-LWCAZDY2.js.map +1 -0
  234. package/dist/{chunk-D7CF3OPZ.js → chunk-MCG4BSRW.js} +5 -5
  235. package/dist/{chunk-D7CF3OPZ.js.map → chunk-MCG4BSRW.js.map} +1 -1
  236. package/dist/{chunk-OBNMSO66.js → chunk-MIYGP34I.js} +14 -14
  237. package/dist/{chunk-OBNMSO66.js.map → chunk-MIYGP34I.js.map} +1 -1
  238. package/dist/{chunk-PXK4WNSU.js → chunk-MS2EE6LT.js} +10 -10
  239. package/dist/{chunk-PXK4WNSU.js.map → chunk-MS2EE6LT.js.map} +1 -1
  240. package/dist/{chunk-JR2FT6T5.js → chunk-N6CB7MK7.js} +6 -6
  241. package/dist/{chunk-JR2FT6T5.js.map → chunk-N6CB7MK7.js.map} +1 -1
  242. package/dist/{chunk-LMEUYRRR.js → chunk-NAA5J2JM.js} +233 -120
  243. package/dist/chunk-NAA5J2JM.js.map +1 -0
  244. package/dist/{chunk-OE7CTIOU.mjs → chunk-NE6QGHFT.mjs} +4 -4
  245. package/dist/{chunk-OE7CTIOU.mjs.map → chunk-NE6QGHFT.mjs.map} +1 -1
  246. package/dist/{chunk-SCVSPTXJ.mjs → chunk-NR52QHOD.mjs} +3 -3
  247. package/dist/{chunk-SCVSPTXJ.mjs.map → chunk-NR52QHOD.mjs.map} +1 -1
  248. package/dist/{chunk-GQF6QAQS.js → chunk-OGNX6JT4.js} +5 -5
  249. package/dist/chunk-OGNX6JT4.js.map +1 -0
  250. package/dist/{chunk-FVW6FT6L.js → chunk-OSU4QA5M.js} +8 -8
  251. package/dist/{chunk-FVW6FT6L.js.map → chunk-OSU4QA5M.js.map} +1 -1
  252. package/dist/{chunk-RI25UGHE.mjs → chunk-PJYTYM5G.mjs} +3 -3
  253. package/dist/{chunk-RI25UGHE.mjs.map → chunk-PJYTYM5G.mjs.map} +1 -1
  254. package/dist/{chunk-DO6ATNLN.js → chunk-PRAHDLKT.js} +5 -5
  255. package/dist/chunk-PRAHDLKT.js.map +1 -0
  256. package/dist/{chunk-RQOKQC7J.mjs → chunk-QEM2F2DC.mjs} +3 -3
  257. package/dist/{chunk-RQOKQC7J.mjs.map → chunk-QEM2F2DC.mjs.map} +1 -1
  258. package/dist/{chunk-3Z3TOPND.js → chunk-QOCLSJIU.js} +3 -3
  259. package/dist/{chunk-3Z3TOPND.js.map → chunk-QOCLSJIU.js.map} +1 -1
  260. package/dist/{chunk-AHKVOYFO.mjs → chunk-QVBAAPNT.mjs} +3 -3
  261. package/dist/{chunk-AHKVOYFO.mjs.map → chunk-QVBAAPNT.mjs.map} +1 -1
  262. package/dist/{chunk-FWFJZV52.mjs → chunk-RC4L4DV2.mjs} +4 -4
  263. package/dist/{chunk-FWFJZV52.mjs.map → chunk-RC4L4DV2.mjs.map} +1 -1
  264. package/dist/{chunk-ZVI7MBVF.mjs → chunk-RDPI27TS.mjs} +12 -10
  265. package/dist/chunk-RDPI27TS.mjs.map +1 -0
  266. package/dist/{chunk-OEW2LFOV.js → chunk-RLUNEEGM.js} +4 -4
  267. package/dist/{chunk-OEW2LFOV.js.map → chunk-RLUNEEGM.js.map} +1 -1
  268. package/dist/{chunk-TCVOGK6U.mjs → chunk-RPCODOWG.mjs} +3 -3
  269. package/dist/{chunk-TCVOGK6U.mjs.map → chunk-RPCODOWG.mjs.map} +1 -1
  270. package/dist/{chunk-QK54SZPF.mjs → chunk-RZGVNDO6.mjs} +4 -4
  271. package/dist/{chunk-QK54SZPF.mjs.map → chunk-RZGVNDO6.mjs.map} +1 -1
  272. package/dist/{chunk-GKVEWOYN.js → chunk-SCRB5DZM.js} +8 -8
  273. package/dist/{chunk-GKVEWOYN.js.map → chunk-SCRB5DZM.js.map} +1 -1
  274. package/dist/{chunk-YQTE32QK.js → chunk-SG7CWD2R.js} +17 -16
  275. package/dist/chunk-SG7CWD2R.js.map +1 -0
  276. package/dist/chunk-TBXWJJGT.js +468 -0
  277. package/dist/chunk-TBXWJJGT.js.map +1 -0
  278. package/dist/{chunk-SJPI34DL.mjs → chunk-TCCGP3FT.mjs} +3 -3
  279. package/dist/{chunk-SJPI34DL.mjs.map → chunk-TCCGP3FT.mjs.map} +1 -1
  280. package/dist/{chunk-7BI2RVQD.js → chunk-TCZHRSWY.js} +4 -4
  281. package/dist/{chunk-7BI2RVQD.js.map → chunk-TCZHRSWY.js.map} +1 -1
  282. package/dist/{chunk-M45AL7EA.js → chunk-TST2IKYO.js} +14 -14
  283. package/dist/{chunk-M45AL7EA.js.map → chunk-TST2IKYO.js.map} +1 -1
  284. package/dist/{chunk-U2V542EO.mjs → chunk-UHYRVALN.mjs} +2 -2
  285. package/dist/{chunk-U2V542EO.mjs.map → chunk-UHYRVALN.mjs.map} +1 -1
  286. package/dist/{chunk-4L7OHRWB.mjs → chunk-UO6KTHBQ.mjs} +4 -4
  287. package/dist/{chunk-4L7OHRWB.mjs.map → chunk-UO6KTHBQ.mjs.map} +1 -1
  288. package/dist/{chunk-H5NBFNND.js → chunk-UZKXOZHR.js} +2 -2
  289. package/dist/chunk-UZKXOZHR.js.map +1 -0
  290. package/dist/{chunk-ZTY4YS7Q.js → chunk-VINLIMAX.js} +3 -3
  291. package/dist/{chunk-ZTY4YS7Q.js.map → chunk-VINLIMAX.js.map} +1 -1
  292. package/dist/{chunk-YC2CKOX6.js → chunk-WDEGGHTB.js} +12 -12
  293. package/dist/{chunk-YC2CKOX6.js.map → chunk-WDEGGHTB.js.map} +1 -1
  294. package/dist/{chunk-OX2GTNMB.mjs → chunk-WV5YQL3W.mjs} +3 -3
  295. package/dist/{chunk-OX2GTNMB.mjs.map → chunk-WV5YQL3W.mjs.map} +1 -1
  296. package/dist/{chunk-3EY5E35M.mjs → chunk-X3MY4PL7.mjs} +210 -107
  297. package/dist/chunk-X3MY4PL7.mjs.map +1 -0
  298. package/dist/{chunk-7SLYI62M.mjs → chunk-XKXZ4OW4.mjs} +4 -4
  299. package/dist/{chunk-7SLYI62M.mjs.map → chunk-XKXZ4OW4.mjs.map} +1 -1
  300. package/dist/{chunk-FX232N4P.mjs → chunk-XSBKR3VF.mjs} +5 -5
  301. package/dist/{chunk-FX232N4P.mjs.map → chunk-XSBKR3VF.mjs.map} +1 -1
  302. package/dist/{chunk-SEP5D4MI.js → chunk-Y2CP5J6Q.js} +2 -2
  303. package/dist/{chunk-SEP5D4MI.js.map → chunk-Y2CP5J6Q.js.map} +1 -1
  304. package/dist/{chunk-HQ2EPU5R.js → chunk-YGDQVZEL.js} +7 -7
  305. package/dist/{chunk-HQ2EPU5R.js.map → chunk-YGDQVZEL.js.map} +1 -1
  306. package/dist/{chunk-KV7XXLJV.mjs → chunk-YPGUV6BT.mjs} +3 -3
  307. package/dist/{chunk-KV7XXLJV.mjs.map → chunk-YPGUV6BT.mjs.map} +1 -1
  308. package/dist/chunk-YRCR7WY3.js +65 -0
  309. package/dist/chunk-YRCR7WY3.js.map +1 -0
  310. package/dist/{chunk-NM567VXC.mjs → chunk-YWLBQ3L5.mjs} +4 -4
  311. package/dist/{chunk-NM567VXC.mjs.map → chunk-YWLBQ3L5.mjs.map} +1 -1
  312. package/dist/{chunk-3HGHWDCY.js → chunk-YYEBFQGS.js} +4 -4
  313. package/dist/{chunk-3HGHWDCY.js.map → chunk-YYEBFQGS.js.map} +1 -1
  314. package/dist/chunk-ZL35JCDA.mjs +61 -0
  315. package/dist/chunk-ZL35JCDA.mjs.map +1 -0
  316. package/dist/chunk-ZR43XFUM.js +60 -0
  317. package/dist/chunk-ZR43XFUM.js.map +1 -0
  318. package/dist/{chunk-EZ5DX7ED.mjs → chunk-ZR4TYCQW.mjs} +3 -3
  319. package/dist/{chunk-EZ5DX7ED.mjs.map → chunk-ZR4TYCQW.mjs.map} +1 -1
  320. package/dist/cli/commands/setup.d.ts +2 -2
  321. package/dist/cli/commands/sync.d.ts +2 -2
  322. package/dist/cli/commands/sync.d.ts.map +1 -1
  323. package/dist/cli/index.js +76 -76
  324. package/dist/cli/index.mjs +29 -29
  325. package/dist/client/index.js +5 -5
  326. package/dist/client/index.mjs +4 -4
  327. package/dist/commerce/index.js +57 -57
  328. package/dist/commerce/index.mjs +5 -5
  329. package/dist/commerce/server.d.ts +1 -1
  330. package/dist/commerce/server.js +7 -7
  331. package/dist/commerce/server.js.map +1 -1
  332. package/dist/commerce/server.mjs +7 -7
  333. package/dist/commerce/server.mjs.map +1 -1
  334. package/dist/discover-LPN55L5B.js +21 -0
  335. package/dist/{discover-NGEPXZOD.js.map → discover-LPN55L5B.js.map} +1 -1
  336. package/dist/discover-QGA6QFSR.mjs +4 -0
  337. package/dist/{discover-CYXYKHZ2.mjs.map → discover-QGA6QFSR.mjs.map} +1 -1
  338. package/dist/engage/index.js +13 -13
  339. package/dist/engage/index.mjs +7 -7
  340. package/dist/fleet/contract.d.ts +1 -1
  341. package/dist/fleet/contract.js +12 -12
  342. package/dist/fleet/contract.mjs +1 -1
  343. package/dist/fleet/index.js +20 -20
  344. package/dist/fleet/index.mjs +5 -5
  345. package/dist/forms/index.js +21 -21
  346. package/dist/forms/index.mjs +10 -10
  347. package/dist/forms/server.js +10 -10
  348. package/dist/forms/server.mjs +8 -8
  349. package/dist/forms/static.js +7 -7
  350. package/dist/forms/static.mjs +6 -6
  351. package/dist/images/index.js +11 -11
  352. package/dist/images/index.mjs +4 -4
  353. package/dist/index.d.ts +2 -2
  354. package/dist/index.d.ts.map +1 -1
  355. package/dist/index.js +70 -70
  356. package/dist/index.mjs +12 -12
  357. package/dist/layout/client.js +10 -10
  358. package/dist/layout/client.mjs +9 -9
  359. package/dist/layout/index.js +12 -12
  360. package/dist/layout/index.mjs +10 -10
  361. package/dist/llms/SpeakableSchema.d.ts +1 -1
  362. package/dist/llms/SpeakableSchema.d.ts.map +1 -1
  363. package/dist/llms/client.d.ts +18 -0
  364. package/dist/llms/client.d.ts.map +1 -0
  365. package/dist/llms/client.js +66 -0
  366. package/dist/llms/client.js.map +1 -0
  367. package/dist/llms/client.mjs +5 -0
  368. package/dist/llms/client.mjs.map +1 -0
  369. package/dist/llms/generateLLMsTxt.d.ts.map +1 -1
  370. package/dist/llms/index.js +75 -478
  371. package/dist/llms/index.js.map +1 -1
  372. package/dist/llms/index.mjs +10 -455
  373. package/dist/llms/index.mjs.map +1 -1
  374. package/dist/llms/types.d.ts +7 -0
  375. package/dist/llms/types.d.ts.map +1 -1
  376. package/dist/maps/index.js +5 -5
  377. package/dist/maps/index.mjs +3 -3
  378. package/dist/og/index.js +7 -7
  379. package/dist/og/index.mjs +2 -2
  380. package/dist/og/route.d.ts +6 -6
  381. package/dist/og/route.js.map +1 -1
  382. package/dist/og/route.mjs.map +1 -1
  383. package/dist/og/wiring.d.ts +4 -4
  384. package/dist/og/wiring.d.ts.map +1 -1
  385. package/dist/proxy/index.js +5 -5
  386. package/dist/proxy/index.mjs +3 -3
  387. package/dist/redirects/index.js +10 -10
  388. package/dist/redirects/index.mjs +3 -3
  389. package/dist/redirects/not-found.js +7 -7
  390. package/dist/redirects/not-found.mjs +3 -3
  391. package/dist/robots/indexnow.d.ts +17 -0
  392. package/dist/robots/indexnow.d.ts.map +1 -0
  393. package/dist/robots/indexnow.js +39 -0
  394. package/dist/robots/indexnow.js.map +1 -0
  395. package/dist/robots/indexnow.mjs +34 -0
  396. package/dist/robots/indexnow.mjs.map +1 -0
  397. package/dist/search/contract.d.ts +1 -1
  398. package/dist/search/contract.js +3 -3
  399. package/dist/search/contract.mjs +1 -1
  400. package/dist/search/index.js +7 -7
  401. package/dist/search/index.mjs +5 -5
  402. package/dist/seo/ManagedSchema.d.ts.map +1 -1
  403. package/dist/seo/client.js +6 -6
  404. package/dist/seo/client.mjs +5 -5
  405. package/dist/seo/index.js +58 -50
  406. package/dist/seo/index.js.map +1 -1
  407. package/dist/seo/index.mjs +23 -15
  408. package/dist/seo/index.mjs.map +1 -1
  409. package/dist/seo/register-sitemap-cli.js +12 -12
  410. package/dist/seo/register-sitemap-cli.mjs +5 -5
  411. package/dist/seo/server.js +21 -21
  412. package/dist/seo/server.mjs +5 -5
  413. package/dist/server/index.js +3 -3
  414. package/dist/server/index.mjs +2 -2
  415. package/dist/{server-api-A2EFCTZX.mjs → server-api-7F5P6CSH.mjs} +6 -6
  416. package/dist/{server-api-A2EFCTZX.mjs.map → server-api-7F5P6CSH.mjs.map} +1 -1
  417. package/dist/{server-api-IWTZ7C3O.js → server-api-OC5JNK6R.js} +24 -24
  418. package/dist/{server-api-IWTZ7C3O.js.map → server-api-OC5JNK6R.js.map} +1 -1
  419. package/dist/shared/build-entries.d.ts +15 -7
  420. package/dist/shared/build-entries.d.ts.map +1 -1
  421. package/dist/shared/version.d.ts +1 -1
  422. package/dist/signal/index.js +11 -11
  423. package/dist/signal/index.mjs +2 -2
  424. package/dist/sitemap/discover.d.ts +1 -1
  425. package/dist/sitemap/index.d.ts +7 -1
  426. package/dist/sitemap/index.d.ts.map +1 -1
  427. package/dist/sitemap/index.js +47 -30
  428. package/dist/sitemap/index.js.map +1 -1
  429. package/dist/sitemap/index.mjs +26 -9
  430. package/dist/sitemap/index.mjs.map +1 -1
  431. package/dist/sitemap/shared.d.ts +1 -1
  432. package/dist/sitemap/shared.d.ts.map +1 -1
  433. package/dist/sites/site-param.d.ts +2 -2
  434. package/dist/sync/index.js +17 -17
  435. package/dist/sync/index.mjs +4 -4
  436. package/dist/types.d.ts +1 -1
  437. package/dist/types.d.ts.map +1 -1
  438. package/dist/writeLLMsTxt-ATADOUVZ.js +20 -0
  439. package/dist/writeLLMsTxt-QJFXBHZF.mjs +11 -0
  440. package/package.json +25 -14
  441. package/dist/BlogPostFaqSection-P3GXVQPA.mjs +0 -11
  442. package/dist/BlogPostFaqSection-P3GXVQPA.mjs.map +0 -1
  443. package/dist/BlogPostFaqSection-YG5J4B4U.js +0 -13
  444. package/dist/BlogPostFaqSection-YG5J4B4U.js.map +0 -1
  445. package/dist/BlogViewTracker-32C4SCHA.js.map +0 -1
  446. package/dist/BlogViewTracker-YQMTEGYZ.mjs.map +0 -1
  447. package/dist/ChatWidget-IRTAMRQS.mjs +0 -15
  448. package/dist/ChatWidget-KCXQXNUF.js +0 -24
  449. package/dist/EngageWidget-7AIUJRXV.mjs +0 -12
  450. package/dist/EngageWidget-EUUZHQOU.js +0 -21
  451. package/dist/ManagedForm-7IDXBQS6.mjs +0 -16
  452. package/dist/ManagedForm-RI2TSUZD.js +0 -25
  453. package/dist/ManagedNewsletterForm-IAGIHBNT.js.map +0 -1
  454. package/dist/ManagedNewsletterForm-UXBJ5OJB.mjs.map +0 -1
  455. package/dist/SitemapSync-DWEL7HTB.js +0 -18
  456. package/dist/SitemapSync-YIAI7PMT.mjs +0 -9
  457. package/dist/blog/AuthorCard.d.ts.map +0 -1
  458. package/dist/blog/AuthorPage.d.ts.map +0 -1
  459. package/dist/blog/BlogFAQ.d.ts.map +0 -1
  460. package/dist/blog/BlogLayout.d.ts.map +0 -1
  461. package/dist/blog/BlogList.d.ts.map +0 -1
  462. package/dist/blog/BlogPost.d.ts.map +0 -1
  463. package/dist/blog/BlogPostFaqSection.d.ts +0 -3
  464. package/dist/blog/BlogPostFaqSection.d.ts.map +0 -1
  465. package/dist/blog/BlogSidebar.d.ts.map +0 -1
  466. package/dist/blog/BlogViewTracker.d.ts.map +0 -1
  467. package/dist/blog/ClusterLandingPage.d.ts.map +0 -1
  468. package/dist/blog/ClusterNavigation.d.ts.map +0 -1
  469. package/dist/blog/ManagedNewsletterForm.d.ts.map +0 -1
  470. package/dist/blog/NewsletterShell.d.ts.map +0 -1
  471. package/dist/blog/NewsletterWidget.d.ts.map +0 -1
  472. package/dist/blog/RelatedPosts.d.ts.map +0 -1
  473. package/dist/blog/ServiceCallout.d.ts.map +0 -1
  474. package/dist/blog/TableOfContents.d.ts.map +0 -1
  475. package/dist/blog/artwork.d.ts +0 -14
  476. package/dist/blog/artwork.d.ts.map +0 -1
  477. package/dist/blog/author-schema.d.ts.map +0 -1
  478. package/dist/blog/author-social.d.ts.map +0 -1
  479. package/dist/blog/blog-styles.d.ts.map +0 -1
  480. package/dist/blog/blog-tables.d.ts.map +0 -1
  481. package/dist/blog/excerpt.d.ts.map +0 -1
  482. package/dist/blog/index.d.ts.map +0 -1
  483. package/dist/blog/index.js.map +0 -1
  484. package/dist/blog/index.mjs.map +0 -1
  485. package/dist/blog/processBlogHtml.d.ts.map +0 -1
  486. package/dist/blog/public-reads.d.ts +0 -27
  487. package/dist/blog/public-reads.d.ts.map +0 -1
  488. package/dist/blog/reading-time.d.ts.map +0 -1
  489. package/dist/blog/routes.d.ts.map +0 -1
  490. package/dist/blog/server-core.d.ts.map +0 -1
  491. package/dist/blog/server-ui.d.ts +0 -29
  492. package/dist/blog/server-ui.d.ts.map +0 -1
  493. package/dist/blog/server-ui.js +0 -267
  494. package/dist/blog/server-ui.js.map +0 -1
  495. package/dist/blog/server-ui.mjs +0 -203
  496. package/dist/blog/server-ui.mjs.map +0 -1
  497. package/dist/blog/server.d.ts.map +0 -1
  498. package/dist/blog/server.js +0 -207
  499. package/dist/blog/server.mjs +0 -10
  500. package/dist/blog/types.d.ts.map +0 -1
  501. package/dist/blog/widget-styles.d.ts +0 -9
  502. package/dist/blog/widget-styles.d.ts.map +0 -1
  503. package/dist/blog-styles-6EY3BS5Y.js.map +0 -1
  504. package/dist/blog-styles-7AKRUMV7.mjs.map +0 -1
  505. package/dist/blog-tables-DWDEWA3S.js +0 -17
  506. package/dist/blog-tables-DWDEWA3S.js.map +0 -1
  507. package/dist/blog-tables-QGIHOESZ.mjs +0 -4
  508. package/dist/blog-tables-QGIHOESZ.mjs.map +0 -1
  509. package/dist/chunk-3EY5E35M.mjs.map +0 -1
  510. package/dist/chunk-4LYW6PMU.mjs.map +0 -1
  511. package/dist/chunk-4TLFZ6NR.mjs.map +0 -1
  512. package/dist/chunk-5B4J3IBX.mjs +0 -164
  513. package/dist/chunk-5B4J3IBX.mjs.map +0 -1
  514. package/dist/chunk-75A4KY4X.mjs.map +0 -1
  515. package/dist/chunk-7TC3GRXQ.js.map +0 -1
  516. package/dist/chunk-AK6JZ3OE.mjs.map +0 -1
  517. package/dist/chunk-FHPW7XVH.js +0 -175
  518. package/dist/chunk-FHPW7XVH.js.map +0 -1
  519. package/dist/chunk-G2WC3CXW.js.map +0 -1
  520. package/dist/chunk-GHECYDSZ.mjs.map +0 -1
  521. package/dist/chunk-GQF6QAQS.js.map +0 -1
  522. package/dist/chunk-H5NBFNND.js.map +0 -1
  523. package/dist/chunk-HX6ZG3PP.js.map +0 -1
  524. package/dist/chunk-JLVCWC6A.mjs.map +0 -1
  525. package/dist/chunk-K4TCEAUX.js.map +0 -1
  526. package/dist/chunk-KPWK23G7.js.map +0 -1
  527. package/dist/chunk-LMEUYRRR.js.map +0 -1
  528. package/dist/chunk-O237KKCX.mjs.map +0 -1
  529. package/dist/chunk-Q2NBD54V.js.map +0 -1
  530. package/dist/chunk-R7GHP3FY.js.map +0 -1
  531. package/dist/chunk-RA4DCRMR.mjs.map +0 -1
  532. package/dist/chunk-TAPCWMBV.mjs +0 -6
  533. package/dist/chunk-TJVZEDE3.js +0 -8
  534. package/dist/chunk-Y5QZPUL3.mjs.map +0 -1
  535. package/dist/chunk-YFX3Q56O.mjs.map +0 -1
  536. package/dist/chunk-YN7QHLWF.js.map +0 -1
  537. package/dist/chunk-YQTE32QK.js.map +0 -1
  538. package/dist/chunk-ZPLN537Q.mjs.map +0 -1
  539. package/dist/chunk-ZVI7MBVF.mjs.map +0 -1
  540. package/dist/discover-CYXYKHZ2.mjs +0 -4
  541. package/dist/discover-NGEPXZOD.js +0 -21
  542. package/dist/writeLLMsTxt-CQ7A4AAL.js +0 -19
  543. package/dist/writeLLMsTxt-NX5MSPYX.mjs +0 -10
  544. /package/dist/{blog → articles}/server.js.map +0 -0
  545. /package/dist/{blog → articles}/server.mjs.map +0 -0
@@ -1,175 +0,0 @@
1
- 'use strict';
2
-
3
- var chunkYN7QHLWF_js = require('./chunk-YN7QHLWF.js');
4
-
5
- // src/blog/public-reads.ts
6
- async function fetchBlogPostBySlug({ apiUrl, apiKey, site }, slug) {
7
- try {
8
- const response = await fetch(chunkYN7QHLWF_js.withSiteParam(`${apiUrl}/public/blog/posts/${slug}`, site), {
9
- headers: { "x-api-key": apiKey },
10
- next: { revalidate: 60 }
11
- });
12
- if (!response.ok) {
13
- if (response.status !== 404) console.error("[Blog] Failed to fetch post:", response.statusText);
14
- return null;
15
- }
16
- const data = await response.json();
17
- return data.post || null;
18
- } catch (error) {
19
- console.error("[Blog] Error fetching post:", error);
20
- return null;
21
- }
22
- }
23
- async function fetchBlogCategories({ apiUrl, apiKey, site }) {
24
- try {
25
- const response = await fetch(chunkYN7QHLWF_js.withSiteParam(`${apiUrl}/public/blog/categories`, site), {
26
- headers: { "x-api-key": apiKey },
27
- next: { revalidate: 300 }
28
- });
29
- if (!response.ok) return [];
30
- const data = await response.json();
31
- return data.categories || [];
32
- } catch (error) {
33
- console.error("[Blog] Error fetching categories:", error);
34
- return [];
35
- }
36
- }
37
- async function fetchRelatedBlogPosts({ apiUrl, apiKey, site }, currentPostId, limit, cache = {}) {
38
- try {
39
- const response = await fetch(`${apiUrl}/public/blog/related`, {
40
- method: "POST",
41
- headers: { "Content-Type": "application/json", "x-api-key": apiKey },
42
- body: JSON.stringify(chunkYN7QHLWF_js.withSiteBody({ current_post_id: currentPostId, limit }, site)),
43
- ...cache.revalidate !== void 0 ? { next: { revalidate: cache.revalidate } } : {}
44
- });
45
- if (!response.ok) {
46
- console.error("[Blog] Failed to fetch related posts:", response.statusText);
47
- return [];
48
- }
49
- const data = await response.json();
50
- return data.posts || [];
51
- } catch (error) {
52
- console.error("[Blog] Error fetching related posts:", error);
53
- return [];
54
- }
55
- }
56
-
57
- // src/blog/artwork.ts
58
- function resolveBlogArtwork(post, placement = "card") {
59
- const editorial = placement === "article" && !!post.editorial_image;
60
- const src = (editorial ? post.editorial_image : post.featured_image) || void 0;
61
- const alt = editorial ? post.editorial_image_alt ?? "" : post.featured_image_alt ?? post.title ?? "";
62
- let composed = false;
63
- if (src) {
64
- try {
65
- composed = /\/Blog\/Cards\//i.test(new URL(src, "https://site-kit.invalid").pathname);
66
- } catch {
67
- }
68
- }
69
- return { src, alt, composed };
70
- }
71
- function blogArtworkImageStyle(artwork) {
72
- return artwork.composed ? { display: "block", height: "auto", maxHeight: "none", objectFit: "contain", transform: "none" } : void 0;
73
- }
74
-
75
- // src/blog/routes.ts
76
- function blogCategorySlug(category) {
77
- const value = typeof category === "string" ? category : category?.slug || category?.name || "";
78
- return value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
79
- }
80
- function localPath(path) {
81
- const value = path.trim();
82
- if (!value || /^[a-z][a-z\d+.-]*:/i.test(value) || value.startsWith("//") || value.includes("\\")) {
83
- throw new Error("Blog routes must be local paths, such as /theforge/guides/story.");
84
- }
85
- return value.startsWith("/") ? value : `/${value}`;
86
- }
87
- function createBlogRoutes(options = {}) {
88
- const raw = (options.basePath ?? options.blogBasePath ?? "/blog").trim() || "/blog";
89
- const index = localPath(raw).replace(/\/+$/, "") || "/";
90
- const prefix = index === "/" ? "" : index;
91
- return {
92
- index,
93
- post(post) {
94
- if (options.postPath) return localPath(options.postPath(post));
95
- const category = blogCategorySlug(post.category || options.category);
96
- return `${prefix}${options.includeCategoryInPath && category ? `/${encodeURIComponent(category)}` : ""}/${encodeURIComponent(post.slug)}`;
97
- },
98
- category(slug) {
99
- const normalized = blogCategorySlug(slug);
100
- return options.categoryPath ? localPath(options.categoryPath(normalized)) : `${prefix}/category/${encodeURIComponent(normalized)}`;
101
- },
102
- cluster: (slug) => `${prefix}/cluster/${encodeURIComponent(slug)}`,
103
- author: (slug) => `${prefix}/author/${encodeURIComponent(slug)}`,
104
- rss: `${prefix}/rss.xml`,
105
- atom: `${prefix}/feed.xml`
106
- };
107
- }
108
- function resolveBlogUrl(path, siteUrl = "") {
109
- return `${siteUrl.replace(/\/+$/, "")}${localPath(path)}`;
110
- }
111
- function resolveBlogPostUrl(post, options = {}) {
112
- const canonical = post.canonical_url?.trim();
113
- if (canonical) {
114
- if (/^https?:\/\//i.test(canonical)) {
115
- try {
116
- return new URL(canonical).toString();
117
- } catch {
118
- }
119
- } else if (canonical.startsWith("/") && !canonical.startsWith("//") && !canonical.includes("\\")) {
120
- return resolveBlogUrl(canonical, options.siteUrl);
121
- }
122
- }
123
- return resolveBlogUrl(createBlogRoutes(options).post(post), options.siteUrl);
124
- }
125
-
126
- // src/blog/author-schema.ts
127
- function generateAuthorSchema(author, options = {}) {
128
- const { siteUrl = "", siteName } = options;
129
- const sameAs = [...author.same_as || []];
130
- if (author.linkedin_url) sameAs.push(author.linkedin_url);
131
- if (author.twitter_url) sameAs.push(author.twitter_url);
132
- if (author.website_url) sameAs.push(author.website_url);
133
- if (author.social_links?.twitter) sameAs.push(`https://twitter.com/${author.social_links.twitter}`);
134
- if (author.social_links?.linkedin) sameAs.push(author.social_links.linkedin);
135
- if (author.social_links?.github) sameAs.push(`https://github.com/${author.social_links.github}`);
136
- const uniqueSameAs = [...new Set(sameAs.filter(Boolean))];
137
- const schema = {
138
- "@context": "https://schema.org",
139
- "@type": "Person",
140
- name: author.name,
141
- url: author.author_page_url || `${siteUrl}/blog/author/${author.slug}`
142
- };
143
- if (author.title) schema.jobTitle = author.title;
144
- if (author.company || siteName) {
145
- schema.worksFor = {
146
- "@type": "Organization",
147
- name: author.company || siteName,
148
- ...siteUrl ? { url: siteUrl } : {}
149
- };
150
- }
151
- if (author.bio || author.short_bio) schema.description = author.short_bio || author.bio;
152
- if (author.avatar_url) schema.image = author.avatar_url;
153
- if (uniqueSameAs.length > 0) schema.sameAs = uniqueSameAs;
154
- if (author.knows_about && author.knows_about.length > 0) schema.knowsAbout = author.knows_about;
155
- if (author.credentials && author.credentials.length > 0) {
156
- schema.hasCredential = author.credentials.map((c) => ({
157
- "@type": "EducationalOccupationalCredential",
158
- credentialCategory: c
159
- }));
160
- }
161
- return schema;
162
- }
163
-
164
- exports.blogArtworkImageStyle = blogArtworkImageStyle;
165
- exports.blogCategorySlug = blogCategorySlug;
166
- exports.createBlogRoutes = createBlogRoutes;
167
- exports.fetchBlogCategories = fetchBlogCategories;
168
- exports.fetchBlogPostBySlug = fetchBlogPostBySlug;
169
- exports.fetchRelatedBlogPosts = fetchRelatedBlogPosts;
170
- exports.generateAuthorSchema = generateAuthorSchema;
171
- exports.resolveBlogArtwork = resolveBlogArtwork;
172
- exports.resolveBlogPostUrl = resolveBlogPostUrl;
173
- exports.resolveBlogUrl = resolveBlogUrl;
174
- //# sourceMappingURL=chunk-FHPW7XVH.js.map
175
- //# sourceMappingURL=chunk-FHPW7XVH.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/blog/public-reads.ts","../src/blog/artwork.ts","../src/blog/routes.ts","../src/blog/author-schema.ts"],"names":["withSiteParam","withSiteBody"],"mappings":"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","file":"chunk-FHPW7XVH.js","sourcesContent":["/**\n * @sonordev/site-kit/blog — shared public blog reads (leaf module)\n *\n * SINGLE SOURCE OF TRUTH for the three blog reads that both `server-core`\n * (credentials from resolveServerApiConfig) and the server-ui components\n * (credentials from their `apiUrl` / `apiKey` props) make:\n *\n * - post by slug — getBlogPost, <BlogPost>\n * - categories — getBlogCategories, <BlogList>, <BlogSidebar>\n * - related posts — getRelatedInsights, <BlogPost>, <RelatedPosts>\n *\n * Each used to be copied into every caller, which is how one copy of the\n * related read kept a camelCase body and a wrong path long after the others\n * were fixed (see the notes in RelatedPosts). Adding the multi-site `site`\n * dimension would have meant a fourth edit to each copy, so they live here now.\n *\n * A leaf on purpose: it takes credentials as arguments and imports no\n * `server-only` code, because the client-stamped `blog` barrel reaches it\n * through BlogList / BlogPost / BlogSidebar. Callers resolve credentials; this\n * module only talks to the API.\n */\nimport { withSiteBody, withSiteParam } from '../sites/site-param'\nimport type { BlogCategory, BlogPost } from './types'\n\nexport interface BlogReadConfig {\n apiUrl: string\n apiKey: string\n /** Sub-site host override. Omit to resolve from NEXT_PUBLIC_SITE_URL. */\n site?: string\n}\n\n/** GET /public/blog/posts/:slug — null when missing or on any failure. */\nexport async function fetchBlogPostBySlug(\n { apiUrl, apiKey, site }: BlogReadConfig,\n slug: string\n): Promise<BlogPost | null> {\n try {\n const response = await fetch(withSiteParam(`${apiUrl}/public/blog/posts/${slug}`, site), {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 60 },\n })\n if (!response.ok) {\n if (response.status !== 404) console.error('[Blog] Failed to fetch post:', response.statusText)\n return null\n }\n const data = await response.json()\n return data.post || null\n } catch (error) {\n console.error('[Blog] Error fetching post:', error)\n return null\n }\n}\n\n/** GET /public/blog/categories — [] on any failure. */\nexport async function fetchBlogCategories({ apiUrl, apiKey, site }: BlogReadConfig): Promise<BlogCategory[]> {\n try {\n const response = await fetch(withSiteParam(`${apiUrl}/public/blog/categories`, site), {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 300 },\n })\n if (!response.ok) return []\n const data = await response.json()\n return data.categories || []\n } catch (error) {\n console.error('[Blog] Error fetching categories:', error)\n return []\n }\n}\n\n/**\n * POST /public/blog/related — [] on any failure.\n *\n * `/public/blog/*`, not `/api/public/blog/*`: public-blog.controller is one of\n * only two public controllers whose @Controller() omits the `api/` segment.\n * The body is snake_case `current_post_id` (the controller looks the post up\n * by id — there is no slug path), and `site` rides in the body because this is\n * the one blog read that isn't a GET.\n *\n * `revalidate` is optional so <RelatedPosts>, which never set a fetch cache\n * lifetime, keeps rendering exactly as it did.\n */\nexport async function fetchRelatedBlogPosts(\n { apiUrl, apiKey, site }: BlogReadConfig,\n currentPostId: string,\n limit: number,\n cache: { revalidate?: number } = {}\n): Promise<BlogPost[]> {\n try {\n const response = await fetch(`${apiUrl}/public/blog/related`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey },\n body: JSON.stringify(withSiteBody({ current_post_id: currentPostId, limit }, site)),\n ...(cache.revalidate !== undefined ? { next: { revalidate: cache.revalidate } } : {}),\n })\n if (!response.ok) {\n console.error('[Blog] Failed to fetch related posts:', response.statusText)\n return []\n }\n const data = await response.json()\n return data.posts || []\n } catch (error) {\n console.error('[Blog] Error fetching related posts:', error)\n return []\n }\n}\n","import type { CSSProperties } from 'react'\nimport type { BlogPost } from './types'\n\nexport interface BlogArtwork {\n src: string | undefined\n alt: string\n composed: boolean\n}\n\ntype ArtworkSource = Pick<BlogPost, 'title' | 'featured_image' | 'featured_image_alt' | 'editorial_image' | 'editorial_image_alt'>\n\n/** Single source of truth for article artwork versus complete promotional cards. */\nexport function resolveBlogArtwork(post: ArtworkSource, placement: 'article' | 'card' = 'card'): BlogArtwork {\n const editorial = placement === 'article' && !!post.editorial_image\n const src = (editorial ? post.editorial_image : post.featured_image) || undefined\n const alt = editorial\n ? post.editorial_image_alt ?? ''\n : post.featured_image_alt ?? post.title ?? ''\n let composed = false\n if (src) {\n try {\n // Inspect the path, not a query string that happens to mention a card.\n composed = /\\/Blog\\/Cards\\//i.test(new URL(src, 'https://site-kit.invalid').pathname)\n } catch { /* An unrecognized source retains the normal photograph layout. */ }\n }\n return { src, alt, composed }\n}\n\n/** Preserve generated text and graphics across every stock card surface. */\nexport function blogArtworkImageStyle(artwork: BlogArtwork): CSSProperties | undefined {\n return artwork.composed\n ? { display: 'block', height: 'auto', maxHeight: 'none', objectFit: 'contain', transform: 'none' }\n : undefined\n}\n","/** Shared, environment-free publication routes for server helpers and blog UI. */\nexport interface BlogRoutePost {\n slug: string\n category?: string | { slug?: string; name?: string } | null\n canonical_url?: string | null\n}\n\nexport interface BlogRoutingOptions {\n /** Publication root. Defaults to /blog. */\n basePath?: string\n /** Existing metadata option; basePath takes precedence when both are set. */\n blogBasePath?: string\n /** Use /publication/category/post instead of /publication/post. */\n includeCategoryInPath?: boolean\n /** Fallback category for partial cluster records. */\n category?: string\n /** A custom local article path. Receives the post's slug and category. */\n postPath?: (post: BlogRoutePost) => string\n /** A custom category destination, for example /theforge?category=guides. */\n categoryPath?: (slug: string) => string\n}\n\nexport function blogCategorySlug(category: BlogRoutePost['category']): string {\n const value = typeof category === 'string' ? category : category?.slug || category?.name || ''\n return value.trim().toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '')\n}\n\nfunction localPath(path: string): string {\n const value = path.trim()\n if (!value || /^[a-z][a-z\\d+.-]*:/i.test(value) || value.startsWith('//') || value.includes('\\\\')) {\n throw new Error('Blog routes must be local paths, such as /theforge/guides/story.')\n }\n return value.startsWith('/') ? value : `/${value}`\n}\n\n/** Single source of truth for publication paths. Custom routes never change OG artwork. */\nexport function createBlogRoutes(options: BlogRoutingOptions = {}) {\n const raw = (options.basePath ?? options.blogBasePath ?? '/blog').trim() || '/blog'\n const index = localPath(raw).replace(/\\/+$/, '') || '/'\n const prefix = index === '/' ? '' : index\n return {\n index,\n post(post: BlogRoutePost): string {\n if (options.postPath) return localPath(options.postPath(post))\n const category = blogCategorySlug(post.category || options.category)\n return `${prefix}${options.includeCategoryInPath && category ? `/${encodeURIComponent(category)}` : ''}/${encodeURIComponent(post.slug)}`\n },\n category(slug: string): string {\n const normalized = blogCategorySlug(slug)\n return options.categoryPath\n ? localPath(options.categoryPath(normalized))\n : `${prefix}/category/${encodeURIComponent(normalized)}`\n },\n cluster: (slug: string) => `${prefix}/cluster/${encodeURIComponent(slug)}`,\n author: (slug: string) => `${prefix}/author/${encodeURIComponent(slug)}`,\n rss: `${prefix}/rss.xml`,\n atom: `${prefix}/feed.xml`,\n }\n}\n\nexport function resolveBlogUrl(path: string, siteUrl = ''): string {\n return `${siteUrl.replace(/\\/+$/, '')}${localPath(path)}`\n}\n\n/** Metadata, feeds, sitemaps and generated schemas agree on a supplied canonical. */\nexport function resolveBlogPostUrl(post: BlogRoutePost, options: BlogRoutingOptions & { siteUrl?: string } = {}): string {\n const canonical = post.canonical_url?.trim()\n if (canonical) {\n if (/^https?:\\/\\//i.test(canonical)) {\n try { return new URL(canonical).toString() } catch { /* use the local route */ }\n } else if (canonical.startsWith('/') && !canonical.startsWith('//') && !canonical.includes('\\\\')) {\n return resolveBlogUrl(canonical, options.siteUrl)\n }\n }\n return resolveBlogUrl(createBlogRoutes(options).post(post), options.siteUrl)\n}\n","/**\n * @sonordev/site-kit/blog — Author JSON-LD (pure)\n *\n * Split out of `./server-core` on purpose. `generateAuthorSchema` is a pure\n * function — it maps a `BlogAuthor` to a Person schema object and touches no\n * env, no config, and no network. It only ever lived in `server-core` because\n * the other author helpers there (`getAuthorBySlug`, `getAuthorPosts`) do fetch.\n *\n * `AuthorPage` is exported from the client-stamped `@sonordev/site-kit/blog`\n * barrel (see `./index.ts`), so importing this one function from `server-core`\n * dragged that whole server module — its `x-api-key` fetches included — into\n * the browser bundle. Keeping the pure half here means `AuthorPage` can stay in\n * the barrel without pulling a single line of server code with it.\n *\n * Anything added here must stay pure. If it needs an API key or a fetch, it\n * belongs in `./server-core`, not in this file.\n */\n\nimport type { BlogAuthor } from './types'\n\n/**\n * Generate Person JSON-LD schema for an author page\n */\nexport function generateAuthorSchema(\n author: BlogAuthor,\n options: { siteUrl?: string; siteName?: string } = {}\n): object {\n const { siteUrl = '', siteName } = options\n\n const sameAs: string[] = [...(author.same_as || [])]\n if (author.linkedin_url) sameAs.push(author.linkedin_url)\n if (author.twitter_url) sameAs.push(author.twitter_url)\n if (author.website_url) sameAs.push(author.website_url)\n if (author.social_links?.twitter) sameAs.push(`https://twitter.com/${author.social_links.twitter}`)\n if (author.social_links?.linkedin) sameAs.push(author.social_links.linkedin)\n if (author.social_links?.github) sameAs.push(`https://github.com/${author.social_links.github}`)\n\n // Deduplicate\n const uniqueSameAs = [...new Set(sameAs.filter(Boolean))]\n\n const schema: Record<string, any> = {\n '@context': 'https://schema.org',\n '@type': 'Person',\n name: author.name,\n url: author.author_page_url || `${siteUrl}/blog/author/${author.slug}`,\n }\n\n if (author.title) schema.jobTitle = author.title\n if (author.company || siteName) {\n schema.worksFor = {\n '@type': 'Organization',\n name: author.company || siteName,\n ...(siteUrl ? { url: siteUrl } : {}),\n }\n }\n if (author.bio || author.short_bio) schema.description = author.short_bio || author.bio\n if (author.avatar_url) schema.image = author.avatar_url\n if (uniqueSameAs.length > 0) schema.sameAs = uniqueSameAs\n if (author.knows_about && author.knows_about.length > 0) schema.knowsAbout = author.knows_about\n if (author.credentials && author.credentials.length > 0) {\n schema.hasCredential = author.credentials.map((c) => ({\n '@type': 'EducationalOccupationalCredential',\n credentialCategory: c,\n }))\n }\n\n return schema\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/search/contract.ts"],"names":[],"mappings":";;;AAmBO,IAAM,eAAA,GAAkB;AAkCxB,IAAM,uBAAA,GAA0B;AAAA,EACrC;AAAA,IACE,IAAA,EAAM,iBAAA;AAAA,IACN,OAAA,EAAS,EAAE,CAAA,EAAG,SAAA;AAAU,GAC1B;AAAA,EACA;AAAA,IACE,IAAA,EAAM,kBAAA;AAAA,IACN,OAAA,EAAS,EAAE,CAAA,EAAG,aAAA,EAAe,IAAA,EAAM,eAAA,EAAiB,KAAA,EAAO,CAAC,MAAA,EAAQ,MAAM,CAAA,EAAG,KAAA,EAAO,CAAA;AAAE;AAE1F","file":"chunk-G2WC3CXW.js","sourcesContent":["/**\n * @sonordev/site-kit/search/contract — site search wire contract.\n *\n * CANONICAL SOURCE for the shape of POST /api/public/search. sonor-api keeps\n * an inline mirror per the cross-repo contract pattern (APIs do not depend on\n * site-kit at runtime); drift is caught by test vectors on both sides.\n *\n * Design notes (4.0 exploration):\n * - One endpoint, unified across content types the project already manages:\n * pages (seo_pages), blog posts, and commerce offerings. The site's whole\n * navigable surface, ranked together.\n * - Tenant scoping comes from the API key (ApiKeyGuard) — requests carry no\n * project id, same as every public endpoint.\n * - `site` narrows multi-site projects (TPS microsites) using the standard\n * host convention from sites/contract.\n * - Results carry a `url` the site can link directly plus a typed `kind`\n * so UIs can group (\"Pages / Posts / Events\").\n */\n\nexport const SEARCH_ENDPOINT = '/api/public/search'\n\nexport type SearchKind = 'page' | 'post' | 'offering'\n\nexport interface SearchRequest {\n /** The user's query. Server trims; empty queries return empty results. */\n q: string\n /** Multi-site narrowing (normalized host, e.g. 'ohiopowerstudies.com'). */\n site?: string\n /** Restrict to specific kinds. Default: all. */\n kinds?: SearchKind[]\n /** Max results across kinds. Server clamps to 25. Default 10. */\n limit?: number\n}\n\nexport interface SearchResult {\n kind: SearchKind\n /** Path or absolute URL the site should link to. */\n url: string\n title: string\n /** Short excerpt with the match context when the backend can produce one. */\n excerpt?: string\n /** Higher = better. Only comparable within a single response. */\n score: number\n}\n\nexport interface SearchResponse {\n query: string\n results: SearchResult[]\n /** Total matches before the limit, per kind — lets UIs show \"12 more posts\". */\n totals?: Partial<Record<SearchKind, number>>\n}\n\n/** Shared test vectors — mirrored by sonor-api's contract test. */\nexport const SEARCH_CONTRACT_VECTORS = [\n {\n name: 'minimal request',\n request: { q: 'bonfire' } satisfies SearchRequest,\n },\n {\n name: 'narrowed request',\n request: { q: 'supply list', site: 'ludlowpto.org', kinds: ['page', 'post'], limit: 5 } satisfies SearchRequest,\n },\n] as const\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/blog/blog-tables.ts"],"names":["frame"],"mappings":"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","file":"chunk-GHECYDSZ.mjs","sourcesContent":["/**\n * Server-rendered table scrolling. Keep the author's table markup intact so\n * captions, header associations, links and table semantics survive unchanged.\n */\n\nconst tableScrollClass = 'sk-blog-table-scroll'\nconst voidElements = new Set([\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta',\n 'param', 'source', 'track', 'wbr',\n])\nconst preservedElements = new Set(['pre', 'code', 'script', 'style', 'textarea', 'xmp', 'template'])\n\n/** Match complete tags, including quoted `>` characters, without reserializing HTML. */\nfunction htmlTags(): RegExp {\n return /<!--[\\s\\S]*?(?:-->|$)|<\\/?[a-z][\\w:-]*(?=[\\s/>])(?:[^\"'<>]|\"[^\"]*\"|'[^']*')*>/gi\n}\n\nfunction hasScrollClass(tag: string): boolean {\n const attributes = tag.replace(/^<[\\w:-]+/, '').replace(/\\/?>$/, '')\n const pattern = /([^\\s=/>]+)(?:\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\s\"'=<>`]+)))?/g\n for (const attribute of attributes.matchAll(pattern)) {\n if (attribute[1].toLowerCase() !== 'class') continue\n return (attribute[2] ?? attribute[3] ?? attribute[4] ?? '').split(/\\s+/).includes(tableScrollClass)\n }\n return false\n}\n\nfunction labelText(html: string): string {\n // Preserve existing character references in the eventual attribute. Escaping\n // them a second time would announce \"amp\" instead of the author's text.\n return html\n .replace(/<!--[\\s\\S]*?(?:-->|$)/g, '')\n .replace(htmlTags(), ' ')\n .replace(/\\s+/g, ' ')\n .trim()\n}\n\nfunction escapeLabel(text: string): string {\n return text\n .replace(/&(?!(?:#\\d+|#x[\\da-f]+|[a-z][\\da-z]+);)/gi, '&amp;')\n .replace(/\"/g, '&quot;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n}\n\nfunction tableLabel(table: string, number: number): string {\n const caption = table.match(/<caption\\b(?:[^\"'<>]|\"[^\"]*\"|'[^']*')*>([\\s\\S]*?)<\\/caption\\s*>/i)?.[1]\n const headers = [...table.matchAll(/<th\\b(?:[^\"'<>]|\"[^\"]*\"|'[^']*')*>([\\s\\S]*?)<\\/th\\s*>/gi)]\n .slice(0, 4)\n .map((match) => labelText(match[1]))\n .filter(Boolean)\n .join(', ')\n const summary = labelText(caption || headers).slice(0, 180)\n return escapeLabel(`Table ${number}${summary ? `: ${summary}` : ''}`)\n}\n\ninterface ElementFrame {\n tag: string\n scrollRegion: boolean\n table?: { start: number; number: number }\n}\n\n/**\n * Single source of truth for default blog table wrappers. Safe to call twice;\n * already wrapped tables and HTML examples are left alone. This is a layout\n * transform, not an HTML sanitizer: content still follows the host's trust policy.\n */\nexport function wrapBlogTables(html: string): string {\n const tags = htmlTags()\n const stack: ElementFrame[] = []\n const tables: Array<{ start: number; end: number; number: number }> = []\n let tableNumber = 0\n let token: RegExpExecArray | null\n\n while ((token = tags.exec(html))) {\n const tag = token[0]\n if (tag.startsWith('<!--')) continue\n const tagName = /^<\\/?([\\w:-]+)/.exec(tag)![1].toLowerCase()\n\n if (tag.startsWith('</')) {\n const index = stack.map((frame) => frame.tag).lastIndexOf(tagName)\n if (index < 0) continue\n const frame = stack[index]\n if (frame.table) tables.push({ ...frame.table, end: tags.lastIndex })\n stack.length = index\n continue\n }\n\n if (preservedElements.has(tagName)) {\n // Code examples and raw text can contain literal HTML. Skip to the end\n // without interpreting any of those tags as article content.\n const closingTag = new RegExp(`</${tagName}\\\\s*>`, 'gi')\n closingTag.lastIndex = tags.lastIndex\n if (!closingTag.exec(html)) break\n tags.lastIndex = closingTag.lastIndex\n continue\n }\n\n if (voidElements.has(tagName) || /\\/\\s*>$/.test(tag)) continue\n const frame: ElementFrame = { tag: tagName, scrollRegion: hasScrollClass(tag) }\n if (tagName === 'table' && !stack.some((ancestor) => ancestor.tag === 'table')) {\n tableNumber += 1\n if (!stack.some((ancestor) => ancestor.scrollRegion)) {\n frame.table = { start: token.index, number: tableNumber }\n }\n }\n stack.push(frame)\n }\n\n let output = ''\n let cursor = 0\n for (const { start, end, number } of tables) {\n const table = html.slice(start, end)\n output += `${html.slice(cursor, start)}<div class=\"${tableScrollClass}\" role=\"region\" tabindex=\"0\" aria-label=\"${tableLabel(table, number)}\">${table}</div>`\n cursor = end\n }\n return output + html.slice(cursor)\n}\n\n/** Native overflow only when content needs it; small tables retain their layout. */\nexport const blogTableCss = /* css */ `\n.sk-blog-content .sk-blog-table-scroll {\n box-sizing: border-box;\n min-width: 0;\n max-width: 100%;\n overflow-x: auto;\n margin: 1.5em 0;\n border: 1px solid var(--sk-surface-border, #e2e8f0);\n border-radius: var(--sk-radius, 0.5rem);\n background: var(--sk-bg-elevated, #f8fafc);\n scrollbar-width: thin;\n scrollbar-color: var(--sk-primary, #2563eb) var(--sk-bg-elevated, #f8fafc);\n overscroll-behavior-x: contain;\n}\n.sk-blog-content .sk-blog-table-scroll:focus-visible {\n outline: 2px solid var(--sk-border-focus, var(--sk-primary, #2563eb));\n outline-offset: 3px;\n}\n.sk-blog-content .sk-blog-table-scroll::-webkit-scrollbar { height: 10px; }\n.sk-blog-content .sk-blog-table-scroll::-webkit-scrollbar-track {\n background: var(--sk-bg-elevated, #f8fafc);\n border-radius: var(--sk-radius, 0.5rem);\n}\n.sk-blog-content .sk-blog-table-scroll::-webkit-scrollbar-thumb {\n background: var(--sk-primary, #2563eb);\n background-clip: padding-box;\n border: 2px solid var(--sk-bg-elevated, #f8fafc);\n border-radius: var(--sk-radius, 0.5rem);\n}\n.sk-blog-content .sk-blog-table-scroll > table {\n display: table;\n margin: 0;\n overflow: visible;\n}\n.sk-blog-content .sk-blog-table-scroll caption {\n padding: 0.625rem 0.875rem;\n text-align: start;\n color: var(--sk-text-secondary, #475569);\n}\n`.trim()\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/blog/BlogFAQ.tsx"],"names":["jsxs","jsx","useRef","useState","useCallback"],"mappings":"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","file":"chunk-GQF6QAQS.js","sourcesContent":["/**\n * @sonordev/site-kit/blog - Blog FAQ Component\n *\n * Renders FAQ items with collapsible accordion behavior.\n * Content is always in the DOM (not display:none) for SEO crawlability.\n * Uses CSS max-height transitions — no JS animation library required.\n *\n * Pairs with FAQPage schema (generated by Signal AI in the blog pipeline)\n * for Google's \"People Also Ask\" featured snippets.\n *\n * @example\n * ```tsx\n * <BlogFAQ items={post.faqItems} />\n * ```\n */\n\n'use client'\n\nimport React, { useState, useRef, useCallback } from 'react'\n\nexport interface FaqItem {\n question: string\n answer: string\n}\n\nexport interface BlogFAQProps {\n items: FaqItem[]\n /** Section title */\n title?: string\n /** Allow multiple items open simultaneously */\n allowMultiple?: boolean\n /** Override styles with Tailwind classes */\n styles?: {\n section?: string\n title?: string\n list?: string\n item?: string\n question?: string\n questionText?: string\n icon?: string\n answer?: string\n answerInner?: string\n }\n unstyled?: boolean\n}\n\n// CSS custom property defaults\nconst defaultStyles = {\n section: {\n margin: '3rem 0',\n padding: 0,\n },\n title: {\n fontSize: '1.5rem',\n fontWeight: 700,\n color: 'var(--sk-text-primary, #0f172a)',\n marginBottom: '1.5rem',\n display: 'flex',\n alignItems: 'center',\n gap: '0.5rem',\n },\n list: {\n listStyle: 'none',\n margin: 0,\n padding: 0,\n display: 'flex',\n flexDirection: 'column' as const,\n gap: '0.5rem',\n },\n item: {\n borderRadius: '0.75rem',\n border: '1px solid var(--sk-surface-border, #e2e8f0)',\n background: 'var(--sk-bg-elevated, #f8fafc)',\n overflow: 'hidden',\n transition: 'border-color 0.2s, box-shadow 0.2s',\n },\n itemOpen: {\n borderColor: 'color-mix(in srgb, var(--sk-primary, #2563eb) 40%, var(--sk-surface-border, #e2e8f0))',\n boxShadow: '0 1px 3px rgba(0,0,0,0.06)',\n },\n question: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n width: '100%',\n padding: '1rem 1.25rem',\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n textAlign: 'left' as const,\n },\n questionText: {\n fontSize: '1rem',\n fontWeight: 600,\n color: 'var(--sk-text-primary, #0f172a)',\n paddingRight: '1rem',\n },\n icon: {\n flexShrink: 0,\n width: '1.25rem',\n height: '1.25rem',\n color: 'var(--sk-primary, #2563eb)',\n transition: 'transform 0.2s',\n },\n answer: {\n overflow: 'hidden',\n transition: 'max-height 0.3s ease, opacity 0.2s ease',\n },\n answerInner: {\n padding: '0 1.25rem 1.25rem',\n fontSize: '0.9375rem',\n lineHeight: 1.7,\n color: 'var(--sk-text-secondary, #475569)',\n },\n}\n\nfunction PlusMinusIcon({ isOpen }: { isOpen: boolean }) {\n return (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n style={{\n ...defaultStyles.icon,\n transform: isOpen ? 'rotate(45deg)' : 'rotate(0deg)',\n }}\n >\n <line x1=\"10\" y1=\"4\" x2=\"10\" y2=\"16\" />\n <line x1=\"4\" y1=\"10\" x2=\"16\" y2=\"10\" />\n </svg>\n )\n}\n\nfunction FAQItem({\n item,\n isOpen,\n onToggle,\n styles,\n unstyled,\n}: {\n item: FaqItem\n isOpen: boolean\n onToggle: () => void\n styles?: BlogFAQProps['styles']\n unstyled?: boolean\n}) {\n const answerRef = useRef<HTMLDivElement>(null)\n\n return (\n <li\n className={styles?.item}\n style={unstyled ? undefined : {\n ...defaultStyles.item,\n ...(isOpen ? defaultStyles.itemOpen : {}),\n }}\n >\n <button\n className={styles?.question}\n style={unstyled ? undefined : defaultStyles.question}\n onClick={onToggle}\n aria-expanded={isOpen}\n type=\"button\"\n >\n <span\n className={styles?.questionText}\n style={unstyled ? undefined : defaultStyles.questionText}\n >\n {item.question}\n </span>\n <span className={styles?.icon}>\n <PlusMinusIcon isOpen={isOpen} />\n </span>\n </button>\n <div\n ref={answerRef}\n className={styles?.answer}\n style={unstyled ? undefined : {\n ...defaultStyles.answer,\n maxHeight: isOpen ? `${(answerRef.current?.scrollHeight || 500) + 40}px` : '0',\n opacity: isOpen ? 1 : 0,\n }}\n role=\"region\"\n aria-hidden={!isOpen}\n >\n <div\n className={styles?.answerInner}\n style={unstyled ? undefined : defaultStyles.answerInner}\n dangerouslySetInnerHTML={{ __html: item.answer }}\n />\n </div>\n </li>\n )\n}\n\nexport function BlogFAQ({\n items,\n title = 'Frequently Asked Questions',\n allowMultiple = false,\n styles,\n unstyled = false,\n}: BlogFAQProps) {\n const [openIndices, setOpenIndices] = useState<Set<number>>(new Set())\n\n const toggle = useCallback((index: number) => {\n setOpenIndices(prev => {\n const next = new Set(allowMultiple ? prev : [])\n if (prev.has(index)) {\n next.delete(index)\n } else {\n next.add(index)\n }\n return next\n })\n }, [allowMultiple])\n\n if (!items || items.length === 0) return null\n\n return (\n <section\n className={styles?.section}\n style={unstyled ? undefined : defaultStyles.section}\n aria-label=\"Frequently Asked Questions\"\n >\n <h2\n className={styles?.title}\n style={unstyled ? undefined : defaultStyles.title}\n >\n {title}\n </h2>\n <ul\n className={styles?.list}\n style={unstyled ? undefined : defaultStyles.list}\n >\n {items.map((item, index) => (\n <FAQItem\n key={index}\n item={item}\n isOpen={openIndices.has(index)}\n onToggle={() => toggle(index)}\n styles={styles}\n unstyled={unstyled}\n />\n ))}\n </ul>\n </section>\n )\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/sites/resolve.ts"],"names":["normalizeSiteHost"],"mappings":";;;;;AAkCO,SAAS,gBAAgB,YAAA,EAA+B;AAC7D,EAAA,MAAM,aACJ,OAAO,OAAA,KAAY,WAAA,GAAc,OAAA,CAAQ,IAAI,oBAAA,GAAuB,MAAA;AAEtE,EAAA,IAAI,WAAW,YAAA,IAAgB,EAAA;AAC/B,EAAA,IAAI,CAAC,YAAY,UAAA,EAAY;AAC3B,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,IAAI,GAAA,CAAI,UAAU,CAAA,CAAE,IAAA;AAAA,IACjC,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AACA,EAAA,IAAI,CAAC,QAAA,IAAY,OAAO,MAAA,KAAW,WAAA,EAAa;AAC9C,IAAA,QAAA,GAAW,OAAO,QAAA,CAAS,IAAA;AAAA,EAC7B;AACA,EAAA,OAAOA,kCAAA,CAAkB,QAAQ,CAAA,IAAK,EAAA;AACxC","file":"chunk-H5NBFNND.js","sourcesContent":["/**\n * @sonordev/site-kit/sites — resolveSiteHost (leaf module)\n *\n * SINGLE SOURCE OF TRUTH for \"which sub-site am I?\" — the multi-site `site`\n * dimension that lets one Sonor project host many domains (bd-aec.com plus 48\n * sibling domains; truepowersystems.com plus 16 state microsites).\n *\n * Precedence, per the platform site contract:\n * explicit `site` > NEXT_PUBLIC_SITE_URL host > window.location.host\n *\n * Deliberately usable on BOTH sides. The browser half seeds\n * `window.__SITE_KIT_SITE__` (see `shared/publishCredential`); the build half\n * tags the sitemap sync, the llms.txt reads and every blog read (see\n * `sitemap/index`, `llms/writeLLMsTxt`, and `./site-param`, which appends the\n * host to API requests) so a build describes only its OWN host. Server-side the\n * `window` branch simply never fires, which leaves the NEXT_PUBLIC_SITE_URL\n * host — the right source at build time.\n *\n * Do not re-fork this. Before it existed the build path sent no `site` at all,\n * so every site in a 49-domain network read whichever sibling's seo_pages row\n * the database happened to hand back for a shared path like `/` — bd-aec.com\n * shipped soqwriters.com's homepage copy in its llms.txt.\n *\n * Its own file, not `./contract`, for the same bundle reason as\n * `./normalize`: browser entries import this without dragging the contract's\n * JSON schema along.\n */\nimport { normalizeSiteHost } from './normalize'\n\n/**\n * Resolve the sub-site host. Always returns a string (possibly empty), already\n * normalized with the shared contract (lowercase host, no protocol/path/port)\n * so it matches exactly what the Sonor API stores.\n */\nexport function resolveSiteHost(explicitSite?: string): string {\n const envSiteUrl =\n typeof process !== 'undefined' ? process.env.NEXT_PUBLIC_SITE_URL : undefined\n\n let resolved = explicitSite ?? ''\n if (!resolved && envSiteUrl) {\n try {\n resolved = new URL(envSiteUrl).host\n } catch {\n /* malformed URL — fall through to client-side host */\n }\n }\n if (!resolved && typeof window !== 'undefined') {\n resolved = window.location.host\n }\n return normalizeSiteHost(resolved) ?? ''\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/blog/widget-styles.ts"],"names":[],"mappings":";;;AAOO,IAAM,WAAA,GAAmC;AAAA,EAC9C,OAAA,EAAS,EAAA;AAAA,EACT,eAAA,EAAiB,uBAAA;AAAA,EACjB,YAAA,EAAc;AAChB;AAEO,IAAM,gBAAA,GAAwC;AAAA,EACnD,MAAA,EAAQ,UAAA;AAAA,EACR,QAAA,EAAU,EAAA;AAAA,EACV,UAAA,EAAY,GAAA;AAAA,EACZ,KAAA,EAAO;AACT","file":"chunk-HX6ZG3PP.js","sourcesContent":["import type React from 'react'\n\n/**\n * Shared sidebar-widget chrome, extracted from BlogSidebar so the client-side\n * NewsletterWidget (its own module — it needs hooks, and BlogSidebar is also\n * bundled into the un-stamped server entry blog/server-ui) can reuse it.\n */\nexport const widgetStyle: React.CSSProperties = {\n padding: 20,\n backgroundColor: 'var(--sk-bg-elevated)',\n borderRadius: 12,\n}\n\nexport const widgetTitleStyle: React.CSSProperties = {\n margin: '0 0 16px',\n fontSize: 16,\n fontWeight: 600,\n color: 'var(--sk-text-primary)',\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/sites/resolve.ts"],"names":[],"mappings":";;;AAkCO,SAAS,gBAAgB,YAAA,EAA+B;AAC7D,EAAA,MAAM,aACJ,OAAO,OAAA,KAAY,WAAA,GAAc,OAAA,CAAQ,IAAI,oBAAA,GAAuB,MAAA;AAEtE,EAAA,IAAI,WAAW,YAAA,IAAgB,EAAA;AAC/B,EAAA,IAAI,CAAC,YAAY,UAAA,EAAY;AAC3B,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,IAAI,GAAA,CAAI,UAAU,CAAA,CAAE,IAAA;AAAA,IACjC,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AACA,EAAA,IAAI,CAAC,QAAA,IAAY,OAAO,MAAA,KAAW,WAAA,EAAa;AAC9C,IAAA,QAAA,GAAW,OAAO,QAAA,CAAS,IAAA;AAAA,EAC7B;AACA,EAAA,OAAO,iBAAA,CAAkB,QAAQ,CAAA,IAAK,EAAA;AACxC","file":"chunk-JLVCWC6A.mjs","sourcesContent":["/**\n * @sonordev/site-kit/sites — resolveSiteHost (leaf module)\n *\n * SINGLE SOURCE OF TRUTH for \"which sub-site am I?\" — the multi-site `site`\n * dimension that lets one Sonor project host many domains (bd-aec.com plus 48\n * sibling domains; truepowersystems.com plus 16 state microsites).\n *\n * Precedence, per the platform site contract:\n * explicit `site` > NEXT_PUBLIC_SITE_URL host > window.location.host\n *\n * Deliberately usable on BOTH sides. The browser half seeds\n * `window.__SITE_KIT_SITE__` (see `shared/publishCredential`); the build half\n * tags the sitemap sync, the llms.txt reads and every blog read (see\n * `sitemap/index`, `llms/writeLLMsTxt`, and `./site-param`, which appends the\n * host to API requests) so a build describes only its OWN host. Server-side the\n * `window` branch simply never fires, which leaves the NEXT_PUBLIC_SITE_URL\n * host — the right source at build time.\n *\n * Do not re-fork this. Before it existed the build path sent no `site` at all,\n * so every site in a 49-domain network read whichever sibling's seo_pages row\n * the database happened to hand back for a shared path like `/` — bd-aec.com\n * shipped soqwriters.com's homepage copy in its llms.txt.\n *\n * Its own file, not `./contract`, for the same bundle reason as\n * `./normalize`: browser entries import this without dragging the contract's\n * JSON schema along.\n */\nimport { normalizeSiteHost } from './normalize'\n\n/**\n * Resolve the sub-site host. Always returns a string (possibly empty), already\n * normalized with the shared contract (lowercase host, no protocol/path/port)\n * so it matches exactly what the Sonor API stores.\n */\nexport function resolveSiteHost(explicitSite?: string): string {\n const envSiteUrl =\n typeof process !== 'undefined' ? process.env.NEXT_PUBLIC_SITE_URL : undefined\n\n let resolved = explicitSite ?? ''\n if (!resolved && envSiteUrl) {\n try {\n resolved = new URL(envSiteUrl).host\n } catch {\n /* malformed URL — fall through to client-side host */\n }\n }\n if (!resolved && typeof window !== 'undefined') {\n resolved = window.location.host\n }\n return normalizeSiteHost(resolved) ?? ''\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/blog/processBlogHtml.ts"],"names":[],"mappings":";;;AAgBO,SAAS,uBAAuB,OAAA,EAAyB;AAC9D,EAAA,IAAI;AACF,IAAA,MAAM,OAAO,OAAA,CAAQ,UAAA,CAAW,MAAM,CAAA,GAAI,OAAA,GAAU,WAAW,OAAO,CAAA,CAAA;AACtE,IAAA,MAAM,CAAA,GAAI,IAAI,GAAA,CAAI,IAAI,CAAA;AACtB,IAAA,OAAO,EAAE,QAAA,CAAS,OAAA,CAAQ,SAAA,EAAW,EAAE,EAAE,WAAA,EAAY;AAAA,EACvD,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAA;AAAA,EACT;AACF;AAQO,IAAM,iBAAA,GAAoB;AAM1B,SAAS,mBAAmB,QAAA,EAA2B;AAC5D,EAAA,MAAM,QAAA,GAAW,UAAU,IAAA,EAAK;AAChC,EAAA,IAAI,UAAU,OAAO,QAAA;AACrB,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,GAAA,CAAI,oBAAA,EAAsB,IAAA,EAAK;AACpD,EAAA,IAAI,MAAM,OAAO,IAAA;AACjB,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,GAAA,CAAI,QAAA,EAAU,IAAA,EAAK;AACxC,EAAA,IAAI,MAAM,OAAO,IAAA;AACjB,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,GAAA,CAAI,UAAA,EAAY,IAAA,EAAK;AAC5C,EAAA,IAAI,MAAA,SAAe,MAAA,CAAO,UAAA,CAAW,MAAM,CAAA,GAAI,MAAA,GAAS,WAAW,MAAM,CAAA,CAAA;AACzE,EAAA,OAAO,EAAA;AACT;AAOO,SAAS,sBAAA,CAAuB,MAAc,OAAA,EAAyB;AAC5E,EAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,OAAA,EAAS,OAAO,IAAA;AAC9B,EAAA,MAAM,QAAA,GAAW,uBAAuB,OAAO,CAAA;AAC/C,EAAA,IAAI,CAAC,UAAU,OAAO,IAAA;AAEtB,EAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,gBAAA,EAAkB,CAAC,OAAO,KAAA,KAAkB;AAC9D,IAAA,MAAM,SAAA,GAAY,KAAA,CAAM,KAAA,CAAM,gCAAgC,CAAA;AAC9D,IAAA,IAAI,CAAC,SAAA,EAAW,OAAO,CAAA,EAAA,EAAK,KAAK,CAAA,CAAA,CAAA;AACjC,IAAA,MAAM,IAAA,GAAO,SAAA,CAAU,CAAC,CAAA,CAAE,IAAA,EAAK;AAC/B,IAAA,IAAI,CAAC,eAAA,CAAgB,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,KAAK,KAAK,CAAA,CAAA,CAAA;AAElD,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,IAAI,CAAA;AACxB,MAAA,MAAM,WAAW,GAAA,CAAI,QAAA,CAAS,QAAQ,SAAA,EAAW,EAAE,EAAE,WAAA,EAAY;AACjE,MAAA,IAAI,QAAA,KAAa,QAAA,EAAU,OAAO,CAAA,EAAA,EAAK,KAAK,CAAA,CAAA,CAAA;AAC5C,MAAA,IAAI,gBAAgB,IAAA,CAAK,KAAK,CAAA,EAAG,OAAO,KAAK,KAAK,CAAA,CAAA,CAAA;AAClD,MAAA,MAAM,OAAA,GAAU,MAAM,IAAA,EAAK;AAC3B,MAAA,OAAO,MAAM,OAAO,CAAA,2CAAA,CAAA;AAAA,IACtB,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,KAAK,KAAK,CAAA,CAAA,CAAA;AAAA,IACnB;AAAA,EACF,CAAC,CAAA;AACH","file":"chunk-K4TCEAUX.js","sourcesContent":["/**\n * Post-process Portal/blog HTML for safe, consistent link behavior.\n * Server-safe string transforms only (no DOM).\n */\n\n/**\n * The host `addExternalLinkTargets` compares links against to decide whether a\n * link is internal (same tab) or external (`target=\"_blank\"`). Lowercased,\n * leading `www.` stripped, so `www.example.com` and `example.com` count as the\n * same site; returns '' for anything unparseable.\n *\n * NOT the multi-site host normalizer. That is `normalizeSiteHost` in\n * `sites/normalize`, which keeps `www.` because `www.example.com` and\n * `example.com` can be different sub-sites of one Sonor project. This used to\n * share that name, so the two were easy to swap by accident.\n */\nexport function linkClassificationHost(siteUrl: string): string {\n try {\n const base = siteUrl.startsWith('http') ? siteUrl : `https://${siteUrl}`\n const u = new URL(base)\n return u.hostname.replace(/^www\\./i, '').toLowerCase()\n } catch {\n return ''\n }\n}\n\n/**\n * @deprecated Renamed to {@link linkClassificationHost} (same behavior: strips\n * `www.`). It shared a name with the multi-site `normalizeSiteHost` from\n * `sites/normalize`, which keeps `www.`. Kept so existing imports from\n * `@sonordev/site-kit/blog` still work.\n */\nexport const normalizeSiteHost = linkClassificationHost\n\n/**\n * Resolve canonical site URL for link classification.\n * Pass `explicit` from props when env vars are not set (e.g. non-Vercel hosts).\n */\nexport function resolveBlogSiteUrl(explicit?: string): string {\n const fromProp = explicit?.trim()\n if (fromProp) return fromProp\n const next = process.env.NEXT_PUBLIC_SITE_URL?.trim()\n if (next) return next\n const site = process.env.SITE_URL?.trim()\n if (site) return site\n const vercel = process.env.VERCEL_URL?.trim()\n if (vercel) return vercel.startsWith('http') ? vercel : `https://${vercel}`\n return ''\n}\n\n/**\n * Add `target=\"_blank\"` and `rel=\"noopener noreferrer\"` to external http(s) links.\n * Same registrable host (with or without `www`) is treated as internal.\n * Skips anchors that already set `target`.\n */\nexport function addExternalLinkTargets(html: string, siteUrl: string): string {\n if (!html || !siteUrl) return html\n const siteHost = linkClassificationHost(siteUrl)\n if (!siteHost) return html\n\n return html.replace(/<a\\b([^>]*)>/gi, (_full, attrs: string) => {\n const hrefMatch = attrs.match(/\\bhref\\s*=\\s*([\"'])([^\"']*)\\1/i)\n if (!hrefMatch) return `<a${attrs}>`\n const href = hrefMatch[2].trim()\n if (!/^https?:\\/\\//i.test(href)) return `<a${attrs}>`\n\n try {\n const url = new URL(href)\n const linkHost = url.hostname.replace(/^www\\./i, '').toLowerCase()\n if (linkHost === siteHost) return `<a${attrs}>`\n if (/\\btarget\\s*=/i.test(attrs)) return `<a${attrs}>`\n const trimmed = attrs.trim()\n return `<a ${trimmed} target=\"_blank\" rel=\"noopener noreferrer\">`\n } catch {\n return `<a${attrs}>`\n }\n })\n}\n"]}