keepset 0.24.0 → 0.26.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/dist/{bundled-BWINQKLQ.js → bundled-V1EJ0k9e.js} +370 -22
- package/dist/{categories-BfqmrAvf.d.ts → categories-HeWbVPhc.d.ts} +117 -18
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/node/fetch-dataset.d.ts +1 -1
- package/dist/node/fetch-dataset.js +372 -25
- package/dist-cli/keepset.mjs +1 -1
- package/package.json +1 -1
- package/schemas/entry.schema.json +1 -1
- package/schemas/manifest.schema.json +1 -1
|
@@ -521,6 +521,18 @@ const ParserSchema = z.discriminatedUnion("format", [
|
|
|
521
521
|
format: z.literal("solomon"),
|
|
522
522
|
encoding: EncodingSchema
|
|
523
523
|
}).strict(),
|
|
524
|
+
z.object({
|
|
525
|
+
format: z.literal("top"),
|
|
526
|
+
encoding: EncodingSchema
|
|
527
|
+
}).strict(),
|
|
528
|
+
z.object({
|
|
529
|
+
format: z.literal("toptw"),
|
|
530
|
+
encoding: EncodingSchema
|
|
531
|
+
}).strict(),
|
|
532
|
+
z.object({
|
|
533
|
+
format: z.literal("tsplib"),
|
|
534
|
+
encoding: EncodingSchema
|
|
535
|
+
}).strict(),
|
|
524
536
|
z.object({
|
|
525
537
|
format: z.literal("csv-table"),
|
|
526
538
|
encoding: EncodingSchema,
|
|
@@ -980,7 +992,7 @@ var catalogue_default = {
|
|
|
980
992
|
"id": "keepset",
|
|
981
993
|
"name": "keepset",
|
|
982
994
|
"description": "The keepset catalogue: datasets with machine-readable recipes that fetch each one and normalise it into its category's target shape.",
|
|
983
|
-
"version": "1.
|
|
995
|
+
"version": "1.14.0",
|
|
984
996
|
"repository": "https://github.com/Mearman/keepset",
|
|
985
997
|
"namespaceAliases": {
|
|
986
998
|
"networkrepository": ["nr"],
|
|
@@ -8635,7 +8647,7 @@ var catalogue_default = {
|
|
|
8635
8647
|
"location",
|
|
8636
8648
|
"travelTime"
|
|
8637
8649
|
],
|
|
8638
|
-
"category": "or/v1",
|
|
8650
|
+
"category": "or-set/v1",
|
|
8639
8651
|
"sources": [{
|
|
8640
8652
|
"url": "https://www.mech.kuleuven.be/en/mim/op",
|
|
8641
8653
|
"retrieved": "2026-10-19",
|
|
@@ -8648,11 +8660,75 @@ var catalogue_default = {
|
|
|
8648
8660
|
"licence": { "kind": "unrecorded" },
|
|
8649
8661
|
"citations": [],
|
|
8650
8662
|
"recipe": {
|
|
8651
|
-
"status": "
|
|
8652
|
-
"
|
|
8663
|
+
"status": "fetchable",
|
|
8664
|
+
"source": 1,
|
|
8665
|
+
"archive": {
|
|
8666
|
+
"kind": "zip",
|
|
8667
|
+
"members": { "extensions": [".txt"] }
|
|
8668
|
+
},
|
|
8669
|
+
"parser": {
|
|
8670
|
+
"format": "top",
|
|
8671
|
+
"encoding": "utf-8"
|
|
8672
|
+
}
|
|
8653
8673
|
},
|
|
8654
|
-
"crosswalk": {
|
|
8655
|
-
|
|
8674
|
+
"crosswalk": {
|
|
8675
|
+
"source": "top",
|
|
8676
|
+
"target": "or-set/v1",
|
|
8677
|
+
"rules": [
|
|
8678
|
+
{
|
|
8679
|
+
"op": "move",
|
|
8680
|
+
"from": "meta",
|
|
8681
|
+
"to": "meta"
|
|
8682
|
+
},
|
|
8683
|
+
{
|
|
8684
|
+
"op": "move",
|
|
8685
|
+
"from": "members[].id",
|
|
8686
|
+
"to": "instances[].id"
|
|
8687
|
+
},
|
|
8688
|
+
{
|
|
8689
|
+
"op": "move",
|
|
8690
|
+
"from": "members[].meta.points",
|
|
8691
|
+
"to": "instances[].meta.points"
|
|
8692
|
+
},
|
|
8693
|
+
{
|
|
8694
|
+
"op": "move",
|
|
8695
|
+
"from": "members[].meta.paths",
|
|
8696
|
+
"to": "instances[].meta.paths"
|
|
8697
|
+
},
|
|
8698
|
+
{
|
|
8699
|
+
"op": "move",
|
|
8700
|
+
"from": "members[].meta.budget",
|
|
8701
|
+
"to": "instances[].meta.budget"
|
|
8702
|
+
},
|
|
8703
|
+
{
|
|
8704
|
+
"op": "move",
|
|
8705
|
+
"from": "members[].nodes[].id",
|
|
8706
|
+
"to": "instances[].nodes[].id"
|
|
8707
|
+
},
|
|
8708
|
+
{
|
|
8709
|
+
"op": "move",
|
|
8710
|
+
"from": "members[].nodes[].score",
|
|
8711
|
+
"to": "instances[].nodes[].prize"
|
|
8712
|
+
},
|
|
8713
|
+
{
|
|
8714
|
+
"op": "move",
|
|
8715
|
+
"from": "members[].nodes[].x",
|
|
8716
|
+
"to": "instances[].nodes[].x"
|
|
8717
|
+
},
|
|
8718
|
+
{
|
|
8719
|
+
"op": "move",
|
|
8720
|
+
"from": "members[].nodes[].y",
|
|
8721
|
+
"to": "instances[].nodes[].y"
|
|
8722
|
+
},
|
|
8723
|
+
{
|
|
8724
|
+
"op": "move",
|
|
8725
|
+
"from": "members[].nodes[].role",
|
|
8726
|
+
"to": "instances[].nodes[].role"
|
|
8727
|
+
}
|
|
8728
|
+
],
|
|
8729
|
+
"oneWay": []
|
|
8730
|
+
},
|
|
8731
|
+
"expectedCounts": { "instances": 60 },
|
|
8656
8732
|
"properties": { "surveyId": "or-0" }
|
|
8657
8733
|
},
|
|
8658
8734
|
{
|
|
@@ -8669,7 +8745,7 @@ var catalogue_default = {
|
|
|
8669
8745
|
"duration",
|
|
8670
8746
|
"travelTime"
|
|
8671
8747
|
],
|
|
8672
|
-
"category": "or/v1",
|
|
8748
|
+
"category": "or-set/v1",
|
|
8673
8749
|
"sources": [{
|
|
8674
8750
|
"url": "https://www.mech.kuleuven.be/en/mim/op",
|
|
8675
8751
|
"retrieved": "2026-10-19",
|
|
@@ -8682,12 +8758,89 @@ var catalogue_default = {
|
|
|
8682
8758
|
"licence": { "kind": "unrecorded" },
|
|
8683
8759
|
"citations": [],
|
|
8684
8760
|
"recipe": {
|
|
8685
|
-
"status": "
|
|
8686
|
-
"
|
|
8761
|
+
"status": "fetchable",
|
|
8762
|
+
"source": 1,
|
|
8763
|
+
"archive": {
|
|
8764
|
+
"kind": "zip",
|
|
8765
|
+
"members": { "extensions": [".txt"] }
|
|
8766
|
+
},
|
|
8767
|
+
"parser": {
|
|
8768
|
+
"format": "toptw",
|
|
8769
|
+
"encoding": "utf-8"
|
|
8770
|
+
}
|
|
8687
8771
|
},
|
|
8688
|
-
"crosswalk": {
|
|
8689
|
-
|
|
8690
|
-
|
|
8772
|
+
"crosswalk": {
|
|
8773
|
+
"source": "toptw",
|
|
8774
|
+
"target": "or-set/v1",
|
|
8775
|
+
"rules": [
|
|
8776
|
+
{
|
|
8777
|
+
"op": "move",
|
|
8778
|
+
"from": "meta",
|
|
8779
|
+
"to": "meta"
|
|
8780
|
+
},
|
|
8781
|
+
{
|
|
8782
|
+
"op": "move",
|
|
8783
|
+
"from": "members[].id",
|
|
8784
|
+
"to": "instances[].id"
|
|
8785
|
+
},
|
|
8786
|
+
{
|
|
8787
|
+
"op": "move",
|
|
8788
|
+
"from": "members[].meta.paths",
|
|
8789
|
+
"to": "instances[].meta.paths"
|
|
8790
|
+
},
|
|
8791
|
+
{
|
|
8792
|
+
"op": "move",
|
|
8793
|
+
"from": "members[].meta.customers",
|
|
8794
|
+
"to": "instances[].meta.customers"
|
|
8795
|
+
},
|
|
8796
|
+
{
|
|
8797
|
+
"op": "move",
|
|
8798
|
+
"from": "members[].meta.capacity",
|
|
8799
|
+
"to": "instances[].meta.capacity"
|
|
8800
|
+
},
|
|
8801
|
+
{
|
|
8802
|
+
"op": "move",
|
|
8803
|
+
"from": "members[].nodes[].id",
|
|
8804
|
+
"to": "instances[].nodes[].id"
|
|
8805
|
+
},
|
|
8806
|
+
{
|
|
8807
|
+
"op": "move",
|
|
8808
|
+
"from": "members[].nodes[].close",
|
|
8809
|
+
"to": "instances[].nodes[].deadline"
|
|
8810
|
+
},
|
|
8811
|
+
{
|
|
8812
|
+
"op": "move",
|
|
8813
|
+
"from": "members[].nodes[].profit",
|
|
8814
|
+
"to": "instances[].nodes[].prize"
|
|
8815
|
+
},
|
|
8816
|
+
{
|
|
8817
|
+
"op": "move",
|
|
8818
|
+
"from": "members[].nodes[].x",
|
|
8819
|
+
"to": "instances[].nodes[].x"
|
|
8820
|
+
},
|
|
8821
|
+
{
|
|
8822
|
+
"op": "move",
|
|
8823
|
+
"from": "members[].nodes[].y",
|
|
8824
|
+
"to": "instances[].nodes[].y"
|
|
8825
|
+
},
|
|
8826
|
+
{
|
|
8827
|
+
"op": "move",
|
|
8828
|
+
"from": "members[].nodes[].service",
|
|
8829
|
+
"to": "instances[].nodes[].service"
|
|
8830
|
+
},
|
|
8831
|
+
{
|
|
8832
|
+
"op": "move",
|
|
8833
|
+
"from": "members[].nodes[].open",
|
|
8834
|
+
"to": "instances[].nodes[].open"
|
|
8835
|
+
}
|
|
8836
|
+
],
|
|
8837
|
+
"oneWay": []
|
|
8838
|
+
},
|
|
8839
|
+
"expectedCounts": { "instances": 29 },
|
|
8840
|
+
"properties": {
|
|
8841
|
+
"surveyId": "or-1",
|
|
8842
|
+
"timeUnit": "abstract units"
|
|
8843
|
+
}
|
|
8691
8844
|
},
|
|
8692
8845
|
{
|
|
8693
8846
|
"id": "lastfm-hgb",
|
|
@@ -56160,20 +56313,119 @@ var catalogue_default = {
|
|
|
56160
56313
|
"territory",
|
|
56161
56314
|
"travelTime"
|
|
56162
56315
|
],
|
|
56163
|
-
"category": "or/v1",
|
|
56316
|
+
"category": "or-set/v1",
|
|
56164
56317
|
"sources": [{
|
|
56165
56318
|
"url": "http://www.vrp-rep.org/datasets/download/angelelli-et-al-2014.zip",
|
|
56166
56319
|
"retrieved": "2026-10-19",
|
|
56167
56320
|
"status": "live"
|
|
56321
|
+
}, {
|
|
56322
|
+
"url": "https://www.vrp-rep.org/datasets/download/angelelli-et-al-2014.zip",
|
|
56323
|
+
"retrieved": "2026-10-19",
|
|
56324
|
+
"status": "live"
|
|
56168
56325
|
}],
|
|
56169
56326
|
"licence": { "kind": "unrecorded" },
|
|
56170
56327
|
"citations": [],
|
|
56171
56328
|
"recipe": {
|
|
56172
|
-
"status": "
|
|
56173
|
-
"
|
|
56329
|
+
"status": "fetchable",
|
|
56330
|
+
"source": 1,
|
|
56331
|
+
"archive": {
|
|
56332
|
+
"kind": "zip",
|
|
56333
|
+
"members": { "extensions": [".cop"] }
|
|
56334
|
+
},
|
|
56335
|
+
"parser": {
|
|
56336
|
+
"format": "tsplib",
|
|
56337
|
+
"encoding": "utf-8"
|
|
56338
|
+
}
|
|
56174
56339
|
},
|
|
56175
|
-
"crosswalk": {
|
|
56176
|
-
|
|
56340
|
+
"crosswalk": {
|
|
56341
|
+
"source": "tsplib",
|
|
56342
|
+
"target": "or-set/v1",
|
|
56343
|
+
"rules": [
|
|
56344
|
+
{
|
|
56345
|
+
"op": "move",
|
|
56346
|
+
"from": "meta",
|
|
56347
|
+
"to": "meta"
|
|
56348
|
+
},
|
|
56349
|
+
{
|
|
56350
|
+
"op": "move",
|
|
56351
|
+
"from": "members[].id",
|
|
56352
|
+
"to": "instances[].id"
|
|
56353
|
+
},
|
|
56354
|
+
{
|
|
56355
|
+
"op": "move",
|
|
56356
|
+
"from": "members[].meta.name",
|
|
56357
|
+
"to": "instances[].meta.name"
|
|
56358
|
+
},
|
|
56359
|
+
{
|
|
56360
|
+
"op": "move",
|
|
56361
|
+
"from": "members[].meta.type",
|
|
56362
|
+
"to": "instances[].meta.type"
|
|
56363
|
+
},
|
|
56364
|
+
{
|
|
56365
|
+
"op": "move",
|
|
56366
|
+
"from": "members[].meta.budget",
|
|
56367
|
+
"to": "instances[].meta.budget"
|
|
56368
|
+
},
|
|
56369
|
+
{
|
|
56370
|
+
"op": "move",
|
|
56371
|
+
"from": "members[].meta.edgeWeightType",
|
|
56372
|
+
"to": "instances[].meta.edgeWeightType"
|
|
56373
|
+
},
|
|
56374
|
+
{
|
|
56375
|
+
"op": "move",
|
|
56376
|
+
"from": "members[].meta.setPrizes",
|
|
56377
|
+
"to": "instances[].meta.setPrizes"
|
|
56378
|
+
},
|
|
56379
|
+
{
|
|
56380
|
+
"op": "move",
|
|
56381
|
+
"from": "members[].nodes[].id",
|
|
56382
|
+
"to": "instances[].nodes[].id"
|
|
56383
|
+
},
|
|
56384
|
+
{
|
|
56385
|
+
"op": "move",
|
|
56386
|
+
"from": "members[].nodes[].lat",
|
|
56387
|
+
"to": "instances[].nodes[].lat"
|
|
56388
|
+
},
|
|
56389
|
+
{
|
|
56390
|
+
"op": "move",
|
|
56391
|
+
"from": "members[].nodes[].lon",
|
|
56392
|
+
"to": "instances[].nodes[].lon"
|
|
56393
|
+
},
|
|
56394
|
+
{
|
|
56395
|
+
"op": "move",
|
|
56396
|
+
"from": "members[].nodes[].x",
|
|
56397
|
+
"to": "instances[].nodes[].x"
|
|
56398
|
+
},
|
|
56399
|
+
{
|
|
56400
|
+
"op": "move",
|
|
56401
|
+
"from": "members[].nodes[].y",
|
|
56402
|
+
"to": "instances[].nodes[].y"
|
|
56403
|
+
},
|
|
56404
|
+
{
|
|
56405
|
+
"op": "move",
|
|
56406
|
+
"from": "members[].nodes[].clusters",
|
|
56407
|
+
"to": "instances[].nodes[].clusters"
|
|
56408
|
+
}
|
|
56409
|
+
],
|
|
56410
|
+
"oneWay": [
|
|
56411
|
+
{
|
|
56412
|
+
"op": "drop",
|
|
56413
|
+
"from": "members[].meta.totalPrize",
|
|
56414
|
+
"direction": "encode"
|
|
56415
|
+
},
|
|
56416
|
+
{
|
|
56417
|
+
"op": "drop",
|
|
56418
|
+
"from": "members[].nodes[].prize",
|
|
56419
|
+
"direction": "encode"
|
|
56420
|
+
},
|
|
56421
|
+
{
|
|
56422
|
+
"op": "drop",
|
|
56423
|
+
"from": "members[].nodes[].probability",
|
|
56424
|
+
"direction": "encode"
|
|
56425
|
+
}
|
|
56426
|
+
]
|
|
56427
|
+
},
|
|
56428
|
+
"expectedCounts": { "instances": 924 },
|
|
56177
56429
|
"properties": { "surveyId": "or-4" }
|
|
56178
56430
|
},
|
|
56179
56431
|
{
|
|
@@ -56216,20 +56468,116 @@ var catalogue_default = {
|
|
|
56216
56468
|
"location",
|
|
56217
56469
|
"travelTime"
|
|
56218
56470
|
],
|
|
56219
|
-
"category": "or/v1",
|
|
56471
|
+
"category": "or-set/v1",
|
|
56220
56472
|
"sources": [{
|
|
56221
56473
|
"url": "http://www.vrp-rep.org/datasets/download/angelelli-et-al-2017.zip",
|
|
56222
56474
|
"retrieved": "2026-10-19",
|
|
56223
56475
|
"status": "live"
|
|
56476
|
+
}, {
|
|
56477
|
+
"url": "https://www.vrp-rep.org/datasets/download/angelelli-et-al-2017.zip",
|
|
56478
|
+
"retrieved": "2026-10-19",
|
|
56479
|
+
"status": "live"
|
|
56224
56480
|
}],
|
|
56225
56481
|
"licence": { "kind": "unrecorded" },
|
|
56226
56482
|
"citations": [],
|
|
56227
56483
|
"recipe": {
|
|
56228
|
-
"status": "
|
|
56229
|
-
"
|
|
56484
|
+
"status": "fetchable",
|
|
56485
|
+
"source": 1,
|
|
56486
|
+
"archive": {
|
|
56487
|
+
"kind": "zip",
|
|
56488
|
+
"members": { "extensions": [".pop"] }
|
|
56489
|
+
},
|
|
56490
|
+
"parser": {
|
|
56491
|
+
"format": "tsplib",
|
|
56492
|
+
"encoding": "utf-8"
|
|
56493
|
+
}
|
|
56230
56494
|
},
|
|
56231
|
-
"crosswalk": {
|
|
56232
|
-
|
|
56495
|
+
"crosswalk": {
|
|
56496
|
+
"source": "tsplib",
|
|
56497
|
+
"target": "or-set/v1",
|
|
56498
|
+
"rules": [
|
|
56499
|
+
{
|
|
56500
|
+
"op": "move",
|
|
56501
|
+
"from": "meta",
|
|
56502
|
+
"to": "meta"
|
|
56503
|
+
},
|
|
56504
|
+
{
|
|
56505
|
+
"op": "move",
|
|
56506
|
+
"from": "members[].id",
|
|
56507
|
+
"to": "instances[].id"
|
|
56508
|
+
},
|
|
56509
|
+
{
|
|
56510
|
+
"op": "move",
|
|
56511
|
+
"from": "members[].meta.name",
|
|
56512
|
+
"to": "instances[].meta.name"
|
|
56513
|
+
},
|
|
56514
|
+
{
|
|
56515
|
+
"op": "move",
|
|
56516
|
+
"from": "members[].meta.type",
|
|
56517
|
+
"to": "instances[].meta.type"
|
|
56518
|
+
},
|
|
56519
|
+
{
|
|
56520
|
+
"op": "move",
|
|
56521
|
+
"from": "members[].meta.budget",
|
|
56522
|
+
"to": "instances[].meta.budget"
|
|
56523
|
+
},
|
|
56524
|
+
{
|
|
56525
|
+
"op": "move",
|
|
56526
|
+
"from": "members[].meta.edgeWeightType",
|
|
56527
|
+
"to": "instances[].meta.edgeWeightType"
|
|
56528
|
+
},
|
|
56529
|
+
{
|
|
56530
|
+
"op": "move",
|
|
56531
|
+
"from": "members[].meta.totalPrize",
|
|
56532
|
+
"to": "instances[].meta.totalPrize"
|
|
56533
|
+
},
|
|
56534
|
+
{
|
|
56535
|
+
"op": "move",
|
|
56536
|
+
"from": "members[].nodes[].id",
|
|
56537
|
+
"to": "instances[].nodes[].id"
|
|
56538
|
+
},
|
|
56539
|
+
{
|
|
56540
|
+
"op": "move",
|
|
56541
|
+
"from": "members[].nodes[].lat",
|
|
56542
|
+
"to": "instances[].nodes[].lat"
|
|
56543
|
+
},
|
|
56544
|
+
{
|
|
56545
|
+
"op": "move",
|
|
56546
|
+
"from": "members[].nodes[].lon",
|
|
56547
|
+
"to": "instances[].nodes[].lon"
|
|
56548
|
+
},
|
|
56549
|
+
{
|
|
56550
|
+
"op": "move",
|
|
56551
|
+
"from": "members[].nodes[].prize",
|
|
56552
|
+
"to": "instances[].nodes[].prize"
|
|
56553
|
+
},
|
|
56554
|
+
{
|
|
56555
|
+
"op": "move",
|
|
56556
|
+
"from": "members[].nodes[].probability",
|
|
56557
|
+
"to": "instances[].nodes[].prizeProbability"
|
|
56558
|
+
},
|
|
56559
|
+
{
|
|
56560
|
+
"op": "move",
|
|
56561
|
+
"from": "members[].nodes[].x",
|
|
56562
|
+
"to": "instances[].nodes[].x"
|
|
56563
|
+
},
|
|
56564
|
+
{
|
|
56565
|
+
"op": "move",
|
|
56566
|
+
"from": "members[].nodes[].y",
|
|
56567
|
+
"to": "instances[].nodes[].y"
|
|
56568
|
+
}
|
|
56569
|
+
],
|
|
56570
|
+
"oneWay": [{
|
|
56571
|
+
"op": "drop",
|
|
56572
|
+
"from": "members[].meta.setPrizes",
|
|
56573
|
+
"direction": "encode"
|
|
56574
|
+
}, {
|
|
56575
|
+
"op": "drop",
|
|
56576
|
+
"from": "members[].nodes[].clusters",
|
|
56577
|
+
"direction": "encode"
|
|
56578
|
+
}]
|
|
56579
|
+
},
|
|
56580
|
+
"expectedCounts": { "instances": 264 },
|
|
56233
56581
|
"properties": { "surveyId": "or-3" }
|
|
56234
56582
|
},
|
|
56235
56583
|
{
|
|
@@ -146,6 +146,24 @@ declare const ParserSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
146
146
|
"utf-8": "utf-8";
|
|
147
147
|
latin1: "latin1";
|
|
148
148
|
}>;
|
|
149
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
150
|
+
format: z.ZodLiteral<"top">;
|
|
151
|
+
encoding: z.ZodEnum<{
|
|
152
|
+
"utf-8": "utf-8";
|
|
153
|
+
latin1: "latin1";
|
|
154
|
+
}>;
|
|
155
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
156
|
+
format: z.ZodLiteral<"toptw">;
|
|
157
|
+
encoding: z.ZodEnum<{
|
|
158
|
+
"utf-8": "utf-8";
|
|
159
|
+
latin1: "latin1";
|
|
160
|
+
}>;
|
|
161
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
162
|
+
format: z.ZodLiteral<"tsplib">;
|
|
163
|
+
encoding: z.ZodEnum<{
|
|
164
|
+
"utf-8": "utf-8";
|
|
165
|
+
latin1: "latin1";
|
|
166
|
+
}>;
|
|
149
167
|
}, z.core.$strict>, z.ZodObject<{
|
|
150
168
|
format: z.ZodLiteral<"csv-table">;
|
|
151
169
|
encoding: z.ZodEnum<{
|
|
@@ -265,6 +283,24 @@ declare const RecipeSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
265
283
|
"utf-8": "utf-8";
|
|
266
284
|
latin1: "latin1";
|
|
267
285
|
}>;
|
|
286
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
287
|
+
format: z.ZodLiteral<"top">;
|
|
288
|
+
encoding: z.ZodEnum<{
|
|
289
|
+
"utf-8": "utf-8";
|
|
290
|
+
latin1: "latin1";
|
|
291
|
+
}>;
|
|
292
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
293
|
+
format: z.ZodLiteral<"toptw">;
|
|
294
|
+
encoding: z.ZodEnum<{
|
|
295
|
+
"utf-8": "utf-8";
|
|
296
|
+
latin1: "latin1";
|
|
297
|
+
}>;
|
|
298
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
299
|
+
format: z.ZodLiteral<"tsplib">;
|
|
300
|
+
encoding: z.ZodEnum<{
|
|
301
|
+
"utf-8": "utf-8";
|
|
302
|
+
latin1: "latin1";
|
|
303
|
+
}>;
|
|
268
304
|
}, z.core.$strict>, z.ZodObject<{
|
|
269
305
|
format: z.ZodLiteral<"csv-table">;
|
|
270
306
|
encoding: z.ZodEnum<{
|
|
@@ -439,6 +475,24 @@ declare const EntrySchema: z.ZodObject<{
|
|
|
439
475
|
"utf-8": "utf-8";
|
|
440
476
|
latin1: "latin1";
|
|
441
477
|
}>;
|
|
478
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
479
|
+
format: z.ZodLiteral<"top">;
|
|
480
|
+
encoding: z.ZodEnum<{
|
|
481
|
+
"utf-8": "utf-8";
|
|
482
|
+
latin1: "latin1";
|
|
483
|
+
}>;
|
|
484
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
485
|
+
format: z.ZodLiteral<"toptw">;
|
|
486
|
+
encoding: z.ZodEnum<{
|
|
487
|
+
"utf-8": "utf-8";
|
|
488
|
+
latin1: "latin1";
|
|
489
|
+
}>;
|
|
490
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
491
|
+
format: z.ZodLiteral<"tsplib">;
|
|
492
|
+
encoding: z.ZodEnum<{
|
|
493
|
+
"utf-8": "utf-8";
|
|
494
|
+
latin1: "latin1";
|
|
495
|
+
}>;
|
|
442
496
|
}, z.core.$strict>, z.ZodObject<{
|
|
443
497
|
format: z.ZodLiteral<"csv-table">;
|
|
444
498
|
encoding: z.ZodEnum<{
|
|
@@ -514,19 +568,19 @@ declare const EntrySchema: z.ZodObject<{
|
|
|
514
568
|
status: "fetchable";
|
|
515
569
|
source: number;
|
|
516
570
|
archive: {
|
|
517
|
-
kind: "none";
|
|
518
|
-
} | {
|
|
519
|
-
kind: "gzip";
|
|
520
|
-
} | {
|
|
521
571
|
kind: "zip" | "tar" | "tar.gz";
|
|
522
|
-
|
|
572
|
+
members: {
|
|
523
573
|
path: string;
|
|
524
574
|
} | {
|
|
525
575
|
extensions: string[];
|
|
526
576
|
};
|
|
577
|
+
} | {
|
|
578
|
+
kind: "none";
|
|
579
|
+
} | {
|
|
580
|
+
kind: "gzip";
|
|
527
581
|
} | {
|
|
528
582
|
kind: "zip" | "tar" | "tar.gz";
|
|
529
|
-
|
|
583
|
+
member: {
|
|
530
584
|
path: string;
|
|
531
585
|
} | {
|
|
532
586
|
extensions: string[];
|
|
@@ -577,6 +631,15 @@ declare const EntrySchema: z.ZodObject<{
|
|
|
577
631
|
} | {
|
|
578
632
|
format: "solomon";
|
|
579
633
|
encoding: "utf-8" | "latin1";
|
|
634
|
+
} | {
|
|
635
|
+
format: "top";
|
|
636
|
+
encoding: "utf-8" | "latin1";
|
|
637
|
+
} | {
|
|
638
|
+
format: "toptw";
|
|
639
|
+
encoding: "utf-8" | "latin1";
|
|
640
|
+
} | {
|
|
641
|
+
format: "tsplib";
|
|
642
|
+
encoding: "utf-8" | "latin1";
|
|
580
643
|
};
|
|
581
644
|
paging?: {
|
|
582
645
|
kind: "arcgis-query";
|
|
@@ -826,6 +889,24 @@ declare const CatalogueIndexSchema: z.ZodObject<{
|
|
|
826
889
|
"utf-8": "utf-8";
|
|
827
890
|
latin1: "latin1";
|
|
828
891
|
}>;
|
|
892
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
893
|
+
format: z.ZodLiteral<"top">;
|
|
894
|
+
encoding: z.ZodEnum<{
|
|
895
|
+
"utf-8": "utf-8";
|
|
896
|
+
latin1: "latin1";
|
|
897
|
+
}>;
|
|
898
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
899
|
+
format: z.ZodLiteral<"toptw">;
|
|
900
|
+
encoding: z.ZodEnum<{
|
|
901
|
+
"utf-8": "utf-8";
|
|
902
|
+
latin1: "latin1";
|
|
903
|
+
}>;
|
|
904
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
905
|
+
format: z.ZodLiteral<"tsplib">;
|
|
906
|
+
encoding: z.ZodEnum<{
|
|
907
|
+
"utf-8": "utf-8";
|
|
908
|
+
latin1: "latin1";
|
|
909
|
+
}>;
|
|
829
910
|
}, z.core.$strict>, z.ZodObject<{
|
|
830
911
|
format: z.ZodLiteral<"csv-table">;
|
|
831
912
|
encoding: z.ZodEnum<{
|
|
@@ -901,19 +982,19 @@ declare const CatalogueIndexSchema: z.ZodObject<{
|
|
|
901
982
|
status: "fetchable";
|
|
902
983
|
source: number;
|
|
903
984
|
archive: {
|
|
904
|
-
kind: "none";
|
|
905
|
-
} | {
|
|
906
|
-
kind: "gzip";
|
|
907
|
-
} | {
|
|
908
985
|
kind: "zip" | "tar" | "tar.gz";
|
|
909
|
-
|
|
986
|
+
members: {
|
|
910
987
|
path: string;
|
|
911
988
|
} | {
|
|
912
989
|
extensions: string[];
|
|
913
990
|
};
|
|
991
|
+
} | {
|
|
992
|
+
kind: "none";
|
|
993
|
+
} | {
|
|
994
|
+
kind: "gzip";
|
|
914
995
|
} | {
|
|
915
996
|
kind: "zip" | "tar" | "tar.gz";
|
|
916
|
-
|
|
997
|
+
member: {
|
|
917
998
|
path: string;
|
|
918
999
|
} | {
|
|
919
1000
|
extensions: string[];
|
|
@@ -964,6 +1045,15 @@ declare const CatalogueIndexSchema: z.ZodObject<{
|
|
|
964
1045
|
} | {
|
|
965
1046
|
format: "solomon";
|
|
966
1047
|
encoding: "utf-8" | "latin1";
|
|
1048
|
+
} | {
|
|
1049
|
+
format: "top";
|
|
1050
|
+
encoding: "utf-8" | "latin1";
|
|
1051
|
+
} | {
|
|
1052
|
+
format: "toptw";
|
|
1053
|
+
encoding: "utf-8" | "latin1";
|
|
1054
|
+
} | {
|
|
1055
|
+
format: "tsplib";
|
|
1056
|
+
encoding: "utf-8" | "latin1";
|
|
967
1057
|
};
|
|
968
1058
|
paging?: {
|
|
969
1059
|
kind: "arcgis-query";
|
|
@@ -1042,19 +1132,19 @@ declare const CatalogueIndexSchema: z.ZodObject<{
|
|
|
1042
1132
|
status: "fetchable";
|
|
1043
1133
|
source: number;
|
|
1044
1134
|
archive: {
|
|
1045
|
-
kind: "none";
|
|
1046
|
-
} | {
|
|
1047
|
-
kind: "gzip";
|
|
1048
|
-
} | {
|
|
1049
1135
|
kind: "zip" | "tar" | "tar.gz";
|
|
1050
|
-
|
|
1136
|
+
members: {
|
|
1051
1137
|
path: string;
|
|
1052
1138
|
} | {
|
|
1053
1139
|
extensions: string[];
|
|
1054
1140
|
};
|
|
1141
|
+
} | {
|
|
1142
|
+
kind: "none";
|
|
1143
|
+
} | {
|
|
1144
|
+
kind: "gzip";
|
|
1055
1145
|
} | {
|
|
1056
1146
|
kind: "zip" | "tar" | "tar.gz";
|
|
1057
|
-
|
|
1147
|
+
member: {
|
|
1058
1148
|
path: string;
|
|
1059
1149
|
} | {
|
|
1060
1150
|
extensions: string[];
|
|
@@ -1105,6 +1195,15 @@ declare const CatalogueIndexSchema: z.ZodObject<{
|
|
|
1105
1195
|
} | {
|
|
1106
1196
|
format: "solomon";
|
|
1107
1197
|
encoding: "utf-8" | "latin1";
|
|
1198
|
+
} | {
|
|
1199
|
+
format: "top";
|
|
1200
|
+
encoding: "utf-8" | "latin1";
|
|
1201
|
+
} | {
|
|
1202
|
+
format: "toptw";
|
|
1203
|
+
encoding: "utf-8" | "latin1";
|
|
1204
|
+
} | {
|
|
1205
|
+
format: "tsplib";
|
|
1206
|
+
encoding: "utf-8" | "latin1";
|
|
1108
1207
|
};
|
|
1109
1208
|
paging?: {
|
|
1110
1209
|
kind: "arcgis-query";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as Parser, A as LineageSchema, B as Citation, C as CatalogueIndex, D as NamespaceNode, E as DatasetQuery, F as AliasSchema, G as Entry, H as ColumnNameSchema, I as Archive, J as IdSchema, K as EntrySchema, L as ArchiveMember, M as ManifestSchema, N as SemVerSchema, O as createCatalogue, P as parseManifest, Q as NamespaceSchema, R as ArchiveMemberSchema, S as Catalogue, T as Dataset, U as CrosswalkReference, V as CitationSchema, W as CrosswalkReferenceSchema, X as LicenceSchema, Y as Licence, Z as Namespace, _ as GraphEdgeSchema, a as CategoryTargets, at as Snapshot, b as GraphV1, c as getCategory, ct as SourceSchema, d as listCategories, dt as waybackUrl, et as ParserSchema, f as OrNode, g as GraphEdge, h as OrV1Schema, i as CategoryTarget, it as RelativePathSchema, j as Manifest, k as Lineage, l as getTarget, lt as WaybackTimestampSchema, m as OrV1, n as CategoryId, nt as Recipe, o as CountedKey, ot as SnapshotSchema, p as OrNodeSchema, q as HttpUrlSchema, r as CategoryIdSchema, rt as RecipeSchema, s as countTarget, st as Source, t as Category, tt as RESERVED_META_KEYS, u as kindOf, ut as parseEntry, v as GraphNode, w as CatalogueIndexSchema, x as GraphV1Schema, y as GraphNodeSchema, z as ArchiveSchema } from "./categories-
|
|
1
|
+
import { $ as Parser, A as LineageSchema, B as Citation, C as CatalogueIndex, D as NamespaceNode, E as DatasetQuery, F as AliasSchema, G as Entry, H as ColumnNameSchema, I as Archive, J as IdSchema, K as EntrySchema, L as ArchiveMember, M as ManifestSchema, N as SemVerSchema, O as createCatalogue, P as parseManifest, Q as NamespaceSchema, R as ArchiveMemberSchema, S as Catalogue, T as Dataset, U as CrosswalkReference, V as CitationSchema, W as CrosswalkReferenceSchema, X as LicenceSchema, Y as Licence, Z as Namespace, _ as GraphEdgeSchema, a as CategoryTargets, at as Snapshot, b as GraphV1, c as getCategory, ct as SourceSchema, d as listCategories, dt as waybackUrl, et as ParserSchema, f as OrNode, g as GraphEdge, h as OrV1Schema, i as CategoryTarget, it as RelativePathSchema, j as Manifest, k as Lineage, l as getTarget, lt as WaybackTimestampSchema, m as OrV1, n as CategoryId, nt as Recipe, o as CountedKey, ot as SnapshotSchema, p as OrNodeSchema, q as HttpUrlSchema, r as CategoryIdSchema, rt as RecipeSchema, s as countTarget, st as Source, t as Category, tt as RESERVED_META_KEYS, u as kindOf, ut as parseEntry, v as GraphNode, w as CatalogueIndexSchema, x as GraphV1Schema, y as GraphNodeSchema, z as ArchiveSchema } from "./categories-HeWbVPhc.js";
|
|
2
2
|
import { Crosswalk } from "twindex";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
//#region src/errors.d.ts
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as NativeParseError, A as toIssues, B as kindOf, C as RESERVED_META_KEYS, D as SourceSchema, E as SnapshotSchema, G as GraphNodeSchema, H as OrNodeSchema, I as CategoryIdSchema, J as ArchiveError, K as GraphV1Schema, L as countTarget, M as NAME_SEPARATOR, N as groupsOf, O as WaybackTimestampSchema, P as namesOf, Q as KeepsetError, R as getCategory, S as ParserSchema, T as RelativePathSchema, U as OrV1Schema, V as listCategories, W as GraphEdgeSchema, X as DatasetAmbiguousError, Y as CatalogueSyntaxError, Z as DatasetNotFoundError, _ as EntrySchema, a as CatalogueIndexSchema, b as LicenceSchema, c as ManifestSchema, d as AliasSchema, et as RecipeError, f as ArchiveMemberSchema, g as CrosswalkReferenceSchema, h as ColumnNameSchema, i as listNamespaces, j as waybackUrl, k as parseEntry, l as SemVerSchema, m as CitationSchema, n as getManifest, o as createCatalogue, p as ArchiveSchema, q as JsonScalarSchema, r as listDatasets, s as LineageSchema, t as getDataset, tt as UnknownCategoryError, u as parseManifest, v as HttpUrlSchema, w as RecipeSchema, x as NamespaceSchema, y as IdSchema, z as getTarget } from "./bundled-
|
|
1
|
+
import { $ as NativeParseError, A as toIssues, B as kindOf, C as RESERVED_META_KEYS, D as SourceSchema, E as SnapshotSchema, G as GraphNodeSchema, H as OrNodeSchema, I as CategoryIdSchema, J as ArchiveError, K as GraphV1Schema, L as countTarget, M as NAME_SEPARATOR, N as groupsOf, O as WaybackTimestampSchema, P as namesOf, Q as KeepsetError, R as getCategory, S as ParserSchema, T as RelativePathSchema, U as OrV1Schema, V as listCategories, W as GraphEdgeSchema, X as DatasetAmbiguousError, Y as CatalogueSyntaxError, Z as DatasetNotFoundError, _ as EntrySchema, a as CatalogueIndexSchema, b as LicenceSchema, c as ManifestSchema, d as AliasSchema, et as RecipeError, f as ArchiveMemberSchema, g as CrosswalkReferenceSchema, h as ColumnNameSchema, i as listNamespaces, j as waybackUrl, k as parseEntry, l as SemVerSchema, m as CitationSchema, n as getManifest, o as createCatalogue, p as ArchiveSchema, q as JsonScalarSchema, r as listDatasets, s as LineageSchema, t as getDataset, tt as UnknownCategoryError, u as parseManifest, v as HttpUrlSchema, w as RecipeSchema, x as NamespaceSchema, y as IdSchema, z as getTarget } from "./bundled-V1EJ0k9e.js";
|
|
2
2
|
import { validateCrosswalk } from "twindex";
|
|
3
3
|
//#region src/serialise.ts
|
|
4
4
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { G as Entry, T as Dataset, at as Snapshot, i as CategoryTarget, st as Source } from "../categories-
|
|
1
|
+
import { G as Entry, T as Dataset, at as Snapshot, i as CategoryTarget, st as Source } from "../categories-HeWbVPhc.js";
|
|
2
2
|
//#region src/node/fetch-dataset.d.ts
|
|
3
3
|
/** The network port a recipe downloads through: `downloadRaw` by default, which returns the bytes exactly as served, or a stand-in under test. */
|
|
4
4
|
export type FetchPort = (url: string, init: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as NativeParseError, F as getOwn, J as ArchiveError, L as countTarget, Q as KeepsetError, et as RecipeError, t as getDataset, z as getTarget } from "../bundled-
|
|
1
|
+
import { $ as NativeParseError, F as getOwn, J as ArchiveError, L as countTarget, Q as KeepsetError, et as RecipeError, t as getDataset, z as getTarget } from "../bundled-V1EJ0k9e.js";
|
|
2
2
|
import { RoundTripMismatchError, assertRoundTrip, encode } from "twindex";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { createHash } from "node:crypto";
|
|
@@ -104,7 +104,7 @@ function parseEdgeList(text, options) {
|
|
|
104
104
|
//#endregion
|
|
105
105
|
//#region src/parsers/gml.ts
|
|
106
106
|
const KEY = /[A-Za-z_][A-Za-z0-9_]*/y;
|
|
107
|
-
const NUMBER$
|
|
107
|
+
const NUMBER$4 = /[+-]?(?:\d+\.?\d*|\.\d+)(?:[Ee][+-]?\d+)?/y;
|
|
108
108
|
/**
|
|
109
109
|
* Matches a sticky pattern at a position.
|
|
110
110
|
* @param pattern - A sticky regular expression.
|
|
@@ -155,7 +155,7 @@ function tokenise(text) {
|
|
|
155
155
|
position = end + 1;
|
|
156
156
|
} else {
|
|
157
157
|
const key = matchAt(KEY, text, position);
|
|
158
|
-
const number = key === void 0 ? matchAt(NUMBER$
|
|
158
|
+
const number = key === void 0 ? matchAt(NUMBER$4, text, position) : void 0;
|
|
159
159
|
const match = key ?? number;
|
|
160
160
|
if (match === void 0) throw new NativeParseError("gml", line, `unexpected character ${JSON.stringify(char)}`);
|
|
161
161
|
tokens.push({
|
|
@@ -833,9 +833,9 @@ function parsePajek(text) {
|
|
|
833
833
|
}
|
|
834
834
|
//#endregion
|
|
835
835
|
//#region src/parsers/solomon.ts
|
|
836
|
-
const FORMAT = "solomon";
|
|
836
|
+
const FORMAT$3 = "solomon";
|
|
837
837
|
/** A line of integers or decimals separated by any run of spaces and tabs, as the files write rows (Solomon's with padded spaces, the Tenerife set with tabs). */
|
|
838
|
-
const NUMBER = /^-?\d+(?:\.\d+)?$/;
|
|
838
|
+
const NUMBER$3 = /^-?\d+(?:\.\d+)?$/;
|
|
839
839
|
/**
|
|
840
840
|
* Reads a token as a finite number.
|
|
841
841
|
* @param token - The token.
|
|
@@ -844,8 +844,8 @@ const NUMBER = /^-?\d+(?:\.\d+)?$/;
|
|
|
844
844
|
* @returns The number.
|
|
845
845
|
* @throws NativeParseError when the token is not a decimal number.
|
|
846
846
|
*/
|
|
847
|
-
function numberOf(token, line, what) {
|
|
848
|
-
if (!NUMBER.test(token)) throw new NativeParseError(FORMAT, line, `expected ${what}, found ${JSON.stringify(token)}`);
|
|
847
|
+
function numberOf$2(token, line, what) {
|
|
848
|
+
if (!NUMBER$3.test(token)) throw new NativeParseError(FORMAT$3, line, `expected ${what}, found ${JSON.stringify(token)}`);
|
|
849
849
|
return Number(token);
|
|
850
850
|
}
|
|
851
851
|
/**
|
|
@@ -858,7 +858,7 @@ function parseSolomon(text) {
|
|
|
858
858
|
const all = lines(text);
|
|
859
859
|
const present = (index) => (all[index] ?? "").trim();
|
|
860
860
|
const name = present(0);
|
|
861
|
-
if (name === "") throw new NativeParseError(FORMAT, 1, "expected the instance name on the first line");
|
|
861
|
+
if (name === "") throw new NativeParseError(FORMAT$3, 1, "expected the instance name on the first line");
|
|
862
862
|
const meta = { name };
|
|
863
863
|
const nodes = [];
|
|
864
864
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -874,7 +874,7 @@ function parseSolomon(text) {
|
|
|
874
874
|
awaitingHeader = true;
|
|
875
875
|
continue;
|
|
876
876
|
}
|
|
877
|
-
if (section === "preamble") throw new NativeParseError(FORMAT, line, `expected VEHICLE or CUSTOMER, found ${JSON.stringify(trimmed)}`);
|
|
877
|
+
if (section === "preamble") throw new NativeParseError(FORMAT$3, line, `expected VEHICLE or CUSTOMER, found ${JSON.stringify(trimmed)}`);
|
|
878
878
|
if (awaitingHeader) {
|
|
879
879
|
awaitingHeader = false;
|
|
880
880
|
continue;
|
|
@@ -882,29 +882,29 @@ function parseSolomon(text) {
|
|
|
882
882
|
const tokens = trimmed.split(/\s+/);
|
|
883
883
|
if (section === "vehicle") {
|
|
884
884
|
const [vehicles, capacity, ...extra] = tokens;
|
|
885
|
-
if (vehicles === void 0 || capacity === void 0 || extra.length > 0) throw new NativeParseError(FORMAT, line, `expected the vehicle count and capacity, found ${JSON.stringify(trimmed)}`);
|
|
886
|
-
meta.vehicles = numberOf(vehicles, line, "the vehicle count");
|
|
887
|
-
meta.capacity = numberOf(capacity, line, "the vehicle capacity");
|
|
885
|
+
if (vehicles === void 0 || capacity === void 0 || extra.length > 0) throw new NativeParseError(FORMAT$3, line, `expected the vehicle count and capacity, found ${JSON.stringify(trimmed)}`);
|
|
886
|
+
meta.vehicles = numberOf$2(vehicles, line, "the vehicle count");
|
|
887
|
+
meta.capacity = numberOf$2(capacity, line, "the vehicle capacity");
|
|
888
888
|
continue;
|
|
889
889
|
}
|
|
890
890
|
const [id, x, y, demand, ready, due, service, ...extra] = tokens;
|
|
891
|
-
if (id === void 0 || x === void 0 || y === void 0 || demand === void 0 || ready === void 0 || due === void 0 || service === void 0 || extra.length > 0) throw new NativeParseError(FORMAT, line, `expected seven numbers (id, x, y, demand, ready, due, service), found ${JSON.stringify(trimmed)}`);
|
|
892
|
-
if (!/^\d+$/.test(id)) throw new NativeParseError(FORMAT, line, `expected a whole number node id, found ${JSON.stringify(id)}`);
|
|
893
|
-
if (seen.has(id)) throw new NativeParseError(FORMAT, line, `node ${id} appears twice`);
|
|
891
|
+
if (id === void 0 || x === void 0 || y === void 0 || demand === void 0 || ready === void 0 || due === void 0 || service === void 0 || extra.length > 0) throw new NativeParseError(FORMAT$3, line, `expected seven numbers (id, x, y, demand, ready, due, service), found ${JSON.stringify(trimmed)}`);
|
|
892
|
+
if (!/^\d+$/.test(id)) throw new NativeParseError(FORMAT$3, line, `expected a whole number node id, found ${JSON.stringify(id)}`);
|
|
893
|
+
if (seen.has(id)) throw new NativeParseError(FORMAT$3, line, `node ${id} appears twice`);
|
|
894
894
|
seen.add(id);
|
|
895
895
|
nodes.push({
|
|
896
896
|
id,
|
|
897
|
-
x: numberOf(x, line, "x"),
|
|
898
|
-
y: numberOf(y, line, "y"),
|
|
899
|
-
demand: numberOf(demand, line, "the demand"),
|
|
900
|
-
ready: numberOf(ready, line, "the ready time"),
|
|
901
|
-
due: numberOf(due, line, "the due date"),
|
|
902
|
-
service: numberOf(service, line, "the service time")
|
|
897
|
+
x: numberOf$2(x, line, "x"),
|
|
898
|
+
y: numberOf$2(y, line, "y"),
|
|
899
|
+
demand: numberOf$2(demand, line, "the demand"),
|
|
900
|
+
ready: numberOf$2(ready, line, "the ready time"),
|
|
901
|
+
due: numberOf$2(due, line, "the due date"),
|
|
902
|
+
service: numberOf$2(service, line, "the service time")
|
|
903
903
|
});
|
|
904
904
|
}
|
|
905
|
-
if (section !== "customer") throw new NativeParseError(FORMAT, all.length, "expected a CUSTOMER section");
|
|
906
|
-
if (nodes.length === 0) throw new NativeParseError(FORMAT, all.length, "the CUSTOMER section has no rows");
|
|
907
|
-
if (meta.vehicles === void 0 || meta.capacity === void 0) throw new NativeParseError(FORMAT, all.length, "expected a VEHICLE section with the vehicle count and capacity");
|
|
905
|
+
if (section !== "customer") throw new NativeParseError(FORMAT$3, all.length, "expected a CUSTOMER section");
|
|
906
|
+
if (nodes.length === 0) throw new NativeParseError(FORMAT$3, all.length, "the CUSTOMER section has no rows");
|
|
907
|
+
if (meta.vehicles === void 0 || meta.capacity === void 0) throw new NativeParseError(FORMAT$3, all.length, "expected a VEHICLE section with the vehicle count and capacity");
|
|
908
908
|
return {
|
|
909
909
|
meta: {
|
|
910
910
|
name: meta.name,
|
|
@@ -915,6 +915,345 @@ function parseSolomon(text) {
|
|
|
915
915
|
};
|
|
916
916
|
}
|
|
917
917
|
//#endregion
|
|
918
|
+
//#region src/parsers/top.ts
|
|
919
|
+
const FORMAT$2 = "top";
|
|
920
|
+
/** The header lines before the first point: `n`, `m` and `tmax`. */
|
|
921
|
+
const HEADER_LINES = 3;
|
|
922
|
+
const NUMBER$2 = /^-?\d+(?:\.\d+)?$/;
|
|
923
|
+
/**
|
|
924
|
+
* Reads the value of a header line `<key> <number>`.
|
|
925
|
+
* @param text - The line.
|
|
926
|
+
* @param key - The key it must start with.
|
|
927
|
+
* @param line - The 1-based line, for the error.
|
|
928
|
+
* @returns The number.
|
|
929
|
+
* @throws NativeParseError when the line is not the key and one number.
|
|
930
|
+
*/
|
|
931
|
+
function headerOf(text, key, line) {
|
|
932
|
+
const [name, value, ...extra] = (text ?? "").trim().split(/\s+/);
|
|
933
|
+
if (name !== key || value === void 0 || extra.length > 0 || !NUMBER$2.test(value)) throw new NativeParseError(FORMAT$2, line, `expected "${key} <number>", found ${JSON.stringify((text ?? "").trim())}`);
|
|
934
|
+
return Number(value);
|
|
935
|
+
}
|
|
936
|
+
/**
|
|
937
|
+
* Parses a team orienteering problem instance (Chao, Golden and Wasil, as the KU Leuven pages describe it): `n <points>`, `m <paths>` and `tmax <budget>` on three lines, then one row of position and score for each point. The first point is where the paths start and the last is where they end, and the rest are to visit; the file has no ids, so a point's id is its zero-based row number. Columns are separated by any run of spaces or tabs, and blank or whitespace only lines are skipped. The positions and the budget are in the same planar unit, which the format does not name.
|
|
938
|
+
* @param text - The file text.
|
|
939
|
+
* @returns The instance: its point count, path count and per-path budget as `meta`, and its nodes in file order.
|
|
940
|
+
* @throws NativeParseError naming the line for a missing or misordered header line, a row that is not three numbers, or a row count that is not the point count.
|
|
941
|
+
*/
|
|
942
|
+
function parseTop(text) {
|
|
943
|
+
const all = lines(text).map((raw, index) => ({
|
|
944
|
+
line: index + 1,
|
|
945
|
+
text: raw.trim()
|
|
946
|
+
})).filter((entry) => entry.text !== "");
|
|
947
|
+
const [first, second, third] = all;
|
|
948
|
+
const rows = all.slice(HEADER_LINES);
|
|
949
|
+
const points = headerOf(first?.text, "n", first?.line ?? 1);
|
|
950
|
+
const paths = headerOf(second?.text, "m", second?.line ?? 2);
|
|
951
|
+
const budget = headerOf(third?.text, "tmax", third?.line ?? HEADER_LINES);
|
|
952
|
+
if (!Number.isInteger(points) || points < 2) throw new NativeParseError(FORMAT$2, first?.line ?? 1, `expected at least a start and an end point, found n ${String(points)}`);
|
|
953
|
+
if (rows.length !== points) throw new NativeParseError(FORMAT$2, all[all.length - 1]?.line ?? 1, `the header gives ${String(points)} points, found ${String(rows.length)} rows`);
|
|
954
|
+
const nodes = rows.map((row, index) => {
|
|
955
|
+
const [x, y, score, ...extra] = row.text.split(/\s+/);
|
|
956
|
+
if (x === void 0 || y === void 0 || score === void 0 || extra.length > 0 || !NUMBER$2.test(x) || !NUMBER$2.test(y) || !NUMBER$2.test(score)) throw new NativeParseError(FORMAT$2, row.line, `expected three numbers (x, y, score), found ${JSON.stringify(row.text)}`);
|
|
957
|
+
return {
|
|
958
|
+
id: String(index),
|
|
959
|
+
x: Number(x),
|
|
960
|
+
y: Number(y),
|
|
961
|
+
score: Number(score),
|
|
962
|
+
role: index === 0 ? "start" : index === points - 1 ? "end" : "visit"
|
|
963
|
+
};
|
|
964
|
+
});
|
|
965
|
+
return {
|
|
966
|
+
meta: {
|
|
967
|
+
points,
|
|
968
|
+
paths,
|
|
969
|
+
budget
|
|
970
|
+
},
|
|
971
|
+
nodes
|
|
972
|
+
};
|
|
973
|
+
}
|
|
974
|
+
//#endregion
|
|
975
|
+
//#region src/parsers/toptw.ts
|
|
976
|
+
const FORMAT$1 = "toptw";
|
|
977
|
+
/** How many numbers the first header line holds (k, paths, customers, t) and the second (D, capacity). */
|
|
978
|
+
const FIRST_HEADER_NUMBERS = 4;
|
|
979
|
+
const SECOND_HEADER_NUMBERS = 2;
|
|
980
|
+
/** Where a node row's fields sit: the length of the unused list is the seventh token, the list follows, and the window's opening and closing come after it. A row without a list is the first token to the window's closing, so it holds this many numbers plus the list's length. */
|
|
981
|
+
const LIST_LENGTH_AT = 6;
|
|
982
|
+
const LIST_STARTS_AT = 7;
|
|
983
|
+
const ROW_NUMBERS_BESIDE_LIST = 9;
|
|
984
|
+
const NUMBER$1 = /^-?\d+(?:\.\d+)?$/;
|
|
985
|
+
/**
|
|
986
|
+
* Reads a token as a finite number.
|
|
987
|
+
* @param token - The token.
|
|
988
|
+
* @param line - The 1-based line, for the error.
|
|
989
|
+
* @param what - What the token should be, for the error.
|
|
990
|
+
* @returns The number.
|
|
991
|
+
* @throws NativeParseError when the token is not a decimal number.
|
|
992
|
+
*/
|
|
993
|
+
function numberOf$1(token, line, what) {
|
|
994
|
+
if (token === void 0 || !NUMBER$1.test(token)) throw new NativeParseError(FORMAT$1, line, `expected ${what}, found ${JSON.stringify(token)}`);
|
|
995
|
+
return Number(token);
|
|
996
|
+
}
|
|
997
|
+
/**
|
|
998
|
+
* Reads a line of a given number of numbers.
|
|
999
|
+
* @param text - The line.
|
|
1000
|
+
* @param count - How many numbers it holds.
|
|
1001
|
+
* @param line - The 1-based line, for the error.
|
|
1002
|
+
* @param what - What the line should be, for the error.
|
|
1003
|
+
* @returns The numbers.
|
|
1004
|
+
* @throws NativeParseError when the line does not hold exactly that many numbers.
|
|
1005
|
+
*/
|
|
1006
|
+
function numbersOf(text, count, line, what) {
|
|
1007
|
+
const tokens = text.trim().split(/\s+/);
|
|
1008
|
+
if (tokens.length !== count) throw new NativeParseError(FORMAT$1, line, `expected ${what}, found ${JSON.stringify(text.trim())}`);
|
|
1009
|
+
return tokens.map((token) => numberOf$1(token, line, what));
|
|
1010
|
+
}
|
|
1011
|
+
/**
|
|
1012
|
+
* Parses a team orienteering problem with time windows instance (TOPTW, in the layout of Righini and Salani, as the KU Leuven pages describe it). The first line holds four numbers, of which the second is the number of paths and the third the number of customers, the second line two, of which the second is the vehicle capacity, and then one row per node, the depot first: its id, position, service duration, profit, an unused number, the length of a list of unused numbers, that list, and the opening and closing of its time window. Columns are separated by any run of spaces, and blank or whitespace only lines are skipped. The row count must be the customer count plus one, which catches a truncated file. The time quantities are in the unit of the source's coordinate grid, which the format does not name.
|
|
1013
|
+
* @param text - The file text.
|
|
1014
|
+
* @returns The instance: its path count, customer count and capacity as `meta`, and its nodes in file order.
|
|
1015
|
+
* @throws NativeParseError naming the line for a header or row that is not made of the numbers the format has, a row whose length does not match its list, a repeated node id, or a row count that is not the customer count plus one.
|
|
1016
|
+
*/
|
|
1017
|
+
function parseToptw(text) {
|
|
1018
|
+
const all = lines(text).map((raw, index) => ({
|
|
1019
|
+
line: index + 1,
|
|
1020
|
+
text: raw.trim()
|
|
1021
|
+
})).filter((entry) => entry.text !== "");
|
|
1022
|
+
const [first, second, ...rows] = all;
|
|
1023
|
+
if (first === void 0 || second === void 0) throw new NativeParseError(FORMAT$1, 1, "expected the two header lines");
|
|
1024
|
+
const [, paths, customers] = numbersOf(first.text, FIRST_HEADER_NUMBERS, first.line, "four numbers (k, paths, customers, t)");
|
|
1025
|
+
const [, capacity] = numbersOf(second.text, SECOND_HEADER_NUMBERS, second.line, "two numbers (D, capacity)");
|
|
1026
|
+
if (paths === void 0 || customers === void 0 || capacity === void 0) throw new NativeParseError(FORMAT$1, first.line, "the header lacks a number");
|
|
1027
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1028
|
+
const nodes = rows.map((row) => {
|
|
1029
|
+
const tokens = row.text.split(/\s+/);
|
|
1030
|
+
const listLength = numberOf$1(tokens[LIST_LENGTH_AT], row.line, "the length of the list after the unused number");
|
|
1031
|
+
if (!Number.isInteger(listLength) || listLength < 0 || tokens.length !== ROW_NUMBERS_BESIDE_LIST + listLength) throw new NativeParseError(FORMAT$1, row.line, `expected ${String(ROW_NUMBERS_BESIDE_LIST + listLength)} numbers for a list of ${String(listLength)}, found ${String(tokens.length)}`);
|
|
1032
|
+
const [id] = tokens;
|
|
1033
|
+
if (id === void 0 || !/^\d+$/.test(id)) throw new NativeParseError(FORMAT$1, row.line, `expected a whole number node id, found ${JSON.stringify(id)}`);
|
|
1034
|
+
if (seen.has(id)) throw new NativeParseError(FORMAT$1, row.line, `node ${id} appears twice`);
|
|
1035
|
+
seen.add(id);
|
|
1036
|
+
return {
|
|
1037
|
+
id,
|
|
1038
|
+
x: numberOf$1(tokens[1], row.line, "x"),
|
|
1039
|
+
y: numberOf$1(tokens[2], row.line, "y"),
|
|
1040
|
+
service: numberOf$1(tokens[3], row.line, "the service duration"),
|
|
1041
|
+
profit: numberOf$1(tokens[4], row.line, "the profit"),
|
|
1042
|
+
open: numberOf$1(tokens[LIST_STARTS_AT + listLength], row.line, "the opening of the window"),
|
|
1043
|
+
close: numberOf$1(tokens[8 + listLength], row.line, "the closing of the window")
|
|
1044
|
+
};
|
|
1045
|
+
});
|
|
1046
|
+
if (nodes.length !== customers + 1) throw new NativeParseError(FORMAT$1, all.length === 0 ? 1 : all[all.length - 1]?.line ?? 1, `the header gives ${String(customers)} customers, so expected ${String(customers + 1)} rows with the depot, found ${String(nodes.length)}`);
|
|
1047
|
+
return {
|
|
1048
|
+
meta: {
|
|
1049
|
+
paths,
|
|
1050
|
+
customers,
|
|
1051
|
+
capacity
|
|
1052
|
+
},
|
|
1053
|
+
nodes
|
|
1054
|
+
};
|
|
1055
|
+
}
|
|
1056
|
+
//#endregion
|
|
1057
|
+
//#region src/parsers/tsplib.ts
|
|
1058
|
+
const FORMAT = "tsplib";
|
|
1059
|
+
/** The instance types the parser reads: the probabilistic and the clustered orienteering problem. */
|
|
1060
|
+
const TYPES = /* @__PURE__ */ new Set(["POP", "COP"]);
|
|
1061
|
+
/** The edge weight types a coordinate section is read under: planar ones keep their coordinates as `x` and `y`, `GEO` converts them to degrees, and `EXPLICIT` has no coordinates. */
|
|
1062
|
+
const PLANAR = /* @__PURE__ */ new Set([
|
|
1063
|
+
"EUC_2D",
|
|
1064
|
+
"CEIL_2D",
|
|
1065
|
+
"ATT"
|
|
1066
|
+
]);
|
|
1067
|
+
const NUMBER = /^-?\d+(?:\.\d+)?$/;
|
|
1068
|
+
const WHOLE = /^\d+$/;
|
|
1069
|
+
const HEADER$1 = /^([A-Z][A-Z_]*)\s*:\s*(.*)$/;
|
|
1070
|
+
const SECTION = /^[A-Z][A-Z_]*$/;
|
|
1071
|
+
/** Minutes in a degree, which a `DDD.MM` coordinate counts in. */
|
|
1072
|
+
const MINUTES_PER_DEGREE = 60;
|
|
1073
|
+
/** `DDD.MM` has two digits of minutes, so the fraction is read in hundredths. */
|
|
1074
|
+
const MINUTE_SCALE = 100;
|
|
1075
|
+
/** How far a coordinate's hundredths may lie from a whole number of minutes: float error in the text's value, not a third digit. */
|
|
1076
|
+
const MINUTE_TOLERANCE = 1e-6;
|
|
1077
|
+
/**
|
|
1078
|
+
* Converts a TSPLIB `GEO` coordinate to decimal degrees. The value is `DDD.MM`, degrees then minutes in one number (`48.23` is 48 degrees 23 minutes), so the fraction is minutes out of a hundred, not a decimal fraction of a degree. The degrees are truncated, which is what makes the conversion agree with the optimal tour lengths the instances record where the specification's `nint` would round minutes of 50 or more up to the next degree.
|
|
1079
|
+
* @param value - The coordinate as the file writes it.
|
|
1080
|
+
* @param line - The 1-based line, for the error.
|
|
1081
|
+
* @returns Decimal degrees, signed like the input.
|
|
1082
|
+
* @throws NativeParseError when the minutes are not a whole number below sixty.
|
|
1083
|
+
*/
|
|
1084
|
+
function degrees(value, line) {
|
|
1085
|
+
const magnitude = Math.abs(value);
|
|
1086
|
+
const whole = Math.trunc(magnitude);
|
|
1087
|
+
const hundredths = (magnitude - whole) * MINUTE_SCALE;
|
|
1088
|
+
const minutes = Math.round(hundredths);
|
|
1089
|
+
if (Math.abs(hundredths - minutes) > MINUTE_TOLERANCE || minutes >= MINUTES_PER_DEGREE) throw new NativeParseError(FORMAT, line, `expected a DDD.MM coordinate with whole minutes below 60, found ${String(value)}`);
|
|
1090
|
+
return Math.sign(value) * (whole + minutes / MINUTES_PER_DEGREE);
|
|
1091
|
+
}
|
|
1092
|
+
/**
|
|
1093
|
+
* Reads a token as a finite number.
|
|
1094
|
+
* @param token - The token.
|
|
1095
|
+
* @param line - The 1-based line, for the error.
|
|
1096
|
+
* @param what - What the token should be, for the error.
|
|
1097
|
+
* @returns The number.
|
|
1098
|
+
* @throws NativeParseError when the token is not a decimal number.
|
|
1099
|
+
*/
|
|
1100
|
+
function numberOf(token, line, what) {
|
|
1101
|
+
if (token === void 0 || !NUMBER.test(token)) throw new NativeParseError(FORMAT, line, `expected ${what}, found ${JSON.stringify(token)}`);
|
|
1102
|
+
return Number(token);
|
|
1103
|
+
}
|
|
1104
|
+
/**
|
|
1105
|
+
* Reads a token as a whole number.
|
|
1106
|
+
* @param token - The token.
|
|
1107
|
+
* @param line - The 1-based line, for the error.
|
|
1108
|
+
* @param what - What the token should be, for the error.
|
|
1109
|
+
* @returns The number.
|
|
1110
|
+
* @throws NativeParseError when the token is not a whole number.
|
|
1111
|
+
*/
|
|
1112
|
+
function wholeOf(token, line, what) {
|
|
1113
|
+
if (token === void 0 || !WHOLE.test(token)) throw new NativeParseError(FORMAT, line, `expected ${what}, found ${JSON.stringify(token)}`);
|
|
1114
|
+
return Number(token);
|
|
1115
|
+
}
|
|
1116
|
+
/**
|
|
1117
|
+
* Reads the header, the coordinate section, the prize and probability section and the set section of a file, skipping every other section.
|
|
1118
|
+
* @param text - The file text.
|
|
1119
|
+
* @returns What it holds.
|
|
1120
|
+
* @throws NativeParseError naming the line for a repeated key, a malformed row, a repeated node or set id, or a row outside any section.
|
|
1121
|
+
*/
|
|
1122
|
+
function collect(text) {
|
|
1123
|
+
const collected = {
|
|
1124
|
+
header: /* @__PURE__ */ new Map(),
|
|
1125
|
+
coords: /* @__PURE__ */ new Map(),
|
|
1126
|
+
prizes: /* @__PURE__ */ new Map(),
|
|
1127
|
+
sets: []
|
|
1128
|
+
};
|
|
1129
|
+
let section;
|
|
1130
|
+
for (const [index, raw] of lines(text).entries()) {
|
|
1131
|
+
const line = index + 1;
|
|
1132
|
+
const trimmed = raw.trim();
|
|
1133
|
+
if (trimmed === "" || trimmed === "EOF") continue;
|
|
1134
|
+
const keyed = HEADER$1.exec(trimmed);
|
|
1135
|
+
const key = keyed?.[1];
|
|
1136
|
+
if (key === "CONSTRAINING_SET_SECTION") {
|
|
1137
|
+
section = "sets";
|
|
1138
|
+
continue;
|
|
1139
|
+
}
|
|
1140
|
+
if (keyed !== null && key !== void 0) {
|
|
1141
|
+
if (collected.header.has(key)) throw new NativeParseError(FORMAT, line, `${key} appears twice`);
|
|
1142
|
+
collected.header.set(key, (keyed[2] ?? "").trim());
|
|
1143
|
+
section = void 0;
|
|
1144
|
+
continue;
|
|
1145
|
+
}
|
|
1146
|
+
if (SECTION.test(trimmed)) {
|
|
1147
|
+
section = trimmed === "NODE_COORD_SECTION" ? "coords" : trimmed === "NODE_PRIZE_PROBABILITY_SECTION" ? "prizes" : "skipped";
|
|
1148
|
+
continue;
|
|
1149
|
+
}
|
|
1150
|
+
const tokens = trimmed.split(/\s+/);
|
|
1151
|
+
if (section === "coords") {
|
|
1152
|
+
const [id, x, y, ...extra] = tokens;
|
|
1153
|
+
if (extra.length > 0) throw new NativeParseError(FORMAT, line, `expected "id x y", found ${JSON.stringify(trimmed)}`);
|
|
1154
|
+
const node = wholeOf(id, line, "a node id");
|
|
1155
|
+
if (collected.coords.has(node)) throw new NativeParseError(FORMAT, line, `node ${String(node)} has two coordinate rows`);
|
|
1156
|
+
collected.coords.set(node, {
|
|
1157
|
+
x: numberOf(x, line, "x"),
|
|
1158
|
+
y: numberOf(y, line, "y"),
|
|
1159
|
+
line
|
|
1160
|
+
});
|
|
1161
|
+
} else if (section === "prizes") {
|
|
1162
|
+
const [id, prize, probability, ...extra] = tokens;
|
|
1163
|
+
if (extra.length > 0) throw new NativeParseError(FORMAT, line, `expected "id prize probability", found ${JSON.stringify(trimmed)}`);
|
|
1164
|
+
const node = wholeOf(id, line, "a node id");
|
|
1165
|
+
if (collected.prizes.has(node)) throw new NativeParseError(FORMAT, line, `node ${String(node)} has two prize rows`);
|
|
1166
|
+
collected.prizes.set(node, {
|
|
1167
|
+
prize: numberOf(prize, line, "the prize"),
|
|
1168
|
+
probability: numberOf(probability, line, "the probability")
|
|
1169
|
+
});
|
|
1170
|
+
} else if (section === "sets") {
|
|
1171
|
+
const [id, prize, ...members] = tokens;
|
|
1172
|
+
const setId = wholeOf(id, line, "a set id");
|
|
1173
|
+
if (collected.sets.some((set) => set.id === setId)) throw new NativeParseError(FORMAT, line, `set ${String(setId)} appears twice`);
|
|
1174
|
+
collected.sets.push({
|
|
1175
|
+
id: setId,
|
|
1176
|
+
prize: numberOf(prize, line, "the set prize"),
|
|
1177
|
+
members: members.map((member) => wholeOf(member, line, "a node id in a set"))
|
|
1178
|
+
});
|
|
1179
|
+
} else if (section === void 0) throw new NativeParseError(FORMAT, line, `expected a KEY : value line or a section, found ${JSON.stringify(trimmed)}`);
|
|
1180
|
+
}
|
|
1181
|
+
return collected;
|
|
1182
|
+
}
|
|
1183
|
+
/**
|
|
1184
|
+
* Reads a header value that must be there.
|
|
1185
|
+
* @param header - The header.
|
|
1186
|
+
* @param key - The key.
|
|
1187
|
+
* @returns Its text.
|
|
1188
|
+
* @throws NativeParseError when the file has no such key.
|
|
1189
|
+
*/
|
|
1190
|
+
function required(header, key) {
|
|
1191
|
+
const value = header.get(key);
|
|
1192
|
+
if (value === void 0) throw new NativeParseError(FORMAT, 1, `expected a ${key} line`);
|
|
1193
|
+
return value;
|
|
1194
|
+
}
|
|
1195
|
+
/**
|
|
1196
|
+
* Parses a TSPLIB style orienteering instance of type `POP` (probabilistic orienteering, Angelelli and others) or `COP` (clustered orienteering), in the layout TSPLIB95 (Reinelt) defines: `KEY : value` header lines and bare keyword sections. The nodes are 1 to `DIMENSION`. The planar weight types keep their coordinates as `x` and `y` and `GEO` converts them to `lat` and `lon`; an `EXPLICIT` file has no coordinates, so its nodes have only the prize data. A `POP` file's `NODE_PRIZE_PROBABILITY_SECTION` gives each node its prize and probability. A `COP` file has no prize on a node: its prizes belong to sets of nodes that may overlap, so each node lists the sets it is in under `clusters` and the sets' prizes are the `setPrizes` metadata, and nothing is divided among the members. The weight matrix is not read, as or/v1 has no arcs.
|
|
1197
|
+
* @param text - The file text.
|
|
1198
|
+
* @returns The instance: its header values as `meta` and its nodes in id order.
|
|
1199
|
+
* @throws NativeParseError naming the line for an unsupported type or weight type, a missing key or section, a node id outside 1 to `DIMENSION` or missing from a section that must cover every node, or a set that names a node outside that range.
|
|
1200
|
+
*/
|
|
1201
|
+
function parseTsplib(text) {
|
|
1202
|
+
const { header, coords, prizes, sets } = collect(text);
|
|
1203
|
+
const type = required(header, "TYPE");
|
|
1204
|
+
if (!TYPES.has(type)) throw new NativeParseError(FORMAT, 1, `expected TYPE POP or COP, found ${JSON.stringify(type)}`);
|
|
1205
|
+
const weightType = required(header, "EDGE_WEIGHT_TYPE");
|
|
1206
|
+
const geographic = weightType === "GEO";
|
|
1207
|
+
if (!geographic && !PLANAR.has(weightType) && weightType !== "EXPLICIT") throw new NativeParseError(FORMAT, 1, `expected EDGE_WEIGHT_TYPE EUC_2D, CEIL_2D, ATT, GEO or EXPLICIT, found ${JSON.stringify(weightType)}`);
|
|
1208
|
+
const dimension = wholeOf(required(header, "DIMENSION"), 1, "DIMENSION");
|
|
1209
|
+
const budget = numberOf(required(header, "TMAX"), 1, "TMAX");
|
|
1210
|
+
if (weightType === "EXPLICIT" ? coords.size > 0 : coords.size !== dimension) throw new NativeParseError(FORMAT, 1, weightType === "EXPLICIT" ? "an EXPLICIT file has no NODE_COORD_SECTION" : `expected ${String(dimension)} coordinate rows, found ${String(coords.size)}`);
|
|
1211
|
+
const inRange = (id) => id >= 1 && id <= dimension;
|
|
1212
|
+
for (const id of [
|
|
1213
|
+
...coords.keys(),
|
|
1214
|
+
...prizes.keys(),
|
|
1215
|
+
...sets.flatMap((set) => set.members)
|
|
1216
|
+
]) if (!inRange(id)) throw new NativeParseError(FORMAT, 1, `node ${String(id)} is outside 1 to ${String(dimension)}`);
|
|
1217
|
+
if (type === "POP" && prizes.size !== dimension) throw new NativeParseError(FORMAT, 1, `expected ${String(dimension)} prize rows, found ${String(prizes.size)}`);
|
|
1218
|
+
if (type === "COP") {
|
|
1219
|
+
const declared = wholeOf(required(header, "SETS"), 1, "SETS");
|
|
1220
|
+
if (sets.length !== declared) throw new NativeParseError(FORMAT, 1, `expected ${String(declared)} sets, found ${String(sets.length)}`);
|
|
1221
|
+
}
|
|
1222
|
+
const clustersOf = (node) => {
|
|
1223
|
+
const ids = sets.filter((set) => set.members.includes(node)).map((set) => String(set.id));
|
|
1224
|
+
return ids.length === 0 ? null : ids.join(",");
|
|
1225
|
+
};
|
|
1226
|
+
const nodes = Array.from({ length: dimension }, (_, index) => {
|
|
1227
|
+
const id = index + 1;
|
|
1228
|
+
const position = coords.get(id);
|
|
1229
|
+
const prize = prizes.get(id);
|
|
1230
|
+
const lat = geographic && position !== void 0 ? degrees(position.x, position.line) : null;
|
|
1231
|
+
const lon = geographic && position !== void 0 ? degrees(position.y, position.line) : null;
|
|
1232
|
+
return {
|
|
1233
|
+
id: String(id),
|
|
1234
|
+
x: geographic ? null : position?.x ?? null,
|
|
1235
|
+
y: geographic ? null : position?.y ?? null,
|
|
1236
|
+
lat,
|
|
1237
|
+
lon,
|
|
1238
|
+
prize: prize?.prize ?? null,
|
|
1239
|
+
probability: prize?.probability ?? null,
|
|
1240
|
+
clusters: clustersOf(id)
|
|
1241
|
+
};
|
|
1242
|
+
});
|
|
1243
|
+
const total = header.get("TPRIZE");
|
|
1244
|
+
return {
|
|
1245
|
+
meta: {
|
|
1246
|
+
name: header.get("NAME") ?? null,
|
|
1247
|
+
type,
|
|
1248
|
+
budget,
|
|
1249
|
+
edgeWeightType: weightType,
|
|
1250
|
+
totalPrize: total === void 0 ? null : numberOf(total, 1, "TPRIZE"),
|
|
1251
|
+
setPrizes: type === "COP" ? sets.map((set) => `${String(set.id)}:${String(set.prize)}`).join(",") : null
|
|
1252
|
+
},
|
|
1253
|
+
nodes
|
|
1254
|
+
};
|
|
1255
|
+
}
|
|
1256
|
+
//#endregion
|
|
918
1257
|
//#region src/parsers/parse-native.ts
|
|
919
1258
|
/** Bytes converted per String.fromCharCode call: spreading a whole file would exceed the engine's argument-count limit, and this many stays well inside every engine's. */
|
|
920
1259
|
const LATIN1_CHUNK = 32768;
|
|
@@ -971,6 +1310,9 @@ function parseNative(bytes, parser) {
|
|
|
971
1310
|
if (parser.format === "matrix-market") return parseMatrixMarket(text);
|
|
972
1311
|
if (parser.format === "gml") return parseGml(text);
|
|
973
1312
|
if (parser.format === "solomon") return parseSolomon(text);
|
|
1313
|
+
if (parser.format === "top") return parseTop(text);
|
|
1314
|
+
if (parser.format === "toptw") return parseToptw(text);
|
|
1315
|
+
if (parser.format === "tsplib") return parseTsplib(text);
|
|
974
1316
|
return parsePajek(text);
|
|
975
1317
|
}
|
|
976
1318
|
/** The ustar header layout (POSIX.1-1988, pax(1) "ustar Interchange Format"): each field's byte offset and length. */
|
|
@@ -1507,6 +1849,8 @@ const REDIRECTS = new Set(Object.values({
|
|
|
1507
1849
|
}));
|
|
1508
1850
|
/** What the downloader says it is, so a server operator can tell where the traffic comes from. */
|
|
1509
1851
|
const USER_AGENT = "keepset (+https://github.com/Mearman/keepset)";
|
|
1852
|
+
/** What the downloader accepts: anything, as the file is the recipe's to read. Node's HTTP client sends no `Accept` header of its own, and a server that content-negotiates a download (the VRP-REP host answers 406 to a request without one) refuses it; every other HTTP client sends this, and RFC 9110 reads an absent header as the same. */
|
|
1853
|
+
const ACCEPT = "*/*";
|
|
1510
1854
|
/** The failure of a connection that sent nothing for the stall time. */
|
|
1511
1855
|
var StalledError = class extends KeepsetError {};
|
|
1512
1856
|
/**
|
|
@@ -1531,7 +1875,10 @@ async function get(url, signal, stall) {
|
|
|
1531
1875
|
let answered;
|
|
1532
1876
|
const request = send(url, {
|
|
1533
1877
|
method: "GET",
|
|
1534
|
-
headers: {
|
|
1878
|
+
headers: {
|
|
1879
|
+
accept: ACCEPT,
|
|
1880
|
+
"user-agent": USER_AGENT
|
|
1881
|
+
},
|
|
1535
1882
|
...signal === void 0 ? {} : { signal }
|
|
1536
1883
|
}, (response) => {
|
|
1537
1884
|
answered = response;
|
package/dist-cli/keepset.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { KeepsetError, NAME_SEPARATOR, countTarget, getDataset, listDatasets, li
|
|
|
4
4
|
import { fetchDataset, roundTripDataset } from "keepset/node";
|
|
5
5
|
import { parseArgs } from "node:util";
|
|
6
6
|
//#region package.json
|
|
7
|
-
var version = "0.
|
|
7
|
+
var version = "0.26.0";
|
|
8
8
|
const usage = `Usage: keepset <command> [options]
|
|
9
9
|
|
|
10
10
|
Commands:
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"$defs":{"Crosswalk":{"$ref":"https://cdn.jsdelivr.net/npm/twindex@0.1.4/schemas/twindex.schema.json"},"Entry":{"additionalProperties":false,"properties":{"aliases":{"items":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*(?:\\/[A-Za-z0-9][A-Za-z0-9._-]*)*$","type":"string"},"minItems":1,"type":"array"},"category":{"enum":["graph/v1","or/v1","or-set/v1"],"type":"string"},"citations":{"items":{"additionalProperties":false,"properties":{"doi":{"pattern":"^10\\.\\d{4,9}\\/\\S+$","type":"string"},"text":{"minLength":1,"type":"string"},"url":{"format":"uri","type":"string"}},"required":["text"],"type":"object"},"type":"array"},"crosswalk":{"anyOf":[{"$ref":"#/$defs/Crosswalk"},{"additionalProperties":false,"properties":{"file":{"type":"string"}},"required":["file"],"type":"object"}]},"description":{"minLength":1,"type":"string"},"domain":{"minLength":1,"type":"string"},"expectedCounts":{"additionalProperties":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"propertyNames":{"pattern":"^[A-Za-z][A-Za-z0-9]*$","type":"string"},"type":"object"},"id":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$","type":"string"},"licence":{"oneOf":[{"additionalProperties":false,"properties":{"id":{"pattern":"^[A-Za-z0-9][A-Za-z0-9.+-]*$","type":"string"},"kind":{"const":"spdx","type":"string"}},"required":["kind","id"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"custom","type":"string"},"name":{"minLength":1,"type":"string"},"url":{"format":"uri","type":"string"}},"required":["kind","name","url"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"unrecorded","type":"string"}},"required":["kind"],"type":"object"}]},"name":{"minLength":1,"type":"string"},"namespace":{"items":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$","type":"string"},"minItems":1,"type":"array"},"properties":{"additionalProperties":{"type":["string","number","boolean","null"]},"propertyNames":{"pattern":"^[A-Za-z][A-Za-z0-9]*$","type":"string"},"type":"object"},"recipe":{"oneOf":[{"additionalProperties":false,"properties":{"archive":{"anyOf":[{"additionalProperties":false,"properties":{"kind":{"const":"none","type":"string"}},"required":["kind"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"gzip","type":"string"}},"required":["kind"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"enum":["zip","tar","tar.gz"],"type":"string"},"member":{"anyOf":[{"additionalProperties":false,"properties":{"path":{"type":"string"}},"required":["path"],"type":"object"},{"additionalProperties":false,"properties":{"extensions":{"items":{"pattern":"^\\.[A-Za-z0-9][A-Za-z0-9.]*$","type":"string"},"minItems":1,"type":"array"}},"required":["extensions"],"type":"object"}]}},"required":["kind","member"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"enum":["zip","tar","tar.gz"],"type":"string"},"members":{"anyOf":[{"additionalProperties":false,"properties":{"path":{"type":"string"}},"required":["path"],"type":"object"},{"additionalProperties":false,"properties":{"extensions":{"items":{"pattern":"^\\.[A-Za-z0-9][A-Za-z0-9.]*$","type":"string"},"minItems":1,"type":"array"}},"required":["extensions"],"type":"object"}]}},"required":["kind","members"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"xlsx","type":"string"},"sheet":{"minLength":1,"type":"string"}},"required":["kind","sheet"],"type":"object"}]},"paging":{"oneOf":[{"additionalProperties":false,"properties":{"kind":{"const":"arcgis-query","type":"string"},"orderBy":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","type":"string"}},"required":["kind","orderBy"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"socrata-resource","type":"string"},"pageSize":{"maximum":9007199254740991,"minimum":1,"type":"integer"}},"required":["kind","pageSize"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"ckan-datastore","type":"string"},"pageSize":{"maximum":9007199254740991,"minimum":1,"type":"integer"}},"required":["kind","pageSize"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"openfema","type":"string"},"pageSize":{"maximum":9007199254740991,"minimum":1,"type":"integer"}},"required":["kind","pageSize"],"type":"object"}]},"parser":{"oneOf":[{"additionalProperties":false,"properties":{"commentPrefixes":{"items":{"minLength":1,"type":"string"},"type":"array"},"delimiter":{"enum":["detect","whitespace","tab","comma","space"],"type":"string"},"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"edge-list","type":"string"},"skipLines":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"sourceColumn":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"targetColumn":{"maximum":9007199254740991,"minimum":0,"type":"integer"}},"required":["format","encoding","delimiter","skipLines","commentPrefixes","sourceColumn","targetColumn"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"matrix-market","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"gml","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"pajek","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"solomon","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"columns":{"items":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"type":"array"},"delimiter":{"enum":["comma","tab","semicolon"],"type":"string"},"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"csv-table","type":"string"},"idColumn":{"anyOf":[{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},{"type":"null"}]},"nullValues":{"items":{"minLength":1,"type":"string"},"type":"array"},"numericColumns":{"items":{"additionalProperties":false,"properties":{"column":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"factor":{"exclusiveMinimum":0,"type":"number"}},"required":["column","factor"],"type":"object"},"type":"array"},"skipLines":{"maximum":9007199254740991,"minimum":0,"type":"integer"}},"required":["format","encoding","delimiter","skipLines","idColumn","numericColumns"],"type":"object"},{"additionalProperties":false,"properties":{"columns":{"items":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"minItems":1,"type":"array"},"dateColumns":{"items":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"type":"array"},"encoding":{"const":"utf-8","type":"string"},"format":{"const":"geojson","type":"string"},"idColumn":{"anyOf":[{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},{"type":"null"}]},"numericColumns":{"items":{"additionalProperties":false,"properties":{"column":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"factor":{"exclusiveMinimum":0,"type":"number"}},"required":["column","factor"],"type":"object"},"type":"array"}},"required":["format","encoding","idColumn","numericColumns","dateColumns","columns"],"type":"object"}]},"source":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"status":{"const":"fetchable","type":"string"}},"required":["status","source","archive","parser"],"type":"object"},{"additionalProperties":false,"properties":{"reason":{"minLength":1,"type":"string"},"status":{"const":"not-fetchable","type":"string"}},"required":["status","reason"],"type":"object"}]},"sources":{"items":{"additionalProperties":false,"properties":{"retrieved":{"format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","type":"string"},"snapshot":{"additionalProperties":false,"properties":{"timestamp":{"pattern":"^\\d{8}(?:\\d{6})?$","type":"string"},"url":{"format":"uri","type":"string"}},"required":["url","timestamp"],"type":"object"},"status":{"enum":["live","dead"],"type":"string"},"url":{"format":"uri","type":"string"}},"required":["url","retrieved","status"],"type":"object"},"minItems":1,"type":"array"},"tags":{"items":{"minLength":1,"type":"string"},"type":"array"}},"required":["id","name","tags","category","sources","licence","citations","recipe","crosswalk","expectedCounts","properties"],"type":"object"}},"$id":"https://cdn.jsdelivr.net/npm/keepset@0.
|
|
1
|
+
{"$defs":{"Crosswalk":{"$ref":"https://cdn.jsdelivr.net/npm/twindex@0.1.4/schemas/twindex.schema.json"},"Entry":{"additionalProperties":false,"properties":{"aliases":{"items":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*(?:\\/[A-Za-z0-9][A-Za-z0-9._-]*)*$","type":"string"},"minItems":1,"type":"array"},"category":{"enum":["graph/v1","or/v1","or-set/v1"],"type":"string"},"citations":{"items":{"additionalProperties":false,"properties":{"doi":{"pattern":"^10\\.\\d{4,9}\\/\\S+$","type":"string"},"text":{"minLength":1,"type":"string"},"url":{"format":"uri","type":"string"}},"required":["text"],"type":"object"},"type":"array"},"crosswalk":{"anyOf":[{"$ref":"#/$defs/Crosswalk"},{"additionalProperties":false,"properties":{"file":{"type":"string"}},"required":["file"],"type":"object"}]},"description":{"minLength":1,"type":"string"},"domain":{"minLength":1,"type":"string"},"expectedCounts":{"additionalProperties":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"propertyNames":{"pattern":"^[A-Za-z][A-Za-z0-9]*$","type":"string"},"type":"object"},"id":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$","type":"string"},"licence":{"oneOf":[{"additionalProperties":false,"properties":{"id":{"pattern":"^[A-Za-z0-9][A-Za-z0-9.+-]*$","type":"string"},"kind":{"const":"spdx","type":"string"}},"required":["kind","id"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"custom","type":"string"},"name":{"minLength":1,"type":"string"},"url":{"format":"uri","type":"string"}},"required":["kind","name","url"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"unrecorded","type":"string"}},"required":["kind"],"type":"object"}]},"name":{"minLength":1,"type":"string"},"namespace":{"items":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$","type":"string"},"minItems":1,"type":"array"},"properties":{"additionalProperties":{"type":["string","number","boolean","null"]},"propertyNames":{"pattern":"^[A-Za-z][A-Za-z0-9]*$","type":"string"},"type":"object"},"recipe":{"oneOf":[{"additionalProperties":false,"properties":{"archive":{"anyOf":[{"additionalProperties":false,"properties":{"kind":{"const":"none","type":"string"}},"required":["kind"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"gzip","type":"string"}},"required":["kind"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"enum":["zip","tar","tar.gz"],"type":"string"},"member":{"anyOf":[{"additionalProperties":false,"properties":{"path":{"type":"string"}},"required":["path"],"type":"object"},{"additionalProperties":false,"properties":{"extensions":{"items":{"pattern":"^\\.[A-Za-z0-9][A-Za-z0-9.]*$","type":"string"},"minItems":1,"type":"array"}},"required":["extensions"],"type":"object"}]}},"required":["kind","member"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"enum":["zip","tar","tar.gz"],"type":"string"},"members":{"anyOf":[{"additionalProperties":false,"properties":{"path":{"type":"string"}},"required":["path"],"type":"object"},{"additionalProperties":false,"properties":{"extensions":{"items":{"pattern":"^\\.[A-Za-z0-9][A-Za-z0-9.]*$","type":"string"},"minItems":1,"type":"array"}},"required":["extensions"],"type":"object"}]}},"required":["kind","members"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"xlsx","type":"string"},"sheet":{"minLength":1,"type":"string"}},"required":["kind","sheet"],"type":"object"}]},"paging":{"oneOf":[{"additionalProperties":false,"properties":{"kind":{"const":"arcgis-query","type":"string"},"orderBy":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","type":"string"}},"required":["kind","orderBy"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"socrata-resource","type":"string"},"pageSize":{"maximum":9007199254740991,"minimum":1,"type":"integer"}},"required":["kind","pageSize"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"ckan-datastore","type":"string"},"pageSize":{"maximum":9007199254740991,"minimum":1,"type":"integer"}},"required":["kind","pageSize"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"openfema","type":"string"},"pageSize":{"maximum":9007199254740991,"minimum":1,"type":"integer"}},"required":["kind","pageSize"],"type":"object"}]},"parser":{"oneOf":[{"additionalProperties":false,"properties":{"commentPrefixes":{"items":{"minLength":1,"type":"string"},"type":"array"},"delimiter":{"enum":["detect","whitespace","tab","comma","space"],"type":"string"},"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"edge-list","type":"string"},"skipLines":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"sourceColumn":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"targetColumn":{"maximum":9007199254740991,"minimum":0,"type":"integer"}},"required":["format","encoding","delimiter","skipLines","commentPrefixes","sourceColumn","targetColumn"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"matrix-market","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"gml","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"pajek","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"solomon","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"top","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"toptw","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"tsplib","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"columns":{"items":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"type":"array"},"delimiter":{"enum":["comma","tab","semicolon"],"type":"string"},"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"csv-table","type":"string"},"idColumn":{"anyOf":[{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},{"type":"null"}]},"nullValues":{"items":{"minLength":1,"type":"string"},"type":"array"},"numericColumns":{"items":{"additionalProperties":false,"properties":{"column":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"factor":{"exclusiveMinimum":0,"type":"number"}},"required":["column","factor"],"type":"object"},"type":"array"},"skipLines":{"maximum":9007199254740991,"minimum":0,"type":"integer"}},"required":["format","encoding","delimiter","skipLines","idColumn","numericColumns"],"type":"object"},{"additionalProperties":false,"properties":{"columns":{"items":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"minItems":1,"type":"array"},"dateColumns":{"items":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"type":"array"},"encoding":{"const":"utf-8","type":"string"},"format":{"const":"geojson","type":"string"},"idColumn":{"anyOf":[{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},{"type":"null"}]},"numericColumns":{"items":{"additionalProperties":false,"properties":{"column":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"factor":{"exclusiveMinimum":0,"type":"number"}},"required":["column","factor"],"type":"object"},"type":"array"}},"required":["format","encoding","idColumn","numericColumns","dateColumns","columns"],"type":"object"}]},"source":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"status":{"const":"fetchable","type":"string"}},"required":["status","source","archive","parser"],"type":"object"},{"additionalProperties":false,"properties":{"reason":{"minLength":1,"type":"string"},"status":{"const":"not-fetchable","type":"string"}},"required":["status","reason"],"type":"object"}]},"sources":{"items":{"additionalProperties":false,"properties":{"retrieved":{"format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","type":"string"},"snapshot":{"additionalProperties":false,"properties":{"timestamp":{"pattern":"^\\d{8}(?:\\d{6})?$","type":"string"},"url":{"format":"uri","type":"string"}},"required":["url","timestamp"],"type":"object"},"status":{"enum":["live","dead"],"type":"string"},"url":{"format":"uri","type":"string"}},"required":["url","retrieved","status"],"type":"object"},"minItems":1,"type":"array"},"tags":{"items":{"minLength":1,"type":"string"},"type":"array"}},"required":["id","name","tags","category","sources","licence","citations","recipe","crosswalk","expectedCounts","properties"],"type":"object"}},"$id":"https://cdn.jsdelivr.net/npm/keepset@0.26.0/schemas/entry.schema.json","$ref":"#/$defs/Entry","$schema":"https://json-schema.org/draft/2020-12/schema"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"$defs":{"Manifest":{"additionalProperties":false,"properties":{"description":{"minLength":1,"type":"string"},"id":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$","type":"string"},"lineage":{"additionalProperties":false,"properties":{"catalogue":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$","type":"string"},"repository":{"format":"uri","type":"string"},"version":{"pattern":"^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$","type":"string"}},"required":["catalogue","version","repository"],"type":"object"},"name":{"minLength":1,"type":"string"},"namespaceAliases":{"additionalProperties":{"items":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$","type":"string"},"minItems":1,"type":"array"},"propertyNames":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$","type":"string"},"type":"object"},"repository":{"format":"uri","type":"string"},"version":{"pattern":"^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$","type":"string"}},"required":["id","name","description","version","repository"],"type":"object"}},"$id":"https://cdn.jsdelivr.net/npm/keepset@0.
|
|
1
|
+
{"$defs":{"Manifest":{"additionalProperties":false,"properties":{"description":{"minLength":1,"type":"string"},"id":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$","type":"string"},"lineage":{"additionalProperties":false,"properties":{"catalogue":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$","type":"string"},"repository":{"format":"uri","type":"string"},"version":{"pattern":"^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$","type":"string"}},"required":["catalogue","version","repository"],"type":"object"},"name":{"minLength":1,"type":"string"},"namespaceAliases":{"additionalProperties":{"items":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$","type":"string"},"minItems":1,"type":"array"},"propertyNames":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$","type":"string"},"type":"object"},"repository":{"format":"uri","type":"string"},"version":{"pattern":"^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$","type":"string"}},"required":["id","name","description","version","repository"],"type":"object"}},"$id":"https://cdn.jsdelivr.net/npm/keepset@0.26.0/schemas/manifest.schema.json","$ref":"#/$defs/Manifest","$schema":"https://json-schema.org/draft/2020-12/schema"}
|