coh-content-db 2.0.0-rc.1 → 2.0.0-rc.11

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 (100) 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 +2 -2
  5. package/CHANGELOG.md +43 -0
  6. package/README.md +52 -24
  7. package/dist/coh-content-db.d.ts +678 -279
  8. package/dist/coh-content-db.js +828 -371
  9. package/dist/coh-content-db.js.map +1 -1
  10. package/dist/coh-content-db.mjs +803 -362
  11. package/dist/coh-content-db.mjs.map +1 -1
  12. package/eslint.config.mjs +1 -0
  13. package/package.json +1 -1
  14. package/src/main/api/alignment.ts +18 -2
  15. package/src/main/api/alternate-data.ts +2 -2
  16. package/src/main/api/badge-data.ts +20 -48
  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 +37 -0
  22. package/src/main/api/contact-data.ts +48 -0
  23. package/src/main/api/enhancement-category.ts +26 -26
  24. package/src/main/api/location-data.ts +28 -0
  25. package/src/main/api/markdown-string.ts +4 -0
  26. package/src/main/api/mission-data.ts +83 -0
  27. package/src/main/api/mission-type.ts +2 -0
  28. package/src/main/api/morality.ts +31 -0
  29. package/src/main/api/sex.ts +8 -1
  30. package/src/main/api/zone-data.ts +20 -0
  31. package/src/main/db/abstract-index.ts +37 -0
  32. package/src/main/db/alignment-list.ts +54 -0
  33. package/src/main/db/alternates.ts +28 -42
  34. package/src/main/db/badge-index.ts +60 -0
  35. package/src/main/db/badge-requirement.ts +81 -0
  36. package/src/main/db/badge-search-options.ts +47 -0
  37. package/src/main/db/badge.ts +76 -71
  38. package/src/main/db/bundle-header.ts +44 -0
  39. package/src/main/db/coh-content-database.ts +123 -14
  40. package/src/main/db/contact.ts +62 -0
  41. package/src/main/db/location.ts +30 -0
  42. package/src/main/db/mission.ts +107 -0
  43. package/src/main/db/morality-list.ts +99 -0
  44. package/src/main/db/paged.ts +7 -0
  45. package/src/main/db/zone.ts +28 -0
  46. package/src/main/index.ts +23 -15
  47. package/src/main/util.ts +108 -7
  48. package/src/test/api/alignment.test.ts +38 -4
  49. package/src/test/api/badge-data.fixture.ts +1 -15
  50. package/src/test/api/badge-data.test.ts +4 -4
  51. package/src/test/api/badge-requirement-data.fixture.ts +7 -0
  52. package/src/test/api/badge-requirement-type.test.ts +31 -0
  53. package/src/test/api/badge-type.test.ts +5 -5
  54. package/src/test/api/bundle-data.fixture.ts +6 -0
  55. package/src/test/api/bundle-header-data.fixture.ts +6 -0
  56. package/src/test/api/contact-data.fixture.ts +7 -0
  57. package/src/test/api/enhancement-category.test.ts +5 -5
  58. package/src/test/api/mission-data.fixture.ts +12 -0
  59. package/src/test/api/sex.test.ts +33 -1
  60. package/src/test/api/zone-data.fixture.ts +8 -0
  61. package/src/test/db/abstract-index.test.ts +55 -0
  62. package/src/test/db/alignment-list.test.ts +200 -0
  63. package/src/test/db/alternates.test.ts +82 -117
  64. package/src/test/db/badge-index.test.ts +547 -0
  65. package/src/test/db/badge-requirement.test.ts +145 -0
  66. package/src/test/db/badge.test.ts +322 -14
  67. package/src/test/db/bundle-header.test.ts +76 -0
  68. package/src/test/db/coh-content-database.test.ts +264 -24
  69. package/src/test/db/contact.test.ts +97 -0
  70. package/src/test/db/location.test.ts +51 -0
  71. package/src/test/db/mission.test.ts +171 -0
  72. package/src/test/db/morality-list.test.ts +457 -0
  73. package/src/test/db/zone.test.ts +36 -0
  74. package/src/test/integration.test.ts +16 -0
  75. package/src/test/util.test.ts +144 -18
  76. package/src/main/api/badge-partial-data.ts +0 -65
  77. package/src/main/api/badge-partial-type.ts +0 -8
  78. package/src/main/api/change.ts +0 -14
  79. package/src/main/api/game-map-data.ts +0 -26
  80. package/src/main/api/plaque-type.ts +0 -6
  81. package/src/main/api/server-group-data.ts +0 -65
  82. package/src/main/api/vidiot-map-data.ts +0 -18
  83. package/src/main/api/vidiot-map-point-of-interest-data.ts +0 -30
  84. package/src/main/changelog.ts +0 -20
  85. package/src/main/db/badge-partial.ts +0 -35
  86. package/src/main/db/game-map.ts +0 -33
  87. package/src/main/db/server-group.ts +0 -112
  88. package/src/main/db/vidiot-map-point-of-interest.ts +0 -40
  89. package/src/main/db/vidiot-map.ts +0 -25
  90. package/src/test/api/badge-partial-data.fixture.ts +0 -17
  91. package/src/test/api/badge-partial-type.test.ts +0 -31
  92. package/src/test/api/game-map-data.fixture.ts +0 -10
  93. package/src/test/api/plaque-type.test.ts +0 -31
  94. package/src/test/api/server-group-data.fixture.ts +0 -23
  95. package/src/test/api/server-group-data.test.ts +0 -15
  96. package/src/test/api/vidiot-map-point-of-interest.fixture.ts +0 -10
  97. package/src/test/api/vidiot-map.fixture.ts +0 -9
  98. package/src/test/changelog.test.ts +0 -36
  99. package/src/test/db/server-group.test.ts +0 -124
  100. package/src/test/index.test.ts +0 -10
