@perspective-ai/sdk-react 1.13.0-pr-64-20260706211041 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -273,6 +273,20 @@ import { FloatBubble } from "@perspective-ai/sdk-react";
273
273
  />
274
274
  ```
275
275
 
276
+ **With teaser control** (the welcome bubble above the button):
277
+
278
+ ```tsx
279
+ // Delay the teaser to 10s and mute the chime
280
+ <FloatBubble
281
+ researchId="your-research-id"
282
+ welcomeMessage="Have a question? I'm here to help."
283
+ teaser={{ delay: 10000, sound: false }}
284
+ />
285
+
286
+ // Disable the welcome sequence entirely (no teaser, chime, or dot)
287
+ <FloatBubble researchId="your-research-id" teaser={{ enabled: false }} />
288
+ ```
289
+
276
290
  ## Hook Options
277
291
 
278
292
  All hooks accept options from `EmbedConfig`:
@@ -284,6 +298,7 @@ interface UsePopupOptions {
284
298
  theme?: "light" | "dark" | "system";
285
299
  channel?: "TEXT" | "VOICE" | ["TEXT", "VOICE"]; // Interaction mode
286
300
  welcomeMessage?: string; // Teaser text (float only)
301
+ teaser?: TeaserConfig; // Teaser on/off, delay (ms), and chime sound (float only)
287
302
  buttonText?: string; // Trigger button text (popup/slider)
288
303
  params?: Record<string, string>;
289
304
  brand?: {
package/dist/index.cjs CHANGED
@@ -331,6 +331,7 @@ function useFloatBubble(options) {
331
331
  host,
332
332
  channel,
333
333
  welcomeMessage,
334
+ teaser,
334
335
  launcher,
335
336
  onReady,
336
337
  onSubmit,
@@ -357,6 +358,14 @@ function useFloatBubble(options) {
357
358
  onClose?.();
358
359
  }, [isControlled, onOpenChange, onClose]);
359
360
  const stableOnClose = useStableCallback(handleClose);
361
+ const teaserEnabled = teaser?.enabled;
362
+ const teaserDelay = teaser?.delay;
363
+ const teaserSound = teaser?.sound;
364
+ const hasTeaser = teaser !== void 0;
365
+ const stableTeaser = react.useMemo(
366
+ () => hasTeaser ? { enabled: teaserEnabled, delay: teaserDelay, sound: teaserSound } : void 0,
367
+ [hasTeaser, teaserEnabled, teaserDelay, teaserSound]
368
+ );
360
369
  const resolvedLauncher = react.useMemo(() => {
361
370
  if (!launcher) return void 0;
362
371
  const { icon, ...rest } = launcher;
@@ -383,6 +392,7 @@ function useFloatBubble(options) {
383
392
  host,
384
393
  channel,
385
394
  welcomeMessage,
395
+ teaser: stableTeaser,
386
396
  launcher: resolvedLauncher,
387
397
  onReady: stableOnReady,
388
398
  onSubmit: stableOnSubmit,
@@ -407,6 +417,7 @@ function useFloatBubble(options) {
407
417
  host,
408
418
  channel,
409
419
  welcomeMessage,
420
+ stableTeaser,
410
421
  resolvedLauncher,
411
422
  stableOnReady,
412
423
  stableOnSubmit,
@@ -736,6 +747,7 @@ function FloatBubble({
736
747
  host,
737
748
  channel,
738
749
  welcomeMessage,
750
+ teaser,
739
751
  disableJsonLdAttribution,
740
752
  launcher,
741
753
  onReady,
@@ -753,6 +765,7 @@ function FloatBubble({
753
765
  host,
754
766
  channel,
755
767
  welcomeMessage,
768
+ teaser,
756
769
  launcher,
757
770
  onReady,
758
771
  onSubmit,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hooks/useStableCallback.ts","../src/hooks/useEmbedConfig.ts","../src/hooks/usePopup.ts","../src/hooks/useSlider.ts","../src/hooks/useFloatBubble.ts","../src/hooks/useAutoOpen.ts","../src/hooks/useThemeSync.ts","../src/DiscoveryMetadata.tsx","../src/Widget.tsx","../src/Fullpage.tsx","../src/FloatBubble.tsx"],"names":["useLayoutEffect","useEffect","useRef","useCallback","useState","fetchEmbedConfig","openPopup","getPersistedOpenState","openSlider","useMemo","isValidElement","renderToStaticMarkup","createFloatBubble","markShown","shouldShow","setupTrigger","SDK_VERSION","jsx","perfLog","createWidget","Fragment","createLoadingIndicator","createFullpage"],"mappings":";;;;;;;;AAEA,IAAM,yBAAA,GACJ,OAAO,MAAA,KAAW,WAAA,GAAcA,qBAAA,GAAkBC,eAAA;AAE7C,SAAS,kBAEd,QAAA,EAAgB;AAChB,EAAA,MAAM,WAAA,GAAcC,aAAO,QAAQ,CAAA;AAEnC,EAAA,yBAAA,CAA0B,MAAM;AAC9B,IAAA,WAAA,CAAY,OAAA,GAAU,QAAA;AAAA,EACxB,CAAC,CAAA;AAKD,EAAA,MAAM,MAAA,GAASC,iBAAA;AAAA,KACZ,CAAA,GAAI,IAAA,KAAgB,WAAA,CAAY,OAAA,GAAU,GAAG,IAAI,CAAA;AAAA,IAClD;AAAC,GACH;AAEA,EAAA,OAAO,WAAW,MAAA,GAAS,QAAA;AAC7B;ACfO,SAAS,cAAA,CACd,YACA,IAAA,EACyB;AACzB,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIC,cAAA,EAExB;AAEF,EAAAH,gBAAU,MAAM;AACd,IAAA,IAAI,SAAA,GAAY,KAAA;AAChB,IAAAI,oBAAA,CAAiB,UAAA,EAAY,IAAI,CAAA,CAAE,IAAA,CAAK,CAAC,MAAA,KAAW;AAClD,MAAA,IAAI,CAAC,WAAW,QAAA,CAAS,EAAE,YAAY,IAAA,EAAM,MAAA,EAAQ,QAAQ,CAAA;AAAA,IAC/D,CAAC,CAAA;AACD,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,IAAA;AAAA,IACd,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,UAAA,EAAY,IAAI,CAAC,CAAA;AAGrB,EAAA,OAAO,OAAO,UAAA,KAAe,UAAA,IAAc,MAAM,IAAA,KAAS,IAAA,GACtD,MAAM,MAAA,GACN,MAAA;AACN;;;ACqBO,SAAS,SAAS,OAAA,EAA0C;AACjE,EAAA,MAAM;AAAA,IACJ,UAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA,IACA,IAAA;AAAA,IACA,YAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAA;AAAA,IACA,UAAA;AAAA,IACA,OAAA;AAAA,IACA,OAAA;AAAA,IACA,IAAA,EAAM,cAAA;AAAA,IACN;AAAA,GACF,GAAI,OAAA;AAEJ,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAID,eAA6B,IAAI,CAAA;AAC7D,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAIA,eAAS,KAAK,CAAA;AACtD,EAAA,MAAM,SAAA,GAAYF,aAA2B,IAAI,CAAA;AACjD,EAAA,MAAM,WAAA,GAAc,cAAA,CAAe,UAAA,EAAY,IAAI,CAAA;AACnD,EAAA,MAAM,cAAA,GAAiBA,aAAO,WAAW,CAAA;AACzC,EAAA,cAAA,CAAe,OAAA,GAAU,WAAA;AAEzB,EAAA,MAAM,eAAe,cAAA,KAAmB,MAAA;AACxC,EAAA,MAAM,MAAA,GAAS,eAAe,cAAA,GAAiB,YAAA;AAE/C,EAAA,MAAM,aAAA,GAAgB,kBAAkB,OAAO,CAAA;AAC/C,EAAA,MAAM,cAAA,GAAiB,kBAAkB,QAAQ,CAAA;AACjD,EAAA,MAAM,gBAAA,GAAmB,kBAAkB,UAAU,CAAA;AACrD,EAAA,MAAM,aAAA,GAAgB,kBAAkB,OAAO,CAAA;AAE/C,EAAA,MAAM,OAAA,GAAUC,iBAAAA;AAAA,IACd,CAAC,KAAA,KAAmB;AAClB,MAAA,IAAI,YAAA,EAAc;AAChB,QAAA,YAAA,GAAe,KAAK,CAAA;AAAA,MACtB,CAAA,MAAO;AACL,QAAA,eAAA,CAAgB,KAAK,CAAA;AAAA,MACvB;AAAA,IACF,CAAA;AAAA,IACA,CAAC,cAAc,YAAY;AAAA,GAC7B;AAEA,EAAA,MAAM,WAAA,GAAcA,kBAAY,MAAM;AACpC,IAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AACpB,IAAA,SAAA,CAAU,IAAI,CAAA;AACd,IAAA,OAAA,CAAQ,KAAK,CAAA;AACb,IAAA,OAAA,IAAU;AAAA,EACZ,CAAA,EAAG,CAAC,OAAA,EAAS,OAAO,CAAC,CAAA;AAErB,EAAA,MAAM,aAAA,GAAgB,kBAAkB,WAAW,CAAA;AAEnD,EAAA,MAAM,WAAA,GAAcA,kBAAY,MAAM;AACpC,IAAA,IAAI,SAAA,CAAU,OAAA,EAAS,OAAO,SAAA,CAAU,OAAA;AAExC,IAAA,MAAM,YAAYG,aAAA,CAAU;AAAA,MAC1B,UAAA;AAAA,MACA,MAAA;AAAA,MACA,KAAA;AAAA,MACA,KAAA;AAAA,MACA,IAAA;AAAA,MACA,YAAA;AAAA,MACA,YAAY,cAAA,CAAe,OAAA;AAAA,MAC3B,OAAA,EAAS,aAAA;AAAA,MACT,QAAA,EAAU,cAAA;AAAA,MACV,UAAA,EAAY,gBAAA;AAAA,MACZ,OAAA,EAAS,aAAA;AAAA,MACT,OAAA,EAAS;AAAA,KACV,CAAA;AAED,IAAA,SAAA,CAAU,OAAA,GAAU,SAAA;AACpB,IAAA,SAAA,CAAU,SAAS,CAAA;AACnB,IAAA,OAAO,SAAA;AAAA,EACT,CAAA,EAAG;AAAA,IACD,UAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA,IACA,IAAA;AAAA,IACA,YAAA;AAAA,IACA,aAAA;AAAA,IACA,cAAA;AAAA,IACA,gBAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,MAAM,YAAA,GAAeH,iBAAAA,CAAY,CAAC,IAAA,KAAgC;AAChE,IAAA,IAAI,UAAU,OAAA,EAAS;AACrB,MAAA,IAAI,SAAS,SAAA,EAAW;AACtB,QAAA,SAAA,CAAU,QAAQ,OAAA,EAAQ;AAAA,MAC5B,CAAA,MAAO;AACL,QAAA,SAAA,CAAU,QAAQ,OAAA,EAAQ;AAAA,MAC5B;AACA,MAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AACpB,MAAA,SAAA,CAAU,IAAI,CAAA;AAAA,IAChB;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,MAAA,GAASA,kBAAY,MAAM;AAC/B,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,YAAA,GAAe,IAAI,CAAA;AAAA,IACrB,CAAA,MAAO;AACL,MAAA,WAAA,EAAY;AACZ,MAAA,eAAA,CAAgB,IAAI,CAAA;AAAA,IACtB;AAAA,EACF,CAAA,EAAG,CAAC,YAAA,EAAc,YAAA,EAAc,WAAW,CAAC,CAAA;AAE5C,EAAA,MAAM,OAAA,GAAUA,kBAAY,MAAM;AAChC,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,YAAA,GAAe,KAAK,CAAA;AAAA,IACtB,CAAA,MAAO;AACL,MAAA,YAAA,CAAa,SAAS,CAAA;AACtB,MAAA,eAAA,CAAgB,KAAK,CAAA;AAAA,IACvB;AAAA,EACF,CAAA,EAAG,CAAC,YAAA,EAAc,YAAA,EAAc,YAAY,CAAC,CAAA;AAE7C,EAAA,MAAM,QAAA,GAAWA,kBAAY,MAAM;AACjC,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,OAAA,EAAQ;AAAA,IACV,CAAA,MAAO;AACL,MAAA,MAAA,EAAO;AAAA,IACT;AAAA,EACF,CAAA,EAAG,CAAC,MAAA,EAAQ,MAAA,EAAQ,OAAO,CAAC,CAAA;AAE5B,EAAAF,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,YAAA,EAAc;AAEnB,IAAA,IAAI,cAAA,IAAkB,CAAC,SAAA,CAAU,OAAA,EAAS;AACxC,MAAA,WAAA,EAAY;AAAA,IACd,CAAA,MAAA,IAAW,CAAC,cAAA,IAAkB,SAAA,CAAU,OAAA,EAAS;AAC/C,MAAA,YAAA,CAAa,SAAS,CAAA;AAAA,IACxB;AAAA,EACF,GAAG,CAAC,cAAA,EAAgB,YAAA,EAAc,WAAA,EAAa,YAAY,CAAC,CAAA;AAE5D,EAAAA,gBAAU,MAAM;AACd,IAAA,IAAI,YAAA,IAAgB,UAAU,OAAA,EAAS;AAEvC,IAAA,IAAIM,yBAAA,CAAsB,EAAE,UAAA,EAAY,IAAA,EAAM,SAAS,IAAA,EAAM,MAAM,IAAA,EAAM;AACvE,MAAA;AAAA,IACF;AAEA,IAAA,WAAA,EAAY;AACZ,IAAA,eAAA,CAAgB,IAAI,CAAA;AAAA,EACtB,GAAG,CAAC,WAAA,EAAa,IAAA,EAAM,YAAA,EAAc,UAAU,CAAC,CAAA;AAEhD,EAAAN,gBAAU,MAAM;AACd,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,UAAU,OAAA,EAAS;AACrB,QAAA,SAAA,CAAU,QAAQ,OAAA,EAAQ;AAC1B,QAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AAAA,MACtB;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,MAAA;AAAA,IACN,KAAA,EAAO,OAAA;AAAA,IACP,MAAA,EAAQ,QAAA;AAAA,IACR,MAAA;AAAA,IACA;AAAA,GACF;AACF;AC3KO,SAAS,UAAU,OAAA,EAA4C;AACpE,EAAA,MAAM;AAAA,IACJ,UAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA,IACA,IAAA;AAAA,IACA,YAAA;AAAA,IACA,UAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAA;AAAA,IACA,UAAA;AAAA,IACA,OAAA;AAAA,IACA,OAAA;AAAA,IACA,IAAA,EAAM,cAAA;AAAA,IACN;AAAA,GACF,GAAI,OAAA;AAEJ,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIG,eAA6B,IAAI,CAAA;AAC7D,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAIA,eAAS,KAAK,CAAA;AACtD,EAAA,MAAM,SAAA,GAAYF,aAA2B,IAAI,CAAA;AACjD,EAAA,MAAM,WAAA,GAAc,cAAA,CAAe,UAAA,EAAY,IAAI,CAAA;AACnD,EAAA,MAAM,cAAA,GAAiBA,aAAO,WAAW,CAAA;AACzC,EAAA,cAAA,CAAe,OAAA,GAAU,WAAA;AAEzB,EAAA,MAAM,eAAe,cAAA,KAAmB,MAAA;AACxC,EAAA,MAAM,MAAA,GAAS,eAAe,cAAA,GAAiB,YAAA;AAE/C,EAAA,MAAM,aAAA,GAAgB,kBAAkB,OAAO,CAAA;AAC/C,EAAA,MAAM,cAAA,GAAiB,kBAAkB,QAAQ,CAAA;AACjD,EAAA,MAAM,gBAAA,GAAmB,kBAAkB,UAAU,CAAA;AACrD,EAAA,MAAM,aAAA,GAAgB,kBAAkB,OAAO,CAAA;AAE/C,EAAA,MAAM,OAAA,GAAUC,iBAAAA;AAAA,IACd,CAAC,KAAA,KAAmB;AAClB,MAAA,IAAI,YAAA,EAAc;AAChB,QAAA,YAAA,GAAe,KAAK,CAAA;AAAA,MACtB,CAAA,MAAO;AACL,QAAA,eAAA,CAAgB,KAAK,CAAA;AAAA,MACvB;AAAA,IACF,CAAA;AAAA,IACA,CAAC,cAAc,YAAY;AAAA,GAC7B;AAEA,EAAA,MAAM,WAAA,GAAcA,kBAAY,MAAM;AACpC,IAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AACpB,IAAA,SAAA,CAAU,IAAI,CAAA;AACd,IAAA,OAAA,CAAQ,KAAK,CAAA;AACb,IAAA,OAAA,IAAU;AAAA,EACZ,CAAA,EAAG,CAAC,OAAA,EAAS,OAAO,CAAC,CAAA;AAErB,EAAA,MAAM,aAAA,GAAgB,kBAAkB,WAAW,CAAA;AAEnD,EAAA,MAAM,YAAA,GAAeA,kBAAY,MAAM;AACrC,IAAA,IAAI,SAAA,CAAU,OAAA,EAAS,OAAO,SAAA,CAAU,OAAA;AAExC,IAAA,MAAM,YAAYK,cAAA,CAAW;AAAA,MAC3B,UAAA;AAAA,MACA,MAAA;AAAA,MACA,KAAA;AAAA,MACA,KAAA;AAAA,MACA,IAAA;AAAA,MACA,YAAA;AAAA,MACA,UAAA;AAAA,MACA,YAAY,cAAA,CAAe,OAAA;AAAA,MAC3B,OAAA,EAAS,aAAA;AAAA,MACT,QAAA,EAAU,cAAA;AAAA,MACV,UAAA,EAAY,gBAAA;AAAA,MACZ,OAAA,EAAS,aAAA;AAAA,MACT,OAAA,EAAS;AAAA,KACV,CAAA;AAED,IAAA,SAAA,CAAU,OAAA,GAAU,SAAA;AACpB,IAAA,SAAA,CAAU,SAAS,CAAA;AACnB,IAAA,OAAO,SAAA;AAAA,EACT,CAAA,EAAG;AAAA,IACD,UAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA,IACA,IAAA;AAAA,IACA,YAAA;AAAA,IACA,UAAA;AAAA,IACA,aAAA;AAAA,IACA,cAAA;AAAA,IACA,gBAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,MAAM,aAAA,GAAgBL,iBAAAA,CAAY,CAAC,IAAA,KAAgC;AACjE,IAAA,IAAI,UAAU,OAAA,EAAS;AACrB,MAAA,IAAI,SAAS,SAAA,EAAW;AACtB,QAAA,SAAA,CAAU,QAAQ,OAAA,EAAQ;AAAA,MAC5B,CAAA,MAAO;AACL,QAAA,SAAA,CAAU,QAAQ,OAAA,EAAQ;AAAA,MAC5B;AACA,MAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AACpB,MAAA,SAAA,CAAU,IAAI,CAAA;AAAA,IAChB;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,MAAA,GAASA,kBAAY,MAAM;AAC/B,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,YAAA,GAAe,IAAI,CAAA;AAAA,IACrB,CAAA,MAAO;AACL,MAAA,YAAA,EAAa;AACb,MAAA,eAAA,CAAgB,IAAI,CAAA;AAAA,IACtB;AAAA,EACF,CAAA,EAAG,CAAC,YAAA,EAAc,YAAA,EAAc,YAAY,CAAC,CAAA;AAE7C,EAAA,MAAM,OAAA,GAAUA,kBAAY,MAAM;AAChC,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,YAAA,GAAe,KAAK,CAAA;AAAA,IACtB,CAAA,MAAO;AACL,MAAA,aAAA,CAAc,SAAS,CAAA;AACvB,MAAA,eAAA,CAAgB,KAAK,CAAA;AAAA,IACvB;AAAA,EACF,CAAA,EAAG,CAAC,YAAA,EAAc,YAAA,EAAc,aAAa,CAAC,CAAA;AAE9C,EAAA,MAAM,QAAA,GAAWA,kBAAY,MAAM;AACjC,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,OAAA,EAAQ;AAAA,IACV,CAAA,MAAO;AACL,MAAA,MAAA,EAAO;AAAA,IACT;AAAA,EACF,CAAA,EAAG,CAAC,MAAA,EAAQ,MAAA,EAAQ,OAAO,CAAC,CAAA;AAE5B,EAAAF,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,YAAA,EAAc;AAEnB,IAAA,IAAI,cAAA,IAAkB,CAAC,SAAA,CAAU,OAAA,EAAS;AACxC,MAAA,YAAA,EAAa;AAAA,IACf,CAAA,MAAA,IAAW,CAAC,cAAA,IAAkB,SAAA,CAAU,OAAA,EAAS;AAC/C,MAAA,aAAA,CAAc,SAAS,CAAA;AAAA,IACzB;AAAA,EACF,GAAG,CAAC,cAAA,EAAgB,YAAA,EAAc,YAAA,EAAc,aAAa,CAAC,CAAA;AAE9D,EAAAA,gBAAU,MAAM;AACd,IAAA,IAAI,YAAA,IAAgB,UAAU,OAAA,EAAS;AAEvC,IAAA,IAAIM,yBAAAA,CAAsB,EAAE,UAAA,EAAY,IAAA,EAAM,UAAU,IAAA,EAAM,MAAM,IAAA,EAAM;AACxE,MAAA;AAAA,IACF;AAEA,IAAA,YAAA,EAAa;AACb,IAAA,eAAA,CAAgB,IAAI,CAAA;AAAA,EACtB,GAAG,CAAC,YAAA,EAAc,IAAA,EAAM,YAAA,EAAc,UAAU,CAAC,CAAA;AAEjD,EAAAN,gBAAU,MAAM;AACd,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,UAAU,OAAA,EAAS;AACrB,QAAA,SAAA,CAAU,QAAQ,OAAA,EAAQ;AAC1B,QAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AAAA,MACtB;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,MAAA;AAAA,IACN,KAAA,EAAO,OAAA;AAAA,IACP,MAAA,EAAQ,QAAA;AAAA,IACR,MAAA;AAAA,IACA;AAAA,GACF;AACF;AC3IO,SAAS,eACd,OAAA,EACsB;AACtB,EAAA,MAAM;AAAA,IACJ,UAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA,IACA,IAAA;AAAA,IACA,OAAA;AAAA,IACA,cAAA;AAAA,IACA,QAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAA;AAAA,IACA,UAAA;AAAA,IACA,OAAA;AAAA,IACA,OAAA;AAAA,IACA,IAAA,EAAM,cAAA;AAAA,IACN;AAAA,GACF,GAAI,OAAA;AAEJ,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIG,eAA6B,IAAI,CAAA;AAC7D,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAIA,eAAS,KAAK,CAAA;AACtD,EAAA,MAAM,SAAA,GAAYF,aAA2B,IAAI,CAAA;AACjD,EAAA,MAAM,WAAA,GAAc,cAAA,CAAe,UAAA,EAAY,IAAI,CAAA;AAEnD,EAAA,MAAM,eAAe,cAAA,KAAmB,MAAA;AAExC,EAAA,MAAM,aAAA,GAAgB,kBAAkB,OAAO,CAAA;AAC/C,EAAA,MAAM,cAAA,GAAiB,kBAAkB,QAAQ,CAAA;AACjD,EAAA,MAAM,gBAAA,GAAmB,kBAAkB,UAAU,CAAA;AACrD,EAAA,MAAM,aAAA,GAAgB,kBAAkB,OAAO,CAAA;AAE/C,EAAA,MAAM,WAAA,GAAcC,kBAAY,MAAM;AACpC,IAAA,eAAA,CAAgB,KAAK,CAAA;AACrB,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,YAAA,GAAe,KAAK,CAAA;AAAA,IACtB;AACA,IAAA,OAAA,IAAU;AAAA,EACZ,CAAA,EAAG,CAAC,YAAA,EAAc,YAAA,EAAc,OAAO,CAAC,CAAA;AAExC,EAAA,MAAM,aAAA,GAAgB,kBAAkB,WAAW,CAAA;AAGnD,EAAA,MAAM,gBAAA,GAAmBM,cAAQ,MAA2C;AAC1E,IAAA,IAAI,CAAC,UAAU,OAAO,MAAA;AACtB,IAAA,MAAM,EAAE,IAAA,EAAM,GAAG,IAAA,EAAK,GAAI,QAAA;AAE1B,IAAA,IACE,IAAA,KAAS,SACT,IAAA,KAAS,IAAA,IACT,SAAS,MAAA,IACT,IAAA,KAAS,CAAA,IACT,IAAA,KAAS,EAAA,EACT;AACA,MAAA,OAAO,OAAO,IAAA,CAAK,IAAI,CAAA,CAAE,MAAA,GAAS,IAAI,IAAA,GAAO,MAAA;AAAA,IAC/C;AACA,IAAA,IAAIC,oBAAA,CAAe,IAAI,CAAA,EAAG;AACxB,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,IAAA,EAAM,EAAE,GAAA,EAAKC,2BAAA,CAAqB,IAAI,CAAA,EAAE,EAAE;AAAA,IAC9D;AAEA,IAAA,IAAI,IAAA,KAAS,SAAA,IAAa,IAAA,KAAS,QAAA,EAAU;AAC3C,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,IAAA,EAAmC;AAAA,IACvD;AACA,IAAA,IAAI,OAAO,IAAA,KAAS,QAAA,KAAa,KAAA,IAAS,IAAA,IAAQ,SAAS,IAAA,CAAA,EAAO;AAChE,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,IAAA,EAAgD;AAAA,IACpE;AAEA,IAAA,OAAO,OAAO,IAAA,CAAK,IAAI,CAAA,CAAE,MAAA,GAAS,IAAI,IAAA,GAAO,MAAA;AAAA,EAC/C,CAAA,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAAV,gBAAU,MAAM;AACd,IAAA,MAAM,YAAYW,qBAAA,CAAkB;AAAA,MAClC,UAAA;AAAA,MACA,MAAA;AAAA,MACA,KAAA;AAAA,MACA,KAAA;AAAA,MACA,IAAA;AAAA,MACA,OAAA;AAAA,MACA,cAAA;AAAA,MACA,QAAA,EAAU,gBAAA;AAAA,MACV,OAAA,EAAS,aAAA;AAAA,MACT,QAAA,EAAU,cAAA;AAAA,MACV,UAAA,EAAY,gBAAA;AAAA,MACZ,OAAA,EAAS,aAAA;AAAA,MACT,OAAA,EAAS;AAAA,KACV,CAAA;AAED,IAAA,SAAA,CAAU,OAAA,GAAU,SAAA;AACpB,IAAA,SAAA,CAAU,SAAS,CAAA;AAEnB,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,SAAA,CAAU,YAAY,SAAA,EAAW;AACnC,QAAA,SAAA,CAAU,OAAA,EAAQ;AAClB,QAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AACpB,QAAA,SAAA,CAAU,IAAI,CAAA;AAAA,MAChB;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG;AAAA,IACD,UAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA,IACA,IAAA;AAAA,IACA,OAAA;AAAA,IACA,cAAA;AAAA,IACA,gBAAA;AAAA,IACA,aAAA;AAAA,IACA,cAAA;AAAA,IACA,gBAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACD,CAAA;AAGD,EAAAX,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,WAAA,IAAe,CAAC,SAAA,CAAU,OAAA,EAAS;AAExC,IAAC,SAAA,CAAU,QAAQ,MAAA,CAAe;AAAA,MAChC,OAAA,EAAS,WAAA,CAAY,OAAA,IAAW,WAAA,CAAY,eAAA,IAAmB,MAAA;AAAA,MAC/D,gBAAgB,WAAA,CAAY,cAAA;AAAA,MAC5B,UAAA,EAAY;AAAA,KACb,CAAA;AAAA,EACH,CAAA,EAAG,CAAC,WAAW,CAAC,CAAA;AAEhB,EAAAA,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,YAAA,IAAgB,CAAC,MAAA,EAAQ;AAE9B,IAAA,IAAI,cAAA,IAAkB,CAAC,MAAA,CAAO,MAAA,EAAQ;AACpC,MAAA,MAAA,CAAO,IAAA,EAAK;AAAA,IACd,CAAA,MAAA,IAAW,CAAC,cAAA,IAAkB,MAAA,CAAO,MAAA,EAAQ;AAC3C,MAAA,MAAA,CAAO,KAAA,EAAM;AAAA,IACf;AAAA,EACF,CAAA,EAAG,CAAC,cAAA,EAAgB,YAAA,EAAc,MAAM,CAAC,CAAA;AAEzC,EAAA,MAAM,MAAA,GAASE,kBAAY,MAAM;AAC/B,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,YAAA,GAAe,IAAI,CAAA;AAAA,IACrB,CAAA,MAAO;AACL,MAAA,SAAA,CAAU,SAAS,IAAA,EAAK;AACxB,MAAA,eAAA,CAAgB,IAAI,CAAA;AAAA,IACtB;AAAA,EACF,CAAA,EAAG,CAAC,YAAA,EAAc,YAAY,CAAC,CAAA;AAE/B,EAAA,MAAM,OAAA,GAAUA,kBAAY,MAAM;AAChC,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,YAAA,GAAe,KAAK,CAAA;AAAA,IACtB,CAAA,MAAO;AACL,MAAA,SAAA,CAAU,SAAS,KAAA,EAAM;AACzB,MAAA,eAAA,CAAgB,KAAK,CAAA;AAAA,IACvB;AAAA,EACF,CAAA,EAAG,CAAC,YAAA,EAAc,YAAY,CAAC,CAAA;AAE/B,EAAA,MAAM,QAAA,GAAWA,kBAAY,MAAM;AACjC,IAAA,MAAM,aAAA,GAAgB,SAAA,CAAU,OAAA,EAAS,MAAA,IAAU,YAAA;AACnD,IAAA,IAAI,aAAA,EAAe;AACjB,MAAA,OAAA,EAAQ;AAAA,IACV,CAAA,MAAO;AACL,MAAA,MAAA,EAAO;AAAA,IACT;AAAA,EACF,CAAA,EAAG,CAAC,YAAA,EAAc,MAAA,EAAQ,OAAO,CAAC,CAAA;AAElC,EAAA,MAAM,SAAA,GAAYA,kBAAY,MAAM;AAClC,IAAA,SAAA,CAAU,SAAS,OAAA,EAAQ;AAC3B,IAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AACpB,IAAA,SAAA,CAAU,IAAI,CAAA;AACd,IAAA,eAAA,CAAgB,KAAK,CAAA;AAAA,EACvB,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,MAAA,GAAS,YAAA,GACX,cAAA,GACC,MAAA,EAAQ,MAAA,IAAU,YAAA;AAEvB,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,MAAA;AAAA,IACN,KAAA,EAAO,OAAA;AAAA,IACP,MAAA,EAAQ,QAAA;AAAA,IACR,OAAA,EAAS,SAAA;AAAA,IACT,MAAA;AAAA,IACA;AAAA,GACF;AACF;AC/NO,SAAS,YAAY,OAAA,EAAgD;AAC1E,EAAA,MAAM,EAAE,OAAA,EAAS,QAAA,GAAW,WAAW,UAAA,EAAY,GAAG,aAAY,GAAI,OAAA;AACtE,EAAA,MAAM,UAAA,GAAaD,aAA4B,IAAI,CAAA;AACnD,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIE,eAAS,KAAK,CAAA;AAChD,EAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,IAAA,KAAS,SAAA,GAAY,QAAQ,KAAA,GAAQ,MAAA;AAClE,EAAA,MAAM,SAAA,GAAY,cAAA,CAAe,UAAA,EAAY,WAAA,CAAY,IAAI,CAAA;AAC7D,EAAA,MAAM,YAAA,GAAeF,aAAO,SAAS,CAAA;AACrC,EAAA,YAAA,CAAa,OAAA,GAAU,SAAA;AAGvB,EAAA,MAAM,eAAA,GAAkB,kBAAkB,MAAM;AAC9C,IAAAW,aAAA,CAAU,YAAY,QAAQ,CAAA;AAC9B,IAAAP,aAAAA,CAAU;AAAA,MACR,UAAA;AAAA,MACA,GAAG,WAAA;AAAA,MACH,YAAY,YAAA,CAAa;AAAA,KAC1B,CAAA;AAAA,EACH,CAAC,CAAA;AAED,EAAAL,gBAAU,MAAM;AACd,IAAA,IAAI,CAACa,cAAA,CAAW,UAAA,EAAY,QAAQ,CAAA,EAAG;AAEvC,IAAA,UAAA,CAAW,OAAA,GAAUC,gBAAA,CAAa,OAAA,EAAS,MAAM;AAC/C,MAAA,YAAA,CAAa,CAAC,IAAA,KAAS;AACrB,QAAA,IAAI,MAAM,OAAO,IAAA;AACjB,QAAA,eAAA,EAAgB;AAChB,QAAA,OAAO,IAAA;AAAA,MACT,CAAC,CAAA;AAAA,IACH,CAAC,CAAA;AAED,IAAA,OAAO,MAAM;AACX,MAAA,UAAA,CAAW,OAAA,IAAU;AACrB,MAAA,UAAA,CAAW,OAAA,GAAU,IAAA;AAAA,IACvB,CAAA;AAAA,EAGF,GAAG,CAAC,UAAA,EAAY,QAAQ,IAAA,EAAM,YAAA,EAAc,QAAQ,CAAC,CAAA;AAErD,EAAA,MAAM,MAAA,GAASZ,kBAAY,MAAM;AAC/B,IAAA,UAAA,CAAW,OAAA,IAAU;AACrB,IAAA,UAAA,CAAW,OAAA,GAAU,IAAA;AAAA,EACvB,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,OAAO,EAAE,QAAQ,SAAA,EAAU;AAC7B;AC7DO,SAAS,YAAA,CAAa,QAAoB,QAAA,EAAiB;AAGhE,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIC,cAAAA;AAAA,IAC9B,KAAA,KAAU,WAAW,KAAA,GAAQ;AAAA,GAC/B;AAEA,EAAAH,gBAAU,MAAM;AACd,IAAA,IAAI,UAAU,QAAA,EAAU;AACtB,MAAA,WAAA,CAAY,KAAK,CAAA;AACjB,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,EAAA,GAAK,MAAA,CAAO,UAAA,CAAW,8BAA8B,CAAA;AAG3D,IAAA,WAAA,CAAY,EAAA,CAAG,OAAA,GAAU,MAAA,GAAS,OAAO,CAAA;AAEzC,IAAA,MAAM,UAAU,CAAC,CAAA,KACf,YAAY,CAAA,CAAE,OAAA,GAAU,SAAS,OAAO,CAAA;AAE1C,IAAA,EAAA,CAAG,gBAAA,CAAiB,UAAU,OAAO,CAAA;AACrC,IAAA,OAAO,MAAM,EAAA,CAAG,mBAAA,CAAoB,QAAA,EAAU,OAAO,CAAA;AAAA,EACvD,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAEV,EAAA,OAAO,QAAA;AACT;ACjCA,IAAM,eAAA,GAAkB,2BAAA;AAgCjB,SAAS,iBAAA,CAAkB,EAAE,OAAA,EAAQ,EAA2B;AACrE,EAAA,MAAM,MAAA,GAAS;AAAA,IACb,UAAA,EAAY,oBAAA;AAAA,IACZ,QAAA,EAAU;AAAA,MACR;AAAA,QACE,OAAA,EAAS,qBAAA;AAAA,QACT,KAAA,EAAO,GAAG,eAAe,CAAA,QAAA,CAAA;AAAA,QACzB,IAAA,EAAM,gBAAA;AAAA,QACN,WAAA,EACE,8LAAA;AAAA,QACF,GAAA,EAAK,eAAA;AAAA,QACL,mBAAA,EAAqB,qBAAA;AAAA,QACrB,iBAAiB,OAAA,IAAWe,qBAAA;AAAA,QAC5B,QAAA,EAAU,EAAE,KAAA,EAAO,CAAA,EAAG,eAAe,CAAA,cAAA,CAAA,EAAiB;AAAA,QACtD,eAAA,EAAiB;AAAA,UACf,OAAA,EAAS,iBAAA;AAAA,UACT,WAAA,EAAa,GAAA;AAAA,UACb,UAAA,EAAY,GAAA;AAAA,UACZ,WAAA,EAAa,GAAA;AAAA,UACb,WAAA,EAAa,CAAA;AAAA,UACb,WAAA,EAAa;AAAA;AACf,OACF;AAAA,MACA;AAAA,QACE,OAAA,EAAS,cAAA;AAAA,QACT,KAAA,EAAO,GAAG,eAAe,CAAA,cAAA,CAAA;AAAA,QACzB,IAAA,EAAM,gBAAA;AAAA,QACN,GAAA,EAAK;AAAA;AACP;AACF,GACF;AAEA,EAAA,uBACEC,cAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,qBAAA;AAAA,MACL,yBAAA,EAAwB,EAAA;AAAA,MACxB,yBAAyB,EAAE,MAAA,EAAQ,IAAA,CAAK,SAAA,CAAU,MAAM,CAAA;AAAE;AAAA,GAC5D;AAEJ;AC7CO,SAAS,MAAA,CAAO;AAAA,EACrB,UAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,KAAA;AAAA,EACA,wBAAA;AAAA,EACA,OAAA;AAAA,EACA,aAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,KAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAgB;AACd,EAAA,MAAM,YAAA,GAAef,aAAuB,IAAI,CAAA;AAChD,EAAA,MAAM,SAAA,GAAYA,aAA2B,IAAI,CAAA;AAGjD,EAAA,MAAM,aAAA,GAAgB,kBAAkB,OAAO,CAAA;AAC/C,EAAA,MAAM,mBAAA,GAAsB,kBAAkB,aAAa,CAAA;AAC3D,EAAA,MAAM,cAAA,GAAiB,kBAAkB,QAAQ,CAAA;AACjD,EAAA,MAAM,gBAAA,GAAmB,kBAAkB,UAAU,CAAA;AACrD,EAAA,MAAM,aAAA,GAAgB,kBAAkB,OAAO,CAAA;AAC/C,EAAA,MAAM,aAAA,GAAgB,kBAAkB,OAAO,CAAA;AAE/C,EAAAD,gBAAU,MAAM;AACd,IAAA,MAAM,YAAY,YAAA,CAAa,OAAA;AAC/B,IAAA,IAAI,CAAC,SAAA,EAAW;AAEhB,IAAAiB,WAAA,CAAQ,WAAA,EAAa,uBAAA,EAAyB,EAAE,UAAA,EAAY,CAAA;AAK5D,IAAA,MAAM,MAAA,GAASC,iBAAa,SAAA,EAAW;AAAA,MACrC,UAAA;AAAA,MACA,MAAA;AAAA,MACA,KAAA;AAAA,MACA,KAAA;AAAA,MACA,IAAA;AAAA,MACA,KAAA;AAAA,MACA,wBAAA;AAAA,MACA,OAAA,EAAS,aAAA;AAAA,MACT,aAAA,EAAe,mBAAA;AAAA,MACf,QAAA,EAAU,cAAA;AAAA,MACV,UAAA,EAAY,gBAAA;AAAA,MACZ,OAAA,EAAS,aAAA;AAAA,MACT,OAAA,EAAS;AAAA,KACV,CAAA;AAED,IAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AAEpB,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,OAAA,GAAU,MAAA;AAAA,IACrB;AAEA,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,UAAU,OAAA,EAAS;AACrB,QAAA,SAAA,CAAU,QAAQ,OAAA,EAAQ;AAC1B,QAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AAAA,MACtB;AACA,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,QAAA,CAAS,OAAA,GAAU,IAAA;AAAA,MACrB;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG;AAAA,IACD,UAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA,IACA,IAAA;AAAA,IACA,KAAA;AAAA,IACA,wBAAA;AAAA,IACA,aAAA;AAAA,IACA,mBAAA;AAAA,IACA,cAAA;AAAA,IACA,gBAAA;AAAA,IACA,aAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,uCACGC,cAAA,EAAA,EACE,QAAA,EAAA;AAAA,IAAA,CAAC,wBAAA,oBAA4BH,cAAAA,CAAC,iBAAA,EAAA,EAAkB,CAAA;AAAA,oBACjDA,cAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,YAAA;AAAA,QACL,SAAA;AAAA,QACA,KAAA;AAAA,QACA,aAAA,EAAY,oBAAA;AAAA,QACX,GAAG;AAAA;AAAA;AACN,GAAA,EACF,CAAA;AAEJ;AC3GO,SAAS,QAAA,CAAS;AAAA,EACvB,UAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,wBAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAA,EAAkB;AAChB,EAAA,MAAM,SAAA,GAAYf,aAA2B,IAAI,CAAA;AAGjD,EAAA,MAAM,aAAA,GAAgB,kBAAkB,OAAO,CAAA;AAC/C,EAAA,MAAM,cAAA,GAAiB,kBAAkB,QAAQ,CAAA;AACjD,EAAA,MAAM,gBAAA,GAAmB,kBAAkB,UAAU,CAAA;AACrD,EAAA,MAAM,aAAA,GAAgB,kBAAkB,OAAO,CAAA;AAC/C,EAAA,MAAM,aAAA,GAAgB,kBAAkB,OAAO,CAAA;AAE/C,EAAAD,gBAAU,MAAM;AAEd,IAAA,MAAM,QAAA,GAAWoB,0BAAA,CAAuB,EAAE,KAAA,EAAO,OAAO,CAAA;AACxD,IAAA,QAAA,CAAS,MAAM,QAAA,GAAW,OAAA;AAC1B,IAAA,QAAA,CAAS,MAAM,KAAA,GAAQ,GAAA;AACvB,IAAA,QAAA,CAAS,MAAM,MAAA,GAAS,YAAA;AACxB,IAAA,QAAA,CAAS,IAAA,CAAK,YAAY,QAAQ,CAAA;AAElC,IAAA,IAAI,SAAA,GAAY,KAAA;AAEhB,IAAAhB,qBAAiB,UAAA,EAAY,IAAI,CAAA,CAAE,IAAA,CAAK,CAAC,MAAA,KAAW;AAClD,MAAA,IAAI,SAAA,EAAW;AACf,MAAA,QAAA,CAAS,MAAA,EAAO;AAEhB,MAAA,MAAM,SAASiB,kBAAA,CAAe;AAAA,QAC5B,UAAA;AAAA,QACA,MAAA;AAAA,QACA,KAAA;AAAA,QACA,KAAA;AAAA,QACA,IAAA;AAAA,QACA,wBAAA;AAAA,QACA,UAAA,EAAY,MAAA;AAAA,QACZ,OAAA,EAAS,aAAA;AAAA,QACT,QAAA,EAAU,cAAA;AAAA,QACV,UAAA,EAAY,gBAAA;AAAA,QACZ,OAAA,EAAS,aAAA;AAAA,QACT,OAAA,EAAS;AAAA,OACV,CAAA;AAED,MAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AAEpB,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,QAAA,CAAS,OAAA,GAAU,MAAA;AAAA,MACrB;AAAA,IACF,CAAC,CAAA;AAED,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,IAAA;AACZ,MAAA,QAAA,CAAS,MAAA,EAAO;AAChB,MAAA,IAAI,UAAU,OAAA,EAAS;AACrB,QAAA,SAAA,CAAU,QAAQ,OAAA,EAAQ;AAC1B,QAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AAAA,MACtB;AACA,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,QAAA,CAAS,OAAA,GAAU,IAAA;AAAA,MACrB;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG;AAAA,IACD,UAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA,IACA,IAAA;AAAA,IACA,wBAAA;AAAA,IACA,aAAA;AAAA,IACA,cAAA;AAAA,IACA,gBAAA;AAAA,IACA,aAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACD,CAAA;AAGD,EAAA,OAAO,wBAAA,GAA2B,IAAA,mBAAOL,cAAAA,CAAC,iBAAA,EAAA,EAAkB,CAAA;AAC9D;AChFO,SAAS,WAAA,CAAY;AAAA,EAC1B,UAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA;AAAA,EACA,cAAA;AAAA,EACA,wBAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAA,EAAqB;AACnB,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,cAAA,CAAe;AAAA,IAChC,UAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA,IACA,IAAA;AAAA,IACA,OAAA;AAAA,IACA,cAAA;AAAA,IAEA,QAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAA;AAAA,IACA,UAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAAhB,gBAAU,MAAM;AACd,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,OAAA,GAAU,MAAA;AAAA,IACrB;AACA,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,QAAA,CAAS,OAAA,GAAU,IAAA;AAAA,MACrB;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,QAAA,EAAU,MAAM,CAAC,CAAA;AAErB,EAAA,OAAO,wBAAA,GAA2B,IAAA,mBAAOgB,cAAAA,CAAC,iBAAA,EAAA,EAAkB,CAAA;AAC9D","file":"index.cjs","sourcesContent":["import { useRef, useCallback, useLayoutEffect, useEffect } from \"react\";\n\nconst useIsomorphicLayoutEffect =\n typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\nexport function useStableCallback<\n T extends ((...args: any[]) => any) | undefined,\n>(callback: T): T {\n const callbackRef = useRef(callback);\n\n useIsomorphicLayoutEffect(() => {\n callbackRef.current = callback;\n });\n\n // Always create the stable wrapper (hooks can't be conditional),\n // but return undefined when no callback is provided to preserve\n // truthiness semantics for consumers that branch on it.\n const stable = useCallback(\n ((...args: any[]) => callbackRef.current?.(...args)) as NonNullable<T>,\n []\n );\n\n return callback ? stable : callback;\n}\n","import { useState, useEffect } from \"react\";\nimport { fetchEmbedConfig, type ThemeConfig } from \"@perspective-ai/sdk\";\n\n/**\n * Fetch embed config (theme, appearance, launcher) from the API.\n * Returns undefined while loading, then the resolved config.\n * Results are cached and deduplicated across hooks sharing a researchId.\n */\nexport function useEmbedConfig(\n researchId: string,\n host?: string\n): ThemeConfig | undefined {\n const [state, setState] = useState<\n { researchId: string; host?: string; config: ThemeConfig } | undefined\n >();\n\n useEffect(() => {\n let cancelled = false;\n fetchEmbedConfig(researchId, host).then((result) => {\n if (!cancelled) setState({ researchId, host, config: result });\n });\n return () => {\n cancelled = true;\n };\n }, [researchId, host]);\n\n // Return undefined if config is for different researchId/host (stale)\n return state?.researchId === researchId && state.host === host\n ? state.config\n : undefined;\n}\n","import { useCallback, useState, useEffect, useRef } from \"react\";\nimport {\n getPersistedOpenState,\n openPopup,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./useStableCallback\";\nimport { useEmbedConfig } from \"./useEmbedConfig\";\n\n/** Options for usePopup hook */\nexport interface UsePopupOptions extends Omit<EmbedConfig, \"type\"> {\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n}\n\n/** Return type for usePopup hook */\nexport interface UsePopupReturn {\n /** Open the popup */\n open: () => void;\n /** Close the popup */\n close: () => void;\n /** Toggle the popup */\n toggle: () => void;\n /** Whether the popup is currently open */\n isOpen: boolean;\n /** The underlying SDK handle (null when closed) */\n handle: EmbedHandle | null;\n}\n\n/**\n * Headless hook for programmatic popup control.\n * Use this when you need custom trigger elements or programmatic control.\n *\n * @example\n * ```tsx\n * // Basic usage with custom trigger\n * const { open, isOpen } = usePopup({ researchId: \"abc\" });\n * <MyCustomButton onClick={open}>Open Survey</MyCustomButton>\n *\n * // Controlled mode\n * const [isOpen, setIsOpen] = useState(false);\n * const popup = usePopup({\n * researchId: \"abc\",\n * open: isOpen,\n * onOpenChange: setIsOpen\n * });\n * ```\n */\nexport function usePopup(options: UsePopupOptions): UsePopupReturn {\n const {\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n open: controlledOpen,\n onOpenChange,\n } = options;\n\n const [handle, setHandle] = useState<EmbedHandle | null>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const handleRef = useRef<EmbedHandle | null>(null);\n const embedConfig = useEmbedConfig(researchId, host);\n const embedConfigRef = useRef(embedConfig);\n embedConfigRef.current = embedConfig;\n\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnError = useStableCallback(onError);\n\n const setOpen = useCallback(\n (value: boolean) => {\n if (isControlled) {\n onOpenChange?.(value);\n } else {\n setInternalOpen(value);\n }\n },\n [isControlled, onOpenChange]\n );\n\n const handleClose = useCallback(() => {\n handleRef.current = null;\n setHandle(null);\n setOpen(false);\n onClose?.();\n }, [setOpen, onClose]);\n\n const stableOnClose = useStableCallback(handleClose);\n\n const createPopup = useCallback(() => {\n if (handleRef.current) return handleRef.current;\n\n const newHandle = openPopup({\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n _apiConfig: embedConfigRef.current,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = newHandle;\n setHandle(newHandle);\n return newHandle;\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n const destroyPopup = useCallback((mode: \"destroy\" | \"unmount\") => {\n if (handleRef.current) {\n if (mode === \"destroy\") {\n handleRef.current.destroy();\n } else {\n handleRef.current.unmount();\n }\n handleRef.current = null;\n setHandle(null);\n }\n }, []);\n\n const openFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(true);\n } else {\n createPopup();\n setInternalOpen(true);\n }\n }, [isControlled, onOpenChange, createPopup]);\n\n const closeFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(false);\n } else {\n destroyPopup(\"destroy\");\n setInternalOpen(false);\n }\n }, [isControlled, onOpenChange, destroyPopup]);\n\n const toggleFn = useCallback(() => {\n if (isOpen) {\n closeFn();\n } else {\n openFn();\n }\n }, [isOpen, openFn, closeFn]);\n\n useEffect(() => {\n if (!isControlled) return;\n\n if (controlledOpen && !handleRef.current) {\n createPopup();\n } else if (!controlledOpen && handleRef.current) {\n destroyPopup(\"destroy\");\n }\n }, [controlledOpen, isControlled, createPopup, destroyPopup]);\n\n useEffect(() => {\n if (isControlled || handleRef.current) return;\n\n if (getPersistedOpenState({ researchId, type: \"popup\", host }) !== true) {\n return;\n }\n\n createPopup();\n setInternalOpen(true);\n }, [createPopup, host, isControlled, researchId]);\n\n useEffect(() => {\n return () => {\n if (handleRef.current) {\n handleRef.current.unmount();\n handleRef.current = null;\n }\n };\n }, []);\n\n return {\n open: openFn,\n close: closeFn,\n toggle: toggleFn,\n isOpen,\n handle,\n };\n}\n","import { useCallback, useState, useEffect, useRef } from \"react\";\nimport {\n getPersistedOpenState,\n openSlider,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./useStableCallback\";\nimport { useEmbedConfig } from \"./useEmbedConfig\";\n\n/** Options for useSlider hook */\nexport interface UseSliderOptions extends Omit<EmbedConfig, \"type\"> {\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n}\n\n/** Return type for useSlider hook */\nexport interface UseSliderReturn {\n /** Open the slider */\n open: () => void;\n /** Close the slider */\n close: () => void;\n /** Toggle the slider */\n toggle: () => void;\n /** Whether the slider is currently open */\n isOpen: boolean;\n /** The underlying SDK handle (null when closed) */\n handle: EmbedHandle | null;\n}\n\n/**\n * Headless hook for programmatic slider control.\n * Use this when you need custom trigger elements or programmatic control.\n *\n * @example\n * ```tsx\n * const { open, isOpen } = useSlider({ researchId: \"abc\" });\n * <MyCustomButton onClick={open}>Give Feedback</MyCustomButton>\n * ```\n */\nexport function useSlider(options: UseSliderOptions): UseSliderReturn {\n const {\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n sliderMode,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n open: controlledOpen,\n onOpenChange,\n } = options;\n\n const [handle, setHandle] = useState<EmbedHandle | null>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const handleRef = useRef<EmbedHandle | null>(null);\n const embedConfig = useEmbedConfig(researchId, host);\n const embedConfigRef = useRef(embedConfig);\n embedConfigRef.current = embedConfig;\n\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnError = useStableCallback(onError);\n\n const setOpen = useCallback(\n (value: boolean) => {\n if (isControlled) {\n onOpenChange?.(value);\n } else {\n setInternalOpen(value);\n }\n },\n [isControlled, onOpenChange]\n );\n\n const handleClose = useCallback(() => {\n handleRef.current = null;\n setHandle(null);\n setOpen(false);\n onClose?.();\n }, [setOpen, onClose]);\n\n const stableOnClose = useStableCallback(handleClose);\n\n const createSlider = useCallback(() => {\n if (handleRef.current) return handleRef.current;\n\n const newHandle = openSlider({\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n sliderMode,\n _apiConfig: embedConfigRef.current,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = newHandle;\n setHandle(newHandle);\n return newHandle;\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n sliderMode,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n const destroySlider = useCallback((mode: \"destroy\" | \"unmount\") => {\n if (handleRef.current) {\n if (mode === \"destroy\") {\n handleRef.current.destroy();\n } else {\n handleRef.current.unmount();\n }\n handleRef.current = null;\n setHandle(null);\n }\n }, []);\n\n const openFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(true);\n } else {\n createSlider();\n setInternalOpen(true);\n }\n }, [isControlled, onOpenChange, createSlider]);\n\n const closeFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(false);\n } else {\n destroySlider(\"destroy\");\n setInternalOpen(false);\n }\n }, [isControlled, onOpenChange, destroySlider]);\n\n const toggleFn = useCallback(() => {\n if (isOpen) {\n closeFn();\n } else {\n openFn();\n }\n }, [isOpen, openFn, closeFn]);\n\n useEffect(() => {\n if (!isControlled) return;\n\n if (controlledOpen && !handleRef.current) {\n createSlider();\n } else if (!controlledOpen && handleRef.current) {\n destroySlider(\"destroy\");\n }\n }, [controlledOpen, isControlled, createSlider, destroySlider]);\n\n useEffect(() => {\n if (isControlled || handleRef.current) return;\n\n if (getPersistedOpenState({ researchId, type: \"slider\", host }) !== true) {\n return;\n }\n\n createSlider();\n setInternalOpen(true);\n }, [createSlider, host, isControlled, researchId]);\n\n useEffect(() => {\n return () => {\n if (handleRef.current) {\n handleRef.current.unmount();\n handleRef.current = null;\n }\n };\n }, []);\n\n return {\n open: openFn,\n close: closeFn,\n toggle: toggleFn,\n isOpen,\n handle,\n };\n}\n","import {\n useCallback,\n useState,\n useEffect,\n useRef,\n useMemo,\n isValidElement,\n} from \"react\";\nimport type { ReactNode } from \"react\";\nimport {\n createFloatBubble,\n type EmbedConfig,\n type FloatHandle,\n type LauncherConfig,\n} from \"@perspective-ai/sdk\";\nimport { renderToStaticMarkup } from \"react-dom/server\";\nimport { useStableCallback } from \"./useStableCallback\";\nimport { useEmbedConfig } from \"./useEmbedConfig\";\n\n/** Launcher config with React support — icon accepts ReactNode in addition to SDK types */\nexport interface LauncherConfigReact extends Omit<LauncherConfig, \"icon\"> {\n icon?: LauncherConfig[\"icon\"] | ReactNode;\n}\n\n/** Options for useFloatBubble hook */\nexport interface UseFloatBubbleOptions extends Omit<\n EmbedConfig,\n \"type\" | \"launcher\"\n> {\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Customize the floating launcher button appearance */\n launcher?: LauncherConfigReact;\n}\n\n/** Return type for useFloatBubble hook */\nexport interface UseFloatBubbleReturn {\n /** Open the float bubble window */\n open: () => void;\n /** Close the float bubble window */\n close: () => void;\n /** Toggle the float bubble window */\n toggle: () => void;\n /** Unmount the float bubble entirely */\n unmount: () => void;\n /** Whether the float bubble window is currently open */\n isOpen: boolean;\n /** The underlying SDK handle (null until mounted) */\n handle: FloatHandle | null;\n}\n\n/**\n * Headless hook for float bubble lifecycle management.\n * Creates a floating bubble button that expands into a chat window.\n * The bubble mounts on component mount and unmounts on component unmount.\n *\n * @example\n * ```tsx\n * // Basic usage - bubble mounts on component mount\n * useFloatBubble({ researchId: \"abc\" });\n *\n * // With programmatic control\n * const { open, close, isOpen } = useFloatBubble({ researchId: \"abc\" });\n * <button onClick={open}>Open Chat</button>\n * ```\n */\nexport function useFloatBubble(\n options: UseFloatBubbleOptions\n): UseFloatBubbleReturn {\n const {\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n launcher,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n open: controlledOpen,\n onOpenChange,\n } = options;\n\n const [handle, setHandle] = useState<FloatHandle | null>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const handleRef = useRef<FloatHandle | null>(null);\n const embedConfig = useEmbedConfig(researchId, host);\n\n const isControlled = controlledOpen !== undefined;\n\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnError = useStableCallback(onError);\n\n const handleClose = useCallback(() => {\n setInternalOpen(false);\n if (isControlled) {\n onOpenChange?.(false);\n }\n onClose?.();\n }, [isControlled, onOpenChange, onClose]);\n\n const stableOnClose = useStableCallback(handleClose);\n\n // Resolve ReactNode icons to SVG strings for the core SDK\n const resolvedLauncher = useMemo((): EmbedConfig[\"launcher\"] | undefined => {\n if (!launcher) return undefined;\n const { icon, ...rest } = launcher;\n // Filter out falsy ReactNode values (e.g., `condition && <Icon />` producing `false`)\n if (\n icon === false ||\n icon === null ||\n icon === undefined ||\n icon === 0 ||\n icon === \"\"\n ) {\n return Object.keys(rest).length > 0 ? rest : undefined;\n }\n if (isValidElement(icon)) {\n return { ...rest, icon: { svg: renderToStaticMarkup(icon) } };\n }\n // Only pass through valid LauncherIcon values to core SDK\n if (icon === \"default\" || icon === \"avatar\") {\n return { ...rest, icon: icon as \"default\" | \"avatar\" };\n }\n if (typeof icon === \"object\" && (\"url\" in icon || \"svg\" in icon)) {\n return { ...rest, icon: icon as { url: string } | { svg: string } };\n }\n // Unrecognized icon value (truthy primitives, arrays, etc.) — ignore it\n return Object.keys(rest).length > 0 ? rest : undefined;\n }, [launcher]);\n\n useEffect(() => {\n const newHandle = createFloatBubble({\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n launcher: resolvedLauncher,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = newHandle;\n setHandle(newHandle);\n\n return () => {\n if (handleRef.current === newHandle) {\n newHandle.unmount();\n handleRef.current = null;\n setHandle(null);\n }\n };\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n resolvedLauncher,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n // Update float with API config when it arrives (appearance, launcher, channels, welcome)\n useEffect(() => {\n if (!embedConfig || !handleRef.current) return;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (handleRef.current.update as any)({\n channel: embedConfig.channel ?? embedConfig.allowedChannels ?? undefined,\n welcomeMessage: embedConfig.welcomeMessage,\n _apiConfig: embedConfig,\n });\n }, [embedConfig]);\n\n useEffect(() => {\n if (!isControlled || !handle) return;\n\n if (controlledOpen && !handle.isOpen) {\n handle.open();\n } else if (!controlledOpen && handle.isOpen) {\n handle.close();\n }\n }, [controlledOpen, isControlled, handle]);\n\n const openFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(true);\n } else {\n handleRef.current?.open();\n setInternalOpen(true);\n }\n }, [isControlled, onOpenChange]);\n\n const closeFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(false);\n } else {\n handleRef.current?.close();\n setInternalOpen(false);\n }\n }, [isControlled, onOpenChange]);\n\n const toggleFn = useCallback(() => {\n const currentlyOpen = handleRef.current?.isOpen ?? internalOpen;\n if (currentlyOpen) {\n closeFn();\n } else {\n openFn();\n }\n }, [internalOpen, openFn, closeFn]);\n\n const unmountFn = useCallback(() => {\n handleRef.current?.unmount();\n handleRef.current = null;\n setHandle(null);\n setInternalOpen(false);\n }, []);\n\n const isOpen = isControlled\n ? controlledOpen\n : (handle?.isOpen ?? internalOpen);\n\n return {\n open: openFn,\n close: closeFn,\n toggle: toggleFn,\n unmount: unmountFn,\n isOpen,\n handle,\n };\n}\n","import { useEffect, useRef, useState, useCallback } from \"react\";\nimport {\n openPopup,\n setupTrigger,\n shouldShow,\n markShown,\n} from \"@perspective-ai/sdk\";\nimport type { EmbedConfig, TriggerConfig, ShowOnce } from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./useStableCallback\";\nimport { useEmbedConfig } from \"./useEmbedConfig\";\n\nexport interface UseAutoOpenOptions extends Omit<\n EmbedConfig,\n \"type\" | \"autoOpen\"\n> {\n trigger: TriggerConfig;\n showOnce?: ShowOnce; // default: \"session\"\n}\n\nexport interface UseAutoOpenReturn {\n /** Cancel the pending trigger */\n cancel: () => void;\n /** Whether the trigger has fired */\n triggered: boolean;\n}\n\nexport function useAutoOpen(options: UseAutoOpenOptions): UseAutoOpenReturn {\n const { trigger, showOnce = \"session\", researchId, ...embedConfig } = options;\n const cleanupRef = useRef<(() => void) | null>(null);\n const [triggered, setTriggered] = useState(false);\n const triggerDelay = trigger.type === \"timeout\" ? trigger.delay : undefined;\n const apiConfig = useEmbedConfig(researchId, embedConfig.host);\n const apiConfigRef = useRef(apiConfig);\n apiConfigRef.current = apiConfig;\n\n // useStableCallback so the trigger always calls with latest config\n const stableOnTrigger = useStableCallback(() => {\n markShown(researchId, showOnce);\n openPopup({\n researchId,\n ...embedConfig,\n _apiConfig: apiConfigRef.current,\n });\n });\n\n useEffect(() => {\n if (!shouldShow(researchId, showOnce)) return;\n\n cleanupRef.current = setupTrigger(trigger, () => {\n setTriggered((prev) => {\n if (prev) return prev; // already fired\n stableOnTrigger();\n return true;\n });\n });\n\n return () => {\n cleanupRef.current?.();\n cleanupRef.current = null;\n };\n // Primitive deps only — avoids re-triggering on object identity changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [researchId, trigger.type, triggerDelay, showOnce]);\n\n const cancel = useCallback(() => {\n cleanupRef.current?.();\n cleanupRef.current = null;\n }, []);\n\n return { cancel, triggered };\n}\n","import { useState, useEffect } from \"react\";\n\ntype Theme = \"light\" | \"dark\";\ntype ThemeInput = \"light\" | \"dark\" | \"system\";\n\n/**\n * Hook to resolve theme based on override and system preference.\n * Listens for system preference changes when theme is \"system\".\n */\nexport function useThemeSync(theme: ThemeInput = \"system\"): Theme {\n // Always start with a deterministic value for SSR hydration safety.\n // The actual system preference is synced in useEffect.\n const [resolved, setResolved] = useState<Theme>(\n theme !== \"system\" ? theme : \"light\"\n );\n\n useEffect(() => {\n if (theme !== \"system\") {\n setResolved(theme);\n return;\n }\n\n const mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n\n // Set initial value\n setResolved(mq.matches ? \"dark\" : \"light\");\n\n const handler = (e: MediaQueryListEvent) =>\n setResolved(e.matches ? \"dark\" : \"light\");\n\n mq.addEventListener(\"change\", handler);\n return () => mq.removeEventListener(\"change\", handler);\n }, [theme]);\n\n return resolved;\n}\n","import { SDK_VERSION } from \"@perspective-ai/sdk/constants\";\n\nconst PERSPECTIVE_URL = \"https://getperspective.ai\";\n\nexport interface DiscoveryMetadataProps {\n /** Override the SDK version in the structured data */\n version?: string;\n}\n\n/**\n * Server-side React component that renders JSON-LD structured data\n * for AEO (Answer Engine Optimization).\n *\n * Place this in your layout or page to ensure AI crawlers that don't\n * execute JavaScript can still identify Perspective AI on your site.\n *\n * The client SDK's `injectJsonLd()` checks for the\n * `[data-perspective-jsonld]` attribute to avoid duplicates.\n *\n * @example\n * // In a Next.js layout or page (server component)\n * import { DiscoveryMetadata } from '@perspective-ai/sdk-react';\n *\n * export default function Layout({ children }) {\n * return (\n * <html>\n * <head>\n * <DiscoveryMetadata />\n * </head>\n * <body>{children}</body>\n * </html>\n * );\n * }\n */\nexport function DiscoveryMetadata({ version }: DiscoveryMetadataProps) {\n const jsonLd = {\n \"@context\": \"https://schema.org\",\n \"@graph\": [\n {\n \"@type\": \"SoftwareApplication\",\n \"@id\": `${PERSPECTIVE_URL}/#widget`,\n name: \"Perspective AI\",\n description:\n \"Rigid forms cause drop-off, weaken qualification, and strip away context. Perspective uses adaptive AI to turn forms into conversations that capture structured data and trigger automation.\",\n url: PERSPECTIVE_URL,\n applicationCategory: \"BusinessApplication\",\n softwareVersion: version ?? SDK_VERSION,\n provider: { \"@id\": `${PERSPECTIVE_URL}/#organization` },\n aggregateRating: {\n \"@type\": \"AggregateRating\",\n ratingValue: \"5\",\n bestRating: \"5\",\n worstRating: \"1\",\n ratingCount: 7,\n reviewCount: 7,\n },\n },\n {\n \"@type\": \"Organization\",\n \"@id\": `${PERSPECTIVE_URL}/#organization`,\n name: \"Perspective AI\",\n url: PERSPECTIVE_URL,\n },\n ],\n };\n\n return (\n <script\n type=\"application/ld+json\"\n data-perspective-jsonld=\"\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}\n />\n );\n}\n","import {\n useRef,\n useEffect,\n Fragment,\n type HTMLAttributes,\n type RefObject,\n} from \"react\";\nimport { DiscoveryMetadata } from \"./DiscoveryMetadata\";\nimport {\n createWidget,\n perfLog,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./hooks/useStableCallback\";\n\nexport interface WidgetProps\n extends\n Omit<EmbedConfig, \"type\">,\n Omit<HTMLAttributes<HTMLDivElement>, \"onError\" | \"onSubmit\"> {\n /** Ref to access the embed handle for programmatic control */\n embedRef?: RefObject<EmbedHandle | null>;\n}\n\n/**\n * Inline widget embed component.\n * Renders the interview directly in a container.\n */\nexport function Widget({\n researchId,\n params,\n brand,\n theme,\n host,\n frame,\n disableJsonLdAttribution,\n onReady,\n onVisualReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n embedRef,\n className,\n style,\n ...divProps\n}: WidgetProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const handleRef = useRef<EmbedHandle | null>(null);\n\n // Stable callbacks to avoid re-mounting on callback changes\n const stableOnReady = useStableCallback(onReady);\n const stableOnVisualReady = useStableCallback(onVisualReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnClose = useStableCallback(onClose);\n const stableOnError = useStableCallback(onError);\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n perfLog(\"SDK-React\", \"Widget effect mounted\", { researchId });\n\n // No upfront config fetch — the iframe resolves workspace-level\n // appearance overrides server-side. createWidget renders its own\n // skeleton while the iframe loads.\n const handle = createWidget(container, {\n researchId,\n params,\n brand,\n theme,\n host,\n frame,\n disableJsonLdAttribution,\n onReady: stableOnReady,\n onVisualReady: stableOnVisualReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = handle;\n\n if (embedRef) {\n embedRef.current = handle;\n }\n\n return () => {\n if (handleRef.current) {\n handleRef.current.unmount();\n handleRef.current = null;\n }\n if (embedRef) {\n embedRef.current = null;\n }\n };\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n frame,\n disableJsonLdAttribution,\n stableOnReady,\n stableOnVisualReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n embedRef,\n ]);\n\n return (\n <Fragment>\n {!disableJsonLdAttribution && <DiscoveryMetadata />}\n <div\n ref={containerRef}\n className={className}\n style={style}\n data-testid=\"perspective-widget\"\n {...divProps}\n />\n </Fragment>\n );\n}\n","import { useRef, useEffect, type RefObject } from \"react\";\nimport { DiscoveryMetadata } from \"./DiscoveryMetadata\";\nimport {\n createFullpage,\n createLoadingIndicator,\n fetchEmbedConfig,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./hooks/useStableCallback\";\n\nexport interface FullpageProps extends Omit<EmbedConfig, \"type\"> {\n /** Ref to access the embed handle for programmatic control */\n embedRef?: RefObject<EmbedHandle | null>;\n}\n\n/**\n * Full viewport embed component.\n * Takes over the entire screen with the interview.\n */\nexport function Fullpage({\n researchId,\n params,\n brand,\n theme,\n host,\n disableJsonLdAttribution,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n embedRef,\n}: FullpageProps) {\n const handleRef = useRef<EmbedHandle | null>(null);\n\n // Stable callbacks\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnClose = useStableCallback(onClose);\n const stableOnError = useStableCallback(onError);\n\n useEffect(() => {\n // Show skeleton instantly while config fetches in parallel\n const skeleton = createLoadingIndicator({ theme, brand });\n skeleton.style.position = \"fixed\";\n skeleton.style.inset = \"0\";\n skeleton.style.zIndex = \"2147483647\";\n document.body.appendChild(skeleton);\n\n let cancelled = false;\n\n fetchEmbedConfig(researchId, host).then((config) => {\n if (cancelled) return;\n skeleton.remove();\n\n const handle = createFullpage({\n researchId,\n params,\n brand,\n theme,\n host,\n disableJsonLdAttribution,\n _apiConfig: config,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = handle;\n\n if (embedRef) {\n embedRef.current = handle;\n }\n });\n\n return () => {\n cancelled = true;\n skeleton.remove();\n if (handleRef.current) {\n handleRef.current.unmount();\n handleRef.current = null;\n }\n if (embedRef) {\n embedRef.current = null;\n }\n };\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n disableJsonLdAttribution,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n embedRef,\n ]);\n\n // The fullpage overlay is added to document.body via SDK; render attribution for SSR\n return disableJsonLdAttribution ? null : <DiscoveryMetadata />;\n}\n","import { useEffect, type RefObject } from \"react\";\nimport { type EmbedConfig, type FloatHandle } from \"@perspective-ai/sdk\";\nimport { DiscoveryMetadata } from \"./DiscoveryMetadata\";\nimport {\n useFloatBubble,\n type LauncherConfigReact,\n} from \"./hooks/useFloatBubble\";\n\nexport interface FloatBubbleProps extends Omit<\n EmbedConfig,\n \"type\" | \"launcher\"\n> {\n /** Ref to access the handle for programmatic control */\n embedRef?: RefObject<FloatHandle | null>;\n /** Customize the floating launcher button appearance */\n launcher?: LauncherConfigReact;\n}\n\n/**\n * Floating bubble widget that expands into a chat window.\n * This is a convenience wrapper around useFloatBubble hook.\n *\n * @example\n * ```tsx\n * <FloatBubble researchId=\"abc\" onSubmit={handleSubmit} />\n * ```\n */\nexport function FloatBubble({\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n disableJsonLdAttribution,\n launcher,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n embedRef,\n}: FloatBubbleProps) {\n const { handle } = useFloatBubble({\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n disableJsonLdAttribution,\n launcher,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n });\n\n useEffect(() => {\n if (embedRef) {\n embedRef.current = handle;\n }\n return () => {\n if (embedRef) {\n embedRef.current = null;\n }\n };\n }, [embedRef, handle]);\n\n return disableJsonLdAttribution ? null : <DiscoveryMetadata />;\n}\n"]}
