@uplifted/react 0.22.6
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/AddClientSheet.d.ts +39 -0
- package/dist/AddClientSheet.d.ts.map +1 -0
- package/dist/AddClientSheet.js +108 -0
- package/dist/AddClientSheet.js.map +1 -0
- package/dist/AiSettingsSheet.d.ts +20 -0
- package/dist/AiSettingsSheet.d.ts.map +1 -0
- package/dist/AiSettingsSheet.js +274 -0
- package/dist/AiSettingsSheet.js.map +1 -0
- package/dist/AssistantGrid.d.ts +30 -0
- package/dist/AssistantGrid.d.ts.map +1 -0
- package/dist/AssistantGrid.js +68 -0
- package/dist/AssistantGrid.js.map +1 -0
- package/dist/AttachmentPicker.d.ts +38 -0
- package/dist/AttachmentPicker.d.ts.map +1 -0
- package/dist/AttachmentPicker.js +173 -0
- package/dist/AttachmentPicker.js.map +1 -0
- package/dist/BulkGenerateSheet.d.ts +25 -0
- package/dist/BulkGenerateSheet.d.ts.map +1 -0
- package/dist/BulkGenerateSheet.js +65 -0
- package/dist/BulkGenerateSheet.js.map +1 -0
- package/dist/ChannelBadge.d.ts +16 -0
- package/dist/ChannelBadge.d.ts.map +1 -0
- package/dist/ChannelBadge.js +19 -0
- package/dist/ChannelBadge.js.map +1 -0
- package/dist/ChannelExplainer.d.ts +17 -0
- package/dist/ChannelExplainer.d.ts.map +1 -0
- package/dist/ChannelExplainer.js +25 -0
- package/dist/ChannelExplainer.js.map +1 -0
- package/dist/ClientList.d.ts +43 -0
- package/dist/ClientList.d.ts.map +1 -0
- package/dist/ClientList.js +76 -0
- package/dist/ClientList.js.map +1 -0
- package/dist/ClosedWindowBanner.d.ts +12 -0
- package/dist/ClosedWindowBanner.d.ts.map +1 -0
- package/dist/ClosedWindowBanner.js +15 -0
- package/dist/ClosedWindowBanner.js.map +1 -0
- package/dist/Composer.d.ts +49 -0
- package/dist/Composer.d.ts.map +1 -0
- package/dist/Composer.js +99 -0
- package/dist/Composer.js.map +1 -0
- package/dist/ComposerExtras.d.ts +15 -0
- package/dist/ComposerExtras.d.ts.map +1 -0
- package/dist/ComposerExtras.js +14 -0
- package/dist/ComposerExtras.js.map +1 -0
- package/dist/ConversationPane.d.ts +33 -0
- package/dist/ConversationPane.d.ts.map +1 -0
- package/dist/ConversationPane.js +126 -0
- package/dist/ConversationPane.js.map +1 -0
- package/dist/DeliveryReceipt.d.ts +7 -0
- package/dist/DeliveryReceipt.d.ts.map +1 -0
- package/dist/DeliveryReceipt.js +13 -0
- package/dist/DeliveryReceipt.js.map +1 -0
- package/dist/DraftGrid.d.ts +17 -0
- package/dist/DraftGrid.d.ts.map +1 -0
- package/dist/DraftGrid.js +43 -0
- package/dist/DraftGrid.js.map +1 -0
- package/dist/HostPreviewPane.d.ts +37 -0
- package/dist/HostPreviewPane.d.ts.map +1 -0
- package/dist/HostPreviewPane.js +106 -0
- package/dist/HostPreviewPane.js.map +1 -0
- package/dist/InlineDrafts.d.ts +14 -0
- package/dist/InlineDrafts.d.ts.map +1 -0
- package/dist/InlineDrafts.js +19 -0
- package/dist/InlineDrafts.js.map +1 -0
- package/dist/ItemActions.d.ts +23 -0
- package/dist/ItemActions.d.ts.map +1 -0
- package/dist/ItemActions.js +83 -0
- package/dist/ItemActions.js.map +1 -0
- package/dist/MediaAttachment.d.ts +7 -0
- package/dist/MediaAttachment.d.ts.map +1 -0
- package/dist/MediaAttachment.js +37 -0
- package/dist/MediaAttachment.js.map +1 -0
- package/dist/OfferSheet.d.ts +32 -0
- package/dist/OfferSheet.d.ts.map +1 -0
- package/dist/OfferSheet.js +84 -0
- package/dist/OfferSheet.js.map +1 -0
- package/dist/ProactiveOptionsSheet.d.ts +14 -0
- package/dist/ProactiveOptionsSheet.d.ts.map +1 -0
- package/dist/ProactiveOptionsSheet.js +58 -0
- package/dist/ProactiveOptionsSheet.js.map +1 -0
- package/dist/QuickSend.d.ts +15 -0
- package/dist/QuickSend.d.ts.map +1 -0
- package/dist/QuickSend.js +90 -0
- package/dist/QuickSend.js.map +1 -0
- package/dist/SegmentEditor.d.ts +25 -0
- package/dist/SegmentEditor.d.ts.map +1 -0
- package/dist/SegmentEditor.js +95 -0
- package/dist/SegmentEditor.js.map +1 -0
- package/dist/Sheet.d.ts +13 -0
- package/dist/Sheet.d.ts.map +1 -0
- package/dist/Sheet.js +64 -0
- package/dist/Sheet.js.map +1 -0
- package/dist/ThreadFeed.d.ts +27 -0
- package/dist/ThreadFeed.d.ts.map +1 -0
- package/dist/ThreadFeed.js +42 -0
- package/dist/ThreadFeed.js.map +1 -0
- package/dist/UpliftPanel.d.ts +40 -0
- package/dist/UpliftPanel.d.ts.map +1 -0
- package/dist/UpliftPanel.js +219 -0
- package/dist/UpliftPanel.js.map +1 -0
- package/dist/UpliftProvider.d.ts +15 -0
- package/dist/UpliftProvider.d.ts.map +1 -0
- package/dist/UpliftProvider.js +19 -0
- package/dist/UpliftProvider.js.map +1 -0
- package/dist/WaitingTemplateGhost.d.ts +12 -0
- package/dist/WaitingTemplateGhost.d.ts.map +1 -0
- package/dist/WaitingTemplateGhost.js +16 -0
- package/dist/WaitingTemplateGhost.js.map +1 -0
- package/dist/channels.d.ts +22 -0
- package/dist/channels.d.ts.map +1 -0
- package/dist/channels.js +31 -0
- package/dist/channels.js.map +1 -0
- package/dist/errors.d.ts +6 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +20 -0
- package/dist/errors.js.map +1 -0
- package/dist/host.d.ts +45 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +35 -0
- package/dist/host.js.map +1 -0
- package/dist/icons.d.ts +48 -0
- package/dist/icons.d.ts.map +1 -0
- package/dist/icons.js +71 -0
- package/dist/icons.js.map +1 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/labels.d.ts +58 -0
- package/dist/labels.d.ts.map +1 -0
- package/dist/labels.js +86 -0
- package/dist/labels.js.map +1 -0
- package/dist/phone.d.ts +18 -0
- package/dist/phone.d.ts.map +1 -0
- package/dist/phone.js +27 -0
- package/dist/phone.js.map +1 -0
- package/dist/proactiveIcons.d.ts +6 -0
- package/dist/proactiveIcons.d.ts.map +1 -0
- package/dist/proactiveIcons.js +39 -0
- package/dist/proactiveIcons.js.map +1 -0
- package/dist/purposes.d.ts +19 -0
- package/dist/purposes.d.ts.map +1 -0
- package/dist/purposes.js +20 -0
- package/dist/purposes.js.map +1 -0
- package/dist/segments.d.ts +29 -0
- package/dist/segments.d.ts.map +1 -0
- package/dist/segments.js +75 -0
- package/dist/segments.js.map +1 -0
- package/dist/smsSegments.d.ts +28 -0
- package/dist/smsSegments.d.ts.map +1 -0
- package/dist/smsSegments.js +100 -0
- package/dist/smsSegments.js.map +1 -0
- package/dist/styles.d.ts +15 -0
- package/dist/styles.d.ts.map +1 -0
- package/dist/styles.js +545 -0
- package/dist/styles.js.map +1 -0
- package/dist/time.d.ts +14 -0
- package/dist/time.d.ts.map +1 -0
- package/dist/time.js +80 -0
- package/dist/time.js.map +1 -0
- package/dist/useAiSettings.d.ts +11 -0
- package/dist/useAiSettings.d.ts.map +1 -0
- package/dist/useAiSettings.js +21 -0
- package/dist/useAiSettings.js.map +1 -0
- package/dist/useBilling.d.ts +40 -0
- package/dist/useBilling.d.ts.map +1 -0
- package/dist/useBilling.js +155 -0
- package/dist/useBilling.js.map +1 -0
- package/dist/useBulkDrafts.d.ts +41 -0
- package/dist/useBulkDrafts.d.ts.map +1 -0
- package/dist/useBulkDrafts.js +112 -0
- package/dist/useBulkDrafts.js.map +1 -0
- package/dist/useClients.d.ts +16 -0
- package/dist/useClients.d.ts.map +1 -0
- package/dist/useClients.js +22 -0
- package/dist/useClients.js.map +1 -0
- package/dist/useDeliveryStatus.d.ts +7 -0
- package/dist/useDeliveryStatus.d.ts.map +1 -0
- package/dist/useDeliveryStatus.js +39 -0
- package/dist/useDeliveryStatus.js.map +1 -0
- package/dist/useDrafts.d.ts +19 -0
- package/dist/useDrafts.d.ts.map +1 -0
- package/dist/useDrafts.js +60 -0
- package/dist/useDrafts.js.map +1 -0
- package/dist/useInstructions.d.ts +9 -0
- package/dist/useInstructions.d.ts.map +1 -0
- package/dist/useInstructions.js +20 -0
- package/dist/useInstructions.js.map +1 -0
- package/dist/useLiveUpdates.d.ts +9 -0
- package/dist/useLiveUpdates.d.ts.map +1 -0
- package/dist/useLiveUpdates.js +48 -0
- package/dist/useLiveUpdates.js.map +1 -0
- package/dist/usePolling.d.ts +6 -0
- package/dist/usePolling.d.ts.map +1 -0
- package/dist/usePolling.js +31 -0
- package/dist/usePolling.js.map +1 -0
- package/dist/usePreviewDrafts.d.ts +15 -0
- package/dist/usePreviewDrafts.d.ts.map +1 -0
- package/dist/usePreviewDrafts.js +77 -0
- package/dist/usePreviewDrafts.js.map +1 -0
- package/dist/useProactiveOptions.d.ts +15 -0
- package/dist/useProactiveOptions.d.ts.map +1 -0
- package/dist/useProactiveOptions.js +39 -0
- package/dist/useProactiveOptions.js.map +1 -0
- package/dist/useSend.d.ts +16 -0
- package/dist/useSend.d.ts.map +1 -0
- package/dist/useSend.js +50 -0
- package/dist/useSend.js.map +1 -0
- package/dist/useStickToBottom.d.ts +12 -0
- package/dist/useStickToBottom.d.ts.map +1 -0
- package/dist/useStickToBottom.js +71 -0
- package/dist/useStickToBottom.js.map +1 -0
- package/dist/useThread.d.ts +26 -0
- package/dist/useThread.d.ts.map +1 -0
- package/dist/useThread.js +76 -0
- package/dist/useThread.js.map +1 -0
- package/dist/useWhatsAppWindow.d.ts +8 -0
- package/dist/useWhatsAppWindow.d.ts.map +1 -0
- package/dist/useWhatsAppWindow.js +22 -0
- package/dist/useWhatsAppWindow.js.map +1 -0
- package/package.json +36 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef, useState } from "react";
|
|
3
|
+
import { IconChevronDown, IconPencil, IconRefresh, IconSparkles } from "./icons.js";
|
|
4
|
+
export const TONES = [
|
|
5
|
+
{ key: "happy", label: "Happy" },
|
|
6
|
+
{ key: "tough", label: "Tough" },
|
|
7
|
+
{ key: "inquisitive", label: "Question" },
|
|
8
|
+
{ key: "five_words", label: "Concise" },
|
|
9
|
+
];
|
|
10
|
+
/* Display-only cap on the text inside a cell, like native. Never affects what gets injected. */
|
|
11
|
+
const PREVIEW_MAX = 75;
|
|
12
|
+
const previewText = (t) => (t.length > PREVIEW_MAX ? `${t.slice(0, PREVIEW_MAX)}…` : t);
|
|
13
|
+
const LOADING_PHRASES = ["Generating…", "Drafting options…", "Reading context…", "Almost there…"];
|
|
14
|
+
/**
|
|
15
|
+
* The draft grid above the editor, a port of native Uplift's ComposerAssistant: a sparkle header
|
|
16
|
+
* that collapses the 2×2 grid, a regenerate control, shimmer cells with cycling copy while the
|
|
17
|
+
* engine writes, and cells labelled with a pencil because clicking one edits, never sends.
|
|
18
|
+
* Cells keep radio semantics so the picked tone is announced.
|
|
19
|
+
*/
|
|
20
|
+
export function AssistantGrid({ drafts, label, selected, onPick, onRegenerate, regenDisabled, open, onToggle, clientFirstName, footnote, onNeedsPlan }) {
|
|
21
|
+
const cells = useRef([]);
|
|
22
|
+
const [phrase, setPhrase] = useState(0);
|
|
23
|
+
const loading = drafts.status === "loading";
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (!loading) {
|
|
26
|
+
setPhrase(0);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const t = setInterval(() => setPhrase((p) => (p + 1) % LOADING_PHRASES.length), 1400);
|
|
30
|
+
return () => clearInterval(t);
|
|
31
|
+
}, [loading]);
|
|
32
|
+
if (drafts.status === "idle")
|
|
33
|
+
return null;
|
|
34
|
+
const refused = drafts.status === "error" && drafts.error?.code === "refused";
|
|
35
|
+
const planInactive = drafts.status === "error" && drafts.error?.code === "plan_inactive";
|
|
36
|
+
const limited = drafts.retryIn !== null;
|
|
37
|
+
const onKey = (i) => (e) => {
|
|
38
|
+
const n = TONES.length;
|
|
39
|
+
let next = null;
|
|
40
|
+
if (e.key === "ArrowRight" || e.key === "ArrowDown")
|
|
41
|
+
next = (i + 1) % n;
|
|
42
|
+
if (e.key === "ArrowLeft" || e.key === "ArrowUp")
|
|
43
|
+
next = (i - 1 + n) % n;
|
|
44
|
+
if (next === null)
|
|
45
|
+
return;
|
|
46
|
+
e.preventDefault();
|
|
47
|
+
const btn = cells.current[next];
|
|
48
|
+
btn?.focus();
|
|
49
|
+
const tone = TONES[next];
|
|
50
|
+
if (btn && tone && drafts.drafts)
|
|
51
|
+
onPick(tone.key, drafts.drafts[tone.key]);
|
|
52
|
+
};
|
|
53
|
+
return (_jsxs("section", { className: "u-ag", "aria-label": "Drafts", children: [_jsxs("div", { className: "u-ag-h", children: [_jsxs("button", { type: "button", className: "u-ag-toggle", "aria-expanded": open, onClick: onToggle, children: [_jsx("span", { className: "u-ag-spark", children: _jsx(IconSparkles, {}) }), _jsx("span", { className: "u-ag-label", children: label }), _jsx("span", { className: `u-ag-chev${open ? " u-ag-chev-open" : ""}`, children: _jsx(IconChevronDown, {}) })] }), limited && _jsxs("span", { className: "u-ag-by", role: "status", children: ["Try again in ", drafts.retryIn, "s"] }), _jsx("button", { type: "button", className: `u-ag-regen${loading ? " u-ag-spinning" : ""}`, "aria-label": "Regenerate drafts", title: "Regenerate drafts", disabled: loading || limited || regenDisabled, onClick: onRegenerate, children: _jsx(IconRefresh, {}) })] }), open && (refused
|
|
54
|
+
? _jsx("p", { className: "u-ag-empty", children: "Uplift won't draft this one. Write it yourself." })
|
|
55
|
+
: planInactive
|
|
56
|
+
? (_jsxs("div", { className: "u-ag-empty", role: "status", children: [_jsx("span", { children: "Your Uplift plan isn't active, so drafts are paused." }), onNeedsPlan && _jsx("button", { type: "button", className: "u-retry", onClick: onNeedsPlan, children: "Reactivate" })] }))
|
|
57
|
+
: drafts.status === "error"
|
|
58
|
+
? (_jsxs("div", { className: "u-ag-empty", role: "status", children: [_jsxs("span", { children: ["Couldn't write drafts. ", drafts.error?.message] }), !limited && _jsx("button", { type: "button", className: "u-retry", onClick: onRegenerate, children: "Retry" })] }))
|
|
59
|
+
: (_jsx("div", { className: "u-ag-grid", role: "radiogroup", "aria-label": "Pick a draft", "aria-busy": loading, children: TONES.map((t, i) => {
|
|
60
|
+
if (loading) {
|
|
61
|
+
return (_jsxs("div", { className: "u-ag-cell u-ag-loading", "aria-hidden": "true", children: [_jsx("span", { className: "u-ag-shimmer" }), _jsx("span", { className: "u-ag-loading-txt", children: LOADING_PHRASES[phrase] })] }, t.key));
|
|
62
|
+
}
|
|
63
|
+
const text = drafts.drafts?.[t.key] ?? "";
|
|
64
|
+
const checked = selected === t.key;
|
|
65
|
+
return (_jsxs("button", { ref: (el) => { cells.current[i] = el; }, type: "button", role: "radio", "aria-checked": checked, tabIndex: checked || (selected === null && i === 0) ? 0 : -1, className: "u-ag-cell", title: `Edit this draft — nothing sends until you press send\n\n${text}`, onClick: () => onPick(t.key, text), onKeyDown: onKey(i), children: [_jsxs("span", { className: "u-ag-lab", children: [t.label, _jsx("span", { className: "u-ag-pencil", children: _jsx(IconPencil, {}) })] }), _jsx("span", { className: "u-ag-txt", children: previewText(text) || "…" })] }, t.key));
|
|
66
|
+
}) }))), open && footnote && !loading && _jsx("p", { className: "u-ag-foot", children: footnote }), clientFirstName ? null : null] }));
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=AssistantGrid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssistantGrid.js","sourceRoot":"","sources":["../src/AssistantGrid.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type Attachment } from "@uplifted/sdk";
|
|
2
|
+
/** accept strings for the typed menu entries (Photo / Video / File), like native. */
|
|
3
|
+
export declare const PICK_ACCEPT: {
|
|
4
|
+
readonly photo: "image/*";
|
|
5
|
+
readonly video: "video/*";
|
|
6
|
+
readonly file: "application/pdf";
|
|
7
|
+
readonly any: "image/*,video/*,audio/*,application/pdf";
|
|
8
|
+
};
|
|
9
|
+
export interface AttachState {
|
|
10
|
+
count: number;
|
|
11
|
+
uploading: boolean;
|
|
12
|
+
ready: number;
|
|
13
|
+
recording: boolean;
|
|
14
|
+
errors: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface AttachmentPickerHandle {
|
|
17
|
+
/** Ready attachments in send shape. */
|
|
18
|
+
getReady: () => Attachment[];
|
|
19
|
+
isBusy: () => boolean;
|
|
20
|
+
hasErrors: () => boolean;
|
|
21
|
+
clear: () => void;
|
|
22
|
+
/** Open the OS file dialog, optionally scoped (PICK_ACCEPT.photo etc.). */
|
|
23
|
+
openPicker: (accept?: string) => void;
|
|
24
|
+
/** Start the in-composer voice recorder (+ → More… → Voice note). */
|
|
25
|
+
startRecording: () => void;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Composer attachments, a port of native Uplift's AttachmentPicker (GH #353): owns the pending
|
|
29
|
+
* attachment state (pick → validate → presign → direct PUT → ready), renders the chips row and the
|
|
30
|
+
* in-composer voice recorder, and exposes a handle to the composer. The trigger UI (the + menu)
|
|
31
|
+
* lives in the composer. Client-side validation mirrors the server allow-list and 16MB cap so bad
|
|
32
|
+
* files are rejected before any upload; the server re-validates everything.
|
|
33
|
+
*/
|
|
34
|
+
export declare const AttachmentPicker: import("react").ForwardRefExoticComponent<{
|
|
35
|
+
clientId?: string | undefined;
|
|
36
|
+
onChange?: ((s: AttachState) => void) | undefined;
|
|
37
|
+
} & import("react").RefAttributes<AttachmentPickerHandle>>;
|
|
38
|
+
//# sourceMappingURL=AttachmentPicker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AttachmentPicker.d.ts","sourceRoot":"","sources":["../src/AttachmentPicker.tsx"],"names":[],"mappings":"AACA,OAAO,EAAmB,KAAK,UAAU,EAAuB,MAAM,eAAe,CAAC;AAItF,qFAAqF;AACrF,eAAO,MAAM,WAAW;;;;;CAKd,CAAC;AAwBX,MAAM,WAAW,WAAW;IAAG,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE;AACtH,MAAM,WAAW,sBAAsB;IACrC,uCAAuC;IACvC,QAAQ,EAAE,MAAM,UAAU,EAAE,CAAC;IAC7B,MAAM,EAAE,MAAM,OAAO,CAAC;IACtB,SAAS,EAAE,MAAM,OAAO,CAAC;IACzB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,2EAA2E;IAC3E,UAAU,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,qEAAqE;IACrE,cAAc,EAAE,MAAM,IAAI,CAAC;CAC5B;AAID;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB;eAAmD,MAAM,GAAG,SAAS;eAAa,CAAC,CAAC,CAAC,EAAE,WAAW,KAAK,IAAI,CAAC,GAAG,SAAS;0DAyInJ,CAAC"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from "react";
|
|
3
|
+
import { MAX_MEDIA_BYTES } from "@uplifted/sdk";
|
|
4
|
+
import { IconAlert, IconCheck, IconFile, IconFilm, IconLoader, IconMic, IconX } from "./icons.js";
|
|
5
|
+
import { useUplift } from "./UpliftProvider.js";
|
|
6
|
+
/** accept strings for the typed menu entries (Photo / Video / File), like native. */
|
|
7
|
+
export const PICK_ACCEPT = {
|
|
8
|
+
photo: "image/*",
|
|
9
|
+
video: "video/*",
|
|
10
|
+
file: "application/pdf",
|
|
11
|
+
any: "image/*,video/*,audio/*,application/pdf",
|
|
12
|
+
};
|
|
13
|
+
const ALLOWED_PREFIXES = ["image/", "video/", "audio/"];
|
|
14
|
+
const ALLOWED_EXACT = ["application/pdf"];
|
|
15
|
+
function isAllowedMime(mime = "") {
|
|
16
|
+
const m = mime.toLowerCase();
|
|
17
|
+
return ALLOWED_EXACT.includes(m) || ALLOWED_PREFIXES.some((p) => m.startsWith(p));
|
|
18
|
+
}
|
|
19
|
+
function typeFromMime(mime = "") {
|
|
20
|
+
if (mime.startsWith("image/"))
|
|
21
|
+
return "image";
|
|
22
|
+
if (mime.startsWith("video/"))
|
|
23
|
+
return "video";
|
|
24
|
+
if (mime.startsWith("audio/"))
|
|
25
|
+
return "audio";
|
|
26
|
+
return "document";
|
|
27
|
+
}
|
|
28
|
+
/** Best supported MediaRecorder format: Chrome/Firefox → webm/opus, Safari → mp4. */
|
|
29
|
+
function recorderMimeType() {
|
|
30
|
+
if (typeof MediaRecorder === "undefined")
|
|
31
|
+
return null;
|
|
32
|
+
for (const t of ["audio/webm;codecs=opus", "audio/webm", "audio/mp4"])
|
|
33
|
+
if (MediaRecorder.isTypeSupported(t))
|
|
34
|
+
return t;
|
|
35
|
+
return "";
|
|
36
|
+
}
|
|
37
|
+
let nextId = 1;
|
|
38
|
+
/**
|
|
39
|
+
* Composer attachments, a port of native Uplift's AttachmentPicker (GH #353): owns the pending
|
|
40
|
+
* attachment state (pick → validate → presign → direct PUT → ready), renders the chips row and the
|
|
41
|
+
* in-composer voice recorder, and exposes a handle to the composer. The trigger UI (the + menu)
|
|
42
|
+
* lives in the composer. Client-side validation mirrors the server allow-list and 16MB cap so bad
|
|
43
|
+
* files are rejected before any upload; the server re-validates everything.
|
|
44
|
+
*/
|
|
45
|
+
export const AttachmentPicker = forwardRef(function AttachmentPicker({ clientId, onChange }, ref) {
|
|
46
|
+
const { client } = useUplift();
|
|
47
|
+
const [items, setItems] = useState([]);
|
|
48
|
+
const [recording, setRecording] = useState(null);
|
|
49
|
+
const inputRef = useRef(null);
|
|
50
|
+
const recorderRef = useRef(null);
|
|
51
|
+
const itemsRef = useRef([]);
|
|
52
|
+
itemsRef.current = items;
|
|
53
|
+
// The composer mirrors this state for Send; report it after commit, never from inside a state
|
|
54
|
+
// updater (React forbids setting a parent's state while this component renders).
|
|
55
|
+
const onChangeRef = useRef(onChange);
|
|
56
|
+
onChangeRef.current = onChange;
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
onChangeRef.current?.({ count: items.length, uploading: items.some((i) => i.status === "uploading"), ready: items.filter((i) => i.status === "ready").length, recording: recording !== null, errors: items.some((i) => i.status === "error") });
|
|
59
|
+
}, [items, recording]);
|
|
60
|
+
const update = useCallback((updater) => { setItems(updater); }, []);
|
|
61
|
+
const addFiles = useCallback(async (fileList) => {
|
|
62
|
+
for (const file of Array.from(fileList ?? [])) {
|
|
63
|
+
const mime = file.type || "application/octet-stream";
|
|
64
|
+
const id = nextId++;
|
|
65
|
+
if (!isAllowedMime(mime)) {
|
|
66
|
+
update((p) => [...p, { id, name: file.name, mimeType: mime, type: "document", previewUrl: null, status: "error", error: "Not supported — you can send photos, videos, audio, and PDFs" }]);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (file.size > MAX_MEDIA_BYTES) {
|
|
70
|
+
update((p) => [...p, { id, name: file.name, mimeType: mime, type: typeFromMime(mime), previewUrl: null, status: "error", error: "Too large — attachments are limited to 16MB" }]);
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
const type = typeFromMime(mime);
|
|
74
|
+
const previewUrl = type === "image" && typeof URL.createObjectURL === "function" ? URL.createObjectURL(file) : null;
|
|
75
|
+
update((p) => [...p, { id, name: file.name, mimeType: mime, sizeBytes: file.size, type, previewUrl, status: "uploading" }]);
|
|
76
|
+
try {
|
|
77
|
+
const up = await client.createMediaUpload({ contentType: mime, sizeBytes: file.size, ...(clientId ? { clientId } : {}) });
|
|
78
|
+
await client.uploadMedia(up, file, mime);
|
|
79
|
+
update((p) => p.map((i) => (i.id === id ? { ...i, status: "ready", publicUrl: up.publicUrl } : i)));
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
update((p) => p.map((i) => (i.id === id ? { ...i, status: "error", error: err?.message || "Upload failed" } : i)));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}, [client, clientId, update]);
|
|
86
|
+
// ── Voice-note recorder ───────────────────────────────────────────────────
|
|
87
|
+
const stopRecorderInternals = useCallback(() => {
|
|
88
|
+
const r = recorderRef.current;
|
|
89
|
+
if (!r)
|
|
90
|
+
return;
|
|
91
|
+
if (r.timerId)
|
|
92
|
+
clearInterval(r.timerId);
|
|
93
|
+
r.stream.getTracks().forEach((t) => t.stop());
|
|
94
|
+
recorderRef.current = null;
|
|
95
|
+
setRecording(null);
|
|
96
|
+
}, []);
|
|
97
|
+
const startRecording = useCallback(async () => {
|
|
98
|
+
if (recorderRef.current)
|
|
99
|
+
return;
|
|
100
|
+
const mimeType = recorderMimeType();
|
|
101
|
+
if (mimeType === null || !navigator.mediaDevices?.getUserMedia) {
|
|
102
|
+
update((p) => [...p, { id: nextId++, name: "Voice note", mimeType: "", type: "audio", previewUrl: null, status: "error", error: "Recording is not supported in this browser" }]);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
let stream;
|
|
106
|
+
try {
|
|
107
|
+
stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
update((p) => [...p, { id: nextId++, name: "Voice note", mimeType: "", type: "audio", previewUrl: null, status: "error", error: "Microphone access was blocked — allow it in your browser settings" }]);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const mediaRecorder = new MediaRecorder(stream, mimeType ? { mimeType } : undefined);
|
|
114
|
+
const r = { mediaRecorder, chunks: [], stream, timerId: null, cancelled: false, seconds: 0 };
|
|
115
|
+
recorderRef.current = r;
|
|
116
|
+
mediaRecorder.ondataavailable = (e) => { if (e.data?.size)
|
|
117
|
+
r.chunks.push(e.data); };
|
|
118
|
+
mediaRecorder.onstop = () => {
|
|
119
|
+
const wasCancelled = r.cancelled;
|
|
120
|
+
const type = mediaRecorder.mimeType || mimeType || "audio/webm";
|
|
121
|
+
const chunks = r.chunks;
|
|
122
|
+
stopRecorderInternals();
|
|
123
|
+
if (wasCancelled || !chunks.length)
|
|
124
|
+
return;
|
|
125
|
+
const base = type.split(";")[0] ?? "audio/webm";
|
|
126
|
+
const ext = base.includes("mp4") ? "m4a" : "webm";
|
|
127
|
+
const file = new File([new Blob(chunks, { type: base })], `voice-note-${new Date().toISOString().replace(/[:.]/g, "-")}.${ext}`, { type: base });
|
|
128
|
+
void addFiles([file]);
|
|
129
|
+
};
|
|
130
|
+
mediaRecorder.start(250);
|
|
131
|
+
setRecording({ seconds: 0 });
|
|
132
|
+
r.timerId = setInterval(() => {
|
|
133
|
+
r.seconds += 1;
|
|
134
|
+
setRecording({ seconds: r.seconds });
|
|
135
|
+
if (r.seconds >= 300 && r.mediaRecorder.state !== "inactive")
|
|
136
|
+
r.mediaRecorder.stop(); // 5-minute cap keeps files well under 16MB
|
|
137
|
+
}, 1000);
|
|
138
|
+
}, [addFiles, stopRecorderInternals, update]);
|
|
139
|
+
const finishRecording = useCallback((cancelled) => {
|
|
140
|
+
const r = recorderRef.current;
|
|
141
|
+
if (!r)
|
|
142
|
+
return;
|
|
143
|
+
r.cancelled = cancelled;
|
|
144
|
+
if (r.mediaRecorder.state !== "inactive")
|
|
145
|
+
r.mediaRecorder.stop();
|
|
146
|
+
else
|
|
147
|
+
stopRecorderInternals();
|
|
148
|
+
}, [stopRecorderInternals]);
|
|
149
|
+
useEffect(() => () => { if (recorderRef.current)
|
|
150
|
+
finishRecording(true); }, [finishRecording]);
|
|
151
|
+
useImperativeHandle(ref, () => ({
|
|
152
|
+
getReady: () => itemsRef.current.filter((i) => i.status === "ready").map((i) => ({ url: i.publicUrl, mimeType: i.mimeType, type: i.type, filename: i.name, ...(i.sizeBytes != null ? { sizeBytes: i.sizeBytes } : {}) })),
|
|
153
|
+
isBusy: () => itemsRef.current.some((i) => i.status === "uploading") || !!recorderRef.current,
|
|
154
|
+
hasErrors: () => itemsRef.current.some((i) => i.status === "error"),
|
|
155
|
+
clear: () => { finishRecording(true); update(() => []); },
|
|
156
|
+
openPicker: (accept) => { if (inputRef.current) {
|
|
157
|
+
inputRef.current.accept = accept || PICK_ACCEPT.any;
|
|
158
|
+
inputRef.current.click();
|
|
159
|
+
} },
|
|
160
|
+
startRecording: () => { void startRecording(); },
|
|
161
|
+
}), [finishRecording, startRecording, update]);
|
|
162
|
+
const removeItem = (id) => update((prev) => {
|
|
163
|
+
const item = prev.find((i) => i.id === id);
|
|
164
|
+
if (item?.previewUrl?.startsWith("blob:"))
|
|
165
|
+
URL.revokeObjectURL(item.previewUrl);
|
|
166
|
+
return prev.filter((i) => i.id !== id);
|
|
167
|
+
});
|
|
168
|
+
const fmtClock = (s) => `${Math.floor(s / 60)}:${String(s % 60).padStart(2, "0")}`;
|
|
169
|
+
return (_jsxs(_Fragment, { children: [recording && (_jsxs("div", { className: "u-rec", role: "status", "aria-live": "polite", children: [_jsx("span", { className: "u-rec-dot" }), _jsxs("span", { children: ["Recording voice note\u2026 ", fmtClock(recording.seconds)] }), _jsx("button", { type: "button", className: "u-rec-btn", onClick: () => finishRecording(true), title: "Discard recording", "aria-label": "Discard recording", children: _jsx(IconX, {}) }), _jsx("button", { type: "button", className: "u-rec-btn u-rec-done", onClick: () => finishRecording(false), title: "Finish and attach", "aria-label": "Finish and attach recording", children: _jsx(IconCheck, {}) })] })), items.length > 0 && (_jsx("div", { className: "u-chips", children: items.map((item) => (_jsxs("span", { className: `u-chip${item.status === "error" ? " u-chip-err" : ""}`, title: item.error || item.name, children: [item.previewUrl
|
|
170
|
+
? _jsx("img", { src: item.previewUrl, alt: "", className: "u-chip-thumb" })
|
|
171
|
+
: item.status === "error" ? _jsx(IconAlert, {}) : item.type === "video" ? _jsx(IconFilm, {}) : item.type === "audio" ? _jsx(IconMic, {}) : _jsx(IconFile, {}), _jsx("span", { className: "u-chip-name", children: item.name }), item.status === "uploading" && _jsx(IconLoader, {}), item.status === "error" && _jsx("span", { className: "u-chip-errtxt", children: item.error }), _jsx("button", { type: "button", className: "u-chip-x", onClick: () => removeItem(item.id), "aria-label": `Remove ${item.name}`, children: _jsx(IconX, {}) })] }, item.id))) })), _jsx("input", { ref: inputRef, type: "file", multiple: true, accept: PICK_ACCEPT.any, style: { display: "none" }, "data-testid": "attachment-input", onChange: (e) => { void addFiles(e.target.files); e.target.value = ""; } })] }));
|
|
172
|
+
});
|
|
173
|
+
//# sourceMappingURL=AttachmentPicker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AttachmentPicker.js","sourceRoot":"","sources":["../src/AttachmentPicker.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { BulkTarget } from "./useBulkDrafts.js";
|
|
2
|
+
/** Native's label for the feature: the toolbar button title and this sheet's heading. */
|
|
3
|
+
export declare const BULK_GENERATE_FEATURE_TITLE = "AI drafts for multiple clients";
|
|
4
|
+
/** One person the coach can pick: connected, or not connected yet (drafted from host activity). */
|
|
5
|
+
export interface BulkCandidate {
|
|
6
|
+
target: BulkTarget;
|
|
7
|
+
name: string;
|
|
8
|
+
lastActiveAt: string | null;
|
|
9
|
+
connected: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Native Uplift's BulkGenerateModal: pick clients (all selected to start), write a prompt (or reuse
|
|
13
|
+
* one of the last eight), and generate. The sheet closes as soon as generation starts; progress shows
|
|
14
|
+
* on each row. Not-connected clients can be picked too: their drafts come from host activity and
|
|
15
|
+
* sending one opens the connect sheet.
|
|
16
|
+
*/
|
|
17
|
+
export declare function BulkGenerateSheet({ candidates, now, onClose, onGenerate, onEditInstructions }: {
|
|
18
|
+
candidates: ReadonlyArray<BulkCandidate>;
|
|
19
|
+
now: Date;
|
|
20
|
+
onClose: () => void;
|
|
21
|
+
onGenerate: (targets: BulkTarget[], prompt: string) => void;
|
|
22
|
+
/** Shown as "Edit AI instructions" when the coach can edit their AI rules. */
|
|
23
|
+
onEditInstructions?: (() => void) | undefined;
|
|
24
|
+
}): import("react").JSX.Element;
|
|
25
|
+
//# sourceMappingURL=BulkGenerateSheet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BulkGenerateSheet.d.ts","sourceRoot":"","sources":["../src/BulkGenerateSheet.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,yFAAyF;AACzF,eAAO,MAAM,2BAA2B,mCAAmC,CAAC;AAE5E,mGAAmG;AACnG,MAAM,WAAW,aAAa;IAAG,MAAM,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE;AAgBpH;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,EAAE;IAC9F,UAAU,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;IACzC,GAAG,EAAE,IAAI,CAAC;IACV,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5D,8EAA8E;IAC9E,kBAAkB,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;CAC/C,+BA8FA"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
+
import { IconSparkles, IconX } from "./icons.js";
|
|
4
|
+
import { avatarColor, initials } from "./labels.js";
|
|
5
|
+
import { Sheet } from "./Sheet.js";
|
|
6
|
+
import { relativeShort } from "./time.js";
|
|
7
|
+
/** Native's label for the feature: the toolbar button title and this sheet's heading. */
|
|
8
|
+
export const BULK_GENERATE_FEATURE_TITLE = "AI drafts for multiple clients";
|
|
9
|
+
const HISTORY_KEY = "uplift_panel_bulk_prompts";
|
|
10
|
+
const HISTORY_MAX = 8;
|
|
11
|
+
const PROMPT_MAX = 500;
|
|
12
|
+
function loadHistory() {
|
|
13
|
+
try {
|
|
14
|
+
const v = JSON.parse(localStorage.getItem(HISTORY_KEY) || "[]");
|
|
15
|
+
return Array.isArray(v) ? v.filter((x) => typeof x === "string").slice(0, HISTORY_MAX) : [];
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function saveHistory(list) {
|
|
22
|
+
try {
|
|
23
|
+
localStorage.setItem(HISTORY_KEY, JSON.stringify(list));
|
|
24
|
+
}
|
|
25
|
+
catch { /* private mode */ }
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Native Uplift's BulkGenerateModal: pick clients (all selected to start), write a prompt (or reuse
|
|
29
|
+
* one of the last eight), and generate. The sheet closes as soon as generation starts; progress shows
|
|
30
|
+
* on each row. Not-connected clients can be picked too: their drafts come from host activity and
|
|
31
|
+
* sending one opens the connect sheet.
|
|
32
|
+
*/
|
|
33
|
+
export function BulkGenerateSheet({ candidates, now, onClose, onGenerate, onEditInstructions }) {
|
|
34
|
+
const keyOf = (c) => `${c.target.kind}:${c.target.id}`;
|
|
35
|
+
const [selected, setSelected] = useState(() => new Set(candidates.map(keyOf)));
|
|
36
|
+
const [prompt, setPrompt] = useState("");
|
|
37
|
+
const [history, setHistory] = useState(loadHistory);
|
|
38
|
+
const promptRef = useRef(null);
|
|
39
|
+
// Start in the prompt, like native. Deferred: Sheet focuses its first control after this effect.
|
|
40
|
+
useEffect(() => { const t = setTimeout(() => promptRef.current?.focus(), 0); return () => clearTimeout(t); }, []);
|
|
41
|
+
const picked = useMemo(() => candidates.filter((c) => selected.has(keyOf(c))), [candidates, selected]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
42
|
+
const allSelected = candidates.length > 0 && picked.length === candidates.length;
|
|
43
|
+
const canGenerate = prompt.trim().length > 0 && picked.length > 0;
|
|
44
|
+
const toggle = (k) => setSelected((s) => { const n = new Set(s); if (n.has(k))
|
|
45
|
+
n.delete(k);
|
|
46
|
+
else
|
|
47
|
+
n.add(k); return n; });
|
|
48
|
+
const toggleAll = () => setSelected(allSelected ? new Set() : new Set(candidates.map(keyOf)));
|
|
49
|
+
const generate = () => {
|
|
50
|
+
if (!canGenerate)
|
|
51
|
+
return;
|
|
52
|
+
const p = prompt.trim();
|
|
53
|
+
const next = [p, ...history.filter((h) => h !== p)].slice(0, HISTORY_MAX);
|
|
54
|
+
setHistory(next);
|
|
55
|
+
saveHistory(next);
|
|
56
|
+
onGenerate(picked.map((c) => c.target), p);
|
|
57
|
+
onClose();
|
|
58
|
+
};
|
|
59
|
+
return (_jsxs(Sheet, { labelledBy: "u-bulk-title", onClose: onClose, children: [_jsxs("div", { className: "u-bulk-head", children: [_jsx("span", { className: "u-bulk-spark", "aria-hidden": "true", children: _jsx(IconSparkles, {}) }), _jsxs("div", { className: "u-bulk-titles", children: [_jsx("h3", { id: "u-bulk-title", children: BULK_GENERATE_FEATURE_TITLE }), _jsxs("p", { className: "u-bulk-sub", children: ["Describe what you want to say\u2014we'll suggest draft options per client.", onEditInstructions && _jsxs(_Fragment, { children: [" ", _jsx("button", { type: "button", className: "u-linkbtn", onClick: onEditInstructions, children: "Edit AI instructions" })] })] })] }), _jsx("button", { type: "button", className: "u-iconbtn", "aria-label": "Close", title: "Close", onClick: onClose, children: _jsx(IconX, {}) })] }), _jsxs("section", { className: "u-bulk-sec", "aria-labelledby": "u-bulk-to", children: [_jsxs("div", { className: "u-bulk-sechead", children: [_jsx("span", { id: "u-bulk-to", className: "u-bulk-label", children: "To" }), _jsx("button", { type: "button", className: "u-linkbtn", onClick: toggleAll, children: allSelected ? "Deselect all" : `Select all (${candidates.length})` })] }), _jsxs("div", { className: "u-bulk-chips", children: [candidates.length === 0 && _jsx("span", { className: "u-bulk-empty", children: "No clients yet." }), candidates.map((c) => {
|
|
60
|
+
const k = keyOf(c);
|
|
61
|
+
const on = selected.has(k);
|
|
62
|
+
return (_jsxs("button", { type: "button", className: `u-bulk-chip${on ? " u-bulk-chip-on" : ""}`, "aria-pressed": on, onClick: () => toggle(k), title: c.connected ? c.name : `${c.name}: not connected yet. Drafts come from their activity; sending asks you to connect them.`, children: [_jsx("span", { className: "u-bulk-av", style: { background: avatarColor(c.target.id), opacity: c.connected ? 1 : 0.7 }, "aria-hidden": "true", children: initials(c.name) }), _jsx("span", { className: "u-bulk-name", children: c.name }), c.lastActiveAt && _jsx("span", { className: "u-bulk-meta", children: relativeShort(c.lastActiveAt, now) })] }, k));
|
|
63
|
+
})] })] }), _jsxs("section", { className: "u-bulk-sec", children: [_jsx("div", { className: "u-bulk-sechead", children: _jsx("label", { htmlFor: "u-bulk-prompt", className: "u-bulk-label", children: "Prompt" }) }), _jsx("textarea", { id: "u-bulk-prompt", ref: promptRef, rows: 4, maxLength: PROMPT_MAX, className: "u-bulk-prompt", value: prompt, onChange: (e) => setPrompt(e.target.value), placeholder: "e.g. Check in with each client based on the time of day and their most recent update." }), history.length > 0 && (_jsxs("div", { className: "u-bulk-hist", children: [_jsx("span", { className: "u-bulk-histlabel", children: "Recent:" }), history.map((h) => (_jsx("button", { type: "button", className: "u-bulk-histbtn", title: h, onClick: () => { setPrompt(h); promptRef.current?.focus(); }, children: h.length > 48 ? `${h.slice(0, 48)}…` : h }, h)))] }))] }), _jsxs("div", { className: "u-bulk-foot", children: [_jsx("button", { type: "button", className: "u-secondary", onClick: onClose, children: "Cancel" }), _jsxs("button", { type: "button", className: "u-send u-bulk-go", disabled: !canGenerate, onClick: generate, children: [_jsx(IconSparkles, {}), "Generate for ", picked.length, " client", picked.length === 1 ? "" : "s"] })] })] }));
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=BulkGenerateSheet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BulkGenerateSheet.js","sourceRoot":"","sources":["../src/BulkGenerateSheet.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Channel } from "@uplifted/sdk";
|
|
2
|
+
/**
|
|
3
|
+
* Corner badge on a client's avatar showing the channel they message through, ported from
|
|
4
|
+
* uplift_coach client/src/components/ui/ChannelBadge.jsx: WhatsApp green with the official glyph,
|
|
5
|
+
* SMS a speech bubble on the highlight colour. A missing channel is SMS, the platform default.
|
|
6
|
+
*/
|
|
7
|
+
export declare function WhatsAppGlyph({ size }: {
|
|
8
|
+
size?: number;
|
|
9
|
+
}): import("react").JSX.Element;
|
|
10
|
+
export declare function SmsGlyph({ size }: {
|
|
11
|
+
size?: number;
|
|
12
|
+
}): import("react").JSX.Element;
|
|
13
|
+
export declare function ChannelBadge({ channel }: {
|
|
14
|
+
channel: Channel | null | undefined;
|
|
15
|
+
}): import("react").JSX.Element;
|
|
16
|
+
//# sourceMappingURL=ChannelBadge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChannelBadge.d.ts","sourceRoot":"","sources":["../src/ChannelBadge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAG7C;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAAE,IAAS,EAAE,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,+BAM7D;AAED,wBAAgB,QAAQ,CAAC,EAAE,IAAS,EAAE,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,+BAMxD;AAED,wBAAgB,YAAY,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAAA;CAAE,+BAQhF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { channelLabel } from "./labels.js";
|
|
3
|
+
/**
|
|
4
|
+
* Corner badge on a client's avatar showing the channel they message through, ported from
|
|
5
|
+
* uplift_coach client/src/components/ui/ChannelBadge.jsx: WhatsApp green with the official glyph,
|
|
6
|
+
* SMS a speech bubble on the highlight colour. A missing channel is SMS, the platform default.
|
|
7
|
+
*/
|
|
8
|
+
export function WhatsAppGlyph({ size = 10 }) {
|
|
9
|
+
return (_jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", children: _jsx("path", { d: "M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.297-.347.446-.52.149-.174.198-.298.297-.497.1-.198.05-.371-.025-.52-.074-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 0 1-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 0 1-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 0 1 2.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0 0 12.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 0 0 5.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 0 0-3.48-8.413Z" }) }));
|
|
10
|
+
}
|
|
11
|
+
export function SmsGlyph({ size = 10 }) {
|
|
12
|
+
return (_jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", children: _jsx("path", { d: "M12 2C6.48 2 2 5.94 2 10.8c0 2.8 1.5 5.29 3.83 6.9-.14 1.13-.6 2.4-1.62 3.5-.2.22-.03.58.27.55 2.05-.2 3.66-1.05 4.79-1.93.87.21 1.79.33 2.73.33 5.52 0 10-3.94 10-8.8S17.52 2 12 2Z" }) }));
|
|
13
|
+
}
|
|
14
|
+
export function ChannelBadge({ channel }) {
|
|
15
|
+
const wa = channel === "whatsapp";
|
|
16
|
+
const label = channelLabel(wa ? "whatsapp" : "sms");
|
|
17
|
+
return (_jsx("span", { className: `u-chan-badge ${wa ? "u-chan-wa" : "u-chan-sms"}`, title: `Messages via ${label}`, "aria-label": `Channel: ${label}`, role: "img", children: wa ? _jsx(WhatsAppGlyph, {}) : _jsx(SmsGlyph, {}) }));
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=ChannelBadge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChannelBadge.js","sourceRoot":"","sources":["../src/ChannelBadge.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,EAAE,IAAI,GAAG,EAAE,EAAqB;IAC5D,OAAO,CACL,cAAK,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,cAAc,iBAAa,MAAM,YACxF,eAAM,CAAC,EAAC,ylCAAylC,GAAG,GAChmC,CACP,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,EAAE,IAAI,GAAG,EAAE,EAAqB;IACvD,OAAO,CACL,cAAK,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,cAAc,iBAAa,MAAM,YACxF,eAAM,CAAC,EAAC,sLAAsL,GAAG,GAC7L,CACP,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,EAAE,OAAO,EAA2C;IAC/E,MAAM,EAAE,GAAG,OAAO,KAAK,UAAU,CAAC;IAClC,MAAM,KAAK,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACpD,OAAO,CACL,eAAM,SAAS,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,gBAAgB,KAAK,EAAE,gBAAc,YAAY,KAAK,EAAE,EAAE,IAAI,EAAC,KAAK,YAC5I,EAAE,CAAC,CAAC,CAAC,KAAC,aAAa,KAAG,CAAC,CAAC,CAAC,KAAC,QAAQ,KAAG,GACjC,CACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Channel } from "@uplifted/sdk";
|
|
2
|
+
/**
|
|
3
|
+
* How a channel works, a port of native Uplift's ChannelDisclaimerModal: WhatsApp's 24-hour window
|
|
4
|
+
* with phone mockups of both sides in both states, and SMS's US/Canada and media limits.
|
|
5
|
+
* Informational only; it stacks over whatever sheet opened it.
|
|
6
|
+
*/
|
|
7
|
+
export declare function ChannelExplainer({ channel, onClose }: {
|
|
8
|
+
channel: Channel;
|
|
9
|
+
onClose: () => void;
|
|
10
|
+
}): import("react").JSX.Element;
|
|
11
|
+
/** The ⓘ that opens the explainer for a channel. */
|
|
12
|
+
export declare function ChannelInfoButton({ channel, label, onOpen }: {
|
|
13
|
+
channel: Channel;
|
|
14
|
+
label: string;
|
|
15
|
+
onOpen: (c: Channel) => void;
|
|
16
|
+
}): import("react").JSX.Element;
|
|
17
|
+
//# sourceMappingURL=ChannelExplainer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChannelExplainer.d.ts","sourceRoot":"","sources":["../src/ChannelExplainer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAoC7C;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,+BA6C/F;AAED,oDAAoD;AACpD,wBAAgB,iBAAiB,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;CAAE,+BAM9H"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { WhatsAppGlyph, SmsGlyph } from "./ChannelBadge.js";
|
|
3
|
+
import { IconInfo } from "./icons.js";
|
|
4
|
+
import { Sheet } from "./Sheet.js";
|
|
5
|
+
const MOCK_MSG = "Great session today — let’s aim for 3 workouts this week 💪";
|
|
6
|
+
/** One coach-side and one client-side phone mock for a window state (native ChannelDisclaimerModal MockupPair). */
|
|
7
|
+
function MockupPair({ closed }) {
|
|
8
|
+
return (_jsxs("div", { className: "u-cx-mocks", children: [_jsxs("div", { className: "u-cx-col", children: [_jsx("span", { className: "u-cx-label", children: "What you see" }), _jsxs("div", { className: "u-cx-phone u-cx-coach", children: [_jsxs("div", { className: "u-cx-coach-bub", children: [MOCK_MSG, closed && _jsx("span", { className: "u-cx-tpl", children: "Sent using template" })] }), _jsx("span", { className: "u-cx-meta", children: closed ? "You write normally — Uplift wraps it for you" : "Normal chat — text, photos, video, voice notes" })] })] }), _jsxs("div", { className: "u-cx-col", children: [_jsx("span", { className: "u-cx-label", children: "What your client sees" }), _jsxs("div", { className: "u-cx-phone u-cx-client", children: [_jsx("div", { className: "u-cx-client-bub", children: closed
|
|
9
|
+
? _jsxs(_Fragment, { children: [_jsx("strong", { children: "New message from your coach" }), " — “Great session today — let’s aim for…”", _jsx("span", { className: "u-cx-link", children: "Tap to read & reply" })] })
|
|
10
|
+
: MOCK_MSG }), _jsx("span", { className: "u-cx-meta", children: closed ? "One reply reopens the 24-hour window" : "Your message, exactly as written" })] })] })] }));
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* How a channel works, a port of native Uplift's ChannelDisclaimerModal: WhatsApp's 24-hour window
|
|
14
|
+
* with phone mockups of both sides in both states, and SMS's US/Canada and media limits.
|
|
15
|
+
* Informational only; it stacks over whatever sheet opened it.
|
|
16
|
+
*/
|
|
17
|
+
export function ChannelExplainer({ channel, onClose }) {
|
|
18
|
+
const wa = channel === "whatsapp";
|
|
19
|
+
return (_jsxs(Sheet, { labelledBy: "u-cx-title", onClose: onClose, children: [_jsxs("div", { className: "u-cx-head", children: [_jsx("span", { className: `u-cx-mark ${wa ? "u-chan-wa" : "u-chan-sms"}`, "aria-hidden": "true", children: wa ? _jsx(WhatsAppGlyph, { size: 16 }) : _jsx(SmsGlyph, { size: 16 }) }), _jsx("h3", { id: "u-cx-title", children: wa ? "How WhatsApp messaging works" : "How SMS messaging works" })] }), wa ? (_jsxs(_Fragment, { children: [_jsxs("p", { className: "u-lede", children: ["WhatsApp is run by Meta, and Meta enforces one big rule for business messaging: the ", _jsx("strong", { children: "24-hour window" }), ". It changes how your messages reach this client, so here\u2019s the honest picture before you commit."] }), _jsxs("div", { className: "u-cx-rule", children: [_jsx("h4", { children: "Window open \u2014 normal messaging" }), _jsx("p", { children: "Every time your client messages you, a 24-hour window opens. Inside it, everything works like regular chat: texts, photos, videos, voice notes \u2014 sent and delivered instantly." })] }), _jsxs("div", { className: "u-cx-rule", children: [_jsx("h4", { children: "Window closed \u2014 messages go inside a template" }), _jsx("p", { children: "If your client hasn\u2019t messaged you in the last 24 hours, Meta only allows pre-approved templates. Uplift handles this automatically: your message is wrapped in an approved template \u2014 the client gets a notification with a preview and a secure link, and one reply from them reopens normal messaging." })] }), _jsx("span", { className: "u-cx-sec", children: "\u2705 Within the 24-hour window" }), _jsx(MockupPair, { closed: false }), _jsx("span", { className: "u-cx-sec", children: "\u23F3 Outside the 24-hour window" }), _jsx(MockupPair, { closed: true }), _jsx("p", { className: "u-cx-foot", children: "Clients who message you regularly will rarely notice any of this \u2014 the window stays open. It matters most for quiet clients you\u2019re re-engaging." })] })) : (_jsxs(_Fragment, { children: [_jsxs("p", { className: "u-lede", children: ["SMS is the zero-friction channel \u2014 nothing to install, nothing to tap \u2014 but it only works reliably for ", _jsx("strong", { children: "US & Canada numbers" }), "."] }), _jsxs("div", { className: "u-cx-rule", children: [_jsx("h4", { children: "US & Canada only" }), _jsx("p", { children: "Uplift\u2019s texting runs on US carrier-registered numbers. Messages to international numbers are unreliable and often silently fail \u2014 if your client is outside the US/Canada, choose WhatsApp instead." })] }), _jsxs("div", { className: "u-cx-rule", children: [_jsx("h4", { children: "Media has carrier limits" }), _jsx("p", { children: "Photos and short videos (about 1MB) send as picture messages; anything bigger \u2014 plus voice notes and PDFs \u2014 is delivered as a tap-to-open link. Clients can text you photos, videos, and voice memos back, but not documents." })] }), _jsx("p", { className: "u-cx-foot", children: "No time-window rules and no app required \u2014 for US clients, SMS is usually the right default." })] })), _jsxs("div", { className: "u-actions", children: [_jsx("span", { className: "u-sp" }), _jsx("button", { type: "button", className: "u-send", onClick: onClose, children: "Got it" })] })] }));
|
|
20
|
+
}
|
|
21
|
+
/** The ⓘ that opens the explainer for a channel. */
|
|
22
|
+
export function ChannelInfoButton({ channel, label, onOpen }) {
|
|
23
|
+
return (_jsx("button", { type: "button", className: "u-cx-info", "aria-label": `How ${label} works`, title: `How ${label} works`, onClick: (e) => { e.stopPropagation(); onOpen(channel); }, children: _jsx(IconInfo, {}) }));
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=ChannelExplainer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChannelExplainer.js","sourceRoot":"","sources":["../src/ChannelExplainer.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { Client, DraftSet, UpliftError } from "@uplifted/sdk";
|
|
3
|
+
import { type HostClient } from "./host.js";
|
|
4
|
+
import { type InboxRow, type SortMode } from "./labels.js";
|
|
5
|
+
import type { LoadStatus } from "./useClients.js";
|
|
6
|
+
import type { BulkRowStatus } from "./useBulkDrafts.js";
|
|
7
|
+
export interface ClientListProps {
|
|
8
|
+
status: LoadStatus;
|
|
9
|
+
error: UpliftError | null;
|
|
10
|
+
/** Rows to show, connected and not-connected clients together, already searched and sorted. */
|
|
11
|
+
rows: InboxRow[];
|
|
12
|
+
/** Connected plus not-connected clients before search: tells "no clients yet" from "no match". */
|
|
13
|
+
totalCount: number;
|
|
14
|
+
search: string;
|
|
15
|
+
onSearch: (q: string) => void;
|
|
16
|
+
sort: SortMode;
|
|
17
|
+
onSort: (mode: SortMode) => void;
|
|
18
|
+
selectedId: string | null;
|
|
19
|
+
onOpen: (client: Client) => void;
|
|
20
|
+
onRetry: () => void;
|
|
21
|
+
onAddClient: () => void;
|
|
22
|
+
/** Opens Bulk generate (native BulkGenerateModal). Native Uplift's sparkles + messages icon at the end of the toolbar. */
|
|
23
|
+
onBulk?: () => void;
|
|
24
|
+
bulkDisabled?: boolean;
|
|
25
|
+
/** AI settings + full screen, shown in the toolbar only on narrow panels (the conversation header has them otherwise). */
|
|
26
|
+
headActions?: ReactNode;
|
|
27
|
+
/** Bulk generate drafts by row key (client id, or `host:<id>`): they take over the row's quick-send chip, like native. */
|
|
28
|
+
drafts: Readonly<Record<string, DraftSet>>;
|
|
29
|
+
/** Bulk generate progress by row key: "Generating…" / "Generation failed" in the quick-send slot. */
|
|
30
|
+
bulkStatus?: Readonly<Record<string, BulkRowStatus>> | undefined;
|
|
31
|
+
/** A quick-send chip sent the prepared draft: refresh the row. */
|
|
32
|
+
onQuickSent?: ((client: Client, body: string) => void) | undefined;
|
|
33
|
+
/** The host app's name, for the "not connected" line. */
|
|
34
|
+
hostName?: string | undefined;
|
|
35
|
+
/** The host owns the client list (it passed hostClients): no add-client entry points here, clients are connected from their host rows. */
|
|
36
|
+
hostManaged?: boolean | undefined;
|
|
37
|
+
onOpenHost?: ((host: HostClient) => void) | undefined;
|
|
38
|
+
/** "Not connected" on a host row: opens the connect sheet for that client. */
|
|
39
|
+
onConnectHost?: ((host: HostClient) => void) | undefined;
|
|
40
|
+
now: Date;
|
|
41
|
+
}
|
|
42
|
+
export declare function ClientList(p: ClientListProps): import("react").JSX.Element;
|
|
43
|
+
//# sourceMappingURL=ClientList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClientList.d.ts","sourceRoot":"","sources":["../src/ClientList.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAsB,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAGhE,OAAO,EAAgD,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGzG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IAC1B,+FAA+F;IAC/F,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,kGAAkG;IAClG,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IACjC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,0HAA0H;IAC1H,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,0HAA0H;IAC1H,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,0HAA0H;IAC1H,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC3C,qGAAqG;IACrG,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,GAAG,SAAS,CAAC;IACjE,kEAAkE;IAClE,WAAW,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACnE,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,0IAA0I;IAC1I,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAClC,UAAU,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACtD,8EAA8E;IAC9E,aAAa,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACzD,GAAG,EAAE,IAAI,CAAC;CACX;AAyBD,wBAAgB,UAAU,CAAC,CAAC,EAAE,eAAe,+BAgE5C"}
|