@@ -1,74 +1,230 @@
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"
61
- ];
87
+ const MISSION_TYPE = ["story-arc", "mission", "task-force", "strike-force", "trial", "personal-story"];
88
+
89
+ const MORALITY = ["hero", "vigilante", "villain", "rogue", "resistance", "loyalist"];
62
90
 
63
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
+ }
98
+
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$5 = (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$5(this, _items$1).add("hero");
126
+ if (this.villain) __privateGet$5(this, _items$1).add("villain");
127
+ if (this.praetorian) __privateGet$5(this, _items$1).add("praetorian");
128
+ }
129
+ get items() {
130
+ return [...__privateGet$5(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
+ }
153
+ }
154
+ }
155
+ _items$1 = new WeakMap();
156
+
157
+ var __typeError$5 = (msg) => {
158
+ throw TypeError(msg);
159
+ };
160
+ var __accessCheck$5 = (obj, member, msg) => member.has(obj) || __typeError$5("Cannot " + msg);
161
+ var __privateGet$4 = (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;
166
+ class Alternates {
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$4(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
+ }
180
+ }
181
+ getValue(alignment, sex) {
182
+ for (let index = __privateGet$4(this, _sortedValues).length; index--; ) {
183
+ const entry = __privateGet$4(this, _sortedValues)[index];
184
+ if ((entry.alignment === void 0 || entry.alignment === alignment) && (entry.sex === void 0 || entry.sex === sex)) return entry.value;
185
+ }
186
+ return this.default?.value;
187
+ }
188
+ /**
189
+ * Get the default value for this list of alternates, the value with the highest priority and lowest specificity.
190
+ */
191
+ get default() {
192
+ return __privateGet$4(this, _sortedValues)[0];
193
+ }
194
+ /**
195
+ * Get the list of alternates sorted in canonical order (alignment then sex, low to high specificity).
196
+ */
197
+ get canonical() {
198
+ return __privateGet$4(this, _sortedValues);
199
+ }
200
+ /**
201
+ * Create a joined string from the alternate values in canonical order.
202
+ * @param separator Separator to use. Default is ' / '
203
+ */
204
+ toString(separator) {
205
+ return this.canonical.map((x) => x.value).join(separator);
206
+ }
207
+ }
208
+ _sortedValues = new WeakMap();
209
+ _Alternates_instances = new WeakSet();
210
+ compareAlternates_fn = function(a, b) {
211
+ const aSpecificity = (a.alignment ? 2 : 0) + (a.sex ? 1 : 0);
212
+ const bSpecificity = (b.alignment ? 2 : 0) + (b.sex ? 1 : 0);
213
+ if (aSpecificity !== bSpecificity) return aSpecificity - bSpecificity;
214
+ const alignmentComparison = compareAlignment(a.alignment, b.alignment);
215
+ if (alignmentComparison !== 0) return alignmentComparison;
216
+ const sexComparison = compareSex(a.sex, b.sex);
217
+ if (sexComparison !== 0) return sexComparison;
218
+ return String(a.value).localeCompare(String(b.value));
219
+ };
64
220
 
65
221
  var __typeError$4 = (msg) => {
66
222
  throw TypeError(msg);
67
223
  };
68
224
  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));
225
+ var __privateGet$3 = (obj, member, getter) => (__accessCheck$4(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
70
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);
71
- var __privateSet$1 = (obj, member, value, setter) => (__accessCheck$4(obj, member, "write to private field"), member.set(obj, value), value);
227
+ var __privateSet$3 = (obj, member, value, setter) => (__accessCheck$4(obj, member, "write to private field"), member.set(obj, value), value);
72
228
  var __privateMethod$1 = (obj, member, method) => (__accessCheck$4(obj, member, "access private method"), method);
73
229
  var _value, _Key_instances, validateKey_fn;
74
230
  const INVALID_KEY_PATTERN = /[^a-z0-9-]/;
@@ -77,10 +233,10 @@ class Key {
77
233
  __privateAdd$4(this, _Key_instances);
78
234
  __privateAdd$4(this, _value);
79
235
  __privateMethod$1(this, _Key_instances, validateKey_fn).call(this, value);
80
- __privateSet$1(this, _value, value);
236
+ __privateSet$3(this, _value, value);
81
237
  }
82
238
  get value() {
83
- return __privateGet$4(this, _value);
239
+ return __privateGet$3(this, _value);
84
240
  }
85
241
  }
86
242
  _value = new WeakMap();
@@ -89,429 +245,611 @@ validateKey_fn = function(key) {
89
245
  if (INVALID_KEY_PATTERN.test(key)) throw new Error(`Invalid key: [${key}]; Keys can only contain lowercase characters, numbers and dashes.`);
90
246
  };
91
247
 
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);
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);
95
251
  class Archetype {
96
252
  constructor(data) {
97
- __publicField$6(this, "key");
98
- __publicField$6(this, "name");
99
- __publicField$6(this, "description");
253
+ __publicField$9(this, "key");
254
+ __publicField$9(this, "name");
255
+ __publicField$9(this, "description");
100
256
  this.key = new Key(data.key).value;
101
257
  this.name = data.name;
102
258
  this.description = data.description;
103
259
  }
104
260
  }
