@neoxr/wb 1.45.65

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,1228 @@
1
+ const axios = require('axios')
2
+ const fetch = require('node-fetch')
3
+ const cheerio = require('cheerio')
4
+ const fs = require('fs')
5
+ const mime = require('mime-types')
6
+ const chalk = require('chalk')
7
+ const path = require('path')
8
+ const FormData = require('form-data')
9
+ const { fromBuffer } = require('file-type')
10
+ const { green, blueBright, redBright } = require('chalk')
11
+ const { tmpdir } = require('os')
12
+ const moment = require('moment-timezone')
13
+ moment.tz.setDefault(process.env.TZ)
14
+ const NodeID3 = require('node-id3')
15
+ const { read, MIME_JPEG, RESIZE_BILINEAR, AUTO } = require('jimp')
16
+ const cloudscraper = require('cloudscraper')
17
+ const Miniget = require('miniget')
18
+ const stream = require('stream')
19
+
20
+ module.exports = class Function {
21
+ /* Delay
22
+ * @param {Integer} time
23
+ */
24
+ delay = time => new Promise(res => setTimeout(res, time))
25
+
26
+ /* Image Resizer for Thumbnail
27
+ * @param {String|Buffer} source
28
+ */
29
+ createThumb = async (source, width = 200) => {
30
+ const { file } = await this.getFile(source)
31
+ let jimp = await read(await this.fetchBuffer(file))
32
+ let buff = await jimp
33
+ .quality(100)
34
+ .resize(width, AUTO, RESIZE_BILINEAR)
35
+ .getBufferAsync(MIME_JPEG)
36
+ return buff
37
+ }
38
+
39
+ /* URL Validator
40
+ * @param {String} url
41
+ */
42
+ isUrl = (url) => {
43
+ return url.match(new RegExp(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%.+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%+.~#?&/=]*)/, 'gi'))
44
+ }
45
+
46
+ /* Fetching JSON
47
+ * @param {String} url
48
+ * @param {Object} head
49
+ */
50
+ fetchJson = async (url, options = {}) => {
51
+ try {
52
+ const result = await (await axios.get(url, {
53
+ ...options
54
+ })).data
55
+ return result
56
+ } catch (e) {
57
+ return ({
58
+ status: false,
59
+ msg: e.message
60
+ })
61
+ }
62
+ }
63
+
64
+ /* Converting to Buffer
65
+ * @param {String|Buffer} file
66
+ * @param {Object} options
67
+ */
68
+ fetchBuffer = async (file, options = {}) => {
69
+ try {
70
+ if (this.isUrl(file)) {
71
+ const buffer = await (await axios.get(file, {
72
+ responseType: "arraybuffer",
73
+ ...options
74
+ })).data
75
+ return buffer
76
+ } else {
77
+ const buffer = fs.readFileSync(file)
78
+ return buffer
79
+ }
80
+ } catch (e) {
81
+ return ({
82
+ status: false,
83
+ msg: e.message
84
+ })
85
+ }
86
+ }
87
+
88
+
89
+ /* Parse Cookie
90
+ * @param {String} url
91
+ * @param {Object} options
92
+ */
93
+ parseCookie = async (file, options = {}) => {
94
+ return new Promise(async (resolve, reject) => {
95
+ try {
96
+ let cookie = await (await axios.get(file, {
97
+ responseType: "arraybuffer",
98
+ headers: options
99
+ })).headers['set-cookie']
100
+ resolve(cookie)
101
+ } catch (e) {
102
+ return ({
103
+ status: false,
104
+ msg: e.message
105
+ })
106
+ }
107
+ })
108
+ }
109
+
110
+ /* Audio Metadata
111
+ * @param {String|Buffer} source
112
+ * @param {Object} tags
113
+ */
114
+ metaAudio = (source, tags = {}) => {
115
+ return new Promise(async (resolve) => {
116
+ try {
117
+ const { status, file, mime } = await this.getFile(await this.fetchBuffer(source))
118
+ if (!status) return resolve({
119
+ status: false
120
+ })
121
+ if (!/audio/.test(mime)) return resolve({
122
+ status: true,
123
+ file
124
+ })
125
+ NodeID3.write(tags, await this.fetchBuffer(file), function(err, buffer) {
126
+ if (err) return resolve({
127
+ status: false
128
+ })
129
+ fs.writeFileSync(file, buffer)
130
+ resolve({
131
+ status: true,
132
+ file
133
+ })
134
+ })
135
+ } catch (e) {
136
+ console.log(e)
137
+ resolve({
138
+ status: false
139
+ })
140
+ }
141
+ })
142
+ }
143
+
144
+ /* Text Style
145
+ * @param {String} type
146
+ * @param {String} text
147
+ */
148
+ texted = (type, text) => {
149
+ switch (type) {
150
+ case 'bold':
151
+ return '*' + text + '*'
152
+ break
153
+ case 'italic':
154
+ return '_' + text + '_'
155
+ break
156
+ case 'monospace':
157
+ return '```' + text + '```'
158
+ }
159
+ }
160
+
161
+ /* Example Format
162
+ * @param {String} isPrefix
163
+ * @param {String} command
164
+ * @param {String} args
165
+ */
166
+ example = (isPrefix, command, args) => {
167
+ return `• ${this.texted('bold', 'Example')} : ${isPrefix + command} ${args}`
168
+ }
169
+
170
+ /* Fix Instagram URL
171
+ * @param {String} url
172
+ */
173
+ igFixed = (url) => {
174
+ let count = url.split('/')
175
+ if (count.length == 7) {
176
+ let username = count[3]
177
+ let destruct = this.removeItem(count, username)
178
+ return destruct.map(v => v).join('/')
179
+ } else return url
180
+ }
181
+
182
+ /* Fix Tiktok URL
183
+ * @param {String} url
184
+ */
185
+ ttFixed = (url) => {
186
+ if (!url.match(/(tiktok.com\/t\/)/g)) return url
187
+ let id = url.split('/t/')[1]
188
+ return 'https://vm.tiktok.com/' + id
189
+ }
190
+
191
+ /* Time Format
192
+ * @param {Integer} ms
193
+ */
194
+ toTime = (ms) => {
195
+ let h = Math.floor(ms / 3600000)
196
+ let m = Math.floor(ms / 60000) % 60
197
+ let s = Math.floor(ms / 1000) % 60
198
+ return [h, m, s].map(v => v.toString().padStart(2, 0)).join(':')
199
+ }
200
+
201
+ /* Readable Time
202
+ * @param {Integer} ms
203
+ */
204
+ readTime = (ms) => {
205
+ const days = Math.floor(ms / (24 * 60 * 60 * 1000))
206
+ const daysms = ms % (24 * 60 * 60 * 1000)
207
+ const hours = Math.floor(daysms / (60 * 60 * 1000))
208
+ const hoursms = ms % (60 * 60 * 1000)
209
+ const minutes = Math.floor(hoursms / (60 * 1000))
210
+ const minutesms = ms % (60 * 1000)
211
+ const sec = Math.floor(minutesms / 1000)
212
+ const format = [days, hours, minutes, sec].map(v => v.toString().padStart(2, 0))
213
+ return {
214
+ days: Number(format[0]),
215
+ hours: Number(format[1]),
216
+ minutes: Number(format[2]),
217
+ seconds: Number(format[3])
218
+ }
219
+ }
220
+
221
+ /* Random Filename
222
+ * @param {String} extension
223
+ */
224
+ filename = (extension) => {
225
+ return `${Math.floor(Math.random() * 10000)}.${extension}`
226
+ }
227
+
228
+ /* Create UUID */
229
+ uuid = () => {
230
+ var dt = new Date().getTime()
231
+ var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
232
+ var r = (dt + Math.random() * 16) % 16 | 0;
233
+ var y = Math.floor(dt / 16);
234
+ return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
235
+ });
236
+ return uuid
237
+ }
238
+
239
+ /* Random Element From Array
240
+ * @param {Array} list
241
+ */
242
+ random = (list) => {
243
+ return list[Math.floor(Math.random() * list.length)]
244
+ }
245
+
246
+ /* Random Number
247
+ * @param {Integer} min
248
+ * @param {Integer} max
249
+ */
250
+ randomInt = (min, max) => {
251
+ min = Math.ceil(min)
252
+ max = Math.floor(max)
253
+ return Math.floor(Math.random() * (max - min + 1)) + min
254
+ }
255
+
256
+ /* Format Number \w Dot
257
+ * @param {Integer} integer
258
+ */
259
+ formatter = (integer) => {
260
+ let numb = parseInt(integer)
261
+ return Number(numb).toLocaleString().replace(/,/g, '.')
262
+ }
263
+
264
+ formatNumber = (integer) => {
265
+ let numb = parseInt(integer)
266
+ return Number(numb).toLocaleString().replace(/,/g, '.')
267
+ }
268
+
269
+ /* H2K Format
270
+ * @param {Integer} integer
271
+ */
272
+ h2k = (integer) => {
273
+ let numb = parseInt(integer)
274
+ return new Intl.NumberFormat('en-US', {
275
+ notation: 'compact'
276
+ }).format(numb)
277
+ }
278
+
279
+ /* To Readable Size
280
+ * @param {Integer} size
281
+ */
282
+ formatSize = (size) => {
283
+ function round(value, precision) {
284
+ var multiplier = Math.pow(10, precision || 0)
285
+ return Math.round(value * multiplier) / multiplier
286
+ }
287
+ var megaByte = 1024 * 1024
288
+ var gigaByte = 1024 * megaByte
289
+ var teraByte = 1024 * gigaByte
290
+ if (size < 1024) {
291
+ return size + ' B'
292
+ } else if (size < megaByte) {
293
+ return round(size / 1024, 1) + ' KB'
294
+ } else if (size < gigaByte) {
295
+ return round(size / megaByte, 1) + ' MB'
296
+ } else if (size < teraByte) {
297
+ return round(size / gigaByte, 1) + ' GB'
298
+ } else {
299
+ return round(size / teraByte, 1) + ' TB'
300
+ }
301
+ return ''
302
+ }
303
+
304
+ /* Fix Instagram URL
305
+ * @param {String|Integer} str
306
+ */
307
+ getSize = async (str) => {
308
+ if (!isNaN(str)) return this.formatSize(str)
309
+ let header = await (await axios.get(str)).headers
310
+ return this.formatSize(header['content-length'])
311
+ }
312
+
313
+ /* Download File To /tmp Folder
314
+ * @param {String|Buffer} source
315
+ * @param {String} filename
316
+ * @param {String} referer
317
+ */
318
+ getFile = async (source, filename, options) => {
319
+ try {
320
+ if (Buffer.isBuffer(source)) {
321
+ let ext, mime
322
+ try {
323
+ mime = await (await fromBuffer(source)).mime
324
+ ext = await (await fromBuffer(source)).ext
325
+ } catch {
326
+ mime = require('mime-types').lookup(filename ? filename.split`.` [filename.split`.`.length - 1] : 'txt')
327
+ ext = require('mime-types').extension(mime)
328
+ }
329
+ const extension = filename ? filename.split`.` [filename.split`.`.length - 1] : ext
330
+ const size = Buffer.byteLength(source)
331
+ const filepath = 'temp/' + (this.uuid() + '.' + ext)
332
+ const file = fs.writeFileSync(filepath, source)
333
+ const name = filename || path.basename(filepath)
334
+ return new Promise(resolve => {
335
+ const data = {
336
+ status: true,
337
+ file: filepath,
338
+ filename: name,
339
+ mime: mime,
340
+ extension: ext,
341
+ size: this.formatSize(size),
342
+ bytes: size
343
+ }
344
+ return resolve(data)
345
+ })
346
+ } else if (source.startsWith('./') || source.startsWith('/')) {
347
+ const mime = require('mime-types').lookup(filename ? filename.split`.` [filename.split`.`.length - 1] : source.split`.` [source.split`.`.length - 1])
348
+ const ext = require('mime-types').extension(mime)
349
+ const extension = filename ? filename.split`.` [filename.split`.`.length - 1] : ext
350
+ const size = fs.statSync(source).size
351
+ const name = filename || path.basename(source)
352
+ return new Promise(resolve => {
353
+ const data = {
354
+ status: true,
355
+ file: source,
356
+ filename: name,
357
+ mime: mime,
358
+ extension: ext,
359
+ size: this.formatSize(size),
360
+ bytes: size
361
+ }
362
+ return resolve(data)
363
+ })
364
+ } else {
365
+ return new Promise(resolve => {
366
+ const mg = new Miniget(source, {
367
+ headers: {
368
+ "Accept": "*/*",
369
+ "User-Agent": "Mozilla/5.0 (Linux; Android 6.0.1; SM-J500G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Mobile Safari/537.36",
370
+ "Referrer-Policy": "strict-origin-when-cross-origin",
371
+ "sec-ch-ua": '"Chromium";v="107", "Not=A?Brand";v="24"',
372
+ "sec-ch-ua-platform": "Android",
373
+ "sec-fetch-dest": "empty",
374
+ "sec-fetch-mode": "cors",
375
+ "sec-fetch-site": "same-origin",
376
+ ...options
377
+ }
378
+ })
379
+ mg.on('response', (response) => {
380
+ if (response.statusCode !== 200) {
381
+ resolve({
382
+ status: false,
383
+ msg: `[${response.statusCode}] : Error while gwtting file`
384
+ })
385
+ return
386
+ }
387
+ const extension = filename ? filename.split`.` [filename.split`.`.length - 1] : mime.extension(response.headers['content-type'])
388
+ const file = fs.createWriteStream(`temp/${this.uuid() + '.' + extension}`)
389
+ const name = filename || path.basename(file.path)
390
+ const transformStream = new stream.Transform({
391
+ transform(chunk, encoding, callback) {
392
+ callback(null, chunk)
393
+ }
394
+ })
395
+ mg.pipe(transformStream).pipe(file)
396
+ file.on('finish', () => {
397
+ const data = {
398
+ status: true,
399
+ file: file.path,
400
+ filename: name,
401
+ mime: mime.lookup(file.path),
402
+ extension: extension,
403
+ size: this.formatSize(response.headers['content-length'] ? response.headers['content-length'] : 0),
404
+ bytes: response.headers['content-length'] ? parseInt(response.headers['content-length']) : 0,
405
+ headers: response.headers
406
+ }
407
+ resolve(data)
408
+ })
409
+ .on('error', (error) => {
410
+ resolve({
411
+ status: false,
412
+ msg: `Error when getting the file`
413
+ })
414
+ })
415
+ })
416
+ })
417
+ }
418
+ } catch (e) {
419
+ return ({
420
+ status: false,
421
+ msg: e.message
422
+ })
423
+ }
424
+ }
425
+
426
+ /* Generate Color
427
+ * @param {String} text
428
+ * @param {String} color
429
+ */
430
+ color = (text, color) => {
431
+ return chalk.keyword(color || 'green').bold(text)
432
+ }
433
+
434
+ /* Get Message Type
435
+ * @param {String|Object} data
436
+ */
437
+ mtype = (data) => {
438
+ function replaceAll(str) {
439
+ let res = str.replace(new RegExp('```', 'g'), '')
440
+ .replace(new RegExp('_', 'g'), '')
441
+ .replace(new RegExp(/[*]/, 'g'), '')
442
+ return res
443
+ }
444
+ let type = (typeof data.text !== 'object') ? replaceAll(data.text) : ''
445
+ return type
446
+ }
447
+
448
+ /* Size Limitation
449
+ * @param {String} str
450
+ * @param {Integer} max
451
+ */
452
+ sizeLimit = (str, max) => {
453
+ let data
454
+ if (str.match('G') || str.match('GB') || str.match('T') || str.match('TB')) return data = {
455
+ oversize: true
456
+ }
457
+ if (str.match('M') || str.match('MB')) {
458
+ let first = str.replace(/MB|M|G|T/g, '').trim()
459
+ if (isNaN(first)) return data = {
460
+ oversize: true
461
+ }
462
+ if (first > max) return data = {
463
+ oversize: true
464
+ }
465
+ return data = {
466
+ oversize: false
467
+ }
468
+ } else {
469
+ return data = {
470
+ oversize: false
471
+ }
472
+ }
473
+ }
474
+
475
+ /* Link Extractor
476
+ * @param {String} text
477
+ */
478
+ generateLink = (text) => {
479
+ let regex = /(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/gi;
480
+ return text.match(regex)
481
+ }
482
+
483
+ /* File Reloader
484
+ * @param {String} file
485
+ */
486
+ reload = (file) => {
487
+ fs.watchFile(file, () => {
488
+ fs.unwatchFile(file)
489
+ console.log(redBright.bold('[ UPDATE ]'), blueBright(moment(new Date() * 1).format('DD/MM/YY HH:mm:ss')), green.bold('~ ' + path.basename(file)))
490
+ delete require.cache[file]
491
+ require(file)
492
+ })
493
+ }
494
+
495
+ /* File Reloader V2
496
+ * @param {String} file
497
+ */
498
+ updateFile = file => {
499
+ const watcher = fs.watch(file, (eventType, filename) => {
500
+ fs.unwatchFile(file)
501
+ if (eventType === 'change') {
502
+ console.log(redBright.bold('[ UPDATE ]'), blueBright(moment(new Date() * 1).format('DD/MM/YY HH:mm:ss')), green.bold('~ ' + path.basename(file)))
503
+ delete require.cache[require.resolve(file)]
504
+ require(file)
505
+ }
506
+ })
507
+
508
+ process.on('exit', () => {
509
+ watcher.close()
510
+ })
511
+ }
512
+
513
+ /* File Reloader V2
514
+ * @param {String} file
515
+ */
516
+
517
+
518
+ /* Print JSON
519
+ * @param {Object} obj
520
+ */
521
+ jsonFormat = (obj) => {
522
+ try {
523
+ let print = (obj && (obj.constructor.name == 'Object' || obj.constructor.name == 'Array')) ? require('util').format(JSON.stringify(obj, null, 2)) : require('util').format(obj)
524
+ return print
525
+ } catch {
526
+ return require('util').format(obj)
527
+ }
528
+ }
529
+
530
+ /* Ucword Format
531
+ * @param {String} str
532
+ */
533
+ ucword = (str) => {
534
+ return (str + '').replace(/^([a-z])|\s+([a-z])/g, function($1) {
535
+ return $1.toUpperCase();
536
+ })
537
+ }
538
+
539
+ /* Next Level Array Concat
540
+ * @param {Array} arr
541
+ */
542
+ arrayJoin = (arr) => {
543
+ var construct = []
544
+ for (var i = 0; i < arr.length; i++) construct = construct.concat(arr[i])
545
+ return construct
546
+ }
547
+
548
+ /* Remove Element Form Array
549
+ * @param {Array} arr
550
+ * @param {String} value
551
+ */
552
+ removeItem = (arr, value) => {
553
+ let index = arr.indexOf(value)
554
+ if (index > -1) arr.splice(index, 1)
555
+ return arr
556
+ }
557
+
558
+ /* Hitstat
559
+ * @param {String} cmd
560
+ * @param {String} who
561
+ */
562
+ hitstat = (cmd, who) => {
563
+ if (/bot|help|menu|stat|hitstat|hitdaily/.test(cmd)) return
564
+ if (typeof global.db == 'undefined') return
565
+ global.db.statistic = global.db.statistic ? global.db.statistic : {}
566
+ if (!global.db.statistic[cmd]) {
567
+ global.db.statistic[cmd] = {
568
+ hitstat: 1,
569
+ today: 1,
570
+ lasthit: new Date * 1,
571
+ sender: who.split`@` [0]
572
+ }
573
+ } else {
574
+ global.db.statistic[cmd].hitstat += 1
575
+ global.db.statistic[cmd].today += 1
576
+ global.db.statistic[cmd].lasthit = new Date * 1
577
+ global.db.statistic[cmd].sender = who.split`@` [0]
578
+ }
579
+ }
580
+
581
+ /* Socmed Link Validator
582
+ * @param {String} url
583
+ */
584
+ socmed = (url) => {
585
+ const regex = [
586
+ /^(?:https?:\/\/(web\.|www\.|m\.)?(facebook|fb)\.(com|watch)\S+)?$/,
587
+ /^(?:https?:\/\/)?(?:www\.)?(?:instagram\.com\/)(?:tv\/|p\/|reel\/)(?:\S+)?$/,
588
+ /^(?:https?:\/\/)?(?:www\.)?(?:instagram\.com\/)(?:stories\/)(?:\S+)?$/,
589
+ /^(?:https?:\/\/)?(?:www\.)?(?:instagram\.com\/)(?:s\/)(?:\S+)?$/,
590
+ /^(?:https?:\/\/)?(?:www\.)?(?:mediafire\.com\/)(?:\S+)?$/,
591
+ /pin(?:terest)?(?:\.it|\.com)/,
592
+ /^(?:https?:\/\/)?(?:www\.|vt\.|vm\.|t\.)?(?:tiktok\.com\/)(?:\S+)?$/,
593
+ /http(?:s)?:\/\/(?:www\.|mobile\.)?twitter\.com\/([a-zA-Z0-9_]+)/,
594
+ /^(?:https?:\/\/)?(?:www\.|m\.|music\.)?youtu\.?be(?:\.com)?\/?.*(?:watch|embed)?(?:.*v=|v\/|\/)([\w\-_]+)\&?/,
595
+ /^(?:https?:\/\/)?(?:podcasts\.)?(?:google\.com\/)(?:feed\/)(?:\S+)?$/
596
+ ]
597
+ return regex.some(v => url.match(v))
598
+ }
599
+
600
+ /* Did You Mean ??
601
+ * @param {String} string
602
+ * @param {Array} array
603
+ * @param {String|Object} options
604
+ */
605
+ matcher = (string, array, options) => {
606
+ function levenshtein(value, other, insensitive) {
607
+ var cache = []
608
+ var codes = []
609
+ var length
610
+ var lengthOther
611
+ var code
612
+ var result
613
+ var distance
614
+ var distanceOther
615
+ var index
616
+ var indexOther
617
+
618
+ if (value === other) {
619
+ return 0
620
+ }
621
+
622
+ length = value.length
623
+ lengthOther = other.length
624
+
625
+ if (length === 0) {
626
+ return lengthOther
627
+ }
628
+
629
+ if (lengthOther === 0) {
630
+ return length
631
+ }
632
+
633
+ if (insensitive) {
634
+ value = value.toLowerCase()
635
+ other = other.toLowerCase()
636
+ }
637
+
638
+ index = 0
639
+
640
+ while (index < length) {
641
+ codes[index] = value.charCodeAt(index)
642
+ cache[index] = ++index
643
+ }
644
+
645
+ indexOther = 0
646
+
647
+ while (indexOther < lengthOther) {
648
+ code = other.charCodeAt(indexOther)
649
+ result = distance = indexOther++
650
+ index = -1
651
+
652
+ while (++index < length) {
653
+ distanceOther = code === codes[index] ? distance : distance + 1
654
+ distance = cache[index]
655
+ cache[index] = result =
656
+ distance > result ?
657
+ distanceOther > result ?
658
+ result + 1 :
659
+ distanceOther :
660
+ distanceOther > distance ?
661
+ distance + 1 :
662
+ distanceOther
663
+ }
664
+ }
665
+ return result
666
+ }
667
+
668
+ function similarity(a, b, options) {
669
+ var left = a || ''
670
+ var right = b || ''
671
+ var insensitive = !(options || {}).sensitive
672
+ var longest = Math.max(left.length, right.length)
673
+ return ((longest === 0 ?
674
+ 1 :
675
+ (longest - levenshtein(left, right, insensitive)) / longest) * 100).toFixed(1)
676
+ }
677
+
678
+ let data = []
679
+ let isArray = array.constructor.name == 'Array' ? array : [array] || []
680
+ isArray.map(v => data.push({
681
+ string: v,
682
+ accuracy: similarity(string, v)
683
+ }))
684
+ return data
685
+ }
686
+
687
+ /* Miliseconds to Date
688
+ * @param {Integer} ms
689
+ */
690
+ toDate = (ms) => {
691
+ let temp = ms
692
+ let days = Math.floor(ms / (24 * 60 * 60 * 1000));
693
+ let daysms = ms % (24 * 60 * 60 * 1000);
694
+ let hours = Math.floor((daysms) / (60 * 60 * 1000));
695
+ let hoursms = ms % (60 * 60 * 1000);
696
+ let minutes = Math.floor((hoursms) / (60 * 1000));
697
+ let minutesms = ms % (60 * 1000);
698
+ let sec = Math.floor((minutesms) / (1000));
699
+ if (days == 0 && hours == 0 && minutes == 0) {
700
+ return "Recently"
701
+ } else {
702
+ return days + "D " + hours + "H " + minutes + "M";
703
+ }
704
+ }
705
+
706
+ /* Time Formater
707
+ * @param {Integer} value
708
+ */
709
+ timeFormat = (value) => {
710
+ const sec = parseInt(value, 10)
711
+ let hours = Math.floor(sec / 3600)
712
+ let minutes = Math.floor((sec - (hours * 3600)) / 60)
713
+ let seconds = sec - (hours * 3600) - (minutes * 60)
714
+ if (hours < 10) hours = '0' + hours
715
+ if (minutes < 10) minutes = '0' + minutes
716
+ if (seconds < 10) seconds = '0' + seconds
717
+ if (hours == parseInt('00')) return minutes + ':' + seconds
718
+ return hours + ':' + minutes + ':' + seconds
719
+ }
720
+
721
+ /* Switcher
722
+ * @param {Boolen} status
723
+ * @param {String} isTrue
724
+ * @param {String} isFalse
725
+ */
726
+ switcher = (status, isTrue, isFalse) => {
727
+ return (status) ? this.texted('bold', isTrue) : this.texted('bold', isFalse)
728
+ }
729
+
730
+ /* Random ID
731
+ * @param {Integer} length
732
+ */
733
+ makeId = (length) => {
734
+ var result = ''
735
+ var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
736
+ var charactersLength = characters.length
737
+ for (var i = 0; i < length; i++) {
738
+ result += characters.charAt(Math.floor(Math.random() * charactersLength))
739
+ }
740
+ return result
741
+ }
742
+
743
+ /* Timeout
744
+ * @param {Integer} ms
745
+ */
746
+ timeReverse = (duration) => {
747
+ let milliseconds = parseInt((duration % 1000) / 100),
748
+ seconds = Math.floor((duration / 1000) % 60),
749
+ minutes = Math.floor((duration / (1000 * 60)) % 60),
750
+ hours = Math.floor((duration / (1000 * 60 * 60)) % 24),
751
+ days = Math.floor(duration / (24 * 60 * 60 * 1000))
752
+ let hoursF = (hours < 10) ? "0" + hours : hours
753
+ let minutesF = (minutes < 10) ? "0" + minutes : minutes
754
+ let secondsF = (seconds < 10) ? "0" + seconds : seconds
755
+ let daysF = (days < 10) ? "0" + days : days
756
+ // return hours + " Jam " + minutes + " Menit" + seconds + " Detik" + milliseconds;
757
+ return daysF + "D " + hoursF + "H " + minutesF + "M"
758
+ }
759
+
760
+ /* Timeout
761
+ * @param ()
762
+ */
763
+ greeting = () => {
764
+ let time = moment.tz(process.env.TZ || 'Asia/Jakarta').format('HH')
765
+ let res = `Don't forget to sleep`
766
+ if (time >= 3) res = `Good Evening`
767
+ if (time > 6) res = `Good Morning`
768
+ if (time >= 11) res = `Good Afternoon`
769
+ if (time >= 18) res = `Good Night`
770
+ return res
771
+ }
772
+
773
+ /* Random JSON From File
774
+ * @param ()
775
+ */
776
+ jsonRandom = (file) => {
777
+ let json = JSON.parse(fs.readFileSync(file))
778
+ return json[Math.floor(Math.random() * json.length)]
779
+ }
780
+
781
+ /* Leveling
782
+ * @param {Integer} xp
783
+ * @param {Integer} multiplier
784
+ */
785
+ level = (xp, multiplier = 5) => {
786
+ var XPAsli = xp
787
+ var level = 1
788
+ while (xp > 1) {
789
+ xp /= multiplier
790
+ if (xp < 1) {
791
+ level == level
792
+ } else {
793
+ level += 1
794
+ }
795
+ }
796
+ var XPLevel = 1
797
+ while (XPAsli >= XPLevel) {
798
+ XPLevel = XPLevel + XPLevel
799
+ }
800
+ var sisaXP = XPLevel - XPAsli
801
+ if (sisaXP == 0) sisaXP = XPLevel + XPLevel
802
+ let kurang = XPLevel - sisaXP
803
+ return [level, XPLevel, sisaXP, kurang]
804
+ }
805
+
806
+ /* Leveling V2
807
+ * @param {Integer} xp
808
+ * @param {Integer} multiplier
809
+ * @param {Integer} def
810
+ */
811
+ leveling = (xp, multiplier, def = 87200) => {
812
+ const xpLevel1 = def * Number(multiplier)
813
+ let currentLevel = (xp <= xpLevel1) ? 1 : Math.floor(xp / xpLevel1)
814
+ let nextLevel = currentLevel + 1
815
+ let xpToLevelUp = xpLevel1 * nextLevel
816
+ let remainingXp = xpToLevelUp - xp
817
+ let result = {
818
+ currentXp: xp,
819
+ currentLevel: currentLevel,
820
+ nextLevel: nextLevel,
821
+ xpToLevelUp: xpToLevelUp,
822
+ remainingXp: remainingXp,
823
+ }
824
+ return result
825
+ }
826
+
827
+ /* Roles
828
+ * @param {Integer} level
829
+ */
830
+ role = (level) => {
831
+ let roles = '-'
832
+ if (level <= 2) {
833
+ roles = 'Newbie ㋡'
834
+ } else if (level <= 4) {
835
+ roles = 'Beginner Grade 1 ⚊¹'
836
+ } else if (level <= 6) {
837
+ roles = 'Beginner Grade 2 ⚊²'
838
+ } else if (level <= 8) {
839
+ roles = 'Beginner Grade 3 ⚊³'
840
+ } else if (level <= 10) {
841
+ roles = 'Beginner Grade 4 ⚊⁴'
842
+ } else if (level <= 12) {
843
+ roles = 'Private Grade 1 ⚌¹'
844
+ } else if (level <= 14) {
845
+ roles = 'Private Grade 2 ⚌²'
846
+ } else if (level <= 16) {
847
+ roles = 'Private Grade 3 ⚌³'
848
+ } else if (level <= 18) {
849
+ roles = 'Private Grade 4 ⚌⁴'
850
+ } else if (level <= 20) {
851
+ roles = 'Private Grade 5 ⚌⁵'
852
+ } else if (level <= 22) {
853
+ roles = 'Corporal Grade 1 ☰¹'
854
+ } else if (level <= 24) {
855
+ roles = 'Corporal Grade 2 ☰²'
856
+ } else if (level <= 26) {
857
+ roles = 'Corporal Grade 3 ☰³'
858
+ } else if (level <= 28) {
859
+ roles = 'Corporal Grade 4 ☰⁴'
860
+ } else if (level <= 30) {
861
+ roles = 'Corporal Grade 5 ☰⁵'
862
+ } else if (level <= 32) {
863
+ roles = 'Sergeant Grade 1 ≣¹'
864
+ } else if (level <= 34) {
865
+ roles = 'Sergeant Grade 2 ≣²'
866
+ } else if (level <= 36) {
867
+ roles = 'Sergeant Grade 3 ≣³'
868
+ } else if (level <= 38) {
869
+ roles = 'Sergeant Grade 4 ≣⁴'
870
+ } else if (level <= 40) {
871
+ roles = 'Sergeant Grade 5 ≣⁵'
872
+ } else if (level <= 42) {
873
+ roles = 'Staff Grade 1 ﹀¹'
874
+ } else if (level <= 44) {
875
+ roles = 'Staff Grade 2 ﹀²'
876
+ } else if (level <= 46) {
877
+ roles = 'Staff Grade 3 ﹀³'
878
+ } else if (level <= 48) {
879
+ roles = 'Staff Grade 4 ﹀⁴'
880
+ } else if (level <= 50) {
881
+ roles = 'Staff Grade 5 ﹀⁵'
882
+ } else if (level <= 52) {
883
+ roles = 'Sergeant Grade 1 ︾¹'
884
+ } else if (level <= 54) {
885
+ roles = 'Sergeant Grade 2 ︾²'
886
+ } else if (level <= 56) {
887
+ roles = 'Sergeant Grade 3 ︾³'
888
+ } else if (level <= 58) {
889
+ roles = 'Sergeant Grade 4 ︾⁴'
890
+ } else if (level <= 60) {
891
+ roles = 'Sergeant Grade 5 ︾⁵'
892
+ } else if (level <= 62) {
893
+ roles = '2nd Lt. Grade 1 ♢¹ '
894
+ } else if (level <= 64) {
895
+ roles = '2nd Lt. Grade 2 ♢²'
896
+ } else if (level <= 66) {
897
+ roles = '2nd Lt. Grade 3 ♢³'
898
+ } else if (level <= 68) {
899
+ roles = '2nd Lt. Grade 4 ♢⁴'
900
+ } else if (level <= 70) {
901
+ roles = '2nd Lt. Grade 5 ♢⁵'
902
+ } else if (level <= 72) {
903
+ roles = '1st Lt. Grade 1 ♢♢¹'
904
+ } else if (level <= 74) {
905
+ roles = '1st Lt. Grade 2 ♢♢²'
906
+ } else if (level <= 76) {
907
+ roles = '1st Lt. Grade 3 ♢♢³'
908
+ } else if (level <= 78) {
909
+ roles = '1st Lt. Grade 4 ♢♢⁴'
910
+ } else if (level <= 80) {
911
+ roles = '1st Lt. Grade 5 ♢♢⁵'
912
+ } else if (level <= 82) {
913
+ roles = 'Major Grade 1 ✷¹'
914
+ } else if (level <= 84) {
915
+ roles = 'Major Grade 2 ✷²'
916
+ } else if (level <= 86) {
917
+ roles = 'Major Grade 3 ✷³'
918
+ } else if (level <= 88) {
919
+ roles = 'Major Grade 4 ✷⁴'
920
+ } else if (level <= 90) {
921
+ roles = 'Major Grade 5 ✷⁵'
922
+ } else if (level <= 92) {
923
+ roles = 'Colonel Grade 1 ✷✷¹'
924
+ } else if (level <= 94) {
925
+ roles = 'Colonel Grade 2 ✷✷²'
926
+ } else if (level <= 96) {
927
+ roles = 'Colonel Grade 3 ✷✷³'
928
+ } else if (level <= 98) {
929
+ roles = 'Colonel Grade 4 ✷✷⁴'
930
+ } else if (level <= 100) {
931
+ roles = 'Colonel Grade 5 ✷✷⁵'
932
+ } else if (level <= 102) {
933
+ roles = 'Brigadier Early ✰'
934
+ } else if (level <= 104) {
935
+ roles = 'Brigadier Silver ✩'
936
+ } else if (level <= 106) {
937
+ roles = 'Brigadier gold ✯'
938
+ } else if (level <= 108) {
939
+ roles = 'Brigadier Platinum ✬'
940
+ } else if (level <= 110) {
941
+ roles = 'Brigadier Diamond ✪'
942
+ } else if (level <= 112) {
943
+ roles = 'Major General Early ✰'
944
+ } else if (level <= 114) {
945
+ roles = 'Major General Silver ✩'
946
+ } else if (level <= 116) {
947
+ roles = 'Major General gold ✯'
948
+ } else if (level <= 118) {
949
+ roles = 'Major General Platinum ✬'
950
+ } else if (level <= 120) {
951
+ roles = 'Major General Diamond ✪'
952
+ } else if (level <= 122) {
953
+ roles = 'Lt. General Early ✰'
954
+ } else if (level <= 124) {
955
+ roles = 'Lt. General Silver ✩'
956
+ } else if (level <= 126) {
957
+ roles = 'Lt. General gold ✯'
958
+ } else if (level <= 128) {
959
+ roles = 'Lt. General Platinum ✬'
960
+ } else if (level <= 130) {
961
+ roles = 'Lt. General Diamond ✪'
962
+ } else if (level <= 132) {
963
+ roles = 'General Early ✰'
964
+ } else if (level <= 134) {
965
+ roles = 'General Silver ✩'
966
+ } else if (level <= 136) {
967
+ roles = 'General gold ✯'
968
+ } else if (level <= 138) {
969
+ roles = 'General Platinum ✬'
970
+ } else if (level <= 140) {
971
+ roles = 'General Diamond ✪'
972
+ } else if (level <= 142) {
973
+ roles = 'Commander Early ★'
974
+ } else if (level <= 144) {
975
+ roles = 'Commander Intermediate ⍣'
976
+ } else if (level <= 146) {
977
+ roles = 'Commander Elite ≛'
978
+ } else if (level <= 148) {
979
+ roles = 'The Commander Hero ⍟'
980
+ } else if (level <= 152) {
981
+ roles = 'Legends 忍'
982
+ } else if (level <= 154) {
983
+ roles = 'Legends 忍'
984
+ } else if (level <= 156) {
985
+ roles = 'Legends 忍'
986
+ } else if (level <= 158) {
987
+ roles = 'Legends 忍'
988
+ } else if (level <= 160) {
989
+ roles = 'Legends 忍'
990
+ } else if (level <= 162) {
991
+ roles = 'Legends 忍'
992
+ } else if (level <= 164) {
993
+ roles = 'Legends 忍'
994
+ } else if (level <= 166) {
995
+ roles = 'Legends 忍'
996
+ } else if (level <= 168) {
997
+ roles = 'Legends 忍'
998
+ } else if (level <= 170) {
999
+ roles = 'Legends 忍'
1000
+ } else if (level <= 172) {
1001
+ roles = 'Legends 忍'
1002
+ } else if (level <= 174) {
1003
+ roles = 'Legends 忍'
1004
+ } else if (level <= 176) {
1005
+ roles = 'Legends 忍'
1006
+ } else if (level <= 178) {
1007
+ roles = 'Legends 忍'
1008
+ } else if (level <= 180) {
1009
+ roles = 'Legends 忍'
1010
+ } else if (level <= 182) {
1011
+ roles = 'Legends 忍'
1012
+ } else if (level <= 184) {
1013
+ roles = 'Legends 忍'
1014
+ } else if (level <= 186) {
1015
+ roles = 'Legends 忍'
1016
+ } else if (level <= 188) {
1017
+ roles = 'Legends 忍'
1018
+ } else if (level <= 190) {
1019
+ roles = 'Legends 忍'
1020
+ } else if (level <= 192) {
1021
+ roles = 'Legends 忍'
1022
+ } else if (level <= 194) {
1023
+ roles = 'Legends 忍'
1024
+ } else if (level <= 196) {
1025
+ roles = 'Legends 忍'
1026
+ } else if (level <= 198) {
1027
+ roles = 'Legends 忍'
1028
+ } else if (level <= 200) {
1029
+ roles = 'Legends 忍'
1030
+ } else if (level <= 210) {
1031
+ roles = 'Legends 忍'
1032
+ } else if (level <= 220) {
1033
+ roles = 'Legends 忍'
1034
+ } else if (level <= 230) {
1035
+ roles = 'Legends 忍'
1036
+ } else if (level <= 240) {
1037
+ roles = 'Legends 忍'
1038
+ } else if (level <= 250) {
1039
+ roles = 'Legends 忍'
1040
+ } else if (level <= 260) {
1041
+ roles = 'Legends 忍'
1042
+ } else if (level <= 270) {
1043
+ roles = 'Legends 忍'
1044
+ } else if (level <= 280) {
1045
+ roles = 'Legends 忍'
1046
+ } else if (level <= 290) {
1047
+ roles = 'Legends 忍'
1048
+ } else if (level <= 300) {
1049
+ roles = 'Legends 忍'
1050
+ } else if (level <= 310) {
1051
+ roles = 'Legends 忍'
1052
+ } else if (level <= 320) {
1053
+ roles = 'Legends 忍'
1054
+ } else if (level <= 330) {
1055
+ roles = 'Legends 忍'
1056
+ } else if (level <= 340) {
1057
+ roles = 'Legends 忍'
1058
+ } else if (level <= 350) {
1059
+ roles = 'Legends 忍'
1060
+ } else if (level <= 360) {
1061
+ roles = 'Legends 忍'
1062
+ } else if (level <= 370) {
1063
+ roles = 'Legends 忍'
1064
+ } else if (level <= 380) {
1065
+ roles = 'Legends 忍'
1066
+ } else if (level <= 390) {
1067
+ roles = 'Legends 忍'
1068
+ } else if (level <= 400) {
1069
+ roles = 'Legends 忍'
1070
+ } else if (level <= 410) {
1071
+ roles = 'Legends 忍'
1072
+ } else if (level <= 420) {
1073
+ roles = 'Legends 忍'
1074
+ } else if (level <= 430) {
1075
+ roles = 'Legends 忍'
1076
+ } else if (level <= 440) {
1077
+ roles = 'Legends 忍'
1078
+ } else if (level <= 450) {
1079
+ roles = 'Legends 忍'
1080
+ } else if (level <= 460) {
1081
+ roles = 'Legends 忍'
1082
+ } else if (level <= 470) {
1083
+ roles = 'Legends 忍'
1084
+ } else if (level <= 480) {
1085
+ roles = 'Legends 忍'
1086
+ } else if (level <= 490) {
1087
+ roles = 'Legends 忍'
1088
+ } else if (level <= 500) {
1089
+ roles = 'Legends 忍'
1090
+ } else if (level <= 600) {
1091
+ roles = 'Legends 忍'
1092
+ } else if (level <= 700) {
1093
+ roles = 'Legends 忍'
1094
+ } else if (level <= 800) {
1095
+ roles = 'Legends 忍'
1096
+ } else if (level <= 900) {
1097
+ roles = 'Legends 忍'
1098
+ } else if (level <= 1000) {
1099
+ roles = 'Legends 忍'
1100
+ } else if (level <= 2000) {
1101
+ roles = 'Legends 忍'
1102
+ } else if (level <= 3000) {
1103
+ roles = 'Legends 忍'
1104
+ } else if (level <= 4000) {
1105
+ roles = 'Legends 忍'
1106
+ } else if (level <= 5000) {
1107
+ roles = 'Legends 忍'
1108
+ } else if (level <= 6000) {
1109
+ roles = 'Legends 忍'
1110
+ } else if (level <= 7000) {
1111
+ roles = 'Legends 忍'
1112
+ } else if (level <= 8000) {
1113
+ roles = 'Legends 忍'
1114
+ } else if (level <= 9000) {
1115
+ roles = 'Legends 忍'
1116
+ } else if (level <= 10000) {
1117
+ roles = 'Legends 忍'
1118
+ }
1119
+ return roles
1120
+ }
1121
+
1122
+ /* Text Cutter
1123
+ * @param {String} text
1124
+ */
1125
+ filter = (text) => {
1126
+ if (text.length > 10) {
1127
+ return text.substr(text.length - 5)
1128
+ } else if (text.length > 7) {
1129
+ return text.substr(text.length - 4)
1130
+ } else if (text.length > 5) {
1131
+ return text.substr(text.length - 3)
1132
+ } else if (text.length > 2) {
1133
+ return text.substr(text.length - 2)
1134
+ } else if (text.length > 1) {
1135
+ return text.substr(text.length - 1)
1136
+ }
1137
+ }
1138
+
1139
+ /* Random String
1140
+ * @param {String} text
1141
+ */
1142
+ randomString = (len, charSet) => {
1143
+ charSet = charSet || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789/+=*-%$();?!#@';
1144
+ var randomString = '';
1145
+ for (var i = 0; i < len; i++) {
1146
+ var randomPoz = Math.floor(Math.random() * charSet.length);
1147
+ randomString += charSet.substring(randomPoz, randomPoz + 1);
1148
+ }
1149
+ return randomString
1150
+ }
1151
+
1152
+ /* Remove Emoji
1153
+ * @param {String} string
1154
+ */
1155
+ removeEmojis = (string) => {
1156
+ var regex = /(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|\ud83c[\ude32-\ude3a]|\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])/g;
1157
+ return string.replace(regex, '')
1158
+ }
1159
+
1160
+ /* Image Resizer
1161
+ * @param {Buffer} buffer
1162
+ * @param {Integer} x
1163
+ * @param {Integer} y
1164
+ */
1165
+ reSize = async (buffer, x, z) => {
1166
+ return new Promise(async (resolve, reject) => {
1167
+ var buff = await read(buffer)
1168
+ var ab = await buff.resize(x, z).getBufferAsync(MIME_JPEG)
1169
+ resolve(ab)
1170
+ })
1171
+ }
1172
+
1173
+ /* Text Style
1174
+ * @param {String} text
1175
+ * @param {Integer} style
1176
+ */
1177
+ Styles = (text, style = 1) => {
1178
+ var xStr = 'abcdefghijklmnopqrstuvwxyz1234567890'.split('')
1179
+ var yStr = Object.freeze({
1180
+ 1: 'ᴀʙᴄᴅᴇꜰɢʜɪᴊᴋʟᴍɴᴏᴘqʀꜱᴛᴜᴠᴡxʏᴢ1234567890'
1181
+ })
1182
+ var replacer = []
1183
+ xStr.map((v, i) => replacer.push({
1184
+ original: v,
1185
+ convert: yStr[style].split('')[i]
1186
+ }))
1187
+ var str = text.toLowerCase().split('')
1188
+ var output = []
1189
+ str.map(v => {
1190
+ const find = replacer.find(x => x.original == v)
1191
+ find ? output.push(find.convert) : output.push(v)
1192
+ })
1193
+ return output.join('')
1194
+ }
1195
+
1196
+ /* Log File
1197
+ * @param {String} log
1198
+ * @param {String} filename
1199
+ */
1200
+ logFile = (log, filename = 'bot') => {
1201
+ const log_file = fs.createWriteStream(path.join(process.cwd(), `${filename}.log`), {
1202
+ flags: 'a'
1203
+ })
1204
+ const time = moment(new Date() * 1).format('DD/MM/YY HH:mm:ss')
1205
+ log_file.write(`[${time}] - ${log}\n`)
1206
+ }
1207
+
1208
+ /* Get Emoji from String
1209
+ * @param {String} str
1210
+ */
1211
+ getEmoji = str => {
1212
+ const regex = /[#*0-9]\uFE0F?\u20E3|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26AA\u26B0\u26B1\u26BD\u26BE\u26C4\u26C8\u26CF\u26D1\u26E9\u26F0-\u26F5\u26F7\u26F8\u26FA\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B55\u3030\u303D\u3297\u3299]\uFE0F?|[\u261D\u270C\u270D](?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u23E9-\u23EC\u23F0\u23F3\u25FD\u2693\u26A1\u26AB\u26C5\u26CE\u26D4\u26EA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2795-\u2797\u27B0\u27BF\u2B50]|\u26D3\uFE0F?(?:\u200D\uD83D\uDCA5)?|\u26F9(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|\u2764\uFE0F?(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|\uD83C(?:[\uDC04\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]\uFE0F?|[\uDF85\uDFC2\uDFC7](?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC4\uDFCA](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDFCB\uDFCC](?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF43\uDF45-\uDF4A\uDF4C-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDF44(?:\u200D\uD83D\uDFEB)?|\uDF4B(?:\u200D\uD83D\uDFE9)?|\uDFC3(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDFF3\uFE0F?(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?)|\uD83D(?:[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3]\uFE0F?|[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4\uDEB5](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD74\uDD90](?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?|[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC25\uDC27-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE41\uDE43\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEDC-\uDEDF\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uDC08(?:\u200D\u2B1B)?|\uDC15(?:\u200D\uD83E\uDDBA)?|\uDC26(?:\u200D(?:\u2B1B|\uD83D\uDD25))?|\uDC3B(?:\u200D\u2744\uFE0F?)?|\uDC41\uFE0F?(?:\u200D\uD83D\uDDE8\uFE0F?)?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?))|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE])))?))?|\uDC6F(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDD75(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDE2E(?:\u200D\uD83D\uDCA8)?|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?|\uDE42(?:\u200D[\u2194\u2195]\uFE0F?)?|\uDEB6(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?)|\uD83E(?:[\uDD0C\uDD0F\uDD18-\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5\uDEC3-\uDEC5\uDEF0\uDEF2-\uDEF8](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD\uDDCF\uDDD4\uDDD6-\uDDDD](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD0D\uDD0E\uDD10-\uDD17\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCC\uDDD0\uDDE0-\uDDFF\uDE70-\uDE7C\uDE80-\uDE88\uDE90-\uDEBD\uDEBF-\uDEC2\uDECE-\uDEDB\uDEE0-\uDEE8]|\uDD3C(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF])?|\uDDCE(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1|\uDDD1\u200D\uD83E\uDDD2(?:\u200D\uD83E\uDDD2)?|\uDDD2(?:\u200D\uD83E\uDDD2)?))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?))?|\uDEF1(?:\uD83C(?:\uDFFB(?:\u200D\uD83E\uDEF2\uD83C[\uDFFC-\uDFFF])?|\uDFFC(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFD-\uDFFF])?|\uDFFD(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])?|\uDFFE(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFD\uDFFF])?|\uDFFF(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFE])?))?)/g
1213
+ return str.match(regex)
1214
+ }
1215
+
1216
+ /* Emoji Prefix Check
1217
+ * @param {String} str
1218
+ */
1219
+ isEmojiPrefix = str => {
1220
+ const regex = /^(?:[#*0-9]\uFE0F?\u20E3|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26AA\u26B0\u26B1\u26BD\u26BE\u26C4\u26C8\u26CF\u26D1\u26E9\u26F0-\u26F5\u26F7\u26F8\u26FA\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B55\u3030\u303D\u3297\u3299]\uFE0F?|[\u261D\u270C\u270D](?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u23E9-\u23EC\u23F0\u23F3\u25FD\u2693\u26A1\u26AB\u26C5\u26CE\u26D4\u26EA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2795-\u2797\u27B0\u27BF\u2B50]|\u26D3\uFE0F?(?:\u200D\uD83D\uDCA5)?|\u26F9(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|\u2764\uFE0F?(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|\uD83C(?:[\uDC04\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]\uFE0F?|[\uDF85\uDFC2\uDFC7](?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC4\uDFCA](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDFCB\uDFCC](?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF43\uDF45-\uDF4A\uDF4C-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDF44(?:\u200D\uD83D\uDFEB)?|\uDF4B(?:\u200D\uD83D\uDFE9)?|\uDFC3(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDFF3\uFE0F?(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?)|\uD83D(?:[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3]\uFE0F?|[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4\uDEB5](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD74\uDD90](?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?|[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC25\uDC27-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE41\uDE43\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEDC-\uDEDF\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uDC08(?:\u200D\u2B1B)?|\uDC15(?:\u200D\uD83E\uDDBA)?|\uDC26(?:\u200D(?:\u2B1B|\uD83D\uDD25))?|\uDC3B(?:\u200D\u2744\uFE0F?)?|\uDC41\uFE0F?(?:\u200D\uD83D\uDDE8\uFE0F?)?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?))|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE])))?))?|\uDC6F(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDD75(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDE2E(?:\u200D\uD83D\uDCA8)?|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?|\uDE42(?:\u200D[\u2194\u2195]\uFE0F?)?|\uDEB6(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?)|\uD83E(?:[\uDD0C\uDD0F\uDD18-\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5\uDEC3-\uDEC5\uDEF0\uDEF2-\uDEF8](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD\uDDCF\uDDD4\uDDD6-\uDDDD](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD0D\uDD0E\uDD10-\uDD17\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCC\uDDD0\uDDE0-\uDDFF\uDE70-\uDE7C\uDE80-\uDE88\uDE90-\uDEBD\uDEBF-\uDEC2\uDECE-\uDEDB\uDEE0-\uDEE8]|\uDD3C(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF])?|\uDDCE(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1|\uDDD1\u200D\uD83E\uDDD2(?:\u200D\uD83E\uDDD2)?|\uDDD2(?:\u200D\uD83E\uDDD2)?))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?))?|\uDEF1(?:\uD83C(?:\uDFFB(?:\u200D\uD83E\uDEF2\uD83C[\uDFFC-\uDFFF])?|\uDFFC(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFD-\uDFFF])?|\uDFFD(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])?|\uDFFE(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFD\uDFFF])?|\uDFFF(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFE])?))?))\w+/;
1221
+ return regex.test(str)
1222
+ }
1223
+
1224
+ /* Get Device
1225
+ * @param {String} id
1226
+ */
1227
+ getDevice = id => id.length > 21 ? 'Android' : id.substring(0, 2) === '3A' ? 'IOS' : 'WhatsApp Web'
1228
+ }