@crockery/fellowship-components 0.3.0 → 0.4.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.
@@ -1,57 +1,57 @@
1
- import { t as e } from "./data-source-C-Gs7kRl.js";
2
- import { n as t, r as n, t as r } from "./decorate-B_ZTN9li.js";
3
- import { a as i, n as a } from "./tooltip-DoQVSnOn.js";
4
- import { createPackageFellowshipDataClient as o } from "@crockery/fellowship-data/client";
5
- import { LitElement as s, css as c, html as l, nothing as u } from "lit";
6
- import { customElement as d, property as f, state as p } from "lit/decorators.js";
7
- import { repeat as m } from "lit/directives/repeat.js";
8
- import { findImage as h } from "@crockery/fellowship-data";
1
+ import { n as e, t } from "./data-source-XbksqUrw.js";
2
+ import { n, r, t as i } from "./decorate-B_ZTN9li.js";
3
+ import { a, n as o } from "./tooltip-DoQVSnOn.js";
4
+ import { createPackageFellowshipDataClient as s } from "@crockery/fellowship-data/client";
5
+ import { LitElement as c, css as l, html as u, nothing as d } from "lit";
6
+ import { customElement as f, property as p, state as m } from "lit/decorators.js";
7
+ import { repeat as h } from "lit/directives/repeat.js";
8
+ import { findImage as g } from "@crockery/fellowship-data";
9
9
  //#region src/data/package-talent-data-source.ts
