minotor 9.0.2 â 9.2.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/.github/workflows/minotor.yml +36 -23
- package/CHANGELOG.md +3 -3
- package/dist/cli.mjs +86 -54
- package/dist/cli.mjs.map +1 -1
- package/dist/parser.cjs.js +19 -10
- package/dist/parser.cjs.js.map +1 -1
- package/dist/parser.esm.js +19 -10
- package/dist/parser.esm.js.map +1 -1
- package/dist/router.cjs.js +1 -1
- package/dist/router.cjs.js.map +1 -1
- package/dist/router.esm.js +1 -1
- package/dist/router.esm.js.map +1 -1
- package/dist/router.umd.js +1 -1
- package/dist/router.umd.js.map +1 -1
- package/dist/routing/result.d.ts +9 -1
- package/dist/stops/stopsIndex.d.ts +7 -1
- package/eslint.config.mjs +0 -1
- package/package.json +25 -25
- package/src/__e2e__/router.test.ts +40 -53
- package/src/__e2e__/timetable/stops.bin +2 -2
- package/src/__e2e__/timetable/timetable.bin +2 -2
- package/src/routing/__tests__/result.test.ts +81 -0
- package/src/routing/result.ts +46 -14
- package/src/stops/__tests__/stopFinder.test.ts +9 -0
- package/src/stops/proto/stops.ts +1 -1
- package/src/stops/stopsIndex.ts +12 -1
- package/src/timetable/proto/timetable.ts +1 -1
|
@@ -2,16 +2,15 @@ name: minotor
|
|
|
2
2
|
|
|
3
3
|
on: [push]
|
|
4
4
|
|
|
5
|
-
env:
|
|
6
|
-
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
7
|
-
|
|
8
5
|
jobs:
|
|
9
6
|
format:
|
|
10
7
|
name: đ
Prettier
|
|
11
8
|
runs-on: ubuntu-latest
|
|
12
9
|
steps:
|
|
13
|
-
- uses: actions/checkout@
|
|
14
|
-
- uses: actions/setup-node@
|
|
10
|
+
- uses: actions/checkout@v4
|
|
11
|
+
- uses: actions/setup-node@v6
|
|
12
|
+
with:
|
|
13
|
+
node-version-file: 'package.json'
|
|
15
14
|
- uses: bahmutov/npm-install@v1
|
|
16
15
|
- name: đ
Prettier
|
|
17
16
|
run: npm run format:check
|
|
@@ -20,8 +19,10 @@ jobs:
|
|
|
20
19
|
name: đ ESLint
|
|
21
20
|
runs-on: ubuntu-latest
|
|
22
21
|
steps:
|
|
23
|
-
- uses: actions/checkout@
|
|
24
|
-
- uses: actions/setup-node@
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
|
+
- uses: actions/setup-node@v6
|
|
24
|
+
with:
|
|
25
|
+
node-version-file: 'package.json'
|
|
25
26
|
- uses: bahmutov/npm-install@v1
|
|
26
27
|
- name: ⏣ ESLint
|
|
27
28
|
run: npm run lint:check
|
|
@@ -30,8 +31,10 @@ jobs:
|
|
|
30
31
|
name: đĄď¸ Audit
|
|
31
32
|
runs-on: ubuntu-latest
|
|
32
33
|
steps:
|
|
33
|
-
- uses: actions/checkout@
|
|
34
|
-
- uses: actions/setup-node@
|
|
34
|
+
- uses: actions/checkout@v4
|
|
35
|
+
- uses: actions/setup-node@v6
|
|
36
|
+
with:
|
|
37
|
+
node-version-file: 'package.json'
|
|
35
38
|
- name: đĄď¸ Audit
|
|
36
39
|
run: npm audit --audit-level=high --omit=dev
|
|
37
40
|
|
|
@@ -39,8 +42,10 @@ jobs:
|
|
|
39
42
|
name: đ Spellcheck
|
|
40
43
|
runs-on: ubuntu-latest
|
|
41
44
|
steps:
|
|
42
|
-
- uses: actions/checkout@
|
|
43
|
-
- uses: actions/setup-node@
|
|
45
|
+
- uses: actions/checkout@v4
|
|
46
|
+
- uses: actions/setup-node@v6
|
|
47
|
+
with:
|
|
48
|
+
node-version-file: 'package.json'
|
|
44
49
|
- uses: bahmutov/npm-install@v1
|
|
45
50
|
- name: đ¸ Spellcheck
|
|
46
51
|
run: npm run spell:check
|
|
@@ -49,8 +54,10 @@ jobs:
|
|
|
49
54
|
name: ĘŚ Typecheck
|
|
50
55
|
runs-on: ubuntu-latest
|
|
51
56
|
steps:
|
|
52
|
-
- uses: actions/checkout@
|
|
53
|
-
- uses: actions/setup-node@
|
|
57
|
+
- uses: actions/checkout@v4
|
|
58
|
+
- uses: actions/setup-node@v6
|
|
59
|
+
with:
|
|
60
|
+
node-version-file: 'package.json'
|
|
54
61
|
- uses: bahmutov/npm-install@v1
|
|
55
62
|
- name: ĘŚ Typecheck
|
|
56
63
|
run: npm run type:check
|
|
@@ -59,10 +66,10 @@ jobs:
|
|
|
59
66
|
name: ⥠Tests
|
|
60
67
|
runs-on: ubuntu-latest
|
|
61
68
|
steps:
|
|
62
|
-
- uses: actions/checkout@
|
|
63
|
-
- uses: actions/setup-node@
|
|
69
|
+
- uses: actions/checkout@v4
|
|
70
|
+
- uses: actions/setup-node@v6
|
|
64
71
|
with:
|
|
65
|
-
node-version: '
|
|
72
|
+
node-version-file: 'package.json'
|
|
66
73
|
- uses: bahmutov/npm-install@v1
|
|
67
74
|
- name: ⥠Tests
|
|
68
75
|
run: npm run test:coverage
|
|
@@ -71,14 +78,14 @@ jobs:
|
|
|
71
78
|
name: đ End-to-end tests
|
|
72
79
|
runs-on: ubuntu-latest
|
|
73
80
|
steps:
|
|
74
|
-
- uses: actions/checkout@
|
|
81
|
+
- uses: actions/checkout@v4
|
|
75
82
|
with:
|
|
76
83
|
lfs: true
|
|
77
84
|
- name: Checkout LFS objects
|
|
78
85
|
run: git lfs pull
|
|
79
|
-
- uses: actions/setup-node@
|
|
86
|
+
- uses: actions/setup-node@v6
|
|
80
87
|
with:
|
|
81
|
-
node-version: '
|
|
88
|
+
node-version-file: 'package.json'
|
|
82
89
|
- uses: bahmutov/npm-install@v1
|
|
83
90
|
- name: đ End-to-end tests
|
|
84
91
|
run: npm run e2e
|
|
@@ -87,15 +94,21 @@ jobs:
|
|
|
87
94
|
name: đ Build & release
|
|
88
95
|
needs: [format, lint, audit, spell, type, test, e2e]
|
|
89
96
|
runs-on: ubuntu-latest
|
|
97
|
+
permissions:
|
|
98
|
+
contents: write
|
|
99
|
+
id-token: write
|
|
90
100
|
steps:
|
|
91
|
-
- uses: actions/checkout@
|
|
92
|
-
- uses: actions/setup-node@
|
|
101
|
+
- uses: actions/checkout@v4
|
|
102
|
+
- uses: actions/setup-node@v6
|
|
103
|
+
with:
|
|
104
|
+
node-version-file: 'package.json'
|
|
93
105
|
- uses: bahmutov/npm-install@v1
|
|
94
106
|
- uses: arduino/setup-protoc@v3
|
|
107
|
+
with:
|
|
108
|
+
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
95
109
|
- name: đ¨ Build
|
|
96
110
|
run: npm run build
|
|
97
111
|
- name: đ Release
|
|
98
112
|
env:
|
|
99
|
-
GITHUB_TOKEN: ${{ secrets.
|
|
100
|
-
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
113
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
101
114
|
run: npm run semantic-release
|
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
# [9.2.0](https://github.com/aubryio/minotor/compare/v9.1.0...v9.2.0) (2026-01-08)
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
###
|
|
4
|
+
### Features
|
|
5
5
|
|
|
6
|
-
*
|
|
6
|
+
* allow to query best routes by stop ids directly ([#58](https://github.com/aubryio/minotor/issues/58)) ([9cd71aa](https://github.com/aubryio/minotor/commit/9cd71aa7f856e0bfcc895dc5b28b43b27154da3b))
|
package/dist/cli.mjs
CHANGED
|
@@ -163,7 +163,7 @@ function requireArgument () {
|
|
|
163
163
|
break;
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
-
if (this._name.
|
|
166
|
+
if (this._name.endsWith('...')) {
|
|
167
167
|
this.variadic = true;
|
|
168
168
|
this._name = this._name.slice(0, -3);
|
|
169
169
|
}
|
|
@@ -183,12 +183,13 @@ function requireArgument () {
|
|
|
183
183
|
* @package
|
|
184
184
|
*/
|
|
185
185
|
|
|
186
|
-
|
|
186
|
+
_collectValue(value, previous) {
|
|
187
187
|
if (previous === this.defaultValue || !Array.isArray(previous)) {
|
|
188
188
|
return [value];
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
-
|
|
191
|
+
previous.push(value);
|
|
192
|
+
return previous;
|
|
192
193
|
}
|
|
193
194
|
|
|
194
195
|
/**
|
|
@@ -233,7 +234,7 @@ function requireArgument () {
|
|
|
233
234
|
);
|
|
234
235
|
}
|
|
235
236
|
if (this.variadic) {
|
|
236
|
-
return this.
|
|
237
|
+
return this._collectValue(arg, previous);
|
|
237
238
|
}
|
|
238
239
|
return arg;
|
|
239
240
|
};
|
|
@@ -1210,12 +1211,13 @@ function requireOption () {
|
|
|
1210
1211
|
* @package
|
|
1211
1212
|
*/
|
|
1212
1213
|
|
|
1213
|
-
|
|
1214
|
+
_collectValue(value, previous) {
|
|
1214
1215
|
if (previous === this.defaultValue || !Array.isArray(previous)) {
|
|
1215
1216
|
return [value];
|
|
1216
1217
|
}
|
|
1217
1218
|
|
|
1218
|
-
|
|
1219
|
+
previous.push(value);
|
|
1220
|
+
return previous;
|
|
1219
1221
|
}
|
|
1220
1222
|
|
|
1221
1223
|
/**
|
|
@@ -1234,7 +1236,7 @@ function requireOption () {
|
|
|
1234
1236
|
);
|
|
1235
1237
|
}
|
|
1236
1238
|
if (this.variadic) {
|
|
1237
|
-
return this.
|
|
1239
|
+
return this._collectValue(arg, previous);
|
|
1238
1240
|
}
|
|
1239
1241
|
return arg;
|
|
1240
1242
|
};
|
|
@@ -1791,11 +1793,10 @@ function requireCommand () {
|
|
|
1791
1793
|
configureOutput(configuration) {
|
|
1792
1794
|
if (configuration === undefined) return this._outputConfiguration;
|
|
1793
1795
|
|
|
1794
|
-
this._outputConfiguration =
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
);
|
|
1796
|
+
this._outputConfiguration = {
|
|
1797
|
+
...this._outputConfiguration,
|
|
1798
|
+
...configuration,
|
|
1799
|
+
};
|
|
1799
1800
|
return this;
|
|
1800
1801
|
}
|
|
1801
1802
|
|
|
@@ -1921,7 +1922,7 @@ function requireCommand () {
|
|
|
1921
1922
|
*/
|
|
1922
1923
|
addArgument(argument) {
|
|
1923
1924
|
const previousArgument = this.registeredArguments.slice(-1)[0];
|
|
1924
|
-
if (previousArgument
|
|
1925
|
+
if (previousArgument?.variadic) {
|
|
1925
1926
|
throw new Error(
|
|
1926
1927
|
`only the last argument can be variadic '${previousArgument.name()}'`,
|
|
1927
1928
|
);
|
|
@@ -2246,7 +2247,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2246
2247
|
if (val !== null && option.parseArg) {
|
|
2247
2248
|
val = this._callParseArg(option, val, oldValue, invalidValueMessage);
|
|
2248
2249
|
} else if (val !== null && option.variadic) {
|
|
2249
|
-
val = option.
|
|
2250
|
+
val = option._collectValue(val, oldValue);
|
|
2250
2251
|
}
|
|
2251
2252
|
|
|
2252
2253
|
// Fill-in appropriate missing values. Long winded but easy to follow.
|
|
@@ -3025,7 +3026,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3025
3026
|
|
|
3026
3027
|
_chainOrCall(promise, fn) {
|
|
3027
3028
|
// thenable
|
|
3028
|
-
if (promise
|
|
3029
|
+
if (promise?.then && typeof promise.then === 'function') {
|
|
3029
3030
|
// already have a promise, chain callback
|
|
3030
3031
|
return promise.then(() => fn());
|
|
3031
3032
|
}
|
|
@@ -3156,7 +3157,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3156
3157
|
promiseChain = this._chainOrCallHooks(promiseChain, 'postAction');
|
|
3157
3158
|
return promiseChain;
|
|
3158
3159
|
}
|
|
3159
|
-
if (this.parent
|
|
3160
|
+
if (this.parent?.listenerCount(commandEvent)) {
|
|
3160
3161
|
checkForUnknownOptions();
|
|
3161
3162
|
this._processArguments();
|
|
3162
3163
|
this.parent.emit(commandEvent, operands, unknown); // legacy
|
|
@@ -3286,15 +3287,14 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3286
3287
|
* sub --unknown uuu op => [sub], [--unknown uuu op]
|
|
3287
3288
|
* sub -- --unknown uuu op => [sub --unknown uuu op], []
|
|
3288
3289
|
*
|
|
3289
|
-
* @param {string[]}
|
|
3290
|
+
* @param {string[]} args
|
|
3290
3291
|
* @return {{operands: string[], unknown: string[]}}
|
|
3291
3292
|
*/
|
|
3292
3293
|
|
|
3293
|
-
parseOptions(
|
|
3294
|
+
parseOptions(args) {
|
|
3294
3295
|
const operands = []; // operands, not options or values
|
|
3295
3296
|
const unknown = []; // first unknown option and remaining unknown args
|
|
3296
3297
|
let dest = operands;
|
|
3297
|
-
const args = argv.slice();
|
|
3298
3298
|
|
|
3299
3299
|
function maybeOption(arg) {
|
|
3300
3300
|
return arg.length > 1 && arg[0] === '-';
|
|
@@ -3302,7 +3302,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3302
3302
|
|
|
3303
3303
|
const negativeNumberArg = (arg) => {
|
|
3304
3304
|
// return false if not a negative number
|
|
3305
|
-
if (
|
|
3305
|
+
if (!/^-(\d+|\d*\.\d+)(e[+-]?\d+)?$/.test(arg)) return false;
|
|
3306
3306
|
// negative number is ok unless digit used as an option in command hierarchy
|
|
3307
3307
|
return !this._getCommandAndAncestors().some((cmd) =>
|
|
3308
3308
|
cmd.options
|
|
@@ -3313,13 +3313,16 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3313
3313
|
|
|
3314
3314
|
// parse options
|
|
3315
3315
|
let activeVariadicOption = null;
|
|
3316
|
-
|
|
3317
|
-
|
|
3316
|
+
let activeGroup = null; // working through group of short options, like -abc
|
|
3317
|
+
let i = 0;
|
|
3318
|
+
while (i < args.length || activeGroup) {
|
|
3319
|
+
const arg = activeGroup ?? args[i++];
|
|
3320
|
+
activeGroup = null;
|
|
3318
3321
|
|
|
3319
3322
|
// literal
|
|
3320
3323
|
if (arg === '--') {
|
|
3321
3324
|
if (dest === unknown) dest.push(arg);
|
|
3322
|
-
dest.push(...args);
|
|
3325
|
+
dest.push(...args.slice(i));
|
|
3323
3326
|
break;
|
|
3324
3327
|
}
|
|
3325
3328
|
|
|
@@ -3337,17 +3340,17 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3337
3340
|
// recognised option, call listener to assign value with possible custom processing
|
|
3338
3341
|
if (option) {
|
|
3339
3342
|
if (option.required) {
|
|
3340
|
-
const value = args
|
|
3343
|
+
const value = args[i++];
|
|
3341
3344
|
if (value === undefined) this.optionMissingArgument(option);
|
|
3342
3345
|
this.emit(`option:${option.name()}`, value);
|
|
3343
3346
|
} else if (option.optional) {
|
|
3344
3347
|
let value = null;
|
|
3345
3348
|
// historical behaviour is optional value is following arg unless an option
|
|
3346
3349
|
if (
|
|
3347
|
-
args.length
|
|
3348
|
-
(!maybeOption(args[
|
|
3350
|
+
i < args.length &&
|
|
3351
|
+
(!maybeOption(args[i]) || negativeNumberArg(args[i]))
|
|
3349
3352
|
) {
|
|
3350
|
-
value = args
|
|
3353
|
+
value = args[i++];
|
|
3351
3354
|
}
|
|
3352
3355
|
this.emit(`option:${option.name()}`, value);
|
|
3353
3356
|
} else {
|
|
@@ -3370,9 +3373,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3370
3373
|
// option with value following in same argument
|
|
3371
3374
|
this.emit(`option:${option.name()}`, arg.slice(2));
|
|
3372
3375
|
} else {
|
|
3373
|
-
// boolean option
|
|
3376
|
+
// boolean option
|
|
3374
3377
|
this.emit(`option:${option.name()}`);
|
|
3375
|
-
|
|
3378
|
+
// remove the processed option and keep processing group
|
|
3379
|
+
activeGroup = `-${arg.slice(2)}`;
|
|
3376
3380
|
}
|
|
3377
3381
|
continue;
|
|
3378
3382
|
}
|
|
@@ -3409,26 +3413,23 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3409
3413
|
) {
|
|
3410
3414
|
if (this._findCommand(arg)) {
|
|
3411
3415
|
operands.push(arg);
|
|
3412
|
-
|
|
3416
|
+
unknown.push(...args.slice(i));
|
|
3413
3417
|
break;
|
|
3414
3418
|
} else if (
|
|
3415
3419
|
this._getHelpCommand() &&
|
|
3416
3420
|
arg === this._getHelpCommand().name()
|
|
3417
3421
|
) {
|
|
3418
|
-
operands.push(arg);
|
|
3419
|
-
if (args.length > 0) operands.push(...args);
|
|
3422
|
+
operands.push(arg, ...args.slice(i));
|
|
3420
3423
|
break;
|
|
3421
3424
|
} else if (this._defaultCommandName) {
|
|
3422
|
-
unknown.push(arg);
|
|
3423
|
-
if (args.length > 0) unknown.push(...args);
|
|
3425
|
+
unknown.push(arg, ...args.slice(i));
|
|
3424
3426
|
break;
|
|
3425
3427
|
}
|
|
3426
3428
|
}
|
|
3427
3429
|
|
|
3428
3430
|
// If using passThroughOptions, stop processing options at first command-argument.
|
|
3429
3431
|
if (this._passThroughOptions) {
|
|
3430
|
-
dest.push(arg);
|
|
3431
|
-
if (args.length > 0) dest.push(...args);
|
|
3432
|
+
dest.push(arg, ...args.slice(i));
|
|
3432
3433
|
break;
|
|
3433
3434
|
}
|
|
3434
3435
|
|
|
@@ -6138,7 +6139,6 @@ class InvalidZone extends Zone {
|
|
|
6138
6139
|
* @private
|
|
6139
6140
|
*/
|
|
6140
6141
|
|
|
6141
|
-
|
|
6142
6142
|
function normalizeZone(input, defaultZone) {
|
|
6143
6143
|
if (isUndefined(input) || input === null) {
|
|
6144
6144
|
return defaultZone;
|
|
@@ -6643,7 +6643,6 @@ function hasInvalidTimeData(obj) {
|
|
|
6643
6643
|
it up into, say, parsingUtil.js and basicUtil.js and so on. But they are divided up by feature area.
|
|
6644
6644
|
*/
|
|
6645
6645
|
|
|
6646
|
-
|
|
6647
6646
|
/**
|
|
6648
6647
|
* @private
|
|
6649
6648
|
*/
|
|
@@ -14431,7 +14430,8 @@ function makeInt64Support() {
|
|
|
14431
14430
|
typeof dv.getBigUint64 === "function" &&
|
|
14432
14431
|
typeof dv.setBigInt64 === "function" &&
|
|
14433
14432
|
typeof dv.setBigUint64 === "function" &&
|
|
14434
|
-
(
|
|
14433
|
+
(!!globalThis.Deno ||
|
|
14434
|
+
typeof process != "object" ||
|
|
14435
14435
|
typeof process.env != "object" ||
|
|
14436
14436
|
process.env.BUF_BIGINT_DISABLE !== "1");
|
|
14437
14437
|
if (ok) {
|
|
@@ -15643,7 +15643,7 @@ function sqDist(ax, ay, bx, by) {
|
|
|
15643
15643
|
return dx * dx + dy * dy;
|
|
15644
15644
|
}
|
|
15645
15645
|
|
|
15646
|
-
const xt="ENTRIES",B="KEYS",G="VALUES",g="";class V{set;_type;_path;constructor(e,n){const o=e._tree,s=Array.from(o.keys());this.set=e,this._type=n,this._path=s.length>0?[{node:o,keys:s}]:[];}next(){const e=this.dive();return this.backtrack(),e}dive(){if(this._path.length===0)return {done:true,value:void 0};const{node:e,keys:n}=z(this._path);if(z(n)===g)return {done:false,value:this.result()};const o=e.get(z(n));return this._path.push({node:o,keys:Array.from(o.keys())}),this.dive()}backtrack(){if(this._path.length===0)return;const e=z(this._path).keys;e.pop(),!(e.length>0)&&(this._path.pop(),this.backtrack());}key(){return this.set._prefix+this._path.map(({keys:e})=>z(e)).filter(e=>e!==g).join("")}value(){return z(this._path).node.get(g)}result(){switch(this._type){case G:return this.value();case B:return this.key();default:return [this.key(),this.value()]}}[Symbol.iterator](){return this}}const z=t=>t[t.length-1],zt=(t,e,n)=>{const o=new Map;if(typeof e!="string")return o;const s=e.length+1,r=s+n,i=new Uint8Array(r*s).fill(n+1);for(let c=0;c<s;++c)i[c]=c;for(let c=1;c<r;++c)i[c*s]=c;return K(t,e,n,o,i,1,s,""),o},K=(t,e,n,o,s,r,i,c)=>{const u=r*i;t:for(const d of t.keys())if(d===g){const a=s[u-1];a<=n&&o.set(c,[t.get(d),a]);}else {let a=r;for(let h=0;h<d.length;++h,++a){const f=d[h],_=i*a,p=_-i;let l=s[_];const m=Math.max(0,a-n-1),y=Math.min(i-1,a+n);for(let w=m;w<y;++w){const C=f!==e[w],O=s[p+w]+ +C,b=s[p+w+1]+1,x=s[_+w]+1,S=s[_+w+1]=Math.min(O,b,x);S<l&&(l=S);}if(l>n)continue t}K(t.get(d),e,n,o,s,a,i,c+d);}};class I{_tree;_prefix;_size=void 0;constructor(e=new Map,n=""){this._tree=e,this._prefix=n;}atPrefix(e){if(!e.startsWith(this._prefix))throw new Error("Mismatched prefix");const[n,o]=v(this._tree,e.slice(this._prefix.length));if(n===void 0){const[s,r]=L(o);for(const i of s.keys())if(i!==g&&i.startsWith(r)){const c=new Map;return c.set(i.slice(r.length),s.get(i)),new I(c,e)}}return new I(n,e)}clear(){this._size=void 0,this._tree.clear();}delete(e){return this._size=void 0,St(this._tree,e)}entries(){return new V(this,xt)}forEach(e){for(const[n,o]of this)e(n,o,this);}fuzzyGet(e,n){return zt(this._tree,e,n)}get(e){const n=T(this._tree,e);return n!==void 0?n.get(g):void 0}has(e){return T(this._tree,e)?.has(g)??false}keys(){return new V(this,B)}set(e,n){if(typeof e!="string")throw new Error("key must be a string");return this._size=void 0,M(this._tree,e).set(g,n),this}get size(){if(this._size)return this._size;this._size=0;const e=this.entries();for(;!e.next().done;)this._size+=1;return this._size}update(e,n){if(typeof e!="string")throw new Error("key must be a string");this._size=void 0;const o=M(this._tree,e);return o.set(g,n(o.get(g))),this}fetch(e,n){if(typeof e!="string")throw new Error("key must be a string");this._size=void 0;const o=M(this._tree,e);let s=o.get(g);return s===void 0&&o.set(g,s=n()),s}values(){return new V(this,G)}[Symbol.iterator](){return this.entries()}static from(e){const n=new I;for(const[o,s]of e)n.set(o,s);return n}static fromObject(e){return I.from(Object.entries(e))}}const v=(t,e,n=[])=>{if(e.length===0||t==null)return [t,n];for(const o of t.keys())if(o!==g&&e.startsWith(o))return n.push([t,o]),v(t.get(o),e.slice(o.length),n);return n.push([t,e]),v(void 0,"",n)},T=(t,e)=>{if(e.length===0||!t)return t;for(const n of t.keys())if(n!==g&&e.startsWith(n))return T(t.get(n),e.slice(n.length))},M=(t,e)=>{const n=e.length;t:for(let o=0;t&&o<n;){for(const r of t.keys())if(r!==g&&e[o]===r[0]){const i=Math.min(n-o,r.length);let c=1;for(;c<i&&e[o+c]===r[c];)++c;const u=t.get(r);if(c===r.length)t=u;else {const d=new Map;d.set(r.slice(c),u),t.set(e.slice(o,o+c),d),t.delete(r),t=d;}o+=c;continue t}const s=new Map;return t.set(e.slice(o),s),s}return t},St=(t,e)=>{const[n,o]=v(t,e);if(n!==void 0){if(n.delete(g),n.size===0)Q(o);else if(n.size===1){const[s,r]=n.entries().next().value;Y(o,s,r);}}},Q=t=>{if(t.length===0)return;const[e,n]=L(t);if(e.delete(n),e.size===0)Q(t.slice(0,-1));else if(e.size===1){const[o,s]=e.entries().next().value;o!==g&&Y(t.slice(0,-1),o,s);}},Y=(t,e,n)=>{if(t.length===0)return;const[o,s]=L(t);o.set(s+e,n),o.delete(s);},L=t=>t[t.length-1],Z=(t,e)=>t._idToShortId.has(e),vt=/[\n\r\p{Z}\p{P}]+/u,D="or",H="and",Ft="and_not",kt=(t,e)=>{t.includes(e)||t.push(e);},tt=(t,e)=>{for(const n of e)t.includes(n)||t.push(n);},et=({score:t},{score:e})=>e-t,nt=()=>new Map,E=(t,e)=>Object.prototype.hasOwnProperty.call(t,e)?t[e]:void 0,ot={[D]:(t,e)=>{for(const n of e.keys()){const o=t.get(n);if(o==null)t.set(n,e.get(n));else {const{score:s,terms:r,match:i}=e.get(n);o.score=o.score+s,o.match=Object.assign(o.match,i),tt(o.terms,r);}}return t},[H]:(t,e)=>{const n=new Map;for(const o of e.keys()){const s=t.get(o);if(s==null)continue;const{score:r,terms:i,match:c}=e.get(o);tt(s.terms,i),n.set(o,{score:s.score+r,terms:s.terms,match:Object.assign(s.match,c)});}return n},[Ft]:(t,e)=>{for(const n of e.keys())t.delete(n);return t}},Ct=(t,e,n,o,s,r)=>{const{k:i,b:c,d:u}=r;return Math.log(1+(n-e+.5)/(e+.5))*(u+t*(i+1)/(t+i*(1-c+c*o/s)))},Ot=t=>(e,n,o)=>({term:e,fuzzy:typeof t.fuzzy=="function"?t.fuzzy(e,n,o):t.fuzzy??false,prefix:typeof t.prefix=="function"?t.prefix(e,n,o):t.prefix===true,termBoost:typeof t.boostTerm=="function"?t.boostTerm(e,n,o):1}),st=(t,e,n,o)=>{for(const s of Object.keys(t._fieldIds))if(t._fieldIds[s]===n){t._options.logger("warn",`SlimSearch: document with ID ${t._documentIds.get(e)} has changed before removal: term "${o}" was not present in field "${s}". Removing a document after it has changed can corrupt the index!`,"version_conflict");return}},it=(t,e,n,o)=>{const s=t._index.fetch(o,nt);let r=s.get(e);if(r==null)r=new Map,r.set(n,1),s.set(e,r);else {const i=r.get(n);r.set(n,(i??0)+1);}},A=(t,e,n,o)=>{if(!t._index.has(o)){st(t,n,e,o);return}const s=t._index.fetch(o,nt),r=s.get(e),i=r?.get(n);!r||typeof i>"u"?st(t,n,e,o):i<=1?r.size<=1?s.delete(e):r.delete(n):r.set(n,i-1),t._index.get(o).size===0&&t._index.delete(o);},Vt=(t,e,n,o,s)=>{let r=t._fieldLength.get(e);r==null&&t._fieldLength.set(e,r=[]),r[n]=s;const i=(t._avgFieldLength[n]||0)*o+s;t._avgFieldLength[n]=i/(o+1);},Tt=(t,e)=>{const n=t._nextId;return t._idToShortId.set(e,n),t._documentIds.set(n,e),t._documentCount+=1,t._nextId+=1,n},Mt=(t,e,n)=>{const{storeFields:o,extractField:s}=t._options;if(o?.length===0)return;let r=t._storedFields.get(e);r===void 0&&t._storedFields.set(e,r={});for(const i of o){const c=s(n,i);c!=null&&(r[i]=c);}},j=(t,e)=>{const{extractField:n,tokenize:o,processTerm:s,fields:r,idField:i}=t._options,c=n(e,i);if(c==null)throw new Error(`SlimSearch: document does not have ID field "${i}"`);if(Z(t,c))throw new Error(`SlimSearch: duplicate ID ${c}`);const u=Tt(t,c);Mt(t,u,e);for(const d of r){const a=n(e,d);if(a==null)continue;const h=o(a.toString(),d),f=t._fieldIds[d],_=new Set(h).size;Vt(t,u,f,t._documentCount-1,_);for(const p of h){const l=s(p,d);if(Array.isArray(l))for(const m of l)it(t,f,u,m);else l&&it(t,f,u,l);}}},q=(t,e)=>{for(const n of e)j(t,n);},Dt={k:1.2,b:.7,d:.5},$={idField:"id",extractField:(t,e)=>t[e],tokenize:t=>t.split(vt),processTerm:t=>t.toLowerCase(),fields:void 0,searchOptions:void 0,storeFields:[],logger:(t,e)=>{console?.[t]?.(e);},autoVacuum:true},rt={combineWith:D,prefix:false,fuzzy:false,maxFuzzy:6,boost:{},weights:{fuzzy:.45,prefix:.375},bm25:Dt},Et={combineWith:H,prefix:(t,e,n)=>e===n.length-1},N={batchSize:1e3,batchWait:10},W={minDirtFactor:.1,minDirtCount:20},P={...N,...W},R=Symbol("*"),jt=(t,e)=>{const n=new Map,o={...t._options.searchOptions,...e};for(const[s,r]of t._documentIds){const i=o.boostDocument?o.boostDocument(r,"",t._storedFields.get(s)):1;n.set(s,{score:i,terms:[],match:{}});}return n},ct=(t,e=D)=>{if(t.length===0)return new Map;const n=e.toLowerCase();if(!(n in ot))throw new Error(`Invalid combination operator: ${e}`);return t.reduce(ot[n])},J=(t,e,n,o,s,r,i,c,u,d=new Map)=>{if(r==null)return d;for(const a of Object.keys(i)){const h=i[a],f=t._fieldIds[a],_=r.get(f);if(_==null)continue;let p=_.size;const l=t._avgFieldLength[f];for(const m of _.keys()){if(!t._documentIds.has(m)){A(t,f,m,n),p-=1;continue}const y=c?c(t._documentIds.get(m),n,t._storedFields.get(m)):1;if(!y)continue;const w=_.get(m),C=t._fieldLength.get(m)[f],O=Ct(w,p,t._documentCount,C,l,u),b=o*s*h*y*O,x=d.get(m);if(x){x.score+=b,kt(x.terms,e);const S=E(x.match,n);S?S.push(a):x.match[n]=[a];}else d.set(m,{score:b,terms:[e],match:{[n]:[a]}});}}return d},qt=(t,e,n)=>{const o={...t._options.searchOptions,...n},s=(o.fields??t._options.fields).reduce((l,m)=>({...l,[m]:E(o.boost,m)||1}),{}),{boostDocument:r,weights:i,maxFuzzy:c,bm25:u}=o,{fuzzy:d,prefix:a}={...rt.weights,...i},h=t._index.get(e.term),f=J(t,e.term,e.term,1,e.termBoost,h,s,r,u);let _,p;if(e.prefix&&(_=t._index.atPrefix(e.term)),e.fuzzy){const l=e.fuzzy===true?.2:e.fuzzy,m=l<1?Math.min(c,Math.round(e.term.length*l)):l;m&&(p=t._index.fuzzyGet(e.term,m));}if(_)for(const[l,m]of _){const y=l.length-e.term.length;if(!y)continue;p?.delete(l);const w=a*l.length/(l.length+.3*y);J(t,e.term,l,w,e.termBoost,m,s,r,u,f);}if(p)for(const l of p.keys()){const[m,y]=p.get(l);if(!y)continue;const w=d*l.length/(l.length+y);J(t,e.term,l,w,e.termBoost,m,s,r,u,f);}return f},ut=(t,e,n={})=>{if(e===R)return jt(t,n);if(typeof e!="string"){const a={...n,...e,queries:void 0},h=e.queries.map(f=>ut(t,f,a));return ct(h,a.combineWith)}const{tokenize:o,processTerm:s,searchOptions:r}=t._options,i={tokenize:o,processTerm:s,...r,...n},{tokenize:c,processTerm:u}=i,d=c(e).flatMap(a=>u(a)).filter(a=>!!a).map(Ot(i)).map(a=>qt(t,a,i));return ct(d,i.combineWith)},dt=(t,e,n={})=>{const{searchOptions:o}=t._options,s={...o,...n},r=ut(t,e,n),i=[];for(const[c,{score:u,terms:d,match:a}]of r){const h=d.length||1,f={id:t._documentIds.get(c),score:u*h,terms:Object.keys(a),queryTerms:d,match:a};Object.assign(f,t._storedFields.get(c)),(s.filter==null||s.filter(f))&&i.push(f);}return e===R&&s.boostDocument==null||i.sort(et),i};class Nt{_options;_index;_documentCount;_documentIds;_idToShortId;_fieldIds;_fieldLength;_avgFieldLength;_nextId;_storedFields;_dirtCount;_currentVacuum;_enqueuedVacuum;_enqueuedVacuumConditions;constructor(e){if(!e?.fields)throw new Error('SlimSearch: option "fields" must be provided');const n=e.autoVacuum==null||e.autoVacuum===true?P:e.autoVacuum;this._options={...$,...e,autoVacuum:n,searchOptions:{...rt,...e.searchOptions},autoSuggestOptions:{...Et,...e.autoSuggestOptions}},this._index=new I,this._documentCount=0,this._documentIds=new Map,this._idToShortId=new Map,this._fieldIds={},this._fieldLength=new Map,this._avgFieldLength=[],this._nextId=0,this._storedFields=new Map,this._dirtCount=0,this._currentVacuum=null,this._enqueuedVacuum=null,this._enqueuedVacuumConditions=W,this.addFields(this._options.fields);}get isVacuuming(){return this._currentVacuum!=null}get dirtCount(){return this._dirtCount}get dirtFactor(){return this._dirtCount/(1+this._documentCount+this._dirtCount)}get documentCount(){return this._documentCount}get termCount(){return this._index.size}toJSON(){const e=[];for(const[n,o]of this._index){const s={};for(const[r,i]of o)s[r]=Object.fromEntries(i);e.push([n,s]);}return {documentCount:this._documentCount,nextId:this._nextId,documentIds:Object.fromEntries(this._documentIds),fieldIds:this._fieldIds,fieldLength:Object.fromEntries(this._fieldLength),averageFieldLength:this._avgFieldLength,storedFields:Object.fromEntries(this._storedFields),dirtCount:this._dirtCount,index:e,version:2}}addFields(e){for(let n=0;n<e.length;n++)this._fieldIds[e[n]]=n;}}const lt=t=>new Nt(t);
|
|
15646
|
+
const It="ENTRIES",U="KEYS",B="VALUES";class L{set;_type;_path;constructor(e,n){const o=e._tree,s=Array.from(o.keys());this.set=e,this._type=n,this._path=s.length>0?[{node:o,keys:s}]:[];}next(){const e=this.dive();return this.backtrack(),e}dive(){if(this._path.length===0)return {done:true,value:void 0};const{node:e,keys:n}=x(this._path);if(x(n)==="")return {done:false,value:this.result()};const o=e.get(x(n));return this._path.push({node:o,keys:Array.from(o.keys())}),this.dive()}backtrack(){if(this._path.length===0)return;const e=x(this._path).keys;e.pop(),!(e.length>0)&&(this._path.pop(),this.backtrack());}key(){return this.set._prefix+this._path.map(({keys:e})=>x(e)).filter(e=>e!=="").join("")}value(){return x(this._path).node.get("")}result(){switch(this._type){case B:return this.value();case U:return this.key();default:return [this.key(),this.value()]}}[Symbol.iterator](){return this}}const x=t=>t[t.length-1],xt=(t,e,n)=>{const o=new Map;if(typeof e!="string")return o;const s=e.length+1,r=s+n,i=new Uint8Array(r*s).fill(n+1);for(let c=0;c<s;++c)i[c]=c;for(let c=1;c<r;++c)i[c*s]=c;return G(t,e,n,o,i,1,s,""),o},G=(t,e,n,o,s,r,i,c)=>{const a=r*i;t:for(const d of t.keys())if(d===""){const u=s[a-1];u<=n&&o.set(c,[t.get(d),u]);}else {let u=r;for(let f=0;f<d.length;++f,++u){const m=d[f],_=i*u,g=_-i;let h=s[_];const l=Math.max(0,u-n-1),p=Math.min(i-1,u+n);for(let w=l;w<p;++w){const k=m!==e[w],C=s[g+w]+ +k,z=s[g+w+1]+1,I=s[_+w]+1,F=s[_+w+1]=Math.min(C,z,I);F<h&&(h=F);}if(h>n)continue t}G(t.get(d),e,n,o,s,u,i,c+d);}};class y{_tree;_prefix;_size=void 0;constructor(e=new Map,n=""){this._tree=e,this._prefix=n;}atPrefix(e){if(!e.startsWith(this._prefix))throw new Error("Mismatched prefix");const[n,o]=S(this._tree,e.slice(this._prefix.length));if(n===void 0){const[s,r]=A(o);for(const i of s.keys())if(i!==""&&i.startsWith(r)){const c=new Map;return c.set(i.slice(r.length),s.get(i)),new y(c,e)}}return new y(n,e)}clear(){this._size=void 0,this._tree.clear();}delete(e){return this._size=void 0,Ft(this._tree,e)}entries(){return new L(this,It)}forEach(e){for(const[n,o]of this)e(n,o,this);}fuzzyGet(e,n){return xt(this._tree,e,n)}get(e){const n=O(this._tree,e);return n!==void 0?n.get(""):void 0}has(e){return O(this._tree,e)?.has("")??false}keys(){return new L(this,U)}set(e,n){if(typeof e!="string")throw new Error("key must be a string");return this._size=void 0,E(this._tree,e).set("",n),this}get size(){if(this._size)return this._size;this._size=0;const e=this.entries();for(;!e.next().done;)this._size+=1;return this._size}update(e,n){if(typeof e!="string")throw new Error("key must be a string");this._size=void 0;const o=E(this._tree,e);return o.set("",n(o.get(""))),this}fetch(e,n){if(typeof e!="string")throw new Error("key must be a string");this._size=void 0;const o=E(this._tree,e);let s=o.get("");return s===void 0&&o.set("",s=n()),s}values(){return new L(this,B)}[Symbol.iterator](){return this.entries()}static from(e){const n=new y;for(const[o,s]of e)n.set(o,s);return n}static fromObject(e){return y.from(Object.entries(e))}}const S=(t,e,n=[])=>{if(e.length===0||t==null)return [t,n];for(const o of t.keys())if(o!==""&&e.startsWith(o))return n.push([t,o]),S(t.get(o),e.slice(o.length),n);return n.push([t,e]),S(void 0,"",n)},O=(t,e)=>{if(e.length===0||!t)return t;for(const n of t.keys())if(n!==""&&e.startsWith(n))return O(t.get(n),e.slice(n.length))},E=(t,e)=>{const n=e.length;t:for(let o=0;t&&o<n;){for(const r of t.keys())if(r!==""&&e[o]===r[0]){const i=Math.min(n-o,r.length);let c=1;for(;c<i&&e[o+c]===r[c];)++c;const a=t.get(r);if(c===r.length)t=a;else {const d=new Map;d.set(r.slice(c),a),t.set(e.slice(o,o+c),d),t.delete(r),t=d;}o+=c;continue t}const s=new Map;return t.set(e.slice(o),s),s}return t},Ft=(t,e)=>{const[n,o]=S(t,e);if(n!==void 0){if(n.delete(""),n.size===0)K(o);else if(n.size===1){const[s,r]=n.entries().next().value;Q(o,s,r);}}},K=t=>{if(t.length===0)return;const[e,n]=A(t);if(e.delete(n),e.size===0)K(t.slice(0,-1));else if(e.size===1){const[o,s]=e.entries().next().value;o!==""&&Q(t.slice(0,-1),o,s);}},Q=(t,e,n)=>{if(t.length===0)return;const[o,s]=A(t);o.set(s+e,n),o.delete(s);},A=t=>t[t.length-1],Y=(t,e)=>t._idToShortId.has(e),St=/[\n\r\p{Z}\p{P}]+/u,V="or",Z="and",bt="and_not",vt=(t,e)=>{t.includes(e)||t.push(e);},X=(t,e)=>{for(const n of e)t.includes(n)||t.push(n);},tt=({score:t},{score:e})=>e-t,et=()=>new Map,T=(t,e)=>Object.prototype.hasOwnProperty.call(t,e)?t[e]:void 0,nt={[V]:(t,e)=>{for(const n of e.keys()){const o=t.get(n);if(o==null)t.set(n,e.get(n));else {const{score:s,terms:r,match:i}=e.get(n);o.score=o.score+s,o.match=Object.assign(o.match,i),X(o.terms,r);}}return t},[Z]:(t,e)=>{const n=new Map;for(const o of e.keys()){const s=t.get(o);if(s==null)continue;const{score:r,terms:i,match:c}=e.get(o);X(s.terms,i),n.set(o,{score:s.score+r,terms:s.terms,match:Object.assign(s.match,c)});}return n},[bt]:(t,e)=>{for(const n of e.keys())t.delete(n);return t}},kt=(t,e,n,o,s,r)=>{const{k:i,b:c,d:a}=r;return Math.log(1+(n-e+.5)/(e+.5))*(a+t*(i+1)/(t+i*(1-c+c*o/s)))},Ct=t=>(e,n,o)=>({term:e,fuzzy:typeof t.fuzzy=="function"?t.fuzzy(e,n,o):t.fuzzy??false,prefix:typeof t.prefix=="function"?t.prefix(e,n,o):t.prefix===true,termBoost:typeof t.boostTerm=="function"?t.boostTerm(e,n,o):1}),ot=(t,e,n,o)=>{for(const s of Object.keys(t._fieldIds))if(t._fieldIds[s]===n){t._options.logger("warn",`SlimSearch: document with ID ${t._documentIds.get(e)} has changed before removal: term "${o}" was not present in field "${s}". Removing a document after it has changed can corrupt the index!`,"version_conflict");return}},st=(t,e,n,o)=>{const s=t._index.fetch(o,et);let r=s.get(e);if(r==null)r=new Map,r.set(n,1),s.set(e,r);else {const i=r.get(n);r.set(n,(i??0)+1);}},M=(t,e,n,o)=>{if(!t._index.has(o)){ot(t,n,e,o);return}const s=t._index.fetch(o,et),r=s.get(e),i=r?.get(n);!r||typeof i>"u"?ot(t,n,e,o):i<=1?r.size<=1?s.delete(e):r.delete(n):r.set(n,i-1),t._index.get(o).size===0&&t._index.delete(o);},Lt=(t,e,n,o,s)=>{let r=t._fieldLength.get(e);r==null&&t._fieldLength.set(e,r=[]),r[n]=s;const i=(t._avgFieldLength[n]||0)*o+s;t._avgFieldLength[n]=i/(o+1);},Ot=(t,e)=>{const n=t._nextId;return t._idToShortId.set(e,n),t._documentIds.set(n,e),t._documentCount+=1,t._nextId+=1,n},Et=(t,e,n)=>{const{storeFields:o,extractField:s}=t._options;if(o?.length===0)return;let r=t._storedFields.get(e);r===void 0&&t._storedFields.set(e,r={});for(const i of o){const c=s(n,i);c!=null&&(r[i]=c);}},D=(t,e)=>{const{extractField:n,stringifyField:o,tokenize:s,processTerm:r,fields:i,idField:c}=t._options,a=n(e,c);if(a==null)throw new Error(`SlimSearch: document does not have ID field "${c}"`);if(Y(t,a))throw new Error(`SlimSearch: duplicate ID ${a}`);const d=Ot(t,a);Et(t,d,e);for(const u of i){const f=n(e,u);if(f==null)continue;const m=s(o(f,u),u),_=t._fieldIds[u],g=new Set(m).size;Lt(t,d,_,t._documentCount-1,g);for(const h of m){const l=r(h,u);if(Array.isArray(l))for(const p of l)st(t,_,d,p);else l&&st(t,_,d,l);}}},j=(t,e)=>{for(const n of e)D(t,n);},Vt={k:1.2,b:.7,d:.5},q={idField:"id",extractField:(t,e)=>t[e],stringifyField:t=>t.toString(),tokenize:t=>t.split(St),processTerm:t=>t.toLowerCase(),fields:void 0,searchOptions:void 0,storeFields:[],logger:(t,e)=>{console?.[t]?.(e);},autoVacuum:true},it={combineWith:V,prefix:false,fuzzy:false,maxFuzzy:6,boost:{},weights:{fuzzy:.45,prefix:.375},bm25:Vt},Tt={combineWith:Z,prefix:(t,e,n)=>e===n.length-1},$={batchSize:1e3,batchWait:10},N={minDirtFactor:.1,minDirtCount:20},W={...$,...N},P=Symbol("*"),Dt=(t,e)=>{const n=new Map,o={...t._options.searchOptions,...e};for(const[s,r]of t._documentIds){const i=o.boostDocument?o.boostDocument(r,"",t._storedFields.get(s)):1;n.set(s,{score:i,terms:[],match:{}});}return n},rt=(t,e=V)=>{if(t.length===0)return new Map;const n=e.toLowerCase();if(!(n in nt))throw new Error(`Invalid combination operator: ${e}`);return t.reduce(nt[n])},R=(t,e,n,o,s,r,i,c,a,d=new Map)=>{if(r==null)return d;for(const u of Object.keys(i)){const f=i[u],m=t._fieldIds[u],_=r.get(m);if(_==null)continue;let g=_.size;const h=t._avgFieldLength[m];for(const l of _.keys()){if(!t._documentIds.has(l)){M(t,m,l,n),g-=1;continue}const p=c?c(t._documentIds.get(l),n,t._storedFields.get(l)):1;if(!p)continue;const w=_.get(l),k=t._fieldLength.get(l)[m],C=kt(w,g,t._documentCount,k,h,a),z=o*s*f*p*C,I=d.get(l);if(I){I.score+=z,vt(I.terms,e);const F=T(I.match,n);F?F.push(u):I.match[n]=[u];}else d.set(l,{score:z,terms:[e],match:{[n]:[u]}});}}return d},jt=(t,e,n)=>{const o={...t._options.searchOptions,...n},s=(o.fields??t._options.fields).reduce((h,l)=>({...h,[l]:T(o.boost,l)||1}),{}),{boostDocument:r,weights:i,maxFuzzy:c,bm25:a}=o,{fuzzy:d,prefix:u}={...it.weights,...i},f=t._index.get(e.term),m=R(t,e.term,e.term,1,e.termBoost,f,s,r,a);let _,g;if(e.prefix&&(_=t._index.atPrefix(e.term)),e.fuzzy){const h=e.fuzzy===true?.2:e.fuzzy,l=h<1?Math.min(c,Math.round(e.term.length*h)):h;l&&(g=t._index.fuzzyGet(e.term,l));}if(_)for(const[h,l]of _){const p=h.length-e.term.length;if(!p)continue;g?.delete(h);const w=u*h.length/(h.length+.3*p);R(t,e.term,h,w,e.termBoost,l,s,r,a,m);}if(g)for(const h of g.keys()){const[l,p]=g.get(h);if(!p)continue;const w=d*h.length/(h.length+p);R(t,e.term,h,w,e.termBoost,l,s,r,a,m);}return m},ct=(t,e,n={})=>{if(e===P)return Dt(t,n);if(typeof e!="string"){const u={...n,...e,queries:void 0},f=e.queries.map(m=>ct(t,m,u));return rt(f,u.combineWith)}const{tokenize:o,processTerm:s,searchOptions:r}=t._options,i={tokenize:o,processTerm:s,...r,...n},{tokenize:c,processTerm:a}=i,d=c(e).flatMap(u=>a(u)).filter(u=>!!u).map(Ct(i)).map(u=>jt(t,u,i));return rt(d,i.combineWith)},ut=(t,e,n={})=>{const{searchOptions:o}=t._options,s={...o,...n},r=ct(t,e,n),i=[];for(const[c,{score:a,terms:d,match:u}]of r){const f=d.length||1,m={id:t._documentIds.get(c),score:a*f,terms:Object.keys(u),queryTerms:d,match:u};Object.assign(m,t._storedFields.get(c)),(s.filter==null||s.filter(m))&&i.push(m);}return e===P&&s.boostDocument==null||i.sort(tt),i};class $t{_options;_index;_documentCount;_documentIds;_idToShortId;_fieldIds;_fieldLength;_avgFieldLength;_nextId;_storedFields;_dirtCount;_currentVacuum;_enqueuedVacuum;_enqueuedVacuumConditions;constructor(e){if(!e?.fields)throw new Error('SlimSearch: option "fields" must be provided');const n=e.autoVacuum==null||e.autoVacuum===true?W:e.autoVacuum;this._options={...q,...e,autoVacuum:n,searchOptions:{...it,...e.searchOptions},autoSuggestOptions:{...Tt,...e.autoSuggestOptions}},this._index=new y,this._documentCount=0,this._documentIds=new Map,this._idToShortId=new Map,this._fieldIds={},this._fieldLength=new Map,this._avgFieldLength=[],this._nextId=0,this._storedFields=new Map,this._dirtCount=0,this._currentVacuum=null,this._enqueuedVacuum=null,this._enqueuedVacuumConditions=N,this.addFields(this._options.fields);}get isVacuuming(){return this._currentVacuum!=null}get dirtCount(){return this._dirtCount}get dirtFactor(){return this._dirtCount/(1+this._documentCount+this._dirtCount)}get documentCount(){return this._documentCount}get termCount(){return this._index.size}toJSON(){const e=[];for(const[n,o]of this._index){const s={};for(const[r,i]of o)s[r]=Object.fromEntries(i);e.push([n,s]);}return {documentCount:this._documentCount,nextId:this._nextId,documentIds:Object.fromEntries(this._documentIds),fieldIds:this._fieldIds,fieldLength:Object.fromEntries(this._fieldLength),averageFieldLength:this._avgFieldLength,storedFields:Object.fromEntries(this._storedFields),dirtCount:this._dirtCount,index:e,version:2}}addFields(e){for(let n=0;n<e.length;n++)this._fieldIds[e[n]]=n;}}const at=t=>new $t(t);
|
|
15647
15647
|
|
|
15648
15648
|
/**
|
|
15649
15649
|
* Generates a list of accent variants for a given term.
|
|
@@ -15685,7 +15685,7 @@ const generateAccentVariants = (term) => {
|
|
|
15685
15685
|
|
|
15686
15686
|
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
|
15687
15687
|
// versions:
|
|
15688
|
-
// protoc-gen-ts_proto v2.
|
|
15688
|
+
// protoc-gen-ts_proto v2.10.1
|
|
15689
15689
|
// protoc v4.23.4
|
|
15690
15690
|
// source: src/stops/proto/stops.proto
|
|
15691
15691
|
/* eslint-disable */
|
|
@@ -16061,7 +16061,7 @@ const serializeLocationType = (locationType) => {
|
|
|
16061
16061
|
};
|
|
16062
16062
|
|
|
16063
16063
|
/**
|
|
16064
|
-
* The
|
|
16064
|
+
* The StopsIndex class provides functionality to search for public transport stops
|
|
16065
16065
|
* by name or geographic location. It leverages text search and geospatial indexing
|
|
16066
16066
|
* to efficiently find stops based on user queries.
|
|
16067
16067
|
*/
|
|
@@ -16092,14 +16092,14 @@ class StopsIndex {
|
|
|
16092
16092
|
});
|
|
16093
16093
|
}
|
|
16094
16094
|
}
|
|
16095
|
-
this.textIndex =
|
|
16095
|
+
this.textIndex = at({
|
|
16096
16096
|
fields: ['name'],
|
|
16097
16097
|
storeFields: ['id'],
|
|
16098
16098
|
searchOptions: { prefix: true, fuzzy: 0.2 },
|
|
16099
16099
|
processTerm: generateAccentVariants,
|
|
16100
16100
|
});
|
|
16101
16101
|
const stopsArray = Array.from(stopsSet.values());
|
|
16102
|
-
|
|
16102
|
+
j(this.textIndex, stopsArray);
|
|
16103
16103
|
this.geoIndex = new KDBush(this.stopPoints.length);
|
|
16104
16104
|
for (let i = 0; i < this.stopPoints.length; i++) {
|
|
16105
16105
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
@@ -16146,7 +16146,7 @@ class StopsIndex {
|
|
|
16146
16146
|
* @returns An array of Stop objects that match the search query.
|
|
16147
16147
|
*/
|
|
16148
16148
|
findStopsByName(query, maxResults = 5) {
|
|
16149
|
-
const results =
|
|
16149
|
+
const results = ut(this.textIndex, query).map((result) => this.stops[result.id]);
|
|
16150
16150
|
return results.slice(0, maxResults);
|
|
16151
16151
|
}
|
|
16152
16152
|
/**
|
|
@@ -16205,6 +16205,16 @@ class StopsIndex {
|
|
|
16205
16205
|
: stop.children;
|
|
16206
16206
|
return Array.from(new Set([id, ...equivalentStops])).map((stopId) => this.stops[stopId]);
|
|
16207
16207
|
}
|
|
16208
|
+
/**
|
|
16209
|
+
* Makes the StopsIndex iterable, allowing iteration over all stops.
|
|
16210
|
+
*
|
|
16211
|
+
* @returns An iterator for the stops.
|
|
16212
|
+
*/
|
|
16213
|
+
*[Symbol.iterator]() {
|
|
16214
|
+
for (const stop of this.stops) {
|
|
16215
|
+
yield stop;
|
|
16216
|
+
}
|
|
16217
|
+
}
|
|
16208
16218
|
}
|
|
16209
16219
|
|
|
16210
16220
|
class Duration {
|
|
@@ -16290,7 +16300,7 @@ class Duration {
|
|
|
16290
16300
|
|
|
16291
16301
|
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
|
16292
16302
|
// versions:
|
|
16293
|
-
// protoc-gen-ts_proto v2.
|
|
16303
|
+
// protoc-gen-ts_proto v2.10.1
|
|
16294
16304
|
// protoc v4.23.4
|
|
16295
16305
|
// source: src/timetable/proto/timetable.proto
|
|
16296
16306
|
/* eslint-disable */
|
|
@@ -21453,6 +21463,26 @@ class Result {
|
|
|
21453
21463
|
this.stopsIndex = stopsIndex;
|
|
21454
21464
|
this.timetable = timetable;
|
|
21455
21465
|
}
|
|
21466
|
+
/**
|
|
21467
|
+
* Reconstructs the best route to a stop by StopId.
|
|
21468
|
+
* (to any stop reachable in less time / transfers than the destination(s) of the query)
|
|
21469
|
+
*
|
|
21470
|
+
* @param to The destination stop by StopId.
|
|
21471
|
+
* @returns a route to the destination stop if it exists.
|
|
21472
|
+
*/
|
|
21473
|
+
bestRouteToStopId(to) {
|
|
21474
|
+
var _a;
|
|
21475
|
+
const sourceStopIds = to instanceof Set
|
|
21476
|
+
? new Set(Array.from(to)
|
|
21477
|
+
.map((stopId) => { var _a; return (_a = this.stopsIndex.findStopById(stopId)) === null || _a === void 0 ? void 0 : _a.sourceStopId; })
|
|
21478
|
+
.filter((sourceId) => sourceId !== undefined))
|
|
21479
|
+
: (_a = this.stopsIndex.findStopById(to)) === null || _a === void 0 ? void 0 : _a.sourceStopId;
|
|
21480
|
+
if (sourceStopIds === undefined ||
|
|
21481
|
+
(sourceStopIds instanceof Set && sourceStopIds.size === 0)) {
|
|
21482
|
+
return undefined;
|
|
21483
|
+
}
|
|
21484
|
+
return this.bestRoute(sourceStopIds);
|
|
21485
|
+
}
|
|
21456
21486
|
/**
|
|
21457
21487
|
* Reconstructs the best route to a stop.
|
|
21458
21488
|
* (to any stop reachable in less time / transfers than the destination(s) of the query)
|
|
@@ -21467,17 +21497,19 @@ class Result {
|
|
|
21467
21497
|
: to
|
|
21468
21498
|
? [to]
|
|
21469
21499
|
: Array.from(this.query.to);
|
|
21470
|
-
const destinations = destinationList.flatMap((destination) => this.stopsIndex.equivalentStops(destination));
|
|
21471
21500
|
// find the first reached destination
|
|
21472
21501
|
let fastestDestination = undefined;
|
|
21473
21502
|
let fastestTime = undefined;
|
|
21474
|
-
for (const
|
|
21475
|
-
const
|
|
21476
|
-
|
|
21477
|
-
|
|
21478
|
-
|
|
21479
|
-
|
|
21480
|
-
|
|
21503
|
+
for (const sourceDestination of destinationList) {
|
|
21504
|
+
const equivalentStops = this.stopsIndex.equivalentStops(sourceDestination);
|
|
21505
|
+
for (const destination of equivalentStops) {
|
|
21506
|
+
const arrivalTime = this.routingState.earliestArrivals.get(destination.id);
|
|
21507
|
+
if (arrivalTime !== undefined) {
|
|
21508
|
+
if (fastestTime === undefined ||
|
|
21509
|
+
arrivalTime.arrival.isBefore(fastestTime.arrival)) {
|
|
21510
|
+
fastestDestination = destination.id;
|
|
21511
|
+
fastestTime = arrivalTime;
|
|
21512
|
+
}
|
|
21481
21513
|
}
|
|
21482
21514
|
}
|
|
21483
21515
|
}
|