@appilots/sdk 0.2.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.js ADDED
@@ -0,0 +1,2836 @@
1
+ 'use strict';
2
+
3
+ var chunkKGN3DNGX_js = require('./chunk-KGN3DNGX.js');
4
+ var chunkIASJ7YHC_js = require('./chunk-IASJ7YHC.js');
5
+ var chunkSIBKF7AA_js = require('./chunk-SIBKF7AA.js');
6
+ var React7 = require('react');
7
+ var reactNative = require('react-native');
8
+ var reactNativeSafeAreaContext = require('react-native-safe-area-context');
9
+ var Svg = require('react-native-svg');
10
+
11
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
12
+
13
+ function _interopNamespace(e) {
14
+ if (e && e.__esModule) return e;
15
+ var n = Object.create(null);
16
+ if (e) {
17
+ Object.keys(e).forEach(function (k) {
18
+ if (k !== 'default') {
19
+ var d = Object.getOwnPropertyDescriptor(e, k);
20
+ Object.defineProperty(n, k, d.get ? d : {
21
+ enumerable: true,
22
+ get: function () { return e[k]; }
23
+ });
24
+ }
25
+ });
26
+ }
27
+ n.default = e;
28
+ return Object.freeze(n);
29
+ }
30
+
31
+ var React7__namespace = /*#__PURE__*/_interopNamespace(React7);
32
+ var Svg__default = /*#__PURE__*/_interopDefault(Svg);
33
+
34
+ // ../shared/dist/chunk-43YQ52Q7.mjs
35
+ var SENSITIVE_FIELD_NAME_RE = /(\b|_|-)(password|senha|contrase[ñn]a|mot[\s_-]*de[\s_-]*passe|passwd|pwd|secret|token|api[\s_-]*key|access[\s_-]*key|private[\s_-]*key|cvv|cvc|cvn|cvc2|cid|pin(?:[\s_-]*code)?|otp|one[\s_-]*time[\s_-]*code|2fa|mfa|security[\s_-]*code|c[óo]digo[\s_-]*seguran[çc]a|c[óo]digo[\s_-]*verifica[çc][ãa]o|verification[\s_-]*code)(\b|_|-)/i;
36
+ function isSensitiveFieldName(id, label, placeholder, type) {
37
+ if (type === "password") return true;
38
+ for (const candidate of [id, label, placeholder]) {
39
+ if (typeof candidate === "string" && SENSITIVE_FIELD_NAME_RE.test(candidate)) {
40
+ return true;
41
+ }
42
+ }
43
+ return false;
44
+ }
45
+
46
+ // src/components/humanizeAction.ts
47
+ function describeAction(action) {
48
+ const state = mapStatus(action.status);
49
+ const label = labelFor(action, state);
50
+ return { label, state };
51
+ }
52
+ function mapStatus(status) {
53
+ switch (status) {
54
+ case "pending":
55
+ return "pending";
56
+ case "executing":
57
+ return "running";
58
+ case "completed":
59
+ return "success";
60
+ case "failed":
61
+ return "failed";
62
+ default:
63
+ return "pending";
64
+ }
65
+ }
66
+ function labelFor(action, state) {
67
+ if (state === "failed") {
68
+ return failureLabel(action);
69
+ }
70
+ switch (action.type) {
71
+ case "navigate":
72
+ return navigateLabel(action, state);
73
+ case "form_fill":
74
+ return formFillLabel(action, state);
75
+ case "ui_interaction":
76
+ return uiInteractionLabel(action, state);
77
+ case "scroll_list":
78
+ return scrollListLabel(action, state);
79
+ case "confirm":
80
+ return confirmLabel(state);
81
+ default:
82
+ return genericLabel(action.type, state);
83
+ }
84
+ }
85
+ function navigateLabel(action, state) {
86
+ const screen = readString(action.payload, "screenName") || "a outra tela";
87
+ switch (state) {
88
+ case "pending":
89
+ return `Vou navegar para ${screen}`;
90
+ case "running":
91
+ return `Navegando para ${screen}...`;
92
+ case "success":
93
+ return `Naveguei para ${screen}`;
94
+ default:
95
+ return `Navega\xE7\xE3o para ${screen}`;
96
+ }
97
+ }
98
+ function formFillLabel(action, state) {
99
+ const fields = readArray(action.payload, "fields");
100
+ const summary = summariseFields(fields);
101
+ switch (state) {
102
+ case "pending":
103
+ return summary ? `Vou preencher ${summary}` : "Vou preencher o formul\xE1rio";
104
+ case "running":
105
+ return summary ? `Preenchendo ${summary}...` : "Preenchendo formul\xE1rio...";
106
+ case "success":
107
+ return summary ? `Preenchi ${summary}` : "Preenchi o formul\xE1rio";
108
+ default:
109
+ return "Preenchimento do formul\xE1rio";
110
+ }
111
+ }
112
+ function uiInteractionLabel(action, state) {
113
+ const verbBase = uiVerb(readString(action.payload, "action"));
114
+ const target = humanActionTarget(action.payload);
115
+ const where = target ? ` em ${target}` : "";
116
+ switch (state) {
117
+ case "pending":
118
+ return `Vou ${verbBase.infinitive}${where}`;
119
+ case "running":
120
+ return `${verbBase.gerund}${where}...`;
121
+ case "success":
122
+ return `${verbBase.past}${where}`;
123
+ default:
124
+ return `Intera\xE7\xE3o${where}`;
125
+ }
126
+ }
127
+ function scrollListLabel(action, state) {
128
+ const payload = action.payload;
129
+ const toIndex = typeof payload?.toIndex === "number" ? payload.toIndex : void 0;
130
+ const direction = payload?.direction === "up" ? "para cima" : "para baixo";
131
+ const target = toIndex !== void 0 ? `at\xE9 o item ${toIndex}` : direction;
132
+ switch (state) {
133
+ case "pending":
134
+ return `Vou rolar a lista ${target}`;
135
+ case "running":
136
+ return `Rolando a lista ${target}...`;
137
+ case "success":
138
+ return `Rolei a lista ${target}`;
139
+ default:
140
+ return "Rolagem da lista";
141
+ }
142
+ }
143
+ function confirmLabel(state) {
144
+ switch (state) {
145
+ case "pending":
146
+ case "running":
147
+ return "Aguardando confirma\xE7\xE3o";
148
+ case "success":
149
+ return "Voc\xEA confirmou";
150
+ case "failed":
151
+ return "Confirma\xE7\xE3o cancelada";
152
+ default:
153
+ return "Confirma\xE7\xE3o";
154
+ }
155
+ }
156
+ function genericLabel(type, state) {
157
+ switch (state) {
158
+ case "pending":
159
+ return `Vou executar ${type}`;
160
+ case "running":
161
+ return `Executando ${type}...`;
162
+ case "success":
163
+ return `Executei ${type}`;
164
+ default:
165
+ return type;
166
+ }
167
+ }
168
+ function failureLabel(action) {
169
+ const cause = humanizeError(action.error);
170
+ const head = failureHead(action);
171
+ return cause ? `${head} (${cause})` : head;
172
+ }
173
+ function failureHead(action) {
174
+ switch (action.type) {
175
+ case "navigate": {
176
+ const screen = readString(action.payload, "screenName") || "a tela";
177
+ return `N\xE3o consegui navegar para ${screen}`;
178
+ }
179
+ case "form_fill":
180
+ return "N\xE3o consegui preencher o formul\xE1rio";
181
+ case "ui_interaction": {
182
+ const verb = uiVerb(readString(action.payload, "action"));
183
+ const target = humanComponentId(
184
+ readString(action.payload, "componentId") || readString(action.payload, "targetId")
185
+ );
186
+ return target ? `N\xE3o consegui ${verb.infinitive} em ${target}` : `N\xE3o consegui ${verb.infinitive}`;
187
+ }
188
+ case "scroll_list":
189
+ return "N\xE3o consegui rolar a lista";
190
+ case "confirm":
191
+ return "Voc\xEA cancelou";
192
+ default:
193
+ return `N\xE3o consegui executar ${action.type}`;
194
+ }
195
+ }
196
+ var TECHNICAL_PATTERNS = [
197
+ /\bat\s+\S+\s*\(/,
198
+ // stack trace frame
199
+ /TypeError|ReferenceError|SyntaxError|RangeError/i,
200
+ /HTTP\s*[45]\d{2}/i,
201
+ /^\s*\{[\s\S]*\}\s*$/,
202
+ // JSON dump
203
+ /undefined is not a function/i,
204
+ /Cannot read propert/i
205
+ ];
206
+ var FRIENDLY_REWRITES = [
207
+ [/rejected by user/i, "cancelado pelo usu\xE1rio"],
208
+ [/component '([^']+)' not found/i, "componente $1 n\xE3o encontrado"],
209
+ [/field '([^']+)' not found/i, "campo $1 n\xE3o encontrado"],
210
+ [/screen '([^']+)' not registered/i, "tela $1 n\xE3o registrada"],
211
+ [/permission denied/i, "sem permiss\xE3o"],
212
+ [/timeout|timed out/i, "tempo esgotado"],
213
+ [/network/i, "falha de rede"]
214
+ ];
215
+ var MAX_REASON_LEN = 80;
216
+ function humanizeError(raw, _action) {
217
+ if (!raw) return void 0;
218
+ const trimmed = String(raw).trim();
219
+ if (!trimmed) return void 0;
220
+ for (const [pattern, replacement] of FRIENDLY_REWRITES) {
221
+ if (pattern.test(trimmed)) {
222
+ return finalize(trimmed.replace(pattern, replacement));
223
+ }
224
+ }
225
+ if (TECHNICAL_PATTERNS.some((p) => p.test(trimmed))) {
226
+ return "algo deu errado";
227
+ }
228
+ if (trimmed.length > MAX_REASON_LEN) {
229
+ return "algo deu errado";
230
+ }
231
+ return finalize(trimmed);
232
+ }
233
+ function finalize(text) {
234
+ let out = text.trim();
235
+ if (out.length > MAX_REASON_LEN) out = out.slice(0, MAX_REASON_LEN - 1).trimEnd() + "\u2026";
236
+ if (out.length > 0) out = out[0].toLowerCase() + out.slice(1);
237
+ return out;
238
+ }
239
+ function uiVerb(raw) {
240
+ switch ((raw ?? "press").toLowerCase()) {
241
+ case "press":
242
+ case "tap":
243
+ case "click":
244
+ return { infinitive: "clicar", gerund: "Clicando", past: "Cliquei" };
245
+ case "longpress":
246
+ case "long_press":
247
+ return { infinitive: "pressionar", gerund: "Pressionando", past: "Pressionei" };
248
+ case "scroll":
249
+ case "scroll_to":
250
+ return { infinitive: "rolar", gerund: "Rolando", past: "Rolei" };
251
+ case "focus":
252
+ return { infinitive: "focar", gerund: "Focando", past: "Foquei" };
253
+ default:
254
+ return { infinitive: "interagir", gerund: "Interagindo", past: "Interagi" };
255
+ }
256
+ }
257
+ function summariseFields(fields) {
258
+ if (!Array.isArray(fields) || fields.length === 0) return void 0;
259
+ const parts = [];
260
+ const visible = fields.slice(0, 3);
261
+ for (const f of visible) {
262
+ if (!f || typeof f !== "object") continue;
263
+ const obj = f;
264
+ const name = humanFieldName(obj.label, obj.fieldId);
265
+ if (!name) continue;
266
+ const fieldIdStr = typeof obj.fieldId === "string" ? obj.fieldId : void 0;
267
+ const labelStr = typeof obj.label === "string" ? obj.label : void 0;
268
+ const fieldTypeStr = typeof obj.fieldType === "string" ? obj.fieldType : void 0;
269
+ const sensitive = isSensitiveFieldName(fieldIdStr, labelStr, void 0, fieldTypeStr);
270
+ if (sensitive) {
271
+ parts.push(`${name}=\u2022\u2022\u2022\u2022`);
272
+ continue;
273
+ }
274
+ const value = formatFieldValue(obj.value);
275
+ parts.push(value !== void 0 ? `${name}=${value}` : name);
276
+ }
277
+ if (parts.length === 0) return void 0;
278
+ const extra = fields.length - parts.length;
279
+ return extra > 0 ? `${parts.join(", ")} +${extra}` : parts.join(", ");
280
+ }
281
+ function formatFieldValue(value) {
282
+ if (value === void 0 || value === null || value === "") return void 0;
283
+ if (typeof value === "string") {
284
+ const v = value.length > 18 ? `${value.slice(0, 17)}\u2026` : value;
285
+ return `"${v}"`;
286
+ }
287
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
288
+ return void 0;
289
+ }
290
+ function humanActionTarget(payload) {
291
+ if (!payload || typeof payload !== "object") return "";
292
+ const record = payload;
293
+ const friendly = readFriendlyString(record, "label") || readFriendlyString(record, "actionDescription") || readFriendlyString(record, "title") || readFriendlyString(record, "name");
294
+ if (friendly) return friendly;
295
+ return humanComponentId(
296
+ readString(payload, "componentId") || readString(payload, "targetId")
297
+ );
298
+ }
299
+ function humanFieldName(label, fieldId) {
300
+ if (typeof label === "string" && label.trim()) return label.trim();
301
+ if (typeof fieldId !== "string" || isTechnicalIdentifier(fieldId)) return void 0;
302
+ return humanComponentId(fieldId) || void 0;
303
+ }
304
+ function readFriendlyString(record, key) {
305
+ const value = record[key];
306
+ if (typeof value !== "string") return "";
307
+ const trimmed = value.trim();
308
+ if (!trimmed || isTechnicalIdentifier(trimmed)) return "";
309
+ return trimmed;
310
+ }
311
+ function humanComponentId(id) {
312
+ if (!id) return "";
313
+ if (isTechnicalIdentifier(id)) return "";
314
+ const cleaned = id.replace(/^(btn-|btn_|button-|component-)/i, "").replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[-_]+/g, " ").trim();
315
+ if (!cleaned) return "";
316
+ return cleaned[0].toUpperCase() + cleaned.slice(1);
317
+ }
318
+ function isTechnicalIdentifier(value) {
319
+ const raw = value.trim();
320
+ if (!raw) return false;
321
+ if (/^el:/i.test(raw)) return true;
322
+ if (/^list-\d+-item-\d+$/i.test(raw)) return true;
323
+ if (/(testid|test-id|accessibilityid|accessibility-id|automationid|automation-id)/i.test(raw)) {
324
+ return true;
325
+ }
326
+ if (/^[a-z]+:[^ ]+:[^ ]+/i.test(raw)) return true;
327
+ if (/^[A-Za-z][\w-]*:[^\s]+$/i.test(raw)) return true;
328
+ if (/^[a-z]+(?:[-_][a-z]+)*[-_][a-z0-9]{5,}$/i.test(raw)) return true;
329
+ return false;
330
+ }
331
+ function readString(payload, key) {
332
+ if (!payload || typeof payload !== "object") return "";
333
+ const v = payload[key];
334
+ return typeof v === "string" ? v : "";
335
+ }
336
+ function readArray(payload, key) {
337
+ if (!payload || typeof payload !== "object") return [];
338
+ const v = payload[key];
339
+ return Array.isArray(v) ? v : [];
340
+ }
341
+
342
+ // src/theme/tokens.ts
343
+ var defaultLightTheme = {
344
+ colors: {
345
+ primary: "#6366f1",
346
+ secondary: "#8b5cf6",
347
+ background: "#ffffff",
348
+ surface: "#f3f4f6",
349
+ text: "#1f2937",
350
+ textSecondary: "#6b7280",
351
+ border: "#e5e7eb",
352
+ // NOTE (BACKLOG 4.2): success/warning/error used to have ZERO visual
353
+ // consumers — nothing read them, so ActionBreadcrumb's tones and the
354
+ // confirm card's destructive accents were hardcoded separately with
355
+ // their OWN hex values (#10B981/#EF4444/#9CA3AF-ish grays). Since no
356
+ // other UI in the SDK reads these three tokens, we picked these
357
+ // defaults to exactly match those pre-existing hardcoded values —
358
+ // wiring the tokens up to ActionBreadcrumb (see breadcrumbPresentation.ts)
359
+ // is now a no-op for anyone on the bundled default theme, while a
360
+ // custom theme's success/warning/error now actually do something.
361
+ success: "#10b981",
362
+ warning: "#9ca3af",
363
+ error: "#ef4444",
364
+ // Same value as `text` — split out so an app can diverge them, but
365
+ // any app that doesn't set these renders pixel-identical to before.
366
+ buttonText: "#1f2937",
367
+ bubbleText: "#1f2937",
368
+ userBubbleText: "#ffffff"
369
+ },
370
+ typography: {
371
+ fontFamily: "System",
372
+ fontSizeXs: 11,
373
+ fontSizeSm: 13,
374
+ fontSizeBase: 15,
375
+ fontSizeLg: 18
376
+ },
377
+ radii: {
378
+ sm: 8,
379
+ md: 12,
380
+ lg: 16
381
+ },
382
+ shadows: {
383
+ appearance: "light"
384
+ }
385
+ };
386
+ var defaultDarkTheme = {
387
+ colors: {
388
+ primary: "#818cf8",
389
+ secondary: "#a78bfa",
390
+ background: "#0f172a",
391
+ surface: "#1e293b",
392
+ text: "#f1f5f9",
393
+ textSecondary: "#94a3b8",
394
+ border: "#334155",
395
+ // Kept IDENTICAL to the light theme's success/warning/error (not the
396
+ // usual "lighter for dark bg" adjustment other tokens get) — the
397
+ // breadcrumb's tones were a fixed, theme-agnostic hardcoded palette
398
+ // before this token existed, rendering the SAME hex in light and dark
399
+ // mode. Diverging them here would change dark-mode breadcrumbs even
400
+ // though nothing in the token tree asked for that.
401
+ success: "#10b981",
402
+ warning: "#9ca3af",
403
+ error: "#ef4444",
404
+ buttonText: "#f1f5f9",
405
+ bubbleText: "#f1f5f9",
406
+ userBubbleText: "#ffffff"
407
+ },
408
+ typography: { ...defaultLightTheme.typography },
409
+ radii: { ...defaultLightTheme.radii },
410
+ shadows: { appearance: "dark" }
411
+ };
412
+ function mergeThemeTokens(base, partial) {
413
+ if (!partial) return base;
414
+ return {
415
+ colors: { ...base.colors, ...partial.colors ?? {} },
416
+ typography: { ...base.typography, ...partial.typography ?? {} },
417
+ radii: { ...base.radii, ...partial.radii ?? {} },
418
+ shadows: { ...base.shadows, ...partial.shadows ?? {} }
419
+ };
420
+ }
421
+ function resolveBaseTheme(mode, systemScheme) {
422
+ if (mode === "dark") return defaultDarkTheme;
423
+ if (mode === "light") return defaultLightTheme;
424
+ return systemScheme === "dark" ? defaultDarkTheme : defaultLightTheme;
425
+ }
426
+
427
+ // src/components/breadcrumbPresentation.ts
428
+ var DEFAULT_BREADCRUMB_PALETTE = {
429
+ primary: defaultLightTheme.colors.primary,
430
+ text: defaultLightTheme.colors.text,
431
+ textSecondary: defaultLightTheme.colors.textSecondary,
432
+ surface: defaultLightTheme.colors.surface,
433
+ border: defaultLightTheme.colors.border,
434
+ success: defaultLightTheme.colors.success,
435
+ warning: defaultLightTheme.colors.warning,
436
+ error: defaultLightTheme.colors.error
437
+ };
438
+ var KNOWN_TINTS = {
439
+ [DEFAULT_BREADCRUMB_PALETTE.primary.toUpperCase()]: "#EEF2FF",
440
+ [DEFAULT_BREADCRUMB_PALETTE.success.toUpperCase()]: "#ECFDF5",
441
+ [DEFAULT_BREADCRUMB_PALETTE.warning.toUpperCase()]: "#F3F4F6",
442
+ [DEFAULT_BREADCRUMB_PALETTE.error.toUpperCase()]: "#FEF2F2"
443
+ };
444
+ function tint(hex) {
445
+ const known = KNOWN_TINTS[hex.toUpperCase()];
446
+ if (known) return known;
447
+ const base = hex.length === 9 ? hex.slice(0, 7) : hex;
448
+ return `${base}1a`;
449
+ }
450
+ function deriveStateTone(palette = DEFAULT_BREADCRUMB_PALETTE) {
451
+ return {
452
+ pending: { color: palette.warning, iconBg: tint(palette.warning) },
453
+ running: { color: palette.primary, iconBg: tint(palette.primary) },
454
+ success: { color: palette.success, iconBg: tint(palette.success) },
455
+ failed: { color: palette.error, iconBg: tint(palette.error) }
456
+ };
457
+ }
458
+ deriveStateTone();
459
+ function iconGlyphFor(state) {
460
+ switch (state) {
461
+ case "pending":
462
+ return "\u25CB";
463
+ case "success":
464
+ return "\u2713";
465
+ case "failed":
466
+ return "\u2717";
467
+ case "running":
468
+ default:
469
+ return "\xB7";
470
+ }
471
+ }
472
+ function isDestructiveAction(action) {
473
+ return action.payload?.destructive === true || action.destructive === true;
474
+ }
475
+ DEFAULT_BREADCRUMB_PALETTE.error;
476
+ function deriveConfirmCardContent(action, palette = DEFAULT_BREADCRUMB_PALETTE) {
477
+ const payload = action.payload ?? {};
478
+ const isDestructive = isDestructiveAction(action);
479
+ const message = typeof payload.message === "string" && payload.message || typeof payload.actionDescription === "string" && payload.actionDescription || "Confirme para prosseguir";
480
+ const title = typeof payload.title === "string" && payload.title || (isDestructive ? "A\xE7\xE3o destrutiva" : "Confirma\xE7\xE3o necess\xE1ria");
481
+ const confirmLabel2 = typeof payload.confirmLabel === "string" && payload.confirmLabel || (isDestructive ? "Sim, executar" : "Confirmar");
482
+ const cancelLabel = typeof payload.cancelLabel === "string" && payload.cancelLabel || "Cancelar";
483
+ return {
484
+ isDestructive,
485
+ title,
486
+ message,
487
+ confirmLabel: confirmLabel2,
488
+ cancelLabel,
489
+ glyph: isDestructive ? "\u26A0" : "?",
490
+ actionColor: isDestructive ? palette.error : palette.primary,
491
+ cardBackground: palette.surface,
492
+ cardBorderColor: isDestructive ? palette.error : palette.border,
493
+ messageColor: palette.textSecondary,
494
+ cancelBackground: palette.border,
495
+ cancelTextColor: palette.textSecondary
496
+ };
497
+ }
498
+
499
+ // src/components/ActionBreadcrumb.tsx
500
+ function ActionBreadcrumb({
501
+ actions,
502
+ primaryColor,
503
+ textColor,
504
+ fontFamily,
505
+ palette,
506
+ requireApprovalFor,
507
+ onApprove,
508
+ onReject
509
+ }) {
510
+ if (actions.length === 0) return null;
511
+ const resolvedPalette = {
512
+ ...DEFAULT_BREADCRUMB_PALETTE,
513
+ ...palette,
514
+ primary: primaryColor,
515
+ text: textColor
516
+ };
517
+ return /* @__PURE__ */ React7__namespace.default.createElement(reactNative.View, { style: styles.container }, actions.map((action) => /* @__PURE__ */ React7__namespace.default.createElement(
518
+ BreadcrumbRow,
519
+ {
520
+ key: action.id,
521
+ action,
522
+ primaryColor,
523
+ textColor,
524
+ fontFamily,
525
+ palette: resolvedPalette,
526
+ needsApproval: requireApprovalFor?.(action) ?? false,
527
+ onApprove,
528
+ onReject
529
+ }
530
+ )));
531
+ }
532
+ function BreadcrumbRow(props) {
533
+ const { action, needsApproval } = props;
534
+ if (action.type === "confirm" && action.status === "pending" && needsApproval) {
535
+ return /* @__PURE__ */ React7__namespace.default.createElement(
536
+ ConfirmCard,
537
+ {
538
+ action,
539
+ palette: props.palette,
540
+ fontFamily: props.fontFamily,
541
+ onApprove: props.onApprove,
542
+ onReject: props.onReject
543
+ }
544
+ );
545
+ }
546
+ return /* @__PURE__ */ React7__namespace.default.createElement(RegularBreadcrumbRow, { ...props });
547
+ }
548
+ function RegularBreadcrumbRow({
549
+ action,
550
+ primaryColor,
551
+ textColor,
552
+ fontFamily,
553
+ palette,
554
+ needsApproval,
555
+ onApprove,
556
+ onReject
557
+ }) {
558
+ const { label, state } = describeAction(action);
559
+ const tone = deriveStateTone(palette)[state];
560
+ const fade = React7.useRef(new reactNative.Animated.Value(0)).current;
561
+ const pulse = React7.useRef(new reactNative.Animated.Value(1)).current;
562
+ const lastState = React7.useRef(state);
563
+ React7.useEffect(() => {
564
+ reactNative.Animated.timing(fade, {
565
+ toValue: 1,
566
+ duration: 180,
567
+ useNativeDriver: true
568
+ }).start();
569
+ }, [fade]);
570
+ React7.useEffect(() => {
571
+ if (lastState.current === state) return;
572
+ lastState.current = state;
573
+ pulse.setValue(0.4);
574
+ reactNative.Animated.timing(pulse, {
575
+ toValue: 1,
576
+ duration: 220,
577
+ useNativeDriver: true
578
+ }).start();
579
+ }, [state, pulse]);
580
+ const isDestructive = isDestructiveAction(action);
581
+ return /* @__PURE__ */ React7__namespace.default.createElement(reactNative.Animated.View, { style: [styles.row, { opacity: fade }] }, /* @__PURE__ */ React7__namespace.default.createElement(reactNative.Animated.View, { style: { opacity: pulse, flexDirection: "row", alignItems: "flex-start", flex: 1 } }, /* @__PURE__ */ React7__namespace.default.createElement(StateIcon, { state, tone, primaryColor }), /* @__PURE__ */ React7__namespace.default.createElement(
582
+ reactNative.Text,
583
+ {
584
+ style: [
585
+ styles.label,
586
+ { color: state === "failed" ? tone.color : textColor, fontFamily }
587
+ ],
588
+ accessibilityLabel: `${state}: ${label}`
589
+ },
590
+ label,
591
+ isDestructive && /* @__PURE__ */ React7__namespace.default.createElement(reactNative.Text, { style: [styles.destructiveTag, { color: palette.error }] }, " \u26A0 destrutiva")
592
+ )), needsApproval && action.status === "pending" && onApprove && onReject && /* @__PURE__ */ React7__namespace.default.createElement(reactNative.View, { style: styles.approvalButtons }, /* @__PURE__ */ React7__namespace.default.createElement(
593
+ reactNative.TouchableOpacity,
594
+ {
595
+ onPress: () => onReject(action.id),
596
+ style: [
597
+ styles.btn,
598
+ { backgroundColor: deriveStateTone(palette).failed.iconBg }
599
+ ],
600
+ activeOpacity: 0.7,
601
+ accessibilityLabel: "Rejeitar a\xE7\xE3o"
602
+ },
603
+ /* @__PURE__ */ React7__namespace.default.createElement(reactNative.Text, { style: [styles.rejectBtnText, { color: palette.error }] }, "Rejeitar")
604
+ ), /* @__PURE__ */ React7__namespace.default.createElement(
605
+ reactNative.TouchableOpacity,
606
+ {
607
+ onPress: () => onApprove(action.id),
608
+ style: [styles.btn, styles.approveBtn, { backgroundColor: primaryColor }],
609
+ activeOpacity: 0.7,
610
+ accessibilityLabel: "Aprovar a\xE7\xE3o"
611
+ },
612
+ /* @__PURE__ */ React7__namespace.default.createElement(reactNative.Text, { style: styles.approveBtnText }, "Aprovar")
613
+ )));
614
+ }
615
+ function ConfirmCard({ action, palette, fontFamily, onApprove, onReject }) {
616
+ const {
617
+ isDestructive,
618
+ title,
619
+ message,
620
+ confirmLabel: confirmLabel2,
621
+ cancelLabel,
622
+ glyph,
623
+ actionColor,
624
+ cardBackground,
625
+ cardBorderColor,
626
+ messageColor,
627
+ cancelBackground,
628
+ cancelTextColor
629
+ } = deriveConfirmCardContent(action, palette);
630
+ return /* @__PURE__ */ React7__namespace.default.createElement(
631
+ reactNative.View,
632
+ {
633
+ style: [
634
+ confirmCardStyles.card,
635
+ { backgroundColor: cardBackground, borderColor: cardBorderColor }
636
+ ],
637
+ testID: "assistant-confirm-card"
638
+ },
639
+ /* @__PURE__ */ React7__namespace.default.createElement(reactNative.View, { style: confirmCardStyles.headerRow }, /* @__PURE__ */ React7__namespace.default.createElement(reactNative.Text, { style: [confirmCardStyles.glyph, { color: actionColor }] }, glyph), /* @__PURE__ */ React7__namespace.default.createElement(
640
+ reactNative.Text,
641
+ {
642
+ style: [
643
+ confirmCardStyles.title,
644
+ { color: isDestructive ? palette.error : palette.text, fontFamily }
645
+ ]
646
+ },
647
+ title
648
+ )),
649
+ /* @__PURE__ */ React7__namespace.default.createElement(reactNative.Text, { style: [confirmCardStyles.message, { color: messageColor, fontFamily }] }, message),
650
+ /* @__PURE__ */ React7__namespace.default.createElement(reactNative.View, { style: confirmCardStyles.buttons }, /* @__PURE__ */ React7__namespace.default.createElement(
651
+ reactNative.TouchableOpacity,
652
+ {
653
+ onPress: () => onReject?.(action.id),
654
+ style: [confirmCardStyles.btn, { backgroundColor: cancelBackground }],
655
+ activeOpacity: 0.7,
656
+ accessibilityLabel: "Cancelar",
657
+ testID: "assistant-confirm-reject"
658
+ },
659
+ /* @__PURE__ */ React7__namespace.default.createElement(reactNative.Text, { style: [confirmCardStyles.cancelText, { color: cancelTextColor, fontFamily }] }, cancelLabel)
660
+ ), /* @__PURE__ */ React7__namespace.default.createElement(
661
+ reactNative.TouchableOpacity,
662
+ {
663
+ onPress: () => onApprove?.(action.id),
664
+ style: [
665
+ confirmCardStyles.btn,
666
+ confirmCardStyles.confirmBtn,
667
+ { backgroundColor: actionColor }
668
+ ],
669
+ activeOpacity: 0.7,
670
+ accessibilityLabel: "Confirmar",
671
+ testID: "assistant-confirm-approve"
672
+ },
673
+ /* @__PURE__ */ React7__namespace.default.createElement(reactNative.Text, { style: [confirmCardStyles.confirmText, { fontFamily }] }, confirmLabel2)
674
+ ))
675
+ );
676
+ }
677
+ var confirmCardStyles = reactNative.StyleSheet.create({
678
+ card: {
679
+ alignSelf: "stretch",
680
+ marginVertical: 6,
681
+ padding: 14,
682
+ borderRadius: 14,
683
+ borderWidth: 1
684
+ // backgroundColor / borderColor set inline — theme-driven (surface / border / error).
685
+ },
686
+ headerRow: {
687
+ flexDirection: "row",
688
+ alignItems: "center",
689
+ gap: 8,
690
+ marginBottom: 6
691
+ },
692
+ glyph: {
693
+ fontSize: 16,
694
+ fontWeight: "700"
695
+ },
696
+ title: {
697
+ fontSize: 14,
698
+ fontWeight: "700",
699
+ flexShrink: 1
700
+ },
701
+ message: {
702
+ fontSize: 14,
703
+ lineHeight: 20,
704
+ // color set inline — theme-driven (textSecondary).
705
+ marginBottom: 12
706
+ },
707
+ buttons: {
708
+ flexDirection: "row",
709
+ gap: 8,
710
+ justifyContent: "flex-end"
711
+ },
712
+ btn: {
713
+ paddingHorizontal: 14,
714
+ paddingVertical: 8,
715
+ borderRadius: 10,
716
+ minWidth: 96,
717
+ alignItems: "center"
718
+ },
719
+ cancelText: {
720
+ fontSize: 13,
721
+ fontWeight: "600"
722
+ // color set inline — theme-driven (textSecondary).
723
+ },
724
+ confirmBtn: {
725
+ // backgroundColor set inline
726
+ },
727
+ confirmText: {
728
+ fontSize: 13,
729
+ fontWeight: "600",
730
+ color: "#FFFFFF"
731
+ }
732
+ });
733
+ function StateIcon({
734
+ state,
735
+ tone,
736
+ primaryColor
737
+ }) {
738
+ return /* @__PURE__ */ React7__namespace.default.createElement(reactNative.View, { style: [styles.iconCircle, { backgroundColor: tone.iconBg }] }, state === "running" ? /* @__PURE__ */ React7__namespace.default.createElement(reactNative.ActivityIndicator, { size: "small", color: primaryColor }) : /* @__PURE__ */ React7__namespace.default.createElement(reactNative.Text, { style: [styles.iconGlyph, { color: tone.color }] }, iconGlyphFor(state)));
739
+ }
740
+ var styles = reactNative.StyleSheet.create({
741
+ container: {
742
+ alignSelf: "stretch",
743
+ marginBottom: 8,
744
+ paddingVertical: 4
745
+ },
746
+ row: {
747
+ flexDirection: "row",
748
+ alignItems: "center",
749
+ paddingVertical: 6,
750
+ paddingHorizontal: 4
751
+ },
752
+ iconCircle: {
753
+ width: 22,
754
+ height: 22,
755
+ borderRadius: 11,
756
+ alignItems: "center",
757
+ justifyContent: "center",
758
+ marginRight: 10,
759
+ marginTop: 1
760
+ },
761
+ iconGlyph: {
762
+ fontSize: 13,
763
+ fontWeight: "700",
764
+ lineHeight: 16
765
+ },
766
+ label: {
767
+ flex: 1,
768
+ fontSize: 14,
769
+ lineHeight: 19
770
+ },
771
+ destructiveTag: {
772
+ // color set inline — theme-driven (error).
773
+ fontSize: 12,
774
+ fontWeight: "700"
775
+ },
776
+ approvalButtons: {
777
+ flexDirection: "row",
778
+ gap: 6,
779
+ marginLeft: 8
780
+ },
781
+ btn: {
782
+ paddingHorizontal: 10,
783
+ paddingVertical: 5,
784
+ borderRadius: 8
785
+ },
786
+ rejectBtnText: {
787
+ fontSize: 12,
788
+ fontWeight: "600"
789
+ // color set inline — theme-driven (error).
790
+ },
791
+ approveBtn: {
792
+ // backgroundColor set inline
793
+ },
794
+ approveBtnText: {
795
+ fontSize: 12,
796
+ fontWeight: "600",
797
+ color: "#FFFFFF"
798
+ }
799
+ });
800
+
801
+ // src/components/personalization.ts
802
+ function str(value) {
803
+ const trimmed = value?.trim();
804
+ return trimmed ? trimmed : void 0;
805
+ }
806
+ function resolveTheme(themeProp, remote) {
807
+ return themeProp ?? remote?.theme ?? void 0;
808
+ }
809
+ function resolveThemeMode(themeModeProp, remote) {
810
+ return themeModeProp ?? remote?.theme?.mode ?? "auto";
811
+ }
812
+ function resolveLocaleProp(localeProp, remote) {
813
+ return localeProp ?? remote?.defaultLocale ?? null;
814
+ }
815
+ function resolvePersonalization(props, remote) {
816
+ return {
817
+ headerTitle: props.headerTitle ?? props.assistantName ?? str(remote?.chatTitle) ?? str(remote?.assistantName),
818
+ assistantAvatar: props.assistantAvatar ?? str(remote?.assistantAvatar),
819
+ emptyStateIcon: props.emptyStateIcon ?? str(remote?.emptyStateIcon),
820
+ welcomeMessage: props.welcomeMessage ?? str(remote?.welcomeMessage),
821
+ // Remote is always a boolean when present (server coerces legacy
822
+ // nulls to true), so `??` chains cleanly to the SDK default.
823
+ poweredByVisible: props.poweredByVisible ?? remote?.poweredByVisible ?? true,
824
+ triggerButtonColor: props.triggerButtonColor ?? str(remote?.triggerButtonColor),
825
+ triggerButtonImage: props.triggerButtonImage ?? str(remote?.triggerButtonImageUrl)
826
+ };
827
+ }
828
+ function ChatIcon({ size = 24, color = "#ffffff" }) {
829
+ return /* @__PURE__ */ React7__namespace.createElement(Svg__default.default, { width: size, height: size, viewBox: "0 0 24 24", fill: "none" }, /* @__PURE__ */ React7__namespace.createElement(
830
+ Svg.Path,
831
+ {
832
+ d: "M5 3.5h14a3 3 0 0 1 3 3v9a3 3 0 0 1-3 3h-7.4l-4.6 4v-4H5a3 3 0 0 1-3-3v-9a3 3 0 0 1 3-3z",
833
+ fill: color
834
+ }
835
+ ));
836
+ }
837
+ function HeadsetIcon({ size = 18, color = "#ffffff" }) {
838
+ return /* @__PURE__ */ React7__namespace.createElement(Svg__default.default, { width: size, height: size, viewBox: "0 0 24 24", fill: "none" }, /* @__PURE__ */ React7__namespace.createElement(
839
+ Svg.Path,
840
+ {
841
+ d: "M12 3a8 8 0 0 0-8 8v5.5A2.5 2.5 0 0 0 6.5 19H8a1 1 0 0 0 1-1v-5a1 1 0 0 0-1-1H6v-1a6 6 0 0 1 12 0v1h-2a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1h1.5a2.5 2.5 0 0 0 2.5-2.5V11a8 8 0 0 0-8-8z",
842
+ fill: color
843
+ }
844
+ ));
845
+ }
846
+
847
+ // src/components/chatTimeline.ts
848
+ function buildChatTimeline(messages, actions) {
849
+ const visibleMessageIds = new Set(messages.map((message) => message.id));
850
+ const visibleActionPrompts = actions.filter(
851
+ (action) => action.type === "confirm" && action.status === "pending"
852
+ );
853
+ const actionsByMessageId = /* @__PURE__ */ new Map();
854
+ const orphanActions = [];
855
+ for (const action of visibleActionPrompts) {
856
+ if (action.messageId && visibleMessageIds.has(action.messageId)) {
857
+ const list = actionsByMessageId.get(action.messageId) ?? [];
858
+ list.push(action);
859
+ actionsByMessageId.set(action.messageId, list);
860
+ } else {
861
+ orphanActions.push(action);
862
+ }
863
+ }
864
+ const timeline = [];
865
+ for (const msg of messages) {
866
+ timeline.push({ type: "message", data: msg });
867
+ if (msg.role === "assistant") {
868
+ const msgActions = actionsByMessageId.get(msg.id);
869
+ if (msgActions && msgActions.length > 0) {
870
+ timeline.push({ type: "breadcrumb", key: `bc-${msg.id}`, actions: msgActions });
871
+ }
872
+ }
873
+ }
874
+ if (orphanActions.length > 0) {
875
+ timeline.push({ type: "breadcrumb", key: "bc-orphan", actions: orphanActions });
876
+ }
877
+ return timeline;
878
+ }
879
+
880
+ // src/components/markdownContent.ts
881
+ var ORDERED_LINE = /^\s*(\d+)\.\s+(.+)$/;
882
+ var BULLET_LINE = /^\s*[-*•]\s+(.+)$/;
883
+ var HEADING_LINE = /^\s*(#{1,6})\s+(.+)$/;
884
+ var FENCE_LINE = /^\s*```\s*([A-Za-z0-9+#_-]*)\s*$/;
885
+ var INLINE_PATTERN = /\[([^\]\n]+)\]\((https?:\/\/[^\s)]+)\)|\*\*(.+?)\*\*|__(.+?)__|`([^`]+)`|\*(.+?)\*|_(.+?)_/g;
886
+ var MIN_ENHANCE_LENGTH = 80;
887
+ var SENTENCE_SPLIT = /[^.!?]+[.!?]+(?=\s+[A-ZÁÉÍÓÚÀÈÌÒÙÂÊÎÔÛÃÕÇÑ¿¡"“]|$)|[^.!?]+$/g;
888
+ var CAPABILITY_SENTENCE = /^((?:No aplicativo,?|In (?:this|the) app,?|En la aplicaci[oó]n,?|Dans l['’]application,?)?(?:\s+(?:voc[eê]|voce|you|tu|usted|puedes|puede|peux))?\s*(?:pode(?:m|r)?|can|could|puedes|puede|peux|peut))\s+(.+?)\.?\s*$/i;
889
+ var INCLUDE_LIST_SENTENCE = /^(.+?)\s+(?:incluem|inclui|include|includes|incluye|incluyen|such as|for example|par exemple|por exemplo)\s+(.+?)\.?\s*$/i;
890
+ function looksLikeMarkdown(content) {
891
+ if (!content) return false;
892
+ return /\*\*.+?\*\*/.test(content) || /__.+?__/.test(content) || /`[^`\n]+`/.test(content) || /^\s*[-*•]\s+/m.test(content) || /^\s*\d+\.\s+/m.test(content) || /^\s*#{1,6}\s+/m.test(content) || /^\s*```/m.test(content) || /\[[^\]\n]+\]\(https?:\/\/[^\s)]+\)/.test(content);
893
+ }
894
+ function splitEnumeration(text) {
895
+ const trimmed = text.trim().replace(/\.\s*$/, "");
896
+ if (!trimmed) return [];
897
+ const commaParts = trimmed.split(",").map((part) => part.trim()).filter(Boolean);
898
+ if (commaParts.length <= 1) {
899
+ const conjParts = trimmed.split(/\s+(?:e|and|y|ou|or)\s+/i).map((part) => part.trim());
900
+ return conjParts.filter(Boolean);
901
+ }
902
+ const last = commaParts[commaParts.length - 1];
903
+ const conjMatch = last.match(/^(.+?)\s+(?:e|and|y|ou|or)\s+(.+)$/i);
904
+ if (conjMatch) {
905
+ commaParts[commaParts.length - 1] = conjMatch[1].trim();
906
+ commaParts.push(conjMatch[2].trim());
907
+ }
908
+ return commaParts.filter(Boolean);
909
+ }
910
+ function splitSentences(text) {
911
+ const matches = text.match(SENTENCE_SPLIT);
912
+ if (!matches) return [text.trim()];
913
+ return matches.map((part) => part.trim()).filter(Boolean);
914
+ }
915
+ function formatCapabilitySentence(sentence) {
916
+ const match = CAPABILITY_SENTENCE.exec(sentence.trim());
917
+ if (!match) return null;
918
+ const items = splitEnumeration(match[2] ?? "");
919
+ if (items.length < 3) return null;
920
+ const intro = `${match[1].trim()}:`;
921
+ return `${intro}
922
+ ${items.map((item) => `- ${item}`).join("\n")}`;
923
+ }
924
+ function formatIncludeListSentence(sentence) {
925
+ const match = INCLUDE_LIST_SENTENCE.exec(sentence.trim());
926
+ if (!match) return null;
927
+ const intro = match[1].trim().replace(/[,:]\s*$/, "");
928
+ const items = splitEnumeration(match[2] ?? "");
929
+ if (items.length < 2) return null;
930
+ return `${intro}:
931
+ ${items.map((item) => `- ${item}`).join("\n")}`;
932
+ }
933
+ function formatReadableSentence(sentence) {
934
+ return formatCapabilitySentence(sentence) ?? formatIncludeListSentence(sentence) ?? sentence.trim();
935
+ }
936
+ function enhancePlainAssistantContent(content) {
937
+ if (!content?.trim() || looksLikeMarkdown(content)) return content;
938
+ const trimmed = content.trim();
939
+ if (trimmed.length < MIN_ENHANCE_LENGTH) return content;
940
+ const sentences = splitSentences(trimmed);
941
+ if (sentences.length === 0) return content;
942
+ const blocks = sentences.map(formatReadableSentence);
943
+ const enhanced = blocks.join("\n\n");
944
+ return enhanced || content;
945
+ }
946
+ function needsWideChatLayout(content) {
947
+ if (!content?.trim()) return false;
948
+ const prepared = enhancePlainAssistantContent(content);
949
+ return looksLikeMarkdown(prepared) || /\n\n+/.test(prepared);
950
+ }
951
+ function parseMarkdownBlocks(content) {
952
+ const lines = content.replace(/\r\n/g, "\n").split("\n");
953
+ const blocks = [];
954
+ let paragraph = [];
955
+ let bulletItems = [];
956
+ let orderedItems = [];
957
+ let codeLines = null;
958
+ let codeLanguage;
959
+ const flushParagraph = () => {
960
+ if (paragraph.length === 0) return;
961
+ blocks.push({ kind: "paragraph", text: paragraph.join("\n") });
962
+ paragraph = [];
963
+ };
964
+ const flushBullets = () => {
965
+ if (bulletItems.length === 0) return;
966
+ blocks.push({ kind: "bullet", items: bulletItems });
967
+ bulletItems = [];
968
+ };
969
+ const flushOrdered = () => {
970
+ if (orderedItems.length === 0) return;
971
+ blocks.push({ kind: "ordered", items: orderedItems });
972
+ orderedItems = [];
973
+ };
974
+ const flushLists = () => {
975
+ flushBullets();
976
+ flushOrdered();
977
+ };
978
+ const flushCode = () => {
979
+ if (codeLines === null) return;
980
+ blocks.push({
981
+ kind: "codeblock",
982
+ code: codeLines.join("\n"),
983
+ ...codeLanguage ? { language: codeLanguage } : {}
984
+ });
985
+ codeLines = null;
986
+ codeLanguage = void 0;
987
+ };
988
+ for (const line of lines) {
989
+ if (codeLines !== null) {
990
+ if (/^\s*```\s*$/.test(line)) {
991
+ flushCode();
992
+ } else {
993
+ codeLines.push(line);
994
+ }
995
+ continue;
996
+ }
997
+ const fence = FENCE_LINE.exec(line);
998
+ if (fence) {
999
+ flushParagraph();
1000
+ flushLists();
1001
+ codeLines = [];
1002
+ codeLanguage = fence[1] || void 0;
1003
+ continue;
1004
+ }
1005
+ const trimmed = line.trim();
1006
+ if (!trimmed) {
1007
+ flushParagraph();
1008
+ flushLists();
1009
+ continue;
1010
+ }
1011
+ const heading = HEADING_LINE.exec(line);
1012
+ if (heading) {
1013
+ flushParagraph();
1014
+ flushLists();
1015
+ const level = Math.min(heading[1].length, 3);
1016
+ blocks.push({ kind: "heading", level, text: heading[2].trim() });
1017
+ continue;
1018
+ }
1019
+ const ordered = ORDERED_LINE.exec(line);
1020
+ if (ordered) {
1021
+ flushParagraph();
1022
+ flushBullets();
1023
+ orderedItems.push(ordered[2].trim());
1024
+ continue;
1025
+ }
1026
+ const bullet = BULLET_LINE.exec(line);
1027
+ if (bullet) {
1028
+ flushParagraph();
1029
+ flushOrdered();
1030
+ bulletItems.push(bullet[1].trim());
1031
+ continue;
1032
+ }
1033
+ flushLists();
1034
+ paragraph.push(line);
1035
+ }
1036
+ flushParagraph();
1037
+ flushLists();
1038
+ flushCode();
1039
+ return blocks.length > 0 ? blocks : [{ kind: "paragraph", text: content }];
1040
+ }
1041
+ function parseInlineMarkdown(text) {
1042
+ if (!text) return [{ kind: "text", value: "" }];
1043
+ const segments = [];
1044
+ let lastIndex = 0;
1045
+ INLINE_PATTERN.lastIndex = 0;
1046
+ for (let match = INLINE_PATTERN.exec(text); match; match = INLINE_PATTERN.exec(text)) {
1047
+ if (match.index > lastIndex) {
1048
+ segments.push({ kind: "text", value: text.slice(lastIndex, match.index) });
1049
+ }
1050
+ if (match[1] && match[2]) {
1051
+ segments.push({ kind: "link", value: match[1].trim(), href: match[2] });
1052
+ } else if (match[3] || match[4]) {
1053
+ segments.push({ kind: "bold", value: (match[3] ?? match[4]).trim() });
1054
+ } else if (match[5]) {
1055
+ segments.push({ kind: "code", value: match[5] });
1056
+ } else if (match[6] || match[7]) {
1057
+ segments.push({ kind: "italic", value: (match[6] ?? match[7]).trim() });
1058
+ }
1059
+ lastIndex = INLINE_PATTERN.lastIndex;
1060
+ }
1061
+ if (lastIndex < text.length) {
1062
+ segments.push({ kind: "text", value: text.slice(lastIndex) });
1063
+ }
1064
+ return segments.length > 0 ? segments : [{ kind: "text", value: text }];
1065
+ }
1066
+
1067
+ // src/components/ChatMarkdown.tsx
1068
+ function segmentKey(segment, index) {
1069
+ return `${segment.kind}-${index}-${segment.value.slice(0, 12)}`;
1070
+ }
1071
+ function renderInlineSegments(text, theme, baseStyle) {
1072
+ const segments = parseInlineMarkdown(text);
1073
+ return segments.map((segment, index) => {
1074
+ const key = segmentKey(segment, index);
1075
+ switch (segment.kind) {
1076
+ case "bold":
1077
+ return /* @__PURE__ */ React7__namespace.default.createElement(reactNative.Text, { key, style: [baseStyle, styles2.bold] }, segment.value);
1078
+ case "italic":
1079
+ return /* @__PURE__ */ React7__namespace.default.createElement(reactNative.Text, { key, style: [baseStyle, styles2.italic] }, segment.value);
1080
+ case "code":
1081
+ return /* @__PURE__ */ React7__namespace.default.createElement(
1082
+ reactNative.Text,
1083
+ {
1084
+ key,
1085
+ style: [
1086
+ baseStyle,
1087
+ styles2.code,
1088
+ {
1089
+ backgroundColor: theme.codeBackground ?? (theme.variant === "user" ? "rgba(255,255,255,0.22)" : "rgba(0,0,0,0.06)"),
1090
+ color: theme.codeColor ?? theme.color
1091
+ }
1092
+ ]
1093
+ },
1094
+ segment.value
1095
+ );
1096
+ case "link":
1097
+ return /* @__PURE__ */ React7__namespace.default.createElement(
1098
+ reactNative.Text,
1099
+ {
1100
+ key,
1101
+ accessibilityRole: "link",
1102
+ style: [
1103
+ baseStyle,
1104
+ styles2.link,
1105
+ {
1106
+ color: theme.linkColor ?? (theme.variant === "user" ? theme.color : "#2563EB")
1107
+ }
1108
+ ],
1109
+ onPress: () => {
1110
+ reactNative.Linking.openURL(segment.href).catch(() => {
1111
+ });
1112
+ }
1113
+ },
1114
+ segment.value
1115
+ );
1116
+ default:
1117
+ return segment.value;
1118
+ }
1119
+ });
1120
+ }
1121
+ function InlineMarkdown({
1122
+ text,
1123
+ theme
1124
+ }) {
1125
+ const baseStyle = {
1126
+ color: theme.color,
1127
+ fontFamily: theme.fontFamily,
1128
+ fontSize: theme.fontSize,
1129
+ lineHeight: theme.lineHeight
1130
+ };
1131
+ return /* @__PURE__ */ React7__namespace.default.createElement(reactNative.Text, { style: baseStyle }, renderInlineSegments(text, theme, baseStyle));
1132
+ }
1133
+ function ChatMarkdown({ content, theme, contentWidth }) {
1134
+ const prepared = enhancePlainAssistantContent(content);
1135
+ const baseTextStyle = {
1136
+ color: theme.color,
1137
+ fontFamily: theme.fontFamily,
1138
+ fontSize: theme.fontSize,
1139
+ lineHeight: theme.lineHeight
1140
+ };
1141
+ const rootStyle = contentWidth ? [styles2.root, { width: contentWidth }] : styles2.root;
1142
+ if (!looksLikeMarkdown(prepared)) {
1143
+ const paragraphs = prepared.split(/\n\n+/).map((part) => part.trim()).filter(Boolean);
1144
+ if (paragraphs.length > 1) {
1145
+ return /* @__PURE__ */ React7__namespace.default.createElement(reactNative.View, { style: rootStyle }, paragraphs.map((paragraph, index) => /* @__PURE__ */ React7__namespace.default.createElement(reactNative.View, { key: `plain-p-${index}`, style: index > 0 ? styles2.blockGap : void 0 }, /* @__PURE__ */ React7__namespace.default.createElement(reactNative.Text, { style: baseTextStyle }, paragraph))));
1146
+ }
1147
+ return /* @__PURE__ */ React7__namespace.default.createElement(reactNative.Text, { style: baseTextStyle }, prepared);
1148
+ }
1149
+ const blocks = parseMarkdownBlocks(prepared);
1150
+ return /* @__PURE__ */ React7__namespace.default.createElement(reactNative.View, { style: rootStyle }, blocks.map((block, blockIndex) => {
1151
+ if (block.kind === "paragraph") {
1152
+ return /* @__PURE__ */ React7__namespace.default.createElement(reactNative.View, { key: `p-${blockIndex}`, style: blockIndex > 0 ? styles2.blockGap : void 0 }, /* @__PURE__ */ React7__namespace.default.createElement(InlineMarkdown, { text: block.text, theme }));
1153
+ }
1154
+ if (block.kind === "heading") {
1155
+ const scale = block.level === 1 ? 1.25 : block.level === 2 ? 1.15 : 1.05;
1156
+ const headingSize = Math.round((theme.fontSize ?? 15) * scale);
1157
+ return /* @__PURE__ */ React7__namespace.default.createElement(reactNative.View, { key: `h-${blockIndex}`, style: blockIndex > 0 ? styles2.blockGap : void 0 }, /* @__PURE__ */ React7__namespace.default.createElement(
1158
+ reactNative.Text,
1159
+ {
1160
+ accessibilityRole: "header",
1161
+ style: [
1162
+ baseTextStyle,
1163
+ styles2.bold,
1164
+ { fontSize: headingSize, lineHeight: Math.round(headingSize * 1.35) }
1165
+ ]
1166
+ },
1167
+ renderInlineSegments(block.text, theme, {
1168
+ ...baseTextStyle,
1169
+ fontSize: headingSize,
1170
+ lineHeight: Math.round(headingSize * 1.35)
1171
+ })
1172
+ ));
1173
+ }
1174
+ if (block.kind === "codeblock") {
1175
+ return /* @__PURE__ */ React7__namespace.default.createElement(
1176
+ reactNative.View,
1177
+ {
1178
+ key: `code-${blockIndex}`,
1179
+ style: [
1180
+ styles2.codeBlock,
1181
+ blockIndex > 0 ? styles2.blockGap : void 0,
1182
+ {
1183
+ backgroundColor: theme.codeBackground ?? (theme.variant === "user" ? "rgba(255,255,255,0.18)" : "rgba(0,0,0,0.055)")
1184
+ }
1185
+ ]
1186
+ },
1187
+ /* @__PURE__ */ React7__namespace.default.createElement(
1188
+ reactNative.Text,
1189
+ {
1190
+ style: [
1191
+ styles2.code,
1192
+ {
1193
+ color: theme.codeColor ?? theme.color,
1194
+ fontSize: (theme.fontSize ?? 15) - 1,
1195
+ lineHeight: Math.round(((theme.fontSize ?? 15) - 1) * 1.45)
1196
+ }
1197
+ ]
1198
+ },
1199
+ block.code
1200
+ )
1201
+ );
1202
+ }
1203
+ if (block.kind === "bullet") {
1204
+ return /* @__PURE__ */ React7__namespace.default.createElement(reactNative.View, { key: `ul-${blockIndex}`, style: blockIndex > 0 ? styles2.blockGap : void 0 }, block.items.map((item, itemIndex) => /* @__PURE__ */ React7__namespace.default.createElement(
1205
+ reactNative.Text,
1206
+ {
1207
+ key: `ul-${blockIndex}-${itemIndex}`,
1208
+ style: [baseTextStyle, itemIndex > 0 ? styles2.listItemGap : void 0]
1209
+ },
1210
+ "\u2022 ",
1211
+ renderInlineSegments(item, theme, baseTextStyle)
1212
+ )));
1213
+ }
1214
+ return /* @__PURE__ */ React7__namespace.default.createElement(reactNative.View, { key: `ol-${blockIndex}`, style: blockIndex > 0 ? styles2.blockGap : void 0 }, block.items.map((item, itemIndex) => /* @__PURE__ */ React7__namespace.default.createElement(
1215
+ reactNative.Text,
1216
+ {
1217
+ key: `ol-${blockIndex}-${itemIndex}`,
1218
+ style: [baseTextStyle, itemIndex > 0 ? styles2.listItemGap : void 0]
1219
+ },
1220
+ `${itemIndex + 1}. `,
1221
+ renderInlineSegments(item, theme, baseTextStyle)
1222
+ )));
1223
+ }));
1224
+ }
1225
+ var styles2 = reactNative.StyleSheet.create({
1226
+ root: {
1227
+ flexShrink: 1,
1228
+ alignSelf: "stretch"
1229
+ },
1230
+ blockGap: {
1231
+ marginTop: 8
1232
+ },
1233
+ listItemGap: {
1234
+ marginTop: 4
1235
+ },
1236
+ bold: {
1237
+ fontWeight: "700"
1238
+ },
1239
+ italic: {
1240
+ fontStyle: "italic"
1241
+ },
1242
+ code: {
1243
+ fontFamily: "Menlo",
1244
+ borderRadius: 4,
1245
+ paddingHorizontal: 4,
1246
+ paddingVertical: 1
1247
+ },
1248
+ codeBlock: {
1249
+ borderRadius: 8,
1250
+ paddingHorizontal: 10,
1251
+ paddingVertical: 8,
1252
+ alignSelf: "stretch"
1253
+ },
1254
+ link: {
1255
+ textDecorationLine: "underline"
1256
+ }
1257
+ });
1258
+ var ThemeContext = React7.createContext(defaultLightTheme);
1259
+ function AppilotsThemeProvider({
1260
+ theme,
1261
+ mode = "auto",
1262
+ children
1263
+ }) {
1264
+ const systemScheme = reactNative.useColorScheme();
1265
+ const tokens = React7.useMemo(
1266
+ () => mergeThemeTokens(resolveBaseTheme(mode, systemScheme), theme ?? void 0),
1267
+ [mode, systemScheme, theme]
1268
+ );
1269
+ return /* @__PURE__ */ React7__namespace.default.createElement(ThemeContext.Provider, { value: tokens }, children);
1270
+ }
1271
+ function useAppilotsTheme() {
1272
+ return React7.useContext(ThemeContext);
1273
+ }
1274
+
1275
+ // src/theme/tailwindBridge.ts
1276
+ var PREFERRED_SHADES = ["500", "600", "400", "700", "300", "800", "200", "900"];
1277
+ function pickColor(value) {
1278
+ if (!value) return void 0;
1279
+ if (typeof value === "string") return value;
1280
+ for (const shade of PREFERRED_SHADES) {
1281
+ if (typeof value[shade] === "string") return value[shade];
1282
+ }
1283
+ for (const v of Object.values(value)) {
1284
+ if (typeof v === "string") return v;
1285
+ }
1286
+ return void 0;
1287
+ }
1288
+ function parseSize(value) {
1289
+ if (typeof value === "number") return value;
1290
+ if (Array.isArray(value)) return parseSize(value[0]);
1291
+ if (typeof value !== "string") return void 0;
1292
+ const trimmed = value.trim();
1293
+ if (trimmed.endsWith("rem")) {
1294
+ const n2 = parseFloat(trimmed);
1295
+ if (!Number.isNaN(n2)) return Math.round(n2 * 16);
1296
+ }
1297
+ if (trimmed.endsWith("px")) {
1298
+ const n2 = parseFloat(trimmed);
1299
+ if (!Number.isNaN(n2)) return Math.round(n2);
1300
+ }
1301
+ const n = parseFloat(trimmed);
1302
+ return Number.isNaN(n) ? void 0 : Math.round(n);
1303
+ }
1304
+ function pickFontFamily(value) {
1305
+ if (!value) return void 0;
1306
+ if (typeof value === "string") return value;
1307
+ return value[0];
1308
+ }
1309
+ function appilotsThemeFromTailwind(config) {
1310
+ const colors = config.theme?.colors ?? {};
1311
+ const out = {};
1312
+ const c = {};
1313
+ const primary = pickColor(colors.primary);
1314
+ if (primary) c.primary = primary;
1315
+ const secondary = pickColor(colors.secondary ?? colors.accent);
1316
+ if (secondary) c.secondary = secondary;
1317
+ const bg = pickColor(colors.background ?? colors.white);
1318
+ if (bg) c.background = bg;
1319
+ const surface = pickColor(colors.surface ?? colors.gray ?? colors.slate);
1320
+ if (surface) c.surface = surface;
1321
+ const textColor = pickColor(colors.text ?? colors.foreground ?? colors.black);
1322
+ if (textColor) c.text = textColor;
1323
+ const muted = pickColor(colors.muted ?? colors.gray);
1324
+ if (muted && muted !== c.text) c.textSecondary = muted;
1325
+ const border = pickColor(colors.border ?? colors.gray);
1326
+ if (border) c.border = border;
1327
+ const success = pickColor(colors.success ?? colors.green ?? colors.emerald);
1328
+ if (success) c.success = success;
1329
+ const warning = pickColor(colors.warning ?? colors.yellow ?? colors.amber);
1330
+ if (warning) c.warning = warning;
1331
+ const error = pickColor(colors.error ?? colors.danger ?? colors.red);
1332
+ if (error) c.error = error;
1333
+ if (Object.keys(c).length > 0) out.colors = c;
1334
+ const fontFamily = pickFontFamily(
1335
+ config.theme?.fontFamily?.sans ?? config.theme?.fontFamily?.body
1336
+ );
1337
+ const sizeXs = parseSize(config.theme?.fontSize?.xs);
1338
+ const sizeSm = parseSize(config.theme?.fontSize?.sm);
1339
+ const sizeBase = parseSize(config.theme?.fontSize?.base);
1340
+ const sizeLg = parseSize(config.theme?.fontSize?.lg);
1341
+ const typography = {};
1342
+ if (fontFamily) typography.fontFamily = fontFamily;
1343
+ if (sizeXs) typography.fontSizeXs = sizeXs;
1344
+ if (sizeSm) typography.fontSizeSm = sizeSm;
1345
+ if (sizeBase) typography.fontSizeBase = sizeBase;
1346
+ if (sizeLg) typography.fontSizeLg = sizeLg;
1347
+ if (Object.keys(typography).length > 0) out.typography = typography;
1348
+ const radiiSm = parseSize(config.theme?.borderRadius?.sm);
1349
+ const radiiMd = parseSize(config.theme?.borderRadius?.md);
1350
+ const radiiLg = parseSize(config.theme?.borderRadius?.lg);
1351
+ const radii = {};
1352
+ if (radiiSm) radii.sm = radiiSm;
1353
+ if (radiiMd) radii.md = radiiMd;
1354
+ if (radiiLg) radii.lg = radiiLg;
1355
+ if (Object.keys(radii).length > 0) out.radii = radii;
1356
+ return out;
1357
+ }
1358
+ var appilotsTheme = {
1359
+ fromTailwind: appilotsThemeFromTailwind
1360
+ };
1361
+
1362
+ // src/i18n/bundles/pt-BR.ts
1363
+ var ptBR = {
1364
+ chatTitle: "Assistente Appilots",
1365
+ clearButton: "Limpar",
1366
+ inputPlaceholder: "Digite uma mensagem...",
1367
+ emptyTitle: "Como posso ajudar?",
1368
+ emptySubtitle: "Navego, preencho formul\xE1rios e executo a\xE7\xF5es neste app.",
1369
+ thinking: "Pensando...",
1370
+ statusAnalyzing: "Analisando a tela...",
1371
+ statusWaitingApp: "Aguardando o app responder...",
1372
+ statusAdjusting: "Ajustando o plano...",
1373
+ poweredBy: "Powered by Appilots",
1374
+ approve: "Aprovar",
1375
+ reject: "Rejeitar",
1376
+ cancelledByUser: "Cancelado pelo usu\xE1rio",
1377
+ unknownAction: "A\xE7\xE3o desconhecida",
1378
+ somethingWentWrong: "Algo deu errado",
1379
+ openChatA11y: "Abrir chat do assistente",
1380
+ closeChatA11y: "Fechar chat do assistente",
1381
+ stopGeneratingA11y: "Parar gera\xE7\xE3o",
1382
+ talkToHumanA11y: "Falar com um atendente humano",
1383
+ humanAgentLabel: "Atendente",
1384
+ escalationRequested: "Certo! Chamei um atendente humano. Voc\xEA pode continuar usando o app normalmente enquanto isso.",
1385
+ escalationConnected: "Um atendente entrou na conversa.",
1386
+ escalationResolved: "O atendimento humano foi encerrado. Voltei a te ajudar por aqui.",
1387
+ escalationOffer: "Se preferir, posso chamar uma pessoa para ajudar.",
1388
+ escalationOfferChip: "Falar com um atendente",
1389
+ escalationPendingBanner: "Aguardando um atendente...",
1390
+ escalationActiveBanner: "Voc\xEA est\xE1 falando com um atendente"
1391
+ };
1392
+
1393
+ // src/i18n/bundles/en.ts
1394
+ var en = {
1395
+ chatTitle: "Appilots Assistant",
1396
+ clearButton: "Clear",
1397
+ inputPlaceholder: "Type a message...",
1398
+ emptyTitle: "How can I help?",
1399
+ emptySubtitle: "I navigate, fill forms, and run actions in this app.",
1400
+ thinking: "Thinking...",
1401
+ statusAnalyzing: "Reading the screen...",
1402
+ statusWaitingApp: "Waiting for the app...",
1403
+ statusAdjusting: "Adjusting the plan...",
1404
+ poweredBy: "Powered by Appilots",
1405
+ approve: "Approve",
1406
+ reject: "Reject",
1407
+ cancelledByUser: "Cancelled by user",
1408
+ unknownAction: "Unknown action",
1409
+ somethingWentWrong: "Something went wrong",
1410
+ openChatA11y: "Open assistant chat",
1411
+ closeChatA11y: "Close assistant chat",
1412
+ stopGeneratingA11y: "Stop generating",
1413
+ talkToHumanA11y: "Talk to a human agent",
1414
+ humanAgentLabel: "Agent",
1415
+ escalationRequested: "Done! I've called a human agent. You can keep using the app normally in the meantime.",
1416
+ escalationConnected: "A human agent joined the conversation.",
1417
+ escalationResolved: "The human handoff has ended. I'm back to help you here.",
1418
+ escalationOffer: "If you prefer, I can bring in a person to help.",
1419
+ escalationOfferChip: "Talk to a human",
1420
+ escalationPendingBanner: "Waiting for a human agent...",
1421
+ escalationActiveBanner: "You're talking to a human agent"
1422
+ };
1423
+
1424
+ // src/i18n/bundles/es.ts
1425
+ var es = {
1426
+ chatTitle: "Asistente Appilots",
1427
+ clearButton: "Limpiar",
1428
+ inputPlaceholder: "Escribe un mensaje...",
1429
+ emptyTitle: "\xBFEn qu\xE9 puedo ayudarte?",
1430
+ emptySubtitle: "Navego, relleno formularios y ejecuto acciones en esta app.",
1431
+ thinking: "Pensando...",
1432
+ statusAnalyzing: "Analizando la pantalla...",
1433
+ statusWaitingApp: "Esperando a la app...",
1434
+ statusAdjusting: "Ajustando el plan...",
1435
+ poweredBy: "Hecho con Appilots",
1436
+ approve: "Aprobar",
1437
+ reject: "Rechazar",
1438
+ cancelledByUser: "Cancelado por el usuario",
1439
+ unknownAction: "Acci\xF3n desconocida",
1440
+ somethingWentWrong: "Algo sali\xF3 mal",
1441
+ openChatA11y: "Abrir chat del asistente",
1442
+ closeChatA11y: "Cerrar chat del asistente",
1443
+ stopGeneratingA11y: "Detener generaci\xF3n",
1444
+ talkToHumanA11y: "Hablar con un agente humano",
1445
+ humanAgentLabel: "Agente",
1446
+ escalationRequested: "\xA1Listo! Llam\xE9 a un agente humano. Mientras tanto puedes seguir usando la app con normalidad.",
1447
+ escalationConnected: "Un agente humano se uni\xF3 a la conversaci\xF3n.",
1448
+ escalationResolved: "La atenci\xF3n humana termin\xF3. Vuelvo a ayudarte por aqu\xED.",
1449
+ escalationOffer: "Si prefieres, puedo llamar a una persona para ayudarte.",
1450
+ escalationOfferChip: "Hablar con un agente",
1451
+ escalationPendingBanner: "Esperando a un agente...",
1452
+ escalationActiveBanner: "Est\xE1s hablando con un agente humano"
1453
+ };
1454
+ var BUNDLES = {
1455
+ "pt-BR": ptBR,
1456
+ en,
1457
+ es
1458
+ };
1459
+ var DEFAULT_LOCALE = "pt-BR";
1460
+ function detectDeviceLocale() {
1461
+ try {
1462
+ let raw;
1463
+ if (reactNative.Platform.OS === "ios") {
1464
+ const settings = reactNative.NativeModules?.SettingsManager?.settings;
1465
+ raw = settings?.AppleLocale || (Array.isArray(settings?.AppleLanguages) ? settings?.AppleLanguages?.[0] : void 0);
1466
+ } else if (reactNative.Platform.OS === "android") {
1467
+ raw = reactNative.NativeModules?.I18nManager?.localeIdentifier;
1468
+ }
1469
+ if (!raw || typeof raw !== "string") return null;
1470
+ const lower = raw.toLowerCase().replace("_", "-");
1471
+ if (lower.startsWith("pt")) return "pt-BR";
1472
+ if (lower.startsWith("es")) return "es";
1473
+ if (lower.startsWith("en")) return "en";
1474
+ return null;
1475
+ } catch {
1476
+ return null;
1477
+ }
1478
+ }
1479
+ function resolveLocale(prop) {
1480
+ if (prop && BUNDLES[prop]) return prop;
1481
+ const detected = detectDeviceLocale();
1482
+ if (detected && BUNDLES[detected]) return detected;
1483
+ return DEFAULT_LOCALE;
1484
+ }
1485
+ var I18nContext = React7.createContext(null);
1486
+ function AppilotsI18nProvider({
1487
+ locale,
1488
+ overrides,
1489
+ children
1490
+ }) {
1491
+ const value = React7.useMemo(() => {
1492
+ const resolved = resolveLocale(locale ?? null);
1493
+ const merged = overrides ? { ...BUNDLES[resolved], ...overrides } : BUNDLES[resolved];
1494
+ return {
1495
+ locale: resolved,
1496
+ strings: merged,
1497
+ t: (key) => merged[key]
1498
+ };
1499
+ }, [locale, overrides]);
1500
+ return /* @__PURE__ */ React7__namespace.default.createElement(I18nContext.Provider, { value }, children);
1501
+ }
1502
+ function useAppilotsI18n() {
1503
+ const ctx = React7.useContext(I18nContext);
1504
+ if (ctx) return ctx;
1505
+ return {
1506
+ locale: DEFAULT_LOCALE,
1507
+ strings: BUNDLES[DEFAULT_LOCALE],
1508
+ t: (key) => BUNDLES[DEFAULT_LOCALE][key]
1509
+ };
1510
+ }
1511
+
1512
+ // src/components/AppilotsChat.tsx
1513
+ function translateLegacyTheme(legacy) {
1514
+ const out = {};
1515
+ if (legacy.primaryColor || legacy.backgroundColor || legacy.textColor || legacy.inputBackgroundColor) {
1516
+ out.colors = {};
1517
+ if (legacy.primaryColor) out.colors.primary = legacy.primaryColor;
1518
+ if (legacy.backgroundColor) out.colors.background = legacy.backgroundColor;
1519
+ if (legacy.textColor) out.colors.text = legacy.textColor;
1520
+ if (legacy.inputBackgroundColor) out.colors.surface = legacy.inputBackgroundColor;
1521
+ }
1522
+ if (legacy.borderRadius !== void 0) {
1523
+ out.radii = { lg: legacy.borderRadius, md: legacy.borderRadius };
1524
+ }
1525
+ if (legacy.fontFamily) {
1526
+ out.typography = { fontFamily: legacy.fontFamily };
1527
+ }
1528
+ return out;
1529
+ }
1530
+ function isLegacyTheme(theme) {
1531
+ if (!theme || typeof theme !== "object") return false;
1532
+ const t = theme;
1533
+ return "primaryColor" in t || "backgroundColor" in t || "textColor" in t || "inputBackgroundColor" in t || typeof t.borderRadius === "number" || typeof t.fontFamily === "string" && !("typography" in t);
1534
+ }
1535
+ function isImageSource(value) {
1536
+ return typeof value === "number" || /^https?:\/\//i.test(value.trim());
1537
+ }
1538
+ var { height: SCREEN_HEIGHT, width: SCREEN_WIDTH } = reactNative.Dimensions.get("window");
1539
+ var CHAT_HORIZONTAL_PADDING = 16;
1540
+ var BUBBLE_HORIZONTAL_PADDING = 14;
1541
+ var ASSISTANT_CONTENT_WIDTH = SCREEN_WIDTH - CHAT_HORIZONTAL_PADDING * 2 - BUBBLE_HORIZONTAL_PADDING * 2;
1542
+ var APPILOTS_SKIP_PROPS = {
1543
+ __appilotsSkip: true,
1544
+ __appilotsInternal: true
1545
+ };
1546
+ function AppilotsChat(props) {
1547
+ const { remotePersonalization } = chunkSIBKF7AA_js.useAppilotsContext();
1548
+ const themeProp = React7.useMemo(() => {
1549
+ if (!props.theme) return void 0;
1550
+ return isLegacyTheme(props.theme) ? translateLegacyTheme(props.theme) : props.theme;
1551
+ }, [props.theme]);
1552
+ return /* @__PURE__ */ React7__namespace.default.createElement(
1553
+ AppilotsThemeProvider,
1554
+ {
1555
+ theme: resolveTheme(themeProp, remotePersonalization),
1556
+ mode: resolveThemeMode(props.themeMode, remotePersonalization)
1557
+ },
1558
+ /* @__PURE__ */ React7__namespace.default.createElement(AppilotsI18nProvider, { locale: resolveLocaleProp(props.locale, remotePersonalization) }, /* @__PURE__ */ React7__namespace.default.createElement(AppilotsChatInner, { ...props }))
1559
+ );
1560
+ }
1561
+ function AppilotsChatInner({
1562
+ visible: controlledVisible,
1563
+ onClose,
1564
+ placeholder,
1565
+ headerTitle: headerTitleProp,
1566
+ autoExecute = true,
1567
+ assistantName: assistantNameProp,
1568
+ assistantAvatar: assistantAvatarProp,
1569
+ emptyStateIcon: emptyStateIconProp,
1570
+ welcomeMessage: welcomeMessageProp,
1571
+ poweredByVisible: poweredByVisibleProp,
1572
+ mode = "bubble",
1573
+ position = "bottom-right",
1574
+ triggerButton = "default",
1575
+ triggerIcon,
1576
+ triggerButtonColor: triggerButtonColorProp,
1577
+ triggerButtonImage: triggerButtonImageProp
1578
+ }) {
1579
+ const theme = useAppilotsTheme();
1580
+ const { strings, t } = useAppilotsI18n();
1581
+ const {
1582
+ messages,
1583
+ isLoading,
1584
+ loadingStatusKey,
1585
+ sendMessage,
1586
+ cancelMessage,
1587
+ clearMessages,
1588
+ escalation,
1589
+ requestHuman
1590
+ } = chunkIASJ7YHC_js.useAppilotsChat({
1591
+ errorPrefix: t("somethingWentWrong"),
1592
+ escalationStrings: {
1593
+ requested: t("escalationRequested"),
1594
+ connected: t("escalationConnected"),
1595
+ resolved: t("escalationResolved"),
1596
+ offer: t("escalationOffer")
1597
+ }
1598
+ });
1599
+ const {
1600
+ pendingActions,
1601
+ executingActions,
1602
+ completedActions,
1603
+ approveAction,
1604
+ rejectAction
1605
+ } = chunkIASJ7YHC_js.useAppilotsActions({ autoExecute });
1606
+ const { emit, remotePersonalization } = chunkSIBKF7AA_js.useAppilotsContext();
1607
+ const {
1608
+ headerTitle: resolvedTitle,
1609
+ assistantAvatar,
1610
+ emptyStateIcon,
1611
+ welcomeMessage,
1612
+ poweredByVisible,
1613
+ triggerButtonColor,
1614
+ triggerButtonImage
1615
+ } = resolvePersonalization(
1616
+ {
1617
+ headerTitle: headerTitleProp,
1618
+ assistantName: assistantNameProp,
1619
+ assistantAvatar: assistantAvatarProp,
1620
+ emptyStateIcon: emptyStateIconProp,
1621
+ welcomeMessage: welcomeMessageProp,
1622
+ poweredByVisible: poweredByVisibleProp,
1623
+ triggerButtonColor: triggerButtonColorProp,
1624
+ triggerButtonImage: triggerButtonImageProp
1625
+ },
1626
+ remotePersonalization
1627
+ );
1628
+ const allActions = [...pendingActions, ...executingActions, ...completedActions];
1629
+ const timeline = buildChatTimeline(messages, allActions);
1630
+ const lastAssistantMessageId = React7__namespace.default.useMemo(() => {
1631
+ for (let i = messages.length - 1; i >= 0; i--) {
1632
+ if (messages[i].role === "assistant") return messages[i].id;
1633
+ }
1634
+ return void 0;
1635
+ }, [messages]);
1636
+ const insets = reactNativeSafeAreaContext.useSafeAreaInsets();
1637
+ const [internalVisible, setInternalVisible] = React7.useState(mode === "inline");
1638
+ const [inputText, setInputText] = React7.useState("");
1639
+ const flatListRef = React7.useRef(null);
1640
+ const slideAnim = React7.useRef(new reactNative.Animated.Value(SCREEN_HEIGHT)).current;
1641
+ const isVisible = mode === "inline" ? true : controlledVisible !== void 0 ? controlledVisible : internalVisible;
1642
+ const showSuggestedPrompts = chunkIASJ7YHC_js.shouldShowSuggestedPrompts({
1643
+ isVisible,
1644
+ messageCount: messages.length,
1645
+ inputText
1646
+ });
1647
+ const { prompts: suggestedPrompts } = chunkIASJ7YHC_js.useSuggestedPrompts({
1648
+ enabled: showSuggestedPrompts,
1649
+ limit: 3
1650
+ });
1651
+ const openChat = React7.useCallback(() => {
1652
+ setInternalVisible(true);
1653
+ emit({ type: "chat:open", timestamp: Date.now(), data: {} });
1654
+ }, [emit]);
1655
+ const closeChat = React7.useCallback(() => {
1656
+ setInternalVisible(false);
1657
+ onClose?.();
1658
+ emit({ type: "chat:close", timestamp: Date.now(), data: {} });
1659
+ }, [onClose, emit]);
1660
+ React7.useEffect(() => {
1661
+ if (mode === "inline") return;
1662
+ reactNative.Animated.spring(slideAnim, {
1663
+ toValue: isVisible ? 0 : SCREEN_HEIGHT,
1664
+ useNativeDriver: true,
1665
+ tension: 65,
1666
+ friction: 11
1667
+ }).start();
1668
+ }, [isVisible, slideAnim, mode]);
1669
+ React7.useEffect(() => {
1670
+ if (messages.length > 0) {
1671
+ setTimeout(() => flatListRef.current?.scrollToEnd({ animated: true }), 100);
1672
+ }
1673
+ }, [messages.length]);
1674
+ const handleSend = React7.useCallback(() => {
1675
+ if (!inputText.trim()) return;
1676
+ sendMessage(inputText.trim());
1677
+ setInputText("");
1678
+ }, [inputText, sendMessage]);
1679
+ const renderMessage = React7.useCallback(
1680
+ ({ item }) => {
1681
+ if (item.role === "system") {
1682
+ const isOffer = item.metadata?.escalationOffer === true;
1683
+ return /* @__PURE__ */ React7__namespace.default.createElement(reactNative.View, { style: styles3.systemMessageContainer }, /* @__PURE__ */ React7__namespace.default.createElement(
1684
+ reactNative.Text,
1685
+ {
1686
+ style: [
1687
+ styles3.systemMessageText,
1688
+ {
1689
+ color: theme.colors.textSecondary,
1690
+ fontFamily: theme.typography.fontFamily,
1691
+ fontSize: theme.typography.fontSizeSm
1692
+ }
1693
+ ]
1694
+ },
1695
+ item.content
1696
+ ), isOffer && !escalation && /* @__PURE__ */ React7__namespace.default.createElement(
1697
+ reactNative.TouchableOpacity,
1698
+ {
1699
+ ...APPILOTS_SKIP_PROPS,
1700
+ style: [
1701
+ styles3.chip,
1702
+ styles3.escalationOfferChip,
1703
+ {
1704
+ backgroundColor: theme.colors.surface,
1705
+ borderColor: theme.colors.border,
1706
+ borderRadius: 999
1707
+ }
1708
+ ],
1709
+ onPress: () => requestHuman("agent_gave_up"),
1710
+ activeOpacity: 0.7,
1711
+ accessibilityRole: "button",
1712
+ accessibilityLabel: strings.talkToHumanA11y,
1713
+ testID: "escalation-offer-chip"
1714
+ },
1715
+ /* @__PURE__ */ React7__namespace.default.createElement(HeadsetIcon, { size: 14, color: theme.colors.textSecondary }),
1716
+ /* @__PURE__ */ React7__namespace.default.createElement(
1717
+ reactNative.Text,
1718
+ {
1719
+ style: [
1720
+ styles3.chipText,
1721
+ {
1722
+ color: theme.colors.text,
1723
+ fontFamily: theme.typography.fontFamily,
1724
+ fontSize: theme.typography.fontSizeSm
1725
+ }
1726
+ ]
1727
+ },
1728
+ strings.escalationOfferChip
1729
+ )
1730
+ ));
1731
+ }
1732
+ const isUser = item.role === "user";
1733
+ const isHumanAgent = item.role === "human_agent";
1734
+ const useWideAssistantLayout = !isUser && needsWideChatLayout(item.content);
1735
+ if (isHumanAgent) {
1736
+ return /* @__PURE__ */ React7__namespace.default.createElement(reactNative.View, { style: styles3.humanAgentContainer, testID: "human-agent-message" }, /* @__PURE__ */ React7__namespace.default.createElement(reactNative.View, { style: styles3.humanAgentLabelRow }, /* @__PURE__ */ React7__namespace.default.createElement(HeadsetIcon, { size: 11, color: theme.colors.secondary }), /* @__PURE__ */ React7__namespace.default.createElement(
1737
+ reactNative.Text,
1738
+ {
1739
+ style: [
1740
+ styles3.humanAgentLabel,
1741
+ {
1742
+ color: theme.colors.textSecondary,
1743
+ fontFamily: theme.typography.fontFamily
1744
+ }
1745
+ ]
1746
+ },
1747
+ escalation?.operatorName ?? strings.humanAgentLabel
1748
+ )), /* @__PURE__ */ React7__namespace.default.createElement(
1749
+ reactNative.View,
1750
+ {
1751
+ accessibilityLabel: item.content,
1752
+ style: [
1753
+ styles3.messageBubble,
1754
+ styles3.assistantBubble,
1755
+ { backgroundColor: theme.colors.surface }
1756
+ ]
1757
+ },
1758
+ /* @__PURE__ */ React7__namespace.default.createElement(
1759
+ ChatMarkdown,
1760
+ {
1761
+ content: item.content,
1762
+ theme: {
1763
+ color: theme.colors.text,
1764
+ fontFamily: theme.typography.fontFamily,
1765
+ fontSize: theme.typography.fontSizeBase,
1766
+ lineHeight: 20,
1767
+ variant: "assistant"
1768
+ }
1769
+ }
1770
+ )
1771
+ ));
1772
+ }
1773
+ return /* @__PURE__ */ React7__namespace.default.createElement(
1774
+ reactNative.View,
1775
+ {
1776
+ testID: isUser ? void 0 : item.id === lastAssistantMessageId ? "assistant-last-message" : "assistant-message",
1777
+ accessibilityLabel: isUser ? void 0 : item.content,
1778
+ style: [
1779
+ styles3.messageBubble,
1780
+ isUser ? [styles3.userBubble, { backgroundColor: theme.colors.primary }] : [
1781
+ styles3.assistantBubble,
1782
+ useWideAssistantLayout && styles3.assistantBubbleWide,
1783
+ { backgroundColor: theme.colors.surface }
1784
+ ]
1785
+ ]
1786
+ },
1787
+ /* @__PURE__ */ React7__namespace.default.createElement(
1788
+ ChatMarkdown,
1789
+ {
1790
+ content: item.content,
1791
+ contentWidth: useWideAssistantLayout ? ASSISTANT_CONTENT_WIDTH : void 0,
1792
+ theme: {
1793
+ color: isUser ? theme.colors.userBubbleText : theme.colors.bubbleText,
1794
+ fontFamily: theme.typography.fontFamily,
1795
+ fontSize: theme.typography.fontSizeBase,
1796
+ lineHeight: 20,
1797
+ variant: isUser ? "user" : "assistant"
1798
+ }
1799
+ }
1800
+ )
1801
+ );
1802
+ },
1803
+ [theme, lastAssistantMessageId, escalation, requestHuman, strings]
1804
+ );
1805
+ const requireApproval = React7.useCallback(
1806
+ (action) => {
1807
+ if (action.status !== "pending") return false;
1808
+ if (action.type === "confirm") return true;
1809
+ return !autoExecute;
1810
+ },
1811
+ [autoExecute]
1812
+ );
1813
+ const renderBreadcrumb = React7.useCallback(
1814
+ (actions) => /* @__PURE__ */ React7__namespace.default.createElement(
1815
+ ActionBreadcrumb,
1816
+ {
1817
+ actions,
1818
+ primaryColor: theme.colors.primary,
1819
+ textColor: theme.colors.text,
1820
+ fontFamily: theme.typography.fontFamily,
1821
+ palette: {
1822
+ textSecondary: theme.colors.textSecondary,
1823
+ surface: theme.colors.surface,
1824
+ border: theme.colors.border,
1825
+ success: theme.colors.success,
1826
+ warning: theme.colors.warning,
1827
+ error: theme.colors.error
1828
+ },
1829
+ requireApprovalFor: requireApproval,
1830
+ onApprove: approveAction,
1831
+ onReject: rejectAction
1832
+ }
1833
+ ),
1834
+ [
1835
+ theme.colors.primary,
1836
+ theme.colors.text,
1837
+ theme.colors.textSecondary,
1838
+ theme.colors.surface,
1839
+ theme.colors.border,
1840
+ theme.colors.success,
1841
+ theme.colors.warning,
1842
+ theme.colors.error,
1843
+ theme.typography.fontFamily,
1844
+ requireApproval,
1845
+ approveAction,
1846
+ rejectAction
1847
+ ]
1848
+ );
1849
+ const resolvedHeaderTitle = resolvedTitle ?? t("chatTitle");
1850
+ const resolvedPlaceholder = placeholder ?? t("inputPlaceholder");
1851
+ const resolvedEmptyTitle = t("emptyTitle");
1852
+ const resolvedEmptySubtitle = welcomeMessage ?? t("emptySubtitle");
1853
+ const showEmptySubtitle = resolvedEmptySubtitle.length > 0 && !(showSuggestedPrompts && suggestedPrompts.length > 0);
1854
+ const renderAvatar = () => {
1855
+ if (!assistantAvatar) {
1856
+ return /* @__PURE__ */ React7__namespace.default.createElement(reactNative.View, { style: [styles3.headerDot, { backgroundColor: theme.colors.primary }] });
1857
+ }
1858
+ if (typeof assistantAvatar === "string") {
1859
+ return /* @__PURE__ */ React7__namespace.default.createElement(reactNative.Image, { source: { uri: assistantAvatar }, style: styles3.headerAvatar });
1860
+ }
1861
+ if (typeof assistantAvatar === "number") {
1862
+ return /* @__PURE__ */ React7__namespace.default.createElement(reactNative.Image, { source: assistantAvatar, style: styles3.headerAvatar });
1863
+ }
1864
+ return /* @__PURE__ */ React7__namespace.default.createElement(reactNative.View, { style: styles3.headerAvatarSlot }, assistantAvatar);
1865
+ };
1866
+ const showTrigger = mode === "bubble" && !isVisible && controlledVisible === void 0 && triggerButton !== "none";
1867
+ const fabPositionStyle = (() => {
1868
+ switch (position) {
1869
+ case "bottom-left":
1870
+ return { bottom: 24, left: 24 };
1871
+ case "top-right":
1872
+ return { top: 24, right: 24 };
1873
+ case "top-left":
1874
+ return { top: 24, left: 24 };
1875
+ case "bottom-right":
1876
+ default:
1877
+ return { bottom: 24, right: 24 };
1878
+ }
1879
+ })();
1880
+ const chatSurface = /* @__PURE__ */ React7__namespace.default.createElement(
1881
+ reactNative.View,
1882
+ {
1883
+ ...APPILOTS_SKIP_PROPS,
1884
+ style: [
1885
+ styles3.chatContainer,
1886
+ mode === "fullscreen" && styles3.chatContainerFullscreen,
1887
+ mode === "sidebar" && styles3.chatContainerSidebar,
1888
+ mode === "inline" && styles3.chatContainerInline,
1889
+ {
1890
+ backgroundColor: theme.colors.background,
1891
+ borderTopLeftRadius: theme.radii.lg,
1892
+ borderTopRightRadius: theme.radii.lg
1893
+ }
1894
+ ]
1895
+ },
1896
+ /* @__PURE__ */ React7__namespace.default.createElement(reactNative.View, { style: [styles3.header, { borderBottomColor: theme.colors.border }] }, /* @__PURE__ */ React7__namespace.default.createElement(reactNative.View, { style: styles3.headerLeft }, renderAvatar(), /* @__PURE__ */ React7__namespace.default.createElement(
1897
+ reactNative.Text,
1898
+ {
1899
+ style: [
1900
+ styles3.headerTitle,
1901
+ {
1902
+ color: theme.colors.text,
1903
+ fontFamily: theme.typography.fontFamily,
1904
+ fontSize: theme.typography.fontSizeLg
1905
+ }
1906
+ ]
1907
+ },
1908
+ resolvedHeaderTitle
1909
+ )), /* @__PURE__ */ React7__namespace.default.createElement(reactNative.View, { style: styles3.headerActions }, /* @__PURE__ */ React7__namespace.default.createElement(
1910
+ reactNative.TouchableOpacity,
1911
+ {
1912
+ ...APPILOTS_SKIP_PROPS,
1913
+ onPress: () => requestHuman("user_requested"),
1914
+ style: styles3.headerButton,
1915
+ accessibilityRole: "button",
1916
+ accessibilityLabel: strings.talkToHumanA11y,
1917
+ testID: "escalation-header-button"
1918
+ },
1919
+ /* @__PURE__ */ React7__namespace.default.createElement(
1920
+ HeadsetIcon,
1921
+ {
1922
+ size: 16,
1923
+ color: escalation ? theme.colors.primary : theme.colors.textSecondary
1924
+ }
1925
+ )
1926
+ ), /* @__PURE__ */ React7__namespace.default.createElement(reactNative.TouchableOpacity, { ...APPILOTS_SKIP_PROPS, onPress: clearMessages, style: styles3.headerButton }, /* @__PURE__ */ React7__namespace.default.createElement(reactNative.Text, { style: [styles3.headerButtonText, { color: theme.colors.textSecondary }] }, strings.clearButton)), mode !== "inline" && /* @__PURE__ */ React7__namespace.default.createElement(
1927
+ reactNative.TouchableOpacity,
1928
+ {
1929
+ ...APPILOTS_SKIP_PROPS,
1930
+ onPress: closeChat,
1931
+ style: styles3.closeButton,
1932
+ accessibilityLabel: strings.closeChatA11y
1933
+ },
1934
+ /* @__PURE__ */ React7__namespace.default.createElement(reactNative.Text, { style: [styles3.closeButtonText, { color: theme.colors.text }] }, "\u2715")
1935
+ ))),
1936
+ escalation && /* @__PURE__ */ React7__namespace.default.createElement(
1937
+ reactNative.View,
1938
+ {
1939
+ style: [
1940
+ styles3.escalationBanner,
1941
+ {
1942
+ borderBottomColor: theme.colors.border,
1943
+ backgroundColor: theme.colors.primary + "0d"
1944
+ }
1945
+ ],
1946
+ testID: "escalation-banner"
1947
+ },
1948
+ /* @__PURE__ */ React7__namespace.default.createElement(HeadsetIcon, { size: 12, color: theme.colors.primary }),
1949
+ /* @__PURE__ */ React7__namespace.default.createElement(
1950
+ reactNative.Text,
1951
+ {
1952
+ style: [
1953
+ styles3.escalationBannerText,
1954
+ {
1955
+ color: theme.colors.textSecondary,
1956
+ fontFamily: theme.typography.fontFamily,
1957
+ fontSize: theme.typography.fontSizeXs
1958
+ }
1959
+ ]
1960
+ },
1961
+ escalation.status === "pending" ? strings.escalationPendingBanner : strings.escalationActiveBanner
1962
+ )
1963
+ ),
1964
+ /* @__PURE__ */ React7__namespace.default.createElement(
1965
+ reactNative.FlatList,
1966
+ {
1967
+ ...APPILOTS_SKIP_PROPS,
1968
+ ref: flatListRef,
1969
+ data: timeline,
1970
+ keyExtractor: (item) => item.type === "message" ? item.data.id : item.key,
1971
+ renderItem: ({ item }) => {
1972
+ if (item.type === "message") {
1973
+ return renderMessage({ item: item.data });
1974
+ }
1975
+ if (item.type === "breadcrumb") {
1976
+ return renderBreadcrumb(item.actions);
1977
+ }
1978
+ return null;
1979
+ },
1980
+ contentContainerStyle: styles3.messageList,
1981
+ ListEmptyComponent: /* @__PURE__ */ React7__namespace.default.createElement(reactNative.View, { style: styles3.emptyState }, emptyStateIcon && isImageSource(emptyStateIcon) ? /* @__PURE__ */ React7__namespace.default.createElement(
1982
+ reactNative.Image,
1983
+ {
1984
+ source: typeof emptyStateIcon === "string" ? { uri: emptyStateIcon } : emptyStateIcon,
1985
+ style: styles3.emptyIconImage,
1986
+ resizeMode: "contain"
1987
+ }
1988
+ ) : /* @__PURE__ */ React7__namespace.default.createElement(
1989
+ reactNative.View,
1990
+ {
1991
+ style: [
1992
+ styles3.emptyIconBadge,
1993
+ { backgroundColor: theme.colors.primary + "14" }
1994
+ ]
1995
+ },
1996
+ emptyStateIcon ? /* @__PURE__ */ React7__namespace.default.createElement(reactNative.Text, { style: styles3.emptyIconEmoji }, emptyStateIcon) : /* @__PURE__ */ React7__namespace.default.createElement(ChatIcon, { size: 30, color: theme.colors.primary })
1997
+ ), /* @__PURE__ */ React7__namespace.default.createElement(
1998
+ reactNative.Text,
1999
+ {
2000
+ style: [
2001
+ styles3.emptyTitle,
2002
+ { color: theme.colors.text, fontFamily: theme.typography.fontFamily }
2003
+ ]
2004
+ },
2005
+ resolvedEmptyTitle
2006
+ ), showEmptySubtitle && /* @__PURE__ */ React7__namespace.default.createElement(
2007
+ reactNative.Text,
2008
+ {
2009
+ style: [
2010
+ styles3.emptySubtitle,
2011
+ {
2012
+ color: theme.colors.textSecondary,
2013
+ fontFamily: theme.typography.fontFamily
2014
+ }
2015
+ ],
2016
+ numberOfLines: 2
2017
+ },
2018
+ resolvedEmptySubtitle
2019
+ ), showSuggestedPrompts && suggestedPrompts.length > 0 && /* @__PURE__ */ React7__namespace.default.createElement(reactNative.View, { style: styles3.chipsContainer }, suggestedPrompts.map((prompt) => /* @__PURE__ */ React7__namespace.default.createElement(
2020
+ reactNative.TouchableOpacity,
2021
+ {
2022
+ key: `${prompt.source}:${prompt.text}`,
2023
+ style: [
2024
+ styles3.chip,
2025
+ {
2026
+ backgroundColor: theme.colors.surface,
2027
+ borderColor: theme.colors.border,
2028
+ borderRadius: 999
2029
+ }
2030
+ ],
2031
+ onPress: () => setInputText(prompt.text),
2032
+ activeOpacity: 0.7,
2033
+ accessibilityLabel: `Suggested prompt: ${prompt.text}`
2034
+ },
2035
+ /* @__PURE__ */ React7__namespace.default.createElement(
2036
+ reactNative.Text,
2037
+ {
2038
+ style: [
2039
+ styles3.chipText,
2040
+ {
2041
+ color: theme.colors.buttonText,
2042
+ fontFamily: theme.typography.fontFamily,
2043
+ fontSize: theme.typography.fontSizeSm
2044
+ }
2045
+ ],
2046
+ numberOfLines: 1
2047
+ },
2048
+ prompt.text
2049
+ )
2050
+ )))),
2051
+ ListFooterComponent: isLoading ? /* @__PURE__ */ React7__namespace.default.createElement(
2052
+ reactNative.View,
2053
+ {
2054
+ style: [
2055
+ styles3.messageBubble,
2056
+ styles3.assistantBubble,
2057
+ { backgroundColor: theme.colors.surface }
2058
+ ]
2059
+ },
2060
+ /* @__PURE__ */ React7__namespace.default.createElement(
2061
+ reactNative.Text,
2062
+ {
2063
+ style: [
2064
+ styles3.messageText,
2065
+ { color: theme.colors.textSecondary, fontFamily: theme.typography.fontFamily }
2066
+ ]
2067
+ },
2068
+ strings[loadingStatusKey] ?? strings.thinking
2069
+ )
2070
+ ) : null
2071
+ }
2072
+ ),
2073
+ /* @__PURE__ */ React7__namespace.default.createElement(
2074
+ reactNative.View,
2075
+ {
2076
+ style: [
2077
+ styles3.inputContainer,
2078
+ {
2079
+ borderTopColor: theme.colors.border,
2080
+ paddingBottom: Math.max(insets.bottom, 10)
2081
+ }
2082
+ ]
2083
+ },
2084
+ /* @__PURE__ */ React7__namespace.default.createElement(
2085
+ reactNative.TextInput,
2086
+ {
2087
+ style: [
2088
+ styles3.input,
2089
+ {
2090
+ backgroundColor: theme.colors.surface,
2091
+ color: theme.colors.text,
2092
+ borderRadius: theme.radii.md,
2093
+ fontFamily: theme.typography.fontFamily,
2094
+ fontSize: theme.typography.fontSizeBase,
2095
+ lineHeight: theme.typography.fontSizeBase * 1.35
2096
+ }
2097
+ ],
2098
+ placeholder: resolvedPlaceholder,
2099
+ placeholderTextColor: theme.colors.textSecondary,
2100
+ value: inputText,
2101
+ onChangeText: setInputText,
2102
+ multiline: true,
2103
+ blurOnSubmit: false,
2104
+ scrollEnabled: true,
2105
+ editable: !isLoading,
2106
+ testID: "assistant-input",
2107
+ __appilotsInternal: true
2108
+ }
2109
+ ),
2110
+ isLoading ? /* @__PURE__ */ React7__namespace.default.createElement(
2111
+ reactNative.TouchableOpacity,
2112
+ {
2113
+ style: [
2114
+ styles3.sendButton,
2115
+ {
2116
+ backgroundColor: theme.colors.primary,
2117
+ borderRadius: theme.radii.md
2118
+ }
2119
+ ],
2120
+ onPress: cancelMessage,
2121
+ accessibilityRole: "button",
2122
+ accessibilityLabel: strings.stopGeneratingA11y,
2123
+ testID: "appilots-stop-button",
2124
+ activeOpacity: 0.7
2125
+ },
2126
+ /* @__PURE__ */ React7__namespace.default.createElement(reactNative.Text, { style: styles3.sendButtonText }, "\u25A0")
2127
+ ) : /* @__PURE__ */ React7__namespace.default.createElement(
2128
+ reactNative.TouchableOpacity,
2129
+ {
2130
+ style: [
2131
+ styles3.sendButton,
2132
+ {
2133
+ backgroundColor: inputText.trim() ? theme.colors.primary : theme.colors.primary + "40",
2134
+ borderRadius: theme.radii.md
2135
+ }
2136
+ ],
2137
+ onPress: handleSend,
2138
+ disabled: !inputText.trim(),
2139
+ activeOpacity: 0.7,
2140
+ accessibilityRole: "button",
2141
+ testID: "assistant-send"
2142
+ },
2143
+ /* @__PURE__ */ React7__namespace.default.createElement(reactNative.Text, { style: styles3.sendButtonText }, "\u2191")
2144
+ )
2145
+ ),
2146
+ poweredByVisible && /* @__PURE__ */ React7__namespace.default.createElement(reactNative.View, { style: styles3.poweredByContainer }, /* @__PURE__ */ React7__namespace.default.createElement(
2147
+ reactNative.Text,
2148
+ {
2149
+ style: [
2150
+ styles3.poweredByText,
2151
+ {
2152
+ color: theme.colors.textSecondary,
2153
+ fontFamily: theme.typography.fontFamily,
2154
+ fontSize: theme.typography.fontSizeXs
2155
+ }
2156
+ ]
2157
+ },
2158
+ strings.poweredBy
2159
+ ))
2160
+ );
2161
+ if (mode === "inline") {
2162
+ return chatSurface;
2163
+ }
2164
+ const renderTrigger = () => {
2165
+ if (triggerButton === "none") return null;
2166
+ if (triggerButton !== "default" && React7__namespace.default.isValidElement(triggerButton)) {
2167
+ return /* @__PURE__ */ React7__namespace.default.createElement(reactNative.View, { ...APPILOTS_SKIP_PROPS, style: [styles3.fabWrapper, fabPositionStyle] }, /* @__PURE__ */ React7__namespace.default.createElement(
2168
+ reactNative.TouchableOpacity,
2169
+ {
2170
+ ...APPILOTS_SKIP_PROPS,
2171
+ onPress: openChat,
2172
+ activeOpacity: 0.8,
2173
+ accessibilityRole: "button",
2174
+ accessibilityLabel: strings.openChatA11y,
2175
+ testID: "assistant-launcher"
2176
+ },
2177
+ triggerButton
2178
+ ));
2179
+ }
2180
+ return /* @__PURE__ */ React7__namespace.default.createElement(
2181
+ reactNative.TouchableOpacity,
2182
+ {
2183
+ ...APPILOTS_SKIP_PROPS,
2184
+ style: [
2185
+ styles3.fab,
2186
+ fabPositionStyle,
2187
+ { backgroundColor: triggerButtonColor ?? theme.colors.primary }
2188
+ ],
2189
+ onPress: openChat,
2190
+ activeOpacity: 0.8,
2191
+ accessibilityRole: "button",
2192
+ accessibilityLabel: strings.openChatA11y,
2193
+ testID: "assistant-launcher"
2194
+ },
2195
+ triggerIcon ?? (triggerButtonImage ? /* @__PURE__ */ React7__namespace.default.createElement(
2196
+ reactNative.Image,
2197
+ {
2198
+ source: typeof triggerButtonImage === "string" ? { uri: triggerButtonImage } : triggerButtonImage,
2199
+ style: styles3.fabImage,
2200
+ resizeMode: "contain"
2201
+ }
2202
+ ) : /* @__PURE__ */ React7__namespace.default.createElement(ChatIcon, { size: 26, color: "#ffffff" }))
2203
+ );
2204
+ };
2205
+ return /* @__PURE__ */ React7__namespace.default.createElement(React7__namespace.default.Fragment, null, showTrigger && renderTrigger(), /* @__PURE__ */ React7__namespace.default.createElement(
2206
+ reactNative.Modal,
2207
+ {
2208
+ ...APPILOTS_SKIP_PROPS,
2209
+ visible: isVisible,
2210
+ transparent: true,
2211
+ animationType: "none",
2212
+ onRequestClose: closeChat
2213
+ },
2214
+ /* @__PURE__ */ React7__namespace.default.createElement(
2215
+ reactNative.Animated.View,
2216
+ {
2217
+ ...APPILOTS_SKIP_PROPS,
2218
+ style: [
2219
+ mode === "fullscreen" ? styles3.modalContainerFullscreen : styles3.modalContainer,
2220
+ mode === "sidebar" && styles3.modalContainerSidebar,
2221
+ { transform: [{ translateY: slideAnim }] }
2222
+ ]
2223
+ },
2224
+ /* @__PURE__ */ React7__namespace.default.createElement(
2225
+ reactNative.KeyboardAvoidingView,
2226
+ {
2227
+ style: styles3.keyboardView,
2228
+ behavior: reactNative.Platform.OS === "ios" ? "padding" : "height",
2229
+ keyboardVerticalOffset: 0
2230
+ },
2231
+ chatSurface
2232
+ )
2233
+ )
2234
+ ));
2235
+ }
2236
+ var styles3 = reactNative.StyleSheet.create({
2237
+ fab: {
2238
+ position: "absolute",
2239
+ width: 56,
2240
+ height: 56,
2241
+ borderRadius: 28,
2242
+ alignItems: "center",
2243
+ justifyContent: "center",
2244
+ elevation: 6,
2245
+ shadowColor: "#000",
2246
+ shadowOffset: { width: 0, height: 3 },
2247
+ shadowOpacity: 0.27,
2248
+ shadowRadius: 4.65,
2249
+ zIndex: 999
2250
+ },
2251
+ fabWrapper: {
2252
+ position: "absolute",
2253
+ zIndex: 999
2254
+ },
2255
+ fabIcon: {
2256
+ fontSize: 24
2257
+ },
2258
+ fabImage: {
2259
+ width: 32,
2260
+ height: 32,
2261
+ borderRadius: 16
2262
+ },
2263
+ modalContainer: {
2264
+ flex: 1,
2265
+ justifyContent: "flex-end",
2266
+ backgroundColor: "rgba(0,0,0,0.4)"
2267
+ },
2268
+ modalContainerFullscreen: {
2269
+ flex: 1,
2270
+ backgroundColor: "rgba(0,0,0,0.4)"
2271
+ },
2272
+ modalContainerSidebar: {
2273
+ // Right-pinned half-width on tablet/web. Stays as bottom-sheet on
2274
+ // narrow phones so we don't hand the user a 50% sliver.
2275
+ flex: 1,
2276
+ flexDirection: "row",
2277
+ justifyContent: "flex-end"
2278
+ },
2279
+ keyboardView: {
2280
+ flex: 1,
2281
+ justifyContent: "flex-end"
2282
+ },
2283
+ chatContainer: {
2284
+ height: SCREEN_HEIGHT * 0.75,
2285
+ shadowColor: "#000",
2286
+ shadowOffset: { width: 0, height: -3 },
2287
+ shadowOpacity: 0.1,
2288
+ shadowRadius: 12,
2289
+ elevation: 10
2290
+ },
2291
+ chatContainerFullscreen: {
2292
+ height: SCREEN_HEIGHT
2293
+ },
2294
+ chatContainerSidebar: {
2295
+ height: SCREEN_HEIGHT,
2296
+ width: SCREEN_WIDTH > 600 ? SCREEN_WIDTH * 0.4 : SCREEN_WIDTH
2297
+ },
2298
+ chatContainerInline: {
2299
+ height: "100%",
2300
+ width: "100%",
2301
+ flex: 1
2302
+ },
2303
+ header: {
2304
+ flexDirection: "row",
2305
+ alignItems: "center",
2306
+ justifyContent: "space-between",
2307
+ paddingHorizontal: 16,
2308
+ paddingVertical: 14,
2309
+ borderBottomWidth: 1
2310
+ },
2311
+ headerLeft: {
2312
+ flexDirection: "row",
2313
+ alignItems: "center",
2314
+ gap: 8
2315
+ },
2316
+ headerDot: {
2317
+ width: 8,
2318
+ height: 8,
2319
+ borderRadius: 4
2320
+ },
2321
+ headerAvatar: {
2322
+ width: 24,
2323
+ height: 24,
2324
+ borderRadius: 12
2325
+ },
2326
+ headerAvatarSlot: {
2327
+ width: 24,
2328
+ height: 24,
2329
+ alignItems: "center",
2330
+ justifyContent: "center"
2331
+ },
2332
+ headerTitle: {
2333
+ fontWeight: "600"
2334
+ },
2335
+ headerActions: {
2336
+ flexDirection: "row",
2337
+ alignItems: "center",
2338
+ gap: 12
2339
+ },
2340
+ headerButton: {
2341
+ paddingHorizontal: 8,
2342
+ paddingVertical: 4
2343
+ },
2344
+ headerButtonText: {
2345
+ fontSize: 13
2346
+ },
2347
+ closeButton: {
2348
+ width: 28,
2349
+ height: 28,
2350
+ borderRadius: 14,
2351
+ alignItems: "center",
2352
+ justifyContent: "center"
2353
+ },
2354
+ closeButtonText: {
2355
+ fontSize: 18,
2356
+ fontWeight: "300"
2357
+ },
2358
+ messageList: {
2359
+ paddingHorizontal: 16,
2360
+ paddingTop: 12,
2361
+ paddingBottom: 8,
2362
+ flexGrow: 1
2363
+ },
2364
+ messageBubble: {
2365
+ paddingHorizontal: BUBBLE_HORIZONTAL_PADDING,
2366
+ paddingVertical: 10,
2367
+ borderRadius: 18,
2368
+ marginBottom: 8
2369
+ },
2370
+ userBubble: {
2371
+ alignSelf: "flex-end",
2372
+ maxWidth: "82%",
2373
+ borderBottomRightRadius: 4
2374
+ },
2375
+ assistantBubble: {
2376
+ alignSelf: "flex-start",
2377
+ maxWidth: "94%",
2378
+ borderBottomLeftRadius: 4
2379
+ },
2380
+ assistantBubbleWide: {
2381
+ width: "100%",
2382
+ maxWidth: "100%"
2383
+ },
2384
+ messageText: {
2385
+ lineHeight: 20
2386
+ },
2387
+ emptyState: {
2388
+ flex: 1,
2389
+ alignItems: "center",
2390
+ justifyContent: "center",
2391
+ paddingVertical: 48,
2392
+ paddingHorizontal: 28
2393
+ },
2394
+ emptyIconBadge: {
2395
+ width: 64,
2396
+ height: 64,
2397
+ borderRadius: 32,
2398
+ alignItems: "center",
2399
+ justifyContent: "center",
2400
+ marginBottom: 20
2401
+ },
2402
+ emptyIconImage: {
2403
+ width: 64,
2404
+ height: 64,
2405
+ marginBottom: 20
2406
+ },
2407
+ emptyIconEmoji: {
2408
+ fontSize: 30,
2409
+ textAlign: "center"
2410
+ },
2411
+ emptyTitle: {
2412
+ fontSize: 20,
2413
+ fontWeight: "600",
2414
+ marginBottom: 6,
2415
+ textAlign: "center"
2416
+ },
2417
+ emptySubtitle: {
2418
+ fontSize: 14,
2419
+ textAlign: "center",
2420
+ lineHeight: 20,
2421
+ maxWidth: 280
2422
+ },
2423
+ chipsContainer: {
2424
+ flexDirection: "row",
2425
+ flexWrap: "wrap",
2426
+ justifyContent: "center",
2427
+ gap: 8,
2428
+ marginTop: 20,
2429
+ maxWidth: 320
2430
+ },
2431
+ chip: {
2432
+ paddingHorizontal: 16,
2433
+ paddingVertical: 10,
2434
+ borderWidth: 1,
2435
+ maxWidth: "100%"
2436
+ },
2437
+ chipText: {
2438
+ fontWeight: "500"
2439
+ },
2440
+ escalationBanner: {
2441
+ flexDirection: "row",
2442
+ alignItems: "center",
2443
+ justifyContent: "center",
2444
+ gap: 6,
2445
+ paddingVertical: 6,
2446
+ paddingHorizontal: 16,
2447
+ borderBottomWidth: 1
2448
+ },
2449
+ escalationBannerText: {
2450
+ fontWeight: "500"
2451
+ },
2452
+ systemMessageContainer: {
2453
+ alignItems: "center",
2454
+ marginVertical: 8,
2455
+ paddingHorizontal: 12,
2456
+ gap: 8
2457
+ },
2458
+ systemMessageText: {
2459
+ textAlign: "center",
2460
+ lineHeight: 18
2461
+ },
2462
+ escalationOfferChip: {
2463
+ flexDirection: "row",
2464
+ alignItems: "center",
2465
+ gap: 6
2466
+ },
2467
+ humanAgentContainer: {
2468
+ alignSelf: "flex-start",
2469
+ maxWidth: "94%"
2470
+ },
2471
+ humanAgentLabelRow: {
2472
+ flexDirection: "row",
2473
+ alignItems: "center",
2474
+ gap: 4,
2475
+ marginBottom: 2,
2476
+ marginLeft: 4
2477
+ },
2478
+ humanAgentLabel: {
2479
+ fontSize: 11,
2480
+ fontWeight: "600",
2481
+ textTransform: "uppercase",
2482
+ letterSpacing: 0.4
2483
+ },
2484
+ inputContainer: {
2485
+ flexDirection: "row",
2486
+ alignItems: "flex-end",
2487
+ paddingHorizontal: 12,
2488
+ paddingVertical: 10,
2489
+ borderTopWidth: 1,
2490
+ gap: 8
2491
+ },
2492
+ input: {
2493
+ flex: 1,
2494
+ minHeight: 38,
2495
+ maxHeight: 120,
2496
+ paddingHorizontal: 16,
2497
+ paddingTop: reactNative.Platform.OS === "ios" ? 9 : 8,
2498
+ paddingBottom: reactNative.Platform.OS === "ios" ? 9 : 8,
2499
+ textAlignVertical: "top"
2500
+ },
2501
+ sendButton: {
2502
+ width: 38,
2503
+ height: 38,
2504
+ alignItems: "center",
2505
+ justifyContent: "center"
2506
+ },
2507
+ sendButtonText: {
2508
+ color: "#ffffff",
2509
+ fontSize: 18,
2510
+ fontWeight: "700"
2511
+ },
2512
+ poweredByContainer: {
2513
+ alignItems: "center",
2514
+ paddingVertical: 4
2515
+ },
2516
+ poweredByText: {
2517
+ fontWeight: "500"
2518
+ }
2519
+ });
2520
+
2521
+ // src/components/ConfirmDialog.tsx
2522
+ function ConfirmDialog(_props = {}) {
2523
+ return null;
2524
+ }
2525
+ function normalizeId(label) {
2526
+ return label.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9\s]/g, "").trim().replace(/\s+(.)/g, (_, c) => c.toUpperCase());
2527
+ }
2528
+ function createAppilotsInput(WrappedComponent) {
2529
+ const AppilotsInput = React7__namespace.default.forwardRef(
2530
+ (props, ref) => {
2531
+ const {
2532
+ appilotsId,
2533
+ appilotsScreen,
2534
+ appilotsFieldType = "text",
2535
+ appilotsEnabled = true,
2536
+ label,
2537
+ value,
2538
+ onChangeText,
2539
+ ...rest
2540
+ } = props;
2541
+ const fieldId = appilotsId || (label ? normalizeId(label) : null);
2542
+ const valueRef = React7.useRef(value ?? "");
2543
+ const onChangeRef = React7.useRef(onChangeText);
2544
+ const innerRef = React7.useRef(null);
2545
+ valueRef.current = value ?? "";
2546
+ onChangeRef.current = onChangeText;
2547
+ const getValue = React7.useCallback(() => valueRef.current, []);
2548
+ const setValue = React7.useCallback((v) => onChangeRef.current?.(v), []);
2549
+ const focus = React7.useCallback(() => {
2550
+ innerRef.current?.focus?.();
2551
+ }, []);
2552
+ React7.useEffect(() => {
2553
+ if (!fieldId || !appilotsEnabled) return;
2554
+ const entry = {
2555
+ kind: "field",
2556
+ getValue,
2557
+ setValue,
2558
+ focus,
2559
+ fieldType: appilotsFieldType,
2560
+ label: label ?? fieldId,
2561
+ screen: appilotsScreen
2562
+ };
2563
+ chunkSIBKF7AA_js.componentRegistry.register(fieldId, entry);
2564
+ return () => {
2565
+ chunkSIBKF7AA_js.componentRegistry.unregister(fieldId);
2566
+ };
2567
+ }, [fieldId, appilotsEnabled, getValue, setValue, focus, appilotsFieldType, label, appilotsScreen]);
2568
+ const mergedRef = React7.useCallback(
2569
+ (instance) => {
2570
+ innerRef.current = instance;
2571
+ if (typeof ref === "function") ref(instance);
2572
+ else if (ref) ref.current = instance;
2573
+ },
2574
+ [ref]
2575
+ );
2576
+ return /* @__PURE__ */ React7__namespace.default.createElement(
2577
+ WrappedComponent,
2578
+ {
2579
+ ...{ label, value, onChangeText, ...rest },
2580
+ ref: mergedRef
2581
+ }
2582
+ );
2583
+ }
2584
+ );
2585
+ AppilotsInput.displayName = `AppilotsInput(${WrappedComponent.displayName || WrappedComponent.name || "Component"})`;
2586
+ return AppilotsInput;
2587
+ }
2588
+ function normalizeId2(label) {
2589
+ return label.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9\s]/g, "").trim().replace(/\s+(.)/g, (_, c) => c.toUpperCase());
2590
+ }
2591
+ function createAppilotsButton(WrappedComponent) {
2592
+ const AppilotsButton = React7__namespace.default.forwardRef(
2593
+ (props, ref) => {
2594
+ const {
2595
+ appilotsId,
2596
+ appilotsScreen,
2597
+ appilotsEnabled = true,
2598
+ title,
2599
+ onPress,
2600
+ ...rest
2601
+ } = props;
2602
+ const targetId = appilotsId || (title ? normalizeId2(title) : null);
2603
+ const onPressRef = React7.useRef(onPress);
2604
+ onPressRef.current = onPress;
2605
+ const press = React7.useCallback(() => onPressRef.current?.(), []);
2606
+ React7.useEffect(() => {
2607
+ if (!targetId || !appilotsEnabled) return;
2608
+ const entry = {
2609
+ kind: "target",
2610
+ press,
2611
+ label: title ?? targetId,
2612
+ screen: appilotsScreen
2613
+ };
2614
+ chunkSIBKF7AA_js.componentRegistry.register(targetId, entry);
2615
+ return () => {
2616
+ chunkSIBKF7AA_js.componentRegistry.unregister(targetId);
2617
+ };
2618
+ }, [targetId, appilotsEnabled, press, title, appilotsScreen]);
2619
+ return /* @__PURE__ */ React7__namespace.default.createElement(
2620
+ WrappedComponent,
2621
+ {
2622
+ ...{ title, onPress, ...rest },
2623
+ ref
2624
+ }
2625
+ );
2626
+ }
2627
+ );
2628
+ AppilotsButton.displayName = `AppilotsButton(${WrappedComponent.displayName || WrappedComponent.name || "Component"})`;
2629
+ return AppilotsButton;
2630
+ }
2631
+ function normalizeId3(label) {
2632
+ return label.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9\s]/g, "").trim().replace(/\s+(.)/g, (_, c) => c.toUpperCase());
2633
+ }
2634
+ function createAppilotsSwitch(WrappedComponent) {
2635
+ const AppilotsSwitch = React7__namespace.default.forwardRef(
2636
+ (props, ref) => {
2637
+ const {
2638
+ appilotsId,
2639
+ appilotsScreen,
2640
+ appilotsEnabled = true,
2641
+ label,
2642
+ value,
2643
+ onValueChange,
2644
+ ...rest
2645
+ } = props;
2646
+ const toggleId = appilotsId || (label ? normalizeId3(label) : null);
2647
+ const valueRef = React7.useRef(value ?? false);
2648
+ const onChangeRef = React7.useRef(onValueChange);
2649
+ valueRef.current = value ?? false;
2650
+ onChangeRef.current = onValueChange;
2651
+ const getValue = React7.useCallback(() => valueRef.current, []);
2652
+ const setValue = React7.useCallback((v) => onChangeRef.current?.(v), []);
2653
+ React7.useEffect(() => {
2654
+ if (!toggleId || !appilotsEnabled) return;
2655
+ const entry = {
2656
+ kind: "toggle",
2657
+ getValue,
2658
+ setValue,
2659
+ label: label ?? toggleId,
2660
+ screen: appilotsScreen
2661
+ };
2662
+ chunkSIBKF7AA_js.componentRegistry.register(toggleId, entry);
2663
+ return () => {
2664
+ chunkSIBKF7AA_js.componentRegistry.unregister(toggleId);
2665
+ };
2666
+ }, [toggleId, appilotsEnabled, getValue, setValue, label, appilotsScreen]);
2667
+ return /* @__PURE__ */ React7__namespace.default.createElement(
2668
+ WrappedComponent,
2669
+ {
2670
+ ...{ label, value, onValueChange, ...rest },
2671
+ ref
2672
+ }
2673
+ );
2674
+ }
2675
+ );
2676
+ AppilotsSwitch.displayName = `AppilotsSwitch(${WrappedComponent.displayName || WrappedComponent.name || "Component"})`;
2677
+ return AppilotsSwitch;
2678
+ }
2679
+
2680
+ Object.defineProperty(exports, "AppilotsNavigationContainer", {
2681
+ enumerable: true,
2682
+ get: function () { return chunkKGN3DNGX_js.AppilotsNavigationContainer; }
2683
+ });
2684
+ Object.defineProperty(exports, "captureSnapshot", {
2685
+ enumerable: true,
2686
+ get: function () { return chunkIASJ7YHC_js.captureSnapshot; }
2687
+ });
2688
+ Object.defineProperty(exports, "executeAction", {
2689
+ enumerable: true,
2690
+ get: function () { return chunkIASJ7YHC_js.executeAction; }
2691
+ });
2692
+ Object.defineProperty(exports, "useAppilots", {
2693
+ enumerable: true,
2694
+ get: function () { return chunkIASJ7YHC_js.useAppilots; }
2695
+ });
2696
+ Object.defineProperty(exports, "useAppilotsActions", {
2697
+ enumerable: true,
2698
+ get: function () { return chunkIASJ7YHC_js.useAppilotsActions; }
2699
+ });
2700
+ Object.defineProperty(exports, "useAppilotsChat", {
2701
+ enumerable: true,
2702
+ get: function () { return chunkIASJ7YHC_js.useAppilotsChat; }
2703
+ });
2704
+ Object.defineProperty(exports, "useAppilotsField", {
2705
+ enumerable: true,
2706
+ get: function () { return chunkIASJ7YHC_js.useAppilotsField; }
2707
+ });
2708
+ Object.defineProperty(exports, "useAppilotsNavigation", {
2709
+ enumerable: true,
2710
+ get: function () { return chunkIASJ7YHC_js.useAppilotsNavigation; }
2711
+ });
2712
+ Object.defineProperty(exports, "useAppilotsSlider", {
2713
+ enumerable: true,
2714
+ get: function () { return chunkIASJ7YHC_js.useAppilotsSlider; }
2715
+ });
2716
+ Object.defineProperty(exports, "useAppilotsTarget", {
2717
+ enumerable: true,
2718
+ get: function () { return chunkIASJ7YHC_js.useAppilotsTarget; }
2719
+ });
2720
+ Object.defineProperty(exports, "useAppilotsToggle", {
2721
+ enumerable: true,
2722
+ get: function () { return chunkIASJ7YHC_js.useAppilotsToggle; }
2723
+ });
2724
+ Object.defineProperty(exports, "useSuggestedPrompts", {
2725
+ enumerable: true,
2726
+ get: function () { return chunkIASJ7YHC_js.useSuggestedPrompts; }
2727
+ });
2728
+ Object.defineProperty(exports, "AppilotsClient", {
2729
+ enumerable: true,
2730
+ get: function () { return chunkSIBKF7AA_js.AppilotsClient; }
2731
+ });
2732
+ Object.defineProperty(exports, "AppilotsProvider", {
2733
+ enumerable: true,
2734
+ get: function () { return chunkSIBKF7AA_js.AppilotsProvider; }
2735
+ });
2736
+ Object.defineProperty(exports, "AppilotsRegistryProvider", {
2737
+ enumerable: true,
2738
+ get: function () { return chunkSIBKF7AA_js.AppilotsRegistryProvider; }
2739
+ });
2740
+ Object.defineProperty(exports, "SDK_VERSION", {
2741
+ enumerable: true,
2742
+ get: function () { return chunkSIBKF7AA_js.SDK_VERSION; }
2743
+ });
2744
+ Object.defineProperty(exports, "_patchJsxRuntimes", {
2745
+ enumerable: true,
2746
+ get: function () { return chunkSIBKF7AA_js._patchJsxRuntimes; }
2747
+ });
2748
+ Object.defineProperty(exports, "clearAppilotsDebugTraces", {
2749
+ enumerable: true,
2750
+ get: function () { return chunkSIBKF7AA_js.clearAppilotsDebugTraces; }
2751
+ });
2752
+ Object.defineProperty(exports, "componentRegistry", {
2753
+ enumerable: true,
2754
+ get: function () { return chunkSIBKF7AA_js.componentRegistry; }
2755
+ });
2756
+ Object.defineProperty(exports, "createComponentRegistry", {
2757
+ enumerable: true,
2758
+ get: function () { return chunkSIBKF7AA_js.createComponentRegistry; }
2759
+ });
2760
+ Object.defineProperty(exports, "createElementRegistry", {
2761
+ enumerable: true,
2762
+ get: function () { return chunkSIBKF7AA_js.createElementRegistry; }
2763
+ });
2764
+ Object.defineProperty(exports, "createListRegistry", {
2765
+ enumerable: true,
2766
+ get: function () { return chunkSIBKF7AA_js.createListRegistry; }
2767
+ });
2768
+ Object.defineProperty(exports, "elementRegistry", {
2769
+ enumerable: true,
2770
+ get: function () { return chunkSIBKF7AA_js.elementRegistry; }
2771
+ });
2772
+ Object.defineProperty(exports, "enableAppilotsAutoTracking", {
2773
+ enumerable: true,
2774
+ get: function () { return chunkSIBKF7AA_js.enableAppilotsAutoTracking; }
2775
+ });
2776
+ Object.defineProperty(exports, "getAppilotsDebugTraces", {
2777
+ enumerable: true,
2778
+ get: function () { return chunkSIBKF7AA_js.getAppilotsDebugTraces; }
2779
+ });
2780
+ Object.defineProperty(exports, "getGlobalConfig", {
2781
+ enumerable: true,
2782
+ get: function () { return chunkSIBKF7AA_js.getGlobalConfig; }
2783
+ });
2784
+ Object.defineProperty(exports, "initAppilots", {
2785
+ enumerable: true,
2786
+ get: function () { return chunkSIBKF7AA_js.initAppilots; }
2787
+ });
2788
+ Object.defineProperty(exports, "isAutoTrackingEnabled", {
2789
+ enumerable: true,
2790
+ get: function () { return chunkSIBKF7AA_js.isAutoTrackingEnabled; }
2791
+ });
2792
+ Object.defineProperty(exports, "listRegistry", {
2793
+ enumerable: true,
2794
+ get: function () { return chunkSIBKF7AA_js.listRegistry; }
2795
+ });
2796
+ Object.defineProperty(exports, "recordAppilotsDebugTrace", {
2797
+ enumerable: true,
2798
+ get: function () { return chunkSIBKF7AA_js.recordAppilotsDebugTrace; }
2799
+ });
2800
+ Object.defineProperty(exports, "registerScreen", {
2801
+ enumerable: true,
2802
+ get: function () { return chunkSIBKF7AA_js.registerScreen; }
2803
+ });
2804
+ Object.defineProperty(exports, "subscribeAppilotsDebugTraces", {
2805
+ enumerable: true,
2806
+ get: function () { return chunkSIBKF7AA_js.subscribeAppilotsDebugTraces; }
2807
+ });
2808
+ Object.defineProperty(exports, "useAppilotsContext", {
2809
+ enumerable: true,
2810
+ get: function () { return chunkSIBKF7AA_js.useAppilotsContext; }
2811
+ });
2812
+ Object.defineProperty(exports, "useResolvedRegistry", {
2813
+ enumerable: true,
2814
+ get: function () { return chunkSIBKF7AA_js.useResolvedRegistry; }
2815
+ });
2816
+ exports.ActionBreadcrumb = ActionBreadcrumb;
2817
+ exports.AppilotsChat = AppilotsChat;
2818
+ exports.AppilotsI18nProvider = AppilotsI18nProvider;
2819
+ exports.AppilotsThemeProvider = AppilotsThemeProvider;
2820
+ exports.ChatIcon = ChatIcon;
2821
+ exports.ConfirmDialog = ConfirmDialog;
2822
+ exports.HeadsetIcon = HeadsetIcon;
2823
+ exports.appilotsTheme = appilotsTheme;
2824
+ exports.appilotsThemeFromTailwind = appilotsThemeFromTailwind;
2825
+ exports.createAppilotsButton = createAppilotsButton;
2826
+ exports.createAppilotsInput = createAppilotsInput;
2827
+ exports.createAppilotsSwitch = createAppilotsSwitch;
2828
+ exports.defaultDarkTheme = defaultDarkTheme;
2829
+ exports.defaultLightTheme = defaultLightTheme;
2830
+ exports.describeAction = describeAction;
2831
+ exports.detectDeviceLocale = detectDeviceLocale;
2832
+ exports.humanizeError = humanizeError;
2833
+ exports.mergeThemeTokens = mergeThemeTokens;
2834
+ exports.resolveLocale = resolveLocale;
2835
+ exports.useAppilotsI18n = useAppilotsI18n;
2836
+ exports.useAppilotsTheme = useAppilotsTheme;