wuira 0.1.9 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/data/spells/forever.json +224281 -0
  3. package/docs/spells.md +60 -0
  4. package/lib/index.d.ts +3 -3
  5. package/lib/index.lua +3 -7
  6. package/lib/spells/BindingActions.d.ts +298 -0
  7. package/lib/spells/BindingActions.lua +3 -0
  8. package/lib/spells/DruidSpells.d.ts +1093 -0
  9. package/lib/spells/DruidSpells.lua +3 -0
  10. package/lib/spells/GeneralSpells.d.ts +941 -0
  11. package/lib/spells/GeneralSpells.lua +3 -0
  12. package/lib/spells/HunterSpells.d.ts +1201 -0
  13. package/lib/spells/HunterSpells.lua +3 -0
  14. package/lib/spells/MageSpells.d.ts +1116 -0
  15. package/lib/spells/MageSpells.lua +3 -0
  16. package/lib/spells/PaladinSpells.d.ts +918 -0
  17. package/lib/spells/PaladinSpells.lua +3 -0
  18. package/lib/spells/PetSpells.d.ts +379 -0
  19. package/lib/spells/PetSpells.lua +3 -0
  20. package/lib/spells/PriestSpells.d.ts +942 -0
  21. package/lib/spells/PriestSpells.lua +3 -0
  22. package/lib/spells/ProfessionSpells.d.ts +5007 -0
  23. package/lib/spells/ProfessionSpells.lua +3 -0
  24. package/lib/spells/RacialSpells.d.ts +83 -0
  25. package/lib/spells/RacialSpells.lua +3 -0
  26. package/lib/spells/RogueSpells.d.ts +745 -0
  27. package/lib/spells/RogueSpells.lua +3 -0
  28. package/lib/spells/ShamanSpells.d.ts +1093 -0
  29. package/lib/spells/ShamanSpells.lua +3 -0
  30. package/lib/spells/WarlockSpells.d.ts +870 -0
  31. package/lib/spells/WarlockSpells.lua +3 -0
  32. package/lib/spells/WarriorSpells.d.ts +764 -0
  33. package/lib/spells/WarriorSpells.lua +3 -0
  34. package/lib/spells/WorldSpells.d.ts +31948 -0
  35. package/lib/spells/WorldSpells.lua +3 -0
  36. package/lib/spells/index.d.ts +17 -0
  37. package/lib/spells/index.lua +3 -0
  38. package/lib/ui/Icon.d.ts +1 -1
  39. package/lib/ui/Label.d.ts +1 -1
  40. package/package.json +19 -1
  41. package/tools/build-library.mjs +5 -1
  42. package/tools/generate-spells.mjs +48 -0
  43. package/tools/spell-data.mjs +27 -0
  44. package/tools/update-spells.mjs +92 -0
  45. package/tsconfig.json +2 -0
  46. package/lib/Spells.d.ts +0 -41
  47. package/lib/Spells.lua +0 -81
@@ -0,0 +1,3 @@
1
+ --[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]
2
+ local ____exports = {}
3
+ return ____exports
@@ -0,0 +1,17 @@
1
+ /// <reference path="../platform/forever.d.ts" />
2
+ /** Generated from Forever 1.60.1.70374. Do not edit; run npm run spells:generate. */
3
+ export { DruidSpells } from "./DruidSpells";
4
+ export { GeneralSpells } from "./GeneralSpells";
5
+ export { HunterSpells } from "./HunterSpells";
6
+ export { MageSpells } from "./MageSpells";
7
+ export { PaladinSpells } from "./PaladinSpells";
8
+ export { PetSpells } from "./PetSpells";
9
+ export { PriestSpells } from "./PriestSpells";
10
+ export { ProfessionSpells } from "./ProfessionSpells";
11
+ export { RacialSpells } from "./RacialSpells";
12
+ export { RogueSpells } from "./RogueSpells";
13
+ export { ShamanSpells } from "./ShamanSpells";
14
+ export { WarlockSpells } from "./WarlockSpells";
15
+ export { WarriorSpells } from "./WarriorSpells";
16
+ export { WorldSpells } from "./WorldSpells";
17
+ export { BindingActions } from "./BindingActions";
@@ -0,0 +1,3 @@
1
+ --[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]
2
+ local ____exports = {}
3
+ return ____exports
package/lib/ui/Icon.d.ts CHANGED
@@ -5,4 +5,4 @@ export type IconProps = CellProps & {
5
5
  textureSource?: TextureSource;
6
6
  texCoords?: readonly [number, number, number, number];
7
7
  };
