coh-content-db 2.0.0-rc.2 → 2.0.0-rc.21

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.
Files changed (120) hide show
  1. package/.editorconfig +10 -11
  2. package/.github/workflows/build.yml +4 -2
  3. package/.github/workflows/pull-request.yml +1 -1
  4. package/.github/workflows/release.yml +1 -1
  5. package/CHANGELOG.md +47 -0
  6. package/README.md +77 -32
  7. package/dist/coh-content-db.d.ts +755 -290
  8. package/dist/coh-content-db.js +1028 -358
  9. package/dist/coh-content-db.js.map +1 -1
  10. package/dist/coh-content-db.mjs +998 -349
  11. package/dist/coh-content-db.mjs.map +1 -1
  12. package/eslint.config.mjs +1 -0
  13. package/jest.config.mjs +1 -0
  14. package/package.json +14 -14
  15. package/src/main/api/alignment.ts +18 -2
  16. package/src/main/api/badge-data.ts +29 -51
  17. package/src/main/api/badge-requirement-data.ts +64 -0
  18. package/src/main/api/badge-requirement-type.ts +32 -0
  19. package/src/main/api/badge-type.ts +15 -15
  20. package/src/main/api/bundle-data.ts +47 -0
  21. package/src/main/api/bundle-header-data.ts +44 -0
  22. package/src/main/api/contact-data.ts +49 -0
  23. package/src/main/api/enhancement-category.ts +26 -26
  24. package/src/main/api/level-range-data.ts +4 -0
  25. package/src/main/api/location-data.ts +28 -0
  26. package/src/main/api/markdown-string.ts +4 -0
  27. package/src/main/api/mission-data.ts +57 -0
  28. package/src/main/api/mission-flashback-data.ts +31 -0
  29. package/src/main/api/mission-type.ts +2 -0
  30. package/src/main/api/morality.ts +49 -0
  31. package/src/main/api/set-title-data.ts +4 -0
  32. package/src/main/api/sex.ts +8 -1
  33. package/src/main/api/variant-context.ts +11 -0
  34. package/src/main/api/variant-data.ts +22 -0
  35. package/src/main/api/zone-data.ts +44 -0
  36. package/src/main/api/zone-type.ts +59 -0
  37. package/src/main/db/abstract-index.ts +37 -0
  38. package/src/main/db/alignment-list.ts +54 -0
  39. package/src/main/db/badge-index.ts +83 -0
  40. package/src/main/db/badge-requirement.ts +81 -0
  41. package/src/main/db/badge-search-options.ts +52 -0
  42. package/src/main/db/badge.ts +97 -74
  43. package/src/main/db/bundle-header.ts +52 -0
  44. package/src/main/db/coh-content-database.ts +123 -14
  45. package/src/main/db/contact.ts +63 -0
  46. package/src/main/db/level-range.ts +15 -0
  47. package/src/main/db/location.ts +30 -0
  48. package/src/main/db/mission.ts +108 -0
  49. package/src/main/db/morality-list.ts +99 -0
  50. package/src/main/db/paged.ts +11 -0
  51. package/src/main/db/set-title-ids.ts +10 -0
  52. package/src/main/db/variants.ts +84 -0
  53. package/src/main/db/zone.ts +57 -0
  54. package/src/main/index.ts +33 -18
  55. package/src/main/util/coalesce-to-array.ts +13 -0
  56. package/src/main/util/links.ts +104 -0
  57. package/src/main/util/to-date.ts +9 -0
  58. package/src/test/api/alignment.test.ts +38 -4
  59. package/src/test/api/badge-data.fixture.ts +2 -15
  60. package/src/test/api/badge-data.test.ts +5 -4
  61. package/src/test/api/badge-requirement-data.fixture.ts +7 -0
  62. package/src/test/api/badge-requirement-type.test.ts +31 -0
  63. package/src/test/api/badge-type.test.ts +5 -5
  64. package/src/test/api/bundle-data.fixture.ts +7 -0
  65. package/src/test/api/bundle-header-data.fixture.ts +8 -0
  66. package/src/test/api/contact-data.fixture.ts +7 -0
  67. package/src/test/api/enhancement-category.test.ts +5 -5
  68. package/src/test/api/mission-data.fixture.ts +12 -0
  69. package/src/test/api/morality.test.ts +31 -0
  70. package/src/test/api/sex.test.ts +33 -1
  71. package/src/test/api/zone-data.fixture.ts +9 -0
  72. package/src/test/db/abstract-index.test.ts +55 -0
  73. package/src/test/db/alignment-list.test.ts +200 -0
  74. package/src/test/db/badge-index.test.ts +653 -0
  75. package/src/test/db/badge-requirement.test.ts +145 -0
  76. package/src/test/db/badge.test.ts +416 -14
  77. package/src/test/db/bundle-header.test.ts +89 -0
  78. package/src/test/db/coh-content-database.test.ts +265 -24
  79. package/src/test/db/contact.test.ts +98 -0
  80. package/src/test/db/level-range.test.ts +47 -0
  81. package/src/test/db/location.test.ts +51 -0
  82. package/src/test/db/mission.test.ts +173 -0
  83. package/src/test/db/morality-list.test.ts +457 -0
  84. package/src/test/db/set-title-ids.test.ts +19 -0
  85. package/src/test/db/variants.test.ts +188 -0
  86. package/src/test/db/zone.test.ts +81 -0
  87. package/src/test/integration.test.ts +16 -0
  88. package/src/test/util/coalese-to-array.test.ts +17 -0
  89. package/src/test/util/links.test.ts +149 -0
  90. package/src/test/util/to-date.test.ts +15 -0
  91. package/src/main/api/alternate-data.ts +0 -22
  92. package/src/main/api/badge-partial-data.ts +0 -65
  93. package/src/main/api/badge-partial-type.ts +0 -8
  94. package/src/main/api/change.ts +0 -14
  95. package/src/main/api/game-map-data.ts +0 -26
  96. package/src/main/api/plaque-type.ts +0 -6
  97. package/src/main/api/server-group-data.ts +0 -65
  98. package/src/main/api/vidiot-map-data.ts +0 -18
  99. package/src/main/api/vidiot-map-point-of-interest-data.ts +0 -30
  100. package/src/main/changelog.ts +0 -20
  101. package/src/main/db/alternates.ts +0 -81
  102. package/src/main/db/badge-partial.ts +0 -35
  103. package/src/main/db/game-map.ts +0 -33
  104. package/src/main/db/server-group.ts +0 -112
  105. package/src/main/db/vidiot-map-point-of-interest.ts +0 -40
  106. package/src/main/db/vidiot-map.ts +0 -25
  107. package/src/main/util.ts +0 -17
  108. package/src/test/api/badge-partial-data.fixture.ts +0 -17
  109. package/src/test/api/badge-partial-type.test.ts +0 -31
  110. package/src/test/api/game-map-data.fixture.ts +0 -10
  111. package/src/test/api/plaque-type.test.ts +0 -31
  112. package/src/test/api/server-group-data.fixture.ts +0 -23
  113. package/src/test/api/server-group-data.test.ts +0 -15
  114. package/src/test/api/vidiot-map-point-of-interest.fixture.ts +0 -10
  115. package/src/test/api/vidiot-map.fixture.ts +0 -9
  116. package/src/test/changelog.test.ts +0 -36
  117. package/src/test/db/alternates.test.ts +0 -223
  118. package/src/test/db/server-group.test.ts +0 -124
  119. package/src/test/index.test.ts +0 -10
  120. package/src/test/util.test.ts +0 -39
@@ -1,83 +1,274 @@
1
- const ALIGNMENT = ["H", "V", "P"];
1
+ const ALIGNMENT = ["hero", "villain", "praetorian"];
2
+ const ALIGNMENT_ORDER = Object.fromEntries(ALIGNMENT.map((x, index) => [x, index]));
3
+ function compareAlignment(a, b) {
4
+ const orderA = a ? ALIGNMENT_ORDER[a] : -1;
5
+ const orderB = b ? ALIGNMENT_ORDER[b] : -1;
6
+ return orderA - orderB;
7
+ }
2
8
 
