fix: enhance error handling in compare and calculateBuild sagas
- Added checks to prevent unhandled TypeErrors in the compare saga when processing empty builds.
- Wrapped the calculateBuild saga in a try-catch block to handle unexpected errors and ensure the rootSaga remains stable.
- Improved logging for errors in the calculateBuild saga to aid in debugging.
refactor: update damage calculation methods and improve champion stats handling
- Refactor damage calculation for turret attacks to use `getDamageMultiplier` for better accuracy.
- Update ability cooldown calculation to utilize `convertAhToCooldownMultiplier` for improved clarity.
- Rearrange bonus armor and magic resistance calculations for champions to ensure correct level-based scaling.
- Introduce a new action to clear loaded champion overrides in the state management for better state handling.
fix: kit AD before EH, cooldown clamp, Slow+Zealot, compare worker sync, item order labels
- Apply kit bonus AD (e.g. Senna mist, Darius Noxian Might) via `applyKitBonusADBeforeEndlessHunger` before Endless Hunger’s innate AH; move EH AH to run before `Adjust_Attack_Count` so rotations and haste scaling see it; remove the later duplicate EH block.
- Slow and Steady: fold Zealot’s bonus AS into the AS→AD conversion; only strip non-Zealot bonus AS at conversion; when Zealot runs afterward, avoid double-counting AS and correct AD if AP changed after Slow and Steady.
- Darius/Senna: drop inline AD from champion files; rely on the early kit-bonus AD path for EH ordering.
- `getAbilityCooldownsPerChampionLevel` / extra abilities: clamp ability level to the last non-null cooldown rank so over-leveled skills don’t read as 0 CD and zero out ability-based effects.
- Item scan: renumber replacement slots starting at 7 (`STANDARD_BUILD_SIZE + 1`) so extra slots (e.g. ADC boots quest) don’t skew displayed replacement order.
- Compare saga: call `workerInstance.setSettings` with current Redux settings before compare so the worker isn’t using stale settings; simplify the generator typing.
- Augments UI: display-name overrides for Crit ’n Cast and Upgrade Infinity Edge; register `critNCast` as implemented.
- Button: remove redundant Enter `onKeyDown` handler (native button already activates on Enter).
Guard against NaN/div-by-zero in damage calculations
Add runtime guards and tests to prevent NaN or infinite values when damage pools or weights are zero or non-finite. Changes include:
- Add tests: defense-nan-guards.spec.ts and changeDamageTypeValue.test.ts to cover edge cases where incomingDamage or saved damage triples are zero or NaN.
- Strengthen applyItemBuildDamageShift to skip shifting when transferable pool or total is non-positive/NaN (use !(x > 0) checks) and normalize to thirds when needed.
- Make enemyChampionProfile robust: use a 1/3 default base when raw totals are non-positive/NaN, fall back to equal share for damageReceived when sum is non-positive, and avoid dividing by zero by using a weightDivisor fallback for averaged stats.
- Update game slice changeDamageTypeValue reducer to avoid 0/0 by checking denom > 0 and defaulting to 0.5 when both other slots are zero.
- Add extra unit tests for item-build damage shifting behavior and edge cases.
- Change IncomingDamageCell input min from 0 to 1 to prevent zero incoming damage being set via the UI.
These changes prevent runtime NaNs/infinities and ensure normalization remains stable in edge-case inputs.
- Enhance enemy damage type representation and clarify tooltips.
- Improved comments in getItemOffensiveProfile.ts to reflect the heuristic nature of damage type calculations.
- Adjusted EnemyTable and TeamDamageComposition components to provide clearer descriptions of damage types and their estimation methods.
Update build card, item limits, and build keys
Remove syncId from the BuildCard chart to prevent unintended chart synchronization. Add ItemLimit.fatality to arenaPerplexity limits. In AlternativeBuilds, stop slicing the builds list and generate a stable unique key using the index plus joined item ids to avoid React key collisions and allow all sorted builds to render.
Refactor imports, dynamic tabs, add benchmarks
- Replace lodash namespace imports with path-specific imports (e.g. lodash/range, lodash/isEqual) to enable better bundling and tree-shaking.
- Split champion static props into its own module and simplify pages/itemop/[championName].tsx to re-export getStaticPaths/getStaticProps; reduces bundle size for the page.
- Add dynamic tab chunking (src/features/itemop/settings-routes.tsx) with prefetchTabChunk and useTransition integration in menu and champion components to warm and load tab chunks without blocking UI.
- Replace the old static settings-routes with a dynamic version that lazy-loads tab components and provides a lightweight loading skeleton.
- Add scripts/benchmark-pages.ts to measure static export page sizes (HTML + referenced JS/CSS) and a package.json script to run it; bump pnpm version and adjust start scripts for webpack/turbopack usage.
- Add public/_headers for long-lived caching of versioned static assets for static hosts (Cloudflare Pages / Netlify-style).
- Preload key fonts in pages/_document.tsx and update font stylesheets to use font-display: swap and reorganize face declarations for better loading behavior.
- Improve robustness: handle KeyboardJS dynamic import failures, guard chunk preloads, and minor accessibility/structure updates in various UI components (RecentSummoners, AlternativeBuilds, CompareBar, Export Settings tree uses deepdash/standalone and lodash helpers).
Other smaller changes: various UI tweaks, selector typings (RootState), small bugfixes and optimizations across components and scrapers.