105
261
 
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 {
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);
302
+ class BadgeRequirement {
110
303
  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");
304
+ /**
305
+ * Unique key used to reference this badge requirement.
306
+ *
307
+ * Keys must be unique and can only contain lowercase letters, numbers and hyphens (`-`).
308
+ */
309
+ __publicField$8(this, "key");
310
+ /**
311
+ * The requirement type.
312
+ */
313
+ __publicField$8(this, "type");
314
+ /**
315
+ * If the requirement involves a location, where it is.
316
+ */
317
+ __publicField$8(this, "location");
318
+ /**
319
+ * If the requirement involves a badge, the badge key.
320
+ */
321
+ __publicField$8(this, "badgeKey");
322
+ /**
323
+ * If the requirement involves a mission, the mission key.
324
+ */
325
+ __publicField$8(this, "missionKey");
326
+ /**
327
+ * If the requirement involves a monument, the text that is displayed thereon.
328
+ */
329
+ __publicField$8(this, "monumentText");
330
+ /**
331
+ * If the requirement involves crafting an invention, the Level of the invention required.
332
+ */
333
+ __publicField$8(this, "inventionLevel");
334
+ /**
335
+ * If the requirement involves crafting an invention, the types of enhancements that will qualify.
336
+ */
337
+ __publicField$8(this, "inventionTypes");
338
+ /**
339
+ * Number of times the task needs to be repeated.
340
+ */
341
+ __publicField$8(this, "count");
342
+ /**
343
+ * Additional information about the requirement.
344
+ */
345
+ __publicField$8(this, "notes");
346
+ /**
347
+ * List of external links. Wiki, forums, etc.
348
+ */
349
+ __publicField$8(this, "links");
123
350
  this.key = new Key(data.key).value;
124
351
  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;
352
+ this.location = coalesceToArray(data.location);
130
353
  this.badgeKey = data.badgeKey;
354
+ this.missionKey = data.missionKey;
355
+ this.monumentText = data.monumentText;
131
356
  this.inventionLevel = data.inventionLevel;
132
357
  this.inventionTypes = data.inventionTypes;
133
- this.inventionCount = data.inventionCount;
358
+ this.count = data.count;
134
359
  this.notes = data.notes;
360
+ this.links = data.links ?? [];
135
361
  }
136
362
  }
137
363
 
364
+ var __defProp$7 = Object.defineProperty;
138
365
  var __typeError$3 = (msg) => {
139
366
  throw TypeError(msg);
140
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);
141
370
  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));
371
+ var __privateGet$2 = (obj, member, getter) => (__accessCheck$3(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
143
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);
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));
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$2(this, _items).add("hero");
407
+ if (this.vigilante) __privateGet$2(this, _items).add("vigilante");
408
+ if (this.villain) __privateGet$2(this, _items).add("villain");
409
+ if (this.rogue) __privateGet$2(this, _items).add("rogue");
410
+ if (this.resistance) __privateGet$2(this, _items).add("resistance");
411
+ if (this.loyalist) __privateGet$2(this, _items).add("loyalist");
155
412
  }
156
- getValue(alignment, sex) {
157
- for (let index = __privateGet$3(this, _sortedValues).length; index--; ) {
158
- 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;
413
+ get items() {
414
+ return [...__privateGet$2(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
+ }
160
460
  }
161
- return void 0;
162
461
  }
462
+ }
463
+ _items = new WeakMap();
464
+
465
+ var __defProp$6 = Object.defineProperty;
466
+ var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
467
+ var __publicField$6 = (obj, key, value) => __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
468
+ class AbstractIndex {
163
469
  /**
164
- * Get the default value for this list of alternates, the value with the highest priority and lowest specificity.
470
+ * Create a new index.
471
+ * @param keyField The field of the values that will act as the key.
472
+ * @param values Values to index.
165
473
  */
166
- get default() {
167
- return __privateGet$3(this, _sortedValues)[0]?.value;
474
+ constructor(keyField, values) {
475
+ __publicField$6(this, "_values", []);
476
+ __publicField$6(this, "_hashTable", {});
477
+ this._values = values ?? [];
478
+ this._hashTable = {};
479
+ for (const value of this.values) {
480
+ const key = value[keyField];
481
+ if (this._hashTable[key] !== void 0) throw new Error(`Duplicate key [${key}]`);
482
+ this._hashTable[key] = value;
483
+ }
168
484
  }
169
485
  /**
170
- * Get the list of alternates sorted in canonical order (alignment then sex, low to high specificity).
486
+ * Return all indexed values
171
487
  */
172
- get canonical() {
173
- return __privateGet$3(this, _sortedValues);
488
+ get values() {
489
+ return this._values;
490
+ }
491
+ /**
492
+ * Get a value from the index
493
+ * @param key Key string
494
+ */
495
+ get(key) {
496
+ if (!key) return void 0;
497
+ return this._hashTable[key];
174
498
  }
175
499
  }
176
- _sortedValues = new WeakMap();
177
- _Alternates_instances = new WeakSet();
178
- compareAlternates_fn = function(a, b) {
179
- const aSpecificity = (a.alignment ? 2 : 0) + (a.sex ? 1 : 0);
180
- const bSpecificity = (b.alignment ? 2 : 0) + (b.sex ? 1 : 0);
181
- if (aSpecificity !== bSpecificity) return aSpecificity - bSpecificity;
182
- const alignmentComparison = __privateMethod(this, _Alternates_instances, compareAlignment_fn).call(this, a.alignment, b.alignment);
183
- if (alignmentComparison !== 0) return alignmentComparison;
184
- const sexComparison = __privateMethod(this, _Alternates_instances, compareSex_fn).call(this, a.sex, b.sex);
185
- if (sexComparison !== 0) return sexComparison;
186
- return String(a.value).localeCompare(String(b.value));
187
- };
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;
205
- };
206
500
 
207
- var __defProp$4 = Object.defineProperty;
501
+ var __defProp$5 = Object.defineProperty;
208
502
  var __typeError$2 = (msg) => {
209
503
  throw TypeError(msg);
210
504
  };
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);
505
+ var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
506
+ var __publicField$5 = (obj, key, value) => __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
213
507
  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));
