@sonordev/site-kit 3.2.0 → 3.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent-manifest.json +1 -1
- package/dist/AnalyticsProvider-A3STXJ65.js +29 -0
- package/dist/{AnalyticsProvider-WK2Z6AIN.js.map → AnalyticsProvider-A3STXJ65.js.map} +1 -1
- package/dist/AnalyticsProvider-LEXGFM2K.mjs +8 -0
- package/dist/{AnalyticsProvider-CD635CHQ.mjs.map → AnalyticsProvider-LEXGFM2K.mjs.map} +1 -1
- package/dist/ChatWidget-4QR2ZDRE.mjs +8 -0
- package/dist/{ChatWidget-UAAWDBNS.mjs.map → ChatWidget-4QR2ZDRE.mjs.map} +1 -1
- package/dist/ChatWidget-U3K2VHVN.js +17 -0
- package/dist/{ChatWidget-AIOOZY6H.js.map → ChatWidget-U3K2VHVN.js.map} +1 -1
- package/dist/EngageWidget-2FMKYJJT.mjs +7 -0
- package/dist/{EngageWidget-EZ5T6H3K.mjs.map → EngageWidget-2FMKYJJT.mjs.map} +1 -1
- package/dist/EngageWidget-TOGMQ2G6.js +16 -0
- package/dist/{EngageWidget-RWVWW56C.js.map → EngageWidget-TOGMQ2G6.js.map} +1 -1
- package/dist/{SignalCore-4B4RNYLV.mjs → SignalCore-5QJG3IJB.mjs} +4 -4
- package/dist/{SignalCore-4B4RNYLV.mjs.map → SignalCore-5QJG3IJB.mjs.map} +1 -1
- package/dist/{SignalCore-AECW2JFP.js → SignalCore-JB3VHHTG.js} +8 -8
- package/dist/{SignalCore-AECW2JFP.js.map → SignalCore-JB3VHHTG.js.map} +1 -1
- package/dist/SitemapSync-BJWSTERT.js +15 -0
- package/dist/{SitemapSync-AICU4SSV.js.map → SitemapSync-BJWSTERT.js.map} +1 -1
- package/dist/SitemapSync-T6PIDW64.mjs +6 -0
- package/dist/{SitemapSync-CIZCAZXK.mjs.map → SitemapSync-T6PIDW64.mjs.map} +1 -1
- package/dist/analytics/index.js +11 -11
- package/dist/analytics/index.mjs +4 -4
- package/dist/brand.css +13 -3
- package/dist/{chunk-GCDVKOSM.js → chunk-52VXHSVT.js} +3 -3
- package/dist/{chunk-GCDVKOSM.js.map → chunk-52VXHSVT.js.map} +1 -1
- package/dist/{chunk-I2GTT2DG.js → chunk-5RX4CUR2.js} +19 -21
- package/dist/chunk-5RX4CUR2.js.map +1 -0
- package/dist/{chunk-OTY7EWET.mjs → chunk-5ZNKNNJ4.mjs} +4 -4
- package/dist/{chunk-OTY7EWET.mjs.map → chunk-5ZNKNNJ4.mjs.map} +1 -1
- package/dist/{chunk-RFIWVH3D.mjs → chunk-7OK6BI3A.mjs} +3 -3
- package/dist/{chunk-RFIWVH3D.mjs.map → chunk-7OK6BI3A.mjs.map} +1 -1
- package/dist/{chunk-N2HR2E4Z.mjs → chunk-7R7SGJG3.mjs} +15 -21
- package/dist/chunk-7R7SGJG3.mjs.map +1 -0
- package/dist/{chunk-FMZOZQBV.mjs → chunk-AMBTOIYM.mjs} +19 -21
- package/dist/chunk-AMBTOIYM.mjs.map +1 -0
- package/dist/{chunk-5OWZUNNE.js → chunk-B5YNHSRA.js} +7 -7
- package/dist/{chunk-5OWZUNNE.js.map → chunk-B5YNHSRA.js.map} +1 -1
- package/dist/{chunk-S3YQGTBF.js → chunk-BNBCSHTK.js} +12 -12
- package/dist/{chunk-S3YQGTBF.js.map → chunk-BNBCSHTK.js.map} +1 -1
- package/dist/{chunk-45QHDA7Q.mjs → chunk-BUCF5FUY.mjs} +3 -3
- package/dist/{chunk-45QHDA7Q.mjs.map → chunk-BUCF5FUY.mjs.map} +1 -1
- package/dist/{chunk-TE3W5REY.js → chunk-DCZUMCEC.js} +14 -14
- package/dist/{chunk-TE3W5REY.js.map → chunk-DCZUMCEC.js.map} +1 -1
- package/dist/{chunk-6HPNFWSC.mjs → chunk-DYCEEU67.mjs} +3 -3
- package/dist/{chunk-6HPNFWSC.mjs.map → chunk-DYCEEU67.mjs.map} +1 -1
- package/dist/{chunk-NDHFU4HV.mjs → chunk-E4TWVVSW.mjs} +4 -4
- package/dist/{chunk-NDHFU4HV.mjs.map → chunk-E4TWVVSW.mjs.map} +1 -1
- package/dist/{chunk-NAVDN4AE.js → chunk-E7M5MDGC.js} +29 -40
- package/dist/chunk-E7M5MDGC.js.map +1 -0
- package/dist/{chunk-2WYEJOGA.mjs → chunk-GMO6POZ2.mjs} +3 -3
- package/dist/{chunk-2WYEJOGA.mjs.map → chunk-GMO6POZ2.mjs.map} +1 -1
- package/dist/{chunk-EAASMIWX.js → chunk-GMSPDTEV.js} +15 -9
- package/dist/chunk-GMSPDTEV.js.map +1 -0
- package/dist/{chunk-T2DEEKVQ.mjs → chunk-IR5UC236.mjs} +3 -3
- package/dist/{chunk-T2DEEKVQ.mjs.map → chunk-IR5UC236.mjs.map} +1 -1
- package/dist/{chunk-HAZN43I6.js → chunk-LF3ID6WN.js} +20 -26
- package/dist/chunk-LF3ID6WN.js.map +1 -0
- package/dist/{chunk-57QV6NIY.mjs → chunk-MKZHVSKL.mjs} +3 -3
- package/dist/{chunk-57QV6NIY.mjs.map → chunk-MKZHVSKL.mjs.map} +1 -1
- package/dist/{chunk-SLWTG2LJ.js → chunk-MX6DK246.js} +13 -13
- package/dist/{chunk-SLWTG2LJ.js.map → chunk-MX6DK246.js.map} +1 -1
- package/dist/{chunk-R5A64DCX.js → chunk-MYAXI33P.js} +8 -8
- package/dist/{chunk-R5A64DCX.js.map → chunk-MYAXI33P.js.map} +1 -1
- package/dist/{chunk-4NTMIU6V.js → chunk-NDROQRDB.js} +6 -6
- package/dist/{chunk-4NTMIU6V.js.map → chunk-NDROQRDB.js.map} +1 -1
- package/dist/{chunk-4FBV5BJW.js → chunk-NJIHMZPC.js} +5 -5
- package/dist/{chunk-4FBV5BJW.js.map → chunk-NJIHMZPC.js.map} +1 -1
- package/dist/{chunk-DSRPKUQI.mjs → chunk-NQ2P7AB3.mjs} +28 -39
- package/dist/chunk-NQ2P7AB3.mjs.map +1 -0
- package/dist/chunk-QLM7RNQI.mjs +6 -0
- package/dist/{chunk-SN2O72UF.mjs.map → chunk-QLM7RNQI.mjs.map} +1 -1
- package/dist/{chunk-LZSCCJ4O.mjs → chunk-SBT4J733.mjs} +11 -5
- package/dist/chunk-SBT4J733.mjs.map +1 -0
- package/dist/{chunk-UT2CF4FC.js → chunk-SGPIGHMN.js} +4 -4
- package/dist/{chunk-UT2CF4FC.js.map → chunk-SGPIGHMN.js.map} +1 -1
- package/dist/{chunk-GN62H6EG.mjs → chunk-VTHCUHMK.mjs} +8 -8
- package/dist/{chunk-GN62H6EG.mjs.map → chunk-VTHCUHMK.mjs.map} +1 -1
- package/dist/chunk-WAAFJPNR.js +8 -0
- package/dist/{chunk-WRZQS7O4.js.map → chunk-WAAFJPNR.js.map} +1 -1
- package/dist/{chunk-EIWRPGOK.mjs → chunk-XHEXIYKY.mjs} +4 -4
- package/dist/{chunk-EIWRPGOK.mjs.map → chunk-XHEXIYKY.mjs.map} +1 -1
- package/dist/{chunk-TVCCZ7NR.js → chunk-XM67L4HL.js} +14 -14
- package/dist/{chunk-TVCCZ7NR.js.map → chunk-XM67L4HL.js.map} +1 -1
- package/dist/cli/index.js +2 -2
- package/dist/cli/index.mjs +1 -1
- package/dist/commerce/index.js +50 -50
- package/dist/commerce/index.mjs +5 -5
- package/dist/engage/index.js +8 -8
- package/dist/engage/index.mjs +5 -5
- package/dist/fleet/index.js +7 -7
- package/dist/fleet/index.mjs +3 -3
- package/dist/forms/index.js +18 -18
- package/dist/forms/index.js.map +1 -1
- package/dist/forms/index.mjs +10 -10
- package/dist/forms/index.mjs.map +1 -1
- package/dist/forms/styles.css +4 -2
- package/dist/images/index.js +10 -10
- package/dist/images/index.mjs +3 -3
- package/dist/index.js +67 -68
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +14 -15
- package/dist/index.mjs.map +1 -1
- package/dist/layout/client.js +6 -6
- package/dist/layout/client.mjs +5 -5
- package/dist/layout/index.js +7 -7
- package/dist/layout/index.mjs +5 -5
- package/dist/maps/index.d.mts +4 -2
- package/dist/maps/index.d.ts +4 -2
- package/dist/maps/index.js +4 -4
- package/dist/maps/index.js.map +1 -1
- package/dist/maps/index.mjs +2 -2
- package/dist/maps/index.mjs.map +1 -1
- package/dist/seo/client.js +4 -4
- package/dist/seo/client.mjs +3 -3
- package/dist/seo/index.js +4 -4
- package/dist/seo/index.mjs +3 -3
- package/dist/signal/index.js +11 -11
- package/dist/signal/index.mjs +2 -2
- package/dist/sync/index.js +15 -13
- package/dist/sync/index.mjs +3 -1
- package/package.json +1 -1
- package/dist/AnalyticsProvider-CD635CHQ.mjs +0 -8
- package/dist/AnalyticsProvider-WK2Z6AIN.js +0 -29
- package/dist/ChatWidget-AIOOZY6H.js +0 -17
- package/dist/ChatWidget-UAAWDBNS.mjs +0 -8
- package/dist/EngageWidget-EZ5T6H3K.mjs +0 -7
- package/dist/EngageWidget-RWVWW56C.js +0 -16
- package/dist/SitemapSync-AICU4SSV.js +0 -15
- package/dist/SitemapSync-CIZCAZXK.mjs +0 -6
- package/dist/chunk-DSRPKUQI.mjs.map +0 -1
- package/dist/chunk-EAASMIWX.js.map +0 -1
- package/dist/chunk-FMZOZQBV.mjs.map +0 -1
- package/dist/chunk-HAZN43I6.js.map +0 -1
- package/dist/chunk-I2GTT2DG.js.map +0 -1
- package/dist/chunk-LZSCCJ4O.mjs.map +0 -1
- package/dist/chunk-N2HR2E4Z.mjs.map +0 -1
- package/dist/chunk-NAVDN4AE.js.map +0 -1
- package/dist/chunk-SN2O72UF.mjs +0 -6
- package/dist/chunk-WRZQS7O4.js +0 -8
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/forms/useFormTracking.ts","../src/forms/defaultSuccessMessage.ts","../src/forms/recaptcha.ts","../src/forms/submitForm.ts","../src/forms/useForm.ts"],"names":["useRef","useEffect","useCallback"],"mappings":";;;;AAwBO,SAAS,eAAA,CAAgB;AAAA,EAC9B,MAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA,GAAU,IAAA;AAAA,EACV,KAAA,GAAQ;AACV,CAAA,EAA+C;AAC7C,EAAA,MAAM,YAAA,GAAe,OAAe,EAAE,CAAA;AACtC,EAAA,MAAM,YAAA,GAAe,OAAe,CAAC,CAAA;AACrC,EAAA,MAAM,gBAAA,GAAmB,OAAe,CAAC,CAAA;AACzC,EAAA,MAAM,YAAA,GAAe,MAAA,CAA+B,EAAE,CAAA;AACtD,EAAA,MAAM,cAAA,GAAiB,OAAe,CAAC,CAAA;AACvC,EAAA,MAAM,UAAA,GAAa,OAAe,CAAC,CAAA;AACnC,EAAA,MAAM,cAAA,GAAiB,OAAsB,IAAI,CAAA;AAGjD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,IAAA,CAAK,2CAA2C,CAAA;AACnE,MAAA;AAAA,IACF;AAGA,IAAA,YAAA,CAAa,OAAA,GAAU,OAAO,UAAA,EAAW;AACzC,IAAA,YAAA,CAAa,OAAA,GAAU,KAAK,GAAA,EAAI;AAChC,IAAA,gBAAA,CAAiB,OAAA,GAAU,KAAK,GAAA,EAAI;AAGpC,IAAA,MAAM,gBAAgB,YAAY;AAChC,MAAA,MAAM,SAAU,MAAA,CAAe,oBAAA;AAC/B,MAAA,MAAM,SAAU,MAAA,CAAe,oBAAA;AAE/B,MAAA,IAAI,CAAC,MAAA,IAAU,CAAC,MAAA,EAAQ;AACtB,QAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,KAAA,CAAM,oCAAoC,CAAA;AAC7D,QAAA;AAAA,MACF;AAEA,MAAA,IAAI;AACF,QAAA,MAAM,WAAW,MAAM,UAAA;AAAA,UACrB,GAAG,MAAM,CAAA,iCAAA,CAAA;AAAA,UACT;AAAA,YACE,MAAA,EAAQ,MAAA;AAAA,YACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,YAC9C,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,cACnB,MAAA;AAAA,cACA,WAAW,YAAA,CAAa,OAAA;AAAA,cACxB,YAAY,aAAA;AAAc,aAC3B;AAAA,WACH;AAAA,UACA,EAAE,MAAA,EAAQ,OAAA,EAAS,CAAA;AAAE,SACvB;AAEA,QAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,UAAA,MAAM,IAAI,MAAM,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,EAAA,EAAK,QAAA,CAAS,UAAU,CAAA,CAAE,CAAA;AAAA,QACnE;AAEA,QAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,IAAA,EAAK;AACjC,QAAA,cAAA,CAAe,UAAU,IAAA,CAAK,EAAA;AAC9B,QAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,GAAA,CAAI,2BAAA,EAA6B,KAAK,EAAE,CAAA;AAAA,MAC7D,SAAS,KAAA,EAAO;AACd,QAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,KAAA,CAAM,kCAAA,EAAoC,KAAK,CAAA;AAAA,MACpE;AAAA,IACF,CAAA;AAEA,IAAA,aAAA,EAAc;AAGd,IAAA,MAAM,qBAAqB,MAAM;AAC/B,MAAA,IAAI,CAAC,eAAe,OAAA,EAAS;AAE7B,MAAA,MAAM,SAAU,MAAA,CAAe,oBAAA;AAC/B,MAAA,MAAM,SAAU,MAAA,CAAe,oBAAA;AAE/B,MAAA,IAAI,CAAC,MAAA,IAAU,CAAC,MAAA,EAAQ;AAExB,MAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,MAAA,MAAM,kBAAkB,IAAA,CAAK,KAAA,CAAA,CAAO,GAAA,GAAM,gBAAA,CAAiB,WAAW,GAAI,CAAA;AAC1E,MAAA,YAAA,CAAa,OAAA,CAAQ,cAAA,CAAe,OAAO,CAAA,GAAI,eAAA;AAK/C,MAAA,WAAA;AAAA,QACE,GAAG,MAAM,CAAA,mCAAA,CAAA;AAAA,QACT;AAAA,UACE,aAAa,cAAA,CAAe,OAAA;AAAA,UAC5B,MAAM,cAAA,CAAe,OAAA;AAAA,UACrB,SAAS,UAAA,CAAW,OAAA;AAAA,UACpB,WAAW,YAAA,CAAa,OAAA;AAAA,UACxB,kBAAkB,IAAA,CAAK,KAAA,CAAA,CAAO,GAAA,GAAM,YAAA,CAAa,WAAW,GAAI;AAAA,SAClE;AAAA,QACA;AAAA,OACF;AAEA,MAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,GAAA,CAAI,6BAA6B,CAAA;AAAA,IACtD,CAAA;AAEA,IAAA,MAAA,CAAO,gBAAA,CAAiB,gBAAgB,kBAAkB,CAAA;AAE1D,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,mBAAA,CAAoB,gBAAgB,kBAAkB,CAAA;AAAA,IAC/D,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,MAAA,EAAQ,OAAA,EAAS,KAAK,CAAC,CAAA;AAG3B,EAAA,MAAM,eAAA,GAAkB,WAAA,CAAY,OAAO,IAAA,KAAiB;AAC1D,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,cAAA,CAAe,OAAA,EAAS;AAEzC,IAAA,MAAM,SAAU,MAAA,CAAe,oBAAA;AAC/B,IAAA,MAAM,SAAU,MAAA,CAAe,oBAAA;AAE/B,IAAA,IAAI,CAAC,MAAA,IAAU,CAAC,MAAA,EAAQ;AACtB,MAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,KAAA,CAAM,oCAAoC,CAAA;AAC7D,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AAGrB,IAAA,MAAM,eAAe,IAAA,CAAK,KAAA,CAAA,CAAO,GAAA,GAAM,gBAAA,CAAiB,WAAW,GAAI,CAAA;AACvE,IAAA,YAAA,CAAa,OAAA,CAAQ,cAAA,CAAe,OAAO,CAAA,GAAI,YAAA;AAG/C,IAAA,cAAA,CAAe,OAAA,GAAU,IAAA;AACzB,IAAA,UAAA,CAAW,OAAA,GAAU,IAAA,CAAK,GAAA,CAAI,UAAA,CAAW,SAAS,IAAI,CAAA;AACtD,IAAA,gBAAA,CAAiB,OAAA,GAAU,GAAA;AAG3B,IAAA,IAAI;AACF,MAAA,MAAM,WAAW,MAAM,UAAA;AAAA,QACrB,GAAG,MAAM,CAAA,gCAAA,CAAA;AAAA,QACT;AAAA,UACE,MAAA,EAAQ,MAAA;AAAA,UACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,UAC9C,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,YACnB,aAAa,cAAA,CAAe,OAAA;AAAA,YAC5B,IAAA;AAAA,YACA,SAAS,UAAA,CAAW,OAAA;AAAA,YACpB,WAAW,YAAA,CAAa;AAAA,WACzB;AAAA,SACH;AAAA,QACA,EAAE,MAAA,EAAQ,OAAA,EAAS,CAAA;AAAE,OACvB;AAEA,MAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,QAAA,MAAM,IAAI,MAAM,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,EAAA,EAAK,QAAA,CAAS,UAAU,CAAA,CAAE,CAAA;AAAA,MACnE;AAEA,MAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,GAAA,CAAI,0BAAA,EAA4B,IAAI,CAAA;AAAA,IACzD,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,KAAA,CAAM,8BAAA,EAAgC,KAAK,CAAA;AAAA,IAChE;AAAA,EACF,CAAA,EAAG,CAAC,OAAA,EAAS,KAAK,CAAC,CAAA;AAGnB,EAAA,MAAM,aAAA,GAAgB,YAAY,YAAY;AAC5C,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,cAAA,CAAe,OAAA,EAAS;AAEzC,IAAA,MAAM,SAAU,MAAA,CAAe,oBAAA;AAC/B,IAAA,MAAM,SAAU,MAAA,CAAe,oBAAA;AAE/B,IAAA,IAAI,CAAC,MAAA,IAAU,CAAC,MAAA,EAAQ;AACtB,MAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,KAAA,CAAM,oCAAoC,CAAA;AAC7D,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AAGrB,IAAA,MAAM,gBAAgB,IAAA,CAAK,KAAA,CAAA,CAAO,GAAA,GAAM,gBAAA,CAAiB,WAAW,GAAI,CAAA;AACxE,IAAA,YAAA,CAAa,OAAA,CAAQ,cAAA,CAAe,OAAO,CAAA,GAAI,aAAA;AAE/C,IAAA,IAAI;AAIF,MAAA,MAAM,WAAW,MAAM,UAAA;AAAA,QACrB,GAAG,MAAM,CAAA,oCAAA,CAAA;AAAA,QACT;AAAA,UACE,MAAA,EAAQ,MAAA;AAAA,UACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,UAC9C,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,YACnB,aAAa,cAAA,CAAe,OAAA;AAAA,YAC5B,UAAA;AAAA,YACA,WAAW,YAAA,CAAa,OAAA;AAAA,YACxB,kBAAkB,IAAA,CAAK,KAAA,CAAA,CAAO,GAAA,GAAM,YAAA,CAAa,WAAW,GAAI;AAAA,WACjE;AAAA,SACH;AAAA,QACA,EAAE,MAAA,EAAQ,OAAA,EAAS,CAAA;AAAE,OACvB;AAEA,MAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,QAAA,MAAM,IAAI,MAAM,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,EAAA,EAAK,QAAA,CAAS,UAAU,CAAA,CAAE,CAAA;AAAA,MACnE;AAEA,MAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,GAAA,CAAI,8CAA8C,CAAA;AAGrE,MAAA,IAAI;AACF,QAAA,MAAM,UAAA;AAAA,UACJ,GAAG,MAAM,CAAA,gCAAA,CAAA;AAAA,UACT;AAAA,YACE,MAAA,EAAQ,MAAA;AAAA,YACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,YAC9C,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,cACnB,WAAW,YAAA,CAAa,OAAA;AAAA,cACxB,cAAA,EAAgB,iBAAA;AAAA,cAChB,QAAA,EAAU,EAAE,MAAA,EAAQ,WAAA,EAAa,eAAe,OAAA,EAAQ;AAAA,cACxD,UAAU,OAAO,MAAA,KAAW,WAAA,GAAc,MAAA,CAAO,SAAS,QAAA,GAAW,GAAA;AAAA,cACrE,UAAU,OAAO,QAAA,KAAa,WAAA,GAAc,QAAA,CAAS,YAAY,IAAA,GAAO,IAAA;AAAA,cACxE,YAAY,aAAA;AAAc,aAC3B;AAAA,WACH;AAAA,UACA,EAAE,MAAA,EAAQ,OAAA,EAAS,CAAA;AAAE,SACvB;AAAA,MACF,SAAS,OAAA,EAAS;AAChB,QAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,KAAA,CAAM,qCAAA,EAAuC,OAAO,CAAA;AAAA,MACzE;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,KAAA,CAAM,oCAAA,EAAsC,KAAK,CAAA;AAAA,IACtE;AAAA,EACF,GAAG,CAAC,OAAA,EAAS,UAAA,EAAY,MAAA,EAAQ,KAAK,CAAC,CAAA;AAEvC,EAAA,OAAO;AAAA,IACL,eAAA;AAAA,IACA,aAAA;AAAA,IACA,WAAW,YAAA,CAAa;AAAA,GAC1B;AACF;AAGA,SAAS,aAAA,GAAiD;AACxD,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,SAAA;AAC1C,EAAA,MAAM,KAAK,SAAA,CAAU,SAAA;AACrB,EAAA,IAAI,4BAAA,CAA6B,IAAA,CAAK,EAAE,CAAA,EAAG,OAAO,QAAA;AAClD,EAAA,IAAI,4DAAA,CAA6D,IAAA,CAAK,EAAE,CAAA,EAAG,OAAO,QAAA;AAClF,EAAA,OAAO,SAAA;AACT;;;ACpQO,IAAM,4BAAA,GACX;;;ACMF,SAAS,WAAW,eAAA,EAA8C;AAChE,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,MAAA;AAC1C,EAAA,IAAI,iBAAiB,OAAO,eAAA;AAC5B,EAAA,MAAM,GAAA,GAAM,MAAA;AACZ,EAAA,OAAO,GAAA,CAAI,+BAAA,IAAmC,OAAA,CAAQ,GAAA,CAAI,8BAAA;AAC5D;AAGA,IAAM,yBAAA,GAA4B,GAAA;AAElC,SAAS,WAAW,OAAA,EAA+B;AACjD,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC9B,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,MAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,MAAA;AAAA,IACF;AACA,IAAA,MAAM,GAAA,GAAM,MAAA;AACZ,IAAA,IAAI,GAAA,CAAI,YAAY,UAAA,EAAY;AAC9B,MAAA,OAAA,CAAQ,IAAI,UAAU,CAAA;AACtB,MAAA;AAAA,IACF;AAKA,IAAA,IAAI,OAAA,GAAU,KAAA;AACd,IAAA,MAAM,MAAA,GAAS,CAAC,KAAA,KAAe;AAC7B,MAAA,IAAI,OAAA,EAAS;AACb,MAAA,OAAA,GAAU,IAAA;AACV,MAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,IACf,CAAA;AACA,IAAA,MAAM,SAAS,UAAA,CAAW,MAAM,MAAA,CAAO,IAAI,GAAG,yBAAyB,CAAA;AAEvE,IAAA,MAAM,eAAe,MAAM;AACzB,MAAA,IAAI,OAAA,EAAS;AACb,MAAA,IAAI,GAAA,CAAI,YAAY,UAAA,EAAY;AAC9B,QAAA,YAAA,CAAa,MAAM,CAAA;AACnB,QAAA,MAAA,CAAO,IAAI,UAAU,CAAA;AACrB,QAAA;AAAA,MACF;AACA,MAAA,UAAA,CAAW,cAAc,EAAE,CAAA;AAAA,IAC7B,CAAA;AAEA,IAAA,MAAM,QAAA,GAAW,QAAA,CAAS,aAAA,CAAc,qCAAqC,CAAA;AAC7E,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,YAAA,EAAa;AACb,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC9C,IAAA,MAAA,CAAO,GAAA,GAAM,yDAAyD,OAAO,CAAA,CAAA;AAC7E,IAAA,MAAA,CAAO,KAAA,GAAQ,IAAA;AACf,IAAA,MAAA,CAAO,MAAA,GAAS,MAAM,YAAA,EAAa;AACnC,IAAA,MAAA,CAAO,UAAU,MAAM;AACrB,MAAA,YAAA,CAAa,MAAM,CAAA;AACnB,MAAA,MAAA,CAAO,IAAI,CAAA;AAAA,IACb,CAAA;AACA,IAAA,QAAA,CAAS,IAAA,CAAK,YAAY,MAAM,CAAA;AAAA,EAClC,CAAC,CAAA;AACH;AAMA,eAAsB,kBAAkB,eAAA,EAAkD;AACxF,EAAA,MAAM,OAAA,GAAU,WAAW,eAAe,CAAA;AAC1C,EAAA,IAAI,CAAC,OAAA,IAAW,OAAO,MAAA,KAAW,aAAa,OAAO,IAAA;AACtD,EAAA,IAAI;AACF,IAAA,MAAM,UAAA,GAAa,MAAM,UAAA,CAAW,OAAO,CAAA;AAC3C,IAAA,IAAI,CAAC,UAAA,EAAY,UAAA,EAAY,OAAA,EAAS,OAAO,IAAA;AAC7C,IAAA,MAAM,KAAA,GAAQ,MAAM,UAAA,CAAW,UAAA,CAAW,QAAQ,OAAA,EAAS,EAAE,MAAA,EAAQ,QAAA,EAAU,CAAA;AAC/E,IAAA,OAAO,KAAA,IAAS,IAAA;AAAA,EAClB,SAAS,GAAA,EAAK;AACZ,IAAA,OAAA,CAAQ,IAAA,CAAK,wBAAwB,GAAG,CAAA;AACxC,IAAA,OAAO,IAAA;AAAA,EACT;AACF;;;AClEA,SAAS,YAAA,GAA+D;AACtE,EAAA,MAAM,SACJ,OAAO,MAAA,KAAW,WAAA,GACb,MAAA,CAAe,wBAAwB,sBAAA,GACxC,sBAAA;AACN,EAAA,MAAM,MAAA,GACJ,OAAO,MAAA,KAAW,WAAA,GAAe,OAAe,oBAAA,GAAuB,MAAA;AACzE,EAAA,OAAO,EAAE,QAAQ,MAAA,EAAO;AAC1B;AAEA,SAAS,YAAA,GAA8C;AACrD,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,EAAC;AAC3C,EAAA,MAAM,MAAA,GAAS,IAAI,eAAA,CAAgB,MAAA,CAAO,SAAS,MAAM,CAAA;AACzD,EAAA,MAAM,MAAqC,EAAC;AAC5C,EAAA,KAAA,MAAW,OAAO,CAAC,YAAA,EAAc,cAAc,cAAA,EAAgB,UAAA,EAAY,aAAa,CAAA,EAAG;AACzF,IAAA,GAAA,CAAI,GAAG,CAAA,GAAI,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA;AAAA,EAC3B;AACA,EAAA,OAAO,GAAA;AACT;AAoBA,eAAsB,UAAA,CAAW;AAAA,EAC/B,MAAA;AAAA,EACA,MAAA;AAAA,EACA,aAAA;AAAA,EACA;AACF,CAAA,EAAqC;AACnC,EAAA,MAAM,EAAE,MAAA,EAAQ,MAAA,EAAO,GAAI,YAAA,EAAa;AACxC,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAM,IAAI,MAAM,6DAA6D,CAAA;AAAA,EAC/E;AAGA,EAAA,MAAM,iBAAiB,MAAA,CAAO,iBAAA,GAC1B,MAAM,iBAAA,CAAkB,MAAA,CAAO,kBAAkB,CAAA,GACjD,IAAA;AACJ,EAAA,IAAI,MAAA,CAAO,iBAAA,IAAqB,CAAC,cAAA,EAAgB;AAC/C,IAAA,MAAM,IAAI,MAAM,wDAAwD,CAAA;AAAA,EAC1E;AAEA,EAAA,MAAM,iBAAA,GAAoB,OAAO,cAAA,IAAkB,sBAAA;AACnD,EAAA,MAAM,MAAM,YAAA,EAAa;AAEzB,EAAA,MAAM,OAAA,GAAU;AAAA,IACd,QAAQ,MAAA,CAAO,EAAA;AAAA,IACf,SAAS,MAAA,CAAO,EAAA;AAAA,IAChB,IAAA,EAAM;AAAA,MACJ,GAAG,MAAA;AAAA,MACH,GAAI,OAAO,gBAAA,GAAmB,EAAE,CAAC,iBAAiB,GAAG,aAAA,EAAc,GAAI;AAAC,KAC1E;AAAA,IACA,QAAA,EAAU;AAAA,MACR,SAAS,OAAO,MAAA,KAAW,WAAA,GAAc,MAAA,CAAO,SAAS,IAAA,GAAO,IAAA;AAAA,MAChE,UAAU,OAAO,QAAA,KAAa,WAAA,GAAc,QAAA,CAAS,YAAY,IAAA,GAAO,IAAA;AAAA,MACxE,SAAA,EAAW,OAAO,SAAA,KAAc,WAAA,GAAc,UAAU,SAAA,GAAY,IAAA;AAAA,MACpE,WACE,OAAO,cAAA,KAAmB,cAAc,cAAA,CAAe,OAAA,CAAQ,SAAS,CAAA,GAAI,IAAA;AAAA;AAAA;AAAA;AAAA,MAI9E,WACE,OAAO,YAAA,KAAiB,cAAc,YAAA,CAAa,OAAA,CAAQ,SAAS,CAAA,GAAI,IAAA;AAAA,MAC1E,gBAAgB,cAAA,IAAkB,MAAA;AAAA,MAClC,WAAW,GAAA,CAAI,UAAA;AAAA,MACf,WAAW,GAAA,CAAI,UAAA;AAAA,MACf,aAAa,GAAA,CAAI,YAAA;AAAA;AAAA;AAAA,MAGjB,IAAA,EACE,OAAO,MAAA,KAAW,WAAA,GACb,OAA0C,iBAAA,IAC3C,MAAA,CAAO,SAAS,IAAA,GAChB,MAAA;AAAA,MACN,aAAA,EAAe;AAAA;AACjB,GACF;AAEA,EAAA,MAAM,WAAW,MAAM,UAAA;AAAA,IACrB,GAAG,MAAM,CAAA,wBAAA,CAAA;AAAA,IACT;AAAA,MACE,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,kBAAA;AAAA,QAChB,aAAA,EAAe,UAAU,MAAM,CAAA;AAAA,OACjC;AAAA,MACA,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,OAAO;AAAA,KAC9B;AAAA,IACA,EAAE,OAAA,EAAS,CAAA,EAAG,SAAA,EAAW,GAAA;AAAM,GACjC;AAEA,EAAA,MAAM,OAAO,MAAM,QAAA,CAAS,MAAK,CAAE,KAAA,CAAM,MAAM,IAAI,CAAA;AAEnD,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,GAAA,GAAA,CACJ,IAAA,EAAM,OAAA,IACN,IAAA,EAAM,KAAA,KACL,QAAA,CAAS,UAAA,IAAc,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,CAAA,CAAA,EAE9C,QAAA,GACA,IAAA,EAAK;AACR,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,MAAM,CAAA,uBAAA,EAA0B,GAAG,CAAA,CAAA,GAAK,CAAA,uBAAA,EAA0B,SAAS,MAAM,CAAA,CAAA;AAAA,KACnF;AAAA,EACF;AAEA,EAAA,OAAO,IAAA;AACT;;;ACrBO,SAAS,OAAA,CACd,YAAA,EACA,OAAA,GAA0B,EAAC,EACZ;AACf,EAAA,MAAM;AAAA,IACJ,SAAA,EAAW,gBAAA;AAAA,IACX,SAAA;AAAA,IACA,OAAA;AAAA,IACA,gBAAgB,EAAC;AAAA,IACjB;AAAA,GACF,GAAI,OAAA;AAGJ,EAAA,MAAM,YAAY,gBAAA,KACf,OAAO,MAAA,KAAW,WAAA,GAAe,OAAe,uBAAA,GAA0B,MAAA,CAAA;AAG7E,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAAmC,IAAI,CAAA;AAC/D,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,IAAI,CAAA;AAC/C,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,SAAuB,IAAI,CAAA;AAC/D,EAAA,MAAM,CAAC,MAAA,EAAQ,cAAc,CAAA,GAAI,SAAkC,aAAa,CAAA;AAChF,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,QAAA,CAAiC,EAAE,CAAA;AAC/D,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAAS,CAAC,CAAA;AAClC,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,SAAS,KAAK,CAAA;AACtD,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,SAAS,KAAK,CAAA;AAClD,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAAwB,IAAI,CAAA;AAGlE,EAAA,MAAM,eAAA,GAAkBA,OAAO,KAAK,CAAA;AACpC,EAAA,MAAM,YAAA,GAAeA,MAAAA,CAAO,IAAA,CAAK,GAAA,EAAK,CAAA;AAEtC,EAAA,MAAM,UAAA,GAAa,MAAM,WAAA,IAAe,CAAA;AACxC,EAAA,MAAM,WAAA,GAAe,MAAM,aAAA,IAAkB,KAAA;AAE7C,EAAA,MAAM,EAAE,eAAA,EAAiB,aAAA,EAAc,GAAI,eAAA,CAAgB;AAAA,IACzD,MAAA,EAAQ,MAAM,EAAA,IAAM,EAAA;AAAA,IACpB;AAAA,GACD,CAAA;AAGD,EAAAC,UAAU,MAAM;AACd,IAAA,MAAM,SAAS,OAAO,MAAA,KAAW,WAAA,GAC5B,MAAA,CAAe,wBAAwB,sBAAA,GACxC,sBAAA;AAEJ,IAAA,eAAe,SAAA,GAAY;AACzB,MAAA,IAAI;AACF,QAAA,YAAA,CAAa,IAAI,CAAA;AACjB,QAAA,aAAA,CAAc,IAAI,CAAA;AAKlB,QAAA,MAAM,aAAa,MACjB,OAAO,MAAA,KAAW,WAAA,GAAe,OAAe,oBAAA,GAAuB,KAAA,CAAA;AACzE,QAAA,IAAI,SAAS,UAAA,EAAW;AACxB,QAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,EAAA,IAAM,CAAC,QAAQ,CAAA,EAAA,EAAK;AACtC,UAAA,MAAM,IAAI,OAAA,CAAQ,CAAC,MAAM,UAAA,CAAW,CAAA,EAAG,GAAG,CAAC,CAAA;AAC3C,UAAA,MAAA,GAAS,UAAA,EAAW;AAAA,QACtB;AACA,QAAA,IAAI,CAAC,MAAA,EAAQ;AACX,UAAA,MAAM,IAAI,MAAM,yFAAyF,CAAA;AAAA,QAC3G;AAEA,QAAA,MAAM,GAAA,GAAM,GAAG,MAAM,CAAA,wBAAA,CAAA;AACrB,QAAA,MAAM,IAAA,GAAoB;AAAA,UACxB,MAAA,EAAQ,MAAA;AAAA,UACR,OAAA,EAAS;AAAA,YACP,cAAA,EAAgB;AAAA,WAClB;AAAA,UACA,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,YACnB;AAAA,WACD;AAAA,SACH;AAQA,QAAA,MAAM,QAAA,GAAW,MAAM,UAAA,CAAW,GAAA,EAAK,IAAA,EAAM,EAAE,MAAA,EAAQ,OAAA,EAAS,CAAA,EAAG,SAAA,EAAW,IAAA,EAAO,CAAA;AAErF,QAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,UAAA,MAAM,IAAI,KAAA,CAAM,CAAA,sBAAA,EAAyB,QAAA,CAAS,UAAU,CAAA,CAAE,CAAA;AAAA,QAChE;AAEA,QAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,IAAA,EAAK;AACjC,QAAA,IAAI,CAAC,IAAA,EAAM,MAAM,IAAI,MAAM,gBAAgB,CAAA;AAE7C,QAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,IAAA,CAAK,kBAAA,EAAoB;AAC5D,UAAA;AAAC,UAAC,MAAA,CAAe,kCAAkC,IAAA,CAAK,kBAAA;AAAA,QAC1D;AAGE,QAAA,IAAI,KAAK,KAAA,EAAO;AACd,UAAA,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,EAAQ,CAAA,KAAA,CAAY,EAAE,WAAA,IAAe,CAAA,KAAM,CAAA,CAAE,WAAA,IAAe,CAAA,CAAE,CAAA;AAAA,QACjF;AACA,QAAA,IAAI,KAAK,MAAA,EAAQ;AACf,UAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,EAAQ,CAAA,KAAA,CAAY,EAAE,UAAA,IAAc,CAAA,KAAM,CAAA,CAAE,UAAA,IAAc,CAAA,CAAE,CAAA;AAAA,QAChF;AAGA,QAAA,MAAM,WAAA,GAAc,IAAA,CAAK,KAAA,EAAO,MAAA,IAAU,CAAA;AAC1C,QAAA,MAAM,gBAAgB,WAAA,GAAc,CAAA;AAEpC,QAAA,MAAM,UAAA,GACJ,OAAO,IAAA,CAAK,eAAA,KAAoB,WAAW,IAAA,CAAK,eAAA,CAAgB,MAAK,GAAI,EAAA;AAC3E,QAAA,MAAM,eAAA,GACJ,UAAA,KACC,OAAQ,IAAA,CAAqC,cAAA,KAAmB,QAAA,GAC7D,MAAA,CAAQ,IAAA,CAAqC,cAAc,CAAA,CAAE,IAAA,EAAK,GAClE,EAAA,CAAA,IACJ,4BAAA;AAEF,QAAA,OAAA,CAAQ;AAAA,UACN,GAAG,IAAA;AAAA,UACH,eAAA;AAAA,UACA,WAAA;AAAA,UACA;AAAA,SACD,CAAA;AAGD,QAAA,MAAM,WAAoC,EAAC;AAC3C,QAAA,KAAA,MAAW,KAAA,IAAS,IAAA,CAAK,MAAA,IAAU,EAAC,EAAG;AACrC,UAAA,IAAI,KAAA,CAAM,aAAA,KAAkB,KAAA,CAAA,IAAa,KAAA,CAAM,kBAAkB,IAAA,EAAM;AACrE,YAAA,QAAA,CAAS,KAAA,CAAM,IAAI,CAAA,GAAI,KAAA,CAAM,aAAA;AAAA,UAC/B;AAAA,QACF;AACA,QAAA,cAAA,CAAe,EAAE,GAAG,QAAA,EAAU,GAAG,eAAe,CAAA;AAAA,MAElD,SAAS,GAAA,EAAK;AACZ,QAAA,aAAA,CAAc,GAAY,CAAA;AAAA,MAC5B,CAAA,SAAE;AACA,QAAA,YAAA,CAAa,KAAK,CAAA;AAAA,MACpB;AAAA,IACF;AAEA,IAAA,SAAA,EAAU;AAAA,EACZ,CAAA,EAAG,CAAC,YAAA,EAAc,SAAS,CAAC,CAAA;AAG5B,EAAA,MAAM,SAAA,GAAY,QAAQ,MAAM,IAAA,EAAM,UAAU,EAAC,EAAG,CAAC,IAAI,CAAC,CAAA;AAG1D,EAAA,MAAM,MAAA,GAAS,QAAQ,MAAM;AAC3B,IAAA,IAAI,CAAC,aAAa,OAAO,SAAA;AAEzB,IAAA,MAAM,oBAAoB,IAAA,EAAM,KAAA,EAAO,KAAK,CAAA,CAAA,KAAK,CAAA,CAAE,gBAAgB,IAAI,CAAA;AACvE,IAAA,IAAI,CAAC,mBAAmB,OAAO,SAAA;AAE/B,IAAA,OAAO,UAAU,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,OAAA,KAAY,kBAAkB,EAAE,CAAA;AAAA,EACjE,GAAG,CAAC,IAAA,EAAM,IAAA,EAAM,SAAA,EAAW,WAAW,CAAC,CAAA;AAGvC,EAAA,MAAM,cAAA,GAAiBC,WAAAA,CAAY,CAAC,KAAA,KAA8B;AAChE,IAAA,IAAI,CAAC,KAAA,CAAM,WAAA,EAAa,SAAA,EAAW,OAAO,IAAA;AAE1C,IAAA,MAAM,EAAE,KAAA,EAAO,SAAA,EAAW,UAAU,KAAA,EAAM,GAAI,MAAM,WAAA,CAAY,SAAA;AAChE,IAAA,MAAM,UAAA,GAAa,OAAO,SAAS,CAAA;AAEnC,IAAA,QAAQ,QAAA;AAAU,MAChB,KAAK,QAAA;AACH,QAAA,OAAO,UAAA,KAAe,KAAA;AAAA,MACxB,KAAK,YAAA;AACH,QAAA,OAAO,UAAA,KAAe,KAAA;AAAA,MACxB,KAAK,UAAA;AACH,QAAA,OAAO,OAAO,UAAA,IAAc,EAAE,EAAE,QAAA,CAAS,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,MACxD,KAAK,cAAA;AACH,QAAA,OAAO,CAAC,OAAO,UAAA,IAAc,EAAE,EAAE,QAAA,CAAS,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,MACzD,KAAK,UAAA;AACH,QAAA,OAAO,CAAC,cAAc,UAAA,KAAe,EAAA;AAAA,MACvC,KAAK,WAAA;AACH,QAAA,OAAO,CAAC,CAAC,UAAA,IAAc,UAAA,KAAe,EAAA;AAAA,MACxC,KAAK,cAAA;AACH,QAAA,OAAO,MAAA,CAAO,UAAU,CAAA,GAAI,MAAA,CAAO,KAAK,CAAA;AAAA,MAC1C,KAAK,WAAA;AACH,QAAA,OAAO,MAAA,CAAO,UAAU,CAAA,GAAI,MAAA,CAAO,KAAK,CAAA;AAAA,MAC1C;AACE,QAAA,OAAO,IAAA;AAAA;AACX,EACF,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAGX,EAAA,MAAM,aAAA,GAAgB,QAAQ,MAAM;AAClC,IAAA,OAAO,MAAA,CAAO,OAAO,cAAc,CAAA;AAAA,EACrC,CAAA,EAAG,CAAC,MAAA,EAAQ,cAAc,CAAC,CAAA;AAG3B,EAAA,MAAM,aAAA,GAAgBA,WAAAA,CAAY,CAAC,KAAA,KAAoC;AACrE,IAAA,IAAI,CAAC,cAAA,CAAe,KAAK,CAAA,EAAG,OAAO,IAAA;AAEnC,IAAA,IAAI,CAAC,SAAA,EAAW,gBAAA,EAAkB,WAAA,EAAa,QAAQ,EAAE,QAAA,CAAS,KAAA,CAAM,UAAU,CAAA,EAAG,OAAO,IAAA;AAE5F,IAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA;AAC/B,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,UAAA,IAAc,EAAC;AAGnC,IAAA,IAAI,KAAA,CAAM,WAAA,KAAgB,CAAC,KAAA,IAAS,UAAU,EAAA,CAAA,EAAK;AACjD,MAAA,OAAO,KAAA,CAAM,YAAA,IAAgB,CAAA,EAAG,KAAA,CAAM,KAAK,CAAA,YAAA,CAAA;AAAA,IAC7C;AAEA,IAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AAEnB,IAAA,MAAM,QAAA,GAAW,OAAO,KAAK,CAAA;AAG7B,IAAA,IAAI,KAAA,CAAM,UAAA,IAAc,QAAA,CAAS,MAAA,GAAS,MAAM,UAAA,EAAY;AAC1D,MAAA,OAAO,CAAA,EAAG,KAAA,CAAM,KAAK,CAAA,kBAAA,EAAqB,MAAM,UAAU,CAAA,WAAA,CAAA;AAAA,IAC5D;AACA,IAAA,IAAI,KAAA,CAAM,UAAA,IAAc,QAAA,CAAS,MAAA,GAAS,MAAM,UAAA,EAAY;AAC1D,MAAA,OAAO,CAAA,EAAG,KAAA,CAAM,KAAK,CAAA,sBAAA,EAAyB,MAAM,UAAU,CAAA,WAAA,CAAA;AAAA,IAChE;AAGA,IAAA,IAAI,MAAM,GAAA,KAAQ,MAAA,IAAa,OAAO,KAAK,CAAA,GAAI,MAAM,GAAA,EAAK;AACxD,MAAA,OAAO,CAAA,EAAG,KAAA,CAAM,KAAK,CAAA,kBAAA,EAAqB,MAAM,GAAG,CAAA,CAAA;AAAA,IACrD;AACA,IAAA,IAAI,MAAM,GAAA,KAAQ,MAAA,IAAa,OAAO,KAAK,CAAA,GAAI,MAAM,GAAA,EAAK;AACxD,MAAA,OAAO,CAAA,EAAG,KAAA,CAAM,KAAK,CAAA,sBAAA,EAAyB,MAAM,GAAG,CAAA,CAAA;AAAA,IACzD;AAGA,IAAA,IAAI,MAAM,OAAA,EAAS;AACjB,MAAA,IAAI;AACF,QAAA,IAAI,CAAC,IAAI,MAAA,CAAO,KAAA,CAAM,OAAO,CAAA,CAAE,IAAA,CAAK,QAAQ,CAAA,EAAG;AAC7C,UAAA,OAAO,KAAA,CAAM,YAAA,IAAgB,CAAA,EAAG,KAAA,CAAM,KAAK,CAAA,WAAA,CAAA;AAAA,QAC7C;AAAA,MACF,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAGA,IAAA,IAAI,MAAM,UAAA,KAAe,OAAA,IAAW,CAAC,4BAAA,CAA6B,IAAA,CAAK,QAAQ,CAAA,EAAG;AAChF,MAAA,OAAO,oCAAA;AAAA,IACT;AAGA,IAAA,IAAI,MAAM,UAAA,KAAe,OAAA,IAAW,CAAC,mBAAA,CAAoB,IAAA,CAAK,QAAQ,CAAA,EAAG;AACvE,MAAA,OAAO,mCAAA;AAAA,IACT;AAEA,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,EAAG,CAAC,MAAA,EAAQ,cAAc,CAAC,CAAA;AAG3B,EAAA,MAAM,QAAA,GAAWA,YAAY,MAAe;AAC1C,IAAA,MAAM,YAAoC,EAAC;AAE3C,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,MAAM,KAAA,GAAQ,cAAc,KAAK,CAAA;AACjC,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,SAAA,CAAU,KAAA,CAAM,IAAI,CAAA,GAAI,KAAA;AAAA,MAC1B;AAAA,IACF;AAEA,IAAA,SAAA,CAAU,SAAS,CAAA;AACnB,IAAA,OAAO,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA,CAAE,MAAA,KAAW,CAAA;AAAA,EAC3C,CAAA,EAAG,CAAC,MAAA,EAAQ,aAAa,CAAC,CAAA;AAI1B,EAAA,MAAM,WAAA,GAAcA,YAAY,MAAe;AAC7C,IAAA,MAAM,YAAoC,EAAC;AAC3C,IAAA,KAAA,MAAW,SAAS,SAAA,EAAW;AAC7B,MAAA,MAAM,KAAA,GAAQ,cAAc,KAAK,CAAA;AACjC,MAAA,IAAI,KAAA,EAAO,SAAA,CAAU,KAAA,CAAM,IAAI,CAAA,GAAI,KAAA;AAAA,IACrC;AACA,IAAA,SAAA,CAAU,SAAS,CAAA;AACnB,IAAA,OAAO,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA,CAAE,MAAA,KAAW,CAAA;AAAA,EAC3C,CAAA,EAAG,CAAC,SAAA,EAAW,aAAa,CAAC,CAAA;AAG7B,EAAA,MAAM,kBAAA,GAAqBA,YAAY,MAA+B;AACpE,IAAA,MAAM,MAA+B,EAAC;AACtC,IAAA,KAAA,MAAW,SAAS,SAAA,EAAW;AAC7B,MAAA,IAAI,CAAC,cAAA,CAAe,KAAK,CAAA,EAAG;AAC5B,MAAA,IAAI,KAAA,CAAM,QAAQ,MAAA,EAAQ,GAAA,CAAI,MAAM,IAAI,CAAA,GAAI,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA;AAAA,IAC/D;AACA,IAAA,OAAO,GAAA;AAAA,EACT,CAAA,EAAG,CAAC,SAAA,EAAW,MAAA,EAAQ,cAAc,CAAC,CAAA;AAGtC,EAAA,MAAM,aAAA,GAAgBA,WAAAA,CAAY,CAAC,GAAA,EAAa,KAAA,KAAmB;AACjE,IAAA,cAAA,CAAe,CAAA,IAAA,MAAS,EAAE,GAAG,IAAA,EAAM,CAAC,GAAG,GAAG,OAAM,CAAE,CAAA;AAElD,IAAA,SAAA,CAAU,CAAA,IAAA,KAAQ;AAChB,MAAA,IAAI,IAAA,CAAK,GAAG,CAAA,EAAG;AACb,QAAA,MAAM,IAAA,GAAO,EAAE,GAAG,IAAA,EAAK;AACvB,QAAA,OAAO,KAAK,GAAG,CAAA;AACf,QAAA,OAAO,IAAA;AAAA,MACT;AACA,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH,CAAA,EAAG,EAAE,CAAA;AAGL,EAAA,MAAM,SAAA,GAAYA,WAAAA,CAAY,CAAC,SAAA,KAAuC;AACpE,IAAA,cAAA,CAAe,WAAS,EAAE,GAAG,IAAA,EAAM,GAAG,WAAU,CAAE,CAAA;AAAA,EACpD,CAAA,EAAG,EAAE,CAAA;AAGL,EAAA,MAAM,WAAA,GAAcA,YAAY,MAAM;AACpC,IAAA,SAAA,CAAU,EAAE,CAAA;AAAA,EACd,CAAA,EAAG,EAAE,CAAA;AAGL,EAAA,MAAM,YAAY,IAAA,GAAO,UAAA;AACzB,EAAA,MAAM,YAAY,IAAA,GAAO,CAAA;AACzB,EAAA,MAAM,aAAa,IAAA,KAAS,UAAA;AAC5B,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAO,IAAA,GAAO,aAAc,GAAG,CAAA;AAErD,EAAA,MAAM,QAAA,GAAWA,YAAY,MAAe;AAC1C,IAAA,IAAI,CAAC,QAAA,EAAS,EAAG,OAAO,KAAA;AAExB,IAAA,IAAI,OAAO,UAAA,EAAY;AACrB,MAAA,MAAM,UAAU,IAAA,GAAO,CAAA;AACvB,MAAA,OAAA,CAAQ,OAAO,CAAA;AACf,MAAA,eAAA,CAAgB,OAAO,CAAA;AACvB,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,OAAO,KAAA;AAAA,EACT,GAAG,CAAC,IAAA,EAAM,UAAA,EAAY,QAAA,EAAU,eAAe,CAAC,CAAA;AAEhD,EAAA,MAAM,QAAA,GAAWA,YAAY,MAAM;AACjC,IAAA,IAAI,OAAO,CAAA,EAAG;AACZ,MAAA,MAAM,UAAU,IAAA,GAAO,CAAA;AACvB,MAAA,OAAA,CAAQ,OAAO,CAAA;AACf,MAAA,eAAA,CAAgB,OAAO,CAAA;AAAA,IACzB;AAAA,EACF,CAAA,EAAG,CAAC,IAAA,EAAM,eAAe,CAAC,CAAA;AAE1B,EAAA,MAAM,QAAA,GAAWA,WAAAA,CAAY,CAAC,UAAA,KAAuB;AACnD,IAAA,IAAI,UAAA,IAAc,CAAA,IAAK,UAAA,IAAc,UAAA,EAAY;AAC/C,MAAA,OAAA,CAAQ,UAAU,CAAA;AAClB,MAAA,eAAA,CAAgB,UAAU,CAAA;AAAA,IAC5B;AAAA,EACF,CAAA,EAAG,CAAC,UAAA,EAAY,eAAe,CAAC,CAAA;AAGhC,EAAA,MAAM,MAAA,GAASA,YAAY,YAAY;AACrC,IAAA,IAAI,CAAC,IAAA,EAAM;AAEX,IAAA,IAAI,gBAAgB,OAAA,EAAS;AAC7B,IAAA,IAAI,CAAC,aAAY,EAAG;AAEpB,IAAA,eAAA,CAAgB,OAAA,GAAU,IAAA;AAC1B,IAAA,eAAA,CAAgB,IAAI,CAAA;AACpB,IAAA,cAAA,CAAe,IAAI,CAAA;AAEnB,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,MAAM,UAAA,CAAW;AAAA,QAC5B,MAAA,EAAQ,IAAA;AAAA,QACR,QAAQ,kBAAA,EAAmB;AAAA,QAC3B,aAAA,EAAe,EAAA;AAAA,QACf,cAAc,YAAA,CAAa;AAAA,OAC5B,CAAA;AAED,MAAA,aAAA,EAAc;AACd,MAAA,aAAA,CAAc,IAAI,CAAA;AAClB,MAAA,SAAA,GAAY,IAAsB,CAAA;AAElC,MAAA,MAAM,aAAA,GAAgB,WAAA,KAAgB,KAAA,GACjC,WAAA,IAAe,KAAK,YAAA,GACrB,KAAA,CAAA;AACJ,MAAA,IAAI,aAAA,EAAe;AACjB,QAAA,MAAA,CAAO,SAAS,IAAA,GAAO,aAAA;AAAA,MACzB;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,+BAA+B,KAAK,CAAA;AAClD,MAAA,cAAA,CAAe,iEAAiE,CAAA;AAChF,MAAA,OAAA,GAAU,KAAc,CAAA;AAAA,IAC1B,CAAA,SAAE;AACA,MAAA,eAAA,CAAgB,OAAA,GAAU,KAAA;AAC1B,MAAA,eAAA,CAAgB,KAAK,CAAA;AAAA,IACvB;AAAA,EACF,CAAA,EAAG,CAAC,IAAA,EAAM,WAAA,EAAa,oBAAoB,aAAA,EAAe,SAAA,EAAW,OAAA,EAAS,WAAW,CAAC,CAAA;AAG1F,EAAA,MAAM,KAAA,GAAQA,YAAY,MAAM;AAC9B,IAAA,cAAA,CAAe,aAAa,CAAA;AAC5B,IAAA,SAAA,CAAU,EAAE,CAAA;AACZ,IAAA,OAAA,CAAQ,CAAC,CAAA;AACT,IAAA,aAAA,CAAc,KAAK,CAAA;AACnB,IAAA,cAAA,CAAe,IAAI,CAAA;AAAA,EACrB,CAAA,EAAG,CAAC,aAAa,CAAC,CAAA;AAElB,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAA;AAAA,IACA,WAAA;AAAA,IAEA,SAAA;AAAA,IACA,MAAA;AAAA,IACA,aAAA;AAAA,IAEA,MAAA;AAAA,IACA,MAAA;AAAA,IACA,aAAA;AAAA,IACA,SAAA;AAAA,IACA,WAAA;AAAA,IAEA,IAAA;AAAA,IACA,UAAA;AAAA,IACA,WAAA;AAAA,IACA,QAAA;AAAA,IAEA,QAAA;AAAA,IACA,QAAA;AAAA,IACA,QAAA;AAAA,IACA,SAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAA;AAAA,IAEA,QAAA;AAAA,IACA,aAAA;AAAA,IACA,cAAA;AAAA,IAEA,MAAA;AAAA,IACA,YAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF;AACF","file":"chunk-7R7SGJG3.mjs","sourcesContent":["/**\n * @sonordev/site-kit/forms - Form Tracking Hook\n * \n * Tracks form analytics including step progress and abandonment\n */\n\n'use client'\n\nimport { useEffect, useRef, useCallback } from 'react'\nimport { sonorFetch, sonorBeacon } from '../shared/sonorFetch'\n\ninterface UseFormTrackingOptions {\n formId: string\n totalSteps: number\n enabled?: boolean\n debug?: boolean\n}\n\ninterface FormTrackingReturn {\n trackStepChange: (step: number) => void\n trackComplete: () => void\n sessionId: string\n}\n\nexport function useFormTracking({\n formId,\n totalSteps,\n enabled = true,\n debug = false,\n}: UseFormTrackingOptions): FormTrackingReturn {\n const sessionIdRef = useRef<string>('')\n const startTimeRef = useRef<number>(0)\n const stepStartTimeRef = useRef<number>(0)\n const stepTimesRef = useRef<Record<number, number>>({})\n const currentStepRef = useRef<number>(1)\n const maxStepRef = useRef<number>(1)\n const analyticsIdRef = useRef<string | null>(null)\n \n // Initialize tracking\n useEffect(() => {\n if (!enabled) return\n if (!formId) {\n if (debug) console.warn('[Forms] Tracking skipped: formId is empty')\n return\n }\n \n // Generate session ID\n sessionIdRef.current = crypto.randomUUID()\n startTimeRef.current = Date.now()\n stepStartTimeRef.current = Date.now()\n \n // Record form start\n const startTracking = async () => {\n const apiUrl = (window as any).__SITE_KIT_API_URL__\n const apiKey = (window as any).__SITE_KIT_API_KEY__\n \n if (!apiUrl || !apiKey) {\n if (debug) console.error('[Forms] Missing API URL or API key')\n return\n }\n \n try {\n const response = await sonorFetch(\n `${apiUrl}/api/public/forms/analytics/start`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n formId,\n sessionId: sessionIdRef.current,\n deviceType: getDeviceType(),\n }),\n },\n { apiKey, retries: 0 },\n )\n \n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n \n const data = await response.json()\n analyticsIdRef.current = data.id\n if (debug) console.log('[Forms] Started tracking:', data.id)\n } catch (error) {\n if (debug) console.error('[Forms] Error starting tracking:', error)\n }\n }\n \n startTracking()\n \n // Handle abandonment on page leave\n const handleBeforeUnload = () => {\n if (!analyticsIdRef.current) return\n \n const apiUrl = (window as any).__SITE_KIT_API_URL__\n const apiKey = (window as any).__SITE_KIT_API_KEY__\n \n if (!apiUrl || !apiKey) return\n \n const now = Date.now()\n const currentStepTime = Math.floor((now - stepStartTimeRef.current) / 1000)\n stepTimesRef.current[currentStepRef.current] = currentStepTime\n\n // Fire-and-forget via sonorBeacon: keepalive fetch keeps the credential in\n // the x-api-key header (raw sendBeacon can't set headers), so abandonment\n // authenticates on 3.2+ token sites and uses the freshest minted token.\n sonorBeacon(\n `${apiUrl}/api/public/forms/analytics/abandon`,\n {\n analyticsId: analyticsIdRef.current,\n step: currentStepRef.current,\n maxStep: maxStepRef.current,\n stepTimes: stepTimesRef.current,\n totalTimeSeconds: Math.floor((now - startTimeRef.current) / 1000),\n },\n apiKey,\n )\n\n if (debug) console.log('[Forms] Abandonment tracked')\n }\n \n window.addEventListener('beforeunload', handleBeforeUnload)\n \n return () => {\n window.removeEventListener('beforeunload', handleBeforeUnload)\n }\n }, [formId, enabled, debug])\n \n // Track step changes\n const trackStepChange = useCallback(async (step: number) => {\n if (!enabled || !analyticsIdRef.current) return\n \n const apiUrl = (window as any).__SITE_KIT_API_URL__\n const apiKey = (window as any).__SITE_KIT_API_KEY__\n \n if (!apiUrl || !apiKey) {\n if (debug) console.error('[Forms] Missing API URL or API key')\n return\n }\n \n const now = Date.now()\n \n // Record time spent on previous step\n const prevStepTime = Math.floor((now - stepStartTimeRef.current) / 1000)\n stepTimesRef.current[currentStepRef.current] = prevStepTime\n \n // Update refs\n currentStepRef.current = step\n maxStepRef.current = Math.max(maxStepRef.current, step)\n stepStartTimeRef.current = now\n \n // Update database\n try {\n const response = await sonorFetch(\n `${apiUrl}/api/public/forms/analytics/step`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n analyticsId: analyticsIdRef.current,\n step,\n maxStep: maxStepRef.current,\n stepTimes: stepTimesRef.current,\n }),\n },\n { apiKey, retries: 0 },\n )\n \n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n \n if (debug) console.log('[Forms] Step changed to:', step)\n } catch (error) {\n if (debug) console.error('[Forms] Error updating step:', error)\n }\n }, [enabled, debug])\n \n // Track completion\n const trackComplete = useCallback(async () => {\n if (!enabled || !analyticsIdRef.current) return\n \n const apiUrl = (window as any).__SITE_KIT_API_URL__\n const apiKey = (window as any).__SITE_KIT_API_KEY__\n \n if (!apiUrl || !apiKey) {\n if (debug) console.error('[Forms] Missing API URL or API key')\n return\n }\n \n const now = Date.now()\n \n // Record time for final step\n const finalStepTime = Math.floor((now - stepStartTimeRef.current) / 1000)\n stepTimesRef.current[currentStepRef.current] = finalStepTime\n \n try {\n // Complete form analytics tracking\n // Note: A database trigger will automatically log this as a conversion\n // in analytics_conversions when completed_at is set\n const response = await sonorFetch(\n `${apiUrl}/api/public/forms/analytics/complete`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n analyticsId: analyticsIdRef.current,\n totalSteps,\n stepTimes: stepTimesRef.current,\n totalTimeSeconds: Math.floor((now - startTimeRef.current) / 1000),\n }),\n },\n { apiKey, retries: 0 },\n )\n \n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n \n if (debug) console.log('[Forms] Form completed, recording conversion')\n\n // Explicitly track as a conversion (don't rely on DB trigger)\n try {\n await sonorFetch(\n `${apiUrl}/api/public/analytics/conversion`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n sessionId: sessionIdRef.current,\n conversionType: 'form_submission',\n metadata: { formId, analyticsId: analyticsIdRef.current },\n pagePath: typeof window !== 'undefined' ? window.location.pathname : '/',\n referrer: typeof document !== 'undefined' ? document.referrer || null : null,\n deviceType: getDeviceType(),\n }),\n },\n { apiKey, retries: 0 },\n )\n } catch (convErr) {\n if (debug) console.error('[Forms] Error recording conversion:', convErr)\n }\n } catch (error) {\n if (debug) console.error('[Forms] Error completing tracking:', error)\n }\n }, [enabled, totalSteps, formId, debug])\n \n return {\n trackStepChange,\n trackComplete,\n sessionId: sessionIdRef.current,\n }\n}\n\n// Helper\nfunction getDeviceType(): 'desktop' | 'mobile' | 'tablet' {\n if (typeof window === 'undefined') return 'desktop'\n const ua = navigator.userAgent\n if (/tablet|ipad|playbook|silk/i.test(ua)) return 'tablet'\n if (/mobile|iphone|ipod|android|blackberry|opera mini|iemobile/i.test(ua)) return 'mobile'\n return 'desktop'\n}\n\n","/** Shown when the API omits or returns an empty `success_message`. */\nexport const DEFAULT_FORM_SUCCESS_MESSAGE =\n 'Thank you for your submission! We will be in touch soon.'\n","/**\n * reCAPTCHA Enterprise - Client-side token generation for site-kit forms\n *\n * Site key is read from:\n * - window.__SITE_KIT_RECAPTCHA_SITE_KEY__ (set by SiteKitProvider)\n * - process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY (when bundled in Next.js app)\n */\n\nfunction getSiteKey(explicitSiteKey?: string): string | undefined {\n if (typeof window === 'undefined') return undefined\n if (explicitSiteKey) return explicitSiteKey\n const win = window as any\n return win.__SITE_KIT_RECAPTCHA_SITE_KEY__ ?? process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY\n}\n\n/** Max time to wait for reCAPTCHA Enterprise to become usable before giving up. */\nconst RECAPTCHA_LOAD_TIMEOUT_MS = 10000\n\nfunction loadScript(siteKey: string): Promise<any> {\n return new Promise((resolve) => {\n if (typeof window === 'undefined') {\n resolve(null)\n return\n }\n const win = window as any\n if (win.grecaptcha?.enterprise) {\n resolve(win.grecaptcha)\n return\n }\n\n // Never hang the form: if the script is blocked (ad-blocker), stalls, or\n // never initializes `grecaptcha.enterprise`, resolve null after a timeout.\n // The caller treats a null result as \"no token\" rather than waiting forever.\n let settled = false\n const finish = (value: any) => {\n if (settled) return\n settled = true\n resolve(value)\n }\n const giveUp = setTimeout(() => finish(null), RECAPTCHA_LOAD_TIMEOUT_MS)\n\n const waitForReady = () => {\n if (settled) return\n if (win.grecaptcha?.enterprise) {\n clearTimeout(giveUp)\n finish(win.grecaptcha)\n return\n }\n setTimeout(waitForReady, 50)\n }\n\n const existing = document.querySelector('script[src*=\"recaptcha/enterprise\"]')\n if (existing) {\n waitForReady()\n return\n }\n\n const script = document.createElement('script')\n script.src = `https://www.google.com/recaptcha/enterprise.js?render=${siteKey}`\n script.async = true\n script.onload = () => waitForReady()\n script.onerror = () => {\n clearTimeout(giveUp)\n finish(null)\n }\n document.head.appendChild(script)\n })\n}\n\n/**\n * Get a reCAPTCHA Enterprise token for form submission.\n * Returns null if not configured or in SSR.\n */\nexport async function getRecaptchaToken(explicitSiteKey?: string): Promise<string | null> {\n const siteKey = getSiteKey(explicitSiteKey)\n if (!siteKey || typeof window === 'undefined') return null\n try {\n const grecaptcha = await loadScript(siteKey)\n if (!grecaptcha?.enterprise?.execute) return null\n const token = await grecaptcha.enterprise.execute(siteKey, { action: 'submit' })\n return token || null\n } catch (err) {\n console.warn('[site-kit reCAPTCHA]', err)\n return null\n }\n}\n","/**\n * @sonordev/site-kit/forms - Shared submission logic\n *\n * Single source of truth for sending a managed form to the Sonor API. Both\n * <ManagedForm> (via FormClient) and the headless useForm() hook submit through\n * here, so the request shape, retry behaviour, reCAPTCHA handling, and error\n * parsing can never drift between the two paths.\n */\n\nimport { sonorFetch } from '../shared/sonorFetch'\nimport { getRecaptchaToken } from './recaptcha'\nimport { DEFAULT_HONEYPOT_FIELD } from './contract'\nimport type { ManagedFormConfig } from './types'\n\n// The honeypot trap-field name lives once in the shared forms contract\n// (single source of truth for site-kit's client + sonor-api's intake).\n// Re-exported so existing importers of this path keep resolving it.\nexport { DEFAULT_HONEYPOT_FIELD }\n\nfunction getApiConfig(): { apiUrl: string; apiKey: string | undefined } {\n const apiUrl =\n typeof window !== 'undefined'\n ? (window as any).__SITE_KIT_API_URL__ || 'https://api.sonor.io'\n : 'https://api.sonor.io'\n const apiKey =\n typeof window !== 'undefined' ? (window as any).__SITE_KIT_API_KEY__ : undefined\n return { apiUrl, apiKey }\n}\n\nfunction getUTMParams(): Record<string, string | null> {\n if (typeof window === 'undefined') return {}\n const params = new URLSearchParams(window.location.search)\n const out: Record<string, string | null> = {}\n for (const key of ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content']) {\n out[key] = params.get(key)\n }\n return out\n}\n\nexport interface SubmitFormArgs {\n config: ManagedFormConfig\n /**\n * Field values to submit. The caller must pass VISIBLE values only —\n * conditionally-hidden fields should be excluded so stale values are not sent.\n */\n values: Record<string, unknown>\n /** Honeypot input value (empty string for the headless hook, which has no honeypot UI). */\n honeypotValue: string\n /** Timestamp (ms) the form was first rendered — a weak anti-bot timing signal. */\n formLoadedAt: number\n}\n\n/**\n * Submit a managed form. Throws on failure (network, timeout, or a non-2xx\n * response) with a human-readable message; resolves with the parsed API\n * response on success.\n */\nexport async function submitForm({\n config,\n values,\n honeypotValue,\n formLoadedAt,\n}: SubmitFormArgs): Promise<unknown> {\n const { apiUrl, apiKey } = getApiConfig()\n if (!apiKey) {\n throw new Error('API key is required. Set SONOR_API_KEY in your environment.')\n }\n\n // reCAPTCHA token is fetched right before the POST so it cannot expire.\n const recaptchaToken = config.recaptcha_enabled\n ? await getRecaptchaToken(config.recaptcha_site_key)\n : null\n if (config.recaptcha_enabled && !recaptchaToken) {\n throw new Error('Verification could not be completed. Please try again.')\n }\n\n const honeypotFieldName = config.honeypot_field || DEFAULT_HONEYPOT_FIELD\n const utm = getUTMParams()\n\n const payload = {\n formId: config.id,\n form_id: config.id,\n data: {\n ...values,\n ...(config.honeypot_enabled ? { [honeypotFieldName]: honeypotValue } : {}),\n },\n metadata: {\n pageUrl: typeof window !== 'undefined' ? window.location.href : null,\n referrer: typeof document !== 'undefined' ? document.referrer || null : null,\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : null,\n sessionId:\n typeof sessionStorage !== 'undefined' ? sessionStorage.getItem('_sk_sid') : null,\n // Anonymous visitor id (_sk_vid) — the same id Analytics/Signal stamp on\n // page views, so the Sonor side can bind this lead to its browsing session\n // (page -> lead attribution). Sent on every submission; null pre-hydration.\n visitorId:\n typeof localStorage !== 'undefined' ? localStorage.getItem('_sk_vid') : null,\n recaptchaToken: recaptchaToken || undefined,\n utmSource: utm.utm_source,\n utmMedium: utm.utm_medium,\n utmCampaign: utm.utm_campaign,\n // Sub-site host — preserved on form_submissions for lead attribution\n // across multi-site projects. Resolved by SiteKitClientProviders.\n site:\n typeof window !== 'undefined'\n ? (window as { __SITE_KIT_SITE__?: string }).__SITE_KIT_SITE__ ||\n window.location.host\n : undefined,\n _formLoadedAt: formLoadedAt,\n },\n }\n\n const response = await sonorFetch(\n `${apiUrl}/api/public/forms/submit`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(payload),\n },\n { retries: 2, timeoutMs: 20000 },\n )\n\n const data = await response.json().catch(() => null)\n\n if (!response.ok) {\n const msg = (\n data?.message ??\n data?.error ??\n (response.statusText || `HTTP ${response.status}`)\n )\n .toString()\n .trim()\n throw new Error(\n msg ? `Failed to submit form: ${msg}` : `Failed to submit form (${response.status})`,\n )\n }\n\n return data\n}\n","/**\n * @sonordev/site-kit/forms - useForm Hook\n * \n * Headless hook for complete control over form rendering.\n * Fetches form config from API, handles validation, state, and submission.\n * \n * @example\n * ```tsx\n * const { form, fields, values, errors, setFieldValue, submit, isSubmitting } = useForm('contact-form')\n * \n * return (\n * <form onSubmit={(e) => { e.preventDefault(); submit() }}>\n * {fields.map(field => (\n * <MyCustomInput\n * key={field.slug}\n * label={field.label}\n * value={values[field.slug]}\n * error={errors[field.slug]}\n * onChange={(val) => setFieldValue(field.slug, val)}\n * />\n * ))}\n * <button type=\"submit\" disabled={isSubmitting}>Submit</button>\n * </form>\n * )\n * ```\n */\n\n'use client'\n\nimport { useState, useEffect, useCallback, useMemo, useRef } from 'react'\nimport { useFormTracking } from './useFormTracking'\nimport { sonorFetch } from '../shared/sonorFetch'\nimport { submitForm } from './submitForm'\nimport type { \n ManagedFormConfig, \n FormField, \n FormSubmission \n} from './types'\nimport { DEFAULT_FORM_SUCCESS_MESSAGE } from './defaultSuccessMessage'\n\n// ============================================\n// Types\n// ============================================\n\nexport interface UseFormOptions {\n /** Project ID (defaults to SiteKitProvider config) */\n projectId?: string\n /** Callback when form submits successfully */\n onSuccess?: (submission: FormSubmission) => void\n /** Callback when submission fails */\n onError?: (error: Error) => void\n /** Initial values to prefill */\n initialValues?: Record<string, unknown>\n /** Auto-redirect after success (override form config) */\n redirectUrl?: string | false\n}\n\nexport interface UseFormReturn {\n /** Form configuration (null while loading) */\n form: ManagedFormConfig | null\n /** Loading state */\n isLoading: boolean\n /** Error fetching form */\n fetchError: Error | null\n /** Human-readable error from the last submit attempt (null when none) */\n submitError: string | null\n\n /** All form fields */\n allFields: FormField[]\n /** Fields for current step (multi-step) or all fields (single step) */\n fields: FormField[]\n /** Visible fields only (respecting conditional logic) */\n visibleFields: FormField[]\n \n /** Current form values */\n values: Record<string, unknown>\n /** Current validation errors */\n errors: Record<string, string>\n \n /** Set a single field value */\n setFieldValue: (key: string, value: unknown) => void\n /** Set multiple field values at once */\n setValues: (values: Record<string, unknown>) => void\n /** Clear all errors */\n clearErrors: () => void\n \n /** Multi-step state */\n step: number\n totalSteps: number\n isMultiStep: boolean\n progress: number\n \n /** Multi-step navigation */\n nextStep: () => boolean\n prevStep: () => void\n goToStep: (step: number) => void\n canGoNext: boolean\n canGoPrev: boolean\n isLastStep: boolean\n \n /** Validate current step */\n validate: () => boolean\n /** Validate a single field */\n validateField: (field: FormField) => string | null\n /** Check if a field is visible (conditional logic) */\n isFieldVisible: (field: FormField) => boolean\n \n /** Submit the form */\n submit: () => Promise<void>\n /** Submission state */\n isSubmitting: boolean\n isComplete: boolean\n /** Reset form to initial state */\n reset: () => void\n}\n\n// ============================================\n// Hook\n// ============================================\n\nexport function useForm(\n formIdOrSlug: string,\n options: UseFormOptions = {}\n): UseFormReturn {\n const { \n projectId: optionsProjectId,\n onSuccess, \n onError, \n initialValues = {},\n redirectUrl,\n } = options\n \n // Get projectId from window globals if not provided\n const projectId = optionsProjectId || \n (typeof window !== 'undefined' ? (window as any).__SITE_KIT_PROJECT_ID__ : undefined)\n \n // State\n const [form, setForm] = useState<ManagedFormConfig | null>(null)\n const [isLoading, setIsLoading] = useState(true)\n const [fetchError, setFetchError] = useState<Error | null>(null)\n const [values, setValuesState] = useState<Record<string, unknown>>(initialValues)\n const [errors, setErrors] = useState<Record<string, string>>({})\n const [step, setStep] = useState(1)\n const [isSubmitting, setIsSubmitting] = useState(false)\n const [isComplete, setIsComplete] = useState(false)\n const [submitError, setSubmitError] = useState<string | null>(null)\n\n // Synchronous re-entrancy guard + anti-bot timing.\n const isSubmittingRef = useRef(false)\n const formLoadedAt = useRef(Date.now())\n\n const totalSteps = form?.total_steps || 1\n const isMultiStep = (form?.is_multi_step) || false\n \n const { trackStepChange, trackComplete } = useFormTracking({\n formId: form?.id || '',\n totalSteps,\n })\n \n // Fetch form config (project is derived from API key on the backend; projectId is optional)\n useEffect(() => {\n const apiUrl = typeof window !== 'undefined'\n ? (window as any).__SITE_KIT_API_URL__ || 'https://api.sonor.io'\n : 'https://api.sonor.io'\n\n async function fetchForm() {\n try {\n setIsLoading(true)\n setFetchError(null)\n\n // The provider sets __SITE_KIT_API_KEY__ during its render; if this\n // hook's effect happens to run first, poll briefly for it rather than\n // failing permanently and wedging the form on \"API key is required\".\n const readApiKey = (): string | undefined =>\n typeof window !== 'undefined' ? (window as any).__SITE_KIT_API_KEY__ : undefined\n let apiKey = readApiKey()\n for (let i = 0; i < 15 && !apiKey; i++) {\n await new Promise((r) => setTimeout(r, 100))\n apiKey = readApiKey()\n }\n if (!apiKey) {\n throw new Error('API key is required. Provide it via SiteKitLayout/SiteKitProvider or set SONOR_API_KEY.')\n }\n\n const url = `${apiUrl}/api/public/forms/config`\n const init: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n formIdOrSlug: formIdOrSlug,\n }),\n }\n\n // Pass the credential via options.apiKey, NOT an Authorization header.\n // extractApiKey() server-side prefers Authorization: Bearer over x-api-key,\n // so a hand-set Bearer pins the stale build-time seed and defeats\n // sonorFetch's refresh — the seed 401s and the refresh-retry keeps\n // re-sending the same dead Bearer. Letting sonorFetch own x-api-key means\n // the server sees the FRESH token.\n const response = await sonorFetch(url, init, { apiKey, retries: 3, timeoutMs: 15000 })\n\n if (!response.ok) {\n throw new Error(`Failed to fetch form: ${response.statusText}`)\n }\n \n const data = await response.json()\n if (!data) throw new Error('Form not found')\n\n if (typeof window !== 'undefined' && data.recaptcha_site_key) {\n ;(window as any).__SITE_KIT_RECAPTCHA_SITE_KEY__ = data.recaptcha_site_key\n }\n \n // Sort steps and fields\n if (data.steps) {\n data.steps.sort((a: any, b: any) => (a.step_number || 0) - (b.step_number || 0))\n }\n if (data.fields) {\n data.fields.sort((a: any, b: any) => (a.sort_order || 0) - (b.sort_order || 0))\n }\n \n // Compute multi-step properties\n const total_steps = data.steps?.length || 1\n const is_multi_step = total_steps > 1\n\n const apiSuccess =\n typeof data.success_message === 'string' ? data.success_message.trim() : ''\n const success_message =\n apiSuccess ||\n (typeof (data as { successMessage?: string }).successMessage === 'string'\n ? String((data as { successMessage?: string }).successMessage).trim()\n : '') ||\n DEFAULT_FORM_SUCCESS_MESSAGE\n \n setForm({\n ...data,\n success_message,\n total_steps,\n is_multi_step,\n })\n \n // Set default values from field configs\n const defaults: Record<string, unknown> = {}\n for (const field of data.fields || []) {\n if (field.default_value !== undefined && field.default_value !== null) {\n defaults[field.slug] = field.default_value\n }\n }\n setValuesState({ ...defaults, ...initialValues })\n \n } catch (err) {\n setFetchError(err as Error)\n } finally {\n setIsLoading(false)\n }\n }\n \n fetchForm()\n }, [formIdOrSlug, projectId])\n \n // All fields\n const allFields = useMemo(() => form?.fields || [], [form])\n \n // Fields for current step\n const fields = useMemo(() => {\n if (!isMultiStep) return allFields\n \n const currentStepConfig = form?.steps?.find(s => s.step_number === step)\n if (!currentStepConfig) return allFields\n \n return allFields.filter(f => f.step_id === currentStepConfig.id)\n }, [form, step, allFields, isMultiStep])\n \n // Check if field is visible (conditional logic)\n const isFieldVisible = useCallback((field: FormField): boolean => {\n if (!field.conditional?.show_when) return true\n \n const { field: condField, operator, value } = field.conditional.show_when\n const fieldValue = values[condField]\n \n switch (operator) {\n case 'equals':\n return fieldValue === value\n case 'not_equals':\n return fieldValue !== value\n case 'contains':\n return String(fieldValue || '').includes(String(value))\n case 'not_contains':\n return !String(fieldValue || '').includes(String(value))\n case 'is_empty':\n return !fieldValue || fieldValue === ''\n case 'not_empty':\n return !!fieldValue && fieldValue !== ''\n case 'greater_than':\n return Number(fieldValue) > Number(value)\n case 'less_than':\n return Number(fieldValue) < Number(value)\n default:\n return true\n }\n }, [values])\n \n // Visible fields only\n const visibleFields = useMemo(() => {\n return fields.filter(isFieldVisible)\n }, [fields, isFieldVisible])\n \n // Validate a single field\n const validateField = useCallback((field: FormField): string | null => {\n if (!isFieldVisible(field)) return null\n // Skip display-only field types\n if (['heading', 'section_header', 'paragraph', 'hidden'].includes(field.field_type)) return null\n\n const value = values[field.slug]\n const rules = field.validation || {}\n \n // Required check\n if (field.is_required && (!value || value === '')) {\n return rules.custom_error || `${field.label} is required`\n }\n \n if (!value) return null\n \n const strValue = String(value)\n \n // Length checks\n if (rules.min_length && strValue.length < rules.min_length) {\n return `${field.label} must be at least ${rules.min_length} characters`\n }\n if (rules.max_length && strValue.length > rules.max_length) {\n return `${field.label} must be no more than ${rules.max_length} characters`\n }\n \n // Numeric checks\n if (rules.min !== undefined && Number(value) < rules.min) {\n return `${field.label} must be at least ${rules.min}`\n }\n if (rules.max !== undefined && Number(value) > rules.max) {\n return `${field.label} must be no more than ${rules.max}`\n }\n \n // Pattern check — guard against an invalid admin-entered pattern.\n if (rules.pattern) {\n try {\n if (!new RegExp(rules.pattern).test(strValue)) {\n return rules.custom_error || `${field.label} is invalid`\n }\n } catch {\n // Malformed pattern — skip rather than crashing the form.\n }\n }\n \n // Email check\n if (field.field_type === 'email' && !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(strValue)) {\n return 'Please enter a valid email address'\n }\n \n // Phone check\n if (field.field_type === 'phone' && !/^[\\d\\s\\-\\+\\(\\)]+$/.test(strValue)) {\n return 'Please enter a valid phone number'\n }\n \n return null\n }, [values, isFieldVisible])\n \n // Validate current step\n const validate = useCallback((): boolean => {\n const newErrors: Record<string, string> = {}\n \n for (const field of fields) {\n const error = validateField(field)\n if (error) {\n newErrors[field.slug] = error\n }\n }\n \n setErrors(newErrors)\n return Object.keys(newErrors).length === 0\n }, [fields, validateField])\n\n // Validate EVERY field across all steps — used on final submit so a required\n // field left empty on an earlier step cannot slip through.\n const validateAll = useCallback((): boolean => {\n const newErrors: Record<string, string> = {}\n for (const field of allFields) {\n const error = validateField(field)\n if (error) newErrors[field.slug] = error\n }\n setErrors(newErrors)\n return Object.keys(newErrors).length === 0\n }, [allFields, validateField])\n\n // Visible field values only — never submit a value from a conditionally-hidden field.\n const buildVisibleValues = useCallback((): Record<string, unknown> => {\n const out: Record<string, unknown> = {}\n for (const field of allFields) {\n if (!isFieldVisible(field)) continue\n if (field.slug in values) out[field.slug] = values[field.slug]\n }\n return out\n }, [allFields, values, isFieldVisible])\n\n // Set single field value\n const setFieldValue = useCallback((key: string, value: unknown) => {\n setValuesState(prev => ({ ...prev, [key]: value }))\n // Clear error when field changes\n setErrors(prev => {\n if (prev[key]) {\n const next = { ...prev }\n delete next[key]\n return next\n }\n return prev\n })\n }, [])\n \n // Set multiple values\n const setValues = useCallback((newValues: Record<string, unknown>) => {\n setValuesState(prev => ({ ...prev, ...newValues }))\n }, [])\n \n // Clear all errors\n const clearErrors = useCallback(() => {\n setErrors({})\n }, [])\n \n // Step navigation\n const canGoNext = step < totalSteps\n const canGoPrev = step > 1\n const isLastStep = step === totalSteps\n const progress = Math.round((step / totalSteps) * 100)\n \n const nextStep = useCallback((): boolean => {\n if (!validate()) return false\n \n if (step < totalSteps) {\n const newStep = step + 1\n setStep(newStep)\n trackStepChange(newStep)\n return true\n }\n return false\n }, [step, totalSteps, validate, trackStepChange])\n \n const prevStep = useCallback(() => {\n if (step > 1) {\n const newStep = step - 1\n setStep(newStep)\n trackStepChange(newStep)\n }\n }, [step, trackStepChange])\n \n const goToStep = useCallback((targetStep: number) => {\n if (targetStep >= 1 && targetStep <= totalSteps) {\n setStep(targetStep)\n trackStepChange(targetStep)\n }\n }, [totalSteps, trackStepChange])\n \n // Submit form\n const submit = useCallback(async () => {\n if (!form) return\n // Re-entrancy guard — blocks a concurrent double-submit in the same tick.\n if (isSubmittingRef.current) return\n if (!validateAll()) return\n\n isSubmittingRef.current = true\n setIsSubmitting(true)\n setSubmitError(null)\n\n try {\n const data = await submitForm({\n config: form,\n values: buildVisibleValues(),\n honeypotValue: '',\n formLoadedAt: formLoadedAt.current,\n })\n\n trackComplete()\n setIsComplete(true)\n onSuccess?.(data as FormSubmission)\n\n const finalRedirect = redirectUrl !== false\n ? (redirectUrl || form.redirect_url)\n : undefined\n if (finalRedirect) {\n window.location.href = finalRedirect\n }\n } catch (error) {\n console.error('[useForm] Submission error:', error)\n setSubmitError('Something went wrong sending your submission. Please try again.')\n onError?.(error as Error)\n } finally {\n isSubmittingRef.current = false\n setIsSubmitting(false)\n }\n }, [form, validateAll, buildVisibleValues, trackComplete, onSuccess, onError, redirectUrl])\n \n // Reset form\n const reset = useCallback(() => {\n setValuesState(initialValues)\n setErrors({})\n setStep(1)\n setIsComplete(false)\n setSubmitError(null)\n }, [initialValues])\n \n return {\n form,\n isLoading,\n fetchError,\n submitError,\n\n allFields,\n fields,\n visibleFields,\n \n values,\n errors,\n setFieldValue,\n setValues,\n clearErrors,\n \n step,\n totalSteps,\n isMultiStep,\n progress,\n \n nextStep,\n prevStep,\n goToStep,\n canGoNext,\n canGoPrev,\n isLastStep,\n \n validate,\n validateField,\n isFieldVisible,\n \n submit,\n isSubmitting,\n isComplete,\n reset,\n }\n}\n"]}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
|
+
import { sonorFetch } from './chunk-SBT4J733.mjs';
|
|
2
3
|
import { useState, useRef, useMemo, useEffect, useCallback } from 'react';
|
|
3
4
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
4
5
|
|
|
5
|
-
// src/sync/BookingWidget.tsx
|
|
6
|
-
|
|
7
6
|
// src/sync/api.ts
|
|
8
7
|
var DEFAULT_API_URL = "https://api.sonor.io";
|
|
9
8
|
function getApiConfig() {
|
|
@@ -11,10 +10,9 @@ function getApiConfig() {
|
|
|
11
10
|
const apiKey = typeof window !== "undefined" ? window.__SITE_KIT_API_KEY__ : void 0;
|
|
12
11
|
return { apiUrl, apiKey };
|
|
13
12
|
}
|
|
14
|
-
function buildHeaders(
|
|
13
|
+
function buildHeaders(isPost = false) {
|
|
15
14
|
const headers = {};
|
|
16
15
|
if (isPost) headers["Content-Type"] = "application/json";
|
|
17
|
-
if (apiKey) headers["x-api-key"] = apiKey;
|
|
18
16
|
return headers;
|
|
19
17
|
}
|
|
20
18
|
async function fetchBookingTypes(orgSlug, apiUrl, apiKey) {
|
|
@@ -22,7 +20,7 @@ async function fetchBookingTypes(orgSlug, apiUrl, apiKey) {
|
|
|
22
20
|
const url = apiUrl || cfg.apiUrl;
|
|
23
21
|
const key = apiKey || cfg.apiKey;
|
|
24
22
|
const endpoint = key ? `${url}/sync/widget/types` : `${url}/sync/public/${orgSlug}/types`;
|
|
25
|
-
const response = await
|
|
23
|
+
const response = await sonorFetch(endpoint, { headers: buildHeaders() }, { apiKey: key, retries: 0 });
|
|
26
24
|
if (!response.ok) {
|
|
27
25
|
const msg = await response.json().catch(() => ({ message: response.statusText }));
|
|
28
26
|
const detail = msg && typeof msg.message === "string" ? msg.message : response.statusText;
|
|
@@ -36,7 +34,7 @@ async function fetchBookingTypeDetails(typeSlug, orgSlug, apiUrl, apiKey) {
|
|
|
36
34
|
const url = apiUrl || cfg.apiUrl;
|
|
37
35
|
const key = apiKey || cfg.apiKey;
|
|
38
36
|
const endpoint = key ? `${url}/sync/widget/types/${typeSlug}` : `${url}/sync/public/${orgSlug}/types/${typeSlug}`;
|
|
39
|
-
const response = await
|
|
37
|
+
const response = await sonorFetch(endpoint, { headers: buildHeaders() }, { apiKey: key, retries: 0 });
|
|
40
38
|
if (!response.ok) {
|
|
41
39
|
const msg = await response.json().catch(() => ({ message: response.statusText }));
|
|
42
40
|
const detail = msg && typeof msg.message === "string" ? msg.message : response.statusText;
|
|
@@ -52,7 +50,7 @@ async function fetchAvailability(typeSlug, date, orgSlug, apiUrl, apiKey, timezo
|
|
|
52
50
|
if (timezone) params.append("timezone", timezone);
|
|
53
51
|
if (hostId) params.append("hostId", hostId);
|
|
54
52
|
const endpoint = key ? `${url}/sync/widget/availability/${typeSlug}?${params}` : `${url}/sync/public/${orgSlug}/availability/${typeSlug}?${params}`;
|
|
55
|
-
const response = await
|
|
53
|
+
const response = await sonorFetch(endpoint, { headers: buildHeaders() }, { apiKey: key, retries: 0 });
|
|
56
54
|
if (!response.ok) {
|
|
57
55
|
const msg = await response.json().catch(() => ({ message: response.statusText }));
|
|
58
56
|
let detail = msg && typeof msg.message === "string" ? String(msg.message).trim() : (response.statusText || "").trim();
|
|
@@ -75,11 +73,11 @@ async function createSlotHold(holdData, apiUrl, apiKey) {
|
|
|
75
73
|
const url = apiUrl || cfg.apiUrl;
|
|
76
74
|
const key = apiKey || cfg.apiKey;
|
|
77
75
|
const endpoint = key ? `${url}/sync/widget/hold` : `${url}/sync/public/hold`;
|
|
78
|
-
const response = await
|
|
76
|
+
const response = await sonorFetch(endpoint, {
|
|
79
77
|
method: "POST",
|
|
80
|
-
headers: buildHeaders(
|
|
78
|
+
headers: buildHeaders(true),
|
|
81
79
|
body: JSON.stringify(holdData)
|
|
82
|
-
});
|
|
80
|
+
}, { apiKey: key, retries: 0 });
|
|
83
81
|
if (!response.ok) {
|
|
84
82
|
throw new Error(`Failed to hold slot: ${response.statusText}`);
|
|
85
83
|
}
|
|
@@ -90,21 +88,21 @@ async function releaseSlotHold(holdId, apiUrl, apiKey) {
|
|
|
90
88
|
const url = apiUrl || cfg.apiUrl;
|
|
91
89
|
const key = apiKey || cfg.apiKey;
|
|
92
90
|
const endpoint = key ? `${url}/sync/widget/hold/${holdId}` : `${url}/sync/public/hold/${holdId}`;
|
|
93
|
-
await
|
|
91
|
+
await sonorFetch(endpoint, {
|
|
94
92
|
method: "DELETE",
|
|
95
|
-
headers: buildHeaders(
|
|
96
|
-
});
|
|
93
|
+
headers: buildHeaders()
|
|
94
|
+
}, { apiKey: key, retries: 0 });
|
|
97
95
|
}
|
|
98
96
|
async function createBooking(bookingData, apiUrl, apiKey) {
|
|
99
97
|
const cfg = getApiConfig();
|
|
100
98
|
const url = apiUrl || cfg.apiUrl;
|
|
101
99
|
const key = apiKey || cfg.apiKey;
|
|
102
100
|
const endpoint = key ? `${url}/sync/widget/booking` : `${url}/sync/public/booking`;
|
|
103
|
-
const response = await
|
|
101
|
+
const response = await sonorFetch(endpoint, {
|
|
104
102
|
method: "POST",
|
|
105
|
-
headers: buildHeaders(
|
|
103
|
+
headers: buildHeaders(true),
|
|
106
104
|
body: JSON.stringify(bookingData)
|
|
107
|
-
});
|
|
105
|
+
}, { apiKey: key, retries: 0 });
|
|
108
106
|
if (!response.ok) {
|
|
109
107
|
const errorData = await response.json().catch(() => ({}));
|
|
110
108
|
throw new Error(errorData.message || `Failed to create booking: ${response.statusText}`);
|
|
@@ -420,9 +418,9 @@ function BookingWidget({
|
|
|
420
418
|
"--sk-text-secondary": styles.textSecondary || "#6b7280",
|
|
421
419
|
"--sk-text-tertiary": styles.textTertiary || "#9ca3af",
|
|
422
420
|
"--sk-border": styles.borderColor || "#e5e7eb",
|
|
423
|
-
"--sk-error": "#
|
|
424
|
-
"--sk-success": "#
|
|
425
|
-
"--sk-warning": "#
|
|
421
|
+
"--sk-error": "#dc2626",
|
|
422
|
+
"--sk-success": "#047857",
|
|
423
|
+
"--sk-warning": "#b45309",
|
|
426
424
|
"--sk-radius": styles.borderRadius || "8px",
|
|
427
425
|
"--sk-font": styles.fontFamily || "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
|
|
428
426
|
"--sk-input-border": styles.inputBorderColor || styles.borderColor || "#e5e7eb",
|
|
@@ -1014,5 +1012,5 @@ var WIDGET_CSS = `
|
|
|
1014
1012
|
`;
|
|
1015
1013
|
|
|
1016
1014
|
export { BookingWidget, createBooking, createSlotHold, detectTimezone, fetchAvailability, fetchAvailableDates, fetchBookingTypeDetails, fetchBookingTypes, formatDate, formatDuration, formatTime, releaseSlotHold };
|
|
1017
|
-
//# sourceMappingURL=chunk-
|
|
1018
|
-
//# sourceMappingURL=chunk-
|
|
1015
|
+
//# sourceMappingURL=chunk-AMBTOIYM.mjs.map
|
|
1016
|
+
//# sourceMappingURL=chunk-AMBTOIYM.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sync/api.ts","../src/sync/BookingWidget.tsx"],"names":["DEFAULT_API_URL"],"mappings":"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","file":"chunk-AMBTOIYM.mjs","sourcesContent":["/**\n * Sync API Functions - Client-side API calls for booking widget\n *\n * Two modes:\n * 1. API-key flow (preferred): Uses x-api-key header → /sync/widget/* endpoints.\n * Project is resolved server-side from the key. No orgSlug needed.\n * 2. Public/orgSlug flow (legacy): Uses /sync/public/:org/* endpoints. No auth.\n */\n\nimport { sonorFetch } from '../shared/sonorFetch'\nimport type {\n BookingType,\n TimeSlot,\n SlotHold,\n BookingResult,\n GuestInfo,\n} from './types'\n\nconst DEFAULT_API_URL = 'https://api.sonor.io'\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Config helper (same pattern as analytics, commerce, engage)\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction getApiConfig() {\n const apiUrl = typeof window !== 'undefined'\n ? (window as any).__SITE_KIT_API_URL__ || DEFAULT_API_URL\n : DEFAULT_API_URL\n const apiKey = typeof window !== 'undefined'\n ? (window as any).__SITE_KIT_API_KEY__\n : undefined\n return { apiUrl, apiKey }\n}\n\n/**\n * Build headers – only Content-Type for POSTs. The credential is NOT set here:\n * it's passed to sonorFetch via options.apiKey so a stale minted-token seed is\n * refreshed transparently (a hand-set x-api-key header would pin the stale seed\n * and 401). The public/orgSlug flow simply passes no key and stays unauthed.\n */\nfunction buildHeaders(isPost = false): Record<string, string> {\n const headers: Record<string, string> = {}\n if (isPost) headers['Content-Type'] = 'application/json'\n return headers\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Read endpoints\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Fetch booking types.\n * - With apiKey → GET /sync/widget/types\n * - With orgSlug → GET /sync/public/:org/types\n */\nexport async function fetchBookingTypes(\n orgSlug?: string,\n apiUrl?: string,\n apiKey?: string,\n): Promise<BookingType[]> {\n const cfg = getApiConfig()\n const url = apiUrl || cfg.apiUrl\n const key = apiKey || cfg.apiKey\n\n const endpoint = key\n ? `${url}/sync/widget/types`\n : `${url}/sync/public/${orgSlug}/types`\n\n const response = await sonorFetch(endpoint, { headers: buildHeaders() }, { apiKey: key, retries: 0 })\n \n if (!response.ok) {\n const msg = await response.json().catch(() => ({ message: response.statusText }))\n const detail = (msg && typeof msg.message === 'string') ? msg.message : response.statusText\n throw new Error(`Failed to fetch booking types: ${response.status} ${detail}`)\n }\n \n const data = await response.json()\n return data.types || []\n}\n\n/**\n * Fetch booking type details\n */\nexport async function fetchBookingTypeDetails(\n typeSlug: string,\n orgSlug?: string,\n apiUrl?: string,\n apiKey?: string,\n): Promise<BookingType> {\n const cfg = getApiConfig()\n const url = apiUrl || cfg.apiUrl\n const key = apiKey || cfg.apiKey\n\n const endpoint = key\n ? `${url}/sync/widget/types/${typeSlug}`\n : `${url}/sync/public/${orgSlug}/types/${typeSlug}`\n\n const response = await sonorFetch(endpoint, { headers: buildHeaders() }, { apiKey: key, retries: 0 })\n \n if (!response.ok) {\n const msg = await response.json().catch(() => ({ message: response.statusText }))\n const detail = (msg && typeof msg.message === 'string') ? msg.message : response.statusText\n throw new Error(`Failed to fetch booking type: ${response.status} ${detail}`)\n }\n \n return response.json()\n}\n\n/**\n * Fetch available time slots for a specific date\n */\nexport async function fetchAvailability(\n typeSlug: string,\n date: string, // YYYY-MM-DD format\n orgSlug?: string,\n apiUrl?: string,\n apiKey?: string,\n timezone?: string,\n hostId?: string,\n): Promise<TimeSlot[]> {\n const cfg = getApiConfig()\n const url = apiUrl || cfg.apiUrl\n const key = apiKey || cfg.apiKey\n\n const params = new URLSearchParams({ date })\n if (timezone) params.append('timezone', timezone)\n if (hostId) params.append('hostId', hostId)\n\n const endpoint = key\n ? `${url}/sync/widget/availability/${typeSlug}?${params}`\n : `${url}/sync/public/${orgSlug}/availability/${typeSlug}?${params}`\n\n const response = await sonorFetch(endpoint, { headers: buildHeaders() }, { apiKey: key, retries: 0 })\n \n if (!response.ok) {\n const msg = await response.json().catch(() => ({ message: response.statusText }))\n let detail = (msg && typeof msg.message === 'string') ? String(msg.message).trim() : (response.statusText || '').trim()\n // Avoid \"404 404\": blank when detail is just the status code or only digits\n if (detail === String(response.status) || /^\\d+$/.test(detail)) detail = ''\n const rest = detail ? `${response.status} ${detail}` : String(response.status)\n const fallback =\n response.status === 404 && !detail\n ? 'No times available. In the Portal, check Sync → Booking Types (Schedule a Tour) has a host assigned and the project API key is set for this site.'\n : null\n throw new Error(fallback || `Failed to fetch availability: ${rest}`.trim())\n }\n \n const data = await response.json()\n const raw = data.slots || []\n // Normalize API shape (startTime/endTime, no available) to widget shape (start/end, available)\n return raw.map((slot: Record<string, unknown>) => ({\n start: slot.startTime ?? slot.start,\n end: slot.endTime ?? slot.end,\n hostId: slot.hostId,\n available: slot.available !== false,\n })) as TimeSlot[]\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Write endpoints\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Hold a time slot temporarily (5-10 minutes)\n */\nexport async function createSlotHold(\n holdData: {\n bookingType: string\n slotStart: string\n slotEnd: string\n hostId: string\n sessionId: string\n guestEmail?: string\n },\n apiUrl?: string,\n apiKey?: string,\n): Promise<SlotHold> {\n const cfg = getApiConfig()\n const url = apiUrl || cfg.apiUrl\n const key = apiKey || cfg.apiKey\n\n const endpoint = key\n ? `${url}/sync/widget/hold`\n : `${url}/sync/public/hold`\n\n const response = await sonorFetch(endpoint, {\n method: 'POST',\n headers: buildHeaders(true),\n body: JSON.stringify(holdData),\n }, { apiKey: key, retries: 0 })\n\n if (!response.ok) {\n throw new Error(`Failed to hold slot: ${response.statusText}`)\n }\n \n return response.json()\n}\n\n/**\n * Release a slot hold\n */\nexport async function releaseSlotHold(\n holdId: string,\n apiUrl?: string,\n apiKey?: string,\n): Promise<void> {\n const cfg = getApiConfig()\n const url = apiUrl || cfg.apiUrl\n const key = apiKey || cfg.apiKey\n\n const endpoint = key\n ? `${url}/sync/widget/hold/${holdId}`\n : `${url}/sync/public/hold/${holdId}`\n\n await sonorFetch(endpoint, {\n method: 'DELETE',\n headers: buildHeaders(),\n }, { apiKey: key, retries: 0 })\n}\n\n/**\n * Create a booking\n */\nexport async function createBooking(\n bookingData: {\n bookingType: string\n scheduledAt: string\n hostId: string\n name: string\n email: string\n phone?: string\n company?: string\n message?: string\n source: string\n timezone?: string\n holdId?: string\n sessionId?: string\n sourceUrl?: string\n },\n apiUrl?: string,\n apiKey?: string,\n): Promise<BookingResult> {\n const cfg = getApiConfig()\n const url = apiUrl || cfg.apiUrl\n const key = apiKey || cfg.apiKey\n\n const endpoint = key\n ? `${url}/sync/widget/booking`\n : `${url}/sync/public/booking`\n\n const response = await sonorFetch(endpoint, {\n method: 'POST',\n headers: buildHeaders(true),\n body: JSON.stringify(bookingData),\n }, { apiKey: key, retries: 0 })\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}))\n throw new Error(errorData.message || `Failed to create booking: ${response.statusText}`)\n }\n \n return response.json()\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Utility helpers\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Get available dates for a month (helper for calendar view)\n * Returns dates that have at least one available slot\n */\nexport async function fetchAvailableDates(\n typeSlug: string,\n startDate: string, // YYYY-MM-DD\n endDate: string, // YYYY-MM-DD\n orgSlug?: string,\n apiUrl?: string,\n apiKey?: string,\n timezone?: string,\n): Promise<string[]> {\n const availableDates: string[] = []\n const start = new Date(startDate)\n const end = new Date(endDate)\n \n const current = new Date(start)\n while (current <= end) {\n const dateStr = current.toISOString().split('T')[0]\n \n try {\n const slots = await fetchAvailability(typeSlug, dateStr, orgSlug, apiUrl, apiKey, timezone)\n if (slots.some(s => s.available)) {\n availableDates.push(dateStr)\n }\n } catch {\n // Skip dates that fail to load\n }\n \n current.setDate(current.getDate() + 1)\n }\n \n return availableDates\n}\n\n/**\n * Detect user's timezone\n */\nexport function detectTimezone(): string {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone\n } catch {\n return 'America/New_York'\n }\n}\n\n/**\n * Format time for display\n */\nexport function formatTime(isoString: string, timezone: string): string {\n const date = new Date(isoString)\n return date.toLocaleTimeString('en-US', {\n hour: 'numeric',\n minute: '2-digit',\n hour12: true,\n timeZone: timezone,\n })\n}\n\n/**\n * Format date for display\n */\nexport function formatDate(isoString: string, timezone: string): string {\n const date = new Date(isoString)\n return date.toLocaleDateString('en-US', {\n weekday: 'long',\n month: 'long',\n day: 'numeric',\n year: 'numeric',\n timeZone: timezone,\n })\n}\n\n/**\n * Format duration for display\n */\nexport function formatDuration(minutes: number): string {\n if (minutes < 60) {\n return `${minutes} min`\n }\n const hours = Math.floor(minutes / 60)\n const mins = minutes % 60\n if (mins === 0) {\n return `${hours} hour${hours > 1 ? 's' : ''}`\n }\n return `${hours}h ${mins}m`\n}\n","'use client'\n\n/**\n * BookingWidget - Premium embeddable booking widget for client sites\n *\n * Calendly-inspired scheduling experience:\n * 1. Full month calendar for date selection\n * 2. Scrollable time-slot column\n * 3. Polished guest information form\n * 4. Animated booking confirmation\n *\n * Ships with self-contained CSS (no external deps) so it works on any site.\n *\n * @example\n * ```tsx\n * import { BookingWidget } from '@sonordev/site-kit'\n *\n * <BookingWidget\n * orgSlug=\"manhattan-development-group\"\n * bookingTypeSlug=\"schedule-a-tour\"\n * hideTypeSelector\n * onBookingComplete={(r) => console.log(r)}\n * />\n * ```\n */\n\nimport * as React from 'react'\nimport { useState, useEffect, useCallback, useMemo, useRef } from 'react'\nimport type {\n BookingWidgetProps,\n BookingType,\n TimeSlot,\n GuestInfo,\n BookingResult,\n SlotHold,\n} from './types'\nimport {\n fetchBookingTypes,\n fetchBookingTypeDetails,\n fetchAvailability,\n createSlotHold,\n releaseSlotHold,\n createBooking,\n detectTimezone,\n formatTime,\n formatDate,\n formatDuration,\n} from './api'\n\n// ─── Constants ─────────────────────────────────────────────────────────────────\n\nconst DEFAULT_API_URL = 'https://api.sonor.io'\nconst DAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] as const\nconst MONTHS = [\n 'January','February','March','April','May','June',\n 'July','August','September','October','November','December',\n] as const\n\ntype BookingStep = 'type' | 'datetime' | 'form' | 'success'\n\n// ─── Helpers ───────────────────────────────────────────────────────────────────\n\nfunction isSameDay(a: Date, b: Date) {\n return (\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n )\n}\n\nfunction isBeforeDay(a: Date, b: Date) {\n const ac = new Date(a.getFullYear(), a.getMonth(), a.getDate())\n const bc = new Date(b.getFullYear(), b.getMonth(), b.getDate())\n return ac < bc\n}\n\nfunction calendarDays(year: number, month: number): (Date | null)[] {\n const first = new Date(year, month, 1)\n const last = new Date(year, month + 1, 0)\n const cells: (Date | null)[] = []\n for (let i = 0; i < first.getDay(); i++) cells.push(null) // leading blanks\n for (let d = 1; d <= last.getDate(); d++) cells.push(new Date(year, month, d))\n return cells\n}\n\n// ─── SVG Icons (inline, no deps) ──────────────────────────────────────────────\n\nfunction ChevronLeft() {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12.5 15L7.5 10L12.5 5\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\"/>\n </svg>\n )\n}\n\nfunction ChevronRight() {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M7.5 5L12.5 10L7.5 15\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\"/>\n </svg>\n )\n}\n\nfunction ClockIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"8\" cy=\"8\" r=\"6.5\" stroke=\"currentColor\" strokeWidth=\"1.2\"/>\n <path d=\"M8 4.5V8L10 10\" stroke=\"currentColor\" strokeWidth=\"1.2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"/>\n </svg>\n )\n}\n\nfunction GlobeIcon() {\n return (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"8\" cy=\"8\" r=\"6.5\" stroke=\"currentColor\" strokeWidth=\"1.2\"/>\n <path d=\"M1.5 8H14.5\" stroke=\"currentColor\" strokeWidth=\"1.2\"/>\n <path d=\"M8 1.5C9.66 3.34 10.61 5.62 10.61 8C10.61 10.38 9.66 12.66 8 14.5C6.34 12.66 5.39 10.38 5.39 8C5.39 5.62 6.34 3.34 8 1.5Z\" stroke=\"currentColor\" strokeWidth=\"1.2\"/>\n </svg>\n )\n}\n\nfunction CheckCircleIcon() {\n return (\n <svg width=\"56\" height=\"56\" viewBox=\"0 0 56 56\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"28\" cy=\"28\" r=\"28\" fill=\"var(--sk-primary)\"/>\n <path d=\"M18 28.5L24.5 35L38 21.5\" stroke=\"white\" strokeWidth=\"3\" strokeLinecap=\"round\" strokeLinejoin=\"round\"/>\n </svg>\n )\n}\n\nfunction CalendarPlusIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"1.5\" y=\"2.5\" width=\"13\" height=\"12\" rx=\"1.5\" stroke=\"currentColor\" strokeWidth=\"1.2\"/>\n <path d=\"M1.5 6.5H14.5\" stroke=\"currentColor\" strokeWidth=\"1.2\"/>\n <path d=\"M5 1V4M11 1V4\" stroke=\"currentColor\" strokeWidth=\"1.2\" strokeLinecap=\"round\"/>\n <path d=\"M8 9V12M6.5 10.5H9.5\" stroke=\"currentColor\" strokeWidth=\"1.2\" strokeLinecap=\"round\"/>\n </svg>\n )\n}\n\nfunction ArrowLeftIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M10 3L5 8L10 13\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\"/>\n </svg>\n )\n}\n\nfunction SpinnerIcon() {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" className=\"bw-spinner\">\n <circle cx=\"10\" cy=\"10\" r=\"8\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeDasharray=\"50.265\" strokeDashoffset=\"25\" opacity=\"0.3\"/>\n <circle cx=\"10\" cy=\"10\" r=\"8\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeDasharray=\"50.265\" strokeDashoffset=\"37.7\"/>\n </svg>\n )\n}\n\n// ─── Component ─────────────────────────────────────────────────────────────────\n\nexport function BookingWidget({\n orgSlug,\n apiKey: propApiKey,\n apiUrl: propApiUrl,\n bookingTypeSlug,\n timezone: propTimezone,\n className = '',\n daysToShow = 60,\n onBookingComplete,\n onError,\n hideTypeSelector = false,\n styles = {},\n}: BookingWidgetProps) {\n // Resolve API key: prop > window global\n const apiKey = propApiKey || (typeof window !== 'undefined' ? (window as any).__SITE_KIT_API_KEY__ : undefined)\n const apiUrl = propApiUrl || (typeof window !== 'undefined' ? (window as any).__SITE_KIT_API_URL__ : undefined) || DEFAULT_API_URL\n // ── State ──\n const [step, setStep] = useState<BookingStep>(bookingTypeSlug ? 'datetime' : 'type')\n const [loading, setLoading] = useState(false)\n const [slotsLoading, setSlotsLoading] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n const [bookingTypes, setBookingTypes] = useState<BookingType[]>([])\n const [selectedType, setSelectedType] = useState<BookingType | null>(null)\n const [viewMonth, setViewMonth] = useState(() => new Date())\n const [selectedDate, setSelectedDate] = useState<Date | null>(null)\n const [slots, setSlots] = useState<TimeSlot[]>([])\n const [selectedSlot, setSelectedSlot] = useState<TimeSlot | null>(null)\n const [confirmedSlot, setConfirmedSlot] = useState(false)\n const [hold, setHold] = useState<SlotHold | null>(null)\n const [guestInfo, setGuestInfo] = useState<GuestInfo>({ name: '', email: '' })\n const [bookingResult, setBookingResult] = useState<BookingResult | null>(null)\n const [submitting, setSubmitting] = useState(false)\n\n const slotsRef = useRef<HTMLDivElement>(null)\n const today = useMemo(() => { const d = new Date(); d.setHours(0,0,0,0); return d }, [])\n const timezone = useMemo(() => propTimezone || detectTimezone(), [propTimezone])\n\n const shortTz = useMemo(() => {\n try {\n const parts = Intl.DateTimeFormat('en-US', { timeZone: timezone, timeZoneName: 'short' })\n .formatToParts(new Date())\n return parts.find(p => p.type === 'timeZoneName')?.value || timezone\n } catch { return timezone }\n }, [timezone])\n\n // Calendar grid for the current view month\n const days = useMemo(() => calendarDays(viewMonth.getFullYear(), viewMonth.getMonth()), [viewMonth])\n const maxDate = useMemo(() => { const d = new Date(today); d.setDate(d.getDate() + daysToShow); return d }, [today, daysToShow])\n\n // ── Data Loading ──\n\n useEffect(() => {\n if (bookingTypeSlug) {\n setLoading(true)\n fetchBookingTypeDetails(bookingTypeSlug, orgSlug, apiUrl, apiKey)\n .then(type => { setSelectedType(type); setStep('datetime') })\n .catch(err => { setError(err.message); onError?.(err) })\n .finally(() => setLoading(false))\n } else {\n setLoading(true)\n fetchBookingTypes(orgSlug, apiUrl, apiKey)\n .then(types => setBookingTypes(types.filter(t => t.is_active)))\n .catch(err => { setError(err.message); onError?.(err) })\n .finally(() => setLoading(false))\n }\n }, [orgSlug, apiKey, bookingTypeSlug, apiUrl, onError])\n\n useEffect(() => {\n if (!selectedDate || !selectedType) return\n const dateStr = selectedDate.toISOString().split('T')[0]\n setSlotsLoading(true)\n setSlots([])\n setSelectedSlot(null)\n setConfirmedSlot(false)\n\n fetchAvailability(selectedType.slug, dateStr, orgSlug, apiUrl, apiKey, timezone)\n .then(s => setSlots(s.filter(slot => slot.available)))\n .catch(err => { setError(err.message); onError?.(err) })\n .finally(() => setSlotsLoading(false))\n }, [selectedDate, selectedType, orgSlug, apiKey, apiUrl, timezone, onError])\n\n // ── Handlers ──\n\n const handleSlotSelect = useCallback((slot: TimeSlot) => {\n setSelectedSlot(slot)\n setConfirmedSlot(false)\n }, [])\n\n const handleSlotConfirm = useCallback(async () => {\n if (!selectedType || !selectedSlot) return\n if (hold) await releaseSlotHold(hold.holdId, apiUrl, apiKey).catch(() => {})\n\n setLoading(true)\n try {\n const newHold = await createSlotHold(\n {\n bookingType: selectedType.slug,\n slotStart: selectedSlot.start,\n slotEnd: selectedSlot.end,\n hostId: selectedSlot.hostId || '',\n sessionId: `bw-${Date.now()}`,\n },\n apiUrl,\n apiKey,\n )\n setHold(newHold)\n setConfirmedSlot(true)\n setStep('form')\n } catch (err: any) {\n setError(err.message)\n onError?.(err)\n } finally {\n setLoading(false)\n }\n }, [selectedType, selectedSlot, hold, timezone, apiUrl, apiKey, onError])\n\n const handleBookingSubmit = useCallback(async (e: React.FormEvent) => {\n e.preventDefault()\n if (!selectedType || !selectedSlot) return\n setSubmitting(true)\n setError(null)\n\n try {\n const result = await createBooking(\n {\n bookingType: selectedType.slug,\n scheduledAt: selectedSlot.start,\n hostId: selectedSlot.hostId || '',\n name: guestInfo.name,\n email: guestInfo.email,\n phone: guestInfo.phone,\n message: guestInfo.notes,\n source: 'main-site',\n timezone,\n holdId: hold?.holdId,\n sessionId: `bw-${Date.now()}`,\n sourceUrl: typeof window !== 'undefined' ? window.location.href : undefined,\n },\n apiUrl,\n apiKey,\n )\n setBookingResult(result)\n setStep('success')\n onBookingComplete?.(result)\n } catch (err: any) {\n setError(err.message)\n onError?.(err)\n } finally {\n setSubmitting(false)\n }\n }, [selectedType, selectedSlot, guestInfo, timezone, hold, apiUrl, apiKey, onBookingComplete, onError])\n\n useEffect(() => {\n return () => { if (hold) releaseSlotHold(hold.holdId, apiUrl, apiKey).catch(() => {}) }\n }, [hold, apiUrl, apiKey])\n\n // ── Month Navigation ──\n\n const canGoPrev = viewMonth.getFullYear() > today.getFullYear() || viewMonth.getMonth() > today.getMonth()\n const canGoNext = viewMonth < maxDate\n\n const goMonth = (dir: -1 | 1) => {\n setViewMonth(prev => new Date(prev.getFullYear(), prev.getMonth() + dir, 1))\n }\n\n // ── Group slots by morning/afternoon ──\n\n const groupedSlots = useMemo(() => {\n const morning: TimeSlot[] = []\n const afternoon: TimeSlot[] = []\n const evening: TimeSlot[] = []\n for (const s of slots) {\n const h = new Date(s.start).getHours()\n if (h < 12) morning.push(s)\n else if (h < 17) afternoon.push(s)\n else evening.push(s)\n }\n return { morning, afternoon, evening }\n }, [slots])\n\n // ── CSS vars ──\n\n const cssVars = {\n '--sk-primary': styles.primaryColor || '#0069ff',\n '--sk-primary-hover': styles.primaryColor\n ? `color-mix(in srgb, ${styles.primaryColor} 90%, black)`\n : '#0055d4',\n '--sk-primary-light': styles.primaryColor\n ? `color-mix(in srgb, ${styles.primaryColor} 12%, white)`\n : '#e8f1ff',\n '--sk-bg': styles.backgroundColor || '#ffffff',\n '--sk-bg-elevated': styles.elevatedColor || '#f9fafb',\n '--sk-surface': styles.surfaceColor || '#f3f4f6',\n '--sk-text-primary': styles.textPrimary || '#1a1a1a',\n '--sk-text-secondary': styles.textSecondary || '#6b7280',\n '--sk-text-tertiary': styles.textTertiary || '#9ca3af',\n '--sk-border': styles.borderColor || '#e5e7eb',\n '--sk-error': '#dc2626',\n '--sk-success': '#047857',\n '--sk-warning': '#b45309',\n '--sk-radius': styles.borderRadius || '8px',\n '--sk-font': styles.fontFamily || \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\",\n '--sk-input-border': styles.inputBorderColor || styles.borderColor || '#e5e7eb',\n '--sk-input-focus-ring': styles.primaryColor\n ? `color-mix(in srgb, ${styles.primaryColor} 12%, ${styles.backgroundColor || 'white'})`\n : '#e8f1ff',\n } as React.CSSProperties\n\n // ── Render ──\n\n return (\n <div className={`bw-root ${className}`} style={cssVars}>\n {/* Error Toast */}\n {error && (\n <div className=\"bw-error\" role=\"alert\">\n <span>{error}</span>\n <button onClick={() => setError(null)} aria-label=\"Dismiss error\">×</button>\n </div>\n )}\n\n {/* ───── Type Selection ───── */}\n {step === 'type' && !hideTypeSelector && (\n <div className=\"bw-step bw-fade-in\">\n <h2 className=\"bw-heading\">Select a Service</h2>\n {loading ? (\n <div className=\"bw-loading\"><SpinnerIcon /> Loading services...</div>\n ) : (\n <div className=\"bw-type-list\">\n {bookingTypes.map(type => (\n <button\n key={type.id}\n className=\"bw-type-card\"\n onClick={() => { setSelectedType(type); setStep('datetime') }}\n >\n <span className=\"bw-type-name\">{type.name}</span>\n {type.description && <span className=\"bw-type-desc\">{type.description}</span>}\n <span className=\"bw-type-meta\">\n <ClockIcon /> {formatDuration(type.duration_minutes)}\n {type.price_cents ? ` · $${(type.price_cents / 100).toFixed(2)}` : ' · Free'}\n {getLocationDisplay(type) ? ` · ${getLocationDisplay(type)!.label}` : ''}\n </span>\n </button>\n ))}\n </div>\n )}\n </div>\n )}\n\n {/* ───── Date & Time ───── */}\n {step === 'datetime' && selectedType && (\n <div className=\"bw-step bw-fade-in\">\n {/* Booking info header */}\n <div className=\"bw-info-header\">\n {!bookingTypeSlug && (\n <button className=\"bw-back\" onClick={() => { setSelectedType(null); setStep('type') }}>\n <ArrowLeftIcon />\n </button>\n )}\n <div>\n <h2 className=\"bw-heading\">{selectedType.name}</h2>\n <div className=\"bw-meta-row\">\n <span className=\"bw-badge\"><ClockIcon /> {formatDuration(selectedType.duration_minutes)}</span>\n <span className=\"bw-badge\"><GlobeIcon /> {shortTz}</span>\n <LocationBadge type={selectedType} />\n </div>\n </div>\n </div>\n\n <div className=\"bw-datetime-layout\">\n {/* Calendar */}\n <div className=\"bw-calendar\">\n <div className=\"bw-cal-header\">\n <button className=\"bw-cal-nav\" onClick={() => goMonth(-1)} disabled={!canGoPrev} aria-label=\"Previous month\">\n <ChevronLeft />\n </button>\n <span className=\"bw-cal-title\">{MONTHS[viewMonth.getMonth()]} {viewMonth.getFullYear()}</span>\n <button className=\"bw-cal-nav\" onClick={() => goMonth(1)} disabled={!canGoNext} aria-label=\"Next month\">\n <ChevronRight />\n </button>\n </div>\n <div className=\"bw-cal-weekdays\">\n {DAYS.map(d => <span key={d} className=\"bw-cal-wd\">{d}</span>)}\n </div>\n <div className=\"bw-cal-grid\">\n {days.map((date, i) => {\n if (!date) return <span key={`e-${i}`} className=\"bw-cal-empty\" />\n const past = isBeforeDay(date, today)\n const future = date > maxDate\n const disabled = past || future\n const sel = selectedDate && isSameDay(date, selectedDate)\n const isToday = isSameDay(date, today)\n return (\n <button\n key={date.toISOString()}\n className={`bw-cal-day${sel ? ' selected' : ''}${isToday ? ' today' : ''}${disabled ? ' disabled' : ''}`}\n onClick={() => !disabled && setSelectedDate(date)}\n disabled={disabled}\n aria-label={date.toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric' })}\n aria-pressed={sel || undefined}\n >\n {date.getDate()}\n </button>\n )\n })}\n </div>\n </div>\n\n {/* Time Slots (appear when date selected) */}\n <div className={`bw-times${selectedDate ? ' visible' : ''}`} ref={slotsRef}>\n {!selectedDate ? (\n <div className=\"bw-times-placeholder\">\n <CalendarPlusIcon />\n <span>Select a date to view available times</span>\n </div>\n ) : slotsLoading ? (\n <div className=\"bw-loading\"><SpinnerIcon /> Loading times...</div>\n ) : slots.length === 0 ? (\n <div className=\"bw-times-empty\">No available times on this date. Try another day.</div>\n ) : (\n <div className=\"bw-times-scroll\">\n <p className=\"bw-times-date\">\n {selectedDate.toLocaleDateString('en-US', { weekday: 'long', month: 'short', day: 'numeric' })}\n </p>\n {groupedSlots.morning.length > 0 && (\n <div className=\"bw-time-group\">\n <span className=\"bw-time-label\">Morning</span>\n {groupedSlots.morning.map(slot => (\n <TimeButton key={slot.start} slot={slot} selected={selectedSlot?.start === slot.start} confirmed={confirmedSlot && selectedSlot?.start === slot.start} onClick={() => handleSlotSelect(slot)} onConfirm={handleSlotConfirm} timezone={timezone} loading={loading} />\n ))}\n </div>\n )}\n {groupedSlots.afternoon.length > 0 && (\n <div className=\"bw-time-group\">\n <span className=\"bw-time-label\">Afternoon</span>\n {groupedSlots.afternoon.map(slot => (\n <TimeButton key={slot.start} slot={slot} selected={selectedSlot?.start === slot.start} confirmed={confirmedSlot && selectedSlot?.start === slot.start} onClick={() => handleSlotSelect(slot)} onConfirm={handleSlotConfirm} timezone={timezone} loading={loading} />\n ))}\n </div>\n )}\n {groupedSlots.evening.length > 0 && (\n <div className=\"bw-time-group\">\n <span className=\"bw-time-label\">Evening</span>\n {groupedSlots.evening.map(slot => (\n <TimeButton key={slot.start} slot={slot} selected={selectedSlot?.start === slot.start} confirmed={confirmedSlot && selectedSlot?.start === slot.start} onClick={() => handleSlotSelect(slot)} onConfirm={handleSlotConfirm} timezone={timezone} loading={loading} />\n ))}\n </div>\n )}\n {(groupedSlots.afternoon.length > 0 || groupedSlots.evening.length > 0) && (\n <p className=\"bw-times-scroll-hint\">Scroll for more times</p>\n )}\n </div>\n )}\n </div>\n </div>\n </div>\n )}\n\n {/* ───── Guest Form ───── */}\n {step === 'form' && selectedType && selectedSlot && (\n <div className=\"bw-step bw-fade-in\">\n <div className=\"bw-info-header\">\n <button className=\"bw-back\" onClick={() => setStep('datetime')}>\n <ArrowLeftIcon />\n </button>\n <div>\n <h2 className=\"bw-heading\">Your Details</h2>\n <div className=\"bw-meta-row\">\n <span className=\"bw-badge\"><ClockIcon /> {formatDuration(selectedType.duration_minutes)}</span>\n <span className=\"bw-badge-accent\">\n {formatDate(selectedSlot.start, timezone)} · {formatTime(selectedSlot.start, timezone)}\n </span>\n <LocationBadge type={selectedType} />\n </div>\n </div>\n </div>\n\n {hold && (\n <div className=\"bw-hold-notice\">\n <SpinnerIcon /> Slot held for you. Complete your details to confirm.\n </div>\n )}\n\n <form onSubmit={handleBookingSubmit} className=\"bw-form\">\n <div className=\"bw-field\">\n <label htmlFor=\"bw-name\">Name <span className=\"bw-req\">*</span></label>\n <input\n id=\"bw-name\"\n type=\"text\"\n required\n value={guestInfo.name}\n onChange={e => setGuestInfo(p => ({ ...p, name: e.target.value }))}\n placeholder=\"Jane Smith\"\n autoComplete=\"name\"\n />\n </div>\n <div className=\"bw-field\">\n <label htmlFor=\"bw-email\">Email <span className=\"bw-req\">*</span></label>\n <input\n id=\"bw-email\"\n type=\"email\"\n required\n value={guestInfo.email}\n onChange={e => setGuestInfo(p => ({ ...p, email: e.target.value }))}\n placeholder=\"jane@example.com\"\n autoComplete=\"email\"\n />\n </div>\n <div className=\"bw-field\">\n <label htmlFor=\"bw-phone\">Phone</label>\n <input\n id=\"bw-phone\"\n type=\"tel\"\n value={guestInfo.phone || ''}\n onChange={e => setGuestInfo(p => ({ ...p, phone: e.target.value }))}\n placeholder=\"(555) 123-4567\"\n autoComplete=\"tel\"\n />\n </div>\n <div className=\"bw-field\">\n <label htmlFor=\"bw-notes\">Notes</label>\n <textarea\n id=\"bw-notes\"\n value={guestInfo.notes || ''}\n onChange={e => setGuestInfo(p => ({ ...p, notes: e.target.value }))}\n placeholder=\"Anything you'd like us to know...\"\n rows={3}\n />\n </div>\n <button type=\"submit\" className=\"bw-submit\" disabled={submitting || !guestInfo.name || !guestInfo.email}>\n {submitting ? <><SpinnerIcon /> Confirming...</> : 'Confirm Booking'}\n </button>\n </form>\n </div>\n )}\n\n {/* ───── Success ───── */}\n {step === 'success' && bookingResult && (\n <div className=\"bw-step bw-fade-in bw-success\">\n <div className=\"bw-success-icon\"><CheckCircleIcon /></div>\n <h2 className=\"bw-heading\">You’re Booked!</h2>\n\n <div className=\"bw-details-card\">\n <div className=\"bw-detail-row\">\n <span className=\"bw-detail-label\">When</span>\n <span className=\"bw-detail-value\">\n {formatDate(selectedSlot?.start || bookingResult.booking.scheduledAt || '', timezone)}<br/>\n {formatTime(selectedSlot?.start || bookingResult.booking.scheduledAt || '', timezone)} ({shortTz})\n </span>\n </div>\n <div className=\"bw-detail-row\">\n <span className=\"bw-detail-label\">Duration</span>\n <span className=\"bw-detail-value\">{formatDuration(selectedType?.duration_minutes ?? bookingResult.booking.durationMinutes ?? 0)}</span>\n </div>\n {bookingResult.booking.hostName && (\n <div className=\"bw-detail-row\">\n <span className=\"bw-detail-label\">With</span>\n <span className=\"bw-detail-value\">{bookingResult.booking.hostName}</span>\n </div>\n )}\n <LocationRow type={selectedType} />\n </div>\n\n <p className=\"bw-email-notice\">We’ve emailed your confirmation to <strong>{guestInfo.email}</strong> with everything you need.</p>\n\n <p className=\"bw-cal-links-label\">Add to your calendar</p>\n <div className=\"bw-cal-links\">\n <a href={bookingResult.calendarLinks.google} target=\"_blank\" rel=\"noopener noreferrer\" className=\"bw-cal-link\">\n <CalendarPlusIcon /> Google\n </a>\n <a href={bookingResult.calendarLinks.outlook} target=\"_blank\" rel=\"noopener noreferrer\" className=\"bw-cal-link\">\n <CalendarPlusIcon /> Outlook\n </a>\n <a href={bookingResult.calendarLinks.ics} download className=\"bw-cal-link\">\n <CalendarPlusIcon /> iCal\n </a>\n </div>\n\n {(bookingResult.rescheduleUrl || bookingResult.cancelUrl) && (\n <p className=\"bw-manage-links\">\n Need to change it?{' '}\n {bookingResult.rescheduleUrl && (\n <a href={bookingResult.rescheduleUrl} target=\"_blank\" rel=\"noopener noreferrer\">Reschedule</a>\n )}\n {bookingResult.rescheduleUrl && bookingResult.cancelUrl && ' · '}\n {bookingResult.cancelUrl && (\n <a href={bookingResult.cancelUrl} target=\"_blank\" rel=\"noopener noreferrer\">Cancel</a>\n )}\n </p>\n )}\n\n {(bookingResult.confirmationCode || bookingResult.booking.confirmationCode) && (\n <p className=\"bw-conf-code\">Confirmation code: <strong>{bookingResult.confirmationCode || bookingResult.booking.confirmationCode}</strong></p>\n )}\n </div>\n )}\n\n {/* Loading overlay for initial type load */}\n {loading && step === 'datetime' && !selectedType && (\n <div className=\"bw-loading\"><SpinnerIcon /> Loading...</div>\n )}\n\n <style>{WIDGET_CSS}</style>\n </div>\n )\n}\n\n// ─── Location display helper + sub-components ──────────────────────────────────\n\ntype LocationDisplay = { kind: string; label: string; detail?: string; mapUrl?: string }\n\nfunction getLocationDisplay(type: BookingType | null): LocationDisplay | null {\n if (!type) return null\n const details = type.location_details?.trim() || undefined\n switch (type.location_type) {\n case 'in_person':\n return {\n kind: 'in_person',\n label: 'In person',\n detail: details,\n mapUrl: details\n ? `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(details)}`\n : undefined,\n }\n case 'phone':\n return { kind: 'phone', label: 'Phone call', detail: details ? `We'll call you at ${details}` : \"We'll call you\" }\n case 'custom':\n return { kind: 'custom', label: details || 'See details' }\n case 'virtual':\n default:\n return { kind: 'virtual', label: 'Video call' }\n }\n}\n\nfunction LocationBadge({ type }: { type: BookingType | null }) {\n const loc = getLocationDisplay(type)\n if (!loc) return null\n return <span className=\"bw-badge\"><MapPinIcon /> {loc.label}</span>\n}\n\nfunction LocationRow({ type }: { type: BookingType | null }) {\n const loc = getLocationDisplay(type)\n if (!loc) return null\n return (\n <div className=\"bw-detail-row\">\n <span className=\"bw-detail-label\">Where</span>\n <span className=\"bw-detail-value\">\n {loc.label}\n {loc.detail ? <><br />{loc.detail}</> : null}\n {loc.mapUrl ? (\n <><br /><a href={loc.mapUrl} target=\"_blank\" rel=\"noopener noreferrer\" className=\"bw-where-link\">Get directions →</a></>\n ) : null}\n {loc.kind === 'virtual' ? (\n <><br /><span className=\"bw-where-muted\">Video link is in your confirmation email.</span></>\n ) : null}\n </span>\n </div>\n )\n}\n\nfunction MapPinIcon() {\n return (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z\" />\n <circle cx=\"12\" cy=\"10\" r=\"3\" />\n </svg>\n )\n}\n\n// ─── TimeButton Sub-component ──────────────────────────────────────────────────\n\nfunction TimeButton({\n slot, selected, confirmed, onClick, onConfirm, timezone, loading,\n}: {\n slot: TimeSlot; selected: boolean; confirmed: boolean; onClick: () => void; onConfirm: () => void; timezone: string; loading: boolean\n}) {\n if (selected && !confirmed) {\n return (\n <div className=\"bw-time-btn-wrap selected\">\n <span className=\"bw-time-text\">{formatTime(slot.start, timezone)}</span>\n <button className=\"bw-time-confirm\" onClick={onConfirm} disabled={loading}>\n {loading ? <SpinnerIcon /> : 'Confirm'}\n </button>\n </div>\n )\n }\n return (\n <button className={`bw-time-btn${selected ? ' selected' : ''}`} onClick={onClick} disabled={loading}>\n {formatTime(slot.start, timezone)}\n </button>\n )\n}\n\n// ─── Styles ────────────────────────────────────────────────────────────────────\n\nconst WIDGET_CSS = `\n/* ── Base ── */\n.bw-root {\n font-family: var(--sk-font);\n color: var(--sk-text-primary);\n line-height: 1.5;\n -webkit-font-smoothing: antialiased;\n box-sizing: border-box;\n isolation: isolate;\n}\n.bw-root *, .bw-root *::before, .bw-root *::after { box-sizing: border-box; }\n\n/* ── Animation ── */\n@keyframes bw-fade-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }\n@keyframes bw-spin { to { transform: rotate(360deg); } }\n.bw-fade-in { animation: bw-fade-in 0.25s ease-out; }\n.bw-spinner { animation: bw-spin 0.8s linear infinite; }\n\n/* ── Error ── */\n.bw-error {\n display: flex; align-items: center; justify-content: space-between; gap: 12px;\n background: #fef2f2; border: 1px solid #fecaca; color: #b91c1c;\n padding: 10px 14px; border-radius: var(--sk-radius); margin-bottom: 16px; font-size: 0.875rem;\n}\n.bw-error button { background: none; border: none; color: inherit; cursor: pointer; font-size: 1.25rem; line-height: 1; padding: 0; }\n\n/* ── Headings ── */\n.bw-heading { font-size: 1.125rem; font-weight: 600; margin: 0; letter-spacing: -0.01em; }\n.bw-meta-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 6px; }\n.bw-badge {\n display: inline-flex; align-items: center; gap: 4px;\n font-size: 0.8125rem; color: var(--sk-text-secondary); font-weight: 400;\n}\n.bw-badge-accent {\n display: inline-flex; align-items: center; gap: 4px;\n font-size: 0.8125rem; color: var(--sk-primary); font-weight: 500;\n}\n\n/* ── Info Header ── */\n.bw-info-header { display: flex; align-items: flex-start; gap: 8px; margin-bottom: 20px; }\n.bw-back {\n display: inline-flex; align-items: center; justify-content: center;\n width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--sk-border);\n background: var(--sk-bg); cursor: pointer; color: var(--sk-text-secondary); flex-shrink: 0; margin-top: 1px;\n transition: all 0.15s;\n}\n.bw-back:hover { background: var(--sk-surface); border-color: var(--sk-border); }\n\n/* ── Loading ── */\n.bw-loading {\n display: flex; align-items: center; justify-content: center; gap: 8px;\n padding: 32px; color: var(--sk-text-secondary); font-size: 0.875rem;\n}\n\n/* ── Type Selection ── */\n.bw-type-list { display: flex; flex-direction: column; gap: 10px; }\n.bw-type-card {\n display: flex; flex-direction: column; text-align: left; gap: 4px;\n padding: 16px; border: 1.5px solid var(--sk-border); border-radius: var(--sk-radius);\n background: var(--sk-bg); cursor: pointer; transition: all 0.15s;\n}\n.bw-type-card:hover { border-color: var(--sk-primary); box-shadow: 0 0 0 3px var(--sk-primary-light); }\n.bw-type-name { font-weight: 600; font-size: 0.9375rem; }\n.bw-type-desc { color: var(--sk-text-secondary); font-size: 0.8125rem; }\n.bw-type-meta { display: flex; align-items: center; gap: 4px; font-size: 0.8125rem; color: var(--sk-text-tertiary); margin-top: 4px; }\n\n/* ── Date-Time Layout ── */\n.bw-datetime-layout {\n display: flex; gap: 0; border-top: 1px solid var(--sk-border); padding-top: 16px;\n}\n@media (max-width: 559px) {\n .bw-datetime-layout { flex-direction: column; }\n}\n@media (min-width: 560px) {\n .bw-datetime-layout { min-height: 400px; }\n .bw-calendar { flex: 1 1 auto; padding-right: 16px; border-right: 1px solid var(--sk-border); }\n .bw-times { width: 180px; flex-shrink: 0; padding-left: 16px; }\n}\n\n/* ── Calendar ── */\n.bw-cal-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }\n.bw-cal-title { font-weight: 600; font-size: 0.9375rem; color: var(--sk-text-primary); }\n.bw-cal-nav {\n display: inline-flex; align-items: center; justify-content: center;\n width: 32px; height: 32px; border-radius: 50%; border: none;\n background: transparent; cursor: pointer; color: var(--sk-text-primary); transition: background 0.15s;\n}\n.bw-cal-nav:hover:not(:disabled) { background: var(--sk-surface); }\n.bw-cal-nav:disabled { opacity: 0.25; cursor: default; }\n\n.bw-cal-weekdays { display: grid; grid-template-columns: repeat(7, 1fr); gap: 0; text-align: center; margin-bottom: 4px; }\n.bw-cal-wd { font-size: 0.6875rem; font-weight: 600; color: var(--sk-text-tertiary); text-transform: uppercase; letter-spacing: 0.04em; padding: 4px 0; }\n\n.bw-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }\n.bw-cal-empty { aspect-ratio: 1; }\n.bw-cal-day {\n aspect-ratio: 1; display: flex; align-items: center; justify-content: center;\n border: none; background: none; border-radius: 50%;\n font-size: 0.8125rem; font-weight: 500; cursor: pointer;\n color: var(--sk-text-primary); transition: all 0.15s; position: relative;\n}\n.bw-cal-day:hover:not(.disabled):not(.selected) { background: var(--sk-surface); }\n.bw-cal-day.today:not(.selected)::after {\n content: ''; position: absolute; bottom: 3px; left: 50%; transform: translateX(-50%);\n width: 4px; height: 4px; border-radius: 50%; background: var(--sk-primary);\n}\n.bw-cal-day.selected {\n background: var(--sk-primary); color: #fff; font-weight: 600;\n}\n/* Past / out-of-range: visible on light and dark parent pages */\n.bw-root button.bw-cal-day.disabled {\n color: var(--sk-text-tertiary);\n cursor: default;\n opacity: 1;\n}\n\n/* ── Time Slots ── */\n.bw-times { transition: opacity 0.2s; }\n.bw-times:not(.visible) { opacity: 0.5; }\n.bw-times.visible { opacity: 1; }\n.bw-times-placeholder {\n display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;\n height: 100%; min-height: 160px; color: var(--sk-text-tertiary); font-size: 0.8125rem; text-align: center; padding: 16px;\n}\n.bw-times-empty {\n display: flex; align-items: center; justify-content: center;\n height: 100%; min-height: 160px; color: var(--sk-text-tertiary); font-size: 0.8125rem; text-align: center; padding: 16px;\n}\n.bw-times-scroll { overflow-y: auto; max-height: 400px; overflow-x: hidden; }\n.bw-times-date { font-weight: 600; font-size: 0.8125rem; color: var(--sk-text-primary); margin: 0 0 12px 0; }\n.bw-time-group { margin-bottom: 16px; }\n.bw-times-scroll-hint {\n font-size: 0.6875rem; color: var(--sk-text-tertiary); text-align: center; margin: 8px 0 0 0; padding-bottom: 8px;\n}\n.bw-time-label { display: block; font-size: 0.6875rem; font-weight: 600; color: var(--sk-text-tertiary); text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 6px; }\n\n.bw-time-btn {\n display: block; width: 100%;\n padding: 10px 12px; margin-bottom: 6px;\n border: 1.5px solid var(--sk-border); border-radius: var(--sk-radius);\n background: var(--sk-bg); cursor: pointer;\n font-size: 0.875rem; font-weight: 500; color: var(--sk-primary); text-align: center;\n transition: all 0.15s;\n}\n.bw-time-btn:hover:not(:disabled) {\n border-color: var(--sk-primary); background: var(--sk-primary-light);\n}\n.bw-time-btn.selected {\n border-color: var(--sk-primary); background: var(--sk-primary); color: #fff;\n}\n.bw-time-btn:disabled { opacity: 0.5; cursor: not-allowed; }\n\n.bw-time-btn-wrap {\n display: flex; align-items: center; gap: 6px; margin-bottom: 6px;\n border: 1.5px solid var(--sk-primary); border-radius: var(--sk-radius); overflow: hidden;\n animation: bw-fade-in 0.15s ease-out;\n}\n.bw-time-btn-wrap .bw-time-text {\n flex: 1; padding: 10px 12px; font-size: 0.875rem; font-weight: 500; color: var(--sk-text-primary); text-align: center;\n background: var(--sk-primary-light);\n}\n.bw-time-confirm {\n display: inline-flex; align-items: center; justify-content: center; gap: 4px;\n padding: 10px 16px; border: none;\n background: var(--sk-primary); color: #fff;\n font-size: 0.8125rem; font-weight: 600; cursor: pointer;\n transition: background 0.15s;\n}\n.bw-time-confirm:hover:not(:disabled) { background: var(--sk-primary-hover); }\n.bw-time-confirm:disabled { opacity: 0.7; cursor: not-allowed; }\n\n/* ── Form ── */\n.bw-hold-notice {\n display: flex; align-items: center; gap: 8px;\n background: var(--sk-primary-light); color: var(--sk-primary);\n padding: 10px 14px; border-radius: var(--sk-radius);\n font-size: 0.8125rem; font-weight: 500; margin-bottom: 20px;\n}\n.bw-form { display: flex; flex-direction: column; gap: 16px; }\n.bw-field label {\n display: block; font-size: 0.8125rem; font-weight: 500; color: var(--sk-text-primary); margin-bottom: 4px;\n}\n.bw-req { color: var(--sk-error); }\n.bw-field input, .bw-field textarea {\n display: block; width: 100%;\n padding: 10px 12px; border: 1.5px solid var(--sk-input-border); border-radius: var(--sk-radius);\n font-size: 0.9375rem; font-family: inherit; color: var(--sk-text-primary); background: var(--sk-bg);\n transition: border-color 0.15s, box-shadow 0.15s;\n}\n.bw-field input::placeholder, .bw-field textarea::placeholder { color: var(--sk-text-tertiary); }\n.bw-field input:focus, .bw-field textarea:focus {\n outline: none; border-color: var(--sk-primary);\n box-shadow: 0 0 0 3px var(--sk-input-focus-ring);\n}\n.bw-submit {\n display: inline-flex; align-items: center; justify-content: center; gap: 8px;\n width: 100%; padding: 14px; margin-top: 4px;\n background: var(--sk-primary); color: #fff; border: none;\n border-radius: var(--sk-radius); font-size: 0.9375rem; font-weight: 600;\n cursor: pointer; transition: background 0.15s;\n}\n.bw-submit:hover:not(:disabled) { background: var(--sk-primary-hover); }\n.bw-submit:disabled { opacity: 0.55; cursor: not-allowed; }\n\n/* ── Success ── */\n.bw-success { text-align: center; }\n.bw-success-icon { margin: 0 auto 16px; width: 56px; height: 56px; animation: bw-fade-in 0.4s ease-out; }\n.bw-conf-code {\n display: inline-block; font-family: 'SF Mono', 'Fira Code', monospace;\n background: var(--sk-surface); padding: 6px 14px; border-radius: 6px;\n font-size: 0.8125rem; color: var(--sk-text-secondary); margin: 4px 0 20px; letter-spacing: 0.04em;\n}\n\n.bw-details-card {\n text-align: left; background: var(--sk-bg-elevated); border: 1px solid var(--sk-border);\n border-radius: var(--sk-radius); padding: 16px; margin-bottom: 20px;\n}\n.bw-detail-row { display: flex; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--sk-border); }\n.bw-detail-row:last-child { border-bottom: none; }\n.bw-detail-label { width: 70px; flex-shrink: 0; font-size: 0.8125rem; color: var(--sk-text-tertiary); font-weight: 500; }\n.bw-detail-value { font-size: 0.875rem; font-weight: 500; color: var(--sk-text-primary); }\n\n.bw-cal-links-label { font-size: 0.8125rem; color: var(--sk-text-secondary); margin: 0 0 8px 0; }\n.bw-cal-links { display: flex; gap: 8px; justify-content: center; margin-bottom: 20px; flex-wrap: wrap; }\n.bw-cal-link {\n display: inline-flex; align-items: center; gap: 6px;\n padding: 8px 14px; border: 1.5px solid var(--sk-border); border-radius: var(--sk-radius);\n text-decoration: none; color: var(--sk-text-primary); font-size: 0.8125rem; font-weight: 500;\n transition: all 0.15s;\n}\n.bw-cal-link:hover { border-color: var(--sk-primary); color: var(--sk-primary); }\n\n.bw-email-notice { font-size: 0.8125rem; color: var(--sk-text-tertiary); margin: 0 0 16px 0; }\n.bw-email-notice strong { color: var(--sk-text-primary); font-weight: 500; }\n.bw-where-link { color: var(--sk-primary, #14B8A6); text-decoration: none; font-weight: 500; }\n.bw-where-muted { color: var(--sk-text-tertiary); font-size: 0.8125rem; }\n.bw-manage-links { font-size: 0.8125rem; color: var(--sk-text-tertiary); margin: 12px 0 0 0; }\n.bw-manage-links a { color: var(--sk-primary, #14B8A6); text-decoration: none; font-weight: 500; }\n`\n\nexport default BookingWidget\n"]}
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
|
|
4
4
|
var chunkHGNSJXWT_js = require('./chunk-HGNSJXWT.js');
|
|
5
5
|
var chunkQ2NBD54V_js = require('./chunk-Q2NBD54V.js');
|
|
6
|
-
var
|
|
7
|
-
var
|
|
6
|
+
var chunkGMSPDTEV_js = require('./chunk-GMSPDTEV.js');
|
|
7
|
+
var chunkWAAFJPNR_js = require('./chunk-WAAFJPNR.js');
|
|
8
8
|
var react = require('react');
|
|
9
9
|
|
|
10
10
|
// src/fleet/heartbeat.ts
|
|
@@ -18,14 +18,14 @@ async function sendFleetHeartbeat(opts) {
|
|
|
18
18
|
const { apiUrl, apiKey } = opts;
|
|
19
19
|
if (!apiUrl || !apiKey) return false;
|
|
20
20
|
const payload = chunkQ2NBD54V_js.buildFleetHeartbeatPayload({
|
|
21
|
-
kitVersion: opts.kitVersion ||
|
|
21
|
+
kitVersion: opts.kitVersion || chunkWAAFJPNR_js.SITE_KIT_VERSION,
|
|
22
22
|
nextVersion: opts.nextVersion,
|
|
23
23
|
modules: opts.modules,
|
|
24
24
|
site: opts.site,
|
|
25
25
|
source: opts.source
|
|
26
26
|
});
|
|
27
27
|
try {
|
|
28
|
-
const res = await
|
|
28
|
+
const res = await chunkGMSPDTEV_js.sonorFetch(
|
|
29
29
|
`${apiUrl.replace(/\/$/, "")}${FLEET_HEARTBEAT_PATH}`,
|
|
30
30
|
{
|
|
31
31
|
method: "POST",
|
|
@@ -70,7 +70,7 @@ function FleetHeartbeat({
|
|
|
70
70
|
if (!key) return;
|
|
71
71
|
const resolvedSite = site ?? w.__SITE_KIT_SITE__ ?? window.location.host ?? "";
|
|
72
72
|
if (oncePerSession) {
|
|
73
|
-
const stamp = `${
|
|
73
|
+
const stamp = `${chunkWAAFJPNR_js.SITE_KIT_VERSION}:${resolvedSite}`;
|
|
74
74
|
try {
|
|
75
75
|
if (sessionStorage.getItem(SESSION_GUARD_KEY) === stamp) {
|
|
76
76
|
sentRef.current = true;
|
|
@@ -98,5 +98,5 @@ exports.FLEET_HEARTBEAT_PATH = FLEET_HEARTBEAT_PATH;
|
|
|
98
98
|
exports.FleetHeartbeat = FleetHeartbeat;
|
|
99
99
|
exports.detectNextVersion = detectNextVersion;
|
|
100
100
|
exports.sendFleetHeartbeat = sendFleetHeartbeat;
|
|
101
|
-
//# sourceMappingURL=chunk-
|
|
102
|
-
//# sourceMappingURL=chunk-
|
|
101
|
+
//# sourceMappingURL=chunk-B5YNHSRA.js.map
|
|
102
|
+
//# sourceMappingURL=chunk-B5YNHSRA.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/fleet/heartbeat.ts","../src/fleet/FleetHeartbeat.tsx"],"names":["sanitizeFleetVersion","buildFleetHeartbeatPayload","SITE_KIT_VERSION","sonorFetch","useDeferredActivation","useRef","useEffect"],"mappings":"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","file":"chunk-5OWZUNNE.js","sourcesContent":["/**\n * @sonordev/site-kit/fleet — heartbeat sender (single source of truth for the POST)\n *\n * One place that turns fleet inputs into a validated payload and ships it to\n * `/api/public/fleet/heartbeat`. Used by BOTH the client component\n * (FleetHeartbeat) and any build-time caller, so the send path never forks.\n *\n * It routes through the canonical `sonorFetch` transport, which already stamps\n * the x-sitekit-version header, attaches x-api-key, and honors the auth\n * circuit breaker — a site on a stale/canceled key will not spam the API.\n */\n\nimport { sonorFetch } from '../shared/sonorFetch'\nimport { SITE_KIT_VERSION } from '../shared/version'\nimport {\n buildFleetHeartbeatPayload,\n sanitizeFleetVersion,\n type FleetHeartbeatPayload,\n type FleetHeartbeatSource,\n type FleetModule,\n} from './contract'\n\n/** Canonical ingest path — resolved against the site's Sonor API origin. */\nexport const FLEET_HEARTBEAT_PATH = '/api/public/fleet/heartbeat'\n\nexport interface SendFleetHeartbeatOptions {\n /** Sonor API origin (e.g. https://api.sonor.io). Trailing slash tolerated. */\n apiUrl: string\n /** Project API key — scopes the request; the project is resolved server-side. */\n apiKey: string\n /** Client-observable active modules (validated/deduped by the contract). */\n modules?: FleetModule[] | string[]\n /** Normalized host for the multi-site sub-dimension (server re-normalizes). */\n site?: string | null\n /** Installed Next.js version, if the caller can resolve it. */\n nextVersion?: string | null\n /** 'client' (runtime boot) or 'build' (CI). Default 'client'. */\n source?: FleetHeartbeatSource\n /** Override the reported kit version. Defaults to the runtime SITE_KIT_VERSION. */\n kitVersion?: string\n /** Log one info line with the result. Never logs at error level. */\n debug?: boolean\n}\n\n/**\n * Best-effort runtime detection of the host Next.js version. Unreliable by\n * design — Next does not expose its version consistently across app/pages\n * router — so it returns null unless a site injects `__SITE_KIT_NEXT_VERSION__`\n * or `window.next.version` is present. Build-time callers should pass\n * `nextVersion` explicitly (resolvable from `next/package.json`).\n */\nexport function detectNextVersion(): string | null {\n if (typeof window === 'undefined') return null\n const w = window as unknown as {\n __SITE_KIT_NEXT_VERSION__?: string\n next?: { version?: string }\n }\n return sanitizeFleetVersion(w.__SITE_KIT_NEXT_VERSION__ ?? w.next?.version ?? null)\n}\n\n/**\n * Fire one heartbeat. Fire-and-forget by contract: it never throws — a\n * telemetry POST must never break a visitor's page or a site's build. Returns\n * true only when the POST was accepted (2xx).\n */\nexport async function sendFleetHeartbeat(opts: SendFleetHeartbeatOptions): Promise<boolean> {\n const { apiUrl, apiKey } = opts\n if (!apiUrl || !apiKey) return false\n\n const payload: FleetHeartbeatPayload = buildFleetHeartbeatPayload({\n kitVersion: opts.kitVersion || SITE_KIT_VERSION,\n nextVersion: opts.nextVersion,\n modules: opts.modules,\n site: opts.site,\n source: opts.source,\n })\n\n try {\n const res = await sonorFetch(\n `${apiUrl.replace(/\\/$/, '')}${FLEET_HEARTBEAT_PATH}`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n },\n // retries: 0 — the once-per-session guard already bounds volume, and a\n // missed heartbeat is harmless (the next page load or passive\n // x-sitekit-version capture re-registers the site).\n { apiKey, retries: 0 },\n )\n if (opts.debug) {\n // info, never error: a visitor's console must stay clean (Lighthouse).\n console.info(\n `[Sonor fleet] heartbeat ${res.status} v${payload.kit_version} [${payload.modules.join(',') || 'none'}]`,\n )\n }\n return res.ok\n } catch (err) {\n if (opts.debug) console.info('[Sonor fleet] heartbeat skipped (network)', err)\n return false\n }\n}\n","/**\n * @sonordev/site-kit/fleet — FleetHeartbeat\n *\n * A childless, effect-only client component that reports this site's build\n * fingerprint (kit version, Next.js version, active modules, host) to Sonor\n * exactly once per browser session. It exists so the platform can answer\n * \"which version / modules / key state is each site running\" without shelling\n * into every client repo.\n *\n * It is mounted as a deferred, CHILDLESS SIBLING — never a wrapper — by\n * SiteKitClientProviders, behind the same idle/first-interaction gate as\n * Analytics and Engage, so it never enters the critical hydration path (see\n * CLAUDE.md \"the page must server-render\"). It renders null and carries no\n * visitor data.\n */\n\n'use client'\n\nimport { useEffect, useRef } from 'react'\nimport { useDeferredActivation } from '../shared/defer'\nimport { SITE_KIT_VERSION } from '../shared/version'\nimport { detectNextVersion, sendFleetHeartbeat } from './heartbeat'\nimport type { FleetModule } from './contract'\n\n/** Session guard key — one heartbeat per session, re-sent when version/host changes. */\nconst SESSION_GUARD_KEY = '_sk_fleet_hb'\n\nexport interface FleetHeartbeatProps {\n /** Sonor API origin. Falls back to `window.__SITE_KIT_API_URL__` then api.sonor.io. */\n apiUrl?: string\n /** Project API key. Falls back to `window.__SITE_KIT_API_KEY__`. */\n apiKey?: string\n /** Host for the multi-site sub-dimension. Falls back to `__SITE_KIT_SITE__` then location.host. */\n site?: string | null\n /** Client-observable active modules (SiteKitClientProviders passes the enabled set). */\n modules?: FleetModule[]\n /** Installed Next.js version if known; otherwise best-effort runtime detection. */\n nextVersion?: string | null\n /**\n * Self-defer to idle / first interaction. Default true so standalone use is\n * safe. SiteKitClientProviders already gates the mount and passes false.\n */\n defer?: boolean\n /** Send at most once per browser session per (version, host). Default true. */\n oncePerSession?: boolean\n debug?: boolean\n}\n\nexport function FleetHeartbeat({\n apiUrl,\n apiKey,\n site,\n modules,\n nextVersion,\n defer = true,\n oncePerSession = true,\n debug = false,\n}: FleetHeartbeatProps) {\n const ready = useDeferredActivation(defer)\n const sentRef = useRef(false)\n\n useEffect(() => {\n if (!ready || sentRef.current) return\n if (typeof window === 'undefined') return\n\n const w = window as unknown as {\n __SITE_KIT_API_URL__?: string\n __SITE_KIT_API_KEY__?: string\n __SITE_KIT_SITE__?: string\n }\n const url = apiUrl || w.__SITE_KIT_API_URL__ || 'https://api.sonor.io'\n const key = apiKey || w.__SITE_KIT_API_KEY__\n if (!key) return // no key resolvable — nothing to authenticate the heartbeat\n\n const resolvedSite = site ?? w.__SITE_KIT_SITE__ ?? window.location.host ?? ''\n\n // Once-per-session-per-(version,host): keeps heartbeat volume to one POST\n // per visitor session while still re-reporting after an upgrade or on a\n // different sub-site. Storage-disabled browsers simply send once per load.\n if (oncePerSession) {\n const stamp = `${SITE_KIT_VERSION}:${resolvedSite}`\n try {\n if (sessionStorage.getItem(SESSION_GUARD_KEY) === stamp) {\n sentRef.current = true\n return\n }\n sessionStorage.setItem(SESSION_GUARD_KEY, stamp)\n } catch {\n /* storage unavailable — fall through and send this load */\n }\n }\n\n sentRef.current = true\n void sendFleetHeartbeat({\n apiUrl: url,\n apiKey: key,\n site: resolvedSite,\n modules,\n nextVersion: nextVersion ?? detectNextVersion(),\n source: 'client',\n debug,\n })\n }, [ready, apiUrl, apiKey, site, modules, nextVersion, oncePerSession, debug])\n\n return null\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/fleet/heartbeat.ts","../src/fleet/FleetHeartbeat.tsx"],"names":["sanitizeFleetVersion","buildFleetHeartbeatPayload","SITE_KIT_VERSION","sonorFetch","useDeferredActivation","useRef","useEffect"],"mappings":"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","file":"chunk-B5YNHSRA.js","sourcesContent":["/**\n * @sonordev/site-kit/fleet — heartbeat sender (single source of truth for the POST)\n *\n * One place that turns fleet inputs into a validated payload and ships it to\n * `/api/public/fleet/heartbeat`. Used by BOTH the client component\n * (FleetHeartbeat) and any build-time caller, so the send path never forks.\n *\n * It routes through the canonical `sonorFetch` transport, which already stamps\n * the x-sitekit-version header, attaches x-api-key, and honors the auth\n * circuit breaker — a site on a stale/canceled key will not spam the API.\n */\n\nimport { sonorFetch } from '../shared/sonorFetch'\nimport { SITE_KIT_VERSION } from '../shared/version'\nimport {\n buildFleetHeartbeatPayload,\n sanitizeFleetVersion,\n type FleetHeartbeatPayload,\n type FleetHeartbeatSource,\n type FleetModule,\n} from './contract'\n\n/** Canonical ingest path — resolved against the site's Sonor API origin. */\nexport const FLEET_HEARTBEAT_PATH = '/api/public/fleet/heartbeat'\n\nexport interface SendFleetHeartbeatOptions {\n /** Sonor API origin (e.g. https://api.sonor.io). Trailing slash tolerated. */\n apiUrl: string\n /** Project API key — scopes the request; the project is resolved server-side. */\n apiKey: string\n /** Client-observable active modules (validated/deduped by the contract). */\n modules?: FleetModule[] | string[]\n /** Normalized host for the multi-site sub-dimension (server re-normalizes). */\n site?: string | null\n /** Installed Next.js version, if the caller can resolve it. */\n nextVersion?: string | null\n /** 'client' (runtime boot) or 'build' (CI). Default 'client'. */\n source?: FleetHeartbeatSource\n /** Override the reported kit version. Defaults to the runtime SITE_KIT_VERSION. */\n kitVersion?: string\n /** Log one info line with the result. Never logs at error level. */\n debug?: boolean\n}\n\n/**\n * Best-effort runtime detection of the host Next.js version. Unreliable by\n * design — Next does not expose its version consistently across app/pages\n * router — so it returns null unless a site injects `__SITE_KIT_NEXT_VERSION__`\n * or `window.next.version` is present. Build-time callers should pass\n * `nextVersion` explicitly (resolvable from `next/package.json`).\n */\nexport function detectNextVersion(): string | null {\n if (typeof window === 'undefined') return null\n const w = window as unknown as {\n __SITE_KIT_NEXT_VERSION__?: string\n next?: { version?: string }\n }\n return sanitizeFleetVersion(w.__SITE_KIT_NEXT_VERSION__ ?? w.next?.version ?? null)\n}\n\n/**\n * Fire one heartbeat. Fire-and-forget by contract: it never throws — a\n * telemetry POST must never break a visitor's page or a site's build. Returns\n * true only when the POST was accepted (2xx).\n */\nexport async function sendFleetHeartbeat(opts: SendFleetHeartbeatOptions): Promise<boolean> {\n const { apiUrl, apiKey } = opts\n if (!apiUrl || !apiKey) return false\n\n const payload: FleetHeartbeatPayload = buildFleetHeartbeatPayload({\n kitVersion: opts.kitVersion || SITE_KIT_VERSION,\n nextVersion: opts.nextVersion,\n modules: opts.modules,\n site: opts.site,\n source: opts.source,\n })\n\n try {\n const res = await sonorFetch(\n `${apiUrl.replace(/\\/$/, '')}${FLEET_HEARTBEAT_PATH}`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n },\n // retries: 0 — the once-per-session guard already bounds volume, and a\n // missed heartbeat is harmless (the next page load or passive\n // x-sitekit-version capture re-registers the site).\n { apiKey, retries: 0 },\n )\n if (opts.debug) {\n // info, never error: a visitor's console must stay clean (Lighthouse).\n console.info(\n `[Sonor fleet] heartbeat ${res.status} v${payload.kit_version} [${payload.modules.join(',') || 'none'}]`,\n )\n }\n return res.ok\n } catch (err) {\n if (opts.debug) console.info('[Sonor fleet] heartbeat skipped (network)', err)\n return false\n }\n}\n","/**\n * @sonordev/site-kit/fleet — FleetHeartbeat\n *\n * A childless, effect-only client component that reports this site's build\n * fingerprint (kit version, Next.js version, active modules, host) to Sonor\n * exactly once per browser session. It exists so the platform can answer\n * \"which version / modules / key state is each site running\" without shelling\n * into every client repo.\n *\n * It is mounted as a deferred, CHILDLESS SIBLING — never a wrapper — by\n * SiteKitClientProviders, behind the same idle/first-interaction gate as\n * Analytics and Engage, so it never enters the critical hydration path (see\n * CLAUDE.md \"the page must server-render\"). It renders null and carries no\n * visitor data.\n */\n\n'use client'\n\nimport { useEffect, useRef } from 'react'\nimport { useDeferredActivation } from '../shared/defer'\nimport { SITE_KIT_VERSION } from '../shared/version'\nimport { detectNextVersion, sendFleetHeartbeat } from './heartbeat'\nimport type { FleetModule } from './contract'\n\n/** Session guard key — one heartbeat per session, re-sent when version/host changes. */\nconst SESSION_GUARD_KEY = '_sk_fleet_hb'\n\nexport interface FleetHeartbeatProps {\n /** Sonor API origin. Falls back to `window.__SITE_KIT_API_URL__` then api.sonor.io. */\n apiUrl?: string\n /** Project API key. Falls back to `window.__SITE_KIT_API_KEY__`. */\n apiKey?: string\n /** Host for the multi-site sub-dimension. Falls back to `__SITE_KIT_SITE__` then location.host. */\n site?: string | null\n /** Client-observable active modules (SiteKitClientProviders passes the enabled set). */\n modules?: FleetModule[]\n /** Installed Next.js version if known; otherwise best-effort runtime detection. */\n nextVersion?: string | null\n /**\n * Self-defer to idle / first interaction. Default true so standalone use is\n * safe. SiteKitClientProviders already gates the mount and passes false.\n */\n defer?: boolean\n /** Send at most once per browser session per (version, host). Default true. */\n oncePerSession?: boolean\n debug?: boolean\n}\n\nexport function FleetHeartbeat({\n apiUrl,\n apiKey,\n site,\n modules,\n nextVersion,\n defer = true,\n oncePerSession = true,\n debug = false,\n}: FleetHeartbeatProps) {\n const ready = useDeferredActivation(defer)\n const sentRef = useRef(false)\n\n useEffect(() => {\n if (!ready || sentRef.current) return\n if (typeof window === 'undefined') return\n\n const w = window as unknown as {\n __SITE_KIT_API_URL__?: string\n __SITE_KIT_API_KEY__?: string\n __SITE_KIT_SITE__?: string\n }\n const url = apiUrl || w.__SITE_KIT_API_URL__ || 'https://api.sonor.io'\n const key = apiKey || w.__SITE_KIT_API_KEY__\n if (!key) return // no key resolvable — nothing to authenticate the heartbeat\n\n const resolvedSite = site ?? w.__SITE_KIT_SITE__ ?? window.location.host ?? ''\n\n // Once-per-session-per-(version,host): keeps heartbeat volume to one POST\n // per visitor session while still re-reporting after an upgrade or on a\n // different sub-site. Storage-disabled browsers simply send once per load.\n if (oncePerSession) {\n const stamp = `${SITE_KIT_VERSION}:${resolvedSite}`\n try {\n if (sessionStorage.getItem(SESSION_GUARD_KEY) === stamp) {\n sentRef.current = true\n return\n }\n sessionStorage.setItem(SESSION_GUARD_KEY, stamp)\n } catch {\n /* storage unavailable — fall through and send this load */\n }\n }\n\n sentRef.current = true\n void sendFleetHeartbeat({\n apiUrl: url,\n apiKey: key,\n site: resolvedSite,\n modules,\n nextVersion: nextVersion ?? detectNextVersion(),\n source: 'client',\n debug,\n })\n }, [ready, apiUrl, apiKey, site, modules, nextVersion, oncePerSession, debug])\n\n return null\n}\n"]}
|