@repzo/widget-react-native 1.0.0 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +167 -74
- package/lib/commonjs/api/client.js +3 -1
- package/lib/commonjs/api/client.js.map +1 -1
- package/lib/commonjs/api/realtime.js +2 -0
- package/lib/commonjs/api/realtime.js.map +1 -1
- package/lib/commonjs/attachments/pickers.js +493 -0
- package/lib/commonjs/attachments/pickers.js.map +1 -0
- package/lib/commonjs/i18n.js +45 -0
- package/lib/commonjs/i18n.js.map +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/locales.js +21 -0
- package/lib/commonjs/locales.js.map +1 -1
- package/lib/commonjs/state/widget-store.js +256 -18
- package/lib/commonjs/state/widget-store.js.map +1 -1
- package/lib/commonjs/types.js +16 -0
- package/lib/commonjs/types.js.map +1 -1
- package/lib/commonjs/ui/WidgetProvider.js +70 -10
- package/lib/commonjs/ui/WidgetProvider.js.map +1 -1
- package/lib/commonjs/ui/components/AttachmentChips.js +135 -0
- package/lib/commonjs/ui/components/AttachmentChips.js.map +1 -0
- package/lib/commonjs/ui/components/AttachmentMenu.js +125 -0
- package/lib/commonjs/ui/components/AttachmentMenu.js.map +1 -0
- package/lib/commonjs/ui/components/ImageViewer.js +181 -0
- package/lib/commonjs/ui/components/ImageViewer.js.map +1 -0
- package/lib/commonjs/ui/components/InAppNotification.js +210 -0
- package/lib/commonjs/ui/components/InAppNotification.js.map +1 -0
- package/lib/commonjs/ui/components/TeamAvatars.js +63 -0
- package/lib/commonjs/ui/components/TeamAvatars.js.map +1 -0
- package/lib/commonjs/ui/components/icons.js +50 -0
- package/lib/commonjs/ui/components/icons.js.map +1 -1
- package/lib/commonjs/ui/screens/chat/ChatView.js +303 -24
- package/lib/commonjs/ui/screens/chat/ChatView.js.map +1 -1
- package/lib/commonjs/ui/screens/chat/ChatView.styles.js +70 -0
- package/lib/commonjs/ui/screens/chat/ChatView.styles.js.map +1 -1
- package/lib/module/api/client.js +3 -1
- package/lib/module/api/client.js.map +1 -1
- package/lib/module/api/realtime.js +2 -0
- package/lib/module/api/realtime.js.map +1 -1
- package/lib/module/attachments/pickers.js +479 -0
- package/lib/module/attachments/pickers.js.map +1 -0
- package/lib/module/i18n.js +44 -0
- package/lib/module/i18n.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/locales.js +21 -0
- package/lib/module/locales.js.map +1 -1
- package/lib/module/state/widget-store.js +256 -18
- package/lib/module/state/widget-store.js.map +1 -1
- package/lib/module/types.js +16 -0
- package/lib/module/types.js.map +1 -1
- package/lib/module/ui/WidgetProvider.js +71 -11
- package/lib/module/ui/WidgetProvider.js.map +1 -1
- package/lib/module/ui/components/AttachmentChips.js +131 -0
- package/lib/module/ui/components/AttachmentChips.js.map +1 -0
- package/lib/module/ui/components/AttachmentMenu.js +120 -0
- package/lib/module/ui/components/AttachmentMenu.js.map +1 -0
- package/lib/module/ui/components/ImageViewer.js +177 -0
- package/lib/module/ui/components/ImageViewer.js.map +1 -0
- package/lib/module/ui/components/InAppNotification.js +208 -0
- package/lib/module/ui/components/InAppNotification.js.map +1 -0
- package/lib/module/ui/components/TeamAvatars.js +59 -0
- package/lib/module/ui/components/TeamAvatars.js.map +1 -0
- package/lib/module/ui/components/icons.js +49 -0
- package/lib/module/ui/components/icons.js.map +1 -1
- package/lib/module/ui/screens/chat/ChatView.js +306 -27
- package/lib/module/ui/screens/chat/ChatView.js.map +1 -1
- package/lib/module/ui/screens/chat/ChatView.styles.js +70 -0
- package/lib/module/ui/screens/chat/ChatView.styles.js.map +1 -1
- package/lib/typescript/commonjs/api/client.d.ts +8 -2
- package/lib/typescript/commonjs/api/client.d.ts.map +1 -1
- package/lib/typescript/commonjs/api/realtime.d.ts.map +1 -1
- package/lib/typescript/commonjs/attachments/pickers.d.ts +81 -0
- package/lib/typescript/commonjs/attachments/pickers.d.ts.map +1 -0
- package/lib/typescript/commonjs/i18n.d.ts +23 -0
- package/lib/typescript/commonjs/i18n.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +1 -1
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/locales.d.ts.map +1 -1
- package/lib/typescript/commonjs/state/widget-store.d.ts +40 -2
- package/lib/typescript/commonjs/state/widget-store.d.ts.map +1 -1
- package/lib/typescript/commonjs/types.d.ts +88 -1
- package/lib/typescript/commonjs/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/WidgetProvider.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/AttachmentChips.d.ts +16 -0
- package/lib/typescript/commonjs/ui/components/AttachmentChips.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/AttachmentMenu.d.ts +28 -0
- package/lib/typescript/commonjs/ui/components/AttachmentMenu.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/ImageViewer.d.ts +23 -0
- package/lib/typescript/commonjs/ui/components/ImageViewer.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/InAppNotification.d.ts +28 -0
- package/lib/typescript/commonjs/ui/components/InAppNotification.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/TeamAvatars.d.ts +17 -0
- package/lib/typescript/commonjs/ui/components/TeamAvatars.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/icons.d.ts +2 -0
- package/lib/typescript/commonjs/ui/components/icons.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/chat/ChatView.d.ts +3 -2
- package/lib/typescript/commonjs/ui/screens/chat/ChatView.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/chat/ChatView.styles.d.ts +69 -0
- package/lib/typescript/commonjs/ui/screens/chat/ChatView.styles.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/chat/ChatView.types.d.ts +41 -2
- package/lib/typescript/commonjs/ui/screens/chat/ChatView.types.d.ts.map +1 -1
- package/lib/typescript/module/api/client.d.ts +8 -2
- package/lib/typescript/module/api/client.d.ts.map +1 -1
- package/lib/typescript/module/api/realtime.d.ts.map +1 -1
- package/lib/typescript/module/attachments/pickers.d.ts +81 -0
- package/lib/typescript/module/attachments/pickers.d.ts.map +1 -0
- package/lib/typescript/module/i18n.d.ts +23 -0
- package/lib/typescript/module/i18n.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +1 -1
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/locales.d.ts.map +1 -1
- package/lib/typescript/module/state/widget-store.d.ts +40 -2
- package/lib/typescript/module/state/widget-store.d.ts.map +1 -1
- package/lib/typescript/module/types.d.ts +88 -1
- package/lib/typescript/module/types.d.ts.map +1 -1
- package/lib/typescript/module/ui/WidgetProvider.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/AttachmentChips.d.ts +16 -0
- package/lib/typescript/module/ui/components/AttachmentChips.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/AttachmentMenu.d.ts +28 -0
- package/lib/typescript/module/ui/components/AttachmentMenu.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/ImageViewer.d.ts +23 -0
- package/lib/typescript/module/ui/components/ImageViewer.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/InAppNotification.d.ts +28 -0
- package/lib/typescript/module/ui/components/InAppNotification.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/TeamAvatars.d.ts +17 -0
- package/lib/typescript/module/ui/components/TeamAvatars.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/icons.d.ts +2 -0
- package/lib/typescript/module/ui/components/icons.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/chat/ChatView.d.ts +3 -2
- package/lib/typescript/module/ui/screens/chat/ChatView.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/chat/ChatView.styles.d.ts +69 -0
- package/lib/typescript/module/ui/screens/chat/ChatView.styles.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/chat/ChatView.types.d.ts +41 -2
- package/lib/typescript/module/ui/screens/chat/ChatView.types.d.ts.map +1 -1
- package/metro.js +17 -32
- package/package.json +18 -1
- package/src/api/client.ts +5 -3
- package/src/api/realtime.ts +2 -0
- package/src/attachments/pickers.ts +515 -0
- package/src/i18n.ts +48 -0
- package/src/index.tsx +4 -0
- package/src/locales.ts +21 -0
- package/src/state/widget-store.ts +256 -19
- package/src/types.ts +95 -0
- package/src/ui/WidgetProvider.tsx +90 -9
- package/src/ui/components/AttachmentChips.tsx +135 -0
- package/src/ui/components/AttachmentMenu.tsx +132 -0
- package/src/ui/components/ImageViewer.tsx +178 -0
- package/src/ui/components/InAppNotification.tsx +225 -0
- package/src/ui/components/TeamAvatars.tsx +58 -0
- package/src/ui/components/icons.tsx +37 -0
- package/src/ui/screens/chat/ChatView.styles.ts +70 -0
- package/src/ui/screens/chat/ChatView.tsx +345 -35
- package/src/ui/screens/chat/ChatView.types.ts +51 -2
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.MAX_TOTAL_ATTACHMENT_BYTES = exports.MAX_ATTACHMENT_BYTES = exports.MAX_ATTACHMENTS = void 0;
|
|
7
|
+
exports.base64ByteLength = base64ByteLength;
|
|
8
|
+
exports.buildDataUrl = buildDataUrl;
|
|
9
|
+
exports.checkAttachmentFits = checkAttachmentFits;
|
|
10
|
+
exports.formatBytes = formatBytes;
|
|
11
|
+
exports.getAttachmentSources = getAttachmentSources;
|
|
12
|
+
exports.isImageAttachment = isImageAttachment;
|
|
13
|
+
exports.normalizeContentType = normalizeContentType;
|
|
14
|
+
exports.pickAttachments = pickAttachments;
|
|
15
|
+
exports.setAttachmentOptions = setAttachmentOptions;
|
|
16
|
+
exports.stripDataUrlPrefix = stripDataUrlPrefix;
|
|
17
|
+
/**
|
|
18
|
+
* Visitor attachments: picking photos/files and turning them into the base64
|
|
19
|
+
* data URLs `POST /api/widget/messages` accepts.
|
|
20
|
+
*
|
|
21
|
+
* The SDK ships no native code, so every picker is borrowed from the host —
|
|
22
|
+
* the same approach as `storage.ts` and `native-gradient.ts`:
|
|
23
|
+
* - `expo-image-picker` → photo library and camera
|
|
24
|
+
* - `expo-document-picker` → any file
|
|
25
|
+
* - `expo-file-system` → reads a picked file as base64 (optional; without it
|
|
26
|
+
* the file is read through `fetch` + `FileReader`)
|
|
27
|
+
* - `expo-image-manipulator` → shrinks photos to fit the 1.5 MB cap (optional;
|
|
28
|
+
* without it a full-resolution camera photo is usually refused as too large)
|
|
29
|
+
*
|
|
30
|
+
* A host without those (or with `react-native-image-picker` etc.) plugs its own
|
|
31
|
+
* picker in through `boot({ attachments: { pick } })`. With neither, the attach
|
|
32
|
+
* button simply isn't shown.
|
|
33
|
+
*
|
|
34
|
+
* No `react-native` import on purpose: the limit and encoding helpers stay
|
|
35
|
+
* testable in plain Node.
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
/** The server keeps the first five and silently drops the rest. */
|
|
39
|
+
const MAX_ATTACHMENTS = exports.MAX_ATTACHMENTS = 5;
|
|
40
|
+
/** Per file, decoded. The server silently drops anything larger. */
|
|
41
|
+
const MAX_ATTACHMENT_BYTES = exports.MAX_ATTACHMENT_BYTES = 1_500_000;
|
|
42
|
+
/**
|
|
43
|
+
* All files in one message, decoded. Base64 inside JSON inflates bytes by
|
|
44
|
+
* ~1.37x and the server caps a request body at 10 MB, so five files at the
|
|
45
|
+
* per-file maximum would come back as a 413.
|
|
46
|
+
*/
|
|
47
|
+
const MAX_TOTAL_ATTACHMENT_BYTES = exports.MAX_TOTAL_ATTACHMENT_BYTES = 6_000_000;
|
|
48
|
+
|
|
49
|
+
/** Photos are re-encoded at this JPEG quality — small enough to fit the cap more often. */
|
|
50
|
+
const IMAGE_QUALITY = 0.7;
|
|
51
|
+
|
|
52
|
+
/** A picked file, encoded and ready to send; what the composer shows as a chip. */
|
|
53
|
+
|
|
54
|
+
/** Why some (or all) of a pick didn't make it into the composer. */
|
|
55
|
+
|
|
56
|
+
// ─── Host integrations ─────────────────────────────────────────────────────
|
|
57
|
+
// Resolved once at module load. Each `require` is static so Metro can see it,
|
|
58
|
+
// and `withRepzoWidget` (metro.js) maps an uninstalled one to an empty module.
|
|
59
|
+
|
|
60
|
+
let imagePicker = null;
|
|
61
|
+
try {
|
|
62
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
63
|
+
const mod = require('expo-image-picker');
|
|
64
|
+
if (typeof mod?.launchImageLibraryAsync === 'function') imagePicker = mod;
|
|
65
|
+
} catch {
|
|
66
|
+
imagePicker = null;
|
|
67
|
+
}
|
|
68
|
+
let documentPicker = null;
|
|
69
|
+
try {
|
|
70
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
71
|
+
const mod = require('expo-document-picker');
|
|
72
|
+
if (typeof mod?.getDocumentAsync === 'function') documentPicker = mod;
|
|
73
|
+
} catch {
|
|
74
|
+
documentPicker = null;
|
|
75
|
+
}
|
|
76
|
+
let fileSystem = null;
|
|
77
|
+
try {
|
|
78
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
79
|
+
fileSystem = require('expo-file-system') ?? null;
|
|
80
|
+
} catch {
|
|
81
|
+
fileSystem = null;
|
|
82
|
+
}
|
|
83
|
+
let imageManipulator = null;
|
|
84
|
+
try {
|
|
85
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
86
|
+
const mod = require('expo-image-manipulator');
|
|
87
|
+
if (typeof mod?.manipulateAsync === 'function' || typeof mod?.ImageManipulator?.manipulate === 'function') {
|
|
88
|
+
imageManipulator = mod;
|
|
89
|
+
}
|
|
90
|
+
} catch {
|
|
91
|
+
imageManipulator = null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Longest edge of a shrunk photo — plenty for chat, typically 200–500 KB as JPEG. */
|
|
95
|
+
const MAX_IMAGE_EDGE = 1600;
|
|
96
|
+
let hostOptions = null;
|
|
97
|
+
|
|
98
|
+
/** Set from `boot({ attachments })`; `null` restores auto-detection. */
|
|
99
|
+
function setAttachmentOptions(options) {
|
|
100
|
+
hostOptions = options;
|
|
101
|
+
}
|
|
102
|
+
const ALL_SOURCES = ['photo', 'camera', 'file'];
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* The options the attach menu offers, in menu order. Empty means no button:
|
|
106
|
+
* attachments were switched off by the host, or nothing can pick a file.
|
|
107
|
+
*/
|
|
108
|
+
function getAttachmentSources() {
|
|
109
|
+
if (hostOptions?.enabled === false) return [];
|
|
110
|
+
if (hostOptions?.pick) {
|
|
111
|
+
const wanted = hostOptions.sources ?? ALL_SOURCES;
|
|
112
|
+
return ALL_SOURCES.filter(source => wanted.includes(source));
|
|
113
|
+
}
|
|
114
|
+
const sources = [];
|
|
115
|
+
if (imagePicker) sources.push('photo');
|
|
116
|
+
if (typeof imagePicker?.launchCameraAsync === 'function') sources.push('camera');
|
|
117
|
+
if (documentPicker) sources.push('file');
|
|
118
|
+
return sources;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// ─── Picking ───────────────────────────────────────────────────────────────
|
|
122
|
+
|
|
123
|
+
/** Returned (not thrown) so no `instanceof` on an Error subclass is needed. */
|
|
124
|
+
const CAMERA_DENIED = 'cameraDenied';
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Opens the picker for `source` and returns what fits alongside `current`.
|
|
128
|
+
* Never throws: a cancelled pick is `{ added: [], problem: null }`.
|
|
129
|
+
*/
|
|
130
|
+
async function pickAttachments(source, current) {
|
|
131
|
+
const slots = MAX_ATTACHMENTS - current.length;
|
|
132
|
+
if (slots <= 0) return {
|
|
133
|
+
added: [],
|
|
134
|
+
problem: 'tooMany'
|
|
135
|
+
};
|
|
136
|
+
let picked;
|
|
137
|
+
try {
|
|
138
|
+
picked = hostOptions?.pick ? await hostOptions.pick(source) : await launchBuiltInPicker(source, slots);
|
|
139
|
+
} catch (error) {
|
|
140
|
+
console.warn('[repzo-widget] attachment picker failed', error);
|
|
141
|
+
return {
|
|
142
|
+
added: [],
|
|
143
|
+
problem: 'failed'
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
if (picked === CAMERA_DENIED) return {
|
|
147
|
+
added: [],
|
|
148
|
+
problem: 'cameraDenied'
|
|
149
|
+
};
|
|
150
|
+
if (!Array.isArray(picked) || picked.length === 0) return {
|
|
151
|
+
added: [],
|
|
152
|
+
problem: null
|
|
153
|
+
};
|
|
154
|
+
const added = [];
|
|
155
|
+
let problem = null;
|
|
156
|
+
for (const file of picked) {
|
|
157
|
+
const accepted = [...current, ...added];
|
|
158
|
+
if (accepted.length >= MAX_ATTACHMENTS) {
|
|
159
|
+
problem = problem ?? 'tooMany';
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
// A size the picker already knows rules a file out before it's read, so
|
|
163
|
+
// a 40 MB video never lands in memory as a base64 string.
|
|
164
|
+
const declared = file.base64 ? null : validSize(file.size);
|
|
165
|
+
const early = declared === null ? null : checkAttachmentFits(accepted, declared);
|
|
166
|
+
if (early) {
|
|
167
|
+
problem = problem ?? early;
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
let draft;
|
|
171
|
+
try {
|
|
172
|
+
draft = await toDraft(file);
|
|
173
|
+
} catch (error) {
|
|
174
|
+
if (error === TOO_LARGE) {
|
|
175
|
+
problem = problem ?? 'tooLarge';
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
console.warn('[repzo-widget] could not read attachment', error);
|
|
179
|
+
problem = problem ?? 'failed';
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
const fits = draft.size > 0 ? checkAttachmentFits(accepted, draft.size) : 'failed';
|
|
183
|
+
if (fits) {
|
|
184
|
+
problem = problem ?? fits;
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
added.push(draft);
|
|
188
|
+
}
|
|
189
|
+
return {
|
|
190
|
+
added,
|
|
191
|
+
problem
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
async function launchBuiltInPicker(source, slots) {
|
|
195
|
+
if (source === 'file') {
|
|
196
|
+
if (!documentPicker) return null;
|
|
197
|
+
const result = await documentPicker.getDocumentAsync({
|
|
198
|
+
type: '*/*',
|
|
199
|
+
multiple: slots > 1,
|
|
200
|
+
copyToCacheDirectory: true
|
|
201
|
+
});
|
|
202
|
+
// SDK 48+ returns `{ canceled, assets }`; older ones a single `{ type, uri, … }`.
|
|
203
|
+
if (result?.canceled || result?.type === 'cancel') return null;
|
|
204
|
+
const assets = Array.isArray(result?.assets) ? result.assets : result?.uri ? [result] : [];
|
|
205
|
+
return assets.map(asset => ({
|
|
206
|
+
name: asset.name || fileNameFromUri(asset.uri) || 'file',
|
|
207
|
+
type: asset.mimeType || '',
|
|
208
|
+
size: asset.size,
|
|
209
|
+
uri: asset.uri
|
|
210
|
+
}));
|
|
211
|
+
}
|
|
212
|
+
if (!imagePicker) return null;
|
|
213
|
+
const options = {
|
|
214
|
+
quality: IMAGE_QUALITY,
|
|
215
|
+
// With the manipulator the photo is re-encoded below, so the picker's own
|
|
216
|
+
// (full-resolution) base64 would only waste memory.
|
|
217
|
+
base64: !imageManipulator,
|
|
218
|
+
exif: false
|
|
219
|
+
};
|
|
220
|
+
let result;
|
|
221
|
+
if (source === 'camera') {
|
|
222
|
+
const permission = await imagePicker.requestCameraPermissionsAsync?.();
|
|
223
|
+
if (permission && permission.granted === false) return CAMERA_DENIED;
|
|
224
|
+
result = await launchImagePicker(imagePicker.launchCameraAsync, options);
|
|
225
|
+
} else {
|
|
226
|
+
result = await launchImagePicker(imagePicker.launchImageLibraryAsync, {
|
|
227
|
+
...options,
|
|
228
|
+
allowsMultipleSelection: slots > 1,
|
|
229
|
+
selectionLimit: slots
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
if (result?.canceled || result?.cancelled) return null;
|
|
233
|
+
const assets = Array.isArray(result?.assets) ? result.assets : [];
|
|
234
|
+
const files = [];
|
|
235
|
+
for (const [index, asset] of assets.slice(0, slots).entries()) {
|
|
236
|
+
const shrunk = await shrinkPhoto(asset);
|
|
237
|
+
const type = shrunk ? 'image/jpeg' : asset.mimeType || guessContentType(asset.fileName || asset.uri) || 'image/jpeg';
|
|
238
|
+
const baseName = (asset.fileName || `photo-${Date.now()}-${index + 1}`).replace(/\.[^.]+$/, '');
|
|
239
|
+
files.push({
|
|
240
|
+
name: `${baseName}.${extensionFor(type)}`,
|
|
241
|
+
type,
|
|
242
|
+
// No `size`: `fileSize` is the original's, not the re-encoded base64's.
|
|
243
|
+
uri: shrunk?.uri ?? asset.uri,
|
|
244
|
+
base64: shrunk?.base64 ?? asset.base64 ?? undefined
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
return files;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* `mediaTypes: ['images']` is the expo-image-picker 16 (SDK 52)+ form; older
|
|
252
|
+
* versions reject the array before any UI shows, so retry with the legacy
|
|
253
|
+
* `MediaTypeOptions.Images` enum they expect.
|
|
254
|
+
*/
|
|
255
|
+
async function launchImagePicker(launch, options) {
|
|
256
|
+
try {
|
|
257
|
+
return await launch({
|
|
258
|
+
...options,
|
|
259
|
+
mediaTypes: ['images']
|
|
260
|
+
});
|
|
261
|
+
} catch (error) {
|
|
262
|
+
const legacy = imagePicker?.MediaTypeOptions?.Images;
|
|
263
|
+
if (!legacy) throw error;
|
|
264
|
+
return launch({
|
|
265
|
+
...options,
|
|
266
|
+
mediaTypes: legacy
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Re-encodes a photo as JPEG, scaled so its longest edge is at most
|
|
273
|
+
* MAX_IMAGE_EDGE. Null when the manipulator isn't installed or fails — the
|
|
274
|
+
* caller then falls back to the picker's own output (and the size check).
|
|
275
|
+
*/
|
|
276
|
+
async function shrinkPhoto(asset) {
|
|
277
|
+
if (!imageManipulator || !asset?.uri) return null;
|
|
278
|
+
const width = Number(asset.width) || 0;
|
|
279
|
+
const height = Number(asset.height) || 0;
|
|
280
|
+
const longest = Math.max(width, height);
|
|
281
|
+
const resize = longest > MAX_IMAGE_EDGE ? width >= height ? {
|
|
282
|
+
width: MAX_IMAGE_EDGE
|
|
283
|
+
} : {
|
|
284
|
+
height: MAX_IMAGE_EDGE
|
|
285
|
+
} : null;
|
|
286
|
+
const saveOptions = {
|
|
287
|
+
compress: IMAGE_QUALITY,
|
|
288
|
+
format: imageManipulator.SaveFormat?.JPEG ?? 'jpeg',
|
|
289
|
+
base64: true
|
|
290
|
+
};
|
|
291
|
+
try {
|
|
292
|
+
let output;
|
|
293
|
+
if (typeof imageManipulator.manipulateAsync === 'function') {
|
|
294
|
+
output = await imageManipulator.manipulateAsync(asset.uri, resize ? [{
|
|
295
|
+
resize
|
|
296
|
+
}] : [], saveOptions);
|
|
297
|
+
} else {
|
|
298
|
+
const context = imageManipulator.ImageManipulator.manipulate(asset.uri);
|
|
299
|
+
if (resize) context.resize(resize);
|
|
300
|
+
const image = await context.renderAsync();
|
|
301
|
+
output = await image.saveAsync(saveOptions);
|
|
302
|
+
}
|
|
303
|
+
return typeof output?.base64 === 'string' && output.base64 ? {
|
|
304
|
+
uri: output.uri ?? asset.uri,
|
|
305
|
+
base64: output.base64
|
|
306
|
+
} : null;
|
|
307
|
+
} catch (error) {
|
|
308
|
+
console.warn('[repzo-widget] could not shrink photo — sending it as picked', error);
|
|
309
|
+
return null;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
async function toDraft(file) {
|
|
313
|
+
let base64 = file.base64 ? stripDataUrlPrefix(file.base64) : '';
|
|
314
|
+
if (!base64) {
|
|
315
|
+
if (!file.uri) throw new Error('Picked file has neither base64 nor uri');
|
|
316
|
+
base64 = await readBase64(file.uri);
|
|
317
|
+
}
|
|
318
|
+
base64 = base64.replace(/\s/g, '');
|
|
319
|
+
const name = (file.name || fileNameFromUri(file.uri) || 'file').slice(0, 255);
|
|
320
|
+
const contentType = normalizeContentType(file.type) ?? guessContentType(name) ?? 'application/octet-stream';
|
|
321
|
+
const dataUrl = buildDataUrl(contentType, base64);
|
|
322
|
+
return {
|
|
323
|
+
id: `draft-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
324
|
+
name,
|
|
325
|
+
contentType,
|
|
326
|
+
size: base64ByteLength(base64),
|
|
327
|
+
dataUrl,
|
|
328
|
+
// Only the chip ever renders a data URL; the store keeps it out of messages.
|
|
329
|
+
previewUri: file.uri || dataUrl
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/** Thrown (by identity) when a file is over the per-file cap before it's read. */
|
|
334
|
+
const TOO_LARGE = new Error('File exceeds the attachment cap');
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* `expo-file-system`'s `File` class (SDK 54+) first, then its legacy
|
|
338
|
+
* `readAsStringAsync` (SDK 53 and older — a throwing stub on 54), then plain
|
|
339
|
+
* `fetch` + `FileReader`, which RN supports for `file://` URIs.
|
|
340
|
+
*
|
|
341
|
+
* Every path checks the size before encoding: the file-system readers only
|
|
342
|
+
* run once the file is known to fit, so a 300 MB video never becomes a
|
|
343
|
+
* 400 MB base64 string. When the size can't be read, `fetch` measures the blob.
|
|
344
|
+
*/
|
|
345
|
+
async function readBase64(uri) {
|
|
346
|
+
if (typeof fileSystem?.File === 'function') {
|
|
347
|
+
let file = null;
|
|
348
|
+
try {
|
|
349
|
+
file = new fileSystem.File(uri);
|
|
350
|
+
} catch {
|
|
351
|
+
file = null;
|
|
352
|
+
}
|
|
353
|
+
const size = validSize(file?.size);
|
|
354
|
+
if (size !== null && size > MAX_ATTACHMENT_BYTES) throw TOO_LARGE;
|
|
355
|
+
if (size !== null && typeof file.base64 === 'function') {
|
|
356
|
+
try {
|
|
357
|
+
const value = await file.base64();
|
|
358
|
+
if (typeof value === 'string' && value) return value;
|
|
359
|
+
} catch {
|
|
360
|
+
// Fall through to the next reader.
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
if (typeof fileSystem?.readAsStringAsync === 'function' && typeof fileSystem?.getInfoAsync === 'function') {
|
|
365
|
+
try {
|
|
366
|
+
const info = await fileSystem.getInfoAsync(uri, {
|
|
367
|
+
size: true
|
|
368
|
+
});
|
|
369
|
+
const size = validSize(info?.size);
|
|
370
|
+
if (size !== null && size > MAX_ATTACHMENT_BYTES) throw TOO_LARGE;
|
|
371
|
+
if (size !== null) {
|
|
372
|
+
const value = await fileSystem.readAsStringAsync(uri, {
|
|
373
|
+
encoding: 'base64'
|
|
374
|
+
});
|
|
375
|
+
if (typeof value === 'string' && value) return value;
|
|
376
|
+
}
|
|
377
|
+
} catch (error) {
|
|
378
|
+
if (error === TOO_LARGE) throw error;
|
|
379
|
+
// Fall through to fetch.
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return readBase64WithFetch(uri);
|
|
383
|
+
}
|
|
384
|
+
async function readBase64WithFetch(uri) {
|
|
385
|
+
const response = await fetch(uri);
|
|
386
|
+
const blob = await response.blob();
|
|
387
|
+
// Checked before encoding: the per-file cap is the most any file may be.
|
|
388
|
+
if (blob.size > MAX_ATTACHMENT_BYTES) throw TOO_LARGE;
|
|
389
|
+
const dataUrl = await new Promise((resolve, reject) => {
|
|
390
|
+
const reader = new FileReader();
|
|
391
|
+
reader.onload = () => resolve(typeof reader.result === 'string' ? reader.result : '');
|
|
392
|
+
reader.onerror = () => reject(reader.error ?? new Error('FileReader failed'));
|
|
393
|
+
reader.readAsDataURL(blob);
|
|
394
|
+
});
|
|
395
|
+
return stripDataUrlPrefix(dataUrl);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// ─── Pure helpers ──────────────────────────────────────────────────────────
|
|
399
|
+
|
|
400
|
+
/** Null when a file of `size` bytes still fits beside `current`; otherwise the limit it breaks. */
|
|
401
|
+
function checkAttachmentFits(current, size) {
|
|
402
|
+
if (current.length >= MAX_ATTACHMENTS) return 'tooMany';
|
|
403
|
+
if (size > MAX_ATTACHMENT_BYTES) return 'tooLarge';
|
|
404
|
+
const total = current.reduce((sum, item) => sum + item.size, 0);
|
|
405
|
+
if (total + size > MAX_TOTAL_ATTACHMENT_BYTES) return 'tooLargeTogether';
|
|
406
|
+
return null;
|
|
407
|
+
}
|
|
408
|
+
function buildDataUrl(contentType, base64) {
|
|
409
|
+
return `data:${normalizeContentType(contentType) ?? 'application/octet-stream'};base64,${base64}`;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/** RFC 6838 `type/subtype` characters; no parameters, no `,` or `;`. */
|
|
413
|
+
const MIME_TYPE = /^[a-z0-9][a-z0-9!#$&^_.+-]{0,63}\/[a-z0-9][a-z0-9!#$&^_.+-]{0,63}$/;
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* A picker's MIME type as a bare lowercase `type/subtype`, or null when it
|
|
417
|
+
* isn't one. Parameters (`;charset=…`) are dropped: anything else could split
|
|
418
|
+
* the data URL at the wrong `,` and hand the server a forged content type.
|
|
419
|
+
*/
|
|
420
|
+
function normalizeContentType(value) {
|
|
421
|
+
if (typeof value !== 'string') return null;
|
|
422
|
+
const bare = value.split(';')[0].trim().toLowerCase();
|
|
423
|
+
return MIME_TYPE.test(bare) ? bare : null;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/** Accepts raw base64 or a whole data URL; returns the base64 part. */
|
|
427
|
+
function stripDataUrlPrefix(value) {
|
|
428
|
+
const comma = value.startsWith('data:') ? value.indexOf(',') : -1;
|
|
429
|
+
return comma >= 0 ? value.slice(comma + 1) : value;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/** Decoded length of a base64 string (whitespace ignored). */
|
|
433
|
+
function base64ByteLength(base64) {
|
|
434
|
+
const clean = base64.replace(/\s/g, '');
|
|
435
|
+
if (!clean) return 0;
|
|
436
|
+
const padding = clean.endsWith('==') ? 2 : clean.endsWith('=') ? 1 : 0;
|
|
437
|
+
return Math.floor(clean.length * 3 / 4) - padding;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/** `1.2 MB`, `340 KB` — for chips; the limits themselves use decimal units too. */
|
|
441
|
+
function formatBytes(bytes) {
|
|
442
|
+
if (bytes >= 1_000_000) return `${(bytes / 1_000_000).toFixed(1).replace(/\.0$/, '')} MB`;
|
|
443
|
+
if (bytes >= 1_000) return `${Math.round(bytes / 1_000)} KB`;
|
|
444
|
+
return `${Math.max(0, Math.round(bytes))} B`;
|
|
445
|
+
}
|
|
446
|
+
function isImageAttachment(contentType) {
|
|
447
|
+
return !!contentType && contentType.toLowerCase().startsWith('image/');
|
|
448
|
+
}
|
|
449
|
+
function validSize(size) {
|
|
450
|
+
return typeof size === 'number' && Number.isFinite(size) && size > 0 ? size : null;
|
|
451
|
+
}
|
|
452
|
+
function fileNameFromUri(uri) {
|
|
453
|
+
if (!uri) return null;
|
|
454
|
+
const last = uri.split(/[?#]/)[0]?.split('/').pop();
|
|
455
|
+
if (!last) return null;
|
|
456
|
+
try {
|
|
457
|
+
return decodeURIComponent(last);
|
|
458
|
+
} catch {
|
|
459
|
+
return last;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
const CONTENT_TYPES = {
|
|
463
|
+
jpg: 'image/jpeg',
|
|
464
|
+
jpeg: 'image/jpeg',
|
|
465
|
+
png: 'image/png',
|
|
466
|
+
gif: 'image/gif',
|
|
467
|
+
webp: 'image/webp',
|
|
468
|
+
heic: 'image/heic',
|
|
469
|
+
heif: 'image/heif',
|
|
470
|
+
pdf: 'application/pdf',
|
|
471
|
+
txt: 'text/plain',
|
|
472
|
+
csv: 'text/csv',
|
|
473
|
+
doc: 'application/msword',
|
|
474
|
+
docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
475
|
+
xls: 'application/vnd.ms-excel',
|
|
476
|
+
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
477
|
+
ppt: 'application/vnd.ms-powerpoint',
|
|
478
|
+
pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
|
479
|
+
zip: 'application/zip',
|
|
480
|
+
mp3: 'audio/mpeg',
|
|
481
|
+
m4a: 'audio/mp4',
|
|
482
|
+
mp4: 'video/mp4',
|
|
483
|
+
mov: 'video/quicktime'
|
|
484
|
+
};
|
|
485
|
+
function guessContentType(nameOrUri) {
|
|
486
|
+
const extension = /\.([a-z0-9]+)$/i.exec(nameOrUri?.split(/[?#]/)[0] ?? '')?.[1];
|
|
487
|
+
return extension ? CONTENT_TYPES[extension.toLowerCase()] ?? null : null;
|
|
488
|
+
}
|
|
489
|
+
function extensionFor(contentType) {
|
|
490
|
+
const subtype = contentType.split('/')[1]?.toLowerCase();
|
|
491
|
+
return subtype === 'jpeg' || !subtype ? 'jpg' : subtype;
|
|
492
|
+
}
|
|
493
|
+
//# sourceMappingURL=pickers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["MAX_ATTACHMENTS","exports","MAX_ATTACHMENT_BYTES","MAX_TOTAL_ATTACHMENT_BYTES","IMAGE_QUALITY","imagePicker","mod","require","launchImageLibraryAsync","documentPicker","getDocumentAsync","fileSystem","imageManipulator","manipulateAsync","ImageManipulator","manipulate","MAX_IMAGE_EDGE","hostOptions","setAttachmentOptions","options","ALL_SOURCES","getAttachmentSources","enabled","pick","wanted","sources","filter","source","includes","push","launchCameraAsync","CAMERA_DENIED","pickAttachments","current","slots","length","added","problem","picked","launchBuiltInPicker","error","console","warn","Array","isArray","file","accepted","declared","base64","validSize","size","early","checkAttachmentFits","draft","toDraft","TOO_LARGE","fits","result","type","multiple","copyToCacheDirectory","canceled","assets","uri","map","asset","name","fileNameFromUri","mimeType","quality","exif","permission","requestCameraPermissionsAsync","granted","launchImagePicker","allowsMultipleSelection","selectionLimit","cancelled","files","index","slice","entries","shrunk","shrinkPhoto","guessContentType","fileName","baseName","Date","now","replace","extensionFor","undefined","launch","mediaTypes","legacy","MediaTypeOptions","Images","width","Number","height","longest","Math","max","resize","saveOptions","compress","format","SaveFormat","JPEG","output","context","image","renderAsync","saveAsync","stripDataUrlPrefix","Error","readBase64","contentType","normalizeContentType","dataUrl","buildDataUrl","id","random","toString","base64ByteLength","previewUri","File","value","readAsStringAsync","getInfoAsync","info","encoding","readBase64WithFetch","response","fetch","blob","Promise","resolve","reject","reader","FileReader","onload","onerror","readAsDataURL","total","reduce","sum","item","MIME_TYPE","bare","split","trim","toLowerCase","test","comma","startsWith","indexOf","clean","padding","endsWith","floor","formatBytes","bytes","toFixed","round","isImageAttachment","isFinite","last","pop","decodeURIComponent","CONTENT_TYPES","jpg","jpeg","png","gif","webp","heic","heif","pdf","txt","csv","doc","docx","xls","xlsx","ppt","pptx","zip","mp3","m4a","mp4","mov","nameOrUri","extension","exec","subtype"],"sourceRoot":"../../../src","sources":["attachments/pickers.ts"],"mappings":";;;;;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA;AACO,MAAMA,eAAe,GAAAC,OAAA,CAAAD,eAAA,GAAG,CAAC;AAChC;AACO,MAAME,oBAAoB,GAAAD,OAAA,CAAAC,oBAAA,GAAG,SAAS;AAC7C;AACA;AACA;AACA;AACA;AACO,MAAMC,0BAA0B,GAAAF,OAAA,CAAAE,0BAAA,GAAG,SAAS;;AAEnD;AACA,MAAMC,aAAa,GAAG,GAAG;;AAEzB;;AAaA;;AAcA;AACA;AACA;;AAEA,IAAIC,WAAgB,GAAG,IAAI;AAC3B,IAAI;EACF;EACA,MAAMC,GAAG,GAAGC,OAAO,CAAC,mBAAmB,CAAC;EACxC,IAAI,OAAOD,GAAG,EAAEE,uBAAuB,KAAK,UAAU,EAAEH,WAAW,GAAGC,GAAG;AAC3E,CAAC,CAAC,MAAM;EACND,WAAW,GAAG,IAAI;AACpB;AAEA,IAAII,cAAmB,GAAG,IAAI;AAC9B,IAAI;EACF;EACA,MAAMH,GAAG,GAAGC,OAAO,CAAC,sBAAsB,CAAC;EAC3C,IAAI,OAAOD,GAAG,EAAEI,gBAAgB,KAAK,UAAU,EAAED,cAAc,GAAGH,GAAG;AACvE,CAAC,CAAC,MAAM;EACNG,cAAc,GAAG,IAAI;AACvB;AAEA,IAAIE,UAAe,GAAG,IAAI;AAC1B,IAAI;EACF;EACAA,UAAU,GAAGJ,OAAO,CAAC,kBAAkB,CAAC,IAAI,IAAI;AAClD,CAAC,CAAC,MAAM;EACNI,UAAU,GAAG,IAAI;AACnB;AAEA,IAAIC,gBAAqB,GAAG,IAAI;AAChC,IAAI;EACF;EACA,MAAMN,GAAG,GAAGC,OAAO,CAAC,wBAAwB,CAAC;EAC7C,IACE,OAAOD,GAAG,EAAEO,eAAe,KAAK,UAAU,IAC1C,OAAOP,GAAG,EAAEQ,gBAAgB,EAAEC,UAAU,KAAK,UAAU,EACvD;IACAH,gBAAgB,GAAGN,GAAG;EACxB;AACF,CAAC,CAAC,MAAM;EACNM,gBAAgB,GAAG,IAAI;AACzB;;AAEA;AACA,MAAMI,cAAc,GAAG,IAAI;AAE3B,IAAIC,WAAgD,GAAG,IAAI;;AAE3D;AACO,SAASC,oBAAoBA,CAACC,OAA4C,EAAQ;EACvFF,WAAW,GAAGE,OAAO;AACvB;AAEA,MAAMC,WAA+B,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC;;AAEnE;AACA;AACA;AACA;AACO,SAASC,oBAAoBA,CAAA,EAAuB;EACzD,IAAIJ,WAAW,EAAEK,OAAO,KAAK,KAAK,EAAE,OAAO,EAAE;EAC7C,IAAIL,WAAW,EAAEM,IAAI,EAAE;IACrB,MAAMC,MAAM,GAAGP,WAAW,CAACQ,OAAO,IAAIL,WAAW;IACjD,OAAOA,WAAW,CAACM,MAAM,CAAEC,MAAM,IAAKH,MAAM,CAACI,QAAQ,CAACD,MAAM,CAAC,CAAC;EAChE;EACA,MAAMF,OAA2B,GAAG,EAAE;EACtC,IAAIpB,WAAW,EAAEoB,OAAO,CAACI,IAAI,CAAC,OAAO,CAAC;EACtC,IAAI,OAAOxB,WAAW,EAAEyB,iBAAiB,KAAK,UAAU,EAAEL,OAAO,CAACI,IAAI,CAAC,QAAQ,CAAC;EAChF,IAAIpB,cAAc,EAAEgB,OAAO,CAACI,IAAI,CAAC,MAAM,CAAC;EACxC,OAAOJ,OAAO;AAChB;;AAEA;;AAEA;AACA,MAAMM,aAAa,GAAG,cAAuB;;AAE7C;AACA;AACA;AACA;AACO,eAAeC,eAAeA,CACnCL,MAAwB,EACxBM,OAA0B,EACL;EACrB,MAAMC,KAAK,GAAGlC,eAAe,GAAGiC,OAAO,CAACE,MAAM;EAC9C,IAAID,KAAK,IAAI,CAAC,EAAE,OAAO;IAAEE,KAAK,EAAE,EAAE;IAAEC,OAAO,EAAE;EAAU,CAAC;EAExD,IAAIC,MAAuD;EAC3D,IAAI;IACFA,MAAM,GAAGrB,WAAW,EAAEM,IAAI,GACtB,MAAMN,WAAW,CAACM,IAAI,CAACI,MAAM,CAAC,GAC9B,MAAMY,mBAAmB,CAACZ,MAAM,EAAEO,KAAK,CAAC;EAC9C,CAAC,CAAC,OAAOM,KAAK,EAAE;IACdC,OAAO,CAACC,IAAI,CAAC,yCAAyC,EAAEF,KAAK,CAAC;IAC9D,OAAO;MAAEJ,KAAK,EAAE,EAAE;MAAEC,OAAO,EAAE;IAAS,CAAC;EACzC;EACA,IAAIC,MAAM,KAAKP,aAAa,EAAE,OAAO;IAAEK,KAAK,EAAE,EAAE;IAAEC,OAAO,EAAE;EAAe,CAAC;EAC3E,IAAI,CAACM,KAAK,CAACC,OAAO,CAACN,MAAM,CAAC,IAAIA,MAAM,CAACH,MAAM,KAAK,CAAC,EAAE,OAAO;IAAEC,KAAK,EAAE,EAAE;IAAEC,OAAO,EAAE;EAAK,CAAC;EAEtF,MAAMD,KAAwB,GAAG,EAAE;EACnC,IAAIC,OAAiC,GAAG,IAAI;EAC5C,KAAK,MAAMQ,IAAI,IAAIP,MAAM,EAAE;IACzB,MAAMQ,QAAQ,GAAG,CAAC,GAAGb,OAAO,EAAE,GAAGG,KAAK,CAAC;IACvC,IAAIU,QAAQ,CAACX,MAAM,IAAInC,eAAe,EAAE;MACtCqC,OAAO,GAAGA,OAAO,IAAI,SAAS;MAC9B;IACF;IACA;IACA;IACA,MAAMU,QAAQ,GAAGF,IAAI,CAACG,MAAM,GAAG,IAAI,GAAGC,SAAS,CAACJ,IAAI,CAACK,IAAI,CAAC;IAC1D,MAAMC,KAAK,GAAGJ,QAAQ,KAAK,IAAI,GAAG,IAAI,GAAGK,mBAAmB,CAACN,QAAQ,EAAEC,QAAQ,CAAC;IAChF,IAAII,KAAK,EAAE;MACTd,OAAO,GAAGA,OAAO,IAAIc,KAAK;MAC1B;IACF;IAEA,IAAIE,KAAsB;IAC1B,IAAI;MACFA,KAAK,GAAG,MAAMC,OAAO,CAACT,IAAI,CAAC;IAC7B,CAAC,CAAC,OAAOL,KAAK,EAAE;MACd,IAAIA,KAAK,KAAKe,SAAS,EAAE;QACvBlB,OAAO,GAAGA,OAAO,IAAI,UAAU;QAC/B;MACF;MACAI,OAAO,CAACC,IAAI,CAAC,0CAA0C,EAAEF,KAAK,CAAC;MAC/DH,OAAO,GAAGA,OAAO,IAAI,QAAQ;MAC7B;IACF;IACA,MAAMmB,IAAI,GAAGH,KAAK,CAACH,IAAI,GAAG,CAAC,GAAGE,mBAAmB,CAACN,QAAQ,EAAEO,KAAK,CAACH,IAAI,CAAC,GAAG,QAAQ;IAClF,IAAIM,IAAI,EAAE;MACRnB,OAAO,GAAGA,OAAO,IAAImB,IAAI;MACzB;IACF;IACApB,KAAK,CAACP,IAAI,CAACwB,KAAK,CAAC;EACnB;EACA,OAAO;IAAEjB,KAAK;IAAEC;EAAQ,CAAC;AAC3B;AAEA,eAAeE,mBAAmBA,CAChCZ,MAAwB,EACxBO,KAAa,EAC6C;EAC1D,IAAIP,MAAM,KAAK,MAAM,EAAE;IACrB,IAAI,CAAClB,cAAc,EAAE,OAAO,IAAI;IAChC,MAAMgD,MAAM,GAAG,MAAMhD,cAAc,CAACC,gBAAgB,CAAC;MACnDgD,IAAI,EAAE,KAAK;MACXC,QAAQ,EAAEzB,KAAK,GAAG,CAAC;MACnB0B,oBAAoB,EAAE;IACxB,CAAC,CAAC;IACF;IACA,IAAIH,MAAM,EAAEI,QAAQ,IAAIJ,MAAM,EAAEC,IAAI,KAAK,QAAQ,EAAE,OAAO,IAAI;IAC9D,MAAMI,MAAa,GAAGnB,KAAK,CAACC,OAAO,CAACa,MAAM,EAAEK,MAAM,CAAC,GAAGL,MAAM,CAACK,MAAM,GAAGL,MAAM,EAAEM,GAAG,GAAG,CAACN,MAAM,CAAC,GAAG,EAAE;IACjG,OAAOK,MAAM,CAACE,GAAG,CAAEC,KAAK,KAAM;MAC5BC,IAAI,EAAED,KAAK,CAACC,IAAI,IAAIC,eAAe,CAACF,KAAK,CAACF,GAAG,CAAC,IAAI,MAAM;MACxDL,IAAI,EAAEO,KAAK,CAACG,QAAQ,IAAI,EAAE;MAC1BlB,IAAI,EAAEe,KAAK,CAACf,IAAI;MAChBa,GAAG,EAAEE,KAAK,CAACF;IACb,CAAC,CAAC,CAAC;EACL;EAEA,IAAI,CAAC1D,WAAW,EAAE,OAAO,IAAI;EAC7B,MAAMc,OAAO,GAAG;IACdkD,OAAO,EAAEjE,aAAa;IACtB;IACA;IACA4C,MAAM,EAAE,CAACpC,gBAAgB;IACzB0D,IAAI,EAAE;EACR,CAAC;EAED,IAAIb,MAAW;EACf,IAAI9B,MAAM,KAAK,QAAQ,EAAE;IACvB,MAAM4C,UAAU,GAAG,MAAMlE,WAAW,CAACmE,6BAA6B,GAAG,CAAC;IACtE,IAAID,UAAU,IAAIA,UAAU,CAACE,OAAO,KAAK,KAAK,EAAE,OAAO1C,aAAa;IACpE0B,MAAM,GAAG,MAAMiB,iBAAiB,CAACrE,WAAW,CAACyB,iBAAiB,EAAEX,OAAO,CAAC;EAC1E,CAAC,MAAM;IACLsC,MAAM,GAAG,MAAMiB,iBAAiB,CAACrE,WAAW,CAACG,uBAAuB,EAAE;MACpE,GAAGW,OAAO;MACVwD,uBAAuB,EAAEzC,KAAK,GAAG,CAAC;MAClC0C,cAAc,EAAE1C;IAClB,CAAC,CAAC;EACJ;EACA,IAAIuB,MAAM,EAAEI,QAAQ,IAAIJ,MAAM,EAAEoB,SAAS,EAAE,OAAO,IAAI;EACtD,MAAMf,MAAa,GAAGnB,KAAK,CAACC,OAAO,CAACa,MAAM,EAAEK,MAAM,CAAC,GAAGL,MAAM,CAACK,MAAM,GAAG,EAAE;EACxE,MAAMgB,KAAwB,GAAG,EAAE;EACnC,KAAK,MAAM,CAACC,KAAK,EAAEd,KAAK,CAAC,IAAIH,MAAM,CAACkB,KAAK,CAAC,CAAC,EAAE9C,KAAK,CAAC,CAAC+C,OAAO,CAAC,CAAC,EAAE;IAC7D,MAAMC,MAAM,GAAG,MAAMC,WAAW,CAAClB,KAAK,CAAC;IACvC,MAAMP,IAAI,GAAGwB,MAAM,GACf,YAAY,GACZjB,KAAK,CAACG,QAAQ,IAAIgB,gBAAgB,CAACnB,KAAK,CAACoB,QAAQ,IAAIpB,KAAK,CAACF,GAAG,CAAC,IAAI,YAAY;IACnF,MAAMuB,QAAQ,GAAG,CAACrB,KAAK,CAACoB,QAAQ,IAAI,SAASE,IAAI,CAACC,GAAG,CAAC,CAAC,IAAIT,KAAK,GAAG,CAAC,EAAE,EAAEU,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;IAC/FX,KAAK,CAACjD,IAAI,CAAC;MACTqC,IAAI,EAAE,GAAGoB,QAAQ,IAAII,YAAY,CAAChC,IAAI,CAAC,EAAE;MACzCA,IAAI;MACJ;MACAK,GAAG,EAAEmB,MAAM,EAAEnB,GAAG,IAAIE,KAAK,CAACF,GAAG;MAC7Bf,MAAM,EAAEkC,MAAM,EAAElC,MAAM,IAAIiB,KAAK,CAACjB,MAAM,IAAI2C;IAC5C,CAAC,CAAC;EACJ;EACA,OAAOb,KAAK;AACd;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAeJ,iBAAiBA,CAACkB,MAAyC,EAAEzE,OAAe,EAAE;EAC3F,IAAI;IACF,OAAO,MAAMyE,MAAM,CAAC;MAAE,GAAGzE,OAAO;MAAE0E,UAAU,EAAE,CAAC,QAAQ;IAAE,CAAC,CAAC;EAC7D,CAAC,CAAC,OAAOrD,KAAK,EAAE;IACd,MAAMsD,MAAM,GAAGzF,WAAW,EAAE0F,gBAAgB,EAAEC,MAAM;IACpD,IAAI,CAACF,MAAM,EAAE,MAAMtD,KAAK;IACxB,OAAOoD,MAAM,CAAC;MAAE,GAAGzE,OAAO;MAAE0E,UAAU,EAAEC;IAAO,CAAC,CAAC;EACnD;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAeX,WAAWA,CAAClB,KAAU,EAAmD;EACtF,IAAI,CAACrD,gBAAgB,IAAI,CAACqD,KAAK,EAAEF,GAAG,EAAE,OAAO,IAAI;EACjD,MAAMkC,KAAK,GAAGC,MAAM,CAACjC,KAAK,CAACgC,KAAK,CAAC,IAAI,CAAC;EACtC,MAAME,MAAM,GAAGD,MAAM,CAACjC,KAAK,CAACkC,MAAM,CAAC,IAAI,CAAC;EACxC,MAAMC,OAAO,GAAGC,IAAI,CAACC,GAAG,CAACL,KAAK,EAAEE,MAAM,CAAC;EACvC,MAAMI,MAAM,GACVH,OAAO,GAAGpF,cAAc,GACpBiF,KAAK,IAAIE,MAAM,GACb;IAAEF,KAAK,EAAEjF;EAAe,CAAC,GACzB;IAAEmF,MAAM,EAAEnF;EAAe,CAAC,GAC5B,IAAI;EACV,MAAMwF,WAAW,GAAG;IAClBC,QAAQ,EAAErG,aAAa;IACvBsG,MAAM,EAAE9F,gBAAgB,CAAC+F,UAAU,EAAEC,IAAI,IAAI,MAAM;IACnD5D,MAAM,EAAE;EACV,CAAC;EACD,IAAI;IACF,IAAI6D,MAAW;IACf,IAAI,OAAOjG,gBAAgB,CAACC,eAAe,KAAK,UAAU,EAAE;MAC1DgG,MAAM,GAAG,MAAMjG,gBAAgB,CAACC,eAAe,CAACoD,KAAK,CAACF,GAAG,EAAEwC,MAAM,GAAG,CAAC;QAAEA;MAAO,CAAC,CAAC,GAAG,EAAE,EAAEC,WAAW,CAAC;IACrG,CAAC,MAAM;MACL,MAAMM,OAAO,GAAGlG,gBAAgB,CAACE,gBAAgB,CAACC,UAAU,CAACkD,KAAK,CAACF,GAAG,CAAC;MACvE,IAAIwC,MAAM,EAAEO,OAAO,CAACP,MAAM,CAACA,MAAM,CAAC;MAClC,MAAMQ,KAAK,GAAG,MAAMD,OAAO,CAACE,WAAW,CAAC,CAAC;MACzCH,MAAM,GAAG,MAAME,KAAK,CAACE,SAAS,CAACT,WAAW,CAAC;IAC7C;IACA,OAAO,OAAOK,MAAM,EAAE7D,MAAM,KAAK,QAAQ,IAAI6D,MAAM,CAAC7D,MAAM,GACtD;MAAEe,GAAG,EAAE8C,MAAM,CAAC9C,GAAG,IAAIE,KAAK,CAACF,GAAG;MAAEf,MAAM,EAAE6D,MAAM,CAAC7D;IAAO,CAAC,GACvD,IAAI;EACV,CAAC,CAAC,OAAOR,KAAK,EAAE;IACdC,OAAO,CAACC,IAAI,CAAC,8DAA8D,EAAEF,KAAK,CAAC;IACnF,OAAO,IAAI;EACb;AACF;AAEA,eAAec,OAAOA,CAACT,IAAqB,EAA4B;EACtE,IAAIG,MAAM,GAAGH,IAAI,CAACG,MAAM,GAAGkE,kBAAkB,CAACrE,IAAI,CAACG,MAAM,CAAC,GAAG,EAAE;EAC/D,IAAI,CAACA,MAAM,EAAE;IACX,IAAI,CAACH,IAAI,CAACkB,GAAG,EAAE,MAAM,IAAIoD,KAAK,CAAC,wCAAwC,CAAC;IACxEnE,MAAM,GAAG,MAAMoE,UAAU,CAACvE,IAAI,CAACkB,GAAG,CAAC;EACrC;EACAf,MAAM,GAAGA,MAAM,CAACyC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;EAElC,MAAMvB,IAAI,GAAG,CAACrB,IAAI,CAACqB,IAAI,IAAIC,eAAe,CAACtB,IAAI,CAACkB,GAAG,CAAC,IAAI,MAAM,EAAEiB,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;EAC7E,MAAMqC,WAAW,GACfC,oBAAoB,CAACzE,IAAI,CAACa,IAAI,CAAC,IAAI0B,gBAAgB,CAAClB,IAAI,CAAC,IAAI,0BAA0B;EACzF,MAAMqD,OAAO,GAAGC,YAAY,CAACH,WAAW,EAAErE,MAAM,CAAC;EACjD,OAAO;IACLyE,EAAE,EAAE,SAASlC,IAAI,CAACC,GAAG,CAAC,CAAC,IAAIa,IAAI,CAACqB,MAAM,CAAC,CAAC,CAACC,QAAQ,CAAC,EAAE,CAAC,CAAC3C,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;IACnEd,IAAI;IACJmD,WAAW;IACXnE,IAAI,EAAE0E,gBAAgB,CAAC5E,MAAM,CAAC;IAC9BuE,OAAO;IACP;IACAM,UAAU,EAAEhF,IAAI,CAACkB,GAAG,IAAIwD;EAC1B,CAAC;AACH;;AAEA;AACA,MAAMhE,SAAS,GAAG,IAAI4D,KAAK,CAAC,iCAAiC,CAAC;;AAE9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAeC,UAAUA,CAACrD,GAAW,EAAmB;EACtD,IAAI,OAAOpD,UAAU,EAAEmH,IAAI,KAAK,UAAU,EAAE;IAC1C,IAAIjF,IAAS,GAAG,IAAI;IACpB,IAAI;MACFA,IAAI,GAAG,IAAIlC,UAAU,CAACmH,IAAI,CAAC/D,GAAG,CAAC;IACjC,CAAC,CAAC,MAAM;MACNlB,IAAI,GAAG,IAAI;IACb;IACA,MAAMK,IAAI,GAAGD,SAAS,CAACJ,IAAI,EAAEK,IAAI,CAAC;IAClC,IAAIA,IAAI,KAAK,IAAI,IAAIA,IAAI,GAAGhD,oBAAoB,EAAE,MAAMqD,SAAS;IACjE,IAAIL,IAAI,KAAK,IAAI,IAAI,OAAOL,IAAI,CAACG,MAAM,KAAK,UAAU,EAAE;MACtD,IAAI;QACF,MAAM+E,KAAK,GAAG,MAAMlF,IAAI,CAACG,MAAM,CAAC,CAAC;QACjC,IAAI,OAAO+E,KAAK,KAAK,QAAQ,IAAIA,KAAK,EAAE,OAAOA,KAAK;MACtD,CAAC,CAAC,MAAM;QACN;MAAA;IAEJ;EACF;EACA,IACE,OAAOpH,UAAU,EAAEqH,iBAAiB,KAAK,UAAU,IACnD,OAAOrH,UAAU,EAAEsH,YAAY,KAAK,UAAU,EAC9C;IACA,IAAI;MACF,MAAMC,IAAI,GAAG,MAAMvH,UAAU,CAACsH,YAAY,CAAClE,GAAG,EAAE;QAAEb,IAAI,EAAE;MAAK,CAAC,CAAC;MAC/D,MAAMA,IAAI,GAAGD,SAAS,CAACiF,IAAI,EAAEhF,IAAI,CAAC;MAClC,IAAIA,IAAI,KAAK,IAAI,IAAIA,IAAI,GAAGhD,oBAAoB,EAAE,MAAMqD,SAAS;MACjE,IAAIL,IAAI,KAAK,IAAI,EAAE;QACjB,MAAM6E,KAAK,GAAG,MAAMpH,UAAU,CAACqH,iBAAiB,CAACjE,GAAG,EAAE;UAAEoE,QAAQ,EAAE;QAAS,CAAC,CAAC;QAC7E,IAAI,OAAOJ,KAAK,KAAK,QAAQ,IAAIA,KAAK,EAAE,OAAOA,KAAK;MACtD;IACF,CAAC,CAAC,OAAOvF,KAAK,EAAE;MACd,IAAIA,KAAK,KAAKe,SAAS,EAAE,MAAMf,KAAK;MACpC;IACF;EACF;EACA,OAAO4F,mBAAmB,CAACrE,GAAG,CAAC;AACjC;AAEA,eAAeqE,mBAAmBA,CAACrE,GAAW,EAAmB;EAC/D,MAAMsE,QAAQ,GAAG,MAAMC,KAAK,CAACvE,GAAG,CAAC;EACjC,MAAMwE,IAAI,GAAG,MAAMF,QAAQ,CAACE,IAAI,CAAC,CAAC;EAClC;EACA,IAAIA,IAAI,CAACrF,IAAI,GAAGhD,oBAAoB,EAAE,MAAMqD,SAAS;EACrD,MAAMgE,OAAO,GAAG,MAAM,IAAIiB,OAAO,CAAS,CAACC,OAAO,EAAEC,MAAM,KAAK;IAC7D,MAAMC,MAAM,GAAG,IAAIC,UAAU,CAAC,CAAC;IAC/BD,MAAM,CAACE,MAAM,GAAG,MAAMJ,OAAO,CAAC,OAAOE,MAAM,CAAClF,MAAM,KAAK,QAAQ,GAAGkF,MAAM,CAAClF,MAAM,GAAG,EAAE,CAAC;IACrFkF,MAAM,CAACG,OAAO,GAAG,MAAMJ,MAAM,CAACC,MAAM,CAACnG,KAAK,IAAI,IAAI2E,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAC7EwB,MAAM,CAACI,aAAa,CAACR,IAAI,CAAC;EAC5B,CAAC,CAAC;EACF,OAAOrB,kBAAkB,CAACK,OAAO,CAAC;AACpC;;AAEA;;AAEA;AACO,SAASnE,mBAAmBA,CACjCnB,OAAwC,EACxCiB,IAAY,EACc;EAC1B,IAAIjB,OAAO,CAACE,MAAM,IAAInC,eAAe,EAAE,OAAO,SAAS;EACvD,IAAIkD,IAAI,GAAGhD,oBAAoB,EAAE,OAAO,UAAU;EAClD,MAAM8I,KAAK,GAAG/G,OAAO,CAACgH,MAAM,CAAC,CAACC,GAAG,EAAEC,IAAI,KAAKD,GAAG,GAAGC,IAAI,CAACjG,IAAI,EAAE,CAAC,CAAC;EAC/D,IAAI8F,KAAK,GAAG9F,IAAI,GAAG/C,0BAA0B,EAAE,OAAO,kBAAkB;EACxE,OAAO,IAAI;AACb;AAEO,SAASqH,YAAYA,CAACH,WAAmB,EAAErE,MAAc,EAAU;EACxE,OAAO,QAAQsE,oBAAoB,CAACD,WAAW,CAAC,IAAI,0BAA0B,WAAWrE,MAAM,EAAE;AACnG;;AAEA;AACA,MAAMoG,SAAS,GAAG,oEAAoE;;AAEtF;AACA;AACA;AACA;AACA;AACO,SAAS9B,oBAAoBA,CAACS,KAAgC,EAAiB;EACpF,IAAI,OAAOA,KAAK,KAAK,QAAQ,EAAE,OAAO,IAAI;EAC1C,MAAMsB,IAAI,GAAGtB,KAAK,CAACuB,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAEC,IAAI,CAAC,CAAC,CAACC,WAAW,CAAC,CAAC;EACtD,OAAOJ,SAAS,CAACK,IAAI,CAACJ,IAAI,CAAC,GAAGA,IAAI,GAAG,IAAI;AAC3C;;AAEA;AACO,SAASnC,kBAAkBA,CAACa,KAAa,EAAU;EACxD,MAAM2B,KAAK,GAAG3B,KAAK,CAAC4B,UAAU,CAAC,OAAO,CAAC,GAAG5B,KAAK,CAAC6B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;EACjE,OAAOF,KAAK,IAAI,CAAC,GAAG3B,KAAK,CAAC/C,KAAK,CAAC0E,KAAK,GAAG,CAAC,CAAC,GAAG3B,KAAK;AACpD;;AAEA;AACO,SAASH,gBAAgBA,CAAC5E,MAAc,EAAU;EACvD,MAAM6G,KAAK,GAAG7G,MAAM,CAACyC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;EACvC,IAAI,CAACoE,KAAK,EAAE,OAAO,CAAC;EACpB,MAAMC,OAAO,GAAGD,KAAK,CAACE,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,GAAGF,KAAK,CAACE,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC;EACtE,OAAO1D,IAAI,CAAC2D,KAAK,CAAEH,KAAK,CAAC1H,MAAM,GAAG,CAAC,GAAI,CAAC,CAAC,GAAG2H,OAAO;AACrD;;AAEA;AACO,SAASG,WAAWA,CAACC,KAAa,EAAU;EACjD,IAAIA,KAAK,IAAI,SAAS,EAAE,OAAO,GAAG,CAACA,KAAK,GAAG,SAAS,EAAEC,OAAO,CAAC,CAAC,CAAC,CAAC1E,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK;EACzF,IAAIyE,KAAK,IAAI,KAAK,EAAE,OAAO,GAAG7D,IAAI,CAAC+D,KAAK,CAACF,KAAK,GAAG,KAAK,CAAC,KAAK;EAC5D,OAAO,GAAG7D,IAAI,CAACC,GAAG,CAAC,CAAC,EAAED,IAAI,CAAC+D,KAAK,CAACF,KAAK,CAAC,CAAC,IAAI;AAC9C;AAEO,SAASG,iBAAiBA,CAAChD,WAAsC,EAAW;EACjF,OAAO,CAAC,CAACA,WAAW,IAAIA,WAAW,CAACmC,WAAW,CAAC,CAAC,CAACG,UAAU,CAAC,QAAQ,CAAC;AACxE;AAEA,SAAS1G,SAASA,CAACC,IAAa,EAAiB;EAC/C,OAAO,OAAOA,IAAI,KAAK,QAAQ,IAAIgD,MAAM,CAACoE,QAAQ,CAACpH,IAAI,CAAC,IAAIA,IAAI,GAAG,CAAC,GAAGA,IAAI,GAAG,IAAI;AACpF;AAEA,SAASiB,eAAeA,CAACJ,GAAuB,EAAiB;EAC/D,IAAI,CAACA,GAAG,EAAE,OAAO,IAAI;EACrB,MAAMwG,IAAI,GAAGxG,GAAG,CAACuF,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAEA,KAAK,CAAC,GAAG,CAAC,CAACkB,GAAG,CAAC,CAAC;EACnD,IAAI,CAACD,IAAI,EAAE,OAAO,IAAI;EACtB,IAAI;IACF,OAAOE,kBAAkB,CAACF,IAAI,CAAC;EACjC,CAAC,CAAC,MAAM;IACN,OAAOA,IAAI;EACb;AACF;AAEA,MAAMG,aAAqC,GAAG;EAC5CC,GAAG,EAAE,YAAY;EACjBC,IAAI,EAAE,YAAY;EAClBC,GAAG,EAAE,WAAW;EAChBC,GAAG,EAAE,WAAW;EAChBC,IAAI,EAAE,YAAY;EAClBC,IAAI,EAAE,YAAY;EAClBC,IAAI,EAAE,YAAY;EAClBC,GAAG,EAAE,iBAAiB;EACtBC,GAAG,EAAE,YAAY;EACjBC,GAAG,EAAE,UAAU;EACfC,GAAG,EAAE,oBAAoB;EACzBC,IAAI,EAAE,yEAAyE;EAC/EC,GAAG,EAAE,0BAA0B;EAC/BC,IAAI,EAAE,mEAAmE;EACzEC,GAAG,EAAE,+BAA+B;EACpCC,IAAI,EAAE,2EAA2E;EACjFC,GAAG,EAAE,iBAAiB;EACtBC,GAAG,EAAE,YAAY;EACjBC,GAAG,EAAE,WAAW;EAChBC,GAAG,EAAE,WAAW;EAChBC,GAAG,EAAE;AACP,CAAC;AAED,SAAS3G,gBAAgBA,CAAC4G,SAAoC,EAAiB;EAC7E,MAAMC,SAAS,GAAG,iBAAiB,CAACC,IAAI,CAACF,SAAS,EAAE1C,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC;EAChF,OAAO2C,SAAS,GAAIvB,aAAa,CAACuB,SAAS,CAACzC,WAAW,CAAC,CAAC,CAAC,IAAI,IAAI,GAAI,IAAI;AAC5E;AAEA,SAAS9D,YAAYA,CAAC2B,WAAmB,EAAU;EACjD,MAAM8E,OAAO,GAAG9E,WAAW,CAACiC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAEE,WAAW,CAAC,CAAC;EACxD,OAAO2C,OAAO,KAAK,MAAM,IAAI,CAACA,OAAO,GAAG,KAAK,GAAGA,OAAO;AACzD","ignoreList":[]}
|
package/lib/commonjs/i18n.js
CHANGED
|
@@ -7,6 +7,7 @@ exports.DEFAULT_LABELS = void 0;
|
|
|
7
7
|
exports.buildLabels = buildLabels;
|
|
8
8
|
exports.createTranslator = createTranslator;
|
|
9
9
|
exports.formatLabel = formatLabel;
|
|
10
|
+
exports.localizeWelcomeText = localizeWelcomeText;
|
|
10
11
|
var _locales = require("./locales.js");
|
|
11
12
|
/**
|
|
12
13
|
* Translations come from the widget config (`translations[locale][key]`), with
|
|
@@ -26,6 +27,26 @@ function createTranslator(config, locale) {
|
|
|
26
27
|
const fallbackLocale = (0, _locales.baseLanguage)(defaultLocale);
|
|
27
28
|
return (key, fallback) => config?.translations?.[locale]?.[key] || config?.translations?.[active]?.[key] || _locales.BUNDLED_TRANSLATIONS[active]?.[key] || config?.translations?.[defaultLocale]?.[key] || _locales.BUNDLED_TRANSLATIONS[fallbackLocale]?.[key] || fallback;
|
|
28
29
|
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Dashboard copy that's written per language: the default language's text is
|
|
33
|
+
* the plain config field and every other enabled language's lives under the
|
|
34
|
+
* same key in `translations`.
|
|
35
|
+
*/
|
|
36
|
+
const WELCOME_TEXT_KEYS = ['welcomeHeading', 'welcomeSubheading', 'startConversationLabel', 'replyTimeLabel'];
|
|
37
|
+
|
|
38
|
+
/** The config with its welcome text in the active locale. */
|
|
39
|
+
function localizeWelcomeText(config, locale) {
|
|
40
|
+
if (!config) return config;
|
|
41
|
+
const translate = createTranslator(config, locale);
|
|
42
|
+
const localized = {
|
|
43
|
+
...config
|
|
44
|
+
};
|
|
45
|
+
WELCOME_TEXT_KEYS.forEach(key => {
|
|
46
|
+
localized[key] = translate(key, config[key]);
|
|
47
|
+
});
|
|
48
|
+
return localized;
|
|
49
|
+
}
|
|
29
50
|
const DEFAULT_LABELS = exports.DEFAULT_LABELS = {
|
|
30
51
|
back: 'Back',
|
|
31
52
|
loading: 'Loading...',
|
|
@@ -33,6 +54,20 @@ const DEFAULT_LABELS = exports.DEFAULT_LABELS = {
|
|
|
33
54
|
emptyConversation: 'Send a message to start the conversation',
|
|
34
55
|
messagePlaceholder: 'Type a message...',
|
|
35
56
|
attachFile: 'Attach file',
|
|
57
|
+
// Attach menu, composer chips and the notices under them.
|
|
58
|
+
attachPhotoLibrary: 'Photo library',
|
|
59
|
+
attachTakePhoto: 'Take photo',
|
|
60
|
+
attachChooseFile: 'File',
|
|
61
|
+
removeAttachment: 'Remove {name}',
|
|
62
|
+
attachmentTooLarge: 'File is too large (max {max})',
|
|
63
|
+
attachmentTooMany: 'You can attach up to {count} files',
|
|
64
|
+
attachmentsTooLargeTogether: 'Attachments are too large to send together — send some in another message',
|
|
65
|
+
attachmentFailed: "Couldn't attach that file",
|
|
66
|
+
// Full-screen image viewer.
|
|
67
|
+
imageLoadFailed: "Couldn't load this image",
|
|
68
|
+
openImageExternally: 'Open image',
|
|
69
|
+
cameraPermissionDenied: 'Allow camera access in Settings to take a photo',
|
|
70
|
+
cancel: 'Cancel',
|
|
36
71
|
failedToSend: 'Failed to send',
|
|
37
72
|
thinking: 'Typing',
|
|
38
73
|
messages: 'Messages',
|
|
@@ -72,6 +107,11 @@ const DEFAULT_LABELS = exports.DEFAULT_LABELS = {
|
|
|
72
107
|
today: 'Today',
|
|
73
108
|
yesterday: 'Yesterday',
|
|
74
109
|
conversationUpdated: 'Conversation updated',
|
|
110
|
+
messageDeleted: 'This message was deleted',
|
|
111
|
+
messageSent: 'Sent',
|
|
112
|
+
messageSeen: 'Seen',
|
|
113
|
+
waitingForTeammate: 'Waiting for a teammate',
|
|
114
|
+
joinedConversation: 'joined the conversation',
|
|
75
115
|
// Forms.
|
|
76
116
|
procedureSend: 'Send details',
|
|
77
117
|
procedureSent: 'Sent',
|
|
@@ -82,6 +122,11 @@ const DEFAULT_LABELS = exports.DEFAULT_LABELS = {
|
|
|
82
122
|
outboundTitle: 'New update',
|
|
83
123
|
outboundCta: 'Learn more',
|
|
84
124
|
dismiss: 'Dismiss',
|
|
125
|
+
// In-app card for a new reply while the messenger is closed.
|
|
126
|
+
notificationReplyFrom: 'Reply from {name}',
|
|
127
|
+
notificationNewReply: 'New reply',
|
|
128
|
+
notificationAttachment: 'Sent an attachment',
|
|
129
|
+
notificationOpenHint: 'Opens the conversation',
|
|
85
130
|
// Rich blocks an agent can send.
|
|
86
131
|
blockService: 'Service',
|
|
87
132
|
blockProduct: 'Product',
|
package/lib/commonjs/i18n.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_locales","require","createTranslator","config","locale","defaultLocale","active","baseLanguage","fallbackLocale","key","fallback","translations","BUNDLED_TRANSLATIONS","DEFAULT_LABELS","exports","back","loading","loadEarlier","emptyConversation","messagePlaceholder","attachFile","failedToSend","thinking","messages","noMessages","historyHidden","startBelow","preChatTitle","preChatSubtitle","preChatSkip","preChatSubmit","viewPreviousConversations","homeRecentTitle","homeViewAllCount","homeNoConversations","homeStatusOnline","homeStatusAway","unreadBadge","team","home","close","retry","connectionError","connecting","chatUnavailable","identityVerificationError","widgetCrashed","timeJustNow","timeMinutes","timeHours","timeDays","timeMonths","timeYears","today","yesterday","conversationUpdated","procedureSend","procedureSent","fieldRequired","invalidEmail","working","outboundTitle","outboundCta","dismiss","blockService","blockProduct","blockChooseTime","blockProfessional","blockPriceOffer","formatLabel","template","values","replace","match","String","buildLabels","
|
|
1
|
+
{"version":3,"names":["_locales","require","createTranslator","config","locale","defaultLocale","active","baseLanguage","fallbackLocale","key","fallback","translations","BUNDLED_TRANSLATIONS","WELCOME_TEXT_KEYS","localizeWelcomeText","translate","localized","forEach","DEFAULT_LABELS","exports","back","loading","loadEarlier","emptyConversation","messagePlaceholder","attachFile","attachPhotoLibrary","attachTakePhoto","attachChooseFile","removeAttachment","attachmentTooLarge","attachmentTooMany","attachmentsTooLargeTogether","attachmentFailed","imageLoadFailed","openImageExternally","cameraPermissionDenied","cancel","failedToSend","thinking","messages","noMessages","historyHidden","startBelow","preChatTitle","preChatSubtitle","preChatSkip","preChatSubmit","viewPreviousConversations","homeRecentTitle","homeViewAllCount","homeNoConversations","homeStatusOnline","homeStatusAway","unreadBadge","team","home","close","retry","connectionError","connecting","chatUnavailable","identityVerificationError","widgetCrashed","timeJustNow","timeMinutes","timeHours","timeDays","timeMonths","timeYears","today","yesterday","conversationUpdated","messageDeleted","messageSent","messageSeen","waitingForTeammate","joinedConversation","procedureSend","procedureSent","fieldRequired","invalidEmail","working","outboundTitle","outboundCta","dismiss","notificationReplyFrom","notificationNewReply","notificationAttachment","notificationOpenHint","blockService","blockProduct","blockChooseTime","blockProfessional","blockPriceOffer","formatLabel","template","values","replace","match","String","buildLabels","labels","Object","keys"],"sourceRoot":"../../src","sources":["i18n.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_controller","require","_events","_storage","_WidgetProvider","_Launcher","_client","_types","_useWidgetState","Space","exports","RepzoWidget","boot","options","controller","store","loginUnidentifiedUser","loginUserWithUserAttributes","user","updateUser","attributes","logout","present","presentSpace","space","presentConversation","conversationId","openConversation","hide","getUnreadConversationCount","Object","values","getState","unreadByConversation","filter","count","length","getUnreadMessageCount","unreadCount","logEvent","eventName","metadata","track","setLocale","locale","addEventListener","event","listener","events","addListener","setStorageAdapter","adapter","setSecureStorageAdapter","setPushToken","push","setManualToken","_default","default"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,IAAAA,WAAA,GAAAC,OAAA;AACA,IAAAC,OAAA,GAAAD,OAAA;AACA,IAAAE,QAAA,GAAAF,OAAA;AASA,IAAAG,eAAA,GAAAH,OAAA;AACA,IAAAI,SAAA,GAAAJ,OAAA;AAEA,IAAAK,OAAA,GAAAL,OAAA;AACA,IAAAM,MAAA,GAAAN,OAAA;AACA,IAAAO,eAAA,GAAAP,OAAA;AAxBA;AACA;AACA;AACA;AACA;AACA;AACA;
|
|
1
|
+
{"version":3,"names":["_controller","require","_events","_storage","_WidgetProvider","_Launcher","_client","_types","_useWidgetState","Space","exports","RepzoWidget","boot","options","controller","store","loginUnidentifiedUser","loginUserWithUserAttributes","user","updateUser","attributes","logout","present","presentSpace","space","presentConversation","conversationId","openConversation","hide","getUnreadConversationCount","Object","values","getState","unreadByConversation","filter","count","length","getUnreadMessageCount","unreadCount","logEvent","eventName","metadata","track","setLocale","locale","addEventListener","event","listener","events","addListener","setStorageAdapter","adapter","setSecureStorageAdapter","setPushToken","push","setManualToken","_default","default"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,IAAAA,WAAA,GAAAC,OAAA;AACA,IAAAC,OAAA,GAAAD,OAAA;AACA,IAAAE,QAAA,GAAAF,OAAA;AASA,IAAAG,eAAA,GAAAH,OAAA;AACA,IAAAI,SAAA,GAAAJ,OAAA;AAEA,IAAAK,OAAA,GAAAL,OAAA;AACA,IAAAM,MAAA,GAAAN,OAAA;AACA,IAAAO,eAAA,GAAAP,OAAA;AAxBA;AACA;AACA;AACA;AACA;AACA;AACA;AAmDA;AAAA,IACYQ,KAAK,GAAAC,OAAA,CAAAD,KAAA,0BAALA,KAAK;EAALA,KAAK;EAALA,KAAK;EAAA,OAALA,KAAK;AAAA;AAiGjB,MAAME,WAA4B,GAAG;EACnCC,IAAI,EAAGC,OAAO,IAAKC,sBAAU,CAACC,KAAK,CAACH,IAAI,CAACC,OAAO,CAAC;EAEjDG,qBAAqB,EAAEA,CAAA,KAAMF,sBAAU,CAACC,KAAK,CAACC,qBAAqB,CAAC,CAAC;EAErEC,2BAA2B,EAAGC,IAAI,IAAKJ,sBAAU,CAACC,KAAK,CAACE,2BAA2B,CAACC,IAAI,CAAC;EAEzFC,UAAU,EAAGC,UAAU,IAAKN,sBAAU,CAACC,KAAK,CAACI,UAAU,CAACC,UAAU,CAAC;EAEnEC,MAAM,EAAEA,CAAA,KAAMP,sBAAU,CAACC,KAAK,CAACM,MAAM,CAAC,CAAC;EAEvCC,OAAO,EAAE,MAAAA,CAAA,KAAY;IACnBR,sBAAU,CAACC,KAAK,CAACO,OAAO,CAAC,CAAC;EAC5B,CAAC;EAEDC,YAAY,EAAE,MAAOC,KAAK,IAAK;IAC7BV,sBAAU,CAACC,KAAK,CAACO,OAAO,CAACE,KAAwB,CAAC;EACpD,CAAC;EAEDC,mBAAmB,EAAGC,cAAc,IAAKZ,sBAAU,CAACC,KAAK,CAACY,gBAAgB,CAACD,cAAc,CAAC;EAE1FE,IAAI,EAAE,MAAAA,CAAA,KAAY;IAChBd,sBAAU,CAACC,KAAK,CAACa,IAAI,CAAC,CAAC;EACzB,CAAC;EAEDC,0BAA0B,EAAE,MAAAA,CAAA,KAC1BC,MAAM,CAACC,MAAM,CAACjB,sBAAU,CAACC,KAAK,CAACiB,QAAQ,CAAC,CAAC,CAACC,oBAAoB,CAAC,CAACC,MAAM,CAAEC,KAAK,IAAKA,KAAK,GAAG,CAAC,CAAC,CACzFC,MAAM;EAEXC,qBAAqB,EAAE,MAAAA,CAAA,KAAYvB,sBAAU,CAACC,KAAK,CAACiB,QAAQ,CAAC,CAAC,CAACM,WAAW;EAE1EC,QAAQ,EAAE,MAAAA,CAAOC,SAAS,EAAEC,QAAQ,KAAK;IACvC3B,sBAAU,CAACC,KAAK,CAAC2B,KAAK,CAACF,SAAS,EAAEC,QAAQ,IAAI,CAAC,CAAC,CAAC;EACnD,CAAC;EAEDE,SAAS,EAAGC,MAAM,IAAK9B,sBAAU,CAACC,KAAK,CAAC4B,SAAS,CAACC,MAAM,CAAC;EAEzDC,gBAAgB,EAAEA,CAACC,KAAK,EAAEC,QAAQ,KAAKjC,sBAAU,CAACkC,MAAM,CAACC,WAAW,CAACH,KAAK,EAAEC,QAAQ,CAAC;EAErFG,iBAAiB,EAAGC,OAAO,IAAK,IAAAD,0BAAiB,EAACC,OAAO,CAAC;EAE1DC,uBAAuB,EAAGD,OAAO,IAAK,IAAAC,gCAAuB,EAACD,OAAO,CAAC;EAEtEE,YAAY,EAAGxC,OAAO,IAAKC,sBAAU,CAACC,KAAK,CAACuC,IAAI,CAACC,cAAc,CAAC1C,OAAO;AACzE,CAAC;AAAC,IAAA2C,QAAA,GAAA9C,OAAA,CAAA+C,OAAA,GAEa9C,WAAW","ignoreList":[]}
|