@salla.sa/twilight-theme-engine 1.0.133 → 1.0.135

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 (274) hide show
  1. package/dist/{AddToCartForm-2BD3R4BH.js → AddToCartForm-ODVZPTKN.js} +3 -3
  2. package/dist/{AddToCartForm-2BD3R4BH.js.map → AddToCartForm-ODVZPTKN.js.map} +1 -1
  3. package/dist/{BlogAuthorPage-BF5XVPHV.js → BlogAuthorPage-BU23SINI.js} +29 -29
  4. package/dist/{BlogAuthorPage-BF5XVPHV.js.map → BlogAuthorPage-BU23SINI.js.map} +1 -1
  5. package/dist/{BlogCategoryPage-BZTNFEM7.js → BlogCategoryPage-ZVITUHP4.js} +29 -29
  6. package/dist/{BlogCategoryPage-BZTNFEM7.js.map → BlogCategoryPage-ZVITUHP4.js.map} +1 -1
  7. package/dist/{BlogPage-7HOCNIL5.js → BlogPage-IN3V7FYK.js} +27 -27
  8. package/dist/{BlogPage-7HOCNIL5.js.map → BlogPage-IN3V7FYK.js.map} +1 -1
  9. package/dist/{BlogSinglePage-SF575W74.js → BlogSinglePage-UJG7YPYZ.js} +27 -27
  10. package/dist/{BlogSinglePage-SF575W74.js.map → BlogSinglePage-UJG7YPYZ.js.map} +1 -1
  11. package/dist/{BlogTagPage-TALXABAF.js → BlogTagPage-XDETNKGR.js} +29 -29
  12. package/dist/{BlogTagPage-TALXABAF.js.map → BlogTagPage-XDETNKGR.js.map} +1 -1
  13. package/dist/{BrandsPage-UNHLTVUG.js → BrandsPage-CBU7JFSX.js} +28 -28
  14. package/dist/{BrandsPage-UNHLTVUG.js.map → BrandsPage-CBU7JFSX.js.map} +1 -1
  15. package/dist/{Breadcrumb-VFMPAWSR.js → Breadcrumb-EA2XETAM.js} +27 -27
  16. package/dist/{Breadcrumb-VFMPAWSR.js.map → Breadcrumb-EA2XETAM.js.map} +1 -1
  17. package/dist/{CartItem-CI2XOVRH.js → CartItem-2TW36QTW.js} +27 -27
  18. package/dist/{CartItem-CI2XOVRH.js.map → CartItem-2TW36QTW.js.map} +1 -1
  19. package/dist/{CartSummary-EQOBVLXK.js → CartSummary-TW2CAX57.js} +27 -27
  20. package/dist/{CartSummary-EQOBVLXK.js.map → CartSummary-TW2CAX57.js.map} +1 -1
  21. package/dist/{Copyright-3JGEXCQZ.js → Copyright-57XPE75X.js} +3 -3
  22. package/dist/{Copyright-3JGEXCQZ.js.map → Copyright-57XPE75X.js.map} +1 -1
  23. package/dist/{CustomerLayout-V5T4OPRY.js → CustomerLayout-A2M7IY34.js} +27 -27
  24. package/dist/{CustomerLayout-V5T4OPRY.js.map → CustomerLayout-A2M7IY34.js.map} +1 -1
  25. package/dist/{Footer-QX4EO5Y4.js → Footer-L5BIYCZ2.js} +4 -4
  26. package/dist/{Footer-QX4EO5Y4.js.map → Footer-L5BIYCZ2.js.map} +1 -1
  27. package/dist/Header-NLBDW4MR.js +23 -0
  28. package/dist/{Header-ORMIZKUL.js.map → Header-NLBDW4MR.js.map} +1 -1
  29. package/dist/{LoyaltyPage-HCLFYNTM.js → LoyaltyPage-BVTDPSP3.js} +27 -27
  30. package/dist/{LoyaltyPage-HCLFYNTM.js.map → LoyaltyPage-BVTDPSP3.js.map} +1 -1
  31. package/dist/{LoyaltyPointsPage-V5OWHGR5.js → LoyaltyPointsPage-HZYPCO7C.js} +9 -9
  32. package/dist/{LoyaltyPointsPage-V5OWHGR5.js.map → LoyaltyPointsPage-HZYPCO7C.js.map} +1 -1
  33. package/dist/{MainMenu-RX7PU77H.js → MainMenu-3HP3YJDH.js} +8 -8
  34. package/dist/{MainMenu-RX7PU77H.js.map → MainMenu-3HP3YJDH.js.map} +1 -1
  35. package/dist/MaintenancePage-U5P43D52.js +7 -0
  36. package/dist/{MaintenancePage-A7CNHM7B.js.map → MaintenancePage-U5P43D52.js.map} +1 -1
  37. package/dist/{MasterLayout-CTVC6FPX.js → MasterLayout-KD3GLYYX.js} +27 -27
  38. package/dist/{MasterLayout-CTVC6FPX.js.map → MasterLayout-KD3GLYYX.js.map} +1 -1
  39. package/dist/{MobileMenu-EQFL7JGB.js → MobileMenu-3UEQTURY.js} +28 -28
  40. package/dist/{MobileMenu-EQFL7JGB.js.map → MobileMenu-3UEQTURY.js.map} +1 -1
  41. package/dist/{NotificationsPage-ZBZNPTZS.js → NotificationsPage-C6LNYZTB.js} +27 -27
  42. package/dist/{NotificationsPage-ZBZNPTZS.js.map → NotificationsPage-C6LNYZTB.js.map} +1 -1
  43. package/dist/{OrderSinglePage-LMWLOLW2.js → OrderSinglePage-LXKINOXP.js} +28 -28
  44. package/dist/{OrderSinglePage-LMWLOLW2.js.map → OrderSinglePage-LXKINOXP.js.map} +1 -1
  45. package/dist/{OrdersPage-6G7BES7J.js → OrdersPage-VBF3P3JH.js} +27 -27
  46. package/dist/{OrdersPage-6G7BES7J.js.map → OrdersPage-VBF3P3JH.js.map} +1 -1
  47. package/dist/{PageSingle-5TPYMYII.js → PageSingle-E7DTNIY7.js} +7 -7
  48. package/dist/{PageSingle-5TPYMYII.js.map → PageSingle-E7DTNIY7.js.map} +1 -1
  49. package/dist/{ProductDetails-JHZ2ZJAA.js → ProductDetails-ZQLQWU7S.js} +8 -8
  50. package/dist/{ProductDetails-JHZ2ZJAA.js.map → ProductDetails-ZQLQWU7S.js.map} +1 -1
  51. package/dist/{ProfilePage-6JITWBAJ.js → ProfilePage-7LAIDEHS.js} +27 -27
  52. package/dist/{ProfilePage-6JITWBAJ.js.map → ProfilePage-7LAIDEHS.js.map} +1 -1
  53. package/dist/{ReviewsPage-PFMEZ27R.js → ReviewsPage-FA3V745S.js} +3 -3
  54. package/dist/{ReviewsPage-PFMEZ27R.js.map → ReviewsPage-FA3V745S.js.map} +1 -1
  55. package/dist/{SeoCartWidget-ZU3ZZRQB.js → SeoCartWidget-4456ASOT.js} +27 -27
  56. package/dist/{SeoCartWidget-ZU3ZZRQB.js.map → SeoCartWidget-4456ASOT.js.map} +1 -1
  57. package/dist/{SettingsPage-J5AF6ECW.js → SettingsPage-IVOHCXVY.js} +27 -27
  58. package/dist/{SettingsPage-J5AF6ECW.js.map → SettingsPage-IVOHCXVY.js.map} +1 -1
  59. package/dist/StoreClosedNotification-DIF6SKBX.js +58 -0
  60. package/dist/{StoreClosedNotification-3FYHHAIP.js.map → StoreClosedNotification-DIF6SKBX.js.map} +1 -1
  61. package/dist/{TestimonialsPage-4Y55RF5P.js → TestimonialsPage-JY7MF5NW.js} +7 -7
  62. package/dist/{TestimonialsPage-4Y55RF5P.js.map → TestimonialsPage-JY7MF5NW.js.map} +1 -1
  63. package/dist/{ThankYouPage-WETHDHC2.js → ThankYouPage-KNHHBFPZ.js} +27 -27
  64. package/dist/{ThankYouPage-WETHDHC2.js.map → ThankYouPage-KNHHBFPZ.js.map} +1 -1
  65. package/dist/{WalletPage-PSTUYDCC.js → WalletPage-HH72DHOC.js} +28 -28
  66. package/dist/{WalletPage-PSTUYDCC.js.map → WalletPage-HH72DHOC.js.map} +1 -1
  67. package/dist/{WishlistPage-AROQHMZ2.js → WishlistPage-5BR63SMU.js} +29 -29
  68. package/dist/{WishlistPage-AROQHMZ2.js.map → WishlistPage-5BR63SMU.js.map} +1 -1
  69. package/dist/ambient/salla-components.d.ts +5 -0
  70. package/dist/api/advertisement.js +5 -5
  71. package/dist/api/apps.js +5 -5
  72. package/dist/api/blog.js +7 -7
  73. package/dist/api/brands.js +7 -7
  74. package/dist/api/cart.js +7 -7
  75. package/dist/api/category.js +7 -7
  76. package/dist/api/client.js +4 -4
  77. package/dist/api/home.js +5 -5
  78. package/dist/api/loyalty.js +7 -7
  79. package/dist/api/menu.js +5 -5
  80. package/dist/api/notification.js +5 -5
  81. package/dist/api/order.js +7 -7
  82. package/dist/api/page.js +7 -7
  83. package/dist/api/product.js +7 -7
  84. package/dist/api/profile.js +4 -4
  85. package/dist/api/store.js +6 -6
  86. package/dist/api/translations.js +5 -5
  87. package/dist/api/user.js +5 -5
  88. package/dist/api/wallet.js +5 -5
  89. package/dist/api/wishlist.js +8 -8
  90. package/dist/{chunk-WBPOWM74.js → chunk-25UDBM27.js} +4 -4
  91. package/dist/{chunk-WBPOWM74.js.map → chunk-25UDBM27.js.map} +1 -1
  92. package/dist/{chunk-XQLAAPWR.js → chunk-2GSYVPQS.js} +7 -7
  93. package/dist/{chunk-XQLAAPWR.js.map → chunk-2GSYVPQS.js.map} +1 -1
  94. package/dist/{chunk-2TLIULJZ.js → chunk-3E3ABCPC.js} +3 -3
  95. package/dist/{chunk-2TLIULJZ.js.map → chunk-3E3ABCPC.js.map} +1 -1
  96. package/dist/{chunk-HTV4KO7G.js → chunk-4CM6JIQF.js} +3 -3
  97. package/dist/{chunk-HTV4KO7G.js.map → chunk-4CM6JIQF.js.map} +1 -1
  98. package/dist/{chunk-U2I3W3KW.js → chunk-4NZKBANW.js} +4 -4
  99. package/dist/{chunk-U2I3W3KW.js.map → chunk-4NZKBANW.js.map} +1 -1
  100. package/dist/{chunk-OOLS535M.js → chunk-4SCGS2CM.js} +7 -7
  101. package/dist/{chunk-OOLS535M.js.map → chunk-4SCGS2CM.js.map} +1 -1
  102. package/dist/{chunk-XN77EK3X.js → chunk-5A37NING.js} +4 -4
  103. package/dist/{chunk-XN77EK3X.js.map → chunk-5A37NING.js.map} +1 -1
  104. package/dist/{chunk-ETQFCKGR.js → chunk-5AOW2SQW.js} +3 -3
  105. package/dist/{chunk-ETQFCKGR.js.map → chunk-5AOW2SQW.js.map} +1 -1
  106. package/dist/{chunk-EHTLXK5F.js → chunk-5UWRPWK2.js} +5 -5
  107. package/dist/{chunk-EHTLXK5F.js.map → chunk-5UWRPWK2.js.map} +1 -1
  108. package/dist/{chunk-7VNVCHID.js → chunk-6K34BCUP.js} +2 -2
  109. package/dist/{chunk-7VNVCHID.js.map → chunk-6K34BCUP.js.map} +1 -1
  110. package/dist/{chunk-QIJJTWW6.js → chunk-6VYW7CVL.js} +4 -4
  111. package/dist/{chunk-QIJJTWW6.js.map → chunk-6VYW7CVL.js.map} +1 -1
  112. package/dist/{chunk-JUFJV4AK.js → chunk-7U5OLKOS.js} +3 -3
  113. package/dist/{chunk-JUFJV4AK.js.map → chunk-7U5OLKOS.js.map} +1 -1
  114. package/dist/{chunk-B3DGM7TM.js → chunk-A5AU64GV.js} +4 -4
  115. package/dist/{chunk-B3DGM7TM.js.map → chunk-A5AU64GV.js.map} +1 -1
  116. package/dist/{chunk-GG5DAIGJ.js → chunk-AXWX5SJC.js} +5 -5
  117. package/dist/{chunk-GG5DAIGJ.js.map → chunk-AXWX5SJC.js.map} +1 -1
  118. package/dist/{chunk-CKH6WBMA.js → chunk-CZ6VJPCG.js} +3 -3
  119. package/dist/{chunk-CKH6WBMA.js.map → chunk-CZ6VJPCG.js.map} +1 -1
  120. package/dist/{chunk-F5BU7T6H.js → chunk-D53M5ASN.js} +7 -7
  121. package/dist/{chunk-F5BU7T6H.js.map → chunk-D53M5ASN.js.map} +1 -1
  122. package/dist/{chunk-RQG44QD7.js → chunk-E5DP3MHE.js} +6 -6
  123. package/dist/{chunk-RQG44QD7.js.map → chunk-E5DP3MHE.js.map} +1 -1
  124. package/dist/{chunk-FHU2MXZA.js → chunk-FXVII733.js} +18 -8
  125. package/dist/chunk-FXVII733.js.map +1 -0
  126. package/dist/{chunk-VSEMOZZY.js → chunk-HDSY5DWF.js} +3 -3
  127. package/dist/{chunk-VSEMOZZY.js.map → chunk-HDSY5DWF.js.map} +1 -1
  128. package/dist/{chunk-Z6E7MMXW.js → chunk-HIOYW3CS.js} +4 -4
  129. package/dist/{chunk-Z6E7MMXW.js.map → chunk-HIOYW3CS.js.map} +1 -1
  130. package/dist/{chunk-BK5TBUGG.js → chunk-HOJ5E2PG.js} +3 -3
  131. package/dist/{chunk-BK5TBUGG.js.map → chunk-HOJ5E2PG.js.map} +1 -1
  132. package/dist/{chunk-G3UTLR3D.js → chunk-IOLNWPRO.js} +4 -4
  133. package/dist/{chunk-G3UTLR3D.js.map → chunk-IOLNWPRO.js.map} +1 -1
  134. package/dist/{chunk-33UM6VQJ.js → chunk-KWJUCI7M.js} +4 -4
  135. package/dist/{chunk-33UM6VQJ.js.map → chunk-KWJUCI7M.js.map} +1 -1
  136. package/dist/{chunk-JGVEGQHJ.js → chunk-LFHYQ6AN.js} +3 -3
  137. package/dist/{chunk-JGVEGQHJ.js.map → chunk-LFHYQ6AN.js.map} +1 -1
  138. package/dist/{chunk-BYLNAYIZ.js → chunk-LUPDYN4T.js} +5 -5
  139. package/dist/{chunk-BYLNAYIZ.js.map → chunk-LUPDYN4T.js.map} +1 -1
  140. package/dist/{chunk-NVL6M25Q.js → chunk-MWG734P7.js} +3 -3
  141. package/dist/{chunk-NVL6M25Q.js.map → chunk-MWG734P7.js.map} +1 -1
  142. package/dist/{chunk-V2M5YNZQ.js → chunk-MWYKP7CI.js} +3 -3
  143. package/dist/{chunk-V2M5YNZQ.js.map → chunk-MWYKP7CI.js.map} +1 -1
  144. package/dist/{chunk-GYXUYHKO.js → chunk-NHA4SBKG.js} +4 -4
  145. package/dist/{chunk-GYXUYHKO.js.map → chunk-NHA4SBKG.js.map} +1 -1
  146. package/dist/{chunk-37O7OVPL.js → chunk-OJKTKMWS.js} +4 -4
  147. package/dist/{chunk-37O7OVPL.js.map → chunk-OJKTKMWS.js.map} +1 -1
  148. package/dist/chunk-OKKS2RA4.js +14 -0
  149. package/dist/{chunk-JYEUOEEI.js.map → chunk-OKKS2RA4.js.map} +1 -1
  150. package/dist/{chunk-QGKARX6O.js → chunk-P3D67RVR.js} +8 -8
  151. package/dist/{chunk-QGKARX6O.js.map → chunk-P3D67RVR.js.map} +1 -1
  152. package/dist/{chunk-MBSWV56J.js → chunk-P6TJCCM3.js} +4 -4
  153. package/dist/{chunk-MBSWV56J.js.map → chunk-P6TJCCM3.js.map} +1 -1
  154. package/dist/{chunk-FID76MUV.js → chunk-Q7E4TNN7.js} +10 -6
  155. package/dist/chunk-Q7E4TNN7.js.map +1 -0
  156. package/dist/{chunk-LDQGZ4R2.js → chunk-RBXGVURD.js} +4 -4
  157. package/dist/{chunk-LDQGZ4R2.js.map → chunk-RBXGVURD.js.map} +1 -1
  158. package/dist/{chunk-4UEXSD7E.js → chunk-RLJLG4EN.js} +6 -6
  159. package/dist/{chunk-4UEXSD7E.js.map → chunk-RLJLG4EN.js.map} +1 -1
  160. package/dist/{chunk-OM2GRPDH.js → chunk-RYGEIQWO.js} +3 -3
  161. package/dist/{chunk-OM2GRPDH.js.map → chunk-RYGEIQWO.js.map} +1 -1
  162. package/dist/{chunk-7ED3XSYN.js → chunk-SGB7HCXF.js} +4 -4
  163. package/dist/{chunk-7ED3XSYN.js.map → chunk-SGB7HCXF.js.map} +1 -1
  164. package/dist/{chunk-PCEKL6S3.js → chunk-SXI2XBCC.js} +7 -7
  165. package/dist/{chunk-PCEKL6S3.js.map → chunk-SXI2XBCC.js.map} +1 -1
  166. package/dist/{chunk-L4TQBWR7.js → chunk-TF6HFXTW.js} +3 -3
  167. package/dist/{chunk-L4TQBWR7.js.map → chunk-TF6HFXTW.js.map} +1 -1
  168. package/dist/{chunk-VSP3INDK.js → chunk-TTLRRVM2.js} +7 -7
  169. package/dist/{chunk-VSP3INDK.js.map → chunk-TTLRRVM2.js.map} +1 -1
  170. package/dist/{chunk-P2WO5CNH.js → chunk-UHGDQIIF.js} +5 -5
  171. package/dist/{chunk-P2WO5CNH.js.map → chunk-UHGDQIIF.js.map} +1 -1
  172. package/dist/{chunk-L55G7FJZ.js → chunk-VNDUKDZG.js} +38 -10
  173. package/dist/chunk-VNDUKDZG.js.map +1 -0
  174. package/dist/{chunk-HIGI3M7E.js → chunk-VZPEPWDF.js} +9 -9
  175. package/dist/{chunk-HIGI3M7E.js.map → chunk-VZPEPWDF.js.map} +1 -1
  176. package/dist/{chunk-KLJTNLZ5.js → chunk-WEKO2DAN.js} +5 -5
  177. package/dist/{chunk-KLJTNLZ5.js.map → chunk-WEKO2DAN.js.map} +1 -1
  178. package/dist/{chunk-RSRGLHVQ.js → chunk-WHFKJ3AS.js} +4 -4
  179. package/dist/{chunk-RSRGLHVQ.js.map → chunk-WHFKJ3AS.js.map} +1 -1
  180. package/dist/{chunk-5FJFN3IW.js → chunk-WQPG22DY.js} +3 -3
  181. package/dist/{chunk-5FJFN3IW.js.map → chunk-WQPG22DY.js.map} +1 -1
  182. package/dist/{chunk-Z2K2O3DI.js → chunk-WVSGVFMM.js} +4 -4
  183. package/dist/{chunk-Z2K2O3DI.js.map → chunk-WVSGVFMM.js.map} +1 -1
  184. package/dist/{chunk-JYV25VNZ.js → chunk-X55R4VVK.js} +3 -3
  185. package/dist/{chunk-JYV25VNZ.js.map → chunk-X55R4VVK.js.map} +1 -1
  186. package/dist/{chunk-IPICQKIF.js → chunk-X5QZBD5V.js} +7 -7
  187. package/dist/{chunk-IPICQKIF.js.map → chunk-X5QZBD5V.js.map} +1 -1
  188. package/dist/{chunk-TLOA4BJF.js → chunk-XHWBJYJL.js} +3 -3
  189. package/dist/{chunk-TLOA4BJF.js.map → chunk-XHWBJYJL.js.map} +1 -1
  190. package/dist/{chunk-PAMMBDFM.js → chunk-YBIL64R7.js} +3 -3
  191. package/dist/{chunk-PAMMBDFM.js.map → chunk-YBIL64R7.js.map} +1 -1
  192. package/dist/{chunk-4SM6UKLE.js → chunk-YJWJPS25.js} +17 -17
  193. package/dist/chunk-YJWJPS25.js.map +1 -0
  194. package/dist/{chunk-N4YBKFJM.js → chunk-YKNDXZAD.js} +24 -24
  195. package/dist/chunk-YKNDXZAD.js.map +1 -0
  196. package/dist/{chunk-SQBLVCES.js → chunk-ZRJXN766.js} +4 -4
  197. package/dist/{chunk-SQBLVCES.js.map → chunk-ZRJXN766.js.map} +1 -1
  198. package/dist/components/cart/index.js +1 -1
  199. package/dist/components/common/index.js +1 -1
  200. package/dist/components/drawer/index.js +25 -25
  201. package/dist/components/home/BundleComponent.d.ts +3 -0
  202. package/dist/components/home/BundleComponent.d.ts.map +1 -1
  203. package/dist/components/home/index.js +29 -29
  204. package/dist/components/layout/index.js +7 -7
  205. package/dist/components/product/index.js +26 -26
  206. package/dist/components/store/index.js +27 -27
  207. package/dist/components/toast/index.js +5 -5
  208. package/dist/dev/editor/index.js +3 -3
  209. package/dist/dev/index.js +3 -3
  210. package/dist/document-class-3GOSUA4H.js +31 -0
  211. package/dist/{document-class-4DT4LTK5.js.map → document-class-3GOSUA4H.js.map} +1 -1
  212. package/dist/hooks/index.js +25 -25
  213. package/dist/hooks/useComments.js +4 -4
  214. package/dist/hooks/useGtm.js +25 -25
  215. package/dist/hooks/useMoney.js +25 -25
  216. package/dist/hooks/useProduct.js +4 -4
  217. package/dist/hooks/useStore.js +25 -25
  218. package/dist/hooks/useUser.js +6 -6
  219. package/dist/hooks/useWishlist.js +4 -4
  220. package/dist/index.js +25 -25
  221. package/dist/native-app/index.js +4 -4
  222. package/dist/{navigation-FTU3OC4V.js → navigation-SN2ZTS4V.js} +8 -8
  223. package/dist/{navigation-FTU3OC4V.js.map → navigation-SN2ZTS4V.js.map} +1 -1
  224. package/dist/navigation-ZV4TGIAA.js +15 -0
  225. package/dist/{navigation-DT6HXCUG.js.map → navigation-ZV4TGIAA.js.map} +1 -1
  226. package/dist/{not-found-BVJSPRMZ.js → not-found-J3UJVHNJ.js} +28 -28
  227. package/dist/{not-found-BVJSPRMZ.js.map → not-found-J3UJVHNJ.js.map} +1 -1
  228. package/dist/providers/index.js +25 -25
  229. package/dist/providers/twilight-init.d.ts.map +1 -1
  230. package/dist/routes/account/orders.js +9 -9
  231. package/dist/routes/account.js +18 -18
  232. package/dist/routes/blog.js +13 -13
  233. package/dist/routes/brands.js +9 -9
  234. package/dist/routes/cart.js +33 -33
  235. package/dist/routes/home.js +30 -30
  236. package/dist/routes/index.js +7 -7
  237. package/dist/routes/loyalty.js +10 -10
  238. package/dist/routes/page.js +9 -9
  239. package/dist/routes/product-listing.js +31 -31
  240. package/dist/routes/product.js +29 -29
  241. package/dist/routes/root/beforeLoad.d.ts +6 -0
  242. package/dist/routes/root/beforeLoad.d.ts.map +1 -1
  243. package/dist/routes/seo-redirects.js +7 -7
  244. package/dist/routes/testimonials.js +5 -5
  245. package/dist/routes/thank-you.js +9 -9
  246. package/dist/skeleton.js +30 -30
  247. package/dist/{store-lookup-OWYYSCDT.js → store-lookup-U6TJNLZM.js} +12 -12
  248. package/dist/{store-lookup-OWYYSCDT.js.map → store-lookup-U6TJNLZM.js.map} +1 -1
  249. package/dist/tanstack.js +22 -22
  250. package/dist/twilight/context.d.ts +3 -2
  251. package/dist/twilight/context.d.ts.map +1 -1
  252. package/dist/utils/baseHead.js +3 -3
  253. package/dist/utils/cookies.d.ts +15 -1
  254. package/dist/utils/cookies.d.ts.map +1 -1
  255. package/dist/utils/index.js +7 -7
  256. package/dist/utils/maintenance.d.ts +37 -5
  257. package/dist/utils/maintenance.d.ts.map +1 -1
  258. package/dist/utils/store-identity.d.ts +10 -0
  259. package/dist/utils/store-identity.d.ts.map +1 -1
  260. package/dist/vite/index.js +5 -5
  261. package/package.json +1 -1
  262. package/tailwind/components/home/BundleComponent.tsx.txt +46 -3
  263. package/tailwind/routes/root/beforeLoad.ts.txt +8 -1
  264. package/dist/Header-ORMIZKUL.js +0 -23
  265. package/dist/MaintenancePage-A7CNHM7B.js +0 -7
  266. package/dist/StoreClosedNotification-3FYHHAIP.js +0 -58
  267. package/dist/chunk-4SM6UKLE.js.map +0 -1
  268. package/dist/chunk-FHU2MXZA.js.map +0 -1
  269. package/dist/chunk-FID76MUV.js.map +0 -1
  270. package/dist/chunk-JYEUOEEI.js +0 -14
  271. package/dist/chunk-L55G7FJZ.js.map +0 -1
  272. package/dist/chunk-N4YBKFJM.js.map +0 -1
  273. package/dist/document-class-4DT4LTK5.js +0 -31
  274. package/dist/navigation-DT6HXCUG.js +0 -15
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/baseHead.ts"],"names":[],"mappings":"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","file":"chunk-OM2GRPDH.js","sourcesContent":["import type { HeadDescriptor } from './head';\nimport type { StoreContext } from '../api/store';\nimport { FALLBACK_LOCALE, isLocale } from '../providers/locale-constants';\nimport { resolveStoreBase, resolveStoreBaseFollowsLocale } from './store-identity';\nimport { splitLeadingSegment } from './store-base';\n\n// ============================================================================\n// Locale helpers\n// ============================================================================\n\n/** Maps ISO-639-1 locale codes to the og:locale format (language_TERRITORY). */\nconst LOCALE_OG_MAP: Record<string, string> = {\n ar: 'ar_AR',\n en: 'en_US',\n};\n\n/**\n * Converts an ISO-639-1 locale string to the og:locale format (e.g. `ar` → `ar_AR`).\n */\nexport function localeToOgLocale(locale: string): string {\n if (!locale) return LOCALE_OG_MAP[FALLBACK_LOCALE] ?? 'ar_AR';\n const base = locale.split(/[-_]/)[0].toLowerCase();\n return LOCALE_OG_MAP[base] ?? `${base}_${base.toUpperCase()}`;\n}\n\n/**\n * The page's own segments of an absolute URL's path: without the store's path (`storePath`, the\n * `/<username>` of a store without a domain) and without a locale beside it. The locale may sit\n * on either side: after the store in a store root (`/<username>/ar/shoes`), and in front of it in\n * the URLs the API hands out for a shared-host store (`/ar/<username>/shoes`).\n */\nfunction pageSegmentsOfUrl(pathname: string, storePath: string): string[] {\n const parts = pathname.split('/').filter(Boolean);\n const store = storePath.split('/').filter(Boolean);\n const storeAt = (index: number) =>\n store.length > 0 && store.every((segment, i) => parts[index + i] === segment);\n const localeAt = (index: number) => parts[index]?.length === 2;\n\n if (storeAt(0)) return parts.slice(store.length + (localeAt(store.length) ? 1 : 0));\n if (localeAt(0) && storeAt(1)) return parts.slice(1 + store.length);\n return parts.slice(localeAt(0) ? 1 : 0);\n}\n\n/**\n * Extracts the path portion from a URL or path string, removing any locale prefix and, from an\n * absolute URL, the store's own path (`storePath`, the `/<username>` of a store without a domain).\n */\nfunction extractPath(urlOrPath: string | undefined, storePath = ''): string {\n if (!urlOrPath) return '/';\n\n try {\n const parsed = new URL(urlOrPath);\n return '/' + pageSegmentsOfUrl(parsed.pathname, storePath).join('/');\n } catch {\n const pathParts = urlOrPath.split('/').filter(Boolean);\n if (pathParts.length > 0 && pathParts[0].length === 2) {\n pathParts.shift();\n }\n return '/' + pathParts.join('/');\n }\n}\n\n/**\n * The store's root URL from its store URL: the domain, plus the `/<username>` a store without\n * its own domain lives under, without a trailing locale.\n * \"https://saudiseamless.com/ar/\" → \"https://saudiseamless.com\"\n * \"https://salla.sa/my-store/ar/\" → \"https://salla.sa/my-store\"\n */\nfunction extractBaseUrl(storeUrl: string): string {\n try {\n const parsed = new URL(storeUrl);\n const segments = parsed.pathname.split('/').filter(Boolean);\n if (isLocale(segments[segments.length - 1])) segments.pop();\n return parsed.origin + segments.map((segment) => `/${segment}`).join('');\n } catch {\n return storeUrl.replace(/\\/[a-z]{2}\\/?$/i, '').replace(/\\/$/, '');\n }\n}\n\n/**\n * The store's root URL as pages are addressed now. On a Salla shared host that is\n * `https://demostore.salla.sa/<username>`: the API's `store.url` still carries the old\n * language segment (`/ar/<username>/`), which redirects, so it is not used there.\n */\nfunction storeRootUrl(storeUrl: string): string {\n const base = resolveStoreBase();\n if (base && resolveStoreBaseFollowsLocale()) {\n try {\n return `${new URL(storeUrl).origin}/${base}`;\n } catch {\n // Not an absolute URL: fall through to the generic rule.\n }\n }\n return extractBaseUrl(storeUrl);\n}\n\n/** Whether pages are addressed without a language segment (a Salla shared host). */\nfunction languageInQuery(): boolean {\n return Boolean(resolveStoreBase() && resolveStoreBaseFollowsLocale());\n}\n\n/**\n * A router path (`/ar/brands`) as a shared host addresses it: the leading locale comes off the\n * path and becomes `?lang=`, since the address carries no language. A path with no leading\n * locale takes `fallbackLocale` for its `?lang=`, or none when that is not given. `path` is\n * `''` for the store root.\n */\nfunction sharedHostPage(\n routerPath: string,\n fallbackLocale?: string\n): { path: string; search: string } {\n const { first, rest } = splitLeadingSegment(routerPath);\n const leading = isLocale(first);\n const remainder = leading ? rest : routerPath;\n const locale = leading ? first : fallbackLocale;\n return {\n path: remainder === '/' ? '' : remainder,\n search: locale ? `?lang=${encodeURIComponent(locale)}` : '',\n };\n}\n\n/**\n * `path` under the store's root URL, the way canonical URLs name a page.\n *\n * On a shared host `path` is the router's, with its virtual locale in front (`/ar/brands`),\n * and the page's address is `/<username>/brands?lang=ar`.\n */\nexport function storePageUrl(\n settings: StoreContext | null | undefined,\n path: string\n): string | undefined {\n const storeUrl = settings?.store?.url;\n if (!storeUrl) return undefined;\n const base = storeRootUrl(storeUrl);\n const page = languageInQuery()\n ? sharedHostPage(path)\n : { path: path === '/' ? '' : path, search: '' };\n if (!page.path && !page.search) return base;\n try {\n // Percent-encodes the decoded path the router hands over, and keeps escapes it left in.\n return new URL(`${base}${page.path}${page.search}`).href;\n } catch {\n return `${base}${page.path}${page.search}`;\n }\n}\n\n// ============================================================================\n// Hreflang alternates builder\n// ============================================================================\n\n/**\n * Builds hreflang alternate links for multilingual SEO.\n *\n * @param settings - StoreContext containing store and languages\n * @param path - Current route path from router (e.g., '/ar/products/123')\n */\nexport function buildHreflangAlternates(\n settings: StoreContext | null | undefined,\n path?: string\n): HeadDescriptor['alternateLanguages'] {\n const languages = settings?.languages;\n if (!languages?.length) {\n return undefined;\n }\n\n const baseUrl = settings?.store?.url ? storeRootUrl(settings.store.url) : '';\n const extractedPath = extractPath(path, baseUrl.replace(/^https?:\\/\\/[^/]+/, ''));\n const defaultLang = languages.find((l) => l.code === FALLBACK_LOCALE) ?? languages[0];\n const inQuery = languageInQuery();\n\n const buildUrl = (langCode: string) => {\n const pagePath = extractedPath === '/' ? '' : extractedPath;\n // On a shared host the language is not in the address; `?lang=` is how a link asks for one.\n return inQuery\n ? `${baseUrl}${pagePath}?lang=${encodeURIComponent(langCode)}`\n : `${baseUrl}/${langCode}${pagePath}`;\n };\n\n return [\n { hreflang: 'x-default', href: buildUrl(defaultLang.code) },\n ...languages.map((lang) => ({ hreflang: lang.code, href: buildUrl(lang.code) })),\n ];\n}\n\n// ============================================================================\n// Base head builder (for __root.tsx)\n// ============================================================================\n\n/**\n * Builds a base {@link HeadDescriptor} with store-wide OG and Twitter defaults.\n * Used in __root.tsx to set base metadata that can be overridden by child routes.\n *\n * Note: hreflang alternates, the canonical and og:url are only generated when\n * path is provided, since we need the current route path. Child routes call\n * buildHreflangAlternates directly with ctx.path.\n */\nexport function buildBaseHead(\n settings: StoreContext | null | undefined,\n locale: string = FALLBACK_LOCALE,\n path?: string\n): HeadDescriptor {\n const store = settings?.store;\n if (!store) return {};\n\n const title = store.meta?.title || store.name;\n const description = store.meta?.description || store.description || undefined;\n const keywords = store.meta?.keywords || undefined;\n const baseUrl = store.url ? storeRootUrl(store.url) : undefined;\n // A child route cannot replace a <link>, so a store-wide canonical would stick to every page.\n // On a shared host `path` is the router's, with the virtual locale in front: the address has\n // none, so it comes off and goes into `?lang=`, which keeps each language's page its own.\n const page = path && languageInQuery() ? sharedHostPage(path, locale) : null;\n const canonicalUrl =\n path && baseUrl\n ? page\n ? `${baseUrl}${page.path}${page.search}`\n : `${baseUrl}${path}`\n : undefined;\n const pagePath = path === '/' ? '' : path;\n const ogUrl =\n path && baseUrl ? (page ? canonicalUrl : `${baseUrl}/${locale}${pagePath}`) : undefined;\n\n // The store saves either a handle or a profile URL (https://x.com/<handle>).\n const twitterHandle = store.social?.twitter\n ?.split('?')[0]\n .replace(/\\/+$/, '')\n .split('/')\n .pop()\n ?.replace(/^@/, '');\n const twitterSite = twitterHandle ? `@${twitterHandle}` : undefined;\n\n return {\n title,\n ...(description ? { description } : {}),\n ...(keywords ? { keywords } : {}),\n ...(canonicalUrl ? { canonical: canonicalUrl } : {}),\n openGraph: {\n type: 'website',\n siteName: store.name,\n title,\n ...(description ? { description } : {}),\n ...(ogUrl ? { url: ogUrl } : {}),\n locale: localeToOgLocale(locale),\n ...(store.logo ? { images: store.logo } : {}),\n },\n twitter: {\n card: 'summary_large_image',\n title,\n ...(description ? { description } : {}),\n ...(twitterSite ? { site: twitterSite } : {}),\n ...(store.logo ? { images: store.logo } : {}),\n },\n ...(path ? { alternateLanguages: buildHreflangAlternates(settings, path) } : {}),\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/utils/baseHead.ts"],"names":[],"mappings":"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","file":"chunk-RYGEIQWO.js","sourcesContent":["import type { HeadDescriptor } from './head';\nimport type { StoreContext } from '../api/store';\nimport { FALLBACK_LOCALE, isLocale } from '../providers/locale-constants';\nimport { resolveStoreBase, resolveStoreBaseFollowsLocale } from './store-identity';\nimport { splitLeadingSegment } from './store-base';\n\n// ============================================================================\n// Locale helpers\n// ============================================================================\n\n/** Maps ISO-639-1 locale codes to the og:locale format (language_TERRITORY). */\nconst LOCALE_OG_MAP: Record<string, string> = {\n ar: 'ar_AR',\n en: 'en_US',\n};\n\n/**\n * Converts an ISO-639-1 locale string to the og:locale format (e.g. `ar` → `ar_AR`).\n */\nexport function localeToOgLocale(locale: string): string {\n if (!locale) return LOCALE_OG_MAP[FALLBACK_LOCALE] ?? 'ar_AR';\n const base = locale.split(/[-_]/)[0].toLowerCase();\n return LOCALE_OG_MAP[base] ?? `${base}_${base.toUpperCase()}`;\n}\n\n/**\n * The page's own segments of an absolute URL's path: without the store's path (`storePath`, the\n * `/<username>` of a store without a domain) and without a locale beside it. The locale may sit\n * on either side: after the store in a store root (`/<username>/ar/shoes`), and in front of it in\n * the URLs the API hands out for a shared-host store (`/ar/<username>/shoes`).\n */\nfunction pageSegmentsOfUrl(pathname: string, storePath: string): string[] {\n const parts = pathname.split('/').filter(Boolean);\n const store = storePath.split('/').filter(Boolean);\n const storeAt = (index: number) =>\n store.length > 0 && store.every((segment, i) => parts[index + i] === segment);\n const localeAt = (index: number) => parts[index]?.length === 2;\n\n if (storeAt(0)) return parts.slice(store.length + (localeAt(store.length) ? 1 : 0));\n if (localeAt(0) && storeAt(1)) return parts.slice(1 + store.length);\n return parts.slice(localeAt(0) ? 1 : 0);\n}\n\n/**\n * Extracts the path portion from a URL or path string, removing any locale prefix and, from an\n * absolute URL, the store's own path (`storePath`, the `/<username>` of a store without a domain).\n */\nfunction extractPath(urlOrPath: string | undefined, storePath = ''): string {\n if (!urlOrPath) return '/';\n\n try {\n const parsed = new URL(urlOrPath);\n return '/' + pageSegmentsOfUrl(parsed.pathname, storePath).join('/');\n } catch {\n const pathParts = urlOrPath.split('/').filter(Boolean);\n if (pathParts.length > 0 && pathParts[0].length === 2) {\n pathParts.shift();\n }\n return '/' + pathParts.join('/');\n }\n}\n\n/**\n * The store's root URL from its store URL: the domain, plus the `/<username>` a store without\n * its own domain lives under, without a trailing locale.\n * \"https://saudiseamless.com/ar/\" → \"https://saudiseamless.com\"\n * \"https://salla.sa/my-store/ar/\" → \"https://salla.sa/my-store\"\n */\nfunction extractBaseUrl(storeUrl: string): string {\n try {\n const parsed = new URL(storeUrl);\n const segments = parsed.pathname.split('/').filter(Boolean);\n if (isLocale(segments[segments.length - 1])) segments.pop();\n return parsed.origin + segments.map((segment) => `/${segment}`).join('');\n } catch {\n return storeUrl.replace(/\\/[a-z]{2}\\/?$/i, '').replace(/\\/$/, '');\n }\n}\n\n/**\n * The store's root URL as pages are addressed now. On a Salla shared host that is\n * `https://demostore.salla.sa/<username>`: the API's `store.url` still carries the old\n * language segment (`/ar/<username>/`), which redirects, so it is not used there.\n */\nfunction storeRootUrl(storeUrl: string): string {\n const base = resolveStoreBase();\n if (base && resolveStoreBaseFollowsLocale()) {\n try {\n return `${new URL(storeUrl).origin}/${base}`;\n } catch {\n // Not an absolute URL: fall through to the generic rule.\n }\n }\n return extractBaseUrl(storeUrl);\n}\n\n/** Whether pages are addressed without a language segment (a Salla shared host). */\nfunction languageInQuery(): boolean {\n return Boolean(resolveStoreBase() && resolveStoreBaseFollowsLocale());\n}\n\n/**\n * A router path (`/ar/brands`) as a shared host addresses it: the leading locale comes off the\n * path and becomes `?lang=`, since the address carries no language. A path with no leading\n * locale takes `fallbackLocale` for its `?lang=`, or none when that is not given. `path` is\n * `''` for the store root.\n */\nfunction sharedHostPage(\n routerPath: string,\n fallbackLocale?: string\n): { path: string; search: string } {\n const { first, rest } = splitLeadingSegment(routerPath);\n const leading = isLocale(first);\n const remainder = leading ? rest : routerPath;\n const locale = leading ? first : fallbackLocale;\n return {\n path: remainder === '/' ? '' : remainder,\n search: locale ? `?lang=${encodeURIComponent(locale)}` : '',\n };\n}\n\n/**\n * `path` under the store's root URL, the way canonical URLs name a page.\n *\n * On a shared host `path` is the router's, with its virtual locale in front (`/ar/brands`),\n * and the page's address is `/<username>/brands?lang=ar`.\n */\nexport function storePageUrl(\n settings: StoreContext | null | undefined,\n path: string\n): string | undefined {\n const storeUrl = settings?.store?.url;\n if (!storeUrl) return undefined;\n const base = storeRootUrl(storeUrl);\n const page = languageInQuery()\n ? sharedHostPage(path)\n : { path: path === '/' ? '' : path, search: '' };\n if (!page.path && !page.search) return base;\n try {\n // Percent-encodes the decoded path the router hands over, and keeps escapes it left in.\n return new URL(`${base}${page.path}${page.search}`).href;\n } catch {\n return `${base}${page.path}${page.search}`;\n }\n}\n\n// ============================================================================\n// Hreflang alternates builder\n// ============================================================================\n\n/**\n * Builds hreflang alternate links for multilingual SEO.\n *\n * @param settings - StoreContext containing store and languages\n * @param path - Current route path from router (e.g., '/ar/products/123')\n */\nexport function buildHreflangAlternates(\n settings: StoreContext | null | undefined,\n path?: string\n): HeadDescriptor['alternateLanguages'] {\n const languages = settings?.languages;\n if (!languages?.length) {\n return undefined;\n }\n\n const baseUrl = settings?.store?.url ? storeRootUrl(settings.store.url) : '';\n const extractedPath = extractPath(path, baseUrl.replace(/^https?:\\/\\/[^/]+/, ''));\n const defaultLang = languages.find((l) => l.code === FALLBACK_LOCALE) ?? languages[0];\n const inQuery = languageInQuery();\n\n const buildUrl = (langCode: string) => {\n const pagePath = extractedPath === '/' ? '' : extractedPath;\n // On a shared host the language is not in the address; `?lang=` is how a link asks for one.\n return inQuery\n ? `${baseUrl}${pagePath}?lang=${encodeURIComponent(langCode)}`\n : `${baseUrl}/${langCode}${pagePath}`;\n };\n\n return [\n { hreflang: 'x-default', href: buildUrl(defaultLang.code) },\n ...languages.map((lang) => ({ hreflang: lang.code, href: buildUrl(lang.code) })),\n ];\n}\n\n// ============================================================================\n// Base head builder (for __root.tsx)\n// ============================================================================\n\n/**\n * Builds a base {@link HeadDescriptor} with store-wide OG and Twitter defaults.\n * Used in __root.tsx to set base metadata that can be overridden by child routes.\n *\n * Note: hreflang alternates, the canonical and og:url are only generated when\n * path is provided, since we need the current route path. Child routes call\n * buildHreflangAlternates directly with ctx.path.\n */\nexport function buildBaseHead(\n settings: StoreContext | null | undefined,\n locale: string = FALLBACK_LOCALE,\n path?: string\n): HeadDescriptor {\n const store = settings?.store;\n if (!store) return {};\n\n const title = store.meta?.title || store.name;\n const description = store.meta?.description || store.description || undefined;\n const keywords = store.meta?.keywords || undefined;\n const baseUrl = store.url ? storeRootUrl(store.url) : undefined;\n // A child route cannot replace a <link>, so a store-wide canonical would stick to every page.\n // On a shared host `path` is the router's, with the virtual locale in front: the address has\n // none, so it comes off and goes into `?lang=`, which keeps each language's page its own.\n const page = path && languageInQuery() ? sharedHostPage(path, locale) : null;\n const canonicalUrl =\n path && baseUrl\n ? page\n ? `${baseUrl}${page.path}${page.search}`\n : `${baseUrl}${path}`\n : undefined;\n const pagePath = path === '/' ? '' : path;\n const ogUrl =\n path && baseUrl ? (page ? canonicalUrl : `${baseUrl}/${locale}${pagePath}`) : undefined;\n\n // The store saves either a handle or a profile URL (https://x.com/<handle>).\n const twitterHandle = store.social?.twitter\n ?.split('?')[0]\n .replace(/\\/+$/, '')\n .split('/')\n .pop()\n ?.replace(/^@/, '');\n const twitterSite = twitterHandle ? `@${twitterHandle}` : undefined;\n\n return {\n title,\n ...(description ? { description } : {}),\n ...(keywords ? { keywords } : {}),\n ...(canonicalUrl ? { canonical: canonicalUrl } : {}),\n openGraph: {\n type: 'website',\n siteName: store.name,\n title,\n ...(description ? { description } : {}),\n ...(ogUrl ? { url: ogUrl } : {}),\n locale: localeToOgLocale(locale),\n ...(store.logo ? { images: store.logo } : {}),\n },\n twitter: {\n card: 'summary_large_image',\n title,\n ...(description ? { description } : {}),\n ...(twitterSite ? { site: twitterSite } : {}),\n ...(store.logo ? { images: store.logo } : {}),\n },\n ...(path ? { alternateLanguages: buildHreflangAlternates(settings, path) } : {}),\n };\n}\n"]}
@@ -1,6 +1,6 @@
1
- import { useDate } from './chunk-N4YBKFJM.js';
1
+ import { useDate } from './chunk-YKNDXZAD.js';
2
2
  import { useTranslation } from './chunk-TYNZ5B2B.js';
