coh-content-db 2.0.0-rc.6 → 2.0.0-rc.7

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 (65) hide show
  1. package/README.md +3 -3
  2. package/dist/coh-content-db.d.ts +384 -181
  3. package/dist/coh-content-db.js +604 -348
  4. package/dist/coh-content-db.js.map +1 -1
  5. package/dist/coh-content-db.mjs +592 -347
  6. package/dist/coh-content-db.mjs.map +1 -1
  7. package/eslint.config.mjs +1 -0
  8. package/package.json +1 -1
  9. package/src/main/api/alignment.ts +18 -2
  10. package/src/main/api/badge-data.ts +12 -42
  11. package/src/main/api/badge-requirement-data.ts +17 -35
  12. package/src/main/api/badge-requirement-type.ts +28 -7
  13. package/src/main/api/badge-type.ts +15 -15
  14. package/src/main/api/contact-data.ts +7 -5
  15. package/src/main/api/content-bundle.ts +6 -0
  16. package/src/main/api/enhancement-category.ts +26 -26
  17. package/src/main/api/location-data.ts +28 -0
  18. package/src/main/api/mission-data.ts +83 -0
  19. package/src/main/api/mission-type.ts +2 -0
  20. package/src/main/api/morality.ts +31 -0
  21. package/src/main/api/sex.ts +8 -1
  22. package/src/main/api/zone-data.ts +1 -1
  23. package/src/main/changelog.ts +5 -4
  24. package/src/main/db/alignment-list.ts +54 -0
  25. package/src/main/db/alternates.ts +15 -32
  26. package/src/main/db/badge-index.ts +11 -36
  27. package/src/main/db/badge-requirement.ts +22 -43
  28. package/src/main/db/badge-search-options.ts +4 -4
  29. package/src/main/db/badge.ts +53 -54
  30. package/src/main/db/coh-content-database.ts +28 -24
  31. package/src/main/db/contact.ts +17 -14
  32. package/src/main/db/location.ts +30 -0
  33. package/src/main/db/mission.ts +107 -0
  34. package/src/main/db/morality-list.ts +99 -0
  35. package/src/main/db/zone.ts +1 -1
  36. package/src/main/index.ts +8 -3
  37. package/src/main/util.ts +43 -3
  38. package/src/test/api/alignment.test.ts +38 -4
  39. package/src/test/api/badge-data.fixture.ts +1 -17
  40. package/src/test/api/badge-data.test.ts +3 -3
  41. package/src/test/api/badge-requirement-data.fixture.ts +1 -11
  42. package/src/test/api/badge-requirement-type.test.ts +3 -3
  43. package/src/test/api/badge-type.test.ts +5 -5
  44. package/src/test/api/contact-data.fixture.ts +0 -6
  45. package/src/test/api/content-bundle.fixture.ts +1 -17
  46. package/src/test/api/enhancement-category.test.ts +5 -5
  47. package/src/test/api/mission-data.fixture.ts +12 -0
  48. package/src/test/api/sex.test.ts +33 -1
  49. package/src/test/api/zone-data.fixture.ts +1 -1
  50. package/src/test/db/alignment-list.test.ts +200 -0
  51. package/src/test/db/alternates.test.ts +60 -56
  52. package/src/test/db/badge-index.test.ts +82 -72
  53. package/src/test/db/badge-requirement.test.ts +35 -70
  54. package/src/test/db/badge.test.ts +185 -64
  55. package/src/test/db/coh-content-database.test.ts +58 -69
  56. package/src/test/db/contact.test.ts +25 -24
  57. package/src/test/db/location.test.ts +51 -0
  58. package/src/test/db/mission.test.ts +171 -0
  59. package/src/test/db/morality-list.test.ts +457 -0
  60. package/src/test/db/zone.test.ts +4 -4
  61. package/src/test/util.test.ts +54 -1
  62. package/src/main/api/plaque-type.ts +0 -6
  63. package/src/main/db/alignments.ts +0 -17
  64. package/src/test/api/alignments.test.ts +0 -40
  65. package/src/test/api/plaque-type.test.ts +0 -31
@@ -1,112 +1,186 @@
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
9
  const BADGE_REQUIREMENT_TYPE = [
4
- "PLAQUE",
5
- "BADGE",
6
- "INVENTION",
7
- "MISSION",
8
- // Complete a mission
9
- "ARC",
10
- // Complete a story arc
11
- "TASK_FORCE",
12
- // Complete a task force
13
- "INVENTION_PLUS_ONE"
14
- // Some invention badges require you to build x of two different invention levels, 'plus one of either level'.
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"
15
38
  ];
16
39
 
17
40
  const BADGE_TYPE = [
18
- "EXPLORATION",
19
- "HISTORY",
20
- "ACCOMPLISHMENT",
21
- "ACHIEVEMENT",
22
- "ACCOLADE",
23
- "GLADIATOR",
24
- "VETERAN",
25
- "PVP",
26
- "INVENTION",
27
- "DEFEAT",
28
- "EVENT",
29
- "OUROBOROS",
30
- "CONSIGNMENT",
31
- "DAY_JOB",
32
- "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"
33
56
  ];
34
57
 
35
58
  const ENHANCEMENT_CATEGORY = [
36
- "DEFENSE_DEBUFF",
37
- "TO_HIT_DEBUFF",
38
- "TAUNT",
39
- "CONFUSE",
40
- "HEALING",
41
- "DEFENSE_BUFF",
42
- "RESIST_DAMAGE",
43
- "INTANGIBILITY",
44
- "SLEEP",
45
- "SLOW",
46
- "HOLD",
47
- "STUN",
48
- "IMMOBILIZE",
49
- "FEAR",
50
- "ENDURANCE_MODIFICATION",
51
- "ENDURANCE_REDUCTION",
52
- "RECHARGE_REDUCTION",
53
- "INTERRUPT_DURATION",
54
- "ACCURACY",
55
- "TO_HIT_BUFF",
56
- "DAMAGE",
57
- "KNOCKBACK",
58
- "RUN_SPEED",
59
- "JUMP",
60
- "FLY_SPEED",
61
- "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"
62
85
  ];
63
86
 
64
- const PLAQUE_TYPE = [
65
- "WALL_PLAQUE",
66
- "MONUMENT"
67
- ];
87
+ const MISSION_TYPE = ["story-arc", "mission", "task-force", "strike-force", "trial", "personal-story"];
88
+
89
+ const MORALITY = ["hero", "vigilante", "villain", "rogue", "resistance", "loyalist"];
68
90
 
69
91
  const SEX = ["M", "F"];
92
+ const SEX_ORDER = Object.fromEntries(SEX.map((x, index) => [x, index]));
93
+ function compareSex(a, b) {
94
+ const orderA = a ? SEX_ORDER[a] : -1;
95
+ const orderB = b ? SEX_ORDER[b] : -1;
96
+ return orderA - orderB;
97
+ }
70
98
 