3
- const BADGE_PARTIAL_TYPE = [
4
- "PLAQUE",
5
- "BADGE",
6
- "INVENTION",
7
- "INVENTION_PLUS_ONE"
8
- // Some invention badges require you to build x of two different invention levels, 'plus one of either level'.
9
+ const BADGE_REQUIREMENT_TYPE = [
10
+ /**
11
+ * Collect a badge.
12
+ */
13
+ "badge",
14
+ /**
15
+ * Craft an invention.
16
+ */
17
+ "invention",
18
+ /**
19
+ * Some invention badges require you to build x of two different invention levels, 'plus one of either level'.
20
+ */
21
+ "invention-plus-one",
22
+ /**
23
+ * Visit a location.
24
+ */
25
+ "location",
26
+ /**
27
+ * Click on a monument.
28
+ */
29
+ "monument",
30
+ /**
31
+ * Complete a mission.
32
+ */
33
+ "mission",
34
+ /**
35
+ * Complete an arbitrary task.
36
+ */
37
+ "task"
9
38
  ];
10
39
 
11
40
  const BADGE_TYPE = [
12
- "EXPLORATION",
13
- "HISTORY",
14
- "ACCOMPLISHMENT",
15
- "ACHIEVEMENT",
16
- "ACCOLADE",
17
- "GLADIATOR",
18
- "VETERAN",
19
- "PVP",
20
- "INVENTION",
21
- "DEFEAT",
22
- "EVENT",
23
- "OUROBOROS",
24
- "CONSIGNMENT",
25
- "DAY_JOB",
26
- "AE"
41
+ "exploration",
42
+ "history",
43
+ "accomplishment",
44
+ "achievement",
45
+ "accolade",
46
+ "gladiator",
47
+ "veteran",
48
+ "pvp",
49
+ "invention",
50
+ "defeat",
51
+ "event",
52
+ "ouroboros",
53
+ "consignment",
54
+ "day-job",
55
+ "architect-entertainment"
27
56
  ];
28
57
 
29
58
  const ENHANCEMENT_CATEGORY = [
30
- "DEFENSE_DEBUFF",
31
- "TO_HIT_DEBUFF",
32
- "TAUNT",
33
- "CONFUSE",
34
- "HEALING",
35
- "DEFENSE_BUFF",
36
- "RESIST_DAMAGE",
37
- "INTANGIBILITY",
38
- "SLEEP",
39
- "SLOW",
40
- "HOLD",
41
- "STUN",
42
- "IMMOBILIZE",
43
- "FEAR",
44
- "ENDURANCE_MODIFICATION",
45
- "ENDURANCE_REDUCTION",
46
- "RECHARGE_REDUCTION",
47
- "INTERRUPT_DURATION",
48
- "ACCURACY",
49
- "TO_HIT_BUFF",
50
- "DAMAGE",
51
- "KNOCKBACK",
52
- "RUN_SPEED",
53
- "JUMP",
54
- "FLY_SPEED",
55
- "RANGE"
59
+ "defense-debuff",
60
+ "to-hit-debuff",
61
+ "taunt",
62
+ "confuse",
63
+ "healing",
64
+ "defense-buff",
65
+ "resist-damage",
66
+ "intangibility",
67
+ "sleep",
68
+ "slow",
69
+ "hold",
70
+ "stun",
71
+ "immobilize",
72
+ "fear",
73
+ "endurance-modification",
74
+ "endurance-reduction",
75
+ "recharge-reduction",
76
+ "interrupt-duration",
77
+ "accuracy",
78
+ "to-hit-buff",
79
+ "damage",
80
+ "knockback",
81
+ "run-speed",
82
+ "jump",
83
+ "fly-speed",
84
+ "range"
56
85
  ];
57
86
 
58
- const PLAQUE_TYPE = [
59
- "WALL_PLAQUE",
60
- "MONUMENT"
87
+ const MISSION_TYPE = ["story-arc", "mission", "task-force", "strike-force", "trial", "personal-story"];
88
+
89
+ const MORALITY = ["hero", "vigilante", "villain", "rogue", "resistance", "loyalist"];
90
+ const MORALITY_EXTENDED = [
91
+ ...MORALITY,
92
+ /**
93
+ * Any of the Primal Earth moralities - Hero, Vigilante, Villain, Rogue.
94
+ */
95
+ "primal",
96
+ /**
97
+ * Either of the Praetorian Earth moralities - Resistance or Loyalist.
98
+ */
99
+ "praetorian",
100
+ /**
101
+ * The moralities that roll up to the Hero {@link Alignment} - Hero and Vigilante.
102
+ */
103
+ "heroic",
104
+ /**
105
+ * The moralities that roll up to the Villain {@link Alignment} - Villain and Rogue.
106
+ */
107
+ "villainous",
108
+ /**
109
+ * Moralities with access to Paragon City - Hero, Vigilante and Rogue.
110
+ */
111
+ "paragon-city-access",
112
+ /**
113
+ * Moralities with access to the Rogue Isles - Villain, Rogue and Vigilante.
114
+ */
115
+ "rogue-isles-access",
116
+ /**
117
+ * All the moralities.
118
+ */
119
+ "all"
61
120
  ];
121
+ const MoralityMap = {
122
+ hero: "hero",
123
+ vigilante: "hero",
124
+ villain: "villain",
125
+ rogue: "villain",
126
+ loyalist: "praetorian",
127
+ resistance: "praetorian",
128
+ praetorian: "praetorian"
129
+ };
62
130
 
63
131
  const SEX = ["M", "F"];
132
+ const SEX_ORDER = Object.fromEntries(SEX.map((x, index) => [x, index]));
133
+ function compareSex(a, b) {
134
+ const orderA = a ? SEX_ORDER[a] : -1;
135
+ const orderB = b ? SEX_ORDER[b] : -1;
136
+ return orderA - orderB;
137
+ }
64
138
 
65
- var __typeError$4 = (msg) => {
139
+ const ZONE_TYPE = [
140
+ /**
141
+ * The standard zone type, even if not technically occurring in the 'City' proper.
142
+ */
143
+ "city",
144
+ /**
145
+ * An Ouroboros flashback to a zone as it was in a previous era.
146
+ */
147
+ "echo",
148
+ /**
149
+ * Tutorial zon, usually inaccessible after leaving.
150
+ */
151
+ "tutorial",
152
+ /**
153
+ * Trial zones, like the Abandoned Sewers trial.
154
+ */
155
+ "trial",
156
+ /**
157
+ * Hazard zones like the Hollows.
158
+ */
159
+ "hazard",
160
+ /**
161
+ * Mayhem mission zones.
162
+ */
163
+ "mayhem",
164
+ /**
165
+ * Safeguard mission zones.
166
+ */
167
+ "safeguard",
168
+ /**
169
+ * Exists inside a mission not covered by the other types.
170
+ */
171
+ "mission",
172
+ /**
173
+ * Incarnate trial zones.
174
+ */
175
+ "incarnate",
176
+ /**
177
+ * Cooprative zones where Heroes and Villains can team up for PvE content.
178
+ */
179
+ "co-op",
180
+ /**
181
+ * PvP zones like Bloody Bay.
182
+ */
183
+ "pvp",
184
+ /**
185
+ * Located in an arena PvP map.
186
+ */
187
+ "arena",
188
+ /**
189
+ * A building, usually contained within another zone, like the AE buildings.
190
+ */
191
+ "building",
192
+ /**
193
+ * Stuff like the (Phone only) zone.
194
+ */
195
+ "other"
196
+ ];
197
+
198
+ var __defProp$c = Object.defineProperty;
199
+ var __typeError$6 = (msg) => {
66
200
  throw TypeError(msg);
67
201
  };
68
- var __accessCheck$4 = (obj, member, msg) => member.has(obj) || __typeError$4("Cannot " + msg);
69
- var __privateGet$4 = (obj, member, getter) => (__accessCheck$4(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
70
- 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);
71
- var __privateSet$1 = (obj, member, value, setter) => (__accessCheck$4(obj, member, "write to private field"), member.set(obj, value), value);
72
- var __privateMethod$1 = (obj, member, method) => (__accessCheck$4(obj, member, "access private method"), method);
202
+ var __defNormalProp$c = (obj, key, value) => key in obj ? __defProp$c(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
203
+ var __publicField$c = (obj, key, value) => __defNormalProp$c(obj, typeof key !== "symbol" ? key + "" : key, value);
204
+ var __accessCheck$6 = (obj, member, msg) => member.has(obj) || __typeError$6("Cannot " + msg);
205
+ var __privateGet$5 = (obj, member, getter) => (__accessCheck$6(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
206
+ var __privateAdd$6 = (obj, member, value) => member.has(obj) ? __typeError$6("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
207
+ var __privateSet$5 = (obj, member, value, setter) => (__accessCheck$6(obj, member, "write to private field"), member.set(obj, value), value);
208
+ var _items$1;
209
+ class AlignmentList {
210
+ constructor(items) {
211
+ __privateAdd$6(this, _items$1);
212
+ __publicField$c(this, "hero");
213
+ __publicField$c(this, "villain");
214
+ __publicField$c(this, "praetorian");
215
+ __publicField$c(this, "primal");
216
+ __publicField$c(this, "all");
217
+ const set = new Set(items ?? [...ALIGNMENT]);
218
+ this.hero = set.has("hero") || set.has("primal") || set.has("all");
219
+ this.villain = set.has("villain") || set.has("primal") || set.has("all");
220
+ this.praetorian = set.has("praetorian") || set.has("all");
221
+ this.primal = this.hero && this.villain;
222
+ this.all = this.hero && this.villain && this.praetorian;
223
+ __privateSet$5(this, _items$1, /* @__PURE__ */ new Set());
224
+ if (this.hero) __privateGet$5(this, _items$1).add("hero");
225
+ if (this.villain) __privateGet$5(this, _items$1).add("villain");
226
+ if (this.praetorian) __privateGet$5(this, _items$1).add("praetorian");
227
+ }
228
+ get items() {
229
+ return [...__privateGet$5(this, _items$1)];
230
+ }
231
+ has(alignment) {
232
+ switch (alignment) {
233
+ case "hero": {
234
+ return this.hero;
235
+ }
236
+ case "villain": {
237
+ return this.villain;
238
+ }
239
+ case "praetorian": {
240
+ return this.praetorian;
241
+ }
242
+ case "primal": {
243
+ return this.primal;
244
+ }
245
+ case "all": {
246
+ return this.all;
247
+ }
248
+ default: {
249
+ return false;
250
+ }
251
+ }
252
+ }
253
+ }
254
+ _items$1 = new WeakMap();
255
+
256
+ var __typeError$5 = (msg) => {
257
+ throw TypeError(msg);
258
+ };
259
+ var __accessCheck$5 = (obj, member, msg) => member.has(obj) || __typeError$5("Cannot " + msg);
260
+ var __privateGet$4 = (obj, member, getter) => (__accessCheck$5(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
261
+ 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);
262
+ var __privateSet$4 = (obj, member, value, setter) => (__accessCheck$5(obj, member, "write to private field"), member.set(obj, value), value);
263
+ var __privateMethod$2 = (obj, member, method) => (__accessCheck$5(obj, member, "access private method"), method);
73
264
  var _value, _Key_instances, validateKey_fn;
74
265
  const INVALID_KEY_PATTERN = /[^a-z0-9-]/;
75
266
  class Key {
76
267
  constructor(value) {
77
- __privateAdd$4(this, _Key_instances);
78
- __privateAdd$4(this, _value);
79
- __privateMethod$1(this, _Key_instances, validateKey_fn).call(this, value);
80
- __privateSet$1(this, _value, value);
268
+ __privateAdd$5(this, _Key_instances);
269
+ __privateAdd$5(this, _value);
270
+ __privateMethod$2(this, _Key_instances, validateKey_fn).call(this, value);
271
+ __privateSet$4(this, _value, value);
81
272
  }
82
273
  get value() {
83
274
  return __privateGet$4(this, _value);
@@ -89,429 +280,751 @@ validateKey_fn = function(key) {
89
280
  if (INVALID_KEY_PATTERN.test(key)) throw new Error(`Invalid key: [${key}]; Keys can only contain lowercase characters, numbers and dashes.`);
90
281
  };
91
282
 
92
- var __defProp$6 = Object.defineProperty;
93
- var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
94
- var __publicField$6 = (obj, key, value) => __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
283
+ var __defProp$b = Object.defineProperty;
284
+ var __defNormalProp$b = (obj, key, value) => key in obj ? __defProp$b(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
285
+ var __publicField$b = (obj, key, value) => __defNormalProp$b(obj, typeof key !== "symbol" ? key + "" : key, value);
95
286
  class Archetype {
96
287
  constructor(data) {
97
- __publicField$6(this, "key");
98
- __publicField$6(this, "name");
99
- __publicField$6(this, "description");
288
+ __publicField$b(this, "key");
289
+ __publicField$b(this, "name");
290
+ __publicField$b(this, "description");
100
291
  this.key = new Key(data.key).value;
101
292
  this.name = data.name;
102
293
  this.description = data.description;
103
294
  }
104
295
  }
105
296
 
106
- var __defProp$5 = Object.defineProperty;
107
- var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
108
- var __publicField$5 = (obj, key, value) => __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
109
- class BadgePartial {
297
+ function coalesceToArray(value) {
298
+ if (!value) return void 0;
299
+ return Array.isArray(value) ? value : [value];
300
+ }
301
+
302
+ var __defProp$a = Object.defineProperty;
303
+ var __defNormalProp$a = (obj, key, value) => key in obj ? __defProp$a(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
304
+ var __publicField$a = (obj, key, value) => __defNormalProp$a(obj, typeof key !== "symbol" ? key + "" : key, value);
305
+ class BadgeRequirement {
110
306
  constructor(data) {
111
- __publicField$5(this, "key");
112
- __publicField$5(this, "type");
113
- __publicField$5(this, "mapKey");
114
- __publicField$5(this, "loc");
115
- __publicField$5(this, "plaqueType");
116
- __publicField$5(this, "inscription");
117
- __publicField$5(this, "vidiotMapKey");
118
- __publicField$5(this, "badgeKey");
119
- __publicField$5(this, "inventionLevel");
120
- __publicField$5(this, "inventionTypes");
121
- __publicField$5(this, "inventionCount");
122
- __publicField$5(this, "notes");
307
+ /**
308
+ * Unique key used to reference this badge requirement.
309
+ *
310
+ * Keys must be unique and can only contain lowercase letters, numbers and hyphens (`-`).
311
+ */
312
+ __publicField$a(this, "key");
313
+ /**
314
+ * The requirement type.
315
+ */
316
+ __publicField$a(this, "type");
317
+ /**
318
+ * If the requirement involves a location, where it is.
319
+ */
320
+ __publicField$a(this, "location");
321
+ /**
322
+ * If the requirement involves a badge, the badge key.
323
+ */
324
+ __publicField$a(this, "badgeKey");
325
+ /**
326
+ * If the requirement involves a mission, the mission key.
327
+ */
328
+ __publicField$a(this, "missionKey");
329
+ /**
330
+ * If the requirement involves a monument, the text that is displayed thereon.
331
+ */
332
+ __publicField$a(this, "monumentText");
333
+ /**
334
+ * If the requirement involves crafting an invention, the Level of the invention required.
335
+ */
336
+ __publicField$a(this, "inventionLevel");
337
+ /**
338
+ * If the requirement involves crafting an invention, the types of enhancements that will qualify.
339
+ */
340
+ __publicField$a(this, "inventionTypes");
341
+ /**
342
+ * Number of times the task needs to be repeated.
343
+ */
344
+ __publicField$a(this, "count");
345
+ /**
346
+ * Additional information about the requirement.
347
+ */
348
+ __publicField$a(this, "notes");
349
+ /**
350
+ * List of external links. Wiki, forums, etc.
351
+ */
352
+ __publicField$a(this, "links");
123
353
  this.key = new Key(data.key).value;
124
354
  this.type = data.type;
125
- this.mapKey = data.mapKey;
126
- this.loc = data.loc;
127
- this.plaqueType = data.plaqueType;
128
- this.inscription = data.inscription;
129
- this.vidiotMapKey = data.vidiotMapKey;
355
+ this.location = coalesceToArray(data.location);
130
356
  this.badgeKey = data.badgeKey;
357
+ this.missionKey = data.missionKey;
358
+ this.monumentText = data.monumentText;
131
359
  this.inventionLevel = data.inventionLevel;
132
360
  this.inventionTypes = data.inventionTypes;
133
- this.inventionCount = data.inventionCount;
361
+ this.count = data.count;
134
362
  this.notes = data.notes;
363
+ this.links = data.links ?? [];
135
364
  }
136
365
  }
137
366
 
138
- var __typeError$3 = (msg) => {
367
+ var __typeError$4 = (msg) => {
139
368
  throw TypeError(msg);
140
369
  };
141
- var __accessCheck$3 = (obj, member, msg) => member.has(obj) || __typeError$3("Cannot " + msg);
142
- var __privateGet$3 = (obj, member, getter) => (__accessCheck$3(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
143
- var __privateAdd$3 = (obj, member, value) => member.has(obj) ? __typeError$3("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
144
- var __privateSet = (obj, member, value, setter) => (__accessCheck$3(obj, member, "write to private field"), member.set(obj, value), value);
145
- var __privateMethod = (obj, member, method) => (__accessCheck$3(obj, member, "access private method"), method);
146
- var _sortedValues, _Alternates_instances, compareAlternates_fn, compareAlignment_fn, compareSex_fn;
147
- const ALIGNMENT_SORT = { H: 2, V: 1, P: 0 };
148
- const SEX_SORT = { M: 1, F: 0 };
149
- class Alternates {
150
- constructor(values) {
151
- __privateAdd$3(this, _Alternates_instances);
152
- __privateAdd$3(this, _sortedValues, []);
153
- __privateSet(this, _sortedValues, values.sort());
154
- __privateGet$3(this, _sortedValues).sort((a, b) => __privateMethod(this, _Alternates_instances, compareAlternates_fn).call(this, a, b));
370
+ var __accessCheck$4 = (obj, member, msg) => member.has(obj) || __typeError$4("Cannot " + msg);
371
+ var __privateGet$3 = (obj, member, getter) => (__accessCheck$4(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
372
+ 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);
373
+ var __privateSet$3 = (obj, member, value, setter) => (__accessCheck$4(obj, member, "write to private field"), member.set(obj, value), value);
374
+ var __privateMethod$1 = (obj, member, method) => (__accessCheck$4(obj, member, "access private method"), method);
375
+ var _sortedValues, _Variants_instances, compareVariants_fn;
376
+ class Variants {
377
+ /**
378
+ * Create a variant set from either a list of categorized values, or a single value when there are no variants.
379
+ * @param value List of variants, or a single value.
380
+ */
381
+ constructor(value) {
382
+ __privateAdd$4(this, _Variants_instances);
383
+ __privateAdd$4(this, _sortedValues, []);
384
+ if (Array.isArray(value)) {
385
+ __privateSet$3(this, _sortedValues, value.toSorted());
386
+ __privateGet$3(this, _sortedValues).sort((a, b) => __privateMethod$1(this, _Variants_instances, compareVariants_fn).call(this, a, b));
387
+ } else {
388
+ __privateSet$3(this, _sortedValues, [{ value }]);
389
+ }
155
390
  }
156
- getValue(alignment, sex) {
391
+ /**
392
+ * Get a variant by context
393
+ * @param context The context
394
+ */
395
+ getVariant(context) {
396
+ const alignment = context?.morality ? MoralityMap[context.morality] : void 0;
397
+ const sex = context?.sex;
157
398
  for (let index = __privateGet$3(this, _sortedValues).length; index--; ) {
158
399
  const entry = __privateGet$3(this, _sortedValues)[index];
159
- if ((entry.alignment === void 0 || entry.alignment === alignment) && (entry.sex === void 0 || entry.sex === sex)) return entry.value;
400
+ if ((entry.alignment === void 0 || entry.alignment === alignment) && (entry.sex === void 0 || entry.sex === sex)) return entry;
160
401
  }
161
- return void 0;
402
+ return this.default;
403
+ }
404
+ /**
405
+ * Get a value by variant context
406
+ * @param context The context
407
+ */
408
+ getValue(context) {
409
+ return this.getVariant(context)?.value;
162
410
  }
163
411
  /**
164
- * Get the default value for this list of alternates, the value with the highest priority and lowest specificity.
412
+ * Get the default value for this list of variants, the value with the highest priority and lowest specificity.
165
413
  */
166
414
  get default() {
167
- return __privateGet$3(this, _sortedValues)[0]?.value;
415
+ return __privateGet$3(this, _sortedValues)[0];
168
416
  }
169
417
  /**
170
- * Get the list of alternates sorted in canonical order (alignment then sex, low to high specificity).
418
+ * Get the list of variants sorted in canonical order (alignment then sex, low to high specificity).
171
419
  */
172
420
  get canonical() {
173
421
  return __privateGet$3(this, _sortedValues);
174
422
  }
423
+ /**
424
+ * Create a joined string from the variant values in canonical order.
425
+ * @param separator Separator to use. Default is ' / '
426
+ */
427
+ toString(separator) {
428
+ return this.canonical.map((x) => x.value).join(separator);
429
+ }
175
430
  }
176
431
  _sortedValues = new WeakMap();
177
- _Alternates_instances = new WeakSet();
178
- compareAlternates_fn = function(a, b) {
432
+ _Variants_instances = new WeakSet();
433
+ compareVariants_fn = function(a, b) {
179
434
  const aSpecificity = (a.alignment ? 2 : 0) + (a.sex ? 1 : 0);
180
435
  const bSpecificity = (b.alignment ? 2 : 0) + (b.sex ? 1 : 0);
181
436
  if (aSpecificity !== bSpecificity) return aSpecificity - bSpecificity;
182
- const alignmentComparison = __privateMethod(this, _Alternates_instances, compareAlignment_fn).call(this, a.alignment, b.alignment);
437
+ const alignmentComparison = compareAlignment(a.alignment, b.alignment);
183
438
  if (alignmentComparison !== 0) return alignmentComparison;
184
- const sexComparison = __privateMethod(this, _Alternates_instances, compareSex_fn).call(this, a.sex, b.sex);
439
+ const sexComparison = compareSex(a.sex, b.sex);
185
440
  if (sexComparison !== 0) return sexComparison;
186
441
  return String(a.value).localeCompare(String(b.value));
187
442
  };
188
- compareAlignment_fn = function(a, b) {
189
- if (a === b) return 0;
190
- if (a === void 0 && b !== void 0) return -1;
191
- if (b === void 0 && a !== void 0) return 1;
192
- const aSort = a === void 0 ? -1 : ALIGNMENT_SORT[a] ?? -1;
193
- const bSort = b === void 0 ? -1 : ALIGNMENT_SORT[b] ?? -1;
194
- if (aSort !== bSort) return bSort - aSort;
195
- return a?.localeCompare(b ?? "") ?? 0;
196
- };
197
- compareSex_fn = function(a, b) {
198
- if (a === b) return 0;
199
- if (a === void 0 && b !== void 0) return -1;
200
- if (b === void 0 && a !== void 0) return 1;
201
- const aSort = SEX_SORT[a ?? -1] ?? -1;
202
- const bSort = SEX_SORT[b ?? -1] ?? -1;
203
- if (aSort !== bSort) return bSort - aSort;
204
- return a?.localeCompare(b ?? "") ?? 0;
443
+
444
+ var __defProp$9 = Object.defineProperty;
445
+ var __typeError$3 = (msg) => {
446
+ throw TypeError(msg);
205
447
  };
448
+ var __defNormalProp$9 = (obj, key, value) => key in obj ? __defProp$9(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
449
+ var __publicField$9 = (obj, key, value) => __defNormalProp$9(obj, typeof key !== "symbol" ? key + "" : key, value);
450
+ var __accessCheck$3 = (obj, member, msg) => member.has(obj) || __typeError$3("Cannot " + msg);
451
+ var __privateGet$2 = (obj, member, getter) => (__accessCheck$3(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
452
+ var __privateAdd$3 = (obj, member, value) => member.has(obj) ? __typeError$3("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
453
+ var __privateSet$2 = (obj, member, value, setter) => (__accessCheck$3(obj, member, "write to private field"), member.set(obj, value), value);
454
+ var _items;
455
+ class MoralityList {
456
+ constructor(items) {
457
+ __privateAdd$3(this, _items);
458
+ __publicField$9(this, "hero");
459
+ __publicField$9(this, "vigilante");
460
+ __publicField$9(this, "villain");
461
+ __publicField$9(this, "rogue");
462
+ __publicField$9(this, "resistance");
463
+ __publicField$9(this, "loyalist");
464
+ __publicField$9(this, "primal");
465
+ __publicField$9(this, "praetorian");
466
+ __publicField$9(this, "heroic");
467
+ __publicField$9(this, "villainous");
468
+ __publicField$9(this, "paragonCityAccess");
469
+ __publicField$9(this, "rogueIslesAccess");
470
+ __publicField$9(this, "all");
471
+ const set = new Set(items ?? [...MORALITY]);
472
+ this.hero = set.has("hero") || set.has("primal") || set.has("heroic") || set.has("paragon-city-access") || set.has("all");
473
+ this.vigilante = set.has("vigilante") || set.has("primal") || set.has("heroic") || set.has("paragon-city-access") || set.has("rogue-isles-access") || set.has("all");
474
+ this.villain = set.has("villain") || set.has("primal") || set.has("villainous") || set.has("rogue-isles-access") || set.has("all");
475
+ this.rogue = set.has("rogue") || set.has("primal") || set.has("villainous") || set.has("paragon-city-access") || set.has("rogue-isles-access") || set.has("all");
476
+ this.resistance = set.has("resistance") || set.has("praetorian") || set.has("all");
477
+ this.loyalist = set.has("loyalist") || set.has("praetorian") || set.has("all");
478
+ this.primal = this.hero && this.vigilante && this.villain && this.rogue;
479
+ this.praetorian = this.loyalist && this.resistance;
480
+ this.heroic = this.hero && this.vigilante;
481
+ this.villainous = this.villain && this.rogue;
482
+ this.paragonCityAccess = this.heroic && this.rogue;
483
+ this.rogueIslesAccess = this.villainous && this.vigilante;
484
+ this.all = this.primal && this.praetorian;
485
+ __privateSet$2(this, _items, /* @__PURE__ */ new Set());
486
+ if (this.hero) __privateGet$2(this, _items).add("hero");
487
+ if (this.vigilante) __privateGet$2(this, _items).add("vigilante");
488
+ if (this.villain) __privateGet$2(this, _items).add("villain");
489
+ if (this.rogue) __privateGet$2(this, _items).add("rogue");
490
+ if (this.resistance) __privateGet$2(this, _items).add("resistance");
491
+ if (this.loyalist) __privateGet$2(this, _items).add("loyalist");
492
+ }
493
+ get items() {
494
+ return [...__privateGet$2(this, _items)];
495
+ }
496
+ has(morality) {
497
+ switch (morality) {
498
+ case "hero": {
499
+ return this.hero;
500
+ }
501
+ case "vigilante": {
502
+ return this.vigilante;
503
+ }
504
+ case "villain": {
505
+ return this.villain;
506
+ }
507
+ case "rogue": {
508
+ return this.rogue;
509
+ }
510
+ case "resistance": {
511
+ return this.resistance;
512
+ }
513
+ case "loyalist": {
514
+ return this.loyalist;
515
+ }
516
+ case "primal": {
517
+ return this.primal;
518
+ }
519
+ case "praetorian": {
520
+ return this.praetorian;
521
+ }
522
+ case "heroic": {
523
+ return this.hero;
524
+ }
525
+ case "paragon-city-access": {
526
+ return this.paragonCityAccess;
527
+ }
528
+ case "rogue-isles-access": {
529
+ return this.rogueIslesAccess;
530
+ }
531
+ case "villainous": {
532
+ return this.villainous;
533
+ }
534
+ case "all": {
535
+ return this.all;
536
+ }
537
+ default: {
538
+ return false;
539
+ }
540
+ }
541
+ }
542
+ }
543
+ _items = new WeakMap();
206
544
 
207
- var __defProp$4 = Object.defineProperty;
545
+ var __defProp$8 = Object.defineProperty;
546
+ var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
547
+ var __publicField$8 = (obj, key, value) => __defNormalProp$8(obj, typeof key !== "symbol" ? key + "" : key, value);
548
+ class AbstractIndex {
549
+ /**
550
+ * Create a new index.
551
+ * @param keyField The field of the values that will act as the key.
552
+ * @param values Values to index.
553
+ */
554
+ constructor(keyField, values) {
555
+ __publicField$8(this, "_values", []);
556
+ __publicField$8(this, "_hashTable", {});
557
+ this._values = values ?? [];
558
+ this._hashTable = {};
559
+ for (const value of this.values) {
560
+ const key = value[keyField];
561
+ if (this._hashTable[key] !== void 0) throw new Error(`Duplicate key [${key}]`);
562
+ this._hashTable[key] = value;
563
+ }
564
+ }
565
+ /**
566
+ * Return all indexed values
567
+ */
568
+ get values() {
569
+ return this._values;
570
+ }
571
+ /**
572
+ * Get a value from the index
573
+ * @param key Key string
574
+ */
575
+ get(key) {
576
+ if (!key) return void 0;
577
+ return this._hashTable[key];
578
+ }
579
+ }
580
+
581
+ function toDate(iso) {
582
+ const date = new Date(iso);
583
+ if (!date || Number.isNaN(date.getTime())) throw new Error(`Invalid date format: [${iso}]`);
584
+ return date;
585
+ }
586
+
587
+ var __defProp$7 = Object.defineProperty;
588
+ var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
589
+ var __publicField$7 = (obj, key, value) => __defNormalProp$7(obj, typeof key !== "symbol" ? key + "" : key, value);
590
+ class SetTitleIds {
591
+ constructor(value) {
592
+ __publicField$7(this, "primal");
593
+ __publicField$7(this, "praetorian");
594
+ [this.primal, this.praetorian] = value;
595
+ }
596
+ }
597
+
598
+ var __defProp$6 = Object.defineProperty;
208
599
  var __typeError$2 = (msg) => {
209
600
  throw TypeError(msg);
210
601
  };
211
- var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
212
- var __publicField$4 = (obj, key, value) => __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
602
+ var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
603
+ var __publicField$6 = (obj, key, value) => __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
213
604
  var __accessCheck$2 = (obj, member, msg) => member.has(obj) || __typeError$2("Cannot " + msg);
214
- var __privateGet$2 = (obj, member, getter) => (__accessCheck$2(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
605
+ var __privateGet$1 = (obj, member, getter) => (__accessCheck$2(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
215
606
  var __privateAdd$2 = (obj, member, value) => member.has(obj) ? __typeError$2("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
216
- var _partialsIndex;
607
+ var __privateSet$1 = (obj, member, value, setter) => (__accessCheck$2(obj, member, "write to private field"), member.set(obj, value), value);
608
+ var _requirementsIndex, _zoneKeys;
217
609
  class Badge {
218
- constructor(data) {
219
- __privateAdd$2(this, _partialsIndex, {});
610
+ constructor(badgeData) {
611
+ __privateAdd$2(this, _requirementsIndex);
612
+ __privateAdd$2(this, _zoneKeys, /* @__PURE__ */ new Set());
220
613
  /**
221
614
  * The database key for this badge.
222
615
  */
223
- __publicField$4(this, "key");
616
+ __publicField$6(this, "key");
224
617
  /**
225
618
  * The type of badge.
226
619
  */
227
- __publicField$4(this, "type");
620
+ __publicField$6(this, "type");
228
621
  /**
229
622
  * The name of this badge.
230
623
  *
231
624
  * May vary by character sex or alignment.
232
625
  */
233
- __publicField$4(this, "name");
626
+ __publicField$6(this, "name");
627
+ /**
628
+ * The date that the badge was added to the game.
629
+ */
630
+ __publicField$6(this, "releaseDate");
234
631
  /**
235
- * The character alignments that this badge is available to.
632
+ * The character moralities that this badge is available to.
236
633
  */
237
- __publicField$4(this, "alignment");
634
+ __publicField$6(this, "morality");
238
635
  /**
239
636
  * The badge text as it appears in-game. May vary by character sex or alignment.
240
637
  */
241
- __publicField$4(this, "badgeText");
638
+ __publicField$6(this, "badgeText");
242
639
  /**
243
- * Description of how to acquire the badge.
244
- *
245
- * Supports {@link https://www.markdownguide.org/|Markdown} format.
640
+ * Short description of how to acquire the badge. Detailed instructions will be in the notes field.
246
641
  */
247
- __publicField$4(this, "acquisition");
642
+ __publicField$6(this, "acquisition");
248
643
  /**
249
644
  * Absolute URL to this badge's icon.
250
645
  *
251
646
  * May vary by character sex or alignment.
252
647
  */
253
- __publicField$4(this, "icon");
648
+ __publicField$6(this, "icon");
254
649
  /**
255
650
  * Freeform notes or tips about the badge.
256
- *
257
- * Supports {@link https://www.markdownguide.org/|Markdown} format.
258
651
  */
259
- __publicField$4(this, "notes");
652
+ __publicField$6(this, "notes");
260
653
  /**
261
- * List of external links for this Badge. Wiki, forums, etc.
654
+ * List of external links. Wiki, forums, etc.
262
655
  */
263
- __publicField$4(this, "links");
656
+ __publicField$6(this, "links");
264
657
  /**
265
- * For exploration badges, the key of the {@link GameMap} that this badge is found on.
658
+ * The id used with the in-game `/settitle` command to apply the badge.
659
+ * The first value is the id for primal characters and the (optional) second number is the id for praetorian characters.
266
660
  */
267
- __publicField$4(this, "mapKey");
661
+ __publicField$6(this, "setTitleId");
268
662
  /**
269
- * For exploration badges, the `/loc` coordinates of the badge on the in-game map.
663
+ * A description of the effect the badge will have, such as a buff or granting a temporary power.
270
664
  */
271
- __publicField$4(this, "loc");
665
+ __publicField$6(this, "effect");
272
666
  /**
273
- * For badges that appear on a Vidiot Map, the number or letter the badge appears as.
667
+ * Some badges are not included in the badge total count... such as Flames of Prometheus, which can be removed by redeeming it for a Notice of the Well.
274
668
  */
275
- __publicField$4(this, "vidiotMapKey");
669
+ __publicField$6(this, "ignoreInTotals");
670
+ this.key = new Key(badgeData.key).value;
671
+ this.type = badgeData.type;
672
+ this.name = new Variants(badgeData.name);
673
+ this.releaseDate = toDate(badgeData.releaseDate);
674
+ this.morality = new MoralityList(coalesceToArray(badgeData.morality));
675
+ this.badgeText = new Variants(badgeData.badgeText ?? []);
676
+ this.acquisition = badgeData.acquisition;
677
+ this.icon = new Variants(badgeData.icon ?? []);
678
+ this.notes = badgeData.notes;
679
+ this.links = badgeData.links ?? [];
680
+ this.effect = badgeData.effect;
681
+ this.setTitleId = badgeData.setTitleId ? new SetTitleIds(badgeData.setTitleId) : void 0;
682
+ this.ignoreInTotals = badgeData.ignoreInTotals ?? false;
683
+ __privateSet$1(this, _requirementsIndex, new AbstractIndex("key", badgeData.requirements?.map((x) => new BadgeRequirement(x))));
684
+ for (const requirement of __privateGet$1(this, _requirementsIndex).values) {
685
+ if (requirement.location) for (const location of requirement.location) {
686
+ if (location.zoneKey) __privateGet$1(this, _zoneKeys).add(location.zoneKey);
687
+ }
688
+ }
689
+ }
690
+ /**
691
+ * Represents the requirements for badges with multiple fulfillment steps, such as visiting monuments for history badges, completing missions, or collecting other badges.
692
+ */
693
+ get requirements() {
694
+ return __privateGet$1(this, _requirementsIndex).values;
695
+ }
696
+ getRequirement(key) {
697
+ return __privateGet$1(this, _requirementsIndex).get(key);
698
+ }
699
+ /**
700
+ * Return a list of all the zone keys referenced by this badge.
701
+ */
702
+ get zoneKeys() {
703
+ return [...__privateGet$1(this, _zoneKeys)];
704
+ }
705
+ /**
706
+ * The zone key if this badge relates to a single zone.
707
+ */
708
+ get zoneKey() {
709
+ return __privateGet$1(this, _zoneKeys).size === 1 ? __privateGet$1(this, _zoneKeys).values().next().value : void 0;
710
+ }
711
+ }
712
+ _requirementsIndex = new WeakMap();
713
+ _zoneKeys = new WeakMap();
714
+ function compareByName(a, b, context) {
715
+ const aName = a?.name?.getValue(context);
716
+ const bName = b?.name?.getValue(context);
717
+ if (!aName && !bName) return 0;
718
+ if (!aName) return 1;
719
+ if (!bName) return -1;
720
+ return aName.localeCompare(bName);
721
+ }
722
+ function compareByZoneKey(a, b) {
723
+ const aZone = a?.zoneKey;
724
+ const bZone = b?.zoneKey;
725
+ if (!aZone && !bZone) return 0;
726
+ if (!aZone) return 1;
727
+ if (!bZone) return -1;
728
+ return aZone.localeCompare(bZone);
729
+ }
730
+ function compareByReleaseDate(a, b) {
731
+ const aReleaseDate = a?.releaseDate?.getTime();
732
+ const bReleaseDate = b?.releaseDate?.getTime();
733
+ if (aReleaseDate === bReleaseDate) return 0;
734
+ if (!aReleaseDate) return 1;
735
+ if (!bReleaseDate) return -1;
736
+ return aReleaseDate < bReleaseDate ? -1 : 1;
737
+ }
738
+
739
+ var __typeError$1 = (msg) => {
740
+ throw TypeError(msg);
741
+ };
742
+ var __accessCheck$1 = (obj, member, msg) => member.has(obj) || __typeError$1("Cannot " + msg);
743
+ var __privateAdd$1 = (obj, member, value) => member.has(obj) ? __typeError$1("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
744
+ var __privateMethod = (obj, member, method) => (__accessCheck$1(obj, member, "access private method"), method);
745
+ var _BadgeIndex_instances, satisfiesQueryPredicate_fn, satisfiesFilterPredicate_fn, sort_fn;
746
+ class BadgeIndex extends AbstractIndex {
747
+ constructor(values) {
748
+ super("key", values);
749
+ __privateAdd$1(this, _BadgeIndex_instances);
750
+ }
751
+ search(options) {
752
+ const matched = 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;
753
+ const sorted = __privateMethod(this, _BadgeIndex_instances, sort_fn).call(this, matched, options);
754
+ const totalPages = options?.pageSize ? Math.ceil(matched.length / options?.pageSize) : 1;
755
+ const pageNumber = Math.max(1, Math.min(totalPages, options?.page ?? 1));
756
+ const items = options?.pageSize ? sorted.slice((pageNumber - 1) * options.pageSize, pageNumber * options?.pageSize) : sorted;
757
+ return {
758
+ items,
759
+ pageIndex: pageNumber - 1,
760
+ pageNumber,
761
+ pageSize: options?.pageSize,
762
+ matchedItemCount: matched.length,
763
+ totalItemCount: this._values.length,
764
+ totalPageCount: totalPages
765
+ };
766
+ }
767
+ }
768
+ _BadgeIndex_instances = new WeakSet();
769
+ satisfiesQueryPredicate_fn = function(badge, query) {
770
+ const queryString = query?.str?.toLowerCase() ?? "";
771
+ const fields = query?.fields ? new Set(query?.fields) : /* @__PURE__ */ new Set(["name"]);
772
+ if (fields.size === 0) return true;
773
+ return !!(fields.has("name") && badge.name.canonical.some((x) => x.value.toLowerCase().includes(queryString)) || fields.has("badge-text") && badge.badgeText.canonical.some((x) => x.value.toLowerCase().includes(queryString)) || fields.has("acquisition") && badge.acquisition?.toLowerCase().includes(queryString) || fields.has("effect") && badge.effect?.toLowerCase().includes(queryString) || fields.has("notes") && badge.notes?.toLowerCase().includes(queryString) || fields.has("set-title-id") && badge.setTitleId?.primal.toString() === queryString || fields.has("set-title-id") && badge.setTitleId?.praetorian?.toString() === queryString);
774
+ };
775
+ satisfiesFilterPredicate_fn = function(badge, filter) {
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));
777
+ };
778
+ sort_fn = function(badges, options) {
779
+ switch (options?.sort) {
780
+ case "name.asc": {
781
+ return badges.toSorted((a, b) => compareByName(a, b, options.variantContext));
782
+ }
783
+ case "name.desc": {
784
+ return badges.toSorted((a, b) => compareByName(b, a, options.variantContext));
785
+ }
786
+ case "zone-key.asc": {
787
+ return badges.toSorted(compareByZoneKey);
788
+ }
789
+ case "zone-key.desc": {
790
+ return badges.toSorted((a, b) => compareByZoneKey(b, a));
791
+ }
792
+ case "release-date.asc": {
793
+ return badges.toSorted(compareByReleaseDate);
794
+ }
795
+ case "release-date.desc": {
796
+ return badges.toSorted((a, b) => compareByReleaseDate(b, a));
797
+ }
798
+ case "canonical.desc": {
799
+ return badges.toReversed();
800
+ }
801
+ default: {
802
+ return [...badges];
803
+ }
804
+ }
805
+ };
806
+
807
+ var __defProp$5 = Object.defineProperty;
808
+ var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
809
+ var __publicField$5 = (obj, key, value) => __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
810
+ class BundleHeader {
811
+ constructor(data) {
276
812
  /**
277
- * ID used with the in-game `/settitle` command to apply the badge.
813
+ * Name of the fork this bundle contains data for.
278
814
  */
279
- __publicField$4(this, "setTitle");
815
+ __publicField$5(this, "name");
280
816
  /**
281
- * A description of the effect the badge will have, such as a buff or granting a temporary power.
282
- *
283
- * Supports {@link https://www.markdownguide.org/|Markdown} format.
817
+ * Version number for this data package.
284
818
  */
285
- __publicField$4(this, "effect");
819
+ __publicField$5(this, "version");
286
820
  /**
287
- * A list of requirements for badges that have partial fulfilment steps, such as visiting plaques for history badges, or collecting other badges for meta-badges like accolades.
821
+ * The time this bundle was last updated.
288
822
  */
289
- __publicField$4(this, "partials");
823
+ __publicField$5(this, "lastUpdateTime");
290
824
  /**
291
- * Some badges are not included in the badge total count... such as Flames of Prometheus, which can be removed by redeeming it for a Notice of the Well.
825
+ * Description of the fork.
292
826
  */
293
- __publicField$4(this, "ignoreInTotals");
294
- this.key = new Key(data.key).value;
295
- this.type = data.type;
296
- this.name = new Alternates(data.name);
297
- this.alignment = data.alignment;
298
- this.badgeText = new Alternates(data.badgeText ?? []);
299
- this.acquisition = data.acquisition;
300
- this.icon = new Alternates(data.icon ?? []);
301
- this.notes = data.notes;
302
- this.links = data.links;
303
- this.mapKey = data.mapKey;
304
- this.loc = data.loc;
305
- this.effect = data.effect;
306
- this.vidiotMapKey = data.vidiotMapKey;
307
- this.setTitle = data.setTitle;
308
- this.ignoreInTotals = data.ignoreInTotals ?? false;
309
- this.partials = data.partials?.map((data2) => {
310
- if (__privateGet$2(this, _partialsIndex)[data2.key] !== void 0) throw new Error(`Duplicate badge partial key [${data2.key}]`);
311
- const badge = new BadgePartial(data2);
312
- __privateGet$2(this, _partialsIndex)[badge.key] = badge;
313
- return badge;
314
- });
315
- }
316
- getPartial(key) {
317
- const result = __privateGet$2(this, _partialsIndex)[key];
318
- if (result === void 0) throw new Error(`Unknown badge partial key [${key}]`);
319
- return result;
320
- }
321
- }
322
- _partialsIndex = new WeakMap();
827
+ __publicField$5(this, "description");
828
+ /**
829
+ * Url for the repository where the bundle is maintained.
830
+ */
831
+ __publicField$5(this, "repositoryUrl");
832
+ /**
833
+ * Url for the location of the changelog.
834
+ */
835
+ __publicField$5(this, "changelogUrl");
836
+ /**
837
+ * List of external links. Wiki, forums, etc.
838
+ */
839
+ __publicField$5(this, "links");
840
+ if (!data) throw new Error("Missing header data");
841
+ this.name = data.name;
842
+ this.version = data.version;
843
+ this.lastUpdateTime = toDate(data.lastUpdateTime);
844
+ this.description = data?.description;
845
+ this.repositoryUrl = data?.repositoryUrl;
846
+ this.changelogUrl = data?.changelogUrl;
847
+ this.links = data?.links ?? [];
848
+ }
849
+ }
850
+
851
+ var __defProp$4 = Object.defineProperty;
852
+ var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
853
+ var __publicField$4 = (obj, key, value) => __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
854
+ class LevelRange {
855
+ constructor(value) {
856
+ __publicField$4(this, "min");
857
+ __publicField$4(this, "max");
858
+ if (Array.isArray(value)) {
859
+ this.min = value[0];
860
+ this.max = value[1] === void 0 ? void 0 : value[1];
861
+ } else {
862
+ this.min = value;
863
+ }
864
+ }
865
+ }
323
866
 
324
867
  var __defProp$3 = Object.defineProperty;
325
868
  var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
326
869
  var __publicField$3 = (obj, key, value) => __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
327
- class VidiotMapPointOfInterest {
870
+ class Zone {
328
871
  constructor(data) {
329
872
  /**
330
- * The pixel-space position of the PoI on the map graphic.
873
+ * Unique key used to reference this zone.
331
874
  *
332
- * Screen-space, pixels from top-left `[0, 0]`.
875
+ * Keys must be unique and can only contain lowercase letters, numbers and hyphens (`-`).
333
876
  */
334
- __publicField$3(this, "pos");
877
+ __publicField$3(this, "key");
335
878
  /**
336
- * Freeform notes about the PoI.
337
- *
338
- * Supports {@link https://www.markdownguide.org/|Markdown} format.
879
+ * The name of the zone as it appears in-game.
339
880
  */
340
- __publicField$3(this, "notes");
881
+ __publicField$3(this, "name");
882
+ /**
883
+ * The type of zone.
884
+ */
885
+ __publicField$3(this, "type");
886
+ /**
887
+ * The character moralities that this zone is accessible by.
888
+ */
889
+ __publicField$3(this, "morality");
341
890
  /**
342
- * If the POI is a zone transfer, the map it transfers to.
891
+ * The level range this zone is recommended for.
343
892
  */
344
- __publicField$3(this, "mapKey");
893
+ __publicField$3(this, "levelRange");
345
894
  /**
346
- * If the POI is a badge, the badge.
895
+ * Freeform notes or tips about the zone.
347
896
  */
348
- __publicField$3(this, "badgeKey");
897
+ __publicField$3(this, "notes");
349
898
  /**
350
- * If the POI is a partial for a badge, the partial key.
899
+ * List of external links. Wiki, forums, etc.
351
900
  */
352
- __publicField$3(this, "badgePartialKey");
353
- this.pos = data.pos;
901
+ __publicField$3(this, "links");
902
+ this.key = new Key(data.key).value;
903
+ this.name = data.name;
904
+ this.type = data.type;
905
+ this.morality = new MoralityList(coalesceToArray(data.morality));
906
+ this.levelRange = data.levelRange ? new LevelRange(data.levelRange) : void 0;
354
907
  this.notes = data.notes;
355
- this.mapKey = data.mapKey;
356
- this.badgeKey = data.badgeKey;
357
- this.badgePartialKey = data.badgePartialKey;
908
+ this.links = data.links ?? [];
358
909
  }
359
910
  }
360
911
 
361
912
  var __defProp$2 = Object.defineProperty;
362
913
  var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
363
914
  var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
364
- class VidiotMap {
915
+ class Contact {
365
916
  constructor(data) {
366
917
  /**
367
- * URL of the map image.
918
+ * Unique key used to reference this contact.
919
+ *
920
+ * Keys must be unique and can only contain lowercase letters, numbers and hyphens (`-`).
368
921
  */
369
- __publicField$2(this, "imageUrl");
922
+ __publicField$2(this, "key");
370
923
  /**
371
- * Name to display for the Vidiot map.
924
+ * The name of this contact.
372
925
  */
373
926
  __publicField$2(this, "name");
374
927
  /**
375
- * List of Points of Interest labelled on the image.
928
+ * The contact's title.
376
929
  */
377
- __publicField$2(this, "pointsOfInterest");
378
- this.imageUrl = data.imageUrl;
379
- this.name = data.name;
380
- this.pointsOfInterest = data.pointsOfInterest?.map((data2) => new VidiotMapPointOfInterest(data2));
381
- }
382
- }
383
-
384
- var __defProp$1 = Object.defineProperty;
385
- var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
386
- var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
387
- class GameMap {
388
- constructor(data) {
930
+ __publicField$2(this, "title");
389
931
  /**
390
- * The database key for this map.
932
+ * The character moralities that this contact will interact with.
391
933
  */
392
- __publicField$1(this, "key");
934
+ __publicField$2(this, "morality");
393
935
  /**
394
- * The name of the map as it appears in-game.
936
+ * The location of this contact.
395
937
  */
396
- __publicField$1(this, "name");
938
+ __publicField$2(this, "location");
397
939
  /**
398
- * List of external links for this Map. Wiki, forums, etc.
940
+ * The level range this contact will offer missions for.
399
941
  */
400
- __publicField$1(this, "links");
942
+ __publicField$2(this, "levelRange");
401
943
  /**
402
- * List of Vidiot Map assets for this map.
944
+ * Freeform notes or tips about the contact.
403
945
  */
404
- __publicField$1(this, "vidiotMaps");
946
+ __publicField$2(this, "notes");
947
+ /**
948
+ * List of external links. Wiki, forums, etc.
949
+ */
950
+ __publicField$2(this, "links");
405
951
  this.key = new Key(data.key).value;
406
952
  this.name = data.name;
407
- this.links = data.links;
408
- this.vidiotMaps = data.vidiotMaps?.map((data2) => new VidiotMap(data2));
953
+ this.title = data.title;
954
+ this.morality = new MoralityList(coalesceToArray(data.morality));
955
+ this.location = data.location;
956
+ this.levelRange = data.levelRange ? new LevelRange(data.levelRange) : void 0;
957
+ this.notes = data.notes;
958
+ this.links = data.links ?? [];
409
959
  }
410
960
  }
411
961
 
412
- var __defProp = Object.defineProperty;
413
- var __typeError$1 = (msg) => {
414
- throw TypeError(msg);
415
- };
416
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
417
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
418
- var __accessCheck$1 = (obj, member, msg) => member.has(obj) || __typeError$1("Cannot " + msg);
419
- var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
420
- var __privateAdd$1 = (obj, member, value) => member.has(obj) ? __typeError$1("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
421
- var _archetypeIndex, _mapIndex, _badgeIndex;
422
- class ServerGroup {
962
+ var __defProp$1 = Object.defineProperty;
963
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
964
+ var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
965
+ class Mission {
423
966
  constructor(data) {
424
- __privateAdd$1(this, _archetypeIndex, {});
425
- __privateAdd$1(this, _mapIndex, {});
426
- __privateAdd$1(this, _badgeIndex, {});
427
- /**
428
- * The database key for this server group.
429
- */
430
- __publicField(this, "key");
431
967
  /**
432
- * Name of the server group.
968
+ * Unique key used to reference this mission.
969
+ *
970
+ * Keys must be unique and can only contain lowercase letters, numbers and hyphens (`-`).
433
971
  */
434
- __publicField(this, "name");
972
+ __publicField$1(this, "key");
435
973
  /**
436
- * Description of the server group.
974
+ * The name of the mission as it appears from the contact.
437
975
  *
438
- * Supports {@link https://www.markdownguide.org/|Markdown} format.
976
+ * The name may be different when viewed in Ouroboros as a Flashback.
439
977
  */
440
- __publicField(this, "description");
978
+ __publicField$1(this, "name");
441
979
  /**
442
- * Repository where the db content package is maintained.
980
+ * The type of mission... Story arc, task force, trial, etc.
443
981
  */
444
- __publicField(this, "repository");
982
+ __publicField$1(this, "type");
445
983
  /**
446
- * List of external links for this Server Group. Wiki, forums, etc.
984
+ * The character moralities that may accept the mission.
447
985
  */
448
- __publicField(this, "links");
986
+ __publicField$1(this, "morality");
449
987
  /**
450
- * List of the game server names in this server group.
451
- * Torchbearer, Excelsior, etc.
988
+ * The keys of any contacts that provide this mission.
452
989
  */
453
- __publicField(this, "servers");
990
+ __publicField$1(this, "contactKeys");
454
991
  /**
455
- * List of archetypes available in this server group.
992
+ * The level range this mission is available for.
456
993
  */
457
- __publicField(this, "archetypes");
994
+ __publicField$1(this, "levelRange");
458
995
  /**
459
- * List of game maps supported by this server group.
996
+ * Freeform notes or tips about the mission.
460
997
  */
461
- __publicField(this, "maps");
998
+ __publicField$1(this, "notes");
462
999
  /**
463
- * List of badges available on this server group.
1000
+ * List of external links. Wiki, forums, etc.
464
1001
  */
465
- __publicField(this, "badges");
1002
+ __publicField$1(this, "links");
466
1003
  /**
467
- * Change log for this data package.
1004
+ * If the mission is available in Ouroboros as a Flashback.
468
1005
  */
469
- __publicField(this, "changelog");
1006
+ __publicField$1(this, "flashback");
470
1007
  this.key = new Key(data.key).value;
471
1008
  this.name = data.name;
472
- this.description = data.description;
473
- this.repository = data.repository;
474
- this.links = data.links;
475
- this.servers = data.servers ?? [];
476
- this.archetypes = data.archetypes?.map((data2) => {
477
- if (__privateGet$1(this, _archetypeIndex)[data2.key] !== void 0) throw new Error(`Duplicate archetype key [${data2.key}]`);
478
- const archetype = new Archetype(data2);
479
- __privateGet$1(this, _archetypeIndex)[archetype.key] = archetype;
480
- return archetype;
481
- }) ?? [];
482
- this.maps = data.maps?.map((data2) => {
483
- if (__privateGet$1(this, _mapIndex)[data2.key] !== void 0) throw new Error(`Duplicate map key [${data2.key}]`);
484
- const map = new GameMap(data2);
485
- __privateGet$1(this, _mapIndex)[map.key] = map;
486
- return map;
487
- }) ?? [];
488
- this.badges = data.badges?.map((data2) => {
489
- if (__privateGet$1(this, _badgeIndex)[data2.key] !== void 0) throw new Error(`Duplicate badge key [${data2.key}]`);
490
- const badge = new Badge(data2);
491
- __privateGet$1(this, _badgeIndex)[badge.key] = badge;
492
- return badge;
493
- }) ?? [];
494
- this.changelog = data.changelog;
495
- }
496
- getArchetype(key) {
497
- const result = __privateGet$1(this, _archetypeIndex)[key];
498
- if (result === void 0) throw new Error(`Unknown archetype key [${key}]`);
499
- return result;
500
- }
501
- getMap(key) {
502
- const result = __privateGet$1(this, _mapIndex)[key];
503
- if (result === void 0) throw new Error(`Unknown map key [${key}]`);
504
- return result;
505
- }
506
- getBadge(key) {
507
- const result = __privateGet$1(this, _badgeIndex)[key];
508
- if (result === void 0) throw new Error(`Unknown badge key [${key}]`);
509
- return result;
1009
+ this.type = data.type;
1010
+ this.morality = new MoralityList(coalesceToArray(data.morality));
1011
+ this.contactKeys = coalesceToArray(data.contactKeys);
1012
+ this.levelRange = data.levelRange ? new LevelRange(data.levelRange) : void 0;
1013
+ this.notes = data.notes;
1014
+ this.links = data.links ?? [];
1015
+ this.flashback = createFlashback(data);
510
1016
  }
511
1017
  }
512
- _archetypeIndex = new WeakMap();
513
- _mapIndex = new WeakMap();
514
- _badgeIndex = new WeakMap();
1018
+ function createFlashback(data) {
1019
+ if (!data.flashback) return void 0;
1020
+ return {
1021
+ id: data.flashback.id,
1022
+ levelRange: data.flashback.levelRange ? new LevelRange(data.flashback.levelRange) : void 0,
1023
+ name: data.flashback.name ?? data.name,
1024
+ morality: new MoralityList(coalesceToArray(data.flashback.morality ?? data.morality)),
1025
+ notes: data.flashback.notes
1026
+ };
1027
+ }
515
1028
 
516
1029
  var __typeError = (msg) => {
517
1030
  throw TypeError(msg);
@@ -519,50 +1032,186 @@ var __typeError = (msg) => {
519
1032
  var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
520
1033
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
521
1034
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
522
- var _serverGroups;
1035
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
1036
+ var _archetypeIndex, _zoneIndex, _contactIndex, _missionIndex, _badgeIndex, _header, _servers;
523
1037
  class CohContentDatabase {
524
- constructor() {
525
- __privateAdd(this, _serverGroups, {});
1038
+ /**
1039
+ * Create a db instance from the given content bundle.
1040
+ * @param bundle The bundle to load.
1041
+ */
1042
+ constructor(bundle) {
1043
+ __privateAdd(this, _archetypeIndex);
1044
+ __privateAdd(this, _zoneIndex);
1045
+ __privateAdd(this, _contactIndex);
1046
+ __privateAdd(this, _missionIndex);
1047
+ __privateAdd(this, _badgeIndex);
1048
+ __privateAdd(this, _header);
1049
+ __privateAdd(this, _servers);
1050
+ __privateSet(this, _header, new BundleHeader(bundle.header));
1051
+ __privateSet(this, _servers, bundle.servers ?? []);
1052
+ __privateSet(this, _archetypeIndex, new AbstractIndex("key", bundle.archetypes?.map((x) => new Archetype(x))));
1053
+ __privateSet(this, _zoneIndex, new AbstractIndex("key", bundle.zones?.map((x) => new Zone(x))));
1054
+ __privateSet(this, _contactIndex, new AbstractIndex("key", bundle.contacts?.map((x) => new Contact(x))));
1055
+ __privateSet(this, _missionIndex, new AbstractIndex("key", bundle.missions?.map((x) => new Mission(x))));
1056
+ __privateSet(this, _badgeIndex, new BadgeIndex(bundle.badges?.map((x) => new Badge(x))));
1057
+ }
1058
+ /**
1059
+ * Header information about the content bundle.
1060
+ */
1061
+ get header() {
1062
+ return __privateGet(this, _header);
1063
+ }
1064
+ /**
1065
+ * List of the game server names.
1066
+ *
1067
+ * Torchbearer, Excelsior, etc.
1068
+ */
1069
+ get servers() {
1070
+ return __privateGet(this, _servers);
1071
+ }
1072
+ /**
1073
+ * List of archetypes.
1074
+ */
1075
+ get archetypes() {
1076
+ return __privateGet(this, _archetypeIndex).values;
1077
+ }
1078
+ /**
1079
+ * Get archetype by key.
1080
+ * @param key The key.
1081
+ */
1082
+ getArchetype(key) {
1083
+ return __privateGet(this, _archetypeIndex).get(key);
1084
+ }
1085
+ /**
1086
+ * List of game zones.
1087
+ */
1088
+ get zones() {
1089
+ return __privateGet(this, _zoneIndex).values;
526
1090
  }
527
1091
  /**
528
- * Load a server group data package into the database.
529
- * @param data The data to load.
1092
+ * Get zone by key.
1093
+ * @param key The key.
530
1094
  */
531
- loadServerGroupData(data) {
532
- __privateGet(this, _serverGroups)[data.key] = new ServerGroup(data);
1095
+ getZone(key) {
1096
+ return __privateGet(this, _zoneIndex).get(key);
533
1097
  }
534
1098
  /**
535
- * Get all the server groups currently loaded in the database.
1099
+ * List of contacts.
536
1100
  */
537
- listServerGroups() {
538
- return Object.values(__privateGet(this, _serverGroups));
1101
+ get contacts() {
1102
+ return __privateGet(this, _contactIndex).values;
539
1103
  }
540
1104
  /**
541
- * get a server group by key.
542
- * @param serverGroupKey The key.
1105
+ * Get contact by key.
1106
+ * @param key The key.
543
1107
  */
544
- getServerGroup(serverGroupKey) {
545
- return __privateGet(this, _serverGroups)[serverGroupKey];
1108
+ getContact(key) {
1109
+ return __privateGet(this, _contactIndex).get(key);
1110
+ }
1111
+ /**
1112
+ * List of missions.
1113
+ */
1114
+ get missions() {
1115
+ return __privateGet(this, _missionIndex).values;
1116
+ }
1117
+ /**
1118
+ * Get mission by key.
1119
+ * @param key The key.
1120
+ */
1121
+ getMission(key) {
1122
+ return __privateGet(this, _missionIndex).get(key);
1123
+ }
1124
+ /**
1125
+ * List of badges.
1126
+ */
1127
+ get badges() {
1128
+ return __privateGet(this, _badgeIndex).values;
1129
+ }
1130
+ /**
1131
+ * Get badge by key.
1132
+ * @param key The key.
1133
+ */
1134
+ getBadge(key) {
1135
+ return __privateGet(this, _badgeIndex).get(key);
1136
+ }
1137
+ /**
1138
+ * Search, sort and filter the badge list.
1139
+ * This is a fairly brute-forced approach and will not be as performant as loading the badge data into a traditional
1140
+ * database engine, but is sufficient for most operations.
1141
+ * @param options {@link BadgeSearchOptions}
1142
+ */
1143
+ searchBadges(options) {
1144
+ return __privateGet(this, _badgeIndex).search(options);
546
1145
  }
547
1146
  }
548
- _serverGroups = new WeakMap();
1147
+ _archetypeIndex = new WeakMap();
1148
+ _zoneIndex = new WeakMap();
1149
+ _contactIndex = new WeakMap();
1150
+ _missionIndex = new WeakMap();
1151
+ _badgeIndex = new WeakMap();
1152
+ _header = new WeakMap();
1153
+ _servers = new WeakMap();
549
1154
 
550
- const CHANGELOG = [
551
- {
552
- version: "2.0.0",
553
- date: /* @__PURE__ */ new Date("2025-03-12"),
554
- description: "* Replaced redundant interfaces with their concrete equivalents.\n* Replaced enums with extensible union types; Server groups with new badge types, enhancement types, etc. can now extend them locally.\n* Removed the `serverGroup` property from entities to simplify the object tree; Server group context will need to be managed separately.\n* Standardized pluralization of some field names (name, icon).\n* Combined `settitle` ids into a single tuple field.\n* Change from GNU to The Unlicense.\n* Removed dependency on lodash. There are now no third-party runtime dependencies.\n* Moved from webpack to rollup for packaging.\n* Add eslint for linting.\n* Add jest for unit tests.\n* Added GitHub Actions for CI.\n"
1155
+ var __defProp = Object.defineProperty;
1156
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1157
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
1158
+ class Location {
1159
+ constructor(data) {
1160
+ /**
1161
+ * Key of the {@link Zone} that the location references.
1162
+ */
1163
+ __publicField(this, "zoneKey");
1164
+ /**
1165
+ * In-game `/loc` coordinates of the location.
1166
+ */
1167
+ __publicField(this, "coords");
1168
+ /**
1169
+ * The type of icon to use if the location appears on a map. (Typically the Vidiot map icon).
1170
+ */
1171
+ __publicField(this, "icon");
1172
+ /**
1173
+ * The text that should appear in the location icon. (Typically a number or symbol from the Vidiot map).
1174
+ */
1175
+ __publicField(this, "iconText");
1176
+ this.zoneKey = data.zoneKey;
1177
+ this.coords = data.coords;
1178
+ this.icon = data.icon;
1179
+ this.iconText = data.iconText;
555
1180
  }
556
- ];
1181
+ }
557
1182
 
558
- function createBadgeReference(target) {
1183
+ function badgeUri(target) {
1184
+ const key = typeof target === "string" ? target : target.key;
1185
+ return `badge://${key}`;
1186
+ }
1187
+ function badgeLink(target) {
1188
+ const key = typeof target === "string" ? target : target.key;
1189
+ return `[${key}](${badgeUri(target)})`;
1190
+ }
1191
+ function contactUri(target) {
1192
+ const key = typeof target === "string" ? target : target.key;
1193
+ return `contact://${key}`;
1194
+ }
1195
+ function contactLink(target) {
1196
+ const key = typeof target === "string" ? target : target.key;
1197
+ return `[${key}](${contactUri(target)})`;
1198
+ }
1199
+ function missionUri(target) {
1200
+ const key = typeof target === "string" ? target : target.key;
1201
+ return `mission://${key}`;
1202
+ }
1203
+ function missionLink(target) {
1204
+ const key = typeof target === "string" ? target : target.key;
1205
+ return `[${key}](${missionUri(target)})`;
1206
+ }
1207
+ function zoneUri(target) {
559
1208
  const key = typeof target === "string" ? target : target.key;
560
- return `[badge:${key}]`;
1209
+ return `zone://${key}`;
561
1210
  }
562
- function createMapReference(target) {
1211
+ function zoneLink(target) {
563
1212
  const key = typeof target === "string" ? target : target.key;
564
- return `[map:${key}]`;
1213
+ return `[${key}](${zoneUri(target)})`;
565
1214
  }
566
1215
 
567
- export { ALIGNMENT, Archetype, BADGE_PARTIAL_TYPE, BADGE_TYPE, Badge, BadgePartial, CHANGELOG, CohContentDatabase, ENHANCEMENT_CATEGORY, GameMap, Key, PLAQUE_TYPE, SEX, ServerGroup, VidiotMap, VidiotMapPointOfInterest, createBadgeReference, createMapReference };
1216
+ 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 };
568
1217
  //# sourceMappingURL=coh-content-db.mjs.map