508
+ var __privateGet$1 = (obj, member, getter) => (__accessCheck$2(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
215
509
  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;
510
+ var __privateSet$1 = (obj, member, value, setter) => (__accessCheck$2(obj, member, "write to private field"), member.set(obj, value), value);
511
+ var _requirementsIndex, _zoneKeys;
217
512
  class Badge {
218
- constructor(data) {
219
- __privateAdd$2(this, _partialsIndex, {});
513
+ constructor(badgeData) {
514
+ __privateAdd$2(this, _requirementsIndex);
515
+ __privateAdd$2(this, _zoneKeys, /* @__PURE__ */ new Set());
220
516
  /**
221
517
  * The database key for this badge.
222
518
  */
223
- __publicField$4(this, "key");
519
+ __publicField$5(this, "key");
224
520
  /**
225
521
  * The type of badge.
226
522
  */
227
- __publicField$4(this, "type");
523
+ __publicField$5(this, "type");
228
524
  /**
229
525
  * The name of this badge.
230
526
  *
231
527
  * May vary by character sex or alignment.
232
528
  */
233
- __publicField$4(this, "name");
529
+ __publicField$5(this, "name");
234
530
  /**
235
- * The character alignments that this badge is available to.
531
+ * The character moralities that this badge is available to.
236
532
  */
237
- __publicField$4(this, "alignment");
533
+ __publicField$5(this, "morality");
238
534
  /**
239
535
  * The badge text as it appears in-game. May vary by character sex or alignment.
240
536
  */
241
- __publicField$4(this, "badgeText");
537
+ __publicField$5(this, "badgeText");
242
538
  /**
243
- * Description of how to acquire the badge.
244
- *
245
- * Supports {@link https://www.markdownguide.org/|Markdown} format.
539
+ * Short description of how to acquire the badge. Detailed instructions will be in the notes field.
246
540
  */
247
- __publicField$4(this, "acquisition");
541
+ __publicField$5(this, "acquisition");
248
542
  /**
249
543
  * Absolute URL to this badge's icon.
250
544
  *
251
545
  * May vary by character sex or alignment.
252
546
  */
253
- __publicField$4(this, "icon");
547
+ __publicField$5(this, "icon");
254
548
  /**
255
549
  * Freeform notes or tips about the badge.
256
- *
257
- * Supports {@link https://www.markdownguide.org/|Markdown} format.
258
550
  */
259
- __publicField$4(this, "notes");
551
+ __publicField$5(this, "notes");
260
552
  /**
261
- * List of external links for this Badge. Wiki, forums, etc.
553
+ * List of external links. Wiki, forums, etc.
262
554
  */
263
- __publicField$4(this, "links");
555
+ __publicField$5(this, "links");
264
556
  /**
265
- * For exploration badges, the key of the {@link GameMap} that this badge is found on.
557
+ * The id used with the in-game `/settitle` command to apply the badge.
558
+ * The first value is the id for primal characters and the (optional) second number is the id for praetorian characters.
266
559
  */
267
- __publicField$4(this, "mapKey");
560
+ __publicField$5(this, "setTitleId");
268
561
  /**
269
- * For exploration badges, the `/loc` coordinates of the badge on the in-game map.
562
+ * A description of the effect the badge will have, such as a buff or granting a temporary power.
270
563
  */
271
- __publicField$4(this, "loc");
564
+ __publicField$5(this, "effect");
272
565
  /**
273
- * For badges that appear on a Vidiot Map, the number or letter the badge appears as.
566
+ * 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
567
  */
275
- __publicField$4(this, "vidiotMapKey");
568
+ __publicField$5(this, "ignoreInTotals");
569
+ this.key = new Key(badgeData.key).value;
570
+ this.type = badgeData.type;
571
+ this.name = new Alternates(badgeData.name);
572
+ this.morality = new MoralityList(coalesceToArray(badgeData.morality));
573
+ this.badgeText = new Alternates(badgeData.badgeText ?? []);
574
+ this.acquisition = badgeData.acquisition;
575
+ this.icon = new Alternates(badgeData.icon ?? []);
576
+ this.notes = badgeData.notes;
577
+ this.links = badgeData.links ?? [];
578
+ this.effect = badgeData.effect;
579
+ this.setTitleId = badgeData.setTitleId;
580
+ this.ignoreInTotals = badgeData.ignoreInTotals ?? false;
581
+ __privateSet$1(this, _requirementsIndex, new AbstractIndex("key", badgeData.requirements?.map((x) => new BadgeRequirement(x))));
582
+ for (const requirement of __privateGet$1(this, _requirementsIndex).values) {
583
+ if (requirement.location) for (const location of requirement.location) {
584
+ if (location.zoneKey) __privateGet$1(this, _zoneKeys).add(location.zoneKey);
585
+ }
586
+ }
587
+ }
588
+ /**
589
+ * Represents the requirements for badges with multiple fulfillment steps, such as visiting monuments for history badges, completing missions, or collecting other badges.
590
+ */
591
+ get requirements() {
592
+ return __privateGet$1(this, _requirementsIndex).values;
593
+ }
594
+ getRequirement(key) {
595
+ return __privateGet$1(this, _requirementsIndex).get(key);
596
+ }
597
+ /**
598
+ * Return a list of all the zone keys referenced by this badge.
599
+ */
600
+ get zoneKeys() {
601
+ return [...__privateGet$1(this, _zoneKeys)];
602
+ }
603
+ /**
604
+ * The zone key if this badge relates to a single zone.
605
+ */
606
+ get zoneKey() {
607
+ return __privateGet$1(this, _zoneKeys).size === 1 ? __privateGet$1(this, _zoneKeys).values().next().value : void 0;
608
+ }
609
+ }
610
+ _requirementsIndex = new WeakMap();
611
+ _zoneKeys = new WeakMap();
612
+ function compareByDefaultName(a, b) {
613
+ const aName = a?.name.default?.value;
614
+ const bName = b?.name.default?.value;
615
+ if (!aName && !bName) return 0;
616
+ if (!aName) return 1;
617
+ if (!bName) return -1;
618
+ return aName.localeCompare(bName);
619
+ }
620
+ function compareByZoneKey(a, b) {
621
+ const aZone = a?.zoneKey;
622
+ const bZone = b?.zoneKey;
623
+ if (!aZone && !bZone) return 0;
624
+ if (!aZone) return 1;
625
+ if (!bZone) return -1;
626
+ return aZone.localeCompare(bZone);
627
+ }
628
+
629
+ var __typeError$1 = (msg) => {
630
+ throw TypeError(msg);
631
+ };
632
+ var __accessCheck$1 = (obj, member, msg) => member.has(obj) || __typeError$1("Cannot " + msg);
633
+ 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);
634
+ var __privateMethod = (obj, member, method) => (__accessCheck$1(obj, member, "access private method"), method);
635
+ var _BadgeIndex_instances, satisfiesQueryPredicate_fn, satisfiesFilterPredicate_fn, sort_fn;
636
+ class BadgeIndex extends AbstractIndex {
637
+ constructor(values) {
638
+ super("key", values);
639
+ __privateAdd$1(this, _BadgeIndex_instances);
640
+ }
641
+ search(options) {
642
+ const filtered = options?.query || options?.filter ? this._values.filter((badge) => __privateMethod(this, _BadgeIndex_instances, satisfiesQueryPredicate_fn).call(this, badge, options?.query) && __privateMethod(this, _BadgeIndex_instances, satisfiesFilterPredicate_fn).call(this, badge, options?.filter)) : this._values;
643
+ const totalPages = options?.pageSize ? Math.ceil(filtered.length / options?.pageSize) : 1;
644
+ const page = Math.max(1, Math.min(totalPages, options?.page ?? 1));
645
+ const paged = options?.pageSize ? filtered.slice((page - 1) * options.pageSize, page * options?.pageSize) : filtered;
646
+ const sorted = __privateMethod(this, _BadgeIndex_instances, sort_fn).call(this, paged, options?.sort);
647
+ return {
648
+ items: sorted,
649
+ page,
650
+ pageSize: options?.pageSize,
651
+ totalItems: filtered.length,
652
+ totalPages
653
+ };
654
+ }
655
+ }
656
+ _BadgeIndex_instances = new WeakSet();
657
+ satisfiesQueryPredicate_fn = function(badge, query) {
658
+ const queryString = query?.str?.toLowerCase() ?? "";
659
+ const fields = query?.fields ? new Set(query?.fields) : /* @__PURE__ */ new Set(["name"]);
660
+ if (fields.size === 0) return true;
661
+ 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?.some((x) => x?.toString().includes(queryString)));
662
+ };
663
+ satisfiesFilterPredicate_fn = function(badge, filter) {
664
+ return (!filter?.type || badge.type === filter.type) && (!filter?.zoneKey || badge.zoneKey === filter.zoneKey) && (!filter?.morality || badge.morality.has(filter.morality));
665
+ };
666
+ sort_fn = function(badges, sort) {
667
+ if (!sort) return badges;
668
+ const ascending = sort.dir !== "desc";
669
+ if (sort.by === "badge-name") return badges.sort((a, b) => ascending ? compareByDefaultName(a, b) : compareByDefaultName(b, a));
670
+ if (sort.by === "zone-key") return badges.sort((a, b) => ascending ? compareByZoneKey(a, b) : compareByZoneKey(b, a));
671
+ return sort.dir === "desc" ? badges.reverse() : badges;
672
+ };
673
+
674
+ var __defProp$4 = Object.defineProperty;
675
+ var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
676
+ var __publicField$4 = (obj, key, value) => __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
677
+ class BundleHeader {
678
+ constructor(data) {
276
679
  /**
277
- * ID used with the in-game `/settitle` command to apply the badge.
680
+ * Name of the content bundle.
278
681
  */
279
- __publicField$4(this, "setTitle");
682
+ __publicField$4(this, "name");
280
683
  /**
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.
684
+ * Description of the fork.
284
685
  */
285
- __publicField$4(this, "effect");
686
+ __publicField$4(this, "description");
286
687
  /**
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.
688
+ * Url for the repository where the bundle is maintained.
288
689
  */
289
- __publicField$4(this, "partials");
690
+ __publicField$4(this, "repositoryUrl");
290
691
  /**
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.
692
+ * Url for the location of the changelog.
292
693
  */
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;
694
+ __publicField$4(this, "changelogUrl");
695
+ /**
696
+ * List of external links. Wiki, forums, etc.
697
+ */
698
+ __publicField$4(this, "links");
699
+ /**
700
+ * The current version of the data package.
701
+ */
702
+ __publicField$4(this, "version");
703
+ this.name = data?.name;
704
+ this.description = data?.description;
705
+ this.repositoryUrl = data?.repositoryUrl;
706
+ this.changelogUrl = data?.changelogUrl;
707
+ this.links = data?.links ?? [];
708
+ this.version = data?.version;
320
709
  }
321
710
  }
322
- _partialsIndex = new WeakMap();
323
711
 
324
712
  var __defProp$3 = Object.defineProperty;
325
713
  var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
326
714
  var __publicField$3 = (obj, key, value) => __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
327
- class VidiotMapPointOfInterest {
715
+ class Zone {
328
716
  constructor(data) {
329
717
  /**
330
- * The pixel-space position of the PoI on the map graphic.
718
+ * Unique key used to reference this zone.
331
719
  *
332
- * Screen-space, pixels from top-left `[0, 0]`.
720
+ * Keys must be unique and can only contain lowercase letters, numbers and hyphens (`-`).
333
721
  */
334
- __publicField$3(this, "pos");
722
+ __publicField$3(this, "key");
335
723
  /**
336
- * Freeform notes about the PoI.
337
- *
338
- * Supports {@link https://www.markdownguide.org/|Markdown} format.
339
- */
340
- __publicField$3(this, "notes");
341
- /**
342
- * If the POI is a zone transfer, the map it transfers to.
343
- */
344
- __publicField$3(this, "mapKey");
345
- /**
346
- * If the POI is a badge, the badge.
724
+ * The name of the zone as it appears in-game.
347
725
  */
348
- __publicField$3(this, "badgeKey");
726
+ __publicField$3(this, "name");
349
727
  /**
350
- * If the POI is a partial for a badge, the partial key.
728
+ * List of external links. Wiki, forums, etc.
351
729
  */
352
- __publicField$3(this, "badgePartialKey");
353
- this.pos = data.pos;
354
- this.notes = data.notes;
355
- this.mapKey = data.mapKey;
356
- this.badgeKey = data.badgeKey;
357
- this.badgePartialKey = data.badgePartialKey;
730
+ __publicField$3(this, "links");
731
+ this.key = new Key(data.key).value;
732
+ this.name = data.name;
733
+ this.links = data.links ?? [];
358
734
  }
359
735
  }
360
736
 
361
737
  var __defProp$2 = Object.defineProperty;
362
738
  var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
363
739
  var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
364
- class VidiotMap {
740
+ class Contact {
365
741
  constructor(data) {
366
742
  /**
367
- * URL of the map image.
743
+ * Unique key used to reference this contact.
744
+ *
745
+ * Keys must be unique and can only contain lowercase letters, numbers and hyphens (`-`).
368
746
  */
369
- __publicField$2(this, "imageUrl");
747
+ __publicField$2(this, "key");
370
748
  /**
371
- * Name to display for the Vidiot map.
749
+ * The name of this contact.
372
750
  */
373
751
  __publicField$2(this, "name");
374
752
  /**
375
- * List of Points of Interest labelled on the image.
753
+ * The contact's title.
376
754
  */
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) {
755
+ __publicField$2(this, "title");
389
756
  /**
390
- * The database key for this map.
757
+ * The character moralities that this contact will interact with.
391
758
  */
392
- __publicField$1(this, "key");
759
+ __publicField$2(this, "morality");
393
760
  /**
394
- * The name of the map as it appears in-game.
761
+ * The location of this contact.
395
762
  */
396
- __publicField$1(this, "name");
763
+ __publicField$2(this, "location");
397
764
  /**
398
- * List of external links for this Map. Wiki, forums, etc.
765
+ * The level range this contact will offer missions for.
399
766
  */
400
- __publicField$1(this, "links");
767
+ __publicField$2(this, "levelRange");
401
768
  /**
402
- * List of Vidiot Map assets for this map.
769
+ * Freeform notes or tips about the contact.
403
770
  */
404
- __publicField$1(this, "vidiotMaps");
771
+ __publicField$2(this, "notes");
772
+ /**
773
+ * List of external links. Wiki, forums, etc.
774
+ */
775
+ __publicField$2(this, "links");
405
776
  this.key = new Key(data.key).value;
406
777
  this.name = data.name;
407
- this.links = data.links;
408
- this.vidiotMaps = data.vidiotMaps?.map((data2) => new VidiotMap(data2));
778
+ this.title = data.title;
779
+ this.morality = new MoralityList(coalesceToArray(data.morality));
780
+ this.location = data.location;
781
+ this.levelRange = data.levelRange;
782
+ this.notes = data.notes;
783
+ this.links = data.links ?? [];
409
784
  }
410
785
  }
411
786
 
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 {
787
+ var __defProp$1 = Object.defineProperty;
788
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
789
+ var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
790
+ class Mission {
423
791
  constructor(data) {
424
- __privateAdd$1(this, _archetypeIndex, {});
425
- __privateAdd$1(this, _mapIndex, {});
426
- __privateAdd$1(this, _badgeIndex, {});
427
792
  /**
428
- * The database key for this server group.
429
- */
430
- __publicField(this, "key");
431
- /**
432
- * Name of the server group.
793
+ * Unique key used to reference this mission.
794
+ *
795
+ * Keys must be unique and can only contain lowercase letters, numbers and hyphens (`-`).
433
796
  */
434
- __publicField(this, "name");
797
+ __publicField$1(this, "key");
435
798
  /**
436
- * Description of the server group.
799
+ * The name of the mission as it appears from the contact.
437
800
  *
438
- * Supports {@link https://www.markdownguide.org/|Markdown} format.
801
+ * The name may be different when viewed in Ouroboros as a Flashback.
439
802
  */
440
- __publicField(this, "description");
803
+ __publicField$1(this, "name");
441
804
  /**
442
- * Repository where the db content package is maintained.
805
+ * The type of mission... Story arc, task force, trial, etc.
443
806
  */
444
- __publicField(this, "repository");
807
+ __publicField$1(this, "type");
445
808
  /**
446
- * List of external links for this Server Group. Wiki, forums, etc.
809
+ * The character moralities that may accept the mission.
447
810
  */
448
- __publicField(this, "links");
811
+ __publicField$1(this, "morality");
449
812
  /**
450
- * List of the game server names in this server group.
451
- * Torchbearer, Excelsior, etc.
813
+ * The keys of any contacts that provide this mission.
452
814
  */
453
- __publicField(this, "servers");
815
+ __publicField$1(this, "contactKeys");
454
816
  /**
455
- * List of archetypes available in this server group.
817
+ * The level range this mission is available for.
456
818
  */
457
- __publicField(this, "archetypes");
819
+ __publicField$1(this, "levelRange");
458
820
  /**
459
- * List of game maps supported by this server group.
821
+ * Freeform notes or tips about the mission.
460
822
  */
461
- __publicField(this, "maps");
823
+ __publicField$1(this, "notes");
462
824
  /**
463
- * List of badges available on this server group.
825
+ * List of external links. Wiki, forums, etc.
464
826
  */
465
- __publicField(this, "badges");
827
+ __publicField$1(this, "links");
466
828
  /**
467
- * Change log for this data package.
829
+ * If the mission is available in Ouroboros as a Flashback.
468
830
  */
469
- __publicField(this, "changelog");
831
+ __publicField$1(this, "flashback");
470
832
  this.key = new Key(data.key).value;
471
833
  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;
834
+ this.type = data.type;
835
+ this.morality = new MoralityList(coalesceToArray(data.morality));
836
+ this.contactKeys = coalesceToArray(data.contactKeys);
837
+ this.levelRange = data.levelRange;
838
+ this.notes = data.notes;
839
+ this.links = data.links ?? [];
840
+ this.flashback = createFlashback(data);
510
841
  }
511
842
  }
512
- _archetypeIndex = new WeakMap();
513
- _mapIndex = new WeakMap();
514
- _badgeIndex = new WeakMap();
843
+ function createFlashback(data) {
844
+ if (!data.flashback) return void 0;
845
+ return {
846
+ id: data.flashback.id,
847
+ levelRange: data.flashback.levelRange ?? data.levelRange,
848
+ name: data.flashback.name ?? data.name,
849
+ morality: new MoralityList(coalesceToArray(data.flashback.morality ?? data.morality)),
850
+ notes: data.flashback.notes
851
+ };
852
+ }
515
853
 
516
854
  var __typeError = (msg) => {
517
855
  throw TypeError(msg);
@@ -519,50 +857,153 @@ var __typeError = (msg) => {
519
857
  var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
520
858
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
521
859
  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;
860
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
861
+ var _archetypeIndex, _zoneIndex, _contactIndex, _missionIndex, _badgeIndex, _header, _servers;
523
862
  class CohContentDatabase {
524
- constructor() {
525
- __privateAdd(this, _serverGroups, {});
863
+ /**
864
+ * Create a db instance from the given content bundle.
865
+ * @param bundle The bundle to load.
866
+ */
867
+ constructor(bundle) {
868
+ __privateAdd(this, _archetypeIndex);
869
+ __privateAdd(this, _zoneIndex);
870
+ __privateAdd(this, _contactIndex);
871
+ __privateAdd(this, _missionIndex);
872
+ __privateAdd(this, _badgeIndex);
873
+ __privateAdd(this, _header);
874
+ __privateAdd(this, _servers);
875
+ __privateSet(this, _header, new BundleHeader(bundle.header));
876
+ __privateSet(this, _servers, bundle.servers ?? []);
877
+ __privateSet(this, _archetypeIndex, new AbstractIndex("key", bundle.archetypes?.map((x) => new Archetype(x))));
878
+ __privateSet(this, _zoneIndex, new AbstractIndex("key", bundle.zones?.map((x) => new Zone(x))));
879
+ __privateSet(this, _contactIndex, new AbstractIndex("key", bundle.contacts?.map((x) => new Contact(x))));
880
+ __privateSet(this, _missionIndex, new AbstractIndex("key", bundle.missions?.map((x) => new Mission(x))));
881
+ __privateSet(this, _badgeIndex, new BadgeIndex(bundle.badges?.map((x) => new Badge(x))));
882
+ }
883
+ /**
884
+ * Header information about the content bundle.
885
+ */
886
+ get header() {
887
+ return __privateGet(this, _header);
888
+ }
889
+ /**
890
+ * List of the game server names.
891
+ *
892
+ * Torchbearer, Excelsior, etc.
893
+ */
894
+ get servers() {
895
+ return __privateGet(this, _servers);
896
+ }
897
+ /**
898
+ * List of archetypes.
899
+ */
900
+ get archetypes() {
901
+ return __privateGet(this, _archetypeIndex).values;
902
+ }
903
+ /**
904
+ * Get archetype by key.
905
+ * @param key The key.
906
+ */
907
+ getArchetype(key) {
908
+ return __privateGet(this, _archetypeIndex).get(key);
526
909
  }
527
910
  /**
528
- * Load a server group data package into the database.
529
- * @param data The data to load.
911
+ * List of game zones.
530
912
  */
531
- loadServerGroupData(data) {
532
- __privateGet(this, _serverGroups)[data.key] = new ServerGroup(data);
913
+ get zones() {
914
+ return __privateGet(this, _zoneIndex).values;
533
915
  }
534
916
  /**
535
- * Get all the server groups currently loaded in the database.
917
+ * Get zone by key.
918
+ * @param key The key.
536
919
  */
537
- listServerGroups() {
538
- return Object.values(__privateGet(this, _serverGroups));
920
+ getZone(key) {
921
+ return __privateGet(this, _zoneIndex).get(key);
539
922
  }
540
923
  /**
541
- * get a server group by key.
542
- * @param serverGroupKey The key.
924
+ * List of contacts.
543
925
  */
544
- getServerGroup(serverGroupKey) {
545
- return __privateGet(this, _serverGroups)[serverGroupKey];
926
+ get contacts() {
927
+ return __privateGet(this, _contactIndex).values;
928
+ }
929
+ /**
930
+ * Get contact by key.
931
+ * @param key The key.
932
+ */
933
+ getContact(key) {
934
+ return __privateGet(this, _contactIndex).get(key);
935
+ }
936
+ /**
937
+ * List of missions.
938
+ */
939
+ get missions() {
940
+ return __privateGet(this, _missionIndex).values;
941
+ }
942
+ /**
943
+ * Get mission by key.
944
+ * @param key The key.
945
+ */
946
+ getMission(key) {
947
+ return __privateGet(this, _missionIndex).get(key);
948
+ }
949
+ /**
950
+ * List of badges.
951
+ */
952
+ get badges() {
953
+ return __privateGet(this, _badgeIndex).values;
954
+ }
955
+ /**
956
+ * Get badge by key.
957
+ * @param key The key.
958
+ */
959
+ getBadge(key) {
960
+ return __privateGet(this, _badgeIndex).get(key);
961
+ }
962
+ /**
963
+ * Search, sort and filter the badge list.
964
+ * This is a fairly brute-forced approach and will not be as performant as loading the badge data into a traditional
965
+ * database engine, but is sufficient for most operations.
966
+ * @param options {@link BadgeSearchOptions}
967
+ */
968
+ searchBadges(options) {
969
+ return __privateGet(this, _badgeIndex).search(options);
546
970
  }
547
971
  }
548
- _serverGroups = new WeakMap();
972
+ _archetypeIndex = new WeakMap();
973
+ _zoneIndex = new WeakMap();
974
+ _contactIndex = new WeakMap();
975
+ _missionIndex = new WeakMap();
976
+ _badgeIndex = new WeakMap();
977
+ _header = new WeakMap();
978
+ _servers = new WeakMap();
549
979
 
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"
980
+ var __defProp = Object.defineProperty;
981
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
982
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
983
+ class Location {
984
+ constructor(data) {
985
+ /**
986
+ * Key of the {@link Zone} that the location references.
987
+ */
988
+ __publicField(this, "zoneKey");
989
+ /**
990
+ * In-game `/loc` coordinates of the location.
991
+ */
992
+ __publicField(this, "coords");
993
+ /**
994
+ * The type of icon to use if the location appears on a map. (Typically the Vidiot map icon).
995
+ */
996
+ __publicField(this, "icon");
997
+ /**
998
+ * The text that should appear in the location icon. (Typically a number or symbol from the Vidiot map).
999
+ */
1000
+ __publicField(this, "iconText");
1001
+ this.zoneKey = data.zoneKey;
1002
+ this.coords = data.coords;
1003
+ this.icon = data.icon;
1004
+ this.iconText = data.iconText;
555
1005
  }
556
- ];
557
-
558
- function createBadgeReference(target) {
559
- const key = typeof target === "string" ? target : target.key;
560
- return `[badge:${key}]`;
561
- }
562
- function createMapReference(target) {
563
- const key = typeof target === "string" ? target : target.key;
564
- return `[map:${key}]`;
565
1006
  }
566
1007
 
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 };
1008
+ export { ALIGNMENT, AlignmentList, Alternates, Archetype, BADGE_REQUIREMENT_TYPE, BADGE_TYPE, Badge, BadgeIndex, BadgeRequirement, BundleHeader, 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 };
568
1009
  //# sourceMappingURL=coh-content-db.mjs.map