8
- export declare function Icon(props: Partial<IconProps>): import("..").Element;
8
+ export declare function Icon(props: Partial<IconProps>): import("./primitives/jsx").Element;
package/lib/ui/Label.d.ts CHANGED
@@ -7,4 +7,4 @@ export type LabelProps = CellProps & {
7
7
  color?: Color;
8
8
  align?: "LEFT" | "CENTER" | "RIGHT";
9
9
  };
10
- export declare function Label(props: Partial<CellProps> & Omit<LabelProps, keyof CellProps>): import("..").Element;
10
+ export declare function Label(props: Partial<CellProps> & Omit<LabelProps, keyof CellProps>): import("./primitives/jsx").Element;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wuira",
3
- "version": "0.1.9",
3
+ "version": "0.2.0",
4
4
  "author": {
5
5
  "name": "Kerim Cetinbas",
6
6
  "email": "a.cetinbas@icloud.com"
@@ -28,6 +28,14 @@
28
28
  "types": "./lib/skins/index.d.ts",
29
29
  "default": "./lib/skins/index.lua"
30
30
  },
31
+ "./spells": {
32
+ "types": "./lib/spells/index.d.ts",
33
+ "default": "./lib/spells/index.lua"
34
+ },
35
+ "./spells/*": {
36
+ "types": "./lib/spells/*.d.ts",
37
+ "default": "./lib/spells/*.lua"
38
+ },
31
39
  "./console-polyfill": {
32
40
  "types": "./lib/console-polyfill.d.ts",
33
41
  "default": "./lib/console-polyfill.lua"
@@ -50,6 +58,12 @@
50
58
  "skins": [
51
59
  "lib/skins/index.d.ts"
52
60
  ],
61
+ "spells": [
62
+ "lib/spells/index.d.ts"
63
+ ],
64
+ "spells/*": [
65
+ "lib/spells/*"
66
+ ],
53
67
  "console-polyfill": [
54
68
  "lib/console-polyfill.d.ts"
55
69
  ]
@@ -61,6 +75,8 @@
61
75
  "tools/",
62
76
  "config/",
63
77
  "templates/",
78
+ "data/spells/forever.json",
79
+ "docs/spells.md",
64
80
  "tsconfig.json",
65
81
  "tsconfig.lib.json",
66
82
  "README.md",
@@ -79,6 +95,8 @@
79
95
  "prepack": "npm run build",
80
96
  "watch": "tstl -p tsconfig.json --watch",
81
97
  "check": "tsc -p tsconfig.json --noEmit",
98
+ "spells:update": "node tools/update-spells.mjs",
99
+ "spells:generate": "node tools/generate-spells.mjs",
82
100
  "test": "node --test tests/*.test.cjs"
83
101
  },
