@xenia-martech/sdk-js 1.2.0-dev.2 → 1.2.0-dev.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +6 -1
  2. package/dist/{actions-BcdlokGO.d.cts → actions-Bhji05Pe.d.cts} +15 -2
  3. package/dist/{actions-BcdlokGO.d.ts → actions-Bhji05Pe.d.ts} +15 -2
  4. package/dist/{api-CktVQ6Gl.d.ts → api-BqSvWgBZ.d.cts} +4 -2
  5. package/dist/{api-BEPW0Uan.d.cts → api-ByoECRhR.d.ts} +4 -2
  6. package/dist/{chunk-DWFVDNU5.js → chunk-INM2SPH4.js} +4 -4
  7. package/dist/chunk-INM2SPH4.js.map +1 -0
  8. package/dist/{chunk-7NGJC7CF.js → chunk-TGG5Y4QD.js} +17 -6
  9. package/dist/chunk-TGG5Y4QD.js.map +1 -0
  10. package/dist/{chunk-3PYPPIUM.cjs → chunk-TRRMMPBH.cjs} +13 -13
  11. package/dist/chunk-TRRMMPBH.cjs.map +1 -0
  12. package/dist/{chunk-IBNIRT7J.cjs → chunk-YZG6JR4E.cjs} +17 -6
  13. package/dist/chunk-YZG6JR4E.cjs.map +1 -0
  14. package/dist/client/index.cjs +16 -5
  15. package/dist/client/index.cjs.map +1 -1
  16. package/dist/client/index.d.cts +2 -2
  17. package/dist/client/index.d.ts +2 -2
  18. package/dist/client/index.js +16 -5
  19. package/dist/client/index.js.map +1 -1
  20. package/dist/client/react/index.cjs +19 -8
  21. package/dist/client/react/index.cjs.map +1 -1
  22. package/dist/client/react/index.d.cts +2 -2
  23. package/dist/client/react/index.d.ts +2 -2
  24. package/dist/client/react/index.js +19 -8
  25. package/dist/client/react/index.js.map +1 -1
  26. package/dist/cms/contentful.cjs +2 -1
  27. package/dist/cms/contentful.cjs.map +1 -1
  28. package/dist/cms/contentful.d.cts +1 -1
  29. package/dist/cms/contentful.d.ts +1 -1
  30. package/dist/cms/contentful.js +2 -1
  31. package/dist/cms/contentful.js.map +1 -1
  32. package/dist/{cookie-names-CLqtmGBM.d.ts → cookie-names-Bxd-VNyJ.d.ts} +1 -1
  33. package/dist/{cookie-names-BACctagz.d.cts → cookie-names-RXVfGYPE.d.cts} +1 -1
  34. package/dist/index.cjs +21 -21
  35. package/dist/index.d.cts +4 -4
  36. package/dist/index.d.ts +4 -4
  37. package/dist/index.js +1 -1
  38. package/dist/next/index.cjs +9 -9
  39. package/dist/next/index.d.cts +3 -3
  40. package/dist/next/index.d.ts +3 -3
  41. package/dist/next/index.js +2 -2
  42. package/dist/{personalize-content-Clc1oMYY.d.cts → personalize-content-Bf6YZdkZ.d.cts} +12 -1
  43. package/dist/{personalize-content-Clc1oMYY.d.ts → personalize-content-Bf6YZdkZ.d.ts} +12 -1
  44. package/dist/server/index.cjs +19 -19
  45. package/dist/server/index.d.cts +5 -5
  46. package/dist/server/index.d.ts +5 -5
  47. package/dist/server/index.js +3 -3
  48. package/dist/xenia-sdk.iife.js +3 -3
  49. package/dist/xenia-sdk.iife.js.map +1 -1
  50. package/dist/{xenia-server-BWhWD0La.d.ts → xenia-server-CcjQenru.d.ts} +2 -2
  51. package/dist/{xenia-server-o_wDOcei.d.cts → xenia-server-MlI3Khya.d.cts} +2 -2
  52. package/package.json +1 -1
  53. package/dist/chunk-3PYPPIUM.cjs.map +0 -1
  54. package/dist/chunk-7NGJC7CF.js.map +0 -1
  55. package/dist/chunk-DWFVDNU5.js.map +0 -1
  56. package/dist/chunk-IBNIRT7J.cjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/actions.ts","../../../src/core/http-client.ts","../../../src/core/token-provider.ts","../../../src/core/api.ts","../../../src/core/cookie-names.ts","../../../src/core/event-payload.ts","../../../src/core/id.ts","../../../src/core/personalize-content.ts","../../../src/core/response-store.ts","../../../src/client/analytics-queue.ts","../../../src/client/auto-track.ts","../../../src/server/cookies.ts","../../../src/client/identity.ts","../../../src/client/widgets/form.ts","../../../src/client/widgets/types.ts","../../../src/client/widgets/spin-wheel.ts","../../../src/client/widgets/index.ts","../../../src/client/renderer.ts","../../../src/client/xenia-client.ts","../../../src/client/react/context.ts","../../../src/client/react/XeniaProvider.tsx","../../../src/core/content-splice.ts","../../../src/client/react/hooks.ts","../../../src/client/react/personalized-content.tsx","../../../src/client/react/components.tsx","../../../src/client/react/message-component.ts"],"names":["compact","MESSAGE_TYPES","escapeHtml","escapeAttr","apply","children","useEffect","useRef","useMemo","useState","createContext","useContext","createElement"],"mappings":";;;;;;;AAWA,IAAM,aAAA,uBAAyC,GAAA,CAAsB;AAAA,EACnE,QAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAC,CAAA;AAED,IAAM,iBAAA,uBAA6C,GAAA,CAAqB;AAAA,EACtE,UAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA,cAAA;AAAA,EACA,KAAA;AAAA,EACA;AACF,CAAC,CAAA;AAMD,IAAM,+BAAoC,IAAI,GAAA,CAAgB,CAAC,UAAA,EAAY,YAAY,CAAC,CAAA;AAExF,IAAM,SAAA,uBAAqC,GAAA,CAAY;AAAA,EACrD,MAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,YAAA;AAAA,EACA,UAAA;AAAA,EACA,GAAG;AACL,CAAC,CAAA;AAGD,SAAS,SAAS,CAAA,EAA2D;AAC3E,EAAA,OAAO,OAAO,MAAM,QAAA,IAAY,CAAA,KAAM,QAAQ,CAAC,KAAA,CAAM,QAAQ,CAAC,CAAA;AAChE;AAEA,SAAS,SAAS,CAAA,EAA8C;AAC9D,EAAA,OAAO,OAAO,CAAA,KAAM,QAAA,GAAW,CAAA,GAAI,MAAA;AACrC;AAEA,SAAS,SAAS,CAAA,EAA8C;AAC9D,EAAA,OAAO,OAAO,CAAA,KAAM,QAAA,GAAW,CAAA,GAAI,MAAA;AACrC;AAMA,SAAS,SAAS,GAAA,EAAoC;AACpD,EAAA,IAAI,CAAC,QAAA,CAAS,GAAG,CAAA,EAAG,OAAO,IAAA;AAC3B,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA;AAC9B,EAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,UAAU,GAAA,CAAI,IAAI,GAAG,OAAO,IAAA;AAE1C,EAAA,IAAI,SAAS,UAAA,EAAY;AACvB,IAAA,MAAM,GAAA,GAAM,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA;AAC5B,IAAA,OAAO,GAAA,GAAM,EAAE,IAAA,EAAM,GAAA,EAAI,GAAI,IAAA;AAAA,EAC/B;AAEA,EAAA,IAAI,IAAA,KAAS,MAAA,IAAU,IAAA,KAAS,MAAA,EAAQ;AACtC,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,GAAA,CAAI,MAAM,CAAA;AAClC,IAAA,OAAO,MAAA,GAAS,EAAE,IAAA,EAAM,MAAA,EAAO,GAAI,IAAA;AAAA,EACrC;AAEA,EAAA,IAAI,IAAA,KAAS,MAAA,IAAU,IAAA,KAAS,YAAA,EAAc;AAC5C,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,GAAA,CAAI,MAAM,CAAA;AAClC,IAAA,IAAI,CAAC,QAAQ,OAAO,IAAA;AACpB,IAAA,OAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA,EAAG,IAAA,EAAM,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA,EAAE;AAAA,EAC5E;AAGA,EAAA,MAAM,GAAA,GAAM,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA,GACxB;AAAA,IACE,KAAA,EAAO,QAAA,CAAS,GAAA,CAAI,GAAA,CAAI,KAAK,CAAA,IAAK,EAAA;AAAA,IAClC,GAAA,EAAK,QAAA,CAAS,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA;AAAA,IACzB,KAAA,EAAO,QAAA,CAAS,GAAA,CAAI,GAAA,CAAI,KAAK;AAAA,GAC/B,GACA,MAAA;AAEJ,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,MAAA,EAAQ,QAAA,CAAS,GAAA,CAAI,MAAM,CAAA;AAAA,IAC3B,KAAA,EAAO,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA;AAAA,IACzB,OAAA,EAAS,QAAA,CAAS,GAAA,CAAI,OAAO,CAAA;AAAA,IAC7B,QAAA,EAAU,QAAA,CAAS,GAAA,CAAI,QAAQ,CAAA;AAAA,IAC/B,IAAA,EAAM,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA;AAAA;AAAA;AAAA;AAAA,IAIvB,KAAK,GAAA,KAAQ,GAAA,CAAI,KAAA,IAAS,GAAA,CAAI,OAAO,GAAA,GAAM,MAAA;AAAA,IAC3C,cAAA,EAAgB,QAAA,CAAS,GAAA,CAAI,cAAc,CAAA;AAAA,IAC3C,QAAA,EAAU,iBAAA,CAAkB,GAAA,CAAI,QAAQ,CAAA;AAAA,IACxC,UAAA,EAAY,YAAA,CAAa,GAAA,CAAI,UAAU,CAAA;AAAA,IACvC,QAAA,EAAU,UAAA,CAAW,GAAA,CAAI,QAAQ,CAAA;AAAA,IACjC,UAAA,EAAY,YAAA,CAAa,GAAA,CAAI,UAAU,CAAA;AAAA,IACvC,KAAA,EAAO,aAAA,CAAc,GAAA,CAAI,KAAK,CAAA;AAAA,IAC9B,WAAA,EAAa,QAAA,CAAS,GAAA,CAAI,WAAW,CAAA;AAAA,IACrC,OAAA,EAAS,QAAA,CAAS,GAAA,CAAI,OAAO,CAAA;AAAA,IAC7B,QAAA,EAAU,QAAA,CAAS,GAAA,CAAI,QAAQ;AAAA,GACjC;AACF;AAEA,SAAS,kBAAkB,CAAA,EAAuD;AAChF,EAAA,MAAM,CAAA,GAAI,SAAS,CAAC,CAAA;AACpB,EAAA,OAAO,CAAA,IAAK,iBAAA,CAAkB,GAAA,CAAI,CAAC,IAAK,CAAA,GAAwB,MAAA;AAClE;AAEA,SAAS,aAAa,CAAA,EAAkD;AACtE,EAAA,MAAM,CAAA,GAAI,SAAS,CAAC,CAAA;AACpB,EAAA,OAAO,CAAA,IAAK,YAAA,CAAa,GAAA,CAAI,CAAC,IAAK,CAAA,GAAmB,MAAA;AACxD;AAGA,SAAS,WAAW,CAAA,EAAuD;AACzE,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,CAAC,GAAG,OAAO,MAAA;AAC9B,EAAA,MAAM,WAA4B,EAAC;AACnC,EAAA,KAAA,MAAW,SAAS,CAAA,EAAG;AACrB,IAAA,IAAI,CAAC,QAAA,CAAS,KAAK,CAAA,EAAG;AACtB,IAAA,MAAM,EAAA,GAAK,QAAA,CAAS,KAAA,CAAM,EAAE,CAAA;AAC5B,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,KAAA,CAAM,KAAK,CAAA;AAClC,IAAA,IAAI,CAAC,EAAA,IAAM,CAAC,KAAA,EAAO;AACnB,IAAA,QAAA,CAAS,IAAA,CAAK;AAAA,MACZ,EAAA;AAAA,MACA,KAAA;AAAA,MACA,QAAA,EAAU,QAAA,CAAS,KAAA,CAAM,QAAQ,CAAA;AAAA,MACjC,MAAA,EAAQ,MAAM,MAAA,KAAW;AAAA,KAC1B,CAAA;AAAA,EACH;AACA,EAAA,OAAO,QAAA,CAAS,SAAS,QAAA,GAAW,MAAA;AACtC;AAOA,SAAS,aAAa,CAAA,EAAwD;AAC5E,EAAA,IAAI,CAAC,QAAA,CAAS,CAAC,CAAA,EAAG,OAAO,MAAA;AACzB,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,CAAA,CAAE,IAAI,CAAA;AAC5B,EAAA,IAAI,CAAC,MAAM,OAAO,MAAA;AAClB,EAAA,OAAO;AAAA,IACL,eAAA,EAAiB,EAAE,eAAA,KAAoB,IAAA;AAAA,IACvC,IAAA;AAAA,IACA,OAAA,EAAS,QAAA,CAAS,CAAA,CAAE,OAAO,CAAA;AAAA,IAC3B,UAAA,EAAY,QAAA,CAAS,CAAA,CAAE,UAAU,CAAA;AAAA,IACjC,gBAAA,EAAkB,QAAA,CAAS,CAAA,CAAE,gBAAgB;AAAA,GAC/C;AACF;AAOA,SAAS,cAAc,CAAA,EAAmD;AACxE,EAAA,IAAI,CAAC,QAAA,CAAS,CAAC,CAAA,EAAG,OAAO,MAAA;AACzB,EAAA,MAAM,KAAA,GAAqB;AAAA,IACzB,eAAA,EAAiB,EAAE,eAAA,KAAoB,IAAA;AAAA,IACvC,WAAA,EAAa,EAAE,WAAA,KAAgB;AAAA,GACjC;AACA,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,eAAA,IAAmB,KAAA,CAAM,WAAA;AAC9C,EAAA,OAAO,SAAS,KAAA,GAAQ,MAAA;AAC1B;AASO,SAAS,aAAa,IAAA,EAAgC;AAC3D,EAAA,IAAI,IAAA;AACJ,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,EAAG;AACvB,IAAA,IAAA,GAAO,IAAA;AAAA,EACT,CAAA,MAAA,IAAW,SAAS,IAAI,CAAA,IAAK,MAAM,OAAA,CAAQ,IAAA,CAAK,YAAY,CAAA,EAAG;AAC7D,IAAA,IAAA,GAAO,IAAA,CAAK,YAAA;AAAA,EACd;AACA,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,SAAU,EAAC;AAElC,EAAA,MAAM,UAAyB,EAAC;AAChC,EAAA,KAAA,MAAW,SAAS,IAAA,EAAM;AACxB,IAAA,MAAM,MAAA,GAAS,SAAS,KAAK,CAAA;AAC7B,IAAA,IAAI,MAAA,EAAQ,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAA;AAAA,EACjC;AACA,EAAA,OAAO,OAAA;AACT;;;AC7LO,IAAM,gBAAA,GAAmB,uCAAA;AAGzB,SAAS,SAAA,GAAqB;AACnC,EAAA,OAAO,OAAO,MAAA,KAAW,WAAA,IAAe,OAAO,QAAA,KAAa,WAAA;AAC9D;AAGO,SAAS,QAAA,CAAS,KAAa,WAAA,EAA8C;AAClF,EAAA,IAAI,CAAC,eAAe,MAAA,CAAO,IAAA,CAAK,WAAW,CAAA,CAAE,MAAA,KAAW,GAAG,OAAO,GAAA;AAClE,EAAA,MAAM,MAAA,GAAS,IAAI,eAAA,CAAgB,WAAW,CAAA;AAC9C,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,QAAA,CAAS,GAAG,IAAI,GAAA,GAAM,GAAA;AACtC,EAAA,OAAO,GAAG,GAAG,CAAA,EAAG,GAAG,CAAA,EAAG,MAAA,CAAO,UAAU,CAAA,CAAA;AACzC;AAGA,SAAS,MAAM,EAAA,EAA2B;AACxC,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,YAAY,UAAA,CAAW,OAAA,EAAS,EAAE,CAAC,CAAA;AACzD;AA+BO,IAAM,SAAA,GAAN,cAAwB,KAAA,CAAM;AAAA,EACnC,WAAA,CACkB,MAAA,EACA,IAAA,EAChB,OAAA,EACA;AACA,IAAA,KAAA,CAAM,OAAA,IAAW,CAAA,2BAAA,EAA8B,MAAM,CAAA,CAAE,CAAA;AAJvC,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACA,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAIhB,IAAA,IAAA,CAAK,IAAA,GAAO,WAAA;AAAA,EACd;AAAA,EANkB,MAAA;AAAA,EACA,IAAA;AAMpB,CAAA;AAGO,IAAM,gBAAA,GAAN,cAA+B,KAAA,CAAM;AAAA,EAC1C,YAA4B,QAAA,EAAkB;AAC5C,IAAA,KAAA,CAAM,CAAA,iBAAA,EAAoB,QAAQ,CAAA,wCAAA,CAA0C,CAAA;AADlD,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AAE1B,IAAA,IAAA,CAAK,IAAA,GAAO,kBAAA;AAAA,EACd;AAAA,EAH4B,QAAA;AAI9B,CAAA;AAOA,IAAM,QAAA,uBAAe,GAAA,EAAoD;AAqBlE,IAAM,aAAN,MAAiB;AAAA,EACL,OAAA;AAAA,EACA,cAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,OAAA;AAAA,EAEjB,YAAY,IAAA,EAAyB;AACnC,IAAA,IAAA,CAAK,WAAW,IAAA,CAAK,OAAA,IAAW,gBAAA,EAAkB,OAAA,CAAQ,QAAQ,EAAE,CAAA;AACpE,IAAA,IAAA,CAAK,cAAA,GAAiB,IAAA,CAAK,cAAA,IAAkB,EAAC;AAC9C,IAAA,IAAA,CAAK,OAAA,GAAU,KAAK,OAAA,IAAW,GAAA;AAC/B,IAAA,IAAA,CAAK,KAAA,GAAQ;AAAA,MACX,QAAA,EAAU,IAAA,CAAK,KAAA,EAAO,QAAA,IAAY,CAAA;AAAA,MAClC,WAAA,EAAa,IAAA,CAAK,KAAA,EAAO,WAAA,IAAe;AAAA,KAC1C;AACA,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAK,KAAA,IAAS,KAAA;AAC3B,IAAA,MAAM,KAAK,IAAA,CAAK,cAAA,KAAmB,OAAO,EAAC,GAAI,KAAK,cAAA,IAAkB,IAAA;AACtE,IAAA,IAAA,CAAK,OAAA,GAAU,EAAA,IAAM,EAAE,gBAAA,EAAkB,EAAA,CAAG,oBAAoB,CAAA,EAAG,UAAA,EAAY,EAAA,CAAG,UAAA,IAAc,GAAA,EAAO;AAAA,EACzG;AAAA,EAEA,MAAM,QAAQ,IAAA,EAA2C;AACvD,IAAA,IAAI,CAAC,IAAA,CAAK,OAAA,EAAS,OAAO,IAAA,CAAK,KAAK,IAAI,CAAA;AAGxC,IAAA,MAAM,MAAM,QAAA,CAAS,IAAA,CAAK,UAAU,IAAA,CAAK,IAAA,EAAM,KAAK,KAAK,CAAA;AACzD,IAAA,MAAM,CAAA,GAAI,SAAS,GAAA,CAAI,GAAG,KAAK,EAAE,QAAA,EAAU,CAAA,EAAG,QAAA,EAAU,CAAA,EAAE;AAC1D,IAAA,IAAI,EAAE,QAAA,EAAU;AACd,MAAA,IAAI,IAAA,CAAK,GAAA,EAAI,GAAI,CAAA,CAAE,QAAA,GAAW,IAAA,CAAK,OAAA,CAAQ,UAAA,EAAY,MAAM,IAAI,gBAAA,CAAiB,GAAG,CAAA;AAErF,MAAA,CAAA,CAAE,QAAA,GAAW,CAAA;AACb,MAAA,CAAA,CAAE,QAAA,GAAW,IAAA,CAAK,OAAA,CAAQ,gBAAA,GAAmB,CAAA;AAAA,IAC/C;AACA,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,IAAA,CAAK,IAAI,CAAA;AACnC,MAAA,QAAA,CAAS,OAAO,GAAG,CAAA;AACnB,MAAA,OAAO,MAAA;AAAA,IACT,SAAS,GAAA,EAAK;AACZ,MAAA,IAAI,eAAe,SAAA,IAAa,CAAC,KAAK,iBAAA,CAAkB,GAAA,CAAI,MAAM,CAAA,EAAG;AACnE,QAAA,QAAA,CAAS,OAAO,GAAG,CAAA;AACnB,QAAA,MAAM,GAAA;AAAA,MACR;AACA,MAAA,CAAA,CAAE,QAAA,IAAY,CAAA;AACd,MAAA,IAAI,CAAA,CAAE,QAAA,IAAY,IAAA,CAAK,OAAA,CAAQ,gBAAA,EAAkB;AAC/C,QAAA,CAAA,CAAE,QAAA,GAAW,KAAK,GAAA,EAAI;AACtB,QAAA,IAAA,CAAK,IAAI,CAAA,mBAAA,EAAsB,IAAA,CAAK,IAAI,CAAA,OAAA,EAAU,CAAA,CAAE,QAAQ,CAAA,SAAA,CAAW,CAAA;AAAA,MACzE;AACA,MAAA,QAAA,CAAS,GAAA,CAAI,KAAK,CAAC,CAAA;AACnB,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAc,KAAK,IAAA,EAA2C;AAC5D,IAAA,MAAM,MAAM,QAAA,CAAS,IAAA,CAAK,UAAU,IAAA,CAAK,IAAA,EAAM,KAAK,KAAK,CAAA;AACzD,IAAA,MAAM,MAAA,GAAS,KAAK,MAAA,IAAU,KAAA;AAC9B,IAAA,MAAM,OAAA,GAAkC;AAAA,MACtC,cAAA,EAAgB,kBAAA;AAAA,MAChB,GAAG,IAAA,CAAK,cAAA;AAAA,MACR,GAAG,IAAA,CAAK;AAAA,KACV;AACA,IAAA,MAAM,IAAA,GAAO,KAAK,IAAA,KAAS,MAAA,GAAY,KAAK,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA,GAAI,MAAA;AACnE,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,IAAW,IAAA,CAAK,OAAA;AACrC,IAAA,MAAM,WAAA,GAAc,KAAK,OAAA,GAAU,CAAA,GAAA,CAAK,KAAK,KAAA,EAAO,QAAA,IAAY,IAAA,CAAK,KAAA,CAAM,QAAA,IAAY,CAAA;AACvF,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,KAAA,EAAO,WAAA,IAAe,KAAK,KAAA,CAAM,WAAA;AAExD,IAAA,IAAI,SAAA;AACJ,IAAA,KAAA,IAAS,OAAA,GAAU,CAAA,EAAG,OAAA,GAAU,WAAA,EAAa,OAAA,EAAA,EAAW;AACtD,MAAA,IAAI;AACF,QAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,gBAAA;AAAA,UAC1B,GAAA;AAAA,UACA,EAAE,MAAA,EAAQ,OAAA,EAAS,IAAA,EAAM,GAAI,IAAA,CAAK,SAAA,GAAY,EAAE,SAAA,EAAW,IAAA,EAAK,GAAI,EAAC,EAAG;AAAA,UACxE;AAAA,SACF;AACA,QAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAA;AAE1C,QAAA,IAAI,SAAS,EAAA,EAAI;AACf,UAAA,OAAO,EAAE,UAAU,IAAA,EAAK;AAAA,QAC1B;AAGA,QAAA,IAAI,KAAK,iBAAA,CAAkB,QAAA,CAAS,MAAM,CAAA,IAAK,OAAA,GAAU,cAAc,CAAA,EAAG;AACxE,UAAA,MAAM,IAAA,GAAO,IAAA,CAAK,YAAA,CAAa,QAAA,EAAU,WAAW,OAAO,CAAA;AAC3D,UAAA,IAAA,CAAK,GAAA,CAAI,YAAY,IAAA,CAAK,IAAI,UAAU,IAAI,CAAA,WAAA,EAAc,QAAA,CAAS,MAAM,CAAA,CAAA,CAAG,CAAA;AAC5E,UAAA,MAAM,MAAM,IAAI,CAAA;AAChB,UAAA;AAAA,QACF;AACA,QAAA,MAAM,IAAI,SAAA,CAAU,QAAA,CAAS,MAAA,EAAQ,IAAI,CAAA;AAAA,MAC3C,SAAS,GAAA,EAAK;AACZ,QAAA,SAAA,GAAY,GAAA;AAEZ,QAAA,IAAI,GAAA,YAAe,WAAW,MAAM,GAAA;AAEpC,QAAA,IAAI,OAAA,GAAU,cAAc,CAAA,EAAG;AAC7B,UAAA,MAAM,IAAA,GAAO,YAAY,CAAA,IAAK,OAAA;AAC9B,UAAA,IAAA,CAAK,IAAI,CAAA,SAAA,EAAY,IAAA,CAAK,IAAI,CAAA,OAAA,EAAU,IAAI,CAAA,kBAAA,CAAoB,CAAA;AAChE,UAAA,MAAM,MAAM,IAAI,CAAA;AAChB,UAAA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,IAAA,MAAM,SAAA,YAAqB,KAAA,GAAQ,SAAA,GAAY,IAAI,MAAM,gBAAgB,CAAA;AAAA,EAC3E;AAAA,EAEA,MAAc,gBAAA,CACZ,GAAA,EACA,IAAA,EACA,OAAA,EACmB;AACnB,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,UAAA,CAAW,KAAA,IAAS,OAAO,CAAA;AAC1D,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,MAAM,GAAA,EAAK,EAAE,GAAG,IAAA,EAAM,MAAA,EAAQ,UAAA,CAAW,MAAA,EAAQ,CAAA;AAAA,IAChE,SAAS,GAAA,EAAK;AACZ,MAAA,IAAI,GAAA,YAAe,KAAA,IAAS,GAAA,CAAI,IAAA,KAAS,YAAA,EAAc;AACrD,QAAA,MAAM,IAAI,MAAM,CAAA,sBAAA,EAAyB,OAAO,MAAM,EAAE,KAAA,EAAO,KAAK,CAAA;AAAA,MACtE;AACA,MAAA,MAAM,GAAA;AAAA,IACR,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,MAAc,UAAU,QAAA,EAAwC;AAC9D,IAAA,MAAM,OAAO,MAAM,QAAA,CAAS,MAAK,CAAE,KAAA,CAAM,MAAM,EAAE,CAAA;AACjD,IAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,IAAA,IAAI;AACF,MAAA,OAAO,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,IACxB,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,kBAAkB,MAAA,EAAyB;AACjD,IAAA,OAAO,MAAA,KAAW,GAAA,IAAQ,MAAA,IAAU,GAAA,IAAO,MAAA,IAAU,GAAA;AAAA,EACvD;AAAA,EAEQ,YAAA,CAAa,QAAA,EAAoB,SAAA,EAAmB,OAAA,EAAyB;AACnF,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,aAAa,CAAA;AACjD,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,MAAM,OAAA,GAAU,OAAO,MAAM,CAAA;AAC7B,MAAA,IAAI,CAAC,MAAA,CAAO,KAAA,CAAM,OAAO,CAAA,SAAU,OAAA,GAAU,GAAA;AAAA,IAC/C;AACA,IAAA,OAAO,YAAY,CAAA,IAAK,OAAA;AAAA,EAC1B;AAAA,EAEQ,IAAI,GAAA,EAAmB;AAC7B,IAAA,IAAI,KAAK,KAAA,EAAO,OAAA,CAAQ,IAAA,CAAK,CAAA,QAAA,EAAW,GAAG,CAAA,CAAE,CAAA;AAAA,EAC/C;AACF,CAAA;;;AChPA,SAAS,UAAU,KAAA,EAAmC;AACpD,EAAA,IAAI;AACF,IAAA,MAAM,OAAA,GAAU,KAAA,CAAM,KAAA,CAAM,GAAG,EAAE,CAAC,CAAA;AAClC,IAAA,IAAI,CAAC,SAAS,OAAO,KAAA,CAAA;AACrB,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,IAAA,EAAM,GAAG,CAAA,CAAE,OAAA,CAAQ,IAAA,EAAM,GAAG,CAAC,CAAC,CAAA;AAC3E,IAAA,OAAO,OAAO,IAAA,CAAK,GAAA,KAAQ,QAAA,GAAW,IAAA,CAAK,MAAM,GAAA,GAAO,KAAA,CAAA;AAAA,EAC1D,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,MAAA;AAAA,EACT;AACF;AAQO,IAAM,gBAAN,MAAoB;AAAA,EACR,MAAA;AAAA,EACT,MAAA,GAAwB,IAAA;AAAA,EACxB,QAAA,GAAmC,IAAA;AAAA,EAE3C,YAAY,MAAA,EAAqB;AAC/B,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,EAChB;AAAA;AAAA,EAGA,SAAA,GAAqB;AACnB,IAAA,OAAO,QAAQ,IAAA,CAAK,MAAA,CAAO,KAAA,IAAS,IAAA,CAAK,OAAO,QAAQ,CAAA;AAAA,EAC1D;AAAA,EAES,WAAW,YAA6B;AAC/C,IAAA,IAAI,IAAA,CAAK,OAAO,KAAA,IAAS,CAAC,KAAK,MAAA,CAAO,QAAA,EAAU,OAAO,IAAA,CAAK,MAAA,CAAO,KAAA;AAEnE,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,IAAA,IAAI,IAAA,CAAK,UAAU,IAAA,CAAK,MAAA,CAAO,YAAY,GAAA,EAAK,OAAO,KAAK,MAAA,CAAO,KAAA;AACnE,IAAA,IAAI,IAAA,CAAK,QAAA,EAAU,OAAO,IAAA,CAAK,QAAA;AAE/B,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,CAAO,QAAA,EAAU;AACzB,MAAA,MAAM,IAAI,MAAM,uDAAuD,CAAA;AAAA,IACzE;AAEA,IAAA,IAAA,CAAK,QAAA,GAAW,OAAA,CAAQ,OAAA,CAAQ,IAAA,CAAK,MAAA,CAAO,UAAU,CAAA,CACnD,IAAA,CAAK,CAAC,KAAA,KAAU;AACf,MAAA,MAAM,GAAA,GAAM,UAAU,KAAK,CAAA;AAE3B,MAAA,MAAM,SAAA,GAAY,GAAA,GAAM,GAAA,GAAM,GAAA,GAAS,MAAM,CAAA,GAAI,GAAA;AACjD,MAAA,IAAA,CAAK,MAAA,GAAS,EAAE,KAAA,EAAO,SAAA,EAAU;AACjC,MAAA,OAAO,KAAA;AAAA,IACT,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM;AACb,MAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAAA,IAClB,CAAC,CAAA;AAEH,IAAA,OAAO,IAAA,CAAK,QAAA;AAAA,EACd,CAAA;AACF,CAAA;;;ACzCA,SAAS,aAAa,CAAA,EAA+B;AACnD,EAAA,OAAO,OAAO,MAAM,QAAA,IAAY,CAAA,KAAM,QAAQ,CAAC,KAAA,CAAM,QAAQ,CAAC,CAAA;AAChE;AAGA,SAAS,cAAc,CAAA,EAAmD;AACxE,EAAA,OAAO,CAAA,KAAM,MAAA,IAAa,YAAA,CAAa,CAAC,IAAK,CAAA,GAAoB,MAAA;AACnE;AAGO,SAAS,QAAQ,GAAA,EAAwD;AAC9E,EAAA,MAAM,MAAkB,EAAC;AACzB,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,EAAG;AACxC,IAAA,IAAI,CAAA,KAAM,MAAA,EAAW,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AAAA,EAChC;AACA,EAAA,OAAO,GAAA;AACT;AAQO,IAAM,WAAN,MAAe;AAAA,EACH,IAAA;AAAA,EACA,QAAA;AAAA,EACA,cAAA;AAAA,EACA,aAAA;AAAA,EAEjB,YAAY,MAAA,EAAqB;AAC/B,IAAA,IAAA,CAAK,WAAW,MAAA,CAAO,QAAA;AACvB,IAAA,IAAA,CAAK,iBAAiB,MAAA,CAAO,cAAA;AAC7B,IAAA,IAAA,CAAK,aAAA,GAAgB,IAAI,aAAA,CAAc,MAAM,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,IAAI,UAAA,CAAW;AAAA,MACzB,SAAS,MAAA,CAAO,OAAA;AAAA,MAChB,gBAAgB,MAAA,CAAO,OAAA;AAAA,MACvB,SAAS,MAAA,CAAO,OAAA;AAAA,MAChB,OAAO,MAAA,CAAO,KAAA;AAAA,MACd,gBAAgB,MAAA,CAAO,cAAA;AAAA,MACvB,OAAO,MAAA,CAAO;AAAA,KACf,CAAA;AAAA,EACH;AAAA;AAAA,EAGQ,aAAA,GAAwC;AAC9C,IAAA,OAAO;AAAA,MACL,eAAe,IAAA,CAAK,QAAA;AAAA,MACpB,iBAAiB,IAAA,CAAK;AAAA,KACxB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,WAAA,GAA+C;AAC3D,IAAA,MAAM,OAAA,GAAU,KAAK,aAAA,EAAc;AACnC,IAAA,IAAI,CAAC,IAAA,CAAK,aAAA,CAAc,SAAA,IAAa,OAAO,OAAA;AAC5C,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,aAAA,CAAc,QAAA,EAAS;AAChD,IAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,aAAA,GAAgB,CAAA,OAAA,EAAU,KAAK,CAAA,CAAA;AAClD,IAAA,OAAO,OAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,OAAA,CACJ,SAAA,EACA,IAAA,EACA,SAAyB,MAAA,EACC;AAC1B,IAAA,MAAM,EAAE,UAAU,IAAA,EAAM,OAAA,KAAY,MAAM,IAAA,CAAK,KAAK,OAAA,CAAQ;AAAA,MAC1D,MAAA;AAAA,MACA,IAAA,EAAM,OAAA;AAAA,MACN,KAAA,EAAO,EAAE,EAAA,EAAI,SAAA,EAAU;AAAA,MACvB,OAAA,EAAS,MAAM,IAAA,CAAK,WAAA,EAAY;AAAA,MAChC,IAAA,EAAM,MAAA,KAAW,MAAA,GAAU,IAAA,IAAQ,EAAC,GAAK,MAAA;AAAA,MACzC,OAAA,EAAS;AAAA,KACV,CAAA;AACD,IAAA,OAAO;AAAA,MACL,QAAQ,QAAA,CAAS,MAAA;AAAA,MACjB,IAAA,EAAM,OAAA;AAAA,MACN,OAAA,EAAS,aAAa,OAAO,CAAA;AAAA,MAC7B,UAAA,EAAY,KAAK,GAAA;AAAI,KACvB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,YAAA,CAAa,GAAA,EAAa,IAAA,EAAiD;AAC/E,IAAA,MAAM,EAAE,UAAU,IAAA,EAAM,OAAA,KAAY,MAAM,IAAA,CAAK,KAAK,OAAA,CAAQ;AAAA,MAC1D,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,qBAAA;AAAA,MACN,KAAA,EAAO,EAAE,GAAA,EAAI;AAAA,MACb,OAAA,EAAS,MAAM,IAAA,CAAK,WAAA,EAAY;AAAA,MAChC,IAAA,EAAM,QAAQ,EAAC;AAAA,MACf,OAAA,EAAS;AAAA,KACV,CAAA;AACD,IAAA,MAAM,GAAA,GAAM,YAAA,CAAa,OAAO,CAAA,GAAI,UAAU,EAAC;AAC/C,IAAA,OAAO;AAAA,MACL,QAAQ,QAAA,CAAS,MAAA;AAAA,MACjB,IAAA,EAAM,OAAA;AAAA,MACN,OAAA,EAAS,aAAa,OAAO,CAAA;AAAA,MAC7B,KAAA,EAAO,aAAA,CAAc,GAAA,CAAI,KAAK,CAAA;AAAA,MAC9B,aAAA,EAAe,IAAI,aAAA,KAAkB,IAAA;AAAA,MACrC,UAAA,EAAY,IAAI,UAAA,KAAe,IAAA;AAAA,MAC/B,eAAe,OAAO,GAAA,CAAI,aAAA,KAAkB,QAAA,GAAW,IAAI,aAAA,GAAgB,MAAA;AAAA,MAC3E,YAAY,OAAO,GAAA,CAAI,UAAA,KAAe,QAAA,GAAY,IAAI,UAAA,GAA4B,MAAA;AAAA,MAClF,UAAA,EAAY,KAAK,GAAA;AAAI,KACvB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,UAAA,CACJ,MAAA,EACA,IAAA,EACkC;AAClC,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,IAAA,CAAK,KAAK,OAAA,CAAQ;AAAA,MACvC,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,gBAAA;AAAA,MACN,OAAA,EAAS,MAAM,IAAA,CAAK,WAAA,EAAY;AAAA,MAChC,IAAA,EAAM,EAAE,MAAA,EAAO;AAAA,MACf,WAAW,IAAA,EAAM;AAAA,KAClB,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,SAAS,IAAA,EAAkD;AAC/D,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,IAAA,CAAK,KAAK,OAAA,CAAQ;AAAA,MACvC,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,yBAAA;AAAA,MACN,OAAA,EAAS,MAAM,IAAA,CAAK,WAAA,EAAY;AAAA,MAChC;AAAA,KACD,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,OAAA,CAAQ,cAAA,EAAwB,OAAA,EAA2C;AAC/E,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,IAAA,CAAK,KAAK,OAAA,CAAQ;AAAA,MACvC,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,wBAAA;AAAA,MACN,OAAA,EAAS,MAAM,IAAA,CAAK,WAAA,EAAY;AAAA,MAChC,MAAM,OAAA,CAAQ;AAAA,QACZ,cAAA;AAAA,QACA,SAAA,EAAW,QAAQ,SAAA,KAAc,IAAA;AAAA,QACjC,SAAA,EAAW,QAAQ,SAAA,KAAc,IAAA;AAAA,QACjC,eAAA,EAAiB,QAAQ,eAAA,KAAoB,IAAA;AAAA,QAC7C,eAAe,OAAA,CAAQ,aAAA;AAAA,QACvB,gBAAgB,OAAA,CAAQ;AAAA,OACzB;AAAA,KACF,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OAAA,CAAQ,UAAA,EAAoB,IAAA,GAAuB,EAAC,EAA2B;AACnF,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,IAAA,CAAK,KAAK,OAAA,CAAQ;AAAA,MACvC,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,8BAAA;AAAA,MACN,KAAA,EAAO,IAAA,CAAK,KAAA,KAAU,MAAA,GAAY,EAAE,OAAO,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,EAAE,GAAI,MAAA;AAAA,MAClE,OAAA,EAAS,MAAM,IAAA,CAAK,WAAA,EAAY;AAAA,MAChC,MAAM,OAAA,CAAQ;AAAA,QACZ,UAAA;AAAA,QACA,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,QAAQ,IAAA,CAAK;AAAA,OACd;AAAA,KACF,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,YAAA,CACJ,KAAA,EACA,IAAA,GAAuB,EAAC,EACO;AAC/B,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,IAAA,CAAK,KAAK,OAAA,CAAQ;AAAA,MACvC,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,oCAAA;AAAA,MACN,KAAA,EAAO,IAAA,CAAK,KAAA,KAAU,MAAA,GAAY,EAAE,OAAO,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,EAAE,GAAI,MAAA;AAAA,MAClE,OAAA,EAAS,MAAM,IAAA,CAAK,WAAA,EAAY;AAAA,MAChC,MAAM,OAAA,CAAQ;AAAA,QACZ,KAAA;AAAA,QACA,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,QAAQ,IAAA,CAAK;AAAA,OACd;AAAA,KACF,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,cAAA,CAAe,QAAA,EAAoB,IAAA,GAAuB,EAAC,EAAkC;AACjG,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,IAAA,CAAK,KAAK,OAAA,CAAQ;AAAA,MACvC,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,sCAAA;AAAA,MACN,OAAA,EAAS,MAAM,IAAA,CAAK,WAAA,EAAY;AAAA,MAChC,MAAM,OAAA,CAAQ;AAAA,QACZ,QAAA;AAAA,QACA,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,QAAQ,IAAA,CAAK;AAAA,OACd;AAAA,KACF,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT;AACF,CAAA;;;ACjQO,IAAM,cAAA,GAAiB,OAAA;AAGvB,SAAS,iBAAA,CAAkB,SAAiB,cAAA,EAAwB;AACzE,EAAA,OAAO,CAAA,EAAG,UAAU,cAAc,CAAA,IAAA,CAAA;AACpC;AAGO,SAAS,iBAAA,CAAkB,SAAiB,cAAA,EAAwB;AACzE,EAAA,OAAO,CAAA,EAAG,UAAU,cAAc,CAAA,QAAA,CAAA;AACpC;AAsBO,SAAS,aAAA,CAAc,KAAA,EAAqB,MAAA,EAAiB,UAAA,GAAa,GAAA,EAAa;AAC5F,EAAA,OAAO,GAAG,iBAAA,CAAkB,MAAM,CAAC,CAAA,CAAA,EAAI,mBAAmB,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC,CAAC,CAAA,kBAAA,EAAqB,IAAA,CAAK,KAAA,CAAM,UAAA,GAAa,KAAK,CAAC,CAAA,cAAA,CAAA;AACrI;;;AC/CA,IAAM,QAAA,uBAAe,GAAA,CAAI;AAAA,EACvB,SAAA;AAAA,EACA,WAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA;AAAA,EACA,YAAA;AAAA,EACA,OAAA;AAAA,EACA,WAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,UAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAC,CAAA;AAaD,SAASA,SAAQ,GAAA,EAAuE;AACtF,EAAA,MAAM,MAAiC,EAAC;AACxC,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,EAAG;AACxC,IAAA,IAAI,CAAA,KAAM,MAAA,EAAW,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AAAA,EAChC;AACA,EAAA,OAAO,GAAA;AACT;AAWO,SAAS,kBAAkB,KAAA,EAAsC;AACtE,EAAA,MAAM,cAAyC,EAAC;AAChD,EAAA,MAAM,WAAsC,EAAC;AAC7C,EAAA,IAAI,MAAM,KAAA,EAAO;AACf,IAAA,KAAA,MAAW,CAAC,GAAG,CAAC,CAAA,IAAK,OAAO,OAAA,CAAQ,KAAA,CAAM,KAAK,CAAA,EAAG;AAChD,MAAA,IAAI,MAAM,MAAA,EAAW;AAKrB,MAAA,IAAI,SAAS,GAAA,CAAI,CAAC,CAAA,EAAG,QAAA,CAAS,CAAC,CAAA,GAAI,CAAA;AAAA,WAC9B,WAAA,CAAY,CAAC,CAAA,GAAI,CAAA;AAAA,IACxB;AAAA,EACF;AAEA,EAAA,MAAM,OAAA,GAAU;AAAA,IACd,GAAG,WAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAKH,GAAG,QAAA;AAAA,IACH,GAAGA,QAAAA,CAAS,KAAA,CAAM,OAAA,IAAW,EAA4C,CAAA;AAAA,IACzE,GAAGA,QAAAA,CAAS,KAAA,CAAM,QAAA,IAAY,EAA4C,CAAA;AAAA,IAC1E,SAAS,KAAA,CAAM,OAAA;AAAA,IACf,GAAI,MAAM,SAAA,GAAY,EAAE,WAAW,KAAA,CAAM,SAAA,KAAc,EAAC;AAAA,IACxD,GAAI,MAAM,SAAA,GAAY,EAAE,WAAW,KAAA,CAAM,SAAA,KAAc;AAAC,GAC1D;AAEA,EAAA,OAAO,OAAA;AACT;;;AC/EA,IAAM,QAAA,GAAW,kCAAA;AAEjB,SAAS,YAAY,MAAA,EAA4B;AAC/C,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,MAAM,CAAA;AACnC,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,MAAA,CAAO,eAAA,EAAiB;AAC3D,IAAA,MAAA,CAAO,gBAAgB,KAAK,CAAA;AAAA,EAC9B,CAAA,MAAO;AACL,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,EAAQ,CAAA,EAAA,EAAK,KAAA,CAAM,CAAC,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,MAAA,KAAW,GAAG,CAAA;AAAA,EAC5E;AACA,EAAA,OAAO,KAAA;AACT;AAQO,SAAS,YAAA,CAAa,IAAA,GAAe,IAAA,CAAK,GAAA,EAAI,EAAW;AAC9D,EAAA,IAAI,QAAA,GAAW,EAAA;AACf,EAAA,IAAI,CAAA,GAAI,IAAA;AACR,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,IAAK,CAAA,EAAG,CAAA,EAAA,EAAK;AAC3B,IAAA,QAAA,GAAW,QAAA,CAAS,CAAA,GAAI,EAAE,CAAA,GAAI,QAAA;AAC9B,IAAA,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,CAAA,GAAI,EAAE,CAAA;AAAA,EACvB;AAEA,EAAA,MAAM,MAAA,GAAS,YAAY,EAAE,CAAA;AAC7B,EAAA,IAAI,UAAA,GAAa,EAAA;AACjB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,EAAI,CAAA,EAAA,EAAK;AAC3B,IAAA,UAAA,IAAc,QAAA,CAAS,MAAA,CAAO,CAAC,CAAA,GAAI,EAAE,CAAA;AAAA,EACvC;AAEA,EAAA,OAAO,QAAA,GAAW,UAAA;AACpB;AAGO,IAAM,mBAAA,GAAsB,EAAA;AAe5B,SAAS,UAAU,GAAA,EAAqB;AAC7C,EAAA,IAAI,GAAA,CAAI,MAAA,IAAU,mBAAA,EAAqB,OAAO,GAAA;AAG9C,EAAA,IAAI,GAAA,GAAM,EAAA;AACV,EAAA,KAAA,MAAW,IAAA,IAAQ,CAAC,UAAA,EAAY,QAAU,CAAA,EAAG;AAC3C,IAAA,IAAI,OAAO,IAAA,KAAS,CAAA;AACpB,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK;AACnC,MAAA,IAAA,IAAQ,GAAA,CAAI,WAAW,CAAC,CAAA;AACxB,MAAA,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,IAAA,EAAM,QAAU,CAAA,KAAM,CAAA;AACvC,MAAA,GAAA,IAAO,QAAA,CAAS,OAAO,EAAE,CAAA;AAAA,IAC3B;AAAA,EACF;AAEA,EAAA,IAAI,MAAA,GAAS,EAAA;AACb,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,mBAAA,EAAqB,CAAA,EAAA,EAAK;AAC5C,IAAA,IAAI,MAAM,CAAA,GAAI,CAAA;AACd,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,GAAA,CAAI,MAAA,EAAQ,KAAK,mBAAA,EAAqB;AACxD,MAAA,GAAA,GAAO,MAAM,EAAA,GAAK,QAAA,CAAS,QAAQ,GAAA,CAAI,CAAC,CAAC,CAAA,KAAO,CAAA;AAAA,IAClD;AACA,IAAA,MAAA,IAAU,QAAA,CAAS,MAAM,EAAE,CAAA;AAAA,EAC7B;AACA,EAAA,OAAO,MAAA;AACT;;;ACyCA,IAAM,kBAAA,GAAqB,GAAA;AAC3B,IAAM,kBAAA,GAAqB,CAAA;AAe3B,IAAM,MAAA,GAAS,CAAC,CAAA,KACd,CAAA,IAAK,OAAO,CAAA,KAAM,QAAA,IAAY,OAAO,eAAA,KAAoB,UAAA,GAAa,eAAA,CAAgB,CAAC,CAAA,GAAI,CAAA;AAU7F,eAAsB,kBAAA,CACpB,SACA,OAAA,EACsC;AACtC,EAAA,MAAM,EAAE,KAAI,GAAI,OAAA;AAChB,EAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,IAAa,kBAAA;AACvC,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,EAAI,IAAK,QAAQ,SAAA,IAAa,kBAAA,CAAA;AACpD,EAAA,MAAM,UAAyB,EAAC;AAChC,EAAA,MAAM,MAAA,GAAS,CAAC,IAAA,KAAsB;AACpC,IAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AACjB,IAAA,IAAI;AACF,MAAA,OAAA,CAAQ,YAAY,IAAI,CAAA;AAAA,IAC1B,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF,CAAA;AAEA,EAAA,IAAI,OAAA,GAAgB,OAAA;AACpB,EAAA,IAAI;AACF,IAAA,IAAI,CAAC,QAAQ,OAAA,IAAW,OAAO,oBAAoB,UAAA,EAAY,OAAA,GAAU,gBAAgB,OAAO,CAAA;AAChG,IAAA,OAAA,GAAU,GAAA,CAAI,OAAA,GAAU,GAAA,CAAI,OAAA,CAAQ,OAAO,CAAA,GAAI,OAAA;AAAA,EACjD,SAAS,KAAA,EAAO;AACd,IAAA,OAAO,EAAE,OAAA,EAAS,OAAA,EAAS,OAAA,EAAS,QAAA,EAAU,OAAO,KAAA,EAAM;AAAA,EAC7D;AAEA,EAAA,MAAM,GAAA,GAAM,EAAE,IAAA,EAAM,OAAA,EAAQ;AAG5B,EAAA,MAAM,OAAA,uBAAc,OAAA,EAAgB;AAGpC,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAqB;AACzC,EAAA,IAAI,QAAA,GAAmB,CAAC,EAAE,MAAA,EAAQ,GAAA,EAAK,KAAK,MAAA,EAAQ,KAAA,EAAO,GAAA,CAAI,IAAA,EAAM,CAAA;AAGrE,EAAA,MAAM,MAAA,GAAS,CAAC,MAAA,EAAiB,CAAA,EAAY,KAAA,KAA0B;AACrE,IAAA,OAAA,CAAQ,GAAA,CAAI,OAAO,KAAK,CAAA;AACxB,IAAA,GAAA,CAAI,WAAA,GAAc,OAAO,KAAK,CAAA;AAG9B,IAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,KAAA,CAAM,GAAA,CAAI,MAAM,CAAA;AAChC,IAAA,IAAI,CAAC,CAAA,CAAE,QAAA,IAAY,KAAA,CAAM,WAAW,CAAA,EAAG;AAErC,MAAA,OAAO,aAAA,CAAc,QAAQ,GAAG,CAAA;AAAA,IAClC;AACA,IAAA,KAAA,MAAW,IAAA,IAAQ,OAAO,IAAI,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,EAAU,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAA;AAChF,IAAA,MAAM,KAAK,CAAA,CAAE,QAAA,CAAS,EAAA,IAAM,MAAA,CAAO,OAAO,EAAA,IAAM,SAAA;AAChD,IAAA,MAAM,IAAA,GAAO,KAAA,CAAM,MAAA,EAAQ,EAAA,EAAI,CAAA,CAAE,QAAA,CAAS,KAAA,IAAS,MAAA,CAAO,MAAA,CAAO,KAAA,EAAO,KAAA,EAAO,GAAG,CAAA;AAClF,IAAA,MAAA,CAAO;AAAA,MACL,QAAQ,MAAA,CAAO,EAAA;AAAA,MACf,IAAA,EAAM,SAAA;AAAA,MACN,EAAA;AAAA,MACA,QAAA,EAAU,KAAA,CAAM,GAAA,CAAI,CAAC,MAAM,GAAA,CAAI,OAAA,CAAQ,CAAC,CAAC,EAAE,MAAA,CAAO,CAAC,EAAA,KAAqB,CAAC,CAAC,EAAE,CAAA;AAAA,MAC5E,UAAA,EAAY,EAAE,QAAA,CAAS,UAAA;AAAA,MACvB,MAAA,EAAQ,EAAE,QAAA,CAAS,MAAA;AAAA,MACnB;AAAA,KACD,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AAEA,EAAA,KAAA,IAAS,KAAA,GAAQ,KAAK,KAAA,EAAA,EAAS;AAC7B,IAAA,MAAM,OAAA,GAAU,KAAK,QAAA,EAAU,GAAA,EAAK,SAAS,KAAA,EAAO,MAAA,EAAQ,CAAC,CAAA,KAAM;AACjE,MAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,EAAE,CAAA;AAC1B,MAAA,OAAO,CAAA,GAAI,MAAA,CAAO,CAAA,EAAG,CAAA,EAAG,KAAK,CAAA,GAAI,MAAA;AAAA,IACnC,CAAC,CAAA;AACD,IAAA,IAAI,OAAA,CAAQ,IAAA,KAAS,CAAA,EAAG,OAAO,EAAE,SAAS,GAAA,CAAI,IAAA,EAAM,OAAA,EAAS,QAAA,EAAU,IAAA,EAAK;AAC5E,IAAA,IAAI,CAAC,OAAA,CAAQ,OAAA,IAAW,KAAA,IAAS,SAAA,EAAW;AAC1C,MAAA,OAAO,EAAE,SAAS,GAAA,CAAI,IAAA,EAAM,SAAS,QAAA,EAAU,CAAC,QAAQ,OAAA,EAAQ;AAAA,IAClE;AACA,IAAA,QAAA,CAAS,OAAA,EAAS,EAAE,OAAA,EAAS,GAAA,CAAI,IAAA,EAAM,KAAA,EAAO,OAAA,EAAS,CAAC,GAAG,OAAA,CAAQ,IAAA,EAAM,GAAG,CAAA;AAE5E,IAAA,IAAI,SAAA;AACJ,IAAA,IAAI,WAAA;AACJ,IAAA,IAAI,OAAA;AACJ,IAAA,IAAI;AACF,MAAA,SAAA,GAAY,MAAM,YAAA,CAAa,OAAA,CAAQ,OAAA,CAAQ,CAAC,GAAG,OAAA,CAAQ,IAAA,EAAM,CAAC,CAAA,EAAG,QAAQ,CAAA;AAC7E,MAAA,CAAC,EAAE,WAAA,EAAa,OAAA,EAAQ,GAAI,MAAM,YAAA,CAAa,gBAAA,CAAiB,SAAA,EAAW,GAAA,EAAK,OAAA,CAAQ,MAAM,CAAA,EAAG,QAAQ,CAAA;AAAA,IAC3G,SAAS,KAAA,EAAO;AACd,MAAA,OAAO,EAAE,OAAA,EAAS,GAAA,CAAI,IAAA,EAAM,OAAA,EAAS,QAAA,EAAU,KAAA,EAAO,KAAA,EAAO,KAAA,KAAU,OAAA,GAAU,MAAA,GAAY,KAAA,EAAM;AAAA,IACrG;AAEA,IAAA,MAAM,QAAA,GAAW,IAAI,GAAA,CAAI,SAAA,CAAU,GAAA,CAAI,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,MAAA,EAAQ,CAAC,CAAC,CAAC,CAAA;AAC5D,IAAA,QAAA,GAAW,EAAC;AACZ,IAAA,KAAA,MAAW,MAAA,IAAU,OAAA,CAAQ,MAAA,EAAO,EAAG;AACrC,MAAA,MAAM,QAAA,GAAW,QAAA,CAAS,GAAA,CAAI,MAAA,CAAO,EAAE,CAAA;AACvC,MAAA,MAAM,KAAA,GAAQ,QAAA,GACV,QAAA,CAAS,GAAA,GACP,QAAA,CAAS,GAAA,CAAI,GAAA,CAAI,CAAC,EAAA,KAAO,WAAA,CAAY,GAAA,CAAI,EAAE,CAAC,EAAE,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,KAAM,MAAS,CAAA,GAC3E,OAAA,CAAQ,GAAA,CAAI,QAAQ,CAAA,IAAK,EAAC,GAC5B,EAAC;AACL,MAAA,MAAM,CAAA,GAAa,EAAE,QAAA,EAAU,KAAA,EAAM;AACrC,MAAA,OAAA,CAAQ,GAAA,CAAI,MAAA,CAAO,EAAA,EAAI,CAAC,CAAA;AACxB,MAAA,QAAA,CAAS,KAAK,GAAG,MAAA,CAAO,MAAA,EAAQ,CAAA,EAAG,KAAK,CAAC,CAAA;AAAA,IAC3C;AACA,IAAA,QAAA,CAAS,OAAA,EAAS,EAAE,OAAA,EAAS,GAAA,CAAI,MAAM,KAAA,EAAO,OAAA,EAAS,EAAC,EAAG,CAAA;AAAA,EAC7D;AACF;AAEA,SAAS,QAAA,CAAS,SAAoC,CAAA,EAA2D;AAC/G,EAAA,IAAI;AACF,IAAA,OAAA,CAAQ,aAAa,CAAC,CAAA;AAAA,EACxB,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAMA,SAAS,KACP,QAAA,EACA,GAAA,EACA,OAAA,EACA,KAAA,EACA,QAEA,KAAA,EACsB;AACtB,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAqB;AACzC,EAAA,MAAM,IAAA,uBAAW,OAAA,EAAgB;AAEjC,EAAA,MAAM,QAAA,uBAAe,OAAA,EAAgB;AACrC,EAAA,MAAM,KAAA,GAAgB,CAAC,GAAG,QAAQ,CAAA;AAElC,EAAA,OAAO,KAAA,CAAM,SAAS,CAAA,EAAG;AACvB,IAAA,MAAM,IAAA,GAAO,MAAM,KAAA,EAAM;AACzB,IAAA,MAAM,QAAQ,IAAA,CAAK,KAAA;AACnB,IAAA,IAAI,CAAC,SAAS,OAAO,KAAA,KAAU,YAAY,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA,EAAG;AAEhE,IAAA,MAAM,EAAA,GAAK,QAAQ,GAAA,CAAI,KAAK,IAAI,MAAA,GAAY,GAAA,CAAI,QAAQ,KAAK,CAAA;AAC7D,IAAA,MAAM,MAAA,GAAS,EAAA,GAAK,GAAA,CAAI,MAAA,CAAO,KAAK,CAAA,GAAI,IAAA;AAExC,IAAA,IAAI,EAAA,IAAM,MAAA,EAAQ,IAAA,KAAS,SAAA,EAAW;AACpC,MAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,EAAE,EAAA,EAAI,MAAA,EAAQ,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,CAAC,IAAI,CAAA,EAAG,CAAA;AAC/D,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,KAAA,CAAM,IAAA,CAAK,GAAG,KAAK,CAAA;AACnB,QAAA;AAAA,MACF;AACA,MAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA;AAC/B,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,QAAA,CAAS,KAAA,CAAM,KAAK,IAAI,CAAA;AAAA,MAC1B,CAAA,MAAO;AACL,QAAA,OAAA,CAAQ,GAAA,CAAI,EAAA,EAAI,EAAE,EAAA,EAAI,MAAA,EAAQ,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,CAAC,IAAI,CAAA,EAAG,CAAA;AAE3D,QAAA,IAAI,MAAA,CAAO,EAAA,KAAO,OAAA,IAAW,MAAA,CAAO,KAAA,EAAO;AACzC,UAAA,MAAM,IAAA,GAAO,GAAA,CAAI,QAAA,CAAS,KAAA,EAAO,OAAO,KAAK,CAAA;AAC7C,UAAA,IAAI,QAAQ,OAAO,IAAA,KAAS,QAAA,EAAU,QAAA,CAAS,IAAI,IAAI,CAAA;AACvD,UAAA,KAAA,CAAM,IAAA,CAAK,GAAG,QAAA,CAAS,KAAK,CAAC,CAAA;AAAA,QAC/B;AAAA,MACF;AACA,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,EAAA,IAAM,MAAA,EAAQ,IAAA,KAAS,QAAA,EAAU;AACnC,MAAA,MAAM,QAAA,GAAW,GAAA,CAAI,cAAA,CAAe,KAAK,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,IAAK,OAAO,CAAA,KAAM,QAAQ,CAAA;AACnF,MAAA,OAAA,CAAQ,IAAI,KAAK,CAAA;AACjB,MAAA,GAAA,CAAI,cAAc,KAAK,CAAA;AACvB,MAAA,IAAI,QAAA,CAAS,SAAS,CAAA,EAAG;AACvB,QAAA,KAAA,MAAW,CAAA,IAAK,QAAA,EAAU,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA;AACvC,QAAA,MAAM,EAAA,GAAK,OAAO,EAAA,IAAM,SAAA;AACxB,QAAA,MAAM,MAAA,GAAkB,EAAc,OAAO,KAAA,EAAO,KAAA,EAAO,CAAC,IAAI,CAAA,EAAE;AAClE,QAAA,KAAA,CAAM,IAAA,CAAK,GAAG,KAAA,CAAM,MAAA,EAAQ,IAAI,MAAA,CAAO,KAAA,EAAO,QAAA,EAAU,GAAG,CAAC,CAAA;AAC5D,QAAA,MAAA,CAAO;AAAA,UACL,MAAA,EAAQ,EAAA;AAAA,UACR,IAAA,EAAM,QAAA;AAAA,UACN,EAAA;AAAA,UACA,QAAA,EAAU,QAAA,CAAS,GAAA,CAAI,CAAC,MAAM,GAAA,CAAI,OAAA,CAAQ,CAAC,CAAC,EAAE,MAAA,CAAO,CAAC,CAAA,KAAmB,CAAC,CAAC,CAAC,CAAA;AAAA,UAC5E;AAAA,SACD,CAAA;AACD,QAAA;AAAA,MACF;AAAA,IAEF;AAEA,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA,EAAG;AACrB,IAAA,IAAA,CAAK,IAAI,KAAK,CAAA;AACd,IAAA,KAAA,CAAM,IAAA,CAAK,GAAG,QAAA,CAAS,KAAK,CAAC,CAAA;AAAA,EAC/B;AACA,EAAA,OAAO,OAAA;AACT;AAGA,SAAS,KAAA,CAAM,MAAA,EAAiB,EAAA,EAAiB,KAAA,EAA2B,OAAe,GAAA,EAAyB;AAClH,EAAA,IAAI,OAAO,OAAA,EAAS;AAClB,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,GAAA,CAAI,QAAA,CAAS,MAAA,CAAO,KAAA,EAAO,KAAA,EAAO,KAAK,CAAA;AACvC,MAAA,OAAO,CAAC,EAAE,MAAA,EAAQ,MAAA,CAAO,OAAO,GAAA,EAAK,KAAA,EAAO,KAAA,EAAO,GAAA,CAAI,QAAA,CAAS,MAAA,CAAO,KAAA,EAAO,KAAK,GAAG,CAAA;AAAA,IACxF;AACA,IAAA,IAAI,IAAI,UAAA,EAAY;AAClB,MAAA,GAAA,CAAI,UAAA,CAAW,MAAA,CAAO,KAAA,EAAO,KAAA,CAAM,CAAC,CAAC,CAAA;AACrC,MAAA,OAAO,MAAA,CAAO,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,KAAA,EAAO,MAAA,CAAO,KAAA,EAAM,CAAE,CAAA;AAAA,IAChE;AACA,IAAA,EAAA,GAAK,SAAA;AAAA,EACP;AAEA,EAAA,MAAM,OAAe,EAAC;AACtB,EAAA,KAAA,MAAW,IAAA,IAAQ,OAAO,KAAA,EAAO;AAC/B,IAAA,MAAM,MAAA,GAAS,EAAA,KAAO,QAAA,IAAY,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAA,GAAI,KAAA,GAAQ,CAAC,KAAA,CAAM,CAAC,CAAC,CAAA;AAChF,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAA,EAAG;AAC9B,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ,OAAO,KAAK,CAAA;AAC9C,MAAA,IAAI,QAAQ,CAAA,EAAG;AACf,MAAA,IAAA,CAAK,MAAA,CAAO,MAAA,CAAO,KAAA,EAAO,CAAA,EAAG,GAAG,MAAM,CAAA;AAAA,IACxC,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,GAAI,OAAO,CAAC,CAAA;AAAA,IAClC;AACA,IAAA,KAAA,MAAW,KAAA,IAAS,MAAA,EAAQ,IAAA,CAAK,IAAA,CAAK,EAAE,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAQ,GAAA,EAAK,IAAA,CAAK,GAAA,EAAK,KAAA,EAAO,CAAA;AAAA,EACrF;AACA,EAAA,OAAO,IAAA;AACT;AAGA,SAAS,aAAA,CAAc,QAAiB,GAAA,EAAyB;AAC/D,EAAA,IAAI,OAAO,MAAA,CAAO,EAAA,KAAO,OAAA,IAAW,MAAA,CAAO,OAAO,KAAA,EAAO;AACvD,IAAA,OAAO,CAAC,EAAE,MAAA,EAAQ,OAAO,KAAA,EAAO,GAAA,EAAK,OAAO,MAAA,CAAO,KAAA,EAAO,KAAA,EAAO,GAAA,CAAI,SAAS,MAAA,CAAO,KAAA,EAAO,OAAO,MAAA,CAAO,KAAK,GAAG,CAAA;AAAA,EACpH;AACA,EAAA,OAAO,MAAA,CAAO,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,KAAA,EAAO,MAAA,CAAO,KAAA,EAAM,CAAE,CAAA;AAChE;AAEA,SAAS,SAAS,KAAA,EAAqB;AACrC,EAAA,IAAI,MAAM,OAAA,CAAQ,KAAK,CAAA,EAAG,OAAO,MAAM,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,MAAO,EAAE,MAAA,EAAQ,KAAA,EAAO,KAAK,CAAA,EAAG,KAAA,EAAO,GAAE,CAAE,CAAA;AAC1F,EAAA,OAAO,OAAO,IAAA,CAAK,KAAK,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,MAAO,EAAE,MAAA,EAAQ,KAAA,EAAO,KAAK,CAAA,EAAG,KAAA,EAAO,KAAA,CAAM,CAAC,GAAE,CAAE,CAAA;AACnF;AAGA,eAAe,gBAAA,CAAiB,SAAA,EAA4B,GAAA,EAAiB,MAAA,EAAiB;AAC5F,EAAA,MAAM,GAAA,GAAM,CAAC,GAAG,IAAI,IAAI,SAAA,CAAU,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAA,CAAE,GAAA,IAAO,EAAE,CAAC,CAAC,CAAA;AAC9D,EAAA,MAAM,OAAA,GAAU,UAAU,MAAA,CAAO,CAAC,MAAM,CAAC,CAAA,CAAE,GAAA,IAAO,CAAA,CAAE,KAAK,CAAA;AACzD,EAAA,MAAM,CAAC,OAAA,EAAS,GAAG,OAAO,CAAA,GAAI,MAAM,QAAQ,GAAA,CAAI;AAAA,IAC9C,GAAA,CAAI,MAAA,GAAS,CAAA,GAAI,GAAA,CAAI,YAAA,CAAa,GAAA,EAAK,MAAM,CAAA,GAAI,OAAA,CAAQ,OAAA,CAAQ,EAAE,CAAA;AAAA,IACnE,GAAG,OAAA,CAAQ,GAAA,CAAI,CAAC,MAAM,GAAA,CAAI,YAAA,CAAa,CAAA,CAAE,KAAA,EAAQ,MAAM,CAAA,CAAE,KAAA,CAAM,MAAM,EAAY,CAAC;AAAA,GACnF,CAAA;AACD,EAAA,MAAM,WAAA,uBAAkB,GAAA,EAAkB;AAC1C,EAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,IAAA,MAAM,EAAA,GAAK,GAAA,CAAI,OAAA,CAAQ,KAAK,CAAA;AAC5B,IAAA,IAAI,EAAA,EAAI,WAAA,CAAY,GAAA,CAAI,EAAA,EAAI,KAAK,CAAA;AAAA,EACnC;AACA,EAAA,MAAM,OAAA,uBAAc,GAAA,EAA2B;AAC/C,EAAA,OAAA,CAAQ,OAAA,CAAQ,CAAC,CAAA,EAAG,CAAA,KAAM,OAAA,CAAQ,IAAI,CAAA,EAAG,OAAA,CAAQ,CAAC,CAAE,CAAC,CAAA;AACrD,EAAA,OAAO,EAAE,aAAa,OAAA,EAAQ;AAChC;AAEA,IAAM,OAAA,0BAAiB,SAAS,CAAA;AAEhC,SAAS,YAAA,CAAgB,SAAqB,QAAA,EAA8B;AAC1E,EAAA,MAAM,SAAA,GAAY,QAAA,GAAW,IAAA,CAAK,GAAA,EAAI;AACtC,EAAA,IAAI,SAAA,IAAa,CAAA,EAAG,OAAO,OAAA,CAAQ,OAAO,OAAO,CAAA;AACjD,EAAA,IAAI,KAAA;AACJ,EAAA,OAAO,QAAQ,IAAA,CAAK;AAAA,IAClB,OAAA;AAAA,IACA,IAAI,OAAA,CAAe,CAAC,CAAA,EAAG,MAAA,KAAW;AAChC,MAAA,KAAA,GAAQ,UAAA,CAAW,MAAM,MAAA,CAAO,OAAO,GAAG,SAAS,CAAA;AAAA,IACrD,CAAC;AAAA,GACF,CAAA,CAAE,OAAA,CAAQ,MAAM,YAAA,CAAa,KAAK,CAAC,CAAA;AACtC;AAQO,SAAS,cAAA,CAAe,SAAkB,GAAA,EAA2B;AAC1E,EAAA,IAAI;AACF,IAAA,IAAI,UAAgB,OAAO,eAAA,KAAoB,UAAA,GAAa,eAAA,CAAgB,OAAO,CAAA,GAAI,OAAA;AACvF,IAAA,OAAA,GAAU,GAAA,CAAI,OAAA,GAAU,GAAA,CAAI,OAAA,CAAQ,OAAO,CAAA,GAAI,OAAA;AAC/C,IAAA,MAAM,IAAA,GAAO,EAAE,MAAA,EAAQ,EAAE,IAAA,EAAM,SAAQ,EAAG,GAAA,EAAK,MAAA,EAAQ,KAAA,EAAO,OAAA,EAAQ;AAEtE,IAAA,OAAO,CAAC,GAAG,IAAA,CAAK,CAAC,IAAI,CAAA,EAAG,GAAA,kBAAK,IAAI,OAAA,EAAQ,EAAG,CAAA,EAAG,MAAM;AAAA,IAAC,CAAA,EAAG,MAAM,KAAA,CAAS,CAAA,CAAE,MAAM,CAAA;AAAA,EAClF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAC;AAAA,EACV;AACF;AAQA,eAAsB,eAAA,CACpB,KACA,OAAA,EAC6C;AAC7C,EAAA,IAAI,IAAA;AACJ,EAAA,IAAI;AACF,IAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,WAAW,MAAM,IAAI,MAAM,mEAAmE,CAAA;AAC/G,IAAA,IAAA,GAAO,MAAM,OAAA,CAAQ,GAAA,CAAI,SAAA,CAAU,GAAA,EAAK,QAAQ,MAAM,CAAA;AAAA,EACxD,SAAS,KAAA,EAAO;AACd,IAAA,OAAO,EAAE,SAAS,IAAA,EAAM,OAAA,EAAS,EAAC,EAAG,QAAA,EAAU,OAAO,KAAA,EAAM;AAAA,EAC9D;AACA,EAAA,IAAI,IAAA,IAAQ,IAAA,EAAM,OAAO,EAAE,OAAA,EAAS,MAAM,OAAA,EAAS,EAAC,EAAG,QAAA,EAAU,IAAA,EAAK;AACtE,EAAA,OAAO,kBAAA,CAAmB,MAAW,OAAO,CAAA;AAC9C;;;ACraO,IAAM,sBAAN,MAAmD;AAAA,EACvC,GAAA,uBAAU,GAAA,EAA6B;AAAA,EAExD,GAAA,CAAI,KAAa,KAAA,EAA8B;AAC7C,IAAA,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,GAAA,EAAK,KAAK,CAAA;AAAA,EACzB;AAAA,EACA,IAAI,GAAA,EAA0C;AAC5C,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA;AAAA,EACzB;AAAA,EACA,IAAA,GAAiB;AACf,IAAA,OAAO,CAAC,GAAG,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA;AAAA,EAC5B;AAAA,EACA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,IAAI,KAAA,EAAM;AAAA,EACjB;AACF,CAAA;AAMO,IAAM,4BAAN,MAAyD;AAAA,EAC7C,KAAA;AAAA,EAEjB,WAAA,CAAY,SAAS,OAAA,EAAS;AAC5B,IAAA,IAAA,CAAK,KAAA,GAAQ,GAAG,MAAM,CAAA,UAAA,CAAA;AAAA,EACxB;AAAA,EAEQ,IAAA,GAAwC;AAC9C,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,YAAA,CAAa,OAAA,CAAQ,IAAA,CAAK,KAAK,CAAA;AAC3C,MAAA,OAAO,GAAA,GAAO,IAAA,CAAK,KAAA,CAAM,GAAG,IAAwC,EAAC;AAAA,IACvE,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,EAAC;AAAA,IACV;AAAA,EACF;AAAA,EAEQ,MAAM,IAAA,EAA6C;AACzD,IAAA,IAAI;AACF,MAAA,YAAA,CAAa,QAAQ,IAAA,CAAK,KAAA,EAAO,IAAA,CAAK,SAAA,CAAU,IAAI,CAAC,CAAA;AAAA,IACvD,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,GAAA,CAAI,KAAa,KAAA,EAA8B;AAC7C,IAAA,MAAM,IAAA,GAAO,KAAK,IAAA,EAAK;AACvB,IAAA,IAAA,CAAK,GAAG,CAAA,GAAI,KAAA;AACZ,IAAA,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,EACjB;AAAA,EACA,IAAI,GAAA,EAA0C;AAC5C,IAAA,OAAO,IAAA,CAAK,IAAA,EAAK,CAAE,GAAG,CAAA;AAAA,EACxB;AAAA,EACA,IAAA,GAAiB;AACf,IAAA,OAAO,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,IAAA,EAAM,CAAA;AAAA,EAChC;AAAA,EACA,KAAA,GAAc;AACZ,IAAA,IAAI;AACF,MAAA,YAAA,CAAa,UAAA,CAAW,KAAK,KAAK,CAAA;AAAA,IACpC,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AACF,CAAA;;;ACrDO,IAAM,iBAAN,MAAqB;AAAA,EAClB,QAAsB,EAAC;AAAA,EACd,IAAA;AAAA,EACA,SAAA;AAAA,EACA,eAAA;AAAA,EACA,YAAA;AAAA,EACA,KAAA;AAAA,EACT,KAAA,GAA+C,IAAA;AAAA,EAC/C,QAAA,GAAW,KAAA;AAAA,EACX,iBAAA,GAAoB,KAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOpB,OAAA,GAAU,KAAA;AAAA,EAED,UAAA,GAAa,MAAY,IAAA,CAAK,aAAA,EAAc;AAAA,EAC5C,qBAAqB,MAAY;AAChD,IAAA,IAAI,QAAA,CAAS,eAAA,KAAoB,QAAA,EAAU,IAAA,CAAK,aAAA,EAAc;AAAA,EAChE,CAAA;AAAA,EAEA,YAAY,IAAA,EAA6B;AACvC,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,SAAA,GAAY,KAAK,SAAA,IAAa,EAAA;AACnC,IAAA,IAAA,CAAK,eAAA,GAAkB,KAAK,eAAA,IAAmB,GAAA;AAC/C,IAAA,IAAA,CAAK,YAAA,GAAe,KAAK,YAAA,IAAgB,GAAA;AACzC,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAK,KAAA,IAAS,KAAA;AAAA,EAC7B;AAAA;AAAA,EAGA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AACf,IAAA,IAAI,IAAA,CAAK,KAAA,IAAS,OAAO,MAAA,KAAW,WAAA,EAAa;AACjD,IAAA,IAAA,CAAK,KAAA,GAAQ,YAAY,MAAM,KAAK,KAAK,KAAA,EAAM,EAAG,KAAK,eAAe,CAAA;AACtE,IAAA,MAAA,CAAO,gBAAA,CAAiB,UAAA,EAAY,IAAA,CAAK,UAAU,CAAA;AACnD,IAAA,QAAA,CAAS,gBAAA,CAAiB,kBAAA,EAAoB,IAAA,CAAK,kBAAkB,CAAA;AACrE,IAAA,IAAA,CAAK,iBAAA,GAAoB,IAAA;AAAA,EAC3B;AAAA;AAAA,EAGA,IAAA,GAAa;AACX,IAAA,IAAA,CAAK,OAAA,GAAU,KAAA;AACf,IAAA,IAAI,IAAA,CAAK,KAAA,EAAO,aAAA,CAAc,IAAA,CAAK,KAAK,CAAA;AACxC,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AACb,IAAA,IAAI,KAAK,iBAAA,EAAmB;AAC1B,MAAA,MAAA,CAAO,mBAAA,CAAoB,UAAA,EAAY,IAAA,CAAK,UAAU,CAAA;AACtD,MAAA,QAAA,CAAS,mBAAA,CAAoB,kBAAA,EAAoB,IAAA,CAAK,kBAAkB,CAAA;AACxE,MAAA,IAAA,CAAK,iBAAA,GAAoB,KAAA;AAAA,IAC3B;AAAA,EACF;AAAA;AAAA,EAGA,QAAQ,KAAA,EAAyB;AAC/B,IAAA,IAAI,KAAK,KAAA,CAAM,MAAA,IAAU,KAAK,YAAA,EAAc,IAAA,CAAK,MAAM,KAAA,EAAM;AAC7D,IAAA,IAAA,CAAK,KAAA,CAAM,KAAK,KAAK,CAAA;AACrB,IAAA,IAAI,IAAA,CAAK,WAAW,IAAA,CAAK,KAAA,CAAM,UAAU,IAAA,CAAK,SAAA,EAAW,KAAK,IAAA,CAAK,KAAA,EAAM;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,MAAM,cAAc,KAAA,EAAkC;AACpD,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,KAAK,CAAC,KAAK,GAAG,EAAE,SAAA,EAAW,MAAM,CAAA;AAAA,IAC9C,SAAS,GAAA,EAAK;AACZ,MAAA,IAAI,CAAC,KAAK,kBAAA,CAAmB,GAAG,GAAG,IAAA,CAAK,OAAA,CAAQ,CAAC,KAAK,CAAC,CAAA;AACvD,MAAA,IAAI,IAAA,CAAK,KAAA,EAAO,OAAA,CAAQ,IAAA,CAAK,iCAAiC,GAAG,CAAA;AAAA,IACnE;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,KAAA,GAAuB;AAC3B,IAAA,IAAI,CAAC,KAAK,OAAA,IAAW,IAAA,CAAK,YAAY,IAAA,CAAK,KAAA,CAAM,WAAW,CAAA,EAAG;AAC/D,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAChB,IAAA,MAAM,QAAQ,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,CAAA,EAAG,KAAK,SAAS,CAAA;AACjD,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,KAAK,KAAK,CAAA;AAAA,IACvB,SAAS,GAAA,EAAK;AAMZ,MAAA,IAAI,CAAC,IAAA,CAAK,kBAAA,CAAmB,GAAG,CAAA,EAAG,IAAA,CAAK,QAAQ,KAAK,CAAA;AACrD,MAAA,IAAI,IAAA,CAAK,KAAA,EAAO,OAAA,CAAQ,IAAA,CAAK,kCAAkC,GAAG,CAAA;AAAA,IACpE,CAAA,SAAE;AACA,MAAA,IAAA,CAAK,QAAA,GAAW,KAAA;AAAA,IAClB;AAAA,EACF;AAAA,EAEQ,mBAAmB,GAAA,EAAuB;AAChD,IAAA,OAAO,eAAe,SAAA,IAAa,GAAA,CAAI,MAAA,IAAU,GAAA,IAAO,IAAI,MAAA,GAAS,GAAA;AAAA,EACvE;AAAA;AAAA,EAGQ,aAAA,GAAsB;AAC5B,IAAA,IAAI,CAAC,IAAA,CAAK,OAAA,IAAW,IAAA,CAAK,KAAA,CAAM,WAAW,CAAA,EAAG;AAC9C,IAAA,MAAM,QAAQ,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA,EAAG,IAAA,CAAK,MAAM,MAAM,CAAA;AACpD,IAAA,KAAK,IAAA,CAAK,KAAK,KAAA,EAAO,EAAE,WAAW,IAAA,EAAM,CAAA,CAAE,KAAA,CAAM,MAAM;AAAA,IAEvD,CAAC,CAAA;AAAA,EACH;AAAA,EAEQ,QAAQ,KAAA,EAA2B;AACzC,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,YAAA,GAAe,IAAA,CAAK,KAAA,CAAM,MAAA;AAC5C,IAAA,IAAI,QAAQ,CAAA,EAAG;AACf,IAAA,IAAA,CAAK,MAAM,OAAA,CAAQ,GAAG,MAAM,KAAA,CAAM,CAAA,EAAG,IAAI,CAAC,CAAA;AAAA,EAC5C;AACF,CAAA;;;AChJA,IAAM,KAAA,uBAA0C,GAAA,CAAqB;AAAA,EACnE,OAAA;AAAA,EACA,WAAA;AAAA,EACA;AACF,CAAC,CAAA;AAQM,SAAS,mBAAmB,KAAA,EAA8B;AAC/D,EAAA,MAAM,GAAA,GAAM,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA;AAC7B,EAAA,IAAI,GAAA,KAAQ,IAAI,OAAO,IAAA;AACvB,EAAA,MAAM,OAAA,GAAU,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,GAAG,CAAA;AAClC,EAAA,MAAM,eAAA,GAAkB,KAAA,CAAM,KAAA,CAAM,GAAA,GAAM,CAAC,CAAA;AAC3C,EAAA,IAAI,CAAC,OAAA,IAAW,CAAC,MAAM,GAAA,CAAI,eAAe,GAAG,OAAO,IAAA;AACpD,EAAA,OAAO,EAAE,SAAS,eAAA,EAAgB;AACpC;AAyBO,SAAS,aAAa,EAAA,EAA8B;AACzD,EAAA,MAAM,UAAA,GAAa,EAAA,CAAG,YAAA,CAAa,wBAAwB,CAAA;AAC3D,EAAA,IAAI,CAAC,YAAY,OAAO,IAAA;AACxB,EAAA,MAAM,cAAA,GAAiB,EAAA,CAAG,YAAA,CAAa,6BAA6B,CAAA;AACpE,EAAA,MAAM,WAAA,GAAc,EAAA,CAAG,YAAA,CAAa,0BAA0B,CAAA;AAC9D,EAAA,MAAM,YAAA,GAAe,EAAA,CAAG,YAAA,CAAa,yBAAyB,CAAA;AAC9D,EAAA,OAAO;AAAA,IACL,UAAA;AAAA,IACA,gBAAgB,cAAA,IAAkB,MAAA;AAAA,IAClC,aAAa,WAAA,IAAe,MAAA;AAAA,IAC5B,YAAA,EAAc,YAAA,IAAgB,IAAA,GAAO,MAAA,GAAY,YAAA,KAAiB;AAAA,GACpE;AACF;AAaO,IAAM,cAAN,MAAkB;AAAA,EACN,IAAA;AAAA,EACA,cAAA,uBAAqB,GAAA,EAAqB;AAAA,EAC1C,SAAA,uBAAgB,GAAA,EAAmC;AAAA,EACnD,aAAA,uBAAoB,GAAA,EAAmC;AAAA,EACvD,SAAA,uBAAgB,GAAA,EAAa;AAAA,EAC7B,aAAA,uBAAoB,GAAA,EAAa;AAAA,EAC1C,YAAA,GAAiD,IAAA;AAAA,EACjD,gBAAA,GAA4C,IAAA;AAAA,EAEpD,YAAY,IAAA,EAAwB;AAClC,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AAAA,EACd;AAAA,EAEA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,WAAA,EAAY;AACjB,IAAA,IAAA,CAAK,KAAK,QAAQ,CAAA;AAClB,IAAA,IAAA,CAAK,cAAA,EAAe;AAAA,EACtB;AAAA,EAEA,IAAA,GAAa;AACX,IAAA,IAAI,KAAK,YAAA,EAAc,QAAA,CAAS,mBAAA,CAAoB,OAAA,EAAS,KAAK,YAAY,CAAA;AAC9E,IAAA,IAAA,CAAK,YAAA,GAAe,IAAA;AACpB,IAAA,IAAA,CAAK,kBAAkB,UAAA,EAAW;AAClC,IAAA,IAAA,CAAK,gBAAA,GAAmB,IAAA;AACxB,IAAA,IAAA,CAAK,UAAU,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAA,CAAE,YAAY,CAAA;AAC5C,IAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AACrB,IAAA,IAAA,CAAK,cAAc,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAA,CAAE,YAAY,CAAA;AAChD,IAAA,IAAA,CAAK,cAAc,KAAA,EAAM;AACzB,IAAA,IAAA,CAAK,eAAe,KAAA,EAAM;AAC1B,IAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AACrB,IAAA,IAAA,CAAK,cAAc,KAAA,EAAM;AAAA,EAC3B;AAAA,EAEQ,IAAA,GAAe;AACrB,IAAA,OAAO,CAAA,KAAA,EAAQ,IAAA,CAAK,IAAA,CAAK,MAAM,CAAA,CAAA;AAAA,EACjC;AAAA,EAEQ,UAAU,EAAA,EAAsB;AACtC,IAAA,IAAI,IAAA,CAAK,IAAA,CAAK,UAAA,IAAc,CAAA,EAAG,OAAO,KAAA;AACtC,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,EAAE,CAAA,IAAK,CAAA;AAC5C,IAAA,IAAI,GAAA,GAAM,IAAA,IAAQ,IAAA,CAAK,IAAA,CAAK,UAAA,EAAY;AACtC,MAAA,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,EAAA,EAAI,GAAG,CAAA;AAC/B,MAAA,OAAO,KAAA;AAAA,IACT;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEQ,WAAA,GAAoB;AAC1B,IAAA,MAAM,IAAA,GAAO,KAAK,IAAA,EAAK;AACvB,IAAA,IAAA,CAAK,YAAA,GAAe,CAAC,KAAA,KAAsB;AACzC,MAAA,MAAM,SAAS,KAAA,CAAM,MAAA;AACrB,MAAA,IAAI,CAAC,MAAA,EAAQ;AAGb,MAAA,MAAM,EAAA,GAAK,MAAA,CAAO,OAAA,CAAQ,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,CAAG,CAAA;AACrC,MAAA,IAAI,EAAA,EAAI;AACN,QAAA,MAAM,GAAA,GAAM,EAAA,CAAG,YAAA,CAAa,IAAI,CAAA;AAChC,QAAA,MAAM,MAAA,GAAS,GAAA,GAAM,kBAAA,CAAmB,GAAG,CAAA,GAAI,IAAA;AAC/C,QAAA,IAAI,MAAA,IAAU,OAAO,eAAA,KAAoB,OAAA,IAAW,CAAC,IAAA,CAAK,SAAA,CAAU,EAAE,CAAA,EAAG;AACvE,UAAA,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,OAAA,EAAS,OAAO,CAAA;AAAA,QACxC;AAAA,MACF;AAGA,MAAA,IAAI,IAAA,CAAK,KAAK,QAAA,EAAU;AACtB,QAAA,MAAM,IAAA,GAAO,MAAA,CAAO,OAAA,CAAQ,mBAAmB,CAAA;AAC/C,QAAA,IAAI,IAAA,EAAM;AACR,UAAA,MAAM,IAAA,GAAO,aAAa,IAAI,CAAA;AAC9B,UAAA,IAAI,IAAA,IAAQ,CAAC,IAAA,CAAK,SAAA,CAAU,IAAI,GAAG,IAAA,CAAK,IAAA,CAAK,QAAA,CAAS,OAAA,EAAS,IAAI,CAAA;AAAA,QACrE;AAAA,MACF;AAAA,IACF,CAAA;AACA,IAAA,QAAA,CAAS,gBAAA,CAAiB,OAAA,EAAS,IAAA,CAAK,YAAY,CAAA;AAAA,EACtD;AAAA,EAEQ,YAAY,EAAA,EAAmB;AACrC,IAAA,IAAI,CAAC,KAAK,IAAA,CAAK,QAAA,IAAY,KAAK,aAAA,CAAc,GAAA,CAAI,EAAE,CAAA,EAAG;AACvD,IAAA,MAAM,IAAA,GAAO,aAAa,EAAE,CAAA;AAG5B,IAAA,IAAI,CAAC,IAAA,EAAM;AACX,IAAA,MAAM,QAAA,GAAW,KAAK,IAAA,CAAK,QAAA;AAC3B,IAAA,MAAM,EAAE,SAAA,EAAW,UAAA,EAAW,GAAI,KAAK,IAAA,CAAK,QAAA;AAC5C,IAAA,MAAM,WAAW,IAAI,oBAAA;AAAA,MACnB,CAAC,OAAA,KAAY;AACX,QAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,UAAA,IAAI,CAAC,MAAM,cAAA,EAAgB;AAC3B,UAAA,IAAI,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,EAAE,CAAA,EAAG;AAChC,UAAA,IAAA,CAAK,aAAA,CAAc,IAAI,EAAE,CAAA;AACzB,UAAA,QAAA,CAAS,cAAc,IAAI,CAAA;AAC3B,UAAA,QAAA,CAAS,UAAA,EAAW;AACpB,UAAA,IAAA,CAAK,aAAA,CAAc,OAAO,EAAE,CAAA;AAAA,QAC9B;AAAA,MACF,CAAA;AAAA,MACA,EAAE,WAAW,UAAA;AAAW,KAC1B;AACA,IAAA,QAAA,CAAS,QAAQ,EAAE,CAAA;AACnB,IAAA,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,EAAA,EAAI,QAAQ,CAAA;AAAA,EACrC;AAAA,EAEQ,eAAA,CAAgB,IAAa,OAAA,EAAuB;AAC1D,IAAA,IAAI,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,EAAE,CAAA,EAAG;AAC5B,IAAA,MAAM,EAAE,SAAA,EAAW,UAAA,EAAY,WAAA,EAAY,GAAI,KAAK,IAAA,CAAK,QAAA;AACzD,IAAA,MAAM,WAAW,IAAI,oBAAA;AAAA,MACnB,CAAC,OAAA,KAAY;AACX,QAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,UAAA,IAAI,CAAC,MAAM,cAAA,EAAgB;AAC3B,UAAA,IAAI,WAAA,IAAe,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,EAAE,CAAA,EAAG;AAC3C,UAAA,IAAI,IAAA,CAAK,SAAA,CAAU,EAAE,CAAA,EAAG;AACxB,UAAA,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,OAAA,EAAS,WAAW,CAAA;AACnC,UAAA,IAAI,WAAA,EAAa;AACf,YAAA,IAAA,CAAK,SAAA,CAAU,IAAI,EAAE,CAAA;AACrB,YAAA,QAAA,CAAS,UAAA,EAAW;AACpB,YAAA,IAAA,CAAK,SAAA,CAAU,OAAO,EAAE,CAAA;AAAA,UAC1B;AAAA,QACF;AAAA,MACF,CAAA;AAAA,MACA,EAAE,WAAW,UAAA;AAAW,KAC1B;AACA,IAAA,QAAA,CAAS,QAAQ,EAAE,CAAA;AACnB,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,EAAA,EAAI,QAAQ,CAAA;AAAA,EACjC;AAAA,EAEQ,cAAc,EAAA,EAAmB;AACvC,IAAA,MAAM,GAAA,GAAM,EAAA,CAAG,YAAA,CAAa,IAAA,CAAK,MAAM,CAAA;AACvC,IAAA,IAAI,CAAC,GAAA,EAAK;AACV,IAAA,MAAM,MAAA,GAAS,mBAAmB,GAAG,CAAA;AACrC,IAAA,IAAI,CAAC,MAAA,EAAQ;AACb,IAAA,IAAI,OAAO,eAAA,KAAoB,WAAA,OAAkB,eAAA,CAAgB,EAAA,EAAI,OAAO,OAAO,CAAA;AAAA,SAAA,IAC1E,MAAA,CAAO,oBAAoB,WAAA,EAAa,IAAA,CAAK,KAAK,IAAA,CAAK,MAAA,CAAO,SAAS,WAAW,CAAA;AAAA,EAC7F;AAAA,EAEQ,KAAK,IAAA,EAAwB;AACnC,IAAA,IAAA,CAAK,gBAAA,CAAiB,CAAA,CAAA,EAAI,IAAA,CAAK,IAAA,EAAM,CAAA,CAAA,CAAG,CAAA,CAAE,OAAA,CAAQ,CAAC,EAAA,KAAO,IAAA,CAAK,aAAA,CAAc,EAAE,CAAC,CAAA;AAChF,IAAA,IAAI,IAAA,CAAK,KAAK,QAAA,EAAU;AACtB,MAAA,IAAA,CAAK,gBAAA,CAAiB,mBAAmB,CAAA,CAAE,OAAA,CAAQ,CAAC,EAAA,KAAO,IAAA,CAAK,WAAA,CAAY,EAAE,CAAC,CAAA;AAAA,IACjF;AAAA,EACF;AAAA,EAEQ,cAAA,GAAuB;AAC7B,IAAA,IAAA,CAAK,gBAAA,GAAmB,IAAI,gBAAA,CAAiB,CAAC,SAAA,KAAc;AAC1D,MAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAChC,QAAA,KAAA,MAAW,IAAA,IAAQ,SAAS,UAAA,EAAY;AACtC,UAAA,IAAI,IAAA,CAAK,QAAA,KAAa,IAAA,CAAK,YAAA,EAAc;AACzC,UAAA,MAAM,EAAA,GAAK,IAAA;AACX,UAAA,IAAA,CAAK,cAAc,EAAE,CAAA;AACrB,UAAA,IAAI,IAAA,CAAK,KAAK,QAAA,IAAY,EAAA,CAAG,QAAQ,mBAAmB,CAAA,EAAG,IAAA,CAAK,WAAA,CAAY,EAAE,CAAA;AAC9E,UAAA,IAAA,CAAK,KAAK,EAAE,CAAA;AAAA,QACd;AAAA,MACF;AAAA,IACF,CAAC,CAAA;AACD,IAAA,IAAA,CAAK,gBAAA,CAAiB,QAAQ,QAAA,CAAS,IAAA,EAAM,EAAE,SAAA,EAAW,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,CAAA;AAAA,EACjF;AACF,CAAA;;;AC5MO,SAAS,aAAa,MAAA,EAA2D;AACtF,EAAA,MAAM,MAA8B,EAAC;AACrC,EAAA,IAAI,CAAC,QAAQ,OAAO,GAAA;AACpB,EAAA,KAAA,MAAW,IAAA,IAAQ,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA,EAAG;AACpC,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,OAAA,CAAQ,GAAG,CAAA;AAC5B,IAAA,IAAI,QAAQ,EAAA,EAAI;AAChB,IAAA,MAAM,MAAM,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,GAAG,EAAE,IAAA,EAAK;AACpC,IAAA,MAAM,QAAQ,IAAA,CAAK,KAAA,CAAM,GAAA,GAAM,CAAC,EAAE,IAAA,EAAK;AACvC,IAAA,IAAI,GAAA,EAAK,GAAA,CAAI,GAAG,CAAA,GAAI,mBAAmB,KAAK,CAAA;AAAA,EAC9C;AACA,EAAA,OAAO,GAAA;AACT;;;AC3BA,IAAM,kBAAA,GAAqB,KAAK,EAAA,GAAK,GAAA;AAY9B,IAAM,WAAN,MAAe;AAAA,EACH,MAAA;AAAA,EACA,MAAA;AAAA,EACT,QAAA,GAA0B,IAAA;AAAA,EAC1B,SAAA,GAA2B,IAAA;AAAA,EAC3B,SAAA,GAA2B,IAAA;AAAA,EAEnC,WAAA,CAAY,MAAA,GAAS,OAAA,EAAS,aAAA,GAAgD,IAAA,EAAM;AAClF,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,MAAA,GAAS,oBAAoB,aAAa,CAAA;AAAA,EACjD;AAAA,EAEQ,IAAI,IAAA,EAAsB;AAChC,IAAA,OAAO,CAAA,EAAG,IAAA,CAAK,MAAM,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,UAAA,GAAqB;AAC3B,IAAA,OAAO,iBAAA,CAAkB,KAAK,MAAM,CAAA;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,mBAAmB,EAAA,EAAqC;AAC9D,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,IAAU,CAAC,EAAA,EAAI;AACzB,IAAA,IAAI;AACF,MAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACrC,MAAA,MAAM,KAAA,GAAQ;AAAA,QACZ,GAAG,IAAA,CAAK,UAAA,EAAY,CAAA,CAAA,EAAI,kBAAA,CAAmB,EAAE,CAAC,CAAA,CAAA;AAAA,QAC9C,QAAA;AAAA,QACA,WAAW,IAAA,CAAK,KAAA,CAAM,KAAK,MAAA,CAAO,UAAA,GAAa,KAAK,CAAC,CAAA,CAAA;AAAA,QACrD,CAAA,SAAA,EAAY,IAAA,CAAK,MAAA,CAAO,QAAQ,CAAA;AAAA,OAClC;AACA,MAAA,IAAI,IAAA,CAAK,OAAO,MAAA,EAAQ,KAAA,CAAM,KAAK,CAAA,OAAA,EAAU,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA,CAAE,CAAA;AACjE,MAAA,IAAI,IAAA,CAAK,MAAA,CAAO,MAAA,EAAQ,KAAA,CAAM,KAAK,QAAQ,CAAA;AAC3C,MAAA,QAAA,CAAS,MAAA,GAAS,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA;AAAA,IACnC,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAAA;AAAA,EAGQ,iBAAA,GAAmC;AACzC,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,IAAU,OAAO,QAAA,KAAa,aAAa,OAAO,IAAA;AAC5D,IAAA,IAAI;AACF,MAAA,OAAO,aAAa,QAAA,CAAS,MAAM,EAAE,IAAA,CAAK,UAAA,EAAY,CAAA,IAAK,IAAA;AAAA,IAC7D,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,eAAA,GAAmC;AACvC,IAAA,IAAI,KAAK,QAAA,EAAU;AACjB,MAAA,IAAA,CAAK,kBAAA,CAAmB,IAAA,CAAK,YAAA,EAAa,IAAK,KAAK,QAAQ,CAAA;AAC5D,MAAA,OAAO,IAAA,CAAK,QAAA;AAAA,IACd;AACA,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,CAAI,WAAW,CAAA;AACvC,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,YAAA,CAAa,OAAA,CAAQ,UAAU,CAAA;AAC9C,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,IAAA,CAAK,QAAA,GAAW,MAAA;AAChB,QAAA,IAAA,CAAK,kBAAA,CAAmB,IAAA,CAAK,YAAA,EAAa,IAAK,MAAM,CAAA;AACrD,QAAA,OAAO,MAAA;AAAA,MACT;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAKA,IAAA,IAAI,EAAA,GAAK,KAAK,iBAAA,EAAkB;AAChC,IAAA,IAAI,CAAC,EAAA,EAAI,EAAA,GAAK,MAAM,KAAK,aAAA,EAAc;AACvC,IAAA,IAAI,CAAC,EAAA,EAAI,EAAA,GAAK,MAAM,KAAK,WAAA,EAAY;AAErC,IAAA,IAAA,CAAK,QAAA,GAAW,EAAA;AAChB,IAAA,IAAI;AACF,MAAA,YAAA,CAAa,OAAA,CAAQ,YAAY,EAAE,CAAA;AAAA,IACrC,CAAA,CAAA,MAAQ;AAAA,IAER;AAGA,IAAA,IAAA,CAAK,kBAAA,CAAmB,IAAA,CAAK,YAAA,EAAa,IAAK,EAAE,CAAA;AACjD,IAAA,OAAO,EAAA;AAAA,EACT;AAAA,EAEA,WAAA,GAA6B;AAC3B,IAAA,OAAO,IAAA,CAAK,QAAA;AAAA,EACd;AAAA,EAEA,MAAc,aAAA,GAAwC;AACpD,IAAA,IAAI;AACF,MAAA,IAAI,CAAC,SAAA,CAAU,YAAA,EAAc,gBAAA,EAAkB,OAAO,IAAA;AACtD,MAAA,MAAM,OAAA,GAAU,MAAM,SAAA,CAAU,YAAA,CAAa,gBAAA,EAAiB;AAC9D,MAAA,MAAM,MAAA,GACJ,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,YAAA,IAAgB,CAAA,CAAE,QAAQ,CAAA,IACzD,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,YAAA,IAAgB,CAAA,CAAE,QAAQ,CAAA,IACzD,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,aAAA,IAAiB,EAAE,QAAQ,CAAA;AAC5D,MAAA,OAAO,QAAQ,QAAA,IAAY,IAAA;AAAA,IAC7B,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAc,WAAA,GAA+B;AAC3C,IAAA,MAAM,GAAA,GAAM;AAAA,MACV,SAAA,CAAU,SAAA;AAAA,MACV,SAAA,CAAU,QAAA;AAAA,MACV,MAAA,CAAO,KAAA;AAAA,MACP,MAAA,CAAO,MAAA;AAAA,MACP,MAAA,CAAO,UAAA;AAAA,MAAA,iBACP,IAAI,IAAA,EAAK,EAAE,iBAAA;AAAkB,KAC/B,CAAE,KAAK,GAAG,CAAA;AACV,IAAA,MAAM,MAAA,GAAS,MAAM,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,SAAA,EAAW,IAAI,WAAA,EAAY,CAAE,MAAA,CAAO,GAAG,CAAC,CAAA;AAClF,IAAA,OAAO,KAAA,CAAM,KAAK,IAAI,UAAA,CAAW,MAAM,CAAC,CAAA,CACrC,IAAI,CAAC,CAAA,KAAM,EAAE,QAAA,CAAS,EAAE,EAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAC,CAAA,CAC1C,KAAK,EAAE,CAAA;AAAA,EACZ;AAAA;AAAA;AAAA,EAKA,SAAS,SAAA,EAAyB;AAChC,IAAA,IAAI,CAAC,SAAA,EAAW;AAChB,IAAA,IAAI;AACF,MAAA,YAAA,CAAa,OAAA,CAAQ,IAAA,CAAK,GAAA,CAAI,YAAY,GAAG,SAAS,CAAA;AAAA,IACxD,CAAA,CAAA,MAAQ;AAAA,IAER;AACA,IAAA,IAAA,CAAK,mBAAmB,SAAS,CAAA;AAAA,EACnC;AAAA,EAEA,YAAA,GAA8B;AAC5B,IAAA,IAAI;AACF,MAAA,OAAO,YAAA,CAAa,OAAA,CAAQ,IAAA,CAAK,GAAA,CAAI,YAAY,CAAC,CAAA;AAAA,IACpD,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,cAAc,UAAA,EAAiC;AAC7C,IAAA,IAAI;AACF,MAAA,IAAI,YAAY,YAAA,CAAa,OAAA,CAAQ,KAAK,GAAA,CAAI,aAAa,GAAG,UAAU,CAAA;AAAA,WACnE,YAAA,CAAa,UAAA,CAAW,IAAA,CAAK,GAAA,CAAI,aAAa,CAAC,CAAA;AAAA,IACtD,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,aAAA,GAA+B;AAC7B,IAAA,IAAI;AACF,MAAA,OAAO,YAAA,CAAa,OAAA,CAAQ,IAAA,CAAK,GAAA,CAAI,aAAa,CAAC,CAAA;AAAA,IACrD,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEA,SAAS,KAAA,EAA4B;AACnC,IAAA,IAAI;AACF,MAAA,IAAI,OAAO,YAAA,CAAa,OAAA,CAAQ,KAAK,GAAA,CAAI,OAAO,GAAG,KAAK,CAAA;AAAA,WACnD,YAAA,CAAa,UAAA,CAAW,IAAA,CAAK,GAAA,CAAI,OAAO,CAAC,CAAA;AAAA,IAChD,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,QAAA,GAA0B;AACxB,IAAA,IAAI;AACF,MAAA,OAAO,YAAA,CAAa,OAAA,CAAQ,IAAA,CAAK,GAAA,CAAI,OAAO,CAAC,CAAA;AAAA,IAC/C,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,YAAA,GAAuB;AACrB,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,YAAY,CAAA;AACnC,IAAA,MAAM,eAAA,GAAkB,IAAA,CAAK,GAAA,CAAI,uBAAuB,CAAA;AACxD,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AAErB,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,cAAA,CAAe,OAAA,CAAQ,KAAK,CAAA;AAC7C,MAAA,MAAM,YAAA,GAAe,MAAA,CAAO,cAAA,CAAe,OAAA,CAAQ,eAAe,CAAC,CAAA;AACnE,MAAA,MAAM,QAAQ,QAAA,IAAY,MAAA,CAAO,SAAS,YAAY,CAAA,IAAK,MAAM,YAAA,GAAe,kBAAA;AAChF,MAAA,MAAM,EAAA,GAAK,KAAA,GAAQ,QAAA,GAAW,YAAA,CAAa,GAAG,CAAA;AAC9C,MAAA,cAAA,CAAe,OAAA,CAAQ,OAAO,EAAE,CAAA;AAChC,MAAA,cAAA,CAAe,OAAA,CAAQ,eAAA,EAAiB,MAAA,CAAO,GAAG,CAAC,CAAA;AACnD,MAAA,IAAA,CAAK,SAAA,GAAY,EAAA;AACjB,MAAA,OAAO,EAAA;AAAA,IACT,CAAA,CAAA,MAAQ;AAEN,MAAA,IAAI,CAAC,IAAA,CAAK,SAAA,EAAW,IAAA,CAAK,SAAA,GAAY,aAAa,GAAG,CAAA;AACtD,MAAA,OAAO,IAAA,CAAK,SAAA;AAAA,IACd;AAAA,EACF;AAAA;AAAA;AAAA,EAKA,aAAa,EAAA,EAAyB;AACpC,IAAA,IAAA,CAAK,YAAY,EAAA,IAAM,EAAA,CAAG,MAAK,GAAI,EAAA,CAAG,MAAK,GAAI,IAAA;AAAA,EACjD;AAAA;AAAA,EAGA,YAAA,GAA8B;AAC5B,IAAA,OAAO,IAAA,CAAK,SAAA,IAAa,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,IAAK,IAAA;AAAA,EACtD;AAAA;AAAA;AAAA,EAKQ,SAAS,IAAA,EAA6B;AAC5C,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,IAAI,eAAA,CAAgB,MAAA,CAAO,SAAS,MAAM,CAAA,CAAE,IAAI,IAAI,CAAA;AAChE,MAAA,IAAI,GAAA,EAAK;AACP,QAAA,IAAI;AACF,UAAA,cAAA,CAAe,OAAA,CAAQ,IAAA,CAAK,GAAA,CAAI,IAAI,GAAG,GAAG,CAAA;AAAA,QAC5C,CAAA,CAAA,MAAQ;AAAA,QAER;AACA,QAAA,OAAO,GAAA;AAAA,MACT;AACA,MAAA,IAAI;AACF,QAAA,OAAO,cAAA,CAAe,OAAA,CAAQ,IAAA,CAAK,GAAA,CAAI,IAAI,CAAC,CAAA;AAAA,MAC9C,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA,EAGA,cAAA,GAAwD;AACtD,IAAA,MAAM,MAA6C,EAAC;AACpD,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,QAAA,CAAS,YAAY,CAAA;AAC5C,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,QAAA,CAAS,YAAY,CAAA;AAC5C,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,QAAA,CAAS,cAAc,CAAA;AAChD,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,QAAA,CAAS,aAAa,CAAA;AAC9C,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA;AAEpC,IAAA,IAAI,SAAA,MAAe,SAAA,GAAY,SAAA;AAC/B,IAAA,IAAI,SAAA,MAAe,SAAA,GAAY,SAAA;AAC/B,IAAA,IAAI,WAAA,MAAiB,WAAA,GAAc,WAAA;AACnC,IAAA,IAAI,UAAA,MAAgB,UAAA,GAAa,UAAA;AACjC,IAAA,IAAI,KAAA,MAAW,KAAA,GAAQ,KAAA;AAEvB,IAAA,IAAI;AACF,MAAA,GAAA,CAAI,GAAA,GAAM,OAAO,QAAA,CAAS,IAAA;AAC1B,MAAA,GAAA,CAAI,IAAA,GAAO,OAAO,QAAA,CAAS,QAAA;AAC3B,MAAA,GAAA,CAAI,KAAA,GAAQ,OAAO,WAAA,CAAY,IAAI,gBAAgB,MAAA,CAAO,QAAA,CAAS,MAAM,CAAC,CAAA;AAC1E,MAAA,IAAI,QAAA,CAAS,QAAA,EAAU,GAAA,CAAI,QAAA,GAAW,QAAA,CAAS,QAAA;AAAA,IACjD,CAAA,CAAA,MAAQ;AAAA,IAER;AAEA,IAAA,MAAM,GAAA,GAAM,KAAK,YAAA,EAAa;AAC9B,IAAA,IAAI,GAAA,MAAS,SAAA,GAAY,GAAA;AAEzB,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;AAGA,SAAS,oBAAoB,GAAA,EAA0D;AACrF,EAAA,IAAI,GAAA,KAAQ,OAAO,OAAO,IAAA;AAC1B,EAAA,MAAM,CAAA,GAAI,GAAA,KAAQ,IAAA,GAAO,EAAC,GAAI,GAAA;AAC9B,EAAA,MAAM,QAAA,GAAW,EAAE,QAAA,IAAY,KAAA;AAE/B,EAAA,MAAM,MAAA,GAAS,QAAA,KAAa,MAAA,GAAS,IAAA,GAAQ,EAAE,MAAA,IAAU,KAAA;AACzD,EAAA,OAAO,EAAE,UAAU,MAAA,EAAQ,UAAA,EAAY,EAAE,UAAA,IAAc,GAAA,EAAK,MAAA,EAAQ,CAAA,CAAE,MAAA,EAAO;AAC/E;;;ACxTO,SAAS,cAAc,IAAA,EAA+D;AAC3F,EAAA,MAAM,SAAiC,EAAC;AACxC,EAAA,IAAA,CAAK,gBAAA,CAAiB,oBAAoB,CAAA,CAAE,OAAA,CAAQ,CAAC,EAAA,KAAO;AAC1D,IAAA,MAAM,IAAA,GAAO,EAAA,CAAG,YAAA,CAAa,kBAAkB,CAAA;AAC/C,IAAA,IAAI,CAAC,IAAA,EAAM;AACX,IAAA,MAAA,CAAO,IAAI,CAAA,GAAI,UAAA,CAAW,EAAE,CAAA;AAAA,EAC9B,CAAC,CAAA;AACD,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,WAAW,EAAA,EAAqB;AACvC,EAAA,IAAI,cAAc,gBAAA,EAAkB;AAClC,IAAA,IAAI,EAAA,CAAG,SAAS,UAAA,EAAY,OAAO,GAAG,OAAA,GAAU,EAAA,CAAG,SAAS,IAAA,GAAO,EAAA;AACnE,IAAA,IAAI,GAAG,IAAA,KAAS,OAAA,SAAgB,EAAA,CAAG,OAAA,GAAU,GAAG,KAAA,GAAQ,EAAA;AACxD,IAAA,OAAO,EAAA,CAAG,KAAA;AAAA,EACZ;AACA,EAAA,IAAI,EAAA,YAAc,mBAAA,IAAuB,EAAA,YAAc,iBAAA,SAA0B,EAAA,CAAG,KAAA;AACpF,EAAA,OAAO,EAAA,CAAG,WAAA,EAAa,IAAA,EAAK,IAAK,EAAA;AACnC;AAGA,SAAS,WAAA,CAAY,IAAgC,QAAA,EAAyB;AAC5E,EAAA,IAAI,CAAC,EAAA,EAAI;AACT,EAAA,IACE,EAAA,YAAc,qBACd,EAAA,YAAc,gBAAA,IACd,cAAc,iBAAA,IACd,EAAA,YAAc,mBAAA,IACd,EAAA,YAAc,mBAAA,EACd;AACA,IAAA,EAAA,CAAG,QAAA,GAAW,QAAA;AAAA,EAChB,WAAW,QAAA,EAAU;AACnB,IAAA,EAAA,CAAG,YAAA,CAAa,iBAAiB,MAAM,CAAA;AAAA,EACzC,CAAA,MAAO;AACL,IAAA,EAAA,CAAG,gBAAgB,eAAe,CAAA;AAAA,EACpC;AACF;AAGA,SAAS,SAAA,CAAU,MAA4B,OAAA,EAAuB;AACpE,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,aAAA,CAAc,oBAAoB,CAAA;AAClD,EAAA,IAAI,EAAA,KAAO,WAAA,GAAc,OAAA;AAC3B;AAEA,IAAM,eAAA,GAAkB,yBAAA;AAIxB,SAAS,mBAAmB,IAAA,EAAkC;AAC5D,EAAA,IAAI,IAAA,CAAK,aAAA,CAAc,CAAA,CAAA,EAAI,eAAe,EAAE,CAAA,EAAG;AAC/C,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,aAAA,CAAc,OAAO,CAAA;AAC5C,EAAA,KAAA,CAAM,EAAA,GAAK,eAAA;AACX,EAAA,KAAA,CAAM,WAAA,GACJ,+TAAA;AAIF,EAAA,IAAA,CAAK,QAAQ,KAAK,CAAA;AACpB;AAGA,SAAS,aAAA,CAAc,IAAgC,UAAA,EAA2B;AAChF,EAAA,IAAI,CAAC,EAAA,EAAI;AACT,EAAA,IAAI,UAAA,EAAY,EAAA,CAAG,YAAA,CAAa,uBAAA,EAAyB,EAAE,CAAA;AAAA,OACtD,EAAA,CAAG,gBAAgB,uBAAuB,CAAA;AACjD;AAKA,SAAS,iBAAA,CAAkB,MAA4B,OAAA,EAA4B;AACjF,EAAA,IAAI,CAAC,OAAA,EAAS;AACd,EAAA,MAAM,IAAA,GAAO,IAAA,YAAgB,UAAA,GAAa,IAAA,CAAK,IAAA,GAAO,IAAA;AACtD,EAAA,IAAI,gBAAgB,WAAA,EAAa;AAC/B,IAAA,IAAA,CAAK,MAAM,UAAA,GAAa,0CAAA;AACxB,IAAA,IAAA,CAAK,MAAM,OAAA,GAAU,GAAA;AACrB,IAAA,IAAA,CAAK,MAAM,SAAA,GAAY,aAAA;AACvB,IAAA,MAAA,CAAO,UAAA,CAAW,SAAS,GAAG,CAAA;AAAA,EAChC,CAAA,MAAO;AACL,IAAA,OAAA,EAAQ;AAAA,EACV;AACF;AAMA,IAAM,0BAAA,GAA6B,GAAA;AAWnC,SAAS,aAAA,CAAc,MAA4B,IAAA,EAAuC;AACxF,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,aAAA,CAAc,sBAAsB,CAAA;AAC3D,EAAA,IAAI,CAAC,WAAW,OAAO,KAAA;AACvB,EAAA,IAAI,SAAA,YAAqB,WAAA,EAAa,SAAA,CAAU,MAAA,GAAS,KAAA;AAAA,OACpD,SAAA,CAAU,gBAAgB,QAAQ,CAAA;AACvC,EAAA,IAAI,IAAA,EAAM;AACR,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AAAA,EAChB,CAAA,MAAO;AACL,IAAA,IAAA,CAAK,gBAAA,CAA8B,yCAAyC,CAAA,CAAE,OAAA,CAAQ,CAAC,EAAA,KAAO;AAC5F,MAAA,EAAA,CAAG,MAAA,GAAS,IAAA;AAAA,IACd,CAAC,CAAA;AAAA,EACH;AACA,EAAA,OAAO,IAAA;AACT;AA6BO,SAAS,cAAA,CACd,IAAA,EACA,MAAA,EACA,GAAA,EACM;AACN,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,aAAA,CAAc,MAAM,CAAA;AACtC,EAAA,IAAI,UAAA,GAAa,KAAA;AACjB,EAAA,kBAAA,CAAmB,IAAI,CAAA;AAEvB,EAAA,MAAM,GAAA,GAAM,CAAC,OAAA,EAAyB,MAAA,KAAyC;AAC7E,IAAA,IAAI,UAAA,EAAY;AAChB,IAAA,IAAI,CAAC,OAAO,UAAA,EAAY;AACtB,MAAA,SAAA,CAAU,MAAM,gCAAgC,CAAA;AAChD,MAAA;AAAA,IACF;AACA,IAAA,UAAA,GAAa,IAAA;AACb,IAAA,SAAA,CAAU,MAAM,EAAE,CAAA;AAClB,IAAA,WAAA,CAAY,SAAS,IAAI,CAAA;AACzB,IAAA,aAAA,CAAc,SAAS,IAAI,CAAA;AAC3B,IAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAC3B,IAAA,MAAM,YAAA,GAAe,MAAA,CAAO,UAAA,CAAW,gBAAA,IAAoB,0BAAA;AAC3D,IAAA,GAAA,CACG,gBAAA,CAAiB,MAAM,CAAA,CACvB,IAAA,CAAK,MAAM;AACV,MAAA,aAAA,CAAc,SAAS,KAAK,CAAA;AAC5B,MAAA,aAAA,CAAc,MAAM,IAAI,CAAA;AACxB,MAAA,MAAM,IAAA,GAAO,KAAK,GAAA,CAAI,CAAA,EAAG,gBAAgB,IAAA,CAAK,GAAA,KAAQ,SAAA,CAAU,CAAA;AAChE,MAAA,MAAA,CAAO,WAAW,MAAM,iBAAA,CAAkB,MAAM,GAAA,CAAI,OAAO,GAAG,IAAI,CAAA;AAAA,IACpE,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AACX,MAAA,aAAA,CAAc,SAAS,KAAK,CAAA;AAC5B,MAAA,WAAA,CAAY,SAAS,KAAK,CAAA;AAC1B,MAAA,SAAA,CAAU,MAAM,yCAAyC,CAAA;AAAA,IAC3D,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM;AACb,MAAA,UAAA,GAAa,KAAA;AAAA,IACf,CAAC,CAAA;AAAA,EACL,CAAA;AAEA,EAAA,IAAI,IAAA,EAAM;AACR,IAAA,IAAA,CAAK,gBAAA,CAAiB,QAAA,EAAU,CAAC,EAAA,KAAO;AACtC,MAAA,EAAA,CAAG,cAAA,EAAe;AAClB,MAAA,MAAM,aAAqC,EAAC;AAC5C,MAAA,IAAI,SAAS,IAAI,CAAA,CAAE,OAAA,CAAQ,CAAC,OAAO,GAAA,KAAQ;AACzC,QAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,UAAA,CAAW,GAAG,CAAA,GAAI,KAAA;AAAA,MACnD,CAAC,CAAA;AACD,MAAA,MAAM,SAAA,GACH,EAAA,CAAmB,SAAA,IAAa,IAAA,CAAK,cAAc,qCAAqC,CAAA;AAC3F,MAAA,GAAA,CAAI,SAAA,EAAW,EAAE,GAAG,aAAA,CAAc,IAAI,CAAA,EAAG,GAAG,YAAY,CAAA;AAAA,IAC1D,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,IAAA,CAAK,gBAAA,CAA8B,qBAAqB,CAAA,CAAE,OAAA,CAAQ,CAAC,EAAA,KAAO;AAGxE,IAAA,IAAI,IAAA,EAAM,QAAA,CAAS,EAAE,CAAA,EAAG;AACxB,IAAA,EAAA,CAAG,gBAAA,CAAiB,SAAS,MAAM,GAAA,CAAI,IAAI,aAAA,CAAc,IAAI,CAAC,CAAC,CAAA;AAAA,EACjE,CAAC,CAAA;AACH;;;ACnKO,SAAS,WAAW,CAAA,EAAmB;AAC5C,EAAA,OAAO,CAAA,CAAE,OAAA,CAAQ,IAAA,EAAM,OAAO,CAAA,CAAE,OAAA,CAAQ,IAAA,EAAM,MAAM,CAAA,CAAE,OAAA,CAAQ,IAAA,EAAM,MAAM,CAAA;AAC5E;AAEO,SAAS,WAAW,CAAA,EAAmB;AAC5C,EAAA,OAAO,UAAA,CAAW,CAAC,CAAA,CAAE,OAAA,CAAQ,MAAM,QAAQ,CAAA;AAC7C;AAaO,SAAS,oBAAA,CAAqB,MAA4B,OAAA,EAA4B;AAC3F,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,MAAM,WAAW,IAAA,CAAK,gBAAA;AAAA,MACpB;AAAA,KAEF;AACA,IAAA,QAAA,CAAS,OAAA,CAAQ,CAAC,EAAA,KAAO;AACvB,MAAA,EAAA,CAAG,gBAAgB,SAAS,CAAA;AAC5B,MAAA,EAAA,CAAG,gBAAA,CAAiB,SAAS,OAAO,CAAA;AAAA,IACtC,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,IAAA,CAAK,gBAAA,CAAiB,2CAA2C,CAAA,CAAE,OAAA,CAAQ,CAAC,EAAA,KAAO;AACjF,IAAA,IAAI,EAAA,YAAc,WAAA,IAAe,EAAA,CAAG,QAAA,CAAS,MAAA,KAAW,KAAK,CAAC,EAAA,CAAG,WAAA,EAAa,IAAA,EAAK,EAAG;AACpF,MAAA,EAAA,CAAG,MAAM,OAAA,GAAU,KAAA;AAAA,IACrB;AAAA,EACF,CAAC,CAAA;AACH;;;AC5EA,IAAM,UAAA,GAAa,GAAA;AACnB,IAAM,SAAS,UAAA,GAAa,CAAA;AAC5B,IAAM,SAAS,UAAA,GAAa,CAAA;AAC5B,IAAM,iBAAiB,CAAC,SAAA,EAAW,WAAW,SAAA,EAAW,SAAA,EAAW,WAAW,SAAS,CAAA;AACxF,IAAM,eAAA,GAAkB,kDAAA;AACxB,IAAM,kBAAA,GAAqB,4DAAA;AAC3B,IAAM,oBAAA,GAAuB,GAAA;AAC7B,IAAM,iBAAA,GAAoB,CAAA,QAAA,EAAW,oBAAoB,CAAA,mBAAA,EAAsB,oBAAoB,CAAA,OAAA,CAAA;AASnG,IAAM,qBAAA,GAAwB,GAAA;AAE9B,IAAM,eAAA,GAAkB,CAAC,KAAA,EAAe,OAAA,KACtC,eAAe,qBAAqB,CAAA,eAAA,EAAkB,OAAO,CAAA,UAAA,EAAa,KAAK,CAAA,CAAA,CAAA;AAGjF,SAAS,UAAA,CAAW,UAAkB,MAAA,EAA0C;AAC9E,EAAA,MAAM,GAAA,GAAO,QAAA,GAAW,IAAA,CAAK,EAAA,GAAM,GAAA;AACnC,EAAA,OAAO,EAAE,CAAA,EAAG,MAAA,GAAS,MAAA,GAAS,KAAK,GAAA,CAAI,GAAG,CAAA,EAAG,CAAA,EAAG,MAAA,GAAS,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,EAAE;AAClF;AAGA,SAAS,WAAA,CAAY,YAAoB,QAAA,EAA0B;AACjE,EAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,UAAA,EAAY,MAAM,CAAA;AAC3C,EAAA,MAAM,GAAA,GAAM,UAAA,CAAW,QAAA,EAAU,MAAM,CAAA;AACvC,EAAA,MAAM,QAAA,GAAW,QAAA,GAAW,UAAA,GAAa,GAAA,GAAM,CAAA,GAAI,CAAA;AACnD,EAAA,OAAO,CAAA,EAAA,EAAK,MAAM,CAAA,CAAA,EAAI,MAAM,MAAM,KAAA,CAAM,CAAC,IAAI,KAAA,CAAM,CAAC,MAAM,MAAM,CAAA,CAAA,EAAI,MAAM,CAAA,GAAA,EAAM,QAAQ,MAAM,GAAA,CAAI,CAAC,CAAA,CAAA,EAAI,GAAA,CAAI,CAAC,CAAA,EAAA,CAAA;AAC9G;AAYO,SAAS,mBAAA,CACd,YAAA,EACA,YAAA,EACA,UAAA,GAAa,CAAA,EACL;AACR,EAAA,IAAI,YAAA,IAAgB,GAAG,OAAO,CAAA;AAC9B,EAAA,MAAM,eAAe,GAAA,GAAM,YAAA;AAC3B,EAAA,MAAM,WAAA,GAAc,YAAA,GAAe,YAAA,GAAe,YAAA,GAAe,CAAA;AACjE,EAAA,MAAM,YAAA,GAAA,CAAgB,MAAM,WAAA,IAAe,GAAA;AAC3C,EAAA,OAAO,aAAa,GAAA,GAAM,YAAA;AAC5B;AAoBA,SAAS,eAAA,CAAgB,UAA8B,QAAA,EAAoC;AACzF,EAAA,MAAM,aAAa,QAAA,GAAW,KAAA,CAAM,KAAK,QAAA,CAAS,QAAQ,IAAI,EAAC;AAC/D,EAAA,MAAM,YAAY,QAAA,GAAW,KAAA,CAAM,KAAK,QAAA,CAAS,QAAQ,IAAI,EAAC;AAC9D,EAAA,IAAI,QAAA,WAAmB,MAAA,GAAS,KAAA;AAChC,EAAA,SAAA,CAAU,OAAA,CAAQ,CAAC,EAAA,KAAO;AACxB,IAAA,IAAI,EAAE,cAAc,WAAA,CAAA,EAAc;AAClC,IAAA,EAAA,CAAG,MAAM,UAAA,GAAa,MAAA;AACtB,IAAA,EAAA,CAAG,MAAM,OAAA,GAAU,GAAA;AACnB,IAAA,EAAA,CAAG,KAAA,CAAM,SAAA,GAAY,eAAA,CAAgB,IAAA,EAAM,GAAgB,CAAA;AAAA,EAC7D,CAAC,CAAA;AAMD,EAAA,SAAA,CAAU,OAAA,CAAQ,CAAC,EAAA,KAAO;AACxB,IAAA,IAAI,EAAA,YAAc,WAAA,EAAa,KAAK,EAAA,CAAG,YAAA;AAAA,EACzC,CAAC,CAAA;AACD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,UAAA,CAAW,OAAA,CAAQ,CAAC,EAAA,KAAO;AACzB,MAAA,IAAI,EAAE,cAAc,WAAA,CAAA,EAAc;AAClC,MAAA,EAAA,CAAG,MAAM,UAAA,GAAa,iBAAA;AACtB,MAAA,EAAA,CAAG,MAAM,OAAA,GAAU,GAAA;AACnB,MAAA,EAAA,CAAG,KAAA,CAAM,SAAA,GAAY,eAAA,CAAgB,IAAA,EAAM,GAAgB,CAAA;AAAA,IAC7D,CAAC,CAAA;AACD,IAAA,SAAA,CAAU,OAAA,CAAQ,CAAC,EAAA,KAAO;AACxB,MAAA,IAAI,EAAE,cAAc,WAAA,CAAA,EAAc;AAClC,MAAA,EAAA,CAAG,MAAM,UAAA,GAAa,iBAAA;AACtB,MAAA,EAAA,CAAG,MAAM,OAAA,GAAU,GAAA;AACnB,MAAA,EAAA,CAAG,KAAA,CAAM,SAAA,GAAY,eAAA,CAAgB,CAAA,EAAG,CAAC,CAAA;AAAA,IAC3C,CAAC,CAAA;AAAA,EACH,CAAC,CAAA;AACD,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,UAAA,CAAW,MAAM;AACf,MAAA,QAAA,CAAS,MAAA,GAAS,IAAA;AAAA,IACpB,GAAG,oBAAoB,CAAA;AAAA,EACzB;AACF;AAGA,SAAS,UAAU,EAAA,EAAsB;AACvC,EAAA,IAAI,OAAO,qBAAA,KAA0B,UAAA,EAAY,qBAAA,CAAsB,EAAE,CAAA;AAAA,OACpE,UAAA,CAAW,IAAI,CAAC,CAAA;AACvB;AAEA,SAAS,SAAS,QAAA,EAAmC;AACnD,EAAA,MAAM,CAAA,GAAI,SAAS,MAAA,IAAU,CAAA;AAC7B,EAAA,MAAM,eAAe,GAAA,GAAM,CAAA;AAC3B,EAAA,MAAM,MAAA,GAAS,QAAA,CACZ,GAAA,CAAI,CAAC,KAAK,CAAA,KAAM;AACf,IAAA,MAAM,QAAQ,CAAA,GAAI,YAAA;AAClB,IAAA,MAAM,MAAM,KAAA,GAAQ,YAAA;AACpB,IAAA,MAAM,QAAQ,GAAA,CAAI,QAAA,IAAY,cAAA,CAAe,CAAA,GAAI,eAAe,MAAM,CAAA;AACtE,IAAA,MAAM,UAAA,GAAa,QAAQ,YAAA,GAAe,CAAA;AAC1C,IAAA,MAAM,UAAA,GAAa,UAAA,CAAW,UAAA,EAAY,MAAA,GAAS,IAAI,CAAA;AACvD,IAAA,OACE,CAAA,SAAA,EAAY,WAAA,CAAY,KAAA,EAAO,GAAG,CAAC,CAAA,QAAA,EAAW,UAAA,CAAW,KAAK,CAAC,CAAA,iDAAA,EACnD,UAAA,CAAW,CAAC,CAAA,KAAA,EAAQ,UAAA,CAAW,CAAC,CAAA,oEAAA,EACvB,UAAU,CAAA,CAAA,EAAI,UAAA,CAAW,CAAC,CAAA,CAAA,EAAI,UAAA,CAAW,CAAC,CAAA,GAAA,EAAM,UAAA,CAAW,GAAA,CAAI,KAAK,CAAC,CAAA,OAAA,CAAA;AAAA,EAE9F,CAAC,CAAA,CACA,IAAA,CAAK,EAAE,CAAA;AACV,EAAA,OACE,CAAA,0CAAA,EAA6C,UAAU,CAAA,CAAA,EAAI,UAAU,CAAA,SAAA,EAAY,UAAU,CAAA,UAAA,EAAa,UAAU,CAAA,8BAAA,EACnF,MAAM,CAAA,wCAAA,EAGE,MAAM,SAAS,MAAM,CAAA,uBAAA,CAAA;AAGhE;AAEO,IAAM,iBAAA,GAAoC;AAAA,EAC/C,KAAK,MAAA,EAA+B;AASlC,IAAA,OACE,CAAA,yDAAA,EAC8B,MAAA,CAAO,WAAA,IAAe,EAAE,CAAA,sEAAA,EAGa,MAAA,CAAO,OAAA,IAAW,EAAE,CAAA,oEAAA,EACtB,MAAA,CAAO,QAAA,IAAY,EAAE,CAAA,YAAA,CAAA;AAAA,EAG1F,CAAA;AAAA,EAEA,IAAA,CAAK,IAAA,EAA4B,MAAA,EAAuB,GAAA,EAA8B;AAIpF,IAAA,oBAAA,CAAqB,IAAA,EAAM,IAAI,OAAO,CAAA;AAEtC,IAAA,MAAM,QAAA,GAAW,MAAA,CAAO,QAAA,IAAY,EAAC;AACrC,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,aAAA,CAA2B,yBAAyB,CAAA;AAC3E,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,aAAA,CAAiC,mBAAmB,CAAA;AACzE,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,aAAA,CAA2B,2BAA2B,CAAA;AACzE,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,aAAA,CAA2B,yBAAyB,CAAA;AACxE,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,aAAA,CAA2B,oBAAoB,CAAA;AAMpE,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,aAAA,CAA2B,yBAAyB,CAAA;AACxE,IAAA,IAAI,QAAQ,MAAA,CAAO,kBAAA,CAAmB,cAAc,QAAA,CAAS,QAAQ,IAAI,kBAAkB,CAAA;AAC3F,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,aAAA,CAA2B,mBAAmB,CAAA;AAEhE,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,MAAA,CAAO,UAAA,EAAY;AAIpC,IAAA,IAAA,CAAK,gBAAA,CAAiB,wBAAwB,CAAA,CAAE,OAAA,CAAQ,CAAC,GAAA,KAAQ;AAC/D,MAAA,GAAA,CAAI,gBAAA,CAAiB,OAAA,EAAS,MAAM,GAAA,CAAI,SAAS,CAAA;AAAA,IACnD,CAAC,CAAA;AAcD,IAAA,MAAM,YAAA,GAAe,CAAC,UAAA,EAAoB,MAAA,EAAiB,QAAA,KAA4B;AACrF,MAAA,IAAA,CAAK,gBAAA,CAAiB,0BAA0B,CAAA,CAAE,OAAA,CAAQ,CAAC,EAAA,KAAO;AAChE,QAAA,EAAA,CAAG,WAAA,GAAc,UAAA;AAAA,MACnB,CAAC,CAAA;AACD,MAAA,MAAM,KAAA,GAAQ,SAAS,MAAA,GAAS,KAAA;AAChC,MAAA,MAAM,KAAA,GAAQ,SAAS,KAAA,GAAQ,MAAA;AAC/B,MAAA,IAAI,KAAA,QAAa,MAAA,GAAS,IAAA;AAC1B,MAAA,eAAA,CAAgB,WAAW,KAAK,CAAA;AAChC,MAAA,IAAI,CAAC,QAAA,EAAU;AACb,QAAA,cAAA,GAAiB,IAAA;AACjB,QAAA,IAAA,CAAK,gBAAA,CAA8B,yBAAyB,CAAA,CAAE,OAAA,CAAQ,CAAC,GAAA,KAAQ;AAC7E,UAAA,GAAA,CAAI,MAAA,GAAS,IAAA;AAAA,QACf,CAAC,CAAA;AAAA,MACH;AAAA,IACF,CAAA;AAEA,IAAA,IAAI,QAAA,GAAW,KAAA;AACf,IAAA,IAAI,cAAA,GAAiB,KAAA;AAarB,IAAA,IAAA,CAAK,gBAAA,CAAiB,yBAAyB,CAAA,CAAE,OAAA,CAAQ,CAAC,GAAA,KAAQ;AAChE,MAAA,GAAA,CAAI,gBAAA,CAAiB,SAAS,MAAM;AAClC,QAAA,IAAI,cAAA,EAAgB;AACpB,QAAA,MAAM,KAAA,GAAQ,KAAA,IAAS,CAAC,KAAA,CAAM,MAAA,GAAS,QAAQ,MAAA,IAAU,CAAC,MAAA,CAAO,MAAA,GAAS,MAAA,GAAS,IAAA;AACnF,QAAA,IAAI,CAAC,KAAA,EAAO;AACZ,QAAA,QAAA,GAAW,KAAA;AACX,QAAA,OAAA,CAAQ,QAAA,GAAW,KAAA;AACnB,QAAA,IAAI,OAAA,UAAiB,WAAA,GAAc,EAAA;AACnC,QAAA,eAAA,CAAgB,OAAO,SAAS,CAAA;AAAA,MAClC,CAAC,CAAA;AAAA,IACH,CAAC,CAAA;AAED,IAAA,OAAA,CAAQ,gBAAA,CAAiB,SAAS,MAAM;AACtC,MAAA,IAAI,QAAA,EAAU;AACd,MAAA,QAAA,GAAW,IAAA;AACX,MAAA,OAAA,CAAQ,QAAA,GAAW,IAAA;AACnB,MAAA,IAAI,OAAA,UAAiB,WAAA,GAAc,EAAA;AAEnC,MAAA,MAAM,MAAA,GAAS,cAAc,IAAI,CAAA;AAKjC,MAAA,GAAA,CACG,gBAAA,CAAiB,MAAM,CAAA,CACvB,IAAA,CAAK,CAAC,QAAA,KAAa;AAClB,QAAA,MAAM,KAAA,GAAQ,SAAS,SAAA,CAAU,CAAC,MAAM,CAAA,CAAE,EAAA,KAAO,QAAA,CAAS,KAAA,EAAO,SAAS,CAAA;AAC1E,QAAA,MAAM,aAAa,QAAA,CAAS,KAAA,EAAO,SAAS,QAAA,CAAS,KAAK,GAAG,KAAA,IAAS,EAAA;AAItE,QAAA,MAAM,SAAS,KAAA,IAAS,CAAA,IAAK,CAAC,CAAC,QAAA,CAAS,KAAK,CAAA,EAAG,MAAA;AAQhD,QAAA,MAAM,QAAA,GAAW,SAAS,aAAA,KAAkB,IAAA;AAE5C,QAAA,IAAI,KAAA,GAAQ,CAAA,IAAK,CAAC,IAAA,EAAM;AACtB,UAAA,YAAA,CAAa,UAAA,EAAY,QAAQ,QAAQ,CAAA;AACzC,UAAA;AAAA,QACF;AAEA,QAAA,MAAM,aAAa,CAAA,GAAI,IAAA,CAAK,MAAM,IAAA,CAAK,MAAA,KAAW,CAAC,CAAA;AACnD,QAAA,MAAM,WAAW,mBAAA,CAAoB,KAAA,EAAO,QAAA,CAAS,MAAA,IAAU,GAAG,UAAU,CAAA;AAS5E,QAAA,MAAM,UAAA,GAAa,wBAAA,CAAyB,IAAA,CAAK,IAAA,CAAK,MAAM,SAAS,CAAA;AACrE,QAAA,MAAM,gBAAgB,UAAA,GAAa,UAAA,CAAW,UAAA,CAAW,CAAC,CAAC,CAAA,GAAI,CAAA;AAC/D,QAAA,IAAA,CAAK,MAAM,UAAA,GAAa,MAAA;AACxB,QAAA,IAAA,CAAK,KAAA,CAAM,SAAA,GAAY,CAAA,OAAA,EAAU,aAAA,GAAgB,GAAG,CAAA,IAAA,CAAA;AACpD,QAAA,KAAK,KAAK,qBAAA,EAAsB;AAEhC,QAAA,IAAA,CAAK,MAAM,UAAA,GAAa,eAAA;AACxB,QAAA,MAAM,kBAAkB,MAAM;AAC5B,UAAA,IAAA,CAAK,mBAAA,CAAoB,iBAAiB,eAAe,CAAA;AACzD,UAAA,YAAA,CAAa,UAAA,EAAY,QAAQ,QAAQ,CAAA;AAAA,QAC3C,CAAA;AACA,QAAA,IAAA,CAAK,gBAAA,CAAiB,iBAAiB,eAAe,CAAA;AAItD,QAAA,SAAA,CAAU,MAAM;AACd,UAAA,IAAA,CAAK,KAAA,CAAM,SAAA,GAAY,CAAA,OAAA,EAAU,QAAQ,CAAA,IAAA,CAAA;AAAA,QAC3C,CAAC,CAAA;AAAA,MACH,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AACX,QAAA,QAAA,GAAW,KAAA;AACX,QAAA,OAAA,CAAQ,QAAA,GAAW,KAAA;AACnB,QAAA,IAAI,OAAA,UAAiB,WAAA,GAAc,yCAAA;AAAA,MACrC,CAAC,CAAA;AAAA,IACL,CAAC,CAAA;AAAA,EACH;AACF,CAAA;;;AC7TO,IAAM,gBAAA,GAAmD;AAAA,EAC9D,YAAA,EAAc;AAChB,CAAA;;;ACsBO,SAAS,aAAA,CACd,MAAA,EACA,IAAA,GAAmB,QAAA,EACH;AAChB,EAAA,IAAI,CAAC,QAAQ,OAAO,IAAA;AACpB,EAAA,MAAM,SAAS,IAAA,CAAK,aAAA,CAAc,qBAAqB,SAAA,CAAU,MAAM,CAAC,CAAA,EAAA,CAAI,CAAA;AAC5E,EAAA,IAAI,QAAQ,OAAO,MAAA;AACnB,EAAA,IAAI;AACF,IAAA,OAAO,IAAA,CAAK,cAAc,MAAM,CAAA;AAAA,EAClC,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEA,SAAS,UAAU,KAAA,EAAuB;AACxC,EAAA,MAAM,MAAA,GAAS,MAAA;AAGf,EAAA,IAAI,OAAO,GAAA,EAAK,MAAA,SAAe,MAAA,CAAO,GAAA,CAAI,OAAO,KAAK,CAAA;AACtD,EAAA,OAAO,KAAA,CAAM,OAAA,CAAQ,QAAA,EAAU,MAAM,CAAA;AACvC;AAGO,SAAS,WAAA,CACd,QACA,OAAA,EACS;AACT,EAAA,MAAM,EAAA,GAAK,cAAc,MAAM,CAAA;AAC/B,EAAA,IAAI,CAAC,IAAI,OAAO,KAAA;AAChB,EAAA,IAAI,OAAA,CAAQ,SAAS,MAAA,EAAW;AAC9B,IAAA,EAAA,CAAG,YAAY,OAAA,CAAQ,IAAA;AAAA,EACzB,CAAA,MAAA,IAAW,OAAA,CAAQ,IAAA,KAAS,MAAA,EAAW;AACrC,IAAA,EAAA,CAAG,cAAc,OAAA,CAAQ,IAAA;AAAA,EAC3B;AACA,EAAA,EAAA,CAAG,gBAAgB,QAAQ,CAAA;AAC3B,EAAA,OAAO,IAAA;AACT;AAGO,SAAS,YAAY,MAAA,EAAyB;AACnD,EAAA,MAAM,EAAA,GAAK,cAAc,MAAM,CAAA;AAC/B,EAAA,IAAI,CAAC,EAAA,IAAM,EAAE,EAAA,YAAc,cAAc,OAAO,KAAA;AAChD,EAAA,EAAA,CAAG,QAAQ,WAAA,GAAc,GAAA;AACzB,EAAA,EAAA,CAAG,KAAA,CAAM,WAAA,CAAY,SAAA,EAAW,MAAA,EAAQ,WAAW,CAAA;AACnD,EAAA,OAAO,IAAA;AACT;AAGO,SAAS,YAAY,MAAA,EAAyB;AACnD,EAAA,MAAM,EAAA,GAAK,cAAc,MAAM,CAAA;AAC/B,EAAA,IAAI,CAAC,EAAA,IAAM,EAAE,EAAA,YAAc,cAAc,OAAO,KAAA;AAChD,EAAA,OAAO,GAAG,OAAA,CAAQ,WAAA;AAClB,EAAA,EAAA,CAAG,KAAA,CAAM,eAAe,SAAS,CAAA;AACjC,EAAA,OAAO,IAAA;AACT;AAEA,IAAMC,cAAAA,uBAAoB,GAAA,CAAsB;AAAA,EAC9C,QAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAC,CAAA;AAED,SAAS,cAAc,IAAA,EAAwC;AAC7D,EAAA,OAAOA,cAAAA,CAAc,IAAI,IAAwB,CAAA;AACnD;AAOO,IAAM,iBAAN,MAAqB;AAAA,EAClB,IAAA,GAA2B,IAAA;AAAA,EAC3B,MAAA,GAA4B,IAAA;AAAA,EACnB,KAAA;AAAA,EACA,eAAA;AAAA,EACA,aAAA;AAAA,EACA,gBAAA;AAAA,EACA,kBAAA;AAAA;AAAA,EAEA,OAAA,uBAAc,GAAA,EAAyB;AAAA,EAExD,WAAA,CACE,OACA,IAAA,EAOA;AACA,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AACb,IAAA,IAAA,CAAK,kBAAkB,IAAA,EAAM,eAAA;AAC7B,IAAA,IAAA,CAAK,gBAAgB,IAAA,EAAM,aAAA;AAC3B,IAAA,IAAA,CAAK,mBAAmB,IAAA,EAAM,gBAAA;AAC9B,IAAA,IAAA,CAAK,qBAAqB,IAAA,EAAM,gBAAA;AAAA,EAClC;AAAA;AAAA,EAGA,MAAM,OAAA,EAAgC;AACpC,IAAA,IAAI,OAAA,GAAU,CAAA;AACd,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,MAAA,IAAI,IAAA,CAAK,QAAA,CAAS,MAAM,CAAA,EAAG,OAAA,EAAA;AAAA,IAC7B;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEQ,SAAS,MAAA,EAA8B;AAC7C,IAAA,QAAQ,OAAO,IAAA;AAAM,MACnB,KAAK,MAAA;AACH,QAAA,OAAO,WAAA,CAAY,OAAO,MAAA,EAAQ;AAAA,UAChC,MAAM,MAAA,CAAO,IAAA;AAAA,UACb,MAAM,MAAA,CAAO;AAAA,SACd,CAAA;AAAA,MACH,KAAK,YAAA;AACH,QAAA,OAAO,WAAA,CAAY,OAAO,MAAA,EAAQ;AAAA,UAChC,MAAM,MAAA,CAAO,IAAA;AAAA,UACb,MAAM,MAAA,CAAO;AAAA,SACd,CAAA;AAAA,MACH,KAAK,MAAA;AACH,QAAA,OAAO,WAAA,CAAY,OAAO,MAAM,CAAA;AAAA,MAClC,KAAK,MAAA;AACH,QAAA,OAAO,WAAA,CAAY,OAAO,MAAM,CAAA;AAAA,MAClC,KAAK,UAAA;AACH,QAAA,IAAI;AACF,UAAA,MAAA,CAAO,QAAA,CAAS,MAAA,CAAO,MAAA,CAAO,GAAG,CAAA;AACjC,UAAA,OAAO,IAAA;AAAA,QACT,CAAA,CAAA,MAAQ;AACN,UAAA,OAAO,KAAA;AAAA,QACT;AAAA,MACF;AACE,QAAA,IAAI,cAAc,MAAA,CAAO,IAAI,GAAG,OAAO,IAAA,CAAK,cAAc,MAAM,CAAA;AAChE,QAAA,OAAO,KAAA;AAAA;AACX,EACF;AAAA;AAAA,EAGA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,CAAC,OAAA,KAAY,SAAS,CAAA;AAC3C,IAAA,IAAA,CAAK,QAAQ,KAAA,EAAM;AACnB,IAAA,IAAA,CAAK,MAAM,MAAA,EAAO;AAClB,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AAAA,EAChB;AAAA,EAEQ,YAAA,GAA2B;AACjC,IAAA,IAAI,IAAA,CAAK,MAAA,EAAQ,OAAO,IAAA,CAAK,MAAA;AAC7B,IAAA,MAAM,IAAA,GAAO,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA;AACzC,IAAA,IAAA,CAAK,YAAA,CAAa,iBAAiB,EAAE,CAAA;AACrC,IAAA,QAAA,CAAS,IAAA,CAAK,YAAY,IAAI,CAAA;AAC9B,IAAA,MAAM,SAAS,IAAA,CAAK,YAAA,CAAa,EAAE,IAAA,EAAM,QAAQ,CAAA;AACjD,IAAA,MAAA,CAAO,WAAA,CAAY,IAAA,CAAK,OAAA,EAAS,CAAA;AACjC,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEQ,OAAA,GAA4B;AAClC,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,aAAA,CAAc,OAAO,CAAA;AAC5C,IAAA,KAAA,CAAM,WAAA,GAAc,IAAA,CAAK,aAAA,GACrB,CAAA,EAAG,MAAM;AAAA,EAAK,IAAA,CAAK,aAAa,CAAA,CAAA,GAChC,MAAA;AACJ,IAAA,OAAO,KAAA;AAAA,EACT;AAAA,EAEQ,cACN,MAAA,EACS;AAIT,IAAA,MAAM,eAAe,MAAA,CAAO,IAAA,KAAS,MAAA,IAAa,CAAC,CAAC,IAAA,CAAK,gBAAA;AAGzD,IAAA,IAAI,MAAA,CAAO,SAAS,QAAA,EAAU;AAC5B,MAAA,IAAI,CAAC,MAAA,CAAO,MAAA,EAAQ,OAAO,KAAA;AAC3B,MAAA,MAAM,EAAA,GAAK,aAAA,CAAc,MAAA,CAAO,MAAM,CAAA;AACtC,MAAA,IAAI,CAAC,IAAI,OAAO,KAAA;AAChB,MAAA,IAAA,CAAK,QAAQ,EAAE,CAAA;AACf,MAAA,IAAI,YAAA,EAAc;AAChB,QAAA,EAAA,CAAG,SAAA,GAAY,EAAA;AACf,QAAA,IAAA,CAAK,cAAA,CAAe,IAAI,MAAA,EAAQ,QAAA,EAAU,MAAM,IAAA,CAAK,OAAA,CAAQ,EAAE,CAAC,CAAA;AAAA,MAClE,CAAA,MAAO;AACL,QAAA,EAAA,CAAG,SAAA,GAAY,IAAA,CAAK,QAAA,CAAS,MAAA,EAAQ,QAAQ,CAAA;AAC7C,QAAA,IAAA,CAAK,QAAA,CAAS,IAAI,MAAM,CAAA;AAAA,MAC1B;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,MAAA,GAAS,KAAK,YAAA,EAAa;AACjC,IAAA,MAAM,IAAA,GAAO,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA;AACzC,IAAA,MAAM,WAAW,IAAA,CAAK,aAAA,CAAc,MAAA,CAAO,IAAA,EAAM,OAAO,QAAQ,CAAA;AAIhE,IAAA,MAAM,aAAA,GAAgB,MAAA,CAAO,IAAA,KAAS,MAAA,GAAY,kBAAA,GAAqB,EAAA;AAIvE,IAAA,MAAM,cAAA,GAAiB,MAAA,CAAO,KAAA,EAAO,WAAA,GAAc,mBAAA,GAAsB,EAAA;AACzE,IAAA,IAAA,CAAK,SAAA,GAAY,CAAA,gBAAA,EAAmB,MAAA,CAAO,IAAI,CAAA,EAAG,QAAA,GAAW,CAAA,CAAA,EAAI,QAAQ,CAAA,CAAA,GAAK,EAAE,CAAA,EAAG,aAAa,GAAG,cAAc,CAAA,CAAA;AACjH,IAAA,MAAA,CAAO,YAAY,IAAI,CAAA;AAEvB,IAAA,MAAM,UAAU,MAAM;AACpB,MAAA,IAAA,CAAK,QAAQ,IAAI,CAAA;AACjB,MAAA,IAAA,CAAK,MAAA,EAAO;AAAA,IACd,CAAA;AAEA,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,IAAA,CAAK,cAAA,CAAe,IAAA,EAAM,MAAA,EAAQ,MAAA,CAAO,MAAM,OAAO,CAAA;AAAA,IACxD,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,SAAA,GAAY,IAAA,CAAK,QAAA,CAAS,MAAA,EAAQ,OAAO,IAAI,CAAA;AAClD,MAAA,IAAA,CAAK,QAAA,CAAS,IAAA,EAAM,MAAA,EAAQ,OAAO,CAAA;AAAA,IACrC;AAEA,IAAA,IAAI,MAAA,CAAO,cAAA,IAAkB,MAAA,CAAO,cAAA,GAAiB,CAAA,EAAG;AACtD,MAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,OAAA,EAAS,MAAA,CAAO,cAAc,CAAA;AAMvD,MAAA,MAAM,iBAAA,GAAoB,MAAM,YAAA,CAAa,KAAK,CAAA;AAClD,MAAA,IAAA,CAAK,iBAAiB,OAAA,EAAS,iBAAA,EAAmB,EAAE,IAAA,EAAM,MAAM,CAAA;AAChE,MAAA,IAAA,CAAK,iBAAiB,SAAA,EAAW,iBAAA,EAAmB,EAAE,IAAA,EAAM,MAAM,CAAA;AAAA,IACpE;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA,EAGQ,cAAA,CACN,SAAA,EACA,MAAA,EACA,OAAA,EACA,KAAA,EACM;AACN,IAAA,IAAI,CAAC,KAAK,gBAAA,EAAkB;AAC5B,IAAA,MAAM,GAAA,GAA2B;AAAA,MAC/B,MAAA;AAAA,MACA,OAAA;AAAA,MACA,KAAA;AAAA,MACA,SAAS,MAAM;AACb,QAAA,IAAI,MAAA,CAAO,KAAK,KAAA,EAAO,IAAA,CAAK,QAAQ,MAAA,CAAO,GAAA,CAAI,KAAA,EAAO,MAAA,CAAO,GAAG,CAAA;AAChE,QAAA,IAAI,MAAA,CAAO,KAAK,GAAA,EAAK,MAAA,CAAO,SAAS,MAAA,CAAO,MAAA,CAAO,IAAI,GAAG,CAAA;AAC1D,QAAA,KAAA,EAAM;AAAA,MACR;AAAA,KACF;AAGA,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,gBAAA,CAAiB,SAAA,EAA0B,GAAG,CAAA;AACnE,IAAA,IAAI,OAAA,EAAS,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,WAAW,OAAO,CAAA;AAAA,EAClD;AAAA;AAAA,EAGQ,QAAQ,SAAA,EAA0B;AACxC,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,SAAS,CAAA;AAC1C,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAA,OAAA,EAAQ;AACR,IAAA,IAAA,CAAK,OAAA,CAAQ,OAAO,SAAS,CAAA;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,aAAA,CACN,MACA,QAAA,EACQ;AACR,IAAA,IAAI,SAAS,OAAA,EAAS;AACpB,MAAA,MAAM,MACJ,QAAA,KAAa,UAAA,IACb,aAAa,WAAA,IACb,QAAA,KAAa,gBACT,QAAA,GACA,cAAA;AACN,MAAA,OAAO,aAAa,GAAG,CAAA,CAAA;AAAA,IACzB;AACA,IAAA,IAAI,SAAS,QAAA,EAAU;AACrB,MAAA,OAAO,CAAA,UAAA,EAAa,QAAA,KAAa,KAAA,GAAQ,KAAA,GAAQ,QAAQ,CAAA,CAAA;AAAA,IAC3D;AACA,IAAA,OAAO,EAAA;AAAA,EACT;AAAA,EAEQ,QAAA,CACN,QACA,OAAA,EACQ;AAGR,IAAA,MAAM,SAAS,MAAA,CAAO,UAAA,GAAa,gBAAA,CAAiB,MAAA,CAAO,UAAU,CAAA,GAAI,MAAA;AACzE,IAAA,IAAI,MAAA,EAAQ,OAAO,MAAA,CAAO,IAAA,CAAK,QAAQ,OAAO,CAAA;AAE9C,IAAA,IAAI,OAAO,IAAA,KAAS,MAAA,SAAkB,cAAA,CAAe,MAAA,CAAO,MAAM,OAAO,CAAA;AACzE,IAAA,IAAI,KAAK,eAAA,EAAiB;AACxB,MAAA,MAAM,GAAA,GAA4B;AAAA,QAChC,MAAA;AAAA,QACA,OAAA;AAAA,QACA,UAAA,EAAAC,WAAAA;AAAA,QACA,UAAA,EAAAC;AAAA,OACF;AACA,MAAA,OAAO,IAAA,CAAK,gBAAgB,GAAG,CAAA;AAAA,IACjC;AACA,IAAA,MAAM,GAAA,GAAM,OAAO,QAAA,GACf,CAAA,4BAAA,EAA+BA,YAAW,MAAA,CAAO,QAAQ,CAAC,CAAA,WAAA,CAAA,GAC1D,EAAA;AACJ,IAAA,MAAM,KAAA,GAAQ,OAAO,KAAA,GACjB,CAAA,yBAAA,EAA4BD,YAAW,MAAA,CAAO,KAAK,CAAC,CAAA,MAAA,CAAA,GACpD,EAAA;AACJ,IAAA,MAAM,GAAA,GAAM,OAAO,OAAA,GACf,CAAA,wBAAA,EAA2BA,YAAW,MAAA,CAAO,OAAO,CAAC,CAAA,MAAA,CAAA,GACrD,EAAA;AACJ,IAAA,MAAM,GAAA,GAAM,OAAO,GAAA,GACf,CAAA,wCAAA,EAA2CA,YAAW,MAAA,CAAO,GAAA,CAAI,KAAK,CAAC,CAAA,SAAA,CAAA,GACvE,EAAA;AACJ,IAAA,MAAM,KAAA,GACJ,OAAA,KAAY,QAAA,GACR,EAAA,GACA,CAAA,0EAAA,CAAA;AACN,IAAA,OAAO,CAAA,wBAAA,EAA2B,KAAK,CAAA,EAAG,GAAG,8BAA8B,KAAK,CAAA,EAAG,GAAG,CAAA,EAAG,GAAG,CAAA,YAAA,CAAA;AAAA,EAC9F;AAAA,EAEQ,QAAA,CACN,IAAA,EACA,MAAA,EACA,OAAA,EACM;AAIN,IAAA,MAAM,SAAS,MAAA,CAAO,UAAA,GAAa,gBAAA,CAAiB,MAAA,CAAO,UAAU,CAAA,GAAI,MAAA;AACzE,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,MAAA,CAAO,KAAK,IAAA,EAAM,MAAA,EAAQ,KAAK,cAAA,CAAe,MAAA,EAAQ,OAAO,CAAC,CAAA;AAC9D,MAAA;AAAA,IACF;AAMA,IAAA,oBAAA,CAAqB,MAAM,OAAO,CAAA;AAElC,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,aAAA,CAAc,8BAA8B,CAAA;AAChE,IAAA,IAAI,MAAA,IAAU,OAAO,GAAA,EAAK;AACxB,MAAA,MAAA,CAAO,gBAAA,CAAiB,SAAS,MAAM;AACrC,QAAA,IAAI,MAAA,CAAO,KAAK,KAAA,EAAO,IAAA,CAAK,QAAQ,MAAA,CAAO,GAAA,CAAI,KAAA,EAAO,MAAA,CAAO,GAAG,CAAA;AAChE,QAAA,IAAI,MAAA,CAAO,KAAK,GAAA,EAAK,MAAA,CAAO,SAAS,MAAA,CAAO,MAAA,CAAO,IAAI,GAAG,CAAA;AAC1D,QAAA,OAAA,IAAU;AAAA,MACZ,CAAC,CAAA;AAAA,IACH;AAKA,IAAA,cAAA,CAAe,MAAM,MAAA,EAAQ,IAAA,CAAK,cAAA,CAAe,MAAA,EAAQ,OAAO,CAAC,CAAA;AAAA,EACnE;AAAA;AAAA,EAGQ,cAAA,CACN,QACA,OAAA,EACmB;AAInB,IAAA,MAAM,iBAAiB,YAAA,EAAa;AACpC,IAAA,OAAO;AAAA,MACL,OAAA;AAAA,MACA,SAAS,MAAM;AACb,QAAA,IAAI,MAAA,CAAO,KAAK,KAAA,EAAO,IAAA,CAAK,QAAQ,MAAA,CAAO,GAAA,CAAI,KAAA,EAAO,MAAA,CAAO,GAAG,CAAA;AAChE,QAAA,IAAI,MAAA,CAAO,KAAK,GAAA,EAAK,MAAA,CAAO,SAAS,MAAA,CAAO,MAAA,CAAO,IAAI,GAAG,CAAA;AAC1D,QAAA,OAAA,IAAU;AAAA,MACZ,CAAA;AAAA,MACA,gBAAA,EAAkB,CAAC,MAAA,KAAW;AAC5B,QAAA,IAAI,CAAC,MAAA,CAAO,UAAA,IAAc,CAAC,KAAK,kBAAA,EAAoB;AAClD,UAAA,OAAO,OAAA,CAAQ,MAAA;AAAA,YACb,IAAI,KAAA;AAAA,cACF;AAAA;AACF,WACF;AAAA,QACF;AACA,QAAA,OAAO,KAAK,kBAAA,CAAmB,MAAA,CAAO,YAAY,MAAA,EAAQ,EAAE,gBAAgB,CAAA;AAAA,MAC9E;AAAA,KACF;AAAA,EACF;AACF,CAAA;AA2BA,SAAS,cAAA,CAAe,MAAc,OAAA,EAAmC;AACvE,EAAA,IAAI,YAAY,OAAA,EAAS;AACvB,IAAA,OAAO,kCAAkC,IAAI,CAAA,MAAA,CAAA;AAAA,EAC/C;AACA,EAAA,OACE,4OAIG,IAAI,CAAA,MAAA,CAAA;AAEX;AAEA,SAASA,YAAW,CAAA,EAAmB;AACrC,EAAA,OAAO,CAAA,CAAE,OAAA,CAAQ,IAAA,EAAM,OAAO,CAAA,CAAE,OAAA,CAAQ,IAAA,EAAM,MAAM,CAAA,CAAE,OAAA,CAAQ,IAAA,EAAM,MAAM,CAAA;AAC5E;AAEA,SAASC,YAAW,CAAA,EAAmB;AACrC,EAAA,OAAOD,WAAAA,CAAW,CAAC,CAAA,CAAE,OAAA,CAAQ,MAAM,QAAQ,CAAA;AAC7C;AAYA,IAAM,MAAA,GAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;;;ACjZR,IAAM,cAAN,MAAkB;AAAA,EACd,GAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EAEQ,OAAA;AAAA,EACA,QAAA;AAAA,EACA,cAAA;AAAA,EACT,OAAA,GAA8B,IAAA;AAAA;AAAA,EAE9B,OAAA,GAAgC,IAAA;AAAA;AAAA,EAEhC,UAAA,GAAa,CAAA;AAAA,EACb,YAAA;AAAA,EACS,SAAA,uBAAgB,GAAA,EAAgC;AAAA,EAEjE,YAAY,OAAA,EAA6B;AACvC,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AACf,IAAA,MAAM,MAAA,GAAS,QAAQ,MAAA,IAAU,OAAA;AACjC,IAAA,IAAA,CAAK,WAAW,IAAI,QAAA,CAAS,MAAA,EAAQ,OAAA,CAAQ,iBAAiB,IAAI,CAAA;AAIlE,IAAA,IAAI,QAAQ,SAAA,EAAW,IAAA,CAAK,QAAA,CAAS,QAAA,CAAS,QAAQ,SAAS,CAAA;AAE/D,IAAA,IAAA,CAAK,GAAA,GAAM,IAAI,QAAA,CAAS,OAAO,CAAA;AAC/B,IAAA,IAAA,CAAK,SAAA,GACH,OAAA,CAAQ,gBAAA,KAAqB,KAAA,IAAS,CAAC,SAAA,EAAU,GAC7C,IAAI,mBAAA,EAAoB,GACxB,IAAI,yBAAA,CAA0B,MAAM,CAAA;AAC1C,IAAA,IAAA,CAAK,QAAA,GAAW,IAAI,cAAA,CAAe,CAAC,KAAA,EAAO,QAAQ,IAAA,CAAK,UAAA,CAAW,KAAA,EAAO,GAAG,CAAA,EAAG;AAAA,MAC9E,iBAAiB,OAAA,CAAQ,eAAA;AAAA,MACzB,eAAe,OAAA,CAAQ,aAAA;AAAA,MACvB,kBAAkB,OAAA,CAAQ,gBAAA;AAAA,MAC1B,gBAAA,EAAkB,CAAC,MAAA,EAAQ,MAAA,EAAQ,YACjC,IAAA,CAAK,gBAAA,CAAiB,MAAA,EAAQ,MAAA,EAAQ,OAAO;AAAA,KAChD,CAAA;AACD,IAAA,IAAA,CAAK,YAAA,GAAe,EAAE,GAAG,OAAA,CAAQ,OAAA,EAAQ;AACzC,IAAA,IAAA,CAAK,cAAA,GAAiB,IAAI,cAAA,CAAe;AAAA,MACvC,OAAO,OAAA,CAAQ,KAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAKf,IAAA,EAAM,CAAC,MAAA,EAAQ,IAAA,KACb,KAAK,GAAA,CAAI,UAAA;AAAA,QACP,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,OAAA,EAAS,IAAA,CAAK,YAAA,EAAa,CAAE,CAAA;AAAA,QACxD;AAAA;AACF,KACH,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,IAAA,GAAsB;AACpB,IAAA,IAAI,CAAC,SAAA,EAAU,EAAG,OAAO,QAAQ,OAAA,EAAQ;AACzC,IAAA,OAAQ,IAAA,CAAK,OAAA,KAAY,IAAA,CAAK,IAAA,EAAK;AAAA,EACrC;AAAA,EAEA,MAAc,IAAA,GAAsB;AAClC,IAAA,MAAM,aAAa,IAAA,CAAK,UAAA;AACxB,IAAA,MAAM,IAAA,CAAK,SAAS,eAAA,EAAgB;AAGpC,IAAA,IAAI,UAAA,KAAe,KAAK,UAAA,EAAY;AAEpC,IAAA,IAAI,IAAA,CAAK,gBAAA,EAAiB,EAAG,IAAA,CAAK,eAAe,KAAA,EAAM;AAEvD,IAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,SAAA,KAAc,KAAA,EAAO;AACpC,MAAA,IAAA,CAAK,OAAA,GAAU,IAAI,WAAA,CAAY;AAAA,QAC7B,MAAA,EAAQ,IAAA,CAAK,OAAA,CAAQ,MAAA,IAAU,OAAA;AAAA,QAC/B,UAAA,EAAY,IAAA,CAAK,OAAA,CAAQ,UAAA,IAAc,GAAA;AAAA,QACvC,QAAA,EAAU;AAAA,UACR,SAAA,EAAW,IAAA,CAAK,OAAA,CAAQ,QAAA,EAAU,SAAA,IAAa,GAAA;AAAA,UAC/C,UAAA,EAAY,IAAA,CAAK,OAAA,CAAQ,QAAA,EAAU,UAAA;AAAA,UACnC,WAAA,EAAa,IAAA,CAAK,OAAA,CAAQ,QAAA,EAAU,WAAA,IAAe;AAAA,SACrD;AAAA;AAAA,QAEA,IAAA,EAAM,CAAC,OAAA,EAAS,WAAA,KACd,KAAK,KAAA,CAAM,OAAA,EAAS,EAAE,eAAA,EAAiB,WAAA,EAAY,EAAG,EAAE,OAAA,EAAS,MAAM,CAAA;AAAA;AAAA,QAEzE,QAAA,EAAU,CAAC,WAAA,EAAa,IAAA,KAAS;AAC/B,UAAA,IAAA,CAAK,KAAA;AAAA,YACH,aAAA;AAAA,YACA;AAAA,cACE,eAAA,EACE,WAAA,KAAgB,YAAA,GACZ,4BAAA,GACA,uBAAA;AAAA,cACN,YAAY,IAAA,CAAK,UAAA;AAAA,cACjB,cAAA,EAAgB,KAAK,cAAA,IAAkB,IAAA;AAAA,cACvC,WAAA,EAAa,KAAK,WAAA,IAAe;AAAA,aACnC;AAAA,YACA,EAAE,SAAS,KAAA;AAAM,WACnB;AAAA,QACF;AAAA,OACD,CAAA;AACD,MAAA,IAAA,CAAK,QAAQ,KAAA,EAAM;AAAA,IACrB;AAAA,EACF;AAAA;AAAA,EAGA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,SAAS,IAAA,EAAK;AACnB,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AACf,IAAA,IAAA,CAAK,SAAS,OAAA,EAAQ;AACtB,IAAA,IAAA,CAAK,eAAe,IAAA,EAAK;AACzB,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AACf,IAAA,IAAA,CAAK,UAAA,EAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,QAAA,CAAS,WAAmB,KAAA,EAAuD;AACjF,IAAA,IAAA,CAAK,QAAA,CAAS,SAAS,SAAS,CAAA;AAChC,IAAA,IAAI,OAAO,UAAA,KAAe,MAAA,OAAgB,QAAA,CAAS,aAAA,CAAc,MAAM,UAAU,CAAA;AACjF,IAAA,IAAI,OAAO,KAAA,KAAU,MAAA,OAAgB,QAAA,CAAS,QAAA,CAAS,MAAM,KAAK,CAAA;AAClE,IAAA,KAAK,IAAA,CAAK,GAAA,CACP,QAAA,CAAS,EAAE,cAAA,EAAgB,SAAA,EAAW,MAAA,EAAQ,KAAA,EAAO,UAAA,EAAY,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,CAAA,CACtF,IAAA,CAAK,CAAC,GAAA,KAAQ,IAAA,CAAK,IAAA,CAAK,UAAA,EAAY,GAAG,CAAC,CAAA,CACxC,KAAA,CAAM,CAAC,GAAA,KAAiB,IAAA,CAAK,SAAA,CAAU,GAAG,CAAC,CAAA;AAAA,EAChD;AAAA;AAAA,EAGA,aAAa,EAAA,EAAyB;AACpC,IAAA,IAAA,CAAK,QAAA,CAAS,aAAa,EAAE,CAAA;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,KAAA,CACE,SAAA,EACA,KAAA,EACA,IAAA,GAAqB,EAAC,EAChB;AACN,IAAA,IAAI,CAAC,WAAU,EAAG;AAClB,IAAA,MAAM,OAAA,GAAU,KAAK,OAAA,KAAY,IAAA;AAEjC,IAAA,IAAI,CAAC,OAAA,IAAW,IAAA,CAAK,UAAA,EAAW,EAAG;AAEnC,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,UAAA,CAAW,SAAA,EAAW,OAAO,IAAI,CAAA;AACpD,IAAA,IAAA,CAAK,IAAA,CAAK,OAAA,EAAS,EAAE,SAAA,EAAW,OAAO,CAAA;AAEvC,IAAA,IAAI,OAAA,EAAS;AAEX,MAAA,KAAK,IAAA,CAAK,cAAA,CAAe,aAAA,CAAc,KAAK,CAAA,CAAE,KAAA,CAAM,CAAC,GAAA,KAAiB,IAAA,CAAK,SAAA,CAAU,GAAG,CAAC,CAAA;AAAA,IAC3F,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,cAAA,CAAe,QAAQ,KAAK,CAAA;AACjC,MAAA,IAAI,IAAA,CAAK,gBAAA,EAAiB,EAAG,IAAA,CAAK,eAAe,KAAA,EAAM;AAAA,IACzD;AAAA,EACF;AAAA;AAAA,EAGQ,UAAA,CACN,SAAA,EACA,KAAA,EACA,IAAA,EACY;AACZ,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,cAAA,EAAe;AACzC,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,IAAA,CAAK,cAAA,EAAe,CAAE,eAAA,EAAgB,CAAE,QAAA;AAAA,IACrD,CAAA,CAAA,MAAQ;AAAA,IAER;AAEA,IAAA,OAAO;AAAA,MACL,SAAA;AAAA,MACA,SAAS,IAAA,CAAK,OAAA,GAAU,UAAU,IAAA,CAAK,OAAO,IAAI,YAAA,EAAa;AAAA,MAC/D,YAAA,EAAc,CAAA;AAAA,MACd,YAAA,EAAc,KAAK,GAAA,EAAI;AAAA,MACvB,MAAA,EAAQ,cAAA;AAAA,MACR,QAAA,EAAU;AAAA,QACR,SAAA,EAAW,IAAA,CAAK,QAAA,CAAS,YAAA,EAAa;AAAA;AAAA,QAEtC,GAAG,IAAA,CAAK,QAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAQR,gBAAgB,GAAA,CAAI,SAAA,IAAa,IAAA,CAAK,QAAA,CAAS,aAAY,IAAK;AAAA,OAClE;AAAA,MACA,OAAA,EAAS;AAAA,QACP,UAAU,GAAA,CAAI,IAAA;AAAA,QACd,UAAU,GAAA,CAAI,QAAA;AAAA,QACd,WAAW,SAAA,CAAU,SAAA;AAAA,QACrB,QAAQ,SAAA,CAAU,QAAA;AAAA,QAClB,QAAA;AAAA,QACA,SAAA,EAAW,IAAA,CAAK,QAAA,CAAS,YAAA,EAAa,IAAK,MAAA;AAAA,QAC3C,WAAW,GAAA,CAAI,SAAA;AAAA,QACf,WAAW,GAAA,CAAI,SAAA;AAAA,QACf,aAAa,GAAA,CAAI,WAAA;AAAA,QACjB,YAAY,GAAA,CAAI,UAAA;AAAA,QAChB,GAAG,IAAA,CAAK;AAAA,OACV;AAAA,MACA,UAAA,EAAY,IAAA,CAAK,SAAA,CAAU,KAAA,EAAO,IAAI,KAAK,CAAA;AAAA,MAC3C,OAAA,EAAS,IAAA,CAAK,OAAA,KAAY,IAAA,GAAO,IAAA,GAAO;AAAA;AAAA;AAAA;AAAA,KAI1C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcQ,SAAA,CACN,OACA,KAAA,EACmD;AACnD,IAAA,IAAI,CAAC,OAAO,OAAO,KAAA;AACnB,IAAA,IAAI,UAAU,KAAA,CAAM,MAAA,KAAW,UAAa,KAAA,CAAM,KAAA,KAAU,SAAY,OAAO,KAAA;AAC/E,IAAA,OAAO,EAAE,GAAG,KAAA,EAAO,MAAA,EAAQ,KAAA,EAAM;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,OAAA,CAAQ,UAAA,EAAoB,IAAA,EAA+C;AAC/E,IAAA,OAAO,KAAK,GAAA,CAAI,OAAA,CAAQ,YAAY,IAAA,CAAK,WAAA,CAAY,IAAI,CAAC,CAAA;AAAA,EAC5D;AAAA;AAAA,EAGA,MAAM,YAAA,CACJ,KAAA,EACA,IAAA,EAC+B;AAC/B,IAAA,OAAO,KAAK,GAAA,CAAI,YAAA,CAAa,OAAO,IAAA,CAAK,WAAA,CAAY,IAAI,CAAC,CAAA;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,kBAAA,CAAsB,IAAA,EAAS,IAAA,EAAoE;AACvG,IAAA,OAAO,kBAAA,CAAmB,IAAA,EAAM,EAAE,GAAG,IAAA,EAAM,SAAS,IAAA,CAAK,aAAA,CAAc,IAAI,CAAA,EAAG,CAAA;AAAA,EAChF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,eAAA,CAA6B,GAAA,EAAc,IAAA,EAA2E;AAC1H,IAAA,OAAO,eAAA,CAAmB,GAAA,EAAK,EAAE,GAAG,IAAA,EAAM,SAAS,IAAA,CAAK,aAAA,CAAc,IAAI,CAAA,EAAG,CAAA;AAAA,EAC/E;AAAA,EAEQ,cAAc,IAAA,EAA6C;AACjE,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,WAAA,CAAY,EAAE,IAAA,EAAM,KAAK,IAAA,EAAM,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAQ,CAAA;AAC7E,IAAA,OAAO,OAAO,GAAA,KAAA,CAAS,MAAM,IAAA,CAAK,GAAA,CAAI,eAAe,GAAA,EAAK,WAAW,CAAA,EAAG,SAAA,IAAa,EAAC;AAAA,EACxF;AAAA;AAAA,EAGQ,gBAAA,GAAuC;AAC7C,IAAA,OAAO,KAAK,QAAA,CAAS,YAAA,MAAkB,IAAA,CAAK,QAAA,CAAS,aAAY,IAAK,MAAA;AAAA,EACxE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBQ,YAAY,IAAA,EAAmD;AACrE,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,cAAA,EAAe;AACzC,IAAA,MAAM,GAAA,GAAM,KAAK,gBAAA,EAAiB;AAClC,IAAA,MAAM,YAAY,OAAA,CAAQ;AAAA,MACxB,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,OAAO,GAAA,CAAI,KAAA;AAAA,MACX,QAAA,EAAU,IAAA,CAAK,QAAA,CAAS,WAAA,EAAY,IAAK,MAAA;AAAA,MACzC,SAAA,EAAW,GAAA;AAAA,MACX,UAAA,EAAY,IAAA,CAAK,QAAA,CAAS,aAAA,EAAc,IAAK,MAAA;AAAA,MAC7C,KAAA,EAAO,IAAA,CAAK,QAAA,CAAS,QAAA,EAAS,IAAK,MAAA;AAAA,MACnC,KAAK,GAAA,CAAI,GAAA;AAAA,MACT,UAAU,GAAA,CAAI,QAAA;AAAA,MACd,WAAW,GAAA,CAAI,SAAA;AAAA,MACf,WAAW,GAAA,CAAI,SAAA;AAAA,MACf,aAAa,GAAA,CAAI,WAAA;AAAA,MACjB,YAAY,GAAA,CAAI,UAAA;AAAA,MAChB,OAAO,GAAA,CAAI;AAAA,KACZ,CAAA;AACD,IAAA,IAAI,GAAA,YAAe,UAAA,GAAa,GAAA;AAChC,IAAA,IAAI,OAAO,IAAA,CAAK,SAAS,CAAA,CAAE,MAAA,KAAW,GAAG,OAAO,IAAA;AAChD,IAAA,OAAO,EAAE,GAAG,IAAA,EAAM,IAAA,EAAM,EAAE,GAAI,IAAA,EAAM,IAAA,IAAQ,EAAC,EAAI,GAAG,SAAA,EAAU,EAAE;AAAA,EAClE;AAAA,EAEQ,UAAA,GAAsB;AAC5B,IAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,UAAA,KAAe,KAAA,EAAO,OAAO,KAAA;AAC9C,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,SAAA;AACZ,MAAA,MAAM,GAAA,GAAM,SAAA,CAAU,UAAA,IAAe,MAAA,CAA8C,UAAA;AACnF,MAAA,IAAI,GAAA,KAAQ,GAAA,IAAO,GAAA,KAAQ,KAAA,EAAO,OAAO,IAAA;AACzC,MAAA,IAAI,GAAA,CAAI,oBAAA,KAAyB,IAAA,EAAM,OAAO,IAAA;AAAA,IAChD,CAAA,CAAA,MAAQ;AAAA,IAER;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAAA,EAEQ,gBAAA,GAA4B;AAClC,IAAA,OAAO,IAAA,CAAK,aAAa,SAAA,KAAc,IAAA;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAA,CACJ,SAAA,EACA,IAAA,EACA,IAAA,EAC0B;AAC1B,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,cAAA,EAAe;AACzC,IAAA,MAAM,OAAO,iBAAA,CAAkB;AAAA,MAC7B,OAAA,EAAS,SAAA;AAAA,MACT,SAAA,EAAW,IAAA,CAAK,QAAA,CAAS,YAAA,EAAa,IAAK,MAAA;AAAA;AAAA;AAAA;AAAA,MAI3C,QAAA,EAAU;AAAA,QACR,QAAA,EAAU,IAAA,CAAK,QAAA,CAAS,WAAA,EAAY,IAAK,MAAA;AAAA,QACzC,SAAA,EAAW,KAAK,gBAAA;AAAiB,OACnC;AAAA,MACA,OAAA,EAAS,GAAA;AAAA,MACT,KAAA,EAAO;AAAA,KACR,CAAA;AAED,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,GAAA,CAAI,QAAQ,SAAA,EAAW,IAAA,EAAmB,IAAA,EAAM,MAAA,IAAU,MAAM,CAAA;AAC5F,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,SAAA,EAAW,QAAQ,CAAA;AACtC,IAAA,IAAA,CAAK,IAAA,CAAK,UAAA,EAAY,EAAE,SAAA,EAAW,UAAU,CAAA;AAE7C,IAAA,MAAME,MAAAA,GAAQ,IAAA,EAAM,KAAA,IAAS,IAAA,CAAK,QAAQ,gBAAA,KAAqB,KAAA;AAC/D,IAAA,IAAIA,MAAAA,IAAS,QAAA,CAAS,OAAA,CAAQ,MAAA,EAAQ;AACpC,MAAA,IAAA,CAAK,YAAA,CAAa,SAAS,OAAO,CAAA;AAAA,IACpC;AACA,IAAA,OAAO,QAAA;AAAA,EACT;AAAA;AAAA,EAGA,YAAY,GAAA,EAA0C;AACpD,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,GAAG,CAAA;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBA,MAAM,gBAAA,CACJ,MAAA,EACA,MAAA,EACA,IAAA,EAC+B;AAC/B,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,cAAA,EAAe;AACzC,IAAA,MAAM,cAAA,GAAiB,IAAA,EAAM,cAAA,IAAkB,YAAA,EAAa;AAC5D,IAAA,MAAM,GAAA,GAAM,MAAA,CAAO,OAAA,IAAW,MAAA,CAAO,UAAA;AACrC,IAAA,MAAM,OAAA,GAAU;AAAA,MACd,SAAA,EAAW,KAAK,gBAAA,EAAiB;AAAA,MACjC,QAAA,EAAU,IAAA,CAAK,QAAA,CAAS,WAAA,EAAY,IAAK,MAAA;AAAA,MACzC,cAAA;AAAA,MACA,MAAM,MAAA,CAAO,IAAA;AAAA,MACb,GAAA;AAAA,MACA,KAAK,GAAA,CAAI,GAAA;AAAA,MACT,UAAU,GAAA,CAAI,QAAA;AAAA,MACd,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,OAAO,GAAA,CAAI,KAAA;AAAA,MACX,WAAW,GAAA,CAAI,SAAA;AAAA,MACf,WAAW,GAAA,CAAI,SAAA;AAAA,MACf,aAAa,GAAA,CAAI,WAAA;AAAA,MACjB,YAAY,GAAA,CAAI,UAAA;AAAA,MAChB,OAAO,GAAA,CAAI;AAAA,KACb;AAOA,IAAA,MAAM,QAAA,GAAW,OAAO,OAAA,GACpB,MAAM,KAAK,GAAA,CAAI,OAAA,CAAQ,OAAO,OAAA,EAAS,OAAA,CAAQ,EAAE,GAAG,OAAA,EAAS,GAAG,MAAA,EAAQ,GAAgB,MAAM,CAAA,GAC9F,MAAM,IAAA,CAAK,GAAA,CAAI,YAAA;AAAA,MACb,OAAO,UAAA,IAAc,EAAA;AAAA,MACrB,OAAA,CAAQ,EAAE,GAAG,OAAA,EAAS,QAAwC;AAAA,KAChE;AAEJ,IAAA,IAAA,CAAK,KAAK,UAAA,EAAY,EAAE,SAAA,EAAW,GAAA,EAAK,UAAU,CAAA;AAClD,IAAA,MAAMA,MAAAA,GAAQ,IAAA,EAAM,KAAA,IAAS,IAAA,CAAK,QAAQ,gBAAA,KAAqB,KAAA;AAC/D,IAAA,IAAIA,UAAS,QAAA,CAAS,OAAA,CAAQ,QAAQ,IAAA,CAAK,YAAA,CAAa,SAAS,OAAO,CAAA;AACxE,IAAA,OAAO,QAAA;AAAA,EACT;AAAA;AAAA,EAIA,WAAA,CAAY,QAAgB,OAAA,EAAoD;AAC9E,IAAA,OAAO,WAAA,CAAY,QAAQ,OAAO,CAAA;AAAA,EACpC;AAAA,EACA,YAAY,MAAA,EAAyB;AACnC,IAAA,OAAO,YAAY,MAAM,CAAA;AAAA,EAC3B;AAAA,EACA,YAAY,MAAA,EAAyB;AACnC,IAAA,OAAO,YAAY,MAAM,CAAA;AAAA,EAC3B;AAAA;AAAA,EAGA,aAAa,OAAA,EAAgC;AAC3C,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,QAAA,CAAS,KAAA,CAAM,OAAO,CAAA;AACzC,IAAA,IAAA,CAAK,KAAK,SAAA,EAAW,EAAE,OAAA,EAAS,OAAA,EAAS,OAAO,CAAA;AAChD,IAAA,OAAO,KAAA;AAAA,EACT;AAAA;AAAA,EAIA,MAAM,QAAQ,KAAA,EAAoC;AAChD,IAAA,MAAM,UAAA,GAAa,KAAK,gBAAA,EAAiB;AACzC,IAAA,IAAA,CAAK,eAAe,EAAE,GAAG,IAAA,CAAK,YAAA,EAAc,GAAG,KAAA,EAAM;AAErD,IAAA,IAAI,WAAU,EAAG;AACf,MAAA,IAAI;AACF,QAAA,QAAA,CAAS,SAAS,aAAA,CAAc,IAAA,CAAK,YAAA,EAAc,IAAA,CAAK,QAAQ,MAAM,CAAA;AAAA,MACxE,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AACA,IAAA,IAAI,IAAA,CAAK,gBAAA,EAAiB,IAAK,CAAC,UAAA,EAAY;AAC1C,MAAA,IAAA,CAAK,eAAe,KAAA,EAAM;AAC1B,MAAA,KAAK,IAAA,CAAK,eAAe,KAAA,EAAM;AAAA,IACjC,CAAA,MAAA,IAAW,CAAC,IAAA,CAAK,gBAAA,MAAsB,UAAA,EAAY;AACjD,MAAA,IAAA,CAAK,eAAe,IAAA,EAAK;AAAA,IAC3B;AAEA,IAAA,MAAM,MAAM,IAAA,CAAK,QAAA,CAAS,cAAa,IAAK,IAAA,CAAK,SAAS,WAAA,EAAY;AACtE,IAAA,IAAI,CAAC,GAAA,EAAK;AACV,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,GAAA,CAAI,OAAA,CAAQ,GAAA,EAAK,KAAK,CAAA;AAAA,IACnC,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,UAAU,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AAAA;AAAA,EAIA,EAAA,CAAG,OAAoB,QAAA,EAAgC;AACrD,IAAA,MAAM,MAAM,IAAA,CAAK,SAAA,CAAU,IAAI,KAAK,CAAA,wBAAS,GAAA,EAAc;AAC3D,IAAA,GAAA,CAAI,IAAI,QAAQ,CAAA;AAChB,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,KAAA,EAAO,GAAG,CAAA;AAC7B,IAAA,OAAO,MAAM,GAAA,CAAI,MAAA,CAAO,QAAQ,CAAA;AAAA,EAClC;AAAA,EAEQ,IAAA,CAAK,OAAoB,OAAA,EAAwB;AACvD,IAAA,IAAA,CAAK,UAAU,GAAA,CAAI,KAAK,CAAA,EAAG,OAAA,CAAQ,CAAC,CAAA,KAAM;AACxC,MAAA,IAAI;AACF,QAAA,CAAA,CAAE,OAAO,CAAA;AAAA,MACX,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAAA,EAEQ,UAAU,GAAA,EAAoB;AACpC,IAAA,MAAM,KAAA,GAAQ,eAAe,KAAA,GAAQ,GAAA,GAAM,IAAI,KAAA,CAAM,MAAA,CAAO,GAAG,CAAC,CAAA;AAChE,IAAA,IAAI,KAAK,OAAA,CAAQ,KAAA,EAAO,OAAA,CAAQ,KAAA,CAAM,WAAW,KAAK,CAAA;AACtD,IAAA,IAAA,CAAK,IAAA,CAAK,SAAS,KAAK,CAAA;AAAA,EAC1B;AAAA,EAEQ,UAAA,CAAW,OAAe,GAAA,EAAuB;AACvD,IAAA,IAAA,CAAK,KAAA,CAAM,KAAA,EAAO,EAAE,QAAA,EAAU,IAAI,KAAA,EAAO,MAAA,EAAQ,GAAA,CAAI,GAAA,IAAO,IAAA,EAAK,EAAG,EAAE,OAAA,EAAS,MAAM,CAAA;AAAA,EACvF;AACF;AAGO,SAAS,kBAAkB,OAAA,EAA0C;AAC1E,EAAA,OAAO,IAAI,YAAY,OAAO,CAAA;AAChC;ACvmBO,IAAM,YAAA,GAAe,cAAkC,IAAI;AAM3D,SAAS,QAAA,GAAwB;AACtC,EAAA,MAAM,MAAA,GAAS,WAAW,YAAY,CAAA;AACtC,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAM,IAAI,MAAM,iDAAiD,CAAA;AAAA,EACnE;AACA,EAAA,OAAO,MAAA;AACT;ACSO,SAAS,cAAc,EAAE,QAAA,EAAAC,WAAU,MAAA,EAAQ,GAAG,SAAQ,EAAuB;AAElF,EAAA,MAAM,GAAA,GAAM,OAA2B,IAAI,CAAA;AAC3C,EAAA,MAAM,QAAA,GAAW,QAAQ,MAAM;AAC7B,IAAA,IAAI,QAAQ,OAAO,MAAA;AACnB,IAAA,IAAI,CAAC,GAAA,CAAI,OAAA,EAAS,GAAA,CAAI,OAAA,GAAU,kBAAkB,OAA6B,CAAA;AAC/E,IAAA,OAAO,GAAA,CAAI,OAAA;AAAA,EACb,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEX,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,KAAK,SAAS,IAAA,EAAK;AACnB,IAAA,OAAO,MAAM,SAAS,OAAA,EAAQ;AAAA,EAChC,CAAA,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAA,2BAAQ,YAAA,CAAa,QAAA,EAAb,EAAsB,KAAA,EAAO,QAAA,EAAW,UAAAA,SAAAA,EAAS,CAAA;AAC3D;;;ACpBA,SAAS,cAAc,CAAA,EAAiD;AACtE,EAAA,OAAO,CAAA,KAAM,QAAQ,OAAO,CAAA,KAAM,YAAY,CAAC,KAAA,CAAM,QAAQ,CAAC,CAAA;AAChE;AAEA,SAAS,UAA+B,KAAA,EAAa;AACnD,EAAA,OAAO,KAAA,KAAU,IAAA,IAAQ,OAAO,KAAA,KAAU,QAAA,GAAW,KAAA,GAAS,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC,CAAA;AAChG;AAEA,SAAS,SAAA,CAAU,IAAA,EAAiB,IAAA,EAAgB,KAAA,EAAkB,IAAA,EAAsC;AAC1G,EAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,IAAA,IAAI,SAAS,OAAA,IAAW,aAAA,CAAc,IAAI,CAAA,IAAK,aAAA,CAAc,KAAK,CAAA,EAAG;AACnE,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,GAAG,KAAA,EAAM;AAAA,IAC7B;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,MAAM,CAAC,GAAA,EAAK,GAAG,IAAI,CAAA,GAAI,IAAA;AACvB,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,EAAG;AACvB,IAAA,MAAM,KAAA,GAAQ,OAAO,GAAG,CAAA;AACxB,IAAA,IAAI,CAAC,MAAA,CAAO,SAAA,CAAU,KAAK,CAAA,IAAK,QAAQ,CAAA,IAAK,KAAA,IAAS,IAAA,CAAK,MAAA,EAAQ,OAAO,IAAA;AAC1E,IAAA,MAAM,IAAA,GAAO,KAAK,KAAA,EAAM;AACxB,IAAA,IAAA,CAAK,KAAK,IAAI,SAAA,CAAU,IAAA,CAAK,KAAK,CAAA,EAAG,IAAA,EAAM,OAAO,IAAI,CAAA;AACtD,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,IAAI,aAAA,CAAc,IAAI,CAAA,EAAG;AACvB,IAAA,IAAI,EAAE,GAAA,IAAO,IAAA,CAAA,EAAO,OAAO,IAAA;AAC3B,IAAA,OAAO,EAAE,GAAG,IAAA,EAAM,CAAC,GAAG,GAAG,SAAA,CAAU,IAAA,CAAK,GAAG,CAAA,EAAG,IAAA,EAAM,KAAA,EAAO,IAAI,CAAA,EAAE;AAAA,EACnE;AACA,EAAA,OAAO,IAAA;AACT;AASO,SAAS,WAAA,CACd,OACA,KAAA,EAC2B;AAC3B,EAAA,MAAM,SAAoC,EAAC;AAC3C,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,EAAG;AAChD,IAAA,MAAA,CAAO,GAAG,CAAA,GAAI,SAAA,CAAU,KAAK,CAAA;AAAA,EAC/B;AACA,EAAA,IAAI,CAAC,OAAO,OAAO,MAAA;AAEnB,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,MAAM,CAAC,SAAS,GAAG,SAAS,IAAI,IAAA,CAAK,UAAA,CAAW,MAAM,GAAG,CAAA;AACzD,IAAA,IAAI,EAAE,WAAW,MAAA,CAAA,EAAS;AAC1B,IAAA,MAAA,CAAO,OAAO,CAAA,GAAI,SAAA,CAAU,MAAA,CAAO,OAAO,CAAA,EAAG,SAAA,EAAW,IAAA,CAAK,WAAA,EAAa,IAAA,CAAK,IAAA,IAAQ,SAAS,CAAA;AAAA,EAClG;AACA,EAAA,OAAO,MAAA;AACT;AAGO,SAAS,oBAAoB,IAAA,EAA4C;AAC9E,EAAA,IAAI,CAAC,aAAA,CAAc,IAAI,CAAA,EAAG,OAAO,MAAA;AACjC,EAAA,MAAM,QAAQ,IAAA,CAAK,iBAAA;AACnB,EAAA,OAAO,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,GAAK,KAAA,GAAqC,MAAA;AACtE;;;AC9DO,SAAS,QAAA,GAIN;AACR,EAAA,MAAM,QAAQ,QAAA,EAAS;AACvB,EAAA,OAAO,WAAA;AAAA,IACL,CAAC,SAAA,EAAW,KAAA,EAAO,IAAA,KAAS;AAC1B,MAAA,KAAA,CAAM,KAAA,CAAM,SAAA,EAAW,KAAA,EAAO,IAAI,CAAA;AAAA,IACpC,CAAA;AAAA,IACA,CAAC,KAAK;AAAA,GACR;AACF;AAcO,SAAS,kBAAA,CACd,WACA,IAAA,EAC0B;AAC1B,EAAA,MAAM,QAAQ,QAAA,EAAS;AACvB,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,SAA2B,IAAI,CAAA;AAC3D,EAAA,MAAM,CAAC,SAAA,EAAW,UAAU,CAAA,GAAI,SAAS,IAAI,CAAA;AAC7C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAuB,IAAI,CAAA;AACrD,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,IAAA,IAAQ,EAAE,CAAA;AAEzC,EAAAC,UAAU,MAAM;AACd,IAAA,IAAI,MAAA,GAAS,IAAA;AACb,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,QAAA,CAAS,IAAI,CAAA;AACb,IAAA,KAAA,CACG,OAAA,CAAQ,SAAA,EAAW,IAAA,EAAM,EAAE,KAAA,EAAO,OAAO,CAAA,CACzC,IAAA,CAAK,CAAC,CAAA,KAAM;AACX,MAAA,IAAI,MAAA,EAAQ,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,IAC9B,CAAC,CAAA,CACA,KAAA,CAAM,CAAC,CAAA,KAAe;AACrB,MAAA,IAAI,MAAA,EAAQ,QAAA,CAAS,CAAA,YAAa,KAAA,GAAQ,CAAA,GAAI,IAAI,KAAA,CAAM,MAAA,CAAO,CAAC,CAAC,CAAC,CAAA;AAAA,IACpE,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM;AACb,MAAA,IAAI,MAAA,aAAmB,KAAK,CAAA;AAAA,IAC9B,CAAC,CAAA;AACH,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,GAAS,KAAA;AAAA,IACX,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,KAAA,EAAO,SAAA,EAAW,OAAO,CAAC,CAAA;AAE9B,EAAA,OAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAA,EAAW,KAAA,EAAM;AAC1C;AAoBO,SAAS,uBAAA,CACd,SAAA,EACA,KAAA,EACA,IAAA,EAC+B;AAC/B,EAAA,MAAM,QAAQ,QAAA,EAAS;AACvB,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,SAAoC,KAAK,CAAA;AACrE,EAAA,MAAM,CAAC,SAAA,EAAW,UAAU,CAAA,GAAI,SAAS,IAAI,CAAA;AAC7C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAuB,IAAI,CAAA;AACrD,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA;AACrC,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,IAAA,IAAQ,EAAE,CAAA;AAEzC,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,MAAA,GAAS,IAAA;AACb,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,QAAA,CAAS,IAAI,CAAA;AACb,IAAA,KAAA,CACG,OAAA,CAAQ,SAAA,EAAW,IAAA,EAAM,EAAE,KAAA,EAAO,OAAO,CAAA,CACzC,IAAA,CAAK,CAAC,CAAA,KAAM;AACX,MAAA,IAAI,CAAC,MAAA,EAAQ;AACb,MAAA,SAAA,CAAU,YAAY,KAAA,EAAO,mBAAA,CAAoB,CAAA,CAAE,IAAI,CAAC,CAAC,CAAA;AAAA,IAC3D,CAAC,CAAA,CACA,KAAA,CAAM,CAAC,CAAA,KAAe;AACrB,MAAA,IAAI,MAAA,EAAQ,QAAA,CAAS,CAAA,YAAa,KAAA,GAAQ,CAAA,GAAI,IAAI,KAAA,CAAM,MAAA,CAAO,CAAC,CAAC,CAAC,CAAA;AAAA,IACpE,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM;AACb,MAAA,IAAI,MAAA,aAAmB,KAAK,CAAA;AAAA,IAC9B,CAAC,CAAA;AACH,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,GAAS,KAAA;AAAA,IACX,CAAA;AAAA,EACF,GAAG,CAAC,KAAA,EAAO,SAAA,EAAW,OAAA,EAAS,QAAQ,CAAC,CAAA;AAExC,EAAA,OAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAA,EAAW,KAAA,EAAM;AAC1C;AAgBO,SAAS,yBAAA,CACd,YACA,IAAA,EACiC;AACjC,EAAA,MAAM,QAAQ,QAAA,EAAS;AACvB,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAA+B,IAAI,CAAA;AAC3D,EAAA,MAAM,CAAC,SAAA,EAAW,UAAU,CAAA,GAAI,SAAS,IAAI,CAAA;AAC7C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAuB,IAAI,CAAA;AACrD,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,EAAE,MAAM,IAAA,EAAM,IAAA,IAAQ,EAAC,EAAG,QAAQ,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,IAAA,EAAM,OAAO,CAAA;AAEnG,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,MAAA,GAAS,IAAA;AACb,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,QAAA,CAAS,IAAI,CAAA;AACb,IAAA,KAAA,CACG,QAAQ,UAAA,EAAY,IAAI,CAAA,CACxB,IAAA,CAAK,CAAC,CAAA,KAAM;AACX,MAAA,IAAI,MAAA,UAAgB,CAAC,CAAA;AAAA,IACvB,CAAC,CAAA,CACA,KAAA,CAAM,CAAC,CAAA,KAAe;AACrB,MAAA,IAAI,MAAA,EAAQ,QAAA,CAAS,CAAA,YAAa,KAAA,GAAQ,CAAA,GAAI,IAAI,KAAA,CAAM,MAAA,CAAO,CAAC,CAAC,CAAC,CAAA;AAAA,IACpE,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM;AACb,MAAA,IAAI,MAAA,aAAmB,KAAK,CAAA;AAAA,IAC9B,CAAC,CAAA;AACH,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,GAAS,KAAA;AAAA,IACX,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,KAAA,EAAO,UAAA,EAAY,OAAO,CAAC,CAAA;AAE/B,EAAA,OAAO,EAAE,IAAA,EAAM,SAAA,EAAW,KAAA,EAAM;AAClC;AAcO,SAAS,8BAAA,CACd,OACA,IAAA,EACsC;AACtC,EAAA,MAAM,QAAQ,QAAA,EAAS;AACvB,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAAsC,IAAI,CAAA;AAClE,EAAA,MAAM,CAAC,SAAA,EAAW,UAAU,CAAA,GAAI,SAAS,IAAI,CAAA;AAC7C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAuB,IAAI,CAAA;AACrD,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA;AACrC,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,EAAE,MAAM,IAAA,EAAM,IAAA,IAAQ,EAAC,EAAG,QAAQ,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,IAAA,EAAM,OAAO,CAAA;AAEnG,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,MAAA,GAAS,IAAA;AACb,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,QAAA,CAAS,IAAI,CAAA;AACb,IAAA,KAAA,CACG,aAAa,KAAA,EAAO,IAAI,CAAA,CACxB,IAAA,CAAK,CAAC,CAAA,KAAM;AACX,MAAA,IAAI,MAAA,UAAgB,CAAC,CAAA;AAAA,IACvB,CAAC,CAAA,CACA,KAAA,CAAM,CAAC,CAAA,KAAe;AACrB,MAAA,IAAI,MAAA,EAAQ,QAAA,CAAS,CAAA,YAAa,KAAA,GAAQ,CAAA,GAAI,IAAI,KAAA,CAAM,MAAA,CAAO,CAAC,CAAC,CAAC,CAAA;AAAA,IACpE,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM;AACb,MAAA,IAAI,MAAA,aAAmB,KAAK,CAAA;AAAA,IAC9B,CAAC,CAAA;AACH,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,GAAS,KAAA;AAAA,IACX,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,KAAA,EAAO,QAAA,EAAU,OAAO,CAAC,CAAA;AAE7B,EAAA,OAAO,EAAE,IAAA,EAAM,SAAA,EAAW,KAAA,EAAM;AAClC;AAaO,SAAS,WAAW,SAAA,EAAqC;AAC9D,EAAA,MAAM,QAAQ,QAAA,EAAS;AACvB,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,QAAA;AAAA,IAC9B,MAAM,KAAA,CAAM,WAAA,CAAY,SAAS,CAAA,IAAK;AAAA,GACxC;AACA,EAAA,MAAM,CAAC,SAAA,EAAW,UAAU,CAAA,GAAI,SAAS,KAAK,CAAA;AAC9C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAuB,IAAI,CAAA;AACrD,EAAA,MAAM,KAAA,GAAQC,OAAO,SAAS,CAAA;AAC9B,EAAA,KAAA,CAAM,OAAA,GAAU,SAAA;AAEhB,EAAA,MAAM,IAAA,GAAO,WAAA;AAAA,IACX,OAAO,IAAA,KAAiD;AACtD,MAAA,UAAA,CAAW,IAAI,CAAA;AACf,MAAA,QAAA,CAAS,IAAI,CAAA;AACb,MAAA,IAAI;AACF,QAAA,MAAM,IAAI,MAAM,KAAA,CAAM,OAAA,CAAQ,KAAA,CAAM,SAAS,IAAI,CAAA;AACjD,QAAA,WAAA,CAAY,CAAC,CAAA;AACb,QAAA,OAAO,CAAA;AAAA,MACT,SAAS,CAAA,EAAG;AACV,QAAA,QAAA,CAAS,CAAA,YAAa,QAAQ,CAAA,GAAI,IAAI,MAAM,MAAA,CAAO,CAAC,CAAC,CAAC,CAAA;AACtD,QAAA,OAAO,IAAA;AAAA,MACT,CAAA,SAAE;AACA,QAAA,UAAA,CAAW,KAAK,CAAA;AAAA,MAClB;AAAA,IACF,CAAA;AAAA,IACA,CAAC,KAAK;AAAA,GACR;AAEA,EAAA,OAAO,EAAE,IAAA,EAAM,QAAA,EAAU,SAAA,EAAW,KAAA,EAAM;AAC5C;AAGO,SAAS,iBAAiB,GAAA,EAA0C;AACzE,EAAA,MAAM,QAAQ,QAAA,EAAS;AACvB,EAAA,OAAO,KAAA,CAAM,YAAY,GAAG,CAAA;AAC9B;ACtOO,SAAS,sBAAA,CACd,MACA,IAAA,EACiC;AACjC,EAAA,MAAM,QAAQ,QAAA,EAAS;AACvB,EAAA,MAAM,IAAA,GAAO,KAAK,MAAA,KAAW,qBAAA;AAG7B,EAAA,MAAM,cAAA,GAAiBC,OAAAA;AAAA,IACrB,MAAM,IAAI,GAAA,CAAI,IAAA,IAAQ,IAAA,GAAO,EAAC,GAAI,cAAA,CAAe,IAAA,EAAM,IAAA,CAAK,GAAG,CAAC,CAAA;AAAA,IAChE,CAAC,IAAI;AAAA;AAAA,GACP;AACA,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIC,QAAAA;AAAA,IAGxB,OAAO,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,GAAO,OAAQ,IAAA,IAAQ,IAAA,EAAO,IAAA,EAAM,KAAA,EAAO,UAAU,KAAA,EAAO,OAAA,EAAS,EAAC,EAAG,SAAS,cAAA,EAAe;AAAA,GAC3H;AAEA,EAAA,MAAM,OAAA,GAAUF,OAAO,IAAI,CAAA;AAC3B,EAAA,OAAA,CAAQ,OAAA,GAAU,IAAA;AAClB,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,EAAE,IAAA,EAAM,IAAA,CAAK,IAAA,IAAQ,EAAC,EAAG,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAQ,CAAA;AAE7E,EAAAD,UAAU,MAAM;AACd,IAAA,IAAI,QAAQ,IAAA,EAAM;AAClB,IAAA,IAAI,MAAA,GAAS,IAAA;AACb,IAAA,MAAM,IAAI,OAAA,CAAQ,OAAA;AAClB,IAAA,QAAA,CAAS,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,GAAO,OAAO,IAAA,EAAM,IAAA,EAAM,KAAA,EAAO,QAAA,EAAU,OAAO,OAAA,EAAS,EAAC,EAAG,OAAA,EAAS,gBAAgB,CAAA;AAClH,IAAA,MAAM,MAAA,GAAS,OACX,UAAA,CAAW,MAAM,UAAU,QAAA,CAAS,CAAC,CAAA,KAAO,CAAA,CAAE,OAAA,GAAU,CAAA,GAAI,EAAE,GAAG,CAAA,EAAG,OAAA,EAAS,IAAA,EAAO,CAAA,EAAG,EAAE,aAAA,IAAiB,CAAA,CAAE,SAAA,IAAa,GAAG,CAAA,GAC5H,MAAA;AAEJ,IAAA,MAAM,UAAyB,EAAC;AAChC,IAAA,KAAK,KAAA,CACF,mBAAmB,IAAA,EAAM;AAAA,MACxB,GAAG,CAAA;AAAA,MACH,UAAU,IAAA,EAAM;AACd,QAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AACjB,QAAA,CAAA,CAAE,YAAY,IAAI,CAAA;AAAA,MACpB,CAAA;AAAA,MACA,WAAW,CAAA,EAAG;AACZ,QAAA,CAAA,CAAE,aAAa,CAAC,CAAA;AAChB,QAAA,IAAI,CAAC,UAAU,IAAA,EAAM;AACrB,QAAA,QAAA,CAAS,EAAE,MAAM,OAAA,EAAS,CAAA,CAAE,SAAc,IAAA,EAAM,KAAA,EAAO,UAAU,KAAA,EAAO,OAAA,EAAS,CAAC,GAAG,OAAO,GAAG,OAAA,EAAS,IAAI,IAAI,CAAA,CAAE,OAAO,GAAG,CAAA;AAAA,MAC9H;AAAA,KACD,CAAA,CACA,IAAA,CAAK,CAAC,CAAA,KAAM;AACX,MAAA,IAAI,QAAQ,QAAA,CAAS,EAAE,MAAM,OAAA,EAAS,CAAA,CAAE,SAAS,IAAA,EAAM,IAAA,EAAM,UAAU,CAAA,CAAE,QAAA,EAAU,SAAS,CAAA,CAAE,OAAA,EAAS,yBAAS,IAAI,GAAA,IAAO,CAAA;AAAA,IAC7H,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM,YAAA,CAAa,MAAM,CAAC,CAAA;AACrC,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,GAAS,KAAA;AACT,MAAA,YAAA,CAAa,MAAM,CAAA;AAAA,IACrB,CAAA;AAAA,EACF,GAAG,CAAC,KAAA,EAAO,MAAM,OAAA,EAAS,IAAA,EAAM,cAAc,CAAC,CAAA;AAE/C,EAAA,MAAM,YAAA,GAAe,IAAI,GAAA,CAAI,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,MAAM,CAAC,CAAA;AAE/D,EAAA,MAAM,OAAA,GAAU,KAAA,CAAM,IAAA,KAAS,IAAA,GAAO,MAAM,OAAA,GAAU,cAAA;AACtD,EAAA,OAAO;AAAA,IACL,SAAS,KAAA,CAAM,OAAA;AAAA,IACf,SAAA,EAAW,IAAA,IAAQ,IAAA,IAAQ,CAAC,KAAA,CAAM,IAAA;AAAA,IAClC,UAAU,KAAA,CAAM,QAAA;AAAA,IAChB,SAAS,KAAA,CAAM,OAAA;AAAA,IACf,MAAA,EAAQ,CAAC,EAAA,KAAQ,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA,GAAI,SAAA,GAAY,YAAA,CAAa,GAAA,CAAI,EAAE,CAAA,GAAI,cAAA,GAAiB;AAAA,GACzF;AACF;AAOO,SAAS,mBAAA,CACd,KACA,IAAA,EACiC;AACjC,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIG,QAAAA,CAAiE,EAAE,KAAA,EAAO,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,CAAA;AACvH,EAAA,MAAM,MAAA,GAASF,MAAAA,CAAO,IAAA,CAAK,GAAG,CAAA;AAC9B,EAAA,MAAA,CAAO,UAAU,IAAA,CAAK,GAAA;AACtB,EAAA,MAAM,SAAS,IAAA,CAAK,SAAA,CAAU,CAAC,GAAA,EAAK,IAAA,CAAK,MAAM,CAAC,CAAA;AAEhD,EAAAD,UAAU,MAAM;AACd,IAAA,IAAI,MAAA,GAAS,IAAA;AACb,IAAA,OAAA,CAAQ,EAAE,KAAA,EAAO,IAAA,EAAM,MAAA,EAAQ,OAAO,CAAA;AACtC,IAAA,MAAM,SAAA,GAAY,OAAO,OAAA,CAAQ,SAAA;AACjC,IAAA,OAAA,CAAQ,OAAA,CAAQ,SAAA,GAAY,SAAA,CAAU,IAAA,CAAK,MAAA,CAAO,OAAA,EAAS,GAAA,EAAK,IAAA,CAAK,MAAM,CAAA,GAAI,IAAI,CAAA,CAChF,IAAA;AAAA,MACC,CAAC,KAAA,KAAU,MAAA,IAAU,OAAA,CAAQ,EAAE,OAAQ,KAAA,IAAS,IAAA,EAAmB,MAAA,EAAQ,IAAA,EAAM,CAAA;AAAA,MACjF,MAAM,MAAA,IAAU,OAAA,CAAQ,EAAE,KAAA,EAAO,MAAM,MAAA,EAAQ,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM;AAAA,KACrE;AACF,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,GAAS,KAAA;AAAA,IACX,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEX,EAAA,MAAM,MAAA,GAAS,sBAAA,CAA0B,IAAA,CAAK,KAAA,EAAO,IAAI,CAAA;AACzD,EAAA,MAAM,QAAA,GAAW,KAAK,KAAA,IAAS,IAAA,GAAO,KAAK,MAAA,IAAU,CAAC,IAAA,CAAK,MAAA,GAAS,MAAA,CAAO,QAAA;AAC3E,EAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,SAAA,EAAW,CAAC,IAAA,CAAK,MAAA,IAAU,MAAA,CAAO,SAAA,EAAW,QAAA,EAAS;AAC5E;AAEA,IAAM,0BAAA,GAA6BI,cAA4D,IAAI,CAAA;AAG5F,SAAS,qBAAqB,KAAA,EAA+E;AAClH,EAAA,OAAO,aAAA,CAAc,2BAA2B,QAAA,EAAU,EAAE,OAAO,KAAA,CAAM,KAAA,EAAM,EAAG,KAAA,CAAM,QAAQ,CAAA;AAClG;AAGO,SAAS,cAAc,OAAA,EAA8D;AAC1F,EAAA,MAAM,GAAA,GAAMC,WAAW,0BAA0B,CAAA;AACjD,EAAA,MAAM,MAAA,GAAS,GAAA,GAAM,GAAA,CAAI,MAAA,CAAO,OAAO,CAAA,GAAI,MAAA;AAC3C,EAAA,OAAO,EAAE,MAAA,EAAQ,SAAA,EAAW,MAAA,KAAW,SAAA,EAAU;AACnD;AC9HO,SAAS,UAAA,CAAW;AAAA,EACzB,KAAA;AAAA,EACA,EAAA,GAAK,OAAA;AAAA,EACL,KAAA;AAAA,EACA,EAAA,GAAK,MAAA;AAAA,EACL,QAAA,EAAAN,SAAAA;AAAA,EACA;AACF,CAAA,EAAoB;AAClB,EAAA,MAAM,QAAQ,QAAA,EAAS;AACvB,EAAA,MAAM,GAAA,GAAME,OAA2B,IAAI,CAAA;AAE3C,EAAAD,UAAU,MAAM;AACd,IAAA,IAAI,OAAO,WAAA,EAAa;AACtB,MAAA,KAAA,CAAM,KAAA,CAAM,KAAA,EAAO,EAAE,GAAG,KAAA,EAAO,eAAA,EAAiB,WAAA,EAAY,EAAG,EAAE,OAAA,EAAS,IAAA,EAAM,CAAA;AAChF,MAAA;AAAA,IACF;AACA,IAAA,IAAI,OAAO,WAAA,EAAa;AACtB,MAAA,MAAM,KAAK,GAAA,CAAI,OAAA;AACf,MAAA,IAAI,CAAC,EAAA,EAAI;AACT,MAAA,MAAM,WAAW,IAAI,oBAAA;AAAA,QACnB,CAAC,OAAA,KAAY;AACX,UAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,YAAA,IAAI,MAAM,cAAA,EAAgB;AACxB,cAAA,KAAA,CAAM,KAAA,CAAM,KAAA,EAAO,EAAE,GAAG,KAAA,EAAO,eAAA,EAAiB,WAAA,EAAY,EAAG,EAAE,OAAA,EAAS,IAAA,EAAM,CAAA;AAChF,cAAA,QAAA,CAAS,UAAA,EAAW;AAAA,YACtB;AAAA,UACF;AAAA,QACF,CAAA;AAAA,QACA,EAAE,WAAW,GAAA;AAAI,OACnB;AACA,MAAA,QAAA,CAAS,QAAQ,EAAE,CAAA;AACnB,MAAA,OAAO,MAAM,SAAS,UAAA,EAAW;AAAA,IACnC;AACA,IAAA;AAAA,EACF,CAAA,EAAG,CAAC,KAAA,EAAO,KAAA,EAAO,EAAE,CAAC,CAAA;AAErB,EAAA,MAAM,QAAA,GACJ,OAAO,OAAA,GACH;AAAA,IACE,OAAA,EAAS,MACP,KAAA,CAAM,KAAA,CAAM,OAAO,EAAE,GAAG,KAAA,EAAO,eAAA,EAAiB,OAAA,EAAQ,EAAG,EAAE,OAAA,EAAS,MAAM;AAAA,MAEhF,EAAC;AAEP,EAAA,OAAOM,aAAAA,CAAc,IAAI,EAAE,GAAA,EAAK,WAAW,GAAG,QAAA,IAAYP,SAAQ,CAAA;AACpE;AAQO,SAAS,YAAA,CAAa,EAAE,OAAA,EAAQ,EAAsB;AAC3D,EAAA,MAAM,QAAQ,QAAA,EAAS;AACvB,EAAAC,UAAU,MAAM;AACd,IAAA,IAAI,OAAA,CAAQ,MAAA,EAAQ,KAAA,CAAM,YAAA,CAAa,OAAO,CAAA;AAAA,EAChD,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AACZ,EAAA,OAAO,IAAA;AACT;ACpDO,SAAS,sBACd,SAAA,EAC0B;AAC1B,EAAA,OAAO,CAAC,WAAW,GAAA,KAAQ;AACzB,IAAA,MAAM,IAAA,GAAa,WAAW,SAAS,CAAA;AACvC,IAAA,IAAA,CAAK,MAAA,CAAOM,aAAAA,CAAc,SAAA,EAAW,GAAG,CAAC,CAAA;AACzC,IAAA,OAAO,MAAM,KAAK,OAAA,EAAQ;AAAA,EAC5B,CAAA;AACF","file":"index.js","sourcesContent":["import type {\n JsonValue,\n MessagePlacement,\n MessagePosition,\n WidgetFormSubmit,\n WidgetSegment,\n WidgetStyle,\n WidgetType,\n XeniaAction,\n} from \"./types\";\n\nconst MESSAGE_TYPES: ReadonlySet<string> = new Set<MessagePlacement>([\n \"banner\",\n \"popup\",\n \"modal\",\n \"inline\",\n]);\n\nconst MESSAGE_POSITIONS: ReadonlySet<string> = new Set<MessagePosition>([\n \"top-left\",\n \"top-right\",\n \"bottom-left\",\n \"bottom-right\",\n \"top\",\n \"bottom\",\n]);\n\n// NOTE: `widgetType` is deliberately NOT added to `ALL_TYPES`/`MESSAGE_TYPES` below — it is an\n// orthogonal field on message-placement actions, not a new `type` value. Keeping `type`'s\n// allowlist untouched is exactly what keeps the PHP SDK's `XeniaActions::KNOWN_TYPES` (same value\n// set) valid with zero PHP changes.\nconst WIDGET_TYPES: ReadonlySet<string> = new Set<WidgetType>([\"standard\", \"spin-wheel\"]);\n\nconst ALL_TYPES: ReadonlySet<string> = new Set<string>([\n \"swap\",\n \"hide\",\n \"show\",\n \"setContent\",\n \"redirect\",\n ...MESSAGE_TYPES,\n]);\n\n/** Type guard for a plain JSON object. */\nfunction isObject(v: JsonValue | undefined): v is { [k: string]: JsonValue } {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\nfunction asString(v: JsonValue | undefined): string | undefined {\n return typeof v === \"string\" ? v : undefined;\n}\n\nfunction asNumber(v: JsonValue | undefined): number | undefined {\n return typeof v === \"number\" ? v : undefined;\n}\n\n/**\n * Validate and narrow a single raw entry into a {@link XeniaAction}.\n * Returns null for anything malformed so a bad entry can't crash the renderer.\n */\nfunction toAction(raw: JsonValue): XeniaAction | null {\n if (!isObject(raw)) return null;\n const type = asString(raw.type);\n if (!type || !ALL_TYPES.has(type)) return null;\n\n if (type === \"redirect\") {\n const url = asString(raw.url);\n return url ? { type, url } : null;\n }\n\n if (type === \"hide\" || type === \"show\") {\n const target = asString(raw.target);\n return target ? { type, target } : null;\n }\n\n if (type === \"swap\" || type === \"setContent\") {\n const target = asString(raw.target);\n if (!target) return null;\n return { type, target, html: asString(raw.html), text: asString(raw.text) };\n }\n\n // Message placement actions (banner/popup/modal/inline).\n const cta = isObject(raw.cta)\n ? {\n label: asString(raw.cta.label) ?? \"\",\n url: asString(raw.cta.url),\n event: asString(raw.cta.event),\n }\n : undefined;\n\n return {\n type: type as MessagePlacement,\n target: asString(raw.target),\n title: asString(raw.title),\n message: asString(raw.message),\n imageUrl: asString(raw.imageUrl),\n html: asString(raw.html),\n // A link-only CTA (empty label, e.g. a spin-wheel's data-xenia-wheel-cta —\n // label is meaningless there, the winHtml/lossHtml design supplies its own button text)\n // must still parse through — gating on `cta.label` alone silently dropped it.\n cta: cta && (cta.label || cta.url) ? cta : undefined,\n dismissAfterMs: asNumber(raw.dismissAfterMs),\n position: asMessagePosition(raw.position),\n widgetType: asWidgetType(raw.widgetType),\n segments: asSegments(raw.segments),\n formSubmit: asFormSubmit(raw.formSubmit),\n style: asWidgetStyle(raw.style),\n spinnerHtml: asString(raw.spinnerHtml),\n winHtml: asString(raw.winHtml),\n lossHtml: asString(raw.lossHtml),\n };\n}\n\nfunction asMessagePosition(v: JsonValue | undefined): MessagePosition | undefined {\n const s = asString(v);\n return s && MESSAGE_POSITIONS.has(s) ? (s as MessagePosition) : undefined;\n}\n\nfunction asWidgetType(v: JsonValue | undefined): WidgetType | undefined {\n const s = asString(v);\n return s && WIDGET_TYPES.has(s) ? (s as WidgetType) : undefined;\n}\n\n/** Narrow a raw `segments` array to label/color/isLoss-only entries — drops anything malformed. */\nfunction asSegments(v: JsonValue | undefined): WidgetSegment[] | undefined {\n if (!Array.isArray(v)) return undefined;\n const segments: WidgetSegment[] = [];\n for (const entry of v) {\n if (!isObject(entry)) continue;\n const id = asString(entry.id);\n const label = asString(entry.label);\n if (!id || !label) continue;\n segments.push({\n id,\n label,\n colorHex: asString(entry.colorHex),\n isLoss: entry.isLoss === true,\n });\n }\n return segments.length ? segments : undefined;\n}\n\n/**\n * Narrow a raw `formSubmit` envelope. Defensive by design (same as the rest of this\n * module) — a malformed envelope (missing `mode`) is dropped entirely rather than\n * passed through half-formed, since the SDK's endpoint-selection logic depends on it.\n */\nfunction asFormSubmit(v: JsonValue | undefined): WidgetFormSubmit | undefined {\n if (!isObject(v)) return undefined;\n const mode = asString(v.mode);\n if (!mode) return undefined;\n return {\n requiresResolve: v.requiresResolve === true,\n mode,\n flowRef: asString(v.flowRef),\n bindingRef: asString(v.bindingRef),\n successDisplayMs: asNumber(v.successDisplayMs),\n };\n}\n\n/**\n * Narrow a raw `style` override. Every field is independently optional/defensive (same\n * philosophy as the rest of this module) — a malformed value for one field just drops that\n * field, it never discards the whole `style` object.\n */\nfunction asWidgetStyle(v: JsonValue | undefined): WidgetStyle | undefined {\n if (!isObject(v)) return undefined;\n const style: WidgetStyle = {\n hideCloseButton: v.hideCloseButton === true,\n hideOverlay: v.hideOverlay === true,\n };\n const hasAny = style.hideCloseButton || style.hideOverlay;\n return hasAny ? style : undefined;\n}\n\n/**\n * Parse render actions out of a webhook-response body.\n *\n * The convention: marketers return `{ \"xeniaActions\": [ ... ] }` (or a bare\n * array) from the `webhook-response` node. Any body without a recognizable\n * `xeniaActions` array yields an empty list — a safe no-op.\n */\nexport function parseActions(body: JsonValue): XeniaAction[] {\n let list: JsonValue | undefined;\n if (Array.isArray(body)) {\n list = body;\n } else if (isObject(body) && Array.isArray(body.xeniaActions)) {\n list = body.xeniaActions;\n }\n if (!Array.isArray(list)) return [];\n\n const actions: XeniaAction[] = [];\n for (const entry of list) {\n const action = toAction(entry);\n if (action) actions.push(action);\n }\n return actions;\n}\n","import type { CircuitBreakerConfig, HttpMethod, JsonValue, RetryConfig } from \"./types\";\n\n/**\n * Default Xenia backend base URL, used whenever `baseUrl` is omitted from\n * config. Points at the hosted engine — override only for a self-hosted or\n * non-default environment.\n */\nexport const DEFAULT_BASE_URL = \"https://engine.xeniamartech.com/xenia\";\n\n/** Returns true when running in a browser environment (SSR-safe). */\nexport function isBrowser(): boolean {\n return typeof window !== \"undefined\" && typeof document !== \"undefined\";\n}\n\n/** Appends query parameters to a URL. Returns the URL unchanged when empty. */\nexport function buildUrl(url: string, queryParams?: Record<string, string>): string {\n if (!queryParams || Object.keys(queryParams).length === 0) return url;\n const params = new URLSearchParams(queryParams);\n const sep = url.includes(\"?\") ? \"&\" : \"?\";\n return `${url}${sep}${params.toString()}`;\n}\n\n/** Sleep helper used by the retry backoff. */\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/** Options for a single request. */\nexport interface RequestOptions {\n method?: HttpMethod;\n /** Path appended to `baseUrl` (should start with `/`). */\n path: string;\n headers?: Record<string, string>;\n query?: Record<string, string>;\n body?: JsonValue;\n /** Per-request timeout override in ms. */\n timeout?: number;\n /** Disable retry for this request (e.g. long-polling webhook). */\n noRetry?: boolean;\n /** Per-request retry override. */\n retry?: RetryConfig;\n /**\n * Keep the request alive past page unload (`fetch`'s `keepalive` flag).\n * Used for best-effort flushes on `pagehide`, where `sendBeacon` can't be\n * used instead because it doesn't support custom headers (tenant scope).\n */\n keepalive?: boolean;\n}\n\n/** Result of a request: the raw Response plus the parsed JSON (or null). */\nexport interface HttpResult {\n response: Response;\n data: JsonValue;\n}\n\n/** Error thrown for non-2xx responses (after retries are exhausted). */\nexport class HttpError extends Error {\n constructor(\n public readonly status: number,\n public readonly data: JsonValue,\n message?: string,\n ) {\n super(message ?? `Request failed with status ${status}`);\n this.name = \"HttpError\";\n }\n}\n\n/** Thrown without a network call while an endpoint's circuit is open (see {@link CircuitBreakerConfig}). */\nexport class CircuitOpenError extends Error {\n constructor(public readonly endpoint: string) {\n super(`Circuit open for ${endpoint}: failing fast until the cooldown passes`);\n this.name = \"CircuitOpenError\";\n }\n}\n\n/**\n * Per-endpoint breaker state, module-wide so it outlives a single client.\n * ponytail: after the cooldown every concurrent caller probes, not just one; fine for a fail-fast\n * guard, add a probe lock if a thundering herd on recovery ever matters.\n */\nconst breakers = new Map<string, { failures: number; openedAt: number }>();\n\nexport interface HttpClientOptions {\n /** Defaults to {@link DEFAULT_BASE_URL} when omitted. */\n baseUrl?: string;\n defaultHeaders?: Record<string, string>;\n timeout?: number;\n retry?: RetryConfig;\n circuitBreaker?: boolean | CircuitBreakerConfig;\n debug?: boolean;\n}\n\n/**\n * Minimal fetch wrapper shared by all runtimes.\n *\n * - Injects default headers (tenant scope, content-type).\n * - Applies an `AbortController` timeout.\n * - Retries transient failures (network error, `429`, `5xx`) with exponential\n * backoff, honoring a `Retry-After` header when present.\n * - Parses JSON, falling back to `null` on empty/invalid bodies.\n */\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly defaultHeaders: Record<string, string>;\n private readonly timeout: number;\n private readonly retry: Required<RetryConfig>;\n private readonly debug: boolean;\n private readonly breaker: Required<CircuitBreakerConfig> | null;\n\n constructor(opts: HttpClientOptions) {\n this.baseUrl = (opts.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.defaultHeaders = opts.defaultHeaders ?? {};\n this.timeout = opts.timeout ?? 8000;\n this.retry = {\n attempts: opts.retry?.attempts ?? 2,\n baseDelayMs: opts.retry?.baseDelayMs ?? 300,\n };\n this.debug = opts.debug ?? false;\n const cb = opts.circuitBreaker === true ? {} : opts.circuitBreaker || null;\n this.breaker = cb && { failureThreshold: cb.failureThreshold ?? 3, cooldownMs: cb.cooldownMs ?? 30_000 };\n }\n\n async request(opts: RequestOptions): Promise<HttpResult> {\n if (!this.breaker) return this.send(opts);\n // Keyed by full URL, query included: every webhook shares `/flow`, and one slow journey\n // (`?id=`) must not short-circuit the others.\n const key = buildUrl(this.baseUrl + opts.path, opts.query);\n const b = breakers.get(key) ?? { failures: 0, openedAt: 0 };\n if (b.openedAt) {\n if (Date.now() - b.openedAt < this.breaker.cooldownMs) throw new CircuitOpenError(key);\n // Half-open: let this call probe; one more failure re-opens.\n b.openedAt = 0;\n b.failures = this.breaker.failureThreshold - 1;\n }\n try {\n const result = await this.send(opts);\n breakers.delete(key);\n return result;\n } catch (err) {\n if (err instanceof HttpError && !this.isRetryableStatus(err.status)) {\n breakers.delete(key); // the backend answered: it's up\n throw err;\n }\n b.failures += 1;\n if (b.failures >= this.breaker.failureThreshold) {\n b.openedAt = Date.now();\n this.log(`circuit opened for ${opts.path} after ${b.failures} failures`);\n }\n breakers.set(key, b);\n throw err;\n }\n }\n\n private async send(opts: RequestOptions): Promise<HttpResult> {\n const url = buildUrl(this.baseUrl + opts.path, opts.query);\n const method = opts.method ?? \"GET\";\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...this.defaultHeaders,\n ...opts.headers,\n };\n const body = opts.body !== undefined ? JSON.stringify(opts.body) : undefined;\n const timeout = opts.timeout ?? this.timeout;\n const maxAttempts = opts.noRetry ? 1 : (opts.retry?.attempts ?? this.retry.attempts) + 1;\n const baseDelay = opts.retry?.baseDelayMs ?? this.retry.baseDelayMs;\n\n let lastError: unknown;\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n const response = await this.fetchWithTimeout(\n url,\n { method, headers, body, ...(opts.keepalive ? { keepalive: true } : {}) },\n timeout,\n );\n const data = await this.parseBody(response);\n\n if (response.ok) {\n return { response, data };\n }\n\n // Retry on 429/5xx if attempts remain; otherwise throw.\n if (this.isRetryableStatus(response.status) && attempt < maxAttempts - 1) {\n const wait = this.retryAfterMs(response, baseDelay, attempt);\n this.log(`retrying ${opts.path} after ${wait}ms (status ${response.status})`);\n await delay(wait);\n continue;\n }\n throw new HttpError(response.status, data);\n } catch (err) {\n lastError = err;\n // Non-retryable HttpError → rethrow immediately.\n if (err instanceof HttpError) throw err;\n // Network/timeout error → retry if attempts remain.\n if (attempt < maxAttempts - 1) {\n const wait = baseDelay * 2 ** attempt;\n this.log(`retrying ${opts.path} after ${wait}ms (network error)`);\n await delay(wait);\n continue;\n }\n }\n }\n throw lastError instanceof Error ? lastError : new Error(\"Request failed\");\n }\n\n private async fetchWithTimeout(\n url: string,\n init: RequestInit,\n timeout: number,\n ): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeout);\n try {\n return await fetch(url, { ...init, signal: controller.signal });\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n throw new Error(`Request timeout after ${timeout}ms`, { cause: err });\n }\n throw err;\n } finally {\n clearTimeout(timer);\n }\n }\n\n private async parseBody(response: Response): Promise<JsonValue> {\n const text = await response.text().catch(() => \"\");\n if (!text) return null;\n try {\n return JSON.parse(text) as JsonValue;\n } catch {\n return text;\n }\n }\n\n private isRetryableStatus(status: number): boolean {\n return status === 429 || (status >= 500 && status <= 599);\n }\n\n private retryAfterMs(response: Response, baseDelay: number, attempt: number): number {\n const header = response.headers.get(\"Retry-After\");\n if (header) {\n const seconds = Number(header);\n if (!Number.isNaN(seconds)) return seconds * 1000;\n }\n return baseDelay * 2 ** attempt;\n }\n\n private log(msg: string): void {\n if (this.debug) console.warn(`[xenia] ${msg}`);\n }\n}\n","import type { XeniaConfig } from \"./types\";\n\ninterface Cached {\n token: string;\n /** Epoch ms when the token should be considered stale. */\n expiresAt: number;\n}\n\n/** JWT `exp` (seconds) if decodable, else undefined. Best-effort, no verify. */\nfunction decodeExp(token: string): number | undefined {\n try {\n const payload = token.split(\".\")[1];\n if (!payload) return undefined;\n const json = JSON.parse(atob(payload.replace(/-/g, \"+\").replace(/_/g, \"/\")));\n return typeof json.exp === \"number\" ? json.exp * 1000 : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Resolves the Bearer token `XeniaApi` attaches to every request, caching a\n * short-lived token from `config.getToken` until ~30s before expiry. A static\n * `config.token` is returned as-is. Isomorphic (browser + Node ≥18, both have\n * global `atob`).\n */\nexport class TokenProvider {\n private readonly config: XeniaConfig;\n private cached: Cached | null = null;\n private inflight: Promise<string> | null = null;\n\n constructor(config: XeniaConfig) {\n this.config = config;\n }\n\n /** Whether a token source is configured at all — lets callers skip resolution entirely. */\n hasSource(): boolean {\n return Boolean(this.config.token || this.config.getToken);\n }\n\n readonly getToken = async (): Promise<string> => {\n if (this.config.token && !this.config.getToken) return this.config.token;\n\n const now = Date.now();\n if (this.cached && this.cached.expiresAt > now) return this.cached.token;\n if (this.inflight) return this.inflight;\n\n if (!this.config.getToken) {\n throw new Error(\"No token source: set config.token or config.getToken.\");\n }\n\n this.inflight = Promise.resolve(this.config.getToken())\n .then((token) => {\n const exp = decodeExp(token);\n // Refresh 30s before real expiry; default 5 min if the token is opaque.\n const expiresAt = exp ? exp - 30_000 : now + 5 * 60_000;\n this.cached = { token, expiresAt };\n return token;\n })\n .finally(() => {\n this.inflight = null;\n });\n\n return this.inflight;\n };\n}\n","import { parseActions } from \"./actions\";\nimport { HttpClient } from \"./http-client\";\nimport { TokenProvider } from \"./token-provider\";\nimport type {\n AnalyticsIngestResponse,\n ConsentState,\n IdentifyRequest,\n IdentifyResponse,\n JsonObject,\n JsonValue,\n ResolveBatchItem,\n ResolveBatchResult,\n ResolveEntriesResult,\n ResolveOptions,\n ResolveResult,\n WebhookResponse,\n WidgetPrize,\n WidgetSubmitResponse,\n WidgetType,\n XeniaConfig,\n XeniaEvent,\n} from \"./types\";\n\n/** Type guard for a plain JSON object (as opposed to an array/primitive/null). */\nfunction isJsonObject(v: JsonValue): v is JsonObject {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\n/** Narrow a raw `prize` field off a `/widget-submissions` response body. */\nfunction asWidgetPrize(v: JsonValue | undefined): WidgetPrize | undefined {\n return v !== undefined && isJsonObject(v) ? (v as WidgetPrize) : undefined;\n}\n\n/** Drop `undefined` values so the JSON body stays clean. */\nexport function compact(obj: Record<string, JsonValue | undefined>): JsonObject {\n const out: JsonObject = {};\n for (const [k, v] of Object.entries(obj)) {\n if (v !== undefined) out[k] = v;\n }\n return out;\n}\n\n/**\n * Low-level, isomorphic Xenia API client. Wraps the raw endpoints; identity,\n * UTM capture, and action rendering are layered on top by the client runtime.\n * All paths are relative to `baseUrl`, which defaults to the hosted engine\n * (`https://engine.xeniamartech.com/xenia`) when omitted from config.\n */\nexport class XeniaApi {\n private readonly http: HttpClient;\n private readonly tenantId: string;\n private readonly environmentKey: string;\n private readonly tokenProvider: TokenProvider;\n\n constructor(config: XeniaConfig) {\n this.tenantId = config.tenantId;\n this.environmentKey = config.environmentKey;\n this.tokenProvider = new TokenProvider(config);\n this.http = new HttpClient({\n baseUrl: config.baseUrl,\n defaultHeaders: config.headers,\n timeout: config.timeout,\n retry: config.retry,\n circuitBreaker: config.circuitBreaker,\n debug: config.debug,\n });\n }\n\n /** Tenant-scope headers required by header-scoped endpoints. */\n private tenantHeaders(): Record<string, string> {\n return {\n \"X-Tenant-Id\": this.tenantId,\n \"X-Environment\": this.environmentKey,\n };\n }\n\n /**\n * Tenant headers plus a resolved `Authorization: Bearer` header when\n * `config.token`/`config.getToken` is set — e.g. required by a webhook\n * trigger node configured with its own auth token. No-op (tenant headers\n * only) when no token source is configured, so this is safe to call\n * unconditionally on every request.\n */\n private async authHeaders(): Promise<Record<string, string>> {\n const headers = this.tenantHeaders();\n if (!this.tokenProvider.hasSource()) return headers;\n const token = await this.tokenProvider.getToken();\n if (token) headers.Authorization = `Bearer ${token}`;\n return headers;\n }\n\n /**\n * Webhook request/response — `GET|POST /flow?id={triggerId}`. Held open by the\n * backend until a `webhook-response` node resolves. Returns the normalized\n * response, including any `xeniaActions` parsed from the body.\n *\n * Not retried by default: the backend long-polls this call, so a retry would\n * duplicate the journey run.\n */\n async webhook(\n triggerId: string,\n data?: JsonValue,\n method: \"GET\" | \"POST\" = \"POST\",\n ): Promise<WebhookResponse> {\n const { response, data: rawBody } = await this.http.request({\n method,\n path: \"/flow\",\n query: { id: triggerId },\n headers: await this.authHeaders(),\n body: method === \"POST\" ? (data ?? {}) : undefined,\n noRetry: true,\n });\n return {\n status: response.status,\n body: rawBody,\n actions: parseActions(rawBody),\n receivedAt: Date.now(),\n };\n }\n\n /**\n * Widget form submission — `POST /widget-submissions?ref={bindingRef}`. Used whenever the\n * action's `formSubmit.requiresResolve` is true (spin-wheel, which must have a\n * server-resolved outcome before anything renders) or `mode === \"endpoint\"` — the common\n * plain-popup case (`mode === \"journey\" && !requiresResolve`) bypasses this entirely and calls\n * {@link webhook} against `flowRef` instead (see `XeniaClient.submitWidgetForm`'s endpoint\n * selection).\n *\n * Not retried (`noRetry: true`), styled like {@link webhook} — a retried POST must never\n * double-fire a journey or double-resolve a prize server-side.\n */\n async submitWidget(ref: string, body?: JsonValue): Promise<WidgetSubmitResponse> {\n const { response, data: rawBody } = await this.http.request({\n method: \"POST\",\n path: \"/widget-submissions\",\n query: { ref },\n headers: await this.authHeaders(),\n body: body ?? {},\n noRetry: true,\n });\n const obj = isJsonObject(rawBody) ? rawBody : {};\n return {\n status: response.status,\n body: rawBody,\n actions: parseActions(rawBody),\n prize: asWidgetPrize(obj.prize),\n alreadyPlayed: obj.alreadyPlayed === true,\n dispatched: obj.dispatched === true,\n dispatchError: typeof obj.dispatchError === \"string\" ? obj.dispatchError : undefined,\n widgetType: typeof obj.widgetType === \"string\" ? (obj.widgetType as WidgetType) : undefined,\n receivedAt: Date.now(),\n };\n }\n\n /**\n * Unified event batch (max 100/request per the backend) — `POST /api/events/v1`.\n * Records analytics for every event and matches/advances a journey for any\n * event with `trigger: true`. Replaces the old `sendEvent()` (journey trigger)\n * and `sendAnalytics()` (CDP) calls.\n */\n async sendEvents(\n events: XeniaEvent[],\n opts?: { keepalive?: boolean },\n ): Promise<AnalyticsIngestResponse> {\n const { data } = await this.http.request({\n method: \"POST\",\n path: \"/api/events/v1\",\n headers: await this.authHeaders(),\n body: { events } as unknown as JsonObject,\n keepalive: opts?.keepalive,\n });\n return data as unknown as AnalyticsIngestResponse;\n }\n\n /** Bind visitor→user — `POST /api/events/v1/identify`. */\n async identify(body: IdentifyRequest): Promise<IdentifyResponse> {\n const { data } = await this.http.request({\n method: \"POST\",\n path: \"/api/events/v1/identify\",\n headers: await this.authHeaders(),\n body: body as unknown as JsonObject,\n });\n return data as unknown as IdentifyResponse;\n }\n\n /**\n * Update consent — `POST /api/events/v1/consent`.\n *\n * The three scope flags are required (non-null) by the backend, so an omitted\n * one is sent as an explicit `false` rather than left out: a partial body like\n * `consent({ analytics: true })` — the shape most callers actually write — is\n * otherwise rejected with a 400 and the consent record is never stored.\n */\n async consent(xeniaVisitorId: string, consent: ConsentState): Promise<JsonValue> {\n const { data } = await this.http.request({\n method: \"POST\",\n path: \"/api/events/v1/consent\",\n headers: await this.authHeaders(),\n body: compact({\n xeniaVisitorId,\n analytics: consent.analytics === true,\n marketing: consent.marketing === true,\n personalization: consent.personalization === true,\n consentSource: consent.consentSource,\n consentVersion: consent.consentVersion,\n }),\n });\n return data;\n }\n\n /**\n * Resolve in-entry content personalization for one content key —\n * `POST /api/personalization/resolve?merge=<bool>`. Requires the SDK Bearer\n * token (same credential as events; resolve is auth-required). `merge=true`\n * returns server-spliced `content`; otherwise splice `swaps` client-side.\n */\n async resolve(contentKey: string, opts: ResolveOptions = {}): Promise<ResolveResult> {\n const { data } = await this.http.request({\n method: \"POST\",\n path: \"/api/personalization/resolve\",\n query: opts.merge !== undefined ? { merge: String(opts.merge) } : undefined,\n headers: await this.authHeaders(),\n body: compact({\n contentKey,\n data: opts.data as JsonValue,\n locale: opts.locale,\n }),\n });\n return data as unknown as ResolveResult;\n }\n\n /**\n * Resolve several content keys in one round-trip (≤50) —\n * `POST /api/personalization/resolve-batch?merge=<bool>`. Same auth/merge\n * semantics as {@link resolve}.\n */\n async resolveBatch(\n items: ResolveBatchItem[],\n opts: ResolveOptions = {},\n ): Promise<ResolveBatchResult[]> {\n const { data } = await this.http.request({\n method: \"POST\",\n path: \"/api/personalization/resolve-batch\",\n query: opts.merge !== undefined ? { merge: String(opts.merge) } : undefined,\n headers: await this.authHeaders(),\n body: compact({\n items: items as unknown as JsonValue,\n data: opts.data as JsonValue,\n locale: opts.locale,\n }),\n });\n return data as unknown as ResolveBatchResult[];\n }\n\n /**\n * Resolve personalized CMS entries by id for one visitor (≤200) —\n * `POST /api/personalization/resolve-entries`. The page resolver\n * ({@link personalizeContent}) calls this once per round with the runtime\n * targets it found; callers rarely need it directly.\n */\n async resolveEntries(entryIds: string[], opts: ResolveOptions = {}): Promise<ResolveEntriesResult> {\n const { data } = await this.http.request({\n method: \"POST\",\n path: \"/api/personalization/resolve-entries\",\n headers: await this.authHeaders(),\n body: compact({\n entryIds: entryIds as unknown as JsonValue,\n data: opts.data as JsonValue,\n locale: opts.locale,\n }),\n });\n return data as unknown as ResolveEntriesResult;\n }\n}\n","/**\n * Cookie names shared by the browser and server halves of the SDK.\n *\n * The visitor cookie is the one channel where two runtimes must agree on a literal string: the\n * browser writes it, a same-origin server reads it back, and that match is what lets a server-side\n * conversion attribute to a browser-entered journey. `config.prefix` namespaces it — so two Xenia\n * apps on one domain keep separate visitors — which means **both halves must derive the name the\n * same way**. Deriving it on one side and hardcoding it on the other silently breaks the link for\n * anyone using a custom prefix: the server just finds no cookie and falls back to no visitor.\n *\n * Always build the name with these helpers rather than interpolating it by hand.\n */\n\nimport type { ConsentState } from \"./types\";\n\n/** Default storage/cookie prefix, matching `XeniaConfig.prefix`. */\nexport const DEFAULT_PREFIX = \"xenia\";\n\n/** Name of the first-party cookie carrying the SDK-owned visitor id, for a given prefix. */\nexport function visitorCookieName(prefix: string = DEFAULT_PREFIX): string {\n return `${prefix || DEFAULT_PREFIX}_vid`;\n}\n\n/** Name of the first-party cookie carrying consent scopes, for a given prefix. */\nexport function consentCookieName(prefix: string = DEFAULT_PREFIX): string {\n return `${prefix || DEFAULT_PREFIX}_consent`;\n}\n\n/**\n * The visitor cookie name for the DEFAULT prefix (`\"xenia_vid\"`).\n *\n * Correct for the common case, and kept so existing code (e.g. reading the cookie straight out of a\n * framework's cookie jar) keeps working. If you set `config.prefix`, use {@link visitorCookieName}\n * instead — this constant will not match what the browser wrote.\n */\nexport const VISITOR_COOKIE = visitorCookieName();\n\n/**\n * The consent cookie name for the DEFAULT prefix (`\"xenia_consent\"`). Same custom-prefix caveat as\n * {@link VISITOR_COOKIE}.\n */\nexport const CONSENT_COOKIE = consentCookieName();\n\n/**\n * A `document.cookie` string carrying consent, in the JSON form the server SDK's `getConsent()`\n * reads back. The browser client's `consent()` writes it; a page with its own consent banner and no\n * browser client can write it directly, so server-side calls see the visitor's choice.\n */\nexport function consentCookie(state: ConsentState, prefix?: string, maxAgeDays = 365): string {\n return `${consentCookieName(prefix)}=${encodeURIComponent(JSON.stringify(state))}; path=/; max-age=${Math.floor(maxAgeDays * 86400)}; SameSite=Lax`;\n}\n","import type { EventContext, EventIdentity, EventPayload, JsonValue } from \"./types\";\n\n/** Reserved keys that map to first-class fields (not passthrough data). */\nconst RESERVED = new Set([\n \"eventId\",\n \"eventType\",\n \"journeyId\",\n \"deviceId\",\n \"visitorId\",\n \"customerId\",\n \"email\",\n \"utmSource\",\n \"utmMedium\",\n \"utmCampaign\",\n \"utmContent\",\n \"utmId\",\n \"url\",\n \"referrer\",\n \"path\",\n \"query\",\n]);\n\nexport interface BuildEventInput {\n eventId: string;\n eventType?: string;\n journeyId?: string;\n identity?: EventIdentity;\n context?: EventContext;\n /** Arbitrary extra properties merged as passthrough data. */\n props?: Record<string, JsonValue | undefined>;\n}\n\n/** Drop `undefined` values so the JSON body stays clean. */\nfunction compact(obj: Record<string, JsonValue | undefined>): Record<string, JsonValue> {\n const out: Record<string, JsonValue> = {};\n for (const [k, v] of Object.entries(obj)) {\n if (v !== undefined) out[k] = v;\n }\n return out;\n}\n\n/**\n * Build the request body for the webhook `/flow` call (`XeniaApi.webhook`).\n *\n * Merge order (later wins): passthrough props < context < identity < core.\n * Field names match the backend `EventTriggerRequest` DTO exactly.\n *\n * @internal Used only by the webhook request/response path — the unified event\n * surface (`track()` → `POST /api/events/v1`) builds {@link XeniaEvent} instead.\n */\nexport function buildEventPayload(input: BuildEventInput): EventPayload {\n const passthrough: Record<string, JsonValue> = {};\n const reserved: Record<string, JsonValue> = {};\n if (input.props) {\n for (const [k, v] of Object.entries(input.props)) {\n if (v === undefined) continue;\n // A prop whose key matches a reserved field (e.g. `email`, `customerId`,\n // `utmSource`) is promoted to that first-class field; everything else is\n // custom passthrough data. Previously reserved-named props were dropped\n // outright — so `track(\"sign_up\", { email })` never sent `email` at all.\n if (RESERVED.has(k)) reserved[k] = v;\n else passthrough[k] = v;\n }\n }\n\n const payload = {\n ...passthrough,\n // Reserved-named props fill first-class fields (e.g. `email`, `customerId`)\n // the SDK didn't auto-collect. Auto-collected context/identity still win for\n // what they reliably know (real page url, visitor/device id), so a stray prop\n // can't override the true page context — see merge order below.\n ...reserved,\n ...compact((input.context ?? {}) as Record<string, JsonValue | undefined>),\n ...compact((input.identity ?? {}) as Record<string, JsonValue | undefined>),\n eventId: input.eventId,\n ...(input.eventType ? { eventType: input.eventType } : {}),\n ...(input.journeyId ? { journeyId: input.journeyId } : {}),\n };\n\n return payload as EventPayload;\n}\n","/** Crockford base32 alphabet (no I/L/O/U, avoids visual ambiguity) — used by ULID. */\nconst ENCODING = \"0123456789ABCDEFGHJKMNPQRSTVWXYZ\";\n\nfunction randomBytes(length: number): Uint8Array {\n const bytes = new Uint8Array(length);\n if (typeof crypto !== \"undefined\" && crypto.getRandomValues) {\n crypto.getRandomValues(bytes);\n } else {\n for (let i = 0; i < length; i++) bytes[i] = Math.floor(Math.random() * 256);\n }\n return bytes;\n}\n\n/**\n * Generate a ULID (Universally Unique Lexicographically Sortable Identifier):\n * a 48-bit timestamp (10 Crockford-base32 chars) + 80 bits of randomness (16\n * chars), 26 chars total — matches the backend's `eventId` field (`≤26`\n * chars). No dependency; implemented inline to keep the SDK lean.\n */\nexport function generateUlid(time: number = Date.now()): string {\n let timePart = \"\";\n let t = time;\n for (let i = 9; i >= 0; i--) {\n timePart = ENCODING[t % 32] + timePart;\n t = Math.floor(t / 32);\n }\n\n const random = randomBytes(16);\n let randomPart = \"\";\n for (let i = 0; i < 16; i++) {\n randomPart += ENCODING[random[i] % 32];\n }\n\n return timePart + randomPart;\n}\n\n/** Backend cap on `eventId` (`@Size(max = 26)`), which a ULID exactly fills. */\nexport const MAX_EVENT_ID_LENGTH = 26;\n\n/**\n * Coerce a caller-supplied dedup key into something the backend will accept.\n *\n * `eventId` is capped at 26 characters server-side, and an over-length value\n * rejects the ENTIRE batch it rides in — not just its own event. That is easy to\n * hit: `\"ord-\" + <uuid>` is 40. Rather than drop the caller's idempotency key or\n * let the batch 400, fold anything longer into a deterministic 26-char digest.\n * Deterministic is the point — the same order id always yields the same event id,\n * so re-firing it still de-dupes to one conversion, which is what the key is for.\n *\n * Truncation is deliberately not used: `\"ord-<uuid>\"` values share a long common\n * prefix, so cutting to 26 chars can map two different orders onto one id.\n */\nexport function toEventId(raw: string): string {\n if (raw.length <= MAX_EVENT_ID_LENGTH) return raw;\n\n // Two independently-seeded FNV-1a passes → 128 bits, encoded Crockford base32.\n let out = \"\";\n for (const seed of [0x811c9dc5, 0x01000193]) {\n let hash = seed >>> 0;\n for (let i = 0; i < raw.length; i++) {\n hash ^= raw.charCodeAt(i);\n hash = Math.imul(hash, 0x01000193) >>> 0;\n out += ENCODING[hash % 32];\n }\n }\n // Fold the accumulated stream down to exactly the cap, order-dependently.\n let digest = \"\";\n for (let i = 0; i < MAX_EVENT_ID_LENGTH; i++) {\n let acc = i + 1;\n for (let j = i; j < out.length; j += MAX_EVENT_ID_LENGTH) {\n acc = (acc * 31 + ENCODING.indexOf(out[j])) >>> 0;\n }\n digest += ENCODING[acc % 32];\n }\n return digest;\n}\n","/**\n * CMS page personalization — walk a fetched CMS page breadth-first, swap the\n * entries Xenia marked as personalized, and do it in as few round trips as\n * the page's nesting allows.\n *\n * Rules (see the \"Rounds\" section of the feature plan):\n * - **Static** targets carry their replacement in the payload (`xeniaVariants`)\n * and are swapped inline — no network at all.\n * - **Runtime** targets are a barrier: their id is collected, their subtree is\n * NOT walked (it may be replaced). One `resolve-entries` call decides every\n * target found in a round, one parallel CMS fetch loads every replacement,\n * and the next round walks whatever now sits at each position.\n * - Never throws: on error or when `timeoutMs` runs out, whatever is not yet\n * decided keeps its base content.\n *\n * CMS specifics live behind {@link CmsAdapter}; built-in adapters ship as\n * `@xenia-martech/sdk-js/cms/contentful` (and later `/cms/contentstack`). Any\n * other CMS works by implementing the interface.\n */\n\nimport type { EntryDecision, EntryQuery, EntrySwapOp, ResolveOptions } from \"./types\";\n\n/** Any value inside a CMS payload — the walker is shape-agnostic; adapters give it meaning. */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Node = any;\n\n/** The parsed `xenia` marker field of a personalized entry. */\nexport interface XeniaMarker {\n kind: \"static\" | \"runtime\";\n op?: EntrySwapOp;\n /** Array field replaced by `op: \"items\"`. */\n field?: string;\n limit?: number;\n}\n\n/** What the page resolver needs to know about a CMS's entries. `N` is the entry shape. */\nexport interface CmsAdapter<N extends object = Node> {\n /** The entry id when `value` is a CMS entry (not a link stub, asset or plain object). */\n entryId(value: unknown): string | undefined;\n /** The entry's Xenia marker, or null when it is not personalized. */\n marker(entry: N): XeniaMarker | null;\n /** Static replacements pinned on the entry (its resolved `xeniaVariants`). */\n staticVariants(entry: N): N[];\n getField(entry: N, field: string): unknown;\n setField(entry: N, field: string, value: unknown): void;\n /** Legacy `items` without a field: copy the replacement's array fields onto the entry. */\n mergeItems?(entry: N, replacement: N): void;\n /**\n * Remove the marker from an entry that has been dealt with (kept base, or had its items replaced),\n * so personalizing the output again — e.g. the browser continuing a server render — never decides\n * it twice. Optional; without it a re-run re-asks Xenia about those entries.\n */\n clearMarker?(entry: N): void;\n /** Normalize a fetched payload before walking (e.g. resolve links). Defaults to identity. */\n prepare?(payload: unknown): unknown;\n /** Load entries by id in ONE call; order does not matter. */\n fetchEntries(ids: string[], locale?: string): Promise<N[]>;\n /** Run a content-type query in ONE call, in the query's order. */\n queryEntries(query: EntryQuery, locale?: string): Promise<N[]>;\n /**\n * Load one page with its whole tree (links resolved), or null when there is none. Optional; it\n * is what lets `personalizePage(ref)` do the fetch, so apps never fetch the page themselves.\n */\n fetchPage?(ref: PageRef, locale?: string): Promise<N | null>;\n}\n\n/** Identifies a page in the CMS: its entry id, or a content type plus exact field values (a slug). */\nexport type PageRef = string | { contentType: string; fields: Record<string, string | number | boolean> };\n\n/** Resolves a round's runtime targets — `XeniaApi.resolveEntries` bound to the visitor. */\nexport type EntryResolver = (entryIds: string[]) => Promise<EntryDecision[]>;\n\n/** Reported for every swap actually applied (for impressions / analytics). */\nexport interface AppliedSwap {\n target: string;\n kind: \"static\" | \"runtime\";\n op: EntrySwapOp;\n /** Ids of the entries now at the target's position (or in its field). */\n entryIds: string[];\n contentKey?: string;\n bucket?: string;\n round: number;\n}\n\nexport interface PersonalizeContentOptions {\n cms: CmsAdapter;\n /** Decides runtime targets. Omit to apply static swaps only (zero network). */\n resolve?: EntryResolver;\n locale?: string;\n /** Max network rounds (nesting depth of runtime targets). Default 3. */\n maxRounds?: number;\n /** Total budget for all rounds, in ms. Undecided targets keep their base. Default 300. */\n timeoutMs?: number;\n /** Mutate the payload in place instead of personalizing a copy. Default false. */\n inPlace?: boolean;\n onApplied?(swap: AppliedSwap): void;\n /**\n * Called when a round starts waiting on the network (`pending` = targets being decided) and when\n * it has been applied (`pending` empty). `content` is the live, partially personalized tree —\n * lets a UI render level by level instead of waiting for every round.\n */\n onProgress?(progress: { content: unknown; round: number; pending: string[] }): void;\n}\n\n/** `personalizeContent` options as taken by `XeniaClient` / `XeniaServer`, which supply `resolve`. */\nexport type PagePersonalizeOptions = Omit<PersonalizeContentOptions, \"resolve\"> &\n Pick<ResolveOptions, \"data\" | \"identity\" | \"context\">;\n\nexport interface PersonalizeContentResult<T> {\n content: T;\n applied: AppliedSwap[];\n /** False when the budget ran out, a call failed, or `maxRounds` was hit with targets left. */\n complete: boolean;\n error?: unknown;\n}\n\nconst DEFAULT_TIMEOUT_MS = 300;\nconst DEFAULT_MAX_ROUNDS = 3;\n\n/** One place a value sits in the tree: `parent[key]`. Arrays are re-indexed by identity on write. */\ninterface Slot {\n parent: Node;\n key: string | number;\n value: Node;\n}\n\n/** What Xenia decided for an entry id, with the fetched replacements (copied per use). */\ninterface Decided {\n decision?: EntryDecision;\n items: Node[];\n}\n\nconst copyOf = (v: Node): Node =>\n v && typeof v === \"object\" && typeof structuredClone === \"function\" ? structuredClone(v) : v;\n\n/** A runtime target found in a round, at every place it appears (an entry may be shared). */\ninterface Pending {\n id: string;\n marker: XeniaMarker;\n entry: Node;\n slots: Slot[];\n}\n\nexport async function personalizeContent<T>(\n payload: T,\n options: PersonalizeContentOptions,\n): Promise<PersonalizeContentResult<T>> {\n const { cms } = options;\n const maxRounds = options.maxRounds ?? DEFAULT_MAX_ROUNDS;\n const deadline = Date.now() + (options.timeoutMs ?? DEFAULT_TIMEOUT_MS);\n const applied: AppliedSwap[] = [];\n const report = (swap: AppliedSwap) => {\n applied.push(swap);\n try {\n options.onApplied?.(swap);\n } catch {\n /* a broken analytics callback must never break rendering */\n }\n };\n\n let content: Node = payload;\n try {\n if (!options.inPlace && typeof structuredClone === \"function\") content = structuredClone(content);\n content = cms.prepare ? cms.prepare(content) : content;\n } catch (error) {\n return { content: payload, applied, complete: false, error };\n }\n\n const box = { root: content };\n // Entries whose own marker is already dealt with this call (kept base / swapped in) — walked as\n // plain content from now on so a target is never decided twice.\n const settled = new WeakSet<object>();\n // Decisions made in this call, by entry id. An entry that turns up again in a later round (a\n // shared entry inside a replacement) gets the same decision — consistent, and no second request.\n const decided = new Map<string, Decided>();\n let frontier: Slot[] = [{ parent: box, key: \"root\", value: box.root }];\n\n /** Apply a decision at a target's slots; returns what to walk next. */\n const settle = (target: Pending, d: Decided, round: number): Slot[] => {\n settled.add(target.entry);\n cms.clearMarker?.(target.entry);\n // A copy per use: fetched entries share objects (one CDA include graph), and a shared object\n // would be \"already settled\" wherever else it appears, hiding entries that are targets there.\n const items = d.items.map(copyOf);\n if (!d.decision || items.length === 0) {\n // Kept base: its subtree was never walked (barrier), so it is next round's frontier.\n return deferredSlots(target, cms);\n }\n for (const item of items) if (item && typeof item === \"object\") settled.add(item);\n const op = d.decision.op ?? target.marker.op ?? \"replace\";\n const next = apply(target, op, d.decision.field ?? target.marker.field, items, cms);\n report({\n target: target.id,\n kind: \"runtime\",\n op,\n entryIds: items.map((e) => cms.entryId(e)).filter((id): id is string => !!id),\n contentKey: d.decision.contentKey,\n bucket: d.decision.bucket,\n round,\n });\n return next;\n };\n\n for (let round = 0; ; round++) {\n const pending = walk(frontier, cms, settled, round, report, (t) => {\n const d = decided.get(t.id);\n return d ? settle(t, d, round) : undefined;\n });\n if (pending.size === 0) return { content: box.root, applied, complete: true };\n if (!options.resolve || round >= maxRounds) {\n return { content: box.root, applied, complete: !options.resolve };\n }\n progress(options, { content: box.root, round, pending: [...pending.keys()] });\n\n let decisions: EntryDecision[];\n let entriesById: Map<string, Node>;\n let queried: Map<EntryDecision, Node[]>;\n try {\n decisions = await withDeadline(options.resolve([...pending.keys()]), deadline);\n ({ entriesById, queried } = await withDeadline(loadReplacements(decisions, cms, options.locale), deadline));\n } catch (error) {\n return { content: box.root, applied, complete: false, error: error === TIMEOUT ? undefined : error };\n }\n\n const byTarget = new Map(decisions.map((d) => [d.target, d]));\n frontier = [];\n for (const target of pending.values()) {\n const decision = byTarget.get(target.id);\n const items = decision\n ? decision.ids\n ? decision.ids.map((id) => entriesById.get(id)).filter((e) => e !== undefined)\n : queried.get(decision) ?? []\n : [];\n const d: Decided = { decision, items };\n decided.set(target.id, d);\n frontier.push(...settle(target, d, round));\n }\n progress(options, { content: box.root, round, pending: [] });\n }\n}\n\nfunction progress(options: PersonalizeContentOptions, p: { content: unknown; round: number; pending: string[] }) {\n try {\n options.onProgress?.(p);\n } catch {\n /* UI callbacks must never break personalization */\n }\n}\n\n/**\n * Breadth-first walk of `frontier`: applies static swaps inline, collects runtime targets (without\n * descending into them) and returns them keyed by entry id.\n */\nfunction walk(\n frontier: Slot[],\n cms: CmsAdapter,\n settled: WeakSet<object>,\n round: number,\n report: (swap: AppliedSwap) => void,\n /** Applies an earlier decision for this entry id inline; undefined when it hasn't been decided. */\n reuse: (target: Pending) => Slot[] | undefined,\n): Map<string, Pending> {\n const pending = new Map<string, Pending>();\n const seen = new WeakSet<object>();\n // Fields held back by a runtime `items` target, wherever the CMS nests them (Contentful: `fields.x`).\n const deferred = new WeakSet<object>();\n const queue: Slot[] = [...frontier];\n\n while (queue.length > 0) {\n const slot = queue.shift()!;\n const value = slot.value;\n if (!value || typeof value !== \"object\" || deferred.has(value)) continue;\n\n const id = settled.has(value) ? undefined : cms.entryId(value);\n const marker = id ? cms.marker(value) : null;\n\n if (id && marker?.kind === \"runtime\") {\n const again = reuse({ id, marker, entry: value, slots: [slot] });\n if (again) {\n queue.push(...again);\n continue;\n }\n const existing = pending.get(id);\n if (existing) {\n existing.slots.push(slot);\n } else {\n pending.set(id, { id, marker, entry: value, slots: [slot] });\n // `items` only defers the replaced field; the entry's other fields are walked now.\n if (marker.op === \"items\" && marker.field) {\n const held = cms.getField(value, marker.field);\n if (held && typeof held === \"object\") deferred.add(held);\n queue.push(...children(value));\n }\n }\n continue;\n }\n\n if (id && marker?.kind === \"static\") {\n const variants = cms.staticVariants(value).filter((v) => v && typeof v === \"object\");\n settled.add(value);\n cms.clearMarker?.(value);\n if (variants.length > 0) {\n for (const v of variants) settled.add(v);\n const op = marker.op ?? \"replace\";\n const target: Pending = { id, marker, entry: value, slots: [slot] };\n queue.push(...apply(target, op, marker.field, variants, cms));\n report({\n target: id,\n kind: \"static\",\n op,\n entryIds: variants.map((v) => cms.entryId(v)).filter((x): x is string => !!x),\n round,\n });\n continue;\n }\n // A static marker with nothing pinned (write-back pending) is just base content.\n }\n\n if (seen.has(value)) continue;\n seen.add(value);\n queue.push(...children(value));\n }\n return pending;\n}\n\n/** Splice `items` in for `target` at all its slots; returns the new content to walk next. */\nfunction apply(target: Pending, op: EntrySwapOp, field: string | undefined, items: Node[], cms: CmsAdapter): Slot[] {\n if (op === \"items\") {\n if (field) {\n cms.setField(target.entry, field, items);\n return [{ parent: target.entry, key: field, value: cms.getField(target.entry, field) }];\n }\n if (cms.mergeItems) {\n cms.mergeItems(target.entry, items[0]);\n return target.slots.map((s) => ({ ...s, value: target.entry }));\n }\n op = \"replace\"; // no merge support → closest meaning\n }\n\n const next: Slot[] = [];\n for (const slot of target.slots) {\n const placed = op === \"expand\" && Array.isArray(slot.parent) ? items : [items[0]];\n if (Array.isArray(slot.parent)) {\n const index = slot.parent.indexOf(target.entry);\n if (index < 0) continue;\n slot.parent.splice(index, 1, ...placed);\n } else {\n slot.parent[slot.key] = placed[0];\n }\n for (const value of placed) next.push({ parent: slot.parent, key: slot.key, value });\n }\n return next;\n}\n\n/** What still needs walking under a target that kept its base content. */\nfunction deferredSlots(target: Pending, cms: CmsAdapter): Slot[] {\n if (target.marker.op === \"items\" && target.marker.field) {\n return [{ parent: target.entry, key: target.marker.field, value: cms.getField(target.entry, target.marker.field) }];\n }\n return target.slots.map((s) => ({ ...s, value: target.entry }));\n}\n\nfunction children(value: Node): Slot[] {\n if (Array.isArray(value)) return value.map((v, i) => ({ parent: value, key: i, value: v }));\n return Object.keys(value).map((k) => ({ parent: value, key: k, value: value[k] }));\n}\n\n/** One `fetchEntries` call for every explicit id, plus one query per content-type decision — all in parallel. */\nasync function loadReplacements(decisions: EntryDecision[], cms: CmsAdapter, locale?: string) {\n const ids = [...new Set(decisions.flatMap((d) => d.ids ?? []))];\n const queries = decisions.filter((d) => !d.ids && d.query);\n const [fetched, ...results] = await Promise.all([\n ids.length > 0 ? cms.fetchEntries(ids, locale) : Promise.resolve([]),\n ...queries.map((d) => cms.queryEntries(d.query!, locale).catch(() => [] as Node[])),\n ]);\n const entriesById = new Map<string, Node>();\n for (const entry of fetched) {\n const id = cms.entryId(entry);\n if (id) entriesById.set(id, entry);\n }\n const queried = new Map<EntryDecision, Node[]>();\n queries.forEach((d, i) => queried.set(d, results[i]!));\n return { entriesById, queried };\n}\n\nconst TIMEOUT = Symbol(\"timeout\");\n\nfunction withDeadline<T>(promise: Promise<T>, deadline: number): Promise<T> {\n const remaining = deadline - Date.now();\n if (remaining <= 0) return Promise.reject(TIMEOUT);\n let timer: ReturnType<typeof setTimeout>;\n return Promise.race([\n promise,\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(TIMEOUT), remaining);\n }),\n ]).finally(() => clearTimeout(timer));\n}\n\n/**\n * The entries Xenia still has to decide on this page — runtime targets reachable without crossing\n * another undecided one. Synchronous and network-free (it reads the `xenia` markers), so a page can\n * render a skeleton in exactly those places from the first frame instead of flashing base content.\n * Nested targets inside a pending one are found once it is decided.\n */\nexport function pendingTargets(payload: unknown, cms: CmsAdapter): string[] {\n try {\n let content: Node = typeof structuredClone === \"function\" ? structuredClone(payload) : payload;\n content = cms.prepare ? cms.prepare(content) : content;\n const root = { parent: { root: content }, key: \"root\", value: content };\n // On a copy: the walk applies static swaps inline, which must not touch the caller's page.\n return [...walk([root], cms, new WeakSet(), 0, () => {}, () => undefined).keys()];\n } catch {\n return [];\n }\n}\n\n/**\n * Fetch a page through `options.cms` and personalize it — {@link personalizeContent} without the\n * fetch in app code. Never throws: a failed fetch comes back as `content: null` with `error`; a page\n * that does not exist as `content: null`, `complete: true`. The page fetch is not counted against\n * `timeoutMs` — that budget is for personalization only.\n */\nexport async function personalizePage<T>(\n ref: PageRef,\n options: PersonalizeContentOptions,\n): Promise<PersonalizeContentResult<T | null>> {\n let page: unknown;\n try {\n if (!options.cms.fetchPage) throw new Error(\"This CMS adapter cannot fetch pages; use personalizeContent(page)\");\n page = await options.cms.fetchPage(ref, options.locale);\n } catch (error) {\n return { content: null, applied: [], complete: false, error };\n }\n if (page == null) return { content: null, applied: [], complete: true };\n return personalizeContent(page as T, options);\n}\n","import type { WebhookResponse } from \"./types\";\n\n/**\n * Persists webhook responses the SDK receives, keyed by an arbitrary string\n * (typically the eventId, triggerId, or journeyId). Lets the app read back the\n * last server response for a given interaction without re-firing it.\n */\nexport interface ResponseStore {\n set(key: string, value: WebhookResponse): void;\n get(key: string): WebhookResponse | undefined;\n keys(): string[];\n clear(): void;\n}\n\n/** In-memory store. Default; lost on reload. */\nexport class MemoryResponseStore implements ResponseStore {\n private readonly map = new Map<string, WebhookResponse>();\n\n set(key: string, value: WebhookResponse): void {\n this.map.set(key, value);\n }\n get(key: string): WebhookResponse | undefined {\n return this.map.get(key);\n }\n keys(): string[] {\n return [...this.map.keys()];\n }\n clear(): void {\n this.map.clear();\n }\n}\n\n/**\n * localStorage-backed store — survives reloads. Falls back to memory semantics\n * (silent no-op reads/writes) when localStorage is unavailable or throws.\n */\nexport class LocalStorageResponseStore implements ResponseStore {\n private readonly nsKey: string;\n\n constructor(prefix = \"xenia\") {\n this.nsKey = `${prefix}_responses`;\n }\n\n private read(): Record<string, WebhookResponse> {\n try {\n const raw = localStorage.getItem(this.nsKey);\n return raw ? (JSON.parse(raw) as Record<string, WebhookResponse>) : {};\n } catch {\n return {};\n }\n }\n\n private write(data: Record<string, WebhookResponse>): void {\n try {\n localStorage.setItem(this.nsKey, JSON.stringify(data));\n } catch {\n /* storage full / unavailable — ignore */\n }\n }\n\n set(key: string, value: WebhookResponse): void {\n const data = this.read();\n data[key] = value;\n this.write(data);\n }\n get(key: string): WebhookResponse | undefined {\n return this.read()[key];\n }\n keys(): string[] {\n return Object.keys(this.read());\n }\n clear(): void {\n try {\n localStorage.removeItem(this.nsKey);\n } catch {\n /* ignore */\n }\n }\n}\n","import { HttpError } from \"../core/http-client\";\nimport type { XeniaEvent } from \"../core/types\";\n\nexport interface AnalyticsQueueOptions {\n /** Injected sender — normally `XeniaApi.sendEvents` bound to an instance. */\n send: (events: XeniaEvent[], opts?: { keepalive?: boolean }) => Promise<unknown>;\n /** Flush once this many events are queued. Default 20. */\n batchSize?: number;\n /** Flush at least this often, in ms. Default 3000. */\n flushIntervalMs?: number;\n /** Hard cap on in-memory events — oldest are dropped past this. Default 200. */\n maxQueueSize?: number;\n debug?: boolean;\n}\n\n/**\n * In-memory batching queue for `POST /api/events/v1`. Analytics\n * ingestion is best-effort: events are never persisted (no offline/localStorage\n * buffer). A batch that fails with a transient error (after `HttpClient`'s own\n * retry/backoff is exhausted) is requeued for the next flush tick, bounded by\n * `maxQueueSize` — under a sustained outage, oldest events are dropped rather\n * than growing memory unboundedly or retrying forever. A batch rejected with a\n * permanent 4xx (e.g. failed identity validation) is dropped immediately\n * instead — the payload will never become valid by resending it unchanged.\n */\nexport class AnalyticsQueue {\n private queue: XeniaEvent[] = [];\n private readonly send: AnalyticsQueueOptions[\"send\"];\n private readonly batchSize: number;\n private readonly flushIntervalMs: number;\n private readonly maxQueueSize: number;\n private readonly debug: boolean;\n private timer: ReturnType<typeof setInterval> | null = null;\n private flushing = false;\n private listenersAttached = false;\n /**\n * Gate on every send path (batchSize-triggered, timer, and unload flush) —\n * set only by `start()`/`stop()`. Events still `enqueue()` (and accumulate,\n * capped) while `false`, so nothing fired before consent is lost; nothing is\n * actually sent over the network until `start()` is called.\n */\n private allowed = false;\n\n private readonly onPageHide = (): void => this.flushOnUnload();\n private readonly onVisibilityChange = (): void => {\n if (document.visibilityState === \"hidden\") this.flushOnUnload();\n };\n\n constructor(opts: AnalyticsQueueOptions) {\n this.send = opts.send;\n this.batchSize = opts.batchSize ?? 20;\n this.flushIntervalMs = opts.flushIntervalMs ?? 3000;\n this.maxQueueSize = opts.maxQueueSize ?? 200;\n this.debug = opts.debug ?? false;\n }\n\n /** Allow sending, and start the periodic flush timer + unload listeners. Idempotent. */\n start(): void {\n this.allowed = true;\n if (this.timer || typeof window === \"undefined\") return;\n this.timer = setInterval(() => void this.flush(), this.flushIntervalMs);\n window.addEventListener(\"pagehide\", this.onPageHide);\n document.addEventListener(\"visibilitychange\", this.onVisibilityChange);\n this.listenersAttached = true;\n }\n\n /** Disallow sending and stop the timer/listeners. Queued events are kept, not flushed. */\n stop(): void {\n this.allowed = false;\n if (this.timer) clearInterval(this.timer);\n this.timer = null;\n if (this.listenersAttached) {\n window.removeEventListener(\"pagehide\", this.onPageHide);\n document.removeEventListener(\"visibilitychange\", this.onVisibilityChange);\n this.listenersAttached = false;\n }\n }\n\n /** Queue an event. Flushes immediately once `batchSize` is reached (if allowed). */\n enqueue(event: XeniaEvent): void {\n if (this.queue.length >= this.maxQueueSize) this.queue.shift();\n this.queue.push(event);\n if (this.allowed && this.queue.length >= this.batchSize) void this.flush();\n }\n\n /**\n * Send one event right now, bypassing the consent gate and the batch window —\n * used for journey triggers, which are latency-sensitive and must fire even\n * before analytics consent is granted (the backend still consent-gates the\n * analytics half server-side). Reuses the same 4xx-drop / transient-requeue\n * policy as {@link flush}: a permanent 4xx is dropped, anything transient is\n * requeued for a later flush tick.\n *\n * Sent with `keepalive` because the canonical trigger is a declarative\n * `data-xenia=\"<eventId>&click\"` on a link or submit button: the click starts a\n * navigation that tears the document down, and a normal fetch is cancelled with\n * it — losing exactly the events a journey is waiting on. `keepalive` lets the\n * request outlive the document (same reason {@link flushOnUnload} uses it).\n */\n async sendImmediate(event: XeniaEvent): Promise<void> {\n try {\n await this.send([event], { keepalive: true });\n } catch (err) {\n if (!this.isPermanentFailure(err)) this.requeue([event]);\n if (this.debug) console.warn(\"[xenia] immediate send failed\", err);\n }\n }\n\n /** Send up to `batchSize` queued events. No-op if not allowed, already flushing, or empty. */\n async flush(): Promise<void> {\n if (!this.allowed || this.flushing || this.queue.length === 0) return;\n this.flushing = true;\n const batch = this.queue.splice(0, this.batchSize);\n try {\n await this.send(batch);\n } catch (err) {\n // A 4xx means the backend permanently rejected this exact payload (e.g.\n // failed identity validation) — HttpClient already retried anything\n // transient (429/5xx/network errors) before giving up, so requeuing a\n // 4xx would just resend the same invalid batch forever, jamming the\n // queue behind it. Drop it; requeue everything else for the next tick.\n if (!this.isPermanentFailure(err)) this.requeue(batch);\n if (this.debug) console.warn(\"[xenia] analytics flush failed\", err);\n } finally {\n this.flushing = false;\n }\n }\n\n private isPermanentFailure(err: unknown): boolean {\n return err instanceof HttpError && err.status >= 400 && err.status < 500;\n }\n\n /** Best-effort synchronous-ish flush of everything queued, for `pagehide`/hidden. */\n private flushOnUnload(): void {\n if (!this.allowed || this.queue.length === 0) return;\n const batch = this.queue.splice(0, this.queue.length);\n void this.send(batch, { keepalive: true }).catch(() => {\n /* page is unloading — nothing left to recover into */\n });\n }\n\n private requeue(batch: XeniaEvent[]): void {\n const room = this.maxQueueSize - this.queue.length;\n if (room <= 0) return;\n this.queue.unshift(...batch.slice(0, room));\n }\n}\n","import type { InteractionType } from \"../core/types\";\n\nconst VALID: ReadonlySet<InteractionType> = new Set<InteractionType>([\n \"click\",\n \"view-port\",\n \"page-load\",\n]);\n\ninterface Parsed {\n eventId: string;\n interactionType: InteractionType;\n}\n\n/** Parse `data-<prefix>=\"<eventId>&<interactionType>\"`. */\nexport function parseDataAttribute(value: string): Parsed | null {\n const sep = value.indexOf(\"&\");\n if (sep === -1) return null;\n const eventId = value.slice(0, sep);\n const interactionType = value.slice(sep + 1) as InteractionType;\n if (!eventId || !VALID.has(interactionType)) return null;\n return { eventId, interactionType };\n}\n\n/** Personalization slot metadata read from `data-xenia-*` attributes. */\nexport interface SlotMeta {\n contentKey: string;\n contentEntryId?: string;\n baseEntryId?: string;\n personalized?: boolean;\n}\n\nexport interface AutoTrackOptions {\n prefix: string;\n throttleMs: number;\n viewport: { threshold: number; rootMargin?: string; triggerOnce: boolean };\n /** Fire an auto-tracked journey event (`data-xenia=\"<eventId>&<type>\"`). */\n fire: (eventId: string, interactionType: InteractionType) => void;\n /**\n * Fire a personalization slot event (`[data-xenia-slot]`) — `impression` on\n * first viewport entry (once), `click` on click. Optional: when omitted, slot\n * scanning is skipped entirely.\n */\n fireSlot?: (interaction: \"impression\" | \"click\", meta: SlotMeta) => void;\n}\n\n/** Read the resolve metadata attributes off a `[data-xenia-slot]` element. */\nexport function readSlotMeta(el: Element): SlotMeta | null {\n const contentKey = el.getAttribute(\"data-xenia-content-key\");\n if (!contentKey) return null;\n const contentEntryId = el.getAttribute(\"data-xenia-content-entry-id\");\n const baseEntryId = el.getAttribute(\"data-xenia-base-entry-id\");\n const personalized = el.getAttribute(\"data-xenia-personalized\");\n return {\n contentKey,\n contentEntryId: contentEntryId ?? undefined,\n baseEntryId: baseEntryId ?? undefined,\n personalized: personalized == null ? undefined : personalized === \"true\",\n };\n}\n\n/**\n * Wires declarative `data-xenia` auto-tracking: delegated clicks, an\n * IntersectionObserver for `view-port`, immediate `page-load`, and a\n * MutationObserver so elements added later are tracked too. Ported from\n * `xenia-tracker.iife.js`.\n *\n * Also scans `[data-xenia-slot]` personalization slots (when `fireSlot` is set):\n * a viewport-once `impression` and click `click`, both read from the resolve\n * metadata attrs (`data-xenia-content-key` / `-content-entry-id` /\n * `-base-entry-id` / `-personalized`).\n */\nexport class AutoTracker {\n private readonly opts: AutoTrackOptions;\n private readonly throttleTimers = new Map<Element, number>();\n private readonly observers = new Map<Element, IntersectionObserver>();\n private readonly slotObservers = new Map<Element, IntersectionObserver>();\n private readonly triggered = new Set<Element>();\n private readonly slotImpressed = new Set<Element>();\n private clickHandler: ((e: MouseEvent) => void) | null = null;\n private mutationObserver: MutationObserver | null = null;\n\n constructor(opts: AutoTrackOptions) {\n this.opts = opts;\n }\n\n start(): void {\n this.setupClicks();\n this.scan(document);\n this.setupMutations();\n }\n\n stop(): void {\n if (this.clickHandler) document.removeEventListener(\"click\", this.clickHandler);\n this.clickHandler = null;\n this.mutationObserver?.disconnect();\n this.mutationObserver = null;\n this.observers.forEach((o) => o.disconnect());\n this.observers.clear();\n this.slotObservers.forEach((o) => o.disconnect());\n this.slotObservers.clear();\n this.throttleTimers.clear();\n this.triggered.clear();\n this.slotImpressed.clear();\n }\n\n private attr(): string {\n return `data-${this.opts.prefix}`;\n }\n\n private throttled(el: Element): boolean {\n if (this.opts.throttleMs <= 0) return false;\n const now = Date.now();\n const last = this.throttleTimers.get(el) ?? 0;\n if (now - last >= this.opts.throttleMs) {\n this.throttleTimers.set(el, now);\n return false;\n }\n return true;\n }\n\n private setupClicks(): void {\n const attr = this.attr();\n this.clickHandler = (event: MouseEvent) => {\n const target = event.target as Element | null;\n if (!target) return;\n\n // Journey trigger click (`data-xenia=\"<eventId>&click\"`).\n const el = target.closest(`[${attr}]`);\n if (el) {\n const raw = el.getAttribute(attr);\n const parsed = raw ? parseDataAttribute(raw) : null;\n if (parsed && parsed.interactionType === \"click\" && !this.throttled(el)) {\n this.opts.fire(parsed.eventId, \"click\");\n }\n }\n\n // Personalization slot click (`[data-xenia-slot]`).\n if (this.opts.fireSlot) {\n const slot = target.closest(\"[data-xenia-slot]\");\n if (slot) {\n const meta = readSlotMeta(slot);\n if (meta && !this.throttled(slot)) this.opts.fireSlot(\"click\", meta);\n }\n }\n };\n document.addEventListener(\"click\", this.clickHandler);\n }\n\n private observeSlot(el: Element): void {\n if (!this.opts.fireSlot || this.slotObservers.has(el)) return;\n const meta = readSlotMeta(el);\n // No resolve metadata yet → not a resolved slot; skip (it'll be re-scanned\n // if replaced with a fresh node carrying the attrs).\n if (!meta) return;\n const fireSlot = this.opts.fireSlot;\n const { threshold, rootMargin } = this.opts.viewport;\n const observer = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n if (!entry.isIntersecting) continue;\n if (this.slotImpressed.has(el)) continue;\n this.slotImpressed.add(el);\n fireSlot(\"impression\", meta);\n observer.disconnect();\n this.slotObservers.delete(el);\n }\n },\n { threshold, rootMargin },\n );\n observer.observe(el);\n this.slotObservers.set(el, observer);\n }\n\n private observeViewport(el: Element, eventId: string): void {\n if (this.observers.has(el)) return;\n const { threshold, rootMargin, triggerOnce } = this.opts.viewport;\n const observer = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n if (!entry.isIntersecting) continue;\n if (triggerOnce && this.triggered.has(el)) continue;\n if (this.throttled(el)) continue;\n this.opts.fire(eventId, \"view-port\");\n if (triggerOnce) {\n this.triggered.add(el);\n observer.disconnect();\n this.observers.delete(el);\n }\n }\n },\n { threshold, rootMargin },\n );\n observer.observe(el);\n this.observers.set(el, observer);\n }\n\n private handleElement(el: Element): void {\n const raw = el.getAttribute(this.attr());\n if (!raw) return;\n const parsed = parseDataAttribute(raw);\n if (!parsed) return;\n if (parsed.interactionType === \"view-port\") this.observeViewport(el, parsed.eventId);\n else if (parsed.interactionType === \"page-load\") this.opts.fire(parsed.eventId, \"page-load\");\n }\n\n private scan(root: ParentNode): void {\n root.querySelectorAll(`[${this.attr()}]`).forEach((el) => this.handleElement(el));\n if (this.opts.fireSlot) {\n root.querySelectorAll(\"[data-xenia-slot]\").forEach((el) => this.observeSlot(el));\n }\n }\n\n private setupMutations(): void {\n this.mutationObserver = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n for (const node of mutation.addedNodes) {\n if (node.nodeType !== Node.ELEMENT_NODE) continue;\n const el = node as Element;\n this.handleElement(el);\n if (this.opts.fireSlot && el.matches(\"[data-xenia-slot]\")) this.observeSlot(el);\n this.scan(el);\n }\n }\n });\n this.mutationObserver.observe(document.body, { childList: true, subtree: true });\n }\n}\n","import {\n CONSENT_COOKIE,\n VISITOR_COOKIE,\n consentCookie,\n consentCookieName,\n visitorCookieName,\n} from \"../core/cookie-names\";\nimport type { ConsentState } from \"../core/types\";\n\n/**\n * Cookie names the SDK reads server-side (set by the browser SDK / your app).\n *\n * The constants are the DEFAULT-prefix names; the functions build the name for any prefix. If you\n * pass `config.prefix` to the browser client, pass the same prefix here — the browser namespaces\n * the cookie by it, so the default name won't be there to find.\n */\nexport { CONSENT_COOKIE, VISITOR_COOKIE, consentCookie, consentCookieName, visitorCookieName };\n\n/**\n * Parse a raw `Cookie` header into a map. Framework-agnostic so it works with\n * `Request.headers.get(\"cookie\")`, Node `req.headers.cookie`, etc.\n */\nexport function parseCookies(header: string | null | undefined): Record<string, string> {\n const out: Record<string, string> = {};\n if (!header) return out;\n for (const part of header.split(\";\")) {\n const idx = part.indexOf(\"=\");\n if (idx === -1) continue;\n const key = part.slice(0, idx).trim();\n const value = part.slice(idx + 1).trim();\n if (key) out[key] = decodeURIComponent(value);\n }\n return out;\n}\n\n/**\n * Read the visitor id the browser SDK wrote, so a server-side event can be bound to the same\n * visitor (`createXeniaServer({ visitorId })`) and attribute to a browser-entered journey.\n *\n * @param prefix Must match the browser client's `config.prefix`. The cookie is namespaced by it, so\n * a mismatch finds nothing and quietly leaves the server with no visitor.\n */\nexport function getVisitorId(\n cookieHeader: string | null | undefined,\n prefix?: string,\n): string | null {\n return parseCookies(cookieHeader)[visitorCookieName(prefix)] ?? null;\n}\n\n/**\n * Read consent from a cookie header. Accepts a JSON blob or a comma-list of\n * granted scopes (e.g. `analytics,personalization`). Absent → all denied.\n *\n * @param prefix Must match the browser client's `config.prefix` — see {@link getVisitorId}.\n */\nexport function getConsent(\n cookieHeader: string | null | undefined,\n prefix?: string,\n): ConsentState {\n const raw = parseCookies(cookieHeader)[consentCookieName(prefix)];\n if (!raw) return { analytics: false, marketing: false, personalization: false };\n try {\n const parsed = JSON.parse(raw) as ConsentState;\n return parsed;\n } catch {\n const scopes = new Set(raw.split(\",\").map((s) => s.trim()));\n return {\n analytics: scopes.has(\"analytics\"),\n marketing: scopes.has(\"marketing\"),\n personalization: scopes.has(\"personalization\"),\n };\n }\n}\n","import { visitorCookieName } from \"../core/cookie-names\";\nimport { parseCookies } from \"../server/cookies\";\nimport { generateUlid } from \"../core/id\";\nimport type { EventContext, VisitorCookieOptions } from \"../core/types\";\n\n/** Session expires after this much inactivity (ms). */\nconst SESSION_TIMEOUT_MS = 30 * 60 * 1000;\n\n/** Resolved visitor-cookie settings, or null when disabled. */\ntype CookieConfig = Required<Omit<VisitorCookieOptions, \"domain\">> & { domain?: string };\n\n/**\n * Browser identity + context manager.\n *\n * Owns the device id, visitor id, session id, UTM capture/persistence, and\n * journey attribution — all the ambient signals the SDK attaches to events so\n * the developer never has to. Ported from the production `xenia-tracker.iife.js`.\n */\nexport class Identity {\n private readonly prefix: string;\n private readonly cookie: CookieConfig | null;\n private deviceId: string | null = null;\n private journeyId: string | null = null;\n private sessionId: string | null = null;\n\n constructor(prefix = \"xenia\", visitorCookie: boolean | VisitorCookieOptions = true) {\n this.prefix = prefix;\n this.cookie = resolveCookieConfig(visitorCookie);\n }\n\n private key(name: string): string {\n return `${this.prefix}_${name}`;\n }\n\n /**\n * The visitor cookie name, namespaced by `config.prefix` so two Xenia apps on one domain keep\n * separate visitors. Built with the SHARED helper the server half also uses\n * (`visitorCookieName`) — the two runtimes have to derive this identically, or the server looks\n * for a cookie the browser never wrote and silently ends up with no visitor, which quietly breaks\n * attribution for server-side conversions.\n */\n private cookieName(): string {\n return visitorCookieName(this.prefix);\n }\n\n /**\n * Persist the effective visitor id to a first-party cookie so same-origin\n * server code can read it (server SDK `getVisitorId(cookieHeader)`) and bind\n * the SAME visitor — the link that lets a server-side conversion attribute to\n * a browser-entered journey. No-op when disabled or off-DOM.\n */\n private writeVisitorCookie(id: string | null | undefined): void {\n if (!this.cookie || !id) return;\n try {\n if (typeof document === \"undefined\") return;\n const parts = [\n `${this.cookieName()}=${encodeURIComponent(id)}`,\n \"path=/\",\n `max-age=${Math.floor(this.cookie.maxAgeDays * 86400)}`,\n `SameSite=${this.cookie.sameSite}`,\n ];\n if (this.cookie.domain) parts.push(`domain=${this.cookie.domain}`);\n if (this.cookie.secure) parts.push(\"Secure\");\n document.cookie = parts.join(\"; \");\n } catch {\n /* document.cookie unavailable */\n }\n }\n\n /** The visitor id already in the cookie — e.g. minted by `xeniaProxy()` on the first request. */\n private readVisitorCookie(): string | null {\n if (!this.cookie || typeof document === \"undefined\") return null;\n try {\n return parseCookies(document.cookie)[this.cookieName()] || null;\n } catch {\n return null;\n }\n }\n\n // ── Device id ────────────────────────────────────────────────────────────\n\n /**\n * Resolve a stable device id: localStorage cache → the visitor cookie a server already set →\n * MediaDevices → SHA-256 browser fingerprint. Cached for the session and across reloads.\n */\n async resolveDeviceId(): Promise<string> {\n if (this.deviceId) {\n this.writeVisitorCookie(this.getVisitorId() ?? this.deviceId);\n return this.deviceId;\n }\n const storageKey = this.key(\"device_id\");\n try {\n const cached = localStorage.getItem(storageKey);\n if (cached) {\n this.deviceId = cached;\n this.writeVisitorCookie(this.getVisitorId() ?? cached);\n return cached;\n }\n } catch {\n /* localStorage unavailable */\n }\n\n // Join the visitor the server already set instead of minting a second id: overwriting it would\n // turn one person into two visitors mid-visit — server-side decisions, A/B groups and journey\n // attribution recorded for the first id would no longer apply.\n let id = this.readVisitorCookie();\n if (!id) id = await this.mediaDeviceId();\n if (!id) id = await this.fingerprint();\n\n this.deviceId = id;\n try {\n localStorage.setItem(storageKey, id);\n } catch {\n /* ignore */\n }\n // Persist the effective visitor id (explicit visitor id if set, else this\n // device id) to the cookie so same-origin server calls resolve the same one.\n this.writeVisitorCookie(this.getVisitorId() ?? id);\n return id;\n }\n\n getDeviceId(): string | null {\n return this.deviceId;\n }\n\n private async mediaDeviceId(): Promise<string | null> {\n try {\n if (!navigator.mediaDevices?.enumerateDevices) return null;\n const devices = await navigator.mediaDevices.enumerateDevices();\n const device =\n devices.find((d) => d.kind === \"videoinput\" && d.deviceId) ||\n devices.find((d) => d.kind === \"audioinput\" && d.deviceId) ||\n devices.find((d) => d.kind === \"audiooutput\" && d.deviceId);\n return device?.deviceId || null;\n } catch {\n return null;\n }\n }\n\n private async fingerprint(): Promise<string> {\n const raw = [\n navigator.userAgent,\n navigator.language,\n screen.width,\n screen.height,\n screen.colorDepth,\n new Date().getTimezoneOffset(),\n ].join(\"|\");\n const buffer = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(raw));\n return Array.from(new Uint8Array(buffer))\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n\n // ── Visitor id ─────────────────────────────────────────────────────────────\n\n /** Persist a visitor id so it rides on every future event. */\n identify(visitorId: string): void {\n if (!visitorId) return;\n try {\n localStorage.setItem(this.key(\"visitor_id\"), visitorId);\n } catch {\n /* ignore */\n }\n this.writeVisitorCookie(visitorId);\n }\n\n getVisitorId(): string | null {\n try {\n return localStorage.getItem(this.key(\"visitor_id\"));\n } catch {\n return null;\n }\n }\n\n // ── Customer id / email ──────────────────────────────────────────────────\n //\n // Ambient, persisted the same way as the visitor id, so a value set once\n // (typically alongside `identify()`) rides on every later `resolve()` call\n // without the caller having to pass it again — the SDK-provided-fields\n // parity list on the Personalization Resolve trigger includes both.\n\n setCustomerId(customerId: string | null): void {\n try {\n if (customerId) localStorage.setItem(this.key(\"customer_id\"), customerId);\n else localStorage.removeItem(this.key(\"customer_id\"));\n } catch {\n /* ignore */\n }\n }\n\n getCustomerId(): string | null {\n try {\n return localStorage.getItem(this.key(\"customer_id\"));\n } catch {\n return null;\n }\n }\n\n setEmail(email: string | null): void {\n try {\n if (email) localStorage.setItem(this.key(\"email\"), email);\n else localStorage.removeItem(this.key(\"email\"));\n } catch {\n /* ignore */\n }\n }\n\n getEmail(): string | null {\n try {\n return localStorage.getItem(this.key(\"email\"));\n } catch {\n return null;\n }\n }\n\n // ── Session id ───────────────────────────────────────────────────────────────\n\n /**\n * Resolve the current session id: reused while activity continues within\n * {@link SESSION_TIMEOUT_MS}, otherwise a new one is minted. Persisted in\n * `sessionStorage` (survives reloads/navigation within the tab, not across\n * tabs or after the timeout) so events sent from other `Identity` instances\n * in the same tab share one session.\n */\n getSessionId(): string {\n const idKey = this.key(\"session_id\");\n const lastActivityKey = this.key(\"session_last_activity\");\n const now = Date.now();\n\n try {\n const storedId = sessionStorage.getItem(idKey);\n const lastActivity = Number(sessionStorage.getItem(lastActivityKey));\n const fresh = storedId && Number.isFinite(lastActivity) && now - lastActivity < SESSION_TIMEOUT_MS;\n const id = fresh ? storedId : generateUlid(now);\n sessionStorage.setItem(idKey, id);\n sessionStorage.setItem(lastActivityKey, String(now));\n this.sessionId = id;\n return id;\n } catch {\n /* sessionStorage unavailable — degrade to one id per page load (no cross-reload persistence, no timeout enforcement) */\n if (!this.sessionId) this.sessionId = generateUlid(now);\n return this.sessionId;\n }\n }\n\n // ── Journey attribution ─────────────────────────────────────────────────────\n\n /** Manually set the customer-journey UUID for this session (overrides utm_id). */\n setJourneyId(id: string | null): void {\n this.journeyId = id && id.trim() ? id.trim() : null;\n }\n\n /** Effective journey id: manual override > utm_id (URL/sessionStorage). */\n getJourneyId(): string | null {\n return this.journeyId || this.utmParam(\"utm_id\") || null;\n }\n\n // ── UTM + page context ───────────────────────────────────────────────────\n\n /** Read a UTM param from the URL, persisting it so it survives navigation. */\n private utmParam(name: string): string | null {\n try {\n const val = new URLSearchParams(window.location.search).get(name);\n if (val) {\n try {\n sessionStorage.setItem(this.key(name), val);\n } catch {\n /* ignore */\n }\n return val;\n }\n try {\n return sessionStorage.getItem(this.key(name));\n } catch {\n /* ignore */\n }\n } catch {\n /* ignore */\n }\n return null;\n }\n\n /** Collect UTM + page context (url/path/query) + visitor id for merging into an event. */\n collectContext(): EventContext & { visitorId?: string } {\n const ctx: EventContext & { visitorId?: string } = {};\n const utmSource = this.utmParam(\"utm_source\");\n const utmMedium = this.utmParam(\"utm_medium\");\n const utmCampaign = this.utmParam(\"utm_campaign\");\n const utmContent = this.utmParam(\"utm_content\");\n const utmId = this.utmParam(\"utm_id\");\n\n if (utmSource) ctx.utmSource = utmSource;\n if (utmMedium) ctx.utmMedium = utmMedium;\n if (utmCampaign) ctx.utmCampaign = utmCampaign;\n if (utmContent) ctx.utmContent = utmContent;\n if (utmId) ctx.utmId = utmId;\n\n try {\n ctx.url = window.location.href;\n ctx.path = window.location.pathname;\n ctx.query = Object.fromEntries(new URLSearchParams(window.location.search));\n if (document.referrer) ctx.referrer = document.referrer;\n } catch {\n /* ignore */\n }\n\n const vid = this.getVisitorId();\n if (vid) ctx.visitorId = vid;\n\n return ctx;\n }\n}\n\n/** Resolve the `visitorCookie` config to concrete settings, or null when disabled. */\nfunction resolveCookieConfig(opt: boolean | VisitorCookieOptions): CookieConfig | null {\n if (opt === false) return null;\n const o = opt === true ? {} : opt;\n const sameSite = o.sameSite ?? \"Lax\";\n // SameSite=None is only honored with Secure, so force it on.\n const secure = sameSite === \"None\" ? true : (o.secure ?? false);\n return { sameSite, secure, maxAgeDays: o.maxAgeDays ?? 365, domain: o.domain };\n}\n","import type { MessageAction, WidgetWireContext } from \"./types\";\n\n/**\n * Shared form-field / submit DOM convention, used by EVERY widget type (including standard\n * popups and `custom`) — see the cross-repo contract. Capturable inputs are marked\n * `data-xenia-field=\"<name>\"`; the submit trigger is marked `data-xenia-submit`. Read directly\n * by `wireFormSubmit()` below, and reused as-is by the spin-wheel widget module\n * (which has its own trigger — a Spin button — but still collects\n * `data-xenia-field` values the same way).\n */\nexport function collectFields(root: Element | ShadowRoot | Document): Record<string, string> {\n const fields: Record<string, string> = {};\n root.querySelectorAll(\"[data-xenia-field]\").forEach((el) => {\n const name = el.getAttribute(\"data-xenia-field\");\n if (!name) return;\n fields[name] = fieldValue(el);\n });\n return fields;\n}\n\nfunction fieldValue(el: Element): string {\n if (el instanceof HTMLInputElement) {\n if (el.type === \"checkbox\") return el.checked ? el.value || \"on\" : \"\";\n if (el.type === \"radio\") return el.checked ? el.value : \"\";\n return el.value;\n }\n if (el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement) return el.value;\n return el.textContent?.trim() ?? \"\";\n}\n\n/** Set/clear the disabled state on whatever kind of element the submit trigger turned out to be. */\nfunction setDisabled(el: Element | null | undefined, disabled: boolean): void {\n if (!el) return;\n if (\n el instanceof HTMLButtonElement ||\n el instanceof HTMLInputElement ||\n el instanceof HTMLSelectElement ||\n el instanceof HTMLTextAreaElement ||\n el instanceof HTMLFieldSetElement\n ) {\n el.disabled = disabled;\n } else if (disabled) {\n el.setAttribute(\"aria-disabled\", \"true\");\n } else {\n el.removeAttribute(\"aria-disabled\");\n }\n}\n\n/** Write (or clear) a message into the widget's `[data-xenia-error]` slot, if the markup has one. */\nfunction showError(root: Element | ShadowRoot, message: string): void {\n const el = root.querySelector(\"[data-xenia-error]\");\n if (el) el.textContent = message;\n}\n\nconst SUBMIT_STYLE_ID = \"xenia-form-submit-style\";\n\n/** Injects the spinner keyframe/rule once per root — self-contained (no dependency on the\n * design's own markup/CSS), so it works whether the design has a `<style>` block or not. */\nfunction ensureSubmitStyles(root: Element | ShadowRoot): void {\n if (root.querySelector(`#${SUBMIT_STYLE_ID}`)) return;\n const style = document.createElement(\"style\");\n style.id = SUBMIT_STYLE_ID;\n style.textContent =\n \"@keyframes xenia-submit-spin{to{transform:rotate(360deg)}}\" +\n \"[data-xenia-submitting]::after{content:'';display:inline-block;width:0.85em;height:0.85em;\" +\n \"margin-left:0.5em;vertical-align:-0.15em;border:2px solid currentColor;\" +\n \"border-right-color:transparent;border-radius:50%;animation:xenia-submit-spin 0.6s linear infinite}\";\n root.prepend(style);\n}\n\n/** Toggles the spinner attribute on the submit control while a request is in flight. */\nfunction setSubmitting(el: Element | null | undefined, submitting: boolean): void {\n if (!el) return;\n if (submitting) el.setAttribute(\"data-xenia-submitting\", \"\");\n else el.removeAttribute(\"data-xenia-submitting\");\n}\n\n/** Fades/scales the whole card out, then dismisses it — the \"submitted!\" beat between a\n * successful response and the widget disappearing, universal regardless of the design's own\n * markup (it targets the shadow host / card root, not anything design-authored). */\nfunction fadeOutAndDismiss(root: Element | ShadowRoot, dismiss?: () => void): void {\n if (!dismiss) return;\n const host = root instanceof ShadowRoot ? root.host : root;\n if (host instanceof HTMLElement) {\n host.style.transition = \"opacity 220ms ease, transform 220ms ease\";\n host.style.opacity = \"0\";\n host.style.transform = \"scale(0.96)\";\n window.setTimeout(dismiss, 220);\n } else {\n dismiss();\n }\n}\n\n/** The real dispatch (`/flow` or `/widget-submissions`) typically responds in well under 100ms —\n * fading the card out the instant it resolves would make it vanish before a visitor registers\n * it worked at all. Used as the floor whenever the marketer hasn't configured their own value\n * on the webhook-response node's Form-submission panel (`formSubmit.successDisplayMs`). */\nconst DEFAULT_SUCCESS_DISPLAY_MS = 900;\n\n/**\n * Reveals the design's own success-state block, if it authored one — the collaboration point\n * with Content Studio/AI content generation: a marketer/AI can add\n * `<div data-xenia-success hidden>You're on the list! 🎉</div>` anywhere in a popup/custom\n * widget's HTML, and this swaps it in for the form/fields the moment a submit succeeds, for\n * whatever `successDisplayMs` window is configured, instead of the card just sitting there\n * disabled (or, with no success block at all, that's exactly what happens — a plain but still\n * minimum-duration-respecting wait before the fade). Returns whether a success block was found.\n */\nfunction revealSuccess(root: Element | ShadowRoot, form: HTMLFormElement | null): boolean {\n const successEl = root.querySelector(\"[data-xenia-success]\");\n if (!successEl) return false;\n if (successEl instanceof HTMLElement) successEl.hidden = false;\n else successEl.removeAttribute(\"hidden\");\n if (form) {\n form.hidden = true;\n } else {\n root.querySelectorAll<HTMLElement>(\"[data-xenia-field], [data-xenia-submit]\").forEach((el) => {\n el.hidden = true;\n });\n }\n return true;\n}\n\n/**\n * Wire the shared field-collection/submit convention onto an already-injected card. Used for\n * every `standard`/`custom` widget (i.e. the fallthrough path in `ActionRenderer.wireCard()`) —\n * this is the fix for the original loophole: a marketer/AI-authored popup with a real `<input>` +\n * submit button now actually does something on submit.\n *\n * - If a real `<form>` is present in the injected HTML, its native `submit` event is\n * auto-detected: `preventDefault()` is called and its `FormData` is merged into the collected\n * `data-xenia-field` values (a marketer/AI who bothers to wrap fields in a `<form>` gets native\n * Enter-to-submit/validation for free — nothing requires it).\n * - Otherwise, the trigger is a click on `[data-xenia-submit]`.\n * - The submit control is disabled synchronously on trigger (double-submit guard) and grows a\n * small spinner (`[data-xenia-submitting]`) for the duration of the request.\n * - On success: the spinner clears, the design's own `[data-xenia-success]` block (if authored —\n * see {@link revealSuccess}) swaps in for the form, and after at least `successDisplayMs` has\n * elapsed since the submit started (real dispatch round-trips are typically well under 100ms,\n * too fast to register on its own), the whole card fades/scales out and dismisses itself\n * ({@link fadeOutAndDismiss}) — the widget never just sits there disabled forever, and never\n * vanishes before a visitor sees it worked.\n * - On error: the spinner clears, the control re-enables, and an error message is shown.\n *\n * The `<form>`'s native `submit` is ALWAYS intercepted, even when `action.formSubmit` is missing\n * (the marketer hasn't configured a submission target in the webhook-response node's\n * Form-submission panel yet) — otherwise an unconfigured widget's real `<form>` falls through to\n * the browser's default GET-to-current-URL submission, i.e. a full page reload. An unconfigured\n * submit now surfaces a visible, inert error instead of silently doing nothing OR reloading.\n */\nexport function wireFormSubmit(\n root: Element | ShadowRoot,\n action: MessageAction,\n ctx: WidgetWireContext,\n): void {\n const form = root.querySelector(\"form\");\n let submitting = false;\n ensureSubmitStyles(root);\n\n const run = (control: Element | null, fields: Record<string, string>): void => {\n if (submitting) return;\n if (!action.formSubmit) {\n showError(root, \"This form isn't connected yet.\");\n return;\n }\n submitting = true;\n showError(root, \"\");\n setDisabled(control, true);\n setSubmitting(control, true);\n const startedAt = Date.now();\n const minDisplayMs = action.formSubmit.successDisplayMs ?? DEFAULT_SUCCESS_DISPLAY_MS;\n ctx\n .submitWidgetForm(fields)\n .then(() => {\n setSubmitting(control, false);\n revealSuccess(root, form);\n const wait = Math.max(0, minDisplayMs - (Date.now() - startedAt));\n window.setTimeout(() => fadeOutAndDismiss(root, ctx.dismiss), wait);\n })\n .catch(() => {\n setSubmitting(control, false);\n setDisabled(control, false);\n showError(root, \"Something went wrong. Please try again.\");\n })\n .finally(() => {\n submitting = false;\n });\n };\n\n if (form) {\n form.addEventListener(\"submit\", (ev) => {\n ev.preventDefault();\n const formFields: Record<string, string> = {};\n new FormData(form).forEach((value, key) => {\n if (typeof value === \"string\") formFields[key] = value;\n });\n const submitter =\n (ev as SubmitEvent).submitter ?? form.querySelector('[type=\"submit\"], button:not([type])');\n run(submitter, { ...collectFields(root), ...formFields });\n });\n }\n\n root.querySelectorAll<HTMLElement>(\"[data-xenia-submit]\").forEach((el) => {\n // An element inside the detected <form> already fires via its `submit` event above —\n // wiring a click handler here too would double-submit.\n if (form?.contains(el)) return;\n el.addEventListener(\"click\", () => run(el, collectFields(root)));\n });\n}\n","import type { MessagePlacement, WidgetSubmitResponse, XeniaAction } from \"../../core/types\";\n\n/** A message-placement action (banner/popup/modal/inline) — the shape every widget renders. */\nexport type MessageAction = Extract<XeniaAction, { type: MessagePlacement }>;\n\n/**\n * Imperative hooks a widget's `wire()` can call back into, injected by `ActionRenderer` —\n * the widget module itself never touches `XeniaClient`/`XeniaApi` directly.\n */\nexport interface WidgetWireContext {\n /**\n * Dismiss this message — unmounts/removes it, same as the built-in card's close button.\n * Absent for placements with no dismiss affordance in this render (e.g. an `inline` action\n * rendered without a wrapping overlay). Widgets should guard with `ctx.dismiss?.()`.\n */\n dismiss?: () => void;\n /** Fire the action's `cta` (event + url), then {@link dismiss}. A no-op beyond dismiss when the action has no `cta`. */\n fireCta: () => void;\n /**\n * Submit captured field values for this widget's `formSubmit` config. Routes to the `/flow`\n * fast path or `/widget-submissions`, per the cross-repo contract's endpoint-selection rule —\n * the widget module never branches on `mode`/inspects the ref fields itself, it just calls this.\n *\n * Rejects if the action has no `formSubmit` config or no submission handler is wired (e.g. a\n * bare `ActionRenderer` constructed without `XeniaClient`). A per-widget-instance\n * `idempotencyKey` is applied automatically and reused across every call from the SAME\n * `wire()` invocation (i.e. a retried submit of the same interaction never mints a new one).\n */\n submitWidgetForm: (fields: Record<string, string>) => Promise<WidgetSubmitResponse>;\n}\n\n/**\n * Renders and wires a `widgetType`'s UI. One implementation per dispatchable widget type,\n * collected into `WIDGET_RENDERERS` (`client/widgets/index.ts`). `standard`/`custom`/undefined\n * are NOT dispatched through this interface — they use `ActionRenderer`'s existing built-in card\n * path unmodified (plus the shared `wireFormSubmit()` addition), per the cross-repo contract.\n */\nexport interface WidgetRenderer {\n /** Build the card markup injected into the shadow overlay or host-page slot. */\n html(action: MessageAction, variant: MessagePlacement): string;\n /** Wire interactivity after `html()`'s markup is already in the DOM under `root`. */\n wire(root: Element | ShadowRoot, action: MessageAction, ctx: WidgetWireContext): void;\n}\n\n/** Shared HTML escaping — mirrors `renderer.ts`'s private helpers (kept local to avoid a coupling import). */\nexport function escapeHtml(s: string): string {\n return s.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n}\n\nexport function escapeAttr(s: string): string {\n return escapeHtml(s).replace(/\"/g, \"&quot;\");\n}\n\n/**\n * Recognizes marketer/AI-pasted close/backdrop elements by convention (`data-xenia-close` AND\n * the common class/id naming marketers actually use) and wires a `dismiss` that always works —\n * shared by `ActionRenderer.wireCard()` (standard widgets) and any widget module that\n * accepts custom HTML for one of its own screens (spin-wheel's `spinnerHtml`/`winHtml`/\n * `lossHtml`). See renderer.ts's original `wireCard` comment\n * for why: a broken inline `onclick` reaching for `document.getElementById(...)` (pasted from a\n * standalone-page template) throws inside a shadow root/host-page slot and leaves the message\n * stuck open, so this drops it and wires a dismiss that's guaranteed to work instead. Also caps\n * a decorative backdrop's perceived darkness the same way.\n */\nexport function wireCloseAffordances(root: Element | ShadowRoot, dismiss?: () => void): void {\n if (dismiss) {\n const closeEls = root.querySelectorAll(\n \".xenia-close, [data-xenia-close], [class*='close' i], [id*='close' i], \" +\n \"[class*='backdrop' i], [id*='backdrop' i]\",\n );\n closeEls.forEach((el) => {\n el.removeAttribute(\"onclick\");\n el.addEventListener(\"click\", dismiss);\n });\n }\n\n root.querySelectorAll(\"[class*='backdrop' i], [id*='backdrop' i]\").forEach((el) => {\n if (el instanceof HTMLElement && el.children.length === 0 && !el.textContent?.trim()) {\n el.style.opacity = \"0.5\";\n }\n });\n}\n","import type { WidgetSegment } from \"../../core/types\";\nimport { collectFields } from \"./form\";\nimport type { MessageAction, WidgetRenderer, WidgetWireContext } from \"./types\";\nimport { escapeAttr, escapeHtml, wireCloseAffordances } from \"./types\";\n\nconst WHEEL_SIZE = 260;\nconst RADIUS = WHEEL_SIZE / 2;\nconst CENTER = WHEEL_SIZE / 2;\nconst DEFAULT_COLORS = [\"#7c3aed\", \"#2563eb\", \"#059669\", \"#d97706\", \"#dc2626\", \"#0891b2\"];\nconst SPIN_TRANSITION = \"transform 3.2s cubic-bezier(0.15, 0.85, 0.25, 1)\";\nconst WHEEL_POINTER_HTML = '<div class=\"xenia-wheel-pointer\" aria-hidden=\"true\"></div>';\nconst REVEAL_TRANSITION_MS = 320;\nconst REVEAL_TRANSITION = `opacity ${REVEAL_TRANSITION_MS}ms ease, transform ${REVEAL_TRANSITION_MS}ms ease`;\n// `perspective(...)` as a TRANSFORM FUNCTION (not the standalone `perspective` CSS property) —\n// applied only to the element being animated, never to an ancestor. A `perspective`/`transform`\n// on an ANCESTOR of a `position:fixed` element becomes that fixed element's containing block per\n// spec, which is exactly the bug `.xenia-widget-result`'s old CSS animation caused (see\n// renderer.ts) — sizing/positioning it relative to that ancestor's own small box instead of the\n// real viewport. Keeping the 3D transform local to the animated element itself sidesteps that\n// entirely: its OWN position:fixed containing-block is unaffected by a transform function inside\n// its OWN `transform` value.\nconst REVEAL_PERSPECTIVE_PX = 900;\nconst REVEAL_DEPTH_PX = 60;\nconst revealTransform = (scale: number, depthPx: number): string =>\n `perspective(${REVEAL_PERSPECTIVE_PX}px) translateZ(${depthPx}px) scale(${scale})`;\n\n/** A point on the wheel's circumference at `angleDeg` (0 = top/12 o'clock, clockwise) and `radius`. */\nfunction polarPoint(angleDeg: number, radius: number): { x: number; y: number } {\n const rad = (angleDeg * Math.PI) / 180;\n return { x: CENTER + radius * Math.sin(rad), y: CENTER - radius * Math.cos(rad) };\n}\n\n/** SVG `<path>` `d` attribute for one pie slice spanning `startAngle`..`endAngle` degrees. */\nfunction segmentPath(startAngle: number, endAngle: number): string {\n const start = polarPoint(startAngle, RADIUS);\n const end = polarPoint(endAngle, RADIUS);\n const largeArc = endAngle - startAngle > 180 ? 1 : 0;\n return `M ${CENTER},${CENTER} L ${start.x},${start.y} A ${RADIUS},${RADIUS} 0 ${largeArc} 1 ${end.x},${end.y} Z`;\n}\n\n/**\n * Deterministic resting rotation (degrees) that lands segment `segmentIndex` (out of\n * `segmentCount`, equal slices starting at 12 o'clock going clockwise) under the wheel's fixed\n * pointer, plus `extraSpins` full rotations for purely cosmetic flair — extra spins are\n * client-random visual dressing ONLY; they never affect which segment the wheel lands on (the\n * returned value mod 360 is fully determined by `segmentIndex`/`segmentCount`).\n *\n * Pure, exported, and unit-testable with no DOM — per the \"wheel resolution sequencing\"\n * rule, this is called only AFTER the server-resolved `segmentIndex` is known, never before.\n */\nexport function computeSpinRotation(\n segmentIndex: number,\n segmentCount: number,\n extraSpins = 0,\n): number {\n if (segmentCount <= 0) return 0;\n const segmentAngle = 360 / segmentCount;\n const centerAngle = segmentIndex * segmentAngle + segmentAngle / 2;\n const landingAngle = (360 - centerAngle) % 360;\n return extraSpins * 360 + landingAngle;\n}\n\n/**\n * Cross-fades between the currently-shown screen and the one replacing it, with a subtle 3D\n * \"recede away / rise toward camera\" depth pop (perspective + translateZ + scale) — applied\n * directly to each screen's OWN top-level element(s) (`outgoing`/`incoming`'s children), not the\n * `data-xenia-wheel-face`/`.xenia-widget-result` wrapper around them. A marketer's spinnerHtml/\n * winHtml/lossHtml almost always makes its own top-level element `position:fixed` (a real \"full-\n * screen overlay\" ask, not a rare edge case — see the Content Studio preview's own fix for the\n * same design pattern) — `opacity` on an ANCESTOR does visually fade a `position:fixed`\n * descendant, but `transform` on an ancestor does not reliably shrink one (its explicit\n * `width:100vw`/`height:100vh` stays put regardless of which element scales) AND would make that\n * ancestor the fixed element's containing block, repositioning it relative to the ancestor's own\n * box instead of the true viewport (see `.xenia-widget-result`'s doc comment in renderer.ts for\n * the exact bug this caused) — so the transform is set on the fixed element itself, both to\n * actually read as a smooth pop instead of an instant cut, AND to keep it correctly centered on\n * the real screen. `incoming` is revealed synchronously (`hidden = false`) so existing callers\n * observing that flag right after this call keep seeing it — only `outgoing`'s `hidden` flip is\n * deferred until the fade finishes, since nothing needs to observe that synchronously.\n */\nfunction crossFadeReveal(outgoing: HTMLElement | null, incoming: HTMLElement | null): void {\n const outContent = outgoing ? Array.from(outgoing.children) : [];\n const inContent = incoming ? Array.from(incoming.children) : [];\n if (incoming) incoming.hidden = false;\n inContent.forEach((el) => {\n if (!(el instanceof HTMLElement)) return;\n el.style.transition = \"none\";\n el.style.opacity = \"0\";\n el.style.transform = revealTransform(0.94, -REVEAL_DEPTH_PX);\n });\n // Force a reflow so the \"from\" state above actually commits before the transition is armed\n // below — otherwise the browser can coalesce both style writes into a single recalc (nothing\n // was ever painted in between to transition FROM), and the reveal silently snaps straight to\n // its end state instead of animating. Same fix already applied to the dial's spin rotation\n // just below in this file, via `dial.getBoundingClientRect()`.\n inContent.forEach((el) => {\n if (el instanceof HTMLElement) void el.offsetHeight;\n });\n nextFrame(() => {\n outContent.forEach((el) => {\n if (!(el instanceof HTMLElement)) return;\n el.style.transition = REVEAL_TRANSITION;\n el.style.opacity = \"0\";\n el.style.transform = revealTransform(0.94, -REVEAL_DEPTH_PX);\n });\n inContent.forEach((el) => {\n if (!(el instanceof HTMLElement)) return;\n el.style.transition = REVEAL_TRANSITION;\n el.style.opacity = \"1\";\n el.style.transform = revealTransform(1, 0);\n });\n });\n if (outgoing) {\n setTimeout(() => {\n outgoing.hidden = true;\n }, REVEAL_TRANSITION_MS);\n }\n}\n\n/** `requestAnimationFrame`, falling back to a macrotask tick where it's unavailable (e.g. jsdom in tests). */\nfunction nextFrame(fn: () => void): void {\n if (typeof requestAnimationFrame === \"function\") requestAnimationFrame(fn);\n else setTimeout(fn, 0);\n}\n\nfunction wheelSvg(segments: WidgetSegment[]): string {\n const n = segments.length || 1;\n const segmentAngle = 360 / n;\n const slices = segments\n .map((seg, i) => {\n const start = i * segmentAngle;\n const end = start + segmentAngle;\n const color = seg.colorHex || DEFAULT_COLORS[i % DEFAULT_COLORS.length];\n const labelAngle = start + segmentAngle / 2;\n const labelPoint = polarPoint(labelAngle, RADIUS * 0.62);\n return (\n `<path d=\"${segmentPath(start, end)}\" fill=\"${escapeAttr(color)}\" stroke=\"#fff\" stroke-width=\"1\"></path>` +\n `<text x=\"${labelPoint.x}\" y=\"${labelPoint.y}\" fill=\"#fff\" font-size=\"12\" text-anchor=\"middle\" ` +\n `transform=\"rotate(${labelAngle} ${labelPoint.x} ${labelPoint.y})\">${escapeHtml(seg.label)}</text>`\n );\n })\n .join(\"\");\n return (\n `<svg class=\"xenia-wheel-svg\" viewBox=\"0 0 ${WHEEL_SIZE} ${WHEEL_SIZE}\" width=\"${WHEEL_SIZE}\" height=\"${WHEEL_SIZE}\">` +\n `<g class=\"xenia-wheel-dial\">${slices}</g>` +\n // Static hub cap over the center seam — a plain circle, so dial rotation (which only this\n // <g> above undergoes) never visibly affects it; kept outside the rotating group on purpose.\n `<circle class=\"xenia-wheel-hub\" cx=\"${CENTER}\" cy=\"${CENTER}\" r=\"6\"></circle>` +\n `</svg>`\n );\n}\n\nexport const spinWheelRenderer: WidgetRenderer = {\n html(action: MessageAction): string {\n // No `.xenia-card` chrome (background/shadow/radius/padding) of our own, and no built-in\n // close button either — `spinnerHtml`/`winHtml`/`lossHtml` are always full marketer/AI-\n // authored HTML (same role a popup's `body` plays via `wrapCustomHtml`, same \"no generated\n // fallback\" rule), so the author's own card chrome AND close affordance are what actually\n // render. Wrapping in `.xenia-card` too used to nest the SDK's own white background/shadow\n // behind the author's own card, visible as an unwanted glow/halo in the padding gap between\n // them once every screen started drawing its own full chrome (see the \"unwanted background\"\n // regression this replaced, and the \"two ×\" regression fixed the same way just above it).\n return (\n `<div class=\"xenia-spin-wheel\">` +\n `<div data-xenia-wheel-face>${action.spinnerHtml ?? \"\"}</div>` +\n // Hidden by default; never shown before the server-resolved outcome is in hand. Exactly\n // one of win/loss is revealed once resolved, based on the landed segment's `isLoss`.\n `<div class=\"xenia-widget-result\" data-xenia-wheel-result hidden>${action.winHtml ?? \"\"}</div>` +\n `<div class=\"xenia-widget-result\" data-xenia-wheel-loss hidden>${action.lossHtml ?? \"\"}</div>` +\n `</div>`\n );\n },\n\n wire(root: Element | ShadowRoot, action: MessageAction, ctx: WidgetWireContext): void {\n // Covers the built-in close button AND any close/backdrop element a marketer's own\n // spinnerHtml/winHtml/lossHtml happens to include, by the same convention every other\n // custom-HTML surface in this SDK already honors.\n wireCloseAffordances(root, ctx.dismiss);\n\n const segments = action.segments ?? [];\n const wheelFace = root.querySelector<HTMLElement>(\"[data-xenia-wheel-face]\");\n const spinBtn = root.querySelector<HTMLButtonElement>(\"[data-xenia-spin]\");\n const winEl = root.querySelector<HTMLElement>(\"[data-xenia-wheel-result]\");\n const lossEl = root.querySelector<HTMLElement>(\"[data-xenia-wheel-loss]\");\n const errorEl = root.querySelector<HTMLElement>(\"[data-xenia-error]\");\n\n // One injection path for the generated SVG wheel + pointer, whether `wheelFace` is the SDK's\n // own generated markup or a marketer's `spinnerHtml` — either way, the slot is where it goes.\n // Runs regardless of `formSubmit` below — an unconfigured widget still shows the wheel, it\n // just isn't spinnable yet (matches every other still-being-configured widget in this SDK).\n const slotEl = root.querySelector<HTMLElement>(\"[data-xenia-wheel-slot]\");\n if (slotEl) slotEl.insertAdjacentHTML(\"afterbegin\", wheelSvg(segments) + WHEEL_POINTER_HTML);\n const dial = root.querySelector<HTMLElement>(\".xenia-wheel-dial\");\n\n if (!spinBtn || !action.formSubmit) return;\n\n // Labels are already baked into the markup by html() — only click handlers are wired here.\n // `fireCta()` still fires any configured cta event/url before dismissing.\n root.querySelectorAll(\"[data-xenia-wheel-cta]\").forEach((btn) => {\n btn.addEventListener(\"click\", () => ctx.fireCta());\n });\n\n // Swap the wheel face for the win/loss reveal screen — never before the resolved outcome is\n // in hand (see the \"wheel resolution sequencing\" rule referenced throughout this\n // file). Both win and loss prize placeholders are populated (a losing segment still has a\n // `label`, e.g. \"Try Again\") — whichever screen isn't shown just stays hidden either way.\n // The swap itself cross-fades (see crossFadeReveal) rather than an instant `hidden` flip —\n // an un-animated cut between two full-screen overlays read as a jarring flash.\n // `canRetry=false` means the BE's own maxPlays/win-lock guard (see\n // WidgetSubmissionService.submit()) reported `alreadyPlayed: true` for THIS reveal — a\n // replay, not a fresh roll. Whether that's because a real win locked the visitor out, or a\n // string of losses used up every configured retry, one more click would only replay the exact\n // same outcome again — so any `[data-xenia-spin-again]` button is hidden for good, instead of\n // sitting there inviting a click that can never do anything.\n const revealResult = (prizeLabel: string, isLoss: boolean, canRetry: boolean): void => {\n root.querySelectorAll(\"[data-xenia-wheel-prize]\").forEach((el) => {\n el.textContent = prizeLabel;\n });\n const shown = isLoss ? lossEl : winEl;\n const other = isLoss ? winEl : lossEl;\n if (other) other.hidden = true; // never shown this round — no fade needed\n crossFadeReveal(wheelFace, shown);\n if (!canRetry) {\n playsExhausted = true;\n root.querySelectorAll<HTMLElement>(\"[data-xenia-spin-again]\").forEach((btn) => {\n btn.hidden = true;\n });\n }\n };\n\n let spinning = false;\n let playsExhausted = false;\n\n // Reverse of revealResult — a marketer's winHtml/lossHtml may include a\n // `[data-xenia-spin-again]` button (e.g. a loss screen's \"Try Again\") offering the visitor\n // another attempt. This was previously undocumented and unwired: an AI-authored design that\n // added the button (a real, organic pattern — visitors naturally expect \"Try Again\" on a\n // spin-wheel to actually try again) produced a dead button that did nothing on click. Wiring\n // it swaps back to the wheel face (same crossFadeReveal transition, reversed) and re-arms the\n // spin button so a fresh `submitWidgetForm` call can fire. This hook only ever re-opens the\n // ASK — it never itself grants another spin. The BE's own maxPlays/win-lock guard is what\n // actually decides whether the next click resolves to a genuinely fresh roll or a replay of\n // the same already-locked-in outcome; `playsExhausted` (set by revealResult above) is a purely\n // defensive belt-and-braces guard in case the button's own `hidden` gets overridden.\n root.querySelectorAll(\"[data-xenia-spin-again]\").forEach((btn) => {\n btn.addEventListener(\"click\", () => {\n if (playsExhausted) return;\n const shown = winEl && !winEl.hidden ? winEl : lossEl && !lossEl.hidden ? lossEl : null;\n if (!shown) return;\n spinning = false;\n spinBtn.disabled = false;\n if (errorEl) errorEl.textContent = \"\";\n crossFadeReveal(shown, wheelFace);\n });\n });\n\n spinBtn.addEventListener(\"click\", () => {\n if (spinning) return;\n spinning = true;\n spinBtn.disabled = true;\n if (errorEl) errorEl.textContent = \"\";\n\n const fields = collectFields(root);\n // Deliberately do NOT touch `dial`'s transform here — no spin animation starts until the\n // resolved outcome is in hand (see the \"Wheel resolution sequencing\" rule). No\n // optimistic spin, no mid-flight correction: there is never a moment where the client has\n // invented an outcome.\n ctx\n .submitWidgetForm(fields)\n .then((response) => {\n const index = segments.findIndex((s) => s.id === response.prize?.segmentId);\n const prizeLabel = response.prize?.label ?? segments[index]?.label ?? \"\";\n // Unknown whether a stale/mismatched replay's original outcome was a loss — the\n // segments list that carried `isLoss` may since have been edited away entirely. Default\n // to the win screen rather than guess; see the \"no matching segment\" case just below.\n const isLoss = index >= 0 && !!segments[index]?.isLoss;\n\n // No matching segment — e.g. a replay (`alreadyPlayed`) resolving against a segmentId\n // from BEFORE the marketer last edited this widget's segments. Landing the dial on some\n // OTHER segment (like index 0) while announcing a label that segment doesn't show would\n // visibly contradict the wheel — the visitor would see it stop on \"15% Off\" while the\n // card reads \"20% Off\". Skip the animation entirely and reveal the true outcome as-is\n // rather than fabricate a landing position that isn't real.\n const canRetry = response.alreadyPlayed !== true;\n\n if (index < 0 || !dial) {\n revealResult(prizeLabel, isLoss, canRetry);\n return;\n }\n\n const extraSpins = 3 + Math.floor(Math.random() * 3); // cosmetic only — never changes the landing segment\n const rotation = computeSpinRotation(index, segments.length || 1, extraSpins);\n\n // Normalize any rotation left over from a PRIOR spin (same visual angle, mod 360) before\n // committing this one's target. `rotation` above is always >= 3*360, so re-basing the\n // current value into [0, 360) guarantees it can never collide with the new target — without\n // this, a retry landing on the same segment as last time could compute the EXACT same\n // absolute rotation the dial is already resting at. When that happens the CSS transform\n // never actually changes, so `transitionend` never fires, and the widget hangs forever —\n // wheel visibly frozen, spin button stuck disabled, no error, no reveal.\n const priorMatch = /rotate\\(([-\\d.]+)deg\\)/.exec(dial.style.transform);\n const priorRotation = priorMatch ? parseFloat(priorMatch[1]) : 0;\n dial.style.transition = \"none\";\n dial.style.transform = `rotate(${priorRotation % 360}deg)`;\n void dial.getBoundingClientRect(); // force reflow so \"transition: none\" above commits first\n\n dial.style.transition = SPIN_TRANSITION;\n const onTransitionEnd = () => {\n dial.removeEventListener(\"transitionend\", onTransitionEnd);\n revealResult(prizeLabel, isLoss, canRetry);\n };\n dial.addEventListener(\"transitionend\", onTransitionEnd);\n // One frame later, so the transition (set above) is guaranteed to have committed\n // before the transform changes — otherwise some browsers skip straight to the end\n // value instead of animating.\n nextFrame(() => {\n dial.style.transform = `rotate(${rotation}deg)`;\n });\n })\n .catch(() => {\n spinning = false;\n spinBtn.disabled = false;\n if (errorEl) errorEl.textContent = \"Something went wrong. Please try again.\";\n });\n });\n },\n};\n","import { spinWheelRenderer } from \"./spin-wheel\";\nimport type { WidgetRenderer } from \"./types\";\n\n/**\n * Dispatch table keyed by `widgetType`, consulted by `ActionRenderer.cardHtml()`/`wireCard()`.\n * `standard`/undefined is deliberately NOT here — it falls through to `ActionRenderer`'s\n * existing built-in card path (plus the shared `wireFormSubmit()` addition), per the cross-repo\n * contract. A 3rd future widget type is one new module + one new line here.\n */\nexport const WIDGET_RENDERERS: Record<string, WidgetRenderer> = {\n \"spin-wheel\": spinWheelRenderer,\n};\n\nexport type { MessageAction, WidgetRenderer, WidgetWireContext } from \"./types\";\nexport { collectFields, wireFormSubmit } from \"./form\";\nexport { computeSpinRotation, spinWheelRenderer } from \"./spin-wheel\";\n","import { generateUlid } from \"../core/id\";\nimport type {\n MessageComponentRenderer,\n MessageCta,\n MessageMountContext,\n MessagePlacement,\n MessagePosition,\n MessageRenderContext,\n MessageTemplateFn,\n WidgetFormSubmit,\n WidgetSubmitResponse,\n XeniaAction,\n} from \"../core/types\";\nimport { wireFormSubmit } from \"./widgets/form\";\nimport type { WidgetWireContext } from \"./widgets/types\";\nimport { wireCloseAffordances } from \"./widgets/types\";\nimport { WIDGET_RENDERERS } from \"./widgets\";\n\n/** Callback invoked when a rendered CTA fires an event. */\nexport type CtaHandler = (event: string, cta: MessageCta) => void;\n\n/** Submits a widget's captured form values — injected from `XeniaClient.submitWidgetForm`. */\nexport type SubmitWidgetFormHandler = (\n submit: WidgetFormSubmit,\n fields: Record<string, string>,\n opts?: { idempotencyKey?: string },\n) => Promise<WidgetSubmitResponse>;\n\n/**\n * Resolve a target string to an element. Supports plain CSS selectors and the\n * `data-xenia-slot=\"<id>\"` convention (a bare id with no CSS metacharacters is\n * treated as a slot name first, then falls back to a selector).\n */\nexport function resolveTarget(\n target: string,\n root: ParentNode = document,\n): Element | null {\n if (!target) return null;\n const bySlot = root.querySelector(`[data-xenia-slot=\"${cssEscape(target)}\"]`);\n if (bySlot) return bySlot;\n try {\n return root.querySelector(target);\n } catch {\n return null;\n }\n}\n\nfunction cssEscape(value: string): string {\n const anyWin = window as unknown as {\n CSS?: { escape?: (v: string) => string };\n };\n if (anyWin.CSS?.escape) return anyWin.CSS.escape(value);\n return value.replace(/[\"\\\\]/g, \"\\\\$&\");\n}\n\n/** Replace an element's content (or the element itself for `swap`). */\nexport function swapContent(\n target: string,\n content: { html?: string; text?: string },\n): boolean {\n const el = resolveTarget(target);\n if (!el) return false;\n if (content.html !== undefined) {\n el.innerHTML = content.html;\n } else if (content.text !== undefined) {\n el.textContent = content.text;\n }\n el.removeAttribute(\"hidden\");\n return true;\n}\n\n/** Hide an element (kept in the DOM; `display:none` via the hidden attribute). */\nexport function hideContent(target: string): boolean {\n const el = resolveTarget(target);\n if (!el || !(el instanceof HTMLElement)) return false;\n el.dataset.xeniaHidden = \"1\";\n el.style.setProperty(\"display\", \"none\", \"important\");\n return true;\n}\n\n/** Reverse {@link hideContent}. */\nexport function showContent(target: string): boolean {\n const el = resolveTarget(target);\n if (!el || !(el instanceof HTMLElement)) return false;\n delete el.dataset.xeniaHidden;\n el.style.removeProperty(\"display\");\n return true;\n}\n\nconst MESSAGE_TYPES = new Set<MessagePlacement>([\n \"banner\",\n \"popup\",\n \"modal\",\n \"inline\",\n]);\n\nfunction isMessageType(type: string): type is MessagePlacement {\n return MESSAGE_TYPES.has(type as MessagePlacement);\n}\n\n/**\n * Renders and applies {@link XeniaAction}s in the browser. Message-style actions\n * (banner/popup/modal/inline) render inside a shadow root so host-page styles\n * never leak in or out.\n */\nexport class ActionRenderer {\n private host: HTMLElement | null = null;\n private shadow: ShadowRoot | null = null;\n private readonly onCta?: CtaHandler;\n private readonly messageTemplate?: MessageTemplateFn;\n private readonly messageStyles?: string;\n private readonly messageComponent?: MessageComponentRenderer;\n private readonly submitWidgetFormFn?: SubmitWidgetFormHandler;\n /** Unmount callbacks for currently-mounted framework components, keyed by their container. */\n private readonly mounted = new Map<Element, () => void>();\n\n constructor(\n onCta?: CtaHandler,\n opts?: {\n messageTemplate?: MessageTemplateFn;\n messageStyles?: string;\n messageComponent?: MessageComponentRenderer;\n /** Wired from `XeniaClient.submitWidgetForm` — powers every widget's form submission. */\n submitWidgetForm?: SubmitWidgetFormHandler;\n },\n ) {\n this.onCta = onCta;\n this.messageTemplate = opts?.messageTemplate;\n this.messageStyles = opts?.messageStyles;\n this.messageComponent = opts?.messageComponent;\n this.submitWidgetFormFn = opts?.submitWidgetForm;\n }\n\n /** Apply a list of actions. Returns the count successfully applied. */\n apply(actions: XeniaAction[]): number {\n let applied = 0;\n for (const action of actions) {\n if (this.applyOne(action)) applied++;\n }\n return applied;\n }\n\n private applyOne(action: XeniaAction): boolean {\n switch (action.type) {\n case \"swap\":\n return swapContent(action.target, {\n html: action.html,\n text: action.text,\n });\n case \"setContent\":\n return swapContent(action.target, {\n html: action.html,\n text: action.text,\n });\n case \"hide\":\n return hideContent(action.target);\n case \"show\":\n return showContent(action.target);\n case \"redirect\":\n try {\n window.location.assign(action.url);\n return true;\n } catch {\n return false;\n }\n default:\n if (isMessageType(action.type)) return this.renderMessage(action);\n return false;\n }\n }\n\n /** Tear down injected message UI, unmounting any still-open framework components first. */\n destroy(): void {\n this.mounted.forEach((unmount) => unmount());\n this.mounted.clear();\n this.host?.remove();\n this.host = null;\n this.shadow = null;\n }\n\n private ensureShadow(): ShadowRoot {\n if (this.shadow) return this.shadow;\n const host = document.createElement(\"div\");\n host.setAttribute(\"data-xenia-ui\", \"\");\n document.body.appendChild(host);\n const shadow = host.attachShadow({ mode: \"open\" });\n shadow.appendChild(this.styleEl());\n this.host = host;\n this.shadow = shadow;\n return shadow;\n }\n\n private styleEl(): HTMLStyleElement {\n const style = document.createElement(\"style\");\n style.textContent = this.messageStyles\n ? `${STYLES}\\n${this.messageStyles}`\n : STYLES;\n return style;\n }\n\n private renderMessage(\n action: Extract<XeniaAction, { type: MessagePlacement }>,\n ): boolean {\n // A framework-native component (if registered) renders directly into the container — it owns\n // the card markup entirely, same precedence as per-action `html`. Falls through to the\n // string-based path (messageTemplate, else the built-in card) otherwise.\n const useComponent = action.html === undefined && !!this.messageComponent;\n\n // Inline messages render into a host-page slot; others into the shadow overlay.\n if (action.type === \"inline\") {\n if (!action.target) return false;\n const el = resolveTarget(action.target);\n if (!el) return false;\n this.unmount(el);\n if (useComponent) {\n el.innerHTML = \"\";\n this.mountComponent(el, action, \"inline\", () => this.unmount(el));\n } else {\n el.innerHTML = this.cardHtml(action, \"inline\");\n this.wireCard(el, action);\n }\n return true;\n }\n\n const shadow = this.ensureShadow();\n const wrap = document.createElement(\"div\");\n const posClass = this.positionClass(action.type, action.position);\n // Custom HTML \"fully replaces the default card design\" (incl. its own backdrop, if any) — so\n // the SDK's own modal backdrop is suppressed when custom HTML is provided, to avoid stacking\n // two dark overlays (the SDK's + the pasted markup's own) into one much-darker-than-intended one.\n const customBgClass = action.html !== undefined ? \" xenia-custom-bg\" : \"\";\n // Marketer-set window-design override (Content Studio's spin-wheel editor) — see WidgetStyle.\n // Mirrors xenia-custom-bg's own transparent-backdrop mechanism; a no-op for placements with no\n // backdrop CSS to begin with (popup/banner), so this is safe to apply regardless of `type`.\n const noOverlayClass = action.style?.hideOverlay ? \" xenia-no-overlay\" : \"\";\n wrap.className = `xenia-msg xenia-${action.type}${posClass ? ` ${posClass}` : \"\"}${customBgClass}${noOverlayClass}`;\n shadow.appendChild(wrap);\n\n const dismiss = () => {\n this.unmount(wrap);\n wrap.remove();\n };\n\n if (useComponent) {\n this.mountComponent(wrap, action, action.type, dismiss);\n } else {\n wrap.innerHTML = this.cardHtml(action, action.type);\n this.wireCard(wrap, action, dismiss);\n }\n\n if (action.dismissAfterMs && action.dismissAfterMs > 0) {\n const timer = setTimeout(dismiss, action.dismissAfterMs);\n // A visitor actively engaging with the widget (clicking anywhere in it, or focusing an\n // input — e.g. mid-way through a capture form) should never have it yanked away under them\n // by a stale timer that has no idea they're still using it. Either signal cancels for good;\n // `once: true` on both means whichever fires first tears itself down and the other stays a\n // harmless no-op listener that self-removes on its own next trigger.\n const cancelAutoDismiss = () => clearTimeout(timer);\n wrap.addEventListener(\"click\", cancelAutoDismiss, { once: true });\n wrap.addEventListener(\"focusin\", cancelAutoDismiss, { once: true });\n }\n return true;\n }\n\n /** Mount a registered `messageComponent` into `container` and remember how to unmount it. */\n private mountComponent(\n container: Element,\n action: Extract<XeniaAction, { type: MessagePlacement }>,\n variant: MessagePlacement,\n close: () => void,\n ): void {\n if (!this.messageComponent) return;\n const ctx: MessageMountContext = {\n action,\n variant,\n close,\n fireCta: () => {\n if (action.cta?.event) this.onCta?.(action.cta.event, action.cta);\n if (action.cta?.url) window.location.assign(action.cta.url);\n close();\n },\n };\n // `container` is a plain DOM `Element` here (it may come from a CSS-selector-resolved\n // `data-xenia-slot`, not just SDK-created wrapper divs) — HTMLElement covers every real target.\n const unmount = this.messageComponent(container as HTMLElement, ctx);\n if (unmount) this.mounted.set(container, unmount);\n }\n\n /** Unmount a previously-mounted component for `container`, if any. */\n private unmount(container: Element): void {\n const unmount = this.mounted.get(container);\n if (!unmount) return;\n unmount();\n this.mounted.delete(container);\n }\n\n /**\n * Resolves the anchor CSS class for banner/popup, defaulting to the SDK's\n * original fixed placement (popup: bottom-right; banner: bottom) when no\n * position is given, so actions built before `position` existed still\n * render exactly as they always have. modal/inline have no anchor class.\n */\n private positionClass(\n type: MessagePlacement,\n position?: MessagePosition,\n ): string {\n if (type === \"popup\") {\n const pos =\n position === \"top-left\" ||\n position === \"top-right\" ||\n position === \"bottom-left\"\n ? position\n : \"bottom-right\";\n return `xenia-pos-${pos}`;\n }\n if (type === \"banner\") {\n return `xenia-pos-${position === \"top\" ? \"top\" : \"bottom\"}`;\n }\n return \"\";\n }\n\n private cardHtml(\n action: Extract<XeniaAction, { type: MessagePlacement }>,\n variant: MessagePlacement,\n ): string {\n // A dispatchable widgetType (spin-wheel) owns its own markup entirely — the\n // existing built-in card path below is untouched for standard/custom/undefined.\n const widget = action.widgetType ? WIDGET_RENDERERS[action.widgetType] : undefined;\n if (widget) return widget.html(action, variant);\n\n if (action.html !== undefined) return wrapCustomHtml(action.html, variant);\n if (this.messageTemplate) {\n const ctx: MessageRenderContext = {\n action,\n variant,\n escapeHtml,\n escapeAttr,\n };\n return this.messageTemplate(ctx);\n }\n const img = action.imageUrl\n ? `<img class=\"xenia-img\" src=\"${escapeAttr(action.imageUrl)}\" alt=\"\" />`\n : \"\";\n const title = action.title\n ? `<div class=\"xenia-title\">${escapeHtml(action.title)}</div>`\n : \"\";\n const msg = action.message\n ? `<div class=\"xenia-body\">${escapeHtml(action.message)}</div>`\n : \"\";\n const cta = action.cta\n ? `<button class=\"xenia-cta\" type=\"button\">${escapeHtml(action.cta.label)}</button>`\n : \"\";\n const close =\n variant === \"inline\"\n ? \"\"\n : `<button class=\"xenia-close\" type=\"button\" aria-label=\"Close\">×</button>`;\n return `<div class=\"xenia-card\">${close}${img}<div class=\"xenia-content\">${title}${msg}${cta}</div></div>`;\n }\n\n private wireCard(\n root: Element | ShadowRoot,\n action: Extract<XeniaAction, { type: MessagePlacement }>,\n dismiss?: () => void,\n ): void {\n // A dispatchable widgetType (spin-wheel) owns its own interactivity entirely —\n // including its own close wiring (via ctx.dismiss) — and skips the generic wiring below,\n // which assumes marketer-pasted/built-in card markup, not the SDK's own generated UI.\n const widget = action.widgetType ? WIDGET_RENDERERS[action.widgetType] : undefined;\n if (widget) {\n widget.wire(root, action, this.buildWidgetCtx(action, dismiss));\n return;\n }\n\n // Custom HTML close/backdrop elements commonly carry their own inline `onclick` reaching for\n // `document.getElementById(...)` — pasted from AI tools or templates built as standalone pages\n // that assume full document access. See `wireCloseAffordances` for why this recognizes them by\n // convention instead of trusting that script.\n wireCloseAffordances(root, dismiss);\n\n const ctaBtn = root.querySelector(\".xenia-cta, [data-xenia-cta]\");\n if (ctaBtn && action.cta) {\n ctaBtn.addEventListener(\"click\", () => {\n if (action.cta?.event) this.onCta?.(action.cta.event, action.cta);\n if (action.cta?.url) window.location.assign(action.cta.url);\n dismiss?.();\n });\n }\n\n // NEW: shared field-collection/submit wiring (every standard/custom widget, including plain\n // popups) — the fix for the original loophole where a popup's real <input> + submit button\n // rendered but submitting it did nothing. A no-op when the action has no `formSubmit` config.\n wireFormSubmit(root, action, this.buildWidgetCtx(action, dismiss));\n }\n\n /** Build the imperative hooks (`dismiss`/`fireCta`/`submitWidgetForm`) handed to a widget's `wire()`. */\n private buildWidgetCtx(\n action: Extract<XeniaAction, { type: MessagePlacement }>,\n dismiss?: () => void,\n ): WidgetWireContext {\n // One idempotency key per rendered widget instance, reused across EVERY submit attempt for\n // this interaction (including a retry after a failed submit) — never regenerated mid-\n // interaction, so a network retry can't double-fire a journey or double-resolve a prize.\n const idempotencyKey = generateUlid();\n return {\n dismiss,\n fireCta: () => {\n if (action.cta?.event) this.onCta?.(action.cta.event, action.cta);\n if (action.cta?.url) window.location.assign(action.cta.url);\n dismiss?.();\n },\n submitWidgetForm: (fields) => {\n if (!action.formSubmit || !this.submitWidgetFormFn) {\n return Promise.reject(\n new Error(\n \"xenia: this action has no formSubmit config, or no submitWidgetForm handler is wired (construct the ActionRenderer via XeniaClient to get one)\",\n ),\n );\n }\n return this.submitWidgetFormFn(action.formSubmit, fields, { idempotencyKey });\n },\n };\n }\n}\n\n/**\n * Xenia is authored by non-technical marketers who paste HTML/CSS from AI tools or templates\n * built as standalone widgets — those commonly declare `position: fixed` with their own\n * top/right/bottom/left on their own top-level element, assuming THEY own placement. For\n * banner/popup/inline, viewport placement is already owned by the SDK's outer wrapper (the\n * Position selector's `xenia-pos-*` class) — a nested `position: fixed` element ignores its\n * ancestor's positioning entirely, so the pasted markup's own placement silently wins over\n * whatever the marketer picked in the Position dropdown.\n *\n * modal is deliberately exempt: it's always full-viewport/centered (no anchor to conflict with),\n * and modal templates commonly nest a `width:100%;height:100%` backdrop a level or two below\n * their own `position:fixed` top-level wrapper. Forcing that wrapper out of the fixed/positioned\n * chain would leave the backdrop's percentage sizing resolving against a content-sized ancestor\n * instead of the viewport, shrinking it down to the card's own bounding box — a worse visual bug\n * than the one this is meant to fix. The double-backdrop problem for modal (its own + the SDK's)\n * is solved separately, by suppressing the SDK's own backdrop (see xenia-custom-bg).\n *\n * Wraps custom HTML in a container so dismiss heuristics have a stable place to query, and — for\n * banner/popup/inline only — forces `position: static` (`!important`) on its direct top-level\n * children, neutralizing any such declarations so the SDK's wrapper is always the single source of\n * truth for where the message sits. The style travels inline with the fragment (not the shared\n * stylesheet) so this works whether the fragment lands in the shadow-DOM message wrapper or a\n * host-page slot (`inline` placement). Nested/descendant elements are untouched either way — only\n * top-level offsets are ever reset.\n */\nfunction wrapCustomHtml(html: string, variant: MessagePlacement): string {\n if (variant === \"modal\") {\n return `<div class=\"xenia-custom-html\">${html}</div>`;\n }\n return (\n `<div class=\"xenia-custom-html\">` +\n `<style>.xenia-custom-html{position:relative}` +\n `.xenia-custom-html>*{position:static!important;inset:auto!important;` +\n `top:auto!important;right:auto!important;bottom:auto!important;left:auto!important}</style>` +\n `${html}</div>`\n );\n}\n\nfunction escapeHtml(s: string): string {\n return s.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n}\n\nfunction escapeAttr(s: string): string {\n return escapeHtml(s).replace(/\"/g, \"&quot;\");\n}\n\n/**\n * Minimal, self-contained styling for message UI (isolated in shadow DOM).\n *\n * Every visually-meaningful value is a `var(--xenia-*, <fallback>)` so a host page can override\n * it just by declaring the custom property anywhere in its own light-DOM CSS (e.g. on `:root`) —\n * custom properties inherit through the shadow boundary. See CSS_VARIABLES.md for the full list.\n * Deliberately NOT declared as a default anywhere in this stylesheet (not even on `:host`): a\n * direct declaration here would out-rank an inherited value from the host page and silently\n * defeat the override, so the fallback in each `var()` call is the only default.\n */\nconst STYLES = `\n:host { all: initial; }\n.xenia-msg { position: fixed; z-index: var(--xenia-z-index, 2147483000);\n font-family: var(--xenia-font-family, system-ui, sans-serif); }\n.xenia-banner { left: 0; right: 0; }\n.xenia-banner.xenia-pos-top { top: 0; }\n.xenia-banner.xenia-pos-bottom { bottom: 0; }\n.xenia-popup { max-width: var(--xenia-popup-max-width, 360px); }\n.xenia-popup.xenia-pos-top-left { top: var(--xenia-popup-offset, 16px); left: var(--xenia-popup-offset, 16px); }\n.xenia-popup.xenia-pos-top-right { top: var(--xenia-popup-offset, 16px); right: var(--xenia-popup-offset, 16px); }\n.xenia-popup.xenia-pos-bottom-left { bottom: var(--xenia-popup-offset, 16px); left: var(--xenia-popup-offset, 16px); }\n.xenia-popup.xenia-pos-bottom-right { bottom: var(--xenia-popup-offset, 16px); right: var(--xenia-popup-offset, 16px); }\n.xenia-modal { inset: 0; display: flex; align-items: center; justify-content: center;\n background: var(--xenia-modal-backdrop, rgba(0,0,0,.12)); }\n.xenia-modal.xenia-custom-bg { background: transparent; }\n.xenia-modal.xenia-no-overlay { background: transparent; }\n.xenia-card { position: relative; background: var(--xenia-card-bg, #fff); color: var(--xenia-card-color, #111);\n border-radius: var(--xenia-card-radius, 12px); box-shadow: var(--xenia-card-shadow, 0 10px 40px rgba(0,0,0,.18));\n padding: var(--xenia-card-padding, 16px 18px); display: flex; gap: var(--xenia-card-gap, 12px);\n align-items: center; }\n.xenia-banner .xenia-card { border-radius: var(--xenia-banner-card-radius, 0); justify-content: center; }\n.xenia-modal .xenia-card { max-width: var(--xenia-modal-max-width, 440px); width: calc(100% - 32px); }\n.xenia-card.xenia-widget { flex-direction: column; align-items: center; text-align: center; }\n.xenia-img { width: var(--xenia-img-size, 56px); height: var(--xenia-img-size, 56px); object-fit: cover;\n border-radius: var(--xenia-img-radius, 8px); }\n.xenia-title { font-weight: var(--xenia-title-weight, 600); font-size: var(--xenia-title-size, 15px);\n margin-bottom: var(--xenia-title-gap, 2px); }\n.xenia-body { font-size: var(--xenia-body-size, 14px); line-height: var(--xenia-body-line-height, 1.4);\n color: var(--xenia-body-color, #444); }\n.xenia-cta { margin-top: 10px; background: var(--xenia-cta-bg, #111); color: var(--xenia-cta-color, #fff);\n border: 0; border-radius: var(--xenia-cta-radius, 8px); padding: var(--xenia-cta-padding, 8px 14px);\n font-size: var(--xenia-cta-size, 14px); cursor: pointer; }\n.xenia-close { position: absolute; top: 6px; right: 8px; background: none; border: 0;\n font-size: var(--xenia-close-size, 20px); line-height: 1; cursor: pointer; color: var(--xenia-close-color, #999); }\n.xenia-wheel-dial { transform-box: fill-box; transform-origin: center; }\n.xenia-wheel-hub { fill: var(--xenia-wheel-pointer-color, #111); }\n.xenia-wheel-wrap { position: relative; display: inline-block; }\n.xenia-wheel-pointer { position: absolute; top: -6px; left: 50%; transform: translateX(-50%);\n width: 0; height: 0; border-left: 9px solid transparent; border-right: 9px solid transparent;\n border-top: 14px solid var(--xenia-wheel-pointer-color, #111); pointer-events: none; }\n.xenia-wheel-spin { margin-top: 10px; background: var(--xenia-cta-bg, #111); color: var(--xenia-cta-color, #fff);\n border: 0; border-radius: var(--xenia-cta-radius, 8px); padding: var(--xenia-cta-padding, 8px 14px);\n font-size: var(--xenia-cta-size, 14px); font-family: inherit; cursor: pointer; }\n.xenia-wheel-spin:disabled { opacity: 0.6; cursor: default; }\n/* The spinner face and the win/loss screens are siblings toggled via the 'hidden' attribute —\n during crossFadeReveal's ~320ms crossfade, BOTH the outgoing and incoming screen are visible\n (not hidden) at once, so without this they'd stack in normal block flow and roughly double\n this box's height for that window. Since .xenia-modal's flexbox re-centers on every height\n change, that briefly-doubled height yanks the whole card to a new position with ZERO\n animation — right before the scale-down transition starts animating smoothly from that\n already-jumped spot, reading as \"not scaling from center\". Grid-stacking every child into the\n same cell (sized to the tallest non-hidden one) makes the outgoing/incoming screens overlay in\n place instead of stacking, so there is no discrete height jump to correct for. */\n.xenia-spin-wheel { display: grid; }\n.xenia-spin-wheel > * { grid-area: 1 / 1; }\n/* No animation/transform here — spin-wheel's win/loss screens are ALWAYS full\n custom HTML now (winHtml/lossHtml), never this class's own generated icon/title/prize/cta\n content (those sub-classes below are unreachable dead CSS, kept only for backwards-compat with\n any already-saved artifact that might still reference them). A transform on THIS wrapper\n would make it the CSS containing block for any fixed/absolute-positioned descendant the\n author's own HTML uses (a real, common case — a \"full-screen overlay\" win/loss design) — the\n fixed child would then size/position itself relative to this wrapper's own small, in-flow,\n often off-center box instead of the true browser viewport, visibly popping in from/toward\n whatever corner the wrapper happens to sit at instead of scaling from the real screen center.\n spin-wheel.ts's crossFadeReveal owns the actual reveal transition (applied to the author's own\n top-level element, never this wrapper) — this class stays a bare, transform-free layout box. */\n.xenia-widget-result { display: flex; flex-direction: column; align-items: center; gap: 4px;\n padding: 8px 4px 2px; text-align: center; }\n.xenia-widget-result[hidden] { display: none; }\n.xenia-widget-result-icon { font-size: 40px; line-height: 1; }\n.xenia-widget-result-title { font-weight: var(--xenia-title-weight, 700); font-size: var(--xenia-title-size, 17px); }\n.xenia-widget-result-prize { font-weight: 600; font-size: 15px; color: var(--xenia-cta-bg, #111);\n background: var(--xenia-result-prize-bg, rgba(0,0,0,.06)); border-radius: var(--xenia-cta-radius, 8px);\n padding: 6px 14px; }\n.xenia-widget-result-cta { margin-top: 8px; background: var(--xenia-cta-bg, #111); color: var(--xenia-cta-color, #fff);\n border: 0; border-radius: var(--xenia-cta-radius, 8px); padding: var(--xenia-cta-padding, 8px 14px);\n font-size: var(--xenia-cta-size, 14px); font-family: inherit; cursor: pointer; }\n`;\n","import { compact, XeniaApi } from \"../core/api\";\nimport { consentCookie } from \"../core/cookie-names\";\nimport { buildEventPayload } from \"../core/event-payload\";\nimport { isBrowser } from \"../core/http-client\";\nimport { generateUlid, toEventId } from \"../core/id\";\nimport { personalizeContent, personalizePage } from \"../core/personalize-content\";\nimport type { EntryResolver, PageRef, PagePersonalizeOptions, PersonalizeContentResult } from \"../core/personalize-content\";\nimport {\n LocalStorageResponseStore,\n MemoryResponseStore,\n type ResponseStore,\n} from \"../core/response-store\";\nimport type {\n AnalyticsEventName,\n ConsentState,\n JsonValue,\n MessageComponentRenderer,\n MessageCta,\n MessageTemplateFn,\n ResolveBatchItem,\n ResolveBatchResult,\n ResolveOptions,\n ResolveResult,\n TrackOptions,\n WebhookResponse,\n WidgetFormSubmit,\n WidgetSubmitResponse,\n XeniaAction,\n XeniaConfig,\n XeniaEvent,\n} from \"../core/types\";\nimport { AnalyticsQueue } from \"./analytics-queue\";\nimport { AutoTracker } from \"./auto-track\";\nimport { Identity } from \"./identity\";\nimport { ActionRenderer, hideContent, showContent, swapContent } from \"./renderer\";\n\n/** Options controlling automatic behaviors. */\nexport interface XeniaClientOptions extends XeniaConfig {\n /** Enable declarative `data-xenia` auto-tracking. Default true. */\n autoTrack?: boolean;\n /** Throttle window (ms) for auto-tracked events. Default 1000. */\n throttleMs?: number;\n /** Viewport options for `view-port` interactions. */\n viewport?: { threshold?: number; rootMargin?: string; triggerOnce?: boolean };\n /** Automatically apply `xeniaActions` from webhook responses. Default true. */\n autoApplyActions?: boolean;\n /** Persist saved webhook responses to localStorage. Default true. */\n persistResponses?: boolean;\n /**\n * Replace the SDK's built-in card markup for every banner/popup/modal/inline\n * action that doesn't specify its own `html`. Applies system-wide.\n */\n messageTemplate?: MessageTemplateFn;\n /** Extra CSS appended to the message overlay's stylesheet (shadow-scoped). */\n messageStyles?: string;\n /**\n * Render a framework-native component (React, Vue, Svelte, …) for every\n * banner/popup/modal/inline action that doesn't specify its own `html`,\n * instead of an HTML string. Takes priority over `messageTemplate` when both\n * are set. See `reactMessageComponent()` in `/client/react` for the React\n * adapter.\n */\n messageComponent?: MessageComponentRenderer;\n /**\n * Honor `navigator.doNotTrack`/`globalPrivacyControl` by suppressing\n * analytics-only `track()` calls entirely (events aren't even queued). Journey\n * triggers (`track(..., { trigger: true })`) always fire. Default true.\n */\n respectDnt?: boolean;\n}\n\n/** Events emitted by the client for observability. */\nexport type ClientEvent = \"event\" | \"response\" | \"actions\" | \"error\" | \"identify\";\ntype Listener = (payload: unknown) => void;\n\n/**\n * High-level browser client. One instance wires identity, auto-tracking, and\n * webhook request/response with action rendering.\n */\nexport class XeniaClient {\n readonly api: XeniaApi;\n readonly identity: Identity;\n readonly responses: ResponseStore;\n\n private readonly options: XeniaClientOptions;\n private readonly renderer: ActionRenderer;\n private readonly analyticsQueue: AnalyticsQueue;\n private tracker: AutoTracker | null = null;\n /** The in-flight (or finished) boot; shared so concurrent `init()` calls start one tracker. */\n private booting: Promise<void> | null = null;\n /** Bumped by `destroy()`, so a boot still waiting on the device id knows to stop. */\n private generation = 0;\n private consentState: ConsentState;\n private readonly listeners = new Map<ClientEvent, Set<Listener>>();\n\n constructor(options: XeniaClientOptions) {\n this.options = options;\n const prefix = options.prefix ?? \"xenia\";\n this.identity = new Identity(prefix, options.visitorCookie ?? true);\n // Seed the SDK-owned visitor id when supplied (persisted locally only — no\n // network call, unlike the public identify()). The auto-resolved device id\n // is still the fallback anchor when this isn't set.\n if (options.visitorId) this.identity.identify(options.visitorId);\n // XeniaApi resolves/caches config.token / config.getToken internally.\n this.api = new XeniaApi(options);\n this.responses =\n options.persistResponses === false || !isBrowser()\n ? new MemoryResponseStore()\n : new LocalStorageResponseStore(prefix);\n this.renderer = new ActionRenderer((event, cta) => this.onCtaEvent(event, cta), {\n messageTemplate: options.messageTemplate,\n messageStyles: options.messageStyles,\n messageComponent: options.messageComponent,\n submitWidgetForm: (submit, fields, subOpts) =>\n this.submitWidgetForm(submit, fields, subOpts),\n });\n this.consentState = { ...options.consent };\n this.analyticsQueue = new AnalyticsQueue({\n debug: options.debug,\n // Stamp the *current* consent state at send time (not enqueue time) — an\n // event queued before consent was granted only ever gets flushed after\n // it's granted (gated by `analyticsAllowed()`), so by send time consent\n // has necessarily changed and the event's own snapshot would be stale.\n send: (events, opts) =>\n this.api.sendEvents(\n events.map((e) => ({ ...e, consent: this.consentState })),\n opts,\n ),\n });\n }\n\n /** Boot the client: resolve device id and start auto-tracking. Idempotent. */\n init(): Promise<void> {\n if (!isBrowser()) return Promise.resolve();\n return (this.booting ??= this.boot());\n }\n\n private async boot(): Promise<void> {\n const generation = this.generation;\n await this.identity.resolveDeviceId();\n // destroy() ran while we waited (React StrictMode's mount→unmount→mount, or a re-init):\n // starting the tracker now would leak one that nothing can stop, double-sending every click.\n if (generation !== this.generation) return;\n\n if (this.analyticsAllowed()) this.analyticsQueue.start();\n\n if (this.options.autoTrack !== false) {\n this.tracker = new AutoTracker({\n prefix: this.options.prefix ?? \"xenia\",\n throttleMs: this.options.throttleMs ?? 1000,\n viewport: {\n threshold: this.options.viewport?.threshold ?? 0.5,\n rootMargin: this.options.viewport?.rootMargin,\n triggerOnce: this.options.viewport?.triggerOnce ?? true,\n },\n // Declarative `data-xenia` elements fire journey triggers (immediate).\n fire: (eventId, interaction) =>\n this.track(eventId, { interactionType: interaction }, { trigger: true }),\n // `[data-xenia-slot]` elements fire analytics-only personalization events.\n fireSlot: (interaction, meta) => {\n this.track(\n \"customEvent\",\n {\n customEventName:\n interaction === \"impression\"\n ? \"personalization_impression\"\n : \"personalization_click\",\n contentKey: meta.contentKey,\n contentEntryId: meta.contentEntryId ?? null,\n baseEntryId: meta.baseEntryId ?? null,\n },\n { trigger: false },\n );\n },\n });\n this.tracker.start();\n }\n }\n\n /** Tear down listeners, observers, and injected UI. */\n destroy(): void {\n this.tracker?.stop();\n this.tracker = null;\n this.renderer.destroy();\n this.analyticsQueue.stop();\n this.booting = null;\n this.generation++;\n }\n\n // ── Identity ───────────────────────────────────────────────────────────────\n\n /**\n * Persist a visitor id, attached to every subsequent event, and bind it to\n * a known user server-side (`POST /api/events/v1/identify`, fire-and-\n * forget — resolves to an `\"identify\"` client event carrying `personId`).\n *\n * `extra.customerId`/`extra.email`, when supplied, are also persisted\n * ambiently (like the visitor id) so they ride on every later `resolve()`\n * call automatically — part of the SDK-provided-fields parity list.\n */\n identify(visitorId: string, extra?: { customerId?: string; email?: string }): void {\n this.identity.identify(visitorId);\n if (extra?.customerId !== undefined) this.identity.setCustomerId(extra.customerId);\n if (extra?.email !== undefined) this.identity.setEmail(extra.email);\n void this.api\n .identify({ xeniaVisitorId: visitorId, userId: extra?.customerId, email: extra?.email })\n .then((res) => this.emit(\"identify\", res))\n .catch((err: unknown) => this.emitError(err));\n }\n\n /** Override the customer-journey UUID (else derived from utm_id). */\n setJourneyId(id: string | null): void {\n this.identity.setJourneyId(id);\n }\n\n // ── Events ─────────────────────────────────────────────────────────────────\n\n /**\n * Send a unified event to `POST /api/events/v1`. Identity, UTM, page context,\n * and journey attribution are attached automatically. Delivery depends on\n * `opts.trigger`:\n *\n * - `trigger: true` — **journey trigger**: sent immediately (journeys are\n * latency-sensitive) and **bypasses client-side consent/DNT gating** (the\n * journey must fire; the backend still consent-gates the analytics half).\n * - `trigger: false` (default) — **analytics only**: enqueued to the batching\n * {@link AnalyticsQueue}, dropped entirely when Do Not Track/GPC is honored,\n * and held (not sent) until `consent({ analytics: true })` is granted.\n *\n * Pass `opts.eventId` (e.g. `\"ord-1001\"`) as a stable dedup key to keep the\n * analytics/conversion side idempotent; otherwise a ULID is generated.\n */\n track(\n eventName: AnalyticsEventName,\n props?: Record<string, JsonValue | undefined>,\n opts: TrackOptions = {},\n ): void {\n if (!isBrowser()) return;\n const trigger = opts.trigger === true;\n // Analytics-only events honor DNT/GPC; journey triggers always fire.\n if (!trigger && this.dntBlocked()) return;\n\n const event = this.buildEvent(eventName, props, opts);\n this.emit(\"event\", { eventName, event });\n\n if (trigger) {\n // Immediate, ungated send — reuses the queue's 4xx-drop/transient-requeue.\n void this.analyticsQueue.sendImmediate(event).catch((err: unknown) => this.emitError(err));\n } else {\n this.analyticsQueue.enqueue(event);\n if (this.analyticsAllowed()) this.analyticsQueue.start();\n }\n }\n\n /** Assemble a {@link XeniaEvent} from ambient identity/context + overrides. */\n private buildEvent(\n eventName: AnalyticsEventName,\n props: Record<string, JsonValue | undefined> | undefined,\n opts: TrackOptions,\n ): XeniaEvent {\n const ctx = this.identity.collectContext();\n let timezone: string | undefined;\n try {\n timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n } catch {\n /* ignore */\n }\n\n return {\n eventName,\n eventId: opts.eventId ? toEventId(opts.eventId) : generateUlid(),\n eventVersion: 1,\n occurredAtMs: Date.now(),\n source: \"xenia-js-sdk\",\n identity: {\n sessionId: this.identity.getSessionId(),\n // Caller extras (email/userId/phone/…) merge in here…\n ...opts.identity,\n // …but `xeniaVisitorId` is SDK-owned and set LAST, so a caller-supplied\n // value is always ignored (defence-in-depth alongside the CallerIdentity\n // type, which omits it). The anchor: the visitor id from `identify()` /\n // `config.visitorId` when set, else the auto-resolved device id — so an\n // anonymous event still carries an anchor and isn't dropped as\n // `missing_identity`. (The backend has no `deviceId` field; the device\n // id rides here as the visitor id instead.)\n xeniaVisitorId: ctx.visitorId ?? this.identity.getDeviceId() ?? undefined,\n },\n context: {\n pagePath: ctx.path,\n referrer: ctx.referrer,\n userAgent: navigator.userAgent,\n locale: navigator.language,\n timezone,\n journeyId: this.identity.getJourneyId() ?? undefined,\n utmSource: ctx.utmSource,\n utmMedium: ctx.utmMedium,\n utmCampaign: ctx.utmCampaign,\n utmContent: ctx.utmContent,\n ...opts.context,\n },\n properties: this.withUtmId(props, ctx.utmId),\n trigger: opts.trigger === true ? true : undefined,\n // `consent` is stamped fresh at send time by the queue's `send` wrapper\n // (see constructor) — not set here, since it may still change between\n // enqueue and flush (e.g. queued before consent is granted).\n };\n }\n\n /**\n * Ensure a captured journey-link `utm_id` rides in `properties.utm_id`.\n *\n * The backend attributes conversions in tiers: a conversion carrying\n * `properties.utm_id` (= the `customer_journey.uuid` from the link the\n * shopper clicked) is tied to that *exact* enrollment — **deterministic**\n * attribution — before any last-touch identity guess. `utm_id` is captured\n * from the landing URL and persisted for the session by {@link Identity}, so\n * a purchase fired pages later still credits the right journey without the\n * developer threading it through by hand. Never clobbers a developer-supplied\n * `utm_id`/`utmId`; a no-op when no journey-link `utm_id` was captured.\n */\n private withUtmId(\n props: Record<string, JsonValue | undefined> | undefined,\n utmId: string | undefined,\n ): Record<string, JsonValue | undefined> | undefined {\n if (!utmId) return props;\n if (props && (props.utm_id !== undefined || props.utmId !== undefined)) return props;\n return { ...props, utm_id: utmId };\n }\n\n // ── Personalization (REST resolve) ─────────────────────────────────────────\n\n /**\n * Resolve in-entry content personalization for one content key\n * (`POST /api/personalization/resolve`). Requires a configured SDK token\n * (`token`/`getToken`) — resolve is auth-required (unlike public event ingest).\n * With `merge: true` the returned `content` is server-spliced.\n */\n async resolve(contentKey: string, opts?: ResolveOptions): Promise<ResolveResult> {\n return this.api.resolve(contentKey, this.withVisitor(opts));\n }\n\n /** Resolve several content keys in one round-trip (`POST /api/personalization/resolve-batch`). */\n async resolveBatch(\n items: ResolveBatchItem[],\n opts?: ResolveOptions,\n ): Promise<ResolveBatchResult[]> {\n return this.api.resolveBatch(items, this.withVisitor(opts));\n }\n\n /**\n * Personalize a fetched CMS page: static swaps are applied from the payload, runtime targets are\n * decided by Xenia in one `resolve-entries` call per nesting level, and replacements are loaded\n * through `opts.cms` (e.g. `contentfulAdapter(...)`). Never throws — anything undecided within\n * `opts.timeoutMs` keeps its base content.\n */\n async personalizeContent<T>(page: T, opts: PagePersonalizeOptions): Promise<PersonalizeContentResult<T>> {\n return personalizeContent(page, { ...opts, resolve: this.entryResolver(opts) });\n }\n\n /**\n * Fetch a page through `opts.cms` and personalize it — the app passes only the page's identity\n * (entry id, or `{ contentType, fields: { slug } }`). Never throws: a failed fetch is `content:\n * null` with `error`, a missing page `content: null`.\n */\n async personalizePage<T = unknown>(ref: PageRef, opts: PagePersonalizeOptions): Promise<PersonalizeContentResult<T | null>> {\n return personalizePage<T>(ref, { ...opts, resolve: this.entryResolver(opts) });\n }\n\n private entryResolver(opts: PagePersonalizeOptions): EntryResolver {\n const resolveOpts = this.withVisitor({ data: opts.data, locale: opts.locale });\n return async (ids) => (await this.api.resolveEntries(ids, resolveOpts)).decisions ?? [];\n }\n\n /** The SDK-owned visitor anchor: the `identify()`/`config.visitorId` id, else the device id. */\n private resolveVisitorId(): string | undefined {\n return this.identity.getVisitorId() ?? this.identity.getDeviceId() ?? undefined;\n }\n\n /**\n * Stamp the full set of SDK-provided fields into the resolve `data` —\n * `path`, `query`, `deviceId`, `visitorId`, `customerId`, `email`, `url`,\n * `referrer`, and the five `utm*` fields — the same field-name/type parity\n * the webhook trigger's \"SDK-provided fields\" already promises, now native\n * (always attached, no marketer toggle) for the Personalization Resolve\n * trigger too. Plus the reserved `_xenia_vid` key the backend reads for\n * holdout/exposure bucketing. All of these are spread LAST (after the\n * caller's own `data`) so none can be overridden per call — the same\n * override-protection guarantee `_xenia_vid` alone used to have, now\n * widened to the full set. A no-op (returns `opts` unchanged) when nothing\n * is resolvable yet (e.g. called before `init()` on a fresh visit with no\n * page context available).\n */\n private withVisitor(opts?: ResolveOptions): ResolveOptions | undefined {\n const ctx = this.identity.collectContext();\n const vid = this.resolveVisitorId();\n const sdkFields = compact({\n path: ctx.path,\n query: ctx.query as JsonValue | undefined,\n deviceId: this.identity.getDeviceId() ?? undefined,\n visitorId: vid,\n customerId: this.identity.getCustomerId() ?? undefined,\n email: this.identity.getEmail() ?? undefined,\n url: ctx.url,\n referrer: ctx.referrer,\n utmSource: ctx.utmSource,\n utmMedium: ctx.utmMedium,\n utmCampaign: ctx.utmCampaign,\n utmContent: ctx.utmContent,\n utmId: ctx.utmId,\n });\n if (vid) sdkFields._xenia_vid = vid;\n if (Object.keys(sdkFields).length === 0) return opts;\n return { ...opts, data: { ...(opts?.data ?? {}), ...sdkFields } };\n }\n\n private dntBlocked(): boolean {\n if (this.options.respectDnt === false) return false;\n try {\n const nav = navigator as Navigator & { globalPrivacyControl?: boolean };\n const dnt = navigator.doNotTrack ?? (window as unknown as { doNotTrack?: string }).doNotTrack;\n if (dnt === \"1\" || dnt === \"yes\") return true;\n if (nav.globalPrivacyControl === true) return true;\n } catch {\n /* ignore */\n }\n return false;\n }\n\n private analyticsAllowed(): boolean {\n return this.consentState.analytics === true;\n }\n\n // ── Webhook request/response ─────────────────────────────────────────────────\n\n /**\n * Send a webhook request to a journey trigger and await its synchronous\n * response (from the `webhook-response` node). The response is saved to the\n * response store (keyed by `triggerId`) and any `xeniaActions` are applied.\n */\n async request(\n triggerId: string,\n data?: Record<string, JsonValue | undefined>,\n opts?: { apply?: boolean; method?: \"GET\" | \"POST\" },\n ): Promise<WebhookResponse> {\n const ctx = this.identity.collectContext();\n const body = buildEventPayload({\n eventId: triggerId,\n journeyId: this.identity.getJourneyId() ?? undefined,\n // SDK-owned visitor anchor (identify()/config.visitorId, else device id) —\n // buildEventPayload merges identity last, so a caller `data.visitorId`\n // can't override it. The webhook/`/flow` field maps to xeniaVisitorId.\n identity: {\n deviceId: this.identity.getDeviceId() ?? undefined,\n visitorId: this.resolveVisitorId(),\n },\n context: ctx,\n props: data,\n });\n\n const response = await this.api.webhook(triggerId, body as JsonValue, opts?.method ?? \"POST\");\n this.responses.set(triggerId, response);\n this.emit(\"response\", { triggerId, response });\n\n const apply = opts?.apply ?? this.options.autoApplyActions !== false;\n if (apply && response.actions.length) {\n this.applyActions(response.actions);\n }\n return response;\n }\n\n /** Read the last saved webhook response for a key (triggerId/eventId). */\n getResponse(key: string): WebhookResponse | undefined {\n return this.responses.get(key);\n }\n\n /**\n * Submit a widget's captured form values (standard/custom popup submit, or a spin-wheel/\n * spin-wheel's resolve request) and apply any returned `xeniaActions`, exactly like\n * {@link request}.\n *\n * **Endpoint selection is config-driven, not SDK-decided** (per the cross-repo contract): a\n * `flowRef` (present only when `mode === \"journey\" && !requiresResolve` — the common\n * plain-popup case) bypasses the resolve endpoint entirely and POSTs straight to the existing\n * public `/flow` fast path; otherwise this POSTs to `/widget-submissions` via `bindingRef`. The\n * SDK is agnostic to *why* — it just follows whichever ref field the backend populated.\n *\n * The full ambient-context parity list {@link request}/`withVisitor()` already build\n * (visitorId, deviceId, url, referrer, path, query, `utm*`) rides on every call, plus `fields`\n * and `submit.mode`/the resolved ref, relayed verbatim/uninterpreted — the SDK never branches\n * on `mode`'s value itself, that's server-side.\n *\n * `opts.idempotencyKey` defaults to a freshly generated ULID; pass the SAME key back in on a\n * retried submit of the same interaction so a network retry can't double-fire a journey or\n * double-resolve a prize server-side.\n */\n async submitWidgetForm(\n submit: WidgetFormSubmit,\n fields: Record<string, string>,\n opts?: { idempotencyKey?: string; apply?: boolean },\n ): Promise<WidgetSubmitResponse> {\n const ctx = this.identity.collectContext();\n const idempotencyKey = opts?.idempotencyKey ?? generateUlid();\n const ref = submit.flowRef ?? submit.bindingRef;\n const ambient = {\n visitorId: this.resolveVisitorId(),\n deviceId: this.identity.getDeviceId() ?? undefined,\n idempotencyKey,\n mode: submit.mode,\n ref,\n url: ctx.url,\n referrer: ctx.referrer,\n path: ctx.path,\n query: ctx.query as JsonValue | undefined,\n utmSource: ctx.utmSource,\n utmMedium: ctx.utmMedium,\n utmCampaign: ctx.utmCampaign,\n utmContent: ctx.utmContent,\n utmId: ctx.utmId,\n };\n\n // `/flow` (flowRef) is the pre-existing, generic webhook-trigger endpoint — it templates\n // `{{fieldName}}` against ROOT-level body keys (matching `config.bodyParams`), same as any\n // other webhook caller, so captured fields must be spread flat, NOT nested. `/widget-submissions`\n // (bindingRef) is this feature's own purpose-built endpoint, whose `WidgetSubmissionRequest`\n // DTO reads a real `fields` object — that shape must stay nested.\n const response = submit.flowRef\n ? await this.api.webhook(submit.flowRef, compact({ ...ambient, ...fields }) as JsonValue, \"POST\")\n : await this.api.submitWidget(\n submit.bindingRef ?? \"\",\n compact({ ...ambient, fields: fields as unknown as JsonValue }) as JsonValue,\n );\n\n this.emit(\"response\", { triggerId: ref, response });\n const apply = opts?.apply ?? this.options.autoApplyActions !== false;\n if (apply && response.actions.length) this.applyActions(response.actions);\n return response as WidgetSubmitResponse;\n }\n\n // ── Imperative render helpers ─────────────────────────────────────────────────\n\n swapContent(target: string, content: { html?: string; text?: string }): boolean {\n return swapContent(target, content);\n }\n hideContent(target: string): boolean {\n return hideContent(target);\n }\n showContent(target: string): boolean {\n return showContent(target);\n }\n\n /** Apply an arbitrary list of actions (e.g. from a custom response). */\n applyActions(actions: XeniaAction[]): number {\n const count = this.renderer.apply(actions);\n this.emit(\"actions\", { actions, applied: count });\n return count;\n }\n\n // ── Consent ─────────────────────────────────────────────────────────────────\n\n async consent(state: ConsentState): Promise<void> {\n const wasAllowed = this.analyticsAllowed();\n this.consentState = { ...this.consentState, ...state };\n // Mirror to a cookie so same-origin server code (`getConsent(cookieHeader)`) sees the choice.\n if (isBrowser()) {\n try {\n document.cookie = consentCookie(this.consentState, this.options.prefix);\n } catch {\n /* document.cookie unavailable */\n }\n }\n if (this.analyticsAllowed() && !wasAllowed) {\n this.analyticsQueue.start();\n void this.analyticsQueue.flush();\n } else if (!this.analyticsAllowed() && wasAllowed) {\n this.analyticsQueue.stop();\n }\n\n const vid = this.identity.getVisitorId() ?? this.identity.getDeviceId();\n if (!vid) return;\n try {\n await this.api.consent(vid, state);\n } catch (err) {\n this.emitError(err);\n }\n }\n\n // ── Events / observability ────────────────────────────────────────────────────\n\n on(event: ClientEvent, listener: Listener): () => void {\n const set = this.listeners.get(event) ?? new Set<Listener>();\n set.add(listener);\n this.listeners.set(event, set);\n return () => set.delete(listener);\n }\n\n private emit(event: ClientEvent, payload: unknown): void {\n this.listeners.get(event)?.forEach((l) => {\n try {\n l(payload);\n } catch {\n /* listener errors are the listener's problem */\n }\n });\n }\n\n private emitError(err: unknown): void {\n const error = err instanceof Error ? err : new Error(String(err));\n if (this.options.debug) console.error(\"[xenia]\", error);\n this.emit(\"error\", error);\n }\n\n private onCtaEvent(event: string, cta: MessageCta): void {\n this.track(event, { ctaLabel: cta.label, ctaUrl: cta.url ?? null }, { trigger: true });\n }\n}\n\n/** Create (but do not init) a client. Call `.init()` to start. */\nexport function createXeniaClient(options: XeniaClientOptions): XeniaClient {\n return new XeniaClient(options);\n}\n","import { createContext, useContext } from \"react\";\nimport type { XeniaClient } from \"../xenia-client\";\n\n/** React context carrying the singleton {@link XeniaClient}. */\nexport const XeniaContext = createContext<XeniaClient | null>(null);\n\n/**\n * Access the client provided by `<XeniaProvider>`. Throws when used outside a\n * provider so misconfiguration fails loudly in development.\n */\nexport function useXenia(): XeniaClient {\n const client = useContext(XeniaContext);\n if (!client) {\n throw new Error(\"useXenia must be used within a <XeniaProvider>.\");\n }\n return client;\n}\n","import { useEffect, useMemo, useRef, type ReactNode } from \"react\";\nimport { createXeniaClient, type XeniaClient, type XeniaClientOptions } from \"../xenia-client\";\nimport { XeniaContext } from \"./context\";\n\nexport interface XeniaProviderProps extends XeniaClientOptions {\n children: ReactNode;\n /**\n * Reuse an already-created client instead of creating one from props. Useful\n * for sharing a single client across React and non-React code.\n */\n client?: XeniaClient;\n}\n\n/**\n * Wraps the app and boots a single {@link XeniaClient}. Everything below it can\n * call `useXenia()`, `useTrack()`, `usePersonalization()`, `useWebhook()`, and\n * render the `<XeniaTrack>` / `<XeniaMessage>` components.\n *\n * @example\n * ```tsx\n * <XeniaProvider tenantId=\"t1\" environmentKey=\"prod\">\n * <App />\n * </XeniaProvider>\n * ```\n */\nexport function XeniaProvider({ children, client, ...options }: XeniaProviderProps) {\n // Create once; ignore prop churn (options are read at init).\n const ref = useRef<XeniaClient | null>(null);\n const instance = useMemo(() => {\n if (client) return client;\n if (!ref.current) ref.current = createXeniaClient(options as XeniaClientOptions);\n return ref.current;\n }, [client]);\n\n useEffect(() => {\n void instance.init();\n return () => instance.destroy();\n }, [instance]);\n\n return <XeniaContext.Provider value={instance}>{children}</XeniaContext.Provider>;\n}\n","import type { JsonValue } from \"./types\";\n\n/**\n * A single content swap, as emitted in a webhook-response body's\n * `xeniaContentSwaps` array (the multi-slot personalization analogue of\n * `xeniaActions`). `identifier` is `\"<slotKey>\"` (whole-slot replace) or\n * `\"<slotKey>.<dotted.path>\"` addressing a node inside that slot's JSON\n * (object keys or array indices).\n *\n * NOTE: this field name/shape is a proposed contract, not yet emitted by any\n * journey node — confirm with the Journey Orchestrator (FE/BE) team before\n * relying on it in production.\n */\nexport interface ContentSwap {\n identifier: string;\n replacement: JsonValue;\n /** `\"replace\"` (default) swaps the whole matched node; `\"merge\"` shallow-merges when both sides are objects. */\n mode?: \"replace\" | \"merge\";\n}\n\nfunction isPlainObject(v: JsonValue): v is { [key: string]: JsonValue } {\n return v !== null && typeof v === \"object\" && !Array.isArray(v);\n}\n\nfunction cloneJson<T extends JsonValue>(value: T): T {\n return value === null || typeof value !== \"object\" ? value : (JSON.parse(JSON.stringify(value)) as T);\n}\n\nfunction setAtPath(node: JsonValue, path: string[], value: JsonValue, mode: \"replace\" | \"merge\"): JsonValue {\n if (path.length === 0) {\n if (mode === \"merge\" && isPlainObject(node) && isPlainObject(value)) {\n return { ...node, ...value };\n }\n return value;\n }\n\n const [key, ...rest] = path;\n if (Array.isArray(node)) {\n const index = Number(key);\n if (!Number.isInteger(index) || index < 0 || index >= node.length) return node;\n const next = node.slice();\n next[index] = setAtPath(next[index], rest, value, mode);\n return next;\n }\n if (isPlainObject(node)) {\n if (!(key in node)) return node;\n return { ...node, [key]: setAtPath(node[key], rest, value, mode) };\n }\n return node;\n}\n\n/**\n * Splice `swaps` into a base map of named content slots, recursively at any\n * nesting depth. Defensive by design (mirrors the PHP SDK's personalization\n * client): a swap whose `identifier` doesn't resolve to an existing slot/path\n * is silently ignored rather than thrown — this never fails, it degrades to\n * the base slot value. Slots are deep-cloned; inputs are never mutated.\n */\nexport function spliceSlots(\n slots: Record<string, JsonValue>,\n swaps: ContentSwap[] | undefined,\n): Record<string, JsonValue> {\n const result: Record<string, JsonValue> = {};\n for (const [key, value] of Object.entries(slots)) {\n result[key] = cloneJson(value);\n }\n if (!swaps) return result;\n\n for (const swap of swaps) {\n const [slotKey, ...pathParts] = swap.identifier.split(\".\");\n if (!(slotKey in result)) continue;\n result[slotKey] = setAtPath(result[slotKey], pathParts, swap.replacement, swap.mode ?? \"replace\");\n }\n return result;\n}\n\n/** Extract `xeniaContentSwaps` from a webhook-response body, if present and well-formed. */\nexport function extractContentSwaps(body: JsonValue): ContentSwap[] | undefined {\n if (!isPlainObject(body)) return undefined;\n const swaps = body.xeniaContentSwaps;\n return Array.isArray(swaps) ? (swaps as unknown as ContentSwap[]) : undefined;\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { extractContentSwaps, spliceSlots } from \"../../core/content-splice\";\nimport type {\n AnalyticsEventName,\n JsonValue,\n ResolveBatchItem,\n ResolveBatchResult,\n ResolveResult,\n TrackOptions,\n WebhookResponse,\n} from \"../../core/types\";\nimport { useXenia } from \"./context\";\n\n/**\n * Stable unified `track(eventName, props?, opts?)` bound to the provider's\n * client. `opts.trigger: true` fires a journey trigger immediately (ungated);\n * the default (`false`) records a batched, consent-gated analytics event. Pass\n * `opts.eventId` for an idempotent dedup key.\n */\nexport function useTrack(): (\n eventName: AnalyticsEventName,\n props?: Record<string, JsonValue | undefined>,\n opts?: TrackOptions,\n) => void {\n const xenia = useXenia();\n return useCallback(\n (eventName, props, opts) => {\n xenia.track(eventName, props, opts);\n },\n [xenia],\n );\n}\n\nexport interface UsePersonalizationResult {\n data: JsonValue | null;\n isLoading: boolean;\n error: Error | null;\n}\n\n/**\n * Resolve personalization by firing a webhook trigger and treating its\n * response body as the personalized data — re-resolves when the trigger id or\n * the serialized `data` changes. Never throws: falls back to `data: null` so\n * the caller can render its own base/fallback content.\n */\nexport function usePersonalization(\n triggerId: string,\n data?: Record<string, JsonValue | undefined>,\n): UsePersonalizationResult {\n const xenia = useXenia();\n const [result, setResult] = useState<JsonValue | null>(null);\n const [isLoading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const dataKey = JSON.stringify(data ?? {});\n\n useEffect(() => {\n let active = true;\n setLoading(true);\n setError(null);\n xenia\n .request(triggerId, data, { apply: false })\n .then((r) => {\n if (active) setResult(r.body);\n })\n .catch((e: unknown) => {\n if (active) setError(e instanceof Error ? e : new Error(String(e)));\n })\n .finally(() => {\n if (active) setLoading(false);\n });\n return () => {\n active = false;\n };\n }, [xenia, triggerId, dataKey]);\n\n return { data: result, isLoading, error };\n}\n\nexport interface UsePersonalizationSlotsResult {\n data: Record<string, JsonValue>;\n isLoading: boolean;\n error: Error | null;\n}\n\n/**\n * Resolve several named content slots from ONE webhook round-trip — a\n * webhook-backed batch-resolve, analogous to a REST personalization client's\n * \"resolve many slots at once\". The response body's `xeniaContentSwaps` array\n * (see `ContentSwap` in `core/content-splice`) is spliced into `slots`\n * recursively; slots with no matching swap come back unchanged. Never throws:\n * degrades to `slots` as-is, so it's always safe to render immediately.\n *\n * Depends on the journey's Webhook Response node emitting `xeniaContentSwaps`\n * — confirm this contract with the Journey Orchestrator team before relying\n * on it in production.\n */\nexport function usePersonalizationSlots(\n triggerId: string,\n slots: Record<string, JsonValue>,\n data?: Record<string, JsonValue | undefined>,\n): UsePersonalizationSlotsResult {\n const xenia = useXenia();\n const [result, setResult] = useState<Record<string, JsonValue>>(slots);\n const [isLoading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const slotsKey = JSON.stringify(slots);\n const dataKey = JSON.stringify(data ?? {});\n\n useEffect(() => {\n let active = true;\n setLoading(true);\n setError(null);\n xenia\n .request(triggerId, data, { apply: false })\n .then((r) => {\n if (!active) return;\n setResult(spliceSlots(slots, extractContentSwaps(r.body)));\n })\n .catch((e: unknown) => {\n if (active) setError(e instanceof Error ? e : new Error(String(e)));\n })\n .finally(() => {\n if (active) setLoading(false);\n });\n return () => {\n active = false;\n };\n }, [xenia, triggerId, dataKey, slotsKey]);\n\n return { data: result, isLoading, error };\n}\n\nexport interface UsePersonalizationResolveResult {\n data: ResolveResult | null;\n isLoading: boolean;\n error: Error | null;\n}\n\n/**\n * Resolve in-entry content personalization for one content key against the REST\n * endpoint (`POST /api/personalization/resolve`) — the production path,\n * alongside the webhook-backed {@link usePersonalization}. Re-resolves when the\n * content key or serialized `data`/`locale` changes. Requires a configured SDK\n * token (resolve is auth-required); exposes the error otherwise. With\n * `merge: true` the result's `content` is server-spliced.\n */\nexport function usePersonalizationResolve(\n contentKey: string,\n opts?: { data?: Record<string, JsonValue | undefined>; locale?: string; merge?: boolean },\n): UsePersonalizationResolveResult {\n const xenia = useXenia();\n const [data, setData] = useState<ResolveResult | null>(null);\n const [isLoading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const optsKey = JSON.stringify({ data: opts?.data ?? {}, locale: opts?.locale, merge: opts?.merge });\n\n useEffect(() => {\n let active = true;\n setLoading(true);\n setError(null);\n xenia\n .resolve(contentKey, opts)\n .then((r) => {\n if (active) setData(r);\n })\n .catch((e: unknown) => {\n if (active) setError(e instanceof Error ? e : new Error(String(e)));\n })\n .finally(() => {\n if (active) setLoading(false);\n });\n return () => {\n active = false;\n };\n }, [xenia, contentKey, optsKey]);\n\n return { data, isLoading, error };\n}\n\nexport interface UsePersonalizationResolveSlotsResult {\n data: ResolveBatchResult[] | null;\n isLoading: boolean;\n error: Error | null;\n}\n\n/**\n * Resolve several content keys in one REST round-trip\n * (`POST /api/personalization/resolve-batch`, ≤50) — the batch analogue of\n * {@link usePersonalizationResolve}. Re-resolves when the item list or\n * serialized `data`/`locale` changes.\n */\nexport function usePersonalizationResolveSlots(\n items: ResolveBatchItem[],\n opts?: { data?: Record<string, JsonValue | undefined>; locale?: string; merge?: boolean },\n): UsePersonalizationResolveSlotsResult {\n const xenia = useXenia();\n const [data, setData] = useState<ResolveBatchResult[] | null>(null);\n const [isLoading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const itemsKey = JSON.stringify(items);\n const optsKey = JSON.stringify({ data: opts?.data ?? {}, locale: opts?.locale, merge: opts?.merge });\n\n useEffect(() => {\n let active = true;\n setLoading(true);\n setError(null);\n xenia\n .resolveBatch(items, opts)\n .then((r) => {\n if (active) setData(r);\n })\n .catch((e: unknown) => {\n if (active) setError(e instanceof Error ? e : new Error(String(e)));\n })\n .finally(() => {\n if (active) setLoading(false);\n });\n return () => {\n active = false;\n };\n }, [xenia, itemsKey, optsKey]);\n\n return { data, isLoading, error };\n}\n\nexport interface UseWebhookResult {\n send: (data?: Record<string, JsonValue | undefined>) => Promise<WebhookResponse | null>;\n response: WebhookResponse | null;\n isLoading: boolean;\n error: Error | null;\n}\n\n/**\n * Imperatively send a webhook request/response for a trigger. The latest\n * response is exposed and its actions auto-applied (per client config).\n */\nexport function useWebhook(triggerId: string): UseWebhookResult {\n const xenia = useXenia();\n const [response, setResponse] = useState<WebhookResponse | null>(\n () => xenia.getResponse(triggerId) ?? null,\n );\n const [isLoading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const idRef = useRef(triggerId);\n idRef.current = triggerId;\n\n const send = useCallback(\n async (data?: Record<string, JsonValue | undefined>) => {\n setLoading(true);\n setError(null);\n try {\n const r = await xenia.request(idRef.current, data);\n setResponse(r);\n return r;\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n return null;\n } finally {\n setLoading(false);\n }\n },\n [xenia],\n );\n\n return { send, response, isLoading, error };\n}\n\n/** Read the last saved webhook response for a key (reactive to sends via re-render). */\nexport function useXeniaResponse(key: string): WebhookResponse | undefined {\n const xenia = useXenia();\n return xenia.getResponse(key);\n}\n","import { createContext, createElement, useContext, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { pendingTargets } from \"../../core/personalize-content\";\nimport type { AppliedSwap, PageRef, PagePersonalizeOptions } from \"../../core/personalize-content\";\nimport { useXenia } from \"./context\";\n\n/** Where one personalized entry stands while the page resolves. */\nexport type EntryStatus = \"pending\" | \"personalized\" | \"base\";\n\nexport interface UsePersonalizedContentOptions extends PagePersonalizeOptions {\n /**\n * What to render before Xenia answers:\n * - `\"base-first\"` (default): the CMS content immediately, swapped in place round by round\n * (best LCP; personalized sections can visibly change).\n * - `\"hide-until-resolved\"`: `content` is null until done or `hideTimeoutMs` — render a skeleton\n * while `isLoading` (no flicker, costs up to `hideTimeoutMs` of blank).\n */\n render?: \"base-first\" | \"hide-until-resolved\";\n /** Cap on the hidden period for `\"hide-until-resolved\"`. Default: `timeoutMs` (300). */\n hideTimeoutMs?: number;\n}\n\nexport interface UsePersonalizedContentResult<T> {\n content: T | null;\n isLoading: boolean;\n /**\n * True once every personalized entry was decided. False while loading, and after a timeout or a\n * failed Xenia/CMS call — the undecided entries then show their base content.\n */\n complete: boolean;\n applied: AppliedSwap[];\n /** Per-entry state, for skeletons / fades on just the sections being decided. */\n status(entryId: string): EntryStatus;\n}\n\n/**\n * Personalize a CMS page in the browser — `XeniaClient.personalizeContent` as a hook. Re-runs when\n * `page` (by identity) or the serialized `data`/`locale` change. Never throws: on failure the base\n * content renders. For pages that can render on the server, prefer `XeniaServer.personalizeContent`\n * (no flicker, no client round trip).\n */\nexport function usePersonalizedContent<T>(\n page: T | null | undefined,\n opts: UsePersonalizedContentOptions,\n): UsePersonalizedContentResult<T> {\n const xenia = useXenia();\n const hide = opts.render === \"hide-until-resolved\";\n // Known from the markers before any network — `status()` is \"pending\" from the very first render\n // (server render included), so a skeleton shows instead of base content that is about to change.\n const initialPending = useMemo(\n () => new Set(page == null ? [] : pendingTargets(page, opts.cms)),\n [page], // markers live in `page`; a new adapter object for the same page changes nothing\n );\n const [state, setState] = useState<{\n page: T | null | undefined; content: T | null; done: boolean; complete: boolean; applied: AppliedSwap[]; pending: Set<string>;\n }>(\n () => ({ page, content: hide ? null : (page ?? null), done: false, complete: false, applied: [], pending: initialPending }),\n );\n // The adapter/callbacks are usually re-created every render; only data/locale/page re-run it.\n const optsRef = useRef(opts);\n optsRef.current = opts;\n const optsKey = JSON.stringify({ data: opts.data ?? {}, locale: opts.locale });\n\n useEffect(() => {\n if (page == null) return;\n let active = true;\n const o = optsRef.current;\n setState({ page, content: hide ? null : page, done: false, complete: false, applied: [], pending: initialPending });\n const reveal = hide\n ? setTimeout(() => active && setState((s) => (s.content ? s : { ...s, content: page })), o.hideTimeoutMs ?? o.timeoutMs ?? 300)\n : undefined;\n\n const applied: AppliedSwap[] = [];\n void xenia\n .personalizeContent(page, {\n ...o,\n onApplied(swap) {\n applied.push(swap);\n o.onApplied?.(swap);\n },\n onProgress(p) {\n o.onProgress?.(p);\n if (!active || hide) return;\n setState({ page, content: p.content as T, done: false, complete: false, applied: [...applied], pending: new Set(p.pending) });\n },\n })\n .then((r) => {\n if (active) setState({ page, content: r.content, done: true, complete: r.complete, applied: r.applied, pending: new Set() });\n })\n .finally(() => clearTimeout(reveal));\n return () => {\n active = false;\n clearTimeout(reveal);\n };\n }, [xenia, page, optsKey, hide, initialPending]);\n\n const personalized = new Set(state.applied.map((a) => a.target));\n // A render for a page whose run hasn't started yet: its targets are pending from the markers.\n const pending = state.page === page ? state.pending : initialPending;\n return {\n content: state.content,\n isLoading: page != null && !state.done,\n complete: state.complete,\n applied: state.applied,\n status: (id) => (pending.has(id) ? \"pending\" : personalized.has(id) ? \"personalized\" : \"base\"),\n };\n}\n\n/**\n * Fetch a page through `opts.cms` and personalize it in the browser — `usePersonalizedContent`\n * without the fetch in app code. `content` is null (and `isLoading` true) while the page loads; a\n * failed or missing page ends with `content: null`, `isLoading: false`.\n */\nexport function usePersonalizedPage<T = unknown>(\n ref: PageRef,\n opts: UsePersonalizedContentOptions,\n): UsePersonalizedContentResult<T> {\n const [page, setPage] = useState<{ value: T | null; loaded: boolean; failed?: boolean }>({ value: null, loaded: false });\n const cmsRef = useRef(opts.cms);\n cmsRef.current = opts.cms;\n const refKey = JSON.stringify([ref, opts.locale]);\n\n useEffect(() => {\n let active = true;\n setPage({ value: null, loaded: false });\n const fetchPage = cmsRef.current.fetchPage;\n Promise.resolve(fetchPage ? fetchPage.call(cmsRef.current, ref, opts.locale) : null)\n .then(\n (value) => active && setPage({ value: (value ?? null) as T | null, loaded: true }),\n () => active && setPage({ value: null, loaded: true, failed: true }),\n );\n return () => {\n active = false;\n };\n }, [refKey]); // refKey covers ref and locale\n\n const result = usePersonalizedContent<T>(page.value, opts);\n const complete = page.value == null ? page.loaded && !page.failed : result.complete;\n return { ...result, isLoading: !page.loaded || result.isLoading, complete };\n}\n\nconst PersonalizedContentContext = createContext<UsePersonalizedContentResult<unknown> | null>(null);\n\n/** Shares a `usePersonalizedContent` result with nested sections (`useXeniaEntry`). */\nexport function XeniaContentProvider(props: { value: UsePersonalizedContentResult<unknown>; children?: ReactNode }) {\n return createElement(PersonalizedContentContext.Provider, { value: props.value }, props.children);\n}\n\n/** Loading state of one entry inside a `<XeniaContentProvider>` — e.g. a skeleton for just that section. */\nexport function useXeniaEntry(entryId: string): { status: EntryStatus; isLoading: boolean } {\n const ctx = useContext(PersonalizedContentContext);\n const status = ctx ? ctx.status(entryId) : \"base\";\n return { status, isLoading: status === \"pending\" };\n}\n","import {\n createElement,\n useEffect,\n useRef,\n type ElementType,\n type ReactNode,\n} from \"react\";\nimport type { InteractionType, XeniaAction } from \"../../core/types\";\nimport { useXenia } from \"./context\";\n\nexport interface XeniaTrackProps {\n /** Event id to fire. */\n event: string;\n /** When to fire. Default \"click\". */\n on?: InteractionType;\n /** Extra properties merged into the event. */\n props?: Record<string, string | number | boolean | null>;\n /** Element type to render. Default \"span\". */\n as?: ElementType;\n children?: ReactNode;\n className?: string;\n}\n\n/**\n * Wrap any element to fire a Xenia event on click, viewport entry, or mount —\n * no `data-` attributes needed.\n */\nexport function XeniaTrack({\n event,\n on = \"click\",\n props,\n as = \"span\",\n children,\n className,\n}: XeniaTrackProps) {\n const xenia = useXenia();\n const ref = useRef<HTMLElement | null>(null);\n\n useEffect(() => {\n if (on === \"page-load\") {\n xenia.track(event, { ...props, interactionType: \"page-load\" }, { trigger: true });\n return;\n }\n if (on === \"view-port\") {\n const el = ref.current;\n if (!el) return;\n const observer = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n xenia.track(event, { ...props, interactionType: \"view-port\" }, { trigger: true });\n observer.disconnect();\n }\n }\n },\n { threshold: 0.5 },\n );\n observer.observe(el);\n return () => observer.disconnect();\n }\n return;\n }, [xenia, event, on]);\n\n const handlers =\n on === \"click\"\n ? {\n onClick: () =>\n xenia.track(event, { ...props, interactionType: \"click\" }, { trigger: true }),\n }\n : {};\n\n return createElement(as, { ref, className, ...handlers }, children);\n}\n\nexport interface XeniaMessageProps {\n /** Actions to render/apply on mount (e.g. from a saved response). */\n actions: XeniaAction[];\n}\n\n/** Imperatively apply a set of render actions when mounted. */\nexport function XeniaMessage({ actions }: XeniaMessageProps) {\n const xenia = useXenia();\n useEffect(() => {\n if (actions.length) xenia.applyActions(actions);\n }, [actions]);\n return null;\n}\n","import { createElement, type ComponentType } from \"react\";\nimport { createRoot, type Root } from \"react-dom/client\";\nimport type { MessageComponentRenderer, MessageMountContext } from \"../../core/types\";\n\n/**\n * Props a component registered via {@link reactMessageComponent} receives —\n * the action being rendered, its placement, and the `close`/`fireCta`\n * callbacks to call from your own markup (a close button, a CTA button, …).\n */\nexport type XeniaMessageComponentProps = MessageMountContext;\n\n/**\n * Adapts a plain React component into the framework-agnostic\n * `messageComponent` shape (`XeniaClientOptions.messageComponent` /\n * `<XeniaProvider messageComponent>`) — the React-native alternative to\n * building an HTML string with `messageTemplate`. The component is mounted\n * with `react-dom/client`'s `createRoot` and unmounted automatically when the\n * message is dismissed.\n *\n * @example\n * ```tsx\n * function OfferCard({ action, close, fireCta }: XeniaMessageComponentProps) {\n * return (\n * <div className=\"offer-card\">\n * <p>{action.message}</p>\n * {action.cta && <button onClick={fireCta}>{action.cta.label}</button>}\n * <button onClick={close} aria-label=\"Close\">×</button>\n * </div>\n * );\n * }\n *\n * <XeniaProvider messageComponent={reactMessageComponent(OfferCard)} ... />\n * ```\n */\nexport function reactMessageComponent(\n Component: ComponentType<XeniaMessageComponentProps>,\n): MessageComponentRenderer {\n return (container, ctx) => {\n const root: Root = createRoot(container);\n root.render(createElement(Component, ctx));\n return () => root.unmount();\n };\n}\n"]}
1
+ {"version":3,"sources":["../../../src/core/actions.ts","../../../src/core/http-client.ts","../../../src/core/token-provider.ts","../../../src/core/api.ts","../../../src/core/cookie-names.ts","../../../src/core/event-payload.ts","../../../src/core/id.ts","../../../src/core/personalize-content.ts","../../../src/core/response-store.ts","../../../src/client/analytics-queue.ts","../../../src/client/auto-track.ts","../../../src/server/cookies.ts","../../../src/client/identity.ts","../../../src/client/widgets/form.ts","../../../src/client/widgets/types.ts","../../../src/client/widgets/spin-wheel.ts","../../../src/client/widgets/index.ts","../../../src/client/renderer.ts","../../../src/client/xenia-client.ts","../../../src/client/react/context.ts","../../../src/client/react/XeniaProvider.tsx","../../../src/core/content-splice.ts","../../../src/client/react/hooks.ts","../../../src/client/react/personalized-content.tsx","../../../src/client/react/components.tsx","../../../src/client/react/message-component.ts"],"names":["compact","MESSAGE_TYPES","escapeHtml","escapeAttr","apply","children","useEffect","useRef","useMemo","useState","createContext","useContext","createElement"],"mappings":"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","file":"index.js","sourcesContent":["import type {\n JsonValue,\n MessagePlacement,\n MessagePosition,\n WidgetFormSubmit,\n WidgetSegment,\n WidgetStyle,\n WidgetType,\n XeniaAction,\n} from \"./types\";\n\nconst MESSAGE_TYPES: ReadonlySet<string> = new Set<MessagePlacement>([\n \"banner\",\n \"popup\",\n \"modal\",\n \"inline\",\n]);\n\nconst MESSAGE_POSITIONS: ReadonlySet<string> = new Set<MessagePosition>([\n \"top-left\",\n \"top-right\",\n \"bottom-left\",\n \"bottom-right\",\n \"top\",\n \"bottom\",\n]);\n\n// NOTE: `widgetType` is deliberately NOT added to `ALL_TYPES`/`MESSAGE_TYPES` below — it is an\n// orthogonal field on message-placement actions, not a new `type` value. Keeping `type`'s\n// allowlist untouched is exactly what keeps the PHP SDK's `XeniaActions::KNOWN_TYPES` (same value\n// set) valid with zero PHP changes.\nconst WIDGET_TYPES: ReadonlySet<string> = new Set<WidgetType>([\"standard\", \"spin-wheel\"]);\n\nconst ALL_TYPES: ReadonlySet<string> = new Set<string>([\n \"swap\",\n \"hide\",\n \"show\",\n \"setContent\",\n \"redirect\",\n ...MESSAGE_TYPES,\n]);\n\n/** Type guard for a plain JSON object. */\nfunction isObject(v: JsonValue | undefined): v is { [k: string]: JsonValue } {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\nfunction asString(v: JsonValue | undefined): string | undefined {\n return typeof v === \"string\" ? v : undefined;\n}\n\nfunction asNumber(v: JsonValue | undefined): number | undefined {\n return typeof v === \"number\" ? v : undefined;\n}\n\n/**\n * Validate and narrow a single raw entry into a {@link XeniaAction}.\n * Returns null for anything malformed so a bad entry can't crash the renderer.\n */\nfunction toAction(raw: JsonValue): XeniaAction | null {\n if (!isObject(raw)) return null;\n const type = asString(raw.type);\n if (!type || !ALL_TYPES.has(type)) return null;\n\n if (type === \"redirect\") {\n const url = asString(raw.url);\n return url ? { type, url } : null;\n }\n\n if (type === \"hide\" || type === \"show\") {\n const target = asString(raw.target);\n return target ? { type, target } : null;\n }\n\n if (type === \"swap\" || type === \"setContent\") {\n const target = asString(raw.target);\n if (!target) return null;\n return { type, target, html: asString(raw.html), text: asString(raw.text) };\n }\n\n // Message placement actions (banner/popup/modal/inline).\n const cta = isObject(raw.cta)\n ? {\n label: asString(raw.cta.label) ?? \"\",\n url: asString(raw.cta.url),\n event: asString(raw.cta.event),\n }\n : undefined;\n\n return {\n type: type as MessagePlacement,\n target: asString(raw.target),\n title: asString(raw.title),\n message: asString(raw.message),\n imageUrl: asString(raw.imageUrl),\n html: asString(raw.html),\n // A link-only CTA (empty label, e.g. a spin-wheel's data-xenia-wheel-cta —\n // label is meaningless there, the winHtml/lossHtml design supplies its own button text)\n // must still parse through — gating on `cta.label` alone silently dropped it.\n cta: cta && (cta.label || cta.url) ? cta : undefined,\n dismissAfterMs: asNumber(raw.dismissAfterMs),\n position: asMessagePosition(raw.position),\n widgetType: asWidgetType(raw.widgetType),\n segments: asSegments(raw.segments),\n formSubmit: asFormSubmit(raw.formSubmit),\n style: asWidgetStyle(raw.style),\n spinnerHtml: asString(raw.spinnerHtml),\n winHtml: asString(raw.winHtml),\n lossHtml: asString(raw.lossHtml),\n };\n}\n\nfunction asMessagePosition(v: JsonValue | undefined): MessagePosition | undefined {\n const s = asString(v);\n return s && MESSAGE_POSITIONS.has(s) ? (s as MessagePosition) : undefined;\n}\n\nfunction asWidgetType(v: JsonValue | undefined): WidgetType | undefined {\n const s = asString(v);\n return s && WIDGET_TYPES.has(s) ? (s as WidgetType) : undefined;\n}\n\n/** Narrow a raw `segments` array to label/color/isLoss-only entries — drops anything malformed. */\nfunction asSegments(v: JsonValue | undefined): WidgetSegment[] | undefined {\n if (!Array.isArray(v)) return undefined;\n const segments: WidgetSegment[] = [];\n for (const entry of v) {\n if (!isObject(entry)) continue;\n const id = asString(entry.id);\n const label = asString(entry.label);\n if (!id || !label) continue;\n segments.push({\n id,\n label,\n colorHex: asString(entry.colorHex),\n isLoss: entry.isLoss === true,\n });\n }\n return segments.length ? segments : undefined;\n}\n\n/**\n * Narrow a raw `formSubmit` envelope. Defensive by design (same as the rest of this\n * module) — a malformed envelope (missing `mode`) is dropped entirely rather than\n * passed through half-formed, since the SDK's endpoint-selection logic depends on it.\n */\nfunction asFormSubmit(v: JsonValue | undefined): WidgetFormSubmit | undefined {\n if (!isObject(v)) return undefined;\n const mode = asString(v.mode);\n if (!mode) return undefined;\n return {\n requiresResolve: v.requiresResolve === true,\n mode,\n flowRef: asString(v.flowRef),\n bindingRef: asString(v.bindingRef),\n successDisplayMs: asNumber(v.successDisplayMs),\n };\n}\n\n/**\n * Narrow a raw `style` override. Every field is independently optional/defensive (same\n * philosophy as the rest of this module) — a malformed value for one field just drops that\n * field, it never discards the whole `style` object.\n */\nfunction asWidgetStyle(v: JsonValue | undefined): WidgetStyle | undefined {\n if (!isObject(v)) return undefined;\n const style: WidgetStyle = {\n hideCloseButton: v.hideCloseButton === true,\n hideOverlay: v.hideOverlay === true,\n };\n const hasAny = style.hideCloseButton || style.hideOverlay;\n return hasAny ? style : undefined;\n}\n\n/**\n * Parse render actions out of a webhook-response body.\n *\n * The convention: marketers return `{ \"xeniaActions\": [ ... ] }` (or a bare\n * array) from the `webhook-response` node. Any body without a recognizable\n * `xeniaActions` array yields an empty list — a safe no-op.\n */\nexport function parseActions(body: JsonValue): XeniaAction[] {\n let list: JsonValue | undefined;\n if (Array.isArray(body)) {\n list = body;\n } else if (isObject(body) && Array.isArray(body.xeniaActions)) {\n list = body.xeniaActions;\n }\n if (!Array.isArray(list)) return [];\n\n const actions: XeniaAction[] = [];\n for (const entry of list) {\n const action = toAction(entry);\n if (action) actions.push(action);\n }\n return actions;\n}\n","import type { CircuitBreakerConfig, HttpMethod, JsonValue, RetryConfig } from \"./types\";\n\n/**\n * Default Xenia backend base URL, used whenever `baseUrl` is omitted from\n * config. Points at the hosted engine — override only for a self-hosted or\n * non-default environment.\n */\nexport const DEFAULT_BASE_URL = \"https://engine.xeniamartech.com/xenia\";\n\n/** Returns true when running in a browser environment (SSR-safe). */\nexport function isBrowser(): boolean {\n return typeof window !== \"undefined\" && typeof document !== \"undefined\";\n}\n\n/** Appends query parameters to a URL. Returns the URL unchanged when empty. */\nexport function buildUrl(url: string, queryParams?: Record<string, string>): string {\n if (!queryParams || Object.keys(queryParams).length === 0) return url;\n const params = new URLSearchParams(queryParams);\n const sep = url.includes(\"?\") ? \"&\" : \"?\";\n return `${url}${sep}${params.toString()}`;\n}\n\n/** Sleep helper used by the retry backoff. */\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/** Options for a single request. */\nexport interface RequestOptions {\n method?: HttpMethod;\n /** Path appended to `baseUrl` (should start with `/`). */\n path: string;\n headers?: Record<string, string>;\n query?: Record<string, string>;\n body?: JsonValue;\n /** Per-request timeout override in ms. */\n timeout?: number;\n /** Disable retry for this request (e.g. long-polling webhook). */\n noRetry?: boolean;\n /** Per-request retry override. */\n retry?: RetryConfig;\n /**\n * Keep the request alive past page unload (`fetch`'s `keepalive` flag).\n * Used for best-effort flushes on `pagehide`, where `sendBeacon` can't be\n * used instead because it doesn't support custom headers (tenant scope).\n */\n keepalive?: boolean;\n}\n\n/** Result of a request: the raw Response plus the parsed JSON (or null). */\nexport interface HttpResult {\n response: Response;\n data: JsonValue;\n}\n\n/** Error thrown for non-2xx responses (after retries are exhausted). */\nexport class HttpError extends Error {\n constructor(\n public readonly status: number,\n public readonly data: JsonValue,\n message?: string,\n ) {\n super(message ?? `Request failed with status ${status}`);\n this.name = \"HttpError\";\n }\n}\n\n/** Thrown without a network call while an endpoint's circuit is open (see {@link CircuitBreakerConfig}). */\nexport class CircuitOpenError extends Error {\n constructor(public readonly endpoint: string) {\n super(`Circuit open for ${endpoint}: failing fast until the cooldown passes`);\n this.name = \"CircuitOpenError\";\n }\n}\n\n/**\n * Per-endpoint breaker state, module-wide so it outlives a single client.\n * ponytail: after the cooldown every concurrent caller probes, not just one; fine for a fail-fast\n * guard, add a probe lock if a thundering herd on recovery ever matters.\n */\nconst breakers = new Map<string, { failures: number; openedAt: number }>();\n\nexport interface HttpClientOptions {\n /** Defaults to {@link DEFAULT_BASE_URL} when omitted. */\n baseUrl?: string;\n defaultHeaders?: Record<string, string>;\n timeout?: number;\n retry?: RetryConfig;\n circuitBreaker?: boolean | CircuitBreakerConfig;\n debug?: boolean;\n}\n\n/**\n * Minimal fetch wrapper shared by all runtimes.\n *\n * - Injects default headers (tenant scope, content-type).\n * - Applies an `AbortController` timeout.\n * - Retries transient failures (network error, `429`, `5xx`) with exponential\n * backoff, honoring a `Retry-After` header when present.\n * - Parses JSON, falling back to `null` on empty/invalid bodies.\n */\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly defaultHeaders: Record<string, string>;\n private readonly timeout: number;\n private readonly retry: Required<RetryConfig>;\n private readonly debug: boolean;\n private readonly breaker: Required<CircuitBreakerConfig> | null;\n\n constructor(opts: HttpClientOptions) {\n this.baseUrl = (opts.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.defaultHeaders = opts.defaultHeaders ?? {};\n this.timeout = opts.timeout ?? 8000;\n this.retry = {\n attempts: opts.retry?.attempts ?? 2,\n baseDelayMs: opts.retry?.baseDelayMs ?? 300,\n };\n this.debug = opts.debug ?? false;\n const cb = opts.circuitBreaker === true ? {} : opts.circuitBreaker || null;\n this.breaker = cb && { failureThreshold: cb.failureThreshold ?? 3, cooldownMs: cb.cooldownMs ?? 30_000 };\n }\n\n async request(opts: RequestOptions): Promise<HttpResult> {\n if (!this.breaker) return this.send(opts);\n // Keyed by full URL, query included: every webhook shares `/flow`, and one slow journey\n // (`?id=`) must not short-circuit the others.\n const key = buildUrl(this.baseUrl + opts.path, opts.query);\n const b = breakers.get(key) ?? { failures: 0, openedAt: 0 };\n if (b.openedAt) {\n if (Date.now() - b.openedAt < this.breaker.cooldownMs) throw new CircuitOpenError(key);\n // Half-open: let this call probe; one more failure re-opens.\n b.openedAt = 0;\n b.failures = this.breaker.failureThreshold - 1;\n }\n try {\n const result = await this.send(opts);\n breakers.delete(key);\n return result;\n } catch (err) {\n if (err instanceof HttpError && !this.isRetryableStatus(err.status)) {\n breakers.delete(key); // the backend answered: it's up\n throw err;\n }\n b.failures += 1;\n if (b.failures >= this.breaker.failureThreshold) {\n b.openedAt = Date.now();\n this.log(`circuit opened for ${opts.path} after ${b.failures} failures`);\n }\n breakers.set(key, b);\n throw err;\n }\n }\n\n private async send(opts: RequestOptions): Promise<HttpResult> {\n const url = buildUrl(this.baseUrl + opts.path, opts.query);\n const method = opts.method ?? \"GET\";\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...this.defaultHeaders,\n ...opts.headers,\n };\n const body = opts.body !== undefined ? JSON.stringify(opts.body) : undefined;\n const timeout = opts.timeout ?? this.timeout;\n const maxAttempts = opts.noRetry ? 1 : (opts.retry?.attempts ?? this.retry.attempts) + 1;\n const baseDelay = opts.retry?.baseDelayMs ?? this.retry.baseDelayMs;\n\n let lastError: unknown;\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n const response = await this.fetchWithTimeout(\n url,\n { method, headers, body, ...(opts.keepalive ? { keepalive: true } : {}) },\n timeout,\n );\n const data = await this.parseBody(response);\n\n if (response.ok) {\n return { response, data };\n }\n\n // Retry on 429/5xx if attempts remain; otherwise throw.\n if (this.isRetryableStatus(response.status) && attempt < maxAttempts - 1) {\n const wait = this.retryAfterMs(response, baseDelay, attempt);\n this.log(`retrying ${opts.path} after ${wait}ms (status ${response.status})`);\n await delay(wait);\n continue;\n }\n throw new HttpError(response.status, data);\n } catch (err) {\n lastError = err;\n // Non-retryable HttpError → rethrow immediately.\n if (err instanceof HttpError) throw err;\n // Network/timeout error → retry if attempts remain.\n if (attempt < maxAttempts - 1) {\n const wait = baseDelay * 2 ** attempt;\n this.log(`retrying ${opts.path} after ${wait}ms (network error)`);\n await delay(wait);\n continue;\n }\n }\n }\n throw lastError instanceof Error ? lastError : new Error(\"Request failed\");\n }\n\n private async fetchWithTimeout(\n url: string,\n init: RequestInit,\n timeout: number,\n ): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeout);\n try {\n return await fetch(url, { ...init, signal: controller.signal });\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n throw new Error(`Request timeout after ${timeout}ms`, { cause: err });\n }\n throw err;\n } finally {\n clearTimeout(timer);\n }\n }\n\n private async parseBody(response: Response): Promise<JsonValue> {\n const text = await response.text().catch(() => \"\");\n if (!text) return null;\n try {\n return JSON.parse(text) as JsonValue;\n } catch {\n return text;\n }\n }\n\n private isRetryableStatus(status: number): boolean {\n return status === 429 || (status >= 500 && status <= 599);\n }\n\n private retryAfterMs(response: Response, baseDelay: number, attempt: number): number {\n const header = response.headers.get(\"Retry-After\");\n if (header) {\n const seconds = Number(header);\n if (!Number.isNaN(seconds)) return seconds * 1000;\n }\n return baseDelay * 2 ** attempt;\n }\n\n private log(msg: string): void {\n if (this.debug) console.warn(`[xenia] ${msg}`);\n }\n}\n","import type { XeniaConfig } from \"./types\";\n\ninterface Cached {\n token: string;\n /** Epoch ms when the token should be considered stale. */\n expiresAt: number;\n}\n\n/** JWT `exp` (seconds) if decodable, else undefined. Best-effort, no verify. */\nfunction decodeExp(token: string): number | undefined {\n try {\n const payload = token.split(\".\")[1];\n if (!payload) return undefined;\n const json = JSON.parse(atob(payload.replace(/-/g, \"+\").replace(/_/g, \"/\")));\n return typeof json.exp === \"number\" ? json.exp * 1000 : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Resolves the Bearer token `XeniaApi` attaches to every request, caching a\n * short-lived token from `config.getToken` until ~30s before expiry. A static\n * `config.token` is returned as-is. Isomorphic (browser + Node ≥18, both have\n * global `atob`).\n */\nexport class TokenProvider {\n private readonly config: XeniaConfig;\n private cached: Cached | null = null;\n private inflight: Promise<string> | null = null;\n\n constructor(config: XeniaConfig) {\n this.config = config;\n }\n\n /** Whether a token source is configured at all — lets callers skip resolution entirely. */\n hasSource(): boolean {\n return Boolean(this.config.token || this.config.getToken);\n }\n\n readonly getToken = async (): Promise<string> => {\n if (this.config.token && !this.config.getToken) return this.config.token;\n\n const now = Date.now();\n if (this.cached && this.cached.expiresAt > now) return this.cached.token;\n if (this.inflight) return this.inflight;\n\n if (!this.config.getToken) {\n throw new Error(\"No token source: set config.token or config.getToken.\");\n }\n\n this.inflight = Promise.resolve(this.config.getToken())\n .then((token) => {\n const exp = decodeExp(token);\n // Refresh 30s before real expiry; default 5 min if the token is opaque.\n const expiresAt = exp ? exp - 30_000 : now + 5 * 60_000;\n this.cached = { token, expiresAt };\n return token;\n })\n .finally(() => {\n this.inflight = null;\n });\n\n return this.inflight;\n };\n}\n","import { parseActions } from \"./actions\";\nimport { HttpClient } from \"./http-client\";\nimport { TokenProvider } from \"./token-provider\";\nimport type {\n AnalyticsIngestResponse,\n ConsentState,\n IdentifyRequest,\n IdentifyResponse,\n JsonObject,\n JsonValue,\n ResolveBatchItem,\n ResolveBatchResult,\n ResolveEntriesResult,\n ResolveOptions,\n ResolveResult,\n WebhookResponse,\n WidgetPrize,\n WidgetSubmitResponse,\n WidgetType,\n XeniaConfig,\n XeniaEvent,\n} from \"./types\";\n\n/** Type guard for a plain JSON object (as opposed to an array/primitive/null). */\nfunction isJsonObject(v: JsonValue): v is JsonObject {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\n/** Narrow a raw `prize` field off a `/widget-submissions` response body. */\nfunction asWidgetPrize(v: JsonValue | undefined): WidgetPrize | undefined {\n return v !== undefined && isJsonObject(v) ? (v as WidgetPrize) : undefined;\n}\n\n/** Drop `undefined` values so the JSON body stays clean. */\nexport function compact(obj: Record<string, JsonValue | undefined>): JsonObject {\n const out: JsonObject = {};\n for (const [k, v] of Object.entries(obj)) {\n if (v !== undefined) out[k] = v;\n }\n return out;\n}\n\n/**\n * Low-level, isomorphic Xenia API client. Wraps the raw endpoints; identity,\n * UTM capture, and action rendering are layered on top by the client runtime.\n * All paths are relative to `baseUrl`, which defaults to the hosted engine\n * (`https://engine.xeniamartech.com/xenia`) when omitted from config.\n */\nexport class XeniaApi {\n private readonly http: HttpClient;\n private readonly tenantId: string;\n private readonly environmentKey: string;\n private readonly tokenProvider: TokenProvider;\n\n constructor(config: XeniaConfig) {\n this.tenantId = config.tenantId;\n this.environmentKey = config.environmentKey;\n this.tokenProvider = new TokenProvider(config);\n this.http = new HttpClient({\n baseUrl: config.baseUrl,\n defaultHeaders: config.headers,\n timeout: config.timeout,\n retry: config.retry,\n circuitBreaker: config.circuitBreaker,\n debug: config.debug,\n });\n }\n\n /** Tenant-scope headers required by header-scoped endpoints. */\n private tenantHeaders(): Record<string, string> {\n return {\n \"X-Tenant-Id\": this.tenantId,\n \"X-Environment\": this.environmentKey,\n };\n }\n\n /**\n * Tenant headers plus a resolved `Authorization: Bearer` header when\n * `config.token`/`config.getToken` is set — e.g. required by a webhook\n * trigger node configured with its own auth token. No-op (tenant headers\n * only) when no token source is configured, so this is safe to call\n * unconditionally on every request.\n */\n private async authHeaders(): Promise<Record<string, string>> {\n const headers = this.tenantHeaders();\n if (!this.tokenProvider.hasSource()) return headers;\n const token = await this.tokenProvider.getToken();\n if (token) headers.Authorization = `Bearer ${token}`;\n return headers;\n }\n\n /**\n * Webhook request/response — `GET|POST /flow?id={triggerId}`. Held open by the\n * backend until a `webhook-response` node resolves. Returns the normalized\n * response, including any `xeniaActions` parsed from the body.\n *\n * Not retried by default: the backend long-polls this call, so a retry would\n * duplicate the journey run.\n */\n async webhook(\n triggerId: string,\n data?: JsonValue,\n method: \"GET\" | \"POST\" = \"POST\",\n ): Promise<WebhookResponse> {\n const { response, data: rawBody } = await this.http.request({\n method,\n path: \"/flow\",\n query: { id: triggerId },\n headers: await this.authHeaders(),\n body: method === \"POST\" ? (data ?? {}) : undefined,\n noRetry: true,\n });\n return {\n status: response.status,\n body: rawBody,\n actions: parseActions(rawBody),\n receivedAt: Date.now(),\n };\n }\n\n /**\n * Widget form submission — `POST /widget-submissions?ref={bindingRef}`. Used whenever the\n * action's `formSubmit.requiresResolve` is true (spin-wheel, which must have a\n * server-resolved outcome before anything renders) or `mode === \"endpoint\"` — the common\n * plain-popup case (`mode === \"journey\" && !requiresResolve`) bypasses this entirely and calls\n * {@link webhook} against `flowRef` instead (see `XeniaClient.submitWidgetForm`'s endpoint\n * selection).\n *\n * Not retried (`noRetry: true`), styled like {@link webhook} — a retried POST must never\n * double-fire a journey or double-resolve a prize server-side.\n */\n async submitWidget(ref: string, body?: JsonValue): Promise<WidgetSubmitResponse> {\n const { response, data: rawBody } = await this.http.request({\n method: \"POST\",\n path: \"/widget-submissions\",\n query: { ref },\n headers: await this.authHeaders(),\n body: body ?? {},\n noRetry: true,\n });\n const obj = isJsonObject(rawBody) ? rawBody : {};\n return {\n status: response.status,\n body: rawBody,\n actions: parseActions(rawBody),\n prize: asWidgetPrize(obj.prize),\n alreadyPlayed: obj.alreadyPlayed === true,\n dispatched: obj.dispatched === true,\n dispatchError: typeof obj.dispatchError === \"string\" ? obj.dispatchError : undefined,\n widgetType: typeof obj.widgetType === \"string\" ? (obj.widgetType as WidgetType) : undefined,\n receivedAt: Date.now(),\n };\n }\n\n /**\n * Unified event batch (max 100/request per the backend) — `POST /api/events/v1`.\n * Records analytics for every event and matches/advances a journey for any\n * event with `trigger: true`. Replaces the old `sendEvent()` (journey trigger)\n * and `sendAnalytics()` (CDP) calls.\n */\n async sendEvents(\n events: XeniaEvent[],\n opts?: { keepalive?: boolean },\n ): Promise<AnalyticsIngestResponse> {\n const { data } = await this.http.request({\n method: \"POST\",\n path: \"/api/events/v1\",\n headers: await this.authHeaders(),\n body: { events } as unknown as JsonObject,\n keepalive: opts?.keepalive,\n });\n return data as unknown as AnalyticsIngestResponse;\n }\n\n /** Bind visitor→user — `POST /api/events/v1/identify`. */\n async identify(body: IdentifyRequest): Promise<IdentifyResponse> {\n const { data } = await this.http.request({\n method: \"POST\",\n path: \"/api/events/v1/identify\",\n headers: await this.authHeaders(),\n body: body as unknown as JsonObject,\n });\n return data as unknown as IdentifyResponse;\n }\n\n /**\n * Update consent — `POST /api/events/v1/consent`.\n *\n * The three scope flags are required (non-null) by the backend, so an omitted\n * one is sent as an explicit `false` rather than left out: a partial body like\n * `consent({ analytics: true })` — the shape most callers actually write — is\n * otherwise rejected with a 400 and the consent record is never stored.\n */\n async consent(xeniaVisitorId: string, consent: ConsentState): Promise<JsonValue> {\n const { data } = await this.http.request({\n method: \"POST\",\n path: \"/api/events/v1/consent\",\n headers: await this.authHeaders(),\n body: compact({\n xeniaVisitorId,\n analytics: consent.analytics === true,\n marketing: consent.marketing === true,\n personalization: consent.personalization === true,\n consentSource: consent.consentSource,\n consentVersion: consent.consentVersion,\n }),\n });\n return data;\n }\n\n /**\n * Resolve in-entry content personalization for one content key —\n * `POST /api/personalization/resolve?merge=<bool>`. Requires the SDK Bearer\n * token (same credential as events; resolve is auth-required). `merge=true`\n * returns server-spliced `content`; otherwise splice `swaps` client-side.\n */\n async resolve(contentKey: string, opts: ResolveOptions = {}): Promise<ResolveResult> {\n const { data } = await this.http.request({\n method: \"POST\",\n path: \"/api/personalization/resolve\",\n query: opts.merge !== undefined ? { merge: String(opts.merge) } : undefined,\n headers: await this.authHeaders(),\n body: compact({\n contentKey,\n data: opts.data as JsonValue,\n locale: opts.locale,\n }),\n });\n return data as unknown as ResolveResult;\n }\n\n /**\n * Resolve several content keys in one round-trip (≤50) —\n * `POST /api/personalization/resolve-batch?merge=<bool>`. Same auth/merge\n * semantics as {@link resolve}.\n */\n async resolveBatch(\n items: ResolveBatchItem[],\n opts: ResolveOptions = {},\n ): Promise<ResolveBatchResult[]> {\n const { data } = await this.http.request({\n method: \"POST\",\n path: \"/api/personalization/resolve-batch\",\n query: opts.merge !== undefined ? { merge: String(opts.merge) } : undefined,\n headers: await this.authHeaders(),\n body: compact({\n items: items as unknown as JsonValue,\n data: opts.data as JsonValue,\n locale: opts.locale,\n }),\n });\n return data as unknown as ResolveBatchResult[];\n }\n\n /**\n * Resolve personalized CMS entries by id for one visitor (≤200) —\n * `POST /api/personalization/resolve-entries`. The page resolver\n * ({@link personalizeContent}) calls this once per round with the runtime\n * targets it found; callers rarely need it directly.\n */\n async resolveEntries(\n entryIds: string[],\n opts: ResolveOptions & { contentKey: string },\n ): Promise<ResolveEntriesResult> {\n const { data } = await this.http.request({\n method: \"POST\",\n path: \"/api/personalization/resolve-entries\",\n headers: await this.authHeaders(),\n body: compact({\n entryIds: entryIds as unknown as JsonValue,\n data: opts.data as JsonValue,\n locale: opts.locale,\n contentKey: opts.contentKey,\n }),\n });\n return data as unknown as ResolveEntriesResult;\n }\n}\n","/**\n * Cookie names shared by the browser and server halves of the SDK.\n *\n * The visitor cookie is the one channel where two runtimes must agree on a literal string: the\n * browser writes it, a same-origin server reads it back, and that match is what lets a server-side\n * conversion attribute to a browser-entered journey. `config.prefix` namespaces it — so two Xenia\n * apps on one domain keep separate visitors — which means **both halves must derive the name the\n * same way**. Deriving it on one side and hardcoding it on the other silently breaks the link for\n * anyone using a custom prefix: the server just finds no cookie and falls back to no visitor.\n *\n * Always build the name with these helpers rather than interpolating it by hand.\n */\n\nimport type { ConsentState } from \"./types\";\n\n/** Default storage/cookie prefix, matching `XeniaConfig.prefix`. */\nexport const DEFAULT_PREFIX = \"xenia\";\n\n/** Name of the first-party cookie carrying the SDK-owned visitor id, for a given prefix. */\nexport function visitorCookieName(prefix: string = DEFAULT_PREFIX): string {\n return `${prefix || DEFAULT_PREFIX}_vid`;\n}\n\n/** Name of the first-party cookie carrying consent scopes, for a given prefix. */\nexport function consentCookieName(prefix: string = DEFAULT_PREFIX): string {\n return `${prefix || DEFAULT_PREFIX}_consent`;\n}\n\n/**\n * The visitor cookie name for the DEFAULT prefix (`\"xenia_vid\"`).\n *\n * Correct for the common case, and kept so existing code (e.g. reading the cookie straight out of a\n * framework's cookie jar) keeps working. If you set `config.prefix`, use {@link visitorCookieName}\n * instead — this constant will not match what the browser wrote.\n */\nexport const VISITOR_COOKIE = visitorCookieName();\n\n/**\n * The consent cookie name for the DEFAULT prefix (`\"xenia_consent\"`). Same custom-prefix caveat as\n * {@link VISITOR_COOKIE}.\n */\nexport const CONSENT_COOKIE = consentCookieName();\n\n/**\n * A `document.cookie` string carrying consent, in the JSON form the server SDK's `getConsent()`\n * reads back. The browser client's `consent()` writes it; a page with its own consent banner and no\n * browser client can write it directly, so server-side calls see the visitor's choice.\n */\nexport function consentCookie(state: ConsentState, prefix?: string, maxAgeDays = 365): string {\n return `${consentCookieName(prefix)}=${encodeURIComponent(JSON.stringify(state))}; path=/; max-age=${Math.floor(maxAgeDays * 86400)}; SameSite=Lax`;\n}\n","import type { EventContext, EventIdentity, EventPayload, JsonValue } from \"./types\";\n\n/** Reserved keys that map to first-class fields (not passthrough data). */\nconst RESERVED = new Set([\n \"eventId\",\n \"eventType\",\n \"journeyId\",\n \"deviceId\",\n \"visitorId\",\n \"customerId\",\n \"email\",\n \"utmSource\",\n \"utmMedium\",\n \"utmCampaign\",\n \"utmContent\",\n \"utmId\",\n \"url\",\n \"referrer\",\n \"path\",\n \"query\",\n]);\n\nexport interface BuildEventInput {\n eventId: string;\n eventType?: string;\n journeyId?: string;\n identity?: EventIdentity;\n context?: EventContext;\n /** Arbitrary extra properties merged as passthrough data. */\n props?: Record<string, JsonValue | undefined>;\n}\n\n/** Drop `undefined` values so the JSON body stays clean. */\nfunction compact(obj: Record<string, JsonValue | undefined>): Record<string, JsonValue> {\n const out: Record<string, JsonValue> = {};\n for (const [k, v] of Object.entries(obj)) {\n if (v !== undefined) out[k] = v;\n }\n return out;\n}\n\n/**\n * Build the request body for the webhook `/flow` call (`XeniaApi.webhook`).\n *\n * Merge order (later wins): passthrough props < context < identity < core.\n * Field names match the backend `EventTriggerRequest` DTO exactly.\n *\n * @internal Used only by the webhook request/response path — the unified event\n * surface (`track()` → `POST /api/events/v1`) builds {@link XeniaEvent} instead.\n */\nexport function buildEventPayload(input: BuildEventInput): EventPayload {\n const passthrough: Record<string, JsonValue> = {};\n const reserved: Record<string, JsonValue> = {};\n if (input.props) {\n for (const [k, v] of Object.entries(input.props)) {\n if (v === undefined) continue;\n // A prop whose key matches a reserved field (e.g. `email`, `customerId`,\n // `utmSource`) is promoted to that first-class field; everything else is\n // custom passthrough data. Previously reserved-named props were dropped\n // outright — so `track(\"sign_up\", { email })` never sent `email` at all.\n if (RESERVED.has(k)) reserved[k] = v;\n else passthrough[k] = v;\n }\n }\n\n const payload = {\n ...passthrough,\n // Reserved-named props fill first-class fields (e.g. `email`, `customerId`)\n // the SDK didn't auto-collect. Auto-collected context/identity still win for\n // what they reliably know (real page url, visitor/device id), so a stray prop\n // can't override the true page context — see merge order below.\n ...reserved,\n ...compact((input.context ?? {}) as Record<string, JsonValue | undefined>),\n ...compact((input.identity ?? {}) as Record<string, JsonValue | undefined>),\n eventId: input.eventId,\n ...(input.eventType ? { eventType: input.eventType } : {}),\n ...(input.journeyId ? { journeyId: input.journeyId } : {}),\n };\n\n return payload as EventPayload;\n}\n","/** Crockford base32 alphabet (no I/L/O/U, avoids visual ambiguity) — used by ULID. */\nconst ENCODING = \"0123456789ABCDEFGHJKMNPQRSTVWXYZ\";\n\nfunction randomBytes(length: number): Uint8Array {\n const bytes = new Uint8Array(length);\n if (typeof crypto !== \"undefined\" && crypto.getRandomValues) {\n crypto.getRandomValues(bytes);\n } else {\n for (let i = 0; i < length; i++) bytes[i] = Math.floor(Math.random() * 256);\n }\n return bytes;\n}\n\n/**\n * Generate a ULID (Universally Unique Lexicographically Sortable Identifier):\n * a 48-bit timestamp (10 Crockford-base32 chars) + 80 bits of randomness (16\n * chars), 26 chars total — matches the backend's `eventId` field (`≤26`\n * chars). No dependency; implemented inline to keep the SDK lean.\n */\nexport function generateUlid(time: number = Date.now()): string {\n let timePart = \"\";\n let t = time;\n for (let i = 9; i >= 0; i--) {\n timePart = ENCODING[t % 32] + timePart;\n t = Math.floor(t / 32);\n }\n\n const random = randomBytes(16);\n let randomPart = \"\";\n for (let i = 0; i < 16; i++) {\n randomPart += ENCODING[random[i] % 32];\n }\n\n return timePart + randomPart;\n}\n\n/** Backend cap on `eventId` (`@Size(max = 26)`), which a ULID exactly fills. */\nexport const MAX_EVENT_ID_LENGTH = 26;\n\n/**\n * Coerce a caller-supplied dedup key into something the backend will accept.\n *\n * `eventId` is capped at 26 characters server-side, and an over-length value\n * rejects the ENTIRE batch it rides in — not just its own event. That is easy to\n * hit: `\"ord-\" + <uuid>` is 40. Rather than drop the caller's idempotency key or\n * let the batch 400, fold anything longer into a deterministic 26-char digest.\n * Deterministic is the point — the same order id always yields the same event id,\n * so re-firing it still de-dupes to one conversion, which is what the key is for.\n *\n * Truncation is deliberately not used: `\"ord-<uuid>\"` values share a long common\n * prefix, so cutting to 26 chars can map two different orders onto one id.\n */\nexport function toEventId(raw: string): string {\n if (raw.length <= MAX_EVENT_ID_LENGTH) return raw;\n\n // Two independently-seeded FNV-1a passes → 128 bits, encoded Crockford base32.\n let out = \"\";\n for (const seed of [0x811c9dc5, 0x01000193]) {\n let hash = seed >>> 0;\n for (let i = 0; i < raw.length; i++) {\n hash ^= raw.charCodeAt(i);\n hash = Math.imul(hash, 0x01000193) >>> 0;\n out += ENCODING[hash % 32];\n }\n }\n // Fold the accumulated stream down to exactly the cap, order-dependently.\n let digest = \"\";\n for (let i = 0; i < MAX_EVENT_ID_LENGTH; i++) {\n let acc = i + 1;\n for (let j = i; j < out.length; j += MAX_EVENT_ID_LENGTH) {\n acc = (acc * 31 + ENCODING.indexOf(out[j])) >>> 0;\n }\n digest += ENCODING[acc % 32];\n }\n return digest;\n}\n","/**\n * CMS page personalization — walk a fetched CMS page breadth-first, swap the\n * entries Xenia marked as personalized, and do it in as few round trips as\n * the page's nesting allows.\n *\n * Rules (see the \"Rounds\" section of the feature plan):\n * - **Static** targets carry their replacement in the payload (`xeniaVariants`)\n * and are swapped inline — no network at all.\n * - **Runtime** targets are a barrier: their id is collected, their subtree is\n * NOT walked (it may be replaced). One `resolve-entries` call decides every\n * target found in a round, one parallel CMS fetch loads every replacement,\n * and the next round walks whatever now sits at each position.\n * - Never throws: on error or when `timeoutMs` runs out, whatever is not yet\n * decided keeps its base content.\n *\n * CMS specifics live behind {@link CmsAdapter}; built-in adapters ship as\n * `@xenia-martech/sdk-js/cms/contentful` (and later `/cms/contentstack`). Any\n * other CMS works by implementing the interface.\n */\n\nimport type { EntryDecision, EntryQuery, EntrySwapOp, ResolveOptions } from \"./types\";\n\n/** Any value inside a CMS payload — the walker is shape-agnostic; adapters give it meaning. */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Node = any;\n\n/** The parsed `xenia` marker field of a personalized entry. */\nexport interface XeniaMarker {\n kind: \"static\" | \"runtime\";\n op?: EntrySwapOp;\n /** Array field replaced by `op: \"items\"`. */\n field?: string;\n limit?: number;\n /**\n * The content keys (Personalization Resolve identifiers) that personalize this entry. A page only\n * acts on markers that list its `contentKey`; a marker without keys is ignored.\n */\n keys?: string[];\n}\n\n/** What the page resolver needs to know about a CMS's entries. `N` is the entry shape. */\nexport interface CmsAdapter<N extends object = Node> {\n /** The entry id when `value` is a CMS entry (not a link stub, asset or plain object). */\n entryId(value: unknown): string | undefined;\n /** The entry's Xenia marker, or null when it is not personalized. */\n marker(entry: N): XeniaMarker | null;\n /** Static replacements pinned on the entry (its resolved `xeniaVariants`). */\n staticVariants(entry: N): N[];\n getField(entry: N, field: string): unknown;\n setField(entry: N, field: string, value: unknown): void;\n /** Legacy `items` without a field: copy the replacement's array fields onto the entry. */\n mergeItems?(entry: N, replacement: N): void;\n /**\n * Remove the marker from an entry that has been dealt with (kept base, or had its items replaced),\n * so personalizing the output again — e.g. the browser continuing a server render — never decides\n * it twice. Optional; without it a re-run re-asks Xenia about those entries.\n */\n clearMarker?(entry: N): void;\n /** Normalize a fetched payload before walking (e.g. resolve links). Defaults to identity. */\n prepare?(payload: unknown): unknown;\n /** Load entries by id in ONE call; order does not matter. */\n fetchEntries(ids: string[], locale?: string): Promise<N[]>;\n /** Run a content-type query in ONE call, in the query's order. */\n queryEntries(query: EntryQuery, locale?: string): Promise<N[]>;\n /**\n * Load one page with its whole tree (links resolved), or null when there is none. Optional; it\n * is what lets `personalizePage(ref)` do the fetch, so apps never fetch the page themselves.\n */\n fetchPage?(ref: PageRef, locale?: string): Promise<N | null>;\n}\n\n/** Identifies a page in the CMS: its entry id, or a content type plus exact field values (a slug). */\nexport type PageRef = string | { contentType: string; fields: Record<string, string | number | boolean> };\n\n/** Resolves a round's runtime targets — `XeniaApi.resolveEntries` bound to the visitor. */\nexport type EntryResolver = (entryIds: string[]) => Promise<EntryDecision[]>;\n\n/** Reported for every swap actually applied (for impressions / analytics). */\nexport interface AppliedSwap {\n target: string;\n kind: \"static\" | \"runtime\";\n op: EntrySwapOp;\n /** Ids of the entries now at the target's position (or in its field). */\n entryIds: string[];\n contentKey?: string;\n bucket?: string;\n round: number;\n}\n\nexport interface PersonalizeContentOptions {\n cms: CmsAdapter;\n /** Decides runtime targets. Omit to apply static swaps only (zero network). */\n resolve?: EntryResolver;\n locale?: string;\n /**\n * The page's Personalization Resolve identifier (required). Only that journey personalizes the\n * page: a marker that doesn't list this key is plain content, and the backend decides for this key\n * alone — another journey targeting the same section is neither consulted nor run.\n */\n contentKey: string;\n /** Max network rounds (nesting depth of runtime targets). Default 3. */\n maxRounds?: number;\n /** Total budget for all rounds, in ms. Undecided targets keep their base. Default 300. */\n timeoutMs?: number;\n /** Mutate the payload in place instead of personalizing a copy. Default false. */\n inPlace?: boolean;\n onApplied?(swap: AppliedSwap): void;\n /**\n * Called when a round starts waiting on the network (`pending` = targets being decided) and when\n * it has been applied (`pending` empty). `content` is the live, partially personalized tree —\n * lets a UI render level by level instead of waiting for every round.\n */\n onProgress?(progress: { content: unknown; round: number; pending: string[] }): void;\n}\n\n/** `personalizeContent` options as taken by `XeniaClient` / `XeniaServer`, which supply `resolve`. */\nexport type PagePersonalizeOptions = Omit<PersonalizeContentOptions, \"resolve\"> &\n Pick<ResolveOptions, \"data\" | \"identity\" | \"context\">;\n\nexport interface PersonalizeContentResult<T> {\n content: T;\n applied: AppliedSwap[];\n /** False when the budget ran out, a call failed, or `maxRounds` was hit with targets left. */\n complete: boolean;\n error?: unknown;\n}\n\nconst DEFAULT_TIMEOUT_MS = 300;\nconst DEFAULT_MAX_ROUNDS = 3;\n\n/** One place a value sits in the tree: `parent[key]`. Arrays are re-indexed by identity on write. */\ninterface Slot {\n parent: Node;\n key: string | number;\n value: Node;\n}\n\n/** What Xenia decided for an entry id, with the fetched replacements (copied per use). */\ninterface Decided {\n decision?: EntryDecision;\n items: Node[];\n}\n\nconst copyOf = (v: Node): Node =>\n v && typeof v === \"object\" && typeof structuredClone === \"function\" ? structuredClone(v) : v;\n\n/** A runtime target found in a round, at every place it appears (an entry may be shared). */\ninterface Pending {\n id: string;\n marker: XeniaMarker;\n entry: Node;\n slots: Slot[];\n}\n\nexport async function personalizeContent<T>(\n payload: T,\n options: PersonalizeContentOptions,\n): Promise<PersonalizeContentResult<T>> {\n const cms = scopedAdapter(options.cms, options.contentKey);\n const maxRounds = options.maxRounds ?? DEFAULT_MAX_ROUNDS;\n const deadline = Date.now() + (options.timeoutMs ?? DEFAULT_TIMEOUT_MS);\n const applied: AppliedSwap[] = [];\n const report = (swap: AppliedSwap) => {\n applied.push(swap);\n try {\n options.onApplied?.(swap);\n } catch {\n /* a broken analytics callback must never break rendering */\n }\n };\n\n let content: Node = payload;\n try {\n if (!options.inPlace && typeof structuredClone === \"function\") content = structuredClone(content);\n content = cms.prepare ? cms.prepare(content) : content;\n } catch (error) {\n return { content: payload, applied, complete: false, error };\n }\n\n const box = { root: content };\n // Entries whose own marker is already dealt with this call (kept base / swapped in) — walked as\n // plain content from now on so a target is never decided twice.\n const settled = new WeakSet<object>();\n // Decisions made in this call, by entry id. An entry that turns up again in a later round (a\n // shared entry inside a replacement) gets the same decision — consistent, and no second request.\n const decided = new Map<string, Decided>();\n let frontier: Slot[] = [{ parent: box, key: \"root\", value: box.root }];\n\n /** Apply a decision at a target's slots; returns what to walk next. */\n const settle = (target: Pending, d: Decided, round: number): Slot[] => {\n settled.add(target.entry);\n cms.clearMarker?.(target.entry);\n // A copy per use: fetched entries share objects (one CDA include graph), and a shared object\n // would be \"already settled\" wherever else it appears, hiding entries that are targets there.\n const items = d.items.map(copyOf);\n if (!d.decision || items.length === 0) {\n // Kept base: its subtree was never walked (barrier), so it is next round's frontier.\n return deferredSlots(target, cms);\n }\n for (const item of items) if (item && typeof item === \"object\") settled.add(item);\n const op = d.decision.op ?? target.marker.op ?? \"replace\";\n const next = apply(target, op, d.decision.field ?? target.marker.field, items, cms);\n report({\n target: target.id,\n kind: \"runtime\",\n op,\n entryIds: items.map((e) => cms.entryId(e)).filter((id): id is string => !!id),\n contentKey: d.decision.contentKey,\n bucket: d.decision.bucket,\n round,\n });\n return next;\n };\n\n for (let round = 0; ; round++) {\n const pending = walk(frontier, cms, settled, round, report, (t) => {\n const d = decided.get(t.id);\n return d ? settle(t, d, round) : undefined;\n });\n if (pending.size === 0) return { content: box.root, applied, complete: true };\n if (!options.resolve || round >= maxRounds) {\n return { content: box.root, applied, complete: !options.resolve };\n }\n progress(options, { content: box.root, round, pending: [...pending.keys()] });\n\n let decisions: EntryDecision[];\n let entriesById: Map<string, Node>;\n let queried: Map<EntryDecision, Node[]>;\n try {\n decisions = await withDeadline(options.resolve([...pending.keys()]), deadline);\n ({ entriesById, queried } = await withDeadline(loadReplacements(decisions, cms, options.locale), deadline));\n } catch (error) {\n return { content: box.root, applied, complete: false, error: error === TIMEOUT ? undefined : error };\n }\n\n const byTarget = new Map(decisions.map((d) => [d.target, d]));\n frontier = [];\n for (const target of pending.values()) {\n const decision = byTarget.get(target.id);\n const items = decision\n ? decision.ids\n ? decision.ids.map((id) => entriesById.get(id)).filter((e) => e !== undefined)\n : queried.get(decision) ?? []\n : [];\n const d: Decided = { decision, items };\n decided.set(target.id, d);\n frontier.push(...settle(target, d, round));\n }\n progress(options, { content: box.root, round, pending: [] });\n }\n}\n\nfunction progress(options: PersonalizeContentOptions, p: { content: unknown; round: number; pending: string[] }) {\n try {\n options.onProgress?.(p);\n } catch {\n /* UI callbacks must never break personalization */\n }\n}\n\n/**\n * Breadth-first walk of `frontier`: applies static swaps inline, collects runtime targets (without\n * descending into them) and returns them keyed by entry id.\n */\nfunction walk(\n frontier: Slot[],\n cms: CmsAdapter,\n settled: WeakSet<object>,\n round: number,\n report: (swap: AppliedSwap) => void,\n /** Applies an earlier decision for this entry id inline; undefined when it hasn't been decided. */\n reuse: (target: Pending) => Slot[] | undefined,\n): Map<string, Pending> {\n const pending = new Map<string, Pending>();\n const seen = new WeakSet<object>();\n // Fields held back by a runtime `items` target, wherever the CMS nests them (Contentful: `fields.x`).\n const deferred = new WeakSet<object>();\n const queue: Slot[] = [...frontier];\n\n while (queue.length > 0) {\n const slot = queue.shift()!;\n const value = slot.value;\n if (!value || typeof value !== \"object\" || deferred.has(value)) continue;\n\n const id = settled.has(value) ? undefined : cms.entryId(value);\n const marker = id ? cms.marker(value) : null;\n\n if (id && marker?.kind === \"runtime\") {\n const again = reuse({ id, marker, entry: value, slots: [slot] });\n if (again) {\n queue.push(...again);\n continue;\n }\n const existing = pending.get(id);\n if (existing) {\n existing.slots.push(slot);\n } else {\n pending.set(id, { id, marker, entry: value, slots: [slot] });\n // `items` only defers the replaced field; the entry's other fields are walked now.\n if (marker.op === \"items\" && marker.field) {\n const held = cms.getField(value, marker.field);\n if (held && typeof held === \"object\") deferred.add(held);\n queue.push(...children(value));\n }\n }\n continue;\n }\n\n if (id && marker?.kind === \"static\") {\n const variants = cms.staticVariants(value).filter((v) => v && typeof v === \"object\");\n settled.add(value);\n cms.clearMarker?.(value);\n if (variants.length > 0) {\n for (const v of variants) settled.add(v);\n const op = marker.op ?? \"replace\";\n const target: Pending = { id, marker, entry: value, slots: [slot] };\n queue.push(...apply(target, op, marker.field, variants, cms));\n report({\n target: id,\n kind: \"static\",\n op,\n entryIds: variants.map((v) => cms.entryId(v)).filter((x): x is string => !!x),\n round,\n });\n continue;\n }\n // A static marker with nothing pinned (write-back pending) is just base content.\n }\n\n if (seen.has(value)) continue;\n seen.add(value);\n queue.push(...children(value));\n }\n return pending;\n}\n\n/** Splice `items` in for `target` at all its slots; returns the new content to walk next. */\nfunction apply(target: Pending, op: EntrySwapOp, field: string | undefined, items: Node[], cms: CmsAdapter): Slot[] {\n if (op === \"items\") {\n if (field) {\n cms.setField(target.entry, field, items);\n return [{ parent: target.entry, key: field, value: cms.getField(target.entry, field) }];\n }\n if (cms.mergeItems) {\n cms.mergeItems(target.entry, items[0]);\n return target.slots.map((s) => ({ ...s, value: target.entry }));\n }\n op = \"replace\"; // no merge support → closest meaning\n }\n\n const next: Slot[] = [];\n for (const slot of target.slots) {\n const placed = op === \"expand\" && Array.isArray(slot.parent) ? items : [items[0]];\n if (Array.isArray(slot.parent)) {\n const index = slot.parent.indexOf(target.entry);\n if (index < 0) continue;\n slot.parent.splice(index, 1, ...placed);\n } else {\n slot.parent[slot.key] = placed[0];\n }\n for (const value of placed) next.push({ parent: slot.parent, key: slot.key, value });\n }\n return next;\n}\n\n/** What still needs walking under a target that kept its base content. */\nfunction deferredSlots(target: Pending, cms: CmsAdapter): Slot[] {\n if (target.marker.op === \"items\" && target.marker.field) {\n return [{ parent: target.entry, key: target.marker.field, value: cms.getField(target.entry, target.marker.field) }];\n }\n return target.slots.map((s) => ({ ...s, value: target.entry }));\n}\n\nfunction children(value: Node): Slot[] {\n if (Array.isArray(value)) return value.map((v, i) => ({ parent: value, key: i, value: v }));\n return Object.keys(value).map((k) => ({ parent: value, key: k, value: value[k] }));\n}\n\n/** One `fetchEntries` call for every explicit id, plus one query per content-type decision — all in parallel. */\nasync function loadReplacements(decisions: EntryDecision[], cms: CmsAdapter, locale?: string) {\n const ids = [...new Set(decisions.flatMap((d) => d.ids ?? []))];\n const queries = decisions.filter((d) => !d.ids && d.query);\n const [fetched, ...results] = await Promise.all([\n ids.length > 0 ? cms.fetchEntries(ids, locale) : Promise.resolve([]),\n ...queries.map((d) => cms.queryEntries(d.query!, locale).catch(() => [] as Node[])),\n ]);\n const entriesById = new Map<string, Node>();\n for (const entry of fetched) {\n const id = cms.entryId(entry);\n if (id) entriesById.set(id, entry);\n }\n const queried = new Map<EntryDecision, Node[]>();\n queries.forEach((d, i) => queried.set(d, results[i]!));\n return { entriesById, queried };\n}\n\nconst TIMEOUT = Symbol(\"timeout\");\n\nfunction withDeadline<T>(promise: Promise<T>, deadline: number): Promise<T> {\n const remaining = deadline - Date.now();\n if (remaining <= 0) return Promise.reject(TIMEOUT);\n let timer: ReturnType<typeof setTimeout>;\n return Promise.race([\n promise,\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(TIMEOUT), remaining);\n }),\n ]).finally(() => clearTimeout(timer));\n}\n\n/**\n * The entries Xenia still has to decide on this page — runtime targets reachable without crossing\n * another undecided one. Synchronous and network-free (it reads the `xenia` markers), so a page can\n * render a skeleton in exactly those places from the first frame instead of flashing base content.\n * Nested targets inside a pending one are found once it is decided.\n */\nexport function pendingTargets(payload: unknown, adapter: CmsAdapter, contentKey: string): string[] {\n const cms = scopedAdapter(adapter, contentKey);\n try {\n let content: Node = typeof structuredClone === \"function\" ? structuredClone(payload) : payload;\n content = cms.prepare ? cms.prepare(content) : content;\n const root = { parent: { root: content }, key: \"root\", value: content };\n // On a copy: the walk applies static swaps inline, which must not touch the caller's page.\n return [...walk([root], cms, new WeakSet(), 0, () => {}, () => undefined).keys()];\n } catch {\n return [];\n }\n}\n\n/**\n * The adapter as the page's journey sees it: only markers that list `contentKey` count. Any other\n * marker — another journey's, or one without keys — is plain content: no static swap, no request,\n * no pending skeleton, and its children are walked as usual.\n */\nfunction scopedAdapter(cms: CmsAdapter, contentKey: string | undefined): CmsAdapter {\n return {\n ...cms,\n marker(entry) {\n const m = cms.marker(entry);\n return m && contentKey && m.keys?.includes(contentKey) ? m : null;\n },\n };\n}\n\n/**\n * Fetch a page through `options.cms` and personalize it — {@link personalizeContent} without the\n * fetch in app code. Never throws: a failed fetch comes back as `content: null` with `error`; a page\n * that does not exist as `content: null`, `complete: true`. The page fetch is not counted against\n * `timeoutMs` — that budget is for personalization only.\n */\nexport async function personalizePage<T>(\n ref: PageRef,\n options: PersonalizeContentOptions,\n): Promise<PersonalizeContentResult<T | null>> {\n let page: unknown;\n try {\n if (!options.cms.fetchPage) throw new Error(\"This CMS adapter cannot fetch pages; use personalizeContent(page)\");\n page = await options.cms.fetchPage(ref, options.locale);\n } catch (error) {\n return { content: null, applied: [], complete: false, error };\n }\n if (page == null) return { content: null, applied: [], complete: true };\n return personalizeContent(page as T, options);\n}\n","import type { WebhookResponse } from \"./types\";\n\n/**\n * Persists webhook responses the SDK receives, keyed by an arbitrary string\n * (typically the eventId, triggerId, or journeyId). Lets the app read back the\n * last server response for a given interaction without re-firing it.\n */\nexport interface ResponseStore {\n set(key: string, value: WebhookResponse): void;\n get(key: string): WebhookResponse | undefined;\n keys(): string[];\n clear(): void;\n}\n\n/** In-memory store. Default; lost on reload. */\nexport class MemoryResponseStore implements ResponseStore {\n private readonly map = new Map<string, WebhookResponse>();\n\n set(key: string, value: WebhookResponse): void {\n this.map.set(key, value);\n }\n get(key: string): WebhookResponse | undefined {\n return this.map.get(key);\n }\n keys(): string[] {\n return [...this.map.keys()];\n }\n clear(): void {\n this.map.clear();\n }\n}\n\n/**\n * localStorage-backed store — survives reloads. Falls back to memory semantics\n * (silent no-op reads/writes) when localStorage is unavailable or throws.\n */\nexport class LocalStorageResponseStore implements ResponseStore {\n private readonly nsKey: string;\n\n constructor(prefix = \"xenia\") {\n this.nsKey = `${prefix}_responses`;\n }\n\n private read(): Record<string, WebhookResponse> {\n try {\n const raw = localStorage.getItem(this.nsKey);\n return raw ? (JSON.parse(raw) as Record<string, WebhookResponse>) : {};\n } catch {\n return {};\n }\n }\n\n private write(data: Record<string, WebhookResponse>): void {\n try {\n localStorage.setItem(this.nsKey, JSON.stringify(data));\n } catch {\n /* storage full / unavailable — ignore */\n }\n }\n\n set(key: string, value: WebhookResponse): void {\n const data = this.read();\n data[key] = value;\n this.write(data);\n }\n get(key: string): WebhookResponse | undefined {\n return this.read()[key];\n }\n keys(): string[] {\n return Object.keys(this.read());\n }\n clear(): void {\n try {\n localStorage.removeItem(this.nsKey);\n } catch {\n /* ignore */\n }\n }\n}\n","import { HttpError } from \"../core/http-client\";\nimport type { XeniaEvent } from \"../core/types\";\n\nexport interface AnalyticsQueueOptions {\n /** Injected sender — normally `XeniaApi.sendEvents` bound to an instance. */\n send: (events: XeniaEvent[], opts?: { keepalive?: boolean }) => Promise<unknown>;\n /** Flush once this many events are queued. Default 20. */\n batchSize?: number;\n /** Flush at least this often, in ms. Default 3000. */\n flushIntervalMs?: number;\n /** Hard cap on in-memory events — oldest are dropped past this. Default 200. */\n maxQueueSize?: number;\n debug?: boolean;\n}\n\n/**\n * In-memory batching queue for `POST /api/events/v1`. Analytics\n * ingestion is best-effort: events are never persisted (no offline/localStorage\n * buffer). A batch that fails with a transient error (after `HttpClient`'s own\n * retry/backoff is exhausted) is requeued for the next flush tick, bounded by\n * `maxQueueSize` — under a sustained outage, oldest events are dropped rather\n * than growing memory unboundedly or retrying forever. A batch rejected with a\n * permanent 4xx (e.g. failed identity validation) is dropped immediately\n * instead — the payload will never become valid by resending it unchanged.\n */\nexport class AnalyticsQueue {\n private queue: XeniaEvent[] = [];\n private readonly send: AnalyticsQueueOptions[\"send\"];\n private readonly batchSize: number;\n private readonly flushIntervalMs: number;\n private readonly maxQueueSize: number;\n private readonly debug: boolean;\n private timer: ReturnType<typeof setInterval> | null = null;\n private flushing = false;\n private listenersAttached = false;\n /**\n * Gate on every send path (batchSize-triggered, timer, and unload flush) —\n * set only by `start()`/`stop()`. Events still `enqueue()` (and accumulate,\n * capped) while `false`, so nothing fired before consent is lost; nothing is\n * actually sent over the network until `start()` is called.\n */\n private allowed = false;\n\n private readonly onPageHide = (): void => this.flushOnUnload();\n private readonly onVisibilityChange = (): void => {\n if (document.visibilityState === \"hidden\") this.flushOnUnload();\n };\n\n constructor(opts: AnalyticsQueueOptions) {\n this.send = opts.send;\n this.batchSize = opts.batchSize ?? 20;\n this.flushIntervalMs = opts.flushIntervalMs ?? 3000;\n this.maxQueueSize = opts.maxQueueSize ?? 200;\n this.debug = opts.debug ?? false;\n }\n\n /** Allow sending, and start the periodic flush timer + unload listeners. Idempotent. */\n start(): void {\n this.allowed = true;\n if (this.timer || typeof window === \"undefined\") return;\n this.timer = setInterval(() => void this.flush(), this.flushIntervalMs);\n window.addEventListener(\"pagehide\", this.onPageHide);\n document.addEventListener(\"visibilitychange\", this.onVisibilityChange);\n this.listenersAttached = true;\n }\n\n /** Disallow sending and stop the timer/listeners. Queued events are kept, not flushed. */\n stop(): void {\n this.allowed = false;\n if (this.timer) clearInterval(this.timer);\n this.timer = null;\n if (this.listenersAttached) {\n window.removeEventListener(\"pagehide\", this.onPageHide);\n document.removeEventListener(\"visibilitychange\", this.onVisibilityChange);\n this.listenersAttached = false;\n }\n }\n\n /** Queue an event. Flushes immediately once `batchSize` is reached (if allowed). */\n enqueue(event: XeniaEvent): void {\n if (this.queue.length >= this.maxQueueSize) this.queue.shift();\n this.queue.push(event);\n if (this.allowed && this.queue.length >= this.batchSize) void this.flush();\n }\n\n /**\n * Send one event right now, bypassing the consent gate and the batch window —\n * used for journey triggers, which are latency-sensitive and must fire even\n * before analytics consent is granted (the backend still consent-gates the\n * analytics half server-side). Reuses the same 4xx-drop / transient-requeue\n * policy as {@link flush}: a permanent 4xx is dropped, anything transient is\n * requeued for a later flush tick.\n *\n * Sent with `keepalive` because the canonical trigger is a declarative\n * `data-xenia=\"<eventId>&click\"` on a link or submit button: the click starts a\n * navigation that tears the document down, and a normal fetch is cancelled with\n * it — losing exactly the events a journey is waiting on. `keepalive` lets the\n * request outlive the document (same reason {@link flushOnUnload} uses it).\n */\n async sendImmediate(event: XeniaEvent): Promise<void> {\n try {\n await this.send([event], { keepalive: true });\n } catch (err) {\n if (!this.isPermanentFailure(err)) this.requeue([event]);\n if (this.debug) console.warn(\"[xenia] immediate send failed\", err);\n }\n }\n\n /** Send up to `batchSize` queued events. No-op if not allowed, already flushing, or empty. */\n async flush(): Promise<void> {\n if (!this.allowed || this.flushing || this.queue.length === 0) return;\n this.flushing = true;\n const batch = this.queue.splice(0, this.batchSize);\n try {\n await this.send(batch);\n } catch (err) {\n // A 4xx means the backend permanently rejected this exact payload (e.g.\n // failed identity validation) — HttpClient already retried anything\n // transient (429/5xx/network errors) before giving up, so requeuing a\n // 4xx would just resend the same invalid batch forever, jamming the\n // queue behind it. Drop it; requeue everything else for the next tick.\n if (!this.isPermanentFailure(err)) this.requeue(batch);\n if (this.debug) console.warn(\"[xenia] analytics flush failed\", err);\n } finally {\n this.flushing = false;\n }\n }\n\n private isPermanentFailure(err: unknown): boolean {\n return err instanceof HttpError && err.status >= 400 && err.status < 500;\n }\n\n /** Best-effort synchronous-ish flush of everything queued, for `pagehide`/hidden. */\n private flushOnUnload(): void {\n if (!this.allowed || this.queue.length === 0) return;\n const batch = this.queue.splice(0, this.queue.length);\n void this.send(batch, { keepalive: true }).catch(() => {\n /* page is unloading — nothing left to recover into */\n });\n }\n\n private requeue(batch: XeniaEvent[]): void {\n const room = this.maxQueueSize - this.queue.length;\n if (room <= 0) return;\n this.queue.unshift(...batch.slice(0, room));\n }\n}\n","import type { InteractionType } from \"../core/types\";\n\nconst VALID: ReadonlySet<InteractionType> = new Set<InteractionType>([\n \"click\",\n \"view-port\",\n \"page-load\",\n]);\n\ninterface Parsed {\n eventId: string;\n interactionType: InteractionType;\n}\n\n/** Parse `data-<prefix>=\"<eventId>&<interactionType>\"`. */\nexport function parseDataAttribute(value: string): Parsed | null {\n const sep = value.indexOf(\"&\");\n if (sep === -1) return null;\n const eventId = value.slice(0, sep);\n const interactionType = value.slice(sep + 1) as InteractionType;\n if (!eventId || !VALID.has(interactionType)) return null;\n return { eventId, interactionType };\n}\n\n/** Personalization slot metadata read from `data-xenia-*` attributes. */\nexport interface SlotMeta {\n contentKey: string;\n contentEntryId?: string;\n baseEntryId?: string;\n personalized?: boolean;\n}\n\nexport interface AutoTrackOptions {\n prefix: string;\n throttleMs: number;\n viewport: { threshold: number; rootMargin?: string; triggerOnce: boolean };\n /** Fire an auto-tracked journey event (`data-xenia=\"<eventId>&<type>\"`). */\n fire: (eventId: string, interactionType: InteractionType) => void;\n /**\n * Fire a personalization slot event (`[data-xenia-slot]`) — `impression` on\n * first viewport entry (once), `click` on click. Optional: when omitted, slot\n * scanning is skipped entirely.\n */\n fireSlot?: (interaction: \"impression\" | \"click\", meta: SlotMeta) => void;\n}\n\n/** Read the resolve metadata attributes off a `[data-xenia-slot]` element. */\nexport function readSlotMeta(el: Element): SlotMeta | null {\n const contentKey = el.getAttribute(\"data-xenia-content-key\");\n if (!contentKey) return null;\n const contentEntryId = el.getAttribute(\"data-xenia-content-entry-id\");\n const baseEntryId = el.getAttribute(\"data-xenia-base-entry-id\");\n const personalized = el.getAttribute(\"data-xenia-personalized\");\n return {\n contentKey,\n contentEntryId: contentEntryId ?? undefined,\n baseEntryId: baseEntryId ?? undefined,\n personalized: personalized == null ? undefined : personalized === \"true\",\n };\n}\n\n/**\n * Wires declarative `data-xenia` auto-tracking: delegated clicks, an\n * IntersectionObserver for `view-port`, immediate `page-load`, and a\n * MutationObserver so elements added later are tracked too. Ported from\n * `xenia-tracker.iife.js`.\n *\n * Also scans `[data-xenia-slot]` personalization slots (when `fireSlot` is set):\n * a viewport-once `impression` and click `click`, both read from the resolve\n * metadata attrs (`data-xenia-content-key` / `-content-entry-id` /\n * `-base-entry-id` / `-personalized`).\n */\nexport class AutoTracker {\n private readonly opts: AutoTrackOptions;\n private readonly throttleTimers = new Map<Element, number>();\n private readonly observers = new Map<Element, IntersectionObserver>();\n private readonly slotObservers = new Map<Element, IntersectionObserver>();\n private readonly triggered = new Set<Element>();\n private readonly slotImpressed = new Set<Element>();\n private clickHandler: ((e: MouseEvent) => void) | null = null;\n private mutationObserver: MutationObserver | null = null;\n\n constructor(opts: AutoTrackOptions) {\n this.opts = opts;\n }\n\n start(): void {\n this.setupClicks();\n this.scan(document);\n this.setupMutations();\n }\n\n stop(): void {\n if (this.clickHandler) document.removeEventListener(\"click\", this.clickHandler);\n this.clickHandler = null;\n this.mutationObserver?.disconnect();\n this.mutationObserver = null;\n this.observers.forEach((o) => o.disconnect());\n this.observers.clear();\n this.slotObservers.forEach((o) => o.disconnect());\n this.slotObservers.clear();\n this.throttleTimers.clear();\n this.triggered.clear();\n this.slotImpressed.clear();\n }\n\n private attr(): string {\n return `data-${this.opts.prefix}`;\n }\n\n private throttled(el: Element): boolean {\n if (this.opts.throttleMs <= 0) return false;\n const now = Date.now();\n const last = this.throttleTimers.get(el) ?? 0;\n if (now - last >= this.opts.throttleMs) {\n this.throttleTimers.set(el, now);\n return false;\n }\n return true;\n }\n\n private setupClicks(): void {\n const attr = this.attr();\n this.clickHandler = (event: MouseEvent) => {\n const target = event.target as Element | null;\n if (!target) return;\n\n // Journey trigger click (`data-xenia=\"<eventId>&click\"`).\n const el = target.closest(`[${attr}]`);\n if (el) {\n const raw = el.getAttribute(attr);\n const parsed = raw ? parseDataAttribute(raw) : null;\n if (parsed && parsed.interactionType === \"click\" && !this.throttled(el)) {\n this.opts.fire(parsed.eventId, \"click\");\n }\n }\n\n // Personalization slot click (`[data-xenia-slot]`).\n if (this.opts.fireSlot) {\n const slot = target.closest(\"[data-xenia-slot]\");\n if (slot) {\n const meta = readSlotMeta(slot);\n if (meta && !this.throttled(slot)) this.opts.fireSlot(\"click\", meta);\n }\n }\n };\n document.addEventListener(\"click\", this.clickHandler);\n }\n\n private observeSlot(el: Element): void {\n if (!this.opts.fireSlot || this.slotObservers.has(el)) return;\n const meta = readSlotMeta(el);\n // No resolve metadata yet → not a resolved slot; skip (it'll be re-scanned\n // if replaced with a fresh node carrying the attrs).\n if (!meta) return;\n const fireSlot = this.opts.fireSlot;\n const { threshold, rootMargin } = this.opts.viewport;\n const observer = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n if (!entry.isIntersecting) continue;\n if (this.slotImpressed.has(el)) continue;\n this.slotImpressed.add(el);\n fireSlot(\"impression\", meta);\n observer.disconnect();\n this.slotObservers.delete(el);\n }\n },\n { threshold, rootMargin },\n );\n observer.observe(el);\n this.slotObservers.set(el, observer);\n }\n\n private observeViewport(el: Element, eventId: string): void {\n if (this.observers.has(el)) return;\n const { threshold, rootMargin, triggerOnce } = this.opts.viewport;\n const observer = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n if (!entry.isIntersecting) continue;\n if (triggerOnce && this.triggered.has(el)) continue;\n if (this.throttled(el)) continue;\n this.opts.fire(eventId, \"view-port\");\n if (triggerOnce) {\n this.triggered.add(el);\n observer.disconnect();\n this.observers.delete(el);\n }\n }\n },\n { threshold, rootMargin },\n );\n observer.observe(el);\n this.observers.set(el, observer);\n }\n\n private handleElement(el: Element): void {\n const raw = el.getAttribute(this.attr());\n if (!raw) return;\n const parsed = parseDataAttribute(raw);\n if (!parsed) return;\n if (parsed.interactionType === \"view-port\") this.observeViewport(el, parsed.eventId);\n else if (parsed.interactionType === \"page-load\") this.opts.fire(parsed.eventId, \"page-load\");\n }\n\n private scan(root: ParentNode): void {\n root.querySelectorAll(`[${this.attr()}]`).forEach((el) => this.handleElement(el));\n if (this.opts.fireSlot) {\n root.querySelectorAll(\"[data-xenia-slot]\").forEach((el) => this.observeSlot(el));\n }\n }\n\n private setupMutations(): void {\n this.mutationObserver = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n for (const node of mutation.addedNodes) {\n if (node.nodeType !== Node.ELEMENT_NODE) continue;\n const el = node as Element;\n this.handleElement(el);\n if (this.opts.fireSlot && el.matches(\"[data-xenia-slot]\")) this.observeSlot(el);\n this.scan(el);\n }\n }\n });\n this.mutationObserver.observe(document.body, { childList: true, subtree: true });\n }\n}\n","import {\n CONSENT_COOKIE,\n VISITOR_COOKIE,\n consentCookie,\n consentCookieName,\n visitorCookieName,\n} from \"../core/cookie-names\";\nimport type { ConsentState } from \"../core/types\";\n\n/**\n * Cookie names the SDK reads server-side (set by the browser SDK / your app).\n *\n * The constants are the DEFAULT-prefix names; the functions build the name for any prefix. If you\n * pass `config.prefix` to the browser client, pass the same prefix here — the browser namespaces\n * the cookie by it, so the default name won't be there to find.\n */\nexport { CONSENT_COOKIE, VISITOR_COOKIE, consentCookie, consentCookieName, visitorCookieName };\n\n/**\n * Parse a raw `Cookie` header into a map. Framework-agnostic so it works with\n * `Request.headers.get(\"cookie\")`, Node `req.headers.cookie`, etc.\n */\nexport function parseCookies(header: string | null | undefined): Record<string, string> {\n const out: Record<string, string> = {};\n if (!header) return out;\n for (const part of header.split(\";\")) {\n const idx = part.indexOf(\"=\");\n if (idx === -1) continue;\n const key = part.slice(0, idx).trim();\n const value = part.slice(idx + 1).trim();\n if (key) out[key] = decodeURIComponent(value);\n }\n return out;\n}\n\n/**\n * Read the visitor id the browser SDK wrote, so a server-side event can be bound to the same\n * visitor (`createXeniaServer({ visitorId })`) and attribute to a browser-entered journey.\n *\n * @param prefix Must match the browser client's `config.prefix`. The cookie is namespaced by it, so\n * a mismatch finds nothing and quietly leaves the server with no visitor.\n */\nexport function getVisitorId(\n cookieHeader: string | null | undefined,\n prefix?: string,\n): string | null {\n return parseCookies(cookieHeader)[visitorCookieName(prefix)] ?? null;\n}\n\n/**\n * Read consent from a cookie header. Accepts a JSON blob or a comma-list of\n * granted scopes (e.g. `analytics,personalization`). Absent → all denied.\n *\n * @param prefix Must match the browser client's `config.prefix` — see {@link getVisitorId}.\n */\nexport function getConsent(\n cookieHeader: string | null | undefined,\n prefix?: string,\n): ConsentState {\n const raw = parseCookies(cookieHeader)[consentCookieName(prefix)];\n if (!raw) return { analytics: false, marketing: false, personalization: false };\n try {\n const parsed = JSON.parse(raw) as ConsentState;\n return parsed;\n } catch {\n const scopes = new Set(raw.split(\",\").map((s) => s.trim()));\n return {\n analytics: scopes.has(\"analytics\"),\n marketing: scopes.has(\"marketing\"),\n personalization: scopes.has(\"personalization\"),\n };\n }\n}\n","import { visitorCookieName } from \"../core/cookie-names\";\nimport { parseCookies } from \"../server/cookies\";\nimport { generateUlid } from \"../core/id\";\nimport type { EventContext, VisitorCookieOptions } from \"../core/types\";\n\n/** Session expires after this much inactivity (ms). */\nconst SESSION_TIMEOUT_MS = 30 * 60 * 1000;\n\n/** Resolved visitor-cookie settings, or null when disabled. */\ntype CookieConfig = Required<Omit<VisitorCookieOptions, \"domain\">> & { domain?: string };\n\n/**\n * Browser identity + context manager.\n *\n * Owns the device id, visitor id, session id, UTM capture/persistence, and\n * journey attribution — all the ambient signals the SDK attaches to events so\n * the developer never has to. Ported from the production `xenia-tracker.iife.js`.\n */\nexport class Identity {\n private readonly prefix: string;\n private readonly cookie: CookieConfig | null;\n private deviceId: string | null = null;\n private journeyId: string | null = null;\n private sessionId: string | null = null;\n\n constructor(prefix = \"xenia\", visitorCookie: boolean | VisitorCookieOptions = true) {\n this.prefix = prefix;\n this.cookie = resolveCookieConfig(visitorCookie);\n }\n\n private key(name: string): string {\n return `${this.prefix}_${name}`;\n }\n\n /**\n * The visitor cookie name, namespaced by `config.prefix` so two Xenia apps on one domain keep\n * separate visitors. Built with the SHARED helper the server half also uses\n * (`visitorCookieName`) — the two runtimes have to derive this identically, or the server looks\n * for a cookie the browser never wrote and silently ends up with no visitor, which quietly breaks\n * attribution for server-side conversions.\n */\n private cookieName(): string {\n return visitorCookieName(this.prefix);\n }\n\n /**\n * Persist the effective visitor id to a first-party cookie so same-origin\n * server code can read it (server SDK `getVisitorId(cookieHeader)`) and bind\n * the SAME visitor — the link that lets a server-side conversion attribute to\n * a browser-entered journey. No-op when disabled or off-DOM.\n */\n private writeVisitorCookie(id: string | null | undefined): void {\n if (!this.cookie || !id) return;\n try {\n if (typeof document === \"undefined\") return;\n const parts = [\n `${this.cookieName()}=${encodeURIComponent(id)}`,\n \"path=/\",\n `max-age=${Math.floor(this.cookie.maxAgeDays * 86400)}`,\n `SameSite=${this.cookie.sameSite}`,\n ];\n if (this.cookie.domain) parts.push(`domain=${this.cookie.domain}`);\n if (this.cookie.secure) parts.push(\"Secure\");\n document.cookie = parts.join(\"; \");\n } catch {\n /* document.cookie unavailable */\n }\n }\n\n /** The visitor id already in the cookie — e.g. minted by `xeniaProxy()` on the first request. */\n private readVisitorCookie(): string | null {\n if (!this.cookie || typeof document === \"undefined\") return null;\n try {\n return parseCookies(document.cookie)[this.cookieName()] || null;\n } catch {\n return null;\n }\n }\n\n // ── Device id ────────────────────────────────────────────────────────────\n\n /**\n * Resolve a stable device id: localStorage cache → the visitor cookie a server already set →\n * MediaDevices → SHA-256 browser fingerprint. Cached for the session and across reloads.\n */\n async resolveDeviceId(): Promise<string> {\n if (this.deviceId) {\n this.writeVisitorCookie(this.getVisitorId() ?? this.deviceId);\n return this.deviceId;\n }\n const storageKey = this.key(\"device_id\");\n try {\n const cached = localStorage.getItem(storageKey);\n if (cached) {\n this.deviceId = cached;\n this.writeVisitorCookie(this.getVisitorId() ?? cached);\n return cached;\n }\n } catch {\n /* localStorage unavailable */\n }\n\n // Join the visitor the server already set instead of minting a second id: overwriting it would\n // turn one person into two visitors mid-visit — server-side decisions, A/B groups and journey\n // attribution recorded for the first id would no longer apply.\n let id = this.readVisitorCookie();\n if (!id) id = await this.mediaDeviceId();\n if (!id) id = await this.fingerprint();\n\n this.deviceId = id;\n try {\n localStorage.setItem(storageKey, id);\n } catch {\n /* ignore */\n }\n // Persist the effective visitor id (explicit visitor id if set, else this\n // device id) to the cookie so same-origin server calls resolve the same one.\n this.writeVisitorCookie(this.getVisitorId() ?? id);\n return id;\n }\n\n getDeviceId(): string | null {\n return this.deviceId;\n }\n\n private async mediaDeviceId(): Promise<string | null> {\n try {\n if (!navigator.mediaDevices?.enumerateDevices) return null;\n const devices = await navigator.mediaDevices.enumerateDevices();\n const device =\n devices.find((d) => d.kind === \"videoinput\" && d.deviceId) ||\n devices.find((d) => d.kind === \"audioinput\" && d.deviceId) ||\n devices.find((d) => d.kind === \"audiooutput\" && d.deviceId);\n return device?.deviceId || null;\n } catch {\n return null;\n }\n }\n\n private async fingerprint(): Promise<string> {\n const raw = [\n navigator.userAgent,\n navigator.language,\n screen.width,\n screen.height,\n screen.colorDepth,\n new Date().getTimezoneOffset(),\n ].join(\"|\");\n const buffer = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(raw));\n return Array.from(new Uint8Array(buffer))\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n\n // ── Visitor id ─────────────────────────────────────────────────────────────\n\n /** Persist a visitor id so it rides on every future event. */\n identify(visitorId: string): void {\n if (!visitorId) return;\n try {\n localStorage.setItem(this.key(\"visitor_id\"), visitorId);\n } catch {\n /* ignore */\n }\n this.writeVisitorCookie(visitorId);\n }\n\n getVisitorId(): string | null {\n try {\n return localStorage.getItem(this.key(\"visitor_id\"));\n } catch {\n return null;\n }\n }\n\n // ── Customer id / email ──────────────────────────────────────────────────\n //\n // Ambient, persisted the same way as the visitor id, so a value set once\n // (typically alongside `identify()`) rides on every later `resolve()` call\n // without the caller having to pass it again — the SDK-provided-fields\n // parity list on the Personalization Resolve trigger includes both.\n\n setCustomerId(customerId: string | null): void {\n try {\n if (customerId) localStorage.setItem(this.key(\"customer_id\"), customerId);\n else localStorage.removeItem(this.key(\"customer_id\"));\n } catch {\n /* ignore */\n }\n }\n\n getCustomerId(): string | null {\n try {\n return localStorage.getItem(this.key(\"customer_id\"));\n } catch {\n return null;\n }\n }\n\n setEmail(email: string | null): void {\n try {\n if (email) localStorage.setItem(this.key(\"email\"), email);\n else localStorage.removeItem(this.key(\"email\"));\n } catch {\n /* ignore */\n }\n }\n\n getEmail(): string | null {\n try {\n return localStorage.getItem(this.key(\"email\"));\n } catch {\n return null;\n }\n }\n\n // ── Session id ───────────────────────────────────────────────────────────────\n\n /**\n * Resolve the current session id: reused while activity continues within\n * {@link SESSION_TIMEOUT_MS}, otherwise a new one is minted. Persisted in\n * `sessionStorage` (survives reloads/navigation within the tab, not across\n * tabs or after the timeout) so events sent from other `Identity` instances\n * in the same tab share one session.\n */\n getSessionId(): string {\n const idKey = this.key(\"session_id\");\n const lastActivityKey = this.key(\"session_last_activity\");\n const now = Date.now();\n\n try {\n const storedId = sessionStorage.getItem(idKey);\n const lastActivity = Number(sessionStorage.getItem(lastActivityKey));\n const fresh = storedId && Number.isFinite(lastActivity) && now - lastActivity < SESSION_TIMEOUT_MS;\n const id = fresh ? storedId : generateUlid(now);\n sessionStorage.setItem(idKey, id);\n sessionStorage.setItem(lastActivityKey, String(now));\n this.sessionId = id;\n return id;\n } catch {\n /* sessionStorage unavailable — degrade to one id per page load (no cross-reload persistence, no timeout enforcement) */\n if (!this.sessionId) this.sessionId = generateUlid(now);\n return this.sessionId;\n }\n }\n\n // ── Journey attribution ─────────────────────────────────────────────────────\n\n /** Manually set the customer-journey UUID for this session (overrides utm_id). */\n setJourneyId(id: string | null): void {\n this.journeyId = id && id.trim() ? id.trim() : null;\n }\n\n /** Effective journey id: manual override > utm_id (URL/sessionStorage). */\n getJourneyId(): string | null {\n return this.journeyId || this.utmParam(\"utm_id\") || null;\n }\n\n // ── UTM + page context ───────────────────────────────────────────────────\n\n /** Read a UTM param from the URL, persisting it so it survives navigation. */\n private utmParam(name: string): string | null {\n try {\n const val = new URLSearchParams(window.location.search).get(name);\n if (val) {\n try {\n sessionStorage.setItem(this.key(name), val);\n } catch {\n /* ignore */\n }\n return val;\n }\n try {\n return sessionStorage.getItem(this.key(name));\n } catch {\n /* ignore */\n }\n } catch {\n /* ignore */\n }\n return null;\n }\n\n /** Collect UTM + page context (url/path/query) + visitor id for merging into an event. */\n collectContext(): EventContext & { visitorId?: string } {\n const ctx: EventContext & { visitorId?: string } = {};\n const utmSource = this.utmParam(\"utm_source\");\n const utmMedium = this.utmParam(\"utm_medium\");\n const utmCampaign = this.utmParam(\"utm_campaign\");\n const utmContent = this.utmParam(\"utm_content\");\n const utmId = this.utmParam(\"utm_id\");\n\n if (utmSource) ctx.utmSource = utmSource;\n if (utmMedium) ctx.utmMedium = utmMedium;\n if (utmCampaign) ctx.utmCampaign = utmCampaign;\n if (utmContent) ctx.utmContent = utmContent;\n if (utmId) ctx.utmId = utmId;\n\n try {\n ctx.url = window.location.href;\n ctx.path = window.location.pathname;\n ctx.query = Object.fromEntries(new URLSearchParams(window.location.search));\n if (document.referrer) ctx.referrer = document.referrer;\n } catch {\n /* ignore */\n }\n\n const vid = this.getVisitorId();\n if (vid) ctx.visitorId = vid;\n\n return ctx;\n }\n}\n\n/** Resolve the `visitorCookie` config to concrete settings, or null when disabled. */\nfunction resolveCookieConfig(opt: boolean | VisitorCookieOptions): CookieConfig | null {\n if (opt === false) return null;\n const o = opt === true ? {} : opt;\n const sameSite = o.sameSite ?? \"Lax\";\n // SameSite=None is only honored with Secure, so force it on.\n const secure = sameSite === \"None\" ? true : (o.secure ?? false);\n return { sameSite, secure, maxAgeDays: o.maxAgeDays ?? 365, domain: o.domain };\n}\n","import type { MessageAction, WidgetWireContext } from \"./types\";\n\n/**\n * Shared form-field / submit DOM convention, used by EVERY widget type (including standard\n * popups and `custom`) — see the cross-repo contract. Capturable inputs are marked\n * `data-xenia-field=\"<name>\"`; the submit trigger is marked `data-xenia-submit`. Read directly\n * by `wireFormSubmit()` below, and reused as-is by the spin-wheel widget module\n * (which has its own trigger — a Spin button — but still collects\n * `data-xenia-field` values the same way).\n */\nexport function collectFields(root: Element | ShadowRoot | Document): Record<string, string> {\n const fields: Record<string, string> = {};\n root.querySelectorAll(\"[data-xenia-field]\").forEach((el) => {\n const name = el.getAttribute(\"data-xenia-field\");\n if (!name) return;\n fields[name] = fieldValue(el);\n });\n return fields;\n}\n\nfunction fieldValue(el: Element): string {\n if (el instanceof HTMLInputElement) {\n if (el.type === \"checkbox\") return el.checked ? el.value || \"on\" : \"\";\n if (el.type === \"radio\") return el.checked ? el.value : \"\";\n return el.value;\n }\n if (el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement) return el.value;\n return el.textContent?.trim() ?? \"\";\n}\n\n/** Set/clear the disabled state on whatever kind of element the submit trigger turned out to be. */\nfunction setDisabled(el: Element | null | undefined, disabled: boolean): void {\n if (!el) return;\n if (\n el instanceof HTMLButtonElement ||\n el instanceof HTMLInputElement ||\n el instanceof HTMLSelectElement ||\n el instanceof HTMLTextAreaElement ||\n el instanceof HTMLFieldSetElement\n ) {\n el.disabled = disabled;\n } else if (disabled) {\n el.setAttribute(\"aria-disabled\", \"true\");\n } else {\n el.removeAttribute(\"aria-disabled\");\n }\n}\n\n/** Write (or clear) a message into the widget's `[data-xenia-error]` slot, if the markup has one. */\nfunction showError(root: Element | ShadowRoot, message: string): void {\n const el = root.querySelector(\"[data-xenia-error]\");\n if (el) el.textContent = message;\n}\n\nconst SUBMIT_STYLE_ID = \"xenia-form-submit-style\";\n\n/** Injects the spinner keyframe/rule once per root — self-contained (no dependency on the\n * design's own markup/CSS), so it works whether the design has a `<style>` block or not. */\nfunction ensureSubmitStyles(root: Element | ShadowRoot): void {\n if (root.querySelector(`#${SUBMIT_STYLE_ID}`)) return;\n const style = document.createElement(\"style\");\n style.id = SUBMIT_STYLE_ID;\n style.textContent =\n \"@keyframes xenia-submit-spin{to{transform:rotate(360deg)}}\" +\n \"[data-xenia-submitting]::after{content:'';display:inline-block;width:0.85em;height:0.85em;\" +\n \"margin-left:0.5em;vertical-align:-0.15em;border:2px solid currentColor;\" +\n \"border-right-color:transparent;border-radius:50%;animation:xenia-submit-spin 0.6s linear infinite}\";\n root.prepend(style);\n}\n\n/** Toggles the spinner attribute on the submit control while a request is in flight. */\nfunction setSubmitting(el: Element | null | undefined, submitting: boolean): void {\n if (!el) return;\n if (submitting) el.setAttribute(\"data-xenia-submitting\", \"\");\n else el.removeAttribute(\"data-xenia-submitting\");\n}\n\n/** Fades/scales the whole card out, then dismisses it — the \"submitted!\" beat between a\n * successful response and the widget disappearing, universal regardless of the design's own\n * markup (it targets the shadow host / card root, not anything design-authored). */\nfunction fadeOutAndDismiss(root: Element | ShadowRoot, dismiss?: () => void): void {\n if (!dismiss) return;\n const host = root instanceof ShadowRoot ? root.host : root;\n if (host instanceof HTMLElement) {\n host.style.transition = \"opacity 220ms ease, transform 220ms ease\";\n host.style.opacity = \"0\";\n host.style.transform = \"scale(0.96)\";\n window.setTimeout(dismiss, 220);\n } else {\n dismiss();\n }\n}\n\n/** The real dispatch (`/flow` or `/widget-submissions`) typically responds in well under 100ms —\n * fading the card out the instant it resolves would make it vanish before a visitor registers\n * it worked at all. Used as the floor whenever the marketer hasn't configured their own value\n * on the webhook-response node's Form-submission panel (`formSubmit.successDisplayMs`). */\nconst DEFAULT_SUCCESS_DISPLAY_MS = 900;\n\n/**\n * Reveals the design's own success-state block, if it authored one — the collaboration point\n * with Content Studio/AI content generation: a marketer/AI can add\n * `<div data-xenia-success hidden>You're on the list! 🎉</div>` anywhere in a popup/custom\n * widget's HTML, and this swaps it in for the form/fields the moment a submit succeeds, for\n * whatever `successDisplayMs` window is configured, instead of the card just sitting there\n * disabled (or, with no success block at all, that's exactly what happens — a plain but still\n * minimum-duration-respecting wait before the fade). Returns whether a success block was found.\n */\nfunction revealSuccess(root: Element | ShadowRoot, form: HTMLFormElement | null): boolean {\n const successEl = root.querySelector(\"[data-xenia-success]\");\n if (!successEl) return false;\n if (successEl instanceof HTMLElement) successEl.hidden = false;\n else successEl.removeAttribute(\"hidden\");\n if (form) {\n form.hidden = true;\n } else {\n root.querySelectorAll<HTMLElement>(\"[data-xenia-field], [data-xenia-submit]\").forEach((el) => {\n el.hidden = true;\n });\n }\n return true;\n}\n\n/**\n * Wire the shared field-collection/submit convention onto an already-injected card. Used for\n * every `standard`/`custom` widget (i.e. the fallthrough path in `ActionRenderer.wireCard()`) —\n * this is the fix for the original loophole: a marketer/AI-authored popup with a real `<input>` +\n * submit button now actually does something on submit.\n *\n * - If a real `<form>` is present in the injected HTML, its native `submit` event is\n * auto-detected: `preventDefault()` is called and its `FormData` is merged into the collected\n * `data-xenia-field` values (a marketer/AI who bothers to wrap fields in a `<form>` gets native\n * Enter-to-submit/validation for free — nothing requires it).\n * - Otherwise, the trigger is a click on `[data-xenia-submit]`.\n * - The submit control is disabled synchronously on trigger (double-submit guard) and grows a\n * small spinner (`[data-xenia-submitting]`) for the duration of the request.\n * - On success: the spinner clears, the design's own `[data-xenia-success]` block (if authored —\n * see {@link revealSuccess}) swaps in for the form, and after at least `successDisplayMs` has\n * elapsed since the submit started (real dispatch round-trips are typically well under 100ms,\n * too fast to register on its own), the whole card fades/scales out and dismisses itself\n * ({@link fadeOutAndDismiss}) — the widget never just sits there disabled forever, and never\n * vanishes before a visitor sees it worked.\n * - On error: the spinner clears, the control re-enables, and an error message is shown.\n *\n * The `<form>`'s native `submit` is ALWAYS intercepted, even when `action.formSubmit` is missing\n * (the marketer hasn't configured a submission target in the webhook-response node's\n * Form-submission panel yet) — otherwise an unconfigured widget's real `<form>` falls through to\n * the browser's default GET-to-current-URL submission, i.e. a full page reload. An unconfigured\n * submit now surfaces a visible, inert error instead of silently doing nothing OR reloading.\n */\nexport function wireFormSubmit(\n root: Element | ShadowRoot,\n action: MessageAction,\n ctx: WidgetWireContext,\n): void {\n const form = root.querySelector(\"form\");\n let submitting = false;\n ensureSubmitStyles(root);\n\n const run = (control: Element | null, fields: Record<string, string>): void => {\n if (submitting) return;\n if (!action.formSubmit) {\n showError(root, \"This form isn't connected yet.\");\n return;\n }\n submitting = true;\n showError(root, \"\");\n setDisabled(control, true);\n setSubmitting(control, true);\n const startedAt = Date.now();\n const minDisplayMs = action.formSubmit.successDisplayMs ?? DEFAULT_SUCCESS_DISPLAY_MS;\n ctx\n .submitWidgetForm(fields)\n .then(() => {\n setSubmitting(control, false);\n revealSuccess(root, form);\n const wait = Math.max(0, minDisplayMs - (Date.now() - startedAt));\n window.setTimeout(() => fadeOutAndDismiss(root, ctx.dismiss), wait);\n })\n .catch(() => {\n setSubmitting(control, false);\n setDisabled(control, false);\n showError(root, \"Something went wrong. Please try again.\");\n })\n .finally(() => {\n submitting = false;\n });\n };\n\n if (form) {\n form.addEventListener(\"submit\", (ev) => {\n ev.preventDefault();\n const formFields: Record<string, string> = {};\n new FormData(form).forEach((value, key) => {\n if (typeof value === \"string\") formFields[key] = value;\n });\n const submitter =\n (ev as SubmitEvent).submitter ?? form.querySelector('[type=\"submit\"], button:not([type])');\n run(submitter, { ...collectFields(root), ...formFields });\n });\n }\n\n root.querySelectorAll<HTMLElement>(\"[data-xenia-submit]\").forEach((el) => {\n // An element inside the detected <form> already fires via its `submit` event above —\n // wiring a click handler here too would double-submit.\n if (form?.contains(el)) return;\n el.addEventListener(\"click\", () => run(el, collectFields(root)));\n });\n}\n","import type { MessagePlacement, WidgetSubmitResponse, XeniaAction } from \"../../core/types\";\n\n/** A message-placement action (banner/popup/modal/inline) — the shape every widget renders. */\nexport type MessageAction = Extract<XeniaAction, { type: MessagePlacement }>;\n\n/**\n * Imperative hooks a widget's `wire()` can call back into, injected by `ActionRenderer` —\n * the widget module itself never touches `XeniaClient`/`XeniaApi` directly.\n */\nexport interface WidgetWireContext {\n /**\n * Dismiss this message — unmounts/removes it, same as the built-in card's close button.\n * Absent for placements with no dismiss affordance in this render (e.g. an `inline` action\n * rendered without a wrapping overlay). Widgets should guard with `ctx.dismiss?.()`.\n */\n dismiss?: () => void;\n /** Fire the action's `cta` (event + url), then {@link dismiss}. A no-op beyond dismiss when the action has no `cta`. */\n fireCta: () => void;\n /**\n * Submit captured field values for this widget's `formSubmit` config. Routes to the `/flow`\n * fast path or `/widget-submissions`, per the cross-repo contract's endpoint-selection rule —\n * the widget module never branches on `mode`/inspects the ref fields itself, it just calls this.\n *\n * Rejects if the action has no `formSubmit` config or no submission handler is wired (e.g. a\n * bare `ActionRenderer` constructed without `XeniaClient`). A per-widget-instance\n * `idempotencyKey` is applied automatically and reused across every call from the SAME\n * `wire()` invocation (i.e. a retried submit of the same interaction never mints a new one).\n */\n submitWidgetForm: (fields: Record<string, string>) => Promise<WidgetSubmitResponse>;\n}\n\n/**\n * Renders and wires a `widgetType`'s UI. One implementation per dispatchable widget type,\n * collected into `WIDGET_RENDERERS` (`client/widgets/index.ts`). `standard`/`custom`/undefined\n * are NOT dispatched through this interface — they use `ActionRenderer`'s existing built-in card\n * path unmodified (plus the shared `wireFormSubmit()` addition), per the cross-repo contract.\n */\nexport interface WidgetRenderer {\n /** Build the card markup injected into the shadow overlay or host-page slot. */\n html(action: MessageAction, variant: MessagePlacement): string;\n /** Wire interactivity after `html()`'s markup is already in the DOM under `root`. */\n wire(root: Element | ShadowRoot, action: MessageAction, ctx: WidgetWireContext): void;\n}\n\n/** Shared HTML escaping — mirrors `renderer.ts`'s private helpers (kept local to avoid a coupling import). */\nexport function escapeHtml(s: string): string {\n return s.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n}\n\nexport function escapeAttr(s: string): string {\n return escapeHtml(s).replace(/\"/g, \"&quot;\");\n}\n\n/**\n * Recognizes marketer/AI-pasted close/backdrop elements by convention (`data-xenia-close` AND\n * the common class/id naming marketers actually use) and wires a `dismiss` that always works —\n * shared by `ActionRenderer.wireCard()` (standard widgets) and any widget module that\n * accepts custom HTML for one of its own screens (spin-wheel's `spinnerHtml`/`winHtml`/\n * `lossHtml`). See renderer.ts's original `wireCard` comment\n * for why: a broken inline `onclick` reaching for `document.getElementById(...)` (pasted from a\n * standalone-page template) throws inside a shadow root/host-page slot and leaves the message\n * stuck open, so this drops it and wires a dismiss that's guaranteed to work instead. Also caps\n * a decorative backdrop's perceived darkness the same way.\n */\nexport function wireCloseAffordances(root: Element | ShadowRoot, dismiss?: () => void): void {\n if (dismiss) {\n const closeEls = root.querySelectorAll(\n \".xenia-close, [data-xenia-close], [class*='close' i], [id*='close' i], \" +\n \"[class*='backdrop' i], [id*='backdrop' i]\",\n );\n closeEls.forEach((el) => {\n el.removeAttribute(\"onclick\");\n el.addEventListener(\"click\", dismiss);\n });\n }\n\n root.querySelectorAll(\"[class*='backdrop' i], [id*='backdrop' i]\").forEach((el) => {\n if (el instanceof HTMLElement && el.children.length === 0 && !el.textContent?.trim()) {\n el.style.opacity = \"0.5\";\n }\n });\n}\n","import type { WidgetSegment } from \"../../core/types\";\nimport { collectFields } from \"./form\";\nimport type { MessageAction, WidgetRenderer, WidgetWireContext } from \"./types\";\nimport { escapeAttr, escapeHtml, wireCloseAffordances } from \"./types\";\n\nconst WHEEL_SIZE = 260;\nconst RADIUS = WHEEL_SIZE / 2;\nconst CENTER = WHEEL_SIZE / 2;\nconst DEFAULT_COLORS = [\"#7c3aed\", \"#2563eb\", \"#059669\", \"#d97706\", \"#dc2626\", \"#0891b2\"];\nconst SPIN_TRANSITION = \"transform 3.2s cubic-bezier(0.15, 0.85, 0.25, 1)\";\nconst WHEEL_POINTER_HTML = '<div class=\"xenia-wheel-pointer\" aria-hidden=\"true\"></div>';\nconst REVEAL_TRANSITION_MS = 320;\nconst REVEAL_TRANSITION = `opacity ${REVEAL_TRANSITION_MS}ms ease, transform ${REVEAL_TRANSITION_MS}ms ease`;\n// `perspective(...)` as a TRANSFORM FUNCTION (not the standalone `perspective` CSS property) —\n// applied only to the element being animated, never to an ancestor. A `perspective`/`transform`\n// on an ANCESTOR of a `position:fixed` element becomes that fixed element's containing block per\n// spec, which is exactly the bug `.xenia-widget-result`'s old CSS animation caused (see\n// renderer.ts) — sizing/positioning it relative to that ancestor's own small box instead of the\n// real viewport. Keeping the 3D transform local to the animated element itself sidesteps that\n// entirely: its OWN position:fixed containing-block is unaffected by a transform function inside\n// its OWN `transform` value.\nconst REVEAL_PERSPECTIVE_PX = 900;\nconst REVEAL_DEPTH_PX = 60;\nconst revealTransform = (scale: number, depthPx: number): string =>\n `perspective(${REVEAL_PERSPECTIVE_PX}px) translateZ(${depthPx}px) scale(${scale})`;\n\n/** A point on the wheel's circumference at `angleDeg` (0 = top/12 o'clock, clockwise) and `radius`. */\nfunction polarPoint(angleDeg: number, radius: number): { x: number; y: number } {\n const rad = (angleDeg * Math.PI) / 180;\n return { x: CENTER + radius * Math.sin(rad), y: CENTER - radius * Math.cos(rad) };\n}\n\n/** SVG `<path>` `d` attribute for one pie slice spanning `startAngle`..`endAngle` degrees. */\nfunction segmentPath(startAngle: number, endAngle: number): string {\n const start = polarPoint(startAngle, RADIUS);\n const end = polarPoint(endAngle, RADIUS);\n const largeArc = endAngle - startAngle > 180 ? 1 : 0;\n return `M ${CENTER},${CENTER} L ${start.x},${start.y} A ${RADIUS},${RADIUS} 0 ${largeArc} 1 ${end.x},${end.y} Z`;\n}\n\n/**\n * Deterministic resting rotation (degrees) that lands segment `segmentIndex` (out of\n * `segmentCount`, equal slices starting at 12 o'clock going clockwise) under the wheel's fixed\n * pointer, plus `extraSpins` full rotations for purely cosmetic flair — extra spins are\n * client-random visual dressing ONLY; they never affect which segment the wheel lands on (the\n * returned value mod 360 is fully determined by `segmentIndex`/`segmentCount`).\n *\n * Pure, exported, and unit-testable with no DOM — per the \"wheel resolution sequencing\"\n * rule, this is called only AFTER the server-resolved `segmentIndex` is known, never before.\n */\nexport function computeSpinRotation(\n segmentIndex: number,\n segmentCount: number,\n extraSpins = 0,\n): number {\n if (segmentCount <= 0) return 0;\n const segmentAngle = 360 / segmentCount;\n const centerAngle = segmentIndex * segmentAngle + segmentAngle / 2;\n const landingAngle = (360 - centerAngle) % 360;\n return extraSpins * 360 + landingAngle;\n}\n\n/**\n * Cross-fades between the currently-shown screen and the one replacing it, with a subtle 3D\n * \"recede away / rise toward camera\" depth pop (perspective + translateZ + scale) — applied\n * directly to each screen's OWN top-level element(s) (`outgoing`/`incoming`'s children), not the\n * `data-xenia-wheel-face`/`.xenia-widget-result` wrapper around them. A marketer's spinnerHtml/\n * winHtml/lossHtml almost always makes its own top-level element `position:fixed` (a real \"full-\n * screen overlay\" ask, not a rare edge case — see the Content Studio preview's own fix for the\n * same design pattern) — `opacity` on an ANCESTOR does visually fade a `position:fixed`\n * descendant, but `transform` on an ancestor does not reliably shrink one (its explicit\n * `width:100vw`/`height:100vh` stays put regardless of which element scales) AND would make that\n * ancestor the fixed element's containing block, repositioning it relative to the ancestor's own\n * box instead of the true viewport (see `.xenia-widget-result`'s doc comment in renderer.ts for\n * the exact bug this caused) — so the transform is set on the fixed element itself, both to\n * actually read as a smooth pop instead of an instant cut, AND to keep it correctly centered on\n * the real screen. `incoming` is revealed synchronously (`hidden = false`) so existing callers\n * observing that flag right after this call keep seeing it — only `outgoing`'s `hidden` flip is\n * deferred until the fade finishes, since nothing needs to observe that synchronously.\n */\nfunction crossFadeReveal(outgoing: HTMLElement | null, incoming: HTMLElement | null): void {\n const outContent = outgoing ? Array.from(outgoing.children) : [];\n const inContent = incoming ? Array.from(incoming.children) : [];\n if (incoming) incoming.hidden = false;\n inContent.forEach((el) => {\n if (!(el instanceof HTMLElement)) return;\n el.style.transition = \"none\";\n el.style.opacity = \"0\";\n el.style.transform = revealTransform(0.94, -REVEAL_DEPTH_PX);\n });\n // Force a reflow so the \"from\" state above actually commits before the transition is armed\n // below — otherwise the browser can coalesce both style writes into a single recalc (nothing\n // was ever painted in between to transition FROM), and the reveal silently snaps straight to\n // its end state instead of animating. Same fix already applied to the dial's spin rotation\n // just below in this file, via `dial.getBoundingClientRect()`.\n inContent.forEach((el) => {\n if (el instanceof HTMLElement) void el.offsetHeight;\n });\n nextFrame(() => {\n outContent.forEach((el) => {\n if (!(el instanceof HTMLElement)) return;\n el.style.transition = REVEAL_TRANSITION;\n el.style.opacity = \"0\";\n el.style.transform = revealTransform(0.94, -REVEAL_DEPTH_PX);\n });\n inContent.forEach((el) => {\n if (!(el instanceof HTMLElement)) return;\n el.style.transition = REVEAL_TRANSITION;\n el.style.opacity = \"1\";\n el.style.transform = revealTransform(1, 0);\n });\n });\n if (outgoing) {\n setTimeout(() => {\n outgoing.hidden = true;\n }, REVEAL_TRANSITION_MS);\n }\n}\n\n/** `requestAnimationFrame`, falling back to a macrotask tick where it's unavailable (e.g. jsdom in tests). */\nfunction nextFrame(fn: () => void): void {\n if (typeof requestAnimationFrame === \"function\") requestAnimationFrame(fn);\n else setTimeout(fn, 0);\n}\n\nfunction wheelSvg(segments: WidgetSegment[]): string {\n const n = segments.length || 1;\n const segmentAngle = 360 / n;\n const slices = segments\n .map((seg, i) => {\n const start = i * segmentAngle;\n const end = start + segmentAngle;\n const color = seg.colorHex || DEFAULT_COLORS[i % DEFAULT_COLORS.length];\n const labelAngle = start + segmentAngle / 2;\n const labelPoint = polarPoint(labelAngle, RADIUS * 0.62);\n return (\n `<path d=\"${segmentPath(start, end)}\" fill=\"${escapeAttr(color)}\" stroke=\"#fff\" stroke-width=\"1\"></path>` +\n `<text x=\"${labelPoint.x}\" y=\"${labelPoint.y}\" fill=\"#fff\" font-size=\"12\" text-anchor=\"middle\" ` +\n `transform=\"rotate(${labelAngle} ${labelPoint.x} ${labelPoint.y})\">${escapeHtml(seg.label)}</text>`\n );\n })\n .join(\"\");\n return (\n `<svg class=\"xenia-wheel-svg\" viewBox=\"0 0 ${WHEEL_SIZE} ${WHEEL_SIZE}\" width=\"${WHEEL_SIZE}\" height=\"${WHEEL_SIZE}\">` +\n `<g class=\"xenia-wheel-dial\">${slices}</g>` +\n // Static hub cap over the center seam — a plain circle, so dial rotation (which only this\n // <g> above undergoes) never visibly affects it; kept outside the rotating group on purpose.\n `<circle class=\"xenia-wheel-hub\" cx=\"${CENTER}\" cy=\"${CENTER}\" r=\"6\"></circle>` +\n `</svg>`\n );\n}\n\nexport const spinWheelRenderer: WidgetRenderer = {\n html(action: MessageAction): string {\n // No `.xenia-card` chrome (background/shadow/radius/padding) of our own, and no built-in\n // close button either — `spinnerHtml`/`winHtml`/`lossHtml` are always full marketer/AI-\n // authored HTML (same role a popup's `body` plays via `wrapCustomHtml`, same \"no generated\n // fallback\" rule), so the author's own card chrome AND close affordance are what actually\n // render. Wrapping in `.xenia-card` too used to nest the SDK's own white background/shadow\n // behind the author's own card, visible as an unwanted glow/halo in the padding gap between\n // them once every screen started drawing its own full chrome (see the \"unwanted background\"\n // regression this replaced, and the \"two ×\" regression fixed the same way just above it).\n return (\n `<div class=\"xenia-spin-wheel\">` +\n `<div data-xenia-wheel-face>${action.spinnerHtml ?? \"\"}</div>` +\n // Hidden by default; never shown before the server-resolved outcome is in hand. Exactly\n // one of win/loss is revealed once resolved, based on the landed segment's `isLoss`.\n `<div class=\"xenia-widget-result\" data-xenia-wheel-result hidden>${action.winHtml ?? \"\"}</div>` +\n `<div class=\"xenia-widget-result\" data-xenia-wheel-loss hidden>${action.lossHtml ?? \"\"}</div>` +\n `</div>`\n );\n },\n\n wire(root: Element | ShadowRoot, action: MessageAction, ctx: WidgetWireContext): void {\n // Covers the built-in close button AND any close/backdrop element a marketer's own\n // spinnerHtml/winHtml/lossHtml happens to include, by the same convention every other\n // custom-HTML surface in this SDK already honors.\n wireCloseAffordances(root, ctx.dismiss);\n\n const segments = action.segments ?? [];\n const wheelFace = root.querySelector<HTMLElement>(\"[data-xenia-wheel-face]\");\n const spinBtn = root.querySelector<HTMLButtonElement>(\"[data-xenia-spin]\");\n const winEl = root.querySelector<HTMLElement>(\"[data-xenia-wheel-result]\");\n const lossEl = root.querySelector<HTMLElement>(\"[data-xenia-wheel-loss]\");\n const errorEl = root.querySelector<HTMLElement>(\"[data-xenia-error]\");\n\n // One injection path for the generated SVG wheel + pointer, whether `wheelFace` is the SDK's\n // own generated markup or a marketer's `spinnerHtml` — either way, the slot is where it goes.\n // Runs regardless of `formSubmit` below — an unconfigured widget still shows the wheel, it\n // just isn't spinnable yet (matches every other still-being-configured widget in this SDK).\n const slotEl = root.querySelector<HTMLElement>(\"[data-xenia-wheel-slot]\");\n if (slotEl) slotEl.insertAdjacentHTML(\"afterbegin\", wheelSvg(segments) + WHEEL_POINTER_HTML);\n const dial = root.querySelector<HTMLElement>(\".xenia-wheel-dial\");\n\n if (!spinBtn || !action.formSubmit) return;\n\n // Labels are already baked into the markup by html() — only click handlers are wired here.\n // `fireCta()` still fires any configured cta event/url before dismissing.\n root.querySelectorAll(\"[data-xenia-wheel-cta]\").forEach((btn) => {\n btn.addEventListener(\"click\", () => ctx.fireCta());\n });\n\n // Swap the wheel face for the win/loss reveal screen — never before the resolved outcome is\n // in hand (see the \"wheel resolution sequencing\" rule referenced throughout this\n // file). Both win and loss prize placeholders are populated (a losing segment still has a\n // `label`, e.g. \"Try Again\") — whichever screen isn't shown just stays hidden either way.\n // The swap itself cross-fades (see crossFadeReveal) rather than an instant `hidden` flip —\n // an un-animated cut between two full-screen overlays read as a jarring flash.\n // `canRetry=false` means the BE's own maxPlays/win-lock guard (see\n // WidgetSubmissionService.submit()) reported `alreadyPlayed: true` for THIS reveal — a\n // replay, not a fresh roll. Whether that's because a real win locked the visitor out, or a\n // string of losses used up every configured retry, one more click would only replay the exact\n // same outcome again — so any `[data-xenia-spin-again]` button is hidden for good, instead of\n // sitting there inviting a click that can never do anything.\n const revealResult = (prizeLabel: string, isLoss: boolean, canRetry: boolean): void => {\n root.querySelectorAll(\"[data-xenia-wheel-prize]\").forEach((el) => {\n el.textContent = prizeLabel;\n });\n const shown = isLoss ? lossEl : winEl;\n const other = isLoss ? winEl : lossEl;\n if (other) other.hidden = true; // never shown this round — no fade needed\n crossFadeReveal(wheelFace, shown);\n if (!canRetry) {\n playsExhausted = true;\n root.querySelectorAll<HTMLElement>(\"[data-xenia-spin-again]\").forEach((btn) => {\n btn.hidden = true;\n });\n }\n };\n\n let spinning = false;\n let playsExhausted = false;\n\n // Reverse of revealResult — a marketer's winHtml/lossHtml may include a\n // `[data-xenia-spin-again]` button (e.g. a loss screen's \"Try Again\") offering the visitor\n // another attempt. This was previously undocumented and unwired: an AI-authored design that\n // added the button (a real, organic pattern — visitors naturally expect \"Try Again\" on a\n // spin-wheel to actually try again) produced a dead button that did nothing on click. Wiring\n // it swaps back to the wheel face (same crossFadeReveal transition, reversed) and re-arms the\n // spin button so a fresh `submitWidgetForm` call can fire. This hook only ever re-opens the\n // ASK — it never itself grants another spin. The BE's own maxPlays/win-lock guard is what\n // actually decides whether the next click resolves to a genuinely fresh roll or a replay of\n // the same already-locked-in outcome; `playsExhausted` (set by revealResult above) is a purely\n // defensive belt-and-braces guard in case the button's own `hidden` gets overridden.\n root.querySelectorAll(\"[data-xenia-spin-again]\").forEach((btn) => {\n btn.addEventListener(\"click\", () => {\n if (playsExhausted) return;\n const shown = winEl && !winEl.hidden ? winEl : lossEl && !lossEl.hidden ? lossEl : null;\n if (!shown) return;\n spinning = false;\n spinBtn.disabled = false;\n if (errorEl) errorEl.textContent = \"\";\n crossFadeReveal(shown, wheelFace);\n });\n });\n\n spinBtn.addEventListener(\"click\", () => {\n if (spinning) return;\n spinning = true;\n spinBtn.disabled = true;\n if (errorEl) errorEl.textContent = \"\";\n\n const fields = collectFields(root);\n // Deliberately do NOT touch `dial`'s transform here — no spin animation starts until the\n // resolved outcome is in hand (see the \"Wheel resolution sequencing\" rule). No\n // optimistic spin, no mid-flight correction: there is never a moment where the client has\n // invented an outcome.\n ctx\n .submitWidgetForm(fields)\n .then((response) => {\n const index = segments.findIndex((s) => s.id === response.prize?.segmentId);\n const prizeLabel = response.prize?.label ?? segments[index]?.label ?? \"\";\n // Unknown whether a stale/mismatched replay's original outcome was a loss — the\n // segments list that carried `isLoss` may since have been edited away entirely. Default\n // to the win screen rather than guess; see the \"no matching segment\" case just below.\n const isLoss = index >= 0 && !!segments[index]?.isLoss;\n\n // No matching segment — e.g. a replay (`alreadyPlayed`) resolving against a segmentId\n // from BEFORE the marketer last edited this widget's segments. Landing the dial on some\n // OTHER segment (like index 0) while announcing a label that segment doesn't show would\n // visibly contradict the wheel — the visitor would see it stop on \"15% Off\" while the\n // card reads \"20% Off\". Skip the animation entirely and reveal the true outcome as-is\n // rather than fabricate a landing position that isn't real.\n const canRetry = response.alreadyPlayed !== true;\n\n if (index < 0 || !dial) {\n revealResult(prizeLabel, isLoss, canRetry);\n return;\n }\n\n const extraSpins = 3 + Math.floor(Math.random() * 3); // cosmetic only — never changes the landing segment\n const rotation = computeSpinRotation(index, segments.length || 1, extraSpins);\n\n // Normalize any rotation left over from a PRIOR spin (same visual angle, mod 360) before\n // committing this one's target. `rotation` above is always >= 3*360, so re-basing the\n // current value into [0, 360) guarantees it can never collide with the new target — without\n // this, a retry landing on the same segment as last time could compute the EXACT same\n // absolute rotation the dial is already resting at. When that happens the CSS transform\n // never actually changes, so `transitionend` never fires, and the widget hangs forever —\n // wheel visibly frozen, spin button stuck disabled, no error, no reveal.\n const priorMatch = /rotate\\(([-\\d.]+)deg\\)/.exec(dial.style.transform);\n const priorRotation = priorMatch ? parseFloat(priorMatch[1]) : 0;\n dial.style.transition = \"none\";\n dial.style.transform = `rotate(${priorRotation % 360}deg)`;\n void dial.getBoundingClientRect(); // force reflow so \"transition: none\" above commits first\n\n dial.style.transition = SPIN_TRANSITION;\n const onTransitionEnd = () => {\n dial.removeEventListener(\"transitionend\", onTransitionEnd);\n revealResult(prizeLabel, isLoss, canRetry);\n };\n dial.addEventListener(\"transitionend\", onTransitionEnd);\n // One frame later, so the transition (set above) is guaranteed to have committed\n // before the transform changes — otherwise some browsers skip straight to the end\n // value instead of animating.\n nextFrame(() => {\n dial.style.transform = `rotate(${rotation}deg)`;\n });\n })\n .catch(() => {\n spinning = false;\n spinBtn.disabled = false;\n if (errorEl) errorEl.textContent = \"Something went wrong. Please try again.\";\n });\n });\n },\n};\n","import { spinWheelRenderer } from \"./spin-wheel\";\nimport type { WidgetRenderer } from \"./types\";\n\n/**\n * Dispatch table keyed by `widgetType`, consulted by `ActionRenderer.cardHtml()`/`wireCard()`.\n * `standard`/undefined is deliberately NOT here — it falls through to `ActionRenderer`'s\n * existing built-in card path (plus the shared `wireFormSubmit()` addition), per the cross-repo\n * contract. A 3rd future widget type is one new module + one new line here.\n */\nexport const WIDGET_RENDERERS: Record<string, WidgetRenderer> = {\n \"spin-wheel\": spinWheelRenderer,\n};\n\nexport type { MessageAction, WidgetRenderer, WidgetWireContext } from \"./types\";\nexport { collectFields, wireFormSubmit } from \"./form\";\nexport { computeSpinRotation, spinWheelRenderer } from \"./spin-wheel\";\n","import { generateUlid } from \"../core/id\";\nimport type {\n MessageComponentRenderer,\n MessageCta,\n MessageMountContext,\n MessagePlacement,\n MessagePosition,\n MessageRenderContext,\n MessageTemplateFn,\n WidgetFormSubmit,\n WidgetSubmitResponse,\n XeniaAction,\n} from \"../core/types\";\nimport { wireFormSubmit } from \"./widgets/form\";\nimport type { WidgetWireContext } from \"./widgets/types\";\nimport { wireCloseAffordances } from \"./widgets/types\";\nimport { WIDGET_RENDERERS } from \"./widgets\";\n\n/** Callback invoked when a rendered CTA fires an event. */\nexport type CtaHandler = (event: string, cta: MessageCta) => void;\n\n/** Submits a widget's captured form values — injected from `XeniaClient.submitWidgetForm`. */\nexport type SubmitWidgetFormHandler = (\n submit: WidgetFormSubmit,\n fields: Record<string, string>,\n opts?: { idempotencyKey?: string },\n) => Promise<WidgetSubmitResponse>;\n\n/**\n * Resolve a target string to an element. Supports plain CSS selectors and the\n * `data-xenia-slot=\"<id>\"` convention (a bare id with no CSS metacharacters is\n * treated as a slot name first, then falls back to a selector).\n */\nexport function resolveTarget(\n target: string,\n root: ParentNode = document,\n): Element | null {\n if (!target) return null;\n const bySlot = root.querySelector(`[data-xenia-slot=\"${cssEscape(target)}\"]`);\n if (bySlot) return bySlot;\n try {\n return root.querySelector(target);\n } catch {\n return null;\n }\n}\n\nfunction cssEscape(value: string): string {\n const anyWin = window as unknown as {\n CSS?: { escape?: (v: string) => string };\n };\n if (anyWin.CSS?.escape) return anyWin.CSS.escape(value);\n return value.replace(/[\"\\\\]/g, \"\\\\$&\");\n}\n\n/** Replace an element's content (or the element itself for `swap`). */\nexport function swapContent(\n target: string,\n content: { html?: string; text?: string },\n): boolean {\n const el = resolveTarget(target);\n if (!el) return false;\n if (content.html !== undefined) {\n el.innerHTML = content.html;\n } else if (content.text !== undefined) {\n el.textContent = content.text;\n }\n el.removeAttribute(\"hidden\");\n return true;\n}\n\n/** Hide an element (kept in the DOM; `display:none` via the hidden attribute). */\nexport function hideContent(target: string): boolean {\n const el = resolveTarget(target);\n if (!el || !(el instanceof HTMLElement)) return false;\n el.dataset.xeniaHidden = \"1\";\n el.style.setProperty(\"display\", \"none\", \"important\");\n return true;\n}\n\n/** Reverse {@link hideContent}. */\nexport function showContent(target: string): boolean {\n const el = resolveTarget(target);\n if (!el || !(el instanceof HTMLElement)) return false;\n delete el.dataset.xeniaHidden;\n el.style.removeProperty(\"display\");\n return true;\n}\n\nconst MESSAGE_TYPES = new Set<MessagePlacement>([\n \"banner\",\n \"popup\",\n \"modal\",\n \"inline\",\n]);\n\nfunction isMessageType(type: string): type is MessagePlacement {\n return MESSAGE_TYPES.has(type as MessagePlacement);\n}\n\n/**\n * Renders and applies {@link XeniaAction}s in the browser. Message-style actions\n * (banner/popup/modal/inline) render inside a shadow root so host-page styles\n * never leak in or out.\n */\nexport class ActionRenderer {\n private host: HTMLElement | null = null;\n private shadow: ShadowRoot | null = null;\n private readonly onCta?: CtaHandler;\n private readonly messageTemplate?: MessageTemplateFn;\n private readonly messageStyles?: string;\n private readonly messageComponent?: MessageComponentRenderer;\n private readonly submitWidgetFormFn?: SubmitWidgetFormHandler;\n /** Unmount callbacks for currently-mounted framework components, keyed by their container. */\n private readonly mounted = new Map<Element, () => void>();\n\n constructor(\n onCta?: CtaHandler,\n opts?: {\n messageTemplate?: MessageTemplateFn;\n messageStyles?: string;\n messageComponent?: MessageComponentRenderer;\n /** Wired from `XeniaClient.submitWidgetForm` — powers every widget's form submission. */\n submitWidgetForm?: SubmitWidgetFormHandler;\n },\n ) {\n this.onCta = onCta;\n this.messageTemplate = opts?.messageTemplate;\n this.messageStyles = opts?.messageStyles;\n this.messageComponent = opts?.messageComponent;\n this.submitWidgetFormFn = opts?.submitWidgetForm;\n }\n\n /** Apply a list of actions. Returns the count successfully applied. */\n apply(actions: XeniaAction[]): number {\n let applied = 0;\n for (const action of actions) {\n if (this.applyOne(action)) applied++;\n }\n return applied;\n }\n\n private applyOne(action: XeniaAction): boolean {\n switch (action.type) {\n case \"swap\":\n return swapContent(action.target, {\n html: action.html,\n text: action.text,\n });\n case \"setContent\":\n return swapContent(action.target, {\n html: action.html,\n text: action.text,\n });\n case \"hide\":\n return hideContent(action.target);\n case \"show\":\n return showContent(action.target);\n case \"redirect\":\n try {\n window.location.assign(action.url);\n return true;\n } catch {\n return false;\n }\n default:\n if (isMessageType(action.type)) return this.renderMessage(action);\n return false;\n }\n }\n\n /** Tear down injected message UI, unmounting any still-open framework components first. */\n destroy(): void {\n this.mounted.forEach((unmount) => unmount());\n this.mounted.clear();\n this.host?.remove();\n this.host = null;\n this.shadow = null;\n }\n\n private ensureShadow(): ShadowRoot {\n if (this.shadow) return this.shadow;\n const host = document.createElement(\"div\");\n host.setAttribute(\"data-xenia-ui\", \"\");\n document.body.appendChild(host);\n const shadow = host.attachShadow({ mode: \"open\" });\n shadow.appendChild(this.styleEl());\n this.host = host;\n this.shadow = shadow;\n return shadow;\n }\n\n private styleEl(): HTMLStyleElement {\n const style = document.createElement(\"style\");\n style.textContent = this.messageStyles\n ? `${STYLES}\\n${this.messageStyles}`\n : STYLES;\n return style;\n }\n\n private renderMessage(\n action: Extract<XeniaAction, { type: MessagePlacement }>,\n ): boolean {\n // A framework-native component (if registered) renders directly into the container — it owns\n // the card markup entirely, same precedence as per-action `html`. Falls through to the\n // string-based path (messageTemplate, else the built-in card) otherwise.\n const useComponent = action.html === undefined && !!this.messageComponent;\n\n // Inline messages render into a host-page slot; others into the shadow overlay.\n if (action.type === \"inline\") {\n if (!action.target) return false;\n const el = resolveTarget(action.target);\n if (!el) return false;\n this.unmount(el);\n if (useComponent) {\n el.innerHTML = \"\";\n this.mountComponent(el, action, \"inline\", () => this.unmount(el));\n } else {\n el.innerHTML = this.cardHtml(action, \"inline\");\n this.wireCard(el, action);\n }\n return true;\n }\n\n const shadow = this.ensureShadow();\n const wrap = document.createElement(\"div\");\n const posClass = this.positionClass(action.type, action.position);\n // Custom HTML \"fully replaces the default card design\" (incl. its own backdrop, if any) — so\n // the SDK's own modal backdrop is suppressed when custom HTML is provided, to avoid stacking\n // two dark overlays (the SDK's + the pasted markup's own) into one much-darker-than-intended one.\n const customBgClass = action.html !== undefined ? \" xenia-custom-bg\" : \"\";\n // Marketer-set window-design override (Content Studio's spin-wheel editor) — see WidgetStyle.\n // Mirrors xenia-custom-bg's own transparent-backdrop mechanism; a no-op for placements with no\n // backdrop CSS to begin with (popup/banner), so this is safe to apply regardless of `type`.\n const noOverlayClass = action.style?.hideOverlay ? \" xenia-no-overlay\" : \"\";\n wrap.className = `xenia-msg xenia-${action.type}${posClass ? ` ${posClass}` : \"\"}${customBgClass}${noOverlayClass}`;\n shadow.appendChild(wrap);\n\n const dismiss = () => {\n this.unmount(wrap);\n wrap.remove();\n };\n\n if (useComponent) {\n this.mountComponent(wrap, action, action.type, dismiss);\n } else {\n wrap.innerHTML = this.cardHtml(action, action.type);\n this.wireCard(wrap, action, dismiss);\n }\n\n if (action.dismissAfterMs && action.dismissAfterMs > 0) {\n const timer = setTimeout(dismiss, action.dismissAfterMs);\n // A visitor actively engaging with the widget (clicking anywhere in it, or focusing an\n // input — e.g. mid-way through a capture form) should never have it yanked away under them\n // by a stale timer that has no idea they're still using it. Either signal cancels for good;\n // `once: true` on both means whichever fires first tears itself down and the other stays a\n // harmless no-op listener that self-removes on its own next trigger.\n const cancelAutoDismiss = () => clearTimeout(timer);\n wrap.addEventListener(\"click\", cancelAutoDismiss, { once: true });\n wrap.addEventListener(\"focusin\", cancelAutoDismiss, { once: true });\n }\n return true;\n }\n\n /** Mount a registered `messageComponent` into `container` and remember how to unmount it. */\n private mountComponent(\n container: Element,\n action: Extract<XeniaAction, { type: MessagePlacement }>,\n variant: MessagePlacement,\n close: () => void,\n ): void {\n if (!this.messageComponent) return;\n const ctx: MessageMountContext = {\n action,\n variant,\n close,\n fireCta: () => {\n if (action.cta?.event) this.onCta?.(action.cta.event, action.cta);\n if (action.cta?.url) window.location.assign(action.cta.url);\n close();\n },\n };\n // `container` is a plain DOM `Element` here (it may come from a CSS-selector-resolved\n // `data-xenia-slot`, not just SDK-created wrapper divs) — HTMLElement covers every real target.\n const unmount = this.messageComponent(container as HTMLElement, ctx);\n if (unmount) this.mounted.set(container, unmount);\n }\n\n /** Unmount a previously-mounted component for `container`, if any. */\n private unmount(container: Element): void {\n const unmount = this.mounted.get(container);\n if (!unmount) return;\n unmount();\n this.mounted.delete(container);\n }\n\n /**\n * Resolves the anchor CSS class for banner/popup, defaulting to the SDK's\n * original fixed placement (popup: bottom-right; banner: bottom) when no\n * position is given, so actions built before `position` existed still\n * render exactly as they always have. modal/inline have no anchor class.\n */\n private positionClass(\n type: MessagePlacement,\n position?: MessagePosition,\n ): string {\n if (type === \"popup\") {\n const pos =\n position === \"top-left\" ||\n position === \"top-right\" ||\n position === \"bottom-left\"\n ? position\n : \"bottom-right\";\n return `xenia-pos-${pos}`;\n }\n if (type === \"banner\") {\n return `xenia-pos-${position === \"top\" ? \"top\" : \"bottom\"}`;\n }\n return \"\";\n }\n\n private cardHtml(\n action: Extract<XeniaAction, { type: MessagePlacement }>,\n variant: MessagePlacement,\n ): string {\n // A dispatchable widgetType (spin-wheel) owns its own markup entirely — the\n // existing built-in card path below is untouched for standard/custom/undefined.\n const widget = action.widgetType ? WIDGET_RENDERERS[action.widgetType] : undefined;\n if (widget) return widget.html(action, variant);\n\n if (action.html !== undefined) return wrapCustomHtml(action.html, variant);\n if (this.messageTemplate) {\n const ctx: MessageRenderContext = {\n action,\n variant,\n escapeHtml,\n escapeAttr,\n };\n return this.messageTemplate(ctx);\n }\n const img = action.imageUrl\n ? `<img class=\"xenia-img\" src=\"${escapeAttr(action.imageUrl)}\" alt=\"\" />`\n : \"\";\n const title = action.title\n ? `<div class=\"xenia-title\">${escapeHtml(action.title)}</div>`\n : \"\";\n const msg = action.message\n ? `<div class=\"xenia-body\">${escapeHtml(action.message)}</div>`\n : \"\";\n const cta = action.cta\n ? `<button class=\"xenia-cta\" type=\"button\">${escapeHtml(action.cta.label)}</button>`\n : \"\";\n const close =\n variant === \"inline\"\n ? \"\"\n : `<button class=\"xenia-close\" type=\"button\" aria-label=\"Close\">×</button>`;\n return `<div class=\"xenia-card\">${close}${img}<div class=\"xenia-content\">${title}${msg}${cta}</div></div>`;\n }\n\n private wireCard(\n root: Element | ShadowRoot,\n action: Extract<XeniaAction, { type: MessagePlacement }>,\n dismiss?: () => void,\n ): void {\n // A dispatchable widgetType (spin-wheel) owns its own interactivity entirely —\n // including its own close wiring (via ctx.dismiss) — and skips the generic wiring below,\n // which assumes marketer-pasted/built-in card markup, not the SDK's own generated UI.\n const widget = action.widgetType ? WIDGET_RENDERERS[action.widgetType] : undefined;\n if (widget) {\n widget.wire(root, action, this.buildWidgetCtx(action, dismiss));\n return;\n }\n\n // Custom HTML close/backdrop elements commonly carry their own inline `onclick` reaching for\n // `document.getElementById(...)` — pasted from AI tools or templates built as standalone pages\n // that assume full document access. See `wireCloseAffordances` for why this recognizes them by\n // convention instead of trusting that script.\n wireCloseAffordances(root, dismiss);\n\n const ctaBtn = root.querySelector(\".xenia-cta, [data-xenia-cta]\");\n if (ctaBtn && action.cta) {\n ctaBtn.addEventListener(\"click\", () => {\n if (action.cta?.event) this.onCta?.(action.cta.event, action.cta);\n if (action.cta?.url) window.location.assign(action.cta.url);\n dismiss?.();\n });\n }\n\n // NEW: shared field-collection/submit wiring (every standard/custom widget, including plain\n // popups) — the fix for the original loophole where a popup's real <input> + submit button\n // rendered but submitting it did nothing. A no-op when the action has no `formSubmit` config.\n wireFormSubmit(root, action, this.buildWidgetCtx(action, dismiss));\n }\n\n /** Build the imperative hooks (`dismiss`/`fireCta`/`submitWidgetForm`) handed to a widget's `wire()`. */\n private buildWidgetCtx(\n action: Extract<XeniaAction, { type: MessagePlacement }>,\n dismiss?: () => void,\n ): WidgetWireContext {\n // One idempotency key per rendered widget instance, reused across EVERY submit attempt for\n // this interaction (including a retry after a failed submit) — never regenerated mid-\n // interaction, so a network retry can't double-fire a journey or double-resolve a prize.\n const idempotencyKey = generateUlid();\n return {\n dismiss,\n fireCta: () => {\n if (action.cta?.event) this.onCta?.(action.cta.event, action.cta);\n if (action.cta?.url) window.location.assign(action.cta.url);\n dismiss?.();\n },\n submitWidgetForm: (fields) => {\n if (!action.formSubmit || !this.submitWidgetFormFn) {\n return Promise.reject(\n new Error(\n \"xenia: this action has no formSubmit config, or no submitWidgetForm handler is wired (construct the ActionRenderer via XeniaClient to get one)\",\n ),\n );\n }\n return this.submitWidgetFormFn(action.formSubmit, fields, { idempotencyKey });\n },\n };\n }\n}\n\n/**\n * Xenia is authored by non-technical marketers who paste HTML/CSS from AI tools or templates\n * built as standalone widgets — those commonly declare `position: fixed` with their own\n * top/right/bottom/left on their own top-level element, assuming THEY own placement. For\n * banner/popup/inline, viewport placement is already owned by the SDK's outer wrapper (the\n * Position selector's `xenia-pos-*` class) — a nested `position: fixed` element ignores its\n * ancestor's positioning entirely, so the pasted markup's own placement silently wins over\n * whatever the marketer picked in the Position dropdown.\n *\n * modal is deliberately exempt: it's always full-viewport/centered (no anchor to conflict with),\n * and modal templates commonly nest a `width:100%;height:100%` backdrop a level or two below\n * their own `position:fixed` top-level wrapper. Forcing that wrapper out of the fixed/positioned\n * chain would leave the backdrop's percentage sizing resolving against a content-sized ancestor\n * instead of the viewport, shrinking it down to the card's own bounding box — a worse visual bug\n * than the one this is meant to fix. The double-backdrop problem for modal (its own + the SDK's)\n * is solved separately, by suppressing the SDK's own backdrop (see xenia-custom-bg).\n *\n * Wraps custom HTML in a container so dismiss heuristics have a stable place to query, and — for\n * banner/popup/inline only — forces `position: static` (`!important`) on its direct top-level\n * children, neutralizing any such declarations so the SDK's wrapper is always the single source of\n * truth for where the message sits. The style travels inline with the fragment (not the shared\n * stylesheet) so this works whether the fragment lands in the shadow-DOM message wrapper or a\n * host-page slot (`inline` placement). Nested/descendant elements are untouched either way — only\n * top-level offsets are ever reset.\n */\nfunction wrapCustomHtml(html: string, variant: MessagePlacement): string {\n if (variant === \"modal\") {\n return `<div class=\"xenia-custom-html\">${html}</div>`;\n }\n return (\n `<div class=\"xenia-custom-html\">` +\n `<style>.xenia-custom-html{position:relative}` +\n `.xenia-custom-html>*{position:static!important;inset:auto!important;` +\n `top:auto!important;right:auto!important;bottom:auto!important;left:auto!important}</style>` +\n `${html}</div>`\n );\n}\n\nfunction escapeHtml(s: string): string {\n return s.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n}\n\nfunction escapeAttr(s: string): string {\n return escapeHtml(s).replace(/\"/g, \"&quot;\");\n}\n\n/**\n * Minimal, self-contained styling for message UI (isolated in shadow DOM).\n *\n * Every visually-meaningful value is a `var(--xenia-*, <fallback>)` so a host page can override\n * it just by declaring the custom property anywhere in its own light-DOM CSS (e.g. on `:root`) —\n * custom properties inherit through the shadow boundary. See CSS_VARIABLES.md for the full list.\n * Deliberately NOT declared as a default anywhere in this stylesheet (not even on `:host`): a\n * direct declaration here would out-rank an inherited value from the host page and silently\n * defeat the override, so the fallback in each `var()` call is the only default.\n */\nconst STYLES = `\n:host { all: initial; }\n.xenia-msg { position: fixed; z-index: var(--xenia-z-index, 2147483000);\n font-family: var(--xenia-font-family, system-ui, sans-serif); }\n.xenia-banner { left: 0; right: 0; }\n.xenia-banner.xenia-pos-top { top: 0; }\n.xenia-banner.xenia-pos-bottom { bottom: 0; }\n.xenia-popup { max-width: var(--xenia-popup-max-width, 360px); }\n.xenia-popup.xenia-pos-top-left { top: var(--xenia-popup-offset, 16px); left: var(--xenia-popup-offset, 16px); }\n.xenia-popup.xenia-pos-top-right { top: var(--xenia-popup-offset, 16px); right: var(--xenia-popup-offset, 16px); }\n.xenia-popup.xenia-pos-bottom-left { bottom: var(--xenia-popup-offset, 16px); left: var(--xenia-popup-offset, 16px); }\n.xenia-popup.xenia-pos-bottom-right { bottom: var(--xenia-popup-offset, 16px); right: var(--xenia-popup-offset, 16px); }\n.xenia-modal { inset: 0; display: flex; align-items: center; justify-content: center;\n background: var(--xenia-modal-backdrop, rgba(0,0,0,.12)); }\n.xenia-modal.xenia-custom-bg { background: transparent; }\n.xenia-modal.xenia-no-overlay { background: transparent; }\n.xenia-card { position: relative; background: var(--xenia-card-bg, #fff); color: var(--xenia-card-color, #111);\n border-radius: var(--xenia-card-radius, 12px); box-shadow: var(--xenia-card-shadow, 0 10px 40px rgba(0,0,0,.18));\n padding: var(--xenia-card-padding, 16px 18px); display: flex; gap: var(--xenia-card-gap, 12px);\n align-items: center; }\n.xenia-banner .xenia-card { border-radius: var(--xenia-banner-card-radius, 0); justify-content: center; }\n.xenia-modal .xenia-card { max-width: var(--xenia-modal-max-width, 440px); width: calc(100% - 32px); }\n.xenia-card.xenia-widget { flex-direction: column; align-items: center; text-align: center; }\n.xenia-img { width: var(--xenia-img-size, 56px); height: var(--xenia-img-size, 56px); object-fit: cover;\n border-radius: var(--xenia-img-radius, 8px); }\n.xenia-title { font-weight: var(--xenia-title-weight, 600); font-size: var(--xenia-title-size, 15px);\n margin-bottom: var(--xenia-title-gap, 2px); }\n.xenia-body { font-size: var(--xenia-body-size, 14px); line-height: var(--xenia-body-line-height, 1.4);\n color: var(--xenia-body-color, #444); }\n.xenia-cta { margin-top: 10px; background: var(--xenia-cta-bg, #111); color: var(--xenia-cta-color, #fff);\n border: 0; border-radius: var(--xenia-cta-radius, 8px); padding: var(--xenia-cta-padding, 8px 14px);\n font-size: var(--xenia-cta-size, 14px); cursor: pointer; }\n.xenia-close { position: absolute; top: 6px; right: 8px; background: none; border: 0;\n font-size: var(--xenia-close-size, 20px); line-height: 1; cursor: pointer; color: var(--xenia-close-color, #999); }\n.xenia-wheel-dial { transform-box: fill-box; transform-origin: center; }\n.xenia-wheel-hub { fill: var(--xenia-wheel-pointer-color, #111); }\n.xenia-wheel-wrap { position: relative; display: inline-block; }\n.xenia-wheel-pointer { position: absolute; top: -6px; left: 50%; transform: translateX(-50%);\n width: 0; height: 0; border-left: 9px solid transparent; border-right: 9px solid transparent;\n border-top: 14px solid var(--xenia-wheel-pointer-color, #111); pointer-events: none; }\n.xenia-wheel-spin { margin-top: 10px; background: var(--xenia-cta-bg, #111); color: var(--xenia-cta-color, #fff);\n border: 0; border-radius: var(--xenia-cta-radius, 8px); padding: var(--xenia-cta-padding, 8px 14px);\n font-size: var(--xenia-cta-size, 14px); font-family: inherit; cursor: pointer; }\n.xenia-wheel-spin:disabled { opacity: 0.6; cursor: default; }\n/* The spinner face and the win/loss screens are siblings toggled via the 'hidden' attribute —\n during crossFadeReveal's ~320ms crossfade, BOTH the outgoing and incoming screen are visible\n (not hidden) at once, so without this they'd stack in normal block flow and roughly double\n this box's height for that window. Since .xenia-modal's flexbox re-centers on every height\n change, that briefly-doubled height yanks the whole card to a new position with ZERO\n animation — right before the scale-down transition starts animating smoothly from that\n already-jumped spot, reading as \"not scaling from center\". Grid-stacking every child into the\n same cell (sized to the tallest non-hidden one) makes the outgoing/incoming screens overlay in\n place instead of stacking, so there is no discrete height jump to correct for. */\n.xenia-spin-wheel { display: grid; }\n.xenia-spin-wheel > * { grid-area: 1 / 1; }\n/* No animation/transform here — spin-wheel's win/loss screens are ALWAYS full\n custom HTML now (winHtml/lossHtml), never this class's own generated icon/title/prize/cta\n content (those sub-classes below are unreachable dead CSS, kept only for backwards-compat with\n any already-saved artifact that might still reference them). A transform on THIS wrapper\n would make it the CSS containing block for any fixed/absolute-positioned descendant the\n author's own HTML uses (a real, common case — a \"full-screen overlay\" win/loss design) — the\n fixed child would then size/position itself relative to this wrapper's own small, in-flow,\n often off-center box instead of the true browser viewport, visibly popping in from/toward\n whatever corner the wrapper happens to sit at instead of scaling from the real screen center.\n spin-wheel.ts's crossFadeReveal owns the actual reveal transition (applied to the author's own\n top-level element, never this wrapper) — this class stays a bare, transform-free layout box. */\n.xenia-widget-result { display: flex; flex-direction: column; align-items: center; gap: 4px;\n padding: 8px 4px 2px; text-align: center; }\n.xenia-widget-result[hidden] { display: none; }\n.xenia-widget-result-icon { font-size: 40px; line-height: 1; }\n.xenia-widget-result-title { font-weight: var(--xenia-title-weight, 700); font-size: var(--xenia-title-size, 17px); }\n.xenia-widget-result-prize { font-weight: 600; font-size: 15px; color: var(--xenia-cta-bg, #111);\n background: var(--xenia-result-prize-bg, rgba(0,0,0,.06)); border-radius: var(--xenia-cta-radius, 8px);\n padding: 6px 14px; }\n.xenia-widget-result-cta { margin-top: 8px; background: var(--xenia-cta-bg, #111); color: var(--xenia-cta-color, #fff);\n border: 0; border-radius: var(--xenia-cta-radius, 8px); padding: var(--xenia-cta-padding, 8px 14px);\n font-size: var(--xenia-cta-size, 14px); font-family: inherit; cursor: pointer; }\n`;\n","import { compact, XeniaApi } from \"../core/api\";\nimport { consentCookie } from \"../core/cookie-names\";\nimport { buildEventPayload } from \"../core/event-payload\";\nimport { isBrowser } from \"../core/http-client\";\nimport { generateUlid, toEventId } from \"../core/id\";\nimport { personalizeContent, personalizePage } from \"../core/personalize-content\";\nimport type { EntryResolver, PageRef, PagePersonalizeOptions, PersonalizeContentResult } from \"../core/personalize-content\";\nimport {\n LocalStorageResponseStore,\n MemoryResponseStore,\n type ResponseStore,\n} from \"../core/response-store\";\nimport type {\n AnalyticsEventName,\n ConsentState,\n JsonValue,\n MessageComponentRenderer,\n MessageCta,\n MessageTemplateFn,\n ResolveBatchItem,\n ResolveBatchResult,\n ResolveOptions,\n ResolveResult,\n TrackOptions,\n WebhookResponse,\n WidgetFormSubmit,\n WidgetSubmitResponse,\n XeniaAction,\n XeniaConfig,\n XeniaEvent,\n} from \"../core/types\";\nimport { AnalyticsQueue } from \"./analytics-queue\";\nimport { AutoTracker } from \"./auto-track\";\nimport { Identity } from \"./identity\";\nimport { ActionRenderer, hideContent, showContent, swapContent } from \"./renderer\";\n\n/** Options controlling automatic behaviors. */\nexport interface XeniaClientOptions extends XeniaConfig {\n /** Enable declarative `data-xenia` auto-tracking. Default true. */\n autoTrack?: boolean;\n /** Throttle window (ms) for auto-tracked events. Default 1000. */\n throttleMs?: number;\n /** Viewport options for `view-port` interactions. */\n viewport?: { threshold?: number; rootMargin?: string; triggerOnce?: boolean };\n /** Automatically apply `xeniaActions` from webhook responses. Default true. */\n autoApplyActions?: boolean;\n /** Persist saved webhook responses to localStorage. Default true. */\n persistResponses?: boolean;\n /**\n * Replace the SDK's built-in card markup for every banner/popup/modal/inline\n * action that doesn't specify its own `html`. Applies system-wide.\n */\n messageTemplate?: MessageTemplateFn;\n /** Extra CSS appended to the message overlay's stylesheet (shadow-scoped). */\n messageStyles?: string;\n /**\n * Render a framework-native component (React, Vue, Svelte, …) for every\n * banner/popup/modal/inline action that doesn't specify its own `html`,\n * instead of an HTML string. Takes priority over `messageTemplate` when both\n * are set. See `reactMessageComponent()` in `/client/react` for the React\n * adapter.\n */\n messageComponent?: MessageComponentRenderer;\n /**\n * Honor `navigator.doNotTrack`/`globalPrivacyControl` by suppressing\n * analytics-only `track()` calls entirely (events aren't even queued). Journey\n * triggers (`track(..., { trigger: true })`) always fire. Default true.\n */\n respectDnt?: boolean;\n}\n\n/** Events emitted by the client for observability. */\nexport type ClientEvent = \"event\" | \"response\" | \"actions\" | \"error\" | \"identify\";\ntype Listener = (payload: unknown) => void;\n\n/**\n * High-level browser client. One instance wires identity, auto-tracking, and\n * webhook request/response with action rendering.\n */\nexport class XeniaClient {\n readonly api: XeniaApi;\n readonly identity: Identity;\n readonly responses: ResponseStore;\n\n private readonly options: XeniaClientOptions;\n private readonly renderer: ActionRenderer;\n private readonly analyticsQueue: AnalyticsQueue;\n private tracker: AutoTracker | null = null;\n /** The in-flight (or finished) boot; shared so concurrent `init()` calls start one tracker. */\n private booting: Promise<void> | null = null;\n /** Bumped by `destroy()`, so a boot still waiting on the device id knows to stop. */\n private generation = 0;\n private consentState: ConsentState;\n private readonly listeners = new Map<ClientEvent, Set<Listener>>();\n\n constructor(options: XeniaClientOptions) {\n this.options = options;\n const prefix = options.prefix ?? \"xenia\";\n this.identity = new Identity(prefix, options.visitorCookie ?? true);\n // Seed the SDK-owned visitor id when supplied (persisted locally only — no\n // network call, unlike the public identify()). The auto-resolved device id\n // is still the fallback anchor when this isn't set.\n if (options.visitorId) this.identity.identify(options.visitorId);\n // XeniaApi resolves/caches config.token / config.getToken internally.\n this.api = new XeniaApi(options);\n this.responses =\n options.persistResponses === false || !isBrowser()\n ? new MemoryResponseStore()\n : new LocalStorageResponseStore(prefix);\n this.renderer = new ActionRenderer((event, cta) => this.onCtaEvent(event, cta), {\n messageTemplate: options.messageTemplate,\n messageStyles: options.messageStyles,\n messageComponent: options.messageComponent,\n submitWidgetForm: (submit, fields, subOpts) =>\n this.submitWidgetForm(submit, fields, subOpts),\n });\n this.consentState = { ...options.consent };\n this.analyticsQueue = new AnalyticsQueue({\n debug: options.debug,\n // Stamp the *current* consent state at send time (not enqueue time) — an\n // event queued before consent was granted only ever gets flushed after\n // it's granted (gated by `analyticsAllowed()`), so by send time consent\n // has necessarily changed and the event's own snapshot would be stale.\n send: (events, opts) =>\n this.api.sendEvents(\n events.map((e) => ({ ...e, consent: this.consentState })),\n opts,\n ),\n });\n }\n\n /** Boot the client: resolve device id and start auto-tracking. Idempotent. */\n init(): Promise<void> {\n if (!isBrowser()) return Promise.resolve();\n return (this.booting ??= this.boot());\n }\n\n private async boot(): Promise<void> {\n const generation = this.generation;\n await this.identity.resolveDeviceId();\n // destroy() ran while we waited (React StrictMode's mount→unmount→mount, or a re-init):\n // starting the tracker now would leak one that nothing can stop, double-sending every click.\n if (generation !== this.generation) return;\n\n if (this.analyticsAllowed()) this.analyticsQueue.start();\n\n if (this.options.autoTrack !== false) {\n this.tracker = new AutoTracker({\n prefix: this.options.prefix ?? \"xenia\",\n throttleMs: this.options.throttleMs ?? 1000,\n viewport: {\n threshold: this.options.viewport?.threshold ?? 0.5,\n rootMargin: this.options.viewport?.rootMargin,\n triggerOnce: this.options.viewport?.triggerOnce ?? true,\n },\n // Declarative `data-xenia` elements fire journey triggers (immediate).\n fire: (eventId, interaction) =>\n this.track(eventId, { interactionType: interaction }, { trigger: true }),\n // `[data-xenia-slot]` elements fire analytics-only personalization events.\n fireSlot: (interaction, meta) => {\n this.track(\n \"customEvent\",\n {\n customEventName:\n interaction === \"impression\"\n ? \"personalization_impression\"\n : \"personalization_click\",\n contentKey: meta.contentKey,\n contentEntryId: meta.contentEntryId ?? null,\n baseEntryId: meta.baseEntryId ?? null,\n },\n { trigger: false },\n );\n },\n });\n this.tracker.start();\n }\n }\n\n /** Tear down listeners, observers, and injected UI. */\n destroy(): void {\n this.tracker?.stop();\n this.tracker = null;\n this.renderer.destroy();\n this.analyticsQueue.stop();\n this.booting = null;\n this.generation++;\n }\n\n // ── Identity ───────────────────────────────────────────────────────────────\n\n /**\n * Persist a visitor id, attached to every subsequent event, and bind it to\n * a known user server-side (`POST /api/events/v1/identify`, fire-and-\n * forget — resolves to an `\"identify\"` client event carrying `personId`).\n *\n * `extra.customerId`/`extra.email`, when supplied, are also persisted\n * ambiently (like the visitor id) so they ride on every later `resolve()`\n * call automatically — part of the SDK-provided-fields parity list.\n */\n identify(visitorId: string, extra?: { customerId?: string; email?: string }): void {\n this.identity.identify(visitorId);\n if (extra?.customerId !== undefined) this.identity.setCustomerId(extra.customerId);\n if (extra?.email !== undefined) this.identity.setEmail(extra.email);\n void this.api\n .identify({ xeniaVisitorId: visitorId, userId: extra?.customerId, email: extra?.email })\n .then((res) => this.emit(\"identify\", res))\n .catch((err: unknown) => this.emitError(err));\n }\n\n /** Override the customer-journey UUID (else derived from utm_id). */\n setJourneyId(id: string | null): void {\n this.identity.setJourneyId(id);\n }\n\n // ── Events ─────────────────────────────────────────────────────────────────\n\n /**\n * Send a unified event to `POST /api/events/v1`. Identity, UTM, page context,\n * and journey attribution are attached automatically. Delivery depends on\n * `opts.trigger`:\n *\n * - `trigger: true` — **journey trigger**: sent immediately (journeys are\n * latency-sensitive) and **bypasses client-side consent/DNT gating** (the\n * journey must fire; the backend still consent-gates the analytics half).\n * - `trigger: false` (default) — **analytics only**: enqueued to the batching\n * {@link AnalyticsQueue}, dropped entirely when Do Not Track/GPC is honored,\n * and held (not sent) until `consent({ analytics: true })` is granted.\n *\n * Pass `opts.eventId` (e.g. `\"ord-1001\"`) as a stable dedup key to keep the\n * analytics/conversion side idempotent; otherwise a ULID is generated.\n */\n track(\n eventName: AnalyticsEventName,\n props?: Record<string, JsonValue | undefined>,\n opts: TrackOptions = {},\n ): void {\n if (!isBrowser()) return;\n const trigger = opts.trigger === true;\n // Analytics-only events honor DNT/GPC; journey triggers always fire.\n if (!trigger && this.dntBlocked()) return;\n\n const event = this.buildEvent(eventName, props, opts);\n this.emit(\"event\", { eventName, event });\n\n if (trigger) {\n // Immediate, ungated send — reuses the queue's 4xx-drop/transient-requeue.\n void this.analyticsQueue.sendImmediate(event).catch((err: unknown) => this.emitError(err));\n } else {\n this.analyticsQueue.enqueue(event);\n if (this.analyticsAllowed()) this.analyticsQueue.start();\n }\n }\n\n /** Assemble a {@link XeniaEvent} from ambient identity/context + overrides. */\n private buildEvent(\n eventName: AnalyticsEventName,\n props: Record<string, JsonValue | undefined> | undefined,\n opts: TrackOptions,\n ): XeniaEvent {\n const ctx = this.identity.collectContext();\n let timezone: string | undefined;\n try {\n timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n } catch {\n /* ignore */\n }\n\n return {\n eventName,\n eventId: opts.eventId ? toEventId(opts.eventId) : generateUlid(),\n eventVersion: 1,\n occurredAtMs: Date.now(),\n source: \"xenia-js-sdk\",\n identity: {\n sessionId: this.identity.getSessionId(),\n // Caller extras (email/userId/phone/…) merge in here…\n ...opts.identity,\n // …but `xeniaVisitorId` is SDK-owned and set LAST, so a caller-supplied\n // value is always ignored (defence-in-depth alongside the CallerIdentity\n // type, which omits it). The anchor: the visitor id from `identify()` /\n // `config.visitorId` when set, else the auto-resolved device id — so an\n // anonymous event still carries an anchor and isn't dropped as\n // `missing_identity`. (The backend has no `deviceId` field; the device\n // id rides here as the visitor id instead.)\n xeniaVisitorId: ctx.visitorId ?? this.identity.getDeviceId() ?? undefined,\n },\n context: {\n pagePath: ctx.path,\n referrer: ctx.referrer,\n userAgent: navigator.userAgent,\n locale: navigator.language,\n timezone,\n journeyId: this.identity.getJourneyId() ?? undefined,\n utmSource: ctx.utmSource,\n utmMedium: ctx.utmMedium,\n utmCampaign: ctx.utmCampaign,\n utmContent: ctx.utmContent,\n ...opts.context,\n },\n properties: this.withUtmId(props, ctx.utmId),\n trigger: opts.trigger === true ? true : undefined,\n // `consent` is stamped fresh at send time by the queue's `send` wrapper\n // (see constructor) — not set here, since it may still change between\n // enqueue and flush (e.g. queued before consent is granted).\n };\n }\n\n /**\n * Ensure a captured journey-link `utm_id` rides in `properties.utm_id`.\n *\n * The backend attributes conversions in tiers: a conversion carrying\n * `properties.utm_id` (= the `customer_journey.uuid` from the link the\n * shopper clicked) is tied to that *exact* enrollment — **deterministic**\n * attribution — before any last-touch identity guess. `utm_id` is captured\n * from the landing URL and persisted for the session by {@link Identity}, so\n * a purchase fired pages later still credits the right journey without the\n * developer threading it through by hand. Never clobbers a developer-supplied\n * `utm_id`/`utmId`; a no-op when no journey-link `utm_id` was captured.\n */\n private withUtmId(\n props: Record<string, JsonValue | undefined> | undefined,\n utmId: string | undefined,\n ): Record<string, JsonValue | undefined> | undefined {\n if (!utmId) return props;\n if (props && (props.utm_id !== undefined || props.utmId !== undefined)) return props;\n return { ...props, utm_id: utmId };\n }\n\n // ── Personalization (REST resolve) ─────────────────────────────────────────\n\n /**\n * Resolve in-entry content personalization for one content key\n * (`POST /api/personalization/resolve`). Requires a configured SDK token\n * (`token`/`getToken`) — resolve is auth-required (unlike public event ingest).\n * With `merge: true` the returned `content` is server-spliced.\n */\n async resolve(contentKey: string, opts?: ResolveOptions): Promise<ResolveResult> {\n return this.api.resolve(contentKey, this.withVisitor(opts));\n }\n\n /** Resolve several content keys in one round-trip (`POST /api/personalization/resolve-batch`). */\n async resolveBatch(\n items: ResolveBatchItem[],\n opts?: ResolveOptions,\n ): Promise<ResolveBatchResult[]> {\n return this.api.resolveBatch(items, this.withVisitor(opts));\n }\n\n /**\n * Personalize a fetched CMS page: static swaps are applied from the payload, runtime targets are\n * decided by Xenia in one `resolve-entries` call per nesting level, and replacements are loaded\n * through `opts.cms` (e.g. `contentfulAdapter(...)`). Never throws — anything undecided within\n * `opts.timeoutMs` keeps its base content.\n */\n async personalizeContent<T>(page: T, opts: PagePersonalizeOptions): Promise<PersonalizeContentResult<T>> {\n return personalizeContent(page, { ...opts, resolve: this.entryResolver(opts) });\n }\n\n /**\n * Fetch a page through `opts.cms` and personalize it — the app passes only the page's identity\n * (entry id, or `{ contentType, fields: { slug } }`). Never throws: a failed fetch is `content:\n * null` with `error`, a missing page `content: null`.\n */\n async personalizePage<T = unknown>(ref: PageRef, opts: PagePersonalizeOptions): Promise<PersonalizeContentResult<T | null>> {\n return personalizePage<T>(ref, { ...opts, resolve: this.entryResolver(opts) });\n }\n\n private entryResolver(opts: PagePersonalizeOptions): EntryResolver {\n const resolveOpts = { ...this.withVisitor({ data: opts.data, locale: opts.locale }), contentKey: opts.contentKey };\n return async (ids) => (await this.api.resolveEntries(ids, resolveOpts)).decisions ?? [];\n }\n\n /** The SDK-owned visitor anchor: the `identify()`/`config.visitorId` id, else the device id. */\n private resolveVisitorId(): string | undefined {\n return this.identity.getVisitorId() ?? this.identity.getDeviceId() ?? undefined;\n }\n\n /**\n * Stamp the full set of SDK-provided fields into the resolve `data` —\n * `path`, `query`, `deviceId`, `visitorId`, `customerId`, `email`, `url`,\n * `referrer`, and the five `utm*` fields — the same field-name/type parity\n * the webhook trigger's \"SDK-provided fields\" already promises, now native\n * (always attached, no marketer toggle) for the Personalization Resolve\n * trigger too. Plus the reserved `_xenia_vid` key the backend reads for\n * holdout/exposure bucketing. All of these are spread LAST (after the\n * caller's own `data`) so none can be overridden per call — the same\n * override-protection guarantee `_xenia_vid` alone used to have, now\n * widened to the full set. A no-op (returns `opts` unchanged) when nothing\n * is resolvable yet (e.g. called before `init()` on a fresh visit with no\n * page context available).\n */\n private withVisitor(opts?: ResolveOptions): ResolveOptions | undefined {\n const ctx = this.identity.collectContext();\n const vid = this.resolveVisitorId();\n const sdkFields = compact({\n path: ctx.path,\n query: ctx.query as JsonValue | undefined,\n deviceId: this.identity.getDeviceId() ?? undefined,\n visitorId: vid,\n customerId: this.identity.getCustomerId() ?? undefined,\n email: this.identity.getEmail() ?? undefined,\n url: ctx.url,\n referrer: ctx.referrer,\n utmSource: ctx.utmSource,\n utmMedium: ctx.utmMedium,\n utmCampaign: ctx.utmCampaign,\n utmContent: ctx.utmContent,\n utmId: ctx.utmId,\n });\n if (vid) sdkFields._xenia_vid = vid;\n if (Object.keys(sdkFields).length === 0) return opts;\n return { ...opts, data: { ...(opts?.data ?? {}), ...sdkFields } };\n }\n\n private dntBlocked(): boolean {\n if (this.options.respectDnt === false) return false;\n try {\n const nav = navigator as Navigator & { globalPrivacyControl?: boolean };\n const dnt = navigator.doNotTrack ?? (window as unknown as { doNotTrack?: string }).doNotTrack;\n if (dnt === \"1\" || dnt === \"yes\") return true;\n if (nav.globalPrivacyControl === true) return true;\n } catch {\n /* ignore */\n }\n return false;\n }\n\n private analyticsAllowed(): boolean {\n return this.consentState.analytics === true;\n }\n\n // ── Webhook request/response ─────────────────────────────────────────────────\n\n /**\n * Send a webhook request to a journey trigger and await its synchronous\n * response (from the `webhook-response` node). The response is saved to the\n * response store (keyed by `triggerId`) and any `xeniaActions` are applied.\n */\n async request(\n triggerId: string,\n data?: Record<string, JsonValue | undefined>,\n opts?: { apply?: boolean; method?: \"GET\" | \"POST\" },\n ): Promise<WebhookResponse> {\n const ctx = this.identity.collectContext();\n const body = buildEventPayload({\n eventId: triggerId,\n journeyId: this.identity.getJourneyId() ?? undefined,\n // SDK-owned visitor anchor (identify()/config.visitorId, else device id) —\n // buildEventPayload merges identity last, so a caller `data.visitorId`\n // can't override it. The webhook/`/flow` field maps to xeniaVisitorId.\n identity: {\n deviceId: this.identity.getDeviceId() ?? undefined,\n visitorId: this.resolveVisitorId(),\n },\n context: ctx,\n props: data,\n });\n\n const response = await this.api.webhook(triggerId, body as JsonValue, opts?.method ?? \"POST\");\n this.responses.set(triggerId, response);\n this.emit(\"response\", { triggerId, response });\n\n const apply = opts?.apply ?? this.options.autoApplyActions !== false;\n if (apply && response.actions.length) {\n this.applyActions(response.actions);\n }\n return response;\n }\n\n /** Read the last saved webhook response for a key (triggerId/eventId). */\n getResponse(key: string): WebhookResponse | undefined {\n return this.responses.get(key);\n }\n\n /**\n * Submit a widget's captured form values (standard/custom popup submit, or a spin-wheel/\n * spin-wheel's resolve request) and apply any returned `xeniaActions`, exactly like\n * {@link request}.\n *\n * **Endpoint selection is config-driven, not SDK-decided** (per the cross-repo contract): a\n * `flowRef` (present only when `mode === \"journey\" && !requiresResolve` — the common\n * plain-popup case) bypasses the resolve endpoint entirely and POSTs straight to the existing\n * public `/flow` fast path; otherwise this POSTs to `/widget-submissions` via `bindingRef`. The\n * SDK is agnostic to *why* — it just follows whichever ref field the backend populated.\n *\n * The full ambient-context parity list {@link request}/`withVisitor()` already build\n * (visitorId, deviceId, url, referrer, path, query, `utm*`) rides on every call, plus `fields`\n * and `submit.mode`/the resolved ref, relayed verbatim/uninterpreted — the SDK never branches\n * on `mode`'s value itself, that's server-side.\n *\n * `opts.idempotencyKey` defaults to a freshly generated ULID; pass the SAME key back in on a\n * retried submit of the same interaction so a network retry can't double-fire a journey or\n * double-resolve a prize server-side.\n */\n async submitWidgetForm(\n submit: WidgetFormSubmit,\n fields: Record<string, string>,\n opts?: { idempotencyKey?: string; apply?: boolean },\n ): Promise<WidgetSubmitResponse> {\n const ctx = this.identity.collectContext();\n const idempotencyKey = opts?.idempotencyKey ?? generateUlid();\n const ref = submit.flowRef ?? submit.bindingRef;\n const ambient = {\n visitorId: this.resolveVisitorId(),\n deviceId: this.identity.getDeviceId() ?? undefined,\n idempotencyKey,\n mode: submit.mode,\n ref,\n url: ctx.url,\n referrer: ctx.referrer,\n path: ctx.path,\n query: ctx.query as JsonValue | undefined,\n utmSource: ctx.utmSource,\n utmMedium: ctx.utmMedium,\n utmCampaign: ctx.utmCampaign,\n utmContent: ctx.utmContent,\n utmId: ctx.utmId,\n };\n\n // `/flow` (flowRef) is the pre-existing, generic webhook-trigger endpoint — it templates\n // `{{fieldName}}` against ROOT-level body keys (matching `config.bodyParams`), same as any\n // other webhook caller, so captured fields must be spread flat, NOT nested. `/widget-submissions`\n // (bindingRef) is this feature's own purpose-built endpoint, whose `WidgetSubmissionRequest`\n // DTO reads a real `fields` object — that shape must stay nested.\n const response = submit.flowRef\n ? await this.api.webhook(submit.flowRef, compact({ ...ambient, ...fields }) as JsonValue, \"POST\")\n : await this.api.submitWidget(\n submit.bindingRef ?? \"\",\n compact({ ...ambient, fields: fields as unknown as JsonValue }) as JsonValue,\n );\n\n this.emit(\"response\", { triggerId: ref, response });\n const apply = opts?.apply ?? this.options.autoApplyActions !== false;\n if (apply && response.actions.length) this.applyActions(response.actions);\n return response as WidgetSubmitResponse;\n }\n\n // ── Imperative render helpers ─────────────────────────────────────────────────\n\n swapContent(target: string, content: { html?: string; text?: string }): boolean {\n return swapContent(target, content);\n }\n hideContent(target: string): boolean {\n return hideContent(target);\n }\n showContent(target: string): boolean {\n return showContent(target);\n }\n\n /** Apply an arbitrary list of actions (e.g. from a custom response). */\n applyActions(actions: XeniaAction[]): number {\n const count = this.renderer.apply(actions);\n this.emit(\"actions\", { actions, applied: count });\n return count;\n }\n\n // ── Consent ─────────────────────────────────────────────────────────────────\n\n async consent(state: ConsentState): Promise<void> {\n const wasAllowed = this.analyticsAllowed();\n this.consentState = { ...this.consentState, ...state };\n // Mirror to a cookie so same-origin server code (`getConsent(cookieHeader)`) sees the choice.\n if (isBrowser()) {\n try {\n document.cookie = consentCookie(this.consentState, this.options.prefix);\n } catch {\n /* document.cookie unavailable */\n }\n }\n if (this.analyticsAllowed() && !wasAllowed) {\n this.analyticsQueue.start();\n void this.analyticsQueue.flush();\n } else if (!this.analyticsAllowed() && wasAllowed) {\n this.analyticsQueue.stop();\n }\n\n const vid = this.identity.getVisitorId() ?? this.identity.getDeviceId();\n if (!vid) return;\n try {\n await this.api.consent(vid, state);\n } catch (err) {\n this.emitError(err);\n }\n }\n\n // ── Events / observability ────────────────────────────────────────────────────\n\n on(event: ClientEvent, listener: Listener): () => void {\n const set = this.listeners.get(event) ?? new Set<Listener>();\n set.add(listener);\n this.listeners.set(event, set);\n return () => set.delete(listener);\n }\n\n private emit(event: ClientEvent, payload: unknown): void {\n this.listeners.get(event)?.forEach((l) => {\n try {\n l(payload);\n } catch {\n /* listener errors are the listener's problem */\n }\n });\n }\n\n private emitError(err: unknown): void {\n const error = err instanceof Error ? err : new Error(String(err));\n if (this.options.debug) console.error(\"[xenia]\", error);\n this.emit(\"error\", error);\n }\n\n private onCtaEvent(event: string, cta: MessageCta): void {\n this.track(event, { ctaLabel: cta.label, ctaUrl: cta.url ?? null }, { trigger: true });\n }\n}\n\n/** Create (but do not init) a client. Call `.init()` to start. */\nexport function createXeniaClient(options: XeniaClientOptions): XeniaClient {\n return new XeniaClient(options);\n}\n","import { createContext, useContext } from \"react\";\nimport type { XeniaClient } from \"../xenia-client\";\n\n/** React context carrying the singleton {@link XeniaClient}. */\nexport const XeniaContext = createContext<XeniaClient | null>(null);\n\n/**\n * Access the client provided by `<XeniaProvider>`. Throws when used outside a\n * provider so misconfiguration fails loudly in development.\n */\nexport function useXenia(): XeniaClient {\n const client = useContext(XeniaContext);\n if (!client) {\n throw new Error(\"useXenia must be used within a <XeniaProvider>.\");\n }\n return client;\n}\n","import { useEffect, useMemo, useRef, type ReactNode } from \"react\";\nimport { createXeniaClient, type XeniaClient, type XeniaClientOptions } from \"../xenia-client\";\nimport { XeniaContext } from \"./context\";\n\nexport interface XeniaProviderProps extends XeniaClientOptions {\n children: ReactNode;\n /**\n * Reuse an already-created client instead of creating one from props. Useful\n * for sharing a single client across React and non-React code.\n */\n client?: XeniaClient;\n}\n\n/**\n * Wraps the app and boots a single {@link XeniaClient}. Everything below it can\n * call `useXenia()`, `useTrack()`, `usePersonalization()`, `useWebhook()`, and\n * render the `<XeniaTrack>` / `<XeniaMessage>` components.\n *\n * @example\n * ```tsx\n * <XeniaProvider tenantId=\"t1\" environmentKey=\"prod\">\n * <App />\n * </XeniaProvider>\n * ```\n */\nexport function XeniaProvider({ children, client, ...options }: XeniaProviderProps) {\n // Create once; ignore prop churn (options are read at init).\n const ref = useRef<XeniaClient | null>(null);\n const instance = useMemo(() => {\n if (client) return client;\n if (!ref.current) ref.current = createXeniaClient(options as XeniaClientOptions);\n return ref.current;\n }, [client]);\n\n useEffect(() => {\n void instance.init();\n return () => instance.destroy();\n }, [instance]);\n\n return <XeniaContext.Provider value={instance}>{children}</XeniaContext.Provider>;\n}\n","import type { JsonValue } from \"./types\";\n\n/**\n * A single content swap, as emitted in a webhook-response body's\n * `xeniaContentSwaps` array (the multi-slot personalization analogue of\n * `xeniaActions`). `identifier` is `\"<slotKey>\"` (whole-slot replace) or\n * `\"<slotKey>.<dotted.path>\"` addressing a node inside that slot's JSON\n * (object keys or array indices).\n *\n * NOTE: this field name/shape is a proposed contract, not yet emitted by any\n * journey node — confirm with the Journey Orchestrator (FE/BE) team before\n * relying on it in production.\n */\nexport interface ContentSwap {\n identifier: string;\n replacement: JsonValue;\n /** `\"replace\"` (default) swaps the whole matched node; `\"merge\"` shallow-merges when both sides are objects. */\n mode?: \"replace\" | \"merge\";\n}\n\nfunction isPlainObject(v: JsonValue): v is { [key: string]: JsonValue } {\n return v !== null && typeof v === \"object\" && !Array.isArray(v);\n}\n\nfunction cloneJson<T extends JsonValue>(value: T): T {\n return value === null || typeof value !== \"object\" ? value : (JSON.parse(JSON.stringify(value)) as T);\n}\n\nfunction setAtPath(node: JsonValue, path: string[], value: JsonValue, mode: \"replace\" | \"merge\"): JsonValue {\n if (path.length === 0) {\n if (mode === \"merge\" && isPlainObject(node) && isPlainObject(value)) {\n return { ...node, ...value };\n }\n return value;\n }\n\n const [key, ...rest] = path;\n if (Array.isArray(node)) {\n const index = Number(key);\n if (!Number.isInteger(index) || index < 0 || index >= node.length) return node;\n const next = node.slice();\n next[index] = setAtPath(next[index], rest, value, mode);\n return next;\n }\n if (isPlainObject(node)) {\n if (!(key in node)) return node;\n return { ...node, [key]: setAtPath(node[key], rest, value, mode) };\n }\n return node;\n}\n\n/**\n * Splice `swaps` into a base map of named content slots, recursively at any\n * nesting depth. Defensive by design (mirrors the PHP SDK's personalization\n * client): a swap whose `identifier` doesn't resolve to an existing slot/path\n * is silently ignored rather than thrown — this never fails, it degrades to\n * the base slot value. Slots are deep-cloned; inputs are never mutated.\n */\nexport function spliceSlots(\n slots: Record<string, JsonValue>,\n swaps: ContentSwap[] | undefined,\n): Record<string, JsonValue> {\n const result: Record<string, JsonValue> = {};\n for (const [key, value] of Object.entries(slots)) {\n result[key] = cloneJson(value);\n }\n if (!swaps) return result;\n\n for (const swap of swaps) {\n const [slotKey, ...pathParts] = swap.identifier.split(\".\");\n if (!(slotKey in result)) continue;\n result[slotKey] = setAtPath(result[slotKey], pathParts, swap.replacement, swap.mode ?? \"replace\");\n }\n return result;\n}\n\n/** Extract `xeniaContentSwaps` from a webhook-response body, if present and well-formed. */\nexport function extractContentSwaps(body: JsonValue): ContentSwap[] | undefined {\n if (!isPlainObject(body)) return undefined;\n const swaps = body.xeniaContentSwaps;\n return Array.isArray(swaps) ? (swaps as unknown as ContentSwap[]) : undefined;\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { extractContentSwaps, spliceSlots } from \"../../core/content-splice\";\nimport type {\n AnalyticsEventName,\n JsonValue,\n ResolveBatchItem,\n ResolveBatchResult,\n ResolveResult,\n TrackOptions,\n WebhookResponse,\n} from \"../../core/types\";\nimport { useXenia } from \"./context\";\n\n/**\n * Stable unified `track(eventName, props?, opts?)` bound to the provider's\n * client. `opts.trigger: true` fires a journey trigger immediately (ungated);\n * the default (`false`) records a batched, consent-gated analytics event. Pass\n * `opts.eventId` for an idempotent dedup key.\n */\nexport function useTrack(): (\n eventName: AnalyticsEventName,\n props?: Record<string, JsonValue | undefined>,\n opts?: TrackOptions,\n) => void {\n const xenia = useXenia();\n return useCallback(\n (eventName, props, opts) => {\n xenia.track(eventName, props, opts);\n },\n [xenia],\n );\n}\n\nexport interface UsePersonalizationResult {\n data: JsonValue | null;\n isLoading: boolean;\n error: Error | null;\n}\n\n/**\n * Resolve personalization by firing a webhook trigger and treating its\n * response body as the personalized data — re-resolves when the trigger id or\n * the serialized `data` changes. Never throws: falls back to `data: null` so\n * the caller can render its own base/fallback content.\n */\nexport function usePersonalization(\n triggerId: string,\n data?: Record<string, JsonValue | undefined>,\n): UsePersonalizationResult {\n const xenia = useXenia();\n const [result, setResult] = useState<JsonValue | null>(null);\n const [isLoading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const dataKey = JSON.stringify(data ?? {});\n\n useEffect(() => {\n let active = true;\n setLoading(true);\n setError(null);\n xenia\n .request(triggerId, data, { apply: false })\n .then((r) => {\n if (active) setResult(r.body);\n })\n .catch((e: unknown) => {\n if (active) setError(e instanceof Error ? e : new Error(String(e)));\n })\n .finally(() => {\n if (active) setLoading(false);\n });\n return () => {\n active = false;\n };\n }, [xenia, triggerId, dataKey]);\n\n return { data: result, isLoading, error };\n}\n\nexport interface UsePersonalizationSlotsResult {\n data: Record<string, JsonValue>;\n isLoading: boolean;\n error: Error | null;\n}\n\n/**\n * Resolve several named content slots from ONE webhook round-trip — a\n * webhook-backed batch-resolve, analogous to a REST personalization client's\n * \"resolve many slots at once\". The response body's `xeniaContentSwaps` array\n * (see `ContentSwap` in `core/content-splice`) is spliced into `slots`\n * recursively; slots with no matching swap come back unchanged. Never throws:\n * degrades to `slots` as-is, so it's always safe to render immediately.\n *\n * Depends on the journey's Webhook Response node emitting `xeniaContentSwaps`\n * — confirm this contract with the Journey Orchestrator team before relying\n * on it in production.\n */\nexport function usePersonalizationSlots(\n triggerId: string,\n slots: Record<string, JsonValue>,\n data?: Record<string, JsonValue | undefined>,\n): UsePersonalizationSlotsResult {\n const xenia = useXenia();\n const [result, setResult] = useState<Record<string, JsonValue>>(slots);\n const [isLoading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const slotsKey = JSON.stringify(slots);\n const dataKey = JSON.stringify(data ?? {});\n\n useEffect(() => {\n let active = true;\n setLoading(true);\n setError(null);\n xenia\n .request(triggerId, data, { apply: false })\n .then((r) => {\n if (!active) return;\n setResult(spliceSlots(slots, extractContentSwaps(r.body)));\n })\n .catch((e: unknown) => {\n if (active) setError(e instanceof Error ? e : new Error(String(e)));\n })\n .finally(() => {\n if (active) setLoading(false);\n });\n return () => {\n active = false;\n };\n }, [xenia, triggerId, dataKey, slotsKey]);\n\n return { data: result, isLoading, error };\n}\n\nexport interface UsePersonalizationResolveResult {\n data: ResolveResult | null;\n isLoading: boolean;\n error: Error | null;\n}\n\n/**\n * Resolve in-entry content personalization for one content key against the REST\n * endpoint (`POST /api/personalization/resolve`) — the production path,\n * alongside the webhook-backed {@link usePersonalization}. Re-resolves when the\n * content key or serialized `data`/`locale` changes. Requires a configured SDK\n * token (resolve is auth-required); exposes the error otherwise. With\n * `merge: true` the result's `content` is server-spliced.\n */\nexport function usePersonalizationResolve(\n contentKey: string,\n opts?: { data?: Record<string, JsonValue | undefined>; locale?: string; merge?: boolean },\n): UsePersonalizationResolveResult {\n const xenia = useXenia();\n const [data, setData] = useState<ResolveResult | null>(null);\n const [isLoading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const optsKey = JSON.stringify({ data: opts?.data ?? {}, locale: opts?.locale, merge: opts?.merge });\n\n useEffect(() => {\n let active = true;\n setLoading(true);\n setError(null);\n xenia\n .resolve(contentKey, opts)\n .then((r) => {\n if (active) setData(r);\n })\n .catch((e: unknown) => {\n if (active) setError(e instanceof Error ? e : new Error(String(e)));\n })\n .finally(() => {\n if (active) setLoading(false);\n });\n return () => {\n active = false;\n };\n }, [xenia, contentKey, optsKey]);\n\n return { data, isLoading, error };\n}\n\nexport interface UsePersonalizationResolveSlotsResult {\n data: ResolveBatchResult[] | null;\n isLoading: boolean;\n error: Error | null;\n}\n\n/**\n * Resolve several content keys in one REST round-trip\n * (`POST /api/personalization/resolve-batch`, ≤50) — the batch analogue of\n * {@link usePersonalizationResolve}. Re-resolves when the item list or\n * serialized `data`/`locale` changes.\n */\nexport function usePersonalizationResolveSlots(\n items: ResolveBatchItem[],\n opts?: { data?: Record<string, JsonValue | undefined>; locale?: string; merge?: boolean },\n): UsePersonalizationResolveSlotsResult {\n const xenia = useXenia();\n const [data, setData] = useState<ResolveBatchResult[] | null>(null);\n const [isLoading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const itemsKey = JSON.stringify(items);\n const optsKey = JSON.stringify({ data: opts?.data ?? {}, locale: opts?.locale, merge: opts?.merge });\n\n useEffect(() => {\n let active = true;\n setLoading(true);\n setError(null);\n xenia\n .resolveBatch(items, opts)\n .then((r) => {\n if (active) setData(r);\n })\n .catch((e: unknown) => {\n if (active) setError(e instanceof Error ? e : new Error(String(e)));\n })\n .finally(() => {\n if (active) setLoading(false);\n });\n return () => {\n active = false;\n };\n }, [xenia, itemsKey, optsKey]);\n\n return { data, isLoading, error };\n}\n\nexport interface UseWebhookResult {\n send: (data?: Record<string, JsonValue | undefined>) => Promise<WebhookResponse | null>;\n response: WebhookResponse | null;\n isLoading: boolean;\n error: Error | null;\n}\n\n/**\n * Imperatively send a webhook request/response for a trigger. The latest\n * response is exposed and its actions auto-applied (per client config).\n */\nexport function useWebhook(triggerId: string): UseWebhookResult {\n const xenia = useXenia();\n const [response, setResponse] = useState<WebhookResponse | null>(\n () => xenia.getResponse(triggerId) ?? null,\n );\n const [isLoading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const idRef = useRef(triggerId);\n idRef.current = triggerId;\n\n const send = useCallback(\n async (data?: Record<string, JsonValue | undefined>) => {\n setLoading(true);\n setError(null);\n try {\n const r = await xenia.request(idRef.current, data);\n setResponse(r);\n return r;\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n return null;\n } finally {\n setLoading(false);\n }\n },\n [xenia],\n );\n\n return { send, response, isLoading, error };\n}\n\n/** Read the last saved webhook response for a key (reactive to sends via re-render). */\nexport function useXeniaResponse(key: string): WebhookResponse | undefined {\n const xenia = useXenia();\n return xenia.getResponse(key);\n}\n","import { createContext, createElement, useContext, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { pendingTargets } from \"../../core/personalize-content\";\nimport type { AppliedSwap, PageRef, PagePersonalizeOptions } from \"../../core/personalize-content\";\nimport { useXenia } from \"./context\";\n\n/** Where one personalized entry stands while the page resolves. */\nexport type EntryStatus = \"pending\" | \"personalized\" | \"base\";\n\nexport interface UsePersonalizedContentOptions extends PagePersonalizeOptions {\n /**\n * What to render before Xenia answers:\n * - `\"base-first\"` (default): the CMS content immediately, swapped in place round by round\n * (best LCP; personalized sections can visibly change).\n * - `\"hide-until-resolved\"`: `content` is null until done or `hideTimeoutMs` — render a skeleton\n * while `isLoading` (no flicker, costs up to `hideTimeoutMs` of blank).\n */\n render?: \"base-first\" | \"hide-until-resolved\";\n /** Cap on the hidden period for `\"hide-until-resolved\"`. Default: `timeoutMs` (300). */\n hideTimeoutMs?: number;\n}\n\nexport interface UsePersonalizedContentResult<T> {\n content: T | null;\n isLoading: boolean;\n /**\n * True once every personalized entry was decided. False while loading, and after a timeout or a\n * failed Xenia/CMS call — the undecided entries then show their base content.\n */\n complete: boolean;\n applied: AppliedSwap[];\n /** Per-entry state, for skeletons / fades on just the sections being decided. */\n status(entryId: string): EntryStatus;\n}\n\n/**\n * Personalize a CMS page in the browser — `XeniaClient.personalizeContent` as a hook. Re-runs when\n * `page` (by identity) or the serialized `data`/`locale` change. Never throws: on failure the base\n * content renders. For pages that can render on the server, prefer `XeniaServer.personalizeContent`\n * (no flicker, no client round trip).\n */\nexport function usePersonalizedContent<T>(\n page: T | null | undefined,\n opts: UsePersonalizedContentOptions,\n): UsePersonalizedContentResult<T> {\n const xenia = useXenia();\n const hide = opts.render === \"hide-until-resolved\";\n // Known from the markers before any network — `status()` is \"pending\" from the very first render\n // (server render included), so a skeleton shows instead of base content that is about to change.\n const initialPending = useMemo(\n () => new Set(page == null ? [] : pendingTargets(page, opts.cms, opts.contentKey)),\n [page, opts.contentKey], // markers live in `page`; a new adapter object for the same page changes nothing\n );\n const [state, setState] = useState<{\n page: T | null | undefined; content: T | null; done: boolean; complete: boolean; applied: AppliedSwap[]; pending: Set<string>;\n }>(\n () => ({ page, content: hide ? null : (page ?? null), done: false, complete: false, applied: [], pending: initialPending }),\n );\n // The adapter/callbacks are usually re-created every render; only data/locale/page re-run it.\n const optsRef = useRef(opts);\n optsRef.current = opts;\n const optsKey = JSON.stringify({ data: opts.data ?? {}, locale: opts.locale, contentKey: opts.contentKey });\n\n useEffect(() => {\n if (page == null) return;\n let active = true;\n const o = optsRef.current;\n setState({ page, content: hide ? null : page, done: false, complete: false, applied: [], pending: initialPending });\n const reveal = hide\n ? setTimeout(() => active && setState((s) => (s.content ? s : { ...s, content: page })), o.hideTimeoutMs ?? o.timeoutMs ?? 300)\n : undefined;\n\n const applied: AppliedSwap[] = [];\n void xenia\n .personalizeContent(page, {\n ...o,\n onApplied(swap) {\n applied.push(swap);\n o.onApplied?.(swap);\n },\n onProgress(p) {\n o.onProgress?.(p);\n if (!active || hide) return;\n setState({ page, content: p.content as T, done: false, complete: false, applied: [...applied], pending: new Set(p.pending) });\n },\n })\n .then((r) => {\n if (active) setState({ page, content: r.content, done: true, complete: r.complete, applied: r.applied, pending: new Set() });\n })\n .finally(() => clearTimeout(reveal));\n return () => {\n active = false;\n clearTimeout(reveal);\n };\n }, [xenia, page, optsKey, hide, initialPending]);\n\n const personalized = new Set(state.applied.map((a) => a.target));\n // A render for a page whose run hasn't started yet: its targets are pending from the markers.\n const pending = state.page === page ? state.pending : initialPending;\n return {\n content: state.content,\n isLoading: page != null && !state.done,\n complete: state.complete,\n applied: state.applied,\n status: (id) => (pending.has(id) ? \"pending\" : personalized.has(id) ? \"personalized\" : \"base\"),\n };\n}\n\n/**\n * Fetch a page through `opts.cms` and personalize it in the browser — `usePersonalizedContent`\n * without the fetch in app code. `content` is null (and `isLoading` true) while the page loads; a\n * failed or missing page ends with `content: null`, `isLoading: false`.\n */\nexport function usePersonalizedPage<T = unknown>(\n ref: PageRef,\n opts: UsePersonalizedContentOptions,\n): UsePersonalizedContentResult<T> {\n const [page, setPage] = useState<{ value: T | null; loaded: boolean; failed?: boolean }>({ value: null, loaded: false });\n const cmsRef = useRef(opts.cms);\n cmsRef.current = opts.cms;\n const refKey = JSON.stringify([ref, opts.locale]);\n\n useEffect(() => {\n let active = true;\n setPage({ value: null, loaded: false });\n const fetchPage = cmsRef.current.fetchPage;\n Promise.resolve(fetchPage ? fetchPage.call(cmsRef.current, ref, opts.locale) : null)\n .then(\n (value) => active && setPage({ value: (value ?? null) as T | null, loaded: true }),\n () => active && setPage({ value: null, loaded: true, failed: true }),\n );\n return () => {\n active = false;\n };\n }, [refKey]); // refKey covers ref and locale\n\n const result = usePersonalizedContent<T>(page.value, opts);\n const complete = page.value == null ? page.loaded && !page.failed : result.complete;\n return { ...result, isLoading: !page.loaded || result.isLoading, complete };\n}\n\nconst PersonalizedContentContext = createContext<UsePersonalizedContentResult<unknown> | null>(null);\n\n/** Shares a `usePersonalizedContent` result with nested sections (`useXeniaEntry`). */\nexport function XeniaContentProvider(props: { value: UsePersonalizedContentResult<unknown>; children?: ReactNode }) {\n return createElement(PersonalizedContentContext.Provider, { value: props.value }, props.children);\n}\n\n/** Loading state of one entry inside a `<XeniaContentProvider>` — e.g. a skeleton for just that section. */\nexport function useXeniaEntry(entryId: string): { status: EntryStatus; isLoading: boolean } {\n const ctx = useContext(PersonalizedContentContext);\n const status = ctx ? ctx.status(entryId) : \"base\";\n return { status, isLoading: status === \"pending\" };\n}\n","import {\n createElement,\n useEffect,\n useRef,\n type ElementType,\n type ReactNode,\n} from \"react\";\nimport type { InteractionType, XeniaAction } from \"../../core/types\";\nimport { useXenia } from \"./context\";\n\nexport interface XeniaTrackProps {\n /** Event id to fire. */\n event: string;\n /** When to fire. Default \"click\". */\n on?: InteractionType;\n /** Extra properties merged into the event. */\n props?: Record<string, string | number | boolean | null>;\n /** Element type to render. Default \"span\". */\n as?: ElementType;\n children?: ReactNode;\n className?: string;\n}\n\n/**\n * Wrap any element to fire a Xenia event on click, viewport entry, or mount —\n * no `data-` attributes needed.\n */\nexport function XeniaTrack({\n event,\n on = \"click\",\n props,\n as = \"span\",\n children,\n className,\n}: XeniaTrackProps) {\n const xenia = useXenia();\n const ref = useRef<HTMLElement | null>(null);\n\n useEffect(() => {\n if (on === \"page-load\") {\n xenia.track(event, { ...props, interactionType: \"page-load\" }, { trigger: true });\n return;\n }\n if (on === \"view-port\") {\n const el = ref.current;\n if (!el) return;\n const observer = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n xenia.track(event, { ...props, interactionType: \"view-port\" }, { trigger: true });\n observer.disconnect();\n }\n }\n },\n { threshold: 0.5 },\n );\n observer.observe(el);\n return () => observer.disconnect();\n }\n return;\n }, [xenia, event, on]);\n\n const handlers =\n on === \"click\"\n ? {\n onClick: () =>\n xenia.track(event, { ...props, interactionType: \"click\" }, { trigger: true }),\n }\n : {};\n\n return createElement(as, { ref, className, ...handlers }, children);\n}\n\nexport interface XeniaMessageProps {\n /** Actions to render/apply on mount (e.g. from a saved response). */\n actions: XeniaAction[];\n}\n\n/** Imperatively apply a set of render actions when mounted. */\nexport function XeniaMessage({ actions }: XeniaMessageProps) {\n const xenia = useXenia();\n useEffect(() => {\n if (actions.length) xenia.applyActions(actions);\n }, [actions]);\n return null;\n}\n","import { createElement, type ComponentType } from \"react\";\nimport { createRoot, type Root } from \"react-dom/client\";\nimport type { MessageComponentRenderer, MessageMountContext } from \"../../core/types\";\n\n/**\n * Props a component registered via {@link reactMessageComponent} receives —\n * the action being rendered, its placement, and the `close`/`fireCta`\n * callbacks to call from your own markup (a close button, a CTA button, …).\n */\nexport type XeniaMessageComponentProps = MessageMountContext;\n\n/**\n * Adapts a plain React component into the framework-agnostic\n * `messageComponent` shape (`XeniaClientOptions.messageComponent` /\n * `<XeniaProvider messageComponent>`) — the React-native alternative to\n * building an HTML string with `messageTemplate`. The component is mounted\n * with `react-dom/client`'s `createRoot` and unmounted automatically when the\n * message is dismissed.\n *\n * @example\n * ```tsx\n * function OfferCard({ action, close, fireCta }: XeniaMessageComponentProps) {\n * return (\n * <div className=\"offer-card\">\n * <p>{action.message}</p>\n * {action.cta && <button onClick={fireCta}>{action.cta.label}</button>}\n * <button onClick={close} aria-label=\"Close\">×</button>\n * </div>\n * );\n * }\n *\n * <XeniaProvider messageComponent={reactMessageComponent(OfferCard)} ... />\n * ```\n */\nexport function reactMessageComponent(\n Component: ComponentType<XeniaMessageComponentProps>,\n): MessageComponentRenderer {\n return (container, ctx) => {\n const root: Root = createRoot(container);\n root.render(createElement(Component, ctx));\n return () => root.unmount();\n };\n}\n"]}