wa-multi-mongodb 3.8.1
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/LICENSE +21 -0
- package/dist/Defaults/index.d.ts +21 -0
- package/dist/Defaults/index.d.ts.map +1 -0
- package/dist/Defaults/index.js +31 -0
- package/dist/Error/index.d.ts +5 -0
- package/dist/Error/index.d.ts.map +1 -0
- package/dist/Error/index.js +14 -0
- package/dist/Messaging/index.d.ts +25 -0
- package/dist/Messaging/index.d.ts.map +1 -0
- package/dist/Messaging/index.js +335 -0
- package/dist/Profile/index.d.ts +9 -0
- package/dist/Profile/index.d.ts.map +1 -0
- package/dist/Profile/index.js +34 -0
- package/dist/Socket/index.d.ts +68 -0
- package/dist/Socket/index.d.ts.map +1 -0
- package/dist/Socket/index.js +527 -0
- package/dist/Types/index.d.ts +70 -0
- package/dist/Types/index.d.ts.map +1 -0
- package/dist/Types/index.js +2 -0
- package/dist/Types/profile.d.ts +5 -0
- package/dist/Types/profile.d.ts.map +1 -0
- package/dist/Types/profile.js +2 -0
- package/dist/Utils/create-delay.d.ts +17 -0
- package/dist/Utils/create-delay.d.ts.map +1 -0
- package/dist/Utils/create-delay.js +38 -0
- package/dist/Utils/error.d.ts +4 -0
- package/dist/Utils/error.d.ts.map +1 -0
- package/dist/Utils/error.js +8 -0
- package/dist/Utils/index.d.ts +4 -0
- package/dist/Utils/index.d.ts.map +1 -0
- package/dist/Utils/index.js +21 -0
- package/dist/Utils/is-exist.d.ts +6 -0
- package/dist/Utils/is-exist.d.ts.map +1 -0
- package/dist/Utils/is-exist.js +53 -0
- package/dist/Utils/message-status.d.ts +4 -0
- package/dist/Utils/message-status.d.ts.map +1 -0
- package/dist/Utils/message-status.js +18 -0
- package/dist/Utils/mongo-auth-state.d.ts +15 -0
- package/dist/Utils/mongo-auth-state.d.ts.map +1 -0
- package/dist/Utils/mongo-auth-state.js +109 -0
- package/dist/Utils/phone-to-jid.d.ts +5 -0
- package/dist/Utils/phone-to-jid.d.ts.map +1 -0
- package/dist/Utils/phone-to-jid.js +30 -0
- package/dist/Utils/save-media.d.ts +6 -0
- package/dist/Utils/save-media.d.ts.map +1 -0
- package/dist/Utils/save-media.js +55 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +46 -0
- package/package.json +37 -0
- package/readme.md +423 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Muhammad Imam Choirudin
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare abstract class CREDENTIALS {
|
|
2
|
+
static DIR_NAME: string;
|
|
3
|
+
static PREFIX: string;
|
|
4
|
+
static MONGO_DB_NAME: string;
|
|
5
|
+
static MONGO_COLLECTION_NAME: string;
|
|
6
|
+
}
|
|
7
|
+
export declare enum CALLBACK_KEY {
|
|
8
|
+
ON_MESSAGE_RECEIVED = "on-message-received",
|
|
9
|
+
ON_QR = "on-qr",
|
|
10
|
+
ON_CONNECTED = "on-connected",
|
|
11
|
+
ON_DISCONNECTED = "on-disconnected",
|
|
12
|
+
ON_CONNECTING = "on-connecting",
|
|
13
|
+
ON_MESSAGE_UPDATED = "on-message-updated",
|
|
14
|
+
ON_PAIRING_CODE = "on-pairing-code"
|
|
15
|
+
}
|
|
16
|
+
export declare abstract class Messages {
|
|
17
|
+
static sessionAlreadyExist: (sessionId: string) => string;
|
|
18
|
+
static sessionNotFound: (sessionId: string) => string;
|
|
19
|
+
static paremetersRequired: (props: string[] | string) => string;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Defaults/index.ts"],"names":[],"mappings":"AAAA,8BAAsB,WAAW;IAC/B,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAoB;IAC3C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAkB;IAGvC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAgB;IAC5C,MAAM,CAAC,qBAAqB,EAAE,MAAM,CAAU;CAC/C;AAED,oBAAY,YAAY;IACtB,mBAAmB,wBAAwB;IAC3C,KAAK,UAAU;IACf,YAAY,iBAAiB;IAC7B,eAAe,oBAAoB;IACnC,aAAa,kBAAkB;IAC/B,kBAAkB,uBAAuB;IACzC,eAAe,oBAAoB;CACpC;AAED,8BAAsB,QAAQ;IAC5B,MAAM,CAAC,mBAAmB,GAAI,WAAW,MAAM,KAAG,MAAM,CACe;IAEvE,MAAM,CAAC,eAAe,GAAI,WAAW,MAAM,KAAG,MAAM,CACP;IAE7C,MAAM,CAAC,kBAAkB,GAAI,OAAO,MAAM,EAAE,GAAG,MAAM,YAOpC;CAClB"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Messages = exports.CALLBACK_KEY = exports.CREDENTIALS = void 0;
|
|
4
|
+
class CREDENTIALS {
|
|
5
|
+
}
|
|
6
|
+
exports.CREDENTIALS = CREDENTIALS;
|
|
7
|
+
CREDENTIALS.DIR_NAME = "wa_credentials";
|
|
8
|
+
CREDENTIALS.PREFIX = "_credentials";
|
|
9
|
+
// Konfigurasi MongoDB
|
|
10
|
+
CREDENTIALS.MONGO_DB_NAME = "wa_session";
|
|
11
|
+
CREDENTIALS.MONGO_COLLECTION_NAME = "auth";
|
|
12
|
+
var CALLBACK_KEY;
|
|
13
|
+
(function (CALLBACK_KEY) {
|
|
14
|
+
CALLBACK_KEY["ON_MESSAGE_RECEIVED"] = "on-message-received";
|
|
15
|
+
CALLBACK_KEY["ON_QR"] = "on-qr";
|
|
16
|
+
CALLBACK_KEY["ON_CONNECTED"] = "on-connected";
|
|
17
|
+
CALLBACK_KEY["ON_DISCONNECTED"] = "on-disconnected";
|
|
18
|
+
CALLBACK_KEY["ON_CONNECTING"] = "on-connecting";
|
|
19
|
+
CALLBACK_KEY["ON_MESSAGE_UPDATED"] = "on-message-updated";
|
|
20
|
+
CALLBACK_KEY["ON_PAIRING_CODE"] = "on-pairing-code";
|
|
21
|
+
})(CALLBACK_KEY || (exports.CALLBACK_KEY = CALLBACK_KEY = {}));
|
|
22
|
+
class Messages {
|
|
23
|
+
}
|
|
24
|
+
exports.Messages = Messages;
|
|
25
|
+
Messages.sessionAlreadyExist = (sessionId) => `Session ID :${sessionId} is already exist, Try another Session ID.`;
|
|
26
|
+
Messages.sessionNotFound = (sessionId) => `Session with ID: ${sessionId} Not Exist!`;
|
|
27
|
+
Messages.paremetersRequired = (props) => `Parameter ${typeof props == "string"
|
|
28
|
+
? props
|
|
29
|
+
: props instanceof Array
|
|
30
|
+
? props.join(", ")
|
|
31
|
+
: ""} is required`;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Error/index.ts"],"names":[],"mappings":"AAAA,qBAAa,aAAc,SAAQ,KAAK;gBAC1B,OAAO,EAAE,MAAM;IAM3B,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,GAAG,GAAG,KAAK,IAAI,aAAa;CAG3D"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WhatsappError = void 0;
|
|
4
|
+
class WhatsappError extends Error {
|
|
5
|
+
constructor(message) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = "WhatsappError";
|
|
8
|
+
Object.setPrototypeOf(this, WhatsappError.prototype);
|
|
9
|
+
}
|
|
10
|
+
static isWhatsappError(error) {
|
|
11
|
+
return error instanceof WhatsappError || error instanceof Error;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.WhatsappError = WhatsappError;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { proto } from "baileys";
|
|
2
|
+
import { SendMediaTypes, SendMessageTypes, SendReadTypes, SendTypingTypes } from "../Types";
|
|
3
|
+
export declare const sendTextMessage: ({ sessionId, to, text, isGroup, ...props }: SendMessageTypes) => Promise<proto.WebMessageInfo | undefined>;
|
|
4
|
+
export declare const sendMedia: ({ sessionId, to, media, type, caption, fileName, isGroup, answering, }: SendMediaTypes) => Promise<proto.WebMessageInfo | undefined>;
|
|
5
|
+
export declare const sendVoiceNote: ({ sessionId, to, isGroup, media, ...props }: Omit<SendMediaTypes, "text">) => Promise<proto.WebMessageInfo | undefined>;
|
|
6
|
+
export declare const sendSticker: ({ sessionId, to, isGroup, media, ...props }: SendMediaTypes) => Promise<proto.WebMessageInfo | undefined>;
|
|
7
|
+
/**
|
|
8
|
+
* Give typing effect to target
|
|
9
|
+
*
|
|
10
|
+
* Looks like human typing
|
|
11
|
+
*
|
|
12
|
+
* @param sessionId - Session ID
|
|
13
|
+
* @param to - Target
|
|
14
|
+
* @param duration - Duration in miliseconds typing effect will appear
|
|
15
|
+
* @param isGroup - Whether the chat is a group
|
|
16
|
+
*/
|
|
17
|
+
export declare const sendTyping: ({ sessionId, to, duration, isGroup, }: SendTypingTypes) => Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Mark message as read
|
|
20
|
+
*
|
|
21
|
+
* @param sessionId - Session ID
|
|
22
|
+
* @param key - Message key to mark as read
|
|
23
|
+
*/
|
|
24
|
+
export declare const readMessage: ({ sessionId, key, }: SendReadTypes) => Promise<void>;
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Messaging/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAqB,MAAM,SAAS,CAAC;AAGnD,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,eAAe,EAChB,MAAM,UAAU,CAAC;AAOlB,eAAO,MAAM,eAAe,GAAU,4CAMnC,gBAAgB,KAAG,OAAO,CAAC,KAAK,CAAC,cAAc,GAAG,SAAS,CAoF7D,CAAC;AAaF,eAAO,MAAM,SAAS,GAAU,wEAS7B,cAAc,KAAG,OAAO,CAAC,KAAK,CAAC,cAAc,GAAG,SAAS,CAyI3D,CAAC;AAEF,eAAO,MAAM,aAAa,GAAU,6CAMjC,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,KAAG,OAAO,CAAC,KAAK,CAAC,cAAc,GAAG,SAAS,CAwBzE,CAAC;AAEF,eAAO,MAAM,WAAW,GAAU,6CAM/B,cAAc,KAAG,OAAO,CAAC,KAAK,CAAC,cAAc,GAAG,SAAS,CAuB3D,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,UAAU,GAAU,uCAK9B,eAAe,KAAG,OAAO,CAAC,IAAI,CAuDhC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAU,qBAG/B,aAAa,KAAG,OAAO,CAAC,IAAI,CA6B9B,CAAC"}
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
12
|
+
var t = {};
|
|
13
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
14
|
+
t[p] = s[p];
|
|
15
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
16
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
17
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
18
|
+
t[p[i]] = s[p[i]];
|
|
19
|
+
}
|
|
20
|
+
return t;
|
|
21
|
+
};
|
|
22
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
23
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.readMessage = exports.sendTyping = exports.sendSticker = exports.sendVoiceNote = exports.sendMedia = exports.sendTextMessage = void 0;
|
|
27
|
+
const Defaults_1 = require("../Defaults");
|
|
28
|
+
const Socket_1 = require("../Socket");
|
|
29
|
+
const Utils_1 = require("../Utils");
|
|
30
|
+
const create_delay_1 = require("../Utils/create-delay");
|
|
31
|
+
const is_exist_1 = require("../Utils/is-exist");
|
|
32
|
+
const mime_1 = __importDefault(require("mime"));
|
|
33
|
+
const Error_1 = require("../Error");
|
|
34
|
+
const sendTextMessage = (_a) => __awaiter(void 0, void 0, void 0, function* () {
|
|
35
|
+
var _b;
|
|
36
|
+
var { sessionId, to, text = "", isGroup = false } = _a, props = __rest(_a, ["sessionId", "to", "text", "isGroup"]);
|
|
37
|
+
const session = (0, Socket_1.getSession)(sessionId);
|
|
38
|
+
if (!session)
|
|
39
|
+
throw new Error_1.WhatsappError(Defaults_1.Messages.sessionNotFound(sessionId));
|
|
40
|
+
to = (0, Utils_1.phoneToJid)({ to, isGroup });
|
|
41
|
+
try {
|
|
42
|
+
// Gunakan flag force untuk mencoba memaksa pengiriman pesan bahkan jika koneksi tidak stabil
|
|
43
|
+
const messageOptions = {
|
|
44
|
+
quoted: props.answering,
|
|
45
|
+
};
|
|
46
|
+
// Deteksi apakah ini grup berdasarkan format JID
|
|
47
|
+
const isGroupChat = to.endsWith('@g.us');
|
|
48
|
+
// Gunakan waktu jeda untuk memastikan koneksi siap
|
|
49
|
+
yield (0, create_delay_1.createDelay)(500);
|
|
50
|
+
// Beri timeout yang lebih pendek untuk grup untuk mencegah hanging
|
|
51
|
+
const timeoutMs = isGroupChat ? 15000 : 30000;
|
|
52
|
+
// Gunakan withTimeout untuk membatasi waktu operasi
|
|
53
|
+
return yield (0, create_delay_1.withTimeout)(session.sendMessage(to, {
|
|
54
|
+
text: text,
|
|
55
|
+
}, messageOptions), timeoutMs, `Pengiriman pesan ke ${to} melebihi batas waktu ${timeoutMs / 1000} detik`);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
console.error(`Error saat mengirim pesan: ${(error === null || error === void 0 ? void 0 : error.message) || 'Unknown error'}`);
|
|
59
|
+
// Jika koneksi tertutup, coba reconnect
|
|
60
|
+
if ((_b = error === null || error === void 0 ? void 0 : error.message) === null || _b === void 0 ? void 0 : _b.includes('Connection Closed')) {
|
|
61
|
+
try {
|
|
62
|
+
yield (0, Socket_1.reconnect)(sessionId);
|
|
63
|
+
yield (0, create_delay_1.createDelay)(3000); // Beri waktu untuk reconnect sepenuhnya
|
|
64
|
+
// Coba kirim lagi setelah reconnect
|
|
65
|
+
return yield (0, create_delay_1.withTimeout)(session.sendMessage(to, {
|
|
66
|
+
text: text,
|
|
67
|
+
}, {
|
|
68
|
+
quoted: props.answering,
|
|
69
|
+
}), 30000, `Pengiriman pesan setelah reconnect melebihi batas waktu`);
|
|
70
|
+
}
|
|
71
|
+
catch (reconnectError) {
|
|
72
|
+
console.error(`Gagal reconnect: ${(reconnectError === null || reconnectError === void 0 ? void 0 : reconnectError.message) || 'Unknown error'}`);
|
|
73
|
+
throw new Error_1.WhatsappError(`Koneksi terputus dan gagal reconnect: ${(reconnectError === null || reconnectError === void 0 ? void 0 : reconnectError.message) || 'Unknown error'}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// Jika ada error timeout atau error lain, coba lagi sekali dengan delay lebih lama
|
|
77
|
+
try {
|
|
78
|
+
yield (0, create_delay_1.createDelay)(2000);
|
|
79
|
+
// Untuk percobaan kedua, gunakan timeout yang lebih lama
|
|
80
|
+
return yield (0, create_delay_1.withTimeout)(session.sendMessage(to, {
|
|
81
|
+
text: text,
|
|
82
|
+
}, {
|
|
83
|
+
quoted: props.answering,
|
|
84
|
+
}), 20000, `Percobaan kedua pengiriman pesan melebihi batas waktu`);
|
|
85
|
+
}
|
|
86
|
+
catch (retryError) {
|
|
87
|
+
console.error(`Gagal pada percobaan kedua: ${(retryError === null || retryError === void 0 ? void 0 : retryError.message) || 'Unknown error'}`);
|
|
88
|
+
throw new Error_1.WhatsappError(`Gagal mengirim pesan: ${(retryError === null || retryError === void 0 ? void 0 : retryError.message) || 'Unknown error'}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
exports.sendTextMessage = sendTextMessage;
|
|
93
|
+
const sendMedia = (_a) => __awaiter(void 0, [_a], void 0, function* ({ sessionId, to, media, type, caption = "", fileName, isGroup = false, answering, }) {
|
|
94
|
+
var _b;
|
|
95
|
+
const session = (0, Socket_1.getSession)(sessionId);
|
|
96
|
+
if (!session)
|
|
97
|
+
throw new Error_1.WhatsappError(Defaults_1.Messages.sessionNotFound(sessionId));
|
|
98
|
+
to = (0, Utils_1.phoneToJid)({ to, isGroup });
|
|
99
|
+
try {
|
|
100
|
+
const mimeType = mime_1.default.getType(typeof media === 'string' ? media : (fileName || '')) || 'application/octet-stream';
|
|
101
|
+
if (!mimeType && type !== 'image' && type !== 'video')
|
|
102
|
+
throw new Error("Cannot get file mimetype!");
|
|
103
|
+
const messageContent = {};
|
|
104
|
+
const options = answering ? { quoted: answering } : {};
|
|
105
|
+
// Deteksi apakah ini grup berdasarkan format JID
|
|
106
|
+
const isGroupChat = to.endsWith('@g.us');
|
|
107
|
+
// Tunda sejenak untuk memastikan koneksi stabil
|
|
108
|
+
yield (0, create_delay_1.createDelay)(500);
|
|
109
|
+
// Persiapkan media dengan isExist
|
|
110
|
+
const processedMedia = (0, is_exist_1.isExist)(media);
|
|
111
|
+
switch (type) {
|
|
112
|
+
case "image":
|
|
113
|
+
messageContent.image = processedMedia;
|
|
114
|
+
messageContent.caption = caption;
|
|
115
|
+
if (fileName)
|
|
116
|
+
messageContent.fileName = fileName;
|
|
117
|
+
break;
|
|
118
|
+
case "video":
|
|
119
|
+
messageContent.video = processedMedia;
|
|
120
|
+
messageContent.caption = caption;
|
|
121
|
+
if (fileName)
|
|
122
|
+
messageContent.fileName = fileName;
|
|
123
|
+
break;
|
|
124
|
+
case "audio":
|
|
125
|
+
messageContent.audio = processedMedia;
|
|
126
|
+
messageContent.mimetype = mimeType;
|
|
127
|
+
if (fileName)
|
|
128
|
+
messageContent.fileName = fileName;
|
|
129
|
+
break;
|
|
130
|
+
case "pdf":
|
|
131
|
+
case "xls":
|
|
132
|
+
case "xlsx":
|
|
133
|
+
case "doc":
|
|
134
|
+
case "docx":
|
|
135
|
+
case "zip":
|
|
136
|
+
case "mp3":
|
|
137
|
+
messageContent.document = processedMedia;
|
|
138
|
+
messageContent.mimetype = mimeType;
|
|
139
|
+
messageContent.caption = caption;
|
|
140
|
+
if (fileName)
|
|
141
|
+
messageContent.fileName = fileName;
|
|
142
|
+
break;
|
|
143
|
+
default:
|
|
144
|
+
throw new Error("Media type not found! (image, video, audio, pdf)");
|
|
145
|
+
}
|
|
146
|
+
// Timeout lebih lama untuk media karena ukuran file
|
|
147
|
+
const timeoutMs = isGroupChat ? 60000 : 120000;
|
|
148
|
+
return yield (0, create_delay_1.withTimeout)(session.sendMessage(to, messageContent, options), timeoutMs, `Pengiriman media melebihi batas waktu ${timeoutMs / 1000} detik`);
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
console.error(`Error saat mengirim media: ${(error === null || error === void 0 ? void 0 : error.message) || 'Unknown error'}`);
|
|
152
|
+
// Jika koneksi tertutup, coba reconnect
|
|
153
|
+
if ((_b = error === null || error === void 0 ? void 0 : error.message) === null || _b === void 0 ? void 0 : _b.includes('Connection Closed')) {
|
|
154
|
+
try {
|
|
155
|
+
yield (0, Socket_1.reconnect)(sessionId);
|
|
156
|
+
yield (0, create_delay_1.createDelay)(3000); // Beri waktu untuk reconnect sepenuhnya
|
|
157
|
+
// Siapkan content media untuk percobaan ulang
|
|
158
|
+
const retryContent = getMessageContent();
|
|
159
|
+
// Coba kirim lagi setelah reconnect
|
|
160
|
+
return yield (0, create_delay_1.withTimeout)(session.sendMessage(to, retryContent, answering ? { quoted: answering } : {}), 180000, // 3 menit untuk percobaan setelah reconnect
|
|
161
|
+
`Pengiriman media setelah reconnect melebihi batas waktu`);
|
|
162
|
+
}
|
|
163
|
+
catch (reconnectError) {
|
|
164
|
+
console.error(`Gagal reconnect: ${(reconnectError === null || reconnectError === void 0 ? void 0 : reconnectError.message) || 'Unknown error'}`);
|
|
165
|
+
throw new Error_1.WhatsappError(`Koneksi terputus dan gagal reconnect: ${(reconnectError === null || reconnectError === void 0 ? void 0 : reconnectError.message) || 'Unknown error'}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// Untuk error timeout atau error lain, coba lagi dengan timeout lebih lama
|
|
169
|
+
try {
|
|
170
|
+
yield (0, create_delay_1.createDelay)(3000);
|
|
171
|
+
// Siapkan content media untuk percobaan ulang
|
|
172
|
+
const retryContent = getMessageContent();
|
|
173
|
+
// Untuk percobaan kedua, gunakan timeout yang lebih lama
|
|
174
|
+
return yield (0, create_delay_1.withTimeout)(session.sendMessage(to, retryContent, answering ? { quoted: answering } : {}), 180000, // 3 menit untuk percobaan kedua
|
|
175
|
+
`Percobaan kedua pengiriman media melebihi batas waktu`);
|
|
176
|
+
}
|
|
177
|
+
catch (retryError) {
|
|
178
|
+
console.error(`Gagal pada percobaan kedua: ${(retryError === null || retryError === void 0 ? void 0 : retryError.message) || 'Unknown error'}`);
|
|
179
|
+
throw new Error_1.WhatsappError(`Gagal mengirim media: ${(retryError === null || retryError === void 0 ? void 0 : retryError.message) || 'Unknown error'}`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// Helper function untuk mendapatkan message content berdasarkan tipe
|
|
183
|
+
function getMessageContent() {
|
|
184
|
+
const processedMedia = (0, is_exist_1.isExist)(media);
|
|
185
|
+
const content = {};
|
|
186
|
+
const fileMimeType = mime_1.default.getType(typeof media === 'string' ? media : (fileName || '')) || 'application/octet-stream';
|
|
187
|
+
switch (type) {
|
|
188
|
+
case "image":
|
|
189
|
+
content.image = processedMedia;
|
|
190
|
+
content.caption = caption;
|
|
191
|
+
if (fileName)
|
|
192
|
+
content.fileName = fileName;
|
|
193
|
+
break;
|
|
194
|
+
case "video":
|
|
195
|
+
content.video = processedMedia;
|
|
196
|
+
content.caption = caption;
|
|
197
|
+
if (fileName)
|
|
198
|
+
content.fileName = fileName;
|
|
199
|
+
break;
|
|
200
|
+
case "audio":
|
|
201
|
+
content.audio = processedMedia;
|
|
202
|
+
content.mimetype = fileMimeType;
|
|
203
|
+
if (fileName)
|
|
204
|
+
content.fileName = fileName;
|
|
205
|
+
break;
|
|
206
|
+
default:
|
|
207
|
+
content.document = processedMedia;
|
|
208
|
+
content.mimetype = fileMimeType;
|
|
209
|
+
content.caption = caption;
|
|
210
|
+
if (fileName)
|
|
211
|
+
content.fileName = fileName;
|
|
212
|
+
}
|
|
213
|
+
return content;
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
exports.sendMedia = sendMedia;
|
|
217
|
+
const sendVoiceNote = (_a) => __awaiter(void 0, void 0, void 0, function* () {
|
|
218
|
+
var { sessionId, to, isGroup = false, media } = _a, props = __rest(_a, ["sessionId", "to", "isGroup", "media"]);
|
|
219
|
+
const session = (0, Socket_1.getSession)(sessionId);
|
|
220
|
+
if (!session)
|
|
221
|
+
throw new Error_1.WhatsappError(Defaults_1.Messages.sessionNotFound(sessionId));
|
|
222
|
+
to = (0, Utils_1.phoneToJid)({ to, isGroup });
|
|
223
|
+
if (!media) {
|
|
224
|
+
throw new Error_1.WhatsappError(`Invalid Media`);
|
|
225
|
+
}
|
|
226
|
+
return yield session.sendMessage(to, {
|
|
227
|
+
audio: typeof media == "string"
|
|
228
|
+
? {
|
|
229
|
+
url: media,
|
|
230
|
+
}
|
|
231
|
+
: media,
|
|
232
|
+
ptt: true,
|
|
233
|
+
}, {
|
|
234
|
+
quoted: props.answering,
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
exports.sendVoiceNote = sendVoiceNote;
|
|
238
|
+
const sendSticker = (_a) => __awaiter(void 0, void 0, void 0, function* () {
|
|
239
|
+
var { sessionId, to, isGroup, media } = _a, props = __rest(_a, ["sessionId", "to", "isGroup", "media"]);
|
|
240
|
+
const session = (0, Socket_1.getSession)(sessionId);
|
|
241
|
+
if (!session)
|
|
242
|
+
throw new Error_1.WhatsappError(Defaults_1.Messages.sessionNotFound(sessionId));
|
|
243
|
+
to = (0, Utils_1.phoneToJid)({ to, isGroup });
|
|
244
|
+
if (!media) {
|
|
245
|
+
throw new Error_1.WhatsappError(`Invalid Media`);
|
|
246
|
+
}
|
|
247
|
+
return yield session.sendMessage(to, {
|
|
248
|
+
sticker: typeof media == "string"
|
|
249
|
+
? {
|
|
250
|
+
url: media,
|
|
251
|
+
}
|
|
252
|
+
: media,
|
|
253
|
+
}, {
|
|
254
|
+
quoted: props.answering,
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
exports.sendSticker = sendSticker;
|
|
258
|
+
/**
|
|
259
|
+
* Give typing effect to target
|
|
260
|
+
*
|
|
261
|
+
* Looks like human typing
|
|
262
|
+
*
|
|
263
|
+
* @param sessionId - Session ID
|
|
264
|
+
* @param to - Target
|
|
265
|
+
* @param duration - Duration in miliseconds typing effect will appear
|
|
266
|
+
* @param isGroup - Whether the chat is a group
|
|
267
|
+
*/
|
|
268
|
+
const sendTyping = (_a) => __awaiter(void 0, [_a], void 0, function* ({ sessionId, to, duration, isGroup, }) {
|
|
269
|
+
var _b;
|
|
270
|
+
const session = (0, Socket_1.getSession)(sessionId);
|
|
271
|
+
if (!session)
|
|
272
|
+
throw new Error_1.WhatsappError(Defaults_1.Messages.sessionNotFound(sessionId));
|
|
273
|
+
to = (0, Utils_1.phoneToJid)({ to, isGroup });
|
|
274
|
+
try {
|
|
275
|
+
// Deteksi apakah ini grup
|
|
276
|
+
const isGroupChat = to.endsWith('@g.us');
|
|
277
|
+
const timeoutMs = isGroupChat ? 5000 : 10000;
|
|
278
|
+
// Kirim status mengetik dengan timeout
|
|
279
|
+
yield (0, create_delay_1.withTimeout)(session.sendPresenceUpdate("composing", to), timeoutMs, `Timeout saat mengirim status mengetik`);
|
|
280
|
+
// Tunggu durasi yang ditentukan
|
|
281
|
+
yield (0, create_delay_1.createDelay)(duration);
|
|
282
|
+
// Setelah durasi, atur kembali status
|
|
283
|
+
yield (0, create_delay_1.withTimeout)(session.sendPresenceUpdate("paused", to), timeoutMs, `Timeout saat menghentikan status mengetik`);
|
|
284
|
+
}
|
|
285
|
+
catch (error) {
|
|
286
|
+
// Jika koneksi tertutup, coba reconnect
|
|
287
|
+
if ((_b = error === null || error === void 0 ? void 0 : error.message) === null || _b === void 0 ? void 0 : _b.includes('Connection Closed')) {
|
|
288
|
+
try {
|
|
289
|
+
yield (0, Socket_1.reconnect)(sessionId);
|
|
290
|
+
yield (0, create_delay_1.createDelay)(2000); // Beri waktu untuk reconnect sepenuhnya
|
|
291
|
+
// Setelah reconnect, coba kirim status mengetik lagi
|
|
292
|
+
const isGroupChat = to.endsWith('@g.us');
|
|
293
|
+
const timeoutMs = isGroupChat ? 5000 : 10000;
|
|
294
|
+
yield (0, create_delay_1.withTimeout)(session.sendPresenceUpdate("composing", to), timeoutMs, `Timeout saat mengirim status mengetik setelah reconnect`);
|
|
295
|
+
yield (0, create_delay_1.createDelay)(duration);
|
|
296
|
+
yield (0, create_delay_1.withTimeout)(session.sendPresenceUpdate("paused", to), timeoutMs, `Timeout saat menghentikan status mengetik setelah reconnect`);
|
|
297
|
+
}
|
|
298
|
+
catch (reconnectError) {
|
|
299
|
+
// Tidak melempar error agar aplikasi tetap berjalan
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
exports.sendTyping = sendTyping;
|
|
305
|
+
/**
|
|
306
|
+
* Mark message as read
|
|
307
|
+
*
|
|
308
|
+
* @param sessionId - Session ID
|
|
309
|
+
* @param key - Message key to mark as read
|
|
310
|
+
*/
|
|
311
|
+
const readMessage = (_a) => __awaiter(void 0, [_a], void 0, function* ({ sessionId, key, }) {
|
|
312
|
+
var _b;
|
|
313
|
+
const session = (0, Socket_1.getSession)(sessionId);
|
|
314
|
+
if (!session)
|
|
315
|
+
throw new Error_1.WhatsappError(Defaults_1.Messages.sessionNotFound(sessionId));
|
|
316
|
+
try {
|
|
317
|
+
// Terapkan timeout untuk mencegah hanging
|
|
318
|
+
yield (0, create_delay_1.withTimeout)(session.readMessages([key]), 10000, "Timeout saat menandai pesan sebagai telah dibaca");
|
|
319
|
+
}
|
|
320
|
+
catch (error) {
|
|
321
|
+
// Jika koneksi tertutup, coba reconnect
|
|
322
|
+
if ((_b = error === null || error === void 0 ? void 0 : error.message) === null || _b === void 0 ? void 0 : _b.includes('Connection Closed')) {
|
|
323
|
+
try {
|
|
324
|
+
yield (0, Socket_1.reconnect)(sessionId);
|
|
325
|
+
yield (0, create_delay_1.createDelay)(2000); // Beri waktu untuk reconnect sepenuhnya
|
|
326
|
+
// Setelah reconnect, coba tandai dibaca lagi
|
|
327
|
+
yield (0, create_delay_1.withTimeout)(session.readMessages([key]), 10000, "Timeout saat menandai pesan sebagai telah dibaca setelah reconnect");
|
|
328
|
+
}
|
|
329
|
+
catch (reconnectError) {
|
|
330
|
+
// Tidak melempar error agar aplikasi tetap berjalan
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
exports.readMessage = readMessage;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { GetProfileInfoProps } from "../Types/profile";
|
|
2
|
+
/**
|
|
3
|
+
* Get profile information of a target (people or group)
|
|
4
|
+
*/
|
|
5
|
+
export declare const getProfileInfo: (props: GetProfileInfoProps) => Promise<{
|
|
6
|
+
profilePictureUrl: string;
|
|
7
|
+
status: import("baileys").USyncQueryResultList[];
|
|
8
|
+
}>;
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Profile/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD;;GAEG;AACH,eAAO,MAAM,cAAc,GAAU,OAAO,mBAAmB;;;EAgB9D,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.getProfileInfo = void 0;
|
|
13
|
+
const Defaults_1 = require("../Defaults");
|
|
14
|
+
const Error_1 = require("../Error");
|
|
15
|
+
const Socket_1 = require("../Socket");
|
|
16
|
+
/**
|
|
17
|
+
* Get profile information of a target (people or group)
|
|
18
|
+
*/
|
|
19
|
+
const getProfileInfo = (props) => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
|
+
const session = (0, Socket_1.getSession)(props.sessionId);
|
|
21
|
+
if (!session)
|
|
22
|
+
throw new Error_1.WhatsappError(Defaults_1.Messages.sessionNotFound(props.sessionId));
|
|
23
|
+
const [profilePictureUrl, status] = yield Promise.allSettled([
|
|
24
|
+
session.profilePictureUrl(props.target, "image", 5000),
|
|
25
|
+
session.fetchStatus(props.target),
|
|
26
|
+
]);
|
|
27
|
+
return {
|
|
28
|
+
profilePictureUrl: profilePictureUrl.status === "fulfilled"
|
|
29
|
+
? profilePictureUrl.value || null
|
|
30
|
+
: null,
|
|
31
|
+
status: status.status === "fulfilled" ? status.value || null : null,
|
|
32
|
+
};
|
|
33
|
+
});
|
|
34
|
+
exports.getProfileInfo = getProfileInfo;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { WASocket } from "baileys";
|
|
2
|
+
import type { MessageReceived, MessageUpdated, StartSessionParams, StartSessionWithPairingCodeParams } from "../Types";
|
|
3
|
+
/**
|
|
4
|
+
* Set MongoDB URI for connection
|
|
5
|
+
* This function will be used to configure MongoDB connection with just the URI
|
|
6
|
+
*
|
|
7
|
+
* @param uri MongoDB connection URI
|
|
8
|
+
*/
|
|
9
|
+
export declare const setMongoURI: (uri: string) => Promise<void>;
|
|
10
|
+
export declare function setMongoCollection(collection: any): void;
|
|
11
|
+
export declare const startSession: (sessionId?: string, options?: StartSessionParams) => Promise<WASocket>;
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* @deprecated Use startSession method instead
|
|
15
|
+
*/
|
|
16
|
+
export declare const startSessionWithPairingCode: (sessionId: string, options: StartSessionWithPairingCodeParams) => Promise<WASocket>;
|
|
17
|
+
/**
|
|
18
|
+
* @deprecated Use startSession method instead
|
|
19
|
+
*/
|
|
20
|
+
export declare const startWhatsapp: (sessionId?: string, options?: StartSessionParams) => Promise<WASocket>;
|
|
21
|
+
export declare const deleteSession: (sessionId: string) => Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Get all active session IDs
|
|
24
|
+
* @returns Array of session IDs
|
|
25
|
+
*/
|
|
26
|
+
export declare const getAllSession: () => Promise<string[]>;
|
|
27
|
+
export declare const getAllSessionSync: () => string[];
|
|
28
|
+
export declare const getSession: (key: string) => WASocket | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* @deprecated Use loadSessionsFromMongo instead
|
|
31
|
+
*/
|
|
32
|
+
export declare const loadSessionsFromStorage: () => void;
|
|
33
|
+
export declare const onMessageReceived: (listener: (msg: MessageReceived) => any) => void;
|
|
34
|
+
export declare const onQRUpdated: (listener: ({ sessionId, qr }: {
|
|
35
|
+
sessionId: string;
|
|
36
|
+
qr: string;
|
|
37
|
+
}) => any) => void;
|
|
38
|
+
export declare const onConnected: (listener: (sessionId: string) => any) => void;
|
|
39
|
+
export declare const onDisconnected: (listener: (sessionId: string) => any) => void;
|
|
40
|
+
export declare const onConnecting: (listener: (sessionId: string) => any) => void;
|
|
41
|
+
export declare const onMessageUpdate: (listener: (data: MessageUpdated) => any) => void;
|
|
42
|
+
export declare const onPairingCode: (listener: (sessionId: string, code: string) => any) => void;
|
|
43
|
+
/**
|
|
44
|
+
* Load all sessions from MongoDB and start them automatically
|
|
45
|
+
*/
|
|
46
|
+
export declare const loadSessionsFromMongo: () => Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Configure MongoDB database and collection names
|
|
49
|
+
*
|
|
50
|
+
* @param dbName MongoDB database name (default: "wa_session")
|
|
51
|
+
* @param collectionName MongoDB collection name for auth storage (default: "auth")
|
|
52
|
+
*/
|
|
53
|
+
export declare const setMongoDBNames: (dbName?: string, collectionName?: string) => void;
|
|
54
|
+
/**
|
|
55
|
+
* Sets the directory name for storing credentials (File-based storage)
|
|
56
|
+
*
|
|
57
|
+
* @deprecated When using MongoDB, this setting has no effect. Only used for legacy file-based storage.
|
|
58
|
+
* @param dirname Directory name for storing credentials (default: "wa_credentials")
|
|
59
|
+
*/
|
|
60
|
+
export declare const setCredentialsDir: (dirname?: string) => void;
|
|
61
|
+
/**
|
|
62
|
+
* Attempt to reconnect a disconnected session
|
|
63
|
+
*
|
|
64
|
+
* @param sessionId Session ID to reconnect
|
|
65
|
+
* @returns Promise<boolean> indicating success
|
|
66
|
+
*/
|
|
67
|
+
export declare const reconnect: (sessionId: string) => Promise<boolean>;
|
|
68
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Socket/index.ts"],"names":[],"mappings":"AAAA,OAAqB,EAInB,QAAQ,EACT,MAAM,SAAS,CAAC;AAIjB,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,iCAAiC,EAClC,MAAM,UAAU,CAAC;AA6BlB;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAU,KAAK,MAAM,kBAe5C,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,GAAG,QAEjD;AAkBD,eAAO,MAAM,YAAY,GACvB,kBAAuB,EACvB,UAAS,kBAAsC,KAC9C,OAAO,CAAC,QAAQ,CA2FlB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,2BAA2B,GACtC,WAAW,MAAM,EACjB,SAAS,iCAAiC,KACzC,OAAO,CAAC,QAAQ,CA8FlB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa,iCAxMf,kBAAkB,KAC1B,OAAO,CAAC,QAAQ,CAuMsB,CAAC;AAE1C,eAAO,MAAM,aAAa,GAAU,WAAW,MAAM,kBA0BpD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,QAAa,OAAO,CAAC,MAAM,EAAE,CAsBtD,CAAC;AAGF,eAAO,MAAM,iBAAiB,QAAO,MAAM,EAAiC,CAAC;AAE7E,eAAO,MAAM,UAAU,GAAI,KAAK,MAAM,KAAG,QAAQ,GAAG,SACrB,CAAC;AAoChC;;GAEG;AACH,eAAO,MAAM,uBAAuB,YAMnC,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,UAAU,CAAC,GAAG,EAAE,eAAe,KAAK,GAAG,SAExE,CAAC;AACF,eAAO,MAAM,WAAW,GACtB,UAAU,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,KAAK,GAAG,SAGxE,CAAC;AACF,eAAO,MAAM,WAAW,GAAI,UAAU,CAAC,SAAS,EAAE,MAAM,KAAK,GAAG,SAE/D,CAAC;AACF,eAAO,MAAM,cAAc,GAAI,UAAU,CAAC,SAAS,EAAE,MAAM,KAAK,GAAG,SAElE,CAAC;AACF,eAAO,MAAM,YAAY,GAAI,UAAU,CAAC,SAAS,EAAE,MAAM,KAAK,GAAG,SAEhE,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,UAAU,CAAC,IAAI,EAAE,cAAc,KAAK,GAAG,SAEtE,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,GAAG,SAGnD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB,qBAcjC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAAI,SAAQ,MAAqB,EAAE,iBAAgB,MAAe,SAI7F,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAI,UAAS,MAAyB,SAGnE,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,SAAS,GAAU,WAAW,MAAM,KAAG,OAAO,CAAC,OAAO,CAsDlE,CAAC"}
|