84
102
  "devDependencies": {
@@ -4,11 +4,15 @@ import { spawnSync } from "node:child_process";
4
4
  import { createRequire } from "node:module";
5
5
  const require = createRequire(import.meta.url);
6
6
  const root = path.resolve(import.meta.dirname, "..");
7
+ // Discard previous build artifacts so deleted modules cannot enter the package.
8
+ const output = path.join(root, "lib");
9
+ if (path.dirname(output) !== root) throw new Error("Library output must remain inside the project");
10
+ fs.rmSync(output, { recursive: true, force: true });
7
11
  const result = spawnSync(process.execPath, [require.resolve("typescript-to-lua/dist/tstl.js"), "-p", "tsconfig.lib.json"], { cwd: root, stdio: "inherit" });
8
12
  if (result.status !== 0) process.exit(result.status || 1);
9
13
  fs.mkdirSync(path.join(root, "lib/platform"), { recursive: true });
10
14
  fs.copyFileSync(path.join(root, "src/platform/forever.d.ts"), path.join(root, "lib/platform/forever.d.ts"));
11
- for (const file of ["index.d.ts", "ui/index.d.ts", "datasources/index.d.ts", "store/index.d.ts", "skins/index.d.ts"]) {
15
+ for (const file of ["index.d.ts", "ui/index.d.ts", "datasources/index.d.ts", "store/index.d.ts", "skins/index.d.ts", "spells/index.d.ts"]) {
12
16
  const target = path.join(root, "lib", file);
13
17
  const reference = file === "index.d.ts" ? "./platform/forever.d.ts" : "../platform/forever.d.ts";
14
18
  fs.writeFileSync(target, `/// <reference path="${reference}" />\n` + fs.readFileSync(target, "utf8"));
@@ -0,0 +1,48 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ const root = path.resolve(import.meta.dirname, "..");
4
+ const catalog = JSON.parse(fs.readFileSync(path.join(root, "data/spells/forever.json"), "utf8"));
5
+ if (catalog.version !== 1 || catalog.product !== "wow_classic_beta") throw new Error("Unsupported spell catalog");
6
+ const output = path.join(root, "src/spells"); fs.mkdirSync(output, { recursive: true });
7
+ const compare = (a, b) => a < b ? -1 : a > b ? 1 : 0;
8
+ const identifier = name => {
9
+ const result = name.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").replace(/['’]/g, "")
10
+ .split(/[^A-Za-z0-9]+/).filter(Boolean).map(word => word[0].toUpperCase() + word.slice(1)).join("");
11
+ return /^[A-Za-z]/.test(result) ? result : "Spell" + result;
12
+ };
13
+ const groups = new Map(), ids = new Set();
14
+ for (const row of catalog.spells) {
15
+ const [id, , , category] = row;
16
+ if (!Number.isSafeInteger(id) || id < 1 || ids.has(id) || !/^[A-Z][A-Za-z]*Spells$/.test(category)) throw new Error("Invalid spell record: " + id);
17
+ ids.add(id); if (!groups.has(category)) groups.set(category, []); groups.get(category).push(row);
18
+ }
19
+ const header = "/** Generated from Forever " + catalog.build + ". Do not edit; run npm run spells:generate. */\n";
20
+ const exports = [];
21
+ for (const [category, rows] of [...groups].sort(([a], [b]) => compare(a, b))) {
22
+ const lines = [], aliases = new Map(), occupied = new Set();
23
+ for (const row of rows) {
24
+ const [id, name, subtext] = row;
25
+ const base = identifier(name || "UnnamedSpell");
26
+ const rank = /^Rank ([0-9]+)$/.exec(subtext);
27
+ const member = base + (rank ? "Rank" + rank[1] : "") + "_" + id;
28
+ occupied.add(member); lines.push(" " + member + " = " + id + ",");
29
+ if (!aliases.has(base)) aliases.set(base, []); aliases.get(base).push(row);
30
+ }
31
+ for (const [base, values] of [...aliases].sort(([a], [b]) => compare(a, b))) {
32
+ if (occupied.has(base)) continue;
33
+ const linked = values.filter(row => row[4]);
34
+ const candidates = linked.length ? linked : values;
35
+ const rank = row => Number(/^Rank ([0-9]+)$/.exec(row[2])?.[1] ?? Number.MAX_SAFE_INTEGER);
36
+ candidates.sort((a, b) => rank(a) - rank(b) || a[0] - b[0]);
37
+ // Ambiguous unranked names require the explicit ID-suffixed member.
38
+ if (candidates.length > 1 && rank(candidates[0]) === rank(candidates[1])) continue;
39
+ occupied.add(base); lines.push(" " + base + " = " + candidates[0][0] + ",");
40
+ }
41
+ fs.writeFileSync(path.join(output, category + ".ts"), header + "export const enum " + category + " {\n" + lines.join("\n") + "\n}\n");
42
+ exports.push('export { ' + category + ' } from "./' + category + '";');
43
+ }
44
+ const bindings = catalog.bindings.actions.map(([name]) => " " + name + " = " + JSON.stringify(name) + ",");
45
+ fs.writeFileSync(path.join(output, "BindingActions.ts"), "/** Native binding command tokens; these are not spell IDs or keyboard shortcuts. */\nexport const enum BindingActions {\n" + bindings.join("\n") + "\n}\n");
46
+ exports.push('export { BindingActions } from "./BindingActions";');
47
+ fs.writeFileSync(path.join(output, "index.ts"), header + exports.join("\n") + "\n");
48
+ console.log("Generated " + ids.size + " spell IDs in " + groups.size + " categories and " + bindings.length + " binding actions");
@@ -0,0 +1,27 @@
1
+ /** Parse DB2 CSV exports, including quoted commas and multiline cells. */
2
+ export function parseCSV(text) {
3
+ const rows = [];
4
+ let row = [], value = "", quoted = false;
5
+ for (let i = 0; i < text.length; i++) {
6
+ const char = text[i];
7
+ if (char === '"') {
8
+ if (quoted && text[i + 1] === '"') { value += '"'; i++; }
9
+ else quoted = !quoted;
10
+ } else if (!quoted && (char === "," || char === "\n" || char === "\r")) {
11
+ row.push(value); value = "";
12
+ if (char !== ",") {
13
+ rows.push(row); row = [];
14
+ if (char === "\r" && text[i + 1] === "\n") i++;
15
+ }
16
+ } else value += char;
17
+ }
18
+ if (quoted) throw new Error("Unterminated CSV cell");
19
+ if (value !== "" || row.length > 0) { row.push(value); rows.push(row); }
20
+ const header = rows.shift();
21
+ if (!header) throw new Error("Empty CSV");
22
+ header[0] = header[0].replace(/^\uFEFF/, "");
23
+ return rows.map(fields => {
24
+ if (fields.length !== header.length) throw new Error("Unexpected CSV field count");
25
+ return Object.fromEntries(header.map((key, index) => [key, fields[index]]));
26
+ });
27
+ }
@@ -0,0 +1,92 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { createHash } from "node:crypto";
4
+ import { parseCSV } from "./spell-data.mjs";
5
+
6
+ const root = path.resolve(import.meta.dirname, "..");
7
+ const argument = name => process.argv[process.argv.indexOf(name) + 1];
8
+ const build = process.argv.includes("--build") ? argument("--build") : undefined;
9
+ if (!build || !/^\d+\.\d+\.\d+\.\d+$/.test(build)) throw new Error("Use --build <Forever client version>, e.g. 1.60.1.70374");
10
+ if (!build.startsWith("1.60.")) throw new Error("Only the Forever 1.60 client branch is supported; other WoW products are not imported");
11
+ const cached = process.argv.includes("--cached");
12
+ const directory = path.join(root, "data/spells/.cache", build);
13
+ fs.mkdirSync(directory, { recursive: true });
14
+ const hash = value => createHash("sha256").update(value).digest("hex");
15
+ const sources = [];
16
+ async function download(url) {
17
+ const response = await fetch(url, { signal: AbortSignal.timeout(60000) });
18
+ if (!response.ok) throw new Error("HTTP " + response.status + ": " + url);
19
+ return response;
20
+ }
21
+ async function table(name) {
22
+ const url = "https://wago.tools/db2/" + name + "/csv?build=" + build;
23
+ const filename = path.join(directory, name + ".csv");
24
+ let text;
25
+ if (cached) text = fs.readFileSync(filename, "utf8");
26
+ else {
27
+ const response = await download(url);
28
+ if (!response.headers.get("content-type")?.includes("text/csv")) throw new Error("Expected CSV: " + name);
29
+ text = await response.text(); fs.writeFileSync(filename, text);
30
+ }
31
+ const rows = parseCSV(text);
32
+ sources.push({ table: name, url, sha256: hash(text), rows: rows.length });
33
+ return [name, rows];
34
+ }
35
+ const results = await Promise.allSettled(["Spell", "SpellName", "SpellClassOptions", "SkillLine", "SkillLineAbility", "ChrClasses"].map(table));
36
+ const failures = results.filter(result => result.status === "rejected");
37
+ if (failures.length) throw new AggregateError(failures.map(result => result.reason), "Spell data download failed");
38
+ const tables = Object.fromEntries(results.map(result => result.value));
39
+ const spells = new Map(tables.Spell.map(row => [Number(row.ID), row]));
40
+ const names = new Map(tables.SpellName.map(row => [Number(row.ID), row.Name_lang]));
41
+ if (spells.size < 1000 || spells.size !== names.size || [...spells.keys()].some(id => !names.has(id))) throw new Error("Spell and SpellName universes differ");
42
+ const families = new Map(tables.ChrClasses.map(row => [Number(row.SpellClassSet), row.Name_lang + "Spells"]));
43
+ const classes = new Map(tables.ChrClasses.map(row => [Number(row.ID), row.Name_lang + "Spells"]));
44
+ const options = new Map(tables.SpellClassOptions.map(row => [Number(row.SpellID), Number(row.SpellClassSet)]));
45
+ const skills = new Map(tables.SkillLine.map(row => [Number(row.ID), row]));
46
+ const linked = new Map();
47
+ for (const row of tables.SkillLineAbility) {
48
+ const id = Number(row.Spell); if (!linked.has(id)) linked.set(id, []);
49
+ linked.get(id).push(row);
50
+ }
51
+ const secondaryProfessions = new Set(["Cooking", "First Aid", "Fishing"]);
52
+ function category(id) {
53
+ const abilities = linked.get(id) ?? [];
54
+ const lines = abilities.map(row => skills.get(Number(row.SkillLine))).filter(Boolean);
55
+ if (lines.some(line => /\bRacial\b/.test(line.DisplayName_lang))) return "RacialSpells";
56
+ if (lines.some(line => line.CategoryID === "11" || secondaryProfessions.has(line.DisplayName_lang))) return "ProfessionSpells";
57
+ if (lines.some(line => line.DisplayName_lang.startsWith("Pet - "))) return "PetSpells";
58
+ const family = families.get(options.get(id)); if (family) return family;
59
+ const owners = new Set();
60
+ for (const ability of abilities) for (const [classId, name] of classes) if ((Number(ability.ClassMask) & (1 << (classId - 1))) !== 0) owners.add(name);
61
+ if (owners.size === 1) return [...owners][0];
62
+ if (lines.length) return "GeneralSpells";
63
+ return "WorldSpells";
64
+ }
65
+ const rows = [...spells].sort(([a], [b]) => a - b).map(([id, spell]) => [
66
+ id, names.get(id), spell.NameSubtext_lang, category(id), (linked.get(id) ?? []).length > 0,
67
+ ]);
68
+ const treeFile = path.join(directory, "ui-tree.json");
69
+ const tree = cached ? JSON.parse(fs.readFileSync(treeFile, "utf8"))
70
+ : await (await download("https://api.github.com/repos/Gethe/wow-ui-source/git/trees/forever?recursive=1")).json();
71
+ if (!/^[a-f0-9]{40}$/.test(tree.sha)) throw new Error("Expected a pinned Forever UI commit");
72
+ if (!cached) fs.writeFileSync(treeFile, JSON.stringify(tree));
73
+ const bindingPath = "Interface/AddOns/Blizzard_FrameXML/Bindings_Camelot.xml";
74
+ const bindingURL = "https://raw.githubusercontent.com/Gethe/wow-ui-source/" + tree.sha + "/" + bindingPath;
75
+ const xml = cached ? fs.readFileSync(path.join(directory, "Bindings_Camelot.xml"), "utf8") : await (await download(bindingURL)).text();
76
+ if (!cached) fs.writeFileSync(path.join(directory, "Bindings_Camelot.xml"), xml);
77
+ const actions = new Map();
78
+ for (const match of xml.replace(/<!--[\s\S]*?-->/g, "").matchAll(/<Binding\s+([^>]+)>/g)) {
79
+ const attributes = Object.fromEntries([...match[1].matchAll(/([\w]+)="([^"]*)"/g)].map(value => [value[1], value[2]]));
80
+ if (!attributes.name || attributes.name === "HEADER") continue;
81
+ if (!/^[A-Z][A-Z0-9_]*$/.test(attributes.name)) throw new Error("Unexpected binding token: " + attributes.name);
82
+ actions.set(attributes.name, attributes.category ?? "");
83
+ }
84
+ if (actions.size < 100) throw new Error("Binding snapshot is incomplete");
85
+ const catalog = {
86
+ version: 1, product: "wow_classic_beta", build, locale: "enUS",
87
+ sources: sources.sort((a, b) => a.table.localeCompare(b.table)),
88
+ columns: ["id", "name", "rank", "category", "skillLineLinked"], spells: rows,
89
+ bindings: { commit: tree.sha, url: bindingURL, sha256: hash(xml), actions: [...actions].sort(([a], [b]) => a.localeCompare(b)) },
90
+ };
91
+ fs.writeFileSync(path.join(root, "data/spells/forever.json"), JSON.stringify(catalog, null, 2) + "\n");
92
+ console.log("Saved " + rows.length + " spell IDs and " + actions.size + " bindings for " + build);
package/tsconfig.json CHANGED
@@ -2,6 +2,8 @@
2
2
  "$schema": "https://raw.githubusercontent.com/TypeScriptToLua/TypeScriptToLua/master/tsconfig-schema.json",
3
3
  "compilerOptions": {
4
4
  "target": "ESNext",
5
+ "module": "Node16",
6
+ "moduleResolution": "Node16",
5
7
  "lib": ["ESNext"],
6
8
  "types": [],
7
9
  "jsx": "react",
package/lib/Spells.d.ts DELETED
@@ -1,41 +0,0 @@
1
- /** Representative spell IDs; aura sources resolve localized names across ranks. */
2
- export declare enum Spells {
3
- Judgement = 20271,
4
- HolyStrike = 679,
5
- Consecration = 26573,
6
- HolyShock = 20473,
7
- Exorcism = 879,
8
- DivineFavor = 20216,
9
- LayOnHands = 633,
10
- BlessingOfProtection = 1022,
11
- BlessingOfFreedom = 1044,
12
- BlessingOfMight = 19740,
13
- BlessingOfWisdom = 19742,
14
- BlessingOfKings = 20217,
15
- BlessingOfLight = 19977,
16
- BlessingOfSalvation = 1038,
17
- BlessingOfSanctuary = 20911,
18
- BlessingOfSacrifice = 6940,
19
- GreaterBlessingOfMight = 25782,
20
- GreaterBlessingOfWisdom = 25894,
21
- GreaterBlessingOfKings = 25898,
22
- GreaterBlessingOfLight = 25890,
23
- GreaterBlessingOfSalvation = 25895,
24
- GreaterBlessingOfSanctuary = 25899,
25
- DevotionAura = 465,
26
- RetributionAura = 7294,
27
- ConcentrationAura = 19746,
28
- ShadowResistanceAura = 19876,
29
- FrostResistanceAura = 19888,
30
- FireResistanceAura = 19891,
31
- SanctityAura = 20218,
32
- VoiceOfTruth = 1310897,
33
- HammerOfJustice = 853,
34
- SealOfRighteousness = 21084,
35
- SealOfTheCrusader = 21082,
36
- SealOfCommand = 20375,
37
- SealOfJustice = 20164,
38
- SealOfLight = 20165,
39
- SealOfWisdom = 20166,
40
- SealOfFury = 20163
41
- }
package/lib/Spells.lua DELETED
@@ -1,81 +0,0 @@
1
- --[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]
2
- local ____exports = {}
3
- --- Representative spell IDs; aura sources resolve localized names across ranks.
4
- ____exports.Spells = ____exports.Spells or ({})
5
- ____exports.Spells.Judgement = 20271
6
- ____exports.Spells[____exports.Spells.Judgement] = "Judgement"
7
- ____exports.Spells.HolyStrike = 679
8
- ____exports.Spells[____exports.Spells.HolyStrike] = "HolyStrike"
9
- ____exports.Spells.Consecration = 26573
10
- ____exports.Spells[____exports.Spells.Consecration] = "Consecration"
11
- ____exports.Spells.HolyShock = 20473
12
- ____exports.Spells[____exports.Spells.HolyShock] = "HolyShock"
13
- ____exports.Spells.Exorcism = 879
14
- ____exports.Spells[____exports.Spells.Exorcism] = "Exorcism"
15
- ____exports.Spells.DivineFavor = 20216
16
- ____exports.Spells[____exports.Spells.DivineFavor] = "DivineFavor"
17
- ____exports.Spells.LayOnHands = 633
18
- ____exports.Spells[____exports.Spells.LayOnHands] = "LayOnHands"
19
- ____exports.Spells.BlessingOfProtection = 1022
20
- ____exports.Spells[____exports.Spells.BlessingOfProtection] = "BlessingOfProtection"
21
- ____exports.Spells.BlessingOfFreedom = 1044
22
- ____exports.Spells[____exports.Spells.BlessingOfFreedom] = "BlessingOfFreedom"
23
- ____exports.Spells.BlessingOfMight = 19740
24
- ____exports.Spells[____exports.Spells.BlessingOfMight] = "BlessingOfMight"
25
- ____exports.Spells.BlessingOfWisdom = 19742
26
- ____exports.Spells[____exports.Spells.BlessingOfWisdom] = "BlessingOfWisdom"
27
- ____exports.Spells.BlessingOfKings = 20217
28
- ____exports.Spells[____exports.Spells.BlessingOfKings] = "BlessingOfKings"
29
- ____exports.Spells.BlessingOfLight = 19977
30
- ____exports.Spells[____exports.Spells.BlessingOfLight] = "BlessingOfLight"
31
- ____exports.Spells.BlessingOfSalvation = 1038
32
- ____exports.Spells[____exports.Spells.BlessingOfSalvation] = "BlessingOfSalvation"
33
- ____exports.Spells.BlessingOfSanctuary = 20911
34
- ____exports.Spells[____exports.Spells.BlessingOfSanctuary] = "BlessingOfSanctuary"
35
- ____exports.Spells.BlessingOfSacrifice = 6940
36
- ____exports.Spells[____exports.Spells.BlessingOfSacrifice] = "BlessingOfSacrifice"
37
- ____exports.Spells.GreaterBlessingOfMight = 25782
38
- ____exports.Spells[____exports.Spells.GreaterBlessingOfMight] = "GreaterBlessingOfMight"
39
- ____exports.Spells.GreaterBlessingOfWisdom = 25894
40
- ____exports.Spells[____exports.Spells.GreaterBlessingOfWisdom] = "GreaterBlessingOfWisdom"
41
- ____exports.Spells.GreaterBlessingOfKings = 25898
42
- ____exports.Spells[____exports.Spells.GreaterBlessingOfKings] = "GreaterBlessingOfKings"
43
- ____exports.Spells.GreaterBlessingOfLight = 25890
44
- ____exports.Spells[____exports.Spells.GreaterBlessingOfLight] = "GreaterBlessingOfLight"
45
- ____exports.Spells.GreaterBlessingOfSalvation = 25895
46
- ____exports.Spells[____exports.Spells.GreaterBlessingOfSalvation] = "GreaterBlessingOfSalvation"
47
- ____exports.Spells.GreaterBlessingOfSanctuary = 25899
48
- ____exports.Spells[____exports.Spells.GreaterBlessingOfSanctuary] = "GreaterBlessingOfSanctuary"
49
- ____exports.Spells.DevotionAura = 465
50
- ____exports.Spells[____exports.Spells.DevotionAura] = "DevotionAura"
51
- ____exports.Spells.RetributionAura = 7294
52
- ____exports.Spells[____exports.Spells.RetributionAura] = "RetributionAura"
53
- ____exports.Spells.ConcentrationAura = 19746
54
- ____exports.Spells[____exports.Spells.ConcentrationAura] = "ConcentrationAura"
55
- ____exports.Spells.ShadowResistanceAura = 19876
56
- ____exports.Spells[____exports.Spells.ShadowResistanceAura] = "ShadowResistanceAura"
57
- ____exports.Spells.FrostResistanceAura = 19888
58
- ____exports.Spells[____exports.Spells.FrostResistanceAura] = "FrostResistanceAura"
59
- ____exports.Spells.FireResistanceAura = 19891
60
- ____exports.Spells[____exports.Spells.FireResistanceAura] = "FireResistanceAura"
61
- ____exports.Spells.SanctityAura = 20218
62
- ____exports.Spells[____exports.Spells.SanctityAura] = "SanctityAura"
63
- ____exports.Spells.VoiceOfTruth = 1310897
64
- ____exports.Spells[____exports.Spells.VoiceOfTruth] = "VoiceOfTruth"
65
- ____exports.Spells.HammerOfJustice = 853
66
- ____exports.Spells[____exports.Spells.HammerOfJustice] = "HammerOfJustice"
67
- ____exports.Spells.SealOfRighteousness = 21084
68
- ____exports.Spells[____exports.Spells.SealOfRighteousness] = "SealOfRighteousness"
69
- ____exports.Spells.SealOfTheCrusader = 21082
70
- ____exports.Spells[____exports.Spells.SealOfTheCrusader] = "SealOfTheCrusader"
71
- ____exports.Spells.SealOfCommand = 20375
72
- ____exports.Spells[____exports.Spells.SealOfCommand] = "SealOfCommand"
73
- ____exports.Spells.SealOfJustice = 20164
74
- ____exports.Spells[____exports.Spells.SealOfJustice] = "SealOfJustice"
75
- ____exports.Spells.SealOfLight = 20165
76
- ____exports.Spells[____exports.Spells.SealOfLight] = "SealOfLight"
77
- ____exports.Spells.SealOfWisdom = 20166
78
- ____exports.Spells[____exports.Spells.SealOfWisdom] = "SealOfWisdom"
79
- ____exports.Spells.SealOfFury = 20163
80
- ____exports.Spells[____exports.Spells.SealOfFury] = "SealOfFury"
81
- return ____exports