Compare commits
5 commits
e74dd17d0e
...
1c6a53096d
| Author | SHA1 | Date | |
|---|---|---|---|
| 1c6a53096d | |||
| fb39e1749f | |||
| e38d5baf6a | |||
| 24999a30ba | |||
| 0334ab1037 |
95
README.md
|
|
@ -1,58 +1,63 @@
|
||||||
# nte-optimizer
|
# nte-optimizer
|
||||||
|
|
||||||
Gear optimizer for *Neverness to Everness*. Static site, no server, no account.
|
> [!CAUTION]
|
||||||
|
> **This repository is vibecoded.** Its implementation was written with substantial AI assistance and may contain plausible-looking mistakes, unsafe assumptions, or unreviewed edge cases. Treat it with care: inspect the code, verify outputs, and run the tests before relying on it.
|
||||||
|
|
||||||
It imports the JSON that [`nte-exporter`](../nte-exporter) writes during a normal
|
Gear optimizer for *Neverness to Everness*. Static site, no server, no account, and no runtime connection to the game.
|
||||||
capture run, and recommends what to equip on whom — drawn onto each character's
|
|
||||||
console grid.
|
|
||||||
|
|
||||||
## Running it
|
It imports a gear snapshot produced by `nte-exporter`, scores the available cartridges and modules, and draws recommended builds directly onto each character's console grid.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Single-character optimization with Prydwen targets or custom targets and weights.
|
||||||
|
- Cartridge set and 2-piece/4-piece bonus selection.
|
||||||
|
- Arc stats, refinements, conditional-effect controls, and explicit notices for effects the model cannot score.
|
||||||
|
- Team optimization against one shared item pool without assigning an item twice.
|
||||||
|
- Console-grid layouts with module placement and enough item detail to find each piece in game.
|
||||||
|
- Local equipment tracking, Equip/Undo, and import refreshes from game truth.
|
||||||
|
- Predicted-versus-measured character sheet comparison.
|
||||||
|
- Hosted build plus a single-file offline build.
|
||||||
|
|
||||||
|
All account data stays in the browser. Nothing is uploaded by the app.
|
||||||
|
|
||||||
|
## Running locally
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm ci
|
npm ci
|
||||||
npm run dev # development
|
npm run dev
|
||||||
npm run build # dist/index.html — the normal build
|
|
||||||
npm run build:single # dist/nte.html — one file, works over file://
|
|
||||||
npm test
|
|
||||||
```
|
```
|
||||||
|
|
||||||
`dist/` is **committed on purpose**. In three years, when `npm ci` fails on some
|
Useful checks and builds:
|
||||||
transitive native module, `python3 -m http.server -d dist` will still work. The
|
|
||||||
source build is the convenience; the committed output is the artifact.
|
|
||||||
|
|
||||||
## Layout
|
```sh
|
||||||
|
npm test
|
||||||
|
npm run check:guides
|
||||||
|
npm run build # hosted build in dist/
|
||||||
|
npm run build:single # standalone dist/nte.html
|
||||||
|
```
|
||||||
|
|
||||||
| path | what lives there |
|
The standalone build works over `file://`. Browser restrictions disable workers, IndexedDB, and bundled artwork there; the app falls back to inline solving and localStorage or memory.
|
||||||
|
|
||||||
|
## Model boundaries
|
||||||
|
|
||||||
|
This is a stat-target optimizer, not a damage simulator. It has no rotation or ability-multiplier model.
|
||||||
|
|
||||||
|
- Targets are floors. Published substat rankings determine their relative weights.
|
||||||
|
- Timed bonuses are reported but not scored without defensible uptime data.
|
||||||
|
- Shield strength, enemy resistance, ally-only buffs, and other unsupported quantities are marked unmodellable instead of mapped onto a different stat.
|
||||||
|
- Level-80 base-stat scaling remains unmeasured, so dependent sheet values are shown as unavailable.
|
||||||
|
- “Proven” means optimal for one packing and cartridge, not globally optimal across every internal beam-search choice.
|
||||||
|
|
||||||
|
## Project layout
|
||||||
|
|
||||||
|
| Path | Contents |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `data-src/` | raw everness mirrors, Arc classifications, guide data. Committed, not shipped. |
|
| `data-src/` | Source classifications, cartridge bonuses, and guide data. |
|
||||||
| `tools/` | build-time scripts. Output goes to `src/generated/`, also committed. |
|
| `tools/` | Data validation, generation, benchmarking, and build scripts. |
|
||||||
| `src/domain/` | **pure.** No DOM, no IndexedDB, no imports from `ui/`, `db/` or `state/`. |
|
| `src/domain/` | Pure stat, board, cartridge, Arc, and scoring logic. |
|
||||||
| `src/solver/` | same rule. Chunked generators, so they run in a worker or inline unchanged. |
|
| `src/solver/` | Worker-safe single-character and team solvers. |
|
||||||
| `src/db/` | schema, migrations, import, persistence adapters. |
|
| `src/db/` | Import validation and local persistence. |
|
||||||
| `src/ui/` | React. Four tabs and a hash router. |
|
| `src/ui/` | React interface. |
|
||||||
|
| `tests/` | Domain, solver, persistence, and integration checks. |
|
||||||
|
|
||||||
The `domain/` and `solver/` rule is what makes them worker-safe, Node-testable
|
`src/domain/` and `src/solver/` stay free of DOM, storage, and UI imports so the same logic runs in tests, inline, or in a Web Worker.
|
||||||
and diffable against the Python they were ported from. Keep it.
|
|
||||||
|
|
||||||
## Two things that are easy to get wrong
|
|
||||||
|
|
||||||
**Ported rules were expensive to derive and break in ways that still look
|
|
||||||
plausible.** Before touching anything in `domain/`, read
|
|
||||||
`~/Apps/nte-research/WIREFORMAT.md` and the "facts worth not re-deriving"
|
|
||||||
section of `RESUME.md`. Builds are 6, 7 or 8 modules and never always 7; the
|
|
||||||
console trait is not always CRIT DMG or Type III; a transposed board renders
|
|
||||||
correctly on a symmetric grid.
|
|
||||||
|
|
||||||
**The model has measured gaps, and the app is built to show them rather than
|
|
||||||
hide them.** Set bonus values are unknown and contribute nothing. The base-stat
|
|
||||||
multiplier has never been read at level 80. A `proven` build is optimal for its
|
|
||||||
packing and cartridge, not globally. Every one of those is surfaced in the UI on
|
|
||||||
purpose — if you find yourself replacing one with a plausible number, don't.
|
|
||||||
|
|
||||||
## Degraded modes
|
|
||||||
|
|
||||||
Opening `dist/nte.html` from the filesystem gives the page an opaque origin, so
|
|
||||||
IndexedDB, workers, `fetch` and module scripts are all unavailable. The app
|
|
||||||
handles this behind two interfaces it never sees through — `PersistenceAdapter`
|
|
||||||
(IndexedDB → localStorage → memory) and `SolverHost` (worker → inline) — and
|
|
||||||
shows a banner when storage is not durable. Artwork is not carried in that build.
|
|
||||||
|
|
|
||||||
1194
data-src/guides.json
|
|
@ -1,127 +1,55 @@
|
||||||
{
|
{
|
||||||
"format": "nte-set-bonuses",
|
"format": "nte-set-bonuses",
|
||||||
"format_version": 1,
|
"format_version": 2,
|
||||||
"note": "Bonus VALUES are not in any capture and not on everness: items.json carries only the cartridge boxes. Each tier stays unknown until read in game or scraped, and an unknown tier contributes nothing rather than a guessed number.",
|
"source": "Prydwen, read 2026-08-21; page updated 2026-04-26",
|
||||||
"sets": {
|
"sets": {
|
||||||
"Crimson: Twin Butterflies": {
|
"Crimson: Twin Butterflies": {
|
||||||
"2": {
|
"2": {"description": "Incantation DMG +10%", "mode": "always", "stats": [{"stat": "DamageUpIncantationBase", "value": 0.1}], "why": "Unconditional wearer stat."},
|
||||||
"unknown": true,
|
"4": {"description": "ATK +6% per nearby team Incantation DMG trigger, up to 6 stacks; each lasts 10s.", "mode": "stacks", "max_stacks": 6, "stats": [{"stat": "AtkUp", "value": 0.06}], "why": "Wearer ATK stacks to 6 and remains active off-field."}
|
||||||
"stats": []
|
},
|
||||||
},
|
"Devil's Blood: Curse": {
|
||||||
"4": {
|
"2": {"description": "Psyche DMG +10%", "mode": "always", "stats": [{"stat": "DamageUpPsycheBase", "value": 0.1}], "why": "Unconditional wearer stat."},
|
||||||
"unknown": true,
|
"4": {"description": "DMG +18%, increased to 36% against units affected by Nova or Stain.", "mode": "always", "stats": [{"stat": "DamageUpGeneralBase", "value": 0.18}], "why": "The unconditional 18% is modelled; the target-conditional increase is not assumed."}
|
||||||
"stats": []
|
},
|
||||||
}
|
"Diabolos": {
|
||||||
},
|
"2": {"description": "Chaos DMG +10%", "mode": "always", "stats": [{"stat": "DamageUpChaosBase", "value": 0.1}], "why": "Unconditional wearer stat."},
|
||||||
"Devil's Blood: Curse": {
|
"4": {"description": "Ignores 12% Chaos RES, increased to 24% for 20s after Nova or Scorch.", "mode": "unmodellable", "stats": [], "why": "Chaos RES is not DEF; mapping this to DefIgnore would model a different quantity."}
|
||||||
"2": {
|
},
|
||||||
"unknown": true,
|
"Fireflies and the Forest": {
|
||||||
"stats": []
|
"2": {"description": "Anima DMG +10%", "mode": "always", "stats": [{"stat": "DamageUpNatureBase", "value": 0.1}], "why": "Anima is named Nature in the stat ids."},
|
||||||
},
|
"4": {"description": "CRIT DMG +8% per nearby team Anima DMG trigger, up to 7 stacks; each lasts 10s.", "mode": "stacks", "max_stacks": 7, "stats": [{"stat": "CritDamageBase", "value": 0.08}], "why": "Wearer CRIT DMG stacks to 7 and remains active off-field."}
|
||||||
"4": {
|
},
|
||||||
"unknown": true,
|
"Kingdom's Guard": {
|
||||||
"stats": []
|
"2": {"description": "DEF +15%", "mode": "always", "stats": [{"stat": "DefUp", "value": 0.15}], "why": "Unconditional wearer stat."},
|
||||||
}
|
"4": {"description": "Shields +20%", "mode": "unmodellable", "stats": [], "why": "Shield strength has no stat-vector slot."}
|
||||||
},
|
},
|
||||||
"Diabolos": {
|
"Lost Radiance": {
|
||||||
"2": {
|
"2": {"description": "Cosmos DMG +10%", "mode": "always", "stats": [{"stat": "DamageUpCosmosBase", "value": 0.1}], "why": "Unconditional wearer stat."},
|
||||||
"unknown": true,
|
"4": {"description": "Ignores 25% DEF for 20s after Ultimate.", "mode": "duration", "stats": [{"stat": "DefIgnore", "value": 0.25}], "why": "Timed post-Ultimate stat; uptime needs rotation data, so it is reported but not scored."}
|
||||||
"stats": []
|
},
|
||||||
},
|
"Quiet Manor": {
|
||||||
"4": {
|
"2": {"description": "Mental DMG +10%", "mode": "always", "stats": [{"stat": "DamageUpPsychicallyBase", "value": 0.1}], "why": "User-decided circumstantial mapping: DamageUpPsychicallyBase is the only non-element damage id, appears on 19 real items, and Fadia's guide pairs Mental DMG with Quiet Manor. Not sheet-confirmed; check in game."},
|
||||||
"unknown": true,
|
"4": {"description": "Mental DMG +12% per Basic Attack, up to 3 stacks; each lasts 6s.", "mode": "stacks", "max_stacks": 3, "stats": [{"stat": "DamageUpPsychicallyBase", "value": 0.12}], "why": "Uses the same user-decided Mental DMG mapping as the 2-piece tier; stacks to 3."}
|
||||||
"stats": []
|
},
|
||||||
}
|
"Shadow Creed": {
|
||||||
},
|
"2": {"description": "ATK +10%", "mode": "always", "stats": [{"stat": "AtkUp", "value": 0.1}], "why": "Unconditional wearer stat."},
|
||||||
"Fireflies and the Forest": {
|
"4": {"description": "ATK +25% for 20s after Skill.", "mode": "duration", "stats": [{"stat": "AtkUp", "value": 0.25}], "why": "Timed post-Skill stat; uptime needs rotation data, so it is reported but not scored."}
|
||||||
"2": {
|
},
|
||||||
"unknown": true,
|
"Speedy Hedgehog": {
|
||||||
"stats": []
|
"2": {"description": "Charge Efficiency +12%", "mode": "always", "stats": [{"stat": "ChargeGetEfficiencyBase", "value": 0.12}], "why": "Unconditional wearer stat."},
|
||||||
},
|
"4": {"description": "All allies' ATK +15% for 20s after wearer uses Ultimate.", "mode": "unmodellable", "stats": [], "why": "Buff applies to allies, not the wearer being optimised."}
|
||||||
"4": {
|
},
|
||||||
"unknown": true,
|
"Street Boxer": {
|
||||||
"stats": []
|
"2": {"description": "Lakshana DMG +10%", "mode": "always", "stats": [{"stat": "DamageUpLakshanaBase", "value": 0.1}], "why": "Unconditional wearer stat."},
|
||||||
}
|
"4": {"description": "CRIT Rate +14%.", "mode": "always", "stats": [{"stat": "CritBase", "value": 0.14}], "why": "Prydwen's reaction sentence repeats 14% from 14%; treated as a source typo, not a second value."}
|
||||||
},
|
},
|
||||||
"Kingdom's Guard": {
|
"Thea's Night Tavern": {
|
||||||
"2": {
|
"2": {"description": "HP +10%", "mode": "always", "stats": [{"stat": "HPMaxUp", "value": 0.1}], "why": "Unconditional wearer stat."},
|
||||||
"unknown": true,
|
"4": {"description": "Healing Bonus +20%", "mode": "always", "stats": [{"stat": "HealUp", "value": 0.2}], "why": "Unconditional wearer stat."}
|
||||||
"stats": []
|
},
|
||||||
},
|
"Tiny Big Adventure": {
|
||||||
"4": {
|
"2": {"description": "HP +10%", "mode": "always", "stats": [{"stat": "HPMaxUp", "value": 0.1}], "why": "Unconditional wearer stat."},
|
||||||
"unknown": true,
|
"4": {"description": "Max HP +4% when taking damage, up to 10 stacks; each lasts 10s; Ultimate grants 10.", "mode": "stacks", "max_stacks": 10, "stats": [{"stat": "HPMaxUp", "value": 0.04}], "why": "Wearer Max HP stacks to 10; targeting the 4-piece tier uses its stated maximum."}
|
||||||
"stats": []
|
}
|
||||||
}
|
|
||||||
},
|
|
||||||
"Lost Radiance": {
|
|
||||||
"2": {
|
|
||||||
"unknown": true,
|
|
||||||
"stats": []
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"unknown": true,
|
|
||||||
"stats": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Quiet Manor": {
|
|
||||||
"2": {
|
|
||||||
"unknown": true,
|
|
||||||
"stats": []
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"unknown": true,
|
|
||||||
"stats": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Shadow Creed": {
|
|
||||||
"2": {
|
|
||||||
"unknown": true,
|
|
||||||
"stats": []
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"unknown": true,
|
|
||||||
"stats": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Speedy Hedgehog": {
|
|
||||||
"2": {
|
|
||||||
"unknown": true,
|
|
||||||
"stats": []
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"unknown": true,
|
|
||||||
"stats": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Street Boxer": {
|
|
||||||
"2": {
|
|
||||||
"unknown": true,
|
|
||||||
"stats": []
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"unknown": true,
|
|
||||||
"stats": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Thea's Night Tavern": {
|
|
||||||
"2": {
|
|
||||||
"unknown": true,
|
|
||||||
"stats": []
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"unknown": true,
|
|
||||||
"stats": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Tiny Big Adventure": {
|
|
||||||
"2": {
|
|
||||||
"unknown": true,
|
|
||||||
"stats": []
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"unknown": true,
|
|
||||||
"stats": []
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
BIN
public/img/YH_lihui_character_adele-1c93d4c6.webp
Normal file
|
After Width: | Height: | Size: 109 KiB |
BIN
public/img/YH_lihui_character_aidejia-863c666d.webp
Normal file
|
After Width: | Height: | Size: 122 KiB |
BIN
public/img/YH_lihui_character_anhunqu-cdc625ba.webp
Normal file
|
After Width: | Height: | Size: 140 KiB |
BIN
public/img/YH_lihui_character_baizhang-634c4c79.webp
Normal file
|
After Width: | Height: | Size: 145 KiB |
BIN
public/img/YH_lihui_character_bohe-0b1d4e6f.webp
Normal file
|
After Width: | Height: | Size: 178 KiB |
BIN
public/img/YH_lihui_character_dafudier-6e05ec14.webp
Normal file
|
After Width: | Height: | Size: 114 KiB |
BIN
public/img/YH_lihui_character_fadiya-8e796e94.webp
Normal file
|
After Width: | Height: | Size: 145 KiB |
BIN
public/img/YH_lihui_character_hahuosuoer-d0eb862f.webp
Normal file
|
After Width: | Height: | Size: 151 KiB |
BIN
public/img/YH_lihui_character_haniya-d6f50120.webp
Normal file
|
After Width: | Height: | Size: 123 KiB |
BIN
public/img/YH_lihui_character_jiuyuan-f46d2630.webp
Normal file
|
After Width: | Height: | Size: 170 KiB |
BIN
public/img/YH_lihui_character_langren-fda901d5.webp
Normal file
|
After Width: | Height: | Size: 99 KiB |
BIN
public/img/YH_lihui_character_nanali-54fe0562.webp
Normal file
|
After Width: | Height: | Size: 209 KiB |
BIN
public/img/YH_lihui_character_nanzhu-d5ba3e19.webp
Normal file
|
After Width: | Height: | Size: 97 KiB |
BIN
public/img/YH_lihui_character_nvzhu-d16dc3c1.webp
Normal file
|
After Width: | Height: | Size: 100 KiB |
BIN
public/img/YH_lihui_character_xiaozhi-46c53452.webp
Normal file
|
After Width: | Height: | Size: 147 KiB |
BIN
public/img/YH_lihui_character_xun-5ab32493.webp
Normal file
|
After Width: | Height: | Size: 229 KiB |
BIN
public/img/YH_lihui_character_zaowu-75eb4a80.webp
Normal file
|
After Width: | Height: | Size: 93 KiB |
BIN
public/img/YH_lihui_fashionshop_canhong-27e1ca03.webp
Normal file
|
After Width: | Height: | Size: 198 KiB |
BIN
public/img/YH_lihui_fashionshop_haiyue1-081a822e.webp
Normal file
|
After Width: | Height: | Size: 149 KiB |
BIN
public/img/YH_lihui_fashionshop_kaesi-166ca8cc.webp
Normal file
|
After Width: | Height: | Size: 121 KiB |
BIN
public/img/YH_lihui_fashionshop_lingke-03f05fd7.webp
Normal file
|
After Width: | Height: | Size: 137 KiB |
BIN
public/img/YH_lihui_fashionshop_yiluoyi-c074e0a9.webp
Normal file
|
After Width: | Height: | Size: 173 KiB |
BIN
public/img/YH_lihui_fashionshop_zhenhong-d64fb4f5.webp
Normal file
|
After Width: | Height: | Size: 169 KiB |
BIN
public/img/fork_Arachne_256-334bca8d.webp
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
public/img/fork_BitGame_256-60716289.webp
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
public/img/fork_BitterCake_256-7dfa230c.webp
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
public/img/fork_BlackBook_256-8c5bc8ff.webp
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
public/img/fork_BlastCandy_256-23f701c1.webp
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
public/img/fork_BoxingCandy_256-3403c6b4.webp
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
public/img/fork_Butterfly_256-8bb7bf88.webp
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
public/img/fork_Castle_256-7b6d7958.webp
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
public/img/fork_DemonBlade_256-95122830.webp
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
public/img/fork_Door_256-5c392b08.webp
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
public/img/fork_GoldRecord_256-8a5c1c91.webp
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
public/img/fork_GoldWool_256-7f1873db.webp
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
public/img/fork_HugVine_256-408c6d47.webp
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
public/img/fork_Kite_256-f749b27a.webp
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
public/img/fork_KnightCandy_256-3fb5130a.webp
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
public/img/fork_LunarPhase_256-04d3a548.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
public/img/fork_MotorCandy_256-22d591e4.webp
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
public/img/fork_Nakupeda_256-ef6a4ed6.webp
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
public/img/fork_NestBird_256-fa9c2459.webp
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
public/img/fork_PaperPlane_256-20eaef80.webp
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
public/img/fork_PoliceRat_256-bcd60a07.webp
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
public/img/fork_Qiaoqiao_256-56594355.webp
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
public/img/fork_Rose_256-245f28c5.webp
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
public/img/fork_ThiefCandy_256-458b7cdd.webp
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
public/img/fork_TigerTally_256-762e1c1b.webp
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
public/img/fork_Time_256-d694a147.webp
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
public/img/fork_Whale_256-87b0cc06.webp
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
public/img/fork_bopu_256-f320967a.webp
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
public/img/fork_dustbin_256-56d579d0.webp
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
public/img/fork_fudianling_256-70ef1a4e.webp
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
public/img/fork_jiaojuan_256-5ef9bea7.webp
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
public/img/fork_jingmotingyuan_256-d316d16f.webp
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
public/img/fork_koinobori_256-3d0f806c.webp
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
public/img/fork_lingganzhongjiezhe_256-2cfe42bc.webp
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
public/img/fork_mamen_256-e3a00dfd.webp
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
public/img/fork_mofeikesi_256-8321dc43.webp
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
public/img/fork_moon_256-e5a415d1.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |