@adatechnology/conversations-ui 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ConversationSimulatorPanel--5fIzXWY.d.ts → ConversationSimulatorPanel-ikgmlciE.d.ts} +103 -1
- package/dist/{chunk-BJNRLLDO.js → chunk-NHQDQJL2.js} +769 -244
- package/dist/index.d.ts +304 -9
- package/dist/index.js +2166 -509
- package/dist/preview/index.d.ts +2 -2
- package/dist/preview/index.js +147 -1
- package/dist/styles.css +135 -0
- package/package.json +2 -2
- package/src/MessageComposer.test.tsx +14 -0
- package/src/MessageComposer.tsx +327 -73
- package/src/RichMessageComposer.test.tsx +22 -4
- package/src/RichMessageComposer.tsx +674 -370
- package/src/index.ts +28 -1
- package/src/preview/createMockConversationsApi.ts +184 -0
- package/src/providers/types.ts +34 -0
- package/src/quickReplies/AttachmentsFormSection.tsx +160 -0
- package/src/quickReplies/QuickRepliesPicker.test.tsx +114 -0
- package/src/quickReplies/QuickRepliesPicker.tsx +188 -0
- package/src/quickReplies/QuickRepliesWorkspace.test.tsx +32 -0
- package/src/quickReplies/QuickRepliesWorkspace.tsx +395 -0
- package/src/quickReplies/createUploadQueue.test.ts +106 -0
- package/src/quickReplies/createUploadQueue.ts +69 -0
- package/src/quickReplies/index.ts +5 -0
- package/src/quickReplies/labels.ts +124 -0
- package/src/quickReplies/quickReply.types.ts +74 -0
- package/src/quickReplies/quickReplyAttachmentUpload.test.ts +76 -0
- package/src/quickReplies/quickReplyAttachmentUpload.ts +81 -0
- package/src/quickReplies/quickReplyAttachments.test.ts +396 -0
- package/src/quickReplies/quickReplyAttachments.ts +289 -0
- package/src/quickReplies/quickReplySearch.test.ts +88 -0
- package/src/quickReplies/quickReplySearch.ts +104 -0
- package/src/quickReplies/quickReplyShortcut.test.ts +38 -0
- package/src/quickReplies/quickReplyShortcut.ts +46 -0
- package/src/quickReplies/resolveConversationVariables.test.ts +63 -0
- package/src/quickReplies/resolveConversationVariables.ts +41 -0
- package/src/quickReplies/useQuickRepliesPicker.test.ts +20 -0
- package/src/quickReplies/useQuickRepliesPicker.ts +121 -0
- package/src/quickReplies/useQuickRepliesWorkspace.test.ts +222 -0
- package/src/quickReplies/useQuickRepliesWorkspace.ts +426 -0
- package/src/quickReplies/useQuickReplyAttachmentUploads.ts +159 -0
- package/src/styles.css +87 -0
- package/src/workspace/ConversationPane.tsx +137 -73
- package/src/workspace/ConversationsWorkspace.tsx +16 -1
- package/src/workspace/QueuedAttachmentsList.test.ts +27 -0
- package/src/workspace/QueuedAttachmentsList.tsx +198 -0
- package/src/workspace/index.ts +1 -0
- package/src/workspace/labels.ts +14 -0
- package/src/workspace/useComposerAttachmentRetry.ts +155 -0
- package/src/workspace/useComposerQueue.ts +220 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import react__default, { ReactNode, CSSProperties, UIEvent, FormEvent, RefObject } from 'react';
|
|
3
|
-
import {
|
|
4
|
-
export { A as AudioRecorderButton, a as AudioRecorderButtonLabels, b as AudioRecorderButtonProps, C as CHANNEL_CAPABILITIES, c as CHANNEL_FILTER_ALL, d as CONVERSATION_CHANNEL, e as ChannelCapabilities, h as CompanyDocument, i as CompanyDocumentPage, l as ConversationDocumentPage, m as ConversationEventSource, n as ConversationPage,
|
|
2
|
+
import react__default, { ReactNode, CSSProperties, UIEvent, FormEvent, RefObject, KeyboardEvent } from 'react';
|
|
3
|
+
import { V as MessagePayload, a9 as ResolveMediaUrl, Q as InteractiveSelection, W as MessageTranscription, O as InteractivePayload, y as ConversationsFeatures, a4 as QuickReply$1, u as ConversationSummary, j as ConversationChannel, R as ListConversationsParams, x as ConversationsApi, ab as SSEProvider, ah as TranscriptionMode, S as ListDocumentsParams, k as ConversationDocument, v as ConversationTemplate, a3 as QueuedAttachment, a6 as QuickReplyInput, a5 as QuickReplyAttachment, w as ConversationVariable, f as ChannelFilter, g as ChannelFilterOption, q as ConversationSimulatorClient, s as ConversationSimulatorPanelLabels, _ as PreviewUploadedMedia } from './ConversationSimulatorPanel-ikgmlciE.js';
|
|
4
|
+
export { A as AudioRecorderButton, a as AudioRecorderButtonLabels, b as AudioRecorderButtonProps, C as CHANNEL_CAPABILITIES, c as CHANNEL_FILTER_ALL, d as CONVERSATION_CHANNEL, e as ChannelCapabilities, h as CompanyDocument, i as CompanyDocumentPage, l as ConversationDocumentPage, m as ConversationEventSource, n as ConversationPage, z as ConversationsTheme, B as ConversationsUIConfig, F as DEFAULT_AUDIO_RECORDER_BUTTON_LABELS, G as DEFAULT_CONVERSATION_CHANNEL, I as DEFAULT_MAX_RECORDING_MILLISECONDS, K as FormatContactHandleParams, L as HANDLE_KIND, M as HandleKind, N as InteractiveOption, P as InteractiveSection, T as MediaRenderer, U as MediaRendererProps, a2 as QUICK_REPLY_ATTACHMENT_LIMIT, a7 as REOPEN_MECHANISM, a8 as ReopenMechanism, ad as SendSimulatorMediaParams, ae as SimulatorMediaKind, af as StoredAttachmentSendResult, ai as TranscriptionStatus, al as capabilitiesOf, am as channelFiltersFor, an as contactFlag, ar as formatContactHandle } from './ConversationSimulatorPanel-ikgmlciE.js';
|
|
5
5
|
import '@adatechnology/meta-whatsapp-contracts/testing';
|
|
6
6
|
|
|
7
7
|
interface MessageBubbleProps {
|
|
@@ -186,6 +186,75 @@ declare const EMOJI_CATEGORIES: readonly EmojiCategory[];
|
|
|
186
186
|
*/
|
|
187
187
|
declare function searchEmojis(query: string): readonly EmojiEntry[];
|
|
188
188
|
|
|
189
|
+
/**
|
|
190
|
+
* Vocabulário das telas de mensagens prontas. Sobrescrevível campo a campo — mesma convenção de
|
|
191
|
+
* `documents/labels.ts` e `workspace/labels.ts`.
|
|
192
|
+
*/
|
|
193
|
+
interface QuickRepliesPickerLabels {
|
|
194
|
+
readonly loading: string;
|
|
195
|
+
readonly error: string;
|
|
196
|
+
readonly empty: string;
|
|
197
|
+
readonly noResults: string;
|
|
198
|
+
/** Contagem ao lado do clipe na linha (QR-32): "2 anexos". */
|
|
199
|
+
readonly attachmentsCount: (count: number) => string;
|
|
200
|
+
/** Mostrado na linha quando a mensagem tem anexo, mas o produto não sabe mandá-lo (QR-33). */
|
|
201
|
+
readonly attachmentsUnavailable: string;
|
|
202
|
+
}
|
|
203
|
+
declare const DEFAULT_QUICK_REPLIES_PICKER_LABELS: QuickRepliesPickerLabels;
|
|
204
|
+
interface QuickRepliesWorkspaceLabels {
|
|
205
|
+
readonly title: string;
|
|
206
|
+
readonly subtitle: (total: number) => string;
|
|
207
|
+
readonly searchPlaceholder: string;
|
|
208
|
+
readonly loading: string;
|
|
209
|
+
readonly failure: string;
|
|
210
|
+
readonly empty: string;
|
|
211
|
+
readonly noResults: string;
|
|
212
|
+
readonly create: string;
|
|
213
|
+
readonly edit: string;
|
|
214
|
+
readonly remove: string;
|
|
215
|
+
readonly removeConfirm: (title: string) => string;
|
|
216
|
+
readonly save: string;
|
|
217
|
+
readonly cancel: string;
|
|
218
|
+
readonly columnTitle: string;
|
|
219
|
+
readonly columnShortcut: string;
|
|
220
|
+
readonly columnBody: string;
|
|
221
|
+
readonly columnActions: string;
|
|
222
|
+
readonly fieldTitle: string;
|
|
223
|
+
readonly fieldTitleInvalid: string;
|
|
224
|
+
readonly fieldShortcut: string;
|
|
225
|
+
readonly fieldShortcutHint: string;
|
|
226
|
+
readonly fieldShortcutInvalid: string;
|
|
227
|
+
readonly fieldBody: string;
|
|
228
|
+
readonly fieldBodyInvalid: string;
|
|
229
|
+
readonly insertVariable: string;
|
|
230
|
+
readonly shortcutTaken: string;
|
|
231
|
+
readonly readOnlyNotice: string;
|
|
232
|
+
readonly saveError: string;
|
|
233
|
+
/** Sem `createQuickReply`/`updateQuickReply` na porta — a tela não deveria nem oferecer o botão,
|
|
234
|
+
* mas o formulário ainda precisa de um texto caso chame `submit` de outro jeito. */
|
|
235
|
+
readonly saveUnavailable: string;
|
|
236
|
+
readonly saving: string;
|
|
237
|
+
readonly deleting: string;
|
|
238
|
+
/** Seção de anexos (QR-31) — só aparece com `uploadQuickReplyAttachment` na porta. */
|
|
239
|
+
readonly attachmentsTitle: string;
|
|
240
|
+
readonly attachmentsAdd: string;
|
|
241
|
+
readonly attachmentsEmpty: string;
|
|
242
|
+
readonly attachmentUploading: (percent: number) => string;
|
|
243
|
+
/** @deprecated Sem uso: não existe um "processando" observável entre a resposta do upload e o
|
|
244
|
+
* item entrar em `editing.attachments` — as duas atualizações de estado acontecem no mesmo
|
|
245
|
+
* commit do React. Mantido no tipo só para não quebrar quem já customiza este campo. */
|
|
246
|
+
readonly attachmentProcessing: string;
|
|
247
|
+
readonly attachmentRetry: string;
|
|
248
|
+
readonly attachmentRemove: string;
|
|
249
|
+
readonly attachmentCancel: string;
|
|
250
|
+
readonly attachmentMoveUp: string;
|
|
251
|
+
readonly attachmentMoveDown: string;
|
|
252
|
+
readonly attachmentLimitReached: string;
|
|
253
|
+
readonly attachmentTooLarge: (filename: string) => string;
|
|
254
|
+
readonly saveBlockedUploading: string;
|
|
255
|
+
}
|
|
256
|
+
declare const DEFAULT_QUICK_REPLIES_WORKSPACE_LABELS: QuickRepliesWorkspaceLabels;
|
|
257
|
+
|
|
189
258
|
/**
|
|
190
259
|
* Mensagem pronta que o atendente cola no campo com um clique.
|
|
191
260
|
*
|
|
@@ -210,8 +279,30 @@ interface MessageComposerLabels {
|
|
|
210
279
|
attach: string;
|
|
211
280
|
send: string;
|
|
212
281
|
removeAttachment: string;
|
|
282
|
+
quickReplies: string;
|
|
213
283
|
}
|
|
214
284
|
declare const DEFAULT_MESSAGE_COMPOSER_LABELS: MessageComposerLabels;
|
|
285
|
+
/**
|
|
286
|
+
* Mensagens prontas do produto, cadastradas pela tela de gestão. **Opcional por capacidade:** sem
|
|
287
|
+
* esta prop o botão de raio e o atalho `/` simplesmente não existem — não um botão que abre uma
|
|
288
|
+
* lista vazia.
|
|
289
|
+
*/
|
|
290
|
+
interface MessageComposerSavedQuickReplies {
|
|
291
|
+
readonly listQuickReplies: (params?: {
|
|
292
|
+
search?: string;
|
|
293
|
+
}) => Promise<QuickReply$1[]>;
|
|
294
|
+
/** Chave do cache do picker — troca de conversa não deve reconsultar o que já carregou. */
|
|
295
|
+
readonly conversationId: string;
|
|
296
|
+
readonly variables?: Readonly<Record<string, string>>;
|
|
297
|
+
readonly labels?: Partial<QuickRepliesPickerLabels>;
|
|
298
|
+
/**
|
|
299
|
+
* Avisada antes de inserir o texto, para o host empurrar os anexos da mensagem escolhida na fila
|
|
300
|
+
* do composer (QR-32). Sem esta prop nada muda — o texto continua sendo inserido do mesmo jeito.
|
|
301
|
+
*/
|
|
302
|
+
readonly onSelect?: (quickReply: QuickReply$1) => void;
|
|
303
|
+
/** Sem `sendStoredAttachments` no host, a linha com anexo avisa em vez de prometer envio (QR-33). */
|
|
304
|
+
readonly hasAttachmentsCapability?: boolean;
|
|
305
|
+
}
|
|
215
306
|
interface MessageComposerProps {
|
|
216
307
|
labels?: Partial<MessageComposerLabels>;
|
|
217
308
|
onSend: (text: string) => void;
|
|
@@ -232,6 +323,8 @@ interface MessageComposerProps {
|
|
|
232
323
|
quickReplies?: readonly QuickReply[];
|
|
233
324
|
/** Valores para `{{variavel}}` — tipicamente nome do cliente, produto, protocolo. */
|
|
234
325
|
quickReplyVariables?: Readonly<Record<string, string>>;
|
|
326
|
+
/** Botão de raio + atalho `/` para as mensagens prontas cadastradas. Ausente, nenhum dos dois aparece. */
|
|
327
|
+
savedQuickReplies?: MessageComposerSavedQuickReplies;
|
|
235
328
|
className?: string;
|
|
236
329
|
classNames?: Partial<MessageComposerClassNames>;
|
|
237
330
|
}
|
|
@@ -248,7 +341,7 @@ interface MessageComposerClassNames {
|
|
|
248
341
|
* Produto com regra própria passa `acceptedFileTypes`.
|
|
249
342
|
*/
|
|
250
343
|
declare const DEFAULT_ACCEPTED_FILE_TYPES: string;
|
|
251
|
-
declare const MessageComposer: ({ onSend, onAttach, value: externalValue, onChange: externalOnChange, quickReplies, quickReplyVariables, features, placeholder, maxLength, disabled, acceptedFileTypes, idleAction, className, classNames, labels, }: MessageComposerProps) => react.JSX.Element;
|
|
344
|
+
declare const MessageComposer: ({ onSend, onAttach, value: externalValue, onChange: externalOnChange, quickReplies, quickReplyVariables, savedQuickReplies, features, placeholder, maxLength, disabled, acceptedFileTypes, idleAction, className, classNames, labels, }: MessageComposerProps) => react.JSX.Element;
|
|
252
345
|
|
|
253
346
|
/** Cada ação que a barra sabe oferecer. `toolbar` decide quais delas aparecem. */
|
|
254
347
|
declare const RICH_COMPOSER_ACTION: {
|
|
@@ -259,6 +352,7 @@ declare const RICH_COMPOSER_ACTION: {
|
|
|
259
352
|
readonly EMOJI: "emoji";
|
|
260
353
|
readonly ATTACH: "attach";
|
|
261
354
|
readonly VARIABLES: "variables";
|
|
355
|
+
readonly QUICK_REPLIES: "quickReplies";
|
|
262
356
|
};
|
|
263
357
|
type RichComposerAction = (typeof RICH_COMPOSER_ACTION)[keyof typeof RICH_COMPOSER_ACTION];
|
|
264
358
|
/** Texto das dicas. O host troca só o que quiser; o resto fica no padrão. */
|
|
@@ -273,8 +367,29 @@ interface RichComposerTooltips {
|
|
|
273
367
|
variables: string;
|
|
274
368
|
/** Botão que abre a formatação recolhida, quando a barra está estreita demais para os quatro. */
|
|
275
369
|
formatting: string;
|
|
370
|
+
quickReplies: string;
|
|
276
371
|
}
|
|
277
372
|
declare const DEFAULT_RICH_COMPOSER_TOOLTIPS: RichComposerTooltips;
|
|
373
|
+
/**
|
|
374
|
+
* Mensagens prontas do produto. **Opcional por capacidade:** sem esta prop o botão de raio e o
|
|
375
|
+
* atalho `/` não existem — não um botão que abre uma lista vazia.
|
|
376
|
+
*/
|
|
377
|
+
interface RichComposerSavedQuickReplies {
|
|
378
|
+
readonly listQuickReplies: (params?: {
|
|
379
|
+
search?: string;
|
|
380
|
+
}) => Promise<QuickReply$1[]>;
|
|
381
|
+
/** Chave do cache do picker — troca de conversa não deve reconsultar o que já carregou. */
|
|
382
|
+
readonly conversationId: string;
|
|
383
|
+
readonly variables?: Readonly<Record<string, string>>;
|
|
384
|
+
readonly labels?: Partial<QuickRepliesPickerLabels>;
|
|
385
|
+
/**
|
|
386
|
+
* Avisada antes de inserir o texto, para o host empurrar os anexos da mensagem escolhida na fila
|
|
387
|
+
* do composer (QR-32). Sem esta prop nada muda — o texto continua sendo inserido do mesmo jeito.
|
|
388
|
+
*/
|
|
389
|
+
readonly onSelect?: (quickReply: QuickReply$1) => void;
|
|
390
|
+
/** Sem `sendStoredAttachments` no host, a linha com anexo avisa em vez de prometer envio (QR-33). */
|
|
391
|
+
readonly hasAttachmentsCapability?: boolean;
|
|
392
|
+
}
|
|
278
393
|
/**
|
|
279
394
|
* Um valor que o operador pode inserir no texto sem digitar. `value` é o que entra no campo — pode
|
|
280
395
|
* ser o dado já resolvido ("Anderson") ou um marcador a resolver depois ("{{nome}}"): quem decide é
|
|
@@ -310,6 +425,8 @@ interface RichMessageComposerProps {
|
|
|
310
425
|
quickReplies?: RichComposerQuickReply[];
|
|
311
426
|
/** Variáveis que o operador pode inserir no texto. Vazio ou ausente, o botão não aparece. */
|
|
312
427
|
variables?: RichComposerVariable[];
|
|
428
|
+
/** Botão de raio + atalho `/` para as mensagens prontas cadastradas. Ausente, nenhum dos dois aparece. */
|
|
429
|
+
savedQuickReplies?: RichComposerSavedQuickReplies;
|
|
313
430
|
/**
|
|
314
431
|
* Quais ações aparecem. Ausente, todas aparecem — menos as que não têm como funcionar (anexo sem
|
|
315
432
|
* `onAttachFiles` some sozinho, porque botão que não faz nada é pior que botão nenhum).
|
|
@@ -1622,6 +1739,136 @@ interface AsyncResourceState<T> {
|
|
|
1622
1739
|
|
|
1623
1740
|
declare function createMediaUrlResolver(api: Pick<ConversationsApi, 'getDocumentUrl' | 'getMediaProxyUrl'>): ResolveMediaUrl;
|
|
1624
1741
|
|
|
1742
|
+
/**
|
|
1743
|
+
* Anexos de uma mensagem pronta escolhida no picker, prontos para entrar na fila como `stored`
|
|
1744
|
+
* (QR-32). Vazio sem `hasAttachmentsCapability` — sem `sendStoredAttachments` no host, empurrar o
|
|
1745
|
+
* item só encalharia na fila sem jeito de sair; a linha do picker já avisou disso antes do clique.
|
|
1746
|
+
*/
|
|
1747
|
+
declare function queuedAttachmentsFromQuickReply(quickReply: Pick<QuickReply$1, 'attachments'>, hasAttachmentsCapability: boolean): readonly QueuedAttachment[];
|
|
1748
|
+
type AttachmentSendStatus = 'waiting' | 'sending' | 'sent' | 'failed' | 'skipped';
|
|
1749
|
+
/** Espelha os tetos da API; o host sobrescreve quando o backend dele aceita outro tamanho. */
|
|
1750
|
+
declare const DEFAULT_MAX_ATTACHMENT_SIZE_BYTES: {
|
|
1751
|
+
readonly document: number;
|
|
1752
|
+
readonly image: number;
|
|
1753
|
+
readonly audio: number;
|
|
1754
|
+
readonly video: number;
|
|
1755
|
+
};
|
|
1756
|
+
type MaxAttachmentSizeBytes = {
|
|
1757
|
+
readonly document: number;
|
|
1758
|
+
readonly image: number;
|
|
1759
|
+
readonly audio: number;
|
|
1760
|
+
readonly video: number;
|
|
1761
|
+
};
|
|
1762
|
+
type OutgoingItems = {
|
|
1763
|
+
readonly text: string;
|
|
1764
|
+
readonly attachments: readonly QueuedAttachment[];
|
|
1765
|
+
};
|
|
1766
|
+
declare function resolveMaxAttachmentSizeBytes(mimeType: string, limits?: MaxAttachmentSizeBytes): number;
|
|
1767
|
+
|
|
1768
|
+
/**
|
|
1769
|
+
* Funções puras do upload de anexo na tela de cadastro (QR-31): validação antes de subir,
|
|
1770
|
+
* reordenação e o limitador de concorrência. Sem estado de React — testáveis sem montar o hook.
|
|
1771
|
+
*/
|
|
1772
|
+
|
|
1773
|
+
type AttachmentFileRejection = {
|
|
1774
|
+
readonly file: File;
|
|
1775
|
+
readonly reason: 'limit' | 'size';
|
|
1776
|
+
};
|
|
1777
|
+
type ValidateAttachmentFilesResult = {
|
|
1778
|
+
readonly accepted: readonly File[];
|
|
1779
|
+
readonly rejected: readonly AttachmentFileRejection[];
|
|
1780
|
+
};
|
|
1781
|
+
|
|
1782
|
+
/**
|
|
1783
|
+
* Portas que a tela de cadastro precisa. `create`/`update`/`delete` ausentes não impedem a leitura
|
|
1784
|
+
* — só tiram a ação correspondente, a mesma regra de capacidade do resto do pacote.
|
|
1785
|
+
*/
|
|
1786
|
+
interface QuickRepliesWorkspaceApi {
|
|
1787
|
+
readonly listQuickReplies?: (params?: {
|
|
1788
|
+
search?: string;
|
|
1789
|
+
}) => Promise<QuickReply$1[]>;
|
|
1790
|
+
readonly createQuickReply?: (input: QuickReplyInput) => Promise<QuickReply$1>;
|
|
1791
|
+
readonly updateQuickReply?: (id: string, input: QuickReplyInput) => Promise<QuickReply$1>;
|
|
1792
|
+
readonly deleteQuickReply?: (id: string) => Promise<void>;
|
|
1793
|
+
/** Sem esta porta, a seção de anexos não aparece — nem no formulário. */
|
|
1794
|
+
readonly uploadQuickReplyAttachment?: (file: File, options?: {
|
|
1795
|
+
onProgress?: (fraction: number) => void;
|
|
1796
|
+
signal?: AbortSignal;
|
|
1797
|
+
}) => Promise<QuickReplyAttachment>;
|
|
1798
|
+
}
|
|
1799
|
+
|
|
1800
|
+
interface QuickRepliesWorkspaceProps {
|
|
1801
|
+
readonly api: QuickRepliesWorkspaceApi;
|
|
1802
|
+
/** Catálogo de variáveis oferecido pelos botões "Inserir variável" do formulário. */
|
|
1803
|
+
readonly variables?: readonly ConversationVariable[];
|
|
1804
|
+
readonly labels?: Partial<QuickRepliesWorkspaceLabels>;
|
|
1805
|
+
readonly className?: string;
|
|
1806
|
+
/** Sobrescreve o teto por tipo de arquivo. Ausente, usa `DEFAULT_MAX_ATTACHMENT_SIZE_BYTES`. */
|
|
1807
|
+
readonly attachmentSizeLimits?: MaxAttachmentSizeBytes;
|
|
1808
|
+
}
|
|
1809
|
+
/**
|
|
1810
|
+
* Tela de gestão das mensagens prontas: tabela com busca e zebra, formulário de criação/edição, e
|
|
1811
|
+
* exclusão com confirmação. Some o formulário quando o host não passa `createQuickReply` — vira
|
|
1812
|
+
* consulta, a mesma regra de capacidade do resto do pacote.
|
|
1813
|
+
*/
|
|
1814
|
+
declare function QuickRepliesWorkspace({ api, variables, labels, className, attachmentSizeLimits, }: QuickRepliesWorkspaceProps): react.JSX.Element;
|
|
1815
|
+
|
|
1816
|
+
/**
|
|
1817
|
+
* Presente só no modo botão: o picker desenha e é dono da própria busca — focada ao abrir, dona de
|
|
1818
|
+
* seta/Enter/Esc. O campo de mensagem não é tocado (QR-04): abrir pelo raio nunca insere `/` nele.
|
|
1819
|
+
* Ausente, a busca vem do atalho `/termo` digitado no próprio campo, que continua no comando.
|
|
1820
|
+
*/
|
|
1821
|
+
type QuickRepliesPickerOwnSearch = {
|
|
1822
|
+
readonly value: string;
|
|
1823
|
+
readonly onChange: (value: string) => void;
|
|
1824
|
+
readonly onKeyDown: (event: KeyboardEvent<HTMLInputElement>) => void;
|
|
1825
|
+
readonly label: string;
|
|
1826
|
+
};
|
|
1827
|
+
type QuickRepliesPickerProps = {
|
|
1828
|
+
/** Id do `listbox`, para o campo (ou a busca própria) apontar `aria-activedescendant`. */
|
|
1829
|
+
readonly id: string;
|
|
1830
|
+
readonly items: readonly QuickReply$1[];
|
|
1831
|
+
readonly search: string;
|
|
1832
|
+
readonly highlightedIndex: number;
|
|
1833
|
+
readonly isLoading: boolean;
|
|
1834
|
+
/** Sinalizador puro — o texto exibido é sempre `labels.error`, nunca mensagem crua de exceção. */
|
|
1835
|
+
readonly hasError?: boolean;
|
|
1836
|
+
readonly onHover: (index: number) => void;
|
|
1837
|
+
readonly onSelect: (quickReply: QuickReply$1) => void;
|
|
1838
|
+
readonly labels?: Partial<QuickRepliesPickerLabels>;
|
|
1839
|
+
readonly className?: string;
|
|
1840
|
+
readonly ownSearch?: QuickRepliesPickerOwnSearch;
|
|
1841
|
+
/** Resolve `{{marcador}}` antes de destacar e mostrar a prévia (QR-04) — quem busca "joão" espera
|
|
1842
|
+
* ver "Olá João" na lista, não o marcador cru. */
|
|
1843
|
+
readonly variables?: Readonly<Record<string, string>>;
|
|
1844
|
+
/** Sem `sendStoredAttachments` no host, a linha com anexo avisa em vez de prometer envio (QR-33). */
|
|
1845
|
+
readonly hasAttachmentsCapability?: boolean;
|
|
1846
|
+
};
|
|
1847
|
+
/**
|
|
1848
|
+
* Lista flutuante do atalho `/` e do botão de raio. Puramente controlada — todo estado (busca,
|
|
1849
|
+
* destaque, carregamento) vem de `useQuickRepliesPicker`, este componente só desenha.
|
|
1850
|
+
*/
|
|
1851
|
+
declare function QuickRepliesPicker({ id, items, search, highlightedIndex, isLoading, hasError, onHover, onSelect, labels, className, ownSearch, variables, hasAttachmentsCapability, }: QuickRepliesPickerProps): react.JSX.Element;
|
|
1852
|
+
|
|
1853
|
+
declare function normalizeForSearch(value: string): string;
|
|
1854
|
+
type FilterQuickRepliesParams = {
|
|
1855
|
+
readonly quickReplies: readonly QuickReply$1[];
|
|
1856
|
+
readonly search: string;
|
|
1857
|
+
/** Resolve `{{marcador}}` antes de comparar — buscar "joão" deve achar quem cita o nome no corpo. */
|
|
1858
|
+
readonly variables?: Readonly<Record<string, string>>;
|
|
1859
|
+
};
|
|
1860
|
+
/** Busca por título, atalho e corpo (com as variáveis já aplicadas). Termo vazio devolve tudo. */
|
|
1861
|
+
declare function filterQuickReplies({ quickReplies, search, variables, }: FilterQuickRepliesParams): readonly QuickReply$1[];
|
|
1862
|
+
type MatchSegment = {
|
|
1863
|
+
readonly text: string;
|
|
1864
|
+
readonly isMatch: boolean;
|
|
1865
|
+
};
|
|
1866
|
+
/**
|
|
1867
|
+
* Segmenta o texto ao redor do termo buscado para o chamador destacar sem HTML — quem cadastrou a
|
|
1868
|
+
* mensagem não deve conseguir injetar marcação pelo próprio corpo ou título.
|
|
1869
|
+
*/
|
|
1870
|
+
declare function highlightMatch(text: string, search: string): readonly MatchSegment[];
|
|
1871
|
+
|
|
1625
1872
|
/**
|
|
1626
1873
|
* Textos da inbox. Todos sobrescrevíveis: o produto troca vocabulário ("cliente" vira "lead") ou
|
|
1627
1874
|
* o idioma inteiro sem tocar no layout — e sem manter uma cópia da tela para isso.
|
|
@@ -1659,6 +1906,14 @@ interface ConversationsWorkspaceLabels {
|
|
|
1659
1906
|
readonly attachFailure: string;
|
|
1660
1907
|
/** Tira um arquivo da fila antes de enviar. */
|
|
1661
1908
|
readonly attachmentRemove: string;
|
|
1909
|
+
/** Estado de cada item da fila durante o envio (QR-47). */
|
|
1910
|
+
readonly attachmentWaiting: string;
|
|
1911
|
+
readonly attachmentSending: string;
|
|
1912
|
+
readonly attachmentSent: string;
|
|
1913
|
+
readonly attachmentFailed: string;
|
|
1914
|
+
/** Servidor parou antes de tentar este arquivo, por causa de uma falha anterior no mesmo lote. */
|
|
1915
|
+
readonly attachmentSkipped: string;
|
|
1916
|
+
readonly attachmentRetry: string;
|
|
1662
1917
|
readonly recordFailure: string;
|
|
1663
1918
|
readonly sendFailure: string;
|
|
1664
1919
|
readonly takeoverToReply: string;
|
|
@@ -1809,6 +2064,7 @@ interface ConversationsWorkspaceProps {
|
|
|
1809
2064
|
readonly initialWhatsappNumber?: string | undefined;
|
|
1810
2065
|
readonly simulator?: ConversationsWorkspaceSimulator;
|
|
1811
2066
|
readonly quickReplies?: readonly QuickReply[];
|
|
2067
|
+
/** @deprecated Use `conversationVariablesFor`, que alimenta os dois composers com uma lista só. */
|
|
1812
2068
|
readonly quickReplyVariablesFor?: (conversation: ConversationSummary, context: Record<string, unknown> | undefined) => Record<string, string>;
|
|
1813
2069
|
/** Etapa do fluxo mostrada no painel de contexto. */
|
|
1814
2070
|
readonly flowLabelOf?: (conversation: ConversationSummary) => string | undefined;
|
|
@@ -1822,8 +2078,16 @@ interface ConversationsWorkspaceProps {
|
|
|
1822
2078
|
readonly initialComposerText?: string | undefined;
|
|
1823
2079
|
/** `rich` troca o campo simples pelo texto com a formatação do WhatsApp desenhada ao escrever. */
|
|
1824
2080
|
readonly composer?: 'simple' | 'rich';
|
|
1825
|
-
/**
|
|
2081
|
+
/**
|
|
2082
|
+
* Valores que o operador insere sem digitar. Só o composer `rich` os oferece.
|
|
2083
|
+
* @deprecated Use `conversationVariablesFor`.
|
|
2084
|
+
*/
|
|
1826
2085
|
readonly composerVariablesFor?: (conversation: ConversationSummary, context: Record<string, unknown> | undefined) => readonly RichComposerVariable[];
|
|
2086
|
+
/**
|
|
2087
|
+
* Dados da conversa que o texto pode citar, numa lista só. Presente, manda sobre
|
|
2088
|
+
* `quickReplyVariablesFor` e `composerVariablesFor`.
|
|
2089
|
+
*/
|
|
2090
|
+
readonly conversationVariablesFor?: (conversation: ConversationSummary, context: Record<string, unknown> | undefined) => readonly ConversationVariable[];
|
|
1827
2091
|
/** Fila de anexos com legenda, como no WhatsApp. Ausente, o clipe manda cada arquivo na hora. */
|
|
1828
2092
|
readonly onSendAttachments?: (conversation: ConversationSummary, files: readonly File[], caption: string) => Promise<void>;
|
|
1829
2093
|
/** Nota de voz. Ausente, o microfone não aparece. */
|
|
@@ -1841,7 +2105,7 @@ interface ConversationsWorkspaceProps {
|
|
|
1841
2105
|
readonly signInHref?: string;
|
|
1842
2106
|
readonly className?: string;
|
|
1843
2107
|
}
|
|
1844
|
-
declare function ConversationsWorkspace({ labels: labelsOverride, filters, perPage, markReadOnOpen, serverPaginated, initialConversationId, initialWhatsappNumber, simulator, quickReplies, quickReplyVariablesFor, flowLabelOf, onDownload, requireTakeoverToReply, messageSelection, initialComposerText, composer, composerVariablesFor, onSendAttachments, onRecordAudio, contextEntriesOf, onAttach, extraUtilitiesFor, renderFilters, renderBulkActions, renderRow, renderAboveTranscript, renderHeaderActions, onSendTemplateToSelected, signInHref, className, }: ConversationsWorkspaceProps): react.JSX.Element;
|
|
2108
|
+
declare function ConversationsWorkspace({ labels: labelsOverride, filters, perPage, markReadOnOpen, serverPaginated, initialConversationId, initialWhatsappNumber, simulator, quickReplies, quickReplyVariablesFor, flowLabelOf, onDownload, requireTakeoverToReply, messageSelection, initialComposerText, composer, composerVariablesFor, conversationVariablesFor, onSendAttachments, onRecordAudio, contextEntriesOf, onAttach, extraUtilitiesFor, renderFilters, renderBulkActions, renderRow, renderAboveTranscript, renderHeaderActions, onSendTemplateToSelected, signInHref, className, }: ConversationsWorkspaceProps): react.JSX.Element;
|
|
1845
2109
|
|
|
1846
2110
|
interface ConversationPaneProps {
|
|
1847
2111
|
readonly conversation: ConversationSummary;
|
|
@@ -1861,6 +2125,7 @@ interface ConversationPaneProps {
|
|
|
1861
2125
|
* Recebe o contexto junto porque o dado que interessa à variável (o nome que o bot perguntou,
|
|
1862
2126
|
* por exemplo) vive no contexto do fluxo, não no resumo da listagem.
|
|
1863
2127
|
*/
|
|
2128
|
+
/** @deprecated Use `conversationVariablesFor`, que alimenta os dois composers com uma lista só. */
|
|
1864
2129
|
readonly quickReplyVariablesFor?: (conversation: ConversationSummary, context: Record<string, unknown> | undefined) => Record<string, string>;
|
|
1865
2130
|
/** Etapa do fluxo ao lado do contexto (ex.: "Anotando o pedido"). */
|
|
1866
2131
|
readonly flowLabel?: string | undefined;
|
|
@@ -1893,8 +2158,16 @@ interface ConversationPaneProps {
|
|
|
1893
2158
|
* é menos coisa na tela.
|
|
1894
2159
|
*/
|
|
1895
2160
|
readonly composer?: 'simple' | 'rich';
|
|
1896
|
-
/**
|
|
2161
|
+
/**
|
|
2162
|
+
* Valores que o operador insere sem digitar. Só o composer `rich` os oferece.
|
|
2163
|
+
* @deprecated Use `conversationVariablesFor`.
|
|
2164
|
+
*/
|
|
1897
2165
|
readonly composerVariablesFor?: (conversation: ConversationSummary, context: Record<string, unknown> | undefined) => readonly RichComposerVariable[];
|
|
2166
|
+
/**
|
|
2167
|
+
* Dados da conversa que o texto pode citar, numa lista só. Presente, manda sobre
|
|
2168
|
+
* `quickReplyVariablesFor` e `composerVariablesFor`.
|
|
2169
|
+
*/
|
|
2170
|
+
readonly conversationVariablesFor?: (conversation: ConversationSummary, context: Record<string, unknown> | undefined) => readonly ConversationVariable[];
|
|
1898
2171
|
/**
|
|
1899
2172
|
* Fila de anexos com legenda, como no WhatsApp: os arquivos escolhidos ficam visíveis acima da
|
|
1900
2173
|
* barra e saem junto com o texto escrito. Ausente, o clipe manda cada arquivo na hora — o que
|
|
@@ -1904,7 +2177,7 @@ interface ConversationPaneProps {
|
|
|
1904
2177
|
/** Grava e envia nota de voz. Ausente, o microfone não aparece. */
|
|
1905
2178
|
readonly onRecordAudio?: (file: File) => Promise<void>;
|
|
1906
2179
|
}
|
|
1907
|
-
declare function ConversationPane({ conversation, now, busy, labels, onTakeover, onReturnToBot, onFinish, onBack, extraUtilities, contextEntriesOf, quickReplies, quickReplyVariablesFor, flowLabel, onDownload, requireTakeoverToReply, messageSelection, initialComposerText, renderAboveTranscript, onAttach, composer, composerVariablesFor, onSendAttachments, onRecordAudio, }: ConversationPaneProps): react.JSX.Element;
|
|
2180
|
+
declare function ConversationPane({ conversation, now, busy, labels, onTakeover, onReturnToBot, onFinish, onBack, extraUtilities, contextEntriesOf, quickReplies, quickReplyVariablesFor, flowLabel, onDownload, requireTakeoverToReply, messageSelection, initialComposerText, renderAboveTranscript, onAttach, composer, composerVariablesFor, conversationVariablesFor, onSendAttachments, onRecordAudio, }: ConversationPaneProps): react.JSX.Element;
|
|
1908
2181
|
|
|
1909
2182
|
interface ConversationsInboxListProps {
|
|
1910
2183
|
readonly inbox: UseConversationsInboxResult;
|
|
@@ -1919,4 +2192,26 @@ interface ConversationsInboxListProps {
|
|
|
1919
2192
|
}
|
|
1920
2193
|
declare function ConversationsInboxList({ inbox, labels, className, renderFilters, renderBulkActions, renderRow, onSendTemplateToSelected, }: ConversationsInboxListProps): react.JSX.Element;
|
|
1921
2194
|
|
|
1922
|
-
|
|
2195
|
+
type QueuedAttachmentsListLabels = {
|
|
2196
|
+
readonly remove: string;
|
|
2197
|
+
readonly waiting: string;
|
|
2198
|
+
readonly sending: string;
|
|
2199
|
+
readonly sent: string;
|
|
2200
|
+
readonly failed: string;
|
|
2201
|
+
readonly skipped: string;
|
|
2202
|
+
readonly retry: string;
|
|
2203
|
+
};
|
|
2204
|
+
type QueuedAttachmentsListProps = {
|
|
2205
|
+
readonly items: readonly QueuedAttachment[];
|
|
2206
|
+
readonly statusOf: (key: string) => AttachmentSendStatus;
|
|
2207
|
+
readonly onRemove: (item: QueuedAttachment) => void;
|
|
2208
|
+
readonly onRetry?: (item: QueuedAttachment) => void;
|
|
2209
|
+
/** Chaves com retry avulso em voo — desabilita o botão "Tentar de novo" desse item específico. */
|
|
2210
|
+
readonly retryingKeys?: ReadonlySet<string>;
|
|
2211
|
+
readonly getThumbnailUrl?: (uploadId: string) => Promise<string>;
|
|
2212
|
+
readonly labels: QueuedAttachmentsListLabels;
|
|
2213
|
+
readonly busy: boolean;
|
|
2214
|
+
};
|
|
2215
|
+
declare function QueuedAttachmentsList({ items, statusOf, onRemove, onRetry, retryingKeys, getThumbnailUrl, labels, busy, }: QueuedAttachmentsListProps): react.JSX.Element | null;
|
|
2216
|
+
|
|
2217
|
+
export { type AsyncResourceState, type AttachmentFileRejection, AudioPlayer, type AudioPlayerProps, AudioTranscription, type AudioTranscriptionProps, Avatar, type AvatarLabels, type AvatarProps, type BotMessages, type BuildTranscriptTextParams, BulkActionBar, type BulkActionBarProps, CHANNEL_BRAND_COLOR, CONVERSATIONS_PER_PAGE, CONVERSATION_WINDOW, ChannelFilter, ChannelFilterOption, ChannelIcon, type ChannelIconProps, ConversationChannel, type ConversationContextEntry, ConversationContextPanel, type ConversationContextPanelClassNames, type ConversationContextPanelLabels, type ConversationContextPanelProps, type ConversationContextStatus, ConversationDocument, ConversationDocumentsPanel, type ConversationDocumentsPanelClassNames, type ConversationDocumentsPanelLabels, type ConversationDocumentsPanelProps, ConversationHeader, type ConversationHeaderClassNames, type ConversationHeaderLabels, type ConversationHeaderProps, type ConversationHeaderUtility, ConversationListItem, type ConversationListItemLabels, type ConversationListItemProps, type ConversationLocales, ConversationLocalesProvider, type ConversationLocalesProviderProps, ConversationPane, type ConversationPaneProps, type ConversationRealtimeHandler, ConversationRow, type ConversationRowClassNames, type ConversationRowProps, ConversationSimulatorClient, ConversationSummary, ConversationTemplate, ConversationVariable, ConversationWallpaper, type ConversationWallpaperProps, type ConversationWindow, ConversationsApi, ConversationsFeatures, ConversationsInboxList, type ConversationsInboxListProps, ConversationsProvider, ConversationsWorkspace, type ConversationsWorkspaceLabels, type ConversationsWorkspaceProps, type ConversationsWorkspaceSimulator, DEFAULT_ACCEPTED_FILE_TYPES, DEFAULT_AVATAR_LABELS, DEFAULT_CONVERSATIONS_WORKSPACE_LABELS, DEFAULT_CONVERSATION_CONTEXT_LABELS, DEFAULT_CONVERSATION_DOCUMENTS_LABELS, DEFAULT_CONVERSATION_HEADER_LABELS, DEFAULT_CONVERSATION_LIST_ITEM_LABELS, DEFAULT_DARK_MODE_TOGGLE_LABELS, DEFAULT_DOCUMENTS_LIBRARY_LABELS, DEFAULT_DOCUMENTS_WORKSPACE_LABELS, DEFAULT_EMOJI_PICKER_LABELS, DEFAULT_INTERACTIVE_MESSAGE_LABELS, DEFAULT_LIGHTBOX_LABELS, DEFAULT_MAX_ATTACHMENT_SIZE_BYTES, DEFAULT_MESSAGE_COMPOSER_LABELS, DEFAULT_QUICK_REPLIES_PICKER_LABELS, DEFAULT_QUICK_REPLIES_WORKSPACE_LABELS, DEFAULT_RICH_COMPOSER_TOOLTIPS, DEFAULT_TEMPLATES_SETTINGS_LABELS, DEFAULT_WHATSAPP_MESSAGE_EDITOR_LABELS, DEFAULT_WINDOW_EXPIRED_LABELS, DOCUMENT_SOURCE_FILTER, DarkModeToggle, type DarkModeToggleLabels, type DarkModeToggleProps, DateDivider, type DateDividerClassNames, type DateDividerProps, type DocumentSourceFilter, type DocumentsFiltersContext, DocumentsLibrary, type DocumentsLibraryClassNames, type DocumentsLibraryLabels, type DocumentsLibraryProps, DocumentsWorkspace, type DocumentsWorkspaceClassNames, type DocumentsWorkspaceLabels, type DocumentsWorkspaceProps, EMOJI_CATEGORIES, type EmojiCategory, type EmojiEntry, EmojiPicker, type EmojiPickerLabels, type EmojiPickerProps, FileIcon, type FileIconProps, type FilterOption, type FilterQuickRepliesParams, InteractiveMessage, type InteractiveMessageLabels, type InteractiveMessageProps, InteractivePayload, InteractiveSelection, Lightbox, type LightboxLabels, type LightboxProps, ListConversationsParams, ListDocumentsParams, ListingPagination, type ListingPaginationProps, type MatchSegment, type MaxAttachmentSizeBytes, MessageBubble, type MessageBubbleProps, MessageComposer, type MessageComposerClassNames, type MessageComposerLabels, type MessageComposerProps, MessagePayload, MessageTail, MessageText, type MessageTextProps, MessageTimestamp, MessageTranscription, MessagesWorkspace, type MessagesWorkspaceApi, type MessagesWorkspaceLabels, type MessagesWorkspaceProps, type MessagesWorkspaceTemplateRole, MultiSelectFilter, type MultiSelectFilterProps, NARROW_MAX_WIDTH_PX, type OutgoingItems, QueuedAttachment, QueuedAttachmentsList, QuickRepliesPicker, type QuickRepliesPickerLabels, type QuickRepliesPickerProps, QuickRepliesWorkspace, type QuickRepliesWorkspaceLabels, type QuickRepliesWorkspaceProps, type QuickReply, QuickReplyAttachment, QuickReplyInput, REPLY_LATENCY, REPLY_LATENCY_CRITICAL_HOURS, REPLY_LATENCY_LATE_HOURS, RICH_COMPOSER_ACTION, type ReplyLatency, type ReplyLatencyParams, ResolveMediaUrl, type RichComposerAction, type RichComposerQuickReply, type RichComposerTooltips, type RichComposerVariable, RichMessageComposer, type RichMessageComposerHandle, type RichMessageComposerProps, SSEProvider, QuickReply$1 as SavedQuickReply, SimpleEmojiPicker, type SimpleEmojiPickerProps, type SimulatorTransportFactory, type SimulatorTransportParams, type SortDirection, SortableHead, type SortableHeadProps, StatusTicks, type StatusTicksProps, TEMPLATE_SETTINGS_TAB, TOOLTIP_ATTRIBUTE, type TemplateSettings, type TemplateSettingsTab, ToastProvider, TooltipLayer, type TopicItem, TopicsForm, type TopicsFormLabels, type TopicsFormProps, TranscriptionMode, type TranscriptionSettings, TranscriptionSettingsForm, type TranscriptionSettingsFormLabels, type TranscriptionSettingsFormProps, type UrlStateOptions, type UseConversationActionsResult, type UseConversationContextResult, type UseConversationDocumentsParams, type UseConversationDocumentsResult, type UseConversationListParams, type UseConversationListResult, type UseConversationMessagesResult, type UseConversationsInboxParams, type UseConversationsInboxResult, type UseInboxActionsResult, type UseScrollToLatestMessageParams, type UseScrollToLatestMessageResult, type UseWaitingNotificationsLabels, type UseWaitingNotificationsParams, type UseWaitingNotificationsResult, type ValidateAttachmentFilesResult, WINDOW_FILTERS, WelcomeFarewellForm, type WelcomeFarewellFormLabels, type WelcomeFarewellFormProps, WhatsAppCreateTemplateForm, type WhatsAppCreateTemplateFormLabels, type WhatsAppCreateTemplateFormProps, type WhatsAppCreateTemplateResult, type WhatsAppCreateTemplateState, WhatsAppMessageEditor, type WhatsAppMessageEditorLabels, type WhatsAppMessageEditorProps, type WhatsAppTemplateHeaderType, WhatsAppTemplateSettingsForm, type WhatsAppTemplateSettingsFormLabels, type WhatsAppTemplateSettingsFormProps, type WhatsAppTemplateSummary, type WhatsAppTemplateVariableSuggestion, WhatsAppTemplatesSettings, type WhatsAppTemplatesSettingsLabels, type WhatsAppTemplatesSettingsProps, WindowExpiredNotice, type WindowExpiredNoticeLabels, type WindowExpiredNoticeProps, type WindowOfParams, applyQuickReplyVariables, buildTranscriptFilename, buildTranscriptText, createMediaUrlResolver, downloadTextFile, filterQuickReplies, formatDateTime, formatFileSize, formatPhone, formatStalledFor, formatTimestamp, highlightMatch, htmlToWA, isReplyOverdue, isSameDay, isWindowBlocking, normalizeForSearch, parseWhatsAppFormatting, phoneInitials, queuedAttachmentsFromQuickReply, replyLatencyOf, resolveMaxAttachmentSizeBytes, resolveQuickReply, searchEmojis, toast, useConversationActions, useConversationContext, useConversationDocuments, useConversationList, useConversationLocales, useConversationMessages, useConversationRealtime, useConversations, useConversationsInbox, useDarkMode, useDebouncedValue, useGlobalRealtime, useInboxActions, useIsDarkTheme, useIsNarrow, useScrollToLatestMessage, useToast, useUrlArrayState, useUrlNumberState, useUrlStringState, useWaitingNotifications, waToHTML, waToHTMLInline, windowOf };
|