@doccloak/core 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +121 -2
- package/README.md +252 -19
- package/dist/doc.d.ts +68 -1
- package/dist/doc.js +447 -62
- package/dist/dom/docx.d.ts +135 -7
- package/dist/dom/docx.js +752 -125
- package/dist/dom/drawingml.d.ts +59 -0
- package/dist/dom/drawingml.js +176 -0
- package/dist/dom/errors.d.ts +35 -0
- package/dist/dom/errors.js +24 -0
- package/dist/dom/index.d.ts +3 -0
- package/dist/dom/index.js +6 -0
- package/dist/dom/office.d.ts +56 -0
- package/dist/dom/office.js +76 -23
- package/dist/dom/opc.d.ts +135 -7
- package/dist/dom/opc.js +407 -14
- package/dist/dom/package-policy.d.ts +137 -0
- package/dist/dom/package-policy.js +355 -0
- package/dist/dom/xlsx.d.ts +64 -6
- package/dist/dom/xlsx.js +75 -20
- package/dist/engine.d.ts +18 -0
- package/dist/engine.js +37 -13
- package/dist/env.d.ts +21 -1
- package/dist/index.d.ts +8 -6
- package/dist/index.js +10 -5
- package/dist/model-loader.d.ts +61 -6
- package/dist/model-loader.js +122 -17
- package/dist/pipeline.d.ts +87 -8
- package/dist/pipeline.js +249 -50
- package/dist/providers/bardsai.d.ts +8 -1
- package/dist/providers/bardsai.js +22 -2
- package/dist/providers/gliner-base.d.ts +8 -1
- package/dist/providers/gliner-base.js +22 -2
- package/dist/providers/gliner.d.ts +8 -1
- package/dist/providers/gliner.js +22 -2
- package/dist/regex/loader.d.ts +2 -0
- package/dist/regex/loader.js +2 -0
- package/dist/regex/rules.data.js +15 -14
- package/dist/regex/types.d.ts +6 -0
- package/dist/session.d.ts +101 -3
- package/dist/session.js +397 -43
- package/dist/surrogates.js +57 -45
- package/dist/worker-protocol.d.ts +13 -1
- package/dist/worker-protocol.js +164 -12
- package/package.json +1 -1
- package/rules/at.json +1 -1
- package/rules/be.json +1 -1
- package/rules/ch.json +1 -1
- package/rules/de.json +1 -1
- package/rules/dk.json +1 -1
- package/rules/es.json +1 -1
- package/rules/fi.json +1 -1
- package/rules/fr.json +1 -1
- package/rules/it.json +1 -1
- package/rules/no.json +1 -1
- package/rules/pl.json +1 -1
- package/rules/pt.json +1 -1
- package/rules/schema.json +4 -0
- package/rules/se.json +1 -1
- package/rules/universal.json +2 -1
package/dist/surrogates.js
CHANGED
|
@@ -82,36 +82,48 @@ export function generateSessionSalt() {
|
|
|
82
82
|
return out;
|
|
83
83
|
}
|
|
84
84
|
// ── Name pools (EN + PL) ───────────────────────────────────
|
|
85
|
+
//
|
|
86
|
+
// Pool hygiene (T182, audit R3/R4): a surrogate becomes a restore KEY, so
|
|
87
|
+
// every alphabetic pool excludes (a) names that are also everyday words
|
|
88
|
+
// in English or, for capitalized-noun languages, in their own language
|
|
89
|
+
// (White, Green, King, Young, Hill, Baker, Post, Wolf, Richter, Urban,
|
|
90
|
+
// Martin the bird, ...) and (b) entries of three letters or fewer (Bo,
|
|
91
|
+
// Per, Odd, Jan, Eva, Bos, Vos, Kok, ...), which fire inside ordinary
|
|
92
|
+
// words even with boundaries around them. Replacements keep the pool
|
|
93
|
+
// size and sit at the same index, so surrogate derivation is unchanged
|
|
94
|
+
// for every original that never picked a removed entry. CJK pools are
|
|
95
|
+
// exempt from (b): their names are one to three characters by design.
|
|
96
|
+
// The pool-hygiene test in tests/surrogates.test.ts enforces both rules.
|
|
85
97
|
const EN_FIRST_MALE = [
|
|
86
98
|
'James', 'John', 'Robert', 'Michael', 'William', 'David', 'Richard', 'Joseph',
|
|
87
|
-
'Thomas', 'Charles', 'Daniel', 'Matthew', 'Anthony', '
|
|
99
|
+
'Thomas', 'Charles', 'Daniel', 'Matthew', 'Anthony', 'Dennis', 'Steven', 'Paul',
|
|
88
100
|
'Andrew', 'Joshua', 'Kevin', 'Brian', 'George', 'Timothy', 'Ronald', 'Edward',
|
|
89
101
|
'Jason', 'Jeffrey', 'Ryan', 'Jacob', 'Gary', 'Nicholas', 'Eric', 'Jonathan',
|
|
90
|
-
'Stephen', 'Larry', 'Justin', '
|
|
102
|
+
'Stephen', 'Larry', 'Justin', 'Douglas', 'Brandon', 'Benjamin', 'Samuel', 'Gregory',
|
|
91
103
|
];
|
|
92
104
|
const EN_FIRST_FEMALE = [
|
|
93
105
|
'Mary', 'Patricia', 'Jennifer', 'Linda', 'Elizabeth', 'Barbara', 'Susan', 'Jessica',
|
|
94
106
|
'Sarah', 'Karen', 'Lisa', 'Nancy', 'Betty', 'Margaret', 'Sandra', 'Ashley',
|
|
95
|
-
'Kimberly', 'Emily', 'Donna', 'Michelle', '
|
|
96
|
-
'Deborah', 'Stephanie', 'Rebecca', 'Sharon', 'Laura', 'Cynthia', 'Kathleen', '
|
|
107
|
+
'Kimberly', 'Emily', 'Donna', 'Michelle', 'Janet', 'Amanda', 'Dorothy', 'Melissa',
|
|
108
|
+
'Deborah', 'Stephanie', 'Rebecca', 'Sharon', 'Laura', 'Cynthia', 'Kathleen', 'Kathryn',
|
|
97
109
|
'Angela', 'Shirley', 'Anna', 'Ruth', 'Brenda', 'Pamela', 'Emma', 'Nicole',
|
|
98
110
|
];
|
|
99
111
|
const EN_SURNAMES = [
|
|
100
|
-
'Smith', 'Johnson', 'Williams', '
|
|
101
|
-
'Wilson', 'Anderson', 'Taylor', 'Thomas', 'Moore', 'Jackson', '
|
|
102
|
-
'Thompson', '
|
|
103
|
-
'Allen', '
|
|
104
|
-
'
|
|
112
|
+
'Smith', 'Johnson', 'Williams', 'Collins', 'Jones', 'Garcia', 'Stewart', 'Davis',
|
|
113
|
+
'Wilson', 'Anderson', 'Taylor', 'Thomas', 'Moore', 'Jackson', 'Morgan', 'Murphy',
|
|
114
|
+
'Thompson', 'Rogers', 'Harris', 'Clark', 'Lewis', 'Robinson', 'Peterson', 'Sullivan',
|
|
115
|
+
'Allen', 'Bennett', 'Wright', 'Hughes', 'Howard', 'Richardson', 'Adams', 'Nelson',
|
|
116
|
+
'Morris', 'Campbell', 'Mitchell', 'Roberts', 'Carter', 'Phillips', 'Evans', 'Turner',
|
|
105
117
|
];
|
|
106
118
|
const PL_FIRST_MALE = [
|
|
107
|
-
'
|
|
119
|
+
'Stanisław', 'Piotr', 'Krzysztof', 'Andrzej', 'Tomasz', 'Paweł', 'Michał', 'Marcin',
|
|
108
120
|
'Marek', 'Grzegorz', 'Jerzy', 'Tadeusz', 'Adam', 'Łukasz', 'Zbigniew', 'Ryszard',
|
|
109
121
|
'Dariusz', 'Henryk', 'Mariusz', 'Kazimierz', 'Wojciech', 'Robert', 'Mateusz', 'Marian',
|
|
110
122
|
'Rafał', 'Jacek', 'Janusz', 'Mirosław', 'Maciej', 'Sławomir', 'Jarosław', 'Kamil',
|
|
111
|
-
'Wiesław', '
|
|
123
|
+
'Wiesław', 'Bogdan', 'Władysław', 'Jakub', 'Artur', 'Zdzisław', 'Edward', 'Dawid',
|
|
112
124
|
];
|
|
113
125
|
const PL_FIRST_FEMALE = [
|
|
114
|
-
'Anna', 'Maria', 'Katarzyna', 'Małgorzata', 'Agnieszka', 'Barbara', 'Krystyna', '
|
|
126
|
+
'Anna', 'Maria', 'Katarzyna', 'Małgorzata', 'Agnieszka', 'Barbara', 'Krystyna', 'Weronika',
|
|
115
127
|
'Elżbieta', 'Zofia', 'Janina', 'Teresa', 'Joanna', 'Magdalena', 'Monika', 'Jadwiga',
|
|
116
128
|
'Danuta', 'Irena', 'Halina', 'Helena', 'Beata', 'Aleksandra', 'Marta', 'Dorota',
|
|
117
129
|
'Marianna', 'Grażyna', 'Jolanta', 'Stanisława', 'Iwona', 'Karolina', 'Bożena', 'Urszula',
|
|
@@ -121,8 +133,8 @@ const PL_FIRST_FEMALE = [
|
|
|
121
133
|
const PL_SURNAMES = [
|
|
122
134
|
'Nowak', 'Kowalski', 'Wiśniewski', 'Wójcik', 'Kowalczyk', 'Kamiński', 'Lewandowski', 'Zieliński',
|
|
123
135
|
'Szymański', 'Woźniak', 'Dąbrowski', 'Kozłowski', 'Jankowski', 'Mazur', 'Kwiatkowski', 'Krawczyk',
|
|
124
|
-
'Piotrowski', 'Grabowski', 'Nowakowski', 'Pawłowski', 'Michalski', 'Nowicki', 'Adamczyk', '
|
|
125
|
-
'
|
|
136
|
+
'Piotrowski', 'Grabowski', 'Nowakowski', 'Pawłowski', 'Michalski', 'Nowicki', 'Adamczyk', 'Kaczmarek',
|
|
137
|
+
'Sobczak', 'Wieczorek', 'Jabłoński', 'Zalewski', 'Majewski', 'Olszewski', 'Jaworski', 'Zawadzki',
|
|
126
138
|
'Malinowski', 'Pawlak', 'Witkowski', 'Walczak', 'Stępień', 'Górski', 'Rutkowski', 'Michalak',
|
|
127
139
|
];
|
|
128
140
|
function feminizePlSurname(surname) {
|
|
@@ -143,7 +155,7 @@ function feminizePlSurname(surname) {
|
|
|
143
155
|
// guaranteed by collision handling, not pool size.
|
|
144
156
|
const DE_FIRST_MALE = [
|
|
145
157
|
'Hans', 'Peter', 'Michael', 'Thomas', 'Andreas', 'Wolfgang', 'Klaus', 'Jürgen',
|
|
146
|
-
'Stefan', 'Christian', 'Markus', 'Alexander', '
|
|
158
|
+
'Stefan', 'Christian', 'Markus', 'Alexander', 'Dieter', 'Rainer', 'Holger', 'Werner',
|
|
147
159
|
'Matthias', 'Bernd', 'Florian', 'Tobias', 'Sebastian', 'Lukas', 'Felix', 'Jonas',
|
|
148
160
|
];
|
|
149
161
|
const DE_FIRST_FEMALE = [
|
|
@@ -152,8 +164,8 @@ const DE_FIRST_FEMALE = [
|
|
|
152
164
|
'Christina', 'Birgit', 'Heike', 'Lena', 'Hannah', 'Laura', 'Lisa', 'Sophie',
|
|
153
165
|
];
|
|
154
166
|
const DE_SURNAMES = [
|
|
155
|
-
'Müller', 'Schmidt', 'Schneider', '
|
|
156
|
-
'Schulz', 'Hoffmann', 'Schäfer', '
|
|
167
|
+
'Müller', 'Schmidt', 'Schneider', 'Herrmann', 'Weber', 'Meyer', 'Wagner', 'Becker',
|
|
168
|
+
'Schulz', 'Hoffmann', 'Schäfer', 'Lehmann', 'Köhler', 'Schulze', 'Klein', 'Hartmann',
|
|
157
169
|
'Schröder', 'Neumann', 'Schwarz', 'Zimmermann', 'Braun', 'Krüger', 'Hofmann', 'Lange',
|
|
158
170
|
];
|
|
159
171
|
const FR_FIRST_MALE = [
|
|
@@ -163,13 +175,13 @@ const FR_FIRST_MALE = [
|
|
|
163
175
|
];
|
|
164
176
|
const FR_FIRST_FEMALE = [
|
|
165
177
|
'Marie', 'Nathalie', 'Isabelle', 'Sylvie', 'Catherine', 'Françoise', 'Christine', 'Monique',
|
|
166
|
-
'Sophie', 'Céline', 'Julie', 'Aurélie', 'Camille', '
|
|
178
|
+
'Sophie', 'Céline', 'Julie', 'Aurélie', 'Camille', 'Mathilde', 'Chloé', 'Manon',
|
|
167
179
|
'Élise', 'Charlotte', 'Emma', 'Louise', 'Alice', 'Juliette', 'Margaux', 'Inès',
|
|
168
180
|
];
|
|
169
181
|
const FR_SURNAMES = [
|
|
170
|
-
'
|
|
182
|
+
'Mercier', 'Bernard', 'Dubois', 'Thomas', 'Robert', 'Richard', 'Rousseau', 'Durand',
|
|
171
183
|
'Leroy', 'Moreau', 'Simon', 'Laurent', 'Lefebvre', 'Michel', 'Garcia', 'David',
|
|
172
|
-
'Bertrand', '
|
|
184
|
+
'Bertrand', 'Garnier', 'Vincent', 'Fournier', 'Morel', 'Girard', 'Lambert', 'Fontaine',
|
|
173
185
|
];
|
|
174
186
|
const ES_FIRST_MALE = [
|
|
175
187
|
'José', 'Antonio', 'Manuel', 'Francisco', 'Juan', 'David', 'Javier', 'Carlos',
|
|
@@ -177,7 +189,7 @@ const ES_FIRST_MALE = [
|
|
|
177
189
|
'Jorge', 'Alberto', 'Diego', 'Adrián', 'Raúl', 'Iván', 'Rubén', 'Óscar',
|
|
178
190
|
];
|
|
179
191
|
const ES_FIRST_FEMALE = [
|
|
180
|
-
'María', 'Carmen', 'Josefa', 'Isabel', '
|
|
192
|
+
'María', 'Carmen', 'Josefa', 'Isabel', 'Alicia', 'Dolores', 'Pilar', 'Teresa',
|
|
181
193
|
'Rosa', 'Cristina', 'Laura', 'Marta', 'Elena', 'Lucía', 'Sara', 'Paula',
|
|
182
194
|
'Raquel', 'Beatriz', 'Silvia', 'Patricia', 'Nuria', 'Alba', 'Andrea', 'Irene',
|
|
183
195
|
];
|
|
@@ -203,19 +215,19 @@ const IT_SURNAMES = [
|
|
|
203
215
|
];
|
|
204
216
|
/** Masculine base forms; feminizeCsSurname derives -ová / -á endings. */
|
|
205
217
|
const CS_FIRST_MALE = [
|
|
206
|
-
'Jiří', '
|
|
218
|
+
'Jiří', 'Vojtěch', 'Petr', 'Josef', 'Pavel', 'Matěj', 'Tomáš', 'Jaroslav',
|
|
207
219
|
'Miroslav', 'Zdeněk', 'František', 'Václav', 'Michal', 'Milan', 'Karel', 'Lukáš',
|
|
208
|
-
'David', 'Ladislav', 'Stanislav', '
|
|
220
|
+
'David', 'Ladislav', 'Stanislav', 'Libor', 'Ondřej', 'Jakub', 'Vladimír', 'Radek',
|
|
209
221
|
];
|
|
210
222
|
const CS_FIRST_FEMALE = [
|
|
211
223
|
'Marie', 'Jiřina', 'Anna', 'Věra', 'Alena', 'Lenka', 'Hana', 'Jaroslava',
|
|
212
|
-
'Kateřina', 'Lucie', '
|
|
224
|
+
'Kateřina', 'Lucie', 'Simona', 'Jana', 'Petra', 'Martina', 'Zuzana', 'Michaela',
|
|
213
225
|
'Tereza', 'Barbora', 'Veronika', 'Kristýna', 'Markéta', 'Ivana', 'Monika', 'Klára',
|
|
214
226
|
];
|
|
215
227
|
const CS_SURNAMES = [
|
|
216
228
|
'Novák', 'Svoboda', 'Novotný', 'Dvořák', 'Černý', 'Procházka', 'Kučera', 'Veselý',
|
|
217
|
-
'Horák', 'Němec', 'Marek', 'Pokorný', 'Pospíšil', 'Hájek', '
|
|
218
|
-
'Růžička', 'Beneš', 'Fiala', 'Sedláček', 'Doležal', 'Zeman', 'Kolář', '
|
|
229
|
+
'Horák', 'Němec', 'Marek', 'Pokorný', 'Pospíšil', 'Hájek', 'Bartoš', 'Jelínek',
|
|
230
|
+
'Růžička', 'Beneš', 'Fiala', 'Sedláček', 'Doležal', 'Zeman', 'Kolář', 'Šimek',
|
|
219
231
|
];
|
|
220
232
|
function feminizeCsSurname(surname) {
|
|
221
233
|
if (surname.endsWith('ý'))
|
|
@@ -241,31 +253,31 @@ const UK_SURNAMES = [
|
|
|
241
253
|
'Мороз', 'Гончаренко', 'Левченко', 'Василенко', 'Кушнір', 'Романюк', 'Гаврилюк', 'Заєць',
|
|
242
254
|
];
|
|
243
255
|
const NL_FIRST_MALE = [
|
|
244
|
-
'Daan', '
|
|
245
|
-
'Maarten', 'Wouter', 'Jeroen', 'Sander', '
|
|
256
|
+
'Daan', 'Luuk', 'Bram', 'Lars', 'Thijs', 'Ruben', 'Kees', 'Joost',
|
|
257
|
+
'Maarten', 'Wouter', 'Jeroen', 'Sander', 'Stijn', 'Niels', 'Floris', 'Gerrit',
|
|
246
258
|
'Pieter', 'Willem', 'Hendrik', 'Cornelis', 'Dirk', 'Jaap', 'Sjoerd', 'Teun',
|
|
247
259
|
];
|
|
248
260
|
const NL_FIRST_FEMALE = [
|
|
249
|
-
'Sanne', 'Lotte', 'Femke', 'Anouk', 'Fleur', '
|
|
261
|
+
'Sanne', 'Lotte', 'Femke', 'Anouk', 'Fleur', 'Saskia', 'Nienke', 'Marloes',
|
|
250
262
|
'Ilse', 'Esmee', 'Roos', 'Lieke', 'Johanna', 'Cornelia', 'Willemien', 'Truus',
|
|
251
|
-
'Marijke', 'Annemiek', 'Wilma', 'Jantine', 'Gerda', 'Hanneke', 'Mieke', '
|
|
263
|
+
'Marijke', 'Annemiek', 'Wilma', 'Jantine', 'Gerda', 'Hanneke', 'Mieke', 'Annelies',
|
|
252
264
|
];
|
|
253
265
|
/** Single-token forms only: multi-token surnames (van der ...) would
|
|
254
266
|
* break the token-count preservation guarantee of generatePerson. */
|
|
255
267
|
const NL_SURNAMES = [
|
|
256
|
-
'Jansen', 'Bakker', 'Visser', 'Smit', 'Meijer', 'Mulder', '
|
|
257
|
-
'Peters', 'Hendriks', 'Dekker', 'Brouwer', 'Dijkstra', 'Smits', 'Kuipers', '
|
|
258
|
-
'
|
|
268
|
+
'Jansen', 'Bakker', 'Visser', 'Smit', 'Meijer', 'Mulder', 'Vermeulen', 'Koster',
|
|
269
|
+
'Peters', 'Hendriks', 'Dekker', 'Brouwer', 'Dijkstra', 'Smits', 'Kuipers', 'Hoekstra',
|
|
270
|
+
'Scholten', 'Verhoeven', 'Willems', 'Maas', 'Hermans', 'Timmermans', 'Schouten', 'Jacobs',
|
|
259
271
|
];
|
|
260
272
|
const PT_FIRST_MALE = [
|
|
261
|
-
'Jo\u00e3o', 'Lu\u00eds', 'Paulo', '
|
|
273
|
+
'Jo\u00e3o', 'Lu\u00eds', 'Paulo', 'Guilherme', 'Nuno', 'Tiago', 'Ricardo', 'Andr\u00e9',
|
|
262
274
|
'Diogo', 'Gon\u00e7alo', 'Vasco', 'Duarte', 'Afonso', 'Bernardo', 'Rodrigo', 'Ant\u00f3nio',
|
|
263
275
|
'Manuel', 'Francisco', 'Carlos', 'Pedro', 'Miguel', 'Jos\u00e9', 'Henrique', 'Sim\u00e3o',
|
|
264
276
|
];
|
|
265
277
|
const PT_FIRST_FEMALE = [
|
|
266
278
|
'Catarina', 'Margarida', 'Mariana', 'Joana', 'Rita', 'Carolina', 'Leonor', 'Matilde',
|
|
267
279
|
'Francisca', 'Madalena', 'Const\u00e2ncia', 'Louren\u00e7a', 'Gra\u00e7a', 'Concei\u00e7\u00e3o', 'Lurdes', 'In\u00eas',
|
|
268
|
-
'Beatriz', 'Isabel', 'Teresa', 'Sofia', '
|
|
280
|
+
'Beatriz', 'Isabel', 'Teresa', 'Sofia', 'Filipa', 'Maria', 'Manuela', 'Fernanda',
|
|
269
281
|
];
|
|
270
282
|
const PT_SURNAMES = [
|
|
271
283
|
'Silva', 'Santos', 'Ferreira', 'Pereira', 'Oliveira', 'Rodrigues', 'Martins', 'Sousa',
|
|
@@ -279,11 +291,11 @@ function feminizeUkSurname(surname) {
|
|
|
279
291
|
return surname; // -енко/-ук/-як and similar are invariant
|
|
280
292
|
}
|
|
281
293
|
const SV_FIRST_MALE = [
|
|
282
|
-
'Erik', 'Lars', 'Karl', 'Anders', 'Johan', '
|
|
283
|
-
'Gunnar', '
|
|
294
|
+
'Erik', 'Lars', 'Karl', 'Anders', 'Johan', 'Mats', 'Nils', 'Sven',
|
|
295
|
+
'Gunnar', 'Olof', 'Bengt', 'G\u00f6ran', 'Henrik', 'Magnus', 'Fredrik', 'Oskar',
|
|
284
296
|
];
|
|
285
297
|
const SV_FIRST_FEMALE = [
|
|
286
|
-
'Anna', '
|
|
298
|
+
'Anna', 'Kristina', 'Maria', 'Karin', 'Ingrid', 'Kerstin', 'Lena', 'Helena',
|
|
287
299
|
'Marianne', 'Birgitta', 'Elin', 'Sara', 'Emma', 'Linnea', 'Astrid', 'Ebba',
|
|
288
300
|
];
|
|
289
301
|
const SV_SURNAMES = [
|
|
@@ -291,23 +303,23 @@ const SV_SURNAMES = [
|
|
|
291
303
|
'Svensson', 'Gustafsson', 'Pettersson', 'Jonsson', 'Lindberg', 'Lindqvist', 'Bergstr\u00f6m', 'Sandberg',
|
|
292
304
|
];
|
|
293
305
|
const NO_FIRST_MALE = [
|
|
294
|
-
'
|
|
306
|
+
'Olav', 'Lars', 'Knut', 'Bj\u00f8rn', 'Arne', 'Einar', 'Geir', 'Sverre',
|
|
295
307
|
'Terje', 'Kjell', 'Espen', 'H\u00e5kon', 'Sindre', 'Eirik', 'Trygve', 'Leif',
|
|
296
308
|
];
|
|
297
309
|
const NO_FIRST_FEMALE = [
|
|
298
|
-
'Anne', 'Inger', 'Kari', 'Marit', 'Ingrid', '
|
|
299
|
-
'Randi', 'Bj\u00f8rg', 'Silje', 'Mari', 'Ingeborg', '
|
|
310
|
+
'Anne', 'Inger', 'Kari', 'Marit', 'Ingrid', 'Hilde', 'Astrid', 'Solveig',
|
|
311
|
+
'Randi', 'Bj\u00f8rg', 'Silje', 'Mari', 'Ingeborg', 'Berit', 'Gunn', 'Sigrid',
|
|
300
312
|
];
|
|
301
313
|
const NO_SURNAMES = [
|
|
302
314
|
'Hansen', 'Johansen', 'Olsen', 'Larsen', 'Andersen', 'Pedersen', 'Nilsen', 'Kristiansen',
|
|
303
|
-
'Jensen', 'Karlsen', 'Berg', 'Haugen', 'Hagen', 'Solberg', 'Moen', '
|
|
315
|
+
'Jensen', 'Karlsen', 'Berg', 'Haugen', 'Hagen', 'Solberg', 'Moen', 'Eide',
|
|
304
316
|
];
|
|
305
317
|
const DA_FIRST_MALE = [
|
|
306
|
-
'Jens', 'Peter', 'Lars', 'Henrik', 'S\u00f8ren', 'Niels', '
|
|
307
|
-
'Mads', 'Rasmus', '
|
|
318
|
+
'Jens', 'Peter', 'Lars', 'Henrik', 'S\u00f8ren', 'Niels', 'Torben', 'Erik',
|
|
319
|
+
'Mads', 'Rasmus', 'Jesper', 'Morten', 'Frederik', 'Mikkel', 'Emil', 'Bjarne',
|
|
308
320
|
];
|
|
309
321
|
const DA_FIRST_FEMALE = [
|
|
310
|
-
'Kirsten', 'Mette', 'Hanne', '
|
|
322
|
+
'Kirsten', 'Mette', 'Hanne', 'Trine', 'Bente', 'Karen', 'Dorthe', 'Helle',
|
|
311
323
|
'Gitte', 'Ditte', 'Freja', 'Signe', 'Maja', 'Cecilie', 'Louise', 'Astrid',
|
|
312
324
|
];
|
|
313
325
|
const DA_SURNAMES = [
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
*/
|
|
22
22
|
import type { DetectedEntity } from './types.js';
|
|
23
23
|
import type { DocCloakEngine, EngineSettings, ProviderId } from './engine.js';
|
|
24
|
-
import type
|
|
24
|
+
import { type RegexRegionId } from './regex/index.js';
|
|
25
25
|
/** Satisfied by Worker, MessagePort and chrome.runtime.Port wrappers. */
|
|
26
26
|
export interface PortLike {
|
|
27
27
|
postMessage(msg: unknown): void;
|
|
@@ -90,6 +90,18 @@ export type EngineResponse = {
|
|
|
90
90
|
} | {
|
|
91
91
|
type: 'released';
|
|
92
92
|
requestId?: number;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Protocol-level failure (T185, R12): a message the host could not act on
|
|
96
|
+
* (unknown type, wrong payload shape) or an error outside the dedicated
|
|
97
|
+
* load/detect replies. `fatal` marks a host that can no longer serve; the
|
|
98
|
+
* client then rejects every pending request and closes.
|
|
99
|
+
*/
|
|
100
|
+
| {
|
|
101
|
+
type: 'error';
|
|
102
|
+
requestId?: number;
|
|
103
|
+
error: string;
|
|
104
|
+
fatal?: boolean;
|
|
93
105
|
};
|
|
94
106
|
/**
|
|
95
107
|
* Serve a real engine over a port. Returns a stop function that
|
package/dist/worker-protocol.js
CHANGED
|
@@ -19,10 +19,83 @@
|
|
|
19
19
|
* is the client side: a DocCloakEngine that forwards over the port (web
|
|
20
20
|
* main thread, extension side panel / service worker).
|
|
21
21
|
*/
|
|
22
|
-
import { clampThreshold, defaultThresholdFor } from "./engine.js";
|
|
22
|
+
import { PROVIDERS, clampThreshold, defaultThresholdFor } from "./engine.js";
|
|
23
|
+
import { REGEX_REGIONS } from "./regex/index.js";
|
|
23
24
|
function errorMessage(err) {
|
|
24
25
|
return err instanceof Error ? err.message : String(err);
|
|
25
26
|
}
|
|
27
|
+
// ── Message validation (R12) ───────────────────────────────
|
|
28
|
+
const REQUEST_TYPES = new Set([
|
|
29
|
+
'init', 'detect', 'switchProvider', 'setThreshold', 'setCustomLabels', 'setRegex', 'setRegexRegion', 'releaseModel',
|
|
30
|
+
]);
|
|
31
|
+
function isRecord(value) {
|
|
32
|
+
return typeof value === 'object' && value !== null;
|
|
33
|
+
}
|
|
34
|
+
function isProviderId(value) {
|
|
35
|
+
return typeof value === 'string' && PROVIDERS.some((p) => p.id === value);
|
|
36
|
+
}
|
|
37
|
+
function isRegexRegionId(value) {
|
|
38
|
+
return typeof value === 'string' && REGEX_REGIONS.includes(value);
|
|
39
|
+
}
|
|
40
|
+
function isStringArray(value) {
|
|
41
|
+
return Array.isArray(value) && value.every((item) => typeof item === 'string');
|
|
42
|
+
}
|
|
43
|
+
function isFiniteNumber(value) {
|
|
44
|
+
return typeof value === 'number' && Number.isFinite(value);
|
|
45
|
+
}
|
|
46
|
+
function optionalRequestId(value) {
|
|
47
|
+
return isFiniteNumber(value) ? value : undefined;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Field-level validation of a message whose `type` is known. Returns a
|
|
51
|
+
* description of the first problem, or null when the payload is usable.
|
|
52
|
+
*/
|
|
53
|
+
function requestProblem(msg) {
|
|
54
|
+
switch (msg.type) {
|
|
55
|
+
case 'init':
|
|
56
|
+
if (msg.providerId !== undefined && !isProviderId(msg.providerId))
|
|
57
|
+
return 'providerId must be a known provider id';
|
|
58
|
+
if (msg.customLabels !== undefined && !isStringArray(msg.customLabels))
|
|
59
|
+
return 'customLabels must be an array of strings';
|
|
60
|
+
if (msg.regexEnabled !== undefined && typeof msg.regexEnabled !== 'boolean')
|
|
61
|
+
return 'regexEnabled must be a boolean';
|
|
62
|
+
if (msg.regexRegion !== undefined && !isRegexRegionId(msg.regexRegion))
|
|
63
|
+
return 'regexRegion must be a known region id';
|
|
64
|
+
return null;
|
|
65
|
+
case 'detect':
|
|
66
|
+
if (!isFiniteNumber(msg.requestId))
|
|
67
|
+
return 'requestId must be a number';
|
|
68
|
+
if (typeof msg.text !== 'string')
|
|
69
|
+
return 'text must be a string';
|
|
70
|
+
return null;
|
|
71
|
+
case 'switchProvider':
|
|
72
|
+
if (!isProviderId(msg.providerId))
|
|
73
|
+
return 'providerId must be a known provider id';
|
|
74
|
+
if (msg.customLabels !== undefined && !isStringArray(msg.customLabels))
|
|
75
|
+
return 'customLabels must be an array of strings';
|
|
76
|
+
return null;
|
|
77
|
+
case 'setThreshold':
|
|
78
|
+
if (!isFiniteNumber(msg.value))
|
|
79
|
+
return 'value must be a finite number';
|
|
80
|
+
return null;
|
|
81
|
+
case 'setCustomLabels':
|
|
82
|
+
if (!isStringArray(msg.labels))
|
|
83
|
+
return 'labels must be an array of strings';
|
|
84
|
+
return null;
|
|
85
|
+
case 'setRegex':
|
|
86
|
+
if (typeof msg.enabled !== 'boolean')
|
|
87
|
+
return 'enabled must be a boolean';
|
|
88
|
+
if (msg.region !== undefined && !isRegexRegionId(msg.region))
|
|
89
|
+
return 'region must be a known region id';
|
|
90
|
+
return null;
|
|
91
|
+
case 'setRegexRegion':
|
|
92
|
+
if (!isRegexRegionId(msg.region))
|
|
93
|
+
return 'region must be a known region id';
|
|
94
|
+
return null;
|
|
95
|
+
case 'releaseModel':
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
26
99
|
// ── Host side ──────────────────────────────────────────────
|
|
27
100
|
/**
|
|
28
101
|
* Serve a real engine over a port. Returns a stop function that
|
|
@@ -46,8 +119,37 @@ export function serveEngine(engine, port) {
|
|
|
46
119
|
post({ type: 'loadError', requestId, error: errorMessage(err) });
|
|
47
120
|
}
|
|
48
121
|
}
|
|
49
|
-
|
|
50
|
-
|
|
122
|
+
/** Fire-and-forget settings message: failures are reported, never thrown. */
|
|
123
|
+
async function handleSetting(run) {
|
|
124
|
+
try {
|
|
125
|
+
await run();
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
post({ type: 'error', error: errorMessage(err) });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Reject a message the host cannot act on. Requests with a dedicated
|
|
133
|
+
* error reply (init/switchProvider -> loadError, detect -> detectError)
|
|
134
|
+
* use it so legacy senders matching by type keep working; everything
|
|
135
|
+
* else gets the generic protocol error.
|
|
136
|
+
*/
|
|
137
|
+
function rejectRequest(raw, problem) {
|
|
138
|
+
const msg = isRecord(raw) ? raw : {};
|
|
139
|
+
const requestId = optionalRequestId(msg.requestId);
|
|
140
|
+
const type = typeof msg.type === 'string' ? msg.type : undefined;
|
|
141
|
+
const error = type ? `Invalid ${type} message: ${problem}` : problem;
|
|
142
|
+
if (type === 'init' || type === 'switchProvider') {
|
|
143
|
+
post({ type: 'loadError', requestId, error });
|
|
144
|
+
}
|
|
145
|
+
else if (type === 'detect' && requestId !== undefined) {
|
|
146
|
+
post({ type: 'detectError', requestId, error });
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
post({ type: 'error', requestId, error });
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
async function dispatch(msg) {
|
|
51
153
|
switch (msg.type) {
|
|
52
154
|
case 'init': {
|
|
53
155
|
await handleLoad(msg.requestId, async () => {
|
|
@@ -87,30 +189,65 @@ export function serveEngine(engine, port) {
|
|
|
87
189
|
break;
|
|
88
190
|
}
|
|
89
191
|
case 'setThreshold': {
|
|
90
|
-
await engine.updateSettings({ threshold: msg.value });
|
|
192
|
+
await handleSetting(() => engine.updateSettings({ threshold: msg.value }));
|
|
91
193
|
break;
|
|
92
194
|
}
|
|
93
195
|
case 'setCustomLabels': {
|
|
94
|
-
await engine.updateSettings({ customLabels: msg.labels });
|
|
196
|
+
await handleSetting(() => engine.updateSettings({ customLabels: msg.labels }));
|
|
95
197
|
break;
|
|
96
198
|
}
|
|
97
199
|
case 'setRegex': {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
200
|
+
await handleSetting(async () => {
|
|
201
|
+
const patch = { regexEnabled: msg.enabled };
|
|
202
|
+
if (msg.region !== undefined)
|
|
203
|
+
patch.regexRegion = msg.region;
|
|
204
|
+
await engine.updateSettings(patch);
|
|
205
|
+
});
|
|
102
206
|
break;
|
|
103
207
|
}
|
|
104
208
|
case 'setRegexRegion': {
|
|
105
|
-
await engine.updateSettings({ regexRegion: msg.region });
|
|
209
|
+
await handleSetting(() => engine.updateSettings({ regexRegion: msg.region }));
|
|
106
210
|
break;
|
|
107
211
|
}
|
|
108
212
|
case 'releaseModel': {
|
|
109
|
-
|
|
110
|
-
|
|
213
|
+
try {
|
|
214
|
+
await engine.release();
|
|
215
|
+
post({ type: 'released', requestId: msg.requestId });
|
|
216
|
+
}
|
|
217
|
+
catch (err) {
|
|
218
|
+
post({ type: 'error', requestId: msg.requestId, error: errorMessage(err) });
|
|
219
|
+
}
|
|
111
220
|
break;
|
|
112
221
|
}
|
|
113
222
|
}
|
|
223
|
+
}
|
|
224
|
+
const unsubscribeMessages = port.onMessage(async (raw) => {
|
|
225
|
+
// R12: the port is same-origin but not trusted with the message shape.
|
|
226
|
+
// Anything that is not a well-formed request gets an error reply and
|
|
227
|
+
// never reaches the engine; nothing here may throw into the transport.
|
|
228
|
+
try {
|
|
229
|
+
if (!isRecord(raw) || typeof raw.type !== 'string') {
|
|
230
|
+
rejectRequest(raw, 'message must be an object with a string type');
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
if (!REQUEST_TYPES.has(raw.type)) {
|
|
234
|
+
post({ type: 'error', requestId: optionalRequestId(raw.requestId), error: `Unknown message type: ${raw.type}` });
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
const problem = requestProblem(raw);
|
|
238
|
+
if (problem) {
|
|
239
|
+
rejectRequest(raw, problem);
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
await dispatch(raw);
|
|
243
|
+
}
|
|
244
|
+
catch (err) {
|
|
245
|
+
// Only reachable if posting a reply itself failed; report best-effort.
|
|
246
|
+
try {
|
|
247
|
+
post({ type: 'error', requestId: isRecord(raw) ? optionalRequestId(raw.requestId) : undefined, error: errorMessage(err) });
|
|
248
|
+
}
|
|
249
|
+
catch { /* transport gone */ }
|
|
250
|
+
}
|
|
114
251
|
});
|
|
115
252
|
return () => {
|
|
116
253
|
unsubscribeMessages();
|
|
@@ -146,6 +283,10 @@ export function connectEngine(port, initial) {
|
|
|
146
283
|
return entry;
|
|
147
284
|
}
|
|
148
285
|
const unsubscribe = port.onMessage((raw) => {
|
|
286
|
+
// Ignore anything that is not an object with a string type: the host is
|
|
287
|
+
// the only expected sender, but a malformed frame must not throw here.
|
|
288
|
+
if (!isRecord(raw) || typeof raw.type !== 'string')
|
|
289
|
+
return;
|
|
149
290
|
const msg = raw;
|
|
150
291
|
switch (msg.type) {
|
|
151
292
|
case 'downloadProgress': {
|
|
@@ -182,6 +323,17 @@ export function connectEngine(port, initial) {
|
|
|
182
323
|
takePending(msg.requestId)?.resolve(undefined);
|
|
183
324
|
break;
|
|
184
325
|
}
|
|
326
|
+
case 'error': {
|
|
327
|
+
const err = new Error(msg.error);
|
|
328
|
+
if (msg.fatal) {
|
|
329
|
+
// The host cannot serve any further request: fail everything
|
|
330
|
+
// that is still waiting instead of leaving promises hanging.
|
|
331
|
+
close(err);
|
|
332
|
+
break;
|
|
333
|
+
}
|
|
334
|
+
takePending(msg.requestId)?.reject(err);
|
|
335
|
+
break;
|
|
336
|
+
}
|
|
185
337
|
}
|
|
186
338
|
});
|
|
187
339
|
function request(kind, message, onProgress) {
|
package/package.json
CHANGED
package/rules/at.json
CHANGED
package/rules/be.json
CHANGED
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
{
|
|
37
37
|
"id": "regex:be:postal",
|
|
38
38
|
"entityType": "ADDRESS",
|
|
39
|
-
"pattern": "\\b[1-9]\\d{3}\\s+[\\p{L}][\\p{L}\\s'-]
|
|
39
|
+
"pattern": "\\b[1-9]\\d{3}\\s+[\\p{L}][\\p{L}\\s'-]*[\\p{L}](?![\\p{L}\\p{N}])",
|
|
40
40
|
"flags": "gu",
|
|
41
41
|
"confidence": 0.75,
|
|
42
42
|
"domains": [
|
package/rules/ch.json
CHANGED
package/rules/de.json
CHANGED
package/rules/dk.json
CHANGED
package/rules/es.json
CHANGED
package/rules/fi.json
CHANGED
package/rules/fr.json
CHANGED
|
@@ -99,7 +99,7 @@
|
|
|
99
99
|
{
|
|
100
100
|
"id": "regex:fr:postal",
|
|
101
101
|
"entityType": "ADDRESS",
|
|
102
|
-
"pattern": "\\b\\d{5}\\s+[\\p{L}][\\p{L}\\s'-]
|
|
102
|
+
"pattern": "\\b\\d{5}\\s+[\\p{L}][\\p{L}\\s'-]*[\\p{L}](?![\\p{L}\\p{N}])",
|
|
103
103
|
"flags": "gu",
|
|
104
104
|
"confidence": 0.8,
|
|
105
105
|
"domains": [
|
package/rules/it.json
CHANGED
package/rules/no.json
CHANGED
package/rules/pl.json
CHANGED
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
{
|
|
117
117
|
"id": "regex:pl:postal",
|
|
118
118
|
"entityType": "ADDRESS",
|
|
119
|
-
"pattern": "\\b\\d{2}-\\d{3}\\s+[\\p{L}][\\p{L}\\s-]
|
|
119
|
+
"pattern": "\\b\\d{2}-\\d{3}\\s+[\\p{L}][\\p{L}\\s-]*[\\p{L}](?![\\p{L}\\p{N}])",
|
|
120
120
|
"flags": "gu",
|
|
121
121
|
"confidence": 0.8,
|
|
122
122
|
"domains": [
|
package/rules/pt.json
CHANGED
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
{
|
|
51
51
|
"id": "regex:pt:postal",
|
|
52
52
|
"entityType": "ADDRESS",
|
|
53
|
-
"pattern": "\\b\\d{4}-\\d{3}\\s+[\\p{L}][\\p{L}\\s'-]
|
|
53
|
+
"pattern": "\\b\\d{4}-\\d{3}\\s+[\\p{L}][\\p{L}\\s'-]*[\\p{L}](?![\\p{L}\\p{N}])",
|
|
54
54
|
"flags": "gu",
|
|
55
55
|
"confidence": 0.85,
|
|
56
56
|
"domains": [
|