Fourstore commited on
Commit
7ca3fa4
·
verified ·
1 Parent(s): 2807ab9

Update endpoints/antibot.js

Browse files
Files changed (1) hide show
  1. endpoints/antibot.js +90 -67
endpoints/antibot.js CHANGED
@@ -1,89 +1,112 @@
1
- const Tesseract = require('tesseract.js');
2
- const { Jimp } = require('jimp');
3
- const fs = require('fs');
 
 
 
 
 
4
 
5
  function buf(b64) {
6
- if (!b64) return null;
7
- if (b64.startsWith("data:image")) b64 = b64.replace(/^data:image\/\w+;base64,/, "");
8
- return Buffer.from(b64, "base64");
9
  }
10
 
11
- function levenshtein(a, b) {
12
- const matrix = Array.from({ length: a.length + 1 }, (_, i) =>
13
- Array(b.length + 1).fill(0)
14
- );
15
- for (let i = 0; i <= a.length; i++) matrix[i][0] = i;
16
- for (let j = 0; j <= b.length; j++) matrix[0][j] = j;
17
- for (let i = 1; i <= a.length; i++) {
18
- for (let j = 1; j <= b.length; j++) {
19
- const cost = a[i - 1] === b[j - 1] ? 0 : 1;
20
- matrix[i][j] = Math.min(
21
- matrix[i - 1][j] + 1,
22
- matrix[i][j - 1] + 1,
23
- matrix[i - 1][j - 1] + cost
24
- );
25
- }
 
 
 
 
 
26
  }
27
- return matrix[a.length][b.length];
28
  }
29
 
30
- function similarity(a, b) {
31
- a = a.toLowerCase();
32
- b = b.toLowerCase();
33
- const distance = levenshtein(a, b);
34
- return 1 - distance / Math.max(a.length, b.length);
 
 
 
 
 
 
35
  }
36
 
37
- async function readTextFromImageBase64(b64) {
38
- const buffer = buf(b64);
39
- const image = await Jimp.read(buffer);
40
- image
41
- .greyscale()
42
- .contrast(0.5)
43
- .normalize()
44
- .resize({ w: 400 });
45
 
46
- const tempFile = `./temp_${Date.now()}.png`;
47
- await image.write(tempFile);
 
48
 
49
- const result = await Tesseract.recognize(tempFile, 'eng', {
50
- logger: m => {}
51
- });
 
 
 
 
52
 
53
- const text = result.data.text
54
- .replace(/\n/g, ' ')
55
- .replace(/[^a-zA-Z0-9 ]/g, '')
56
- .trim()
57
- .toLowerCase();
 
 
 
 
 
 
58
 
59
- fs.unlinkSync(tempFile);
60
- return text;
 
 
61
  }
62
 
63
  module.exports = async function (data) {
64
- const mainText = await readTextFromImageBase64(data.main || "");
65
- const mainWords = mainText.split(' ').filter(Boolean);
 
 
 
 
 
66
 
67
  const botResults = [];
68
- for (let i = 0; i < (data.bots || []).length; i++) {
69
- const bot = data.bots[i];
70
- const text = await readTextFromImageBase64(bot.img || "");
71
- botResults.push({ id: bot.id, text });
 
72
  }
73
 
74
- const order = [];
75
- for (const word of mainWords) {
76
- let bestMatch = { id: null, score: 0 };
77
- for (const bot of botResults) {
78
- const score = similarity(word, bot.text);
79
- if (score > bestMatch.score) bestMatch = { id: bot.id, score };
80
- }
81
- order.push(bestMatch.score > 0.5 ? bestMatch.id : null);
82
- }
83
 
84
- return {
85
- soal: mainWords,
86
- botResults,
87
- order: order.filter(id => id !== null)
88
- };
89
  };
 
1
+ const Tesseract = require("tesseract.js");
2
+ const fs = require("fs");
3
+ const path = require("path");
4
+
5
+ async function loadJimp() {
6
+ const jimp = await import("jimp");
7
+ return jimp.default;
8
+ }
9
 
10
  function buf(b64) {
11
+ return Buffer.from(b64.replace(/^data:image\/\w+;base64,/, ""), "base64");
 
 
12
  }
