@guidelytech/react-native 0.15.0 → 0.16.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/dist/index.d.cts CHANGED
@@ -685,13 +685,18 @@ interface UiState {
685
685
  checklists: ChecklistView[];
686
686
  survey: SurveyView | null;
687
687
  resourceCenterOpen: boolean;
688
+ /** An article to show in the resource center (from a help-article link); `seq` changes per request. */
689
+ resourceCenterArticle?: {
690
+ id: string;
691
+ seq: number;
692
+ } | null;
688
693
  theme: Partial<ProjectTheme>;
689
694
  /** Scout is on for this platform; the overlay renders the messenger (see `client.getMessenger()`). */
690
695
  messenger: boolean;
691
696
  }
692
697
 
693
698
  declare const SDK_NAME = "@guidelytech/react-native";
694
- declare const SDK_VERSION = "0.15.0";
699
+ declare const SDK_VERSION = "0.16.0";
695
700
  declare const DEFAULT_API_URL = "https://guidelytech.com";
696
701
  /** Host-platform services the engine needs; the provider supplies React Native implementations. */
697
702
  interface PlatformBridge {
@@ -753,6 +758,8 @@ declare class GuidelyClient {
753
758
  private expanded;
754
759
  private surveyView;
755
760
  private resourceCenterOpen;
761
+ /** The article a help-article link asked the resource center to show (`seq` tells repeats apart). */
762
+ private resourceCenterArticle;
756
763
  private cleanups;
757
764
  private timers;
758
765
  private visibilityWatchers;
@@ -944,6 +951,8 @@ declare class GuidelyClient {
944
951
  pressButton(guideId: string, button: StepButton): void;
945
952
  /** The close (×) button of a step. */
946
953
  closeStep(guideId: string): void;
954
+ /** The video on a step was tapped: records `guide_video_clicked`, then opens the video outside the app. */
955
+ openVideo(guideId: string, url: string): void;
947
956
  /** The dimmed backdrop behind a step was tapped. */
948
957
  backdropPressed(guideId: string): void;
949
958
  /** Hotspot dot tapped: show (or hide) its card. */
@@ -998,6 +1007,13 @@ declare class GuidelyClient {
998
1007
  /** Impressions, completion and dismissal for a guide. */
999
1008
  getGuideState(idOrKey: string): GuideLocalState;
1000
1009
  openResourceCenter(): void;
1010
+ /**
1011
+ * Opens one help article: in Scout's Help tab when the messenger is on, otherwise in the resource
1012
+ * center. Help-article links in guides and articles (`#guidely-article:<id>`) call this.
1013
+ */
1014
+ openArticle(articleId: string): void;
1015
+ /** A resource-center article with its body: from the config, or fetched when the config left it out. */
1016
+ loadArticle(articleId: string): Promise<ResourceCenterArticle | null>;
1001
1017
  closeResourceCenter(): void;
1002
1018
  /** Creates or removes the messenger to match the config (on only when enabled for this platform). */
1003
1019
  private syncMessenger;
package/dist/index.d.ts CHANGED
@@ -685,13 +685,18 @@ interface UiState {
685
685
  checklists: ChecklistView[];
686
686
  survey: SurveyView | null;
687
687
  resourceCenterOpen: boolean;
688
+ /** An article to show in the resource center (from a help-article link); `seq` changes per request. */
689
+ resourceCenterArticle?: {
690
+ id: string;
691
+ seq: number;
692
+ } | null;
688
693
  theme: Partial<ProjectTheme>;
689
694
  /** Scout is on for this platform; the overlay renders the messenger (see `client.getMessenger()`). */
690
695
  messenger: boolean;
691
696
  }
692
697
 
693
698
  declare const SDK_NAME = "@guidelytech/react-native";
694
- declare const SDK_VERSION = "0.15.0";
699
+ declare const SDK_VERSION = "0.16.0";
695
700
  declare const DEFAULT_API_URL = "https://guidelytech.com";
696
701
  /** Host-platform services the engine needs; the provider supplies React Native implementations. */
697
702
  interface PlatformBridge {
@@ -753,6 +758,8 @@ declare class GuidelyClient {
753
758
  private expanded;
754
759
  private surveyView;
755
760
  private resourceCenterOpen;
761
+ /** The article a help-article link asked the resource center to show (`seq` tells repeats apart). */
762
+ private resourceCenterArticle;
756
763
  private cleanups;
757
764
  private timers;
758
765
  private visibilityWatchers;
@@ -944,6 +951,8 @@ declare class GuidelyClient {
944
951
  pressButton(guideId: string, button: StepButton): void;
945
952
  /** The close (×) button of a step. */
946
953
  closeStep(guideId: string): void;
954
+ /** The video on a step was tapped: records `guide_video_clicked`, then opens the video outside the app. */
955
+ openVideo(guideId: string, url: string): void;
947
956
  /** The dimmed backdrop behind a step was tapped. */
948
957
  backdropPressed(guideId: string): void;
949
958
  /** Hotspot dot tapped: show (or hide) its card. */
@@ -998,6 +1007,13 @@ declare class GuidelyClient {
998
1007
  /** Impressions, completion and dismissal for a guide. */
999
1008
  getGuideState(idOrKey: string): GuideLocalState;
1000
1009
  openResourceCenter(): void;
1010
+ /**
1011
+ * Opens one help article: in Scout's Help tab when the messenger is on, otherwise in the resource
1012
+ * center. Help-article links in guides and articles (`#guidely-article:<id>`) call this.
1013
+ */
1014
+ openArticle(articleId: string): void;
1015
+ /** A resource-center article with its body: from the config, or fetched when the config left it out. */
1016
+ loadArticle(articleId: string): Promise<ResourceCenterArticle | null>;
1001
1017
  closeResourceCenter(): void;
1002
1018
  /** Creates or removes the messenger to match the config (on only when enabled for this platform). */
1003
1019
  private syncMessenger;
package/dist/index.js CHANGED
@@ -96,7 +96,7 @@ function FlagsProvider({ children, client: external, payload, ...options }) {
96
96
  return /* @__PURE__ */ jsx(FlagsContext.Provider, { value, children });
97
97
  }
98
98
 
99
- // ../shared/dist/chunk-XJXXVV3C.js
99
+ // ../shared/dist/chunk-7PWYIAJI.js
100
100
  function fnv1a(input) {
101
101
  let h = 2166136261;
102
102
  for (let i = 0; i < input.length; i++) {
@@ -505,6 +505,16 @@ function isSafeMediaUrl(url) {
505
505
  return false;
506
506
  }
507
507
  }
508
+ function videoThumbnailUrl(url) {
509
+ const embed = url ? toEmbedUrl(url) : null;
510
+ if (embed?.provider !== "youtube") return null;
511
+ const id = embed.src.split("/embed/")[1]?.split("?")[0];
512
+ return id ? `https://i.ytimg.com/vi/${id}/hqdefault.jpg` : null;
513
+ }
514
+ function stepVideo(step) {
515
+ if (!step.videoUrl || !isSafeMediaUrl(step.videoUrl)) return null;
516
+ return { url: step.videoUrl, poster: (step.imageUrl && isSafeMediaUrl(step.imageUrl) ? step.imageUrl : null) ?? videoThumbnailUrl(step.videoUrl) };
517
+ }
508
518
  var MAX_COLLECTION_DEPTH = 3;
509
519
  function matchesAudiences(required, member) {
510
520
  if (!required || required.length === 0) return true;
@@ -574,6 +584,13 @@ function unreadAnnouncements(items, lastSeenAt) {
574
584
  if (Number.isNaN(seen)) return items.length;
575
585
  return items.filter((a) => Date.parse(a.publishedAt) > seen).length;
576
586
  }
587
+ var ARTICLE_HREF_PREFIX = "#guidely-article:";
588
+ var ARTICLE_ID = /^[A-Za-z0-9_-]{1,64}$/;
589
+ function articleIdFromHref(href) {
590
+ if (!href || !href.startsWith(ARTICLE_HREF_PREFIX)) return null;
591
+ const id = href.slice(ARTICLE_HREF_PREFIX.length);
592
+ return ARTICLE_ID.test(id) ? id : null;
593
+ }
577
594
  var CAPTURE_SCREENSHOT_MAX_BYTES = 8 * 1024 * 1024;
578
595
  var DEFAULT_LOCALE = "en";
579
596
  function normalizeLocale(input) {
@@ -2900,7 +2917,7 @@ var PersistentStore = class {
2900
2917
 
2901
2918
  // src/core/client.ts
2902
2919
  var SDK_NAME = "@guidelytech/react-native";
2903
- var SDK_VERSION = "0.15.0";
2920
+ var SDK_VERSION = "0.16.0";
2904
2921
  var DEFAULT_API_URL = "https://guidelytech.com";
2905
2922
  var PAGE_SCOPED = /* @__PURE__ */ new Set(["page_load", "url_match", "element_click", "element_visible", "delay"]);
2906
2923
  var CACHED_START_MS = 1500;
@@ -2952,6 +2969,8 @@ var GuidelyClient = class {
2952
2969
  __publicField(this, "expanded", /* @__PURE__ */ new Set());
2953
2970
  __publicField(this, "surveyView", null);
2954
2971
  __publicField(this, "resourceCenterOpen", false);
2972
+ /** The article a help-article link asked the resource center to show (`seq` tells repeats apart). */
2973
+ __publicField(this, "resourceCenterArticle", null);
2955
2974
  __publicField(this, "cleanups", []);
2956
2975
  __publicField(this, "timers", /* @__PURE__ */ new Set());
2957
2976
  __publicField(this, "visibilityWatchers", /* @__PURE__ */ new Map());
@@ -4117,6 +4136,8 @@ var GuidelyClient = class {
4117
4136
  */
4118
4137
  navigate(url) {
4119
4138
  if (!url) return;
4139
+ const articleId = articleIdFromHref(url);
4140
+ if (articleId) return this.openArticle(articleId);
4120
4141
  try {
4121
4142
  if (this.options.onNavigate?.(url) === true) return;
4122
4143
  if (/^[a-z][a-z0-9+.-]*:/i.test(url)) this.bridge.openExternal(url);
@@ -4140,7 +4161,7 @@ var GuidelyClient = class {
4140
4161
  for (const f of [...this.flows.values(), ...this.active ? [this.active] : []]) if (f.view) steps.push({ ...f.view, expanded: this.expanded.has(f.guide.id) });
4141
4162
  const checklists = [];
4142
4163
  this.checklists.forEach((w, id) => checklists.push({ guide: w.guide, progress: this.getChecklistProgress(id), open: w.open }));
4143
- this.ui = { steps, checklists, survey: this.surveyView, resourceCenterOpen: this.resourceCenterOpen, theme: this.themeFor(), messenger: !!this.messenger };
4164
+ this.ui = { steps, checklists, survey: this.surveyView, resourceCenterOpen: this.resourceCenterOpen, resourceCenterArticle: this.resourceCenterArticle, theme: this.themeFor(), messenger: !!this.messenger };
4144
4165
  for (const cb of Array.from(this.uiListeners)) {
4145
4166
  try {
4146
4167
  cb();
@@ -4160,6 +4181,12 @@ var GuidelyClient = class {
4160
4181
  closeStep(guideId) {
4161
4182
  this.flowFor(guideId)?.controller.dismiss();
4162
4183
  }
4184
+ /** The video on a step was tapped: records `guide_video_clicked`, then opens the video outside the app. */
4185
+ openVideo(guideId, url) {
4186
+ const v = this.flowFor(guideId)?.view;
4187
+ if (v) this.enqueue("guide_video_clicked", { guideId: v.guide.id, guideVersion: v.guide.version, stepId: v.step.id, stepIndex: v.index, properties: { videoUrl: url } });
4188
+ this.navigate(url);
4189
+ }
4163
4190
  /** The dimmed backdrop behind a step was tapped. */
4164
4191
  backdropPressed(guideId) {
4165
4192
  const f = this.flowFor(guideId);
@@ -4432,10 +4459,40 @@ var GuidelyClient = class {
4432
4459
  this.emitter.emit("resource-center:open");
4433
4460
  this.notify();
4434
4461
  }
4462
+ /**
4463
+ * Opens one help article: in Scout's Help tab when the messenger is on, otherwise in the resource
4464
+ * center. Help-article links in guides and articles (`#guidely-article:<id>`) call this.
4465
+ */
4466
+ openArticle(articleId) {
4467
+ if (this.messenger) {
4468
+ this.whenHydrated(() => void this.messenger?.openArticle(articleId));
4469
+ return;
4470
+ }
4471
+ if (!this.getResourceCenter()) {
4472
+ this.log("openArticle: the resource center is not enabled or published for this environment");
4473
+ return;
4474
+ }
4475
+ this.resourceCenterArticle = { id: articleId, seq: (this.resourceCenterArticle?.seq ?? 0) + 1 };
4476
+ if (this.resourceCenterOpen) this.notify();
4477
+ else this.openResourceCenter();
4478
+ }
4479
+ /** A resource-center article with its body: from the config, or fetched when the config left it out. */
4480
+ async loadArticle(articleId) {
4481
+ const listed = this.getResourceCenter()?.articles.find((a) => a.id === articleId);
4482
+ if (listed && !listed.bodyOmitted) return listed;
4483
+ try {
4484
+ const locale = this.articleLocale();
4485
+ const res = await this.api.get(`/articles/${encodeURIComponent(articleId)}`, locale ? { params: { locale } } : {});
4486
+ return res.ok && res.data ? res.data.article : null;
4487
+ } catch {
4488
+ return null;
4489
+ }
4490
+ }
4435
4491
  closeResourceCenter() {
4436
4492
  if (this.messenger) return this.closeMessenger();
4437
4493
  if (!this.resourceCenterOpen) return;
4438
4494
  this.resourceCenterOpen = false;
4495
+ this.resourceCenterArticle = null;
4439
4496
  this.notify();
4440
4497
  }
4441
4498
  // ---------------------------------------------------------------------------
@@ -4846,7 +4903,7 @@ function resolveTapTarget(event, opts = {}) {
4846
4903
 
4847
4904
  // src/ui/Overlay.tsx
4848
4905
  import { useCallback as useCallback2, useEffect as useEffect7, useRef as useRef4, useState as useState7, useSyncExternalStore as useSyncExternalStore3 } from "react";
4849
- import { Platform as Platform5, Pressable as Pressable8, StatusBar, StyleSheet as StyleSheet9, Text as Text8, useColorScheme, useWindowDimensions, View as View9 } from "react-native";
4906
+ import { Platform as Platform5, Pressable as Pressable9, StatusBar, StyleSheet as StyleSheet9, Text as Text8, useColorScheme, useWindowDimensions, View as View9 } from "react-native";
4850
4907
 
4851
4908
  // src/ui/Checklist.tsx
4852
4909
  import { Pressable as Pressable3, ScrollView as ScrollView2, StyleSheet as StyleSheet3, Text as Text3, View as View3 } from "react-native";
@@ -5781,7 +5838,7 @@ var styles4 = StyleSheet4.create({
5781
5838
  import { Fragment as Fragment4, useEffect as useEffect4, useMemo as useMemo4, useState as useState4 } from "react";
5782
5839
  import { Modal as Modal3, Platform as Platform3, Pressable as Pressable5, ScrollView as ScrollView4, StyleSheet as StyleSheet5, Text as Text5, TextInput as TextInput2, View as View5 } from "react-native";
5783
5840
  import { Fragment as Fragment5, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
5784
- function ResourceCenter({ client, palette: p, open, topInset, bottomInset }) {
5841
+ function ResourceCenter({ client, palette: p, open, articleRequest, topInset, bottomInset }) {
5785
5842
  const rc = client.getResourceCenter();
5786
5843
  const [query, setQuery] = useState4("");
5787
5844
  const [results, setResults] = useState4(null);
@@ -5794,6 +5851,19 @@ function ResourceCenter({ client, palette: p, open, topInset, bottomInset }) {
5794
5851
  setArticle(null);
5795
5852
  }
5796
5853
  }, [open]);
5854
+ useEffect4(() => {
5855
+ if (!open || !articleRequest) return;
5856
+ let alive = true;
5857
+ void client.loadArticle(articleRequest.id).then((a) => {
5858
+ if (!alive || !a) return;
5859
+ if (a.externalUrl) return client.navigate(a.externalUrl);
5860
+ client.articleViewed(a);
5861
+ setArticle(a);
5862
+ });
5863
+ return () => {
5864
+ alive = false;
5865
+ };
5866
+ }, [client, open, articleRequest?.seq]);
5797
5867
  useEffect4(() => {
5798
5868
  const q = query.trim();
5799
5869
  if (q.length < 2) {
@@ -5933,7 +6003,7 @@ var styles5 = StyleSheet5.create({
5933
6003
 
5934
6004
  // src/ui/StepLayer.tsx
5935
6005
  import { useEffect as useEffect5, useRef as useRef3, useState as useState5 } from "react";
5936
- import { AccessibilityInfo as AccessibilityInfo2, Animated as Animated2, Easing as Easing2, Pressable as Pressable6, StyleSheet as StyleSheet7, View as View7 } from "react-native";
6006
+ import { AccessibilityInfo as AccessibilityInfo2, Animated as Animated2, Easing as Easing2, Pressable as Pressable7, StyleSheet as StyleSheet7, View as View7 } from "react-native";
5937
6007
 
5938
6008
  // src/core/position.ts
5939
6009
  var MARGIN = 12;
@@ -5973,7 +6043,7 @@ function positionCard(target, size, viewport, insets, placement, offset) {
5973
6043
  }
5974
6044
 
5975
6045
  // src/ui/StepCard.tsx
5976
- import { Image as Image2, StyleSheet as StyleSheet6, Text as Text6, View as View6 } from "react-native";
6046
+ import { Image as Image2, Pressable as Pressable6, StyleSheet as StyleSheet6, Text as Text6, View as View6 } from "react-native";
5977
6047
  import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
5978
6048
  function StepCard({ view, client, palette: p, width, style, compact }) {
5979
6049
  const { step, guide } = view;
@@ -5981,8 +6051,25 @@ function StepCard({ view, client, palette: p, width, style, compact }) {
5981
6051
  const body = step.type === "custom" ? step.customHtml || step.body : step.body;
5982
6052
  const showProgress = step.showProgress && view.total > 1;
5983
6053
  const onLink = (url) => client.navigate(url);
6054
+ const video = stepVideo(step);
5984
6055
  return /* @__PURE__ */ jsx7(Surface, { palette: p, style: [{ width }, style], children: /* @__PURE__ */ jsxs5(View6, { accessible: false, accessibilityViewIsModal: view.asModal || step.type === "modal", style: compact ? styles6.compact : styles6.inner, children: [
5985
- step.imageUrl ? (
6056
+ video ? (
6057
+ // The video opens outside the app (browser or the provider's app), like a new tab on the web.
6058
+ /* @__PURE__ */ jsxs5(
6059
+ Pressable6,
6060
+ {
6061
+ onPress: () => client.openVideo(guide.id, video.url),
6062
+ accessibilityRole: "button",
6063
+ accessibilityLabel: step.title ? `Play video: ${step.title}` : "Play video",
6064
+ accessibilityHint: "Opens the video outside the app",
6065
+ style: [styles6.video, { borderRadius: Math.max(0, p.radius - 4) }],
6066
+ children: [
6067
+ video.poster ? /* @__PURE__ */ jsx7(Image2, { source: { uri: video.poster }, style: StyleSheet6.absoluteFill, resizeMode: "cover", accessibilityIgnoresInvertColors: true, accessible: false }) : null,
6068
+ /* @__PURE__ */ jsx7(View6, { style: styles6.play, children: /* @__PURE__ */ jsx7(View6, { style: styles6.playTriangle }) })
6069
+ ]
6070
+ }
6071
+ )
6072
+ ) : step.imageUrl ? (
5986
6073
  // An empty description marks the image as decorative: screen readers skip it.
5987
6074
  /* @__PURE__ */ jsx7(
5988
6075
  Image2,
@@ -6023,6 +6110,10 @@ var styles6 = StyleSheet6.create({
6023
6110
  inner: { padding: 16, gap: 10 },
6024
6111
  compact: { paddingHorizontal: 14, paddingVertical: 10, gap: 6 },
6025
6112
  image: { width: "100%", height: 140, marginBottom: 2 },
6113
+ video: { width: "100%", aspectRatio: 16 / 9, maxHeight: 200, marginBottom: 2, overflow: "hidden", backgroundColor: "#0f172a", alignItems: "center", justifyContent: "center" },
6114
+ play: { width: 52, height: 52, borderRadius: 26, backgroundColor: "rgba(15,23,42,0.72)", alignItems: "center", justifyContent: "center", paddingLeft: 4 },
6115
+ // A CSS-border triangle: no icon font needed.
6116
+ playTriangle: { width: 0, height: 0, borderTopWidth: 10, borderBottomWidth: 10, borderLeftWidth: 16, borderTopColor: "transparent", borderBottomColor: "transparent", borderLeftColor: "#fff" },
6026
6117
  header: { flexDirection: "row", alignItems: "flex-start", gap: 8 },
6027
6118
  title: { flex: 1, fontSize: 17, fontWeight: "700", lineHeight: 22 },
6028
6119
  flex: { flex: 1 },
@@ -6082,7 +6173,7 @@ function StepLayer({ view, client, palette: p, geometry }) {
6082
6173
  if (step.type === "hotspot" && !view.expanded) return;
6083
6174
  AccessibilityInfo2.announceForAccessibility?.(announcement(view));
6084
6175
  }, [view.key, view.expanded]);
6085
- const backdrop = (children) => /* @__PURE__ */ jsx8(Pressable6, { accessible: false, style: [StyleSheet7.absoluteFill, { backgroundColor: p.overlay }], onPress: () => client.backdropPressed(view.guide.id), children });
6176
+ const backdrop = (children) => /* @__PURE__ */ jsx8(Pressable7, { accessible: false, style: [StyleSheet7.absoluteFill, { backgroundColor: p.overlay }], onPress: () => client.backdropPressed(view.guide.id), children });
6086
6177
  const anchored = !view.asModal && ["tooltip", "popover", "spotlight", "hotspot"].includes(step.type);
6087
6178
  if (!anchored && step.type === "banner") {
6088
6179
  const top = step.position.startsWith("top");
@@ -6121,10 +6212,10 @@ function StepLayer({ view, client, palette: p, geometry }) {
6121
6212
  [hole.x + hole.width - r, hole.y + hole.height - r, -2 * r, -2 * r]
6122
6213
  ];
6123
6214
  return /* @__PURE__ */ jsxs6(Animated2.View, { pointerEvents: "box-none", style: [StyleSheet7.absoluteFill, { opacity }], children: [
6124
- /* @__PURE__ */ jsx8(Pressable6, { accessible: false, onPress: press, style: [styles7.abs, shade, { left: 0, right: 0, top: 0, height: Math.max(0, hole.y) }] }),
6125
- /* @__PURE__ */ jsx8(Pressable6, { accessible: false, onPress: press, style: [styles7.abs, shade, { left: 0, right: 0, top: hole.y + hole.height, bottom: 0 }] }),
6126
- /* @__PURE__ */ jsx8(Pressable6, { accessible: false, onPress: press, style: [styles7.abs, shade, { left: 0, width: Math.max(0, hole.x), top: hole.y, height: hole.height }] }),
6127
- /* @__PURE__ */ jsx8(Pressable6, { accessible: false, onPress: press, style: [styles7.abs, shade, { left: hole.x + hole.width, right: 0, top: hole.y, height: hole.height }] }),
6215
+ /* @__PURE__ */ jsx8(Pressable7, { accessible: false, onPress: press, style: [styles7.abs, shade, { left: 0, right: 0, top: 0, height: Math.max(0, hole.y) }] }),
6216
+ /* @__PURE__ */ jsx8(Pressable7, { accessible: false, onPress: press, style: [styles7.abs, shade, { left: 0, right: 0, top: hole.y + hole.height, bottom: 0 }] }),
6217
+ /* @__PURE__ */ jsx8(Pressable7, { accessible: false, onPress: press, style: [styles7.abs, shade, { left: 0, width: Math.max(0, hole.x), top: hole.y, height: hole.height }] }),
6218
+ /* @__PURE__ */ jsx8(Pressable7, { accessible: false, onPress: press, style: [styles7.abs, shade, { left: hole.x + hole.width, right: 0, top: hole.y, height: hole.height }] }),
6128
6219
  r > 0 ? corners.map(([left, top, dx, dy], i) => /* @__PURE__ */ jsx8(View7, { pointerEvents: "none", style: [styles7.abs, { left, top, width: r, height: r, overflow: "hidden" }], children: /* @__PURE__ */ jsx8(View7, { style: [styles7.abs, { left: dx, top: dy, width: 4 * r, height: 4 * r, borderRadius: 2 * r, borderWidth: r, borderColor: p.overlay }] }) }, i)) : null,
6129
6220
  /* @__PURE__ */ jsx8(View7, { pointerEvents: "none", style: [styles7.abs, { left: hole.x, top: hole.y, width: hole.width, height: hole.height, borderRadius: r, borderWidth: 2, borderColor: p.primary }] }),
6130
6221
  /* @__PURE__ */ jsx8(Anchored, { view, client, palette: p, geometry, rect: hole, width: cardWidth })
@@ -6168,7 +6259,7 @@ function Hotspot({ x, y, size, pulse, color, onPress, label }) {
6168
6259
  loop.start();
6169
6260
  return () => loop.stop();
6170
6261
  }, [pulse, reduceMotion, scale]);
6171
- return /* @__PURE__ */ jsxs6(Pressable6, { accessibilityRole: "button", accessibilityLabel: label, onPress, hitSlop: 14, style: [styles7.abs, { left: x, top: y, width: size, height: size }], children: [
6262
+ return /* @__PURE__ */ jsxs6(Pressable7, { accessibilityRole: "button", accessibilityLabel: label, onPress, hitSlop: 14, style: [styles7.abs, { left: x, top: y, width: size, height: size }], children: [
6172
6263
  pulse && !reduceMotion ? /* @__PURE__ */ jsx8(
6173
6264
  Animated2.View,
6174
6265
  {
@@ -6192,7 +6283,7 @@ import {
6192
6283
  AccessibilityInfo as AccessibilityInfo3,
6193
6284
  KeyboardAvoidingView,
6194
6285
  Platform as Platform4,
6195
- Pressable as Pressable7,
6286
+ Pressable as Pressable8,
6196
6287
  ScrollView as ScrollView5,
6197
6288
  StyleSheet as StyleSheet8,
6198
6289
  Text as Text7,
@@ -6250,7 +6341,7 @@ function Survey({
6250
6341
  style: StyleSheet8.absoluteFill,
6251
6342
  children: [
6252
6343
  centered ? /* @__PURE__ */ jsx9(
6253
- Pressable7,
6344
+ Pressable8,
6254
6345
  {
6255
6346
  accessible: false,
6256
6347
  style: [StyleSheet8.absoluteFill, { backgroundColor: p.overlay }],
@@ -6347,7 +6438,7 @@ function QuestionInput({
6347
6438
  const values = Array.from({ length: max - min + 1 }, (_, i) => min + i);
6348
6439
  return /* @__PURE__ */ jsxs7(View8, { children: [
6349
6440
  /* @__PURE__ */ jsx9(View8, { style: styles8.scale, accessibilityRole: "radiogroup", accessibilityLabel: q.title, children: values.map((n) => /* @__PURE__ */ jsx9(
6350
- Pressable7,
6441
+ Pressable8,
6351
6442
  {
6352
6443
  accessibilityRole: "radio",
6353
6444
  accessibilityState: { selected: value === n },
@@ -6367,7 +6458,7 @@ function QuestionInput({
6367
6458
  case "rating": {
6368
6459
  const max = q.scaleMax ?? 5;
6369
6460
  return /* @__PURE__ */ jsx9(View8, { style: styles8.stars, accessibilityRole: "radiogroup", accessibilityLabel: q.title, children: Array.from({ length: max }, (_, i) => i + 1).map((n) => /* @__PURE__ */ jsx9(
6370
- Pressable7,
6461
+ Pressable8,
6371
6462
  {
6372
6463
  accessibilityRole: "radio",
6373
6464
  accessibilityLabel: `${n} of ${max}`,
@@ -6393,7 +6484,7 @@ function QuestionInput({
6393
6484
  [true, "\u{1F44D}", "Thumbs up"],
6394
6485
  [false, "\u{1F44E}", "Thumbs down"]
6395
6486
  ].map(([val, icon, label]) => /* @__PURE__ */ jsx9(
6396
- Pressable7,
6487
+ Pressable8,
6397
6488
  {
6398
6489
  accessibilityRole: "radio",
6399
6490
  accessibilityLabel: label,
@@ -6413,7 +6504,7 @@ function QuestionInput({
6413
6504
  return /* @__PURE__ */ jsx9(View8, { style: styles8.choices, children: q.options.map((o) => {
6414
6505
  const on = selected.has(o.id);
6415
6506
  return /* @__PURE__ */ jsxs7(
6416
- Pressable7,
6507
+ Pressable8,
6417
6508
  {
6418
6509
  accessibilityRole: multi ? "checkbox" : "radio",
6419
6510
  accessibilityState: { checked: on },
@@ -6599,7 +6690,7 @@ function GuidelyOverlay({ client, insets: insetsProp, launcherOffset }) {
6599
6690
  return /* @__PURE__ */ jsxs8(View9, { ref, collapsable: false, pointerEvents: "box-none", style: StyleSheet9.absoluteFill, onLayout: measureOrigin, children: [
6600
6691
  ui.checklists.map((c) => /* @__PURE__ */ jsx10(Checklist, { view: c, client, palette: palette(client.themeFor(c.guide), scheme), geometry, showLauncher: client.options.showChecklistLauncher !== false, launcherBottom: launcherOffset }, c.guide.id)),
6601
6692
  showRcLauncher ? /* @__PURE__ */ jsxs8(
6602
- Pressable8,
6693
+ Pressable9,
6603
6694
  {
6604
6695
  accessibilityRole: "button",
6605
6696
  accessibilityLabel: rcLauncherLabel(client),
@@ -6624,7 +6715,7 @@ function GuidelyOverlay({ client, insets: insetsProp, launcherOffset }) {
6624
6715
  ) : null,
6625
6716
  ui.survey ? /* @__PURE__ */ jsx10(Survey, { view: ui.survey, client, palette: palette(client.themeFor(ui.survey.guide), scheme), geometry }) : null,
6626
6717
  ui.steps.map((s) => /* @__PURE__ */ jsx10(StepLayer, { view: s, client, palette: palette(client.themeFor(s.guide), scheme, s.guide.config.appearance), geometry }, s.key)),
6627
- messenger ? /* @__PURE__ */ jsx10(MessengerSheet, { store: messenger, client, palette: basePalette, topInset: insets.top, bottomInset: insets.bottom }) : /* @__PURE__ */ jsx10(ResourceCenter, { client, palette: basePalette, open: ui.resourceCenterOpen, topInset: insets.top, bottomInset: insets.bottom })
6718
+ messenger ? /* @__PURE__ */ jsx10(MessengerSheet, { store: messenger, client, palette: basePalette, topInset: insets.top, bottomInset: insets.bottom }) : /* @__PURE__ */ jsx10(ResourceCenter, { client, palette: basePalette, open: ui.resourceCenterOpen, articleRequest: ui.resourceCenterArticle ?? null, topInset: insets.top, bottomInset: insets.bottom })
6628
6719
  ] });
6629
6720
  }
6630
6721
  var styles9 = StyleSheet9.create({