-
Notifications
You must be signed in to change notification settings - Fork 2
/
worker.js
135 lines (135 loc) · 4.96 KB
/
worker.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
importScripts("data/jbo.js");
importScripts(
"latkerlo-jvotci/js/docs/data.js",
"latkerlo-jvotci/js/docs/rafsi.js",
"latkerlo-jvotci/js/docs/tarmi.js",
"latkerlo-jvotci/js/docs/tools.js",
"latkerlo-jvotci/js/docs/jvozba.js",
"latkerlo-jvotci/js/docs/katna.js"
);
var config;
function h(t) {
return t.replace(/[h‘’]/igu, "'");
}
// TODO: selmaho() - parse into ↓
function selmahois(x, y) {
const [xname, xdigit, xsub, xstar] = x;
const [yname, ydigit, ysub, ystar] = y;
return h(xname) == h(yname) && (xdigit == ydigit || xdigit == null) && (xsub == ysub || xsub == null) && (!xstar || ystar);
}
function getVowelsFrom(str) {
var vowels = str.toLowerCase();
vowels = vowels.replace(/(?<=[aeoy])i/g, "ĭ").replace(/(?<=[aeoy])u/g, "ŭ");
while (/[iu]/.test(vowels)) {
vowels = vowels
.replace(/i(?![aeiouyīū])/gu, "ī").replace(/u(?![aeiouyīū])/gu, "ū")
.replace(/i(?=[aeoyīū])/gu, "ị").replace(/u(?=[aeīoūy])/gu, "ụ");
}
if (config["rhyme.ignorey"])
vowels = vowels.replace(/[^aeiouĭŭīūịụ]/gu, "");
else
vowels = vowels.replace(/[^aeiouyĭŭīūịụ]/gu, "");
return vowels;
}
function xusegismu_zo(g) {
return /^[bcdfgjklmnprstvxz]([aeiou][bcdfgjklmnprstvxz]|[bcdfgjklmnprstvxz][aeiou])[bcdfgjklmnprstvxz][aeiou]$/.test(g);
}
function search(query) {
const original = query;
if (!config["regex"]) {
query = query.toLowerCase();
}
var results = [];
if (config["rhyme"]) {
const v = getVowelsFrom(query);
for (const entry of jbo) {
var text = getVowelsFrom(entry.word);
if (v != "" && text.endsWith(v)) {
results.push([entry, v.length - text.length]);
}
}
} else if (config["regex"]) {
var rgx;
try {
rgx = new RegExp(
config["regex.tight"] ? "^(" + query + ")$" : query,
config["regex.insensitive"] ? "i" : ""
);
} catch (e) {
return [];
}
for (const entry of jbo) {
if (rgx.test(entry.word)) {
results.push([entry, 1]);
}
}
} else if (/^[A-GI-PR-VX-Z][A-Gh'I-PR-VX-Zabc0-9*+]*$/.test(original)) {
for (const entry of jbo) {
if (entry.selmaho) {
let y = entry.selmaho;
let ystar = y.includes("*");
let ydigit = (y.match(/\d+/) ?? [null])[0];
let ysub = (y.match(/[abc]+/) ?? [null])[0];
let yname = (h(y).match(/[A-GI-PR-VX-Z][A-G'I-PR-VX-Z+]*/) ?? [null])[0];
let x = original;
let xstar = x.includes("*");
let xdigit = (x.match(/\d+/) ?? [null])[0];
let xsub = (x.match(/[abc]+/) ?? [null])[0];
let xname = (h(x).match(/[A-GI-PR-VX-Z][A-G'I-PR-VX-Z+]*/) ?? [null])[0];
if (selmahois([xname, xdigit, xsub, xstar], [yname, ydigit, ysub, ystar])) {
results.push([entry, 1]);
}
}
}
} else {
// hi
if (query == "hi") {
results.push([jbo.find(entry => entry.word == "coi"), 3]);
return results;
}
// exact matches
for (const w of query.split(/[\s.]+/)) {
const exact = jbo.find(entry => entry.word.toLowerCase().replace(/\./g, "") == h(w));
if (exact) {
results.push([exact, 10]);
}
}
for (const entry of jbo) {
const bonus = (entry.score >= 1000 ? 0.375 : 0) + (xusegismu_zo(entry.word) ? 0.125 : 0);
if (RAFSI.get(entry.word) && RAFSI.get(entry.word).includes(h(query))) {
results.push([entry, 4]);
}
const rgx = query.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const regex = `(\\b|\\W|^)${rgx}e?s?(\\b|\\W|$)`; // doi la bavyse'i ko ba'e *na* galfi ti. you tried that like 4,0000 times
if (new RegExp(regex, "iu").test(entry.definition)) {
results.push([entry, 3 + bonus]);
}
if (entry.word.toLowerCase().startsWith(h(query))) {
results.push([entry, 2 + 0.5]);
} else if (entry.word.toLowerCase().includes(h(query))) {
results.push([entry, 2]);
}
if (entry.notes && new RegExp(regex, "iu").test(entry.notes)) {
results.push([entry, 1 + bonus]);
}
}
}
results = removeDuplicates(results);
return results;
}
function removeDuplicates(list) {
var sortedList = list.sort((a, b) => b[1] - a[1]);
const logged = {};
sortedList = sortedList.filter(entry => {
if (logged[entry[0].word]) return false;
logged[entry[0].word] = true;
return true;
});
return sortedList;
}
onmessage = function(e) {
const query = e.data.query;
config = e.data.config;
const res = search(query);
postMessage(res);
};