@sonordev/site-kit 4.3.2 → 5.1.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 (296) hide show
  1. package/agent-manifest.json +8 -5
  2. package/dist/AnalyticsProvider-2LCSA6G3.mjs +10 -0
  3. package/dist/{AnalyticsProvider-TWRQHKPZ.mjs.map → AnalyticsProvider-2LCSA6G3.mjs.map} +1 -1
  4. package/dist/AnalyticsProvider-V2U3TQMH.js +31 -0
  5. package/dist/{AnalyticsProvider-DNMYYBKX.js.map → AnalyticsProvider-V2U3TQMH.js.map} +1 -1
  6. package/dist/BlogViewTracker-COTPD7WL.js +51 -0
  7. package/dist/BlogViewTracker-COTPD7WL.js.map +1 -0
  8. package/dist/BlogViewTracker-HG25ONRP.mjs +48 -0
  9. package/dist/BlogViewTracker-HG25ONRP.mjs.map +1 -0
  10. package/dist/ChatWidget-4QUJYFXU.js +20 -0
  11. package/dist/{ChatWidget-MDWEXISQ.js.map → ChatWidget-4QUJYFXU.js.map} +1 -1
  12. package/dist/ChatWidget-RWO7R7EJ.mjs +11 -0
  13. package/dist/{ChatWidget-UQMEJAHY.mjs.map → ChatWidget-RWO7R7EJ.mjs.map} +1 -1
  14. package/dist/EngageWidget-LF4AC4QN.mjs +9 -0
  15. package/dist/{EngageWidget-UIIN43ZU.mjs.map → EngageWidget-LF4AC4QN.mjs.map} +1 -1
  16. package/dist/EngageWidget-RSOXB3YM.js +18 -0
  17. package/dist/{EngageWidget-VRC7NUG6.js.map → EngageWidget-RSOXB3YM.js.map} +1 -1
  18. package/dist/{FileField-W4VXQ3CM.js → FileField-S2GUM3QB.js} +6 -6
  19. package/dist/{FileField-W4VXQ3CM.js.map → FileField-S2GUM3QB.js.map} +1 -1
  20. package/dist/{FileField-LVF3SCDC.mjs → FileField-YJ7DZXC3.mjs} +5 -5
  21. package/dist/{FileField-LVF3SCDC.mjs.map → FileField-YJ7DZXC3.mjs.map} +1 -1
  22. package/dist/{FormSpotlight-CRLFAPNI.js → FormSpotlight-7WAXLXZA.js} +15 -15
  23. package/dist/{FormSpotlight-CRLFAPNI.js.map → FormSpotlight-7WAXLXZA.js.map} +1 -1
  24. package/dist/{FormSpotlight-ZPISKGIX.mjs → FormSpotlight-HLH5LQKI.mjs} +3 -3
  25. package/dist/{FormSpotlight-ZPISKGIX.mjs.map → FormSpotlight-HLH5LQKI.mjs.map} +1 -1
  26. package/dist/{FormStage-QMRPAROJ.js → FormStage-LEZYERJB.js} +13 -13
  27. package/dist/{FormStage-QMRPAROJ.js.map → FormStage-LEZYERJB.js.map} +1 -1
  28. package/dist/{FormStage-WQOAP7CR.mjs → FormStage-Q5JW75AF.mjs} +3 -3
  29. package/dist/{FormStage-WQOAP7CR.mjs.map → FormStage-Q5JW75AF.mjs.map} +1 -1
  30. package/dist/ManagedForm-H4SEFSAF.js +23 -0
  31. package/dist/{ManagedForm-7L2W5BBZ.js.map → ManagedForm-H4SEFSAF.js.map} +1 -1
  32. package/dist/ManagedForm-U3NFIVEC.mjs +14 -0
  33. package/dist/{ManagedForm-D7CFOIXH.mjs.map → ManagedForm-U3NFIVEC.mjs.map} +1 -1
  34. package/dist/ManagedNewsletterForm-KT2NGUNW.js +64 -0
  35. package/dist/ManagedNewsletterForm-KT2NGUNW.js.map +1 -0
  36. package/dist/ManagedNewsletterForm-YKYW7B6P.mjs +62 -0
  37. package/dist/ManagedNewsletterForm-YKYW7B6P.mjs.map +1 -0
  38. package/dist/{SignalCore-JQLRWMPJ.mjs → SignalCore-2BH5PUGS.mjs} +5 -5
  39. package/dist/{SignalCore-JQLRWMPJ.mjs.map → SignalCore-2BH5PUGS.mjs.map} +1 -1
  40. package/dist/{SignalCore-DNXKQKRO.js → SignalCore-JM4ODFL2.js} +11 -11
  41. package/dist/{SignalCore-DNXKQKRO.js.map → SignalCore-JM4ODFL2.js.map} +1 -1
  42. package/dist/SitemapSync-5CXS2JGB.mjs +8 -0
  43. package/dist/{SitemapSync-RFY6PUG7.mjs.map → SitemapSync-5CXS2JGB.mjs.map} +1 -1
  44. package/dist/SitemapSync-J4UMJRTO.js +17 -0
  45. package/dist/{SitemapSync-SR6OJRIA.js.map → SitemapSync-J4UMJRTO.js.map} +1 -1
  46. package/dist/analytics/index.js +9 -9
  47. package/dist/analytics/index.mjs +4 -4
  48. package/dist/blog/AuthorCard.d.ts.map +1 -1
  49. package/dist/blog/AuthorPage.d.ts.map +1 -1
  50. package/dist/blog/BlogList.d.ts +7 -1
  51. package/dist/blog/BlogList.d.ts.map +1 -1
  52. package/dist/blog/BlogPost.d.ts +1 -1
  53. package/dist/blog/BlogPost.d.ts.map +1 -1
  54. package/dist/blog/BlogSidebar.d.ts +0 -7
  55. package/dist/blog/BlogSidebar.d.ts.map +1 -1
  56. package/dist/blog/BlogViewTracker.d.ts +10 -0
  57. package/dist/blog/BlogViewTracker.d.ts.map +1 -0
  58. package/dist/blog/ClusterLandingPage.d.ts.map +1 -1
  59. package/dist/blog/ManagedNewsletterForm.d.ts +13 -0
  60. package/dist/blog/ManagedNewsletterForm.d.ts.map +1 -0
  61. package/dist/blog/NewsletterShell.d.ts +18 -0
  62. package/dist/blog/NewsletterShell.d.ts.map +1 -0
  63. package/dist/blog/NewsletterWidget.d.ts +31 -0
  64. package/dist/blog/NewsletterWidget.d.ts.map +1 -0
  65. package/dist/blog/RelatedPosts.d.ts.map +1 -1
  66. package/dist/blog/author-social.d.ts +15 -0
  67. package/dist/blog/author-social.d.ts.map +1 -0
  68. package/dist/blog/author-social.test.d.ts +2 -0
  69. package/dist/blog/author-social.test.d.ts.map +1 -0
  70. package/dist/blog/blog-view-tracker.test.d.ts +2 -0
  71. package/dist/blog/blog-view-tracker.test.d.ts.map +1 -0
  72. package/dist/blog/category-metadata.test.d.ts +2 -0
  73. package/dist/blog/category-metadata.test.d.ts.map +1 -0
  74. package/dist/blog/index.d.ts +13 -7
  75. package/dist/blog/index.d.ts.map +1 -1
  76. package/dist/blog/index.js +94 -505
  77. package/dist/blog/index.js.map +1 -1
  78. package/dist/blog/index.mjs +59 -491
  79. package/dist/blog/index.mjs.map +1 -1
  80. package/dist/blog/newsletter-widget.test.d.ts +2 -0
  81. package/dist/blog/newsletter-widget.test.d.ts.map +1 -0
  82. package/dist/blog/reading-time.d.ts +10 -0
  83. package/dist/blog/reading-time.d.ts.map +1 -0
  84. package/dist/blog/reading-time.test.d.ts +2 -0
  85. package/dist/blog/reading-time.test.d.ts.map +1 -0
  86. package/dist/blog/server-core-contract.test.d.ts +2 -0
  87. package/dist/blog/server-core-contract.test.d.ts.map +1 -0
  88. package/dist/blog/server-core.d.ts +16 -4
  89. package/dist/blog/server-core.d.ts.map +1 -1
  90. package/dist/blog/server-ui.d.ts +5 -0
  91. package/dist/blog/server-ui.d.ts.map +1 -1
  92. package/dist/blog/server-ui.js +35 -10
  93. package/dist/blog/server-ui.js.map +1 -1
  94. package/dist/blog/server-ui.mjs +8 -6
  95. package/dist/blog/server-ui.mjs.map +1 -1
  96. package/dist/blog/server.d.ts +16 -4
  97. package/dist/blog/server.d.ts.map +1 -1
  98. package/dist/blog/server.js +40 -40
  99. package/dist/blog/server.mjs +1 -1
  100. package/dist/blog/tag-links.test.d.ts +2 -0
  101. package/dist/blog/tag-links.test.d.ts.map +1 -0
  102. package/dist/blog/types-wire-shape.test.d.ts +2 -0
  103. package/dist/blog/types-wire-shape.test.d.ts.map +1 -0
  104. package/dist/blog/types.d.ts +25 -19
  105. package/dist/blog/types.d.ts.map +1 -1
  106. package/dist/blog/widget-styles.d.ts +9 -0
  107. package/dist/blog/widget-styles.d.ts.map +1 -0
  108. package/dist/{chunk-I2IA3JXD.js → chunk-2EJX56YJ.js} +8 -8
  109. package/dist/{chunk-I2IA3JXD.js.map → chunk-2EJX56YJ.js.map} +1 -1
  110. package/dist/{chunk-NJ4YX3CI.mjs → chunk-2XHEUWHV.mjs} +4 -4
  111. package/dist/{chunk-NJ4YX3CI.mjs.map → chunk-2XHEUWHV.mjs.map} +1 -1
  112. package/dist/{chunk-RUOEUMAW.js → chunk-44ZTBQH4.js} +3 -3
  113. package/dist/{chunk-RUOEUMAW.js.map → chunk-44ZTBQH4.js.map} +1 -1
  114. package/dist/chunk-4SQ6PROR.mjs +6 -0
  115. package/dist/{chunk-NQNSATTA.mjs.map → chunk-4SQ6PROR.mjs.map} +1 -1
  116. package/dist/{chunk-D4KHH44S.mjs → chunk-4TU246Q4.mjs} +10 -3
  117. package/dist/chunk-4TU246Q4.mjs.map +1 -0
  118. package/dist/{chunk-BUF6IZUE.mjs → chunk-5G2ZRQMO.mjs} +3 -3
  119. package/dist/{chunk-BUF6IZUE.mjs.map → chunk-5G2ZRQMO.mjs.map} +1 -1
  120. package/dist/{chunk-A7OO6OPW.mjs → chunk-5W56B52Z.mjs} +3 -3
  121. package/dist/{chunk-A7OO6OPW.mjs.map → chunk-5W56B52Z.mjs.map} +1 -1
  122. package/dist/{chunk-LVM63JSA.mjs → chunk-6YKNDQYJ.mjs} +3 -3
  123. package/dist/{chunk-LVM63JSA.mjs.map → chunk-6YKNDQYJ.mjs.map} +1 -1
  124. package/dist/{chunk-JJS63TDR.mjs → chunk-A3VGZAZQ.mjs} +483 -21
  125. package/dist/chunk-A3VGZAZQ.mjs.map +1 -0
  126. package/dist/{chunk-YWBXKEAF.js → chunk-ACLBRIYD.js} +3 -3
  127. package/dist/{chunk-YWBXKEAF.js.map → chunk-ACLBRIYD.js.map} +1 -1
  128. package/dist/{chunk-OQTP5M5Y.js → chunk-ACWGG4VW.js} +9 -9
  129. package/dist/{chunk-OQTP5M5Y.js.map → chunk-ACWGG4VW.js.map} +1 -1
  130. package/dist/{chunk-NQEUFRMX.mjs → chunk-ADBLBGCQ.mjs} +3 -3
  131. package/dist/{chunk-NQEUFRMX.mjs.map → chunk-ADBLBGCQ.mjs.map} +1 -1
  132. package/dist/{chunk-45VPULF2.mjs → chunk-ADOGOLYO.mjs} +4 -4
  133. package/dist/{chunk-45VPULF2.mjs.map → chunk-ADOGOLYO.mjs.map} +1 -1
  134. package/dist/chunk-AK6JZ3OE.mjs +65 -0
  135. package/dist/chunk-AK6JZ3OE.mjs.map +1 -0
  136. package/dist/{chunk-UR4HKLHW.js → chunk-BGBJSMXT.js} +6 -6
  137. package/dist/{chunk-UR4HKLHW.js.map → chunk-BGBJSMXT.js.map} +1 -1
  138. package/dist/{chunk-INR6AQ54.mjs → chunk-BUDV7QHH.mjs} +4 -4
  139. package/dist/{chunk-INR6AQ54.mjs.map → chunk-BUDV7QHH.mjs.map} +1 -1
  140. package/dist/{chunk-C22WW7G2.mjs → chunk-BVLGJ2CZ.mjs} +3 -3
  141. package/dist/{chunk-C22WW7G2.mjs.map → chunk-BVLGJ2CZ.mjs.map} +1 -1
  142. package/dist/{chunk-6WJDTGM6.js → chunk-CBMHJPR7.js} +5 -5
  143. package/dist/{chunk-6WJDTGM6.js.map → chunk-CBMHJPR7.js.map} +1 -1
  144. package/dist/{chunk-H3F4GV2S.js → chunk-CGQO7MFO.js} +14 -14
  145. package/dist/{chunk-H3F4GV2S.js.map → chunk-CGQO7MFO.js.map} +1 -1
  146. package/dist/{chunk-ZXRORNAW.js → chunk-CKPFETIO.js} +4 -4
  147. package/dist/{chunk-ZXRORNAW.js.map → chunk-CKPFETIO.js.map} +1 -1
  148. package/dist/{chunk-EQZ42LAK.mjs → chunk-CYQB5GLU.mjs} +4 -4
  149. package/dist/{chunk-EQZ42LAK.mjs.map → chunk-CYQB5GLU.mjs.map} +1 -1
  150. package/dist/{chunk-6VHVIBLQ.mjs → chunk-DHXQBTXE.mjs} +62 -41
  151. package/dist/chunk-DHXQBTXE.mjs.map +1 -0
  152. package/dist/{chunk-5EFSD7VM.js → chunk-DKRXPXOR.js} +490 -20
  153. package/dist/chunk-DKRXPXOR.js.map +1 -0
  154. package/dist/chunk-DO6ATNLN.js +67 -0
  155. package/dist/chunk-DO6ATNLN.js.map +1 -0
  156. package/dist/{chunk-R6XBPA6C.mjs → chunk-DTNNZJYM.mjs} +4 -4
  157. package/dist/{chunk-R6XBPA6C.mjs.map → chunk-DTNNZJYM.mjs.map} +1 -1
  158. package/dist/{chunk-4OSZ2JD3.js → chunk-E3GHVAMK.js} +18 -18
  159. package/dist/{chunk-4OSZ2JD3.js.map → chunk-E3GHVAMK.js.map} +1 -1
  160. package/dist/{chunk-I6XKZNFT.mjs → chunk-EKTMXHBI.mjs} +3 -3
  161. package/dist/{chunk-I6XKZNFT.mjs.map → chunk-EKTMXHBI.mjs.map} +1 -1
  162. package/dist/{chunk-M52FYLV4.js → chunk-EZLK2OQL.js} +7 -7
  163. package/dist/{chunk-M52FYLV4.js.map → chunk-EZLK2OQL.js.map} +1 -1
  164. package/dist/{chunk-VLHHBJSV.js → chunk-FMOOQKZU.js} +8 -8
  165. package/dist/{chunk-VLHHBJSV.js.map → chunk-FMOOQKZU.js.map} +1 -1
  166. package/dist/{chunk-LQENHKD3.mjs → chunk-FZISCIJV.mjs} +4 -4
  167. package/dist/{chunk-LQENHKD3.mjs.map → chunk-FZISCIJV.mjs.map} +1 -1
  168. package/dist/{chunk-CQWG5ICB.js → chunk-GYAH4KFC.js} +4 -4
  169. package/dist/{chunk-CQWG5ICB.js.map → chunk-GYAH4KFC.js.map} +1 -1
  170. package/dist/{chunk-FIA3WNEM.js → chunk-GZVSGQKT.js} +3 -3
  171. package/dist/{chunk-FIA3WNEM.js.map → chunk-GZVSGQKT.js.map} +1 -1
  172. package/dist/{chunk-EUAOOOIE.js → chunk-HPIY7AR3.js} +14 -14
  173. package/dist/{chunk-EUAOOOIE.js.map → chunk-HPIY7AR3.js.map} +1 -1
  174. package/dist/chunk-HX6ZG3PP.js +19 -0
  175. package/dist/chunk-HX6ZG3PP.js.map +1 -0
  176. package/dist/{chunk-H27UCW6K.js → chunk-IQLYFQKZ.js} +15 -15
  177. package/dist/{chunk-H27UCW6K.js.map → chunk-IQLYFQKZ.js.map} +1 -1
  178. package/dist/{chunk-FBI6LYTM.js → chunk-JBGRXICL.js} +62 -41
  179. package/dist/chunk-JBGRXICL.js.map +1 -0
  180. package/dist/{chunk-E242GZNE.js → chunk-JEI3CSY4.js} +4 -4
  181. package/dist/{chunk-E242GZNE.js.map → chunk-JEI3CSY4.js.map} +1 -1
  182. package/dist/{chunk-6ABCPVJL.js → chunk-MCXHQHIX.js} +4 -4
  183. package/dist/{chunk-6ABCPVJL.js.map → chunk-MCXHQHIX.js.map} +1 -1
  184. package/dist/{chunk-JNKQKGYH.mjs → chunk-NIJVVW4G.mjs} +3 -3
  185. package/dist/{chunk-JNKQKGYH.mjs.map → chunk-NIJVVW4G.mjs.map} +1 -1
  186. package/dist/{chunk-TY3BPHTE.mjs → chunk-NSTY7ZZA.mjs} +7 -7
  187. package/dist/{chunk-TY3BPHTE.mjs.map → chunk-NSTY7ZZA.mjs.map} +1 -1
  188. package/dist/{chunk-3BXYZC3V.mjs → chunk-OAJVITNO.mjs} +3 -3
  189. package/dist/{chunk-3BXYZC3V.mjs.map → chunk-OAJVITNO.mjs.map} +1 -1
  190. package/dist/{chunk-36E6QKGL.mjs → chunk-OTHKWMDB.mjs} +3 -3
  191. package/dist/{chunk-36E6QKGL.mjs.map → chunk-OTHKWMDB.mjs.map} +1 -1
  192. package/dist/{chunk-ZWMAQ52D.mjs → chunk-ROJ25QM3.mjs} +3 -3
  193. package/dist/{chunk-ZWMAQ52D.mjs.map → chunk-ROJ25QM3.mjs.map} +1 -1
  194. package/dist/{chunk-NDS6MXIP.mjs → chunk-SXNKLHOX.mjs} +3 -3
  195. package/dist/{chunk-NDS6MXIP.mjs.map → chunk-SXNKLHOX.mjs.map} +1 -1
  196. package/dist/{chunk-VYNOQCEK.js → chunk-TAM2D54C.js} +14 -14
  197. package/dist/{chunk-VYNOQCEK.js.map → chunk-TAM2D54C.js.map} +1 -1
  198. package/dist/{chunk-VU45CH5R.mjs → chunk-TECD4AP7.mjs} +3 -3
  199. package/dist/{chunk-VU45CH5R.mjs.map → chunk-TECD4AP7.mjs.map} +1 -1
  200. package/dist/{chunk-MWKYLWCH.mjs → chunk-UMWVTIIZ.mjs} +8 -8
  201. package/dist/{chunk-MWKYLWCH.mjs.map → chunk-UMWVTIIZ.mjs.map} +1 -1
  202. package/dist/{chunk-ULP6BTN2.js → chunk-VCNPTLK2.js} +12 -12
  203. package/dist/{chunk-ULP6BTN2.js.map → chunk-VCNPTLK2.js.map} +1 -1
  204. package/dist/{chunk-FPWPRFTP.js → chunk-VIIGOCX4.js} +15 -15
  205. package/dist/{chunk-FPWPRFTP.js.map → chunk-VIIGOCX4.js.map} +1 -1
  206. package/dist/{chunk-PSBAUXUH.mjs → chunk-VWVUYL5J.mjs} +4 -4
  207. package/dist/{chunk-PSBAUXUH.mjs.map → chunk-VWVUYL5J.mjs.map} +1 -1
  208. package/dist/{chunk-67MTTPJV.js → chunk-WMNRTCYY.js} +11 -11
  209. package/dist/{chunk-67MTTPJV.js.map → chunk-WMNRTCYY.js.map} +1 -1
  210. package/dist/{chunk-C3M5E4YI.js → chunk-WZMM57R2.js} +5 -5
  211. package/dist/{chunk-C3M5E4YI.js.map → chunk-WZMM57R2.js.map} +1 -1
  212. package/dist/chunk-YFX3Q56O.mjs +16 -0
  213. package/dist/chunk-YFX3Q56O.mjs.map +1 -0
  214. package/dist/chunk-YPEX4RDE.js +8 -0
  215. package/dist/{chunk-UXIUJYFK.js.map → chunk-YPEX4RDE.js.map} +1 -1
  216. package/dist/{chunk-R7V7HNJJ.js → chunk-Z33JXJTJ.js} +10 -3
  217. package/dist/chunk-Z33JXJTJ.js.map +1 -0
  218. package/dist/{chunk-X2PAODFM.mjs → chunk-ZFZMN4LT.mjs} +3 -3
  219. package/dist/{chunk-X2PAODFM.mjs.map → chunk-ZFZMN4LT.mjs.map} +1 -1
  220. package/dist/cli/index.js +7 -27
  221. package/dist/cli/index.js.map +1 -1
  222. package/dist/cli/index.mjs +5 -25
  223. package/dist/cli/index.mjs.map +1 -1
  224. package/dist/client/index.js +4 -4
  225. package/dist/client/index.mjs +3 -3
  226. package/dist/commerce/index.js +56 -56
  227. package/dist/commerce/index.mjs +5 -5
  228. package/dist/commerce/server-result.test.d.ts +2 -0
  229. package/dist/commerce/server-result.test.d.ts.map +1 -0
  230. package/dist/commerce/server.d.ts +51 -0
  231. package/dist/commerce/server.d.ts.map +1 -1
  232. package/dist/commerce/server.js +57 -24
  233. package/dist/commerce/server.js.map +1 -1
  234. package/dist/commerce/server.mjs +54 -25
  235. package/dist/commerce/server.mjs.map +1 -1
  236. package/dist/engage/index.js +10 -10
  237. package/dist/engage/index.mjs +7 -7
  238. package/dist/fleet/index.js +8 -8
  239. package/dist/fleet/index.mjs +4 -4
  240. package/dist/forms/index.js +16 -16
  241. package/dist/forms/index.mjs +9 -9
  242. package/dist/forms/server.js +10 -10
  243. package/dist/forms/server.mjs +8 -8
  244. package/dist/forms/static.js +7 -7
  245. package/dist/forms/static.mjs +6 -6
  246. package/dist/images/index.js +11 -11
  247. package/dist/images/index.mjs +4 -4
  248. package/dist/index.js +63 -63
  249. package/dist/index.mjs +9 -9
  250. package/dist/layout/client.js +8 -8
  251. package/dist/layout/client.mjs +7 -7
  252. package/dist/layout/index.js +10 -10
  253. package/dist/layout/index.mjs +8 -8
  254. package/dist/llms/generateLLMsTxt.d.ts.map +1 -1
  255. package/dist/llms/humanize-industry.d.ts +9 -0
  256. package/dist/llms/humanize-industry.d.ts.map +1 -0
  257. package/dist/llms/humanize-industry.test.d.ts +2 -0
  258. package/dist/llms/humanize-industry.test.d.ts.map +1 -0
  259. package/dist/llms/index.js +12 -12
  260. package/dist/llms/index.mjs +2 -2
  261. package/dist/maps/index.js +5 -5
  262. package/dist/maps/index.mjs +3 -3
  263. package/dist/search/index.js +4 -4
  264. package/dist/search/index.mjs +3 -3
  265. package/dist/seo/client.js +5 -5
  266. package/dist/seo/client.mjs +4 -4
  267. package/dist/seo/index.js +5 -5
  268. package/dist/seo/index.mjs +4 -4
  269. package/dist/server/index.js +3 -3
  270. package/dist/server/index.mjs +2 -2
  271. package/dist/shared/version.d.ts +1 -1
  272. package/dist/signal/index.js +11 -11
  273. package/dist/signal/index.mjs +2 -2
  274. package/dist/sitemap/index.js +2 -2
  275. package/dist/sitemap/index.mjs +1 -1
  276. package/dist/sync/index.js +16 -16
  277. package/dist/sync/index.mjs +4 -4
  278. package/package.json +1 -1
  279. package/dist/AnalyticsProvider-DNMYYBKX.js +0 -31
  280. package/dist/AnalyticsProvider-TWRQHKPZ.mjs +0 -10
  281. package/dist/ChatWidget-MDWEXISQ.js +0 -20
  282. package/dist/ChatWidget-UQMEJAHY.mjs +0 -11
  283. package/dist/EngageWidget-UIIN43ZU.mjs +0 -9
  284. package/dist/EngageWidget-VRC7NUG6.js +0 -18
  285. package/dist/ManagedForm-7L2W5BBZ.js +0 -23
  286. package/dist/ManagedForm-D7CFOIXH.mjs +0 -14
  287. package/dist/SitemapSync-RFY6PUG7.mjs +0 -8
  288. package/dist/SitemapSync-SR6OJRIA.js +0 -17
  289. package/dist/chunk-5EFSD7VM.js.map +0 -1
  290. package/dist/chunk-6VHVIBLQ.mjs.map +0 -1
  291. package/dist/chunk-D4KHH44S.mjs.map +0 -1
  292. package/dist/chunk-FBI6LYTM.js.map +0 -1
  293. package/dist/chunk-JJS63TDR.mjs.map +0 -1
  294. package/dist/chunk-NQNSATTA.mjs +0 -6
  295. package/dist/chunk-R7V7HNJJ.js.map +0 -1
  296. package/dist/chunk-UXIUJYFK.js +0 -8
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/forms/HoneypotField.tsx","../src/forms/native-fallback.tsx"],"names":["jsx","getApiConfig","jsxs","Fragment"],"mappings":";;;;;AAqCO,SAAS,aAAA,CAAc,EAAE,IAAA,EAAM,KAAA,EAAO,UAAS,EAAuB;AAC3E,EAAA,MAAM,WAAA,GAAc,OAAO,QAAA,KAAa,UAAA;AACxC,EAAA,uBACEA,cAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,MAAA;AAAA,MACL,IAAA;AAAA,MACA,QAAA,EAAU,EAAA;AAAA,MACV,YAAA,EAAa,cAAA;AAAA,MACb,aAAA,EAAY,MAAA;AAAA,MACZ,KAAA,EAAK,IAAA;AAAA,MACL,kBAAA,EAAiB,EAAA;AAAA,MAGjB,gBAAA,EAAe,EAAA;AAAA,MACf,eAAA,EAAc,MAAA;AAAA,MACd,gBAAA,EAAe,OAAA;AAAA,MACf,eAAA,EAAc,EAAA;AAAA,MACd,KAAA,EAAO;AAAA,QACL,QAAA,EAAU,UAAA;AAAA,QACV,IAAA,EAAM,KAAA;AAAA,QACN,KAAA,EAAO,CAAA;AAAA,QACP,MAAA,EAAQ,CAAA;AAAA,QACR,QAAA,EAAU,QAAA;AAAA,QACV,OAAA,EAAS,CAAA;AAAA,QACT,UAAA,EAAY,QAAA;AAAA,QACZ,aAAA,EAAe;AAAA,OACjB;AAAA,MACC,GAAI,WAAA,GACD;AAAA,QACE,OAAO,KAAA,IAAS,EAAA;AAAA,QAChB,QAAA,EAAU,CAAC,CAAA,KAA2C;AACpD,UAAA,QAAA,CAAU,CAAA,CAAE,OAAO,KAAK,CAAA;AACxB,UAAA,IAAI,CAAA,CAAE,OAAO,KAAA,EAAO;AAElB,YAAA,OAAA,CAAQ,KAAK,4BAA4B,CAAA;AAAA,UAC3C;AAAA,QACF;AAAA,OACF,GACA,EAAE,YAAA,EAAc,EAAA;AAAG;AAAA,GACzB;AAEJ;ACjDA,SAAS,eAAe,MAAA,EAAuD;AAC7E,EAAA,OAAO,CAAC,CAAC,MAAA,EAAQ,YAAA,IAAgB,CAAC,MAAA,CAAO,aAAA;AAC3C;AAGO,SAAS,gBACd,MAAA,EACsC;AACtC,EAAA,IAAI,CAAC,cAAA,CAAe,MAAM,CAAA,SAAU,EAAC;AACrC,EAAA,MAAM,EAAE,MAAA,EAAO,GAAIC,6BAAA,EAAa;AAChC,EAAA,OAAO,EAAE,MAAA,EAAQ,CAAA,EAAG,MAAM,CAAA,+BAAA,CAAA,EAAmC,QAAQ,MAAA,EAAO;AAC9E;AAaO,SAAS,oBAAA,CAAqB,EAAE,MAAA,EAAQ,QAAA,EAAS,EAA8B;AACpF,EAAA,IAAI,CAAC,cAAA,CAAe,MAAM,CAAA,EAAG,OAAO,IAAA;AACpC,EAAA,uBACEC,eAAA,CAAAC,mBAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAAH,cAAAA,CAAC,OAAA,EAAA,EAAM,IAAA,EAAK,QAAA,EAAS,IAAA,EAAK,aAAY,KAAA,EAAO,MAAA,CAAQ,YAAA,EAAc,QAAA,EAAQ,IAAA,EAAC,CAAA;AAAA,IAC3E,QAAA,mBAAWA,cAAAA,CAAC,OAAA,EAAA,EAAM,IAAA,EAAK,QAAA,EAAS,IAAA,EAAK,YAAA,EAAa,KAAA,EAAO,QAAA,EAAU,QAAA,EAAQ,IAAA,EAAC,CAAA,GAAK;AAAA,GAAA,EACpF,CAAA;AAEJ","file":"chunk-6ABCPVJL.js","sourcesContent":["/**\n * Single source of truth for the honeypot input — rendered by BOTH form\n * experiences (classic and stage) inside their <form>. The customRender path\n * deliberately gets none (documented limitation: custom renders lose the\n * honeypot, which is why alternate experiences must be render branches).\n *\n * Invariants (do not weaken any of these):\n * - `inert` blocks focus/interaction at the browser level, surviving hostile\n * site CSS that could defeat the inline styles.\n * - data-sk-honeypot gives site CSS a stable opt-OUT hook.\n * - Controlled input: bots filling via JS still fire React onChange, so the\n * value reaches submitForm's data payload.\n * - Name comes from config (`honeypot_field || DEFAULT_HONEYPOT_FIELD` from\n * the shared contract) — resolved by the caller, never forked here.\n * - The trap must be invisible to AUTOFILL as well as to people. A browser or\n * password manager filling a hidden input flags a real visitor as a bot, and\n * because the value is stripped server-side the mistake is undiagnosable\n * after the fact. `autocomplete=\"off\"` does not achieve this — it is the one\n * value Chrome deliberately ignores for contact/address autofill — so the\n * trap declares `new-password` (never offered saved contact data) plus the\n * documented per-manager opt-outs.\n */\n\nimport React from 'react'\n\nexport interface HoneypotFieldProps {\n name: string\n value?: string\n /**\n * Omit for STATIC mode — an uncontrolled trap a Server Component can render.\n * The trap's whole job is server-side (the value is read off the submission\n * and stripped), so it needs no client state to work; the controlled form is\n * only so the hydrated JSON path can read it back out of React state.\n */\n onChange?: (value: string) => void\n}\n\nexport function HoneypotField({ name, value, onChange }: HoneypotFieldProps) {\n const interactive = typeof onChange === 'function'\n return (\n <input\n type=\"text\"\n name={name}\n tabIndex={-1}\n autoComplete=\"new-password\"\n aria-hidden=\"true\"\n inert\n data-sk-honeypot=\"\"\n // Password-manager opt-outs: 1Password, LastPass, Dashlane, Bitwarden.\n // Each ignores its own attribute; none respects autocomplete alone.\n data-1p-ignore=\"\"\n data-lpignore=\"true\"\n data-form-type=\"other\"\n data-bwignore=\"\"\n style={{\n position: 'absolute',\n left: -9999,\n width: 1,\n height: 1,\n overflow: 'hidden',\n opacity: 0,\n visibility: 'hidden',\n pointerEvents: 'none',\n }}\n {...(interactive\n ? {\n value: value ?? '',\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange!(e.target.value)\n if (e.target.value) {\n // Bot detected\n console.warn('[Forms] Honeypot triggered')\n }\n },\n }\n : { defaultValue: '' })}\n />\n )\n}\n","'use client'\n\n/**\n * No-JS native submission fallback — the floor under every managed form.\n *\n * The classic form is the SSR/no-JS surface (experiences are post-hydration\n * chunks), so it alone carries a real `action`/`method` pointing at\n * sonor-api's POST /api/public/forms/submit-native. With JS running, the\n * form's onSubmit preventDefault()s and the JSON path wins; without JS the\n * browser performs an ordinary form-encoded POST and the lead still lands.\n *\n * Auth rides in the hidden `_sk_token` field: a signed, single-purpose\n * credential minted by the api-key-authenticated forms/config endpoint\n * (`native_token` in the response). No token in the config (older API, or no\n * signing secret) means no fallback — the form keeps its historical behavior\n * rather than pointing at an endpoint that will reject it.\n *\n * Multi-step forms are excluded: step navigation is JS, and a native POST of\n * step-1 fields alone fails whole-form validation server-side. Single-step\n * forms are the overwhelming lead-capture case.\n *\n * Single source of truth for the gating — the form attrs and the hidden\n * fields must always agree, so both read the same predicate.\n */\n\nimport React from 'react'\nimport type { ManagedFormConfig } from './types'\nimport { getApiConfig } from './submitForm'\n\nfunction nativeEligible(config: ManagedFormConfig | null | undefined): boolean {\n return !!config?.native_token && !config.is_multi_step\n}\n\n/** `action`/`method` for the classic <form> — empty when ineligible. */\nexport function nativeFormProps(\n config: ManagedFormConfig | null | undefined,\n): { action?: string; method?: 'post' } {\n if (!nativeEligible(config)) return {}\n const { apiUrl } = getApiConfig()\n return { action: `${apiUrl}/api/public/forms/submit-native`, method: 'post' }\n}\n\nexport interface NativeFallbackFieldsProps {\n config: ManagedFormConfig | null | undefined\n /**\n * Absolute URL the native 303 should land on (usually the page hosting the\n * form). Optional — without it the server falls back to the Referer origin,\n * which loses the path but still returns the visitor to the right site.\n */\n returnTo?: string\n}\n\n/** Hidden control fields the native endpoint reads (`_sk_*` namespace). */\nexport function NativeFallbackFields({ config, returnTo }: NativeFallbackFieldsProps) {\n if (!nativeEligible(config)) return null\n return (\n <>\n <input type=\"hidden\" name=\"_sk_token\" value={config!.native_token} readOnly />\n {returnTo ? <input type=\"hidden\" name=\"_sk_return\" value={returnTo} readOnly /> : null}\n </>\n )\n}\n"]}
1
+ {"version":3,"sources":["../src/forms/HoneypotField.tsx","../src/forms/native-fallback.tsx"],"names":["jsx","getApiConfig","jsxs","Fragment"],"mappings":";;;;;AAqCO,SAAS,aAAA,CAAc,EAAE,IAAA,EAAM,KAAA,EAAO,UAAS,EAAuB;AAC3E,EAAA,MAAM,WAAA,GAAc,OAAO,QAAA,KAAa,UAAA;AACxC,EAAA,uBACEA,cAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,MAAA;AAAA,MACL,IAAA;AAAA,MACA,QAAA,EAAU,EAAA;AAAA,MACV,YAAA,EAAa,cAAA;AAAA,MACb,aAAA,EAAY,MAAA;AAAA,MACZ,KAAA,EAAK,IAAA;AAAA,MACL,kBAAA,EAAiB,EAAA;AAAA,MAGjB,gBAAA,EAAe,EAAA;AAAA,MACf,eAAA,EAAc,MAAA;AAAA,MACd,gBAAA,EAAe,OAAA;AAAA,MACf,eAAA,EAAc,EAAA;AAAA,MACd,KAAA,EAAO;AAAA,QACL,QAAA,EAAU,UAAA;AAAA,QACV,IAAA,EAAM,KAAA;AAAA,QACN,KAAA,EAAO,CAAA;AAAA,QACP,MAAA,EAAQ,CAAA;AAAA,QACR,QAAA,EAAU,QAAA;AAAA,QACV,OAAA,EAAS,CAAA;AAAA,QACT,UAAA,EAAY,QAAA;AAAA,QACZ,aAAA,EAAe;AAAA,OACjB;AAAA,MACC,GAAI,WAAA,GACD;AAAA,QACE,OAAO,KAAA,IAAS,EAAA;AAAA,QAChB,QAAA,EAAU,CAAC,CAAA,KAA2C;AACpD,UAAA,QAAA,CAAU,CAAA,CAAE,OAAO,KAAK,CAAA;AACxB,UAAA,IAAI,CAAA,CAAE,OAAO,KAAA,EAAO;AAElB,YAAA,OAAA,CAAQ,KAAK,4BAA4B,CAAA;AAAA,UAC3C;AAAA,QACF;AAAA,OACF,GACA,EAAE,YAAA,EAAc,EAAA;AAAG;AAAA,GACzB;AAEJ;ACjDA,SAAS,eAAe,MAAA,EAAuD;AAC7E,EAAA,OAAO,CAAC,CAAC,MAAA,EAAQ,YAAA,IAAgB,CAAC,MAAA,CAAO,aAAA;AAC3C;AAGO,SAAS,gBACd,MAAA,EACsC;AACtC,EAAA,IAAI,CAAC,cAAA,CAAe,MAAM,CAAA,SAAU,EAAC;AACrC,EAAA,MAAM,EAAE,MAAA,EAAO,GAAIC,6BAAA,EAAa;AAChC,EAAA,OAAO,EAAE,MAAA,EAAQ,CAAA,EAAG,MAAM,CAAA,+BAAA,CAAA,EAAmC,QAAQ,MAAA,EAAO;AAC9E;AAaO,SAAS,oBAAA,CAAqB,EAAE,MAAA,EAAQ,QAAA,EAAS,EAA8B;AACpF,EAAA,IAAI,CAAC,cAAA,CAAe,MAAM,CAAA,EAAG,OAAO,IAAA;AACpC,EAAA,uBACEC,eAAA,CAAAC,mBAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAAH,cAAAA,CAAC,OAAA,EAAA,EAAM,IAAA,EAAK,QAAA,EAAS,IAAA,EAAK,aAAY,KAAA,EAAO,MAAA,CAAQ,YAAA,EAAc,QAAA,EAAQ,IAAA,EAAC,CAAA;AAAA,IAC3E,QAAA,mBAAWA,cAAAA,CAAC,OAAA,EAAA,EAAM,IAAA,EAAK,QAAA,EAAS,IAAA,EAAK,YAAA,EAAa,KAAA,EAAO,QAAA,EAAU,QAAA,EAAQ,IAAA,EAAC,CAAA,GAAK;AAAA,GAAA,EACpF,CAAA;AAEJ","file":"chunk-MCXHQHIX.js","sourcesContent":["/**\n * Single source of truth for the honeypot input — rendered by BOTH form\n * experiences (classic and stage) inside their <form>. The customRender path\n * deliberately gets none (documented limitation: custom renders lose the\n * honeypot, which is why alternate experiences must be render branches).\n *\n * Invariants (do not weaken any of these):\n * - `inert` blocks focus/interaction at the browser level, surviving hostile\n * site CSS that could defeat the inline styles.\n * - data-sk-honeypot gives site CSS a stable opt-OUT hook.\n * - Controlled input: bots filling via JS still fire React onChange, so the\n * value reaches submitForm's data payload.\n * - Name comes from config (`honeypot_field || DEFAULT_HONEYPOT_FIELD` from\n * the shared contract) — resolved by the caller, never forked here.\n * - The trap must be invisible to AUTOFILL as well as to people. A browser or\n * password manager filling a hidden input flags a real visitor as a bot, and\n * because the value is stripped server-side the mistake is undiagnosable\n * after the fact. `autocomplete=\"off\"` does not achieve this — it is the one\n * value Chrome deliberately ignores for contact/address autofill — so the\n * trap declares `new-password` (never offered saved contact data) plus the\n * documented per-manager opt-outs.\n */\n\nimport React from 'react'\n\nexport interface HoneypotFieldProps {\n name: string\n value?: string\n /**\n * Omit for STATIC mode — an uncontrolled trap a Server Component can render.\n * The trap's whole job is server-side (the value is read off the submission\n * and stripped), so it needs no client state to work; the controlled form is\n * only so the hydrated JSON path can read it back out of React state.\n */\n onChange?: (value: string) => void\n}\n\nexport function HoneypotField({ name, value, onChange }: HoneypotFieldProps) {\n const interactive = typeof onChange === 'function'\n return (\n <input\n type=\"text\"\n name={name}\n tabIndex={-1}\n autoComplete=\"new-password\"\n aria-hidden=\"true\"\n inert\n data-sk-honeypot=\"\"\n // Password-manager opt-outs: 1Password, LastPass, Dashlane, Bitwarden.\n // Each ignores its own attribute; none respects autocomplete alone.\n data-1p-ignore=\"\"\n data-lpignore=\"true\"\n data-form-type=\"other\"\n data-bwignore=\"\"\n style={{\n position: 'absolute',\n left: -9999,\n width: 1,\n height: 1,\n overflow: 'hidden',\n opacity: 0,\n visibility: 'hidden',\n pointerEvents: 'none',\n }}\n {...(interactive\n ? {\n value: value ?? '',\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange!(e.target.value)\n if (e.target.value) {\n // Bot detected\n console.warn('[Forms] Honeypot triggered')\n }\n },\n }\n : { defaultValue: '' })}\n />\n )\n}\n","'use client'\n\n/**\n * No-JS native submission fallback — the floor under every managed form.\n *\n * The classic form is the SSR/no-JS surface (experiences are post-hydration\n * chunks), so it alone carries a real `action`/`method` pointing at\n * sonor-api's POST /api/public/forms/submit-native. With JS running, the\n * form's onSubmit preventDefault()s and the JSON path wins; without JS the\n * browser performs an ordinary form-encoded POST and the lead still lands.\n *\n * Auth rides in the hidden `_sk_token` field: a signed, single-purpose\n * credential minted by the api-key-authenticated forms/config endpoint\n * (`native_token` in the response). No token in the config (older API, or no\n * signing secret) means no fallback — the form keeps its historical behavior\n * rather than pointing at an endpoint that will reject it.\n *\n * Multi-step forms are excluded: step navigation is JS, and a native POST of\n * step-1 fields alone fails whole-form validation server-side. Single-step\n * forms are the overwhelming lead-capture case.\n *\n * Single source of truth for the gating — the form attrs and the hidden\n * fields must always agree, so both read the same predicate.\n */\n\nimport React from 'react'\nimport type { ManagedFormConfig } from './types'\nimport { getApiConfig } from './submitForm'\n\nfunction nativeEligible(config: ManagedFormConfig | null | undefined): boolean {\n return !!config?.native_token && !config.is_multi_step\n}\n\n/** `action`/`method` for the classic <form> — empty when ineligible. */\nexport function nativeFormProps(\n config: ManagedFormConfig | null | undefined,\n): { action?: string; method?: 'post' } {\n if (!nativeEligible(config)) return {}\n const { apiUrl } = getApiConfig()\n return { action: `${apiUrl}/api/public/forms/submit-native`, method: 'post' }\n}\n\nexport interface NativeFallbackFieldsProps {\n config: ManagedFormConfig | null | undefined\n /**\n * Absolute URL the native 303 should land on (usually the page hosting the\n * form). Optional — without it the server falls back to the Referer origin,\n * which loses the path but still returns the visitor to the right site.\n */\n returnTo?: string\n}\n\n/** Hidden control fields the native endpoint reads (`_sk_*` namespace). */\nexport function NativeFallbackFields({ config, returnTo }: NativeFallbackFieldsProps) {\n if (!nativeEligible(config)) return null\n return (\n <>\n <input type=\"hidden\" name=\"_sk_token\" value={config!.native_token} readOnly />\n {returnTo ? <input type=\"hidden\" name=\"_sk_return\" value={returnTo} readOnly /> : null}\n </>\n )\n}\n"]}
@@ -54,7 +54,7 @@ function useSignal() {
54
54
  return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
55
55
  }
