coh-content-db 2.0.0-rc.19 → 2.0.0-rc.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -1
- package/dist/coh-content-db.d.ts +81 -56
- package/dist/coh-content-db.js +105 -82
- package/dist/coh-content-db.js.map +1 -1
- package/dist/coh-content-db.mjs +103 -81
- package/dist/coh-content-db.mjs.map +1 -1
- package/package.json +1 -1
- package/src/main/api/badge-data.ts +6 -6
- package/src/main/api/morality.ts +15 -0
- package/src/main/api/variant-context.ts +11 -0
- package/src/main/api/{alternate-data.ts → variant-data.ts} +4 -4
- package/src/main/db/badge-index.ts +6 -6
- package/src/main/db/badge-search-options.ts +6 -0
- package/src/main/db/badge.ts +11 -10
- package/src/main/db/variants.ts +84 -0
- package/src/main/index.ts +3 -2
- package/src/test/api/morality.test.ts +31 -0
- package/src/test/db/badge-index.test.ts +12 -0
- package/src/test/db/badge.test.ts +30 -8
- package/src/test/db/{alternates.test.ts → variants.test.ts} +24 -24
- package/src/main/db/alternates.ts +0 -67
package/CHANGELOG.md
CHANGED
|
@@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
-
## [2.0.0-rc.
|
|
8
|
+
## [2.0.0-rc.20] - 2026-01-03
|
|
9
9
|
|
|
10
10
|
### Added
|
|
11
11
|
|
package/dist/coh-content-db.d.ts
CHANGED
|
@@ -11,28 +11,6 @@ type AlignmentExtended = Alignment
|
|
|
11
11
|
| 'all';
|
|
12
12
|
declare function compareAlignment(a?: Alignment, b?: Alignment): number;
|
|
13
13
|
|
|
14
|
-
declare const SEX: readonly ["M", "F"];
|
|
15
|
-
type Sex = typeof SEX[number];
|
|
16
|
-
declare function compareSex(a?: Sex, b?: Sex): number;
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Some badge values differ based on the alignment or sex of the character.
|
|
20
|
-
*/
|
|
21
|
-
interface AlternateData<V> {
|
|
22
|
-
/**
|
|
23
|
-
* The character alignment this alternate applies to.
|
|
24
|
-
*/
|
|
25
|
-
readonly alignment?: Alignment;
|
|
26
|
-
/**
|
|
27
|
-
* The character sex this alternate applies to.
|
|
28
|
-
*/
|
|
29
|
-
readonly sex?: Sex;
|
|
30
|
-
/**
|
|
31
|
-
* The value for this combination.
|
|
32
|
-
*/
|
|
33
|
-
readonly value: V;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
14
|
interface ArchetypeData {
|
|
37
15
|
readonly key: string;
|
|
38
16
|
readonly name: string;
|
|
@@ -131,10 +109,36 @@ interface BadgeRequirementData {
|
|
|
131
109
|
declare const BADGE_TYPE: readonly ["exploration", "history", "accomplishment", "achievement", "accolade", "gladiator", "veteran", "pvp", "invention", "defeat", "event", "ouroboros", "consignment", "day-job", "architect-entertainment"];
|
|
132
110
|
type BadgeType = typeof BADGE_TYPE[number];
|
|
133
111
|
|
|
112
|
+
declare const SEX: readonly ["M", "F"];
|
|
113
|
+
type Sex = typeof SEX[number];
|
|
114
|
+
declare function compareSex(a?: Sex, b?: Sex): number;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Some badge values differ based on the alignment or sex of a character.
|
|
118
|
+
*/
|
|
119
|
+
interface VariantData<V> {
|
|
120
|
+
/**
|
|
121
|
+
* The character alignment this variant applies to.
|
|
122
|
+
*/
|
|
123
|
+
readonly alignment?: Alignment;
|
|
124
|
+
/**
|
|
125
|
+
* The character sex this variant applies to.
|
|
126
|
+
*/
|
|
127
|
+
readonly sex?: Sex;
|
|
128
|
+
/**
|
|
129
|
+
* The value for this combination.
|
|
130
|
+
*/
|
|
131
|
+
readonly value: V;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
134
|
declare const MORALITY: readonly ["hero", "vigilante", "villain", "rogue", "resistance", "loyalist"];
|
|
135
135
|
declare const MORALITY_EXTENDED: readonly ["hero", "vigilante", "villain", "rogue", "resistance", "loyalist", "primal", "praetorian", "heroic", "villainous", "paragon-city-access", "rogue-isles-access", "all"];
|
|
136
136
|
type Morality = typeof MORALITY[number];
|
|
137
137
|
type MoralityExtended = typeof MORALITY_EXTENDED[number];
|
|
138
|
+
/**
|
|
139
|
+
* Maps a morality to the underlying alignment
|
|
140
|
+
*/
|
|
141
|
+
declare const MoralityMap: Record<Morality | Alignment, Alignment>;
|
|
138
142
|
|
|
139
143
|
/**
|
|
140
144
|
* The id, or a pair of ids [primal, praetorian] that are used with the /settitle command to set a badge
|
|
@@ -155,9 +159,9 @@ interface BadgeData {
|
|
|
155
159
|
/**
|
|
156
160
|
* The name of this badge.
|
|
157
161
|
*
|
|
158
|
-
* If the value differs by sex or alignment, include an {@link
|
|
162
|
+
* If the value differs by sex or alignment, include an {@link VariantData} for each variant.
|
|
159
163
|
*/
|
|
160
|
-
readonly name: string |
|
|
164
|
+
readonly name: string | VariantData<string>[];
|
|
161
165
|
/**
|
|
162
166
|
* The date that the badge was added to the game.
|
|
163
167
|
*/
|
|
@@ -169,7 +173,7 @@ interface BadgeData {
|
|
|
169
173
|
/**
|
|
170
174
|
* The badge text as it appears in-game. May vary by character sex or alignment.
|
|
171
175
|
*/
|
|
172
|
-
readonly badgeText?:
|
|
176
|
+
readonly badgeText?: VariantData<MarkdownString>[] | MarkdownString;
|
|
173
177
|
/**
|
|
174
178
|
* Short description of how to acquire the badge. Detailed instructions should go in the notes field.
|
|
175
179
|
*/
|
|
@@ -177,9 +181,9 @@ interface BadgeData {
|
|
|
177
181
|
/**
|
|
178
182
|
* List of absolute URLs for this badge's icons.
|
|
179
183
|
*
|
|
180
|
-
* If the value differs by sex or alignment, include an {@link
|
|
184
|
+
* If the value differs by sex or alignment, include an {@link VariantData} for each variant.
|
|
181
185
|
*/
|
|
182
|
-
readonly icon?: string |
|
|
186
|
+
readonly icon?: string | VariantData<string>[];
|
|
183
187
|
/**
|
|
184
188
|
* Freeform notes or tips about the badge.
|
|
185
189
|
*/
|
|
@@ -425,6 +429,14 @@ interface BundleData {
|
|
|
425
429
|
readonly badges?: BadgeData[];
|
|
426
430
|
}
|
|
427
431
|
|
|
432
|
+
/**
|
|
433
|
+
* For badges, aspects like the name, icon, or badge text can vary depending on context, such as the alignment or sex of the character.
|
|
434
|
+
*/
|
|
435
|
+
interface VariantContext {
|
|
436
|
+
readonly morality?: Morality | Alignment;
|
|
437
|
+
readonly sex?: Sex;
|
|
438
|
+
}
|
|
439
|
+
|
|
428
440
|
declare class AlignmentList {
|
|
429
441
|
#private;
|
|
430
442
|
readonly hero: boolean;
|
|
@@ -437,29 +449,6 @@ declare class AlignmentList {
|
|
|
437
449
|
has(alignment?: AlignmentExtended): boolean;
|
|
438
450
|
}
|
|
439
451
|
|
|
440
|
-
declare class Alternates<T> {
|
|
441
|
-
#private;
|
|
442
|
-
/**
|
|
443
|
-
* Create an alternate set from either a list of categorized values, or a single value when there are no alternates.
|
|
444
|
-
* @param value List of alternates, or a single value.
|
|
445
|
-
*/
|
|
446
|
-
constructor(value: AlternateData<T>[] | T);
|
|
447
|
-
getValue(alignment?: Alignment, sex?: Sex): T | undefined;
|
|
448
|
-
/**
|
|
449
|
-
* Get the default value for this list of alternates, the value with the highest priority and lowest specificity.
|
|
450
|
-
*/
|
|
451
|
-
get default(): AlternateData<T> | undefined;
|
|
452
|
-
/**
|
|
453
|
-
* Get the list of alternates sorted in canonical order (alignment then sex, low to high specificity).
|
|
454
|
-
*/
|
|
455
|
-
get canonical(): AlternateData<T>[];
|
|
456
|
-
/**
|
|
457
|
-
* Create a joined string from the alternate values in canonical order.
|
|
458
|
-
* @param separator Separator to use. Default is ' / '
|
|
459
|
-
*/
|
|
460
|
-
toString(separator: string): string;
|
|
461
|
-
}
|
|
462
|
-
|
|
463
452
|
declare class Archetype {
|
|
464
453
|
readonly key: string;
|
|
465
454
|
readonly name: string;
|
|
@@ -537,6 +526,38 @@ declare class BadgeRequirement {
|
|
|
537
526
|
constructor(data: BadgeRequirementData);
|
|
538
527
|
}
|
|
539
528
|
|
|
529
|
+
declare class Variants<T> {
|
|
530
|
+
#private;
|
|
531
|
+
/**
|
|
532
|
+
* Create a variant set from either a list of categorized values, or a single value when there are no variants.
|
|
533
|
+
* @param value List of variants, or a single value.
|
|
534
|
+
*/
|
|
535
|
+
constructor(value: VariantData<T>[] | T);
|
|
536
|
+
/**
|
|
537
|
+
* Get a variant by context
|
|
538
|
+
* @param context The context
|
|
539
|
+
*/
|
|
540
|
+
getVariant(context?: VariantContext): VariantData<T> | undefined;
|
|
541
|
+
/**
|
|
542
|
+
* Get a value by variant context
|
|
543
|
+
* @param context The context
|
|
544
|
+
*/
|
|
545
|
+
getValue(context?: VariantContext): T | undefined;
|
|
546
|
+
/**
|
|
547
|
+
* Get the default value for this list of variants, the value with the highest priority and lowest specificity.
|
|
548
|
+
*/
|
|
549
|
+
get default(): VariantData<T> | undefined;
|
|
550
|
+
/**
|
|
551
|
+
* Get the list of variants sorted in canonical order (alignment then sex, low to high specificity).
|
|
552
|
+
*/
|
|
553
|
+
get canonical(): VariantData<T>[];
|
|
554
|
+
/**
|
|
555
|
+
* Create a joined string from the variant values in canonical order.
|
|
556
|
+
* @param separator Separator to use. Default is ' / '
|
|
557
|
+
*/
|
|
558
|
+
toString(separator: string): string;
|
|
559
|
+
}
|
|
560
|
+
|
|
540
561
|
declare class MoralityList {
|
|
541
562
|
#private;
|
|
542
563
|
readonly hero: boolean;
|
|
@@ -578,7 +599,7 @@ declare class Badge {
|
|
|
578
599
|
*
|
|
579
600
|
* May vary by character sex or alignment.
|
|
580
601
|
*/
|
|
581
|
-
readonly name:
|
|
602
|
+
readonly name: Variants<string>;
|
|
582
603
|
/**
|
|
583
604
|
* The date that the badge was added to the game.
|
|
584
605
|
*/
|
|
@@ -590,7 +611,7 @@ declare class Badge {
|
|
|
590
611
|
/**
|
|
591
612
|
* The badge text as it appears in-game. May vary by character sex or alignment.
|
|
592
613
|
*/
|
|
593
|
-
readonly badgeText:
|
|
614
|
+
readonly badgeText: Variants<MarkdownString>;
|
|
594
615
|
/**
|
|
595
616
|
* Short description of how to acquire the badge. Detailed instructions will be in the notes field.
|
|
596
617
|
*/
|
|
@@ -600,7 +621,7 @@ declare class Badge {
|
|
|
600
621
|
*
|
|
601
622
|
* May vary by character sex or alignment.
|
|
602
623
|
*/
|
|
603
|
-
readonly icon:
|
|
624
|
+
readonly icon: Variants<string>;
|
|
604
625
|
/**
|
|
605
626
|
* Freeform notes or tips about the badge.
|
|
606
627
|
*/
|
|
@@ -637,7 +658,7 @@ declare class Badge {
|
|
|
637
658
|
*/
|
|
638
659
|
get zoneKey(): string | undefined;
|
|
639
660
|
}
|
|
640
|
-
declare function
|
|
661
|
+
declare function compareByName(a?: Badge, b?: Badge, context?: VariantContext): number;
|
|
641
662
|
declare function compareByZoneKey(a?: Badge, b?: Badge): number;
|
|
642
663
|
declare function compareByReleaseDate(a?: Badge, b?: Badge): number;
|
|
643
664
|
|
|
@@ -662,6 +683,10 @@ interface BadgeSearchOptions {
|
|
|
662
683
|
morality?: Morality;
|
|
663
684
|
predicate?: (badge: Badge) => boolean;
|
|
664
685
|
};
|
|
686
|
+
/**
|
|
687
|
+
* Adjust search results based on a given variant context (morality or sex of a character).
|
|
688
|
+
*/
|
|
689
|
+
variantContext?: VariantContext;
|
|
665
690
|
/**
|
|
666
691
|
* Sort results.
|
|
667
692
|
*
|
|
@@ -1032,5 +1057,5 @@ declare function zoneUri(target: string | Zone | ZoneData): string;
|
|
|
1032
1057
|
*/
|
|
1033
1058
|
declare function zoneLink(target: string | Zone | ZoneData): string;
|
|
1034
1059
|
|
|
1035
|
-
export { ALIGNMENT, AlignmentList,
|
|
1036
|
-
export type { Alignment, AlignmentExtended,
|
|
1060
|
+
export { ALIGNMENT, AlignmentList, Archetype, BADGE_REQUIREMENT_TYPE, BADGE_TYPE, Badge, BadgeIndex, BadgeRequirement, BundleHeader, CohContentDatabase, Contact, ENHANCEMENT_CATEGORY, Key, LevelRange, Location, MISSION_TYPE, MORALITY, MORALITY_EXTENDED, Mission, MoralityList, MoralityMap, SEX, SetTitleIds, Variants, ZONE_TYPE, Zone, badgeLink, badgeUri, compareAlignment, compareByName, compareByReleaseDate, compareByZoneKey, compareSex, contactLink, contactUri, missionLink, missionUri, zoneLink, zoneUri };
|
|
1061
|
+
export type { Alignment, AlignmentExtended, ArchetypeData, BadgeData, BadgeQueryableField, BadgeRequirementData, BadgeRequirementType, BadgeSearchOptions, BadgeSort, BadgeType, BundleData, BundleHeaderData, ContactData, Coords, EnhancementCategory, LevelRangeData, Link, LocationData, LocationIcon, MarkdownString, MissionData, MissionFlashbackData, MissionType, Morality, MoralityExtended, Paged, SetTitleData, Sex, VariantContext, VariantData, ZoneData, ZoneType };
|
package/dist/coh-content-db.js
CHANGED
|
@@ -120,6 +120,15 @@ const MORALITY_EXTENDED = [
|
|
|
120
120
|
*/
|
|
121
121
|
"all"
|
|
122
122
|
];
|
|
123
|
+
const MoralityMap = {
|
|
124
|
+
hero: "hero",
|
|
125
|
+
vigilante: "hero",
|
|
126
|
+
villain: "villain",
|
|
127
|
+
rogue: "villain",
|
|
128
|
+
loyalist: "praetorian",
|
|
129
|
+
resistance: "praetorian",
|
|
130
|
+
praetorian: "praetorian"
|
|
131
|
+
};
|
|
123
132
|
|
|
124
133
|
const SEX = ["M", "F"];
|
|
125
134
|
const SEX_ORDER = Object.fromEntries(SEX.map((x, index) => [x, index]));
|
|
@@ -254,81 +263,17 @@ var __privateGet$4 = (obj, member, getter) => (__accessCheck$5(obj, member, "rea
|
|
|
254
263
|
var __privateAdd$5 = (obj, member, value) => member.has(obj) ? __typeError$5("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
255
264
|
var __privateSet$4 = (obj, member, value, setter) => (__accessCheck$5(obj, member, "write to private field"), member.set(obj, value), value);
|
|
256
265
|
var __privateMethod$2 = (obj, member, method) => (__accessCheck$5(obj, member, "access private method"), method);
|
|
257
|
-
var _sortedValues, _Alternates_instances, compareAlternates_fn;
|
|
258
|
-
class Alternates {
|
|
259
|
-
/**
|
|
260
|
-
* Create an alternate set from either a list of categorized values, or a single value when there are no alternates.
|
|
261
|
-
* @param value List of alternates, or a single value.
|
|
262
|
-
*/
|
|
263
|
-
constructor(value) {
|
|
264
|
-
__privateAdd$5(this, _Alternates_instances);
|
|
265
|
-
__privateAdd$5(this, _sortedValues, []);
|
|
266
|
-
if (Array.isArray(value)) {
|
|
267
|
-
__privateSet$4(this, _sortedValues, value.toSorted());
|
|
268
|
-
__privateGet$4(this, _sortedValues).sort((a, b) => __privateMethod$2(this, _Alternates_instances, compareAlternates_fn).call(this, a, b));
|
|
269
|
-
} else {
|
|
270
|
-
__privateSet$4(this, _sortedValues, [{ value }]);
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
getValue(alignment, sex) {
|
|
274
|
-
for (let index = __privateGet$4(this, _sortedValues).length; index--; ) {
|
|
275
|
-
const entry = __privateGet$4(this, _sortedValues)[index];
|
|
276
|
-
if ((entry.alignment === void 0 || entry.alignment === alignment) && (entry.sex === void 0 || entry.sex === sex)) return entry.value;
|
|
277
|
-
}
|
|
278
|
-
return this.default?.value;
|
|
279
|
-
}
|
|
280
|
-
/**
|
|
281
|
-
* Get the default value for this list of alternates, the value with the highest priority and lowest specificity.
|
|
282
|
-
*/
|
|
283
|
-
get default() {
|
|
284
|
-
return __privateGet$4(this, _sortedValues)[0];
|
|
285
|
-
}
|
|
286
|
-
/**
|
|
287
|
-
* Get the list of alternates sorted in canonical order (alignment then sex, low to high specificity).
|
|
288
|
-
*/
|
|
289
|
-
get canonical() {
|
|
290
|
-
return __privateGet$4(this, _sortedValues);
|
|
291
|
-
}
|
|
292
|
-
/**
|
|
293
|
-
* Create a joined string from the alternate values in canonical order.
|
|
294
|
-
* @param separator Separator to use. Default is ' / '
|
|
295
|
-
*/
|
|
296
|
-
toString(separator) {
|
|
297
|
-
return this.canonical.map((x) => x.value).join(separator);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
_sortedValues = new WeakMap();
|
|
301
|
-
_Alternates_instances = new WeakSet();
|
|
302
|
-
compareAlternates_fn = function(a, b) {
|
|
303
|
-
const aSpecificity = (a.alignment ? 2 : 0) + (a.sex ? 1 : 0);
|
|
304
|
-
const bSpecificity = (b.alignment ? 2 : 0) + (b.sex ? 1 : 0);
|
|
305
|
-
if (aSpecificity !== bSpecificity) return aSpecificity - bSpecificity;
|
|
306
|
-
const alignmentComparison = compareAlignment(a.alignment, b.alignment);
|
|
307
|
-
if (alignmentComparison !== 0) return alignmentComparison;
|
|
308
|
-
const sexComparison = compareSex(a.sex, b.sex);
|
|
309
|
-
if (sexComparison !== 0) return sexComparison;
|
|
310
|
-
return String(a.value).localeCompare(String(b.value));
|
|
311
|
-
};
|
|
312
|
-
|
|
313
|
-
var __typeError$4 = (msg) => {
|
|
314
|
-
throw TypeError(msg);
|
|
315
|
-
};
|
|
316
|
-
var __accessCheck$4 = (obj, member, msg) => member.has(obj) || __typeError$4("Cannot " + msg);
|
|
317
|
-
var __privateGet$3 = (obj, member, getter) => (__accessCheck$4(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
318
|
-
var __privateAdd$4 = (obj, member, value) => member.has(obj) ? __typeError$4("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
319
|
-
var __privateSet$3 = (obj, member, value, setter) => (__accessCheck$4(obj, member, "write to private field"), member.set(obj, value), value);
|
|
320
|
-
var __privateMethod$1 = (obj, member, method) => (__accessCheck$4(obj, member, "access private method"), method);
|
|
321
266
|
var _value, _Key_instances, validateKey_fn;
|
|
322
267
|
const INVALID_KEY_PATTERN = /[^a-z0-9-]/;
|
|
323
268
|
class Key {
|
|
324
269
|
constructor(value) {
|
|
325
|
-
__privateAdd$
|
|
326
|
-
__privateAdd$
|
|
327
|
-
__privateMethod$
|
|
328
|
-
__privateSet$
|
|
270
|
+
__privateAdd$5(this, _Key_instances);
|
|
271
|
+
__privateAdd$5(this, _value);
|
|
272
|
+
__privateMethod$2(this, _Key_instances, validateKey_fn).call(this, value);
|
|
273
|
+
__privateSet$4(this, _value, value);
|
|
329
274
|
}
|
|
330
275
|
get value() {
|
|
331
|
-
return __privateGet$
|
|
276
|
+
return __privateGet$4(this, _value);
|
|
332
277
|
}
|
|
333
278
|
}
|
|
334
279
|
_value = new WeakMap();
|
|
@@ -421,6 +366,83 @@ class BadgeRequirement {
|
|
|
421
366
|
}
|
|
422
367
|
}
|
|
423
368
|
|
|
369
|
+
var __typeError$4 = (msg) => {
|
|
370
|
+
throw TypeError(msg);
|
|
371
|
+
};
|
|
372
|
+
var __accessCheck$4 = (obj, member, msg) => member.has(obj) || __typeError$4("Cannot " + msg);
|
|
373
|
+
var __privateGet$3 = (obj, member, getter) => (__accessCheck$4(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
374
|
+
var __privateAdd$4 = (obj, member, value) => member.has(obj) ? __typeError$4("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
375
|
+
var __privateSet$3 = (obj, member, value, setter) => (__accessCheck$4(obj, member, "write to private field"), member.set(obj, value), value);
|
|
376
|
+
var __privateMethod$1 = (obj, member, method) => (__accessCheck$4(obj, member, "access private method"), method);
|
|
377
|
+
var _sortedValues, _Variants_instances, compareVariants_fn;
|
|
378
|
+
class Variants {
|
|
379
|
+
/**
|
|
380
|
+
* Create a variant set from either a list of categorized values, or a single value when there are no variants.
|
|
381
|
+
* @param value List of variants, or a single value.
|
|
382
|
+
*/
|
|
383
|
+
constructor(value) {
|
|
384
|
+
__privateAdd$4(this, _Variants_instances);
|
|
385
|
+
__privateAdd$4(this, _sortedValues, []);
|
|
386
|
+
if (Array.isArray(value)) {
|
|
387
|
+
__privateSet$3(this, _sortedValues, value.toSorted());
|
|
388
|
+
__privateGet$3(this, _sortedValues).sort((a, b) => __privateMethod$1(this, _Variants_instances, compareVariants_fn).call(this, a, b));
|
|
389
|
+
} else {
|
|
390
|
+
__privateSet$3(this, _sortedValues, [{ value }]);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Get a variant by context
|
|
395
|
+
* @param context The context
|
|
396
|
+
*/
|
|
397
|
+
getVariant(context) {
|
|
398
|
+
const alignment = context?.morality ? MoralityMap[context.morality] : void 0;
|
|
399
|
+
const sex = context?.sex;
|
|
400
|
+
for (let index = __privateGet$3(this, _sortedValues).length; index--; ) {
|
|
401
|
+
const entry = __privateGet$3(this, _sortedValues)[index];
|
|
402
|
+
if ((entry.alignment === void 0 || entry.alignment === alignment) && (entry.sex === void 0 || entry.sex === sex)) return entry;
|
|
403
|
+
}
|
|
404
|
+
return this.default;
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Get a value by variant context
|
|
408
|
+
* @param context The context
|
|
409
|
+
*/
|
|
410
|
+
getValue(context) {
|
|
411
|
+
return this.getVariant(context)?.value;
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Get the default value for this list of variants, the value with the highest priority and lowest specificity.
|
|
415
|
+
*/
|
|
416
|
+
get default() {
|
|
417
|
+
return __privateGet$3(this, _sortedValues)[0];
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Get the list of variants sorted in canonical order (alignment then sex, low to high specificity).
|
|
421
|
+
*/
|
|
422
|
+
get canonical() {
|
|
423
|
+
return __privateGet$3(this, _sortedValues);
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Create a joined string from the variant values in canonical order.
|
|
427
|
+
* @param separator Separator to use. Default is ' / '
|
|
428
|
+
*/
|
|
429
|
+
toString(separator) {
|
|
430
|
+
return this.canonical.map((x) => x.value).join(separator);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
_sortedValues = new WeakMap();
|
|
434
|
+
_Variants_instances = new WeakSet();
|
|
435
|
+
compareVariants_fn = function(a, b) {
|
|
436
|
+
const aSpecificity = (a.alignment ? 2 : 0) + (a.sex ? 1 : 0);
|
|
437
|
+
const bSpecificity = (b.alignment ? 2 : 0) + (b.sex ? 1 : 0);
|
|
438
|
+
if (aSpecificity !== bSpecificity) return aSpecificity - bSpecificity;
|
|
439
|
+
const alignmentComparison = compareAlignment(a.alignment, b.alignment);
|
|
440
|
+
if (alignmentComparison !== 0) return alignmentComparison;
|
|
441
|
+
const sexComparison = compareSex(a.sex, b.sex);
|
|
442
|
+
if (sexComparison !== 0) return sexComparison;
|
|
443
|
+
return String(a.value).localeCompare(String(b.value));
|
|
444
|
+
};
|
|
445
|
+
|
|
424
446
|
var __defProp$9 = Object.defineProperty;
|
|
425
447
|
var __typeError$3 = (msg) => {
|
|
426
448
|
throw TypeError(msg);
|
|
@@ -649,12 +671,12 @@ class Badge {
|
|
|
649
671
|
__publicField$6(this, "ignoreInTotals");
|
|
650
672
|
this.key = new Key(badgeData.key).value;
|
|
651
673
|
this.type = badgeData.type;
|
|
652
|
-
this.name = new
|
|
674
|
+
this.name = new Variants(badgeData.name);
|
|
653
675
|
this.releaseDate = toDate(badgeData.releaseDate);
|
|
654
676
|
this.morality = new MoralityList(coalesceToArray(badgeData.morality));
|
|
655
|
-
this.badgeText = new
|
|
677
|
+
this.badgeText = new Variants(badgeData.badgeText ?? []);
|
|
656
678
|
this.acquisition = badgeData.acquisition;
|
|
657
|
-
this.icon = new
|
|
679
|
+
this.icon = new Variants(badgeData.icon ?? []);
|
|
658
680
|
this.notes = badgeData.notes;
|
|
659
681
|
this.links = badgeData.links ?? [];
|
|
660
682
|
this.effect = badgeData.effect;
|
|
@@ -691,9 +713,9 @@ class Badge {
|
|
|
691
713
|
}
|
|
692
714
|
_requirementsIndex = new WeakMap();
|
|
693
715
|
_zoneKeys = new WeakMap();
|
|
694
|
-
function
|
|
695
|
-
const aName = a?.name
|
|
696
|
-
const bName = b?.name
|
|
716
|
+
function compareByName(a, b, context) {
|
|
717
|
+
const aName = a?.name?.getValue(context);
|
|
718
|
+
const bName = b?.name?.getValue(context);
|
|
697
719
|
if (!aName && !bName) return 0;
|
|
698
720
|
if (!aName) return 1;
|
|
699
721
|
if (!bName) return -1;
|
|
@@ -730,7 +752,7 @@ class BadgeIndex extends AbstractIndex {
|
|
|
730
752
|
}
|
|
731
753
|
search(options) {
|
|
732
754
|
const filtered = options?.query || options?.filter ? this._values.filter((badge) => __privateMethod(this, _BadgeIndex_instances, satisfiesQueryPredicate_fn).call(this, badge, options?.query) && __privateMethod(this, _BadgeIndex_instances, satisfiesFilterPredicate_fn).call(this, badge, options?.filter)) : this._values;
|
|
733
|
-
const sorted = __privateMethod(this, _BadgeIndex_instances, sort_fn).call(this, filtered, options
|
|
755
|
+
const sorted = __privateMethod(this, _BadgeIndex_instances, sort_fn).call(this, filtered, options);
|
|
734
756
|
const totalPages = options?.pageSize ? Math.ceil(filtered.length / options?.pageSize) : 1;
|
|
735
757
|
const page = Math.max(1, Math.min(totalPages, options?.page ?? 1));
|
|
736
758
|
const paged = options?.pageSize ? sorted.slice((page - 1) * options.pageSize, page * options?.pageSize) : sorted;
|
|
@@ -753,13 +775,13 @@ satisfiesQueryPredicate_fn = function(badge, query) {
|
|
|
753
775
|
satisfiesFilterPredicate_fn = function(badge, filter) {
|
|
754
776
|
return (!filter?.type || badge.type === filter.type) && (!filter?.zoneKey || badge.zoneKey === filter.zoneKey) && (!filter?.morality || badge.morality.has(filter.morality)) && (!filter?.predicate || filter.predicate(badge));
|
|
755
777
|
};
|
|
756
|
-
sort_fn = function(badges,
|
|
757
|
-
switch (sort) {
|
|
778
|
+
sort_fn = function(badges, options) {
|
|
779
|
+
switch (options?.sort) {
|
|
758
780
|
case "name.asc": {
|
|
759
|
-
return badges.toSorted(
|
|
781
|
+
return badges.toSorted((a, b) => compareByName(a, b, options.variantContext));
|
|
760
782
|
}
|
|
761
783
|
case "name.desc": {
|
|
762
|
-
return badges.toSorted((a, b) =>
|
|
784
|
+
return badges.toSorted((a, b) => compareByName(b, a, options.variantContext));
|
|
763
785
|
}
|
|
764
786
|
case "zone-key.asc": {
|
|
765
787
|
return badges.toSorted(compareByZoneKey);
|
|
@@ -1193,7 +1215,6 @@ function zoneLink(target) {
|
|
|
1193
1215
|
|
|
1194
1216
|
exports.ALIGNMENT = ALIGNMENT;
|
|
1195
1217
|
exports.AlignmentList = AlignmentList;
|
|
1196
|
-
exports.Alternates = Alternates;
|
|
1197
1218
|
exports.Archetype = Archetype;
|
|
1198
1219
|
exports.BADGE_REQUIREMENT_TYPE = BADGE_REQUIREMENT_TYPE;
|
|
1199
1220
|
exports.BADGE_TYPE = BADGE_TYPE;
|
|
@@ -1212,14 +1233,16 @@ exports.MORALITY = MORALITY;
|
|
|
1212
1233
|
exports.MORALITY_EXTENDED = MORALITY_EXTENDED;
|
|
1213
1234
|
exports.Mission = Mission;
|
|
1214
1235
|
exports.MoralityList = MoralityList;
|
|
1236
|
+
exports.MoralityMap = MoralityMap;
|
|
1215
1237
|
exports.SEX = SEX;
|
|
1216
1238
|
exports.SetTitleIds = SetTitleIds;
|
|
1239
|
+
exports.Variants = Variants;
|
|
1217
1240
|
exports.ZONE_TYPE = ZONE_TYPE;
|
|
1218
1241
|
exports.Zone = Zone;
|
|
1219
1242
|
exports.badgeLink = badgeLink;
|
|
1220
1243
|
exports.badgeUri = badgeUri;
|
|
1221
1244
|
exports.compareAlignment = compareAlignment;
|
|
1222
|
-
exports.
|
|
1245
|
+
exports.compareByName = compareByName;
|
|
1223
1246
|
exports.compareByReleaseDate = compareByReleaseDate;
|
|
1224
1247
|
exports.compareByZoneKey = compareByZoneKey;
|
|
1225
1248
|
exports.compareSex = compareSex;
|