10
- var g = (e = {}) => {
11
- let t = o(e);
10
+ var _ = (e = {}) => {
11
+ let t = s(e);
12
12
  return {
13
13
  loadHeroTalents: (e, n) => t.loadHeroTalents(e, n),
14
14
  resolveAssetUrl: (e) => t.resolveAssetUrl(e)
15
15
  };
16
- }, _ = [
16
+ }, v = [
17
17
  "I",
18
18
  "II",
19
19
  "III",
20
20
  "IV",
21
21
  "V",
22
22
  "VI"
23
- ], v = (e) => _[e - 1] ?? String(e), y = (e, t, n) => ({
23
+ ], y = (e) => v[e - 1] ?? String(e), b = (e, t, n) => ({
24
24
  code: e,
25
25
  message: n,
26
26
  talentId: t.id
27
- }), b = (e, t) => {
27
+ }), x = (e, t) => {
28
28
  let n = [], r = /* @__PURE__ */ new Set(), i = [];
29
29
  for (let a of e.talents) {
30
30
  if (a.row === null && a.column === null) continue;
31
31
  if (!Number.isInteger(a.row) || !Number.isInteger(a.column) || a.row === null || a.column === null || a.row < 1 || a.row > 6 || a.column < 1 || a.column > 3) {
32
- n.push(y("invalid-position", a, `Talent “${a.id}” has an invalid row or column and was skipped.`));
32
+ n.push(b("invalid-position", a, `Talent “${a.id}” has an invalid row or column and was skipped.`));
33
33
  continue;
34
34
  }
35
35
  let e = `${a.row}:${a.column}`;
36
36
  if (r.has(e)) {
37
- n.push(y("duplicate-position", a, `Talent “${a.id}” duplicates row ${a.row}, column ${a.column} and was skipped.`));
37
+ n.push(b("duplicate-position", a, `Talent “${a.id}” duplicates row ${a.row}, column ${a.column} and was skipped.`));
38
38
  continue;
39
39
  }
40
40
  r.add(e);
41
41
  let o = Number.isInteger(a.pointCost) && (a.pointCost ?? 0) > 0 ? a.pointCost : null;
42
- o === null && n.push(y("invalid-cost", a, `Talent “${a.id}” has an invalid point cost.`)), a.name || n.push(y("missing-name", a, `Talent “${a.id}” has no display name.`)), a.description || n.push(y("missing-description", a, `Talent “${a.id}” has no description.`));
43
- let s = h(a.images, {
42
+ o === null && n.push(b("invalid-cost", a, `Talent “${a.id}” has an invalid point cost.`)), a.name || n.push(b("missing-name", a, `Talent “${a.id}” has no display name.`)), a.description || n.push(b("missing-description", a, `Talent “${a.id}” has no description.`));
43
+ let s = g(a.images, {
44
44
  type: "talent",
45
45
  size: "200"
46
- }) ?? h(a.images, {
46
+ }) ?? g(a.images, {
47
47
  type: "talent",
48
48
  size: "full"
49
49
  }), c = null;
50
- if (!s) n.push(y("missing-image", a, `Talent “${a.id}” has no icon.`));
50
+ if (!s) n.push(b("missing-image", a, `Talent “${a.id}” has no icon.`));
51
51
  else try {
52
52
  c = t.resolveAssetUrl(s);
53
53
  } catch (e) {
54
- n.push(y("asset-url-error", a, `The icon URL for talent “${a.id}” could not be resolved: ${String(e)}.`));
54
+ n.push(b("asset-url-error", a, `The icon URL for talent “${a.id}” could not be resolved: ${String(e)}.`));
55
55
  }
56
56
  i.push({
57
57
  talent: a,
@@ -64,7 +64,7 @@ var g = (e = {}) => {
64
64
  i.sort((e, t) => e.row - t.row || e.column - t.column);
65
65
  let a = new Map(i.map((e) => [e.talent.id, e])), o = [...new Set(i.map(({ row: e }) => e))].map((e) => ({
66
66
  row: e,
67
- label: v(e),
67
+ label: y(e),
68
68
  talents: i.filter((t) => t.row === e)
69
69
  }));
70
70
  return {
@@ -73,13 +73,13 @@ var g = (e = {}) => {
73
73
  talentById: a,
74
74
  warnings: n
75
75
  };
76
- }, x = 14, S = (e) => Math.min(14, Math.max(0, Math.round(Number.isFinite(e) ? e : 14))), C = (e, t) => {
76
+ }, S = 14, C = (e) => Math.min(14, Math.max(0, Math.round(Number.isFinite(e) ? e : 14))), w = (e, t) => {
77
77
  let n = new Set(t), r = [...e.talentById.values()].filter(({ talent: e }) => n.has(e.id)).map(({ talent: e }) => e.id), i = new Set(r);
78
78
  return {
79
79
  selectedTalentIds: r,
80
80
  removedTalentIds: [...new Set(t)].filter((e) => !i.has(e))
81
81
  };
82
- }, w = (e, t, n) => {
82
+ }, T = (e, t, n) => {
83
83
  let r = new Set(t), i = [...e.talentById.values()].reduce((e, t) => r.has(t.talent.id) && t.pointCost !== null ? e + t.pointCost : e, 0), a = n - i;
84
84
  return {
85
85
  selectedTalentIds: [...e.talentById.values()].filter(({ talent: e }) => r.has(e.id)).map(({ talent: e }) => e.id),
@@ -87,7 +87,7 @@ var g = (e = {}) => {
87
87
  remainingPoints: a,
88
88
  overBudget: a < 0
89
89
  };
90
- }, T = (e, t) => e !== null && !t.overBudget && e <= t.remainingPoints, E = c`
90
+ }, E = (e, t) => e !== null && !t.overBudget && e <= t.remainingPoints, D = l`
91
91
  :host {
92
92
  --fellowship-talent-background: var(--_fellowship-field-canvas);
93
93
  --fellowship-talent-surface: var(--_fellowship-field-surface);
@@ -635,20 +635,20 @@ var g = (e = {}) => {
635
635
  transform: none;
636
636
  }
637
637
  }
638
- `, D = {
638
+ `, O = {
639
639
  bubbles: !0,
640
640
  composed: !0
641
- }, O = (e, t) => e.length !== t?.length || e.some((e, n) => e !== t[n]), k = (e) => `talent:${e}`, A = (e) => ({
641
+ }, k = (e, t) => e.length !== t?.length || e.some((e, n) => e !== t[n]), A = (e) => `talent:${e}`, j = (e) => ({
642
642
  selectedTalentIds: [],
643
643
  spentPoints: 0,
644
644
  remainingPoints: e,
645
645
  overBudget: !1
646
- }), j = class extends s {
646
+ }), M = class extends c {
647
647
  constructor(...e) {
648
- super(...e), this.heroId = "", this.talentPoints = 14, this.selectedTalentIds = [], this.assetBaseUrl = null, this.dataSource = null, this.renderTalent = null, this.showPointControls = !0, this.showTooltips = !0, this._status = "empty", this._error = null, this._model = null, this._failedImages = /* @__PURE__ */ new Set(), this._announcement = "", this._renderSelectionState = A(14), this._talentPresentation = /* @__PURE__ */ new Map(), this._talentRenderContent = /* @__PURE__ */ new Map(), this.#e = null, this.#t = 0, this.#n = null, this.#r = !1, this.#i = /* @__PURE__ */ new Set(), this.#a = [];
648
+ super(...e), this.heroId = "", this.talentPoints = 14, this.selectedTalentIds = [], this.assetBaseUrl = null, this.dataSource = null, this.renderTalent = null, this.showPointControls = !0, this.showTooltips = !0, this._status = "empty", this._error = null, this._model = null, this._failedImages = /* @__PURE__ */ new Set(), this._announcement = "", this._renderSelectionState = j(14), this._talentPresentation = /* @__PURE__ */ new Map(), this._talentRenderContent = /* @__PURE__ */ new Map(), this.#e = null, this.#t = 0, this.#n = null, this.#r = !1, this.#i = /* @__PURE__ */ new Set(), this.#a = [];
649
649
  }
650
650
  static {
651
- this.styles = [n, E];
651
+ this.styles = [r, D];
652
652
  }
653
653
  #e;
654
654
  #t;
@@ -657,7 +657,7 @@ var g = (e = {}) => {
657
657
  #i;
658
658
  #a;
659
659
  connectedCallback() {
660
- super.connectedCallback(), t(this.ownerDocument);
660
+ super.connectedCallback(), n(this.ownerDocument);
661
661
  }
662
662
  disconnectedCallback() {
663
663
  this.#e?.abort(), super.disconnectedCallback();
@@ -670,7 +670,7 @@ var g = (e = {}) => {
670
670
  return;
671
671
  }
672
672
  if (e.has("talentPoints")) {
673
- let t = S(this.talentPoints);
673
+ let t = C(this.talentPoints);
674
674
  if (t !== this.talentPoints) {
675
675
  this.#r = !0, this.talentPoints = t, this.#v("normalization");
676
676
  return;
@@ -682,20 +682,20 @@ var g = (e = {}) => {
682
682
  willUpdate(e) {
683
683
  super.willUpdate(e);
684
684
  let t = e.has("_model") || e.has("selectedTalentIds") || e.has("talentPoints");
685
- t && (this._renderSelectionState = this._model ? w(this._model, this.selectedTalentIds, this.talentPoints) : A(this.talentPoints)), e.has("renderTalent") && this.#i.clear(), (t || e.has("renderTalent")) && this.#l(this._renderSelectionState);
685
+ t && (this._renderSelectionState = this._model ? T(this._model, this.selectedTalentIds, this.talentPoints) : j(this.talentPoints)), e.has("renderTalent") && this.#i.clear(), (t || e.has("renderTalent")) && this.#l(this._renderSelectionState);
686
686
  }
687
687
  get renderModel() {
688
688
  return this._model;
689
689
  }
690
690
  get selectionState() {
691
- return this._model ? w(this._model, this.selectedTalentIds, this.talentPoints) : A(this.talentPoints);
691
+ return this._model ? T(this._model, this.selectedTalentIds, this.talentPoints) : j(this.talentPoints);
692
692
  }
693
693
  reset() {
694
694
  this.selectedTalentIds.length !== 0 && (this.selectedTalentIds = [], this.#_("reset"));
695
695
  }
696
696
  selectTalent(e) {
697
697
  let t = this._model?.talentById.get(e), n = this.selectionState;
698
- return !t || n.selectedTalentIds.includes(e) || !T(t.pointCost, n) ? !1 : (this.selectedTalentIds = [...n.selectedTalentIds, e], this.#_("api"), !0);
698
+ return !t || n.selectedTalentIds.includes(e) || !E(t.pointCost, n) ? !1 : (this.selectedTalentIds = [...n.selectedTalentIds, e], this.#_("api"), !0);
699
699
  }
700
700
  deselectTalent(e) {
701
701
  return this.selectionState.selectedTalentIds.includes(e) ? (this.selectedTalentIds = this.selectionState.selectedTalentIds.filter((t) => t !== e), this.#_("api"), !0) : !1;
@@ -705,7 +705,7 @@ var g = (e = {}) => {
705
705
  }
706
706
  render() {
707
707
  let e = this._renderSelectionState;
708
- return l`
708
+ return u`
709
709
  <section
710
710
  class="container"
711
711
  part="container"
@@ -719,7 +719,7 @@ var g = (e = {}) => {
719
719
  `;
720
720
  }
721
721
  #o(e) {
722
- return l`
722
+ return u`
723
723
  <header class="header" part="header">
724
724
  <h2 class="heading" part="heading">Talent points</h2>
725
725
  <div class="points-cluster">
@@ -734,7 +734,7 @@ var g = (e = {}) => {
734
734
  <span class="points-separator" aria-hidden="true">/</span>
735
735
  <span class="points-total" part="points-total">${this.talentPoints}</span>
736
736
  </div>
737
- ${this.showPointControls ? l`
737
+ ${this.showPointControls ? u`
738
738
  <div
739
739
  class="point-controls"
740
740
  part="point-controls"
@@ -764,7 +764,7 @@ var g = (e = {}) => {
764
764
  +
765
765
  </button>
766
766
  </div>
767
- ` : u}
767
+ ` : d}
768
768
  <button
769
769
  class="clear-all"
770
770
  part="clear-all"
@@ -779,7 +779,7 @@ var g = (e = {}) => {
779
779
  `;
780
780
  }
781
781
  #s(e) {
782
- return e.rows.length === 0 ? l`
782
+ return e.rows.length === 0 ? u`
783
783
  <div class="status" part="empty-state" role="status">
784
784
  <div class="status-card">
785
785
  <div class="status-mark" aria-hidden="true">◇</div>
@@ -789,14 +789,14 @@ var g = (e = {}) => {
789
789
  </p>
790
790
  </div>
791
791
  </div>
792
- ` : l`
792
+ ` : u`
793
793
  <div class="grid" part="grid" role="group" aria-label="Talent tiers">
794
- ${m(e.rows, (e) => e.row, (e) => l`
794
+ ${h(e.rows, (e) => e.row, (e) => u`
795
795
  <fieldset class="row" part="row">
796
796
  <legend class="visually-hidden">Talent tier ${e.label}</legend>
797
797
  <span class="row-label" part="row-label" aria-hidden="true">${e.label}</span>
798
798
  <div class="row-talents">
799
- ${m(e.talents, (e) => e.talent.id, (e) => this.#c(e))}
799
+ ${h(e.talents, (e) => e.talent.id, (e) => this.#c(e))}
800
800
  </div>
801
801
  </fieldset>
802
802
  `)}
@@ -805,8 +805,8 @@ var g = (e = {}) => {
805
805
  }
806
806
  #c(e) {
807
807
  let t = this._talentPresentation.get(e.talent.id);
808
- if (!t) return u;
809
- let { context: n, name: r, descriptionId: i, affordability: a, description: o } = t, { selected: s, disabled: c } = n, d = l`
808
+ if (!t) return d;
809
+ let { context: n, name: r, descriptionId: i, affordability: a, description: o } = t, { selected: s, disabled: c } = n, l = u`
810
810
  <button
811
811
  class="talent"
812
812
  part="talent"
@@ -821,22 +821,22 @@ var g = (e = {}) => {
821
821
  <span class="talent-cost" part="talent-cost">${e.pointCost ?? "–"}</span>
822
822
  </button>
823
823
  `;
824
- return l`
825
- ${this.showTooltips && (e.talent.description || c) ? l`
824
+ return u`
825
+ ${this.showTooltips && (e.talent.description || c) ? u`
826
826
  <fellowship-tooltip
827
827
  .heading=${r}
828
828
  .text=${e.talent.description ?? a}
829
829
  >
830
- ${d}
830
+ ${l}
831
831
  </fellowship-tooltip>
832
- ` : d}
832
+ ` : l}
833
833
  <span class="visually-hidden" id=${i}>${o}</span>
834
834
  `;
835
835
  }
836
836
  #l(e) {
837
- let t = this.renderTalent, n = this._model, r = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Map();
837
+ let t = this.renderTalent, n = this._model, r = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map();
838
838
  if (n) for (let o of n.talentById.values()) {
839
- let s = e.selectedTalentIds.includes(o.talent.id), c = T(o.pointCost, e), l = !s && !c, u = o.talent.name ?? o.talent.id, d = o.pointCost === null ? "This talent has no valid point cost." : l ? `Requires ${o.pointCost} talent points; ${Math.max(0, e.remainingPoints)} remaining.` : `${o.pointCost} talent ${o.pointCost === 1 ? "point" : "points"}.`, f = {
839
+ let s = e.selectedTalentIds.includes(o.talent.id), c = E(o.pointCost, e), l = !s && !c, u = o.talent.name ?? o.talent.id, d = o.pointCost === null ? "This talent has no valid point cost." : l ? `Requires ${o.pointCost} talent points; ${Math.max(0, e.remainingPoints)} remaining.` : `${o.pointCost} talent ${o.pointCost === 1 ? "point" : "points"}.`, f = {
840
840
  talent: o,
841
841
  hero: n.hero,
842
842
  selected: s,
@@ -846,12 +846,12 @@ var g = (e = {}) => {
846
846
  remainingPoints: e.remainingPoints,
847
847
  talentPoints: this.talentPoints
848
848
  };
849
- if (a.set(o.talent.id, {
849
+ if (i.set(o.talent.id, {
850
850
  context: f,
851
851
  name: u,
852
852
  descriptionId: `talent-description-${o.row}-${o.column}`,
853
853
  affordability: d,
854
- description: [i(o.talent.description ?? ""), d].filter(Boolean).join(" ")
854
+ description: [a(o.talent.description ?? ""), d].filter(Boolean).join(" ")
855
855
  }), t) try {
856
856
  r.set(o.talent.id, t(f));
857
857
  } catch (e) {
@@ -862,20 +862,20 @@ var g = (e = {}) => {
862
862
  }));
863
863
  }
864
864
  }
865
- this._talentPresentation = a, this._talentRenderContent = r;
865
+ this._talentPresentation = i, this._talentRenderContent = r;
866
866
  }
867
867
  #u(e) {
868
- let t = e.talent, n = t.talent.name ?? t.talent.id, r = this.renderTalent && this._talentRenderContent.has(t.talent.id) ? this._talentRenderContent.get(t.talent.id) : l`
869
- <slot name=${k(t.talent.id)}>
868
+ let t = e.talent, n = t.talent.name ?? t.talent.id, r = this.renderTalent && this._talentRenderContent.has(t.talent.id) ? this._talentRenderContent.get(t.talent.id) : u`
869
+ <slot name=${A(t.talent.id)}>
870
870
  <span class="talent-name" part="talent-name" title=${n}>${n}</span>
871
871
  </slot>
872
872
  `;
873
- return l`
873
+ return u`
874
874
  ${this.#d(t, n)} ${r}
875
875
  `;
876
876
  }
877
877
  #d(e, t) {
878
- return e.imageUrl && !this._failedImages.has(e.talent.id) ? l`
878
+ return e.imageUrl && !this._failedImages.has(e.talent.id) ? u`
879
879
  <img
880
880
  class="talent-icon"
881
881
  part="talent-icon"
@@ -884,11 +884,11 @@ var g = (e = {}) => {
884
884
  draggable="false"
885
885
  @error=${() => this.#b(e)}
886
886
  />
887
- ` : l`<span class="talent-icon-fallback" part="talent-icon-fallback">${t.split(/\s+/).map((e) => e[0]).join("").slice(0, 2).toUpperCase()}</span>`;
887
+ ` : u`<span class="talent-icon-fallback" part="talent-icon-fallback">${t.split(/\s+/).map((e) => e[0]).join("").slice(0, 2).toUpperCase()}</span>`;
888
888
  }
889
889
  #f() {
890
890
  let e = this._status === "loading", t = this._status === "empty", n = e ? "Reading talent codex" : t ? "Choose a hero" : "Talents unavailable", r = e ? "Loading the hero and their available talents." : t ? "Set the hero-id attribute or heroId property to build a talent loadout." : this._error?.message ?? "An unexpected talent data error occurred.";
891
- return l`
891
+ return u`
892
892
  <div
893
893
  class="status"
894
894
  part=${this._status === "error" ? "error-state" : "status"}
@@ -898,7 +898,7 @@ var g = (e = {}) => {
898
898
  <div class="status-mark" aria-hidden="true">${e ? "…" : "✦"}</div>
899
899
  <p class="status-title">${n}</p>
900
900
  <p class="status-copy">${r}</p>
901
- ${this._status === "error" ? l`<button class="retry-button" type="button" @click=${this.retry}>Retry</button>` : u}
901
+ ${this._status === "error" ? u`<button class="retry-button" type="button" @click=${this.retry}>Retry</button>` : d}
902
902
  </div>
903
903
  </div>
904
904
  `;
@@ -910,18 +910,18 @@ var g = (e = {}) => {
910
910
  return;
911
911
  }
912
912
  this._status = "loading";
913
- let r = this.dataSource ?? g(this.assetBaseUrl ? { assetBaseUrl: this.assetBaseUrl } : {});
913
+ let r = this.dataSource ?? _(this.assetBaseUrl ? { assetBaseUrl: this.assetBaseUrl } : {});
914
914
  try {
915
915
  let i = await r.loadHeroTalents(t, this.#e.signal);
916
916
  if (n !== this.#t || this.#e.signal.aborted) return;
917
- if (i.manifest.schemaVersion !== 1) throw new e("unsupported-schema", `Unsupported fellowship-data schema version: ${String(i.manifest.schemaVersion)}.`);
918
- let a = b(i, r);
917
+ e(i.manifest.schemaVersion);
918
+ let a = x(i, r);
919
919
  this._model = a, this._status = "ready";
920
920
  let o = this.#m(!1);
921
921
  await this.updateComplete;
922
922
  let s = this.selectionState;
923
923
  this.dispatchEvent(new CustomEvent("fellowship-talents-ready", {
924
- ...D,
924
+ ...O,
925
925
  detail: {
926
926
  data: i,
927
927
  model: a,
@@ -935,7 +935,7 @@ var g = (e = {}) => {
935
935
  }
936
936
  #m(e) {
937
937
  if (!this._model) return !1;
938
- let t = C(this._model, this.selectedTalentIds);
938
+ let t = w(this._model, this.selectedTalentIds);
939
939
  return t.selectedTalentIds.length !== this.selectedTalentIds.length || t.selectedTalentIds.some((e, t) => e !== this.selectedTalentIds[t]) ? (this.selectedTalentIds = t.selectedTalentIds, t.removedTalentIds.length > 0 && this.#x([{
940
940
  code: "invalid-selection",
941
941
  message: `Removed unavailable talent selections: ${t.removedTalentIds.join(", ")}.`,
@@ -954,13 +954,13 @@ var g = (e = {}) => {
954
954
  this.selectedTalentIds = [...this.selectionState.selectedTalentIds, e.talent.id], this.#_("user");
955
955
  }
956
956
  #g(e, t) {
957
- let n = S(e), r = this.selectionState;
957
+ let n = C(e), r = this.selectionState;
958
958
  n === this.talentPoints || n < r.spentPoints || (this.talentPoints = n, this.#r = !0, this.#v(t));
959
959
  }
960
960
  #_(e) {
961
- let t = this._model ? w(this._model, this.selectedTalentIds, this.talentPoints) : A(this.talentPoints);
961
+ let t = this._model ? T(this._model, this.selectedTalentIds, this.talentPoints) : j(this.talentPoints);
962
962
  this.dispatchEvent(new CustomEvent("fellowship-talent-selection-change", {
963
- ...D,
963
+ ...O,
964
964
  detail: {
965
965
  ...t,
966
966
  source: e
@@ -970,7 +970,7 @@ var g = (e = {}) => {
970
970
  #v(e) {
971
971
  let t = this.selectionState;
972
972
  this.dispatchEvent(new CustomEvent("fellowship-talent-points-change", {
973
- ...D,
973
+ ...O,
974
974
  detail: {
975
975
  ...t,
976
976
  talentPoints: this.talentPoints,
@@ -1001,7 +1001,7 @@ var g = (e = {}) => {
1001
1001
  }
1002
1002
  #x(e) {
1003
1003
  this.dispatchEvent(new CustomEvent("fellowship-talents-warning", {
1004
- ...D,
1004
+ ...O,
1005
1005
  detail: {
1006
1006
  warnings: e,
1007
1007
  model: this._model
@@ -1013,44 +1013,44 @@ var g = (e = {}) => {
1013
1013
  let e = this.#a;
1014
1014
  this.#a = [], this.#x(e);
1015
1015
  }
1016
- #C(t) {
1017
- let n = typeof t == "object" && t && "code" in t && "message" in t ? {
1018
- code: String(t.code),
1019
- message: String(t.message),
1020
- ...t instanceof e && t.cause !== void 0 ? { cause: t.cause } : {}
1016
+ #C(e) {
1017
+ let n = typeof e == "object" && e && "code" in e && "message" in e ? {
1018
+ code: String(e.code),
1019
+ message: String(e.message),
1020
+ ...e instanceof t && e.cause !== void 0 ? { cause: e.cause } : {}
1021
1021
  } : {
1022
1022
  code: "unknown",
1023
- message: t instanceof Error ? t.message : String(t)
1023
+ message: e instanceof Error ? e.message : String(e)
1024
1024
  };
1025
1025
  this._error = n, this._status = "error", this.dispatchEvent(new CustomEvent("fellowship-talents-error", {
1026
- ...D,
1026
+ ...O,
1027
1027
  detail: n
1028
1028
  }));
1029
1029
  }
1030
1030
  };
1031
- r([f({
1031
+ i([p({
1032
1032
  type: String,
1033
1033
  attribute: "hero-id"
1034
- })], j.prototype, "heroId", void 0), r([f({
1034
+ })], M.prototype, "heroId", void 0), i([p({
1035
1035
  type: Number,
1036
1036
  attribute: "talent-points"
1037
- })], j.prototype, "talentPoints", void 0), r([f({
1037
+ })], M.prototype, "talentPoints", void 0), i([p({
1038
1038
  attribute: !1,
1039
- hasChanged: O
1040
- })], j.prototype, "selectedTalentIds", void 0), r([f({
1039
+ hasChanged: k
1040
+ })], M.prototype, "selectedTalentIds", void 0), i([p({
1041
1041
  type: String,
1042
1042
  attribute: "asset-base-url"
1043
- })], j.prototype, "assetBaseUrl", void 0), r([f({ attribute: !1 })], j.prototype, "dataSource", void 0), r([f({ attribute: !1 })], j.prototype, "renderTalent", void 0), r([f({
1043
+ })], M.prototype, "assetBaseUrl", void 0), i([p({ attribute: !1 })], M.prototype, "dataSource", void 0), i([p({ attribute: !1 })], M.prototype, "renderTalent", void 0), i([p({
1044
1044
  type: Boolean,
1045
1045
  attribute: "show-point-controls"
1046
- })], j.prototype, "showPointControls", void 0), r([f({
1046
+ })], M.prototype, "showPointControls", void 0), i([p({
1047
1047
  type: Boolean,
1048
1048
  attribute: "show-tooltips"
1049
- })], j.prototype, "showTooltips", void 0), r([p()], j.prototype, "_status", void 0), r([p()], j.prototype, "_error", void 0), r([p()], j.prototype, "_model", void 0), r([p()], j.prototype, "_failedImages", void 0), r([p()], j.prototype, "_announcement", void 0), r([p()], j.prototype, "_renderSelectionState", void 0), r([p()], j.prototype, "_talentPresentation", void 0), r([p()], j.prototype, "_talentRenderContent", void 0), j = r([d("fellowship-talent-calculator")], j);
1050
- var M = () => {
1051
- a(), customElements.get("fellowship-talent-calculator") || customElements.define("fellowship-talent-calculator", j);
1049
+ })], M.prototype, "showTooltips", void 0), i([m()], M.prototype, "_status", void 0), i([m()], M.prototype, "_error", void 0), i([m()], M.prototype, "_model", void 0), i([m()], M.prototype, "_failedImages", void 0), i([m()], M.prototype, "_announcement", void 0), i([m()], M.prototype, "_renderSelectionState", void 0), i([m()], M.prototype, "_talentPresentation", void 0), i([m()], M.prototype, "_talentRenderContent", void 0), M = i([f("fellowship-talent-calculator")], M);
1050
+ var N = () => {
1051
+ o(), customElements.get("fellowship-talent-calculator") || customElements.define("fellowship-talent-calculator", M);
1052
1052
  };
1053
1053
  //#endregion
1054
- export { T as a, S as c, g as d, x as i, b as l, M as n, w as o, k as r, C as s, j as t, v as u };
1054
+ export { E as a, C as c, _ as d, S as i, x as l, N as n, T as o, A as r, w as s, M as t, y as u };
1055
1055
 
1056
- //# sourceMappingURL=talent-calculator-CIPNbqK5.js.map
1056
+ //# sourceMappingURL=talent-calculator-Dxuc2dZ8.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"talent-calculator-Dxuc2dZ8.js","names":["#abortController","#flushRendererWarnings","#loadHeroTalents","#skipNextPropertyPointEvent","#emitPointsChange","#normalizeSelections","#reportOverBudget","#rendererFailures","#prepareTalentRenderContent","#emitSelectionChange","#renderHeader","#renderGrid","#renderStatus","#setTalentPoints","#renderTalent","#handleTalentActivation","#renderTalentContent","#pendingRendererWarnings","#renderDefaultTalentIcon","#handleImageError","#loadToken","#lastOverBudgetSignature","#reportWarnings","#setError"],"sources":["../../src/data/package-talent-data-source.ts","../../src/talent-calculator/render-model.ts","../../src/talent-calculator/selection-state.ts","../../src/talent-calculator/talent-calculator.styles.ts","../../src/talent-calculator/talent-calculator.ts"],"sourcesContent":["import { createPackageFellowshipDataClient } from \"@crockery/fellowship-data/client\";\n\nimport type { FellowshipTalentDataSource } from \"./talent-data-source.js\";\n\n/** @deprecated Create a package Fellowship data client instead. */\nexport interface PackageFellowshipTalentDataSourceOptions {\n readonly assetBaseUrl?: string;\n}\n\n/** @deprecated Use `createPackageFellowshipDataClient` from `@crockery/fellowship-data/client`. */\nexport const createPackageFellowshipTalentDataSource = (\n options: PackageFellowshipTalentDataSourceOptions = {},\n): FellowshipTalentDataSource => {\n const client = createPackageFellowshipDataClient(options);\n return {\n loadHeroTalents: (heroId, signal) => client.loadHeroTalents(heroId, signal),\n resolveAssetUrl: (asset) => client.resolveAssetUrl(asset),\n };\n};\n","import { findImage } from \"@crockery/fellowship-data\";\nimport type { Talent } from \"@crockery/fellowship-data\";\n\nimport type {\n FellowshipTalentDataSource,\n TalentCalculatorData,\n} from \"../data/talent-data-source.js\";\nimport type {\n TalentCalculatorRenderModel,\n TalentCalculatorTalentModel,\n TalentCalculatorWarning,\n} from \"./types.js\";\n\nconst romanNumerals = [\"I\", \"II\", \"III\", \"IV\", \"V\", \"VI\"] as const;\n\nexport const talentRowLabel = (row: number): string => romanNumerals[row - 1] ?? String(row);\n\nconst warning = (\n code: TalentCalculatorWarning[\"code\"],\n talent: Talent,\n message: string,\n): TalentCalculatorWarning => ({ code, message, talentId: talent.id });\n\nexport const createTalentCalculatorRenderModel = (\n data: TalentCalculatorData,\n source: FellowshipTalentDataSource,\n): TalentCalculatorRenderModel => {\n const warnings: TalentCalculatorWarning[] = [];\n const occupied = new Set<string>();\n const models: TalentCalculatorTalentModel[] = [];\n\n for (const talent of data.talents) {\n if (talent.row === null && talent.column === null) {\n continue;\n }\n if (\n !Number.isInteger(talent.row) ||\n !Number.isInteger(talent.column) ||\n talent.row === null ||\n talent.column === null ||\n talent.row < 1 ||\n talent.row > 6 ||\n talent.column < 1 ||\n talent.column > 3\n ) {\n warnings.push(\n warning(\n \"invalid-position\",\n talent,\n `Talent “${talent.id}” has an invalid row or column and was skipped.`,\n ),\n );\n continue;\n }\n\n const cell = `${talent.row}:${talent.column}`;\n if (occupied.has(cell)) {\n warnings.push(\n warning(\n \"duplicate-position\",\n talent,\n `Talent “${talent.id}” duplicates row ${talent.row}, column ${talent.column} and was skipped.`,\n ),\n );\n continue;\n }\n occupied.add(cell);\n\n const pointCost =\n Number.isInteger(talent.pointCost) && (talent.pointCost ?? 0) > 0 ? talent.pointCost : null;\n if (pointCost === null) {\n warnings.push(\n warning(\"invalid-cost\", talent, `Talent “${talent.id}” has an invalid point cost.`),\n );\n }\n if (!talent.name) {\n warnings.push(warning(\"missing-name\", talent, `Talent “${talent.id}” has no display name.`));\n }\n if (!talent.description) {\n warnings.push(\n warning(\"missing-description\", talent, `Talent “${talent.id}” has no description.`),\n );\n }\n\n const image =\n findImage(talent.images, { type: \"talent\", size: \"200\" }) ??\n findImage(talent.images, { type: \"talent\", size: \"full\" });\n let imageUrl: string | null = null;\n if (!image) {\n warnings.push(warning(\"missing-image\", talent, `Talent “${talent.id}” has no icon.`));\n } else {\n try {\n imageUrl = source.resolveAssetUrl(image);\n } catch (error: unknown) {\n warnings.push(\n warning(\n \"asset-url-error\",\n talent,\n `The icon URL for talent “${talent.id}” could not be resolved: ${String(error)}.`,\n ),\n );\n }\n }\n\n models.push({\n talent,\n row: talent.row,\n column: talent.column,\n pointCost,\n imageUrl,\n });\n }\n\n models.sort((a, b) => a.row - b.row || a.column - b.column);\n const talentById = new Map(models.map((model) => [model.talent.id, model]));\n const rows = [...new Set(models.map(({ row }) => row))].map((row) => ({\n row,\n label: talentRowLabel(row),\n talents: models.filter((talent) => talent.row === row),\n }));\n\n return { hero: data.hero, rows, talentById, warnings };\n};\n","import type { TalentCalculatorRenderModel, TalentCalculatorSelectionState } from \"./types.js\";\n\nexport const MAX_TALENT_POINTS = 14;\n\nexport const normalizeTalentPoints = (value: number): number =>\n Math.min(\n MAX_TALENT_POINTS,\n Math.max(0, Math.round(Number.isFinite(value) ? value : MAX_TALENT_POINTS)),\n );\n\nexport const normalizeSelectedTalentIds = (\n model: TalentCalculatorRenderModel,\n selectedTalentIds: readonly string[],\n): {\n readonly selectedTalentIds: readonly string[];\n readonly removedTalentIds: readonly string[];\n} => {\n const requested = new Set(selectedTalentIds);\n const selected = [...model.talentById.values()]\n .filter(({ talent }) => requested.has(talent.id))\n .map(({ talent }) => talent.id);\n const selectedSet = new Set(selected);\n const removed = [...new Set(selectedTalentIds)].filter((id) => !selectedSet.has(id));\n return { selectedTalentIds: selected, removedTalentIds: removed };\n};\n\nexport const createTalentCalculatorSelectionState = (\n model: TalentCalculatorRenderModel,\n selectedTalentIds: readonly string[],\n talentPoints: number,\n): TalentCalculatorSelectionState => {\n const selected = new Set(selectedTalentIds);\n const spentPoints = [...model.talentById.values()].reduce(\n (total, talent) =>\n selected.has(talent.talent.id) && talent.pointCost !== null\n ? total + talent.pointCost\n : total,\n 0,\n );\n const remainingPoints = talentPoints - spentPoints;\n return {\n selectedTalentIds: [...model.talentById.values()]\n .filter(({ talent }) => selected.has(talent.id))\n .map(({ talent }) => talent.id),\n spentPoints,\n remainingPoints,\n overBudget: remainingPoints < 0,\n };\n};\n\nexport const canSelectTalent = (\n pointCost: number | null,\n state: TalentCalculatorSelectionState,\n): boolean => pointCost !== null && !state.overBudget && pointCost <= state.remainingPoints;\n","import { css } from \"lit\";\n\nexport const talentCalculatorStyles = css`\n :host {\n --fellowship-talent-background: var(--_fellowship-field-canvas);\n --fellowship-talent-surface: var(--_fellowship-field-surface);\n --fellowship-talent-card-background: var(--_fellowship-field-surface);\n --fellowship-talent-card-selected-background: color-mix(\n in srgb,\n var(--_fellowship-field-surface-raised) 88%,\n var(--_fellowship-field-accent)\n );\n --fellowship-talent-foreground: var(--_fellowship-field-ink);\n --fellowship-talent-muted: var(--_fellowship-field-muted);\n --fellowship-talent-disabled: var(--_fellowship-field-tertiary);\n --fellowship-talent-border: var(--_fellowship-field-border);\n --fellowship-talent-selection: var(--_fellowship-field-accent);\n --fellowship-talent-focus: var(--_fellowship-field-focus);\n --fellowship-talent-points: var(--_fellowship-field-brass);\n --fellowship-talent-danger: var(--_fellowship-field-ember);\n --fellowship-talent-control-surface: var(--_fellowship-field-inset);\n --fellowship-talent-icon-size: 56px;\n --fellowship-talent-font-family: var(--_fellowship-field-font-family);\n --fellowship-talent-tactical-font-family: var(--_fellowship-field-mono-font-family);\n --fellowship-talent-radius: var(--_fellowship-field-radius);\n\n display: block;\n min-width: 0;\n container-type: inline-size;\n color: var(--fellowship-talent-foreground);\n font-family: var(--fellowship-talent-font-family);\n -webkit-font-smoothing: antialiased;\n }\n\n :host([hidden]) {\n display: none;\n }\n\n *,\n *::before,\n *::after {\n box-sizing: border-box;\n }\n\n button {\n font: inherit;\n }\n\n .container {\n min-width: 0;\n padding: 16px;\n border-radius: calc(var(--fellowship-talent-radius) + 2px);\n background: var(--fellowship-talent-background);\n }\n\n .header {\n min-height: 72px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 24px;\n padding: 8px 8px 24px;\n }\n\n .heading {\n margin: 0;\n color: var(--fellowship-talent-muted);\n font-size: 12px;\n font-weight: 600;\n line-height: 16px;\n letter-spacing: 0.12em;\n text-transform: uppercase;\n }\n\n .points-cluster,\n .point-controls {\n display: flex;\n align-items: center;\n }\n\n .points-cluster {\n gap: 16px;\n }\n\n .points {\n display: flex;\n align-items: baseline;\n gap: 4px;\n color: var(--fellowship-talent-foreground);\n font-family: var(--fellowship-talent-tactical-font-family);\n font-size: 32px;\n font-weight: 600;\n line-height: 40px;\n letter-spacing: -0.04em;\n font-variant-numeric: tabular-nums;\n }\n\n .points-spent {\n color: var(--fellowship-talent-points);\n }\n\n .points-separator,\n .points-total {\n color: var(--_fellowship-field-tertiary);\n }\n\n .points-separator {\n font-size: 18px;\n font-weight: 500;\n }\n\n .points[data-invalid=\"true\"],\n .points[data-invalid=\"true\"] .points-spent {\n color: var(--fellowship-talent-danger);\n }\n\n .point-controls {\n gap: 4px;\n padding: 2px;\n border-radius: calc(var(--fellowship-talent-radius) + 2px);\n background: var(--fellowship-talent-control-surface);\n box-shadow: inset 0 0 0 1px var(--fellowship-talent-border);\n }\n\n .point-control {\n width: 40px;\n height: 40px;\n display: inline-grid;\n place-items: center;\n padding: 0;\n border: 0;\n border-radius: 4px;\n background: transparent;\n color: var(--fellowship-talent-muted);\n font-family: var(--fellowship-talent-tactical-font-family);\n font-size: 18px;\n font-weight: 500;\n line-height: 1;\n cursor: pointer;\n transition:\n background-color 120ms cubic-bezier(0.23, 1, 0.32, 1),\n color 120ms cubic-bezier(0.23, 1, 0.32, 1),\n transform 120ms cubic-bezier(0.23, 1, 0.32, 1);\n }\n\n .point-control:active:not(:disabled) {\n transform: scale(0.97);\n }\n\n .point-control:focus-visible,\n .clear-all:focus-visible,\n .talent:focus-visible,\n .retry-button:focus-visible {\n outline: 2px solid var(--fellowship-talent-focus);\n outline-offset: 2px;\n }\n\n .point-control:disabled {\n color: var(--fellowship-talent-disabled);\n cursor: not-allowed;\n opacity: 0.48;\n }\n\n .clear-all {\n min-height: 44px;\n padding: 0 8px;\n border: 0;\n border-radius: 4px;\n background: transparent;\n color: var(--fellowship-talent-muted);\n font-size: 12px;\n font-weight: 600;\n line-height: 1;\n letter-spacing: 0.04em;\n white-space: nowrap;\n cursor: pointer;\n transition:\n background-color 120ms cubic-bezier(0.23, 1, 0.32, 1),\n color 120ms cubic-bezier(0.23, 1, 0.32, 1),\n transform 120ms cubic-bezier(0.23, 1, 0.32, 1);\n }\n\n .clear-all:active:not(:disabled) {\n transform: scale(0.97);\n }\n\n .clear-all:disabled {\n color: var(--fellowship-talent-disabled);\n cursor: not-allowed;\n opacity: 0.42;\n }\n\n .grid {\n display: grid;\n gap: 16px;\n padding: 8px 0 0;\n }\n\n .row {\n min-width: 0;\n min-inline-size: 0;\n width: 100%;\n display: grid;\n grid-template-columns: 48px minmax(0, 1fr);\n align-items: stretch;\n gap: 8px;\n margin: 0;\n padding: 0;\n border: 0;\n }\n\n .row-label {\n position: relative;\n display: flex;\n align-items: flex-start;\n justify-content: center;\n padding-top: 16px;\n color: var(--fellowship-talent-disabled);\n font-family: var(--fellowship-talent-tactical-font-family);\n font-size: 11px;\n font-weight: 600;\n line-height: 16px;\n text-align: center;\n letter-spacing: 0.08em;\n }\n\n .row-label::before {\n position: absolute;\n inset: 0 0 0 auto;\n width: 1px;\n background: var(--fellowship-talent-border);\n content: \"\";\n }\n\n .row-label::after {\n position: absolute;\n top: 23px;\n right: -3px;\n width: 7px;\n height: 1px;\n background: var(--fellowship-talent-selection);\n content: \"\";\n }\n\n .row-talents {\n min-width: 0;\n display: grid;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: 8px;\n }\n\n fellowship-tooltip {\n display: block;\n min-width: 0;\n }\n\n .talent {\n position: relative;\n width: 100%;\n min-width: 0;\n min-height: 88px;\n display: grid;\n grid-template-columns: var(--fellowship-talent-icon-size) minmax(0, 1fr);\n align-items: center;\n gap: 16px;\n padding: 16px 36px 16px 16px;\n overflow: hidden;\n border: 1px solid transparent;\n border-radius: var(--fellowship-talent-radius);\n background: var(--fellowship-talent-card-background);\n color: var(--fellowship-talent-foreground);\n box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--fellowship-talent-border) 64%, transparent);\n text-align: left;\n cursor: pointer;\n transition:\n background-color 140ms cubic-bezier(0.23, 1, 0.32, 1),\n box-shadow 140ms cubic-bezier(0.23, 1, 0.32, 1),\n transform 120ms cubic-bezier(0.23, 1, 0.32, 1),\n opacity 140ms linear;\n }\n\n .talent::before {\n position: absolute;\n top: 16px;\n left: 0;\n width: 2px;\n height: 24px;\n background: transparent;\n content: \"\";\n }\n\n .talent:active:not([aria-disabled=\"true\"]) {\n transform: scale(0.99);\n }\n\n .talent[aria-pressed=\"true\"] {\n background: var(--fellowship-talent-card-selected-background);\n box-shadow: inset 0 0 0 1px\n color-mix(in srgb, var(--fellowship-talent-selection) 32%, transparent);\n }\n\n .talent[aria-pressed=\"true\"]::before {\n background: var(--fellowship-talent-selection);\n }\n\n .talent[aria-disabled=\"true\"] {\n color: var(--fellowship-talent-disabled);\n cursor: not-allowed;\n opacity: 0.46;\n }\n\n .talent-icon,\n .talent-icon-fallback {\n width: var(--fellowship-talent-icon-size);\n height: var(--fellowship-talent-icon-size);\n border-radius: calc(var(--fellowship-talent-radius) - 2px);\n box-shadow: inset 0 0 0 1px var(--fellowship-talent-border);\n }\n\n .talent-icon {\n display: block;\n object-fit: cover;\n }\n\n .talent-icon-fallback {\n display: grid;\n place-items: center;\n background: var(--fellowship-talent-control-surface);\n color: var(--fellowship-talent-muted);\n font-family: var(--fellowship-talent-tactical-font-family);\n font-size: 13px;\n font-weight: 600;\n letter-spacing: 0.08em;\n }\n\n .talent[aria-pressed=\"true\"] .talent-icon,\n .talent[aria-pressed=\"true\"] .talent-icon-fallback {\n box-shadow:\n inset 0 0 0 1px var(--fellowship-talent-border),\n 0 0 0 1px color-mix(in srgb, var(--fellowship-talent-selection) 60%, transparent);\n }\n\n .talent-name {\n min-width: 0;\n overflow: hidden;\n color: currentColor;\n font-size: 16px;\n font-weight: 600;\n line-height: 24px;\n text-overflow: ellipsis;\n text-wrap: balance;\n white-space: nowrap;\n }\n\n .talent-cost {\n position: absolute;\n top: 12px;\n right: 12px;\n color: var(--fellowship-talent-muted);\n font-family: var(--fellowship-talent-tactical-font-family);\n font-size: 11px;\n font-weight: 600;\n line-height: 16px;\n font-variant-numeric: tabular-nums;\n }\n\n .talent[aria-pressed=\"true\"] .talent-cost {\n color: var(--fellowship-talent-focus);\n }\n\n .status {\n min-height: 256px;\n display: grid;\n place-items: center;\n padding: 32px;\n color: var(--fellowship-talent-muted);\n text-align: center;\n }\n\n .status-card {\n max-width: 480px;\n }\n\n .status-mark {\n display: flex;\n width: 40px;\n height: 24px;\n align-items: center;\n justify-content: space-between;\n margin: 0 auto 16px;\n color: var(--fellowship-talent-points);\n font-family: var(--fellowship-talent-tactical-font-family);\n font-size: 16px;\n }\n\n .status-mark::before,\n .status-mark::after {\n width: 8px;\n height: 1px;\n background: var(--fellowship-talent-border);\n content: \"\";\n }\n\n .status-title {\n margin: 0;\n color: var(--fellowship-talent-foreground);\n font-size: 18px;\n font-weight: 600;\n line-height: 24px;\n text-wrap: balance;\n }\n\n .status-copy {\n margin: 8px 0 0;\n font-size: 14px;\n line-height: 24px;\n text-wrap: pretty;\n }\n\n .retry-button {\n min-height: 44px;\n margin-top: 24px;\n padding: 0 16px;\n border: 1px solid var(--fellowship-talent-border);\n border-radius: 4px;\n background: var(--fellowship-talent-control-surface);\n color: var(--fellowship-talent-foreground);\n font-weight: 600;\n cursor: pointer;\n }\n\n .visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n\n @media (hover: hover) {\n .point-control:hover:not(:disabled) {\n background: var(--fellowship-talent-surface);\n color: var(--fellowship-talent-foreground);\n }\n\n .clear-all:hover:not(:disabled) {\n background: color-mix(in srgb, var(--fellowship-talent-danger) 8%, transparent);\n color: var(--fellowship-talent-danger);\n }\n\n .talent:hover:not([aria-disabled=\"true\"]) {\n background: var(--_fellowship-field-surface-raised);\n box-shadow: inset 0 0 0 1px var(--fellowship-talent-border);\n }\n }\n\n @container (max-width: 719px) {\n .container {\n padding: 16px 12px;\n }\n\n .header {\n min-height: 80px;\n grid-template-columns: 1fr;\n display: grid;\n gap: 8px;\n padding: 4px 4px 20px;\n }\n\n .heading {\n font-size: 11px;\n }\n\n .points-cluster {\n width: 100%;\n flex-wrap: wrap;\n justify-content: flex-start;\n gap: 8px;\n }\n\n .points {\n font-size: 28px;\n line-height: 36px;\n }\n\n .grid {\n gap: 24px;\n }\n\n .row {\n grid-template-columns: 1fr;\n gap: 8px;\n }\n\n .row-label {\n min-height: 24px;\n align-items: center;\n justify-content: flex-start;\n padding: 0 0 0 16px;\n text-align: left;\n }\n\n .row-label::before {\n inset: 12px auto auto 0;\n width: 8px;\n height: 1px;\n }\n\n .row-label::after {\n top: 9px;\n right: auto;\n left: 0;\n width: 1px;\n height: 7px;\n }\n\n .row-talents {\n grid-template-columns: 1fr;\n gap: 8px;\n }\n\n .talent {\n --fellowship-talent-icon-size: 52px;\n\n min-height: 80px;\n padding-block: 12px;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .point-control,\n .clear-all,\n .talent {\n transition:\n background-color 100ms linear,\n box-shadow 100ms linear,\n color 100ms linear,\n opacity 100ms linear;\n }\n\n .point-control:active:not(:disabled),\n .clear-all:active:not(:disabled),\n .talent:active:not([aria-disabled=\"true\"]) {\n transform: none;\n }\n }\n`;\n","import { html, LitElement, nothing, type PropertyValues, type TemplateResult } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { repeat } from \"lit/directives/repeat.js\";\n\nimport { assertSupportedFellowshipDataSchema, FellowshipDataError } from \"../data/data-source.js\";\nimport { createPackageFellowshipTalentDataSource } from \"../data/package-talent-data-source.js\";\nimport type { FellowshipTalentDataSource } from \"../data/talent-data-source.js\";\nimport { fieldManualStyles } from \"../styles/field-manual.styles.js\";\nimport { installFieldManualFonts } from \"../styles/field-manual-fonts.js\";\nimport { stripFellowshipRichText } from \"../tooltip/rich-text.js\";\nimport { defineFellowshipTooltip } from \"../tooltip/tooltip.js\";\nimport { createTalentCalculatorRenderModel } from \"./render-model.js\";\nimport {\n canSelectTalent,\n createTalentCalculatorSelectionState,\n MAX_TALENT_POINTS,\n normalizeSelectedTalentIds,\n normalizeTalentPoints,\n} from \"./selection-state.js\";\nimport { talentCalculatorStyles } from \"./talent-calculator.styles.js\";\nimport type {\n FellowshipTalentsErrorDetail,\n FellowshipTalentsReadyDetail,\n FellowshipTalentsWarningDetail,\n LitTalentRenderer,\n TalentCalculatorRenderModel,\n TalentCalculatorSelectionState,\n TalentCalculatorTalentModel,\n TalentCalculatorTalentRenderContext,\n TalentCalculatorWarning,\n TalentPointsChangeDetail,\n TalentPointsChangeSource,\n TalentSelectionChangeDetail,\n TalentSelectionChangeSource,\n} from \"./types.js\";\n\ntype ComponentStatus = \"empty\" | \"loading\" | \"ready\" | \"error\";\n\ninterface TalentPresentation {\n readonly context: TalentCalculatorTalentRenderContext;\n readonly name: string;\n readonly descriptionId: string;\n readonly affordability: string;\n readonly description: string;\n}\n\nconst eventOptions = { bubbles: true, composed: true } as const;\n\nconst stringArrayChanged = (\n value: readonly string[],\n previous: readonly string[] | undefined,\n): boolean =>\n value.length !== previous?.length || value.some((item, index) => item !== previous[index]);\n\nexport const talentSlotName = (talentId: string): string => `talent:${talentId}`;\n\nconst fallbackSelectionState = (talentPoints: number): TalentCalculatorSelectionState => ({\n selectedTalentIds: [],\n spentPoints: 0,\n remainingPoints: talentPoints,\n overBudget: false,\n});\n\nexport { MAX_TALENT_POINTS };\n\n/**\n * @fires fellowship-talents-ready - Fired after talent data is loaded and rendered.\n * @fires fellowship-talents-error - Fired when talent data cannot be loaded.\n * @fires fellowship-talents-warning - Fired for recoverable data and renderer issues.\n * @fires fellowship-talent-selection-change - Fired when selected talents change.\n * @fires fellowship-talent-points-change - Fired when the point budget changes.\n */\n@customElement(\"fellowship-talent-calculator\")\nexport class FellowshipTalentCalculatorElement extends LitElement {\n static override styles = [fieldManualStyles, talentCalculatorStyles];\n\n @property({ type: String, attribute: \"hero-id\" }) heroId = \"\";\n @property({ type: Number, attribute: \"talent-points\" }) talentPoints = MAX_TALENT_POINTS;\n @property({ attribute: false, hasChanged: stringArrayChanged })\n selectedTalentIds: readonly string[] = [];\n @property({ type: String, attribute: \"asset-base-url\" }) assetBaseUrl: string | null = null;\n @property({ attribute: false }) dataSource: FellowshipTalentDataSource | null = null;\n @property({ attribute: false }) renderTalent: LitTalentRenderer | null = null;\n @property({ type: Boolean, attribute: \"show-point-controls\" }) showPointControls = true;\n @property({ type: Boolean, attribute: \"show-tooltips\" }) showTooltips = true;\n\n @state() private _status: ComponentStatus = \"empty\";\n @state() private _error: FellowshipTalentsErrorDetail | null = null;\n @state() private _model: TalentCalculatorRenderModel | null = null;\n @state() private _failedImages = new Set<string>();\n @state() private _announcement = \"\";\n @state() private _renderSelectionState = fallbackSelectionState(MAX_TALENT_POINTS);\n @state() private _talentPresentation = new Map<string, TalentPresentation>();\n @state() private _talentRenderContent = new Map<string, unknown>();\n\n #abortController: AbortController | null = null;\n #loadToken = 0;\n #lastOverBudgetSignature: string | null = null;\n #skipNextPropertyPointEvent = false;\n #rendererFailures = new Set<string>();\n #pendingRendererWarnings: TalentCalculatorWarning[] = [];\n\n override connectedCallback(): void {\n super.connectedCallback();\n installFieldManualFonts(this.ownerDocument);\n }\n\n override disconnectedCallback(): void {\n this.#abortController?.abort();\n super.disconnectedCallback();\n }\n\n protected override updated(changed: PropertyValues<this>): void {\n super.updated(changed);\n this.#flushRendererWarnings();\n\n if (changed.has(\"heroId\") || changed.has(\"dataSource\") || changed.has(\"assetBaseUrl\")) {\n queueMicrotask(() => {\n if (this.isConnected) {\n void this.#loadHeroTalents();\n }\n });\n return;\n }\n\n if (changed.has(\"talentPoints\")) {\n const normalized = normalizeTalentPoints(this.talentPoints);\n if (normalized !== this.talentPoints) {\n this.#skipNextPropertyPointEvent = true;\n this.talentPoints = normalized;\n this.#emitPointsChange(\"normalization\");\n return;\n }\n if (this.#skipNextPropertyPointEvent) {\n this.#skipNextPropertyPointEvent = false;\n } else if (changed.get(\"talentPoints\") !== undefined) {\n this.#emitPointsChange(\"property\");\n }\n }\n\n if (changed.has(\"selectedTalentIds\") && this._model) {\n this.#normalizeSelections(true);\n }\n\n this.#reportOverBudget();\n }\n\n protected override willUpdate(changed: PropertyValues): void {\n super.willUpdate(changed);\n\n const selectionChanged =\n changed.has(\"_model\") || changed.has(\"selectedTalentIds\") || changed.has(\"talentPoints\");\n if (selectionChanged) {\n this._renderSelectionState = this._model\n ? createTalentCalculatorSelectionState(\n this._model,\n this.selectedTalentIds,\n this.talentPoints,\n )\n : fallbackSelectionState(this.talentPoints);\n }\n\n if (changed.has(\"renderTalent\")) {\n this.#rendererFailures.clear();\n }\n if (selectionChanged || changed.has(\"renderTalent\")) {\n this.#prepareTalentRenderContent(this._renderSelectionState);\n }\n }\n\n get renderModel(): TalentCalculatorRenderModel | null {\n return this._model;\n }\n\n get selectionState(): TalentCalculatorSelectionState {\n return this._model\n ? createTalentCalculatorSelectionState(this._model, this.selectedTalentIds, this.talentPoints)\n : fallbackSelectionState(this.talentPoints);\n }\n\n reset(): void {\n if (this.selectedTalentIds.length === 0) {\n return;\n }\n this.selectedTalentIds = [];\n this.#emitSelectionChange(\"reset\");\n }\n\n selectTalent(talentId: string): boolean {\n const model = this._model?.talentById.get(talentId);\n const state = this.selectionState;\n if (\n !model ||\n state.selectedTalentIds.includes(talentId) ||\n !canSelectTalent(model.pointCost, state)\n ) {\n return false;\n }\n this.selectedTalentIds = [...state.selectedTalentIds, talentId];\n this.#emitSelectionChange(\"api\");\n return true;\n }\n\n deselectTalent(talentId: string): boolean {\n if (!this.selectionState.selectedTalentIds.includes(talentId)) {\n return false;\n }\n this.selectedTalentIds = this.selectionState.selectedTalentIds.filter((id) => id !== talentId);\n this.#emitSelectionChange(\"api\");\n return true;\n }\n\n retry(): void {\n void this.#loadHeroTalents();\n }\n\n override render(): TemplateResult {\n const state = this._renderSelectionState;\n const label = this._model?.hero.name ?? this._model?.hero.id ?? \"Fellowship hero\";\n return html`\n <section\n class=\"container\"\n part=\"container\"\n aria-label=${`${label} talent calculator`}\n aria-invalid=${String(state.overBudget)}\n >\n ${this.#renderHeader(state)}\n ${\n this._status === \"ready\" && this._model\n ? this.#renderGrid(this._model)\n : this.#renderStatus()\n }\n <p class=\"visually-hidden\" role=\"status\" aria-live=\"polite\">${this._announcement}</p>\n </section>\n `;\n }\n\n #renderHeader(state: TalentCalculatorSelectionState): TemplateResult {\n return html`\n <header class=\"header\" part=\"header\">\n <h2 class=\"heading\" part=\"heading\">Talent points</h2>\n <div class=\"points-cluster\">\n <div\n class=\"points\"\n part=\"points\"\n data-invalid=${String(state.overBudget)}\n aria-label=${`${state.spentPoints} of ${this.talentPoints} talent points spent`}\n aria-live=\"polite\"\n >\n <span class=\"points-spent\" part=\"points-spent\">${state.spentPoints}</span>\n <span class=\"points-separator\" aria-hidden=\"true\">/</span>\n <span class=\"points-total\" part=\"points-total\">${this.talentPoints}</span>\n </div>\n ${\n this.showPointControls\n ? html`\n <div\n class=\"point-controls\"\n part=\"point-controls\"\n role=\"group\"\n aria-label=\"Talent points\"\n >\n <button\n class=\"point-control\"\n part=\"point-control\"\n type=\"button\"\n aria-label=\"Decrease available talent points\"\n title=\"Decrease available talent points\"\n ?disabled=${this.talentPoints <= state.spentPoints}\n @click=${() => this.#setTalentPoints(this.talentPoints - 1, \"decrement\")}\n >\n −\n </button>\n <button\n class=\"point-control\"\n part=\"point-control\"\n type=\"button\"\n aria-label=\"Increase available talent points\"\n title=\"Increase available talent points\"\n ?disabled=${this.talentPoints >= MAX_TALENT_POINTS}\n @click=${() => this.#setTalentPoints(this.talentPoints + 1, \"increment\")}\n >\n +\n </button>\n </div>\n `\n : nothing\n }\n <button\n class=\"clear-all\"\n part=\"clear-all\"\n type=\"button\"\n ?disabled=${state.selectedTalentIds.length === 0}\n @click=${this.reset}\n >\n Clear All\n </button>\n </div>\n </header>\n `;\n }\n\n #renderGrid(model: TalentCalculatorRenderModel): TemplateResult {\n if (model.rows.length === 0) {\n return html`\n <div class=\"status\" part=\"empty-state\" role=\"status\">\n <div class=\"status-card\">\n <div class=\"status-mark\" aria-hidden=\"true\">◇</div>\n <p class=\"status-title\">No active talents</p>\n <p class=\"status-copy\">\n ${model.hero.name ?? model.hero.id} has no positioned talents.\n </p>\n </div>\n </div>\n `;\n }\n\n return html`\n <div class=\"grid\" part=\"grid\" role=\"group\" aria-label=\"Talent tiers\">\n ${repeat(\n model.rows,\n (row) => row.row,\n (row) => html`\n <fieldset class=\"row\" part=\"row\">\n <legend class=\"visually-hidden\">Talent tier ${row.label}</legend>\n <span class=\"row-label\" part=\"row-label\" aria-hidden=\"true\">${row.label}</span>\n <div class=\"row-talents\">\n ${repeat(\n row.talents,\n (talent) => talent.talent.id,\n (talent) => this.#renderTalent(talent),\n )}\n </div>\n </fieldset>\n `,\n )}\n </div>\n `;\n }\n\n #renderTalent(talent: TalentCalculatorTalentModel): TemplateResult | typeof nothing {\n const presentation = this._talentPresentation.get(talent.talent.id);\n if (!presentation) {\n return nothing;\n }\n const { context, name, descriptionId, affordability, description } = presentation;\n const { selected, disabled } = context;\n const card = html`\n <button\n class=\"talent\"\n part=\"talent\"\n type=\"button\"\n aria-label=${`${name}, ${affordability}`}\n aria-describedby=${descriptionId}\n aria-pressed=${String(selected)}\n aria-disabled=${String(disabled)}\n @click=${() => this.#handleTalentActivation(talent, selected, disabled)}\n >\n ${this.#renderTalentContent(context)}\n <span class=\"talent-cost\" part=\"talent-cost\">${talent.pointCost ?? \"–\"}</span>\n </button>\n `;\n\n return html`\n ${\n this.showTooltips && (talent.talent.description || disabled)\n ? html`\n <fellowship-tooltip\n .heading=${name}\n .text=${talent.talent.description ?? affordability}\n >\n ${card}\n </fellowship-tooltip>\n `\n : card\n }\n <span class=\"visually-hidden\" id=${descriptionId}>${description}</span>\n `;\n }\n\n #prepareTalentRenderContent(state: TalentCalculatorSelectionState): void {\n const renderer = this.renderTalent;\n const model = this._model;\n const content = new Map<string, unknown>();\n const presentations = new Map<string, TalentPresentation>();\n\n if (model) {\n for (const talent of model.talentById.values()) {\n const selected = state.selectedTalentIds.includes(talent.talent.id);\n const affordable = canSelectTalent(talent.pointCost, state);\n const disabled = !selected && !affordable;\n const name = talent.talent.name ?? talent.talent.id;\n const affordability =\n talent.pointCost === null\n ? \"This talent has no valid point cost.\"\n : disabled\n ? `Requires ${talent.pointCost} talent points; ${Math.max(0, state.remainingPoints)} remaining.`\n : `${talent.pointCost} talent ${talent.pointCost === 1 ? \"point\" : \"points\"}.`;\n const context: TalentCalculatorTalentRenderContext = {\n talent,\n hero: model.hero,\n selected,\n affordable,\n disabled,\n spentPoints: state.spentPoints,\n remainingPoints: state.remainingPoints,\n talentPoints: this.talentPoints,\n };\n presentations.set(talent.talent.id, {\n context,\n name,\n descriptionId: `talent-description-${talent.row}-${talent.column}`,\n affordability,\n description: [stripFellowshipRichText(talent.talent.description ?? \"\"), affordability]\n .filter(Boolean)\n .join(\" \"),\n });\n if (!renderer) {\n continue;\n }\n try {\n content.set(talent.talent.id, renderer(context));\n } catch (error: unknown) {\n if (!this.#rendererFailures.has(talent.talent.id)) {\n this.#rendererFailures.add(talent.talent.id);\n this.#pendingRendererWarnings.push({\n code: \"renderer-error\",\n message: `The talent renderer failed for “${talent.talent.id}”: ${String(error)}.`,\n talentId: talent.talent.id,\n });\n }\n }\n }\n }\n\n this._talentPresentation = presentations;\n this._talentRenderContent = content;\n }\n\n #renderTalentContent(context: TalentCalculatorTalentRenderContext): unknown {\n const talent = context.talent;\n const name = talent.talent.name ?? talent.talent.id;\n const content =\n this.renderTalent && this._talentRenderContent.has(talent.talent.id)\n ? this._talentRenderContent.get(talent.talent.id)\n : html`\n <slot name=${talentSlotName(talent.talent.id)}>\n <span class=\"talent-name\" part=\"talent-name\" title=${name}>${name}</span>\n </slot>\n `;\n\n return html`\n ${this.#renderDefaultTalentIcon(talent, name)} ${content}\n `;\n }\n\n #renderDefaultTalentIcon(talent: TalentCalculatorTalentModel, name: string): TemplateResult {\n if (talent.imageUrl && !this._failedImages.has(talent.talent.id)) {\n return html`\n <img\n class=\"talent-icon\"\n part=\"talent-icon\"\n src=${talent.imageUrl}\n alt=\"\"\n draggable=\"false\"\n @error=${() => this.#handleImageError(talent)}\n />\n `;\n }\n const rune = name\n .split(/\\s+/)\n .map((part) => part[0])\n .join(\"\")\n .slice(0, 2)\n .toUpperCase();\n return html`<span class=\"talent-icon-fallback\" part=\"talent-icon-fallback\">${rune}</span>`;\n }\n\n #renderStatus(): TemplateResult {\n const loading = this._status === \"loading\";\n const empty = this._status === \"empty\";\n const title = loading\n ? \"Reading talent codex\"\n : empty\n ? \"Choose a hero\"\n : \"Talents unavailable\";\n const copy = loading\n ? \"Loading the hero and their available talents.\"\n : empty\n ? \"Set the hero-id attribute or heroId property to build a talent loadout.\"\n : (this._error?.message ?? \"An unexpected talent data error occurred.\");\n return html`\n <div\n class=\"status\"\n part=${this._status === \"error\" ? \"error-state\" : \"status\"}\n role=${this._status === \"error\" ? \"alert\" : \"status\"}\n >\n <div class=\"status-card\">\n <div class=\"status-mark\" aria-hidden=\"true\">${loading ? \"…\" : \"✦\"}</div>\n <p class=\"status-title\">${title}</p>\n <p class=\"status-copy\">${copy}</p>\n ${\n this._status === \"error\"\n ? html`<button class=\"retry-button\" type=\"button\" @click=${this.retry}>Retry</button>`\n : nothing\n }\n </div>\n </div>\n `;\n }\n\n async #loadHeroTalents(): Promise<void> {\n const heroId = this.heroId.trim();\n const token = ++this.#loadToken;\n this.#abortController?.abort();\n this.#abortController = new AbortController();\n this._model = null;\n this._error = null;\n this._failedImages = new Set();\n this.#rendererFailures.clear();\n this.#lastOverBudgetSignature = null;\n\n if (!heroId) {\n this._status = \"empty\";\n return;\n }\n\n this._status = \"loading\";\n const source =\n this.dataSource ??\n createPackageFellowshipTalentDataSource(\n this.assetBaseUrl ? { assetBaseUrl: this.assetBaseUrl } : {},\n );\n\n try {\n const data = await source.loadHeroTalents(heroId, this.#abortController.signal);\n if (token !== this.#loadToken || this.#abortController.signal.aborted) {\n return;\n }\n assertSupportedFellowshipDataSchema(data.manifest.schemaVersion);\n const model = createTalentCalculatorRenderModel(data, source);\n this._model = model;\n this._status = \"ready\";\n const normalized = this.#normalizeSelections(false);\n await this.updateComplete;\n const selection = this.selectionState;\n this.dispatchEvent(\n new CustomEvent<FellowshipTalentsReadyDetail>(\"fellowship-talents-ready\", {\n ...eventOptions,\n detail: { data, model, selection },\n }),\n );\n if (model.warnings.length > 0) {\n this.#reportWarnings(model.warnings);\n }\n if (normalized) {\n this.#emitSelectionChange(\"normalization\");\n }\n this.#reportOverBudget();\n } catch (error: unknown) {\n if (token !== this.#loadToken || this.#abortController.signal.aborted) {\n return;\n }\n this.#setError(error);\n }\n }\n\n #normalizeSelections(emit: boolean): boolean {\n if (!this._model) {\n return false;\n }\n const normalized = normalizeSelectedTalentIds(this._model, this.selectedTalentIds);\n const changed =\n normalized.selectedTalentIds.length !== this.selectedTalentIds.length ||\n normalized.selectedTalentIds.some((id, index) => id !== this.selectedTalentIds[index]);\n if (!changed) {\n return false;\n }\n this.selectedTalentIds = normalized.selectedTalentIds;\n if (normalized.removedTalentIds.length > 0) {\n this.#reportWarnings([\n {\n code: \"invalid-selection\",\n message: `Removed unavailable talent selections: ${normalized.removedTalentIds.join(\", \")}.`,\n talentId: null,\n },\n ]);\n }\n if (emit) {\n this.#emitSelectionChange(\"normalization\");\n }\n return true;\n }\n\n #handleTalentActivation(\n talent: TalentCalculatorTalentModel,\n selected: boolean,\n disabled: boolean,\n ): void {\n if (selected) {\n this.selectedTalentIds = this.selectionState.selectedTalentIds.filter(\n (id) => id !== talent.talent.id,\n );\n this.#emitSelectionChange(\"user\");\n return;\n }\n if (disabled) {\n this._announcement = this.selectionState.overBudget\n ? \"The current build exceeds the available talent points. Deselect a talent first.\"\n : `Not enough points for ${talent.talent.name ?? talent.talent.id}.`;\n return;\n }\n this.selectedTalentIds = [...this.selectionState.selectedTalentIds, talent.talent.id];\n this.#emitSelectionChange(\"user\");\n }\n\n #setTalentPoints(value: number, source: TalentPointsChangeSource): void {\n const normalized = normalizeTalentPoints(value);\n const state = this.selectionState;\n if (normalized === this.talentPoints || normalized < state.spentPoints) {\n return;\n }\n this.talentPoints = normalized;\n this.#skipNextPropertyPointEvent = true;\n this.#emitPointsChange(source);\n }\n\n #emitSelectionChange(source: TalentSelectionChangeSource): void {\n const state = this._model\n ? createTalentCalculatorSelectionState(this._model, this.selectedTalentIds, this.talentPoints)\n : fallbackSelectionState(this.talentPoints);\n this.dispatchEvent(\n new CustomEvent<TalentSelectionChangeDetail>(\"fellowship-talent-selection-change\", {\n ...eventOptions,\n detail: { ...state, source },\n }),\n );\n }\n\n #emitPointsChange(source: TalentPointsChangeSource): void {\n const state = this.selectionState;\n this.dispatchEvent(\n new CustomEvent<TalentPointsChangeDetail>(\"fellowship-talent-points-change\", {\n ...eventOptions,\n detail: { ...state, talentPoints: this.talentPoints, source },\n }),\n );\n }\n\n #reportOverBudget(): void {\n const state = this.selectionState;\n if (!state.overBudget) {\n this.#lastOverBudgetSignature = null;\n this.removeAttribute(\"aria-invalid\");\n return;\n }\n this.setAttribute(\"aria-invalid\", \"true\");\n const signature = `${this.talentPoints}:${state.selectedTalentIds.join(\",\")}`;\n if (signature === this.#lastOverBudgetSignature) {\n return;\n }\n this.#lastOverBudgetSignature = signature;\n this.#reportWarnings([\n {\n code: \"over-budget\",\n message: `The selected talents cost ${state.spentPoints} points, exceeding the ${this.talentPoints}-point budget.`,\n talentId: null,\n },\n ]);\n }\n\n #handleImageError(talent: TalentCalculatorTalentModel): void {\n if (this._failedImages.has(talent.talent.id)) {\n return;\n }\n this._failedImages = new Set(this._failedImages).add(talent.talent.id);\n this.#reportWarnings([\n {\n code: \"asset-image-error\",\n message: `The icon for talent “${talent.talent.id}” could not be loaded.`,\n talentId: talent.talent.id,\n },\n ]);\n }\n\n #reportWarnings(warnings: readonly TalentCalculatorWarning[]): void {\n this.dispatchEvent(\n new CustomEvent<FellowshipTalentsWarningDetail>(\"fellowship-talents-warning\", {\n ...eventOptions,\n detail: { warnings, model: this._model },\n }),\n );\n }\n\n #flushRendererWarnings(): void {\n if (this.#pendingRendererWarnings.length === 0) {\n return;\n }\n const warnings = this.#pendingRendererWarnings;\n this.#pendingRendererWarnings = [];\n this.#reportWarnings(warnings);\n }\n\n #setError(error: unknown): void {\n const detail: FellowshipTalentsErrorDetail =\n typeof error === \"object\" && error !== null && \"code\" in error && \"message\" in error\n ? {\n code: String(error.code),\n message: String(error.message),\n ...(error instanceof FellowshipDataError && error.cause !== undefined\n ? { cause: error.cause }\n : {}),\n }\n : { code: \"unknown\", message: error instanceof Error ? error.message : String(error) };\n this._error = detail;\n this._status = \"error\";\n this.dispatchEvent(\n new CustomEvent<FellowshipTalentsErrorDetail>(\"fellowship-talents-error\", {\n ...eventOptions,\n detail,\n }),\n );\n }\n}\n\nexport const defineFellowshipTalentCalculator = (): void => {\n defineFellowshipTooltip();\n if (!customElements.get(\"fellowship-talent-calculator\")) {\n customElements.define(\"fellowship-talent-calculator\", FellowshipTalentCalculatorElement);\n }\n};\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"fellowship-talent-calculator\": FellowshipTalentCalculatorElement;\n }\n}\n"],"mappings":"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"}
@@ -1,6 +1,8 @@
1
- export { FellowshipDataError } from "@crockery/fellowship-data/client";
1
+ import { FellowshipDataError } from "@crockery/fellowship-data/client";
2
+ export { FellowshipDataError };
2
3
  export type { DungeonMapData, FellowshipDataErrorCode, } from "@crockery/fellowship-data/client";
3
4
  import type { FellowshipDataClient } from "@crockery/fellowship-data/client";
5
+ export declare const assertSupportedFellowshipDataSchema: (schemaVersion: number) => void;
4
6
  /** @deprecated Use the corresponding `FellowshipDataClient` methods. */
5
7
  export type FellowshipDataSource = Pick<FellowshipDataClient, "loadDungeon" | "resolveAssetUrl">;
6
8
  //# sourceMappingURL=data-source.d.ts.map