@codebam/cf-workers-telegram-bot 7.17.0 → 7.19.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/telegram_api.d.ts +7 -7
- package/dist/telegram_api.js +9 -10
- package/dist/telegram_bot.js +7 -4
- package/dist/telegram_execution_context.d.ts +3 -2
- package/dist/telegram_execution_context.js +22 -14
- package/dist/types/Bored.d.ts +2 -2
- package/dist/types/ChatPermissions.d.ts +2 -2
- package/dist/types/DDGQueryResponse.d.ts +2 -2
- package/dist/types/Joke.d.ts +2 -2
- package/dist/types/Kanye.d.ts +2 -2
- package/dist/types/PartialTelegramUpdate.d.ts +2 -2
- package/dist/types/TelegramChat.d.ts +2 -2
- package/dist/types/TelegramDocument.d.ts +9 -0
- package/dist/types/TelegramDocument.js +1 -0
- package/dist/types/TelegramFrom.d.ts +2 -2
- package/dist/types/TelegramInlineQuery.d.ts +2 -2
- package/dist/types/TelegramInputMessageContent.d.ts +2 -2
- package/dist/types/TelegramMessage.d.ts +4 -2
- package/dist/types/TelegramMessageEntity.d.ts +2 -2
- package/dist/types/TelegramPhotoSize.d.ts +2 -2
- package/dist/types/TelegramUpdate.js +1 -1
- package/dist/types/TelegramUser.d.ts +2 -2
- package/dist/webhook.js +1 -1
- package/package.json +9 -9
package/dist/telegram_api.d.ts
CHANGED
|
@@ -4,28 +4,28 @@ import TelegramInlineQueryResultArticle from './types/TelegramInlineQueryResultA
|
|
|
4
4
|
import TelegramInlineQueryResultPhoto from './types/TelegramInlineQueryResultPhoto.js';
|
|
5
5
|
import TelegramInlineQueryResultVideo from './types/TelegramInlineQueryResultVideo.js';
|
|
6
6
|
export default class TelegramApi {
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
getApiUrl(botApi: string, slug: string, data: Record<string, SerializableData>): Request<unknown, CfProperties<unknown>>;
|
|
8
|
+
getFile(botApi: string, data: {
|
|
9
9
|
file_id: string;
|
|
10
|
-
}, token: string): Promise<
|
|
11
|
-
|
|
10
|
+
}, token: string): Promise<Response>;
|
|
11
|
+
sendMessage(botApi: string, data: {
|
|
12
12
|
reply_to_message_id: number | string;
|
|
13
13
|
chat_id: number | string;
|
|
14
14
|
text: string;
|
|
15
15
|
parse_mode: string;
|
|
16
16
|
}): Promise<Response>;
|
|
17
|
-
|
|
17
|
+
sendVideo(botApi: string, data: {
|
|
18
18
|
reply_to_message_id: number | string;
|
|
19
19
|
chat_id: number | string;
|
|
20
20
|
video: string;
|
|
21
21
|
}): Promise<Response>;
|
|
22
|
-
|
|
22
|
+
sendPhoto(botApi: string, data: {
|
|
23
23
|
reply_to_message_id: number | string;
|
|
24
24
|
chat_id: number | string;
|
|
25
25
|
photo: string;
|
|
26
26
|
caption: string;
|
|
27
27
|
}): Promise<Response>;
|
|
28
|
-
|
|
28
|
+
answerInline(botApi: string, data: {
|
|
29
29
|
inline_query_id: number | string;
|
|
30
30
|
results: TelegramInlineQueryResultArticle[] | TelegramInlineQueryResultPhoto[] | TelegramInlineQueryResultVideo[];
|
|
31
31
|
}): Promise<Response>;
|
package/dist/telegram_api.js
CHANGED
|
@@ -1,33 +1,32 @@
|
|
|
1
1
|
export default class TelegramApi {
|
|
2
|
-
|
|
2
|
+
getApiUrl(botApi, slug, data) {
|
|
3
3
|
const request = new URL(botApi + (slug.startsWith('/') || botApi.endsWith('/') ? '' : '/') + slug);
|
|
4
4
|
const params = new URLSearchParams();
|
|
5
5
|
for (const i in data) {
|
|
6
6
|
params.append(i, data[i].toString());
|
|
7
7
|
}
|
|
8
|
-
return new Request(`${request}?${params}`);
|
|
8
|
+
return new Request(`${request.toString()}?${params.toString()}`);
|
|
9
9
|
}
|
|
10
|
-
|
|
10
|
+
async getFile(botApi, data, token) {
|
|
11
11
|
const url = this.getApiUrl(botApi, 'getFile', data);
|
|
12
12
|
const response = await fetch(url);
|
|
13
|
-
const json =
|
|
13
|
+
const json = await response.json();
|
|
14
14
|
const file_path = json.result.file_path;
|
|
15
|
-
|
|
16
|
-
return await file_response.arrayBuffer();
|
|
15
|
+
return await fetch(`https://api.telegram.org/file/bot${token}/${file_path}`);
|
|
17
16
|
}
|
|
18
|
-
|
|
17
|
+
async sendMessage(botApi, data) {
|
|
19
18
|
const url = this.getApiUrl(botApi, 'sendMessage', data);
|
|
20
19
|
return await fetch(url);
|
|
21
20
|
}
|
|
22
|
-
|
|
21
|
+
async sendVideo(botApi, data) {
|
|
23
22
|
const url = this.getApiUrl(botApi, 'sendVideo', data);
|
|
24
23
|
return await fetch(url);
|
|
25
24
|
}
|
|
26
|
-
|
|
25
|
+
async sendPhoto(botApi, data) {
|
|
27
26
|
const url = this.getApiUrl(botApi, 'sendPhoto', data);
|
|
28
27
|
return await fetch(url);
|
|
29
28
|
}
|
|
30
|
-
|
|
29
|
+
async answerInline(botApi, data) {
|
|
31
30
|
const url = this.getApiUrl(botApi, 'answerInlineQuery', {
|
|
32
31
|
inline_query_id: data.inline_query_id,
|
|
33
32
|
results: JSON.stringify(data.results),
|
package/dist/telegram_bot.js
CHANGED
|
@@ -13,7 +13,7 @@ export default class TelegramBot {
|
|
|
13
13
|
this.api = new URL('https://api.telegram.org/bot' + token);
|
|
14
14
|
}
|
|
15
15
|
on(event, callback) {
|
|
16
|
-
if (['on', 'handle'].
|
|
16
|
+
if (!['on', 'handle'].includes(event)) {
|
|
17
17
|
this.commands[event] = callback;
|
|
18
18
|
}
|
|
19
19
|
return this;
|
|
@@ -43,17 +43,20 @@ export default class TelegramBot {
|
|
|
43
43
|
command = ':photo';
|
|
44
44
|
break;
|
|
45
45
|
}
|
|
46
|
+
case 'document': {
|
|
47
|
+
command = ':document';
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
46
50
|
default:
|
|
47
51
|
break;
|
|
48
52
|
}
|
|
49
53
|
if (args.at(0)?.startsWith('/')) {
|
|
50
54
|
command = args.at(0)?.slice(1) ?? 'default';
|
|
51
55
|
}
|
|
52
|
-
this.commands
|
|
53
|
-
if (!this.commands[command]) {
|
|
56
|
+
if (!(command in this.commands)) {
|
|
54
57
|
command = 'default';
|
|
55
58
|
}
|
|
56
|
-
return await this.commands[command]
|
|
59
|
+
return await this.commands[command](ctx);
|
|
57
60
|
}
|
|
58
61
|
case 'GET': {
|
|
59
62
|
switch (url.searchParams.get('command')) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
+
import TelegramApi from './telegram_api.js';
|
|
2
3
|
import TelegramBot from './telegram_bot.js';
|
|
3
4
|
import SerializableData from './types/SerializableData.js';
|
|
4
5
|
import TelegramUpdate from './types/TelegramUpdate.js';
|
|
@@ -6,15 +7,15 @@ export default class TelegramExecutionContext {
|
|
|
6
7
|
bot: TelegramBot;
|
|
7
8
|
update: TelegramUpdate;
|
|
8
9
|
update_type: string;
|
|
10
|
+
api: TelegramApi;
|
|
9
11
|
private data;
|
|
10
12
|
constructor(bot: TelegramBot, update: TelegramUpdate);
|
|
11
13
|
getText(): string;
|
|
12
14
|
next(): Response;
|
|
13
15
|
setData(key: string, value: SerializableData): this;
|
|
14
|
-
deleteData(key: string): this;
|
|
15
16
|
getData(key: string): SerializableData;
|
|
16
17
|
replyVideo(video: string, options?: Record<string, SerializableData>): Promise<Response | undefined>;
|
|
17
|
-
getFile(file_id: string): Promise<
|
|
18
|
+
getFile(file_id: string): Promise<Response>;
|
|
18
19
|
replyPhoto(photo: string, caption?: string, options?: Record<string, SerializableData>): Promise<Response | undefined>;
|
|
19
20
|
reply(message: string, parse_mode?: string, options?: Record<string, SerializableData>): Promise<Response | undefined>;
|
|
20
21
|
}
|
|
@@ -6,6 +6,7 @@ export default class TelegramExecutionContext {
|
|
|
6
6
|
bot;
|
|
7
7
|
update;
|
|
8
8
|
update_type = '';
|
|
9
|
+
api = new TelegramApi();
|
|
9
10
|
data = {};
|
|
10
11
|
constructor(bot, update) {
|
|
11
12
|
this.bot = bot;
|
|
@@ -19,9 +20,12 @@ export default class TelegramExecutionContext {
|
|
|
19
20
|
else if (this.update.inline_query?.query) {
|
|
20
21
|
this.update_type = 'inline';
|
|
21
22
|
}
|
|
23
|
+
else if (this.update.message?.document) {
|
|
24
|
+
this.update_type = 'document';
|
|
25
|
+
}
|
|
22
26
|
}
|
|
23
27
|
getText() {
|
|
24
|
-
return this.update.message?.text
|
|
28
|
+
return this.update.message?.text ?? this.update.inline_query?.query ?? '';
|
|
25
29
|
}
|
|
26
30
|
next() {
|
|
27
31
|
return new Response('ok');
|
|
@@ -30,24 +34,20 @@ export default class TelegramExecutionContext {
|
|
|
30
34
|
this.data[key] = value;
|
|
31
35
|
return this;
|
|
32
36
|
}
|
|
33
|
-
deleteData(key) {
|
|
34
|
-
delete this.data[key];
|
|
35
|
-
return this;
|
|
36
|
-
}
|
|
37
37
|
getData(key) {
|
|
38
38
|
return this.data[key];
|
|
39
39
|
}
|
|
40
40
|
async replyVideo(video, options = {}) {
|
|
41
41
|
switch (this.update_type) {
|
|
42
42
|
case 'message':
|
|
43
|
-
return await
|
|
43
|
+
return await this.api.sendVideo(this.bot.api.toString(), {
|
|
44
44
|
...options,
|
|
45
45
|
chat_id: this.update.message?.chat.id.toString() ?? '',
|
|
46
46
|
reply_to_message_id: this.update.message?.message_id.toString() ?? '',
|
|
47
47
|
video,
|
|
48
48
|
});
|
|
49
49
|
case 'inline':
|
|
50
|
-
return await
|
|
50
|
+
return await this.api.answerInline(this.bot.api.toString(), {
|
|
51
51
|
...options,
|
|
52
52
|
inline_query_id: this.update.inline_query?.id.toString() ?? '',
|
|
53
53
|
results: [new TelegramInlineQueryResultVideo(video)],
|
|
@@ -57,12 +57,12 @@ export default class TelegramExecutionContext {
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
async getFile(file_id) {
|
|
60
|
-
return await
|
|
60
|
+
return await this.api.getFile(this.bot.api.toString(), { file_id }, this.bot.token);
|
|
61
61
|
}
|
|
62
62
|
async replyPhoto(photo, caption = '', options = {}) {
|
|
63
63
|
switch (this.update_type) {
|
|
64
64
|
case 'photo':
|
|
65
|
-
return await
|
|
65
|
+
return await this.api.sendPhoto(this.bot.api.toString(), {
|
|
66
66
|
...options,
|
|
67
67
|
chat_id: this.update.message?.chat.id.toString() ?? '',
|
|
68
68
|
reply_to_message_id: this.update.message?.message_id.toString() ?? '',
|
|
@@ -70,7 +70,7 @@ export default class TelegramExecutionContext {
|
|
|
70
70
|
caption,
|
|
71
71
|
});
|
|
72
72
|
case 'message':
|
|
73
|
-
return await
|
|
73
|
+
return await this.api.sendPhoto(this.bot.api.toString(), {
|
|
74
74
|
...options,
|
|
75
75
|
chat_id: this.update.message?.chat.id.toString() ?? '',
|
|
76
76
|
reply_to_message_id: this.update.message?.message_id.toString() ?? '',
|
|
@@ -78,7 +78,7 @@ export default class TelegramExecutionContext {
|
|
|
78
78
|
caption,
|
|
79
79
|
});
|
|
80
80
|
case 'inline':
|
|
81
|
-
return await
|
|
81
|
+
return await this.api.answerInline(this.bot.api.toString(), {
|
|
82
82
|
inline_query_id: this.update.inline_query?.id.toString() ?? '',
|
|
83
83
|
results: [new TelegramInlineQueryResultPhoto(photo)],
|
|
84
84
|
});
|
|
@@ -89,7 +89,7 @@ export default class TelegramExecutionContext {
|
|
|
89
89
|
async reply(message, parse_mode = '', options = {}) {
|
|
90
90
|
switch (this.update_type) {
|
|
91
91
|
case 'message':
|
|
92
|
-
return await
|
|
92
|
+
return await this.api.sendMessage(this.bot.api.toString(), {
|
|
93
93
|
...options,
|
|
94
94
|
chat_id: this.update.message?.chat.id.toString() ?? '',
|
|
95
95
|
reply_to_message_id: this.update.message?.message_id.toString() ?? '',
|
|
@@ -97,7 +97,7 @@ export default class TelegramExecutionContext {
|
|
|
97
97
|
parse_mode,
|
|
98
98
|
});
|
|
99
99
|
case 'photo':
|
|
100
|
-
return await
|
|
100
|
+
return await this.api.sendMessage(this.bot.api.toString(), {
|
|
101
101
|
...options,
|
|
102
102
|
chat_id: this.update.message?.chat.id.toString() ?? '',
|
|
103
103
|
reply_to_message_id: this.update.message?.message_id.toString() ?? '',
|
|
@@ -105,10 +105,18 @@ export default class TelegramExecutionContext {
|
|
|
105
105
|
parse_mode,
|
|
106
106
|
});
|
|
107
107
|
case 'inline':
|
|
108
|
-
return await
|
|
108
|
+
return await this.api.answerInline(this.bot.api.toString(), {
|
|
109
109
|
inline_query_id: this.update.inline_query?.id.toString() ?? '',
|
|
110
110
|
results: [new TelegramInlineQueryResultArticle(message)],
|
|
111
111
|
});
|
|
112
|
+
case 'document':
|
|
113
|
+
return await this.api.sendMessage(this.bot.api.toString(), {
|
|
114
|
+
...options,
|
|
115
|
+
chat_id: this.update.message?.chat.id.toString() ?? '',
|
|
116
|
+
reply_to_message_id: this.update.message?.message_id.toString() ?? '',
|
|
117
|
+
text: message,
|
|
118
|
+
parse_mode,
|
|
119
|
+
});
|
|
112
120
|
default:
|
|
113
121
|
break;
|
|
114
122
|
}
|
package/dist/types/Bored.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
interface ChatPermissions {
|
|
2
2
|
can_send_messages?: boolean;
|
|
3
3
|
can_send_audios?: boolean;
|
|
4
4
|
can_send_documents?: boolean;
|
|
@@ -13,5 +13,5 @@ type ChatPermissions = {
|
|
|
13
13
|
can_invite_users?: boolean;
|
|
14
14
|
can_pin_messages?: boolean;
|
|
15
15
|
can_manage_topics?: boolean;
|
|
16
|
-
}
|
|
16
|
+
}
|
|
17
17
|
export default ChatPermissions;
|
package/dist/types/Joke.d.ts
CHANGED
package/dist/types/Kanye.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import TelegramInlineQuery from './TelegramInlineQuery.js';
|
|
2
2
|
import TelegramMessage from './TelegramMessage.js';
|
|
3
|
-
|
|
3
|
+
interface PartialTelegramUpdate {
|
|
4
4
|
update_id?: number;
|
|
5
5
|
message?: TelegramMessage;
|
|
6
6
|
edited_message?: TelegramMessage;
|
|
7
7
|
channel_post?: TelegramMessage;
|
|
8
8
|
edited_channel_post?: TelegramMessage;
|
|
9
9
|
inline_query?: TelegramInlineQuery;
|
|
10
|
-
}
|
|
10
|
+
}
|
|
11
11
|
export default PartialTelegramUpdate;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import TelegramMessage from './TelegramMessage.js';
|
|
2
|
-
|
|
2
|
+
interface TelegramChat {
|
|
3
3
|
id: number;
|
|
4
4
|
type: string;
|
|
5
5
|
title?: string;
|
|
@@ -17,5 +17,5 @@ type TelegramChat = {
|
|
|
17
17
|
sticker_set_name?: string;
|
|
18
18
|
can_set_sticker_set?: boolean;
|
|
19
19
|
linked_chat_id?: number;
|
|
20
|
-
}
|
|
20
|
+
}
|
|
21
21
|
export default TelegramChat;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import TelegramFrom from './TelegramFrom.js';
|
|
2
|
-
|
|
2
|
+
interface TelegramInlineQuery {
|
|
3
3
|
chat_type: 'sender' | 'private' | 'group' | 'supergroup' | 'channel';
|
|
4
4
|
from: TelegramFrom;
|
|
5
5
|
id: number;
|
|
6
6
|
offset: string;
|
|
7
7
|
query: string;
|
|
8
|
-
}
|
|
8
|
+
}
|
|
9
9
|
export default TelegramInlineQuery;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import TelegramChat from './TelegramChat.js';
|
|
2
|
+
import { TelegramDocument } from './TelegramDocument.js';
|
|
2
3
|
import TelegramFrom from './TelegramFrom.js';
|
|
3
4
|
import TelegramMessageEntity from './TelegramMessageEntity.js';
|
|
4
5
|
import TelegramPhotoSize from './TelegramPhotoSize.js';
|
|
5
6
|
import TelegramUser from './TelegramUser.js';
|
|
6
|
-
|
|
7
|
+
interface TelegramMessage {
|
|
7
8
|
message_id: number;
|
|
8
9
|
from: TelegramFrom;
|
|
9
10
|
sender_chat?: TelegramChat;
|
|
@@ -24,6 +25,7 @@ type TelegramMessage = {
|
|
|
24
25
|
author_signature?: string;
|
|
25
26
|
text?: string;
|
|
26
27
|
entities?: TelegramMessageEntity[];
|
|
28
|
+
document?: TelegramDocument;
|
|
27
29
|
photo?: TelegramPhotoSize[];
|
|
28
30
|
caption?: string;
|
|
29
31
|
caption_entities?: TelegramMessageEntity[];
|
|
@@ -39,5 +41,5 @@ type TelegramMessage = {
|
|
|
39
41
|
migrate_from_chat_id?: number;
|
|
40
42
|
pinned_message?: TelegramMessage;
|
|
41
43
|
connected_website?: string;
|
|
42
|
-
}
|
|
44
|
+
}
|
|
43
45
|
export default TelegramMessage;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import TelegramUser from './TelegramUser.js';
|
|
2
|
-
|
|
2
|
+
interface TelegramMessageEntity {
|
|
3
3
|
type: string;
|
|
4
4
|
offset: number;
|
|
5
5
|
length: number;
|
|
6
6
|
url?: string;
|
|
7
7
|
user?: TelegramUser;
|
|
8
8
|
language?: string;
|
|
9
|
-
}
|
|
9
|
+
}
|
|
10
10
|
export default TelegramMessageEntity;
|
|
@@ -17,7 +17,7 @@ export default class TelegramUpdate extends Update {
|
|
|
17
17
|
// chat_join_request: TelegramChatJoinRequest;
|
|
18
18
|
constructor(update) {
|
|
19
19
|
super();
|
|
20
|
-
this.update_id = update.update_id
|
|
20
|
+
this.update_id = update.update_id ?? 0;
|
|
21
21
|
this.message = update.message;
|
|
22
22
|
this.edited_message = update.edited_message;
|
|
23
23
|
this.channel_post = update.channel_post;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
interface TelegramUser {
|
|
2
2
|
id: number;
|
|
3
3
|
is_bot: boolean;
|
|
4
4
|
first_name: string;
|
|
@@ -8,5 +8,5 @@ type TelegramUser = {
|
|
|
8
8
|
can_join_groups?: boolean;
|
|
9
9
|
can_read_all_group_messages?: boolean;
|
|
10
10
|
supports_inline_queries: boolean;
|
|
11
|
-
}
|
|
11
|
+
}
|
|
12
12
|
export default TelegramUser;
|
package/dist/webhook.js
CHANGED
|
@@ -12,6 +12,6 @@ export default class Webhook {
|
|
|
12
12
|
params.append('max_connections', '100');
|
|
13
13
|
params.append('allowed_updates', JSON.stringify(['message', 'inline_query']));
|
|
14
14
|
params.append('drop_pending_updates', 'true');
|
|
15
|
-
return await fetch(`${url}?${params}`);
|
|
15
|
+
return await fetch(`${url.toString()}?${params.toString()}`);
|
|
16
16
|
}
|
|
17
17
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codebam/cf-workers-telegram-bot",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.19.0",
|
|
4
4
|
"description": "serverless telegram bot on cf workers",
|
|
5
5
|
"main": "./dist/main.js",
|
|
6
6
|
"module": "./dist/main.js",
|
|
@@ -31,18 +31,18 @@
|
|
|
31
31
|
"url": "https://github.com/codebam/cf-workers-telegram-bot.git"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@cloudflare/workers-types": "^4.
|
|
35
|
-
"@eslint/js": "^9.
|
|
36
|
-
"@typescript-eslint/eslint-plugin": "^7.
|
|
37
|
-
"@typescript-eslint/parser": "^7.
|
|
38
|
-
"eslint": "^
|
|
34
|
+
"@cloudflare/workers-types": "^4.20240512.0",
|
|
35
|
+
"@eslint/js": "^9.3.0",
|
|
36
|
+
"@typescript-eslint/eslint-plugin": "^7.10.0",
|
|
37
|
+
"@typescript-eslint/parser": "^7.10.0",
|
|
38
|
+
"eslint": "^8.56.0",
|
|
39
39
|
"eslint-config-prettier": "^9.1.0",
|
|
40
|
-
"globals": "^15.
|
|
40
|
+
"globals": "^15.3.0",
|
|
41
41
|
"lerna": "^8.1.2",
|
|
42
42
|
"prettier": "^3.2.5",
|
|
43
43
|
"typescript": "^5.4.5",
|
|
44
|
-
"typescript-eslint": "^7.
|
|
44
|
+
"typescript-eslint": "^7.10.0",
|
|
45
45
|
"vitest": "^1.6.0"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "6a464429f3ce661593659db8145d5b73ac75e5e3"
|
|
48
48
|
}
|