@sonordev/site-kit 5.1.0 → 5.3.1

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 (267) hide show
  1. package/README.md +15 -0
  2. package/agent-manifest.json +23 -2
  3. package/dist/AnalyticsProvider-NA7EMJCA.mjs +10 -0
  4. package/dist/{AnalyticsProvider-2LCSA6G3.mjs.map → AnalyticsProvider-NA7EMJCA.mjs.map} +1 -1
  5. package/dist/AnalyticsProvider-XE3ADUUH.js +31 -0
  6. package/dist/{AnalyticsProvider-V2U3TQMH.js.map → AnalyticsProvider-XE3ADUUH.js.map} +1 -1
  7. package/dist/{BlogViewTracker-COTPD7WL.js → BlogViewTracker-DVJHZ7CM.js} +6 -6
  8. package/dist/{BlogViewTracker-COTPD7WL.js.map → BlogViewTracker-DVJHZ7CM.js.map} +1 -1
  9. package/dist/{BlogViewTracker-HG25ONRP.mjs → BlogViewTracker-MKJYTTJQ.mjs} +5 -5
  10. package/dist/{BlogViewTracker-HG25ONRP.mjs.map → BlogViewTracker-MKJYTTJQ.mjs.map} +1 -1
  11. package/dist/ChatWidget-BD4F4XLD.mjs +11 -0
  12. package/dist/{ChatWidget-RWO7R7EJ.mjs.map → ChatWidget-BD4F4XLD.mjs.map} +1 -1
  13. package/dist/ChatWidget-BZ3KOSXG.js +20 -0
  14. package/dist/{ChatWidget-4QUJYFXU.js.map → ChatWidget-BZ3KOSXG.js.map} +1 -1
  15. package/dist/EngageWidget-JPP6EDCJ.js +18 -0
  16. package/dist/{EngageWidget-RSOXB3YM.js.map → EngageWidget-JPP6EDCJ.js.map} +1 -1
  17. package/dist/EngageWidget-L7B6PCM3.mjs +9 -0
  18. package/dist/{EngageWidget-LF4AC4QN.mjs.map → EngageWidget-L7B6PCM3.mjs.map} +1 -1
  19. package/dist/{FileField-YJ7DZXC3.mjs → FileField-7WPRONDS.mjs} +5 -5
  20. package/dist/{FileField-YJ7DZXC3.mjs.map → FileField-7WPRONDS.mjs.map} +1 -1
  21. package/dist/{FileField-S2GUM3QB.js → FileField-GHT7444Y.js} +6 -6
  22. package/dist/{FileField-S2GUM3QB.js.map → FileField-GHT7444Y.js.map} +1 -1
  23. package/dist/{FormSpotlight-7WAXLXZA.js → FormSpotlight-BB2IB7IX.js} +18 -18
  24. package/dist/{FormSpotlight-7WAXLXZA.js.map → FormSpotlight-BB2IB7IX.js.map} +1 -1
  25. package/dist/{FormSpotlight-HLH5LQKI.mjs → FormSpotlight-WZVS6HHR.mjs} +4 -4
  26. package/dist/{FormSpotlight-HLH5LQKI.mjs.map → FormSpotlight-WZVS6HHR.mjs.map} +1 -1
  27. package/dist/{FormStage-LEZYERJB.js → FormStage-FLBLXENZ.js} +15 -15
  28. package/dist/{FormStage-LEZYERJB.js.map → FormStage-FLBLXENZ.js.map} +1 -1
  29. package/dist/{FormStage-Q5JW75AF.mjs → FormStage-Y3NHHMV2.mjs} +4 -4
  30. package/dist/{FormStage-Q5JW75AF.mjs.map → FormStage-Y3NHHMV2.mjs.map} +1 -1
  31. package/dist/ManagedForm-2OPCHDNJ.js +23 -0
  32. package/dist/{ManagedForm-H4SEFSAF.js.map → ManagedForm-2OPCHDNJ.js.map} +1 -1
  33. package/dist/ManagedForm-AJM6D4SK.mjs +14 -0
  34. package/dist/{ManagedForm-U3NFIVEC.mjs.map → ManagedForm-AJM6D4SK.mjs.map} +1 -1
  35. package/dist/{ManagedNewsletterForm-KT2NGUNW.js → ManagedNewsletterForm-L2ZHJ7F4.js} +8 -8
  36. package/dist/{ManagedNewsletterForm-KT2NGUNW.js.map → ManagedNewsletterForm-L2ZHJ7F4.js.map} +1 -1
  37. package/dist/{ManagedNewsletterForm-YKYW7B6P.mjs → ManagedNewsletterForm-MJI2JXIB.mjs} +7 -7
  38. package/dist/{ManagedNewsletterForm-YKYW7B6P.mjs.map → ManagedNewsletterForm-MJI2JXIB.mjs.map} +1 -1
  39. package/dist/{SignalCore-2BH5PUGS.mjs → SignalCore-23YDDSWO.mjs} +5 -5
  40. package/dist/{SignalCore-2BH5PUGS.mjs.map → SignalCore-23YDDSWO.mjs.map} +1 -1
  41. package/dist/{SignalCore-JM4ODFL2.js → SignalCore-G2VM7NUP.js} +11 -11
  42. package/dist/{SignalCore-JM4ODFL2.js.map → SignalCore-G2VM7NUP.js.map} +1 -1
  43. package/dist/SitemapSync-T2N3TCWF.js +17 -0
  44. package/dist/{SitemapSync-J4UMJRTO.js.map → SitemapSync-T2N3TCWF.js.map} +1 -1
  45. package/dist/SitemapSync-YLWMU6J3.mjs +8 -0
  46. package/dist/{SitemapSync-5CXS2JGB.mjs.map → SitemapSync-YLWMU6J3.mjs.map} +1 -1
  47. package/dist/analytics/index.js +9 -9
  48. package/dist/analytics/index.mjs +4 -4
  49. package/dist/blog/index.js +20 -20
  50. package/dist/blog/index.mjs +3 -3
  51. package/dist/blog/server-ui.js +14 -14
  52. package/dist/blog/server-ui.mjs +2 -2
  53. package/dist/{chunk-44ZTBQH4.js → chunk-2MPOO6QJ.js} +3 -3
  54. package/dist/{chunk-44ZTBQH4.js.map → chunk-2MPOO6QJ.js.map} +1 -1
  55. package/dist/{chunk-E3GHVAMK.js → chunk-2VQ5YXOD.js} +23 -23
  56. package/dist/{chunk-E3GHVAMK.js.map → chunk-2VQ5YXOD.js.map} +1 -1
  57. package/dist/{chunk-CGQO7MFO.js → chunk-47566YF4.js} +14 -14
  58. package/dist/{chunk-CGQO7MFO.js.map → chunk-47566YF4.js.map} +1 -1
  59. package/dist/{chunk-ADOGOLYO.mjs → chunk-4HL6CAZ7.mjs} +4 -4
  60. package/dist/{chunk-ADOGOLYO.mjs.map → chunk-4HL6CAZ7.mjs.map} +1 -1
  61. package/dist/{chunk-DTNNZJYM.mjs → chunk-4IMZ45YA.mjs} +5 -5
  62. package/dist/{chunk-DTNNZJYM.mjs.map → chunk-4IMZ45YA.mjs.map} +1 -1
  63. package/dist/{chunk-ACLBRIYD.js → chunk-4S7BHFGT.js} +3 -3
  64. package/dist/{chunk-ACLBRIYD.js.map → chunk-4S7BHFGT.js.map} +1 -1
  65. package/dist/{chunk-FMOOQKZU.js → chunk-5HMN3FXL.js} +10 -10
  66. package/dist/{chunk-FMOOQKZU.js.map → chunk-5HMN3FXL.js.map} +1 -1
  67. package/dist/{chunk-TAM2D54C.js → chunk-5TGSM5EQ.js} +14 -14
  68. package/dist/{chunk-TAM2D54C.js.map → chunk-5TGSM5EQ.js.map} +1 -1
  69. package/dist/{chunk-BVLGJ2CZ.mjs → chunk-77HT6TYK.mjs} +3 -3
  70. package/dist/{chunk-BVLGJ2CZ.mjs.map → chunk-77HT6TYK.mjs.map} +1 -1
  71. package/dist/{chunk-2XHEUWHV.mjs → chunk-7UPPYERC.mjs} +4 -4
  72. package/dist/{chunk-2XHEUWHV.mjs.map → chunk-7UPPYERC.mjs.map} +1 -1
  73. package/dist/chunk-AEW7EFYU.js +147 -0
  74. package/dist/chunk-AEW7EFYU.js.map +1 -0
  75. package/dist/{chunk-OAJVITNO.mjs → chunk-AJBJH3BA.mjs} +3 -3
  76. package/dist/{chunk-OAJVITNO.mjs.map → chunk-AJBJH3BA.mjs.map} +1 -1
  77. package/dist/{chunk-SXNKLHOX.mjs → chunk-AKQA5ZYZ.mjs} +3 -3
  78. package/dist/{chunk-SXNKLHOX.mjs.map → chunk-AKQA5ZYZ.mjs.map} +1 -1
  79. package/dist/{chunk-WZMM57R2.js → chunk-APL44ZVK.js} +5 -5
  80. package/dist/{chunk-WZMM57R2.js.map → chunk-APL44ZVK.js.map} +1 -1
  81. package/dist/{chunk-JEI3CSY4.js → chunk-AVPMSJCQ.js} +4 -4
  82. package/dist/{chunk-JEI3CSY4.js.map → chunk-AVPMSJCQ.js.map} +1 -1
  83. package/dist/{chunk-TECD4AP7.mjs → chunk-COAVBUMS.mjs} +3 -3
  84. package/dist/{chunk-TECD4AP7.mjs.map → chunk-COAVBUMS.mjs.map} +1 -1
  85. package/dist/{chunk-BUDV7QHH.mjs → chunk-DBJRJ2Q2.mjs} +4 -4
  86. package/dist/{chunk-BUDV7QHH.mjs.map → chunk-DBJRJ2Q2.mjs.map} +1 -1
  87. package/dist/{chunk-OTHKWMDB.mjs → chunk-DN6A6KXH.mjs} +3 -3
  88. package/dist/{chunk-OTHKWMDB.mjs.map → chunk-DN6A6KXH.mjs.map} +1 -1
  89. package/dist/{chunk-GYAH4KFC.js → chunk-DTX4R45S.js} +40 -4
  90. package/dist/chunk-DTX4R45S.js.map +1 -0
  91. package/dist/{chunk-UMWVTIIZ.mjs → chunk-FH4LLJFL.mjs} +8 -8
  92. package/dist/{chunk-UMWVTIIZ.mjs.map → chunk-FH4LLJFL.mjs.map} +1 -1
  93. package/dist/{chunk-ZFZMN4LT.mjs → chunk-GM5E6R5W.mjs} +39 -3
  94. package/dist/chunk-GM5E6R5W.mjs.map +1 -0
  95. package/dist/{chunk-GZVSGQKT.js → chunk-GPH3VVLP.js} +3 -3
  96. package/dist/{chunk-GZVSGQKT.js.map → chunk-GPH3VVLP.js.map} +1 -1
  97. package/dist/{chunk-CBMHJPR7.js → chunk-GQTSQR63.js} +5 -5
  98. package/dist/{chunk-CBMHJPR7.js.map → chunk-GQTSQR63.js.map} +1 -1
  99. package/dist/{chunk-BGBJSMXT.js → chunk-GTK3CGWF.js} +6 -6
  100. package/dist/{chunk-BGBJSMXT.js.map → chunk-GTK3CGWF.js.map} +1 -1
  101. package/dist/{chunk-LB7LHVWI.mjs → chunk-H7274TKR.mjs} +9 -3
  102. package/dist/chunk-H7274TKR.mjs.map +1 -0
  103. package/dist/{chunk-MCXHQHIX.js → chunk-HIV5YK5G.js} +4 -4
  104. package/dist/{chunk-MCXHQHIX.js.map → chunk-HIV5YK5G.js.map} +1 -1
  105. package/dist/chunk-HRQ4367C.mjs +6 -0
  106. package/dist/{chunk-4SQ6PROR.mjs.map → chunk-HRQ4367C.mjs.map} +1 -1
  107. package/dist/{chunk-A3VGZAZQ.mjs → chunk-I72AUITZ.mjs} +3 -3
  108. package/dist/{chunk-A3VGZAZQ.mjs.map → chunk-I72AUITZ.mjs.map} +1 -1
  109. package/dist/{chunk-2ACKOMAL.js → chunk-IPV2TUAT.js} +9 -3
  110. package/dist/chunk-IPV2TUAT.js.map +1 -0
  111. package/dist/{chunk-CYQB5GLU.mjs → chunk-ISKJLXB4.mjs} +4 -4
  112. package/dist/{chunk-CYQB5GLU.mjs.map → chunk-ISKJLXB4.mjs.map} +1 -1
  113. package/dist/{chunk-HPIY7AR3.js → chunk-KP56C66Z.js} +14 -14
  114. package/dist/{chunk-HPIY7AR3.js.map → chunk-KP56C66Z.js.map} +1 -1
  115. package/dist/{chunk-PXAALKTP.js → chunk-KP5BFPGT.js} +5 -3
  116. package/dist/chunk-KP5BFPGT.js.map +1 -0
  117. package/dist/{chunk-VCNPTLK2.js → chunk-LFJRMY4V.js} +12 -12
  118. package/dist/{chunk-VCNPTLK2.js.map → chunk-LFJRMY4V.js.map} +1 -1
  119. package/dist/{chunk-2EJX56YJ.js → chunk-LHD45PGP.js} +8 -8
  120. package/dist/{chunk-2EJX56YJ.js.map → chunk-LHD45PGP.js.map} +1 -1
  121. package/dist/chunk-MLXUMVBK.mjs +142 -0
  122. package/dist/chunk-MLXUMVBK.mjs.map +1 -0
  123. package/dist/{chunk-ROJ25QM3.mjs → chunk-NW5CBNRU.mjs} +3 -3
  124. package/dist/{chunk-ROJ25QM3.mjs.map → chunk-NW5CBNRU.mjs.map} +1 -1
  125. package/dist/{chunk-5G2ZRQMO.mjs → chunk-PA5ZVCW2.mjs} +3 -3
  126. package/dist/{chunk-5G2ZRQMO.mjs.map → chunk-PA5ZVCW2.mjs.map} +1 -1
  127. package/dist/{chunk-IQLYFQKZ.js → chunk-QG7WHAGD.js} +15 -15
  128. package/dist/{chunk-IQLYFQKZ.js.map → chunk-QG7WHAGD.js.map} +1 -1
  129. package/dist/{chunk-FZISCIJV.mjs → chunk-R4PFWVGZ.mjs} +4 -4
  130. package/dist/{chunk-FZISCIJV.mjs.map → chunk-R4PFWVGZ.mjs.map} +1 -1
  131. package/dist/{chunk-5YKMHPJL.mjs → chunk-R5F2JQVX.mjs} +5 -3
  132. package/dist/chunk-R5F2JQVX.mjs.map +1 -0
  133. package/dist/{chunk-CKPFETIO.js → chunk-SHZXSIRH.js} +4 -4
  134. package/dist/{chunk-CKPFETIO.js.map → chunk-SHZXSIRH.js.map} +1 -1
  135. package/dist/{chunk-NSTY7ZZA.mjs → chunk-SI7R3IJX.mjs} +8 -8
  136. package/dist/{chunk-NSTY7ZZA.mjs.map → chunk-SI7R3IJX.mjs.map} +1 -1
  137. package/dist/{chunk-ACWGG4VW.js → chunk-TAIGHH5J.js} +9 -9
  138. package/dist/{chunk-ACWGG4VW.js.map → chunk-TAIGHH5J.js.map} +1 -1
  139. package/dist/chunk-TMQKZ4DO.js +8 -0
  140. package/dist/{chunk-YPEX4RDE.js.map → chunk-TMQKZ4DO.js.map} +1 -1
  141. package/dist/{chunk-VIIGOCX4.js → chunk-UJOEN4X6.js} +15 -15
  142. package/dist/{chunk-VIIGOCX4.js.map → chunk-UJOEN4X6.js.map} +1 -1
  143. package/dist/{chunk-EZLK2OQL.js → chunk-UYR22S67.js} +7 -7
  144. package/dist/{chunk-EZLK2OQL.js.map → chunk-UYR22S67.js.map} +1 -1
  145. package/dist/{chunk-5W56B52Z.mjs → chunk-VGX6G3TA.mjs} +3 -3
  146. package/dist/{chunk-5W56B52Z.mjs.map → chunk-VGX6G3TA.mjs.map} +1 -1
  147. package/dist/{chunk-WMNRTCYY.js → chunk-VLR2UYO4.js} +11 -11
  148. package/dist/{chunk-WMNRTCYY.js.map → chunk-VLR2UYO4.js.map} +1 -1
  149. package/dist/{chunk-VWVUYL5J.mjs → chunk-W47J6ZZG.mjs} +4 -4
  150. package/dist/{chunk-VWVUYL5J.mjs.map → chunk-W47J6ZZG.mjs.map} +1 -1
  151. package/dist/{chunk-NIJVVW4G.mjs → chunk-WD57YWY5.mjs} +3 -3
  152. package/dist/{chunk-NIJVVW4G.mjs.map → chunk-WD57YWY5.mjs.map} +1 -1
  153. package/dist/{chunk-ADBLBGCQ.mjs → chunk-WZZYTFDV.mjs} +3 -3
  154. package/dist/{chunk-ADBLBGCQ.mjs.map → chunk-WZZYTFDV.mjs.map} +1 -1
  155. package/dist/{chunk-EKTMXHBI.mjs → chunk-X4PL7R63.mjs} +3 -3
  156. package/dist/{chunk-EKTMXHBI.mjs.map → chunk-X4PL7R63.mjs.map} +1 -1
  157. package/dist/{chunk-6YKNDQYJ.mjs → chunk-XR47TOGW.mjs} +3 -3
  158. package/dist/{chunk-6YKNDQYJ.mjs.map → chunk-XR47TOGW.mjs.map} +1 -1
  159. package/dist/{chunk-DKRXPXOR.js → chunk-ZMFJXFUY.js} +3 -3
  160. package/dist/{chunk-DKRXPXOR.js.map → chunk-ZMFJXFUY.js.map} +1 -1
  161. package/dist/cli/index.js +3 -3
  162. package/dist/cli/index.mjs +1 -1
  163. package/dist/client/index.js +4 -4
  164. package/dist/client/index.mjs +3 -3
  165. package/dist/commerce/index.js +56 -56
  166. package/dist/commerce/index.mjs +5 -5
  167. package/dist/config/index.js +2 -2
  168. package/dist/config/index.mjs +1 -1
  169. package/dist/engage/index.js +13 -13
  170. package/dist/engage/index.mjs +7 -7
  171. package/dist/fleet/index.js +8 -8
  172. package/dist/fleet/index.mjs +4 -4
  173. package/dist/forms/FormField.d.ts +2 -1
  174. package/dist/forms/FormField.d.ts.map +1 -1
  175. package/dist/forms/ga4-identity.d.ts +31 -0
  176. package/dist/forms/ga4-identity.d.ts.map +1 -0
  177. package/dist/forms/ga4-identity.test.d.ts +2 -0
  178. package/dist/forms/ga4-identity.test.d.ts.map +1 -0
  179. package/dist/forms/index.js +24 -24
  180. package/dist/forms/index.mjs +10 -10
  181. package/dist/forms/server.js +11 -11
  182. package/dist/forms/server.mjs +9 -9
  183. package/dist/forms/static.js +8 -8
  184. package/dist/forms/static.mjs +7 -7
  185. package/dist/forms/styles.css +21 -0
  186. package/dist/forms/submitForm.d.ts.map +1 -1
  187. package/dist/forms/types.d.ts +13 -0
  188. package/dist/forms/types.d.ts.map +1 -1
  189. package/dist/images/index.js +11 -11
  190. package/dist/images/index.mjs +4 -4
  191. package/dist/index.js +63 -63
  192. package/dist/index.mjs +9 -9
  193. package/dist/layout/client.js +8 -8
  194. package/dist/layout/client.mjs +7 -7
  195. package/dist/layout/index.js +10 -10
  196. package/dist/layout/index.mjs +8 -8
  197. package/dist/maps/index.js +5 -5
  198. package/dist/maps/index.mjs +3 -3
  199. package/dist/motion/Parallax.d.ts +42 -0
  200. package/dist/motion/Parallax.d.ts.map +1 -0
  201. package/dist/motion/Reveal.d.ts +59 -0
  202. package/dist/motion/Reveal.d.ts.map +1 -0
  203. package/dist/motion/ScrollScene.d.ts +42 -0
  204. package/dist/motion/ScrollScene.d.ts.map +1 -0
  205. package/dist/motion/engine.d.ts +74 -0
  206. package/dist/motion/engine.d.ts.map +1 -0
  207. package/dist/motion/failsafe.d.ts +20 -0
  208. package/dist/motion/failsafe.d.ts.map +1 -0
  209. package/dist/motion/gsap.d.ts +84 -0
  210. package/dist/motion/gsap.d.ts.map +1 -0
  211. package/dist/motion/gsap.js +103 -0
  212. package/dist/motion/gsap.js.map +1 -0
  213. package/dist/motion/gsap.mjs +99 -0
  214. package/dist/motion/gsap.mjs.map +1 -0
  215. package/dist/motion/index.d.ts +31 -0
  216. package/dist/motion/index.d.ts.map +1 -0
  217. package/dist/motion/index.js +252 -0
  218. package/dist/motion/index.js.map +1 -0
  219. package/dist/motion/index.mjs +230 -0
  220. package/dist/motion/index.mjs.map +1 -0
  221. package/dist/motion/motion.test.d.ts +16 -0
  222. package/dist/motion/motion.test.d.ts.map +1 -0
  223. package/dist/motion/three.d.ts +105 -0
  224. package/dist/motion/three.d.ts.map +1 -0
  225. package/dist/motion/three.js +150 -0
  226. package/dist/motion/three.js.map +1 -0
  227. package/dist/motion/three.mjs +145 -0
  228. package/dist/motion/three.mjs.map +1 -0
  229. package/dist/proxy/index.js +3 -3
  230. package/dist/proxy/index.mjs +2 -2
  231. package/dist/proxy/securityHeaders.d.ts +21 -6
  232. package/dist/proxy/securityHeaders.d.ts.map +1 -1
  233. package/dist/search/index.js +4 -4
  234. package/dist/search/index.mjs +3 -3
  235. package/dist/seo/client.js +5 -5
  236. package/dist/seo/client.mjs +4 -4
  237. package/dist/seo/index.js +5 -5
  238. package/dist/seo/index.mjs +4 -4
  239. package/dist/server/index.js +3 -3
  240. package/dist/server/index.mjs +2 -2
  241. package/dist/shared/build-entries.d.ts +7 -1
  242. package/dist/shared/build-entries.d.ts.map +1 -1
  243. package/dist/shared/version.d.ts +1 -1
  244. package/dist/signal/index.js +11 -11
  245. package/dist/signal/index.mjs +2 -2
  246. package/dist/sync/index.js +16 -16
  247. package/dist/sync/index.mjs +4 -4
  248. package/package.json +28 -2
  249. package/skills/site-kit/SKILL.md +6 -0
  250. package/dist/AnalyticsProvider-2LCSA6G3.mjs +0 -10
  251. package/dist/AnalyticsProvider-V2U3TQMH.js +0 -31
  252. package/dist/ChatWidget-4QUJYFXU.js +0 -20
  253. package/dist/ChatWidget-RWO7R7EJ.mjs +0 -11
  254. package/dist/EngageWidget-LF4AC4QN.mjs +0 -9
  255. package/dist/EngageWidget-RSOXB3YM.js +0 -18
  256. package/dist/ManagedForm-H4SEFSAF.js +0 -23
  257. package/dist/ManagedForm-U3NFIVEC.mjs +0 -14
  258. package/dist/SitemapSync-5CXS2JGB.mjs +0 -8
  259. package/dist/SitemapSync-J4UMJRTO.js +0 -17
  260. package/dist/chunk-2ACKOMAL.js.map +0 -1
  261. package/dist/chunk-4SQ6PROR.mjs +0 -6
  262. package/dist/chunk-5YKMHPJL.mjs.map +0 -1
  263. package/dist/chunk-GYAH4KFC.js.map +0 -1
  264. package/dist/chunk-LB7LHVWI.mjs.map +0 -1
  265. package/dist/chunk-PXAALKTP.js.map +0 -1
  266. package/dist/chunk-YPEX4RDE.js +0 -8
  267. package/dist/chunk-ZFZMN4LT.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/motion/engine.ts"],"names":[],"mappings":"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","file":"chunk-MLXUMVBK.mjs","sourcesContent":["/**\n * @sonordev/site-kit/motion — the scroll engine.\n *\n * One idea, applied everywhere: pin a scene, turn scroll into p in [0,1],\n * render(p). Every motion primitive in this module (Reveal, Parallax,\n * ScrollScene, the GSAP and three.js tiers) sits on this loop.\n *\n * Rules the engine enforces so every site inherits them:\n *\n * - Native scroll only. The wheel is never hijacked and the body is never\n * transformed; the liquid feel comes from each scene lerping its rendered\n * p toward the real scroll position.\n * - One shared requestAnimationFrame loop drives every visible scene and\n * sleeps when everything has settled. A page with thirty parallax layers\n * costs one rAF, not thirty.\n * - Offscreen scenes (beyond a 35% viewport margin) are not rendered at all.\n * - prefers-reduced-motion holds each scene at a fixed representative frame\n * instead of scrubbing, and the loop stays asleep.\n * - Nothing here touches the DOM at import time, so it is safe in any module\n * graph a server component reaches; scenes register from effects.\n *\n * Zero dependencies, ~2KB. Extracted from the upforgelabs.com engine\n * (components/cinema/engine.ts) — that repo's docs/SCROLL-CINEMA.md is the\n * full playbook for building scenes on top of it.\n */\n\nexport type SceneMode = 'pin' | 'view'\n\nexport interface SceneInfo {\n /** The un-smoothed progress the scene is easing toward. */\n target: number\n /** False on the single frame rendered as the scene leaves the margin. */\n visible: boolean\n}\n\nexport type SceneRender = (p: number, info: SceneInfo) => void\n\nexport interface SceneOptions {\n /** Keep rendering every frame while visible (shader time, particles). */\n continuous?: boolean\n /** Frame to hold under prefers-reduced-motion. Default 0.55. */\n reducedP?: number\n /**\n * \"pin\": progress across a tall sticky wrapper — 0 when its top reaches\n * the top of the viewport, 1 when its bottom does (default).\n * \"view\": progress of a normal block traveling through the viewport —\n * 0 as its top enters at the bottom, 1 as its bottom leaves at the top.\n */\n mode?: SceneMode\n /**\n * Per-frame interpolation toward the real scroll position, in (0, 1].\n * Lower is more liquid, 1 is locked to the scrollbar. Default 0.16.\n */\n lerp?: number\n}\n\ninterface Scene {\n pin: HTMLElement\n cb: SceneRender\n p: number\n target: number\n top: number\n height: number\n visible: boolean\n settled: boolean\n continuous: boolean\n reducedP: number\n mode: SceneMode\n lerp: number\n}\n\nconst scenes = new Set<Scene>()\nlet rafId = 0\nlet io: IntersectionObserver | null = null\nlet initialized = false\nlet reduced = false\nlet measureTimer: ReturnType<typeof setTimeout> | undefined\n\nconst clamp01 = (v: number) => Math.min(1, Math.max(0, v))\n\n/**\n * Pure progress math, exported so it can be unit-tested and reused by\n * anything that wants the same mapping without registering a scene.\n */\nexport function sceneProgress(\n mode: SceneMode,\n top: number,\n height: number,\n scrollY: number,\n viewportHeight: number,\n): number {\n if (mode === 'view') {\n return clamp01((scrollY + viewportHeight - top) / (viewportHeight + height))\n }\n return clamp01((scrollY - top) / Math.max(1, height - viewportHeight))\n}\n\nfunction measureAll() {\n const sy = window.scrollY\n for (const s of scenes) {\n const r = s.pin.getBoundingClientRect()\n s.top = r.top + sy\n s.height = s.pin.offsetHeight\n s.settled = false\n }\n}\n\nfunction targetFor(s: Scene, sy: number, vh: number): number {\n return sceneProgress(s.mode, s.top, s.height, sy, vh)\n}\n\nfunction frame() {\n rafId = 0\n const sy = window.scrollY\n const vh = window.innerHeight\n let active = false\n for (const s of scenes) {\n if (!s.visible) continue\n s.target = reduced ? s.reducedP : targetFor(s, sy, vh)\n const d = s.target - s.p\n if (Math.abs(d) > 0.0006) {\n s.p += d * s.lerp\n s.settled = false\n active = true\n } else if (!s.settled) {\n s.p = s.target\n s.settled = true\n } else if (!s.continuous) {\n continue\n }\n if (s.continuous) active = true\n s.cb(s.p, { target: s.target, visible: s.visible })\n }\n if (active) schedule()\n}\n\nfunction schedule() {\n if (!rafId) rafId = requestAnimationFrame(frame)\n}\n\nfunction wake() {\n for (const s of scenes) s.settled = false\n schedule()\n}\n\nfunction init() {\n if (initialized || typeof window === 'undefined') return\n initialized = true\n\n const mq = window.matchMedia('(prefers-reduced-motion: reduce)')\n reduced = mq.matches\n mq.addEventListener?.('change', (e) => {\n reduced = e.matches\n wake()\n })\n\n io = new IntersectionObserver(\n (entries) => {\n const sy = window.scrollY\n const vh = window.innerHeight\n for (const entry of entries) {\n for (const s of scenes) {\n if (s.pin !== entry.target) continue\n s.visible = entry.isIntersecting\n if (!entry.isIntersecting) {\n // Leaving mid-lerp would freeze a stale in-between frame. Snap\n // to the resting state on exit and tell the scene it is gone.\n s.p = reduced ? s.reducedP : targetFor(s, sy, vh)\n s.settled = true\n s.cb(s.p, { target: s.p, visible: false })\n }\n }\n }\n schedule()\n },\n { rootMargin: '35% 0px 35% 0px' },\n )\n\n window.addEventListener('scroll', wake, { passive: true })\n window.addEventListener('resize', () => {\n clearTimeout(measureTimer)\n measureTimer = setTimeout(() => {\n measureAll()\n wake()\n }, 120)\n })\n document.fonts?.ready?.then(() => {\n measureAll()\n wake()\n })\n}\n\n/** True when the visitor asked for reduced motion. Always false on the server. */\nexport function prefersReducedMotion(): boolean {\n if (typeof window === 'undefined') return false\n init()\n return reduced\n}\n\n/**\n * Re-measure every scene and redraw. Call after a layout change the engine\n * cannot see — an accordion opening above a scene, images without\n * dimensions settling, a font swap outside document.fonts.\n */\nexport function refreshScenes(): void {\n if (typeof window === 'undefined' || !initialized) return\n measureAll()\n wake()\n}\n\n/**\n * Register a scene. Returns an unregister function for effect cleanup.\n *\n * `pin` is the element whose position drives progress: the tall wrapper of\n * a sticky stage in \"pin\" mode, or the block itself in \"view\" mode. The\n * callback runs only while the pin is within 35% of the viewport, plus one\n * final frame as it leaves.\n */\nexport function registerScene(\n pin: HTMLElement,\n cb: SceneRender,\n opts: SceneOptions = {},\n): () => void {\n if (typeof window === 'undefined') return () => {}\n init()\n const s: Scene = {\n pin,\n cb,\n p: 0,\n target: 0,\n top: 0,\n height: 1,\n visible: false,\n settled: false,\n continuous: !!opts.continuous,\n reducedP: opts.reducedP ?? 0.55,\n mode: opts.mode ?? 'pin',\n lerp: Math.min(1, Math.max(0.01, opts.lerp ?? 0.16)),\n }\n scenes.add(s)\n io?.observe(pin)\n // A pin the observer already watches fires no new entry for a scene that\n // registers late (after a lazy import, say), so seed visibility from the\n // current geometry instead of waiting for a change that never comes.\n const r = pin.getBoundingClientRect()\n const margin = window.innerHeight * 0.35\n s.visible = r.bottom > -margin && r.top < window.innerHeight + margin\n measureAll()\n schedule()\n return () => {\n scenes.delete(s)\n io?.unobserve(pin)\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { resolveSiteHost } from './chunk-GZJE23Y5.mjs';
2
- import { configureSiteCredential, currentCredential } from './chunk-SXNKLHOX.mjs';
2
+ import { configureSiteCredential, currentCredential } from './chunk-AKQA5ZYZ.mjs';
3
3
 
4
4
  // src/shared/publishCredential.ts
5
5
  function publishSiteCredential({
@@ -19,5 +19,5 @@ function publishSiteCredential({
19
19
  }
20
20
 
21
21
  export { publishSiteCredential };
22
- //# sourceMappingURL=chunk-ROJ25QM3.mjs.map
23
- //# sourceMappingURL=chunk-ROJ25QM3.mjs.map
22
+ //# sourceMappingURL=chunk-NW5CBNRU.mjs.map
23
+ //# sourceMappingURL=chunk-NW5CBNRU.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/shared/publishCredential.ts"],"names":[],"mappings":";;;;AAkEO,SAAS,qBAAA,CAAsB;AAAA,EACpC,MAAA;AAAA,EACA,MAAA,GAAS,sBAAA;AAAA,EACT,IAAA;AAAA,EACA,KAAA,GAAQ,KAAA;AAAA,EACR;AACF,CAAA,EAAuC;AACrC,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AAKnC,EAAA,uBAAA,CAAwB,EAAE,UAAA,EAAY,MAAA,EAAQ,MAAA,EAAQ,CAAA;AACrD,EAAC,OAAe,oBAAA,GAAuB,MAAA;AACvC,EAAC,MAAA,CAAe,oBAAA,GAAuB,iBAAA,CAAkB,MAAM,CAAA;AAC/D,EAAC,OAAe,kBAAA,GAAqB,KAAA;AACrC,EAAC,MAAA,CAAe,iBAAA,GAAoB,IAAA,IAAQ,eAAA,EAAgB;AAG7D,EAAA,IAAI,cAAA,EAAiB,MAAA,CAAe,uBAAA,GAA0B,cAAA;AAChE","file":"chunk-ROJ25QM3.mjs","sourcesContent":["/**\n * @sonordev/site-kit shared — Client credential + window-global publishing\n *\n * SINGLE SOURCE OF TRUTH for seeding the browser-side token manager and the\n * `window.__SITE_KIT_*` globals that every client module reads. Used by:\n *\n * - `SiteKitClientProviders` (core `SiteKitLayout`)\n * - `SiteKitCredential` (`@sonordev/site-kit/client`) — the public component\n * for layouts that are NOT core `SiteKitLayout`, e.g.\n * `@sonordev/agency-site-kit`'s `AgencySiteKitLayout`.\n *\n * Do not re-fork this. Before it existed, agency sites hand-rolled their own\n * \"set the globals on mount\" component (upforge's `UptradeSiteKitInit`), and\n * because those copies had no access to the token manager they published the\n * RAW `sonor_` key into the client bundle — the exact exposure the mint exists\n * to prevent. Any layout that puts a credential on `window` goes through here.\n *\n * Client-safe: no `server-only` guard, SSR-safe (every write is window-gated).\n * The minting half is server-only and lives in `../server/mint-site-token`.\n */\n// Leaf modules, NOT '../sites/contract' — see sites/normalize.ts. Importing the\n// full contract here shipped its JSON schema to every browser that loads a\n// credential-publishing entry.\nimport { resolveSiteHost } from '../sites/resolve'\nimport { configureSiteCredential, currentCredential } from './siteToken'\n\n/**\n * Re-exported so the client-side callers below and every existing importer keep\n * a single name for this. The implementation lives in `../sites/resolve` — the\n * ONE resolver shared by the browser (this file) and the build-time sitemap /\n * llms.txt path, so both tag the same host.\n */\nexport { resolveSiteHost }\n\nexport interface PublishSiteCredentialOptions {\n /**\n * The credential the layout minted server-side. In 3.2+ this is a short-lived\n * `st1.` token that `sonorFetch` refreshes transparently. A raw `sonor_` key\n * still works (2.x kit, or the mint-failed fallback) but should never be\n * routed here from a client component — it would ship the secret to the\n * browser.\n */\n apiKey?: string\n apiUrl?: string\n /** Pre-resolved sub-site host. Omit to resolve via `resolveSiteHost`. */\n site?: string\n debug?: boolean\n /**\n * Referrer-restricted Google Maps BROWSER key for client map components.\n * Resolved server-side by SiteKitLayout (NEXT_PUBLIC_GOOGLE_MAPS_API_KEY /\n * GOOGLE_MAPS_BROWSER_KEY) because maps/api.ts runs client-side, where a bare\n * process.env read is dead code unless the app's bundler happens to inline it.\n * Never route a server secret here.\n */\n mapsBrowserKey?: string\n}\n\n/**\n * Seed the token manager and publish the `window.__SITE_KIT_*` globals.\n *\n * Called during RENDER, not in an effect: client modules read these globals in\n * their own mount effects, and effects run child-first, so an effect-based\n * publish would land after the modules that need it.\n *\n * No-op on the server.\n */\nexport function publishSiteCredential({\n apiKey,\n apiUrl = 'https://api.sonor.io',\n site,\n debug = false,\n mapsBrowserKey,\n}: PublishSiteCredentialOptions): void {\n if (typeof window === 'undefined') return\n\n // Seed the client token manager. The window global is set to the freshest\n // token held — a prior page this session may already have refreshed past the\n // seed the layout injected. In raw-key mode this is a passthrough.\n configureSiteCredential({ credential: apiKey, apiUrl })\n ;(window as any).__SITE_KIT_API_URL__ = apiUrl\n ;(window as any).__SITE_KIT_API_KEY__ = currentCredential(apiKey)\n ;(window as any).__SITE_KIT_DEBUG__ = debug\n ;(window as any).__SITE_KIT_SITE__ = site ?? resolveSiteHost()\n // maps/api.ts falls back to this global when the Sonor platform hasn't\n // provisioned a browser key. Don't clobber a value another layout already set.\n if (mapsBrowserKey) (window as any).__GOOGLE_MAPS_API_KEY__ = mapsBrowserKey\n}\n"]}
1
+ {"version":3,"sources":["../src/shared/publishCredential.ts"],"names":[],"mappings":";;;;AAkEO,SAAS,qBAAA,CAAsB;AAAA,EACpC,MAAA;AAAA,EACA,MAAA,GAAS,sBAAA;AAAA,EACT,IAAA;AAAA,EACA,KAAA,GAAQ,KAAA;AAAA,EACR;AACF,CAAA,EAAuC;AACrC,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AAKnC,EAAA,uBAAA,CAAwB,EAAE,UAAA,EAAY,MAAA,EAAQ,MAAA,EAAQ,CAAA;AACrD,EAAC,OAAe,oBAAA,GAAuB,MAAA;AACvC,EAAC,MAAA,CAAe,oBAAA,GAAuB,iBAAA,CAAkB,MAAM,CAAA;AAC/D,EAAC,OAAe,kBAAA,GAAqB,KAAA;AACrC,EAAC,MAAA,CAAe,iBAAA,GAAoB,IAAA,IAAQ,eAAA,EAAgB;AAG7D,EAAA,IAAI,cAAA,EAAiB,MAAA,CAAe,uBAAA,GAA0B,cAAA;AAChE","file":"chunk-NW5CBNRU.mjs","sourcesContent":["/**\n * @sonordev/site-kit shared — Client credential + window-global publishing\n *\n * SINGLE SOURCE OF TRUTH for seeding the browser-side token manager and the\n * `window.__SITE_KIT_*` globals that every client module reads. Used by:\n *\n * - `SiteKitClientProviders` (core `SiteKitLayout`)\n * - `SiteKitCredential` (`@sonordev/site-kit/client`) — the public component\n * for layouts that are NOT core `SiteKitLayout`, e.g.\n * `@sonordev/agency-site-kit`'s `AgencySiteKitLayout`.\n *\n * Do not re-fork this. Before it existed, agency sites hand-rolled their own\n * \"set the globals on mount\" component (upforge's `UptradeSiteKitInit`), and\n * because those copies had no access to the token manager they published the\n * RAW `sonor_` key into the client bundle — the exact exposure the mint exists\n * to prevent. Any layout that puts a credential on `window` goes through here.\n *\n * Client-safe: no `server-only` guard, SSR-safe (every write is window-gated).\n * The minting half is server-only and lives in `../server/mint-site-token`.\n */\n// Leaf modules, NOT '../sites/contract' — see sites/normalize.ts. Importing the\n// full contract here shipped its JSON schema to every browser that loads a\n// credential-publishing entry.\nimport { resolveSiteHost } from '../sites/resolve'\nimport { configureSiteCredential, currentCredential } from './siteToken'\n\n/**\n * Re-exported so the client-side callers below and every existing importer keep\n * a single name for this. The implementation lives in `../sites/resolve` — the\n * ONE resolver shared by the browser (this file) and the build-time sitemap /\n * llms.txt path, so both tag the same host.\n */\nexport { resolveSiteHost }\n\nexport interface PublishSiteCredentialOptions {\n /**\n * The credential the layout minted server-side. In 3.2+ this is a short-lived\n * `st1.` token that `sonorFetch` refreshes transparently. A raw `sonor_` key\n * still works (2.x kit, or the mint-failed fallback) but should never be\n * routed here from a client component — it would ship the secret to the\n * browser.\n */\n apiKey?: string\n apiUrl?: string\n /** Pre-resolved sub-site host. Omit to resolve via `resolveSiteHost`. */\n site?: string\n debug?: boolean\n /**\n * Referrer-restricted Google Maps BROWSER key for client map components.\n * Resolved server-side by SiteKitLayout (NEXT_PUBLIC_GOOGLE_MAPS_API_KEY /\n * GOOGLE_MAPS_BROWSER_KEY) because maps/api.ts runs client-side, where a bare\n * process.env read is dead code unless the app's bundler happens to inline it.\n * Never route a server secret here.\n */\n mapsBrowserKey?: string\n}\n\n/**\n * Seed the token manager and publish the `window.__SITE_KIT_*` globals.\n *\n * Called during RENDER, not in an effect: client modules read these globals in\n * their own mount effects, and effects run child-first, so an effect-based\n * publish would land after the modules that need it.\n *\n * No-op on the server.\n */\nexport function publishSiteCredential({\n apiKey,\n apiUrl = 'https://api.sonor.io',\n site,\n debug = false,\n mapsBrowserKey,\n}: PublishSiteCredentialOptions): void {\n if (typeof window === 'undefined') return\n\n // Seed the client token manager. The window global is set to the freshest\n // token held — a prior page this session may already have refreshed past the\n // seed the layout injected. In raw-key mode this is a passthrough.\n configureSiteCredential({ credential: apiKey, apiUrl })\n ;(window as any).__SITE_KIT_API_URL__ = apiUrl\n ;(window as any).__SITE_KIT_API_KEY__ = currentCredential(apiKey)\n ;(window as any).__SITE_KIT_DEBUG__ = debug\n ;(window as any).__SITE_KIT_SITE__ = site ?? resolveSiteHost()\n // maps/api.ts falls back to this global when the Sonor platform hasn't\n // provisioned a browser key. Don't clobber a value another layout already set.\n if (mapsBrowserKey) (window as any).__GOOGLE_MAPS_API_KEY__ = mapsBrowserKey\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- import { sonorFetch } from './chunk-ADOGOLYO.mjs';
2
+ import { sonorFetch } from './chunk-4HL6CAZ7.mjs';
3
3
  import { useState, useCallback, useEffect } from 'react';
4
4
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
5
5
 
@@ -521,5 +521,5 @@ async function clearImageSlot(config, slotId, pagePath) {
521
521
  }
522
522
 
523
523
  export { ManagedImage, assignImageToSlot, clearImageSlot, fetchManagedImage, fetchManagedImages, listImageFiles, uploadImage };
524
- //# sourceMappingURL=chunk-5G2ZRQMO.mjs.map
525
- //# sourceMappingURL=chunk-5G2ZRQMO.mjs.map
524
+ //# sourceMappingURL=chunk-PA5ZVCW2.mjs.map
525
+ //# sourceMappingURL=chunk-PA5ZVCW2.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/images/ManagedImage.tsx","../src/images/api.ts"],"names":[],"mappings":"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","file":"chunk-5G2ZRQMO.mjs","sourcesContent":["/**\n * ManagedImage - Portal-managed image component\n * \n * Features:\n * - Fetches images from Portal API via API key (never direct Supabase)\n * - Dev mode: Click to open image picker modal\n * - Supports responsive variants\n * - Automatic focal point handling\n * - Placeholder state for empty slots\n * \n * @example\n * ```tsx\n * <ManagedImage \n * slotId=\"hero-background\"\n * alt=\"Hero background image\"\n * className=\"w-full h-96 object-cover\"\n * />\n * ```\n */\n\n'use client'\n\nimport React, { useState, useEffect, useCallback } from 'react'\nimport { sonorFetch } from '../shared/sonorFetch'\n\nexport interface ManagedImageData {\n id: string\n slot_id: string\n page_path: string | null\n file_id: string | null\n external_url: string | null\n alt_text: string | null\n title: string | null\n caption: string | null\n focal_point_x: number\n focal_point_y: number\n aspect_ratio: string | null\n public_url?: string\n is_placeholder: boolean\n}\n\nexport interface ImageFile {\n id: string\n filename: string\n storage_path: string\n mime_type: string\n file_size: number\n folder_path: string | null\n public_url?: string\n}\n\nexport interface ManagedImageProps {\n /** API key for Portal API */\n apiKey?: string\n /** API URL (defaults to https://api.sonor.io) */\n apiUrl?: string\n /** Unique slot identifier (e.g., 'hero-background', 'about-team-1') */\n slotId: string\n /** Page path for page-specific slots (defaults to current path) */\n pagePath?: string\n /** Fallback alt text if not set in Portal */\n alt?: string\n /** CSS class names */\n className?: string\n /** Image width */\n width?: number | string\n /** Image height */\n height?: number | string\n /** CSS object-fit property */\n objectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down'\n /** Fallback image URL when no image assigned */\n fallback?: string\n /** Custom placeholder component */\n placeholder?: React.ReactNode\n /** Called when image loads */\n onLoad?: () => void\n /** Called on error */\n onError?: (error: Error) => void\n /** Priority loading (Next.js Image optimization) */\n priority?: boolean\n /** Additional styles */\n style?: React.CSSProperties\n /** Enable dev picker even outside dev mode */\n forceDevMode?: boolean\n}\n\n// Check if we're in dev mode\nconst isDevMode = (): boolean => {\n if (typeof window === 'undefined') return false\n return (\n process.env.NODE_ENV === 'development' ||\n window.location.hostname === 'localhost' ||\n window.location.hostname === '127.0.0.1' ||\n window.location.search.includes('uptrade_dev=true')\n )\n}\n\nexport function ManagedImage({\n apiKey = process.env.SONOR_API_KEY,\n apiUrl = process.env.SONOR_API_URL || 'https://api.sonor.io',\n slotId,\n pagePath,\n alt,\n className = '',\n width,\n height,\n objectFit = 'cover',\n fallback,\n placeholder,\n onLoad,\n onError,\n priority,\n style,\n forceDevMode,\n}: ManagedImageProps) {\n const [imageData, setImageData] = useState<ManagedImageData | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<Error | null>(null)\n const [showPicker, setShowPicker] = useState(false)\n const [devMode] = useState(() => forceDevMode || isDevMode())\n\n // Get current page path if not provided\n const currentPath = pagePath ?? (typeof window !== 'undefined' ? window.location.pathname : '/')\n\n // Fetch image data from Portal API\n const fetchImage = useCallback(async () => {\n if (!apiKey || !apiUrl) {\n setLoading(false)\n return\n }\n\n try {\n const params = new URLSearchParams({ page_path: currentPath })\n const res = await sonorFetch(\n `${apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch image: ${res.status}`)\n }\n\n const data = await res.json()\n setImageData(data.image)\n setError(null)\n } catch (err) {\n // warn, not error: a failed slot fetch must not fail the Lighthouse\n // best-practices errors-in-console audit on every page using this slot.\n console.warn('[ManagedImage] Fetch error:', err)\n setError(err instanceof Error ? err : new Error(String(err)))\n onError?.(err instanceof Error ? err : new Error(String(err)))\n } finally {\n setLoading(false)\n }\n }, [apiKey, apiUrl, slotId, currentPath, onError])\n\n useEffect(() => {\n fetchImage()\n }, [fetchImage])\n\n // Calculate object-position from focal point\n const objectPosition = imageData\n ? `${imageData.focal_point_x}% ${imageData.focal_point_y}%`\n : '50% 50%'\n\n // Get the image URL\n const imageUrl = imageData?.public_url || imageData?.external_url || fallback\n\n // Handle click in dev mode\n const handleClick = (e: React.MouseEvent) => {\n if (devMode) {\n e.preventDefault()\n e.stopPropagation()\n setShowPicker(true)\n }\n }\n\n // Render placeholder state\n if (loading) {\n return (\n <div\n className={`bg-gray-200 animate-pulse ${className}`}\n style={{\n width: width ?? '100%',\n height: height ?? 200,\n ...style,\n }}\n />\n )\n }\n\n // No image assigned - show placeholder or dev picker hint\n if (!imageUrl) {\n if (placeholder) {\n return <>{placeholder}</>\n }\n\n return (\n <div\n onClick={handleClick}\n className={`\n bg-gray-100 border-2 border-dashed border-gray-300 \n flex items-center justify-center text-gray-400\n ${devMode ? 'cursor-pointer hover:border-blue-400 hover:text-blue-500 hover:bg-blue-50' : ''}\n ${className}\n `}\n style={{\n width: width ?? '100%',\n height: height ?? 200,\n ...style,\n }}\n title={devMode ? `Click to add image for slot: ${slotId}` : undefined}\n >\n <div className=\"text-center p-4\">\n <svg\n className=\"w-12 h-12 mx-auto mb-2\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n />\n </svg>\n {devMode && (\n <p className=\"text-sm font-medium\">Click to add image</p>\n )}\n <p className=\"text-xs mt-1\">{slotId}</p>\n </div>\n\n {showPicker && (\n <ImagePickerModal\n slotId={slotId}\n pagePath={currentPath}\n config={{ apiKey, apiUrl }}\n onClose={() => setShowPicker(false)}\n onSelect={() => {\n setShowPicker(false)\n fetchImage()\n }}\n />\n )}\n </div>\n )\n }\n\n // Render the image\n return (\n <div className=\"relative\" style={{ width, height }}>\n <img\n src={imageUrl}\n alt={imageData?.alt_text || alt || ''}\n title={imageData?.title || undefined}\n data-managed-image=\"true\"\n data-slot-id={slotId}\n data-page-path={currentPath}\n className={className}\n style={{\n objectFit,\n objectPosition,\n width: width ?? '100%',\n height: height ?? 'auto',\n ...style,\n }}\n onLoad={onLoad}\n onError={() => onError?.(new Error('Image failed to load'))}\n loading={priority ? 'eager' : 'lazy'}\n onClick={handleClick}\n />\n\n {/* Dev mode overlay */}\n {devMode && (\n <div\n className=\"absolute inset-0 bg-black/0 hover:bg-black/30 transition-colors cursor-pointer flex items-center justify-center opacity-0 hover:opacity-100\"\n onClick={handleClick}\n >\n <div className=\"bg-white/90 px-3 py-1.5 rounded-lg shadow-lg text-sm font-medium text-gray-700\">\n Edit Image\n </div>\n </div>\n )}\n\n {showPicker && (\n <ImagePickerModal\n slotId={slotId}\n pagePath={currentPath}\n config={{ apiKey, apiUrl }}\n currentImage={imageData}\n onClose={() => setShowPicker(false)}\n onSelect={() => {\n setShowPicker(false)\n fetchImage()\n }}\n />\n )}\n </div>\n )\n}\n\n// ============================================================================\n// IMAGE PICKER MODAL\n// ============================================================================\n\ninterface ImagePickerModalProps {\n slotId: string\n pagePath: string\n config: any\n currentImage?: ManagedImageData | null\n onClose: () => void\n onSelect: () => void\n}\n\nfunction ImagePickerModal({\n slotId,\n pagePath,\n config,\n currentImage,\n onClose,\n onSelect,\n}: ImagePickerModalProps) {\n const [files, setFiles] = useState<ImageFile[]>([])\n const [folders, setFolders] = useState<string[]>([])\n const [currentFolder, setCurrentFolder] = useState<string>('')\n const [search, setSearch] = useState('')\n const [loading, setLoading] = useState(true)\n const [uploading, setUploading] = useState(false)\n const [altText, setAltText] = useState(currentImage?.alt_text || '')\n\n // Fetch available files\n const fetchFiles = useCallback(async () => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n setLoading(true)\n try {\n const params = new URLSearchParams()\n if (currentFolder) params.set('folder', currentFolder)\n if (search) params.set('search', search)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/files?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (res.ok) {\n const data = await res.json()\n setFiles(data.files || [])\n setFolders(data.folders || [])\n }\n } catch (err) {\n console.warn('[ImagePicker] Fetch error:', err)\n } finally {\n setLoading(false)\n }\n }, [config?.apiKey, config?.apiUrl, currentFolder, search])\n\n useEffect(() => {\n fetchFiles()\n }, [fetchFiles])\n\n // Select an existing file\n const handleSelectFile = async (file: ImageFile) => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n try {\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n page_path: pagePath,\n file_id: file.id,\n alt_text: altText || file.filename,\n }),\n },\n { apiKey: config.apiKey, retries: 0 },\n )\n\n if (res.ok) {\n onSelect()\n }\n } catch (err) {\n console.warn('[ImagePicker] Select error:', err)\n }\n }\n\n // Upload new file\n const handleUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0]\n if (!file || !config?.apiKey || !config?.apiUrl) return\n\n setUploading(true)\n try {\n const formData = new FormData()\n formData.append('file', file)\n formData.append('slot_id', slotId)\n formData.append('page_path', pagePath)\n formData.append('folder', currentFolder || 'Website/Images')\n if (altText) formData.append('alt_text', altText)\n\n // No Content-Type — the browser sets the multipart boundary. Long\n // timeout, no retry: a retried upload would duplicate the file.\n const res = await sonorFetch(`${config.apiUrl}/public/images/upload`, {\n method: 'POST',\n body: formData,\n }, { apiKey: config.apiKey, retries: 0, timeoutMs: 60000 })\n\n if (res.ok) {\n onSelect()\n }\n } catch (err) {\n console.warn('[ImagePicker] Upload error:', err)\n } finally {\n setUploading(false)\n }\n }\n\n // Clear the slot\n const handleClear = async () => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n try {\n const params = new URLSearchParams({ page_path: pagePath })\n await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { method: 'DELETE' },\n { apiKey: config.apiKey, retries: 0 },\n )\n onSelect()\n } catch (err) {\n console.warn('[ImagePicker] Clear error:', err)\n }\n }\n\n return (\n <div\n className=\"fixed inset-0 z-[99999] bg-black/50 flex items-center justify-center p-4\"\n onClick={onClose}\n >\n <div\n className=\"bg-white rounded-xl shadow-2xl max-w-4xl w-full max-h-[90vh] overflow-hidden\"\n onClick={(e) => e.stopPropagation()}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between p-4 border-b\">\n <div>\n <h2 className=\"text-lg font-semibold\">Select Image</h2>\n <p className=\"text-sm text-gray-500\">Slot: {slotId}</p>\n </div>\n <button\n onClick={onClose}\n className=\"text-gray-400 hover:text-gray-600 p-2\"\n >\n <svg className=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n {/* Body */}\n <div className=\"p-4 overflow-y-auto\" style={{ maxHeight: 'calc(90vh - 180px)' }}>\n {/* Upload & Search */}\n <div className=\"flex gap-4 mb-4\">\n <div className=\"flex-1\">\n <input\n type=\"text\"\n placeholder=\"Search images...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"w-full px-3 py-2 border rounded-lg text-sm\"\n />\n </div>\n <label className=\"px-4 py-2 bg-blue-600 text-white rounded-lg cursor-pointer hover:bg-blue-700 text-sm font-medium flex items-center gap-2\">\n {uploading ? 'Uploading...' : 'Upload New'}\n <input\n type=\"file\"\n accept=\"image/*\"\n onChange={handleUpload}\n disabled={uploading}\n className=\"hidden\"\n />\n </label>\n {currentImage?.file_id && (\n <button\n onClick={handleClear}\n className=\"px-4 py-2 border border-red-200 text-red-600 rounded-lg hover:bg-red-50 text-sm\"\n >\n Remove\n </button>\n )}\n </div>\n\n {/* Alt text input */}\n <div className=\"mb-4\">\n <input\n type=\"text\"\n placeholder=\"Alt text for image...\"\n value={altText}\n onChange={(e) => setAltText(e.target.value)}\n className=\"w-full px-3 py-2 border rounded-lg text-sm\"\n />\n </div>\n\n {/* Folder navigation */}\n {folders.length > 0 && (\n <div className=\"flex gap-2 mb-4 flex-wrap\">\n <button\n onClick={() => setCurrentFolder('')}\n className={`px-3 py-1 text-sm rounded-full ${\n !currentFolder ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 hover:bg-gray-200'\n }`}\n >\n All\n </button>\n {folders.map((folder) => (\n <button\n key={folder}\n onClick={() => setCurrentFolder(folder)}\n className={`px-3 py-1 text-sm rounded-full ${\n currentFolder === folder ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 hover:bg-gray-200'\n }`}\n >\n {folder}\n </button>\n ))}\n </div>\n )}\n\n {/* File grid */}\n {loading ? (\n <div className=\"grid grid-cols-4 gap-4\">\n {[...Array(8)].map((_, i) => (\n <div key={i} className=\"aspect-square bg-gray-200 rounded-lg animate-pulse\" />\n ))}\n </div>\n ) : files.length === 0 ? (\n <div className=\"text-center py-12 text-gray-500\">\n <p>No images found</p>\n <p className=\"text-sm mt-1\">Upload a new image to get started</p>\n </div>\n ) : (\n <div className=\"grid grid-cols-4 gap-4\">\n {files.map((file) => (\n <button\n key={file.id}\n onClick={() => handleSelectFile(file)}\n className={`\n aspect-square rounded-lg overflow-hidden border-2 transition-all\n hover:border-blue-400 hover:shadow-lg\n ${currentImage?.file_id === file.id ? 'border-blue-500 ring-2 ring-blue-200' : 'border-gray-200'}\n `}\n >\n <img\n src={file.public_url}\n alt={file.filename}\n className=\"w-full h-full object-cover\"\n />\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"p-4 border-t bg-gray-50 flex justify-end\">\n <button\n onClick={onClose}\n className=\"px-4 py-2 text-gray-700 hover:bg-gray-100 rounded-lg text-sm\"\n >\n Cancel\n </button>\n </div>\n </div>\n </div>\n )\n}\n\nexport default ManagedImage\n","/**\n * Images API functions\n * \n * All functions use Portal API with API key authentication.\n * Never makes direct Supabase calls.\n */\n\nimport type { ManagedImageData, ImageFile } from './ManagedImage'\nimport { sonorFetch } from '../shared/sonorFetch'\n\nexport interface ImageApiConfig {\n apiUrl: string\n apiKey: string\n}\n\n/**\n * Fetch a managed image for a specific slot\n */\nexport async function fetchManagedImage(\n config: ImageApiConfig,\n slotId: string,\n pagePath?: string,\n): Promise<{ image: ManagedImageData | null; is_placeholder: boolean }> {\n const params = new URLSearchParams()\n if (pagePath) params.set('page_path', pagePath)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Fetch all managed images for the project\n */\nexport async function fetchManagedImages(\n config: ImageApiConfig,\n options?: {\n pagePath?: string\n category?: string\n includePlaceholders?: boolean\n },\n): Promise<{ images: ManagedImageData[] }> {\n const params = new URLSearchParams()\n if (options?.pagePath) params.set('page_path', options.pagePath)\n if (options?.category) params.set('category', options.category)\n if (options?.includePlaceholders) params.set('include_placeholders', 'true')\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch images: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * List available image files in the project\n */\nexport async function listImageFiles(\n config: ImageApiConfig,\n options?: {\n folder?: string\n search?: string\n },\n): Promise<{ files: ImageFile[]; folders: string[] }> {\n const params = new URLSearchParams()\n if (options?.folder) params.set('folder', options.folder)\n if (options?.search) params.set('search', options.search)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/files?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to list files: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Upload a new image\n */\nexport async function uploadImage(\n config: ImageApiConfig,\n file: File,\n options?: {\n slotId?: string\n pagePath?: string\n folder?: string\n altText?: string\n },\n): Promise<{ file: ImageFile; image?: ManagedImageData }> {\n const formData = new FormData()\n formData.append('file', file)\n if (options?.slotId) formData.append('slot_id', options.slotId)\n if (options?.pagePath) formData.append('page_path', options.pagePath)\n if (options?.folder) formData.append('folder', options.folder)\n if (options?.altText) formData.append('alt_text', options.altText)\n\n // No Content-Type — the browser sets the multipart boundary. Long timeout,\n // no retry: a retried upload would duplicate the file.\n const res = await sonorFetch(`${config.apiUrl}/public/images/upload`, {\n method: 'POST',\n body: formData,\n }, { apiKey: config.apiKey, retries: 0, timeoutMs: 60000 })\n\n if (!res.ok) {\n throw new Error(`Failed to upload image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Assign an existing file to an image slot\n */\nexport async function assignImageToSlot(\n config: ImageApiConfig,\n slotId: string,\n options: {\n fileId?: string\n externalUrl?: string\n pagePath?: string\n altText?: string\n title?: string\n caption?: string\n focalPointX?: number\n focalPointY?: number\n aspectRatio?: string\n },\n): Promise<{ image: ManagedImageData }> {\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n page_path: options.pagePath,\n file_id: options.fileId,\n external_url: options.externalUrl,\n alt_text: options.altText,\n title: options.title,\n caption: options.caption,\n focal_point_x: options.focalPointX,\n focal_point_y: options.focalPointY,\n aspect_ratio: options.aspectRatio,\n }),\n },\n { apiKey: config.apiKey, retries: 0 },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to assign image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Clear an image from a slot (keeps the file)\n */\nexport async function clearImageSlot(\n config: ImageApiConfig,\n slotId: string,\n pagePath?: string,\n): Promise<{ success: boolean }> {\n const params = new URLSearchParams()\n if (pagePath) params.set('page_path', pagePath)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { method: 'DELETE' },\n { apiKey: config.apiKey, retries: 0 },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to clear slot: ${res.status}`)\n }\n\n return res.json()\n}\n"]}
1
+ {"version":3,"sources":["../src/images/ManagedImage.tsx","../src/images/api.ts"],"names":[],"mappings":"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","file":"chunk-PA5ZVCW2.mjs","sourcesContent":["/**\n * ManagedImage - Portal-managed image component\n * \n * Features:\n * - Fetches images from Portal API via API key (never direct Supabase)\n * - Dev mode: Click to open image picker modal\n * - Supports responsive variants\n * - Automatic focal point handling\n * - Placeholder state for empty slots\n * \n * @example\n * ```tsx\n * <ManagedImage \n * slotId=\"hero-background\"\n * alt=\"Hero background image\"\n * className=\"w-full h-96 object-cover\"\n * />\n * ```\n */\n\n'use client'\n\nimport React, { useState, useEffect, useCallback } from 'react'\nimport { sonorFetch } from '../shared/sonorFetch'\n\nexport interface ManagedImageData {\n id: string\n slot_id: string\n page_path: string | null\n file_id: string | null\n external_url: string | null\n alt_text: string | null\n title: string | null\n caption: string | null\n focal_point_x: number\n focal_point_y: number\n aspect_ratio: string | null\n public_url?: string\n is_placeholder: boolean\n}\n\nexport interface ImageFile {\n id: string\n filename: string\n storage_path: string\n mime_type: string\n file_size: number\n folder_path: string | null\n public_url?: string\n}\n\nexport interface ManagedImageProps {\n /** API key for Portal API */\n apiKey?: string\n /** API URL (defaults to https://api.sonor.io) */\n apiUrl?: string\n /** Unique slot identifier (e.g., 'hero-background', 'about-team-1') */\n slotId: string\n /** Page path for page-specific slots (defaults to current path) */\n pagePath?: string\n /** Fallback alt text if not set in Portal */\n alt?: string\n /** CSS class names */\n className?: string\n /** Image width */\n width?: number | string\n /** Image height */\n height?: number | string\n /** CSS object-fit property */\n objectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down'\n /** Fallback image URL when no image assigned */\n fallback?: string\n /** Custom placeholder component */\n placeholder?: React.ReactNode\n /** Called when image loads */\n onLoad?: () => void\n /** Called on error */\n onError?: (error: Error) => void\n /** Priority loading (Next.js Image optimization) */\n priority?: boolean\n /** Additional styles */\n style?: React.CSSProperties\n /** Enable dev picker even outside dev mode */\n forceDevMode?: boolean\n}\n\n// Check if we're in dev mode\nconst isDevMode = (): boolean => {\n if (typeof window === 'undefined') return false\n return (\n process.env.NODE_ENV === 'development' ||\n window.location.hostname === 'localhost' ||\n window.location.hostname === '127.0.0.1' ||\n window.location.search.includes('uptrade_dev=true')\n )\n}\n\nexport function ManagedImage({\n apiKey = process.env.SONOR_API_KEY,\n apiUrl = process.env.SONOR_API_URL || 'https://api.sonor.io',\n slotId,\n pagePath,\n alt,\n className = '',\n width,\n height,\n objectFit = 'cover',\n fallback,\n placeholder,\n onLoad,\n onError,\n priority,\n style,\n forceDevMode,\n}: ManagedImageProps) {\n const [imageData, setImageData] = useState<ManagedImageData | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<Error | null>(null)\n const [showPicker, setShowPicker] = useState(false)\n const [devMode] = useState(() => forceDevMode || isDevMode())\n\n // Get current page path if not provided\n const currentPath = pagePath ?? (typeof window !== 'undefined' ? window.location.pathname : '/')\n\n // Fetch image data from Portal API\n const fetchImage = useCallback(async () => {\n if (!apiKey || !apiUrl) {\n setLoading(false)\n return\n }\n\n try {\n const params = new URLSearchParams({ page_path: currentPath })\n const res = await sonorFetch(\n `${apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch image: ${res.status}`)\n }\n\n const data = await res.json()\n setImageData(data.image)\n setError(null)\n } catch (err) {\n // warn, not error: a failed slot fetch must not fail the Lighthouse\n // best-practices errors-in-console audit on every page using this slot.\n console.warn('[ManagedImage] Fetch error:', err)\n setError(err instanceof Error ? err : new Error(String(err)))\n onError?.(err instanceof Error ? err : new Error(String(err)))\n } finally {\n setLoading(false)\n }\n }, [apiKey, apiUrl, slotId, currentPath, onError])\n\n useEffect(() => {\n fetchImage()\n }, [fetchImage])\n\n // Calculate object-position from focal point\n const objectPosition = imageData\n ? `${imageData.focal_point_x}% ${imageData.focal_point_y}%`\n : '50% 50%'\n\n // Get the image URL\n const imageUrl = imageData?.public_url || imageData?.external_url || fallback\n\n // Handle click in dev mode\n const handleClick = (e: React.MouseEvent) => {\n if (devMode) {\n e.preventDefault()\n e.stopPropagation()\n setShowPicker(true)\n }\n }\n\n // Render placeholder state\n if (loading) {\n return (\n <div\n className={`bg-gray-200 animate-pulse ${className}`}\n style={{\n width: width ?? '100%',\n height: height ?? 200,\n ...style,\n }}\n />\n )\n }\n\n // No image assigned - show placeholder or dev picker hint\n if (!imageUrl) {\n if (placeholder) {\n return <>{placeholder}</>\n }\n\n return (\n <div\n onClick={handleClick}\n className={`\n bg-gray-100 border-2 border-dashed border-gray-300 \n flex items-center justify-center text-gray-400\n ${devMode ? 'cursor-pointer hover:border-blue-400 hover:text-blue-500 hover:bg-blue-50' : ''}\n ${className}\n `}\n style={{\n width: width ?? '100%',\n height: height ?? 200,\n ...style,\n }}\n title={devMode ? `Click to add image for slot: ${slotId}` : undefined}\n >\n <div className=\"text-center p-4\">\n <svg\n className=\"w-12 h-12 mx-auto mb-2\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n />\n </svg>\n {devMode && (\n <p className=\"text-sm font-medium\">Click to add image</p>\n )}\n <p className=\"text-xs mt-1\">{slotId}</p>\n </div>\n\n {showPicker && (\n <ImagePickerModal\n slotId={slotId}\n pagePath={currentPath}\n config={{ apiKey, apiUrl }}\n onClose={() => setShowPicker(false)}\n onSelect={() => {\n setShowPicker(false)\n fetchImage()\n }}\n />\n )}\n </div>\n )\n }\n\n // Render the image\n return (\n <div className=\"relative\" style={{ width, height }}>\n <img\n src={imageUrl}\n alt={imageData?.alt_text || alt || ''}\n title={imageData?.title || undefined}\n data-managed-image=\"true\"\n data-slot-id={slotId}\n data-page-path={currentPath}\n className={className}\n style={{\n objectFit,\n objectPosition,\n width: width ?? '100%',\n height: height ?? 'auto',\n ...style,\n }}\n onLoad={onLoad}\n onError={() => onError?.(new Error('Image failed to load'))}\n loading={priority ? 'eager' : 'lazy'}\n onClick={handleClick}\n />\n\n {/* Dev mode overlay */}\n {devMode && (\n <div\n className=\"absolute inset-0 bg-black/0 hover:bg-black/30 transition-colors cursor-pointer flex items-center justify-center opacity-0 hover:opacity-100\"\n onClick={handleClick}\n >\n <div className=\"bg-white/90 px-3 py-1.5 rounded-lg shadow-lg text-sm font-medium text-gray-700\">\n Edit Image\n </div>\n </div>\n )}\n\n {showPicker && (\n <ImagePickerModal\n slotId={slotId}\n pagePath={currentPath}\n config={{ apiKey, apiUrl }}\n currentImage={imageData}\n onClose={() => setShowPicker(false)}\n onSelect={() => {\n setShowPicker(false)\n fetchImage()\n }}\n />\n )}\n </div>\n )\n}\n\n// ============================================================================\n// IMAGE PICKER MODAL\n// ============================================================================\n\ninterface ImagePickerModalProps {\n slotId: string\n pagePath: string\n config: any\n currentImage?: ManagedImageData | null\n onClose: () => void\n onSelect: () => void\n}\n\nfunction ImagePickerModal({\n slotId,\n pagePath,\n config,\n currentImage,\n onClose,\n onSelect,\n}: ImagePickerModalProps) {\n const [files, setFiles] = useState<ImageFile[]>([])\n const [folders, setFolders] = useState<string[]>([])\n const [currentFolder, setCurrentFolder] = useState<string>('')\n const [search, setSearch] = useState('')\n const [loading, setLoading] = useState(true)\n const [uploading, setUploading] = useState(false)\n const [altText, setAltText] = useState(currentImage?.alt_text || '')\n\n // Fetch available files\n const fetchFiles = useCallback(async () => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n setLoading(true)\n try {\n const params = new URLSearchParams()\n if (currentFolder) params.set('folder', currentFolder)\n if (search) params.set('search', search)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/files?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (res.ok) {\n const data = await res.json()\n setFiles(data.files || [])\n setFolders(data.folders || [])\n }\n } catch (err) {\n console.warn('[ImagePicker] Fetch error:', err)\n } finally {\n setLoading(false)\n }\n }, [config?.apiKey, config?.apiUrl, currentFolder, search])\n\n useEffect(() => {\n fetchFiles()\n }, [fetchFiles])\n\n // Select an existing file\n const handleSelectFile = async (file: ImageFile) => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n try {\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n page_path: pagePath,\n file_id: file.id,\n alt_text: altText || file.filename,\n }),\n },\n { apiKey: config.apiKey, retries: 0 },\n )\n\n if (res.ok) {\n onSelect()\n }\n } catch (err) {\n console.warn('[ImagePicker] Select error:', err)\n }\n }\n\n // Upload new file\n const handleUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0]\n if (!file || !config?.apiKey || !config?.apiUrl) return\n\n setUploading(true)\n try {\n const formData = new FormData()\n formData.append('file', file)\n formData.append('slot_id', slotId)\n formData.append('page_path', pagePath)\n formData.append('folder', currentFolder || 'Website/Images')\n if (altText) formData.append('alt_text', altText)\n\n // No Content-Type — the browser sets the multipart boundary. Long\n // timeout, no retry: a retried upload would duplicate the file.\n const res = await sonorFetch(`${config.apiUrl}/public/images/upload`, {\n method: 'POST',\n body: formData,\n }, { apiKey: config.apiKey, retries: 0, timeoutMs: 60000 })\n\n if (res.ok) {\n onSelect()\n }\n } catch (err) {\n console.warn('[ImagePicker] Upload error:', err)\n } finally {\n setUploading(false)\n }\n }\n\n // Clear the slot\n const handleClear = async () => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n try {\n const params = new URLSearchParams({ page_path: pagePath })\n await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { method: 'DELETE' },\n { apiKey: config.apiKey, retries: 0 },\n )\n onSelect()\n } catch (err) {\n console.warn('[ImagePicker] Clear error:', err)\n }\n }\n\n return (\n <div\n className=\"fixed inset-0 z-[99999] bg-black/50 flex items-center justify-center p-4\"\n onClick={onClose}\n >\n <div\n className=\"bg-white rounded-xl shadow-2xl max-w-4xl w-full max-h-[90vh] overflow-hidden\"\n onClick={(e) => e.stopPropagation()}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between p-4 border-b\">\n <div>\n <h2 className=\"text-lg font-semibold\">Select Image</h2>\n <p className=\"text-sm text-gray-500\">Slot: {slotId}</p>\n </div>\n <button\n onClick={onClose}\n className=\"text-gray-400 hover:text-gray-600 p-2\"\n >\n <svg className=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n {/* Body */}\n <div className=\"p-4 overflow-y-auto\" style={{ maxHeight: 'calc(90vh - 180px)' }}>\n {/* Upload & Search */}\n <div className=\"flex gap-4 mb-4\">\n <div className=\"flex-1\">\n <input\n type=\"text\"\n placeholder=\"Search images...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"w-full px-3 py-2 border rounded-lg text-sm\"\n />\n </div>\n <label className=\"px-4 py-2 bg-blue-600 text-white rounded-lg cursor-pointer hover:bg-blue-700 text-sm font-medium flex items-center gap-2\">\n {uploading ? 'Uploading...' : 'Upload New'}\n <input\n type=\"file\"\n accept=\"image/*\"\n onChange={handleUpload}\n disabled={uploading}\n className=\"hidden\"\n />\n </label>\n {currentImage?.file_id && (\n <button\n onClick={handleClear}\n className=\"px-4 py-2 border border-red-200 text-red-600 rounded-lg hover:bg-red-50 text-sm\"\n >\n Remove\n </button>\n )}\n </div>\n\n {/* Alt text input */}\n <div className=\"mb-4\">\n <input\n type=\"text\"\n placeholder=\"Alt text for image...\"\n value={altText}\n onChange={(e) => setAltText(e.target.value)}\n className=\"w-full px-3 py-2 border rounded-lg text-sm\"\n />\n </div>\n\n {/* Folder navigation */}\n {folders.length > 0 && (\n <div className=\"flex gap-2 mb-4 flex-wrap\">\n <button\n onClick={() => setCurrentFolder('')}\n className={`px-3 py-1 text-sm rounded-full ${\n !currentFolder ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 hover:bg-gray-200'\n }`}\n >\n All\n </button>\n {folders.map((folder) => (\n <button\n key={folder}\n onClick={() => setCurrentFolder(folder)}\n className={`px-3 py-1 text-sm rounded-full ${\n currentFolder === folder ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 hover:bg-gray-200'\n }`}\n >\n {folder}\n </button>\n ))}\n </div>\n )}\n\n {/* File grid */}\n {loading ? (\n <div className=\"grid grid-cols-4 gap-4\">\n {[...Array(8)].map((_, i) => (\n <div key={i} className=\"aspect-square bg-gray-200 rounded-lg animate-pulse\" />\n ))}\n </div>\n ) : files.length === 0 ? (\n <div className=\"text-center py-12 text-gray-500\">\n <p>No images found</p>\n <p className=\"text-sm mt-1\">Upload a new image to get started</p>\n </div>\n ) : (\n <div className=\"grid grid-cols-4 gap-4\">\n {files.map((file) => (\n <button\n key={file.id}\n onClick={() => handleSelectFile(file)}\n className={`\n aspect-square rounded-lg overflow-hidden border-2 transition-all\n hover:border-blue-400 hover:shadow-lg\n ${currentImage?.file_id === file.id ? 'border-blue-500 ring-2 ring-blue-200' : 'border-gray-200'}\n `}\n >\n <img\n src={file.public_url}\n alt={file.filename}\n className=\"w-full h-full object-cover\"\n />\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"p-4 border-t bg-gray-50 flex justify-end\">\n <button\n onClick={onClose}\n className=\"px-4 py-2 text-gray-700 hover:bg-gray-100 rounded-lg text-sm\"\n >\n Cancel\n </button>\n </div>\n </div>\n </div>\n )\n}\n\nexport default ManagedImage\n","/**\n * Images API functions\n * \n * All functions use Portal API with API key authentication.\n * Never makes direct Supabase calls.\n */\n\nimport type { ManagedImageData, ImageFile } from './ManagedImage'\nimport { sonorFetch } from '../shared/sonorFetch'\n\nexport interface ImageApiConfig {\n apiUrl: string\n apiKey: string\n}\n\n/**\n * Fetch a managed image for a specific slot\n */\nexport async function fetchManagedImage(\n config: ImageApiConfig,\n slotId: string,\n pagePath?: string,\n): Promise<{ image: ManagedImageData | null; is_placeholder: boolean }> {\n const params = new URLSearchParams()\n if (pagePath) params.set('page_path', pagePath)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Fetch all managed images for the project\n */\nexport async function fetchManagedImages(\n config: ImageApiConfig,\n options?: {\n pagePath?: string\n category?: string\n includePlaceholders?: boolean\n },\n): Promise<{ images: ManagedImageData[] }> {\n const params = new URLSearchParams()\n if (options?.pagePath) params.set('page_path', options.pagePath)\n if (options?.category) params.set('category', options.category)\n if (options?.includePlaceholders) params.set('include_placeholders', 'true')\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch images: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * List available image files in the project\n */\nexport async function listImageFiles(\n config: ImageApiConfig,\n options?: {\n folder?: string\n search?: string\n },\n): Promise<{ files: ImageFile[]; folders: string[] }> {\n const params = new URLSearchParams()\n if (options?.folder) params.set('folder', options.folder)\n if (options?.search) params.set('search', options.search)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/files?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to list files: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Upload a new image\n */\nexport async function uploadImage(\n config: ImageApiConfig,\n file: File,\n options?: {\n slotId?: string\n pagePath?: string\n folder?: string\n altText?: string\n },\n): Promise<{ file: ImageFile; image?: ManagedImageData }> {\n const formData = new FormData()\n formData.append('file', file)\n if (options?.slotId) formData.append('slot_id', options.slotId)\n if (options?.pagePath) formData.append('page_path', options.pagePath)\n if (options?.folder) formData.append('folder', options.folder)\n if (options?.altText) formData.append('alt_text', options.altText)\n\n // No Content-Type — the browser sets the multipart boundary. Long timeout,\n // no retry: a retried upload would duplicate the file.\n const res = await sonorFetch(`${config.apiUrl}/public/images/upload`, {\n method: 'POST',\n body: formData,\n }, { apiKey: config.apiKey, retries: 0, timeoutMs: 60000 })\n\n if (!res.ok) {\n throw new Error(`Failed to upload image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Assign an existing file to an image slot\n */\nexport async function assignImageToSlot(\n config: ImageApiConfig,\n slotId: string,\n options: {\n fileId?: string\n externalUrl?: string\n pagePath?: string\n altText?: string\n title?: string\n caption?: string\n focalPointX?: number\n focalPointY?: number\n aspectRatio?: string\n },\n): Promise<{ image: ManagedImageData }> {\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n page_path: options.pagePath,\n file_id: options.fileId,\n external_url: options.externalUrl,\n alt_text: options.altText,\n title: options.title,\n caption: options.caption,\n focal_point_x: options.focalPointX,\n focal_point_y: options.focalPointY,\n aspect_ratio: options.aspectRatio,\n }),\n },\n { apiKey: config.apiKey, retries: 0 },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to assign image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Clear an image from a slot (keeps the file)\n */\nexport async function clearImageSlot(\n config: ImageApiConfig,\n slotId: string,\n pagePath?: string,\n): Promise<{ success: boolean }> {\n const params = new URLSearchParams()\n if (pagePath) params.set('page_path', pagePath)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { method: 'DELETE' },\n { apiKey: config.apiKey, retries: 0 },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to clear slot: ${res.status}`)\n }\n\n return res.json()\n}\n"]}
@@ -1,8 +1,8 @@
1
1
  'use client';
2
2
  'use strict';
3
3
 
4
- var chunkVCNPTLK2_js = require('./chunk-VCNPTLK2.js');
5
- var chunkVIIGOCX4_js = require('./chunk-VIIGOCX4.js');
4
+ var chunkLFJRMY4V_js = require('./chunk-LFJRMY4V.js');
5
+ var chunkUJOEN4X6_js = require('./chunk-UJOEN4X6.js');
6
6
  var react = require('react');
7
7
  var ReactMarkdown = require('react-markdown');
8
8
  var jsxRuntime = require('react/jsx-runtime');
@@ -37,7 +37,7 @@ function InlineManagedForm({ slug, prefill, primaryColor, primaryRgb }) {
37
37
  submit,
38
38
  isSubmitting,
39
39
  isComplete
40
- } = chunkVCNPTLK2_js.useForm(slug, { initialValues: prefill || {} });
40
+ } = chunkLFJRMY4V_js.useForm(slug, { initialValues: prefill || {} });
41
41
  const cardStyle = {
42
42
  marginTop: 8,
43
43
  padding: 12,
@@ -389,7 +389,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, sign
389
389
  const { apiKey } = getApiConfig();
390
390
  if (!apiKey) return;
391
391
  let cancelled = false;
392
- chunkVIIGOCX4_js.sonorFetch(`${baseUrl}/api/public/seo/project-info`, {}, { apiKey, retries: 0 }).then((res) => res.ok ? res.json() : null).then((data) => {
392
+ chunkUJOEN4X6_js.sonorFetch(`${baseUrl}/api/public/seo/project-info`, {}, { apiKey, retries: 0 }).then((res) => res.ok ? res.json() : null).then((data) => {
393
393
  if (cancelled || !data?.valid || !data?.project_id) return;
394
394
  setResolvedProjectId(data.project_id);
395
395
  }).catch(() => {
@@ -403,7 +403,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, sign
403
403
  const apiKey = ensureApiKey();
404
404
  if (!apiKey) return;
405
405
  try {
406
- const response = await chunkVIIGOCX4_js.sonorFetch(`${baseUrl}/engage/widget/config?projectId=${projectId}`, {}, { apiKey, retries: 0 });
406
+ const response = await chunkUJOEN4X6_js.sonorFetch(`${baseUrl}/engage/widget/config?projectId=${projectId}`, {}, { apiKey, retries: 0 });
407
407
  if (response.ok) {
408
408
  const { data } = await response.json();
409
409
  setWidgetConfig(data ?? null);
@@ -419,7 +419,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, sign
419
419
  const apiKey = ensureApiKey();
420
420
  if (!apiKey) return null;
421
421
  try {
422
- const response = await chunkVIIGOCX4_js.sonorFetch(`${baseUrl}/engage/widget/availability?projectId=${projectId}`, {}, { apiKey, retries: 0 });
422
+ const response = await chunkUJOEN4X6_js.sonorFetch(`${baseUrl}/engage/widget/availability?projectId=${projectId}`, {}, { apiKey, retries: 0 });
423
423
  if (response.ok) {
424
424
  const { data } = await response.json();
425
425
  setAvailability(data);
@@ -436,7 +436,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, sign
436
436
  const apiKey = ensureApiKey();
437
437
  if (!apiKey) return null;
438
438
  try {
439
- const response = await chunkVIIGOCX4_js.sonorFetch(`${baseUrl}/engage/widget/session`, {
439
+ const response = await chunkUJOEN4X6_js.sonorFetch(`${baseUrl}/engage/widget/session`, {
440
440
  method: "POST",
441
441
  headers: { "Content-Type": "application/json" },
442
442
  body: JSON.stringify({
@@ -497,7 +497,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, sign
497
497
  pageUrl: typeof window !== "undefined" ? window.location.href : void 0,
498
498
  ...siteContext ? { siteContext } : {}
499
499
  };
500
- const res = await chunkVIIGOCX4_js.sonorFetch(url, {
500
+ const res = await chunkUJOEN4X6_js.sonorFetch(url, {
501
501
  method: "POST",
502
502
  headers: {
503
503
  "Content-Type": "application/json"
@@ -608,7 +608,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, sign
608
608
  if (currentSessionId) {
609
609
  const apiKey = ensureApiKey();
610
610
  if (apiKey) {
611
- chunkVIIGOCX4_js.sonorFetch(`${baseUrl}/engage/widget/messages?sessionId=${currentSessionId}`, {}, { apiKey, retries: 0 }).then((res) => res.ok ? res.json() : null).then((json) => {
611
+ chunkUJOEN4X6_js.sonorFetch(`${baseUrl}/engage/widget/messages?sessionId=${currentSessionId}`, {}, { apiKey, retries: 0 }).then((res) => res.ok ? res.json() : null).then((json) => {
612
612
  const data = json?.data ?? json;
613
613
  if (Array.isArray(data) && data.length) {
614
614
  setMessages((prev) => {
@@ -671,7 +671,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, sign
671
671
  try {
672
672
  const apiKey = ensureApiKey();
673
673
  if (!apiKey) return;
674
- const response = await chunkVIIGOCX4_js.sonorFetch(`${baseUrl}/engage/widget/messages?sessionId=${currentSessionId}`, {}, { apiKey, retries: 0 });
674
+ const response = await chunkUJOEN4X6_js.sonorFetch(`${baseUrl}/engage/widget/messages?sessionId=${currentSessionId}`, {}, { apiKey, retries: 0 });
675
675
  if (response.ok) {
676
676
  const { data } = await response.json();
677
677
  setMessages((prev) => {
@@ -824,7 +824,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, sign
824
824
  form.append("file", file);
825
825
  form.append("sessionId", sessionId);
826
826
  form.append("visitorId", visitorId);
827
- const res = await chunkVIIGOCX4_js.sonorFetch(`${baseUrl}/engage/widget/upload`, {
827
+ const res = await chunkUJOEN4X6_js.sonorFetch(`${baseUrl}/engage/widget/upload`, {
828
828
  method: "POST",
829
829
  body: form
830
830
  }, { apiKey, retries: 0 });
@@ -971,7 +971,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, sign
971
971
  if (!apiKey) return;
972
972
  setCheckingHandoff(true);
973
973
  try {
974
- const res = await chunkVIIGOCX4_js.sonorFetch(`${baseUrl}/engage/widget/handoff`, {
974
+ const res = await chunkUJOEN4X6_js.sonorFetch(`${baseUrl}/engage/widget/handoff`, {
975
975
  method: "POST",
976
976
  headers: { "Content-Type": "application/json" },
977
977
  body: JSON.stringify({ sessionId })
@@ -1010,7 +1010,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, sign
1010
1010
  setIsLoading(true);
1011
1011
  setOfflineError(null);
1012
1012
  try {
1013
- const response = await chunkVIIGOCX4_js.sonorFetch(`${baseUrl}/engage/widget/offline-form`, {
1013
+ const response = await chunkUJOEN4X6_js.sonorFetch(`${baseUrl}/engage/widget/offline-form`, {
1014
1014
  method: "POST",
1015
1015
  headers: { "Content-Type": "application/json" },
1016
1016
  body: JSON.stringify({
@@ -1611,5 +1611,5 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, sign
1611
1611
  }
1612
1612
 
1613
1613
  exports.ChatWidget = ChatWidget;
1614
- //# sourceMappingURL=chunk-IQLYFQKZ.js.map
1615
- //# sourceMappingURL=chunk-IQLYFQKZ.js.map
1614
+ //# sourceMappingURL=chunk-QG7WHAGD.js.map
1615
+ //# sourceMappingURL=chunk-QG7WHAGD.js.map