spamscanner 7.0.14 → 7.0.15
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/README.md +1 -1
- package/dist/cjs/arf.cjs +1261 -30
- package/dist/cjs/arf.cjs.map +4 -4
- package/dist/cjs/index.cjs +176 -23
- package/dist/cjs/index.cjs.map +3 -3
- package/dist/esm/arf.js +1262 -30
- package/dist/esm/arf.js.map +4 -4
- package/dist/esm/cli.js +3227 -3074
- package/dist/esm/cli.js.map +4 -4
- package/dist/esm/index.js +172 -21
- package/dist/esm/index.js.map +3 -3
- package/dist/types/attachments.d.ts +2 -1
- package/dist/types/parse.d.ts +14 -0
- package/package.json +1 -1
package/dist/esm/arf.js
CHANGED
|
@@ -1,13 +1,1149 @@
|
|
|
1
1
|
// src/arf.js
|
|
2
|
-
import { Buffer as
|
|
2
|
+
import { Buffer as Buffer3 } from "node:buffer";
|
|
3
3
|
import { randomBytes } from "node:crypto";
|
|
4
4
|
import { isIP } from "node:net";
|
|
5
5
|
|
|
6
6
|
// src/parse.js
|
|
7
|
-
import { Buffer } from "node:buffer";
|
|
7
|
+
import { Buffer as Buffer2 } from "node:buffer";
|
|
8
8
|
import { createHash } from "node:crypto";
|
|
9
9
|
import { Readable } from "node:stream";
|
|
10
10
|
import { MailParser, simpleParser } from "mailparser";
|
|
11
|
+
|
|
12
|
+
// src/attachments.js
|
|
13
|
+
import { Buffer } from "node:buffer";
|
|
14
|
+
|
|
15
|
+
// src/linear.js
|
|
16
|
+
import { createRequire } from "node:module";
|
|
17
|
+
function loadRe2(load = createRequire(import.meta.url)) {
|
|
18
|
+
try {
|
|
19
|
+
return load("re2");
|
|
20
|
+
} catch {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
var RE2 = loadRe2();
|
|
25
|
+
var BOUNDED = /^{([01]),\d{2,}}/;
|
|
26
|
+
var WHITESPACE = String.raw`\t\n\x0B\f\r \x{A0}\x{1680}\x{2000}-\x{200A}\x{2028}\x{2029}\x{202F}\x{205F}\x{3000}\x{FEFF}`;
|
|
27
|
+
function re2Source(source) {
|
|
28
|
+
let out = "";
|
|
29
|
+
let inClass = false;
|
|
30
|
+
let unicodeClass = false;
|
|
31
|
+
let afterClass = false;
|
|
32
|
+
for (let i = 0; i < source.length; i++) {
|
|
33
|
+
const char = source[i];
|
|
34
|
+
const repeats = afterClass;
|
|
35
|
+
afterClass = false;
|
|
36
|
+
if (char === "{" && !inClass && repeats && unicodeClass) {
|
|
37
|
+
const bound = BOUNDED.exec(source.slice(i, i + 16));
|
|
38
|
+
if (bound) {
|
|
39
|
+
out += bound[1] === "0" ? "*" : "+";
|
|
40
|
+
i += bound[0].length - 1;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (char === "\\") {
|
|
45
|
+
const next = source[++i] ?? "";
|
|
46
|
+
if (inClass && (next === "p" || next === "P")) {
|
|
47
|
+
unicodeClass = true;
|
|
48
|
+
}
|
|
49
|
+
if (next === "s") {
|
|
50
|
+
out += inClass ? WHITESPACE : `[${WHITESPACE}]`;
|
|
51
|
+
} else if (next === "S") {
|
|
52
|
+
if (inClass) {
|
|
53
|
+
throw new TypeError(String.raw`\S inside a character class has no RE2 equivalent here`);
|
|
54
|
+
}
|
|
55
|
+
out += `[^${WHITESPACE}]`;
|
|
56
|
+
} else {
|
|
57
|
+
out += `\\${next}`;
|
|
58
|
+
}
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (char === "[" && !inClass) {
|
|
62
|
+
inClass = true;
|
|
63
|
+
unicodeClass = false;
|
|
64
|
+
} else if (char === "]" && inClass) {
|
|
65
|
+
inClass = false;
|
|
66
|
+
afterClass = true;
|
|
67
|
+
}
|
|
68
|
+
out += char;
|
|
69
|
+
}
|
|
70
|
+
return out;
|
|
71
|
+
}
|
|
72
|
+
function linear(source, flags = "", Engine = RE2) {
|
|
73
|
+
return Engine ? new Engine(re2Source(source), flags) : new RegExp(source, flags);
|
|
74
|
+
}
|
|
75
|
+
function trimEndOf(value, characters) {
|
|
76
|
+
let end = value.length;
|
|
77
|
+
while (end > 0 && characters.includes(value[end - 1])) {
|
|
78
|
+
end--;
|
|
79
|
+
}
|
|
80
|
+
return value.slice(0, end);
|
|
81
|
+
}
|
|
82
|
+
function caseless(word) {
|
|
83
|
+
return [...word].map((letter) => `[${letter}${letter.toUpperCase()}]`).join("");
|
|
84
|
+
}
|
|
85
|
+
var OPENER = linear(String.raw`<(${caseless("script")}|${caseless("style")})\b`, "g");
|
|
86
|
+
var CLOSERS = {
|
|
87
|
+
script: linear(String.raw`<\/${caseless("script")}\s*>`, "g"),
|
|
88
|
+
style: linear(String.raw`<\/${caseless("style")}\s*>`, "g")
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
// src/tokenizer.js
|
|
92
|
+
import { parse as parseDomain2 } from "tldts";
|
|
93
|
+
|
|
94
|
+
// src/homograph.js
|
|
95
|
+
import { domainToUnicode } from "node:url";
|
|
96
|
+
import { parse as parseDomain } from "tldts";
|
|
97
|
+
|
|
98
|
+
// src/language.js
|
|
99
|
+
import { franc } from "franc";
|
|
100
|
+
var SCRIPTS = [
|
|
101
|
+
["Latin", new RegExp("\\p{Script=Latin}", "u")],
|
|
102
|
+
["Cyrillic", new RegExp("\\p{Script=Cyrillic}", "u")],
|
|
103
|
+
["Greek", new RegExp("\\p{Script=Greek}", "u")],
|
|
104
|
+
["Han", new RegExp("\\p{Script=Han}", "u")],
|
|
105
|
+
["Hiragana", new RegExp("\\p{Script=Hiragana}", "u")],
|
|
106
|
+
["Katakana", new RegExp("\\p{Script=Katakana}", "u")],
|
|
107
|
+
["Hangul", new RegExp("\\p{Script=Hangul}", "u")],
|
|
108
|
+
["Arabic", new RegExp("\\p{Script=Arabic}", "u")],
|
|
109
|
+
["Hebrew", new RegExp("\\p{Script=Hebrew}", "u")],
|
|
110
|
+
["Thai", new RegExp("\\p{Script=Thai}", "u")],
|
|
111
|
+
["Devanagari", new RegExp("\\p{Script=Devanagari}", "u")],
|
|
112
|
+
["Bengali", new RegExp("\\p{Script=Bengali}", "u")],
|
|
113
|
+
["Tamil", new RegExp("\\p{Script=Tamil}", "u")],
|
|
114
|
+
["Telugu", new RegExp("\\p{Script=Telugu}", "u")],
|
|
115
|
+
["Gujarati", new RegExp("\\p{Script=Gujarati}", "u")],
|
|
116
|
+
["Gurmukhi", new RegExp("\\p{Script=Gurmukhi}", "u")],
|
|
117
|
+
["Kannada", new RegExp("\\p{Script=Kannada}", "u")],
|
|
118
|
+
["Malayalam", new RegExp("\\p{Script=Malayalam}", "u")],
|
|
119
|
+
["Armenian", new RegExp("\\p{Script=Armenian}", "u")],
|
|
120
|
+
["Georgian", new RegExp("\\p{Script=Georgian}", "u")],
|
|
121
|
+
["Ethiopic", new RegExp("\\p{Script=Ethiopic}", "u")],
|
|
122
|
+
["Khmer", new RegExp("\\p{Script=Khmer}", "u")],
|
|
123
|
+
["Lao", new RegExp("\\p{Script=Lao}", "u")],
|
|
124
|
+
["Myanmar", new RegExp("\\p{Script=Myanmar}", "u")],
|
|
125
|
+
["Sinhala", new RegExp("\\p{Script=Sinhala}", "u")]
|
|
126
|
+
];
|
|
127
|
+
var LETTER = new RegExp("\\p{L}", "u");
|
|
128
|
+
function scriptOf(char) {
|
|
129
|
+
const entry = SCRIPTS.find(([, pattern]) => pattern.test(char));
|
|
130
|
+
return entry ? entry[0] : "Other";
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// src/homograph.js
|
|
134
|
+
var INTERNATIONAL_BRANDS = [
|
|
135
|
+
"alipay",
|
|
136
|
+
"auspost",
|
|
137
|
+
"bancolombia",
|
|
138
|
+
"bnpparibas",
|
|
139
|
+
"bradesco",
|
|
140
|
+
"caixabank",
|
|
141
|
+
"canadapost",
|
|
142
|
+
"commerzbank",
|
|
143
|
+
"coupang",
|
|
144
|
+
"creditagricole",
|
|
145
|
+
"deutschebank",
|
|
146
|
+
"flipkart",
|
|
147
|
+
"gosuslugi",
|
|
148
|
+
"japanpost",
|
|
149
|
+
"kakaobank",
|
|
150
|
+
"klarna",
|
|
151
|
+
"kucoin",
|
|
152
|
+
"lazada",
|
|
153
|
+
"mercadolibre",
|
|
154
|
+
"mercadolivre",
|
|
155
|
+
"mercadopago",
|
|
156
|
+
"mercari",
|
|
157
|
+
"natwest",
|
|
158
|
+
"nubank",
|
|
159
|
+
"phonepe",
|
|
160
|
+
"postbank",
|
|
161
|
+
"rakuten",
|
|
162
|
+
"sberbank",
|
|
163
|
+
"swisscom",
|
|
164
|
+
"trustwallet",
|
|
165
|
+
"unicredit",
|
|
166
|
+
"vodafone",
|
|
167
|
+
"wechat",
|
|
168
|
+
"yandex"
|
|
169
|
+
];
|
|
170
|
+
var BRANDS = [
|
|
171
|
+
"adobe",
|
|
172
|
+
"airbnb",
|
|
173
|
+
"alibaba",
|
|
174
|
+
"aliexpress",
|
|
175
|
+
"amazon",
|
|
176
|
+
"americanexpress",
|
|
177
|
+
"amex",
|
|
178
|
+
"apple",
|
|
179
|
+
"appleid",
|
|
180
|
+
"att",
|
|
181
|
+
"binance",
|
|
182
|
+
"bankofamerica",
|
|
183
|
+
"barclays",
|
|
184
|
+
"bestbuy",
|
|
185
|
+
"blockchain",
|
|
186
|
+
"booking",
|
|
187
|
+
"bybit",
|
|
188
|
+
"cashapp",
|
|
189
|
+
"chase",
|
|
190
|
+
"citibank",
|
|
191
|
+
"cloudflare",
|
|
192
|
+
"coinbase",
|
|
193
|
+
"comcast",
|
|
194
|
+
"costco",
|
|
195
|
+
"dhl",
|
|
196
|
+
"discord",
|
|
197
|
+
"docusign",
|
|
198
|
+
"dropbox",
|
|
199
|
+
"ebay",
|
|
200
|
+
"facebook",
|
|
201
|
+
"fedex",
|
|
202
|
+
"forwardemail",
|
|
203
|
+
"github",
|
|
204
|
+
"gitlab",
|
|
205
|
+
"gmail",
|
|
206
|
+
"godaddy",
|
|
207
|
+
"google",
|
|
208
|
+
"hmrc",
|
|
209
|
+
"hotmail",
|
|
210
|
+
"hsbc",
|
|
211
|
+
"icloud",
|
|
212
|
+
"instagram",
|
|
213
|
+
"intuit",
|
|
214
|
+
"irs",
|
|
215
|
+
"kraken",
|
|
216
|
+
"ledger",
|
|
217
|
+
"linkedin",
|
|
218
|
+
"mastercard",
|
|
219
|
+
"mcafee",
|
|
220
|
+
"metamask",
|
|
221
|
+
"microsoft",
|
|
222
|
+
"microsoftonline",
|
|
223
|
+
"namecheap",
|
|
224
|
+
"netflix",
|
|
225
|
+
"norton",
|
|
226
|
+
"office",
|
|
227
|
+
"office365",
|
|
228
|
+
"okta",
|
|
229
|
+
"onedrive",
|
|
230
|
+
"outlook",
|
|
231
|
+
"paypal",
|
|
232
|
+
"proton",
|
|
233
|
+
"protonmail",
|
|
234
|
+
"quickbooks",
|
|
235
|
+
"revolut",
|
|
236
|
+
"roblox",
|
|
237
|
+
"royalmail",
|
|
238
|
+
"salesforce",
|
|
239
|
+
"samsung",
|
|
240
|
+
"santander",
|
|
241
|
+
"sharepoint",
|
|
242
|
+
"shopify",
|
|
243
|
+
"skype",
|
|
244
|
+
"slack",
|
|
245
|
+
"sparkasse",
|
|
246
|
+
"spotify",
|
|
247
|
+
"steam",
|
|
248
|
+
"steampowered",
|
|
249
|
+
"stripe",
|
|
250
|
+
"telegram",
|
|
251
|
+
"tiktok",
|
|
252
|
+
"tmobile",
|
|
253
|
+
"trezor",
|
|
254
|
+
"tutanota",
|
|
255
|
+
"twitter",
|
|
256
|
+
"uber",
|
|
257
|
+
"ups",
|
|
258
|
+
"usps",
|
|
259
|
+
"venmo",
|
|
260
|
+
"verizon",
|
|
261
|
+
"visa",
|
|
262
|
+
"walmart",
|
|
263
|
+
"wellsfargo",
|
|
264
|
+
"whatsapp",
|
|
265
|
+
"wise",
|
|
266
|
+
"xfinity",
|
|
267
|
+
"yahoo",
|
|
268
|
+
"zelle",
|
|
269
|
+
"zoom",
|
|
270
|
+
...INTERNATIONAL_BRANDS
|
|
271
|
+
];
|
|
272
|
+
var WORD_BRANDS = /* @__PURE__ */ new Set(["apple", "blockchain", "booking", "chase", "discord", "kraken", "ledger", "office", "proton", "slack", "steam", "stripe"]);
|
|
273
|
+
var HELP_WORDS = ["help", "helpdesk", "support"];
|
|
274
|
+
var COMMON_WORD_BRANDS = /* @__PURE__ */ new Map([
|
|
275
|
+
["blockchain", ["wallet", "wallets", ...HELP_WORDS]],
|
|
276
|
+
["booking", []],
|
|
277
|
+
["kraken", ["trade", "trading", "wallet", "wallets", ...HELP_WORDS]],
|
|
278
|
+
["ledger", ["live", "wallet", "wallets", ...HELP_WORDS]],
|
|
279
|
+
["office", []],
|
|
280
|
+
["proton", ["pay", "wallet", ...HELP_WORDS]],
|
|
281
|
+
["steam", ["community", "gift", "giftcard", "gifts", "trade", "trading", "wallet", ...HELP_WORDS]],
|
|
282
|
+
["stripe", ["payment", "payments", ...HELP_WORDS]]
|
|
283
|
+
]);
|
|
284
|
+
var TYPO_WORDS = /* @__PURE__ */ new Set([...WORD_BRANDS, "adobe", "binance", "fedex", "gmail", "icloud", "norton", "samsung", "tiktok", "tmobile", "trezor", "twitter", "venmo", "zelle"]);
|
|
285
|
+
var ASCII_TRICKS = [
|
|
286
|
+
[/rn/g, "m"],
|
|
287
|
+
[/vv/g, "w"],
|
|
288
|
+
[/cl/g, "d"],
|
|
289
|
+
[/0/g, "o"],
|
|
290
|
+
[/1/g, "l"],
|
|
291
|
+
[/3/g, "e"],
|
|
292
|
+
[/4/g, "a"],
|
|
293
|
+
[/5/g, "s"],
|
|
294
|
+
[/7/g, "t"],
|
|
295
|
+
[/8/g, "b"]
|
|
296
|
+
];
|
|
297
|
+
var LETTER_TRICKS = ASCII_TRICKS.filter(([pattern]) => pattern.source === "cl" || pattern.source === "vv");
|
|
298
|
+
|
|
299
|
+
// src/entities.js
|
|
300
|
+
var NAMED = [
|
|
301
|
+
"AElig=c6,AMP=26,Aacute=c1,Abreve=102,Acirc=c2,Acy=410,Afr=1d504,Agrave=c0,Alpha=391,Amacr=100,And=2a",
|
|
302
|
+
"53,Aogon=104,Aopf=1d538,ApplyFunction=2061,Aring=c5,Ascr=1d49c,Assign=2254,Atilde=c3,Auml=c4,Backsla",
|
|
303
|
+
"sh=2216,Barv=2ae7,Barwed=2306,Bcy=411,Because=2235,Bernoullis=212c,Beta=392,Bfr=1d505,Bopf=1d539,Bre",
|
|
304
|
+
"ve=2d8,Bscr=212c,Bumpeq=224e,CHcy=427,COPY=a9,Cacute=106,Cap=22d2,CapitalDifferentialD=2145,Cayleys=",
|
|
305
|
+
"212d,Ccaron=10c,Ccedil=c7,Ccirc=108,Cconint=2230,Cdot=10a,Cedilla=b8,CenterDot=b7,Cfr=212d,Chi=3a7,C",
|
|
306
|
+
"ircleDot=2299,CircleMinus=2296,CirclePlus=2295,CircleTimes=2297,ClockwiseContourIntegral=2232,CloseC",
|
|
307
|
+
"urlyDoubleQuote=201d,CloseCurlyQuote=2019,Colon=2237,Colone=2a74,Congruent=2261,Conint=222f,ContourI",
|
|
308
|
+
"ntegral=222e,Copf=2102,Coproduct=2210,CounterClockwiseContourIntegral=2233,Cross=2a2f,Cscr=1d49e,Cup",
|
|
309
|
+
"=22d3,CupCap=224d,DD=2145,DDotrahd=2911,DJcy=402,DScy=405,DZcy=40f,Dagger=2021,Darr=21a1,Dashv=2ae4,",
|
|
310
|
+
"Dcaron=10e,Dcy=414,Del=2207,Delta=394,Dfr=1d507,DiacriticalAcute=b4,DiacriticalDot=2d9,DiacriticalDo",
|
|
311
|
+
"ubleAcute=2dd,DiacriticalGrave=60,DiacriticalTilde=2dc,Diamond=22c4,DifferentialD=2146,Dopf=1d53b,Do",
|
|
312
|
+
"t=a8,DotDot=20dc,DotEqual=2250,DoubleContourIntegral=222f,DoubleDot=a8,DoubleDownArrow=21d3,DoubleLe",
|
|
313
|
+
"ftArrow=21d0,DoubleLeftRightArrow=21d4,DoubleLeftTee=2ae4,DoubleLongLeftArrow=27f8,DoubleLongLeftRig",
|
|
314
|
+
"htArrow=27fa,DoubleLongRightArrow=27f9,DoubleRightArrow=21d2,DoubleRightTee=22a8,DoubleUpArrow=21d1,",
|
|
315
|
+
"DoubleUpDownArrow=21d5,DoubleVerticalBar=2225,DownArrow=2193,DownArrowBar=2913,DownArrowUpArrow=21f5",
|
|
316
|
+
",DownBreve=311,DownLeftRightVector=2950,DownLeftTeeVector=295e,DownLeftVector=21bd,DownLeftVectorBar",
|
|
317
|
+
"=2956,DownRightTeeVector=295f,DownRightVector=21c1,DownRightVectorBar=2957,DownTee=22a4,DownTeeArrow",
|
|
318
|
+
"=21a7,Downarrow=21d3,Dscr=1d49f,Dstrok=110,ENG=14a,ETH=d0,Eacute=c9,Ecaron=11a,Ecirc=ca,Ecy=42d,Edot",
|
|
319
|
+
"=116,Efr=1d508,Egrave=c8,Element=2208,Emacr=112,EmptySmallSquare=25fb,EmptyVerySmallSquare=25ab,Eogo",
|
|
320
|
+
"n=118,Eopf=1d53c,Epsilon=395,Equal=2a75,EqualTilde=2242,Equilibrium=21cc,Escr=2130,Esim=2a73,Eta=397",
|
|
321
|
+
",Euml=cb,Exists=2203,ExponentialE=2147,Fcy=424,Ffr=1d509,FilledSmallSquare=25fc,FilledVerySmallSquar",
|
|
322
|
+
"e=25aa,Fopf=1d53d,ForAll=2200,Fouriertrf=2131,Fscr=2131,GJcy=403,GT=3e,Gamma=393,Gammad=3dc,Gbreve=1",
|
|
323
|
+
"1e,Gcedil=122,Gcirc=11c,Gcy=413,Gdot=120,Gfr=1d50a,Gg=22d9,Gopf=1d53e,GreaterEqual=2265,GreaterEqual",
|
|
324
|
+
"Less=22db,GreaterFullEqual=2267,GreaterGreater=2aa2,GreaterLess=2277,GreaterSlantEqual=2a7e,GreaterT",
|
|
325
|
+
"ilde=2273,Gscr=1d4a2,Gt=226b,HARDcy=42a,Hacek=2c7,Hat=5e,Hcirc=124,Hfr=210c,HilbertSpace=210b,Hopf=2",
|
|
326
|
+
"10d,HorizontalLine=2500,Hscr=210b,Hstrok=126,HumpDownHump=224e,HumpEqual=224f,IEcy=415,IJlig=132,IOc",
|
|
327
|
+
"y=401,Iacute=cd,Icirc=ce,Icy=418,Idot=130,Ifr=2111,Igrave=cc,Im=2111,Imacr=12a,ImaginaryI=2148,Impli",
|
|
328
|
+
"es=21d2,Int=222c,Integral=222b,Intersection=22c2,InvisibleComma=2063,InvisibleTimes=2062,Iogon=12e,I",
|
|
329
|
+
"opf=1d540,Iota=399,Iscr=2110,Itilde=128,Iukcy=406,Iuml=cf,Jcirc=134,Jcy=419,Jfr=1d50d,Jopf=1d541,Jsc",
|
|
330
|
+
"r=1d4a5,Jsercy=408,Jukcy=404,KHcy=425,KJcy=40c,Kappa=39a,Kcedil=136,Kcy=41a,Kfr=1d50e,Kopf=1d542,Ksc",
|
|
331
|
+
"r=1d4a6,LJcy=409,LT=3c,Lacute=139,Lambda=39b,Lang=27ea,Laplacetrf=2112,Larr=219e,Lcaron=13d,Lcedil=1",
|
|
332
|
+
"3b,Lcy=41b,LeftAngleBracket=27e8,LeftArrow=2190,LeftArrowBar=21e4,LeftArrowRightArrow=21c6,LeftCeili",
|
|
333
|
+
"ng=2308,LeftDoubleBracket=27e6,LeftDownTeeVector=2961,LeftDownVector=21c3,LeftDownVectorBar=2959,Lef",
|
|
334
|
+
"tFloor=230a,LeftRightArrow=2194,LeftRightVector=294e,LeftTee=22a3,LeftTeeArrow=21a4,LeftTeeVector=29",
|
|
335
|
+
"5a,LeftTriangle=22b2,LeftTriangleBar=29cf,LeftTriangleEqual=22b4,LeftUpDownVector=2951,LeftUpTeeVect",
|
|
336
|
+
"or=2960,LeftUpVector=21bf,LeftUpVectorBar=2958,LeftVector=21bc,LeftVectorBar=2952,Leftarrow=21d0,Lef",
|
|
337
|
+
"trightarrow=21d4,LessEqualGreater=22da,LessFullEqual=2266,LessGreater=2276,LessLess=2aa1,LessSlantEq",
|
|
338
|
+
"ual=2a7d,LessTilde=2272,Lfr=1d50f,Ll=22d8,Lleftarrow=21da,Lmidot=13f,LongLeftArrow=27f5,LongLeftRigh",
|
|
339
|
+
"tArrow=27f7,LongRightArrow=27f6,Longleftarrow=27f8,Longleftrightarrow=27fa,Longrightarrow=27f9,Lopf=",
|
|
340
|
+
"1d543,LowerLeftArrow=2199,LowerRightArrow=2198,Lscr=2112,Lsh=21b0,Lstrok=141,Lt=226a,Map=2905,Mcy=41",
|
|
341
|
+
"c,MediumSpace=205f,Mellintrf=2133,Mfr=1d510,MinusPlus=2213,Mopf=1d544,Mscr=2133,Mu=39c,NJcy=40a,Nacu",
|
|
342
|
+
"te=143,Ncaron=147,Ncedil=145,Ncy=41d,NegativeMediumSpace=200b,NegativeThickSpace=200b,NegativeThinSp",
|
|
343
|
+
"ace=200b,NegativeVeryThinSpace=200b,NestedGreaterGreater=226b,NestedLessLess=226a,NewLine=a,Nfr=1d51",
|
|
344
|
+
"1,NoBreak=2060,NonBreakingSpace=a0,Nopf=2115,Not=2aec,NotCongruent=2262,NotCupCap=226d,NotDoubleVert",
|
|
345
|
+
"icalBar=2226,NotElement=2209,NotEqual=2260,NotEqualTilde=2242.338,NotExists=2204,NotGreater=226f,Not",
|
|
346
|
+
"GreaterEqual=2271,NotGreaterFullEqual=2267.338,NotGreaterGreater=226b.338,NotGreaterLess=2279,NotGre",
|
|
347
|
+
"aterSlantEqual=2a7e.338,NotGreaterTilde=2275,NotHumpDownHump=224e.338,NotHumpEqual=224f.338,NotLeftT",
|
|
348
|
+
"riangle=22ea,NotLeftTriangleBar=29cf.338,NotLeftTriangleEqual=22ec,NotLess=226e,NotLessEqual=2270,No",
|
|
349
|
+
"tLessGreater=2278,NotLessLess=226a.338,NotLessSlantEqual=2a7d.338,NotLessTilde=2274,NotNestedGreater",
|
|
350
|
+
"Greater=2aa2.338,NotNestedLessLess=2aa1.338,NotPrecedes=2280,NotPrecedesEqual=2aaf.338,NotPrecedesSl",
|
|
351
|
+
"antEqual=22e0,NotReverseElement=220c,NotRightTriangle=22eb,NotRightTriangleBar=29d0.338,NotRightTria",
|
|
352
|
+
"ngleEqual=22ed,NotSquareSubset=228f.338,NotSquareSubsetEqual=22e2,NotSquareSuperset=2290.338,NotSqua",
|
|
353
|
+
"reSupersetEqual=22e3,NotSubset=2282.20d2,NotSubsetEqual=2288,NotSucceeds=2281,NotSucceedsEqual=2ab0.",
|
|
354
|
+
"338,NotSucceedsSlantEqual=22e1,NotSucceedsTilde=227f.338,NotSuperset=2283.20d2,NotSupersetEqual=2289",
|
|
355
|
+
",NotTilde=2241,NotTildeEqual=2244,NotTildeFullEqual=2247,NotTildeTilde=2249,NotVerticalBar=2224,Nscr",
|
|
356
|
+
"=1d4a9,Ntilde=d1,Nu=39d,OElig=152,Oacute=d3,Ocirc=d4,Ocy=41e,Odblac=150,Ofr=1d512,Ograve=d2,Omacr=14",
|
|
357
|
+
"c,Omega=3a9,Omicron=39f,Oopf=1d546,OpenCurlyDoubleQuote=201c,OpenCurlyQuote=2018,Or=2a54,Oscr=1d4aa,",
|
|
358
|
+
"Oslash=d8,Otilde=d5,Otimes=2a37,Ouml=d6,OverBar=203e,OverBrace=23de,OverBracket=23b4,OverParenthesis",
|
|
359
|
+
"=23dc,PartialD=2202,Pcy=41f,Pfr=1d513,Phi=3a6,Pi=3a0,PlusMinus=b1,Poincareplane=210c,Popf=2119,Pr=2a",
|
|
360
|
+
"bb,Precedes=227a,PrecedesEqual=2aaf,PrecedesSlantEqual=227c,PrecedesTilde=227e,Prime=2033,Product=22",
|
|
361
|
+
"0f,Proportion=2237,Proportional=221d,Pscr=1d4ab,Psi=3a8,QUOT=22,Qfr=1d514,Qopf=211a,Qscr=1d4ac,RBarr",
|
|
362
|
+
"=2910,REG=ae,Racute=154,Rang=27eb,Rarr=21a0,Rarrtl=2916,Rcaron=158,Rcedil=156,Rcy=420,Re=211c,Revers",
|
|
363
|
+
"eElement=220b,ReverseEquilibrium=21cb,ReverseUpEquilibrium=296f,Rfr=211c,Rho=3a1,RightAngleBracket=2",
|
|
364
|
+
"7e9,RightArrow=2192,RightArrowBar=21e5,RightArrowLeftArrow=21c4,RightCeiling=2309,RightDoubleBracket",
|
|
365
|
+
"=27e7,RightDownTeeVector=295d,RightDownVector=21c2,RightDownVectorBar=2955,RightFloor=230b,RightTee=",
|
|
366
|
+
"22a2,RightTeeArrow=21a6,RightTeeVector=295b,RightTriangle=22b3,RightTriangleBar=29d0,RightTriangleEq",
|
|
367
|
+
"ual=22b5,RightUpDownVector=294f,RightUpTeeVector=295c,RightUpVector=21be,RightUpVectorBar=2954,Right",
|
|
368
|
+
"Vector=21c0,RightVectorBar=2953,Rightarrow=21d2,Ropf=211d,RoundImplies=2970,Rrightarrow=21db,Rscr=21",
|
|
369
|
+
"1b,Rsh=21b1,RuleDelayed=29f4,SHCHcy=429,SHcy=428,SOFTcy=42c,Sacute=15a,Sc=2abc,Scaron=160,Scedil=15e",
|
|
370
|
+
",Scirc=15c,Scy=421,Sfr=1d516,ShortDownArrow=2193,ShortLeftArrow=2190,ShortRightArrow=2192,ShortUpArr",
|
|
371
|
+
"ow=2191,Sigma=3a3,SmallCircle=2218,Sopf=1d54a,Sqrt=221a,Square=25a1,SquareIntersection=2293,SquareSu",
|
|
372
|
+
"bset=228f,SquareSubsetEqual=2291,SquareSuperset=2290,SquareSupersetEqual=2292,SquareUnion=2294,Sscr=",
|
|
373
|
+
"1d4ae,Star=22c6,Sub=22d0,Subset=22d0,SubsetEqual=2286,Succeeds=227b,SucceedsEqual=2ab0,SucceedsSlant",
|
|
374
|
+
"Equal=227d,SucceedsTilde=227f,SuchThat=220b,Sum=2211,Sup=22d1,Superset=2283,SupersetEqual=2287,Supse",
|
|
375
|
+
"t=22d1,THORN=de,TRADE=2122,TSHcy=40b,TScy=426,Tab=9,Tau=3a4,Tcaron=164,Tcedil=162,Tcy=422,Tfr=1d517,",
|
|
376
|
+
"Therefore=2234,Theta=398,ThickSpace=205f.200a,ThinSpace=2009,Tilde=223c,TildeEqual=2243,TildeFullEqu",
|
|
377
|
+
"al=2245,TildeTilde=2248,Topf=1d54b,TripleDot=20db,Tscr=1d4af,Tstrok=166,Uacute=da,Uarr=219f,Uarrocir",
|
|
378
|
+
"=2949,Ubrcy=40e,Ubreve=16c,Ucirc=db,Ucy=423,Udblac=170,Ufr=1d518,Ugrave=d9,Umacr=16a,UnderBar=5f,Und",
|
|
379
|
+
"erBrace=23df,UnderBracket=23b5,UnderParenthesis=23dd,Union=22c3,UnionPlus=228e,Uogon=172,Uopf=1d54c,",
|
|
380
|
+
"UpArrow=2191,UpArrowBar=2912,UpArrowDownArrow=21c5,UpDownArrow=2195,UpEquilibrium=296e,UpTee=22a5,Up",
|
|
381
|
+
"TeeArrow=21a5,Uparrow=21d1,Updownarrow=21d5,UpperLeftArrow=2196,UpperRightArrow=2197,Upsi=3d2,Upsilo",
|
|
382
|
+
"n=3a5,Uring=16e,Uscr=1d4b0,Utilde=168,Uuml=dc,VDash=22ab,Vbar=2aeb,Vcy=412,Vdash=22a9,Vdashl=2ae6,Ve",
|
|
383
|
+
"e=22c1,Verbar=2016,Vert=2016,VerticalBar=2223,VerticalLine=7c,VerticalSeparator=2758,VerticalTilde=2",
|
|
384
|
+
"240,VeryThinSpace=200a,Vfr=1d519,Vopf=1d54d,Vscr=1d4b1,Vvdash=22aa,Wcirc=174,Wedge=22c0,Wfr=1d51a,Wo",
|
|
385
|
+
"pf=1d54e,Wscr=1d4b2,Xfr=1d51b,Xi=39e,Xopf=1d54f,Xscr=1d4b3,YAcy=42f,YIcy=407,YUcy=42e,Yacute=dd,Ycir",
|
|
386
|
+
"c=176,Ycy=42b,Yfr=1d51c,Yopf=1d550,Yscr=1d4b4,Yuml=178,ZHcy=416,Zacute=179,Zcaron=17d,Zcy=417,Zdot=1",
|
|
387
|
+
"7b,ZeroWidthSpace=200b,Zeta=396,Zfr=2128,Zopf=2124,Zscr=1d4b5,aacute=e1,abreve=103,ac=223e,acE=223e.",
|
|
388
|
+
"333,acd=223f,acirc=e2,acute=b4,acy=430,aelig=e6,af=2061,afr=1d51e,agrave=e0,alefsym=2135,aleph=2135,",
|
|
389
|
+
"alpha=3b1,amacr=101,amalg=2a3f,amp=26,and=2227,andand=2a55,andd=2a5c,andslope=2a58,andv=2a5a,ang=222",
|
|
390
|
+
"0,ange=29a4,angle=2220,angmsd=2221,angmsdaa=29a8,angmsdab=29a9,angmsdac=29aa,angmsdad=29ab,angmsdae=",
|
|
391
|
+
"29ac,angmsdaf=29ad,angmsdag=29ae,angmsdah=29af,angrt=221f,angrtvb=22be,angrtvbd=299d,angsph=2222,ang",
|
|
392
|
+
"st=c5,angzarr=237c,aogon=105,aopf=1d552,ap=2248,apE=2a70,apacir=2a6f,ape=224a,apid=224b,apos=27,appr",
|
|
393
|
+
"ox=2248,approxeq=224a,aring=e5,ascr=1d4b6,ast=2a,asymp=2248,asympeq=224d,atilde=e3,auml=e4,awconint=",
|
|
394
|
+
"2233,awint=2a11,bNot=2aed,backcong=224c,backepsilon=3f6,backprime=2035,backsim=223d,backsimeq=22cd,b",
|
|
395
|
+
"arvee=22bd,barwed=2305,barwedge=2305,bbrk=23b5,bbrktbrk=23b6,bcong=224c,bcy=431,bdquo=201e,becaus=22",
|
|
396
|
+
"35,because=2235,bemptyv=29b0,bepsi=3f6,bernou=212c,beta=3b2,beth=2136,between=226c,bfr=1d51f,bigcap=",
|
|
397
|
+
"22c2,bigcirc=25ef,bigcup=22c3,bigodot=2a00,bigoplus=2a01,bigotimes=2a02,bigsqcup=2a06,bigstar=2605,b",
|
|
398
|
+
"igtriangledown=25bd,bigtriangleup=25b3,biguplus=2a04,bigvee=22c1,bigwedge=22c0,bkarow=290d,blackloze",
|
|
399
|
+
"nge=29eb,blacksquare=25aa,blacktriangle=25b4,blacktriangledown=25be,blacktriangleleft=25c2,blacktria",
|
|
400
|
+
"ngleright=25b8,blank=2423,blk12=2592,blk14=2591,blk34=2593,block=2588,bne=3d.20e5,bnequiv=2261.20e5,",
|
|
401
|
+
"bnot=2310,bopf=1d553,bot=22a5,bottom=22a5,bowtie=22c8,boxDL=2557,boxDR=2554,boxDl=2556,boxDr=2553,bo",
|
|
402
|
+
"xH=2550,boxHD=2566,boxHU=2569,boxHd=2564,boxHu=2567,boxUL=255d,boxUR=255a,boxUl=255c,boxUr=2559,boxV",
|
|
403
|
+
"=2551,boxVH=256c,boxVL=2563,boxVR=2560,boxVh=256b,boxVl=2562,boxVr=255f,boxbox=29c9,boxdL=2555,boxdR",
|
|
404
|
+
"=2552,boxdl=2510,boxdr=250c,boxh=2500,boxhD=2565,boxhU=2568,boxhd=252c,boxhu=2534,boxminus=229f,boxp",
|
|
405
|
+
"lus=229e,boxtimes=22a0,boxuL=255b,boxuR=2558,boxul=2518,boxur=2514,boxv=2502,boxvH=256a,boxvL=2561,b",
|
|
406
|
+
"oxvR=255e,boxvh=253c,boxvl=2524,boxvr=251c,bprime=2035,breve=2d8,brvbar=a6,bscr=1d4b7,bsemi=204f,bsi",
|
|
407
|
+
"m=223d,bsime=22cd,bsol=5c,bsolb=29c5,bsolhsub=27c8,bull=2022,bullet=2022,bump=224e,bumpE=2aae,bumpe=",
|
|
408
|
+
"224f,bumpeq=224f,cacute=107,cap=2229,capand=2a44,capbrcup=2a49,capcap=2a4b,capcup=2a47,capdot=2a40,c",
|
|
409
|
+
"aps=2229.fe00,caret=2041,caron=2c7,ccaps=2a4d,ccaron=10d,ccedil=e7,ccirc=109,ccups=2a4c,ccupssm=2a50",
|
|
410
|
+
",cdot=10b,cedil=b8,cemptyv=29b2,cent=a2,centerdot=b7,cfr=1d520,chcy=447,check=2713,checkmark=2713,ch",
|
|
411
|
+
"i=3c7,cir=25cb,cirE=29c3,circ=2c6,circeq=2257,circlearrowleft=21ba,circlearrowright=21bb,circledR=ae",
|
|
412
|
+
",circledS=24c8,circledast=229b,circledcirc=229a,circleddash=229d,cire=2257,cirfnint=2a10,cirmid=2aef",
|
|
413
|
+
",cirscir=29c2,clubs=2663,clubsuit=2663,colon=3a,colone=2254,coloneq=2254,comma=2c,commat=40,comp=220",
|
|
414
|
+
"1,compfn=2218,complement=2201,complexes=2102,cong=2245,congdot=2a6d,conint=222e,copf=1d554,coprod=22",
|
|
415
|
+
"10,copy=a9,copysr=2117,crarr=21b5,cross=2717,cscr=1d4b8,csub=2acf,csube=2ad1,csup=2ad0,csupe=2ad2,ct",
|
|
416
|
+
"dot=22ef,cudarrl=2938,cudarrr=2935,cuepr=22de,cuesc=22df,cularr=21b6,cularrp=293d,cup=222a,cupbrcap=",
|
|
417
|
+
"2a48,cupcap=2a46,cupcup=2a4a,cupdot=228d,cupor=2a45,cups=222a.fe00,curarr=21b7,curarrm=293c,curlyeqp",
|
|
418
|
+
"rec=22de,curlyeqsucc=22df,curlyvee=22ce,curlywedge=22cf,curren=a4,curvearrowleft=21b6,curvearrowrigh",
|
|
419
|
+
"t=21b7,cuvee=22ce,cuwed=22cf,cwconint=2232,cwint=2231,cylcty=232d,dArr=21d3,dHar=2965,dagger=2020,da",
|
|
420
|
+
"leth=2138,darr=2193,dash=2010,dashv=22a3,dbkarow=290f,dblac=2dd,dcaron=10f,dcy=434,dd=2146,ddagger=2",
|
|
421
|
+
"021,ddarr=21ca,ddotseq=2a77,deg=b0,delta=3b4,demptyv=29b1,dfisht=297f,dfr=1d521,dharl=21c3,dharr=21c",
|
|
422
|
+
"2,diam=22c4,diamond=22c4,diamondsuit=2666,diams=2666,die=a8,digamma=3dd,disin=22f2,div=f7,divide=f7,",
|
|
423
|
+
"divideontimes=22c7,divonx=22c7,djcy=452,dlcorn=231e,dlcrop=230d,dollar=24,dopf=1d555,dot=2d9,doteq=2",
|
|
424
|
+
"250,doteqdot=2251,dotminus=2238,dotplus=2214,dotsquare=22a1,doublebarwedge=2306,downarrow=2193,downd",
|
|
425
|
+
"ownarrows=21ca,downharpoonleft=21c3,downharpoonright=21c2,drbkarow=2910,drcorn=231f,drcrop=230c,dscr",
|
|
426
|
+
"=1d4b9,dscy=455,dsol=29f6,dstrok=111,dtdot=22f1,dtri=25bf,dtrif=25be,duarr=21f5,duhar=296f,dwangle=2",
|
|
427
|
+
"9a6,dzcy=45f,dzigrarr=27ff,eDDot=2a77,eDot=2251,eacute=e9,easter=2a6e,ecaron=11b,ecir=2256,ecirc=ea,",
|
|
428
|
+
"ecolon=2255,ecy=44d,edot=117,ee=2147,efDot=2252,efr=1d522,eg=2a9a,egrave=e8,egs=2a96,egsdot=2a98,el=",
|
|
429
|
+
"2a99,elinters=23e7,ell=2113,els=2a95,elsdot=2a97,emacr=113,empty=2205,emptyset=2205,emptyv=2205,emsp",
|
|
430
|
+
"=2003,emsp13=2004,emsp14=2005,eng=14b,ensp=2002,eogon=119,eopf=1d556,epar=22d5,eparsl=29e3,eplus=2a7",
|
|
431
|
+
"1,epsi=3b5,epsilon=3b5,epsiv=3f5,eqcirc=2256,eqcolon=2255,eqsim=2242,eqslantgtr=2a96,eqslantless=2a9",
|
|
432
|
+
"5,equals=3d,equest=225f,equiv=2261,equivDD=2a78,eqvparsl=29e5,erDot=2253,erarr=2971,escr=212f,esdot=",
|
|
433
|
+
"2250,esim=2242,eta=3b7,eth=f0,euml=eb,euro=20ac,excl=21,exist=2203,expectation=2130,exponentiale=214",
|
|
434
|
+
"7,fallingdotseq=2252,fcy=444,female=2640,ffilig=fb03,fflig=fb00,ffllig=fb04,ffr=1d523,filig=fb01,fjl",
|
|
435
|
+
"ig=66.6a,flat=266d,fllig=fb02,fltns=25b1,fnof=192,fopf=1d557,forall=2200,fork=22d4,forkv=2ad9,fparti",
|
|
436
|
+
"nt=2a0d,frac12=bd,frac13=2153,frac14=bc,frac15=2155,frac16=2159,frac18=215b,frac23=2154,frac25=2156,",
|
|
437
|
+
"frac34=be,frac35=2157,frac38=215c,frac45=2158,frac56=215a,frac58=215d,frac78=215e,frasl=2044,frown=2",
|
|
438
|
+
"322,fscr=1d4bb,gE=2267,gEl=2a8c,gacute=1f5,gamma=3b3,gammad=3dd,gap=2a86,gbreve=11f,gcirc=11d,gcy=43",
|
|
439
|
+
"3,gdot=121,ge=2265,gel=22db,geq=2265,geqq=2267,geqslant=2a7e,ges=2a7e,gescc=2aa9,gesdot=2a80,gesdoto",
|
|
440
|
+
"=2a82,gesdotol=2a84,gesl=22db.fe00,gesles=2a94,gfr=1d524,gg=226b,ggg=22d9,gimel=2137,gjcy=453,gl=227",
|
|
441
|
+
"7,glE=2a92,gla=2aa5,glj=2aa4,gnE=2269,gnap=2a8a,gnapprox=2a8a,gne=2a88,gneq=2a88,gneqq=2269,gnsim=22",
|
|
442
|
+
"e7,gopf=1d558,grave=60,gscr=210a,gsim=2273,gsime=2a8e,gsiml=2a90,gt=3e,gtcc=2aa7,gtcir=2a7a,gtdot=22",
|
|
443
|
+
"d7,gtlPar=2995,gtquest=2a7c,gtrapprox=2a86,gtrarr=2978,gtrdot=22d7,gtreqless=22db,gtreqqless=2a8c,gt",
|
|
444
|
+
"rless=2277,gtrsim=2273,gvertneqq=2269.fe00,gvnE=2269.fe00,hArr=21d4,hairsp=200a,half=bd,hamilt=210b,",
|
|
445
|
+
"hardcy=44a,harr=2194,harrcir=2948,harrw=21ad,hbar=210f,hcirc=125,hearts=2665,heartsuit=2665,hellip=2",
|
|
446
|
+
"026,hercon=22b9,hfr=1d525,hksearow=2925,hkswarow=2926,hoarr=21ff,homtht=223b,hookleftarrow=21a9,hook",
|
|
447
|
+
"rightarrow=21aa,hopf=1d559,horbar=2015,hscr=1d4bd,hslash=210f,hstrok=127,hybull=2043,hyphen=2010,iac",
|
|
448
|
+
"ute=ed,ic=2063,icirc=ee,icy=438,iecy=435,iexcl=a1,iff=21d4,ifr=1d526,igrave=ec,ii=2148,iiiint=2a0c,i",
|
|
449
|
+
"iint=222d,iinfin=29dc,iiota=2129,ijlig=133,imacr=12b,image=2111,imagline=2110,imagpart=2111,imath=13",
|
|
450
|
+
"1,imof=22b7,imped=1b5,in=2208,incare=2105,infin=221e,infintie=29dd,inodot=131,int=222b,intcal=22ba,i",
|
|
451
|
+
"ntegers=2124,intercal=22ba,intlarhk=2a17,intprod=2a3c,iocy=451,iogon=12f,iopf=1d55a,iota=3b9,iprod=2",
|
|
452
|
+
"a3c,iquest=bf,iscr=1d4be,isin=2208,isinE=22f9,isindot=22f5,isins=22f4,isinsv=22f3,isinv=2208,it=2062",
|
|
453
|
+
",itilde=129,iukcy=456,iuml=ef,jcirc=135,jcy=439,jfr=1d527,jmath=237,jopf=1d55b,jscr=1d4bf,jsercy=458",
|
|
454
|
+
",jukcy=454,kappa=3ba,kappav=3f0,kcedil=137,kcy=43a,kfr=1d528,kgreen=138,khcy=445,kjcy=45c,kopf=1d55c",
|
|
455
|
+
",kscr=1d4c0,lAarr=21da,lArr=21d0,lAtail=291b,lBarr=290e,lE=2266,lEg=2a8b,lHar=2962,lacute=13a,laempt",
|
|
456
|
+
"yv=29b4,lagran=2112,lambda=3bb,lang=27e8,langd=2991,langle=27e8,lap=2a85,laquo=ab,larr=2190,larrb=21",
|
|
457
|
+
"e4,larrbfs=291f,larrfs=291d,larrhk=21a9,larrlp=21ab,larrpl=2939,larrsim=2973,larrtl=21a2,lat=2aab,la",
|
|
458
|
+
"tail=2919,late=2aad,lates=2aad.fe00,lbarr=290c,lbbrk=2772,lbrace=7b,lbrack=5b,lbrke=298b,lbrksld=298",
|
|
459
|
+
"f,lbrkslu=298d,lcaron=13e,lcedil=13c,lceil=2308,lcub=7b,lcy=43b,ldca=2936,ldquo=201c,ldquor=201e,ldr",
|
|
460
|
+
"dhar=2967,ldrushar=294b,ldsh=21b2,le=2264,leftarrow=2190,leftarrowtail=21a2,leftharpoondown=21bd,lef",
|
|
461
|
+
"tharpoonup=21bc,leftleftarrows=21c7,leftrightarrow=2194,leftrightarrows=21c6,leftrightharpoons=21cb,",
|
|
462
|
+
"leftrightsquigarrow=21ad,leftthreetimes=22cb,leg=22da,leq=2264,leqq=2266,leqslant=2a7d,les=2a7d,lesc",
|
|
463
|
+
"c=2aa8,lesdot=2a7f,lesdoto=2a81,lesdotor=2a83,lesg=22da.fe00,lesges=2a93,lessapprox=2a85,lessdot=22d",
|
|
464
|
+
"6,lesseqgtr=22da,lesseqqgtr=2a8b,lessgtr=2276,lesssim=2272,lfisht=297c,lfloor=230a,lfr=1d529,lg=2276",
|
|
465
|
+
",lgE=2a91,lhard=21bd,lharu=21bc,lharul=296a,lhblk=2584,ljcy=459,ll=226a,llarr=21c7,llcorner=231e,llh",
|
|
466
|
+
"ard=296b,lltri=25fa,lmidot=140,lmoust=23b0,lmoustache=23b0,lnE=2268,lnap=2a89,lnapprox=2a89,lne=2a87",
|
|
467
|
+
",lneq=2a87,lneqq=2268,lnsim=22e6,loang=27ec,loarr=21fd,lobrk=27e6,longleftarrow=27f5,longleftrightar",
|
|
468
|
+
"row=27f7,longmapsto=27fc,longrightarrow=27f6,looparrowleft=21ab,looparrowright=21ac,lopar=2985,lopf=",
|
|
469
|
+
"1d55d,loplus=2a2d,lotimes=2a34,lowast=2217,lowbar=5f,loz=25ca,lozenge=25ca,lozf=29eb,lpar=28,lparlt=",
|
|
470
|
+
"2993,lrarr=21c6,lrcorner=231f,lrhar=21cb,lrhard=296d,lrm=200e,lrtri=22bf,lsaquo=2039,lscr=1d4c1,lsh=",
|
|
471
|
+
"21b0,lsim=2272,lsime=2a8d,lsimg=2a8f,lsqb=5b,lsquo=2018,lsquor=201a,lstrok=142,lt=3c,ltcc=2aa6,ltcir",
|
|
472
|
+
"=2a79,ltdot=22d6,lthree=22cb,ltimes=22c9,ltlarr=2976,ltquest=2a7b,ltrPar=2996,ltri=25c3,ltrie=22b4,l",
|
|
473
|
+
"trif=25c2,lurdshar=294a,luruhar=2966,lvertneqq=2268.fe00,lvnE=2268.fe00,mDDot=223a,macr=af,male=2642",
|
|
474
|
+
",malt=2720,maltese=2720,map=21a6,mapsto=21a6,mapstodown=21a7,mapstoleft=21a4,mapstoup=21a5,marker=25",
|
|
475
|
+
"ae,mcomma=2a29,mcy=43c,mdash=2014,measuredangle=2221,mfr=1d52a,mho=2127,micro=b5,mid=2223,midast=2a,",
|
|
476
|
+
"midcir=2af0,middot=b7,minus=2212,minusb=229f,minusd=2238,minusdu=2a2a,mlcp=2adb,mldr=2026,mnplus=221",
|
|
477
|
+
"3,models=22a7,mopf=1d55e,mp=2213,mscr=1d4c2,mstpos=223e,mu=3bc,multimap=22b8,mumap=22b8,nGg=22d9.338",
|
|
478
|
+
",nGt=226b.20d2,nGtv=226b.338,nLeftarrow=21cd,nLeftrightarrow=21ce,nLl=22d8.338,nLt=226a.20d2,nLtv=22",
|
|
479
|
+
"6a.338,nRightarrow=21cf,nVDash=22af,nVdash=22ae,nabla=2207,nacute=144,nang=2220.20d2,nap=2249,napE=2",
|
|
480
|
+
"a70.338,napid=224b.338,napos=149,napprox=2249,natur=266e,natural=266e,naturals=2115,nbsp=a0,nbump=22",
|
|
481
|
+
"4e.338,nbumpe=224f.338,ncap=2a43,ncaron=148,ncedil=146,ncong=2247,ncongdot=2a6d.338,ncup=2a42,ncy=43",
|
|
482
|
+
"d,ndash=2013,ne=2260,neArr=21d7,nearhk=2924,nearr=2197,nearrow=2197,nedot=2250.338,nequiv=2262,nesea",
|
|
483
|
+
"r=2928,nesim=2242.338,nexist=2204,nexists=2204,nfr=1d52b,ngE=2267.338,nge=2271,ngeq=2271,ngeqq=2267.",
|
|
484
|
+
"338,ngeqslant=2a7e.338,nges=2a7e.338,ngsim=2275,ngt=226f,ngtr=226f,nhArr=21ce,nharr=21ae,nhpar=2af2,",
|
|
485
|
+
"ni=220b,nis=22fc,nisd=22fa,niv=220b,njcy=45a,nlArr=21cd,nlE=2266.338,nlarr=219a,nldr=2025,nle=2270,n",
|
|
486
|
+
"leftarrow=219a,nleftrightarrow=21ae,nleq=2270,nleqq=2266.338,nleqslant=2a7d.338,nles=2a7d.338,nless=",
|
|
487
|
+
"226e,nlsim=2274,nlt=226e,nltri=22ea,nltrie=22ec,nmid=2224,nopf=1d55f,not=ac,notin=2209,notinE=22f9.3",
|
|
488
|
+
"38,notindot=22f5.338,notinva=2209,notinvb=22f7,notinvc=22f6,notni=220c,notniva=220c,notnivb=22fe,not",
|
|
489
|
+
"nivc=22fd,npar=2226,nparallel=2226,nparsl=2afd.20e5,npart=2202.338,npolint=2a14,npr=2280,nprcue=22e0",
|
|
490
|
+
",npre=2aaf.338,nprec=2280,npreceq=2aaf.338,nrArr=21cf,nrarr=219b,nrarrc=2933.338,nrarrw=219d.338,nri",
|
|
491
|
+
"ghtarrow=219b,nrtri=22eb,nrtrie=22ed,nsc=2281,nsccue=22e1,nsce=2ab0.338,nscr=1d4c3,nshortmid=2224,ns",
|
|
492
|
+
"hortparallel=2226,nsim=2241,nsime=2244,nsimeq=2244,nsmid=2224,nspar=2226,nsqsube=22e2,nsqsupe=22e3,n",
|
|
493
|
+
"sub=2284,nsubE=2ac5.338,nsube=2288,nsubset=2282.20d2,nsubseteq=2288,nsubseteqq=2ac5.338,nsucc=2281,n",
|
|
494
|
+
"succeq=2ab0.338,nsup=2285,nsupE=2ac6.338,nsupe=2289,nsupset=2283.20d2,nsupseteq=2289,nsupseteqq=2ac6",
|
|
495
|
+
".338,ntgl=2279,ntilde=f1,ntlg=2278,ntriangleleft=22ea,ntrianglelefteq=22ec,ntriangleright=22eb,ntria",
|
|
496
|
+
"nglerighteq=22ed,nu=3bd,num=23,numero=2116,numsp=2007,nvDash=22ad,nvHarr=2904,nvap=224d.20d2,nvdash=",
|
|
497
|
+
"22ac,nvge=2265.20d2,nvgt=3e.20d2,nvinfin=29de,nvlArr=2902,nvle=2264.20d2,nvlt=3c.20d2,nvltrie=22b4.2",
|
|
498
|
+
"0d2,nvrArr=2903,nvrtrie=22b5.20d2,nvsim=223c.20d2,nwArr=21d6,nwarhk=2923,nwarr=2196,nwarrow=2196,nwn",
|
|
499
|
+
"ear=2927,oS=24c8,oacute=f3,oast=229b,ocir=229a,ocirc=f4,ocy=43e,odash=229d,odblac=151,odiv=2a38,odot",
|
|
500
|
+
"=2299,odsold=29bc,oelig=153,ofcir=29bf,ofr=1d52c,ogon=2db,ograve=f2,ogt=29c1,ohbar=29b5,ohm=3a9,oint",
|
|
501
|
+
"=222e,olarr=21ba,olcir=29be,olcross=29bb,oline=203e,olt=29c0,omacr=14d,omega=3c9,omicron=3bf,omid=29",
|
|
502
|
+
"b6,ominus=2296,oopf=1d560,opar=29b7,operp=29b9,oplus=2295,or=2228,orarr=21bb,ord=2a5d,order=2134,ord",
|
|
503
|
+
"erof=2134,ordf=aa,ordm=ba,origof=22b6,oror=2a56,orslope=2a57,orv=2a5b,oscr=2134,oslash=f8,osol=2298,",
|
|
504
|
+
"otilde=f5,otimes=2297,otimesas=2a36,ouml=f6,ovbar=233d,par=2225,para=b6,parallel=2225,parsim=2af3,pa",
|
|
505
|
+
"rsl=2afd,part=2202,pcy=43f,percnt=25,period=2e,permil=2030,perp=22a5,pertenk=2031,pfr=1d52d,phi=3c6,",
|
|
506
|
+
"phiv=3d5,phmmat=2133,phone=260e,pi=3c0,pitchfork=22d4,piv=3d6,planck=210f,planckh=210e,plankv=210f,p",
|
|
507
|
+
"lus=2b,plusacir=2a23,plusb=229e,pluscir=2a22,plusdo=2214,plusdu=2a25,pluse=2a72,plusmn=b1,plussim=2a",
|
|
508
|
+
"26,plustwo=2a27,pm=b1,pointint=2a15,popf=1d561,pound=a3,pr=227a,prE=2ab3,prap=2ab7,prcue=227c,pre=2a",
|
|
509
|
+
"af,prec=227a,precapprox=2ab7,preccurlyeq=227c,preceq=2aaf,precnapprox=2ab9,precneqq=2ab5,precnsim=22",
|
|
510
|
+
"e8,precsim=227e,prime=2032,primes=2119,prnE=2ab5,prnap=2ab9,prnsim=22e8,prod=220f,profalar=232e,prof",
|
|
511
|
+
"line=2312,profsurf=2313,prop=221d,propto=221d,prsim=227e,prurel=22b0,pscr=1d4c5,psi=3c8,puncsp=2008,",
|
|
512
|
+
"qfr=1d52e,qint=2a0c,qopf=1d562,qprime=2057,qscr=1d4c6,quaternions=210d,quatint=2a16,quest=3f,questeq",
|
|
513
|
+
"=225f,quot=22,rAarr=21db,rArr=21d2,rAtail=291c,rBarr=290f,rHar=2964,race=223d.331,racute=155,radic=2",
|
|
514
|
+
"21a,raemptyv=29b3,rang=27e9,rangd=2992,range=29a5,rangle=27e9,raquo=bb,rarr=2192,rarrap=2975,rarrb=2",
|
|
515
|
+
"1e5,rarrbfs=2920,rarrc=2933,rarrfs=291e,rarrhk=21aa,rarrlp=21ac,rarrpl=2945,rarrsim=2974,rarrtl=21a3",
|
|
516
|
+
",rarrw=219d,ratail=291a,ratio=2236,rationals=211a,rbarr=290d,rbbrk=2773,rbrace=7d,rbrack=5d,rbrke=29",
|
|
517
|
+
"8c,rbrksld=298e,rbrkslu=2990,rcaron=159,rcedil=157,rceil=2309,rcub=7d,rcy=440,rdca=2937,rdldhar=2969",
|
|
518
|
+
",rdquo=201d,rdquor=201d,rdsh=21b3,real=211c,realine=211b,realpart=211c,reals=211d,rect=25ad,reg=ae,r",
|
|
519
|
+
"fisht=297d,rfloor=230b,rfr=1d52f,rhard=21c1,rharu=21c0,rharul=296c,rho=3c1,rhov=3f1,rightarrow=2192,",
|
|
520
|
+
"rightarrowtail=21a3,rightharpoondown=21c1,rightharpoonup=21c0,rightleftarrows=21c4,rightleftharpoons",
|
|
521
|
+
"=21cc,rightrightarrows=21c9,rightsquigarrow=219d,rightthreetimes=22cc,ring=2da,risingdotseq=2253,rla",
|
|
522
|
+
"rr=21c4,rlhar=21cc,rlm=200f,rmoust=23b1,rmoustache=23b1,rnmid=2aee,roang=27ed,roarr=21fe,robrk=27e7,",
|
|
523
|
+
"ropar=2986,ropf=1d563,roplus=2a2e,rotimes=2a35,rpar=29,rpargt=2994,rppolint=2a12,rrarr=21c9,rsaquo=2",
|
|
524
|
+
"03a,rscr=1d4c7,rsh=21b1,rsqb=5d,rsquo=2019,rsquor=2019,rthree=22cc,rtimes=22ca,rtri=25b9,rtrie=22b5,",
|
|
525
|
+
"rtrif=25b8,rtriltri=29ce,ruluhar=2968,rx=211e,sacute=15b,sbquo=201a,sc=227b,scE=2ab4,scap=2ab8,scaro",
|
|
526
|
+
"n=161,sccue=227d,sce=2ab0,scedil=15f,scirc=15d,scnE=2ab6,scnap=2aba,scnsim=22e9,scpolint=2a13,scsim=",
|
|
527
|
+
"227f,scy=441,sdot=22c5,sdotb=22a1,sdote=2a66,seArr=21d8,searhk=2925,searr=2198,searrow=2198,sect=a7,",
|
|
528
|
+
"semi=3b,seswar=2929,setminus=2216,setmn=2216,sext=2736,sfr=1d530,sfrown=2322,sharp=266f,shchcy=449,s",
|
|
529
|
+
"hcy=448,shortmid=2223,shortparallel=2225,shy=ad,sigma=3c3,sigmaf=3c2,sigmav=3c2,sim=223c,simdot=2a6a",
|
|
530
|
+
",sime=2243,simeq=2243,simg=2a9e,simgE=2aa0,siml=2a9d,simlE=2a9f,simne=2246,simplus=2a24,simrarr=2972",
|
|
531
|
+
",slarr=2190,smallsetminus=2216,smashp=2a33,smeparsl=29e4,smid=2223,smile=2323,smt=2aaa,smte=2aac,smt",
|
|
532
|
+
"es=2aac.fe00,softcy=44c,sol=2f,solb=29c4,solbar=233f,sopf=1d564,spades=2660,spadesuit=2660,spar=2225",
|
|
533
|
+
",sqcap=2293,sqcaps=2293.fe00,sqcup=2294,sqcups=2294.fe00,sqsub=228f,sqsube=2291,sqsubset=228f,sqsubs",
|
|
534
|
+
"eteq=2291,sqsup=2290,sqsupe=2292,sqsupset=2290,sqsupseteq=2292,squ=25a1,square=25a1,squarf=25aa,squf",
|
|
535
|
+
"=25aa,srarr=2192,sscr=1d4c8,ssetmn=2216,ssmile=2323,sstarf=22c6,star=2606,starf=2605,straightepsilon",
|
|
536
|
+
"=3f5,straightphi=3d5,strns=af,sub=2282,subE=2ac5,subdot=2abd,sube=2286,subedot=2ac3,submult=2ac1,sub",
|
|
537
|
+
"nE=2acb,subne=228a,subplus=2abf,subrarr=2979,subset=2282,subseteq=2286,subseteqq=2ac5,subsetneq=228a",
|
|
538
|
+
",subsetneqq=2acb,subsim=2ac7,subsub=2ad5,subsup=2ad3,succ=227b,succapprox=2ab8,succcurlyeq=227d,succ",
|
|
539
|
+
"eq=2ab0,succnapprox=2aba,succneqq=2ab6,succnsim=22e9,succsim=227f,sum=2211,sung=266a,sup=2283,sup1=b",
|
|
540
|
+
"9,sup2=b2,sup3=b3,supE=2ac6,supdot=2abe,supdsub=2ad8,supe=2287,supedot=2ac4,suphsol=27c9,suphsub=2ad",
|
|
541
|
+
"7,suplarr=297b,supmult=2ac2,supnE=2acc,supne=228b,supplus=2ac0,supset=2283,supseteq=2287,supseteqq=2",
|
|
542
|
+
"ac6,supsetneq=228b,supsetneqq=2acc,supsim=2ac8,supsub=2ad4,supsup=2ad6,swArr=21d9,swarhk=2926,swarr=",
|
|
543
|
+
"2199,swarrow=2199,swnwar=292a,szlig=df,target=2316,tau=3c4,tbrk=23b4,tcaron=165,tcedil=163,tcy=442,t",
|
|
544
|
+
"dot=20db,telrec=2315,tfr=1d531,there4=2234,therefore=2234,theta=3b8,thetasym=3d1,thetav=3d1,thickapp",
|
|
545
|
+
"rox=2248,thicksim=223c,thinsp=2009,thkap=2248,thksim=223c,thorn=fe,tilde=2dc,times=d7,timesb=22a0,ti",
|
|
546
|
+
"mesbar=2a31,timesd=2a30,tint=222d,toea=2928,top=22a4,topbot=2336,topcir=2af1,topf=1d565,topfork=2ada",
|
|
547
|
+
",tosa=2929,tprime=2034,trade=2122,triangle=25b5,triangledown=25bf,triangleleft=25c3,trianglelefteq=2",
|
|
548
|
+
"2b4,triangleq=225c,triangleright=25b9,trianglerighteq=22b5,tridot=25ec,trie=225c,triminus=2a3a,tripl",
|
|
549
|
+
"us=2a39,trisb=29cd,tritime=2a3b,trpezium=23e2,tscr=1d4c9,tscy=446,tshcy=45b,tstrok=167,twixt=226c,tw",
|
|
550
|
+
"oheadleftarrow=219e,twoheadrightarrow=21a0,uArr=21d1,uHar=2963,uacute=fa,uarr=2191,ubrcy=45e,ubreve=",
|
|
551
|
+
"16d,ucirc=fb,ucy=443,udarr=21c5,udblac=171,udhar=296e,ufisht=297e,ufr=1d532,ugrave=f9,uharl=21bf,uha",
|
|
552
|
+
"rr=21be,uhblk=2580,ulcorn=231c,ulcorner=231c,ulcrop=230f,ultri=25f8,umacr=16b,uml=a8,uogon=173,uopf=",
|
|
553
|
+
"1d566,uparrow=2191,updownarrow=2195,upharpoonleft=21bf,upharpoonright=21be,uplus=228e,upsi=3c5,upsih",
|
|
554
|
+
"=3d2,upsilon=3c5,upuparrows=21c8,urcorn=231d,urcorner=231d,urcrop=230e,uring=16f,urtri=25f9,uscr=1d4",
|
|
555
|
+
"ca,utdot=22f0,utilde=169,utri=25b5,utrif=25b4,uuarr=21c8,uuml=fc,uwangle=29a7,vArr=21d5,vBar=2ae8,vB",
|
|
556
|
+
"arv=2ae9,vDash=22a8,vangrt=299c,varepsilon=3f5,varkappa=3f0,varnothing=2205,varphi=3d5,varpi=3d6,var",
|
|
557
|
+
"propto=221d,varr=2195,varrho=3f1,varsigma=3c2,varsubsetneq=228a.fe00,varsubsetneqq=2acb.fe00,varsups",
|
|
558
|
+
"etneq=228b.fe00,varsupsetneqq=2acc.fe00,vartheta=3d1,vartriangleleft=22b2,vartriangleright=22b3,vcy=",
|
|
559
|
+
"432,vdash=22a2,vee=2228,veebar=22bb,veeeq=225a,vellip=22ee,verbar=7c,vert=7c,vfr=1d533,vltri=22b2,vn",
|
|
560
|
+
"sub=2282.20d2,vnsup=2283.20d2,vopf=1d567,vprop=221d,vrtri=22b3,vscr=1d4cb,vsubnE=2acb.fe00,vsubne=22",
|
|
561
|
+
"8a.fe00,vsupnE=2acc.fe00,vsupne=228b.fe00,vzigzag=299a,wcirc=175,wedbar=2a5f,wedge=2227,wedgeq=2259,",
|
|
562
|
+
"weierp=2118,wfr=1d534,wopf=1d568,wp=2118,wr=2240,wreath=2240,wscr=1d4cc,xcap=22c2,xcirc=25ef,xcup=22",
|
|
563
|
+
"c3,xdtri=25bd,xfr=1d535,xhArr=27fa,xharr=27f7,xi=3be,xlArr=27f8,xlarr=27f5,xmap=27fc,xnis=22fb,xodot",
|
|
564
|
+
"=2a00,xopf=1d569,xoplus=2a01,xotime=2a02,xrArr=27f9,xrarr=27f6,xscr=1d4cd,xsqcup=2a06,xuplus=2a04,xu",
|
|
565
|
+
"tri=25b3,xvee=22c1,xwedge=22c0,yacute=fd,yacy=44f,ycirc=177,ycy=44b,yen=a5,yfr=1d536,yicy=457,yopf=1",
|
|
566
|
+
"d56a,yscr=1d4ce,yucy=44e,yuml=ff,zacute=17a,zcaron=17e,zcy=437,zdot=17c,zeetrf=2128,zeta=3b6,zfr=1d5",
|
|
567
|
+
"37,zhcy=436,zigrarr=21dd,zopf=1d56b,zscr=1d4cf,zwj=200d,zwnj=200c"
|
|
568
|
+
].join("");
|
|
569
|
+
var NAMED_REFERENCES = new Map(NAMED.split(",").map((entry) => {
|
|
570
|
+
const [name, codes] = entry.split("=");
|
|
571
|
+
return [name, String.fromCodePoint(...codes.split(".").map((code) => Number.parseInt(code, 16)))];
|
|
572
|
+
}));
|
|
573
|
+
|
|
574
|
+
// src/html.js
|
|
575
|
+
var LATIN1 = "nbsp iexcl cent pound curren yen brvbar sect uml copy ordf laquo not shy reg macr deg plusmn sup2 sup3 acute micro para middot cedil sup1 ordm raquo frac14 frac12 frac34 iquest Agrave Aacute Acirc Atilde Auml Aring AElig Ccedil Egrave Eacute Ecirc Euml Igrave Iacute Icirc Iuml ETH Ntilde Ograve Oacute Ocirc Otilde Ouml times Oslash Ugrave Uacute Ucirc Uuml Yacute THORN szlig agrave aacute acirc atilde auml aring aelig ccedil egrave eacute ecirc euml igrave iacute icirc iuml eth ntilde ograve oacute ocirc otilde ouml divide oslash ugrave uacute ucirc uuml yacute thorn yuml".split(" ");
|
|
576
|
+
var LEGACY = /* @__PURE__ */ new Set([...LATIN1, "amp", "lt", "gt", "quot", "AMP", "LT", "GT", "QUOT", "COPY", "REG"]);
|
|
577
|
+
var LEGACY_LONGEST = Math.max(...[...LEGACY].map((name) => name.length));
|
|
578
|
+
var UNSHOWN = /* @__PURE__ */ new Set(["script", "style", "title", "noembed", "noframes", "iframe"]);
|
|
579
|
+
var RAW_SHOWN = /* @__PURE__ */ new Set(["textarea", "xmp"]);
|
|
580
|
+
var RAW_END = Object.fromEntries([...UNSHOWN, ...RAW_SHOWN].map((name) => [name, linear(String.raw`<\/${caseless(name)}[\s/>]`, "g")]));
|
|
581
|
+
var CLOSES_PARAGRAPH = /* @__PURE__ */ new Set(["address", "article", "aside", "blockquote", "center", "dd", "details", "dialog", "dir", "div", "dl", "dt", "fieldset", "figcaption", "figure", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "header", "hgroup", "hr", "li", "listing", "main", "menu", "nav", "ol", "p", "plaintext", "pre", "search", "section", "summary", "table", "ul", "xmp"]);
|
|
582
|
+
var PARTS_OF_TABLE = /* @__PURE__ */ new Set(["caption", "col", "colgroup", "tbody", "td", "tfoot", "th", "thead", "tr"]);
|
|
583
|
+
var TABLE_STRUCTURE = [...PARTS_OF_TABLE, "table", "template"];
|
|
584
|
+
var NOT_REOPENING = /* @__PURE__ */ new Set([...CLOSES_PARAGRAPH, "base", "basefont", "bgsound", "body", "caption", "col", "colgroup", "frame", "frameset", "head", "html", "iframe", "link", "meta", "noembed", "noframes", "script", "style", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "title", "tr"]);
|
|
585
|
+
var COMMENT_END = linear("--!?>", "g");
|
|
586
|
+
var LABEL_END = linear(String.raw`<\/${caseless("label")}[\s/>]`);
|
|
587
|
+
var UNITS = {
|
|
588
|
+
px: 1,
|
|
589
|
+
pt: 4 / 3,
|
|
590
|
+
pc: 16,
|
|
591
|
+
in: 96,
|
|
592
|
+
cm: 96 / 2.54,
|
|
593
|
+
mm: 96 / 25.4,
|
|
594
|
+
q: 96 / 101.6,
|
|
595
|
+
rem: 16
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
// src/tokenizer.js
|
|
599
|
+
function characterClass(ranges, flags = "gu") {
|
|
600
|
+
const hex = (code) => `\\u{${code.toString(16)}}`;
|
|
601
|
+
return new RegExp(`[${ranges.map(([first, last]) => last ? `${hex(first)}-${hex(last)}` : hex(first)).join("")}]`, flags);
|
|
602
|
+
}
|
|
603
|
+
var INVISIBLE = [[173], [847], [4447, 4448], [6068, 6069], [6158], [8203], [8206, 8207], [8234, 8238], [8288, 8292], [8294, 8297], [12644], [65279], [65440]];
|
|
604
|
+
var OBFUSCATING = characterClass(INVISIBLE);
|
|
605
|
+
var JOINERS = characterClass([[8204, 8205], [65024, 65039]]);
|
|
606
|
+
var INVISIBLE_OR_JOINER = characterClass([...INVISIBLE, [8204, 8205]]);
|
|
607
|
+
var LATIN_END = new RegExp("\\p{Script=Latin}$", "u");
|
|
608
|
+
var LATIN_START = new RegExp("^\\p{Script=Latin}", "u");
|
|
609
|
+
var ZWSP_SCRIPTS = String.raw`\p{Script=Thai}\p{Script=Lao}\p{Script=Khmer}\p{Script=Myanmar}\p{Script=Tibetan}`;
|
|
610
|
+
var ZWSP_SCRIPT_END = new RegExp(`[${ZWSP_SCRIPTS}]$`, "u");
|
|
611
|
+
var ZWSP_SCRIPT_START = new RegExp(`^[${ZWSP_SCRIPTS}]`, "u");
|
|
612
|
+
var BIDI = characterClass([[8206, 8207], [8234, 8236], [8294, 8297]], "u");
|
|
613
|
+
var DIGIT_END = new RegExp("\\p{N}$", "u");
|
|
614
|
+
var DIGIT_START = new RegExp("^\\p{N}", "u");
|
|
615
|
+
var STYLED_LETTERS = characterClass([[119808, 120831], [127280, 127305]], "u");
|
|
616
|
+
var WIDE_LETTERS = characterClass([[9312, 9471], [65313, 65338], [65345, 65370]], "u");
|
|
617
|
+
var LOOKALIKES = {
|
|
618
|
+
\u0430: "a",
|
|
619
|
+
\u0432: "b",
|
|
620
|
+
\u0435: "e",
|
|
621
|
+
\u0451: "e",
|
|
622
|
+
\u043A: "k",
|
|
623
|
+
\u043C: "m",
|
|
624
|
+
\u043D: "h",
|
|
625
|
+
\u043E: "o",
|
|
626
|
+
\u0440: "p",
|
|
627
|
+
\u0441: "c",
|
|
628
|
+
\u0442: "t",
|
|
629
|
+
\u0443: "y",
|
|
630
|
+
\u0445: "x",
|
|
631
|
+
\u0455: "s",
|
|
632
|
+
\u0456: "i",
|
|
633
|
+
\u0457: "i",
|
|
634
|
+
\u0458: "j",
|
|
635
|
+
"\u0501": "d",
|
|
636
|
+
"\u051B": "q",
|
|
637
|
+
"\u051D": "w",
|
|
638
|
+
\u04BB: "h",
|
|
639
|
+
"\u04CF": "l",
|
|
640
|
+
\u0261: "g",
|
|
641
|
+
\u044C: "b",
|
|
642
|
+
\u043F: "n",
|
|
643
|
+
\u0433: "r",
|
|
644
|
+
\u03B1: "a",
|
|
645
|
+
\u03B2: "b",
|
|
646
|
+
\u03B5: "e",
|
|
647
|
+
\u03B7: "n",
|
|
648
|
+
\u03B9: "i",
|
|
649
|
+
\u03BA: "k",
|
|
650
|
+
\u03BD: "v",
|
|
651
|
+
\u03BF: "o",
|
|
652
|
+
\u03C1: "p",
|
|
653
|
+
\u03C4: "t",
|
|
654
|
+
\u03C5: "u",
|
|
655
|
+
\u03C7: "x",
|
|
656
|
+
\u03C9: "w",
|
|
657
|
+
\u03B3: "y",
|
|
658
|
+
\u03BC: "u"
|
|
659
|
+
};
|
|
660
|
+
var LEET_DIGITS = new RegExp("\\p{L}[0134578]{1,2}\\p{L}", "u");
|
|
661
|
+
var URL_PATTERN = linear(String.raw`\b(?:https?:\/\/|www\.)[^\s<>"'\x60]+|\b[a-z\d][a-z\d-]{0,62}(?:\.[a-z\d-]{1,63}){0,10}\.[a-z]{2,24}\/[^\s<>"'\x60]*`, "giu");
|
|
662
|
+
var EMAIL_SOURCE = String.raw`[\p{L}\p{N}._%+-]{1,64}@([\p{L}\p{N}-]{1,63}(?:\.[\p{L}\p{N}-]{1,63}){0,10}\.\p{L}{2,24})`;
|
|
663
|
+
var EMAIL_PATTERN = linear(EMAIL_SOURCE, "gu");
|
|
664
|
+
var PHONE_PATTERN = linear(String.raw`(?:\+|0{2})\d[\d\s().-]{7,}\d|\(\d{3}\)\s?\d{3}[\s.-]\d{4}|\b(?:\d{3}[.-]){2}\d{4}\b`, "g");
|
|
665
|
+
var IP_PATTERN = linear(String.raw`\b(?:25[0-5]|2[0-4]\d|1?\d?\d)(?:\.(?:25[0-5]|2[0-4]\d|1?\d?\d)){3}\b`, "g");
|
|
666
|
+
var MONEY_PATTERN = linear(String.raw`[$€£¥₹₽₩₺₦]\s?\d|\d\s?(?:[$€£¥₹₽₩₺₦]|usd|eur|gbp|dollars?|euros?)\b`, "giu");
|
|
667
|
+
var BITCOIN_PATTERN = linear(String.raw`\b(?:bc1[ac-hj-np-z02-9]{25,60}|[13][a-km-zA-HJ-NP-Z1-9]{25,34})\b`, "g");
|
|
668
|
+
var CARD_PATTERN = linear(String.raw`\b(?:\d[ -]?){13,19}\b`, "g");
|
|
669
|
+
var ANCHOR_START = linear(String.raw`<a[\t\n\f\r />]`, "gi");
|
|
670
|
+
var SHOWN_URL = linear(String.raw`^(?:https?:\/\/|www\.)\S+$|^[a-z\d-]{1,63}(?:\.[a-z\d-]{1,63}){1,10}(?:\/\S*)?$`, "i");
|
|
671
|
+
var IMG_PIXEL = linear(String.raw`<img\b[^<>]*\b(?:width|height)\s*=\s*["']?[01]["'\s>]`, "i");
|
|
672
|
+
var IMG = linear(String.raw`<img\b`, "gi");
|
|
673
|
+
var BARE_HOST = linear(String.raw`\b[a-z\d][a-z\d-]{0,62}(?:\.[a-z\d-]{1,63}){0,9}\.[a-z]{2,24}\b`, "gi");
|
|
674
|
+
var BRAND_NAMES = new Set(BRANDS);
|
|
675
|
+
var LATIN_LOOKALIKES = { Cyrillic: {}, Greek: {} };
|
|
676
|
+
for (const [char, latin] of Object.entries(LOOKALIKES)) {
|
|
677
|
+
const target = LATIN_LOOKALIKES[scriptOf(char)];
|
|
678
|
+
if (target && !target[latin]) {
|
|
679
|
+
target[latin] = char;
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
var LATIN = new RegExp("\\p{Script=Latin}", "u");
|
|
683
|
+
var ADDRESS_SOURCE = String.raw`[\p{L}\p{N}._%+-]{1,64}@([\p{L}\p{N}-]{1,63}(?:\.[\p{L}\p{N}-]{1,63}){1,10})`;
|
|
684
|
+
var NAMED_ADDRESS = linear(ADDRESS_SOURCE, "u");
|
|
685
|
+
|
|
686
|
+
// src/attachments.js
|
|
687
|
+
var EXECUTABLE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
688
|
+
"ade",
|
|
689
|
+
"adp",
|
|
690
|
+
"apk",
|
|
691
|
+
"app",
|
|
692
|
+
"appimage",
|
|
693
|
+
"appinstaller",
|
|
694
|
+
"application",
|
|
695
|
+
"appref-ms",
|
|
696
|
+
"appx",
|
|
697
|
+
"appxbundle",
|
|
698
|
+
"asp",
|
|
699
|
+
"aspx",
|
|
700
|
+
"asx",
|
|
701
|
+
"bas",
|
|
702
|
+
"bat",
|
|
703
|
+
"bgi",
|
|
704
|
+
"cab",
|
|
705
|
+
"chm",
|
|
706
|
+
"cmd",
|
|
707
|
+
"cnt",
|
|
708
|
+
"com",
|
|
709
|
+
"command",
|
|
710
|
+
"cpl",
|
|
711
|
+
"csh",
|
|
712
|
+
"diagcab",
|
|
713
|
+
"dll",
|
|
714
|
+
"dmg",
|
|
715
|
+
"docm",
|
|
716
|
+
"dotm",
|
|
717
|
+
"elf",
|
|
718
|
+
"exe",
|
|
719
|
+
"fxp",
|
|
720
|
+
"gadget",
|
|
721
|
+
"grp",
|
|
722
|
+
"hlp",
|
|
723
|
+
"hpj",
|
|
724
|
+
"hta",
|
|
725
|
+
"htc",
|
|
726
|
+
"img",
|
|
727
|
+
"inf",
|
|
728
|
+
"ins",
|
|
729
|
+
"ipa",
|
|
730
|
+
"iqy",
|
|
731
|
+
"iso",
|
|
732
|
+
"isp",
|
|
733
|
+
"its",
|
|
734
|
+
"jar",
|
|
735
|
+
"jnlp",
|
|
736
|
+
"js",
|
|
737
|
+
"jse",
|
|
738
|
+
"ksh",
|
|
739
|
+
"library-ms",
|
|
740
|
+
"lnk",
|
|
741
|
+
"mad",
|
|
742
|
+
"maf",
|
|
743
|
+
"mag",
|
|
744
|
+
"mam",
|
|
745
|
+
"maq",
|
|
746
|
+
"mar",
|
|
747
|
+
"mas",
|
|
748
|
+
"mau",
|
|
749
|
+
"mav",
|
|
750
|
+
"maw",
|
|
751
|
+
"mcf",
|
|
752
|
+
"mda",
|
|
753
|
+
"mde",
|
|
754
|
+
"mdt",
|
|
755
|
+
"mdw",
|
|
756
|
+
"mdz",
|
|
757
|
+
"msc",
|
|
758
|
+
"msh",
|
|
759
|
+
"msh1",
|
|
760
|
+
"msh1xml",
|
|
761
|
+
"msh2",
|
|
762
|
+
"msh2xml",
|
|
763
|
+
"mshxml",
|
|
764
|
+
"msi",
|
|
765
|
+
"msix",
|
|
766
|
+
"msixbundle",
|
|
767
|
+
"msp",
|
|
768
|
+
"mst",
|
|
769
|
+
"msu",
|
|
770
|
+
"nsh",
|
|
771
|
+
"one",
|
|
772
|
+
"onepkg",
|
|
773
|
+
"ops",
|
|
774
|
+
"osd",
|
|
775
|
+
"pcd",
|
|
776
|
+
"pif",
|
|
777
|
+
"pkg",
|
|
778
|
+
"pl",
|
|
779
|
+
"plg",
|
|
780
|
+
"potm",
|
|
781
|
+
"ppam",
|
|
782
|
+
"ppsm",
|
|
783
|
+
"pptm",
|
|
784
|
+
"prf",
|
|
785
|
+
"prg",
|
|
786
|
+
"ps1",
|
|
787
|
+
"ps1xml",
|
|
788
|
+
"ps2",
|
|
789
|
+
"ps2xml",
|
|
790
|
+
"psc1",
|
|
791
|
+
"psc2",
|
|
792
|
+
"py",
|
|
793
|
+
"pyc",
|
|
794
|
+
"pyo",
|
|
795
|
+
"pyw",
|
|
796
|
+
"pyz",
|
|
797
|
+
"pyzw",
|
|
798
|
+
"reg",
|
|
799
|
+
"scf",
|
|
800
|
+
"scpt",
|
|
801
|
+
"scr",
|
|
802
|
+
"sct",
|
|
803
|
+
"search-ms",
|
|
804
|
+
"searchconnector-ms",
|
|
805
|
+
"settingcontent-ms",
|
|
806
|
+
"sh",
|
|
807
|
+
"shb",
|
|
808
|
+
"shs",
|
|
809
|
+
"slk",
|
|
810
|
+
"sys",
|
|
811
|
+
"vb",
|
|
812
|
+
"vbe",
|
|
813
|
+
"vbp",
|
|
814
|
+
"vbs",
|
|
815
|
+
"vhd",
|
|
816
|
+
"vhdx",
|
|
817
|
+
"vsmacros",
|
|
818
|
+
"vsw",
|
|
819
|
+
"webpnp",
|
|
820
|
+
"website",
|
|
821
|
+
"ws",
|
|
822
|
+
"wsb",
|
|
823
|
+
"wsc",
|
|
824
|
+
"wsf",
|
|
825
|
+
"wsh",
|
|
826
|
+
"xbap",
|
|
827
|
+
"xlam",
|
|
828
|
+
"xll",
|
|
829
|
+
"xlsm",
|
|
830
|
+
"xltm",
|
|
831
|
+
"xnk"
|
|
832
|
+
]);
|
|
833
|
+
var RISKY_EXTENSIONS = /* @__PURE__ */ new Set(["cer", "der", "mat", "pst", "theme", "tmp", "url"]);
|
|
834
|
+
var SCRIPT_EXTENSIONS = /* @__PURE__ */ new Set(["asp", "aspx", "csh", "js", "ksh", "pl", "py", "pyc", "pyo", "pyw", "pyz", "pyzw", "sh"]);
|
|
835
|
+
var MACRO_EXTENSIONS = /* @__PURE__ */ new Set(["docm", "dotm", "xlsm", "xltm", "xlam", "pptm", "potm", "ppsm", "ppam", "sldm"]);
|
|
836
|
+
var DOCUMENT_EXTENSIONS = /* @__PURE__ */ new Set(["pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "txt", "rtf", "jpg", "jpeg", "png", "gif", "zip", "csv", "odt", "ods", "html", "htm", "mp3", "mp4", "mov", "wav", "eml", "msg", "xml", "json"]);
|
|
837
|
+
var TEMPORARY_EXTENSIONS = /* @__PURE__ */ new Set(["tmp"]);
|
|
838
|
+
var BIDI_CONTROLS = characterClass([[8234, 8238], [8294, 8297]], "u");
|
|
839
|
+
var ALL_BIDI_CONTROLS = characterClass([[8234, 8238], [8294, 8297]], "gu");
|
|
840
|
+
var ARCHIVE_TYPES = /* @__PURE__ */ new Set(["zip", "rar", "7z", "gz", "bz2", "xz", "cab", "iso", "tar", "zst", "lzh", "ace", "arj"]);
|
|
841
|
+
function sniff(buffer) {
|
|
842
|
+
if (!Buffer.isBuffer(buffer) || buffer.length < 4) {
|
|
843
|
+
return null;
|
|
844
|
+
}
|
|
845
|
+
const at = (offset, bytes) => buffer.length >= offset + bytes.length && bytes.every((byte, i) => buffer[offset + i] === byte);
|
|
846
|
+
const ascii = (offset, text) => at(offset, [...Buffer.from(text, "latin1")]);
|
|
847
|
+
const result = (type, executable = false) => ({ type, executable, archive: ARCHIVE_TYPES.has(type) });
|
|
848
|
+
if (ascii(0, "MZ") && buffer.length >= 64 && at(buffer.readUInt32LE(60), [80, 69, 0, 0])) {
|
|
849
|
+
return result("exe", true);
|
|
850
|
+
}
|
|
851
|
+
if (at(0, [127, 69, 76, 70])) {
|
|
852
|
+
return result("elf", true);
|
|
853
|
+
}
|
|
854
|
+
const magic = buffer.readUInt32BE(0);
|
|
855
|
+
if ([4277009102, 4277009103, 3472551422, 3489328638].includes(magic)) {
|
|
856
|
+
return result("macho", true);
|
|
857
|
+
}
|
|
858
|
+
if (magic === 3405691582) {
|
|
859
|
+
return result("macho", true);
|
|
860
|
+
}
|
|
861
|
+
if (at(0, [76, 0, 0, 0, 1, 20, 2, 0])) {
|
|
862
|
+
return result("lnk", true);
|
|
863
|
+
}
|
|
864
|
+
if (at(0, [208, 207, 17, 224, 161, 177, 26, 225])) {
|
|
865
|
+
return result("ole");
|
|
866
|
+
}
|
|
867
|
+
if (at(0, [80, 75, 3, 4]) || at(0, [80, 75, 5, 6])) {
|
|
868
|
+
const names = entriesOf(buffer).map((entry) => entry.name);
|
|
869
|
+
if (names.includes("AndroidManifest.xml") || names.includes("classes.dex")) {
|
|
870
|
+
return result("apk", true);
|
|
871
|
+
}
|
|
872
|
+
if (names.includes("META-INF/MANIFEST.MF") && names.some((name) => name.endsWith(".class"))) {
|
|
873
|
+
return result("jar", true);
|
|
874
|
+
}
|
|
875
|
+
if (names.some((name) => name.startsWith("word/"))) {
|
|
876
|
+
return result("docx");
|
|
877
|
+
}
|
|
878
|
+
if (names.some((name) => name.startsWith("xl/"))) {
|
|
879
|
+
return result("xlsx");
|
|
880
|
+
}
|
|
881
|
+
if (names.some((name) => name.startsWith("ppt/"))) {
|
|
882
|
+
return result("pptx");
|
|
883
|
+
}
|
|
884
|
+
return result("zip");
|
|
885
|
+
}
|
|
886
|
+
if (ascii(0, "Rar!")) {
|
|
887
|
+
return result("rar");
|
|
888
|
+
}
|
|
889
|
+
if (at(0, [55, 122, 188, 175, 39, 28])) {
|
|
890
|
+
return result("7z");
|
|
891
|
+
}
|
|
892
|
+
if (at(0, [31, 139])) {
|
|
893
|
+
return result("gz");
|
|
894
|
+
}
|
|
895
|
+
if (ascii(0, "MSCF")) {
|
|
896
|
+
return result("cab");
|
|
897
|
+
}
|
|
898
|
+
if (ascii(32769, "CD001") || ascii(34817, "CD001") || ascii(36865, "CD001")) {
|
|
899
|
+
return result("iso");
|
|
900
|
+
}
|
|
901
|
+
if (ascii(0, "conectix") || ascii(0, "vhdxfile")) {
|
|
902
|
+
return result("vhd", true);
|
|
903
|
+
}
|
|
904
|
+
if (ascii(0, "%PDF")) {
|
|
905
|
+
return result("pdf");
|
|
906
|
+
}
|
|
907
|
+
if (ascii(0, String.raw`{\rt`)) {
|
|
908
|
+
return result("rtf");
|
|
909
|
+
}
|
|
910
|
+
if (at(0, [137, 80, 78, 71])) {
|
|
911
|
+
return result("png");
|
|
912
|
+
}
|
|
913
|
+
if (at(0, [255, 216, 255])) {
|
|
914
|
+
return result("jpg");
|
|
915
|
+
}
|
|
916
|
+
if (ascii(0, "GIF8")) {
|
|
917
|
+
return result("gif");
|
|
918
|
+
}
|
|
919
|
+
if (ascii(0, "RIFF") && ascii(8, "WEBP")) {
|
|
920
|
+
return result("webp");
|
|
921
|
+
}
|
|
922
|
+
if (ascii(0, "#!")) {
|
|
923
|
+
return result("script", true);
|
|
924
|
+
}
|
|
925
|
+
const head = buffer.subarray(0, 1024).toString("utf8").replace(/^\uFEFF/u, "").trimStart().toLowerCase();
|
|
926
|
+
if (head.startsWith("<svg") || head.startsWith("<?xml") && head.includes("<svg")) {
|
|
927
|
+
return result("svg");
|
|
928
|
+
}
|
|
929
|
+
if (head.startsWith("<!doctype html") || head.startsWith("<html") || head.startsWith("<head") || head.startsWith("<script")) {
|
|
930
|
+
return result("html");
|
|
931
|
+
}
|
|
932
|
+
return null;
|
|
933
|
+
}
|
|
934
|
+
var ZIP_FAMILY = /* @__PURE__ */ new Set(["zip", "docx", "xlsx", "pptx"]);
|
|
935
|
+
var OFFICE_TYPES = /* @__PURE__ */ new Set(["docx", "xlsx", "pptx"]);
|
|
936
|
+
var OFFICE_EMBEDDED = MACRO_EXTENSIONS;
|
|
937
|
+
var ENTRIES = /* @__PURE__ */ new WeakMap();
|
|
938
|
+
function entriesOf(buffer) {
|
|
939
|
+
let entries = ENTRIES.get(buffer);
|
|
940
|
+
if (!entries) {
|
|
941
|
+
entries = zipEntries(buffer);
|
|
942
|
+
ENTRIES.set(buffer, entries);
|
|
943
|
+
}
|
|
944
|
+
return entries;
|
|
945
|
+
}
|
|
946
|
+
function zipEntries(buffer, limit = 2e3) {
|
|
947
|
+
const start = Math.max(0, buffer.length - 65557);
|
|
948
|
+
const records = [];
|
|
949
|
+
for (let i = buffer.length - 22; i >= start; i--) {
|
|
950
|
+
if (buffer.readUInt32LE(i) === 101010256 && (records.length === 0 || i + 22 + buffer.readUInt16LE(i + 20) === buffer.length)) {
|
|
951
|
+
records.push(i);
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
const state = {
|
|
955
|
+
entries: [],
|
|
956
|
+
limit,
|
|
957
|
+
read: /* @__PURE__ */ new Set(),
|
|
958
|
+
names: MAX_NAME_BYTES
|
|
959
|
+
};
|
|
960
|
+
for (const eocd of records) {
|
|
961
|
+
const offset = directoryOf(buffer, eocd);
|
|
962
|
+
if (offset !== -1) {
|
|
963
|
+
readDirectory(buffer, offset, state);
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
return state.entries;
|
|
967
|
+
}
|
|
968
|
+
var MAX_NAME_LENGTH = 1024;
|
|
969
|
+
var MAX_NAME_BYTES = 1024 * 1024;
|
|
970
|
+
var DIRECTORY = 33639248;
|
|
971
|
+
var isDirectory = (buffer, offset) => offset >= 0 && offset + 46 <= buffer.length && buffer.readUInt32LE(offset) === DIRECTORY;
|
|
972
|
+
function directoryOf(buffer, eocd) {
|
|
973
|
+
let offset = buffer.readUInt32LE(eocd + 16);
|
|
974
|
+
let size = buffer.readUInt32LE(eocd + 12);
|
|
975
|
+
const locator = eocd - 20;
|
|
976
|
+
if ((offset === 4294967295 || size === 4294967295) && locator >= 0 && buffer.readUInt32LE(locator) === 117853008) {
|
|
977
|
+
const stated = Number(buffer.readBigUInt64LE(locator + 8));
|
|
978
|
+
const isRecord = (at) => at >= 0 && at + 56 <= locator && buffer.readUInt32LE(at) === 101075792;
|
|
979
|
+
const record = isRecord(stated) ? stated : locator - 56;
|
|
980
|
+
if (isRecord(record)) {
|
|
981
|
+
size = Number(buffer.readBigUInt64LE(record + 40));
|
|
982
|
+
offset = Number(buffer.readBigUInt64LE(record + 48));
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
if (isDirectory(buffer, offset)) {
|
|
986
|
+
return offset;
|
|
987
|
+
}
|
|
988
|
+
for (const end of [eocd, locator - 56]) {
|
|
989
|
+
const directory = end - size;
|
|
990
|
+
if (directory < end && isDirectory(buffer, directory)) {
|
|
991
|
+
return directory;
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
return -1;
|
|
995
|
+
}
|
|
996
|
+
function readDirectory(buffer, offset, state) {
|
|
997
|
+
while (state.entries.length < state.limit && isDirectory(buffer, offset) && !state.read.has(offset)) {
|
|
998
|
+
state.read.add(offset);
|
|
999
|
+
const flags = buffer.readUInt16LE(offset + 8);
|
|
1000
|
+
const size = buffer.readUInt32LE(offset + 24);
|
|
1001
|
+
const nameLength = buffer.readUInt16LE(offset + 28);
|
|
1002
|
+
const extraLength = buffer.readUInt16LE(offset + 30);
|
|
1003
|
+
const commentLength = buffer.readUInt16LE(offset + 32);
|
|
1004
|
+
const encoding = flags & 2048 ? "utf8" : "latin1";
|
|
1005
|
+
const start = offset + 46;
|
|
1006
|
+
const end = Math.min(buffer.length, start + nameLength);
|
|
1007
|
+
const kept = Math.min(end - start, MAX_NAME_LENGTH);
|
|
1008
|
+
state.names -= kept;
|
|
1009
|
+
if (state.names < 0) {
|
|
1010
|
+
return;
|
|
1011
|
+
}
|
|
1012
|
+
const half = MAX_NAME_LENGTH / 2;
|
|
1013
|
+
const name = end - start > MAX_NAME_LENGTH ? `${buffer.toString(encoding, start, start + half)}\u2026${buffer.toString(encoding, end - half, end)}` : buffer.toString(encoding, start, end);
|
|
1014
|
+
state.entries.push({ name, encrypted: (flags & 1) === 1, size });
|
|
1015
|
+
offset += 46 + nameLength + extraLength + commentLength;
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
function shorten(name, max = 100) {
|
|
1019
|
+
const characters = [...name];
|
|
1020
|
+
return characters.length <= max ? name : `${characters.slice(0, max - 41).join("")}\u2026${characters.slice(-40).join("")}`;
|
|
1021
|
+
}
|
|
1022
|
+
function extensionOf(name) {
|
|
1023
|
+
const base = trimEndOf(String(name).toLowerCase().replace(ALL_BIDI_CONTROLS, "").split(/[/\\]/).pop(), ". ");
|
|
1024
|
+
const whole = lastExtension(base);
|
|
1025
|
+
const file = base.replace(/^[a-z]:/, "");
|
|
1026
|
+
const colon = file.indexOf(":");
|
|
1027
|
+
if (colon !== -1 && /^(?::?\$data)?$/.test(file.slice(colon + 1))) {
|
|
1028
|
+
return lastExtension(trimEndOf(file.slice(0, colon), ". "));
|
|
1029
|
+
}
|
|
1030
|
+
return whole;
|
|
1031
|
+
}
|
|
1032
|
+
var COMPRESSED_EXTENSIONS = /* @__PURE__ */ new Set(["gz", "bz2", "xz", "zst"]);
|
|
1033
|
+
function uncompressedName(name) {
|
|
1034
|
+
if (!COMPRESSED_EXTENSIONS.has(extensionOf(name))) {
|
|
1035
|
+
return String(name);
|
|
1036
|
+
}
|
|
1037
|
+
const trimmed = trimEndOf(String(name).replace(ALL_BIDI_CONTROLS, ""), ". ");
|
|
1038
|
+
return trimmed.slice(0, trimmed.lastIndexOf("."));
|
|
1039
|
+
}
|
|
1040
|
+
function lastExtension(base) {
|
|
1041
|
+
const dot = base.lastIndexOf(".");
|
|
1042
|
+
return dot === -1 ? "" : base.slice(dot + 1).trim();
|
|
1043
|
+
}
|
|
1044
|
+
var VBA_NAMES = /* @__PURE__ */ new Set(["vba", "_vba_project", "_vba_project_cur", "macros"]);
|
|
1045
|
+
function oleHasMacros(buffer) {
|
|
1046
|
+
for (let offset = 512; offset + 128 <= buffer.length; offset += 128) {
|
|
1047
|
+
const length = buffer.readUInt16LE(offset + 64);
|
|
1048
|
+
const type = buffer[offset + 66];
|
|
1049
|
+
if ((type === 1 || type === 2) && length >= 4 && length <= 64 && length % 2 === 0 && VBA_NAMES.has(buffer.subarray(offset, offset + length - 2).toString("utf16le").toLowerCase())) {
|
|
1050
|
+
return true;
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
return false;
|
|
1054
|
+
}
|
|
1055
|
+
var PDF_ACTIVE = linear(String.raw`\/(?:JavaScript|JS|Launch)\b`);
|
|
1056
|
+
var escaped = (character) => {
|
|
1057
|
+
const hex = character.codePointAt(0).toString(16);
|
|
1058
|
+
return `(?:${character}|#${hex[0]}[${hex[1].toLowerCase()}${hex[1].toUpperCase()}])`;
|
|
1059
|
+
};
|
|
1060
|
+
var WORD_ESCAPE = String.raw`#(?:3\d|4[1-9a-fA-F]|5[\daA]|5[fF]|6[1-9a-fA-F]|7[\daA])`;
|
|
1061
|
+
var PDF_ACTIVE_ESCAPED = new RegExp(`/(?:${["JavaScript", "JS", "Launch"].map((name) => [...name].map((character) => escaped(character)).join("")).join("|")})(?![\\w]|${WORD_ESCAPE})`);
|
|
1062
|
+
var pdfActive = (text) => PDF_ACTIVE.test(text) || PDF_ACTIVE_ESCAPED.test(text);
|
|
1063
|
+
function inspectAttachments(attachments = []) {
|
|
1064
|
+
const findings = [];
|
|
1065
|
+
for (const attachment of attachments) {
|
|
1066
|
+
const filename = typeof attachment.filename === "string" ? attachment.filename : "";
|
|
1067
|
+
const name = filename || "unnamed attachment";
|
|
1068
|
+
const content = Buffer.isBuffer(attachment.content) ? attachment.content : null;
|
|
1069
|
+
const extension = extensionOf(filename);
|
|
1070
|
+
const detected = content ? sniff(content) : null;
|
|
1071
|
+
const add = (type, message, extra = {}) => findings.push({
|
|
1072
|
+
type,
|
|
1073
|
+
filename: name,
|
|
1074
|
+
message,
|
|
1075
|
+
...extra
|
|
1076
|
+
});
|
|
1077
|
+
if (BIDI_CONTROLS.test(filename)) {
|
|
1078
|
+
add("rtl_override", `Attachment "${name}" uses a right-to-left override to hide its real extension`);
|
|
1079
|
+
}
|
|
1080
|
+
const parts = trimEndOf(filename.toLowerCase(), ". ").split(".");
|
|
1081
|
+
if (parts.length >= 3 && (EXECUTABLE_EXTENSIONS.has(extension) || RISKY_EXTENSIONS.has(extension)) && !TEMPORARY_EXTENSIONS.has(extension) && DOCUMENT_EXTENSIONS.has(parts.at(-2).trim())) {
|
|
1082
|
+
add("double_extension", `Attachment "${name}" has a document extension followed by a program extension`, { extension });
|
|
1083
|
+
}
|
|
1084
|
+
const byName = EXECUTABLE_EXTENSIONS.has(extension) && !MACRO_EXTENSIONS.has(extension);
|
|
1085
|
+
if (detected?.executable && (detected.type !== "script" || !byName)) {
|
|
1086
|
+
add(extension && !EXECUTABLE_EXTENSIONS.has(extension) ? "disguised_executable" : "executable", `Attachment "${name}" contains a program (${detected.type})${extension && extension !== detected.type ? ` but is named .${extension}` : ""}`, { extension: detected.type });
|
|
1087
|
+
} else if (byName) {
|
|
1088
|
+
add("executable", `Attachment "${name}" is a file type that runs code (.${extension})`, { extension });
|
|
1089
|
+
} else if (RISKY_EXTENSIONS.has(extension)) {
|
|
1090
|
+
add("risky_attachment", `Attachment "${name}" is a risky file type (.${extension})`, { extension });
|
|
1091
|
+
}
|
|
1092
|
+
const held = COMPRESSED_EXTENSIONS.has(extension) ? extensionOf(uncompressedName(filename)) : "";
|
|
1093
|
+
if (EXECUTABLE_EXTENSIONS.has(held)) {
|
|
1094
|
+
const script = SCRIPT_EXTENSIONS.has(held);
|
|
1095
|
+
add(script ? "script_in_archive" : "executable_in_archive", `Archive "${name}" contains ${script ? "a script" : "a program"} (${shorten(uncompressedName(filename).split(/[/\\]/).pop())})`, { extension: held, extensions: [held] });
|
|
1096
|
+
}
|
|
1097
|
+
const webPage = detected?.type === "html" || detected?.type === "svg" || ["htm", "html", "mht", "mhtml", "shtml", "xht", "xhtml", "svg"].includes(extension);
|
|
1098
|
+
const addWebPage = () => {
|
|
1099
|
+
const active = content !== null && /<script\b|<form\b|\bon(?:load|error|click)\s*=|javascript:|window\.location|document\.location|atob\(/i.test(content.subarray(0, 2e5).toString("utf8"));
|
|
1100
|
+
add("html_attachment", `Attachment "${name}" is ${detected?.type === "svg" || extension === "svg" ? "an SVG image" : "a web page"}${active ? " with scripts or forms" : ""}`, { extension: extension || detected?.type, active });
|
|
1101
|
+
};
|
|
1102
|
+
if (!content) {
|
|
1103
|
+
if (webPage) {
|
|
1104
|
+
addWebPage();
|
|
1105
|
+
}
|
|
1106
|
+
continue;
|
|
1107
|
+
}
|
|
1108
|
+
const zipFamily = ZIP_FAMILY.has(detected?.type) || extension === "zip" && !detected?.executable && entriesOf(content).length > 0;
|
|
1109
|
+
if (zipFamily) {
|
|
1110
|
+
const entries = entriesOf(content);
|
|
1111
|
+
const office = OFFICE_TYPES.has(detected?.type);
|
|
1112
|
+
if (entries.some((entry) => /(?:^|\/)vbaproject\.bin$/i.test(entry.name))) {
|
|
1113
|
+
add("macro", `Attachment "${name}" is an Office document with a VBA macro project`, { extension });
|
|
1114
|
+
} else if (office && entries.some((entry) => MACRO_EXTENSIONS.has(extensionOf(entry.name)))) {
|
|
1115
|
+
add("macro", `Attachment "${name}" is an Office document holding another with macros`, { extension });
|
|
1116
|
+
}
|
|
1117
|
+
const inner = entries.filter((entry) => EXECUTABLE_EXTENSIONS.has(extensionOf(uncompressedName(entry.name))) && !(office && OFFICE_EMBEDDED.has(extensionOf(entry.name))));
|
|
1118
|
+
const details = { extension: extensionOf(uncompressedName(inner[0]?.name ?? "")), extensions: [...new Set(inner.map((entry) => extensionOf(uncompressedName(entry.name))))] };
|
|
1119
|
+
const listed = inner.slice(0, 3).map((entry) => shorten(entry.name.split("/").pop())).join(", ");
|
|
1120
|
+
if (inner.some((entry) => !SCRIPT_EXTENSIONS.has(extensionOf(uncompressedName(entry.name))))) {
|
|
1121
|
+
add("executable_in_archive", `Archive "${name}" contains ${inner.length === 1 ? "a program" : `${inner.length} programs`} (${listed})`, details);
|
|
1122
|
+
} else if (inner.length > 0) {
|
|
1123
|
+
add("script_in_archive", `Archive "${name}" contains ${inner.length === 1 ? "a script" : `${inner.length} scripts`} (${listed})`, details);
|
|
1124
|
+
}
|
|
1125
|
+
if ((detected?.type === "zip" || !ZIP_FAMILY.has(detected?.type)) && entries.some((entry) => entry.encrypted)) {
|
|
1126
|
+
add("encrypted_archive", `Archive "${name}" is password protected, so its contents cannot be scanned`, { extension });
|
|
1127
|
+
}
|
|
1128
|
+
} else if (detected?.type === "ole") {
|
|
1129
|
+
if (oleHasMacros(content)) {
|
|
1130
|
+
add("macro", `Attachment "${name}" is an Office document with a VBA macro project`, { extension });
|
|
1131
|
+
}
|
|
1132
|
+
} else if (detected?.type === "pdf" || extension === "pdf") {
|
|
1133
|
+
if (pdfActive(content.toString("latin1"))) {
|
|
1134
|
+
add("pdf_active", `PDF "${name}" contains JavaScript or a launch action`, { extension: "pdf" });
|
|
1135
|
+
}
|
|
1136
|
+
} else if (detected?.type === "rtf" && /\\object\b|\\objdata\b|\\objupdate\b/.test(content.toString("latin1"))) {
|
|
1137
|
+
add("rtf_object", `RTF document "${name}" embeds an OLE object`, { extension: "rtf" });
|
|
1138
|
+
}
|
|
1139
|
+
if (webPage) {
|
|
1140
|
+
addWebPage();
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
return findings;
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
// src/parse.js
|
|
11
1147
|
var ADDRESS_FIELDS = /* @__PURE__ */ new Set(["from", "to", "cc", "bcc", "sender", "reply-to", "delivered-to", "return-path", "disposition-notification-to"]);
|
|
12
1148
|
var MAX_ADDRESS_FIELD = 16 * 1024;
|
|
13
1149
|
var MAX_ADDRESS_SEPARATORS = 2e3;
|
|
@@ -16,21 +1152,21 @@ var MAX_ADDRESS_TOTAL = 64 * 1024;
|
|
|
16
1152
|
var ADDRESS_OPERATORS = /* @__PURE__ */ new Map([['"', '"'], ["(", ")"], ["<", ">"], [",", ""], [":", ";"], [";", ""]]);
|
|
17
1153
|
var SINGLE_FIELDS = /* @__PURE__ */ new Set(["message-id", "content-id", "from", "sender", "in-reply-to", "reply-to", "subject", "date", "content-disposition", "content-type", "content-transfer-encoding", "priority", "mime-version", "content-description", "precedence", "errors-to", "disposition-notification-to"]);
|
|
18
1154
|
var PRIORITY_FIELDS = /* @__PURE__ */ new Set(["priority", "x-priority", "x-msmail-priority", "importance"]);
|
|
19
|
-
var
|
|
1155
|
+
var BOUNDED2 = /* @__PURE__ */ Symbol("bounded address fields");
|
|
20
1156
|
var ROOM = /* @__PURE__ */ Symbol("room left for address fields");
|
|
21
1157
|
var PARSER_OPTIONS = {
|
|
22
1158
|
skipHtmlToText: true,
|
|
23
1159
|
skipImageLinks: true,
|
|
24
1160
|
skipTextToHtml: true,
|
|
25
1161
|
skipTextLinks: true,
|
|
26
|
-
[
|
|
1162
|
+
[BOUNDED2]: true
|
|
27
1163
|
};
|
|
28
1164
|
function boundAddressField(line, room) {
|
|
29
1165
|
const start = line.indexOf(":") + 1;
|
|
30
1166
|
const limit = Math.min(line.length, MAX_ADDRESS_FIELD, room);
|
|
31
1167
|
let end = start;
|
|
32
1168
|
let expecting = "";
|
|
33
|
-
let
|
|
1169
|
+
let escaped2 = false;
|
|
34
1170
|
let separators = 0;
|
|
35
1171
|
let groups = 0;
|
|
36
1172
|
let index = start;
|
|
@@ -39,8 +1175,8 @@ function boundAddressField(line, room) {
|
|
|
39
1175
|
if ((chr === "," || chr === ";") && ++separators > MAX_ADDRESS_SEPARATORS) {
|
|
40
1176
|
break;
|
|
41
1177
|
}
|
|
42
|
-
if (
|
|
43
|
-
|
|
1178
|
+
if (escaped2) {
|
|
1179
|
+
escaped2 = false;
|
|
44
1180
|
} else if (expecting !== "" && chr === expecting) {
|
|
45
1181
|
expecting = "";
|
|
46
1182
|
end = chr === ";" ? index + 1 : end;
|
|
@@ -48,7 +1184,7 @@ function boundAddressField(line, room) {
|
|
|
48
1184
|
expecting = ADDRESS_OPERATORS.get(chr);
|
|
49
1185
|
end = chr === "," || chr === ";" ? index : end;
|
|
50
1186
|
} else if (expecting === '"' && chr === "\\") {
|
|
51
|
-
|
|
1187
|
+
escaped2 = true;
|
|
52
1188
|
}
|
|
53
1189
|
if (chr === ":" && expecting === ";" && ++groups > MAX_ADDRESS_GROUPS) {
|
|
54
1190
|
break;
|
|
@@ -74,7 +1210,7 @@ function boundAddressLines(lines, budget, only = null) {
|
|
|
74
1210
|
}
|
|
75
1211
|
var { processHeaders } = MailParser.prototype;
|
|
76
1212
|
MailParser.prototype.processHeaders = function(lines) {
|
|
77
|
-
if (!this.options[
|
|
1213
|
+
if (!this.options[BOUNDED2]) {
|
|
78
1214
|
return processHeaders.call(this, lines);
|
|
79
1215
|
}
|
|
80
1216
|
this[ROOM] ??= { room: MAX_ADDRESS_TOTAL };
|
|
@@ -120,18 +1256,103 @@ var KEPT_FIELDS = /* @__PURE__ */ new Set([
|
|
|
120
1256
|
var AUTH_FIELDS = /* @__PURE__ */ new Set([...KEPT_FIELDS, "arc-seal", "arc-message-signature"]);
|
|
121
1257
|
var MAX_NESTED_BYTES = 25 * 1024 * 1024;
|
|
122
1258
|
var PARSE_TIMEOUT = 6e4;
|
|
1259
|
+
var NAMED_TEXT = /* @__PURE__ */ Symbol("named text parts");
|
|
1260
|
+
var ENCODED_FILES = /^(?:begin [0-7]{3,4} |=ybegin\b[^\r\n\u2028\u2029]*?\bname=)([^\r\n\u2028\u2029]+)\r?$/gm;
|
|
1261
|
+
var MAX_ENCODED_FILES = 1e3;
|
|
1262
|
+
var foundIn = /* @__PURE__ */ new WeakMap();
|
|
1263
|
+
function addFinding(list, part) {
|
|
1264
|
+
const found = foundIn.get(list) ?? /* @__PURE__ */ new Set();
|
|
1265
|
+
foundIn.set(list, found);
|
|
1266
|
+
const types = inspectAttachments([part]).map((finding) => finding.type);
|
|
1267
|
+
if (types.some((type) => !found.has(type))) {
|
|
1268
|
+
list.push(part);
|
|
1269
|
+
for (const type of types) {
|
|
1270
|
+
found.add(type);
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
function parametersOf(value) {
|
|
1275
|
+
const parameters = [];
|
|
1276
|
+
let start = -1;
|
|
1277
|
+
let quoted = false;
|
|
1278
|
+
for (let i = 0; i < value.length; i++) {
|
|
1279
|
+
if (quoted && value[i] === "\\") {
|
|
1280
|
+
i++;
|
|
1281
|
+
} else if (value[i] === '"') {
|
|
1282
|
+
quoted = !quoted;
|
|
1283
|
+
} else if (value[i] === ";" && !quoted) {
|
|
1284
|
+
if (start !== -1) {
|
|
1285
|
+
parameters.push(value.slice(start, i));
|
|
1286
|
+
}
|
|
1287
|
+
start = i + 1;
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
if (start !== -1) {
|
|
1291
|
+
parameters.push(value.slice(start));
|
|
1292
|
+
}
|
|
1293
|
+
return parameters;
|
|
1294
|
+
}
|
|
1295
|
+
var MAX_NAME_FIELDS = 8;
|
|
1296
|
+
var MAX_NAME_PARAMETERS = 32;
|
|
1297
|
+
function repeatedNames(node) {
|
|
1298
|
+
const names = [];
|
|
1299
|
+
const { headers, libmime } = node ?? {};
|
|
1300
|
+
if (typeof headers?.get !== "function" || typeof libmime?.parseHeaderValue !== "function") {
|
|
1301
|
+
return names;
|
|
1302
|
+
}
|
|
1303
|
+
const read = (value, parameter) => {
|
|
1304
|
+
let name = "";
|
|
1305
|
+
try {
|
|
1306
|
+
name = libmime.decodeWords(String(libmime.parseHeaderValue(value, { stripComments: true }).params[parameter] ?? "")).trim();
|
|
1307
|
+
} catch {
|
|
1308
|
+
}
|
|
1309
|
+
if (name !== "") {
|
|
1310
|
+
names.push(name);
|
|
1311
|
+
}
|
|
1312
|
+
};
|
|
1313
|
+
for (const [field, parameter] of [["content-disposition", "filename"], ["content-type", "name"]]) {
|
|
1314
|
+
const values = headers.get(field).slice(0, MAX_NAME_FIELDS);
|
|
1315
|
+
for (const value of values) {
|
|
1316
|
+
const parameters = parametersOf(value).slice(0, MAX_NAME_PARAMETERS).map((text) => ({ text, key: text.slice(0, Math.max(0, text.indexOf("="))).trim().toLowerCase() }));
|
|
1317
|
+
const repeated = parameters.filter(({ key }) => (key === parameter || key.startsWith(`${parameter}*`)) && parameters.filter((other) => other.key === key).length > 1);
|
|
1318
|
+
if (values.length > 1) {
|
|
1319
|
+
read(value, parameter);
|
|
1320
|
+
}
|
|
1321
|
+
for (const { text } of repeated) {
|
|
1322
|
+
read(`x;${text}`, text.slice(0, text.indexOf("=")).trim().toLowerCase().replace(/\*.*$/, ""));
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
return names;
|
|
1327
|
+
}
|
|
123
1328
|
async function simpleParse(raw, { timeout = PARSE_TIMEOUT, parser = simpleParser } = {}) {
|
|
124
1329
|
const input = Readable.from([finishable(unfoldHeaders(raw))], { objectMode: false, autoDestroy: false });
|
|
125
1330
|
input.on("error", () => {
|
|
126
1331
|
});
|
|
1332
|
+
const named = [];
|
|
127
1333
|
const { pipe } = input;
|
|
128
1334
|
input.pipe = function(parser2, options) {
|
|
129
1335
|
parser2.splitter?.on("error", (error) => input.destroy(error));
|
|
1336
|
+
const { createNode } = parser2;
|
|
1337
|
+
if (typeof createNode === "function") {
|
|
1338
|
+
parser2.createNode = function(node) {
|
|
1339
|
+
const created = createNode.call(this, node);
|
|
1340
|
+
if (created?.isAttachment === false && node?.filename) {
|
|
1341
|
+
addFinding(named, { filename: String(node.filename), contentType: created.contentType, content: null });
|
|
1342
|
+
}
|
|
1343
|
+
for (const filename of repeatedNames(node)) {
|
|
1344
|
+
if (filename !== node?.filename) {
|
|
1345
|
+
addFinding(named, { filename, contentType: created?.contentType || "application/octet-stream", content: null });
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
return created;
|
|
1349
|
+
};
|
|
1350
|
+
}
|
|
130
1351
|
return pipe.call(this, parser2, options);
|
|
131
1352
|
};
|
|
132
1353
|
let timer;
|
|
133
1354
|
try {
|
|
134
|
-
|
|
1355
|
+
const mail = await Promise.race([
|
|
135
1356
|
parser(input, PARSER_OPTIONS),
|
|
136
1357
|
new Promise((resolve, reject) => {
|
|
137
1358
|
timer = setTimeout(() => {
|
|
@@ -141,14 +1362,25 @@ async function simpleParse(raw, { timeout = PARSE_TIMEOUT, parser = simpleParser
|
|
|
141
1362
|
}, timeout);
|
|
142
1363
|
})
|
|
143
1364
|
]);
|
|
1365
|
+
if (mail && typeof mail === "object") {
|
|
1366
|
+
let count = 0;
|
|
1367
|
+
for (const [, filename] of String(mail.text ?? "").matchAll(ENCODED_FILES)) {
|
|
1368
|
+
addFinding(named, { filename: filename.trim(), contentType: "application/octet-stream", content: null });
|
|
1369
|
+
if (++count >= MAX_ENCODED_FILES) {
|
|
1370
|
+
break;
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
Object.defineProperty(mail, NAMED_TEXT, { value: named });
|
|
1374
|
+
}
|
|
1375
|
+
return mail;
|
|
144
1376
|
} finally {
|
|
145
1377
|
clearTimeout(timer);
|
|
146
1378
|
input.destroy();
|
|
147
1379
|
}
|
|
148
1380
|
}
|
|
149
1381
|
function finishable(raw) {
|
|
150
|
-
const buffer =
|
|
151
|
-
return
|
|
1382
|
+
const buffer = Buffer2.isBuffer(raw) ? raw : Buffer2.from(raw);
|
|
1383
|
+
return Buffer2.concat([buffer, Buffer2.from(buffer.at(-1) === 10 ? "\r\n\r\n" : "\r\n\r\n\r\n")]);
|
|
152
1384
|
}
|
|
153
1385
|
var MAX_FOLDS = 256;
|
|
154
1386
|
function headerValue(line) {
|
|
@@ -156,18 +1388,18 @@ function headerValue(line) {
|
|
|
156
1388
|
let key = null;
|
|
157
1389
|
let inKey = false;
|
|
158
1390
|
let quoted = false;
|
|
159
|
-
let
|
|
1391
|
+
let escaped2 = false;
|
|
160
1392
|
let value = "";
|
|
161
1393
|
for (const chr of line.slice(line.indexOf(":") + 1).replaceAll(/\r?\n[ \t]*/g, " ")) {
|
|
162
1394
|
if (inKey && chr === "=") {
|
|
163
1395
|
key = value.trim().toLowerCase();
|
|
164
1396
|
inKey = false;
|
|
165
1397
|
value = "";
|
|
166
|
-
} else if (inKey ||
|
|
1398
|
+
} else if (inKey || escaped2) {
|
|
167
1399
|
value += chr;
|
|
168
|
-
|
|
1400
|
+
escaped2 = false;
|
|
169
1401
|
} else if (chr === "\\") {
|
|
170
|
-
|
|
1402
|
+
escaped2 = true;
|
|
171
1403
|
} else if (chr === '"') {
|
|
172
1404
|
quoted = !quoted;
|
|
173
1405
|
} else if (chr === ";" && !quoted) {
|
|
@@ -213,7 +1445,7 @@ function unfoldHeaders(raw) {
|
|
|
213
1445
|
const type = first.get("content-type") ?? { value: "", boundary: "" };
|
|
214
1446
|
const encoding = (first.get("content-transfer-encoding")?.value ?? "").replaceAll(/\(.*\)/g, "").trim();
|
|
215
1447
|
if (blank && type.boundary) {
|
|
216
|
-
boundaries.push(
|
|
1448
|
+
boundaries.push(Buffer2.from(type.boundary));
|
|
217
1449
|
}
|
|
218
1450
|
head = blank && ["message/rfc822", "message/global"].includes(type.value) && ["", "7bit", "8bit", "binary"].includes(encoding) && first.get("content-disposition")?.value === "inline";
|
|
219
1451
|
};
|
|
@@ -247,11 +1479,11 @@ function unfoldHeaders(raw) {
|
|
|
247
1479
|
const chunks = [];
|
|
248
1480
|
let copied = 0;
|
|
249
1481
|
for (const field of unfold) {
|
|
250
|
-
chunks.push(raw.subarray(copied, field.start),
|
|
1482
|
+
chunks.push(raw.subarray(copied, field.start), Buffer2.from(raw.toString("latin1", field.start, field.end).replaceAll(/\r?\n[ \t]*/g, " "), "latin1"));
|
|
251
1483
|
copied = field.end;
|
|
252
1484
|
}
|
|
253
1485
|
chunks.push(raw.subarray(copied));
|
|
254
|
-
return
|
|
1486
|
+
return Buffer2.concat(chunks);
|
|
255
1487
|
}
|
|
256
1488
|
|
|
257
1489
|
// src/arf.js
|
|
@@ -311,7 +1543,7 @@ function parseReportingMta(value) {
|
|
|
311
1543
|
}
|
|
312
1544
|
function decodeQuotedPrintable(text) {
|
|
313
1545
|
const soft = text.replaceAll(/=\r?\n/g, "");
|
|
314
|
-
const bytes =
|
|
1546
|
+
const bytes = Buffer3.allocUnsafe(soft.length);
|
|
315
1547
|
let length = 0;
|
|
316
1548
|
for (let i = 0; i < soft.length; i++) {
|
|
317
1549
|
if (soft[i] === "=" && /^[\da-f]{2}$/i.test(soft.slice(i + 1, i + 3))) {
|
|
@@ -324,8 +1556,8 @@ function decodeQuotedPrintable(text) {
|
|
|
324
1556
|
return bytes.subarray(0, length);
|
|
325
1557
|
}
|
|
326
1558
|
function findPart(raw, boundary, types) {
|
|
327
|
-
const
|
|
328
|
-
const parts = raw.split(new RegExp(String.raw`\r?\n--${
|
|
1559
|
+
const escaped2 = boundary.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
|
|
1560
|
+
const parts = raw.split(new RegExp(String.raw`\r?\n--${escaped2}(?:--)?[ \t]*(?=\r?\n|$)`));
|
|
329
1561
|
for (const part of parts.slice(1)) {
|
|
330
1562
|
const match = /^\r?\n((?:[^\r\n]+\r?\n)*)\r?\n([\s\S]*)$/.exec(part);
|
|
331
1563
|
if (!match) {
|
|
@@ -339,11 +1571,11 @@ function findPart(raw, boundary, types) {
|
|
|
339
1571
|
const encoding = (/^content-transfer-encoding:\s*(\S+)/im.exec(headers)?.[1] || "").toLowerCase();
|
|
340
1572
|
let content;
|
|
341
1573
|
if (encoding === "base64") {
|
|
342
|
-
content =
|
|
1574
|
+
content = Buffer3.from(match[2], "base64");
|
|
343
1575
|
} else if (encoding === "quoted-printable") {
|
|
344
1576
|
content = decodeQuotedPrintable(match[2]);
|
|
345
1577
|
} else {
|
|
346
|
-
content =
|
|
1578
|
+
content = Buffer3.from(match[2], "latin1");
|
|
347
1579
|
}
|
|
348
1580
|
return { type, content };
|
|
349
1581
|
}
|
|
@@ -359,7 +1591,7 @@ function isArfMessage(parsed) {
|
|
|
359
1591
|
return /^multipart\/report\b/i.test(String(value)) && type.toLowerCase() === "feedback-report";
|
|
360
1592
|
}
|
|
361
1593
|
async function parse(message) {
|
|
362
|
-
const source = message instanceof Uint8Array && !
|
|
1594
|
+
const source = message instanceof Uint8Array && !Buffer3.isBuffer(message) ? Buffer3.from(message.buffer, message.byteOffset, message.byteLength) : message;
|
|
363
1595
|
const parsed = await simpleParse(source);
|
|
364
1596
|
if (!isArfMessage(parsed)) {
|
|
365
1597
|
throw new Error("Not an ARF report: expected multipart/report with report-type=feedback-report");
|
|
@@ -404,7 +1636,7 @@ async function parse(message) {
|
|
|
404
1636
|
originalHeaders: null,
|
|
405
1637
|
rawFeedbackReport: raw
|
|
406
1638
|
};
|
|
407
|
-
const text = (
|
|
1639
|
+
const text = (Buffer3.isBuffer(source) ? source : Buffer3.from(String(source))).toString("latin1");
|
|
408
1640
|
const { boundary } = parsed.headers.get("content-type").params;
|
|
409
1641
|
const human = findPart(text, boundary, ["text/plain"]);
|
|
410
1642
|
result.humanReadable = human ? human.content.toString("utf8").trim() || null : null;
|
|
@@ -504,9 +1736,9 @@ function create(options = {}) {
|
|
|
504
1736
|
const tail = `\r
|
|
505
1737
|
--${boundary}--\r
|
|
506
1738
|
`;
|
|
507
|
-
if (
|
|
1739
|
+
if (Buffer3.isBuffer(originalMessage)) {
|
|
508
1740
|
const end = originalMessage.at(-1) === 10 ? originalMessage.at(-2) === 13 ? 2 : 1 : 0;
|
|
509
|
-
return
|
|
1741
|
+
return Buffer3.concat([Buffer3.from(head), originalMessage.subarray(0, originalMessage.length - end), Buffer3.from(tail)]);
|
|
510
1742
|
}
|
|
511
1743
|
return head + String(originalMessage).replace(/\r?\n$/, "") + tail;
|
|
512
1744
|
}
|
|
@@ -517,14 +1749,14 @@ function encodeWords(text) {
|
|
|
517
1749
|
const words = [];
|
|
518
1750
|
let word = "";
|
|
519
1751
|
for (const character of text) {
|
|
520
|
-
if (
|
|
1752
|
+
if (Buffer3.byteLength(word + character) > 45) {
|
|
521
1753
|
words.push(word);
|
|
522
1754
|
word = "";
|
|
523
1755
|
}
|
|
524
1756
|
word += character;
|
|
525
1757
|
}
|
|
526
1758
|
words.push(word);
|
|
527
|
-
return words.map((part) => `=?UTF-8?B?${
|
|
1759
|
+
return words.map((part) => `=?UTF-8?B?${Buffer3.from(part).toString("base64")}?=`).join("\r\n ");
|
|
528
1760
|
}
|
|
529
1761
|
var ArfParser = {
|
|
530
1762
|
isArfMessage,
|