56
56
  var LazySignalCore = dynamic(
57
- () => import('./SignalCore-JQLRWMPJ.mjs').then((m) => ({ default: m.SignalCore })),
57
+ () => import('./SignalCore-2BH5PUGS.mjs').then((m) => ({ default: m.SignalCore })),
58
58
  { ssr: false }
59
59
  );
60
60
  function SignalBridge({
@@ -161,5 +161,5 @@ function useSignalExperiment(experimentId) {
161
161
  }
162
162
 
163
163
  export { SignalBridge, useSignal, useSignalConfig, useSignalEvent, useSignalExperiment, useSignalOutcome };
164
- //# sourceMappingURL=chunk-JNKQKGYH.mjs.map
165
- //# sourceMappingURL=chunk-JNKQKGYH.mjs.map
164
+ //# sourceMappingURL=chunk-NIJVVW4G.mjs.map
165
+ //# sourceMappingURL=chunk-NIJVVW4G.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/signal/store.ts","../src/signal/SignalBridge.tsx"],"names":[],"mappings":";;;;;AAyBA,IAAM,gBAAwC,EAAC;AAC/C,IAAM,kBAAmC,EAAC;AAC1C,IAAM,WAAA,GAAc,GAAA;AACpB,IAAI,cAAA,GAAiB,KAAA;AAGrB,IAAM,IAAA,GAA2B,OAAO,MAAA,CAAO;AAAA,EAC7C,MAAA,EAAQ,IAAA;AAAA,EACR,OAAA,EAAS,IAAA;AAAA,EACT,KAAA,EAAO,IAAA;AAAA,EACP,UAAA,EAAY,CAAC,KAAA,KAAgC;AAC3C,IAAA,IAAI,aAAA,CAAc,MAAA,GAAS,WAAA,EAAa,aAAA,CAAc,KAAK,KAAK,CAAA;AAAA,SAAA,IACvD,CAAC,cAAA,EAAgB;AACxB,MAAA,cAAA,GAAiB,IAAA;AACjB,MAAA,OAAA,CAAQ,KAAK,iHAA4G,CAAA;AAAA,IAC3H;AAAA,EACF,CAAA;AAAA,EACA,YAAA,EAAc,CAAC,OAAA,KAA2B;AACxC,IAAA,IAAI,eAAA,CAAgB,MAAA,GAAS,WAAA,EAAa,eAAA,CAAgB,KAAK,OAAO,CAAA;AAAA,EACxE,CAAA;AAAA,EACA,eAAe,MAAM,IAAA;AAAA,EACrB,eAAe,YAAY;AAAA,EAAC;AAC9B,CAAC,CAAA;AAED,IAAI,OAAA,GAA8B,IAAA;AAClC,IAAM,SAAA,uBAAgB,GAAA,EAAgB;AAEtC,SAAS,IAAA,GAAO;AACd,EAAA,KAAA,MAAW,CAAA,IAAK,WAAW,CAAA,EAAE;AAC/B;AAGO,SAAS,cAAc,KAAA,EAAiC;AAC7D,EAAA,MAAM,eAAe,OAAA,KAAY,IAAA;AACjC,EAAA,OAAA,GAAU,KAAA;AACV,EAAA,IAAI,YAAA,EAAc;AAGhB,IAAA,aAAA,CAAc,MAAA,CAAO,CAAC,CAAA,CAAE,OAAA,CAAQ,OAAK,KAAA,CAAM,UAAA,CAAW,CAAC,CAAC,CAAA;AACxD,IAAA,eAAA,CAAgB,MAAA,CAAO,CAAC,CAAA,CAAE,OAAA,CAAQ,OAAK,KAAA,CAAM,YAAA,CAAa,CAAC,CAAC,CAAA;AAAA,EAC9D;AACA,EAAA,IAAA,EAAK;AACP;AAGO,SAAS,WAAA,GAAoB;AAClC,EAAA,OAAA,GAAU,IAAA;AACV,EAAA,IAAA,EAAK;AACP;AAEA,SAAS,UAAU,QAAA,EAAsB;AACvC,EAAA,SAAA,CAAU,IAAI,QAAQ,CAAA;AACtB,EAAA,OAAO,MAAM,SAAA,CAAU,MAAA,CAAO,QAAQ,CAAA;AACxC;AAEA,IAAM,cAAc,MAAM,OAAA;AAC1B,IAAM,oBAAoB,MAAM,IAAA;AAMzB,SAAS,SAAA,GAAgC;AAC9C,EAAA,OAAO,oBAAA,CAAqB,SAAA,EAAW,WAAA,EAAa,iBAAiB,CAAA;AACvE;ACnDA,IAAM,cAAA,GAAiB,OAAA;AAAA,EACrB,MAAM,OAAO,2BAAc,CAAA,CAAE,IAAA,CAAK,QAAM,EAAE,OAAA,EAAS,CAAA,CAAE,UAAA,EAAW,CAAE,CAAA;AAAA,EAClE,EAAE,KAAK,KAAA;AACT,CAAA;AAcO,SAAS,YAAA,CAAa;AAAA,EAC3B,OAAA,GAAU,IAAA;AAAA,EACV,QAAA,GAAW,IAAA;AAAA,EACX,WAAA,GAAc,IAAA;AAAA,EACd,gBAAA,GAAmB,IAAA;AAAA,EACnB,SAAA,EAAW,iBAAA;AAAA,EACX,SAAA,EAAW,iBAAA;AAAA,EACX,eAAA;AAAA,EACA;AACF,CAAA,EAAsB;AACpB,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,SAA8B,IAAI,CAAA;AAC9D,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,IAAI,CAAA;AAC3C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAuB,IAAI,CAAA;AAErD,EAAA,MAAM,OAAA,GAAU,OAA6B,IAAI,CAAA;AAGjD,EAAA,MAAM,gBAAA,GAAmB,MAAA,CAA+B,EAAE,CAAA;AAC1D,EAAA,MAAM,kBAAA,GAAqB,MAAA,CAAwB,EAAE,CAAA;AAErD,EAAA,MAAM,WAAA,GAAc,WAAA,CAAY,CAAC,KAAA,KAA2B;AAC1D,IAAA,SAAA,CAAU,MAAM,MAAM,CAAA;AACtB,IAAA,UAAA,CAAW,MAAM,OAAO,CAAA;AACxB,IAAA,QAAA,CAAS,MAAM,KAAK,CAAA;AAAA,EACtB,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,cAAA,GAAiB,WAAA,CAAY,CAAC,GAAA,KAA8B;AAChE,IAAA,OAAA,CAAQ,OAAA,GAAU,GAAA;AAClB,IAAA,IAAI,GAAA,EAAK;AACP,MAAA,gBAAA,CAAiB,OAAA,CAAQ,OAAO,CAAC,CAAA,CAAE,QAAQ,CAAA,KAAA,KAAS,GAAA,CAAI,UAAA,CAAW,KAAK,CAAC,CAAA;AACzE,MAAA,kBAAA,CAAmB,OAAA,CAAQ,OAAO,CAAC,CAAA,CAAE,QAAQ,CAAA,OAAA,KAAW,GAAA,CAAI,YAAA,CAAa,OAAO,CAAC,CAAA;AAAA,IACnF;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,UAAA,GAAa,WAAA,CAAY,CAAC,KAAA,KAAgC;AAC9D,IAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,MAAA,OAAA,CAAQ,OAAA,CAAQ,WAAW,KAAK,CAAA;AAAA,IAClC,CAAA,MAAO;AACL,MAAA,gBAAA,CAAiB,OAAA,CAAQ,KAAK,KAAK,CAAA;AAAA,IACrC;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,YAAA,GAAe,WAAA,CAAY,CAAC,OAAA,KAA2B;AAC3D,IAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,MAAA,OAAA,CAAQ,OAAA,CAAQ,aAAa,OAAO,CAAA;AAAA,IACtC,CAAA,MAAO;AACL,MAAA,kBAAA,CAAmB,OAAA,CAAQ,KAAK,OAAO,CAAA;AAAA,IACzC;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,aAAA,GAAgB,WAAA,CAAY,CAAC,YAAA,KAAsD;AAGvF,IAAA,OAAO,OAAA,CAAQ,OAAA,EAAS,aAAA,CAAc,YAAY,CAAA,IAAK,IAAA;AAAA,EACzD,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,aAAA,GAAgB,YAAY,YAAY;AAC5C,IAAA,MAAM,OAAA,CAAQ,SAAS,aAAA,EAAc;AAAA,EACvC,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,YAAA,GAAe,QAA4B,OAAO;AAAA,IACtD,MAAA;AAAA,IACA,OAAA;AAAA,IACA,KAAA;AAAA,IACA,UAAA;AAAA,IACA,YAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACF,CAAA,EAAI,CAAC,MAAA,EAAQ,OAAA,EAAS,OAAO,UAAA,EAAY,YAAA,EAAc,aAAA,EAAe,aAAa,CAAC,CAAA;AAIpF,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,aAAA,CAAc,YAAY,CAAA;AAAA,EAC5B,CAAA,EAAG,CAAC,YAAY,CAAC,CAAA;AACjB,EAAA,SAAA,CAAU,MAAM,MAAM,WAAA,EAAY,EAAG,EAAE,CAAA;AAEvC,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,IAAA,QAAA;AAAA,IACA,OAAA,oBACC,GAAA;AAAA,MAAC,cAAA;AAAA,MAAA;AAAA,QACC,OAAA;AAAA,QACA,QAAA;AAAA,QACA,WAAA;AAAA,QACA,gBAAA;AAAA,QACA,iBAAA;AAAA,QACA,iBAAA;AAAA,QACA,eAAA;AAAA,QACA,UAAA,EAAY,cAAA;AAAA,QACZ,OAAA,EAAS;AAAA;AAAA;AACX,GAAA,EAEJ,CAAA;AAEJ;AASO,SAAS,eAAA,GAAuC;AACrD,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,SAAA,EAAU;AAC7B,EAAA,OAAO,MAAA;AACT;AAKO,SAAS,cAAA,GAAiB;AAC/B,EAAA,MAAM,EAAE,UAAA,EAAW,GAAI,SAAA,EAAU;AACjC,EAAA,OAAO,UAAA;AACT;AAKO,SAAS,gBAAA,GAAmB;AACjC,EAAA,MAAM,EAAE,YAAA,EAAa,GAAI,SAAA,EAAU;AACnC,EAAA,OAAO,EAAE,YAAA,EAAa;AACxB;AAKO,SAAS,oBAAoB,YAAA,EAIlC;AACA,EAAA,MAAM,EAAE,aAAA,EAAe,MAAA,EAAO,GAAI,SAAA,EAAU;AAC5C,EAAA,MAAM,UAAA,GAAa,cAAc,YAAY,CAAA;AAG7C,EAAA,MAAM,aAAa,MAAA,EAAQ,WAAA,EAAa,KAAK,CAAA,CAAA,KAAK,CAAA,CAAE,OAAO,YAAY,CAAA;AACvE,EAAA,MAAM,SAAA,GAAY,YAAY,MAAA,KAAW,SAAA;AAEzC,EAAA,OAAO;AAAA,IACL,UAAA,EAAY,YAAY,UAAA,GAAa,IAAA;AAAA,IACrC,OAAA,EAAS,SAAA,IAAa,UAAA,GAAa,UAAA,CAAW,WAAA,GAAc,IAAA;AAAA,IAC5D,SAAA,EAAW,CAAC,UAAA,IAAc,UAAA,CAAW,WAAA,KAAgB;AAAA,GACvD;AACF","file":"chunk-JNKQKGYH.mjs","sourcesContent":["'use client'\n\n/**\n * Signal store — module singleton behind useSignal().\n *\n * 4.0: SignalBridge no longer wraps page children in a React context; it\n * mounts as a childless sibling and publishes its API here. useSignal()\n * subscribes via useSyncExternalStore, so consumers work anywhere in the\n * tree — and BEFORE the bridge mounts, they get a buffering stub whose\n * trackEvent/trackOutcome queue calls that the bridge drains on publish.\n * getExperiment returns null pre-publish, identical to the pre-config\n * `loading` window consumers already handle.\n *\n * Behavior change vs 3.x (major): useSignal() no longer throws outside a\n * SignalBridge. With signal disabled it stays a bounded no-op stub — a\n * one-time debug warning fires instead of a crash.\n */\n\nimport { useSyncExternalStore } from 'react'\nimport type {\n SignalContextValue,\n SignalEvent,\n SignalOutcome,\n} from './types'\n\nconst pendingEvents: Partial<SignalEvent>[] = []\nconst pendingOutcomes: SignalOutcome[] = []\nconst MAX_PENDING = 100\nlet warnedNoBridge = false\n\n/** Frozen pre-bridge stub — stable reference (useSyncExternalStore requirement). */\nconst STUB: SignalContextValue = Object.freeze({\n config: null,\n loading: true,\n error: null,\n trackEvent: (event: Partial<SignalEvent>) => {\n if (pendingEvents.length < MAX_PENDING) pendingEvents.push(event)\n else if (!warnedNoBridge) {\n warnedNoBridge = true\n console.warn('[site-kit] Signal events are queuing but no SignalBridge has mounted — is signal enabled on SiteKitLayout?')\n }\n },\n trackOutcome: (outcome: SignalOutcome) => {\n if (pendingOutcomes.length < MAX_PENDING) pendingOutcomes.push(outcome)\n },\n getExperiment: () => null,\n refreshConfig: async () => {},\n})\n\nlet current: SignalContextValue = STUB\nconst listeners = new Set<() => void>()\n\nfunction emit() {\n for (const l of listeners) l()\n}\n\n/** Bridge-side: publish the live API (called whenever its value changes). */\nexport function publishSignal(value: SignalContextValue): void {\n const firstPublish = current === STUB\n current = value\n if (firstPublish) {\n // Drain calls made before the bridge mounted. The bridge's own trackEvent\n // buffers again internally until SignalCore loads, so nothing is lost.\n pendingEvents.splice(0).forEach(e => value.trackEvent(e))\n pendingOutcomes.splice(0).forEach(o => value.trackOutcome(o))\n }\n emit()\n}\n\n/** Bridge-side: reset on unmount so a remount starts clean (tests, HMR). */\nexport function resetSignal(): void {\n current = STUB\n emit()\n}\n\nfunction subscribe(onChange: () => void) {\n listeners.add(onChange)\n return () => listeners.delete(onChange)\n}\n\nconst getSnapshot = () => current\nconst getServerSnapshot = () => STUB\n\n/**\n * Access Signal (experiments, behavioral events) from anywhere in the tree.\n * No provider required — see module docs for pre-mount buffering semantics.\n */\nexport function useSignal(): SignalContextValue {\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)\n}\n","/**\n * @sonordev/site-kit/signal - SignalBridge\n *\n * Central coordination layer for Signal AI integration.\n *\n * Architecture (2026-07 perf release): SignalBridge is a tiny SSR-SAFE context shell. It\n * renders {children} immediately — children server-render and hydrate\n * normally, no ssr:false wrapper — and lazy-loads the heavy machinery\n * (SignalCore: config fetch, SSE streaming, experiment assignment, event\n * queue, behavior tracking) as a CHILDLESS sibling. The core registers its\n * imperative API into the shell on mount; `trackEvent`/`trackOutcome` calls\n * made before the core is ready are buffered and drained on registration.\n *\n * This removes the old failure mode where enabling `signal` de-opted the\n * whole route to client rendering (the same SSR bailout the analytics\n * sibling-mount fixed) — the #1 recommendation of the 2026-07 perf audit.\n *\n * The core is NOT idle-deferred: experiment variants must apply as early as\n * possible, so it starts loading on hydration.\n */\n\n'use client'\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport dynamic from 'next/dynamic'\nimport type { SignalCoreApi, SignalCoreState } from './SignalCore'\nimport type {\n SignalConfig,\n SignalContextValue,\n SignalBridgeProps,\n SignalEvent,\n SignalOutcome,\n ExperimentAssignment,\n} from './types'\n\n// Heavy machinery — loaded client-side only, never wraps content.\nimport { publishSignal, resetSignal, useSignal } from './store'\n\nconst LazySignalCore = dynamic(\n () => import('./SignalCore').then(m => ({ default: m.SignalCore })),\n { ssr: false },\n)\n\n// ============================================\n// Context\n// ============================================\n\n// 4.0: the context is gone. useSignal() reads the module store, so consumers\n// work anywhere in the tree and SignalBridge mounts as a childless sibling.\nexport { useSignal } from './store'\n\n// ============================================\n// SignalBridge Component (shell)\n// ============================================\n\nexport function SignalBridge({\n enabled = true,\n realtime = true,\n experiments = true,\n behaviorTracking = true,\n visitorId: externalVisitorId,\n sessionId: externalSessionId,\n pageMetadataRef,\n children,\n}: SignalBridgeProps) {\n const [config, setConfig] = useState<SignalConfig | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<Error | null>(null)\n\n const coreRef = useRef<SignalCoreApi | null>(null)\n // Calls made before the core chunk loads are buffered here and drained on\n // registration — consumers can call trackEvent/trackOutcome from first render.\n const pendingEventsRef = useRef<Partial<SignalEvent>[]>([])\n const pendingOutcomesRef = useRef<SignalOutcome[]>([])\n\n const handleState = useCallback((state: SignalCoreState) => {\n setConfig(state.config)\n setLoading(state.loading)\n setError(state.error)\n }, [])\n\n const handleRegister = useCallback((api: SignalCoreApi | null) => {\n coreRef.current = api\n if (api) {\n pendingEventsRef.current.splice(0).forEach(event => api.trackEvent(event))\n pendingOutcomesRef.current.splice(0).forEach(outcome => api.trackOutcome(outcome))\n }\n }, [])\n\n const trackEvent = useCallback((event: Partial<SignalEvent>) => {\n if (coreRef.current) {\n coreRef.current.trackEvent(event)\n } else {\n pendingEventsRef.current.push(event)\n }\n }, [])\n\n const trackOutcome = useCallback((outcome: SignalOutcome) => {\n if (coreRef.current) {\n coreRef.current.trackOutcome(outcome)\n } else {\n pendingOutcomesRef.current.push(outcome)\n }\n }, [])\n\n const getExperiment = useCallback((experimentId: string): ExperimentAssignment | null => {\n // null before the core loads — identical to the pre-config-fetch behavior\n // consumers already handle via `loading`.\n return coreRef.current?.getExperiment(experimentId) ?? null\n }, [])\n\n const refreshConfig = useCallback(async () => {\n await coreRef.current?.refreshConfig()\n }, [])\n\n const contextValue = useMemo<SignalContextValue>(() => ({\n config,\n loading,\n error,\n trackEvent,\n trackOutcome,\n getExperiment,\n refreshConfig,\n }), [config, loading, error, trackEvent, trackOutcome, getExperiment, refreshConfig])\n\n // Publish to the module store (drains pre-mount buffered calls on first\n // publish); reset on unmount so tests/HMR start clean.\n useEffect(() => {\n publishSignal(contextValue)\n }, [contextValue])\n useEffect(() => () => resetSignal(), [])\n\n return (\n <>\n {children}\n {enabled && (\n <LazySignalCore\n enabled={enabled}\n realtime={realtime}\n experiments={experiments}\n behaviorTracking={behaviorTracking}\n externalVisitorId={externalVisitorId}\n externalSessionId={externalSessionId}\n pageMetadataRef={pageMetadataRef}\n onRegister={handleRegister}\n onState={handleState}\n />\n )}\n </>\n )\n}\n\n// ============================================\n// Convenience Hooks\n// ============================================\n\n/**\n * Hook to access Signal config\n */\nexport function useSignalConfig(): SignalConfig | null {\n const { config } = useSignal()\n return config\n}\n\n/**\n * Hook for tracking events\n */\nexport function useSignalEvent() {\n const { trackEvent } = useSignal()\n return trackEvent\n}\n\n/**\n * Hook for tracking outcomes/conversions\n */\nexport function useSignalOutcome() {\n const { trackOutcome } = useSignal()\n return { trackOutcome }\n}\n\n/**\n * Hook for experiment assignment\n */\nexport function useSignalExperiment(experimentId: string): {\n assignment: ExperimentAssignment | null\n variant: string | null\n isControl: boolean\n} {\n const { getExperiment, config } = useSignal()\n const assignment = getExperiment(experimentId)\n\n // Check if experiment is running\n const experiment = config?.experiments?.find(e => e.id === experimentId)\n const isRunning = experiment?.status === 'running'\n\n return {\n assignment: isRunning ? assignment : null,\n variant: isRunning && assignment ? assignment.variant_key : null,\n isControl: !assignment || assignment.variant_key === 'control',\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/signal/store.ts","../src/signal/SignalBridge.tsx"],"names":[],"mappings":"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","file":"chunk-NIJVVW4G.mjs","sourcesContent":["'use client'\n\n/**\n * Signal store — module singleton behind useSignal().\n *\n * 4.0: SignalBridge no longer wraps page children in a React context; it\n * mounts as a childless sibling and publishes its API here. useSignal()\n * subscribes via useSyncExternalStore, so consumers work anywhere in the\n * tree — and BEFORE the bridge mounts, they get a buffering stub whose\n * trackEvent/trackOutcome queue calls that the bridge drains on publish.\n * getExperiment returns null pre-publish, identical to the pre-config\n * `loading` window consumers already handle.\n *\n * Behavior change vs 3.x (major): useSignal() no longer throws outside a\n * SignalBridge. With signal disabled it stays a bounded no-op stub — a\n * one-time debug warning fires instead of a crash.\n */\n\nimport { useSyncExternalStore } from 'react'\nimport type {\n SignalContextValue,\n SignalEvent,\n SignalOutcome,\n} from './types'\n\nconst pendingEvents: Partial<SignalEvent>[] = []\nconst pendingOutcomes: SignalOutcome[] = []\nconst MAX_PENDING = 100\nlet warnedNoBridge = false\n\n/** Frozen pre-bridge stub — stable reference (useSyncExternalStore requirement). */\nconst STUB: SignalContextValue = Object.freeze({\n config: null,\n loading: true,\n error: null,\n trackEvent: (event: Partial<SignalEvent>) => {\n if (pendingEvents.length < MAX_PENDING) pendingEvents.push(event)\n else if (!warnedNoBridge) {\n warnedNoBridge = true\n console.warn('[site-kit] Signal events are queuing but no SignalBridge has mounted — is signal enabled on SiteKitLayout?')\n }\n },\n trackOutcome: (outcome: SignalOutcome) => {\n if (pendingOutcomes.length < MAX_PENDING) pendingOutcomes.push(outcome)\n },\n getExperiment: () => null,\n refreshConfig: async () => {},\n})\n\nlet current: SignalContextValue = STUB\nconst listeners = new Set<() => void>()\n\nfunction emit() {\n for (const l of listeners) l()\n}\n\n/** Bridge-side: publish the live API (called whenever its value changes). */\nexport function publishSignal(value: SignalContextValue): void {\n const firstPublish = current === STUB\n current = value\n if (firstPublish) {\n // Drain calls made before the bridge mounted. The bridge's own trackEvent\n // buffers again internally until SignalCore loads, so nothing is lost.\n pendingEvents.splice(0).forEach(e => value.trackEvent(e))\n pendingOutcomes.splice(0).forEach(o => value.trackOutcome(o))\n }\n emit()\n}\n\n/** Bridge-side: reset on unmount so a remount starts clean (tests, HMR). */\nexport function resetSignal(): void {\n current = STUB\n emit()\n}\n\nfunction subscribe(onChange: () => void) {\n listeners.add(onChange)\n return () => listeners.delete(onChange)\n}\n\nconst getSnapshot = () => current\nconst getServerSnapshot = () => STUB\n\n/**\n * Access Signal (experiments, behavioral events) from anywhere in the tree.\n * No provider required — see module docs for pre-mount buffering semantics.\n */\nexport function useSignal(): SignalContextValue {\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)\n}\n","/**\n * @sonordev/site-kit/signal - SignalBridge\n *\n * Central coordination layer for Signal AI integration.\n *\n * Architecture (2026-07 perf release): SignalBridge is a tiny SSR-SAFE context shell. It\n * renders {children} immediately — children server-render and hydrate\n * normally, no ssr:false wrapper — and lazy-loads the heavy machinery\n * (SignalCore: config fetch, SSE streaming, experiment assignment, event\n * queue, behavior tracking) as a CHILDLESS sibling. The core registers its\n * imperative API into the shell on mount; `trackEvent`/`trackOutcome` calls\n * made before the core is ready are buffered and drained on registration.\n *\n * This removes the old failure mode where enabling `signal` de-opted the\n * whole route to client rendering (the same SSR bailout the analytics\n * sibling-mount fixed) — the #1 recommendation of the 2026-07 perf audit.\n *\n * The core is NOT idle-deferred: experiment variants must apply as early as\n * possible, so it starts loading on hydration.\n */\n\n'use client'\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport dynamic from 'next/dynamic'\nimport type { SignalCoreApi, SignalCoreState } from './SignalCore'\nimport type {\n SignalConfig,\n SignalContextValue,\n SignalBridgeProps,\n SignalEvent,\n SignalOutcome,\n ExperimentAssignment,\n} from './types'\n\n// Heavy machinery — loaded client-side only, never wraps content.\nimport { publishSignal, resetSignal, useSignal } from './store'\n\nconst LazySignalCore = dynamic(\n () => import('./SignalCore').then(m => ({ default: m.SignalCore })),\n { ssr: false },\n)\n\n// ============================================\n// Context\n// ============================================\n\n// 4.0: the context is gone. useSignal() reads the module store, so consumers\n// work anywhere in the tree and SignalBridge mounts as a childless sibling.\nexport { useSignal } from './store'\n\n// ============================================\n// SignalBridge Component (shell)\n// ============================================\n\nexport function SignalBridge({\n enabled = true,\n realtime = true,\n experiments = true,\n behaviorTracking = true,\n visitorId: externalVisitorId,\n sessionId: externalSessionId,\n pageMetadataRef,\n children,\n}: SignalBridgeProps) {\n const [config, setConfig] = useState<SignalConfig | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<Error | null>(null)\n\n const coreRef = useRef<SignalCoreApi | null>(null)\n // Calls made before the core chunk loads are buffered here and drained on\n // registration — consumers can call trackEvent/trackOutcome from first render.\n const pendingEventsRef = useRef<Partial<SignalEvent>[]>([])\n const pendingOutcomesRef = useRef<SignalOutcome[]>([])\n\n const handleState = useCallback((state: SignalCoreState) => {\n setConfig(state.config)\n setLoading(state.loading)\n setError(state.error)\n }, [])\n\n const handleRegister = useCallback((api: SignalCoreApi | null) => {\n coreRef.current = api\n if (api) {\n pendingEventsRef.current.splice(0).forEach(event => api.trackEvent(event))\n pendingOutcomesRef.current.splice(0).forEach(outcome => api.trackOutcome(outcome))\n }\n }, [])\n\n const trackEvent = useCallback((event: Partial<SignalEvent>) => {\n if (coreRef.current) {\n coreRef.current.trackEvent(event)\n } else {\n pendingEventsRef.current.push(event)\n }\n }, [])\n\n const trackOutcome = useCallback((outcome: SignalOutcome) => {\n if (coreRef.current) {\n coreRef.current.trackOutcome(outcome)\n } else {\n pendingOutcomesRef.current.push(outcome)\n }\n }, [])\n\n const getExperiment = useCallback((experimentId: string): ExperimentAssignment | null => {\n // null before the core loads — identical to the pre-config-fetch behavior\n // consumers already handle via `loading`.\n return coreRef.current?.getExperiment(experimentId) ?? null\n }, [])\n\n const refreshConfig = useCallback(async () => {\n await coreRef.current?.refreshConfig()\n }, [])\n\n const contextValue = useMemo<SignalContextValue>(() => ({\n config,\n loading,\n error,\n trackEvent,\n trackOutcome,\n getExperiment,\n refreshConfig,\n }), [config, loading, error, trackEvent, trackOutcome, getExperiment, refreshConfig])\n\n // Publish to the module store (drains pre-mount buffered calls on first\n // publish); reset on unmount so tests/HMR start clean.\n useEffect(() => {\n publishSignal(contextValue)\n }, [contextValue])\n useEffect(() => () => resetSignal(), [])\n\n return (\n <>\n {children}\n {enabled && (\n <LazySignalCore\n enabled={enabled}\n realtime={realtime}\n experiments={experiments}\n behaviorTracking={behaviorTracking}\n externalVisitorId={externalVisitorId}\n externalSessionId={externalSessionId}\n pageMetadataRef={pageMetadataRef}\n onRegister={handleRegister}\n onState={handleState}\n />\n )}\n </>\n )\n}\n\n// ============================================\n// Convenience Hooks\n// ============================================\n\n/**\n * Hook to access Signal config\n */\nexport function useSignalConfig(): SignalConfig | null {\n const { config } = useSignal()\n return config\n}\n\n/**\n * Hook for tracking events\n */\nexport function useSignalEvent() {\n const { trackEvent } = useSignal()\n return trackEvent\n}\n\n/**\n * Hook for tracking outcomes/conversions\n */\nexport function useSignalOutcome() {\n const { trackOutcome } = useSignal()\n return { trackOutcome }\n}\n\n/**\n * Hook for experiment assignment\n */\nexport function useSignalExperiment(experimentId: string): {\n assignment: ExperimentAssignment | null\n variant: string | null\n isControl: boolean\n} {\n const { getExperiment, config } = useSignal()\n const assignment = getExperiment(experimentId)\n\n // Check if experiment is running\n const experiment = config?.experiments?.find(e => e.id === experimentId)\n const isRunning = experiment?.status === 'running'\n\n return {\n assignment: isRunning ? assignment : null,\n variant: isRunning && assignment ? assignment.variant_key : null,\n isControl: !assignment || assignment.variant_key === 'control',\n }\n}\n"]}
@@ -1,9 +1,9 @@
1
1
  'use client';
2
- import { countStageViews, countStageQuestions, useFieldControls } from './chunk-C22WW7G2.mjs';
3
- import { HoneypotField, NativeFallbackFields, nativeFormProps } from './chunk-A7OO6OPW.mjs';
2
+ import { countStageViews, countStageQuestions, useFieldControls } from './chunk-BVLGJ2CZ.mjs';
3
+ import { HoneypotField, NativeFallbackFields, nativeFormProps } from './chunk-5W56B52Z.mjs';
4
4
  import { DelightStyles, FormMomentum, FormField } from './chunk-LB7LHVWI.mjs';
5
- import { useFormTracking, useForm } from './chunk-INR6AQ54.mjs';
6
- import { submitForm, DEFAULT_FORM_SUCCESS_MESSAGE } from './chunk-X2PAODFM.mjs';
5
+ import { useFormTracking, useForm } from './chunk-BUDV7QHH.mjs';
6
+ import { submitForm, DEFAULT_FORM_SUCCESS_MESSAGE } from './chunk-ZFZMN4LT.mjs';
7
7
  import { DEFAULT_HONEYPOT_FIELD } from './chunk-TMVKRQGJ.mjs';
8
8
  import { useState, useRef, useMemo, useEffect, useCallback } from 'react';
9
9
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
@@ -68,7 +68,7 @@ function FormClient({
68
68
  return;
69
69
  }
70
70
  let cancelled = false;
71
- const load = resolvedExperience === "stage" ? import('./FormStage-WQOAP7CR.mjs').then((m) => m.FormStage) : import('./FormSpotlight-ZPISKGIX.mjs').then((m) => m.FormSpotlight);
71
+ const load = resolvedExperience === "stage" ? import('./FormStage-Q5JW75AF.mjs').then((m) => m.FormStage) : import('./FormSpotlight-HLH5LQKI.mjs').then((m) => m.FormSpotlight);
72
72
  load.then((Component) => {
73
73
  if (!cancelled) setExperience(() => Component);
74
74
  }).catch((err) => {
@@ -514,5 +514,5 @@ function ManagedForm({
514
514
  }
515
515
 
516
516
  export { FormClient, ManagedForm };
517
- //# sourceMappingURL=chunk-TY3BPHTE.mjs.map
518
- //# sourceMappingURL=chunk-TY3BPHTE.mjs.map
517
+ //# sourceMappingURL=chunk-NSTY7ZZA.mjs.map
518
+ //# sourceMappingURL=chunk-NSTY7ZZA.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/forms/FormClient.tsx","../src/forms/ManagedForm.tsx"],"names":["currentStepConfig","jsx"],"mappings":";;;;;;;;;AAmDO,SAAS,UAAA,CAAW;AAAA,EACzB,MAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA;AAAA,EACA,YAAA;AAAA,EACA,UAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAAA,EAAoB;AAGlB,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,SAAkC,MAAM;AAClE,IAAA,MAAM,WAAoC,EAAC;AAC3C,IAAA,KAAA,MAAW,KAAA,IAAS,MAAA,CAAO,MAAA,IAAU,EAAC,EAAG;AACvC,MAAA,IAAI,KAAA,CAAM,aAAA,KAAkB,MAAA,IAAa,KAAA,CAAM,kBAAkB,IAAA,EAAM;AACrE,QAAA,QAAA,CAAS,KAAA,CAAM,IAAI,CAAA,GAAI,KAAA,CAAM,aAAA;AAAA,MAC/B;AAAA,IACF;AAIA,IAAA,OAAO,EAAE,GAAG,QAAA,EAAU,GAAI,aAAA,IAAiB,EAAC,EAAG;AAAA,EACjD,CAAC,CAAA;AACD,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,QAAA,CAAiC,EAAE,CAAA;AAC/D,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAAS,CAAC,CAAA;AAGlC,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAI,SAA6B,SAAS,CAAA;AAChF,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,SAAS,KAAK,CAAA;AACtD,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,SAAS,KAAK,CAAA;AAClD,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAAwB,IAAI,CAAA;AAClE,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAI,SAAS,EAAE,CAAA;AAGrD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,QAAA,CAAkC,EAAE,CAAA;AAClE,EAAA,MAAM,iBAAA,GAAoB,OAAO,cAAA,IAAkB,sBAAA;AAGnD,EAAA,MAAM,YAAA,GAAe,MAAA,CAAO,IAAA,CAAK,GAAA,EAAK,CAAA;AAEtC,EAAA,MAAM,eAAA,GAAkB,OAAO,KAAK,CAAA;AASpC,EAAA,MAAM,cAAA,GAAiB,QAAQ,MAAM,eAAA,CAAgB,MAAM,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AACtE,EAAA,MAAM,aAAA,GAAgB,QAAQ,MAAM,mBAAA,CAAoB,MAAM,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AACzE,EAAA,MAAM,SAAA,GACJ,eACC,MAAA,CAAO,MAAA,KAAW,UACf,OAAA,GACA,MAAA,CAAO,MAAA,KAAW,SAAA,GAChB,SAAA,GACA,WAAA,CAAA;AACR,EAAA,MAAM,qBACJ,CAAC,YAAA,IAAgB,gBAAgB,CAAA,IAAK,SAAA,KAAc,YAChD,SAAA,GACA,SAAA;AAMN,EAAA,MAAM,aAAA,GAAgB,gBAAA,CAAiB,MAAA,CAAO,MAAM,CAAA;AAEpD,EAAA,MAAM,EAAE,eAAA,EAAiB,aAAA,EAAc,GAAI,eAAA,CAAgB;AAAA,IACzD,QAAQ,MAAA,CAAO,EAAA;AAAA;AAAA;AAAA,IAGf,YACE,kBAAA,KAAuB,OAAA,GACnB,iBACA,kBAAA,KAAuB,WAAA,GACrB,gBACA,MAAA,CAAO;AAAA,GAChB,CAAA;AAKD,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAChC,SAA8E,IAAI,CAAA;AACpF,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,YAAA,IAAgB,CAAC,UAAA,EAAY;AAClC,IAAA,IAAI,SAAA,GAAY,KAAA;AAChB,IAAA,OAAO,gCAAmB,CAAA,CACvB,IAAA,CAAK,CAAC,CAAA,KAAM;AACX,MAAA,IAAI,CAAC,SAAA,EAAW,cAAA,CAAe,MAAM,EAAE,eAAe,CAAA;AAAA,IACxD,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AAAA,IAEb,CAAC,CAAA;AACH,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,IAAA;AAAA,IACd,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,YAAA,EAAc,UAAU,CAAC,CAAA;AAO7B,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAC9B,SAA4D,IAAI,CAAA;AAClE,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,uBAAuB,SAAA,EAAW;AACpC,MAAA,aAAA,CAAc,IAAI,CAAA;AAClB,MAAA;AAAA,IACF;AACA,IAAA,IAAI,SAAA,GAAY,KAAA;AAChB,IAAA,MAAM,OACJ,kBAAA,KAAuB,OAAA,GACnB,OAAO,0BAAa,CAAA,CAAE,KAAK,CAAC,CAAA,KAAM,EAAE,SAAS,CAAA,GAC7C,OAAO,8BAAiB,CAAA,CAAE,KAAK,CAAC,CAAA,KAAM,EAAE,aAAa,CAAA;AAC3D,IAAA,IAAA,CACG,IAAA,CAAK,CAAC,SAAA,KAAc;AAGnB,MAAA,IAAI,CAAC,SAAA,EAAW,aAAA,CAAc,MAAM,SAAS,CAAA;AAAA,IAC/C,CAAC,CAAA,CACA,KAAA,CAAM,CAAC,GAAA,KAAQ;AAEd,MAAA,OAAA,CAAQ,KAAA,CAAM,0DAA0D,GAAG,CAAA;AAAA,IAC7E,CAAC,CAAA;AACH,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,IAAA;AAAA,IACd,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,kBAAkB,CAAC,CAAA;AAGvB,EAAA,MAAM,aAAA,GAAgB,QAAQ,MAAM;AAClC,IAAA,IAAI,CAAC,OAAO,aAAA,EAAe;AACzB,MAAA,OAAO,MAAA,CAAO,UAAU,EAAC;AAAA,IAC3B;AAEA,IAAA,MAAMA,qBAAoB,MAAA,CAAO,KAAA,EAAO,KAAK,CAAA,CAAA,KAAK,CAAA,CAAE,gBAAgB,IAAI,CAAA;AACxE,IAAA,IAAI,CAACA,kBAAAA,EAAmB,OAAO,MAAA,CAAO,UAAU,EAAC;AAEjD,IAAA,OAAA,CAAQ,MAAA,CAAO,UAAU,EAAC,EAAG,OAAO,CAAA,CAAA,KAAK,CAAA,CAAE,OAAA,KAAYA,kBAAAA,CAAkB,EAAE,CAAA;AAAA,EAC7E,CAAA,EAAG,CAAC,MAAA,EAAQ,IAAI,CAAC,CAAA;AAGjB,EAAA,MAAM,cAAA,GAAiB,WAAA,CAAY,CAAC,KAAA,KAAkC;AACpE,IAAA,IAAI,CAAC,KAAA,CAAM,WAAA,EAAa,SAAA,EAAW,OAAO,IAAA;AAE1C,IAAA,MAAM,EAAE,KAAA,EAAO,SAAA,EAAW,UAAU,KAAA,EAAM,GAAI,MAAM,WAAA,CAAY,SAAA;AAChE,IAAA,MAAM,UAAA,GAAa,OAAO,SAAS,CAAA;AAEnC,IAAA,QAAQ,QAAA;AAAU,MAChB,KAAK,QAAA;AACH,QAAA,OAAO,UAAA,KAAe,KAAA;AAAA,MACxB,KAAK,YAAA;AACH,QAAA,OAAO,UAAA,KAAe,KAAA;AAAA,MACxB,KAAK,UAAA;AACH,QAAA,OAAO,OAAO,UAAU,CAAA,CAAE,QAAA,CAAS,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,MAClD,KAAK,cAAA;AACH,QAAA,OAAO,CAAC,MAAA,CAAO,UAAU,EAAE,QAAA,CAAS,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,MACnD,KAAK,UAAA;AACH,QAAA,OAAO,CAAC,cAAc,UAAA,KAAe,EAAA;AAAA,MACvC,KAAK,WAAA;AACH,QAAA,OAAO,CAAC,CAAC,UAAA,IAAc,UAAA,KAAe,EAAA;AAAA,MACxC,KAAK,cAAA;AACH,QAAA,OAAO,MAAA,CAAO,UAAU,CAAA,GAAI,MAAA,CAAO,KAAK,CAAA;AAAA,MAC1C,KAAK,WAAA;AACH,QAAA,OAAO,MAAA,CAAO,UAAU,CAAA,GAAI,MAAA,CAAO,KAAK,CAAA;AAAA,MAC1C;AACE,QAAA,OAAO,IAAA;AAAA;AACX,EACF,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAGX,EAAA,MAAM,aAAA,GAAgB,WAAA,CAAY,CAAC,KAAA,KAAwC;AACzE,IAAA,IAAI,CAAC,cAAA,CAAe,KAAK,CAAA,EAAG,OAAO,IAAA;AAEnC,IAAA,IAAI,CAAC,SAAA,EAAW,gBAAA,EAAkB,WAAA,EAAa,QAAQ,EAAE,QAAA,CAAS,KAAA,CAAM,UAAU,CAAA,EAAG,OAAO,IAAA;AAE5F,IAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA;AAC/B,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,UAAA,IAAc,EAAC;AAGnC,IAAA,IAAI,KAAA,CAAM,WAAA,KAAgB,CAAC,KAAA,IAAS,UAAU,EAAA,CAAA,EAAK;AACjD,MAAA,OAAO,KAAA,CAAM,YAAA,IAAgB,CAAA,EAAG,KAAA,CAAM,KAAK,CAAA,YAAA,CAAA;AAAA,IAC7C;AAEA,IAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AAEnB,IAAA,MAAM,QAAA,GAAW,OAAO,KAAK,CAAA;AAG7B,IAAA,IAAI,KAAA,CAAM,UAAA,IAAc,QAAA,CAAS,MAAA,GAAS,MAAM,UAAA,EAAY;AAC1D,MAAA,OAAO,CAAA,EAAG,KAAA,CAAM,KAAK,CAAA,kBAAA,EAAqB,MAAM,UAAU,CAAA,WAAA,CAAA;AAAA,IAC5D;AACA,IAAA,IAAI,KAAA,CAAM,UAAA,IAAc,QAAA,CAAS,MAAA,GAAS,MAAM,UAAA,EAAY;AAC1D,MAAA,OAAO,CAAA,EAAG,KAAA,CAAM,KAAK,CAAA,sBAAA,EAAyB,MAAM,UAAU,CAAA,WAAA,CAAA;AAAA,IAChE;AAGA,IAAA,IAAI,MAAM,GAAA,KAAQ,MAAA,IAAa,OAAO,KAAK,CAAA,GAAI,MAAM,GAAA,EAAK;AACxD,MAAA,OAAO,CAAA,EAAG,KAAA,CAAM,KAAK,CAAA,kBAAA,EAAqB,MAAM,GAAG,CAAA,CAAA;AAAA,IACrD;AACA,IAAA,IAAI,MAAM,GAAA,KAAQ,MAAA,IAAa,OAAO,KAAK,CAAA,GAAI,MAAM,GAAA,EAAK;AACxD,MAAA,OAAO,CAAA,EAAG,KAAA,CAAM,KAAK,CAAA,sBAAA,EAAyB,MAAM,GAAG,CAAA,CAAA;AAAA,IACzD;AAGA,IAAA,IAAI,MAAM,OAAA,EAAS;AACjB,MAAA,IAAI;AACF,QAAA,IAAI,CAAC,IAAI,MAAA,CAAO,KAAA,CAAM,OAAO,CAAA,CAAE,IAAA,CAAK,QAAQ,CAAA,EAAG;AAC7C,UAAA,OAAO,KAAA,CAAM,YAAA,IAAgB,CAAA,EAAG,KAAA,CAAM,KAAK,CAAA,WAAA,CAAA;AAAA,QAC7C;AAAA,MACF,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAGA,IAAA,IAAI,MAAM,UAAA,KAAe,OAAA,IAAW,CAAC,4BAAA,CAA6B,IAAA,CAAK,QAAQ,CAAA,EAAG;AAChF,MAAA,OAAO,oCAAA;AAAA,IACT;AAGA,IAAA,IAAI,MAAM,UAAA,KAAe,OAAA,IAAW,CAAC,mBAAA,CAAoB,IAAA,CAAK,QAAQ,CAAA,EAAG;AACvE,MAAA,OAAO,mCAAA;AAAA,IACT;AAEA,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,EAAG,CAAC,MAAA,EAAQ,cAAc,CAAC,CAAA;AAG3B,EAAA,MAAM,eAAA,GAAkB,WAAA,CAAY,CAAC,KAAA,KAAkC;AACrE,IAAA,IAAI,CAAC,cAAA,CAAe,KAAK,CAAA,EAAG,OAAO,KAAA;AACnC,IAAA,IAAI,CAAC,SAAA,EAAW,gBAAA,EAAkB,WAAA,EAAa,QAAQ,EAAE,QAAA,CAAS,KAAA,CAAM,UAAU,CAAA,EAAG,OAAO,KAAA;AAC5F,IAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA;AAC/B,IAAA,IAAI,UAAU,MAAA,IAAa,KAAA,KAAU,IAAA,IAAQ,KAAA,KAAU,IAAI,OAAO,KAAA;AAClE,IAAA,OAAO,aAAA,CAAc,KAAK,CAAA,KAAM,IAAA;AAAA,EAClC,CAAA,EAAG,CAAC,MAAA,EAAQ,cAAA,EAAgB,aAAa,CAAC,CAAA;AAE1C,EAAA,MAAM,QAAA,GAAW,QAAQ,MAAM;AAC7B,IAAA,MAAM,UAAA,GAAA,CAAc,MAAA,CAAO,MAAA,IAAU,EAAC,EAAG,MAAA;AAAA,MACvC,CAAA,CAAA,KAAK,CAAA,CAAE,WAAA,IAAe,cAAA,CAAe,CAAC,CAAA,IAAK,CAAC,CAAC,SAAA,EAAW,kBAAkB,WAAA,EAAa,QAAQ,CAAA,CAAE,QAAA,CAAS,EAAE,UAAU;AAAA,KACxH;AACA,IAAA,OAAO,EAAE,MAAM,UAAA,CAAW,MAAA,CAAO,eAAe,CAAA,CAAE,MAAA,EAAQ,KAAA,EAAO,UAAA,CAAW,MAAA,EAAO;AAAA,EACrF,CAAA,EAAG,CAAC,MAAA,EAAQ,cAAA,EAAgB,eAAe,CAAC,CAAA;AAG5C,EAAA,MAAM,YAAA,GAAe,YAAY,MAAe;AAC9C,IAAA,MAAM,YAAoC,EAAC;AAE3C,IAAA,KAAA,MAAW,SAAS,aAAA,EAAe;AACjC,MAAA,MAAM,KAAA,GAAQ,cAAc,KAAK,CAAA;AACjC,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,SAAA,CAAU,KAAA,CAAM,IAAI,CAAA,GAAI,KAAA;AAAA,MAC1B;AAAA,IACF;AAEA,IAAA,SAAA,CAAU,SAAS,CAAA;AACnB,IAAA,OAAO,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA,CAAE,MAAA,KAAW,CAAA;AAAA,EAC3C,CAAA,EAAG,CAAC,aAAA,EAAe,aAAa,CAAC,CAAA;AAKjC,EAAA,MAAM,WAAA,GAAc,YAAY,MAAsD;AACpF,IAAA,MAAM,SAAA,GAAY,MAAA,CAAO,MAAA,IAAU,EAAC;AACpC,IAAA,MAAM,YAAoC,EAAC;AAC3C,IAAA,KAAA,MAAW,SAAS,SAAA,EAAW;AAC7B,MAAA,MAAM,KAAA,GAAQ,cAAc,KAAK,CAAA;AACjC,MAAA,IAAI,KAAA,EAAO,SAAA,CAAU,KAAA,CAAM,IAAI,CAAA,GAAI,KAAA;AAAA,IACrC;AACA,IAAA,SAAA,CAAU,SAAS,CAAA;AACnB,IAAA,IAAI,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA,CAAE,MAAA,KAAW,CAAA,EAAG,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,cAAA,EAAgB,IAAA,EAAK;AAEjF,IAAA,IAAI,cAAA,GAAgC,IAAA;AACpC,IAAA,IAAI,MAAA,CAAO,aAAA,IAAiB,MAAA,CAAO,KAAA,EAAO;AACxC,MAAA,MAAM,OAAA,GAAU,CAAC,GAAG,MAAA,CAAO,KAAK,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,WAAA,GAAc,EAAE,WAAW,CAAA;AAC9E,MAAA,KAAA,MAAW,KAAK,OAAA,EAAS;AACvB,QAAA,IAAI,SAAA,CAAU,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAA,KAAY,CAAA,CAAE,EAAA,IAAM,SAAA,CAAU,CAAA,CAAE,IAAI,CAAC,CAAA,EAAG;AAClE,UAAA,cAAA,GAAiB,CAAA,CAAE,WAAA;AACnB,UAAA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,cAAA,EAAe;AAAA,EACrC,CAAA,EAAG,CAAC,MAAA,EAAQ,aAAa,CAAC,CAAA;AAI1B,EAAA,MAAM,kBAAA,GAAqB,YAAY,MAA+B;AACpE,IAAA,MAAM,MAA+B,EAAC;AACtC,IAAA,KAAA,MAAW,KAAA,IAAS,MAAA,CAAO,MAAA,IAAU,EAAC,EAAG;AACvC,MAAA,IAAI,CAAC,cAAA,CAAe,KAAK,CAAA,EAAG;AAC5B,MAAA,IAAI,KAAA,CAAM,QAAQ,MAAA,EAAQ,GAAA,CAAI,MAAM,IAAI,CAAA,GAAI,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA;AAAA,IAC/D;AACA,IAAA,OAAO,GAAA;AAAA,EACT,CAAA,EAAG,CAAC,MAAA,EAAQ,MAAA,EAAQ,cAAc,CAAC,CAAA;AAGnC,EAAA,MAAM,aAAA,GAAgB,WAAA,CAAY,CAAC,GAAA,EAAa,KAAA,KAAmB;AACjE,IAAA,UAAA,CAAW,CAAA,IAAA,KAAS,IAAA,CAAK,GAAG,CAAA,GAAI,IAAA,GAAO,EAAE,GAAG,IAAA,EAAM,CAAC,GAAG,GAAG,IAAA,EAAO,CAAA;AAChE,IAAA,SAAA,CAAU,CAAA,IAAA,MAAS,EAAE,GAAG,IAAA,EAAM,CAAC,GAAG,GAAG,OAAM,CAAE,CAAA;AAE7C,IAAA,IAAI,MAAA,CAAO,GAAG,CAAA,EAAG;AACf,MAAA,SAAA,CAAU,CAAA,IAAA,KAAQ;AAChB,QAAA,MAAM,IAAA,GAAO,EAAE,GAAG,IAAA,EAAK;AACvB,QAAA,OAAO,KAAK,GAAG,CAAA;AACf,QAAA,OAAO,IAAA;AAAA,MACT,CAAC,CAAA;AAAA,IACH;AAAA,EACF,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAGX,EAAA,MAAM,QAAA,GAAW,YAAY,MAAe;AAC1C,IAAA,IAAI,CAAC,YAAA,EAAa,EAAG,OAAO,KAAA;AAE5B,IAAA,IAAI,IAAA,GAAO,OAAO,WAAA,EAAa;AAC7B,MAAA,MAAM,UAAU,IAAA,GAAO,CAAA;AACvB,MAAA,gBAAA,CAAiB,SAAS,CAAA;AAC1B,MAAA,OAAA,CAAQ,OAAO,CAAA;AACf,MAAA,eAAA,CAAgB,OAAO,CAAA;AACvB,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,OAAO,KAAA;AAAA,EACT,GAAG,CAAC,IAAA,EAAM,OAAO,WAAA,EAAa,YAAA,EAAc,eAAe,CAAC,CAAA;AAE5D,EAAA,MAAM,QAAA,GAAW,YAAY,MAAM;AACjC,IAAA,IAAI,OAAO,CAAA,EAAG;AACZ,MAAA,MAAM,UAAU,IAAA,GAAO,CAAA;AACvB,MAAA,gBAAA,CAAiB,MAAM,CAAA;AACvB,MAAA,OAAA,CAAQ,OAAO,CAAA;AACf,MAAA,eAAA,CAAgB,OAAO,CAAA;AAAA,IACzB;AAAA,EACF,CAAA,EAAG,CAAC,IAAA,EAAM,eAAe,CAAC,CAAA;AAE1B,EAAA,MAAM,QAAA,GAAW,WAAA,CAAY,CAAC,UAAA,KAAuB;AACnD,IAAA,IAAI,UAAA,IAAc,CAAA,IAAK,UAAA,IAAc,MAAA,CAAO,WAAA,EAAa;AACvD,MAAA,gBAAA,CAAiB,UAAA,GAAa,IAAA,GAAO,MAAA,GAAS,SAAS,CAAA;AACvD,MAAA,OAAA,CAAQ,UAAU,CAAA;AAClB,MAAA,eAAA,CAAgB,UAAU,CAAA;AAAA,IAC5B;AAAA,EACF,GAAG,CAAC,IAAA,EAAM,MAAA,CAAO,WAAA,EAAa,eAAe,CAAC,CAAA;AAG9C,EAAA,MAAM,MAAA,GAAS,YAAY,YAAY;AAGrC,IAAA,IAAI,gBAAgB,OAAA,EAAS;AAE7B,IAAA,MAAM,EAAE,EAAA,EAAI,cAAA,EAAe,GAAI,WAAA,EAAY;AAC3C,IAAA,IAAI,CAAC,EAAA,EAAI;AACP,MAAA,IAAI,kBAAkB,IAAA,EAAM;AAC1B,QAAA,gBAAA,CAAiB,MAAM,CAAA;AACvB,QAAA,OAAA,CAAQ,cAAc,CAAA;AAAA,MACxB;AACA,MAAA;AAAA,IACF;AAEA,IAAA,eAAA,CAAgB,OAAA,GAAU,IAAA;AAC1B,IAAA,eAAA,CAAgB,IAAI,CAAA;AACpB,IAAA,cAAA,CAAe,IAAI,CAAA;AAEnB,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,MAAM,UAAA,CAAW;AAAA,QAC5B,MAAA;AAAA,QACA,QAAQ,kBAAA,EAAmB;AAAA,QAC3B,aAAA,EAAe,MAAA,CAAO,gBAAA,GAAmB,aAAA,GAAgB,EAAA;AAAA,QACzD,cAAc,YAAA,CAAa;AAAA,OAC5B,CAAA;AAED,MAAA,aAAA,EAAc;AACd,MAAA,aAAA,CAAc,IAAI,CAAA;AAClB,MAAA,SAAA,GAAY,IAAsB,CAAA;AAElC,MAAA,IAAI,OAAO,YAAA,EAAc;AACvB,QAAA,MAAA,CAAO,QAAA,CAAS,OAAO,MAAA,CAAO,YAAA;AAAA,MAChC;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,6BAA6B,KAAK,CAAA;AAChD,MAAA,cAAA,CAAe,iEAAiE,CAAA;AAChF,MAAA,OAAA,GAAU,KAAc,CAAA;AAAA,IAC1B,CAAA,SAAE;AACA,MAAA,eAAA,CAAgB,OAAA,GAAU,KAAA;AAC1B,MAAA,eAAA,CAAgB,KAAK,CAAA;AAAA,IACvB;AAAA,EACF,CAAA,EAAG,CAAC,MAAA,EAAQ,aAAA,EAAe,aAAa,kBAAA,EAAoB,aAAA,EAAe,SAAA,EAAW,OAAO,CAAC,CAAA;AAG9F,EAAA,MAAM,QAAA,GAAW,QAAQ,MAAM;AAC7B,IAAA,OAAO,IAAA,CAAK,KAAA,CAAO,IAAA,GAAO,MAAA,CAAO,cAAe,GAAG,CAAA;AAAA,EACrD,CAAA,EAAG,CAAC,IAAA,EAAM,MAAA,CAAO,WAAW,CAAC,CAAA;AAI7B,EAAA,MAAM,iBAAA,GAAoB,OAAA;AAAA,IACxB,MAAM,OAAO,KAAA,EAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,gBAAgB,IAAI,CAAA;AAAA,IACtD,CAAC,MAAA,CAAO,KAAA,EAAO,IAAI;AAAA,GACrB;AAKA,EAAA,MAAM,YAAA,GAAe,OAA8B,IAAI,CAAA;AACvD,EAAA,MAAM,eAAA,GAAkB,OAAO,KAAK,CAAA;AACpC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAO,aAAA,EAAe;AAC3B,IAAA,IAAI,CAAC,gBAAgB,OAAA,EAAS;AAC5B,MAAA,eAAA,CAAgB,OAAA,GAAU,IAAA;AAC1B,MAAA;AAAA,IACF;AACA,IAAA,YAAA,CAAa,SAAS,KAAA,EAAM;AAAA,EAC9B,CAAA,EAAG,CAAC,IAAA,EAAM,MAAA,CAAO,aAAa,CAAC,CAAA;AAI/B,EAAA,MAAM,WAAA,GAA+B;AAAA,IACnC,MAAA;AAAA,IACA,MAAA,EAAQ,aAAA;AAAA,IACR,IAAA;AAAA,IACA,YAAY,MAAA,CAAO,WAAA;AAAA,IACnB,MAAA;AAAA,IACA,MAAA;AAAA,IACA,YAAA;AAAA,IACA,QAAA;AAAA,IACA,QAAA;AAAA,IACA,QAAA;AAAA,IACA,QAAA;AAAA,IACA,MAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACF;AAGA,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,MAAM,MAAM,MAAA,CAAO,eAAA;AACnB,IAAA,MAAM,OAAA,GACJ,OAAO,GAAA,KAAQ,QAAA,IAAY,GAAA,CAAI,IAAA,EAAK,CAAE,MAAA,GAAS,CAAA,GAC3C,GAAA,CAAI,IAAA,EAAK,GACT,4BAAA;AAON,IAAA,IAAI,WAAA,EAAa,uBAAO,GAAA,CAAC,WAAA,EAAA,EAAY,SAAkB,SAAA,EAAsB,CAAA;AAC7E,IAAA,uBACE,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAsB,cAAA,EAAa,sBAAA,EAAuB,MAAK,QAAA,EAClE,QAAA,kBAAA,GAAA,CAAC,GAAA,EAAA,EAAG,QAAA,EAAA,OAAA,EAAQ,CAAA,EACd,CAAA;AAAA,EAEJ;AAGA,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,uBAAO,GAAA,CAAA,QAAA,EAAA,EAAG,QAAA,EAAA,YAAA,CAAa,WAAW,CAAA,EAAE,CAAA;AAAA,EACtC;AAKA,EAAA,IAAI,kBAAA,KAAuB,aAAa,UAAA,EAAY;AAClD,IAAA,MAAM,MAAA,GAAgC;AAAA,MACpC,MAAA;AAAA,MACA,MAAA;AAAA,MACA,MAAA;AAAA,MACA,OAAA;AAAA,MACA,YAAA;AAAA,MACA,WAAA;AAAA,MACA,QAAA;AAAA,MACA,SAAA;AAAA,MACA,aAAA;AAAA,MACA,aAAA;AAAA,MACA,cAAA;AAAA,MACA,eAAA;AAAA,MACA,eAAA,EAAiB,CAAC,IAAA,EAAM,OAAA,KACtB,UAAU,CAAC,IAAA,MAAU,EAAE,GAAG,IAAA,EAAM,CAAC,IAAI,GAAG,SAAQ,CAAE,CAAA;AAAA,MACpD,MAAA;AAAA,MACA,eAAA;AAAA,MACA,QAAA,EAAU,OAAO,gBAAA,mBACf,GAAA;AAAA,QAAC,aAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAM,iBAAA;AAAA,UACN,KAAA,EAAO,aAAA;AAAA,UACP,QAAA,EAAU;AAAA;AAAA,OACZ,GACE;AAAA,KACN;AACA,IAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,aAAA,EAAA,EAAc,CAAA;AAAA,sBACf,GAAA,CAAC,UAAA,EAAA,EAAY,GAAG,MAAA,EAAQ;AAAA,KAAA,EAC1B,CAAA;AAAA,EAEJ;AAGA,EAAA,uBACE,IAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MAAK,eAAA,EAAe,eAAe,YAAA,GAAe,MAAA;AAAA,MAGjD,eAAA,EACE,QAAA,CAAS,KAAA,GAAQ,CAAA,IAAK,QAAA,CAAS,IAAA,IAAQ,QAAA,CAAS,KAAA,IAAS,IAAA,IAAQ,MAAA,CAAO,WAAA,GACpE,MAAA,GACA,MAAA;AAAA,MAEN,SAAA,EAAW,CAAA,QAAA,EAAW,SAAA,IAAa,EAAE,CAAA,CAAA;AAAA,MAGpC,GAAG,gBAAgB,MAAM,CAAA;AAAA,MAC1B,QAAA,EAAU,CAAC,CAAA,KAAM;AACf,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,IAAI,IAAA,GAAO,OAAO,WAAA,EAAa;AAC7B,UAAA,QAAA,EAAS;AAAA,QACX,CAAA,MAAO;AACL,UAAA,MAAA,EAAO;AAAA,QACT;AAAA,MACF,CAAA;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,aAAA,EAAA,EAAc,CAAA;AAAA,4BACd,YAAA,EAAA,EAAa,IAAA,EAAM,SAAS,IAAA,EAAM,KAAA,EAAO,SAAS,KAAA,EAAO,CAAA;AAAA,QAEzD,MAAA,CAAO,aAAA,oBACN,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,mBAAA,EACb,QAAA,EAAA;AAAA,0BAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,0BAAA,EACb,QAAA,EAAA;AAAA,4BAAA,IAAA,CAAC,MAAA,EAAA,EAAK,WAAU,wBAAA,EAAyB,QAAA,EAAA;AAAA,cAAA,OAAA;AAAA,cACjC,IAAA;AAAA,cAAK,MAAA;AAAA,cAAK,MAAA,CAAO;AAAA,aAAA,EACzB,CAAA;AAAA,YAGC,MAAA,CAAO,aAAA,oBACN,IAAA,CAAC,MAAA,EAAA,EAAK,WAAU,2BAAA,EAA6B,QAAA,EAAA;AAAA,cAAA,QAAA;AAAA,cAAS;AAAA,aAAA,EAAC;AAAA,WAAA,EAE3D,CAAA;AAAA,0BACA,GAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAU,yBAAA;AAAA,cACV,IAAA,EAAK,aAAA;AAAA,cACL,eAAA,EAAe,CAAA;AAAA,cACf,iBAAe,MAAA,CAAO,WAAA;AAAA,cACtB,eAAA,EAAe,IAAA;AAAA,cACf,gBAAA,EAAgB,CAAA,KAAA,EAAQ,IAAI,CAAA,IAAA,EAAO,OAAO,WAAW,CAAA,CAAA;AAAA,cAErD,QAAA,kBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uBAAA,EAAwB,KAAA,EAAO,EAAE,KAAA,EAAO,CAAA,EAAG,QAAQ,CAAA,CAAA,CAAA,EAAI,EAAG;AAAA;AAAA,WAC3E;AAAA,0BACA,GAAA,CAAC,QAAG,SAAA,EAAU,wBAAA,EAAyB,eAAY,MAAA,EAChD,QAAA,EAAA,KAAA,CAAM,KAAK,EAAE,MAAA,EAAQ,OAAO,WAAA,EAAY,EAAG,CAAC,CAAA,EAAG,CAAA,KAAM,IAAI,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,qBAChE,GAAA;AAAA,YAAC,IAAA;AAAA,YAAA;AAAA,cAEC,SAAA,EACE,2BACC,CAAA,KAAM,IAAA,GAAO,oCAAoC,EAAA,CAAA,IACjD,CAAA,GAAI,OAAO,8BAAA,GAAiC,EAAA;AAAA,aAAA;AAAA,YAJ1C;AAAA,WAOR,CAAA,EACH;AAAA,SAAA,EACF,CAAA;AAAA,wBAIF,IAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YAEC,GAAA,EAAK,YAAA;AAAA,YACL,QAAA,EAAU,EAAA;AAAA,YACV,WACE,eAAA,IACC,MAAA,CAAO,aAAA,GAAgB,CAAA,gBAAA,EAAmB,aAAa,CAAA,CAAA,GAAK,EAAA,CAAA;AAAA,YAG9D,QAAA,EAAA;AAAA,cAAA,MAAA,CAAO,aAAA,KAAkB,mBAAmB,KAAA,IAAS,iBAAA,EAAmB,gCACvE,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,qBAAA,EACZ,QAAA,EAAA;AAAA,gBAAA,iBAAA,CAAkB,yBACjB,GAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,qBAAA,EAAuB,4BAAkB,KAAA,EAAM,CAAA;AAAA,gBAE9D,kBAAkB,WAAA,oBACjB,GAAA,CAAC,OAAE,SAAA,EAAU,2BAAA,EAA6B,4BAAkB,WAAA,EAAY;AAAA,eAAA,EAE5E,CAAA;AAAA,kCAGD,KAAA,EAAA,EAAI,SAAA,EAAU,mBACZ,QAAA,EAAA,aAAA,CAAc,GAAA,CAAI,CAAC,KAAA,KAAU;AAC5B,gBAAA,IAAI,CAAC,cAAA,CAAe,KAAK,CAAA,EAAG,OAAO,IAAA;AAEnC,gBAAA,2BACG,KAAA,EAAA,EAAmB,SAAA,EAAW,kDAAkD,KAAA,CAAM,KAAA,IAAS,MAAM,CAAA,CAAA,EACpG,QAAA,kBAAA,GAAA;AAAA,kBAAC,SAAA;AAAA,kBAAA;AAAA,oBACC,KAAA;AAAA,oBACA,KAAA,EAAO,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA;AAAA,oBACxB,KAAA,EAAO,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA;AAAA,oBACxB,SAAA,EAAW,CAAC,CAAC,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAA,IAAK,CAAC,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA,IAAK,gBAAgB,KAAK,CAAA;AAAA,oBAChF,UAAU,CAAC,KAAA,KAAU,aAAA,CAAc,KAAA,CAAM,MAAM,KAAK,CAAA;AAAA,oBACpD,QAAA,EAAU;AAAA;AAAA,iBACZ,EAAA,EARQ,MAAM,EAShB,CAAA;AAAA,cAEJ,CAAC,CAAA,EACH;AAAA;AAAA,WAAA;AAAA,UApCK;AAAA,SAqCP;AAAA,wBAGA,IAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,kBAAA;AAAA,YACV,OAAO,EAAE,cAAA,EAAgB,IAAA,GAAO,CAAA,GAAI,kBAAkB,UAAA,EAAW;AAAA,YAEhE,QAAA,EAAA;AAAA,cAAA,IAAA,GAAO,CAAA,wBACL,QAAA,EAAA,EAAO,IAAA,EAAK,UAAS,SAAA,EAAU,iCAAA,EAAkC,OAAA,EAAS,QAAA,EAAU,QAAA,EAAA,MAAA,EAErF,CAAA;AAAA,8BAEF,GAAA,CAAC,QAAA,EAAA,EAAO,IAAA,EAAK,QAAA,EAAS,WAAU,mCAAA,EAAoC,QAAA,EAAU,YAAA,EAC3E,QAAA,EAAA,YAAA,GACG,kBACA,IAAA,GAAO,MAAA,CAAO,WAAA,GACZ,MAAA,GACA,OAAO,kBAAA,EAEf;AAAA;AAAA;AAAA,SACF;AAAA,QAEC,WAAA,oBACC,GAAA;AAAA,UAAC,GAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,uBAAA;AAAA,YACV,IAAA,EAAK,OAAA;AAAA,YACL,OAAO,EAAE,KAAA,EAAO,4BAA4B,QAAA,EAAU,EAAA,EAAI,WAAW,EAAA,EAAG;AAAA,YAEvE,QAAA,EAAA;AAAA;AAAA,SACH;AAAA,QAKD,OAAO,gBAAA,oBACN,GAAA;AAAA,UAAC,aAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAM,iBAAA;AAAA,YACN,KAAA,EAAO,aAAA;AAAA,YACP,QAAA,EAAU;AAAA;AAAA,SACZ;AAAA,wBAIF,GAAA,CAAC,oBAAA,EAAA,EAAqB,MAAA,EAAgB,QAAA,EAAU,cAAA,EAAgB;AAAA;AAAA;AAAA,GAClE;AAEJ;ACzqBO,SAAS,WAAA,CAAY;AAAA,EAC1B,MAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA;AAAA,EACA,aAAA;AAAA,EACA,UAAA;AAAA,EACA,cAAA;AAAA,EACA,aAAA;AAAA,EACA;AACF,CAAA,EAAqB;AACnB,EAAA,MAAM;AAAA,IACJ,IAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACF,GAAI,QAAQ,MAAA,EAAQ;AAAA,IAClB,SAAA;AAAA,IACA,SAAA;AAAA,IACA,OAAA;AAAA,IACA,WAAA,EAAa,aAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUb,cAAA,EAAgB;AAAA,GACjB,CAAA;AAED,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,uBACEC,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EACH,QAAA,kBAAAA,GAAAA,CAAC,GAAA,EAAA,EAAE,KAAA,EAAO,EAAE,KAAA,EAAO,SAAA,EAAU,EAAG,6BAAe,CAAA,EACjD,CAAA;AAAA,EAEJ;AAEA,EAAA,IAAI,UAAA,IAAc,CAAC,IAAA,EAAM;AACvB,IAAA,uBACEA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EACH,0BAAAA,GAAAA,CAAC,GAAA,EAAA,EAAE,KAAA,EAAO,EAAE,OAAO,0BAAA,EAA2B,EAC3C,QAAA,EAAA,UAAA,EAAY,OAAA,IAAW,+BAC1B,CAAA,EACF,CAAA;AAAA,EAEJ;AAGA,EAAA,uBACEA,GAAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,MAAA,EAAQ,IAAA;AAAA,MACR,SAAA;AAAA,MACA,SAAA;AAAA,MACA,OAAA;AAAA,MACA,YAAA,EAAc,QAAA;AAAA,MACd,UAAA;AAAA,MACA,cAAA;AAAA,MACA;AAAA;AAAA,GACF;AAEJ","file":"chunk-TY3BPHTE.mjs","sourcesContent":["/**\n * @sonordev/site-kit/forms - Form Client Component\n * \n * Handles form state, validation, and submission\n */\n\n'use client'\n\nimport React, { useState, useCallback, useMemo, useRef, useEffect } from 'react'\nimport { useFormTracking } from './useFormTracking'\nimport { FormField } from './FormField'\nimport { submitForm, DEFAULT_HONEYPOT_FIELD } from './submitForm'\nimport type { \n ManagedFormConfig, \n FormField as FormFieldType, \n FormRenderProps,\n FormSubmission,\n} from './types'\nimport { DEFAULT_FORM_SUCCESS_MESSAGE } from './defaultSuccessMessage'\nimport { DelightStyles, FormMomentum } from './delight'\nimport { HoneypotField } from './HoneypotField'\nimport { useFieldControls } from './field-controls'\nimport { nativeFormProps, NativeFallbackFields } from './native-fallback'\nimport { countStageViews, countStageQuestions } from './experience-plan'\nimport type { ExperienceRenderProps, FormExperience } from './types'\n\ninterface FormClientProps {\n config: ManagedFormConfig\n className?: string\n onSuccess?: (submission: FormSubmission) => void\n onError?: (error: Error) => void\n customRender?: (props: FormRenderProps) => React.ReactNode\n /**\n * Pre-fill field values by slug. For context the page already has and the\n * visitor should not retype: an email captured earlier in a conversation,\n * the service they were reading about, an estimate the assistant just\n * produced. Applied ON TOP of each field's configured default_value.\n *\n * Unknown slugs are ignored, so a stale key cannot break the form.\n */\n defaultValues?: Record<string, unknown>\n /**\n * Which rendering the form gets. Defaults to the form's `layout` config\n * (`layout: 'stage'` in Sonor flips a form to stage with no site deploy),\n * else 'classic'. customRender always wins over this.\n */\n experience?: FormExperience\n /** Absolute page URL for the no-JS 303 to land on (see native-fallback). */\n nativeReturnTo?: string\n}\n\nexport function FormClient({\n config,\n className,\n onSuccess,\n onError,\n customRender,\n experience,\n nativeReturnTo,\n defaultValues,\n}: FormClientProps) {\n // Seed default_value fields once (lazy initializer — config is stable for\n // the life of this mount; ManagedForm only renders us once it has a form).\n const [values, setValues] = useState<Record<string, unknown>>(() => {\n const defaults: Record<string, unknown> = {}\n for (const field of config.fields || []) {\n if (field.default_value !== undefined && field.default_value !== null) {\n defaults[field.slug] = field.default_value\n }\n }\n // Caller-supplied values win over the form's configured defaults — they\n // are per-visitor context (what Echo already knows about this person,\n // the service they were reading about) rather than form configuration.\n return { ...defaults, ...(defaultValues || {}) }\n })\n const [errors, setErrors] = useState<Record<string, string>>({})\n const [step, setStep] = useState(1)\n // Direction of the last step change, so the transition slides the way the\n // user is travelling ('forward' on Next, 'back' on Back).\n const [stepDirection, setStepDirection] = useState<'forward' | 'back'>('forward')\n const [isSubmitting, setIsSubmitting] = useState(false)\n const [isComplete, setIsComplete] = useState(false)\n const [submitError, setSubmitError] = useState<string | null>(null)\n const [honeypotValue, setHoneypotValue] = useState('')\n // Fields the user has interacted with — the valid tick only appears after\n // real input (never on pristine fields), so it reads as earned feedback.\n const [touched, setTouched] = useState<Record<string, boolean>>({})\n const honeypotFieldName = config.honeypot_field || DEFAULT_HONEYPOT_FIELD\n\n // Anti-bot: record when form first rendered (bots submit in < 3 seconds)\n const formLoadedAt = useRef(Date.now())\n // Synchronous guard against a concurrent double-submit (Enter + click, etc.).\n const isSubmittingRef = useRef(false)\n\n // Resolve the experience: explicit prop > form config > SPOTLIGHT.\n //\n // Spotlight is the 4.0 default: every managed form converses back unless it\n // opts out. Opting out is `experience=\"classic\"` on the component or\n // `layout: 'classic'` in Sonor (forms are data, so either side can decide\n // with no deploy from the other). customRender always wins, and a form with\n // no answerable fields has nothing to perform, so it falls back to classic.\n const stageBeatCount = useMemo(() => countStageViews(config), [config])\n const questionCount = useMemo(() => countStageQuestions(config), [config])\n const requested: FormExperience =\n experience ??\n (config.layout === 'stage'\n ? 'stage'\n : config.layout === 'classic'\n ? 'classic'\n : 'spotlight')\n const resolvedExperience: FormExperience =\n !customRender && questionCount > 0 && requested !== 'classic'\n ? requested\n : 'classic'\n\n // Date/file controls are fetched only when the form actually has such a\n // field — most forms have neither, and the date picker alone was ~5 KB\n // gzipped in every forms bundle. Until a chunk lands (and for SSR/no-JS),\n // FormField renders the native control, which submits the same value.\n const fieldControls = useFieldControls(config.fields)\n\n const { trackStepChange, trackComplete } = useFormTracking({\n formId: config.id,\n // Alternate experiences report their unit (beat / field index) as the\n // step — form_analytics becomes a drop-off funnel with zero API changes.\n totalSteps:\n resolvedExperience === 'stage'\n ? stageBeatCount\n : resolvedExperience === 'spotlight'\n ? questionCount\n : config.total_steps,\n })\n\n // The celebration is fetched as soon as the user starts submitting, so the\n // chunk arrives during the network round-trip and the payoff still feels\n // instant — without putting its markup and CSS in every form's bundle.\n const [Celebration, setCelebration] =\n useState<React.ComponentType<{ message: string; className?: string }> | null>(null)\n useEffect(() => {\n if (!isSubmitting && !isComplete) return\n let cancelled = false\n import('./FormCelebration')\n .then((m) => {\n if (!cancelled) setCelebration(() => m.FormCelebration)\n })\n .catch(() => {\n // Stays null — the plain confirmation message renders instead.\n })\n return () => {\n cancelled = true\n }\n }, [isSubmitting, isComplete])\n\n // Experience components load on demand, so a classic form (the fleet\n // default) never downloads stage/spotlight code or their stylesheets.\n // Until the chunk lands — and for SSR and no-JS — the CLASSIC form renders:\n // a complete, working, submittable form. The experience is progressive\n // enhancement layered on top, never a prerequisite for capturing the lead.\n const [Experience, setExperience] =\n useState<React.ComponentType<ExperienceRenderProps> | null>(null)\n useEffect(() => {\n if (resolvedExperience === 'classic') {\n setExperience(null)\n return\n }\n let cancelled = false\n const load =\n resolvedExperience === 'stage'\n ? import('./FormStage').then((m) => m.FormStage)\n : import('./FormSpotlight').then((m) => m.FormSpotlight)\n load\n .then((Component) => {\n // setState with a component value needs the updater form, or React\n // would call it as a lazy initializer.\n if (!cancelled) setExperience(() => Component)\n })\n .catch((err) => {\n // Chunk failed (offline, cache miss, CDN hiccup): stay on classic.\n console.error('[Forms] Experience failed to load; using classic form:', err)\n })\n return () => {\n cancelled = true\n }\n }, [resolvedExperience])\n \n // Get fields for current step\n const currentFields = useMemo(() => {\n if (!config.is_multi_step) {\n return config.fields || []\n }\n \n const currentStepConfig = config.steps?.find(s => s.step_number === step)\n if (!currentStepConfig) return config.fields || []\n \n return (config.fields || []).filter(f => f.step_id === currentStepConfig.id)\n }, [config, step])\n \n // Check if field is visible (conditional logic)\n const isFieldVisible = useCallback((field: FormFieldType): boolean => {\n if (!field.conditional?.show_when) return true\n \n const { field: condField, operator, value } = field.conditional.show_when\n const fieldValue = values[condField]\n \n switch (operator) {\n case 'equals':\n return fieldValue === value\n case 'not_equals':\n return fieldValue !== value\n case 'contains':\n return String(fieldValue).includes(String(value))\n case 'not_contains':\n return !String(fieldValue).includes(String(value))\n case 'is_empty':\n return !fieldValue || fieldValue === ''\n case 'not_empty':\n return !!fieldValue && fieldValue !== ''\n case 'greater_than':\n return Number(fieldValue) > Number(value)\n case 'less_than':\n return Number(fieldValue) < Number(value)\n default:\n return true\n }\n }, [values])\n \n // Validate field\n const validateField = useCallback((field: FormFieldType): string | null => {\n if (!isFieldVisible(field)) return null\n // Skip display-only field types\n if (['heading', 'section_header', 'paragraph', 'hidden'].includes(field.field_type)) return null\n \n const value = values[field.slug]\n const rules = field.validation || {}\n \n // Required check\n if (field.is_required && (!value || value === '')) {\n return rules.custom_error || `${field.label} is required`\n }\n \n if (!value) return null\n \n const strValue = String(value)\n \n // Length checks\n if (rules.min_length && strValue.length < rules.min_length) {\n return `${field.label} must be at least ${rules.min_length} characters`\n }\n if (rules.max_length && strValue.length > rules.max_length) {\n return `${field.label} must be no more than ${rules.max_length} characters`\n }\n \n // Numeric checks\n if (rules.min !== undefined && Number(value) < rules.min) {\n return `${field.label} must be at least ${rules.min}`\n }\n if (rules.max !== undefined && Number(value) > rules.max) {\n return `${field.label} must be no more than ${rules.max}`\n }\n \n // Pattern check — guard against an invalid admin-entered pattern.\n if (rules.pattern) {\n try {\n if (!new RegExp(rules.pattern).test(strValue)) {\n return rules.custom_error || `${field.label} is invalid`\n }\n } catch {\n // Malformed pattern — skip rather than crashing the whole form render.\n }\n }\n \n // Email check\n if (field.field_type === 'email' && !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(strValue)) {\n return 'Please enter a valid email address'\n }\n \n // Phone check\n if (field.field_type === 'phone' && !/^[\\d\\s\\-\\+\\(\\)]+$/.test(strValue)) {\n return 'Please enter a valid phone number'\n }\n \n return null\n }, [values, isFieldVisible])\n \n // Delight: per-field validity for the tick + fields-completed momentum.\n const fieldIsComplete = useCallback((field: FormFieldType): boolean => {\n if (!isFieldVisible(field)) return false\n if (['heading', 'section_header', 'paragraph', 'hidden'].includes(field.field_type)) return false\n const value = values[field.slug]\n if (value === undefined || value === null || value === '') return false\n return validateField(field) === null\n }, [values, isFieldVisible, validateField])\n\n const momentum = useMemo(() => {\n const measurable = (config.fields || []).filter(\n f => f.is_required && isFieldVisible(f) && !['heading', 'section_header', 'paragraph', 'hidden'].includes(f.field_type),\n )\n return { done: measurable.filter(fieldIsComplete).length, total: measurable.length }\n }, [config, isFieldVisible, fieldIsComplete])\n\n // Validate current step\n const validateStep = useCallback((): boolean => {\n const newErrors: Record<string, string> = {}\n \n for (const field of currentFields) {\n const error = validateField(field)\n if (error) {\n newErrors[field.slug] = error\n }\n }\n \n setErrors(newErrors)\n return Object.keys(newErrors).length === 0\n }, [currentFields, validateField])\n\n // Validate EVERY field across all steps — used on final submit so a required\n // field left empty on an earlier step cannot slip through. Returns the first\n // step containing an error so the user can be taken straight to it.\n const validateAll = useCallback((): { ok: boolean; firstErrorStep: number | null } => {\n const allFields = config.fields || []\n const newErrors: Record<string, string> = {}\n for (const field of allFields) {\n const error = validateField(field)\n if (error) newErrors[field.slug] = error\n }\n setErrors(newErrors)\n if (Object.keys(newErrors).length === 0) return { ok: true, firstErrorStep: null }\n\n let firstErrorStep: number | null = null\n if (config.is_multi_step && config.steps) {\n const ordered = [...config.steps].sort((a, b) => a.step_number - b.step_number)\n for (const s of ordered) {\n if (allFields.some((f) => f.step_id === s.id && newErrors[f.slug])) {\n firstErrorStep = s.step_number\n break\n }\n }\n }\n return { ok: false, firstErrorStep }\n }, [config, validateField])\n\n // Collect values for currently-visible fields only, so a value typed into a\n // field that later became conditionally hidden is never submitted.\n const buildVisibleValues = useCallback((): Record<string, unknown> => {\n const out: Record<string, unknown> = {}\n for (const field of config.fields || []) {\n if (!isFieldVisible(field)) continue\n if (field.slug in values) out[field.slug] = values[field.slug]\n }\n return out\n }, [config, values, isFieldVisible])\n\n // Set field value\n const setFieldValue = useCallback((key: string, value: unknown) => {\n setTouched(prev => (prev[key] ? prev : { ...prev, [key]: true }))\n setValues(prev => ({ ...prev, [key]: value }))\n // Clear error when field changes\n if (errors[key]) {\n setErrors(prev => {\n const next = { ...prev }\n delete next[key]\n return next\n })\n }\n }, [errors])\n \n // Step navigation\n const nextStep = useCallback((): boolean => {\n if (!validateStep()) return false\n \n if (step < config.total_steps) {\n const newStep = step + 1\n setStepDirection('forward')\n setStep(newStep)\n trackStepChange(newStep)\n return true\n }\n return false\n }, [step, config.total_steps, validateStep, trackStepChange])\n\n const prevStep = useCallback(() => {\n if (step > 1) {\n const newStep = step - 1\n setStepDirection('back')\n setStep(newStep)\n trackStepChange(newStep)\n }\n }, [step, trackStepChange])\n\n const goToStep = useCallback((targetStep: number) => {\n if (targetStep >= 1 && targetStep <= config.total_steps) {\n setStepDirection(targetStep < step ? 'back' : 'forward')\n setStep(targetStep)\n trackStepChange(targetStep)\n }\n }, [step, config.total_steps, trackStepChange])\n \n // Submit form\n const submit = useCallback(async () => {\n // Re-entrancy guard — refs update synchronously, so this blocks a second\n // submit fired in the same tick (Enter key + button click, or a double-tap).\n if (isSubmittingRef.current) return\n\n const { ok, firstErrorStep } = validateAll()\n if (!ok) {\n if (firstErrorStep != null) {\n setStepDirection('back')\n setStep(firstErrorStep)\n }\n return\n }\n\n isSubmittingRef.current = true\n setIsSubmitting(true)\n setSubmitError(null)\n\n try {\n const data = await submitForm({\n config,\n values: buildVisibleValues(),\n honeypotValue: config.honeypot_enabled ? honeypotValue : '',\n formLoadedAt: formLoadedAt.current,\n })\n\n trackComplete()\n setIsComplete(true)\n onSuccess?.(data as FormSubmission)\n\n if (config.redirect_url) {\n window.location.href = config.redirect_url\n }\n } catch (error) {\n console.error('[Forms] Submission error:', error)\n setSubmitError('Something went wrong sending your submission. Please try again.')\n onError?.(error as Error)\n } finally {\n isSubmittingRef.current = false\n setIsSubmitting(false)\n }\n }, [config, honeypotValue, validateAll, buildVisibleValues, trackComplete, onSuccess, onError])\n \n // Progress percentage\n const progress = useMemo(() => {\n return Math.round((step / config.total_steps) * 100)\n }, [step, config.total_steps])\n\n // Title/description the admin gave the current step, used as the step's\n // conversational heading. Absent for single-step forms.\n const currentStepConfig = useMemo(\n () => config.steps?.find((s) => s.step_number === step),\n [config.steps, step],\n )\n\n // Move focus to the new step's panel so keyboard and screen-reader users land\n // on the fields they just navigated to instead of staying on a button that\n // has moved. Skipped on first render so the form never steals focus on load.\n const stepPanelRef = useRef<HTMLDivElement | null>(null)\n const hasNavigatedRef = useRef(false)\n useEffect(() => {\n if (!config.is_multi_step) return\n if (!hasNavigatedRef.current) {\n hasNavigatedRef.current = true\n return\n }\n stepPanelRef.current?.focus()\n }, [step, config.is_multi_step])\n\n\n // Render props for custom rendering\n const renderProps: FormRenderProps = {\n config,\n fields: currentFields,\n step,\n totalSteps: config.total_steps,\n values,\n errors,\n isSubmitting,\n progress,\n nextStep,\n prevStep,\n goToStep,\n submit,\n setFieldValue,\n isFieldVisible,\n }\n \n // Show success message (fallback when API returns empty / null success_message)\n if (isComplete) {\n const raw = config.success_message\n const message =\n typeof raw === 'string' && raw.trim().length > 0\n ? raw.trim()\n : DEFAULT_FORM_SUCCESS_MESSAGE\n // The payoff moment — celebration, not a receipt. Sites theme it via\n // --sk-primary + data-sk-part; reduced-motion users get the static check.\n // Loaded lazily (it only ever renders AFTER a submit round-trip, so the\n // chunk fetch is free), but the confirmation itself never depends on\n // that chunk: until it lands, and if it never lands, the plain message\n // below is shown. A user must always be told their submission worked.\n if (Celebration) return <Celebration message={message} className={className} />\n return (\n <div className={className} data-sk-part=\"celebration-fallback\" role=\"status\">\n <p>{message}</p>\n </div>\n )\n }\n \n // Custom render\n if (customRender) {\n return <>{customRender(renderProps)}</>\n }\n\n // Alternate experiences — render BRANCHES, not customRenders: this\n // FormClient still owns values/errors/honeypot/submit, so spam defense and\n // validation are identical to classic.\n if (resolvedExperience !== 'classic' && Experience) {\n const bundle: ExperienceRenderProps = {\n config,\n values,\n errors,\n touched,\n isSubmitting,\n submitError,\n momentum,\n className,\n setFieldValue,\n validateField,\n isFieldVisible,\n fieldIsComplete,\n applyFieldError: (slug, message) =>\n setErrors((prev) => ({ ...prev, [slug]: message })),\n submit,\n trackStepChange,\n honeypot: config.honeypot_enabled ? (\n <HoneypotField\n name={honeypotFieldName}\n value={honeypotValue}\n onChange={setHoneypotValue}\n />\n ) : null,\n }\n return (\n <>\n <DelightStyles />\n <Experience {...bundle} />\n </>\n )\n }\n\n // Default render\n return (\n <form data-sk-state={isSubmitting ? 'submitting' : 'idle'}\n // Ready = every required field validates AND the submit button (not\n // \"Next\") is what's showing — the wake-up glow means \"press start\".\n data-sk-ready={\n momentum.total > 0 && momentum.done >= momentum.total && step >= config.total_steps\n ? 'true'\n : undefined\n }\n className={`sk-form ${className || ''}`}\n // No-JS floor: real action/method so the browser can POST without the\n // bundle. With JS the preventDefault below always wins.\n {...nativeFormProps(config)}\n onSubmit={(e) => {\n e.preventDefault()\n if (step < config.total_steps) {\n nextStep()\n } else {\n submit()\n }\n }}\n >\n <DelightStyles />\n <FormMomentum done={momentum.done} total={momentum.total} />\n {/* Step indicator for multi-step */}\n {config.is_multi_step && (\n <div className=\"sk-form__progress\">\n <div className=\"sk-form__progress-header\">\n <span className=\"sk-form__progress-step\">\n Step {step} of {config.total_steps}\n </span>\n {/* The percentage readout is opt-in — \"Step 2 of 4\" already gives\n the user their position, and a bare number reads as pressure. */}\n {config.show_progress && (\n <span className=\"sk-form__progress-percent\">{progress}%</span>\n )}\n </div>\n <div\n className=\"sk-form__progress-track\"\n role=\"progressbar\"\n aria-valuemin={1}\n aria-valuemax={config.total_steps}\n aria-valuenow={step}\n aria-valuetext={`Step ${step} of ${config.total_steps}`}\n >\n <div className=\"sk-form__progress-bar\" style={{ width: `${progress}%` }} />\n </div>\n <ol className=\"sk-form__progress-dots\" aria-hidden=\"true\">\n {Array.from({ length: config.total_steps }, (_, i) => i + 1).map((n) => (\n <li\n key={n}\n className={\n 'sk-form__progress-dot' +\n (n === step ? ' sk-form__progress-dot--current' : '') +\n (n < step ? ' sk-form__progress-dot--done' : '')\n }\n />\n ))}\n </ol>\n </div>\n )}\n\n {/* Fields — keyed by step so each step animates in on navigation */}\n <div\n key={step}\n ref={stepPanelRef}\n tabIndex={-1}\n className={\n 'sk-form__step' +\n (config.is_multi_step ? ` sk-form__step--${stepDirection}` : '')\n }\n >\n {config.is_multi_step && (currentStepConfig?.title || currentStepConfig?.description) && (\n <div className=\"sk-form__step-intro\">\n {currentStepConfig.title && (\n <h3 className=\"sk-form__step-title\">{currentStepConfig.title}</h3>\n )}\n {currentStepConfig.description && (\n <p className=\"sk-form__step-description\">{currentStepConfig.description}</p>\n )}\n </div>\n )}\n\n <div className=\"sk-form__fields\">\n {currentFields.map((field) => {\n if (!isFieldVisible(field)) return null\n\n return (\n <div key={field.id} className={`sk-form__field-wrapper sk-form__field-wrapper--${field.width || 'full'}`}>\n <FormField\n field={field}\n value={values[field.slug]}\n error={errors[field.slug]}\n showValid={!!touched[field.slug] && !errors[field.slug] && fieldIsComplete(field)}\n onChange={(value) => setFieldValue(field.slug, value)}\n controls={fieldControls}\n />\n </div>\n )\n })}\n </div>\n </div>\n\n {/* Navigation buttons */}\n <div\n className=\"sk-form__actions\"\n style={{ justifyContent: step > 1 ? 'space-between' : 'flex-end' }}\n >\n {step > 1 && (\n <button type=\"button\" className=\"sk-form__btn sk-form__btn--back\" onClick={prevStep}>\n Back\n </button>\n )}\n <button type=\"submit\" className=\"sk-form__btn sk-form__btn--submit\" disabled={isSubmitting}>\n {isSubmitting\n ? 'Submitting...'\n : step < config.total_steps\n ? 'Next'\n : config.submit_button_text\n }\n </button>\n </div>\n\n {submitError && (\n <p\n className=\"sk-form__submit-error\"\n role=\"alert\"\n style={{ color: 'var(--sk-error, #dc2626)', fontSize: 14, marginTop: 12 }}\n >\n {submitError}\n </p>\n )}\n\n {/* Honeypot field — shared single source of truth with the stage\n experience (HoneypotField.tsx holds the invariants). */}\n {config.honeypot_enabled && (\n <HoneypotField\n name={honeypotFieldName}\n value={honeypotValue}\n onChange={setHoneypotValue}\n />\n )}\n\n {/* No-JS control fields (_sk_token auth + _sk_return destination). */}\n <NativeFallbackFields config={config} returnTo={nativeReturnTo} />\n </form>\n )\n}\n","/**\n * @sonordev/site-kit/forms - Managed Form Component\n * \n * Fetches form config from Portal API and renders fields with validation\n */\n\n'use client'\n\nimport type { ManagedFormProps } from './types'\nimport { useForm } from './useForm'\nimport { FormClient } from './FormClient'\n\n// ============================================\n// Main Component (Client Component)\n// ============================================\n\nexport function ManagedForm({\n formId,\n projectId,\n className,\n onSuccess,\n onError,\n initialConfig,\n experience,\n nativeReturnTo,\n defaultValues,\n children,\n}: ManagedFormProps) {\n const {\n form,\n isLoading,\n fetchError,\n } = useForm(formId, {\n projectId,\n onSuccess,\n onError,\n initialForm: initialConfig,\n // FormClient below owns this form's tracking — it renders the fields,\n // drives step navigation and runs the submit, so it is the only thing that\n // can report a real funnel. useForm is used here purely to FETCH the\n // config; we never call its submit, so its analytics row could only ever\n // open and abandon, never complete.\n //\n // Leaving this on is the double-count bug fixed in 4.2.2: two\n // trackers per form, two form_analytics rows per page load, every\n // start -> submission rate reported at half its true value.\n trackAnalytics: false,\n })\n \n if (isLoading) {\n return (\n <div className={className}>\n <p style={{ color: '#6b7280' }}>Loading form...</p>\n </div>\n )\n }\n \n if (fetchError || !form) {\n return (\n <div className={className}>\n <p style={{ color: 'var(--sk-error, #dc2626)' }}>\n {fetchError?.message || 'Form not found or inactive.'}\n </p>\n </div>\n )\n }\n \n // Pass to client component for interactivity\n return (\n <FormClient\n config={form}\n className={className}\n onSuccess={onSuccess}\n onError={onError}\n customRender={children}\n experience={experience}\n nativeReturnTo={nativeReturnTo}\n defaultValues={defaultValues}\n />\n )\n}\n\n"]}
1
+ {"version":3,"sources":["../src/forms/FormClient.tsx","../src/forms/ManagedForm.tsx"],"names":["currentStepConfig","jsx"],"mappings":"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","file":"chunk-NSTY7ZZA.mjs","sourcesContent":["/**\n * @sonordev/site-kit/forms - Form Client Component\n * \n * Handles form state, validation, and submission\n */\n\n'use client'\n\nimport React, { useState, useCallback, useMemo, useRef, useEffect } from 'react'\nimport { useFormTracking } from './useFormTracking'\nimport { FormField } from './FormField'\nimport { submitForm, DEFAULT_HONEYPOT_FIELD } from './submitForm'\nimport type { \n ManagedFormConfig, \n FormField as FormFieldType, \n FormRenderProps,\n FormSubmission,\n} from './types'\nimport { DEFAULT_FORM_SUCCESS_MESSAGE } from './defaultSuccessMessage'\nimport { DelightStyles, FormMomentum } from './delight'\nimport { HoneypotField } from './HoneypotField'\nimport { useFieldControls } from './field-controls'\nimport { nativeFormProps, NativeFallbackFields } from './native-fallback'\nimport { countStageViews, countStageQuestions } from './experience-plan'\nimport type { ExperienceRenderProps, FormExperience } from './types'\n\ninterface FormClientProps {\n config: ManagedFormConfig\n className?: string\n onSuccess?: (submission: FormSubmission) => void\n onError?: (error: Error) => void\n customRender?: (props: FormRenderProps) => React.ReactNode\n /**\n * Pre-fill field values by slug. For context the page already has and the\n * visitor should not retype: an email captured earlier in a conversation,\n * the service they were reading about, an estimate the assistant just\n * produced. Applied ON TOP of each field's configured default_value.\n *\n * Unknown slugs are ignored, so a stale key cannot break the form.\n */\n defaultValues?: Record<string, unknown>\n /**\n * Which rendering the form gets. Defaults to the form's `layout` config\n * (`layout: 'stage'` in Sonor flips a form to stage with no site deploy),\n * else 'classic'. customRender always wins over this.\n */\n experience?: FormExperience\n /** Absolute page URL for the no-JS 303 to land on (see native-fallback). */\n nativeReturnTo?: string\n}\n\nexport function FormClient({\n config,\n className,\n onSuccess,\n onError,\n customRender,\n experience,\n nativeReturnTo,\n defaultValues,\n}: FormClientProps) {\n // Seed default_value fields once (lazy initializer — config is stable for\n // the life of this mount; ManagedForm only renders us once it has a form).\n const [values, setValues] = useState<Record<string, unknown>>(() => {\n const defaults: Record<string, unknown> = {}\n for (const field of config.fields || []) {\n if (field.default_value !== undefined && field.default_value !== null) {\n defaults[field.slug] = field.default_value\n }\n }\n // Caller-supplied values win over the form's configured defaults — they\n // are per-visitor context (what Echo already knows about this person,\n // the service they were reading about) rather than form configuration.\n return { ...defaults, ...(defaultValues || {}) }\n })\n const [errors, setErrors] = useState<Record<string, string>>({})\n const [step, setStep] = useState(1)\n // Direction of the last step change, so the transition slides the way the\n // user is travelling ('forward' on Next, 'back' on Back).\n const [stepDirection, setStepDirection] = useState<'forward' | 'back'>('forward')\n const [isSubmitting, setIsSubmitting] = useState(false)\n const [isComplete, setIsComplete] = useState(false)\n const [submitError, setSubmitError] = useState<string | null>(null)\n const [honeypotValue, setHoneypotValue] = useState('')\n // Fields the user has interacted with — the valid tick only appears after\n // real input (never on pristine fields), so it reads as earned feedback.\n const [touched, setTouched] = useState<Record<string, boolean>>({})\n const honeypotFieldName = config.honeypot_field || DEFAULT_HONEYPOT_FIELD\n\n // Anti-bot: record when form first rendered (bots submit in < 3 seconds)\n const formLoadedAt = useRef(Date.now())\n // Synchronous guard against a concurrent double-submit (Enter + click, etc.).\n const isSubmittingRef = useRef(false)\n\n // Resolve the experience: explicit prop > form config > SPOTLIGHT.\n //\n // Spotlight is the 4.0 default: every managed form converses back unless it\n // opts out. Opting out is `experience=\"classic\"` on the component or\n // `layout: 'classic'` in Sonor (forms are data, so either side can decide\n // with no deploy from the other). customRender always wins, and a form with\n // no answerable fields has nothing to perform, so it falls back to classic.\n const stageBeatCount = useMemo(() => countStageViews(config), [config])\n const questionCount = useMemo(() => countStageQuestions(config), [config])\n const requested: FormExperience =\n experience ??\n (config.layout === 'stage'\n ? 'stage'\n : config.layout === 'classic'\n ? 'classic'\n : 'spotlight')\n const resolvedExperience: FormExperience =\n !customRender && questionCount > 0 && requested !== 'classic'\n ? requested\n : 'classic'\n\n // Date/file controls are fetched only when the form actually has such a\n // field — most forms have neither, and the date picker alone was ~5 KB\n // gzipped in every forms bundle. Until a chunk lands (and for SSR/no-JS),\n // FormField renders the native control, which submits the same value.\n const fieldControls = useFieldControls(config.fields)\n\n const { trackStepChange, trackComplete } = useFormTracking({\n formId: config.id,\n // Alternate experiences report their unit (beat / field index) as the\n // step — form_analytics becomes a drop-off funnel with zero API changes.\n totalSteps:\n resolvedExperience === 'stage'\n ? stageBeatCount\n : resolvedExperience === 'spotlight'\n ? questionCount\n : config.total_steps,\n })\n\n // The celebration is fetched as soon as the user starts submitting, so the\n // chunk arrives during the network round-trip and the payoff still feels\n // instant — without putting its markup and CSS in every form's bundle.\n const [Celebration, setCelebration] =\n useState<React.ComponentType<{ message: string; className?: string }> | null>(null)\n useEffect(() => {\n if (!isSubmitting && !isComplete) return\n let cancelled = false\n import('./FormCelebration')\n .then((m) => {\n if (!cancelled) setCelebration(() => m.FormCelebration)\n })\n .catch(() => {\n // Stays null — the plain confirmation message renders instead.\n })\n return () => {\n cancelled = true\n }\n }, [isSubmitting, isComplete])\n\n // Experience components load on demand, so a classic form (the fleet\n // default) never downloads stage/spotlight code or their stylesheets.\n // Until the chunk lands — and for SSR and no-JS — the CLASSIC form renders:\n // a complete, working, submittable form. The experience is progressive\n // enhancement layered on top, never a prerequisite for capturing the lead.\n const [Experience, setExperience] =\n useState<React.ComponentType<ExperienceRenderProps> | null>(null)\n useEffect(() => {\n if (resolvedExperience === 'classic') {\n setExperience(null)\n return\n }\n let cancelled = false\n const load =\n resolvedExperience === 'stage'\n ? import('./FormStage').then((m) => m.FormStage)\n : import('./FormSpotlight').then((m) => m.FormSpotlight)\n load\n .then((Component) => {\n // setState with a component value needs the updater form, or React\n // would call it as a lazy initializer.\n if (!cancelled) setExperience(() => Component)\n })\n .catch((err) => {\n // Chunk failed (offline, cache miss, CDN hiccup): stay on classic.\n console.error('[Forms] Experience failed to load; using classic form:', err)\n })\n return () => {\n cancelled = true\n }\n }, [resolvedExperience])\n \n // Get fields for current step\n const currentFields = useMemo(() => {\n if (!config.is_multi_step) {\n return config.fields || []\n }\n \n const currentStepConfig = config.steps?.find(s => s.step_number === step)\n if (!currentStepConfig) return config.fields || []\n \n return (config.fields || []).filter(f => f.step_id === currentStepConfig.id)\n }, [config, step])\n \n // Check if field is visible (conditional logic)\n const isFieldVisible = useCallback((field: FormFieldType): boolean => {\n if (!field.conditional?.show_when) return true\n \n const { field: condField, operator, value } = field.conditional.show_when\n const fieldValue = values[condField]\n \n switch (operator) {\n case 'equals':\n return fieldValue === value\n case 'not_equals':\n return fieldValue !== value\n case 'contains':\n return String(fieldValue).includes(String(value))\n case 'not_contains':\n return !String(fieldValue).includes(String(value))\n case 'is_empty':\n return !fieldValue || fieldValue === ''\n case 'not_empty':\n return !!fieldValue && fieldValue !== ''\n case 'greater_than':\n return Number(fieldValue) > Number(value)\n case 'less_than':\n return Number(fieldValue) < Number(value)\n default:\n return true\n }\n }, [values])\n \n // Validate field\n const validateField = useCallback((field: FormFieldType): string | null => {\n if (!isFieldVisible(field)) return null\n // Skip display-only field types\n if (['heading', 'section_header', 'paragraph', 'hidden'].includes(field.field_type)) return null\n \n const value = values[field.slug]\n const rules = field.validation || {}\n \n // Required check\n if (field.is_required && (!value || value === '')) {\n return rules.custom_error || `${field.label} is required`\n }\n \n if (!value) return null\n \n const strValue = String(value)\n \n // Length checks\n if (rules.min_length && strValue.length < rules.min_length) {\n return `${field.label} must be at least ${rules.min_length} characters`\n }\n if (rules.max_length && strValue.length > rules.max_length) {\n return `${field.label} must be no more than ${rules.max_length} characters`\n }\n \n // Numeric checks\n if (rules.min !== undefined && Number(value) < rules.min) {\n return `${field.label} must be at least ${rules.min}`\n }\n if (rules.max !== undefined && Number(value) > rules.max) {\n return `${field.label} must be no more than ${rules.max}`\n }\n \n // Pattern check — guard against an invalid admin-entered pattern.\n if (rules.pattern) {\n try {\n if (!new RegExp(rules.pattern).test(strValue)) {\n return rules.custom_error || `${field.label} is invalid`\n }\n } catch {\n // Malformed pattern — skip rather than crashing the whole form render.\n }\n }\n \n // Email check\n if (field.field_type === 'email' && !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(strValue)) {\n return 'Please enter a valid email address'\n }\n \n // Phone check\n if (field.field_type === 'phone' && !/^[\\d\\s\\-\\+\\(\\)]+$/.test(strValue)) {\n return 'Please enter a valid phone number'\n }\n \n return null\n }, [values, isFieldVisible])\n \n // Delight: per-field validity for the tick + fields-completed momentum.\n const fieldIsComplete = useCallback((field: FormFieldType): boolean => {\n if (!isFieldVisible(field)) return false\n if (['heading', 'section_header', 'paragraph', 'hidden'].includes(field.field_type)) return false\n const value = values[field.slug]\n if (value === undefined || value === null || value === '') return false\n return validateField(field) === null\n }, [values, isFieldVisible, validateField])\n\n const momentum = useMemo(() => {\n const measurable = (config.fields || []).filter(\n f => f.is_required && isFieldVisible(f) && !['heading', 'section_header', 'paragraph', 'hidden'].includes(f.field_type),\n )\n return { done: measurable.filter(fieldIsComplete).length, total: measurable.length }\n }, [config, isFieldVisible, fieldIsComplete])\n\n // Validate current step\n const validateStep = useCallback((): boolean => {\n const newErrors: Record<string, string> = {}\n \n for (const field of currentFields) {\n const error = validateField(field)\n if (error) {\n newErrors[field.slug] = error\n }\n }\n \n setErrors(newErrors)\n return Object.keys(newErrors).length === 0\n }, [currentFields, validateField])\n\n // Validate EVERY field across all steps — used on final submit so a required\n // field left empty on an earlier step cannot slip through. Returns the first\n // step containing an error so the user can be taken straight to it.\n const validateAll = useCallback((): { ok: boolean; firstErrorStep: number | null } => {\n const allFields = config.fields || []\n const newErrors: Record<string, string> = {}\n for (const field of allFields) {\n const error = validateField(field)\n if (error) newErrors[field.slug] = error\n }\n setErrors(newErrors)\n if (Object.keys(newErrors).length === 0) return { ok: true, firstErrorStep: null }\n\n let firstErrorStep: number | null = null\n if (config.is_multi_step && config.steps) {\n const ordered = [...config.steps].sort((a, b) => a.step_number - b.step_number)\n for (const s of ordered) {\n if (allFields.some((f) => f.step_id === s.id && newErrors[f.slug])) {\n firstErrorStep = s.step_number\n break\n }\n }\n }\n return { ok: false, firstErrorStep }\n }, [config, validateField])\n\n // Collect values for currently-visible fields only, so a value typed into a\n // field that later became conditionally hidden is never submitted.\n const buildVisibleValues = useCallback((): Record<string, unknown> => {\n const out: Record<string, unknown> = {}\n for (const field of config.fields || []) {\n if (!isFieldVisible(field)) continue\n if (field.slug in values) out[field.slug] = values[field.slug]\n }\n return out\n }, [config, values, isFieldVisible])\n\n // Set field value\n const setFieldValue = useCallback((key: string, value: unknown) => {\n setTouched(prev => (prev[key] ? prev : { ...prev, [key]: true }))\n setValues(prev => ({ ...prev, [key]: value }))\n // Clear error when field changes\n if (errors[key]) {\n setErrors(prev => {\n const next = { ...prev }\n delete next[key]\n return next\n })\n }\n }, [errors])\n \n // Step navigation\n const nextStep = useCallback((): boolean => {\n if (!validateStep()) return false\n \n if (step < config.total_steps) {\n const newStep = step + 1\n setStepDirection('forward')\n setStep(newStep)\n trackStepChange(newStep)\n return true\n }\n return false\n }, [step, config.total_steps, validateStep, trackStepChange])\n\n const prevStep = useCallback(() => {\n if (step > 1) {\n const newStep = step - 1\n setStepDirection('back')\n setStep(newStep)\n trackStepChange(newStep)\n }\n }, [step, trackStepChange])\n\n const goToStep = useCallback((targetStep: number) => {\n if (targetStep >= 1 && targetStep <= config.total_steps) {\n setStepDirection(targetStep < step ? 'back' : 'forward')\n setStep(targetStep)\n trackStepChange(targetStep)\n }\n }, [step, config.total_steps, trackStepChange])\n \n // Submit form\n const submit = useCallback(async () => {\n // Re-entrancy guard — refs update synchronously, so this blocks a second\n // submit fired in the same tick (Enter key + button click, or a double-tap).\n if (isSubmittingRef.current) return\n\n const { ok, firstErrorStep } = validateAll()\n if (!ok) {\n if (firstErrorStep != null) {\n setStepDirection('back')\n setStep(firstErrorStep)\n }\n return\n }\n\n isSubmittingRef.current = true\n setIsSubmitting(true)\n setSubmitError(null)\n\n try {\n const data = await submitForm({\n config,\n values: buildVisibleValues(),\n honeypotValue: config.honeypot_enabled ? honeypotValue : '',\n formLoadedAt: formLoadedAt.current,\n })\n\n trackComplete()\n setIsComplete(true)\n onSuccess?.(data as FormSubmission)\n\n if (config.redirect_url) {\n window.location.href = config.redirect_url\n }\n } catch (error) {\n console.error('[Forms] Submission error:', error)\n setSubmitError('Something went wrong sending your submission. Please try again.')\n onError?.(error as Error)\n } finally {\n isSubmittingRef.current = false\n setIsSubmitting(false)\n }\n }, [config, honeypotValue, validateAll, buildVisibleValues, trackComplete, onSuccess, onError])\n \n // Progress percentage\n const progress = useMemo(() => {\n return Math.round((step / config.total_steps) * 100)\n }, [step, config.total_steps])\n\n // Title/description the admin gave the current step, used as the step's\n // conversational heading. Absent for single-step forms.\n const currentStepConfig = useMemo(\n () => config.steps?.find((s) => s.step_number === step),\n [config.steps, step],\n )\n\n // Move focus to the new step's panel so keyboard and screen-reader users land\n // on the fields they just navigated to instead of staying on a button that\n // has moved. Skipped on first render so the form never steals focus on load.\n const stepPanelRef = useRef<HTMLDivElement | null>(null)\n const hasNavigatedRef = useRef(false)\n useEffect(() => {\n if (!config.is_multi_step) return\n if (!hasNavigatedRef.current) {\n hasNavigatedRef.current = true\n return\n }\n stepPanelRef.current?.focus()\n }, [step, config.is_multi_step])\n\n\n // Render props for custom rendering\n const renderProps: FormRenderProps = {\n config,\n fields: currentFields,\n step,\n totalSteps: config.total_steps,\n values,\n errors,\n isSubmitting,\n progress,\n nextStep,\n prevStep,\n goToStep,\n submit,\n setFieldValue,\n isFieldVisible,\n }\n \n // Show success message (fallback when API returns empty / null success_message)\n if (isComplete) {\n const raw = config.success_message\n const message =\n typeof raw === 'string' && raw.trim().length > 0\n ? raw.trim()\n : DEFAULT_FORM_SUCCESS_MESSAGE\n // The payoff moment — celebration, not a receipt. Sites theme it via\n // --sk-primary + data-sk-part; reduced-motion users get the static check.\n // Loaded lazily (it only ever renders AFTER a submit round-trip, so the\n // chunk fetch is free), but the confirmation itself never depends on\n // that chunk: until it lands, and if it never lands, the plain message\n // below is shown. A user must always be told their submission worked.\n if (Celebration) return <Celebration message={message} className={className} />\n return (\n <div className={className} data-sk-part=\"celebration-fallback\" role=\"status\">\n <p>{message}</p>\n </div>\n )\n }\n \n // Custom render\n if (customRender) {\n return <>{customRender(renderProps)}</>\n }\n\n // Alternate experiences — render BRANCHES, not customRenders: this\n // FormClient still owns values/errors/honeypot/submit, so spam defense and\n // validation are identical to classic.\n if (resolvedExperience !== 'classic' && Experience) {\n const bundle: ExperienceRenderProps = {\n config,\n values,\n errors,\n touched,\n isSubmitting,\n submitError,\n momentum,\n className,\n setFieldValue,\n validateField,\n isFieldVisible,\n fieldIsComplete,\n applyFieldError: (slug, message) =>\n setErrors((prev) => ({ ...prev, [slug]: message })),\n submit,\n trackStepChange,\n honeypot: config.honeypot_enabled ? (\n <HoneypotField\n name={honeypotFieldName}\n value={honeypotValue}\n onChange={setHoneypotValue}\n />\n ) : null,\n }\n return (\n <>\n <DelightStyles />\n <Experience {...bundle} />\n </>\n )\n }\n\n // Default render\n return (\n <form data-sk-state={isSubmitting ? 'submitting' : 'idle'}\n // Ready = every required field validates AND the submit button (not\n // \"Next\") is what's showing — the wake-up glow means \"press start\".\n data-sk-ready={\n momentum.total > 0 && momentum.done >= momentum.total && step >= config.total_steps\n ? 'true'\n : undefined\n }\n className={`sk-form ${className || ''}`}\n // No-JS floor: real action/method so the browser can POST without the\n // bundle. With JS the preventDefault below always wins.\n {...nativeFormProps(config)}\n onSubmit={(e) => {\n e.preventDefault()\n if (step < config.total_steps) {\n nextStep()\n } else {\n submit()\n }\n }}\n >\n <DelightStyles />\n <FormMomentum done={momentum.done} total={momentum.total} />\n {/* Step indicator for multi-step */}\n {config.is_multi_step && (\n <div className=\"sk-form__progress\">\n <div className=\"sk-form__progress-header\">\n <span className=\"sk-form__progress-step\">\n Step {step} of {config.total_steps}\n </span>\n {/* The percentage readout is opt-in — \"Step 2 of 4\" already gives\n the user their position, and a bare number reads as pressure. */}\n {config.show_progress && (\n <span className=\"sk-form__progress-percent\">{progress}%</span>\n )}\n </div>\n <div\n className=\"sk-form__progress-track\"\n role=\"progressbar\"\n aria-valuemin={1}\n aria-valuemax={config.total_steps}\n aria-valuenow={step}\n aria-valuetext={`Step ${step} of ${config.total_steps}`}\n >\n <div className=\"sk-form__progress-bar\" style={{ width: `${progress}%` }} />\n </div>\n <ol className=\"sk-form__progress-dots\" aria-hidden=\"true\">\n {Array.from({ length: config.total_steps }, (_, i) => i + 1).map((n) => (\n <li\n key={n}\n className={\n 'sk-form__progress-dot' +\n (n === step ? ' sk-form__progress-dot--current' : '') +\n (n < step ? ' sk-form__progress-dot--done' : '')\n }\n />\n ))}\n </ol>\n </div>\n )}\n\n {/* Fields — keyed by step so each step animates in on navigation */}\n <div\n key={step}\n ref={stepPanelRef}\n tabIndex={-1}\n className={\n 'sk-form__step' +\n (config.is_multi_step ? ` sk-form__step--${stepDirection}` : '')\n }\n >\n {config.is_multi_step && (currentStepConfig?.title || currentStepConfig?.description) && (\n <div className=\"sk-form__step-intro\">\n {currentStepConfig.title && (\n <h3 className=\"sk-form__step-title\">{currentStepConfig.title}</h3>\n )}\n {currentStepConfig.description && (\n <p className=\"sk-form__step-description\">{currentStepConfig.description}</p>\n )}\n </div>\n )}\n\n <div className=\"sk-form__fields\">\n {currentFields.map((field) => {\n if (!isFieldVisible(field)) return null\n\n return (\n <div key={field.id} className={`sk-form__field-wrapper sk-form__field-wrapper--${field.width || 'full'}`}>\n <FormField\n field={field}\n value={values[field.slug]}\n error={errors[field.slug]}\n showValid={!!touched[field.slug] && !errors[field.slug] && fieldIsComplete(field)}\n onChange={(value) => setFieldValue(field.slug, value)}\n controls={fieldControls}\n />\n </div>\n )\n })}\n </div>\n </div>\n\n {/* Navigation buttons */}\n <div\n className=\"sk-form__actions\"\n style={{ justifyContent: step > 1 ? 'space-between' : 'flex-end' }}\n >\n {step > 1 && (\n <button type=\"button\" className=\"sk-form__btn sk-form__btn--back\" onClick={prevStep}>\n Back\n </button>\n )}\n <button type=\"submit\" className=\"sk-form__btn sk-form__btn--submit\" disabled={isSubmitting}>\n {isSubmitting\n ? 'Submitting...'\n : step < config.total_steps\n ? 'Next'\n : config.submit_button_text\n }\n </button>\n </div>\n\n {submitError && (\n <p\n className=\"sk-form__submit-error\"\n role=\"alert\"\n style={{ color: 'var(--sk-error, #dc2626)', fontSize: 14, marginTop: 12 }}\n >\n {submitError}\n </p>\n )}\n\n {/* Honeypot field — shared single source of truth with the stage\n experience (HoneypotField.tsx holds the invariants). */}\n {config.honeypot_enabled && (\n <HoneypotField\n name={honeypotFieldName}\n value={honeypotValue}\n onChange={setHoneypotValue}\n />\n )}\n\n {/* No-JS control fields (_sk_token auth + _sk_return destination). */}\n <NativeFallbackFields config={config} returnTo={nativeReturnTo} />\n </form>\n )\n}\n","/**\n * @sonordev/site-kit/forms - Managed Form Component\n * \n * Fetches form config from Portal API and renders fields with validation\n */\n\n'use client'\n\nimport type { ManagedFormProps } from './types'\nimport { useForm } from './useForm'\nimport { FormClient } from './FormClient'\n\n// ============================================\n// Main Component (Client Component)\n// ============================================\n\nexport function ManagedForm({\n formId,\n projectId,\n className,\n onSuccess,\n onError,\n initialConfig,\n experience,\n nativeReturnTo,\n defaultValues,\n children,\n}: ManagedFormProps) {\n const {\n form,\n isLoading,\n fetchError,\n } = useForm(formId, {\n projectId,\n onSuccess,\n onError,\n initialForm: initialConfig,\n // FormClient below owns this form's tracking — it renders the fields,\n // drives step navigation and runs the submit, so it is the only thing that\n // can report a real funnel. useForm is used here purely to FETCH the\n // config; we never call its submit, so its analytics row could only ever\n // open and abandon, never complete.\n //\n // Leaving this on is the double-count bug fixed in 4.2.2: two\n // trackers per form, two form_analytics rows per page load, every\n // start -> submission rate reported at half its true value.\n trackAnalytics: false,\n })\n \n if (isLoading) {\n return (\n <div className={className}>\n <p style={{ color: '#6b7280' }}>Loading form...</p>\n </div>\n )\n }\n \n if (fetchError || !form) {\n return (\n <div className={className}>\n <p style={{ color: 'var(--sk-error, #dc2626)' }}>\n {fetchError?.message || 'Form not found or inactive.'}\n </p>\n </div>\n )\n }\n \n // Pass to client component for interactivity\n return (\n <FormClient\n config={form}\n className={className}\n onSuccess={onSuccess}\n onError={onError}\n customRender={children}\n experience={experience}\n nativeReturnTo={nativeReturnTo}\n defaultValues={defaultValues}\n />\n )\n}\n\n"]}
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
  import { registerAnalyticsDispatcher } from './chunk-3DPXOZAU.mjs';
3
3
  import { getOrCreateVisitorId, getOrCreateSessionId } from './chunk-ZZQAGCSI.mjs';
4
- import { sonorFetch, sonorBeacon } from './chunk-45VPULF2.mjs';
4
+ import { sonorFetch, sonorBeacon } from './chunk-ADOGOLYO.mjs';
5
5
  import { createContext, useRef, useEffect, useState, useCallback, useMemo, useContext } from 'react';
6
6
  import { usePathname } from 'next/navigation';
7
7
  import { jsxs, jsx } from 'react/jsx-runtime';
@@ -1098,5 +1098,5 @@ function useTrackEvent() {
1098
1098
  }
1099
1099
 
1100
1100
  export { AnalyticsProvider, WebVitals, useAnalytics, useAnalyticsOptional, useTrackEvent };
1101
- //# sourceMappingURL=chunk-3BXYZC3V.mjs.map
1102
- //# sourceMappingURL=chunk-3BXYZC3V.mjs.map
1101
+ //# sourceMappingURL=chunk-OAJVITNO.mjs.map
1102
+ //# sourceMappingURL=chunk-OAJVITNO.mjs.map