@gmb/bitmark-parser-generator 5.22.0 → 5.23.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.
@@ -31,6 +31,7 @@ __export(index_exports, {
31
31
  BitmarkStringGenerator: () => BitmarkStringGenerator,
32
32
  BitmarkVersion: () => BitmarkVersion,
33
33
  BodyTextFormat: () => BodyTextFormat,
34
+ BoundingBoxIndex: () => BoundingBoxIndex,
34
35
  Builder: () => Builder,
35
36
  CardSetVersion: () => CardSetVersion,
36
37
  InfoFormat: () => InfoFormat,
@@ -326,6 +327,7 @@ var BitType2 = {
326
327
  footNote: "foot-note",
327
328
  formFreeText: "form-free-text",
328
329
  formula: "formula",
330
+ formulaImage: "formula-image",
329
331
  gapText: "gap-text",
330
332
  gapTextInstructionGrouped: "gap-text-instruction-grouped",
331
333
  glossaryTerm: "glossary-term",
@@ -750,8 +752,10 @@ var TagFormat = {
750
752
  // If the value is treated as a boolean
751
753
  invertedBoolean: "invertedBoolean",
752
754
  // If the value is treated as a boolean with the value inverted (e.g. isLongAnswer ==> isShortAnswer = false)
753
- enumeration: "enumeration"
755
+ enumeration: "enumeration",
754
756
  // If the value is treated as an enumeration (the value is a string that must be one of a predefined set of values)
757
+ coordinates: "coordinates"
758
+ // Comma-separated list of 4 numbers (e.g. bounding-box x, y, x1, y1)
755
759
  };
756
760
 
757
761
  // src/model/enum/TextFormat.ts
@@ -836,7 +840,11 @@ var AbstractTagConfig = class {
836
840
  // Default: 0
837
841
  __publicField(this, "chain");
838
842
  __publicField(this, "jsonKey");
839
- // If the json key is different from the tag
843
+ // Legacy string-form jsonKey
844
+ __publicField(this, "exportJsonKey");
845
+ // New JSON-pattern jsonKey (export-only)
846
+ __publicField(this, "hasExportJsonKey");
847
+ // True iff exportJsonKey was explicitly set
840
848
  __publicField(this, "deprecated");
841
849
  this.type = params.type;
842
850
  this.configKey = params.configKey;
@@ -845,6 +853,8 @@ var AbstractTagConfig = class {
845
853
  this.minCount = params.minCount;
846
854
  this.chain = params.chain;
847
855
  this.jsonKey = params.jsonKey;
856
+ this.exportJsonKey = params.exportJsonKey;
857
+ this.hasExportJsonKey = params.hasExportJsonKey;
848
858
  this.deprecated = params.deprecated;
849
859
  }
850
860
  };
@@ -854,7 +864,6 @@ var MarkupTagConfig = class extends AbstractTagConfig {
854
864
  constructor(params) {
855
865
  super({
856
866
  type: BitTagConfigKeyType.tag,
857
- jsonKey: void 0,
858
867
  ...params
859
868
  });
860
869
  __publicField(this, "type", BitTagConfigKeyType.tag);
@@ -966,8 +975,8 @@ var ResourceTagConfig = class extends AbstractTagConfig {
966
975
 
967
976
  // src/model/config/CardVariantConfig.ts
968
977
  var CardVariantConfig = class {
969
- // JSON path for body text
970
- constructor(tags2, bodyAllowed, bodyRequired, repeatCount, jsonKey) {
978
+ // Body text format. Default: bitmark++
979
+ constructor(tags2, bodyAllowed, bodyRequired, repeatCount, jsonKey, exportJsonKey, hasExportJsonKey = false, format) {
971
980
  __publicField(this, "tags");
972
981
  __publicField(this, "bodyAllowed");
973
982
  // Default: true
@@ -977,11 +986,19 @@ var CardVariantConfig = class {
977
986
  // Default: 1
978
987
  // JSON mapping fields
979
988
  __publicField(this, "jsonKey");
989
+ // JSON path for body text (legacy)
990
+ __publicField(this, "exportJsonKey");
991
+ // New JSON-pattern jsonKey
992
+ __publicField(this, "hasExportJsonKey");
993
+ __publicField(this, "format");
980
994
  this.tags = tags2;
981
995
  this.bodyAllowed = bodyAllowed == null ? true : bodyAllowed;
982
996
  this.bodyRequired = bodyRequired;
983
997
  this.repeatCount = repeatCount;
984
998
  this.jsonKey = jsonKey;
999
+ this.exportJsonKey = exportJsonKey;
1000
+ this.hasExportJsonKey = hasExportJsonKey;
1001
+ this.format = format;
985
1002
  }
986
1003
  toString(options) {
987
1004
  const opts = Object.assign({}, options);
@@ -1005,14 +1022,18 @@ ${tag.toString(opts)}`;
1005
1022
 
1006
1023
  // src/model/config/CardSideConfig.ts
1007
1024
  var CardSideConfig = class {
1008
- constructor(name, repeat, variants, jsonKey) {
1025
+ constructor(name, repeat, variants, jsonKey, exportJsonKey, hasExportJsonKey = false) {
1009
1026
  __publicField(this, "name");
1010
1027
  __publicField(this, "repeat");
1011
1028
  __publicField(this, "jsonKey");
1029
+ __publicField(this, "exportJsonKey");
1030
+ __publicField(this, "hasExportJsonKey");
1012
1031
  __publicField(this, "variants");
1013
1032
  this.name = name;
1014
1033
  this.repeat = repeat;
1015
1034
  this.jsonKey = jsonKey;
1035
+ this.exportJsonKey = exportJsonKey;
1036
+ this.hasExportJsonKey = hasExportJsonKey;
1016
1037
  this.variants = variants;
1017
1038
  }
1018
1039
  toString(options) {
@@ -1034,13 +1055,17 @@ var CardSideConfig = class {
1034
1055
 
1035
1056
  // src/model/config/CardSetConfig.ts
1036
1057
  var CardSetConfig = class {
1037
- constructor(configKey, jsonKey, sections, sides) {
1058
+ constructor(configKey, jsonKey, exportJsonKey, hasExportJsonKey, sections, sides) {
1038
1059
  __publicField(this, "configKey");
1039
1060
  __publicField(this, "jsonKey");
1061
+ __publicField(this, "exportJsonKey");
1062
+ __publicField(this, "hasExportJsonKey");
1040
1063
  __publicField(this, "sections");
1041
1064
  __publicField(this, "sides");
1042
1065
  this.configKey = configKey;
1043
1066
  this.jsonKey = jsonKey;
1067
+ this.exportJsonKey = exportJsonKey;
1068
+ this.hasExportJsonKey = hasExportJsonKey;
1044
1069
  this.sections = sections;
1045
1070
  this.sides = sides;
1046
1071
  }
@@ -1335,6 +1360,7 @@ var propertyKeys = {
1335
1360
  property_formula: "@formula",
1336
1361
  property_fullName: "@fullName",
1337
1362
  property_groupTag: "@groupTag",
1363
+ property_gUri: "@gUri",
1338
1364
  property_handInAcceptFileType: "@handInAcceptFileType",
1339
1365
  property_handInInstruction: "@handInInstruction",
1340
1366
  property_handInRequirement: "@handInRequirement",
@@ -1470,6 +1496,7 @@ var propertyKeys = {
1470
1496
  property_siteName: "@siteName",
1471
1497
  property_size: "@size",
1472
1498
  property_slug: "@slug",
1499
+ property_sourceBB: "@sourceBB",
1473
1500
  property_sourceDocument: "@sourceDocument",
1474
1501
  property_sourceRL: "@sourceRL",
1475
1502
  property_spaceId: "@spaceId",
@@ -2223,25 +2250,29 @@ var CARDSETS = {
2223
2250
  //
2224
2251
  [CardSetConfigKey.flashcard]: {
2225
2252
  jsonKey: "cards",
2253
+ exportJsonKey: { cards: "$" },
2226
2254
  sides: [
2227
2255
  {
2228
2256
  name: "question",
2229
2257
  variants: [
2230
2258
  {
2231
2259
  jsonKey: "question.text",
2260
+ exportJsonKey: { question: { text: "$" } },
2232
2261
  tags: [
2233
2262
  {
2234
2263
  key: ConfigKey.group_standardTags,
2235
2264
  description: "Standard tags for the flashcard."
2236
2265
  },
2237
2266
  {
2267
+ exportJsonKey: { title: "$" },
2238
2268
  key: ConfigKey.tag_title,
2239
2269
  description: "Title of the flashcard."
2240
2270
  },
2241
2271
  {
2242
2272
  key: ConfigKey.group_resourceIcon,
2243
2273
  description: "Icon resource for the flashcard.",
2244
- jsonKey: "question.icon|resource(type=image, key=image)"
2274
+ jsonKey: "question.icon|resource(type=image, key=image)",
2275
+ exportJsonKey: { question: { icon: { type: "image", image: { src: "$" } } } }
2245
2276
  }
2246
2277
  ]
2247
2278
  }
@@ -2252,37 +2283,45 @@ var CARDSETS = {
2252
2283
  variants: [
2253
2284
  {
2254
2285
  jsonKey: "answer.text",
2286
+ exportJsonKey: { answer: { text: "$" } },
2255
2287
  tags: [
2256
2288
  {
2257
2289
  key: ConfigKey.group_standardTags,
2258
2290
  description: "Standard tags for the flashcard."
2259
2291
  },
2260
2292
  {
2293
+ exportJsonKey: { title: "$" },
2261
2294
  key: ConfigKey.tag_title,
2262
2295
  description: "Title of the flashcard."
2263
2296
  },
2264
2297
  {
2265
2298
  key: ConfigKey.group_resourceIcon,
2266
2299
  description: "Icon resource for the flashcard.",
2267
- jsonKey: "answer.icon|resource(type=image, key=image)"
2300
+ jsonKey: "answer.icon|resource(type=image, key=image)",
2301
+ exportJsonKey: { answer: { icon: { type: "image", image: { src: "$" } } } }
2268
2302
  }
2269
2303
  ]
2270
2304
  },
2271
2305
  {
2272
2306
  jsonKey: "alternativeAnswers[].text",
2307
+ exportJsonKey: { alternativeAnswers: [{ text: "$" }] },
2273
2308
  tags: [
2274
2309
  {
2275
2310
  key: ConfigKey.group_standardTags,
2276
2311
  description: "Standard tags for the flashcard."
2277
2312
  },
2278
2313
  {
2314
+ exportJsonKey: { title: "$" },
2279
2315
  key: ConfigKey.tag_title,
2280
2316
  description: "Title of the flashcard."
2281
2317
  },
2282
2318
  {
2283
2319
  key: ConfigKey.group_resourceIcon,
2284
2320
  description: "Icon resource for the flashcard.",
2285
- jsonKey: "alternativeAnswers[].icon|resource(type=image, key=image)"
2321
+ jsonKey: "alternativeAnswers[].icon|resource(type=image, key=image)",
2322
+ exportJsonKey: {
2323
+ alternativeAnswers: [{ icon: { type: "image", image: { src: "$" } } }]
2324
+ }
2286
2325
  }
2287
2326
  ],
2288
2327
  repeatCount: Count.infinity
@@ -2296,12 +2335,14 @@ var CARDSETS = {
2296
2335
  //
2297
2336
  [CardSetConfigKey.definitionList]: {
2298
2337
  jsonKey: "definitions",
2338
+ exportJsonKey: { definitions: "$" },
2299
2339
  sides: [
2300
2340
  {
2301
2341
  name: "term",
2302
2342
  variants: [
2303
2343
  {
2304
2344
  jsonKey: "term.text",
2345
+ exportJsonKey: { term: { text: "$" } },
2305
2346
  tags: [
2306
2347
  {
2307
2348
  key: ConfigKey.group_standardTags,
@@ -2311,13 +2352,15 @@ var CARDSETS = {
2311
2352
  key: ConfigKey.tag_title,
2312
2353
  description: "Title of the definition.",
2313
2354
  format: TagFormat.plainText,
2314
- jsonKey: "^heading.forKeys"
2355
+ jsonKey: "^heading.forKeys",
2356
+ exportJsonKey: { "@bit": { heading: { forKeys: "$" } } }
2315
2357
  },
2316
2358
  {
2317
2359
  key: ConfigKey.group_resourceIcon,
2318
2360
  description: "Icon resource for the definition.",
2319
2361
  format: TagFormat.plainText,
2320
- jsonKey: "term.icon|resource(type=image, key=image)"
2362
+ jsonKey: "term.icon|resource(type=image, key=image)",
2363
+ exportJsonKey: { term: { icon: { type: "image", image: { src: "$" } } } }
2321
2364
  }
2322
2365
  ]
2323
2366
  }
@@ -2328,6 +2371,7 @@ var CARDSETS = {
2328
2371
  variants: [
2329
2372
  {
2330
2373
  jsonKey: "definition.text",
2374
+ exportJsonKey: { definition: { text: "$" } },
2331
2375
  tags: [
2332
2376
  {
2333
2377
  key: ConfigKey.group_standardTags,
@@ -2337,30 +2381,37 @@ var CARDSETS = {
2337
2381
  key: ConfigKey.tag_title,
2338
2382
  description: "Title of the definition.",
2339
2383
  format: TagFormat.plainText,
2340
- jsonKey: "^heading.forValues"
2384
+ jsonKey: "^heading.forValues",
2385
+ exportJsonKey: { "@bit": { heading: { forValues: "$" } } }
2341
2386
  },
2342
2387
  {
2343
2388
  key: ConfigKey.group_resourceIcon,
2344
2389
  description: "Icon resource for the definition.",
2345
- jsonKey: "definition.icon|resource(type=image, key=image)"
2390
+ jsonKey: "definition.icon|resource(type=image, key=image)",
2391
+ exportJsonKey: { definition: { icon: { type: "image", image: { src: "$" } } } }
2346
2392
  }
2347
2393
  ]
2348
2394
  },
2349
2395
  {
2350
2396
  jsonKey: "alternativeDefinitions[].text",
2397
+ exportJsonKey: { alternativeDefinitions: [{ text: "$" }] },
2351
2398
  tags: [
2352
2399
  {
2353
2400
  key: ConfigKey.group_standardTags,
2354
2401
  description: "Standard tags for the definition."
2355
2402
  },
2356
2403
  {
2404
+ exportJsonKey: { title: "$" },
2357
2405
  key: ConfigKey.tag_title,
2358
2406
  description: "Title of the definition."
2359
2407
  },
2360
2408
  {
2361
2409
  key: ConfigKey.group_resourceIcon,
2362
2410
  description: "Icon resource for the definition.",
2363
- jsonKey: "alternativeDefinitions[].icon|resource(type=image, key=image)"
2411
+ jsonKey: "alternativeDefinitions[].icon|resource(type=image, key=image)",
2412
+ exportJsonKey: {
2413
+ alternativeDefinitions: [{ icon: { type: "image", image: { src: "$" } } }]
2414
+ }
2364
2415
  }
2365
2416
  ],
2366
2417
  repeatCount: Count.infinity
@@ -2374,12 +2425,14 @@ var CARDSETS = {
2374
2425
  //
2375
2426
  [CardSetConfigKey.matchPairs]: {
2376
2427
  jsonKey: "pairs",
2428
+ exportJsonKey: { pairs: "$" },
2377
2429
  sides: [
2378
2430
  {
2379
2431
  name: "key",
2380
2432
  variants: [
2381
2433
  {
2382
2434
  jsonKey: "key",
2435
+ exportJsonKey: { key: "$" },
2383
2436
  tags: [
2384
2437
  {
2385
2438
  key: ConfigKey.group_standardTags,
@@ -2389,22 +2442,29 @@ var CARDSETS = {
2389
2442
  key: ConfigKey.tag_title,
2390
2443
  description: "Title of the match pair.",
2391
2444
  format: TagFormat.plainText,
2392
- jsonKey: "^heading.forKeys"
2445
+ jsonKey: "^heading.forKeys",
2446
+ exportJsonKey: { "@bit": { heading: { forKeys: "$" } } }
2393
2447
  },
2394
2448
  {
2395
2449
  key: ConfigKey.property_isCaseSensitive,
2450
+ exportJsonKey: [
2451
+ { "@absent": { isCaseSensitive: "$ancestor" } },
2452
+ { isCaseSensitive: "$" }
2453
+ ],
2396
2454
  description: "Property to indicate if the match is case sensitive.",
2397
2455
  format: TagFormat.boolean
2398
2456
  },
2399
2457
  {
2400
2458
  key: ConfigKey.resource_audio,
2401
2459
  description: "Audio resource for the match pair.",
2402
- jsonKey: "keyAudio"
2460
+ jsonKey: "keyAudio",
2461
+ exportJsonKey: { keyAudio: "$" }
2403
2462
  },
2404
2463
  {
2405
2464
  key: ConfigKey.resource_image,
2406
2465
  description: "Image resource for the match pair.",
2407
- jsonKey: "keyImage"
2466
+ jsonKey: "keyImage",
2467
+ exportJsonKey: { keyImage: "$" }
2408
2468
  }
2409
2469
  ]
2410
2470
  }
@@ -2416,6 +2476,7 @@ var CARDSETS = {
2416
2476
  variants: [
2417
2477
  {
2418
2478
  jsonKey: "values[]",
2479
+ exportJsonKey: { values: ["$"] },
2419
2480
  tags: [
2420
2481
  {
2421
2482
  key: ConfigKey.group_standardTags,
@@ -2425,10 +2486,15 @@ var CARDSETS = {
2425
2486
  key: ConfigKey.tag_title,
2426
2487
  description: "Title of the match pair.",
2427
2488
  format: TagFormat.plainText,
2428
- jsonKey: "^heading.forValues"
2489
+ jsonKey: "^heading.forValues",
2490
+ exportJsonKey: { "@bit": { heading: { forValues: "$" } } }
2429
2491
  },
2430
2492
  {
2431
2493
  key: ConfigKey.property_isCaseSensitive,
2494
+ exportJsonKey: [
2495
+ { "@absent": { isCaseSensitive: "$ancestor" } },
2496
+ { isCaseSensitive: "$" }
2497
+ ],
2432
2498
  description: "Property to indicate if the match is case sensitive.",
2433
2499
  format: TagFormat.boolean
2434
2500
  }
@@ -2444,12 +2510,14 @@ var CARDSETS = {
2444
2510
  //
2445
2511
  [CardSetConfigKey.matchAudioPairs]: {
2446
2512
  jsonKey: "pairs",
2513
+ exportJsonKey: { pairs: "$" },
2447
2514
  sides: [
2448
2515
  {
2449
2516
  name: "key",
2450
2517
  variants: [
2451
2518
  {
2452
2519
  jsonKey: "key",
2520
+ exportJsonKey: { key: "$" },
2453
2521
  tags: [
2454
2522
  {
2455
2523
  key: ConfigKey.group_standardTags,
@@ -2459,12 +2527,14 @@ var CARDSETS = {
2459
2527
  key: ConfigKey.tag_title,
2460
2528
  description: "Title of the audio match pair.",
2461
2529
  format: TagFormat.plainText,
2462
- jsonKey: "^heading.forKeys"
2530
+ jsonKey: "^heading.forKeys",
2531
+ exportJsonKey: { "@bit": { heading: { forKeys: "$" } } }
2463
2532
  },
2464
2533
  {
2465
2534
  key: ConfigKey.resource_audio,
2466
2535
  description: "Audio resource for the match pair.",
2467
- jsonKey: "keyAudio"
2536
+ jsonKey: "keyAudio",
2537
+ exportJsonKey: { keyAudio: "$" }
2468
2538
  }
2469
2539
  ]
2470
2540
  }
@@ -2476,6 +2546,7 @@ var CARDSETS = {
2476
2546
  variants: [
2477
2547
  {
2478
2548
  jsonKey: "values[]",
2549
+ exportJsonKey: { values: ["$"] },
2479
2550
  tags: [
2480
2551
  {
2481
2552
  key: ConfigKey.group_standardTags,
@@ -2485,7 +2556,8 @@ var CARDSETS = {
2485
2556
  key: ConfigKey.tag_title,
2486
2557
  description: "Title of the audio match pair.",
2487
2558
  format: TagFormat.plainText,
2488
- jsonKey: "^heading.forValues"
2559
+ jsonKey: "^heading.forValues",
2560
+ exportJsonKey: { "@bit": { heading: { forValues: "$" } } }
2489
2561
  },
2490
2562
  {
2491
2563
  key: ConfigKey.resource_audio,
@@ -2503,12 +2575,14 @@ var CARDSETS = {
2503
2575
  //
2504
2576
  [CardSetConfigKey.matchImagePairs]: {
2505
2577
  jsonKey: "pairs",
2578
+ exportJsonKey: { pairs: "$" },
2506
2579
  sides: [
2507
2580
  {
2508
2581
  name: "key",
2509
2582
  variants: [
2510
2583
  {
2511
2584
  jsonKey: "key",
2585
+ exportJsonKey: { key: "$" },
2512
2586
  tags: [
2513
2587
  {
2514
2588
  key: ConfigKey.group_standardTags,
@@ -2518,12 +2592,14 @@ var CARDSETS = {
2518
2592
  key: ConfigKey.tag_title,
2519
2593
  description: "Title of the image match pair.",
2520
2594
  format: TagFormat.plainText,
2521
- jsonKey: "^heading.forKeys"
2595
+ jsonKey: "^heading.forKeys",
2596
+ exportJsonKey: { "@bit": { heading: { forKeys: "$" } } }
2522
2597
  },
2523
2598
  {
2524
2599
  key: ConfigKey.resource_image,
2525
2600
  description: "Image resource for the match pair.",
2526
- jsonKey: "keyImage"
2601
+ jsonKey: "keyImage",
2602
+ exportJsonKey: { keyImage: "$" }
2527
2603
  }
2528
2604
  ]
2529
2605
  }
@@ -2535,6 +2611,7 @@ var CARDSETS = {
2535
2611
  variants: [
2536
2612
  {
2537
2613
  jsonKey: "values[]",
2614
+ exportJsonKey: { values: ["$"] },
2538
2615
  tags: [
2539
2616
  {
2540
2617
  key: ConfigKey.group_standardTags,
@@ -2544,7 +2621,8 @@ var CARDSETS = {
2544
2621
  key: ConfigKey.tag_title,
2545
2622
  description: "Title of the image match pair.",
2546
2623
  format: TagFormat.plainText,
2547
- jsonKey: "^heading.forValues"
2624
+ jsonKey: "^heading.forValues",
2625
+ exportJsonKey: { "@bit": { heading: { forValues: "$" } } }
2548
2626
  },
2549
2627
  {
2550
2628
  key: ConfigKey.resource_image,
@@ -2562,12 +2640,14 @@ var CARDSETS = {
2562
2640
  //
2563
2641
  [CardSetConfigKey.matchMatrix]: {
2564
2642
  jsonKey: "matrix",
2643
+ exportJsonKey: { matrix: "$" },
2565
2644
  sides: [
2566
2645
  {
2567
2646
  name: "key",
2568
2647
  variants: [
2569
2648
  {
2570
2649
  jsonKey: "key",
2650
+ exportJsonKey: { key: "$" },
2571
2651
  tags: [
2572
2652
  {
2573
2653
  key: ConfigKey.group_standardItemLeadInstructionHint,
@@ -2575,6 +2655,11 @@ var CARDSETS = {
2575
2655
  },
2576
2656
  {
2577
2657
  key: ConfigKey.property_example,
2658
+ exportJsonKey: [
2659
+ { "@keyonly": { isExample: true, "@bit": { isExample: true } } },
2660
+ { "@absent": { isExample: true, "@bit": { isExample: true } } },
2661
+ { isExample: true, example: "$", "@bit": { isExample: true } }
2662
+ ],
2578
2663
  description: "Example text for the match matrix.",
2579
2664
  format: TagFormat.plainText
2580
2665
  },
@@ -2582,10 +2667,15 @@ var CARDSETS = {
2582
2667
  key: ConfigKey.tag_title,
2583
2668
  description: "Title of the match matrix.",
2584
2669
  format: TagFormat.plainText,
2585
- jsonKey: "^heading.forKeys"
2670
+ jsonKey: "^heading.forKeys",
2671
+ exportJsonKey: { "@bit": { heading: { forKeys: "$" } } }
2586
2672
  },
2587
2673
  {
2588
2674
  key: ConfigKey.property_isCaseSensitive,
2675
+ exportJsonKey: [
2676
+ { "@absent": { isCaseSensitive: "$ancestor" } },
2677
+ { isCaseSensitive: "$" }
2678
+ ],
2589
2679
  description: "Property to indicate if the match is case sensitive.",
2590
2680
  format: TagFormat.boolean
2591
2681
  }
@@ -2599,6 +2689,7 @@ var CARDSETS = {
2599
2689
  variants: [
2600
2690
  {
2601
2691
  jsonKey: "cells[{s}].values[]",
2692
+ exportJsonKey: { cells: { $s: { values: ["$"] } } },
2602
2693
  tags: [
2603
2694
  {
2604
2695
  key: ConfigKey.group_standardItemLeadInstructionHint,
@@ -2606,6 +2697,18 @@ var CARDSETS = {
2606
2697
  },
2607
2698
  {
2608
2699
  key: ConfigKey.property_example,
2700
+ exportJsonKey: [
2701
+ {
2702
+ "@keyonly": {
2703
+ cells: { $s: { isExample: true, example: "$parent.values[0]" } },
2704
+ "@bit": { isExample: true }
2705
+ }
2706
+ },
2707
+ {
2708
+ "@absent": { cells: { $s: { isExample: true, example: "$parent.values[0]" } } }
2709
+ },
2710
+ { cells: { $s: { isExample: true, example: "$" } }, "@bit": { isExample: true } }
2711
+ ],
2609
2712
  description: "Example text for the match matrix.",
2610
2713
  format: TagFormat.plainText
2611
2714
  },
@@ -2613,10 +2716,15 @@ var CARDSETS = {
2613
2716
  key: ConfigKey.tag_title,
2614
2717
  description: "Title of the match matrix.",
2615
2718
  format: TagFormat.plainText,
2616
- jsonKey: "^heading.forValues"
2719
+ jsonKey: "^heading.forValues",
2720
+ exportJsonKey: { "@bit": { heading: { forValues: "$" } } }
2617
2721
  },
2618
2722
  {
2619
2723
  key: ConfigKey.property_isCaseSensitive,
2724
+ exportJsonKey: [
2725
+ { "@absent": { isCaseSensitive: "$ancestor" } },
2726
+ { isCaseSensitive: "$" }
2727
+ ],
2620
2728
  description: "Property to indicate if the match is case sensitive.",
2621
2729
  format: TagFormat.boolean
2622
2730
  }
@@ -2632,23 +2740,27 @@ var CARDSETS = {
2632
2740
  //
2633
2741
  [CardSetConfigKey.statements]: {
2634
2742
  jsonKey: "statements",
2743
+ exportJsonKey: { statements: "$" },
2635
2744
  sides: [
2636
2745
  {
2637
2746
  name: "statement",
2638
2747
  variants: [
2639
2748
  {
2640
2749
  jsonKey: "statement",
2750
+ exportJsonKey: { statement: "$" },
2641
2751
  tags: [
2642
2752
  {
2643
2753
  key: ConfigKey.tag_true,
2644
2754
  description: "Tag for true statements.",
2645
2755
  jsonKey: "statement|set(isCorrect=true)",
2756
+ exportJsonKey: { statement: "$", isCorrect: true },
2646
2757
  maxCount: 1
2647
2758
  },
2648
2759
  {
2649
2760
  key: ConfigKey.tag_false,
2650
2761
  description: "Tag for false statements.",
2651
2762
  jsonKey: "statement|set(isCorrect=false)",
2763
+ exportJsonKey: { statement: "$", isCorrect: false },
2652
2764
  maxCount: 1
2653
2765
  },
2654
2766
  {
@@ -2667,6 +2779,7 @@ var CARDSETS = {
2667
2779
  //
2668
2780
  [CardSetConfigKey.quiz]: {
2669
2781
  jsonKey: "quizzes",
2782
+ exportJsonKey: { quizzes: "$" },
2670
2783
  sides: [
2671
2784
  {
2672
2785
  name: "choices",
@@ -2694,6 +2807,7 @@ var CARDSETS = {
2694
2807
  //
2695
2808
  [CardSetConfigKey.feedback]: {
2696
2809
  jsonKey: "feedbacks",
2810
+ exportJsonKey: { feedbacks: "$" },
2697
2811
  sides: [
2698
2812
  {
2699
2813
  name: "choices",
@@ -2713,7 +2827,8 @@ var CARDSETS = {
2713
2827
  key: ConfigKey.tag_title,
2714
2828
  description: "Title of the feedback.",
2715
2829
  format: TagFormat.plainText,
2716
- jsonKey: "^heading.forKeys"
2830
+ jsonKey: "^heading.forKeys",
2831
+ exportJsonKey: { "@bit": { heading: { forKeys: "$" } } }
2717
2832
  }
2718
2833
  ],
2719
2834
  bodyAllowed: false
@@ -2725,6 +2840,7 @@ var CARDSETS = {
2725
2840
  variants: [
2726
2841
  {
2727
2842
  jsonKey: "reason.text",
2843
+ exportJsonKey: { reason: { text: "$" } },
2728
2844
  tags: [
2729
2845
  {
2730
2846
  key: ConfigKey.group_standardItemLeadInstructionHint,
@@ -2732,11 +2848,20 @@ var CARDSETS = {
2732
2848
  },
2733
2849
  {
2734
2850
  key: ConfigKey.property_reasonableNumOfChars,
2851
+ exportJsonKey: [
2852
+ { "@absent": { reasonableNumOfChars: "$ancestor" } },
2853
+ { reasonableNumOfChars: "$" }
2854
+ ],
2735
2855
  description: "Property for reasonable number of characters.",
2736
2856
  format: TagFormat.number
2737
2857
  },
2738
2858
  {
2739
2859
  key: ConfigKey.property_example,
2860
+ exportJsonKey: [
2861
+ { "@keyonly": { isExample: true, example: true, "@bit": { isExample: true } } },
2862
+ { "@absent": { isExample: true, example: true, "@bit": { isExample: true } } },
2863
+ { isExample: true, example: "$", "@bit": { isExample: true } }
2864
+ ],
2740
2865
  description: "Example text for the feedback.",
2741
2866
  format: TagFormat.plainText
2742
2867
  },
@@ -2744,7 +2869,8 @@ var CARDSETS = {
2744
2869
  key: ConfigKey.tag_title,
2745
2870
  description: "Title of the feedback.",
2746
2871
  format: TagFormat.plainText,
2747
- jsonKey: "^heading.forValues"
2872
+ jsonKey: "^heading.forValues",
2873
+ exportJsonKey: { "@bit": { heading: { forValues: "$" } } }
2748
2874
  }
2749
2875
  ],
2750
2876
  bodyAllowed: true
@@ -2758,21 +2884,29 @@ var CARDSETS = {
2758
2884
  //
2759
2885
  [CardSetConfigKey.questions]: {
2760
2886
  jsonKey: "questions",
2887
+ exportJsonKey: { questions: "$" },
2761
2888
  sides: [
2762
2889
  {
2763
2890
  name: "question",
2764
2891
  variants: [
2765
2892
  {
2766
2893
  jsonKey: "question",
2894
+ exportJsonKey: { question: "$" },
2767
2895
  tags: [
2768
2896
  {
2769
2897
  key: ConfigKey.property_reasonableNumOfChars,
2898
+ exportJsonKey: [
2899
+ { "@absent": { reasonableNumOfChars: "$ancestor" } },
2900
+ { reasonableNumOfChars: "$" }
2901
+ ],
2770
2902
  description: "Property for reasonable number of characters.",
2771
2903
  format: TagFormat.number
2772
2904
  },
2773
2905
  {
2906
+ exportJsonKey: { sampleSolution: "$" },
2774
2907
  key: ConfigKey.tag_sampleSolution,
2775
- description: "Sample solution for the question."
2908
+ description: "Sample solution for the question.",
2909
+ format: TagFormat.plainText
2776
2910
  },
2777
2911
  {
2778
2912
  key: ConfigKey.property_sampleSolution,
@@ -2812,6 +2946,7 @@ var CARDSETS = {
2812
2946
  variants: [
2813
2947
  {
2814
2948
  jsonKey: "elements[]",
2949
+ exportJsonKey: { elements: ["$"] },
2815
2950
  tags: [
2816
2951
  {
2817
2952
  key: ConfigKey.group_standardItemLeadInstructionHint,
@@ -2819,6 +2954,11 @@ var CARDSETS = {
2819
2954
  },
2820
2955
  {
2821
2956
  key: ConfigKey.property_example,
2957
+ exportJsonKey: [
2958
+ { "@keyonly": { isExample: true, example: true, "@bit": { isExample: true } } },
2959
+ { "@absent": { isExample: true, example: true, "@bit": { isExample: true } } },
2960
+ { isExample: true, example: "$", "@bit": { isExample: true } }
2961
+ ],
2822
2962
  description: "Example text for the element.",
2823
2963
  format: TagFormat.plainText
2824
2964
  }
@@ -2834,6 +2974,7 @@ var CARDSETS = {
2834
2974
  //
2835
2975
  [CardSetConfigKey.table]: {
2836
2976
  jsonKey: "table.data",
2977
+ exportJsonKey: { table: { data: "$" } },
2837
2978
  sides: [
2838
2979
  {
2839
2980
  name: "cell",
@@ -2849,6 +2990,7 @@ var CARDSETS = {
2849
2990
  {
2850
2991
  key: ConfigKey.tag_title,
2851
2992
  jsonKey: "^table.columns[]",
2993
+ exportJsonKey: { "@bit": { table: { columns: ["$"] } } },
2852
2994
  description: "Title of the table."
2853
2995
  },
2854
2996
  {
@@ -2889,18 +3031,34 @@ var CARDSETS = {
2889
3031
  [CardSetConfigKey.tableExtended]: {
2890
3032
  jsonKey: null,
2891
3033
  sections: {
2892
- "table-header": { jsonKey: "table.header.rows", sideJsonKey: "cells[{s}]|set(title=true)" },
2893
- "table-body": { jsonKey: "table.body.rows", isDefault: true },
2894
- "table-footer": { jsonKey: "table.footer.rows", sideJsonKey: "cells[{s}]|set(title=true)" }
3034
+ "table-header": {
3035
+ jsonKey: "table.header.rows",
3036
+ exportJsonKey: { table: { header: { rows: "$" } } },
3037
+ sideJsonKey: "cells[{s}]|set(title=true)",
3038
+ sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } }
3039
+ },
3040
+ "table-body": {
3041
+ jsonKey: "table.body.rows",
3042
+ exportJsonKey: { table: { body: { rows: "$" } } },
3043
+ isDefault: true
3044
+ },
3045
+ "table-footer": {
3046
+ jsonKey: "table.footer.rows",
3047
+ exportJsonKey: { table: { footer: { rows: "$" } } },
3048
+ sideJsonKey: "cells[{s}]|set(title=true)",
3049
+ sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } }
3050
+ }
2895
3051
  },
2896
3052
  sides: [
2897
3053
  {
2898
3054
  name: "cell",
2899
3055
  repeat: true,
2900
3056
  jsonKey: "cells[{s}]",
3057
+ exportJsonKey: { cells: { $s: "$" } },
2901
3058
  variants: [
2902
3059
  {
2903
3060
  jsonKey: "content",
3061
+ exportJsonKey: { content: "$" },
2904
3062
  tags: [
2905
3063
  {
2906
3064
  key: ConfigKey.group_standardItemLeadInstructionHint,
@@ -2909,29 +3067,38 @@ var CARDSETS = {
2909
3067
  {
2910
3068
  key: ConfigKey.tag_title,
2911
3069
  jsonKey: ".",
3070
+ exportJsonKey: {
3071
+ "@bit": {
3072
+ table: { header: { rows: { cells: { cells: { $s: { content: "$" } } } } } }
3073
+ }
3074
+ },
2912
3075
  description: "Title of the table cell."
2913
3076
  },
2914
3077
  {
2915
3078
  key: ConfigKey.property_tableCellType,
2916
3079
  jsonKey: "title|bool(th)",
3080
+ exportJsonKey: [{ "@value=th": { title: true } }],
2917
3081
  description: "Table cell type (th/td).",
2918
3082
  format: TagFormat.plainText
2919
3083
  },
2920
3084
  {
2921
3085
  key: ConfigKey.property_tableRowSpan,
2922
3086
  jsonKey: "rowspan",
3087
+ exportJsonKey: { rowspan: "$" },
2923
3088
  description: "Number of rows the cell spans.",
2924
3089
  format: TagFormat.number
2925
3090
  },
2926
3091
  {
2927
3092
  key: ConfigKey.property_tableColSpan,
2928
3093
  jsonKey: "colspan",
3094
+ exportJsonKey: { colspan: "$" },
2929
3095
  description: "Number of columns the cell spans.",
2930
3096
  format: TagFormat.number
2931
3097
  },
2932
3098
  {
2933
3099
  key: ConfigKey.property_tableScope,
2934
3100
  jsonKey: "scope",
3101
+ exportJsonKey: { scope: "$" },
2935
3102
  description: "Scope attribute for header cells.",
2936
3103
  format: TagFormat.plainText
2937
3104
  },
@@ -2952,6 +3119,7 @@ var CARDSETS = {
2952
3119
  //
2953
3120
  [CardSetConfigKey.pronunciationTable]: {
2954
3121
  jsonKey: "pronunciationTable.data",
3122
+ exportJsonKey: { pronunciationTable: { data: "$" } },
2955
3123
  sides: [
2956
3124
  {
2957
3125
  name: "cell",
@@ -2959,12 +3127,14 @@ var CARDSETS = {
2959
3127
  variants: [
2960
3128
  {
2961
3129
  jsonKey: "body",
3130
+ exportJsonKey: { body: "$" },
2962
3131
  tags: [
2963
3132
  {
2964
3133
  key: ConfigKey.group_standardItemLeadInstructionHint,
2965
3134
  description: "Standard tags for lead, instruction, and hint."
2966
3135
  },
2967
3136
  {
3137
+ exportJsonKey: { title: "$" },
2968
3138
  key: ConfigKey.tag_title,
2969
3139
  description: "Title of the pronunciation table."
2970
3140
  },
@@ -2985,12 +3155,15 @@ var CARDSETS = {
2985
3155
  //
2986
3156
  [CardSetConfigKey.botActionResponses]: {
2987
3157
  jsonKey: "responses",
3158
+ exportJsonKey: { responses: "$" },
2988
3159
  sides: [
2989
3160
  {
2990
3161
  name: "response",
2991
3162
  variants: [
2992
3163
  {
2993
3164
  jsonKey: "feedback",
3165
+ exportJsonKey: { feedback: "$" },
3166
+ format: TextFormat2.plainText,
2994
3167
  tags: [
2995
3168
  {
2996
3169
  key: ConfigKey.property_reaction,
@@ -2998,16 +3171,53 @@ var CARDSETS = {
2998
3171
  format: TagFormat.plainText
2999
3172
  },
3000
3173
  {
3001
- key: ConfigKey.group_standardItemLead,
3002
- description: "Item, lead, page number, and margin number for the bot action response."
3174
+ key: ConfigKey.tag_item,
3175
+ jsonKey: "item",
3176
+ exportJsonKey: { item: "$" },
3177
+ format: TagFormat.plainText,
3178
+ description: "The item for the bit",
3179
+ chain: [
3180
+ {
3181
+ key: ConfigKey.tag_item,
3182
+ jsonKey: "lead",
3183
+ exportJsonKey: { lead: "$" },
3184
+ description: "The lead for the bit",
3185
+ maxCount: 1,
3186
+ chain: [
3187
+ {
3188
+ key: ConfigKey.tag_item,
3189
+ jsonKey: "pageNumber",
3190
+ exportJsonKey: { pageNumber: "$" },
3191
+ description: "The page number for the bit",
3192
+ maxCount: 1,
3193
+ chain: [
3194
+ {
3195
+ key: ConfigKey.tag_item,
3196
+ jsonKey: "marginNumber",
3197
+ exportJsonKey: { marginNumber: "$" },
3198
+ description: "The margin number for the bit",
3199
+ maxCount: 1
3200
+ }
3201
+ ]
3202
+ }
3203
+ ]
3204
+ }
3205
+ ]
3003
3206
  },
3004
3207
  {
3005
3208
  key: ConfigKey.tag_instruction,
3006
3209
  description: "The response label for the bot action.",
3007
- jsonKey: "response"
3210
+ jsonKey: "response",
3211
+ exportJsonKey: { response: "$" },
3212
+ format: TagFormat.plainText
3008
3213
  },
3009
3214
  {
3010
3215
  key: ConfigKey.property_example,
3216
+ exportJsonKey: [
3217
+ { "@keyonly": { isExample: true, example: true, "@bit": { isExample: true } } },
3218
+ { "@absent": { isExample: true, example: true, "@bit": { isExample: true } } },
3219
+ { isExample: true, example: "$", "@bit": { isExample: true } }
3220
+ ],
3011
3221
  description: "Example text for the bot action response.",
3012
3222
  format: TagFormat.plainText
3013
3223
  }
@@ -3022,12 +3232,14 @@ var CARDSETS = {
3022
3232
  //
3023
3233
  [CardSetConfigKey.clozeList]: {
3024
3234
  jsonKey: "listItems",
3235
+ exportJsonKey: { listItems: "$" },
3025
3236
  sides: [
3026
3237
  {
3027
3238
  name: "content",
3028
3239
  variants: [
3029
3240
  {
3030
3241
  jsonKey: "body",
3242
+ exportJsonKey: { body: "$" },
3031
3243
  tags: [
3032
3244
  {
3033
3245
  key: ConfigKey.group_standardTags,
@@ -3048,18 +3260,21 @@ var CARDSETS = {
3048
3260
  //
3049
3261
  [CardSetConfigKey.exampleBitList]: {
3050
3262
  jsonKey: "listItems",
3263
+ exportJsonKey: { listItems: "$" },
3051
3264
  sides: [
3052
3265
  {
3053
3266
  name: "item",
3054
3267
  variants: [
3055
3268
  {
3056
3269
  jsonKey: "body",
3270
+ exportJsonKey: { body: "$" },
3057
3271
  tags: [
3058
3272
  {
3059
3273
  key: ConfigKey.group_standardTags,
3060
3274
  description: "Standard tags for example bits."
3061
3275
  },
3062
3276
  {
3277
+ exportJsonKey: { title: "$" },
3063
3278
  key: ConfigKey.tag_title,
3064
3279
  description: "Title of the example bit."
3065
3280
  }
@@ -3074,14 +3289,17 @@ var CARDSETS = {
3074
3289
  //
3075
3290
  [CardSetConfigKey.ingredients]: {
3076
3291
  jsonKey: "ingredients",
3292
+ exportJsonKey: { ingredients: "$" },
3077
3293
  sides: [
3078
3294
  {
3079
3295
  name: "ingredient",
3080
3296
  variants: [
3081
3297
  {
3082
3298
  jsonKey: "ingredient",
3299
+ exportJsonKey: { ingredient: "$" },
3083
3300
  tags: [
3084
3301
  {
3302
+ exportJsonKey: { title: "$" },
3085
3303
  key: ConfigKey.tag_title,
3086
3304
  description: "Title of the ingredient."
3087
3305
  },
@@ -3089,6 +3307,7 @@ var CARDSETS = {
3089
3307
  key: ConfigKey.tag_true,
3090
3308
  description: "Checked state for the ingredient.",
3091
3309
  jsonKey: "|set(checked=true)",
3310
+ exportJsonKey: { checked: true, $: "$" },
3092
3311
  maxCount: 1
3093
3312
  // nullable: true,
3094
3313
  },
@@ -3096,6 +3315,7 @@ var CARDSETS = {
3096
3315
  key: ConfigKey.tag_false,
3097
3316
  description: "Unchecked state for the ingredient.",
3098
3317
  jsonKey: "|set(checked=false)",
3318
+ exportJsonKey: { checked: false, $: "$" },
3099
3319
  maxCount: 1
3100
3320
  // nullable: true,
3101
3321
  },
@@ -3107,9 +3327,11 @@ var CARDSETS = {
3107
3327
  key: ConfigKey.tag_instruction,
3108
3328
  description: "The quantity of the ingredient.",
3109
3329
  jsonKey: "quantity",
3330
+ exportJsonKey: { quantity: "$" },
3110
3331
  format: TagFormat.number
3111
3332
  },
3112
3333
  {
3334
+ exportJsonKey: { hint: "$" },
3113
3335
  key: ConfigKey.tag_hint,
3114
3336
  description: "The hint for the ingredient."
3115
3337
  },
@@ -3145,6 +3367,7 @@ var CARDSETS = {
3145
3367
  //
3146
3368
  [CardSetConfigKey.bookReferenceList]: {
3147
3369
  jsonKey: "bookReferences",
3370
+ exportJsonKey: { bookReferences: "$" },
3148
3371
  sides: [
3149
3372
  {
3150
3373
  name: "reference",
@@ -3204,6 +3427,11 @@ var GROUPS = {
3204
3427
  format: TagFormat.plainText,
3205
3428
  maxCount: Count.infinity
3206
3429
  },
3430
+ {
3431
+ key: ConfigKey.property_gUri,
3432
+ description: "Global URI for the bit",
3433
+ format: TagFormat.plainText
3434
+ },
3207
3435
  {
3208
3436
  key: ConfigKey.property_customerId,
3209
3437
  description: "The customer-specific identifier for the bit",
@@ -3387,12 +3615,14 @@ var GROUPS = {
3387
3615
  {
3388
3616
  key: ConfigKey.property_groupTag,
3389
3617
  jsonKey: "groupTag.name",
3618
+ exportJsonKey: { groupTag: { name: "$" } },
3390
3619
  description: "The group tag(s) for the bit",
3391
3620
  format: TagFormat.plainText,
3392
3621
  maxCount: Count.infinity,
3393
3622
  chain: [
3394
3623
  {
3395
3624
  key: ConfigKey.property_tag,
3625
+ exportJsonKey: { tags: ["$"] },
3396
3626
  description: "The tag(s) for the group",
3397
3627
  format: TagFormat.plainText,
3398
3628
  maxCount: Count.infinity
@@ -3423,6 +3653,12 @@ var GROUPS = {
3423
3653
  format: TagFormat.plainText,
3424
3654
  maxCount: Count.infinity
3425
3655
  },
3656
+ {
3657
+ key: ConfigKey.property_sourceBB,
3658
+ description: "The source bounding box(es) for the bit (x, y, x1, y1)",
3659
+ format: TagFormat.coordinates,
3660
+ maxCount: Count.infinity
3661
+ },
3426
3662
  {
3427
3663
  key: ConfigKey.property_levelCEFRp,
3428
3664
  description: "The CEFRp level for the bit",
@@ -3460,6 +3696,7 @@ var GROUPS = {
3460
3696
  maxCount: Count.infinity
3461
3697
  },
3462
3698
  {
3699
+ exportJsonKey: { anchor: "$" },
3463
3700
  key: ConfigKey.tag_anchor,
3464
3701
  name: "Anchor",
3465
3702
  format: TagFormat.plainText,
@@ -3497,23 +3734,27 @@ var GROUPS = {
3497
3734
  {
3498
3735
  key: ConfigKey.tag_item,
3499
3736
  jsonKey: "item",
3737
+ exportJsonKey: { item: "$" },
3500
3738
  description: "The item for the bit",
3501
3739
  chain: [
3502
3740
  {
3503
3741
  key: ConfigKey.tag_item,
3504
3742
  jsonKey: "lead",
3743
+ exportJsonKey: { lead: "$" },
3505
3744
  description: "The lead for the bit",
3506
3745
  maxCount: 1,
3507
3746
  chain: [
3508
3747
  {
3509
3748
  key: ConfigKey.tag_item,
3510
3749
  jsonKey: "pageNumber",
3750
+ exportJsonKey: { pageNumber: "$" },
3511
3751
  description: "The page number for the bit",
3512
3752
  maxCount: 1,
3513
3753
  chain: [
3514
3754
  {
3515
3755
  key: ConfigKey.tag_item,
3516
3756
  jsonKey: "marginNumber",
3757
+ exportJsonKey: { marginNumber: "$" },
3517
3758
  description: "The margin number for the bit",
3518
3759
  maxCount: 1
3519
3760
  }
@@ -3534,11 +3775,13 @@ var GROUPS = {
3534
3775
  description: "Item, lead, page number, and margin number tags"
3535
3776
  },
3536
3777
  {
3778
+ exportJsonKey: { instruction: "$" },
3537
3779
  key: ConfigKey.tag_instruction,
3538
3780
  name: "Instruction",
3539
3781
  description: "The instruction for the bit"
3540
3782
  },
3541
3783
  {
3784
+ exportJsonKey: { hint: "$" },
3542
3785
  key: ConfigKey.tag_hint,
3543
3786
  name: "Hint",
3544
3787
  description: "The hint for the bit"
@@ -3558,9 +3801,17 @@ var GROUPS = {
3558
3801
  description: "Item, lead, page number, margin number, instruction and hint tags"
3559
3802
  },
3560
3803
  {
3804
+ // Bit-level example tag: bare/synthesized records the marker only;
3805
+ // valued [@example:text] emits `isExample: true` and `example` as
3806
+ // PM-rendered rich text (bitmark+ format).
3561
3807
  key: ConfigKey.property_example,
3808
+ exportJsonKey: [
3809
+ { "@keyonly": { isExample: true } },
3810
+ { "@absent": { isExample: true } },
3811
+ { isExample: true, example: "$" }
3812
+ ],
3562
3813
  description: "The example(s) for the bit",
3563
- format: TagFormat.plainText
3814
+ format: TagFormat.bitmarkText
3564
3815
  }
3565
3816
  ]
3566
3817
  },
@@ -3571,6 +3822,7 @@ var GROUPS = {
3571
3822
  {
3572
3823
  key: ConfigKey.property_imageSource,
3573
3824
  jsonKey: "imageSource.url",
3825
+ exportJsonKey: { imageSource: { url: "$" } },
3574
3826
  description: "The source of an image",
3575
3827
  format: TagFormat.plainText,
3576
3828
  chain: [
@@ -3605,6 +3857,7 @@ var GROUPS = {
3605
3857
  {
3606
3858
  key: ConfigKey.property_technicalTerm,
3607
3859
  jsonKey: "technicalTerm.technicalTerm",
3860
+ exportJsonKey: { technicalTerm: { technicalTerm: "$" } },
3608
3861
  description: "The technical term",
3609
3862
  format: TagFormat.plainText,
3610
3863
  chain: [
@@ -3624,6 +3877,7 @@ var GROUPS = {
3624
3877
  {
3625
3878
  key: ConfigKey.property_person,
3626
3879
  jsonKey: "partner.name",
3880
+ exportJsonKey: { partner: { name: "$" } },
3627
3881
  description: "A person",
3628
3882
  format: TagFormat.plainText,
3629
3883
  chain: [
@@ -3635,6 +3889,7 @@ var GROUPS = {
3635
3889
  {
3636
3890
  key: ConfigKey.group_resourceImage,
3637
3891
  jsonKey: "avatarImage|resource(type=image, key=image)",
3892
+ exportJsonKey: { avatarImage: { type: "image", image: { src: "$" } } },
3638
3893
  description: "The image of the person"
3639
3894
  }
3640
3895
  ]
@@ -3643,6 +3898,7 @@ var GROUPS = {
3643
3898
  // Deprecated (parter renamed to person)
3644
3899
  key: ConfigKey.property_partner,
3645
3900
  jsonKey: "partner.name",
3901
+ exportJsonKey: { partner: { name: "$" } },
3646
3902
  description: "A partner",
3647
3903
  format: TagFormat.plainText,
3648
3904
  chain: [
@@ -3654,6 +3910,7 @@ var GROUPS = {
3654
3910
  {
3655
3911
  key: ConfigKey.group_resourceImage,
3656
3912
  jsonKey: "avatarImage|resource(type=image, key=image)",
3913
+ exportJsonKey: { avatarImage: { type: "image", image: { src: "$" } } },
3657
3914
  description: "The image of the partner"
3658
3915
  }
3659
3916
  ]
@@ -3665,15 +3922,19 @@ var GROUPS = {
3665
3922
  description: "Gap chain",
3666
3923
  tags: [
3667
3924
  {
3925
+ exportJsonKey: { solutions: [["$"]] },
3668
3926
  key: ConfigKey.tag_gap,
3669
3927
  description: "The value of a gap in the content",
3670
3928
  maxCount: Count.infinity,
3929
+ format: TagFormat.plainText,
3671
3930
  chain: [
3672
3931
  {
3673
3932
  key: ConfigKey.tag_gap,
3674
3933
  jsonKey: "solutions[]",
3934
+ exportJsonKey: { solutions: ["$"] },
3675
3935
  description: "Alternative values for the gaps in the content",
3676
- maxCount: Count.infinity
3936
+ maxCount: Count.infinity,
3937
+ format: TagFormat.plainText
3677
3938
  },
3678
3939
  {
3679
3940
  key: ConfigKey.group_standardItemLeadInstructionHint,
@@ -3682,12 +3943,33 @@ var GROUPS = {
3682
3943
  {
3683
3944
  key: ConfigKey.property_example,
3684
3945
  jsonKey: "example",
3946
+ exportJsonKey: [
3947
+ {
3948
+ "@keyonly": {
3949
+ isExample: true,
3950
+ example: "$parent.solutions[0]",
3951
+ "@bit": { isExample: true }
3952
+ }
3953
+ },
3954
+ {
3955
+ "@absent": {
3956
+ isExample: true,
3957
+ example: "$parent.solutions[0]",
3958
+ "@bit": { isExample: true }
3959
+ }
3960
+ },
3961
+ { isExample: true, example: "$", "@bit": { isExample: true } }
3962
+ ],
3685
3963
  description: "An example for the gap",
3686
- format: TagFormat.plainText
3964
+ format: TagFormat.bitmarkText
3687
3965
  },
3688
3966
  {
3689
3967
  key: ConfigKey.property_isCaseSensitive,
3690
3968
  jsonKey: "isCaseSensitive",
3969
+ exportJsonKey: [
3970
+ { "@absent": { isCaseSensitive: "$ancestor" } },
3971
+ { isCaseSensitive: "$" }
3972
+ ],
3691
3973
  description: "If true, the gap text is case sensitive",
3692
3974
  format: TagFormat.boolean,
3693
3975
  defaultValue: "true"
@@ -3701,21 +3983,27 @@ var GROUPS = {
3701
3983
  description: "True/False chain",
3702
3984
  tags: [
3703
3985
  {
3986
+ exportJsonKey: { choices: [{ choice: "$", isCorrect: true }] },
3704
3987
  key: ConfigKey.tag_true,
3705
3988
  description: "True value for a true/false statement/question",
3706
3989
  maxCount: Count.infinity,
3990
+ format: TagFormat.plainText,
3707
3991
  chain: [
3708
3992
  {
3709
3993
  key: ConfigKey.tag_true,
3710
3994
  jsonKey: "choices[]|set(isCorrect=true)",
3995
+ exportJsonKey: { choices: [{ choice: "$", isCorrect: true }] },
3711
3996
  description: "True values for a true/false statement/question",
3712
- maxCount: Count.infinity
3997
+ maxCount: Count.infinity,
3998
+ format: TagFormat.plainText
3713
3999
  },
3714
4000
  {
3715
4001
  key: ConfigKey.tag_false,
3716
4002
  jsonKey: "choices[]|set(isCorrect=false)",
4003
+ exportJsonKey: { choices: [{ choice: "$", isCorrect: false }] },
3717
4004
  description: "False values for a true/false statement/question",
3718
- maxCount: Count.infinity
4005
+ maxCount: Count.infinity,
4006
+ format: TagFormat.plainText
3719
4007
  },
3720
4008
  {
3721
4009
  key: ConfigKey.group_standardItemLeadInstructionHint,
@@ -3724,27 +4012,50 @@ var GROUPS = {
3724
4012
  {
3725
4013
  key: ConfigKey.property_example,
3726
4014
  jsonKey: "example",
4015
+ exportJsonKey: [
4016
+ {
4017
+ "@keyonly": {
4018
+ isExample: true,
4019
+ example: "$parent.isCorrect",
4020
+ "@bit": { isExample: true }
4021
+ }
4022
+ },
4023
+ {
4024
+ "@absent": {
4025
+ isExample: true,
4026
+ example: "$parent.isCorrect",
4027
+ "@bit": { isExample: true }
4028
+ }
4029
+ },
4030
+ { isExample: true, example: "$", "@bit": { isExample: true } }
4031
+ ],
3727
4032
  description: "An example for the true/false statement/question",
3728
- format: TagFormat.plainText
4033
+ format: TagFormat.bitmarkText
3729
4034
  }
3730
4035
  ]
3731
4036
  },
3732
4037
  {
4038
+ exportJsonKey: { choices: [{ choice: "$", isCorrect: false }] },
3733
4039
  key: ConfigKey.tag_false,
3734
4040
  description: "False value for a true/false statement/question",
3735
4041
  maxCount: Count.infinity,
4042
+ format: TagFormat.plainText,
3736
4043
  chain: [
3737
4044
  {
3738
4045
  key: ConfigKey.tag_true,
3739
4046
  jsonKey: "choices[]|set(isCorrect=true)",
4047
+ exportJsonKey: { choices: [{ choice: "$", isCorrect: true }] },
3740
4048
  description: "True values for a true/false statement/question",
3741
- maxCount: Count.infinity
4049
+ maxCount: Count.infinity,
4050
+ format: TagFormat.plainText
3742
4051
  },
3743
4052
  {
3744
4053
  key: ConfigKey.tag_false,
3745
4054
  jsonKey: "choices[]|set(isCorrect=false)",
4055
+ exportJsonKey: { choices: [{ choice: "$", isCorrect: false }] },
3746
4056
  description: "False values for a true/false statement/question",
3747
- maxCount: Count.infinity
4057
+ maxCount: Count.infinity,
4058
+ format: TagFormat.plainText
3748
4059
  },
3749
4060
  {
3750
4061
  key: ConfigKey.group_standardItemLeadInstructionHint,
@@ -3753,8 +4064,25 @@ var GROUPS = {
3753
4064
  {
3754
4065
  key: ConfigKey.property_example,
3755
4066
  jsonKey: "example",
4067
+ exportJsonKey: [
4068
+ {
4069
+ "@keyonly": {
4070
+ isExample: true,
4071
+ example: "$parent.isCorrect",
4072
+ "@bit": { isExample: true }
4073
+ }
4074
+ },
4075
+ {
4076
+ "@absent": {
4077
+ isExample: true,
4078
+ example: "$parent.isCorrect",
4079
+ "@bit": { isExample: true }
4080
+ }
4081
+ },
4082
+ { isExample: true, example: "$", "@bit": { isExample: true } }
4083
+ ],
3756
4084
  description: "An example for the true/false statement/question",
3757
- format: TagFormat.plainText
4085
+ format: TagFormat.bitmarkText
3758
4086
  }
3759
4087
  ]
3760
4088
  }
@@ -3767,6 +4095,7 @@ var GROUPS = {
3767
4095
  {
3768
4096
  key: ConfigKey.property_mark,
3769
4097
  jsonKey: "marks.mark",
4098
+ exportJsonKey: { marks: { mark: ["$"] } },
3770
4099
  description: "The mark configuration",
3771
4100
  format: TagFormat.plainText,
3772
4101
  maxCount: Count.infinity,
@@ -3790,9 +4119,11 @@ var GROUPS = {
3790
4119
  description: "Mark chain",
3791
4120
  tags: [
3792
4121
  {
4122
+ exportJsonKey: { solution: ["$"] },
3793
4123
  key: ConfigKey.tag_mark,
3794
4124
  description: "The marked content",
3795
4125
  maxCount: Count.infinity,
4126
+ format: TagFormat.plainText,
3796
4127
  chain: [
3797
4128
  {
3798
4129
  key: ConfigKey.property_mark,
@@ -3803,8 +4134,13 @@ var GROUPS = {
3803
4134
  {
3804
4135
  key: ConfigKey.property_example,
3805
4136
  jsonKey: "example",
4137
+ exportJsonKey: [
4138
+ { "@keyonly": { isExample: true, example: true, "@bit": { isExample: true } } },
4139
+ { "@absent": { isExample: true, example: true, "@bit": { isExample: true } } },
4140
+ { isExample: true, example: "$", "@bit": { isExample: true } }
4141
+ ],
3806
4142
  description: "An example for the marked content",
3807
- format: TagFormat.plainText
4143
+ format: TagFormat.bitmarkText
3808
4144
  }
3809
4145
  ]
3810
4146
  }
@@ -3893,7 +4229,8 @@ var GROUPS = {
3893
4229
  name: "Title",
3894
4230
  description: "The title of the book",
3895
4231
  maxCount: 2,
3896
- jsonKey: "title|multi(count=2, key=subtitle)"
4232
+ jsonKey: "title|multi(count=2, key=subtitle)",
4233
+ exportJsonKey: [{ "@level=1": { title: "$" } }, { "@level=2": { subtitle: "$" } }]
3897
4234
  },
3898
4235
  {
3899
4236
  key: ConfigKey.property_subtype,
@@ -3909,6 +4246,7 @@ var GROUPS = {
3909
4246
  {
3910
4247
  key: ConfigKey.resource_coverImage,
3911
4248
  jsonKey: "coverImage|resource(type=image, key=image)",
4249
+ exportJsonKey: { coverImage: { type: "image", image: { src: "$" } } },
3912
4250
  description: "The cover image of the book",
3913
4251
  chain: [
3914
4252
  {
@@ -3926,6 +4264,7 @@ var GROUPS = {
3926
4264
  {
3927
4265
  key: ConfigKey.resource_backgroundImage,
3928
4266
  jsonKey: "backgroundImage|resource(type=image, key=image)",
4267
+ exportJsonKey: { backgroundImage: { type: "image", image: { src: "$" } } },
3929
4268
  description: "The background image of the book",
3930
4269
  chain: [
3931
4270
  {
@@ -4085,10 +4424,21 @@ var GROUPS = {
4085
4424
  format: TagFormat.plainText,
4086
4425
  chain: [
4087
4426
  {
4427
+ exportJsonKey: { reference: "$" },
4088
4428
  key: ConfigKey.tag_reference,
4089
4429
  format: TagFormat.plainText,
4090
- description: "The reference(s) for the book(s) in the learning path",
4091
- maxCount: 2
4430
+ description: "The reference for the book(s) in the learning path",
4431
+ maxCount: 1,
4432
+ chain: [
4433
+ {
4434
+ key: ConfigKey.tag_reference,
4435
+ jsonKey: "referenceEnd",
4436
+ exportJsonKey: { referenceEnd: "$" },
4437
+ format: TagFormat.plainText,
4438
+ description: "The referenceEnd for the book(s) in the learning path",
4439
+ maxCount: 1
4440
+ }
4441
+ ]
4092
4442
  }
4093
4443
  ]
4094
4444
  }
@@ -4228,6 +4578,8 @@ var GROUPS = {
4228
4578
  tags: [
4229
4579
  {
4230
4580
  key: ConfigKey.resource_imagePlaceholder,
4581
+ jsonKey: "imagePlaceholder|resource(type=image, key=image)",
4582
+ exportJsonKey: { imagePlaceholder: { type: "image", image: { src: "$" } } },
4231
4583
  description: "Placeholder image for the resource",
4232
4584
  chain: [
4233
4585
  {
@@ -4412,6 +4764,7 @@ var GROUPS = {
4412
4764
  {
4413
4765
  key: ConfigKey.property_posterImage,
4414
4766
  jsonKey: "posterImage.src",
4767
+ exportJsonKey: { posterImage: { src: "$" } },
4415
4768
  description: "The poster image for the video",
4416
4769
  format: TagFormat.plainText,
4417
4770
  chain: [
@@ -4468,6 +4821,7 @@ var GROUPS = {
4468
4821
  tags: [
4469
4822
  {
4470
4823
  key: ConfigKey.resource_image,
4824
+ exportJsonKey: { resource: { type: "image", image: { src: "$" } } },
4471
4825
  description: "The image resource",
4472
4826
  chain: [
4473
4827
  {
@@ -4532,6 +4886,7 @@ var GROUPS = {
4532
4886
  tags: [
4533
4887
  {
4534
4888
  key: ConfigKey.resource_imageLink,
4889
+ exportJsonKey: { resource: { type: "image-link", imageLink: { url: "$" } } },
4535
4890
  description: "The link to the image resource",
4536
4891
  chain: [
4537
4892
  {
@@ -4548,6 +4903,7 @@ var GROUPS = {
4548
4903
  tags: [
4549
4904
  {
4550
4905
  key: ConfigKey.resource_audio,
4906
+ exportJsonKey: { resource: { type: "audio", audio: { src: "$" } } },
4551
4907
  description: "The audio resource",
4552
4908
  chain: [
4553
4909
  {
@@ -4564,6 +4920,7 @@ var GROUPS = {
4564
4920
  tags: [
4565
4921
  {
4566
4922
  key: ConfigKey.resource_audioEmbed,
4923
+ exportJsonKey: { resource: { type: "audio-embed", audioEmbed: { src: "$" } } },
4567
4924
  description: "The embedded audio resource",
4568
4925
  chain: [
4569
4926
  {
@@ -4580,6 +4937,7 @@ var GROUPS = {
4580
4937
  tags: [
4581
4938
  {
4582
4939
  key: ConfigKey.resource_audioLink,
4940
+ exportJsonKey: { resource: { type: "audio-link", audioLink: { url: "$" } } },
4583
4941
  description: "The link to the audio resource",
4584
4942
  chain: [
4585
4943
  {
@@ -4596,6 +4954,7 @@ var GROUPS = {
4596
4954
  tags: [
4597
4955
  {
4598
4956
  key: ConfigKey.resource_video,
4957
+ exportJsonKey: { resource: { type: "video", video: { src: "$" } } },
4599
4958
  description: "The video resource",
4600
4959
  chain: [
4601
4960
  {
@@ -4612,6 +4971,7 @@ var GROUPS = {
4612
4971
  tags: [
4613
4972
  {
4614
4973
  key: ConfigKey.resource_videoEmbed,
4974
+ exportJsonKey: { resource: { type: "video-embed", videoEmbed: { url: "$" } } },
4615
4975
  description: "The embedded video resource",
4616
4976
  chain: [
4617
4977
  {
@@ -4628,6 +4988,7 @@ var GROUPS = {
4628
4988
  tags: [
4629
4989
  {
4630
4990
  key: ConfigKey.resource_videoLink,
4991
+ exportJsonKey: { resource: { type: "video-link", videoLink: { url: "$" } } },
4631
4992
  description: "The link to the video resource",
4632
4993
  chain: [
4633
4994
  {
@@ -4644,6 +5005,9 @@ var GROUPS = {
4644
5005
  tags: [
4645
5006
  {
4646
5007
  key: ConfigKey.resource_stillImageFilmEmbed,
5008
+ exportJsonKey: {
5009
+ resource: { type: "still-image-film-embed", stillImageFilmEmbed: { url: "$" } }
5010
+ },
4647
5011
  description: "The embedded still image film resource",
4648
5012
  chain: [
4649
5013
  {
@@ -4660,6 +5024,9 @@ var GROUPS = {
4660
5024
  tags: [
4661
5025
  {
4662
5026
  key: ConfigKey.resource_stillImageFilmLink,
5027
+ exportJsonKey: {
5028
+ resource: { type: "still-image-film-link", stillImageFilmLink: { url: "$" } }
5029
+ },
4663
5030
  description: "The link to the still image film resource",
4664
5031
  chain: [
4665
5032
  {
@@ -4724,6 +5091,7 @@ var GROUPS = {
4724
5091
  tags: [
4725
5092
  {
4726
5093
  key: ConfigKey.resource_document,
5094
+ exportJsonKey: { resource: { type: "document", document: { url: "$" } } },
4727
5095
  description: "The document resource",
4728
5096
  chain: [
4729
5097
  {
@@ -4740,6 +5108,7 @@ var GROUPS = {
4740
5108
  tags: [
4741
5109
  {
4742
5110
  key: ConfigKey.resource_documentEmbed,
5111
+ exportJsonKey: { resource: { type: "document-embed", documentEmbed: { url: "$" } } },
4743
5112
  description: "The embedded document resource",
4744
5113
  chain: [
4745
5114
  {
@@ -4756,6 +5125,7 @@ var GROUPS = {
4756
5125
  tags: [
4757
5126
  {
4758
5127
  key: ConfigKey.resource_documentLink,
5128
+ exportJsonKey: { resource: { type: "document-link", documentLink: { url: "$" } } },
4759
5129
  description: "The link to the document resource",
4760
5130
  chain: [
4761
5131
  {
@@ -4772,6 +5142,7 @@ var GROUPS = {
4772
5142
  tags: [
4773
5143
  {
4774
5144
  key: ConfigKey.resource_documentDownload,
5145
+ exportJsonKey: { resource: { type: "document-download", documentDownload: { url: "$" } } },
4775
5146
  description: "The downloadable document resource",
4776
5147
  chain: [
4777
5148
  {
@@ -4788,6 +5159,7 @@ var GROUPS = {
4788
5159
  tags: [
4789
5160
  {
4790
5161
  key: ConfigKey.resource_appLink,
5162
+ exportJsonKey: { resource: { type: "app-link", appLink: { url: "$" } } },
4791
5163
  description: "The link to the app resource",
4792
5164
  chain: [
4793
5165
  {
@@ -4804,6 +5176,7 @@ var GROUPS = {
4804
5176
  tags: [
4805
5177
  {
4806
5178
  key: ConfigKey.resource_websiteLink,
5179
+ exportJsonKey: { resource: { type: "website-link", websiteLink: { url: "$" } } },
4807
5180
  description: "The link to the website resource",
4808
5181
  chain: [
4809
5182
  {
@@ -4862,6 +5235,7 @@ var GROUPS = {
4862
5235
  {
4863
5236
  key: ConfigKey.resource_previewImage,
4864
5237
  jsonKey: "previewImage|resource(type=image, key=image)",
5238
+ exportJsonKey: { previewImage: { type: "image", image: { src: "$" } } },
4865
5239
  description: "The preview image resource",
4866
5240
  chain: [
4867
5241
  {
@@ -4879,6 +5253,7 @@ var GROUPS = {
4879
5253
  {
4880
5254
  key: ConfigKey.resource_previewVideo,
4881
5255
  jsonKey: "previewVideo|resource(type=video, key=video)",
5256
+ exportJsonKey: { previewVideo: { type: "video", video: { src: "$" } } },
4882
5257
  description: "The preview video resource",
4883
5258
  chain: [
4884
5259
  {
@@ -4943,20 +5318,48 @@ var ConfigHydrator = class {
4943
5318
  _side.name,
4944
5319
  _side.repeat ?? false,
4945
5320
  variantsOfSide,
4946
- _side.jsonKey
5321
+ _side.jsonKey,
5322
+ _side.exportJsonKey,
5323
+ Object.prototype.hasOwnProperty.call(_side, "exportJsonKey")
4947
5324
  );
4948
5325
  sides.push(sideConfig);
4949
5326
  }
4950
5327
  const cardSetConfig = new CardSetConfig(
4951
5328
  _cardSet,
4952
5329
  _cardSetConfig.jsonKey,
4953
- _cardSetConfig.sections,
5330
+ _cardSetConfig.exportJsonKey,
5331
+ Object.prototype.hasOwnProperty.call(_cardSetConfig, "exportJsonKey"),
5332
+ this.hydrateCardSections(_cardSetConfig.sections),
4954
5333
  sides
4955
5334
  );
4956
5335
  return cardSetConfig;
4957
5336
  }
5337
+ hydrateCardSections(sections) {
5338
+ if (!sections) return void 0;
5339
+ const out = {};
5340
+ for (const [k, v] of Object.entries(sections)) {
5341
+ out[k] = {
5342
+ jsonKey: v.jsonKey,
5343
+ exportJsonKey: v.exportJsonKey,
5344
+ hasExportJsonKey: Object.prototype.hasOwnProperty.call(v, "exportJsonKey"),
5345
+ isDefault: v.isDefault,
5346
+ sideJsonKey: v.sideJsonKey,
5347
+ sideExportJsonKey: v.sideExportJsonKey,
5348
+ hasSideExportJsonKey: Object.prototype.hasOwnProperty.call(v, "sideExportJsonKey")
5349
+ };
5350
+ }
5351
+ return out;
5352
+ }
4958
5353
  hydrateTagConfig(_tag) {
4959
- const { key: _configKey, maxCount, minCount, chain: _chain, deprecated } = _tag;
5354
+ const {
5355
+ key: _configKey,
5356
+ maxCount,
5357
+ minCount,
5358
+ chain: _chain,
5359
+ deprecated,
5360
+ jsonKey,
5361
+ exportJsonKey
5362
+ } = _tag;
4960
5363
  const configKey = (0, import_superenum15.Enum)(ConfigKey).fromValue(_configKey) || ConfigKey._unknown;
4961
5364
  if (!configKey) throw new Error(`No tag key found for config key '${configKey}'`);
4962
5365
  const tag = (0, import_superenum15.Enum)(Tag).fromValue(configKey);
@@ -4971,6 +5374,9 @@ var ConfigHydrator = class {
4971
5374
  maxCount: maxCount ?? MAX_COUNT_DEFAULT,
4972
5375
  minCount: minCount ?? MIN_COUNT_DEFAULT,
4973
5376
  chain,
5377
+ jsonKey,
5378
+ exportJsonKey,
5379
+ hasExportJsonKey: Object.prototype.hasOwnProperty.call(_tag, "exportJsonKey"),
4974
5380
  deprecated
4975
5381
  });
4976
5382
  return {
@@ -4989,7 +5395,8 @@ var ConfigHydrator = class {
4989
5395
  format,
4990
5396
  values,
4991
5397
  defaultValue,
4992
- jsonKey
5398
+ jsonKey,
5399
+ exportJsonKey
4993
5400
  } = _tag;
4994
5401
  const configKey = (0, import_superenum15.Enum)(ConfigKey).fromValue(_configKey) || ConfigKey._unknown;
4995
5402
  if (!configKey) throw new Error(`No property key found for config key '${configKey}'`);
@@ -5005,6 +5412,8 @@ var ConfigHydrator = class {
5005
5412
  minCount: minCount ?? MIN_COUNT_DEFAULT,
5006
5413
  chain,
5007
5414
  jsonKey,
5415
+ exportJsonKey,
5416
+ hasExportJsonKey: Object.prototype.hasOwnProperty.call(_tag, "exportJsonKey"),
5008
5417
  format,
5009
5418
  values,
5010
5419
  defaultValue,
@@ -5017,7 +5426,15 @@ var ConfigHydrator = class {
5017
5426
  };
5018
5427
  }
5019
5428
  hydrateResourceTagConfig(_tag) {
5020
- const { key: _configKey, maxCount, minCount, chain: _chain, deprecated, jsonKey } = _tag;
5429
+ const {
5430
+ key: _configKey,
5431
+ maxCount,
5432
+ minCount,
5433
+ chain: _chain,
5434
+ deprecated,
5435
+ jsonKey,
5436
+ exportJsonKey
5437
+ } = _tag;
5021
5438
  const configKey = (0, import_superenum15.Enum)(ConfigKey).fromValue(_configKey) || ConfigKey._unknown;
5022
5439
  if (!configKey) throw new Error(`No resource key found for config key '${configKey}'`);
5023
5440
  const tag = _configKey.substring(1);
@@ -5032,6 +5449,8 @@ var ConfigHydrator = class {
5032
5449
  minCount: minCount ?? MIN_COUNT_DEFAULT,
5033
5450
  chain,
5034
5451
  jsonKey,
5452
+ exportJsonKey,
5453
+ hasExportJsonKey: Object.prototype.hasOwnProperty.call(_tag, "exportJsonKey"),
5035
5454
  deprecated
5036
5455
  });
5037
5456
  return {
@@ -5063,14 +5482,25 @@ var ConfigHydrator = class {
5063
5482
  };
5064
5483
  }
5065
5484
  hydrateCardVariantConfig(_variant) {
5066
- const { tags: _tags, bodyAllowed, bodyRequired, repeatCount, jsonKey } = _variant;
5485
+ const {
5486
+ tags: _tags,
5487
+ bodyAllowed,
5488
+ bodyRequired,
5489
+ repeatCount,
5490
+ jsonKey,
5491
+ exportJsonKey,
5492
+ format
5493
+ } = _variant;
5067
5494
  const tags2 = this.hydrateTagsConfig(_tags);
5068
5495
  const cardSetConfig = new CardVariantConfig(
5069
5496
  tags2.tags,
5070
5497
  bodyAllowed,
5071
5498
  bodyRequired,
5072
5499
  repeatCount,
5073
- jsonKey
5500
+ jsonKey,
5501
+ exportJsonKey,
5502
+ Object.prototype.hasOwnProperty.call(_variant, "exportJsonKey"),
5503
+ format
5074
5504
  );
5075
5505
  return cardSetConfig;
5076
5506
  }
@@ -5108,6 +5538,7 @@ var BITS = {
5108
5538
  description: "Common tags for quiz bits"
5109
5539
  },
5110
5540
  {
5541
+ exportJsonKey: { title: "$" },
5111
5542
  key: ConfigKey.tag_title,
5112
5543
  description: "The title of the flashcard quiz"
5113
5544
  },
@@ -5116,6 +5547,20 @@ var BITS = {
5116
5547
  description: "The flashcard set to use for the app flashcards",
5117
5548
  format: TagFormat.plainText,
5118
5549
  maxCount: Count.infinity
5550
+ },
5551
+ {
5552
+ // Override inherited @example from group_standardTags: string root
5553
+ // example. Bare/synthesized emits `example: "true"` (a text literal
5554
+ // that field-coerces to a paragraph "true" in bitmark+ contexts);
5555
+ // valued [@example:text] emits the user's text via `$`.
5556
+ key: ConfigKey.property_example,
5557
+ exportJsonKey: [
5558
+ { "@keyonly": { isExample: true, example: "true" } },
5559
+ { "@absent": { isExample: true, example: "true" } },
5560
+ { isExample: true, example: "$" }
5561
+ ],
5562
+ description: "The example text for the bit",
5563
+ format: TagFormat.plainText
5119
5564
  }
5120
5565
  ],
5121
5566
  rootExampleType: ExampleType.string
@@ -5197,6 +5642,7 @@ var BITS = {
5197
5642
  description: "Article bit, used for articles / paragraphs",
5198
5643
  tags: [
5199
5644
  {
5645
+ exportJsonKey: { title: "$" },
5200
5646
  key: ConfigKey.tag_title,
5201
5647
  description: "The title of the article"
5202
5648
  }
@@ -5304,7 +5750,8 @@ var BITS = {
5304
5750
  key: ConfigKey.tag_title,
5305
5751
  description: "Title and subtitle of the catalog item",
5306
5752
  maxCount: 2,
5307
- jsonKey: "title|multi(count=2, key=subtitle)"
5753
+ jsonKey: "title|multi(count=2, key=subtitle)",
5754
+ exportJsonKey: [{ "@level=1": { title: "$" } }, { "@level=2": { subtitle: "$" } }]
5308
5755
  },
5309
5756
  {
5310
5757
  key: ConfigKey.property_coverImage,
@@ -5314,6 +5761,7 @@ var BITS = {
5314
5761
  {
5315
5762
  key: ConfigKey.resource_coverImage,
5316
5763
  jsonKey: "coverImage|resource(type=image, key=image)",
5764
+ exportJsonKey: { coverImage: { type: "image", image: { src: "$" } } },
5317
5765
  description: "Cover image of the catalog item",
5318
5766
  chain: [
5319
5767
  {
@@ -5441,6 +5889,17 @@ var BITS = {
5441
5889
  key: ConfigKey.group_previewVideos,
5442
5890
  description: "Array of preview videos for the catalog item",
5443
5891
  maxCount: Count.infinity
5892
+ },
5893
+ {
5894
+ // Override inherited @example from group_standardTags: string root example.
5895
+ key: ConfigKey.property_example,
5896
+ exportJsonKey: [
5897
+ { "@keyonly": { isExample: true, example: "true" } },
5898
+ { "@absent": { isExample: true, example: "true" } },
5899
+ { isExample: true, example: "$" }
5900
+ ],
5901
+ description: "The example text for the bit",
5902
+ format: TagFormat.plainText
5444
5903
  }
5445
5904
  ],
5446
5905
  rootExampleType: ExampleType.string
@@ -5454,7 +5913,8 @@ var BITS = {
5454
5913
  key: ConfigKey.tag_title,
5455
5914
  description: "Title and subtitle of the catalog item",
5456
5915
  maxCount: 2,
5457
- jsonKey: "title|multi(count=2, key=subtitle)"
5916
+ jsonKey: "title|multi(count=2, key=subtitle)",
5917
+ exportJsonKey: [{ "@level=1": { title: "$" } }, { "@level=2": { subtitle: "$" } }]
5458
5918
  },
5459
5919
  {
5460
5920
  key: ConfigKey.property_coverImage,
@@ -5464,6 +5924,7 @@ var BITS = {
5464
5924
  {
5465
5925
  key: ConfigKey.resource_coverImage,
5466
5926
  jsonKey: "coverImage|resource(type=image, key=image)",
5927
+ exportJsonKey: { coverImage: { type: "image", image: { src: "$" } } },
5467
5928
  description: "Cover image of the catalog item",
5468
5929
  chain: [
5469
5930
  {
@@ -5591,6 +6052,17 @@ var BITS = {
5591
6052
  key: ConfigKey.group_previewVideos,
5592
6053
  description: "Array of preview videos for the catalog item",
5593
6054
  maxCount: Count.infinity
6055
+ },
6056
+ {
6057
+ // Override inherited @example from group_standardTags: string root example.
6058
+ key: ConfigKey.property_example,
6059
+ exportJsonKey: [
6060
+ { "@keyonly": { isExample: true, example: "true" } },
6061
+ { "@absent": { isExample: true, example: "true" } },
6062
+ { isExample: true, example: "$" }
6063
+ ],
6064
+ description: "The example text for the bit",
6065
+ format: TagFormat.plainText
5594
6066
  }
5595
6067
  ],
5596
6068
  rootExampleType: ExampleType.string
@@ -5604,7 +6076,8 @@ var BITS = {
5604
6076
  key: ConfigKey.tag_title,
5605
6077
  description: "Title and subtitle of the catalog item",
5606
6078
  maxCount: 2,
5607
- jsonKey: "title|multi(count=2, key=subtitle)"
6079
+ jsonKey: "title|multi(count=2, key=subtitle)",
6080
+ exportJsonKey: [{ "@level=1": { title: "$" } }, { "@level=2": { subtitle: "$" } }]
5608
6081
  },
5609
6082
  {
5610
6083
  key: ConfigKey.property_coverImage,
@@ -5730,6 +6203,17 @@ var BITS = {
5730
6203
  key: ConfigKey.group_previewVideos,
5731
6204
  description: "Array of preview videos for the catalog item",
5732
6205
  maxCount: Count.infinity
6206
+ },
6207
+ {
6208
+ // Override inherited @example from group_standardTags: string root example.
6209
+ key: ConfigKey.property_example,
6210
+ exportJsonKey: [
6211
+ { "@keyonly": { isExample: true, example: "true" } },
6212
+ { "@absent": { isExample: true, example: "true" } },
6213
+ { isExample: true, example: "$" }
6214
+ ],
6215
+ description: "The example text for the bit",
6216
+ format: TagFormat.plainText
5733
6217
  }
5734
6218
  ],
5735
6219
  rootExampleType: ExampleType.string
@@ -5931,11 +6415,13 @@ var BITS = {
5931
6415
  description: "Bit alias, used to create an alias for a bit",
5932
6416
  tags: [
5933
6417
  {
6418
+ exportJsonKey: { reference: "$" },
5934
6419
  key: ConfigKey.tag_reference,
5935
6420
  format: TagFormat.plainText,
5936
6421
  description: "The reference to the bit that this alias points to"
5937
6422
  },
5938
6423
  {
6424
+ exportJsonKey: { anchor: "$" },
5939
6425
  key: ConfigKey.tag_anchor,
5940
6426
  format: TagFormat.plainText,
5941
6427
  description: "The anchor for the bit alias, used for linking"
@@ -6137,7 +6623,8 @@ var BITS = {
6137
6623
  description: "The title of the book cover",
6138
6624
  maxCount: 2,
6139
6625
  // title & subtitle
6140
- jsonKey: "title|multi(count=2, key=subtitle)"
6626
+ jsonKey: "title|multi(count=2, key=subtitle)",
6627
+ exportJsonKey: [{ "@level=1": { title: "$" } }, { "@level=2": { subtitle: "$" } }]
6141
6628
  },
6142
6629
  {
6143
6630
  key: ConfigKey.property_coverColor,
@@ -6281,6 +6768,7 @@ var BITS = {
6281
6768
  description: "Chapter bit, used to define chapters in books or articles",
6282
6769
  tags: [
6283
6770
  {
6771
+ exportJsonKey: { anchor: "$" },
6284
6772
  key: ConfigKey.tag_anchor,
6285
6773
  format: TagFormat.plainText,
6286
6774
  description: "The anchor for the chapter, used for linking"
@@ -6288,7 +6776,8 @@ var BITS = {
6288
6776
  {
6289
6777
  key: ConfigKey.tag_title,
6290
6778
  description: "The title of the chapter",
6291
- jsonKey: "title|setMulti(level)"
6779
+ jsonKey: "title|setMulti(level)",
6780
+ exportJsonKey: { title: "$", level: "$level" }
6292
6781
  },
6293
6782
  {
6294
6783
  key: ConfigKey.property_toc,
@@ -6341,6 +6830,7 @@ var BITS = {
6341
6830
  },
6342
6831
  {
6343
6832
  key: ConfigKey.property_isCaseSensitive,
6833
+ exportJsonKey: {},
6344
6834
  description: "If the cloze answers are case sensitive",
6345
6835
  format: TagFormat.boolean,
6346
6836
  defaultValue: "true"
@@ -6438,6 +6928,11 @@ var BITS = {
6438
6928
  description: "Formula bit, used for mathematical formulas in articles or documents",
6439
6929
  textFormatDefault: TextFormat2.latex
6440
6930
  },
6931
+ [BitType2.formulaImage]: {
6932
+ since: "5.23.0",
6933
+ baseBitType: BitType2.formula,
6934
+ description: "Formula image bit, used for mathematical formulas rendered as images"
6935
+ },
6441
6936
  [BitType2.smartStandardFormula]: {
6442
6937
  since: "3.11.0",
6443
6938
  baseBitType: BitType2.formula,
@@ -6790,6 +7285,7 @@ var BITS = {
6790
7285
  {
6791
7286
  key: ConfigKey.property_servings,
6792
7287
  jsonKey: "servings.servings",
7288
+ exportJsonKey: { servings: { servings: "$" } },
6793
7289
  description: "The number of servings for the ingredients",
6794
7290
  format: TagFormat.number,
6795
7291
  chain: [
@@ -6815,6 +7311,7 @@ var BITS = {
6815
7311
  format: TagFormat.boolean
6816
7312
  },
6817
7313
  {
7314
+ exportJsonKey: { hint: "$" },
6818
7315
  key: ConfigKey.tag_hint,
6819
7316
  description: "Hint for the ingredient, used to provide additional information",
6820
7317
  format: TagFormat.plainText
@@ -6992,6 +7489,17 @@ var BITS = {
6992
7489
  description: "Reference for the essay, used to link to external resources",
6993
7490
  format: TagFormat.plainText,
6994
7491
  maxCount: Count.infinity
7492
+ },
7493
+ {
7494
+ // Override inherited @example from group_standardTags: string root example.
7495
+ key: ConfigKey.property_example,
7496
+ exportJsonKey: [
7497
+ { "@keyonly": { isExample: true, example: "true" } },
7498
+ { "@absent": { isExample: true, example: "true" } },
7499
+ { isExample: true, example: "$" }
7500
+ ],
7501
+ description: "The example text for the essay bit",
7502
+ format: TagFormat.plainText
6995
7503
  }
6996
7504
  ],
6997
7505
  rootExampleType: ExampleType.string
@@ -7012,8 +7520,20 @@ var BITS = {
7012
7520
  description: "Example bit, used to provide examples in articles or books",
7013
7521
  tags: [
7014
7522
  {
7523
+ exportJsonKey: { title: "$" },
7015
7524
  key: ConfigKey.tag_title,
7016
7525
  description: "The title of the example"
7526
+ },
7527
+ {
7528
+ // Override inherited @example from group_standardTags: string root example.
7529
+ key: ConfigKey.property_example,
7530
+ exportJsonKey: [
7531
+ { "@keyonly": { isExample: true, example: "true" } },
7532
+ { "@absent": { isExample: true, example: "true" } },
7533
+ { isExample: true, example: "$" }
7534
+ ],
7535
+ description: "The example text for the example bit",
7536
+ format: TagFormat.plainText
7017
7537
  }
7018
7538
  ],
7019
7539
  rootExampleType: ExampleType.string
@@ -7879,6 +8399,7 @@ var BITS = {
7879
8399
  // Image resource
7880
8400
  key: ConfigKey.group_resourceImage,
7881
8401
  description: "Resource image tags for logo grave images, used to attach images",
8402
+ exportJsonKey: { images: "$" },
7882
8403
  minCount: 1,
7883
8404
  maxCount: Count.infinity
7884
8405
  }
@@ -8042,15 +8563,27 @@ var BITS = {
8042
8563
  format: TagFormat.plainText,
8043
8564
  chain: [
8044
8565
  {
8566
+ exportJsonKey: { reference: "$" },
8045
8567
  key: ConfigKey.tag_reference,
8046
8568
  format: TagFormat.plainText,
8047
8569
  description: "Reference tag for the book, used to link to the book in the system",
8048
- maxCount: 2
8570
+ maxCount: 1,
8571
+ chain: [
8572
+ {
8573
+ key: ConfigKey.tag_reference,
8574
+ jsonKey: "referenceEnd",
8575
+ exportJsonKey: { referenceEnd: "$" },
8576
+ format: TagFormat.plainText,
8577
+ description: "End reference tag for the book, used to specify a range",
8578
+ maxCount: 1
8579
+ }
8580
+ ]
8049
8581
  }
8050
8582
  ]
8051
8583
  },
8052
8584
  {
8053
8585
  /* Allow incorrectly chained reference tag */
8586
+ exportJsonKey: { reference: "$" },
8054
8587
  key: ConfigKey.tag_reference,
8055
8588
  format: TagFormat.plainText,
8056
8589
  description: "Reference tag for the book, used to link to the book in the system"
@@ -8097,18 +8630,41 @@ var BITS = {
8097
8630
  format: TagFormat.plainText,
8098
8631
  chain: [
8099
8632
  {
8633
+ exportJsonKey: { reference: "$" },
8100
8634
  key: ConfigKey.tag_reference,
8101
8635
  format: TagFormat.plainText,
8102
8636
  description: "Reference tag for the book, used to link to the book in the system",
8103
- maxCount: 2
8637
+ maxCount: 1,
8638
+ chain: [
8639
+ {
8640
+ key: ConfigKey.tag_reference,
8641
+ jsonKey: "referenceEnd",
8642
+ exportJsonKey: { referenceEnd: "$" },
8643
+ format: TagFormat.plainText,
8644
+ description: "End reference tag for the book, used to specify a range",
8645
+ maxCount: 1
8646
+ }
8647
+ ]
8104
8648
  }
8105
8649
  ]
8106
8650
  },
8107
8651
  {
8108
8652
  /* Allow incorrectly chained reference tag */
8653
+ exportJsonKey: { reference: "$" },
8109
8654
  key: ConfigKey.tag_reference,
8110
8655
  format: TagFormat.plainText,
8111
- description: "Reference tag for the book, used to link to the book in the system"
8656
+ description: "Reference tag for the book, used to link to the book in the system",
8657
+ maxCount: 1,
8658
+ chain: [
8659
+ {
8660
+ key: ConfigKey.tag_reference,
8661
+ jsonKey: "referenceEnd",
8662
+ exportJsonKey: { referenceEnd: "$" },
8663
+ format: TagFormat.plainText,
8664
+ description: "End reference tag for the book, used to specify a range",
8665
+ maxCount: 1
8666
+ }
8667
+ ]
8112
8668
  },
8113
8669
  {
8114
8670
  key: ConfigKey.property_buttonCaption,
@@ -8137,10 +8693,21 @@ var BITS = {
8137
8693
  maxCount: Count.infinity,
8138
8694
  chain: [
8139
8695
  {
8696
+ exportJsonKey: { reference: "$" },
8140
8697
  key: ConfigKey.tag_reference,
8141
8698
  format: TagFormat.plainText,
8142
8699
  description: "Reference tag for the book, used to link to the book in the system",
8143
- maxCount: 2
8700
+ maxCount: 1,
8701
+ chain: [
8702
+ {
8703
+ key: ConfigKey.tag_reference,
8704
+ jsonKey: "referenceEnd",
8705
+ exportJsonKey: { referenceEnd: "$" },
8706
+ format: TagFormat.plainText,
8707
+ description: "End reference tag for the book, used to specify a range",
8708
+ maxCount: 1
8709
+ }
8710
+ ]
8144
8711
  }
8145
8712
  ]
8146
8713
  },
@@ -8307,6 +8874,7 @@ var BITS = {
8307
8874
  tags: [
8308
8875
  {
8309
8876
  key: ConfigKey.resource_backgroundWallpaper,
8877
+ exportJsonKey: { backgroundWallpaper: { type: "image", image: { src: "$" } } },
8310
8878
  description: "Background wallpaper for the image, used to set a background for the image",
8311
8879
  chain: [
8312
8880
  {
@@ -8489,6 +9057,7 @@ var BITS = {
8489
9057
  },
8490
9058
  {
8491
9059
  key: ConfigKey.resource_backgroundWallpaper,
9060
+ exportJsonKey: { backgroundWallpaper: { type: "image", image: { src: "$" } } },
8492
9061
  description: "Background wallpaper for the image, used to set a background for the image",
8493
9062
  chain: [
8494
9063
  {
@@ -8641,6 +9210,7 @@ var BITS = {
8641
9210
  // Image resource
8642
9211
  key: ConfigKey.group_resourceImage,
8643
9212
  description: "Resource image tags for logo grave images, used to attach images",
9213
+ exportJsonKey: { logos: "$" },
8644
9214
  minCount: 1,
8645
9215
  maxCount: Count.infinity
8646
9216
  }
@@ -8658,6 +9228,7 @@ var BITS = {
8658
9228
  description: "Internal link bit, used to create links to other bits in articles or books",
8659
9229
  tags: [
8660
9230
  {
9231
+ exportJsonKey: { reference: "$" },
8661
9232
  key: ConfigKey.tag_reference,
8662
9233
  format: TagFormat.plainText,
8663
9234
  description: "Reference tag for the internal link, used to link to the target bit"
@@ -8676,6 +9247,7 @@ var BITS = {
8676
9247
  },
8677
9248
  {
8678
9249
  key: ConfigKey.property_reasonableNumOfChars,
9250
+ exportJsonKey: {},
8679
9251
  description: "Reasonable number of characters for the interview, used to limit input size",
8680
9252
  format: TagFormat.number
8681
9253
  }
@@ -9051,6 +9623,7 @@ var BITS = {
9051
9623
  },
9052
9624
  {
9053
9625
  key: ConfigKey.property_isCaseSensitive,
9626
+ exportJsonKey: {},
9054
9627
  description: "Case sensitivity for matching pairs, used to define if matches are case-sensitive",
9055
9628
  format: TagFormat.boolean,
9056
9629
  defaultValue: "true"
@@ -9103,6 +9676,7 @@ var BITS = {
9103
9676
  tags: [
9104
9677
  {
9105
9678
  key: ConfigKey.property_reasonableNumOfChars,
9679
+ exportJsonKey: {},
9106
9680
  description: "Reasonable number of characters for feedback, used to limit input size",
9107
9681
  format: TagFormat.number
9108
9682
  }
@@ -9244,6 +9818,7 @@ var BITS = {
9244
9818
  description: "Page bit, used to create pages in articles or books",
9245
9819
  tags: [
9246
9820
  {
9821
+ exportJsonKey: { title: "$" },
9247
9822
  key: ConfigKey.tag_title,
9248
9823
  description: "Title of the page, used to display the page title"
9249
9824
  },
@@ -9603,6 +10178,7 @@ var BITS = {
9603
10178
  {
9604
10179
  key: ConfigKey.resource_platformBackgroundImage,
9605
10180
  jsonKey: "platformBackgroundImage|resource(type=image, key=image)",
10181
+ exportJsonKey: { platformBackgroundImage: { type: "image", image: { src: "$" } } },
9606
10182
  description: "The platform section chat background image",
9607
10183
  chain: [
9608
10184
  {
@@ -9696,6 +10272,7 @@ var BITS = {
9696
10272
  description: "Review note bit, used to create review notes in articles or books",
9697
10273
  tags: [
9698
10274
  {
10275
+ exportJsonKey: { title: "$" },
9699
10276
  key: ConfigKey.tag_title,
9700
10277
  description: "Title of the review note, used to display the note title"
9701
10278
  },
@@ -9714,6 +10291,17 @@ var BITS = {
9714
10291
  key: ConfigKey.property_resolvedBy,
9715
10292
  description: "Resolved by for the review note, used to define who resolved the note",
9716
10293
  format: TagFormat.plainText
10294
+ },
10295
+ {
10296
+ // Override inherited @example from group_standardTags: string root example.
10297
+ key: ConfigKey.property_example,
10298
+ exportJsonKey: [
10299
+ { "@keyonly": { isExample: true, example: "true" } },
10300
+ { "@absent": { isExample: true, example: "true" } },
10301
+ { isExample: true, example: "$" }
10302
+ ],
10303
+ description: "The example text for the review note bit",
10304
+ format: TagFormat.plainText
9717
10305
  }
9718
10306
  ],
9719
10307
  rootExampleType: ExampleType.string
@@ -9766,11 +10354,13 @@ var BITS = {
9766
10354
  tags: [
9767
10355
  // Not sure if these are actually valid here, but include them as they are in the test bit.
9768
10356
  {
10357
+ exportJsonKey: { anchor: "$" },
9769
10358
  key: ConfigKey.tag_anchor,
9770
10359
  format: TagFormat.plainText,
9771
10360
  description: "Anchor for the sample solution, used to link to the solution"
9772
10361
  },
9773
10362
  {
10363
+ exportJsonKey: { reference: "$" },
9774
10364
  key: ConfigKey.tag_reference,
9775
10365
  format: TagFormat.plainText,
9776
10366
  description: "Reference for the sample solution, used to link to the source of the solution"
@@ -9786,6 +10376,19 @@ var BITS = {
9786
10376
  {
9787
10377
  key: ConfigKey.group_quizCommon,
9788
10378
  description: "Common quiz tags for sequences"
10379
+ },
10380
+ {
10381
+ // Override inherited @example from group_standardTags: this bit has
10382
+ // a boolean root example (rootExampleType: boolean), so bit-level
10383
+ // [@example] writes `example: true` in addition to `isExample: true`.
10384
+ key: ConfigKey.property_example,
10385
+ exportJsonKey: [
10386
+ { "@keyonly": { isExample: true, example: true } },
10387
+ { "@absent": { isExample: true, example: true } },
10388
+ { isExample: true, example: "$" }
10389
+ ],
10390
+ description: "The example flag for the bit (boolean)",
10391
+ format: TagFormat.plainText
9789
10392
  }
9790
10393
  ],
9791
10394
  cardSet: CardSetConfigKey.elements,
@@ -9893,6 +10496,7 @@ var BITS = {
9893
10496
  {
9894
10497
  key: ConfigKey.property_ratingLevelStart,
9895
10498
  jsonKey: "ratingLevelStart.level",
10499
+ exportJsonKey: { ratingLevelStart: { level: "$" } },
9896
10500
  description: "Start level for the rating survey, used to define the lowest rating",
9897
10501
  format: TagFormat.number,
9898
10502
  chain: [
@@ -9906,6 +10510,7 @@ var BITS = {
9906
10510
  {
9907
10511
  key: ConfigKey.property_ratingLevelEnd,
9908
10512
  jsonKey: "ratingLevelEnd.level",
10513
+ exportJsonKey: { ratingLevelEnd: { level: "$" } },
9909
10514
  description: "End level for the rating survey, used to define the highest rating",
9910
10515
  format: TagFormat.number,
9911
10516
  chain: [
@@ -10058,6 +10663,7 @@ var BITS = {
10058
10663
  },
10059
10664
  {
10060
10665
  key: ConfigKey.resource_backgroundWallpaper,
10666
+ exportJsonKey: { backgroundWallpaper: { type: "image", image: { src: "$" } } },
10061
10667
  description: "Background wallpaper for the image, used to set a background for the image",
10062
10668
  chain: [
10063
10669
  {
@@ -10441,12 +11047,34 @@ var BITS = {
10441
11047
  format: TagFormat.plainText
10442
11048
  },
10443
11049
  {
11050
+ exportJsonKey: { choices: [{ choice: "$", isCorrect: true }] },
10444
11051
  key: ConfigKey.tag_true,
10445
- description: "Tag for the true option in the true/false question"
11052
+ description: "Tag for the true option in the true/false question",
11053
+ format: TagFormat.plainText
10446
11054
  },
10447
11055
  {
11056
+ exportJsonKey: { choices: [{ choice: "$", isCorrect: false }] },
10448
11057
  key: ConfigKey.tag_false,
10449
- description: "Tag for the false option in the true/false question"
11058
+ description: "Tag for the false option in the true/false question",
11059
+ format: TagFormat.plainText
11060
+ },
11061
+ {
11062
+ // Override inherited @example from group_standardTags: boolean root
11063
+ // example. Note: the legacy reference parser ties the bare-form
11064
+ // example value to `statement.isCorrect`, but the statement is not
11065
+ // yet emitted when this tag fires at bit-header. The pattern below
11066
+ // emits a literal `true` for bare/synthesized and `$` for valued —
11067
+ // sufficient for `[+...]` (correct) statements which dominate the
11068
+ // fixtures; `[-...]` (incorrect) bits with bare `[@example]` would
11069
+ // need either a runtime extension or an explicit `[@example:false]`.
11070
+ key: ConfigKey.property_example,
11071
+ exportJsonKey: [
11072
+ { "@keyonly": { isExample: true, example: true } },
11073
+ { "@absent": { isExample: true, example: true } },
11074
+ { isExample: true, example: "$" }
11075
+ ],
11076
+ description: "The example flag for the bit (boolean)",
11077
+ format: TagFormat.plainText
10450
11078
  }
10451
11079
  ],
10452
11080
  rootExampleType: ExampleType.boolean
@@ -11029,6 +11657,8 @@ var Config = class {
11029
11657
  maxCount: 1,
11030
11658
  chain: tag.chain,
11031
11659
  jsonKey: tag.jsonKey,
11660
+ exportJsonKey: tag.exportJsonKey,
11661
+ hasExportJsonKey: tag.hasExportJsonKey,
11032
11662
  deprecated: tag.deprecated
11033
11663
  });
11034
11664
  finalResourceTags[k] = newTag;
@@ -11133,7 +11763,7 @@ var instance2 = new Config();
11133
11763
  // src/generated/package_info.ts
11134
11764
  var PACKAGE_INFO = {
11135
11765
  "name": "@gmb/bitmark-parser-generator",
11136
- "version": "5.22.0",
11766
+ "version": "5.23.0",
11137
11767
  "author": "Get More Brain Ltd",
11138
11768
  "license": "ISC",
11139
11769
  "description": "A bitmark parser and generator using Peggy.js"
@@ -11727,6 +12357,8 @@ var NodeType = {
11727
12357
  gmbExternalShopItems: "gmbExternalShopItems",
11728
12358
  groupTag: "groupTag",
11729
12359
  groupTagValue: "groupTagValue",
12360
+ gUri: "gUri",
12361
+ gUriValue: "gUriValue",
11730
12362
  handInAcceptFileType: "handInAcceptFileType",
11731
12363
  handInAcceptFileTypeValue: "handInAcceptFileTypeValue",
11732
12364
  handInInstruction: "handInInstruction",
@@ -12069,6 +12701,8 @@ var NodeType = {
12069
12701
  solution: "solution",
12070
12702
  solutions: "solutions",
12071
12703
  solutionsValue: "solutionsValue",
12704
+ sourceBB: "sourceBB",
12705
+ sourceBBValue: "sourceBBValue",
12072
12706
  sourceDocument: "sourceDocument",
12073
12707
  sourceDocumentValue: "sourceDocumentValue",
12074
12708
  sourceRL: "sourceRL",
@@ -24949,6 +25583,7 @@ var Builder = class extends BaseBuilder {
24949
25583
  isCommented: data.isCommented,
24950
25584
  // Properties
24951
25585
  id: this.toAstProperty(bitType, ConfigKey.property_id, data.id, options),
25586
+ gUri: this.toAstProperty(bitType, ConfigKey.property_gUri, data.gUri, options),
24952
25587
  internalComment: this.toAstProperty(
24953
25588
  bitType,
24954
25589
  ConfigKey.property_internalComment,
@@ -25160,6 +25795,7 @@ var Builder = class extends BaseBuilder {
25160
25795
  data.extractorInternal,
25161
25796
  options
25162
25797
  ),
25798
+ sourceBB: this.normaliseSourceBB(data.sourceBB),
25163
25799
  levelCEFRp: this.toAstProperty(
25164
25800
  bitType,
25165
25801
  ConfigKey.property_levelCEFRp,
@@ -26180,6 +26816,19 @@ var Builder = class extends BaseBuilder {
26180
26816
  nodes = Object.values(combinedNodes);
26181
26817
  return nodes.length > 0 ? nodes : void 0;
26182
26818
  }
26819
+ /**
26820
+ * Normalise a sourceBB input into the AST shape (always number[][]).
26821
+ * Accepts a single 4-number tuple or an array of tuples; returns undefined when empty.
26822
+ */
26823
+ normaliseSourceBB(data) {
26824
+ if (data == null) return void 0;
26825
+ if (!Array.isArray(data) || data.length === 0) return void 0;
26826
+ const isNested = data.some(Array.isArray);
26827
+ const tuples = (isNested ? data : [data]).filter(
26828
+ (t) => Array.isArray(t) && t.length === 4 && t.every((n) => typeof n === "number")
26829
+ );
26830
+ return tuples.length > 0 ? tuples : void 0;
26831
+ }
26183
26832
  /**
26184
26833
  * Build groupTag node
26185
26834
  *
@@ -28499,6 +29148,23 @@ var BitmarkGenerator = class extends AstWalkerGenerator {
28499
29148
  format: TagFormat.plainText
28500
29149
  });
28501
29150
  }
29151
+ // bitmarkAst -> bits -> bitsValue -> sourceBB
29152
+ enter_sourceBB(node, route) {
29153
+ const parent = this.getParentNode(route);
29154
+ if (parent?.key !== NodeType.bitsValue) return false;
29155
+ const tuples = node.value;
29156
+ if (!Array.isArray(tuples) || tuples.length === 0) return false;
29157
+ this.writeProperty(
29158
+ "sourceBB",
29159
+ tuples.map((t) => t.join(", ")),
29160
+ route,
29161
+ {
29162
+ format: TagFormat.plainText,
29163
+ array: true
29164
+ }
29165
+ );
29166
+ return false;
29167
+ }
28502
29168
  // bitmarkAst -> bits -> bitsValue -> questions -> questionsValue -> additionalSolutions -> additionalSolutionsValue
28503
29169
  leaf_additionalSolutionsValue(node, route) {
28504
29170
  const parent = this.getParentNode(route, 2);
@@ -30622,6 +31288,16 @@ var JsonGenerator = class extends AstWalkerGenerator {
30622
31288
  enter_ratingLevelEnd(node, route) {
30623
31289
  return this.standardHandler(node, route, NodeType.bitsValue, { array: false });
30624
31290
  }
31291
+ // bitmarkAst -> bits -> bitsValue -> sourceBB
31292
+ enter_sourceBB(node, route) {
31293
+ const tuples = node.value;
31294
+ const parent = this.getParentNode(route);
31295
+ if (parent?.key !== NodeType.bitsValue) return false;
31296
+ if (tuples && tuples.length > 0) {
31297
+ this.bitJson.sourceBB = tuples.length === 1 ? tuples[0] : tuples;
31298
+ }
31299
+ return false;
31300
+ }
30625
31301
  // bitmarkAst -> bits -> bitsValue -> productId
30626
31302
  enter_productId(node, route) {
30627
31303
  const productIds = node.value;
@@ -35300,6 +35976,17 @@ function propertyContentProcessor(context, contentDepth, tagsConfig, content, ta
35300
35976
  format: TextFormat2.bitmarkText,
35301
35977
  location: TextLocation2.tag
35302
35978
  });
35979
+ case TagFormat.coordinates:
35980
+ const coordRaw = instance3.unbreakscape(v2, {
35981
+ format: TextFormat2.plainText,
35982
+ location: TextLocation2.tag
35983
+ });
35984
+ if (coordRaw == null) return void 0;
35985
+ const coordParts = coordRaw.split(",").map((p) => instance6.asNumber(p.trim()));
35986
+ if (coordParts.length !== 4 || coordParts.some((n) => n == null)) {
35987
+ return void 0;
35988
+ }
35989
+ return coordParts;
35303
35990
  }
35304
35991
  }
35305
35992
  return instance3.unbreakscape(v2, {
@@ -35336,6 +36023,8 @@ function propertyContentProcessor(context, contentDepth, tagsConfig, content, ta
35336
36023
  minCount: 1,
35337
36024
  chain: void 0,
35338
36025
  jsonKey: void 0,
36026
+ exportJsonKey: void 0,
36027
+ hasExportJsonKey: false,
35339
36028
  format: TagFormat.bitmarkText,
35340
36029
  values: void 0,
35341
36030
  defaultValue: void 0,
@@ -35346,19 +36035,18 @@ function propertyContentProcessor(context, contentDepth, tagsConfig, content, ta
35346
36035
  }
35347
36036
 
35348
36037
  // src/parser/bitmark/peg/contentProcessors/ReferenceTagContentProcessor.ts
35349
- function referenceTagContentProcessor(_context, _contentDepth, _tagsConfig, content, target, isReferenceEnd) {
35350
- const { value } = content;
36038
+ function referenceTagContentProcessor(context, _contentDepth, tagsConfig, content, target) {
36039
+ const { value, chain } = content;
35351
36040
  const trimmedStringValue = stringUtils.trimmedString(value);
35352
- if (isReferenceEnd) {
35353
- target.referenceEnd = instance3.unbreakscape(trimmedStringValue, {
35354
- format: TextFormat2.bitmarkText,
35355
- location: TextLocation2.tag
35356
- });
35357
- } else {
35358
- target.reference = instance3.unbreakscape(trimmedStringValue, {
35359
- format: TextFormat2.bitmarkText,
35360
- location: TextLocation2.tag
35361
- });
36041
+ target.reference = instance3.unbreakscape(trimmedStringValue, {
36042
+ format: TextFormat2.bitmarkText,
36043
+ location: TextLocation2.tag
36044
+ });
36045
+ if (Array.isArray(chain) && chain.length > 0) {
36046
+ const sub = context.bitContentProcessor(ContentDepth.Chain, tagsConfig, chain);
36047
+ if (sub.reference != null) {
36048
+ target.referenceEnd = sub.reference;
36049
+ }
35362
36050
  }
35363
36051
  }
35364
36052
 
@@ -36044,7 +36732,6 @@ var BitmarkPegParserProcessor = class {
36044
36732
  result.markConfig = [];
36045
36733
  result.extraProperties = {};
36046
36734
  result.internalComments = [];
36047
- let seenReference = false;
36048
36735
  let inFooter = false;
36049
36736
  const bodyParts = [];
36050
36737
  let bodyTextPart = instance3.EMPTY_STRING;
@@ -36080,15 +36767,7 @@ var BitmarkPegParserProcessor = class {
36080
36767
  defaultTagContentProcessor(this.context, contentDepth, tagsConfig, content, result);
36081
36768
  break;
36082
36769
  case TypeKey.Reference:
36083
- referenceTagContentProcessor(
36084
- this.context,
36085
- contentDepth,
36086
- tagsConfig,
36087
- content,
36088
- result,
36089
- seenReference
36090
- );
36091
- seenReference = true;
36770
+ referenceTagContentProcessor(this.context, contentDepth, tagsConfig, content, result);
36092
36771
  break;
36093
36772
  case TypeKey.Title:
36094
36773
  titleTagContentProcessor(this.context, contentDepth, tagsConfig, content, result);
@@ -40468,6 +41147,117 @@ var JsonStringGenerator = class {
40468
41147
  }
40469
41148
  };
40470
41149
 
41150
+ // src/utils/BoundingBox.ts
41151
+ function toBbox(arr) {
41152
+ if (!Array.isArray(arr) || arr.length !== 4) return null;
41153
+ if (!arr.every(Number.isFinite)) return null;
41154
+ return [arr[0], arr[1], arr[2], arr[3]];
41155
+ }
41156
+ function parseSourceBB(sourceBB) {
41157
+ if (sourceBB == null) return [];
41158
+ if (!Array.isArray(sourceBB) || sourceBB.length === 0) return [];
41159
+ const isNested = sourceBB.some(Array.isArray);
41160
+ const candidates = isNested ? sourceBB : [sourceBB];
41161
+ const out = [];
41162
+ for (const candidate of candidates) {
41163
+ const box = toBbox(candidate);
41164
+ if (box) out.push(box);
41165
+ }
41166
+ return out;
41167
+ }
41168
+ function boundingBoxIntersects(a, b) {
41169
+ return a[0] < b[2] && a[2] > b[0] && a[1] < b[3] && a[3] > b[1];
41170
+ }
41171
+ function boundingBoxUnion(boxes) {
41172
+ if (boxes.length === 0) return null;
41173
+ let [x0, y0, x1, y1] = boxes[0];
41174
+ for (let i = 1; i < boxes.length; i++) {
41175
+ const b = boxes[i];
41176
+ if (b[0] < x0) x0 = b[0];
41177
+ if (b[1] < y0) y0 = b[1];
41178
+ if (b[2] > x1) x1 = b[2];
41179
+ if (b[3] > y1) y1 = b[3];
41180
+ }
41181
+ return [x0, y0, x1, y1];
41182
+ }
41183
+ var BoundingBoxIndex = class _BoundingBoxIndex {
41184
+ constructor(entries) {
41185
+ __publicField(this, "_entries");
41186
+ __publicField(this, "bitmarkParser", new BitmarkParserGenerator());
41187
+ this._entries = entries;
41188
+ }
41189
+ /**
41190
+ * Build an index from already-parsed bits. Bits without a parseable
41191
+ * `sourceBB` are dropped. Order of the input is preserved.
41192
+ *
41193
+ * Pass `options.sourceRL` to scope the index to a single source page —
41194
+ * bits whose `sourceRL` doesn't match (or is absent) are excluded.
41195
+ */
41196
+ static fromBits(wrappers, options) {
41197
+ const filterSourceRL = options?.sourceRL;
41198
+ const entries = [];
41199
+ for (const wrapper of wrappers) {
41200
+ if (!wrapper?.bit) continue;
41201
+ if (filterSourceRL !== void 0 && wrapper.bit.sourceRL !== filterSourceRL) {
41202
+ continue;
41203
+ }
41204
+ const boxes = parseSourceBB(wrapper.bit.sourceBB);
41205
+ if (boxes.length === 0) continue;
41206
+ entries.push({ bit: wrapper.bit, wrapper, boxes });
41207
+ }
41208
+ return new _BoundingBoxIndex(entries);
41209
+ }
41210
+ /** All bits with at least one valid `sourceBB`, in input order. */
41211
+ get entries() {
41212
+ return this._entries;
41213
+ }
41214
+ /**
41215
+ * Bits whose ANY `sourceBB` box intersects `query` (strict overlap —
41216
+ * touching-only edges do NOT count as an intersection).
41217
+ */
41218
+ intersecting(query) {
41219
+ const matches = [];
41220
+ for (const entry of this._entries) {
41221
+ if (entry.boxes.some((box) => boundingBoxIntersects(query, box))) {
41222
+ matches.push(entry);
41223
+ }
41224
+ }
41225
+ return matches;
41226
+ }
41227
+ /**
41228
+ * Flat list of every individual `sourceBB` box that intersects `query`.
41229
+ * For a multi-box bit, only the boxes that themselves intersected are
41230
+ * returned.
41231
+ */
41232
+ intersectingBoxes(query) {
41233
+ const matches = [];
41234
+ for (const entry of this._entries) {
41235
+ for (const box of entry.boxes) {
41236
+ if (boundingBoxIntersects(query, box)) matches.push(box);
41237
+ }
41238
+ }
41239
+ return matches;
41240
+ }
41241
+ /**
41242
+ * Smallest axis-aligned box that fully encloses every individual `sourceBB`
41243
+ * box that intersected the query. For a multi-box bit, only the boxes that
41244
+ * themselves intersected contribute to the union — non-intersecting boxes
41245
+ * from the same bit are ignored. Returns `null` if no box matches.
41246
+ */
41247
+ enclosingBoundingBox(query) {
41248
+ return boundingBoxUnion(this.intersectingBoxes(query));
41249
+ }
41250
+ /** Render selected bits back to bitmark text. Empty input returns `''`. */
41251
+ toBitmark(entries) {
41252
+ if (entries.length === 0) return "";
41253
+ const wrappers = entries.map((e) => e.wrapper);
41254
+ return this.bitmarkParser.convert(wrappers, {
41255
+ outputFormat: Output.bitmark,
41256
+ bitmarkOptions: { prettifyJson: true }
41257
+ });
41258
+ }
41259
+ };
41260
+
40471
41261
  // src/index.ts
40472
41262
  init();
40473
41263
  // Annotate the CommonJS export names for ESM import in node:
@@ -40481,6 +41271,7 @@ init();
40481
41271
  BitmarkStringGenerator,
40482
41272
  BitmarkVersion,
40483
41273
  BodyTextFormat,
41274
+ BoundingBoxIndex,
40484
41275
  Builder,
40485
41276
  CardSetVersion,
40486
41277
  InfoFormat,