1
+ {"version":3,"sources":["../src/hooks/useStableCallback.ts","../src/hooks/useEmbedConfig.ts","../src/hooks/usePopup.ts","../src/hooks/useSlider.ts","../src/hooks/useFloatBubble.ts","../src/hooks/useAutoOpen.ts","../src/hooks/useThemeSync.ts","../src/DiscoveryMetadata.tsx","../src/Widget.tsx","../src/Fullpage.tsx","../src/FloatBubble.tsx"],"names":["useLayoutEffect","useEffect","useRef","useCallback","useState","fetchEmbedConfig","openPopup","getPersistedOpenState","openSlider","useMemo","isValidElement","renderToStaticMarkup","createFloatBubble","markShown","shouldShow","setupTrigger","SDK_VERSION","jsx","perfLog","createWidget","Fragment","createLoadingIndicator","createFullpage"],"mappings":"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","file":"index.cjs","sourcesContent":["import { useRef, useCallback, useLayoutEffect, useEffect } from \"react\";\n\nconst useIsomorphicLayoutEffect =\n typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\nexport function useStableCallback<\n T extends ((...args: any[]) => any) | undefined,\n>(callback: T): T {\n const callbackRef = useRef(callback);\n\n useIsomorphicLayoutEffect(() => {\n callbackRef.current = callback;\n });\n\n // Always create the stable wrapper (hooks can't be conditional),\n // but return undefined when no callback is provided to preserve\n // truthiness semantics for consumers that branch on it.\n const stable = useCallback(\n ((...args: any[]) => callbackRef.current?.(...args)) as NonNullable<T>,\n []\n );\n\n return callback ? stable : callback;\n}\n","import { useState, useEffect } from \"react\";\nimport { fetchEmbedConfig, type ThemeConfig } from \"@perspective-ai/sdk\";\n\n/**\n * Fetch embed config (theme, appearance, launcher) from the API.\n * Returns undefined while loading, then the resolved config.\n * Results are cached and deduplicated across hooks sharing a researchId.\n */\nexport function useEmbedConfig(\n researchId: string,\n host?: string\n): ThemeConfig | undefined {\n const [state, setState] = useState<\n { researchId: string; host?: string; config: ThemeConfig } | undefined\n >();\n\n useEffect(() => {\n let cancelled = false;\n fetchEmbedConfig(researchId, host).then((result) => {\n if (!cancelled) setState({ researchId, host, config: result });\n });\n return () => {\n cancelled = true;\n };\n }, [researchId, host]);\n\n // Return undefined if config is for different researchId/host (stale)\n return state?.researchId === researchId && state.host === host\n ? state.config\n : undefined;\n}\n","import { useCallback, useState, useEffect, useRef } from \"react\";\nimport {\n getPersistedOpenState,\n openPopup,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./useStableCallback\";\nimport { useEmbedConfig } from \"./useEmbedConfig\";\n\n/** Options for usePopup hook */\nexport interface UsePopupOptions extends Omit<EmbedConfig, \"type\"> {\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n}\n\n/** Return type for usePopup hook */\nexport interface UsePopupReturn {\n /** Open the popup */\n open: () => void;\n /** Close the popup */\n close: () => void;\n /** Toggle the popup */\n toggle: () => void;\n /** Whether the popup is currently open */\n isOpen: boolean;\n /** The underlying SDK handle (null when closed) */\n handle: EmbedHandle | null;\n}\n\n/**\n * Headless hook for programmatic popup control.\n * Use this when you need custom trigger elements or programmatic control.\n *\n * @example\n * ```tsx\n * // Basic usage with custom trigger\n * const { open, isOpen } = usePopup({ researchId: \"abc\" });\n * <MyCustomButton onClick={open}>Open Survey</MyCustomButton>\n *\n * // Controlled mode\n * const [isOpen, setIsOpen] = useState(false);\n * const popup = usePopup({\n * researchId: \"abc\",\n * open: isOpen,\n * onOpenChange: setIsOpen\n * });\n * ```\n */\nexport function usePopup(options: UsePopupOptions): UsePopupReturn {\n const {\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n open: controlledOpen,\n onOpenChange,\n } = options;\n\n const [handle, setHandle] = useState<EmbedHandle | null>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const handleRef = useRef<EmbedHandle | null>(null);\n const embedConfig = useEmbedConfig(researchId, host);\n const embedConfigRef = useRef(embedConfig);\n embedConfigRef.current = embedConfig;\n\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnError = useStableCallback(onError);\n\n const setOpen = useCallback(\n (value: boolean) => {\n if (isControlled) {\n onOpenChange?.(value);\n } else {\n setInternalOpen(value);\n }\n },\n [isControlled, onOpenChange]\n );\n\n const handleClose = useCallback(() => {\n handleRef.current = null;\n setHandle(null);\n setOpen(false);\n onClose?.();\n }, [setOpen, onClose]);\n\n const stableOnClose = useStableCallback(handleClose);\n\n const createPopup = useCallback(() => {\n if (handleRef.current) return handleRef.current;\n\n const newHandle = openPopup({\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n _apiConfig: embedConfigRef.current,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = newHandle;\n setHandle(newHandle);\n return newHandle;\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n const destroyPopup = useCallback((mode: \"destroy\" | \"unmount\") => {\n if (handleRef.current) {\n if (mode === \"destroy\") {\n handleRef.current.destroy();\n } else {\n handleRef.current.unmount();\n }\n handleRef.current = null;\n setHandle(null);\n }\n }, []);\n\n const openFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(true);\n } else {\n createPopup();\n setInternalOpen(true);\n }\n }, [isControlled, onOpenChange, createPopup]);\n\n const closeFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(false);\n } else {\n destroyPopup(\"destroy\");\n setInternalOpen(false);\n }\n }, [isControlled, onOpenChange, destroyPopup]);\n\n const toggleFn = useCallback(() => {\n if (isOpen) {\n closeFn();\n } else {\n openFn();\n }\n }, [isOpen, openFn, closeFn]);\n\n useEffect(() => {\n if (!isControlled) return;\n\n if (controlledOpen && !handleRef.current) {\n createPopup();\n } else if (!controlledOpen && handleRef.current) {\n destroyPopup(\"destroy\");\n }\n }, [controlledOpen, isControlled, createPopup, destroyPopup]);\n\n useEffect(() => {\n if (isControlled || handleRef.current) return;\n\n if (getPersistedOpenState({ researchId, type: \"popup\", host }) !== true) {\n return;\n }\n\n createPopup();\n setInternalOpen(true);\n }, [createPopup, host, isControlled, researchId]);\n\n useEffect(() => {\n return () => {\n if (handleRef.current) {\n handleRef.current.unmount();\n handleRef.current = null;\n }\n };\n }, []);\n\n return {\n open: openFn,\n close: closeFn,\n toggle: toggleFn,\n isOpen,\n handle,\n };\n}\n","import { useCallback, useState, useEffect, useRef } from \"react\";\nimport {\n getPersistedOpenState,\n openSlider,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./useStableCallback\";\nimport { useEmbedConfig } from \"./useEmbedConfig\";\n\n/** Options for useSlider hook */\nexport interface UseSliderOptions extends Omit<EmbedConfig, \"type\"> {\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n}\n\n/** Return type for useSlider hook */\nexport interface UseSliderReturn {\n /** Open the slider */\n open: () => void;\n /** Close the slider */\n close: () => void;\n /** Toggle the slider */\n toggle: () => void;\n /** Whether the slider is currently open */\n isOpen: boolean;\n /** The underlying SDK handle (null when closed) */\n handle: EmbedHandle | null;\n}\n\n/**\n * Headless hook for programmatic slider control.\n * Use this when you need custom trigger elements or programmatic control.\n *\n * @example\n * ```tsx\n * const { open, isOpen } = useSlider({ researchId: \"abc\" });\n * <MyCustomButton onClick={open}>Give Feedback</MyCustomButton>\n * ```\n */\nexport function useSlider(options: UseSliderOptions): UseSliderReturn {\n const {\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n sliderMode,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n open: controlledOpen,\n onOpenChange,\n } = options;\n\n const [handle, setHandle] = useState<EmbedHandle | null>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const handleRef = useRef<EmbedHandle | null>(null);\n const embedConfig = useEmbedConfig(researchId, host);\n const embedConfigRef = useRef(embedConfig);\n embedConfigRef.current = embedConfig;\n\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnError = useStableCallback(onError);\n\n const setOpen = useCallback(\n (value: boolean) => {\n if (isControlled) {\n onOpenChange?.(value);\n } else {\n setInternalOpen(value);\n }\n },\n [isControlled, onOpenChange]\n );\n\n const handleClose = useCallback(() => {\n handleRef.current = null;\n setHandle(null);\n setOpen(false);\n onClose?.();\n }, [setOpen, onClose]);\n\n const stableOnClose = useStableCallback(handleClose);\n\n const createSlider = useCallback(() => {\n if (handleRef.current) return handleRef.current;\n\n const newHandle = openSlider({\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n sliderMode,\n _apiConfig: embedConfigRef.current,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = newHandle;\n setHandle(newHandle);\n return newHandle;\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n sliderMode,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n const destroySlider = useCallback((mode: \"destroy\" | \"unmount\") => {\n if (handleRef.current) {\n if (mode === \"destroy\") {\n handleRef.current.destroy();\n } else {\n handleRef.current.unmount();\n }\n handleRef.current = null;\n setHandle(null);\n }\n }, []);\n\n const openFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(true);\n } else {\n createSlider();\n setInternalOpen(true);\n }\n }, [isControlled, onOpenChange, createSlider]);\n\n const closeFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(false);\n } else {\n destroySlider(\"destroy\");\n setInternalOpen(false);\n }\n }, [isControlled, onOpenChange, destroySlider]);\n\n const toggleFn = useCallback(() => {\n if (isOpen) {\n closeFn();\n } else {\n openFn();\n }\n }, [isOpen, openFn, closeFn]);\n\n useEffect(() => {\n if (!isControlled) return;\n\n if (controlledOpen && !handleRef.current) {\n createSlider();\n } else if (!controlledOpen && handleRef.current) {\n destroySlider(\"destroy\");\n }\n }, [controlledOpen, isControlled, createSlider, destroySlider]);\n\n useEffect(() => {\n if (isControlled || handleRef.current) return;\n\n if (getPersistedOpenState({ researchId, type: \"slider\", host }) !== true) {\n return;\n }\n\n createSlider();\n setInternalOpen(true);\n }, [createSlider, host, isControlled, researchId]);\n\n useEffect(() => {\n return () => {\n if (handleRef.current) {\n handleRef.current.unmount();\n handleRef.current = null;\n }\n };\n }, []);\n\n return {\n open: openFn,\n close: closeFn,\n toggle: toggleFn,\n isOpen,\n handle,\n };\n}\n","import {\n useCallback,\n useState,\n useEffect,\n useRef,\n useMemo,\n isValidElement,\n} from \"react\";\nimport type { ReactNode } from \"react\";\nimport {\n createFloatBubble,\n type EmbedConfig,\n type FloatHandle,\n type LauncherConfig,\n} from \"@perspective-ai/sdk\";\nimport { renderToStaticMarkup } from \"react-dom/server\";\nimport { useStableCallback } from \"./useStableCallback\";\nimport { useEmbedConfig } from \"./useEmbedConfig\";\n\n/** Launcher config with React support — icon accepts ReactNode in addition to SDK types */\nexport interface LauncherConfigReact extends Omit<LauncherConfig, \"icon\"> {\n icon?: LauncherConfig[\"icon\"] | ReactNode;\n}\n\n/** Options for useFloatBubble hook */\nexport interface UseFloatBubbleOptions extends Omit<\n EmbedConfig,\n \"type\" | \"launcher\"\n> {\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Customize the floating launcher button appearance */\n launcher?: LauncherConfigReact;\n}\n\n/** Return type for useFloatBubble hook */\nexport interface UseFloatBubbleReturn {\n /** Open the float bubble window */\n open: () => void;\n /** Close the float bubble window */\n close: () => void;\n /** Toggle the float bubble window */\n toggle: () => void;\n /** Unmount the float bubble entirely */\n unmount: () => void;\n /** Whether the float bubble window is currently open */\n isOpen: boolean;\n /** The underlying SDK handle (null until mounted) */\n handle: FloatHandle | null;\n}\n\n/**\n * Headless hook for float bubble lifecycle management.\n * Creates a floating bubble button that expands into a chat window.\n * The bubble mounts on component mount and unmounts on component unmount.\n *\n * @example\n * ```tsx\n * // Basic usage - bubble mounts on component mount\n * useFloatBubble({ researchId: \"abc\" });\n *\n * // With programmatic control\n * const { open, close, isOpen } = useFloatBubble({ researchId: \"abc\" });\n * <button onClick={open}>Open Chat</button>\n * ```\n */\nexport function useFloatBubble(\n options: UseFloatBubbleOptions\n): UseFloatBubbleReturn {\n const {\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n teaser,\n launcher,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n open: controlledOpen,\n onOpenChange,\n } = options;\n\n const [handle, setHandle] = useState<FloatHandle | null>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const handleRef = useRef<FloatHandle | null>(null);\n const embedConfig = useEmbedConfig(researchId, host);\n\n const isControlled = controlledOpen !== undefined;\n\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnError = useStableCallback(onError);\n\n const handleClose = useCallback(() => {\n setInternalOpen(false);\n if (isControlled) {\n onOpenChange?.(false);\n }\n onClose?.();\n }, [isControlled, onOpenChange, onClose]);\n\n const stableOnClose = useStableCallback(handleClose);\n\n // Stabilize the teaser object on its primitive fields so an inline object\n // literal prop doesn't remount the whole bubble on every parent render\n const teaserEnabled = teaser?.enabled;\n const teaserDelay = teaser?.delay;\n const teaserSound = teaser?.sound;\n const hasTeaser = teaser !== undefined;\n const stableTeaser = useMemo(\n (): EmbedConfig[\"teaser\"] =>\n hasTeaser\n ? { enabled: teaserEnabled, delay: teaserDelay, sound: teaserSound }\n : undefined,\n [hasTeaser, teaserEnabled, teaserDelay, teaserSound]\n );\n\n // Resolve ReactNode icons to SVG strings for the core SDK\n const resolvedLauncher = useMemo((): EmbedConfig[\"launcher\"] | undefined => {\n if (!launcher) return undefined;\n const { icon, ...rest } = launcher;\n // Filter out falsy ReactNode values (e.g., `condition && <Icon />` producing `false`)\n if (\n icon === false ||\n icon === null ||\n icon === undefined ||\n icon === 0 ||\n icon === \"\"\n ) {\n return Object.keys(rest).length > 0 ? rest : undefined;\n }\n if (isValidElement(icon)) {\n return { ...rest, icon: { svg: renderToStaticMarkup(icon) } };\n }\n // Only pass through valid LauncherIcon values to core SDK\n if (icon === \"default\" || icon === \"avatar\") {\n return { ...rest, icon: icon as \"default\" | \"avatar\" };\n }\n if (typeof icon === \"object\" && (\"url\" in icon || \"svg\" in icon)) {\n return { ...rest, icon: icon as { url: string } | { svg: string } };\n }\n // Unrecognized icon value (truthy primitives, arrays, etc.) — ignore it\n return Object.keys(rest).length > 0 ? rest : undefined;\n }, [launcher]);\n\n useEffect(() => {\n const newHandle = createFloatBubble({\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n teaser: stableTeaser,\n launcher: resolvedLauncher,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = newHandle;\n setHandle(newHandle);\n\n return () => {\n if (handleRef.current === newHandle) {\n newHandle.unmount();\n handleRef.current = null;\n setHandle(null);\n }\n };\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n stableTeaser,\n resolvedLauncher,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n // Update float with API config when it arrives (appearance, launcher, channels, welcome)\n useEffect(() => {\n if (!embedConfig || !handleRef.current) return;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (handleRef.current.update as any)({\n channel: embedConfig.channel ?? embedConfig.allowedChannels ?? undefined,\n welcomeMessage: embedConfig.welcomeMessage,\n _apiConfig: embedConfig,\n });\n }, [embedConfig]);\n\n useEffect(() => {\n if (!isControlled || !handle) return;\n\n if (controlledOpen && !handle.isOpen) {\n handle.open();\n } else if (!controlledOpen && handle.isOpen) {\n handle.close();\n }\n }, [controlledOpen, isControlled, handle]);\n\n const openFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(true);\n } else {\n handleRef.current?.open();\n setInternalOpen(true);\n }\n }, [isControlled, onOpenChange]);\n\n const closeFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(false);\n } else {\n handleRef.current?.close();\n setInternalOpen(false);\n }\n }, [isControlled, onOpenChange]);\n\n const toggleFn = useCallback(() => {\n const currentlyOpen = handleRef.current?.isOpen ?? internalOpen;\n if (currentlyOpen) {\n closeFn();\n } else {\n openFn();\n }\n }, [internalOpen, openFn, closeFn]);\n\n const unmountFn = useCallback(() => {\n handleRef.current?.unmount();\n handleRef.current = null;\n setHandle(null);\n setInternalOpen(false);\n }, []);\n\n const isOpen = isControlled\n ? controlledOpen\n : (handle?.isOpen ?? internalOpen);\n\n return {\n open: openFn,\n close: closeFn,\n toggle: toggleFn,\n unmount: unmountFn,\n isOpen,\n handle,\n };\n}\n","import { useEffect, useRef, useState, useCallback } from \"react\";\nimport {\n openPopup,\n setupTrigger,\n shouldShow,\n markShown,\n} from \"@perspective-ai/sdk\";\nimport type { EmbedConfig, TriggerConfig, ShowOnce } from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./useStableCallback\";\nimport { useEmbedConfig } from \"./useEmbedConfig\";\n\nexport interface UseAutoOpenOptions extends Omit<\n EmbedConfig,\n \"type\" | \"autoOpen\"\n> {\n trigger: TriggerConfig;\n showOnce?: ShowOnce; // default: \"session\"\n}\n\nexport interface UseAutoOpenReturn {\n /** Cancel the pending trigger */\n cancel: () => void;\n /** Whether the trigger has fired */\n triggered: boolean;\n}\n\nexport function useAutoOpen(options: UseAutoOpenOptions): UseAutoOpenReturn {\n const { trigger, showOnce = \"session\", researchId, ...embedConfig } = options;\n const cleanupRef = useRef<(() => void) | null>(null);\n const [triggered, setTriggered] = useState(false);\n const triggerDelay = trigger.type === \"timeout\" ? trigger.delay : undefined;\n const apiConfig = useEmbedConfig(researchId, embedConfig.host);\n const apiConfigRef = useRef(apiConfig);\n apiConfigRef.current = apiConfig;\n\n // useStableCallback so the trigger always calls with latest config\n const stableOnTrigger = useStableCallback(() => {\n markShown(researchId, showOnce);\n openPopup({\n researchId,\n ...embedConfig,\n _apiConfig: apiConfigRef.current,\n });\n });\n\n useEffect(() => {\n if (!shouldShow(researchId, showOnce)) return;\n\n cleanupRef.current = setupTrigger(trigger, () => {\n setTriggered((prev) => {\n if (prev) return prev; // already fired\n stableOnTrigger();\n return true;\n });\n });\n\n return () => {\n cleanupRef.current?.();\n cleanupRef.current = null;\n };\n // Primitive deps only — avoids re-triggering on object identity changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [researchId, trigger.type, triggerDelay, showOnce]);\n\n const cancel = useCallback(() => {\n cleanupRef.current?.();\n cleanupRef.current = null;\n }, []);\n\n return { cancel, triggered };\n}\n","import { useState, useEffect } from \"react\";\n\ntype Theme = \"light\" | \"dark\";\ntype ThemeInput = \"light\" | \"dark\" | \"system\";\n\n/**\n * Hook to resolve theme based on override and system preference.\n * Listens for system preference changes when theme is \"system\".\n */\nexport function useThemeSync(theme: ThemeInput = \"system\"): Theme {\n // Always start with a deterministic value for SSR hydration safety.\n // The actual system preference is synced in useEffect.\n const [resolved, setResolved] = useState<Theme>(\n theme !== \"system\" ? theme : \"light\"\n );\n\n useEffect(() => {\n if (theme !== \"system\") {\n setResolved(theme);\n return;\n }\n\n const mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n\n // Set initial value\n setResolved(mq.matches ? \"dark\" : \"light\");\n\n const handler = (e: MediaQueryListEvent) =>\n setResolved(e.matches ? \"dark\" : \"light\");\n\n mq.addEventListener(\"change\", handler);\n return () => mq.removeEventListener(\"change\", handler);\n }, [theme]);\n\n return resolved;\n}\n","import { SDK_VERSION } from \"@perspective-ai/sdk/constants\";\n\nconst PERSPECTIVE_URL = \"https://getperspective.ai\";\n\nexport interface DiscoveryMetadataProps {\n /** Override the SDK version in the structured data */\n version?: string;\n}\n\n/**\n * Server-side React component that renders JSON-LD structured data\n * for AEO (Answer Engine Optimization).\n *\n * Place this in your layout or page to ensure AI crawlers that don't\n * execute JavaScript can still identify Perspective AI on your site.\n *\n * The client SDK's `injectJsonLd()` checks for the\n * `[data-perspective-jsonld]` attribute to avoid duplicates.\n *\n * @example\n * // In a Next.js layout or page (server component)\n * import { DiscoveryMetadata } from '@perspective-ai/sdk-react';\n *\n * export default function Layout({ children }) {\n * return (\n * <html>\n * <head>\n * <DiscoveryMetadata />\n * </head>\n * <body>{children}</body>\n * </html>\n * );\n * }\n */\nexport function DiscoveryMetadata({ version }: DiscoveryMetadataProps) {\n const jsonLd = {\n \"@context\": \"https://schema.org\",\n \"@graph\": [\n {\n \"@type\": \"SoftwareApplication\",\n \"@id\": `${PERSPECTIVE_URL}/#widget`,\n name: \"Perspective AI\",\n description:\n \"Rigid forms cause drop-off, weaken qualification, and strip away context. Perspective uses adaptive AI to turn forms into conversations that capture structured data and trigger automation.\",\n url: PERSPECTIVE_URL,\n applicationCategory: \"BusinessApplication\",\n softwareVersion: version ?? SDK_VERSION,\n provider: { \"@id\": `${PERSPECTIVE_URL}/#organization` },\n aggregateRating: {\n \"@type\": \"AggregateRating\",\n ratingValue: \"5\",\n bestRating: \"5\",\n worstRating: \"1\",\n ratingCount: 7,\n reviewCount: 7,\n },\n },\n {\n \"@type\": \"Organization\",\n \"@id\": `${PERSPECTIVE_URL}/#organization`,\n name: \"Perspective AI\",\n url: PERSPECTIVE_URL,\n },\n ],\n };\n\n return (\n <script\n type=\"application/ld+json\"\n data-perspective-jsonld=\"\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}\n />\n );\n}\n","import {\n useRef,\n useEffect,\n Fragment,\n type HTMLAttributes,\n type RefObject,\n} from \"react\";\nimport { DiscoveryMetadata } from \"./DiscoveryMetadata\";\nimport {\n createWidget,\n perfLog,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./hooks/useStableCallback\";\n\nexport interface WidgetProps\n extends\n Omit<EmbedConfig, \"type\">,\n Omit<HTMLAttributes<HTMLDivElement>, \"onError\" | \"onSubmit\"> {\n /** Ref to access the embed handle for programmatic control */\n embedRef?: RefObject<EmbedHandle | null>;\n}\n\n/**\n * Inline widget embed component.\n * Renders the interview directly in a container.\n */\nexport function Widget({\n researchId,\n params,\n brand,\n theme,\n host,\n frame,\n disableJsonLdAttribution,\n onReady,\n onVisualReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n embedRef,\n className,\n style,\n ...divProps\n}: WidgetProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const handleRef = useRef<EmbedHandle | null>(null);\n\n // Stable callbacks to avoid re-mounting on callback changes\n const stableOnReady = useStableCallback(onReady);\n const stableOnVisualReady = useStableCallback(onVisualReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnClose = useStableCallback(onClose);\n const stableOnError = useStableCallback(onError);\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n perfLog(\"SDK-React\", \"Widget effect mounted\", { researchId });\n\n // No upfront config fetch — the iframe resolves workspace-level\n // appearance overrides server-side. createWidget renders its own\n // skeleton while the iframe loads.\n const handle = createWidget(container, {\n researchId,\n params,\n brand,\n theme,\n host,\n frame,\n disableJsonLdAttribution,\n onReady: stableOnReady,\n onVisualReady: stableOnVisualReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = handle;\n\n if (embedRef) {\n embedRef.current = handle;\n }\n\n return () => {\n if (handleRef.current) {\n handleRef.current.unmount();\n handleRef.current = null;\n }\n if (embedRef) {\n embedRef.current = null;\n }\n };\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n frame,\n disableJsonLdAttribution,\n stableOnReady,\n stableOnVisualReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n embedRef,\n ]);\n\n return (\n <Fragment>\n {!disableJsonLdAttribution && <DiscoveryMetadata />}\n <div\n ref={containerRef}\n className={className}\n style={style}\n data-testid=\"perspective-widget\"\n {...divProps}\n />\n </Fragment>\n );\n}\n","import { useRef, useEffect, type RefObject } from \"react\";\nimport { DiscoveryMetadata } from \"./DiscoveryMetadata\";\nimport {\n createFullpage,\n createLoadingIndicator,\n fetchEmbedConfig,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./hooks/useStableCallback\";\n\nexport interface FullpageProps extends Omit<EmbedConfig, \"type\"> {\n /** Ref to access the embed handle for programmatic control */\n embedRef?: RefObject<EmbedHandle | null>;\n}\n\n/**\n * Full viewport embed component.\n * Takes over the entire screen with the interview.\n */\nexport function Fullpage({\n researchId,\n params,\n brand,\n theme,\n host,\n disableJsonLdAttribution,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n embedRef,\n}: FullpageProps) {\n const handleRef = useRef<EmbedHandle | null>(null);\n\n // Stable callbacks\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnClose = useStableCallback(onClose);\n const stableOnError = useStableCallback(onError);\n\n useEffect(() => {\n // Show skeleton instantly while config fetches in parallel\n const skeleton = createLoadingIndicator({ theme, brand });\n skeleton.style.position = \"fixed\";\n skeleton.style.inset = \"0\";\n skeleton.style.zIndex = \"2147483647\";\n document.body.appendChild(skeleton);\n\n let cancelled = false;\n\n fetchEmbedConfig(researchId, host).then((config) => {\n if (cancelled) return;\n skeleton.remove();\n\n const handle = createFullpage({\n researchId,\n params,\n brand,\n theme,\n host,\n disableJsonLdAttribution,\n _apiConfig: config,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = handle;\n\n if (embedRef) {\n embedRef.current = handle;\n }\n });\n\n return () => {\n cancelled = true;\n skeleton.remove();\n if (handleRef.current) {\n handleRef.current.unmount();\n handleRef.current = null;\n }\n if (embedRef) {\n embedRef.current = null;\n }\n };\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n disableJsonLdAttribution,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n embedRef,\n ]);\n\n // The fullpage overlay is added to document.body via SDK; render attribution for SSR\n return disableJsonLdAttribution ? null : <DiscoveryMetadata />;\n}\n","import { useEffect, type RefObject } from \"react\";\nimport { type EmbedConfig, type FloatHandle } from \"@perspective-ai/sdk\";\nimport { DiscoveryMetadata } from \"./DiscoveryMetadata\";\nimport {\n useFloatBubble,\n type LauncherConfigReact,\n} from \"./hooks/useFloatBubble\";\n\nexport interface FloatBubbleProps extends Omit<\n EmbedConfig,\n \"type\" | \"launcher\"\n> {\n /** Ref to access the handle for programmatic control */\n embedRef?: RefObject<FloatHandle | null>;\n /** Customize the floating launcher button appearance */\n launcher?: LauncherConfigReact;\n}\n\n/**\n * Floating bubble widget that expands into a chat window.\n * This is a convenience wrapper around useFloatBubble hook.\n *\n * @example\n * ```tsx\n * <FloatBubble researchId=\"abc\" onSubmit={handleSubmit} />\n * ```\n */\nexport function FloatBubble({\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n teaser,\n disableJsonLdAttribution,\n launcher,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n embedRef,\n}: FloatBubbleProps) {\n const { handle } = useFloatBubble({\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n teaser,\n disableJsonLdAttribution,\n launcher,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n });\n\n useEffect(() => {\n if (embedRef) {\n embedRef.current = handle;\n }\n return () => {\n if (embedRef) {\n embedRef.current = null;\n }\n };\n }, [embedRef, handle]);\n\n return disableJsonLdAttribution ? null : <DiscoveryMetadata />;\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { EmbedConfig, EmbedHandle, LauncherConfig, FloatHandle, TriggerConfig, ShowOnce, ThemeConfig } from '@perspective-ai/sdk';
2
- export { AutoOpenConfig, BrandColors, EmbedConfig, EmbedError, EmbedHandle, FloatHandle, ShowOnce, ThemeValue, TriggerConfig } from '@perspective-ai/sdk';
2
+ export { AutoOpenConfig, BrandColors, EmbedConfig, EmbedError, EmbedHandle, FloatHandle, ShowOnce, TeaserConfig, ThemeValue, TriggerConfig } from '@perspective-ai/sdk';
3
3
  import { ReactNode, HTMLAttributes, RefObject } from 'react';
4
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
5
5
 
@@ -185,7 +185,7 @@ interface FloatBubbleProps extends Omit<EmbedConfig, "type" | "launcher"> {
185
185
  * <FloatBubble researchId="abc" onSubmit={handleSubmit} />
186
186
  * ```
187
187
  */
188
- declare function FloatBubble({ researchId, params, brand, theme, host, channel, welcomeMessage, disableJsonLdAttribution, launcher, onReady, onSubmit, onNavigate, onClose, onError, embedRef, }: FloatBubbleProps): react_jsx_runtime.JSX.Element | null;
188
+ declare function FloatBubble({ researchId, params, brand, theme, host, channel, welcomeMessage, teaser, disableJsonLdAttribution, launcher, onReady, onSubmit, onNavigate, onClose, onError, embedRef, }: FloatBubbleProps): react_jsx_runtime.JSX.Element | null;
189
189
 
190
190
  interface DiscoveryMetadataProps {
191
191
  /** Override the SDK version in the structured data */
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { EmbedConfig, EmbedHandle, LauncherConfig, FloatHandle, TriggerConfig, ShowOnce, ThemeConfig } from '@perspective-ai/sdk';
2
- export { AutoOpenConfig, BrandColors, EmbedConfig, EmbedError, EmbedHandle, FloatHandle, ShowOnce, ThemeValue, TriggerConfig } from '@perspective-ai/sdk';
2
+ export { AutoOpenConfig, BrandColors, EmbedConfig, EmbedError, EmbedHandle, FloatHandle, ShowOnce, TeaserConfig, ThemeValue, TriggerConfig } from '@perspective-ai/sdk';
3
3
  import { ReactNode, HTMLAttributes, RefObject } from 'react';
4
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
5
5
 
@@ -185,7 +185,7 @@ interface FloatBubbleProps extends Omit<EmbedConfig, "type" | "launcher"> {
185
185
  * <FloatBubble researchId="abc" onSubmit={handleSubmit} />
186
186
  * ```
187
187
  */
188
- declare function FloatBubble({ researchId, params, brand, theme, host, channel, welcomeMessage, disableJsonLdAttribution, launcher, onReady, onSubmit, onNavigate, onClose, onError, embedRef, }: FloatBubbleProps): react_jsx_runtime.JSX.Element | null;
188
+ declare function FloatBubble({ researchId, params, brand, theme, host, channel, welcomeMessage, teaser, disableJsonLdAttribution, launcher, onReady, onSubmit, onNavigate, onClose, onError, embedRef, }: FloatBubbleProps): react_jsx_runtime.JSX.Element | null;
189
189
 
190
190
  interface DiscoveryMetadataProps {
191
191
  /** Override the SDK version in the structured data */
package/dist/index.js CHANGED
@@ -329,6 +329,7 @@ function useFloatBubble(options) {
329
329
  host,
330
330
  channel,
331
331
  welcomeMessage,
332
+ teaser,
332
333
  launcher,
333
334
  onReady,
334
335
  onSubmit,
@@ -355,6 +356,14 @@ function useFloatBubble(options) {
355
356
  onClose?.();
356
357
  }, [isControlled, onOpenChange, onClose]);
357
358
  const stableOnClose = useStableCallback(handleClose);
359
+ const teaserEnabled = teaser?.enabled;
360
+ const teaserDelay = teaser?.delay;
361
+ const teaserSound = teaser?.sound;
362
+ const hasTeaser = teaser !== void 0;
363
+ const stableTeaser = useMemo(
364
+ () => hasTeaser ? { enabled: teaserEnabled, delay: teaserDelay, sound: teaserSound } : void 0,
365
+ [hasTeaser, teaserEnabled, teaserDelay, teaserSound]
366
+ );
358
367
  const resolvedLauncher = useMemo(() => {
359
368
  if (!launcher) return void 0;
360
369
  const { icon, ...rest } = launcher;
@@ -381,6 +390,7 @@ function useFloatBubble(options) {
381
390
  host,
382
391
  channel,
383
392
  welcomeMessage,
393
+ teaser: stableTeaser,
384
394
  launcher: resolvedLauncher,
385
395
  onReady: stableOnReady,
386
396
  onSubmit: stableOnSubmit,
@@ -405,6 +415,7 @@ function useFloatBubble(options) {
405
415
  host,
406
416
  channel,
407
417
  welcomeMessage,
418
+ stableTeaser,
408
419
  resolvedLauncher,
409
420
  stableOnReady,
410
421
  stableOnSubmit,
@@ -734,6 +745,7 @@ function FloatBubble({
734
745
  host,
735
746
  channel,
736
747
  welcomeMessage,
748
+ teaser,
737
749
  disableJsonLdAttribution,
738
750
  launcher,
739
751
  onReady,
@@ -751,6 +763,7 @@ function FloatBubble({
751
763
  host,
752
764
  channel,
753
765
  welcomeMessage,
766
+ teaser,
754
767
  launcher,
755
768
  onReady,
756
769
  onSubmit,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hooks/useStableCallback.ts","../src/hooks/useEmbedConfig.ts","../src/hooks/usePopup.ts","../src/hooks/useSlider.ts","../src/hooks/useFloatBubble.ts","../src/hooks/useAutoOpen.ts","../src/hooks/useThemeSync.ts","../src/DiscoveryMetadata.tsx","../src/Widget.tsx","../src/Fullpage.tsx","../src/FloatBubble.tsx"],"names":["useEffect","useState","useRef","useCallback","getPersistedOpenState","openPopup","jsx","fetchEmbedConfig"],"mappings":";;;;;;AAEA,IAAM,yBAAA,GACJ,OAAO,MAAA,KAAW,WAAA,GAAc,eAAA,GAAkB,SAAA;AAE7C,SAAS,kBAEd,QAAA,EAAgB;AAChB,EAAA,MAAM,WAAA,GAAc,OAAO,QAAQ,CAAA;AAEnC,EAAA,yBAAA,CAA0B,MAAM;AAC9B,IAAA,WAAA,CAAY,OAAA,GAAU,QAAA;AAAA,EACxB,CAAC,CAAA;AAKD,EAAA,MAAM,MAAA,GAAS,WAAA;AAAA,KACZ,CAAA,GAAI,IAAA,KAAgB,WAAA,CAAY,OAAA,GAAU,GAAG,IAAI,CAAA;AAAA,IAClD;AAAC,GACH;AAEA,EAAA,OAAO,WAAW,MAAA,GAAS,QAAA;AAC7B;ACfO,SAAS,cAAA,CACd,YACA,IAAA,EACyB;AACzB,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,QAAA,EAExB;AAEF,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,SAAA,GAAY,KAAA;AAChB,IAAA,gBAAA,CAAiB,UAAA,EAAY,IAAI,CAAA,CAAE,IAAA,CAAK,CAAC,MAAA,KAAW;AAClD,MAAA,IAAI,CAAC,WAAW,QAAA,CAAS,EAAE,YAAY,IAAA,EAAM,MAAA,EAAQ,QAAQ,CAAA;AAAA,IAC/D,CAAC,CAAA;AACD,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,IAAA;AAAA,IACd,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,UAAA,EAAY,IAAI,CAAC,CAAA;AAGrB,EAAA,OAAO,OAAO,UAAA,KAAe,UAAA,IAAc,MAAM,IAAA,KAAS,IAAA,GACtD,MAAM,MAAA,GACN,MAAA;AACN;;;ACqBO,SAAS,SAAS,OAAA,EAA0C;AACjE,EAAA,MAAM;AAAA,IACJ,UAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA,IACA,IAAA;AAAA,IACA,YAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAA;AAAA,IACA,UAAA;AAAA,IACA,OAAA;AAAA,IACA,OAAA;AAAA,IACA,IAAA,EAAM,cAAA;AAAA,IACN;AAAA,GACF,GAAI,OAAA;AAEJ,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIC,SAA6B,IAAI,CAAA;AAC7D,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAIA,SAAS,KAAK,CAAA;AACtD,EAAA,MAAM,SAAA,GAAYC,OAA2B,IAAI,CAAA;AACjD,EAAA,MAAM,WAAA,GAAc,cAAA,CAAe,UAAA,EAAY,IAAI,CAAA;AACnD,EAAA,MAAM,cAAA,GAAiBA,OAAO,WAAW,CAAA;AACzC,EAAA,cAAA,CAAe,OAAA,GAAU,WAAA;AAEzB,EAAA,MAAM,eAAe,cAAA,KAAmB,MAAA;AACxC,EAAA,MAAM,MAAA,GAAS,eAAe,cAAA,GAAiB,YAAA;AAE/C,EAAA,MAAM,aAAA,GAAgB,kBAAkB,OAAO,CAAA;AAC/C,EAAA,MAAM,cAAA,GAAiB,kBAAkB,QAAQ,CAAA;AACjD,EAAA,MAAM,gBAAA,GAAmB,kBAAkB,UAAU,CAAA;AACrD,EAAA,MAAM,aAAA,GAAgB,kBAAkB,OAAO,CAAA;AAE/C,EAAA,MAAM,OAAA,GAAUC,WAAAA;AAAA,IACd,CAAC,KAAA,KAAmB;AAClB,MAAA,IAAI,YAAA,EAAc;AAChB,QAAA,YAAA,GAAe,KAAK,CAAA;AAAA,MACtB,CAAA,MAAO;AACL,QAAA,eAAA,CAAgB,KAAK,CAAA;AAAA,MACvB;AAAA,IACF,CAAA;AAAA,IACA,CAAC,cAAc,YAAY;AAAA,GAC7B;AAEA,EAAA,MAAM,WAAA,GAAcA,YAAY,MAAM;AACpC,IAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AACpB,IAAA,SAAA,CAAU,IAAI,CAAA;AACd,IAAA,OAAA,CAAQ,KAAK,CAAA;AACb,IAAA,OAAA,IAAU;AAAA,EACZ,CAAA,EAAG,CAAC,OAAA,EAAS,OAAO,CAAC,CAAA;AAErB,EAAA,MAAM,aAAA,GAAgB,kBAAkB,WAAW,CAAA;AAEnD,EAAA,MAAM,WAAA,GAAcA,YAAY,MAAM;AACpC,IAAA,IAAI,SAAA,CAAU,OAAA,EAAS,OAAO,SAAA,CAAU,OAAA;AAExC,IAAA,MAAM,YAAY,SAAA,CAAU;AAAA,MAC1B,UAAA;AAAA,MACA,MAAA;AAAA,MACA,KAAA;AAAA,MACA,KAAA;AAAA,MACA,IAAA;AAAA,MACA,YAAA;AAAA,MACA,YAAY,cAAA,CAAe,OAAA;AAAA,MAC3B,OAAA,EAAS,aAAA;AAAA,MACT,QAAA,EAAU,cAAA;AAAA,MACV,UAAA,EAAY,gBAAA;AAAA,MACZ,OAAA,EAAS,aAAA;AAAA,MACT,OAAA,EAAS;AAAA,KACV,CAAA;AAED,IAAA,SAAA,CAAU,OAAA,GAAU,SAAA;AACpB,IAAA,SAAA,CAAU,SAAS,CAAA;AACnB,IAAA,OAAO,SAAA;AAAA,EACT,CAAA,EAAG;AAAA,IACD,UAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA,IACA,IAAA;AAAA,IACA,YAAA;AAAA,IACA,aAAA;AAAA,IACA,cAAA;AAAA,IACA,gBAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,MAAM,YAAA,GAAeA,WAAAA,CAAY,CAAC,IAAA,KAAgC;AAChE,IAAA,IAAI,UAAU,OAAA,EAAS;AACrB,MAAA,IAAI,SAAS,SAAA,EAAW;AACtB,QAAA,SAAA,CAAU,QAAQ,OAAA,EAAQ;AAAA,MAC5B,CAAA,MAAO;AACL,QAAA,SAAA,CAAU,QAAQ,OAAA,EAAQ;AAAA,MAC5B;AACA,MAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AACpB,MAAA,SAAA,CAAU,IAAI,CAAA;AAAA,IAChB;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,MAAA,GAASA,YAAY,MAAM;AAC/B,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,YAAA,GAAe,IAAI,CAAA;AAAA,IACrB,CAAA,MAAO;AACL,MAAA,WAAA,EAAY;AACZ,MAAA,eAAA,CAAgB,IAAI,CAAA;AAAA,IACtB;AAAA,EACF,CAAA,EAAG,CAAC,YAAA,EAAc,YAAA,EAAc,WAAW,CAAC,CAAA;AAE5C,EAAA,MAAM,OAAA,GAAUA,YAAY,MAAM;AAChC,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,YAAA,GAAe,KAAK,CAAA;AAAA,IACtB,CAAA,MAAO;AACL,MAAA,YAAA,CAAa,SAAS,CAAA;AACtB,MAAA,eAAA,CAAgB,KAAK,CAAA;AAAA,IACvB;AAAA,EACF,CAAA,EAAG,CAAC,YAAA,EAAc,YAAA,EAAc,YAAY,CAAC,CAAA;AAE7C,EAAA,MAAM,QAAA,GAAWA,YAAY,MAAM;AACjC,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,OAAA,EAAQ;AAAA,IACV,CAAA,MAAO;AACL,MAAA,MAAA,EAAO;AAAA,IACT;AAAA,EACF,CAAA,EAAG,CAAC,MAAA,EAAQ,MAAA,EAAQ,OAAO,CAAC,CAAA;AAE5B,EAAAH,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,YAAA,EAAc;AAEnB,IAAA,IAAI,cAAA,IAAkB,CAAC,SAAA,CAAU,OAAA,EAAS;AACxC,MAAA,WAAA,EAAY;AAAA,IACd,CAAA,MAAA,IAAW,CAAC,cAAA,IAAkB,SAAA,CAAU,OAAA,EAAS;AAC/C,MAAA,YAAA,CAAa,SAAS,CAAA;AAAA,IACxB;AAAA,EACF,GAAG,CAAC,cAAA,EAAgB,YAAA,EAAc,WAAA,EAAa,YAAY,CAAC,CAAA;AAE5D,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,YAAA,IAAgB,UAAU,OAAA,EAAS;AAEvC,IAAA,IAAI,qBAAA,CAAsB,EAAE,UAAA,EAAY,IAAA,EAAM,SAAS,IAAA,EAAM,MAAM,IAAA,EAAM;AACvE,MAAA;AAAA,IACF;AAEA,IAAA,WAAA,EAAY;AACZ,IAAA,eAAA,CAAgB,IAAI,CAAA;AAAA,EACtB,GAAG,CAAC,WAAA,EAAa,IAAA,EAAM,YAAA,EAAc,UAAU,CAAC,CAAA;AAEhD,EAAAA,UAAU,MAAM;AACd,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,UAAU,OAAA,EAAS;AACrB,QAAA,SAAA,CAAU,QAAQ,OAAA,EAAQ;AAC1B,QAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AAAA,MACtB;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,MAAA;AAAA,IACN,KAAA,EAAO,OAAA;AAAA,IACP,MAAA,EAAQ,QAAA;AAAA,IACR,MAAA;AAAA,IACA;AAAA,GACF;AACF;AC3KO,SAAS,UAAU,OAAA,EAA4C;AACpE,EAAA,MAAM;AAAA,IACJ,UAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA,IACA,IAAA;AAAA,IACA,YAAA;AAAA,IACA,UAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAA;AAAA,IACA,UAAA;AAAA,IACA,OAAA;AAAA,IACA,OAAA;AAAA,IACA,IAAA,EAAM,cAAA;AAAA,IACN;AAAA,GACF,GAAI,OAAA;AAEJ,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIC,SAA6B,IAAI,CAAA;AAC7D,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAIA,SAAS,KAAK,CAAA;AACtD,EAAA,MAAM,SAAA,GAAYC,OAA2B,IAAI,CAAA;AACjD,EAAA,MAAM,WAAA,GAAc,cAAA,CAAe,UAAA,EAAY,IAAI,CAAA;AACnD,EAAA,MAAM,cAAA,GAAiBA,OAAO,WAAW,CAAA;AACzC,EAAA,cAAA,CAAe,OAAA,GAAU,WAAA;AAEzB,EAAA,MAAM,eAAe,cAAA,KAAmB,MAAA;AACxC,EAAA,MAAM,MAAA,GAAS,eAAe,cAAA,GAAiB,YAAA;AAE/C,EAAA,MAAM,aAAA,GAAgB,kBAAkB,OAAO,CAAA;AAC/C,EAAA,MAAM,cAAA,GAAiB,kBAAkB,QAAQ,CAAA;AACjD,EAAA,MAAM,gBAAA,GAAmB,kBAAkB,UAAU,CAAA;AACrD,EAAA,MAAM,aAAA,GAAgB,kBAAkB,OAAO,CAAA;AAE/C,EAAA,MAAM,OAAA,GAAUC,WAAAA;AAAA,IACd,CAAC,KAAA,KAAmB;AAClB,MAAA,IAAI,YAAA,EAAc;AAChB,QAAA,YAAA,GAAe,KAAK,CAAA;AAAA,MACtB,CAAA,MAAO;AACL,QAAA,eAAA,CAAgB,KAAK,CAAA;AAAA,MACvB;AAAA,IACF,CAAA;AAAA,IACA,CAAC,cAAc,YAAY;AAAA,GAC7B;AAEA,EAAA,MAAM,WAAA,GAAcA,YAAY,MAAM;AACpC,IAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AACpB,IAAA,SAAA,CAAU,IAAI,CAAA;AACd,IAAA,OAAA,CAAQ,KAAK,CAAA;AACb,IAAA,OAAA,IAAU;AAAA,EACZ,CAAA,EAAG,CAAC,OAAA,EAAS,OAAO,CAAC,CAAA;AAErB,EAAA,MAAM,aAAA,GAAgB,kBAAkB,WAAW,CAAA;AAEnD,EAAA,MAAM,YAAA,GAAeA,YAAY,MAAM;AACrC,IAAA,IAAI,SAAA,CAAU,OAAA,EAAS,OAAO,SAAA,CAAU,OAAA;AAExC,IAAA,MAAM,YAAY,UAAA,CAAW;AAAA,MAC3B,UAAA;AAAA,MACA,MAAA;AAAA,MACA,KAAA;AAAA,MACA,KAAA;AAAA,MACA,IAAA;AAAA,MACA,YAAA;AAAA,MACA,UAAA;AAAA,MACA,YAAY,cAAA,CAAe,OAAA;AAAA,MAC3B,OAAA,EAAS,aAAA;AAAA,MACT,QAAA,EAAU,cAAA;AAAA,MACV,UAAA,EAAY,gBAAA;AAAA,MACZ,OAAA,EAAS,aAAA;AAAA,MACT,OAAA,EAAS;AAAA,KACV,CAAA;AAED,IAAA,SAAA,CAAU,OAAA,GAAU,SAAA;AACpB,IAAA,SAAA,CAAU,SAAS,CAAA;AACnB,IAAA,OAAO,SAAA;AAAA,EACT,CAAA,EAAG;AAAA,IACD,UAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA,IACA,IAAA;AAAA,IACA,YAAA;AAAA,IACA,UAAA;AAAA,IACA,aAAA;AAAA,IACA,cAAA;AAAA,IACA,gBAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,MAAM,aAAA,GAAgBA,WAAAA,CAAY,CAAC,IAAA,KAAgC;AACjE,IAAA,IAAI,UAAU,OAAA,EAAS;AACrB,MAAA,IAAI,SAAS,SAAA,EAAW;AACtB,QAAA,SAAA,CAAU,QAAQ,OAAA,EAAQ;AAAA,MAC5B,CAAA,MAAO;AACL,QAAA,SAAA,CAAU,QAAQ,OAAA,EAAQ;AAAA,MAC5B;AACA,MAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AACpB,MAAA,SAAA,CAAU,IAAI,CAAA;AAAA,IAChB;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,MAAA,GAASA,YAAY,MAAM;AAC/B,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,YAAA,GAAe,IAAI,CAAA;AAAA,IACrB,CAAA,MAAO;AACL,MAAA,YAAA,EAAa;AACb,MAAA,eAAA,CAAgB,IAAI,CAAA;AAAA,IACtB;AAAA,EACF,CAAA,EAAG,CAAC,YAAA,EAAc,YAAA,EAAc,YAAY,CAAC,CAAA;AAE7C,EAAA,MAAM,OAAA,GAAUA,YAAY,MAAM;AAChC,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,YAAA,GAAe,KAAK,CAAA;AAAA,IACtB,CAAA,MAAO;AACL,MAAA,aAAA,CAAc,SAAS,CAAA;AACvB,MAAA,eAAA,CAAgB,KAAK,CAAA;AAAA,IACvB;AAAA,EACF,CAAA,EAAG,CAAC,YAAA,EAAc,YAAA,EAAc,aAAa,CAAC,CAAA;AAE9C,EAAA,MAAM,QAAA,GAAWA,YAAY,MAAM;AACjC,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,OAAA,EAAQ;AAAA,IACV,CAAA,MAAO;AACL,MAAA,MAAA,EAAO;AAAA,IACT;AAAA,EACF,CAAA,EAAG,CAAC,MAAA,EAAQ,MAAA,EAAQ,OAAO,CAAC,CAAA;AAE5B,EAAAH,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,YAAA,EAAc;AAEnB,IAAA,IAAI,cAAA,IAAkB,CAAC,SAAA,CAAU,OAAA,EAAS;AACxC,MAAA,YAAA,EAAa;AAAA,IACf,CAAA,MAAA,IAAW,CAAC,cAAA,IAAkB,SAAA,CAAU,OAAA,EAAS;AAC/C,MAAA,aAAA,CAAc,SAAS,CAAA;AAAA,IACzB;AAAA,EACF,GAAG,CAAC,cAAA,EAAgB,YAAA,EAAc,YAAA,EAAc,aAAa,CAAC,CAAA;AAE9D,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,YAAA,IAAgB,UAAU,OAAA,EAAS;AAEvC,IAAA,IAAII,qBAAAA,CAAsB,EAAE,UAAA,EAAY,IAAA,EAAM,UAAU,IAAA,EAAM,MAAM,IAAA,EAAM;AACxE,MAAA;AAAA,IACF;AAEA,IAAA,YAAA,EAAa;AACb,IAAA,eAAA,CAAgB,IAAI,CAAA;AAAA,EACtB,GAAG,CAAC,YAAA,EAAc,IAAA,EAAM,YAAA,EAAc,UAAU,CAAC,CAAA;AAEjD,EAAAJ,UAAU,MAAM;AACd,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,UAAU,OAAA,EAAS;AACrB,QAAA,SAAA,CAAU,QAAQ,OAAA,EAAQ;AAC1B,QAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AAAA,MACtB;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,MAAA;AAAA,IACN,KAAA,EAAO,OAAA;AAAA,IACP,MAAA,EAAQ,QAAA;AAAA,IACR,MAAA;AAAA,IACA;AAAA,GACF;AACF;AC3IO,SAAS,eACd,OAAA,EACsB;AACtB,EAAA,MAAM;AAAA,IACJ,UAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA,IACA,IAAA;AAAA,IACA,OAAA;AAAA,IACA,cAAA;AAAA,IACA,QAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAA;AAAA,IACA,UAAA;AAAA,IACA,OAAA;AAAA,IACA,OAAA;AAAA,IACA,IAAA,EAAM,cAAA;AAAA,IACN;AAAA,GACF,GAAI,OAAA;AAEJ,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIC,SAA6B,IAAI,CAAA;AAC7D,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAIA,SAAS,KAAK,CAAA;AACtD,EAAA,MAAM,SAAA,GAAYC,OAA2B,IAAI,CAAA;AACjD,EAAA,MAAM,WAAA,GAAc,cAAA,CAAe,UAAA,EAAY,IAAI,CAAA;AAEnD,EAAA,MAAM,eAAe,cAAA,KAAmB,MAAA;AAExC,EAAA,MAAM,aAAA,GAAgB,kBAAkB,OAAO,CAAA;AAC/C,EAAA,MAAM,cAAA,GAAiB,kBAAkB,QAAQ,CAAA;AACjD,EAAA,MAAM,gBAAA,GAAmB,kBAAkB,UAAU,CAAA;AACrD,EAAA,MAAM,aAAA,GAAgB,kBAAkB,OAAO,CAAA;AAE/C,EAAA,MAAM,WAAA,GAAcC,YAAY,MAAM;AACpC,IAAA,eAAA,CAAgB,KAAK,CAAA;AACrB,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,YAAA,GAAe,KAAK,CAAA;AAAA,IACtB;AACA,IAAA,OAAA,IAAU;AAAA,EACZ,CAAA,EAAG,CAAC,YAAA,EAAc,YAAA,EAAc,OAAO,CAAC,CAAA;AAExC,EAAA,MAAM,aAAA,GAAgB,kBAAkB,WAAW,CAAA;AAGnD,EAAA,MAAM,gBAAA,GAAmB,QAAQ,MAA2C;AAC1E,IAAA,IAAI,CAAC,UAAU,OAAO,MAAA;AACtB,IAAA,MAAM,EAAE,IAAA,EAAM,GAAG,IAAA,EAAK,GAAI,QAAA;AAE1B,IAAA,IACE,IAAA,KAAS,SACT,IAAA,KAAS,IAAA,IACT,SAAS,MAAA,IACT,IAAA,KAAS,CAAA,IACT,IAAA,KAAS,EAAA,EACT;AACA,MAAA,OAAO,OAAO,IAAA,CAAK,IAAI,CAAA,CAAE,MAAA,GAAS,IAAI,IAAA,GAAO,MAAA;AAAA,IAC/C;AACA,IAAA,IAAI,cAAA,CAAe,IAAI,CAAA,EAAG;AACxB,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,IAAA,EAAM,EAAE,GAAA,EAAK,oBAAA,CAAqB,IAAI,CAAA,EAAE,EAAE;AAAA,IAC9D;AAEA,IAAA,IAAI,IAAA,KAAS,SAAA,IAAa,IAAA,KAAS,QAAA,EAAU;AAC3C,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,IAAA,EAAmC;AAAA,IACvD;AACA,IAAA,IAAI,OAAO,IAAA,KAAS,QAAA,KAAa,KAAA,IAAS,IAAA,IAAQ,SAAS,IAAA,CAAA,EAAO;AAChE,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,IAAA,EAAgD;AAAA,IACpE;AAEA,IAAA,OAAO,OAAO,IAAA,CAAK,IAAI,CAAA,CAAE,MAAA,GAAS,IAAI,IAAA,GAAO,MAAA;AAAA,EAC/C,CAAA,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAAH,UAAU,MAAM;AACd,IAAA,MAAM,YAAY,iBAAA,CAAkB;AAAA,MAClC,UAAA;AAAA,MACA,MAAA;AAAA,MACA,KAAA;AAAA,MACA,KAAA;AAAA,MACA,IAAA;AAAA,MACA,OAAA;AAAA,MACA,cAAA;AAAA,MACA,QAAA,EAAU,gBAAA;AAAA,MACV,OAAA,EAAS,aAAA;AAAA,MACT,QAAA,EAAU,cAAA;AAAA,MACV,UAAA,EAAY,gBAAA;AAAA,MACZ,OAAA,EAAS,aAAA;AAAA,MACT,OAAA,EAAS;AAAA,KACV,CAAA;AAED,IAAA,SAAA,CAAU,OAAA,GAAU,SAAA;AACpB,IAAA,SAAA,CAAU,SAAS,CAAA;AAEnB,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,SAAA,CAAU,YAAY,SAAA,EAAW;AACnC,QAAA,SAAA,CAAU,OAAA,EAAQ;AAClB,QAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AACpB,QAAA,SAAA,CAAU,IAAI,CAAA;AAAA,MAChB;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG;AAAA,IACD,UAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA,IACA,IAAA;AAAA,IACA,OAAA;AAAA,IACA,cAAA;AAAA,IACA,gBAAA;AAAA,IACA,aAAA;AAAA,IACA,cAAA;AAAA,IACA,gBAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACD,CAAA;AAGD,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,WAAA,IAAe,CAAC,SAAA,CAAU,OAAA,EAAS;AAExC,IAAC,SAAA,CAAU,QAAQ,MAAA,CAAe;AAAA,MAChC,OAAA,EAAS,WAAA,CAAY,OAAA,IAAW,WAAA,CAAY,eAAA,IAAmB,MAAA;AAAA,MAC/D,gBAAgB,WAAA,CAAY,cAAA;AAAA,MAC5B,UAAA,EAAY;AAAA,KACb,CAAA;AAAA,EACH,CAAA,EAAG,CAAC,WAAW,CAAC,CAAA;AAEhB,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,YAAA,IAAgB,CAAC,MAAA,EAAQ;AAE9B,IAAA,IAAI,cAAA,IAAkB,CAAC,MAAA,CAAO,MAAA,EAAQ;AACpC,MAAA,MAAA,CAAO,IAAA,EAAK;AAAA,IACd,CAAA,MAAA,IAAW,CAAC,cAAA,IAAkB,MAAA,CAAO,MAAA,EAAQ;AAC3C,MAAA,MAAA,CAAO,KAAA,EAAM;AAAA,IACf;AAAA,EACF,CAAA,EAAG,CAAC,cAAA,EAAgB,YAAA,EAAc,MAAM,CAAC,CAAA;AAEzC,EAAA,MAAM,MAAA,GAASG,YAAY,MAAM;AAC/B,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,YAAA,GAAe,IAAI,CAAA;AAAA,IACrB,CAAA,MAAO;AACL,MAAA,SAAA,CAAU,SAAS,IAAA,EAAK;AACxB,MAAA,eAAA,CAAgB,IAAI,CAAA;AAAA,IACtB;AAAA,EACF,CAAA,EAAG,CAAC,YAAA,EAAc,YAAY,CAAC,CAAA;AAE/B,EAAA,MAAM,OAAA,GAAUA,YAAY,MAAM;AAChC,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,YAAA,GAAe,KAAK,CAAA;AAAA,IACtB,CAAA,MAAO;AACL,MAAA,SAAA,CAAU,SAAS,KAAA,EAAM;AACzB,MAAA,eAAA,CAAgB,KAAK,CAAA;AAAA,IACvB;AAAA,EACF,CAAA,EAAG,CAAC,YAAA,EAAc,YAAY,CAAC,CAAA;AAE/B,EAAA,MAAM,QAAA,GAAWA,YAAY,MAAM;AACjC,IAAA,MAAM,aAAA,GAAgB,SAAA,CAAU,OAAA,EAAS,MAAA,IAAU,YAAA;AACnD,IAAA,IAAI,aAAA,EAAe;AACjB,MAAA,OAAA,EAAQ;AAAA,IACV,CAAA,MAAO;AACL,MAAA,MAAA,EAAO;AAAA,IACT;AAAA,EACF,CAAA,EAAG,CAAC,YAAA,EAAc,MAAA,EAAQ,OAAO,CAAC,CAAA;AAElC,EAAA,MAAM,SAAA,GAAYA,YAAY,MAAM;AAClC,IAAA,SAAA,CAAU,SAAS,OAAA,EAAQ;AAC3B,IAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AACpB,IAAA,SAAA,CAAU,IAAI,CAAA;AACd,IAAA,eAAA,CAAgB,KAAK,CAAA;AAAA,EACvB,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,MAAA,GAAS,YAAA,GACX,cAAA,GACC,MAAA,EAAQ,MAAA,IAAU,YAAA;AAEvB,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,MAAA;AAAA,IACN,KAAA,EAAO,OAAA;AAAA,IACP,MAAA,EAAQ,QAAA;AAAA,IACR,OAAA,EAAS,SAAA;AAAA,IACT,MAAA;AAAA,IACA;AAAA,GACF;AACF;AC/NO,SAAS,YAAY,OAAA,EAAgD;AAC1E,EAAA,MAAM,EAAE,OAAA,EAAS,QAAA,GAAW,WAAW,UAAA,EAAY,GAAG,aAAY,GAAI,OAAA;AACtE,EAAA,MAAM,UAAA,GAAaD,OAA4B,IAAI,CAAA;AACnD,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAID,SAAS,KAAK,CAAA;AAChD,EAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,IAAA,KAAS,SAAA,GAAY,QAAQ,KAAA,GAAQ,MAAA;AAClE,EAAA,MAAM,SAAA,GAAY,cAAA,CAAe,UAAA,EAAY,WAAA,CAAY,IAAI,CAAA;AAC7D,EAAA,MAAM,YAAA,GAAeC,OAAO,SAAS,CAAA;AACrC,EAAA,YAAA,CAAa,OAAA,GAAU,SAAA;AAGvB,EAAA,MAAM,eAAA,GAAkB,kBAAkB,MAAM;AAC9C,IAAA,SAAA,CAAU,YAAY,QAAQ,CAAA;AAC9B,IAAAG,SAAAA,CAAU;AAAA,MACR,UAAA;AAAA,MACA,GAAG,WAAA;AAAA,MACH,YAAY,YAAA,CAAa;AAAA,KAC1B,CAAA;AAAA,EACH,CAAC,CAAA;AAED,EAAAL,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,UAAA,CAAW,UAAA,EAAY,QAAQ,CAAA,EAAG;AAEvC,IAAA,UAAA,CAAW,OAAA,GAAU,YAAA,CAAa,OAAA,EAAS,MAAM;AAC/C,MAAA,YAAA,CAAa,CAAC,IAAA,KAAS;AACrB,QAAA,IAAI,MAAM,OAAO,IAAA;AACjB,QAAA,eAAA,EAAgB;AAChB,QAAA,OAAO,IAAA;AAAA,MACT,CAAC,CAAA;AAAA,IACH,CAAC,CAAA;AAED,IAAA,OAAO,MAAM;AACX,MAAA,UAAA,CAAW,OAAA,IAAU;AACrB,MAAA,UAAA,CAAW,OAAA,GAAU,IAAA;AAAA,IACvB,CAAA;AAAA,EAGF,GAAG,CAAC,UAAA,EAAY,QAAQ,IAAA,EAAM,YAAA,EAAc,QAAQ,CAAC,CAAA;AAErD,EAAA,MAAM,MAAA,GAASG,YAAY,MAAM;AAC/B,IAAA,UAAA,CAAW,OAAA,IAAU;AACrB,IAAA,UAAA,CAAW,OAAA,GAAU,IAAA;AAAA,EACvB,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,OAAO,EAAE,QAAQ,SAAA,EAAU;AAC7B;AC7DO,SAAS,YAAA,CAAa,QAAoB,QAAA,EAAiB;AAGhE,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIF,QAAAA;AAAA,IAC9B,KAAA,KAAU,WAAW,KAAA,GAAQ;AAAA,GAC/B;AAEA,EAAAD,UAAU,MAAM;AACd,IAAA,IAAI,UAAU,QAAA,EAAU;AACtB,MAAA,WAAA,CAAY,KAAK,CAAA;AACjB,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,EAAA,GAAK,MAAA,CAAO,UAAA,CAAW,8BAA8B,CAAA;AAG3D,IAAA,WAAA,CAAY,EAAA,CAAG,OAAA,GAAU,MAAA,GAAS,OAAO,CAAA;AAEzC,IAAA,MAAM,UAAU,CAAC,CAAA,KACf,YAAY,CAAA,CAAE,OAAA,GAAU,SAAS,OAAO,CAAA;AAE1C,IAAA,EAAA,CAAG,gBAAA,CAAiB,UAAU,OAAO,CAAA;AACrC,IAAA,OAAO,MAAM,EAAA,CAAG,mBAAA,CAAoB,QAAA,EAAU,OAAO,CAAA;AAAA,EACvD,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAEV,EAAA,OAAO,QAAA;AACT;ACjCA,IAAM,eAAA,GAAkB,2BAAA;AAgCjB,SAAS,iBAAA,CAAkB,EAAE,OAAA,EAAQ,EAA2B;AACrE,EAAA,MAAM,MAAA,GAAS;AAAA,IACb,UAAA,EAAY,oBAAA;AAAA,IACZ,QAAA,EAAU;AAAA,MACR;AAAA,QACE,OAAA,EAAS,qBAAA;AAAA,QACT,KAAA,EAAO,GAAG,eAAe,CAAA,QAAA,CAAA;AAAA,QACzB,IAAA,EAAM,gBAAA;AAAA,QACN,WAAA,EACE,8LAAA;AAAA,QACF,GAAA,EAAK,eAAA;AAAA,QACL,mBAAA,EAAqB,qBAAA;AAAA,QACrB,iBAAiB,OAAA,IAAW,WAAA;AAAA,QAC5B,QAAA,EAAU,EAAE,KAAA,EAAO,CAAA,EAAG,eAAe,CAAA,cAAA,CAAA,EAAiB;AAAA,QACtD,eAAA,EAAiB;AAAA,UACf,OAAA,EAAS,iBAAA;AAAA,UACT,WAAA,EAAa,GAAA;AAAA,UACb,UAAA,EAAY,GAAA;AAAA,UACZ,WAAA,EAAa,GAAA;AAAA,UACb,WAAA,EAAa,CAAA;AAAA,UACb,WAAA,EAAa;AAAA;AACf,OACF;AAAA,MACA;AAAA,QACE,OAAA,EAAS,cAAA;AAAA,QACT,KAAA,EAAO,GAAG,eAAe,CAAA,cAAA,CAAA;AAAA,QACzB,IAAA,EAAM,gBAAA;AAAA,QACN,GAAA,EAAK;AAAA;AACP;AACF,GACF;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,qBAAA;AAAA,MACL,yBAAA,EAAwB,EAAA;AAAA,MACxB,yBAAyB,EAAE,MAAA,EAAQ,IAAA,CAAK,SAAA,CAAU,MAAM,CAAA;AAAE;AAAA,GAC5D;AAEJ;AC7CO,SAAS,MAAA,CAAO;AAAA,EACrB,UAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,KAAA;AAAA,EACA,wBAAA;AAAA,EACA,OAAA;AAAA,EACA,aAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,KAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAgB;AACd,EAAA,MAAM,YAAA,GAAeE,OAAuB,IAAI,CAAA;AAChD,EAAA,MAAM,SAAA,GAAYA,OAA2B,IAAI,CAAA;AAGjD,EAAA,MAAM,aAAA,GAAgB,kBAAkB,OAAO,CAAA;AAC/C,EAAA,MAAM,mBAAA,GAAsB,kBAAkB,aAAa,CAAA;AAC3D,EAAA,MAAM,cAAA,GAAiB,kBAAkB,QAAQ,CAAA;AACjD,EAAA,MAAM,gBAAA,GAAmB,kBAAkB,UAAU,CAAA;AACrD,EAAA,MAAM,aAAA,GAAgB,kBAAkB,OAAO,CAAA;AAC/C,EAAA,MAAM,aAAA,GAAgB,kBAAkB,OAAO,CAAA;AAE/C,EAAAF,UAAU,MAAM;AACd,IAAA,MAAM,YAAY,YAAA,CAAa,OAAA;AAC/B,IAAA,IAAI,CAAC,SAAA,EAAW;AAEhB,IAAA,OAAA,CAAQ,WAAA,EAAa,uBAAA,EAAyB,EAAE,UAAA,EAAY,CAAA;AAK5D,IAAA,MAAM,MAAA,GAAS,aAAa,SAAA,EAAW;AAAA,MACrC,UAAA;AAAA,MACA,MAAA;AAAA,MACA,KAAA;AAAA,MACA,KAAA;AAAA,MACA,IAAA;AAAA,MACA,KAAA;AAAA,MACA,wBAAA;AAAA,MACA,OAAA,EAAS,aAAA;AAAA,MACT,aAAA,EAAe,mBAAA;AAAA,MACf,QAAA,EAAU,cAAA;AAAA,MACV,UAAA,EAAY,gBAAA;AAAA,MACZ,OAAA,EAAS,aAAA;AAAA,MACT,OAAA,EAAS;AAAA,KACV,CAAA;AAED,IAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AAEpB,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,OAAA,GAAU,MAAA;AAAA,IACrB;AAEA,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,UAAU,OAAA,EAAS;AACrB,QAAA,SAAA,CAAU,QAAQ,OAAA,EAAQ;AAC1B,QAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AAAA,MACtB;AACA,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,QAAA,CAAS,OAAA,GAAU,IAAA;AAAA,MACrB;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG;AAAA,IACD,UAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA,IACA,IAAA;AAAA,IACA,KAAA;AAAA,IACA,wBAAA;AAAA,IACA,aAAA;AAAA,IACA,mBAAA;AAAA,IACA,cAAA;AAAA,IACA,gBAAA;AAAA,IACA,aAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,4BACG,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,IAAA,CAAC,wBAAA,oBAA4BM,GAAAA,CAAC,iBAAA,EAAA,EAAkB,CAAA;AAAA,oBACjDA,GAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,YAAA;AAAA,QACL,SAAA;AAAA,QACA,KAAA;AAAA,QACA,aAAA,EAAY,oBAAA;AAAA,QACX,GAAG;AAAA;AAAA;AACN,GAAA,EACF,CAAA;AAEJ;AC3GO,SAAS,QAAA,CAAS;AAAA,EACvB,UAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,wBAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAA,EAAkB;AAChB,EAAA,MAAM,SAAA,GAAYJ,OAA2B,IAAI,CAAA;AAGjD,EAAA,MAAM,aAAA,GAAgB,kBAAkB,OAAO,CAAA;AAC/C,EAAA,MAAM,cAAA,GAAiB,kBAAkB,QAAQ,CAAA;AACjD,EAAA,MAAM,gBAAA,GAAmB,kBAAkB,UAAU,CAAA;AACrD,EAAA,MAAM,aAAA,GAAgB,kBAAkB,OAAO,CAAA;AAC/C,EAAA,MAAM,aAAA,GAAgB,kBAAkB,OAAO,CAAA;AAE/C,EAAAF,UAAU,MAAM;AAEd,IAAA,MAAM,QAAA,GAAW,sBAAA,CAAuB,EAAE,KAAA,EAAO,OAAO,CAAA;AACxD,IAAA,QAAA,CAAS,MAAM,QAAA,GAAW,OAAA;AAC1B,IAAA,QAAA,CAAS,MAAM,KAAA,GAAQ,GAAA;AACvB,IAAA,QAAA,CAAS,MAAM,MAAA,GAAS,YAAA;AACxB,IAAA,QAAA,CAAS,IAAA,CAAK,YAAY,QAAQ,CAAA;AAElC,IAAA,IAAI,SAAA,GAAY,KAAA;AAEhB,IAAAO,iBAAiB,UAAA,EAAY,IAAI,CAAA,CAAE,IAAA,CAAK,CAAC,MAAA,KAAW;AAClD,MAAA,IAAI,SAAA,EAAW;AACf,MAAA,QAAA,CAAS,MAAA,EAAO;AAEhB,MAAA,MAAM,SAAS,cAAA,CAAe;AAAA,QAC5B,UAAA;AAAA,QACA,MAAA;AAAA,QACA,KAAA;AAAA,QACA,KAAA;AAAA,QACA,IAAA;AAAA,QACA,wBAAA;AAAA,QACA,UAAA,EAAY,MAAA;AAAA,QACZ,OAAA,EAAS,aAAA;AAAA,QACT,QAAA,EAAU,cAAA;AAAA,QACV,UAAA,EAAY,gBAAA;AAAA,QACZ,OAAA,EAAS,aAAA;AAAA,QACT,OAAA,EAAS;AAAA,OACV,CAAA;AAED,MAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AAEpB,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,QAAA,CAAS,OAAA,GAAU,MAAA;AAAA,MACrB;AAAA,IACF,CAAC,CAAA;AAED,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,IAAA;AACZ,MAAA,QAAA,CAAS,MAAA,EAAO;AAChB,MAAA,IAAI,UAAU,OAAA,EAAS;AACrB,QAAA,SAAA,CAAU,QAAQ,OAAA,EAAQ;AAC1B,QAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AAAA,MACtB;AACA,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,QAAA,CAAS,OAAA,GAAU,IAAA;AAAA,MACrB;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG;AAAA,IACD,UAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA,IACA,IAAA;AAAA,IACA,wBAAA;AAAA,IACA,aAAA;AAAA,IACA,cAAA;AAAA,IACA,gBAAA;AAAA,IACA,aAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACD,CAAA;AAGD,EAAA,OAAO,wBAAA,GAA2B,IAAA,mBAAOD,GAAAA,CAAC,iBAAA,EAAA,EAAkB,CAAA;AAC9D;AChFO,SAAS,WAAA,CAAY;AAAA,EAC1B,UAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA;AAAA,EACA,cAAA;AAAA,EACA,wBAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAA,EAAqB;AACnB,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,cAAA,CAAe;AAAA,IAChC,UAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA,IACA,IAAA;AAAA,IACA,OAAA;AAAA,IACA,cAAA;AAAA,IAEA,QAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAA;AAAA,IACA,UAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAAN,UAAU,MAAM;AACd,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,OAAA,GAAU,MAAA;AAAA,IACrB;AACA,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,QAAA,CAAS,OAAA,GAAU,IAAA;AAAA,MACrB;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,QAAA,EAAU,MAAM,CAAC,CAAA;AAErB,EAAA,OAAO,wBAAA,GAA2B,IAAA,mBAAOM,GAAAA,CAAC,iBAAA,EAAA,EAAkB,CAAA;AAC9D","file":"index.js","sourcesContent":["import { useRef, useCallback, useLayoutEffect, useEffect } from \"react\";\n\nconst useIsomorphicLayoutEffect =\n typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\nexport function useStableCallback<\n T extends ((...args: any[]) => any) | undefined,\n>(callback: T): T {\n const callbackRef = useRef(callback);\n\n useIsomorphicLayoutEffect(() => {\n callbackRef.current = callback;\n });\n\n // Always create the stable wrapper (hooks can't be conditional),\n // but return undefined when no callback is provided to preserve\n // truthiness semantics for consumers that branch on it.\n const stable = useCallback(\n ((...args: any[]) => callbackRef.current?.(...args)) as NonNullable<T>,\n []\n );\n\n return callback ? stable : callback;\n}\n","import { useState, useEffect } from \"react\";\nimport { fetchEmbedConfig, type ThemeConfig } from \"@perspective-ai/sdk\";\n\n/**\n * Fetch embed config (theme, appearance, launcher) from the API.\n * Returns undefined while loading, then the resolved config.\n * Results are cached and deduplicated across hooks sharing a researchId.\n */\nexport function useEmbedConfig(\n researchId: string,\n host?: string\n): ThemeConfig | undefined {\n const [state, setState] = useState<\n { researchId: string; host?: string; config: ThemeConfig } | undefined\n >();\n\n useEffect(() => {\n let cancelled = false;\n fetchEmbedConfig(researchId, host).then((result) => {\n if (!cancelled) setState({ researchId, host, config: result });\n });\n return () => {\n cancelled = true;\n };\n }, [researchId, host]);\n\n // Return undefined if config is for different researchId/host (stale)\n return state?.researchId === researchId && state.host === host\n ? state.config\n : undefined;\n}\n","import { useCallback, useState, useEffect, useRef } from \"react\";\nimport {\n getPersistedOpenState,\n openPopup,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./useStableCallback\";\nimport { useEmbedConfig } from \"./useEmbedConfig\";\n\n/** Options for usePopup hook */\nexport interface UsePopupOptions extends Omit<EmbedConfig, \"type\"> {\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n}\n\n/** Return type for usePopup hook */\nexport interface UsePopupReturn {\n /** Open the popup */\n open: () => void;\n /** Close the popup */\n close: () => void;\n /** Toggle the popup */\n toggle: () => void;\n /** Whether the popup is currently open */\n isOpen: boolean;\n /** The underlying SDK handle (null when closed) */\n handle: EmbedHandle | null;\n}\n\n/**\n * Headless hook for programmatic popup control.\n * Use this when you need custom trigger elements or programmatic control.\n *\n * @example\n * ```tsx\n * // Basic usage with custom trigger\n * const { open, isOpen } = usePopup({ researchId: \"abc\" });\n * <MyCustomButton onClick={open}>Open Survey</MyCustomButton>\n *\n * // Controlled mode\n * const [isOpen, setIsOpen] = useState(false);\n * const popup = usePopup({\n * researchId: \"abc\",\n * open: isOpen,\n * onOpenChange: setIsOpen\n * });\n * ```\n */\nexport function usePopup(options: UsePopupOptions): UsePopupReturn {\n const {\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n open: controlledOpen,\n onOpenChange,\n } = options;\n\n const [handle, setHandle] = useState<EmbedHandle | null>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const handleRef = useRef<EmbedHandle | null>(null);\n const embedConfig = useEmbedConfig(researchId, host);\n const embedConfigRef = useRef(embedConfig);\n embedConfigRef.current = embedConfig;\n\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnError = useStableCallback(onError);\n\n const setOpen = useCallback(\n (value: boolean) => {\n if (isControlled) {\n onOpenChange?.(value);\n } else {\n setInternalOpen(value);\n }\n },\n [isControlled, onOpenChange]\n );\n\n const handleClose = useCallback(() => {\n handleRef.current = null;\n setHandle(null);\n setOpen(false);\n onClose?.();\n }, [setOpen, onClose]);\n\n const stableOnClose = useStableCallback(handleClose);\n\n const createPopup = useCallback(() => {\n if (handleRef.current) return handleRef.current;\n\n const newHandle = openPopup({\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n _apiConfig: embedConfigRef.current,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = newHandle;\n setHandle(newHandle);\n return newHandle;\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n const destroyPopup = useCallback((mode: \"destroy\" | \"unmount\") => {\n if (handleRef.current) {\n if (mode === \"destroy\") {\n handleRef.current.destroy();\n } else {\n handleRef.current.unmount();\n }\n handleRef.current = null;\n setHandle(null);\n }\n }, []);\n\n const openFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(true);\n } else {\n createPopup();\n setInternalOpen(true);\n }\n }, [isControlled, onOpenChange, createPopup]);\n\n const closeFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(false);\n } else {\n destroyPopup(\"destroy\");\n setInternalOpen(false);\n }\n }, [isControlled, onOpenChange, destroyPopup]);\n\n const toggleFn = useCallback(() => {\n if (isOpen) {\n closeFn();\n } else {\n openFn();\n }\n }, [isOpen, openFn, closeFn]);\n\n useEffect(() => {\n if (!isControlled) return;\n\n if (controlledOpen && !handleRef.current) {\n createPopup();\n } else if (!controlledOpen && handleRef.current) {\n destroyPopup(\"destroy\");\n }\n }, [controlledOpen, isControlled, createPopup, destroyPopup]);\n\n useEffect(() => {\n if (isControlled || handleRef.current) return;\n\n if (getPersistedOpenState({ researchId, type: \"popup\", host }) !== true) {\n return;\n }\n\n createPopup();\n setInternalOpen(true);\n }, [createPopup, host, isControlled, researchId]);\n\n useEffect(() => {\n return () => {\n if (handleRef.current) {\n handleRef.current.unmount();\n handleRef.current = null;\n }\n };\n }, []);\n\n return {\n open: openFn,\n close: closeFn,\n toggle: toggleFn,\n isOpen,\n handle,\n };\n}\n","import { useCallback, useState, useEffect, useRef } from \"react\";\nimport {\n getPersistedOpenState,\n openSlider,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./useStableCallback\";\nimport { useEmbedConfig } from \"./useEmbedConfig\";\n\n/** Options for useSlider hook */\nexport interface UseSliderOptions extends Omit<EmbedConfig, \"type\"> {\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n}\n\n/** Return type for useSlider hook */\nexport interface UseSliderReturn {\n /** Open the slider */\n open: () => void;\n /** Close the slider */\n close: () => void;\n /** Toggle the slider */\n toggle: () => void;\n /** Whether the slider is currently open */\n isOpen: boolean;\n /** The underlying SDK handle (null when closed) */\n handle: EmbedHandle | null;\n}\n\n/**\n * Headless hook for programmatic slider control.\n * Use this when you need custom trigger elements or programmatic control.\n *\n * @example\n * ```tsx\n * const { open, isOpen } = useSlider({ researchId: \"abc\" });\n * <MyCustomButton onClick={open}>Give Feedback</MyCustomButton>\n * ```\n */\nexport function useSlider(options: UseSliderOptions): UseSliderReturn {\n const {\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n sliderMode,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n open: controlledOpen,\n onOpenChange,\n } = options;\n\n const [handle, setHandle] = useState<EmbedHandle | null>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const handleRef = useRef<EmbedHandle | null>(null);\n const embedConfig = useEmbedConfig(researchId, host);\n const embedConfigRef = useRef(embedConfig);\n embedConfigRef.current = embedConfig;\n\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnError = useStableCallback(onError);\n\n const setOpen = useCallback(\n (value: boolean) => {\n if (isControlled) {\n onOpenChange?.(value);\n } else {\n setInternalOpen(value);\n }\n },\n [isControlled, onOpenChange]\n );\n\n const handleClose = useCallback(() => {\n handleRef.current = null;\n setHandle(null);\n setOpen(false);\n onClose?.();\n }, [setOpen, onClose]);\n\n const stableOnClose = useStableCallback(handleClose);\n\n const createSlider = useCallback(() => {\n if (handleRef.current) return handleRef.current;\n\n const newHandle = openSlider({\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n sliderMode,\n _apiConfig: embedConfigRef.current,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = newHandle;\n setHandle(newHandle);\n return newHandle;\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n sliderMode,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n const destroySlider = useCallback((mode: \"destroy\" | \"unmount\") => {\n if (handleRef.current) {\n if (mode === \"destroy\") {\n handleRef.current.destroy();\n } else {\n handleRef.current.unmount();\n }\n handleRef.current = null;\n setHandle(null);\n }\n }, []);\n\n const openFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(true);\n } else {\n createSlider();\n setInternalOpen(true);\n }\n }, [isControlled, onOpenChange, createSlider]);\n\n const closeFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(false);\n } else {\n destroySlider(\"destroy\");\n setInternalOpen(false);\n }\n }, [isControlled, onOpenChange, destroySlider]);\n\n const toggleFn = useCallback(() => {\n if (isOpen) {\n closeFn();\n } else {\n openFn();\n }\n }, [isOpen, openFn, closeFn]);\n\n useEffect(() => {\n if (!isControlled) return;\n\n if (controlledOpen && !handleRef.current) {\n createSlider();\n } else if (!controlledOpen && handleRef.current) {\n destroySlider(\"destroy\");\n }\n }, [controlledOpen, isControlled, createSlider, destroySlider]);\n\n useEffect(() => {\n if (isControlled || handleRef.current) return;\n\n if (getPersistedOpenState({ researchId, type: \"slider\", host }) !== true) {\n return;\n }\n\n createSlider();\n setInternalOpen(true);\n }, [createSlider, host, isControlled, researchId]);\n\n useEffect(() => {\n return () => {\n if (handleRef.current) {\n handleRef.current.unmount();\n handleRef.current = null;\n }\n };\n }, []);\n\n return {\n open: openFn,\n close: closeFn,\n toggle: toggleFn,\n isOpen,\n handle,\n };\n}\n","import {\n useCallback,\n useState,\n useEffect,\n useRef,\n useMemo,\n isValidElement,\n} from \"react\";\nimport type { ReactNode } from \"react\";\nimport {\n createFloatBubble,\n type EmbedConfig,\n type FloatHandle,\n type LauncherConfig,\n} from \"@perspective-ai/sdk\";\nimport { renderToStaticMarkup } from \"react-dom/server\";\nimport { useStableCallback } from \"./useStableCallback\";\nimport { useEmbedConfig } from \"./useEmbedConfig\";\n\n/** Launcher config with React support — icon accepts ReactNode in addition to SDK types */\nexport interface LauncherConfigReact extends Omit<LauncherConfig, \"icon\"> {\n icon?: LauncherConfig[\"icon\"] | ReactNode;\n}\n\n/** Options for useFloatBubble hook */\nexport interface UseFloatBubbleOptions extends Omit<\n EmbedConfig,\n \"type\" | \"launcher\"\n> {\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Customize the floating launcher button appearance */\n launcher?: LauncherConfigReact;\n}\n\n/** Return type for useFloatBubble hook */\nexport interface UseFloatBubbleReturn {\n /** Open the float bubble window */\n open: () => void;\n /** Close the float bubble window */\n close: () => void;\n /** Toggle the float bubble window */\n toggle: () => void;\n /** Unmount the float bubble entirely */\n unmount: () => void;\n /** Whether the float bubble window is currently open */\n isOpen: boolean;\n /** The underlying SDK handle (null until mounted) */\n handle: FloatHandle | null;\n}\n\n/**\n * Headless hook for float bubble lifecycle management.\n * Creates a floating bubble button that expands into a chat window.\n * The bubble mounts on component mount and unmounts on component unmount.\n *\n * @example\n * ```tsx\n * // Basic usage - bubble mounts on component mount\n * useFloatBubble({ researchId: \"abc\" });\n *\n * // With programmatic control\n * const { open, close, isOpen } = useFloatBubble({ researchId: \"abc\" });\n * <button onClick={open}>Open Chat</button>\n * ```\n */\nexport function useFloatBubble(\n options: UseFloatBubbleOptions\n): UseFloatBubbleReturn {\n const {\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n launcher,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n open: controlledOpen,\n onOpenChange,\n } = options;\n\n const [handle, setHandle] = useState<FloatHandle | null>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const handleRef = useRef<FloatHandle | null>(null);\n const embedConfig = useEmbedConfig(researchId, host);\n\n const isControlled = controlledOpen !== undefined;\n\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnError = useStableCallback(onError);\n\n const handleClose = useCallback(() => {\n setInternalOpen(false);\n if (isControlled) {\n onOpenChange?.(false);\n }\n onClose?.();\n }, [isControlled, onOpenChange, onClose]);\n\n const stableOnClose = useStableCallback(handleClose);\n\n // Resolve ReactNode icons to SVG strings for the core SDK\n const resolvedLauncher = useMemo((): EmbedConfig[\"launcher\"] | undefined => {\n if (!launcher) return undefined;\n const { icon, ...rest } = launcher;\n // Filter out falsy ReactNode values (e.g., `condition && <Icon />` producing `false`)\n if (\n icon === false ||\n icon === null ||\n icon === undefined ||\n icon === 0 ||\n icon === \"\"\n ) {\n return Object.keys(rest).length > 0 ? rest : undefined;\n }\n if (isValidElement(icon)) {\n return { ...rest, icon: { svg: renderToStaticMarkup(icon) } };\n }\n // Only pass through valid LauncherIcon values to core SDK\n if (icon === \"default\" || icon === \"avatar\") {\n return { ...rest, icon: icon as \"default\" | \"avatar\" };\n }\n if (typeof icon === \"object\" && (\"url\" in icon || \"svg\" in icon)) {\n return { ...rest, icon: icon as { url: string } | { svg: string } };\n }\n // Unrecognized icon value (truthy primitives, arrays, etc.) — ignore it\n return Object.keys(rest).length > 0 ? rest : undefined;\n }, [launcher]);\n\n useEffect(() => {\n const newHandle = createFloatBubble({\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n launcher: resolvedLauncher,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = newHandle;\n setHandle(newHandle);\n\n return () => {\n if (handleRef.current === newHandle) {\n newHandle.unmount();\n handleRef.current = null;\n setHandle(null);\n }\n };\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n resolvedLauncher,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n // Update float with API config when it arrives (appearance, launcher, channels, welcome)\n useEffect(() => {\n if (!embedConfig || !handleRef.current) return;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (handleRef.current.update as any)({\n channel: embedConfig.channel ?? embedConfig.allowedChannels ?? undefined,\n welcomeMessage: embedConfig.welcomeMessage,\n _apiConfig: embedConfig,\n });\n }, [embedConfig]);\n\n useEffect(() => {\n if (!isControlled || !handle) return;\n\n if (controlledOpen && !handle.isOpen) {\n handle.open();\n } else if (!controlledOpen && handle.isOpen) {\n handle.close();\n }\n }, [controlledOpen, isControlled, handle]);\n\n const openFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(true);\n } else {\n handleRef.current?.open();\n setInternalOpen(true);\n }\n }, [isControlled, onOpenChange]);\n\n const closeFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(false);\n } else {\n handleRef.current?.close();\n setInternalOpen(false);\n }\n }, [isControlled, onOpenChange]);\n\n const toggleFn = useCallback(() => {\n const currentlyOpen = handleRef.current?.isOpen ?? internalOpen;\n if (currentlyOpen) {\n closeFn();\n } else {\n openFn();\n }\n }, [internalOpen, openFn, closeFn]);\n\n const unmountFn = useCallback(() => {\n handleRef.current?.unmount();\n handleRef.current = null;\n setHandle(null);\n setInternalOpen(false);\n }, []);\n\n const isOpen = isControlled\n ? controlledOpen\n : (handle?.isOpen ?? internalOpen);\n\n return {\n open: openFn,\n close: closeFn,\n toggle: toggleFn,\n unmount: unmountFn,\n isOpen,\n handle,\n };\n}\n","import { useEffect, useRef, useState, useCallback } from \"react\";\nimport {\n openPopup,\n setupTrigger,\n shouldShow,\n markShown,\n} from \"@perspective-ai/sdk\";\nimport type { EmbedConfig, TriggerConfig, ShowOnce } from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./useStableCallback\";\nimport { useEmbedConfig } from \"./useEmbedConfig\";\n\nexport interface UseAutoOpenOptions extends Omit<\n EmbedConfig,\n \"type\" | \"autoOpen\"\n> {\n trigger: TriggerConfig;\n showOnce?: ShowOnce; // default: \"session\"\n}\n\nexport interface UseAutoOpenReturn {\n /** Cancel the pending trigger */\n cancel: () => void;\n /** Whether the trigger has fired */\n triggered: boolean;\n}\n\nexport function useAutoOpen(options: UseAutoOpenOptions): UseAutoOpenReturn {\n const { trigger, showOnce = \"session\", researchId, ...embedConfig } = options;\n const cleanupRef = useRef<(() => void) | null>(null);\n const [triggered, setTriggered] = useState(false);\n const triggerDelay = trigger.type === \"timeout\" ? trigger.delay : undefined;\n const apiConfig = useEmbedConfig(researchId, embedConfig.host);\n const apiConfigRef = useRef(apiConfig);\n apiConfigRef.current = apiConfig;\n\n // useStableCallback so the trigger always calls with latest config\n const stableOnTrigger = useStableCallback(() => {\n markShown(researchId, showOnce);\n openPopup({\n researchId,\n ...embedConfig,\n _apiConfig: apiConfigRef.current,\n });\n });\n\n useEffect(() => {\n if (!shouldShow(researchId, showOnce)) return;\n\n cleanupRef.current = setupTrigger(trigger, () => {\n setTriggered((prev) => {\n if (prev) return prev; // already fired\n stableOnTrigger();\n return true;\n });\n });\n\n return () => {\n cleanupRef.current?.();\n cleanupRef.current = null;\n };\n // Primitive deps only — avoids re-triggering on object identity changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [researchId, trigger.type, triggerDelay, showOnce]);\n\n const cancel = useCallback(() => {\n cleanupRef.current?.();\n cleanupRef.current = null;\n }, []);\n\n return { cancel, triggered };\n}\n","import { useState, useEffect } from \"react\";\n\ntype Theme = \"light\" | \"dark\";\ntype ThemeInput = \"light\" | \"dark\" | \"system\";\n\n/**\n * Hook to resolve theme based on override and system preference.\n * Listens for system preference changes when theme is \"system\".\n */\nexport function useThemeSync(theme: ThemeInput = \"system\"): Theme {\n // Always start with a deterministic value for SSR hydration safety.\n // The actual system preference is synced in useEffect.\n const [resolved, setResolved] = useState<Theme>(\n theme !== \"system\" ? theme : \"light\"\n );\n\n useEffect(() => {\n if (theme !== \"system\") {\n setResolved(theme);\n return;\n }\n\n const mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n\n // Set initial value\n setResolved(mq.matches ? \"dark\" : \"light\");\n\n const handler = (e: MediaQueryListEvent) =>\n setResolved(e.matches ? \"dark\" : \"light\");\n\n mq.addEventListener(\"change\", handler);\n return () => mq.removeEventListener(\"change\", handler);\n }, [theme]);\n\n return resolved;\n}\n","import { SDK_VERSION } from \"@perspective-ai/sdk/constants\";\n\nconst PERSPECTIVE_URL = \"https://getperspective.ai\";\n\nexport interface DiscoveryMetadataProps {\n /** Override the SDK version in the structured data */\n version?: string;\n}\n\n/**\n * Server-side React component that renders JSON-LD structured data\n * for AEO (Answer Engine Optimization).\n *\n * Place this in your layout or page to ensure AI crawlers that don't\n * execute JavaScript can still identify Perspective AI on your site.\n *\n * The client SDK's `injectJsonLd()` checks for the\n * `[data-perspective-jsonld]` attribute to avoid duplicates.\n *\n * @example\n * // In a Next.js layout or page (server component)\n * import { DiscoveryMetadata } from '@perspective-ai/sdk-react';\n *\n * export default function Layout({ children }) {\n * return (\n * <html>\n * <head>\n * <DiscoveryMetadata />\n * </head>\n * <body>{children}</body>\n * </html>\n * );\n * }\n */\nexport function DiscoveryMetadata({ version }: DiscoveryMetadataProps) {\n const jsonLd = {\n \"@context\": \"https://schema.org\",\n \"@graph\": [\n {\n \"@type\": \"SoftwareApplication\",\n \"@id\": `${PERSPECTIVE_URL}/#widget`,\n name: \"Perspective AI\",\n description:\n \"Rigid forms cause drop-off, weaken qualification, and strip away context. Perspective uses adaptive AI to turn forms into conversations that capture structured data and trigger automation.\",\n url: PERSPECTIVE_URL,\n applicationCategory: \"BusinessApplication\",\n softwareVersion: version ?? SDK_VERSION,\n provider: { \"@id\": `${PERSPECTIVE_URL}/#organization` },\n aggregateRating: {\n \"@type\": \"AggregateRating\",\n ratingValue: \"5\",\n bestRating: \"5\",\n worstRating: \"1\",\n ratingCount: 7,\n reviewCount: 7,\n },\n },\n {\n \"@type\": \"Organization\",\n \"@id\": `${PERSPECTIVE_URL}/#organization`,\n name: \"Perspective AI\",\n url: PERSPECTIVE_URL,\n },\n ],\n };\n\n return (\n <script\n type=\"application/ld+json\"\n data-perspective-jsonld=\"\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}\n />\n );\n}\n","import {\n useRef,\n useEffect,\n Fragment,\n type HTMLAttributes,\n type RefObject,\n} from \"react\";\nimport { DiscoveryMetadata } from \"./DiscoveryMetadata\";\nimport {\n createWidget,\n perfLog,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./hooks/useStableCallback\";\n\nexport interface WidgetProps\n extends\n Omit<EmbedConfig, \"type\">,\n Omit<HTMLAttributes<HTMLDivElement>, \"onError\" | \"onSubmit\"> {\n /** Ref to access the embed handle for programmatic control */\n embedRef?: RefObject<EmbedHandle | null>;\n}\n\n/**\n * Inline widget embed component.\n * Renders the interview directly in a container.\n */\nexport function Widget({\n researchId,\n params,\n brand,\n theme,\n host,\n frame,\n disableJsonLdAttribution,\n onReady,\n onVisualReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n embedRef,\n className,\n style,\n ...divProps\n}: WidgetProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const handleRef = useRef<EmbedHandle | null>(null);\n\n // Stable callbacks to avoid re-mounting on callback changes\n const stableOnReady = useStableCallback(onReady);\n const stableOnVisualReady = useStableCallback(onVisualReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnClose = useStableCallback(onClose);\n const stableOnError = useStableCallback(onError);\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n perfLog(\"SDK-React\", \"Widget effect mounted\", { researchId });\n\n // No upfront config fetch — the iframe resolves workspace-level\n // appearance overrides server-side. createWidget renders its own\n // skeleton while the iframe loads.\n const handle = createWidget(container, {\n researchId,\n params,\n brand,\n theme,\n host,\n frame,\n disableJsonLdAttribution,\n onReady: stableOnReady,\n onVisualReady: stableOnVisualReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = handle;\n\n if (embedRef) {\n embedRef.current = handle;\n }\n\n return () => {\n if (handleRef.current) {\n handleRef.current.unmount();\n handleRef.current = null;\n }\n if (embedRef) {\n embedRef.current = null;\n }\n };\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n frame,\n disableJsonLdAttribution,\n stableOnReady,\n stableOnVisualReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n embedRef,\n ]);\n\n return (\n <Fragment>\n {!disableJsonLdAttribution && <DiscoveryMetadata />}\n <div\n ref={containerRef}\n className={className}\n style={style}\n data-testid=\"perspective-widget\"\n {...divProps}\n />\n </Fragment>\n );\n}\n","import { useRef, useEffect, type RefObject } from \"react\";\nimport { DiscoveryMetadata } from \"./DiscoveryMetadata\";\nimport {\n createFullpage,\n createLoadingIndicator,\n fetchEmbedConfig,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./hooks/useStableCallback\";\n\nexport interface FullpageProps extends Omit<EmbedConfig, \"type\"> {\n /** Ref to access the embed handle for programmatic control */\n embedRef?: RefObject<EmbedHandle | null>;\n}\n\n/**\n * Full viewport embed component.\n * Takes over the entire screen with the interview.\n */\nexport function Fullpage({\n researchId,\n params,\n brand,\n theme,\n host,\n disableJsonLdAttribution,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n embedRef,\n}: FullpageProps) {\n const handleRef = useRef<EmbedHandle | null>(null);\n\n // Stable callbacks\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnClose = useStableCallback(onClose);\n const stableOnError = useStableCallback(onError);\n\n useEffect(() => {\n // Show skeleton instantly while config fetches in parallel\n const skeleton = createLoadingIndicator({ theme, brand });\n skeleton.style.position = \"fixed\";\n skeleton.style.inset = \"0\";\n skeleton.style.zIndex = \"2147483647\";\n document.body.appendChild(skeleton);\n\n let cancelled = false;\n\n fetchEmbedConfig(researchId, host).then((config) => {\n if (cancelled) return;\n skeleton.remove();\n\n const handle = createFullpage({\n researchId,\n params,\n brand,\n theme,\n host,\n disableJsonLdAttribution,\n _apiConfig: config,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = handle;\n\n if (embedRef) {\n embedRef.current = handle;\n }\n });\n\n return () => {\n cancelled = true;\n skeleton.remove();\n if (handleRef.current) {\n handleRef.current.unmount();\n handleRef.current = null;\n }\n if (embedRef) {\n embedRef.current = null;\n }\n };\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n disableJsonLdAttribution,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n embedRef,\n ]);\n\n // The fullpage overlay is added to document.body via SDK; render attribution for SSR\n return disableJsonLdAttribution ? null : <DiscoveryMetadata />;\n}\n","import { useEffect, type RefObject } from \"react\";\nimport { type EmbedConfig, type FloatHandle } from \"@perspective-ai/sdk\";\nimport { DiscoveryMetadata } from \"./DiscoveryMetadata\";\nimport {\n useFloatBubble,\n type LauncherConfigReact,\n} from \"./hooks/useFloatBubble\";\n\nexport interface FloatBubbleProps extends Omit<\n EmbedConfig,\n \"type\" | \"launcher\"\n> {\n /** Ref to access the handle for programmatic control */\n embedRef?: RefObject<FloatHandle | null>;\n /** Customize the floating launcher button appearance */\n launcher?: LauncherConfigReact;\n}\n\n/**\n * Floating bubble widget that expands into a chat window.\n * This is a convenience wrapper around useFloatBubble hook.\n *\n * @example\n * ```tsx\n * <FloatBubble researchId=\"abc\" onSubmit={handleSubmit} />\n * ```\n */\nexport function FloatBubble({\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n disableJsonLdAttribution,\n launcher,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n embedRef,\n}: FloatBubbleProps) {\n const { handle } = useFloatBubble({\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n disableJsonLdAttribution,\n launcher,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n });\n\n useEffect(() => {\n if (embedRef) {\n embedRef.current = handle;\n }\n return () => {\n if (embedRef) {\n embedRef.current = null;\n }\n };\n }, [embedRef, handle]);\n\n return disableJsonLdAttribution ? null : <DiscoveryMetadata />;\n}\n"]}
1
+ {"version":3,"sources":["../src/hooks/useStableCallback.ts","../src/hooks/useEmbedConfig.ts","../src/hooks/usePopup.ts","../src/hooks/useSlider.ts","../src/hooks/useFloatBubble.ts","../src/hooks/useAutoOpen.ts","../src/hooks/useThemeSync.ts","../src/DiscoveryMetadata.tsx","../src/Widget.tsx","../src/Fullpage.tsx","../src/FloatBubble.tsx"],"names":["useEffect","useState","useRef","useCallback","getPersistedOpenState","openPopup","jsx","fetchEmbedConfig"],"mappings":"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","file":"index.js","sourcesContent":["import { useRef, useCallback, useLayoutEffect, useEffect } from \"react\";\n\nconst useIsomorphicLayoutEffect =\n typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\nexport function useStableCallback<\n T extends ((...args: any[]) => any) | undefined,\n>(callback: T): T {\n const callbackRef = useRef(callback);\n\n useIsomorphicLayoutEffect(() => {\n callbackRef.current = callback;\n });\n\n // Always create the stable wrapper (hooks can't be conditional),\n // but return undefined when no callback is provided to preserve\n // truthiness semantics for consumers that branch on it.\n const stable = useCallback(\n ((...args: any[]) => callbackRef.current?.(...args)) as NonNullable<T>,\n []\n );\n\n return callback ? stable : callback;\n}\n","import { useState, useEffect } from \"react\";\nimport { fetchEmbedConfig, type ThemeConfig } from \"@perspective-ai/sdk\";\n\n/**\n * Fetch embed config (theme, appearance, launcher) from the API.\n * Returns undefined while loading, then the resolved config.\n * Results are cached and deduplicated across hooks sharing a researchId.\n */\nexport function useEmbedConfig(\n researchId: string,\n host?: string\n): ThemeConfig | undefined {\n const [state, setState] = useState<\n { researchId: string; host?: string; config: ThemeConfig } | undefined\n >();\n\n useEffect(() => {\n let cancelled = false;\n fetchEmbedConfig(researchId, host).then((result) => {\n if (!cancelled) setState({ researchId, host, config: result });\n });\n return () => {\n cancelled = true;\n };\n }, [researchId, host]);\n\n // Return undefined if config is for different researchId/host (stale)\n return state?.researchId === researchId && state.host === host\n ? state.config\n : undefined;\n}\n","import { useCallback, useState, useEffect, useRef } from \"react\";\nimport {\n getPersistedOpenState,\n openPopup,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./useStableCallback\";\nimport { useEmbedConfig } from \"./useEmbedConfig\";\n\n/** Options for usePopup hook */\nexport interface UsePopupOptions extends Omit<EmbedConfig, \"type\"> {\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n}\n\n/** Return type for usePopup hook */\nexport interface UsePopupReturn {\n /** Open the popup */\n open: () => void;\n /** Close the popup */\n close: () => void;\n /** Toggle the popup */\n toggle: () => void;\n /** Whether the popup is currently open */\n isOpen: boolean;\n /** The underlying SDK handle (null when closed) */\n handle: EmbedHandle | null;\n}\n\n/**\n * Headless hook for programmatic popup control.\n * Use this when you need custom trigger elements or programmatic control.\n *\n * @example\n * ```tsx\n * // Basic usage with custom trigger\n * const { open, isOpen } = usePopup({ researchId: \"abc\" });\n * <MyCustomButton onClick={open}>Open Survey</MyCustomButton>\n *\n * // Controlled mode\n * const [isOpen, setIsOpen] = useState(false);\n * const popup = usePopup({\n * researchId: \"abc\",\n * open: isOpen,\n * onOpenChange: setIsOpen\n * });\n * ```\n */\nexport function usePopup(options: UsePopupOptions): UsePopupReturn {\n const {\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n open: controlledOpen,\n onOpenChange,\n } = options;\n\n const [handle, setHandle] = useState<EmbedHandle | null>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const handleRef = useRef<EmbedHandle | null>(null);\n const embedConfig = useEmbedConfig(researchId, host);\n const embedConfigRef = useRef(embedConfig);\n embedConfigRef.current = embedConfig;\n\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnError = useStableCallback(onError);\n\n const setOpen = useCallback(\n (value: boolean) => {\n if (isControlled) {\n onOpenChange?.(value);\n } else {\n setInternalOpen(value);\n }\n },\n [isControlled, onOpenChange]\n );\n\n const handleClose = useCallback(() => {\n handleRef.current = null;\n setHandle(null);\n setOpen(false);\n onClose?.();\n }, [setOpen, onClose]);\n\n const stableOnClose = useStableCallback(handleClose);\n\n const createPopup = useCallback(() => {\n if (handleRef.current) return handleRef.current;\n\n const newHandle = openPopup({\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n _apiConfig: embedConfigRef.current,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = newHandle;\n setHandle(newHandle);\n return newHandle;\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n const destroyPopup = useCallback((mode: \"destroy\" | \"unmount\") => {\n if (handleRef.current) {\n if (mode === \"destroy\") {\n handleRef.current.destroy();\n } else {\n handleRef.current.unmount();\n }\n handleRef.current = null;\n setHandle(null);\n }\n }, []);\n\n const openFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(true);\n } else {\n createPopup();\n setInternalOpen(true);\n }\n }, [isControlled, onOpenChange, createPopup]);\n\n const closeFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(false);\n } else {\n destroyPopup(\"destroy\");\n setInternalOpen(false);\n }\n }, [isControlled, onOpenChange, destroyPopup]);\n\n const toggleFn = useCallback(() => {\n if (isOpen) {\n closeFn();\n } else {\n openFn();\n }\n }, [isOpen, openFn, closeFn]);\n\n useEffect(() => {\n if (!isControlled) return;\n\n if (controlledOpen && !handleRef.current) {\n createPopup();\n } else if (!controlledOpen && handleRef.current) {\n destroyPopup(\"destroy\");\n }\n }, [controlledOpen, isControlled, createPopup, destroyPopup]);\n\n useEffect(() => {\n if (isControlled || handleRef.current) return;\n\n if (getPersistedOpenState({ researchId, type: \"popup\", host }) !== true) {\n return;\n }\n\n createPopup();\n setInternalOpen(true);\n }, [createPopup, host, isControlled, researchId]);\n\n useEffect(() => {\n return () => {\n if (handleRef.current) {\n handleRef.current.unmount();\n handleRef.current = null;\n }\n };\n }, []);\n\n return {\n open: openFn,\n close: closeFn,\n toggle: toggleFn,\n isOpen,\n handle,\n };\n}\n","import { useCallback, useState, useEffect, useRef } from \"react\";\nimport {\n getPersistedOpenState,\n openSlider,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./useStableCallback\";\nimport { useEmbedConfig } from \"./useEmbedConfig\";\n\n/** Options for useSlider hook */\nexport interface UseSliderOptions extends Omit<EmbedConfig, \"type\"> {\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n}\n\n/** Return type for useSlider hook */\nexport interface UseSliderReturn {\n /** Open the slider */\n open: () => void;\n /** Close the slider */\n close: () => void;\n /** Toggle the slider */\n toggle: () => void;\n /** Whether the slider is currently open */\n isOpen: boolean;\n /** The underlying SDK handle (null when closed) */\n handle: EmbedHandle | null;\n}\n\n/**\n * Headless hook for programmatic slider control.\n * Use this when you need custom trigger elements or programmatic control.\n *\n * @example\n * ```tsx\n * const { open, isOpen } = useSlider({ researchId: \"abc\" });\n * <MyCustomButton onClick={open}>Give Feedback</MyCustomButton>\n * ```\n */\nexport function useSlider(options: UseSliderOptions): UseSliderReturn {\n const {\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n sliderMode,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n open: controlledOpen,\n onOpenChange,\n } = options;\n\n const [handle, setHandle] = useState<EmbedHandle | null>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const handleRef = useRef<EmbedHandle | null>(null);\n const embedConfig = useEmbedConfig(researchId, host);\n const embedConfigRef = useRef(embedConfig);\n embedConfigRef.current = embedConfig;\n\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnError = useStableCallback(onError);\n\n const setOpen = useCallback(\n (value: boolean) => {\n if (isControlled) {\n onOpenChange?.(value);\n } else {\n setInternalOpen(value);\n }\n },\n [isControlled, onOpenChange]\n );\n\n const handleClose = useCallback(() => {\n handleRef.current = null;\n setHandle(null);\n setOpen(false);\n onClose?.();\n }, [setOpen, onClose]);\n\n const stableOnClose = useStableCallback(handleClose);\n\n const createSlider = useCallback(() => {\n if (handleRef.current) return handleRef.current;\n\n const newHandle = openSlider({\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n sliderMode,\n _apiConfig: embedConfigRef.current,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = newHandle;\n setHandle(newHandle);\n return newHandle;\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n sliderMode,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n const destroySlider = useCallback((mode: \"destroy\" | \"unmount\") => {\n if (handleRef.current) {\n if (mode === \"destroy\") {\n handleRef.current.destroy();\n } else {\n handleRef.current.unmount();\n }\n handleRef.current = null;\n setHandle(null);\n }\n }, []);\n\n const openFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(true);\n } else {\n createSlider();\n setInternalOpen(true);\n }\n }, [isControlled, onOpenChange, createSlider]);\n\n const closeFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(false);\n } else {\n destroySlider(\"destroy\");\n setInternalOpen(false);\n }\n }, [isControlled, onOpenChange, destroySlider]);\n\n const toggleFn = useCallback(() => {\n if (isOpen) {\n closeFn();\n } else {\n openFn();\n }\n }, [isOpen, openFn, closeFn]);\n\n useEffect(() => {\n if (!isControlled) return;\n\n if (controlledOpen && !handleRef.current) {\n createSlider();\n } else if (!controlledOpen && handleRef.current) {\n destroySlider(\"destroy\");\n }\n }, [controlledOpen, isControlled, createSlider, destroySlider]);\n\n useEffect(() => {\n if (isControlled || handleRef.current) return;\n\n if (getPersistedOpenState({ researchId, type: \"slider\", host }) !== true) {\n return;\n }\n\n createSlider();\n setInternalOpen(true);\n }, [createSlider, host, isControlled, researchId]);\n\n useEffect(() => {\n return () => {\n if (handleRef.current) {\n handleRef.current.unmount();\n handleRef.current = null;\n }\n };\n }, []);\n\n return {\n open: openFn,\n close: closeFn,\n toggle: toggleFn,\n isOpen,\n handle,\n };\n}\n","import {\n useCallback,\n useState,\n useEffect,\n useRef,\n useMemo,\n isValidElement,\n} from \"react\";\nimport type { ReactNode } from \"react\";\nimport {\n createFloatBubble,\n type EmbedConfig,\n type FloatHandle,\n type LauncherConfig,\n} from \"@perspective-ai/sdk\";\nimport { renderToStaticMarkup } from \"react-dom/server\";\nimport { useStableCallback } from \"./useStableCallback\";\nimport { useEmbedConfig } from \"./useEmbedConfig\";\n\n/** Launcher config with React support — icon accepts ReactNode in addition to SDK types */\nexport interface LauncherConfigReact extends Omit<LauncherConfig, \"icon\"> {\n icon?: LauncherConfig[\"icon\"] | ReactNode;\n}\n\n/** Options for useFloatBubble hook */\nexport interface UseFloatBubbleOptions extends Omit<\n EmbedConfig,\n \"type\" | \"launcher\"\n> {\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Customize the floating launcher button appearance */\n launcher?: LauncherConfigReact;\n}\n\n/** Return type for useFloatBubble hook */\nexport interface UseFloatBubbleReturn {\n /** Open the float bubble window */\n open: () => void;\n /** Close the float bubble window */\n close: () => void;\n /** Toggle the float bubble window */\n toggle: () => void;\n /** Unmount the float bubble entirely */\n unmount: () => void;\n /** Whether the float bubble window is currently open */\n isOpen: boolean;\n /** The underlying SDK handle (null until mounted) */\n handle: FloatHandle | null;\n}\n\n/**\n * Headless hook for float bubble lifecycle management.\n * Creates a floating bubble button that expands into a chat window.\n * The bubble mounts on component mount and unmounts on component unmount.\n *\n * @example\n * ```tsx\n * // Basic usage - bubble mounts on component mount\n * useFloatBubble({ researchId: \"abc\" });\n *\n * // With programmatic control\n * const { open, close, isOpen } = useFloatBubble({ researchId: \"abc\" });\n * <button onClick={open}>Open Chat</button>\n * ```\n */\nexport function useFloatBubble(\n options: UseFloatBubbleOptions\n): UseFloatBubbleReturn {\n const {\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n teaser,\n launcher,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n open: controlledOpen,\n onOpenChange,\n } = options;\n\n const [handle, setHandle] = useState<FloatHandle | null>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const handleRef = useRef<FloatHandle | null>(null);\n const embedConfig = useEmbedConfig(researchId, host);\n\n const isControlled = controlledOpen !== undefined;\n\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnError = useStableCallback(onError);\n\n const handleClose = useCallback(() => {\n setInternalOpen(false);\n if (isControlled) {\n onOpenChange?.(false);\n }\n onClose?.();\n }, [isControlled, onOpenChange, onClose]);\n\n const stableOnClose = useStableCallback(handleClose);\n\n // Stabilize the teaser object on its primitive fields so an inline object\n // literal prop doesn't remount the whole bubble on every parent render\n const teaserEnabled = teaser?.enabled;\n const teaserDelay = teaser?.delay;\n const teaserSound = teaser?.sound;\n const hasTeaser = teaser !== undefined;\n const stableTeaser = useMemo(\n (): EmbedConfig[\"teaser\"] =>\n hasTeaser\n ? { enabled: teaserEnabled, delay: teaserDelay, sound: teaserSound }\n : undefined,\n [hasTeaser, teaserEnabled, teaserDelay, teaserSound]\n );\n\n // Resolve ReactNode icons to SVG strings for the core SDK\n const resolvedLauncher = useMemo((): EmbedConfig[\"launcher\"] | undefined => {\n if (!launcher) return undefined;\n const { icon, ...rest } = launcher;\n // Filter out falsy ReactNode values (e.g., `condition && <Icon />` producing `false`)\n if (\n icon === false ||\n icon === null ||\n icon === undefined ||\n icon === 0 ||\n icon === \"\"\n ) {\n return Object.keys(rest).length > 0 ? rest : undefined;\n }\n if (isValidElement(icon)) {\n return { ...rest, icon: { svg: renderToStaticMarkup(icon) } };\n }\n // Only pass through valid LauncherIcon values to core SDK\n if (icon === \"default\" || icon === \"avatar\") {\n return { ...rest, icon: icon as \"default\" | \"avatar\" };\n }\n if (typeof icon === \"object\" && (\"url\" in icon || \"svg\" in icon)) {\n return { ...rest, icon: icon as { url: string } | { svg: string } };\n }\n // Unrecognized icon value (truthy primitives, arrays, etc.) — ignore it\n return Object.keys(rest).length > 0 ? rest : undefined;\n }, [launcher]);\n\n useEffect(() => {\n const newHandle = createFloatBubble({\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n teaser: stableTeaser,\n launcher: resolvedLauncher,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = newHandle;\n setHandle(newHandle);\n\n return () => {\n if (handleRef.current === newHandle) {\n newHandle.unmount();\n handleRef.current = null;\n setHandle(null);\n }\n };\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n stableTeaser,\n resolvedLauncher,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n // Update float with API config when it arrives (appearance, launcher, channels, welcome)\n useEffect(() => {\n if (!embedConfig || !handleRef.current) return;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (handleRef.current.update as any)({\n channel: embedConfig.channel ?? embedConfig.allowedChannels ?? undefined,\n welcomeMessage: embedConfig.welcomeMessage,\n _apiConfig: embedConfig,\n });\n }, [embedConfig]);\n\n useEffect(() => {\n if (!isControlled || !handle) return;\n\n if (controlledOpen && !handle.isOpen) {\n handle.open();\n } else if (!controlledOpen && handle.isOpen) {\n handle.close();\n }\n }, [controlledOpen, isControlled, handle]);\n\n const openFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(true);\n } else {\n handleRef.current?.open();\n setInternalOpen(true);\n }\n }, [isControlled, onOpenChange]);\n\n const closeFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(false);\n } else {\n handleRef.current?.close();\n setInternalOpen(false);\n }\n }, [isControlled, onOpenChange]);\n\n const toggleFn = useCallback(() => {\n const currentlyOpen = handleRef.current?.isOpen ?? internalOpen;\n if (currentlyOpen) {\n closeFn();\n } else {\n openFn();\n }\n }, [internalOpen, openFn, closeFn]);\n\n const unmountFn = useCallback(() => {\n handleRef.current?.unmount();\n handleRef.current = null;\n setHandle(null);\n setInternalOpen(false);\n }, []);\n\n const isOpen = isControlled\n ? controlledOpen\n : (handle?.isOpen ?? internalOpen);\n\n return {\n open: openFn,\n close: closeFn,\n toggle: toggleFn,\n unmount: unmountFn,\n isOpen,\n handle,\n };\n}\n","import { useEffect, useRef, useState, useCallback } from \"react\";\nimport {\n openPopup,\n setupTrigger,\n shouldShow,\n markShown,\n} from \"@perspective-ai/sdk\";\nimport type { EmbedConfig, TriggerConfig, ShowOnce } from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./useStableCallback\";\nimport { useEmbedConfig } from \"./useEmbedConfig\";\n\nexport interface UseAutoOpenOptions extends Omit<\n EmbedConfig,\n \"type\" | \"autoOpen\"\n> {\n trigger: TriggerConfig;\n showOnce?: ShowOnce; // default: \"session\"\n}\n\nexport interface UseAutoOpenReturn {\n /** Cancel the pending trigger */\n cancel: () => void;\n /** Whether the trigger has fired */\n triggered: boolean;\n}\n\nexport function useAutoOpen(options: UseAutoOpenOptions): UseAutoOpenReturn {\n const { trigger, showOnce = \"session\", researchId, ...embedConfig } = options;\n const cleanupRef = useRef<(() => void) | null>(null);\n const [triggered, setTriggered] = useState(false);\n const triggerDelay = trigger.type === \"timeout\" ? trigger.delay : undefined;\n const apiConfig = useEmbedConfig(researchId, embedConfig.host);\n const apiConfigRef = useRef(apiConfig);\n apiConfigRef.current = apiConfig;\n\n // useStableCallback so the trigger always calls with latest config\n const stableOnTrigger = useStableCallback(() => {\n markShown(researchId, showOnce);\n openPopup({\n researchId,\n ...embedConfig,\n _apiConfig: apiConfigRef.current,\n });\n });\n\n useEffect(() => {\n if (!shouldShow(researchId, showOnce)) return;\n\n cleanupRef.current = setupTrigger(trigger, () => {\n setTriggered((prev) => {\n if (prev) return prev; // already fired\n stableOnTrigger();\n return true;\n });\n });\n\n return () => {\n cleanupRef.current?.();\n cleanupRef.current = null;\n };\n // Primitive deps only — avoids re-triggering on object identity changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [researchId, trigger.type, triggerDelay, showOnce]);\n\n const cancel = useCallback(() => {\n cleanupRef.current?.();\n cleanupRef.current = null;\n }, []);\n\n return { cancel, triggered };\n}\n","import { useState, useEffect } from \"react\";\n\ntype Theme = \"light\" | \"dark\";\ntype ThemeInput = \"light\" | \"dark\" | \"system\";\n\n/**\n * Hook to resolve theme based on override and system preference.\n * Listens for system preference changes when theme is \"system\".\n */\nexport function useThemeSync(theme: ThemeInput = \"system\"): Theme {\n // Always start with a deterministic value for SSR hydration safety.\n // The actual system preference is synced in useEffect.\n const [resolved, setResolved] = useState<Theme>(\n theme !== \"system\" ? theme : \"light\"\n );\n\n useEffect(() => {\n if (theme !== \"system\") {\n setResolved(theme);\n return;\n }\n\n const mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n\n // Set initial value\n setResolved(mq.matches ? \"dark\" : \"light\");\n\n const handler = (e: MediaQueryListEvent) =>\n setResolved(e.matches ? \"dark\" : \"light\");\n\n mq.addEventListener(\"change\", handler);\n return () => mq.removeEventListener(\"change\", handler);\n }, [theme]);\n\n return resolved;\n}\n","import { SDK_VERSION } from \"@perspective-ai/sdk/constants\";\n\nconst PERSPECTIVE_URL = \"https://getperspective.ai\";\n\nexport interface DiscoveryMetadataProps {\n /** Override the SDK version in the structured data */\n version?: string;\n}\n\n/**\n * Server-side React component that renders JSON-LD structured data\n * for AEO (Answer Engine Optimization).\n *\n * Place this in your layout or page to ensure AI crawlers that don't\n * execute JavaScript can still identify Perspective AI on your site.\n *\n * The client SDK's `injectJsonLd()` checks for the\n * `[data-perspective-jsonld]` attribute to avoid duplicates.\n *\n * @example\n * // In a Next.js layout or page (server component)\n * import { DiscoveryMetadata } from '@perspective-ai/sdk-react';\n *\n * export default function Layout({ children }) {\n * return (\n * <html>\n * <head>\n * <DiscoveryMetadata />\n * </head>\n * <body>{children}</body>\n * </html>\n * );\n * }\n */\nexport function DiscoveryMetadata({ version }: DiscoveryMetadataProps) {\n const jsonLd = {\n \"@context\": \"https://schema.org\",\n \"@graph\": [\n {\n \"@type\": \"SoftwareApplication\",\n \"@id\": `${PERSPECTIVE_URL}/#widget`,\n name: \"Perspective AI\",\n description:\n \"Rigid forms cause drop-off, weaken qualification, and strip away context. Perspective uses adaptive AI to turn forms into conversations that capture structured data and trigger automation.\",\n url: PERSPECTIVE_URL,\n applicationCategory: \"BusinessApplication\",\n softwareVersion: version ?? SDK_VERSION,\n provider: { \"@id\": `${PERSPECTIVE_URL}/#organization` },\n aggregateRating: {\n \"@type\": \"AggregateRating\",\n ratingValue: \"5\",\n bestRating: \"5\",\n worstRating: \"1\",\n ratingCount: 7,\n reviewCount: 7,\n },\n },\n {\n \"@type\": \"Organization\",\n \"@id\": `${PERSPECTIVE_URL}/#organization`,\n name: \"Perspective AI\",\n url: PERSPECTIVE_URL,\n },\n ],\n };\n\n return (\n <script\n type=\"application/ld+json\"\n data-perspective-jsonld=\"\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}\n />\n );\n}\n","import {\n useRef,\n useEffect,\n Fragment,\n type HTMLAttributes,\n type RefObject,\n} from \"react\";\nimport { DiscoveryMetadata } from \"./DiscoveryMetadata\";\nimport {\n createWidget,\n perfLog,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./hooks/useStableCallback\";\n\nexport interface WidgetProps\n extends\n Omit<EmbedConfig, \"type\">,\n Omit<HTMLAttributes<HTMLDivElement>, \"onError\" | \"onSubmit\"> {\n /** Ref to access the embed handle for programmatic control */\n embedRef?: RefObject<EmbedHandle | null>;\n}\n\n/**\n * Inline widget embed component.\n * Renders the interview directly in a container.\n */\nexport function Widget({\n researchId,\n params,\n brand,\n theme,\n host,\n frame,\n disableJsonLdAttribution,\n onReady,\n onVisualReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n embedRef,\n className,\n style,\n ...divProps\n}: WidgetProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const handleRef = useRef<EmbedHandle | null>(null);\n\n // Stable callbacks to avoid re-mounting on callback changes\n const stableOnReady = useStableCallback(onReady);\n const stableOnVisualReady = useStableCallback(onVisualReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnClose = useStableCallback(onClose);\n const stableOnError = useStableCallback(onError);\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n perfLog(\"SDK-React\", \"Widget effect mounted\", { researchId });\n\n // No upfront config fetch — the iframe resolves workspace-level\n // appearance overrides server-side. createWidget renders its own\n // skeleton while the iframe loads.\n const handle = createWidget(container, {\n researchId,\n params,\n brand,\n theme,\n host,\n frame,\n disableJsonLdAttribution,\n onReady: stableOnReady,\n onVisualReady: stableOnVisualReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = handle;\n\n if (embedRef) {\n embedRef.current = handle;\n }\n\n return () => {\n if (handleRef.current) {\n handleRef.current.unmount();\n handleRef.current = null;\n }\n if (embedRef) {\n embedRef.current = null;\n }\n };\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n frame,\n disableJsonLdAttribution,\n stableOnReady,\n stableOnVisualReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n embedRef,\n ]);\n\n return (\n <Fragment>\n {!disableJsonLdAttribution && <DiscoveryMetadata />}\n <div\n ref={containerRef}\n className={className}\n style={style}\n data-testid=\"perspective-widget\"\n {...divProps}\n />\n </Fragment>\n );\n}\n","import { useRef, useEffect, type RefObject } from \"react\";\nimport { DiscoveryMetadata } from \"./DiscoveryMetadata\";\nimport {\n createFullpage,\n createLoadingIndicator,\n fetchEmbedConfig,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./hooks/useStableCallback\";\n\nexport interface FullpageProps extends Omit<EmbedConfig, \"type\"> {\n /** Ref to access the embed handle for programmatic control */\n embedRef?: RefObject<EmbedHandle | null>;\n}\n\n/**\n * Full viewport embed component.\n * Takes over the entire screen with the interview.\n */\nexport function Fullpage({\n researchId,\n params,\n brand,\n theme,\n host,\n disableJsonLdAttribution,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n embedRef,\n}: FullpageProps) {\n const handleRef = useRef<EmbedHandle | null>(null);\n\n // Stable callbacks\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnClose = useStableCallback(onClose);\n const stableOnError = useStableCallback(onError);\n\n useEffect(() => {\n // Show skeleton instantly while config fetches in parallel\n const skeleton = createLoadingIndicator({ theme, brand });\n skeleton.style.position = \"fixed\";\n skeleton.style.inset = \"0\";\n skeleton.style.zIndex = \"2147483647\";\n document.body.appendChild(skeleton);\n\n let cancelled = false;\n\n fetchEmbedConfig(researchId, host).then((config) => {\n if (cancelled) return;\n skeleton.remove();\n\n const handle = createFullpage({\n researchId,\n params,\n brand,\n theme,\n host,\n disableJsonLdAttribution,\n _apiConfig: config,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = handle;\n\n if (embedRef) {\n embedRef.current = handle;\n }\n });\n\n return () => {\n cancelled = true;\n skeleton.remove();\n if (handleRef.current) {\n handleRef.current.unmount();\n handleRef.current = null;\n }\n if (embedRef) {\n embedRef.current = null;\n }\n };\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n disableJsonLdAttribution,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n embedRef,\n ]);\n\n // The fullpage overlay is added to document.body via SDK; render attribution for SSR\n return disableJsonLdAttribution ? null : <DiscoveryMetadata />;\n}\n","import { useEffect, type RefObject } from \"react\";\nimport { type EmbedConfig, type FloatHandle } from \"@perspective-ai/sdk\";\nimport { DiscoveryMetadata } from \"./DiscoveryMetadata\";\nimport {\n useFloatBubble,\n type LauncherConfigReact,\n} from \"./hooks/useFloatBubble\";\n\nexport interface FloatBubbleProps extends Omit<\n EmbedConfig,\n \"type\" | \"launcher\"\n> {\n /** Ref to access the handle for programmatic control */\n embedRef?: RefObject<FloatHandle | null>;\n /** Customize the floating launcher button appearance */\n launcher?: LauncherConfigReact;\n}\n\n/**\n * Floating bubble widget that expands into a chat window.\n * This is a convenience wrapper around useFloatBubble hook.\n *\n * @example\n * ```tsx\n * <FloatBubble researchId=\"abc\" onSubmit={handleSubmit} />\n * ```\n */\nexport function FloatBubble({\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n teaser,\n disableJsonLdAttribution,\n launcher,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n embedRef,\n}: FloatBubbleProps) {\n const { handle } = useFloatBubble({\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n teaser,\n disableJsonLdAttribution,\n launcher,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n });\n\n useEffect(() => {\n if (embedRef) {\n embedRef.current = handle;\n }\n return () => {\n if (embedRef) {\n embedRef.current = null;\n }\n };\n }, [embedRef, handle]);\n\n return disableJsonLdAttribution ? null : <DiscoveryMetadata />;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@perspective-ai/sdk-react",
3
- "version": "1.13.0-pr-64-20260706211041",
3
+ "version": "1.13.0",
4
4
  "description": "React components for Perspective AI embed SDK",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -56,7 +56,7 @@
56
56
  "react-dom": "^18.0.0 || ^19.0.0"
57
57
  },
58
58
  "dependencies": {
59
- "@perspective-ai/sdk": "^1.13.0-pr-64-20260706211041"
59
+ "@perspective-ai/sdk": "^1.13.0"
60
60
  },
61
61
  "devDependencies": {
62
62
  "@testing-library/dom": "^10.4.1",
@@ -33,6 +33,7 @@ export function FloatBubble({
33
33
  host,
34
34
  channel,
35
35
  welcomeMessage,
36
+ teaser,
36
37
  disableJsonLdAttribution,
37
38
  launcher,
38
39
  onReady,
@@ -50,6 +51,7 @@ export function FloatBubble({
50
51
  host,
51
52
  channel,
52
53
  welcomeMessage,
54
+ teaser,
53
55
  disableJsonLdAttribution,
54
56
  launcher,
55
57
  onReady,
@@ -77,6 +77,7 @@ export function useFloatBubble(
77
77
  host,
78
78
  channel,
79
79
  welcomeMessage,
80
+ teaser,
80
81
  launcher,
81
82
  onReady,
82
83
  onSubmit,
@@ -109,6 +110,20 @@ export function useFloatBubble(
109
110
 
110
111
  const stableOnClose = useStableCallback(handleClose);
111
112
 
113
+ // Stabilize the teaser object on its primitive fields so an inline object
114
+ // literal prop doesn't remount the whole bubble on every parent render
115
+ const teaserEnabled = teaser?.enabled;
116
+ const teaserDelay = teaser?.delay;
117
+ const teaserSound = teaser?.sound;
118
+ const hasTeaser = teaser !== undefined;
119
+ const stableTeaser = useMemo(
120
+ (): EmbedConfig["teaser"] =>
121
+ hasTeaser
122
+ ? { enabled: teaserEnabled, delay: teaserDelay, sound: teaserSound }
123
+ : undefined,
124
+ [hasTeaser, teaserEnabled, teaserDelay, teaserSound]
125
+ );
126
+
112
127
  // Resolve ReactNode icons to SVG strings for the core SDK
113
128
  const resolvedLauncher = useMemo((): EmbedConfig["launcher"] | undefined => {
114
129
  if (!launcher) return undefined;
@@ -146,6 +161,7 @@ export function useFloatBubble(
146
161
  host,
147
162
  channel,
148
163
  welcomeMessage,
164
+ teaser: stableTeaser,
149
165
  launcher: resolvedLauncher,
150
166
  onReady: stableOnReady,
151
167
  onSubmit: stableOnSubmit,
@@ -172,6 +188,7 @@ export function useFloatBubble(
172
188
  host,
173
189
  channel,
174
190
  welcomeMessage,
191
+ stableTeaser,
175
192
  resolvedLauncher,
176
193
  stableOnReady,
177
194
  stableOnSubmit,
package/src/index.ts CHANGED
@@ -59,4 +59,5 @@ export type {
59
59
  TriggerConfig,
60
60
  ShowOnce,
61
61
  AutoOpenConfig,
62
+ TeaserConfig,
62
63
  } from "@perspective-ai/sdk";