keithbaileys 1.0.6 → 1.0.8

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.
@@ -0,0 +1,1205 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const { proto } = require("../../WAProto");
4
+ const { generateMessageIDV2 } = require("./generics");
5
+ const { randomBytes, randomUUID } = require("crypto");
6
+ const JS_KEYWORDS = new Set([
7
+ "import",
8
+ "export",
9
+ "from",
10
+ "default",
11
+ "as",
12
+ "const",
13
+ "let",
14
+ "var",
15
+ "function",
16
+ "class",
17
+ "extends",
18
+ "new",
19
+ "return",
20
+ "if",
21
+ "else",
22
+ "for",
23
+ "while",
24
+ "do",
25
+ "switch",
26
+ "case",
27
+ "break",
28
+ "continue",
29
+ "try",
30
+ "catch",
31
+ "finally",
32
+ "throw",
33
+ "async",
34
+ "await",
35
+ "yield",
36
+ "typeof",
37
+ "instanceof",
38
+ "in",
39
+ "of",
40
+ "delete",
41
+ "void",
42
+ "true",
43
+ "false",
44
+ "null",
45
+ "undefined",
46
+ "NaN",
47
+ "Infinity",
48
+ "this",
49
+ "super",
50
+ "static",
51
+ "get",
52
+ "set",
53
+ "debugger",
54
+ "with",
55
+ ]);
56
+ const PYTHON_KEYWORDS = new Set([
57
+ "import",
58
+ "from",
59
+ "as",
60
+ "def",
61
+ "class",
62
+ "return",
63
+ "if",
64
+ "elif",
65
+ "else",
66
+ "for",
67
+ "while",
68
+ "break",
69
+ "continue",
70
+ "try",
71
+ "except",
72
+ "finally",
73
+ "raise",
74
+ "with",
75
+ "yield",
76
+ "lambda",
77
+ "pass",
78
+ "del",
79
+ "global",
80
+ "nonlocal",
81
+ "assert",
82
+ "True",
83
+ "False",
84
+ "None",
85
+ "and",
86
+ "or",
87
+ "not",
88
+ "in",
89
+ "is",
90
+ "async",
91
+ "await",
92
+ "self",
93
+ "print",
94
+ ]);
95
+ const GO_KEYWORDS = new Set([
96
+ "func",
97
+ "package",
98
+ "import",
99
+ "return",
100
+ "if",
101
+ "else",
102
+ "for",
103
+ "switch",
104
+ "case",
105
+ "break",
106
+ "continue",
107
+ "type",
108
+ "struct",
109
+ "interface",
110
+ "map",
111
+ "chan",
112
+ "go",
113
+ "defer",
114
+ "const",
115
+ "var",
116
+ "range",
117
+ "true",
118
+ "false",
119
+ "nil",
120
+ "select",
121
+ "default",
122
+ "fallthrough",
123
+ ]);
124
+ const LUA_KEYWORDS = new Set([
125
+ "function",
126
+ "end",
127
+ "if",
128
+ "then",
129
+ "else",
130
+ "elseif",
131
+ "for",
132
+ "while",
133
+ "do",
134
+ "local",
135
+ "return",
136
+ "true",
137
+ "false",
138
+ "nil",
139
+ "repeat",
140
+ "until",
141
+ "in",
142
+ "not",
143
+ "and",
144
+ "or",
145
+ ]);
146
+ const BASH_KEYWORDS = new Set([
147
+ "if",
148
+ "then",
149
+ "else",
150
+ "elif",
151
+ "fi",
152
+ "for",
153
+ "while",
154
+ "do",
155
+ "done",
156
+ "case",
157
+ "esac",
158
+ "echo",
159
+ "export",
160
+ "return",
161
+ "in",
162
+ "function",
163
+ "local",
164
+ "read",
165
+ "set",
166
+ "unset",
167
+ "true",
168
+ "false",
169
+ "exit",
170
+ "source",
171
+ "alias",
172
+ "declare",
173
+ "typeset",
174
+ ]);
175
+ const LANGUAGE_KEYWORDS = {
176
+ javascript: JS_KEYWORDS,
177
+ typescript: JS_KEYWORDS,
178
+ js: JS_KEYWORDS,
179
+ ts: JS_KEYWORDS,
180
+ python: PYTHON_KEYWORDS,
181
+ py: PYTHON_KEYWORDS,
182
+ go: GO_KEYWORDS,
183
+ golang: GO_KEYWORDS,
184
+ lua: LUA_KEYWORDS,
185
+ bash: BASH_KEYWORDS,
186
+ sh: BASH_KEYWORDS,
187
+ shell: BASH_KEYWORDS,
188
+ };
189
+ var CodeHighlightType;
190
+ (function (CodeHighlightType) {
191
+ CodeHighlightType[(CodeHighlightType["DEFAULT"] = 0)] = "DEFAULT";
192
+ CodeHighlightType[(CodeHighlightType["KEYWORD"] = 1)] = "KEYWORD";
193
+ CodeHighlightType[(CodeHighlightType["METHOD"] = 2)] = "METHOD";
194
+ CodeHighlightType[(CodeHighlightType["STRING"] = 3)] = "STRING";
195
+ CodeHighlightType[(CodeHighlightType["NUMBER"] = 4)] = "NUMBER";
196
+ CodeHighlightType[(CodeHighlightType["COMMENT"] = 5)] = "COMMENT";
197
+ })(CodeHighlightType || (CodeHighlightType = {}));
198
+ var RichSubMessageType;
199
+ (function (RichSubMessageType) {
200
+ RichSubMessageType[(RichSubMessageType["UNKNOWN"] = 0)] = "UNKNOWN";
201
+ RichSubMessageType[(RichSubMessageType["GRID_IMAGE"] = 1)] = "GRID_IMAGE";
202
+ RichSubMessageType[(RichSubMessageType["TEXT"] = 2)] = "TEXT";
203
+ RichSubMessageType[(RichSubMessageType["INLINE_IMAGE"] = 3)] = "INLINE_IMAGE";
204
+ RichSubMessageType[(RichSubMessageType["TABLE"] = 4)] = "TABLE";
205
+ RichSubMessageType[(RichSubMessageType["CODE"] = 5)] = "CODE";
206
+ RichSubMessageType[(RichSubMessageType["DYNAMIC"] = 6)] = "DYNAMIC";
207
+ RichSubMessageType[(RichSubMessageType["MAP"] = 7)] = "MAP";
208
+ RichSubMessageType[(RichSubMessageType["LATEX"] = 8)] = "LATEX";
209
+ RichSubMessageType[(RichSubMessageType["CONTENT_ITEMS"] = 9)] =
210
+ "CONTENT_ITEMS";
211
+ })(RichSubMessageType || (RichSubMessageType = {}));
212
+ const tokenizeCode = (codeStr, language = "javascript") => {
213
+ const keywords = LANGUAGE_KEYWORDS[language] || JS_KEYWORDS;
214
+ const blocks = [];
215
+ const lines = codeStr.split("\n");
216
+ for (let li = 0; li < lines.length; li++) {
217
+ const line = lines[li];
218
+ const isLast = li === lines.length - 1;
219
+ const nl = isLast ? "" : "\n";
220
+ if (!line.trim()) {
221
+ blocks.push({
222
+ highlightType: CodeHighlightType.DEFAULT,
223
+ codeContent: line + nl,
224
+ });
225
+ continue;
226
+ }
227
+ if (line.trim().startsWith("//") || line.trim().startsWith("#")) {
228
+ blocks.push({
229
+ highlightType: CodeHighlightType.COMMENT,
230
+ codeContent: line + nl,
231
+ });
232
+ continue;
233
+ }
234
+ const regex =
235
+ /(\/\/.*$|#.*$)|(["'`](?:[^"'`\\]|\\.)*["'`])|(\b\d+(?:\.\d+)?\b)|(\b[a-zA-Z_$][\w$]*\b)|([^\s\w$"'`]+)|(\s+)/g;
236
+ let match;
237
+ const tokens = [];
238
+ while ((match = regex.exec(line)) !== null) {
239
+ const val = match[0];
240
+ if (match[1]) {
241
+ tokens.push({
242
+ highlightType: CodeHighlightType.COMMENT,
243
+ codeContent: val,
244
+ });
245
+ } else if (match[2]) {
246
+ tokens.push({
247
+ highlightType: CodeHighlightType.STRING,
248
+ codeContent: val,
249
+ });
250
+ } else if (match[3]) {
251
+ tokens.push({
252
+ highlightType: CodeHighlightType.NUMBER,
253
+ codeContent: val,
254
+ });
255
+ } else if (match[4]) {
256
+ if (keywords.has(val)) {
257
+ tokens.push({
258
+ highlightType: CodeHighlightType.KEYWORD,
259
+ codeContent: val,
260
+ });
261
+ } else {
262
+ const after = line.slice(regex.lastIndex).trimStart();
263
+ if (after.startsWith("(")) {
264
+ tokens.push({
265
+ highlightType: CodeHighlightType.METHOD,
266
+ codeContent: val,
267
+ });
268
+ } else {
269
+ tokens.push({
270
+ highlightType: CodeHighlightType.DEFAULT,
271
+ codeContent: val,
272
+ });
273
+ }
274
+ }
275
+ } else {
276
+ tokens.push({
277
+ highlightType: CodeHighlightType.DEFAULT,
278
+ codeContent: val,
279
+ });
280
+ }
281
+ }
282
+ if (tokens.length === 0) {
283
+ blocks.push({
284
+ highlightType: CodeHighlightType.DEFAULT,
285
+ codeContent: line + nl,
286
+ });
287
+ continue;
288
+ }
289
+ const merged = [];
290
+ for (const t of tokens) {
291
+ const prev = merged.length > 0 ? merged[merged.length - 1] : undefined;
292
+ if (prev && prev.highlightType === t.highlightType) {
293
+ prev.codeContent += t.codeContent;
294
+ } else {
295
+ merged.push({ ...t });
296
+ }
297
+ }
298
+ if (merged.length > 0) {
299
+ merged[merged.length - 1].codeContent += nl;
300
+ }
301
+ blocks.push(...merged);
302
+ }
303
+ return blocks;
304
+ };
305
+ const buildRichContextInfo = (quoted) => {
306
+ const ctxInfo = {
307
+ forwardingScore: 1,
308
+ isForwarded: true,
309
+ forwardedAiBotMessageInfo: { botJid: "867051314767696@bot" },
310
+ forwardOrigin: 4,
311
+ };
312
+ if (quoted?.key) {
313
+ ctxInfo.stanzaId = quoted.key.id;
314
+ ctxInfo.participant =
315
+ quoted.key.participant || quoted.sender || quoted.key.remoteJid;
316
+ ctxInfo.quotedMessage = quoted.message;
317
+ }
318
+ return ctxInfo;
319
+ };
320
+ const buildBotForwardedMessage = (
321
+ submessages,
322
+ contextInfo,
323
+ unifiedResponse,
324
+ ) => {
325
+ const richResponse = {
326
+ messageType: 1,
327
+ submessages,
328
+ contextInfo,
329
+ };
330
+ if (unifiedResponse) {
331
+ richResponse.unifiedResponse = unifiedResponse;
332
+ }
333
+ return {
334
+ botForwardedMessage: {
335
+ message: {
336
+ richResponseMessage: richResponse,
337
+ },
338
+ },
339
+ };
340
+ };
341
+ const generateTableContent = (
342
+ title,
343
+ headers,
344
+ rows,
345
+ quoted,
346
+ options = {},
347
+ ) => {
348
+ const { footer, headerText } = options;
349
+ const tableRows = [
350
+ { items: headers, isHeading: true },
351
+ ...rows.map((row) => ({ items: row.map(String) })),
352
+ ];
353
+ const submessages = [];
354
+ if (headerText) {
355
+ submessages.push({ messageType: 2, messageText: headerText });
356
+ }
357
+ submessages.push({
358
+ messageType: 4,
359
+ tableMetadata: { title, rows: tableRows },
360
+ });
361
+ if (footer) {
362
+ submessages.push({ messageType: 2, messageText: footer });
363
+ }
364
+ const ctxInfo = buildRichContextInfo(quoted);
365
+ return {
366
+ message: buildBotForwardedMessage(submessages, ctxInfo),
367
+ messageId: generateMessageIDV2(),
368
+ };
369
+ };
370
+ const generateListContent = (title, items, quoted, options = {}) => {
371
+ const { footer, headerText } = options;
372
+ const tableRows = items.map((item) => ({
373
+ items: Array.isArray(item) ? item.map(String) : [String(item)],
374
+ }));
375
+ const submessages = [];
376
+ if (headerText) {
377
+ submessages.push({ messageType: 2, messageText: headerText });
378
+ }
379
+ submessages.push({
380
+ messageType: 4,
381
+ tableMetadata: { title, rows: tableRows },
382
+ });
383
+ if (footer) {
384
+ submessages.push({ messageType: 2, messageText: footer });
385
+ }
386
+ const ctxInfo = buildRichContextInfo(quoted);
387
+ return {
388
+ message: buildBotForwardedMessage(submessages, ctxInfo),
389
+ messageId: generateMessageIDV2(),
390
+ };
391
+ };
392
+ const generateCodeBlockContent = (code, quoted, options = {}) => {
393
+ const { title, footer, language = "javascript" } = options;
394
+ const submessages = [];
395
+ if (title) {
396
+ submessages.push({ messageType: 2, messageText: title });
397
+ }
398
+ submessages.push({
399
+ messageType: 5,
400
+ codeMetadata: {
401
+ codeLanguage: language,
402
+ codeBlocks: tokenizeCode(code, language),
403
+ },
404
+ });
405
+ if (footer) {
406
+ submessages.push({ messageType: 2, messageText: footer });
407
+ }
408
+ const ctxInfo = buildRichContextInfo(quoted);
409
+ return {
410
+ message: buildBotForwardedMessage(submessages, ctxInfo),
411
+ messageId: generateMessageIDV2(),
412
+ };
413
+ };
414
+ const generateLatexContent = (quoted, options) => {
415
+ const { text, expressions, headerText, footer } = options;
416
+ const submessages = [];
417
+ if (headerText) {
418
+ submessages.push({ messageType: 2, messageText: headerText });
419
+ }
420
+ const latexExpressions = expressions.map((expr) => {
421
+ const entry = {
422
+ latexExpression: expr.latexExpression,
423
+ url: expr.url,
424
+ width: expr.width,
425
+ height: expr.height,
426
+ };
427
+ if (expr.fontHeight !== undefined) entry.fontHeight = expr.fontHeight;
428
+ if (expr.imageTopPadding !== undefined)
429
+ entry.imageTopPadding = expr.imageTopPadding;
430
+ if (expr.imageLeadingPadding !== undefined)
431
+ entry.imageLeadingPadding = expr.imageLeadingPadding;
432
+ if (expr.imageBottomPadding !== undefined)
433
+ entry.imageBottomPadding = expr.imageBottomPadding;
434
+ if (expr.imageTrailingPadding !== undefined)
435
+ entry.imageTrailingPadding = expr.imageTrailingPadding;
436
+ return entry;
437
+ });
438
+ submessages.push({
439
+ messageType: 8,
440
+ latexMetadata: {
441
+ text: text || "",
442
+ expressions: latexExpressions,
443
+ },
444
+ });
445
+ if (footer) {
446
+ submessages.push({ messageType: 2, messageText: footer });
447
+ }
448
+ const ctxInfo = buildRichContextInfo(quoted);
449
+ return {
450
+ message: buildBotForwardedMessage(submessages, ctxInfo),
451
+ messageId: generateMessageIDV2(),
452
+ };
453
+ };
454
+ const generateLatexImageContent = async (
455
+ quoted,
456
+ options,
457
+ uploadFn,
458
+ renderLatexToPng,
459
+ ) => {
460
+ const { text, expressions, headerText, footer } = options;
461
+ const submessages = [];
462
+ if (headerText) {
463
+ submessages.push({ messageType: 2, messageText: headerText });
464
+ }
465
+ const latexExpressions = await Promise.all(
466
+ expressions.map(async (expr) => {
467
+ const { buffer, width, height } = await renderLatexToPng(
468
+ expr.latexExpression,
469
+ );
470
+ const uploadResult = await uploadFn(buffer, "image");
471
+ const imageUrl = uploadResult.url || uploadResult.directPath;
472
+ return {
473
+ latexExpression: expr.latexExpression,
474
+ url: imageUrl,
475
+ width,
476
+ height,
477
+ };
478
+ }),
479
+ );
480
+ submessages.push({
481
+ messageType: 8,
482
+ latexMetadata: {
483
+ text: text || "",
484
+ expressions: latexExpressions,
485
+ },
486
+ });
487
+ if (footer) {
488
+ submessages.push({ messageType: 2, messageText: footer });
489
+ }
490
+ const ctxInfo = buildRichContextInfo(quoted);
491
+ return {
492
+ message: buildBotForwardedMessage(submessages, ctxInfo),
493
+ messageId: generateMessageIDV2(),
494
+ };
495
+ };
496
+ const generateLatexInlineImageContent = async (
497
+ quoted,
498
+ options,
499
+ uploadFn,
500
+ renderLatexToPng,
501
+ ) => {
502
+ const { text, expressions, headerText, footer } = options;
503
+ const submessages = [];
504
+ if (headerText) {
505
+ submessages.push({ messageType: 2, messageText: headerText });
506
+ }
507
+ if (text) {
508
+ submessages.push({ messageType: 2, messageText: text });
509
+ }
510
+ for (const expr of expressions) {
511
+ const { buffer, width, height } = await renderLatexToPng(
512
+ expr.latexExpression,
513
+ );
514
+ const uploadResult = await uploadFn(buffer, "image");
515
+ const imageUrl = uploadResult.url || uploadResult.directPath;
516
+ submessages.push({
517
+ messageType: 3,
518
+ imageMetadata: {
519
+ imageUrl: {
520
+ imagePreviewUrl: imageUrl,
521
+ imageHighResUrl: imageUrl,
522
+ },
523
+ imageText: expr.latexExpression,
524
+ alignment: 2,
525
+ },
526
+ });
527
+ }
528
+ if (footer) {
529
+ submessages.push({ messageType: 2, messageText: footer });
530
+ }
531
+ const ctxInfo = buildRichContextInfo(quoted);
532
+ return {
533
+ message: buildBotForwardedMessage(submessages, ctxInfo),
534
+ messageId: generateMessageIDV2(),
535
+ };
536
+ };
537
+ const captureUnifiedResponse = (msg) => {
538
+ const botFwd = msg?.botForwardedMessage?.message;
539
+ if (!botFwd) return null;
540
+ const rich = botFwd.richResponseMessage;
541
+ if (!rich?.unifiedResponse?.data) return null;
542
+ return {
543
+ unifiedResponse: { data: rich.unifiedResponse.data },
544
+ submessages: rich.submessages || [],
545
+ contextInfo: rich.contextInfo || {},
546
+ };
547
+ };
548
+ const generateUnifiedResponseContent = (quoted, captured) => {
549
+ const ctxInfo = buildRichContextInfo(quoted);
550
+ return {
551
+ message: buildBotForwardedMessage(
552
+ captured.submessages,
553
+ ctxInfo,
554
+ captured.unifiedResponse,
555
+ ),
556
+ messageId: generateMessageIDV2(),
557
+ };
558
+ };
559
+ const generateRichMessageContent = (submessages, quoted) => {
560
+ const ctxInfo = buildRichContextInfo(quoted);
561
+ return {
562
+ message: buildBotForwardedMessage(submessages, ctxInfo),
563
+ messageId: generateMessageIDV2(),
564
+ };
565
+ };
566
+ const HIGHLIGHT_TYPE_MAP = {
567
+ 0: "DEFAULT",
568
+ 1: "KEYWORD",
569
+ 2: "METHOD",
570
+ 3: "STR",
571
+ 4: "NUMBER",
572
+ 5: "COMMENT",
573
+ };
574
+ const tokenizeCodeV2 = (code, language = "javascript") => {
575
+ const keywords = LANGUAGE_KEYWORDS[language] || JS_KEYWORDS;
576
+ const tokens = [];
577
+ let i = 0;
578
+ const n = code.length;
579
+ const push = (codeContent, highlightType) => {
580
+ if (!codeContent) return;
581
+ const last = tokens[tokens.length - 1];
582
+ if (last && last.highlightType === highlightType) {
583
+ last.codeContent += codeContent;
584
+ } else {
585
+ tokens.push({ codeContent, highlightType });
586
+ }
587
+ };
588
+ const isWordStart = (c) => /[a-zA-Z_$]/.test(c);
589
+ const isWord = (c) => /[a-zA-Z0-9_$]/.test(c);
590
+ const isNum = (c) => /[0-9]/.test(c);
591
+ while (i < n) {
592
+ const c = code[i];
593
+ if (c === "\n" || c === "\t" || c === " " || /\s/.test(c)) {
594
+ let s = i;
595
+ while (i < n && /\s/.test(code[i])) i++;
596
+ push(code.slice(s, i), 0);
597
+ continue;
598
+ }
599
+ if (c === "/" && code[i + 1] === "/") {
600
+ let s = i;
601
+ i += 2;
602
+ while (i < n && code[i] !== "\n") i++;
603
+ push(code.slice(s, i), 5);
604
+ continue;
605
+ }
606
+ if (c === "/" && code[i + 1] === "*") {
607
+ let s = i;
608
+ i += 2;
609
+ while (i < n - 1 && !(code[i] === "*" && code[i + 1] === "/")) i++;
610
+ i += 2;
611
+ push(code.slice(s, i), 5);
612
+ continue;
613
+ }
614
+ if (
615
+ c === "#" &&
616
+ (language === "python" ||
617
+ language === "py" ||
618
+ language === "bash" ||
619
+ language === "sh" ||
620
+ language === "shell" ||
621
+ language === "lua")
622
+ ) {
623
+ let s = i;
624
+ i++;
625
+ while (i < n && code[i] !== "\n") i++;
626
+ push(code.slice(s, i), 5);
627
+ continue;
628
+ }
629
+ if (c === '"' || c === "'" || c === "`") {
630
+ let s = i;
631
+ const q = c;
632
+ i++;
633
+ while (i < n) {
634
+ if (code[i] === "\\" && i + 1 < n) {
635
+ i += 2;
636
+ } else if (code[i] === q) {
637
+ i++;
638
+ break;
639
+ } else i++;
640
+ }
641
+ push(code.slice(s, i), 3);
642
+ continue;
643
+ }
644
+ if (isNum(c)) {
645
+ let s = i;
646
+ while (i < n && /[0-9.xXa-fA-FeEbBoO_]/.test(code[i])) i++;
647
+ push(code.slice(s, i), 4);
648
+ continue;
649
+ }
650
+ if (isWordStart(c)) {
651
+ let s = i;
652
+ while (i < n && isWord(code[i])) i++;
653
+ const word = code.slice(s, i);
654
+ let type = 0;
655
+ if (keywords.has(word)) {
656
+ type = 1;
657
+ } else {
658
+ let j = i;
659
+ while (j < n && /\s/.test(code[j])) j++;
660
+ if (code[j] === "(") type = 2;
661
+ }
662
+ push(word, type);
663
+ continue;
664
+ }
665
+ push(c, 0);
666
+ i++;
667
+ }
668
+ return {
669
+ codeBlock: tokens,
670
+ unified_codeBlock: tokens.map((t) => ({
671
+ content: t.codeContent,
672
+ type: HIGHLIGHT_TYPE_MAP[t.highlightType] || "DEFAULT",
673
+ })),
674
+ };
675
+ };
676
+ const toTableMetadataV2 = (input) => {
677
+ if (input === undefined || input === null) {
678
+ throw new Error(
679
+ "Table input is missing — pass either { headers: string[], rows: string[][] }, " +
680
+ "a 2D array [[headers...], [row1...], ...], or [title, \"h1|h2\", \"r1c1|r1c2;;r2c1|r2c2\"]",
681
+ );
682
+ }
683
+
684
+ let title = "";
685
+ let header = [];
686
+ let parsedRows = [];
687
+
688
+ if (!Array.isArray(input) && typeof input === "object") {
689
+ // Documented shape: { title?, headers, rows }
690
+ if (!Array.isArray(input.headers) || input.headers.length === 0) {
691
+ throw new Error("Table input must include a non-empty \"headers\" array");
692
+ }
693
+ title = input.title || "";
694
+ header = input.headers.map(String);
695
+ parsedRows = Array.isArray(input.rows)
696
+ ? input.rows.map((row) => (Array.isArray(row) ? row.map(String) : [String(row)]))
697
+ : [];
698
+ } else if (
699
+ Array.isArray(input) &&
700
+ input.length > 0 &&
701
+ Array.isArray(input[0])
702
+ ) {
703
+ // 2D array shape: [[headers...], [row1...], [row2...]]
704
+ const [headerRow, ...rows] = input;
705
+ header = headerRow.map(String);
706
+ parsedRows = rows.map((row) => (Array.isArray(row) ? row.map(String) : [String(row)]));
707
+ } else if (Array.isArray(input) && input.length > 0) {
708
+ // Legacy flat shape: [title, "h1|h2", "r1c1|r1c2;;r2c1|r2c2", ...]
709
+ const [t, headerStr, ...rest] = input;
710
+ const splitCols = (str) => {
711
+ if (typeof str !== "string") return [];
712
+ return str.includes("|")
713
+ ? str.split("|").map((s) => s.trim())
714
+ : str.split(",").map((s) => s.trim());
715
+ };
716
+ const splitRows = (str) => {
717
+ if (typeof str !== "string") return [];
718
+ return str.split(";;").map((row) => splitCols(row));
719
+ };
720
+ title = t;
721
+ header = splitCols(headerStr);
722
+ parsedRows = rest.flatMap(splitRows);
723
+ } else {
724
+ throw new Error("Input must be a non-empty array or a { headers, rows } object");
725
+ }
726
+ const maxLen = Math.max(header.length, ...parsedRows.map((r) => r.length));
727
+ const unified_rows = [
728
+ {
729
+ is_header: true,
730
+ cells: [...header, ...Array(maxLen - header.length).fill("")],
731
+ },
732
+ ...parsedRows.map((cells) => ({
733
+ is_header: false,
734
+ cells: [...cells, ...Array(maxLen - cells.length).fill("")],
735
+ })),
736
+ ];
737
+ const rows = unified_rows.map((r) => ({
738
+ items: r.cells,
739
+ ...(r.is_header ? { isHeading: true } : {}),
740
+ }));
741
+ return { title, rows, unified_rows };
742
+ };
743
+ const generateTableContentV2 = (table, quoted, options = {}) => {
744
+ const { title, footer, headerText, text } = options;
745
+ const { unified_rows } = toTableMetadataV2(table);
746
+ const sections = [];
747
+ if (headerText || title) {
748
+ const headingText = headerText || title;
749
+ sections.push({
750
+ view_model: {
751
+ primitive: {
752
+ text: headingText,
753
+ __typename: "GenAIMarkdownTextUXPrimitive",
754
+ },
755
+ __typename: "GenAISingleLayoutViewModel",
756
+ },
757
+ });
758
+ }
759
+ if (text) {
760
+ sections.push({
761
+ view_model: {
762
+ primitive: {
763
+ text,
764
+ __typename: "GenAIMarkdownTextUXPrimitive",
765
+ },
766
+ __typename: "GenAISingleLayoutViewModel",
767
+ },
768
+ });
769
+ }
770
+ sections.push({
771
+ view_model: {
772
+ primitive: {
773
+ rows: unified_rows,
774
+ __typename: "GenATableUXPrimitive",
775
+ },
776
+ __typename: "GenAISingleLayoutViewModel",
777
+ },
778
+ });
779
+ if (footer) {
780
+ sections.push({
781
+ view_model: {
782
+ primitive: {
783
+ text: footer,
784
+ __typename: "GenAIMarkdownTextUXPrimitive",
785
+ },
786
+ __typename: "GenAISingleLayoutViewModel",
787
+ },
788
+ });
789
+ }
790
+ const responseId = randomUUID();
791
+ const unifiedData = {
792
+ response_id: responseId,
793
+ sections,
794
+ };
795
+ const base64Data = Buffer.from(JSON.stringify(unifiedData)).toString(
796
+ "base64",
797
+ );
798
+ const ctxInfo = {
799
+ forwardingScore: 2,
800
+ isForwarded: true,
801
+ forwardedAiBotMessageInfo: { botJid: "259786046210223@bot" },
802
+ forwardOrigin: 4,
803
+ botMessageSharingInfo: {
804
+ botEntryPointOrigin: 1,
805
+ forwardScore: 2,
806
+ },
807
+ };
808
+ if (quoted?.key) {
809
+ ctxInfo.stanzaId = quoted.key.id;
810
+ ctxInfo.participant =
811
+ quoted.key.participant || quoted.sender || quoted.key.remoteJid;
812
+ ctxInfo.quotedMessage = quoted.message;
813
+ }
814
+ const content = {
815
+ messageContextInfo: {
816
+ threadId: [],
817
+ deviceListMetadata: {
818
+ senderKeyIndexes: [],
819
+ recipientKeyIndexes: [],
820
+ recipientKeyHash: "",
821
+ recipientTimestamp: Math.floor(Date.now() / 1000),
822
+ },
823
+ deviceListMetadataVersion: 2,
824
+ messageSecret: randomBytes(32),
825
+ },
826
+ botForwardedMessage: {
827
+ message: {
828
+ richResponseMessage: {
829
+ submessages: [],
830
+ messageType: 1,
831
+ unifiedResponse: { data: base64Data },
832
+ contextInfo: ctxInfo,
833
+ },
834
+ },
835
+ },
836
+ };
837
+ return {
838
+ message: content,
839
+ messageId: generateMessageIDV2(),
840
+ };
841
+ };
842
+ const generateCodeBlockContentV2 = (code, quoted, options = {}) => {
843
+ const { title, footer, language = "javascript", text } = options;
844
+ const { unified_codeBlock } = tokenizeCodeV2(code, language);
845
+ const sections = [];
846
+ if (text) {
847
+ sections.push({
848
+ view_model: {
849
+ primitive: {
850
+ text,
851
+ __typename: "GenAIMarkdownTextUXPrimitive",
852
+ },
853
+ __typename: "GenAISingleLayoutViewModel",
854
+ },
855
+ });
856
+ }
857
+ sections.push({
858
+ view_model: {
859
+ primitive: {
860
+ language,
861
+ code_blocks: unified_codeBlock,
862
+ __typename: "GenAICodeUXPrimitive",
863
+ },
864
+ __typename: "GenAISingleLayoutViewModel",
865
+ },
866
+ });
867
+ if (footer) {
868
+ sections.push({
869
+ view_model: {
870
+ primitive: {
871
+ text: footer,
872
+ __typename: "GenAIMarkdownTextUXPrimitive",
873
+ },
874
+ __typename: "GenAISingleLayoutViewModel",
875
+ },
876
+ });
877
+ }
878
+ const responseId = randomUUID();
879
+ const unifiedData = {
880
+ response_id: responseId,
881
+ sections,
882
+ };
883
+ const base64Data = Buffer.from(JSON.stringify(unifiedData)).toString(
884
+ "base64",
885
+ );
886
+ const ctxInfo = {
887
+ mentionedJid: [],
888
+ groupMentions: [],
889
+ statusAttributions: [],
890
+ forwardingScore: 2,
891
+ isForwarded: true,
892
+ forwardedAiBotMessageInfo: { botJid: "259786046210223@bot" },
893
+ forwardOrigin: 4,
894
+ botMessageSharingInfo: {
895
+ botEntryPointOrigin: 1,
896
+ forwardScore: 2,
897
+ },
898
+ };
899
+ if (quoted?.key) {
900
+ ctxInfo.stanzaId = quoted.key.id;
901
+ ctxInfo.participant =
902
+ quoted.key.participant || quoted.sender || quoted.key.remoteJid;
903
+ ctxInfo.quotedMessage = quoted.message;
904
+ }
905
+ const content = {
906
+ messageContextInfo: {
907
+ threadId: [],
908
+ deviceListMetadata: {
909
+ senderKeyIndexes: [],
910
+ recipientKeyIndexes: [],
911
+ recipientKeyHash: "",
912
+ recipientTimestamp: Math.floor(Date.now() / 1000),
913
+ },
914
+ deviceListMetadataVersion: 2,
915
+ messageSecret: randomBytes(32),
916
+ },
917
+ botForwardedMessage: {
918
+ message: {
919
+ richResponseMessage: {
920
+ submessages: [],
921
+ messageType: 1,
922
+ unifiedResponse: { data: base64Data },
923
+ contextInfo: ctxInfo,
924
+ },
925
+ },
926
+ },
927
+ };
928
+ return {
929
+ message: content,
930
+ messageId: generateMessageIDV2(),
931
+ };
932
+ };
933
+ const generateLinkContent = (text, links, quoted, options = {}) => {
934
+ const {
935
+ footer,
936
+ botJid = "867051314767696@bot",
937
+ forwardingScore = 3,
938
+ citations = [],
939
+ proofs = [],
940
+ } = options;
941
+ const submessages = [];
942
+ const fullText = footer ? `${text}${footer}` : text;
943
+ submessages.push({ messageType: 2, messageText: fullText });
944
+ const sections = [];
945
+ const inlineEntities = links.map((link, i) => {
946
+ const url = typeof link === "string" ? link : link.url;
947
+ const displayName =
948
+ typeof link === "object" && link.displayName
949
+ ? link.displayName
950
+ : citations[i]?.sourceTitle || `Link ${i + 1}`;
951
+ return {
952
+ key: `IE_${i}`,
953
+ metadata: {
954
+ display_name: displayName,
955
+ is_trusted: false,
956
+ url,
957
+ __typename: "GenAIInlineLinkItem",
958
+ },
959
+ };
960
+ });
961
+ sections.push({
962
+ view_model: {
963
+ primitive: {
964
+ text,
965
+ inline_entities: inlineEntities,
966
+ __typename: "GenAIMarkdownTextUXPrimitive",
967
+ },
968
+ __typename: "GenAISingleLayoutViewModel",
969
+ },
970
+ });
971
+ if (footer) {
972
+ sections.push({
973
+ view_model: {
974
+ primitive: {
975
+ text: footer,
976
+ __typename: "GenAIMarkdownTextUXPrimitive",
977
+ },
978
+ __typename: "GenAISingleLayoutViewModel",
979
+ },
980
+ });
981
+ }
982
+ const responseId = randomUUID();
983
+ const unifiedData = {
984
+ response_id: responseId,
985
+ sections,
986
+ };
987
+ const base64Data = Buffer.from(JSON.stringify(unifiedData)).toString(
988
+ "base64",
989
+ );
990
+ const ctxInfo = {
991
+ forwardingScore,
992
+ isForwarded: true,
993
+ forwardedAiBotMessageInfo: { botJid },
994
+ forwardOrigin: 4,
995
+ botMessageSharingInfo: {
996
+ forwardScore: forwardingScore,
997
+ },
998
+ };
999
+ if (quoted?.key) {
1000
+ ctxInfo.stanzaId = quoted.key.id;
1001
+ ctxInfo.participant =
1002
+ quoted.key.participant || quoted.sender || quoted.key.remoteJid;
1003
+ ctxInfo.quotedMessage = quoted.message;
1004
+ }
1005
+ const messageContextInfo = {
1006
+ messageSecret: randomBytes(32),
1007
+ };
1008
+ if (citations.length > 0 || proofs.length > 0) {
1009
+ const botMetadata = {};
1010
+ if (citations.length > 0) {
1011
+ botMetadata.richResponseSourcesMetadata = {
1012
+ sources: citations.map((c, i) => ({
1013
+ provider: 1,
1014
+ thumbnailCdnUrl: "",
1015
+ sourceProviderUrl:
1016
+ typeof links[i] === "string" ? links[i] : links[i]?.url || "",
1017
+ sourceQuery: c.sourceQuery || "",
1018
+ faviconCdnUrl: c.faviconCdnUrl || "",
1019
+ citationNumber: c.citationNumber ?? i + 1,
1020
+ sourceTitle: c.sourceTitle || "",
1021
+ })),
1022
+ };
1023
+ }
1024
+ if (proofs.length > 0) {
1025
+ botMetadata.verificationMetadata = {
1026
+ proofs: proofs.map((p) => ({
1027
+ version: p.version || 1,
1028
+ useCase: p.useCase || 1,
1029
+ signature: p.signature || "",
1030
+ certificateChain: p.certificateChain || [],
1031
+ })),
1032
+ };
1033
+ }
1034
+ messageContextInfo.botMetadata = botMetadata;
1035
+ }
1036
+ const content = {
1037
+ messageContextInfo,
1038
+ botForwardedMessage: {
1039
+ message: {
1040
+ richResponseMessage: {
1041
+ messageType: 1,
1042
+ submessages,
1043
+ unifiedResponse: { data: base64Data },
1044
+ contextInfo: ctxInfo,
1045
+ },
1046
+ },
1047
+ },
1048
+ };
1049
+ return {
1050
+ message: content,
1051
+ messageId: generateMessageIDV2(),
1052
+ };
1053
+ };
1054
+ const generateLinkContentV2 = (text, links, quoted, options = {}) => {
1055
+ const { footer, searchEngine = "MAME" } = options;
1056
+ const submessages = [];
1057
+ const fullText = footer ? `${text}${footer}` : text;
1058
+ submessages.push({ messageType: 2, messageText: fullText });
1059
+ const sections = [];
1060
+ const inlineEntities = links.map((link, i) => {
1061
+ const url = typeof link === "string" ? link : link.url;
1062
+ const displayName =
1063
+ typeof link === "object" && link.displayName
1064
+ ? link.displayName
1065
+ : `Link ${i + 1}`;
1066
+ const sourceDisplayName =
1067
+ typeof link === "object" && link.sourceDisplayName
1068
+ ? link.sourceDisplayName
1069
+ : `Source ${i + 1}`;
1070
+ const sourceSubtitle =
1071
+ typeof link === "object" && link.sourceSubtitle
1072
+ ? link.sourceSubtitle
1073
+ : "";
1074
+ return {
1075
+ key: `IE_${i}`,
1076
+ metadata: {
1077
+ reference_id: i + 1,
1078
+ reference_url: url,
1079
+ reference_title: displayName,
1080
+ reference_display_name: displayName,
1081
+ sources: [
1082
+ {
1083
+ source_type: "THIRD_PARTY",
1084
+ source_display_name: sourceDisplayName,
1085
+ source_subtitle: sourceSubtitle,
1086
+ source_url: url,
1087
+ },
1088
+ ],
1089
+ __typename: "GenAISearchCitationItem",
1090
+ },
1091
+ };
1092
+ });
1093
+ sections.push({
1094
+ view_model: {
1095
+ primitive: {
1096
+ text,
1097
+ inline_entities: inlineEntities,
1098
+ __typename: "GenAIMarkdownTextUXPrimitive",
1099
+ },
1100
+ __typename: "GenAISingleLayoutViewModel",
1101
+ },
1102
+ });
1103
+ const searchSources = links.map((link, i) => {
1104
+ const url = typeof link === "string" ? link : link.url;
1105
+ const sourceDisplayName =
1106
+ typeof link === "object" && link.sourceDisplayName
1107
+ ? link.sourceDisplayName
1108
+ : `Source ${i + 1}`;
1109
+ const sourceSubtitle =
1110
+ typeof link === "object" && link.sourceSubtitle
1111
+ ? link.sourceSubtitle
1112
+ : "";
1113
+ return {
1114
+ source_type: "THIRD_PARTY",
1115
+ source_display_name: sourceDisplayName,
1116
+ source_subtitle: sourceSubtitle,
1117
+ source_url: url,
1118
+ };
1119
+ });
1120
+ sections.push({
1121
+ view_model: {
1122
+ primitive: {
1123
+ sources: searchSources,
1124
+ search_engine: searchEngine,
1125
+ __typename: "GenAISearchResultPrimitive",
1126
+ },
1127
+ __typename: "GenAISingleLayoutViewModel",
1128
+ },
1129
+ });
1130
+ if (footer) {
1131
+ sections.push({
1132
+ view_model: {
1133
+ primitive: {
1134
+ text: footer,
1135
+ __typename: "GenAIMarkdownTextUXPrimitive",
1136
+ },
1137
+ __typename: "GenAISingleLayoutViewModel",
1138
+ },
1139
+ });
1140
+ }
1141
+ const responseId = randomUUID();
1142
+ const unifiedData = {
1143
+ response_id: responseId,
1144
+ sections,
1145
+ };
1146
+ const base64Data = Buffer.from(JSON.stringify(unifiedData)).toString(
1147
+ "base64",
1148
+ );
1149
+ const ctxInfo = {
1150
+ isForwarded: true,
1151
+ forwardOrigin: 4,
1152
+ };
1153
+ if (quoted?.key) {
1154
+ ctxInfo.participant =
1155
+ quoted.key.participant || quoted.sender || quoted.key.remoteJid;
1156
+ ctxInfo.quotedMessage = quoted.message;
1157
+ }
1158
+ const content = {
1159
+ messageContextInfo: {
1160
+ threadId: [],
1161
+ messageSecret: randomBytes(32),
1162
+ },
1163
+ botForwardedMessage: {
1164
+ message: {
1165
+ richResponseMessage: {
1166
+ messageType: 1,
1167
+ submessages,
1168
+ unifiedResponse: { data: base64Data },
1169
+ contextInfo: ctxInfo,
1170
+ },
1171
+ },
1172
+ },
1173
+ };
1174
+ return {
1175
+ message: content,
1176
+ messageId: generateMessageIDV2(),
1177
+ };
1178
+ };
1179
+
1180
+ exports.JS_KEYWORDS = JS_KEYWORDS;
1181
+ exports.PYTHON_KEYWORDS = PYTHON_KEYWORDS;
1182
+ exports.GO_KEYWORDS = GO_KEYWORDS;
1183
+ exports.LUA_KEYWORDS = LUA_KEYWORDS;
1184
+ exports.BASH_KEYWORDS = BASH_KEYWORDS;
1185
+ exports.LANGUAGE_KEYWORDS = LANGUAGE_KEYWORDS;
1186
+ exports.CodeHighlightType = CodeHighlightType;
1187
+ exports.RichSubMessageType = RichSubMessageType;
1188
+ exports.tokenizeCode = tokenizeCode;
1189
+ exports.buildRichContextInfo = buildRichContextInfo;
1190
+ exports.buildBotForwardedMessage = buildBotForwardedMessage;
1191
+ exports.generateTableContent = generateTableContent;
1192
+ exports.generateListContent = generateListContent;
1193
+ exports.generateCodeBlockContent = generateCodeBlockContent;
1194
+ exports.generateLatexContent = generateLatexContent;
1195
+ exports.generateLatexImageContent = generateLatexImageContent;
1196
+ exports.generateLatexInlineImageContent = generateLatexInlineImageContent;
1197
+ exports.captureUnifiedResponse = captureUnifiedResponse;
1198
+ exports.generateUnifiedResponseContent = generateUnifiedResponseContent;
1199
+ exports.generateRichMessageContent = generateRichMessageContent;
1200
+ exports.tokenizeCodeV2 = tokenizeCodeV2;
1201
+ exports.toTableMetadataV2 = toTableMetadataV2;
1202
+ exports.generateTableContentV2 = generateTableContentV2;
1203
+ exports.generateCodeBlockContentV2 = generateCodeBlockContentV2;
1204
+ exports.generateLinkContent = generateLinkContent;
1205
+ exports.generateLinkContentV2 = generateLinkContentV2;