13
 
14
+ const SMALL = {
15
+ zero:0, one:1, two:2, three:3, four:4,
16
+ five:5, six:6, seven:7, eight:8, nine:9,
17
+ ten:10, eleven:11, twelve:12, thirteen:13, fourteen:14,
18
+ fifteen:15, sixteen:16, seventeen:17, eighteen:18, nineteen:19
19
+ };
20
+
21
+ const TENS = {
22
+ twenty:20, thirty:30, forty:40, fifty:50,
23
+ sixty:60, seventy:70, eighty:80, ninety:90
24
+ };
25
+
26
+ function wordsToNumber(words) {
27
+ let total = 0, current = 0;
28
+ for (let w of words) {
29
+ if (SMALL[w] !== undefined) current += SMALL[w];
30
+ else if (TENS[w] !== undefined) current += TENS[w];
31
+ else if (w === "hundred") current *= 100;
32
+ else if (w === "thousand") { total += current * 1000; current = 0; }
33
+ else if (w === "million") { total += current * 1000000; current = 0; }
34
  }
35
+ return total + current;
36
  }
37
 
38
+ function solveMath(tokens) {
39
+ const expr = tokens.join(" ")
40
+ .replace(/x/g, "*")
41
+ .replace(/times/g, "*")
42
+ .replace(/plus/g, "+")
43
+ .replace(/minus/g, "-")
44
+ .replace(/divide/g, "/")
45
+ .replace(/divided/g, "/");
46
+
47
+ try { return Function("return " + expr)(); }
48
+ catch { return null; }
49
  }
50
 
51
+ function normalizeWords(t) {
52
+ return t.replace(/[^a-z0-9 ]/g, " ")
53
+ .replace(/\s+/g, " ")
54
+ .trim()
55
+ .split(" ")
56
+ .filter(Boolean);
57
+ }
 
58
 
59
+ function convertSmart(tokens) {
60
+ if (tokens.every(x => /^[0-9]+$/.test(x)))
61
+ return parseInt(tokens.join(""));
62
 
63
+ if (tokens.every(x =>
64
+ SMALL[x] !== undefined ||
65
+ TENS[x] !== undefined ||
66
+ x === "hundred" ||
67
+ x === "thousand" ||
68
+ x === "million"
69
+ )) return wordsToNumber(tokens);
70
 
71
+ return solveMath(tokens);
72
+ }
73
+
74
+ async function readTextFromBase64(b64) {
75
+ const Jimp = await loadJimp();
76
+ const img = await Jimp.read(buf(b64));
77
+
78
+ img.greyscale().contrast(0.7).normalize().resize(500, Jimp.AUTO);
79
+
80
+ const tmp = path.join(__dirname, "tmp_" + Date.now() + ".png");
81
+ await img.write(tmp);
82
 
83
+ const res = await Tesseract.recognize(tmp, "eng", { logger: () => {} });
84
+ fs.unlinkSync(tmp);
85
+
86
+ return res.data.text.toLowerCase().replace(/[^a-z0-9 ]/g, " ").trim();
87
  }
88
 
89
  module.exports = async function (data) {
90
+ const mainText = await readTextFromBase64(data.main);
91
+ const tokens = normalizeWords(mainText);
92
+ const orderVal = convertSmart(tokens);
93
+
94
+ let orderNumbers = [];
95
+ if (typeof orderVal === "number" && !Number.isNaN(orderVal))
96
+ orderNumbers = [orderVal];
97
 
98
  const botResults = [];
99
+ for (let b of data.bots) {
100
+ const raw = await readTextFromBase64(b.img);
101
+ const t = normalizeWords(raw);
102
+ const val = convertSmart(t);
103
+ botResults.push({ id: b.id, number: Number.isNaN(val) ? null : val });
104
  }
105
 
106
+ const finalOrder = orderNumbers.map(n => {
107
+ const f = botResults.find(x => x.number === n);
108
+ return f ? f.id : null;
109
+ });
 
 
 
 
 
110
 
111
+ return { tokens, orderNumbers, botResults, result: finalOrder };
 
 
 
 
112
  };