@crockery/fellowship-components 0.4.1 → 1.0.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.
- package/README.md +31 -17
- package/RELEASING.md +2 -2
- package/THIRD_PARTY_LICENSES.md +12 -0
- package/dist/assets/dm-mono-latin-400-normal-4GdczIuU.woff2 +0 -0
- package/dist/assets/dm-mono-latin-500-normal-DRMDZjhP.woff2 +0 -0
- package/dist/assets/syne-latin-700-normal-AF3Rs61n.woff2 +0 -0
- package/dist/assets/syne-latin-800-normal-EehdNYzx.woff2 +0 -0
- package/dist/chunks/decorate-DyMgX_Uh.js +9 -0
- package/dist/chunks/{dungeon-cast-browser-CSnu3gC5.js → dungeon-cast-browser-DdG8klca.js} +62 -58
- package/dist/chunks/{dungeon-map-CutIcCVP.js → dungeon-map-D0-DAjZ9.js} +130 -131
- package/dist/chunks/{decorate-B_ZTN9li.js → field-manual-fonts-DTFloVFe.js} +18 -23
- package/dist/chunks/gear-planner-Bgt77Ovf.js +1696 -0
- package/dist/chunks/{talent-calculator-Dxuc2dZ8.js → talent-calculator-DbU6P1AP.js} +36 -35
- package/dist/chunks/tooltip-C3SSJw-t.js +482 -0
- package/dist/data/cast-data-source.d.ts +1 -1
- package/dist/data/data-source.d.ts +1 -1
- package/dist/data/package-cast-data-source.d.ts +1 -5
- package/dist/data/package-data-source.d.ts +1 -5
- package/dist/data/package-talent-data-source.d.ts +1 -5
- package/dist/data/talent-data-source.d.ts +1 -1
- package/dist/dungeon-cast-browser/dungeon-cast-browser.d.ts +2 -1
- package/dist/dungeon-cast-browser/render-model.d.ts +3 -2
- package/dist/dungeon-cast-browser/types.d.ts +2 -2
- package/dist/dungeon-cast-browser.js +1 -1
- package/dist/dungeon-map/dungeon-map.d.ts +2 -1
- package/dist/dungeon-map/render-model.d.ts +3 -3
- package/dist/dungeon-map/types.d.ts +2 -2
- package/dist/dungeon-map.js +1 -1
- package/dist/gear-planner/gear-planner.d.ts +36 -0
- package/dist/gear-planner/gear-planner.styles.d.ts +1 -0
- package/dist/gear-planner/gear-position.d.ts +19 -0
- package/dist/gear-planner/index.d.ts +2 -0
- package/dist/gear-planner/item-workbench.d.ts +18 -0
- package/dist/gear-planner/item-workbench.styles.d.ts +1 -0
- package/dist/gear-planner/types.d.ts +24 -0
- package/dist/gear-planner.js +5 -0
- package/dist/index.d.ts +6 -5
- package/dist/index.js +9 -7
- package/dist/react/dungeon-cast-browser.d.ts +8 -3
- package/dist/react/dungeon-cast-browser.js +11 -4
- package/dist/react/dungeon-map.d.ts +3 -1
- package/dist/react/dungeon-map.js +1 -1
- package/dist/react/gear-planner.d.ts +14 -0
- package/dist/react/gear-planner.js +23 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/talent-calculator.d.ts +3 -1
- package/dist/react/talent-calculator.js +1 -1
- package/dist/react/tooltip.js +1 -1
- package/dist/react.js +2 -1
- package/dist/styles/dungeon-poster-fonts.d.ts +2 -0
- package/dist/styles/dungeon-poster.styles.d.ts +7 -0
- package/dist/talent-calculator/render-model.d.ts +3 -2
- package/dist/talent-calculator/talent-calculator.d.ts +2 -1
- package/dist/talent-calculator/types.d.ts +2 -2
- package/dist/talent-calculator.js +1 -1
- package/dist/tooltip.js +3 -3
- package/package.json +15 -2
- package/src/dungeon-cast-browser/README.md +10 -4
- package/src/dungeon-map/README.md +5 -6
- package/src/gear-planner/README.md +44 -0
- package/src/talent-calculator/README.md +5 -6
- package/src/tooltip/README.md +5 -6
- package/dist/chunks/data-source-XbksqUrw.js +0 -7
- package/dist/chunks/tooltip-DoQVSnOn.js +0 -410
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { i as e, n as t, r as n, t as r } from "./field-manual-fonts-DTFloVFe.js";
|
|
2
|
+
import { t as i } from "./decorate-DyMgX_Uh.js";
|
|
3
3
|
import { createPackageFellowshipDataClient as a } from "@crockery/fellowship-data/client";
|
|
4
4
|
import { LitElement as o, css as s, html as c, nothing as l } from "lit";
|
|
5
5
|
import { customElement as u, property as d, query as f, state as p } from "lit/decorators.js";
|
|
@@ -7,12 +7,9 @@ import { repeat as m } from "lit/directives/repeat.js";
|
|
|
7
7
|
import { styleMap as h } from "lit/directives/style-map.js";
|
|
8
8
|
import { findImage as g } from "@crockery/fellowship-data";
|
|
9
9
|
//#region src/data/package-data-source.ts
|
|
10
|
-
var _ = (
|
|
11
|
-
let
|
|
12
|
-
return {
|
|
13
|
-
loadDungeon: (e, n) => t.loadDungeon(e, n),
|
|
14
|
-
resolveAssetUrl: (e) => t.resolveAssetUrl(e)
|
|
15
|
-
};
|
|
10
|
+
var _ = () => {
|
|
11
|
+
let e = a();
|
|
12
|
+
return { loadDungeon: (t, n) => e.loadDungeon(t, n) };
|
|
16
13
|
}, v = s`
|
|
17
14
|
:host {
|
|
18
15
|
--fellowship-map-soot: var(--_fellowship-field-canvas);
|
|
@@ -516,7 +513,7 @@ var _ = (e = {}) => {
|
|
|
516
513
|
size: "200"
|
|
517
514
|
}) : null, l = null;
|
|
518
515
|
if (c) try {
|
|
519
|
-
l = n
|
|
516
|
+
l = n(c);
|
|
520
517
|
} catch (e) {
|
|
521
518
|
r.push({
|
|
522
519
|
code: "asset-url-error",
|
|
@@ -599,12 +596,12 @@ var _ = (e = {}) => {
|
|
|
599
596
|
composed: !0
|
|
600
597
|
}, F = class extends o {
|
|
601
598
|
constructor(...e) {
|
|
602
|
-
super(...e), this.dungeonId = "", this.mapImageId = null, this.
|
|
599
|
+
super(...e), this.dungeonId = "", this.mapImageId = null, this.resolveAssetUrl = null, this.dataSource = null, this.renderEnemy = null, this.renderGroup = null, this.mapLabelFormatter = null, this.showControls = !0, this.showMapSelector = !0, this.maxZoom = 8, this.externalOverlay = !1, this._status = "empty", this._error = null, this._data = null, this._model = null, this._selectedMap = null, this._viewportState = {
|
|
603
600
|
zoom: 1,
|
|
604
601
|
scale: 1,
|
|
605
602
|
x: 0,
|
|
606
603
|
y: 0
|
|
607
|
-
}, this._isPanning = !1, this._enemyRenderContent = /* @__PURE__ */ new Map(), this._groupRenderContent = /* @__PURE__ */ new Map(), this._mapLabels = /* @__PURE__ */ new Map(), this.#e = null, this.#t =
|
|
604
|
+
}, this._isPanning = !1, this._enemyRenderContent = /* @__PURE__ */ new Map(), this._groupRenderContent = /* @__PURE__ */ new Map(), this._mapLabels = /* @__PURE__ */ new Map(), this.#e = null, this.#t = 0, this.#n = 0, this.#r = null, this.#i = new N(), this.#a = /* @__PURE__ */ new Map(), this.#o = null, this.#s = 0, this.#c = null, this.#l = /* @__PURE__ */ new Set(), this.#u = [], this.#A = (e) => {
|
|
608
605
|
if (![
|
|
609
606
|
"ArrowLeft",
|
|
610
607
|
"ArrowRight",
|
|
@@ -612,30 +609,30 @@ var _ = (e = {}) => {
|
|
|
612
609
|
"End"
|
|
613
610
|
].includes(e.key)) return;
|
|
614
611
|
let t = this._data?.dungeon.mapImages ?? [], n = t.findIndex(({ id: e }) => e === this._selectedMap?.id), r = e.key === "Home" ? 0 : e.key === "End" ? t.length - 1 : e.key === "ArrowRight" ? (n + 1) % t.length : (n - 1 + t.length) % t.length, i = t[r];
|
|
615
|
-
i && (e.preventDefault(), this.#
|
|
612
|
+
i && (e.preventDefault(), this.#k(i), this.updateComplete.then(() => {
|
|
616
613
|
this.renderRoot.querySelector(`[data-map-index="${r}"]`)?.focus();
|
|
617
614
|
}));
|
|
618
|
-
}, this.#
|
|
615
|
+
}, this.#j = (e) => {
|
|
619
616
|
if (!this._model || this._status !== "ready") return;
|
|
620
617
|
e.preventDefault();
|
|
621
618
|
let t = this._viewportElement?.getBoundingClientRect();
|
|
622
619
|
if (!t) return;
|
|
623
620
|
let n = Math.exp(-e.deltaY * .0015);
|
|
624
|
-
this.#
|
|
625
|
-
}, this.#
|
|
621
|
+
this.#i.zoomAt(n, e.clientX - t.left, e.clientY - t.top), this.#R("wheel");
|
|
622
|
+
}, this.#M = (e) => {
|
|
626
623
|
if (!(e.target !== this._viewportElement || !this._model)) {
|
|
627
|
-
if (e.key === "+" || e.key === "=") e.preventDefault(), this.#
|
|
628
|
-
else if (e.key === "-") e.preventDefault(), this.#
|
|
629
|
-
else if (e.key === "0") e.preventDefault(), this.#
|
|
630
|
-
else if (e.key === "ArrowLeft") e.preventDefault(), this.#
|
|
631
|
-
else if (e.key === "ArrowRight") e.preventDefault(), this.#
|
|
632
|
-
else if (e.key === "ArrowUp") e.preventDefault(), this.#
|
|
633
|
-
else if (e.key === "ArrowDown") e.preventDefault(), this.#
|
|
624
|
+
if (e.key === "+" || e.key === "=") e.preventDefault(), this.#i.zoomAt(1.35);
|
|
625
|
+
else if (e.key === "-") e.preventDefault(), this.#i.zoomAt(1 / 1.35);
|
|
626
|
+
else if (e.key === "0") e.preventDefault(), this.#i.fit();
|
|
627
|
+
else if (e.key === "ArrowLeft") e.preventDefault(), this.#i.panBy(56, 0);
|
|
628
|
+
else if (e.key === "ArrowRight") e.preventDefault(), this.#i.panBy(-56, 0);
|
|
629
|
+
else if (e.key === "ArrowUp") e.preventDefault(), this.#i.panBy(0, 56);
|
|
630
|
+
else if (e.key === "ArrowDown") e.preventDefault(), this.#i.panBy(0, -56);
|
|
634
631
|
else return;
|
|
635
|
-
this.#
|
|
632
|
+
this.#R("keyboard");
|
|
636
633
|
}
|
|
637
|
-
}, this.#
|
|
638
|
-
if (!this._model || this.#
|
|
634
|
+
}, this.#N = (e) => {
|
|
635
|
+
if (!this._model || this.#I(e)) return;
|
|
639
636
|
let t = this._viewportElement, n = t?.getBoundingClientRect();
|
|
640
637
|
if (!t || !n) return;
|
|
641
638
|
t.setPointerCapture(e.pointerId);
|
|
@@ -643,41 +640,41 @@ var _ = (e = {}) => {
|
|
|
643
640
|
x: e.clientX - n.left,
|
|
644
641
|
y: e.clientY - n.top
|
|
645
642
|
};
|
|
646
|
-
if (this.#
|
|
647
|
-
else if (this.#
|
|
648
|
-
let [e, t] = [...this.#
|
|
649
|
-
e && t && (this.#
|
|
643
|
+
if (this.#a.set(e.pointerId, r), this._isPanning = !0, this.#a.size === 1) this.#o = r;
|
|
644
|
+
else if (this.#a.size === 2) {
|
|
645
|
+
let [e, t] = [...this.#a.values()];
|
|
646
|
+
e && t && (this.#s = Math.hypot(t.x - e.x, t.y - e.y), this.#c = {
|
|
650
647
|
x: (e.x + t.x) / 2,
|
|
651
648
|
y: (e.y + t.y) / 2
|
|
652
649
|
});
|
|
653
650
|
}
|
|
654
|
-
}, this.#
|
|
655
|
-
if (!this.#
|
|
651
|
+
}, this.#P = (e) => {
|
|
652
|
+
if (!this.#a.has(e.pointerId)) return;
|
|
656
653
|
let t = this._viewportElement?.getBoundingClientRect();
|
|
657
654
|
if (!t) return;
|
|
658
655
|
let n = {
|
|
659
656
|
x: e.clientX - t.left,
|
|
660
657
|
y: e.clientY - t.top
|
|
661
658
|
};
|
|
662
|
-
if (this.#
|
|
663
|
-
this.#
|
|
659
|
+
if (this.#a.set(e.pointerId, n), this.#a.size === 1 && this.#o) {
|
|
660
|
+
this.#i.panBy(n.x - this.#o.x, n.y - this.#o.y), this.#o = n, this.#R("pan");
|
|
664
661
|
return;
|
|
665
662
|
}
|
|
666
|
-
if (this.#
|
|
667
|
-
let [e, t] = [...this.#
|
|
663
|
+
if (this.#a.size === 2) {
|
|
664
|
+
let [e, t] = [...this.#a.values()];
|
|
668
665
|
if (!e || !t) return;
|
|
669
666
|
let n = Math.hypot(t.x - e.x, t.y - e.y), r = {
|
|
670
667
|
x: (e.x + t.x) / 2,
|
|
671
668
|
y: (e.y + t.y) / 2
|
|
672
669
|
};
|
|
673
|
-
this.#
|
|
670
|
+
this.#s > 0 && this.#i.zoomAt(n / this.#s, r.x, r.y), this.#c && this.#i.panBy(r.x - this.#c.x, r.y - this.#c.y), this.#s = n, this.#c = r, this.#R("pinch");
|
|
674
671
|
}
|
|
675
|
-
}, this.#
|
|
676
|
-
this.#
|
|
672
|
+
}, this.#F = (e) => {
|
|
673
|
+
this.#a.delete(e.pointerId), this.#a.size === 1 ? this.#o = [...this.#a.values()][0] ?? null : this.#a.size === 0 && (this.#o = null, this.#c = null, this.#s = 0, this._isPanning = !1);
|
|
677
674
|
};
|
|
678
675
|
}
|
|
679
676
|
static {
|
|
680
|
-
this.styles = [
|
|
677
|
+
this.styles = [t, v];
|
|
681
678
|
}
|
|
682
679
|
#e;
|
|
683
680
|
#t;
|
|
@@ -690,56 +687,55 @@ var _ = (e = {}) => {
|
|
|
690
687
|
#c;
|
|
691
688
|
#l;
|
|
692
689
|
#u;
|
|
693
|
-
#d;
|
|
694
690
|
connectedCallback() {
|
|
695
|
-
super.connectedCallback(),
|
|
691
|
+
super.connectedCallback(), r(this.ownerDocument), this.#r ??= new ResizeObserver(() => this.#L());
|
|
696
692
|
}
|
|
697
693
|
disconnectedCallback() {
|
|
698
|
-
this.#
|
|
694
|
+
this.#e?.abort(), this.#r?.disconnect(), super.disconnectedCallback();
|
|
699
695
|
}
|
|
700
696
|
firstUpdated(e) {
|
|
701
697
|
super.firstUpdated(e);
|
|
702
698
|
let t = this._viewportElement;
|
|
703
|
-
t && this.#
|
|
699
|
+
t && this.#r?.observe(t);
|
|
704
700
|
}
|
|
705
701
|
updated(e) {
|
|
706
|
-
if (super.updated(e), this.#
|
|
702
|
+
if (super.updated(e), this.#B(), e.has("dungeonId") || e.has("dataSource") || e.has("resolveAssetUrl")) {
|
|
707
703
|
queueMicrotask(() => {
|
|
708
|
-
this.isConnected && this.#
|
|
704
|
+
this.isConnected && this.#p();
|
|
709
705
|
});
|
|
710
706
|
return;
|
|
711
707
|
}
|
|
712
708
|
e.has("mapImageId") && this._data && queueMicrotask(() => {
|
|
713
|
-
this.isConnected && this.#
|
|
714
|
-
}), e.has("maxZoom") && e.get("maxZoom") !== void 0 && (this.#
|
|
709
|
+
this.isConnected && this.#m(!0);
|
|
710
|
+
}), e.has("maxZoom") && e.get("maxZoom") !== void 0 && (this.#i.maxZoom = Math.max(1, this.maxZoom), this.#i.zoomAt(1), queueMicrotask(() => this.#R("button")));
|
|
715
711
|
}
|
|
716
712
|
willUpdate(e) {
|
|
717
|
-
super.willUpdate(e), (e.has("renderEnemy") || e.has("renderGroup") || e.has("mapLabelFormatter")) && this.#
|
|
713
|
+
super.willUpdate(e), (e.has("renderEnemy") || e.has("renderGroup") || e.has("mapLabelFormatter")) && this.#l.clear(), (e.has("_model") || e.has("renderEnemy") || e.has("renderGroup")) && this.#_(), (e.has("_data") || e.has("mapLabelFormatter")) && this.#v();
|
|
718
714
|
}
|
|
719
715
|
fitToView() {
|
|
720
|
-
this.#
|
|
716
|
+
this.#i.fit(), this.#R("fit");
|
|
721
717
|
}
|
|
722
718
|
zoomIn() {
|
|
723
|
-
this.#
|
|
719
|
+
this.#i.zoomAt(1.35), this.#R("button");
|
|
724
720
|
}
|
|
725
721
|
zoomOut() {
|
|
726
|
-
this.#
|
|
722
|
+
this.#i.zoomAt(1 / 1.35), this.#R("button");
|
|
727
723
|
}
|
|
728
724
|
retry() {
|
|
729
|
-
this.#
|
|
725
|
+
this.#p();
|
|
730
726
|
}
|
|
731
727
|
get renderModel() {
|
|
732
728
|
return this._model;
|
|
733
729
|
}
|
|
734
730
|
render() {
|
|
735
|
-
let e = this._model, t = this._viewportState, n = this.#
|
|
731
|
+
let e = this._model, t = this._viewportState, n = this.#f, r = e ? {
|
|
736
732
|
width: `${e.mapImage.width}px`,
|
|
737
733
|
height: `${e.mapImage.height}px`,
|
|
738
734
|
transform: `translate3d(${t.x}px, ${t.y}px, 0) scale(${t.scale})`,
|
|
739
735
|
"--fellowship-map-inverse-scale": String(1 / t.scale)
|
|
740
736
|
} : {};
|
|
741
737
|
return c`
|
|
742
|
-
<section class="viewer" aria-label=${this.#
|
|
738
|
+
<section class="viewer" aria-label=${this.#d}>
|
|
743
739
|
<div
|
|
744
740
|
class="viewport"
|
|
745
741
|
part="viewport"
|
|
@@ -748,12 +744,12 @@ var _ = (e = {}) => {
|
|
|
748
744
|
tabindex="0"
|
|
749
745
|
aria-describedby="map-instructions"
|
|
750
746
|
data-panning=${String(this._isPanning)}
|
|
751
|
-
@wheel=${this.#
|
|
752
|
-
@keydown=${this.#
|
|
753
|
-
@pointerdown=${this.#
|
|
754
|
-
@pointermove=${this.#
|
|
755
|
-
@pointerup=${this.#
|
|
756
|
-
@pointercancel=${this.#
|
|
747
|
+
@wheel=${this.#j}
|
|
748
|
+
@keydown=${this.#M}
|
|
749
|
+
@pointerdown=${this.#N}
|
|
750
|
+
@pointermove=${this.#P}
|
|
751
|
+
@pointerup=${this.#F}
|
|
752
|
+
@pointercancel=${this.#F}
|
|
757
753
|
>
|
|
758
754
|
${e ? c`
|
|
759
755
|
<div
|
|
@@ -767,18 +763,18 @@ var _ = (e = {}) => {
|
|
|
767
763
|
class="map-canvas"
|
|
768
764
|
part="map-canvas"
|
|
769
765
|
role="img"
|
|
770
|
-
aria-label=${`${e.dungeon.name ?? e.dungeon.id}, ${this.#
|
|
766
|
+
aria-label=${`${e.dungeon.name ?? e.dungeon.id}, ${this.#O(e.mapImage)}`}
|
|
771
767
|
.width=${e.mapImage.width}
|
|
772
768
|
.height=${e.mapImage.height}
|
|
773
769
|
></canvas>
|
|
774
770
|
<div class="overlay" part="overlay">
|
|
775
|
-
${this.externalOverlay ? c`<slot name="overlay"></slot>` : this.#
|
|
771
|
+
${this.externalOverlay ? c`<slot name="overlay"></slot>` : this.#y(e)}
|
|
776
772
|
</div>
|
|
777
773
|
</div>
|
|
778
|
-
${this.#
|
|
774
|
+
${this.#T(e)} ${this.#E()}
|
|
779
775
|
${e.groups.length === 0 && this._status === "ready" ? c`<div class="empty-badge">No enemy placements on this map</div>` : l}
|
|
780
776
|
` : l}
|
|
781
|
-
${this.#
|
|
777
|
+
${this.#D()}
|
|
782
778
|
<p class="visually-hidden" id="map-instructions">
|
|
783
779
|
Drag to pan. Use the mouse wheel, plus and minus keys, or zoom controls to zoom. Press
|
|
784
780
|
zero to fit the full map.
|
|
@@ -787,49 +783,55 @@ var _ = (e = {}) => {
|
|
|
787
783
|
</section>
|
|
788
784
|
`;
|
|
789
785
|
}
|
|
790
|
-
get #
|
|
786
|
+
get #d() {
|
|
791
787
|
return this._data ? `${this._data.dungeon.name ?? this._data.dungeon.id} dungeon map` : "Fellowship dungeon map";
|
|
792
788
|
}
|
|
793
|
-
get #
|
|
789
|
+
get #f() {
|
|
794
790
|
if (!this.showMapSelector || !this._model || this._model.dungeon.mapImages.length <= 1 || !this._selectedMap) return l;
|
|
795
791
|
let e = this._model.dungeon.mapImages.findIndex((e) => e.id === this._selectedMap?.id);
|
|
796
792
|
return e >= 0 ? `map-tab-${e}` : l;
|
|
797
793
|
}
|
|
798
|
-
async #
|
|
799
|
-
let t = this.dungeonId.trim(), n = ++this.#
|
|
800
|
-
if (this.#
|
|
794
|
+
async #p() {
|
|
795
|
+
let t = this.dungeonId.trim(), n = ++this.#t;
|
|
796
|
+
if (this.#n += 1, this.#e?.abort(), this.#e = new AbortController(), this._data = null, this._model = null, this._selectedMap = null, this._error = null, this.#l.clear(), !t) {
|
|
801
797
|
this._status = "empty";
|
|
802
798
|
return;
|
|
803
799
|
}
|
|
800
|
+
if (!this.resolveAssetUrl) {
|
|
801
|
+
this.#g({
|
|
802
|
+
code: "asset-resolver-missing",
|
|
803
|
+
message: "A resolveAssetUrl callback is required to render Fellowship images."
|
|
804
|
+
});
|
|
805
|
+
return;
|
|
806
|
+
}
|
|
804
807
|
this._status = "loading";
|
|
805
|
-
let r = this.dataSource ?? _(
|
|
806
|
-
this.#e = r;
|
|
808
|
+
let r = this.dataSource ?? _();
|
|
807
809
|
try {
|
|
808
|
-
let i = await r.loadDungeon(t, this.#
|
|
809
|
-
if (n !== this.#
|
|
810
|
-
e(i.manifest.schemaVersion), this._data = i, await this.#
|
|
810
|
+
let i = await r.loadDungeon(t, this.#e.signal);
|
|
811
|
+
if (n !== this.#t || this.#e.signal.aborted) return;
|
|
812
|
+
e(i.manifest.schemaVersion), this._data = i, await this.#m(!0);
|
|
811
813
|
} catch (e) {
|
|
812
|
-
if (n !== this.#
|
|
813
|
-
this.#
|
|
814
|
+
if (n !== this.#t || this.#e.signal.aborted) return;
|
|
815
|
+
this.#g(e);
|
|
814
816
|
}
|
|
815
817
|
}
|
|
816
|
-
async #
|
|
817
|
-
let t = this._data, n = this
|
|
818
|
+
async #m(e) {
|
|
819
|
+
let t = this._data, n = this.resolveAssetUrl;
|
|
818
820
|
if (!t || !n) return;
|
|
819
821
|
let r = this.mapImageId ? t.dungeon.mapImages.find(({ id: e }) => e === this.mapImageId) : t.dungeon.mapImages[0];
|
|
820
822
|
if (!r) {
|
|
821
|
-
this.#
|
|
823
|
+
this.#g({
|
|
822
824
|
code: "map-not-found",
|
|
823
825
|
message: this.mapImageId ? `No map image with ID “${this.mapImageId}” exists for this dungeon.` : "This dungeon does not include a map image."
|
|
824
826
|
});
|
|
825
827
|
return;
|
|
826
828
|
}
|
|
827
|
-
let i = ++this.#
|
|
829
|
+
let i = ++this.#n, a = A(t, r, n);
|
|
828
830
|
this._model = a, this._selectedMap = r, this._status = "loading", this._error = null, await this.updateComplete;
|
|
829
831
|
let o = this._viewportElement;
|
|
830
|
-
o && (this.#
|
|
832
|
+
o && (this.#i.maxZoom = Math.max(1, this.maxZoom), this.#i.setDimensions(o.clientWidth, o.clientHeight, r.width, r.height), e && this.#i.fit(), this._viewportState = this.#i.state, await this.updateComplete);
|
|
831
833
|
try {
|
|
832
|
-
if (await this.#
|
|
834
|
+
if (await this.#h(r, n, i), i !== this.#n) return;
|
|
833
835
|
this._status = "ready", this.dispatchEvent(new CustomEvent("fellowship-map-ready", {
|
|
834
836
|
...P,
|
|
835
837
|
detail: {
|
|
@@ -844,35 +846,35 @@ var _ = (e = {}) => {
|
|
|
844
846
|
}
|
|
845
847
|
}));
|
|
846
848
|
} catch (e) {
|
|
847
|
-
i === this.#
|
|
849
|
+
i === this.#n && this.#g({
|
|
848
850
|
code: "map-image-error",
|
|
849
851
|
message: `Unable to load the dungeon map image: ${String(e)}.`,
|
|
850
852
|
cause: e
|
|
851
853
|
});
|
|
852
854
|
}
|
|
853
855
|
}
|
|
854
|
-
async #
|
|
856
|
+
async #h(e, t, n) {
|
|
855
857
|
let r = new Image();
|
|
856
|
-
if (r.crossOrigin = "anonymous", r.src = t
|
|
858
|
+
if (r.crossOrigin = "anonymous", r.src = t(e), await r.decode(), n !== this.#n) return;
|
|
857
859
|
let i = this._canvasElement, a = i?.getContext("2d");
|
|
858
860
|
if (!i || !a) throw Error("A 2D canvas context is unavailable.");
|
|
859
861
|
a.clearRect(0, 0, i.width, i.height), a.drawImage(r, 0, 0, e.width, e.height);
|
|
860
862
|
}
|
|
861
|
-
#
|
|
862
|
-
let
|
|
863
|
+
#g(e) {
|
|
864
|
+
let t = typeof e == "object" && e && "code" in e && "message" in e ? {
|
|
863
865
|
code: String(e.code),
|
|
864
866
|
message: String(e.message),
|
|
865
|
-
...e instanceof
|
|
867
|
+
...e instanceof n && e.cause !== void 0 ? { cause: e.cause } : {}
|
|
866
868
|
} : {
|
|
867
869
|
code: "unknown",
|
|
868
870
|
message: e instanceof Error ? e.message : String(e)
|
|
869
871
|
};
|
|
870
|
-
this._error =
|
|
872
|
+
this._error = t, this._status = "error", this.dispatchEvent(new CustomEvent("fellowship-map-error", {
|
|
871
873
|
...P,
|
|
872
|
-
detail:
|
|
874
|
+
detail: t
|
|
873
875
|
}));
|
|
874
876
|
}
|
|
875
|
-
#
|
|
877
|
+
#_() {
|
|
876
878
|
let e = this._model, t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map();
|
|
877
879
|
if (!e) {
|
|
878
880
|
this._enemyRenderContent = t, this._groupRenderContent = n;
|
|
@@ -886,10 +888,10 @@ var _ = (e = {}) => {
|
|
|
886
888
|
mapImage: e.mapImage
|
|
887
889
|
}));
|
|
888
890
|
} catch (e) {
|
|
889
|
-
this.#
|
|
891
|
+
this.#z(`enemy:${r.instanceId}`, "enemy-renderer-error", e);
|
|
890
892
|
}
|
|
891
893
|
if (this._enemyRenderContent = t, this.renderGroup) for (let t of e.groups) {
|
|
892
|
-
let r = t.enemies.map((e) => this.#
|
|
894
|
+
let r = t.enemies.map((e) => this.#C(t, e)), i = this.#b(e, t);
|
|
893
895
|
try {
|
|
894
896
|
n.set(i, this.renderGroup({
|
|
895
897
|
group: t,
|
|
@@ -898,49 +900,49 @@ var _ = (e = {}) => {
|
|
|
898
900
|
mapImage: e.mapImage
|
|
899
901
|
}));
|
|
900
902
|
} catch (e) {
|
|
901
|
-
this.#
|
|
903
|
+
this.#z(`group:${i}`, "group-renderer-error", e);
|
|
902
904
|
}
|
|
903
905
|
}
|
|
904
906
|
this._groupRenderContent = n;
|
|
905
907
|
}
|
|
906
|
-
#
|
|
908
|
+
#v() {
|
|
907
909
|
let e = /* @__PURE__ */ new Map(), t = this._data?.dungeon;
|
|
908
910
|
if (t) for (let n of t.mapImages) try {
|
|
909
911
|
e.set(n.id, this.mapLabelFormatter?.(n, t) ?? j(n, t));
|
|
910
912
|
} catch (r) {
|
|
911
|
-
this.#
|
|
913
|
+
this.#z(`map-label:${n.id}`, "map-label-formatter-error", r), e.set(n.id, j(n, t));
|
|
912
914
|
}
|
|
913
915
|
this._mapLabels = e;
|
|
914
916
|
}
|
|
915
|
-
#
|
|
916
|
-
return m(e.groups, (t) => this.#
|
|
917
|
+
#y(e) {
|
|
918
|
+
return m(e.groups, (t) => this.#b(e, t), (t) => this.#x(e, t));
|
|
917
919
|
}
|
|
918
|
-
#
|
|
920
|
+
#b(e, t) {
|
|
919
921
|
return `${e.mapImage.id}:${String(t.id)}:${t.enemies[0]?.instanceId ?? "empty"}`;
|
|
920
922
|
}
|
|
921
|
-
#
|
|
923
|
+
#x(e, t) {
|
|
922
924
|
let n = t.visualBounds, r = {
|
|
923
925
|
left: `${n.x * 100}%`,
|
|
924
926
|
top: `${n.y * 100}%`,
|
|
925
927
|
width: `${n.width * 100}%`,
|
|
926
928
|
height: `${n.height * 100}%`
|
|
927
|
-
}, i = this.#
|
|
929
|
+
}, i = this.#b(e, t), a = this.renderGroup && this._groupRenderContent.has(i) ? this._groupRenderContent.get(i) ?? l : this.#S(t);
|
|
928
930
|
return c` <div class="group-anchor" part="group" style=${h(r)}>${a}</div> `;
|
|
929
931
|
}
|
|
930
|
-
#
|
|
932
|
+
#S(e) {
|
|
931
933
|
return c`
|
|
932
934
|
<div class="default-group">
|
|
933
935
|
<div class="group-ring" aria-hidden="true"></div>
|
|
934
936
|
<span class="group-label">${`G${e.id ?? "–"}${e.dungeonScore === null ? "" : ` · ${e.dungeonScore}`}`}</span>
|
|
935
|
-
${m(e.enemies, (e) => e.instanceId, (t) => this.#
|
|
937
|
+
${m(e.enemies, (e) => e.instanceId, (t) => this.#C(e, t))}
|
|
936
938
|
</div>
|
|
937
939
|
`;
|
|
938
940
|
}
|
|
939
|
-
#
|
|
941
|
+
#C(e, t) {
|
|
940
942
|
let n = e.visualBounds, r = {
|
|
941
943
|
left: `${(t.position.x - n.x) / n.width * 100}%`,
|
|
942
944
|
top: `${(t.position.y - n.y) / n.height * 100}%`
|
|
943
|
-
}, i = this.renderEnemy && this._enemyRenderContent.has(t.instanceId) ? this._enemyRenderContent.get(t.instanceId) ?? l : this.#
|
|
945
|
+
}, i = this.renderEnemy && this._enemyRenderContent.has(t.instanceId) ? this._enemyRenderContent.get(t.instanceId) ?? l : this.#w(t), a = t.enemy?.name ?? t.placement.id;
|
|
944
946
|
return c`
|
|
945
947
|
<div
|
|
946
948
|
class="enemy-anchor"
|
|
@@ -954,7 +956,7 @@ var _ = (e = {}) => {
|
|
|
954
956
|
</div>
|
|
955
957
|
`;
|
|
956
958
|
}
|
|
957
|
-
#
|
|
959
|
+
#w(e) {
|
|
958
960
|
let t = (e.enemy?.name ?? e.placement.id).split(/\s+/).map((e) => e[0]).join("").slice(0, 2).toUpperCase();
|
|
959
961
|
return c`
|
|
960
962
|
<span class="enemy-marker" data-boss=${String(e.enemy?.isBoss === !0)}>
|
|
@@ -962,7 +964,7 @@ var _ = (e = {}) => {
|
|
|
962
964
|
</span>
|
|
963
965
|
`;
|
|
964
966
|
}
|
|
965
|
-
#
|
|
967
|
+
#T(e) {
|
|
966
968
|
let t = e.dungeon.mapImages;
|
|
967
969
|
return !this.showMapSelector || t.length <= 1 ? l : c`
|
|
968
970
|
<div class="map-selector" part="map-selector" role="tablist" aria-label="Dungeon maps">
|
|
@@ -977,16 +979,16 @@ var _ = (e = {}) => {
|
|
|
977
979
|
aria-selected=${String(e.id === this._selectedMap?.id)}
|
|
978
980
|
tabindex=${e.id === this._selectedMap?.id ? "0" : "-1"}
|
|
979
981
|
data-map-index=${String(t)}
|
|
980
|
-
@click=${() => this.#
|
|
981
|
-
@keydown=${this.#
|
|
982
|
+
@click=${() => this.#k(e)}
|
|
983
|
+
@keydown=${this.#A}
|
|
982
984
|
>
|
|
983
|
-
${this.#
|
|
985
|
+
${this.#O(e)}
|
|
984
986
|
</button>
|
|
985
987
|
`)}
|
|
986
988
|
</div>
|
|
987
989
|
`;
|
|
988
990
|
}
|
|
989
|
-
#
|
|
991
|
+
#E() {
|
|
990
992
|
return !this.showControls || !this._model ? l : c`
|
|
991
993
|
<div class="controls" part="controls" role="group" aria-label="Map zoom controls">
|
|
992
994
|
<button
|
|
@@ -1022,7 +1024,7 @@ var _ = (e = {}) => {
|
|
|
1022
1024
|
</div>
|
|
1023
1025
|
`;
|
|
1024
1026
|
}
|
|
1025
|
-
#
|
|
1027
|
+
#D() {
|
|
1026
1028
|
if (this._status === "ready") return l;
|
|
1027
1029
|
let e = this._status === "loading", t = this._status === "empty", n = e ? "Charting dungeon" : t ? "Choose a dungeon" : "Map unavailable", r = e ? "Loading Fellowship data and preparing the tactical layer." : t ? "Set the dungeon-id attribute or dungeonId property to render a map." : this._error?.message ?? "An unexpected map error occurred.";
|
|
1028
1030
|
return c`
|
|
@@ -1036,10 +1038,10 @@ var _ = (e = {}) => {
|
|
|
1036
1038
|
</div>
|
|
1037
1039
|
`;
|
|
1038
1040
|
}
|
|
1039
|
-
#
|
|
1041
|
+
#O(e) {
|
|
1040
1042
|
return this._mapLabels.get(e.id) ?? "Map";
|
|
1041
1043
|
}
|
|
1042
|
-
#
|
|
1044
|
+
#k(e) {
|
|
1043
1045
|
e.id !== this._selectedMap?.id && (this.mapImageId = e.id, this.dispatchEvent(new CustomEvent("fellowship-map-image-change", {
|
|
1044
1046
|
...P,
|
|
1045
1047
|
detail: {
|
|
@@ -1048,39 +1050,39 @@ var _ = (e = {}) => {
|
|
|
1048
1050
|
}
|
|
1049
1051
|
})));
|
|
1050
1052
|
}
|
|
1053
|
+
#A;
|
|
1051
1054
|
#j;
|
|
1052
1055
|
#M;
|
|
1053
1056
|
#N;
|
|
1054
1057
|
#P;
|
|
1055
1058
|
#F;
|
|
1056
|
-
#I
|
|
1057
|
-
#L(e) {
|
|
1059
|
+
#I(e) {
|
|
1058
1060
|
return e.composedPath().some((e) => e instanceof HTMLElement && e.matches("button, a, input, select, textarea, [contenteditable='true']"));
|
|
1059
1061
|
}
|
|
1060
|
-
#
|
|
1062
|
+
#L() {
|
|
1061
1063
|
let e = this._viewportElement, t = this._selectedMap;
|
|
1062
|
-
!e || !t || (this.#
|
|
1064
|
+
!e || !t || (this.#i.setDimensions(e.clientWidth, e.clientHeight, t.width, t.height), this.#R("resize"));
|
|
1063
1065
|
}
|
|
1064
|
-
#
|
|
1065
|
-
this._viewportState = this.#
|
|
1066
|
+
#R(e) {
|
|
1067
|
+
this._viewportState = this.#i.state, this.dispatchEvent(new CustomEvent("fellowship-map-viewport-change", {
|
|
1066
1068
|
...P,
|
|
1067
1069
|
detail: {
|
|
1068
|
-
viewport: this.#
|
|
1070
|
+
viewport: this.#i.state,
|
|
1069
1071
|
source: e
|
|
1070
1072
|
}
|
|
1071
1073
|
}));
|
|
1072
1074
|
}
|
|
1073
|
-
#
|
|
1074
|
-
this.#
|
|
1075
|
+
#z(e, t, n) {
|
|
1076
|
+
this.#l.has(e) || (this.#l.add(e), this.#u.push({
|
|
1075
1077
|
code: t,
|
|
1076
1078
|
message: n instanceof Error ? n.message : String(n),
|
|
1077
1079
|
cause: n
|
|
1078
1080
|
}));
|
|
1079
1081
|
}
|
|
1080
|
-
#
|
|
1081
|
-
if (this.#
|
|
1082
|
-
let e = this.#
|
|
1083
|
-
this.#
|
|
1082
|
+
#B() {
|
|
1083
|
+
if (this.#u.length === 0) return;
|
|
1084
|
+
let e = this.#u;
|
|
1085
|
+
this.#u = [];
|
|
1084
1086
|
for (let t of e) this.dispatchEvent(new CustomEvent("fellowship-map-error", {
|
|
1085
1087
|
...P,
|
|
1086
1088
|
detail: t
|
|
@@ -1093,10 +1095,7 @@ i([d({
|
|
|
1093
1095
|
})], F.prototype, "dungeonId", void 0), i([d({
|
|
1094
1096
|
type: String,
|
|
1095
1097
|
attribute: "map-image-id"
|
|
1096
|
-
})], F.prototype, "mapImageId", void 0), i([d({
|
|
1097
|
-
type: String,
|
|
1098
|
-
attribute: "asset-base-url"
|
|
1099
|
-
})], F.prototype, "assetBaseUrl", void 0), i([d({ attribute: !1 })], F.prototype, "dataSource", void 0), i([d({ attribute: !1 })], F.prototype, "renderEnemy", void 0), i([d({ attribute: !1 })], F.prototype, "renderGroup", void 0), i([d({ attribute: !1 })], F.prototype, "mapLabelFormatter", void 0), i([d({
|
|
1098
|
+
})], F.prototype, "mapImageId", void 0), i([d({ attribute: !1 })], F.prototype, "resolveAssetUrl", void 0), i([d({ attribute: !1 })], F.prototype, "dataSource", void 0), i([d({ attribute: !1 })], F.prototype, "renderEnemy", void 0), i([d({ attribute: !1 })], F.prototype, "renderGroup", void 0), i([d({ attribute: !1 })], F.prototype, "mapLabelFormatter", void 0), i([d({
|
|
1100
1099
|
type: Boolean,
|
|
1101
1100
|
attribute: "show-controls"
|
|
1102
1101
|
})], F.prototype, "showControls", void 0), i([d({
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { FellowshipDataError as e } from "@crockery/fellowship-data/client";
|
|
2
|
+
import { css as t } from "lit";
|
|
3
|
+
//#region src/data/data-source.ts
|
|
4
|
+
var n = 2, r = (t) => {
|
|
5
|
+
if (t !== n) throw new e("unsupported-schema", `Unsupported fellowship-data schema version: ${String(t)}.`);
|
|
6
|
+
}, i = t`
|
|
4
7
|
:host {
|
|
5
8
|
--_fellowship-field-canvas: var(--fellowship-field-canvas, #0b0f13);
|
|
6
9
|
--_fellowship-field-surface: var(--fellowship-field-surface, #10161c);
|
|
@@ -35,56 +38,48 @@ var t = e`
|
|
|
35
38
|
);
|
|
36
39
|
--_fellowship-field-radius: var(--fellowship-field-radius, 6px);
|
|
37
40
|
}
|
|
38
|
-
`,
|
|
41
|
+
`, a = new URL("../assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2", import.meta.url).href, o = new URL("../assets/ibm-plex-mono-latin-600-normal-BgSNZQsw.woff2", import.meta.url).href, s = new URL("../assets/ibm-plex-sans-condensed-latin-400-normal-DKyD6XsY.woff2", import.meta.url).href, c = new URL("../assets/ibm-plex-sans-condensed-latin-500-normal-BqaLkUoX.woff2", import.meta.url).href, l = new URL("../assets/ibm-plex-sans-condensed-latin-600-normal-CRd5VyFf.woff2", import.meta.url).href, u = new URL("../assets/ibm-plex-sans-condensed-latin-700-normal-D8r4s4aS.woff2", import.meta.url).href, d = [
|
|
39
42
|
{
|
|
40
43
|
family: "Fellowship Field",
|
|
41
44
|
weight: "400",
|
|
42
|
-
url:
|
|
45
|
+
url: s
|
|
43
46
|
},
|
|
44
47
|
{
|
|
45
48
|
family: "Fellowship Field",
|
|
46
49
|
weight: "500",
|
|
47
|
-
url:
|
|
50
|
+
url: c
|
|
48
51
|
},
|
|
49
52
|
{
|
|
50
53
|
family: "Fellowship Field",
|
|
51
54
|
weight: "600",
|
|
52
|
-
url:
|
|
55
|
+
url: l
|
|
53
56
|
},
|
|
54
57
|
{
|
|
55
58
|
family: "Fellowship Field",
|
|
56
59
|
weight: "700",
|
|
57
|
-
url:
|
|
60
|
+
url: u
|
|
58
61
|
},
|
|
59
62
|
{
|
|
60
63
|
family: "Fellowship Tactical",
|
|
61
64
|
weight: "500",
|
|
62
|
-
url:
|
|
65
|
+
url: a
|
|
63
66
|
},
|
|
64
67
|
{
|
|
65
68
|
family: "Fellowship Tactical",
|
|
66
69
|
weight: "600",
|
|
67
|
-
url:
|
|
70
|
+
url: o
|
|
68
71
|
}
|
|
69
|
-
],
|
|
70
|
-
if (
|
|
72
|
+
], f = /* @__PURE__ */ new WeakSet(), p = (e) => {
|
|
73
|
+
if (f.has(e)) return;
|
|
71
74
|
let t = e.defaultView?.FontFace;
|
|
72
75
|
if (!t || !e.fonts) return;
|
|
73
|
-
let n =
|
|
76
|
+
let n = d.map(({ family: e, weight: n, url: r }) => new t(e, `url(${JSON.stringify(r)}) format("woff2")`, {
|
|
74
77
|
display: "swap",
|
|
75
78
|
style: "normal",
|
|
76
79
|
weight: n
|
|
77
80
|
}));
|
|
78
81
|
for (let t of n) e.fonts.add(t);
|
|
79
|
-
|
|
82
|
+
f.add(e);
|
|
80
83
|
};
|
|
81
84
|
//#endregion
|
|
82
|
-
|
|
83
|
-
function d(e, t, n, r) {
|
|
84
|
-
var i = arguments.length, a = i < 3 ? t : r === null ? r = Object.getOwnPropertyDescriptor(t, n) : r, o;
|
|
85
|
-
if (typeof Reflect == "object" && typeof Reflect.decorate == "function") a = Reflect.decorate(e, t, n, r);
|
|
86
|
-
else for (var s = e.length - 1; s >= 0; s--) (o = e[s]) && (a = (i < 3 ? o(a) : i > 3 ? o(t, n, a) : o(t, n)) || a);
|
|
87
|
-
return i > 3 && a && Object.defineProperty(t, n, a), a;
|
|
88
|
-
}
|
|
89
|
-
//#endregion
|
|
90
|
-
export { u as n, t as r, d as t };
|
|
85
|
+
export { r as i, i as n, e as r, p as t };
|