3
- import { Image } from './chunk-NVL6M25Q.js';
3
+ import { Image } from './chunk-MWG734P7.js';
4
4
  import { Link } from './chunk-AXW67SY7.js';
5
5
  import { jsxs, jsx } from 'react/jsx-runtime';
6
6
 
@@ -61,5 +61,5 @@ function BlogListLayout({
61
61
  }
62
62
 
63
63
  export { BlogArticleCard, BlogListLayout };
64
- //# sourceMappingURL=chunk-7ED3XSYN.js.map
65
- //# sourceMappingURL=chunk-7ED3XSYN.js.map
64
+ //# sourceMappingURL=chunk-SGB7HCXF.js.map
65
+ //# sourceMappingURL=chunk-SGB7HCXF.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/routes/blog/components.tsx"],"names":[],"mappings":"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","file":"chunk-7ED3XSYN.js","sourcesContent":["import type { ReactNode } from 'react';\nimport { useTranslation } from '../../providers/I18nProvider';\nimport { useDate } from '../../hooks';\nimport { Image, Link } from '../../components/common';\nimport type { BlogCategory, ArticleSummary } from './types';\n\nexport function BlogCategoriesSidebar({ categories }: { categories: BlogCategory[] }) {\n const { t } = useTranslation();\n\n if (!categories.length) return null;\n\n return (\n <nav aria-label=\"Sidebar\" className=\"hidden lg:block lg:sticky shrink-0 top-24 col-span-2\">\n <h2 className=\"font-bold mb-3\">{t('pages.blog_categories.categories')}</h2>\n <ul>\n {categories.map((category) => (\n <li key={category.id} className={category.is_current ? 'text-primary' : ''}>\n <Link className=\"py-3 block text-sm hover:text-primary\" to={category.url}>\n {category.name}\n </Link>\n </li>\n ))}\n </ul>\n </nav>\n );\n}\n\nexport function BlogArticleCard({\n article,\n showAuthor = false,\n}: {\n article: ArticleSummary;\n showAuthor?: boolean;\n}) {\n const { format: formatDate } = useDate();\n\n return (\n <div className=\"list-block post-entry relative h-full transition-shadow duration-500 bg-white hover:shadow-default rounded-lg justify-around overflow-hidden flex flex-col\">\n <Link\n to={article.url}\n className=\"post-entry__image relative overflow-hidden hover:opacity-90 w-full h-56 bg-border-color flex items-center justify-center\"\n >\n {article.image && (\n <Image\n className=\"h-full w-full object-cover\"\n src={article.image}\n alt={article.name}\n aspectRatio=\"16/9\"\n />\n )}\n </Link>\n <div className=\"flex-1 px-5 pt-5 pb-7\">\n <div className=\"mb-2.5 text-gray-500 rounded-md inline-flex text-sm rtl:space-x-reverse space-x-5\">\n <div className=\"flex items-center\">\n <i className=\"sicon-calendar-date rtl:ml-1 ltr:mr-1\"></i>\n <span>{formatDate(article.created_at)}</span>\n </div>\n {showAuthor && article.author && (\n <Link to={article.author.url} className=\"flex items-center hover:text-dark\">\n <i className=\"sicon-user rtl:ml-1 ltr:mr-1\"></i>\n <span>{article.author.name}</span>\n </Link>\n )}\n </div>\n <h3 className=\"post-entry__title text-sm font-bold text-gray-800 leading-6 mb-2.5\">\n <Link to={article.url}>{article.name}</Link>\n </h3>\n <p className=\"text-sm text-gray-500 leading-6 mb-2.5\">{article.description}</p>\n </div>\n </div>\n );\n}\n\nexport function BlogListLayout({\n categories,\n children,\n}: {\n categories: BlogCategory[];\n children: ReactNode;\n}) {\n return (\n <div className=\"grid grid-cols-1 lg:grid-cols-8 gap-8\">\n <BlogCategoriesSidebar categories={categories} />\n <div className=\"main-content lg:col-span-6\">{children}</div>\n </div>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/routes/blog/components.tsx"],"names":[],"mappings":"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","file":"chunk-SGB7HCXF.js","sourcesContent":["import type { ReactNode } from 'react';\nimport { useTranslation } from '../../providers/I18nProvider';\nimport { useDate } from '../../hooks';\nimport { Image, Link } from '../../components/common';\nimport type { BlogCategory, ArticleSummary } from './types';\n\nexport function BlogCategoriesSidebar({ categories }: { categories: BlogCategory[] }) {\n const { t } = useTranslation();\n\n if (!categories.length) return null;\n\n return (\n <nav aria-label=\"Sidebar\" className=\"hidden lg:block lg:sticky shrink-0 top-24 col-span-2\">\n <h2 className=\"font-bold mb-3\">{t('pages.blog_categories.categories')}</h2>\n <ul>\n {categories.map((category) => (\n <li key={category.id} className={category.is_current ? 'text-primary' : ''}>\n <Link className=\"py-3 block text-sm hover:text-primary\" to={category.url}>\n {category.name}\n </Link>\n </li>\n ))}\n </ul>\n </nav>\n );\n}\n\nexport function BlogArticleCard({\n article,\n showAuthor = false,\n}: {\n article: ArticleSummary;\n showAuthor?: boolean;\n}) {\n const { format: formatDate } = useDate();\n\n return (\n <div className=\"list-block post-entry relative h-full transition-shadow duration-500 bg-white hover:shadow-default rounded-lg justify-around overflow-hidden flex flex-col\">\n <Link\n to={article.url}\n className=\"post-entry__image relative overflow-hidden hover:opacity-90 w-full h-56 bg-border-color flex items-center justify-center\"\n >\n {article.image && (\n <Image\n className=\"h-full w-full object-cover\"\n src={article.image}\n alt={article.name}\n aspectRatio=\"16/9\"\n />\n )}\n </Link>\n <div className=\"flex-1 px-5 pt-5 pb-7\">\n <div className=\"mb-2.5 text-gray-500 rounded-md inline-flex text-sm rtl:space-x-reverse space-x-5\">\n <div className=\"flex items-center\">\n <i className=\"sicon-calendar-date rtl:ml-1 ltr:mr-1\"></i>\n <span>{formatDate(article.created_at)}</span>\n </div>\n {showAuthor && article.author && (\n <Link to={article.author.url} className=\"flex items-center hover:text-dark\">\n <i className=\"sicon-user rtl:ml-1 ltr:mr-1\"></i>\n <span>{article.author.name}</span>\n </Link>\n )}\n </div>\n <h3 className=\"post-entry__title text-sm font-bold text-gray-800 leading-6 mb-2.5\">\n <Link to={article.url}>{article.name}</Link>\n </h3>\n <p className=\"text-sm text-gray-500 leading-6 mb-2.5\">{article.description}</p>\n </div>\n </div>\n );\n}\n\nexport function BlogListLayout({\n categories,\n children,\n}: {\n categories: BlogCategory[];\n children: ReactNode;\n}) {\n return (\n <div className=\"grid grid-cols-1 lg:grid-cols-8 gap-8\">\n <BlogCategoriesSidebar categories={categories} />\n <div className=\"main-content lg:col-span-6\">{children}</div>\n </div>\n );\n}\n"]}
@@ -1,9 +1,9 @@
1
- import { ensureTwilightContextFromMatches } from './chunk-JYV25VNZ.js';
2
- import { renderThemeHookSlotsScript, renderAppScopeInstallScript } from './chunk-5FJFN3IW.js';
1
+ import { ensureTwilightContextFromMatches } from './chunk-X55R4VVK.js';
2
+ import { renderThemeHookSlotsScript, renderAppScopeInstallScript } from './chunk-WQPG22DY.js';
3
3
  import { resolveHead, mergeHead } from './chunk-GD26FI4J.js';
4
- import { buildBaseHead } from './chunk-OM2GRPDH.js';
5
- import { readEnv, renderRuntimeEnvScript, escapeForInlineScript } from './chunk-FHU2MXZA.js';
6
- import { getTwilightContext, SettingsError } from './chunk-7VNVCHID.js';
4
+ import { buildBaseHead } from './chunk-RYGEIQWO.js';
5
+ import { readEnv, renderRuntimeEnvScript, escapeForInlineScript } from './chunk-FXVII733.js';
6
+ import { getTwilightContext, SettingsError } from './chunk-6K34BCUP.js';
7
7
  import { FALLBACK_LOCALE } from './chunk-T72DAX7R.js';
8
8
 
9
9
  // src/routes/root/head.ts
@@ -296,5 +296,5 @@ function buildCustomJsScript(customJs, isUrl) {
296
296
  }
297
297
 
298
298
  export { TICKETING_SCRIPT_URL, resolveTwilightSdkUrl, rootHead };
299
- //# sourceMappingURL=chunk-PCEKL6S3.js.map
300
- //# sourceMappingURL=chunk-PCEKL6S3.js.map
299
+ //# sourceMappingURL=chunk-SXI2XBCC.js.map
300
+ //# sourceMappingURL=chunk-SXI2XBCC.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/routes/root/head.ts"],"names":[],"mappings":"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","file":"chunk-PCEKL6S3.js","sourcesContent":["import type { HeadDescriptor, HeadResult } from '../../utils/head';\nimport { mergeHead, resolveHead } from '../../utils/head';\nimport { buildBaseHead } from '../../utils/baseHead';\nimport { FALLBACK_LOCALE } from '../../providers/locale-constants';\nimport { getTwilightContext } from '../../twilight/context';\nimport type { TwilightContextMatch } from '../../twilight/ensure-context';\nimport { ensureTwilightContextFromMatches } from '../../twilight/ensure-context';\nimport type { StoreContext } from '../../api/store';\nimport type { AppSnippet } from '../../api/apps';\nimport { SettingsError } from '../../utils/errors';\nimport { renderAppScopeInstallScript } from '../../utils/app-scope';\nimport { renderThemeHookSlotsScript } from '../../utils/theme-hook-slots';\nimport { escapeForInlineScript } from '../../utils/inline-script';\nimport { readEnv, renderRuntimeEnvScript } from '../../utils/runtime-env';\n\nconst SALLA_ICONS_CSS_URL = 'https://cdn.assets.salla.network/static/fonts/sallaicons.css?v=2.0.5';\nconst LIT_VERSION = '3.3.3';\nconst LIT_CDN_BASE = `https://cdn.assets.salla.network/static/lit/${LIT_VERSION}`;\n\n/** Bare-specifier map for the lit build the engine's `<salla-*>` web components resolve against. */\nconst LIT_IMPORTS: Record<string, string> = {\n lit: `${LIT_CDN_BASE}/lit.js`,\n 'lit/': `${LIT_CDN_BASE}/`,\n 'lit-html': `${LIT_CDN_BASE}/lit-html/lit-html.js`,\n 'lit-html/': `${LIT_CDN_BASE}/lit-html/`,\n 'lit-element': `${LIT_CDN_BASE}/lit-element/lit-element.js`,\n 'lit-element/': `${LIT_CDN_BASE}/lit-element/`,\n '@lit/reactive-element': `${LIT_CDN_BASE}/reactive-element/reactive-element.js`,\n '@lit/reactive-element/': `${LIT_CDN_BASE}/reactive-element/`,\n};\n\nexport const TICKETING_SCRIPT_URL =\n 'https://cdn.assets.salla.network/latest/@salla.sa/ui-store-ticketing-system/ticketing-system.es.js';\n\nconst TWILIGHT_RELEASE_CDN = 'https://cdn.salla.network/js/twilight';\nconst TWILIGHT_DEV_CDN = 'https://cdn.assets.salla.network/dev/@salla.sa/twilight';\n// The oldest Twilight release this engine works with. Raise it whenever the engine\n// starts relying on something newer; the reason lives in that commit. Today's floor:\n// components ship their own CSS, which themes no longer compile (SallaApp/twilight#2107).\nconst MIN_TWILIGHT_VERSION = '2.14.538';\n// Last resort when no override and no platform pin, and the substitute for a pin below the floor.\nconst DEFAULT_TWILIGHT_VERSION = '2.14.584';\nconst releaseUrl = (version: string): string =>\n `${TWILIGHT_RELEASE_CDN}/${version}/twilight.esm.js`;\n// The head is built more than once per request (early hints, then the page); say it once.\nconst warnedPins = new Set<string>();\n\n/** `x.y.z` release pins only; dev shas and other strings are loaded as given. */\nfunction belowMinimum(version: string): boolean {\n return (\n /^\\d+\\.\\d+\\.\\d+$/.test(version) &&\n version.localeCompare(MIN_TWILIGHT_VERSION, undefined, { numeric: true }) < 0\n );\n}\n\n/** The `x.y.z` release segment of a release-CDN `.../twilight.esm.js` URL, if present. */\nfunction releaseVersionInUrl(url: string): string | null {\n const match = url.match(/\\/(\\d+\\.\\d+\\.\\d+)\\/twilight\\.esm\\.js(?:[?#]|$)/);\n return match ? match[1] : null;\n}\n\n/**\n * `VITE_TWILIGHT_URL`/`VITE_TWILIGHT_VERSION` outrank everything below, including\n * `theme.twilight.version`'s own `belowMinimum` guard — a stale override wins\n * silently otherwise (TD-16375: a scaffold-time pin outlived the engine raising\n * MIN_TWILIGHT_VERSION, so every new theme rendered without component CSS and\n * nothing said why). Only a dev-mode nudge, not a swap: an env override is a\n * deliberate choice, so unlike the settings-pin path below this never substitutes\n * the engine default underneath the developer.\n */\nfunction warnIfOverrideBelowMinimum(source: string, version: string): void {\n // Worker logs in production should stay quiet -- this is a developer-directed nudge,\n // not a user-facing or production-monitored signal. import.meta.env.DEV is a static\n // false in production builds, so this branch (and the console.warn below) is\n // tree-shaken out entirely, same as DevSettingsWidget / dev-settings-store.ts.\n if (!import.meta.env.DEV) return;\n if (!belowMinimum(version)) return;\n const key = `${source}:${version}`;\n if (warnedPins.has(key)) return;\n warnedPins.add(key);\n console.warn(\n `[twilight] ${source}=${version} is below the engine minimum ${MIN_TWILIGHT_VERSION} — components may load without their CSS (SallaApp/twilight#2107). Unset it or bump it to ${MIN_TWILIGHT_VERSION}+.`\n );\n}\n\n/**\n * Which twilight.esm.js the storefront loads, in priority order:\n * 1. `VITE_TWILIGHT_URL` — full local/deployment override.\n * 2. `VITE_TWILIGHT_VERSION` — dev-CDN build override.\n * 3. `theme.twilight.version` from the settings endpoint — the platform-pinned\n * release used when no environment override is configured.\n * 4. The engine's default release, also used when the pin is below the engine minimum.\n */\nexport function resolveTwilightSdkUrl(settings?: StoreContext): string {\n const urlOverride = readEnv('VITE_TWILIGHT_URL');\n if (urlOverride) {\n const version = releaseVersionInUrl(urlOverride);\n if (version) warnIfOverrideBelowMinimum('VITE_TWILIGHT_URL', version);\n return urlOverride;\n }\n\n const versionOverride = readEnv('VITE_TWILIGHT_VERSION');\n if (versionOverride) {\n warnIfOverrideBelowMinimum('VITE_TWILIGHT_VERSION', versionOverride);\n return `${TWILIGHT_DEV_CDN}/${versionOverride}/twilight.esm.js`;\n }\n\n const pinnedVersion = settings?.theme?.twilight?.version;\n if (pinnedVersion && belowMinimum(pinnedVersion)) {\n if (!warnedPins.has(pinnedVersion)) {\n warnedPins.add(pinnedVersion);\n console.warn(\n `[twilight] theme.twilight.version ${pinnedVersion} is below the engine minimum ${MIN_TWILIGHT_VERSION}; loading ${DEFAULT_TWILIGHT_VERSION} instead`\n );\n }\n return releaseUrl(DEFAULT_TWILIGHT_VERSION);\n }\n if (pinnedVersion) return releaseUrl(pinnedVersion);\n\n return releaseUrl(DEFAULT_TWILIGHT_VERSION);\n}\n\n// On a page that preloads its LCP image, the icon font (~270 KB) applies once the first screen's\n// priority images have painted, so it doesn't compete with them; other pages swap on load.\nconst MEDIA_SWAP_SCRIPT = `\n(function(){var d=document,s=function(l){if(l.sheet||\"all\"===l.media)l.media=\"all\";else l.onload=function(){this.media=\"all\"}},f=d.getElementById(\"salla-theme-font\"),i=d.getElementById(\"salla-icons-css\");f&&s(f);if(!i)return;if(!d.querySelector('link[rel=\"preload\"][as=\"image\"]'))return s(i);var g=function(){g=function(){};s(i)},p=function(){requestAnimationFrame(function(){setTimeout(function(){g()})});setTimeout(function(){g()},100)};d.addEventListener(\"DOMContentLoaded\",function(){var m=[].filter.call(d.querySelectorAll('img[fetchpriority=\"high\"]'),function(x){return!x.complete}),n=m.length;if(!n)return p();m.forEach(function(x){var o=function(){--n||p()};x.addEventListener(\"load\",o,{once:!0});x.addEventListener(\"error\",o,{once:!0})});setTimeout(function(){g()},2500)})})();\n`.trim();\n\nconst LOADING_CSS = `\n.loading-overlay{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:#fff;z-index:9999}\n.loading-spinner{animation:spin 1s linear infinite;border-radius:9999px;height:3rem;width:3rem;border-bottom:2px solid var(--color-primary,#000)}\n@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}\nhtml,body{margin:0;padding:0;height:100%}\n`.trim();\n\nconst SALLA_INIT_SCRIPT = `\nwindow.salla = window.Salla = window.Salla || window.salla || {};\nwindow.Salla.onReady = window.Salla.onReady || function(callback) {\n return new Promise(function(resolve) {\n if (window.Salla.status === 'ready') {\n var config = window.salla && window.salla.config && window.salla.config.all();\n resolve(callback ? callback(config) : config);\n } else {\n window.addEventListener('twilight::initiated', function(event) {\n resolve(callback ? callback(event.detail) : event.detail);\n }, { once: true });\n }\n });\n};\n`.trim();\n\n/**\n * Distinct snippet-host origins to `preconnect` (warm DNS/TCP/TLS during parse). From the real\n * URLs (dev/prod-correct), deduped and capped at 4. No `crossOrigin`: snippets are no-cors fetches.\n */\nexport function snippetPreconnectOrigins(snippets: readonly AppSnippet[] | undefined): string[] {\n if (!snippets?.length) return [];\n const origins = new Set<string>();\n for (const app of snippets) {\n if (app.status !== 'enabled') continue;\n for (const s of app.snippets) {\n if (!s.url) continue;\n try {\n origins.add(new URL(s.url).origin);\n } catch {\n /* skip a malformed snippet url rather than breaking the head */\n }\n if (origins.size >= 4) return [...origins];\n }\n }\n return [...origins];\n}\n\nexport function rootHead(ctx: {\n params: Record<string, string>;\n matches?: readonly TwilightContextMatch[];\n}): HeadResult {\n // Re-run on the client during hydration, where the twilight module store may\n // still be empty. Recover it from the resolved match context so the head is\n // built from real settings instead of falling through to 'Store Unavailable'.\n ensureTwilightContextFromMatches(ctx.matches);\n\n let settings: StoreContext | undefined;\n try {\n settings = getTwilightContext().settings;\n } catch (e) {\n if (e instanceof SettingsError) {\n return resolveHead({\n title: 'Store Unavailable',\n });\n }\n throw e;\n }\n const locale = ctx.params.locale || FALLBACK_LOCALE;\n const parts = deriveHeadParts(settings);\n\n return resolveHead(\n mergeHead(buildBaseHead(settings, locale), {\n meta: buildRootMeta(parts),\n links: buildRootLinks(parts),\n styles: buildRootStyles(parts),\n importMap: [{ imports: LIT_IMPORTS }],\n scripts: buildRootScripts(parts),\n })\n );\n}\n\n/** Everything the root head's tag builders read, derived once from the store settings. */\ninterface RootHeadParts {\n store: StoreContext['store'] | undefined;\n favicon?: string;\n primaryColor?: string;\n fontUrl?: string;\n fontUrlWithDisplay?: string;\n isGoogleFont?: boolean;\n fontFamilyName?: string;\n customJs?: string;\n customCss?: string;\n isCustomCssUrl?: boolean;\n isCustomJsUrl?: boolean;\n twilightSdkUrl: string;\n /** The visitor gets the maintenance page, which loads no SDK and no app snippets. */\n maintenance: boolean;\n snippetPreconnects: Array<{ rel: 'preconnect'; href: string }>;\n appScopeInstallScript: string;\n themeHookSlotsScript: string | null;\n runtimeEnvScript: string | null;\n}\n\n/** Google Fonts only honours `display=swap` as a query param; other hosts get the @font-face\n * override instead (see buildRootStyles). */\nfunction deriveFontParts(theme?: StoreContext['theme']) {\n const font = theme?.font;\n const fontUrl = font?.url || font?.path;\n const isGoogleFont = fontUrl?.includes('fonts.googleapis.com');\n const needsDisplay = Boolean(isGoogleFont && fontUrl && !fontUrl.includes('display='));\n const separator = fontUrl?.includes('?') ? '&' : '?';\n\n return {\n fontUrl,\n isGoogleFont,\n fontFamilyName: font?.family_name,\n fontUrlWithDisplay: needsDisplay ? `${fontUrl}${separator}display=swap` : fontUrl,\n };\n}\n\n/** Theme customization JS/CSS, each either a URL to load or an inline blob to embed. */\nfunction deriveCustomizationParts(theme?: StoreContext['theme']) {\n const customization = theme?.customization;\n const customJs = customization?.js?.trim();\n const customCss = customization?.css?.trim();\n const isUrl = (value?: string): boolean =>\n Boolean(value?.startsWith('http') || value?.startsWith('//'));\n\n return {\n customJs,\n customCss,\n isCustomCssUrl: isUrl(customCss),\n isCustomJsUrl: isUrl(customJs),\n };\n}\n\nfunction deriveHeadParts(settings?: StoreContext): RootHeadParts {\n const store = settings?.store;\n\n return {\n store,\n favicon: store?.icon,\n primaryColor: settings?.theme?.color?.primary,\n ...deriveFontParts(settings?.theme),\n ...deriveCustomizationParts(settings?.theme),\n twilightSdkUrl: resolveTwilightSdkUrl(settings),\n maintenance: getTwilightContext().maintenance,\n // Warm the connection to the snippet host(s) during head parse, so the body's deferred\n // `<script src>` snippet tags fetch off an already-open socket instead of DNS+TCP+TLS.\n snippetPreconnects: snippetPreconnectOrigins(getTwilightContext().appsSnippets).map((href) => ({\n rel: 'preconnect' as const,\n href,\n })),\n // Install `Salla.appScope` inline at parse time, before the SDK is ready — else a snippet's\n // onReady callback calls it too early and throws. Always emitted, even when the settings\n // prefetch failed: the CDN snippet tags ship regardless (they come from the *snippets*\n // endpoint), so the factory has to exist for them. `installAppScope` then seeds the real\n // buckets into this install once the client query resolves.\n appScopeInstallScript: renderAppScopeInstallScript(\n getTwilightContext().appsSettings ?? { apps: {} }\n ),\n // Whitelist the theme's own hook slots at parse time too, for the same reason: apps register\n // their `onReady` callbacks from parser-inserted snippet tags, long before React hydrates.\n themeHookSlotsScript: renderThemeHookSlotsScript(),\n // Env this render resolved (worker `vars` live in server-only `process.env`), handed to the\n // client so it doesn't silently fall back to the production defaults. Re-rendered on the\n // client during hydration, where it resolves to the same values or to nothing.\n runtimeEnvScript: renderRuntimeEnvScript(),\n };\n}\n\nfunction buildRootMeta(p: RootHeadParts): NonNullable<HeadDescriptor['meta']> {\n return [\n { name: 'robots', content: 'index, follow' },\n { name: 'msapplication-TileColor', content: '#ffffff' },\n ...(p.favicon ? [{ name: 'msapplication-TileImage', content: p.favicon }] : []),\n ...(p.primaryColor\n ? [\n { name: 'theme-color', content: p.primaryColor },\n { name: 'msapplication-navbutton-color', content: p.primaryColor },\n { name: 'apple-mobile-web-app-status-bar-style', content: p.primaryColor },\n ]\n : []),\n ];\n}\n\nfunction buildRootLinks(p: RootHeadParts): NonNullable<HeadDescriptor['links']> {\n return [\n { rel: 'preconnect', href: 'https://api.salla.dev' },\n { rel: 'preconnect', href: 'https://cdn.salla.sa' },\n { rel: 'preconnect', href: 'https://cdn.assets.salla.network', crossOrigin: 'anonymous' },\n // Warm the installed apps' CDN snippet host(s) — see snippetPreconnectOrigins.\n // Not on the maintenance page: it renders neither the snippets nor the SDK.\n ...(p.maintenance ? [] : p.snippetPreconnects),\n ...(p.isGoogleFont\n ? [\n {\n rel: 'preconnect' as const,\n href: 'https://fonts.gstatic.com',\n crossOrigin: 'anonymous' as const,\n },\n ]\n : []),\n ...(p.maintenance ? [] : [{ rel: 'modulepreload' as const, href: p.twilightSdkUrl }]),\n ...(p.fontUrlWithDisplay\n ? [\n {\n id: 'salla-theme-font',\n rel: 'stylesheet',\n href: p.fontUrlWithDisplay,\n media: 'print',\n },\n ]\n : []),\n ...(p.fontUrlWithDisplay && !p.isGoogleFont && p.fontFamilyName\n ? [\n {\n id: 'salla-font-display-override',\n rel: 'preload',\n as: 'style',\n href: p.fontUrlWithDisplay,\n },\n ]\n : []),\n ...(p.favicon ? [{ rel: 'icon', href: p.favicon }] : []),\n ...(p.favicon\n ? [{ id: 'salla-apple-icon', rel: 'apple-touch-icon-precomposed', href: p.favicon }]\n : []),\n ...(p.isCustomCssUrl && p.customCss\n ? [{ id: 'salla-custom-css', rel: 'stylesheet', href: p.customCss }]\n : []),\n {\n id: 'salla-icons-css',\n rel: 'stylesheet',\n href: SALLA_ICONS_CSS_URL,\n media: 'print',\n },\n // {\n // id: 'intl-tel-input-css',\n // rel: 'stylesheet',\n // href: 'https://cdn.jsdelivr.net/npm/intl-tel-input@26.8.0/build/css/intlTelInput.css',\n // },\n ...(p.isCustomJsUrl && p.customJs\n ? [{ id: 'salla-custom-js-preload', rel: 'preload', as: 'script', href: p.customJs }]\n : []),\n ];\n}\n\n// Hoistable (href + precedence): the web components insert their own <style> near the top of\n// <head> before hydration, which a positionally hydrated <style> would be matched against.\nconst hoisted = (id: string, children: string) => ({\n id,\n href: id,\n precedence: 'default',\n children,\n});\n\nfunction buildRootStyles(p: RootHeadParts): NonNullable<HeadDescriptor['styles']> {\n return [\n hoisted('twilight-loading', LOADING_CSS),\n ...(!p.isGoogleFont && p.fontFamilyName\n ? [\n hoisted(\n 'salla-font-display-swap',\n `@font-face{font-family:\"${p.fontFamilyName}\";font-display:swap;src:local(\"${p.fontFamilyName}\")}`\n ),\n ]\n : []),\n ...(!p.isCustomCssUrl && p.customCss ? [hoisted('salla-custom-css', p.customCss)] : []),\n ];\n}\n\nfunction buildRootScripts(p: RootHeadParts): NonNullable<HeadDescriptor['scripts']> {\n return [\n // First: the API base / store identifier this render used, so the hydrated client\n // resolves the same ones (worker `vars` never reach the browser bundle on their own).\n ...(p.runtimeEnvScript ? [{ id: 'salla-runtime-env', children: p.runtimeEnvScript }] : []),\n { id: 'twilight-init', children: SALLA_INIT_SCRIPT },\n // After twilight-init (which defines window.Salla) and before the SDK module, so the\n // appScope factory exists ahead of any snippet's onReady callback firing.\n { id: 'salla-app-scope', children: p.appScopeInstallScript },\n // Arms the hook-slot whitelist push here, so its `twilight::initiated` listener is\n // registered before any app snippet's — listeners fire in registration order.\n ...(p.themeHookSlotsScript\n ? [{ id: 'salla-theme-hook-slots', children: p.themeHookSlotsScript }]\n : []),\n { id: 'salla-async-css', children: MEDIA_SWAP_SCRIPT },\n // The SDK and ticketing modules are rendered at the end of <body> (SallaSdkScripts).\n ...(p.customJs ? [buildCustomJsScript(p.customJs, Boolean(p.isCustomJsUrl))] : []),\n ];\n}\n\n/** A URL customization is loaded after SDK init; an inline one is wrapped so a syntax/runtime\n * error in partner JS warns instead of taking the page down. */\nfunction buildCustomJsScript(customJs: string, isUrl: boolean) {\n return {\n id: 'salla-custom-js',\n children: isUrl\n ? `window.addEventListener('twilight::initiated',function(){var s=document.createElement('script');s.src=${escapeForInlineScript(JSON.stringify(customJs))};s.async=true;document.head.appendChild(s)},{once:true});`\n : `try { ${customJs} } catch(e) { console.warn(\"[ThemeCustomization] Custom JS error:\", e); }`,\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/routes/root/head.ts"],"names":[],"mappings":";;;;;;;;;AAeA,IAAM,mBAAA,GAAsB,sEAAA;AAC5B,IAAM,WAAA,GAAc,OAAA;AACpB,IAAM,YAAA,GAAe,+CAA+C,WAAW,CAAA,CAAA;AAG/E,IAAM,WAAA,GAAsC;AAAA,EAC1C,GAAA,EAAK,GAAG,YAAY,CAAA,OAAA,CAAA;AAAA,EACpB,MAAA,EAAQ,GAAG,YAAY,CAAA,CAAA,CAAA;AAAA,EACvB,UAAA,EAAY,GAAG,YAAY,CAAA,qBAAA,CAAA;AAAA,EAC3B,WAAA,EAAa,GAAG,YAAY,CAAA,UAAA,CAAA;AAAA,EAC5B,aAAA,EAAe,GAAG,YAAY,CAAA,2BAAA,CAAA;AAAA,EAC9B,cAAA,EAAgB,GAAG,YAAY,CAAA,aAAA,CAAA;AAAA,EAC/B,uBAAA,EAAyB,GAAG,YAAY,CAAA,qCAAA,CAAA;AAAA,EACxC,wBAAA,EAA0B,GAAG,YAAY,CAAA,kBAAA;AAC3C,CAAA;AAEO,IAAM,oBAAA,GACX;AAEF,IAAM,oBAAA,GAAuB,uCAAA;AAC7B,IAAM,gBAAA,GAAmB,yDAAA;AAIzB,IAAM,oBAAA,GAAuB,UAAA;AAE7B,IAAM,wBAAA,GAA2B,UAAA;AACjC,IAAM,aAAa,CAAC,OAAA,KAClB,CAAA,EAAG,oBAAoB,IAAI,OAAO,CAAA,gBAAA,CAAA;AAEpC,IAAM,UAAA,uBAAiB,GAAA,EAAY;AAGnC,SAAS,aAAa,OAAA,EAA0B;AAC9C,EAAA,OACE,iBAAA,CAAkB,IAAA,CAAK,OAAO,CAAA,IAC9B,OAAA,CAAQ,aAAA,CAAc,oBAAA,EAAsB,MAAA,EAAW,EAAE,OAAA,EAAS,IAAA,EAAM,CAAA,GAAI,CAAA;AAEhF;AAGA,SAAS,oBAAoB,GAAA,EAA4B;AACvD,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,KAAA,CAAM,gDAAgD,CAAA;AACxE,EAAA,OAAO,KAAA,GAAQ,KAAA,CAAM,CAAC,CAAA,GAAI,IAAA;AAC5B;AAWA,SAAS,0BAAA,CAA2B,QAAgB,OAAA,EAAuB;AAKzE,EAAA,IAAI,CAAC,MAAA,CAAA,IAAA,CAAY,GAAA,CAAI,GAAA,EAAK;AAC1B,EAAA,IAAI,CAAC,YAAA,CAAa,OAAO,CAAA,EAAG;AAC5B,EAAA,MAAM,GAAA,GAAM,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA;AAChC,EAAA,IAAI,UAAA,CAAW,GAAA,CAAI,GAAG,CAAA,EAAG;AACzB,EAAA,UAAA,CAAW,IAAI,GAAG,CAAA;AAClB,EAAA,OAAA,CAAQ,IAAA;AAAA,IACN,cAAc,MAAM,CAAA,CAAA,EAAI,OAAO,CAAA,6BAAA,EAAgC,oBAAoB,kGAA6F,oBAAoB,CAAA,EAAA;AAAA,GACtM;AACF;AAUO,SAAS,sBAAsB,QAAA,EAAiC;AACrE,EAAA,MAAM,WAAA,GAAc,QAAQ,mBAAmB,CAAA;AAC/C,EAAA,IAAI,WAAA,EAAa;AACf,IAAA,MAAM,OAAA,GAAU,oBAAoB,WAAW,CAAA;AAC/C,IAAA,IAAI,OAAA,EAAS,0BAAA,CAA2B,mBAAA,EAAqB,OAAO,CAAA;AACpE,IAAA,OAAO,WAAA;AAAA,EACT;AAEA,EAAA,MAAM,eAAA,GAAkB,QAAQ,uBAAuB,CAAA;AACvD,EAAA,IAAI,eAAA,EAAiB;AACnB,IAAA,0BAAA,CAA2B,yBAAyB,eAAe,CAAA;AACnE,IAAA,OAAO,CAAA,EAAG,gBAAgB,CAAA,CAAA,EAAI,eAAe,CAAA,gBAAA,CAAA;AAAA,EAC/C;AAEA,EAAA,MAAM,aAAA,GAAgB,QAAA,EAAU,KAAA,EAAO,QAAA,EAAU,OAAA;AACjD,EAAA,IAAI,aAAA,IAAiB,YAAA,CAAa,aAAa,CAAA,EAAG;AAChD,IAAA,IAAI,CAAC,UAAA,CAAW,GAAA,CAAI,aAAa,CAAA,EAAG;AAClC,MAAA,UAAA,CAAW,IAAI,aAAa,CAAA;AAC5B,MAAA,OAAA,CAAQ,IAAA;AAAA,QACN,CAAA,kCAAA,EAAqC,aAAa,CAAA,6BAAA,EAAgC,oBAAoB,aAAa,wBAAwB,CAAA,QAAA;AAAA,OAC7I;AAAA,IACF;AACA,IAAA,OAAO,WAAW,wBAAwB,CAAA;AAAA,EAC5C;AACA,EAAA,IAAI,aAAA,EAAe,OAAO,UAAA,CAAW,aAAa,CAAA;AAElD,EAAA,OAAO,WAAW,wBAAwB,CAAA;AAC5C;AAIA,IAAM,iBAAA,GAAoB;AAAA;AAAA,CAAA,CAExB,IAAA,EAAK;AAEP,IAAM,WAAA,GAAc;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAKlB,IAAA,EAAK;AAEP,IAAM,iBAAA,GAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAcxB,IAAA,EAAK;AAMA,SAAS,yBAAyB,QAAA,EAAuD;AAC9F,EAAA,IAAI,CAAC,QAAA,EAAU,MAAA,EAAQ,OAAO,EAAC;AAC/B,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAChC,EAAA,KAAA,MAAW,OAAO,QAAA,EAAU;AAC1B,IAAA,IAAI,GAAA,CAAI,WAAW,SAAA,EAAW;AAC9B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,QAAA,EAAU;AAC5B,MAAA,IAAI,CAAC,EAAE,GAAA,EAAK;AACZ,MAAA,IAAI;AACF,QAAA,OAAA,CAAQ,IAAI,IAAI,GAAA,CAAI,CAAA,CAAE,GAAG,EAAE,MAAM,CAAA;AAAA,MACnC,CAAA,CAAA,MAAQ;AAAA,MAER;AACA,MAAA,IAAI,QAAQ,IAAA,IAAQ,CAAA,EAAG,OAAO,CAAC,GAAG,OAAO,CAAA;AAAA,IAC3C;AAAA,EACF;AACA,EAAA,OAAO,CAAC,GAAG,OAAO,CAAA;AACpB;AAEO,SAAS,SAAS,GAAA,EAGV;AAIb,EAAA,gCAAA,CAAiC,IAAI,OAAO,CAAA;AAE5C,EAAA,IAAI,QAAA;AACJ,EAAA,IAAI;AACF,IAAA,QAAA,GAAW,oBAAmB,CAAE,QAAA;AAAA,EAClC,SAAS,CAAA,EAAG;AACV,IAAA,IAAI,aAAa,aAAA,EAAe;AAC9B,MAAA,OAAO,WAAA,CAAY;AAAA,QACjB,KAAA,EAAO;AAAA,OACR,CAAA;AAAA,IACH;AACA,IAAA,MAAM,CAAA;AAAA,EACR;AACA,EAAA,MAAM,MAAA,GAAS,GAAA,CAAI,MAAA,CAAO,MAAA,IAAU,eAAA;AACpC,EAAA,MAAM,KAAA,GAAQ,gBAAgB,QAAQ,CAAA;AAEtC,EAAA,OAAO,WAAA;AAAA,IACL,SAAA,CAAU,aAAA,CAAc,QAAA,EAAU,MAAM,CAAA,EAAG;AAAA,MACzC,IAAA,EAAM,cAAc,KAAK,CAAA;AAAA,MACzB,KAAA,EAAO,eAAe,KAAK,CAAA;AAAA,MAC3B,MAAA,EAAQ,gBAAgB,KAAK,CAAA;AAAA,MAC7B,SAAA,EAAW,CAAC,EAAE,OAAA,EAAS,aAAa,CAAA;AAAA,MACpC,OAAA,EAAS,iBAAiB,KAAK;AAAA,KAChC;AAAA,GACH;AACF;AA0BA,SAAS,gBAAgB,KAAA,EAA+B;AACtD,EAAA,MAAM,OAAO,KAAA,EAAO,IAAA;AACpB,EAAA,MAAM,OAAA,GAAU,IAAA,EAAM,GAAA,IAAO,IAAA,EAAM,IAAA;AACnC,EAAA,MAAM,YAAA,GAAe,OAAA,EAAS,QAAA,CAAS,sBAAsB,CAAA;AAC7D,EAAA,MAAM,YAAA,GAAe,QAAQ,YAAA,IAAgB,OAAA,IAAW,CAAC,OAAA,CAAQ,QAAA,CAAS,UAAU,CAAC,CAAA;AACrF,EAAA,MAAM,SAAA,GAAY,OAAA,EAAS,QAAA,CAAS,GAAG,IAAI,GAAA,GAAM,GAAA;AAEjD,EAAA,OAAO;AAAA,IACL,OAAA;AAAA,IACA,YAAA;AAAA,IACA,gBAAgB,IAAA,EAAM,WAAA;AAAA,IACtB,oBAAoB,YAAA,GAAe,CAAA,EAAG,OAAO,CAAA,EAAG,SAAS,CAAA,YAAA,CAAA,GAAiB;AAAA,GAC5E;AACF;AAGA,SAAS,yBAAyB,KAAA,EAA+B;AAC/D,EAAA,MAAM,gBAAgB,KAAA,EAAO,aAAA;AAC7B,EAAA,MAAM,QAAA,GAAW,aAAA,EAAe,EAAA,EAAI,IAAA,EAAK;AACzC,EAAA,MAAM,SAAA,GAAY,aAAA,EAAe,GAAA,EAAK,IAAA,EAAK;AAC3C,EAAA,MAAM,KAAA,GAAQ,CAAC,KAAA,KACb,OAAA,CAAQ,KAAA,EAAO,UAAA,CAAW,MAAM,CAAA,IAAK,KAAA,EAAO,UAAA,CAAW,IAAI,CAAC,CAAA;AAE9D,EAAA,OAAO;AAAA,IACL,QAAA;AAAA,IACA,SAAA;AAAA,IACA,cAAA,EAAgB,MAAM,SAAS,CAAA;AAAA,IAC/B,aAAA,EAAe,MAAM,QAAQ;AAAA,GAC/B;AACF;AAEA,SAAS,gBAAgB,QAAA,EAAwC;AAC/D,EAAA,MAAM,QAAQ,QAAA,EAAU,KAAA;AAExB,EAAA,OAAO;AAAA,IACL,KAAA;AAAA,IACA,SAAS,KAAA,EAAO,IAAA;AAAA,IAChB,YAAA,EAAc,QAAA,EAAU,KAAA,EAAO,KAAA,EAAO,OAAA;AAAA,IACtC,GAAG,eAAA,CAAgB,QAAA,EAAU,KAAK,CAAA;AAAA,IAClC,GAAG,wBAAA,CAAyB,QAAA,EAAU,KAAK,CAAA;AAAA,IAC3C,cAAA,EAAgB,sBAAsB,QAAQ,CAAA;AAAA,IAC9C,WAAA,EAAa,oBAAmB,CAAE,WAAA;AAAA;AAAA;AAAA,IAGlC,kBAAA,EAAoB,yBAAyB,kBAAA,EAAmB,CAAE,YAAY,CAAA,CAAE,GAAA,CAAI,CAAC,IAAA,MAAU;AAAA,MAC7F,GAAA,EAAK,YAAA;AAAA,MACL;AAAA,KACF,CAAE,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMF,qBAAA,EAAuB,2BAAA;AAAA,MACrB,oBAAmB,CAAE,YAAA,IAAgB,EAAE,IAAA,EAAM,EAAC;AAAE,KAClD;AAAA;AAAA;AAAA,IAGA,sBAAsB,0BAAA,EAA2B;AAAA;AAAA;AAAA;AAAA,IAIjD,kBAAkB,sBAAA;AAAuB,GAC3C;AACF;AAEA,SAAS,cAAc,CAAA,EAAuD;AAC5E,EAAA,OAAO;AAAA,IACL,EAAE,IAAA,EAAM,QAAA,EAAU,OAAA,EAAS,eAAA,EAAgB;AAAA,IAC3C,EAAE,IAAA,EAAM,yBAAA,EAA2B,OAAA,EAAS,SAAA,EAAU;AAAA,IACtD,GAAI,CAAA,CAAE,OAAA,GAAU,CAAC,EAAE,IAAA,EAAM,yBAAA,EAA2B,OAAA,EAAS,CAAA,CAAE,OAAA,EAAS,CAAA,GAAI,EAAC;AAAA,IAC7E,GAAI,EAAE,YAAA,GACF;AAAA,MACE,EAAE,IAAA,EAAM,aAAA,EAAe,OAAA,EAAS,EAAE,YAAA,EAAa;AAAA,MAC/C,EAAE,IAAA,EAAM,+BAAA,EAAiC,OAAA,EAAS,EAAE,YAAA,EAAa;AAAA,MACjE,EAAE,IAAA,EAAM,uCAAA,EAAyC,OAAA,EAAS,EAAE,YAAA;AAAa,QAE3E;AAAC,GACP;AACF;AAEA,SAAS,eAAe,CAAA,EAAwD;AAC9E,EAAA,OAAO;AAAA,IACL,EAAE,GAAA,EAAK,YAAA,EAAc,IAAA,EAAM,uBAAA,EAAwB;AAAA,IACnD,EAAE,GAAA,EAAK,YAAA,EAAc,IAAA,EAAM,sBAAA,EAAuB;AAAA,IAClD,EAAE,GAAA,EAAK,YAAA,EAAc,IAAA,EAAM,kCAAA,EAAoC,aAAa,WAAA,EAAY;AAAA;AAAA;AAAA,IAGxF,GAAI,CAAA,CAAE,WAAA,GAAc,KAAK,CAAA,CAAE,kBAAA;AAAA,IAC3B,GAAI,EAAE,YAAA,GACF;AAAA,MACE;AAAA,QACE,GAAA,EAAK,YAAA;AAAA,QACL,IAAA,EAAM,2BAAA;AAAA,QACN,WAAA,EAAa;AAAA;AACf,QAEF,EAAC;AAAA,IACL,GAAI,CAAA,CAAE,WAAA,GAAc,EAAC,GAAI,CAAC,EAAE,GAAA,EAAK,eAAA,EAA0B,IAAA,EAAM,CAAA,CAAE,cAAA,EAAgB,CAAA;AAAA,IACnF,GAAI,EAAE,kBAAA,GACF;AAAA,MACE;AAAA,QACE,EAAA,EAAI,kBAAA;AAAA,QACJ,GAAA,EAAK,YAAA;AAAA,QACL,MAAM,CAAA,CAAE,kBAAA;AAAA,QACR,KAAA,EAAO;AAAA;AACT,QAEF,EAAC;AAAA,IACL,GAAI,CAAA,CAAE,kBAAA,IAAsB,CAAC,CAAA,CAAE,YAAA,IAAgB,EAAE,cAAA,GAC7C;AAAA,MACE;AAAA,QACE,EAAA,EAAI,6BAAA;AAAA,QACJ,GAAA,EAAK,SAAA;AAAA,QACL,EAAA,EAAI,OAAA;AAAA,QACJ,MAAM,CAAA,CAAE;AAAA;AACV,QAEF,EAAC;AAAA,IACL,GAAI,CAAA,CAAE,OAAA,GAAU,CAAC,EAAE,GAAA,EAAK,MAAA,EAAQ,IAAA,EAAM,CAAA,CAAE,OAAA,EAAS,CAAA,GAAI,EAAC;AAAA,IACtD,GAAI,CAAA,CAAE,OAAA,GACF,CAAC,EAAE,EAAA,EAAI,kBAAA,EAAoB,GAAA,EAAK,8BAAA,EAAgC,IAAA,EAAM,CAAA,CAAE,OAAA,EAAS,IACjF,EAAC;AAAA,IACL,GAAI,CAAA,CAAE,cAAA,IAAkB,CAAA,CAAE,SAAA,GACtB,CAAC,EAAE,EAAA,EAAI,kBAAA,EAAoB,GAAA,EAAK,cAAc,IAAA,EAAM,CAAA,CAAE,SAAA,EAAW,IACjE,EAAC;AAAA,IACL;AAAA,MACE,EAAA,EAAI,iBAAA;AAAA,MACJ,GAAA,EAAK,YAAA;AAAA,MACL,IAAA,EAAM,mBAAA;AAAA,MACN,KAAA,EAAO;AAAA,KACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,GAAI,CAAA,CAAE,aAAA,IAAiB,EAAE,QAAA,GACrB,CAAC,EAAE,EAAA,EAAI,yBAAA,EAA2B,GAAA,EAAK,SAAA,EAAW,IAAI,QAAA,EAAU,IAAA,EAAM,EAAE,QAAA,EAAU,IAClF;AAAC,GACP;AACF;AAIA,IAAM,OAAA,GAAU,CAAC,EAAA,EAAY,QAAA,MAAsB;AAAA,EACjD,EAAA;AAAA,EACA,IAAA,EAAM,EAAA;AAAA,EACN,UAAA,EAAY,SAAA;AAAA,EACZ;AACF,CAAA,CAAA;AAEA,SAAS,gBAAgB,CAAA,EAAyD;AAChF,EAAA,OAAO;AAAA,IACL,OAAA,CAAQ,oBAAoB,WAAW,CAAA;AAAA,IACvC,GAAI,CAAC,CAAA,CAAE,YAAA,IAAgB,EAAE,cAAA,GACrB;AAAA,MACE,OAAA;AAAA,QACE,yBAAA;AAAA,QACA,CAAA,wBAAA,EAA2B,CAAA,CAAE,cAAc,CAAA,+BAAA,EAAkC,EAAE,cAAc,CAAA,GAAA;AAAA;AAC/F,QAEF,EAAC;AAAA,IACL,GAAI,CAAC,CAAA,CAAE,cAAA,IAAkB,CAAA,CAAE,SAAA,GAAY,CAAC,OAAA,CAAQ,kBAAA,EAAoB,CAAA,CAAE,SAAS,CAAC,IAAI;AAAC,GACvF;AACF;AAEA,SAAS,iBAAiB,CAAA,EAA0D;AAClF,EAAA,OAAO;AAAA;AAAA;AAAA,IAGL,GAAI,CAAA,CAAE,gBAAA,GAAmB,CAAC,EAAE,EAAA,EAAI,mBAAA,EAAqB,QAAA,EAAU,CAAA,CAAE,gBAAA,EAAkB,CAAA,GAAI,EAAC;AAAA,IACxF,EAAE,EAAA,EAAI,eAAA,EAAiB,QAAA,EAAU,iBAAA,EAAkB;AAAA;AAAA;AAAA,IAGnD,EAAE,EAAA,EAAI,iBAAA,EAAmB,QAAA,EAAU,EAAE,qBAAA,EAAsB;AAAA;AAAA;AAAA,IAG3D,GAAI,CAAA,CAAE,oBAAA,GACF,CAAC,EAAE,EAAA,EAAI,wBAAA,EAA0B,QAAA,EAAU,CAAA,CAAE,oBAAA,EAAsB,CAAA,GACnE,EAAC;AAAA,IACL,EAAE,EAAA,EAAI,iBAAA,EAAmB,QAAA,EAAU,iBAAA,EAAkB;AAAA;AAAA,IAErD,GAAI,CAAA,CAAE,QAAA,GAAW,CAAC,mBAAA,CAAoB,CAAA,CAAE,QAAA,EAAU,OAAA,CAAQ,CAAA,CAAE,aAAa,CAAC,CAAC,IAAI;AAAC,GAClF;AACF;AAIA,SAAS,mBAAA,CAAoB,UAAkB,KAAA,EAAgB;AAC7D,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,iBAAA;AAAA,IACJ,QAAA,EAAU,KAAA,GACN,CAAA,sGAAA,EAAyG,qBAAA,CAAsB,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAC,CAAA,yDAAA,CAAA,GACxJ,CAAA,MAAA,EAAS,QAAQ,CAAA,yEAAA;AAAA,GACvB;AACF","file":"chunk-SXI2XBCC.js","sourcesContent":["import type { HeadDescriptor, HeadResult } from '../../utils/head';\nimport { mergeHead, resolveHead } from '../../utils/head';\nimport { buildBaseHead } from '../../utils/baseHead';\nimport { FALLBACK_LOCALE } from '../../providers/locale-constants';\nimport { getTwilightContext } from '../../twilight/context';\nimport type { TwilightContextMatch } from '../../twilight/ensure-context';\nimport { ensureTwilightContextFromMatches } from '../../twilight/ensure-context';\nimport type { StoreContext } from '../../api/store';\nimport type { AppSnippet } from '../../api/apps';\nimport { SettingsError } from '../../utils/errors';\nimport { renderAppScopeInstallScript } from '../../utils/app-scope';\nimport { renderThemeHookSlotsScript } from '../../utils/theme-hook-slots';\nimport { escapeForInlineScript } from '../../utils/inline-script';\nimport { readEnv, renderRuntimeEnvScript } from '../../utils/runtime-env';\n\nconst SALLA_ICONS_CSS_URL = 'https://cdn.assets.salla.network/static/fonts/sallaicons.css?v=2.0.5';\nconst LIT_VERSION = '3.3.3';\nconst LIT_CDN_BASE = `https://cdn.assets.salla.network/static/lit/${LIT_VERSION}`;\n\n/** Bare-specifier map for the lit build the engine's `<salla-*>` web components resolve against. */\nconst LIT_IMPORTS: Record<string, string> = {\n lit: `${LIT_CDN_BASE}/lit.js`,\n 'lit/': `${LIT_CDN_BASE}/`,\n 'lit-html': `${LIT_CDN_BASE}/lit-html/lit-html.js`,\n 'lit-html/': `${LIT_CDN_BASE}/lit-html/`,\n 'lit-element': `${LIT_CDN_BASE}/lit-element/lit-element.js`,\n 'lit-element/': `${LIT_CDN_BASE}/lit-element/`,\n '@lit/reactive-element': `${LIT_CDN_BASE}/reactive-element/reactive-element.js`,\n '@lit/reactive-element/': `${LIT_CDN_BASE}/reactive-element/`,\n};\n\nexport const TICKETING_SCRIPT_URL =\n 'https://cdn.assets.salla.network/latest/@salla.sa/ui-store-ticketing-system/ticketing-system.es.js';\n\nconst TWILIGHT_RELEASE_CDN = 'https://cdn.salla.network/js/twilight';\nconst TWILIGHT_DEV_CDN = 'https://cdn.assets.salla.network/dev/@salla.sa/twilight';\n// The oldest Twilight release this engine works with. Raise it whenever the engine\n// starts relying on something newer; the reason lives in that commit. Today's floor:\n// components ship their own CSS, which themes no longer compile (SallaApp/twilight#2107).\nconst MIN_TWILIGHT_VERSION = '2.14.538';\n// Last resort when no override and no platform pin, and the substitute for a pin below the floor.\nconst DEFAULT_TWILIGHT_VERSION = '2.14.584';\nconst releaseUrl = (version: string): string =>\n `${TWILIGHT_RELEASE_CDN}/${version}/twilight.esm.js`;\n// The head is built more than once per request (early hints, then the page); say it once.\nconst warnedPins = new Set<string>();\n\n/** `x.y.z` release pins only; dev shas and other strings are loaded as given. */\nfunction belowMinimum(version: string): boolean {\n return (\n /^\\d+\\.\\d+\\.\\d+$/.test(version) &&\n version.localeCompare(MIN_TWILIGHT_VERSION, undefined, { numeric: true }) < 0\n );\n}\n\n/** The `x.y.z` release segment of a release-CDN `.../twilight.esm.js` URL, if present. */\nfunction releaseVersionInUrl(url: string): string | null {\n const match = url.match(/\\/(\\d+\\.\\d+\\.\\d+)\\/twilight\\.esm\\.js(?:[?#]|$)/);\n return match ? match[1] : null;\n}\n\n/**\n * `VITE_TWILIGHT_URL`/`VITE_TWILIGHT_VERSION` outrank everything below, including\n * `theme.twilight.version`'s own `belowMinimum` guard — a stale override wins\n * silently otherwise (TD-16375: a scaffold-time pin outlived the engine raising\n * MIN_TWILIGHT_VERSION, so every new theme rendered without component CSS and\n * nothing said why). Only a dev-mode nudge, not a swap: an env override is a\n * deliberate choice, so unlike the settings-pin path below this never substitutes\n * the engine default underneath the developer.\n */\nfunction warnIfOverrideBelowMinimum(source: string, version: string): void {\n // Worker logs in production should stay quiet -- this is a developer-directed nudge,\n // not a user-facing or production-monitored signal. import.meta.env.DEV is a static\n // false in production builds, so this branch (and the console.warn below) is\n // tree-shaken out entirely, same as DevSettingsWidget / dev-settings-store.ts.\n if (!import.meta.env.DEV) return;\n if (!belowMinimum(version)) return;\n const key = `${source}:${version}`;\n if (warnedPins.has(key)) return;\n warnedPins.add(key);\n console.warn(\n `[twilight] ${source}=${version} is below the engine minimum ${MIN_TWILIGHT_VERSION} — components may load without their CSS (SallaApp/twilight#2107). Unset it or bump it to ${MIN_TWILIGHT_VERSION}+.`\n );\n}\n\n/**\n * Which twilight.esm.js the storefront loads, in priority order:\n * 1. `VITE_TWILIGHT_URL` — full local/deployment override.\n * 2. `VITE_TWILIGHT_VERSION` — dev-CDN build override.\n * 3. `theme.twilight.version` from the settings endpoint — the platform-pinned\n * release used when no environment override is configured.\n * 4. The engine's default release, also used when the pin is below the engine minimum.\n */\nexport function resolveTwilightSdkUrl(settings?: StoreContext): string {\n const urlOverride = readEnv('VITE_TWILIGHT_URL');\n if (urlOverride) {\n const version = releaseVersionInUrl(urlOverride);\n if (version) warnIfOverrideBelowMinimum('VITE_TWILIGHT_URL', version);\n return urlOverride;\n }\n\n const versionOverride = readEnv('VITE_TWILIGHT_VERSION');\n if (versionOverride) {\n warnIfOverrideBelowMinimum('VITE_TWILIGHT_VERSION', versionOverride);\n return `${TWILIGHT_DEV_CDN}/${versionOverride}/twilight.esm.js`;\n }\n\n const pinnedVersion = settings?.theme?.twilight?.version;\n if (pinnedVersion && belowMinimum(pinnedVersion)) {\n if (!warnedPins.has(pinnedVersion)) {\n warnedPins.add(pinnedVersion);\n console.warn(\n `[twilight] theme.twilight.version ${pinnedVersion} is below the engine minimum ${MIN_TWILIGHT_VERSION}; loading ${DEFAULT_TWILIGHT_VERSION} instead`\n );\n }\n return releaseUrl(DEFAULT_TWILIGHT_VERSION);\n }\n if (pinnedVersion) return releaseUrl(pinnedVersion);\n\n return releaseUrl(DEFAULT_TWILIGHT_VERSION);\n}\n\n// On a page that preloads its LCP image, the icon font (~270 KB) applies once the first screen's\n// priority images have painted, so it doesn't compete with them; other pages swap on load.\nconst MEDIA_SWAP_SCRIPT = `\n(function(){var d=document,s=function(l){if(l.sheet||\"all\"===l.media)l.media=\"all\";else l.onload=function(){this.media=\"all\"}},f=d.getElementById(\"salla-theme-font\"),i=d.getElementById(\"salla-icons-css\");f&&s(f);if(!i)return;if(!d.querySelector('link[rel=\"preload\"][as=\"image\"]'))return s(i);var g=function(){g=function(){};s(i)},p=function(){requestAnimationFrame(function(){setTimeout(function(){g()})});setTimeout(function(){g()},100)};d.addEventListener(\"DOMContentLoaded\",function(){var m=[].filter.call(d.querySelectorAll('img[fetchpriority=\"high\"]'),function(x){return!x.complete}),n=m.length;if(!n)return p();m.forEach(function(x){var o=function(){--n||p()};x.addEventListener(\"load\",o,{once:!0});x.addEventListener(\"error\",o,{once:!0})});setTimeout(function(){g()},2500)})})();\n`.trim();\n\nconst LOADING_CSS = `\n.loading-overlay{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:#fff;z-index:9999}\n.loading-spinner{animation:spin 1s linear infinite;border-radius:9999px;height:3rem;width:3rem;border-bottom:2px solid var(--color-primary,#000)}\n@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}\nhtml,body{margin:0;padding:0;height:100%}\n`.trim();\n\nconst SALLA_INIT_SCRIPT = `\nwindow.salla = window.Salla = window.Salla || window.salla || {};\nwindow.Salla.onReady = window.Salla.onReady || function(callback) {\n return new Promise(function(resolve) {\n if (window.Salla.status === 'ready') {\n var config = window.salla && window.salla.config && window.salla.config.all();\n resolve(callback ? callback(config) : config);\n } else {\n window.addEventListener('twilight::initiated', function(event) {\n resolve(callback ? callback(event.detail) : event.detail);\n }, { once: true });\n }\n });\n};\n`.trim();\n\n/**\n * Distinct snippet-host origins to `preconnect` (warm DNS/TCP/TLS during parse). From the real\n * URLs (dev/prod-correct), deduped and capped at 4. No `crossOrigin`: snippets are no-cors fetches.\n */\nexport function snippetPreconnectOrigins(snippets: readonly AppSnippet[] | undefined): string[] {\n if (!snippets?.length) return [];\n const origins = new Set<string>();\n for (const app of snippets) {\n if (app.status !== 'enabled') continue;\n for (const s of app.snippets) {\n if (!s.url) continue;\n try {\n origins.add(new URL(s.url).origin);\n } catch {\n /* skip a malformed snippet url rather than breaking the head */\n }\n if (origins.size >= 4) return [...origins];\n }\n }\n return [...origins];\n}\n\nexport function rootHead(ctx: {\n params: Record<string, string>;\n matches?: readonly TwilightContextMatch[];\n}): HeadResult {\n // Re-run on the client during hydration, where the twilight module store may\n // still be empty. Recover it from the resolved match context so the head is\n // built from real settings instead of falling through to 'Store Unavailable'.\n ensureTwilightContextFromMatches(ctx.matches);\n\n let settings: StoreContext | undefined;\n try {\n settings = getTwilightContext().settings;\n } catch (e) {\n if (e instanceof SettingsError) {\n return resolveHead({\n title: 'Store Unavailable',\n });\n }\n throw e;\n }\n const locale = ctx.params.locale || FALLBACK_LOCALE;\n const parts = deriveHeadParts(settings);\n\n return resolveHead(\n mergeHead(buildBaseHead(settings, locale), {\n meta: buildRootMeta(parts),\n links: buildRootLinks(parts),\n styles: buildRootStyles(parts),\n importMap: [{ imports: LIT_IMPORTS }],\n scripts: buildRootScripts(parts),\n })\n );\n}\n\n/** Everything the root head's tag builders read, derived once from the store settings. */\ninterface RootHeadParts {\n store: StoreContext['store'] | undefined;\n favicon?: string;\n primaryColor?: string;\n fontUrl?: string;\n fontUrlWithDisplay?: string;\n isGoogleFont?: boolean;\n fontFamilyName?: string;\n customJs?: string;\n customCss?: string;\n isCustomCssUrl?: boolean;\n isCustomJsUrl?: boolean;\n twilightSdkUrl: string;\n /** The visitor gets the maintenance page, which loads no SDK and no app snippets. */\n maintenance: boolean;\n snippetPreconnects: Array<{ rel: 'preconnect'; href: string }>;\n appScopeInstallScript: string;\n themeHookSlotsScript: string | null;\n runtimeEnvScript: string | null;\n}\n\n/** Google Fonts only honours `display=swap` as a query param; other hosts get the @font-face\n * override instead (see buildRootStyles). */\nfunction deriveFontParts(theme?: StoreContext['theme']) {\n const font = theme?.font;\n const fontUrl = font?.url || font?.path;\n const isGoogleFont = fontUrl?.includes('fonts.googleapis.com');\n const needsDisplay = Boolean(isGoogleFont && fontUrl && !fontUrl.includes('display='));\n const separator = fontUrl?.includes('?') ? '&' : '?';\n\n return {\n fontUrl,\n isGoogleFont,\n fontFamilyName: font?.family_name,\n fontUrlWithDisplay: needsDisplay ? `${fontUrl}${separator}display=swap` : fontUrl,\n };\n}\n\n/** Theme customization JS/CSS, each either a URL to load or an inline blob to embed. */\nfunction deriveCustomizationParts(theme?: StoreContext['theme']) {\n const customization = theme?.customization;\n const customJs = customization?.js?.trim();\n const customCss = customization?.css?.trim();\n const isUrl = (value?: string): boolean =>\n Boolean(value?.startsWith('http') || value?.startsWith('//'));\n\n return {\n customJs,\n customCss,\n isCustomCssUrl: isUrl(customCss),\n isCustomJsUrl: isUrl(customJs),\n };\n}\n\nfunction deriveHeadParts(settings?: StoreContext): RootHeadParts {\n const store = settings?.store;\n\n return {\n store,\n favicon: store?.icon,\n primaryColor: settings?.theme?.color?.primary,\n ...deriveFontParts(settings?.theme),\n ...deriveCustomizationParts(settings?.theme),\n twilightSdkUrl: resolveTwilightSdkUrl(settings),\n maintenance: getTwilightContext().maintenance,\n // Warm the connection to the snippet host(s) during head parse, so the body's deferred\n // `<script src>` snippet tags fetch off an already-open socket instead of DNS+TCP+TLS.\n snippetPreconnects: snippetPreconnectOrigins(getTwilightContext().appsSnippets).map((href) => ({\n rel: 'preconnect' as const,\n href,\n })),\n // Install `Salla.appScope` inline at parse time, before the SDK is ready — else a snippet's\n // onReady callback calls it too early and throws. Always emitted, even when the settings\n // prefetch failed: the CDN snippet tags ship regardless (they come from the *snippets*\n // endpoint), so the factory has to exist for them. `installAppScope` then seeds the real\n // buckets into this install once the client query resolves.\n appScopeInstallScript: renderAppScopeInstallScript(\n getTwilightContext().appsSettings ?? { apps: {} }\n ),\n // Whitelist the theme's own hook slots at parse time too, for the same reason: apps register\n // their `onReady` callbacks from parser-inserted snippet tags, long before React hydrates.\n themeHookSlotsScript: renderThemeHookSlotsScript(),\n // Env this render resolved (worker `vars` live in server-only `process.env`), handed to the\n // client so it doesn't silently fall back to the production defaults. Re-rendered on the\n // client during hydration, where it resolves to the same values or to nothing.\n runtimeEnvScript: renderRuntimeEnvScript(),\n };\n}\n\nfunction buildRootMeta(p: RootHeadParts): NonNullable<HeadDescriptor['meta']> {\n return [\n { name: 'robots', content: 'index, follow' },\n { name: 'msapplication-TileColor', content: '#ffffff' },\n ...(p.favicon ? [{ name: 'msapplication-TileImage', content: p.favicon }] : []),\n ...(p.primaryColor\n ? [\n { name: 'theme-color', content: p.primaryColor },\n { name: 'msapplication-navbutton-color', content: p.primaryColor },\n { name: 'apple-mobile-web-app-status-bar-style', content: p.primaryColor },\n ]\n : []),\n ];\n}\n\nfunction buildRootLinks(p: RootHeadParts): NonNullable<HeadDescriptor['links']> {\n return [\n { rel: 'preconnect', href: 'https://api.salla.dev' },\n { rel: 'preconnect', href: 'https://cdn.salla.sa' },\n { rel: 'preconnect', href: 'https://cdn.assets.salla.network', crossOrigin: 'anonymous' },\n // Warm the installed apps' CDN snippet host(s) — see snippetPreconnectOrigins.\n // Not on the maintenance page: it renders neither the snippets nor the SDK.\n ...(p.maintenance ? [] : p.snippetPreconnects),\n ...(p.isGoogleFont\n ? [\n {\n rel: 'preconnect' as const,\n href: 'https://fonts.gstatic.com',\n crossOrigin: 'anonymous' as const,\n },\n ]\n : []),\n ...(p.maintenance ? [] : [{ rel: 'modulepreload' as const, href: p.twilightSdkUrl }]),\n ...(p.fontUrlWithDisplay\n ? [\n {\n id: 'salla-theme-font',\n rel: 'stylesheet',\n href: p.fontUrlWithDisplay,\n media: 'print',\n },\n ]\n : []),\n ...(p.fontUrlWithDisplay && !p.isGoogleFont && p.fontFamilyName\n ? [\n {\n id: 'salla-font-display-override',\n rel: 'preload',\n as: 'style',\n href: p.fontUrlWithDisplay,\n },\n ]\n : []),\n ...(p.favicon ? [{ rel: 'icon', href: p.favicon }] : []),\n ...(p.favicon\n ? [{ id: 'salla-apple-icon', rel: 'apple-touch-icon-precomposed', href: p.favicon }]\n : []),\n ...(p.isCustomCssUrl && p.customCss\n ? [{ id: 'salla-custom-css', rel: 'stylesheet', href: p.customCss }]\n : []),\n {\n id: 'salla-icons-css',\n rel: 'stylesheet',\n href: SALLA_ICONS_CSS_URL,\n media: 'print',\n },\n // {\n // id: 'intl-tel-input-css',\n // rel: 'stylesheet',\n // href: 'https://cdn.jsdelivr.net/npm/intl-tel-input@26.8.0/build/css/intlTelInput.css',\n // },\n ...(p.isCustomJsUrl && p.customJs\n ? [{ id: 'salla-custom-js-preload', rel: 'preload', as: 'script', href: p.customJs }]\n : []),\n ];\n}\n\n// Hoistable (href + precedence): the web components insert their own <style> near the top of\n// <head> before hydration, which a positionally hydrated <style> would be matched against.\nconst hoisted = (id: string, children: string) => ({\n id,\n href: id,\n precedence: 'default',\n children,\n});\n\nfunction buildRootStyles(p: RootHeadParts): NonNullable<HeadDescriptor['styles']> {\n return [\n hoisted('twilight-loading', LOADING_CSS),\n ...(!p.isGoogleFont && p.fontFamilyName\n ? [\n hoisted(\n 'salla-font-display-swap',\n `@font-face{font-family:\"${p.fontFamilyName}\";font-display:swap;src:local(\"${p.fontFamilyName}\")}`\n ),\n ]\n : []),\n ...(!p.isCustomCssUrl && p.customCss ? [hoisted('salla-custom-css', p.customCss)] : []),\n ];\n}\n\nfunction buildRootScripts(p: RootHeadParts): NonNullable<HeadDescriptor['scripts']> {\n return [\n // First: the API base / store identifier this render used, so the hydrated client\n // resolves the same ones (worker `vars` never reach the browser bundle on their own).\n ...(p.runtimeEnvScript ? [{ id: 'salla-runtime-env', children: p.runtimeEnvScript }] : []),\n { id: 'twilight-init', children: SALLA_INIT_SCRIPT },\n // After twilight-init (which defines window.Salla) and before the SDK module, so the\n // appScope factory exists ahead of any snippet's onReady callback firing.\n { id: 'salla-app-scope', children: p.appScopeInstallScript },\n // Arms the hook-slot whitelist push here, so its `twilight::initiated` listener is\n // registered before any app snippet's — listeners fire in registration order.\n ...(p.themeHookSlotsScript\n ? [{ id: 'salla-theme-hook-slots', children: p.themeHookSlotsScript }]\n : []),\n { id: 'salla-async-css', children: MEDIA_SWAP_SCRIPT },\n // The SDK and ticketing modules are rendered at the end of <body> (SallaSdkScripts).\n ...(p.customJs ? [buildCustomJsScript(p.customJs, Boolean(p.isCustomJsUrl))] : []),\n ];\n}\n\n/** A URL customization is loaded after SDK init; an inline one is wrapped so a syntax/runtime\n * error in partner JS warns instead of taking the page down. */\nfunction buildCustomJsScript(customJs: string, isUrl: boolean) {\n return {\n id: 'salla-custom-js',\n children: isUrl\n ? `window.addEventListener('twilight::initiated',function(){var s=document.createElement('script');s.src=${escapeForInlineScript(JSON.stringify(customJs))};s.async=true;document.head.appendChild(s)},{once:true});`\n : `try { ${customJs} } catch(e) { console.warn(\"[ThemeCustomization] Custom JS error:\", e); }`,\n };\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { onSallaEvent } from './chunk-GYXUYHKO.js';
1
+ import { onSallaEvent } from './chunk-NHA4SBKG.js';
2
2
  import { useState, useRef, useEffect, useCallback } from 'react';
3
3
 
4
4
  function useProduct(initialProduct, options) {
@@ -61,5 +61,5 @@ function useProduct(initialProduct, options) {
61
61
  }
62
62
 
63
63
  export { useProduct };
64
- //# sourceMappingURL=chunk-L4TQBWR7.js.map
65
- //# sourceMappingURL=chunk-L4TQBWR7.js.map
64
+ //# sourceMappingURL=chunk-TF6HFXTW.js.map
65
+ //# sourceMappingURL=chunk-TF6HFXTW.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hooks/useProduct.ts"],"names":[],"mappings":"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","file":"chunk-L4TQBWR7.js","sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\nimport type { Product } from '../types';\nimport { onSallaEvent } from '../utils/sdk-helpers';\n\n/**\n * UseProductResult - Return type for useProduct hook\n */\nexport interface UseProductResult {\n /** Current product state (updates on option changes) */\n product: Product;\n /** Reload product data from API */\n reload: () => Promise<void>;\n}\n\nexport interface UseProductOptions {\n /**\n * True while `initialProduct` is a list-card stand-in. When it flips to false\n * (details arrived), state re-seeds. Do not infer this from `options`/`images`\n * — list payloads may include those fields.\n */\n isPreview?: boolean;\n}\n\n/**\n * useProduct - Hook for managing product state with live updates\n *\n * Provides reactive product data with automatic updates for price, stock,\n * and variant changes. Handles manual reloads (e.g., after add-to-cart)\n * and subscribes to Salla SDK events for real-time price updates.\n *\n * Stock status is reflected in `product.is_out_of_stock` which updates\n * when price calculations succeed or fail (e.g., unavailable option combinations).\n *\n * @param initialProduct - The initial product object (typically from loader/SSR).\n * @param options.isPreview - Pass true for a list-card placeholder so the hook\n * re-seeds when details for the same id arrive (`isPreview` goes false).\n *\n * @returns Object with product and reload function\n *\n * @example\n * ```tsx\n * function ProductDetails({ product }) {\n * const { product: updatedProduct, reload } = useProduct(product);\n *\n * const handleAddToCart = async () => {\n * await addToCart(updatedProduct.id);\n * await reload(); // Refresh product state after cart update\n * };\n *\n * return (\n * <div>\n * <h1>{updatedProduct.name}</h1>\n * <p>Price: {formatMoney(updatedProduct.price)}</p>\n * {updatedProduct.is_out_of_stock && <p>Currently out of stock</p>}\n * <button onClick={handleAddToCart}>Add to Cart</button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useProduct(initialProduct: Product, options?: UseProductOptions): UseProductResult {\n const [product, setProduct] = useState<Product>(initialProduct);\n\n // Always keep a ref to the latest initialProduct so the re-seed effect below\n // can read it without adding the full object to the dependency array.\n const initialProductRef = useRef<Product>(initialProduct);\n useEffect(() => {\n initialProductRef.current = initialProduct;\n });\n\n const reload = useCallback(async () => {\n const salla = window.salla;\n if (!salla?.api?.product?.getDetails) return;\n try {\n const response = await salla.api.product.getDetails(String(product.id), [\n 'images',\n 'category',\n ]);\n if (response?.success && response.data) {\n setProduct(response.data as Product);\n }\n } catch {\n // silently ignore network errors during reload\n }\n }, [product.id]);\n\n // Re-seed when the loader navigates to a different product, or when a\n // list-card placeholder (`isPreview`) is replaced by details for the same id.\n // Object identity is not a dependency — that would reset live option/price state.\n useEffect(() => {\n setProduct(initialProductRef.current);\n }, [initialProduct.id, options?.isPreview]);\n\n // Subscribe to Salla option-change events so price/stock stays in sync\n useEffect(() => onSallaEvent('product:options.updated', reload), [reload]);\n\n // Subscribe to price update events (matches product.js registerEvents)\n useEffect(() => {\n const handlePriceUpdated = (res: { data?: Record<string, unknown> }) => {\n const data = res.data;\n if (!data) return;\n\n setProduct((prev) => {\n const price = (data.price as number) ?? prev.price;\n const regularPrice = (data.regular_price as number) ?? prev.regular_price;\n // The payload has no sale_price: like product.js, `price` is the payable (sale) figure.\n const isOnSale = Boolean(data.has_sale_price) && regularPrice > price;\n return {\n ...prev,\n price,\n sale_price: isOnSale ? price : prev.sale_price,\n regular_price: regularPrice,\n is_on_sale: isOnSale,\n starting_price: null,\n weight: (data.weight as string) || '',\n // An empty variant SKU/barcode blanks it; a payload without the field keeps it (product.js).\n sku: data.sku === undefined ? prev.sku : (data.sku as string) || '',\n barcode: data.barcode === undefined ? prev.barcode : (data.barcode as string) || '',\n is_out_of_stock: false,\n };\n });\n };\n\n const listener = handlePriceUpdated as (...args: unknown[]) => void;\n\n // Root on/off: onPriceUpdated registers a wrapper that salla.event.off can't match.\n return onSallaEvent('product::price.updated', listener);\n }, []);\n\n // Subscribe to price update failed events (matches product.js)\n useEffect(() => {\n const handlePriceFailed = () => {\n setProduct((prev) => ({ ...prev, is_out_of_stock: true }));\n };\n\n return onSallaEvent('product::price.updated.failed', handlePriceFailed);\n }, []);\n\n return { product, reload };\n}\n"]}
1
+ {"version":3,"sources":["../src/hooks/useProduct.ts"],"names":[],"mappings":"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","file":"chunk-TF6HFXTW.js","sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\nimport type { Product } from '../types';\nimport { onSallaEvent } from '../utils/sdk-helpers';\n\n/**\n * UseProductResult - Return type for useProduct hook\n */\nexport interface UseProductResult {\n /** Current product state (updates on option changes) */\n product: Product;\n /** Reload product data from API */\n reload: () => Promise<void>;\n}\n\nexport interface UseProductOptions {\n /**\n * True while `initialProduct` is a list-card stand-in. When it flips to false\n * (details arrived), state re-seeds. Do not infer this from `options`/`images`\n * — list payloads may include those fields.\n */\n isPreview?: boolean;\n}\n\n/**\n * useProduct - Hook for managing product state with live updates\n *\n * Provides reactive product data with automatic updates for price, stock,\n * and variant changes. Handles manual reloads (e.g., after add-to-cart)\n * and subscribes to Salla SDK events for real-time price updates.\n *\n * Stock status is reflected in `product.is_out_of_stock` which updates\n * when price calculations succeed or fail (e.g., unavailable option combinations).\n *\n * @param initialProduct - The initial product object (typically from loader/SSR).\n * @param options.isPreview - Pass true for a list-card placeholder so the hook\n * re-seeds when details for the same id arrive (`isPreview` goes false).\n *\n * @returns Object with product and reload function\n *\n * @example\n * ```tsx\n * function ProductDetails({ product }) {\n * const { product: updatedProduct, reload } = useProduct(product);\n *\n * const handleAddToCart = async () => {\n * await addToCart(updatedProduct.id);\n * await reload(); // Refresh product state after cart update\n * };\n *\n * return (\n * <div>\n * <h1>{updatedProduct.name}</h1>\n * <p>Price: {formatMoney(updatedProduct.price)}</p>\n * {updatedProduct.is_out_of_stock && <p>Currently out of stock</p>}\n * <button onClick={handleAddToCart}>Add to Cart</button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useProduct(initialProduct: Product, options?: UseProductOptions): UseProductResult {\n const [product, setProduct] = useState<Product>(initialProduct);\n\n // Always keep a ref to the latest initialProduct so the re-seed effect below\n // can read it without adding the full object to the dependency array.\n const initialProductRef = useRef<Product>(initialProduct);\n useEffect(() => {\n initialProductRef.current = initialProduct;\n });\n\n const reload = useCallback(async () => {\n const salla = window.salla;\n if (!salla?.api?.product?.getDetails) return;\n try {\n const response = await salla.api.product.getDetails(String(product.id), [\n 'images',\n 'category',\n ]);\n if (response?.success && response.data) {\n setProduct(response.data as Product);\n }\n } catch {\n // silently ignore network errors during reload\n }\n }, [product.id]);\n\n // Re-seed when the loader navigates to a different product, or when a\n // list-card placeholder (`isPreview`) is replaced by details for the same id.\n // Object identity is not a dependency — that would reset live option/price state.\n useEffect(() => {\n setProduct(initialProductRef.current);\n }, [initialProduct.id, options?.isPreview]);\n\n // Subscribe to Salla option-change events so price/stock stays in sync\n useEffect(() => onSallaEvent('product:options.updated', reload), [reload]);\n\n // Subscribe to price update events (matches product.js registerEvents)\n useEffect(() => {\n const handlePriceUpdated = (res: { data?: Record<string, unknown> }) => {\n const data = res.data;\n if (!data) return;\n\n setProduct((prev) => {\n const price = (data.price as number) ?? prev.price;\n const regularPrice = (data.regular_price as number) ?? prev.regular_price;\n // The payload has no sale_price: like product.js, `price` is the payable (sale) figure.\n const isOnSale = Boolean(data.has_sale_price) && regularPrice > price;\n return {\n ...prev,\n price,\n sale_price: isOnSale ? price : prev.sale_price,\n regular_price: regularPrice,\n is_on_sale: isOnSale,\n starting_price: null,\n weight: (data.weight as string) || '',\n // An empty variant SKU/barcode blanks it; a payload without the field keeps it (product.js).\n sku: data.sku === undefined ? prev.sku : (data.sku as string) || '',\n barcode: data.barcode === undefined ? prev.barcode : (data.barcode as string) || '',\n is_out_of_stock: false,\n };\n });\n };\n\n const listener = handlePriceUpdated as (...args: unknown[]) => void;\n\n // Root on/off: onPriceUpdated registers a wrapper that salla.event.off can't match.\n return onSallaEvent('product::price.updated', listener);\n }, []);\n\n // Subscribe to price update failed events (matches product.js)\n useEffect(() => {\n const handlePriceFailed = () => {\n setProduct((prev) => ({ ...prev, is_out_of_stock: true }));\n };\n\n return onSallaEvent('product::price.updated.failed', handlePriceFailed);\n }, []);\n\n return { product, reload };\n}\n"]}
@@ -1,11 +1,11 @@
1
1
  import { reorder, useLiveBlockMoves } from './chunk-IXHM24Z4.js';
2
- import { HomeComponentRenderer, ReorderProducts } from './chunk-L55G7FJZ.js';
3
- import { home } from './chunk-PAMMBDFM.js';
4
- import { useDevHomeBlocks } from './chunk-WBPOWM74.js';
5
- import { storePageUrl, buildHreflangAlternates } from './chunk-OM2GRPDH.js';
2
+ import { HomeComponentRenderer, ReorderProducts } from './chunk-VNDUKDZG.js';
3
+ import { home } from './chunk-YBIL64R7.js';
4
+ import { useDevHomeBlocks } from './chunk-25UDBM27.js';
5
+ import { storePageUrl, buildHreflangAlternates } from './chunk-RYGEIQWO.js';
6
6
  import { RouteId } from './chunk-OUW6WESU.js';
7
7
  import { HookSlot } from './chunk-5XDPAKF5.js';
8
- import { getTwilightContext } from './chunk-7VNVCHID.js';
8
+ import { getTwilightContext } from './chunk-6K34BCUP.js';
9
9
  import { memo, useState, useCallback } from 'react';
10
10
  import { Pulse } from '@salla.sa/twilight-components-react';
11
11
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
@@ -102,5 +102,5 @@ function head(ctx) {
102
102
  var Home = { id: RouteId.INDEX, loader, head, Component: HomePage };
103
103
 
104
104
  export { Home, HomeSkeleton, homeLoader };
105
- //# sourceMappingURL=chunk-VSP3INDK.js.map
106
- //# sourceMappingURL=chunk-VSP3INDK.js.map
105
+ //# sourceMappingURL=chunk-TTLRRVM2.js.map
106
+ //# sourceMappingURL=chunk-TTLRRVM2.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/routes/home/loader.ts","../src/routes/home/HomePage.tsx","../src/routes/home/index.tsx"],"names":["HomeSkeleton","HomePage"],"mappings":"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","file":"chunk-VSP3INDK.js","sourcesContent":["import { getTwilightContext } from '../../twilight/context';\nimport { home } from '../../api/home';\nimport type { HomeComponentData } from '../../types';\nimport { RouteId } from '../../router/route-ids';\n\nexport interface HomeLoaderData {\n locale: string;\n components: HomeComponentData[];\n page: { slug: string };\n}\n\nexport async function homeLoader(ctx?: { locale?: string }): Promise<HomeLoaderData> {\n const { queryClient } = getTwilightContext();\n const components = await queryClient.ensureQueryData(home.queries.components());\n const result = {\n locale: ctx?.locale || 'ar',\n components: components.map((comp) => ({\n ...comp,\n path: comp.path?.replace('home.', '') || comp.path,\n })),\n page: { slug: RouteId.INDEX },\n };\n return result;\n}\n","import { memo, useCallback, useState } from 'react';\nimport { useDevHomeBlocks } from '../../dev/dev-settings-store';\nimport { HookSlot } from '../../hooks';\nimport { HomeComponentRenderer, ReorderProducts } from '../../components/home';\nimport { reorder, useLiveBlockMoves } from '../../components/live-editor/moves';\nimport type { HomePageProps } from './types';\nimport type { HomeComponentData } from '../../types';\nimport { Pulse } from '@salla.sa/twilight-components-react';\n\nexport const HomeSkeleton = memo(function HomeSkeleton() {\n return (\n <>\n <div className=\"s-block container skeleton-block-hero\">\n <Pulse className=\"h-64 sm:h-80 rounded-md\" />\n </div>\n <div className=\"s-block container skeleton-block-products\">\n <Pulse className=\"h-10 w-48 mb-4\" />\n <div className=\"grid grid-cols-2 sm:grid-cols-4 gap-4\">\n {[1, 2, 3, 4].map((i) => (\n <Pulse key={i} className=\"h-56\" />\n ))}\n </div>\n </div>\n <div className=\"s-block container skeleton-block-products\">\n <Pulse className=\"h-10 w-48 mb-4\" />\n <div className=\"grid grid-cols-2 sm:grid-cols-4 gap-4\">\n {[1, 2, 3, 4].map((i) => (\n <Pulse key={i} className=\"h-56\" />\n ))}\n </div>\n </div>\n </>\n );\n});\n\n/** The blocks' places in the store's order: 0, 1, 2… */\nconst storeOrder = (blocks: readonly unknown[]) => Array.from(blocks, (_, at) => at);\n\nexport const HomePage = memo(function HomePage({ components = [] }: HomePageProps) {\n // Dev-mode only: the dev editor's layout replaces the store's blocks while it\n // is on. No-op passthrough in production builds.\n const renderedComponents = useDevHomeBlocks(components);\n // The theme editor's preview moves blocks in place while the editor saves the\n // order; blocks from the server (a new page, a reload) start over from theirs.\n const [moved, setMoved] = useState<{ source: HomeComponentData[]; order: number[] } | null>(null);\n const order = moved?.source === renderedComponents ? moved.order : null;\n const onMove = useCallback(\n (from: number, to: number) =>\n setMoved((prev) => ({\n source: renderedComponents,\n order: reorder(\n prev?.source === renderedComponents ? prev.order : storeOrder(renderedComponents),\n from,\n to\n ),\n })),\n [renderedComponents]\n );\n useLiveBlockMoves(onMove);\n const placed = order ?? storeOrder(renderedComponents);\n\n return (\n <>\n <HookSlot name=\"home:start\" />\n <HookSlot name=\"home:content\" />\n {placed.map((at, index) => {\n const data = renderedComponents[at];\n // `data.key` is the twilight.json catalog id, shared by every placement\n // of that block. Platform blocks send null. The block's place in the\n // store's order is unique and stays with it when the preview moves it, so\n // a move keeps its state; a dev layout block keeps its own id.\n return <HomeComponentRenderer key={data.__dev_id ?? at} data={data} index={index} />;\n })}\n <HookSlot name=\"home:end\" />\n <ReorderProducts />\n </>\n );\n});\n\nexport { HomePage as default };\n","import type { HeadDescriptor } from '../../utils/head';\nimport { buildHreflangAlternates, storePageUrl } from '../../utils/baseHead';\nimport type { HomeLoaderData } from './loader';\nimport { homeLoader } from './loader';\nimport type { TwilightContext } from '../../twilight/context';\nimport { HomePage } from './HomePage';\nimport { RouteId } from '../../router/route-ids';\n\nexport { HomeSkeleton } from './HomePage';\nexport { registerHomeComponents, DefaultHomeComponents } from '../../components/home/register';\nexport { registerHomeComponentConfig } from '../../components/home';\nexport type { HomePageProps } from './types';\nexport type { HomeLoaderData } from './loader';\nexport type {\n HomeComponentsProps,\n AnyHomeComponent,\n HomeComponentConfig,\n} from '../../components/home';\n\nfunction loader(_ctx?: { locale?: string }): Promise<HomeLoaderData> {\n return homeLoader({ locale: _ctx?.locale });\n}\n\nfunction head(ctx: TwilightContext): HeadDescriptor {\n const store = ctx.settings?.store;\n if (!store) return {};\n\n const title = store.meta?.title ?? store.name;\n const description = store.meta?.description ?? store.description;\n const keywords = store.meta?.keywords;\n // `/ar`, like Twig, where store.url reads `/ar/`.\n const url = storePageUrl(ctx.settings, ctx.location.pathname) ?? store.url;\n\n return {\n title,\n description,\n keywords,\n canonical: url,\n openGraph: {\n type: 'website',\n title,\n description,\n images: store.logo,\n url,\n },\n twitter: {\n card: 'summary_large_image',\n title,\n description,\n images: store.logo,\n },\n alternateLanguages: buildHreflangAlternates(ctx.settings, ctx.location.pathname),\n };\n}\n\nexport const Home = { id: RouteId.INDEX, loader, head, Component: HomePage } as const;\n\nexport { homeLoader };\n"]}
1
+ {"version":3,"sources":["../src/routes/home/loader.ts","../src/routes/home/HomePage.tsx","../src/routes/home/index.tsx"],"names":["HomeSkeleton","HomePage"],"mappings":"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","file":"chunk-TTLRRVM2.js","sourcesContent":["import { getTwilightContext } from '../../twilight/context';\nimport { home } from '../../api/home';\nimport type { HomeComponentData } from '../../types';\nimport { RouteId } from '../../router/route-ids';\n\nexport interface HomeLoaderData {\n locale: string;\n components: HomeComponentData[];\n page: { slug: string };\n}\n\nexport async function homeLoader(ctx?: { locale?: string }): Promise<HomeLoaderData> {\n const { queryClient } = getTwilightContext();\n const components = await queryClient.ensureQueryData(home.queries.components());\n const result = {\n locale: ctx?.locale || 'ar',\n components: components.map((comp) => ({\n ...comp,\n path: comp.path?.replace('home.', '') || comp.path,\n })),\n page: { slug: RouteId.INDEX },\n };\n return result;\n}\n","import { memo, useCallback, useState } from 'react';\nimport { useDevHomeBlocks } from '../../dev/dev-settings-store';\nimport { HookSlot } from '../../hooks';\nimport { HomeComponentRenderer, ReorderProducts } from '../../components/home';\nimport { reorder, useLiveBlockMoves } from '../../components/live-editor/moves';\nimport type { HomePageProps } from './types';\nimport type { HomeComponentData } from '../../types';\nimport { Pulse } from '@salla.sa/twilight-components-react';\n\nexport const HomeSkeleton = memo(function HomeSkeleton() {\n return (\n <>\n <div className=\"s-block container skeleton-block-hero\">\n <Pulse className=\"h-64 sm:h-80 rounded-md\" />\n </div>\n <div className=\"s-block container skeleton-block-products\">\n <Pulse className=\"h-10 w-48 mb-4\" />\n <div className=\"grid grid-cols-2 sm:grid-cols-4 gap-4\">\n {[1, 2, 3, 4].map((i) => (\n <Pulse key={i} className=\"h-56\" />\n ))}\n </div>\n </div>\n <div className=\"s-block container skeleton-block-products\">\n <Pulse className=\"h-10 w-48 mb-4\" />\n <div className=\"grid grid-cols-2 sm:grid-cols-4 gap-4\">\n {[1, 2, 3, 4].map((i) => (\n <Pulse key={i} className=\"h-56\" />\n ))}\n </div>\n </div>\n </>\n );\n});\n\n/** The blocks' places in the store's order: 0, 1, 2… */\nconst storeOrder = (blocks: readonly unknown[]) => Array.from(blocks, (_, at) => at);\n\nexport const HomePage = memo(function HomePage({ components = [] }: HomePageProps) {\n // Dev-mode only: the dev editor's layout replaces the store's blocks while it\n // is on. No-op passthrough in production builds.\n const renderedComponents = useDevHomeBlocks(components);\n // The theme editor's preview moves blocks in place while the editor saves the\n // order; blocks from the server (a new page, a reload) start over from theirs.\n const [moved, setMoved] = useState<{ source: HomeComponentData[]; order: number[] } | null>(null);\n const order = moved?.source === renderedComponents ? moved.order : null;\n const onMove = useCallback(\n (from: number, to: number) =>\n setMoved((prev) => ({\n source: renderedComponents,\n order: reorder(\n prev?.source === renderedComponents ? prev.order : storeOrder(renderedComponents),\n from,\n to\n ),\n })),\n [renderedComponents]\n );\n useLiveBlockMoves(onMove);\n const placed = order ?? storeOrder(renderedComponents);\n\n return (\n <>\n <HookSlot name=\"home:start\" />\n <HookSlot name=\"home:content\" />\n {placed.map((at, index) => {\n const data = renderedComponents[at];\n // `data.key` is the twilight.json catalog id, shared by every placement\n // of that block. Platform blocks send null. The block's place in the\n // store's order is unique and stays with it when the preview moves it, so\n // a move keeps its state; a dev layout block keeps its own id.\n return <HomeComponentRenderer key={data.__dev_id ?? at} data={data} index={index} />;\n })}\n <HookSlot name=\"home:end\" />\n <ReorderProducts />\n </>\n );\n});\n\nexport { HomePage as default };\n","import type { HeadDescriptor } from '../../utils/head';\nimport { buildHreflangAlternates, storePageUrl } from '../../utils/baseHead';\nimport type { HomeLoaderData } from './loader';\nimport { homeLoader } from './loader';\nimport type { TwilightContext } from '../../twilight/context';\nimport { HomePage } from './HomePage';\nimport { RouteId } from '../../router/route-ids';\n\nexport { HomeSkeleton } from './HomePage';\nexport { registerHomeComponents, DefaultHomeComponents } from '../../components/home/register';\nexport { registerHomeComponentConfig } from '../../components/home';\nexport type { HomePageProps } from './types';\nexport type { HomeLoaderData } from './loader';\nexport type {\n HomeComponentsProps,\n AnyHomeComponent,\n HomeComponentConfig,\n} from '../../components/home';\n\nfunction loader(_ctx?: { locale?: string }): Promise<HomeLoaderData> {\n return homeLoader({ locale: _ctx?.locale });\n}\n\nfunction head(ctx: TwilightContext): HeadDescriptor {\n const store = ctx.settings?.store;\n if (!store) return {};\n\n const title = store.meta?.title ?? store.name;\n const description = store.meta?.description ?? store.description;\n const keywords = store.meta?.keywords;\n // `/ar`, like Twig, where store.url reads `/ar/`.\n const url = storePageUrl(ctx.settings, ctx.location.pathname) ?? store.url;\n\n return {\n title,\n description,\n keywords,\n canonical: url,\n openGraph: {\n type: 'website',\n title,\n description,\n images: store.logo,\n url,\n },\n twitter: {\n card: 'summary_large_image',\n title,\n description,\n images: store.logo,\n },\n alternateLanguages: buildHreflangAlternates(ctx.settings, ctx.location.pathname),\n };\n}\n\nexport const Home = { id: RouteId.INDEX, loader, head, Component: HomePage } as const;\n\nexport { homeLoader };\n"]}
@@ -1,6 +1,6 @@
1
- import { orThrow } from './chunk-4UEXSD7E.js';
2
- import { api } from './chunk-RQG44QD7.js';
3
- import { getSallaSDK } from './chunk-GYXUYHKO.js';
1
+ import { orThrow } from './chunk-RLJLG4EN.js';
2
+ import { api } from './chunk-E5DP3MHE.js';
3
+ import { getSallaSDK } from './chunk-NHA4SBKG.js';
4
4
  import { queryOptions } from '@tanstack/react-query';
5
5
 
6
6
  function normalizeCartResponse(data) {
@@ -44,5 +44,5 @@ var cart = {
44
44
  };
45
45
 
46
46
  export { cart };
47
- //# sourceMappingURL=chunk-P2WO5CNH.js.map
48
- //# sourceMappingURL=chunk-P2WO5CNH.js.map
47
+ //# sourceMappingURL=chunk-UHGDQIIF.js.map
48
+ //# sourceMappingURL=chunk-UHGDQIIF.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/api/cart.ts"],"names":[],"mappings":";;;;;AAaA,SAAS,sBAAsB,IAAA,EAAoC;AACjE,EAAA,IAAI,CAAC,IAAA,CAAK,IAAA,EAAM,OAAO,IAAA;AACvB,EAAA,OAAO;AAAA,IACL,GAAG,IAAA,CAAK,IAAA;AAAA,IACR,OAAA,EAAS,KAAK,OAAA,IAAW,IAAA;AAAA;AAAA,IAEzB,IAAA,EAAM,IAAA,CAAK,IAAA,IAAQ,IAAA,CAAK,KAAK,IAAA,IAAQ;AAAA,GACvC;AACF;AAEO,IAAM,IAAA,GAAO;AAAA,EAClB,GAAA,EAAK,OAAO,MAAA,KAAyC;AACnD,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,GAAA,CAAI,IAAI,CAAA,KAAA,EAAQ,MAAM,CAAA,CAAE,CAAA,CAAE,IAAA,EAAgC;AACjF,IAAA,OAAO,sBAAsB,IAAI,CAAA;AAAA,EACnC,CAAA;AAAA,EAEA,YAAY,CAAC,MAAA,KAAyC,QAAQ,IAAA,CAAK,GAAA,CAAI,MAAM,CAAC,CAAA;AAAA;AAAA,EAG9E,cAAc,YAAoC;AAChD,IAAA,MAAM,QAAQ,WAAA,EAAY;AAC1B,IAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AAEnB,IAAA,MAAM,KAAA,CAAM,OAAA,EAAQ,CAAE,KAAA,CAAM,MAAM,MAAS,CAAA;AAC3C,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,gBAAA,EAAiB;AAAA,EACzC,CAAA;AAAA,EAEA,OAAA,EAAS;AAAA,IACP,MAAA,EAAQ,CAAC,MAAA,KACP,YAAA,CAAa;AAAA,MACX,QAAA,EAAU,CAAC,MAAA,EAAQ,MAAM,CAAA;AAAA,MACzB,OAAA,EAAS,MAAM,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA;AAAA;AAAA,MAE9B,SAAA,EAAW,CAAA;AAAA,MACX,MAAA,EAAQ;AAAA,KACT,CAAA;AAAA,IACH,SAAA,EAAW,MACT,YAAA,CAAa;AAAA,MACX,QAAA,EAAU,CAAC,MAAA,EAAQ,YAAY,CAAA;AAAA,MAC/B,OAAA,EAAS,MAAM,IAAA,CAAK,YAAA,EAAa;AAAA;AAAA,MAEjC,SAAA,EAAW,CAAA;AAAA,MACX,MAAA,EAAQ;AAAA,KACT;AAAA;AAEP","file":"chunk-P2WO5CNH.js","sourcesContent":["import { queryOptions } from '@tanstack/react-query';\nimport { api } from './client';\nimport type { Cart } from '../types';\nimport { orThrow } from '../providers/NavigationProvider';\nimport { getSallaSDK } from '../utils/sdk-helpers';\n\nexport interface CartApiResponse {\n /** Absent once the cart was turned into an order (the body then carries a top-level `redirect`). */\n cart?: Omit<Cart, 'loyalty'>;\n loyalty?: Cart['loyalty'];\n gift?: Cart['gift'];\n}\n\nfunction normalizeCartResponse(data: CartApiResponse): Cart | null {\n if (!data.cart) return null;\n return {\n ...data.cart,\n loyalty: data.loyalty ?? null,\n // The API sends `gift` inside `cart`.\n gift: data.gift ?? data.cart.gift ?? null,\n } as Cart;\n}\n\nexport const cart = {\n get: async (cartId: number): Promise<Cart | null> => {\n const { data } = await api.get(`cart/${cartId}`).json<{ data: CartApiResponse }>();\n return normalizeCartResponse(data);\n },\n\n getOrThrow: (cartId: number): Promise<Cart | null> => orThrow(cart.get(cartId)),\n\n /** The visitor's cart id, which only the Salla SDK knows; `null` outside the browser. */\n getCurrentId: async (): Promise<number | null> => {\n const salla = getSallaSDK();\n if (!salla) return null;\n // The app bundle can run before the SDK module, when `salla` is still the head stub.\n await salla.onReady().catch(() => undefined);\n return salla.cart.api.getCurrentCartId();\n },\n\n queries: {\n detail: (cartId: number) =>\n queryOptions({\n queryKey: ['cart', cartId],\n queryFn: () => cart.get(cartId),\n // The SDK changes the cart from any page, so a cached copy is never safe to show.\n staleTime: 0,\n gcTime: 0,\n }),\n currentId: () =>\n queryOptions({\n queryKey: ['cart', 'current-id'],\n queryFn: () => cart.getCurrentId(),\n // Completing an order starts a new cart, so an earlier id is never reused.\n staleTime: 0,\n gcTime: 0,\n }),\n },\n};\n"]}
1
+ {"version":3,"sources":["../src/api/cart.ts"],"names":[],"mappings":";;;;;AAaA,SAAS,sBAAsB,IAAA,EAAoC;AACjE,EAAA,IAAI,CAAC,IAAA,CAAK,IAAA,EAAM,OAAO,IAAA;AACvB,EAAA,OAAO;AAAA,IACL,GAAG,IAAA,CAAK,IAAA;AAAA,IACR,OAAA,EAAS,KAAK,OAAA,IAAW,IAAA;AAAA;AAAA,IAEzB,IAAA,EAAM,IAAA,CAAK,IAAA,IAAQ,IAAA,CAAK,KAAK,IAAA,IAAQ;AAAA,GACvC;AACF;AAEO,IAAM,IAAA,GAAO;AAAA,EAClB,GAAA,EAAK,OAAO,MAAA,KAAyC;AACnD,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,GAAA,CAAI,IAAI,CAAA,KAAA,EAAQ,MAAM,CAAA,CAAE,CAAA,CAAE,IAAA,EAAgC;AACjF,IAAA,OAAO,sBAAsB,IAAI,CAAA;AAAA,EACnC,CAAA;AAAA,EAEA,YAAY,CAAC,MAAA,KAAyC,QAAQ,IAAA,CAAK,GAAA,CAAI,MAAM,CAAC,CAAA;AAAA;AAAA,EAG9E,cAAc,YAAoC;AAChD,IAAA,MAAM,QAAQ,WAAA,EAAY;AAC1B,IAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AAEnB,IAAA,MAAM,KAAA,CAAM,OAAA,EAAQ,CAAE,KAAA,CAAM,MAAM,MAAS,CAAA;AAC3C,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,gBAAA,EAAiB;AAAA,EACzC,CAAA;AAAA,EAEA,OAAA,EAAS;AAAA,IACP,MAAA,EAAQ,CAAC,MAAA,KACP,YAAA,CAAa;AAAA,MACX,QAAA,EAAU,CAAC,MAAA,EAAQ,MAAM,CAAA;AAAA,MACzB,OAAA,EAAS,MAAM,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA;AAAA;AAAA,MAE9B,SAAA,EAAW,CAAA;AAAA,MACX,MAAA,EAAQ;AAAA,KACT,CAAA;AAAA,IACH,SAAA,EAAW,MACT,YAAA,CAAa;AAAA,MACX,QAAA,EAAU,CAAC,MAAA,EAAQ,YAAY,CAAA;AAAA,MAC/B,OAAA,EAAS,MAAM,IAAA,CAAK,YAAA,EAAa;AAAA;AAAA,MAEjC,SAAA,EAAW,CAAA;AAAA,MACX,MAAA,EAAQ;AAAA,KACT;AAAA;AAEP","file":"chunk-UHGDQIIF.js","sourcesContent":["import { queryOptions } from '@tanstack/react-query';\nimport { api } from './client';\nimport type { Cart } from '../types';\nimport { orThrow } from '../providers/NavigationProvider';\nimport { getSallaSDK } from '../utils/sdk-helpers';\n\nexport interface CartApiResponse {\n /** Absent once the cart was turned into an order (the body then carries a top-level `redirect`). */\n cart?: Omit<Cart, 'loyalty'>;\n loyalty?: Cart['loyalty'];\n gift?: Cart['gift'];\n}\n\nfunction normalizeCartResponse(data: CartApiResponse): Cart | null {\n if (!data.cart) return null;\n return {\n ...data.cart,\n loyalty: data.loyalty ?? null,\n // The API sends `gift` inside `cart`.\n gift: data.gift ?? data.cart.gift ?? null,\n } as Cart;\n}\n\nexport const cart = {\n get: async (cartId: number): Promise<Cart | null> => {\n const { data } = await api.get(`cart/${cartId}`).json<{ data: CartApiResponse }>();\n return normalizeCartResponse(data);\n },\n\n getOrThrow: (cartId: number): Promise<Cart | null> => orThrow(cart.get(cartId)),\n\n /** The visitor's cart id, which only the Salla SDK knows; `null` outside the browser. */\n getCurrentId: async (): Promise<number | null> => {\n const salla = getSallaSDK();\n if (!salla) return null;\n // The app bundle can run before the SDK module, when `salla` is still the head stub.\n await salla.onReady().catch(() => undefined);\n return salla.cart.api.getCurrentCartId();\n },\n\n queries: {\n detail: (cartId: number) =>\n queryOptions({\n queryKey: ['cart', cartId],\n queryFn: () => cart.get(cartId),\n // The SDK changes the cart from any page, so a cached copy is never safe to show.\n staleTime: 0,\n gcTime: 0,\n }),\n currentId: () =>\n queryOptions({\n queryKey: ['cart', 'current-id'],\n queryFn: () => cart.getCurrentId(),\n // Completing an order starts a new cart, so an earlier id is never reused.\n staleTime: 0,\n gcTime: 0,\n }),\n },\n};\n"]}
@@ -1,12 +1,12 @@
1
- import { home } from './chunk-PAMMBDFM.js';
2
- import { product } from './chunk-BYLNAYIZ.js';
3
- import { ProductCard } from './chunk-QGKARX6O.js';
1
+ import { home } from './chunk-YBIL64R7.js';
2
+ import { product } from './chunk-LUPDYN4T.js';
3
+ import { ProductCard } from './chunk-P3D67RVR.js';
4
4
  import { registry } from './chunk-Y32RHCOH.js';
5
5
  import { useTranslation } from './chunk-TYNZ5B2B.js';
6
- import { Image, LazyRenderWhenVisible } from './chunk-NVL6M25Q.js';
6
+ import { Image, LazyRenderWhenVisible } from './chunk-MWG734P7.js';
7
7
  import { Link } from './chunk-AXW67SY7.js';
8
- import { whenSallaLoaded } from './chunk-GYXUYHKO.js';
9
- import { getTwilightContext } from './chunk-7VNVCHID.js';
8
+ import { whenSallaLoaded } from './chunk-NHA4SBKG.js';
9
+ import { getTwilightContext } from './chunk-6K34BCUP.js';
10
10
  import { useTwilight, TwilightContext } from './chunk-DF6FBKDN.js';
11
11
  import { memo, useState, useCallback, createElement, useEffect, lazy, Component, useRef, useMemo, Suspense } from 'react';
12
12
  import { SallaProductsSlider, SallaProductsList, ProductsSliderSkeleton, ListSkeleton, SliderSkeleton, BackgroundSliderSkeleton, BulletDeliverySkeleton, ReviewItemSkeleton, FixedProductsSkeleton, Pulse } from '@salla.sa/twilight-components-react';
@@ -446,15 +446,42 @@ var Youtube = memo(function Youtube2({ data }) {
446
446
  if (!youtubeId) return null;
447
447
  return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx("div", { className: "container", children: /* @__PURE__ */ jsx("div", { className: "videoWrapper", children: isLoaded ? /* @__PURE__ */ jsx("lite-youtube", { videoid: youtubeId, params: "rel=0" }) : /* @__PURE__ */ jsx("div", { className: "animate-pulse bg-gray-200 w-full h-full min-h-[300px] rounded" }) }) }) });
448
448
  });
449
+ var SIZE_PROPS = ["min-height", "height", "width", "aspect-ratio"];
450
+ var SKELETON_PROPS = [...SIZE_PROPS, "skeleton-style"];
451
+ function pickSkeletonProps(props) {
452
+ if (!props || typeof props !== "object") return {};
453
+ return Object.fromEntries(
454
+ Object.entries(props).filter(
455
+ ([name, value]) => SKELETON_PROPS.includes(name) && typeof value === "string" && value.trim() !== ""
456
+ )
457
+ );
458
+ }
459
+ function reservedSizeStyle(props) {
460
+ const sizes = SIZE_PROPS.filter((name) => props[name]);
461
+ if (!sizes.length) return void 0;
462
+ return Object.fromEntries(
463
+ sizes.map((name) => [
464
+ name.replace(/-([a-z])/g, (_, char) => char.toUpperCase()),
465
+ props[name]
466
+ ])
467
+ );
468
+ }
449
469
  var BundleComponent = memo(function BundleComponent2(props) {
450
470
  const [mounted, setMounted] = useState(false);
451
471
  useEffect(() => {
452
472
  setMounted(true);
453
473
  }, []);
474
+ const {
475
+ component_name: componentName,
476
+ bundle_id: bundleId,
477
+ component_props: componentProps,
478
+ ...rest
479
+ } = props.data;
480
+ const skeletonProps = pickSkeletonProps(componentProps);
454
481
  if (!mounted) {
455
- return null;
482
+ const style = reservedSizeStyle(skeletonProps);
483
+ return style ? /* @__PURE__ */ jsx("div", { "aria-hidden": "true", style }) : null;
456
484
  }
457
- const { component_name: componentName, bundle_id: bundleId, ...rest } = props.data;
458
485
  const config = JSON.stringify(rest);
459
486
  return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
460
487
  "salla-custom-component",
@@ -462,6 +489,7 @@ var BundleComponent = memo(function BundleComponent2(props) {
462
489
  "component-name": componentName,
463
490
  "bundle-id": bundleId,
464
491
  config,
492
+ ...skeletonProps,
465
493
  suppressHydrationWarning: true
466
494
  }
467
495
  ) });
@@ -791,5 +819,5 @@ var ReorderProducts = memo(function ReorderProducts2() {
791
819
  });
792
820
 
793
821
  export { BundleComponent, ComponentErrorBoundary, DefaultHomeComponents, FeaturedProductsStyle1, FeaturedProductsStyle2, FeaturedProductsStyle3, FixedBanner, FixedProducts, HomeComponentRenderer, LazyTestimonials, PageBlocks, ParallaxBackground, PhotosSlider, ProductsSlider, ReorderProducts, SquarePhotos, StoreFeatures, Youtube, registerHomeComponentConfig, registerHomeComponents, useReorderButtons };
794
- //# sourceMappingURL=chunk-L55G7FJZ.js.map
795
- //# sourceMappingURL=chunk-L55G7FJZ.js.map
822
+ //# sourceMappingURL=chunk-VNDUKDZG.js.map
823
+ //# sourceMappingURL=chunk-VNDUKDZG.js.map