71
- var __defProp$7 = Object.defineProperty;
72
- var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
73
- var __publicField$7 = (obj, key, value) => __defNormalProp$7(obj, typeof key !== "symbol" ? key + "" : key, value);
74
- class Alignments {
75
- constructor(raw) {
76
- __publicField$7(this, "items");
77
- __publicField$7(this, "hero");
78
- __publicField$7(this, "villain");
79
- __publicField$7(this, "praetorian");
80
- __publicField$7(this, "primal");
81
- this.items = raw;
82
- this.hero = raw.includes("H");
83
- this.villain = raw.includes("V");
84
- this.praetorian = raw.includes("P");
85
- this.primal = !this.praetorian && (this.hero || this.villain);
99
+ var __defProp$a = Object.defineProperty;
100
+ var __typeError$6 = (msg) => {
101
+ throw TypeError(msg);
102
+ };
103
+ var __defNormalProp$a = (obj, key, value) => key in obj ? __defProp$a(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
104
+ var __publicField$a = (obj, key, value) => __defNormalProp$a(obj, typeof key !== "symbol" ? key + "" : key, value);
105
+ var __accessCheck$6 = (obj, member, msg) => member.has(obj) || __typeError$6("Cannot " + msg);
106
+ var __privateGet$6 = (obj, member, getter) => (__accessCheck$6(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
107
+ 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);
108
+ var __privateSet$5 = (obj, member, value, setter) => (__accessCheck$6(obj, member, "write to private field"), member.set(obj, value), value);
109
+ var _items$1;
110
+ class AlignmentList {
111
+ constructor(items) {
112
+ __privateAdd$6(this, _items$1);
113
+ __publicField$a(this, "hero");
114
+ __publicField$a(this, "villain");
115
+ __publicField$a(this, "praetorian");
116
+ __publicField$a(this, "primal");
117
+ __publicField$a(this, "all");
118
+ const set = new Set(items ?? [...ALIGNMENT]);
119
+ this.hero = set.has("hero") || set.has("primal") || set.has("all");
120
+ this.villain = set.has("villain") || set.has("primal") || set.has("all");
121
+ this.praetorian = set.has("praetorian") || set.has("all");
122
+ this.primal = this.hero && this.villain;
123
+ this.all = this.hero && this.villain && this.praetorian;
124
+ __privateSet$5(this, _items$1, /* @__PURE__ */ new Set());
125
+ if (this.hero) __privateGet$6(this, _items$1).add("hero");
126
+ if (this.villain) __privateGet$6(this, _items$1).add("villain");
127
+ if (this.praetorian) __privateGet$6(this, _items$1).add("praetorian");
128
+ }
129
+ get items() {
130
+ return [...__privateGet$6(this, _items$1)];
131
+ }
132
+ has(alignment) {
133
+ switch (alignment) {
134
+ case "hero": {
135
+ return this.hero;
136
+ }
137
+ case "villain": {
138
+ return this.villain;
139
+ }
140
+ case "praetorian": {
141
+ return this.praetorian;
142
+ }
143
+ case "primal": {
144
+ return this.primal;
145
+ }
146
+ case "all": {
147
+ return this.all;
148
+ }
149
+ default: {
150
+ return false;
151
+ }
152
+ }
86
153
  }
87
154
  }
155
+ _items$1 = new WeakMap();
88
156
 
89
- var __typeError$4 = (msg) => {
157
+ var __typeError$5 = (msg) => {
90
158
  throw TypeError(msg);
91
159
  };
92
- var __accessCheck$4 = (obj, member, msg) => member.has(obj) || __typeError$4("Cannot " + msg);
93
- var __privateGet$4 = (obj, member, getter) => (__accessCheck$4(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
94
- 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);
95
- var __privateSet$3 = (obj, member, value, setter) => (__accessCheck$4(obj, member, "write to private field"), member.set(obj, value), value);
96
- var __privateMethod$2 = (obj, member, method) => (__accessCheck$4(obj, member, "access private method"), method);
97
- var _sortedValues, _Alternates_instances, compareAlternates_fn, compareAlignment_fn, compareSex_fn;
98
- const ALIGNMENT_SORT = { H: 2, V: 1, P: 0 };
99
- const SEX_SORT = { M: 1, F: 0 };
160
+ var __accessCheck$5 = (obj, member, msg) => member.has(obj) || __typeError$5("Cannot " + msg);
161
+ var __privateGet$5 = (obj, member, getter) => (__accessCheck$5(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
162
+ 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);
163
+ var __privateSet$4 = (obj, member, value, setter) => (__accessCheck$5(obj, member, "write to private field"), member.set(obj, value), value);
164
+ var __privateMethod$2 = (obj, member, method) => (__accessCheck$5(obj, member, "access private method"), method);
165
+ var _sortedValues, _Alternates_instances, compareAlternates_fn;
100
166
  class Alternates {
101
- constructor(values) {
102
- __privateAdd$4(this, _Alternates_instances);
103
- __privateAdd$4(this, _sortedValues, []);
104
- __privateSet$3(this, _sortedValues, values.sort());
105
- __privateGet$4(this, _sortedValues).sort((a, b) => __privateMethod$2(this, _Alternates_instances, compareAlternates_fn).call(this, a, b));
167
+ /**
168
+ * Create an alternate set from either a list of categorized values, or a single value when there are no alternates.
169
+ * @param value List of alternates, or a single value.
170
+ */
171
+ constructor(value) {
172
+ __privateAdd$5(this, _Alternates_instances);
173
+ __privateAdd$5(this, _sortedValues, []);
174
+ if (Array.isArray(value)) {
175
+ __privateSet$4(this, _sortedValues, value.sort());
176
+ __privateGet$5(this, _sortedValues).sort((a, b) => __privateMethod$2(this, _Alternates_instances, compareAlternates_fn).call(this, a, b));
177
+ } else {
178
+ __privateSet$4(this, _sortedValues, [{ value }]);
179
+ }
106
180
  }
107
181
  getValue(alignment, sex) {
108
- for (let index = __privateGet$4(this, _sortedValues).length; index--; ) {
109
- const entry = __privateGet$4(this, _sortedValues)[index];
182
+ for (let index = __privateGet$5(this, _sortedValues).length; index--; ) {
183
+ const entry = __privateGet$5(this, _sortedValues)[index];
110
184
  if ((entry.alignment === void 0 || entry.alignment === alignment) && (entry.sex === void 0 || entry.sex === sex)) return entry.value;
111
185
  }
112
186
  return this.default?.value;
@@ -115,13 +189,13 @@ class Alternates {
115
189
  * Get the default value for this list of alternates, the value with the highest priority and lowest specificity.
116
190
  */
117
191
  get default() {
118
- return __privateGet$4(this, _sortedValues)[0];
192
+ return __privateGet$5(this, _sortedValues)[0];
119
193
  }
120
194
  /**
121
195
  * Get the list of alternates sorted in canonical order (alignment then sex, low to high specificity).
122
196
  */
123
197
  get canonical() {
124
- return __privateGet$4(this, _sortedValues);
198
+ return __privateGet$5(this, _sortedValues);
125
199
  }
126
200
  /**
127
201
  * Create a joined string from the alternate values in canonical order.
@@ -137,48 +211,32 @@ compareAlternates_fn = function(a, b) {
137
211
  const aSpecificity = (a.alignment ? 2 : 0) + (a.sex ? 1 : 0);
138
212
  const bSpecificity = (b.alignment ? 2 : 0) + (b.sex ? 1 : 0);
139
213
  if (aSpecificity !== bSpecificity) return aSpecificity - bSpecificity;
140
- const alignmentComparison = __privateMethod$2(this, _Alternates_instances, compareAlignment_fn).call(this, a.alignment, b.alignment);
214
+ const alignmentComparison = compareAlignment(a.alignment, b.alignment);
141
215
  if (alignmentComparison !== 0) return alignmentComparison;
142
- const sexComparison = __privateMethod$2(this, _Alternates_instances, compareSex_fn).call(this, a.sex, b.sex);
216
+ const sexComparison = compareSex(a.sex, b.sex);
143
217
  if (sexComparison !== 0) return sexComparison;
144
218
  return String(a.value).localeCompare(String(b.value));
145
219
  };
146
- compareAlignment_fn = function(a, b) {
147
- if (a === b) return 0;
148
- if (a === void 0 && b !== void 0) return -1;
149
- if (b === void 0 && a !== void 0) return 1;
150
- const aSort = a === void 0 ? -1 : ALIGNMENT_SORT[a] ?? -1;
151
- const bSort = b === void 0 ? -1 : ALIGNMENT_SORT[b] ?? -1;
152
- return bSort - aSort;
153
- };
154
- compareSex_fn = function(a, b) {
155
- if (a === b) return 0;
156
- if (a === void 0 && b !== void 0) return -1;
157
- if (b === void 0 && a !== void 0) return 1;
158
- const aSort = SEX_SORT[a ?? -1] ?? -1;
159
- const bSort = SEX_SORT[b ?? -1] ?? -1;
160
- return bSort - aSort;
161
- };
162
220
 
163
- var __typeError$3 = (msg) => {
221
+ var __typeError$4 = (msg) => {
164
222
  throw TypeError(msg);
165
223
  };
166
- var __accessCheck$3 = (obj, member, msg) => member.has(obj) || __typeError$3("Cannot " + msg);
167
- var __privateGet$3 = (obj, member, getter) => (__accessCheck$3(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
168
- 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);
169
- var __privateSet$2 = (obj, member, value, setter) => (__accessCheck$3(obj, member, "write to private field"), member.set(obj, value), value);
170
- var __privateMethod$1 = (obj, member, method) => (__accessCheck$3(obj, member, "access private method"), method);
224
+ var __accessCheck$4 = (obj, member, msg) => member.has(obj) || __typeError$4("Cannot " + msg);
225
+ var __privateGet$4 = (obj, member, getter) => (__accessCheck$4(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
226
+ 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);
227
+ var __privateSet$3 = (obj, member, value, setter) => (__accessCheck$4(obj, member, "write to private field"), member.set(obj, value), value);
228
+ var __privateMethod$1 = (obj, member, method) => (__accessCheck$4(obj, member, "access private method"), method);
171
229
  var _value, _Key_instances, validateKey_fn;
172
230
  const INVALID_KEY_PATTERN = /[^a-z0-9-]/;
173
231
  class Key {
174
232
  constructor(value) {
175
- __privateAdd$3(this, _Key_instances);
176
- __privateAdd$3(this, _value);
233
+ __privateAdd$4(this, _Key_instances);
234
+ __privateAdd$4(this, _value);
177
235
  __privateMethod$1(this, _Key_instances, validateKey_fn).call(this, value);
178
- __privateSet$2(this, _value, value);
236
+ __privateSet$3(this, _value, value);
179
237
  }
180
238
  get value() {
181
- return __privateGet$3(this, _value);
239
+ return __privateGet$4(this, _value);
182
240
  }
183
241
  }
184
242
  _value = new WeakMap();
@@ -187,215 +245,314 @@ validateKey_fn = function(key) {
187
245
  if (INVALID_KEY_PATTERN.test(key)) throw new Error(`Invalid key: [${key}]; Keys can only contain lowercase characters, numbers and dashes.`);
188
246
  };
189
247
 
190
- var __defProp$6 = Object.defineProperty;
191
- var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
192
- var __publicField$6 = (obj, key, value) => __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
248
+ var __defProp$9 = Object.defineProperty;
249
+ var __defNormalProp$9 = (obj, key, value) => key in obj ? __defProp$9(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
250
+ var __publicField$9 = (obj, key, value) => __defNormalProp$9(obj, typeof key !== "symbol" ? key + "" : key, value);
193
251
  class Archetype {
194
252
  constructor(data) {
195
- __publicField$6(this, "key");
196
- __publicField$6(this, "name");
197
- __publicField$6(this, "description");
253
+ __publicField$9(this, "key");
254
+ __publicField$9(this, "name");
255
+ __publicField$9(this, "description");
198
256
  this.key = new Key(data.key).value;
199
257
  this.name = data.name;
200
258
  this.description = data.description;
201
259
  }
202
260
  }
203
261
 
204
- var __defProp$5 = Object.defineProperty;
205
- var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
206
- var __publicField$5 = (obj, key, value) => __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
262
+ function badgeUri(target) {
263
+ const key = typeof target === "string" ? target : target.key;
264
+ return `badge://${key}`;
265
+ }
266
+ function badgeLink(target) {
267
+ const key = typeof target === "string" ? target : target.key;
268
+ return `[${key}](${badgeUri(target)})`;
269
+ }
270
+ function contactUri(target) {
271
+ const key = typeof target === "string" ? target : target.key;
272
+ return `contact://${key}`;
273
+ }
274
+ function contactLink(target) {
275
+ const key = typeof target === "string" ? target : target.key;
276
+ return `[${key}](${contactUri(target)})`;
277
+ }
278
+ function missionUri(target) {
279
+ const key = typeof target === "string" ? target : target.key;
280
+ return `mission://${key}`;
281
+ }
282
+ function missionLink(target) {
283
+ const key = typeof target === "string" ? target : target.key;
284
+ return `[${key}](${missionUri(target)})`;
285
+ }
286
+ function zoneUri(target) {
287
+ const key = typeof target === "string" ? target : target.key;
288
+ return `zone://${key}`;
289
+ }
290
+ function zoneLink(target) {
291
+ const key = typeof target === "string" ? target : target.key;
292
+ return `[${key}](${zoneUri(target)})`;
293
+ }
294
+ function coalesceToArray(value) {
295
+ if (!value) return void 0;
296
+ return Array.isArray(value) ? value : [value];
297
+ }
298
+
299
+ var __defProp$8 = Object.defineProperty;
300
+ var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
301
+ var __publicField$8 = (obj, key, value) => __defNormalProp$8(obj, typeof key !== "symbol" ? key + "" : key, value);
207
302
  class BadgeRequirement {
208
303
  constructor(data) {
209
304
  /**
210
- * Key.
211
- */
212
- __publicField$5(this, "key");
213
- /**
214
- * Type of requirement.
215
- */
216
- __publicField$5(this, "type");
217
- /**
218
- * Zone the requirement is located in.
219
- */
220
- __publicField$5(this, "zoneKey");
221
- /**
222
- * /loc coordinates.
223
- */
224
- __publicField$5(this, "loc");
225
- /**
226
- * Is it a wall plaque or a physical monument?
305
+ * Unique key used to reference this badge requirement.
306
+ *
307
+ * Keys must be unique and can only contain lowercase letters, numbers and hyphens (`-`).
227
308
  */
228
- __publicField$5(this, "plaqueType");
309
+ __publicField$8(this, "key");
229
310
  /**
230
- * Plaque inscription.
311
+ * The requirement type.
231
312
  */
232
- __publicField$5(this, "plaqueInscription");
313
+ __publicField$8(this, "type");
233
314
  /**
234
- * The number or letter the plaque appears as on Vidiot Maps.
315
+ * If the requirement involves a location, where it is.
235
316
  */
236
- __publicField$5(this, "vidiotMapKey");
317
+ __publicField$8(this, "location");
237
318
  /**
238
- * The key of the badge for this requirement.
319
+ * If the requirement involves a badge, the badge key.
239
320
  */
240
- __publicField$5(this, "badgeKey");
321
+ __publicField$8(this, "badgeKey");
241
322
  /**
242
- * Mission name.
323
+ * If the requirement involves a mission, the mission key.
243
324
  */
244
- __publicField$5(this, "missionName");
325
+ __publicField$8(this, "missionKey");
245
326
  /**
246
- * {@link Contact} key for the story arc.
327
+ * If the requirement involves a monument, the text that is displayed thereon.
247
328
  */
248
- __publicField$5(this, "contactKey");
329
+ __publicField$8(this, "monumentText");
249
330
  /**
250
- * Level of the invention required.
331
+ * If the requirement involves crafting an invention, the Level of the invention required.
251
332
  */
252
- __publicField$5(this, "inventionLevel");
333
+ __publicField$8(this, "inventionLevel");
253
334
  /**
254
- * The types of enhancements required to be crafted.
335
+ * If the requirement involves crafting an invention, the types of enhancements that will qualify.
255
336
  */
256
- __publicField$5(this, "inventionTypes");
337
+ __publicField$8(this, "inventionTypes");
257
338
  /**
258
- * Number of invention crafts required.
339
+ * Number of times the task needs to be repeated.
259
340
  */
260
- __publicField$5(this, "inventionCount");
341
+ __publicField$8(this, "count");
261
342
  /**
262
- * Any additional notes.
343
+ * Additional information about the requirement.
263
344
  */
264
- __publicField$5(this, "notes");
345
+ __publicField$8(this, "notes");
265
346
  /**
266
347
  * List of external links. Wiki, forums, etc.
267
348
  */
268
- __publicField$5(this, "links");
349
+ __publicField$8(this, "links");
269
350
  this.key = new Key(data.key).value;
270
351
  this.type = data.type;
271
- this.zoneKey = data.zoneKey;
272
- this.loc = data.loc;
273
- this.plaqueType = data.plaqueType;
274
- this.plaqueInscription = data.plaqueInscription;
275
- this.vidiotMapKey = data.vidiotMapKey;
352
+ this.location = coalesceToArray(data.location);
276
353
  this.badgeKey = data.badgeKey;
277
- this.missionName = data.missionName;
278
- this.contactKey = data.contactKey;
354
+ this.missionKey = data.missionKey;
355
+ this.monumentText = data.monumentText;
279
356
  this.inventionLevel = data.inventionLevel;
280
357
  this.inventionTypes = data.inventionTypes;
281
- this.inventionCount = data.inventionCount;
358
+ this.count = data.count;
282
359
  this.notes = data.notes;
283
360
  this.links = data.links ?? [];
284
361
  }
285
362
  }
286
363
 
287
- var __defProp$4 = Object.defineProperty;
364
+ var __defProp$7 = Object.defineProperty;
365
+ var __typeError$3 = (msg) => {
366
+ throw TypeError(msg);
367
+ };
368
+ var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
369
+ var __publicField$7 = (obj, key, value) => __defNormalProp$7(obj, typeof key !== "symbol" ? key + "" : key, value);
370
+ var __accessCheck$3 = (obj, member, msg) => member.has(obj) || __typeError$3("Cannot " + msg);
371
+ var __privateGet$3 = (obj, member, getter) => (__accessCheck$3(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
372
+ 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);
373
+ var __privateSet$2 = (obj, member, value, setter) => (__accessCheck$3(obj, member, "write to private field"), member.set(obj, value), value);
374
+ var _items;
375
+ class MoralityList {
376
+ constructor(items) {
377
+ __privateAdd$3(this, _items);
378
+ __publicField$7(this, "hero");
379
+ __publicField$7(this, "vigilante");
380
+ __publicField$7(this, "villain");
381
+ __publicField$7(this, "rogue");
382
+ __publicField$7(this, "resistance");
383
+ __publicField$7(this, "loyalist");
384
+ __publicField$7(this, "primal");
385
+ __publicField$7(this, "praetorian");
386
+ __publicField$7(this, "heroic");
387
+ __publicField$7(this, "villainous");
388
+ __publicField$7(this, "paragonCityAccess");
389
+ __publicField$7(this, "rogueIslesAccess");
390
+ __publicField$7(this, "all");
391
+ const set = new Set(items ?? [...MORALITY]);
392
+ this.hero = set.has("hero") || set.has("primal") || set.has("heroic") || set.has("paragon-city-access") || set.has("all");
393
+ this.vigilante = set.has("vigilante") || set.has("primal") || set.has("heroic") || set.has("paragon-city-access") || set.has("rogue-isles-access") || set.has("all");
394
+ this.villain = set.has("villain") || set.has("primal") || set.has("villainous") || set.has("rogue-isles-access") || set.has("all");
395
+ this.rogue = set.has("rogue") || set.has("primal") || set.has("villainous") || set.has("paragon-city-access") || set.has("rogue-isles-access") || set.has("all");
396
+ this.resistance = set.has("resistance") || set.has("praetorian") || set.has("all");
397
+ this.loyalist = set.has("loyalist") || set.has("praetorian") || set.has("all");
398
+ this.primal = this.hero && this.vigilante && this.villain && this.rogue;
399
+ this.praetorian = this.loyalist && this.resistance;
400
+ this.heroic = this.hero && this.vigilante;
401
+ this.villainous = this.villain && this.rogue;
402
+ this.paragonCityAccess = this.heroic && this.rogue;
403
+ this.rogueIslesAccess = this.villainous && this.vigilante;
404
+ this.all = this.primal && this.praetorian;
405
+ __privateSet$2(this, _items, /* @__PURE__ */ new Set());
406
+ if (this.hero) __privateGet$3(this, _items).add("hero");
407
+ if (this.vigilante) __privateGet$3(this, _items).add("vigilante");
408
+ if (this.villain) __privateGet$3(this, _items).add("villain");
409
+ if (this.rogue) __privateGet$3(this, _items).add("rogue");
410
+ if (this.resistance) __privateGet$3(this, _items).add("resistance");
411
+ if (this.loyalist) __privateGet$3(this, _items).add("loyalist");
412
+ }
413
+ get items() {
414
+ return [...__privateGet$3(this, _items)];
415
+ }
416
+ has(morality) {
417
+ switch (morality) {
418
+ case "hero": {
419
+ return this.hero;
420
+ }
421
+ case "vigilante": {
422
+ return this.vigilante;
423
+ }
424
+ case "villain": {
425
+ return this.villain;
426
+ }
427
+ case "rogue": {
428
+ return this.rogue;
429
+ }
430
+ case "resistance": {
431
+ return this.resistance;
432
+ }
433
+ case "loyalist": {
434
+ return this.loyalist;
435
+ }
436
+ case "primal": {
437
+ return this.primal;
438
+ }
439
+ case "praetorian": {
440
+ return this.praetorian;
441
+ }
442
+ case "heroic": {
443
+ return this.hero;
444
+ }
445
+ case "paragon-city-access": {
446
+ return this.paragonCityAccess;
447
+ }
448
+ case "rogue-isles-access": {
449
+ return this.rogueIslesAccess;
450
+ }
451
+ case "villainous": {
452
+ return this.villainous;
453
+ }
454
+ case "all": {
455
+ return this.all;
456
+ }
457
+ default: {
458
+ return false;
459
+ }
460
+ }
461
+ }
462
+ }
463
+ _items = new WeakMap();
464
+
465
+ var __defProp$6 = Object.defineProperty;
288
466
  var __typeError$2 = (msg) => {
289
467
  throw TypeError(msg);
290
468
  };
291
- var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
292
- var __publicField$4 = (obj, key, value) => __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
469
+ var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
470
+ var __publicField$6 = (obj, key, value) => __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
293
471
  var __accessCheck$2 = (obj, member, msg) => member.has(obj) || __typeError$2("Cannot " + msg);
294
472
  var __privateGet$2 = (obj, member, getter) => (__accessCheck$2(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
295
473
  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);
296
- var _requirementsIndex;
474
+ var _requirementsIndex, _zoneKeys;
297
475
  class Badge {
298
476
  constructor(badgeData) {
299
477
  __privateAdd$2(this, _requirementsIndex, {});
478
+ __privateAdd$2(this, _zoneKeys, /* @__PURE__ */ new Set());
300
479
  /**
301
480
  * The database key for this badge.
302
481
  */
303
- __publicField$4(this, "key");
482
+ __publicField$6(this, "key");
304
483
  /**
305
484
  * The type of badge.
306
485
  */
307
- __publicField$4(this, "type");
486
+ __publicField$6(this, "type");
308
487
  /**
309
488
  * The name of this badge.
310
489
  *
311
490
  * May vary by character sex or alignment.
312
491
  */
313
- __publicField$4(this, "name");
492
+ __publicField$6(this, "name");
314
493
  /**
315
- * The character alignments that this badge is available to.
494
+ * The character moralities that this badge is available to.
316
495
  */
317
- __publicField$4(this, "alignment");
496
+ __publicField$6(this, "morality");
318
497
  /**
319
498
  * The badge text as it appears in-game. May vary by character sex or alignment.
320
499
  */
321
- __publicField$4(this, "badgeText");
500
+ __publicField$6(this, "badgeText");
322
501
  /**
323
502
  * Short description of how to acquire the badge. Detailed instructions will be in the notes field.
324
503
  */
325
- __publicField$4(this, "acquisition");
504
+ __publicField$6(this, "acquisition");
326
505
  /**
327
506
  * Absolute URL to this badge's icon.
328
507
  *
329
508
  * May vary by character sex or alignment.
330
509
  */
331
- __publicField$4(this, "icon");
510
+ __publicField$6(this, "icon");
332
511
  /**
333
512
  * Freeform notes or tips about the badge.
334
513
  */
335
- __publicField$4(this, "notes");
514
+ __publicField$6(this, "notes");
336
515
  /**
337
516
  * List of external links. Wiki, forums, etc.
338
517
  */
339
- __publicField$4(this, "links");
340
- /**
341
- * For exploration badges, the key of the {@link Zone} that this badge is found on.
342
- */
343
- __publicField$4(this, "zoneKey");
344
- /**
345
- * For exploration badges, the `/loc` coordinates of the badge.
346
- */
347
- __publicField$4(this, "loc");
348
- /**
349
- * For plaques that appear on a Vidiot Map, the number or letter the badge appears as.
350
- */
351
- __publicField$4(this, "vidiotMapKey");
518
+ __publicField$6(this, "links");
352
519
  /**
353
- * ID used with the in-game `/settitle` command to apply the badge.
520
+ * The id used with the in-game `/settitle` command to apply the badge.
521
+ * The first value is the id for primal characters and the (optional) second number is the id for praetorian characters.
354
522
  */
355
- __publicField$4(this, "setTitle");
523
+ __publicField$6(this, "setTitleId");
356
524
  /**
357
525
  * A description of the effect the badge will have, such as a buff or granting a temporary power.
358
526
  */
359
- __publicField$4(this, "effect");
527
+ __publicField$6(this, "effect");
360
528
  /**
361
- * Represents the layered requirements for badges with multiple fulfillment steps,
362
- * such as visiting plaques for history badges or collecting other badges.
363
- *
364
- * The outer array represents groups of requirements evaluated with OR logic —
365
- * fulfilling any group satisfies the badge.
366
- *
367
- * Each inner array represents individual requirements evaluated with AND logic —
368
- * all conditions in the group must be met.
529
+ * Represents the requirements for badges with multiple fulfillment steps, such as visiting monuments for history badges, completing missions, or collecting other badges.
369
530
  */
370
- __publicField$4(this, "requirements");
531
+ __publicField$6(this, "requirements");
371
532
  /**
372
533
  * 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.
373
534
  */
374
- __publicField$4(this, "ignoreInTotals");
535
+ __publicField$6(this, "ignoreInTotals");
375
536
  this.key = new Key(badgeData.key).value;
376
537
  this.type = badgeData.type;
377
538
  this.name = new Alternates(badgeData.name);
378
- this.alignment = new Alignments(badgeData.alignment);
539
+ this.morality = new MoralityList(coalesceToArray(badgeData.morality));
379
540
  this.badgeText = new Alternates(badgeData.badgeText ?? []);
380
541
  this.acquisition = badgeData.acquisition;
381
542
  this.icon = new Alternates(badgeData.icon ?? []);
382
543
  this.notes = badgeData.notes;
383
544
  this.links = badgeData.links ?? [];
384
- this.zoneKey = badgeData.zoneKey;
385
- this.loc = badgeData.loc;
386
545
  this.effect = badgeData.effect;
387
- this.vidiotMapKey = badgeData.vidiotMapKey;
388
- this.setTitle = badgeData.setTitle;
546
+ this.setTitleId = badgeData.setTitleId;
389
547
  this.ignoreInTotals = badgeData.ignoreInTotals ?? false;
390
- this.requirements = badgeData.requirements?.map((groups, index) => {
391
- const existingKeysInGroup = /* @__PURE__ */ new Set();
392
- return groups.map((requirementData) => {
393
- if (existingKeysInGroup.has(requirementData.key)) throw new Error(`Duplicate badge requirement key [${badgeData.key}:${requirementData.key}] in group [${index + 1}]`);
394
- existingKeysInGroup.add(requirementData.key);
395
- const badge = new BadgeRequirement(requirementData);
396
- __privateGet$2(this, _requirementsIndex)[badge.key] = badge;
397
- return badge;
398
- });
548
+ this.requirements = badgeData.requirements?.map((requirementData) => {
549
+ if (__privateGet$2(this, _requirementsIndex)[requirementData.key]) throw new Error(`Duplicate badge requirement key [${badgeData.key}:${requirementData.key}]`);
550
+ const requirement = new BadgeRequirement(requirementData);
551
+ __privateGet$2(this, _requirementsIndex)[requirement.key] = requirement;
552
+ if (requirement.location) for (const location of requirement.location) {
553
+ if (location.zoneKey) __privateGet$2(this, _zoneKeys).add(location.zoneKey);
554
+ }
555
+ return requirement;
399
556
  });
400
557
  }
401
558
  getRequirement(key) {
@@ -403,8 +560,37 @@ class Badge {
403
560
  if (result === void 0) throw new Error(`Unknown badge requirement key [${key}]`);
404
561
  return result;
405
562
  }
563
+ /**
564
+ * Return a list of all the zone keys referenced by this badge.
565
+ */
566
+ get zoneKeys() {
567
+ return [...__privateGet$2(this, _zoneKeys)];
568
+ }
569
+ /**
570
+ * The zone key if this badge relates to a single zone.
571
+ */
572
+ get zoneKey() {
573
+ return __privateGet$2(this, _zoneKeys).size === 1 ? __privateGet$2(this, _zoneKeys).values().next().value : void 0;
574
+ }
406
575
  }
407
576
  _requirementsIndex = new WeakMap();
577
+ _zoneKeys = new WeakMap();
578
+ function compareByDefaultName(a, b) {
579
+ const aName = a?.name.default?.value;
580
+ const bName = b?.name.default?.value;
581
+ if (!aName && !bName) return 0;
582
+ if (!aName) return 1;
583
+ if (!bName) return -1;
584
+ return aName.localeCompare(bName);
585
+ }
586
+ function compareByZoneKey(a, b) {
587
+ const aZone = a?.zoneKey;
588
+ const bZone = b?.zoneKey;
589
+ if (!aZone && !bZone) return 0;
590
+ if (!aZone) return 1;
591
+ if (!bZone) return -1;
592
+ return aZone.localeCompare(bZone);
593
+ }
408
594
 
409
595
  var __typeError$1 = (msg) => {
410
596
  throw TypeError(msg);
@@ -414,16 +600,12 @@ var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "rea
414
600
  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);
415
601
  var __privateSet$1 = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), member.set(obj, value), value);
416
602
  var __privateMethod = (obj, member, method) => (__accessCheck$1(obj, member, "access private method"), method);
417
- var _badges, _badgeIndex$1, _zoneOrder, _BadgeIndex_instances, satisfiesQueryPredicate_fn, satisfiesFilterPredicate_fn, sort_fn;
603
+ var _badges, _badgeIndex$1, _BadgeIndex_instances, satisfiesQueryPredicate_fn, satisfiesFilterPredicate_fn, sort_fn;
418
604
  class BadgeIndex {
419
- constructor(badges, zones) {
605
+ constructor(badges) {
420
606
  __privateAdd$1(this, _BadgeIndex_instances);
421
607
  __privateAdd$1(this, _badges, []);
422
608
  __privateAdd$1(this, _badgeIndex$1, {});
423
- __privateAdd$1(this, _zoneOrder, {});
424
- __privateSet$1(this, _zoneOrder, Object.fromEntries(
425
- zones?.sort((a, b) => a.name.localeCompare(b.name))?.map((x, index) => [x.key, index]) ?? []
426
- ));
427
609
  __privateSet$1(this, _badges, badges);
428
610
  for (const badge of badges) {
429
611
  if (__privateGet$1(this, _badgeIndex$1)[badge.key] !== void 0) throw new Error(`Duplicate badge key [${badge.key}]`);
@@ -431,12 +613,8 @@ class BadgeIndex {
431
613
  }
432
614
  }
433
615
  getBadge(key) {
434
- const result = __privateGet$1(this, _badgeIndex$1)[key];
435
- if (result === void 0) throw new Error(`Unknown badge key [${key}]`);
436
- return result;
437
- }
438
- badgeExists(key) {
439
- return !!__privateGet$1(this, _badgeIndex$1)[key];
616
+ if (!key) return void 0;
617
+ return __privateGet$1(this, _badgeIndex$1)[key];
440
618
  }
441
619
  searchBadges(options) {
442
620
  const filtered = options?.query || options?.filter ? __privateGet$1(this, _badges).filter((badge) => __privateMethod(this, _BadgeIndex_instances, satisfiesQueryPredicate_fn).call(this, badge, options?.query) && __privateMethod(this, _BadgeIndex_instances, satisfiesFilterPredicate_fn).call(this, badge, options?.filter)) : __privateGet$1(this, _badges);
@@ -455,55 +633,47 @@ class BadgeIndex {
455
633
  }
456
634
  _badges = new WeakMap();
457
635
  _badgeIndex$1 = new WeakMap();
458
- _zoneOrder = new WeakMap();
459
636
  _BadgeIndex_instances = new WeakSet();
460
637
  satisfiesQueryPredicate_fn = function(badge, query) {
461
638
  const queryString = query?.str?.toLowerCase() ?? "";
462
- return !!((query?.on?.name ?? true) && badge.name.canonical.some((x) => x.value.toLowerCase().includes(queryString)) || query?.on?.badgeText && badge.badgeText.canonical.some((x) => x.value.toLowerCase().includes(queryString)) || query?.on?.acquisition && badge.acquisition?.toLowerCase().includes(queryString) || query?.on?.effect && badge.effect?.toLowerCase().includes(queryString) || query?.on?.notes && badge.notes?.toLowerCase().includes(queryString) || query?.on?.setTitle && (badge.setTitle?.id?.toString().includes(queryString) || badge.setTitle?.praetorianId?.toString().includes(queryString)));
639
+ return !!((query?.on?.name ?? true) && badge.name.canonical.some((x) => x.value.toLowerCase().includes(queryString)) || query?.on?.badgeText && badge.badgeText.canonical.some((x) => x.value.toLowerCase().includes(queryString)) || query?.on?.acquisition && badge.acquisition?.toLowerCase().includes(queryString) || query?.on?.effect && badge.effect?.toLowerCase().includes(queryString) || query?.on?.notes && badge.notes?.toLowerCase().includes(queryString) || query?.on?.setTitle && badge.setTitleId?.some((x) => x?.toString().includes(queryString)));
463
640
  };
464
641
  satisfiesFilterPredicate_fn = function(badge, filter) {
465
- return (!filter?.type || badge.type === filter.type) && (!filter?.zoneKey || badge.zoneKey === filter.zoneKey) && (!filter?.alignment || badge.alignment.items.includes(filter.alignment));
642
+ return (!filter?.type || badge.type === filter.type) && (!filter?.zoneKey || badge.zoneKey === filter.zoneKey) && (!filter?.morality || badge.morality.has(filter.morality));
466
643
  };
467
644
  sort_fn = function(badges, sort) {
468
645
  if (!sort) return badges;
469
- const ascending = sort.dir !== "DESC";
470
- if (!sort.by || sort.by === "CANONICAL") return sort.dir === "DESC" ? badges.reverse() : badges;
471
- if (sort.by === "BADGE_NAME") return ascending ? badges.sort((a, b) => a.name.default?.value.localeCompare(b.name.default?.value ?? "") ?? 0) : badges.sort((a, b) => b.name.default?.value.localeCompare(a.name.default?.value ?? "") ?? 0);
472
- return badges.sort((a, b) => {
473
- const aIndex = __privateGet$1(this, _zoneOrder)[a.zoneKey ?? ""];
474
- const bIndex = __privateGet$1(this, _zoneOrder)[b.zoneKey ?? ""];
475
- if (aIndex === bIndex) return 0;
476
- if (aIndex === void 0) return ascending ? 1 : -1;
477
- if (bIndex === void 0) return ascending ? -1 : 1;
478
- return ascending ? aIndex - bIndex : bIndex - aIndex;
479
- });
646
+ const ascending = sort.dir !== "desc";
647
+ if (sort.by === "badge-name") return badges.sort((a, b) => ascending ? compareByDefaultName(a, b) : compareByDefaultName(b, a));
648
+ if (sort.by === "zone-key") return badges.sort((a, b) => ascending ? compareByZoneKey(a, b) : compareByZoneKey(b, a));
649
+ return sort.dir === "desc" ? badges.reverse() : badges;
480
650
  };
481
651
 
482
- var __defProp$3 = Object.defineProperty;
483
- var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
484
- var __publicField$3 = (obj, key, value) => __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
652
+ var __defProp$5 = Object.defineProperty;
653
+ var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
654
+ var __publicField$5 = (obj, key, value) => __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
485
655
  class BundleMetadata {
486
656
  constructor(bundle) {
487
657
  /**
488
658
  * Name of the content bundle.
489
659
  */
490
- __publicField$3(this, "name");
660
+ __publicField$5(this, "name");
491
661
  /**
492
662
  * Description of the fork.
493
663
  */
494
- __publicField$3(this, "description");
664
+ __publicField$5(this, "description");
495
665
  /**
496
666
  * Repository where the db content package is maintained.
497
667
  */
498
- __publicField$3(this, "repository");
668
+ __publicField$5(this, "repository");
499
669
  /**
500
670
  * List of external links. Wiki, forums, etc.
501
671
  */
502
- __publicField$3(this, "links");
672
+ __publicField$5(this, "links");
503
673
  /**
504
674
  * Change log for this data package.
505
675
  */
506
- __publicField$3(this, "changelog");
676
+ __publicField$5(this, "changelog");
507
677
  this.name = bundle.name;
508
678
  this.description = bundle.description;
509
679
  this.repository = bundle.repository;
@@ -512,92 +682,159 @@ class BundleMetadata {
512
682
  }
513
683
  }
514
684
 
515
- var __defProp$2 = Object.defineProperty;
516
- var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
517
- var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
685
+ var __defProp$4 = Object.defineProperty;
686
+ var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
687
+ var __publicField$4 = (obj, key, value) => __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
518
688
  class Zone {
519
689
  constructor(data) {
520
690
  /**
521
691
  * Unique key used to reference this zone.
522
692
  *
523
- * Keys can only contain lowercase letters, numbers and hyphens (`-`).
693
+ * Keys must be unique and can only contain lowercase letters, numbers and hyphens (`-`).
524
694
  */
525
- __publicField$2(this, "key");
695
+ __publicField$4(this, "key");
526
696
  /**
527
697
  * The name of the zone as it appears in-game.
528
698
  */
529
- __publicField$2(this, "name");
699
+ __publicField$4(this, "name");
530
700
  /**
531
701
  * List of external links. Wiki, forums, etc.
532
702
  */
533
- __publicField$2(this, "links");
703
+ __publicField$4(this, "links");
534
704
  this.key = new Key(data.key).value;
535
705
  this.name = data.name;
536
706
  this.links = data.links ?? [];
537
707
  }
538
708
  }
539
709
 
540
- var __defProp$1 = Object.defineProperty;
541
- var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
542
- var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
710
+ var __defProp$3 = Object.defineProperty;
711
+ var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
712
+ var __publicField$3 = (obj, key, value) => __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
543
713
  class Contact {
544
- constructor(contactData) {
714
+ constructor(data) {
545
715
  /**
546
716
  * Unique key used to reference this contact.
547
717
  *
548
- * Keys can only contain lowercase letters, numbers and hyphens (`-`).
718
+ * Keys must be unique and can only contain lowercase letters, numbers and hyphens (`-`).
549
719
  */
550
- __publicField$1(this, "key");
720
+ __publicField$3(this, "key");
551
721
  /**
552
722
  * The name of this contact.
553
723
  */
554
- __publicField$1(this, "name");
724
+ __publicField$3(this, "name");
555
725
  /**
556
726
  * The contact's title.
557
727
  */
558
- __publicField$1(this, "title");
728
+ __publicField$3(this, "title");
559
729
  /**
560
- * The zone this character is located in.
730
+ * The character moralities that this contact will interact with.
561
731
  */
562
- __publicField$1(this, "zoneKey");
732
+ __publicField$3(this, "morality");
563
733
  /**
564
- * The `/loc` coordinates of the contact.
734
+ * The location of this contact.
565
735
  */
566
- __publicField$1(this, "loc");
736
+ __publicField$3(this, "location");
567
737
  /**
568
738
  * The level range this contact will offer missions for.
569
739
  */
570
- __publicField$1(this, "levelRange");
740
+ __publicField$3(this, "levelRange");
571
741
  /**
572
742
  * Freeform notes or tips about the contact.
573
743
  */
574
- __publicField$1(this, "notes");
744
+ __publicField$3(this, "notes");
575
745
  /**
576
746
  * List of external links. Wiki, forums, etc.
577
747
  */
578
- __publicField$1(this, "links");
579
- this.key = new Key(contactData.key).value;
580
- this.name = contactData.name;
581
- this.title = contactData.title;
582
- this.zoneKey = contactData.zoneKey;
583
- this.loc = contactData.loc;
584
- this.levelRange = contactData.levelRange;
585
- this.notes = contactData.notes;
586
- this.links = contactData.links ?? [];
748
+ __publicField$3(this, "links");
749
+ this.key = new Key(data.key).value;
750
+ this.name = data.name;
751
+ this.title = data.title;
752
+ this.morality = new MoralityList(coalesceToArray(data.morality));
753
+ this.location = data.location;
754
+ this.levelRange = data.levelRange;
755
+ this.notes = data.notes;
756
+ this.links = data.links ?? [];
587
757
  }
588
758
  }
589
759
 
590
- var __defProp = Object.defineProperty;
760
+ var __defProp$2 = Object.defineProperty;
761
+ var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
762
+ var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
763
+ class Mission {
764
+ constructor(data) {
765
+ /**
766
+ * Unique key used to reference this mission.
767
+ *
768
+ * Keys must be unique and can only contain lowercase letters, numbers and hyphens (`-`).
769
+ */
770
+ __publicField$2(this, "key");
771
+ /**
772
+ * The name of the mission as it appears from the contact.
773
+ *
774
+ * The name may be different when viewed in Ouroboros as a Flashback.
775
+ */
776
+ __publicField$2(this, "name");
777
+ /**
778
+ * The type of mission... Story arc, task force, trial, etc.
779
+ */
780
+ __publicField$2(this, "type");
781
+ /**
782
+ * The character moralities that may accept the mission.
783
+ */
784
+ __publicField$2(this, "morality");
785
+ /**
786
+ * The keys of any contacts that provide this mission.
787
+ */
788
+ __publicField$2(this, "contactKeys");
789
+ /**
790
+ * The level range this mission is available for.
791
+ */
792
+ __publicField$2(this, "levelRange");
793
+ /**
794
+ * Freeform notes or tips about the mission.
795
+ */
796
+ __publicField$2(this, "notes");
797
+ /**
798
+ * List of external links. Wiki, forums, etc.
799
+ */
800
+ __publicField$2(this, "links");
801
+ /**
802
+ * If the mission is available in Ouroboros as a Flashback.
803
+ */
804
+ __publicField$2(this, "flashback");
805
+ this.key = new Key(data.key).value;
806
+ this.name = data.name;
807
+ this.type = data.type;
808
+ this.morality = new MoralityList(coalesceToArray(data.morality));
809
+ this.contactKeys = coalesceToArray(data.contactKeys);
810
+ this.levelRange = data.levelRange;
811
+ this.notes = data.notes;
812
+ this.links = data.links ?? [];
813
+ this.flashback = createFlashback(data);
814
+ }
815
+ }
816
+ function createFlashback(data) {
817
+ if (!data.flashback) return void 0;
818
+ return {
819
+ id: data.flashback.id,
820
+ levelRange: data.flashback.levelRange ?? data.levelRange,
821
+ name: data.flashback.name ?? data.name,
822
+ morality: new MoralityList(coalesceToArray(data.flashback.morality ?? data.morality)),
823
+ notes: data.flashback.notes
824
+ };
825
+ }
826
+
827
+ var __defProp$1 = Object.defineProperty;
591
828
  var __typeError = (msg) => {
592
829
  throw TypeError(msg);
593
830
  };
594
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
595
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
831
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
832
+ var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
596
833
  var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
597
834
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
598
835
  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);
599
836
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
600
- var _archetypeIndex, _zoneIndex, _contactIndex, _badgeIndex;
837
+ var _archetypeIndex, _zoneIndex, _contactIndex, _missionIndex, _badgeIndex;
601
838
  class CohContentDatabase {
602
839
  /**
603
840
  * Initialize the database with a content bundle.
@@ -607,33 +844,38 @@ class CohContentDatabase {
607
844
  __privateAdd(this, _archetypeIndex, {});
608
845
  __privateAdd(this, _zoneIndex, {});
609
846
  __privateAdd(this, _contactIndex, {});
847
+ __privateAdd(this, _missionIndex, {});
610
848
  __privateAdd(this, _badgeIndex);
611
849
  /**
612
850
  * Metadata about the content bundle.
613
851
  */
614
- __publicField(this, "metadata");
852
+ __publicField$1(this, "metadata");
615
853
  /**
616
854
  * List of the game server names.
617
855
  *
618
856
  * Torchbearer, Excelsior, etc.
619
857
  */
620
- __publicField(this, "servers");
858
+ __publicField$1(this, "servers");
621
859
  /**
622
860
  * List of archetypes.
623
861
  */
624
- __publicField(this, "archetypes");
862
+ __publicField$1(this, "archetypes");
625
863
  /**
626
864
  * List of game zones.
627
865
  */
628
- __publicField(this, "zones");
866
+ __publicField$1(this, "zones");
629
867
  /**
630
868
  * List of contacts.
631
869
  */
632
- __publicField(this, "contacts");
870
+ __publicField$1(this, "contacts");
871
+ /**
872
+ * List of missions.
873
+ */
874
+ __publicField$1(this, "missions");
633
875
  /**
634
876
  * List of badges.
635
877
  */
636
- __publicField(this, "badges");
878
+ __publicField$1(this, "badges");
637
879
  this.metadata = new BundleMetadata(bundle);
638
880
  this.servers = bundle.servers ?? [];
639
881
  this.archetypes = bundle.archetypes?.map((data) => {
@@ -654,36 +896,34 @@ class CohContentDatabase {
654
896
  __privateGet(this, _contactIndex)[contact.key] = contact;
655
897
  return contact;
656
898
  }) ?? [];
899
+ this.missions = bundle.missions?.map((data) => {
900
+ if (__privateGet(this, _missionIndex)[data.key] !== void 0) throw new Error(`Duplicate mission key '${data.key}'`);
901
+ const mission = new Mission(data);
902
+ __privateGet(this, _missionIndex)[mission.key] = mission;
903
+ return mission;
904
+ }) ?? [];
657
905
  this.badges = bundle.badges?.map((data) => new Badge(data)) ?? [];
658
- __privateSet(this, _badgeIndex, new BadgeIndex(this.badges, this.zones));
906
+ __privateSet(this, _badgeIndex, new BadgeIndex(this.badges));
659
907
  }
660
908
  getArchetype(key) {
661
- const result = __privateGet(this, _archetypeIndex)[key];
662
- if (result === void 0) throw new Error(`Unknown archetype key '${key}'`);
663
- return result;
909
+ if (!key) return void 0;
910
+ return __privateGet(this, _archetypeIndex)[key];
664
911
  }
665
912
  getZone(key) {
666
- const result = __privateGet(this, _zoneIndex)[key];
667
- if (result === void 0) throw new Error(`Unknown zone key '${key}'`);
668
- return result;
913
+ if (!key) return void 0;
914
+ return __privateGet(this, _zoneIndex)[key];
669
915
  }
670
916
  getContact(key) {
671
- const result = __privateGet(this, _contactIndex)[key];
672
- if (result === void 0) throw new Error(`Unknown contact key '${key}'`);
673
- return result;
674
- }
675
- zoneExists(key) {
676
- return !!__privateGet(this, _zoneIndex)[key];
917
+ if (!key) return void 0;
918
+ return __privateGet(this, _contactIndex)[key];
677
919
  }
678
- contactExists(key) {
679
- return !!__privateGet(this, _contactIndex)[key];
920
+ getMission(key) {
921
+ if (!key) return void 0;
922
+ return __privateGet(this, _missionIndex)[key];
680
923
  }
681
924
  getBadge(key) {
682
925
  return __privateGet(this, _badgeIndex).getBadge(key);
683
926
  }
684
- badgeExists(key) {
685
- return __privateGet(this, _badgeIndex).badgeExists(key);
686
- }
687
927
  /**
688
928
  * Search, sort and filter the badge list.
689
929
  * This is a fairly brute-forced approach and will not be as performant as loading the badge data into a traditional
@@ -697,23 +937,53 @@ class CohContentDatabase {
697
937
  _archetypeIndex = new WeakMap();
698
938
  _zoneIndex = new WeakMap();
699
939
  _contactIndex = new WeakMap();
940
+ _missionIndex = new WeakMap();
700
941
  _badgeIndex = new WeakMap();
701
942
 
943
+ var __defProp = Object.defineProperty;
944
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
945
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
946
+ class Location {
947
+ constructor(data) {
948
+ /**
949
+ * Key of the {@link Zone} that the location references.
950
+ */
951
+ __publicField(this, "zoneKey");
952
+ /**
953
+ * In-game `/loc` coordinates of the location.
954
+ */
955
+ __publicField(this, "coords");
956
+ /**
957
+ * The type of icon to use if the location appears on a map. (Typically the Vidiot map icon).
958
+ */
959
+ __publicField(this, "icon");
960
+ /**
961
+ * The text that should appear in the location icon. (Typically a number or symbol from the Vidiot map).
962
+ */
963
+ __publicField(this, "iconText");
964
+ this.zoneKey = data.zoneKey;
965
+ this.coords = data.coords;
966
+ this.icon = data.icon;
967
+ this.iconText = data.iconText;
968
+ }
969
+ }
970
+
702
971
  const CHANGELOG = [
703
972
  {
704
973
  version: "2.0.0",
705
974
  date: /* @__PURE__ */ new Date("2025-03-12"),
706
975
  description: `* Replaced redundant interfaces with their concrete equivalents.
707
976
  * Server groups are now referred to as 'forks'.
708
- * Replaced enums with union types.
709
- * \`IServerGroupData\` is now \`ContentBundle\` and each database instance is now designed to accept only a single server group.
977
+ * Replaced enums with union types and changed values to \`kebab-case\`.
978
+ * \`IServerGroupData\` is now \`ContentBundle\` and each database instance is now designed to accept only a single bundle.
710
979
  * \`GameMap\` is now \`Zone\`.
711
980
  * Removed the \`serverGroup\` property from entities to simplify the object tree given that only a single context can exist per db now.
712
981
  * Added a simple indexing and search function for badge names, text and acquisition info.
713
982
  * Zone and badge references now follow a standard Markdown link format with a \`badge://\` or \`map://\` protocol.
714
- * Badge partials are now known as badge requirements and support both AND and OR groups of requirements.
983
+ * Badge partials are now known as badge requirements.
715
984
  * Removed the \`VidiotMap\` API as it was never used or fleshed out properly.
716
- * Added support for story arcs to badge requirements including a link to the contact.
985
+ * Added formal support for Missions and Contacts in badge requirements.
986
+ * Move exploration badge locations into badge requirement list.
717
987
  * Standardized pluralization of some field names (name, icon).
718
988
  * Combined \`settitle\` ids into a single tuple field.
719
989
  * Change from GNU to The Unlicense.
@@ -726,30 +996,5 @@ const CHANGELOG = [
726
996
  }
727
997
  ];
728
998
 
729
- function badgeUri(target) {
730
- const key = typeof target === "string" ? target : target.key;
731
- return `badge://${key}`;
732
- }
733
- function badgeLink(target) {
734
- const key = typeof target === "string" ? target : target.key;
735
- return `[${key}](${badgeUri(target)})`;
736
- }
737
- function contactUri(target) {
738
- const key = typeof target === "string" ? target : target.key;
739
- return `contact://${key}`;
740
- }
741
- function contactLink(target) {
742
- const key = typeof target === "string" ? target : target.key;
743
- return `[${key}](${contactUri(target)})`;
744
- }
745
- function zoneUri(target) {
746
- const key = typeof target === "string" ? target : target.key;
747
- return `zone://${key}`;
748
- }
749
- function zoneLink(target) {
750
- const key = typeof target === "string" ? target : target.key;
751
- return `[${key}](${zoneUri(target)})`;
752
- }
753
-
754
- export { ALIGNMENT, Alignments, Alternates, Archetype, BADGE_REQUIREMENT_TYPE, BADGE_TYPE, Badge, BadgeIndex, BadgeRequirement, BundleMetadata, CHANGELOG, CohContentDatabase, Contact, ENHANCEMENT_CATEGORY, Key, PLAQUE_TYPE, SEX, Zone, badgeLink, badgeUri, contactLink, contactUri, zoneLink, zoneUri };
999
+ export { ALIGNMENT, AlignmentList, Alternates, Archetype, BADGE_REQUIREMENT_TYPE, BADGE_TYPE, Badge, BadgeIndex, BadgeRequirement, BundleMetadata, CHANGELOG, CohContentDatabase, Contact, ENHANCEMENT_CATEGORY, Key, Location, MISSION_TYPE, MORALITY, Mission, MoralityList, SEX, Zone, badgeLink, badgeUri, coalesceToArray, compareAlignment, compareByDefaultName, compareByZoneKey, compareSex, contactLink, contactUri, missionLink, missionUri, zoneLink, zoneUri };
755
1000
  //# sourceMappingURL=coh-content-db.mjs.map