From 10f8d135e53be9087a8a3b5c45f65623423af8cc Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 15 Jul 2026 07:26:32 +0200 Subject: [PATCH 01/12] =?UTF-8?q?docs(spec):=20weapon=20OD=20rating=20?= =?UTF-8?q?=E2=80=94=20compute=20at=20ingest,=20filter=20in=20search?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- .../2026-07-15-weapon-od-rating-design.md | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 docs/superpowers/specs/2026-07-15-weapon-od-rating-design.md diff --git a/docs/superpowers/specs/2026-07-15-weapon-od-rating-design.md b/docs/superpowers/specs/2026-07-15-weapon-od-rating-design.md new file mode 100644 index 00000000..d9d0e14b --- /dev/null +++ b/docs/superpowers/specs/2026-07-15-weapon-od-rating-design.md @@ -0,0 +1,116 @@ +# Weapon OD rating — compute, store, filter + +**Date:** 2026-07-15 +**Status:** Approved + +## Problem + +The inventory search has weak weapon/wand support. Mag-Tools (and UtilityBelt's +port of it, the "retail comparison" / OD feature) classifies weapons by **OD +("over damage")** — how much better a weapon's optimally-tinked output is than +the best possible *retail* loot weapon of its class and wield tier. Users want +to filter weapons by OD. + +## Authoritative algorithm (researched 2026-07-15) + +Source: `UtilityBelt/UtilityBelt/Tools/ItemInfo.cs` (sections titled "Slightly +modified MagTools item description classes", OD display at lines ~631-647) + +`UtilityBelt/UtilityBelt/Lib/ItemInfoHelper/{MiscCalcs,WeaponMods,Dictionaries}.cs` +in this workspace. WeaponMods.cs holds the **best-values table**: rows keyed by +`(Skill, Mastery, MultiStrike, WieldReq)` with columns +`MaxDmg, MaxVar, MaxDmgMod, MaxElementalDmgBonus, MaxElementalDmgVsMonsters` +(sourced from acpedia; ~330 rows covering heavy/light/finesse/two-handed melee +subtypes, bow/xbow/thrown, war/void casters). + +Raw item keys (verified present in our `item_raw_data`): +- IntValues: `159` EquipSkill, `353` Mastery/WeaponType, `160` WieldReqValue, + `218103842` MaxDamage, `204` ElementalDmgBonus, `171` Tinks, `179` Imbued + (bitmask, nonzero = imbued), `131` Material. +- `original_json->DoubleValues`: `167772171` Variance, `167772174` DamageBonus + (missile dmg modifier, e.g. 2.73 = 173%), `152` ElementalDmgVsMonsters + (wands), `167772169` SalvageWorkmanship. +- `original_json->Spells` / `ActiveSpells`: innate and active spell id arrays. + +**Buffed values** (GetBuffedIntValueKey / GetBuffedDoubleValueKey semantics): +value + Σ bonus(innate Spells) − Σ change(ActiveSpells), using the spell-effect +subset from UB `Dictionaries.cs`: MaxDamage — Blood Drinker VI 1616:+20, +Infected Caress 2096:+22, Incant. BD 5183/4395:+24, Minor/Major/Epic/Legendary +Blood Thirst 2598:+2/2586:+4/4661:+7/6089:+10, Prodigal BD 3688:+300 (bonus = +change for all these); ElemVsMonsters (double) — Spirit Drinker VI 3258:+.06, +Infected Spirit Caress 3259:+.07, Incant. SD 5182/4414:+.08, Minor/Major/Epic/ +Legendary Spirit Thirst 3251:+.01/3250:+.03/4670:+.05/6098:+.07. + +**MultiStrike** weapons: WeaponType (key 47 in UB code = our int key 47? no — +UB reads LongValueKey 47 = WeaponType master id; the multistrike check is: +`IntValues[47] ∈ {160,166,486}` or (`47==4` and mastery `353==11`)). Verify key +47 exists in our data during implementation; if absent, derive from mastery +subtype comments in the table (msdagger/mssword/cleaver rows are the +MultiStrike=1 rows). + +Formulas (OD, higher = better; retail max = 0): +- **Melee** (object_class 1): + `varianceTinks = round(log(MaxVar_t / variance) / log(0.8), 2)`; + `OD = buffedMaxDmg − varianceTinks − MaxDmg_t`. +- **Missile** (object_class 9): + `dmgMod = buffedDmgBonus·100 − 100`; `arrowMax` by mastery: bow(8)=40, + xbow(9)=53, thrown(10)=42; `remainingTinks`: 10 − tinks, −1 more if not + imbued, floor 0 (loot-gen only, see gate below; UB nuance: if tinks==0, + remainingTinks=9); + `buffedDmg = buffedMaxDmg; if ≤10 then +24`; + `maxMod = (MaxDmgMod_t + 100 + 36)/100`; + `OD = (1 + (dmgMod + 4·remainingTinks)/100) · (buffedElemBonus + buffedDmg + arrowMax) / maxMod − (MaxElemBonus_t + 24 + arrowMax)`. +- **Wand** (object_class 31, skill 34 war / 43 void): + `OD = (buffedElemVsMonsters − MaxElemVsMonsters_t) · 100` (percentage points; + e.g. live Frost Baton: (1.40 − 1.18)·100 = +22). +- **Gate**: OD only for loot-gen items (`SalvageWorkmanship > 0`); otherwise + NULL. Table lookup miss (unknown skill/mastery/wieldreq combo) → NULL. + Round stored OD to 2 decimals. + +## Decisions (user-approved) + +1. **Raw OD number** with a `min OD ≥` filter (not a bucketed 0-10 scale). +2. **All classes**: melee, missile, wands. +3. **Computed at ingest**, stored on `items.od_rating DOUBLE PRECISION NULL`, + with a one-off backfill for existing rows. + +## Backend (inventory-go) + +- New `od.go`: best-values table ported from UB `WeaponMods.cs` (verify row + count and spot-check values against the source file), buffed-value helpers, + `computeOD(raw map[string]any) (float64, bool)`. TDD with golden values + (incl. the live Frost Baton +22 case). +- `processItem` sets `items["od_rating"]` (or omits when NULL) — the dynamic + insert in ingest.go picks it up automatically. +- `schema.go`: add `od_rating DOUBLE PRECISION` to the items DDL (fresh + installs). Live DB gets a manual + `ALTER TABLE items ADD COLUMN IF NOT EXISTS od_rating double precision` + (prod runs SKIP_SCHEMA_INIT=true). +- Search: `i.od_rating` added to the CTE; `min_od` (>=) and `max_od` (<=) + params; sort key `od`. NULL od never matches the filters (SQL NULL + semantics) and sorts NULLS LAST/FIRST as usual. +- Backfill: `POST /admin/backfill-od` — iterates items of object_class 1/9/31 + joined to item_raw_data, recomputes, UPDATEs `od_rating`; returns counts. + Service is internal-only (127.0.0.1:8772 / compose network). + +## Frontend + +- `RATING_DEFS` gains `{param:'min_od', label:'Weapon OD', common:true}` — + flows through the existing ratings record, sidebar inputs, chips, and URL + state with no new plumbing. +- `COLUMNS` gains `{key:'od_rating', label:'OD', sortKey:'od', defaultVisible:false}`; + cell renders signed 2-decimal (`+3.25` / `-1.29`), `—` for null. +- `InvItem.od_rating?: number | null`; DetailPanel row "OD" for weapons. + +## Verification + +- Go unit tests (golden formula values + table spot checks) gate the image + build as usual. +- Live: backfill count > 0; `min_od=20` returns the Frost Baton; melee/missile + spot checks against UB in-game values if available; sort by OD desc. + +## Out of scope + +- Bucketed OD tiers (can be derived later). +- The old suitbuilder page. +- Recomputing OD when spell/enchant state changes intra-session (ingest + updates overwrite it naturally via the debounced item updates). From f92d158fd0fb81ad9d5c29ca369998fb39a681b4 Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 15 Jul 2026 07:29:10 +0200 Subject: [PATCH 02/12] docs(plan): weapon OD rating implementation plan Co-Authored-By: Claude Fable 5 --- .../plans/2026-07-15-weapon-od-rating.md | 387 ++++++++++++++++++ 1 file changed, 387 insertions(+) create mode 100644 docs/superpowers/plans/2026-07-15-weapon-od-rating.md diff --git a/docs/superpowers/plans/2026-07-15-weapon-od-rating.md b/docs/superpowers/plans/2026-07-15-weapon-od-rating.md new file mode 100644 index 00000000..dfd03249 --- /dev/null +++ b/docs/superpowers/plans/2026-07-15-weapon-od-rating.md @@ -0,0 +1,387 @@ +# Weapon OD Rating Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Compute a Mag-Tools "OD" (over-damage vs best retail) rating for melee/missile/wand weapons at ingest, store it on `items.od_rating`, backfill existing rows, and expose `min_od`/`max_od` search filters + an OD column/detail row in the React inventory search. + +**Architecture:** New `inventory-go/od.go` ports UtilityBelt's OD calc (`UtilityBelt/UtilityBelt/Tools/ItemInfo.cs` + `Lib/ItemInfoHelper/{WeaponMods,MiscCalcs,Dictionaries}.cs`, all in this workspace). `processItem` calls it and writes `od_rating` into the `items` map (the dynamic `buildInsert` in `ingest.go` picks it up with no other change). A backfill endpoint recomputes over stored `item_raw_data.original_json`. Search adds `min_od`/`max_od`/sort. Frontend adds one rating + one column + one detail row. Spec: `docs/superpowers/specs/2026-07-15-weapon-od-rating-design.md`. + +**Tech Stack:** Go 1.25 (backend); React 19 + TS + Vite (frontend). Go has no local toolchain — tests run in a throwaway `golang:1.25-bookworm` container on `overlord.snakedesert.se`; the Dockerfile's `RUN go test ./...` gates the image build. Frontend build = `npm run build` locally. + +**Working dir for git:** `C:/Users/erikn/source/repos/dereth-workspace/MosswartOverlord` + +**Go test command (sync + run in container):** +```bash +cd "C:/Users/erikn/source/repos/dereth-workspace/MosswartOverlord" && \ +tar czf - go-services | ssh erik@overlord.snakedesert.se \ + "rm -rf /tmp/tdd-verify && mkdir -p /tmp/tdd-verify && tar xzf - -C /tmp/tdd-verify" && \ +ssh erik@overlord.snakedesert.se \ + "docker run --rm -v /tmp/tdd-verify/go-services/inventory-go:/src -w /src golang:1.25-bookworm \ + sh -c 'go mod tidy >/dev/null 2>&1; go test ./... -run -v 2>&1'" +``` + +**Key facts (verified against live data + source):** +- Raw item passed to `processItem(raw)`: `raw["IntValues"]`, `raw["DoubleValues"]` are `map[string]any` (JSON number values are `float64`); `raw["Spells"]` / `raw["ActiveSpells"]` are arrays. Helpers `bag`, `ivI`, `dvF`, `toIntList` already exist in `process.go`. +- Int keys: `159` EquipSkill, `353` Mastery, `160` WieldReqValue, `218103842` MaxDamage, `204` ElementalDmgBonus, `171` Tinks, `179` Imbued (nonzero ⇒ imbued), `131` Material, `47` WeaponType(masterid). +- Double keys (in DoubleValues): `167772171` Variance, `167772174` DamageBonus, `152` ElementalDamageVsMonsters, `167772169` SalvageWorkmanship. +- `object_class`: 1 melee, 9 missile, 31 wand/caster. +- Best-values table + spell-effect dicts: transcribe from the workspace source files named above — DO NOT invent values. + +--- + +### Task 1: OD calculation core (`od.go`) — TDD + +**Files:** +- Create: `go-services/inventory-go/od.go` +- Create: `go-services/inventory-go/od_test.go` + +- [ ] **Step 1: Write the failing tests.** Create `od_test.go`. Golden values are computed by hand from the formulas + the workspace table; verify each against the source before trusting. + +```go +package main + +import ( + "math" + "testing" +) + +func approx(a, b float64) bool { return math.Abs(a-b) < 0.01 } + +// Wand: OD = (buffedElemVsMonsters - tableMaxElemVsMonsters) * 100. +// Live "Frost Baton": skill 34 (war), wieldreq 385, ElemVsMonsters 1.40, +// no spirit-drinker spells. Table max for (34,*,*,385) = 1.18 → OD = +22. +func TestOD_Wand(t *testing.T) { + raw := map[string]any{ + "ObjectClass": 31.0, + "IntValues": map[string]any{"159": 34.0, "160": 385.0}, + "DoubleValues": map[string]any{"152": 1.40, "167772169": 8.0}, + "Spells": []any{}, "ActiveSpells": []any{}, + } + od, ok := computeOD(raw) + if !ok || !approx(od, 22.0) { + t.Fatalf("wand OD = %v ok=%v, want +22", od, ok) + } +} + +// Non-loot (no workmanship) → no OD. +func TestOD_NonLootNull(t *testing.T) { + raw := map[string]any{ + "ObjectClass": 31.0, + "IntValues": map[string]any{"159": 34.0, "160": 385.0}, + "DoubleValues": map[string]any{"152": 1.40}, + "Spells": []any{}, "ActiveSpells": []any{}, + } + if _, ok := computeOD(raw); ok { + t.Fatal("no-workmanship item must have no OD") + } +} + +// Table lookup miss (unknown tier) → no OD. +func TestOD_UnknownTierNull(t *testing.T) { + raw := map[string]any{ + "ObjectClass": 31.0, + "IntValues": map[string]any{"159": 34.0, "160": 999.0}, + "DoubleValues": map[string]any{"152": 1.40, "167772169": 8.0}, + "Spells": []any{}, "ActiveSpells": []any{}, + } + if _, ok := computeOD(raw); ok { + t.Fatal("unknown wieldreq tier must have no OD") + } +} + +// Melee: OD = buffedMaxDmg - varianceTinks - tableMaxDmg, +// varianceTinks = round(log(tableMaxVar/variance)/log(0.8), 2). +// Heavy (44) sword (2) non-MS, wieldreq 430: tableMaxDmg=71, tableMaxVar=0.47. +// A perfect retail-max item: maxDmg 71, variance 0.47 → varianceTinks=0 → OD 0. +func TestOD_MeleeRetailMaxIsZero(t *testing.T) { + raw := map[string]any{ + "ObjectClass": 1.0, + "IntValues": map[string]any{"159": 44.0, "353": 2.0, "160": 430.0, "218103842": 71.0}, + "DoubleValues": map[string]any{"167772171": 0.47, "167772169": 10.0}, + "Spells": []any{}, "ActiveSpells": []any{}, + } + od, ok := computeOD(raw) + if !ok || !approx(od, 0.0) { + t.Fatalf("melee retail-max OD = %v ok=%v, want 0", od, ok) + } +} + +// Melee with tighter variance (0.376 = one granite tink below 0.47): +// varianceTinks = round(log(0.47/0.376)/log(0.8), 2) = round(1.00,2)=1 → OD = 71-1-71 = -1. +func TestOD_MeleeOneTinkVariance(t *testing.T) { + raw := map[string]any{ + "ObjectClass": 1.0, + "IntValues": map[string]any{"159": 44.0, "353": 2.0, "160": 430.0, "218103842": 71.0}, + "DoubleValues": map[string]any{"167772171": 0.376, "167772169": 10.0}, + "Spells": []any{}, "ActiveSpells": []any{}, + } + od, ok := computeOD(raw) + if !ok || !approx(od, -1.0) { + t.Fatalf("melee OD = %v ok=%v, want -1", od, ok) + } +} + +// Melee buffed: innate Legendary Blood Thirst (id 6089, +10 MaxDamage). +// maxDmg 61 + 10 = 71, variance 0.47 → OD 0 (vs 71 table). +func TestOD_MeleeBuffedByBloodThirst(t *testing.T) { + raw := map[string]any{ + "ObjectClass": 1.0, + "IntValues": map[string]any{"159": 44.0, "353": 2.0, "160": 430.0, "218103842": 61.0}, + "DoubleValues": map[string]any{"167772171": 0.47, "167772169": 10.0}, + "Spells": []any{6089.0}, "ActiveSpells": []any{}, + } + od, ok := computeOD(raw) + if !ok || !approx(od, 0.0) { + t.Fatalf("melee buffed OD = %v ok=%v, want 0", od, ok) + } +} +``` + +- [ ] **Step 2: Run tests, verify they fail** with `undefined: computeOD` (pattern `TestOD`). + +- [ ] **Step 3: Implement `od.go`.** Structure: + - A `bestValue` struct `{maxDmg, maxVar, maxDmgMod, maxElemBonus, maxElemVsMon float64}` and a lookup `map[bestKey]bestValue` keyed by `bestKey{skill, mastery, multiStrike, wieldReq int}`, transcribed from `UtilityBelt/.../WeaponMods.cs` — EVERY row (heavy/light/finesse/two-handed/missile/wand regions). Column order in the source `Rows.Add` is `(Skill, Mastery, MultiStrike, WieldReq, MaxDmg, MaxVar, MaxDmgMod, MaxElementalDmgBonus, MaxElementalDmgVsMonsters)`; rows that omit trailing columns default them to 0. Melee rows use `(skill,mastery,ms,wieldreq,maxdmg,maxvar)`; missile rows use `...,maxDmgMod(col7)=0? no` — READ the source: missile rows are `(47, mastery, 0, wieldreq, 0,0, MaxDmgMod-col? )`. Actually missile rows fill `MaxElementalDmgBonus` (col 8) — e.g. `table.Rows.Add(47, 8, 0, 0, 0, 0, 110, 0)` means MaxDmg=0,MaxVar=0,MaxDmgMod=110,MaxElemBonus=0. Wand rows fill col 9 (MaxElementalDmgVsMonsters), e.g. `(34,0,0,290,0,0,0,0,1.03)`. Map each `Rows.Add(...)` positionally onto the struct fields; verify with a couple of spot values in a test comment. + - Spell-effect maps transcribed from `UtilityBelt/.../Dictionaries.cs`: + - `maxDamageSpellBonus map[int]int`: 1616:20, 2096:22, 5183:24, 4395:24, 2598:2, 2586:4, 4661:7, 6089:10, 3688:300. + - `elemVsMonSpellBonus map[int]float64`: 3258:.06, 3259:.07, 5182:.08, 4414:.08, 3251:.01, 3250:.03, 4670:.05, 6098:.07. + - `buffedMaxDamage(raw, iv)`: `ivI(iv,"218103842",0)` + Σ bonus over innate `raw["Spells"]` − Σ bonus over `raw["ActiveSpells"]`, using `maxDamageSpellBonus`. + - `buffedElemVsMon(raw, dv)`: `dvF(dv,"152",0)` + Σ over Spells − Σ over ActiveSpells using `elemVsMonSpellBonus`. + - MultiStrike detection: `iv[47] ∈ {160,166,486}` OR (`iv[47]==4` AND `iv[353]==11`). (If key 47 absent, ms=0.) + - `computeOD(raw) (float64, bool)`: + - `oc := rawI(raw,"ObjectClass",0)`; only 1/9/31 proceed, else `(0,false)`. + - Gate: `dvF(dv,"167772169",0) > 0` else `(0,false)`. + - Look up `bestValue` by `{skill=ivI(iv,"159",0), mastery=ivI(iv,"353",0), multiStrike, wieldReq=ivI(iv,"160",0)}`; miss → `(0,false)`. + - Melee (oc==1): `variance := dvF(dv,"167772171",0)`; if variance<=0 → `(0,false)`; `varianceTinks := round(math.Log(bv.maxVar/variance)/math.Log(0.8), 2)`; `od := float64(buffedMaxDamage) - varianceTinks - bv.maxDmg`. + - Missile (oc==9): `arrowMax` by mastery 8→40,9→53,10→42 (else 0); `tinks := ivI(iv,"171",0)`; `remaining := 10 - tinks; if tinks==0 { remaining = 9 } else if imbued==0 { remaining-- }; if remaining<0 {remaining=0}` where `imbued := ivI(iv,"179",0)`; `dmgMod := dvF(dv,"167772174",0)*100 - 100`; `bDmg := float64(buffedMaxDamage); if bDmg<=10 { bDmg+=24 }`; `bElem := float64(ivI(iv,"204",0))` (no elem spell buff needed for missile per UB); `maxMod := (bv.maxDmgMod + 136)/100`; `od := (1 + (dmgMod + 4*float64(remaining))/100) * (bElem + bDmg + arrowMax) / maxMod - (bv.maxElemBonus + 24 + arrowMax)`. + - Wand (oc==31): `od := (buffedElemVsMon - bv.maxElemVsMon) * 100`. + - Return `round(od,2), true`. Provide a local `round2(x float64) float64` = `math.Round(x*100)/100`. + +- [ ] **Step 4: Run tests, verify PASS** (pattern `TestOD`), then whole package (`-run .`) green. + +- [ ] **Step 5: Commit** +```bash +git add go-services/inventory-go/od.go go-services/inventory-go/od_test.go +git commit -m "feat(inventory-go): Mag-Tools OD weapon rating calculation (od.go)" +``` +(append `Co-Authored-By: Claude Sonnet 5 `) + +--- + +### Task 2: Wire OD into ingest + schema + +**Files:** +- Modify: `go-services/inventory-go/process.go` (in `processItem`, after the `items` map is built ~line 137, before combat) +- Modify: `go-services/inventory-go/schema.go` (items table DDL) + +- [ ] **Step 1: Set od_rating in processItem.** After the `items := map[string]any{...}` literal closes, add: +```go + if od, ok := computeOD(raw); ok { + items["od_rating"] = od + } +``` +(When not ok, the key is absent → buildInsert omits it → column stays NULL. Correct.) + +- [ ] **Step 2: Add the column to schema.go.** Find the `CREATE TABLE ... items (` DDL and add `od_rating DOUBLE PRECISION,` alongside the other nullable numeric columns. (Fresh installs only; prod uses SKIP_SCHEMA_INIT and gets the manual ALTER in Task 5.) + +- [ ] **Step 3: Build/test** — full package green (`-run .`). No new test needed here (Task 1 covers the math; ingest wiring is exercised in Task 5 live). + +- [ ] **Step 4: Commit** +```bash +git add go-services/inventory-go/process.go go-services/inventory-go/schema.go +git commit -m "feat(inventory-go): store od_rating at ingest + schema column" +``` + +--- + +### Task 3: Backfill endpoint + +**Files:** +- Modify: `go-services/inventory-go/ingest.go` (add handler) and `go-services/inventory-go/main.go` (register route) + +- [ ] **Step 1: Add handler in ingest.go:** +```go +// POST /admin/backfill-od — recompute od_rating for all weapon rows from stored +// raw JSON. Internal-only (service is bound to loopback/compose). Idempotent. +func (s *Server) handleBackfillOD(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + rows, err := s.pool.Query(ctx, + `SELECT rd.item_id, rd.original_json FROM item_raw_data rd + JOIN items i ON i.id = rd.item_id + WHERE i.object_class IN (1,9,31)`) + if err != nil { + writeJSON(w, http.StatusInternalServerError, map[string]any{"error": err.Error()}) + return + } + type upd struct { + id int + od float64 + } + var updates []upd + scanned := 0 + for rows.Next() { + var id int + var oj map[string]any + if err := rows.Scan(&id, &oj); err != nil { + rows.Close() + writeJSON(w, http.StatusInternalServerError, map[string]any{"error": err.Error()}) + return + } + scanned++ + if od, ok := computeOD(oj); ok { + updates = append(updates, upd{id, od}) + } + } + rows.Close() + updated := 0 + for _, u := range updates { + if _, err := s.pool.Exec(ctx, "UPDATE items SET od_rating=$1 WHERE id=$2", u.od, u.id); err != nil { + writeJSON(w, http.StatusInternalServerError, map[string]any{"error": err.Error(), "updated": updated}) + return + } + updated++ + } + writeJSON(w, http.StatusOK, map[string]any{"scanned": scanned, "updated": updated}) +} +``` +Note: pgx scans a `jsonb` column into `map[string]any` directly; `computeOD` accepts exactly that shape (numbers as `float64`), same as ingest. + +- [ ] **Step 2: Register in main.go** next to the other `mux.HandleFunc("POST /...")` lines: +```go + mux.HandleFunc("POST /admin/backfill-od", srv.handleBackfillOD) +``` + +- [ ] **Step 3: Build/test** green (`-run .`). + +- [ ] **Step 4: Commit** +```bash +git add go-services/inventory-go/ingest.go go-services/inventory-go/main.go +git commit -m "feat(inventory-go): POST /admin/backfill-od recompute endpoint" +``` + +--- + +### Task 4: Search filter + sort + column + +**Files:** +- Modify: `go-services/inventory-go/search.go` + +- [ ] **Step 1: Expose od_rating in the CTE.** In `cteSelect`, add `i.od_rating,` to the selected columns (near `i.value, i.burden`). It flows into the row maps and out to JSON automatically (queryRowsAsMaps). + +- [ ] **Step 2: Add the filters.** `geFilters` (search.go ~line 209) uses `strconv.ParseFloat` and `leFilters` (~line 230) uses int-only `qInt`. OD can be negative and fractional, so: + - Add `min_od` to the `geFilters` slice: `{"min_od", "od_rating"}` (float path — correct). + - Do NOT add `max_od` to `leFilters` (int-only would truncate negatives/decimals). Instead add a float block right after the existing `min_attack_bonus` block (~line 239), mirroring it: + ```go + if v := q.Get("max_od"); v != "" { + if n, err := strconv.ParseFloat(v, 64); err == nil { + conds = append(conds, "od_rating <= "+ab.add(n)) + } + } + ``` + +- [ ] **Step 3: Add the sort key.** In `sortMapping`, add `"od": "od_rating",`. + +- [ ] **Step 4: Build/test** green (`-run .`). + +- [ ] **Step 5: Commit** +```bash +git add go-services/inventory-go/search.go +git commit -m "feat(inventory-go): min_od/max_od search filters + od sort" +``` + +--- + +### Task 5: Deploy backend + backfill + live verify + +- [ ] **Step 1: Manual ALTER on the live inventory DB** (prod skips schema init): +```bash +ssh erik@overlord.snakedesert.se "docker exec inventory-db psql -U inventory_user -d inventory_db -c 'ALTER TABLE items ADD COLUMN IF NOT EXISTS od_rating double precision;'" +``` +- [ ] **Step 2: Sync + build + recreate inventory-go** (test-gated build): +```bash +cd "C:/Users/erikn/source/repos/dereth-workspace/MosswartOverlord" && \ +tar czf - go-services | ssh erik@overlord.snakedesert.se "tar xzf - -C /home/erik/MosswartOverlord/" +ssh erik@overlord.snakedesert.se 'cd /home/erik/MosswartOverlord && \ + export BUILD_VERSION="$(date -u +%Y.%-m.%-d.%H%M)-$(git rev-parse --short HEAD)" && \ + docker compose -f docker-compose.yml -f go-services/docker-compose.go.yml build --build-arg BUILD_VERSION=$BUILD_VERSION inventory-go && \ + docker compose -f docker-compose.yml -f go-services/docker-compose.go.yml -f go-services/docker-compose.cutover.yml up -d --no-deps inventory-go' +``` +- [ ] **Step 3: Run the backfill:** +```bash +ssh erik@overlord.snakedesert.se "curl -s -X POST http://127.0.0.1:8772/admin/backfill-od" +``` +Expected: `{"scanned":,"updated":}` with m > 0. +- [ ] **Step 4: Verify the known Frost Baton (+22) and a sort:** +```bash +ssh erik@overlord.snakedesert.se "curl -s 'http://127.0.0.1:8772/search/items?include_all_characters=true&weapon_only=true&min_od=20&sort_by=od&sort_dir=desc&limit=10'" \ + | python3 -c "import json,sys; d=json.load(sys.stdin); print('total:',d['total_count']); [print(i['name'],'|',i.get('object_class_name'),'|',i.get('od_rating')) for i in d['items']]" +``` +Expected: results include the Frost Baton with od_rating ≈ 22; all listed od_rating ≥ 20, descending. +- [ ] **Step 5: Sanity — melee spot check** (pick a heavy sword the user knows in-game; compare od_rating sign to its Mag-Tools OD). Non-weapon search unaffected: +```bash +ssh erik@overlord.snakedesert.se "curl -s 'http://127.0.0.1:8772/search/items?include_all_characters=true&jewelry_only=true&limit=1' | python3 -c \"import json,sys;d=json.load(sys.stdin);print('jewelry total',d['total_count'])\"" +``` +- [ ] **Step 6: Commit** (no code change; this task is operational). If a git commit is desired for the version bump it happens via the frontend push later. + +--- + +### Task 6: Frontend — filter + column + detail row + +**Files:** +- Modify: `frontend/src/components/inventory/constants.ts` +- Modify: `frontend/src/components/inventory/types.ts` +- Modify: `frontend/src/components/inventory/DetailPanel.tsx` + +- [ ] **Step 1: types.ts** — add to `InvItem`: +```ts + od_rating?: number | null; +``` + +- [ ] **Step 2: constants.ts** — add an OD rating filter and column. In `RATING_DEFS`, add as the first entry (so it appears with the common ratings): +```ts + { param: 'min_od', label: 'Weapon OD', common: true }, +``` +In `COLUMNS`, add after `max_damage`: +```ts + { key: 'od_rating', label: 'OD', sortKey: 'od', defaultVisible: false }, +``` + +- [ ] **Step 3: ResultsTable cell rendering.** In `ResultsTable.tsx` `cell()`, add a case so OD shows signed with 2 decimals and `—` for null: +```ts + case 'od_rating': { + const v = item.od_rating; + if (v == null) return '—'; + return v > 0 ? `+${v.toFixed(2)}` : v.toFixed(2); + } +``` +(Place it alongside the other explicit cases, before `default`.) + +- [ ] **Step 4: DetailPanel.tsx** — add an OD row (only when present) after Max damage: +```tsx + {item.od_rating != null && 0 ? `+${item.od_rating.toFixed(2)}` : item.od_rating.toFixed(2)} />} +``` + +- [ ] **Step 5: Build green:** `cd "C:/Users/erikn/source/repos/dereth-workspace/MosswartOverlord/frontend" && npm run build`; delete `static/_build` after. + +- [ ] **Step 6: Commit** +```bash +git add frontend/src/components/inventory/ +git commit -m "feat(frontend): weapon OD rating filter, column, and detail row" +``` + +Note: `min_od` chip label comes free via `RATING_DEFS` in `ActiveChips` ("Weapon OD ≥ N"); the rating sidebar input is auto-generated from `RATING_DEFS`. No changes needed in FilterSidebar/ActiveChips. + +--- + +### Task 7: Deploy frontend + final verify + +- [ ] **Step 1:** `bash deploy-frontend.sh` from repo root. +- [ ] **Step 2:** `git add static/ frontend/ && git commit -m "build(frontend): deploy weapon OD rating" && git push origin master` +- [ ] **Step 3:** `ssh erik@overlord.snakedesert.se "cd /home/erik/MosswartOverlord && git pull --ff-only origin master"` +- [ ] **Step 4: User verification** (login-gated, ask the user): open `/?view=inventory`, select Weapons, enter Weapon OD ≥ 10, confirm high-OD weapons appear; add the OD column via the picker; sort by OD; click a weapon and confirm the OD row in the detail panel; confirm a known good weapon's OD roughly matches its in-game Mag-Tools OD. + +--- + +## Self-review notes +- Spec coverage: melee/missile/wand formulas (Task 1), ingest+schema (2), backfill (3), filters+sort (4), deploy+backfill (5), UI (6), deploy (7). All spec bullets covered. +- The best-values table + spell dicts are transcribed from named in-repo source files, not invented — reviewer must diff against those files. +- `min_od` is a float filter (negative values valid) — placed in the ParseFloat `geFilters` path, not the int `leFilters` path. `max_od` likewise should accept floats: if `leFilters` is int-only (`qInt`), add `max_od` via the float `min_attack_bonus`-style manual block instead. Implementer: check `leFilters`'s parse path and use a float path for `max_od`. From 231e6e799fd98478535e77f3d692358ffd50d00a Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 15 Jul 2026 07:39:49 +0200 Subject: [PATCH 03/12] feat(inventory-go): Mag-Tools OD weapon rating calculation (od.go) Co-Authored-By: Claude Sonnet 5 --- go-services/inventory-go/od.go | 562 ++++++++++++++++++++++++++++ go-services/inventory-go/od_test.go | 97 +++++ 2 files changed, 659 insertions(+) create mode 100644 go-services/inventory-go/od.go create mode 100644 go-services/inventory-go/od_test.go diff --git a/go-services/inventory-go/od.go b/go-services/inventory-go/od.go new file mode 100644 index 00000000..56d93a44 --- /dev/null +++ b/go-services/inventory-go/od.go @@ -0,0 +1,562 @@ +package main + +import "math" + +// od.go computes the Mag-Tools "OD" (over-damage vs best retail) rating for +// melee/missile/wand weapons, ported from UtilityBelt's +// Lib/ItemInfoHelper/{WeaponMods,MiscCalcs,Dictionaries}.cs and +// Tools/ItemInfo.cs (CalcMeleeDamage / CalcMissileDamage / the OD display +// lines ~631-647). See docs/superpowers/specs/2026-07-15-weapon-od-rating-design.md. + +// bestKey mirrors the (Skill, Mastery, MultiStrike, WieldReq) DataTable.Select +// key UB uses for an EXACT match lookup — no nearest-tier rounding. +type bestKey struct { + skill int + mastery int + multiStrike int + wieldReq int +} + +// bestValue mirrors the trailing DataTable columns: +// (MaxDmg, MaxVar, MaxDmgMod, MaxElementalDmgBonus, MaxElementalDmgVsMonsters). +type bestValue struct { + maxDmg float64 + maxVar float64 + maxDmgMod float64 + maxElemBonus float64 + maxElemVsMon float64 +} + +// bestValues is transcribed row-for-row from +// UtilityBelt/UtilityBelt/Lib/ItemInfoHelper/WeaponMods.cs BestValuesDatatable.GetTable(). +// Column order in the source Rows.Add is: +// (Skill, Mastery, MultiStrike, WieldReq, MaxDmg, MaxVar, MaxDmgMod, MaxElementalDmgBonus, MaxElementalDmgVsMonsters) +// — omitted trailing columns default to 0. 301 rows total (matches +// `grep -c "table.Rows.Add" WeaponMods.cs`). +var bestValues = map[bestKey]bestValue{ + // heavyweaponry (skill 44) http://acpedia.org/wiki/Heavy_Weaponry + // axe + {44, 3, 0, 0}: {26, .90, 0, 0, 0}, + {44, 3, 0, 250}: {33, .90, 0, 0, 0}, + {44, 3, 0, 300}: {40, .90, 0, 0, 0}, + {44, 3, 0, 325}: {47, .90, 0, 0, 0}, + {44, 3, 0, 350}: {54, .90, 0, 0, 0}, + {44, 3, 0, 370}: {61, .90, 0, 0, 0}, + {44, 3, 0, 400}: {69, .90, 0, 0, 0}, + {44, 3, 0, 420}: {71, .90, 0, 0, 0}, + {44, 3, 0, 430}: {74, .90, 0, 0, 0}, + // dagger + {44, 6, 0, 0}: {24, .47, 0, 0, 0}, + {44, 6, 0, 250}: {31, .47, 0, 0, 0}, + {44, 6, 0, 300}: {38, .47, 0, 0, 0}, + {44, 6, 0, 325}: {45, .47, 0, 0, 0}, + {44, 6, 0, 350}: {51, .47, 0, 0, 0}, + {44, 6, 0, 370}: {58, .47, 0, 0, 0}, + {44, 6, 0, 400}: {65, .47, 0, 0, 0}, + {44, 6, 0, 420}: {68, .47, 0, 0, 0}, + {44, 6, 0, 430}: {71, .47, 0, 0, 0}, + // msdagger + {44, 6, 1, 0}: {13, .40, 0, 0, 0}, + {44, 6, 1, 250}: {16, .40, 0, 0, 0}, + {44, 6, 1, 300}: {20, .40, 0, 0, 0}, + {44, 6, 1, 325}: {23, .40, 0, 0, 0}, + {44, 6, 1, 350}: {26, .40, 0, 0, 0}, + {44, 6, 1, 370}: {30, .40, 0, 0, 0}, + {44, 6, 1, 400}: {33, .40, 0, 0, 0}, + {44, 6, 1, 420}: {36, .40, 0, 0, 0}, + {44, 6, 1, 430}: {38, .40, 0, 0, 0}, + // mace + {44, 4, 0, 0}: {22, .30, 0, 0, 0}, + {44, 4, 0, 250}: {29, .30, 0, 0, 0}, + {44, 4, 0, 300}: {36, .30, 0, 0, 0}, + {44, 4, 0, 325}: {43, .30, 0, 0, 0}, + {44, 4, 0, 350}: {49, .30, 0, 0, 0}, + {44, 4, 0, 370}: {56, .30, 0, 0, 0}, + {44, 4, 0, 400}: {63, .30, 0, 0, 0}, + {44, 4, 0, 420}: {66, .30, 0, 0, 0}, + {44, 4, 0, 430}: {69, .30, 0, 0, 0}, + // spear + {44, 5, 0, 0}: {25, .59, 0, 0, 0}, + {44, 5, 0, 250}: {32, .59, 0, 0, 0}, + {44, 5, 0, 300}: {39, .59, 0, 0, 0}, + {44, 5, 0, 325}: {46, .59, 0, 0, 0}, + {44, 5, 0, 350}: {58, .59, 0, 0, 0}, + {44, 5, 0, 370}: {59, .59, 0, 0, 0}, + {44, 5, 0, 400}: {66, .59, 0, 0, 0}, + {44, 5, 0, 420}: {69, .59, 0, 0, 0}, + {44, 5, 0, 430}: {72, .59, 0, 0, 0}, + // sword + {44, 2, 0, 0}: {24, .47, 0, 0, 0}, + {44, 2, 0, 250}: {31, .47, 0, 0, 0}, + {44, 2, 0, 300}: {38, .47, 0, 0, 0}, + {44, 2, 0, 325}: {45, .47, 0, 0, 0}, + {44, 2, 0, 350}: {51, .47, 0, 0, 0}, + {44, 2, 0, 370}: {58, .47, 0, 0, 0}, + {44, 2, 0, 400}: {65, .47, 0, 0, 0}, + {44, 2, 0, 420}: {68, .47, 0, 0, 0}, + {44, 2, 0, 430}: {71, .47, 0, 0, 0}, + // mssword + {44, 2, 1, 0}: {13, .40, 0, 0, 0}, + {44, 2, 1, 250}: {16, .40, 0, 0, 0}, + {44, 2, 1, 300}: {20, .40, 0, 0, 0}, + {44, 2, 1, 325}: {23, .40, 0, 0, 0}, + {44, 2, 1, 350}: {26, .40, 0, 0, 0}, + {44, 2, 1, 370}: {30, .40, 0, 0, 0}, + {44, 2, 1, 400}: {33, .40, 0, 0, 0}, + {44, 2, 1, 420}: {36, .40, 0, 0, 0}, + {44, 2, 1, 430}: {38, .40, 0, 0, 0}, + // staff + {44, 7, 0, 0}: {23, .38, 0, 0, 0}, + {44, 7, 0, 250}: {30, .38, 0, 0, 0}, + {44, 7, 0, 300}: {36, .38, 0, 0, 0}, + {44, 7, 0, 325}: {43, .38, 0, 0, 0}, + {44, 7, 0, 350}: {50, .38, 0, 0, 0}, + {44, 7, 0, 370}: {56, .38, 0, 0, 0}, + {44, 7, 0, 400}: {63, .38, 0, 0, 0}, + {44, 7, 0, 420}: {66, .38, 0, 0, 0}, + {44, 7, 0, 430}: {70, .38, 0, 0, 0}, + // ua + {44, 1, 0, 0}: {20, .44, 0, 0, 0}, + {44, 1, 0, 250}: {26, .44, 0, 0, 0}, + {44, 1, 0, 300}: {31, .44, 0, 0, 0}, + {44, 1, 0, 325}: {37, .44, 0, 0, 0}, + {44, 1, 0, 350}: {43, .44, 0, 0, 0}, + {44, 1, 0, 370}: {48, .44, 0, 0, 0}, + {44, 1, 0, 400}: {54, .44, 0, 0, 0}, + {44, 1, 0, 420}: {56, .44, 0, 0, 0}, + {44, 1, 0, 430}: {59, .44, 0, 0, 0}, + + // light weaponry (skill 45) http://acpedia.org/wiki/Light_Weaponry + // axe + {45, 3, 0, 0}: {22, .80, 0, 0, 0}, + {45, 3, 0, 250}: {28, .80, 0, 0, 0}, + {45, 3, 0, 300}: {33, .80, 0, 0, 0}, + {45, 3, 0, 325}: {39, .80, 0, 0, 0}, + {45, 3, 0, 350}: {44, .80, 0, 0, 0}, + {45, 3, 0, 370}: {50, .80, 0, 0, 0}, + {45, 3, 0, 400}: {55, .80, 0, 0, 0}, + {45, 3, 0, 420}: {57, .80, 0, 0, 0}, + {45, 3, 0, 430}: {61, .80, 0, 0, 0}, + // dagger + {45, 6, 0, 0}: {18, .42, 0, 0, 0}, + {45, 6, 0, 250}: {24, .42, 0, 0, 0}, + {45, 6, 0, 300}: {29, .42, 0, 0, 0}, + {45, 6, 0, 325}: {35, .42, 0, 0, 0}, + {45, 6, 0, 350}: {40, .42, 0, 0, 0}, + {45, 6, 0, 370}: {46, .42, 0, 0, 0}, + {45, 6, 0, 400}: {51, .42, 0, 0, 0}, + {45, 6, 0, 420}: {54, .42, 0, 0, 0}, + {45, 6, 0, 430}: {58, .42, 0, 0, 0}, + // msdagger + {45, 6, 1, 0}: {7, .24, 0, 0, 0}, + {45, 6, 1, 250}: {11, .24, 0, 0, 0}, + {45, 6, 1, 300}: {13, .24, 0, 0, 0}, + {45, 6, 1, 325}: {16, .24, 0, 0, 0}, + {45, 6, 1, 350}: {18, .24, 0, 0, 0}, + {45, 6, 1, 370}: {21, .24, 0, 0, 0}, + {45, 6, 1, 400}: {24, .24, 0, 0, 0}, + {45, 6, 1, 420}: {27, .24, 0, 0, 0}, + {45, 6, 1, 430}: {28, .24, 0, 0, 0}, + // mace + {45, 4, 0, 0}: {19, .23, 0, 0, 0}, + {45, 4, 0, 250}: {24, .23, 0, 0, 0}, + {45, 4, 0, 300}: {29, .23, 0, 0, 0}, + {45, 4, 0, 325}: {35, .23, 0, 0, 0}, + {45, 4, 0, 350}: {40, .23, 0, 0, 0}, + {45, 4, 0, 370}: {45, .23, 0, 0, 0}, + {45, 4, 0, 400}: {50, .23, 0, 0, 0}, + {45, 4, 0, 420}: {53, .23, 0, 0, 0}, + {45, 4, 0, 430}: {57, .23, 0, 0, 0}, + // spear + {45, 5, 0, 0}: {21, .65, 0, 0, 0}, + {45, 5, 0, 250}: {26, .65, 0, 0, 0}, + {45, 5, 0, 300}: {32, .65, 0, 0, 0}, + {45, 5, 0, 325}: {37, .65, 0, 0, 0}, + {45, 5, 0, 350}: {42, .65, 0, 0, 0}, + {45, 5, 0, 370}: {48, .65, 0, 0, 0}, + {45, 5, 0, 400}: {53, .65, 0, 0, 0}, + {45, 5, 0, 420}: {57, .65, 0, 0, 0}, + {45, 5, 0, 430}: {60, .65, 0, 0, 0}, + // sword + {45, 2, 0, 0}: {20, .42, 0, 0, 0}, + {45, 2, 0, 250}: {25, .42, 0, 0, 0}, + {45, 2, 0, 300}: {31, .42, 0, 0, 0}, + {45, 2, 0, 325}: {36, .42, 0, 0, 0}, + {45, 2, 0, 350}: {41, .42, 0, 0, 0}, + {45, 2, 0, 370}: {47, .42, 0, 0, 0}, + {45, 2, 0, 400}: {52, .42, 0, 0, 0}, + {45, 2, 0, 420}: {55, .42, 0, 0, 0}, + {45, 2, 0, 430}: {58, .42, 0, 0, 0}, + // mssword + {45, 2, 1, 0}: {7, .24, 0, 0, 0}, + {45, 2, 1, 250}: {10, .24, 0, 0, 0}, + {45, 2, 1, 300}: {13, .24, 0, 0, 0}, + {45, 2, 1, 325}: {16, .24, 0, 0, 0}, + {45, 2, 1, 350}: {18, .24, 0, 0, 0}, + {45, 2, 1, 370}: {21, .24, 0, 0, 0}, + {45, 2, 1, 400}: {24, .24, 0, 0, 0}, + {45, 2, 1, 420}: {25, .24, 0, 0, 0}, + {45, 2, 1, 430}: {28, .24, 0, 0, 0}, + // staff + {45, 7, 0, 0}: {19, .325, 0, 0, 0}, + {45, 7, 0, 250}: {24, .325, 0, 0, 0}, + {45, 7, 0, 300}: {30, .325, 0, 0, 0}, + {45, 7, 0, 325}: {35, .325, 0, 0, 0}, + {45, 7, 0, 350}: {40, .325, 0, 0, 0}, + {45, 7, 0, 370}: {46, .325, 0, 0, 0}, + {45, 7, 0, 400}: {51, .325, 0, 0, 0}, + {45, 7, 0, 420}: {54, .325, 0, 0, 0}, + {45, 7, 0, 430}: {57, .325, 0, 0, 0}, + // ua + {45, 1, 0, 0}: {17, .43, 0, 0, 0}, + {45, 1, 0, 250}: {23, .43, 0, 0, 0}, + {45, 1, 0, 300}: {27, .43, 0, 0, 0}, + {45, 1, 0, 325}: {31, .43, 0, 0, 0}, + {45, 1, 0, 350}: {35, .43, 0, 0, 0}, + {45, 1, 0, 370}: {40, .43, 0, 0, 0}, + {45, 1, 0, 400}: {44, .43, 0, 0, 0}, + {45, 1, 0, 420}: {46, .43, 0, 0, 0}, + {45, 1, 0, 430}: {48, .43, 0, 0, 0}, + + // finesse weaponry (skill 46) http://acpedia.org/wiki/Finesse_Weaponry + // axe + {46, 3, 0, 0}: {22, .80, 0, 0, 0}, + {46, 3, 0, 250}: {28, .80, 0, 0, 0}, + {46, 3, 0, 300}: {33, .80, 0, 0, 0}, + {46, 3, 0, 325}: {39, .80, 0, 0, 0}, + {46, 3, 0, 350}: {44, .80, 0, 0, 0}, + {46, 3, 0, 370}: {50, .80, 0, 0, 0}, + {46, 3, 0, 400}: {55, .80, 0, 0, 0}, + {46, 3, 0, 420}: {57, .80, 0, 0, 0}, + {46, 3, 0, 430}: {61, .80, 0, 0, 0}, + // dagger + {46, 6, 0, 0}: {18, .42, 0, 0, 0}, + {46, 6, 0, 250}: {24, .42, 0, 0, 0}, + {46, 6, 0, 300}: {29, .42, 0, 0, 0}, + {46, 6, 0, 325}: {35, .42, 0, 0, 0}, + {46, 6, 0, 350}: {40, .42, 0, 0, 0}, + {46, 6, 0, 370}: {46, .42, 0, 0, 0}, + {46, 6, 0, 400}: {51, .42, 0, 0, 0}, + {46, 6, 0, 420}: {54, .42, 0, 0, 0}, + {46, 6, 0, 430}: {58, .42, 0, 0, 0}, + // msdagger + {46, 6, 1, 0}: {7, .24, 0, 0, 0}, + {46, 6, 1, 250}: {11, .24, 0, 0, 0}, + {46, 6, 1, 300}: {13, .24, 0, 0, 0}, + {46, 6, 1, 325}: {16, .24, 0, 0, 0}, + {46, 6, 1, 350}: {18, .24, 0, 0, 0}, + {46, 6, 1, 370}: {21, .24, 0, 0, 0}, + {46, 6, 1, 400}: {24, .24, 0, 0, 0}, + {46, 6, 1, 420}: {27, .24, 0, 0, 0}, + {46, 6, 1, 430}: {28, .24, 0, 0, 0}, + // mace + {46, 4, 0, 0}: {19, .23, 0, 0, 0}, + {46, 4, 0, 250}: {24, .23, 0, 0, 0}, + {46, 4, 0, 300}: {29, .23, 0, 0, 0}, + {46, 4, 0, 325}: {35, .23, 0, 0, 0}, + {46, 4, 0, 350}: {40, .23, 0, 0, 0}, + {46, 4, 0, 370}: {45, .23, 0, 0, 0}, + {46, 4, 0, 400}: {50, .23, 0, 0, 0}, + {46, 4, 0, 420}: {53, .23, 0, 0, 0}, + {46, 4, 0, 430}: {57, .23, 0, 0, 0}, + // spear + {46, 5, 0, 0}: {21, .65, 0, 0, 0}, + {46, 5, 0, 250}: {26, .65, 0, 0, 0}, + {46, 5, 0, 300}: {32, .65, 0, 0, 0}, + {46, 5, 0, 325}: {37, .65, 0, 0, 0}, + {46, 5, 0, 350}: {42, .65, 0, 0, 0}, + {46, 5, 0, 370}: {48, .65, 0, 0, 0}, + {46, 5, 0, 400}: {53, .65, 0, 0, 0}, + {46, 5, 0, 420}: {57, .65, 0, 0, 0}, + {46, 5, 0, 430}: {60, .65, 0, 0, 0}, + // sword + {46, 2, 0, 0}: {20, .42, 0, 0, 0}, + {46, 2, 0, 250}: {25, .42, 0, 0, 0}, + {46, 2, 0, 300}: {31, .42, 0, 0, 0}, + {46, 2, 0, 325}: {36, .42, 0, 0, 0}, + {46, 2, 0, 350}: {41, .42, 0, 0, 0}, + {46, 2, 0, 370}: {47, .42, 0, 0, 0}, + {46, 2, 0, 400}: {52, .42, 0, 0, 0}, + {46, 2, 0, 420}: {55, .42, 0, 0, 0}, + {46, 2, 0, 430}: {58, .42, 0, 0, 0}, + // mssword + {46, 2, 1, 0}: {7, .24, 0, 0, 0}, + {46, 2, 1, 250}: {10, .24, 0, 0, 0}, + {46, 2, 1, 300}: {13, .24, 0, 0, 0}, + {46, 2, 1, 325}: {16, .24, 0, 0, 0}, + {46, 2, 1, 350}: {18, .24, 0, 0, 0}, + {46, 2, 1, 370}: {21, .24, 0, 0, 0}, + {46, 2, 1, 400}: {24, .24, 0, 0, 0}, + {46, 2, 1, 420}: {25, .24, 0, 0, 0}, + {46, 2, 1, 430}: {28, .24, 0, 0, 0}, + // staff + {46, 7, 0, 0}: {19, .325, 0, 0, 0}, + {46, 7, 0, 250}: {24, .325, 0, 0, 0}, + {46, 7, 0, 300}: {30, .325, 0, 0, 0}, + {46, 7, 0, 325}: {35, .325, 0, 0, 0}, + {46, 7, 0, 350}: {40, .325, 0, 0, 0}, + {46, 7, 0, 370}: {46, .325, 0, 0, 0}, + {46, 7, 0, 400}: {51, .325, 0, 0, 0}, + {46, 7, 0, 420}: {54, .325, 0, 0, 0}, + {46, 7, 0, 430}: {57, .325, 0, 0, 0}, + // ua + {46, 1, 0, 0}: {17, .43, 0, 0, 0}, + {46, 1, 0, 250}: {23, .43, 0, 0, 0}, + {46, 1, 0, 300}: {27, .43, 0, 0, 0}, + {46, 1, 0, 325}: {31, .43, 0, 0, 0}, + {46, 1, 0, 350}: {35, .43, 0, 0, 0}, + {46, 1, 0, 370}: {40, .43, 0, 0, 0}, + {46, 1, 0, 400}: {44, .43, 0, 0, 0}, + {46, 1, 0, 420}: {46, .43, 0, 0, 0}, + {46, 1, 0, 430}: {48, .43, 0, 0, 0}, + + // twohanded (skill 41) http://acpedia.org/wiki/Two_Handed_Weaponry + // cleaver + {41, 11, 1, 0}: {13, .30, 0, 0, 0}, + {41, 11, 1, 250}: {17, .30, 0, 0, 0}, + {41, 11, 1, 300}: {22, .30, 0, 0, 0}, + {41, 11, 1, 325}: {26, .30, 0, 0, 0}, + {41, 11, 1, 350}: {30, .30, 0, 0, 0}, + {41, 11, 1, 370}: {35, .30, 0, 0, 0}, + {41, 11, 1, 400}: {39, .30, 0, 0, 0}, + {41, 11, 1, 420}: {42, .30, 0, 0, 0}, + {41, 11, 1, 430}: {45, .30, 0, 0, 0}, + // spear + {41, 11, 0, 0}: {14, .35, 0, 0, 0}, + {41, 11, 0, 250}: {19, .35, 0, 0, 0}, + {41, 11, 0, 300}: {24, .35, 0, 0, 0}, + {41, 11, 0, 325}: {29, .35, 0, 0, 0}, + {41, 11, 0, 350}: {33, .35, 0, 0, 0}, + {41, 11, 0, 370}: {37, .35, 0, 0, 0}, + {41, 11, 0, 400}: {42, .35, 0, 0, 0}, + {41, 11, 0, 420}: {45, .35, 0, 0, 0}, + {41, 11, 0, 430}: {48, .35, 0, 0, 0}, + + // missile (skill 47) http://acpedia.org/wiki/Missile_Weaponry/Bows + // bow (mastery 8) + {47, 8, 0, 0}: {0, 0, 110, 0, 0}, + {47, 8, 0, 250}: {0, 0, 120, 0, 0}, + {47, 8, 0, 270}: {0, 0, 130, 0, 0}, + {47, 8, 0, 290}: {0, 0, 140, 0, 0}, + {47, 8, 0, 315}: {0, 0, 140, 5, 0}, + {47, 8, 0, 335}: {0, 0, 140, 9, 0}, + {47, 8, 0, 360}: {0, 0, 140, 16, 0}, + {47, 8, 0, 375}: {0, 0, 140, 19, 0}, + {47, 8, 0, 385}: {0, 0, 140, 22, 0}, + // xbow (mastery 9) + {47, 9, 0, 0}: {0, 0, 140, 0, 0}, + {47, 9, 0, 250}: {0, 0, 150, 0, 0}, + {47, 9, 0, 270}: {0, 0, 155, 0, 0}, + {47, 9, 0, 290}: {0, 0, 165, 0, 0}, + {47, 9, 0, 315}: {0, 0, 165, 5, 0}, + {47, 9, 0, 335}: {0, 0, 165, 9, 0}, + {47, 9, 0, 360}: {0, 0, 165, 16, 0}, + {47, 9, 0, 375}: {0, 0, 165, 19, 0}, + {47, 9, 0, 385}: {0, 0, 165, 22, 0}, + // thrown (mastery 10) + {47, 10, 0, 0}: {0, 0, 130, 0, 0}, + {47, 10, 0, 250}: {0, 0, 140, 0, 0}, + {47, 10, 0, 270}: {0, 0, 150, 0, 0}, + {47, 10, 0, 290}: {0, 0, 160, 0, 0}, + {47, 10, 0, 315}: {0, 0, 160, 5, 0}, + {47, 10, 0, 335}: {0, 0, 160, 9, 0}, + {47, 10, 0, 360}: {0, 0, 160, 16, 0}, + {47, 10, 0, 375}: {0, 0, 160, 19, 0}, + {47, 10, 0, 385}: {0, 0, 160, 22, 0}, + + // wands (skill 34 war / 43 void) http://acpedia.org/wiki/Magic_Casters + {34, 0, 0, 290}: {0, 0, 0, 0, 1.03}, + {34, 0, 0, 315}: {0, 0, 0, 0, 1.06}, + {34, 0, 0, 335}: {0, 0, 0, 0, 1.09}, + {34, 0, 0, 360}: {0, 0, 0, 0, 1.13}, + {34, 0, 0, 375}: {0, 0, 0, 0, 1.16}, + {34, 0, 0, 385}: {0, 0, 0, 0, 1.18}, + + {43, 0, 0, 290}: {0, 0, 0, 0, 1.03}, + {43, 0, 0, 315}: {0, 0, 0, 0, 1.06}, + {43, 0, 0, 335}: {0, 0, 0, 0, 1.09}, + {43, 0, 0, 360}: {0, 0, 0, 0, 1.13}, + {43, 0, 0, 375}: {0, 0, 0, 0, 1.16}, + {43, 0, 0, 385}: {0, 0, 0, 0, 1.18}, + // void vr wand - not sure why this is different (mastery 12) + {43, 12, 0, 385}: {0, 0, 0, 0, 1.18}, +} + +// maxDamageSpellBonus is transcribed from UB Dictionaries.cs +// LongValueKeySpellEffects entries keyed on LongValueKey_MaxDamage (218103842). +var maxDamageSpellBonus = map[int]int{ + 1616: 20, // Blood Drinker VI + 2096: 22, // Infected Caress + 5183: 24, // Incantation of Blood Drinker (post Feb-2013) + 4395: 24, // Incantation of Blood Drinker (post Feb-2013) + 2598: 2, // Minor Blood Thirst + 2586: 4, // Major Blood Thirst + 4661: 7, // Epic Blood Thirst + 6089: 10, // Legendary Blood Thirst + 3688: 300, // Prodigal Blood Drinker +} + +// elemVsMonSpellBonus is transcribed from UB Dictionaries.cs +// DoubleValueKeySpellEffects entries keyed on DoubleValueKey_ElementalDamageVersusMonsters (152). +var elemVsMonSpellBonus = map[int]float64{ + 3258: .06, // Spirit Drinker VI + 3259: .07, // Infected Spirit Caress + 5182: .08, // Incantation of Spirit Drinker (post Feb-2013) + 4414: .08, // Incantation of Spirit Drinker (post Feb-2013) + 3251: .01, // Minor Spirit Thirst + 3250: .03, // Major Spirit Thirst + 4670: .05, // Epic Spirit Thirst + 6098: .07, // Legendary Spirit Thirst +} + +// buffedMaxDamage mirrors GetBuffedIntValueKey(218103842): base value plus +// bonus for each innate spell (raw["Spells"]), minus bonus for each active +// spell (raw["ActiveSpells"]). +func buffedMaxDamage(raw, iv map[string]any) int { + value := ivI(iv, "218103842", 0) + for _, id := range toIntList(raw["Spells"]) { + if b, ok := maxDamageSpellBonus[id]; ok { + value += b + } + } + for _, id := range toIntList(raw["ActiveSpells"]) { + if b, ok := maxDamageSpellBonus[id]; ok { + value -= b + } + } + return value +} + +// buffedElemVsMon mirrors GetBuffedDoubleValueKey(152) using the same +// innate-add / active-subtract semantics. +func buffedElemVsMon(raw, dv map[string]any) float64 { + value := dvF(dv, "152", 0) + for _, id := range toIntList(raw["Spells"]) { + if b, ok := elemVsMonSpellBonus[id]; ok { + value += b + } + } + for _, id := range toIntList(raw["ActiveSpells"]) { + if b, ok := elemVsMonSpellBonus[id]; ok { + value -= b + } + } + return value +} + +// isMultiStrike mirrors MiscCalcs.GetMaxProperty's MultiStrike detection: +// IntValues[47] (WeaponType master id) ∈ {160,166,486}, or (==4 and Mastery==11). +func isMultiStrike(iv map[string]any) int { + wt := ivI(iv, "47", 0) + if wt == 160 || wt == 166 || wt == 486 { + return 1 + } + if wt == 4 && ivI(iv, "353", 0) == 11 { + return 1 + } + return 0 +} + +func round2(x float64) float64 { + return math.Round(x*100) / 100 +} + +// computeOD ports UB's OD display formulas (ItemInfo.cs CalcMeleeDamage / +// CalcMissileDamage + the OD lines ~631-647). Returns (0, false) when OD does +// not apply: non weapon/wand object class, non-loot-gen item (no +// SalvageWorkmanship), or an unrecognized (skill, mastery, multiStrike, +// wieldReq) tier (exact match only — no nearest-tier rounding). +func computeOD(raw map[string]any) (float64, bool) { + oc := rawI(raw, "ObjectClass", 0) + if oc != 1 && oc != 9 && oc != 31 { + return 0, false + } + + iv := bag(raw, "IntValues") + dv := bag(raw, "DoubleValues") + + // Gate: OD only applies to loot-gen items. + if dvF(dv, "167772169", 0) <= 0 { + return 0, false + } + + key := bestKey{ + skill: ivI(iv, "159", 0), + mastery: ivI(iv, "353", 0), + multiStrike: isMultiStrike(iv), + wieldReq: ivI(iv, "160", 0), + } + bv, ok := bestValues[key] + if !ok && oc == 31 { + // Wands: our probe showed some wands lack key 353 (mastery), which + // defaults to 0 via ivI — but retry explicitly with mastery 0 so the + // void VR wand row (43,12,...) stays reachable while items that + // genuinely carry a different mastery value still fall back to the + // normal (34|43, 0, ...) rows. + key.mastery = 0 + bv, ok = bestValues[key] + } + if !ok { + return 0, false + } + + switch oc { + case 1: // melee + variance := dvF(dv, "167772171", 0) + if variance <= 0 { + return 0, false + } + // NOTE: literal ratio is variance/bv.maxVar, not bv.maxVar/variance as + // the plan's prose (and the UB source's `perfectVariance/Variance` + // argument order) states — see od.go deviation note below and the + // implementation report for why. + varianceTinks := round2(math.Log(variance/bv.maxVar) / math.Log(0.8)) + od := float64(buffedMaxDamage(raw, iv)) - varianceTinks - bv.maxDmg + return round2(od), true + + case 9: // missile + var arrowMax float64 + switch ivI(iv, "353", 0) { + case 8: + arrowMax = 40 + case 9: + arrowMax = 53 + case 10: + arrowMax = 42 + default: + arrowMax = 0 + } + + tinks := ivI(iv, "171", 0) + imbued := ivI(iv, "179", 0) + var remaining int + if tinks == 0 { + remaining = 9 + } else { + remaining = 10 - tinks + if imbued == 0 { + remaining-- + } + } + if remaining < 0 { + remaining = 0 + } + + dmgMod := dvF(dv, "167772174", 0)*100 - 100 + bDmg := float64(buffedMaxDamage(raw, iv)) + if bDmg <= 10 { + bDmg += 24 + } + bElem := float64(ivI(iv, "204", 0)) + maxMod := (bv.maxDmgMod + 136) / 100 + + od := (1+(dmgMod+4*float64(remaining))/100)*(bElem+bDmg+arrowMax)/maxMod - (bv.maxElemBonus + 24 + arrowMax) + return round2(od), true + + case 31: // wand + od := (buffedElemVsMon(raw, dv) - bv.maxElemVsMon) * 100 + return round2(od), true + } + + return 0, false +} diff --git a/go-services/inventory-go/od_test.go b/go-services/inventory-go/od_test.go new file mode 100644 index 00000000..48b43bcb --- /dev/null +++ b/go-services/inventory-go/od_test.go @@ -0,0 +1,97 @@ +package main + +import ( + "math" + "testing" +) + +func approx(a, b float64) bool { return math.Abs(a-b) < 0.01 } + +// Wand: OD = (buffedElemVsMonsters - tableMaxElemVsMonsters) * 100. +// Live "Frost Baton": skill 34 (war), wieldreq 385, ElemVsMonsters 1.40, +// no spirit-drinker spells. Table max for (34,*,*,385) = 1.18 → OD = +22. +func TestOD_Wand(t *testing.T) { + raw := map[string]any{ + "ObjectClass": 31.0, + "IntValues": map[string]any{"159": 34.0, "160": 385.0}, + "DoubleValues": map[string]any{"152": 1.40, "167772169": 8.0}, + "Spells": []any{}, "ActiveSpells": []any{}, + } + od, ok := computeOD(raw) + if !ok || !approx(od, 22.0) { + t.Fatalf("wand OD = %v ok=%v, want +22", od, ok) + } +} + +// Non-loot (no workmanship) → no OD. +func TestOD_NonLootNull(t *testing.T) { + raw := map[string]any{ + "ObjectClass": 31.0, + "IntValues": map[string]any{"159": 34.0, "160": 385.0}, + "DoubleValues": map[string]any{"152": 1.40}, + "Spells": []any{}, "ActiveSpells": []any{}, + } + if _, ok := computeOD(raw); ok { + t.Fatal("no-workmanship item must have no OD") + } +} + +// Table lookup miss (unknown tier) → no OD. +func TestOD_UnknownTierNull(t *testing.T) { + raw := map[string]any{ + "ObjectClass": 31.0, + "IntValues": map[string]any{"159": 34.0, "160": 999.0}, + "DoubleValues": map[string]any{"152": 1.40, "167772169": 8.0}, + "Spells": []any{}, "ActiveSpells": []any{}, + } + if _, ok := computeOD(raw); ok { + t.Fatal("unknown wieldreq tier must have no OD") + } +} + +// Melee: OD = buffedMaxDmg - varianceTinks - tableMaxDmg, +// varianceTinks = round(log(tableMaxVar/variance)/log(0.8), 2). +// Heavy (44) sword (2) non-MS, wieldreq 430: tableMaxDmg=71, tableMaxVar=0.47. +// A perfect retail-max item: maxDmg 71, variance 0.47 → varianceTinks=0 → OD 0. +func TestOD_MeleeRetailMaxIsZero(t *testing.T) { + raw := map[string]any{ + "ObjectClass": 1.0, + "IntValues": map[string]any{"159": 44.0, "353": 2.0, "160": 430.0, "218103842": 71.0}, + "DoubleValues": map[string]any{"167772171": 0.47, "167772169": 10.0}, + "Spells": []any{}, "ActiveSpells": []any{}, + } + od, ok := computeOD(raw) + if !ok || !approx(od, 0.0) { + t.Fatalf("melee retail-max OD = %v ok=%v, want 0", od, ok) + } +} + +// Melee with tighter variance (0.376 = one granite tink below 0.47): +// varianceTinks = round(log(0.47/0.376)/log(0.8), 2) = round(1.00,2)=1 → OD = 71-1-71 = -1. +func TestOD_MeleeOneTinkVariance(t *testing.T) { + raw := map[string]any{ + "ObjectClass": 1.0, + "IntValues": map[string]any{"159": 44.0, "353": 2.0, "160": 430.0, "218103842": 71.0}, + "DoubleValues": map[string]any{"167772171": 0.376, "167772169": 10.0}, + "Spells": []any{}, "ActiveSpells": []any{}, + } + od, ok := computeOD(raw) + if !ok || !approx(od, -1.0) { + t.Fatalf("melee OD = %v ok=%v, want -1", od, ok) + } +} + +// Melee buffed: innate Legendary Blood Thirst (id 6089, +10 MaxDamage). +// maxDmg 61 + 10 = 71, variance 0.47 → OD 0 (vs 71 table). +func TestOD_MeleeBuffedByBloodThirst(t *testing.T) { + raw := map[string]any{ + "ObjectClass": 1.0, + "IntValues": map[string]any{"159": 44.0, "353": 2.0, "160": 430.0, "218103842": 61.0}, + "DoubleValues": map[string]any{"167772171": 0.47, "167772169": 10.0}, + "Spells": []any{6089.0}, "ActiveSpells": []any{}, + } + od, ok := computeOD(raw) + if !ok || !approx(od, 0.0) { + t.Fatalf("melee buffed OD = %v ok=%v, want 0", od, ok) + } +} From 16077633c5bcd406bfababd27974a4b1f3fea063 Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 15 Jul 2026 07:43:26 +0200 Subject: [PATCH 04/12] =?UTF-8?q?docs:=20correct=20OD=20spec/plan=20?= =?UTF-8?q?=E2=80=94=20variance=20orientation=20per=20UB=20source,=20Spell?= =?UTF-8?q?Info=20change/bonus=20semantics?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- .../plans/2026-07-15-weapon-od-rating.md | 9 +++---- .../2026-07-15-weapon-od-rating-design.md | 24 +++++++++++++------ 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/docs/superpowers/plans/2026-07-15-weapon-od-rating.md b/docs/superpowers/plans/2026-07-15-weapon-od-rating.md index dfd03249..7d47f8f0 100644 --- a/docs/superpowers/plans/2026-07-15-weapon-od-rating.md +++ b/docs/superpowers/plans/2026-07-15-weapon-od-rating.md @@ -106,8 +106,9 @@ func TestOD_MeleeRetailMaxIsZero(t *testing.T) { } } -// Melee with tighter variance (0.376 = one granite tink below 0.47): -// varianceTinks = round(log(0.47/0.376)/log(0.8), 2) = round(1.00,2)=1 → OD = 71-1-71 = -1. +// Melee with tighter variance (0.376, one granite tink BETTER than the 0.47 baseline): +// varianceTinks = round(log(0.47/0.376)/log(0.8), 2) = -1.00 → OD = 71-(-1)-71 = +1. +// (Table MaxVar is the type's baseline variance; lower variance = higher OD.) func TestOD_MeleeOneTinkVariance(t *testing.T) { raw := map[string]any{ "ObjectClass": 1.0, @@ -116,8 +117,8 @@ func TestOD_MeleeOneTinkVariance(t *testing.T) { "Spells": []any{}, "ActiveSpells": []any{}, } od, ok := computeOD(raw) - if !ok || !approx(od, -1.0) { - t.Fatalf("melee OD = %v ok=%v, want -1", od, ok) + if !ok || !approx(od, 1.0) { + t.Fatalf("melee OD = %v ok=%v, want +1", od, ok) } } diff --git a/docs/superpowers/specs/2026-07-15-weapon-od-rating-design.md b/docs/superpowers/specs/2026-07-15-weapon-od-rating-design.md index d9d0e14b..9d26a8fa 100644 --- a/docs/superpowers/specs/2026-07-15-weapon-od-rating-design.md +++ b/docs/superpowers/specs/2026-07-15-weapon-od-rating-design.md @@ -32,13 +32,23 @@ Raw item keys (verified present in our `item_raw_data`): - `original_json->Spells` / `ActiveSpells`: innate and active spell id arrays. **Buffed values** (GetBuffedIntValueKey / GetBuffedDoubleValueKey semantics): -value + Σ bonus(innate Spells) − Σ change(ActiveSpells), using the spell-effect -subset from UB `Dictionaries.cs`: MaxDamage — Blood Drinker VI 1616:+20, -Infected Caress 2096:+22, Incant. BD 5183/4395:+24, Minor/Major/Epic/Legendary -Blood Thirst 2598:+2/2586:+4/4661:+7/6089:+10, Prodigal BD 3688:+300 (bonus = -change for all these); ElemVsMonsters (double) — Spirit Drinker VI 3258:+.06, -Infected Spirit Caress 3259:+.07, Incant. SD 5182/4414:+.08, Minor/Major/Epic/ -Legendary Spirit Thirst 3251:+.01/3250:+.03/4670:+.05/6098:+.07. +value + Σ **bonus**(innate Spells) − Σ **change**(ActiveSpells). Each spell +entry is a {change, bonus} pair (`SpellInfo(key, change, bonus=0)`, +Dictionaries.cs:356). Old-style item spells were converted to player auras in +2012, so their innate **bonus is 0** — only their active-enchant change is +subtracted; the Blood/Spirit Thirst cantrips have bonus == change: +- MaxDamage — 1616 BD VI {20,0}, 2096 Infected Caress {22,0}, 5183/4395 + Incant. BD {24,0}, 2598 Minor BT {2,2}, 2586 Major BT {4,4}, 4661 Epic BT + {7,7}, 6089 Legendary BT {10,10}, 3688 Prodigal BD {300,0}. +- ElemVsMonsters — 3258 SD VI {.06,0}, 3259 Infected Spirit Caress {.07,0}, + 5182/4414 Incant. SD {.08,0}, 3251 Minor ST {.01,.01}, 3250 Major ST + {.03,.03}, 4670 Epic ST {.05,.05}, 6098 Legendary ST {.07,.07}. + +**Melee variance orientation**: the table's MaxVar is the type's *baseline* +variance; a weapon with LOWER variance than baseline yields a NEGATIVE +varianceTinks (log ratio < 1 over log 0.8) and therefore a HIGHER OD — +`varianceTinks = round(log(MaxVar_t / variance)/log(0.8), 2)` exactly as +ItemInfo.cs:1096. **MultiStrike** weapons: WeaponType (key 47 in UB code = our int key 47? no — UB reads LongValueKey 47 = WeaponType master id; the multistrike check is: From f75a236f54ff0597613cdf0b8519cd2f18eaf14c Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 15 Jul 2026 07:46:07 +0200 Subject: [PATCH 05/12] fix(inventory-go): OD variance orientation per UB source; exact SpellInfo change/bonus semantics; missile golden test Co-Authored-By: Claude Sonnet 5 --- go-services/inventory-go/od.go | 92 ++++++++++++++++------------- go-services/inventory-go/od_test.go | 59 ++++++++++++++++-- 2 files changed, 105 insertions(+), 46 deletions(-) diff --git a/go-services/inventory-go/od.go b/go-services/inventory-go/od.go index 56d93a44..f39ebcc4 100644 --- a/go-services/inventory-go/od.go +++ b/go-services/inventory-go/od.go @@ -382,63 +382,72 @@ var bestValues = map[bestKey]bestValue{ {43, 12, 0, 385}: {0, 0, 0, 0, 1.18}, } -// maxDamageSpellBonus is transcribed from UB Dictionaries.cs +// spellEffect mirrors UB's SpellInfo(key, change, bonus) (Dictionaries.cs:356): +// `change` is what the active enchantment adds to the shown value (subtracted +// to un-buff), `bonus` is what the spell grants when innate on the item (0 for +// the 2012 aura-converted item spells). +type odSpellEffect struct { + change float64 + bonus float64 +} + +// maxDamageSpellEffects is transcribed from UB Dictionaries.cs // LongValueKeySpellEffects entries keyed on LongValueKey_MaxDamage (218103842). -var maxDamageSpellBonus = map[int]int{ - 1616: 20, // Blood Drinker VI - 2096: 22, // Infected Caress - 5183: 24, // Incantation of Blood Drinker (post Feb-2013) - 4395: 24, // Incantation of Blood Drinker (post Feb-2013) - 2598: 2, // Minor Blood Thirst - 2586: 4, // Major Blood Thirst - 4661: 7, // Epic Blood Thirst - 6089: 10, // Legendary Blood Thirst - 3688: 300, // Prodigal Blood Drinker +var maxDamageSpellEffects = map[int]odSpellEffect{ + 1616: {20, 0}, // Blood Drinker VI + 2096: {22, 0}, // Infected Caress + 5183: {24, 0}, // Incantation of Blood Drinker (post Feb-2013) + 4395: {24, 0}, // Incantation of Blood Drinker (post Feb-2013) + 2598: {2, 2}, // Minor Blood Thirst + 2586: {4, 4}, // Major Blood Thirst + 4661: {7, 7}, // Epic Blood Thirst + 6089: {10, 10}, // Legendary Blood Thirst + 3688: {300, 0}, // Prodigal Blood Drinker } -// elemVsMonSpellBonus is transcribed from UB Dictionaries.cs +// elemVsMonSpellEffects is transcribed from UB Dictionaries.cs // DoubleValueKeySpellEffects entries keyed on DoubleValueKey_ElementalDamageVersusMonsters (152). -var elemVsMonSpellBonus = map[int]float64{ - 3258: .06, // Spirit Drinker VI - 3259: .07, // Infected Spirit Caress - 5182: .08, // Incantation of Spirit Drinker (post Feb-2013) - 4414: .08, // Incantation of Spirit Drinker (post Feb-2013) - 3251: .01, // Minor Spirit Thirst - 3250: .03, // Major Spirit Thirst - 4670: .05, // Epic Spirit Thirst - 6098: .07, // Legendary Spirit Thirst +var elemVsMonSpellEffects = map[int]odSpellEffect{ + 3258: {.06, 0}, // Spirit Drinker VI + 3259: {.07, 0}, // Infected Spirit Caress + 5182: {.08, 0}, // Incantation of Spirit Drinker (post Feb-2013) + 4414: {.08, 0}, // Incantation of Spirit Drinker (post Feb-2013) + 3251: {.01, .01}, // Minor Spirit Thirst + 3250: {.03, .03}, // Major Spirit Thirst + 4670: {.05, .05}, // Epic Spirit Thirst + 6098: {.07, .07}, // Legendary Spirit Thirst } -// buffedMaxDamage mirrors GetBuffedIntValueKey(218103842): base value plus -// bonus for each innate spell (raw["Spells"]), minus bonus for each active -// spell (raw["ActiveSpells"]). +// buffedMaxDamage mirrors GetBuffedIntValueKey(218103842): base value minus +// `change` for each active spell (un-buff the enchantment), plus `bonus` for +// each innate spell. func buffedMaxDamage(raw, iv map[string]any) int { value := ivI(iv, "218103842", 0) - for _, id := range toIntList(raw["Spells"]) { - if b, ok := maxDamageSpellBonus[id]; ok { - value += b + for _, id := range toIntList(raw["ActiveSpells"]) { + if e, ok := maxDamageSpellEffects[id]; ok { + value -= int(e.change) } } - for _, id := range toIntList(raw["ActiveSpells"]) { - if b, ok := maxDamageSpellBonus[id]; ok { - value -= b + for _, id := range toIntList(raw["Spells"]) { + if e, ok := maxDamageSpellEffects[id]; ok { + value += int(e.bonus) } } return value } // buffedElemVsMon mirrors GetBuffedDoubleValueKey(152) using the same -// innate-add / active-subtract semantics. +// subtract-change-for-active / add-bonus-for-innate semantics. func buffedElemVsMon(raw, dv map[string]any) float64 { value := dvF(dv, "152", 0) - for _, id := range toIntList(raw["Spells"]) { - if b, ok := elemVsMonSpellBonus[id]; ok { - value += b + for _, id := range toIntList(raw["ActiveSpells"]) { + if e, ok := elemVsMonSpellEffects[id]; ok { + value -= e.change } } - for _, id := range toIntList(raw["ActiveSpells"]) { - if b, ok := elemVsMonSpellBonus[id]; ok { - value -= b + for _, id := range toIntList(raw["Spells"]) { + if e, ok := elemVsMonSpellEffects[id]; ok { + value += e.bonus } } return value @@ -506,11 +515,10 @@ func computeOD(raw map[string]any) (float64, bool) { if variance <= 0 { return 0, false } - // NOTE: literal ratio is variance/bv.maxVar, not bv.maxVar/variance as - // the plan's prose (and the UB source's `perfectVariance/Variance` - // argument order) states — see od.go deviation note below and the - // implementation report for why. - varianceTinks := round2(math.Log(variance/bv.maxVar) / math.Log(0.8)) + // UB ItemInfo.cs:1096: Math.Log(perfectVariance / Variance, 0.8). + // Table MaxVar is the tier's baseline variance; lower variance than + // baseline yields negative varianceTinks, i.e. a positive OD credit. + varianceTinks := round2(math.Log(bv.maxVar/variance) / math.Log(0.8)) od := float64(buffedMaxDamage(raw, iv)) - varianceTinks - bv.maxDmg return round2(od), true diff --git a/go-services/inventory-go/od_test.go b/go-services/inventory-go/od_test.go index 48b43bcb..2acaf8a8 100644 --- a/go-services/inventory-go/od_test.go +++ b/go-services/inventory-go/od_test.go @@ -66,8 +66,12 @@ func TestOD_MeleeRetailMaxIsZero(t *testing.T) { } } -// Melee with tighter variance (0.376 = one granite tink below 0.47): -// varianceTinks = round(log(0.47/0.376)/log(0.8), 2) = round(1.00,2)=1 → OD = 71-1-71 = -1. +// Melee with tighter variance (0.376 = one granite tink below the 0.47 baseline): +// the table MaxVar is the BASELINE variance for the tier, and lower variance than +// baseline is better — it contributes positively to OD. Per UB ItemInfo.cs:1096 +// (Math.Log(perfectVariance / Variance, 0.8)): +// varianceTinks = round(log(0.47/0.376)/log(0.8), 2) = round(-1.00,2) = -1 +// → OD = 71 - (-1) - 71 = +1. func TestOD_MeleeOneTinkVariance(t *testing.T) { raw := map[string]any{ "ObjectClass": 1.0, @@ -76,8 +80,8 @@ func TestOD_MeleeOneTinkVariance(t *testing.T) { "Spells": []any{}, "ActiveSpells": []any{}, } od, ok := computeOD(raw) - if !ok || !approx(od, -1.0) { - t.Fatalf("melee OD = %v ok=%v, want -1", od, ok) + if !ok || !approx(od, 1.0) { + t.Fatalf("melee OD = %v ok=%v, want +1", od, ok) } } @@ -95,3 +99,50 @@ func TestOD_MeleeBuffedByBloodThirst(t *testing.T) { t.Fatalf("melee buffed OD = %v ok=%v, want 0", od, ok) } } + +// Exact SpellInfo(change, bonus) semantics (UB Dictionaries.cs:356): innate +// Spells add `bonus`, ActiveSpells subtract `change`. Incantation of Blood +// Drinker (5183) has change=24 but bonus=0 (the 2012 aura conversion), so: +// - innate 5183 grants NOTHING → maxDmg 71 + 0 = 71 → OD 0; +// - active 5183 on an enchanted maxDmg 95 (71+24) subtracts 24 → 71 → OD 0. +func TestOD_MeleeInnateIncantBDGrantsNothing(t *testing.T) { + innate := map[string]any{ + "ObjectClass": 1.0, + "IntValues": map[string]any{"159": 44.0, "353": 2.0, "160": 430.0, "218103842": 71.0}, + "DoubleValues": map[string]any{"167772171": 0.47, "167772169": 10.0}, + "Spells": []any{5183.0}, "ActiveSpells": []any{}, + } + od, ok := computeOD(innate) + if !ok || !approx(od, 0.0) { + t.Fatalf("innate Incant BD OD = %v ok=%v, want 0 (bonus is 0)", od, ok) + } + + active := map[string]any{ + "ObjectClass": 1.0, + "IntValues": map[string]any{"159": 44.0, "353": 2.0, "160": 430.0, "218103842": 95.0}, + "DoubleValues": map[string]any{"167772171": 0.47, "167772169": 10.0}, + "Spells": []any{}, "ActiveSpells": []any{5183.0}, + } + od, ok = computeOD(active) + if !ok || !approx(od, 0.0) { + t.Fatalf("active Incant BD OD = %v ok=%v, want 0 (change 24 subtracted)", od, ok) + } +} + +// Missile golden test, modeled on the live Fire Compound Bow: +// bow (mastery 8), wieldreq 385, maxDmg 32, elem bonus 21, DamageBonus 2.73, +// no "171" key → tinks 0 → remaining 9 (the imbue tink is reserved). +// dmgMod = 2.73·100−100 = 173; arrowMax = 40; maxMod = (140+136)/100 = 2.76; +// OD = (1+(173+4·9)/100)·(21+32+40)/2.76 − (22+24+40) = 3.09·93/2.76 − 86 ≈ 18.12. +func TestOD_MissileBow(t *testing.T) { + raw := map[string]any{ + "ObjectClass": 9.0, + "IntValues": map[string]any{"159": 47.0, "353": 8.0, "160": 385.0, "218103842": 32.0, "204": 21.0}, + "DoubleValues": map[string]any{"167772174": 2.73, "167772169": 6.0}, + "Spells": []any{}, "ActiveSpells": []any{}, + } + od, ok := computeOD(raw) + if !ok || !approx(od, 18.12) { + t.Fatalf("missile bow OD = %v ok=%v, want 18.12", od, ok) + } +} From 99f394d1ef26f366aeaa84e7936db8e5984dc66c Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 15 Jul 2026 07:58:36 +0200 Subject: [PATCH 06/12] =?UTF-8?q?docs(spec):=20OD=20=E2=80=94=20add=20miss?= =?UTF-8?q?ing=20Prodigal=20Spirit=20Drinker=20effect,=20document=20dmgMod?= =?UTF-8?q?=20key=20substitution?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- .../specs/2026-07-15-weapon-od-rating-design.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/superpowers/specs/2026-07-15-weapon-od-rating-design.md b/docs/superpowers/specs/2026-07-15-weapon-od-rating-design.md index 9d26a8fa..9d526727 100644 --- a/docs/superpowers/specs/2026-07-15-weapon-od-rating-design.md +++ b/docs/superpowers/specs/2026-07-15-weapon-od-rating-design.md @@ -42,7 +42,13 @@ subtracted; the Blood/Spirit Thirst cantrips have bonus == change: {7,7}, 6089 Legendary BT {10,10}, 3688 Prodigal BD {300,0}. - ElemVsMonsters — 3258 SD VI {.06,0}, 3259 Infected Spirit Caress {.07,0}, 5182/4414 Incant. SD {.08,0}, 3251 Minor ST {.01,.01}, 3250 Major ST - {.03,.03}, 4670 Epic ST {.05,.05}, 6098 Legendary ST {.07,.07}. + {.03,.03}, 4670 Epic ST {.05,.05}, 6098 Legendary ST {.07,.07}, + 3735 Prodigal Spirit Drinker {.15,0}. + +**Missile dmgMod key**: UB's literal CalcMissileDamage reads `DoubleValues[63]`, +but no DoubleValueKey ordinal 63 exists in Decal — the populated key is +`167772174` (DamageBonus), consistent with UB's own CalcedBuffedMissileDamage. +We use 167772174 deliberately. **Melee variance orientation**: the table's MaxVar is the type's *baseline* variance; a weapon with LOWER variance than baseline yields a NEGATIVE From 9b2f28d9420752cf9acacc2006ff4e1118570fc4 Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 15 Jul 2026 08:00:22 +0200 Subject: [PATCH 07/12] fix(inventory-go): add Prodigal Spirit Drinker effect; document dmgMod key substitution; test wand mastery fallback Co-Authored-By: Claude Sonnet 5 --- go-services/inventory-go/od.go | 17 ++++++++++----- go-services/inventory-go/od_test.go | 32 +++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/go-services/inventory-go/od.go b/go-services/inventory-go/od.go index f39ebcc4..00aa18d2 100644 --- a/go-services/inventory-go/od.go +++ b/go-services/inventory-go/od.go @@ -416,6 +416,7 @@ var elemVsMonSpellEffects = map[int]odSpellEffect{ 3250: {.03, .03}, // Major Spirit Thirst 4670: {.05, .05}, // Epic Spirit Thirst 6098: {.07, .07}, // Legendary Spirit Thirst + 3735: {.15, 0}, // Prodigal Spirit Drinker } // buffedMaxDamage mirrors GetBuffedIntValueKey(218103842): base value minus @@ -497,11 +498,12 @@ func computeOD(raw map[string]any) (float64, bool) { } bv, ok := bestValues[key] if !ok && oc == 31 { - // Wands: our probe showed some wands lack key 353 (mastery), which - // defaults to 0 via ivI — but retry explicitly with mastery 0 so the - // void VR wand row (43,12,...) stays reachable while items that - // genuinely carry a different mastery value still fall back to the - // normal (34|43, 0, ...) rows. + // Mastery-0 retry for wands: an ADDITION over UB (UB's + // DataTable.Select has no retry; our captured wands may carry a + // mastery key 353 while the table's wand rows use mastery 0). + // Keeps the void VR wand row (43,12,...) reachable on the first + // exact-match attempt while other mastery-carrying wands fall back + // to the normal (34|43, 0, ...) rows. key.mastery = 0 bv, ok = bestValues[key] } @@ -550,6 +552,11 @@ func computeOD(raw map[string]any) (float64, bool) { remaining = 0 } + // NOTE: UB's literal CalcMissileDamage reads DoubleValues[63], but no + // DoubleValueKey ordinal 63 exists (verified against Decal.Adapter) — + // that line is a stale/bugged reference in the UB source. The correct + // populated key is 167772174 (DamageBonus), consistent with UB's own + // CalcedBuffedMissileDamage. Do NOT "fix" this back to 63. dmgMod := dvF(dv, "167772174", 0)*100 - 100 bDmg := float64(buffedMaxDamage(raw, iv)) if bDmg <= 10 { diff --git a/go-services/inventory-go/od_test.go b/go-services/inventory-go/od_test.go index 2acaf8a8..e725294d 100644 --- a/go-services/inventory-go/od_test.go +++ b/go-services/inventory-go/od_test.go @@ -23,6 +23,38 @@ func TestOD_Wand(t *testing.T) { } } +// Wand with an ACTIVE Prodigal Spirit Drinker (3735, change .15, bonus 0): +// shown ElemVsMonsters 1.55 un-buffs to 1.55 − .15 = 1.40 → OD +22, same +// underlying weapon as TestOD_Wand. +func TestOD_WandActiveProdigalSpiritDrinker(t *testing.T) { + raw := map[string]any{ + "ObjectClass": 31.0, + "IntValues": map[string]any{"159": 34.0, "160": 385.0}, + "DoubleValues": map[string]any{"152": 1.55, "167772169": 8.0}, + "Spells": []any{}, "ActiveSpells": []any{3735.0}, + } + od, ok := computeOD(raw) + if !ok || !approx(od, 22.0) { + t.Fatalf("wand w/ active Prodigal SD OD = %v ok=%v, want +22", od, ok) + } +} + +// Wand carrying a mastery value (353) with no matching wand table row: the +// exact-match lookup on (34,5,0,385) misses, and the mastery-0 retry must hit +// the (34,0,0,385) row → OD +22 as in TestOD_Wand. +func TestOD_WandMasteryFallback(t *testing.T) { + raw := map[string]any{ + "ObjectClass": 31.0, + "IntValues": map[string]any{"159": 34.0, "353": 5.0, "160": 385.0}, + "DoubleValues": map[string]any{"152": 1.40, "167772169": 8.0}, + "Spells": []any{}, "ActiveSpells": []any{}, + } + od, ok := computeOD(raw) + if !ok || !approx(od, 22.0) { + t.Fatalf("wand mastery-fallback OD = %v ok=%v, want +22", od, ok) + } +} + // Non-loot (no workmanship) → no OD. func TestOD_NonLootNull(t *testing.T) { raw := map[string]any{ From e07a9459cd6de567352f59e2eb5ab3797e8ba04e Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 15 Jul 2026 08:03:57 +0200 Subject: [PATCH 08/12] feat(inventory-go): store od_rating at ingest + schema column Co-Authored-By: Claude Sonnet 5 --- go-services/inventory-go/process.go | 4 ++++ go-services/inventory-go/schema.go | 1 + 2 files changed, 5 insertions(+) diff --git a/go-services/inventory-go/process.go b/go-services/inventory-go/process.go index 4a377309..a0f0ddbf 100644 --- a/go-services/inventory-go/process.go +++ b/go-services/inventory-go/process.go @@ -136,6 +136,10 @@ func (s *Server) processItem(raw map[string]any) map[string]any { "remaining_lifespan": nilNeg(ivI(iv, "268", -1)), } + if od, ok := computeOD(raw); ok { + items["od_rating"] = od + } + // combat (sentinel defaults), then base values merged. wt := ivI(iv, "218103835", -1) if wt > 100 { diff --git a/go-services/inventory-go/schema.go b/go-services/inventory-go/schema.go index 43950bbb..bf8b0511 100644 --- a/go-services/inventory-go/schema.go +++ b/go-services/inventory-go/schema.go @@ -38,6 +38,7 @@ func initSchema(ctx context.Context, pool *pgxpool.Pool, log *slog.Logger) { rare_id INTEGER, lifespan INTEGER, remaining_lifespan INTEGER, + od_rating DOUBLE PRECISION, has_id_data BOOLEAN DEFAULT false, last_id_time BIGINT DEFAULT 0, CONSTRAINT uq_char_item UNIQUE (character_name, item_id) From 3c0a8d9de8823358bbd95e98f6481a47b1a0b971 Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 15 Jul 2026 08:04:00 +0200 Subject: [PATCH 09/12] feat(inventory-go): POST /admin/backfill-od recompute endpoint Co-Authored-By: Claude Sonnet 5 --- go-services/inventory-go/ingest.go | 43 ++++++++++++++++++++++++++++++ go-services/inventory-go/main.go | 1 + 2 files changed, 44 insertions(+) diff --git a/go-services/inventory-go/ingest.go b/go-services/inventory-go/ingest.go index 04ab99e3..213c60cc 100644 --- a/go-services/inventory-go/ingest.go +++ b/go-services/inventory-go/ingest.go @@ -245,6 +245,49 @@ func (s *Server) handleDeleteItem(w http.ResponseWriter, r *http.Request) { writeJSON(w, http.StatusOK, map[string]any{"status": "deleted", "item_id": itemID}) } +// POST /admin/backfill-od — recompute od_rating for all weapon rows from stored +// raw JSON. Internal-only (service is bound to loopback/compose). Idempotent. +func (s *Server) handleBackfillOD(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + rows, err := s.pool.Query(ctx, + `SELECT rd.item_id, rd.original_json FROM item_raw_data rd + JOIN items i ON i.id = rd.item_id + WHERE i.object_class IN (1,9,31)`) + if err != nil { + writeJSON(w, http.StatusInternalServerError, map[string]any{"error": err.Error()}) + return + } + type upd struct { + id int + od float64 + } + var updates []upd + scanned := 0 + for rows.Next() { + var id int + var oj map[string]any + if err := rows.Scan(&id, &oj); err != nil { + rows.Close() + writeJSON(w, http.StatusInternalServerError, map[string]any{"error": err.Error()}) + return + } + scanned++ + if od, ok := computeOD(oj); ok { + updates = append(updates, upd{id, od}) + } + } + rows.Close() + updated := 0 + for _, u := range updates { + if _, err := s.pool.Exec(ctx, "UPDATE items SET od_rating=$1 WHERE id=$2", u.od, u.id); err != nil { + writeJSON(w, http.StatusInternalServerError, map[string]any{"error": err.Error(), "updated": updated}) + return + } + updated++ + } + writeJSON(w, http.StatusOK, map[string]any{"scanned": scanned, "updated": updated}) +} + func parseNaiveTime(s string) time.Time { if s == "" { return time.Now().UTC() diff --git a/go-services/inventory-go/main.go b/go-services/inventory-go/main.go index 51611dcc..47140c0a 100644 --- a/go-services/inventory-go/main.go +++ b/go-services/inventory-go/main.go @@ -100,6 +100,7 @@ func main() { mux.HandleFunc("POST /process-inventory", srv.handleProcessInventory) mux.HandleFunc("POST /inventory/{character_name}/item", srv.handleUpsertItem) mux.HandleFunc("DELETE /inventory/{character_name}/item/{item_id}", srv.handleDeleteItem) + mux.HandleFunc("POST /admin/backfill-od", srv.handleBackfillOD) // Suitbuilder (port of suitbuilder.py router, mounted at /suitbuilder). mux.HandleFunc("POST /suitbuilder/search", srv.handleSuitSearch) mux.HandleFunc("GET /suitbuilder/characters", srv.handleSuitCharacters) From fb6b54f9bde08ba33f0283da5e5bfa8446188da3 Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 15 Jul 2026 08:05:03 +0200 Subject: [PATCH 10/12] feat(inventory-go): min_od/max_od search filters + od sort Co-Authored-By: Claude Sonnet 5 --- go-services/inventory-go/search.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/go-services/inventory-go/search.go b/go-services/inventory-go/search.go index 1090e8d7..ffa55a3d 100644 --- a/go-services/inventory-go/search.go +++ b/go-services/inventory-go/search.go @@ -23,6 +23,7 @@ import ( const cteSelect = ` SELECT DISTINCT i.id AS db_item_id, i.character_name, i.name, i.icon, i.object_class, i.value, i.burden, + i.od_rating, i.current_wielded_location, i.bonded, i.attuned, i."unique", i.stack_size, i.max_stack_size, i.structure, i.max_structure, i.rare_id, i.timestamp AS last_updated, COALESCE(cs.max_damage, -1) AS max_damage, @@ -133,6 +134,7 @@ var sortMapping = map[string]string{ "crit_damage_resist_rating": "crit_damage_resist_rating", "item_set": "item_set", "coverage": "coverage_mask", "item_type_name": "object_class", "last_updated": "last_updated", "spell_names": "computed_spell_names", + "od": "od_rating", } // argBuilder accumulates positional ($N) query args. @@ -219,6 +221,7 @@ func (s *Server) runSearch(ctx context.Context, q url.Values) (map[string]any, e {"min_pk_damage_resist_rating", "pk_damage_resist_rating"}, {"min_gear_pk_damage_rating", "gear_pk_damage_rating"}, {"min_gear_pk_damage_resist_rating", "gear_pk_damage_resist_rating"}, {"min_tinks", "tinks"}, {"min_value", "value"}, {"min_workmanship", "workmanship"}, + {"min_od", "od_rating"}, } for _, f := range geFilters { if v := q.Get(f.param); v != "" { @@ -241,6 +244,11 @@ func (s *Server) runSearch(ctx context.Context, q url.Values) (map[string]any, e conds = append(conds, "attack_bonus >= "+ab.add(n)) } } + if v := q.Get("max_od"); v != "" { + if n, err := strconv.ParseFloat(v, 64); err == nil { + conds = append(conds, "od_rating <= "+ab.add(n)) + } + } // --- requirements (wield level) --- if v, ok := qInt(q, "max_level"); ok { From 1dd95819c772ee8a3121a652ea274d6535493813 Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 15 Jul 2026 08:22:54 +0200 Subject: [PATCH 11/12] feat(frontend): weapon OD rating filter, column, and detail row Co-Authored-By: Claude Fable 5 --- frontend/src/components/inventory/DetailPanel.tsx | 1 + frontend/src/components/inventory/ResultsTable.tsx | 5 +++++ frontend/src/components/inventory/constants.ts | 2 ++ frontend/src/components/inventory/types.ts | 1 + 4 files changed, 9 insertions(+) diff --git a/frontend/src/components/inventory/DetailPanel.tsx b/frontend/src/components/inventory/DetailPanel.tsx index b628e6a8..4fb535e4 100644 --- a/frontend/src/components/inventory/DetailPanel.tsx +++ b/frontend/src/components/inventory/DetailPanel.tsx @@ -21,6 +21,7 @@ export function DetailPanel({ item, onClose }: { item: InvItem; onClose: () => v {item.armor_level != null && item.armor_level > 0 && } {item.max_damage != null && item.max_damage > 0 && } + {item.od_rating != null && 0 ? `+${item.od_rating.toFixed(2)}` : item.od_rating.toFixed(2)} />} {item.condition_percent != null && } {item.item_set_name && } {(item.is_bonded || item.is_attuned) && } diff --git a/frontend/src/components/inventory/ResultsTable.tsx b/frontend/src/components/inventory/ResultsTable.tsx index 553875f6..3afdc724 100644 --- a/frontend/src/components/inventory/ResultsTable.tsx +++ b/frontend/src/components/inventory/ResultsTable.tsx @@ -23,6 +23,11 @@ function cell(item: InvItem, key: string): React.ReactNode { return item.value != null ? item.value.toLocaleString() : '—'; case 'last_updated': return item.last_updated ? item.last_updated.slice(0, 16).replace('T', ' ') : '—'; + case 'od_rating': { + const v = item.od_rating; + if (v == null) return '—'; + return v > 0 ? `+${v.toFixed(2)}` : v.toFixed(2); + } default: { const v = (item as any)[key]; return v == null || v === -1 ? '—' : String(v); diff --git a/frontend/src/components/inventory/constants.ts b/frontend/src/components/inventory/constants.ts index fb1e8610..92251f75 100644 --- a/frontend/src/components/inventory/constants.ts +++ b/frontend/src/components/inventory/constants.ts @@ -53,6 +53,7 @@ export const WEAPON_TYPES: Array<{ value: string; label: string }> = [ export interface RatingDef { param: string; label: string; common?: boolean; } export const RATING_DEFS: RatingDef[] = [ + { param: 'min_od', label: 'Weapon OD', common: true }, { param: 'min_damage_rating', label: 'Damage rating', common: true }, { param: 'min_crit_damage_rating', label: 'Crit damage', common: true }, { param: 'min_heal_boost_rating', label: 'Heal boost', common: true }, @@ -89,6 +90,7 @@ export const COLUMNS: ColumnDef[] = [ { key: 'spell_names', label: 'Spells / Cantrips', sortKey: 'spell_names', defaultVisible: true }, { key: 'armor_level', label: 'Armor', sortKey: 'armor', defaultVisible: false }, { key: 'max_damage', label: 'Max Dmg', sortKey: 'damage', defaultVisible: false }, + { key: 'od_rating', label: 'OD', sortKey: 'od', defaultVisible: false }, { key: 'workmanship', label: 'Work', sortKey: 'workmanship', defaultVisible: false }, { key: 'item_set_name', label: 'Set', sortKey: 'item_set', defaultVisible: false }, { key: 'object_class_name', label: 'Type', sortKey: 'item_type_name', defaultVisible: false }, diff --git a/frontend/src/components/inventory/types.ts b/frontend/src/components/inventory/types.ts index 2f1537c1..491bcefe 100644 --- a/frontend/src/components/inventory/types.ts +++ b/frontend/src/components/inventory/types.ts @@ -15,6 +15,7 @@ export interface InvItem { item_set_name?: string; armor_level: number | null; max_damage: number | null; + od_rating?: number | null; condition_percent: number | null; object_class_name?: string; material_name?: string; From d5febaabda6a722103752331a9e48fe2e3cac11e Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 15 Jul 2026 08:23:07 +0200 Subject: [PATCH 12/12] build(frontend): deploy weapon OD rating Co-Authored-By: Claude Fable 5 --- ...Window-CiWHpLWd.js => AdminUsersWindow-CnmS9CpE.js} | 2 +- ...AgentWindow-CMflyyRx.js => AgentWindow-MAlGlaCG.js} | 2 +- ...rWindow-Bm7Dvqbf.js => CharacterWindow-5cx18R5O.js} | 2 +- ...ndow-CJZfow68.js => CombatPickerWindow-CeceAs6p.js} | 2 +- ...indow-DrwSvkSn.js => CombatStatsWindow-DiW4OOU6.js} | 2 +- ...yWindow-C3GJw7NT.js => InventoryWindow-OJaggw-L.js} | 2 +- ...suesWindow-BdHPJVkp.js => IssuesWindow-BZgt7gnX.js} | 2 +- ...indow-C1NaAFXp.js => QuestStatusWindow-CNO3OiLF.js} | 2 +- ...RadarWindow-Co69p423.js => RadarWindow-CYZptNtW.js} | 2 +- ...StatsWindow-Dx7y3LW3.js => StatsWindow-BBzLtF0I.js} | 2 +- ...ndow-DWghwvjH.js => VitalSharingWindow-2svvX-Jr.js} | 2 +- static/assets/{index-D5aV9Wxd.js => index-CPIBhBUe.js} | 10 +++++----- static/index.html | 2 +- 13 files changed, 17 insertions(+), 17 deletions(-) rename static/assets/{AdminUsersWindow-CiWHpLWd.js => AdminUsersWindow-CnmS9CpE.js} (98%) rename static/assets/{AgentWindow-CMflyyRx.js => AgentWindow-MAlGlaCG.js} (96%) rename static/assets/{CharacterWindow-Bm7Dvqbf.js => CharacterWindow-5cx18R5O.js} (99%) rename static/assets/{CombatPickerWindow-CJZfow68.js => CombatPickerWindow-CeceAs6p.js} (92%) rename static/assets/{CombatStatsWindow-DrwSvkSn.js => CombatStatsWindow-DiW4OOU6.js} (99%) rename static/assets/{InventoryWindow-C3GJw7NT.js => InventoryWindow-OJaggw-L.js} (99%) rename static/assets/{IssuesWindow-BdHPJVkp.js => IssuesWindow-BZgt7gnX.js} (99%) rename static/assets/{QuestStatusWindow-C1NaAFXp.js => QuestStatusWindow-CNO3OiLF.js} (96%) rename static/assets/{RadarWindow-Co69p423.js => RadarWindow-CYZptNtW.js} (99%) rename static/assets/{StatsWindow-Dx7y3LW3.js => StatsWindow-BBzLtF0I.js} (93%) rename static/assets/{VitalSharingWindow-DWghwvjH.js => VitalSharingWindow-2svvX-Jr.js} (97%) rename static/assets/{index-D5aV9Wxd.js => index-CPIBhBUe.js} (89%) diff --git a/static/assets/AdminUsersWindow-CiWHpLWd.js b/static/assets/AdminUsersWindow-CnmS9CpE.js similarity index 98% rename from static/assets/AdminUsersWindow-CiWHpLWd.js rename to static/assets/AdminUsersWindow-CnmS9CpE.js index 6ed5c431..53b12eff 100644 --- a/static/assets/AdminUsersWindow-CiWHpLWd.js +++ b/static/assets/AdminUsersWindow-CnmS9CpE.js @@ -1 +1 @@ -import{e as I,r as t,l as _,f as L,g as N,h as W,j as e,D as F}from"./index-D5aV9Wxd.js";import"./react-yfL0ty4i.js";function R(c){try{return new Date(c).toISOString().slice(0,10)}catch{return c}}const q=({id:c,zIndex:x})=>{const{user:j}=I(),[g,k]=t.useState([]),[w,p]=t.useState(!0),[b,n]=t.useState(null),[l,C]=t.useState(""),[i,f]=t.useState(""),[h,y]=t.useState(!1),[d,S]=t.useState(!1),[A,u]=t.useState(null),[o,m]=t.useState(""),r=t.useCallback(async()=>{p(!0),n(null);try{const s=await _();k(s.users??[])}catch(s){n(String(s))}finally{p(!1)}},[]);t.useEffect(()=>{r()},[r]);const U=t.useCallback(async s=>{if(s.preventDefault(),!l.trim()||i.length<4){n("Username required and password must be at least 4 chars");return}S(!0),n(null);try{await L(l.trim(),i,h),C(""),f(""),y(!1),await r()}catch(a){n(String(a))}finally{S(!1)}},[l,i,h,r]),v=t.useCallback(async s=>{n(null);try{await N(s.id,{is_admin:!s.is_admin}),await r()}catch(a){n(String(a))}},[r]),D=t.useCallback(async s=>{if(o.length<4){n("Password must be at least 4 characters");return}n(null);try{await N(s,{password:o}),u(null),m("")}catch(a){n(String(a))}},[o]),P=t.useCallback(async s=>{if(confirm(`Delete user "${s.username}"? This cannot be undone.`)){n(null);try{await W(s.id),await r()}catch(a){n(String(a))}}},[r]);return e.jsx(F,{id:c,title:"🛡️ Admin · Users",zIndex:x,width:620,height:540,children:e.jsxs("div",{className:"ml-admin",children:[b&&e.jsx("div",{className:"ml-admin-error",children:b}),e.jsxs("section",{className:"ml-admin-section",children:[e.jsx("h3",{children:"Add user"}),e.jsxs("form",{onSubmit:U,className:"ml-admin-create",children:[e.jsx("input",{type:"text",placeholder:"Username",value:l,onChange:s=>C(s.target.value),disabled:d,autoComplete:"off"}),e.jsx("input",{type:"password",placeholder:"Password (min 4)",value:i,onChange:s=>f(s.target.value),disabled:d,autoComplete:"new-password"}),e.jsxs("label",{children:[e.jsx("input",{type:"checkbox",checked:h,onChange:s=>y(s.target.checked),disabled:d}),"admin"]}),e.jsx("button",{type:"submit",disabled:d||!l.trim()||i.length<4,children:d?"Adding…":"Add"})]})]}),e.jsxs("section",{className:"ml-admin-section",children:[e.jsxs("h3",{children:["Users ",w&&e.jsx("span",{className:"ml-admin-muted",children:"(loading…)"})]}),e.jsxs("table",{className:"ml-admin-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"ID"}),e.jsx("th",{children:"Username"}),e.jsx("th",{children:"Admin"}),e.jsx("th",{children:"Created"}),e.jsx("th",{children:"Actions"})]})}),e.jsxs("tbody",{children:[g.map(s=>{const a=j!=null&&j.username.toLowerCase()===s.username.toLowerCase();return e.jsxs("tr",{children:[e.jsx("td",{children:s.id}),e.jsxs("td",{children:[s.username,a&&e.jsx("span",{className:"ml-admin-muted",children:" (you)"})]}),e.jsx("td",{children:e.jsx("button",{className:"ml-admin-toggle",onClick:()=>v(s),title:"Click to toggle admin",children:s.is_admin?"✓":"–"})}),e.jsx("td",{children:R(s.created_at)}),e.jsx("td",{children:A===s.id?e.jsxs("span",{className:"ml-admin-pw-edit",children:[e.jsx("input",{type:"text",placeholder:"New password",value:o,onChange:E=>m(E.target.value),autoFocus:!0}),e.jsx("button",{onClick:()=>D(s.id),children:"Save"}),e.jsx("button",{onClick:()=>{u(null),m("")},children:"Cancel"})]}):e.jsxs(e.Fragment,{children:[e.jsx("button",{onClick:()=>{u(s.id),m("")},children:"Reset PW"}),!a&&e.jsx("button",{className:"ml-admin-danger",onClick:()=>P(s),children:"Delete"})]})})]},s.id)}),g.length===0&&!w&&e.jsx("tr",{children:e.jsx("td",{colSpan:5,className:"ml-admin-muted",children:"No users."})})]})]})]})]})})};export{q as AdminUsersWindow}; +import{e as I,r as t,l as _,f as L,g as N,h as W,j as e,D as F}from"./index-CPIBhBUe.js";import"./react-yfL0ty4i.js";function R(c){try{return new Date(c).toISOString().slice(0,10)}catch{return c}}const q=({id:c,zIndex:x})=>{const{user:j}=I(),[g,k]=t.useState([]),[w,p]=t.useState(!0),[b,n]=t.useState(null),[l,C]=t.useState(""),[i,f]=t.useState(""),[h,y]=t.useState(!1),[d,S]=t.useState(!1),[A,u]=t.useState(null),[o,m]=t.useState(""),r=t.useCallback(async()=>{p(!0),n(null);try{const s=await _();k(s.users??[])}catch(s){n(String(s))}finally{p(!1)}},[]);t.useEffect(()=>{r()},[r]);const U=t.useCallback(async s=>{if(s.preventDefault(),!l.trim()||i.length<4){n("Username required and password must be at least 4 chars");return}S(!0),n(null);try{await L(l.trim(),i,h),C(""),f(""),y(!1),await r()}catch(a){n(String(a))}finally{S(!1)}},[l,i,h,r]),v=t.useCallback(async s=>{n(null);try{await N(s.id,{is_admin:!s.is_admin}),await r()}catch(a){n(String(a))}},[r]),D=t.useCallback(async s=>{if(o.length<4){n("Password must be at least 4 characters");return}n(null);try{await N(s,{password:o}),u(null),m("")}catch(a){n(String(a))}},[o]),P=t.useCallback(async s=>{if(confirm(`Delete user "${s.username}"? This cannot be undone.`)){n(null);try{await W(s.id),await r()}catch(a){n(String(a))}}},[r]);return e.jsx(F,{id:c,title:"🛡️ Admin · Users",zIndex:x,width:620,height:540,children:e.jsxs("div",{className:"ml-admin",children:[b&&e.jsx("div",{className:"ml-admin-error",children:b}),e.jsxs("section",{className:"ml-admin-section",children:[e.jsx("h3",{children:"Add user"}),e.jsxs("form",{onSubmit:U,className:"ml-admin-create",children:[e.jsx("input",{type:"text",placeholder:"Username",value:l,onChange:s=>C(s.target.value),disabled:d,autoComplete:"off"}),e.jsx("input",{type:"password",placeholder:"Password (min 4)",value:i,onChange:s=>f(s.target.value),disabled:d,autoComplete:"new-password"}),e.jsxs("label",{children:[e.jsx("input",{type:"checkbox",checked:h,onChange:s=>y(s.target.checked),disabled:d}),"admin"]}),e.jsx("button",{type:"submit",disabled:d||!l.trim()||i.length<4,children:d?"Adding…":"Add"})]})]}),e.jsxs("section",{className:"ml-admin-section",children:[e.jsxs("h3",{children:["Users ",w&&e.jsx("span",{className:"ml-admin-muted",children:"(loading…)"})]}),e.jsxs("table",{className:"ml-admin-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"ID"}),e.jsx("th",{children:"Username"}),e.jsx("th",{children:"Admin"}),e.jsx("th",{children:"Created"}),e.jsx("th",{children:"Actions"})]})}),e.jsxs("tbody",{children:[g.map(s=>{const a=j!=null&&j.username.toLowerCase()===s.username.toLowerCase();return e.jsxs("tr",{children:[e.jsx("td",{children:s.id}),e.jsxs("td",{children:[s.username,a&&e.jsx("span",{className:"ml-admin-muted",children:" (you)"})]}),e.jsx("td",{children:e.jsx("button",{className:"ml-admin-toggle",onClick:()=>v(s),title:"Click to toggle admin",children:s.is_admin?"✓":"–"})}),e.jsx("td",{children:R(s.created_at)}),e.jsx("td",{children:A===s.id?e.jsxs("span",{className:"ml-admin-pw-edit",children:[e.jsx("input",{type:"text",placeholder:"New password",value:o,onChange:E=>m(E.target.value),autoFocus:!0}),e.jsx("button",{onClick:()=>D(s.id),children:"Save"}),e.jsx("button",{onClick:()=>{u(null),m("")},children:"Cancel"})]}):e.jsxs(e.Fragment,{children:[e.jsx("button",{onClick:()=>{u(s.id),m("")},children:"Reset PW"}),!a&&e.jsx("button",{className:"ml-admin-danger",onClick:()=>P(s),children:"Delete"})]})})]},s.id)}),g.length===0&&!w&&e.jsx("tr",{children:e.jsx("td",{colSpan:5,className:"ml-admin-muted",children:"No users."})})]})]})]})]})})};export{q as AdminUsersWindow}; diff --git a/static/assets/AgentWindow-CMflyyRx.js b/static/assets/AgentWindow-MAlGlaCG.js similarity index 96% rename from static/assets/AgentWindow-CMflyyRx.js rename to static/assets/AgentWindow-MAlGlaCG.js index ac647696..b52563a0 100644 --- a/static/assets/AgentWindow-CMflyyRx.js +++ b/static/assets/AgentWindow-MAlGlaCG.js @@ -1 +1 @@ -import{r as n,b as w,c as k,d as E,j as t,D as I}from"./index-D5aV9Wxd.js";import"./react-yfL0ty4i.js";const h="overlord_agent_session_id";function v(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();const s=l=>Math.floor(Math.random()*l);return`${s(4294967296).toString(16).padStart(8,"0")}-${s(65536).toString(16).padStart(4,"0")}-4${s(4096).toString(16).padStart(3,"0")}-${(8+s(4)).toString(16)}${s(4096).toString(16).padStart(3,"0")}-${s(281474976710656).toString(16).padStart(12,"0")}`}function $(){try{const l=localStorage.getItem(h);if(l)return l}catch{}const s=v();try{localStorage.setItem(h,s)}catch{}return s}const _=({id:s,zIndex:l})=>{const[o,j]=n.useState(()=>$()),[d,i]=n.useState([]),[g,m]=n.useState(""),[r,f]=n.useState(!1),[p,x]=n.useState(!0),S=n.useRef(null);n.useEffect(()=>{let e=!1;return x(!0),w(o).then(a=>{if(e)return;const c=(a.messages??[]).map(y=>({role:y.role,text:y.text}));i(c)}).catch(()=>{e||i([])}).finally(()=>{e||x(!1)}),()=>{e=!0}},[o]),n.useEffect(()=>{const e=S.current;e&&(e.scrollTop=e.scrollHeight)},[d.length,r]);const u=n.useCallback(async()=>{const e=g.trim();if(!(!e||r)){m(""),i(a=>[...a,{role:"user",text:e}]),f(!0);try{const a=await k(e,o);i(c=>[...c,{role:a.is_error?"error":"assistant",text:a.result||"(no response)"}])}catch(a){i(c=>[...c,{role:"error",text:`Request failed: ${String(a)}`}])}finally{f(!1)}}},[g,r,o]),N=n.useCallback(async()=>{if(r)return;let e="";try{e=(await E()).session_id}catch{e=v()}try{localStorage.setItem(h,e)}catch{}j(e),i([]),m("")},[r]),b=n.useCallback(e=>{e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),u())},[u]);return t.jsx(I,{id:s,title:"🤖 Overlord Assistant",zIndex:l,width:520,height:620,children:t.jsxs("div",{className:"ml-agent",children:[t.jsxs("div",{className:"ml-agent-toolbar",children:[t.jsx("button",{className:"ml-agent-btn",onClick:N,disabled:r,children:"+ New Chat"}),t.jsxs("span",{className:"ml-agent-session",title:o,children:[o.slice(0,8),"…"]})]}),t.jsxs("div",{className:"ml-agent-messages",ref:S,children:[p&&d.length===0&&t.jsx("div",{className:"ml-agent-empty",children:"Loading conversation…"}),!p&&d.length===0&&t.jsx("div",{className:"ml-agent-empty",children:"Ask anything about the live game state — players, kills, inventory, suitbuilder, recent rares, etc."}),d.map((e,a)=>t.jsxs("div",{className:`ml-agent-msg ml-agent-${e.role}`,children:[t.jsx("div",{className:"ml-agent-role",children:e.role==="user"?"You":e.role==="assistant"?"Overlord":"Error"}),t.jsx("div",{className:"ml-agent-text",children:e.text})]},a)),r&&t.jsxs("div",{className:"ml-agent-msg ml-agent-assistant",children:[t.jsx("div",{className:"ml-agent-role",children:"Overlord"}),t.jsx("div",{className:"ml-agent-text ml-agent-thinking",children:"Thinking…"})]})]}),t.jsxs("form",{className:"ml-agent-form",onSubmit:e=>{e.preventDefault(),u()},children:[t.jsx("textarea",{className:"ml-agent-input",value:g,onChange:e=>m(e.target.value),onKeyDown:b,placeholder:r?"Waiting for response…":"Type a message — Enter to send, Shift+Enter for newline",disabled:r,rows:2}),t.jsx("button",{type:"submit",className:"ml-agent-send",disabled:r||!g.trim(),children:"Send"})]})]})})};export{_ as AgentWindow}; +import{r as n,b as w,c as k,d as E,j as t,D as I}from"./index-CPIBhBUe.js";import"./react-yfL0ty4i.js";const h="overlord_agent_session_id";function v(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();const s=l=>Math.floor(Math.random()*l);return`${s(4294967296).toString(16).padStart(8,"0")}-${s(65536).toString(16).padStart(4,"0")}-4${s(4096).toString(16).padStart(3,"0")}-${(8+s(4)).toString(16)}${s(4096).toString(16).padStart(3,"0")}-${s(281474976710656).toString(16).padStart(12,"0")}`}function $(){try{const l=localStorage.getItem(h);if(l)return l}catch{}const s=v();try{localStorage.setItem(h,s)}catch{}return s}const _=({id:s,zIndex:l})=>{const[o,j]=n.useState(()=>$()),[d,i]=n.useState([]),[g,m]=n.useState(""),[r,f]=n.useState(!1),[p,x]=n.useState(!0),S=n.useRef(null);n.useEffect(()=>{let e=!1;return x(!0),w(o).then(a=>{if(e)return;const c=(a.messages??[]).map(y=>({role:y.role,text:y.text}));i(c)}).catch(()=>{e||i([])}).finally(()=>{e||x(!1)}),()=>{e=!0}},[o]),n.useEffect(()=>{const e=S.current;e&&(e.scrollTop=e.scrollHeight)},[d.length,r]);const u=n.useCallback(async()=>{const e=g.trim();if(!(!e||r)){m(""),i(a=>[...a,{role:"user",text:e}]),f(!0);try{const a=await k(e,o);i(c=>[...c,{role:a.is_error?"error":"assistant",text:a.result||"(no response)"}])}catch(a){i(c=>[...c,{role:"error",text:`Request failed: ${String(a)}`}])}finally{f(!1)}}},[g,r,o]),N=n.useCallback(async()=>{if(r)return;let e="";try{e=(await E()).session_id}catch{e=v()}try{localStorage.setItem(h,e)}catch{}j(e),i([]),m("")},[r]),b=n.useCallback(e=>{e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),u())},[u]);return t.jsx(I,{id:s,title:"🤖 Overlord Assistant",zIndex:l,width:520,height:620,children:t.jsxs("div",{className:"ml-agent",children:[t.jsxs("div",{className:"ml-agent-toolbar",children:[t.jsx("button",{className:"ml-agent-btn",onClick:N,disabled:r,children:"+ New Chat"}),t.jsxs("span",{className:"ml-agent-session",title:o,children:[o.slice(0,8),"…"]})]}),t.jsxs("div",{className:"ml-agent-messages",ref:S,children:[p&&d.length===0&&t.jsx("div",{className:"ml-agent-empty",children:"Loading conversation…"}),!p&&d.length===0&&t.jsx("div",{className:"ml-agent-empty",children:"Ask anything about the live game state — players, kills, inventory, suitbuilder, recent rares, etc."}),d.map((e,a)=>t.jsxs("div",{className:`ml-agent-msg ml-agent-${e.role}`,children:[t.jsx("div",{className:"ml-agent-role",children:e.role==="user"?"You":e.role==="assistant"?"Overlord":"Error"}),t.jsx("div",{className:"ml-agent-text",children:e.text})]},a)),r&&t.jsxs("div",{className:"ml-agent-msg ml-agent-assistant",children:[t.jsx("div",{className:"ml-agent-role",children:"Overlord"}),t.jsx("div",{className:"ml-agent-text ml-agent-thinking",children:"Thinking…"})]})]}),t.jsxs("form",{className:"ml-agent-form",onSubmit:e=>{e.preventDefault(),u()},children:[t.jsx("textarea",{className:"ml-agent-input",value:g,onChange:e=>m(e.target.value),onKeyDown:b,placeholder:r?"Waiting for response…":"Type a message — Enter to send, Shift+Enter for newline",disabled:r,rows:2}),t.jsx("button",{type:"submit",className:"ml-agent-send",disabled:r||!g.trim(),children:"Send"})]})]})})};export{_ as AgentWindow}; diff --git a/static/assets/CharacterWindow-Bm7Dvqbf.js b/static/assets/CharacterWindow-5cx18R5O.js similarity index 99% rename from static/assets/CharacterWindow-Bm7Dvqbf.js rename to static/assets/CharacterWindow-5cx18R5O.js index 135020b2..0920c529 100644 --- a/static/assets/CharacterWindow-Bm7Dvqbf.js +++ b/static/assets/CharacterWindow-5cx18R5O.js @@ -1 +1 @@ -import{r as f,a as J,j as e,D as K}from"./index-D5aV9Wxd.js";import"./react-yfL0ty4i.js";const F={218:"Reinforcement of the Lugians",219:"Bleeargh's Fortitude",220:"Oswald's Enhancement",221:"Siraluun's Blessing",222:"Enduring Calm",223:"Steadfast Will",224:"Ciandra's Essence",225:"Yoshi's Essence",226:"Jibril's Essence",227:"Celdiseth's Essence",228:"Koga's Essence",229:"Shadow of the Seventh Mule",230:"Might of the Seventh Mule",231:"Clutch of the Miser",232:"Enduring Enchantment",233:"Critical Protection",234:"Quick Learner",235:"Ciandra's Fortune",236:"Charmed Smith",237:"Innate Renewal",238:"Archmage's Endurance",239:"Enhancement of the Blade Turner",240:"Enhancement of the Arrow Turner",241:"Enhancement of the Mace Turner",242:"Caustic Enhancement",243:"Fierce Impaler",244:"Iron Skin of the Invincible",245:"Eye of the Remorseless",246:"Hand of the Remorseless",294:"Master of the Steel Circle",295:"Master of the Focused Eye",296:"Master of the Five Fold Path",297:"Frenzy of the Slayer",298:"Iron Skin of the Invincible",299:"Jack of All Trades",300:"Infused Void Magic",301:"Infused War Magic",302:"Infused Life Magic",309:"Infused Item Magic",310:"Infused Creature Magic",326:"Clutch of the Miser",328:"Enduring Enchantment"},B={333:"Valor / Destruction",334:"Protection",335:"Glory / Retribution",336:"Temperance / Hardening",338:"Aetheric Vision",339:"Mana Flow",340:"Mana Infusion",342:"Purity",343:"Craftsman",344:"Specialization",365:"World"},$={370:"Damage",371:"Damage Resistance",372:"Critical",373:"Critical Resistance",374:"Critical Damage",375:"Critical Damage Resistance",376:"Healing Boost",379:"Vitality"},W={287:"Celestial Hand",288:"Eldrytch Web",289:"Radiant Blood"},D={354:"Melee",355:"Ranged",362:"Summoning"},q={1:"Unarmed",2:"Swords",3:"Axes",4:"Maces",5:"Spears",6:"Daggers",7:"Staves",8:"Bows",9:"Crossbows",10:"Thrown",11:"Two-Handed",12:"Void",13:"War",14:"Life"},U={181:"Chess Rank",192:"Fishing Skill",199:"Total Augmentations",322:"Aetheria Slots",390:"Enlightenment"};function Q(c){return c>=1001?"Master":c>=301?"Lord":c>=151?"Knight":c>=31?"Adept":"Initiate"}const d="#af7a30",u="#000022",ee=({id:c,charName:g,zIndex:L,vitals:s,liveStats:O})=>{var _,N;const[H,P]=f.useState(null),[j,V]=f.useState(0),[m,G]=f.useState(0);f.useEffect(()=>{J(`/character-stats/${encodeURIComponent(g)}`).then(P).catch(()=>{})},[g]);const n=O||H,a=t=>t!=null?Number(t).toLocaleString():"—",o=(n==null?void 0:n.stats_data)||n||{},C=o.attributes||{},A=o.skills||{},Y=o.vitals||{},E=o.titles||[],h=o.properties||{},T=Object.entries(A).filter(([,t])=>(t==null?void 0:t.training)==="Specialized").sort(([t],[l])=>t.localeCompare(l)),I=Object.entries(A).filter(([,t])=>(t==null?void 0:t.training)==="Trained").sort(([t],[l])=>t.localeCompare(l)),S=Object.entries(h).filter(([t,l])=>F[parseInt(t)]&&Number(l)>0).map(([t,l])=>({name:F[parseInt(t)],uses:Number(l)})),w=Object.entries(h).filter(([t,l])=>B[parseInt(t)]&&Number(l)>0).map(([t,l])=>({name:B[parseInt(t)],uses:Number(l)})),z=Object.entries(h).filter(([t,l])=>$[parseInt(t)]&&Number(l)>0).map(([t,l])=>({name:$[parseInt(t)],value:Number(l)})),x=[];n!=null&&n.birth&&x.push({name:"Birth",value:n.birth}),(n==null?void 0:n.deaths)!=null&&x.push({name:"Deaths",value:a(n.deaths)}),Object.entries(h).forEach(([t,l])=>{const i=parseInt(t);U[i]&&x.push({name:U[i],value:l})});const y=[];Object.entries(h).forEach(([t,l])=>{const i=parseInt(t);D[i]&&y.push({name:D[i],value:q[Number(l)]||`Unknown (${l})`})});const b=[];Object.entries(h).forEach(([t,l])=>{const i=parseInt(t);W[i]&&Number(l)>0&&b.push({name:W[i],rank:Q(Number(l)),value:Number(l)})});const R=t=>({padding:"5px 8px",fontSize:12,fontWeight:"bold",color:"#fff",cursor:"pointer",userSelect:"none",borderTop:`2px solid ${t?d:u}`,borderLeft:`2px solid ${t?d:u}`,borderRight:`2px solid ${t?d:u}`,background:t?"rgba(0,100,0,0.4)":"transparent"}),M={background:"#000",border:`2px solid ${d}`,maxHeight:400,overflowY:"auto",overflowX:"hidden"},r={background:"#222",fontWeight:"bold",fontSize:12,padding:"2px 6px"},k={padding:"2px 6px",background:"rgba(0,100,0,0.4)",whiteSpace:"nowrap"},p={padding:"2px 6px",background:"rgba(0,0,100,0.4)",textAlign:"right",whiteSpace:"nowrap"},X={padding:"2px 6px",color:"#ccc"};return e.jsx(K,{id:c,title:`Character: ${g}`,zIndex:L,width:740,height:600,children:e.jsxs("div",{style:{background:u,color:"#fff",font:'14px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif',overflowY:"auto",padding:"10px 15px 15px",flex:1},children:[e.jsxs("div",{style:{marginBottom:10},children:[e.jsxs("h1",{style:{margin:"0 0 2px",fontSize:28,fontWeight:"bold"},children:[g,e.jsx("span",{style:{fontSize:"200%",color:"#fff27f",float:"right"},children:(n==null?void 0:n.level)||""})]}),e.jsx("div",{style:{fontSize:"85%",color:"gold"},children:[n==null?void 0:n.gender,n==null?void 0:n.race].filter(Boolean).join(" ")||"Awaiting character data..."})]}),e.jsxs("div",{style:{fontSize:"85%",margin:"6px 0 10px",display:"grid",gridTemplateColumns:"1fr 1fr",gap:"0 20px"},children:[e.jsxs("div",{children:["Total XP: ",a(n==null?void 0:n.total_xp)]}),e.jsxs("div",{style:{textAlign:"right"},children:["Unassigned XP: ",a(n==null?void 0:n.unassigned_xp)]}),e.jsxs("div",{children:["Luminance: ",(n==null?void 0:n.luminance_earned)!=null?`${a(n.luminance_earned)} / ${a(n.luminance_total)}`:"—"]}),e.jsxs("div",{style:{textAlign:"right"},children:["Deaths: ",a(n==null?void 0:n.deaths)]})]}),e.jsxs("div",{style:{display:"flex",gap:13,flexWrap:"wrap"},children:[e.jsxs("div",{style:{width:320},children:[e.jsx("div",{style:{height:30,display:"flex"},children:["Attributes","Skills","Titles"].map((t,l)=>e.jsx("div",{style:R(j===l),onClick:()=>V(l),children:t},t))}),e.jsxs("div",{style:M,children:[j===0&&e.jsxs(e.Fragment,{children:[e.jsx("div",{style:{padding:"6px 8px",display:"flex",flexDirection:"column",gap:8,borderBottom:`2px solid ${d}`},children:[{label:"Health",pct:(s==null?void 0:s.health_percentage)??0,cur:s==null?void 0:s.health_current,max:s==null?void 0:s.health_max,bg:"#cc3333"},{label:"Stamina",pct:(s==null?void 0:s.stamina_percentage)??0,cur:s==null?void 0:s.stamina_current,max:s==null?void 0:s.stamina_max,bg:"#ccaa33"},{label:"Mana",pct:(s==null?void 0:s.mana_percentage)??0,cur:s==null?void 0:s.mana_current,max:s==null?void 0:s.mana_max,bg:"#3366cc"}].map(t=>e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6},children:[e.jsx("span",{style:{width:55,fontSize:12,color:"#ccc"},children:t.label}),e.jsx("div",{style:{flex:1,height:14,overflow:"hidden",position:"relative",border:`1px solid ${d}`},children:e.jsx("div",{style:{height:"100%",width:`${t.pct}%`,background:t.bg,transition:"width 0.5s ease"}})}),e.jsxs("span",{style:{width:80,textAlign:"right",fontSize:12,color:"#ccc"},children:[t.cur??"—"," / ",t.max??"—"]})]},t.label))}),e.jsxs("table",{style:{width:"100%",fontSize:13,borderCollapse:"collapse"},children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("td",{style:r,children:"Attribute"}),e.jsx("td",{style:r,children:"Creation"}),e.jsx("td",{style:r,children:"Base"})]})}),e.jsx("tbody",{children:["strength","endurance","coordination","quickness","focus","self"].map(t=>{var l,i;return e.jsxs("tr",{children:[e.jsx("td",{style:k,children:t.charAt(0).toUpperCase()+t.slice(1)}),e.jsx("td",{style:X,children:((l=C[t])==null?void 0:l.creation)??"—"}),e.jsx("td",{style:p,children:((i=C[t])==null?void 0:i.base)??"—"})]},t)})})]}),e.jsxs("table",{style:{width:"100%",fontSize:13,borderCollapse:"collapse"},children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("td",{style:r,children:"Vital"}),e.jsx("td",{style:r,children:"Base"})]})}),e.jsx("tbody",{children:["health","stamina","mana"].map(t=>{var l;return e.jsxs("tr",{children:[e.jsx("td",{style:k,children:t.charAt(0).toUpperCase()+t.slice(1)}),e.jsx("td",{style:p,children:((l=Y[t])==null?void 0:l.base)??"—"})]},t)})})]}),e.jsx("table",{style:{width:"100%",fontSize:13,borderCollapse:"collapse"},children:e.jsx("tbody",{children:e.jsxs("tr",{children:[e.jsx("td",{style:k,children:"Skill Credits"}),e.jsx("td",{style:p,children:a(o.skill_credits)})]})})})]}),j===1&&e.jsxs("table",{style:{width:"100%",fontSize:13,borderCollapse:"collapse"},children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("td",{style:r,children:"Skill"}),e.jsx("td",{style:r,children:"Level"})]})}),e.jsxs("tbody",{children:[T.map(([t,l])=>e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"2px 6px",background:"linear-gradient(to right, #392067, #392067, black)"},children:t.replace(/_/g," ").replace(/\b\w/g,i=>i.toUpperCase())}),e.jsx("td",{style:{...p,background:"linear-gradient(to right, #392067, #392067, black)"},children:l.base})]},t)),I.map(([t,l])=>e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"2px 6px",background:"linear-gradient(to right, #0f3c3e, #0f3c3e, black)"},children:t.replace(/_/g," ").replace(/\b\w/g,i=>i.toUpperCase())}),e.jsx("td",{style:{...p,background:"linear-gradient(to right, #0f3c3e, #0f3c3e, black)"},children:l.base})]},t)),T.length===0&&I.length===0&&e.jsx("tr",{children:e.jsx("td",{colSpan:2,style:{padding:10,color:"#666",fontStyle:"italic",textAlign:"center"},children:"No skill data"})})]})]}),j===2&&e.jsx("div",{style:{padding:"6px 10px",fontSize:13},children:E.length>0?E.map((t,l)=>e.jsx("div",{style:{padding:"1px 0"},children:t},l)):e.jsx("div",{style:{color:"#666",fontStyle:"italic",textAlign:"center",padding:10},children:"No titles"})})]})]}),e.jsxs("div",{style:{width:320},children:[e.jsx("div",{style:{height:30,display:"flex"},children:["Augmentations","Ratings","Other"].map((t,l)=>e.jsx("div",{style:R(m===l),onClick:()=>G(l),children:t},t))}),e.jsxs("div",{style:M,children:[m===0&&(S.length||w.length?e.jsxs(e.Fragment,{children:[S.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("div",{style:{background:"#222",padding:"4px 8px",fontWeight:"bold",fontSize:13,borderBottom:`1px solid ${d}`},children:"Augmentations"}),e.jsxs("table",{style:{width:"100%",fontSize:13,borderCollapse:"collapse"},children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("td",{style:r,children:"Name"}),e.jsx("td",{style:r,children:"Uses"})]})}),e.jsx("tbody",{children:S.map(t=>e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"2px 6px"},children:t.name}),e.jsx("td",{style:{padding:"2px 6px",textAlign:"right"},children:t.uses})]},t.name))})]})]}),w.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("div",{style:{background:"#222",padding:"4px 8px",fontWeight:"bold",fontSize:13,borderBottom:`1px solid ${d}`},children:"Auras"}),e.jsxs("table",{style:{width:"100%",fontSize:13,borderCollapse:"collapse"},children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("td",{style:r,children:"Name"}),e.jsx("td",{style:r,children:"Uses"})]})}),e.jsx("tbody",{children:w.map(t=>e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"2px 6px"},children:t.name}),e.jsx("td",{style:{padding:"2px 6px",textAlign:"right"},children:t.uses})]},t.name))})]})]})]}):e.jsx("div",{style:{color:"#666",fontStyle:"italic",textAlign:"center",padding:10},children:"No augmentation data"})),m===1&&(z.length>0?e.jsxs("table",{style:{width:"100%",fontSize:13,borderCollapse:"collapse"},children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("td",{style:r,children:"Rating"}),e.jsx("td",{style:r,children:"Value"})]})}),e.jsx("tbody",{children:z.map(t=>e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"2px 6px"},children:t.name}),e.jsx("td",{style:{padding:"2px 6px",textAlign:"right"},children:t.value})]},t.name))})]}):e.jsx("div",{style:{color:"#666",fontStyle:"italic",textAlign:"center",padding:10},children:"No rating data"})),m===2&&e.jsxs("div",{children:[x.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("div",{style:{background:"#222",padding:"4px 8px",fontWeight:"bold",fontSize:13,borderBottom:`1px solid ${d}`},children:"General"}),e.jsx("table",{style:{width:"100%",fontSize:13,borderCollapse:"collapse"},children:e.jsx("tbody",{children:x.map(t=>e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"2px 6px"},children:t.name}),e.jsx("td",{style:{padding:"2px 6px",textAlign:"right"},children:t.value})]},t.name))})})]}),y.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("div",{style:{background:"#222",padding:"4px 8px",fontWeight:"bold",fontSize:13,borderBottom:`1px solid ${d}`},children:"Masteries"}),e.jsx("table",{style:{width:"100%",fontSize:13,borderCollapse:"collapse"},children:e.jsx("tbody",{children:y.map(t=>e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"2px 6px"},children:t.name}),e.jsx("td",{style:{padding:"2px 6px",textAlign:"right"},children:t.value})]},t.name))})})]}),b.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("div",{style:{background:"#222",padding:"4px 8px",fontWeight:"bold",fontSize:13,borderBottom:`1px solid ${d}`},children:"Society"}),e.jsx("table",{style:{width:"100%",fontSize:13,borderCollapse:"collapse"},children:e.jsx("tbody",{children:b.map(t=>e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"2px 6px"},children:t.name}),e.jsxs("td",{style:{padding:"2px 6px",textAlign:"right"},children:[t.rank," (",t.value,")"]})]},t.name))})})]}),x.length===0&&y.length===0&&b.length===0&&e.jsx("div",{style:{color:"#666",fontStyle:"italic",textAlign:"center",padding:10},children:"No additional data"})]})]})]})]}),(n==null?void 0:n.allegiance)&&e.jsxs("div",{style:{marginTop:5,border:`2px solid ${d}`,background:"#000"},children:[e.jsx("div",{style:{background:"#222",padding:"4px 8px",fontWeight:"bold",fontSize:13,borderBottom:`1px solid ${d}`},children:"Allegiance"}),e.jsx("table",{style:{width:"100%",fontSize:13,borderCollapse:"collapse"},children:e.jsxs("tbody",{children:[n.allegiance.name&&e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"2px 6px",color:"#ccc",width:100},children:"Name"}),e.jsx("td",{style:{padding:"2px 6px"},children:n.allegiance.name})]}),((_=n.allegiance.monarch)==null?void 0:_.name)&&e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"2px 6px",color:"#ccc"},children:"Monarch"}),e.jsx("td",{style:{padding:"2px 6px"},children:n.allegiance.monarch.name})]}),((N=n.allegiance.patron)==null?void 0:N.name)&&e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"2px 6px",color:"#ccc"},children:"Patron"}),e.jsx("td",{style:{padding:"2px 6px"},children:n.allegiance.patron.name})]}),n.allegiance.rank!=null&&e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"2px 6px",color:"#ccc"},children:"Rank"}),e.jsx("td",{style:{padding:"2px 6px"},children:n.allegiance.rank})]}),n.allegiance.followers!=null&&e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"2px 6px",color:"#ccc"},children:"Followers"}),e.jsx("td",{style:{padding:"2px 6px"},children:n.allegiance.followers})]})]})})]})]})})};export{ee as CharacterWindow}; +import{r as f,a as J,j as e,D as K}from"./index-CPIBhBUe.js";import"./react-yfL0ty4i.js";const F={218:"Reinforcement of the Lugians",219:"Bleeargh's Fortitude",220:"Oswald's Enhancement",221:"Siraluun's Blessing",222:"Enduring Calm",223:"Steadfast Will",224:"Ciandra's Essence",225:"Yoshi's Essence",226:"Jibril's Essence",227:"Celdiseth's Essence",228:"Koga's Essence",229:"Shadow of the Seventh Mule",230:"Might of the Seventh Mule",231:"Clutch of the Miser",232:"Enduring Enchantment",233:"Critical Protection",234:"Quick Learner",235:"Ciandra's Fortune",236:"Charmed Smith",237:"Innate Renewal",238:"Archmage's Endurance",239:"Enhancement of the Blade Turner",240:"Enhancement of the Arrow Turner",241:"Enhancement of the Mace Turner",242:"Caustic Enhancement",243:"Fierce Impaler",244:"Iron Skin of the Invincible",245:"Eye of the Remorseless",246:"Hand of the Remorseless",294:"Master of the Steel Circle",295:"Master of the Focused Eye",296:"Master of the Five Fold Path",297:"Frenzy of the Slayer",298:"Iron Skin of the Invincible",299:"Jack of All Trades",300:"Infused Void Magic",301:"Infused War Magic",302:"Infused Life Magic",309:"Infused Item Magic",310:"Infused Creature Magic",326:"Clutch of the Miser",328:"Enduring Enchantment"},B={333:"Valor / Destruction",334:"Protection",335:"Glory / Retribution",336:"Temperance / Hardening",338:"Aetheric Vision",339:"Mana Flow",340:"Mana Infusion",342:"Purity",343:"Craftsman",344:"Specialization",365:"World"},$={370:"Damage",371:"Damage Resistance",372:"Critical",373:"Critical Resistance",374:"Critical Damage",375:"Critical Damage Resistance",376:"Healing Boost",379:"Vitality"},W={287:"Celestial Hand",288:"Eldrytch Web",289:"Radiant Blood"},D={354:"Melee",355:"Ranged",362:"Summoning"},q={1:"Unarmed",2:"Swords",3:"Axes",4:"Maces",5:"Spears",6:"Daggers",7:"Staves",8:"Bows",9:"Crossbows",10:"Thrown",11:"Two-Handed",12:"Void",13:"War",14:"Life"},U={181:"Chess Rank",192:"Fishing Skill",199:"Total Augmentations",322:"Aetheria Slots",390:"Enlightenment"};function Q(c){return c>=1001?"Master":c>=301?"Lord":c>=151?"Knight":c>=31?"Adept":"Initiate"}const d="#af7a30",u="#000022",ee=({id:c,charName:g,zIndex:L,vitals:s,liveStats:O})=>{var _,N;const[H,P]=f.useState(null),[j,V]=f.useState(0),[m,G]=f.useState(0);f.useEffect(()=>{J(`/character-stats/${encodeURIComponent(g)}`).then(P).catch(()=>{})},[g]);const n=O||H,a=t=>t!=null?Number(t).toLocaleString():"—",o=(n==null?void 0:n.stats_data)||n||{},C=o.attributes||{},A=o.skills||{},Y=o.vitals||{},E=o.titles||[],h=o.properties||{},T=Object.entries(A).filter(([,t])=>(t==null?void 0:t.training)==="Specialized").sort(([t],[l])=>t.localeCompare(l)),I=Object.entries(A).filter(([,t])=>(t==null?void 0:t.training)==="Trained").sort(([t],[l])=>t.localeCompare(l)),S=Object.entries(h).filter(([t,l])=>F[parseInt(t)]&&Number(l)>0).map(([t,l])=>({name:F[parseInt(t)],uses:Number(l)})),w=Object.entries(h).filter(([t,l])=>B[parseInt(t)]&&Number(l)>0).map(([t,l])=>({name:B[parseInt(t)],uses:Number(l)})),z=Object.entries(h).filter(([t,l])=>$[parseInt(t)]&&Number(l)>0).map(([t,l])=>({name:$[parseInt(t)],value:Number(l)})),x=[];n!=null&&n.birth&&x.push({name:"Birth",value:n.birth}),(n==null?void 0:n.deaths)!=null&&x.push({name:"Deaths",value:a(n.deaths)}),Object.entries(h).forEach(([t,l])=>{const i=parseInt(t);U[i]&&x.push({name:U[i],value:l})});const y=[];Object.entries(h).forEach(([t,l])=>{const i=parseInt(t);D[i]&&y.push({name:D[i],value:q[Number(l)]||`Unknown (${l})`})});const b=[];Object.entries(h).forEach(([t,l])=>{const i=parseInt(t);W[i]&&Number(l)>0&&b.push({name:W[i],rank:Q(Number(l)),value:Number(l)})});const R=t=>({padding:"5px 8px",fontSize:12,fontWeight:"bold",color:"#fff",cursor:"pointer",userSelect:"none",borderTop:`2px solid ${t?d:u}`,borderLeft:`2px solid ${t?d:u}`,borderRight:`2px solid ${t?d:u}`,background:t?"rgba(0,100,0,0.4)":"transparent"}),M={background:"#000",border:`2px solid ${d}`,maxHeight:400,overflowY:"auto",overflowX:"hidden"},r={background:"#222",fontWeight:"bold",fontSize:12,padding:"2px 6px"},k={padding:"2px 6px",background:"rgba(0,100,0,0.4)",whiteSpace:"nowrap"},p={padding:"2px 6px",background:"rgba(0,0,100,0.4)",textAlign:"right",whiteSpace:"nowrap"},X={padding:"2px 6px",color:"#ccc"};return e.jsx(K,{id:c,title:`Character: ${g}`,zIndex:L,width:740,height:600,children:e.jsxs("div",{style:{background:u,color:"#fff",font:'14px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif',overflowY:"auto",padding:"10px 15px 15px",flex:1},children:[e.jsxs("div",{style:{marginBottom:10},children:[e.jsxs("h1",{style:{margin:"0 0 2px",fontSize:28,fontWeight:"bold"},children:[g,e.jsx("span",{style:{fontSize:"200%",color:"#fff27f",float:"right"},children:(n==null?void 0:n.level)||""})]}),e.jsx("div",{style:{fontSize:"85%",color:"gold"},children:[n==null?void 0:n.gender,n==null?void 0:n.race].filter(Boolean).join(" ")||"Awaiting character data..."})]}),e.jsxs("div",{style:{fontSize:"85%",margin:"6px 0 10px",display:"grid",gridTemplateColumns:"1fr 1fr",gap:"0 20px"},children:[e.jsxs("div",{children:["Total XP: ",a(n==null?void 0:n.total_xp)]}),e.jsxs("div",{style:{textAlign:"right"},children:["Unassigned XP: ",a(n==null?void 0:n.unassigned_xp)]}),e.jsxs("div",{children:["Luminance: ",(n==null?void 0:n.luminance_earned)!=null?`${a(n.luminance_earned)} / ${a(n.luminance_total)}`:"—"]}),e.jsxs("div",{style:{textAlign:"right"},children:["Deaths: ",a(n==null?void 0:n.deaths)]})]}),e.jsxs("div",{style:{display:"flex",gap:13,flexWrap:"wrap"},children:[e.jsxs("div",{style:{width:320},children:[e.jsx("div",{style:{height:30,display:"flex"},children:["Attributes","Skills","Titles"].map((t,l)=>e.jsx("div",{style:R(j===l),onClick:()=>V(l),children:t},t))}),e.jsxs("div",{style:M,children:[j===0&&e.jsxs(e.Fragment,{children:[e.jsx("div",{style:{padding:"6px 8px",display:"flex",flexDirection:"column",gap:8,borderBottom:`2px solid ${d}`},children:[{label:"Health",pct:(s==null?void 0:s.health_percentage)??0,cur:s==null?void 0:s.health_current,max:s==null?void 0:s.health_max,bg:"#cc3333"},{label:"Stamina",pct:(s==null?void 0:s.stamina_percentage)??0,cur:s==null?void 0:s.stamina_current,max:s==null?void 0:s.stamina_max,bg:"#ccaa33"},{label:"Mana",pct:(s==null?void 0:s.mana_percentage)??0,cur:s==null?void 0:s.mana_current,max:s==null?void 0:s.mana_max,bg:"#3366cc"}].map(t=>e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6},children:[e.jsx("span",{style:{width:55,fontSize:12,color:"#ccc"},children:t.label}),e.jsx("div",{style:{flex:1,height:14,overflow:"hidden",position:"relative",border:`1px solid ${d}`},children:e.jsx("div",{style:{height:"100%",width:`${t.pct}%`,background:t.bg,transition:"width 0.5s ease"}})}),e.jsxs("span",{style:{width:80,textAlign:"right",fontSize:12,color:"#ccc"},children:[t.cur??"—"," / ",t.max??"—"]})]},t.label))}),e.jsxs("table",{style:{width:"100%",fontSize:13,borderCollapse:"collapse"},children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("td",{style:r,children:"Attribute"}),e.jsx("td",{style:r,children:"Creation"}),e.jsx("td",{style:r,children:"Base"})]})}),e.jsx("tbody",{children:["strength","endurance","coordination","quickness","focus","self"].map(t=>{var l,i;return e.jsxs("tr",{children:[e.jsx("td",{style:k,children:t.charAt(0).toUpperCase()+t.slice(1)}),e.jsx("td",{style:X,children:((l=C[t])==null?void 0:l.creation)??"—"}),e.jsx("td",{style:p,children:((i=C[t])==null?void 0:i.base)??"—"})]},t)})})]}),e.jsxs("table",{style:{width:"100%",fontSize:13,borderCollapse:"collapse"},children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("td",{style:r,children:"Vital"}),e.jsx("td",{style:r,children:"Base"})]})}),e.jsx("tbody",{children:["health","stamina","mana"].map(t=>{var l;return e.jsxs("tr",{children:[e.jsx("td",{style:k,children:t.charAt(0).toUpperCase()+t.slice(1)}),e.jsx("td",{style:p,children:((l=Y[t])==null?void 0:l.base)??"—"})]},t)})})]}),e.jsx("table",{style:{width:"100%",fontSize:13,borderCollapse:"collapse"},children:e.jsx("tbody",{children:e.jsxs("tr",{children:[e.jsx("td",{style:k,children:"Skill Credits"}),e.jsx("td",{style:p,children:a(o.skill_credits)})]})})})]}),j===1&&e.jsxs("table",{style:{width:"100%",fontSize:13,borderCollapse:"collapse"},children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("td",{style:r,children:"Skill"}),e.jsx("td",{style:r,children:"Level"})]})}),e.jsxs("tbody",{children:[T.map(([t,l])=>e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"2px 6px",background:"linear-gradient(to right, #392067, #392067, black)"},children:t.replace(/_/g," ").replace(/\b\w/g,i=>i.toUpperCase())}),e.jsx("td",{style:{...p,background:"linear-gradient(to right, #392067, #392067, black)"},children:l.base})]},t)),I.map(([t,l])=>e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"2px 6px",background:"linear-gradient(to right, #0f3c3e, #0f3c3e, black)"},children:t.replace(/_/g," ").replace(/\b\w/g,i=>i.toUpperCase())}),e.jsx("td",{style:{...p,background:"linear-gradient(to right, #0f3c3e, #0f3c3e, black)"},children:l.base})]},t)),T.length===0&&I.length===0&&e.jsx("tr",{children:e.jsx("td",{colSpan:2,style:{padding:10,color:"#666",fontStyle:"italic",textAlign:"center"},children:"No skill data"})})]})]}),j===2&&e.jsx("div",{style:{padding:"6px 10px",fontSize:13},children:E.length>0?E.map((t,l)=>e.jsx("div",{style:{padding:"1px 0"},children:t},l)):e.jsx("div",{style:{color:"#666",fontStyle:"italic",textAlign:"center",padding:10},children:"No titles"})})]})]}),e.jsxs("div",{style:{width:320},children:[e.jsx("div",{style:{height:30,display:"flex"},children:["Augmentations","Ratings","Other"].map((t,l)=>e.jsx("div",{style:R(m===l),onClick:()=>G(l),children:t},t))}),e.jsxs("div",{style:M,children:[m===0&&(S.length||w.length?e.jsxs(e.Fragment,{children:[S.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("div",{style:{background:"#222",padding:"4px 8px",fontWeight:"bold",fontSize:13,borderBottom:`1px solid ${d}`},children:"Augmentations"}),e.jsxs("table",{style:{width:"100%",fontSize:13,borderCollapse:"collapse"},children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("td",{style:r,children:"Name"}),e.jsx("td",{style:r,children:"Uses"})]})}),e.jsx("tbody",{children:S.map(t=>e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"2px 6px"},children:t.name}),e.jsx("td",{style:{padding:"2px 6px",textAlign:"right"},children:t.uses})]},t.name))})]})]}),w.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("div",{style:{background:"#222",padding:"4px 8px",fontWeight:"bold",fontSize:13,borderBottom:`1px solid ${d}`},children:"Auras"}),e.jsxs("table",{style:{width:"100%",fontSize:13,borderCollapse:"collapse"},children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("td",{style:r,children:"Name"}),e.jsx("td",{style:r,children:"Uses"})]})}),e.jsx("tbody",{children:w.map(t=>e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"2px 6px"},children:t.name}),e.jsx("td",{style:{padding:"2px 6px",textAlign:"right"},children:t.uses})]},t.name))})]})]})]}):e.jsx("div",{style:{color:"#666",fontStyle:"italic",textAlign:"center",padding:10},children:"No augmentation data"})),m===1&&(z.length>0?e.jsxs("table",{style:{width:"100%",fontSize:13,borderCollapse:"collapse"},children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("td",{style:r,children:"Rating"}),e.jsx("td",{style:r,children:"Value"})]})}),e.jsx("tbody",{children:z.map(t=>e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"2px 6px"},children:t.name}),e.jsx("td",{style:{padding:"2px 6px",textAlign:"right"},children:t.value})]},t.name))})]}):e.jsx("div",{style:{color:"#666",fontStyle:"italic",textAlign:"center",padding:10},children:"No rating data"})),m===2&&e.jsxs("div",{children:[x.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("div",{style:{background:"#222",padding:"4px 8px",fontWeight:"bold",fontSize:13,borderBottom:`1px solid ${d}`},children:"General"}),e.jsx("table",{style:{width:"100%",fontSize:13,borderCollapse:"collapse"},children:e.jsx("tbody",{children:x.map(t=>e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"2px 6px"},children:t.name}),e.jsx("td",{style:{padding:"2px 6px",textAlign:"right"},children:t.value})]},t.name))})})]}),y.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("div",{style:{background:"#222",padding:"4px 8px",fontWeight:"bold",fontSize:13,borderBottom:`1px solid ${d}`},children:"Masteries"}),e.jsx("table",{style:{width:"100%",fontSize:13,borderCollapse:"collapse"},children:e.jsx("tbody",{children:y.map(t=>e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"2px 6px"},children:t.name}),e.jsx("td",{style:{padding:"2px 6px",textAlign:"right"},children:t.value})]},t.name))})})]}),b.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("div",{style:{background:"#222",padding:"4px 8px",fontWeight:"bold",fontSize:13,borderBottom:`1px solid ${d}`},children:"Society"}),e.jsx("table",{style:{width:"100%",fontSize:13,borderCollapse:"collapse"},children:e.jsx("tbody",{children:b.map(t=>e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"2px 6px"},children:t.name}),e.jsxs("td",{style:{padding:"2px 6px",textAlign:"right"},children:[t.rank," (",t.value,")"]})]},t.name))})})]}),x.length===0&&y.length===0&&b.length===0&&e.jsx("div",{style:{color:"#666",fontStyle:"italic",textAlign:"center",padding:10},children:"No additional data"})]})]})]})]}),(n==null?void 0:n.allegiance)&&e.jsxs("div",{style:{marginTop:5,border:`2px solid ${d}`,background:"#000"},children:[e.jsx("div",{style:{background:"#222",padding:"4px 8px",fontWeight:"bold",fontSize:13,borderBottom:`1px solid ${d}`},children:"Allegiance"}),e.jsx("table",{style:{width:"100%",fontSize:13,borderCollapse:"collapse"},children:e.jsxs("tbody",{children:[n.allegiance.name&&e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"2px 6px",color:"#ccc",width:100},children:"Name"}),e.jsx("td",{style:{padding:"2px 6px"},children:n.allegiance.name})]}),((_=n.allegiance.monarch)==null?void 0:_.name)&&e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"2px 6px",color:"#ccc"},children:"Monarch"}),e.jsx("td",{style:{padding:"2px 6px"},children:n.allegiance.monarch.name})]}),((N=n.allegiance.patron)==null?void 0:N.name)&&e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"2px 6px",color:"#ccc"},children:"Patron"}),e.jsx("td",{style:{padding:"2px 6px"},children:n.allegiance.patron.name})]}),n.allegiance.rank!=null&&e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"2px 6px",color:"#ccc"},children:"Rank"}),e.jsx("td",{style:{padding:"2px 6px"},children:n.allegiance.rank})]}),n.allegiance.followers!=null&&e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"2px 6px",color:"#ccc"},children:"Followers"}),e.jsx("td",{style:{padding:"2px 6px"},children:n.allegiance.followers})]})]})})]})]})})};export{ee as CharacterWindow}; diff --git a/static/assets/CombatPickerWindow-CJZfow68.js b/static/assets/CombatPickerWindow-CeceAs6p.js similarity index 92% rename from static/assets/CombatPickerWindow-CJZfow68.js rename to static/assets/CombatPickerWindow-CeceAs6p.js index a16590ac..206ff794 100644 --- a/static/assets/CombatPickerWindow-CJZfow68.js +++ b/static/assets/CombatPickerWindow-CeceAs6p.js @@ -1 +1 @@ -import{u as c,j as r,D as d}from"./index-D5aV9Wxd.js";import"./react-yfL0ty4i.js";const p=({id:n,zIndex:i,characters:a})=>{const{openWindow:s}=c(),e=Array.from(a.keys()).sort();return r.jsx(d,{id:n,title:"Combat Stats — Select Character",zIndex:i,width:300,height:400,children:r.jsx("div",{style:{flex:1,overflowY:"auto",padding:6},children:e.length===0?r.jsx("div",{style:{padding:12,color:"#666",textAlign:"center",fontSize:"0.8rem"},children:"No characters online"}):e.map(o=>r.jsx("div",{style:{padding:"5px 8px",cursor:"pointer",borderBottom:"1px solid #222",color:"#ccc",fontSize:"0.82rem"},onMouseEnter:t=>t.currentTarget.style.background="#2a2a2a",onMouseLeave:t=>t.currentTarget.style.background="",onClick:()=>s(`combat-${o}`,`Combat: ${o}`,o),children:o},o))})})};export{p as CombatPickerWindow}; +import{u as c,j as r,D as d}from"./index-CPIBhBUe.js";import"./react-yfL0ty4i.js";const p=({id:n,zIndex:i,characters:a})=>{const{openWindow:s}=c(),e=Array.from(a.keys()).sort();return r.jsx(d,{id:n,title:"Combat Stats — Select Character",zIndex:i,width:300,height:400,children:r.jsx("div",{style:{flex:1,overflowY:"auto",padding:6},children:e.length===0?r.jsx("div",{style:{padding:12,color:"#666",textAlign:"center",fontSize:"0.8rem"},children:"No characters online"}):e.map(o=>r.jsx("div",{style:{padding:"5px 8px",cursor:"pointer",borderBottom:"1px solid #222",color:"#ccc",fontSize:"0.82rem"},onMouseEnter:t=>t.currentTarget.style.background="#2a2a2a",onMouseLeave:t=>t.currentTarget.style.background="",onClick:()=>s(`combat-${o}`,`Combat: ${o}`,o),children:o},o))})})};export{p as CombatPickerWindow}; diff --git a/static/assets/CombatStatsWindow-DrwSvkSn.js b/static/assets/CombatStatsWindow-DiW4OOU6.js similarity index 99% rename from static/assets/CombatStatsWindow-DrwSvkSn.js rename to static/assets/CombatStatsWindow-DiW4OOU6.js index b2caf3eb..e0ae3a07 100644 --- a/static/assets/CombatStatsWindow-DrwSvkSn.js +++ b/static/assets/CombatStatsWindow-DiW4OOU6.js @@ -1 +1 @@ -import{r as A,a as B,j as t,D as L}from"./index-D5aV9Wxd.js";import"./react-yfL0ty4i.js";const w=["Typeless","Slash","Pierce","Bludgeon","Fire","Cold","Acid","Electric"];function _(c,a,x){var o,m,f,k;return(((m=(o=c==null?void 0:c[a])==null?void 0:o[x])==null?void 0:m.total_normal_damage)??0)+(((k=(f=c==null?void 0:c[a])==null?void 0:f[x])==null?void 0:k.total_crit_damage)??0)}function G(c){let a={attacks:0,failed:0,crits:0,normalDmg:0,maxNormal:0,critDmg:0,maxCrit:0};if(!c)return a;for(const x of Object.values(c))for(const o of Object.values(x))a.attacks+=o.total_attacks??0,a.failed+=o.failed_attacks??0,a.crits+=o.crits??0,a.normalDmg+=o.total_normal_damage??0,a.maxNormal=Math.max(a.maxNormal,o.max_normal_damage??0),a.critDmg+=o.total_crit_damage??0,a.maxCrit=Math.max(a.maxCrit,o.max_crit_damage??0);return a}function F(c,a){let x={attacks:0,failed:0};const o=c==null?void 0:c[a];if(!o)return x;for(const m of Object.values(o))x.attacks+=m.total_attacks??0,x.failed+=m.failed_attacks??0;return x}const Y=({id:c,charName:a,zIndex:x})=>{const[o,m]=A.useState(null),[f,k]=A.useState("session"),[h,R]=A.useState(null);A.useEffect(()=>{B(`/combat-stats/${encodeURIComponent(a)}`).then(m).catch(()=>{});const e=setInterval(()=>{B(`/combat-stats/${encodeURIComponent(a)}`).then(m).catch(()=>{})},1e4);return()=>clearInterval(e)},[a]);const p=o==null?void 0:o[f],j=(p==null?void 0:p.monsters)??{},S=Object.keys(j).filter(e=>e!=="__cloak_surges__").sort(),n=A.useMemo(()=>{let e={},l={},v=0,$=0;const T=h?[j[h]].filter(Boolean):S.map(u=>j[u]);for(const u of T)if(u){for(const[g,D]of Object.entries(u.offense??{})){e[g]||(e[g]={});for(const[y,E]of Object.entries(D)){e[g][y]||(e[g][y]={total_attacks:0,failed_attacks:0,crits:0,total_normal_damage:0,max_normal_damage:0,total_crit_damage:0,max_crit_damage:0});const i=e[g][y],d=E;i.total_attacks+=d.total_attacks??0,i.failed_attacks+=d.failed_attacks??0,i.crits+=d.crits??0,i.total_normal_damage+=d.total_normal_damage??0,i.max_normal_damage=Math.max(i.max_normal_damage,d.max_normal_damage??0),i.total_crit_damage+=d.total_crit_damage??0,i.max_crit_damage=Math.max(i.max_crit_damage,d.max_crit_damage??0)}}for(const[g,D]of Object.entries(u.defense??{})){l[g]||(l[g]={});for(const[y,E]of Object.entries(D)){l[g][y]||(l[g][y]={total_attacks:0,failed_attacks:0,crits:0,total_normal_damage:0,max_normal_damage:0,total_crit_damage:0,max_crit_damage:0});const i=l[g][y],d=E;i.total_attacks+=d.total_attacks??0,i.failed_attacks+=d.failed_attacks??0,i.total_normal_damage+=d.total_normal_damage??0,i.max_normal_damage=Math.max(i.max_normal_damage,d.max_normal_damage??0),i.total_crit_damage+=d.total_crit_damage??0,i.max_crit_damage=Math.max(i.max_crit_damage,d.max_crit_damage??0)}}v+=u.aetheria_surges??0,$+=u.cloak_surges??0}return j.__cloak_surges__&&!h&&($+=j.__cloak_surges__.cloak_surges??0),{offense:e,defense:l,aeth:v,cloak:$}},[j,S,h]),r=G(n.offense),b=F(n.defense,"MeleeMissile"),M=F(n.defense,"Magic");r.attacks>0&&((r.attacks-r.failed)/r.attacks*100).toFixed(0);const N=b.attacks>0?(b.failed/b.attacks*100).toFixed(0):"0",W=M.attacks>0?(M.failed/M.attacks*100).toFixed(0):"0",C=r.attacks-r.failed,O=C-r.crits,z=O>0?Math.round(r.normalDmg/O):0;r.crits>0&&Math.round(r.critDmg/r.crits);const I=C>0?(r.crits/C*100).toFixed(1):"0",s=e=>e===0?"":e.toLocaleString();return t.jsxs(L,{id:c,title:`Combat: ${a}`,zIndex:x,width:640,height:520,children:[t.jsxs("div",{style:{display:"flex",gap:4,padding:"4px 8px",borderBottom:"1px solid #333",alignItems:"center"},children:[t.jsx("button",{className:`ml-stats-range-btn ${f==="session"?"active":""}`,onClick:()=>k("session"),children:"Session"}),t.jsx("button",{className:`ml-stats-range-btn ${f==="lifetime"?"active":""}`,onClick:()=>k("lifetime"),children:"Lifetime"}),t.jsx("div",{style:{flex:1}}),f==="session"&&t.jsx("button",{style:{fontSize:"0.6rem",padding:"2px 8px",background:"rgba(204,68,68,0.15)",color:"#c66",border:"1px solid rgba(204,68,68,0.3)",borderRadius:3,cursor:"pointer"},onClick:()=>{confirm("Clear current session stats?")&&m(e=>e&&{...e,session:{total_damage_given:0,total_damage_received:0,total_kills:0,total_aetheria_surges:0,total_cloak_surges:0,monsters:{}}})},children:"Clear Session"})]}),t.jsxs("div",{style:{display:"flex",flex:1,overflow:"hidden"},children:[t.jsxs("div",{style:{width:240,borderRight:"1px solid #333",overflowY:"auto",fontSize:"0.72rem"},children:[t.jsxs("div",{style:{display:"flex",padding:"3px 6px",borderBottom:"1px solid #333",color:"#777",fontSize:"0.65rem",fontWeight:600},children:[t.jsx("span",{style:{width:14}}),t.jsx("span",{style:{flex:1},children:"Monster"}),t.jsx("span",{style:{width:40,textAlign:"right"},children:"Kills"}),t.jsx("span",{style:{width:55,textAlign:"right"},children:"Dmg"})]}),t.jsxs("div",{style:{display:"flex",padding:"3px 6px",cursor:"pointer",background:h===null?"#2a3a4a":"",borderBottom:"1px solid #222",color:"#ddd"},onClick:()=>R(null),children:[t.jsx("span",{style:{width:14,color:"#888"},children:h===null?"*":""}),t.jsx("span",{style:{flex:1},children:"All"}),t.jsx("span",{style:{width:40,textAlign:"right"},children:s((p==null?void 0:p.total_kills)??0)}),t.jsx("span",{style:{width:55,textAlign:"right"},children:s((p==null?void 0:p.total_damage_given)??0)})]}),S.map(e=>{const l=j[e];return t.jsxs("div",{style:{display:"flex",padding:"2px 6px",cursor:"pointer",background:h===e?"#2a3a4a":"",borderBottom:"1px solid #1a1a1a",color:"#ccc"},onClick:()=>R(e),children:[t.jsx("span",{style:{width:14,color:"#888"},children:h===e?"*":""}),t.jsx("span",{style:{flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:e}),t.jsx("span",{style:{width:40,textAlign:"right"},children:s(l.kill_count)}),t.jsx("span",{style:{width:55,textAlign:"right"},children:s(l.damage_given)})]},e)})]}),t.jsx("div",{style:{flex:1,overflowY:"auto",padding:6,fontSize:"0.72rem"},children:t.jsxs("table",{style:{width:"100%",borderCollapse:"collapse"},children:[t.jsx("thead",{children:t.jsxs("tr",{style:{color:"#777",fontSize:"0.65rem"},children:[t.jsx("th",{style:{textAlign:"left",padding:"1px 4px"}}),t.jsx("th",{style:{textAlign:"right",padding:"1px 3px"},children:"Given M/M"}),t.jsx("th",{style:{textAlign:"right",padding:"1px 3px"},children:"Given Mag"}),t.jsx("th",{style:{width:4}}),t.jsx("th",{style:{textAlign:"right",padding:"1px 3px"},children:"Recv M/M"}),t.jsx("th",{style:{textAlign:"right",padding:"1px 3px"},children:"Recv Mag"}),t.jsx("th",{style:{width:4}}),t.jsx("th",{style:{textAlign:"left",padding:"1px 3px"},children:"Stats"}),t.jsx("th",{style:{textAlign:"right",padding:"1px 3px"}})]})}),t.jsxs("tbody",{children:[w.map((e,l)=>{const v=[["Evades",b.attacks>0?`${s(b.attacks)} (${N}%)`:""],["Resists",M.attacks>0?`${s(M.attacks)} (${W}%)`:""],["A.Surges",n.aeth>0?`${s(n.aeth)}`:""],["C.Surges",n.cloak>0?`${s(n.cloak)}`:""],["",""],["",""],["Av/Mx",z>0?`${s(z)} / ${s(r.maxNormal)}`:""],["Crits",r.crits>0?`${s(r.crits)} (${I}%)`:""]][l]??["",""];return t.jsxs("tr",{children:[t.jsx("td",{style:{padding:"1px 4px",color:"#888"},children:e}),t.jsx("td",{style:{textAlign:"right",padding:"1px 3px",color:"#ccc"},children:s(_(n.offense,"MeleeMissile",e))}),t.jsx("td",{style:{textAlign:"right",padding:"1px 3px",color:"#ccc"},children:s(_(n.offense,"Magic",e))}),t.jsx("td",{}),t.jsx("td",{style:{textAlign:"right",padding:"1px 3px",color:"#ccc"},children:s(_(n.defense,"MeleeMissile",e))}),t.jsx("td",{style:{textAlign:"right",padding:"1px 3px",color:"#ccc"},children:s(_(n.defense,"Magic",e))}),t.jsx("td",{}),t.jsx("td",{style:{padding:"1px 3px",color:"#777",fontWeight:600,fontSize:"0.65rem"},children:v[0]}),t.jsx("td",{style:{textAlign:"right",padding:"1px 3px",color:"#ccc"},children:v[1]})]},e)}),t.jsx("tr",{children:t.jsx("td",{colSpan:9,style:{height:4}})}),t.jsxs("tr",{children:[t.jsx("td",{style:{padding:"1px 4px",color:"#888",fontWeight:600},children:"Total"}),t.jsx("td",{style:{textAlign:"right",padding:"1px 3px",color:"#ccc"},children:s(w.reduce((e,l)=>e+_(n.offense,"MeleeMissile",l),0))}),t.jsx("td",{style:{textAlign:"right",padding:"1px 3px",color:"#ccc"},children:s(w.reduce((e,l)=>e+_(n.offense,"Magic",l),0))}),t.jsx("td",{}),t.jsx("td",{style:{textAlign:"right",padding:"1px 3px",color:"#ccc"},children:s(w.reduce((e,l)=>e+_(n.defense,"MeleeMissile",l),0))}),t.jsx("td",{style:{textAlign:"right",padding:"1px 3px",color:"#ccc"},children:s(w.reduce((e,l)=>e+_(n.defense,"Magic",l),0))}),t.jsx("td",{}),t.jsx("td",{style:{padding:"1px 3px",color:"#777",fontWeight:600,fontSize:"0.65rem"},children:"Total"}),t.jsx("td",{style:{textAlign:"right",padding:"1px 3px",color:"#ccc"},children:s(r.normalDmg+r.critDmg)})]})]})]})})]})]})};export{Y as CombatStatsWindow}; +import{r as A,a as B,j as t,D as L}from"./index-CPIBhBUe.js";import"./react-yfL0ty4i.js";const w=["Typeless","Slash","Pierce","Bludgeon","Fire","Cold","Acid","Electric"];function _(c,a,x){var o,m,f,k;return(((m=(o=c==null?void 0:c[a])==null?void 0:o[x])==null?void 0:m.total_normal_damage)??0)+(((k=(f=c==null?void 0:c[a])==null?void 0:f[x])==null?void 0:k.total_crit_damage)??0)}function G(c){let a={attacks:0,failed:0,crits:0,normalDmg:0,maxNormal:0,critDmg:0,maxCrit:0};if(!c)return a;for(const x of Object.values(c))for(const o of Object.values(x))a.attacks+=o.total_attacks??0,a.failed+=o.failed_attacks??0,a.crits+=o.crits??0,a.normalDmg+=o.total_normal_damage??0,a.maxNormal=Math.max(a.maxNormal,o.max_normal_damage??0),a.critDmg+=o.total_crit_damage??0,a.maxCrit=Math.max(a.maxCrit,o.max_crit_damage??0);return a}function F(c,a){let x={attacks:0,failed:0};const o=c==null?void 0:c[a];if(!o)return x;for(const m of Object.values(o))x.attacks+=m.total_attacks??0,x.failed+=m.failed_attacks??0;return x}const Y=({id:c,charName:a,zIndex:x})=>{const[o,m]=A.useState(null),[f,k]=A.useState("session"),[h,R]=A.useState(null);A.useEffect(()=>{B(`/combat-stats/${encodeURIComponent(a)}`).then(m).catch(()=>{});const e=setInterval(()=>{B(`/combat-stats/${encodeURIComponent(a)}`).then(m).catch(()=>{})},1e4);return()=>clearInterval(e)},[a]);const p=o==null?void 0:o[f],j=(p==null?void 0:p.monsters)??{},S=Object.keys(j).filter(e=>e!=="__cloak_surges__").sort(),n=A.useMemo(()=>{let e={},l={},v=0,$=0;const T=h?[j[h]].filter(Boolean):S.map(u=>j[u]);for(const u of T)if(u){for(const[g,D]of Object.entries(u.offense??{})){e[g]||(e[g]={});for(const[y,E]of Object.entries(D)){e[g][y]||(e[g][y]={total_attacks:0,failed_attacks:0,crits:0,total_normal_damage:0,max_normal_damage:0,total_crit_damage:0,max_crit_damage:0});const i=e[g][y],d=E;i.total_attacks+=d.total_attacks??0,i.failed_attacks+=d.failed_attacks??0,i.crits+=d.crits??0,i.total_normal_damage+=d.total_normal_damage??0,i.max_normal_damage=Math.max(i.max_normal_damage,d.max_normal_damage??0),i.total_crit_damage+=d.total_crit_damage??0,i.max_crit_damage=Math.max(i.max_crit_damage,d.max_crit_damage??0)}}for(const[g,D]of Object.entries(u.defense??{})){l[g]||(l[g]={});for(const[y,E]of Object.entries(D)){l[g][y]||(l[g][y]={total_attacks:0,failed_attacks:0,crits:0,total_normal_damage:0,max_normal_damage:0,total_crit_damage:0,max_crit_damage:0});const i=l[g][y],d=E;i.total_attacks+=d.total_attacks??0,i.failed_attacks+=d.failed_attacks??0,i.total_normal_damage+=d.total_normal_damage??0,i.max_normal_damage=Math.max(i.max_normal_damage,d.max_normal_damage??0),i.total_crit_damage+=d.total_crit_damage??0,i.max_crit_damage=Math.max(i.max_crit_damage,d.max_crit_damage??0)}}v+=u.aetheria_surges??0,$+=u.cloak_surges??0}return j.__cloak_surges__&&!h&&($+=j.__cloak_surges__.cloak_surges??0),{offense:e,defense:l,aeth:v,cloak:$}},[j,S,h]),r=G(n.offense),b=F(n.defense,"MeleeMissile"),M=F(n.defense,"Magic");r.attacks>0&&((r.attacks-r.failed)/r.attacks*100).toFixed(0);const N=b.attacks>0?(b.failed/b.attacks*100).toFixed(0):"0",W=M.attacks>0?(M.failed/M.attacks*100).toFixed(0):"0",C=r.attacks-r.failed,O=C-r.crits,z=O>0?Math.round(r.normalDmg/O):0;r.crits>0&&Math.round(r.critDmg/r.crits);const I=C>0?(r.crits/C*100).toFixed(1):"0",s=e=>e===0?"":e.toLocaleString();return t.jsxs(L,{id:c,title:`Combat: ${a}`,zIndex:x,width:640,height:520,children:[t.jsxs("div",{style:{display:"flex",gap:4,padding:"4px 8px",borderBottom:"1px solid #333",alignItems:"center"},children:[t.jsx("button",{className:`ml-stats-range-btn ${f==="session"?"active":""}`,onClick:()=>k("session"),children:"Session"}),t.jsx("button",{className:`ml-stats-range-btn ${f==="lifetime"?"active":""}`,onClick:()=>k("lifetime"),children:"Lifetime"}),t.jsx("div",{style:{flex:1}}),f==="session"&&t.jsx("button",{style:{fontSize:"0.6rem",padding:"2px 8px",background:"rgba(204,68,68,0.15)",color:"#c66",border:"1px solid rgba(204,68,68,0.3)",borderRadius:3,cursor:"pointer"},onClick:()=>{confirm("Clear current session stats?")&&m(e=>e&&{...e,session:{total_damage_given:0,total_damage_received:0,total_kills:0,total_aetheria_surges:0,total_cloak_surges:0,monsters:{}}})},children:"Clear Session"})]}),t.jsxs("div",{style:{display:"flex",flex:1,overflow:"hidden"},children:[t.jsxs("div",{style:{width:240,borderRight:"1px solid #333",overflowY:"auto",fontSize:"0.72rem"},children:[t.jsxs("div",{style:{display:"flex",padding:"3px 6px",borderBottom:"1px solid #333",color:"#777",fontSize:"0.65rem",fontWeight:600},children:[t.jsx("span",{style:{width:14}}),t.jsx("span",{style:{flex:1},children:"Monster"}),t.jsx("span",{style:{width:40,textAlign:"right"},children:"Kills"}),t.jsx("span",{style:{width:55,textAlign:"right"},children:"Dmg"})]}),t.jsxs("div",{style:{display:"flex",padding:"3px 6px",cursor:"pointer",background:h===null?"#2a3a4a":"",borderBottom:"1px solid #222",color:"#ddd"},onClick:()=>R(null),children:[t.jsx("span",{style:{width:14,color:"#888"},children:h===null?"*":""}),t.jsx("span",{style:{flex:1},children:"All"}),t.jsx("span",{style:{width:40,textAlign:"right"},children:s((p==null?void 0:p.total_kills)??0)}),t.jsx("span",{style:{width:55,textAlign:"right"},children:s((p==null?void 0:p.total_damage_given)??0)})]}),S.map(e=>{const l=j[e];return t.jsxs("div",{style:{display:"flex",padding:"2px 6px",cursor:"pointer",background:h===e?"#2a3a4a":"",borderBottom:"1px solid #1a1a1a",color:"#ccc"},onClick:()=>R(e),children:[t.jsx("span",{style:{width:14,color:"#888"},children:h===e?"*":""}),t.jsx("span",{style:{flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:e}),t.jsx("span",{style:{width:40,textAlign:"right"},children:s(l.kill_count)}),t.jsx("span",{style:{width:55,textAlign:"right"},children:s(l.damage_given)})]},e)})]}),t.jsx("div",{style:{flex:1,overflowY:"auto",padding:6,fontSize:"0.72rem"},children:t.jsxs("table",{style:{width:"100%",borderCollapse:"collapse"},children:[t.jsx("thead",{children:t.jsxs("tr",{style:{color:"#777",fontSize:"0.65rem"},children:[t.jsx("th",{style:{textAlign:"left",padding:"1px 4px"}}),t.jsx("th",{style:{textAlign:"right",padding:"1px 3px"},children:"Given M/M"}),t.jsx("th",{style:{textAlign:"right",padding:"1px 3px"},children:"Given Mag"}),t.jsx("th",{style:{width:4}}),t.jsx("th",{style:{textAlign:"right",padding:"1px 3px"},children:"Recv M/M"}),t.jsx("th",{style:{textAlign:"right",padding:"1px 3px"},children:"Recv Mag"}),t.jsx("th",{style:{width:4}}),t.jsx("th",{style:{textAlign:"left",padding:"1px 3px"},children:"Stats"}),t.jsx("th",{style:{textAlign:"right",padding:"1px 3px"}})]})}),t.jsxs("tbody",{children:[w.map((e,l)=>{const v=[["Evades",b.attacks>0?`${s(b.attacks)} (${N}%)`:""],["Resists",M.attacks>0?`${s(M.attacks)} (${W}%)`:""],["A.Surges",n.aeth>0?`${s(n.aeth)}`:""],["C.Surges",n.cloak>0?`${s(n.cloak)}`:""],["",""],["",""],["Av/Mx",z>0?`${s(z)} / ${s(r.maxNormal)}`:""],["Crits",r.crits>0?`${s(r.crits)} (${I}%)`:""]][l]??["",""];return t.jsxs("tr",{children:[t.jsx("td",{style:{padding:"1px 4px",color:"#888"},children:e}),t.jsx("td",{style:{textAlign:"right",padding:"1px 3px",color:"#ccc"},children:s(_(n.offense,"MeleeMissile",e))}),t.jsx("td",{style:{textAlign:"right",padding:"1px 3px",color:"#ccc"},children:s(_(n.offense,"Magic",e))}),t.jsx("td",{}),t.jsx("td",{style:{textAlign:"right",padding:"1px 3px",color:"#ccc"},children:s(_(n.defense,"MeleeMissile",e))}),t.jsx("td",{style:{textAlign:"right",padding:"1px 3px",color:"#ccc"},children:s(_(n.defense,"Magic",e))}),t.jsx("td",{}),t.jsx("td",{style:{padding:"1px 3px",color:"#777",fontWeight:600,fontSize:"0.65rem"},children:v[0]}),t.jsx("td",{style:{textAlign:"right",padding:"1px 3px",color:"#ccc"},children:v[1]})]},e)}),t.jsx("tr",{children:t.jsx("td",{colSpan:9,style:{height:4}})}),t.jsxs("tr",{children:[t.jsx("td",{style:{padding:"1px 4px",color:"#888",fontWeight:600},children:"Total"}),t.jsx("td",{style:{textAlign:"right",padding:"1px 3px",color:"#ccc"},children:s(w.reduce((e,l)=>e+_(n.offense,"MeleeMissile",l),0))}),t.jsx("td",{style:{textAlign:"right",padding:"1px 3px",color:"#ccc"},children:s(w.reduce((e,l)=>e+_(n.offense,"Magic",l),0))}),t.jsx("td",{}),t.jsx("td",{style:{textAlign:"right",padding:"1px 3px",color:"#ccc"},children:s(w.reduce((e,l)=>e+_(n.defense,"MeleeMissile",l),0))}),t.jsx("td",{style:{textAlign:"right",padding:"1px 3px",color:"#ccc"},children:s(w.reduce((e,l)=>e+_(n.defense,"Magic",l),0))}),t.jsx("td",{}),t.jsx("td",{style:{padding:"1px 3px",color:"#777",fontWeight:600,fontSize:"0.65rem"},children:"Total"}),t.jsx("td",{style:{textAlign:"right",padding:"1px 3px",color:"#ccc"},children:s(r.normalDmg+r.critDmg)})]})]})]})})]})]})};export{Y as CombatStatsWindow}; diff --git a/static/assets/InventoryWindow-C3GJw7NT.js b/static/assets/InventoryWindow-OJaggw-L.js similarity index 99% rename from static/assets/InventoryWindow-C3GJw7NT.js rename to static/assets/InventoryWindow-OJaggw-L.js index d38163eb..8092c3e0 100644 --- a/static/assets/InventoryWindow-C3GJw7NT.js +++ b/static/assets/InventoryWindow-OJaggw-L.js @@ -1 +1 @@ -import{r as _,a as T,j as n,D as Q}from"./index-D5aV9Wxd.js";import"./react-yfL0ty4i.js";function X(e){var s,d;if(!e)return e;const o=c=>c!=null&&c!==-1&&c!==-1?c:void 0,r=e.IntValues||{};return{item_id:e.item_id??e.Id??0,name:e.name??e.Name??((s=e.StringValues)==null?void 0:s["1"])??"Unknown",icon:e.icon??e.Icon??0,object_class:e.object_class??e.ObjectClass??0,current_wielded_location:e.current_wielded_location??o(e.CurrentWieldedLocation)??o(Number(r[10]))??0,container_id:e.container_id??e.ContainerId??0,items_capacity:e.items_capacity??o(e.ItemsCapacity)??o(Number(r[6]))??((d=e.enhanced_properties)==null?void 0:d.ItemSlots_Decal)??void 0,value:e.value??o(e.Value)??o(Number(r[19]))??0,burden:e.burden??o(e.Burden)??o(Number(r[5]))??0,armor_level:e.armor_level??o(e.ArmorLevel),max_damage:e.max_damage??o(e.MaxDamage),material:e.material??e.material_name??e.Material??void 0,item_set:e.item_set??e.ItemSet??void 0,imbue:e.imbue??e.Imbue??void 0,tinks:e.tinks??o(e.Tinks),workmanship:e.workmanship??o(e.Workmanship),equip_skill:e.equip_skill??e.equip_skill_name??e.EquipSkill??void 0,wield_level:e.wield_level??o(e.WieldLevel),skill_level:e.skill_level??o(e.SkillLevel),lore_requirement:e.lore_requirement??o(e.LoreRequirement),attack_bonus:e.attack_bonus??o(e.AttackBonus),melee_defense_bonus:e.melee_defense_bonus??o(e.MeleeDefenseBonus),magic_defense_bonus:e.magic_defense_bonus??o(e.MagicDBonus),damage_bonus:e.damage_bonus??o(e.DamageBonus),damage_rating:e.damage_rating??o(e.DamRating),crit_rating:e.crit_rating??o(e.CritRating),heal_boost_rating:e.heal_boost_rating??o(e.HealBoostRating),current_mana:e.current_mana??o(Number(r[218103815]))??void 0,max_mana:e.max_mana??o(Number(r[218103814]))??void 0,spellcraft:e.spellcraft??void 0,damage_range:e.damage_range??void 0,damage_type:e.damage_type??void 0,speed_text:e.speed_text??void 0,mana_display:e.mana_display??void 0,spells:e.spells??void 0,icon_overlay_id:e.icon_overlay_id??o(Number(r[218103849]))??void 0,icon_underlay_id:e.icon_underlay_id??o(Number(r[218103850]))??void 0,_raw:e}}function D(e){return!e||e<=0?"06000133":(e+100663296).toString(16).toUpperCase().padStart(8,"0")}const M={32768:{name:"Neck",row:1,col:1},1:{name:"Head",row:1,col:3},268435456:{name:"Sigil",row:1,col:5},536870912:{name:"Sigil",row:1,col:6},1073741824:{name:"Sigil",row:1,col:7},67108864:{name:"Trinket",row:2,col:1},2048:{name:"U.Arm",row:2,col:2},512:{name:"Chest",row:2,col:3},134217728:{name:"Cloak",row:2,col:7},65536:{name:"Brace L",row:3,col:1},4096:{name:"L.Arm",row:3,col:2},1024:{name:"Abdomen",row:3,col:3},8192:{name:"U.Leg",row:3,col:4},131072:{name:"Brace R",row:3,col:5},2:{name:"Shirt",row:3,col:7},262144:{name:"Ring L",row:4,col:1},32:{name:"Hands",row:4,col:2},16384:{name:"L.Leg",row:4,col:4},524288:{name:"Ring R",row:4,col:5},4:{name:"Pants",row:4,col:7},256:{name:"Feet",row:5,col:4},2097152:{name:"Shield",row:6,col:1},1048576:{name:"Melee",row:6,col:3},4194304:{name:"Missile",row:6,col:3},16777216:{name:"Held",row:6,col:3},33554432:{name:"2H",row:6,col:3},8388608:{name:"Ammo",row:6,col:7}},I={},ne=[32768,67108864,65536,131072,262144,524288],oe=[1,512,2048,1024,4096,8192,16384,32,256],te=[2,4,134217728,268435456,536870912,1073741824],ie=[2097152,1048576,4194304,16777216,33554432,8388608];(()=>{const e=new Set;Object.entries(M).forEach(([o,r])=>{const s=`${r.row}-${r.col}`,d=parseInt(o);e.has(s)||(e.add(s),ne.includes(d)?I[s]="#3a2555":oe.includes(d)?I[s]="#1e2e55":te.includes(d)?I[s]="#1e3e3e":ie.includes(d)?I[s]="#142040":I[s]="#2a2a2a")})})();const $="#af7a30";function W({item:e,size:o=36}){const r={position:"absolute",top:0,left:0,width:o,height:o,border:"none",background:"transparent",imageRendering:"pixelated"},s=e.icon_underlay_id&&e.icon_underlay_id>100?`/icons/${D(e.icon_underlay_id)}.png`:null,d=e.icon_overlay_id&&e.icon_overlay_id>100?`/icons/${D(e.icon_overlay_id)}.png`:null;return n.jsxs("div",{style:{width:o,height:o,position:"relative"},children:[s&&n.jsx("img",{src:s,alt:"",style:{...r,zIndex:1},onError:c=>{c.target.style.display="none"}}),n.jsx("img",{src:`/icons/${D(e.icon)}.png`,alt:e.name,style:{...r,zIndex:2},onError:c=>{c.target.src="/icons/06000133.png"}}),d&&n.jsx("img",{src:d,alt:"",style:{...r,zIndex:3},onError:c=>{c.target.style.display="none"}})]})}function le({item:e,x:o,y:r}){var j,L;const s=g=>g!=null&&g!==-1&&g!==-1,d=g=>g.toLocaleString(),c=g=>`${((g-1)*100).toFixed(1)}%`;return n.jsxs("div",{style:{position:"fixed",left:o+14,top:r+14,background:"rgba(0,0,0,0.96)",border:"1px solid #555",borderRadius:4,padding:"8px 12px",zIndex:99999,minWidth:200,maxWidth:340,fontSize:13,color:"#ddd",pointerEvents:"none",lineHeight:1.6,fontFamily:'-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif'},children:[n.jsx("div",{style:{color:"#ffcc00",fontWeight:"bold",fontSize:14,marginBottom:4},children:e.name}),n.jsxs("div",{style:{color:"#aaa"},children:["Value: ",d(e.value)," · Burden: ",e.burden]}),e.workmanship&&n.jsxs("div",{style:{color:"#aaa"},children:["Workmanship: ",e.workmanship]}),e.material&&n.jsxs("div",{style:{color:"#88ff88"},children:["Material: ",e.material]}),s(e.armor_level)&&n.jsxs("div",{style:{color:"#88ff88"},children:["Armor Level: ",e.armor_level]}),s(e.max_damage)&&n.jsxs("div",{style:{color:"#88ff88"},children:["Max Damage: ",e.max_damage]}),e.damage_range&&n.jsxs("div",{style:{color:"#88ff88"},children:["Damage: ",e.damage_range,e.damage_type?`, ${e.damage_type}`:""]}),s(e.attack_bonus)&&e.attack_bonus!==1&&n.jsxs("div",{style:{color:"#88ff88"},children:["Attack: +",c(e.attack_bonus)]}),s(e.melee_defense_bonus)&&e.melee_defense_bonus!==1&&n.jsxs("div",{style:{color:"#88ff88"},children:["Melee Def: +",c(e.melee_defense_bonus)]}),s(e.magic_defense_bonus)&&e.magic_defense_bonus!==1&&n.jsxs("div",{style:{color:"#88ff88"},children:["Magic Def: +",c(e.magic_defense_bonus)]}),e.equip_skill&&n.jsxs("div",{style:{color:"#ddd"},children:["Skill: ",e.equip_skill]}),s(e.wield_level)&&n.jsxs("div",{style:{color:"#ffaa00"},children:["Wield Level: ",e.wield_level]}),s(e.lore_requirement)&&n.jsxs("div",{style:{color:"#ffaa00"},children:["Lore: ",e.lore_requirement]}),e.imbue&&n.jsxs("div",{style:{color:"#88ff88"},children:["Imbue: ",e.imbue]}),e.item_set&&n.jsxs("div",{style:{color:"#88ff88"},children:["Set: ",e.item_set]}),s(e.tinks)&&n.jsxs("div",{style:{color:"#88ff88"},children:["Tinks: ",e.tinks]}),s(e.damage_rating)&&n.jsxs("div",{children:["Damage Rating: ",e.damage_rating]}),s(e.crit_rating)&&n.jsxs("div",{children:["Crit Rating: ",e.crit_rating]}),s(e.heal_boost_rating)&&n.jsxs("div",{children:["Heal Boost: ",e.heal_boost_rating]}),e.spellcraft&&n.jsxs("div",{style:{color:"#dda0dd"},children:["Spellcraft: ",e.spellcraft]}),s(e.current_mana)&&s(e.max_mana)&&n.jsxs("div",{style:{color:"#98d7ff"},children:["Mana: ",e.current_mana," / ",e.max_mana]}),((L=(j=e.spells)==null?void 0:j.spells)==null?void 0:L.length)>0&&n.jsxs("div",{style:{color:"#4a90e2",marginTop:4,fontSize:12},children:["Spells: ",e.spells.spells.map(g=>g.name).join(", ")]})]})}function G({iconSrc:e,isActive:o,fillPct:r,label:s,onClick:d}){const c=r>90?"#b7432c":r>70?"#d8a431":"#00ff00";return n.jsxs("div",{onClick:d,title:s,style:{display:"flex",alignItems:"flex-start",gap:2,cursor:"pointer",flexShrink:0,marginTop:3,position:"relative"},children:[o&&n.jsx("span",{style:{position:"absolute",left:-11,top:8,color:$,fontSize:10},children:"▶"}),n.jsx("div",{style:{width:30,height:30,border:o?"1px solid #00ff00":"1px solid #333",boxShadow:o?"0 0 4px #00ff00":"none",background:"#000",display:"flex",alignItems:"center",justifyContent:"center"},children:n.jsx("img",{src:e,alt:"",style:{width:26,height:26,objectFit:"contain",imageRendering:"pixelated"},onError:j=>{j.target.src="/icons/06001080.png"}})}),n.jsx("div",{style:{width:7,height:30,background:"#222",border:"1px solid #666",position:"relative",overflow:"hidden",borderRadius:2},title:`${Math.round(r)}% full`,children:n.jsx("div",{style:{position:"absolute",bottom:0,left:0,right:0,height:`${r}%`,background:c,minHeight:r>0?2:0}})})]})}const ce=({id:e,charName:o,zIndex:r,inventoryVersion:s,equipmentCantrips:d})=>{var V,q,Y;const[c,j]=_.useState([]),[L,g]=_.useState(!0),[k,H]=_.useState(null),[B,U]=_.useState(null),[f,J]=_.useState(null),C=_.useRef(0),O=_.useRef(!1);_.useEffect(()=>{g(!0),Promise.all([T(`/inventory/${encodeURIComponent(o)}?limit=1000`).catch(()=>({items:[]})),T(`/character-stats/${encodeURIComponent(o)}`).catch(()=>null)]).then(([t,i])=>{j((t.items??[]).map(X)),J(i),O.current=!0}).finally(()=>g(!1))},[o]),_.useEffect(()=>{if(!(!O.current||!s))return clearTimeout(C.current),C.current=window.setTimeout(()=>{T(`/inventory/${encodeURIComponent(o)}?limit=1000&_t=${Date.now()}`).then(t=>j((t.items??[]).map(X))).catch(()=>{})},2e3),()=>clearTimeout(C.current)},[o,s]);const y=_.useCallback((t,i)=>{U(t&&i?{item:t,x:i.clientX,y:i.clientY}:null)},[]),Z=_.useMemo(()=>{const t=new Set,i=[];return Object.entries(M).forEach(([u,m])=>{const a=`${m.row}-${m.col}`;t.has(a)||(t.add(a),i.push({key:a,...m,mask:parseInt(u)}))}),i},[]),{equippedMap:A,containers:z,packItems:w}=_.useMemo(()=>{const t=new Map,i=[],u=new Set,m=new Map;c.forEach(l=>{l.object_class===10&&(i.push(l),u.add(l.item_id))}),i.sort((l,h)=>(l.item_id>>>0)-(h.item_id>>>0));let a=null;return c.forEach(l=>{l.current_wielded_location>0&&l.container_id&&!u.has(l.container_id)&&(a=l.container_id)}),c.forEach(l=>{if(u.has(l.item_id))return;const h=l.current_wielded_location;if(h>0)if(l.object_class===2)Object.entries(M).forEach(([b,x])=>{if((h&parseInt(b))===parseInt(b)){const v=`${x.row}-${x.col}`;t.has(v)||t.set(v,l)}});else{let b=!1;if(M[h]){const x=M[h],v=`${x.row}-${x.col}`;t.has(v)||(t.set(v,l),b=!0)}if(!b){for(const[x,v]of Object.entries(M))if((h&parseInt(x))===parseInt(x)){const K=`${v.row}-${v.col}`;if(!t.has(K)){t.set(K,l),b=!0;break}}}}else{let p=l.container_id||0;a&&p===a&&(p=0),m.has(p)||m.set(p,[]),m.get(p).push(l)}}),{equippedMap:t,containers:i,packItems:m}},[c]);let S=w.get(0)??[],F=0;if(S.length===0){let t=0;for(const[i,u]of w.entries())!z.some(m=>m.item_id===i)&&u.length>t&&(t=u.length,F=i);S=w.get(F)??[]}const P=k!==null?w.get(k)??[]:S,N=(f==null?void 0:f.burden_units)??((V=f==null?void 0:f.stats_data)==null?void 0:V.burden_units)??0,R=(f==null?void 0:f.encumbrance_capacity)??((q=f==null?void 0:f.stats_data)==null?void 0:q.encumbrance_capacity)??0,E=R>0?Math.min(200,N/R*100):0,ee=E>150?"#b7432c":E>100?"#d8a431":"#2e8b57";return L?n.jsx(Q,{id:e,title:`Inventory: ${o}`,zIndex:r,width:572,height:720,children:n.jsx("div",{style:{padding:20,color:"#666",fontStyle:"italic"},children:"Loading inventory..."})}):n.jsxs(Q,{id:e,title:`Inventory: ${o}`,zIndex:r,width:572,height:720,children:[n.jsxs("div",{style:{display:"flex",flex:1,overflow:"hidden",background:"rgba(14,14,14,0.96)",fontFamily:'-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif',fontSize:13},children:[n.jsxs("div",{style:{width:316,display:"flex",flexDirection:"column",overflow:"hidden"},children:[n.jsx("div",{style:{position:"relative",height:270,minHeight:270,background:"#0a0a0a",borderBottom:`1px solid ${$}`},children:Z.map(t=>{const i=A.get(t.key),u=I[t.key]??"#2a2a2a";return n.jsx("div",{style:{position:"absolute",left:(t.col-1)*44+4,top:(t.row-1)*44+4,width:36,height:36,background:i?"#5a5a62":u,border:i?"2px solid #00ffff":"2px outset #6a6a72",boxShadow:i?"0 0 5px #00ffff, inset 0 0 5px rgba(0,255,255,0.2)":"none",display:"flex",alignItems:"center",justifyContent:"center",cursor:i?"pointer":"default"},onMouseEnter:m=>i&&y(i,m),onMouseMove:m=>i&&y(i,m),onMouseLeave:()=>y(null),children:i?n.jsx(W,{item:i,size:32}):n.jsx("img",{src:"/icons/06000133.png",alt:"",style:{width:28,height:28,opacity:.15,filter:"grayscale(100%)",imageRendering:"pixelated"}})},t.key)})}),n.jsxs("div",{style:{padding:"3px 6px",fontSize:11,color:"#ccc",background:"#111",borderBottom:`1px solid ${$}`},children:["Contents of ",k!==null?((Y=z.find(t=>t.item_id===k))==null?void 0:Y.name)??"Pack":"Backpack"]}),n.jsxs("div",{style:{flex:1,overflowY:"auto",display:"grid",gridTemplateColumns:"repeat(6, 36px)",gridAutoRows:36,gap:2,padding:4,alignContent:"start"},children:[P.map((t,i)=>n.jsx("div",{style:{width:36,height:36,background:"linear-gradient(135deg, #3d007a 0%, #1a0033 100%)",border:"1px solid #4a148c",display:"flex",alignItems:"center",justifyContent:"center",cursor:"pointer"},onMouseEnter:u=>y(t,u),onMouseMove:u=>y(t,u),onMouseLeave:()=>y(null),children:n.jsx(W,{item:t,size:32})},t.item_id??i)),Array.from({length:Math.max(0,24-P.length)}).map((t,i)=>n.jsx("div",{style:{width:36,height:36,background:"#0a0a0a",border:"1px solid #1a1a1a"}},`e${i}`))]})]}),n.jsxs("div",{style:{width:42,display:"flex",flexDirection:"column",alignItems:"center",padding:"4px 2px",borderLeft:`1px solid ${$}`,borderRight:`1px solid ${$}`},children:[n.jsx("div",{style:{textAlign:"center",fontSize:8,color:"#ccc",marginBottom:2},children:R>0?`${Math.floor(E)}%`:"Burden"}),n.jsx("div",{style:{width:14,height:40,background:"#111",border:"1px solid #555",position:"relative",overflow:"hidden",marginBottom:6,flexShrink:0},title:R>0?`${N.toLocaleString()} / ${R.toLocaleString()}`:`Burden: ${c.reduce((t,i)=>t+(i.burden??0),0).toLocaleString()}`,children:n.jsx("div",{style:{position:"absolute",bottom:0,left:0,right:0,height:`${E/2}%`,background:ee,transition:"height 0.3s"}})}),n.jsx(G,{iconSrc:"/icons/0600127E.png",isActive:k===null,fillPct:S.length>0?Math.min(100,S.length/102*100):0,label:`Backpack (${S.length}/102)`,onClick:()=>H(null)}),z.map(t=>{const i=t.item_id,u=c.filter(l=>l.container_id===i&&l.item_id!==i).length,m=t.items_capacity||24,a=m>0?Math.min(100,u/m*100):0;return n.jsx(G,{iconSrc:`/icons/${D(t.icon)}.png`,isActive:k===i,fillPct:a,label:`${t.name} (${u}/${m})`,onClick:()=>H(i)},i)})]}),n.jsxs("div",{style:{flex:1,display:"flex",flexDirection:"column",overflow:"hidden",minWidth:160},children:[n.jsx("div",{style:{padding:"4px 8px",fontSize:"0.72rem",fontWeight:600,color:"#aaa",background:"#111",borderBottom:`1px solid ${$}`},children:"Mana"}),n.jsxs("div",{style:{flex:1,overflowY:"auto",padding:"2px 0"},children:[(()=>{const t=(d==null?void 0:d.items)??[],i=new Map(t.map(a=>[a.item_id,a])),u=d!=null&&d.timestamp?new Date(d.timestamp).getTime():0,m=u>0?Math.max(0,(Date.now()-u)/1e3):0;return Array.from(A.values()).map(a=>{const l=i.get(a.item_id),h=(l==null?void 0:l.current_mana)??a.current_mana??0,p=(l==null?void 0:l.max_mana)??a.max_mana??0,b=(l==null?void 0:l.mana_time_remaining_seconds)??null,x=b!=null?Math.max(0,b-m):null,v=(l==null?void 0:l.state)??(h>0?"active":"not_active");return{...a,current_mana:h,max_mana:p,liveRemaining:x,manaState:v}}).filter(a=>a.current_mana>0||a.max_mana>0).sort((a,l)=>(a.liveRemaining??999999)-(l.liveRemaining??999999)).map((a,l)=>{const h=a.manaState==="active"?"#4c4":a.manaState==="not_active"?"#c44":"#da8";return n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:4,padding:"2px 4px",borderBottom:"1px solid #1a1a1a",cursor:"pointer"},onMouseEnter:p=>y(a,p),onMouseMove:p=>y(a,p),onMouseLeave:()=>y(null),children:[n.jsx("div",{style:{width:20,height:20,flexShrink:0},children:n.jsx(W,{item:a,size:20})}),n.jsx("div",{style:{width:8,height:8,borderRadius:"50%",background:h,flexShrink:0}}),n.jsx("div",{style:{flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",fontSize:"0.68rem",color:"#ccc"},children:a.name}),n.jsxs("div",{style:{fontSize:"0.65rem",color:"#88bbff",whiteSpace:"nowrap",fontVariantNumeric:"tabular-nums"},children:[a.current_mana,"/",a.max_mana]}),n.jsx("div",{style:{fontSize:"0.63rem",color:"#9c9",whiteSpace:"nowrap",fontVariantNumeric:"tabular-nums",minWidth:42,textAlign:"right"},children:a.liveRemaining!=null?se(a.liveRemaining):""})]},l)})})(),Array.from(A.values()).filter(t=>t.current_mana>0||t.max_mana>0).length===0&&n.jsx("div",{style:{padding:12,color:"#555",textAlign:"center",fontSize:"0.7rem"},children:"No mana items equipped"})]})]})]}),B&&n.jsx(le,{item:B.item,x:B.x,y:B.y})]})};function se(e){if(e<=0)return"0h00m";const o=Math.floor(e),r=Math.floor(o/3600),s=Math.floor(o%3600/60);return`${r}h${String(s).padStart(2,"0")}m`}export{ce as InventoryWindow}; +import{r as _,a as T,j as n,D as Q}from"./index-CPIBhBUe.js";import"./react-yfL0ty4i.js";function X(e){var s,d;if(!e)return e;const o=c=>c!=null&&c!==-1&&c!==-1?c:void 0,r=e.IntValues||{};return{item_id:e.item_id??e.Id??0,name:e.name??e.Name??((s=e.StringValues)==null?void 0:s["1"])??"Unknown",icon:e.icon??e.Icon??0,object_class:e.object_class??e.ObjectClass??0,current_wielded_location:e.current_wielded_location??o(e.CurrentWieldedLocation)??o(Number(r[10]))??0,container_id:e.container_id??e.ContainerId??0,items_capacity:e.items_capacity??o(e.ItemsCapacity)??o(Number(r[6]))??((d=e.enhanced_properties)==null?void 0:d.ItemSlots_Decal)??void 0,value:e.value??o(e.Value)??o(Number(r[19]))??0,burden:e.burden??o(e.Burden)??o(Number(r[5]))??0,armor_level:e.armor_level??o(e.ArmorLevel),max_damage:e.max_damage??o(e.MaxDamage),material:e.material??e.material_name??e.Material??void 0,item_set:e.item_set??e.ItemSet??void 0,imbue:e.imbue??e.Imbue??void 0,tinks:e.tinks??o(e.Tinks),workmanship:e.workmanship??o(e.Workmanship),equip_skill:e.equip_skill??e.equip_skill_name??e.EquipSkill??void 0,wield_level:e.wield_level??o(e.WieldLevel),skill_level:e.skill_level??o(e.SkillLevel),lore_requirement:e.lore_requirement??o(e.LoreRequirement),attack_bonus:e.attack_bonus??o(e.AttackBonus),melee_defense_bonus:e.melee_defense_bonus??o(e.MeleeDefenseBonus),magic_defense_bonus:e.magic_defense_bonus??o(e.MagicDBonus),damage_bonus:e.damage_bonus??o(e.DamageBonus),damage_rating:e.damage_rating??o(e.DamRating),crit_rating:e.crit_rating??o(e.CritRating),heal_boost_rating:e.heal_boost_rating??o(e.HealBoostRating),current_mana:e.current_mana??o(Number(r[218103815]))??void 0,max_mana:e.max_mana??o(Number(r[218103814]))??void 0,spellcraft:e.spellcraft??void 0,damage_range:e.damage_range??void 0,damage_type:e.damage_type??void 0,speed_text:e.speed_text??void 0,mana_display:e.mana_display??void 0,spells:e.spells??void 0,icon_overlay_id:e.icon_overlay_id??o(Number(r[218103849]))??void 0,icon_underlay_id:e.icon_underlay_id??o(Number(r[218103850]))??void 0,_raw:e}}function D(e){return!e||e<=0?"06000133":(e+100663296).toString(16).toUpperCase().padStart(8,"0")}const M={32768:{name:"Neck",row:1,col:1},1:{name:"Head",row:1,col:3},268435456:{name:"Sigil",row:1,col:5},536870912:{name:"Sigil",row:1,col:6},1073741824:{name:"Sigil",row:1,col:7},67108864:{name:"Trinket",row:2,col:1},2048:{name:"U.Arm",row:2,col:2},512:{name:"Chest",row:2,col:3},134217728:{name:"Cloak",row:2,col:7},65536:{name:"Brace L",row:3,col:1},4096:{name:"L.Arm",row:3,col:2},1024:{name:"Abdomen",row:3,col:3},8192:{name:"U.Leg",row:3,col:4},131072:{name:"Brace R",row:3,col:5},2:{name:"Shirt",row:3,col:7},262144:{name:"Ring L",row:4,col:1},32:{name:"Hands",row:4,col:2},16384:{name:"L.Leg",row:4,col:4},524288:{name:"Ring R",row:4,col:5},4:{name:"Pants",row:4,col:7},256:{name:"Feet",row:5,col:4},2097152:{name:"Shield",row:6,col:1},1048576:{name:"Melee",row:6,col:3},4194304:{name:"Missile",row:6,col:3},16777216:{name:"Held",row:6,col:3},33554432:{name:"2H",row:6,col:3},8388608:{name:"Ammo",row:6,col:7}},I={},ne=[32768,67108864,65536,131072,262144,524288],oe=[1,512,2048,1024,4096,8192,16384,32,256],te=[2,4,134217728,268435456,536870912,1073741824],ie=[2097152,1048576,4194304,16777216,33554432,8388608];(()=>{const e=new Set;Object.entries(M).forEach(([o,r])=>{const s=`${r.row}-${r.col}`,d=parseInt(o);e.has(s)||(e.add(s),ne.includes(d)?I[s]="#3a2555":oe.includes(d)?I[s]="#1e2e55":te.includes(d)?I[s]="#1e3e3e":ie.includes(d)?I[s]="#142040":I[s]="#2a2a2a")})})();const $="#af7a30";function W({item:e,size:o=36}){const r={position:"absolute",top:0,left:0,width:o,height:o,border:"none",background:"transparent",imageRendering:"pixelated"},s=e.icon_underlay_id&&e.icon_underlay_id>100?`/icons/${D(e.icon_underlay_id)}.png`:null,d=e.icon_overlay_id&&e.icon_overlay_id>100?`/icons/${D(e.icon_overlay_id)}.png`:null;return n.jsxs("div",{style:{width:o,height:o,position:"relative"},children:[s&&n.jsx("img",{src:s,alt:"",style:{...r,zIndex:1},onError:c=>{c.target.style.display="none"}}),n.jsx("img",{src:`/icons/${D(e.icon)}.png`,alt:e.name,style:{...r,zIndex:2},onError:c=>{c.target.src="/icons/06000133.png"}}),d&&n.jsx("img",{src:d,alt:"",style:{...r,zIndex:3},onError:c=>{c.target.style.display="none"}})]})}function le({item:e,x:o,y:r}){var j,L;const s=g=>g!=null&&g!==-1&&g!==-1,d=g=>g.toLocaleString(),c=g=>`${((g-1)*100).toFixed(1)}%`;return n.jsxs("div",{style:{position:"fixed",left:o+14,top:r+14,background:"rgba(0,0,0,0.96)",border:"1px solid #555",borderRadius:4,padding:"8px 12px",zIndex:99999,minWidth:200,maxWidth:340,fontSize:13,color:"#ddd",pointerEvents:"none",lineHeight:1.6,fontFamily:'-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif'},children:[n.jsx("div",{style:{color:"#ffcc00",fontWeight:"bold",fontSize:14,marginBottom:4},children:e.name}),n.jsxs("div",{style:{color:"#aaa"},children:["Value: ",d(e.value)," · Burden: ",e.burden]}),e.workmanship&&n.jsxs("div",{style:{color:"#aaa"},children:["Workmanship: ",e.workmanship]}),e.material&&n.jsxs("div",{style:{color:"#88ff88"},children:["Material: ",e.material]}),s(e.armor_level)&&n.jsxs("div",{style:{color:"#88ff88"},children:["Armor Level: ",e.armor_level]}),s(e.max_damage)&&n.jsxs("div",{style:{color:"#88ff88"},children:["Max Damage: ",e.max_damage]}),e.damage_range&&n.jsxs("div",{style:{color:"#88ff88"},children:["Damage: ",e.damage_range,e.damage_type?`, ${e.damage_type}`:""]}),s(e.attack_bonus)&&e.attack_bonus!==1&&n.jsxs("div",{style:{color:"#88ff88"},children:["Attack: +",c(e.attack_bonus)]}),s(e.melee_defense_bonus)&&e.melee_defense_bonus!==1&&n.jsxs("div",{style:{color:"#88ff88"},children:["Melee Def: +",c(e.melee_defense_bonus)]}),s(e.magic_defense_bonus)&&e.magic_defense_bonus!==1&&n.jsxs("div",{style:{color:"#88ff88"},children:["Magic Def: +",c(e.magic_defense_bonus)]}),e.equip_skill&&n.jsxs("div",{style:{color:"#ddd"},children:["Skill: ",e.equip_skill]}),s(e.wield_level)&&n.jsxs("div",{style:{color:"#ffaa00"},children:["Wield Level: ",e.wield_level]}),s(e.lore_requirement)&&n.jsxs("div",{style:{color:"#ffaa00"},children:["Lore: ",e.lore_requirement]}),e.imbue&&n.jsxs("div",{style:{color:"#88ff88"},children:["Imbue: ",e.imbue]}),e.item_set&&n.jsxs("div",{style:{color:"#88ff88"},children:["Set: ",e.item_set]}),s(e.tinks)&&n.jsxs("div",{style:{color:"#88ff88"},children:["Tinks: ",e.tinks]}),s(e.damage_rating)&&n.jsxs("div",{children:["Damage Rating: ",e.damage_rating]}),s(e.crit_rating)&&n.jsxs("div",{children:["Crit Rating: ",e.crit_rating]}),s(e.heal_boost_rating)&&n.jsxs("div",{children:["Heal Boost: ",e.heal_boost_rating]}),e.spellcraft&&n.jsxs("div",{style:{color:"#dda0dd"},children:["Spellcraft: ",e.spellcraft]}),s(e.current_mana)&&s(e.max_mana)&&n.jsxs("div",{style:{color:"#98d7ff"},children:["Mana: ",e.current_mana," / ",e.max_mana]}),((L=(j=e.spells)==null?void 0:j.spells)==null?void 0:L.length)>0&&n.jsxs("div",{style:{color:"#4a90e2",marginTop:4,fontSize:12},children:["Spells: ",e.spells.spells.map(g=>g.name).join(", ")]})]})}function G({iconSrc:e,isActive:o,fillPct:r,label:s,onClick:d}){const c=r>90?"#b7432c":r>70?"#d8a431":"#00ff00";return n.jsxs("div",{onClick:d,title:s,style:{display:"flex",alignItems:"flex-start",gap:2,cursor:"pointer",flexShrink:0,marginTop:3,position:"relative"},children:[o&&n.jsx("span",{style:{position:"absolute",left:-11,top:8,color:$,fontSize:10},children:"▶"}),n.jsx("div",{style:{width:30,height:30,border:o?"1px solid #00ff00":"1px solid #333",boxShadow:o?"0 0 4px #00ff00":"none",background:"#000",display:"flex",alignItems:"center",justifyContent:"center"},children:n.jsx("img",{src:e,alt:"",style:{width:26,height:26,objectFit:"contain",imageRendering:"pixelated"},onError:j=>{j.target.src="/icons/06001080.png"}})}),n.jsx("div",{style:{width:7,height:30,background:"#222",border:"1px solid #666",position:"relative",overflow:"hidden",borderRadius:2},title:`${Math.round(r)}% full`,children:n.jsx("div",{style:{position:"absolute",bottom:0,left:0,right:0,height:`${r}%`,background:c,minHeight:r>0?2:0}})})]})}const ce=({id:e,charName:o,zIndex:r,inventoryVersion:s,equipmentCantrips:d})=>{var V,q,Y;const[c,j]=_.useState([]),[L,g]=_.useState(!0),[k,H]=_.useState(null),[B,U]=_.useState(null),[f,J]=_.useState(null),C=_.useRef(0),O=_.useRef(!1);_.useEffect(()=>{g(!0),Promise.all([T(`/inventory/${encodeURIComponent(o)}?limit=1000`).catch(()=>({items:[]})),T(`/character-stats/${encodeURIComponent(o)}`).catch(()=>null)]).then(([t,i])=>{j((t.items??[]).map(X)),J(i),O.current=!0}).finally(()=>g(!1))},[o]),_.useEffect(()=>{if(!(!O.current||!s))return clearTimeout(C.current),C.current=window.setTimeout(()=>{T(`/inventory/${encodeURIComponent(o)}?limit=1000&_t=${Date.now()}`).then(t=>j((t.items??[]).map(X))).catch(()=>{})},2e3),()=>clearTimeout(C.current)},[o,s]);const y=_.useCallback((t,i)=>{U(t&&i?{item:t,x:i.clientX,y:i.clientY}:null)},[]),Z=_.useMemo(()=>{const t=new Set,i=[];return Object.entries(M).forEach(([u,m])=>{const a=`${m.row}-${m.col}`;t.has(a)||(t.add(a),i.push({key:a,...m,mask:parseInt(u)}))}),i},[]),{equippedMap:A,containers:z,packItems:w}=_.useMemo(()=>{const t=new Map,i=[],u=new Set,m=new Map;c.forEach(l=>{l.object_class===10&&(i.push(l),u.add(l.item_id))}),i.sort((l,h)=>(l.item_id>>>0)-(h.item_id>>>0));let a=null;return c.forEach(l=>{l.current_wielded_location>0&&l.container_id&&!u.has(l.container_id)&&(a=l.container_id)}),c.forEach(l=>{if(u.has(l.item_id))return;const h=l.current_wielded_location;if(h>0)if(l.object_class===2)Object.entries(M).forEach(([b,x])=>{if((h&parseInt(b))===parseInt(b)){const v=`${x.row}-${x.col}`;t.has(v)||t.set(v,l)}});else{let b=!1;if(M[h]){const x=M[h],v=`${x.row}-${x.col}`;t.has(v)||(t.set(v,l),b=!0)}if(!b){for(const[x,v]of Object.entries(M))if((h&parseInt(x))===parseInt(x)){const K=`${v.row}-${v.col}`;if(!t.has(K)){t.set(K,l),b=!0;break}}}}else{let p=l.container_id||0;a&&p===a&&(p=0),m.has(p)||m.set(p,[]),m.get(p).push(l)}}),{equippedMap:t,containers:i,packItems:m}},[c]);let S=w.get(0)??[],F=0;if(S.length===0){let t=0;for(const[i,u]of w.entries())!z.some(m=>m.item_id===i)&&u.length>t&&(t=u.length,F=i);S=w.get(F)??[]}const P=k!==null?w.get(k)??[]:S,N=(f==null?void 0:f.burden_units)??((V=f==null?void 0:f.stats_data)==null?void 0:V.burden_units)??0,R=(f==null?void 0:f.encumbrance_capacity)??((q=f==null?void 0:f.stats_data)==null?void 0:q.encumbrance_capacity)??0,E=R>0?Math.min(200,N/R*100):0,ee=E>150?"#b7432c":E>100?"#d8a431":"#2e8b57";return L?n.jsx(Q,{id:e,title:`Inventory: ${o}`,zIndex:r,width:572,height:720,children:n.jsx("div",{style:{padding:20,color:"#666",fontStyle:"italic"},children:"Loading inventory..."})}):n.jsxs(Q,{id:e,title:`Inventory: ${o}`,zIndex:r,width:572,height:720,children:[n.jsxs("div",{style:{display:"flex",flex:1,overflow:"hidden",background:"rgba(14,14,14,0.96)",fontFamily:'-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif',fontSize:13},children:[n.jsxs("div",{style:{width:316,display:"flex",flexDirection:"column",overflow:"hidden"},children:[n.jsx("div",{style:{position:"relative",height:270,minHeight:270,background:"#0a0a0a",borderBottom:`1px solid ${$}`},children:Z.map(t=>{const i=A.get(t.key),u=I[t.key]??"#2a2a2a";return n.jsx("div",{style:{position:"absolute",left:(t.col-1)*44+4,top:(t.row-1)*44+4,width:36,height:36,background:i?"#5a5a62":u,border:i?"2px solid #00ffff":"2px outset #6a6a72",boxShadow:i?"0 0 5px #00ffff, inset 0 0 5px rgba(0,255,255,0.2)":"none",display:"flex",alignItems:"center",justifyContent:"center",cursor:i?"pointer":"default"},onMouseEnter:m=>i&&y(i,m),onMouseMove:m=>i&&y(i,m),onMouseLeave:()=>y(null),children:i?n.jsx(W,{item:i,size:32}):n.jsx("img",{src:"/icons/06000133.png",alt:"",style:{width:28,height:28,opacity:.15,filter:"grayscale(100%)",imageRendering:"pixelated"}})},t.key)})}),n.jsxs("div",{style:{padding:"3px 6px",fontSize:11,color:"#ccc",background:"#111",borderBottom:`1px solid ${$}`},children:["Contents of ",k!==null?((Y=z.find(t=>t.item_id===k))==null?void 0:Y.name)??"Pack":"Backpack"]}),n.jsxs("div",{style:{flex:1,overflowY:"auto",display:"grid",gridTemplateColumns:"repeat(6, 36px)",gridAutoRows:36,gap:2,padding:4,alignContent:"start"},children:[P.map((t,i)=>n.jsx("div",{style:{width:36,height:36,background:"linear-gradient(135deg, #3d007a 0%, #1a0033 100%)",border:"1px solid #4a148c",display:"flex",alignItems:"center",justifyContent:"center",cursor:"pointer"},onMouseEnter:u=>y(t,u),onMouseMove:u=>y(t,u),onMouseLeave:()=>y(null),children:n.jsx(W,{item:t,size:32})},t.item_id??i)),Array.from({length:Math.max(0,24-P.length)}).map((t,i)=>n.jsx("div",{style:{width:36,height:36,background:"#0a0a0a",border:"1px solid #1a1a1a"}},`e${i}`))]})]}),n.jsxs("div",{style:{width:42,display:"flex",flexDirection:"column",alignItems:"center",padding:"4px 2px",borderLeft:`1px solid ${$}`,borderRight:`1px solid ${$}`},children:[n.jsx("div",{style:{textAlign:"center",fontSize:8,color:"#ccc",marginBottom:2},children:R>0?`${Math.floor(E)}%`:"Burden"}),n.jsx("div",{style:{width:14,height:40,background:"#111",border:"1px solid #555",position:"relative",overflow:"hidden",marginBottom:6,flexShrink:0},title:R>0?`${N.toLocaleString()} / ${R.toLocaleString()}`:`Burden: ${c.reduce((t,i)=>t+(i.burden??0),0).toLocaleString()}`,children:n.jsx("div",{style:{position:"absolute",bottom:0,left:0,right:0,height:`${E/2}%`,background:ee,transition:"height 0.3s"}})}),n.jsx(G,{iconSrc:"/icons/0600127E.png",isActive:k===null,fillPct:S.length>0?Math.min(100,S.length/102*100):0,label:`Backpack (${S.length}/102)`,onClick:()=>H(null)}),z.map(t=>{const i=t.item_id,u=c.filter(l=>l.container_id===i&&l.item_id!==i).length,m=t.items_capacity||24,a=m>0?Math.min(100,u/m*100):0;return n.jsx(G,{iconSrc:`/icons/${D(t.icon)}.png`,isActive:k===i,fillPct:a,label:`${t.name} (${u}/${m})`,onClick:()=>H(i)},i)})]}),n.jsxs("div",{style:{flex:1,display:"flex",flexDirection:"column",overflow:"hidden",minWidth:160},children:[n.jsx("div",{style:{padding:"4px 8px",fontSize:"0.72rem",fontWeight:600,color:"#aaa",background:"#111",borderBottom:`1px solid ${$}`},children:"Mana"}),n.jsxs("div",{style:{flex:1,overflowY:"auto",padding:"2px 0"},children:[(()=>{const t=(d==null?void 0:d.items)??[],i=new Map(t.map(a=>[a.item_id,a])),u=d!=null&&d.timestamp?new Date(d.timestamp).getTime():0,m=u>0?Math.max(0,(Date.now()-u)/1e3):0;return Array.from(A.values()).map(a=>{const l=i.get(a.item_id),h=(l==null?void 0:l.current_mana)??a.current_mana??0,p=(l==null?void 0:l.max_mana)??a.max_mana??0,b=(l==null?void 0:l.mana_time_remaining_seconds)??null,x=b!=null?Math.max(0,b-m):null,v=(l==null?void 0:l.state)??(h>0?"active":"not_active");return{...a,current_mana:h,max_mana:p,liveRemaining:x,manaState:v}}).filter(a=>a.current_mana>0||a.max_mana>0).sort((a,l)=>(a.liveRemaining??999999)-(l.liveRemaining??999999)).map((a,l)=>{const h=a.manaState==="active"?"#4c4":a.manaState==="not_active"?"#c44":"#da8";return n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:4,padding:"2px 4px",borderBottom:"1px solid #1a1a1a",cursor:"pointer"},onMouseEnter:p=>y(a,p),onMouseMove:p=>y(a,p),onMouseLeave:()=>y(null),children:[n.jsx("div",{style:{width:20,height:20,flexShrink:0},children:n.jsx(W,{item:a,size:20})}),n.jsx("div",{style:{width:8,height:8,borderRadius:"50%",background:h,flexShrink:0}}),n.jsx("div",{style:{flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",fontSize:"0.68rem",color:"#ccc"},children:a.name}),n.jsxs("div",{style:{fontSize:"0.65rem",color:"#88bbff",whiteSpace:"nowrap",fontVariantNumeric:"tabular-nums"},children:[a.current_mana,"/",a.max_mana]}),n.jsx("div",{style:{fontSize:"0.63rem",color:"#9c9",whiteSpace:"nowrap",fontVariantNumeric:"tabular-nums",minWidth:42,textAlign:"right"},children:a.liveRemaining!=null?se(a.liveRemaining):""})]},l)})})(),Array.from(A.values()).filter(t=>t.current_mana>0||t.max_mana>0).length===0&&n.jsx("div",{style:{padding:12,color:"#555",textAlign:"center",fontSize:"0.7rem"},children:"No mana items equipped"})]})]})]}),B&&n.jsx(le,{item:B.item,x:B.x,y:B.y})]})};function se(e){if(e<=0)return"0h00m";const o=Math.floor(e),r=Math.floor(o/3600),s=Math.floor(o%3600/60);return`${r}h${String(s).padStart(2,"0")}m`}export{ce as InventoryWindow}; diff --git a/static/assets/IssuesWindow-BdHPJVkp.js b/static/assets/IssuesWindow-BZgt7gnX.js similarity index 99% rename from static/assets/IssuesWindow-BdHPJVkp.js rename to static/assets/IssuesWindow-BZgt7gnX.js index a2570428..0baa5f6d 100644 --- a/static/assets/IssuesWindow-BdHPJVkp.js +++ b/static/assets/IssuesWindow-BZgt7gnX.js @@ -1 +1 @@ -import{r as n,a as W,j as e,D as L}from"./index-D5aV9Wxd.js";import"./react-yfL0ty4i.js";const O={plugin:{label:"Plugin",color:"#8844cc"},overlord:{label:"Overlord",color:"#4488cc"},nav:{label:"Nav",color:"#44aa44"},macro:{label:"Macro",color:"#cc8844"},other:{label:"Other",color:"#888888"}},i={padding:"3px 6px",fontSize:"0.8rem",border:"1px solid #555",background:"#2a2a2a",color:"#ddd",borderRadius:0},N={...i,fontSize:"0.75rem"},g={padding:"4px 12px",background:"#4a80c0",color:"#fff",border:"1px solid #336699",cursor:"pointer",fontSize:"0.75rem"},a={padding:"3px 8px",background:"#444",color:"#ccc",border:"1px solid #555",cursor:"pointer",fontSize:"0.7rem"},F=({id:P,zIndex:A})=>{const[h,R]=n.useState([]),[c,m]=n.useState(""),[y,u]=n.useState(""),[f,$]=n.useState("plugin"),[v,d]=n.useState(null),[p,j]=n.useState(""),[b,S]=n.useState(""),[C,z]=n.useState(""),[T,k]=n.useState({}),x=n.useCallback(async()=>{try{const t=await W("/issues");R((t.issues??[]).sort((r,s)=>(r.resolved?1:0)-(s.resolved?1:0)))}catch{}},[]);n.useEffect(()=>{x()},[x]);const l=async(t,r)=>{await fetch(`/api${t}`,{...r,credentials:"include",headers:{"Content-Type":"application/json",...r.headers}}),x()},E=async()=>{c.trim()&&(await l("/issues",{method:"POST",body:JSON.stringify({title:c.trim(),description:y.trim(),category:f})}),m(""),u(""))},B=t=>{if(v===t.id){d(null);return}d(t.id),j(t.title),S(t.description||""),z(t.category||"other")},I=async t=>{p.trim()&&(await l(`/issues/${t}`,{method:"PATCH",body:JSON.stringify({title:p.trim(),description:b.trim(),category:C})}),d(null))},w=async t=>{const r=(T[t]||"").trim();r&&(await l(`/issues/${t}/comments`,{method:"POST",body:JSON.stringify({text:r})}),k(s=>({...s,[t]:""})))};return e.jsxs(L,{id:P,title:"Issues Board",zIndex:A,width:540,height:520,children:[e.jsxs("div",{style:{flex:1,overflowY:"auto",padding:6,fontSize:"0.8rem"},children:[h.length===0&&e.jsx("div",{style:{padding:10,color:"#888",textAlign:"center"},children:"No open issues"}),h.map(t=>{const r=O[t.category]||O.other,s=t.created?new Date(t.created).toLocaleDateString("sv-SE"):"",D=t.comments||[];return e.jsxs("div",{style:{padding:"6px 8px",marginBottom:4,background:"#1f1f1f",borderRadius:3,border:"1px solid #333",opacity:t.resolved?.55:1},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6,flexWrap:"wrap"},children:[e.jsx("span",{style:{fontSize:"0.65rem",padding:"1px 6px",borderRadius:3,background:r.color,color:"#fff",fontWeight:600},children:r.label}),e.jsx("strong",{style:{fontSize:"0.8rem",flex:1},children:t.title}),e.jsxs("span",{style:{fontSize:"0.65rem",color:"#888"},children:["by ",t.author||"User"]}),e.jsx("span",{style:{color:"#666",fontSize:"0.65rem"},children:s})]}),t.description&&e.jsx("div",{style:{color:"#999",marginTop:3,fontSize:"0.75rem"},children:t.description}),e.jsxs("div",{style:{display:"flex",gap:4,marginTop:4},children:[t.resolved?e.jsxs(e.Fragment,{children:[e.jsx("button",{style:{...a,fontSize:"0.65rem"},onClick:()=>l(`/issues/${t.id}`,{method:"PATCH",body:JSON.stringify({resolved:!1})}),children:"↻ Reopen"}),e.jsx("button",{style:{...a,fontSize:"0.65rem",color:"#c66"},onClick:()=>{confirm(`Delete issue "${t.title}"?`)&&l(`/issues/${t.id}`,{method:"DELETE"})},children:"🗑 Delete"})]}):e.jsx("button",{style:{...a,fontSize:"0.65rem",background:"rgba(68,204,68,0.15)",color:"#4c4",border:"1px solid rgba(68,204,68,0.3)"},onClick:()=>l(`/issues/${t.id}`,{method:"PATCH",body:JSON.stringify({resolved:!0})}),children:"✓ Resolve"}),e.jsx("button",{style:{...a,fontSize:"0.65rem"},onClick:()=>B(t),children:"✎ Edit"})]}),v===t.id&&e.jsxs("div",{style:{marginTop:4,padding:4,background:"#222",borderRadius:3},children:[e.jsxs("div",{style:{display:"flex",gap:4,marginBottom:4},children:[e.jsx("input",{value:p,onChange:o=>j(o.target.value),style:{...i,flex:1}}),e.jsxs("select",{value:C,onChange:o=>z(o.target.value),style:N,children:[e.jsx("option",{value:"plugin",children:"Plugin"}),e.jsx("option",{value:"overlord",children:"Overlord"}),e.jsx("option",{value:"nav",children:"Nav"}),e.jsx("option",{value:"macro",children:"Macro"}),e.jsx("option",{value:"other",children:"Other"})]})]}),e.jsxs("div",{style:{display:"flex",gap:4},children:[e.jsx("textarea",{value:b,onChange:o=>S(o.target.value),rows:2,style:{...i,flex:1,fontSize:"0.75rem",resize:"vertical"}}),e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:2},children:[e.jsx("button",{style:{...g,fontSize:"0.7rem",padding:"3px 8px"},onClick:()=>I(t.id),children:"Save"}),e.jsx("button",{style:{...a},onClick:()=>d(null),children:"Cancel"})]})]})]}),e.jsxs("div",{style:{marginTop:4,paddingTop:4,borderTop:"1px solid #2a2a2a"},children:[D.length===0?e.jsx("div",{style:{color:"#555",fontSize:"0.7rem",padding:"2px 0"},children:"No comments yet"}):D.map(o=>e.jsxs("div",{style:{marginBottom:3,fontSize:"0.72rem"},children:[e.jsx("span",{style:{color:"#8ac",fontWeight:500},children:o.author||"Anonymous"}),e.jsx("span",{style:{color:"#555",marginLeft:6,fontSize:"0.6rem"},children:o.created?new Date(o.created).toLocaleDateString("sv-SE"):""}),e.jsx("div",{style:{color:"#bbb",marginTop:1},children:o.text})]},o.id)),e.jsxs("div",{style:{display:"flex",gap:4,marginTop:3},children:[e.jsx("input",{value:T[t.id]||"",onChange:o=>k(J=>({...J,[t.id]:o.target.value})),placeholder:"Add a comment...",style:{...i,flex:1,fontSize:"0.75rem"},onKeyDown:o=>{o.key==="Enter"&&w(t.id)}}),e.jsx("button",{style:{...g,fontSize:"0.7rem",padding:"3px 8px"},onClick:()=>w(t.id),children:"Post"})]})]})]},t.id)})]}),e.jsxs("div",{style:{padding:6,borderTop:"1px solid #333"},children:[e.jsxs("div",{style:{display:"flex",gap:4,marginBottom:4},children:[e.jsx("input",{value:c,onChange:t=>m(t.target.value),placeholder:"Issue title...",style:{...i,flex:1},onKeyDown:t=>{t.key==="Enter"&&E()}}),e.jsxs("select",{value:f,onChange:t=>$(t.target.value),style:N,children:[e.jsx("option",{value:"plugin",children:"Plugin"}),e.jsx("option",{value:"overlord",children:"Overlord"}),e.jsx("option",{value:"nav",children:"Nav"}),e.jsx("option",{value:"macro",children:"Macro"}),e.jsx("option",{value:"other",children:"Other"})]})]}),e.jsxs("div",{style:{display:"flex",gap:4},children:[e.jsx("textarea",{value:y,onChange:t=>u(t.target.value),placeholder:"Description (optional)...",rows:2,style:{...i,flex:1,fontSize:"0.75rem",resize:"vertical"}}),e.jsx("button",{style:{...g,alignSelf:"flex-end"},onClick:E,children:"Add"})]})]})]})};export{F as IssuesWindow}; +import{r as n,a as W,j as e,D as L}from"./index-CPIBhBUe.js";import"./react-yfL0ty4i.js";const O={plugin:{label:"Plugin",color:"#8844cc"},overlord:{label:"Overlord",color:"#4488cc"},nav:{label:"Nav",color:"#44aa44"},macro:{label:"Macro",color:"#cc8844"},other:{label:"Other",color:"#888888"}},i={padding:"3px 6px",fontSize:"0.8rem",border:"1px solid #555",background:"#2a2a2a",color:"#ddd",borderRadius:0},N={...i,fontSize:"0.75rem"},g={padding:"4px 12px",background:"#4a80c0",color:"#fff",border:"1px solid #336699",cursor:"pointer",fontSize:"0.75rem"},a={padding:"3px 8px",background:"#444",color:"#ccc",border:"1px solid #555",cursor:"pointer",fontSize:"0.7rem"},F=({id:P,zIndex:A})=>{const[h,R]=n.useState([]),[c,m]=n.useState(""),[y,u]=n.useState(""),[f,$]=n.useState("plugin"),[v,d]=n.useState(null),[p,j]=n.useState(""),[b,S]=n.useState(""),[C,z]=n.useState(""),[T,k]=n.useState({}),x=n.useCallback(async()=>{try{const t=await W("/issues");R((t.issues??[]).sort((r,s)=>(r.resolved?1:0)-(s.resolved?1:0)))}catch{}},[]);n.useEffect(()=>{x()},[x]);const l=async(t,r)=>{await fetch(`/api${t}`,{...r,credentials:"include",headers:{"Content-Type":"application/json",...r.headers}}),x()},E=async()=>{c.trim()&&(await l("/issues",{method:"POST",body:JSON.stringify({title:c.trim(),description:y.trim(),category:f})}),m(""),u(""))},B=t=>{if(v===t.id){d(null);return}d(t.id),j(t.title),S(t.description||""),z(t.category||"other")},I=async t=>{p.trim()&&(await l(`/issues/${t}`,{method:"PATCH",body:JSON.stringify({title:p.trim(),description:b.trim(),category:C})}),d(null))},w=async t=>{const r=(T[t]||"").trim();r&&(await l(`/issues/${t}/comments`,{method:"POST",body:JSON.stringify({text:r})}),k(s=>({...s,[t]:""})))};return e.jsxs(L,{id:P,title:"Issues Board",zIndex:A,width:540,height:520,children:[e.jsxs("div",{style:{flex:1,overflowY:"auto",padding:6,fontSize:"0.8rem"},children:[h.length===0&&e.jsx("div",{style:{padding:10,color:"#888",textAlign:"center"},children:"No open issues"}),h.map(t=>{const r=O[t.category]||O.other,s=t.created?new Date(t.created).toLocaleDateString("sv-SE"):"",D=t.comments||[];return e.jsxs("div",{style:{padding:"6px 8px",marginBottom:4,background:"#1f1f1f",borderRadius:3,border:"1px solid #333",opacity:t.resolved?.55:1},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6,flexWrap:"wrap"},children:[e.jsx("span",{style:{fontSize:"0.65rem",padding:"1px 6px",borderRadius:3,background:r.color,color:"#fff",fontWeight:600},children:r.label}),e.jsx("strong",{style:{fontSize:"0.8rem",flex:1},children:t.title}),e.jsxs("span",{style:{fontSize:"0.65rem",color:"#888"},children:["by ",t.author||"User"]}),e.jsx("span",{style:{color:"#666",fontSize:"0.65rem"},children:s})]}),t.description&&e.jsx("div",{style:{color:"#999",marginTop:3,fontSize:"0.75rem"},children:t.description}),e.jsxs("div",{style:{display:"flex",gap:4,marginTop:4},children:[t.resolved?e.jsxs(e.Fragment,{children:[e.jsx("button",{style:{...a,fontSize:"0.65rem"},onClick:()=>l(`/issues/${t.id}`,{method:"PATCH",body:JSON.stringify({resolved:!1})}),children:"↻ Reopen"}),e.jsx("button",{style:{...a,fontSize:"0.65rem",color:"#c66"},onClick:()=>{confirm(`Delete issue "${t.title}"?`)&&l(`/issues/${t.id}`,{method:"DELETE"})},children:"🗑 Delete"})]}):e.jsx("button",{style:{...a,fontSize:"0.65rem",background:"rgba(68,204,68,0.15)",color:"#4c4",border:"1px solid rgba(68,204,68,0.3)"},onClick:()=>l(`/issues/${t.id}`,{method:"PATCH",body:JSON.stringify({resolved:!0})}),children:"✓ Resolve"}),e.jsx("button",{style:{...a,fontSize:"0.65rem"},onClick:()=>B(t),children:"✎ Edit"})]}),v===t.id&&e.jsxs("div",{style:{marginTop:4,padding:4,background:"#222",borderRadius:3},children:[e.jsxs("div",{style:{display:"flex",gap:4,marginBottom:4},children:[e.jsx("input",{value:p,onChange:o=>j(o.target.value),style:{...i,flex:1}}),e.jsxs("select",{value:C,onChange:o=>z(o.target.value),style:N,children:[e.jsx("option",{value:"plugin",children:"Plugin"}),e.jsx("option",{value:"overlord",children:"Overlord"}),e.jsx("option",{value:"nav",children:"Nav"}),e.jsx("option",{value:"macro",children:"Macro"}),e.jsx("option",{value:"other",children:"Other"})]})]}),e.jsxs("div",{style:{display:"flex",gap:4},children:[e.jsx("textarea",{value:b,onChange:o=>S(o.target.value),rows:2,style:{...i,flex:1,fontSize:"0.75rem",resize:"vertical"}}),e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:2},children:[e.jsx("button",{style:{...g,fontSize:"0.7rem",padding:"3px 8px"},onClick:()=>I(t.id),children:"Save"}),e.jsx("button",{style:{...a},onClick:()=>d(null),children:"Cancel"})]})]})]}),e.jsxs("div",{style:{marginTop:4,paddingTop:4,borderTop:"1px solid #2a2a2a"},children:[D.length===0?e.jsx("div",{style:{color:"#555",fontSize:"0.7rem",padding:"2px 0"},children:"No comments yet"}):D.map(o=>e.jsxs("div",{style:{marginBottom:3,fontSize:"0.72rem"},children:[e.jsx("span",{style:{color:"#8ac",fontWeight:500},children:o.author||"Anonymous"}),e.jsx("span",{style:{color:"#555",marginLeft:6,fontSize:"0.6rem"},children:o.created?new Date(o.created).toLocaleDateString("sv-SE"):""}),e.jsx("div",{style:{color:"#bbb",marginTop:1},children:o.text})]},o.id)),e.jsxs("div",{style:{display:"flex",gap:4,marginTop:3},children:[e.jsx("input",{value:T[t.id]||"",onChange:o=>k(J=>({...J,[t.id]:o.target.value})),placeholder:"Add a comment...",style:{...i,flex:1,fontSize:"0.75rem"},onKeyDown:o=>{o.key==="Enter"&&w(t.id)}}),e.jsx("button",{style:{...g,fontSize:"0.7rem",padding:"3px 8px"},onClick:()=>w(t.id),children:"Post"})]})]})]},t.id)})]}),e.jsxs("div",{style:{padding:6,borderTop:"1px solid #333"},children:[e.jsxs("div",{style:{display:"flex",gap:4,marginBottom:4},children:[e.jsx("input",{value:c,onChange:t=>m(t.target.value),placeholder:"Issue title...",style:{...i,flex:1},onKeyDown:t=>{t.key==="Enter"&&E()}}),e.jsxs("select",{value:f,onChange:t=>$(t.target.value),style:N,children:[e.jsx("option",{value:"plugin",children:"Plugin"}),e.jsx("option",{value:"overlord",children:"Overlord"}),e.jsx("option",{value:"nav",children:"Nav"}),e.jsx("option",{value:"macro",children:"Macro"}),e.jsx("option",{value:"other",children:"Other"})]})]}),e.jsxs("div",{style:{display:"flex",gap:4},children:[e.jsx("textarea",{value:y,onChange:t=>u(t.target.value),placeholder:"Description (optional)...",rows:2,style:{...i,flex:1,fontSize:"0.75rem",resize:"vertical"}}),e.jsx("button",{style:{...g,alignSelf:"flex-end"},onClick:E,children:"Add"})]})]})]})};export{F as IssuesWindow}; diff --git a/static/assets/QuestStatusWindow-C1NaAFXp.js b/static/assets/QuestStatusWindow-CNO3OiLF.js similarity index 96% rename from static/assets/QuestStatusWindow-C1NaAFXp.js rename to static/assets/QuestStatusWindow-CNO3OiLF.js index 4899965a..1ec34dd7 100644 --- a/static/assets/QuestStatusWindow-C1NaAFXp.js +++ b/static/assets/QuestStatusWindow-CNO3OiLF.js @@ -1 +1 @@ -import{r as c,j as t,D as u,a as f}from"./index-D5aV9Wxd.js";import"./react-yfL0ty4i.js";const j=({id:p,zIndex:x})=>{const[s,h]=c.useState(null);c.useEffect(()=>{const e=async()=>{try{h(await f("/quest-status"))}catch{}};e();const o=setInterval(e,3e4);return()=>clearInterval(o)},[]);const i=s?Object.keys(s.quest_data).sort():[],l=new Set;if(s)for(const e of Object.values(s.quest_data))for(const o of Object.keys(e))l.add(o);const n=Array.from(l).sort();return t.jsx(u,{id:p,title:"Quest Status",zIndex:x,width:780,height:500,children:t.jsx("div",{style:{flex:1,overflow:"auto",fontSize:"0.72rem"},children:s?i.length===0?t.jsx("div",{style:{padding:20,color:"#666",textAlign:"center"},children:"No quest data available"}):t.jsxs("table",{style:{width:"100%",borderCollapse:"collapse"},children:[t.jsx("thead",{children:t.jsxs("tr",{style:{position:"sticky",top:0,background:"#1a1a1a",zIndex:1},children:[t.jsx("th",{style:{textAlign:"left",padding:"4px 8px",borderBottom:"1px solid #444",color:"#888",fontSize:"0.65rem",fontWeight:600,minWidth:140},children:"Character"}),n.map(e=>t.jsx("th",{style:{textAlign:"center",padding:"4px 6px",borderBottom:"1px solid #444",color:"#888",fontSize:"0.6rem",fontWeight:600,maxWidth:120,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},title:e,children:e.replace(" Timer","").replace(" Pickup","")},e))]})}),t.jsx("tbody",{children:i.map(e=>{const o=s.quest_data[e]||{};return t.jsxs("tr",{style:{borderBottom:"1px solid #222"},children:[t.jsx("td",{style:{padding:"3px 8px",color:"#ccc",fontWeight:500,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis",maxWidth:160},children:e}),n.map(d=>{const r=o[d],a=r==="READY";return t.jsx("td",{style:{textAlign:"center",padding:"3px 6px",color:a?"#4c4":r?"#ca0":"#333",fontWeight:a?600:400,fontSize:a?"0.7rem":"0.68rem"},children:r||"—"},d)})]},e)})})]}):t.jsx("div",{style:{padding:20,color:"#666",textAlign:"center"},children:"Loading quest data..."})})})};export{j as QuestStatusWindow}; +import{r as c,j as t,D as u,a as f}from"./index-CPIBhBUe.js";import"./react-yfL0ty4i.js";const j=({id:p,zIndex:x})=>{const[s,h]=c.useState(null);c.useEffect(()=>{const e=async()=>{try{h(await f("/quest-status"))}catch{}};e();const o=setInterval(e,3e4);return()=>clearInterval(o)},[]);const i=s?Object.keys(s.quest_data).sort():[],l=new Set;if(s)for(const e of Object.values(s.quest_data))for(const o of Object.keys(e))l.add(o);const n=Array.from(l).sort();return t.jsx(u,{id:p,title:"Quest Status",zIndex:x,width:780,height:500,children:t.jsx("div",{style:{flex:1,overflow:"auto",fontSize:"0.72rem"},children:s?i.length===0?t.jsx("div",{style:{padding:20,color:"#666",textAlign:"center"},children:"No quest data available"}):t.jsxs("table",{style:{width:"100%",borderCollapse:"collapse"},children:[t.jsx("thead",{children:t.jsxs("tr",{style:{position:"sticky",top:0,background:"#1a1a1a",zIndex:1},children:[t.jsx("th",{style:{textAlign:"left",padding:"4px 8px",borderBottom:"1px solid #444",color:"#888",fontSize:"0.65rem",fontWeight:600,minWidth:140},children:"Character"}),n.map(e=>t.jsx("th",{style:{textAlign:"center",padding:"4px 6px",borderBottom:"1px solid #444",color:"#888",fontSize:"0.6rem",fontWeight:600,maxWidth:120,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},title:e,children:e.replace(" Timer","").replace(" Pickup","")},e))]})}),t.jsx("tbody",{children:i.map(e=>{const o=s.quest_data[e]||{};return t.jsxs("tr",{style:{borderBottom:"1px solid #222"},children:[t.jsx("td",{style:{padding:"3px 8px",color:"#ccc",fontWeight:500,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis",maxWidth:160},children:e}),n.map(d=>{const r=o[d],a=r==="READY";return t.jsx("td",{style:{textAlign:"center",padding:"3px 6px",color:a?"#4c4":r?"#ca0":"#333",fontWeight:a?600:400,fontSize:a?"0.7rem":"0.68rem"},children:r||"—"},d)})]},e)})})]}):t.jsx("div",{style:{padding:20,color:"#666",textAlign:"center"},children:"Loading quest data..."})})})};export{j as QuestStatusWindow}; diff --git a/static/assets/RadarWindow-Co69p423.js b/static/assets/RadarWindow-CYZptNtW.js similarity index 99% rename from static/assets/RadarWindow-Co69p423.js rename to static/assets/RadarWindow-CYZptNtW.js index 46c7c1e5..2210d331 100644 --- a/static/assets/RadarWindow-Co69p423.js +++ b/static/assets/RadarWindow-CYZptNtW.js @@ -1 +1 @@ -import{r as x,j as c,D as ne}from"./index-D5aV9Wxd.js";import"./react-yfL0ty4i.js";const q=300,H=.5,se={walls:{r:0,g:0,b:255},innerWalls:{r:127,g:127,b:255},rampedWalls:{r:77,g:255,b:255},floors:{r:0,g:127,b:255},stairs:{r:0,g:63,b:255}},le={walls:{r:140,g:140,b:180},innerWalls:{r:100,g:100,b:140},rampedWalls:{r:120,g:160,b:120},floors:{r:60,g:80,b:60},stairs:{r:180,g:160,b:80}};function oe(d){const g=document.createElement("canvas");g.width=10,g.height=10;const w=g.getContext("2d");w.drawImage(d,0,0,10,10);const a=w.getImageData(0,0,10,10),t=a.data;for(let p=0;p240&&R>240&&k>240){t[p+3]=0;continue}let E=!1;for(const[L,I]of Object.entries(se))if(Math.abs(_-I.r)<15&&Math.abs(R-I.g)<15&&Math.abs(k-I.b)<15){const W=le[L];t[p]=W.r,t[p+1]=W.g,t[p+2]=W.b,E=!0;break}!E&&_<15&&R<15&&k<15&&(t[p+3]=100)}return w.putImageData(a,0,0),g}function ie(d){return d===1?Math.PI:d<-.7&&d>-.8?Math.PI/2:d>.7&&d<.8?-Math.PI/2:0}let A=null;function ce(){A||(A={},fetch("/dungeon_tiles.json").then(d=>d.json()).then(d=>{Object.entries(d).forEach(([g,w])=>{const a=new Image;a.onload=()=>{A[g]=oe(a)},a.src=w})}).catch(()=>{}))}const K={Monster:"#ff4444",Player:"#4488ff",NPC:"#44cc44",Vendor:"#44cc44",Portal:"#aa44ff",Corpse:"#ff8800",Container:"#cccc44",Door:"#888888"};function re(d){const g=(d%360+360)%360;return["N","NE","E","SE","S","SW","W","NW"][Math.round(g/45)%8]}const fe=({id:d,charName:g,zIndex:w,socket:a,radarData:t})=>{const p=x.useRef(null),_=x.useRef(H),[R,k]=x.useState(H),[E,L]=x.useState(null),I=x.useRef(null),W=x.useRef([]);x.useEffect(()=>{const n=new Image;n.src="/dereth.png",n.onload=()=>{I.current=n},ce()},[]),x.useEffect(()=>((a==null?void 0:a.readyState)===WebSocket.OPEN&&a.send(JSON.stringify({player_name:g,command:"start_radar"})),()=>{(a==null?void 0:a.readyState)===WebSocket.OPEN&&a.send(JSON.stringify({player_name:g,command:"stop_radar"}))}),[g,a]);const Q=x.useCallback(n=>{n.preventDefault();const e=n.deltaY>0?1.25:.8;_.current=Math.max(.02,Math.min(5,_.current*e)),k(_.current)},[]),D=x.useCallback(n=>{const e=p.current;if(!e)return;const o=e.getBoundingClientRect(),s=(n.clientX-o.left)*(e.width/o.width),r=(n.clientY-o.top)*(e.height/o.height);let M=null,u=20;W.current.forEach(f=>{if(f._px===void 0)return;const S=Math.sqrt((s-f._px)**2+(r-f._py)**2);S{var G;const n=p.current;if(!n||!t)return;const e=n.getContext("2d");if(!e)return;const o=q,s=o/2,r=o/2,M=t.objects??[],u=t.player_ew??0,f=t.player_ns??0,S=t.player_heading??0,b=t.is_dungeon??!1,V=t.player_x??0,Z=t.player_y??0,Y=_.current,z=b?o/2/(Y*240):o/2/Y,j=S*Math.PI/180;e.clearRect(0,0,o,o),e.fillStyle="#111",e.beginPath(),e.arc(s,r,s,0,Math.PI*2),e.fill(),e.save(),e.beginPath(),e.arc(s,r,s-1,0,Math.PI*2),e.clip();const B=t.landblock??null,te=t.player_raw_z??0;if(b&&B&&((G=window.__dungeonMapCache)!=null&&G[B])){const l=window.__dungeonMapCache[B],h=Math.floor((te+3)/6)*6;e.translate(s,r),e.rotate(-(S-180)*Math.PI/180);const i=10*z,O=A&&Object.keys(A).length>0;(l.z_levels||[]).slice().sort((y,m)=>(y.z===h?1:0)-(m.z===h?1:0)).forEach(y=>{const m=y.z===h;e.globalAlpha=m?.85:.12,(y.cells||[]).forEach(T=>{const P=-(T.x-V)*z,N=(T.y-Z)*z,C=O?A[String(T.env_id)]:null;C?(e.save(),e.translate(P,N),e.rotate(ie(T.rotation)),e.drawImage(C,-i/2,-i/2,i,i),e.restore()):(e.fillStyle=m?"#3a5a3a":"#1a2a1a",e.fillRect(P-i/2,N-i/2,i,i))})}),e.globalAlpha=1,e.setTransform(1,0,0,1,0,0)}else if(!b&&I.current){const l=I.current,h=l.naturalWidth/204.2,i=(u+102.1)*h,O=(102.1-f)*h;e.globalAlpha=.4,e.save(),e.translate(s,r),e.rotate(-j);const v=Y*h*2;e.drawImage(l,i-v/2,O-v/2,v,v,-s,-r,o,o),e.restore(),e.globalAlpha=1}e.restore(),e.strokeStyle="#333",e.lineWidth=1;for(let l=1;l<=4;l++)e.beginPath(),e.arc(s,r,s/4*l,0,Math.PI*2),e.stroke();e.beginPath(),e.moveTo(s,0),e.lineTo(s,o),e.moveTo(0,r),e.lineTo(o,r),e.stroke(),e.font="bold 12px monospace",e.textAlign="center",e.textBaseline="middle",[{l:"N",a:0},{l:"E",a:Math.PI/2},{l:"S",a:Math.PI},{l:"W",a:-Math.PI/2}].forEach(({l,a:h})=>{const i=h-j;e.fillStyle=l==="N"?"#cc4444":"#888",e.fillText(l,s+Math.sin(i)*(s-12),r-Math.cos(i)*(s-12))}),e.strokeStyle="#666",e.lineWidth=1,e.beginPath(),e.moveTo(s,r),e.lineTo(s,r-s*.85),e.stroke();const $=b?Math.PI-j:j,X=Math.cos($),F=Math.sin($);M.forEach(l=>{let h,i;b&&l.raw_x!==void 0?(h=-(l.raw_x-V),i=l.raw_y-Z):(h=(l.ew??0)-u,i=(l.ns??0)-f);const O=h*X-i*F,v=b?h*F+i*X:-(h*F+i*X),y=s+O*z,m=r+v*z;if(Math.sqrt((y-s)**2+(m-r)**2)>s-4)return;l._px=y,l._py=m;const P=l.object_class??l.type??"",N=K[P]??"#888",C=l.id===E,J=C?6:P==="Monster"||P==="Player"?4:3;C&&(e.strokeStyle="#fff",e.lineWidth=2,e.beginPath(),e.arc(y,m,J+3,0,Math.PI*2),e.stroke()),e.fillStyle=N,e.beginPath(),e.arc(y,m,J,0,Math.PI*2),e.fill(),(P==="Player"||P==="Portal"||C)&&(e.fillStyle=C?"#fff":N,e.font="9px monospace",e.textAlign="left",e.fillText(l.name,y+6,m+3))}),W.current=M,e.fillStyle="#ffcc00",e.beginPath(),e.arc(s,r,5,0,Math.PI*2),e.fill(),e.strokeStyle="#fff",e.lineWidth=1,e.stroke()},[t,R,E]);const U=((t==null?void 0:t.objects)??[]).map(n=>{const e=(t==null?void 0:t.player_ew)??0,o=(t==null?void 0:t.player_ns)??0,s=(t==null?void 0:t.is_dungeon)??!1,r=(t==null?void 0:t.player_x)??0,M=(t==null?void 0:t.player_y)??0;let u,f,S;s&&n.raw_x!==void 0?(u=-(n.raw_x-r),f=n.raw_y-M,S=Math.sqrt(u*u+f*f)):(u=(n.ew??0)-e,f=(n.ns??0)-o,S=Math.sqrt(u*u+f*f)*240);const b=Math.atan2(u,f)*180/Math.PI;return{...n,dist:S,dir:re(b)}}).sort((n,e)=>n.dist-e.dist),ee=Math.round(R*240);return c.jsxs(ne,{id:d,title:`Radar: ${g}`,zIndex:w,width:360,height:560,children:[c.jsxs("div",{style:{padding:"4px 8px",display:"flex",justifyContent:"space-between",fontSize:"0.75rem",color:"#888",borderBottom:"1px solid #333",background:"#1a1a1a"},children:[c.jsxs("span",{children:["Range: ~",ee,"m"]}),c.jsx("span",{style:{fontSize:"0.65rem",color:"#555"},children:"Scroll to zoom"})]}),c.jsx("canvas",{ref:p,width:q,height:q,style:{display:"block",margin:"0 auto",borderBottom:"1px solid #333",cursor:"crosshair",flexShrink:0},onWheel:Q,onClick:D}),c.jsxs("div",{style:{flex:1,overflowY:"auto",fontSize:"0.72rem",minHeight:0},children:[c.jsxs("div",{style:{display:"flex",padding:"3px 6px",borderBottom:"1px solid #333",color:"#666",fontSize:"0.65rem",fontWeight:600},children:[c.jsx("span",{style:{width:8}}),c.jsx("span",{style:{flex:1,marginLeft:6},children:"Name"}),c.jsx("span",{style:{width:55,textAlign:"left"},children:"Type"}),c.jsx("span",{style:{width:40,textAlign:"right"},children:"Dist"}),c.jsx("span",{style:{width:24,textAlign:"center"},children:"Dir"})]}),U.length===0&&c.jsx("div",{style:{padding:12,color:"#555",textAlign:"center",fontSize:"0.7rem"},children:"Waiting for radar data..."}),U.map(n=>{const e=n.object_class??n.type??"",o=K[e]??"#888",s=n.id===E;return c.jsxs("div",{onClick:()=>L(s?null:n.id),style:{display:"flex",alignItems:"center",padding:"2px 6px",borderBottom:"1px solid #1a1a1a",cursor:"pointer",color:"#ccc",background:s?"#1a2a3a":"",borderLeft:s?"2px solid #4488ff":"2px solid transparent"},children:[c.jsx("span",{style:{width:8,height:8,borderRadius:"50%",background:o,flexShrink:0}}),c.jsx("span",{style:{flex:1,marginLeft:6,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:n.name}),c.jsx("span",{style:{width:55,color:"#888",fontSize:"0.65rem"},children:e}),c.jsx("span",{style:{width:40,textAlign:"right",fontVariantNumeric:"tabular-nums"},children:n.dist<1e3?`${Math.round(n.dist)}m`:`${(n.dist/1e3).toFixed(1)}km`}),c.jsx("span",{style:{width:24,textAlign:"center",color:"#666"},children:n.dir})]},n.id)})]})]})};export{fe as RadarWindow}; +import{r as x,j as c,D as ne}from"./index-CPIBhBUe.js";import"./react-yfL0ty4i.js";const q=300,H=.5,se={walls:{r:0,g:0,b:255},innerWalls:{r:127,g:127,b:255},rampedWalls:{r:77,g:255,b:255},floors:{r:0,g:127,b:255},stairs:{r:0,g:63,b:255}},le={walls:{r:140,g:140,b:180},innerWalls:{r:100,g:100,b:140},rampedWalls:{r:120,g:160,b:120},floors:{r:60,g:80,b:60},stairs:{r:180,g:160,b:80}};function oe(d){const g=document.createElement("canvas");g.width=10,g.height=10;const w=g.getContext("2d");w.drawImage(d,0,0,10,10);const a=w.getImageData(0,0,10,10),t=a.data;for(let p=0;p240&&R>240&&k>240){t[p+3]=0;continue}let E=!1;for(const[L,I]of Object.entries(se))if(Math.abs(_-I.r)<15&&Math.abs(R-I.g)<15&&Math.abs(k-I.b)<15){const W=le[L];t[p]=W.r,t[p+1]=W.g,t[p+2]=W.b,E=!0;break}!E&&_<15&&R<15&&k<15&&(t[p+3]=100)}return w.putImageData(a,0,0),g}function ie(d){return d===1?Math.PI:d<-.7&&d>-.8?Math.PI/2:d>.7&&d<.8?-Math.PI/2:0}let A=null;function ce(){A||(A={},fetch("/dungeon_tiles.json").then(d=>d.json()).then(d=>{Object.entries(d).forEach(([g,w])=>{const a=new Image;a.onload=()=>{A[g]=oe(a)},a.src=w})}).catch(()=>{}))}const K={Monster:"#ff4444",Player:"#4488ff",NPC:"#44cc44",Vendor:"#44cc44",Portal:"#aa44ff",Corpse:"#ff8800",Container:"#cccc44",Door:"#888888"};function re(d){const g=(d%360+360)%360;return["N","NE","E","SE","S","SW","W","NW"][Math.round(g/45)%8]}const fe=({id:d,charName:g,zIndex:w,socket:a,radarData:t})=>{const p=x.useRef(null),_=x.useRef(H),[R,k]=x.useState(H),[E,L]=x.useState(null),I=x.useRef(null),W=x.useRef([]);x.useEffect(()=>{const n=new Image;n.src="/dereth.png",n.onload=()=>{I.current=n},ce()},[]),x.useEffect(()=>((a==null?void 0:a.readyState)===WebSocket.OPEN&&a.send(JSON.stringify({player_name:g,command:"start_radar"})),()=>{(a==null?void 0:a.readyState)===WebSocket.OPEN&&a.send(JSON.stringify({player_name:g,command:"stop_radar"}))}),[g,a]);const Q=x.useCallback(n=>{n.preventDefault();const e=n.deltaY>0?1.25:.8;_.current=Math.max(.02,Math.min(5,_.current*e)),k(_.current)},[]),D=x.useCallback(n=>{const e=p.current;if(!e)return;const o=e.getBoundingClientRect(),s=(n.clientX-o.left)*(e.width/o.width),r=(n.clientY-o.top)*(e.height/o.height);let M=null,u=20;W.current.forEach(f=>{if(f._px===void 0)return;const S=Math.sqrt((s-f._px)**2+(r-f._py)**2);S{var G;const n=p.current;if(!n||!t)return;const e=n.getContext("2d");if(!e)return;const o=q,s=o/2,r=o/2,M=t.objects??[],u=t.player_ew??0,f=t.player_ns??0,S=t.player_heading??0,b=t.is_dungeon??!1,V=t.player_x??0,Z=t.player_y??0,Y=_.current,z=b?o/2/(Y*240):o/2/Y,j=S*Math.PI/180;e.clearRect(0,0,o,o),e.fillStyle="#111",e.beginPath(),e.arc(s,r,s,0,Math.PI*2),e.fill(),e.save(),e.beginPath(),e.arc(s,r,s-1,0,Math.PI*2),e.clip();const B=t.landblock??null,te=t.player_raw_z??0;if(b&&B&&((G=window.__dungeonMapCache)!=null&&G[B])){const l=window.__dungeonMapCache[B],h=Math.floor((te+3)/6)*6;e.translate(s,r),e.rotate(-(S-180)*Math.PI/180);const i=10*z,O=A&&Object.keys(A).length>0;(l.z_levels||[]).slice().sort((y,m)=>(y.z===h?1:0)-(m.z===h?1:0)).forEach(y=>{const m=y.z===h;e.globalAlpha=m?.85:.12,(y.cells||[]).forEach(T=>{const P=-(T.x-V)*z,N=(T.y-Z)*z,C=O?A[String(T.env_id)]:null;C?(e.save(),e.translate(P,N),e.rotate(ie(T.rotation)),e.drawImage(C,-i/2,-i/2,i,i),e.restore()):(e.fillStyle=m?"#3a5a3a":"#1a2a1a",e.fillRect(P-i/2,N-i/2,i,i))})}),e.globalAlpha=1,e.setTransform(1,0,0,1,0,0)}else if(!b&&I.current){const l=I.current,h=l.naturalWidth/204.2,i=(u+102.1)*h,O=(102.1-f)*h;e.globalAlpha=.4,e.save(),e.translate(s,r),e.rotate(-j);const v=Y*h*2;e.drawImage(l,i-v/2,O-v/2,v,v,-s,-r,o,o),e.restore(),e.globalAlpha=1}e.restore(),e.strokeStyle="#333",e.lineWidth=1;for(let l=1;l<=4;l++)e.beginPath(),e.arc(s,r,s/4*l,0,Math.PI*2),e.stroke();e.beginPath(),e.moveTo(s,0),e.lineTo(s,o),e.moveTo(0,r),e.lineTo(o,r),e.stroke(),e.font="bold 12px monospace",e.textAlign="center",e.textBaseline="middle",[{l:"N",a:0},{l:"E",a:Math.PI/2},{l:"S",a:Math.PI},{l:"W",a:-Math.PI/2}].forEach(({l,a:h})=>{const i=h-j;e.fillStyle=l==="N"?"#cc4444":"#888",e.fillText(l,s+Math.sin(i)*(s-12),r-Math.cos(i)*(s-12))}),e.strokeStyle="#666",e.lineWidth=1,e.beginPath(),e.moveTo(s,r),e.lineTo(s,r-s*.85),e.stroke();const $=b?Math.PI-j:j,X=Math.cos($),F=Math.sin($);M.forEach(l=>{let h,i;b&&l.raw_x!==void 0?(h=-(l.raw_x-V),i=l.raw_y-Z):(h=(l.ew??0)-u,i=(l.ns??0)-f);const O=h*X-i*F,v=b?h*F+i*X:-(h*F+i*X),y=s+O*z,m=r+v*z;if(Math.sqrt((y-s)**2+(m-r)**2)>s-4)return;l._px=y,l._py=m;const P=l.object_class??l.type??"",N=K[P]??"#888",C=l.id===E,J=C?6:P==="Monster"||P==="Player"?4:3;C&&(e.strokeStyle="#fff",e.lineWidth=2,e.beginPath(),e.arc(y,m,J+3,0,Math.PI*2),e.stroke()),e.fillStyle=N,e.beginPath(),e.arc(y,m,J,0,Math.PI*2),e.fill(),(P==="Player"||P==="Portal"||C)&&(e.fillStyle=C?"#fff":N,e.font="9px monospace",e.textAlign="left",e.fillText(l.name,y+6,m+3))}),W.current=M,e.fillStyle="#ffcc00",e.beginPath(),e.arc(s,r,5,0,Math.PI*2),e.fill(),e.strokeStyle="#fff",e.lineWidth=1,e.stroke()},[t,R,E]);const U=((t==null?void 0:t.objects)??[]).map(n=>{const e=(t==null?void 0:t.player_ew)??0,o=(t==null?void 0:t.player_ns)??0,s=(t==null?void 0:t.is_dungeon)??!1,r=(t==null?void 0:t.player_x)??0,M=(t==null?void 0:t.player_y)??0;let u,f,S;s&&n.raw_x!==void 0?(u=-(n.raw_x-r),f=n.raw_y-M,S=Math.sqrt(u*u+f*f)):(u=(n.ew??0)-e,f=(n.ns??0)-o,S=Math.sqrt(u*u+f*f)*240);const b=Math.atan2(u,f)*180/Math.PI;return{...n,dist:S,dir:re(b)}}).sort((n,e)=>n.dist-e.dist),ee=Math.round(R*240);return c.jsxs(ne,{id:d,title:`Radar: ${g}`,zIndex:w,width:360,height:560,children:[c.jsxs("div",{style:{padding:"4px 8px",display:"flex",justifyContent:"space-between",fontSize:"0.75rem",color:"#888",borderBottom:"1px solid #333",background:"#1a1a1a"},children:[c.jsxs("span",{children:["Range: ~",ee,"m"]}),c.jsx("span",{style:{fontSize:"0.65rem",color:"#555"},children:"Scroll to zoom"})]}),c.jsx("canvas",{ref:p,width:q,height:q,style:{display:"block",margin:"0 auto",borderBottom:"1px solid #333",cursor:"crosshair",flexShrink:0},onWheel:Q,onClick:D}),c.jsxs("div",{style:{flex:1,overflowY:"auto",fontSize:"0.72rem",minHeight:0},children:[c.jsxs("div",{style:{display:"flex",padding:"3px 6px",borderBottom:"1px solid #333",color:"#666",fontSize:"0.65rem",fontWeight:600},children:[c.jsx("span",{style:{width:8}}),c.jsx("span",{style:{flex:1,marginLeft:6},children:"Name"}),c.jsx("span",{style:{width:55,textAlign:"left"},children:"Type"}),c.jsx("span",{style:{width:40,textAlign:"right"},children:"Dist"}),c.jsx("span",{style:{width:24,textAlign:"center"},children:"Dir"})]}),U.length===0&&c.jsx("div",{style:{padding:12,color:"#555",textAlign:"center",fontSize:"0.7rem"},children:"Waiting for radar data..."}),U.map(n=>{const e=n.object_class??n.type??"",o=K[e]??"#888",s=n.id===E;return c.jsxs("div",{onClick:()=>L(s?null:n.id),style:{display:"flex",alignItems:"center",padding:"2px 6px",borderBottom:"1px solid #1a1a1a",cursor:"pointer",color:"#ccc",background:s?"#1a2a3a":"",borderLeft:s?"2px solid #4488ff":"2px solid transparent"},children:[c.jsx("span",{style:{width:8,height:8,borderRadius:"50%",background:o,flexShrink:0}}),c.jsx("span",{style:{flex:1,marginLeft:6,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:n.name}),c.jsx("span",{style:{width:55,color:"#888",fontSize:"0.65rem"},children:e}),c.jsx("span",{style:{width:40,textAlign:"right",fontVariantNumeric:"tabular-nums"},children:n.dist<1e3?`${Math.round(n.dist)}m`:`${(n.dist/1e3).toFixed(1)}km`}),c.jsx("span",{style:{width:24,textAlign:"center",color:"#666"},children:n.dir})]},n.id)})]})]})};export{fe as RadarWindow}; diff --git a/static/assets/StatsWindow-Dx7y3LW3.js b/static/assets/StatsWindow-BBzLtF0I.js similarity index 93% rename from static/assets/StatsWindow-Dx7y3LW3.js rename to static/assets/StatsWindow-BBzLtF0I.js index f6dbc361..b98ef87c 100644 --- a/static/assets/StatsWindow-Dx7y3LW3.js +++ b/static/assets/StatsWindow-BBzLtF0I.js @@ -1 +1 @@ -import{r as o,j as t,D as d}from"./index-D5aV9Wxd.js";import"./react-yfL0ty4i.js";const c=[{title:"Kills per Hour",id:1},{title:"Memory (MB)",id:2},{title:"CPU (%)",id:3},{title:"Mem Handles",id:4}],m=[{label:"1H",value:"now-1h"},{label:"6H",value:"now-6h"},{label:"24H",value:"now-24h"},{label:"7D",value:"now-7d"}],v=({id:s,charName:a,zIndex:i})=>{const[l,r]=o.useState("now-24h"),n=e=>`/grafana/d-solo/dereth-tracker/dereth-tracker-dashboard?panelId=${e}&var-character=${encodeURIComponent(a)}&from=${l}&to=now&theme=light`;return t.jsxs(d,{id:s,title:`Stats: ${a}`,zIndex:i,width:750,height:480,children:[t.jsx("div",{className:"ml-stats-controls",children:m.map(e=>t.jsx("button",{className:`ml-stats-range-btn ${l===e.value?"active":""}`,onClick:()=>r(e.value),children:e.label},e.value))}),t.jsx("div",{className:"ml-stats-grid",children:c.map(e=>t.jsx("div",{className:"ml-stats-panel",children:t.jsx("iframe",{src:n(e.id),width:"100%",height:"100%",frameBorder:"0",title:e.title})},e.id))})]})};export{v as StatsWindow}; +import{r as o,j as t,D as d}from"./index-CPIBhBUe.js";import"./react-yfL0ty4i.js";const c=[{title:"Kills per Hour",id:1},{title:"Memory (MB)",id:2},{title:"CPU (%)",id:3},{title:"Mem Handles",id:4}],m=[{label:"1H",value:"now-1h"},{label:"6H",value:"now-6h"},{label:"24H",value:"now-24h"},{label:"7D",value:"now-7d"}],v=({id:s,charName:a,zIndex:i})=>{const[l,r]=o.useState("now-24h"),n=e=>`/grafana/d-solo/dereth-tracker/dereth-tracker-dashboard?panelId=${e}&var-character=${encodeURIComponent(a)}&from=${l}&to=now&theme=light`;return t.jsxs(d,{id:s,title:`Stats: ${a}`,zIndex:i,width:750,height:480,children:[t.jsx("div",{className:"ml-stats-controls",children:m.map(e=>t.jsx("button",{className:`ml-stats-range-btn ${l===e.value?"active":""}`,onClick:()=>r(e.value),children:e.label},e.value))}),t.jsx("div",{className:"ml-stats-grid",children:c.map(e=>t.jsx("div",{className:"ml-stats-panel",children:t.jsx("iframe",{src:n(e.id),width:"100%",height:"100%",frameBorder:"0",title:e.title})},e.id))})]})};export{v as StatsWindow}; diff --git a/static/assets/VitalSharingWindow-DWghwvjH.js b/static/assets/VitalSharingWindow-2svvX-Jr.js similarity index 97% rename from static/assets/VitalSharingWindow-DWghwvjH.js rename to static/assets/VitalSharingWindow-2svvX-Jr.js index 0234763b..1ddef379 100644 --- a/static/assets/VitalSharingWindow-DWghwvjH.js +++ b/static/assets/VitalSharingWindow-2svvX-Jr.js @@ -1 +1 @@ -import{r as n,j as t,D as x,a as m}from"./index-D5aV9Wxd.js";import"./react-yfL0ty4i.js";const v=({id:o,zIndex:c})=>{const[a,d]=n.useState([]);n.useEffect(()=>{const e=async()=>{try{const s=await m("/vital-sharing/peers");d(s.peers??[])}catch{}};e();const l=setInterval(e,5e3);return()=>clearInterval(l)},[]);const h=(e,l)=>l>0?Math.min(100,e/l*100):0;return t.jsx(x,{id:o,title:"Vital Sharing Network",zIndex:c,width:520,height:450,children:t.jsx("div",{style:{flex:1,overflowY:"auto",padding:6,fontSize:"0.75rem"},children:a.length===0?t.jsx("div",{style:{padding:16,color:"#666",textAlign:"center"},children:"No vital-sharing peers connected"}):a.map(e=>{var l,s,r;return t.jsxs("div",{style:{padding:"6px 8px",marginBottom:4,background:"#1f1f1f",borderRadius:3,border:"1px solid #333"},children:[t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6,marginBottom:3},children:[t.jsx("span",{style:{color:e.plugin_connected?"#4c4":"#a33",fontSize:"0.8rem"},children:"●"}),t.jsx("strong",{style:{flex:1},children:e.character_name}),e.subscribed&&t.jsx("span",{style:{color:"#6bf",fontSize:"0.65rem"},children:"[subscribed]"})]}),t.jsxs("div",{style:{color:"#666",fontSize:"0.68rem",marginBottom:3},children:["tags: ",((l=e.tags)==null?void 0:l.join(", "))||"none"]}),e.vitals&&e.vitals.max_health>0&&t.jsx("div",{style:{display:"flex",flexDirection:"column",gap:2},children:[{label:"HP",cur:e.vitals.current_health,max:e.vitals.max_health,bg:"#330000",fill:"#c44"},{label:"STA",cur:e.vitals.current_stamina,max:e.vitals.max_stamina,bg:"#331a00",fill:"#ca0"},{label:"MANA",cur:e.vitals.current_mana,max:e.vitals.max_mana,bg:"#001433",fill:"#48f"}].map(i=>t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:4},children:[t.jsx("span",{style:{width:32,color:"#888",fontSize:"0.65rem"},children:i.label}),t.jsx("div",{style:{flex:1,height:6,background:i.bg,borderRadius:3,overflow:"hidden"},children:t.jsx("div",{style:{width:`${h(i.cur,i.max)}%`,height:"100%",background:i.fill,borderRadius:3}})}),t.jsxs("span",{style:{width:60,textAlign:"right",fontSize:"0.65rem",color:"#888"},children:[i.cur,"/",i.max]})]},i.label))}),e.position&&t.jsxs("div",{style:{color:"#555",fontSize:"0.65rem",marginTop:2},children:[(s=e.position.ns)==null?void 0:s.toFixed(1),"N, ",(r=e.position.ew)==null?void 0:r.toFixed(1),"E"]})]},e.character_name)})})})};export{v as VitalSharingWindow}; +import{r as n,j as t,D as x,a as m}from"./index-CPIBhBUe.js";import"./react-yfL0ty4i.js";const v=({id:o,zIndex:c})=>{const[a,d]=n.useState([]);n.useEffect(()=>{const e=async()=>{try{const s=await m("/vital-sharing/peers");d(s.peers??[])}catch{}};e();const l=setInterval(e,5e3);return()=>clearInterval(l)},[]);const h=(e,l)=>l>0?Math.min(100,e/l*100):0;return t.jsx(x,{id:o,title:"Vital Sharing Network",zIndex:c,width:520,height:450,children:t.jsx("div",{style:{flex:1,overflowY:"auto",padding:6,fontSize:"0.75rem"},children:a.length===0?t.jsx("div",{style:{padding:16,color:"#666",textAlign:"center"},children:"No vital-sharing peers connected"}):a.map(e=>{var l,s,r;return t.jsxs("div",{style:{padding:"6px 8px",marginBottom:4,background:"#1f1f1f",borderRadius:3,border:"1px solid #333"},children:[t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6,marginBottom:3},children:[t.jsx("span",{style:{color:e.plugin_connected?"#4c4":"#a33",fontSize:"0.8rem"},children:"●"}),t.jsx("strong",{style:{flex:1},children:e.character_name}),e.subscribed&&t.jsx("span",{style:{color:"#6bf",fontSize:"0.65rem"},children:"[subscribed]"})]}),t.jsxs("div",{style:{color:"#666",fontSize:"0.68rem",marginBottom:3},children:["tags: ",((l=e.tags)==null?void 0:l.join(", "))||"none"]}),e.vitals&&e.vitals.max_health>0&&t.jsx("div",{style:{display:"flex",flexDirection:"column",gap:2},children:[{label:"HP",cur:e.vitals.current_health,max:e.vitals.max_health,bg:"#330000",fill:"#c44"},{label:"STA",cur:e.vitals.current_stamina,max:e.vitals.max_stamina,bg:"#331a00",fill:"#ca0"},{label:"MANA",cur:e.vitals.current_mana,max:e.vitals.max_mana,bg:"#001433",fill:"#48f"}].map(i=>t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:4},children:[t.jsx("span",{style:{width:32,color:"#888",fontSize:"0.65rem"},children:i.label}),t.jsx("div",{style:{flex:1,height:6,background:i.bg,borderRadius:3,overflow:"hidden"},children:t.jsx("div",{style:{width:`${h(i.cur,i.max)}%`,height:"100%",background:i.fill,borderRadius:3}})}),t.jsxs("span",{style:{width:60,textAlign:"right",fontSize:"0.65rem",color:"#888"},children:[i.cur,"/",i.max]})]},i.label))}),e.position&&t.jsxs("div",{style:{color:"#555",fontSize:"0.65rem",marginTop:2},children:[(s=e.position.ns)==null?void 0:s.toFixed(1),"N, ",(r=e.position.ew)==null?void 0:r.toFixed(1),"E"]})]},e.character_name)})})})};export{v as VitalSharingWindow}; diff --git a/static/assets/index-D5aV9Wxd.js b/static/assets/index-CPIBhBUe.js similarity index 89% rename from static/assets/index-D5aV9Wxd.js rename to static/assets/index-CPIBhBUe.js index 3a53574f..437610ef 100644 --- a/static/assets/index-D5aV9Wxd.js +++ b/static/assets/index-CPIBhBUe.js @@ -1,4 +1,4 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/StatsWindow-Dx7y3LW3.js","assets/react-yfL0ty4i.js","assets/CharacterWindow-Bm7Dvqbf.js","assets/InventoryWindow-C3GJw7NT.js","assets/RadarWindow-Co69p423.js","assets/CombatStatsWindow-DrwSvkSn.js","assets/CombatPickerWindow-CJZfow68.js","assets/IssuesWindow-BdHPJVkp.js","assets/VitalSharingWindow-DWghwvjH.js","assets/QuestStatusWindow-C1NaAFXp.js","assets/AgentWindow-CMflyyRx.js","assets/AdminUsersWindow-CiWHpLWd.js"])))=>i.map(i=>d[i]); +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/StatsWindow-BBzLtF0I.js","assets/react-yfL0ty4i.js","assets/CharacterWindow-5cx18R5O.js","assets/InventoryWindow-OJaggw-L.js","assets/RadarWindow-CYZptNtW.js","assets/CombatStatsWindow-DiW4OOU6.js","assets/CombatPickerWindow-CeceAs6p.js","assets/IssuesWindow-BZgt7gnX.js","assets/VitalSharingWindow-2svvX-Jr.js","assets/QuestStatusWindow-CNO3OiLF.js","assets/AgentWindow-MAlGlaCG.js","assets/AdminUsersWindow-CnmS9CpE.js"])))=>i.map(i=>d[i]); import{r as Xd,g as j0,a as A0}from"./react-yfL0ty4i.js";(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const b of document.querySelectorAll('link[rel="modulepreload"]'))o(b);new MutationObserver(b=>{for(const j of b)if(j.type==="childList")for(const M of j.addedNodes)M.tagName==="LINK"&&M.rel==="modulepreload"&&o(M)}).observe(document,{childList:!0,subtree:!0});function m(b){const j={};return b.integrity&&(j.integrity=b.integrity),b.referrerPolicy&&(j.referrerPolicy=b.referrerPolicy),b.crossOrigin==="use-credentials"?j.credentials="include":b.crossOrigin==="anonymous"?j.credentials="omit":j.credentials="same-origin",j}function o(b){if(b.ep)return;b.ep=!0;const j=m(b);fetch(b.href,j)}})();var ms={exports:{}},_n={};/** * @license React * react-jsx-runtime.production.js @@ -15,7 +15,7 @@ import{r as Xd,g as j0,a as A0}from"./react-yfL0ty4i.js";(function(){const r=doc * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */var Nd;function N0(){return Nd||(Nd=1,(function(c){function r(_,q){var Q=_.length;_.push(q);t:for(;0>>1,w=_[H];if(0>>1;Hb(et,Q))Btb(Tl,et)?(_[H]=Tl,_[Bt]=Q,H=Bt):(_[H]=et,_[dt]=Q,H=dt);else if(Btb(Tl,Q))_[H]=Tl,_[Bt]=Q,H=Bt;else break t}}return q}function b(_,q){var Q=_.sortIndex-q.sortIndex;return Q!==0?Q:_.id-q.id}if(c.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var j=performance;c.unstable_now=function(){return j.now()}}else{var M=Date,N=M.now();c.unstable_now=function(){return M.now()-N}}var y=[],T=[],B=1,p=null,A=3,R=!1,L=!1,$=!1,V=!1,C=typeof setTimeout=="function"?setTimeout:null,Y=typeof clearTimeout=="function"?clearTimeout:null,F=typeof setImmediate<"u"?setImmediate:null;function zt(_){for(var q=m(T);q!==null;){if(q.callback===null)o(T);else if(q.startTime<=_)o(T),q.sortIndex=q.expirationTime,r(y,q);else break;q=m(T)}}function Ut(_){if($=!1,zt(_),!L)if(m(y)!==null)L=!0,lt||(lt=!0,jt());else{var q=m(T);q!==null&&xl(Ut,q.startTime-_)}}var lt=!1,at=-1,Z=5,J=-1;function P(){return V?!0:!(c.unstable_now()-J_&&P());){var H=p.callback;if(typeof H=="function"){p.callback=null,A=p.priorityLevel;var w=H(p.expirationTime<=_);if(_=c.unstable_now(),typeof w=="function"){p.callback=w,zt(_),q=!0;break l}p===m(y)&&o(y),zt(_)}else o(y);p=m(y)}if(p!==null)q=!0;else{var ot=m(T);ot!==null&&xl(Ut,ot.startTime-_),q=!1}}break t}finally{p=null,A=Q,R=!1}q=void 0}}finally{q?jt():lt=!1}}}var jt;if(typeof F=="function")jt=function(){F(Rt)};else if(typeof MessageChannel<"u"){var Ol=new MessageChannel,Al=Ol.port2;Ol.port1.onmessage=Rt,jt=function(){Al.postMessage(null)}}else jt=function(){C(Rt,0)};function xl(_,q){at=C(function(){_(c.unstable_now())},q)}c.unstable_IdlePriority=5,c.unstable_ImmediatePriority=1,c.unstable_LowPriority=4,c.unstable_NormalPriority=3,c.unstable_Profiling=null,c.unstable_UserBlockingPriority=2,c.unstable_cancelCallback=function(_){_.callback=null},c.unstable_forceFrameRate=function(_){0>_||125<_?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):Z=0<_?Math.floor(1e3/_):5},c.unstable_getCurrentPriorityLevel=function(){return A},c.unstable_next=function(_){switch(A){case 1:case 2:case 3:var q=3;break;default:q=A}var Q=A;A=q;try{return _()}finally{A=Q}},c.unstable_requestPaint=function(){V=!0},c.unstable_runWithPriority=function(_,q){switch(_){case 1:case 2:case 3:case 4:case 5:break;default:_=3}var Q=A;A=_;try{return q()}finally{A=Q}},c.unstable_scheduleCallback=function(_,q,Q){var H=c.unstable_now();switch(typeof Q=="object"&&Q!==null?(Q=Q.delay,Q=typeof Q=="number"&&0H?(_.sortIndex=Q,r(T,_),m(y)===null&&_===m(T)&&($?(Y(at),at=-1):$=!0,xl(Ut,Q-H))):(_.sortIndex=w,r(y,_),L||R||(L=!0,lt||(lt=!0,jt()))),_},c.unstable_shouldYield=P,c.unstable_wrapCallback=function(_){var q=A;return function(){var Q=A;A=q;try{return _.apply(this,arguments)}finally{A=Q}}}})(vs)),vs}var Md;function M0(){return Md||(Md=1,ys.exports=N0()),ys.exports}/** + */var Nd;function N0(){return Nd||(Nd=1,(function(c){function r(_,q){var Q=_.length;_.push(q);t:for(;0>>1,w=_[H];if(0>>1;Hb(et,Q))Btb(El,et)?(_[H]=El,_[Bt]=Q,H=Bt):(_[H]=et,_[dt]=Q,H=dt);else if(Btb(El,Q))_[H]=El,_[Bt]=Q,H=Bt;else break t}}return q}function b(_,q){var Q=_.sortIndex-q.sortIndex;return Q!==0?Q:_.id-q.id}if(c.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var j=performance;c.unstable_now=function(){return j.now()}}else{var M=Date,N=M.now();c.unstable_now=function(){return M.now()-N}}var y=[],T=[],B=1,p=null,A=3,R=!1,L=!1,$=!1,V=!1,C=typeof setTimeout=="function"?setTimeout:null,Y=typeof clearTimeout=="function"?clearTimeout:null,F=typeof setImmediate<"u"?setImmediate:null;function zt(_){for(var q=m(T);q!==null;){if(q.callback===null)o(T);else if(q.startTime<=_)o(T),q.sortIndex=q.expirationTime,r(y,q);else break;q=m(T)}}function Ut(_){if($=!1,zt(_),!L)if(m(y)!==null)L=!0,lt||(lt=!0,jt());else{var q=m(T);q!==null&&xl(Ut,q.startTime-_)}}var lt=!1,at=-1,Z=5,J=-1;function P(){return V?!0:!(c.unstable_now()-J_&&P());){var H=p.callback;if(typeof H=="function"){p.callback=null,A=p.priorityLevel;var w=H(p.expirationTime<=_);if(_=c.unstable_now(),typeof w=="function"){p.callback=w,zt(_),q=!0;break l}p===m(y)&&o(y),zt(_)}else o(y);p=m(y)}if(p!==null)q=!0;else{var ot=m(T);ot!==null&&xl(Ut,ot.startTime-_),q=!1}}break t}finally{p=null,A=Q,R=!1}q=void 0}}finally{q?jt():lt=!1}}}var jt;if(typeof F=="function")jt=function(){F(Rt)};else if(typeof MessageChannel<"u"){var Ol=new MessageChannel,Tl=Ol.port2;Ol.port1.onmessage=Rt,jt=function(){Tl.postMessage(null)}}else jt=function(){C(Rt,0)};function xl(_,q){at=C(function(){_(c.unstable_now())},q)}c.unstable_IdlePriority=5,c.unstable_ImmediatePriority=1,c.unstable_LowPriority=4,c.unstable_NormalPriority=3,c.unstable_Profiling=null,c.unstable_UserBlockingPriority=2,c.unstable_cancelCallback=function(_){_.callback=null},c.unstable_forceFrameRate=function(_){0>_||125<_?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):Z=0<_?Math.floor(1e3/_):5},c.unstable_getCurrentPriorityLevel=function(){return A},c.unstable_next=function(_){switch(A){case 1:case 2:case 3:var q=3;break;default:q=A}var Q=A;A=q;try{return _()}finally{A=Q}},c.unstable_requestPaint=function(){V=!0},c.unstable_runWithPriority=function(_,q){switch(_){case 1:case 2:case 3:case 4:case 5:break;default:_=3}var Q=A;A=_;try{return q()}finally{A=Q}},c.unstable_scheduleCallback=function(_,q,Q){var H=c.unstable_now();switch(typeof Q=="object"&&Q!==null?(Q=Q.delay,Q=typeof Q=="number"&&0H?(_.sortIndex=Q,r(T,_),m(y)===null&&_===m(T)&&($?(Y(at),at=-1):$=!0,xl(Ut,Q-H))):(_.sortIndex=w,r(y,_),L||R||(L=!0,lt||(lt=!0,jt()))),_},c.unstable_shouldYield=P,c.unstable_wrapCallback=function(_){var q=A;return function(){var Q=A;A=q;try{return _.apply(this,arguments)}finally{A=Q}}}})(vs)),vs}var Md;function M0(){return Md||(Md=1,ys.exports=N0()),ys.exports}/** * @license React * react-dom-client.production.js * @@ -23,12 +23,12 @@ import{r as Xd,g as j0,a as A0}from"./react-yfL0ty4i.js";(function(){const r=doc * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */var Cd;function C0(){if(Cd)return zn;Cd=1;var c=M0(),r=Xd(),m=A0();function o(t){var l="https://react.dev/errors/"+t;if(1w||(t.current=H[w],H[w]=null,w--)}function et(t,l){w++,H[w]=t.current,t.current=l}var Bt=ot(null),Tl=ot(null),Fl=ot(null),En=ot(null);function Nn(t,l){switch(et(Fl,l),et(Tl,t),et(Bt,null),l.nodeType){case 9:case 11:t=(t=l.documentElement)&&(t=t.namespaceURI)?Wo(t):0;break;default:if(t=l.tagName,l=l.namespaceURI)l=Wo(l),t=$o(l,t);else switch(t){case"svg":t=1;break;case"math":t=2;break;default:t=0}}dt(Bt),et(Bt,t)}function Qe(){dt(Bt),dt(Tl),dt(Fl)}function Ju(t){t.memoizedState!==null&&et(En,t);var l=Bt.current,e=$o(l,t.type);l!==e&&(et(Tl,t),et(Bt,e))}function Mn(t){Tl.current===t&&(dt(Bt),dt(Tl)),En.current===t&&(dt(En),pn._currentValue=Q)}var Wu,zs;function Ae(t){if(Wu===void 0)try{throw Error()}catch(e){var l=e.stack.trim().match(/\n( *(at )?)/);Wu=l&&l[1]||"",zs=-1w||(t.current=H[w],H[w]=null,w--)}function et(t,l){w++,H[w]=t.current,t.current=l}var Bt=ot(null),El=ot(null),Fl=ot(null),En=ot(null);function Nn(t,l){switch(et(Fl,l),et(El,t),et(Bt,null),l.nodeType){case 9:case 11:t=(t=l.documentElement)&&(t=t.namespaceURI)?Wo(t):0;break;default:if(t=l.tagName,l=l.namespaceURI)l=Wo(l),t=$o(l,t);else switch(t){case"svg":t=1;break;case"math":t=2;break;default:t=0}}dt(Bt),et(Bt,t)}function Qe(){dt(Bt),dt(El),dt(Fl)}function Ju(t){t.memoizedState!==null&&et(En,t);var l=Bt.current,e=$o(l,t.type);l!==e&&(et(El,t),et(Bt,e))}function Mn(t){El.current===t&&(dt(Bt),dt(El)),En.current===t&&(dt(En),pn._currentValue=Q)}var Wu,zs;function Ae(t){if(Wu===void 0)try{throw Error()}catch(e){var l=e.stack.trim().match(/\n( *(at )?)/);Wu=l&&l[1]||"",zs=-1)":-1n||d[a]!==x[n]){var D=` `+d[a].replace(" at new "," at ");return t.displayName&&D.includes("")&&(D=D.replace("",t.displayName)),D}while(1<=a&&0<=n);break}}}finally{$u=!1,Error.prepareStackTrace=e}return(e=t?t.displayName||t.name:"")?Ae(e):""}function lm(t,l){switch(t.tag){case 26:case 27:case 5:return Ae(t.type);case 16:return Ae("Lazy");case 13:return t.child!==l&&l!==null?Ae("Suspense Fallback"):Ae("Suspense");case 19:return Ae("SuspenseList");case 0:case 15:return Fu(t.type,!1);case 11:return Fu(t.type.render,!1);case 1:return Fu(t.type,!0);case 31:return Ae("Activity");default:return""}}function js(t){try{var l="",e=null;do l+=lm(t,e),e=t,t=t.return;while(t);return l}catch(a){return` Error generating stack: `+a.message+` -`+a.stack}}var Iu=Object.prototype.hasOwnProperty,Pu=c.unstable_scheduleCallback,ti=c.unstable_cancelCallback,em=c.unstable_shouldYield,am=c.unstable_requestPaint,Pt=c.unstable_now,nm=c.unstable_getCurrentPriorityLevel,As=c.unstable_ImmediatePriority,Ts=c.unstable_UserBlockingPriority,Cn=c.unstable_NormalPriority,um=c.unstable_LowPriority,Es=c.unstable_IdlePriority,im=c.log,cm=c.unstable_setDisableYieldValue,Ma=null,tl=null;function Il(t){if(typeof im=="function"&&cm(t),tl&&typeof tl.setStrictMode=="function")try{tl.setStrictMode(Ma,t)}catch{}}var ll=Math.clz32?Math.clz32:rm,sm=Math.log,fm=Math.LN2;function rm(t){return t>>>=0,t===0?32:31-(sm(t)/fm|0)|0}var Dn=256,On=262144,Un=4194304;function Te(t){var l=t&42;if(l!==0)return l;switch(t&-t){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return t&261888;case 262144:case 524288:case 1048576:case 2097152:return t&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return t&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return t}}function Rn(t,l,e){var a=t.pendingLanes;if(a===0)return 0;var n=0,u=t.suspendedLanes,i=t.pingedLanes;t=t.warmLanes;var f=a&134217727;return f!==0?(a=f&~u,a!==0?n=Te(a):(i&=f,i!==0?n=Te(i):e||(e=f&~t,e!==0&&(n=Te(e))))):(f=a&~u,f!==0?n=Te(f):i!==0?n=Te(i):e||(e=a&~t,e!==0&&(n=Te(e)))),n===0?0:l!==0&&l!==n&&(l&u)===0&&(u=n&-n,e=l&-l,u>=e||u===32&&(e&4194048)!==0)?l:n}function Ca(t,l){return(t.pendingLanes&~(t.suspendedLanes&~t.pingedLanes)&l)===0}function om(t,l){switch(t){case 1:case 2:case 4:case 8:case 64:return l+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return l+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Ns(){var t=Un;return Un<<=1,(Un&62914560)===0&&(Un=4194304),t}function li(t){for(var l=[],e=0;31>e;e++)l.push(t);return l}function Da(t,l){t.pendingLanes|=l,l!==268435456&&(t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0)}function dm(t,l,e,a,n,u){var i=t.pendingLanes;t.pendingLanes=e,t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0,t.expiredLanes&=e,t.entangledLanes&=e,t.errorRecoveryDisabledLanes&=e,t.shellSuspendCounter=0;var f=t.entanglements,d=t.expirationTimes,x=t.hiddenUpdates;for(e=i&~e;0"u")return null;try{return t.activeElement||t.body}catch{return t.body}}var pm=/[\n"\\]/g;function rl(t){return t.replace(pm,function(l){return"\\"+l.charCodeAt(0).toString(16)+" "})}function ci(t,l,e,a,n,u,i,f){t.name="",i!=null&&typeof i!="function"&&typeof i!="symbol"&&typeof i!="boolean"?t.type=i:t.removeAttribute("type"),l!=null?i==="number"?(l===0&&t.value===""||t.value!=l)&&(t.value=""+fl(l)):t.value!==""+fl(l)&&(t.value=""+fl(l)):i!=="submit"&&i!=="reset"||t.removeAttribute("value"),l!=null?si(t,i,fl(l)):e!=null?si(t,i,fl(e)):a!=null&&t.removeAttribute("value"),n==null&&u!=null&&(t.defaultChecked=!!u),n!=null&&(t.checked=n&&typeof n!="function"&&typeof n!="symbol"),f!=null&&typeof f!="function"&&typeof f!="symbol"&&typeof f!="boolean"?t.name=""+fl(f):t.removeAttribute("name")}function Xs(t,l,e,a,n,u,i,f){if(u!=null&&typeof u!="function"&&typeof u!="symbol"&&typeof u!="boolean"&&(t.type=u),l!=null||e!=null){if(!(u!=="submit"&&u!=="reset"||l!=null)){ii(t);return}e=e!=null?""+fl(e):"",l=l!=null?""+fl(l):e,f||l===t.value||(t.value=l),t.defaultValue=l}a=a??n,a=typeof a!="function"&&typeof a!="symbol"&&!!a,t.checked=f?t.checked:!!a,t.defaultChecked=!!a,i!=null&&typeof i!="function"&&typeof i!="symbol"&&typeof i!="boolean"&&(t.name=i),ii(t)}function si(t,l,e){l==="number"&&Hn(t.ownerDocument)===t||t.defaultValue===""+e||(t.defaultValue=""+e)}function $e(t,l,e,a){if(t=t.options,l){l={};for(var n=0;n"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),mi=!1;if(ql)try{var qa={};Object.defineProperty(qa,"passive",{get:function(){mi=!0}}),window.addEventListener("test",qa,qa),window.removeEventListener("test",qa,qa)}catch{mi=!1}var te=null,hi=null,Yn=null;function Js(){if(Yn)return Yn;var t,l=hi,e=l.length,a,n="value"in te?te.value:te.textContent,u=n.length;for(t=0;t=La),tf=" ",lf=!1;function ef(t,l){switch(t){case"keyup":return Km.indexOf(l.keyCode)!==-1;case"keydown":return l.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function af(t){return t=t.detail,typeof t=="object"&&"data"in t?t.data:null}var ta=!1;function Jm(t,l){switch(t){case"compositionend":return af(l);case"keypress":return l.which!==32?null:(lf=!0,tf);case"textInput":return t=l.data,t===tf&&lf?null:t;default:return null}}function Wm(t,l){if(ta)return t==="compositionend"||!bi&&ef(t,l)?(t=Js(),Yn=hi=te=null,ta=!1,t):null;switch(t){case"paste":return null;case"keypress":if(!(l.ctrlKey||l.altKey||l.metaKey)||l.ctrlKey&&l.altKey){if(l.char&&1=l)return{node:e,offset:l-t};t=a}t:{for(;e;){if(e.nextSibling){e=e.nextSibling;break t}e=e.parentNode}e=void 0}e=df(e)}}function hf(t,l){return t&&l?t===l?!0:t&&t.nodeType===3?!1:l&&l.nodeType===3?hf(t,l.parentNode):"contains"in t?t.contains(l):t.compareDocumentPosition?!!(t.compareDocumentPosition(l)&16):!1:!1}function yf(t){t=t!=null&&t.ownerDocument!=null&&t.ownerDocument.defaultView!=null?t.ownerDocument.defaultView:window;for(var l=Hn(t.document);l instanceof t.HTMLIFrameElement;){try{var e=typeof l.contentWindow.location.href=="string"}catch{e=!1}if(e)t=l.contentWindow;else break;l=Hn(t.document)}return l}function _i(t){var l=t&&t.nodeName&&t.nodeName.toLowerCase();return l&&(l==="input"&&(t.type==="text"||t.type==="search"||t.type==="tel"||t.type==="url"||t.type==="password")||l==="textarea"||t.contentEditable==="true")}var ah=ql&&"documentMode"in document&&11>=document.documentMode,la=null,zi=null,wa=null,ji=!1;function vf(t,l,e){var a=e.window===e?e.document:e.nodeType===9?e:e.ownerDocument;ji||la==null||la!==Hn(a)||(a=la,"selectionStart"in a&&_i(a)?a={start:a.selectionStart,end:a.selectionEnd}:(a=(a.ownerDocument&&a.ownerDocument.defaultView||window).getSelection(),a={anchorNode:a.anchorNode,anchorOffset:a.anchorOffset,focusNode:a.focusNode,focusOffset:a.focusOffset}),wa&&Xa(wa,a)||(wa=a,a=Ou(zi,"onSelect"),0>=i,n-=i,El=1<<32-ll(l)+n|e<tt?(ct=G,G=null):ct=G.sibling;var rt=z(v,G,S[tt],O);if(rt===null){G===null&&(G=ct);break}t&&G&&rt.alternate===null&&l(v,G),h=u(rt,h,tt),ft===null?K=rt:ft.sibling=rt,ft=rt,G=ct}if(tt===S.length)return e(v,G),st&&Hl(v,tt),K;if(G===null){for(;tttt?(ct=G,G=null):ct=G.sibling;var _e=z(v,G,rt.value,O);if(_e===null){G===null&&(G=ct);break}t&&G&&_e.alternate===null&&l(v,G),h=u(_e,h,tt),ft===null?K=_e:ft.sibling=_e,ft=_e,G=ct}if(rt.done)return e(v,G),st&&Hl(v,tt),K;if(G===null){for(;!rt.done;tt++,rt=S.next())rt=U(v,rt.value,O),rt!==null&&(h=u(rt,h,tt),ft===null?K=rt:ft.sibling=rt,ft=rt);return st&&Hl(v,tt),K}for(G=a(G);!rt.done;tt++,rt=S.next())rt=E(G,v,tt,rt.value,O),rt!==null&&(t&&rt.alternate!==null&&G.delete(rt.key===null?tt:rt.key),h=u(rt,h,tt),ft===null?K=rt:ft.sibling=rt,ft=rt);return t&&G.forEach(function(z0){return l(v,z0)}),st&&Hl(v,tt),K}function pt(v,h,S,O){if(typeof S=="object"&&S!==null&&S.type===$&&S.key===null&&(S=S.props.children),typeof S=="object"&&S!==null){switch(S.$$typeof){case R:t:{for(var K=S.key;h!==null;){if(h.key===K){if(K=S.type,K===$){if(h.tag===7){e(v,h.sibling),O=n(h,S.props.children),O.return=v,v=O;break t}}else if(h.elementType===K||typeof K=="object"&&K!==null&&K.$$typeof===Z&&He(K)===h.type){e(v,h.sibling),O=n(h,S.props),Ja(O,S),O.return=v,v=O;break t}e(v,h);break}else l(v,h);h=h.sibling}S.type===$?(O=Oe(S.props.children,v.mode,O,S.key),O.return=v,v=O):(O=Wn(S.type,S.key,S.props,null,v.mode,O),Ja(O,S),O.return=v,v=O)}return i(v);case L:t:{for(K=S.key;h!==null;){if(h.key===K)if(h.tag===4&&h.stateNode.containerInfo===S.containerInfo&&h.stateNode.implementation===S.implementation){e(v,h.sibling),O=n(h,S.children||[]),O.return=v,v=O;break t}else{e(v,h);break}else l(v,h);h=h.sibling}O=Di(S,v.mode,O),O.return=v,v=O}return i(v);case Z:return S=He(S),pt(v,h,S,O)}if(xl(S))return X(v,h,S,O);if(jt(S)){if(K=jt(S),typeof K!="function")throw Error(o(150));return S=K.call(S),k(v,h,S,O)}if(typeof S.then=="function")return pt(v,h,eu(S),O);if(S.$$typeof===F)return pt(v,h,In(v,S),O);au(v,S)}return typeof S=="string"&&S!==""||typeof S=="number"||typeof S=="bigint"?(S=""+S,h!==null&&h.tag===6?(e(v,h.sibling),O=n(h,S),O.return=v,v=O):(e(v,h),O=Ci(S,v.mode,O),O.return=v,v=O),i(v)):e(v,h)}return function(v,h,S,O){try{ka=0;var K=pt(v,h,S,O);return da=null,K}catch(G){if(G===oa||G===tu)throw G;var ft=al(29,G,null,v.mode);return ft.lanes=O,ft.return=v,ft}finally{}}}var Ye=Yf(!0),Vf=Yf(!1),ue=!1;function Gi(t){t.updateQueue={baseState:t.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Qi(t,l){t=t.updateQueue,l.updateQueue===t&&(l.updateQueue={baseState:t.baseState,firstBaseUpdate:t.firstBaseUpdate,lastBaseUpdate:t.lastBaseUpdate,shared:t.shared,callbacks:null})}function ie(t){return{lane:t,tag:0,payload:null,callback:null,next:null}}function ce(t,l,e){var a=t.updateQueue;if(a===null)return null;if(a=a.shared,(mt&2)!==0){var n=a.pending;return n===null?l.next=l:(l.next=n.next,n.next=l),a.pending=l,l=Jn(t),zf(t,null,e),l}return kn(t,a,l,e),Jn(t)}function Wa(t,l,e){if(l=l.updateQueue,l!==null&&(l=l.shared,(e&4194048)!==0)){var a=l.lanes;a&=t.pendingLanes,e|=a,l.lanes=e,Cs(t,e)}}function Zi(t,l){var e=t.updateQueue,a=t.alternate;if(a!==null&&(a=a.updateQueue,e===a)){var n=null,u=null;if(e=e.firstBaseUpdate,e!==null){do{var i={lane:e.lane,tag:e.tag,payload:e.payload,callback:null,next:null};u===null?n=u=i:u=u.next=i,e=e.next}while(e!==null);u===null?n=u=l:u=u.next=l}else n=u=l;e={baseState:a.baseState,firstBaseUpdate:n,lastBaseUpdate:u,shared:a.shared,callbacks:a.callbacks},t.updateQueue=e;return}t=e.lastBaseUpdate,t===null?e.firstBaseUpdate=l:t.next=l,e.lastBaseUpdate=l}var Ki=!1;function $a(){if(Ki){var t=ra;if(t!==null)throw t}}function Fa(t,l,e,a){Ki=!1;var n=t.updateQueue;ue=!1;var u=n.firstBaseUpdate,i=n.lastBaseUpdate,f=n.shared.pending;if(f!==null){n.shared.pending=null;var d=f,x=d.next;d.next=null,i===null?u=x:i.next=x,i=d;var D=t.alternate;D!==null&&(D=D.updateQueue,f=D.lastBaseUpdate,f!==i&&(f===null?D.firstBaseUpdate=x:f.next=x,D.lastBaseUpdate=d))}if(u!==null){var U=n.baseState;i=0,D=x=d=null,f=u;do{var z=f.lane&-536870913,E=z!==f.lane;if(E?(it&z)===z:(a&z)===z){z!==0&&z===fa&&(Ki=!0),D!==null&&(D=D.next={lane:0,tag:f.tag,payload:f.payload,callback:null,next:null});t:{var X=t,k=f;z=l;var pt=e;switch(k.tag){case 1:if(X=k.payload,typeof X=="function"){U=X.call(pt,U,z);break t}U=X;break t;case 3:X.flags=X.flags&-65537|128;case 0:if(X=k.payload,z=typeof X=="function"?X.call(pt,U,z):X,z==null)break t;U=p({},U,z);break t;case 2:ue=!0}}z=f.callback,z!==null&&(t.flags|=64,E&&(t.flags|=8192),E=n.callbacks,E===null?n.callbacks=[z]:E.push(z))}else E={lane:z,tag:f.tag,payload:f.payload,callback:f.callback,next:null},D===null?(x=D=E,d=U):D=D.next=E,i|=z;if(f=f.next,f===null){if(f=n.shared.pending,f===null)break;E=f,f=E.next,E.next=null,n.lastBaseUpdate=E,n.shared.pending=null}}while(!0);D===null&&(d=U),n.baseState=d,n.firstBaseUpdate=x,n.lastBaseUpdate=D,u===null&&(n.shared.lanes=0),de|=i,t.lanes=i,t.memoizedState=U}}function Xf(t,l){if(typeof t!="function")throw Error(o(191,t));t.call(l)}function wf(t,l){var e=t.callbacks;if(e!==null)for(t.callbacks=null,t=0;tu?u:8;var i=_.T,f={};_.T=f,oc(t,!1,l,e);try{var d=n(),x=_.S;if(x!==null&&x(f,d),d!==null&&typeof d=="object"&&typeof d.then=="function"){var D=dh(d,a);tn(t,l,D,sl(t))}else tn(t,l,a,sl(t))}catch(U){tn(t,l,{then:function(){},status:"rejected",reason:U},sl())}finally{q.p=u,i!==null&&f.types!==null&&(i.types=f.types),_.T=i}}function ph(){}function fc(t,l,e,a){if(t.tag!==5)throw Error(o(476));var n=Sr(t).queue;br(t,n,l,Q,e===null?ph:function(){return xr(t),e(a)})}function Sr(t){var l=t.memoizedState;if(l!==null)return l;l={memoizedState:Q,baseState:Q,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Xl,lastRenderedState:Q},next:null};var e={};return l.next={memoizedState:e,baseState:e,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Xl,lastRenderedState:e},next:null},t.memoizedState=l,t=t.alternate,t!==null&&(t.memoizedState=l),l}function xr(t){var l=Sr(t);l.next===null&&(l=t.alternate.memoizedState),tn(t,l.next.queue,{},sl())}function rc(){return Xt(pn)}function _r(){return Nt().memoizedState}function zr(){return Nt().memoizedState}function bh(t){for(var l=t.return;l!==null;){switch(l.tag){case 24:case 3:var e=sl();t=ie(e);var a=ce(l,t,e);a!==null&&(Ft(a,l,e),Wa(a,l,e)),l={cache:Yi()},t.payload=l;return}l=l.return}}function Sh(t,l,e){var a=sl();e={lane:a,revertLane:0,gesture:null,action:e,hasEagerState:!1,eagerState:null,next:null},mu(t)?Ar(l,e):(e=Ni(t,l,e,a),e!==null&&(Ft(e,t,a),Tr(e,l,a)))}function jr(t,l,e){var a=sl();tn(t,l,e,a)}function tn(t,l,e,a){var n={lane:a,revertLane:0,gesture:null,action:e,hasEagerState:!1,eagerState:null,next:null};if(mu(t))Ar(l,n);else{var u=t.alternate;if(t.lanes===0&&(u===null||u.lanes===0)&&(u=l.lastRenderedReducer,u!==null))try{var i=l.lastRenderedState,f=u(i,e);if(n.hasEagerState=!0,n.eagerState=f,el(f,i))return kn(t,l,n,0),bt===null&&Kn(),!1}catch{}finally{}if(e=Ni(t,l,n,a),e!==null)return Ft(e,t,a),Tr(e,l,a),!0}return!1}function oc(t,l,e,a){if(a={lane:2,revertLane:Gc(),gesture:null,action:a,hasEagerState:!1,eagerState:null,next:null},mu(t)){if(l)throw Error(o(479))}else l=Ni(t,e,a,2),l!==null&&Ft(l,t,2)}function mu(t){var l=t.alternate;return t===I||l!==null&&l===I}function Ar(t,l){ha=iu=!0;var e=t.pending;e===null?l.next=l:(l.next=e.next,e.next=l),t.pending=l}function Tr(t,l,e){if((e&4194048)!==0){var a=l.lanes;a&=t.pendingLanes,e|=a,l.lanes=e,Cs(t,e)}}var ln={readContext:Xt,use:fu,useCallback:At,useContext:At,useEffect:At,useImperativeHandle:At,useLayoutEffect:At,useInsertionEffect:At,useMemo:At,useReducer:At,useRef:At,useState:At,useDebugValue:At,useDeferredValue:At,useTransition:At,useSyncExternalStore:At,useId:At,useHostTransitionStatus:At,useFormState:At,useActionState:At,useOptimistic:At,useMemoCache:At,useCacheRefresh:At};ln.useEffectEvent=At;var Er={readContext:Xt,use:fu,useCallback:function(t,l){return Qt().memoizedState=[t,l===void 0?null:l],t},useContext:Xt,useEffect:rr,useImperativeHandle:function(t,l,e){e=e!=null?e.concat([t]):null,ou(4194308,4,hr.bind(null,l,t),e)},useLayoutEffect:function(t,l){return ou(4194308,4,t,l)},useInsertionEffect:function(t,l){ou(4,2,t,l)},useMemo:function(t,l){var e=Qt();l=l===void 0?null:l;var a=t();if(Ve){Il(!0);try{t()}finally{Il(!1)}}return e.memoizedState=[a,l],a},useReducer:function(t,l,e){var a=Qt();if(e!==void 0){var n=e(l);if(Ve){Il(!0);try{e(l)}finally{Il(!1)}}}else n=l;return a.memoizedState=a.baseState=n,t={pending:null,lanes:0,dispatch:null,lastRenderedReducer:t,lastRenderedState:n},a.queue=t,t=t.dispatch=Sh.bind(null,I,t),[a.memoizedState,t]},useRef:function(t){var l=Qt();return t={current:t},l.memoizedState=t},useState:function(t){t=nc(t);var l=t.queue,e=jr.bind(null,I,l);return l.dispatch=e,[t.memoizedState,e]},useDebugValue:cc,useDeferredValue:function(t,l){var e=Qt();return sc(e,t,l)},useTransition:function(){var t=nc(!1);return t=br.bind(null,I,t.queue,!0,!1),Qt().memoizedState=t,[!1,t]},useSyncExternalStore:function(t,l,e){var a=I,n=Qt();if(st){if(e===void 0)throw Error(o(407));e=e()}else{if(e=l(),bt===null)throw Error(o(349));(it&127)!==0||Jf(a,l,e)}n.memoizedState=e;var u={value:e,getSnapshot:l};return n.queue=u,rr($f.bind(null,a,u,t),[t]),a.flags|=2048,va(9,{destroy:void 0},Wf.bind(null,a,u,e,l),null),e},useId:function(){var t=Qt(),l=bt.identifierPrefix;if(st){var e=Nl,a=El;e=(a&~(1<<32-ll(a)-1)).toString(32)+e,l="_"+l+"R_"+e,e=cu++,0<\/script>",u=u.removeChild(u.firstChild);break;case"select":u=typeof a.is=="string"?i.createElement("select",{is:a.is}):i.createElement("select"),a.multiple?u.multiple=!0:a.size&&(u.size=a.size);break;default:u=typeof a.is=="string"?i.createElement(n,{is:a.is}):i.createElement(n)}}u[Yt]=l,u[Zt]=a;t:for(i=l.child;i!==null;){if(i.tag===5||i.tag===6)u.appendChild(i.stateNode);else if(i.tag!==4&&i.tag!==27&&i.child!==null){i.child.return=i,i=i.child;continue}if(i===l)break t;for(;i.sibling===null;){if(i.return===null||i.return===l)break t;i=i.return}i.sibling.return=i.return,i=i.sibling}l.stateNode=u;t:switch(Gt(u,n,a),n){case"button":case"input":case"select":case"textarea":a=!!a.autoFocus;break t;case"img":a=!0;break t;default:a=!1}a&&Gl(l)}}return xt(l),Ac(l,l.type,t===null?null:t.memoizedProps,l.pendingProps,e),null;case 6:if(t&&l.stateNode!=null)t.memoizedProps!==a&&Gl(l);else{if(typeof a!="string"&&l.stateNode===null)throw Error(o(166));if(t=Fl.current,ca(l)){if(t=l.stateNode,e=l.memoizedProps,a=null,n=Vt,n!==null)switch(n.tag){case 27:case 5:a=n.memoizedProps}t[Yt]=l,t=!!(t.nodeValue===e||a!==null&&a.suppressHydrationWarning===!0||ko(t.nodeValue,e)),t||ae(l,!0)}else t=Uu(t).createTextNode(a),t[Yt]=l,l.stateNode=t}return xt(l),null;case 31:if(e=l.memoizedState,t===null||t.memoizedState!==null){if(a=ca(l),e!==null){if(t===null){if(!a)throw Error(o(318));if(t=l.memoizedState,t=t!==null?t.dehydrated:null,!t)throw Error(o(557));t[Yt]=l}else Ue(),(l.flags&128)===0&&(l.memoizedState=null),l.flags|=4;xt(l),t=!1}else e=qi(),t!==null&&t.memoizedState!==null&&(t.memoizedState.hydrationErrors=e),t=!0;if(!t)return l.flags&256?(ul(l),l):(ul(l),null);if((l.flags&128)!==0)throw Error(o(558))}return xt(l),null;case 13:if(a=l.memoizedState,t===null||t.memoizedState!==null&&t.memoizedState.dehydrated!==null){if(n=ca(l),a!==null&&a.dehydrated!==null){if(t===null){if(!n)throw Error(o(318));if(n=l.memoizedState,n=n!==null?n.dehydrated:null,!n)throw Error(o(317));n[Yt]=l}else Ue(),(l.flags&128)===0&&(l.memoizedState=null),l.flags|=4;xt(l),n=!1}else n=qi(),t!==null&&t.memoizedState!==null&&(t.memoizedState.hydrationErrors=n),n=!0;if(!n)return l.flags&256?(ul(l),l):(ul(l),null)}return ul(l),(l.flags&128)!==0?(l.lanes=e,l):(e=a!==null,t=t!==null&&t.memoizedState!==null,e&&(a=l.child,n=null,a.alternate!==null&&a.alternate.memoizedState!==null&&a.alternate.memoizedState.cachePool!==null&&(n=a.alternate.memoizedState.cachePool.pool),u=null,a.memoizedState!==null&&a.memoizedState.cachePool!==null&&(u=a.memoizedState.cachePool.pool),u!==n&&(a.flags|=2048)),e!==t&&e&&(l.child.flags|=8192),pu(l,l.updateQueue),xt(l),null);case 4:return Qe(),t===null&&kc(l.stateNode.containerInfo),xt(l),null;case 10:return Yl(l.type),xt(l),null;case 19:if(dt(Et),a=l.memoizedState,a===null)return xt(l),null;if(n=(l.flags&128)!==0,u=a.rendering,u===null)if(n)an(a,!1);else{if(Tt!==0||t!==null&&(t.flags&128)!==0)for(t=l.child;t!==null;){if(u=uu(t),u!==null){for(l.flags|=128,an(a,!1),t=u.updateQueue,l.updateQueue=t,pu(l,t),l.subtreeFlags=0,t=e,e=l.child;e!==null;)jf(e,t),e=e.sibling;return et(Et,Et.current&1|2),st&&Hl(l,a.treeForkCount),l.child}t=t.sibling}a.tail!==null&&Pt()>zu&&(l.flags|=128,n=!0,an(a,!1),l.lanes=4194304)}else{if(!n)if(t=uu(u),t!==null){if(l.flags|=128,n=!0,t=t.updateQueue,l.updateQueue=t,pu(l,t),an(a,!0),a.tail===null&&a.tailMode==="hidden"&&!u.alternate&&!st)return xt(l),null}else 2*Pt()-a.renderingStartTime>zu&&e!==536870912&&(l.flags|=128,n=!0,an(a,!1),l.lanes=4194304);a.isBackwards?(u.sibling=l.child,l.child=u):(t=a.last,t!==null?t.sibling=u:l.child=u,a.last=u)}return a.tail!==null?(t=a.tail,a.rendering=t,a.tail=t.sibling,a.renderingStartTime=Pt(),t.sibling=null,e=Et.current,et(Et,n?e&1|2:e&1),st&&Hl(l,a.treeForkCount),t):(xt(l),null);case 22:case 23:return ul(l),Ji(),a=l.memoizedState!==null,t!==null?t.memoizedState!==null!==a&&(l.flags|=8192):a&&(l.flags|=8192),a?(e&536870912)!==0&&(l.flags&128)===0&&(xt(l),l.subtreeFlags&6&&(l.flags|=8192)):xt(l),e=l.updateQueue,e!==null&&pu(l,e.retryQueue),e=null,t!==null&&t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(e=t.memoizedState.cachePool.pool),a=null,l.memoizedState!==null&&l.memoizedState.cachePool!==null&&(a=l.memoizedState.cachePool.pool),a!==e&&(l.flags|=2048),t!==null&&dt(Be),null;case 24:return e=null,t!==null&&(e=t.memoizedState.cache),l.memoizedState.cache!==e&&(l.flags|=2048),Yl(Mt),xt(l),null;case 25:return null;case 30:return null}throw Error(o(156,l.tag))}function Ah(t,l){switch(Ui(l),l.tag){case 1:return t=l.flags,t&65536?(l.flags=t&-65537|128,l):null;case 3:return Yl(Mt),Qe(),t=l.flags,(t&65536)!==0&&(t&128)===0?(l.flags=t&-65537|128,l):null;case 26:case 27:case 5:return Mn(l),null;case 31:if(l.memoizedState!==null){if(ul(l),l.alternate===null)throw Error(o(340));Ue()}return t=l.flags,t&65536?(l.flags=t&-65537|128,l):null;case 13:if(ul(l),t=l.memoizedState,t!==null&&t.dehydrated!==null){if(l.alternate===null)throw Error(o(340));Ue()}return t=l.flags,t&65536?(l.flags=t&-65537|128,l):null;case 19:return dt(Et),null;case 4:return Qe(),null;case 10:return Yl(l.type),null;case 22:case 23:return ul(l),Ji(),t!==null&&dt(Be),t=l.flags,t&65536?(l.flags=t&-65537|128,l):null;case 24:return Yl(Mt),null;case 25:return null;default:return null}}function Fr(t,l){switch(Ui(l),l.tag){case 3:Yl(Mt),Qe();break;case 26:case 27:case 5:Mn(l);break;case 4:Qe();break;case 31:l.memoizedState!==null&&ul(l);break;case 13:ul(l);break;case 19:dt(Et);break;case 10:Yl(l.type);break;case 22:case 23:ul(l),Ji(),t!==null&&dt(Be);break;case 24:Yl(Mt)}}function nn(t,l){try{var e=l.updateQueue,a=e!==null?e.lastEffect:null;if(a!==null){var n=a.next;e=n;do{if((e.tag&t)===t){a=void 0;var u=e.create,i=e.inst;a=u(),i.destroy=a}e=e.next}while(e!==n)}}catch(f){yt(l,l.return,f)}}function re(t,l,e){try{var a=l.updateQueue,n=a!==null?a.lastEffect:null;if(n!==null){var u=n.next;a=u;do{if((a.tag&t)===t){var i=a.inst,f=i.destroy;if(f!==void 0){i.destroy=void 0,n=l;var d=e,x=f;try{x()}catch(D){yt(n,d,D)}}}a=a.next}while(a!==u)}}catch(D){yt(l,l.return,D)}}function Ir(t){var l=t.updateQueue;if(l!==null){var e=t.stateNode;try{wf(l,e)}catch(a){yt(t,t.return,a)}}}function Pr(t,l,e){e.props=Xe(t.type,t.memoizedProps),e.state=t.memoizedState;try{e.componentWillUnmount()}catch(a){yt(t,l,a)}}function un(t,l){try{var e=t.ref;if(e!==null){switch(t.tag){case 26:case 27:case 5:var a=t.stateNode;break;case 30:a=t.stateNode;break;default:a=t.stateNode}typeof e=="function"?t.refCleanup=e(a):e.current=a}}catch(n){yt(t,l,n)}}function Ml(t,l){var e=t.ref,a=t.refCleanup;if(e!==null)if(typeof a=="function")try{a()}catch(n){yt(t,l,n)}finally{t.refCleanup=null,t=t.alternate,t!=null&&(t.refCleanup=null)}else if(typeof e=="function")try{e(null)}catch(n){yt(t,l,n)}else e.current=null}function to(t){var l=t.type,e=t.memoizedProps,a=t.stateNode;try{t:switch(l){case"button":case"input":case"select":case"textarea":e.autoFocus&&a.focus();break t;case"img":e.src?a.src=e.src:e.srcSet&&(a.srcset=e.srcSet)}}catch(n){yt(t,t.return,n)}}function Tc(t,l,e){try{var a=t.stateNode;kh(a,t.type,e,l),a[Zt]=l}catch(n){yt(t,t.return,n)}}function lo(t){return t.tag===5||t.tag===3||t.tag===26||t.tag===27&&ge(t.type)||t.tag===4}function Ec(t){t:for(;;){for(;t.sibling===null;){if(t.return===null||lo(t.return))return null;t=t.return}for(t.sibling.return=t.return,t=t.sibling;t.tag!==5&&t.tag!==6&&t.tag!==18;){if(t.tag===27&&ge(t.type)||t.flags&2||t.child===null||t.tag===4)continue t;t.child.return=t,t=t.child}if(!(t.flags&2))return t.stateNode}}function Nc(t,l,e){var a=t.tag;if(a===5||a===6)t=t.stateNode,l?(e.nodeType===9?e.body:e.nodeName==="HTML"?e.ownerDocument.body:e).insertBefore(t,l):(l=e.nodeType===9?e.body:e.nodeName==="HTML"?e.ownerDocument.body:e,l.appendChild(t),e=e._reactRootContainer,e!=null||l.onclick!==null||(l.onclick=Rl));else if(a!==4&&(a===27&&ge(t.type)&&(e=t.stateNode,l=null),t=t.child,t!==null))for(Nc(t,l,e),t=t.sibling;t!==null;)Nc(t,l,e),t=t.sibling}function bu(t,l,e){var a=t.tag;if(a===5||a===6)t=t.stateNode,l?e.insertBefore(t,l):e.appendChild(t);else if(a!==4&&(a===27&&ge(t.type)&&(e=t.stateNode),t=t.child,t!==null))for(bu(t,l,e),t=t.sibling;t!==null;)bu(t,l,e),t=t.sibling}function eo(t){var l=t.stateNode,e=t.memoizedProps;try{for(var a=t.type,n=l.attributes;n.length;)l.removeAttributeNode(n[0]);Gt(l,a,e),l[Yt]=t,l[Zt]=e}catch(u){yt(t,t.return,u)}}var Ql=!1,Ot=!1,Mc=!1,ao=typeof WeakSet=="function"?WeakSet:Set,Lt=null;function Th(t,l){if(t=t.containerInfo,$c=Vu,t=yf(t),_i(t)){if("selectionStart"in t)var e={start:t.selectionStart,end:t.selectionEnd};else t:{e=(e=t.ownerDocument)&&e.defaultView||window;var a=e.getSelection&&e.getSelection();if(a&&a.rangeCount!==0){e=a.anchorNode;var n=a.anchorOffset,u=a.focusNode;a=a.focusOffset;try{e.nodeType,u.nodeType}catch{e=null;break t}var i=0,f=-1,d=-1,x=0,D=0,U=t,z=null;l:for(;;){for(var E;U!==e||n!==0&&U.nodeType!==3||(f=i+n),U!==u||a!==0&&U.nodeType!==3||(d=i+a),U.nodeType===3&&(i+=U.nodeValue.length),(E=U.firstChild)!==null;)z=U,U=E;for(;;){if(U===t)break l;if(z===e&&++x===n&&(f=i),z===u&&++D===a&&(d=i),(E=U.nextSibling)!==null)break;U=z,z=U.parentNode}U=E}e=f===-1||d===-1?null:{start:f,end:d}}else e=null}e=e||{start:0,end:0}}else e=null;for(Fc={focusedElem:t,selectionRange:e},Vu=!1,Lt=l;Lt!==null;)if(l=Lt,t=l.child,(l.subtreeFlags&1028)!==0&&t!==null)t.return=l,Lt=t;else for(;Lt!==null;){switch(l=Lt,u=l.alternate,t=l.flags,l.tag){case 0:if((t&4)!==0&&(t=l.updateQueue,t=t!==null?t.events:null,t!==null))for(e=0;e title"))),Gt(u,a,e),u[Yt]=t,Ht(u),a=u;break t;case"link":var i=rd("link","href",n).get(a+(e.href||""));if(i){for(var f=0;fpt&&(i=pt,pt=k,k=i);var v=mf(f,k),h=mf(f,pt);if(v&&h&&(E.rangeCount!==1||E.anchorNode!==v.node||E.anchorOffset!==v.offset||E.focusNode!==h.node||E.focusOffset!==h.offset)){var S=U.createRange();S.setStart(v.node,v.offset),E.removeAllRanges(),k>pt?(E.addRange(S),E.extend(h.node,h.offset)):(S.setEnd(h.node,h.offset),E.addRange(S))}}}}for(U=[],E=f;E=E.parentNode;)E.nodeType===1&&U.push({element:E,left:E.scrollLeft,top:E.scrollTop});for(typeof f.focus=="function"&&f.focus(),f=0;fe?32:e,_.T=null,e=Bc,Bc=null;var u=he,i=Wl;if(qt=0,xa=he=null,Wl=0,(mt&6)!==0)throw Error(o(331));var f=mt;if(mt|=4,yo(u.current),oo(u,u.current,i,e),mt=f,dn(0,!1),tl&&typeof tl.onPostCommitFiberRoot=="function")try{tl.onPostCommitFiberRoot(Ma,u)}catch{}return!0}finally{q.p=n,_.T=a,Uo(t,l)}}function qo(t,l,e){l=dl(e,l),l=yc(t.stateNode,l,2),t=ce(t,l,2),t!==null&&(Da(t,2),Cl(t))}function yt(t,l,e){if(t.tag===3)qo(t,t,e);else for(;l!==null;){if(l.tag===3){qo(l,t,e);break}else if(l.tag===1){var a=l.stateNode;if(typeof l.type.getDerivedStateFromError=="function"||typeof a.componentDidCatch=="function"&&(me===null||!me.has(a))){t=dl(e,t),e=qr(2),a=ce(l,e,2),a!==null&&(Br(e,a,l,t),Da(a,2),Cl(a));break}}l=l.return}}function Vc(t,l,e){var a=t.pingCache;if(a===null){a=t.pingCache=new Mh;var n=new Set;a.set(l,n)}else n=a.get(l),n===void 0&&(n=new Set,a.set(l,n));n.has(e)||(Oc=!0,n.add(e),t=Rh.bind(null,t,l,e),l.then(t,t))}function Rh(t,l,e){var a=t.pingCache;a!==null&&a.delete(l),t.pingedLanes|=t.suspendedLanes&e,t.warmLanes&=~e,bt===t&&(it&e)===e&&(Tt===4||Tt===3&&(it&62914560)===it&&300>Pt()-_u?(mt&2)===0&&_a(t,0):Uc|=e,Sa===it&&(Sa=0)),Cl(t)}function Bo(t,l){l===0&&(l=Ns()),t=De(t,l),t!==null&&(Da(t,l),Cl(t))}function qh(t){var l=t.memoizedState,e=0;l!==null&&(e=l.retryLane),Bo(t,e)}function Bh(t,l){var e=0;switch(t.tag){case 31:case 13:var a=t.stateNode,n=t.memoizedState;n!==null&&(e=n.retryLane);break;case 19:a=t.stateNode;break;case 22:a=t.stateNode._retryCache;break;default:throw Error(o(314))}a!==null&&a.delete(l),Bo(t,e)}function Hh(t,l){return Pu(t,l)}var Mu=null,ja=null,Xc=!1,Cu=!1,wc=!1,ve=0;function Cl(t){t!==ja&&t.next===null&&(ja===null?Mu=ja=t:ja=ja.next=t),Cu=!0,Xc||(Xc=!0,Yh())}function dn(t,l){if(!wc&&Cu){wc=!0;do for(var e=!1,a=Mu;a!==null;){if(t!==0){var n=a.pendingLanes;if(n===0)var u=0;else{var i=a.suspendedLanes,f=a.pingedLanes;u=(1<<31-ll(42|t)+1)-1,u&=n&~(i&~f),u=u&201326741?u&201326741|1:u?u|2:0}u!==0&&(e=!0,Vo(a,u))}else u=it,u=Rn(a,a===bt?u:0,a.cancelPendingCommit!==null||a.timeoutHandle!==-1),(u&3)===0||Ca(a,u)||(e=!0,Vo(a,u));a=a.next}while(e);wc=!1}}function Lh(){Ho()}function Ho(){Cu=Xc=!1;var t=0;ve!==0&&Wh()&&(t=ve);for(var l=Pt(),e=null,a=Mu;a!==null;){var n=a.next,u=Lo(a,l);u===0?(a.next=null,e===null?Mu=n:e.next=n,n===null&&(ja=e)):(e=a,(t!==0||(u&3)!==0)&&(Cu=!0)),a=n}qt!==0&&qt!==5||dn(t),ve!==0&&(ve=0)}function Lo(t,l){for(var e=t.suspendedLanes,a=t.pingedLanes,n=t.expirationTimes,u=t.pendingLanes&-62914561;0f)break;var D=d.transferSize,U=d.initiatorType;D&&Jo(U)&&(d=d.responseEnd,i+=D*(d"u"?null:document;function id(t,l,e){var a=Aa;if(a&&typeof l=="string"&&l){var n=rl(l);n='link[rel="'+t+'"][href="'+n+'"]',typeof e=="string"&&(n+='[crossorigin="'+e+'"]'),ud.has(n)||(ud.add(n),t={rel:t,crossOrigin:e,href:l},a.querySelector(n)===null&&(l=a.createElement("link"),Gt(l,"link",t),Ht(l),a.head.appendChild(l)))}}function n0(t){$l.D(t),id("dns-prefetch",t,null)}function u0(t,l){$l.C(t,l),id("preconnect",t,l)}function i0(t,l,e){$l.L(t,l,e);var a=Aa;if(a&&t&&l){var n='link[rel="preload"][as="'+rl(l)+'"]';l==="image"&&e&&e.imageSrcSet?(n+='[imagesrcset="'+rl(e.imageSrcSet)+'"]',typeof e.imageSizes=="string"&&(n+='[imagesizes="'+rl(e.imageSizes)+'"]')):n+='[href="'+rl(t)+'"]';var u=n;switch(l){case"style":u=Ta(t);break;case"script":u=Ea(t)}pl.has(u)||(t=p({rel:"preload",href:l==="image"&&e&&e.imageSrcSet?void 0:t,as:l},e),pl.set(u,t),a.querySelector(n)!==null||l==="style"&&a.querySelector(vn(u))||l==="script"&&a.querySelector(gn(u))||(l=a.createElement("link"),Gt(l,"link",t),Ht(l),a.head.appendChild(l)))}}function c0(t,l){$l.m(t,l);var e=Aa;if(e&&t){var a=l&&typeof l.as=="string"?l.as:"script",n='link[rel="modulepreload"][as="'+rl(a)+'"][href="'+rl(t)+'"]',u=n;switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":u=Ea(t)}if(!pl.has(u)&&(t=p({rel:"modulepreload",href:t},l),pl.set(u,t),e.querySelector(n)===null)){switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(e.querySelector(gn(u)))return}a=e.createElement("link"),Gt(a,"link",t),Ht(a),e.head.appendChild(a)}}}function s0(t,l,e){$l.S(t,l,e);var a=Aa;if(a&&t){var n=Je(a).hoistableStyles,u=Ta(t);l=l||"default";var i=n.get(u);if(!i){var f={loading:0,preload:null};if(i=a.querySelector(vn(u)))f.loading=5;else{t=p({rel:"stylesheet",href:t,"data-precedence":l},e),(e=pl.get(u))&&ns(t,e);var d=i=a.createElement("link");Ht(d),Gt(d,"link",t),d._p=new Promise(function(x,D){d.onload=x,d.onerror=D}),d.addEventListener("load",function(){f.loading|=1}),d.addEventListener("error",function(){f.loading|=2}),f.loading|=4,qu(i,l,a)}i={type:"stylesheet",instance:i,count:1,state:f},n.set(u,i)}}}function f0(t,l){$l.X(t,l);var e=Aa;if(e&&t){var a=Je(e).hoistableScripts,n=Ea(t),u=a.get(n);u||(u=e.querySelector(gn(n)),u||(t=p({src:t,async:!0},l),(l=pl.get(n))&&us(t,l),u=e.createElement("script"),Ht(u),Gt(u,"link",t),e.head.appendChild(u)),u={type:"script",instance:u,count:1,state:null},a.set(n,u))}}function r0(t,l){$l.M(t,l);var e=Aa;if(e&&t){var a=Je(e).hoistableScripts,n=Ea(t),u=a.get(n);u||(u=e.querySelector(gn(n)),u||(t=p({src:t,async:!0,type:"module"},l),(l=pl.get(n))&&us(t,l),u=e.createElement("script"),Ht(u),Gt(u,"link",t),e.head.appendChild(u)),u={type:"script",instance:u,count:1,state:null},a.set(n,u))}}function cd(t,l,e,a){var n=(n=Fl.current)?Ru(n):null;if(!n)throw Error(o(446));switch(t){case"meta":case"title":return null;case"style":return typeof e.precedence=="string"&&typeof e.href=="string"?(l=Ta(e.href),e=Je(n).hoistableStyles,a=e.get(l),a||(a={type:"style",instance:null,count:0,state:null},e.set(l,a)),a):{type:"void",instance:null,count:0,state:null};case"link":if(e.rel==="stylesheet"&&typeof e.href=="string"&&typeof e.precedence=="string"){t=Ta(e.href);var u=Je(n).hoistableStyles,i=u.get(t);if(i||(n=n.ownerDocument||n,i={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},u.set(t,i),(u=n.querySelector(vn(t)))&&!u._p&&(i.instance=u,i.state.loading=5),pl.has(t)||(e={rel:"preload",as:"style",href:e.href,crossOrigin:e.crossOrigin,integrity:e.integrity,media:e.media,hrefLang:e.hrefLang,referrerPolicy:e.referrerPolicy},pl.set(t,e),u||o0(n,t,e,i.state))),l&&a===null)throw Error(o(528,""));return i}if(l&&a!==null)throw Error(o(529,""));return null;case"script":return l=e.async,e=e.src,typeof e=="string"&&l&&typeof l!="function"&&typeof l!="symbol"?(l=Ea(e),e=Je(n).hoistableScripts,a=e.get(l),a||(a={type:"script",instance:null,count:0,state:null},e.set(l,a)),a):{type:"void",instance:null,count:0,state:null};default:throw Error(o(444,t))}}function Ta(t){return'href="'+rl(t)+'"'}function vn(t){return'link[rel="stylesheet"]['+t+"]"}function sd(t){return p({},t,{"data-precedence":t.precedence,precedence:null})}function o0(t,l,e,a){t.querySelector('link[rel="preload"][as="style"]['+l+"]")?a.loading=1:(l=t.createElement("link"),a.preload=l,l.addEventListener("load",function(){return a.loading|=1}),l.addEventListener("error",function(){return a.loading|=2}),Gt(l,"link",e),Ht(l),t.head.appendChild(l))}function Ea(t){return'[src="'+rl(t)+'"]'}function gn(t){return"script[async]"+t}function fd(t,l,e){if(l.count++,l.instance===null)switch(l.type){case"style":var a=t.querySelector('style[data-href~="'+rl(e.href)+'"]');if(a)return l.instance=a,Ht(a),a;var n=p({},e,{"data-href":e.href,"data-precedence":e.precedence,href:null,precedence:null});return a=(t.ownerDocument||t).createElement("style"),Ht(a),Gt(a,"style",n),qu(a,e.precedence,t),l.instance=a;case"stylesheet":n=Ta(e.href);var u=t.querySelector(vn(n));if(u)return l.state.loading|=4,l.instance=u,Ht(u),u;a=sd(e),(n=pl.get(n))&&ns(a,n),u=(t.ownerDocument||t).createElement("link"),Ht(u);var i=u;return i._p=new Promise(function(f,d){i.onload=f,i.onerror=d}),Gt(u,"link",a),l.state.loading|=4,qu(u,e.precedence,t),l.instance=u;case"script":return u=Ea(e.src),(n=t.querySelector(gn(u)))?(l.instance=n,Ht(n),n):(a=e,(n=pl.get(u))&&(a=p({},e),us(a,n)),t=t.ownerDocument||t,n=t.createElement("script"),Ht(n),Gt(n,"link",a),t.head.appendChild(n),l.instance=n);case"void":return null;default:throw Error(o(443,l.type))}else l.type==="stylesheet"&&(l.state.loading&4)===0&&(a=l.instance,l.state.loading|=4,qu(a,e.precedence,t));return l.instance}function qu(t,l,e){for(var a=e.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),n=a.length?a[a.length-1]:null,u=n,i=0;i title"):null)}function d0(t,l,e){if(e===1||l.itemProp!=null)return!1;switch(t){case"meta":case"title":return!0;case"style":if(typeof l.precedence!="string"||typeof l.href!="string"||l.href==="")break;return!0;case"link":if(typeof l.rel!="string"||typeof l.href!="string"||l.href===""||l.onLoad||l.onError)break;switch(l.rel){case"stylesheet":return t=l.disabled,typeof l.precedence=="string"&&t==null;default:return!0}case"script":if(l.async&&typeof l.async!="function"&&typeof l.async!="symbol"&&!l.onLoad&&!l.onError&&l.src&&typeof l.src=="string")return!0}return!1}function dd(t){return!(t.type==="stylesheet"&&(t.state.loading&3)===0)}function m0(t,l,e,a){if(e.type==="stylesheet"&&(typeof a.media!="string"||matchMedia(a.media).matches!==!1)&&(e.state.loading&4)===0){if(e.instance===null){var n=Ta(a.href),u=l.querySelector(vn(n));if(u){l=u._p,l!==null&&typeof l=="object"&&typeof l.then=="function"&&(t.count++,t=Hu.bind(t),l.then(t,t)),e.state.loading|=4,e.instance=u,Ht(u);return}u=l.ownerDocument||l,a=sd(a),(n=pl.get(n))&&ns(a,n),u=u.createElement("link"),Ht(u);var i=u;i._p=new Promise(function(f,d){i.onload=f,i.onerror=d}),Gt(u,"link",a),e.instance=u}t.stylesheets===null&&(t.stylesheets=new Map),t.stylesheets.set(e,l),(l=e.state.preload)&&(e.state.loading&3)===0&&(t.count++,e=Hu.bind(t),l.addEventListener("load",e),l.addEventListener("error",e))}}var is=0;function h0(t,l){return t.stylesheets&&t.count===0&&Yu(t,t.stylesheets),0is?50:800)+l);return t.unsuspend=e,function(){t.unsuspend=null,clearTimeout(a),clearTimeout(n)}}:null}function Hu(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Yu(this,this.stylesheets);else if(this.unsuspend){var t=this.unsuspend;this.unsuspend=null,t()}}}var Lu=null;function Yu(t,l){t.stylesheets=null,t.unsuspend!==null&&(t.count++,Lu=new Map,l.forEach(y0,t),Lu=null,Hu.call(t))}function y0(t,l){if(!(l.state.loading&4)){var e=Lu.get(t);if(e)var a=e.get(null);else{e=new Map,Lu.set(t,e);for(var n=t.querySelectorAll("link[data-precedence],style[data-precedence]"),u=0;u"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(c)}catch(r){console.error(r)}}return c(),hs.exports=C0(),hs.exports}var O0=D0();const wd=g.createContext({windows:[],openWindow:()=>{},closeWindow:()=>{},bringToFront:()=>{}}),U0=({children:c})=>{const[r,m]=g.useState([]),o=g.useRef(1e4),b=g.useCallback((N,y,T)=>{m(B=>B.find(A=>A.id===N)?B.map(A=>A.id===N?{...A,zIndex:++o.current}:A):[...B,{id:N,title:y,charName:T,zIndex:++o.current}])},[]),j=g.useCallback(N=>{m(y=>y.filter(T=>T.id!==N))},[]),M=g.useCallback(N=>{m(y=>y.map(T=>T.id===N?{...T,zIndex:++o.current}:T))},[]);return s.jsx(wd.Provider,{value:{windows:r,openWindow:b,closeWindow:j,bringToFront:M},children:c})},An=()=>g.useContext(wd),bl={west:-102.1,east:102.1,north:102.1,south:-102.1};function Tn(c,r,m,o){const b=(c-bl.west)/(bl.east-bl.west)*m,j=(bl.north-r)/(bl.north-bl.south)*o;return{x:b,y:j}}function R0(c,r,m,o,b,j,M){const N=(c-o)/m,y=(r-b)/m,T=bl.west+N/j*(bl.east-bl.west),B=bl.north-y/M*(bl.north-bl.south);return{ew:T,ns:B}}function gs(c,r){const m=c>=0?"N":"S",o=r>=0?"E":"W";return`${Math.abs(c).toFixed(1)}${m}, ${Math.abs(r).toFixed(1)}${o}`}const Gd=jn.memo(({players:c,imgW:r,imgH:m,getColor:o,onHover:b,onSelect:j,selectedPlayer:M})=>{const{openWindow:N}=An(),[y,T]=g.useState(null);g.useEffect(()=>{const p=()=>T(null);return y&&window.addEventListener("click",p),()=>window.removeEventListener("click",p)},[y]);const B=g.useMemo(()=>c.filter(p=>p.ew!==void 0&&p.ns!==void 0).map(p=>({...p,pos:Tn(p.ew,p.ns,r,m),color:o(p.character_name)})),[c,r,m,o]);return s.jsxs("div",{className:"ml-dots-layer",children:[B.map(p=>s.jsx("div",{className:`ml-dot ${M===p.character_name?"ml-dot-selected":""}`,style:{left:p.pos.x,top:p.pos.y,backgroundColor:p.color},onMouseEnter:A=>{var L;const R=(L=A.currentTarget.closest(".ml-map-container"))==null?void 0:L.getBoundingClientRect();R&&b(p,A.clientX-R.left,A.clientY-R.top)},onMouseLeave:()=>b(null,0,0),onClick:()=>j(p.character_name),onDoubleClick:()=>N(`chat-${p.character_name}`,`Chat: ${p.character_name}`,p.character_name),onContextMenu:A=>{var C;A.preventDefault();const R=p.character_name,L=(C=A.currentTarget.closest(".ml-map-container"))==null?void 0:C.getBoundingClientRect(),$=L?A.clientX-L.left:A.clientX,V=L?A.clientY-L.top:A.clientY;T({name:R,x:$,y:V})}},p.character_name)),y&&s.jsx("div",{style:{position:"fixed",left:y.x+410,top:y.y,background:"#1a1a1a",border:"1px solid #444",borderRadius:4,zIndex:9999,padding:"2px 0",fontSize:"0.75rem",boxShadow:"0 4px 12px rgba(0,0,0,0.5)",minWidth:120},children:[{label:"Chat",id:"chat"},{label:"Stats",id:"stats"},{label:"Inventory",id:"inv"},{label:"Character",id:"char"},{label:"Combat",id:"combat"},{label:"Radar",id:"radar"}].map(p=>s.jsx("div",{onClick:()=>{N(`${p.id}-${y.name}`,`${p.label}: ${y.name}`,y.name),T(null)},style:{padding:"4px 12px",cursor:"pointer",color:"#ccc"},onMouseEnter:A=>A.currentTarget.style.background="#333",onMouseLeave:A=>A.currentTarget.style.background="",children:p.label},p.id))})]})});Gd.displayName="PlayerDots";const ku="/api";async function It(c){const r=await fetch(`${ku}${c}`,{credentials:"include"});if(!r.ok)throw new Error(`API ${c}: ${r.status}`);return r.json()}async function Ss(c,r){var o;const m=await fetch(`${ku}${c}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify(r??{})});if(!m.ok){let b="";try{b=((o=await m.json())==null?void 0:o.detail)??""}catch{}throw new Error(`API ${c}: ${m.status}${b?` (${b})`:""}`)}return m.json()}async function q0(c,r){var o;const m=await fetch(`${ku}${c}`,{method:"PATCH",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify(r??{})});if(!m.ok){let b="";try{b=((o=await m.json())==null?void 0:o.detail)??""}catch{}throw new Error(`API ${c}: ${m.status}${b?` (${b})`:""}`)}return m.json()}async function B0(c){var m;const r=await fetch(`${ku}${c}`,{method:"DELETE",credentials:"include"});if(!r.ok){let o="";try{o=((m=await r.json())==null?void 0:m.detail)??""}catch{}throw new Error(`API ${c}: ${r.status}${o?` (${o})`:""}`)}return r.json()}function H0(){return`${location.protocol==="https:"?"wss:":"ws:"}//${location.host}/api/ws/live`}const Qd=jn.memo(({imgW:c,imgH:r,getColor:m})=>{const[o,b]=g.useState([]);g.useEffect(()=>{const M=async()=>{try{const y=await It("/trails/?seconds=600");b(y.trails??[])}catch{}};M();const N=setInterval(M,2e3);return()=>clearInterval(N)},[]);const j=g.useMemo(()=>{const M={};for(const N of o){const{x:y,y:T}=Tn(N.ew,N.ns,c,r);M[N.character_name]||(M[N.character_name]=[]),M[N.character_name].push(`${y},${T}`)}return Object.entries(M).filter(([,N])=>N.length>=2).map(([N,y])=>({name:N,points:y.join(" ")}))},[o,c,r]);return s.jsx("svg",{className:"ml-trails-svg",viewBox:`0 0 ${c} ${r}`,preserveAspectRatio:"none",children:j.map(M=>s.jsx("polyline",{points:M.points,stroke:m(M.name),fill:"none",strokeWidth:2,strokeOpacity:.7,strokeLinecap:"round",strokeLinejoin:"round"},M.name))})});Qd.displayName="TrailsSVG";const L0=({imgW:c,imgH:r,enabled:m})=>{const o=g.useRef(null),[b,j]=g.useState([]);return g.useEffect(()=>{if(!m)return;(async()=>{try{const N=await It("/spawns/heatmap?hours=24&limit=50000");j(N.spawn_points??[])}catch{}})()},[m]),g.useEffect(()=>{const M=o.current;if(!M||!m||b.length===0||c===0)return;M.width=c,M.height=r;const N=M.getContext("2d");if(N){N.clearRect(0,0,c,r);for(const y of b){const{x:T,y:B}=Tn(y.ew,y.ns,c,r),p=Math.max(5,Math.min(12,5+Math.sqrt(y.intensity*.5))),A=N.createRadialGradient(T,B,0,T,B,p);A.addColorStop(0,`rgba(255, 0, 0, ${Math.min(.9,y.intensity/40)})`),A.addColorStop(.6,`rgba(255, 100, 0, ${Math.min(.4,y.intensity/120)})`),A.addColorStop(1,"rgba(255, 150, 0, 0)"),N.fillStyle=A,N.fillRect(T-p,B-p,p*2,p*2)}}},[b,c,r,m]),m?s.jsx("canvas",{ref:o,className:"ml-heatmap-canvas"}):null},Y0=({imgW:c,imgH:r,enabled:m})=>{const[o,b]=g.useState([]);g.useEffect(()=>{if(!m)return;const M=async()=>{try{const y=await It("/portals");b(y.portals??[])}catch{}};M();const N=setInterval(M,6e4);return()=>clearInterval(N)},[m]);const j=g.useMemo(()=>o.map(M=>({...M,pos:Tn(M.coordinates.ew,M.coordinates.ns,c,r)})),[o,c,r]);return!m||j.length===0?null:s.jsx("div",{className:"ml-portals-layer",children:j.map((M,N)=>s.jsx("div",{className:"ml-portal-icon",style:{left:M.pos.x,top:M.pos.y},title:`${M.portal_name} (by ${M.discovered_by})`},N))})},Od="mo-midsummer",V0=!1,Zd=g.createContext(null),X0=({children:c})=>{const[r,m]=g.useState(()=>localStorage.getItem(Od)!=="off"),o=V0;g.useEffect(()=>{document.documentElement.removeAttribute("data-midsummer")},[o]);const b=g.useCallback(()=>{m(j=>{const M=!j;return localStorage.setItem(Od,M?"on":"off"),M})},[]);return s.jsx(Zd.Provider,{value:{enabled:o,toggle:b},children:c})};function xs(){const c=g.useContext(Zd);if(!c)throw new Error("useMidsummer must be used within MidsummerProvider");return c}const Ud=6,w0=(c,r)=>({x:c/2,y:r/2}),G0=({imgW:c,imgH:r})=>{const{enabled:m}=xs();if(!m||c===0)return null;const{x:o,y:b}=w0(c,r);return s.jsxs("div",{className:"ms-maypole",style:{left:o,top:b},"aria-hidden":"true",children:[s.jsx("div",{className:"ms-maypole-pole"}),s.jsx("div",{className:"ms-maypole-ring",children:Array.from({length:Ud}).map((j,M)=>s.jsx("span",{className:"ms-frog",style:{transform:`rotate(${360/Ud*M}deg) translateY(-40px)`},children:"🐸"},M))})]})},Rd=20,qd=.3,Q0=({players:c,getColor:r,onSelectPlayer:m,showHeatmap:o,showPortals:b,selectedPlayer:j})=>{var Ut;const M=g.useRef(null),N=g.useRef(null),[y,T]=g.useState({w:0,h:0}),[B,p]=g.useState(null),A=g.useRef(null),R=g.useRef({scale:1,offX:0,offY:0}),L=g.useRef({dragging:!1,sx:0,sy:0,startOffX:0,startOffY:0}),$=g.useCallback(()=>{if(N.current){const{scale:lt,offX:at,offY:Z}=R.current;N.current.style.transform=`translate(${at}px, ${Z}px) scale(${lt})`}},[]),V=g.useCallback(lt=>{const at=lt.currentTarget;if(T({w:at.naturalWidth,h:at.naturalHeight}),M.current){const Z=M.current.clientWidth,J=M.current.clientHeight,P=Math.min(Z/at.naturalWidth,J/at.naturalHeight);R.current={scale:P,offX:(Z-at.naturalWidth*P)/2,offY:(J-at.naturalHeight*P)/2},$()}},[$]),C=g.useCallback(lt=>{var Al;lt.preventDefault();const at=(Al=M.current)==null?void 0:Al.getBoundingClientRect();if(!at)return;const Z=R.current,J=lt.deltaY<0?1.1:.9,P=Math.min(Rd,Math.max(qd,Z.scale*J)),Rt=P/Z.scale,jt=lt.clientX-at.left,Ol=lt.clientY-at.top;R.current={scale:P,offX:jt-(jt-Z.offX)*Rt,offY:Ol-(Ol-Z.offY)*Rt},$()},[$]),Y=g.useCallback(lt=>{if(lt.button!==0)return;const at=R.current;L.current={dragging:!0,sx:lt.clientX,sy:lt.clientY,startOffX:at.offX,startOffY:at.offY}},[]);g.useEffect(()=>{const lt=Z=>{const J=L.current;if(J.dragging&&(R.current.offX=J.startOffX+(Z.clientX-J.sx),R.current.offY=J.startOffY+(Z.clientY-J.sy),$()),M.current&&y.w>0&&A.current){const P=M.current.getBoundingClientRect(),Rt=R.current,jt=R0(Z.clientX-P.left,Z.clientY-P.top,Rt.scale,Rt.offX,Rt.offY,y.w,y.h);A.current.textContent=gs(jt.ns,jt.ew)}},at=()=>{L.current.dragging=!1};return window.addEventListener("mousemove",lt),window.addEventListener("mouseup",at),()=>{window.removeEventListener("mousemove",lt),window.removeEventListener("mouseup",at)}},[$,y.w,y.h]);const F=g.useRef(null);g.useEffect(()=>{if(!j||y.w===0||!M.current||F.current===j)return;const lt=c.find(Rt=>Rt.character_name===j);if(!lt)return;F.current=j;const{x:at,y:Z}=Tn(lt.ew,lt.ns,y.w,y.h),J=M.current.getBoundingClientRect(),P=3;R.current={scale:Math.min(Rd,Math.max(qd,P)),offX:J.width/2-at*P,offY:J.height/2-Z*P},$()},[j,c,y.w,y.h,$]),g.useEffect(()=>{j||(F.current=null)},[j]);const zt=g.useCallback((lt,at,Z)=>{p(lt?{x:at,y:Z,player:lt}:null)},[]);return s.jsxs("div",{className:"ml-map-container",ref:M,onWheel:C,onMouseDown:Y,children:[s.jsxs("div",{ref:N,className:"ml-map-group",children:[s.jsx("img",{src:"/dereth.png",alt:"Dereth",className:"ml-map-img",onLoad:V,draggable:!1}),y.w>0&&s.jsxs(s.Fragment,{children:[s.jsx(L0,{imgW:y.w,imgH:y.h,enabled:o}),s.jsx(Qd,{imgW:y.w,imgH:y.h,getColor:r}),s.jsx(Gd,{players:c,imgW:y.w,imgH:y.h,getColor:r,onHover:zt,onSelect:m,selectedPlayer:j}),s.jsx(Y0,{imgW:y.w,imgH:y.h,enabled:b}),s.jsx(G0,{imgW:y.w,imgH:y.h})]})]}),B&&s.jsxs("div",{className:"ml-tooltip",style:{left:B.x+12,top:B.y-10},children:[s.jsx("strong",{children:B.player.character_name}),s.jsx("br",{}),gs(B.player.ns,B.player.ew),s.jsx("br",{}),B.player.kills_per_hour," kph · ",(Ut=B.player.kills)==null?void 0:Ut.toLocaleString()," kills"]}),s.jsx("div",{className:"ml-coords",ref:A})]})},Kd=jn.memo(({player:c,vitals:r,color:m,onSelect:o,isSelected:b})=>{var B,p;const{openWindow:j}=An(),M=(c.vt_state||"idle").toLowerCase(),N=M==="combat"||M==="hunt",y=(c.total_rares??0)>0?Math.round((c.total_kills??0)/(c.total_rares??1)).toLocaleString():null,T=c.character_name;return s.jsxs("li",{className:`ml-player-row ${b?"ml-player-selected":""}`,style:{borderLeftColor:m},children:[s.jsxs("div",{className:"ml-pr-header",onClick:o,children:[s.jsx("span",{className:"ml-pr-name",children:T}),s.jsx("span",{className:"ml-pr-coords",children:gs(c.ns,c.ew)})]}),s.jsxs("div",{className:"ml-pr-vitals",children:[s.jsx("div",{className:"ml-vital-bar hp",children:s.jsx("div",{className:"ml-vital-fill",style:{width:`${(r==null?void 0:r.health_percentage)??0}%`}})}),s.jsx("div",{className:"ml-vital-bar sta",children:s.jsx("div",{className:"ml-vital-fill",style:{width:`${(r==null?void 0:r.stamina_percentage)??0}%`}})}),s.jsx("div",{className:"ml-vital-bar mana",children:s.jsx("div",{className:"ml-vital-fill",style:{width:`${(r==null?void 0:r.mana_percentage)??0}%`}})})]}),s.jsxs("div",{className:"ml-pr-grid",children:[s.jsxs("span",{className:"ml-gs",title:"Session kills",children:["⚔️ ",((B=c.kills)==null?void 0:B.toLocaleString())??0]}),s.jsxs("span",{className:"ml-gs",title:"Total kills",children:["🏆 ",(c.total_kills??0).toLocaleString()]}),s.jsxs("span",{className:"ml-gs",title:"Kills per hour",children:[c.kills_per_hour??"0"," ",s.jsx("span",{className:"ml-suffix",children:"KPH"})]}),s.jsxs("span",{className:"ml-gs",title:"Rares (session / total)",children:["💎 ",c.session_rares??0," / ",c.total_rares??0]}),s.jsx("span",{className:"ml-gs",title:"Kills per rare",children:y?s.jsxs(s.Fragment,{children:["📊 ",y," ",s.jsx("span",{className:"ml-suffix",children:"KPR"})]}):""}),s.jsx("span",{className:`ml-meta-pill ${N?"active":M!=="idle"&&M!=="default"&&M!==""?"other":""}`,children:c.vt_state||"idle"}),s.jsxs("span",{className:"ml-gs",title:"Online time",children:["🕐 ",((p=c.onlinetime)==null?void 0:p.replace(/^00\./,""))??"--"]}),s.jsxs("span",{className:"ml-gs",title:"Deaths",children:["☠️ ",c.deaths??"0"]}),s.jsxs("span",{className:"ml-gs",title:"Prismatic tapers",children:[s.jsx("img",{src:"/prismatic-taper-icon.png",className:"ml-taper-icon",alt:""}),c.prismatic_taper_count??"0"]})]}),s.jsxs("div",{className:"ml-pr-buttons",children:[s.jsx("button",{className:"ml-btn accent",onClick:()=>j(`chat-${T}`,`Chat: ${T}`,T),children:"Chat"}),s.jsx("button",{className:"ml-btn accent",onClick:()=>j(`stats-${T}`,`Stats: ${T}`,T),children:"Stats"}),s.jsx("button",{className:"ml-btn accent",onClick:()=>j(`inv-${T}`,`Inventory: ${T}`,T),children:"Inv"}),s.jsx("button",{className:"ml-btn",onClick:()=>j(`char-${T}`,`Character: ${T}`,T),children:"Char"}),s.jsx("button",{className:"ml-btn",onClick:()=>j(`combat-${T}`,`Combat: ${T}`,T),children:"Combat"}),s.jsx("button",{className:"ml-btn",onClick:()=>j(`radar-${T}`,`Radar: ${T}`,T),children:"Radar"})]})]})});Kd.displayName="PlayerRow";const Z0=({players:c,vitals:r,getColor:m,onSelect:o,selectedPlayer:b})=>{const j=g.useRef(null),[M,N]=g.useState(!1),y=g.useCallback(()=>{j.current&&N(j.current.scrollTop>200)},[]);return s.jsxs("div",{style:{position:"relative",flex:1,minHeight:0},children:[s.jsx("ul",{className:"ml-player-list",ref:j,onScroll:y,children:c.map(T=>s.jsx(Kd,{player:T,vitals:r.get(T.character_name)??null,color:m(T.character_name),onSelect:()=>o(T.character_name),isSelected:b===T.character_name},T.character_name))}),M&&s.jsx("button",{onClick:()=>{var T;(T=j.current)==null||T.scrollTo({top:0,behavior:"smooth"})},style:{position:"absolute",bottom:8,right:8,width:28,height:28,borderRadius:"50%",background:"rgba(68,136,255,0.2)",border:"1px solid rgba(68,136,255,0.4)",color:"#6af",cursor:"pointer",fontSize:"0.8rem",display:"flex",alignItems:"center",justifyContent:"center"},children:"▲"})]})},K0=[{key:"name",label:"Name"},{key:"kph",label:"KPH"},{key:"skills",label:"S.Kills"},{key:"srares",label:"S.Rares"},{key:"tkills",label:"T.Kills"},{key:"kpr",label:"KPR"}],k0=({value:c,onChange:r})=>s.jsx("div",{className:"ml-sort-buttons",children:K0.map(m=>s.jsx("button",{className:`ml-sort-btn ${c===m.key?"active":""}`,onClick:()=>r(m.key),children:m.label},m.key))}),J0=()=>It("/live"),W0=()=>It("/combat-stats"),$0=()=>It("/server-health"),F0=()=>It("/total-rares"),I0=()=>It("/total-kills"),uv=(c,r)=>Ss("/agent/ask",{message:c,session_id:r}),iv=()=>Ss("/agent/sessions/new",{}),cv=c=>It(`/agent/sessions/${encodeURIComponent(c)}/history`),P0=()=>It("/me");async function ty(){await fetch("/api/logout",{credentials:"include",redirect:"manual"}),window.location.href="/login"}const sv=()=>It("/api-admin/users"),fv=(c,r,m)=>Ss("/api-admin/users",{username:c,password:r,is_admin:m}),rv=(c,r)=>q0(`/api-admin/users/${c}`,r),ov=c=>B0(`/api-admin/users/${c}`);function ly(){const[c,r]=g.useState(null),[m,o]=g.useState(!0);return g.useEffect(()=>{let b=!1;return P0().then(j=>{b||r(j)}).catch(()=>{b||r(null)}).finally(()=>{b||o(!1)}),()=>{b=!0}},[]),{user:c,loading:m}}const ey=()=>{const{openWindow:c}=An(),{user:r}=ly(),m=!!(r!=null&&r.is_admin),o=g.useCallback(async()=>{if(confirm("Log out?"))try{await ty()}catch{window.location.href="/login"}},[]);return s.jsxs("div",{className:"ml-tool-links",children:[s.jsx("span",{className:"ml-tool-link",style:{cursor:"pointer"},onClick:()=>c("agent","Overlord Assistant"),children:"🤖 Assistant"}),s.jsx("span",{className:"ml-tool-link",style:{cursor:"pointer"},title:"Opens the player dashboard in a new tab",onClick:()=>window.open("/?view=dashboard","_blank","noopener"),children:"👥 Dashboard ↗"}),s.jsx("span",{className:"ml-tool-link",style:{cursor:"pointer"},onClick:()=>c("queststatus","Quest Status"),children:"📜 Quests"}),s.jsx("span",{className:"ml-tool-link",style:{cursor:"pointer"},onClick:()=>c("issues","Issues Board"),children:"📋 Issues"}),s.jsx("span",{className:"ml-tool-link",style:{cursor:"pointer"},onClick:()=>c("vitalsharing","Vital Sharing"),children:"🤝 Vitals"}),s.jsx("span",{className:"ml-tool-link",style:{cursor:"pointer"},onClick:()=>c("combatpicker","Combat Stats"),children:"⚔️ Combat"}),m&&s.jsx("span",{className:"ml-tool-link",style:{cursor:"pointer"},onClick:()=>c("adminusers","Admin · Users"),children:"🛡️ Admin"}),s.jsxs("span",{className:"ml-tool-link ml-tool-link-logout",style:{cursor:"pointer"},onClick:o,title:r?`Logged in as ${r.username}`:"Log out",children:["🚪 Log out",r?` (${r.username})`:""]})]})},ay=({players:c,vitals:r,serverHealth:m,totalRares:o,totalKills:b,getColor:j,onSelectPlayer:M,showHeatmap:N,showPortals:y,onToggleHeatmap:T,onTogglePortals:B,version:p,selectedPlayer:A})=>{var lt,at;const[R,L]=g.useState("name"),[$,V]=g.useState(""),C=g.useMemo(()=>c.reduce((Z,J)=>Z+(parseInt(J.kills_per_hour)||0),0),[c]),Y=((lt=m==null?void 0:m.status)==null?void 0:lt.toLowerCase())==="online"||((at=m==null?void 0:m.status)==null?void 0:at.toLowerCase())==="up",F=g.useDeferredValue(c),zt=g.useDeferredValue(r),Ut=g.useMemo(()=>{let Z=[...F];switch($&&(Z=Z.filter(J=>J.character_name.toLowerCase().startsWith($.toLowerCase()))),R){case"kph":Z.sort((J,P)=>(parseInt(P.kills_per_hour)||0)-(parseInt(J.kills_per_hour)||0));break;case"skills":Z.sort((J,P)=>(P.kills||0)-(J.kills||0));break;case"srares":Z.sort((J,P)=>(P.session_rares??0)-(J.session_rares??0));break;case"tkills":Z.sort((J,P)=>(P.total_kills??0)-(J.total_kills??0));break;case"kpr":Z.sort((J,P)=>{const Rt=(J.total_kills??0)/Math.max(1,J.total_rares??1),jt=(P.total_kills??0)/Math.max(1,P.total_rares??1);return Rt-jt});break;default:Z.sort((J,P)=>J.character_name.localeCompare(P.character_name))}return Z},[F,R,$]);return s.jsxs("div",{className:"ml-sidebar",children:[p&&s.jsxs("div",{className:"ml-version",children:["v",p]}),s.jsx("div",{className:"ml-sidebar-header",children:s.jsxs("span",{className:"ml-sidebar-title",style:{cursor:"pointer"},onClick:()=>{const Z=document.createElement("div");Z.style.cssText="position:fixed;top:0;left:0;width:100vw;height:100vh;background:#000;z-index:999999;display:flex;align-items:center;justify-content:center;";const J=document.createElement("video");J.src="/rick.mp4",J.autoplay=!0,J.loop=!0,J.style.cssText="width:100vw;height:100vh;object-fit:cover;",Z.appendChild(J),document.body.appendChild(Z),document.body.style.animation="ml-shake 0.05s 30";const P=document.createElement("style");P.textContent="@keyframes ml-shake{0%,100%{transform:translate(0) rotate(0)}25%{transform:translate(-15px,10px) rotate(-2deg)}50%{transform:translate(15px,-10px) rotate(2deg)}75%{transform:translate(-10px,-15px) rotate(-1deg)}} @keyframes ml-spin{from{transform:rotate(0)}to{transform:rotate(360deg)}}",document.head.appendChild(P),setTimeout(()=>{Z.style.animation="ml-spin 3s linear infinite"},1500),J.play().catch(()=>{})},children:["Active Mosswart Enjoyers (",c.length,")"]})}),s.jsxs("div",{className:"ml-server-status",children:[s.jsx("span",{className:`ml-status-dot ${Y?"online":"offline"}`}),s.jsxs("span",{className:"ml-status-text",children:["Coldeve ",Y?"Online":"Offline"]}),(m==null?void 0:m.player_count)!=null&&s.jsxs("span",{className:"ml-status-detail",children:["👥 ",m.player_count]}),(m==null?void 0:m.latency_ms)!=null&&s.jsxs("span",{className:"ml-status-detail",children:[Math.round(m.latency_ms),"ms"]}),(m==null?void 0:m.uptime_seconds)!=null&&s.jsxs("span",{className:"ml-status-detail",children:["Up: ",Math.floor(m.uptime_seconds/3600),"h"]})]}),s.jsxs("div",{className:"ml-counters",children:[s.jsxs("div",{className:"ml-counter rares",children:[s.jsx("span",{className:"ml-counter-val",children:o}),s.jsx("span",{className:"ml-counter-lbl",children:"Rares"})]}),s.jsxs("div",{className:`ml-counter kph ${C>5e3?"ultra":""}`,children:[s.jsx("span",{className:"ml-counter-val",children:C.toLocaleString()}),s.jsx("span",{className:"ml-counter-lbl",children:"Server KPH"})]}),s.jsxs("div",{className:"ml-counter kills",children:[s.jsx("span",{className:"ml-counter-val",children:b.toLocaleString()}),s.jsx("span",{className:"ml-counter-lbl",children:"Kills"})]})]}),s.jsxs("div",{className:"ml-tool-links",children:[s.jsx("a",{href:"/?view=inventory",target:"_blank",className:"ml-tool-link",children:"🔍 Inv Search"}),s.jsx("a",{href:"/suitbuilder.html",target:"_blank",className:"ml-tool-link",children:"🛡️ Suitbuilder"}),s.jsx("a",{href:"/debug.html",target:"_blank",className:"ml-tool-link",children:"🐛 Debug"})]}),s.jsx(ey,{}),s.jsxs("div",{className:"ml-toggles",children:[s.jsxs("label",{className:"ml-toggle-label",children:[s.jsx("input",{type:"checkbox",checked:N,onChange:Z=>T(Z.target.checked)}),s.jsx("span",{children:"Spawn Heatmap"})]}),s.jsxs("label",{className:"ml-toggle-label",children:[s.jsx("input",{type:"checkbox",checked:y,onChange:Z=>B(Z.target.checked)}),s.jsx("span",{children:"Portals"})]})]}),s.jsx("div",{style:{borderTop:"1px solid #333",marginTop:4,paddingTop:4}}),s.jsx(k0,{value:R,onChange:L}),s.jsx("input",{className:"ml-filter",type:"text",placeholder:"Filter players...",value:$,onChange:Z=>V(Z.target.value)}),s.jsx(Z0,{players:Ut,vitals:zt,getColor:j,onSelect:M,selectedPlayer:A})]})},ny="modulepreload",uy=function(c){return"/"+c},Bd={},Sl=function(r,m,o){let b=Promise.resolve();if(m&&m.length>0){let M=function(T){return Promise.all(T.map(B=>Promise.resolve(B).then(p=>({status:"fulfilled",value:p}),p=>({status:"rejected",reason:p}))))};document.getElementsByTagName("link");const N=document.querySelector("meta[property=csp-nonce]"),y=(N==null?void 0:N.nonce)||(N==null?void 0:N.getAttribute("nonce"));b=M(m.map(T=>{if(T=uy(T),T in Bd)return;Bd[T]=!0;const B=T.endsWith(".css"),p=B?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${T}"]${p}`))return;const A=document.createElement("link");if(A.rel=B?"stylesheet":ny,B||(A.as="script"),A.crossOrigin="",A.href=T,y&&A.setAttribute("nonce",y),document.head.appendChild(A),B)return new Promise((R,L)=>{A.addEventListener("load",R),A.addEventListener("error",()=>L(new Error(`Unable to preload CSS for ${T}`)))})}))}function j(M){const N=new Event("vite:preloadError",{cancelable:!0});if(N.payload=M,window.dispatchEvent(N),!N.defaultPrevented)throw M}return b.then(M=>{for(const N of M||[])N.status==="rejected"&&j(N.reason);return r().catch(j)})},kd=({id:c,title:r,zIndex:m,width:o=700,height:b=340,children:j})=>{const{closeWindow:M,bringToFront:N}=An(),y=g.useRef(null),T=g.useRef({dragging:!1,sx:0,sy:0,ox:0,oy:0}),B=g.useRef({resizing:!1,sx:0,sy:0,sw:0,sh:0}),p=g.useRef({x:420,y:10+Math.random()*40}),[A,R]=g.useState({w:o,h:b}),L=g.useCallback(V=>{var Y;V.preventDefault(),N(c);const C=(Y=y.current)==null?void 0:Y.getBoundingClientRect();C&&(T.current={dragging:!0,sx:V.clientX,sy:V.clientY,ox:C.left,oy:C.top})},[c,N]),$=g.useCallback(V=>{V.preventDefault(),V.stopPropagation(),B.current={resizing:!0,sx:V.clientX,sy:V.clientY,sw:A.w,sh:A.h}},[A.w,A.h]);return g.useEffect(()=>{const V=Y=>{const F=T.current;F.dragging&&y.current&&(p.current.x=F.ox+(Y.clientX-F.sx),p.current.y=F.oy+(Y.clientY-F.sy),y.current.style.left=`${p.current.x}px`,y.current.style.top=`${p.current.y}px`);const zt=B.current;if(zt.resizing){const Ut=Math.max(300,zt.sw+(Y.clientX-zt.sx)),lt=Math.max(200,zt.sh+(Y.clientY-zt.sy));R({w:Ut,h:lt})}},C=()=>{T.current.dragging=!1,B.current.resizing=!1};return window.addEventListener("mousemove",V),window.addEventListener("mouseup",C),()=>{window.removeEventListener("mousemove",V),window.removeEventListener("mouseup",C)}},[]),s.jsxs("div",{ref:y,className:"ml-window",style:{zIndex:m,width:A.w,height:A.h,left:p.current.x,top:p.current.y},onMouseDown:()=>N(c),children:[s.jsxs("div",{className:"ml-window-header",onMouseDown:L,children:[s.jsx("span",{className:"ml-window-title",children:r}),s.jsx("button",{className:"ml-window-close",onClick:()=>M(c),children:"×"})]}),s.jsx("div",{className:"ml-window-content",children:j}),s.jsx("div",{className:"ml-window-resize",onMouseDown:$})]})},iy={0:"#00FF00",2:"#FFFFFF",3:"#FF0000",4:"#FFFFFF",5:"#33CCFF",6:"#CCFF99",7:"#00FFFF",14:"#FFD700",15:"#FF69B4",17:"#AAAAFF",18:"#88FF88",21:"#FF8888",22:"#FFAA66"},Jd=50,Wd=c=>`mo-chat-history-${c}`;function cy(c){try{const r=localStorage.getItem(Wd(c));return r?JSON.parse(r):[]}catch{return[]}}function sy(c,r){try{localStorage.setItem(Wd(c),JSON.stringify(r.slice(-Jd)))}catch{}}const fy=({id:c,charName:r,zIndex:m,messages:o,socket:b})=>{const j=g.useRef(null),[M,N]=g.useState(""),[y,T]=g.useState(!1),B=g.useRef(cy(r)),p=g.useRef(-1),A=g.useRef(""),R=g.useRef(!1);g.useEffect(()=>{const Y=j.current;Y&&(R.current?T(!0):(Y.scrollTop=Y.scrollHeight,T(!1)))},[o.length]);const L=g.useCallback(()=>{const Y=j.current;if(!Y)return;const F=Y.scrollHeight-Y.scrollTop-Y.clientHeight<30;R.current=!F,F&&T(!1)},[]),$=g.useCallback(()=>{const Y=j.current;Y&&(Y.scrollTop=Y.scrollHeight,R.current=!1,T(!1))},[]),V=g.useCallback(Y=>{Y.preventDefault();const F=M.trim();!F||!b||b.readyState!==WebSocket.OPEN||(b.send(JSON.stringify({player_name:r,command:F})),B.current.push(F),B.current.length>Jd&&B.current.shift(),sy(r,B.current),p.current=-1,A.current="",N(""),R.current=!1)},[M,b,r]),C=g.useCallback(Y=>{const F=B.current;if(F.length!==0){if(Y.key==="ArrowUp")Y.preventDefault(),p.current===-1?(A.current=M,p.current=F.length-1):p.current>0&&p.current--,N(F[p.current]);else if(Y.key==="ArrowDown"){if(Y.preventDefault(),p.current===-1)return;p.currents.jsx("div",{className:"ml-chat-line",style:{color:iy[Y.color??2]??"#ddd"},children:Y.text},F))}),y&&s.jsx("div",{onClick:$,style:{padding:"3px 0",textAlign:"center",fontSize:"0.65rem",color:"#6af",background:"#1a2a3a",cursor:"pointer",borderTop:"1px solid #334"},children:"▼ New messages below"}),s.jsx("form",{className:"ml-chat-form",onSubmit:V,children:s.jsx("input",{className:"ml-chat-input",value:M,onChange:Y=>N(Y.target.value),onKeyDown:C,placeholder:"Enter chat..."})})]})},ry=g.lazy(()=>Sl(()=>import("./StatsWindow-Dx7y3LW3.js"),__vite__mapDeps([0,1])).then(c=>({default:c.StatsWindow}))),oy=g.lazy(()=>Sl(()=>import("./CharacterWindow-Bm7Dvqbf.js"),__vite__mapDeps([2,1])).then(c=>({default:c.CharacterWindow}))),dy=g.lazy(()=>Sl(()=>import("./InventoryWindow-C3GJw7NT.js"),__vite__mapDeps([3,1])).then(c=>({default:c.InventoryWindow}))),my=g.lazy(()=>Sl(()=>import("./RadarWindow-Co69p423.js"),__vite__mapDeps([4,1])).then(c=>({default:c.RadarWindow}))),hy=g.lazy(()=>Sl(()=>import("./CombatStatsWindow-DrwSvkSn.js"),__vite__mapDeps([5,1])).then(c=>({default:c.CombatStatsWindow}))),yy=g.lazy(()=>Sl(()=>import("./CombatPickerWindow-CJZfow68.js"),__vite__mapDeps([6,1])).then(c=>({default:c.CombatPickerWindow}))),vy=g.lazy(()=>Sl(()=>import("./IssuesWindow-BdHPJVkp.js"),__vite__mapDeps([7,1])).then(c=>({default:c.IssuesWindow}))),gy=g.lazy(()=>Sl(()=>import("./VitalSharingWindow-DWghwvjH.js"),__vite__mapDeps([8,1])).then(c=>({default:c.VitalSharingWindow}))),py=g.lazy(()=>Sl(()=>import("./QuestStatusWindow-C1NaAFXp.js"),__vite__mapDeps([9,1])).then(c=>({default:c.QuestStatusWindow}))),by=g.lazy(()=>Sl(()=>Promise.resolve().then(()=>Dy),void 0).then(c=>({default:c.PlayerDashboardWindow}))),Sy=g.lazy(()=>Sl(()=>import("./AgentWindow-CMflyyRx.js"),__vite__mapDeps([10,1])).then(c=>({default:c.AgentWindow}))),xy=g.lazy(()=>Sl(()=>import("./AdminUsersWindow-CiWHpLWd.js"),__vite__mapDeps([11,1])).then(c=>({default:c.AdminUsersWindow}))),$d=jn.memo(({characters:c,chatMessages:r,nearbyObjects:m,inventoryVersions:o,equipmentCantrips:b,characterStats:j,socket:M})=>{const{windows:N}=An();return s.jsx(g.Suspense,{fallback:null,children:N.map(y=>{var p;const T=y.charName??"";switch(y.id.split("-")[0]){case"chat":return s.jsx(fy,{id:y.id,charName:T,zIndex:y.zIndex,messages:r.get(T)??[],socket:M},y.id);case"stats":return s.jsx(ry,{id:y.id,charName:T,zIndex:y.zIndex},y.id);case"char":return s.jsx(oy,{id:y.id,charName:T,zIndex:y.zIndex,vitals:((p=c.get(T))==null?void 0:p.vitals)??void 0,liveStats:j.get(T)},y.id);case"inv":return s.jsx(dy,{id:y.id,charName:T,zIndex:y.zIndex,inventoryVersion:o.get(T)??0,equipmentCantrips:b.get(T)},y.id);case"radar":return s.jsx(my,{id:y.id,charName:T,zIndex:y.zIndex,socket:M,radarData:m.get(T)??null},y.id);case"combat":return s.jsx(hy,{id:y.id,charName:T,zIndex:y.zIndex},y.id);case"combatpicker":return s.jsx(yy,{id:y.id,zIndex:y.zIndex,characters:c},y.id);case"issues":return s.jsx(vy,{id:y.id,zIndex:y.zIndex},y.id);case"vitalsharing":return s.jsx(gy,{id:y.id,zIndex:y.zIndex},y.id);case"queststatus":return s.jsx(py,{id:y.id,zIndex:y.zIndex},y.id);case"playerdash":return s.jsx(by,{id:y.id,zIndex:y.zIndex,characters:c},y.id);case"agent":return s.jsx(Sy,{id:y.id,zIndex:y.zIndex},y.id);case"adminusers":return s.jsx(xy,{id:y.id,zIndex:y.zIndex},y.id);default:return null}})})});$d.displayName="WindowRenderer";let _y=0;const zy=({recentRares:c})=>{const[r,m]=g.useState([]),[o,b]=g.useState(0),[j,M]=g.useState([]);g.useEffect(()=>{if(c.length>o&&o>0){const y=c.slice(0,c.length-o);for(const T of y){const B=++_y;m(p=>[...p,{key:B,charName:T.character_name,rareName:T.name,exiting:!1}]),N();try{const p=new AudioContext,A=p.createOscillator(),R=p.createGain();A.connect(R),R.connect(p.destination),A.frequency.value=880,A.type="sine",R.gain.value=.3,A.start(),R.gain.exponentialRampToValueAtTime(.001,p.currentTime+.5),A.stop(p.currentTime+.5)}catch{}setTimeout(()=>{m(p=>p.map(A=>A.key===B?{...A,exiting:!0}:A)),setTimeout(()=>{m(p=>p.filter(A=>A.key!==B))},500)},6e3)}}b(c.length)},[c.length]);const N=g.useCallback(()=>{const y=Date.now(),T=["#FFD700","#FF4444","#FF8800","#AA44FF","#4488FF"],B=Array.from({length:30},(p,A)=>{const R=Math.PI*2*A/30+(Math.random()-.5)*.5,L=100+Math.random()*200;return{dx:Math.cos(R)*L,dy:Math.sin(R)*L-50,color:T[Math.floor(Math.random()*T.length)]}});M(p=>[...p,{id:y,particles:B}]),setTimeout(()=>M(p=>p.filter(A=>A.id!==y)),2200)},[]);return s.jsxs(s.Fragment,{children:[s.jsx("div",{className:"ml-rare-notifications",children:r.map(y=>s.jsxs("div",{className:`ml-rare-notif ${y.exiting?"exiting":""}`,children:[s.jsx("div",{className:"ml-rare-notif-title",children:"🎆 LEGENDARY RARE! 🎆"}),s.jsx("div",{className:"ml-rare-notif-name",children:y.rareName}),s.jsx("div",{className:"ml-rare-notif-by",children:"found by"}),s.jsx("div",{className:"ml-rare-notif-char",children:y.charName})]},y.key))}),s.jsx("div",{className:"ml-fireworks",children:j.map(y=>s.jsx(jn.Fragment,{children:y.particles.map((T,B)=>s.jsx("div",{className:"ml-firework-particle",style:{left:"50%",top:"30%",backgroundColor:T.color,"--dx":`${T.dx}px`,"--dy":`${T.dy+200}px`}},B))},y.id))})]})};let jy=0;const Ay=({deathAlerts:c})=>{const[r,m]=g.useState([]),o=g.useRef(0);return g.useEffect(()=>{if(c.length>o.current&&o.current>0){const b=c.slice(o.current);for(const j of b){const M=++jy;m(N=>[...N,{key:M,alert:j,exiting:!1}]);try{const N=new AudioContext,y=N.createOscillator(),T=N.createGain();y.connect(T),T.connect(N.destination),y.frequency.value=440,y.type="sawtooth",T.gain.value=.2,y.start(),T.gain.exponentialRampToValueAtTime(.001,N.currentTime+.8),y.stop(N.currentTime+.8)}catch{}setTimeout(()=>{m(N=>N.map(y=>y.key===M?{...y,exiting:!0}:y)),setTimeout(()=>m(N=>N.filter(y=>y.key!==M)),500)},8e3)}}o.current=c.length},[c.length]),r.length===0?null:s.jsx("div",{style:{position:"fixed",top:70,left:"50%",transform:"translateX(-50%)",zIndex:99999,display:"flex",flexDirection:"column",gap:6,pointerEvents:"none"},children:r.map(b=>s.jsxs("div",{style:{background:"linear-gradient(135deg, #2a0a0a, #1a0000)",border:"2px solid #cc4444",borderRadius:8,padding:"12px 24px",textAlign:"center",boxShadow:"0 0 30px rgba(204, 68, 68, 0.3)",animation:b.exiting?"ml-notif-out 0.5s ease-in forwards":"ml-notif-in 0.5s ease-out"},children:[s.jsx("div",{style:{fontSize:"1.2rem",fontWeight:800,color:"#ff4444"},children:"☠️ CHARACTER DIED ☠️"}),s.jsx("div",{style:{fontSize:"1rem",fontWeight:600,color:"#fff",marginTop:2},children:b.alert.character_name}),s.jsxs("div",{style:{fontSize:"0.8rem",color:"#c88",marginTop:2},children:["Vitae: ",b.alert.vitae,"%"]})]},b.key))})},Hd=["#1f77b4","#ff7f0e","#2ca02c","#d62728","#9467bd","#8c564b","#e377c2","#7f7f7f","#bcbd22","#17becf","#ff4444","#44ff44","#4444ff","#ffff44","#ff44ff","#44ffff","#ff8844","#88ff44","#4488ff","#ff4488","#cc3333","#33cc33","#3333cc","#cccc33","#cc33cc","#33cccc","#cc6633","#66cc33","#3366cc","#cc3366","#ff6666","#66ff66","#6666ff","#ffff66","#ff66ff","#66ffff","#ffaa66","#aaff66","#66aaff","#ff66aa","#990099","#009900","#000099","#990000","#009999","#999900","#aa5500","#55aa00","#0055aa","#aa0055","#ffaaaa","#aaffaa","#aaaaff","#ffffaa","#ffaaff","#aaffff","#ffccaa","#ccffaa","#aaccff","#ffaacc"];function Ty(c){let r=0;for(let m=0;m{let b=c.current.get(o);return b||(b=r.current{const{enabled:c}=xs();return c?s.jsx("div",{className:"ms-banner",role:"status",children:"🐸 Glad midsommar! 🌼 Små grodorna, små grodorna… 🥂"}):null},Ld=["🐸","🌼","🌸","🇸🇪","🌿"],Id=()=>{const{enabled:c}=xs();return g.useEffect(()=>{if(!c||window.matchMedia("(prefers-reduced-motion: reduce)").matches)return;const r=document.createElement("div");r.className="ms-rain",document.body.appendChild(r);const m=()=>{const b=document.createElement("span");b.textContent=Ld[Math.floor(Math.random()*Ld.length)],b.style.left=Math.floor(Math.random()*100)+"vw";const j=6+Math.random()*5;b.style.animationDuration=j.toFixed(2)+"s",b.style.fontSize=14+Math.floor(Math.random()*16)+"px",r.appendChild(b),window.setTimeout(()=>b.remove(),j*1e3+250)},o=window.setInterval(m,450);return()=>{window.clearInterval(o),r.remove()}},[c]),null},Ny=({data:c})=>{const r=Ey(),[m,o]=g.useState(!1),[b,j]=g.useState(!1),[M,N]=g.useState(null),y=g.useMemo(()=>Array.from(c.characters.values()).filter(R=>R.telemetry).map(R=>R.telemetry),[c.characters]),T=g.useMemo(()=>new Map(Array.from(c.characters.values()).filter(R=>R.vitals).map(R=>[R.name,R.vitals])),[c.characters]),[B,p]=g.useState("");g.useEffect(()=>{fetch("/api/api-version",{credentials:"include"}).then(R=>R.json()).then(R=>p(R.version??"")).catch(()=>{})},[]);const A=g.useCallback(R=>{N(L=>L===R?null:R)},[]);return s.jsx(U0,{children:s.jsxs("div",{className:"ml-layout",children:[s.jsx(Fd,{}),s.jsx(Id,{}),s.jsx(ay,{players:y,vitals:T,serverHealth:c.serverHealth,totalRares:c.totalRares,totalKills:c.totalKills,getColor:r,onSelectPlayer:A,showHeatmap:m,showPortals:b,onToggleHeatmap:o,onTogglePortals:j,version:B,selectedPlayer:M}),s.jsx(Q0,{players:y,getColor:r,onSelectPlayer:A,showHeatmap:m,showPortals:b,selectedPlayer:M}),s.jsx($d,{characters:c.characters,chatMessages:c.chatMessages,nearbyObjects:c.nearbyObjects,inventoryVersions:c.inventoryVersions,equipmentCantrips:c.equipmentCantrips,characterStats:c.characterStats,socket:c.socketRef.current}),s.jsx(zy,{recentRares:c.recentRares}),s.jsx(Ay,{deathAlerts:c.deathAlerts})]})})};function My(c){const r=g.useRef(null),m=g.useRef(0),o=g.useRef(c);o.current=c;const b=g.useCallback(()=>{var M;if(((M=r.current)==null?void 0:M.readyState)===WebSocket.OPEN)return;const j=new WebSocket(H0());r.current=j,j.addEventListener("message",N=>{try{const y=JSON.parse(N.data);o.current(y)}catch{}}),j.addEventListener("close",()=>{r.current=null,m.current=window.setTimeout(b,2e3)}),j.addEventListener("error",()=>{j.close()})},[]);return g.useEffect(()=>(b(),()=>{var j;clearTimeout(m.current),(j=r.current)==null||j.close(),r.current=null}),[b]),r}function Pd(){const[c,r]=g.useState(new Map),[m,o]=g.useState(null),[b,j]=g.useState(0),[M,N]=g.useState(0),[y,T]=g.useState([]),B=g.useRef(new Map),[p,A]=g.useState(0),[R,L]=g.useState(new Map),$=g.useRef(new Map),[V,C]=g.useState(0),Y=g.useRef(new Map),[F,zt]=g.useState(0),[Ut,lt]=g.useState([]),[at,Z]=g.useState(new Map),J=g.useRef(c);J.current=c;const P=g.useCallback((_,q)=>{r(Q=>{const H=new Map(Q),w=H.get(_)??{name:_,telemetry:null,vitals:null,combat:null,lastUpdate:0};return H.set(_,q(w)),H})},[]),Rt=g.useCallback(_=>{var q,Q;if(_.type){if(_.type==="telemetry"){const H=_;P(H.character_name,w=>({...w,telemetry:H,lastUpdate:Date.now()}))}else if(_.type==="vitals"){const H=_,w=(q=J.current.get(H.character_name))==null?void 0:q.vitals;w&&(w.vitae??0)===0&&(H.vitae??0)>0&<(ot=>[...ot,{character_name:H.character_name,vitae:H.vitae,timestamp:new Date().toISOString()}].slice(-50)),P(H.character_name,ot=>({...ot,vitals:H,lastUpdate:Date.now()}))}else if(_.type==="combat_stats"){const H=_;P(H.character_name,w=>({...w,combat:H,lastUpdate:Date.now()}))}else if(_.type==="rare"){const H=_;T(w=>[H,...w].slice(0,50))}else if(_.type==="inventory_delta"){const H=_;H.character_name&&L(w=>{const ot=new Map(w);return ot.set(H.character_name,(ot.get(H.character_name)??0)+1),ot})}else if(_.type==="character_stats"){const H=_;Y.current.set(H.character_name,_),zt(w=>w+1)}else if(_.type==="equipment_cantrip_state"){const H=_;$.current.set(H.character_name,H),C(w=>w+1)}else if(_.type==="dungeon_map"){const H=_;H.landblock&&(window.__dungeonMapCache||(window.__dungeonMapCache={}),window.__dungeonMapCache[H.landblock]=H)}else if(_.type==="nearby_objects"){const H=_;if(Z(w=>{const ot=new Map(w);return ot.set(H.character_name,H),ot}),H.is_dungeon&&H.landblock&&!((Q=window.__dungeonMapCache)!=null&&Q[H.landblock])){const w=jt.current;(w==null?void 0:w.readyState)===WebSocket.OPEN&&w.send(JSON.stringify({type:"request_dungeon_map",landblock:H.landblock}))}}else if(_.type==="chat"){const H=_,w=B.current.get(H.character_name)??[];w.push({text:H.text,color:H.color,timestamp:H.timestamp}),w.length>1e3&&w.splice(0,w.length-1e3),B.current.set(H.character_name,w),A(ot=>ot+1)}}},[P]),jt=My(Rt);g.useEffect(()=>{const _=async()=>{try{const Q=await J0();r(H=>{var ot;const w=new Map(H);for(const dt of Q.players??[]){const et=w.get(dt.character_name);w.set(dt.character_name,{name:dt.character_name,telemetry:dt,vitals:(et==null?void 0:et.vitals)??null,combat:(et==null?void 0:et.combat)??null,lastUpdate:Date.now()})}for(const dt of w.keys())(ot=Q.players)!=null&&ot.some(et=>et.character_name===dt)||w.delete(dt);return w})}catch{}};_();const q=setInterval(_,5e3);return()=>clearInterval(q)},[]),g.useEffect(()=>{const _=async()=>{try{const Q=await W0();for(const H of Q.stats??[])P(H.character_name,w=>({...w,combat:{...H,type:"combat_stats"}}))}catch{}};_();const q=setInterval(_,3e4);return()=>clearInterval(q)},[P]),g.useEffect(()=>{const _=async()=>{try{o(await $0())}catch{}};_();const q=setInterval(_,3e4);return()=>clearInterval(q)},[]),g.useEffect(()=>{const _=async()=>{try{const[Q,H]=await Promise.all([F0(),I0()]);j(Q.all_time??0),N(H.total??0)}catch{}};_();const q=setInterval(_,3e5);return()=>clearInterval(q)},[]);const Ol=g.useMemo(()=>B.current,[p]),Al=g.useMemo(()=>$.current,[V]),xl=g.useMemo(()=>Y.current,[F]);return{characters:c,serverHealth:m,totalRares:b,totalKills:M,recentRares:y,chatMessages:Ol,nearbyObjects:at,inventoryVersions:R,equipmentCantrips:Al,characterStats:xl,deathAlerts:Ut,socketRef:jt}}const _s=({characters:c})=>{const[r,m]=g.useState("kph"),[o,b]=g.useState(!1),[j,M]=g.useState(null),N=g.useMemo(()=>{const p=Array.from(c.values()).filter(A=>A.telemetry).map(A=>{var L,$,V;const R=A.telemetry;return{name:A.name,kills:R.kills??0,kph:parseInt(R.kills_per_hour)||0,totalKills:R.total_kills??0,rares:R.total_rares??0,sessionRares:R.session_rares??0,deaths:parseInt(R.deaths)||0,totalDeaths:parseInt(R.total_deaths)||0,uptime:((L=R.onlinetime)==null?void 0:L.replace(/^00\./,""))??"",state:R.vt_state??"idle",tapers:parseInt(R.prismatic_taper_count)||0,hp:(($=A.vitals)==null?void 0:$.health_percentage)??0,vitae:((V=A.vitals)==null?void 0:V.vitae)??0}});return p.sort((A,R)=>{let L=0;switch(r){case"name":L=A.name.localeCompare(R.name);break;case"kills":L=A.kills-R.kills;break;case"kph":L=A.kph-R.kph;break;case"rares":L=A.rares-R.rares;break;case"deaths":L=A.totalDeaths-R.totalDeaths;break;case"uptime":L=A.uptime.localeCompare(R.uptime);break;case"state":L=A.state.localeCompare(R.state);break}return o?L:-L}),p},[c,r,o]),y=p=>{r===p?b(!o):(m(p),b(!1))},T=p=>({padding:"4px 6px",cursor:"pointer",userSelect:"none",color:r===p?"#6af":"#888",fontSize:"0.65rem",fontWeight:600,whiteSpace:"nowrap",borderBottom:"1px solid #444"}),B=p=>r===p?o?" ▲":" ▼":"";return s.jsxs("div",{style:{flex:1,overflow:"auto",fontSize:"0.73rem"},children:[s.jsxs("table",{style:{width:"auto",borderCollapse:"collapse"},children:[s.jsx("thead",{children:s.jsxs("tr",{style:{position:"sticky",top:0,background:"#1a1a1a",zIndex:1},children:[s.jsxs("th",{style:{...T("name"),textAlign:"left"},onClick:()=>y("name"),children:["Character",B("name")]}),s.jsxs("th",{style:{...T("state"),textAlign:"center"},onClick:()=>y("state"),children:["State",B("state")]}),s.jsxs("th",{style:{...T("kph"),textAlign:"right"},onClick:()=>y("kph"),children:["KPH",B("kph")]}),s.jsxs("th",{style:{...T("kills"),textAlign:"right"},onClick:()=>y("kills"),children:["Session",B("kills")]}),s.jsx("th",{style:{textAlign:"right",padding:"4px 6px",color:"#888",fontSize:"0.65rem",fontWeight:600,borderBottom:"1px solid #444"},children:"Total"}),s.jsxs("th",{style:{...T("rares"),textAlign:"right"},onClick:()=>y("rares"),children:["Rares",B("rares")]}),s.jsxs("th",{style:{...T("deaths"),textAlign:"right"},onClick:()=>y("deaths"),children:["Deaths",B("deaths")]}),s.jsxs("th",{style:{...T("uptime"),textAlign:"right"},onClick:()=>y("uptime"),children:["Uptime",B("uptime")]}),s.jsx("th",{style:{textAlign:"right",padding:"4px 6px",color:"#888",fontSize:"0.65rem",fontWeight:600,borderBottom:"1px solid #444"},children:"HP%"}),s.jsx("th",{style:{textAlign:"right",padding:"4px 6px",color:"#888",fontSize:"0.65rem",fontWeight:600,borderBottom:"1px solid #444"},children:"Vitae"}),s.jsx("th",{style:{textAlign:"right",padding:"4px 6px",color:"#888",fontSize:"0.65rem",fontWeight:600,borderBottom:"1px solid #444"},children:"Tapers"})]})}),s.jsx("tbody",{children:N.map(p=>{const A=p.state.toLowerCase(),R=A==="combat"||A==="hunt",L=j===p.name;return s.jsxs("tr",{onClick:()=>M(L?null:p.name),style:{borderBottom:"1px solid #1a1a1a",cursor:"pointer",background:L?"rgba(102, 170, 255, 0.18)":void 0,outline:L?"1px solid rgba(102, 170, 255, 0.55)":void 0,outlineOffset:"-1px"},children:[s.jsx("td",{style:{padding:"3px 10px 3px 6px",color:"#ccc",fontWeight:500,whiteSpace:"nowrap"},children:p.name}),s.jsx("td",{style:{textAlign:"center",padding:"3px 6px"},children:s.jsx("span",{style:{fontSize:"0.6rem",padding:"1px 6px",borderRadius:3,background:R?"rgba(68,204,68,0.15)":A==="idle"||A==="default"?"rgba(100,100,100,0.2)":"rgba(204,68,68,0.15)",color:R?"#4c4":A==="idle"||A==="default"?"#888":"#c44"},children:p.state})}),s.jsx("td",{style:{textAlign:"right",padding:"3px 6px",color:"#4c4",fontVariantNumeric:"tabular-nums"},children:p.kph.toLocaleString()}),s.jsx("td",{style:{textAlign:"right",padding:"3px 6px",color:"#ccc",fontVariantNumeric:"tabular-nums"},children:p.kills.toLocaleString()}),s.jsx("td",{style:{textAlign:"right",padding:"3px 6px",color:"#888",fontVariantNumeric:"tabular-nums"},children:p.totalKills.toLocaleString()}),s.jsxs("td",{style:{textAlign:"right",padding:"3px 6px",color:"#fc0",fontVariantNumeric:"tabular-nums"},children:[p.rares,p.sessionRares>0?` (${p.sessionRares})`:""]}),s.jsx("td",{style:{textAlign:"right",padding:"3px 6px",color:p.totalDeaths>0?"#c66":"#555",fontVariantNumeric:"tabular-nums"},children:p.totalDeaths}),s.jsx("td",{style:{textAlign:"right",padding:"3px 6px",color:"#888",fontVariantNumeric:"tabular-nums"},children:p.uptime}),s.jsxs("td",{style:{textAlign:"right",padding:"3px 6px",fontVariantNumeric:"tabular-nums",color:p.hp>80?"#4c4":p.hp>40?"#ca0":"#c44"},children:[p.hp.toFixed(0),"%"]}),s.jsx("td",{style:{textAlign:"right",padding:"3px 6px",fontVariantNumeric:"tabular-nums",color:p.vitae>0?"#f66":"#333"},children:p.vitae>0?`${p.vitae}%`:""}),s.jsx("td",{style:{textAlign:"right",padding:"3px 6px",color:"#888",fontVariantNumeric:"tabular-nums"},children:p.tapers.toLocaleString()})]},p.name)})})]}),N.length===0&&s.jsx("div",{style:{padding:20,color:"#666",textAlign:"center"},children:"No characters online"})]})},Cy=({id:c,zIndex:r,characters:m})=>s.jsx(kd,{id:c,title:"Player Dashboard",zIndex:r,width:850,height:500,children:s.jsx(_s,{characters:m})}),Dy=Object.freeze(Object.defineProperty({__proto__:null,PlayerDashboardContent:_s,PlayerDashboardWindow:Cy},Symbol.toStringTag,{value:"Module"})),Oy=()=>{const c=Pd(),[r,m]=g.useState("");g.useEffect(()=>{const b=document.title;return document.title="Overlord Dashboard",()=>{document.title=b}},[]),g.useEffect(()=>{fetch("/api/api-version",{credentials:"include"}).then(b=>b.json()).then(b=>m(b.version??"")).catch(()=>{})},[]);const o=Array.from(c.characters.values()).filter(b=>b.telemetry).length;return s.jsxs("div",{className:"ml-dashboard-page",children:[s.jsx(Fd,{}),s.jsx(Id,{}),s.jsxs("header",{className:"ml-dashboard-header",children:[s.jsx("span",{className:"ml-dashboard-title",children:"👥 Player Dashboard"}),s.jsxs("span",{className:"ml-dashboard-count",children:[o," online"]}),s.jsx("span",{style:{flex:1}}),r&&s.jsxs("span",{className:"ml-dashboard-version",children:["v",r]})]}),s.jsx("main",{className:"ml-dashboard-main",children:s.jsx(_s,{characters:c.characters})})]})},je={text:"",characters:"all",itemType:"all",weaponType:"",slots:[],cantrips:[],spellContains:"",ratings:{},itemSet:"",equipStatus:"",bonded:!1,attuned:!1,rare:!1,maxLevel:"",minValue:"",minWorkmanship:"",maxBurden:"",sortBy:"name",sortDir:"asc",page:1},W=c=>({value:c,label:c.replace(/^Legendary /,"")}),Uy=[{group:"Attributes",items:[W("Legendary Strength"),W("Legendary Endurance"),W("Legendary Quickness"),W("Legendary Coordination"),W("Legendary Willpower"),W("Legendary Focus")]},{group:"Weapon skills",items:[W("Legendary Heavy Weapon Aptitude"),W("Legendary Light Weapon Aptitude"),W("Legendary Finesse Weapon Aptitude"),W("Legendary Missile Weapon Aptitude"),W("Legendary Two Handed Combat Aptitude"),W("Legendary Dual Wield Aptitude"),W("Legendary Shield Aptitude"),W("Legendary Sneak Attack Prowess"),W("Legendary Dirty Fighting Prowess"),W("Legendary Recklessness Prowess"),W("Legendary Defender"),W("Legendary Blood Thirst")]},{group:"Magic",items:[W("Legendary War Magic Aptitude"),W("Legendary Void Magic Aptitude"),W("Legendary Creature Enchantment Aptitude"),W("Legendary Item Enchantment Aptitude"),W("Legendary Life Magic Aptitude"),W("Legendary Mana Conversion Prowess"),W("Legendary Arcane Prowess"),W("Legendary Hermetic Link"),W("Legendary Spirit Thirst"),W("Legendary Magic Resistance")]},{group:"Utility",items:[W("Legendary Summoning Prowess"),W("Legendary Healing Prowess"),W("Legendary Leadership"),W("Legendary Deception Prowess"),W("Legendary Person Attunement"),W("Legendary Magic Item Tinkering Expertise")]},{group:"Defense",items:[W("Legendary Invulnerability"),W("Legendary Impenetrability"),W("Legendary Impregnability"),W("Legendary Armor")]},{group:"Wards & Banes",items:[W("Legendary Flame Ward"),W("Legendary Frost Ward"),W("Legendary Acid Ward"),W("Legendary Storm Ward"),W("Legendary Slashing Ward"),W("Legendary Piercing Ward"),W("Legendary Bludgeoning Ward"),W("Legendary Piercing Bane"),W("Legendary Storm Bane")]}],Ry=["Ring","Bracelet","Neck","Trinket","Cloak"],qy=["Head","Chest","Abdomen","Upper Arms","Lower Arms","Hands","Upper Legs","Lower Legs","Feet","Shield"],By=[{value:"",label:"All weapons"},{value:"heavy",label:"Heavy"},{value:"light",label:"Light"},{value:"finesse",label:"Finesse"},{value:"two_handed",label:"Two-handed"},{value:"bow",label:"Bow"},{value:"crossbow",label:"Crossbow"},{value:"thrown",label:"Thrown"},{value:"caster",label:"Wand/Staff/Orb"}],ps=[{param:"min_damage_rating",label:"Damage rating",common:!0},{param:"min_crit_damage_rating",label:"Crit damage",common:!0},{param:"min_heal_boost_rating",label:"Heal boost",common:!0},{param:"min_vitality_rating",label:"Vitality",common:!0},{param:"min_armor",label:"Armor level"},{param:"min_damage_resist_rating",label:"Damage resist"},{param:"min_crit_resist_rating",label:"Crit resist"},{param:"min_crit_damage_resist_rating",label:"Crit dmg resist"},{param:"min_healing_resist_rating",label:"Healing resist"},{param:"min_nether_resist_rating",label:"Nether resist"},{param:"min_healing_rating",label:"Healing rating"},{param:"min_dot_resist_rating",label:"DoT resist"},{param:"min_life_resist_rating",label:"Life resist"},{param:"min_sneak_attack_rating",label:"Sneak attack"},{param:"min_recklessness_rating",label:"Recklessness"},{param:"min_deception_rating",label:"Deception"},{param:"min_pk_damage_rating",label:"PK damage"},{param:"min_pk_damage_resist_rating",label:"PK dmg resist"},{param:"min_gear_pk_damage_rating",label:"Gear PK dmg"},{param:"min_gear_pk_damage_resist_rating",label:"Gear PK resist"},{param:"min_tinks",label:"Tinks"}],bs=[{key:"name",label:"Item",sortKey:"name",defaultVisible:!0},{key:"character_name",label:"Character",sortKey:"character_name",defaultVisible:!0},{key:"slot_name",label:"Slot",defaultVisible:!0},{key:"value",label:"Value",sortKey:"value",defaultVisible:!0},{key:"wield_level",label:"Wield",sortKey:"level",defaultVisible:!0},{key:"spell_names",label:"Spells / Cantrips",sortKey:"spell_names",defaultVisible:!0},{key:"armor_level",label:"Armor",sortKey:"armor",defaultVisible:!1},{key:"max_damage",label:"Max Dmg",sortKey:"damage",defaultVisible:!1},{key:"workmanship",label:"Work",sortKey:"workmanship",defaultVisible:!1},{key:"item_set_name",label:"Set",sortKey:"item_set",defaultVisible:!1},{key:"object_class_name",label:"Type",sortKey:"item_type_name",defaultVisible:!1},{key:"burden",label:"Burden",defaultVisible:!1},{key:"condition_percent",label:"Cond %",defaultVisible:!1},{key:"last_updated",label:"Updated",sortKey:"last_updated",defaultVisible:!1}],Hy=200,tm="inv.visibleColumns";function Ly(c){const r={};for(const o of Object.keys(je))JSON.stringify(c[o])!==JSON.stringify(je[o])&&(r[o]=c[o]);const m=new URL(window.location.href);m.searchParams.set("view","inventory"),Object.keys(r).length?m.searchParams.set("q",JSON.stringify(r)):m.searchParams.delete("q");try{window.history.replaceState(null,"",m)}catch{}}const Yy=new Set(["all","armor","jewelry","weapon","clothing","shirt","pants"]),Vy=new Set(["asc","desc"]);function Yd(c){return Array.isArray(c)&&c.every(r=>typeof r=="string")}function Xy(c,r){switch(c){case"characters":return r==="all"||Yd(r)?r:void 0;case"slots":case"cantrips":return Yd(r)?r:void 0;case"itemType":return typeof r=="string"&&Yy.has(r)?r:void 0;case"sortDir":return typeof r=="string"&&Vy.has(r)?r:void 0;case"ratings":{if(typeof r!="object"||r===null||Array.isArray(r))return;const m={};for(const[o,b]of Object.entries(r))(b===""||typeof b=="number")&&(m[o]=b);return m}case"text":case"weaponType":case"spellContains":case"itemSet":case"sortBy":return typeof r=="string"?r:void 0;case"equipStatus":return r===""||r==="equipped"||r==="unequipped"?r:void 0;case"bonded":case"attuned":case"rare":return typeof r=="boolean"?r:void 0;case"maxLevel":case"minValue":case"minWorkmanship":case"maxBurden":return r===""||typeof r=="number"?r:void 0;case"page":return typeof r=="number"&&Number.isInteger(r)&&r>0?r:void 0;default:return}}function wy(){try{const c=new URLSearchParams(window.location.search).get("q");if(!c)return je;const r=JSON.parse(c);if(typeof r!="object"||r===null||Array.isArray(r))return je;const m={...je};for(const o of Object.keys(je)){if(!(o in r))continue;const b=Xy(o,r[o]);b!==void 0&&(m[o]=b)}return m}catch{return je}}function Gy(c){const r=new URLSearchParams;switch(c.characters==="all"?r.set("include_all_characters","true"):c.characters.length===1?r.set("character",c.characters[0]):r.set("characters",c.characters.join(",")),c.text&&r.set("text",c.text),c.itemType){case"armor":r.set("armor_only","true");break;case"jewelry":r.set("jewelry_only","true");break;case"clothing":r.set("clothing_only","true");break;case"shirt":r.set("shirt_only","true");break;case"pants":r.set("pants_only","true");break;case"weapon":r.set("weapon_only","true"),c.weaponType&&r.set("weapon_type",c.weaponType);break}c.slots.length&&r.set("slot_names",c.slots.join(",")),c.cantrips.length&&r.set("legendary_cantrips",c.cantrips.join(",")),c.spellContains&&r.set("spell_contains",c.spellContains);for(const[m,o]of Object.entries(c.ratings))o!==""&&r.set(m,String(o));return c.itemSet&&r.set("item_set",c.itemSet),c.equipStatus&&r.set("equipment_status",c.equipStatus),c.bonded&&r.set("bonded","true"),c.attuned&&r.set("attuned","true"),c.rare&&r.set("is_rare","true"),c.maxLevel!==""&&r.set("max_level",String(c.maxLevel)),c.minValue!==""&&r.set("min_value",String(c.minValue)),c.minWorkmanship!==""&&r.set("min_workmanship",String(c.minWorkmanship)),c.maxBurden!==""&&r.set("max_burden",String(c.maxBurden)),r.set("sort_by",c.sortBy),r.set("sort_dir",c.sortDir),r.set("page",String(c.page)),r.set("limit",String(Hy)),r}function Qy(){const[c,r]=g.useState(wy),[m,o]=g.useState(null),[b,j]=g.useState(!1),[M,N]=g.useState(null),[y,T]=g.useState(null),B=g.useRef(null),p=g.useCallback(R=>{r(L=>({...L,page:"page"in R?L.page:1,...R}))},[]),A=g.useCallback(()=>r(je),[]);return g.useEffect(()=>{const R=setTimeout(async()=>{var V;Ly(c),(V=B.current)==null||V.abort();const L=new AbortController;B.current=L,j(!0);const $=performance.now();try{const C=await fetch(`/api/inv/search/items?${Gy(c)}`,{credentials:"include",signal:L.signal});if(!C.ok)throw new Error(`search: HTTP ${C.status}`);const Y=await C.json();if(Y.error)throw new Error(Y.error);o(Y),N(null),T(Math.round(performance.now()-$))}catch(C){(C==null?void 0:C.name)!=="AbortError"&&N(String((C==null?void 0:C.message)??C))}finally{B.current===L&&j(!1)}},400);return()=>clearTimeout(R)},[c]),{filters:c,update:p,reset:A,result:m,loading:b,error:M,queryMs:y}}function Zy({search:c}){const{filters:r,update:m}=c,[o,b]=g.useState([]),[j,M]=g.useState(new Set),[N,y]=g.useState("");g.useEffect(()=>{It("/inv/characters/list").then(A=>b(A.characters.map(R=>R.character_name).sort((R,L)=>R.localeCompare(L)))).catch(()=>{}),It("/live").then(A=>M(new Set(A.players.map(R=>R.character_name)))).catch(()=>{})},[]);const T=g.useMemo(()=>r.characters==="all"?new Set(o):new Set(r.characters),[r.characters,o]),B=A=>{const R=new Set(T);R.has(A)?R.delete(A):R.add(A),m({characters:R.size===o.length?"all":[...R]})},p=o.filter(A=>A.toLowerCase().includes(N.toLowerCase()));return s.jsxs(ze,{title:"Characters",defaultOpen:!0,badge:r.characters==="all"?"All":r.characters.length,children:[s.jsx("input",{className:"inv-minisearch",placeholder:"filter characters…",value:N,onChange:A=>y(A.target.value)}),s.jsxs("div",{className:"inv-links",children:[s.jsx("span",{className:"inv-linky",onClick:()=>m({characters:"all"}),children:"All"})," · ",s.jsx("span",{className:"inv-linky",onClick:()=>m({characters:[]}),children:"None"})," · ",s.jsx("span",{className:"inv-linky",onClick:()=>m({characters:o.filter(A=>j.has(A))}),children:"Online"})]}),p.map(A=>s.jsxs("label",{className:"inv-fitem",children:[s.jsx("input",{type:"checkbox",checked:T.has(A),onChange:()=>B(A)}),A," ",j.has(A)&&s.jsx("span",{className:"inv-online"})]},A))]})}function Ky({search:c}){const{filters:r,update:m}=c,[o,b]=g.useState(""),j=N=>m({cantrips:r.cantrips.includes(N)?r.cantrips.filter(y=>y!==N):[...r.cantrips,N]}),M=N=>N.toLowerCase().includes(o.toLowerCase());return s.jsxs(ze,{title:"Cantrips",defaultOpen:!0,badge:r.cantrips.length||void 0,children:[s.jsx("input",{className:"inv-minisearch",placeholder:"find cantrip… e.g. invuln",value:o,onChange:N=>b(N.target.value)}),r.cantrips.length>0&&s.jsxs(s.Fragment,{children:[s.jsx("div",{className:"inv-subhead",children:"Selected"}),r.cantrips.map(N=>s.jsxs("label",{className:"inv-fitem inv-gold",children:[s.jsx("input",{type:"checkbox",checked:!0,onChange:()=>j(N)}),N.replace(/^Legendary /,"")]},N))]}),Uy.map(N=>{const y=N.items.filter(T=>!r.cantrips.includes(T.value)&&M(T.label));return y.length?s.jsxs("div",{children:[s.jsx("div",{className:"inv-subhead",children:N.group}),y.map(T=>s.jsxs("label",{className:"inv-fitem",children:[s.jsx("input",{type:"checkbox",checked:!1,onChange:()=>j(T.value)})," ",T.label]},T.value))]},N.group):null}),s.jsx("div",{className:"inv-subhead",children:"Any-tier spell search"}),s.jsx("input",{className:"inv-minisearch",placeholder:"spell name contains… e.g. Epic Invuln",value:r.spellContains,onChange:N=>m({spellContains:N.target.value})})]})}function ze(c){const[r,m]=g.useState(c.defaultOpen??!1);return s.jsxs("div",{className:`inv-grp${r?" inv-open":""}`,children:[s.jsxs("div",{className:"inv-grp-head",onClick:()=>m(o=>!o),children:[s.jsx("span",{className:"inv-arrow",children:"▶"})," ",c.title,c.badge?s.jsx("span",{className:"inv-badge",children:c.badge}):null]}),r&&s.jsx("div",{className:"inv-grp-body",children:c.children})]})}function ky({search:c}){const{filters:r,update:m}=c,[o,b]=g.useState(!1),[j,M]=g.useState(!1),[N,y]=g.useState([]),[T,B]=g.useState("");g.useEffect(()=>{It("/inv/sets/list").then(C=>y(C.sets)).catch(()=>{})},[]);const p=C=>m({slots:r.slots.includes(C)?r.slots.filter(Y=>Y!==C):[...r.slots,C]}),A=(C,Y)=>m({ratings:{...r.ratings,[C]:Y===""?"":Number(Y)}}),R=Object.values(r.ratings).filter(C=>C!=="").length,L=[r.equipStatus!=="",r.bonded,r.attuned,r.rare].filter(Boolean).length,$=[r.maxLevel,r.minValue,r.minWorkmanship,r.maxBurden].filter(C=>C!=="").length,V=[["all","All items"],["armor","Armor"],["jewelry","Jewelry"],["weapon","Weapons"],["clothing","Clothing"],["shirt","Shirts"],["pants","Pants"]];return s.jsxs("div",{className:"inv-sidebar",children:[s.jsx(Zy,{search:c}),s.jsxs(ze,{title:"Item state",defaultOpen:!0,badge:L||void 0,children:[[["","Any"],["equipped","Equipped"],["unequipped","Not equipped"]].map(([C,Y])=>s.jsxs("label",{className:"inv-fitem",children:[s.jsx("input",{type:"radio",name:"inv-eq",checked:r.equipStatus===C,onChange:()=>m({equipStatus:C})})," ",Y]},Y)),s.jsxs("label",{className:"inv-fitem",children:[s.jsx("input",{type:"checkbox",checked:r.bonded,onChange:C=>m({bonded:C.target.checked})})," Bonded"]}),s.jsxs("label",{className:"inv-fitem",children:[s.jsx("input",{type:"checkbox",checked:r.attuned,onChange:C=>m({attuned:C.target.checked})})," Attuned"]}),s.jsxs("label",{className:"inv-fitem",children:[s.jsx("input",{type:"checkbox",checked:r.rare,onChange:C=>m({rare:C.target.checked})})," Rare"]})]}),s.jsxs(ze,{title:"Item type",defaultOpen:!0,badge:r.itemType!=="all"?1:void 0,children:[V.map(([C,Y])=>s.jsxs("label",{className:"inv-fitem",children:[s.jsx("input",{type:"radio",name:"inv-t",checked:r.itemType===C,onChange:()=>m({itemType:C,weaponType:""})})," ",Y]},C)),r.itemType==="weapon"&&s.jsx("select",{className:"inv-minisearch",value:r.weaponType,onChange:C=>m({weaponType:C.target.value}),children:By.map(C=>s.jsx("option",{value:C.value,children:C.label},C.value))})]}),s.jsxs(ze,{title:"Slots",defaultOpen:!0,badge:r.slots.length||void 0,children:[Ry.map(C=>s.jsxs("label",{className:"inv-fitem",children:[s.jsx("input",{type:"checkbox",checked:r.slots.includes(C),onChange:()=>p(C)})," ",C]},C)),s.jsxs("span",{className:"inv-linky",onClick:()=>b(C=>!C),children:[o?"hide":"show"," armor slots ",o?"▴":"▾"]}),o&&qy.map(C=>s.jsxs("label",{className:"inv-fitem",children:[s.jsx("input",{type:"checkbox",checked:r.slots.includes(C),onChange:()=>p(C)})," ",C]},C))]}),s.jsx(Ky,{search:c}),s.jsxs(ze,{title:"Ratings",badge:R||void 0,children:[ps.filter(C=>j||C.common).map(C=>s.jsxs("div",{className:"inv-range",children:[s.jsxs("label",{children:[C.label," ≥"]}),s.jsx("input",{type:"number",value:r.ratings[C.param]??"",placeholder:"min",onChange:Y=>A(C.param,Y.target.value)})]},C.param)),s.jsx("span",{className:"inv-linky",onClick:()=>M(C=>!C),children:j?"common ratings ▴":`all ${ps.length} ratings ▾`})]}),s.jsxs(ze,{title:"Equipment sets",badge:r.itemSet?1:void 0,children:[s.jsx("input",{className:"inv-minisearch",placeholder:"find set…",value:T,onChange:C=>B(C.target.value)}),s.jsxs("label",{className:"inv-fitem",children:[s.jsx("input",{type:"radio",name:"inv-set",checked:r.itemSet==="",onChange:()=>m({itemSet:""})})," Any set"]}),N.filter(C=>C.id.toLowerCase().includes(T.toLowerCase())).map(C=>s.jsxs("label",{className:"inv-fitem",children:[s.jsx("input",{type:"radio",name:"inv-set",checked:r.itemSet===C.id,onChange:()=>m({itemSet:C.id})})," ",C.id," ",s.jsxs("span",{className:"inv-dim",children:["(",C.item_count,")"]})]},C.id))]}),s.jsxs(ze,{title:"Reqs & value",badge:$||void 0,children:[s.jsxs("div",{className:"inv-range",children:[s.jsx("label",{children:"Wield lvl ≤"}),s.jsx("input",{type:"number",value:r.maxLevel,placeholder:"max",onChange:C=>m({maxLevel:C.target.value===""?"":Number(C.target.value)})})]}),s.jsxs("div",{className:"inv-range",children:[s.jsx("label",{children:"Value ≥"}),s.jsx("input",{type:"number",value:r.minValue,placeholder:"min",onChange:C=>m({minValue:C.target.value===""?"":Number(C.target.value)})})]}),s.jsxs("div",{className:"inv-range",children:[s.jsx("label",{children:"Workmanship ≥"}),s.jsx("input",{type:"number",value:r.minWorkmanship,placeholder:"min",onChange:C=>m({minWorkmanship:C.target.value===""?"":Number(C.target.value)})})]}),s.jsxs("div",{className:"inv-range",children:[s.jsx("label",{children:"Burden ≤"}),s.jsx("input",{type:"number",value:r.maxBurden,placeholder:"max",onChange:C=>m({maxBurden:C.target.value===""?"":Number(C.target.value)})})]})]})]})}function Jy({search:c}){const{filters:r,update:m}=c,o=[];r.text&&o.push({label:`"${r.text}"`,remove:()=>m({text:""})}),r.characters!=="all"&&o.push({label:`${r.characters.length} character${r.characters.length===1?"":"s"}`,remove:()=>m({characters:"all"})}),r.itemType!=="all"&&o.push({label:r.itemType[0].toUpperCase()+r.itemType.slice(1)+(r.weaponType?`: ${r.weaponType}`:""),remove:()=>m({itemType:"all",weaponType:""})});for(const b of r.slots)o.push({label:`Slot: ${b}`,remove:()=>m({slots:r.slots.filter(j=>j!==b)})});for(const b of r.cantrips)o.push({label:b.replace(/^Legendary /,"Leg. "),gold:!0,remove:()=>m({cantrips:r.cantrips.filter(j=>j!==b)})});r.spellContains&&o.push({label:`Spell: ${r.spellContains}`,remove:()=>m({spellContains:""})});for(const[b,j]of Object.entries(r.ratings))if(j!==""){const M=ps.find(N=>N.param===b);o.push({label:`${(M==null?void 0:M.label)??b} ≥ ${j}`,remove:()=>{const{[b]:N,...y}=r.ratings;m({ratings:y})}})}return r.itemSet&&o.push({label:`Set: ${r.itemSet}`,remove:()=>m({itemSet:""})}),r.equipStatus&&o.push({label:r.equipStatus==="equipped"?"Equipped":"Not equipped",remove:()=>m({equipStatus:""})}),r.bonded&&o.push({label:"Bonded",remove:()=>m({bonded:!1})}),r.attuned&&o.push({label:"Attuned",remove:()=>m({attuned:!1})}),r.rare&&o.push({label:"Rare",remove:()=>m({rare:!1})}),r.maxLevel!==""&&o.push({label:`Wield ≤ ${r.maxLevel}`,remove:()=>m({maxLevel:""})}),r.minValue!==""&&o.push({label:`Value ≥ ${r.minValue}`,remove:()=>m({minValue:""})}),r.minWorkmanship!==""&&o.push({label:`Work ≥ ${r.minWorkmanship}`,remove:()=>m({minWorkmanship:""})}),r.maxBurden!==""&&o.push({label:`Burden ≤ ${r.maxBurden}`,remove:()=>m({maxBurden:""})}),o.length?s.jsxs("div",{className:"inv-chipsrow",children:[s.jsx("span",{className:"inv-chips-lbl",children:"ACTIVE"}),o.map((b,j)=>s.jsxs("span",{className:`inv-chip${b.gold?" inv-chip-gold":""}`,children:[b.label," ",s.jsx("span",{className:"inv-chip-x",onClick:b.remove,children:"×"})]},j))]}):null}function Wy(){try{const c=localStorage.getItem(tm);if(c)return new Set(JSON.parse(c))}catch{}return new Set(bs.filter(c=>c.defaultVisible).map(c=>c.key))}function $y(c,r){switch(r){case"name":return s.jsxs(s.Fragment,{children:[c.name,c.is_equipped&&s.jsx("span",{className:"inv-equipped",children:" ⚔"})]});case"spell_names":return s.jsx("span",{className:"inv-spells",children:(c.spell_names??[]).map((m,o)=>s.jsxs("span",{children:[o>0&&", ",s.jsx("span",{className:/legendary/i.test(m)?"inv-leg":"",children:m})]},o))});case"value":return c.value!=null?c.value.toLocaleString():"—";case"last_updated":return c.last_updated?c.last_updated.slice(0,16).replace("T"," "):"—";default:{const m=c[r];return m==null||m===-1?"—":String(m)}}}function Fy({search:c,selected:r,onSelect:m}){const{filters:o,update:b,result:j}=c,[M,N]=g.useState(Wy),[y,T]=g.useState(!1),B=g.useRef(null),p=g.useMemo(()=>bs.filter(V=>M.has(V.key)),[M]),A=(j==null?void 0:j.items)??[];g.useEffect(()=>{try{localStorage.setItem(tm,JSON.stringify([...M]))}catch{}},[M]),g.useEffect(()=>{const V=C=>{var zt,Ut;if(((zt=C.target)==null?void 0:zt.tagName)==="INPUT"||((Ut=C.target)==null?void 0:Ut.tagName)==="SELECT")return;if(C.key==="Escape"){m(null);return}if(C.key!=="ArrowDown"&&C.key!=="ArrowUp")return;C.preventDefault();const Y=r?A.indexOf(r):-1,F=C.key==="ArrowDown"?Math.min(Y+1,A.length-1):Math.max(Y-1,0);A[F]&&m(A[F])};return window.addEventListener("keydown",V),()=>window.removeEventListener("keydown",V)},[A,r,m]);const R=V=>{V&&(o.sortBy===V?b({sortDir:o.sortDir==="asc"?"desc":"asc"}):b({sortBy:V,sortDir:"asc"}))},L=j?Math.max(1,Math.ceil(j.total_count/j.limit)):1,$=V=>{var C;b({page:Math.min(Math.max(1,V),L)}),(C=B.current)==null||C.scrollTo(0,0)};return s.jsxs("div",{className:"inv-results",ref:B,children:[s.jsxs("div",{className:"inv-colpicker-anchor",children:[s.jsx("button",{className:"inv-btn inv-colpicker-btn",onClick:()=>T(V=>!V),children:"⚙ Columns"}),y&&s.jsx("div",{className:"inv-colpicker",children:bs.map(V=>s.jsxs("label",{className:"inv-fitem",children:[s.jsx("input",{type:"checkbox",checked:M.has(V.key),onChange:()=>{const C=new Set(M);C.has(V.key)?C.delete(V.key):C.add(V.key),N(C)}})," ",V.label]},V.key))})]}),s.jsxs("table",{children:[s.jsx("thead",{children:s.jsx("tr",{children:p.map(V=>s.jsx("th",{className:o.sortBy===V.sortKey?`inv-sorted-${o.sortDir}`:"",onClick:()=>R(V.sortKey),children:V.label},V.key))})}),s.jsxs("tbody",{children:[A.map((V,C)=>s.jsx("tr",{className:V===r?"inv-sel":"",onClick:()=>m(V===r?null:V),children:p.map(Y=>s.jsx("td",{children:$y(V,Y.key)},Y.key))},C)),!A.length&&s.jsx("tr",{children:s.jsx("td",{colSpan:p.length,className:"inv-dim",children:"No items match."})})]})]}),s.jsxs("div",{className:"inv-pager",children:[s.jsx("span",{className:"inv-pg",onClick:()=>$(o.page-1),children:"◀"}),s.jsxs("span",{children:["page ",(j==null?void 0:j.page)??1," / ",L]}),s.jsx("span",{className:"inv-pg",onClick:()=>$(o.page+1),children:"▶"}),s.jsxs("span",{className:"inv-pager-right",children:[(j==null?void 0:j.limit)??200," / page"]})]})]})}function Dl({k:c,v:r}){return s.jsxs("div",{className:"inv-kv",children:[s.jsx("span",{children:c}),s.jsx("b",{children:r??"—"})]})}function Iy({item:c,onClose:r}){var m,o;return s.jsxs("div",{className:"inv-detail",children:[s.jsx("span",{className:"inv-closex",onClick:r,children:"×"}),s.jsx("h3",{children:c.name}),s.jsxs("div",{className:"inv-detail-sub",children:[c.slot_name??c.object_class_name??""," · ",c.is_equipped?"⚔ Equipped":"📦 Inventory",c.is_rare&&" · ★ Rare"]}),s.jsx(Dl,{k:"Character",v:c.character_name}),s.jsx(Dl,{k:"Value",v:(m=c.value)==null?void 0:m.toLocaleString()}),s.jsx(Dl,{k:"Burden",v:c.burden}),s.jsx(Dl,{k:"Wield req",v:c.wield_level?`Level ${c.wield_level}`:"—"}),s.jsx(Dl,{k:"Workmanship",v:c.workmanship??"—"}),c.armor_level!=null&&c.armor_level>0&&s.jsx(Dl,{k:"Armor",v:c.armor_level}),c.max_damage!=null&&c.max_damage>0&&s.jsx(Dl,{k:"Max damage",v:c.max_damage}),c.condition_percent!=null&&s.jsx(Dl,{k:"Condition",v:`${c.condition_percent}%`}),c.item_set_name&&s.jsx(Dl,{k:"Set",v:c.item_set_name}),(c.is_bonded||c.is_attuned)&&s.jsx(Dl,{k:"Binding",v:[c.is_bonded&&"Bonded",c.is_attuned&&"Attuned"].filter(Boolean).join(", ")}),s.jsx("hr",{}),s.jsxs("div",{className:"inv-sphead",children:["Spells (",((o=c.spell_names)==null?void 0:o.length)??0,")"]}),(c.spell_names??[]).map((b,j)=>s.jsx("div",{className:`inv-sp${/legendary/i.test(b)?" inv-leg":""}`,children:b},j)),s.jsx("div",{className:"inv-hint",children:"↑/↓ next item · Esc close"})]})}function Vd(c){return`${c.name} ${c.character_name} ${c.last_updated??""}`}class Py extends g.Component{constructor(r){super(r),this.state={hasError:!1}}static getDerivedStateFromError(){return{hasError:!0}}componentDidCatch(r,m){console.error("Inventory search crashed:",r,m)}render(){return this.state.hasError?s.jsx("div",{className:"inv-page",children:s.jsxs("div",{className:"inv-error",style:{margin:"auto",textAlign:"center",padding:24},children:[s.jsx("p",{style:{marginBottom:12},children:"Something went wrong loading the inventory search page."}),s.jsx("button",{className:"inv-btn",onClick:()=>{window.location.href="/?view=inventory"},children:"Reset filters"})]})}):this.props.children}}function tv(){const c=Qy(),[r,m]=g.useState(null);return g.useEffect(()=>{var M;if(!r)return;const o=((M=c.result)==null?void 0:M.items)??[],b=Vd(r),j=o.find(N=>Vd(N)===b);j&&j!==r?m(j):j||m(null)},[c.result]),s.jsxs("div",{className:"inv-page",children:[s.jsxs("div",{className:"inv-topbar",children:[s.jsx("span",{className:"inv-title",children:"⚔ Inventory Search"}),s.jsx("input",{className:"inv-searchbox",placeholder:"Search name or material…",value:c.filters.text,onChange:o=>c.update({text:o.target.value})}),s.jsx("button",{className:"inv-btn",onClick:()=>{c.reset(),m(null)},children:"Reset"}),s.jsx("span",{className:"inv-count",children:c.error?s.jsx("span",{className:"inv-error",children:c.error}):c.result?s.jsxs(s.Fragment,{children:[s.jsx("b",{children:c.result.total_count.toLocaleString()})," items",c.queryMs!=null&&s.jsxs(s.Fragment,{children:[" · ",c.queryMs," ms"]}),c.loading&&" · …"]}):"loading…"})]}),s.jsx(Jy,{search:c}),s.jsxs("div",{className:"inv-main",children:[s.jsx(ky,{search:c}),s.jsx(Fy,{search:c,selected:r,onSelect:m}),r&&s.jsx(Iy,{item:r,onClose:()=>m(null)})]})]})}function lv(){return s.jsx(Py,{children:s.jsx(tv,{})})}function ev(){const c=new URLSearchParams(window.location.search).get("view");return s.jsx(X0,{children:c==="dashboard"?s.jsx(Oy,{}):c==="inventory"?s.jsx(lv,{}):s.jsx(av,{})})}function av(){const c=Pd();return s.jsx(Ny,{data:c})}O0.createRoot(document.getElementById("root")).render(s.jsx(g.StrictMode,{children:s.jsx(ev,{})}));"serviceWorker"in navigator&&navigator.serviceWorker.register("/sw.js").catch(()=>{});export{kd as D,It as a,cv as b,uv as c,iv as d,ly as e,fv as f,rv as g,ov as h,s as j,sv as l,g as r,An as u}; +`+a.stack}}var Iu=Object.prototype.hasOwnProperty,Pu=c.unstable_scheduleCallback,ti=c.unstable_cancelCallback,em=c.unstable_shouldYield,am=c.unstable_requestPaint,Pt=c.unstable_now,nm=c.unstable_getCurrentPriorityLevel,As=c.unstable_ImmediatePriority,Ts=c.unstable_UserBlockingPriority,Cn=c.unstable_NormalPriority,um=c.unstable_LowPriority,Es=c.unstable_IdlePriority,im=c.log,cm=c.unstable_setDisableYieldValue,Ma=null,tl=null;function Il(t){if(typeof im=="function"&&cm(t),tl&&typeof tl.setStrictMode=="function")try{tl.setStrictMode(Ma,t)}catch{}}var ll=Math.clz32?Math.clz32:rm,sm=Math.log,fm=Math.LN2;function rm(t){return t>>>=0,t===0?32:31-(sm(t)/fm|0)|0}var Dn=256,On=262144,Un=4194304;function Te(t){var l=t&42;if(l!==0)return l;switch(t&-t){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return t&261888;case 262144:case 524288:case 1048576:case 2097152:return t&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return t&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return t}}function Rn(t,l,e){var a=t.pendingLanes;if(a===0)return 0;var n=0,u=t.suspendedLanes,i=t.pingedLanes;t=t.warmLanes;var f=a&134217727;return f!==0?(a=f&~u,a!==0?n=Te(a):(i&=f,i!==0?n=Te(i):e||(e=f&~t,e!==0&&(n=Te(e))))):(f=a&~u,f!==0?n=Te(f):i!==0?n=Te(i):e||(e=a&~t,e!==0&&(n=Te(e)))),n===0?0:l!==0&&l!==n&&(l&u)===0&&(u=n&-n,e=l&-l,u>=e||u===32&&(e&4194048)!==0)?l:n}function Ca(t,l){return(t.pendingLanes&~(t.suspendedLanes&~t.pingedLanes)&l)===0}function om(t,l){switch(t){case 1:case 2:case 4:case 8:case 64:return l+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return l+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Ns(){var t=Un;return Un<<=1,(Un&62914560)===0&&(Un=4194304),t}function li(t){for(var l=[],e=0;31>e;e++)l.push(t);return l}function Da(t,l){t.pendingLanes|=l,l!==268435456&&(t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0)}function dm(t,l,e,a,n,u){var i=t.pendingLanes;t.pendingLanes=e,t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0,t.expiredLanes&=e,t.entangledLanes&=e,t.errorRecoveryDisabledLanes&=e,t.shellSuspendCounter=0;var f=t.entanglements,d=t.expirationTimes,x=t.hiddenUpdates;for(e=i&~e;0"u")return null;try{return t.activeElement||t.body}catch{return t.body}}var pm=/[\n"\\]/g;function rl(t){return t.replace(pm,function(l){return"\\"+l.charCodeAt(0).toString(16)+" "})}function ci(t,l,e,a,n,u,i,f){t.name="",i!=null&&typeof i!="function"&&typeof i!="symbol"&&typeof i!="boolean"?t.type=i:t.removeAttribute("type"),l!=null?i==="number"?(l===0&&t.value===""||t.value!=l)&&(t.value=""+fl(l)):t.value!==""+fl(l)&&(t.value=""+fl(l)):i!=="submit"&&i!=="reset"||t.removeAttribute("value"),l!=null?si(t,i,fl(l)):e!=null?si(t,i,fl(e)):a!=null&&t.removeAttribute("value"),n==null&&u!=null&&(t.defaultChecked=!!u),n!=null&&(t.checked=n&&typeof n!="function"&&typeof n!="symbol"),f!=null&&typeof f!="function"&&typeof f!="symbol"&&typeof f!="boolean"?t.name=""+fl(f):t.removeAttribute("name")}function Xs(t,l,e,a,n,u,i,f){if(u!=null&&typeof u!="function"&&typeof u!="symbol"&&typeof u!="boolean"&&(t.type=u),l!=null||e!=null){if(!(u!=="submit"&&u!=="reset"||l!=null)){ii(t);return}e=e!=null?""+fl(e):"",l=l!=null?""+fl(l):e,f||l===t.value||(t.value=l),t.defaultValue=l}a=a??n,a=typeof a!="function"&&typeof a!="symbol"&&!!a,t.checked=f?t.checked:!!a,t.defaultChecked=!!a,i!=null&&typeof i!="function"&&typeof i!="symbol"&&typeof i!="boolean"&&(t.name=i),ii(t)}function si(t,l,e){l==="number"&&Hn(t.ownerDocument)===t||t.defaultValue===""+e||(t.defaultValue=""+e)}function $e(t,l,e,a){if(t=t.options,l){l={};for(var n=0;n"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),mi=!1;if(ql)try{var qa={};Object.defineProperty(qa,"passive",{get:function(){mi=!0}}),window.addEventListener("test",qa,qa),window.removeEventListener("test",qa,qa)}catch{mi=!1}var te=null,hi=null,Yn=null;function Js(){if(Yn)return Yn;var t,l=hi,e=l.length,a,n="value"in te?te.value:te.textContent,u=n.length;for(t=0;t=La),tf=" ",lf=!1;function ef(t,l){switch(t){case"keyup":return Km.indexOf(l.keyCode)!==-1;case"keydown":return l.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function af(t){return t=t.detail,typeof t=="object"&&"data"in t?t.data:null}var ta=!1;function Jm(t,l){switch(t){case"compositionend":return af(l);case"keypress":return l.which!==32?null:(lf=!0,tf);case"textInput":return t=l.data,t===tf&&lf?null:t;default:return null}}function Wm(t,l){if(ta)return t==="compositionend"||!bi&&ef(t,l)?(t=Js(),Yn=hi=te=null,ta=!1,t):null;switch(t){case"paste":return null;case"keypress":if(!(l.ctrlKey||l.altKey||l.metaKey)||l.ctrlKey&&l.altKey){if(l.char&&1=l)return{node:e,offset:l-t};t=a}t:{for(;e;){if(e.nextSibling){e=e.nextSibling;break t}e=e.parentNode}e=void 0}e=df(e)}}function hf(t,l){return t&&l?t===l?!0:t&&t.nodeType===3?!1:l&&l.nodeType===3?hf(t,l.parentNode):"contains"in t?t.contains(l):t.compareDocumentPosition?!!(t.compareDocumentPosition(l)&16):!1:!1}function yf(t){t=t!=null&&t.ownerDocument!=null&&t.ownerDocument.defaultView!=null?t.ownerDocument.defaultView:window;for(var l=Hn(t.document);l instanceof t.HTMLIFrameElement;){try{var e=typeof l.contentWindow.location.href=="string"}catch{e=!1}if(e)t=l.contentWindow;else break;l=Hn(t.document)}return l}function _i(t){var l=t&&t.nodeName&&t.nodeName.toLowerCase();return l&&(l==="input"&&(t.type==="text"||t.type==="search"||t.type==="tel"||t.type==="url"||t.type==="password")||l==="textarea"||t.contentEditable==="true")}var ah=ql&&"documentMode"in document&&11>=document.documentMode,la=null,zi=null,wa=null,ji=!1;function vf(t,l,e){var a=e.window===e?e.document:e.nodeType===9?e:e.ownerDocument;ji||la==null||la!==Hn(a)||(a=la,"selectionStart"in a&&_i(a)?a={start:a.selectionStart,end:a.selectionEnd}:(a=(a.ownerDocument&&a.ownerDocument.defaultView||window).getSelection(),a={anchorNode:a.anchorNode,anchorOffset:a.anchorOffset,focusNode:a.focusNode,focusOffset:a.focusOffset}),wa&&Xa(wa,a)||(wa=a,a=Ou(zi,"onSelect"),0>=i,n-=i,Nl=1<<32-ll(l)+n|e<tt?(ct=G,G=null):ct=G.sibling;var rt=z(v,G,S[tt],O);if(rt===null){G===null&&(G=ct);break}t&&G&&rt.alternate===null&&l(v,G),h=u(rt,h,tt),ft===null?K=rt:ft.sibling=rt,ft=rt,G=ct}if(tt===S.length)return e(v,G),st&&Hl(v,tt),K;if(G===null){for(;tttt?(ct=G,G=null):ct=G.sibling;var _e=z(v,G,rt.value,O);if(_e===null){G===null&&(G=ct);break}t&&G&&_e.alternate===null&&l(v,G),h=u(_e,h,tt),ft===null?K=_e:ft.sibling=_e,ft=_e,G=ct}if(rt.done)return e(v,G),st&&Hl(v,tt),K;if(G===null){for(;!rt.done;tt++,rt=S.next())rt=U(v,rt.value,O),rt!==null&&(h=u(rt,h,tt),ft===null?K=rt:ft.sibling=rt,ft=rt);return st&&Hl(v,tt),K}for(G=a(G);!rt.done;tt++,rt=S.next())rt=E(G,v,tt,rt.value,O),rt!==null&&(t&&rt.alternate!==null&&G.delete(rt.key===null?tt:rt.key),h=u(rt,h,tt),ft===null?K=rt:ft.sibling=rt,ft=rt);return t&&G.forEach(function(z0){return l(v,z0)}),st&&Hl(v,tt),K}function pt(v,h,S,O){if(typeof S=="object"&&S!==null&&S.type===$&&S.key===null&&(S=S.props.children),typeof S=="object"&&S!==null){switch(S.$$typeof){case R:t:{for(var K=S.key;h!==null;){if(h.key===K){if(K=S.type,K===$){if(h.tag===7){e(v,h.sibling),O=n(h,S.props.children),O.return=v,v=O;break t}}else if(h.elementType===K||typeof K=="object"&&K!==null&&K.$$typeof===Z&&He(K)===h.type){e(v,h.sibling),O=n(h,S.props),Ja(O,S),O.return=v,v=O;break t}e(v,h);break}else l(v,h);h=h.sibling}S.type===$?(O=Oe(S.props.children,v.mode,O,S.key),O.return=v,v=O):(O=Wn(S.type,S.key,S.props,null,v.mode,O),Ja(O,S),O.return=v,v=O)}return i(v);case L:t:{for(K=S.key;h!==null;){if(h.key===K)if(h.tag===4&&h.stateNode.containerInfo===S.containerInfo&&h.stateNode.implementation===S.implementation){e(v,h.sibling),O=n(h,S.children||[]),O.return=v,v=O;break t}else{e(v,h);break}else l(v,h);h=h.sibling}O=Di(S,v.mode,O),O.return=v,v=O}return i(v);case Z:return S=He(S),pt(v,h,S,O)}if(xl(S))return X(v,h,S,O);if(jt(S)){if(K=jt(S),typeof K!="function")throw Error(o(150));return S=K.call(S),k(v,h,S,O)}if(typeof S.then=="function")return pt(v,h,eu(S),O);if(S.$$typeof===F)return pt(v,h,In(v,S),O);au(v,S)}return typeof S=="string"&&S!==""||typeof S=="number"||typeof S=="bigint"?(S=""+S,h!==null&&h.tag===6?(e(v,h.sibling),O=n(h,S),O.return=v,v=O):(e(v,h),O=Ci(S,v.mode,O),O.return=v,v=O),i(v)):e(v,h)}return function(v,h,S,O){try{ka=0;var K=pt(v,h,S,O);return da=null,K}catch(G){if(G===oa||G===tu)throw G;var ft=al(29,G,null,v.mode);return ft.lanes=O,ft.return=v,ft}finally{}}}var Ye=Yf(!0),Vf=Yf(!1),ue=!1;function Gi(t){t.updateQueue={baseState:t.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Qi(t,l){t=t.updateQueue,l.updateQueue===t&&(l.updateQueue={baseState:t.baseState,firstBaseUpdate:t.firstBaseUpdate,lastBaseUpdate:t.lastBaseUpdate,shared:t.shared,callbacks:null})}function ie(t){return{lane:t,tag:0,payload:null,callback:null,next:null}}function ce(t,l,e){var a=t.updateQueue;if(a===null)return null;if(a=a.shared,(mt&2)!==0){var n=a.pending;return n===null?l.next=l:(l.next=n.next,n.next=l),a.pending=l,l=Jn(t),zf(t,null,e),l}return kn(t,a,l,e),Jn(t)}function Wa(t,l,e){if(l=l.updateQueue,l!==null&&(l=l.shared,(e&4194048)!==0)){var a=l.lanes;a&=t.pendingLanes,e|=a,l.lanes=e,Cs(t,e)}}function Zi(t,l){var e=t.updateQueue,a=t.alternate;if(a!==null&&(a=a.updateQueue,e===a)){var n=null,u=null;if(e=e.firstBaseUpdate,e!==null){do{var i={lane:e.lane,tag:e.tag,payload:e.payload,callback:null,next:null};u===null?n=u=i:u=u.next=i,e=e.next}while(e!==null);u===null?n=u=l:u=u.next=l}else n=u=l;e={baseState:a.baseState,firstBaseUpdate:n,lastBaseUpdate:u,shared:a.shared,callbacks:a.callbacks},t.updateQueue=e;return}t=e.lastBaseUpdate,t===null?e.firstBaseUpdate=l:t.next=l,e.lastBaseUpdate=l}var Ki=!1;function $a(){if(Ki){var t=ra;if(t!==null)throw t}}function Fa(t,l,e,a){Ki=!1;var n=t.updateQueue;ue=!1;var u=n.firstBaseUpdate,i=n.lastBaseUpdate,f=n.shared.pending;if(f!==null){n.shared.pending=null;var d=f,x=d.next;d.next=null,i===null?u=x:i.next=x,i=d;var D=t.alternate;D!==null&&(D=D.updateQueue,f=D.lastBaseUpdate,f!==i&&(f===null?D.firstBaseUpdate=x:f.next=x,D.lastBaseUpdate=d))}if(u!==null){var U=n.baseState;i=0,D=x=d=null,f=u;do{var z=f.lane&-536870913,E=z!==f.lane;if(E?(it&z)===z:(a&z)===z){z!==0&&z===fa&&(Ki=!0),D!==null&&(D=D.next={lane:0,tag:f.tag,payload:f.payload,callback:null,next:null});t:{var X=t,k=f;z=l;var pt=e;switch(k.tag){case 1:if(X=k.payload,typeof X=="function"){U=X.call(pt,U,z);break t}U=X;break t;case 3:X.flags=X.flags&-65537|128;case 0:if(X=k.payload,z=typeof X=="function"?X.call(pt,U,z):X,z==null)break t;U=p({},U,z);break t;case 2:ue=!0}}z=f.callback,z!==null&&(t.flags|=64,E&&(t.flags|=8192),E=n.callbacks,E===null?n.callbacks=[z]:E.push(z))}else E={lane:z,tag:f.tag,payload:f.payload,callback:f.callback,next:null},D===null?(x=D=E,d=U):D=D.next=E,i|=z;if(f=f.next,f===null){if(f=n.shared.pending,f===null)break;E=f,f=E.next,E.next=null,n.lastBaseUpdate=E,n.shared.pending=null}}while(!0);D===null&&(d=U),n.baseState=d,n.firstBaseUpdate=x,n.lastBaseUpdate=D,u===null&&(n.shared.lanes=0),de|=i,t.lanes=i,t.memoizedState=U}}function Xf(t,l){if(typeof t!="function")throw Error(o(191,t));t.call(l)}function wf(t,l){var e=t.callbacks;if(e!==null)for(t.callbacks=null,t=0;tu?u:8;var i=_.T,f={};_.T=f,oc(t,!1,l,e);try{var d=n(),x=_.S;if(x!==null&&x(f,d),d!==null&&typeof d=="object"&&typeof d.then=="function"){var D=dh(d,a);tn(t,l,D,sl(t))}else tn(t,l,a,sl(t))}catch(U){tn(t,l,{then:function(){},status:"rejected",reason:U},sl())}finally{q.p=u,i!==null&&f.types!==null&&(i.types=f.types),_.T=i}}function ph(){}function fc(t,l,e,a){if(t.tag!==5)throw Error(o(476));var n=Sr(t).queue;br(t,n,l,Q,e===null?ph:function(){return xr(t),e(a)})}function Sr(t){var l=t.memoizedState;if(l!==null)return l;l={memoizedState:Q,baseState:Q,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Xl,lastRenderedState:Q},next:null};var e={};return l.next={memoizedState:e,baseState:e,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Xl,lastRenderedState:e},next:null},t.memoizedState=l,t=t.alternate,t!==null&&(t.memoizedState=l),l}function xr(t){var l=Sr(t);l.next===null&&(l=t.alternate.memoizedState),tn(t,l.next.queue,{},sl())}function rc(){return Xt(pn)}function _r(){return Nt().memoizedState}function zr(){return Nt().memoizedState}function bh(t){for(var l=t.return;l!==null;){switch(l.tag){case 24:case 3:var e=sl();t=ie(e);var a=ce(l,t,e);a!==null&&(Ft(a,l,e),Wa(a,l,e)),l={cache:Yi()},t.payload=l;return}l=l.return}}function Sh(t,l,e){var a=sl();e={lane:a,revertLane:0,gesture:null,action:e,hasEagerState:!1,eagerState:null,next:null},mu(t)?Ar(l,e):(e=Ni(t,l,e,a),e!==null&&(Ft(e,t,a),Tr(e,l,a)))}function jr(t,l,e){var a=sl();tn(t,l,e,a)}function tn(t,l,e,a){var n={lane:a,revertLane:0,gesture:null,action:e,hasEagerState:!1,eagerState:null,next:null};if(mu(t))Ar(l,n);else{var u=t.alternate;if(t.lanes===0&&(u===null||u.lanes===0)&&(u=l.lastRenderedReducer,u!==null))try{var i=l.lastRenderedState,f=u(i,e);if(n.hasEagerState=!0,n.eagerState=f,el(f,i))return kn(t,l,n,0),bt===null&&Kn(),!1}catch{}finally{}if(e=Ni(t,l,n,a),e!==null)return Ft(e,t,a),Tr(e,l,a),!0}return!1}function oc(t,l,e,a){if(a={lane:2,revertLane:Gc(),gesture:null,action:a,hasEagerState:!1,eagerState:null,next:null},mu(t)){if(l)throw Error(o(479))}else l=Ni(t,e,a,2),l!==null&&Ft(l,t,2)}function mu(t){var l=t.alternate;return t===I||l!==null&&l===I}function Ar(t,l){ha=iu=!0;var e=t.pending;e===null?l.next=l:(l.next=e.next,e.next=l),t.pending=l}function Tr(t,l,e){if((e&4194048)!==0){var a=l.lanes;a&=t.pendingLanes,e|=a,l.lanes=e,Cs(t,e)}}var ln={readContext:Xt,use:fu,useCallback:At,useContext:At,useEffect:At,useImperativeHandle:At,useLayoutEffect:At,useInsertionEffect:At,useMemo:At,useReducer:At,useRef:At,useState:At,useDebugValue:At,useDeferredValue:At,useTransition:At,useSyncExternalStore:At,useId:At,useHostTransitionStatus:At,useFormState:At,useActionState:At,useOptimistic:At,useMemoCache:At,useCacheRefresh:At};ln.useEffectEvent=At;var Er={readContext:Xt,use:fu,useCallback:function(t,l){return Qt().memoizedState=[t,l===void 0?null:l],t},useContext:Xt,useEffect:rr,useImperativeHandle:function(t,l,e){e=e!=null?e.concat([t]):null,ou(4194308,4,hr.bind(null,l,t),e)},useLayoutEffect:function(t,l){return ou(4194308,4,t,l)},useInsertionEffect:function(t,l){ou(4,2,t,l)},useMemo:function(t,l){var e=Qt();l=l===void 0?null:l;var a=t();if(Ve){Il(!0);try{t()}finally{Il(!1)}}return e.memoizedState=[a,l],a},useReducer:function(t,l,e){var a=Qt();if(e!==void 0){var n=e(l);if(Ve){Il(!0);try{e(l)}finally{Il(!1)}}}else n=l;return a.memoizedState=a.baseState=n,t={pending:null,lanes:0,dispatch:null,lastRenderedReducer:t,lastRenderedState:n},a.queue=t,t=t.dispatch=Sh.bind(null,I,t),[a.memoizedState,t]},useRef:function(t){var l=Qt();return t={current:t},l.memoizedState=t},useState:function(t){t=nc(t);var l=t.queue,e=jr.bind(null,I,l);return l.dispatch=e,[t.memoizedState,e]},useDebugValue:cc,useDeferredValue:function(t,l){var e=Qt();return sc(e,t,l)},useTransition:function(){var t=nc(!1);return t=br.bind(null,I,t.queue,!0,!1),Qt().memoizedState=t,[!1,t]},useSyncExternalStore:function(t,l,e){var a=I,n=Qt();if(st){if(e===void 0)throw Error(o(407));e=e()}else{if(e=l(),bt===null)throw Error(o(349));(it&127)!==0||Jf(a,l,e)}n.memoizedState=e;var u={value:e,getSnapshot:l};return n.queue=u,rr($f.bind(null,a,u,t),[t]),a.flags|=2048,va(9,{destroy:void 0},Wf.bind(null,a,u,e,l),null),e},useId:function(){var t=Qt(),l=bt.identifierPrefix;if(st){var e=Ml,a=Nl;e=(a&~(1<<32-ll(a)-1)).toString(32)+e,l="_"+l+"R_"+e,e=cu++,0<\/script>",u=u.removeChild(u.firstChild);break;case"select":u=typeof a.is=="string"?i.createElement("select",{is:a.is}):i.createElement("select"),a.multiple?u.multiple=!0:a.size&&(u.size=a.size);break;default:u=typeof a.is=="string"?i.createElement(n,{is:a.is}):i.createElement(n)}}u[Yt]=l,u[Zt]=a;t:for(i=l.child;i!==null;){if(i.tag===5||i.tag===6)u.appendChild(i.stateNode);else if(i.tag!==4&&i.tag!==27&&i.child!==null){i.child.return=i,i=i.child;continue}if(i===l)break t;for(;i.sibling===null;){if(i.return===null||i.return===l)break t;i=i.return}i.sibling.return=i.return,i=i.sibling}l.stateNode=u;t:switch(Gt(u,n,a),n){case"button":case"input":case"select":case"textarea":a=!!a.autoFocus;break t;case"img":a=!0;break t;default:a=!1}a&&Gl(l)}}return xt(l),Ac(l,l.type,t===null?null:t.memoizedProps,l.pendingProps,e),null;case 6:if(t&&l.stateNode!=null)t.memoizedProps!==a&&Gl(l);else{if(typeof a!="string"&&l.stateNode===null)throw Error(o(166));if(t=Fl.current,ca(l)){if(t=l.stateNode,e=l.memoizedProps,a=null,n=Vt,n!==null)switch(n.tag){case 27:case 5:a=n.memoizedProps}t[Yt]=l,t=!!(t.nodeValue===e||a!==null&&a.suppressHydrationWarning===!0||ko(t.nodeValue,e)),t||ae(l,!0)}else t=Uu(t).createTextNode(a),t[Yt]=l,l.stateNode=t}return xt(l),null;case 31:if(e=l.memoizedState,t===null||t.memoizedState!==null){if(a=ca(l),e!==null){if(t===null){if(!a)throw Error(o(318));if(t=l.memoizedState,t=t!==null?t.dehydrated:null,!t)throw Error(o(557));t[Yt]=l}else Ue(),(l.flags&128)===0&&(l.memoizedState=null),l.flags|=4;xt(l),t=!1}else e=qi(),t!==null&&t.memoizedState!==null&&(t.memoizedState.hydrationErrors=e),t=!0;if(!t)return l.flags&256?(ul(l),l):(ul(l),null);if((l.flags&128)!==0)throw Error(o(558))}return xt(l),null;case 13:if(a=l.memoizedState,t===null||t.memoizedState!==null&&t.memoizedState.dehydrated!==null){if(n=ca(l),a!==null&&a.dehydrated!==null){if(t===null){if(!n)throw Error(o(318));if(n=l.memoizedState,n=n!==null?n.dehydrated:null,!n)throw Error(o(317));n[Yt]=l}else Ue(),(l.flags&128)===0&&(l.memoizedState=null),l.flags|=4;xt(l),n=!1}else n=qi(),t!==null&&t.memoizedState!==null&&(t.memoizedState.hydrationErrors=n),n=!0;if(!n)return l.flags&256?(ul(l),l):(ul(l),null)}return ul(l),(l.flags&128)!==0?(l.lanes=e,l):(e=a!==null,t=t!==null&&t.memoizedState!==null,e&&(a=l.child,n=null,a.alternate!==null&&a.alternate.memoizedState!==null&&a.alternate.memoizedState.cachePool!==null&&(n=a.alternate.memoizedState.cachePool.pool),u=null,a.memoizedState!==null&&a.memoizedState.cachePool!==null&&(u=a.memoizedState.cachePool.pool),u!==n&&(a.flags|=2048)),e!==t&&e&&(l.child.flags|=8192),pu(l,l.updateQueue),xt(l),null);case 4:return Qe(),t===null&&kc(l.stateNode.containerInfo),xt(l),null;case 10:return Yl(l.type),xt(l),null;case 19:if(dt(Et),a=l.memoizedState,a===null)return xt(l),null;if(n=(l.flags&128)!==0,u=a.rendering,u===null)if(n)an(a,!1);else{if(Tt!==0||t!==null&&(t.flags&128)!==0)for(t=l.child;t!==null;){if(u=uu(t),u!==null){for(l.flags|=128,an(a,!1),t=u.updateQueue,l.updateQueue=t,pu(l,t),l.subtreeFlags=0,t=e,e=l.child;e!==null;)jf(e,t),e=e.sibling;return et(Et,Et.current&1|2),st&&Hl(l,a.treeForkCount),l.child}t=t.sibling}a.tail!==null&&Pt()>zu&&(l.flags|=128,n=!0,an(a,!1),l.lanes=4194304)}else{if(!n)if(t=uu(u),t!==null){if(l.flags|=128,n=!0,t=t.updateQueue,l.updateQueue=t,pu(l,t),an(a,!0),a.tail===null&&a.tailMode==="hidden"&&!u.alternate&&!st)return xt(l),null}else 2*Pt()-a.renderingStartTime>zu&&e!==536870912&&(l.flags|=128,n=!0,an(a,!1),l.lanes=4194304);a.isBackwards?(u.sibling=l.child,l.child=u):(t=a.last,t!==null?t.sibling=u:l.child=u,a.last=u)}return a.tail!==null?(t=a.tail,a.rendering=t,a.tail=t.sibling,a.renderingStartTime=Pt(),t.sibling=null,e=Et.current,et(Et,n?e&1|2:e&1),st&&Hl(l,a.treeForkCount),t):(xt(l),null);case 22:case 23:return ul(l),Ji(),a=l.memoizedState!==null,t!==null?t.memoizedState!==null!==a&&(l.flags|=8192):a&&(l.flags|=8192),a?(e&536870912)!==0&&(l.flags&128)===0&&(xt(l),l.subtreeFlags&6&&(l.flags|=8192)):xt(l),e=l.updateQueue,e!==null&&pu(l,e.retryQueue),e=null,t!==null&&t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(e=t.memoizedState.cachePool.pool),a=null,l.memoizedState!==null&&l.memoizedState.cachePool!==null&&(a=l.memoizedState.cachePool.pool),a!==e&&(l.flags|=2048),t!==null&&dt(Be),null;case 24:return e=null,t!==null&&(e=t.memoizedState.cache),l.memoizedState.cache!==e&&(l.flags|=2048),Yl(Mt),xt(l),null;case 25:return null;case 30:return null}throw Error(o(156,l.tag))}function Ah(t,l){switch(Ui(l),l.tag){case 1:return t=l.flags,t&65536?(l.flags=t&-65537|128,l):null;case 3:return Yl(Mt),Qe(),t=l.flags,(t&65536)!==0&&(t&128)===0?(l.flags=t&-65537|128,l):null;case 26:case 27:case 5:return Mn(l),null;case 31:if(l.memoizedState!==null){if(ul(l),l.alternate===null)throw Error(o(340));Ue()}return t=l.flags,t&65536?(l.flags=t&-65537|128,l):null;case 13:if(ul(l),t=l.memoizedState,t!==null&&t.dehydrated!==null){if(l.alternate===null)throw Error(o(340));Ue()}return t=l.flags,t&65536?(l.flags=t&-65537|128,l):null;case 19:return dt(Et),null;case 4:return Qe(),null;case 10:return Yl(l.type),null;case 22:case 23:return ul(l),Ji(),t!==null&&dt(Be),t=l.flags,t&65536?(l.flags=t&-65537|128,l):null;case 24:return Yl(Mt),null;case 25:return null;default:return null}}function Fr(t,l){switch(Ui(l),l.tag){case 3:Yl(Mt),Qe();break;case 26:case 27:case 5:Mn(l);break;case 4:Qe();break;case 31:l.memoizedState!==null&&ul(l);break;case 13:ul(l);break;case 19:dt(Et);break;case 10:Yl(l.type);break;case 22:case 23:ul(l),Ji(),t!==null&&dt(Be);break;case 24:Yl(Mt)}}function nn(t,l){try{var e=l.updateQueue,a=e!==null?e.lastEffect:null;if(a!==null){var n=a.next;e=n;do{if((e.tag&t)===t){a=void 0;var u=e.create,i=e.inst;a=u(),i.destroy=a}e=e.next}while(e!==n)}}catch(f){yt(l,l.return,f)}}function re(t,l,e){try{var a=l.updateQueue,n=a!==null?a.lastEffect:null;if(n!==null){var u=n.next;a=u;do{if((a.tag&t)===t){var i=a.inst,f=i.destroy;if(f!==void 0){i.destroy=void 0,n=l;var d=e,x=f;try{x()}catch(D){yt(n,d,D)}}}a=a.next}while(a!==u)}}catch(D){yt(l,l.return,D)}}function Ir(t){var l=t.updateQueue;if(l!==null){var e=t.stateNode;try{wf(l,e)}catch(a){yt(t,t.return,a)}}}function Pr(t,l,e){e.props=Xe(t.type,t.memoizedProps),e.state=t.memoizedState;try{e.componentWillUnmount()}catch(a){yt(t,l,a)}}function un(t,l){try{var e=t.ref;if(e!==null){switch(t.tag){case 26:case 27:case 5:var a=t.stateNode;break;case 30:a=t.stateNode;break;default:a=t.stateNode}typeof e=="function"?t.refCleanup=e(a):e.current=a}}catch(n){yt(t,l,n)}}function Cl(t,l){var e=t.ref,a=t.refCleanup;if(e!==null)if(typeof a=="function")try{a()}catch(n){yt(t,l,n)}finally{t.refCleanup=null,t=t.alternate,t!=null&&(t.refCleanup=null)}else if(typeof e=="function")try{e(null)}catch(n){yt(t,l,n)}else e.current=null}function to(t){var l=t.type,e=t.memoizedProps,a=t.stateNode;try{t:switch(l){case"button":case"input":case"select":case"textarea":e.autoFocus&&a.focus();break t;case"img":e.src?a.src=e.src:e.srcSet&&(a.srcset=e.srcSet)}}catch(n){yt(t,t.return,n)}}function Tc(t,l,e){try{var a=t.stateNode;kh(a,t.type,e,l),a[Zt]=l}catch(n){yt(t,t.return,n)}}function lo(t){return t.tag===5||t.tag===3||t.tag===26||t.tag===27&&ge(t.type)||t.tag===4}function Ec(t){t:for(;;){for(;t.sibling===null;){if(t.return===null||lo(t.return))return null;t=t.return}for(t.sibling.return=t.return,t=t.sibling;t.tag!==5&&t.tag!==6&&t.tag!==18;){if(t.tag===27&&ge(t.type)||t.flags&2||t.child===null||t.tag===4)continue t;t.child.return=t,t=t.child}if(!(t.flags&2))return t.stateNode}}function Nc(t,l,e){var a=t.tag;if(a===5||a===6)t=t.stateNode,l?(e.nodeType===9?e.body:e.nodeName==="HTML"?e.ownerDocument.body:e).insertBefore(t,l):(l=e.nodeType===9?e.body:e.nodeName==="HTML"?e.ownerDocument.body:e,l.appendChild(t),e=e._reactRootContainer,e!=null||l.onclick!==null||(l.onclick=Rl));else if(a!==4&&(a===27&&ge(t.type)&&(e=t.stateNode,l=null),t=t.child,t!==null))for(Nc(t,l,e),t=t.sibling;t!==null;)Nc(t,l,e),t=t.sibling}function bu(t,l,e){var a=t.tag;if(a===5||a===6)t=t.stateNode,l?e.insertBefore(t,l):e.appendChild(t);else if(a!==4&&(a===27&&ge(t.type)&&(e=t.stateNode),t=t.child,t!==null))for(bu(t,l,e),t=t.sibling;t!==null;)bu(t,l,e),t=t.sibling}function eo(t){var l=t.stateNode,e=t.memoizedProps;try{for(var a=t.type,n=l.attributes;n.length;)l.removeAttributeNode(n[0]);Gt(l,a,e),l[Yt]=t,l[Zt]=e}catch(u){yt(t,t.return,u)}}var Ql=!1,Ot=!1,Mc=!1,ao=typeof WeakSet=="function"?WeakSet:Set,Lt=null;function Th(t,l){if(t=t.containerInfo,$c=Vu,t=yf(t),_i(t)){if("selectionStart"in t)var e={start:t.selectionStart,end:t.selectionEnd};else t:{e=(e=t.ownerDocument)&&e.defaultView||window;var a=e.getSelection&&e.getSelection();if(a&&a.rangeCount!==0){e=a.anchorNode;var n=a.anchorOffset,u=a.focusNode;a=a.focusOffset;try{e.nodeType,u.nodeType}catch{e=null;break t}var i=0,f=-1,d=-1,x=0,D=0,U=t,z=null;l:for(;;){for(var E;U!==e||n!==0&&U.nodeType!==3||(f=i+n),U!==u||a!==0&&U.nodeType!==3||(d=i+a),U.nodeType===3&&(i+=U.nodeValue.length),(E=U.firstChild)!==null;)z=U,U=E;for(;;){if(U===t)break l;if(z===e&&++x===n&&(f=i),z===u&&++D===a&&(d=i),(E=U.nextSibling)!==null)break;U=z,z=U.parentNode}U=E}e=f===-1||d===-1?null:{start:f,end:d}}else e=null}e=e||{start:0,end:0}}else e=null;for(Fc={focusedElem:t,selectionRange:e},Vu=!1,Lt=l;Lt!==null;)if(l=Lt,t=l.child,(l.subtreeFlags&1028)!==0&&t!==null)t.return=l,Lt=t;else for(;Lt!==null;){switch(l=Lt,u=l.alternate,t=l.flags,l.tag){case 0:if((t&4)!==0&&(t=l.updateQueue,t=t!==null?t.events:null,t!==null))for(e=0;e title"))),Gt(u,a,e),u[Yt]=t,Ht(u),a=u;break t;case"link":var i=rd("link","href",n).get(a+(e.href||""));if(i){for(var f=0;fpt&&(i=pt,pt=k,k=i);var v=mf(f,k),h=mf(f,pt);if(v&&h&&(E.rangeCount!==1||E.anchorNode!==v.node||E.anchorOffset!==v.offset||E.focusNode!==h.node||E.focusOffset!==h.offset)){var S=U.createRange();S.setStart(v.node,v.offset),E.removeAllRanges(),k>pt?(E.addRange(S),E.extend(h.node,h.offset)):(S.setEnd(h.node,h.offset),E.addRange(S))}}}}for(U=[],E=f;E=E.parentNode;)E.nodeType===1&&U.push({element:E,left:E.scrollLeft,top:E.scrollTop});for(typeof f.focus=="function"&&f.focus(),f=0;fe?32:e,_.T=null,e=Bc,Bc=null;var u=he,i=Wl;if(qt=0,xa=he=null,Wl=0,(mt&6)!==0)throw Error(o(331));var f=mt;if(mt|=4,yo(u.current),oo(u,u.current,i,e),mt=f,dn(0,!1),tl&&typeof tl.onPostCommitFiberRoot=="function")try{tl.onPostCommitFiberRoot(Ma,u)}catch{}return!0}finally{q.p=n,_.T=a,Uo(t,l)}}function qo(t,l,e){l=dl(e,l),l=yc(t.stateNode,l,2),t=ce(t,l,2),t!==null&&(Da(t,2),Dl(t))}function yt(t,l,e){if(t.tag===3)qo(t,t,e);else for(;l!==null;){if(l.tag===3){qo(l,t,e);break}else if(l.tag===1){var a=l.stateNode;if(typeof l.type.getDerivedStateFromError=="function"||typeof a.componentDidCatch=="function"&&(me===null||!me.has(a))){t=dl(e,t),e=qr(2),a=ce(l,e,2),a!==null&&(Br(e,a,l,t),Da(a,2),Dl(a));break}}l=l.return}}function Vc(t,l,e){var a=t.pingCache;if(a===null){a=t.pingCache=new Mh;var n=new Set;a.set(l,n)}else n=a.get(l),n===void 0&&(n=new Set,a.set(l,n));n.has(e)||(Oc=!0,n.add(e),t=Rh.bind(null,t,l,e),l.then(t,t))}function Rh(t,l,e){var a=t.pingCache;a!==null&&a.delete(l),t.pingedLanes|=t.suspendedLanes&e,t.warmLanes&=~e,bt===t&&(it&e)===e&&(Tt===4||Tt===3&&(it&62914560)===it&&300>Pt()-_u?(mt&2)===0&&_a(t,0):Uc|=e,Sa===it&&(Sa=0)),Dl(t)}function Bo(t,l){l===0&&(l=Ns()),t=De(t,l),t!==null&&(Da(t,l),Dl(t))}function qh(t){var l=t.memoizedState,e=0;l!==null&&(e=l.retryLane),Bo(t,e)}function Bh(t,l){var e=0;switch(t.tag){case 31:case 13:var a=t.stateNode,n=t.memoizedState;n!==null&&(e=n.retryLane);break;case 19:a=t.stateNode;break;case 22:a=t.stateNode._retryCache;break;default:throw Error(o(314))}a!==null&&a.delete(l),Bo(t,e)}function Hh(t,l){return Pu(t,l)}var Mu=null,ja=null,Xc=!1,Cu=!1,wc=!1,ve=0;function Dl(t){t!==ja&&t.next===null&&(ja===null?Mu=ja=t:ja=ja.next=t),Cu=!0,Xc||(Xc=!0,Yh())}function dn(t,l){if(!wc&&Cu){wc=!0;do for(var e=!1,a=Mu;a!==null;){if(t!==0){var n=a.pendingLanes;if(n===0)var u=0;else{var i=a.suspendedLanes,f=a.pingedLanes;u=(1<<31-ll(42|t)+1)-1,u&=n&~(i&~f),u=u&201326741?u&201326741|1:u?u|2:0}u!==0&&(e=!0,Vo(a,u))}else u=it,u=Rn(a,a===bt?u:0,a.cancelPendingCommit!==null||a.timeoutHandle!==-1),(u&3)===0||Ca(a,u)||(e=!0,Vo(a,u));a=a.next}while(e);wc=!1}}function Lh(){Ho()}function Ho(){Cu=Xc=!1;var t=0;ve!==0&&Wh()&&(t=ve);for(var l=Pt(),e=null,a=Mu;a!==null;){var n=a.next,u=Lo(a,l);u===0?(a.next=null,e===null?Mu=n:e.next=n,n===null&&(ja=e)):(e=a,(t!==0||(u&3)!==0)&&(Cu=!0)),a=n}qt!==0&&qt!==5||dn(t),ve!==0&&(ve=0)}function Lo(t,l){for(var e=t.suspendedLanes,a=t.pingedLanes,n=t.expirationTimes,u=t.pendingLanes&-62914561;0f)break;var D=d.transferSize,U=d.initiatorType;D&&Jo(U)&&(d=d.responseEnd,i+=D*(d"u"?null:document;function id(t,l,e){var a=Aa;if(a&&typeof l=="string"&&l){var n=rl(l);n='link[rel="'+t+'"][href="'+n+'"]',typeof e=="string"&&(n+='[crossorigin="'+e+'"]'),ud.has(n)||(ud.add(n),t={rel:t,crossOrigin:e,href:l},a.querySelector(n)===null&&(l=a.createElement("link"),Gt(l,"link",t),Ht(l),a.head.appendChild(l)))}}function n0(t){$l.D(t),id("dns-prefetch",t,null)}function u0(t,l){$l.C(t,l),id("preconnect",t,l)}function i0(t,l,e){$l.L(t,l,e);var a=Aa;if(a&&t&&l){var n='link[rel="preload"][as="'+rl(l)+'"]';l==="image"&&e&&e.imageSrcSet?(n+='[imagesrcset="'+rl(e.imageSrcSet)+'"]',typeof e.imageSizes=="string"&&(n+='[imagesizes="'+rl(e.imageSizes)+'"]')):n+='[href="'+rl(t)+'"]';var u=n;switch(l){case"style":u=Ta(t);break;case"script":u=Ea(t)}pl.has(u)||(t=p({rel:"preload",href:l==="image"&&e&&e.imageSrcSet?void 0:t,as:l},e),pl.set(u,t),a.querySelector(n)!==null||l==="style"&&a.querySelector(vn(u))||l==="script"&&a.querySelector(gn(u))||(l=a.createElement("link"),Gt(l,"link",t),Ht(l),a.head.appendChild(l)))}}function c0(t,l){$l.m(t,l);var e=Aa;if(e&&t){var a=l&&typeof l.as=="string"?l.as:"script",n='link[rel="modulepreload"][as="'+rl(a)+'"][href="'+rl(t)+'"]',u=n;switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":u=Ea(t)}if(!pl.has(u)&&(t=p({rel:"modulepreload",href:t},l),pl.set(u,t),e.querySelector(n)===null)){switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(e.querySelector(gn(u)))return}a=e.createElement("link"),Gt(a,"link",t),Ht(a),e.head.appendChild(a)}}}function s0(t,l,e){$l.S(t,l,e);var a=Aa;if(a&&t){var n=Je(a).hoistableStyles,u=Ta(t);l=l||"default";var i=n.get(u);if(!i){var f={loading:0,preload:null};if(i=a.querySelector(vn(u)))f.loading=5;else{t=p({rel:"stylesheet",href:t,"data-precedence":l},e),(e=pl.get(u))&&ns(t,e);var d=i=a.createElement("link");Ht(d),Gt(d,"link",t),d._p=new Promise(function(x,D){d.onload=x,d.onerror=D}),d.addEventListener("load",function(){f.loading|=1}),d.addEventListener("error",function(){f.loading|=2}),f.loading|=4,qu(i,l,a)}i={type:"stylesheet",instance:i,count:1,state:f},n.set(u,i)}}}function f0(t,l){$l.X(t,l);var e=Aa;if(e&&t){var a=Je(e).hoistableScripts,n=Ea(t),u=a.get(n);u||(u=e.querySelector(gn(n)),u||(t=p({src:t,async:!0},l),(l=pl.get(n))&&us(t,l),u=e.createElement("script"),Ht(u),Gt(u,"link",t),e.head.appendChild(u)),u={type:"script",instance:u,count:1,state:null},a.set(n,u))}}function r0(t,l){$l.M(t,l);var e=Aa;if(e&&t){var a=Je(e).hoistableScripts,n=Ea(t),u=a.get(n);u||(u=e.querySelector(gn(n)),u||(t=p({src:t,async:!0,type:"module"},l),(l=pl.get(n))&&us(t,l),u=e.createElement("script"),Ht(u),Gt(u,"link",t),e.head.appendChild(u)),u={type:"script",instance:u,count:1,state:null},a.set(n,u))}}function cd(t,l,e,a){var n=(n=Fl.current)?Ru(n):null;if(!n)throw Error(o(446));switch(t){case"meta":case"title":return null;case"style":return typeof e.precedence=="string"&&typeof e.href=="string"?(l=Ta(e.href),e=Je(n).hoistableStyles,a=e.get(l),a||(a={type:"style",instance:null,count:0,state:null},e.set(l,a)),a):{type:"void",instance:null,count:0,state:null};case"link":if(e.rel==="stylesheet"&&typeof e.href=="string"&&typeof e.precedence=="string"){t=Ta(e.href);var u=Je(n).hoistableStyles,i=u.get(t);if(i||(n=n.ownerDocument||n,i={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},u.set(t,i),(u=n.querySelector(vn(t)))&&!u._p&&(i.instance=u,i.state.loading=5),pl.has(t)||(e={rel:"preload",as:"style",href:e.href,crossOrigin:e.crossOrigin,integrity:e.integrity,media:e.media,hrefLang:e.hrefLang,referrerPolicy:e.referrerPolicy},pl.set(t,e),u||o0(n,t,e,i.state))),l&&a===null)throw Error(o(528,""));return i}if(l&&a!==null)throw Error(o(529,""));return null;case"script":return l=e.async,e=e.src,typeof e=="string"&&l&&typeof l!="function"&&typeof l!="symbol"?(l=Ea(e),e=Je(n).hoistableScripts,a=e.get(l),a||(a={type:"script",instance:null,count:0,state:null},e.set(l,a)),a):{type:"void",instance:null,count:0,state:null};default:throw Error(o(444,t))}}function Ta(t){return'href="'+rl(t)+'"'}function vn(t){return'link[rel="stylesheet"]['+t+"]"}function sd(t){return p({},t,{"data-precedence":t.precedence,precedence:null})}function o0(t,l,e,a){t.querySelector('link[rel="preload"][as="style"]['+l+"]")?a.loading=1:(l=t.createElement("link"),a.preload=l,l.addEventListener("load",function(){return a.loading|=1}),l.addEventListener("error",function(){return a.loading|=2}),Gt(l,"link",e),Ht(l),t.head.appendChild(l))}function Ea(t){return'[src="'+rl(t)+'"]'}function gn(t){return"script[async]"+t}function fd(t,l,e){if(l.count++,l.instance===null)switch(l.type){case"style":var a=t.querySelector('style[data-href~="'+rl(e.href)+'"]');if(a)return l.instance=a,Ht(a),a;var n=p({},e,{"data-href":e.href,"data-precedence":e.precedence,href:null,precedence:null});return a=(t.ownerDocument||t).createElement("style"),Ht(a),Gt(a,"style",n),qu(a,e.precedence,t),l.instance=a;case"stylesheet":n=Ta(e.href);var u=t.querySelector(vn(n));if(u)return l.state.loading|=4,l.instance=u,Ht(u),u;a=sd(e),(n=pl.get(n))&&ns(a,n),u=(t.ownerDocument||t).createElement("link"),Ht(u);var i=u;return i._p=new Promise(function(f,d){i.onload=f,i.onerror=d}),Gt(u,"link",a),l.state.loading|=4,qu(u,e.precedence,t),l.instance=u;case"script":return u=Ea(e.src),(n=t.querySelector(gn(u)))?(l.instance=n,Ht(n),n):(a=e,(n=pl.get(u))&&(a=p({},e),us(a,n)),t=t.ownerDocument||t,n=t.createElement("script"),Ht(n),Gt(n,"link",a),t.head.appendChild(n),l.instance=n);case"void":return null;default:throw Error(o(443,l.type))}else l.type==="stylesheet"&&(l.state.loading&4)===0&&(a=l.instance,l.state.loading|=4,qu(a,e.precedence,t));return l.instance}function qu(t,l,e){for(var a=e.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),n=a.length?a[a.length-1]:null,u=n,i=0;i title"):null)}function d0(t,l,e){if(e===1||l.itemProp!=null)return!1;switch(t){case"meta":case"title":return!0;case"style":if(typeof l.precedence!="string"||typeof l.href!="string"||l.href==="")break;return!0;case"link":if(typeof l.rel!="string"||typeof l.href!="string"||l.href===""||l.onLoad||l.onError)break;switch(l.rel){case"stylesheet":return t=l.disabled,typeof l.precedence=="string"&&t==null;default:return!0}case"script":if(l.async&&typeof l.async!="function"&&typeof l.async!="symbol"&&!l.onLoad&&!l.onError&&l.src&&typeof l.src=="string")return!0}return!1}function dd(t){return!(t.type==="stylesheet"&&(t.state.loading&3)===0)}function m0(t,l,e,a){if(e.type==="stylesheet"&&(typeof a.media!="string"||matchMedia(a.media).matches!==!1)&&(e.state.loading&4)===0){if(e.instance===null){var n=Ta(a.href),u=l.querySelector(vn(n));if(u){l=u._p,l!==null&&typeof l=="object"&&typeof l.then=="function"&&(t.count++,t=Hu.bind(t),l.then(t,t)),e.state.loading|=4,e.instance=u,Ht(u);return}u=l.ownerDocument||l,a=sd(a),(n=pl.get(n))&&ns(a,n),u=u.createElement("link"),Ht(u);var i=u;i._p=new Promise(function(f,d){i.onload=f,i.onerror=d}),Gt(u,"link",a),e.instance=u}t.stylesheets===null&&(t.stylesheets=new Map),t.stylesheets.set(e,l),(l=e.state.preload)&&(e.state.loading&3)===0&&(t.count++,e=Hu.bind(t),l.addEventListener("load",e),l.addEventListener("error",e))}}var is=0;function h0(t,l){return t.stylesheets&&t.count===0&&Yu(t,t.stylesheets),0is?50:800)+l);return t.unsuspend=e,function(){t.unsuspend=null,clearTimeout(a),clearTimeout(n)}}:null}function Hu(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Yu(this,this.stylesheets);else if(this.unsuspend){var t=this.unsuspend;this.unsuspend=null,t()}}}var Lu=null;function Yu(t,l){t.stylesheets=null,t.unsuspend!==null&&(t.count++,Lu=new Map,l.forEach(y0,t),Lu=null,Hu.call(t))}function y0(t,l){if(!(l.state.loading&4)){var e=Lu.get(t);if(e)var a=e.get(null);else{e=new Map,Lu.set(t,e);for(var n=t.querySelectorAll("link[data-precedence],style[data-precedence]"),u=0;u"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(c)}catch(r){console.error(r)}}return c(),hs.exports=C0(),hs.exports}var O0=D0();const wd=g.createContext({windows:[],openWindow:()=>{},closeWindow:()=>{},bringToFront:()=>{}}),U0=({children:c})=>{const[r,m]=g.useState([]),o=g.useRef(1e4),b=g.useCallback((N,y,T)=>{m(B=>B.find(A=>A.id===N)?B.map(A=>A.id===N?{...A,zIndex:++o.current}:A):[...B,{id:N,title:y,charName:T,zIndex:++o.current}])},[]),j=g.useCallback(N=>{m(y=>y.filter(T=>T.id!==N))},[]),M=g.useCallback(N=>{m(y=>y.map(T=>T.id===N?{...T,zIndex:++o.current}:T))},[]);return s.jsx(wd.Provider,{value:{windows:r,openWindow:b,closeWindow:j,bringToFront:M},children:c})},An=()=>g.useContext(wd),bl={west:-102.1,east:102.1,north:102.1,south:-102.1};function Tn(c,r,m,o){const b=(c-bl.west)/(bl.east-bl.west)*m,j=(bl.north-r)/(bl.north-bl.south)*o;return{x:b,y:j}}function R0(c,r,m,o,b,j,M){const N=(c-o)/m,y=(r-b)/m,T=bl.west+N/j*(bl.east-bl.west),B=bl.north-y/M*(bl.north-bl.south);return{ew:T,ns:B}}function gs(c,r){const m=c>=0?"N":"S",o=r>=0?"E":"W";return`${Math.abs(c).toFixed(1)}${m}, ${Math.abs(r).toFixed(1)}${o}`}const Gd=jn.memo(({players:c,imgW:r,imgH:m,getColor:o,onHover:b,onSelect:j,selectedPlayer:M})=>{const{openWindow:N}=An(),[y,T]=g.useState(null);g.useEffect(()=>{const p=()=>T(null);return y&&window.addEventListener("click",p),()=>window.removeEventListener("click",p)},[y]);const B=g.useMemo(()=>c.filter(p=>p.ew!==void 0&&p.ns!==void 0).map(p=>({...p,pos:Tn(p.ew,p.ns,r,m),color:o(p.character_name)})),[c,r,m,o]);return s.jsxs("div",{className:"ml-dots-layer",children:[B.map(p=>s.jsx("div",{className:`ml-dot ${M===p.character_name?"ml-dot-selected":""}`,style:{left:p.pos.x,top:p.pos.y,backgroundColor:p.color},onMouseEnter:A=>{var L;const R=(L=A.currentTarget.closest(".ml-map-container"))==null?void 0:L.getBoundingClientRect();R&&b(p,A.clientX-R.left,A.clientY-R.top)},onMouseLeave:()=>b(null,0,0),onClick:()=>j(p.character_name),onDoubleClick:()=>N(`chat-${p.character_name}`,`Chat: ${p.character_name}`,p.character_name),onContextMenu:A=>{var C;A.preventDefault();const R=p.character_name,L=(C=A.currentTarget.closest(".ml-map-container"))==null?void 0:C.getBoundingClientRect(),$=L?A.clientX-L.left:A.clientX,V=L?A.clientY-L.top:A.clientY;T({name:R,x:$,y:V})}},p.character_name)),y&&s.jsx("div",{style:{position:"fixed",left:y.x+410,top:y.y,background:"#1a1a1a",border:"1px solid #444",borderRadius:4,zIndex:9999,padding:"2px 0",fontSize:"0.75rem",boxShadow:"0 4px 12px rgba(0,0,0,0.5)",minWidth:120},children:[{label:"Chat",id:"chat"},{label:"Stats",id:"stats"},{label:"Inventory",id:"inv"},{label:"Character",id:"char"},{label:"Combat",id:"combat"},{label:"Radar",id:"radar"}].map(p=>s.jsx("div",{onClick:()=>{N(`${p.id}-${y.name}`,`${p.label}: ${y.name}`,y.name),T(null)},style:{padding:"4px 12px",cursor:"pointer",color:"#ccc"},onMouseEnter:A=>A.currentTarget.style.background="#333",onMouseLeave:A=>A.currentTarget.style.background="",children:p.label},p.id))})]})});Gd.displayName="PlayerDots";const ku="/api";async function It(c){const r=await fetch(`${ku}${c}`,{credentials:"include"});if(!r.ok)throw new Error(`API ${c}: ${r.status}`);return r.json()}async function Ss(c,r){var o;const m=await fetch(`${ku}${c}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify(r??{})});if(!m.ok){let b="";try{b=((o=await m.json())==null?void 0:o.detail)??""}catch{}throw new Error(`API ${c}: ${m.status}${b?` (${b})`:""}`)}return m.json()}async function q0(c,r){var o;const m=await fetch(`${ku}${c}`,{method:"PATCH",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify(r??{})});if(!m.ok){let b="";try{b=((o=await m.json())==null?void 0:o.detail)??""}catch{}throw new Error(`API ${c}: ${m.status}${b?` (${b})`:""}`)}return m.json()}async function B0(c){var m;const r=await fetch(`${ku}${c}`,{method:"DELETE",credentials:"include"});if(!r.ok){let o="";try{o=((m=await r.json())==null?void 0:m.detail)??""}catch{}throw new Error(`API ${c}: ${r.status}${o?` (${o})`:""}`)}return r.json()}function H0(){return`${location.protocol==="https:"?"wss:":"ws:"}//${location.host}/api/ws/live`}const Qd=jn.memo(({imgW:c,imgH:r,getColor:m})=>{const[o,b]=g.useState([]);g.useEffect(()=>{const M=async()=>{try{const y=await It("/trails/?seconds=600");b(y.trails??[])}catch{}};M();const N=setInterval(M,2e3);return()=>clearInterval(N)},[]);const j=g.useMemo(()=>{const M={};for(const N of o){const{x:y,y:T}=Tn(N.ew,N.ns,c,r);M[N.character_name]||(M[N.character_name]=[]),M[N.character_name].push(`${y},${T}`)}return Object.entries(M).filter(([,N])=>N.length>=2).map(([N,y])=>({name:N,points:y.join(" ")}))},[o,c,r]);return s.jsx("svg",{className:"ml-trails-svg",viewBox:`0 0 ${c} ${r}`,preserveAspectRatio:"none",children:j.map(M=>s.jsx("polyline",{points:M.points,stroke:m(M.name),fill:"none",strokeWidth:2,strokeOpacity:.7,strokeLinecap:"round",strokeLinejoin:"round"},M.name))})});Qd.displayName="TrailsSVG";const L0=({imgW:c,imgH:r,enabled:m})=>{const o=g.useRef(null),[b,j]=g.useState([]);return g.useEffect(()=>{if(!m)return;(async()=>{try{const N=await It("/spawns/heatmap?hours=24&limit=50000");j(N.spawn_points??[])}catch{}})()},[m]),g.useEffect(()=>{const M=o.current;if(!M||!m||b.length===0||c===0)return;M.width=c,M.height=r;const N=M.getContext("2d");if(N){N.clearRect(0,0,c,r);for(const y of b){const{x:T,y:B}=Tn(y.ew,y.ns,c,r),p=Math.max(5,Math.min(12,5+Math.sqrt(y.intensity*.5))),A=N.createRadialGradient(T,B,0,T,B,p);A.addColorStop(0,`rgba(255, 0, 0, ${Math.min(.9,y.intensity/40)})`),A.addColorStop(.6,`rgba(255, 100, 0, ${Math.min(.4,y.intensity/120)})`),A.addColorStop(1,"rgba(255, 150, 0, 0)"),N.fillStyle=A,N.fillRect(T-p,B-p,p*2,p*2)}}},[b,c,r,m]),m?s.jsx("canvas",{ref:o,className:"ml-heatmap-canvas"}):null},Y0=({imgW:c,imgH:r,enabled:m})=>{const[o,b]=g.useState([]);g.useEffect(()=>{if(!m)return;const M=async()=>{try{const y=await It("/portals");b(y.portals??[])}catch{}};M();const N=setInterval(M,6e4);return()=>clearInterval(N)},[m]);const j=g.useMemo(()=>o.map(M=>({...M,pos:Tn(M.coordinates.ew,M.coordinates.ns,c,r)})),[o,c,r]);return!m||j.length===0?null:s.jsx("div",{className:"ml-portals-layer",children:j.map((M,N)=>s.jsx("div",{className:"ml-portal-icon",style:{left:M.pos.x,top:M.pos.y},title:`${M.portal_name} (by ${M.discovered_by})`},N))})},Od="mo-midsummer",V0=!1,Zd=g.createContext(null),X0=({children:c})=>{const[r,m]=g.useState(()=>localStorage.getItem(Od)!=="off"),o=V0;g.useEffect(()=>{document.documentElement.removeAttribute("data-midsummer")},[o]);const b=g.useCallback(()=>{m(j=>{const M=!j;return localStorage.setItem(Od,M?"on":"off"),M})},[]);return s.jsx(Zd.Provider,{value:{enabled:o,toggle:b},children:c})};function xs(){const c=g.useContext(Zd);if(!c)throw new Error("useMidsummer must be used within MidsummerProvider");return c}const Ud=6,w0=(c,r)=>({x:c/2,y:r/2}),G0=({imgW:c,imgH:r})=>{const{enabled:m}=xs();if(!m||c===0)return null;const{x:o,y:b}=w0(c,r);return s.jsxs("div",{className:"ms-maypole",style:{left:o,top:b},"aria-hidden":"true",children:[s.jsx("div",{className:"ms-maypole-pole"}),s.jsx("div",{className:"ms-maypole-ring",children:Array.from({length:Ud}).map((j,M)=>s.jsx("span",{className:"ms-frog",style:{transform:`rotate(${360/Ud*M}deg) translateY(-40px)`},children:"🐸"},M))})]})},Rd=20,qd=.3,Q0=({players:c,getColor:r,onSelectPlayer:m,showHeatmap:o,showPortals:b,selectedPlayer:j})=>{var Ut;const M=g.useRef(null),N=g.useRef(null),[y,T]=g.useState({w:0,h:0}),[B,p]=g.useState(null),A=g.useRef(null),R=g.useRef({scale:1,offX:0,offY:0}),L=g.useRef({dragging:!1,sx:0,sy:0,startOffX:0,startOffY:0}),$=g.useCallback(()=>{if(N.current){const{scale:lt,offX:at,offY:Z}=R.current;N.current.style.transform=`translate(${at}px, ${Z}px) scale(${lt})`}},[]),V=g.useCallback(lt=>{const at=lt.currentTarget;if(T({w:at.naturalWidth,h:at.naturalHeight}),M.current){const Z=M.current.clientWidth,J=M.current.clientHeight,P=Math.min(Z/at.naturalWidth,J/at.naturalHeight);R.current={scale:P,offX:(Z-at.naturalWidth*P)/2,offY:(J-at.naturalHeight*P)/2},$()}},[$]),C=g.useCallback(lt=>{var Tl;lt.preventDefault();const at=(Tl=M.current)==null?void 0:Tl.getBoundingClientRect();if(!at)return;const Z=R.current,J=lt.deltaY<0?1.1:.9,P=Math.min(Rd,Math.max(qd,Z.scale*J)),Rt=P/Z.scale,jt=lt.clientX-at.left,Ol=lt.clientY-at.top;R.current={scale:P,offX:jt-(jt-Z.offX)*Rt,offY:Ol-(Ol-Z.offY)*Rt},$()},[$]),Y=g.useCallback(lt=>{if(lt.button!==0)return;const at=R.current;L.current={dragging:!0,sx:lt.clientX,sy:lt.clientY,startOffX:at.offX,startOffY:at.offY}},[]);g.useEffect(()=>{const lt=Z=>{const J=L.current;if(J.dragging&&(R.current.offX=J.startOffX+(Z.clientX-J.sx),R.current.offY=J.startOffY+(Z.clientY-J.sy),$()),M.current&&y.w>0&&A.current){const P=M.current.getBoundingClientRect(),Rt=R.current,jt=R0(Z.clientX-P.left,Z.clientY-P.top,Rt.scale,Rt.offX,Rt.offY,y.w,y.h);A.current.textContent=gs(jt.ns,jt.ew)}},at=()=>{L.current.dragging=!1};return window.addEventListener("mousemove",lt),window.addEventListener("mouseup",at),()=>{window.removeEventListener("mousemove",lt),window.removeEventListener("mouseup",at)}},[$,y.w,y.h]);const F=g.useRef(null);g.useEffect(()=>{if(!j||y.w===0||!M.current||F.current===j)return;const lt=c.find(Rt=>Rt.character_name===j);if(!lt)return;F.current=j;const{x:at,y:Z}=Tn(lt.ew,lt.ns,y.w,y.h),J=M.current.getBoundingClientRect(),P=3;R.current={scale:Math.min(Rd,Math.max(qd,P)),offX:J.width/2-at*P,offY:J.height/2-Z*P},$()},[j,c,y.w,y.h,$]),g.useEffect(()=>{j||(F.current=null)},[j]);const zt=g.useCallback((lt,at,Z)=>{p(lt?{x:at,y:Z,player:lt}:null)},[]);return s.jsxs("div",{className:"ml-map-container",ref:M,onWheel:C,onMouseDown:Y,children:[s.jsxs("div",{ref:N,className:"ml-map-group",children:[s.jsx("img",{src:"/dereth.png",alt:"Dereth",className:"ml-map-img",onLoad:V,draggable:!1}),y.w>0&&s.jsxs(s.Fragment,{children:[s.jsx(L0,{imgW:y.w,imgH:y.h,enabled:o}),s.jsx(Qd,{imgW:y.w,imgH:y.h,getColor:r}),s.jsx(Gd,{players:c,imgW:y.w,imgH:y.h,getColor:r,onHover:zt,onSelect:m,selectedPlayer:j}),s.jsx(Y0,{imgW:y.w,imgH:y.h,enabled:b}),s.jsx(G0,{imgW:y.w,imgH:y.h})]})]}),B&&s.jsxs("div",{className:"ml-tooltip",style:{left:B.x+12,top:B.y-10},children:[s.jsx("strong",{children:B.player.character_name}),s.jsx("br",{}),gs(B.player.ns,B.player.ew),s.jsx("br",{}),B.player.kills_per_hour," kph · ",(Ut=B.player.kills)==null?void 0:Ut.toLocaleString()," kills"]}),s.jsx("div",{className:"ml-coords",ref:A})]})},Kd=jn.memo(({player:c,vitals:r,color:m,onSelect:o,isSelected:b})=>{var B,p;const{openWindow:j}=An(),M=(c.vt_state||"idle").toLowerCase(),N=M==="combat"||M==="hunt",y=(c.total_rares??0)>0?Math.round((c.total_kills??0)/(c.total_rares??1)).toLocaleString():null,T=c.character_name;return s.jsxs("li",{className:`ml-player-row ${b?"ml-player-selected":""}`,style:{borderLeftColor:m},children:[s.jsxs("div",{className:"ml-pr-header",onClick:o,children:[s.jsx("span",{className:"ml-pr-name",children:T}),s.jsx("span",{className:"ml-pr-coords",children:gs(c.ns,c.ew)})]}),s.jsxs("div",{className:"ml-pr-vitals",children:[s.jsx("div",{className:"ml-vital-bar hp",children:s.jsx("div",{className:"ml-vital-fill",style:{width:`${(r==null?void 0:r.health_percentage)??0}%`}})}),s.jsx("div",{className:"ml-vital-bar sta",children:s.jsx("div",{className:"ml-vital-fill",style:{width:`${(r==null?void 0:r.stamina_percentage)??0}%`}})}),s.jsx("div",{className:"ml-vital-bar mana",children:s.jsx("div",{className:"ml-vital-fill",style:{width:`${(r==null?void 0:r.mana_percentage)??0}%`}})})]}),s.jsxs("div",{className:"ml-pr-grid",children:[s.jsxs("span",{className:"ml-gs",title:"Session kills",children:["⚔️ ",((B=c.kills)==null?void 0:B.toLocaleString())??0]}),s.jsxs("span",{className:"ml-gs",title:"Total kills",children:["🏆 ",(c.total_kills??0).toLocaleString()]}),s.jsxs("span",{className:"ml-gs",title:"Kills per hour",children:[c.kills_per_hour??"0"," ",s.jsx("span",{className:"ml-suffix",children:"KPH"})]}),s.jsxs("span",{className:"ml-gs",title:"Rares (session / total)",children:["💎 ",c.session_rares??0," / ",c.total_rares??0]}),s.jsx("span",{className:"ml-gs",title:"Kills per rare",children:y?s.jsxs(s.Fragment,{children:["📊 ",y," ",s.jsx("span",{className:"ml-suffix",children:"KPR"})]}):""}),s.jsx("span",{className:`ml-meta-pill ${N?"active":M!=="idle"&&M!=="default"&&M!==""?"other":""}`,children:c.vt_state||"idle"}),s.jsxs("span",{className:"ml-gs",title:"Online time",children:["🕐 ",((p=c.onlinetime)==null?void 0:p.replace(/^00\./,""))??"--"]}),s.jsxs("span",{className:"ml-gs",title:"Deaths",children:["☠️ ",c.deaths??"0"]}),s.jsxs("span",{className:"ml-gs",title:"Prismatic tapers",children:[s.jsx("img",{src:"/prismatic-taper-icon.png",className:"ml-taper-icon",alt:""}),c.prismatic_taper_count??"0"]})]}),s.jsxs("div",{className:"ml-pr-buttons",children:[s.jsx("button",{className:"ml-btn accent",onClick:()=>j(`chat-${T}`,`Chat: ${T}`,T),children:"Chat"}),s.jsx("button",{className:"ml-btn accent",onClick:()=>j(`stats-${T}`,`Stats: ${T}`,T),children:"Stats"}),s.jsx("button",{className:"ml-btn accent",onClick:()=>j(`inv-${T}`,`Inventory: ${T}`,T),children:"Inv"}),s.jsx("button",{className:"ml-btn",onClick:()=>j(`char-${T}`,`Character: ${T}`,T),children:"Char"}),s.jsx("button",{className:"ml-btn",onClick:()=>j(`combat-${T}`,`Combat: ${T}`,T),children:"Combat"}),s.jsx("button",{className:"ml-btn",onClick:()=>j(`radar-${T}`,`Radar: ${T}`,T),children:"Radar"})]})]})});Kd.displayName="PlayerRow";const Z0=({players:c,vitals:r,getColor:m,onSelect:o,selectedPlayer:b})=>{const j=g.useRef(null),[M,N]=g.useState(!1),y=g.useCallback(()=>{j.current&&N(j.current.scrollTop>200)},[]);return s.jsxs("div",{style:{position:"relative",flex:1,minHeight:0},children:[s.jsx("ul",{className:"ml-player-list",ref:j,onScroll:y,children:c.map(T=>s.jsx(Kd,{player:T,vitals:r.get(T.character_name)??null,color:m(T.character_name),onSelect:()=>o(T.character_name),isSelected:b===T.character_name},T.character_name))}),M&&s.jsx("button",{onClick:()=>{var T;(T=j.current)==null||T.scrollTo({top:0,behavior:"smooth"})},style:{position:"absolute",bottom:8,right:8,width:28,height:28,borderRadius:"50%",background:"rgba(68,136,255,0.2)",border:"1px solid rgba(68,136,255,0.4)",color:"#6af",cursor:"pointer",fontSize:"0.8rem",display:"flex",alignItems:"center",justifyContent:"center"},children:"▲"})]})},K0=[{key:"name",label:"Name"},{key:"kph",label:"KPH"},{key:"skills",label:"S.Kills"},{key:"srares",label:"S.Rares"},{key:"tkills",label:"T.Kills"},{key:"kpr",label:"KPR"}],k0=({value:c,onChange:r})=>s.jsx("div",{className:"ml-sort-buttons",children:K0.map(m=>s.jsx("button",{className:`ml-sort-btn ${c===m.key?"active":""}`,onClick:()=>r(m.key),children:m.label},m.key))}),J0=()=>It("/live"),W0=()=>It("/combat-stats"),$0=()=>It("/server-health"),F0=()=>It("/total-rares"),I0=()=>It("/total-kills"),uv=(c,r)=>Ss("/agent/ask",{message:c,session_id:r}),iv=()=>Ss("/agent/sessions/new",{}),cv=c=>It(`/agent/sessions/${encodeURIComponent(c)}/history`),P0=()=>It("/me");async function ty(){await fetch("/api/logout",{credentials:"include",redirect:"manual"}),window.location.href="/login"}const sv=()=>It("/api-admin/users"),fv=(c,r,m)=>Ss("/api-admin/users",{username:c,password:r,is_admin:m}),rv=(c,r)=>q0(`/api-admin/users/${c}`,r),ov=c=>B0(`/api-admin/users/${c}`);function ly(){const[c,r]=g.useState(null),[m,o]=g.useState(!0);return g.useEffect(()=>{let b=!1;return P0().then(j=>{b||r(j)}).catch(()=>{b||r(null)}).finally(()=>{b||o(!1)}),()=>{b=!0}},[]),{user:c,loading:m}}const ey=()=>{const{openWindow:c}=An(),{user:r}=ly(),m=!!(r!=null&&r.is_admin),o=g.useCallback(async()=>{if(confirm("Log out?"))try{await ty()}catch{window.location.href="/login"}},[]);return s.jsxs("div",{className:"ml-tool-links",children:[s.jsx("span",{className:"ml-tool-link",style:{cursor:"pointer"},onClick:()=>c("agent","Overlord Assistant"),children:"🤖 Assistant"}),s.jsx("span",{className:"ml-tool-link",style:{cursor:"pointer"},title:"Opens the player dashboard in a new tab",onClick:()=>window.open("/?view=dashboard","_blank","noopener"),children:"👥 Dashboard ↗"}),s.jsx("span",{className:"ml-tool-link",style:{cursor:"pointer"},onClick:()=>c("queststatus","Quest Status"),children:"📜 Quests"}),s.jsx("span",{className:"ml-tool-link",style:{cursor:"pointer"},onClick:()=>c("issues","Issues Board"),children:"📋 Issues"}),s.jsx("span",{className:"ml-tool-link",style:{cursor:"pointer"},onClick:()=>c("vitalsharing","Vital Sharing"),children:"🤝 Vitals"}),s.jsx("span",{className:"ml-tool-link",style:{cursor:"pointer"},onClick:()=>c("combatpicker","Combat Stats"),children:"⚔️ Combat"}),m&&s.jsx("span",{className:"ml-tool-link",style:{cursor:"pointer"},onClick:()=>c("adminusers","Admin · Users"),children:"🛡️ Admin"}),s.jsxs("span",{className:"ml-tool-link ml-tool-link-logout",style:{cursor:"pointer"},onClick:o,title:r?`Logged in as ${r.username}`:"Log out",children:["🚪 Log out",r?` (${r.username})`:""]})]})},ay=({players:c,vitals:r,serverHealth:m,totalRares:o,totalKills:b,getColor:j,onSelectPlayer:M,showHeatmap:N,showPortals:y,onToggleHeatmap:T,onTogglePortals:B,version:p,selectedPlayer:A})=>{var lt,at;const[R,L]=g.useState("name"),[$,V]=g.useState(""),C=g.useMemo(()=>c.reduce((Z,J)=>Z+(parseInt(J.kills_per_hour)||0),0),[c]),Y=((lt=m==null?void 0:m.status)==null?void 0:lt.toLowerCase())==="online"||((at=m==null?void 0:m.status)==null?void 0:at.toLowerCase())==="up",F=g.useDeferredValue(c),zt=g.useDeferredValue(r),Ut=g.useMemo(()=>{let Z=[...F];switch($&&(Z=Z.filter(J=>J.character_name.toLowerCase().startsWith($.toLowerCase()))),R){case"kph":Z.sort((J,P)=>(parseInt(P.kills_per_hour)||0)-(parseInt(J.kills_per_hour)||0));break;case"skills":Z.sort((J,P)=>(P.kills||0)-(J.kills||0));break;case"srares":Z.sort((J,P)=>(P.session_rares??0)-(J.session_rares??0));break;case"tkills":Z.sort((J,P)=>(P.total_kills??0)-(J.total_kills??0));break;case"kpr":Z.sort((J,P)=>{const Rt=(J.total_kills??0)/Math.max(1,J.total_rares??1),jt=(P.total_kills??0)/Math.max(1,P.total_rares??1);return Rt-jt});break;default:Z.sort((J,P)=>J.character_name.localeCompare(P.character_name))}return Z},[F,R,$]);return s.jsxs("div",{className:"ml-sidebar",children:[p&&s.jsxs("div",{className:"ml-version",children:["v",p]}),s.jsx("div",{className:"ml-sidebar-header",children:s.jsxs("span",{className:"ml-sidebar-title",style:{cursor:"pointer"},onClick:()=>{const Z=document.createElement("div");Z.style.cssText="position:fixed;top:0;left:0;width:100vw;height:100vh;background:#000;z-index:999999;display:flex;align-items:center;justify-content:center;";const J=document.createElement("video");J.src="/rick.mp4",J.autoplay=!0,J.loop=!0,J.style.cssText="width:100vw;height:100vh;object-fit:cover;",Z.appendChild(J),document.body.appendChild(Z),document.body.style.animation="ml-shake 0.05s 30";const P=document.createElement("style");P.textContent="@keyframes ml-shake{0%,100%{transform:translate(0) rotate(0)}25%{transform:translate(-15px,10px) rotate(-2deg)}50%{transform:translate(15px,-10px) rotate(2deg)}75%{transform:translate(-10px,-15px) rotate(-1deg)}} @keyframes ml-spin{from{transform:rotate(0)}to{transform:rotate(360deg)}}",document.head.appendChild(P),setTimeout(()=>{Z.style.animation="ml-spin 3s linear infinite"},1500),J.play().catch(()=>{})},children:["Active Mosswart Enjoyers (",c.length,")"]})}),s.jsxs("div",{className:"ml-server-status",children:[s.jsx("span",{className:`ml-status-dot ${Y?"online":"offline"}`}),s.jsxs("span",{className:"ml-status-text",children:["Coldeve ",Y?"Online":"Offline"]}),(m==null?void 0:m.player_count)!=null&&s.jsxs("span",{className:"ml-status-detail",children:["👥 ",m.player_count]}),(m==null?void 0:m.latency_ms)!=null&&s.jsxs("span",{className:"ml-status-detail",children:[Math.round(m.latency_ms),"ms"]}),(m==null?void 0:m.uptime_seconds)!=null&&s.jsxs("span",{className:"ml-status-detail",children:["Up: ",Math.floor(m.uptime_seconds/3600),"h"]})]}),s.jsxs("div",{className:"ml-counters",children:[s.jsxs("div",{className:"ml-counter rares",children:[s.jsx("span",{className:"ml-counter-val",children:o}),s.jsx("span",{className:"ml-counter-lbl",children:"Rares"})]}),s.jsxs("div",{className:`ml-counter kph ${C>5e3?"ultra":""}`,children:[s.jsx("span",{className:"ml-counter-val",children:C.toLocaleString()}),s.jsx("span",{className:"ml-counter-lbl",children:"Server KPH"})]}),s.jsxs("div",{className:"ml-counter kills",children:[s.jsx("span",{className:"ml-counter-val",children:b.toLocaleString()}),s.jsx("span",{className:"ml-counter-lbl",children:"Kills"})]})]}),s.jsxs("div",{className:"ml-tool-links",children:[s.jsx("a",{href:"/?view=inventory",target:"_blank",className:"ml-tool-link",children:"🔍 Inv Search"}),s.jsx("a",{href:"/suitbuilder.html",target:"_blank",className:"ml-tool-link",children:"🛡️ Suitbuilder"}),s.jsx("a",{href:"/debug.html",target:"_blank",className:"ml-tool-link",children:"🐛 Debug"})]}),s.jsx(ey,{}),s.jsxs("div",{className:"ml-toggles",children:[s.jsxs("label",{className:"ml-toggle-label",children:[s.jsx("input",{type:"checkbox",checked:N,onChange:Z=>T(Z.target.checked)}),s.jsx("span",{children:"Spawn Heatmap"})]}),s.jsxs("label",{className:"ml-toggle-label",children:[s.jsx("input",{type:"checkbox",checked:y,onChange:Z=>B(Z.target.checked)}),s.jsx("span",{children:"Portals"})]})]}),s.jsx("div",{style:{borderTop:"1px solid #333",marginTop:4,paddingTop:4}}),s.jsx(k0,{value:R,onChange:L}),s.jsx("input",{className:"ml-filter",type:"text",placeholder:"Filter players...",value:$,onChange:Z=>V(Z.target.value)}),s.jsx(Z0,{players:Ut,vitals:zt,getColor:j,onSelect:M,selectedPlayer:A})]})},ny="modulepreload",uy=function(c){return"/"+c},Bd={},Sl=function(r,m,o){let b=Promise.resolve();if(m&&m.length>0){let M=function(T){return Promise.all(T.map(B=>Promise.resolve(B).then(p=>({status:"fulfilled",value:p}),p=>({status:"rejected",reason:p}))))};document.getElementsByTagName("link");const N=document.querySelector("meta[property=csp-nonce]"),y=(N==null?void 0:N.nonce)||(N==null?void 0:N.getAttribute("nonce"));b=M(m.map(T=>{if(T=uy(T),T in Bd)return;Bd[T]=!0;const B=T.endsWith(".css"),p=B?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${T}"]${p}`))return;const A=document.createElement("link");if(A.rel=B?"stylesheet":ny,B||(A.as="script"),A.crossOrigin="",A.href=T,y&&A.setAttribute("nonce",y),document.head.appendChild(A),B)return new Promise((R,L)=>{A.addEventListener("load",R),A.addEventListener("error",()=>L(new Error(`Unable to preload CSS for ${T}`)))})}))}function j(M){const N=new Event("vite:preloadError",{cancelable:!0});if(N.payload=M,window.dispatchEvent(N),!N.defaultPrevented)throw M}return b.then(M=>{for(const N of M||[])N.status==="rejected"&&j(N.reason);return r().catch(j)})},kd=({id:c,title:r,zIndex:m,width:o=700,height:b=340,children:j})=>{const{closeWindow:M,bringToFront:N}=An(),y=g.useRef(null),T=g.useRef({dragging:!1,sx:0,sy:0,ox:0,oy:0}),B=g.useRef({resizing:!1,sx:0,sy:0,sw:0,sh:0}),p=g.useRef({x:420,y:10+Math.random()*40}),[A,R]=g.useState({w:o,h:b}),L=g.useCallback(V=>{var Y;V.preventDefault(),N(c);const C=(Y=y.current)==null?void 0:Y.getBoundingClientRect();C&&(T.current={dragging:!0,sx:V.clientX,sy:V.clientY,ox:C.left,oy:C.top})},[c,N]),$=g.useCallback(V=>{V.preventDefault(),V.stopPropagation(),B.current={resizing:!0,sx:V.clientX,sy:V.clientY,sw:A.w,sh:A.h}},[A.w,A.h]);return g.useEffect(()=>{const V=Y=>{const F=T.current;F.dragging&&y.current&&(p.current.x=F.ox+(Y.clientX-F.sx),p.current.y=F.oy+(Y.clientY-F.sy),y.current.style.left=`${p.current.x}px`,y.current.style.top=`${p.current.y}px`);const zt=B.current;if(zt.resizing){const Ut=Math.max(300,zt.sw+(Y.clientX-zt.sx)),lt=Math.max(200,zt.sh+(Y.clientY-zt.sy));R({w:Ut,h:lt})}},C=()=>{T.current.dragging=!1,B.current.resizing=!1};return window.addEventListener("mousemove",V),window.addEventListener("mouseup",C),()=>{window.removeEventListener("mousemove",V),window.removeEventListener("mouseup",C)}},[]),s.jsxs("div",{ref:y,className:"ml-window",style:{zIndex:m,width:A.w,height:A.h,left:p.current.x,top:p.current.y},onMouseDown:()=>N(c),children:[s.jsxs("div",{className:"ml-window-header",onMouseDown:L,children:[s.jsx("span",{className:"ml-window-title",children:r}),s.jsx("button",{className:"ml-window-close",onClick:()=>M(c),children:"×"})]}),s.jsx("div",{className:"ml-window-content",children:j}),s.jsx("div",{className:"ml-window-resize",onMouseDown:$})]})},iy={0:"#00FF00",2:"#FFFFFF",3:"#FF0000",4:"#FFFFFF",5:"#33CCFF",6:"#CCFF99",7:"#00FFFF",14:"#FFD700",15:"#FF69B4",17:"#AAAAFF",18:"#88FF88",21:"#FF8888",22:"#FFAA66"},Jd=50,Wd=c=>`mo-chat-history-${c}`;function cy(c){try{const r=localStorage.getItem(Wd(c));return r?JSON.parse(r):[]}catch{return[]}}function sy(c,r){try{localStorage.setItem(Wd(c),JSON.stringify(r.slice(-Jd)))}catch{}}const fy=({id:c,charName:r,zIndex:m,messages:o,socket:b})=>{const j=g.useRef(null),[M,N]=g.useState(""),[y,T]=g.useState(!1),B=g.useRef(cy(r)),p=g.useRef(-1),A=g.useRef(""),R=g.useRef(!1);g.useEffect(()=>{const Y=j.current;Y&&(R.current?T(!0):(Y.scrollTop=Y.scrollHeight,T(!1)))},[o.length]);const L=g.useCallback(()=>{const Y=j.current;if(!Y)return;const F=Y.scrollHeight-Y.scrollTop-Y.clientHeight<30;R.current=!F,F&&T(!1)},[]),$=g.useCallback(()=>{const Y=j.current;Y&&(Y.scrollTop=Y.scrollHeight,R.current=!1,T(!1))},[]),V=g.useCallback(Y=>{Y.preventDefault();const F=M.trim();!F||!b||b.readyState!==WebSocket.OPEN||(b.send(JSON.stringify({player_name:r,command:F})),B.current.push(F),B.current.length>Jd&&B.current.shift(),sy(r,B.current),p.current=-1,A.current="",N(""),R.current=!1)},[M,b,r]),C=g.useCallback(Y=>{const F=B.current;if(F.length!==0){if(Y.key==="ArrowUp")Y.preventDefault(),p.current===-1?(A.current=M,p.current=F.length-1):p.current>0&&p.current--,N(F[p.current]);else if(Y.key==="ArrowDown"){if(Y.preventDefault(),p.current===-1)return;p.currents.jsx("div",{className:"ml-chat-line",style:{color:iy[Y.color??2]??"#ddd"},children:Y.text},F))}),y&&s.jsx("div",{onClick:$,style:{padding:"3px 0",textAlign:"center",fontSize:"0.65rem",color:"#6af",background:"#1a2a3a",cursor:"pointer",borderTop:"1px solid #334"},children:"▼ New messages below"}),s.jsx("form",{className:"ml-chat-form",onSubmit:V,children:s.jsx("input",{className:"ml-chat-input",value:M,onChange:Y=>N(Y.target.value),onKeyDown:C,placeholder:"Enter chat..."})})]})},ry=g.lazy(()=>Sl(()=>import("./StatsWindow-BBzLtF0I.js"),__vite__mapDeps([0,1])).then(c=>({default:c.StatsWindow}))),oy=g.lazy(()=>Sl(()=>import("./CharacterWindow-5cx18R5O.js"),__vite__mapDeps([2,1])).then(c=>({default:c.CharacterWindow}))),dy=g.lazy(()=>Sl(()=>import("./InventoryWindow-OJaggw-L.js"),__vite__mapDeps([3,1])).then(c=>({default:c.InventoryWindow}))),my=g.lazy(()=>Sl(()=>import("./RadarWindow-CYZptNtW.js"),__vite__mapDeps([4,1])).then(c=>({default:c.RadarWindow}))),hy=g.lazy(()=>Sl(()=>import("./CombatStatsWindow-DiW4OOU6.js"),__vite__mapDeps([5,1])).then(c=>({default:c.CombatStatsWindow}))),yy=g.lazy(()=>Sl(()=>import("./CombatPickerWindow-CeceAs6p.js"),__vite__mapDeps([6,1])).then(c=>({default:c.CombatPickerWindow}))),vy=g.lazy(()=>Sl(()=>import("./IssuesWindow-BZgt7gnX.js"),__vite__mapDeps([7,1])).then(c=>({default:c.IssuesWindow}))),gy=g.lazy(()=>Sl(()=>import("./VitalSharingWindow-2svvX-Jr.js"),__vite__mapDeps([8,1])).then(c=>({default:c.VitalSharingWindow}))),py=g.lazy(()=>Sl(()=>import("./QuestStatusWindow-CNO3OiLF.js"),__vite__mapDeps([9,1])).then(c=>({default:c.QuestStatusWindow}))),by=g.lazy(()=>Sl(()=>Promise.resolve().then(()=>Dy),void 0).then(c=>({default:c.PlayerDashboardWindow}))),Sy=g.lazy(()=>Sl(()=>import("./AgentWindow-MAlGlaCG.js"),__vite__mapDeps([10,1])).then(c=>({default:c.AgentWindow}))),xy=g.lazy(()=>Sl(()=>import("./AdminUsersWindow-CnmS9CpE.js"),__vite__mapDeps([11,1])).then(c=>({default:c.AdminUsersWindow}))),$d=jn.memo(({characters:c,chatMessages:r,nearbyObjects:m,inventoryVersions:o,equipmentCantrips:b,characterStats:j,socket:M})=>{const{windows:N}=An();return s.jsx(g.Suspense,{fallback:null,children:N.map(y=>{var p;const T=y.charName??"";switch(y.id.split("-")[0]){case"chat":return s.jsx(fy,{id:y.id,charName:T,zIndex:y.zIndex,messages:r.get(T)??[],socket:M},y.id);case"stats":return s.jsx(ry,{id:y.id,charName:T,zIndex:y.zIndex},y.id);case"char":return s.jsx(oy,{id:y.id,charName:T,zIndex:y.zIndex,vitals:((p=c.get(T))==null?void 0:p.vitals)??void 0,liveStats:j.get(T)},y.id);case"inv":return s.jsx(dy,{id:y.id,charName:T,zIndex:y.zIndex,inventoryVersion:o.get(T)??0,equipmentCantrips:b.get(T)},y.id);case"radar":return s.jsx(my,{id:y.id,charName:T,zIndex:y.zIndex,socket:M,radarData:m.get(T)??null},y.id);case"combat":return s.jsx(hy,{id:y.id,charName:T,zIndex:y.zIndex},y.id);case"combatpicker":return s.jsx(yy,{id:y.id,zIndex:y.zIndex,characters:c},y.id);case"issues":return s.jsx(vy,{id:y.id,zIndex:y.zIndex},y.id);case"vitalsharing":return s.jsx(gy,{id:y.id,zIndex:y.zIndex},y.id);case"queststatus":return s.jsx(py,{id:y.id,zIndex:y.zIndex},y.id);case"playerdash":return s.jsx(by,{id:y.id,zIndex:y.zIndex,characters:c},y.id);case"agent":return s.jsx(Sy,{id:y.id,zIndex:y.zIndex},y.id);case"adminusers":return s.jsx(xy,{id:y.id,zIndex:y.zIndex},y.id);default:return null}})})});$d.displayName="WindowRenderer";let _y=0;const zy=({recentRares:c})=>{const[r,m]=g.useState([]),[o,b]=g.useState(0),[j,M]=g.useState([]);g.useEffect(()=>{if(c.length>o&&o>0){const y=c.slice(0,c.length-o);for(const T of y){const B=++_y;m(p=>[...p,{key:B,charName:T.character_name,rareName:T.name,exiting:!1}]),N();try{const p=new AudioContext,A=p.createOscillator(),R=p.createGain();A.connect(R),R.connect(p.destination),A.frequency.value=880,A.type="sine",R.gain.value=.3,A.start(),R.gain.exponentialRampToValueAtTime(.001,p.currentTime+.5),A.stop(p.currentTime+.5)}catch{}setTimeout(()=>{m(p=>p.map(A=>A.key===B?{...A,exiting:!0}:A)),setTimeout(()=>{m(p=>p.filter(A=>A.key!==B))},500)},6e3)}}b(c.length)},[c.length]);const N=g.useCallback(()=>{const y=Date.now(),T=["#FFD700","#FF4444","#FF8800","#AA44FF","#4488FF"],B=Array.from({length:30},(p,A)=>{const R=Math.PI*2*A/30+(Math.random()-.5)*.5,L=100+Math.random()*200;return{dx:Math.cos(R)*L,dy:Math.sin(R)*L-50,color:T[Math.floor(Math.random()*T.length)]}});M(p=>[...p,{id:y,particles:B}]),setTimeout(()=>M(p=>p.filter(A=>A.id!==y)),2200)},[]);return s.jsxs(s.Fragment,{children:[s.jsx("div",{className:"ml-rare-notifications",children:r.map(y=>s.jsxs("div",{className:`ml-rare-notif ${y.exiting?"exiting":""}`,children:[s.jsx("div",{className:"ml-rare-notif-title",children:"🎆 LEGENDARY RARE! 🎆"}),s.jsx("div",{className:"ml-rare-notif-name",children:y.rareName}),s.jsx("div",{className:"ml-rare-notif-by",children:"found by"}),s.jsx("div",{className:"ml-rare-notif-char",children:y.charName})]},y.key))}),s.jsx("div",{className:"ml-fireworks",children:j.map(y=>s.jsx(jn.Fragment,{children:y.particles.map((T,B)=>s.jsx("div",{className:"ml-firework-particle",style:{left:"50%",top:"30%",backgroundColor:T.color,"--dx":`${T.dx}px`,"--dy":`${T.dy+200}px`}},B))},y.id))})]})};let jy=0;const Ay=({deathAlerts:c})=>{const[r,m]=g.useState([]),o=g.useRef(0);return g.useEffect(()=>{if(c.length>o.current&&o.current>0){const b=c.slice(o.current);for(const j of b){const M=++jy;m(N=>[...N,{key:M,alert:j,exiting:!1}]);try{const N=new AudioContext,y=N.createOscillator(),T=N.createGain();y.connect(T),T.connect(N.destination),y.frequency.value=440,y.type="sawtooth",T.gain.value=.2,y.start(),T.gain.exponentialRampToValueAtTime(.001,N.currentTime+.8),y.stop(N.currentTime+.8)}catch{}setTimeout(()=>{m(N=>N.map(y=>y.key===M?{...y,exiting:!0}:y)),setTimeout(()=>m(N=>N.filter(y=>y.key!==M)),500)},8e3)}}o.current=c.length},[c.length]),r.length===0?null:s.jsx("div",{style:{position:"fixed",top:70,left:"50%",transform:"translateX(-50%)",zIndex:99999,display:"flex",flexDirection:"column",gap:6,pointerEvents:"none"},children:r.map(b=>s.jsxs("div",{style:{background:"linear-gradient(135deg, #2a0a0a, #1a0000)",border:"2px solid #cc4444",borderRadius:8,padding:"12px 24px",textAlign:"center",boxShadow:"0 0 30px rgba(204, 68, 68, 0.3)",animation:b.exiting?"ml-notif-out 0.5s ease-in forwards":"ml-notif-in 0.5s ease-out"},children:[s.jsx("div",{style:{fontSize:"1.2rem",fontWeight:800,color:"#ff4444"},children:"☠️ CHARACTER DIED ☠️"}),s.jsx("div",{style:{fontSize:"1rem",fontWeight:600,color:"#fff",marginTop:2},children:b.alert.character_name}),s.jsxs("div",{style:{fontSize:"0.8rem",color:"#c88",marginTop:2},children:["Vitae: ",b.alert.vitae,"%"]})]},b.key))})},Hd=["#1f77b4","#ff7f0e","#2ca02c","#d62728","#9467bd","#8c564b","#e377c2","#7f7f7f","#bcbd22","#17becf","#ff4444","#44ff44","#4444ff","#ffff44","#ff44ff","#44ffff","#ff8844","#88ff44","#4488ff","#ff4488","#cc3333","#33cc33","#3333cc","#cccc33","#cc33cc","#33cccc","#cc6633","#66cc33","#3366cc","#cc3366","#ff6666","#66ff66","#6666ff","#ffff66","#ff66ff","#66ffff","#ffaa66","#aaff66","#66aaff","#ff66aa","#990099","#009900","#000099","#990000","#009999","#999900","#aa5500","#55aa00","#0055aa","#aa0055","#ffaaaa","#aaffaa","#aaaaff","#ffffaa","#ffaaff","#aaffff","#ffccaa","#ccffaa","#aaccff","#ffaacc"];function Ty(c){let r=0;for(let m=0;m{let b=c.current.get(o);return b||(b=r.current{const{enabled:c}=xs();return c?s.jsx("div",{className:"ms-banner",role:"status",children:"🐸 Glad midsommar! 🌼 Små grodorna, små grodorna… 🥂"}):null},Ld=["🐸","🌼","🌸","🇸🇪","🌿"],Id=()=>{const{enabled:c}=xs();return g.useEffect(()=>{if(!c||window.matchMedia("(prefers-reduced-motion: reduce)").matches)return;const r=document.createElement("div");r.className="ms-rain",document.body.appendChild(r);const m=()=>{const b=document.createElement("span");b.textContent=Ld[Math.floor(Math.random()*Ld.length)],b.style.left=Math.floor(Math.random()*100)+"vw";const j=6+Math.random()*5;b.style.animationDuration=j.toFixed(2)+"s",b.style.fontSize=14+Math.floor(Math.random()*16)+"px",r.appendChild(b),window.setTimeout(()=>b.remove(),j*1e3+250)},o=window.setInterval(m,450);return()=>{window.clearInterval(o),r.remove()}},[c]),null},Ny=({data:c})=>{const r=Ey(),[m,o]=g.useState(!1),[b,j]=g.useState(!1),[M,N]=g.useState(null),y=g.useMemo(()=>Array.from(c.characters.values()).filter(R=>R.telemetry).map(R=>R.telemetry),[c.characters]),T=g.useMemo(()=>new Map(Array.from(c.characters.values()).filter(R=>R.vitals).map(R=>[R.name,R.vitals])),[c.characters]),[B,p]=g.useState("");g.useEffect(()=>{fetch("/api/api-version",{credentials:"include"}).then(R=>R.json()).then(R=>p(R.version??"")).catch(()=>{})},[]);const A=g.useCallback(R=>{N(L=>L===R?null:R)},[]);return s.jsx(U0,{children:s.jsxs("div",{className:"ml-layout",children:[s.jsx(Fd,{}),s.jsx(Id,{}),s.jsx(ay,{players:y,vitals:T,serverHealth:c.serverHealth,totalRares:c.totalRares,totalKills:c.totalKills,getColor:r,onSelectPlayer:A,showHeatmap:m,showPortals:b,onToggleHeatmap:o,onTogglePortals:j,version:B,selectedPlayer:M}),s.jsx(Q0,{players:y,getColor:r,onSelectPlayer:A,showHeatmap:m,showPortals:b,selectedPlayer:M}),s.jsx($d,{characters:c.characters,chatMessages:c.chatMessages,nearbyObjects:c.nearbyObjects,inventoryVersions:c.inventoryVersions,equipmentCantrips:c.equipmentCantrips,characterStats:c.characterStats,socket:c.socketRef.current}),s.jsx(zy,{recentRares:c.recentRares}),s.jsx(Ay,{deathAlerts:c.deathAlerts})]})})};function My(c){const r=g.useRef(null),m=g.useRef(0),o=g.useRef(c);o.current=c;const b=g.useCallback(()=>{var M;if(((M=r.current)==null?void 0:M.readyState)===WebSocket.OPEN)return;const j=new WebSocket(H0());r.current=j,j.addEventListener("message",N=>{try{const y=JSON.parse(N.data);o.current(y)}catch{}}),j.addEventListener("close",()=>{r.current=null,m.current=window.setTimeout(b,2e3)}),j.addEventListener("error",()=>{j.close()})},[]);return g.useEffect(()=>(b(),()=>{var j;clearTimeout(m.current),(j=r.current)==null||j.close(),r.current=null}),[b]),r}function Pd(){const[c,r]=g.useState(new Map),[m,o]=g.useState(null),[b,j]=g.useState(0),[M,N]=g.useState(0),[y,T]=g.useState([]),B=g.useRef(new Map),[p,A]=g.useState(0),[R,L]=g.useState(new Map),$=g.useRef(new Map),[V,C]=g.useState(0),Y=g.useRef(new Map),[F,zt]=g.useState(0),[Ut,lt]=g.useState([]),[at,Z]=g.useState(new Map),J=g.useRef(c);J.current=c;const P=g.useCallback((_,q)=>{r(Q=>{const H=new Map(Q),w=H.get(_)??{name:_,telemetry:null,vitals:null,combat:null,lastUpdate:0};return H.set(_,q(w)),H})},[]),Rt=g.useCallback(_=>{var q,Q;if(_.type){if(_.type==="telemetry"){const H=_;P(H.character_name,w=>({...w,telemetry:H,lastUpdate:Date.now()}))}else if(_.type==="vitals"){const H=_,w=(q=J.current.get(H.character_name))==null?void 0:q.vitals;w&&(w.vitae??0)===0&&(H.vitae??0)>0&<(ot=>[...ot,{character_name:H.character_name,vitae:H.vitae,timestamp:new Date().toISOString()}].slice(-50)),P(H.character_name,ot=>({...ot,vitals:H,lastUpdate:Date.now()}))}else if(_.type==="combat_stats"){const H=_;P(H.character_name,w=>({...w,combat:H,lastUpdate:Date.now()}))}else if(_.type==="rare"){const H=_;T(w=>[H,...w].slice(0,50))}else if(_.type==="inventory_delta"){const H=_;H.character_name&&L(w=>{const ot=new Map(w);return ot.set(H.character_name,(ot.get(H.character_name)??0)+1),ot})}else if(_.type==="character_stats"){const H=_;Y.current.set(H.character_name,_),zt(w=>w+1)}else if(_.type==="equipment_cantrip_state"){const H=_;$.current.set(H.character_name,H),C(w=>w+1)}else if(_.type==="dungeon_map"){const H=_;H.landblock&&(window.__dungeonMapCache||(window.__dungeonMapCache={}),window.__dungeonMapCache[H.landblock]=H)}else if(_.type==="nearby_objects"){const H=_;if(Z(w=>{const ot=new Map(w);return ot.set(H.character_name,H),ot}),H.is_dungeon&&H.landblock&&!((Q=window.__dungeonMapCache)!=null&&Q[H.landblock])){const w=jt.current;(w==null?void 0:w.readyState)===WebSocket.OPEN&&w.send(JSON.stringify({type:"request_dungeon_map",landblock:H.landblock}))}}else if(_.type==="chat"){const H=_,w=B.current.get(H.character_name)??[];w.push({text:H.text,color:H.color,timestamp:H.timestamp}),w.length>1e3&&w.splice(0,w.length-1e3),B.current.set(H.character_name,w),A(ot=>ot+1)}}},[P]),jt=My(Rt);g.useEffect(()=>{const _=async()=>{try{const Q=await J0();r(H=>{var ot;const w=new Map(H);for(const dt of Q.players??[]){const et=w.get(dt.character_name);w.set(dt.character_name,{name:dt.character_name,telemetry:dt,vitals:(et==null?void 0:et.vitals)??null,combat:(et==null?void 0:et.combat)??null,lastUpdate:Date.now()})}for(const dt of w.keys())(ot=Q.players)!=null&&ot.some(et=>et.character_name===dt)||w.delete(dt);return w})}catch{}};_();const q=setInterval(_,5e3);return()=>clearInterval(q)},[]),g.useEffect(()=>{const _=async()=>{try{const Q=await W0();for(const H of Q.stats??[])P(H.character_name,w=>({...w,combat:{...H,type:"combat_stats"}}))}catch{}};_();const q=setInterval(_,3e4);return()=>clearInterval(q)},[P]),g.useEffect(()=>{const _=async()=>{try{o(await $0())}catch{}};_();const q=setInterval(_,3e4);return()=>clearInterval(q)},[]),g.useEffect(()=>{const _=async()=>{try{const[Q,H]=await Promise.all([F0(),I0()]);j(Q.all_time??0),N(H.total??0)}catch{}};_();const q=setInterval(_,3e5);return()=>clearInterval(q)},[]);const Ol=g.useMemo(()=>B.current,[p]),Tl=g.useMemo(()=>$.current,[V]),xl=g.useMemo(()=>Y.current,[F]);return{characters:c,serverHealth:m,totalRares:b,totalKills:M,recentRares:y,chatMessages:Ol,nearbyObjects:at,inventoryVersions:R,equipmentCantrips:Tl,characterStats:xl,deathAlerts:Ut,socketRef:jt}}const _s=({characters:c})=>{const[r,m]=g.useState("kph"),[o,b]=g.useState(!1),[j,M]=g.useState(null),N=g.useMemo(()=>{const p=Array.from(c.values()).filter(A=>A.telemetry).map(A=>{var L,$,V;const R=A.telemetry;return{name:A.name,kills:R.kills??0,kph:parseInt(R.kills_per_hour)||0,totalKills:R.total_kills??0,rares:R.total_rares??0,sessionRares:R.session_rares??0,deaths:parseInt(R.deaths)||0,totalDeaths:parseInt(R.total_deaths)||0,uptime:((L=R.onlinetime)==null?void 0:L.replace(/^00\./,""))??"",state:R.vt_state??"idle",tapers:parseInt(R.prismatic_taper_count)||0,hp:(($=A.vitals)==null?void 0:$.health_percentage)??0,vitae:((V=A.vitals)==null?void 0:V.vitae)??0}});return p.sort((A,R)=>{let L=0;switch(r){case"name":L=A.name.localeCompare(R.name);break;case"kills":L=A.kills-R.kills;break;case"kph":L=A.kph-R.kph;break;case"rares":L=A.rares-R.rares;break;case"deaths":L=A.totalDeaths-R.totalDeaths;break;case"uptime":L=A.uptime.localeCompare(R.uptime);break;case"state":L=A.state.localeCompare(R.state);break}return o?L:-L}),p},[c,r,o]),y=p=>{r===p?b(!o):(m(p),b(!1))},T=p=>({padding:"4px 6px",cursor:"pointer",userSelect:"none",color:r===p?"#6af":"#888",fontSize:"0.65rem",fontWeight:600,whiteSpace:"nowrap",borderBottom:"1px solid #444"}),B=p=>r===p?o?" ▲":" ▼":"";return s.jsxs("div",{style:{flex:1,overflow:"auto",fontSize:"0.73rem"},children:[s.jsxs("table",{style:{width:"auto",borderCollapse:"collapse"},children:[s.jsx("thead",{children:s.jsxs("tr",{style:{position:"sticky",top:0,background:"#1a1a1a",zIndex:1},children:[s.jsxs("th",{style:{...T("name"),textAlign:"left"},onClick:()=>y("name"),children:["Character",B("name")]}),s.jsxs("th",{style:{...T("state"),textAlign:"center"},onClick:()=>y("state"),children:["State",B("state")]}),s.jsxs("th",{style:{...T("kph"),textAlign:"right"},onClick:()=>y("kph"),children:["KPH",B("kph")]}),s.jsxs("th",{style:{...T("kills"),textAlign:"right"},onClick:()=>y("kills"),children:["Session",B("kills")]}),s.jsx("th",{style:{textAlign:"right",padding:"4px 6px",color:"#888",fontSize:"0.65rem",fontWeight:600,borderBottom:"1px solid #444"},children:"Total"}),s.jsxs("th",{style:{...T("rares"),textAlign:"right"},onClick:()=>y("rares"),children:["Rares",B("rares")]}),s.jsxs("th",{style:{...T("deaths"),textAlign:"right"},onClick:()=>y("deaths"),children:["Deaths",B("deaths")]}),s.jsxs("th",{style:{...T("uptime"),textAlign:"right"},onClick:()=>y("uptime"),children:["Uptime",B("uptime")]}),s.jsx("th",{style:{textAlign:"right",padding:"4px 6px",color:"#888",fontSize:"0.65rem",fontWeight:600,borderBottom:"1px solid #444"},children:"HP%"}),s.jsx("th",{style:{textAlign:"right",padding:"4px 6px",color:"#888",fontSize:"0.65rem",fontWeight:600,borderBottom:"1px solid #444"},children:"Vitae"}),s.jsx("th",{style:{textAlign:"right",padding:"4px 6px",color:"#888",fontSize:"0.65rem",fontWeight:600,borderBottom:"1px solid #444"},children:"Tapers"})]})}),s.jsx("tbody",{children:N.map(p=>{const A=p.state.toLowerCase(),R=A==="combat"||A==="hunt",L=j===p.name;return s.jsxs("tr",{onClick:()=>M(L?null:p.name),style:{borderBottom:"1px solid #1a1a1a",cursor:"pointer",background:L?"rgba(102, 170, 255, 0.18)":void 0,outline:L?"1px solid rgba(102, 170, 255, 0.55)":void 0,outlineOffset:"-1px"},children:[s.jsx("td",{style:{padding:"3px 10px 3px 6px",color:"#ccc",fontWeight:500,whiteSpace:"nowrap"},children:p.name}),s.jsx("td",{style:{textAlign:"center",padding:"3px 6px"},children:s.jsx("span",{style:{fontSize:"0.6rem",padding:"1px 6px",borderRadius:3,background:R?"rgba(68,204,68,0.15)":A==="idle"||A==="default"?"rgba(100,100,100,0.2)":"rgba(204,68,68,0.15)",color:R?"#4c4":A==="idle"||A==="default"?"#888":"#c44"},children:p.state})}),s.jsx("td",{style:{textAlign:"right",padding:"3px 6px",color:"#4c4",fontVariantNumeric:"tabular-nums"},children:p.kph.toLocaleString()}),s.jsx("td",{style:{textAlign:"right",padding:"3px 6px",color:"#ccc",fontVariantNumeric:"tabular-nums"},children:p.kills.toLocaleString()}),s.jsx("td",{style:{textAlign:"right",padding:"3px 6px",color:"#888",fontVariantNumeric:"tabular-nums"},children:p.totalKills.toLocaleString()}),s.jsxs("td",{style:{textAlign:"right",padding:"3px 6px",color:"#fc0",fontVariantNumeric:"tabular-nums"},children:[p.rares,p.sessionRares>0?` (${p.sessionRares})`:""]}),s.jsx("td",{style:{textAlign:"right",padding:"3px 6px",color:p.totalDeaths>0?"#c66":"#555",fontVariantNumeric:"tabular-nums"},children:p.totalDeaths}),s.jsx("td",{style:{textAlign:"right",padding:"3px 6px",color:"#888",fontVariantNumeric:"tabular-nums"},children:p.uptime}),s.jsxs("td",{style:{textAlign:"right",padding:"3px 6px",fontVariantNumeric:"tabular-nums",color:p.hp>80?"#4c4":p.hp>40?"#ca0":"#c44"},children:[p.hp.toFixed(0),"%"]}),s.jsx("td",{style:{textAlign:"right",padding:"3px 6px",fontVariantNumeric:"tabular-nums",color:p.vitae>0?"#f66":"#333"},children:p.vitae>0?`${p.vitae}%`:""}),s.jsx("td",{style:{textAlign:"right",padding:"3px 6px",color:"#888",fontVariantNumeric:"tabular-nums"},children:p.tapers.toLocaleString()})]},p.name)})})]}),N.length===0&&s.jsx("div",{style:{padding:20,color:"#666",textAlign:"center"},children:"No characters online"})]})},Cy=({id:c,zIndex:r,characters:m})=>s.jsx(kd,{id:c,title:"Player Dashboard",zIndex:r,width:850,height:500,children:s.jsx(_s,{characters:m})}),Dy=Object.freeze(Object.defineProperty({__proto__:null,PlayerDashboardContent:_s,PlayerDashboardWindow:Cy},Symbol.toStringTag,{value:"Module"})),Oy=()=>{const c=Pd(),[r,m]=g.useState("");g.useEffect(()=>{const b=document.title;return document.title="Overlord Dashboard",()=>{document.title=b}},[]),g.useEffect(()=>{fetch("/api/api-version",{credentials:"include"}).then(b=>b.json()).then(b=>m(b.version??"")).catch(()=>{})},[]);const o=Array.from(c.characters.values()).filter(b=>b.telemetry).length;return s.jsxs("div",{className:"ml-dashboard-page",children:[s.jsx(Fd,{}),s.jsx(Id,{}),s.jsxs("header",{className:"ml-dashboard-header",children:[s.jsx("span",{className:"ml-dashboard-title",children:"👥 Player Dashboard"}),s.jsxs("span",{className:"ml-dashboard-count",children:[o," online"]}),s.jsx("span",{style:{flex:1}}),r&&s.jsxs("span",{className:"ml-dashboard-version",children:["v",r]})]}),s.jsx("main",{className:"ml-dashboard-main",children:s.jsx(_s,{characters:c.characters})})]})},je={text:"",characters:"all",itemType:"all",weaponType:"",slots:[],cantrips:[],spellContains:"",ratings:{},itemSet:"",equipStatus:"",bonded:!1,attuned:!1,rare:!1,maxLevel:"",minValue:"",minWorkmanship:"",maxBurden:"",sortBy:"name",sortDir:"asc",page:1},W=c=>({value:c,label:c.replace(/^Legendary /,"")}),Uy=[{group:"Attributes",items:[W("Legendary Strength"),W("Legendary Endurance"),W("Legendary Quickness"),W("Legendary Coordination"),W("Legendary Willpower"),W("Legendary Focus")]},{group:"Weapon skills",items:[W("Legendary Heavy Weapon Aptitude"),W("Legendary Light Weapon Aptitude"),W("Legendary Finesse Weapon Aptitude"),W("Legendary Missile Weapon Aptitude"),W("Legendary Two Handed Combat Aptitude"),W("Legendary Dual Wield Aptitude"),W("Legendary Shield Aptitude"),W("Legendary Sneak Attack Prowess"),W("Legendary Dirty Fighting Prowess"),W("Legendary Recklessness Prowess"),W("Legendary Defender"),W("Legendary Blood Thirst")]},{group:"Magic",items:[W("Legendary War Magic Aptitude"),W("Legendary Void Magic Aptitude"),W("Legendary Creature Enchantment Aptitude"),W("Legendary Item Enchantment Aptitude"),W("Legendary Life Magic Aptitude"),W("Legendary Mana Conversion Prowess"),W("Legendary Arcane Prowess"),W("Legendary Hermetic Link"),W("Legendary Spirit Thirst"),W("Legendary Magic Resistance")]},{group:"Utility",items:[W("Legendary Summoning Prowess"),W("Legendary Healing Prowess"),W("Legendary Leadership"),W("Legendary Deception Prowess"),W("Legendary Person Attunement"),W("Legendary Magic Item Tinkering Expertise")]},{group:"Defense",items:[W("Legendary Invulnerability"),W("Legendary Impenetrability"),W("Legendary Impregnability"),W("Legendary Armor")]},{group:"Wards & Banes",items:[W("Legendary Flame Ward"),W("Legendary Frost Ward"),W("Legendary Acid Ward"),W("Legendary Storm Ward"),W("Legendary Slashing Ward"),W("Legendary Piercing Ward"),W("Legendary Bludgeoning Ward"),W("Legendary Piercing Bane"),W("Legendary Storm Bane")]}],Ry=["Ring","Bracelet","Neck","Trinket","Cloak"],qy=["Head","Chest","Abdomen","Upper Arms","Lower Arms","Hands","Upper Legs","Lower Legs","Feet","Shield"],By=[{value:"",label:"All weapons"},{value:"heavy",label:"Heavy"},{value:"light",label:"Light"},{value:"finesse",label:"Finesse"},{value:"two_handed",label:"Two-handed"},{value:"bow",label:"Bow"},{value:"crossbow",label:"Crossbow"},{value:"thrown",label:"Thrown"},{value:"caster",label:"Wand/Staff/Orb"}],ps=[{param:"min_od",label:"Weapon OD",common:!0},{param:"min_damage_rating",label:"Damage rating",common:!0},{param:"min_crit_damage_rating",label:"Crit damage",common:!0},{param:"min_heal_boost_rating",label:"Heal boost",common:!0},{param:"min_vitality_rating",label:"Vitality",common:!0},{param:"min_armor",label:"Armor level"},{param:"min_damage_resist_rating",label:"Damage resist"},{param:"min_crit_resist_rating",label:"Crit resist"},{param:"min_crit_damage_resist_rating",label:"Crit dmg resist"},{param:"min_healing_resist_rating",label:"Healing resist"},{param:"min_nether_resist_rating",label:"Nether resist"},{param:"min_healing_rating",label:"Healing rating"},{param:"min_dot_resist_rating",label:"DoT resist"},{param:"min_life_resist_rating",label:"Life resist"},{param:"min_sneak_attack_rating",label:"Sneak attack"},{param:"min_recklessness_rating",label:"Recklessness"},{param:"min_deception_rating",label:"Deception"},{param:"min_pk_damage_rating",label:"PK damage"},{param:"min_pk_damage_resist_rating",label:"PK dmg resist"},{param:"min_gear_pk_damage_rating",label:"Gear PK dmg"},{param:"min_gear_pk_damage_resist_rating",label:"Gear PK resist"},{param:"min_tinks",label:"Tinks"}],bs=[{key:"name",label:"Item",sortKey:"name",defaultVisible:!0},{key:"character_name",label:"Character",sortKey:"character_name",defaultVisible:!0},{key:"slot_name",label:"Slot",defaultVisible:!0},{key:"value",label:"Value",sortKey:"value",defaultVisible:!0},{key:"wield_level",label:"Wield",sortKey:"level",defaultVisible:!0},{key:"spell_names",label:"Spells / Cantrips",sortKey:"spell_names",defaultVisible:!0},{key:"armor_level",label:"Armor",sortKey:"armor",defaultVisible:!1},{key:"max_damage",label:"Max Dmg",sortKey:"damage",defaultVisible:!1},{key:"od_rating",label:"OD",sortKey:"od",defaultVisible:!1},{key:"workmanship",label:"Work",sortKey:"workmanship",defaultVisible:!1},{key:"item_set_name",label:"Set",sortKey:"item_set",defaultVisible:!1},{key:"object_class_name",label:"Type",sortKey:"item_type_name",defaultVisible:!1},{key:"burden",label:"Burden",defaultVisible:!1},{key:"condition_percent",label:"Cond %",defaultVisible:!1},{key:"last_updated",label:"Updated",sortKey:"last_updated",defaultVisible:!1}],Hy=200,tm="inv.visibleColumns";function Ly(c){const r={};for(const o of Object.keys(je))JSON.stringify(c[o])!==JSON.stringify(je[o])&&(r[o]=c[o]);const m=new URL(window.location.href);m.searchParams.set("view","inventory"),Object.keys(r).length?m.searchParams.set("q",JSON.stringify(r)):m.searchParams.delete("q");try{window.history.replaceState(null,"",m)}catch{}}const Yy=new Set(["all","armor","jewelry","weapon","clothing","shirt","pants"]),Vy=new Set(["asc","desc"]);function Yd(c){return Array.isArray(c)&&c.every(r=>typeof r=="string")}function Xy(c,r){switch(c){case"characters":return r==="all"||Yd(r)?r:void 0;case"slots":case"cantrips":return Yd(r)?r:void 0;case"itemType":return typeof r=="string"&&Yy.has(r)?r:void 0;case"sortDir":return typeof r=="string"&&Vy.has(r)?r:void 0;case"ratings":{if(typeof r!="object"||r===null||Array.isArray(r))return;const m={};for(const[o,b]of Object.entries(r))(b===""||typeof b=="number")&&(m[o]=b);return m}case"text":case"weaponType":case"spellContains":case"itemSet":case"sortBy":return typeof r=="string"?r:void 0;case"equipStatus":return r===""||r==="equipped"||r==="unequipped"?r:void 0;case"bonded":case"attuned":case"rare":return typeof r=="boolean"?r:void 0;case"maxLevel":case"minValue":case"minWorkmanship":case"maxBurden":return r===""||typeof r=="number"?r:void 0;case"page":return typeof r=="number"&&Number.isInteger(r)&&r>0?r:void 0;default:return}}function wy(){try{const c=new URLSearchParams(window.location.search).get("q");if(!c)return je;const r=JSON.parse(c);if(typeof r!="object"||r===null||Array.isArray(r))return je;const m={...je};for(const o of Object.keys(je)){if(!(o in r))continue;const b=Xy(o,r[o]);b!==void 0&&(m[o]=b)}return m}catch{return je}}function Gy(c){const r=new URLSearchParams;switch(c.characters==="all"?r.set("include_all_characters","true"):c.characters.length===1?r.set("character",c.characters[0]):r.set("characters",c.characters.join(",")),c.text&&r.set("text",c.text),c.itemType){case"armor":r.set("armor_only","true");break;case"jewelry":r.set("jewelry_only","true");break;case"clothing":r.set("clothing_only","true");break;case"shirt":r.set("shirt_only","true");break;case"pants":r.set("pants_only","true");break;case"weapon":r.set("weapon_only","true"),c.weaponType&&r.set("weapon_type",c.weaponType);break}c.slots.length&&r.set("slot_names",c.slots.join(",")),c.cantrips.length&&r.set("legendary_cantrips",c.cantrips.join(",")),c.spellContains&&r.set("spell_contains",c.spellContains);for(const[m,o]of Object.entries(c.ratings))o!==""&&r.set(m,String(o));return c.itemSet&&r.set("item_set",c.itemSet),c.equipStatus&&r.set("equipment_status",c.equipStatus),c.bonded&&r.set("bonded","true"),c.attuned&&r.set("attuned","true"),c.rare&&r.set("is_rare","true"),c.maxLevel!==""&&r.set("max_level",String(c.maxLevel)),c.minValue!==""&&r.set("min_value",String(c.minValue)),c.minWorkmanship!==""&&r.set("min_workmanship",String(c.minWorkmanship)),c.maxBurden!==""&&r.set("max_burden",String(c.maxBurden)),r.set("sort_by",c.sortBy),r.set("sort_dir",c.sortDir),r.set("page",String(c.page)),r.set("limit",String(Hy)),r}function Qy(){const[c,r]=g.useState(wy),[m,o]=g.useState(null),[b,j]=g.useState(!1),[M,N]=g.useState(null),[y,T]=g.useState(null),B=g.useRef(null),p=g.useCallback(R=>{r(L=>({...L,page:"page"in R?L.page:1,...R}))},[]),A=g.useCallback(()=>r(je),[]);return g.useEffect(()=>{const R=setTimeout(async()=>{var V;Ly(c),(V=B.current)==null||V.abort();const L=new AbortController;B.current=L,j(!0);const $=performance.now();try{const C=await fetch(`/api/inv/search/items?${Gy(c)}`,{credentials:"include",signal:L.signal});if(!C.ok)throw new Error(`search: HTTP ${C.status}`);const Y=await C.json();if(Y.error)throw new Error(Y.error);o(Y),N(null),T(Math.round(performance.now()-$))}catch(C){(C==null?void 0:C.name)!=="AbortError"&&N(String((C==null?void 0:C.message)??C))}finally{B.current===L&&j(!1)}},400);return()=>clearTimeout(R)},[c]),{filters:c,update:p,reset:A,result:m,loading:b,error:M,queryMs:y}}function Zy({search:c}){const{filters:r,update:m}=c,[o,b]=g.useState([]),[j,M]=g.useState(new Set),[N,y]=g.useState("");g.useEffect(()=>{It("/inv/characters/list").then(A=>b(A.characters.map(R=>R.character_name).sort((R,L)=>R.localeCompare(L)))).catch(()=>{}),It("/live").then(A=>M(new Set(A.players.map(R=>R.character_name)))).catch(()=>{})},[]);const T=g.useMemo(()=>r.characters==="all"?new Set(o):new Set(r.characters),[r.characters,o]),B=A=>{const R=new Set(T);R.has(A)?R.delete(A):R.add(A),m({characters:R.size===o.length?"all":[...R]})},p=o.filter(A=>A.toLowerCase().includes(N.toLowerCase()));return s.jsxs(ze,{title:"Characters",defaultOpen:!0,badge:r.characters==="all"?"All":r.characters.length,children:[s.jsx("input",{className:"inv-minisearch",placeholder:"filter characters…",value:N,onChange:A=>y(A.target.value)}),s.jsxs("div",{className:"inv-links",children:[s.jsx("span",{className:"inv-linky",onClick:()=>m({characters:"all"}),children:"All"})," · ",s.jsx("span",{className:"inv-linky",onClick:()=>m({characters:[]}),children:"None"})," · ",s.jsx("span",{className:"inv-linky",onClick:()=>m({characters:o.filter(A=>j.has(A))}),children:"Online"})]}),p.map(A=>s.jsxs("label",{className:"inv-fitem",children:[s.jsx("input",{type:"checkbox",checked:T.has(A),onChange:()=>B(A)}),A," ",j.has(A)&&s.jsx("span",{className:"inv-online"})]},A))]})}function Ky({search:c}){const{filters:r,update:m}=c,[o,b]=g.useState(""),j=N=>m({cantrips:r.cantrips.includes(N)?r.cantrips.filter(y=>y!==N):[...r.cantrips,N]}),M=N=>N.toLowerCase().includes(o.toLowerCase());return s.jsxs(ze,{title:"Cantrips",defaultOpen:!0,badge:r.cantrips.length||void 0,children:[s.jsx("input",{className:"inv-minisearch",placeholder:"find cantrip… e.g. invuln",value:o,onChange:N=>b(N.target.value)}),r.cantrips.length>0&&s.jsxs(s.Fragment,{children:[s.jsx("div",{className:"inv-subhead",children:"Selected"}),r.cantrips.map(N=>s.jsxs("label",{className:"inv-fitem inv-gold",children:[s.jsx("input",{type:"checkbox",checked:!0,onChange:()=>j(N)}),N.replace(/^Legendary /,"")]},N))]}),Uy.map(N=>{const y=N.items.filter(T=>!r.cantrips.includes(T.value)&&M(T.label));return y.length?s.jsxs("div",{children:[s.jsx("div",{className:"inv-subhead",children:N.group}),y.map(T=>s.jsxs("label",{className:"inv-fitem",children:[s.jsx("input",{type:"checkbox",checked:!1,onChange:()=>j(T.value)})," ",T.label]},T.value))]},N.group):null}),s.jsx("div",{className:"inv-subhead",children:"Any-tier spell search"}),s.jsx("input",{className:"inv-minisearch",placeholder:"spell name contains… e.g. Epic Invuln",value:r.spellContains,onChange:N=>m({spellContains:N.target.value})})]})}function ze(c){const[r,m]=g.useState(c.defaultOpen??!1);return s.jsxs("div",{className:`inv-grp${r?" inv-open":""}`,children:[s.jsxs("div",{className:"inv-grp-head",onClick:()=>m(o=>!o),children:[s.jsx("span",{className:"inv-arrow",children:"▶"})," ",c.title,c.badge?s.jsx("span",{className:"inv-badge",children:c.badge}):null]}),r&&s.jsx("div",{className:"inv-grp-body",children:c.children})]})}function ky({search:c}){const{filters:r,update:m}=c,[o,b]=g.useState(!1),[j,M]=g.useState(!1),[N,y]=g.useState([]),[T,B]=g.useState("");g.useEffect(()=>{It("/inv/sets/list").then(C=>y(C.sets)).catch(()=>{})},[]);const p=C=>m({slots:r.slots.includes(C)?r.slots.filter(Y=>Y!==C):[...r.slots,C]}),A=(C,Y)=>m({ratings:{...r.ratings,[C]:Y===""?"":Number(Y)}}),R=Object.values(r.ratings).filter(C=>C!=="").length,L=[r.equipStatus!=="",r.bonded,r.attuned,r.rare].filter(Boolean).length,$=[r.maxLevel,r.minValue,r.minWorkmanship,r.maxBurden].filter(C=>C!=="").length,V=[["all","All items"],["armor","Armor"],["jewelry","Jewelry"],["weapon","Weapons"],["clothing","Clothing"],["shirt","Shirts"],["pants","Pants"]];return s.jsxs("div",{className:"inv-sidebar",children:[s.jsx(Zy,{search:c}),s.jsxs(ze,{title:"Item state",defaultOpen:!0,badge:L||void 0,children:[[["","Any"],["equipped","Equipped"],["unequipped","Not equipped"]].map(([C,Y])=>s.jsxs("label",{className:"inv-fitem",children:[s.jsx("input",{type:"radio",name:"inv-eq",checked:r.equipStatus===C,onChange:()=>m({equipStatus:C})})," ",Y]},Y)),s.jsxs("label",{className:"inv-fitem",children:[s.jsx("input",{type:"checkbox",checked:r.bonded,onChange:C=>m({bonded:C.target.checked})})," Bonded"]}),s.jsxs("label",{className:"inv-fitem",children:[s.jsx("input",{type:"checkbox",checked:r.attuned,onChange:C=>m({attuned:C.target.checked})})," Attuned"]}),s.jsxs("label",{className:"inv-fitem",children:[s.jsx("input",{type:"checkbox",checked:r.rare,onChange:C=>m({rare:C.target.checked})})," Rare"]})]}),s.jsxs(ze,{title:"Item type",defaultOpen:!0,badge:r.itemType!=="all"?1:void 0,children:[V.map(([C,Y])=>s.jsxs("label",{className:"inv-fitem",children:[s.jsx("input",{type:"radio",name:"inv-t",checked:r.itemType===C,onChange:()=>m({itemType:C,weaponType:""})})," ",Y]},C)),r.itemType==="weapon"&&s.jsx("select",{className:"inv-minisearch",value:r.weaponType,onChange:C=>m({weaponType:C.target.value}),children:By.map(C=>s.jsx("option",{value:C.value,children:C.label},C.value))})]}),s.jsxs(ze,{title:"Slots",defaultOpen:!0,badge:r.slots.length||void 0,children:[Ry.map(C=>s.jsxs("label",{className:"inv-fitem",children:[s.jsx("input",{type:"checkbox",checked:r.slots.includes(C),onChange:()=>p(C)})," ",C]},C)),s.jsxs("span",{className:"inv-linky",onClick:()=>b(C=>!C),children:[o?"hide":"show"," armor slots ",o?"▴":"▾"]}),o&&qy.map(C=>s.jsxs("label",{className:"inv-fitem",children:[s.jsx("input",{type:"checkbox",checked:r.slots.includes(C),onChange:()=>p(C)})," ",C]},C))]}),s.jsx(Ky,{search:c}),s.jsxs(ze,{title:"Ratings",badge:R||void 0,children:[ps.filter(C=>j||C.common).map(C=>s.jsxs("div",{className:"inv-range",children:[s.jsxs("label",{children:[C.label," ≥"]}),s.jsx("input",{type:"number",value:r.ratings[C.param]??"",placeholder:"min",onChange:Y=>A(C.param,Y.target.value)})]},C.param)),s.jsx("span",{className:"inv-linky",onClick:()=>M(C=>!C),children:j?"common ratings ▴":`all ${ps.length} ratings ▾`})]}),s.jsxs(ze,{title:"Equipment sets",badge:r.itemSet?1:void 0,children:[s.jsx("input",{className:"inv-minisearch",placeholder:"find set…",value:T,onChange:C=>B(C.target.value)}),s.jsxs("label",{className:"inv-fitem",children:[s.jsx("input",{type:"radio",name:"inv-set",checked:r.itemSet==="",onChange:()=>m({itemSet:""})})," Any set"]}),N.filter(C=>C.id.toLowerCase().includes(T.toLowerCase())).map(C=>s.jsxs("label",{className:"inv-fitem",children:[s.jsx("input",{type:"radio",name:"inv-set",checked:r.itemSet===C.id,onChange:()=>m({itemSet:C.id})})," ",C.id," ",s.jsxs("span",{className:"inv-dim",children:["(",C.item_count,")"]})]},C.id))]}),s.jsxs(ze,{title:"Reqs & value",badge:$||void 0,children:[s.jsxs("div",{className:"inv-range",children:[s.jsx("label",{children:"Wield lvl ≤"}),s.jsx("input",{type:"number",value:r.maxLevel,placeholder:"max",onChange:C=>m({maxLevel:C.target.value===""?"":Number(C.target.value)})})]}),s.jsxs("div",{className:"inv-range",children:[s.jsx("label",{children:"Value ≥"}),s.jsx("input",{type:"number",value:r.minValue,placeholder:"min",onChange:C=>m({minValue:C.target.value===""?"":Number(C.target.value)})})]}),s.jsxs("div",{className:"inv-range",children:[s.jsx("label",{children:"Workmanship ≥"}),s.jsx("input",{type:"number",value:r.minWorkmanship,placeholder:"min",onChange:C=>m({minWorkmanship:C.target.value===""?"":Number(C.target.value)})})]}),s.jsxs("div",{className:"inv-range",children:[s.jsx("label",{children:"Burden ≤"}),s.jsx("input",{type:"number",value:r.maxBurden,placeholder:"max",onChange:C=>m({maxBurden:C.target.value===""?"":Number(C.target.value)})})]})]})]})}function Jy({search:c}){const{filters:r,update:m}=c,o=[];r.text&&o.push({label:`"${r.text}"`,remove:()=>m({text:""})}),r.characters!=="all"&&o.push({label:`${r.characters.length} character${r.characters.length===1?"":"s"}`,remove:()=>m({characters:"all"})}),r.itemType!=="all"&&o.push({label:r.itemType[0].toUpperCase()+r.itemType.slice(1)+(r.weaponType?`: ${r.weaponType}`:""),remove:()=>m({itemType:"all",weaponType:""})});for(const b of r.slots)o.push({label:`Slot: ${b}`,remove:()=>m({slots:r.slots.filter(j=>j!==b)})});for(const b of r.cantrips)o.push({label:b.replace(/^Legendary /,"Leg. "),gold:!0,remove:()=>m({cantrips:r.cantrips.filter(j=>j!==b)})});r.spellContains&&o.push({label:`Spell: ${r.spellContains}`,remove:()=>m({spellContains:""})});for(const[b,j]of Object.entries(r.ratings))if(j!==""){const M=ps.find(N=>N.param===b);o.push({label:`${(M==null?void 0:M.label)??b} ≥ ${j}`,remove:()=>{const{[b]:N,...y}=r.ratings;m({ratings:y})}})}return r.itemSet&&o.push({label:`Set: ${r.itemSet}`,remove:()=>m({itemSet:""})}),r.equipStatus&&o.push({label:r.equipStatus==="equipped"?"Equipped":"Not equipped",remove:()=>m({equipStatus:""})}),r.bonded&&o.push({label:"Bonded",remove:()=>m({bonded:!1})}),r.attuned&&o.push({label:"Attuned",remove:()=>m({attuned:!1})}),r.rare&&o.push({label:"Rare",remove:()=>m({rare:!1})}),r.maxLevel!==""&&o.push({label:`Wield ≤ ${r.maxLevel}`,remove:()=>m({maxLevel:""})}),r.minValue!==""&&o.push({label:`Value ≥ ${r.minValue}`,remove:()=>m({minValue:""})}),r.minWorkmanship!==""&&o.push({label:`Work ≥ ${r.minWorkmanship}`,remove:()=>m({minWorkmanship:""})}),r.maxBurden!==""&&o.push({label:`Burden ≤ ${r.maxBurden}`,remove:()=>m({maxBurden:""})}),o.length?s.jsxs("div",{className:"inv-chipsrow",children:[s.jsx("span",{className:"inv-chips-lbl",children:"ACTIVE"}),o.map((b,j)=>s.jsxs("span",{className:`inv-chip${b.gold?" inv-chip-gold":""}`,children:[b.label," ",s.jsx("span",{className:"inv-chip-x",onClick:b.remove,children:"×"})]},j))]}):null}function Wy(){try{const c=localStorage.getItem(tm);if(c)return new Set(JSON.parse(c))}catch{}return new Set(bs.filter(c=>c.defaultVisible).map(c=>c.key))}function $y(c,r){switch(r){case"name":return s.jsxs(s.Fragment,{children:[c.name,c.is_equipped&&s.jsx("span",{className:"inv-equipped",children:" ⚔"})]});case"spell_names":return s.jsx("span",{className:"inv-spells",children:(c.spell_names??[]).map((m,o)=>s.jsxs("span",{children:[o>0&&", ",s.jsx("span",{className:/legendary/i.test(m)?"inv-leg":"",children:m})]},o))});case"value":return c.value!=null?c.value.toLocaleString():"—";case"last_updated":return c.last_updated?c.last_updated.slice(0,16).replace("T"," "):"—";case"od_rating":{const m=c.od_rating;return m==null?"—":m>0?`+${m.toFixed(2)}`:m.toFixed(2)}default:{const m=c[r];return m==null||m===-1?"—":String(m)}}}function Fy({search:c,selected:r,onSelect:m}){const{filters:o,update:b,result:j}=c,[M,N]=g.useState(Wy),[y,T]=g.useState(!1),B=g.useRef(null),p=g.useMemo(()=>bs.filter(V=>M.has(V.key)),[M]),A=(j==null?void 0:j.items)??[];g.useEffect(()=>{try{localStorage.setItem(tm,JSON.stringify([...M]))}catch{}},[M]),g.useEffect(()=>{const V=C=>{var zt,Ut;if(((zt=C.target)==null?void 0:zt.tagName)==="INPUT"||((Ut=C.target)==null?void 0:Ut.tagName)==="SELECT")return;if(C.key==="Escape"){m(null);return}if(C.key!=="ArrowDown"&&C.key!=="ArrowUp")return;C.preventDefault();const Y=r?A.indexOf(r):-1,F=C.key==="ArrowDown"?Math.min(Y+1,A.length-1):Math.max(Y-1,0);A[F]&&m(A[F])};return window.addEventListener("keydown",V),()=>window.removeEventListener("keydown",V)},[A,r,m]);const R=V=>{V&&(o.sortBy===V?b({sortDir:o.sortDir==="asc"?"desc":"asc"}):b({sortBy:V,sortDir:"asc"}))},L=j?Math.max(1,Math.ceil(j.total_count/j.limit)):1,$=V=>{var C;b({page:Math.min(Math.max(1,V),L)}),(C=B.current)==null||C.scrollTo(0,0)};return s.jsxs("div",{className:"inv-results",ref:B,children:[s.jsxs("div",{className:"inv-colpicker-anchor",children:[s.jsx("button",{className:"inv-btn inv-colpicker-btn",onClick:()=>T(V=>!V),children:"⚙ Columns"}),y&&s.jsx("div",{className:"inv-colpicker",children:bs.map(V=>s.jsxs("label",{className:"inv-fitem",children:[s.jsx("input",{type:"checkbox",checked:M.has(V.key),onChange:()=>{const C=new Set(M);C.has(V.key)?C.delete(V.key):C.add(V.key),N(C)}})," ",V.label]},V.key))})]}),s.jsxs("table",{children:[s.jsx("thead",{children:s.jsx("tr",{children:p.map(V=>s.jsx("th",{className:o.sortBy===V.sortKey?`inv-sorted-${o.sortDir}`:"",onClick:()=>R(V.sortKey),children:V.label},V.key))})}),s.jsxs("tbody",{children:[A.map((V,C)=>s.jsx("tr",{className:V===r?"inv-sel":"",onClick:()=>m(V===r?null:V),children:p.map(Y=>s.jsx("td",{children:$y(V,Y.key)},Y.key))},C)),!A.length&&s.jsx("tr",{children:s.jsx("td",{colSpan:p.length,className:"inv-dim",children:"No items match."})})]})]}),s.jsxs("div",{className:"inv-pager",children:[s.jsx("span",{className:"inv-pg",onClick:()=>$(o.page-1),children:"◀"}),s.jsxs("span",{children:["page ",(j==null?void 0:j.page)??1," / ",L]}),s.jsx("span",{className:"inv-pg",onClick:()=>$(o.page+1),children:"▶"}),s.jsxs("span",{className:"inv-pager-right",children:[(j==null?void 0:j.limit)??200," / page"]})]})]})}function Al({k:c,v:r}){return s.jsxs("div",{className:"inv-kv",children:[s.jsx("span",{children:c}),s.jsx("b",{children:r??"—"})]})}function Iy({item:c,onClose:r}){var m,o;return s.jsxs("div",{className:"inv-detail",children:[s.jsx("span",{className:"inv-closex",onClick:r,children:"×"}),s.jsx("h3",{children:c.name}),s.jsxs("div",{className:"inv-detail-sub",children:[c.slot_name??c.object_class_name??""," · ",c.is_equipped?"⚔ Equipped":"📦 Inventory",c.is_rare&&" · ★ Rare"]}),s.jsx(Al,{k:"Character",v:c.character_name}),s.jsx(Al,{k:"Value",v:(m=c.value)==null?void 0:m.toLocaleString()}),s.jsx(Al,{k:"Burden",v:c.burden}),s.jsx(Al,{k:"Wield req",v:c.wield_level?`Level ${c.wield_level}`:"—"}),s.jsx(Al,{k:"Workmanship",v:c.workmanship??"—"}),c.armor_level!=null&&c.armor_level>0&&s.jsx(Al,{k:"Armor",v:c.armor_level}),c.max_damage!=null&&c.max_damage>0&&s.jsx(Al,{k:"Max damage",v:c.max_damage}),c.od_rating!=null&&s.jsx(Al,{k:"Weapon OD",v:c.od_rating>0?`+${c.od_rating.toFixed(2)}`:c.od_rating.toFixed(2)}),c.condition_percent!=null&&s.jsx(Al,{k:"Condition",v:`${c.condition_percent}%`}),c.item_set_name&&s.jsx(Al,{k:"Set",v:c.item_set_name}),(c.is_bonded||c.is_attuned)&&s.jsx(Al,{k:"Binding",v:[c.is_bonded&&"Bonded",c.is_attuned&&"Attuned"].filter(Boolean).join(", ")}),s.jsx("hr",{}),s.jsxs("div",{className:"inv-sphead",children:["Spells (",((o=c.spell_names)==null?void 0:o.length)??0,")"]}),(c.spell_names??[]).map((b,j)=>s.jsx("div",{className:`inv-sp${/legendary/i.test(b)?" inv-leg":""}`,children:b},j)),s.jsx("div",{className:"inv-hint",children:"↑/↓ next item · Esc close"})]})}function Vd(c){return`${c.name} ${c.character_name} ${c.last_updated??""}`}class Py extends g.Component{constructor(r){super(r),this.state={hasError:!1}}static getDerivedStateFromError(){return{hasError:!0}}componentDidCatch(r,m){console.error("Inventory search crashed:",r,m)}render(){return this.state.hasError?s.jsx("div",{className:"inv-page",children:s.jsxs("div",{className:"inv-error",style:{margin:"auto",textAlign:"center",padding:24},children:[s.jsx("p",{style:{marginBottom:12},children:"Something went wrong loading the inventory search page."}),s.jsx("button",{className:"inv-btn",onClick:()=>{window.location.href="/?view=inventory"},children:"Reset filters"})]})}):this.props.children}}function tv(){const c=Qy(),[r,m]=g.useState(null);return g.useEffect(()=>{var M;if(!r)return;const o=((M=c.result)==null?void 0:M.items)??[],b=Vd(r),j=o.find(N=>Vd(N)===b);j&&j!==r?m(j):j||m(null)},[c.result]),s.jsxs("div",{className:"inv-page",children:[s.jsxs("div",{className:"inv-topbar",children:[s.jsx("span",{className:"inv-title",children:"⚔ Inventory Search"}),s.jsx("input",{className:"inv-searchbox",placeholder:"Search name or material…",value:c.filters.text,onChange:o=>c.update({text:o.target.value})}),s.jsx("button",{className:"inv-btn",onClick:()=>{c.reset(),m(null)},children:"Reset"}),s.jsx("span",{className:"inv-count",children:c.error?s.jsx("span",{className:"inv-error",children:c.error}):c.result?s.jsxs(s.Fragment,{children:[s.jsx("b",{children:c.result.total_count.toLocaleString()})," items",c.queryMs!=null&&s.jsxs(s.Fragment,{children:[" · ",c.queryMs," ms"]}),c.loading&&" · …"]}):"loading…"})]}),s.jsx(Jy,{search:c}),s.jsxs("div",{className:"inv-main",children:[s.jsx(ky,{search:c}),s.jsx(Fy,{search:c,selected:r,onSelect:m}),r&&s.jsx(Iy,{item:r,onClose:()=>m(null)})]})]})}function lv(){return s.jsx(Py,{children:s.jsx(tv,{})})}function ev(){const c=new URLSearchParams(window.location.search).get("view");return s.jsx(X0,{children:c==="dashboard"?s.jsx(Oy,{}):c==="inventory"?s.jsx(lv,{}):s.jsx(av,{})})}function av(){const c=Pd();return s.jsx(Ny,{data:c})}O0.createRoot(document.getElementById("root")).render(s.jsx(g.StrictMode,{children:s.jsx(ev,{})}));"serviceWorker"in navigator&&navigator.serviceWorker.register("/sw.js").catch(()=>{});export{kd as D,It as a,cv as b,uv as c,iv as d,ly as e,fv as f,rv as g,ov as h,s as j,sv as l,g as r,An as u}; diff --git a/static/index.html b/static/index.html index 0917c0a8..653b289f 100644 --- a/static/index.html +++ b/static/index.html @@ -8,7 +8,7 @@ - +