Compare commits
@@ -0,0 +1,59 @@
|
||||
---
|
||||
name: wizwar-audits
|
||||
description: Run the Wiz-War health audits — UI coverage of engine events/cards (the "telepath audit"), live-game ledger inspection by room code, and the pre-deploy determinism gate. Use when asked to audit, when adding cards or events, or when a player reports "the engine did X but I never saw it".
|
||||
---
|
||||
|
||||
# Wiz-War audits
|
||||
|
||||
Three recurring audits keep the maze honest. The first is self-enforcing;
|
||||
the other two are on-demand.
|
||||
|
||||
## 1. UI coverage — "the telepath audit" (automated)
|
||||
|
||||
`packages/engine/test/ui-coverage.test.ts` runs with every `npm test` and
|
||||
fails when:
|
||||
|
||||
- a GameEvent type has no client handling (no `humanize` case in
|
||||
`net.svelte.ts`, no fx in `fx.ts`, no modal check in `App.svelte`) and is
|
||||
not in the test's `SILENT_BY_DESIGN` allowlist — each allowlist entry
|
||||
needs a reason for why the player sees the information another way;
|
||||
- a card resolver demanding a cell/edge target is missing from App's
|
||||
`CELL_CARDS` / `EDGE_CARDS` click-targeting sets (an unaimable cast).
|
||||
|
||||
When adding an **event**: give it a `humanize` line at minimum. Private
|
||||
info (`visibleTo` events carrying cards) deserves the `cardReveal` modal
|
||||
in App.svelte — see `handRevealedPrivate` / `cardsStolenPrivate` /
|
||||
`handTakenPrivate` for the pattern. When adding a **card** with a cell or
|
||||
edge target, add it to the App targeting set; with `params`, wire the
|
||||
named-card picker (`NAMED_CARDS` + suggestions) or a bespoke control.
|
||||
|
||||
The one axis the test cannot judge: whether a `params`-taking card's
|
||||
input UI actually offers sensible choices. Check that by hand when adding
|
||||
one (thief → target's steallables, deja-vu → discard contents, etc.).
|
||||
|
||||
## 2. Live-game audit by room code
|
||||
|
||||
Fetch and replay production ledgers (details in auto-memory
|
||||
`wizwar-fetch-game-files`):
|
||||
|
||||
scp root@104.236.96.198:/var/lib/wizwar/rooms/<CODE>.jsonl <scratchpad>/
|
||||
|
||||
Replay with `createGame({playerIds, seed, sets, colors, deckRev})` +
|
||||
`applyCommand` per command line (see `deploy/replay-verify.mjs`). Stop at
|
||||
any seq to inspect full state. To ask why a bot did something, rebuild
|
||||
the state at its turn and call `automatonCommand(viewFor(state, id),
|
||||
style, tier)` — and if its choice differs from the ledger, the engine
|
||||
refused it and the fallback burned the turn.
|
||||
|
||||
For "which games are open/stalled" sweeps: fetch all `*.jsonl`, replay
|
||||
each, and report phase / round / humans vs bots / last command's `at`.
|
||||
|
||||
## 3. Determinism gate (before deploying engine changes)
|
||||
|
||||
deploy/verify-ledgers.sh 104.236.96.198
|
||||
|
||||
Strict-replays every production ledger against the local engine; one
|
||||
refused command fails. A room whose ledger no longer replays becomes
|
||||
unreachable after restart. Rules changes while games are live need a
|
||||
`deckRev` bump plus an engine gate. Production deckRev is currently 1,
|
||||
so low numbers are not stale.
|
||||
@@ -0,0 +1,141 @@
|
||||
---
|
||||
name: wizwar-duel
|
||||
description: Play Wiz-War live against Eric — join his room as a real seat, reason about every move yourself, and duel turn by turn over the websocket. Use when Eric wants a game, gives a room code, or says "let's play".
|
||||
---
|
||||
|
||||
# Playing Wiz-War against Eric
|
||||
|
||||
You are a PLAYER, not the automaton. Read the board, reason, and choose
|
||||
every command yourself. Eric plays in his browser; you play through the
|
||||
CLI seat at `tools/claude-seat.mjs`. He prompts "go" after his moves —
|
||||
each of his messages is your cue to look and act.
|
||||
|
||||
## The seat client
|
||||
|
||||
Run from the repo root (needs the workspace's `ws` package):
|
||||
|
||||
```bash
|
||||
node tools/claude-seat.mjs join <ROOM> Claude # take a seat (token saved)
|
||||
node tools/claude-seat.mjs view # board + hand + last events
|
||||
node tools/claude-seat.mjs do '<command json>' # one engine command
|
||||
node tools/claude-seat.mjs chat "text" # table talk
|
||||
```
|
||||
|
||||
Seat state persists in `/tmp/wizwar-claude-seat.json` (override:
|
||||
`WIZWAR_SEAT`); server defaults to production (`WIZWAR_SERVER` to point
|
||||
elsewhere). Eric creates the room, gives you the code, and starts the
|
||||
game after you join.
|
||||
|
||||
Commands are the engine's `Command` union (packages/engine/src/game.ts):
|
||||
`{"type":"move","direction":"N|S|E|W"}`, `cast` (with `target`, optional
|
||||
`numberInstanceIds`/`params`), `playNumberForMovement`, `pickUpTreasure`,
|
||||
`dropTreasure`, `warpStep`, `counteract`, `pass`, `punch`, `setAmbush`,
|
||||
`wardChoice`, `endTurn` (with `draw`). A refused command costs nothing —
|
||||
probing legality is free, so when unsure, try it and read the error.
|
||||
|
||||
## Reading the map
|
||||
|
||||
- The renderer prints y=0 at top; **y grows SOUTH**. N = y-1, S = y+1.
|
||||
- `C2` is you, `P1` etc. are opponents, `$c`/`$1` treasures, `h?` homes,
|
||||
two-letter codes are square contents (SA safe, RO rosebush, ST stone,
|
||||
DU dust). `D` on a line is a door, `—` a wall, blank is open.
|
||||
- WARPS line lists rim passages as `2,0N→2,9`: standing at (2,0) and
|
||||
moving N carries you to (2,9). **The warp rides one specific side of
|
||||
its square** — check which before you walk (a wrong guess burns moves;
|
||||
ask me how I know).
|
||||
- Dimensional-warp TOKENS (cast by players) are separate: stand on one
|
||||
and `warpStep`. Creatures use `creatureWarpStep`.
|
||||
|
||||
## Hard-won rules knowledge (each cost me something in game one)
|
||||
|
||||
- `pickUpTreasure` ENDS your turn's actions AND movement — arrive with
|
||||
the grab as your last act, never mid-plan. `dropTreasure` at home too.
|
||||
- You can pick up ANY floor treasure, including your own stolen-and-
|
||||
delivered one sitting on the enemy's home square. Repossession is real.
|
||||
- THIEF and punches need same-square; THIEF steals a *named* card and
|
||||
fizzles (card spent) on a wrong guess.
|
||||
- MENTAL FORCE moves the victim ≤3 *walked* spaces — walls and relocked
|
||||
doors shrink its reach; rev 5+ refuses impossible destinations.
|
||||
- Doors relock behind you when you pass through (rev 4+). Your own
|
||||
escape route can seal itself — and seal pursuers out.
|
||||
- LOS threads through rim warps: you can be seen (and shot) through a
|
||||
warp mouth from the far side of the board. Camping one square off the
|
||||
mouth keeps you hidden.
|
||||
- lock-in-place freezes movement AND warpStep for a full turn; REUSE
|
||||
SPELL retrieves only your LAST cast spell, enabling one re-lock.
|
||||
- An ambush (`setAmbush` interrupt/opportunity-fire + committed attack)
|
||||
triggers on LOS *entry* transitions only — someone already in sight
|
||||
never springs it. It survives forever and fires out of turn.
|
||||
- Walking-dead bleeds ½ life per space moved, permanently. Once cursed,
|
||||
every plan must be priced in steps.
|
||||
|
||||
## Game-two scars (each cost me the game or nearly)
|
||||
|
||||
- **RECOUNT THE SCOREBOARD EVERY TURN**: how many treasures does each
|
||||
player have banked AT HOME right now? I sprinted a "winning" delivery
|
||||
in game two that was actually my FIRST of two — Eric had un-banked me
|
||||
five rounds earlier and let me monologue. Banked counts, not vibes.
|
||||
- A banked treasure is NOT safe: anyone can pick it up off your home
|
||||
square and carry it away. Guard the bank or count it as contested.
|
||||
- LOS is FREE-ANGLE center-to-center (the rulebook's rule), not rows
|
||||
and columns: razor diagonals threading open gaps are legal for
|
||||
everyone — including at you. The board draws bent/straight traces.
|
||||
- ILLUSIONARY ATTACK deals its imitated spell's damage if NOT
|
||||
countered; ANY counteraction dispels it entirely. Counter it with
|
||||
the cheapest thing you hold; never "call the bluff" by passing.
|
||||
- Never trust your ASCII parse of the map for multi-step plans: run a
|
||||
BFS over `view.board.edges` (see tools/claude-seat.mjs view JSON, or
|
||||
write a quick router) before spending a number card on a sprint. I
|
||||
burned a 7-move turn bouncing off six misread walls.
|
||||
- Eric counter-plays YOUR bot upgrades: he summoned a troll bodyguard
|
||||
specifically against the archmage's exile-the-winner instinct, and
|
||||
relocated MY home sector mid-carry. Expect meta-warfare.
|
||||
- In 4p with automatons: the bots are chaos agents — they stun, exile,
|
||||
disease, and con. Herd them at Eric; never assume they're on script.
|
||||
|
||||
## Game-three scars (lost in four rounds)
|
||||
|
||||
- **CHECK `dimWarps` EVERY SINGLE VIEW** — Kestrel (Eric's wizard) has
|
||||
won two games
|
||||
with quietly-placed wormholes ending beside his home. The client
|
||||
prints a !! line for them; treat any new token pair as a five-alarm
|
||||
fire and recompute both players' delivery distances through it.
|
||||
- **Never lead the attack against Kestrel.** Three games, three saved
|
||||
counters sprung at the perfect moment (anti-anti, full-shield bait,
|
||||
full-reflection held three rounds for my lightning). Force his
|
||||
counters out with throwaways or positional threats before committing
|
||||
a real spell; his patience is perfect and he telegraphs nothing.
|
||||
- DESTROY WALL showers the ADJACENT caster with rubble (4 damage) —
|
||||
cast it from range, never on your own square's edge.
|
||||
- Wading a rosebush costs 3. A reflected LIGHTNING BLAST still stuns
|
||||
its caster even at 1 reflected damage — the stun is the payload, and
|
||||
a lost turn against Kestrel is a lost game.
|
||||
- Grab-turn-one openings feel great and prove nothing: deliveries are
|
||||
the only score. He banked quietly both times while I showboated.
|
||||
|
||||
## Playing well
|
||||
|
||||
- Kestrel (Eric) is EXCELLENT: he baited my thief, saved anti-anti for
|
||||
my full shield, and won game one with a home-to-home dimensional-warp
|
||||
superhighway. Infrastructure beats sprinting — watch what he builds,
|
||||
and consider your own wormhole early.
|
||||
- Win = 2 enemy treasures delivered to your home, or last wizard alive.
|
||||
Track BOTH players' step-counted delivery timelines every turn; the
|
||||
race is decided in tempo, not damage.
|
||||
- Hold counters (full-shield, absorb) for permanent curses and lethal
|
||||
damage. Absorb soaks 3 points; it cannot touch durations.
|
||||
- OPSEC: your prose is visible to Eric. NEVER name the cards you hold or
|
||||
draw, and never announce plans. (Game one: I narrated my hand like a
|
||||
debug log until he asked why I was making it easy.) Trash talk freely
|
||||
— about the board, never your hand.
|
||||
- Send `chat` for table talk at dramatic moments; it's half the fun.
|
||||
|
||||
## Cadence
|
||||
|
||||
1. On "go": `view`, read HIS events since your last turn (the client
|
||||
prints only NEW events; `view` shows a short history tail).
|
||||
2. Think about the whole board — his timeline, yours, threats, LOS.
|
||||
3. Execute your commands one at a time, checking errors.
|
||||
4. `endTurn` with a draw that respects the 7-card hand limit.
|
||||
5. Tell Eric it's his turn — reasoning aloud is fine, hand contents are
|
||||
not. When a stack waits on him, say so and wait for "go".
|
||||
@@ -4,4 +4,6 @@ dist/
|
||||
.env
|
||||
.DS_Store
|
||||
data/
|
||||
.claude/
|
||||
.claude/*
|
||||
!.claude/skills/
|
||||
.playwright-mcp/
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
[ 241ms] [ERROR] Failed to load resource: the server responded with a status of 404 (File not found) @ http://localhost:8891/favicon.ico:0
|
||||
@@ -1,2 +0,0 @@
|
||||
[ 420ms] [ERROR] Failed to load resource: the server responded with a status of 404 () @ https://fonts.gstatic.com/s/caveat/v23/WnzQHAc5bAfYB2QRah7pcpNvOx-pjcB9KomBkMTTKQ2ysvYDK_guvzEJ99YU.woff2:0
|
||||
[ 6552ms] [ERROR] Failed to load resource: the server responded with a status of 404 () @ https://fonts.gstatic.com/s/caveat/v23/WnzQHAc5bAfYB2QRah7pcpNvOx-pjcB9KomBkMTTKQ2ysvYDK_guvzEJ99YU.woff2:0
|
||||
@@ -1,2 +0,0 @@
|
||||
[ 193ms] [ERROR] Failed to load resource: the server responded with a status of 404 () @ https://fonts.gstatic.com/s/caveat/v23/WnzQHAc5bAfYB2QRah7pcpNvOx-pjcB9KomBkMTTKQ2ysvYDK_guvzEJ99YU.woff2:0
|
||||
[ 6215ms] [ERROR] Failed to load resource: the server responded with a status of 404 () @ https://fonts.gstatic.com/s/caveat/v23/WnzQHAc5bAfYB2QRah7pcpNvOx-pjcB9KomBkMTTKQ2ysvYDK_guvzEJ99YU.woff2:0
|
||||
@@ -1 +0,0 @@
|
||||
[ 189ms] [ERROR] Failed to load resource: the server responded with a status of 404 () @ https://fonts.gstatic.com/s/caveat/v23/WnzQHAc5bAfYB2QRah7pcpNvOx-pjcB9KomBkMTTKQ2ysvYDK_guvzEJ99YU.woff2:0
|
||||
@@ -1,914 +0,0 @@
|
||||
[ 152609ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 257646ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/tokens/treasure-4.png:0
|
||||
[ 258772ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 260278ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 261785ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 263294ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 264799ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 265121ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/tokens/wraith.png:0
|
||||
[ 266304ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 267808ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 269317ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 270822ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 272327ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 272620ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/tokens/skeleton.png:0
|
||||
[ 273838ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 275344ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 276855ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 277125ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/tokens/treasure-3.png:0
|
||||
[ 278368ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 279883ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 281397ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 282923ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 283123ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/tokens/wraith.png:0
|
||||
[ 284461ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 284627ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/tokens/wraith.png:0
|
||||
[ 286048ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 286122ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/tokens/wraith.png:0
|
||||
[ 287581ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 289243ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 290813ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 292595ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 294390ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 296415ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 298083ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 300593ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 302383ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 305833ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 309405ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 312716ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 313128ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/tokens/treasure-4.png:0
|
||||
[ 315372ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 319132ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/tokens/wraith.png:0
|
||||
[ 320626ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/tokens/wraith.png:0
|
||||
[ 321235ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 325129ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/tokens/wraith.png:0
|
||||
[ 325237ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 331677ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 332629ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/tokens/skeleton.png:0
|
||||
[ 335630ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/tokens/wraith.png:0
|
||||
[ 336248ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 337130ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/tokens/wraith.png:0
|
||||
[ 340522ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 346285ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 349124ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/tokens/skeleton.png:0
|
||||
[ 350627ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/tokens/skeleton.png:0
|
||||
[ 351422ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 352127ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/tokens/skeleton.png:0
|
||||
[ 355407ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 361038ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 364125ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/tokens/skeleton.png:0
|
||||
[ 365624ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/tokens/skeleton.png:0
|
||||
[ 366381ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 367125ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/tokens/skeleton.png:0
|
||||
[ 372878ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 374624ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/tokens/thorn-bush.png:0
|
||||
[ 376712ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 381718ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 386406ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 388135ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/tokens/treasure-4.png:0
|
||||
[ 389196ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 392191ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 396170ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 397675ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 399182ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 400688ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 402195ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 403703ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 405207ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 406723ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 408239ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 409766ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 411321ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 412956ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 414636ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 416487ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 419087ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 422410ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 428868ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 433168ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 438630ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 444730ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 450587ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 456456ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 460605ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 463161ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 469664ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 473816ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 478354ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 481420ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 486756ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 492582ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 497201ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 503098ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 509043ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 514068ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 518839ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 522451ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 527128ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 531685ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 535957ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 538795ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 543124ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 549494ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 554492ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 558509ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 563139ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 568562ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 573251ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 578506ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 581743ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 586998ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 590328ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 595255ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 599038ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 602039ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 607836ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 610796ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 615157ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 620870ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 627369ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 632975ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 637405ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 638907ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 640412ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 641916ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 643421ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 644930ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 646436ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 647944ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 649452ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 650989ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 652541ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 654188ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 655847ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 657977ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 660684ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 664051ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 668595ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 673293ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 677621ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 684037ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 689808ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 695746ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 698306ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 702945ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 705817ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 710928ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 715275ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 718798ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 721739ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 726637ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 732957ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 738147ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 742270ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 747558ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 751595ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 757878ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 759380ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 760882ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 762384ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 763887ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 765390ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 766898ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 768407ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 769928ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 771456ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 773301ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 774945ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 776750ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 778502ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 780488ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 783155ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 787528ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 791871ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 798122ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 803059ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 807298ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 813473ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 816831ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 819506ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 824823ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 827747ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 831197ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 837479ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 842361ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 847902ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 851866ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 858060ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 860876ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 866298ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 872252ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 877633ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 883956ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 888030ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 891523ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 894404ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 897780ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 902616ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 907855ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 914182ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 919017ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 924366ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 930117ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 933514ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 937308ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 941885ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 944709ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 947727ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 954108ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 958510ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 961051ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 965152ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 970130ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 973824ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 978781ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 981419ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 985895ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 991092ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 995656ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 999330ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1000833ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1002334ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1003836ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1005338ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1006841ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1008347ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1009853ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1011363ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1012892ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1014431ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1016008ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1017804ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1019636ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1021968ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1025918ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1030911ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1036872ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1042476ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1046566ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1049648ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1054344ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1058372ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1063206ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1067191ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1070939ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1075397ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1080940ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1085883ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1090965ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1095519ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1101984ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1108035ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1110627ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1115173ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1117746ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1123195ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1126552ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1129802ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1135218ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1140687ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1146402ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1150144ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1156238ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1161595ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1168027ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1173338ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1177064ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1183027ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1188131ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1191735ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1195157ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1197737ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1203300ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1209522ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1213650ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1219100ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1223494ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1229841ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1235732ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1240814ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1242316ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1243818ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1245320ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1246822ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1248325ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1249830ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1251342ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1252857ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1254399ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1255953ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1257511ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1259263ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1261221ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1263410ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1267294ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1271995ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1275306ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1279944ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1282751ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1286088ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1291529ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1296577ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1301422ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1304057ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1307586ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1312541ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1316164ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1322638ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1328537ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1333627ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1337920ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1341347ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1347133ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1350410ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1356545ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1359840ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1364706ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1370998ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1376683ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1380372ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1385933ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1390373ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1395807ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1402308ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1406555ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1411992ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1418370ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1423620ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1426621ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1431576ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1437386ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1441649ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1447868ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1452368ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1458783ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1462262ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1467373ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1470884ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1474064ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1477555ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1480103ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1483605ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1488167ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1492812ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1497873ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1501672ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1506179ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1509169ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1511741ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1517646ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1520993ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1525701ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1531664ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1534270ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1540398ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1545631ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1551430ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1555883ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1561789ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1565419ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1571348ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1577540ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1580171ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1583175ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1587237ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1590726ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1595865ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1601873ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1603377ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1604882ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1606385ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1607886ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1609391ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1610897ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1612401ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1613918ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1615437ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1617018ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1618600ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1620186ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1622078ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1624517ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1626966ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1630727ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1636685ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1641233ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1646675ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1650627ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1656147ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1661012ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1664297ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1669486ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1675362ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1678087ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1681784ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1684714ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1690197ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1694231ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1696742ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1702523ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1707245ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1710064ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1712824ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1716844ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1721241ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1727490ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1731235ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1737620ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1740738ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1745610ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1749658ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1752580ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1757381ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1763004ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1766308ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1769306ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1774715ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1780095ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1784290ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1788290ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1794315ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1798954ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1804568ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1810874ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1814383ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1818248ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1823554ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1828717ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1831520ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1837969ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1841753ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1846062ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1848849ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1854446ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1857424ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1862532ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1865457ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1871479ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1874485ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1880353ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1886600ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1892180ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1895932ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1901436ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1906242ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1910357ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1915241ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1920443ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1925222ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1929301ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1935745ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1941015ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1947156ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1951199ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1954444ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1957007ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1960603ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1965472ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1971633ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1977521ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1981887ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1986763ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1992580ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 1997428ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2000954ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2004018ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2008388ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2014146ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2019732ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2024346ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2028732ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2031876ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2035690ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2038927ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2044692ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2048165ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2053743ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2057367ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2063442ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2067326ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2073679ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2078322ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2081638ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2087160ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2089714ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2094168ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2100099ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2103559ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2108513ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2114335ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2117373ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2121864ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2124564ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2127871ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2132095ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2136929ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2141041ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2145649ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2149001ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2154009ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2160289ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2163045ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2165703ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2170435ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2174533ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2180602ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2183970ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2188449ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2193432ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2199108ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2204514ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2207782ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2211154ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2215151ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2220369ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2225592ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2231073ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2235170ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2240112ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2244580ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2247102ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2250935ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2255955ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2258852ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2262219ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2264998ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2267798ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2270679ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2274693ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2279141ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2282490ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2286691ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2289394ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2292786ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2296212ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2300543ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2305529ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2308432ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2311316ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2314048ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2316693ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2322528ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2324032ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2325535ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2327037ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2328542ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2330047ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2331551ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2333060ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2334577ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2336108ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2337661ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2339261ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2340987ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2342639ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2345062ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2348366ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2353317ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2355970ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2359594ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2364295ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2367025ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2371664ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2377695ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2381580ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2386975ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2390940ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2394713ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2401025ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2405701ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2411823ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2415444ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2420374ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2423205ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2427036ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2430201ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2436228ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2438745ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2444585ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2448007ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2454240ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2458605ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2464638ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2470000ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2473175ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2477001ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2479825ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2484531ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2488429ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2492443ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2496478ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2501547ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2507275ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2510246ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2515481ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2521325ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2525597ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2530079ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2535097ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2540374ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2542949ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2548608ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2551606ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2556970ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2561263ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2565704ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2572096ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2575748ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2582140ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2585099ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2590689ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2594429ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2597097ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2602443ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2607934ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2614368ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2620818ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2624934ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2628080ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2632012ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2637006ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2642781ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2646257ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2652129ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2657111ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2660939ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2664222ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2669288ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2673049ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2676641ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2681975ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2687399ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2691143ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2696611ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2703022ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2708508ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2714883ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2717965ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2722863ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2728592ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2733433ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2736887ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2742050ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2747152ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2750961ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2755709ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2758387ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2763234ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2769308ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2773944ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2779439ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2785326ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2789150ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2794479ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2798015ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2801733ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2807469ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2812759ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2816189ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2819131ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2822274ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2828181ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2830727ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2835268ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2839885ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2844976ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2848223ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2852362ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2857536ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2860326ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2865597ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2870360ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2874396ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2879603ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2882989ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2887738ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2893278ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2897898ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2903133ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2907693ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2911511ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2914480ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2917693ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2921511ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2925378ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2929156ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2935224ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2938411ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2941024ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2945187ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2951569ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2956360ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2961798ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2965727ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2970053ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2974647ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2979076ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2981619ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2987413ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2993916ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 2998753ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3001903ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3006772ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3011205ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3014554ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3020716ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3023620ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3026157ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3029519ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3035750ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3039670ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3042900ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3044406ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3045914ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3047418ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3048922ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3050430ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3051939ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3053445ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3054967ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3056494ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3058030ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3059628ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3061317ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3063423ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3066066ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3068474ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3074611ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3077389ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3082564ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3087158ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3092042ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3095006ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3098000ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3103792ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3108176ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3113108ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3119057ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3124557ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3128114ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3133142ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3138219ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3142613ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3148283ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3151899ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3158316ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3162178ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3168249ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3173905ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3176488ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3181480ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3186837ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3191469ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3194980ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3197653ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3201336ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3203881ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3206942ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3211591ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3215373ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3218728ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3225017ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3228703ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3232200ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3237448ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3242351ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3247124ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3252066ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3255098ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3259315ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3262478ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3266693ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3270494ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3273054ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3277894ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3282605ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3288518ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3293125ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3296507ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3300670ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3304649ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3308506ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3311481ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3315602ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3320942ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3326992ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3333216ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3337256ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3341453ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3347555ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3354038ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3356888ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3362528ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3366751ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3369538ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3373007ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3375695ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3381660ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3384842ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3388825ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3392144ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3398278ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3402530ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3408098ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3411990ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3415196ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3418524ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3422228ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3428353ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3433802ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3438650ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3444440ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3449911ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3452569ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3458996ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3462459ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3467357ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3472061ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3474872ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3478920ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3483514ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3488504ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3491057ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3493906ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3496871ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3500059ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3502727ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3505903ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3510467ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3515876ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3521311ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3525950ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3530738ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3535015ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3540198ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3544208ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3549195ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3552985ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3557174ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3563243ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3567252ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3572021ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3575643ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3579788ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3582447ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3585466ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3591751ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3598168ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3604102ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3607947ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3610538ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3616706ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3620289ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3623721ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3627180ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3632796ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3638073ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3640758ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3646904ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3651797ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3656013ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3662055ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3666118ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3670932ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3674363ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3678373ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3680890ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3686407ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3691838ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3695096ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3698225ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3702845ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3707325ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3712438ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3716578ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3722898ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3728045ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3731225ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3734886ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3739139ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3745096ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3748311ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3751855ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3757292ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3761803ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3765291ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3768150ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3773562ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3777280ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3783067ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3788040ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3793912ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3797201ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3801405ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3807099ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3810442ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3816380ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3819171ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3824260ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3829688ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3833018ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3838405ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3844117ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
[ 3849133ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-CAp618mF.js:1
|
||||
@@ -1,111 +0,0 @@
|
||||
[ 42371ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 43886ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 45394ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 46919ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 48431ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 49959ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 51481ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 53015ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 54540ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 56106ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 57655ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 59243ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 60824ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 62373ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 64118ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 65819ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 67479ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 69533ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 71254ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 73239ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 75156ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 77567ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 79344ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 82250ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 84565ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 87132ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 89921ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 93142ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 98107ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 104584ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 109315ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 115771ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 119994ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 123085ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 127882ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 132038ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 136193ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 139900ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 145744ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 149772ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 155655ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 161972ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 165111ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 168591ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 173742ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 177546ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 181369ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 185903ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 192162ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 196171ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 200493ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 205354ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 211752ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 215768ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 222137ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 226759ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 229986ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 233330ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 239355ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 241945ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 246266ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 249470ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 252456ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 256007ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 259678ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 263588ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 265091ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 266596ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 268100ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 269607ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 271116ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 272631ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 274158ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 275679ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 277195ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 278748ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 280315ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 282015ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 283816ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 286032ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 289050ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 294863ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 299002ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 304415ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 309592ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 313676ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 319577ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 324707ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 331144ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 334534ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 340368ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 344144ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 348860ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 353197ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 357820ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 363134ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 368501ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 374774ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 377875ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 383036ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 386527ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 389849ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 393039ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 399322ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 404697ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 410152ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 413233ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 417776ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 422157ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 426743ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
[ 432337ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-BOw6MkX3.js:1
|
||||
@@ -1,429 +0,0 @@
|
||||
[ 35054ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 39723ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 44598ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 47198ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 49750ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 53719ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 56428ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 61648ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 63162ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 64675ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 66195ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 67706ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 69227ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 70755ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 72291ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 73837ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 75385ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 76960ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 78534ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 80074ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 81618ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 83252ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 84885ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 86634ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 88437ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 90326ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 92416ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 94536ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 97180ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 99575ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 101437ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 104134ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 108046ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 110554ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 114812ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 120862ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 123580ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 130010ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 134170ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 137430ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 140113ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 145273ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 148065ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 153804ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 157723ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 161864ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 166915ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 173017ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 175633ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 178990ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 184171ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 187217ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 190181ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 196101ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 198894ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 202277ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 205792ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 209887ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 215804ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 219229ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 225167ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 231226ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 234198ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 237455ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 242784ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 246994ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 251485ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 256755ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 260660ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 265940ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 271286ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 273814ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 280244ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 283009ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 287095ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 291512ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 295679ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 298956ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 302484ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 306317ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 309708ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 314305ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 318189ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 321592ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 325611ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 331050ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 334034ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 339965ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 346034ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 351487ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 354694ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 357326ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 361177ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 367484ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 371295ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 375303ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 380341ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 384829ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 387824ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 393096ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 397852ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 402971ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 409360ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 415831ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 419239ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 422671ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 427291ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 432417ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 435014ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 438621ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 442682ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 448014ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 453011ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 458610ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 463117ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 465647ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 472001ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 477628ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 483262ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 487618ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 494014ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 497698ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 502277ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 508131ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 512554ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 516162ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 519192ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 525023ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 530401ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 536323ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 542138ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 543642ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 545148ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 546664ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 548173ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 549687ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 551193ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 552706ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 554234ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 555769ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 557346ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 558933ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 560699ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 562433ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 564351ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 566850ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 571504ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 576704ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 580031ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 586469ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 591484ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 597562ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 601328ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 604230ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 610716ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 614756ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 619191ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 622632ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 628757ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 633165ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 635772ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 641787ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 646319ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 650540ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 653919ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 659958ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 663089ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 664597ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 666107ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 667620ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 669125ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 670630ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 672135ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 673660ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 675188ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 676720ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 678303ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 679929ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 681713ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 683638ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 686042ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 688483ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 694213ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 700120ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 705030ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 708102ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 713737ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 718257ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 723483ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 726575ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 731009ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 733615ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 739850ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 743296ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 747591ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 750935ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 753792ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 759827ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 765846ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 770080ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 776003ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 781143ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 785813ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 790908ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 794723ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 799978ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 802566ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 808697ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 812967ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 817030ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 820028ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 826526ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 829216ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 833505ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 838637ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 843812ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 849871ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 854886ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 860741ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 865567ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 869130ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 874426ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 880608ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 885176ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 888150ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 891310ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 894480ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 899982ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 904792ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 908807ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 914072ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 916853ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 920114ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 925647ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 930995ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 934357ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 937913ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 941634ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 947338ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 950320ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 954153ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 957484ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 961665ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 965207ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 968046ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 971084ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 973824ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 980166ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 984179ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 989191ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 995232ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 997946ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1001234ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1006913ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1011516ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1014303ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1018041ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1021328ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1026098ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1030726ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1035086ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1041304ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1044467ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1049226ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1052558ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1058154ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1061028ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1065787ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1071637ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1075522ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1080951ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1085930ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1088820ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1092037ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1098390ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1102678ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1105217ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1109419ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1115559ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1121996ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1126779ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1132972ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1137004ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1140326ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1144869ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1150935ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1153701ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1157899ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1164235ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1169866ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1175925ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1182032ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1185270ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1190429ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1194642ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1197213ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1202483ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1205053ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1211337ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1217603ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1222257ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1228017ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1230586ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1234756ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1241044ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1246986ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1250672ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1253955ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1257042ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1262105ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1267671ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1272574ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1275340ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1279286ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1285505ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1291182ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1297631ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1301928ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1305765ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1308479ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1312882ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1318669ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1322416ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1327478ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1331288ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1335858ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1339718ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1343574ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1346446ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1352867ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1358790ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1363759ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1366710ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1370961ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1376653ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1379396ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1383377ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1384881ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1386390ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1387895ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1389407ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1390917ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1392426ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1393937ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1395459ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1396995ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1398541ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1400159ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1401910ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1403957ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1405787ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1408494ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1411369ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1414797ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1421173ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1424677ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1429773ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1432811ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1436872ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1439648ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1444751ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1448652ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1453645ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1459299ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1465442ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1468615ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1473754ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1477523ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1481404ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1484988ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1487873ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1491214ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1497291ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1500003ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1505529ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1508113ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1514157ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1520490ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1526105ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1530847ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1534309ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1536942ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1540226ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1544946ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1549964ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1556375ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1560217ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1565790ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1571967ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1577594ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1584020ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1588841ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1594870ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1599656ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1604363ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1607346ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1610702ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1616755ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1623158ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1628550ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1632054ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1634779ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1637945ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1643501ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1648496ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1654167ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1657851ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1661856ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1666697ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1670130ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1674976ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1679260ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1683713ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1688808ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1691522ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1695744ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1700477ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1703591ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1709022ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1711953ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1715990ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1718918ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1724646ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1727912ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1730598ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1736344ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1742739ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1748352ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
[ 1753260ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-Di4XAJUy.js:1
|
||||
@@ -1,377 +0,0 @@
|
||||
[ 29344ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 30899ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 32561ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 34184ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 35928ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 37715ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 39631ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 41322ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 43033ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 45784ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 47804ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 49866ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 53009ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 56409ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 59363ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 63719ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 66762ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 70350ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 76689ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 81421ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 86291ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 89108ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 94293ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 97541ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 103020ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 107616ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 109193ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 110784ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 112404ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 114032ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 115694ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 117378ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 119185ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 120846ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 122568ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 124665ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 126643ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 128678ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 131022ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 132789ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 135871ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 138712ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 141776ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 144631ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 149520ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 154737ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 157644ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 163732ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 169477ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 174008ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 178040ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 184181ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 190486ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 193749ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 199856ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 203003ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 206637ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 210167ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 215950ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 221046ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 225043ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 229602ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 232212ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 235783ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 240726ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 243562ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 246869ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 251933ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 256811ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 262875ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 268069ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 274279ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 277187ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 281386ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 287570ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 292533ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 297630ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 300789ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 306371ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 309321ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 313317ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 318531ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 325018ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 329131ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 334398ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 339026ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 345304ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 348984ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 354153ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 360602ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 367042ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 371403ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 374946ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 378537ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 384543ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 389557ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 395542ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 399198ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 405437ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 409320ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 414671ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 418122ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 422762ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 428522ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 434933ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 440494ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 444233ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 450393ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 456150ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 461178ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 466151ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 470131ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 474193ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 479280ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 485693ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 488787ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 491348ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 495642ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 499529ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 504086ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 507420ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 510475ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 513984ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 517094ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 520899ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 525963ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 532473ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 538010ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 541731ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 546731ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 552391ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 556687ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 561523ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 566456ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 571832ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 576666ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 580876ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 586166ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 591690ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 595601ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 598801ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 604138ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 610022ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 613113ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 617769ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 622903ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 629006ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 634764ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 639842ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 646351ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 651246ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 656927ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 663128ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 666172ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 672227ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 674779ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 680821ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 683499ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 687108ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 693288ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 699344ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 705710ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 710719ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 713304ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 718987ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 723791ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 726724ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 731497ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 734625ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 737301ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 742213ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 748167ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 752333ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 757603ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 762855ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 767730ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 770446ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 775325ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 779214ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 784258ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 789404ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 794365ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 800712ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 806259ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 809002ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 814602ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 820169ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 826159ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 830500ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 835718ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 841998ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 845761ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 849917ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 853357ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 857404ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 861368ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 866163ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 870000ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 875043ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 877705ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 880875ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 883697ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 888642ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 894438ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 897790ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 902219ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 907725ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 912450ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 917475ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 920695ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 923237ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 929062ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 933057ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 939436ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 945047ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 947650ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 950261ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 956750ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 961470ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 967049ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 972248ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 978206ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 982605ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 986752ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 990762ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 995100ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 999238ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1003392ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1006862ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1013152ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1018404ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1024738ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1030411ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1034332ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1039879ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1043544ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1049905ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1054006ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1058765ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1064114ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1065622ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1067130ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1068637ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1070143ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1071649ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1073158ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1074670ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1076191ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1077716ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1079301ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1080856ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1082621ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1084390ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1086608ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1089809ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1095268ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1099245ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1101821ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1107303ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1111821ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1116150ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1120447ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1125107ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1128193ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1134639ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1138321ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1143884ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1149537ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1154196ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1157467ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1163215ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1168420ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1172928ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1176457ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1181365ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1184980ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1186483ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1187988ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1189492ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1190996ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1192501ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1194010ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1195522ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1197039ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1198572ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1200103ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1201728ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1203407ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1205221ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1207434ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1209600ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1216044ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1219574ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1222415ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1226555ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1230085ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1235975ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1241444ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1247150ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1251140ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1255615ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1259285ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1261836ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1268334ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1274384ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1280093ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1285751ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1288962ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1292148ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1296126ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1299244ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1303124ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1308863ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1311614ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1315668ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1321312ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1325255ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1328741ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1334807ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1338738ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1342898ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1347527ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1351693ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1357640ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1360630ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1365117ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1370383ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1375202ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1378488ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1383416ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1388071ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1391775ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1395068ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1401362ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1405927ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1409973ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1415788ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1419993ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1422568ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1427897ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1431247ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1436017ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1440676ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1444279ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1447985ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1453812ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1459007ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1464539ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1469651ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1472486ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1478828ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1483427ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1488790ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1492253ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1496471ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1500655ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1504766ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1507334ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1513726ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1517718ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1520603ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1523915ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1529894ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1535783ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1539666ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1543362ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1546661ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1550202ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1553917ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1559517ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1562654ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1566220ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1570798ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1573997ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1577376ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1583494ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
[ 1588863ms] [ERROR] WebSocket connection to 'ws://127.0.0.1:8899/ws' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ http://127.0.0.1:8899/assets/index-C9p8jmUs.js:1
|
||||
@@ -1,4 +0,0 @@
|
||||
- generic [ref=e2]:
|
||||
- heading "Wiz-War" [level=1] [ref=e4]
|
||||
- generic [ref=e5]: A game of magical combat in a stone labyrinth
|
||||
- generic [ref=e13]: the classic 1993 edition · faithfully reproduced · play free with friends
|
||||
@@ -1,34 +0,0 @@
|
||||
- generic [ref=e3]:
|
||||
- banner [ref=e4]:
|
||||
- generic [ref=e5]: Wiz-War
|
||||
- generic [ref=e6]: sixth edition
|
||||
- button "help & rules" [ref=e7] [cursor=pointer]
|
||||
- generic [ref=e9]:
|
||||
- generic [ref=e10]: Wiz-War
|
||||
- generic [ref=e11]: A game of magical combat in a stone labyrinth
|
||||
- button "about this game — a labor of love" [ref=e12] [cursor=pointer]
|
||||
- generic [ref=e13]:
|
||||
- generic [ref=e14]: Your wizard's name
|
||||
- textbox "Your wizard's name" [ref=e15]:
|
||||
- /placeholder: e.g. Mordecai
|
||||
- generic [ref=e16]:
|
||||
- button "Create a game" [disabled] [ref=e17]
|
||||
- generic [ref=e18]: or join one
|
||||
- textbox "CODE" [ref=e19]
|
||||
- button "Join" [disabled] [ref=e20]
|
||||
- generic [ref=e21]:
|
||||
- generic [ref=e22]: "or play here, passing the device:"
|
||||
- group "number of wizards" [ref=e23]:
|
||||
- button "2" [ref=e24] [cursor=pointer]
|
||||
- button "3" [ref=e25] [cursor=pointer]
|
||||
- button "4" [ref=e26] [cursor=pointer]
|
||||
- button "5" [ref=e27] [cursor=pointer]
|
||||
- button "6" [ref=e28] [cursor=pointer]
|
||||
- button "Gather 2 wizards" [ref=e29] [cursor=pointer]
|
||||
- generic [ref=e30]:
|
||||
- 'checkbox "with Expansion Set #1" [checked] [ref=e31]'
|
||||
- text: "with Expansion Set #1"
|
||||
- generic [ref=e32]:
|
||||
- textbox "seat transfer phrase" [ref=e33]:
|
||||
- /placeholder: ember-troll-dagger
|
||||
- button "Claim a transferred seat" [disabled] [ref=e34]
|
||||
@@ -1,44 +0,0 @@
|
||||
- generic [ref=f1e3]:
|
||||
- banner [ref=f1e4]:
|
||||
- generic [ref=f1e5]: Wiz-War
|
||||
- generic [ref=f1e6]: sixth edition
|
||||
- button "help & rules" [ref=f1e7] [cursor=pointer]
|
||||
- alert [ref=f1e44]: no such room
|
||||
- generic [ref=f1e9]:
|
||||
- generic [ref=f1e10]: Wiz-War
|
||||
- generic [ref=f1e11]: A game of magical combat in a stone labyrinth
|
||||
- button "about this game — a labor of love" [ref=f1e12] [cursor=pointer]
|
||||
- generic [ref=f1e13]:
|
||||
- generic [ref=f1e14]: Your wizard's name
|
||||
- textbox "Your wizard's name" [ref=f1e15]:
|
||||
- /placeholder: e.g. Mordecai
|
||||
- generic [ref=f1e16]:
|
||||
- button "Create a game" [disabled] [ref=f1e17]
|
||||
- generic [ref=f1e18]: or join one
|
||||
- textbox "CODE" [ref=f1e19]
|
||||
- button "Join" [disabled] [ref=f1e20]
|
||||
- generic [ref=f1e21]:
|
||||
- generic [ref=f1e22]: "or play here, passing the device:"
|
||||
- group "number of wizards" [ref=f1e23]:
|
||||
- button "2" [ref=f1e24] [cursor=pointer]
|
||||
- button "3" [ref=f1e25] [cursor=pointer]
|
||||
- button "4" [ref=f1e26] [cursor=pointer]
|
||||
- button "5" [ref=f1e27] [cursor=pointer]
|
||||
- button "6" [ref=f1e28] [cursor=pointer]
|
||||
- button "Gather 2 wizards" [ref=f1e29] [cursor=pointer]
|
||||
- generic [ref=f1e30]:
|
||||
- 'checkbox "with Expansion Set #1" [checked] [ref=f1e31]'
|
||||
- text: "with Expansion Set #1"
|
||||
- generic [ref=f1e32]:
|
||||
- textbox "seat transfer phrase" [ref=f1e33]:
|
||||
- /placeholder: ember-troll-dagger
|
||||
- button "Claim a transferred seat" [disabled] [ref=f1e34]
|
||||
- generic [ref=f1e35]:
|
||||
- generic [ref=f1e36]:
|
||||
- generic [ref=f1e37]: your games
|
||||
- button "notify me on my turn" [ref=f1e38] [cursor=pointer]
|
||||
- generic [ref=f1e39]:
|
||||
- button "R9E8 as alice — unreachable" [active] [ref=f1e40] [cursor=pointer]:
|
||||
- generic [ref=f1e41]: R9E8
|
||||
- generic [ref=f1e42]: as alice — unreachable
|
||||
- button "×" [ref=f1e43] [cursor=pointer]
|
||||
@@ -1,34 +0,0 @@
|
||||
- generic [ref=f2e3]:
|
||||
- banner [ref=f2e4]:
|
||||
- generic [ref=f2e5]: Wiz-War
|
||||
- generic [ref=f2e6]: sixth edition
|
||||
- button "help & rules" [ref=f2e7] [cursor=pointer]
|
||||
- generic [ref=f2e9]:
|
||||
- generic [ref=f2e10]: Wiz-War
|
||||
- generic [ref=f2e11]: A game of magical combat in a stone labyrinth
|
||||
- button "about this game — a labor of love" [ref=f2e12] [cursor=pointer]
|
||||
- generic [ref=f2e13]:
|
||||
- generic [ref=f2e14]: Your wizard's name
|
||||
- textbox "Your wizard's name" [ref=f2e15]:
|
||||
- /placeholder: e.g. Mordecai
|
||||
- generic [ref=f2e16]:
|
||||
- button "Create a game" [disabled] [ref=f2e17]
|
||||
- generic [ref=f2e18]: or join one
|
||||
- textbox "CODE" [ref=f2e19]
|
||||
- button "Join" [disabled] [ref=f2e20]
|
||||
- generic [ref=f2e21]:
|
||||
- generic [ref=f2e22]: "or play here, passing the device:"
|
||||
- group "number of wizards" [ref=f2e23]:
|
||||
- button "2" [ref=f2e24] [cursor=pointer]
|
||||
- button "3" [ref=f2e25] [cursor=pointer]
|
||||
- button "4" [ref=f2e26] [cursor=pointer]
|
||||
- button "5" [ref=f2e27] [cursor=pointer]
|
||||
- button "6" [ref=f2e28] [cursor=pointer]
|
||||
- button "Gather 2 wizards" [ref=f2e29] [cursor=pointer]
|
||||
- generic [ref=f2e30]:
|
||||
- 'checkbox "with Expansion Set #1" [checked] [ref=f2e31]'
|
||||
- text: "with Expansion Set #1"
|
||||
- generic [ref=f2e32]:
|
||||
- textbox "seat transfer phrase" [ref=f2e33]:
|
||||
- /placeholder: ember-troll-dagger
|
||||
- button "Claim a transferred seat" [disabled] [ref=f2e34]
|
||||
@@ -1,43 +0,0 @@
|
||||
- generic [ref=f4e3]:
|
||||
- banner [ref=f4e4]:
|
||||
- generic [ref=f4e5]: Wiz-War
|
||||
- generic [ref=f4e6]: sixth edition
|
||||
- button "help & rules" [ref=f4e7] [cursor=pointer]
|
||||
- generic [ref=f4e9]:
|
||||
- generic [ref=f4e10]: Wiz-War
|
||||
- generic [ref=f4e11]: A game of magical combat in a stone labyrinth
|
||||
- button "about this game — a labor of love" [ref=f4e12] [cursor=pointer]
|
||||
- generic [ref=f4e13]:
|
||||
- generic [ref=f4e14]: Your wizard's name
|
||||
- textbox "Your wizard's name" [ref=f4e15]:
|
||||
- /placeholder: e.g. Mordecai
|
||||
- generic [ref=f4e16]:
|
||||
- button "Create a game" [disabled] [ref=f4e17]
|
||||
- generic [ref=f4e18]: or join one
|
||||
- textbox "CODE" [ref=f4e19]
|
||||
- button "Join" [disabled] [ref=f4e20]
|
||||
- generic [ref=f4e21]:
|
||||
- generic [ref=f4e22]: "or play here, passing the device:"
|
||||
- group "number of wizards" [ref=f4e23]:
|
||||
- button "2" [ref=f4e24] [cursor=pointer]
|
||||
- button "3" [ref=f4e25] [cursor=pointer]
|
||||
- button "4" [ref=f4e26] [cursor=pointer]
|
||||
- button "5" [ref=f4e27] [cursor=pointer]
|
||||
- button "6" [ref=f4e28] [cursor=pointer]
|
||||
- button "Gather 2 wizards" [ref=f4e29] [cursor=pointer]
|
||||
- generic [ref=f4e30]:
|
||||
- 'checkbox "with Expansion Set #1" [checked] [ref=f4e31]'
|
||||
- text: "with Expansion Set #1"
|
||||
- generic [ref=f4e32]:
|
||||
- textbox "seat transfer phrase" [ref=f4e33]:
|
||||
- /placeholder: ember-troll-dagger
|
||||
- button "Claim a transferred seat" [disabled] [ref=f4e34]
|
||||
- generic [ref=f4e35]:
|
||||
- generic [ref=f4e36]:
|
||||
- generic [ref=f4e37]: your games
|
||||
- button "notify me on my turn" [ref=f4e38] [cursor=pointer]
|
||||
- generic [ref=f4e39]:
|
||||
- button "R9E8 as alice — unreachable" [ref=f4e40] [cursor=pointer]:
|
||||
- generic [ref=f4e41]: R9E8
|
||||
- generic [ref=f4e42]: as alice — unreachable
|
||||
- button "×" [ref=f4e43] [cursor=pointer]
|
||||
@@ -1,34 +0,0 @@
|
||||
- generic [ref=f5e3]:
|
||||
- banner [ref=f5e4]:
|
||||
- generic [ref=f5e5]: Wiz-War
|
||||
- generic [ref=f5e6]: sixth edition
|
||||
- button "help & rules" [ref=f5e7] [cursor=pointer]
|
||||
- generic [ref=f5e9]:
|
||||
- generic [ref=f5e10]: Wiz-War
|
||||
- generic [ref=f5e11]: A game of magical combat in a stone labyrinth
|
||||
- button "about this game — a labor of love" [ref=f5e12] [cursor=pointer]
|
||||
- generic [ref=f5e13]:
|
||||
- generic [ref=f5e14]: Your wizard's name
|
||||
- textbox "Your wizard's name" [ref=f5e15]:
|
||||
- /placeholder: e.g. Mordecai
|
||||
- generic [ref=f5e16]:
|
||||
- button "Create a game" [disabled] [ref=f5e17]
|
||||
- generic [ref=f5e18]: or join one
|
||||
- textbox "CODE" [ref=f5e19]
|
||||
- button "Join" [disabled] [ref=f5e20]
|
||||
- generic [ref=f5e21]:
|
||||
- generic [ref=f5e22]: "or play here, passing the device:"
|
||||
- group "number of wizards" [ref=f5e23]:
|
||||
- button "2" [ref=f5e24] [cursor=pointer]
|
||||
- button "3" [ref=f5e25] [cursor=pointer]
|
||||
- button "4" [ref=f5e26] [cursor=pointer]
|
||||
- button "5" [ref=f5e27] [cursor=pointer]
|
||||
- button "6" [ref=f5e28] [cursor=pointer]
|
||||
- button "Gather 2 wizards" [ref=f5e29] [cursor=pointer]
|
||||
- generic [ref=f5e30]:
|
||||
- 'checkbox "with Expansion Set #1" [checked] [ref=f5e31]'
|
||||
- text: "with Expansion Set #1"
|
||||
- generic [ref=f5e32]:
|
||||
- textbox "seat transfer phrase" [ref=f5e33]:
|
||||
- /placeholder: ember-troll-dagger
|
||||
- button "Claim a transferred seat" [disabled] [ref=f5e34]
|
||||
@@ -1,289 +0,0 @@
|
||||
- generic [ref=f6e3]:
|
||||
- banner [ref=f6e4]:
|
||||
- generic [ref=f6e5]: Wiz-War
|
||||
- generic [ref=f6e6]: sixth edition
|
||||
- generic [ref=f6e7]: room R9E8
|
||||
- button "transfer seat" [ref=f6e8] [cursor=pointer]
|
||||
- button "leave table" [ref=f6e9] [cursor=pointer]
|
||||
- button "help & rules" [ref=f6e10] [cursor=pointer]
|
||||
- alertdialog "the game is won" [ref=f6e11]:
|
||||
- generic [ref=f6e12]:
|
||||
- generic [ref=f6e13]: 🏆
|
||||
- generic [ref=f6e14]: alice
|
||||
- generic [ref=f6e15]: the last wizard standing
|
||||
- button "Behold the final board" [ref=f6e16] [cursor=pointer]
|
||||
- generic [ref=f6e17]:
|
||||
- img [ref=f6e19]:
|
||||
- button [ref=f6e20] [cursor=pointer]
|
||||
- button [ref=f6e21] [cursor=pointer]
|
||||
- button [ref=f6e22] [cursor=pointer]
|
||||
- button [ref=f6e23] [cursor=pointer]
|
||||
- button [ref=f6e24] [cursor=pointer]
|
||||
- button [ref=f6e25] [cursor=pointer]
|
||||
- button [ref=f6e26] [cursor=pointer]
|
||||
- button [ref=f6e27] [cursor=pointer]
|
||||
- button [ref=f6e28] [cursor=pointer]
|
||||
- button [ref=f6e29] [cursor=pointer]
|
||||
- button [ref=f6e30] [cursor=pointer]
|
||||
- button [ref=f6e31] [cursor=pointer]
|
||||
- button [ref=f6e32] [cursor=pointer]
|
||||
- button [ref=f6e33] [cursor=pointer]
|
||||
- button [ref=f6e34] [cursor=pointer]
|
||||
- button [ref=f6e35] [cursor=pointer]
|
||||
- button [ref=f6e36] [cursor=pointer]
|
||||
- button [ref=f6e37] [cursor=pointer]
|
||||
- button [ref=f6e38] [cursor=pointer]
|
||||
- button [ref=f6e39] [cursor=pointer]
|
||||
- button [ref=f6e40] [cursor=pointer]
|
||||
- button [ref=f6e41] [cursor=pointer]
|
||||
- button [ref=f6e42] [cursor=pointer]
|
||||
- button [ref=f6e43] [cursor=pointer]
|
||||
- button [ref=f6e44] [cursor=pointer]
|
||||
- button [ref=f6e45] [cursor=pointer]
|
||||
- button [ref=f6e46] [cursor=pointer]
|
||||
- button [ref=f6e47] [cursor=pointer]
|
||||
- button [ref=f6e48] [cursor=pointer]
|
||||
- button [ref=f6e49] [cursor=pointer]
|
||||
- button [ref=f6e50] [cursor=pointer]
|
||||
- button [ref=f6e51] [cursor=pointer]
|
||||
- button [ref=f6e52] [cursor=pointer]
|
||||
- button [ref=f6e53] [cursor=pointer]
|
||||
- button [ref=f6e54] [cursor=pointer]
|
||||
- button [ref=f6e55] [cursor=pointer]
|
||||
- button [ref=f6e56] [cursor=pointer]
|
||||
- button [ref=f6e57] [cursor=pointer]
|
||||
- button [ref=f6e58] [cursor=pointer]
|
||||
- button [ref=f6e59] [cursor=pointer]
|
||||
- button [ref=f6e60] [cursor=pointer]
|
||||
- button [ref=f6e61] [cursor=pointer]
|
||||
- button [ref=f6e62] [cursor=pointer]
|
||||
- button [ref=f6e63] [cursor=pointer]
|
||||
- button [ref=f6e64] [cursor=pointer]
|
||||
- button [ref=f6e65] [cursor=pointer]
|
||||
- button [ref=f6e66] [cursor=pointer]
|
||||
- button [ref=f6e67] [cursor=pointer]
|
||||
- button [ref=f6e68] [cursor=pointer]
|
||||
- button [ref=f6e69] [cursor=pointer]
|
||||
- button "↑ A" [ref=f6e131] [cursor=pointer]:
|
||||
- generic: ↑
|
||||
- generic: A
|
||||
- button "↓ A" [ref=f6e133] [cursor=pointer]:
|
||||
- generic: ↓
|
||||
- generic: A
|
||||
- button "← B" [ref=f6e135] [cursor=pointer]:
|
||||
- generic: ←
|
||||
- generic: B
|
||||
- button "→ B" [ref=f6e137] [cursor=pointer]:
|
||||
- generic: →
|
||||
- generic: B
|
||||
- button "→ C" [ref=f6e139] [cursor=pointer]:
|
||||
- generic: →
|
||||
- generic: C
|
||||
- button "← C" [ref=f6e141] [cursor=pointer]:
|
||||
- generic: ←
|
||||
- generic: C
|
||||
- button [ref=f6e143] [cursor=pointer]
|
||||
- complementary [ref=f6e145]:
|
||||
- generic [ref=f6e146]:
|
||||
- text: You missed 94 moves.
|
||||
- button "▶ Watch what happened" [ref=f6e147] [cursor=pointer]
|
||||
- button "skip" [ref=f6e148] [cursor=pointer]
|
||||
- generic [ref=f6e149]: 🏆 alice wins!
|
||||
- generic [ref=f6e150]:
|
||||
- generic [ref=f6e151]: life-points
|
||||
- generic [ref=f6e152]:
|
||||
- generic [ref=f6e154]: alice (you)
|
||||
- generic [ref=f6e155]: "1"
|
||||
- generic [ref=f6e156]: 14 cards
|
||||
- generic [ref=f6e157]:
|
||||
- generic [ref=f6e159]: bob
|
||||
- generic [ref=f6e160]: "0"
|
||||
- generic [ref=f6e161]: 0 cards
|
||||
- generic [ref=f6e162]:
|
||||
- text: draw pile 111 ·
|
||||
- button "discards 0" [ref=f6e163] [cursor=pointer]
|
||||
- generic "game log" [ref=f6e164]:
|
||||
- generic [ref=f6e165]: — alice's turn (round 7) —
|
||||
- generic [ref=f6e166]: alice punches bob!
|
||||
- generic [ref=f6e167]: bob takes 1 damage (punch from alice) — 9 life left.
|
||||
- generic [ref=f6e168]: — bob's turn (round 8) —
|
||||
- generic [ref=f6e169]: bob punches alice!
|
||||
- generic [ref=f6e170]: alice takes 1 damage (punch from bob) — 9 life left.
|
||||
- generic [ref=f6e171]: — alice's turn (round 8) —
|
||||
- generic [ref=f6e172]: alice punches bob!
|
||||
- generic [ref=f6e173]: bob takes 1 damage (punch from alice) — 8 life left.
|
||||
- generic [ref=f6e174]: — bob's turn (round 9) —
|
||||
- generic [ref=f6e175]: bob punches alice!
|
||||
- generic [ref=f6e176]: alice takes 1 damage (punch from bob) — 8 life left.
|
||||
- generic [ref=f6e177]: — alice's turn (round 9) —
|
||||
- generic [ref=f6e178]: alice punches bob!
|
||||
- generic [ref=f6e179]: bob takes 1 damage (punch from alice) — 7 life left.
|
||||
- generic [ref=f6e180]: — bob's turn (round 10) —
|
||||
- generic [ref=f6e181]: bob punches alice!
|
||||
- generic [ref=f6e182]: alice takes 1 damage (punch from bob) — 7 life left.
|
||||
- generic [ref=f6e183]: — alice's turn (round 10) —
|
||||
- generic [ref=f6e184]: alice punches bob!
|
||||
- generic [ref=f6e185]: bob takes 1 damage (punch from alice) — 6 life left.
|
||||
- generic [ref=f6e186]: — bob's turn (round 11) —
|
||||
- generic [ref=f6e187]: bob punches alice!
|
||||
- generic [ref=f6e188]: alice takes 1 damage (punch from bob) — 6 life left.
|
||||
- generic [ref=f6e189]: — alice's turn (round 11) —
|
||||
- generic [ref=f6e190]: alice punches bob!
|
||||
- generic [ref=f6e191]: bob takes 1 damage (punch from alice) — 5 life left.
|
||||
- generic [ref=f6e192]: — bob's turn (round 12) —
|
||||
- generic [ref=f6e193]: bob punches alice!
|
||||
- generic [ref=f6e194]: alice takes 1 damage (punch from bob) — 5 life left.
|
||||
- generic [ref=f6e195]: — alice's turn (round 12) —
|
||||
- generic [ref=f6e196]: alice punches bob!
|
||||
- generic [ref=f6e197]: bob takes 1 damage (punch from alice) — 4 life left.
|
||||
- generic [ref=f6e198]: — bob's turn (round 13) —
|
||||
- generic [ref=f6e199]: bob punches alice!
|
||||
- generic [ref=f6e200]: alice takes 1 damage (punch from bob) — 4 life left.
|
||||
- generic [ref=f6e201]: — alice's turn (round 13) —
|
||||
- generic [ref=f6e202]: alice punches bob!
|
||||
- generic [ref=f6e203]: bob takes 1 damage (punch from alice) — 3 life left.
|
||||
- generic [ref=f6e204]: — bob's turn (round 14) —
|
||||
- generic [ref=f6e205]: bob punches alice!
|
||||
- generic [ref=f6e206]: alice takes 1 damage (punch from bob) — 3 life left.
|
||||
- generic [ref=f6e207]: — alice's turn (round 14) —
|
||||
- generic [ref=f6e208]: alice punches bob!
|
||||
- generic [ref=f6e209]: bob takes 1 damage (punch from alice) — 2 life left.
|
||||
- generic [ref=f6e210]: — bob's turn (round 15) —
|
||||
- generic [ref=f6e211]: bob punches alice!
|
||||
- generic [ref=f6e212]: alice takes 1 damage (punch from bob) — 2 life left.
|
||||
- generic [ref=f6e213]: — alice's turn (round 15) —
|
||||
- generic [ref=f6e214]: alice punches bob!
|
||||
- generic [ref=f6e215]: bob takes 1 damage (punch from alice) — 1 life left.
|
||||
- generic [ref=f6e216]: — bob's turn (round 16) —
|
||||
- generic [ref=f6e217]: bob punches alice!
|
||||
- generic [ref=f6e218]: alice takes 1 damage (punch from bob) — 1 life left.
|
||||
- generic [ref=f6e219]: — alice's turn (round 16) —
|
||||
- generic [ref=f6e220]: alice punches bob!
|
||||
- generic [ref=f6e221]: bob takes 1 damage (punch from alice) — 0 life left.
|
||||
- generic [ref=f6e222]: ☠ bob is dead — killed by alice.
|
||||
- generic [ref=f6e223]: alice takes 7 cards from bob's body.
|
||||
- generic [ref=f6e224]: 🏆 alice WINS — last wizard standing!
|
||||
- generic [ref=f6e225]:
|
||||
- generic [ref=f6e226]: Hand over the limit — mark cards and discard.
|
||||
- generic [ref=f6e228]:
|
||||
- button "Pick up treasure" [disabled] [ref=f6e229]
|
||||
- button "Drop treasure" [disabled] [ref=f6e230]
|
||||
- button "Punch a wall…" [disabled] [ref=f6e231]
|
||||
- button "Discard cards…" [ref=f6e232] [cursor=pointer]
|
||||
- generic [ref=f6e233]:
|
||||
- text: draw
|
||||
- combobox "draw" [ref=f6e234]:
|
||||
- option "0"
|
||||
- option "1"
|
||||
- option "2" [selected]
|
||||
- button "End turn" [ref=f6e235] [cursor=pointer]
|
||||
- generic "all hands revealed" [ref=f6e236]:
|
||||
- generic [ref=f6e237]:
|
||||
- text: The hands, face-up
|
||||
- button "⟲ Watch the whole game" [ref=f6e238] [cursor=pointer]
|
||||
- generic [ref=f6e239]:
|
||||
- generic [ref=f6e240]: 🏆 alice
|
||||
- generic [ref=f6e241]:
|
||||
- button "NEUTRAL ADJACENT Pick Lock Unlock any door (but the door will relock behind you). Can only use when adjacent to door. You may \"hold the door open\" for others, if you wish. This is not a spell." [ref=f6e242] [cursor=pointer]:
|
||||
- generic [ref=f6e243]: NEUTRAL
|
||||
- generic [ref=f6e244]: ADJACENT
|
||||
- generic [ref=f6e245]: Pick Lock
|
||||
- generic [ref=f6e246]: Unlock any door (but the door will relock behind you). Can only use when adjacent to door. You may "hold the door open" for others, if you wish. This is not a spell.
|
||||
- button "NEUTRAL L.O.S. Remove Lock Permanently removes lock from any one door. Must be adjacent to door to use. Door is still considered to block L.O.S." [ref=f6e247] [cursor=pointer]:
|
||||
- generic [ref=f6e248]: NEUTRAL
|
||||
- generic [ref=f6e249]: L.O.S.
|
||||
- generic [ref=f6e250]: Remove Lock
|
||||
- generic [ref=f6e251]: Permanently removes lock from any one door. Must be adjacent to door to use. Door is still considered to block L.O.S.
|
||||
- button "ATTACK L.O.S. Fireball Does five points of magical damage and destroys all magical stones an opponent is carrying, if any of the points get through." [ref=f6e252] [cursor=pointer]:
|
||||
- generic [ref=f6e253]: ATTACK
|
||||
- generic [ref=f6e254]: L.O.S.
|
||||
- generic [ref=f6e255]: Fireball
|
||||
- generic [ref=f6e256]: Does five points of magical damage and destroys all magical stones an opponent is carrying, if any of the points get through.
|
||||
- button "ATTACK L.O.S. Power Drain Drain points from an opponent and add them to your own points. Amount equals NUMBER card played." [ref=f6e257] [cursor=pointer]:
|
||||
- generic [ref=f6e258]: ATTACK
|
||||
- generic [ref=f6e259]: L.O.S.
|
||||
- generic [ref=f6e260]: Power Drain
|
||||
- generic [ref=f6e261]: Drain points from an opponent and add them to your own points. Amount equals NUMBER card played.
|
||||
- button "COUNTERACTION Reflection A spell cast against you works 50% for both parties. Only works on point-based or duration-based spells. Round fractions up. A single lost turn, then, divided and rounded up, is a lost turn for both players." [ref=f6e262] [cursor=pointer]:
|
||||
- generic [ref=f6e263]: COUNTERACTION
|
||||
- generic [ref=f6e264]: Reflection
|
||||
- generic [ref=f6e265]: A spell cast against you works 50% for both parties. Only works on point-based or duration-based spells. Round fractions up. A single lost turn, then, divided and rounded up, is a lost turn for both players.
|
||||
- button "4 4 Wiz-War 4" [ref=f6e266] [cursor=pointer]:
|
||||
- generic [ref=f6e267]: "4"
|
||||
- generic [ref=f6e268]: "4"
|
||||
- generic [ref=f6e269]: Wiz-War
|
||||
- generic [ref=f6e270]: "4"
|
||||
- button "NEUTRAL/COUNTERACTION Reuse Spell You may retrieve any spell you use immediately after you use it (but not the NUMBER card, if used). You may reuse your retrieved spell immediately if you wish (except when it is an ATTACK)." [ref=f6e271] [cursor=pointer]:
|
||||
- generic [ref=f6e272]: NEUTRAL/COUNTERACTION
|
||||
- generic [ref=f6e273]: Reuse Spell
|
||||
- generic [ref=f6e274]: You may retrieve any spell you use immediately after you use it (but not the NUMBER card, if used). You may reuse your retrieved spell immediately if you wish (except when it is an ATTACK).
|
||||
- button "ATTACK L.O.S. Powerthrust A telekinetic blow that does magical damage equal to two points plus an (optional) accompanying NUMBER card." [ref=f6e275] [cursor=pointer]:
|
||||
- generic [ref=f6e276]: ATTACK
|
||||
- generic [ref=f6e277]: L.O.S.
|
||||
- generic [ref=f6e278]: Powerthrust
|
||||
- generic [ref=f6e279]: A telekinetic blow that does magical damage equal to two points plus an (optional) accompanying NUMBER card.
|
||||
- button "NEUTRAL Amplify Doubles spell power of one point-based or duration-based spell. Two AMPLIFY spells quadruple spell power when used together." [ref=f6e280] [cursor=pointer]:
|
||||
- generic [ref=f6e281]: NEUTRAL
|
||||
- generic [ref=f6e282]: Amplify
|
||||
- generic [ref=f6e283]: Doubles spell power of one point-based or duration-based spell. Two AMPLIFY spells quadruple spell power when used together.
|
||||
- button "ATTACK L.O.S. Sudden Death Does ten points of magical damage to any person or object." [ref=f6e284] [cursor=pointer]:
|
||||
- generic [ref=f6e285]: ATTACK
|
||||
- generic [ref=f6e286]: L.O.S.
|
||||
- generic [ref=f6e287]: Sudden Death
|
||||
- generic [ref=f6e288]: Does ten points of magical damage to any person or object.
|
||||
- button "NEUTRAL Amplify Doubles spell power of one point-based or duration-based spell. Two AMPLIFY spells quadruple spell power when used together." [ref=f6e289] [cursor=pointer]:
|
||||
- generic [ref=f6e290]: NEUTRAL
|
||||
- generic [ref=f6e291]: Amplify
|
||||
- generic [ref=f6e292]: Doubles spell power of one point-based or duration-based spell. Two AMPLIFY spells quadruple spell power when used together.
|
||||
- button "COUNTERACTION Absorb Spell You can nullify and take into your hand one spell used directly against you. Does not include NUMBER cards. Will work on other COUNTERACTIONS. REFLECTION, FULL REFLECTION, FULL SHIELD have no effect on this card." [ref=f6e293] [cursor=pointer]:
|
||||
- generic [ref=f6e294]: COUNTERACTION
|
||||
- generic [ref=f6e295]: Absorb Spell
|
||||
- generic [ref=f6e296]: You can nullify and take into your hand one spell used directly against you. Does not include NUMBER cards. Will work on other COUNTERACTIONS. REFLECTION, FULL REFLECTION, FULL SHIELD have no effect on this card.
|
||||
- button "ATTACK L.O.S. Lightning Blast Does magical damage equal to the accompanying NUMBER card, and stuns. Opponent loses one turn while recovering from electrified senses. If all damage gets counteracted, opponent does not lose turn." [ref=f6e297] [cursor=pointer]:
|
||||
- generic [ref=f6e298]: ATTACK
|
||||
- generic [ref=f6e299]: L.O.S.
|
||||
- generic [ref=f6e300]: Lightning Blast
|
||||
- generic [ref=f6e301]: Does magical damage equal to the accompanying NUMBER card, and stuns. Opponent loses one turn while recovering from electrified senses. If all damage gets counteracted, opponent does not lose turn.
|
||||
- button "ATTACK ADJACENT Wizardblade Does magical damage equal to the NUMBER card played. Does NO damage without a NUMBER card. Must be on same square as opponent to attack. If target fills an entire square, you must be in an adjacent square to use. This card is permanent. Display when used." [ref=f6e302] [cursor=pointer]:
|
||||
- generic [ref=f6e303]: ATTACK
|
||||
- generic [ref=f6e304]: ADJACENT
|
||||
- generic [ref=f6e305]: Wizardblade
|
||||
- generic [ref=f6e306]: Does magical damage equal to the NUMBER card played. Does NO damage without a NUMBER card. Must be on same square as opponent to attack. If target fills an entire square, you must be in an adjacent square to use. This card is permanent. Display when used.
|
||||
- generic [ref=f6e307]:
|
||||
- generic [ref=f6e308]:
|
||||
- text: bob
|
||||
- generic [ref=f6e309]: as they fell
|
||||
- generic [ref=f6e310]:
|
||||
- button "ATTACK L.O.S. Powerthrust A telekinetic blow that does magical damage equal to two points plus an (optional) accompanying NUMBER card." [ref=f6e311] [cursor=pointer]:
|
||||
- generic [ref=f6e312]: ATTACK
|
||||
- generic [ref=f6e313]: L.O.S.
|
||||
- generic [ref=f6e314]: Powerthrust
|
||||
- generic [ref=f6e315]: A telekinetic blow that does magical damage equal to two points plus an (optional) accompanying NUMBER card.
|
||||
- button "NEUTRAL Amplify Doubles spell power of one point-based or duration-based spell. Two AMPLIFY spells quadruple spell power when used together." [ref=f6e316] [cursor=pointer]:
|
||||
- generic [ref=f6e317]: NEUTRAL
|
||||
- generic [ref=f6e318]: Amplify
|
||||
- generic [ref=f6e319]: Doubles spell power of one point-based or duration-based spell. Two AMPLIFY spells quadruple spell power when used together.
|
||||
- button "ATTACK L.O.S. Sudden Death Does ten points of magical damage to any person or object." [ref=f6e320] [cursor=pointer]:
|
||||
- generic [ref=f6e321]: ATTACK
|
||||
- generic [ref=f6e322]: L.O.S.
|
||||
- generic [ref=f6e323]: Sudden Death
|
||||
- generic [ref=f6e324]: Does ten points of magical damage to any person or object.
|
||||
- button "NEUTRAL Amplify Doubles spell power of one point-based or duration-based spell. Two AMPLIFY spells quadruple spell power when used together." [ref=f6e325] [cursor=pointer]:
|
||||
- generic [ref=f6e326]: NEUTRAL
|
||||
- generic [ref=f6e327]: Amplify
|
||||
- generic [ref=f6e328]: Doubles spell power of one point-based or duration-based spell. Two AMPLIFY spells quadruple spell power when used together.
|
||||
- button "COUNTERACTION Absorb Spell You can nullify and take into your hand one spell used directly against you. Does not include NUMBER cards. Will work on other COUNTERACTIONS. REFLECTION, FULL REFLECTION, FULL SHIELD have no effect on this card." [ref=f6e329] [cursor=pointer]:
|
||||
- generic [ref=f6e330]: COUNTERACTION
|
||||
- generic [ref=f6e331]: Absorb Spell
|
||||
- generic [ref=f6e332]: You can nullify and take into your hand one spell used directly against you. Does not include NUMBER cards. Will work on other COUNTERACTIONS. REFLECTION, FULL REFLECTION, FULL SHIELD have no effect on this card.
|
||||
- button "ATTACK L.O.S. Lightning Blast Does magical damage equal to the accompanying NUMBER card, and stuns. Opponent loses one turn while recovering from electrified senses. If all damage gets counteracted, opponent does not lose turn." [ref=f6e333] [cursor=pointer]:
|
||||
- generic [ref=f6e334]: ATTACK
|
||||
- generic [ref=f6e335]: L.O.S.
|
||||
- generic [ref=f6e336]: Lightning Blast
|
||||
- generic [ref=f6e337]: Does magical damage equal to the accompanying NUMBER card, and stuns. Opponent loses one turn while recovering from electrified senses. If all damage gets counteracted, opponent does not lose turn.
|
||||
- button "ATTACK ADJACENT Wizardblade Does magical damage equal to the NUMBER card played. Does NO damage without a NUMBER card. Must be on same square as opponent to attack. If target fills an entire square, you must be in an adjacent square to use. This card is permanent. Display when used." [ref=f6e338] [cursor=pointer]:
|
||||
- generic [ref=f6e339]: ATTACK
|
||||
- generic [ref=f6e340]: ADJACENT
|
||||
- generic [ref=f6e341]: Wizardblade
|
||||
- generic [ref=f6e342]: Does magical damage equal to the NUMBER card played. Does NO damage without a NUMBER card. Must be on same square as opponent to attack. If target fills an entire square, you must be in an adjacent square to use. This card is permanent. Display when used.
|
||||
- generic "your hand" [ref=f6e343]
|
||||
@@ -1,283 +0,0 @@
|
||||
- generic [ref=f6e3]:
|
||||
- banner [ref=f6e4]:
|
||||
- generic [ref=f6e5]: Wiz-War
|
||||
- generic [ref=f6e6]: sixth edition
|
||||
- generic [ref=f6e7]: room R9E8
|
||||
- button "transfer seat" [ref=f6e8] [cursor=pointer]
|
||||
- button "leave table" [ref=f6e9] [cursor=pointer]
|
||||
- button "help & rules" [ref=f6e10] [cursor=pointer]
|
||||
- generic [ref=f6e17]:
|
||||
- img [ref=f6e19]:
|
||||
- button [ref=f6e20] [cursor=pointer]
|
||||
- button [ref=f6e21] [cursor=pointer]
|
||||
- button [ref=f6e22] [cursor=pointer]
|
||||
- button [ref=f6e23] [cursor=pointer]
|
||||
- button [ref=f6e24] [cursor=pointer]
|
||||
- button [ref=f6e25] [cursor=pointer]
|
||||
- button [ref=f6e26] [cursor=pointer]
|
||||
- button [ref=f6e27] [cursor=pointer]
|
||||
- button [ref=f6e28] [cursor=pointer]
|
||||
- button [ref=f6e29] [cursor=pointer]
|
||||
- button [ref=f6e30] [cursor=pointer]
|
||||
- button [ref=f6e31] [cursor=pointer]
|
||||
- button [ref=f6e32] [cursor=pointer]
|
||||
- button [ref=f6e33] [cursor=pointer]
|
||||
- button [ref=f6e34] [cursor=pointer]
|
||||
- button [ref=f6e35] [cursor=pointer]
|
||||
- button [ref=f6e36] [cursor=pointer]
|
||||
- button [ref=f6e37] [cursor=pointer]
|
||||
- button [ref=f6e38] [cursor=pointer]
|
||||
- button [ref=f6e39] [cursor=pointer]
|
||||
- button [ref=f6e40] [cursor=pointer]
|
||||
- button [ref=f6e41] [cursor=pointer]
|
||||
- button [ref=f6e42] [cursor=pointer]
|
||||
- button [ref=f6e43] [cursor=pointer]
|
||||
- button [ref=f6e44] [cursor=pointer]
|
||||
- button [ref=f6e45] [cursor=pointer]
|
||||
- button [ref=f6e46] [cursor=pointer]
|
||||
- button [ref=f6e47] [cursor=pointer]
|
||||
- button [ref=f6e48] [cursor=pointer]
|
||||
- button [ref=f6e49] [cursor=pointer]
|
||||
- button [ref=f6e50] [cursor=pointer]
|
||||
- button [ref=f6e51] [cursor=pointer]
|
||||
- button [ref=f6e52] [cursor=pointer]
|
||||
- button [ref=f6e53] [cursor=pointer]
|
||||
- button [ref=f6e54] [cursor=pointer]
|
||||
- button [ref=f6e55] [cursor=pointer]
|
||||
- button [ref=f6e56] [cursor=pointer]
|
||||
- button [ref=f6e57] [cursor=pointer]
|
||||
- button [ref=f6e58] [cursor=pointer]
|
||||
- button [ref=f6e59] [cursor=pointer]
|
||||
- button [ref=f6e60] [cursor=pointer]
|
||||
- button [ref=f6e61] [cursor=pointer]
|
||||
- button [ref=f6e62] [cursor=pointer]
|
||||
- button [ref=f6e63] [cursor=pointer]
|
||||
- button [ref=f6e64] [cursor=pointer]
|
||||
- button [ref=f6e65] [cursor=pointer]
|
||||
- button [ref=f6e66] [cursor=pointer]
|
||||
- button [ref=f6e67] [cursor=pointer]
|
||||
- button [ref=f6e68] [cursor=pointer]
|
||||
- button [ref=f6e69] [cursor=pointer]
|
||||
- button "↑ A" [ref=f6e131] [cursor=pointer]:
|
||||
- generic: ↑
|
||||
- generic: A
|
||||
- button "↓ A" [ref=f6e133] [cursor=pointer]:
|
||||
- generic: ↓
|
||||
- generic: A
|
||||
- button "← B" [ref=f6e135] [cursor=pointer]:
|
||||
- generic: ←
|
||||
- generic: B
|
||||
- button "→ B" [ref=f6e137] [cursor=pointer]:
|
||||
- generic: →
|
||||
- generic: B
|
||||
- button "→ C" [ref=f6e139] [cursor=pointer]:
|
||||
- generic: →
|
||||
- generic: C
|
||||
- button "← C" [ref=f6e141] [cursor=pointer]:
|
||||
- generic: ←
|
||||
- generic: C
|
||||
- button [ref=f6e143] [cursor=pointer]
|
||||
- complementary [ref=f6e145]:
|
||||
- generic [ref=f6e146]:
|
||||
- text: You missed 94 moves.
|
||||
- button "▶ Watch what happened" [ref=f6e147] [cursor=pointer]
|
||||
- button "skip" [ref=f6e148] [cursor=pointer]
|
||||
- generic [ref=f6e149]: 🏆 alice wins!
|
||||
- generic [ref=f6e150]:
|
||||
- generic [ref=f6e151]: life-points
|
||||
- generic [ref=f6e152]:
|
||||
- generic [ref=f6e154]: alice (you)
|
||||
- generic [ref=f6e155]: "1"
|
||||
- generic [ref=f6e156]: 14 cards
|
||||
- generic [ref=f6e157]:
|
||||
- generic [ref=f6e159]: bob
|
||||
- generic [ref=f6e160]: "0"
|
||||
- generic [ref=f6e161]: 0 cards
|
||||
- generic [ref=f6e162]:
|
||||
- text: draw pile 111 ·
|
||||
- button "discards 0" [ref=f6e163] [cursor=pointer]
|
||||
- generic "game log" [ref=f6e164]:
|
||||
- generic [ref=f6e165]: — alice's turn (round 7) —
|
||||
- generic [ref=f6e166]: alice punches bob!
|
||||
- generic [ref=f6e167]: bob takes 1 damage (punch from alice) — 9 life left.
|
||||
- generic [ref=f6e168]: — bob's turn (round 8) —
|
||||
- generic [ref=f6e169]: bob punches alice!
|
||||
- generic [ref=f6e170]: alice takes 1 damage (punch from bob) — 9 life left.
|
||||
- generic [ref=f6e171]: — alice's turn (round 8) —
|
||||
- generic [ref=f6e172]: alice punches bob!
|
||||
- generic [ref=f6e173]: bob takes 1 damage (punch from alice) — 8 life left.
|
||||
- generic [ref=f6e174]: — bob's turn (round 9) —
|
||||
- generic [ref=f6e175]: bob punches alice!
|
||||
- generic [ref=f6e176]: alice takes 1 damage (punch from bob) — 8 life left.
|
||||
- generic [ref=f6e177]: — alice's turn (round 9) —
|
||||
- generic [ref=f6e178]: alice punches bob!
|
||||
- generic [ref=f6e179]: bob takes 1 damage (punch from alice) — 7 life left.
|
||||
- generic [ref=f6e180]: — bob's turn (round 10) —
|
||||
- generic [ref=f6e181]: bob punches alice!
|
||||
- generic [ref=f6e182]: alice takes 1 damage (punch from bob) — 7 life left.
|
||||
- generic [ref=f6e183]: — alice's turn (round 10) —
|
||||
- generic [ref=f6e184]: alice punches bob!
|
||||
- generic [ref=f6e185]: bob takes 1 damage (punch from alice) — 6 life left.
|
||||
- generic [ref=f6e186]: — bob's turn (round 11) —
|
||||
- generic [ref=f6e187]: bob punches alice!
|
||||
- generic [ref=f6e188]: alice takes 1 damage (punch from bob) — 6 life left.
|
||||
- generic [ref=f6e189]: — alice's turn (round 11) —
|
||||
- generic [ref=f6e190]: alice punches bob!
|
||||
- generic [ref=f6e191]: bob takes 1 damage (punch from alice) — 5 life left.
|
||||
- generic [ref=f6e192]: — bob's turn (round 12) —
|
||||
- generic [ref=f6e193]: bob punches alice!
|
||||
- generic [ref=f6e194]: alice takes 1 damage (punch from bob) — 5 life left.
|
||||
- generic [ref=f6e195]: — alice's turn (round 12) —
|
||||
- generic [ref=f6e196]: alice punches bob!
|
||||
- generic [ref=f6e197]: bob takes 1 damage (punch from alice) — 4 life left.
|
||||
- generic [ref=f6e198]: — bob's turn (round 13) —
|
||||
- generic [ref=f6e199]: bob punches alice!
|
||||
- generic [ref=f6e200]: alice takes 1 damage (punch from bob) — 4 life left.
|
||||
- generic [ref=f6e201]: — alice's turn (round 13) —
|
||||
- generic [ref=f6e202]: alice punches bob!
|
||||
- generic [ref=f6e203]: bob takes 1 damage (punch from alice) — 3 life left.
|
||||
- generic [ref=f6e204]: — bob's turn (round 14) —
|
||||
- generic [ref=f6e205]: bob punches alice!
|
||||
- generic [ref=f6e206]: alice takes 1 damage (punch from bob) — 3 life left.
|
||||
- generic [ref=f6e207]: — alice's turn (round 14) —
|
||||
- generic [ref=f6e208]: alice punches bob!
|
||||
- generic [ref=f6e209]: bob takes 1 damage (punch from alice) — 2 life left.
|
||||
- generic [ref=f6e210]: — bob's turn (round 15) —
|
||||
- generic [ref=f6e211]: bob punches alice!
|
||||
- generic [ref=f6e212]: alice takes 1 damage (punch from bob) — 2 life left.
|
||||
- generic [ref=f6e213]: — alice's turn (round 15) —
|
||||
- generic [ref=f6e214]: alice punches bob!
|
||||
- generic [ref=f6e215]: bob takes 1 damage (punch from alice) — 1 life left.
|
||||
- generic [ref=f6e216]: — bob's turn (round 16) —
|
||||
- generic [ref=f6e217]: bob punches alice!
|
||||
- generic [ref=f6e218]: alice takes 1 damage (punch from bob) — 1 life left.
|
||||
- generic [ref=f6e219]: — alice's turn (round 16) —
|
||||
- generic [ref=f6e220]: alice punches bob!
|
||||
- generic [ref=f6e221]: bob takes 1 damage (punch from alice) — 0 life left.
|
||||
- generic [ref=f6e222]: ☠ bob is dead — killed by alice.
|
||||
- generic [ref=f6e223]: alice takes 7 cards from bob's body.
|
||||
- generic [ref=f6e224]: 🏆 alice WINS — last wizard standing!
|
||||
- generic [ref=f6e225]:
|
||||
- generic [ref=f6e226]: Hand over the limit — mark cards and discard.
|
||||
- generic [ref=f6e228]:
|
||||
- button "Pick up treasure" [disabled] [ref=f6e229]
|
||||
- button "Drop treasure" [disabled] [ref=f6e230]
|
||||
- button "Punch a wall…" [disabled] [ref=f6e231]
|
||||
- button "Discard cards…" [ref=f6e232] [cursor=pointer]
|
||||
- generic [ref=f6e233]:
|
||||
- text: draw
|
||||
- combobox "draw" [ref=f6e234]:
|
||||
- option "0"
|
||||
- option "1"
|
||||
- option "2" [selected]
|
||||
- button "End turn" [ref=f6e235] [cursor=pointer]
|
||||
- generic "all hands revealed" [ref=f6e236]:
|
||||
- generic [ref=f6e237]:
|
||||
- text: The hands, face-up
|
||||
- button "⟲ Watch the whole game" [ref=f6e238] [cursor=pointer]
|
||||
- generic [ref=f6e239]:
|
||||
- generic [ref=f6e240]: 🏆 alice
|
||||
- generic [ref=f6e241]:
|
||||
- button "NEUTRAL ADJACENT Pick Lock Unlock any door (but the door will relock behind you). Can only use when adjacent to door. You may \"hold the door open\" for others, if you wish. This is not a spell." [ref=f6e242] [cursor=pointer]:
|
||||
- generic [ref=f6e243]: NEUTRAL
|
||||
- generic [ref=f6e244]: ADJACENT
|
||||
- generic [ref=f6e245]: Pick Lock
|
||||
- generic [ref=f6e246]: Unlock any door (but the door will relock behind you). Can only use when adjacent to door. You may "hold the door open" for others, if you wish. This is not a spell.
|
||||
- button "NEUTRAL L.O.S. Remove Lock Permanently removes lock from any one door. Must be adjacent to door to use. Door is still considered to block L.O.S." [ref=f6e247] [cursor=pointer]:
|
||||
- generic [ref=f6e248]: NEUTRAL
|
||||
- generic [ref=f6e249]: L.O.S.
|
||||
- generic [ref=f6e250]: Remove Lock
|
||||
- generic [ref=f6e251]: Permanently removes lock from any one door. Must be adjacent to door to use. Door is still considered to block L.O.S.
|
||||
- button "ATTACK L.O.S. Fireball Does five points of magical damage and destroys all magical stones an opponent is carrying, if any of the points get through." [ref=f6e252] [cursor=pointer]:
|
||||
- generic [ref=f6e253]: ATTACK
|
||||
- generic [ref=f6e254]: L.O.S.
|
||||
- generic [ref=f6e255]: Fireball
|
||||
- generic [ref=f6e256]: Does five points of magical damage and destroys all magical stones an opponent is carrying, if any of the points get through.
|
||||
- button "ATTACK L.O.S. Power Drain Drain points from an opponent and add them to your own points. Amount equals NUMBER card played." [ref=f6e257] [cursor=pointer]:
|
||||
- generic [ref=f6e258]: ATTACK
|
||||
- generic [ref=f6e259]: L.O.S.
|
||||
- generic [ref=f6e260]: Power Drain
|
||||
- generic [ref=f6e261]: Drain points from an opponent and add them to your own points. Amount equals NUMBER card played.
|
||||
- button "COUNTERACTION Reflection A spell cast against you works 50% for both parties. Only works on point-based or duration-based spells. Round fractions up. A single lost turn, then, divided and rounded up, is a lost turn for both players." [ref=f6e262] [cursor=pointer]:
|
||||
- generic [ref=f6e263]: COUNTERACTION
|
||||
- generic [ref=f6e264]: Reflection
|
||||
- generic [ref=f6e265]: A spell cast against you works 50% for both parties. Only works on point-based or duration-based spells. Round fractions up. A single lost turn, then, divided and rounded up, is a lost turn for both players.
|
||||
- button "4 4 Wiz-War 4" [ref=f6e266] [cursor=pointer]:
|
||||
- generic [ref=f6e267]: "4"
|
||||
- generic [ref=f6e268]: "4"
|
||||
- generic [ref=f6e269]: Wiz-War
|
||||
- generic [ref=f6e270]: "4"
|
||||
- button "NEUTRAL/COUNTERACTION Reuse Spell You may retrieve any spell you use immediately after you use it (but not the NUMBER card, if used). You may reuse your retrieved spell immediately if you wish (except when it is an ATTACK)." [ref=f6e271] [cursor=pointer]:
|
||||
- generic [ref=f6e272]: NEUTRAL/COUNTERACTION
|
||||
- generic [ref=f6e273]: Reuse Spell
|
||||
- generic [ref=f6e274]: You may retrieve any spell you use immediately after you use it (but not the NUMBER card, if used). You may reuse your retrieved spell immediately if you wish (except when it is an ATTACK).
|
||||
- button "ATTACK L.O.S. Powerthrust A telekinetic blow that does magical damage equal to two points plus an (optional) accompanying NUMBER card." [ref=f6e275] [cursor=pointer]:
|
||||
- generic [ref=f6e276]: ATTACK
|
||||
- generic [ref=f6e277]: L.O.S.
|
||||
- generic [ref=f6e278]: Powerthrust
|
||||
- generic [ref=f6e279]: A telekinetic blow that does magical damage equal to two points plus an (optional) accompanying NUMBER card.
|
||||
- button "NEUTRAL Amplify Doubles spell power of one point-based or duration-based spell. Two AMPLIFY spells quadruple spell power when used together." [ref=f6e280] [cursor=pointer]:
|
||||
- generic [ref=f6e281]: NEUTRAL
|
||||
- generic [ref=f6e282]: Amplify
|
||||
- generic [ref=f6e283]: Doubles spell power of one point-based or duration-based spell. Two AMPLIFY spells quadruple spell power when used together.
|
||||
- button "ATTACK L.O.S. Sudden Death Does ten points of magical damage to any person or object." [ref=f6e284] [cursor=pointer]:
|
||||
- generic [ref=f6e285]: ATTACK
|
||||
- generic [ref=f6e286]: L.O.S.
|
||||
- generic [ref=f6e287]: Sudden Death
|
||||
- generic [ref=f6e288]: Does ten points of magical damage to any person or object.
|
||||
- button "NEUTRAL Amplify Doubles spell power of one point-based or duration-based spell. Two AMPLIFY spells quadruple spell power when used together." [ref=f6e289] [cursor=pointer]:
|
||||
- generic [ref=f6e290]: NEUTRAL
|
||||
- generic [ref=f6e291]: Amplify
|
||||
- generic [ref=f6e292]: Doubles spell power of one point-based or duration-based spell. Two AMPLIFY spells quadruple spell power when used together.
|
||||
- button "COUNTERACTION Absorb Spell You can nullify and take into your hand one spell used directly against you. Does not include NUMBER cards. Will work on other COUNTERACTIONS. REFLECTION, FULL REFLECTION, FULL SHIELD have no effect on this card." [ref=f6e293] [cursor=pointer]:
|
||||
- generic [ref=f6e294]: COUNTERACTION
|
||||
- generic [ref=f6e295]: Absorb Spell
|
||||
- generic [ref=f6e296]: You can nullify and take into your hand one spell used directly against you. Does not include NUMBER cards. Will work on other COUNTERACTIONS. REFLECTION, FULL REFLECTION, FULL SHIELD have no effect on this card.
|
||||
- button "ATTACK L.O.S. Lightning Blast Does magical damage equal to the accompanying NUMBER card, and stuns. Opponent loses one turn while recovering from electrified senses. If all damage gets counteracted, opponent does not lose turn." [ref=f6e297] [cursor=pointer]:
|
||||
- generic [ref=f6e298]: ATTACK
|
||||
- generic [ref=f6e299]: L.O.S.
|
||||
- generic [ref=f6e300]: Lightning Blast
|
||||
- generic [ref=f6e301]: Does magical damage equal to the accompanying NUMBER card, and stuns. Opponent loses one turn while recovering from electrified senses. If all damage gets counteracted, opponent does not lose turn.
|
||||
- button "ATTACK ADJACENT Wizardblade Does magical damage equal to the NUMBER card played. Does NO damage without a NUMBER card. Must be on same square as opponent to attack. If target fills an entire square, you must be in an adjacent square to use. This card is permanent. Display when used." [ref=f6e302] [cursor=pointer]:
|
||||
- generic [ref=f6e303]: ATTACK
|
||||
- generic [ref=f6e304]: ADJACENT
|
||||
- generic [ref=f6e305]: Wizardblade
|
||||
- generic [ref=f6e306]: Does magical damage equal to the NUMBER card played. Does NO damage without a NUMBER card. Must be on same square as opponent to attack. If target fills an entire square, you must be in an adjacent square to use. This card is permanent. Display when used.
|
||||
- generic [ref=f6e307]:
|
||||
- generic [ref=f6e308]:
|
||||
- text: bob
|
||||
- generic [ref=f6e309]: as they fell
|
||||
- generic [ref=f6e310]:
|
||||
- button "ATTACK L.O.S. Powerthrust A telekinetic blow that does magical damage equal to two points plus an (optional) accompanying NUMBER card." [ref=f6e311] [cursor=pointer]:
|
||||
- generic [ref=f6e312]: ATTACK
|
||||
- generic [ref=f6e313]: L.O.S.
|
||||
- generic [ref=f6e314]: Powerthrust
|
||||
- generic [ref=f6e315]: A telekinetic blow that does magical damage equal to two points plus an (optional) accompanying NUMBER card.
|
||||
- button "NEUTRAL Amplify Doubles spell power of one point-based or duration-based spell. Two AMPLIFY spells quadruple spell power when used together." [ref=f6e316] [cursor=pointer]:
|
||||
- generic [ref=f6e317]: NEUTRAL
|
||||
- generic [ref=f6e318]: Amplify
|
||||
- generic [ref=f6e319]: Doubles spell power of one point-based or duration-based spell. Two AMPLIFY spells quadruple spell power when used together.
|
||||
- button "ATTACK L.O.S. Sudden Death Does ten points of magical damage to any person or object." [ref=f6e320] [cursor=pointer]:
|
||||
- generic [ref=f6e321]: ATTACK
|
||||
- generic [ref=f6e322]: L.O.S.
|
||||
- generic [ref=f6e323]: Sudden Death
|
||||
- generic [ref=f6e324]: Does ten points of magical damage to any person or object.
|
||||
- button "NEUTRAL Amplify Doubles spell power of one point-based or duration-based spell. Two AMPLIFY spells quadruple spell power when used together." [ref=f6e325] [cursor=pointer]:
|
||||
- generic [ref=f6e326]: NEUTRAL
|
||||
- generic [ref=f6e327]: Amplify
|
||||
- generic [ref=f6e328]: Doubles spell power of one point-based or duration-based spell. Two AMPLIFY spells quadruple spell power when used together.
|
||||
- button "COUNTERACTION Absorb Spell You can nullify and take into your hand one spell used directly against you. Does not include NUMBER cards. Will work on other COUNTERACTIONS. REFLECTION, FULL REFLECTION, FULL SHIELD have no effect on this card." [ref=f6e329] [cursor=pointer]:
|
||||
- generic [ref=f6e330]: COUNTERACTION
|
||||
- generic [ref=f6e331]: Absorb Spell
|
||||
- generic [ref=f6e332]: You can nullify and take into your hand one spell used directly against you. Does not include NUMBER cards. Will work on other COUNTERACTIONS. REFLECTION, FULL REFLECTION, FULL SHIELD have no effect on this card.
|
||||
- button "ATTACK L.O.S. Lightning Blast Does magical damage equal to the accompanying NUMBER card, and stuns. Opponent loses one turn while recovering from electrified senses. If all damage gets counteracted, opponent does not lose turn." [ref=f6e333] [cursor=pointer]:
|
||||
- generic [ref=f6e334]: ATTACK
|
||||
- generic [ref=f6e335]: L.O.S.
|
||||
- generic [ref=f6e336]: Lightning Blast
|
||||
- generic [ref=f6e337]: Does magical damage equal to the accompanying NUMBER card, and stuns. Opponent loses one turn while recovering from electrified senses. If all damage gets counteracted, opponent does not lose turn.
|
||||
- button "ATTACK ADJACENT Wizardblade Does magical damage equal to the NUMBER card played. Does NO damage without a NUMBER card. Must be on same square as opponent to attack. If target fills an entire square, you must be in an adjacent square to use. This card is permanent. Display when used." [ref=f6e338] [cursor=pointer]:
|
||||
- generic [ref=f6e339]: ATTACK
|
||||
- generic [ref=f6e340]: ADJACENT
|
||||
- generic [ref=f6e341]: Wizardblade
|
||||
- generic [ref=f6e342]: Does magical damage equal to the NUMBER card played. Does NO damage without a NUMBER card. Must be on same square as opponent to attack. If target fills an entire square, you must be in an adjacent square to use. This card is permanent. Display when used.
|
||||
- generic "your hand" [ref=f6e343]
|
||||
@@ -1,369 +0,0 @@
|
||||
- generic [ref=f6e3]:
|
||||
- banner [ref=f6e4]:
|
||||
- generic [ref=f6e5]: Wiz-War
|
||||
- generic [ref=f6e6]: sixth edition
|
||||
- generic [ref=f6e7]: room R9E8
|
||||
- button "transfer seat" [ref=f6e8] [cursor=pointer]
|
||||
- button "leave table" [ref=f6e9] [cursor=pointer]
|
||||
- button "help & rules" [ref=f6e10] [cursor=pointer]
|
||||
- dialog "what happened while you were away" [ref=f6e345]:
|
||||
- banner [ref=f6e346]:
|
||||
- generic [ref=f6e347]: The whole tale, from the deal
|
||||
- generic [ref=f6e348]: move 1 of 94
|
||||
- button "skip to now" [ref=f6e349] [cursor=pointer]
|
||||
- img [ref=f6e351]:
|
||||
- button [ref=f6e352] [cursor=pointer]
|
||||
- button [ref=f6e353] [cursor=pointer]
|
||||
- button [ref=f6e354] [cursor=pointer]
|
||||
- button [ref=f6e355] [cursor=pointer]
|
||||
- button [ref=f6e356] [cursor=pointer]
|
||||
- button [ref=f6e357] [cursor=pointer]
|
||||
- button [ref=f6e358] [cursor=pointer]
|
||||
- button [ref=f6e359] [cursor=pointer]
|
||||
- button [ref=f6e360] [cursor=pointer]
|
||||
- button [ref=f6e361] [cursor=pointer]
|
||||
- button [ref=f6e362] [cursor=pointer]
|
||||
- button [ref=f6e363] [cursor=pointer]
|
||||
- button [ref=f6e364] [cursor=pointer]
|
||||
- button [ref=f6e365] [cursor=pointer]
|
||||
- button [ref=f6e366] [cursor=pointer]
|
||||
- button [ref=f6e367] [cursor=pointer]
|
||||
- button [ref=f6e368] [cursor=pointer]
|
||||
- button [ref=f6e369] [cursor=pointer]
|
||||
- button [ref=f6e370] [cursor=pointer]
|
||||
- button [ref=f6e371] [cursor=pointer]
|
||||
- button [ref=f6e372] [cursor=pointer]
|
||||
- button [ref=f6e373] [cursor=pointer]
|
||||
- button [ref=f6e374] [cursor=pointer]
|
||||
- button [ref=f6e375] [cursor=pointer]
|
||||
- button [ref=f6e376] [cursor=pointer]
|
||||
- button [ref=f6e377] [cursor=pointer]
|
||||
- button [ref=f6e378] [cursor=pointer]
|
||||
- button [ref=f6e379] [cursor=pointer]
|
||||
- button [ref=f6e380] [cursor=pointer]
|
||||
- button [ref=f6e381] [cursor=pointer]
|
||||
- button [ref=f6e382] [cursor=pointer]
|
||||
- button [ref=f6e383] [cursor=pointer]
|
||||
- button [ref=f6e384] [cursor=pointer]
|
||||
- button [ref=f6e385] [cursor=pointer]
|
||||
- button [ref=f6e386] [cursor=pointer]
|
||||
- button [ref=f6e387] [cursor=pointer]
|
||||
- button [ref=f6e388] [cursor=pointer]
|
||||
- button [ref=f6e389] [cursor=pointer]
|
||||
- button [ref=f6e390] [cursor=pointer]
|
||||
- button [ref=f6e391] [cursor=pointer]
|
||||
- button [ref=f6e392] [cursor=pointer]
|
||||
- button [ref=f6e393] [cursor=pointer]
|
||||
- button [ref=f6e394] [cursor=pointer]
|
||||
- button [ref=f6e395] [cursor=pointer]
|
||||
- button [ref=f6e396] [cursor=pointer]
|
||||
- button [ref=f6e397] [cursor=pointer]
|
||||
- button [ref=f6e398] [cursor=pointer]
|
||||
- button [ref=f6e399] [cursor=pointer]
|
||||
- button [ref=f6e400] [cursor=pointer]
|
||||
- button [ref=f6e401] [cursor=pointer]
|
||||
- button "↑ A" [ref=f6e463] [cursor=pointer]:
|
||||
- generic: ↑
|
||||
- generic: A
|
||||
- button "↓ A" [ref=f6e465] [cursor=pointer]:
|
||||
- generic: ↓
|
||||
- generic: A
|
||||
- button "← B" [ref=f6e467] [cursor=pointer]:
|
||||
- generic: ←
|
||||
- generic: B
|
||||
- button "→ B" [ref=f6e469] [cursor=pointer]:
|
||||
- generic: →
|
||||
- generic: B
|
||||
- button "→ C" [ref=f6e471] [cursor=pointer]:
|
||||
- generic: →
|
||||
- generic: C
|
||||
- button "← C" [ref=f6e473] [cursor=pointer]:
|
||||
- generic: ←
|
||||
- generic: C
|
||||
- button [ref=f6e475] [cursor=pointer]
|
||||
- button [ref=f6e477] [cursor=pointer]
|
||||
- generic [ref=f6e479]:
|
||||
- strong [ref=f6e480]: bob
|
||||
- generic [ref=f6e481]: — alice's turn (round 1) —
|
||||
- generic [ref=f6e482]:
|
||||
- button "previous move" [ref=f6e483] [cursor=pointer]: ◀
|
||||
- button "pause" [ref=f6e484] [cursor=pointer]: ❚❚
|
||||
- button "next move" [ref=f6e485] [cursor=pointer]: ▶
|
||||
- button "1×" [ref=f6e486] [cursor=pointer]
|
||||
- button "2×" [ref=f6e487] [cursor=pointer]
|
||||
- button "4×" [ref=f6e488] [cursor=pointer]
|
||||
- generic [ref=f6e17]:
|
||||
- img [ref=f6e19]:
|
||||
- button [ref=f6e20] [cursor=pointer]
|
||||
- button [ref=f6e21] [cursor=pointer]
|
||||
- button [ref=f6e22] [cursor=pointer]
|
||||
- button [ref=f6e23] [cursor=pointer]
|
||||
- button [ref=f6e24] [cursor=pointer]
|
||||
- button [ref=f6e25] [cursor=pointer]
|
||||
- button [ref=f6e26] [cursor=pointer]
|
||||
- button [ref=f6e27] [cursor=pointer]
|
||||
- button [ref=f6e28] [cursor=pointer]
|
||||
- button [ref=f6e29] [cursor=pointer]
|
||||
- button [ref=f6e30] [cursor=pointer]
|
||||
- button [ref=f6e31] [cursor=pointer]
|
||||
- button [ref=f6e32] [cursor=pointer]
|
||||
- button [ref=f6e33] [cursor=pointer]
|
||||
- button [ref=f6e34] [cursor=pointer]
|
||||
- button [ref=f6e35] [cursor=pointer]
|
||||
- button [ref=f6e36] [cursor=pointer]
|
||||
- button [ref=f6e37] [cursor=pointer]
|
||||
- button [ref=f6e38] [cursor=pointer]
|
||||
- button [ref=f6e39] [cursor=pointer]
|
||||
- button [ref=f6e40] [cursor=pointer]
|
||||
- button [ref=f6e41] [cursor=pointer]
|
||||
- button [ref=f6e42] [cursor=pointer]
|
||||
- button [ref=f6e43] [cursor=pointer]
|
||||
- button [ref=f6e44] [cursor=pointer]
|
||||
- button [ref=f6e45] [cursor=pointer]
|
||||
- button [ref=f6e46] [cursor=pointer]
|
||||
- button [ref=f6e47] [cursor=pointer]
|
||||
- button [ref=f6e48] [cursor=pointer]
|
||||
- button [ref=f6e49] [cursor=pointer]
|
||||
- button [ref=f6e50] [cursor=pointer]
|
||||
- button [ref=f6e51] [cursor=pointer]
|
||||
- button [ref=f6e52] [cursor=pointer]
|
||||
- button [ref=f6e53] [cursor=pointer]
|
||||
- button [ref=f6e54] [cursor=pointer]
|
||||
- button [ref=f6e55] [cursor=pointer]
|
||||
- button [ref=f6e56] [cursor=pointer]
|
||||
- button [ref=f6e57] [cursor=pointer]
|
||||
- button [ref=f6e58] [cursor=pointer]
|
||||
- button [ref=f6e59] [cursor=pointer]
|
||||
- button [ref=f6e60] [cursor=pointer]
|
||||
- button [ref=f6e61] [cursor=pointer]
|
||||
- button [ref=f6e62] [cursor=pointer]
|
||||
- button [ref=f6e63] [cursor=pointer]
|
||||
- button [ref=f6e64] [cursor=pointer]
|
||||
- button [ref=f6e65] [cursor=pointer]
|
||||
- button [ref=f6e66] [cursor=pointer]
|
||||
- button [ref=f6e67] [cursor=pointer]
|
||||
- button [ref=f6e68] [cursor=pointer]
|
||||
- button [ref=f6e69] [cursor=pointer]
|
||||
- button "↑ A" [ref=f6e131] [cursor=pointer]:
|
||||
- generic: ↑
|
||||
- generic: A
|
||||
- button "↓ A" [ref=f6e133] [cursor=pointer]:
|
||||
- generic: ↓
|
||||
- generic: A
|
||||
- button "← B" [ref=f6e135] [cursor=pointer]:
|
||||
- generic: ←
|
||||
- generic: B
|
||||
- button "→ B" [ref=f6e137] [cursor=pointer]:
|
||||
- generic: →
|
||||
- generic: B
|
||||
- button "→ C" [ref=f6e139] [cursor=pointer]:
|
||||
- generic: →
|
||||
- generic: C
|
||||
- button "← C" [ref=f6e141] [cursor=pointer]:
|
||||
- generic: ←
|
||||
- generic: C
|
||||
- button [ref=f6e143] [cursor=pointer]
|
||||
- complementary [ref=f6e145]:
|
||||
- generic [ref=f6e146]:
|
||||
- text: You missed 94 moves.
|
||||
- button "▶ Watch what happened" [ref=f6e147] [cursor=pointer]
|
||||
- button "skip" [ref=f6e148] [cursor=pointer]
|
||||
- generic [ref=f6e149]: 🏆 alice wins!
|
||||
- generic [ref=f6e150]:
|
||||
- generic [ref=f6e151]: life-points
|
||||
- generic [ref=f6e152]:
|
||||
- generic [ref=f6e154]: alice (you)
|
||||
- generic [ref=f6e155]: "1"
|
||||
- generic [ref=f6e156]: 14 cards
|
||||
- generic [ref=f6e157]:
|
||||
- generic [ref=f6e159]: bob
|
||||
- generic [ref=f6e160]: "0"
|
||||
- generic [ref=f6e161]: 0 cards
|
||||
- generic [ref=f6e162]:
|
||||
- text: draw pile 111 ·
|
||||
- button "discards 0" [ref=f6e163] [cursor=pointer]
|
||||
- generic "game log" [ref=f6e164]:
|
||||
- generic [ref=f6e165]: — alice's turn (round 7) —
|
||||
- generic [ref=f6e166]: alice punches bob!
|
||||
- generic [ref=f6e167]: bob takes 1 damage (punch from alice) — 9 life left.
|
||||
- generic [ref=f6e168]: — bob's turn (round 8) —
|
||||
- generic [ref=f6e169]: bob punches alice!
|
||||
- generic [ref=f6e170]: alice takes 1 damage (punch from bob) — 9 life left.
|
||||
- generic [ref=f6e171]: — alice's turn (round 8) —
|
||||
- generic [ref=f6e172]: alice punches bob!
|
||||
- generic [ref=f6e173]: bob takes 1 damage (punch from alice) — 8 life left.
|
||||
- generic [ref=f6e174]: — bob's turn (round 9) —
|
||||
- generic [ref=f6e175]: bob punches alice!
|
||||
- generic [ref=f6e176]: alice takes 1 damage (punch from bob) — 8 life left.
|
||||
- generic [ref=f6e177]: — alice's turn (round 9) —
|
||||
- generic [ref=f6e178]: alice punches bob!
|
||||
- generic [ref=f6e179]: bob takes 1 damage (punch from alice) — 7 life left.
|
||||
- generic [ref=f6e180]: — bob's turn (round 10) —
|
||||
- generic [ref=f6e181]: bob punches alice!
|
||||
- generic [ref=f6e182]: alice takes 1 damage (punch from bob) — 7 life left.
|
||||
- generic [ref=f6e183]: — alice's turn (round 10) —
|
||||
- generic [ref=f6e184]: alice punches bob!
|
||||
- generic [ref=f6e185]: bob takes 1 damage (punch from alice) — 6 life left.
|
||||
- generic [ref=f6e186]: — bob's turn (round 11) —
|
||||
- generic [ref=f6e187]: bob punches alice!
|
||||
- generic [ref=f6e188]: alice takes 1 damage (punch from bob) — 6 life left.
|
||||
- generic [ref=f6e189]: — alice's turn (round 11) —
|
||||
- generic [ref=f6e190]: alice punches bob!
|
||||
- generic [ref=f6e191]: bob takes 1 damage (punch from alice) — 5 life left.
|
||||
- generic [ref=f6e192]: — bob's turn (round 12) —
|
||||
- generic [ref=f6e193]: bob punches alice!
|
||||
- generic [ref=f6e194]: alice takes 1 damage (punch from bob) — 5 life left.
|
||||
- generic [ref=f6e195]: — alice's turn (round 12) —
|
||||
- generic [ref=f6e196]: alice punches bob!
|
||||
- generic [ref=f6e197]: bob takes 1 damage (punch from alice) — 4 life left.
|
||||
- generic [ref=f6e198]: — bob's turn (round 13) —
|
||||
- generic [ref=f6e199]: bob punches alice!
|
||||
- generic [ref=f6e200]: alice takes 1 damage (punch from bob) — 4 life left.
|
||||
- generic [ref=f6e201]: — alice's turn (round 13) —
|
||||
- generic [ref=f6e202]: alice punches bob!
|
||||
- generic [ref=f6e203]: bob takes 1 damage (punch from alice) — 3 life left.
|
||||
- generic [ref=f6e204]: — bob's turn (round 14) —
|
||||
- generic [ref=f6e205]: bob punches alice!
|
||||
- generic [ref=f6e206]: alice takes 1 damage (punch from bob) — 3 life left.
|
||||
- generic [ref=f6e207]: — alice's turn (round 14) —
|
||||
- generic [ref=f6e208]: alice punches bob!
|
||||
- generic [ref=f6e209]: bob takes 1 damage (punch from alice) — 2 life left.
|
||||
- generic [ref=f6e210]: — bob's turn (round 15) —
|
||||
- generic [ref=f6e211]: bob punches alice!
|
||||
- generic [ref=f6e212]: alice takes 1 damage (punch from bob) — 2 life left.
|
||||
- generic [ref=f6e213]: — alice's turn (round 15) —
|
||||
- generic [ref=f6e214]: alice punches bob!
|
||||
- generic [ref=f6e215]: bob takes 1 damage (punch from alice) — 1 life left.
|
||||
- generic [ref=f6e216]: — bob's turn (round 16) —
|
||||
- generic [ref=f6e217]: bob punches alice!
|
||||
- generic [ref=f6e218]: alice takes 1 damage (punch from bob) — 1 life left.
|
||||
- generic [ref=f6e219]: — alice's turn (round 16) —
|
||||
- generic [ref=f6e220]: alice punches bob!
|
||||
- generic [ref=f6e221]: bob takes 1 damage (punch from alice) — 0 life left.
|
||||
- generic [ref=f6e222]: ☠ bob is dead — killed by alice.
|
||||
- generic [ref=f6e223]: alice takes 7 cards from bob's body.
|
||||
- generic [ref=f6e224]: 🏆 alice WINS — last wizard standing!
|
||||
- generic [ref=f6e225]:
|
||||
- generic [ref=f6e226]: Hand over the limit — mark cards and discard.
|
||||
- generic [ref=f6e228]:
|
||||
- button "Pick up treasure" [disabled] [ref=f6e229]
|
||||
- button "Drop treasure" [disabled] [ref=f6e230]
|
||||
- button "Punch a wall…" [disabled] [ref=f6e231]
|
||||
- button "Discard cards…" [ref=f6e232] [cursor=pointer]
|
||||
- generic [ref=f6e233]:
|
||||
- text: draw
|
||||
- combobox "draw" [ref=f6e234]:
|
||||
- option "0"
|
||||
- option "1"
|
||||
- option "2" [selected]
|
||||
- button "End turn" [ref=f6e235] [cursor=pointer]
|
||||
- generic "all hands revealed" [ref=f6e236]:
|
||||
- generic [ref=f6e237]:
|
||||
- text: The hands, face-up
|
||||
- button "⟲ Watch the whole game" [active] [ref=f6e238] [cursor=pointer]
|
||||
- generic [ref=f6e239]:
|
||||
- generic [ref=f6e240]: 🏆 alice
|
||||
- generic [ref=f6e241]:
|
||||
- button "NEUTRAL ADJACENT Pick Lock Unlock any door (but the door will relock behind you). Can only use when adjacent to door. You may \"hold the door open\" for others, if you wish. This is not a spell." [ref=f6e242] [cursor=pointer]:
|
||||
- generic [ref=f6e243]: NEUTRAL
|
||||
- generic [ref=f6e244]: ADJACENT
|
||||
- generic [ref=f6e245]: Pick Lock
|
||||
- generic [ref=f6e246]: Unlock any door (but the door will relock behind you). Can only use when adjacent to door. You may "hold the door open" for others, if you wish. This is not a spell.
|
||||
- button "NEUTRAL L.O.S. Remove Lock Permanently removes lock from any one door. Must be adjacent to door to use. Door is still considered to block L.O.S." [ref=f6e247] [cursor=pointer]:
|
||||
- generic [ref=f6e248]: NEUTRAL
|
||||
- generic [ref=f6e249]: L.O.S.
|
||||
- generic [ref=f6e250]: Remove Lock
|
||||
- generic [ref=f6e251]: Permanently removes lock from any one door. Must be adjacent to door to use. Door is still considered to block L.O.S.
|
||||
- button "ATTACK L.O.S. Fireball Does five points of magical damage and destroys all magical stones an opponent is carrying, if any of the points get through." [ref=f6e252] [cursor=pointer]:
|
||||
- generic [ref=f6e253]: ATTACK
|
||||
- generic [ref=f6e254]: L.O.S.
|
||||
- generic [ref=f6e255]: Fireball
|
||||
- generic [ref=f6e256]: Does five points of magical damage and destroys all magical stones an opponent is carrying, if any of the points get through.
|
||||
- button "ATTACK L.O.S. Power Drain Drain points from an opponent and add them to your own points. Amount equals NUMBER card played." [ref=f6e257] [cursor=pointer]:
|
||||
- generic [ref=f6e258]: ATTACK
|
||||
- generic [ref=f6e259]: L.O.S.
|
||||
- generic [ref=f6e260]: Power Drain
|
||||
- generic [ref=f6e261]: Drain points from an opponent and add them to your own points. Amount equals NUMBER card played.
|
||||
- button "COUNTERACTION Reflection A spell cast against you works 50% for both parties. Only works on point-based or duration-based spells. Round fractions up. A single lost turn, then, divided and rounded up, is a lost turn for both players." [ref=f6e262] [cursor=pointer]:
|
||||
- generic [ref=f6e263]: COUNTERACTION
|
||||
- generic [ref=f6e264]: Reflection
|
||||
- generic [ref=f6e265]: A spell cast against you works 50% for both parties. Only works on point-based or duration-based spells. Round fractions up. A single lost turn, then, divided and rounded up, is a lost turn for both players.
|
||||
- button "4 4 Wiz-War 4" [ref=f6e266] [cursor=pointer]:
|
||||
- generic [ref=f6e267]: "4"
|
||||
- generic [ref=f6e268]: "4"
|
||||
- generic [ref=f6e269]: Wiz-War
|
||||
- generic [ref=f6e270]: "4"
|
||||
- button "NEUTRAL/COUNTERACTION Reuse Spell You may retrieve any spell you use immediately after you use it (but not the NUMBER card, if used). You may reuse your retrieved spell immediately if you wish (except when it is an ATTACK)." [ref=f6e271] [cursor=pointer]:
|
||||
- generic [ref=f6e272]: NEUTRAL/COUNTERACTION
|
||||
- generic [ref=f6e273]: Reuse Spell
|
||||
- generic [ref=f6e274]: You may retrieve any spell you use immediately after you use it (but not the NUMBER card, if used). You may reuse your retrieved spell immediately if you wish (except when it is an ATTACK).
|
||||
- button "ATTACK L.O.S. Powerthrust A telekinetic blow that does magical damage equal to two points plus an (optional) accompanying NUMBER card." [ref=f6e275] [cursor=pointer]:
|
||||
- generic [ref=f6e276]: ATTACK
|
||||
- generic [ref=f6e277]: L.O.S.
|
||||
- generic [ref=f6e278]: Powerthrust
|
||||
- generic [ref=f6e279]: A telekinetic blow that does magical damage equal to two points plus an (optional) accompanying NUMBER card.
|
||||
- button "NEUTRAL Amplify Doubles spell power of one point-based or duration-based spell. Two AMPLIFY spells quadruple spell power when used together." [ref=f6e280] [cursor=pointer]:
|
||||
- generic [ref=f6e281]: NEUTRAL
|
||||
- generic [ref=f6e282]: Amplify
|
||||
- generic [ref=f6e283]: Doubles spell power of one point-based or duration-based spell. Two AMPLIFY spells quadruple spell power when used together.
|
||||
- button "ATTACK L.O.S. Sudden Death Does ten points of magical damage to any person or object." [ref=f6e284] [cursor=pointer]:
|
||||
- generic [ref=f6e285]: ATTACK
|
||||
- generic [ref=f6e286]: L.O.S.
|
||||
- generic [ref=f6e287]: Sudden Death
|
||||
- generic [ref=f6e288]: Does ten points of magical damage to any person or object.
|
||||
- button "NEUTRAL Amplify Doubles spell power of one point-based or duration-based spell. Two AMPLIFY spells quadruple spell power when used together." [ref=f6e289] [cursor=pointer]:
|
||||
- generic [ref=f6e290]: NEUTRAL
|
||||
- generic [ref=f6e291]: Amplify
|
||||
- generic [ref=f6e292]: Doubles spell power of one point-based or duration-based spell. Two AMPLIFY spells quadruple spell power when used together.
|
||||
- button "COUNTERACTION Absorb Spell You can nullify and take into your hand one spell used directly against you. Does not include NUMBER cards. Will work on other COUNTERACTIONS. REFLECTION, FULL REFLECTION, FULL SHIELD have no effect on this card." [ref=f6e293] [cursor=pointer]:
|
||||
- generic [ref=f6e294]: COUNTERACTION
|
||||
- generic [ref=f6e295]: Absorb Spell
|
||||
- generic [ref=f6e296]: You can nullify and take into your hand one spell used directly against you. Does not include NUMBER cards. Will work on other COUNTERACTIONS. REFLECTION, FULL REFLECTION, FULL SHIELD have no effect on this card.
|
||||
- button "ATTACK L.O.S. Lightning Blast Does magical damage equal to the accompanying NUMBER card, and stuns. Opponent loses one turn while recovering from electrified senses. If all damage gets counteracted, opponent does not lose turn." [ref=f6e297] [cursor=pointer]:
|
||||
- generic [ref=f6e298]: ATTACK
|
||||
- generic [ref=f6e299]: L.O.S.
|
||||
- generic [ref=f6e300]: Lightning Blast
|
||||
- generic [ref=f6e301]: Does magical damage equal to the accompanying NUMBER card, and stuns. Opponent loses one turn while recovering from electrified senses. If all damage gets counteracted, opponent does not lose turn.
|
||||
- button "ATTACK ADJACENT Wizardblade Does magical damage equal to the NUMBER card played. Does NO damage without a NUMBER card. Must be on same square as opponent to attack. If target fills an entire square, you must be in an adjacent square to use. This card is permanent. Display when used." [ref=f6e302] [cursor=pointer]:
|
||||
- generic [ref=f6e303]: ATTACK
|
||||
- generic [ref=f6e304]: ADJACENT
|
||||
- generic [ref=f6e305]: Wizardblade
|
||||
- generic [ref=f6e306]: Does magical damage equal to the NUMBER card played. Does NO damage without a NUMBER card. Must be on same square as opponent to attack. If target fills an entire square, you must be in an adjacent square to use. This card is permanent. Display when used.
|
||||
- generic [ref=f6e307]:
|
||||
- generic [ref=f6e308]:
|
||||
- text: bob
|
||||
- generic [ref=f6e309]: as they fell
|
||||
- generic [ref=f6e310]:
|
||||
- button "ATTACK L.O.S. Powerthrust A telekinetic blow that does magical damage equal to two points plus an (optional) accompanying NUMBER card." [ref=f6e311] [cursor=pointer]:
|
||||
- generic [ref=f6e312]: ATTACK
|
||||
- generic [ref=f6e313]: L.O.S.
|
||||
- generic [ref=f6e314]: Powerthrust
|
||||
- generic [ref=f6e315]: A telekinetic blow that does magical damage equal to two points plus an (optional) accompanying NUMBER card.
|
||||
- button "NEUTRAL Amplify Doubles spell power of one point-based or duration-based spell. Two AMPLIFY spells quadruple spell power when used together." [ref=f6e316] [cursor=pointer]:
|
||||
- generic [ref=f6e317]: NEUTRAL
|
||||
- generic [ref=f6e318]: Amplify
|
||||
- generic [ref=f6e319]: Doubles spell power of one point-based or duration-based spell. Two AMPLIFY spells quadruple spell power when used together.
|
||||
- button "ATTACK L.O.S. Sudden Death Does ten points of magical damage to any person or object." [ref=f6e320] [cursor=pointer]:
|
||||
- generic [ref=f6e321]: ATTACK
|
||||
- generic [ref=f6e322]: L.O.S.
|
||||
- generic [ref=f6e323]: Sudden Death
|
||||
- generic [ref=f6e324]: Does ten points of magical damage to any person or object.
|
||||
- button "NEUTRAL Amplify Doubles spell power of one point-based or duration-based spell. Two AMPLIFY spells quadruple spell power when used together." [ref=f6e325] [cursor=pointer]:
|
||||
- generic [ref=f6e326]: NEUTRAL
|
||||
- generic [ref=f6e327]: Amplify
|
||||
- generic [ref=f6e328]: Doubles spell power of one point-based or duration-based spell. Two AMPLIFY spells quadruple spell power when used together.
|
||||
- button "COUNTERACTION Absorb Spell You can nullify and take into your hand one spell used directly against you. Does not include NUMBER cards. Will work on other COUNTERACTIONS. REFLECTION, FULL REFLECTION, FULL SHIELD have no effect on this card." [ref=f6e329] [cursor=pointer]:
|
||||
- generic [ref=f6e330]: COUNTERACTION
|
||||
- generic [ref=f6e331]: Absorb Spell
|
||||
- generic [ref=f6e332]: You can nullify and take into your hand one spell used directly against you. Does not include NUMBER cards. Will work on other COUNTERACTIONS. REFLECTION, FULL REFLECTION, FULL SHIELD have no effect on this card.
|
||||
- button "ATTACK L.O.S. Lightning Blast Does magical damage equal to the accompanying NUMBER card, and stuns. Opponent loses one turn while recovering from electrified senses. If all damage gets counteracted, opponent does not lose turn." [ref=f6e333] [cursor=pointer]:
|
||||
- generic [ref=f6e334]: ATTACK
|
||||
- generic [ref=f6e335]: L.O.S.
|
||||
- generic [ref=f6e336]: Lightning Blast
|
||||
- generic [ref=f6e337]: Does magical damage equal to the accompanying NUMBER card, and stuns. Opponent loses one turn while recovering from electrified senses. If all damage gets counteracted, opponent does not lose turn.
|
||||
- button "ATTACK ADJACENT Wizardblade Does magical damage equal to the NUMBER card played. Does NO damage without a NUMBER card. Must be on same square as opponent to attack. If target fills an entire square, you must be in an adjacent square to use. This card is permanent. Display when used." [ref=f6e338] [cursor=pointer]:
|
||||
- generic [ref=f6e339]: ATTACK
|
||||
- generic [ref=f6e340]: ADJACENT
|
||||
- generic [ref=f6e341]: Wizardblade
|
||||
- generic [ref=f6e342]: Does magical damage equal to the NUMBER card played. Does NO damage without a NUMBER card. Must be on same square as opponent to attack. If target fills an entire square, you must be in an adjacent square to use. This card is permanent. Display when used.
|
||||
- generic "your hand" [ref=f6e343]
|
||||
@@ -1,243 +0,0 @@
|
||||
- generic [ref=f7e3]:
|
||||
- banner [ref=f7e4]:
|
||||
- generic [ref=f7e5]: Wiz-War
|
||||
- generic [ref=f7e6]: sixth edition
|
||||
- generic [ref=f7e7]: room NX8Y
|
||||
- button "transfer seat" [ref=f7e8] [cursor=pointer]
|
||||
- button "leave table" [ref=f7e9] [cursor=pointer]
|
||||
- button "help & rules" [ref=f7e10] [cursor=pointer]
|
||||
- alertdialog "the game is won" [ref=f7e11]:
|
||||
- generic [ref=f7e12]:
|
||||
- generic [ref=f7e13]: 🏆
|
||||
- generic [ref=f7e14]: Kestrel
|
||||
- generic [ref=f7e15]: carried two stolen treasures home — the maze is theirs
|
||||
- button "Behold the final board" [ref=f7e16] [cursor=pointer]
|
||||
- generic [ref=f7e17]:
|
||||
- img [ref=f7e19]:
|
||||
- button [ref=f7e20] [cursor=pointer]
|
||||
- button [ref=f7e21] [cursor=pointer]
|
||||
- button [ref=f7e22] [cursor=pointer]
|
||||
- button [ref=f7e23] [cursor=pointer]
|
||||
- button [ref=f7e24] [cursor=pointer]
|
||||
- button [ref=f7e25] [cursor=pointer]
|
||||
- button [ref=f7e26] [cursor=pointer]
|
||||
- button [ref=f7e27] [cursor=pointer]
|
||||
- button [ref=f7e28] [cursor=pointer]
|
||||
- button [ref=f7e29] [cursor=pointer]
|
||||
- button [ref=f7e30] [cursor=pointer]
|
||||
- button [ref=f7e31] [cursor=pointer]
|
||||
- button [ref=f7e32] [cursor=pointer]
|
||||
- button [ref=f7e33] [cursor=pointer]
|
||||
- button [ref=f7e34] [cursor=pointer]
|
||||
- button [ref=f7e35] [cursor=pointer]
|
||||
- button [ref=f7e36] [cursor=pointer]
|
||||
- button [ref=f7e37] [cursor=pointer]
|
||||
- button [ref=f7e38] [cursor=pointer]
|
||||
- button [ref=f7e39] [cursor=pointer]
|
||||
- button [ref=f7e40] [cursor=pointer]
|
||||
- button [ref=f7e41] [cursor=pointer]
|
||||
- button [ref=f7e42] [cursor=pointer]
|
||||
- button [ref=f7e43] [cursor=pointer]
|
||||
- button [ref=f7e44] [cursor=pointer]
|
||||
- button [ref=f7e45] [cursor=pointer]
|
||||
- button [ref=f7e46] [cursor=pointer]
|
||||
- button [ref=f7e47] [cursor=pointer]
|
||||
- button [ref=f7e48] [cursor=pointer]
|
||||
- button [ref=f7e49] [cursor=pointer]
|
||||
- button [ref=f7e50] [cursor=pointer]
|
||||
- button [ref=f7e51] [cursor=pointer]
|
||||
- button [ref=f7e52] [cursor=pointer]
|
||||
- button [ref=f7e53] [cursor=pointer]
|
||||
- button [ref=f7e54] [cursor=pointer]
|
||||
- button [ref=f7e55] [cursor=pointer]
|
||||
- button [ref=f7e56] [cursor=pointer]
|
||||
- button [ref=f7e57] [cursor=pointer]
|
||||
- button [ref=f7e58] [cursor=pointer]
|
||||
- button [ref=f7e59] [cursor=pointer]
|
||||
- button [ref=f7e60] [cursor=pointer]
|
||||
- button [ref=f7e61] [cursor=pointer]
|
||||
- button [ref=f7e62] [cursor=pointer]
|
||||
- button [ref=f7e63] [cursor=pointer]
|
||||
- button [ref=f7e64] [cursor=pointer]
|
||||
- button [ref=f7e65] [cursor=pointer]
|
||||
- button [ref=f7e66] [cursor=pointer]
|
||||
- button [ref=f7e67] [cursor=pointer]
|
||||
- button [ref=f7e68] [cursor=pointer]
|
||||
- button [ref=f7e69] [cursor=pointer]
|
||||
- button "↑ A" [ref=f7e131] [cursor=pointer]:
|
||||
- generic: ↑
|
||||
- generic: A
|
||||
- button "↓ A" [ref=f7e133] [cursor=pointer]:
|
||||
- generic: ↓
|
||||
- generic: A
|
||||
- button "← B" [ref=f7e135] [cursor=pointer]:
|
||||
- generic: ←
|
||||
- generic: B
|
||||
- button "→ B" [ref=f7e137] [cursor=pointer]:
|
||||
- generic: →
|
||||
- generic: B
|
||||
- button "→ C" [ref=f7e139] [cursor=pointer]:
|
||||
- generic: →
|
||||
- generic: C
|
||||
- button "← C" [ref=f7e141] [cursor=pointer]:
|
||||
- generic: ←
|
||||
- generic: C
|
||||
- button [ref=f7e143] [cursor=pointer]
|
||||
- button "wraith (Kestrel) — 2/4 dmg" [ref=f7e145] [cursor=pointer]
|
||||
- button "skeleton (Some Old Guy) — 0/4 dmg" [ref=f7e147] [cursor=pointer]
|
||||
- complementary [ref=f7e149]:
|
||||
- generic [ref=f7e150]:
|
||||
- text: You missed 142 moves.
|
||||
- button "▶ Watch what happened" [ref=f7e151] [cursor=pointer]
|
||||
- button "skip" [ref=f7e152] [cursor=pointer]
|
||||
- generic [ref=f7e153]: 🏆 Kestrel wins!
|
||||
- generic [ref=f7e154]:
|
||||
- generic [ref=f7e155]: life-points
|
||||
- generic [ref=f7e156]:
|
||||
- generic [ref=f7e158]: Some Old Guy (you)
|
||||
- generic [ref=f7e159]: "4"
|
||||
- generic [ref=f7e160]: 0 cards
|
||||
- generic [ref=f7e161]:
|
||||
- generic [ref=f7e163]: Kestrel
|
||||
- generic [ref=f7e164]: "15"
|
||||
- generic [ref=f7e165]: 8 cards
|
||||
- button "Brainstone" [ref=f7e167] [cursor=pointer]
|
||||
- generic [ref=f7e168]:
|
||||
- text: draw pile 156 ·
|
||||
- button "discards 35" [ref=f7e169] [cursor=pointer]
|
||||
- generic "game log" [ref=f7e170]:
|
||||
- generic [ref=f7e171]: Kestrel plays a 3 for movement (6 total).
|
||||
- generic [ref=f7e172]: Kestrel casts Pick Lock.
|
||||
- generic [ref=f7e173]: Kestrel unlocks a door.
|
||||
- generic [ref=f7e174]: Kestrel grabs Some Old Guy's treasure!
|
||||
- generic [ref=f7e175]: Kestrel draws 2 card(s).
|
||||
- generic [ref=f7e176]: The door swings shut and relocks.
|
||||
- generic [ref=f7e177]: — Some Old Guy's turn (round 5) —
|
||||
- generic [ref=f7e178]: Some Old Guy plays a 2 for movement (5 total).
|
||||
- generic [ref=f7e179]: Some Old Guy casts Drop Object at Kestrel.
|
||||
- generic [ref=f7e180]: Kestrel drops a treasure.
|
||||
- generic [ref=f7e181]: Some Old Guy draws 2 card(s).
|
||||
- generic [ref=f7e182]: — Kestrel's turn (round 5) —
|
||||
- generic [ref=f7e183]: Kestrel charges a wand (2 charges).
|
||||
- generic [ref=f7e184]: The wand crackles (1 left).
|
||||
- generic [ref=f7e185]: Kestrel casts Sticky Wand with a 2 at Some Old Guy.
|
||||
- generic [ref=f7e186]: Kestrel displays Sticky Wand.
|
||||
- generic [ref=f7e187]: Sticky Wand webs settles over Some Old Guy (1 turn).
|
||||
- generic [ref=f7e188]: Some Old Guy is tangled in sticky webs!
|
||||
- generic [ref=f7e189]: Some Old Guy interrupts the flow of time (Opportunity Fire)!
|
||||
- generic [ref=f7e190]: The Wraith falls upon Some Old Guy!
|
||||
- generic [ref=f7e191]: Some Old Guy takes 2 damage (wraith's touch) — 6 life left.
|
||||
- generic [ref=f7e192]: "Some Old Guy discards Number “3” (Expansion #1)."
|
||||
- generic [ref=f7e193]: Kestrel grabs Some Old Guy's treasure!
|
||||
- generic [ref=f7e194]: Kestrel draws 2 card(s).
|
||||
- generic [ref=f7e195]: — Some Old Guy's turn (round 6) —
|
||||
- generic [ref=f7e196]: Some Old Guy draws 2 card(s).
|
||||
- generic [ref=f7e197]: Sticky Wand webs wears off Some Old Guy.
|
||||
- generic [ref=f7e198]: — Kestrel's turn (round 6) —
|
||||
- generic [ref=f7e199]: The Wraith falls upon Some Old Guy!
|
||||
- generic [ref=f7e200]: Some Old Guy takes 2 damage (wraith's touch) — 4 life left.
|
||||
- generic [ref=f7e201]: "Some Old Guy discards Number “2” (Expansion #1)."
|
||||
- generic [ref=f7e202]: Kestrel's wand crumbles to dust.
|
||||
- generic [ref=f7e203]: Kestrel casts Sticky Wand at Some Old Guy.
|
||||
- generic [ref=f7e204]: Kestrel displays Sticky Wand.
|
||||
- generic [ref=f7e205]: Sticky Wand webs settles over Some Old Guy (1 turn).
|
||||
- generic [ref=f7e206]: Some Old Guy is tangled in sticky webs!
|
||||
- generic [ref=f7e207]: Kestrel casts Pick Lock.
|
||||
- generic [ref=f7e208]: Kestrel unlocks a door.
|
||||
- generic [ref=f7e209]: Kestrel draws 2 card(s).
|
||||
- generic [ref=f7e210]: The door swings shut and relocks.
|
||||
- generic [ref=f7e211]: — Some Old Guy's turn (round 7) —
|
||||
- generic [ref=f7e212]: Some Old Guy casts Walking Dead.
|
||||
- generic [ref=f7e213]: Some Old Guy draws 2 card(s).
|
||||
- generic [ref=f7e214]: Sticky Wand webs wears off Some Old Guy.
|
||||
- generic [ref=f7e215]: — Kestrel's turn (round 7) —
|
||||
- generic [ref=f7e216]: Kestrel casts Brainstone.
|
||||
- generic [ref=f7e217]: Kestrel displays Brainstone.
|
||||
- generic [ref=f7e218]: Kestrel draws 2 card(s).
|
||||
- generic [ref=f7e219]: — Some Old Guy's turn (round 8) —
|
||||
- generic [ref=f7e220]: The Skeleton strikes!
|
||||
- generic [ref=f7e221]: The Wraith takes 2 damage.
|
||||
- generic [ref=f7e222]: Some Old Guy casts Thornbush.
|
||||
- generic [ref=f7e223]: Some Old Guy plays a 2 for movement (5 total).
|
||||
- generic [ref=f7e224]: Some Old Guy draws 2 card(s).
|
||||
- generic [ref=f7e225]: — Kestrel's turn (round 8) —
|
||||
- generic [ref=f7e226]: Kestrel casts Pick Lock.
|
||||
- generic [ref=f7e227]: Kestrel unlocks a door.
|
||||
- generic [ref=f7e228]: Kestrel drops a treasure on Kestrel's home base!
|
||||
- generic [ref=f7e229]: Some Old Guy is eliminated — both treasures lost!
|
||||
- generic [ref=f7e230]: 🏆 Kestrel WINS by treasure!
|
||||
- generic [ref=f7e231]:
|
||||
- generic "all hands revealed" [ref=f7e233]:
|
||||
- generic [ref=f7e234]:
|
||||
- text: The hands, face-up
|
||||
- button "⟲ Watch the whole game" [ref=f7e235] [cursor=pointer]
|
||||
- generic [ref=f7e236]:
|
||||
- generic [ref=f7e237]:
|
||||
- text: Some Old Guy
|
||||
- generic [ref=f7e238]: as they fell
|
||||
- generic [ref=f7e239]:
|
||||
- button "COUNTERACTION Blunt Reduces any damage done to you by 1/2. Round fractions up. Works on point-based or duration-based spells, or physical damage." [ref=f7e240] [cursor=pointer]:
|
||||
- generic [ref=f7e241]: COUNTERACTION
|
||||
- generic [ref=f7e242]: Blunt
|
||||
- generic [ref=f7e243]: Reduces any damage done to you by 1/2. Round fractions up. Works on point-based or duration-based spells, or physical damage.
|
||||
- button "2 2 Wiz-War 2" [ref=f7e244] [cursor=pointer]:
|
||||
- generic [ref=f7e245]: "2"
|
||||
- generic [ref=f7e246]: "2"
|
||||
- generic [ref=f7e247]: Wiz-War
|
||||
- generic [ref=f7e248]: "2"
|
||||
- button "ATTACK L.O.S. Large Rock You may throw it. Does two points physical damage. Once thrown, it may be picked up and thrown again by any player." [ref=f7e249] [cursor=pointer]:
|
||||
- generic [ref=f7e250]: ATTACK
|
||||
- generic [ref=f7e251]: L.O.S.
|
||||
- generic [ref=f7e252]: Large Rock
|
||||
- generic [ref=f7e253]: You may throw it. Does two points physical damage. Once thrown, it may be picked up and thrown again by any player.
|
||||
- button "NEUTRAL L.O.S. Create Door Creates a permanent, locked door in any stone wall or corridor. If cast on an illusionary wall, it is under the illusion, which must be seen through in order to use the door." [ref=f7e254] [cursor=pointer]:
|
||||
- generic [ref=f7e255]: NEUTRAL
|
||||
- generic [ref=f7e256]: L.O.S.
|
||||
- generic [ref=f7e257]: Create Door
|
||||
- generic [ref=f7e258]: Creates a permanent, locked door in any stone wall or corridor. If cast on an illusionary wall, it is under the illusion, which must be seen through in order to use the door.
|
||||
- button "NEUTRAL Around the Corner You may cast any line of sight spell around one corner (up to 180 degrees)" [ref=f7e259] [cursor=pointer]:
|
||||
- generic [ref=f7e260]: NEUTRAL
|
||||
- generic [ref=f7e261]: Around the Corner
|
||||
- generic [ref=f7e262]: You may cast any line of sight spell around one corner (up to 180 degrees)
|
||||
- button "NEUTRAL Alter Ego Create a stationary double of yourself in the square you now occupy. It may use any of the spells in your hand, and you need not be in its L.O.S. to do so. Permanent until destroyed. Any damage done to it at all destroys it." [ref=f7e263] [cursor=pointer]:
|
||||
- generic [ref=f7e264]: NEUTRAL
|
||||
- generic [ref=f7e265]: Alter Ego
|
||||
- generic [ref=f7e266]: Create a stationary double of yourself in the square you now occupy. It may use any of the spells in your hand, and you need not be in its L.O.S. to do so. Permanent until destroyed. Any damage done to it at all destroys it.
|
||||
- generic [ref=f7e267]:
|
||||
- generic [ref=f7e268]: 🏆 Kestrel
|
||||
- generic [ref=f7e269]:
|
||||
- button "NEUTRAL Adrenaline Allows two attacks in one turn. Duration equals NUMBER card played." [ref=f7e270] [cursor=pointer]:
|
||||
- generic [ref=f7e271]: NEUTRAL
|
||||
- generic [ref=f7e272]: Adrenaline
|
||||
- generic [ref=f7e273]: Allows two attacks in one turn. Duration equals NUMBER card played.
|
||||
- button "COUNTERACTION Reflection A spell cast against you works 50% for both parties. Only works on point-based or duration-based spells. Round fractions up. A single lost turn, then, divided and rounded up, is a lost turn for both players." [ref=f7e274] [cursor=pointer]:
|
||||
- generic [ref=f7e275]: COUNTERACTION
|
||||
- generic [ref=f7e276]: Reflection
|
||||
- generic [ref=f7e277]: A spell cast against you works 50% for both parties. Only works on point-based or duration-based spells. Round fractions up. A single lost turn, then, divided and rounded up, is a lost turn for both players.
|
||||
- button "NEUTRAL L.O.S. Ugly You momentarily become so ugly that all opponents in L.O.S. retreat as far away as necessary to avoid L.O.S., along the shortest path available. This happens during your turn. Passage through firewalls and bushes blocks L.O.S. For multiple corridor choices, opponent rolls D4 for random direction. Affects SHRUNK and INVISIBLE opponents." [ref=f7e278] [cursor=pointer]:
|
||||
- generic [ref=f7e279]: NEUTRAL
|
||||
- generic [ref=f7e280]: L.O.S.
|
||||
- generic [ref=f7e281]: Ugly
|
||||
- generic [ref=f7e282]: You momentarily become so ugly that all opponents in L.O.S. retreat as far away as necessary to avoid L.O.S., along the shortest path available. This happens during your turn. Passage through firewalls and bushes blocks L.O.S. For multiple corridor choices, opponent rolls D4 for random direction. Affects SHRUNK and INVISIBLE opponents.
|
||||
- button "NEUTRAL Shrink You shrink. Reduces opponent's chance to hit you by 50% in any attack. Also reduces your normal movement to 2. Duration equals NUMBER card played." [ref=f7e283] [cursor=pointer]:
|
||||
- generic [ref=f7e284]: NEUTRAL
|
||||
- generic [ref=f7e285]: Shrink
|
||||
- generic [ref=f7e286]: You shrink. Reduces opponent's chance to hit you by 50% in any attack. Also reduces your normal movement to 2. Duration equals NUMBER card played.
|
||||
- 'button "Brainstone POWER: Draw two more cards, now. Hand limit is now nine cards (including this card). This card is permanent. Display when used." [ref=f7e287] [cursor=pointer]':
|
||||
- generic [ref=f7e288]: Brainstone
|
||||
- generic [ref=f7e289]: "POWER: Draw two more cards, now. Hand limit is now nine cards (including this card). This card is permanent. Display when used."
|
||||
- button "COUNTERACTION Absorb Spell You can nullify and take into your hand one spell used directly against you. Does not include NUMBER cards. Will work on other COUNTERACTIONS. REFLECTION, FULL REFLECTION, FULL SHIELD have no effect on this card." [ref=f7e290] [cursor=pointer]:
|
||||
- generic [ref=f7e291]: COUNTERACTION
|
||||
- generic [ref=f7e292]: Absorb Spell
|
||||
- generic [ref=f7e293]: You can nullify and take into your hand one spell used directly against you. Does not include NUMBER cards. Will work on other COUNTERACTIONS. REFLECTION, FULL REFLECTION, FULL SHIELD have no effect on this card.
|
||||
- button "ATTACK L.O.S. Swap Meet This spell lets you swap any two carried items (your choice) with another player. REFLECTION nullifies the spell. FULL REFLECTION lets the other player decide which objects, if any, will be swapped." [ref=f7e294] [cursor=pointer]:
|
||||
- generic [ref=f7e295]: ATTACK
|
||||
- generic [ref=f7e296]: L.O.S.
|
||||
- generic [ref=f7e297]: Swap Meet
|
||||
- generic [ref=f7e298]: This spell lets you swap any two carried items (your choice) with another player. REFLECTION nullifies the spell. FULL REFLECTION lets the other player decide which objects, if any, will be swapped.
|
||||
- button "NEUTRAL L.O.S. Trader Swap the positions of any two items that are resting on the floor, both within your line of sight. Does not overcome GLUE. Does not work on players or monsters." [ref=f7e299] [cursor=pointer]:
|
||||
- generic [ref=f7e300]: NEUTRAL
|
||||
- generic [ref=f7e301]: L.O.S.
|
||||
- generic [ref=f7e302]: Trader
|
||||
- generic [ref=f7e303]: Swap the positions of any two items that are resting on the floor, both within your line of sight. Does not overcome GLUE. Does not work on players or monsters.
|
||||
- generic "your hand" [ref=f7e304]
|
||||
@@ -1,237 +0,0 @@
|
||||
- generic [ref=f7e3]:
|
||||
- banner [ref=f7e4]:
|
||||
- generic [ref=f7e5]: Wiz-War
|
||||
- generic [ref=f7e6]: sixth edition
|
||||
- generic [ref=f7e7]: room NX8Y
|
||||
- button "transfer seat" [ref=f7e8] [cursor=pointer]
|
||||
- button "leave table" [ref=f7e9] [cursor=pointer]
|
||||
- button "help & rules" [ref=f7e10] [cursor=pointer]
|
||||
- generic [ref=f7e17]:
|
||||
- img [ref=f7e19]:
|
||||
- button [ref=f7e20] [cursor=pointer]
|
||||
- button [ref=f7e21] [cursor=pointer]
|
||||
- button [ref=f7e22] [cursor=pointer]
|
||||
- button [ref=f7e23] [cursor=pointer]
|
||||
- button [ref=f7e24] [cursor=pointer]
|
||||
- button [ref=f7e25] [cursor=pointer]
|
||||
- button [ref=f7e26] [cursor=pointer]
|
||||
- button [ref=f7e27] [cursor=pointer]
|
||||
- button [ref=f7e28] [cursor=pointer]
|
||||
- button [ref=f7e29] [cursor=pointer]
|
||||
- button [ref=f7e30] [cursor=pointer]
|
||||
- button [ref=f7e31] [cursor=pointer]
|
||||
- button [ref=f7e32] [cursor=pointer]
|
||||
- button [ref=f7e33] [cursor=pointer]
|
||||
- button [ref=f7e34] [cursor=pointer]
|
||||
- button [ref=f7e35] [cursor=pointer]
|
||||
- button [ref=f7e36] [cursor=pointer]
|
||||
- button [ref=f7e37] [cursor=pointer]
|
||||
- button [ref=f7e38] [cursor=pointer]
|
||||
- button [ref=f7e39] [cursor=pointer]
|
||||
- button [ref=f7e40] [cursor=pointer]
|
||||
- button [ref=f7e41] [cursor=pointer]
|
||||
- button [ref=f7e42] [cursor=pointer]
|
||||
- button [ref=f7e43] [cursor=pointer]
|
||||
- button [ref=f7e44] [cursor=pointer]
|
||||
- button [ref=f7e45] [cursor=pointer]
|
||||
- button [ref=f7e46] [cursor=pointer]
|
||||
- button [ref=f7e47] [cursor=pointer]
|
||||
- button [ref=f7e48] [cursor=pointer]
|
||||
- button [ref=f7e49] [cursor=pointer]
|
||||
- button [ref=f7e50] [cursor=pointer]
|
||||
- button [ref=f7e51] [cursor=pointer]
|
||||
- button [ref=f7e52] [cursor=pointer]
|
||||
- button [ref=f7e53] [cursor=pointer]
|
||||
- button [ref=f7e54] [cursor=pointer]
|
||||
- button [ref=f7e55] [cursor=pointer]
|
||||
- button [ref=f7e56] [cursor=pointer]
|
||||
- button [ref=f7e57] [cursor=pointer]
|
||||
- button [ref=f7e58] [cursor=pointer]
|
||||
- button [ref=f7e59] [cursor=pointer]
|
||||
- button [ref=f7e60] [cursor=pointer]
|
||||
- button [ref=f7e61] [cursor=pointer]
|
||||
- button [ref=f7e62] [cursor=pointer]
|
||||
- button [ref=f7e63] [cursor=pointer]
|
||||
- button [ref=f7e64] [cursor=pointer]
|
||||
- button [ref=f7e65] [cursor=pointer]
|
||||
- button [ref=f7e66] [cursor=pointer]
|
||||
- button [ref=f7e67] [cursor=pointer]
|
||||
- button [ref=f7e68] [cursor=pointer]
|
||||
- button [ref=f7e69] [cursor=pointer]
|
||||
- button "↑ A" [ref=f7e131] [cursor=pointer]:
|
||||
- generic: ↑
|
||||
- generic: A
|
||||
- button "↓ A" [ref=f7e133] [cursor=pointer]:
|
||||
- generic: ↓
|
||||
- generic: A
|
||||
- button "← B" [ref=f7e135] [cursor=pointer]:
|
||||
- generic: ←
|
||||
- generic: B
|
||||
- button "→ B" [ref=f7e137] [cursor=pointer]:
|
||||
- generic: →
|
||||
- generic: B
|
||||
- button "→ C" [ref=f7e139] [cursor=pointer]:
|
||||
- generic: →
|
||||
- generic: C
|
||||
- button "← C" [ref=f7e141] [cursor=pointer]:
|
||||
- generic: ←
|
||||
- generic: C
|
||||
- button [ref=f7e143] [cursor=pointer]
|
||||
- button "wraith (Kestrel) — 2/4 dmg" [ref=f7e145] [cursor=pointer]
|
||||
- button "skeleton (Some Old Guy) — 0/4 dmg" [ref=f7e147] [cursor=pointer]
|
||||
- complementary [ref=f7e149]:
|
||||
- generic [ref=f7e150]:
|
||||
- text: You missed 142 moves.
|
||||
- button "▶ Watch what happened" [ref=f7e151] [cursor=pointer]
|
||||
- button "skip" [ref=f7e152] [cursor=pointer]
|
||||
- generic [ref=f7e153]: 🏆 Kestrel wins!
|
||||
- generic [ref=f7e154]:
|
||||
- generic [ref=f7e155]: life-points
|
||||
- generic [ref=f7e156]:
|
||||
- generic [ref=f7e158]: Some Old Guy (you)
|
||||
- generic [ref=f7e159]: "4"
|
||||
- generic [ref=f7e160]: 0 cards
|
||||
- generic [ref=f7e161]:
|
||||
- generic [ref=f7e163]: Kestrel
|
||||
- generic [ref=f7e164]: "15"
|
||||
- generic [ref=f7e165]: 8 cards
|
||||
- button "Brainstone" [ref=f7e167] [cursor=pointer]
|
||||
- generic [ref=f7e168]:
|
||||
- text: draw pile 156 ·
|
||||
- button "discards 35" [ref=f7e169] [cursor=pointer]
|
||||
- generic "game log" [ref=f7e170]:
|
||||
- generic [ref=f7e171]: Kestrel plays a 3 for movement (6 total).
|
||||
- generic [ref=f7e172]: Kestrel casts Pick Lock.
|
||||
- generic [ref=f7e173]: Kestrel unlocks a door.
|
||||
- generic [ref=f7e174]: Kestrel grabs Some Old Guy's treasure!
|
||||
- generic [ref=f7e175]: Kestrel draws 2 card(s).
|
||||
- generic [ref=f7e176]: The door swings shut and relocks.
|
||||
- generic [ref=f7e177]: — Some Old Guy's turn (round 5) —
|
||||
- generic [ref=f7e178]: Some Old Guy plays a 2 for movement (5 total).
|
||||
- generic [ref=f7e179]: Some Old Guy casts Drop Object at Kestrel.
|
||||
- generic [ref=f7e180]: Kestrel drops a treasure.
|
||||
- generic [ref=f7e181]: Some Old Guy draws 2 card(s).
|
||||
- generic [ref=f7e182]: — Kestrel's turn (round 5) —
|
||||
- generic [ref=f7e183]: Kestrel charges a wand (2 charges).
|
||||
- generic [ref=f7e184]: The wand crackles (1 left).
|
||||
- generic [ref=f7e185]: Kestrel casts Sticky Wand with a 2 at Some Old Guy.
|
||||
- generic [ref=f7e186]: Kestrel displays Sticky Wand.
|
||||
- generic [ref=f7e187]: Sticky Wand webs settles over Some Old Guy (1 turn).
|
||||
- generic [ref=f7e188]: Some Old Guy is tangled in sticky webs!
|
||||
- generic [ref=f7e189]: Some Old Guy interrupts the flow of time (Opportunity Fire)!
|
||||
- generic [ref=f7e190]: The Wraith falls upon Some Old Guy!
|
||||
- generic [ref=f7e191]: Some Old Guy takes 2 damage (wraith's touch) — 6 life left.
|
||||
- generic [ref=f7e192]: "Some Old Guy discards Number “3” (Expansion #1)."
|
||||
- generic [ref=f7e193]: Kestrel grabs Some Old Guy's treasure!
|
||||
- generic [ref=f7e194]: Kestrel draws 2 card(s).
|
||||
- generic [ref=f7e195]: — Some Old Guy's turn (round 6) —
|
||||
- generic [ref=f7e196]: Some Old Guy draws 2 card(s).
|
||||
- generic [ref=f7e197]: Sticky Wand webs wears off Some Old Guy.
|
||||
- generic [ref=f7e198]: — Kestrel's turn (round 6) —
|
||||
- generic [ref=f7e199]: The Wraith falls upon Some Old Guy!
|
||||
- generic [ref=f7e200]: Some Old Guy takes 2 damage (wraith's touch) — 4 life left.
|
||||
- generic [ref=f7e201]: "Some Old Guy discards Number “2” (Expansion #1)."
|
||||
- generic [ref=f7e202]: Kestrel's wand crumbles to dust.
|
||||
- generic [ref=f7e203]: Kestrel casts Sticky Wand at Some Old Guy.
|
||||
- generic [ref=f7e204]: Kestrel displays Sticky Wand.
|
||||
- generic [ref=f7e205]: Sticky Wand webs settles over Some Old Guy (1 turn).
|
||||
- generic [ref=f7e206]: Some Old Guy is tangled in sticky webs!
|
||||
- generic [ref=f7e207]: Kestrel casts Pick Lock.
|
||||
- generic [ref=f7e208]: Kestrel unlocks a door.
|
||||
- generic [ref=f7e209]: Kestrel draws 2 card(s).
|
||||
- generic [ref=f7e210]: The door swings shut and relocks.
|
||||
- generic [ref=f7e211]: — Some Old Guy's turn (round 7) —
|
||||
- generic [ref=f7e212]: Some Old Guy casts Walking Dead.
|
||||
- generic [ref=f7e213]: Some Old Guy draws 2 card(s).
|
||||
- generic [ref=f7e214]: Sticky Wand webs wears off Some Old Guy.
|
||||
- generic [ref=f7e215]: — Kestrel's turn (round 7) —
|
||||
- generic [ref=f7e216]: Kestrel casts Brainstone.
|
||||
- generic [ref=f7e217]: Kestrel displays Brainstone.
|
||||
- generic [ref=f7e218]: Kestrel draws 2 card(s).
|
||||
- generic [ref=f7e219]: — Some Old Guy's turn (round 8) —
|
||||
- generic [ref=f7e220]: The Skeleton strikes!
|
||||
- generic [ref=f7e221]: The Wraith takes 2 damage.
|
||||
- generic [ref=f7e222]: Some Old Guy casts Thornbush.
|
||||
- generic [ref=f7e223]: Some Old Guy plays a 2 for movement (5 total).
|
||||
- generic [ref=f7e224]: Some Old Guy draws 2 card(s).
|
||||
- generic [ref=f7e225]: — Kestrel's turn (round 8) —
|
||||
- generic [ref=f7e226]: Kestrel casts Pick Lock.
|
||||
- generic [ref=f7e227]: Kestrel unlocks a door.
|
||||
- generic [ref=f7e228]: Kestrel drops a treasure on Kestrel's home base!
|
||||
- generic [ref=f7e229]: Some Old Guy is eliminated — both treasures lost!
|
||||
- generic [ref=f7e230]: 🏆 Kestrel WINS by treasure!
|
||||
- generic [ref=f7e231]:
|
||||
- generic "all hands revealed" [ref=f7e233]:
|
||||
- generic [ref=f7e234]:
|
||||
- text: The hands, face-up
|
||||
- button "⟲ Watch the whole game" [ref=f7e235] [cursor=pointer]
|
||||
- generic [ref=f7e236]:
|
||||
- generic [ref=f7e237]:
|
||||
- text: Some Old Guy
|
||||
- generic [ref=f7e238]: as they fell
|
||||
- generic [ref=f7e239]:
|
||||
- button "COUNTERACTION Blunt Reduces any damage done to you by 1/2. Round fractions up. Works on point-based or duration-based spells, or physical damage." [ref=f7e240] [cursor=pointer]:
|
||||
- generic [ref=f7e241]: COUNTERACTION
|
||||
- generic [ref=f7e242]: Blunt
|
||||
- generic [ref=f7e243]: Reduces any damage done to you by 1/2. Round fractions up. Works on point-based or duration-based spells, or physical damage.
|
||||
- button "2 2 Wiz-War 2" [ref=f7e244] [cursor=pointer]:
|
||||
- generic [ref=f7e245]: "2"
|
||||
- generic [ref=f7e246]: "2"
|
||||
- generic [ref=f7e247]: Wiz-War
|
||||
- generic [ref=f7e248]: "2"
|
||||
- button "ATTACK L.O.S. Large Rock You may throw it. Does two points physical damage. Once thrown, it may be picked up and thrown again by any player." [ref=f7e249] [cursor=pointer]:
|
||||
- generic [ref=f7e250]: ATTACK
|
||||
- generic [ref=f7e251]: L.O.S.
|
||||
- generic [ref=f7e252]: Large Rock
|
||||
- generic [ref=f7e253]: You may throw it. Does two points physical damage. Once thrown, it may be picked up and thrown again by any player.
|
||||
- button "NEUTRAL L.O.S. Create Door Creates a permanent, locked door in any stone wall or corridor. If cast on an illusionary wall, it is under the illusion, which must be seen through in order to use the door." [ref=f7e254] [cursor=pointer]:
|
||||
- generic [ref=f7e255]: NEUTRAL
|
||||
- generic [ref=f7e256]: L.O.S.
|
||||
- generic [ref=f7e257]: Create Door
|
||||
- generic [ref=f7e258]: Creates a permanent, locked door in any stone wall or corridor. If cast on an illusionary wall, it is under the illusion, which must be seen through in order to use the door.
|
||||
- button "NEUTRAL Around the Corner You may cast any line of sight spell around one corner (up to 180 degrees)" [ref=f7e259] [cursor=pointer]:
|
||||
- generic [ref=f7e260]: NEUTRAL
|
||||
- generic [ref=f7e261]: Around the Corner
|
||||
- generic [ref=f7e262]: You may cast any line of sight spell around one corner (up to 180 degrees)
|
||||
- button "NEUTRAL Alter Ego Create a stationary double of yourself in the square you now occupy. It may use any of the spells in your hand, and you need not be in its L.O.S. to do so. Permanent until destroyed. Any damage done to it at all destroys it." [ref=f7e263] [cursor=pointer]:
|
||||
- generic [ref=f7e264]: NEUTRAL
|
||||
- generic [ref=f7e265]: Alter Ego
|
||||
- generic [ref=f7e266]: Create a stationary double of yourself in the square you now occupy. It may use any of the spells in your hand, and you need not be in its L.O.S. to do so. Permanent until destroyed. Any damage done to it at all destroys it.
|
||||
- generic [ref=f7e267]:
|
||||
- generic [ref=f7e268]: 🏆 Kestrel
|
||||
- generic [ref=f7e269]:
|
||||
- button "NEUTRAL Adrenaline Allows two attacks in one turn. Duration equals NUMBER card played." [ref=f7e270] [cursor=pointer]:
|
||||
- generic [ref=f7e271]: NEUTRAL
|
||||
- generic [ref=f7e272]: Adrenaline
|
||||
- generic [ref=f7e273]: Allows two attacks in one turn. Duration equals NUMBER card played.
|
||||
- button "COUNTERACTION Reflection A spell cast against you works 50% for both parties. Only works on point-based or duration-based spells. Round fractions up. A single lost turn, then, divided and rounded up, is a lost turn for both players." [ref=f7e274] [cursor=pointer]:
|
||||
- generic [ref=f7e275]: COUNTERACTION
|
||||
- generic [ref=f7e276]: Reflection
|
||||
- generic [ref=f7e277]: A spell cast against you works 50% for both parties. Only works on point-based or duration-based spells. Round fractions up. A single lost turn, then, divided and rounded up, is a lost turn for both players.
|
||||
- button "NEUTRAL L.O.S. Ugly You momentarily become so ugly that all opponents in L.O.S. retreat as far away as necessary to avoid L.O.S., along the shortest path available. This happens during your turn. Passage through firewalls and bushes blocks L.O.S. For multiple corridor choices, opponent rolls D4 for random direction. Affects SHRUNK and INVISIBLE opponents." [ref=f7e278] [cursor=pointer]:
|
||||
- generic [ref=f7e279]: NEUTRAL
|
||||
- generic [ref=f7e280]: L.O.S.
|
||||
- generic [ref=f7e281]: Ugly
|
||||
- generic [ref=f7e282]: You momentarily become so ugly that all opponents in L.O.S. retreat as far away as necessary to avoid L.O.S., along the shortest path available. This happens during your turn. Passage through firewalls and bushes blocks L.O.S. For multiple corridor choices, opponent rolls D4 for random direction. Affects SHRUNK and INVISIBLE opponents.
|
||||
- button "NEUTRAL Shrink You shrink. Reduces opponent's chance to hit you by 50% in any attack. Also reduces your normal movement to 2. Duration equals NUMBER card played." [ref=f7e283] [cursor=pointer]:
|
||||
- generic [ref=f7e284]: NEUTRAL
|
||||
- generic [ref=f7e285]: Shrink
|
||||
- generic [ref=f7e286]: You shrink. Reduces opponent's chance to hit you by 50% in any attack. Also reduces your normal movement to 2. Duration equals NUMBER card played.
|
||||
- 'button "Brainstone POWER: Draw two more cards, now. Hand limit is now nine cards (including this card). This card is permanent. Display when used." [ref=f7e287] [cursor=pointer]':
|
||||
- generic [ref=f7e288]: Brainstone
|
||||
- generic [ref=f7e289]: "POWER: Draw two more cards, now. Hand limit is now nine cards (including this card). This card is permanent. Display when used."
|
||||
- button "COUNTERACTION Absorb Spell You can nullify and take into your hand one spell used directly against you. Does not include NUMBER cards. Will work on other COUNTERACTIONS. REFLECTION, FULL REFLECTION, FULL SHIELD have no effect on this card." [ref=f7e290] [cursor=pointer]:
|
||||
- generic [ref=f7e291]: COUNTERACTION
|
||||
- generic [ref=f7e292]: Absorb Spell
|
||||
- generic [ref=f7e293]: You can nullify and take into your hand one spell used directly against you. Does not include NUMBER cards. Will work on other COUNTERACTIONS. REFLECTION, FULL REFLECTION, FULL SHIELD have no effect on this card.
|
||||
- button "ATTACK L.O.S. Swap Meet This spell lets you swap any two carried items (your choice) with another player. REFLECTION nullifies the spell. FULL REFLECTION lets the other player decide which objects, if any, will be swapped." [ref=f7e294] [cursor=pointer]:
|
||||
- generic [ref=f7e295]: ATTACK
|
||||
- generic [ref=f7e296]: L.O.S.
|
||||
- generic [ref=f7e297]: Swap Meet
|
||||
- generic [ref=f7e298]: This spell lets you swap any two carried items (your choice) with another player. REFLECTION nullifies the spell. FULL REFLECTION lets the other player decide which objects, if any, will be swapped.
|
||||
- button "NEUTRAL L.O.S. Trader Swap the positions of any two items that are resting on the floor, both within your line of sight. Does not overcome GLUE. Does not work on players or monsters." [ref=f7e299] [cursor=pointer]:
|
||||
- generic [ref=f7e300]: NEUTRAL
|
||||
- generic [ref=f7e301]: L.O.S.
|
||||
- generic [ref=f7e302]: Trader
|
||||
- generic [ref=f7e303]: Swap the positions of any two items that are resting on the floor, both within your line of sight. Does not overcome GLUE. Does not work on players or monsters.
|
||||
- generic "your hand" [ref=f7e304]
|
||||
@@ -1,324 +0,0 @@
|
||||
- generic [ref=f7e3]:
|
||||
- banner [ref=f7e4]:
|
||||
- generic [ref=f7e5]: Wiz-War
|
||||
- generic [ref=f7e6]: sixth edition
|
||||
- generic [ref=f7e7]: room NX8Y
|
||||
- button "transfer seat" [ref=f7e8] [cursor=pointer]
|
||||
- button "leave table" [ref=f7e9] [cursor=pointer]
|
||||
- button "help & rules" [ref=f7e10] [cursor=pointer]
|
||||
- dialog "what happened while you were away" [ref=f7e306]:
|
||||
- banner [ref=f7e307]:
|
||||
- generic [ref=f7e308]: The whole tale, from the deal
|
||||
- generic [ref=f7e309]: move 1 of 142
|
||||
- button "skip to now" [ref=f7e310] [cursor=pointer]
|
||||
- img [ref=f7e312]:
|
||||
- button [ref=f7e313] [cursor=pointer]
|
||||
- button [ref=f7e314] [cursor=pointer]
|
||||
- button [ref=f7e315] [cursor=pointer]
|
||||
- button [ref=f7e316] [cursor=pointer]
|
||||
- button [ref=f7e317] [cursor=pointer]
|
||||
- button [ref=f7e318] [cursor=pointer]
|
||||
- button [ref=f7e319] [cursor=pointer]
|
||||
- button [ref=f7e320] [cursor=pointer]
|
||||
- button [ref=f7e321] [cursor=pointer]
|
||||
- button [ref=f7e322] [cursor=pointer]
|
||||
- button [ref=f7e323] [cursor=pointer]
|
||||
- button [ref=f7e324] [cursor=pointer]
|
||||
- button [ref=f7e325] [cursor=pointer]
|
||||
- button [ref=f7e326] [cursor=pointer]
|
||||
- button [ref=f7e327] [cursor=pointer]
|
||||
- button [ref=f7e328] [cursor=pointer]
|
||||
- button [ref=f7e329] [cursor=pointer]
|
||||
- button [ref=f7e330] [cursor=pointer]
|
||||
- button [ref=f7e331] [cursor=pointer]
|
||||
- button [ref=f7e332] [cursor=pointer]
|
||||
- button [ref=f7e333] [cursor=pointer]
|
||||
- button [ref=f7e334] [cursor=pointer]
|
||||
- button [ref=f7e335] [cursor=pointer]
|
||||
- button [ref=f7e336] [cursor=pointer]
|
||||
- button [ref=f7e337] [cursor=pointer]
|
||||
- button [ref=f7e338] [cursor=pointer]
|
||||
- button [ref=f7e339] [cursor=pointer]
|
||||
- button [ref=f7e340] [cursor=pointer]
|
||||
- button [ref=f7e341] [cursor=pointer]
|
||||
- button [ref=f7e342] [cursor=pointer]
|
||||
- button [ref=f7e343] [cursor=pointer]
|
||||
- button [ref=f7e344] [cursor=pointer]
|
||||
- button [ref=f7e345] [cursor=pointer]
|
||||
- button [ref=f7e346] [cursor=pointer]
|
||||
- button [ref=f7e347] [cursor=pointer]
|
||||
- button [ref=f7e348] [cursor=pointer]
|
||||
- button [ref=f7e349] [cursor=pointer]
|
||||
- button [ref=f7e350] [cursor=pointer]
|
||||
- button [ref=f7e351] [cursor=pointer]
|
||||
- button [ref=f7e352] [cursor=pointer]
|
||||
- button [ref=f7e353] [cursor=pointer]
|
||||
- button [ref=f7e354] [cursor=pointer]
|
||||
- button [ref=f7e355] [cursor=pointer]
|
||||
- button [ref=f7e356] [cursor=pointer]
|
||||
- button [ref=f7e357] [cursor=pointer]
|
||||
- button [ref=f7e358] [cursor=pointer]
|
||||
- button [ref=f7e359] [cursor=pointer]
|
||||
- button [ref=f7e360] [cursor=pointer]
|
||||
- button [ref=f7e361] [cursor=pointer]
|
||||
- button [ref=f7e362] [cursor=pointer]
|
||||
- button "↑ A" [ref=f7e423] [cursor=pointer]:
|
||||
- generic: ↑
|
||||
- generic: A
|
||||
- button "↓ A" [ref=f7e425] [cursor=pointer]:
|
||||
- generic: ↓
|
||||
- generic: A
|
||||
- button "← B" [ref=f7e427] [cursor=pointer]:
|
||||
- generic: ←
|
||||
- generic: B
|
||||
- button "→ B" [ref=f7e429] [cursor=pointer]:
|
||||
- generic: →
|
||||
- generic: B
|
||||
- button "→ C" [ref=f7e431] [cursor=pointer]:
|
||||
- generic: →
|
||||
- generic: C
|
||||
- button "← C" [ref=f7e433] [cursor=pointer]:
|
||||
- generic: ←
|
||||
- generic: C
|
||||
- button [ref=f7e435] [cursor=pointer]
|
||||
- button [ref=f7e437] [cursor=pointer]
|
||||
- generic [ref=f7e439]:
|
||||
- strong [ref=f7e440]: Some Old Guy
|
||||
- generic [ref=f7e441]: Some Old Guy casts Bloodstone.
|
||||
- generic [ref=f7e442]: Some Old Guy displays Bloodstone.
|
||||
- generic [ref=f7e443]:
|
||||
- button "previous move" [ref=f7e444] [cursor=pointer]: ◀
|
||||
- button "pause" [ref=f7e445] [cursor=pointer]: ❚❚
|
||||
- button "next move" [ref=f7e446] [cursor=pointer]: ▶
|
||||
- button "1×" [ref=f7e447] [cursor=pointer]
|
||||
- button "2×" [ref=f7e448] [cursor=pointer]
|
||||
- button "4×" [ref=f7e449] [cursor=pointer]
|
||||
- generic [ref=f7e17]:
|
||||
- img [ref=f7e19]:
|
||||
- button [ref=f7e20] [cursor=pointer]
|
||||
- button [ref=f7e21] [cursor=pointer]
|
||||
- button [ref=f7e22] [cursor=pointer]
|
||||
- button [ref=f7e23] [cursor=pointer]
|
||||
- button [ref=f7e24] [cursor=pointer]
|
||||
- button [ref=f7e25] [cursor=pointer]
|
||||
- button [ref=f7e26] [cursor=pointer]
|
||||
- button [ref=f7e27] [cursor=pointer]
|
||||
- button [ref=f7e28] [cursor=pointer]
|
||||
- button [ref=f7e29] [cursor=pointer]
|
||||
- button [ref=f7e30] [cursor=pointer]
|
||||
- button [ref=f7e31] [cursor=pointer]
|
||||
- button [ref=f7e32] [cursor=pointer]
|
||||
- button [ref=f7e33] [cursor=pointer]
|
||||
- button [ref=f7e34] [cursor=pointer]
|
||||
- button [ref=f7e35] [cursor=pointer]
|
||||
- button [ref=f7e36] [cursor=pointer]
|
||||
- button [ref=f7e37] [cursor=pointer]
|
||||
- button [ref=f7e38] [cursor=pointer]
|
||||
- button [ref=f7e39] [cursor=pointer]
|
||||
- button [ref=f7e40] [cursor=pointer]
|
||||
- button [ref=f7e41] [cursor=pointer]
|
||||
- button [ref=f7e42] [cursor=pointer]
|
||||
- button [ref=f7e43] [cursor=pointer]
|
||||
- button [ref=f7e44] [cursor=pointer]
|
||||
- button [ref=f7e45] [cursor=pointer]
|
||||
- button [ref=f7e46] [cursor=pointer]
|
||||
- button [ref=f7e47] [cursor=pointer]
|
||||
- button [ref=f7e48] [cursor=pointer]
|
||||
- button [ref=f7e49] [cursor=pointer]
|
||||
- button [ref=f7e50] [cursor=pointer]
|
||||
- button [ref=f7e51] [cursor=pointer]
|
||||
- button [ref=f7e52] [cursor=pointer]
|
||||
- button [ref=f7e53] [cursor=pointer]
|
||||
- button [ref=f7e54] [cursor=pointer]
|
||||
- button [ref=f7e55] [cursor=pointer]
|
||||
- button [ref=f7e56] [cursor=pointer]
|
||||
- button [ref=f7e57] [cursor=pointer]
|
||||
- button [ref=f7e58] [cursor=pointer]
|
||||
- button [ref=f7e59] [cursor=pointer]
|
||||
- button [ref=f7e60] [cursor=pointer]
|
||||
- button [ref=f7e61] [cursor=pointer]
|
||||
- button [ref=f7e62] [cursor=pointer]
|
||||
- button [ref=f7e63] [cursor=pointer]
|
||||
- button [ref=f7e64] [cursor=pointer]
|
||||
- button [ref=f7e65] [cursor=pointer]
|
||||
- button [ref=f7e66] [cursor=pointer]
|
||||
- button [ref=f7e67] [cursor=pointer]
|
||||
- button [ref=f7e68] [cursor=pointer]
|
||||
- button [ref=f7e69] [cursor=pointer]
|
||||
- button "↑ A" [ref=f7e131] [cursor=pointer]:
|
||||
- generic: ↑
|
||||
- generic: A
|
||||
- button "↓ A" [ref=f7e133] [cursor=pointer]:
|
||||
- generic: ↓
|
||||
- generic: A
|
||||
- button "← B" [ref=f7e135] [cursor=pointer]:
|
||||
- generic: ←
|
||||
- generic: B
|
||||
- button "→ B" [ref=f7e137] [cursor=pointer]:
|
||||
- generic: →
|
||||
- generic: B
|
||||
- button "→ C" [ref=f7e139] [cursor=pointer]:
|
||||
- generic: →
|
||||
- generic: C
|
||||
- button "← C" [ref=f7e141] [cursor=pointer]:
|
||||
- generic: ←
|
||||
- generic: C
|
||||
- button [ref=f7e143] [cursor=pointer]
|
||||
- button "wraith (Kestrel) — 2/4 dmg" [ref=f7e145] [cursor=pointer]
|
||||
- button "skeleton (Some Old Guy) — 0/4 dmg" [ref=f7e147] [cursor=pointer]
|
||||
- complementary [ref=f7e149]:
|
||||
- generic [ref=f7e150]:
|
||||
- text: You missed 142 moves.
|
||||
- button "▶ Watch what happened" [ref=f7e151] [cursor=pointer]
|
||||
- button "skip" [ref=f7e152] [cursor=pointer]
|
||||
- generic [ref=f7e153]: 🏆 Kestrel wins!
|
||||
- generic [ref=f7e154]:
|
||||
- generic [ref=f7e155]: life-points
|
||||
- generic [ref=f7e156]:
|
||||
- generic [ref=f7e158]: Some Old Guy (you)
|
||||
- generic [ref=f7e159]: "4"
|
||||
- generic [ref=f7e160]: 0 cards
|
||||
- generic [ref=f7e161]:
|
||||
- generic [ref=f7e163]: Kestrel
|
||||
- generic [ref=f7e164]: "15"
|
||||
- generic [ref=f7e165]: 8 cards
|
||||
- button "Brainstone" [ref=f7e167] [cursor=pointer]
|
||||
- generic [ref=f7e168]:
|
||||
- text: draw pile 156 ·
|
||||
- button "discards 35" [ref=f7e169] [cursor=pointer]
|
||||
- generic "game log" [ref=f7e170]:
|
||||
- generic [ref=f7e171]: Kestrel plays a 3 for movement (6 total).
|
||||
- generic [ref=f7e172]: Kestrel casts Pick Lock.
|
||||
- generic [ref=f7e173]: Kestrel unlocks a door.
|
||||
- generic [ref=f7e174]: Kestrel grabs Some Old Guy's treasure!
|
||||
- generic [ref=f7e175]: Kestrel draws 2 card(s).
|
||||
- generic [ref=f7e176]: The door swings shut and relocks.
|
||||
- generic [ref=f7e177]: — Some Old Guy's turn (round 5) —
|
||||
- generic [ref=f7e178]: Some Old Guy plays a 2 for movement (5 total).
|
||||
- generic [ref=f7e179]: Some Old Guy casts Drop Object at Kestrel.
|
||||
- generic [ref=f7e180]: Kestrel drops a treasure.
|
||||
- generic [ref=f7e181]: Some Old Guy draws 2 card(s).
|
||||
- generic [ref=f7e182]: — Kestrel's turn (round 5) —
|
||||
- generic [ref=f7e183]: Kestrel charges a wand (2 charges).
|
||||
- generic [ref=f7e184]: The wand crackles (1 left).
|
||||
- generic [ref=f7e185]: Kestrel casts Sticky Wand with a 2 at Some Old Guy.
|
||||
- generic [ref=f7e186]: Kestrel displays Sticky Wand.
|
||||
- generic [ref=f7e187]: Sticky Wand webs settles over Some Old Guy (1 turn).
|
||||
- generic [ref=f7e188]: Some Old Guy is tangled in sticky webs!
|
||||
- generic [ref=f7e189]: Some Old Guy interrupts the flow of time (Opportunity Fire)!
|
||||
- generic [ref=f7e190]: The Wraith falls upon Some Old Guy!
|
||||
- generic [ref=f7e191]: Some Old Guy takes 2 damage (wraith's touch) — 6 life left.
|
||||
- generic [ref=f7e192]: "Some Old Guy discards Number “3” (Expansion #1)."
|
||||
- generic [ref=f7e193]: Kestrel grabs Some Old Guy's treasure!
|
||||
- generic [ref=f7e194]: Kestrel draws 2 card(s).
|
||||
- generic [ref=f7e195]: — Some Old Guy's turn (round 6) —
|
||||
- generic [ref=f7e196]: Some Old Guy draws 2 card(s).
|
||||
- generic [ref=f7e197]: Sticky Wand webs wears off Some Old Guy.
|
||||
- generic [ref=f7e198]: — Kestrel's turn (round 6) —
|
||||
- generic [ref=f7e199]: The Wraith falls upon Some Old Guy!
|
||||
- generic [ref=f7e200]: Some Old Guy takes 2 damage (wraith's touch) — 4 life left.
|
||||
- generic [ref=f7e201]: "Some Old Guy discards Number “2” (Expansion #1)."
|
||||
- generic [ref=f7e202]: Kestrel's wand crumbles to dust.
|
||||
- generic [ref=f7e203]: Kestrel casts Sticky Wand at Some Old Guy.
|
||||
- generic [ref=f7e204]: Kestrel displays Sticky Wand.
|
||||
- generic [ref=f7e205]: Sticky Wand webs settles over Some Old Guy (1 turn).
|
||||
- generic [ref=f7e206]: Some Old Guy is tangled in sticky webs!
|
||||
- generic [ref=f7e207]: Kestrel casts Pick Lock.
|
||||
- generic [ref=f7e208]: Kestrel unlocks a door.
|
||||
- generic [ref=f7e209]: Kestrel draws 2 card(s).
|
||||
- generic [ref=f7e210]: The door swings shut and relocks.
|
||||
- generic [ref=f7e211]: — Some Old Guy's turn (round 7) —
|
||||
- generic [ref=f7e212]: Some Old Guy casts Walking Dead.
|
||||
- generic [ref=f7e213]: Some Old Guy draws 2 card(s).
|
||||
- generic [ref=f7e214]: Sticky Wand webs wears off Some Old Guy.
|
||||
- generic [ref=f7e215]: — Kestrel's turn (round 7) —
|
||||
- generic [ref=f7e216]: Kestrel casts Brainstone.
|
||||
- generic [ref=f7e217]: Kestrel displays Brainstone.
|
||||
- generic [ref=f7e218]: Kestrel draws 2 card(s).
|
||||
- generic [ref=f7e219]: — Some Old Guy's turn (round 8) —
|
||||
- generic [ref=f7e220]: The Skeleton strikes!
|
||||
- generic [ref=f7e221]: The Wraith takes 2 damage.
|
||||
- generic [ref=f7e222]: Some Old Guy casts Thornbush.
|
||||
- generic [ref=f7e223]: Some Old Guy plays a 2 for movement (5 total).
|
||||
- generic [ref=f7e224]: Some Old Guy draws 2 card(s).
|
||||
- generic [ref=f7e225]: — Kestrel's turn (round 8) —
|
||||
- generic [ref=f7e226]: Kestrel casts Pick Lock.
|
||||
- generic [ref=f7e227]: Kestrel unlocks a door.
|
||||
- generic [ref=f7e228]: Kestrel drops a treasure on Kestrel's home base!
|
||||
- generic [ref=f7e229]: Some Old Guy is eliminated — both treasures lost!
|
||||
- generic [ref=f7e230]: 🏆 Kestrel WINS by treasure!
|
||||
- generic [ref=f7e231]:
|
||||
- generic "all hands revealed" [ref=f7e233]:
|
||||
- generic [ref=f7e234]:
|
||||
- text: The hands, face-up
|
||||
- button "⟲ Watch the whole game" [active] [ref=f7e235] [cursor=pointer]
|
||||
- generic [ref=f7e236]:
|
||||
- generic [ref=f7e237]:
|
||||
- text: Some Old Guy
|
||||
- generic [ref=f7e238]: as they fell
|
||||
- generic [ref=f7e239]:
|
||||
- button "COUNTERACTION Blunt Reduces any damage done to you by 1/2. Round fractions up. Works on point-based or duration-based spells, or physical damage." [ref=f7e240] [cursor=pointer]:
|
||||
- generic [ref=f7e241]: COUNTERACTION
|
||||
- generic [ref=f7e242]: Blunt
|
||||
- generic [ref=f7e243]: Reduces any damage done to you by 1/2. Round fractions up. Works on point-based or duration-based spells, or physical damage.
|
||||
- button "2 2 Wiz-War 2" [ref=f7e244] [cursor=pointer]:
|
||||
- generic [ref=f7e245]: "2"
|
||||
- generic [ref=f7e246]: "2"
|
||||
- generic [ref=f7e247]: Wiz-War
|
||||
- generic [ref=f7e248]: "2"
|
||||
- button "ATTACK L.O.S. Large Rock You may throw it. Does two points physical damage. Once thrown, it may be picked up and thrown again by any player." [ref=f7e249] [cursor=pointer]:
|
||||
- generic [ref=f7e250]: ATTACK
|
||||
- generic [ref=f7e251]: L.O.S.
|
||||
- generic [ref=f7e252]: Large Rock
|
||||
- generic [ref=f7e253]: You may throw it. Does two points physical damage. Once thrown, it may be picked up and thrown again by any player.
|
||||
- button "NEUTRAL L.O.S. Create Door Creates a permanent, locked door in any stone wall or corridor. If cast on an illusionary wall, it is under the illusion, which must be seen through in order to use the door." [ref=f7e254] [cursor=pointer]:
|
||||
- generic [ref=f7e255]: NEUTRAL
|
||||
- generic [ref=f7e256]: L.O.S.
|
||||
- generic [ref=f7e257]: Create Door
|
||||
- generic [ref=f7e258]: Creates a permanent, locked door in any stone wall or corridor. If cast on an illusionary wall, it is under the illusion, which must be seen through in order to use the door.
|
||||
- button "NEUTRAL Around the Corner You may cast any line of sight spell around one corner (up to 180 degrees)" [ref=f7e259] [cursor=pointer]:
|
||||
- generic [ref=f7e260]: NEUTRAL
|
||||
- generic [ref=f7e261]: Around the Corner
|
||||
- generic [ref=f7e262]: You may cast any line of sight spell around one corner (up to 180 degrees)
|
||||
- button "NEUTRAL Alter Ego Create a stationary double of yourself in the square you now occupy. It may use any of the spells in your hand, and you need not be in its L.O.S. to do so. Permanent until destroyed. Any damage done to it at all destroys it." [ref=f7e263] [cursor=pointer]:
|
||||
- generic [ref=f7e264]: NEUTRAL
|
||||
- generic [ref=f7e265]: Alter Ego
|
||||
- generic [ref=f7e266]: Create a stationary double of yourself in the square you now occupy. It may use any of the spells in your hand, and you need not be in its L.O.S. to do so. Permanent until destroyed. Any damage done to it at all destroys it.
|
||||
- generic [ref=f7e267]:
|
||||
- generic [ref=f7e268]: 🏆 Kestrel
|
||||
- generic [ref=f7e269]:
|
||||
- button "NEUTRAL Adrenaline Allows two attacks in one turn. Duration equals NUMBER card played." [ref=f7e270] [cursor=pointer]:
|
||||
- generic [ref=f7e271]: NEUTRAL
|
||||
- generic [ref=f7e272]: Adrenaline
|
||||
- generic [ref=f7e273]: Allows two attacks in one turn. Duration equals NUMBER card played.
|
||||
- button "COUNTERACTION Reflection A spell cast against you works 50% for both parties. Only works on point-based or duration-based spells. Round fractions up. A single lost turn, then, divided and rounded up, is a lost turn for both players." [ref=f7e274] [cursor=pointer]:
|
||||
- generic [ref=f7e275]: COUNTERACTION
|
||||
- generic [ref=f7e276]: Reflection
|
||||
- generic [ref=f7e277]: A spell cast against you works 50% for both parties. Only works on point-based or duration-based spells. Round fractions up. A single lost turn, then, divided and rounded up, is a lost turn for both players.
|
||||
- button "NEUTRAL L.O.S. Ugly You momentarily become so ugly that all opponents in L.O.S. retreat as far away as necessary to avoid L.O.S., along the shortest path available. This happens during your turn. Passage through firewalls and bushes blocks L.O.S. For multiple corridor choices, opponent rolls D4 for random direction. Affects SHRUNK and INVISIBLE opponents." [ref=f7e278] [cursor=pointer]:
|
||||
- generic [ref=f7e279]: NEUTRAL
|
||||
- generic [ref=f7e280]: L.O.S.
|
||||
- generic [ref=f7e281]: Ugly
|
||||
- generic [ref=f7e282]: You momentarily become so ugly that all opponents in L.O.S. retreat as far away as necessary to avoid L.O.S., along the shortest path available. This happens during your turn. Passage through firewalls and bushes blocks L.O.S. For multiple corridor choices, opponent rolls D4 for random direction. Affects SHRUNK and INVISIBLE opponents.
|
||||
- button "NEUTRAL Shrink You shrink. Reduces opponent's chance to hit you by 50% in any attack. Also reduces your normal movement to 2. Duration equals NUMBER card played." [ref=f7e283] [cursor=pointer]:
|
||||
- generic [ref=f7e284]: NEUTRAL
|
||||
- generic [ref=f7e285]: Shrink
|
||||
- generic [ref=f7e286]: You shrink. Reduces opponent's chance to hit you by 50% in any attack. Also reduces your normal movement to 2. Duration equals NUMBER card played.
|
||||
- 'button "Brainstone POWER: Draw two more cards, now. Hand limit is now nine cards (including this card). This card is permanent. Display when used." [ref=f7e287] [cursor=pointer]':
|
||||
- generic [ref=f7e288]: Brainstone
|
||||
- generic [ref=f7e289]: "POWER: Draw two more cards, now. Hand limit is now nine cards (including this card). This card is permanent. Display when used."
|
||||
- button "COUNTERACTION Absorb Spell You can nullify and take into your hand one spell used directly against you. Does not include NUMBER cards. Will work on other COUNTERACTIONS. REFLECTION, FULL REFLECTION, FULL SHIELD have no effect on this card." [ref=f7e290] [cursor=pointer]:
|
||||
- generic [ref=f7e291]: COUNTERACTION
|
||||
- generic [ref=f7e292]: Absorb Spell
|
||||
- generic [ref=f7e293]: You can nullify and take into your hand one spell used directly against you. Does not include NUMBER cards. Will work on other COUNTERACTIONS. REFLECTION, FULL REFLECTION, FULL SHIELD have no effect on this card.
|
||||
- button "ATTACK L.O.S. Swap Meet This spell lets you swap any two carried items (your choice) with another player. REFLECTION nullifies the spell. FULL REFLECTION lets the other player decide which objects, if any, will be swapped." [ref=f7e294] [cursor=pointer]:
|
||||
- generic [ref=f7e295]: ATTACK
|
||||
- generic [ref=f7e296]: L.O.S.
|
||||
- generic [ref=f7e297]: Swap Meet
|
||||
- generic [ref=f7e298]: This spell lets you swap any two carried items (your choice) with another player. REFLECTION nullifies the spell. FULL REFLECTION lets the other player decide which objects, if any, will be swapped.
|
||||
- button "NEUTRAL L.O.S. Trader Swap the positions of any two items that are resting on the floor, both within your line of sight. Does not overcome GLUE. Does not work on players or monsters." [ref=f7e299] [cursor=pointer]:
|
||||
- generic [ref=f7e300]: NEUTRAL
|
||||
- generic [ref=f7e301]: L.O.S.
|
||||
- generic [ref=f7e302]: Trader
|
||||
- generic [ref=f7e303]: Swap the positions of any two items that are resting on the floor, both within your line of sight. Does not overcome GLUE. Does not work on players or monsters.
|
||||
- generic "your hand" [ref=f7e304]
|
||||
@@ -1,44 +0,0 @@
|
||||
- generic [ref=f8e3]:
|
||||
- banner [ref=f8e4]:
|
||||
- generic [ref=f8e5]: Wiz-War
|
||||
- generic [ref=f8e6]: sixth edition
|
||||
- button "help & rules" [ref=f8e7] [cursor=pointer]
|
||||
- generic [ref=f8e8]: reconnecting…
|
||||
- generic [ref=f8e10]:
|
||||
- generic [ref=f8e11]: Wiz-War
|
||||
- generic [ref=f8e12]: A game of magical combat in a stone labyrinth
|
||||
- button "about this game — a labor of love" [ref=f8e13] [cursor=pointer]
|
||||
- generic [ref=f8e14]:
|
||||
- generic [ref=f8e15]: Your wizard's name
|
||||
- textbox "Your wizard's name" [ref=f8e16]:
|
||||
- /placeholder: e.g. Mordecai
|
||||
- generic [ref=f8e17]:
|
||||
- button "Create a game" [disabled] [ref=f8e18]
|
||||
- generic [ref=f8e19]: or join one
|
||||
- textbox "CODE" [ref=f8e20]
|
||||
- button "Join" [disabled] [ref=f8e21]
|
||||
- generic [ref=f8e22]:
|
||||
- generic [ref=f8e23]: "or play here, passing the device:"
|
||||
- group "number of wizards" [ref=f8e24]:
|
||||
- button "2" [ref=f8e25] [cursor=pointer]
|
||||
- button "3" [ref=f8e26] [cursor=pointer]
|
||||
- button "4" [ref=f8e27] [cursor=pointer]
|
||||
- button "5" [ref=f8e28] [cursor=pointer]
|
||||
- button "6" [ref=f8e29] [cursor=pointer]
|
||||
- button "Gather 2 wizards" [ref=f8e30] [cursor=pointer]
|
||||
- generic [ref=f8e31]:
|
||||
- 'checkbox "with Expansion Set #1" [checked] [ref=f8e32]'
|
||||
- text: "with Expansion Set #1"
|
||||
- generic [ref=f8e33]:
|
||||
- textbox "seat transfer phrase" [ref=f8e34]:
|
||||
- /placeholder: ember-troll-dagger
|
||||
- button "Claim a transferred seat" [disabled] [ref=f8e35]
|
||||
- generic [ref=f8e36]:
|
||||
- generic [ref=f8e37]:
|
||||
- generic [ref=f8e38]: your games
|
||||
- button "notify me on my turn" [ref=f8e39] [cursor=pointer]
|
||||
- generic [ref=f8e40]:
|
||||
- button "NX8Y as Some Old Guy — unreachable" [ref=f8e41] [cursor=pointer]:
|
||||
- generic [ref=f8e42]: NX8Y
|
||||
- generic [ref=f8e43]: as Some Old Guy — unreachable
|
||||
- button "×" [ref=f8e44] [cursor=pointer]
|
||||
@@ -1,44 +0,0 @@
|
||||
- generic [ref=f9e3]:
|
||||
- banner [ref=f9e4]:
|
||||
- generic [ref=f9e5]: Wiz-War
|
||||
- generic [ref=f9e6]: sixth edition
|
||||
- button "help & rules" [ref=f9e7] [cursor=pointer]
|
||||
- generic [ref=f9e8]: reconnecting…
|
||||
- generic [ref=f9e10]:
|
||||
- generic [ref=f9e11]: Wiz-War
|
||||
- generic [ref=f9e12]: A game of magical combat in a stone labyrinth
|
||||
- button "about this game — a labor of love" [ref=f9e13] [cursor=pointer]
|
||||
- generic [ref=f9e14]:
|
||||
- generic [ref=f9e15]: Your wizard's name
|
||||
- textbox "Your wizard's name" [ref=f9e16]:
|
||||
- /placeholder: e.g. Mordecai
|
||||
- generic [ref=f9e17]:
|
||||
- button "Create a game" [disabled] [ref=f9e18]
|
||||
- generic [ref=f9e19]: or join one
|
||||
- textbox "CODE" [ref=f9e20]
|
||||
- button "Join" [disabled] [ref=f9e21]
|
||||
- generic [ref=f9e22]:
|
||||
- generic [ref=f9e23]: "or play here, passing the device:"
|
||||
- group "number of wizards" [ref=f9e24]:
|
||||
- button "2" [ref=f9e25] [cursor=pointer]
|
||||
- button "3" [ref=f9e26] [cursor=pointer]
|
||||
- button "4" [ref=f9e27] [cursor=pointer]
|
||||
- button "5" [ref=f9e28] [cursor=pointer]
|
||||
- button "6" [ref=f9e29] [cursor=pointer]
|
||||
- button "Gather 2 wizards" [ref=f9e30] [cursor=pointer]
|
||||
- generic [ref=f9e31]:
|
||||
- 'checkbox "with Expansion Set #1" [checked] [ref=f9e32]'
|
||||
- text: "with Expansion Set #1"
|
||||
- generic [ref=f9e33]:
|
||||
- textbox "seat transfer phrase" [ref=f9e34]:
|
||||
- /placeholder: ember-troll-dagger
|
||||
- button "Claim a transferred seat" [disabled] [ref=f9e35]
|
||||
- generic [ref=f9e36]:
|
||||
- generic [ref=f9e37]:
|
||||
- generic [ref=f9e38]: your games
|
||||
- button "notify me on my turn" [ref=f9e39] [cursor=pointer]
|
||||
- generic [ref=f9e40]:
|
||||
- button "NX8Y as Some Old Guy — unreachable" [ref=f9e41] [cursor=pointer]:
|
||||
- generic [ref=f9e42]: NX8Y
|
||||
- generic [ref=f9e43]: as Some Old Guy — unreachable
|
||||
- button "×" [ref=f9e44] [cursor=pointer]
|
||||
@@ -1,44 +0,0 @@
|
||||
- generic [ref=f10e3]:
|
||||
- banner [ref=f10e4]:
|
||||
- generic [ref=f10e5]: Wiz-War
|
||||
- generic [ref=f10e6]: sixth edition
|
||||
- button "help & rules" [ref=f10e7] [cursor=pointer]
|
||||
- generic [ref=f10e8]: reconnecting…
|
||||
- generic [ref=f10e10]:
|
||||
- generic [ref=f10e11]: Wiz-War
|
||||
- generic [ref=f10e12]: A game of magical combat in a stone labyrinth
|
||||
- button "about this game — a labor of love" [ref=f10e13] [cursor=pointer]
|
||||
- generic [ref=f10e14]:
|
||||
- generic [ref=f10e15]: Your wizard's name
|
||||
- textbox "Your wizard's name" [ref=f10e16]:
|
||||
- /placeholder: e.g. Mordecai
|
||||
- generic [ref=f10e17]:
|
||||
- button "Create a game" [disabled] [ref=f10e18]
|
||||
- generic [ref=f10e19]: or join one
|
||||
- textbox "CODE" [ref=f10e20]
|
||||
- button "Join" [disabled] [ref=f10e21]
|
||||
- generic [ref=f10e22]:
|
||||
- generic [ref=f10e23]: "or play here, passing the device:"
|
||||
- group "number of wizards" [ref=f10e24]:
|
||||
- button "2" [ref=f10e25] [cursor=pointer]
|
||||
- button "3" [ref=f10e26] [cursor=pointer]
|
||||
- button "4" [ref=f10e27] [cursor=pointer]
|
||||
- button "5" [ref=f10e28] [cursor=pointer]
|
||||
- button "6" [ref=f10e29] [cursor=pointer]
|
||||
- button "Gather 2 wizards" [ref=f10e30] [cursor=pointer]
|
||||
- generic [ref=f10e31]:
|
||||
- 'checkbox "with Expansion Set #1" [checked] [ref=f10e32]'
|
||||
- text: "with Expansion Set #1"
|
||||
- generic [ref=f10e33]:
|
||||
- textbox "seat transfer phrase" [ref=f10e34]:
|
||||
- /placeholder: ember-troll-dagger
|
||||
- button "Claim a transferred seat" [disabled] [ref=f10e35]
|
||||
- generic [ref=f10e36]:
|
||||
- generic [ref=f10e37]:
|
||||
- generic [ref=f10e38]: your games
|
||||
- button "notify me on my turn" [ref=f10e39] [cursor=pointer]
|
||||
- generic [ref=f10e40]:
|
||||
- button "NX8Y as Some Old Guy — unreachable" [ref=f10e41] [cursor=pointer]:
|
||||
- generic [ref=f10e42]: NX8Y
|
||||
- generic [ref=f10e43]: as Some Old Guy — unreachable
|
||||
- button "×" [ref=f10e44] [cursor=pointer]
|
||||
@@ -23,6 +23,14 @@ research), installs dependencies on the droplet, and restarts the service.
|
||||
Games in progress survive: state lives in room files, and clients reconnect
|
||||
automatically.
|
||||
|
||||
Before any deploy that touches the engine, run the determinism gate:
|
||||
|
||||
deploy/verify-ledgers.sh 104.236.96.198
|
||||
|
||||
It fetches every production ledger and strictly replays it against the local
|
||||
engine; a single refused command fails the check. A room whose ledger no
|
||||
longer replays becomes unreachable after restart, so this is not optional.
|
||||
|
||||
## New droplet from scratch
|
||||
|
||||
1. `doctl compute droplet create wizwar --region nyc3 --size s-1vcpu-1gb \
|
||||
@@ -35,4 +43,10 @@ automatically.
|
||||
|
||||
- Logs: `ssh root@<ip> journalctl -u wizwar -f`
|
||||
- Restart: `ssh root@<ip> systemctl restart wizwar`
|
||||
- Backup games: `scp -r root@<ip>:/var/lib/wizwar/rooms ./rooms-backup`
|
||||
- Nightly backups: `wizwar-backup.sh` runs from root's crontab at 07:17 UTC,
|
||||
pushing /var/lib/wizwar to the `kestrel-wizwar-backups` Space (nyc3) via
|
||||
rclone. It is installed at /usr/local/bin/wizwar-backup.sh on the droplet;
|
||||
`setup-droplet.sh` does NOT install it — on a fresh droplet, copy the
|
||||
script, configure rclone (the script refuses to run while the config still
|
||||
holds its CHANGE_ME placeholder), and add the cron entry by hand.
|
||||
- One-off backup: `scp -r root@<ip>:/var/lib/wizwar/rooms ./rooms-backup`
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// Strict full-ledger replay: ANY refused command is a hard failure.
|
||||
import { readFileSync } from "fs";
|
||||
import { createGame, applyCommand } from "../packages/engine/src/game.ts";
|
||||
const lines = readFileSync(process.argv[2], "utf8").trim().split("\n").map((l) => JSON.parse(l));
|
||||
const meta = lines.find((l) => l.kind === "meta");
|
||||
const start = lines.find((l) => l.kind === "start");
|
||||
if (!start) {
|
||||
console.log(`OK ${process.argv[2].split("/").pop()}: lobby only, nothing to replay`);
|
||||
process.exit(0);
|
||||
}
|
||||
const joins = lines.filter((l) => l.kind === "join");
|
||||
const playerIds = [...new Set([meta.hostId, ...joins.map((j) => j.name)])];
|
||||
let { state } = createGame({ playerIds, seed: meta.seed, sets: start.expansion ? ["basic", "expansion1"] : ["basic"], colors: start.colors, deckRev: start.deckRev });
|
||||
let n = 0;
|
||||
for (const l of lines) {
|
||||
if (l.kind !== "command") continue;
|
||||
const r = applyCommand(state, l.playerId, l.command);
|
||||
if (!r.ok) { console.log(`FAIL ${process.argv[2].split("/").pop()} seq ${l.seq}: ${r.error}`); process.exit(1); }
|
||||
state = r.state; n++;
|
||||
}
|
||||
console.log(`OK ${process.argv[2].split("/").pop()}: ${n} commands replay clean`);
|
||||
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
# Pre-deploy determinism check: fetch every production ledger and strictly
|
||||
# replay it against the LOCAL engine. Any refused command is a hard failure.
|
||||
# Run from the repo root before deploying any engine change.
|
||||
set -euo pipefail
|
||||
HOST="${1:-104.236.96.198}"
|
||||
TMP=$(mktemp -d)
|
||||
trap 'rm -rf "$TMP"' EXIT
|
||||
scp -q "root@$HOST:/var/lib/wizwar/rooms/*.jsonl" "$TMP/"
|
||||
fails=0
|
||||
for f in "$TMP"/*.jsonl; do
|
||||
# `|| true`: a failing replay must feed the tally, not abort the loop.
|
||||
out=$(npx tsx deploy/replay-verify.mjs "$f" 2>&1 | tail -1) || true
|
||||
case "$out" in
|
||||
OK*) ;;
|
||||
*) echo "${out:-$(basename "$f"): replay crashed with no output}"; fails=$((fails+1));;
|
||||
esac
|
||||
done
|
||||
count=$(ls "$TMP" | wc -l | tr -d ' ')
|
||||
echo "--- $count ledgers checked, $fails failures"
|
||||
[ "$fails" -eq 0 ]
|
||||
@@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
# Nightly wiz-war ledger backup to DigitalOcean Spaces.
|
||||
# current/ - exact mirror of /var/lib/wizwar
|
||||
# snapshots/ - one dated copy per day, pruned after 90 days
|
||||
# Ledgers are append-only JSONL; the game server never needs stopping.
|
||||
set -u
|
||||
BUCKET="kestrel-wizwar-backups"
|
||||
SRC="/var/lib/wizwar"
|
||||
LOG="/var/log/wizwar/backup.log"
|
||||
STAMP=$(date +%Y-%m-%d)
|
||||
|
||||
if grep -q CHANGE_ME /root/.config/rclone/rclone.conf; then
|
||||
echo "$(date -Is) skipped: Spaces credentials not configured yet" >> "$LOG"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
{
|
||||
echo "=== $(date -Is) backup start"
|
||||
rclone sync "$SRC" "spaces:$BUCKET/wizwar/current" 2>&1
|
||||
rclone copy "$SRC" "spaces:$BUCKET/wizwar/snapshots/$STAMP" 2>&1
|
||||
# Prune dated snapshots older than 90 days (by directory name).
|
||||
CUTOFF=$(date -d "90 days ago" +%Y-%m-%d)
|
||||
rclone lsf "spaces:$BUCKET/wizwar/snapshots/" --dirs-only 2>/dev/null | \
|
||||
while read -r d; do
|
||||
day="${d%/}"
|
||||
if [[ "$day" < "$CUTOFF" ]]; then
|
||||
echo "pruning snapshot $day"
|
||||
rclone purge "spaces:$BUCKET/wizwar/snapshots/$day" 2>&1
|
||||
fi
|
||||
done
|
||||
echo "=== $(date -Is) backup done"
|
||||
} >> "$LOG"
|
||||
@@ -27,8 +27,6 @@ export interface Warp {
|
||||
from: { cell: Cell; side: Side };
|
||||
/** ...you arrive at this cell (entering through `side`). */
|
||||
to: { cell: Cell; side: Side };
|
||||
/** An aisle (AUTO) warp joins two edges that meet at a corner. */
|
||||
aisle?: boolean;
|
||||
}
|
||||
|
||||
export interface AssembledBoard {
|
||||
@@ -121,7 +119,7 @@ export interface AssemblyOptions {
|
||||
* openings pair straight across the map — correct for the 4p square; the
|
||||
* standard 2p column crosses its side openings and must pass pairs.
|
||||
*/
|
||||
warpPairs?: ([OpeningRef, OpeningRef] | [OpeningRef, OpeningRef, "aisle"])[];
|
||||
warpPairs?: [OpeningRef, OpeningRef][];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -206,12 +204,11 @@ export function assembleBoard(
|
||||
};
|
||||
|
||||
if (options.warpPairs) {
|
||||
for (const [a, b, kind] of options.warpPairs) {
|
||||
for (const [a, b] of options.warpPairs) {
|
||||
const ca = openingCell(a.sector, a.side);
|
||||
const cb = openingCell(b.sector, b.side);
|
||||
const aisle = kind === "aisle" ? { aisle: true as const } : {};
|
||||
warps.push({ from: { cell: ca, side: a.side }, to: { cell: cb, side: b.side }, ...aisle });
|
||||
warps.push({ from: { cell: cb, side: b.side }, to: { cell: ca, side: a.side }, ...aisle });
|
||||
warps.push({ from: { cell: ca, side: a.side }, to: { cell: cb, side: b.side } });
|
||||
warps.push({ from: { cell: cb, side: b.side }, to: { cell: ca, side: a.side } });
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < placements.length; i++) {
|
||||
@@ -363,6 +360,41 @@ export function hasWarpLineOfSight(
|
||||
to: Cell,
|
||||
blockedCells?: Record<string, true>,
|
||||
): boolean {
|
||||
return warpSightTrace(board, from, to, blockedCells) !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* How a sight line reached its target — the material for drawing it. A warp
|
||||
* trace carries the two mouths and the exact rim-crossing points (in board
|
||||
* coordinates, where cell (x,y) spans [x,x+1]) so a renderer can draw the
|
||||
* near leg to `entry` and the far leg from `exit`.
|
||||
*/
|
||||
export type SightTrace =
|
||||
| { kind: "direct" }
|
||||
| {
|
||||
kind: "warp";
|
||||
mouthA: { cell: Cell; side: Side };
|
||||
mouthB: { cell: Cell; side: Side };
|
||||
entry: { x: number; y: number };
|
||||
exit: { x: number; y: number };
|
||||
};
|
||||
|
||||
export function traceSight(
|
||||
board: AssembledBoard,
|
||||
from: Cell,
|
||||
to: Cell,
|
||||
blockedCells?: Record<string, true>,
|
||||
): SightTrace | null {
|
||||
if (hasLineOfSight(board, from, to, blockedCells)) return { kind: "direct" };
|
||||
return warpSightTrace(board, from, to, blockedCells);
|
||||
}
|
||||
|
||||
function warpSightTrace(
|
||||
board: AssembledBoard,
|
||||
from: Cell,
|
||||
to: Cell,
|
||||
blockedCells?: Record<string, true>,
|
||||
): Extract<SightTrace, { kind: "warp" }> | null {
|
||||
const DIR: Record<Side, { x: number; y: number }> = {
|
||||
N: { x: 0, y: -1 }, S: { x: 0, y: 1 }, E: { x: 1, y: 0 }, W: { x: -1, y: 0 },
|
||||
};
|
||||
@@ -375,6 +407,9 @@ export function hasWarpLineOfSight(
|
||||
// A filled mouth chokes the tunnel unless the viewer/target IS the mouth.
|
||||
if (blockedCells?.[cellKey(mouthA)] && cellKey(from) !== cellKey(mouthA)) continue;
|
||||
if (blockedCells?.[cellKey(mouthB)] && cellKey(to) !== cellKey(mouthB)) continue;
|
||||
// A wall built over either mouth seals the tunnel to sight entirely.
|
||||
if (edgeState(board, mouthA, sideA) !== "open") continue;
|
||||
if (edgeState(board, mouthB, w.to.side) !== "open") continue;
|
||||
|
||||
// Rotation taking the far board's inward direction onto sideA.
|
||||
const u = DIR[inward], v = DIR[sideA];
|
||||
@@ -423,10 +458,16 @@ export function hasWarpLineOfSight(
|
||||
segmentClear(board, Pfar.x, Pfar.y, to.x + 0.5, to.y + 0.5, blockedCells,
|
||||
[cellKey(to), cellKey(mouthB)])
|
||||
) {
|
||||
return true;
|
||||
return {
|
||||
kind: "warp",
|
||||
mouthA: { cell: mouthA, side: sideA },
|
||||
mouthB: { cell: mouthB, side: w.to.side },
|
||||
entry: P,
|
||||
exit: Pfar,
|
||||
};
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
/** The game's full line-of-sight check: direct, or through a wraparound opening. */
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import cardsData from "../data/cards.json";
|
||||
|
||||
export type CardSet = "basic" | "expansion1" | "expansion2";
|
||||
export type CardSet = "basic" | "expansion1";
|
||||
export type CardType =
|
||||
| "attack"
|
||||
| "neutral"
|
||||
|
||||
@@ -9,3 +9,4 @@ export * from "./cards";
|
||||
export * from "./setups";
|
||||
export * from "./game";
|
||||
export * from "./view";
|
||||
export * from "./automaton";
|
||||
|
||||
@@ -68,7 +68,7 @@ export function setupBoard(playerCount: number, rng: RngState): SetupResult {
|
||||
];
|
||||
const board = assembleBoard(placements, {
|
||||
warpPairs: [
|
||||
[{ sector: 0, side: "W" }, { sector: 1, side: "N" }, "aisle"], // AUTO WARP corner
|
||||
[{ sector: 0, side: "W" }, { sector: 1, side: "N" }], // AUTO WARP corner
|
||||
[{ sector: 0, side: "N" }, { sector: 2, side: "S" }],
|
||||
[{ sector: 1, side: "W" }, { sector: 2, side: "E" }],
|
||||
[{ sector: 0, side: "E" }, { sector: 1, side: "S" }],
|
||||
@@ -106,10 +106,10 @@ export function setupBoard(playerCount: number, rng: RngState): SetupResult {
|
||||
warpPairs: [
|
||||
[{ sector: 0, side: "N" }, { sector: 4, side: "S" }], // tip to tip
|
||||
[{ sector: 1, side: "W" }, { sector: 3, side: "E" }],
|
||||
[{ sector: 0, side: "W" }, { sector: 1, side: "N" }, "aisle"], // aisle-warp corners
|
||||
[{ sector: 0, side: "E" }, { sector: 3, side: "N" }, "aisle"],
|
||||
[{ sector: 4, side: "W" }, { sector: 1, side: "S" }, "aisle"],
|
||||
[{ sector: 4, side: "E" }, { sector: 3, side: "S" }, "aisle"],
|
||||
[{ sector: 0, side: "W" }, { sector: 1, side: "N" }], // aisle-warp corners
|
||||
[{ sector: 0, side: "E" }, { sector: 3, side: "N" }],
|
||||
[{ sector: 4, side: "W" }, { sector: 1, side: "S" }],
|
||||
[{ sector: 4, side: "E" }, { sector: 3, side: "S" }],
|
||||
],
|
||||
});
|
||||
return { board, rng: rngN };
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// The server sends this after every state change; clients never see the
|
||||
// deck order or other players' hands.
|
||||
|
||||
import { sightBetween, type AssembledBoard } from "./board";
|
||||
import { type CardInstance } from "./cards";
|
||||
import { SIDES, edgeKey, sightBetween, traceSight, type AssembledBoard, type Cell, type SightTrace } from "./board";
|
||||
import { cardDef, type CardInstance } from "./cards";
|
||||
import {
|
||||
boardView,
|
||||
LOS_BLOCKING_CONTENT,
|
||||
@@ -28,6 +28,8 @@ export interface PlayerPublicView {
|
||||
carriedTreasureId: string | null;
|
||||
lostTurns: number;
|
||||
extraTurns: number;
|
||||
/** Banked PASS THROUGH WALL crossings — cast openly, so public knowledge. */
|
||||
passWallCharges: number;
|
||||
displayed: CardInstance[];
|
||||
/** Which of the six physical wizard colors this player plays. */
|
||||
colorIndex: number;
|
||||
@@ -55,13 +57,26 @@ export interface GameView {
|
||||
/** Duration spells in play (public knowledge). */
|
||||
sustained: SustainedEffect[];
|
||||
squareContents: Record<string, SquareContent>;
|
||||
/** Cells whose contents are glued down (public: the cast was seen). */
|
||||
gluedCells: Record<string, true>;
|
||||
/** Safes standing open (their combination entered this turn). */
|
||||
openSafes: string[];
|
||||
groundObjects: Record<string, CardInstance[]>;
|
||||
/** The rules revision this game was dealt under. */
|
||||
deckRev: number;
|
||||
doorStates: Record<string, "jammed" | "removed">;
|
||||
/** Accumulated attack damage per edge (public — cracks show). */
|
||||
wallDamage: Record<string, number>;
|
||||
openDoorEdges: string[];
|
||||
/** Door edges held open by a standing wizard. */
|
||||
heldDoorEdges: string[];
|
||||
/** Edges conjured into being (walls, doors, firewalls) - dispellable. */
|
||||
createdEdges: string[];
|
||||
/** Illusion edges YOU know are fake (creator or saw through); others see walls. */
|
||||
knownIllusionEdges: string[];
|
||||
/** Every illusion edge and YOUR verdict on it: untested
|
||||
* shimmers, believes renders solid, mine/seesThrough are ghosts. */
|
||||
illusionEdges: Record<string, "untested" | "believes" | "seesThrough" | "mine">;
|
||||
creatures: CreatureState[];
|
||||
/** Charges left on displayed wands (public), by card instance id. */
|
||||
wandCharges: Record<string, number>;
|
||||
@@ -71,8 +86,8 @@ export interface GameView {
|
||||
outOfTurnWindow: { playerId: PlayerId; kind: "interrupt" | "opportunity-fire" } | null;
|
||||
/** CHAOS shield windows in progress (public: everyone sees it coming). */
|
||||
chaosPending: { casterId: PlayerId; queue: PlayerId[] } | null;
|
||||
/** Whether YOUR ward is set to spring. */
|
||||
yourWardArmed: boolean;
|
||||
/** A grab hangs while the treasure's owner decides their Ward. */
|
||||
wardPending: { ownerId: PlayerId; takerId: PlayerId } | null;
|
||||
/** YOUR armed ambushes. Other players' ambushes are invisible. */
|
||||
yourAmbushes: AmbushState[];
|
||||
/** Once the game is finished, every hand goes face-up on the table. */
|
||||
@@ -82,11 +97,17 @@ export interface GameView {
|
||||
export function viewFor(state: GameState, playerId: PlayerId): GameView {
|
||||
const you = state.players.find((p) => p.id === playerId);
|
||||
// Illusion walls render as real walls unless this viewer knows better.
|
||||
// Their locations are open knowledge (the cast is public at a table) —
|
||||
// what stays personal is each player's verdict.
|
||||
const base = boardView(state);
|
||||
const knownIllusionEdges: string[] = [];
|
||||
const illusionEdges: Record<string, "untested" | "believes" | "seesThrough" | "mine"> = {};
|
||||
let edges = base.edges;
|
||||
for (const [key, wall] of Object.entries(state.illusionWalls)) {
|
||||
const knows = wall.createdBy === playerId || wall.belief[playerId] === "seesThrough";
|
||||
illusionEdges[key] =
|
||||
wall.createdBy === playerId ? "mine"
|
||||
: wall.belief[playerId] ?? "untested";
|
||||
if (knows) {
|
||||
knownIllusionEdges.push(key);
|
||||
} else {
|
||||
@@ -114,6 +135,7 @@ export function viewFor(state: GameState, playerId: PlayerId): GameView {
|
||||
carriedTreasureId: p.carriedTreasureId,
|
||||
lostTurns: p.lostTurns,
|
||||
extraTurns: p.extraTurns,
|
||||
passWallCharges: p.passWallCharges,
|
||||
displayed: p.hand.filter((c) => p.displayed.includes(c.instanceId)),
|
||||
})),
|
||||
yourHand: you ? [...you.hand] : [],
|
||||
@@ -128,13 +150,19 @@ export function viewFor(state: GameState, playerId: PlayerId): GameView {
|
||||
pendingDiscard: state.pendingDiscard,
|
||||
sustained: state.sustained.map((s) => ({ ...s })),
|
||||
squareContents: { ...state.squareContents },
|
||||
gluedCells: { ...state.gluedCells },
|
||||
openSafes: [...state.openSafes],
|
||||
groundObjects: Object.fromEntries(
|
||||
Object.entries(state.groundObjects).map(([k, v]) => [k, [...v]]),
|
||||
),
|
||||
deckRev: state.config.deckRev ?? 1,
|
||||
doorStates: { ...state.doorStates },
|
||||
wallDamage: { ...state.wallDamage },
|
||||
openDoorEdges: [...state.openDoorEdges],
|
||||
heldDoorEdges: state.heldDoors.map((h) => h.key),
|
||||
createdEdges: Object.keys(state.createdEdges),
|
||||
knownIllusionEdges,
|
||||
illusionEdges,
|
||||
creatures: state.creatures.map((c) => ({ ...c, scorchedThisTurn: [...c.scorchedThisTurn] })),
|
||||
wandCharges: { ...state.wandCharges },
|
||||
dimWarps: state.dimWarps.map((w) => ({ a: { ...w.a }, b: { ...w.b } })),
|
||||
@@ -142,7 +170,7 @@ export function viewFor(state: GameState, playerId: PlayerId): GameView {
|
||||
chaosPending: state.chaosPending
|
||||
? { casterId: state.chaosPending.casterId, queue: [...state.chaosPending.queue] }
|
||||
: null,
|
||||
yourWardArmed: state.wardArmed.includes(playerId),
|
||||
wardPending: state.wardPending ? { ...state.wardPending } : null,
|
||||
yourAmbushes: state.ambushes
|
||||
.filter((a) => a.ownerId === playerId)
|
||||
.map((a) => ({ ...a, numbers: [...a.numbers] })),
|
||||
@@ -167,6 +195,57 @@ export function sightedCellsFor(view: GameView): Set<string> {
|
||||
const out = new Set<string>();
|
||||
const me = view.players.find((p) => p.id === view.you);
|
||||
if (!me) return out;
|
||||
const { board, blockers } = sightBasis(view);
|
||||
for (const key of Object.keys(board.cells)) {
|
||||
const [x, y] = key.split(",").map(Number) as [number, number];
|
||||
if (sightBetween(board, me.position, { x, y }, blockers)) out.add(key);
|
||||
}
|
||||
// VISIONSTONE lets its bearer see through exactly one wall or door —
|
||||
// any one — so a square is also sighted if removing a single edge
|
||||
// reveals it, mirroring the engine's casterLos.
|
||||
if (me.displayed.some((c) => c.cardId === "visionstone")) {
|
||||
const unseen = Object.keys(board.cells).filter((k) => !out.has(k));
|
||||
for (const edgeK of Object.keys(board.edges)) {
|
||||
if (unseen.length === 0) break;
|
||||
if ((board.edges[edgeK] ?? "open") === "open") continue;
|
||||
const edges = { ...board.edges };
|
||||
delete edges[edgeK];
|
||||
const opened = { ...board, edges };
|
||||
for (let i = unseen.length - 1; i >= 0; i--) {
|
||||
const [x, y] = unseen[i]!.split(",").map(Number) as [number, number];
|
||||
if (sightBetween(opened, me.position, { x, y }, blockers)) {
|
||||
out.add(unseen[i]!);
|
||||
unseen.splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/** The board-as-seen and sight blockers this view's sight rules run against. */
|
||||
function sightBasis(view: GameView): { board: GameView["board"]; blockers: Record<string, true> } {
|
||||
// Held-open doors are open doorways to every eye. Beyond them, the
|
||||
// viewer at a door's threshold may pull it open and peek (rules rev 2):
|
||||
// lock removed, door unlocked this turn, or PICK LOCK / MASTER KEY in
|
||||
// hand — mirroring the engine's doorsAjar.
|
||||
let board = view.board;
|
||||
const openKeys = new Set(view.heldDoorEdges);
|
||||
const me = view.players.find((p) => p.id === view.you);
|
||||
if (view.deckRev >= 2 && me?.alive) {
|
||||
const carriesKey = view.yourHand.some((c) => c.cardId === "pick-lock" || c.cardId === "master-key");
|
||||
for (const side of SIDES) {
|
||||
const key = edgeKey(me.position, side);
|
||||
if (board.edges[key] !== "door") continue;
|
||||
const workable = carriesKey && view.doorStates[key] !== "jammed";
|
||||
if (workable || view.doorStates[key] === "removed" || view.openDoorEdges.includes(key)) openKeys.add(key);
|
||||
}
|
||||
}
|
||||
if (openKeys.size > 0) {
|
||||
const edges = { ...board.edges };
|
||||
for (const k of openKeys) delete edges[k];
|
||||
board = { ...board, edges };
|
||||
}
|
||||
const blockers: Record<string, true> = {};
|
||||
for (const [key, content] of Object.entries(view.squareContents)) {
|
||||
if (LOS_BLOCKING_CONTENT[content.kind]) blockers[key] = true;
|
||||
@@ -176,16 +255,78 @@ export function sightedCellsFor(view: GameView): Set<string> {
|
||||
blockers[`${p.position.x},${p.position.y}`] = true;
|
||||
}
|
||||
}
|
||||
for (const key of Object.keys(view.board.cells)) {
|
||||
const [x, y] = key.split(",").map(Number) as [number, number];
|
||||
if (sightBetween(view.board, me.position, { x, y }, blockers)) out.add(key);
|
||||
return { board, blockers };
|
||||
}
|
||||
|
||||
/**
|
||||
* How one square sees another under this viewer's knowledge of the board
|
||||
* (believed illusion walls block; held doors admit). Null when no sight
|
||||
* exists — the renderer's material for drawing the line an attack traveled.
|
||||
*/
|
||||
export function traceSightFor(view: GameView, from: Cell, to: Cell): SightTrace | null {
|
||||
const { board, blockers } = sightBasis(view);
|
||||
return traceSight(board, from, to, blockers);
|
||||
}
|
||||
|
||||
/**
|
||||
* AROUND THE CORNER's bent sight, from this viewer's knowledge: the caster
|
||||
* sees a middle square which sees the target — mirroring the engine's
|
||||
* bentLos so a client can predict whether the modifier will land.
|
||||
*/
|
||||
export function bentSightFor(view: GameView, from: Cell, to: Cell): boolean {
|
||||
const { board, blockers } = sightBasis(view);
|
||||
if (sightBetween(board, from, to, blockers)) return true;
|
||||
for (const key of Object.keys(board.cells)) {
|
||||
if (blockers[key]) continue;
|
||||
const [mx, my] = key.split(",").map(Number) as [number, number];
|
||||
const mid = { x: mx, y: my };
|
||||
if (sightBetween(board, from, mid, blockers) && sightBetween(board, mid, to, blockers)) {
|
||||
return true;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The sight line behind the attack currently on the stack — the board's
|
||||
* answer to "how can he even see me?". Null when nothing should draw:
|
||||
* no stack, a creature's or physical attack, a non-LOS card, attacker and
|
||||
* defender sharing a square, or no sight under this viewer's knowledge
|
||||
* (a believed illusion wall can honestly hide the line).
|
||||
*/
|
||||
export function stackSightTrace(
|
||||
view: GameView,
|
||||
): { from: Cell; to: Cell; trace: SightTrace; bend?: { mid: Cell; trace: SightTrace } } | null {
|
||||
const stack = view.stack;
|
||||
if (!stack || stack.creatureId) return null;
|
||||
if (!stack.attackCard || cardDef(stack.attackCard.cardId).los !== true) return null;
|
||||
const a = view.players.find((p) => p.id === stack.attackerId);
|
||||
const d = view.players.find((p) => p.id === stack.defenderId);
|
||||
if (!a || !d) return null;
|
||||
if (a.position.x === d.position.x && a.position.y === d.position.y) return null;
|
||||
const trace = traceSightFor(view, a.position, d.position);
|
||||
if (trace) return { from: a.position, to: d.position, trace };
|
||||
// AROUND THE CORNER: no straight line exists — find a middle square both
|
||||
// ends can see and draw the sight leg by leg, so the table can audit the
|
||||
// needle instead of doubting it.
|
||||
if (stack.bentCorner) {
|
||||
for (const key of Object.keys(view.board.cells)) {
|
||||
const [mx, my] = key.split(",").map(Number) as [number, number];
|
||||
const mid = { x: mx, y: my };
|
||||
if ((mid.x === a.position.x && mid.y === a.position.y) ||
|
||||
(mid.x === d.position.x && mid.y === d.position.y)) continue;
|
||||
const leg1 = traceSightFor(view, a.position, mid);
|
||||
if (!leg1) continue;
|
||||
const leg2 = traceSightFor(view, mid, d.position);
|
||||
if (leg2) return { from: a.position, to: d.position, trace: leg1, bend: { mid, trace: leg2 } };
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
const CREATION_CARD_IDS = new Set([
|
||||
"fill-square-with-stone", "thornbush", "killer-ooze", "rosebush", "dust-cloud",
|
||||
"fill-square-with-slime", "create-pit", "handful-of-tacks", "glue", "safe", "boobytrap",
|
||||
"fill-square-with-slime", "create-pit", "handful-of-tacks",
|
||||
]);
|
||||
const SUMMON_CARD_IDS = new Set([
|
||||
"troll", "skeleton", "wraith", "fire-imp", "democratic-monster", "shadow",
|
||||
@@ -209,7 +350,6 @@ export function eligibleCellsFor(view: GameView, cardId: string): Set<string> |
|
||||
const out = new Set<string>();
|
||||
for (const k of cells) {
|
||||
if (view.squareContents[k]) continue;
|
||||
const [x, y] = k.split(",").map(Number) as [number, number];
|
||||
if (view.board.homes.some((h) => key(h.x, h.y) === k)) continue;
|
||||
if (view.players.some((p) => p.alive && key(p.position.x, p.position.y) === k)) continue;
|
||||
if (view.treasures.some((t) => t.position && key(t.position.x, t.position.y) === k)) continue;
|
||||
@@ -217,7 +357,6 @@ export function eligibleCellsFor(view: GameView, cardId: string): Set<string> |
|
||||
if (view.dimWarps.some((w) => key(w.a.x, w.a.y) === k || key(w.b.x, w.b.y) === k)) continue;
|
||||
if (!sighted.has(k)) continue;
|
||||
out.add(k);
|
||||
void x; void y;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@@ -256,11 +395,52 @@ export function eligibleCellsFor(view: GameView, cardId: string): Set<string> |
|
||||
return out;
|
||||
}
|
||||
|
||||
if (cardId === "boobytrap") {
|
||||
// Tokens go anywhere on the board except solid stone — no sight needed;
|
||||
// a trap you can see coming is a poor trap.
|
||||
return new Set(cells.filter((k) => view.squareContents[k]?.kind !== "stone"));
|
||||
}
|
||||
|
||||
if (cardId === "glue" || cardId === "safe") {
|
||||
// Both seize a square that HOLDS something — a loose object or an
|
||||
// unclaimed treasure — within the caster's sight. The safe additionally
|
||||
// needs the square clear of terrain to build around its prize.
|
||||
const out = new Set<string>();
|
||||
for (const k of cells) {
|
||||
if (cardId === "safe" && view.squareContents[k]) continue;
|
||||
const hasObject =
|
||||
(view.groundObjects[k] ?? []).length > 0 ||
|
||||
view.treasures.some((t) => t.position && !t.carriedBy && key(t.position.x, t.position.y) === k);
|
||||
if (!hasObject) continue;
|
||||
if (!sighted.has(k)) continue;
|
||||
out.add(k);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
if (cardId === "thumb-of-god") {
|
||||
// The die is aimed by sight; where it lands after drifting is fate's.
|
||||
return sighted;
|
||||
}
|
||||
if (cardId === "stone-to-water") {
|
||||
return new Set(cells.filter((k) => view.squareContents[k]?.kind === "stone"));
|
||||
// The cast demands sight of the stone block, so only sighted ones light.
|
||||
// The card equally targets stone WALLS — edges the cell-shadow cannot
|
||||
// express — so with no stone square in view, dimming would shroud the
|
||||
// true targets: light everything instead.
|
||||
const out = new Set(
|
||||
cells.filter((k) => view.squareContents[k]?.kind === "stone" && sighted.has(k)),
|
||||
);
|
||||
return out.size > 0 ? out : null;
|
||||
}
|
||||
if (cardId === "dispel-creation") {
|
||||
return new Set(cells.filter((k) => view.squareContents[k] != null));
|
||||
// Anything created — terrain or creature, whoever made it — in sight.
|
||||
const out = new Set<string>();
|
||||
for (const k of cells) {
|
||||
const created = view.squareContents[k] != null ||
|
||||
view.creatures.some((c) => key(c.position.x, c.position.y) === k);
|
||||
if (created && sighted.has(k)) out.add(k);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,981 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
applyCommand,
|
||||
createGame,
|
||||
sustainedOn,
|
||||
type GameState,
|
||||
type PlayerId,
|
||||
} from "../src/game";
|
||||
import { cellKey, edgeKey } from "../src/board";
|
||||
import { sightedCellsFor, viewFor } from "../src/view";
|
||||
import { automatonCommand, automatonFallback, type AutomatonStyle, type AutomatonTier } from "../src/automaton";
|
||||
import { pushSustained } from "./helpers";
|
||||
|
||||
/** Whose input does the maze want right now? */
|
||||
function actingSeat(state: GameState): PlayerId {
|
||||
return (
|
||||
state.wardPending?.ownerId ??
|
||||
state.stack?.waitingOn ??
|
||||
state.pendingDiscard ??
|
||||
state.chaosPending?.queue[0] ??
|
||||
state.outOfTurnWindow?.playerId ??
|
||||
state.players[state.turn.activeIndex]!.id
|
||||
);
|
||||
}
|
||||
|
||||
/** Drive a full bot-vs-bot game; returns the final state and command count. */
|
||||
function playOut(
|
||||
seed: number, players: number, expansion = true,
|
||||
styles: AutomatonStyle[] = [], tiers: AutomatonTier[] = [],
|
||||
) {
|
||||
const ids = Array.from({ length: players }, (_, i) => `bot${i + 1}`);
|
||||
const styleOf = new Map(ids.map((id, i) => [id, styles[i] ?? "hunter"]));
|
||||
const tierOf = new Map(ids.map((id, i) => [id, tiers[i] ?? "archmage"]));
|
||||
let { state } = createGame({
|
||||
playerIds: ids,
|
||||
seed,
|
||||
sets: expansion ? ["basic", "expansion1"] : ["basic"],
|
||||
});
|
||||
let commands = 0;
|
||||
let stuck = 0;
|
||||
const CAP = 4000;
|
||||
while (state.phase === "playing" && commands < CAP) {
|
||||
const seat = actingSeat(state);
|
||||
const view = viewFor(state, seat);
|
||||
const tier = tierOf.get(seat);
|
||||
const chosen = automatonCommand(view, styleOf.get(seat), tier);
|
||||
const cmd = chosen ?? automatonFallback(view, tier);
|
||||
let r = applyCommand(state, seat, cmd);
|
||||
if (!r.ok) {
|
||||
// Retry with the fallback only if the fallback was not what just failed.
|
||||
const fb = automatonFallback(view, tier);
|
||||
if (chosen) r = applyCommand(state, seat, fb);
|
||||
if (!r.ok) {
|
||||
stuck++;
|
||||
if (stuck > 3) {
|
||||
throw new Error(
|
||||
`automaton stuck at seat ${seat} after ${commands} commands: ` +
|
||||
`${JSON.stringify(cmd)} -> ${JSON.stringify(fb)} both refused (${r.error})`,
|
||||
);
|
||||
}
|
||||
// Last-ditch: burn the turn structure forward.
|
||||
r = applyCommand(state, seat, { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) r = applyCommand(state, seat, { type: "pass" });
|
||||
if (!r.ok) throw new Error(`unrecoverable at ${seat}: ${r.error}`);
|
||||
}
|
||||
} else {
|
||||
stuck = 0;
|
||||
}
|
||||
state = r.state;
|
||||
commands++;
|
||||
}
|
||||
return { state, commands };
|
||||
}
|
||||
|
||||
describe("automaton vs automaton", () => {
|
||||
it("two clockwork wizards fight a game to its end", () => {
|
||||
const { state } = playOut(11, 2);
|
||||
expect(state.phase).toBe("finished");
|
||||
expect(state.winner).not.toBeNull();
|
||||
});
|
||||
|
||||
it("holds up across many seeds without wedging", () => {
|
||||
let finished = 0;
|
||||
for (const seed of [1, 2, 3, 5, 8, 13, 21, 34]) {
|
||||
const { state } = playOut(seed, 2);
|
||||
if (state.phase === "finished") finished++;
|
||||
}
|
||||
// Cautious clockwork can stall a maze; most games must still conclude.
|
||||
expect(finished).toBeGreaterThanOrEqual(6);
|
||||
});
|
||||
|
||||
it("a full table of four automatons concludes", () => {
|
||||
const { state } = playOut(7, 4);
|
||||
expect(state.phase).toBe("finished");
|
||||
});
|
||||
|
||||
it("the apprentice handicap bites where cards decide: combat mirrors", () => {
|
||||
// Deterministic across these seeds: same brains, same dice.
|
||||
let arch = 0, appr = 0;
|
||||
for (const seed of [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233]) {
|
||||
const { state } = playOut(seed, 2, true,
|
||||
["berserker", "berserker"], ["archmage", "apprentice"]);
|
||||
if (state.winner === "bot1") arch++;
|
||||
if (state.winner === "bot2") appr++;
|
||||
}
|
||||
expect(arch).toBeGreaterThan(appr);
|
||||
});
|
||||
|
||||
it("every temperament finishes its wars", () => {
|
||||
for (const styles of [
|
||||
["berserker", "hunter"], ["worrier", "hunter"], ["berserker", "worrier"],
|
||||
] as AutomatonStyle[][]) {
|
||||
let finished = 0;
|
||||
for (const seed of [3, 17, 29]) {
|
||||
const { state } = playOut(seed, 2, true, styles);
|
||||
if (state.phase === "finished") finished++;
|
||||
}
|
||||
expect(finished).toBeGreaterThanOrEqual(2);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function underAttack(attackId: string, defenderHand: { instanceId: string; cardId: string }[], rig?: (s: GameState, defender: string) => void) {
|
||||
let { state } = createGame({ playerIds: ["human", "bot"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
// burn round 1
|
||||
for (let i = 0; i < 2; i++) {
|
||||
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(`setup: ${r.error}`);
|
||||
state = r.state;
|
||||
}
|
||||
while (actingSeat(state) !== "human") {
|
||||
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(`setup: ${r.error}`);
|
||||
state = r.state;
|
||||
}
|
||||
const human = state.players.find((p) => p.id === "human")!;
|
||||
const bot = state.players.find((p) => p.id === "bot")!;
|
||||
bot.position = { ...human.position };
|
||||
defenderHand.forEach((c, i) => { bot.hand[i] = c; });
|
||||
human.hand[0] = { instanceId: `${attackId}#A`, cardId: attackId };
|
||||
rig?.(state, "bot");
|
||||
const r = applyCommand(state, "human", {
|
||||
type: "cast", instanceId: `${attackId}#A`, target: { kind: "player", playerId: "bot" },
|
||||
...(attackId === "drop-object" ? { params: { cardId: "dagger" } } : {}),
|
||||
});
|
||||
if (!r.ok) throw new Error(`setup: ${r.error}`);
|
||||
return r.state;
|
||||
}
|
||||
|
||||
describe("the clockwork does not waste counters on pointless targets", () => {
|
||||
it("passes on drop-object rather than absorbing nothing", () => {
|
||||
const state = underAttack("drop-object", [
|
||||
{ instanceId: "absorb#T", cardId: "absorb" },
|
||||
{ instanceId: "blunt#T", cardId: "blunt" },
|
||||
{ instanceId: "dagger#T", cardId: "dagger" },
|
||||
]);
|
||||
const cmd = automatonCommand(viewFor(state, "bot"), "hunter", "archmage");
|
||||
expect(cmd).toEqual({ type: "pass" });
|
||||
});
|
||||
|
||||
it("shields a drop-object aimed at its carried treasure", () => {
|
||||
const state = underAttack("drop-object", [
|
||||
{ instanceId: "full-shield#T", cardId: "full-shield" },
|
||||
{ instanceId: "dagger#T", cardId: "dagger" },
|
||||
], (s, defender) => {
|
||||
const d = s.players.find((p) => p.id === defender)!;
|
||||
const t = s.treasures.find((t) => t.owner !== defender)!;
|
||||
t.position = null; t.carriedBy = defender; d.carriedTreasureId = t.id;
|
||||
});
|
||||
const cmd = automatonCommand(viewFor(state, "bot"), "hunter", "archmage");
|
||||
expect(cmd).toEqual({ type: "counteract", instanceId: "full-shield#T" });
|
||||
});
|
||||
});
|
||||
|
||||
describe("the clockwork guards gold only within sight", () => {
|
||||
// A refused cast forfeits the bot's whole turn (the fallback is endTurn),
|
||||
// so SAFE must only ever be offered where the engine's sight rule allows it.
|
||||
function goldOnTheFloor() {
|
||||
let { state } = createGame({ playerIds: ["bot", "foe"], seed: 7, sets: ["basic", "expansion1"] });
|
||||
while (actingSeat(state) !== "bot") {
|
||||
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
const bot = state.players.find((p) => p.id === "bot")!;
|
||||
const foe = state.players.find((p) => p.id === "foe")!;
|
||||
foe.position = { ...bot.position };
|
||||
bot.hand = [{ instanceId: "safe#T", cardId: "safe" }];
|
||||
const gold = state.treasures.find((t) => t.owner === "bot")!;
|
||||
gold.carriedBy = null;
|
||||
return { state, bot, gold };
|
||||
}
|
||||
|
||||
it("never blind-casts SAFE at a treasure out of sight", () => {
|
||||
const { state, bot, gold } = goldOnTheFloor();
|
||||
const sighted = sightedCellsFor(viewFor(state, "bot"));
|
||||
const hidden = Object.keys(state.board.cells).find(
|
||||
(k) => !sighted.has(k) && !state.squareContents[k],
|
||||
)!;
|
||||
const [x, y] = hidden.split(",").map(Number);
|
||||
gold.position = { x: x!, y: y! };
|
||||
|
||||
const cmd = automatonCommand(viewFor(state, "bot"), "hunter", "archmage");
|
||||
// Whatever the brain picks, the engine must accept it — a refusal
|
||||
// forfeits the bot's turn.
|
||||
const chosen = cmd ?? automatonFallback(viewFor(state, "bot"), "archmage");
|
||||
expect(applyCommand(state, "bot", chosen).ok).toBe(true);
|
||||
});
|
||||
|
||||
it("still locks up gold it can see", () => {
|
||||
const { state, bot, gold } = goldOnTheFloor();
|
||||
const sighted = sightedCellsFor(viewFor(state, "bot"));
|
||||
const seen = [...sighted].find(
|
||||
(k) => k !== cellKey(bot.position) && !state.squareContents[k],
|
||||
)!;
|
||||
const [x, y] = seen.split(",").map(Number);
|
||||
gold.position = { x: x!, y: y! };
|
||||
|
||||
const cmd = automatonCommand(viewFor(state, "bot"), "hunter", "archmage");
|
||||
expect(cmd).toEqual({
|
||||
type: "cast", instanceId: "safe#T",
|
||||
target: { kind: "cell", cell: gold.position },
|
||||
});
|
||||
expect(applyCommand(state, "bot", cmd!).ok).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("the clockwork honors IDIOT's march", () => {
|
||||
// The engine never steers a cursed wizard's feet; the duty is the brain's.
|
||||
function cursedBot() {
|
||||
let { state } = createGame({ playerIds: ["bot", "foe"], seed: 7, sets: ["basic", "expansion1"] });
|
||||
// Past round 1 (no combat) and around to the bot's turn.
|
||||
for (let i = 0; i < 2; i++) {
|
||||
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
while (actingSeat(state) !== "bot") {
|
||||
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
pushSustained(state, {
|
||||
id: "fx-idiot", cardId: "idiot", casterId: "foe", targetId: "bot",
|
||||
remainingTurns: 9999, data: {},
|
||||
});
|
||||
return state;
|
||||
}
|
||||
|
||||
it("marches to its own gold until the curse lifts", () => {
|
||||
let state = cursedBot();
|
||||
state.players.find((p) => p.id === "bot")!.hand = [];
|
||||
// A walled route can cost more steps than one turn's allowance; the
|
||||
// march may span turns (the foe just passes).
|
||||
for (let i = 0; i < 30 && sustainedOn(state, "bot", "idiot").length > 0; i++) {
|
||||
const seat = actingSeat(state);
|
||||
const cmd = seat === "bot"
|
||||
? automatonCommand(viewFor(state, "bot"), "hunter", "archmage")
|
||||
?? automatonFallback(viewFor(state, "bot"), "archmage")
|
||||
: { type: "endTurn", draw: 0 } as const;
|
||||
const r = applyCommand(state, seat, cmd);
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
expect(sustainedOn(state, "bot", "idiot").length).toBe(0);
|
||||
});
|
||||
|
||||
it("shakes its gold from a thief's arms with DROP OBJECT", () => {
|
||||
const state = cursedBot();
|
||||
const bot = state.players.find((p) => p.id === "bot")!;
|
||||
const thief = state.players.find((p) => p.id === "foe")!;
|
||||
thief.position = { ...bot.position };
|
||||
const own = state.treasures.find((t) => t.owner === "bot")!;
|
||||
own.carriedBy = "foe";
|
||||
own.position = null;
|
||||
thief.carriedTreasureId = own.id;
|
||||
bot.hand = [{ instanceId: "drop-object#T", cardId: "drop-object" }];
|
||||
const cmd = automatonCommand(viewFor(state, "bot"), "hunter", "archmage");
|
||||
expect(cmd).toEqual({
|
||||
type: "cast", instanceId: "drop-object#T",
|
||||
target: { kind: "player", playerId: "foe" }, params: { cardId: "treasure" },
|
||||
});
|
||||
expect(applyCommand(state, "bot", cmd!).ok).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("the clockwork wades hazards rather than surrender", () => {
|
||||
it("takes the slime road when no clean path to anything exists", () => {
|
||||
let { state } = createGame({ playerIds: ["bot", "foe"], seed: 7, sets: ["basic", "expansion1"] });
|
||||
while (actingSeat(state) !== "bot") {
|
||||
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
const bot = state.players.find((p) => p.id === "bot")!;
|
||||
bot.hand = [];
|
||||
// Wall the bot into its square except one side; slime that one exit.
|
||||
const sides = ["N", "S", "E", "W"] as const;
|
||||
const board = state.board;
|
||||
const open = sides.filter((s) => {
|
||||
const n = { x: bot.position.x + (s === "E" ? 1 : s === "W" ? -1 : 0),
|
||||
y: bot.position.y + (s === "S" ? 1 : s === "N" ? -1 : 0) };
|
||||
return board.cells[cellKey(n)] !== undefined;
|
||||
});
|
||||
const exit = open[0]!;
|
||||
for (const s2 of sides) {
|
||||
if (s2 !== exit) state.edgeOverrides[edgeKey(bot.position, s2)] = "wall";
|
||||
else state.edgeOverrides[edgeKey(bot.position, s2)] = "open";
|
||||
}
|
||||
const beyond = { x: bot.position.x + (exit === "E" ? 1 : exit === "W" ? -1 : 0),
|
||||
y: bot.position.y + (exit === "S" ? 1 : exit === "N" ? -1 : 0) };
|
||||
state.squareContents[cellKey(beyond)] = { kind: "slime", damage: 0, createdBy: "foe" };
|
||||
const cmd = automatonCommand(viewFor(state, "bot"), "hunter", "archmage");
|
||||
expect(cmd).toEqual({ type: "move", direction: exit });
|
||||
expect(applyCommand(state, "bot", cmd!).ok).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("the clockwork respects the bush's shelter", () => {
|
||||
function faceOffWithFireball() {
|
||||
let { state } = createGame({ playerIds: ["bot", "foe"], seed: 7, sets: ["basic", "expansion1"] });
|
||||
for (let i = 0; i < 2; i++) {
|
||||
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
while (actingSeat(state) !== "bot") {
|
||||
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
const bot = state.players.find((p) => p.id === "bot")!;
|
||||
const foe = state.players.find((p) => p.id === "foe")!;
|
||||
foe.position = { ...bot.position };
|
||||
bot.hand = [{ instanceId: "fireball#T", cardId: "fireball" }];
|
||||
return { state, bot, foe };
|
||||
}
|
||||
|
||||
it("never aims at a wizard sheltered in a thornbush", () => {
|
||||
const { state, foe } = faceOffWithFireball();
|
||||
state.squareContents[cellKey(foe.position)] = { kind: "thornbush", damage: 0, createdBy: "foe" };
|
||||
const cmd = automatonCommand(viewFor(state, "bot"), "hunter", "archmage")
|
||||
?? automatonFallback(viewFor(state, "bot"), "archmage");
|
||||
// Whatever it picks, the engine must accept it — and it must not be
|
||||
// the refused fireball that would burn the whole turn.
|
||||
expect(cmd).not.toMatchObject({ type: "cast", instanceId: "fireball#T" });
|
||||
expect(applyCommand(state, "bot", cmd).ok).toBe(true);
|
||||
});
|
||||
|
||||
it("never attacks out of its own bush", () => {
|
||||
const { state, bot, foe } = faceOffWithFireball();
|
||||
foe.position = { ...bot.position };
|
||||
state.squareContents[cellKey(bot.position)] = { kind: "thornbush", damage: 0, createdBy: "foe" };
|
||||
const cmd = automatonCommand(viewFor(state, "bot"), "hunter", "archmage")
|
||||
?? automatonFallback(viewFor(state, "bot"), "archmage");
|
||||
expect(cmd).not.toMatchObject({ type: "cast", instanceId: "fireball#T" });
|
||||
expect(applyCommand(state, "bot", cmd).ok).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("a clogged hand gets shed, not hoarded", () => {
|
||||
it("the bot discards dead weight so the end-of-turn draw has room", () => {
|
||||
let { state } = createGame({ playerIds: ["bot", "other"], seed: 42, sets: ["basic"] });
|
||||
while (actingSeat(state) !== "bot") {
|
||||
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
const bot = state.players.find((p) => p.id === "bot")!;
|
||||
// Seven situational neutrals the brain has no play for: a dead hand.
|
||||
bot.hand = Array.from({ length: 7 }, (_, i) => (
|
||||
{ instanceId: `rotate-sector#${i}`, cardId: "rotate-sector" }
|
||||
));
|
||||
// Walk the bot's turn until it wants to end: it must shed before drawing.
|
||||
for (let guard = 0; guard < 30; guard++) {
|
||||
const view = viewFor(state, "bot");
|
||||
const cmd = automatonCommand(view, "hunter", "archmage")!;
|
||||
if (cmd.type === "discard") {
|
||||
expect(cmd.instanceIds.length).toBe(2);
|
||||
const r = applyCommand(state, "bot", cmd);
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
const next = automatonCommand(viewFor(state, "bot"), "hunter", "archmage")!;
|
||||
expect(next).toEqual({ type: "endTurn", draw: 2 });
|
||||
return;
|
||||
}
|
||||
if (cmd.type === "endTurn") throw new Error("ended the turn without shedding a dead hand");
|
||||
const r = applyCommand(state, "bot", cmd);
|
||||
if (!r.ok) throw new Error(`${cmd.type}: ${r.error}`);
|
||||
state = r.state;
|
||||
}
|
||||
throw new Error("never reached the end of the turn");
|
||||
});
|
||||
});
|
||||
|
||||
describe("the clockwork honors absorb's fine print", () => {
|
||||
it("answers NO SPELL with blunt, never absorb — durations soak no points", () => {
|
||||
const state = underAttack("no-spell", [
|
||||
{ instanceId: "absorb#T", cardId: "absorb" },
|
||||
{ instanceId: "blunt#T", cardId: "blunt" },
|
||||
]);
|
||||
const cmd = automatonCommand(viewFor(state, "bot"), "hunter", "archmage");
|
||||
expect(cmd).toEqual({ type: "counteract", instanceId: "blunt#T" });
|
||||
});
|
||||
});
|
||||
|
||||
describe("the clockwork wields destroy wall", () => {
|
||||
it("blasts its way out when no road leads to the gold", () => {
|
||||
let { state } = createGame({ playerIds: ["bot", "other"], seed: 42, sets: ["basic"] });
|
||||
while (actingSeat(state) !== "bot") {
|
||||
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
const bot = state.players.find((p) => p.id === "bot")!;
|
||||
// Brick the bot into a one-square cell far from everything.
|
||||
bot.position = { x: 4, y: 4 };
|
||||
for (const side of ["N", "S", "E", "W"] as const) {
|
||||
state.edgeOverrides[edgeKey(bot.position, side)] = "wall";
|
||||
}
|
||||
state.players.find((p) => p.id === "other")!.position = { x: 0, y: 0 };
|
||||
bot.hand[0] = { instanceId: "destroy-wall#T", cardId: "destroy-wall" };
|
||||
const cmd = automatonCommand(viewFor(state, "bot"), "hunter", "archmage");
|
||||
expect(cmd).toMatchObject({ type: "cast", instanceId: "destroy-wall#T" });
|
||||
// And the engine accepts the blast it chose.
|
||||
const r = applyCommand(state, "bot", cmd!);
|
||||
expect(r.ok).toBe(true);
|
||||
});
|
||||
|
||||
it("values destroy wall above the chaff when forced to discard", () => {
|
||||
let { state } = createGame({ playerIds: ["bot", "other"], seed: 42, sets: ["basic"] });
|
||||
const bot = state.players.find((p) => p.id === "bot")!;
|
||||
bot.hand = [
|
||||
{ instanceId: "destroy-wall#T", cardId: "destroy-wall" },
|
||||
{ instanceId: "trader#T", cardId: "trader" },
|
||||
{ instanceId: "strength#T", cardId: "strength" },
|
||||
{ instanceId: "adrenaline#T", cardId: "adrenaline" },
|
||||
{ instanceId: "full-shield#T", cardId: "full-shield" },
|
||||
{ instanceId: "fireball#T", cardId: "fireball" },
|
||||
{ instanceId: "number-3#T", cardId: "number-3" },
|
||||
{ instanceId: "troll#T", cardId: "troll" },
|
||||
];
|
||||
state.pendingDiscard = "bot";
|
||||
const cmd = automatonCommand(viewFor(state, "bot"), "hunter", "archmage");
|
||||
expect(cmd?.type).toBe("discard");
|
||||
if (cmd?.type === "discard") {
|
||||
expect(cmd.instanceIds).not.toContain("destroy-wall#T");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("the clockwork wields pass through wall", () => {
|
||||
it("banks a crossing when bricked in, then steps through the wall", () => {
|
||||
let { state } = createGame({ playerIds: ["bot", "other"], seed: 42, sets: ["basic"] });
|
||||
while (actingSeat(state) !== "bot") {
|
||||
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
const bot = state.players.find((p) => p.id === "bot")!;
|
||||
bot.position = { x: 4, y: 4 };
|
||||
for (const side of ["N", "S", "E", "W"] as const) {
|
||||
state.edgeOverrides[edgeKey(bot.position, side)] = "wall";
|
||||
}
|
||||
state.players.find((p) => p.id === "other")!.position = { x: 0, y: 0 };
|
||||
bot.hand[0] = { instanceId: "pass-through-wall#T", cardId: "pass-through-wall" };
|
||||
const cast = automatonCommand(viewFor(state, "bot"), "hunter", "archmage");
|
||||
expect(cast).toMatchObject({ type: "cast", instanceId: "pass-through-wall#T" });
|
||||
let r = applyCommand(state, "bot", cast!);
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
expect(state.players.find((p) => p.id === "bot")!.passWallCharges).toBe(1);
|
||||
// The charge is spent on a step through the bricks.
|
||||
const step = automatonCommand(viewFor(state, "bot"), "hunter", "archmage");
|
||||
expect(step?.type).toBe("move");
|
||||
r = applyCommand(state, "bot", step!);
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
const after = r.state.players.find((p) => p.id === "bot")!;
|
||||
expect(cellKey(after.position)).not.toBe(cellKey({ x: 4, y: 4 }));
|
||||
expect(after.passWallCharges).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("the clockwork denies the road", () => {
|
||||
it("walls a thief's corridor when its treasure is being carried home", () => {
|
||||
let { state } = createGame({ playerIds: ["bot", "other"], seed: 42, sets: ["basic"] });
|
||||
while (actingSeat(state) !== "bot") {
|
||||
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
const bot = state.players.find((p) => p.id === "bot")!;
|
||||
const thief = state.players.find((p) => p.id === "other")!;
|
||||
// The thief carries the bot's treasure down a one-lane tube to its home.
|
||||
const t = state.treasures.find((t) => t.owner === "bot")!;
|
||||
t.position = null;
|
||||
t.carriedBy = "other";
|
||||
thief.carriedTreasureId = t.id;
|
||||
thief.position = { x: 4, y: 2 };
|
||||
thief.home = { x: 4, y: 6 };
|
||||
for (let y = 2; y <= 6; y++) {
|
||||
state.edgeOverrides[edgeKey({ x: 4, y }, "E")] = "wall";
|
||||
state.edgeOverrides[edgeKey({ x: 4, y }, "W")] = "wall";
|
||||
}
|
||||
state.edgeOverrides[edgeKey({ x: 4, y: 6 }, "S")] = "wall";
|
||||
for (let y = 2; y <= 5; y++) {
|
||||
state.edgeOverrides[edgeKey({ x: 4, y }, "S")] = "open";
|
||||
}
|
||||
bot.position = { x: 4, y: 4 };
|
||||
bot.hand = [{ instanceId: "create-wall#T", cardId: "create-wall" }];
|
||||
const cmd = automatonCommand(viewFor(state, "bot"), "hunter", "archmage");
|
||||
expect(cmd).toMatchObject({ type: "cast", instanceId: "create-wall#T" });
|
||||
const r = applyCommand(state, "bot", cmd!);
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
// The blockade must actually sever the thief's road home.
|
||||
const target = (cmd as { target: { cell: { x: number; y: number }; side: string } }).target;
|
||||
expect(["N", "S"]).toContain(target.side);
|
||||
expect(target.cell.x).toBe(4);
|
||||
});
|
||||
});
|
||||
|
||||
describe("the widened spellbook", () => {
|
||||
it("dispels a conjured wall standing between it and the only road", () => {
|
||||
let { state } = createGame({ playerIds: ["bot", "other"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
while (actingSeat(state) !== "bot") {
|
||||
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
const bot = state.players.find((p) => p.id === "bot")!;
|
||||
bot.position = { x: 4, y: 4 };
|
||||
for (const side of ["N", "S", "E", "W"] as const) {
|
||||
const k = edgeKey(bot.position, side);
|
||||
state.edgeOverrides[k] = "wall";
|
||||
state.createdEdges[k] = true;
|
||||
}
|
||||
state.players.find((p) => p.id === "other")!.position = { x: 0, y: 0 };
|
||||
bot.hand = [{ instanceId: "dispel-creation#T", cardId: "dispel-creation" }];
|
||||
const cmd = automatonCommand(viewFor(state, "bot"), "hunter", "archmage");
|
||||
expect(cmd).toMatchObject({ type: "cast", instanceId: "dispel-creation#T" });
|
||||
const r = applyCommand(state, "bot", cmd!);
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
});
|
||||
|
||||
it("offers a buddy pact to the hound at its heels", () => {
|
||||
let { state } = createGame({ playerIds: ["bot", "other"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
while (actingSeat(state) !== "bot") {
|
||||
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
const bot = state.players.find((p) => p.id === "bot")!;
|
||||
const hound = state.players.find((p) => p.id === "other")!;
|
||||
hound.position = { ...bot.position };
|
||||
bot.hand = [{ instanceId: "buddy#T", cardId: "buddy" }];
|
||||
const cmd = automatonCommand(viewFor(state, "bot"), "worrier", "archmage");
|
||||
expect(cmd).toEqual({
|
||||
type: "cast", instanceId: "buddy#T",
|
||||
target: { kind: "player", playerId: "other" },
|
||||
});
|
||||
const r = applyCommand(state, "bot", cmd!);
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
});
|
||||
});
|
||||
|
||||
describe("finishing tactics: exile and adrenaline", () => {
|
||||
it("exiles a thief carrying its gold to the far end of nowhere", () => {
|
||||
let { state } = createGame({ playerIds: ["bot", "other"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
// burn round 1 and reach the bot's turn
|
||||
for (let guard = 0; guard < 10 && !(actingSeat(state) === "bot" && state.turn.round > 1); guard++) {
|
||||
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
const bot = state.players.find((p) => p.id === "bot")!;
|
||||
const thief = state.players.find((p) => p.id === "other")!;
|
||||
const t = state.treasures.find((t) => t.owner === "bot")!;
|
||||
t.position = null;
|
||||
t.carriedBy = "other";
|
||||
thief.carriedTreasureId = t.id;
|
||||
// The thief is a step from delivering; the bot watches from beside them.
|
||||
thief.position = { x: thief.home.x, y: thief.home.y === 0 ? 1 : thief.home.y - 1 };
|
||||
bot.position = { ...thief.position };
|
||||
bot.hand = [{ instanceId: "teleport-opponent#T", cardId: "teleport-opponent" }];
|
||||
const cmd = automatonCommand(viewFor(state, "bot"), "hunter", "archmage");
|
||||
expect(cmd).toMatchObject({ type: "cast", instanceId: "teleport-opponent#T" });
|
||||
const dest = (cmd as { params: { cell: { x: number; y: number } } }).params.cell;
|
||||
// The chosen square is a long march from the thief's own home.
|
||||
const d = Math.abs(dest.x - thief.home.x) + Math.abs(dest.y - thief.home.y);
|
||||
expect(d).toBeGreaterThanOrEqual(5);
|
||||
const r = applyCommand(state, "bot", cmd!);
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
});
|
||||
|
||||
it("casts adrenaline when two blows finish what one cannot", () => {
|
||||
let { state } = createGame({ playerIds: ["bot", "other"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
for (let guard = 0; guard < 10 && !(actingSeat(state) === "bot" && state.turn.round > 1); guard++) {
|
||||
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
const bot = state.players.find((p) => p.id === "bot")!;
|
||||
const prey = state.players.find((p) => p.id === "other")!;
|
||||
prey.position = { ...bot.position };
|
||||
prey.life = 7; // fireball (5) alone cannot; fireball + dagger (3) can
|
||||
bot.hand = [
|
||||
{ instanceId: "adrenaline#T", cardId: "adrenaline" },
|
||||
{ instanceId: "fireball#T", cardId: "fireball" },
|
||||
{ instanceId: "dagger#T", cardId: "dagger" },
|
||||
{ instanceId: "number-2#T", cardId: "number-2" },
|
||||
];
|
||||
const cmd = automatonCommand(viewFor(state, "bot"), "berserker", "archmage");
|
||||
expect(cmd).toMatchObject({ type: "cast", instanceId: "adrenaline#T" });
|
||||
const r = applyCommand(state, "bot", cmd!);
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
});
|
||||
});
|
||||
|
||||
describe("the fireball-then-buddy lockout", () => {
|
||||
it("burns the target, then signs the pact so they cannot hit back", () => {
|
||||
let { state } = createGame({ playerIds: ["bot", "other"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
for (let guard = 0; guard < 10 && !(actingSeat(state) === "bot" && state.turn.round > 1); guard++) {
|
||||
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
const bot = state.players.find((p) => p.id === "bot")!;
|
||||
const prey = state.players.find((p) => p.id === "other")!;
|
||||
prey.position = { ...bot.position };
|
||||
bot.life = 8; // bleeding: the clockwork wants out of this fight
|
||||
bot.hand = [
|
||||
{ instanceId: "fireball#T", cardId: "fireball" },
|
||||
{ instanceId: "buddy#T", cardId: "buddy" },
|
||||
];
|
||||
// First: the blow.
|
||||
let cmd = automatonCommand(viewFor(state, "bot"), "hunter", "archmage");
|
||||
expect(cmd).toMatchObject({ type: "cast", instanceId: "fireball#T" });
|
||||
let r = applyCommand(state, "bot", cmd!);
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
r = applyCommand(state, "other", { type: "pass" });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
// Then: the pact.
|
||||
cmd = automatonCommand(viewFor(state, "bot"), "hunter", "archmage");
|
||||
expect(cmd).toEqual({
|
||||
type: "cast", instanceId: "buddy#T",
|
||||
target: { kind: "player", playerId: "other" },
|
||||
});
|
||||
r = applyCommand(state, "bot", cmd!);
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
// The pact holds: the victim cannot strike their tormentor.
|
||||
expect(state.sustained.some(
|
||||
(s) => s.cardId === "buddy" && s.casterId === "bot" && s.targetId === "other",
|
||||
)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("a pact once signed is honored", () => {
|
||||
it("will not attack the wizard it just buddied", () => {
|
||||
let { state } = createGame({ playerIds: ["bot", "other"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
for (let guard = 0; guard < 10 && !(actingSeat(state) === "bot" && state.turn.round > 1); guard++) {
|
||||
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
const bot = state.players.find((p) => p.id === "bot")!;
|
||||
const prey = state.players.find((p) => p.id === "other")!;
|
||||
prey.position = { ...bot.position };
|
||||
// The pact already stands; a fireball waits in hand as temptation.
|
||||
pushSustained(state, {
|
||||
id: "fx-test", cardId: "buddy", casterId: "bot", targetId: "other",
|
||||
remainingTurns: 1000, data: {},
|
||||
});
|
||||
bot.hand = [{ instanceId: "fireball#T", cardId: "fireball" }];
|
||||
const cmd = automatonCommand(viewFor(state, "bot"), "hunter", "archmage");
|
||||
// Anything but an attack on the pacted wizard: no cast at them, no punch.
|
||||
expect(cmd?.type === "punch").toBe(false);
|
||||
if (cmd?.type === "cast") {
|
||||
expect((cmd as { target?: { playerId?: string } }).target?.playerId).not.toBe("other");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("no number is wasted on a turn that ends at a grab", () => {
|
||||
it("gold two free steps away: the berserker charges without spending its 5", () => {
|
||||
let { state } = createGame({ playerIds: ["bot", "other"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
for (let guard = 0; guard < 10 && !(actingSeat(state) === "bot" && state.turn.round > 1); guard++) {
|
||||
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
const bot = state.players.find((p) => p.id === "bot")!;
|
||||
const prey = state.players.find((p) => p.id === "other")!;
|
||||
// Enemy far across the maze; their treasure lies one step from the bot.
|
||||
prey.position = { x: 0, y: 0 };
|
||||
bot.position = { x: 5, y: 5 };
|
||||
const t = state.treasures.find((t) => t.owner === "other")!;
|
||||
t.position = { x: 5, y: 6 };
|
||||
t.carriedBy = null;
|
||||
state.edgeOverrides[edgeKey({ x: 5, y: 5 }, "S")] = "open";
|
||||
bot.hand = [
|
||||
{ instanceId: "number-5#T", cardId: "number-5" },
|
||||
{ instanceId: "number-2#T", cardId: "number-2" },
|
||||
];
|
||||
const cmd = automatonCommand(viewFor(state, "bot"), "berserker", "archmage");
|
||||
expect(cmd?.type).not.toBe("playNumberForMovement");
|
||||
});
|
||||
});
|
||||
|
||||
describe("the clockwork flees the dread", () => {
|
||||
it("caught in FEAR's bubble, it spends its legs moving away", () => {
|
||||
let { state } = createGame({ playerIds: ["bot", "grim"], seed: 42, sets: ["basic"] });
|
||||
for (let guard = 0; guard < 10 && !(actingSeat(state) === "bot" && state.turn.round > 1); guard++) {
|
||||
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
const bot = state.players.find((p) => p.id === "bot")!;
|
||||
const grim = state.players.find((p) => p.id === "grim")!;
|
||||
grim.position = { x: 2, y: 5 };
|
||||
bot.position = { x: 2, y: 7 }; // two spaces inside the dread
|
||||
pushSustained(state, {
|
||||
id: "fx-fear", cardId: "fear", casterId: "grim", targetId: "grim",
|
||||
remainingTurns: 5, data: {},
|
||||
});
|
||||
const cmd = automatonCommand(viewFor(state, "bot"), "berserker", "archmage");
|
||||
expect(cmd?.type).toBe("move");
|
||||
if (cmd?.type === "move") {
|
||||
const r = applyCommand(state, "bot", cmd);
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
const after = r.state.players.find((p) => p.id === "bot")!;
|
||||
const d = Math.abs(after.position.x - grim.position.x) + Math.abs(after.position.y - grim.position.y);
|
||||
expect(d).toBeGreaterThan(2);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("the thief-chase holds one goal per turn", () => {
|
||||
it("a clockwork beside its thief never shuttles on and off their square", () => {
|
||||
let { state } = createGame({ playerIds: ["thief", "bot"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
// Round 2, thief's turn burned; the bot acts with a full allowance.
|
||||
while (state.turn.round < 2 || state.players[state.turn.activeIndex]!.id !== "bot") {
|
||||
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
const thief = state.players.find((p) => p.id === "thief")!;
|
||||
const bot = state.players.find((p) => p.id === "bot")!;
|
||||
// The thief carries the bot's gold and stands one step away.
|
||||
const mine = state.treasures.find((t) => t.owner === "bot")!;
|
||||
mine.carriedBy = "thief";
|
||||
mine.position = null;
|
||||
thief.position = { x: 2, y: 4 };
|
||||
bot.position = { x: 2, y: 5 };
|
||||
state.edgeOverrides[edgeKey({ x: 2, y: 4 }, "S")] = "open";
|
||||
// A number card and no attacks: the blow the chase serves cannot land.
|
||||
bot.hand = [];
|
||||
bot.hand.push({ cardId: "number-2", instanceId: "N2" });
|
||||
const visited = [cellKey(bot.position)];
|
||||
for (let guard = 0; guard < 40; guard++) {
|
||||
const view = viewFor(state, "bot");
|
||||
const cmd = automatonCommand(view, "hunter", "archmage") ?? automatonFallback(view, "archmage");
|
||||
if (cmd.type === "endTurn") break;
|
||||
const r = applyCommand(state, "bot", cmd);
|
||||
if (!r.ok) break;
|
||||
state = r.state;
|
||||
const at = cellKey(state.players.find((p) => p.id === "bot")!.position);
|
||||
if (cmd.type === "move" && at !== visited[visited.length - 1]) visited.push(at);
|
||||
}
|
||||
// No step may return to the square just departed: A-B-A is the shuttle.
|
||||
for (let i = 2; i < visited.length; i++) {
|
||||
expect(visited[i]).not.toBe(visited[i - 2]);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("the archmage's key, shield, and race discipline", () => {
|
||||
function botTurn() {
|
||||
const seed = 42;
|
||||
let { state } = createGame({ playerIds: ["foe", "bot"], seed, sets: ["basic", "expansion1"] });
|
||||
while (state.turn.round < 2 || state.players[state.turn.activeIndex]!.id !== "bot") {
|
||||
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
it("a MASTER KEY drawn goes straight on display", () => {
|
||||
const state = botTurn();
|
||||
const bot = state.players.find((p) => p.id === "bot")!;
|
||||
bot.hand.push({ cardId: "master-key", instanceId: "MK" });
|
||||
const cmd = automatonCommand(viewFor(state, "bot"), "hunter", "archmage");
|
||||
expect(cmd).toEqual({ type: "cast", instanceId: "MK" });
|
||||
});
|
||||
|
||||
it("a lethal small blow is countered, thrift be damned", () => {
|
||||
let { state } = createGame({ playerIds: ["foe", "bot"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
while (state.turn.round < 2 || state.players[state.turn.activeIndex]!.id !== "foe") {
|
||||
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
const foe = state.players.find((p) => p.id === "foe")!;
|
||||
const bot = state.players.find((p) => p.id === "bot")!;
|
||||
bot.position = { ...foe.position };
|
||||
bot.life = 2;
|
||||
bot.hand = [{ cardId: "full-shield", instanceId: "FS" }];
|
||||
foe.hand.push({ cardId: "fireball", instanceId: "FB" });
|
||||
const r = applyCommand(state, "foe", {
|
||||
type: "cast", instanceId: "FB", target: { kind: "player", playerId: "bot" },
|
||||
});
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
// Base fireball, 2 points: below every thrift threshold, but fatal at
|
||||
// 2 life — the shield comes out.
|
||||
const cmd = automatonCommand(viewFor(r.state, "bot"), "hunter", "archmage");
|
||||
expect(cmd).toEqual({ type: "counteract", instanceId: "FS" });
|
||||
});
|
||||
|
||||
it("no number is hoarded against the delivery that wins the game", () => {
|
||||
let state = botTurn();
|
||||
const bot = state.players.find((p) => p.id === "bot")!;
|
||||
const foe = state.players.find((p) => p.id === "foe")!;
|
||||
// One of the foe's treasures already rests at the bot's home; the bot
|
||||
// carries the second, four squares out with three legs — only the
|
||||
// number bridges it home this turn.
|
||||
const gold = state.treasures.filter((t) => t.owner === "foe");
|
||||
expect(gold.length).toBeGreaterThanOrEqual(2);
|
||||
gold[0]!.position = { ...bot.home };
|
||||
gold[0]!.carriedBy = null;
|
||||
gold[1]!.carriedBy = "bot";
|
||||
gold[1]!.position = null;
|
||||
bot.carriedTreasureId = gold[1]!.id;
|
||||
foe.position = { ...bot.home }; // a foe in sight: the war chest would hoard
|
||||
// Legs only: an attack in hand would fire at the foe in sight and
|
||||
// open a stack this single-seat loop cannot answer.
|
||||
bot.hand = [{ cardId: "number-3", instanceId: "N3" }];
|
||||
// Carve a straight, open four-square run to home; the rig owns its
|
||||
// geometry rather than praying the seed provides it.
|
||||
const home = bot.home;
|
||||
const column = [4, 3, 2, 1, 0].map((d) => ({ x: home.x, y: home.y - d }));
|
||||
for (const c of column) {
|
||||
if (!viewFor(state, "bot").board.cells[cellKey(c)]) {
|
||||
throw new Error("setup: the column north of home runs off the board");
|
||||
}
|
||||
delete state.squareContents[cellKey(c)];
|
||||
}
|
||||
bot.position = { ...column[0]! };
|
||||
for (const c of column.slice(0, 4)) state.edgeOverrides[edgeKey(c, "S")] = "open";
|
||||
for (let guard = 0; guard < 12; guard++) {
|
||||
const view = viewFor(state, "bot");
|
||||
const cmd = automatonCommand(view, "hunter", "archmage") ?? automatonFallback(view, "archmage");
|
||||
if (cmd.type === "playNumberForMovement") return; // the chest opened for the win
|
||||
if (cmd.type === "endTurn") break;
|
||||
const r = applyCommand(state, "bot", cmd);
|
||||
if (!r.ok) break;
|
||||
state = r.state;
|
||||
if (state.phase !== "playing") return; // delivered and won outright
|
||||
}
|
||||
throw new Error("the clockwork hoarded its number instead of winning");
|
||||
});
|
||||
});
|
||||
|
||||
describe("bank guarding, teleport delivery, and turn theft", () => {
|
||||
function rig() {
|
||||
const players = ["foe", "bot"];
|
||||
let { state } = createGame({ playerIds: players, seed: 42, sets: ["basic", "expansion1"] });
|
||||
while (state.turn.round < 2 || state.players[state.turn.activeIndex]!.id !== "bot") {
|
||||
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
it("a raider at the stocked bank's gates pulls the clockwork home", () => {
|
||||
const state = rig();
|
||||
const bot = state.players.find((p) => p.id === "bot")!;
|
||||
const foe = state.players.find((p) => p.id === "foe")!;
|
||||
const gold = state.treasures.find((t) => t.owner === "foe")!;
|
||||
gold.position = { ...bot.home };
|
||||
gold.carriedBy = null;
|
||||
foe.position = { x: bot.home.x, y: bot.home.y + 1 };
|
||||
bot.position = { ...foe.home };
|
||||
bot.hand = [];
|
||||
// The march may wind through the maze; what matters is that it ENDS
|
||||
// at the threatened bank, not out on the gold map.
|
||||
let cur = state;
|
||||
for (let guard = 0; guard < 60; guard++) {
|
||||
const seat = actingSeat(cur);
|
||||
if (seat !== "bot") {
|
||||
// The foe answers stacks with a pass and burns its turns.
|
||||
let r2 = applyCommand(cur, seat, { type: "pass" });
|
||||
if (!r2.ok) r2 = applyCommand(cur, seat, { type: "endTurn", draw: 0 });
|
||||
if (!r2.ok) throw new Error(`foe stuck: ${r2.error}`);
|
||||
cur = r2.state;
|
||||
continue;
|
||||
}
|
||||
const view = viewFor(cur, "bot");
|
||||
const cmd = automatonCommand(view, "hunter", "archmage") ?? automatonFallback(view, "archmage");
|
||||
const r = applyCommand(cur, "bot", cmd);
|
||||
if (!r.ok) throw new Error(`refused: ${JSON.stringify(cmd)} — ${r.error}`);
|
||||
cur = r.state;
|
||||
const at = cur.players.find((p) => p.id === "bot")!;
|
||||
if (cellKey(at.position) === cellKey(bot.home)) return;
|
||||
}
|
||||
throw new Error("the clockwork never came home to its threatened bank");
|
||||
});
|
||||
|
||||
it("carrying with home a blink away, it teleports the delivery", () => {
|
||||
const state = rig();
|
||||
const bot = state.players.find((p) => p.id === "bot")!;
|
||||
const prize = state.treasures.find((t) => t.owner === "foe")!;
|
||||
prize.carriedBy = "bot";
|
||||
prize.position = null;
|
||||
bot.carriedTreasureId = prize.id;
|
||||
// Two squares from home as the spell flies, but walled off on foot.
|
||||
bot.position = { x: bot.home.x, y: bot.home.y + 2 };
|
||||
for (const side of ["N", "S", "E", "W"] as const) {
|
||||
state.edgeOverrides[edgeKey(bot.position, side)] = "wall";
|
||||
}
|
||||
bot.hand = [{ cardId: "teleport", instanceId: "TP" }];
|
||||
const cmd = automatonCommand(viewFor(state, "bot"), "hunter", "archmage");
|
||||
expect(cmd).toEqual({ type: "cast", instanceId: "TP", target: { kind: "cell", cell: { ...bot.home } } });
|
||||
});
|
||||
|
||||
it("a would-win carrier eats the lightning, not the fireball", () => {
|
||||
let state = rig();
|
||||
const bot = state.players.find((p) => p.id === "bot")!;
|
||||
const foe = state.players.find((p) => p.id === "foe")!;
|
||||
// Foe has one banked and carries the second: one delivery from winning.
|
||||
const banked = state.treasures.find((t) => t.owner === "bot")!;
|
||||
banked.position = { ...foe.home };
|
||||
const carried = state.treasures.filter((t) => t.owner === "bot")[1];
|
||||
if (!carried) throw new Error("setup: the bot owns fewer than two treasures");
|
||||
carried.carriedBy = "foe";
|
||||
carried.position = null;
|
||||
foe.carriedTreasureId = carried.id;
|
||||
foe.position = { ...bot.position };
|
||||
bot.hand = [
|
||||
{ cardId: "fireball", instanceId: "FB" },
|
||||
{ cardId: "lightning-blast", instanceId: "LB" },
|
||||
{ cardId: "number-4", instanceId: "N4" },
|
||||
];
|
||||
const cmd = automatonCommand(viewFor(state, "bot"), "hunter", "archmage");
|
||||
expect(cmd).toMatchObject({ type: "cast", instanceId: "LB" });
|
||||
});
|
||||
});
|
||||
|
||||
describe("the denial planner offers only castable blocks", () => {
|
||||
it("tacks are offered only at the caster's feet", () => {
|
||||
// TACKS demand adjacency; a planner that proposes them at range has
|
||||
// its cast refused every turn, and the refusal-fallback loop reads
|
||||
// as an idle bot.
|
||||
let { state } = createGame({ playerIds: ["foe", "bot"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
while (state.turn.round < 2 || state.players[state.turn.activeIndex]!.id !== "bot") {
|
||||
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
const bot = state.players.find((p) => p.id === "bot")!;
|
||||
const foe = state.players.find((p) => p.id === "foe")!;
|
||||
// The bot's floor gold with a raider closing on it, and only TACKS
|
||||
// in hand to deny the road — from a stand-off distance.
|
||||
const gold = state.treasures.find((t) => t.owner === "bot" && t.position)!;
|
||||
foe.position = { ...gold.position! };
|
||||
bot.position = { ...bot.home };
|
||||
bot.hand = [{ cardId: "handful-of-tacks", instanceId: "HT" }];
|
||||
for (let guard = 0; guard < 6; guard++) {
|
||||
const cmd = automatonCommand(viewFor(state, "bot"), "hunter", "archmage");
|
||||
if (!cmd) break;
|
||||
const r = applyCommand(state, "bot", cmd);
|
||||
// Whatever the brain proposes, the engine must accept it.
|
||||
if (!r.ok) throw new Error(`brain proposed a refused command: ${JSON.stringify(cmd)} — ${r.error}`);
|
||||
state = r.state;
|
||||
if (cmd.type === "endTurn") break;
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -9,6 +9,11 @@ import {
|
||||
type SectorPlacement,
|
||||
} from "../src/board";
|
||||
import { buildDeck } from "../src/cards";
|
||||
import { edgeKey, type Side } from "../src/board";
|
||||
import { activePlayer, applyCommand, boardView, createGame, gameLos } from "../src/game";
|
||||
import { createRng } from "../src/rng";
|
||||
import { setupBoard } from "../src/setups";
|
||||
import { giveCard } from "./helpers";
|
||||
|
||||
describe("card data", () => {
|
||||
it("basic deck is exactly 125 cards (official 6e rulebook)", () => {
|
||||
@@ -109,9 +114,7 @@ describe("board assembly", () => {
|
||||
});
|
||||
|
||||
describe("player counts 2-6", () => {
|
||||
it("assembles a coherent board for every supported count", async () => {
|
||||
const { setupBoard } = await import("../src/setups");
|
||||
const { createRng } = await import("../src/rng");
|
||||
it("assembles a coherent board for every supported count", () => {
|
||||
for (const n of [2, 3, 4, 5, 6]) {
|
||||
const { board } = setupBoard(n, createRng(n * 7));
|
||||
expect(board.homes.length).toBe(n);
|
||||
@@ -127,8 +130,7 @@ describe("player counts 2-6", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("full games start at every count", async () => {
|
||||
const { createGame } = await import("../src/game");
|
||||
it("full games start at every count", () => {
|
||||
for (const n of [3, 5, 6]) {
|
||||
const ids = Array.from({ length: n }, (_, i) => `w${i}`);
|
||||
const { state } = createGame({ playerIds: ids, seed: 99 + n, sets: ["basic", "expansion1"] });
|
||||
@@ -158,12 +160,7 @@ describe("sight and the wraparound openings", () => {
|
||||
});
|
||||
});
|
||||
|
||||
import { createRng } from "../src/rng";
|
||||
import { setupBoard as setupBoardForPins } from "../src/setups";
|
||||
|
||||
describe("setup diagram pairings (rulebook Set-Up Diagram)", () => {
|
||||
const setupBoard = setupBoardForPins;
|
||||
|
||||
function onEdge(c: { x: number; y: number }, origin: { x: number; y: number }, side: string): boolean {
|
||||
if (side === "N") return c.y === origin.y && c.x >= origin.x && c.x < origin.x + 5;
|
||||
if (side === "S") return c.y === origin.y + 4 && c.x >= origin.x && c.x < origin.x + 5;
|
||||
@@ -203,17 +200,16 @@ describe("setup diagram pairings (rulebook Set-Up Diagram)", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("relocation discards the aisle warp: only opposite edges connect after", async () => {
|
||||
const { createGame, applyCommand, activePlayer } = await import("../src/game");
|
||||
let { state } = createGame({ playerIds: ["a", "b", "c"], seed: 7, sets: ["basic"], deckRev: 5 });
|
||||
it("relocation discards the aisle warp: only opposite edges connect after", () => {
|
||||
let { state } = createGame({ playerIds: ["a", "b", "c"], seed: 7, sets: ["basic"] });
|
||||
const bent = (warps: typeof state.board.warps) =>
|
||||
warps.filter((w) => w.from.cell.x !== w.to.cell.x && w.from.cell.y !== w.to.cell.y);
|
||||
expect(bent(state.board.warps).length).toBeGreaterThan(0); // the arc exists
|
||||
const me = activePlayer(state);
|
||||
me.hand[0] = { instanceId: "rel#1", cardId: "relocate-sector" };
|
||||
const rel = giveCard(state, me.id, "relocate-sector");
|
||||
// Slide the top sector from (5,0) across to (0,0): an L becomes a block.
|
||||
const r = applyCommand(state, me.id, {
|
||||
type: "cast", instanceId: "rel#1",
|
||||
type: "cast", instanceId: rel.instanceId,
|
||||
target: { kind: "cell", cell: { x: 0, y: 0 } }, params: { cell: { x: 7, y: 2 } },
|
||||
});
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
@@ -223,8 +219,10 @@ describe("setup diagram pairings (rulebook Set-Up Diagram)", () => {
|
||||
|
||||
describe("the aisle warp treats its corner as adjacent — sight included", () => {
|
||||
it("sight passes through the AUTO WARP, diagonals and all", () => {
|
||||
const { board } = setupBoardForPins(3, createRng(7));
|
||||
const aisle = board.warps.find((w) => w.aisle)!;
|
||||
const { board } = setupBoard(3, createRng(7));
|
||||
const aisle = board.warps.find(
|
||||
(w) => w.from.cell.x !== w.to.cell.x && w.from.cell.y !== w.to.cell.y,
|
||||
)!;
|
||||
expect(aisle).toBeDefined();
|
||||
// From the aisle mouth, squares beyond the corner are visible — including
|
||||
// at least one OFF the straight axis (the adjacency promise).
|
||||
@@ -243,3 +241,77 @@ describe("the aisle warp treats its corner as adjacent — sight included", () =
|
||||
expect(offAxis).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("bricking over a warp mouth", () => {
|
||||
it("create wall seals a lettered opening: no passage, no sight", () => {
|
||||
let { state } = createGame({ playerIds: ["a", "b"], seed: 42, sets: ["basic"] });
|
||||
// round 1 passes
|
||||
for (let i = 0; i < 2; i++) {
|
||||
const r = applyCommand(state, activePlayer(state).id, { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
const w = state.board.warps[0]!;
|
||||
const caster = activePlayer(state);
|
||||
caster.position = { ...w.from.cell };
|
||||
caster.hand[0] = { instanceId: "cw#1", cardId: "create-wall" };
|
||||
const r = applyCommand(state, caster.id, {
|
||||
type: "cast", instanceId: "cw#1",
|
||||
target: { kind: "edge", cell: w.from.cell, side: w.from.side },
|
||||
});
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
// Passage: stepping into the warp is now a wall.
|
||||
const step = stepTarget(boardView(state), w.from.cell, w.from.side);
|
||||
expect(step.kind).toBe("blocked");
|
||||
// Sight: the far mouth no longer carries warp sight.
|
||||
expect(gameLos(state, w.from.cell, w.to.cell)).toBe(false);
|
||||
// One tunnel: the FAR mouth is walled too, and unwalling it reopens both.
|
||||
const farStep = stepTarget(boardView(state), w.to.cell, w.to.side);
|
||||
expect(farStep.kind).toBe("blocked");
|
||||
const caster2 = activePlayer(state);
|
||||
caster2.position = { ...w.to.cell };
|
||||
caster2.hand[0] = { instanceId: "dw#1", cardId: "destroy-wall" };
|
||||
const r2 = applyCommand(state, caster2.id, {
|
||||
type: "cast", instanceId: "dw#1",
|
||||
target: { kind: "edge", cell: w.to.cell, side: w.to.side },
|
||||
});
|
||||
if (!r2.ok) throw new Error(r2.error);
|
||||
expect(stepTarget(boardView(r2.state), w.from.cell, w.from.side).kind).toBe("warp");
|
||||
});
|
||||
});
|
||||
|
||||
describe("breaching the rim", () => {
|
||||
it("destroying a perimeter wall opens both sides as a new warp", () => {
|
||||
let { state } = createGame({ playerIds: ["a", "b"], seed: 42, sets: ["basic"] });
|
||||
for (let i = 0; i < 2; i++) {
|
||||
const r = applyCommand(state, activePlayer(state).id, { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
// Find a rim wall with a wrap counterpart that is NOT already an opening.
|
||||
const view = boardView(state);
|
||||
for (const key of Object.keys(view.cells)) {
|
||||
const [x, y] = key.split(",").map(Number) as [number, number];
|
||||
for (const side of ["N", "E", "S", "W"] as Side[]) {
|
||||
const n = { x: x + (side === "E" ? 1 : side === "W" ? -1 : 0), y: y + (side === "S" ? 1 : side === "N" ? -1 : 0) };
|
||||
if (view.cells[`${n.x},${n.y}`]) continue;
|
||||
if ((view.edges[edgeKey({ x, y }, side)] ?? "open") !== "wall") continue;
|
||||
const caster = activePlayer(state);
|
||||
caster.position = { x, y };
|
||||
caster.hand[0] = { instanceId: "dw#1", cardId: "destroy-wall" };
|
||||
const warpsBefore = state.board.warps.length;
|
||||
const r = applyCommand(state, caster.id, {
|
||||
type: "cast", instanceId: "dw#1", target: { kind: "edge", cell: { x, y }, side },
|
||||
});
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
if (r.state.board.warps.length === warpsBefore) continue; // no counterpart in this row
|
||||
expect(r.state.board.warps.length).toBe(warpsBefore + 2);
|
||||
const w = r.state.board.warps[warpsBefore]!;
|
||||
expect(stepTarget(boardView(r.state), w.from.cell, w.from.side).kind).toBe("warp");
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new Error("setup: no breachable rim wall found");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { applyCommand, activePlayer, boardView, createGame } from "../src/game";
|
||||
import { cellKey, edgeKey, hasLineOfSight, neighbor, type Side, SIDES, stepTarget } from "../src/board";
|
||||
import { applyCommand, activePlayer, boardView, createGame, type GameState } from "../src/game";
|
||||
import { cellKey, edgeKey, hasLineOfSight, neighbor, type Cell, type Side, SIDES, stepTarget } from "../src/board";
|
||||
import type { CardInstance } from "../src/cards";
|
||||
import { sightedCellsFor, stackSightTrace, viewFor } from "../src/view";
|
||||
import { newGame, must, giveCard, toRound2, faceOff } from "./helpers";
|
||||
|
||||
/** Test surgery: put a specific card into a player's hand (swapping one out). */
|
||||
@@ -30,10 +31,10 @@ describe("attack spells", () => {
|
||||
d.hand[1] = { instanceId: "full-shield#T", cardId: "full-shield" };
|
||||
|
||||
state = must(state, attacker, { type: "cast", instanceId: fb.instanceId, target: { kind: "player", playerId: defender } });
|
||||
// Full shield stops everything -> stones survive.
|
||||
// Full shield stops everything -> stones survive. (A total stop
|
||||
// resolves on the attacker's pass; no bounce back.)
|
||||
state = must(state, defender, { type: "counteract", instanceId: "full-shield#T" });
|
||||
state = must(state, attacker, { type: "pass" });
|
||||
state = must(state, defender, { type: "pass" });
|
||||
const after = state.players.find((p) => p.id === defender)!;
|
||||
expect(after.life).toBe(15);
|
||||
expect(after.hand.some((c) => c.cardId === "powerstone")).toBe(true);
|
||||
@@ -110,7 +111,8 @@ describe("attack spells", () => {
|
||||
state = must(state, attacker, { type: "cast", instanceId: fb.instanceId, target: { kind: "player", playerId: defender } });
|
||||
state = must(state, defender, { type: "counteract", instanceId: "full-reflection#T" });
|
||||
state = must(state, attacker, { type: "pass" });
|
||||
state = must(state, defender, { type: "pass" });
|
||||
// The returned spell is a fresh attack on its caster: their window.
|
||||
state = must(state, attacker, { type: "pass" });
|
||||
expect(state.players.find((p) => p.id === defender)!.life).toBe(15);
|
||||
expect(state.players.find((p) => p.id === attacker)!.life).toBe(10);
|
||||
});
|
||||
@@ -249,14 +251,6 @@ describe("stack discipline", () => {
|
||||
expect(applyCommand(state, defender, { type: "move", direction: "N" }).ok).toBe(false);
|
||||
});
|
||||
|
||||
it("unimplemented cards refuse to cast with a clear error", () => {
|
||||
let { state } = newGame();
|
||||
const caster = activePlayer(state);
|
||||
const card = giveCard(state, caster.id, "bomb"); // expansion2: historical, never implemented
|
||||
const result = applyCommand(state, caster.id, { type: "cast", instanceId: card.instanceId });
|
||||
expect(result.ok).toBe(false);
|
||||
if (!result.ok) expect(result.error).toMatch(/not implemented/);
|
||||
});
|
||||
});
|
||||
|
||||
describe("speedstone", () => {
|
||||
@@ -277,8 +271,7 @@ describe("speedstone", () => {
|
||||
});
|
||||
|
||||
describe("the post-game reveal", () => {
|
||||
it("shows an eliminated player's hand as they fell, not their emptied one", async () => {
|
||||
const { viewFor } = await import("../src/view");
|
||||
it("shows an eliminated player's hand as they fell, not their emptied one", () => {
|
||||
let { state } = newGame();
|
||||
state = toRound2(state);
|
||||
const attacker = activePlayer(state);
|
||||
@@ -315,17 +308,15 @@ describe("stored-log compatibility", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("deck revisions", () => {
|
||||
it("revision 2 removes LIFESAVER at two players, and only there", () => {
|
||||
const two = createGame({ playerIds: ["a", "b"], seed: 9, sets: ["basic", "expansion1"], deckRev: 2 });
|
||||
describe("the two-player deck", () => {
|
||||
it("two-player games shed LIFESAVER; bigger tables keep it", () => {
|
||||
const two = createGame({ playerIds: ["a", "b"], seed: 9, sets: ["basic", "expansion1"] });
|
||||
const inGame = (s: typeof two.state) =>
|
||||
[...s.deck, ...s.discard, ...s.players.flatMap((p) => p.hand)].some((c) => c.cardId === "lifesaver");
|
||||
expect(inGame(two.state)).toBe(false);
|
||||
// Three players keep it; old two-player games (no deckRev) keep it too.
|
||||
const three = createGame({ playerIds: ["a", "b", "c"], seed: 9, sets: ["basic", "expansion1"], deckRev: 2 });
|
||||
// Three players keep it.
|
||||
const three = createGame({ playerIds: ["a", "b", "c"], seed: 9, sets: ["basic", "expansion1"] });
|
||||
expect(inGame(three.state)).toBe(true);
|
||||
const legacy = createGame({ playerIds: ["a", "b"], seed: 9, sets: ["basic", "expansion1"] });
|
||||
expect(inGame(legacy.state)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -350,7 +341,7 @@ describe("attacking walls and doors", () => {
|
||||
expect(applyCommand(state, me.id, { type: "punchWall", cell, side }).ok).toBe(false);
|
||||
});
|
||||
|
||||
it("a powered fireball brings a wall down at 20 accumulated damage", () => {
|
||||
it("repeated fireballs bring a wall down at 20 accumulated damage", () => {
|
||||
let { state } = newGame();
|
||||
state = toRound2(state);
|
||||
let me = activePlayer(state);
|
||||
@@ -388,43 +379,60 @@ describe("attacking walls and doors", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("rules revision 3", () => {
|
||||
function rev3Game(seed = 42) {
|
||||
return createGame({ playerIds: ["alice", "bob", "cara"], seed, sets: ["basic", "expansion1"], deckRev: 3 });
|
||||
describe("the ward window and chaos shields", () => {
|
||||
function threeGame(seed = 42) {
|
||||
return createGame({ playerIds: ["alice", "bob", "cara"], seed, sets: ["basic", "expansion1"] });
|
||||
}
|
||||
|
||||
it("ward springs only when its owner armed it", () => {
|
||||
let { state } = rev3Game();
|
||||
it("the grab hangs while the ward's owner decides — and arming ahead is refused", () => {
|
||||
let { state } = threeGame();
|
||||
state = toRound2(state);
|
||||
state = must(state, activePlayer(state).id, { type: "endTurn", draw: 0 });
|
||||
const thief = activePlayer(state);
|
||||
const owner = state.players.find((p) => p.id !== thief.id)!;
|
||||
giveCard(state, owner.id, "ward", "W", 0);
|
||||
expect(applyCommand(state, owner.id, { type: "armWard" }).ok).toBe(false);
|
||||
const treasure = state.treasures.find((t) => t.owner === owner.id)!;
|
||||
|
||||
// Unarmed: the grab goes unpunished.
|
||||
thief.position = { ...treasure.position! };
|
||||
let s2 = must(state, thief.id, { type: "pickUpTreasure" });
|
||||
expect(s2.players.find((p) => p.id === thief.id)!.life).toBe(15);
|
||||
expect(s2.players.find((p) => p.id === owner.id)!.hand.some((c) => c.cardId === "ward")).toBe(true);
|
||||
state = must(state, thief.id, { type: "pickUpTreasure" });
|
||||
expect(state.wardPending).toEqual({ ownerId: owner.id, takerId: thief.id });
|
||||
// Spring it: the thief bleeds 3 and the ward is spent.
|
||||
state = must(state, owner.id, { type: "wardChoice", play: true });
|
||||
expect(state.players.find((p) => p.id === thief.id)!.life).toBe(12);
|
||||
expect(state.players.find((p) => p.id === owner.id)!.hand.some((c) => c.cardId === "ward")).toBe(false);
|
||||
});
|
||||
|
||||
// Armed (on the owner's own turn): the trap bites for 3.
|
||||
state.players[state.turn.activeIndex] = state.players[state.turn.activeIndex]!;
|
||||
const ownerTurnState = (() => {
|
||||
let s = state;
|
||||
while (activePlayer(s).id !== owner.id) s = must(s, activePlayer(s).id, { type: "endTurn", draw: 0 });
|
||||
return s;
|
||||
})();
|
||||
let s3 = must(ownerTurnState, owner.id, { type: "armWard", armed: true });
|
||||
while (activePlayer(s3).id !== thief.id) s3 = must(s3, activePlayer(s3).id, { type: "endTurn", draw: 0 });
|
||||
s3.players.find((p) => p.id === thief.id)!.position = { ...treasure.position! };
|
||||
s3 = must(s3, thief.id, { type: "pickUpTreasure" });
|
||||
expect(s3.players.find((p) => p.id === thief.id)!.life).toBe(12);
|
||||
expect(s3.wardArmed).not.toContain(owner.id);
|
||||
it("chaos casts bare — no target, every other wizard queued for a shield", () => {
|
||||
let { state } = threeGame();
|
||||
state = toRound2(state);
|
||||
state = must(state, activePlayer(state).id, { type: "endTurn", draw: 0 });
|
||||
const caster = activePlayer(state);
|
||||
const others = state.players.filter((p) => p.id !== caster.id).map((p) => p.id);
|
||||
const chaos = giveCard(state, caster.id, "chaos", "C", 0);
|
||||
const shielder = others[0]!;
|
||||
giveCard(state, shielder, "full-shield", "S", 0);
|
||||
const shielderHand = () => state.players.find((p) => p.id === shielder)!.hand.map((c) => c.instanceId).sort();
|
||||
const kept = shielderHand().filter((id) => id !== "full-shield#S").sort();
|
||||
|
||||
state = must(state, caster.id, { type: "cast", instanceId: chaos.instanceId });
|
||||
// No stack: the queue opens at once, in turn order from the caster.
|
||||
expect(state.stack).toBeNull();
|
||||
expect(state.chaosPending?.queue.length).toBe(2);
|
||||
const first = state.chaosPending!.queue[0]!;
|
||||
state = first === shielder
|
||||
? must(state, first, { type: "counteract", instanceId: "full-shield#S" })
|
||||
: must(state, first, { type: "pass" });
|
||||
const second = state.chaosPending!.queue[0]!;
|
||||
state = second === shielder
|
||||
? must(state, second, { type: "counteract", instanceId: "full-shield#S" })
|
||||
: must(state, second, { type: "pass" });
|
||||
expect(state.chaosPending).toBeNull();
|
||||
// The shielded hand rode out the storm untouched.
|
||||
expect(shielderHand()).toEqual(kept);
|
||||
});
|
||||
|
||||
it("chaos: bystanders may shield out, reflections are refused", () => {
|
||||
let { state } = rev3Game();
|
||||
let { state } = threeGame();
|
||||
state = toRound2(state);
|
||||
state = must(state, activePlayer(state).id, { type: "endTurn", draw: 0 });
|
||||
const caster = activePlayer(state);
|
||||
@@ -451,7 +459,7 @@ describe("rules revision 3", () => {
|
||||
});
|
||||
|
||||
it("chaos: the defender's full shield sits them out without stopping it", () => {
|
||||
let { state } = rev3Game();
|
||||
let { state } = threeGame();
|
||||
state = toRound2(state);
|
||||
state = must(state, activePlayer(state).id, { type: "endTurn", draw: 0 });
|
||||
const caster = activePlayer(state);
|
||||
@@ -467,25 +475,12 @@ describe("rules revision 3", () => {
|
||||
});
|
||||
state = must(state, defender.id, { type: "counteract", instanceId: "full-shield#S" });
|
||||
state = must(state, caster.id, { type: "pass" }); // caster declines to anti-anti
|
||||
state = must(state, defender.id, { type: "pass" }); // defender rests on the shield
|
||||
// Bystander declines; the scramble happens without the defender.
|
||||
expect(state.chaosPending?.queue[0]).toBe(bystander.id);
|
||||
state = must(state, bystander.id, { type: "pass" });
|
||||
expect(state.chaosPending).toBeNull();
|
||||
expect(defenderHand()).toEqual(kept);
|
||||
});
|
||||
|
||||
it("legacy games (rev < 3) keep the automatic ward", () => {
|
||||
let { state } = createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic"] });
|
||||
state = toRound2(state);
|
||||
const thief = activePlayer(state);
|
||||
const owner = state.players.find((p) => p.id !== thief.id)!;
|
||||
giveCard(state, owner.id, "ward", "W", 0);
|
||||
const treasure = state.treasures.find((t) => t.owner === owner.id)!;
|
||||
thief.position = { ...treasure.position! };
|
||||
state = must(state, thief.id, { type: "pickUpTreasure" });
|
||||
expect(state.players.find((p) => p.id === thief.id)!.life).toBe(12);
|
||||
});
|
||||
});
|
||||
|
||||
describe("zero-damage utility attacks", () => {
|
||||
@@ -526,8 +521,7 @@ describe("zero-damage utility attacks", () => {
|
||||
target: { kind: "player", playerId: defender },
|
||||
});
|
||||
state = must(state, defender, { type: "counteract", instanceId: "full-shield#FS" });
|
||||
state = must(state, attacker, { type: "pass" });
|
||||
const result = applyCommand(state, defender, { type: "pass" });
|
||||
const result = applyCommand(state, attacker, { type: "pass" });
|
||||
if (!result.ok) throw new Error(result.error);
|
||||
const resolved = result.events.find((e) => e.type === "attackResolved");
|
||||
expect(resolved && "fullyStopped" in resolved && resolved.fullyStopped).toBe(true);
|
||||
@@ -535,6 +529,83 @@ describe("zero-damage utility attacks", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("the VISIONSTONE pierces one wall", () => {
|
||||
function stoneRig() {
|
||||
let { state } = newGame();
|
||||
state = toRound2(state);
|
||||
const a = activePlayer(state);
|
||||
const b = state.players.find((p) => p.id !== a.id)!;
|
||||
a.position = { x: 2, y: 4 };
|
||||
b.position = { x: 2, y: 5 };
|
||||
state.edgeOverrides[edgeKey({ x: 2, y: 4 }, "S")] = "wall";
|
||||
return { state, a, b };
|
||||
}
|
||||
|
||||
it("its bearer casts an attack straight through the wall", () => {
|
||||
const { state, a, b } = stoneRig();
|
||||
const fb = giveCard(state, a.id, "fireball", "FB", 1);
|
||||
const refused = applyCommand(state, a.id, {
|
||||
type: "cast", instanceId: fb.instanceId, target: { kind: "player", playerId: b.id },
|
||||
});
|
||||
expect(refused.ok).toBe(false);
|
||||
const stone = giveCard(state, a.id, "visionstone", "VS");
|
||||
a.displayed.push(stone.instanceId);
|
||||
const cast = applyCommand(state, a.id, {
|
||||
type: "cast", instanceId: fb.instanceId, target: { kind: "player", playerId: b.id },
|
||||
});
|
||||
expect(cast.ok).toBe(true);
|
||||
});
|
||||
|
||||
it("its bearer plants a THORNBUSH through the wall", () => {
|
||||
const { state, a } = stoneRig();
|
||||
// The square past the wall must be bare ground for a creation.
|
||||
const cell = { x: 2, y: 5 };
|
||||
for (const p of state.players) if (cellKey(p.position) === cellKey(cell)) p.position = { x: 0, y: 0 };
|
||||
const bush = giveCard(state, a.id, "thornbush", "TB");
|
||||
const refused = applyCommand(state, a.id, {
|
||||
type: "cast", instanceId: bush.instanceId, target: { kind: "cell", cell },
|
||||
});
|
||||
expect(refused.ok).toBe(false);
|
||||
if (!refused.ok) expect(refused.error).toContain("line of sight");
|
||||
const stone = giveCard(state, a.id, "visionstone", "VS", 1);
|
||||
a.displayed.push(stone.instanceId);
|
||||
const cast = applyCommand(state, a.id, {
|
||||
type: "cast", instanceId: bush.instanceId, target: { kind: "cell", cell },
|
||||
});
|
||||
expect(cast.ok).toBe(true);
|
||||
});
|
||||
|
||||
it("the client's sighted squares agree with the stone", () => {
|
||||
const { state, a, b } = stoneRig();
|
||||
expect(sightedCellsFor(viewFor(state, a.id)).has(cellKey(b.position))).toBe(false);
|
||||
const stone = giveCard(state, a.id, "visionstone", "VS");
|
||||
a.displayed.push(stone.instanceId);
|
||||
expect(sightedCellsFor(viewFor(state, a.id)).has(cellKey(b.position))).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("teleport wraps the maze's rim", () => {
|
||||
it("four spaces counted through a warp mouth reach the far side", () => {
|
||||
let { state } = newGame();
|
||||
state = toRound2(state);
|
||||
// Stand the active wizard at a wraparound mouth; the paired cell is
|
||||
// ONE teleport step away, exactly as it is one walking step.
|
||||
const active = activePlayer(state);
|
||||
const warp = boardView(state).warps[0]!;
|
||||
active.position = { ...warp.from.cell };
|
||||
const tp = giveCard(state, active.id, "teleport", "TP", 0);
|
||||
const r = applyCommand(state, active.id, {
|
||||
type: "cast", instanceId: tp.instanceId,
|
||||
target: { kind: "cell", cell: { ...warp.to.cell } },
|
||||
});
|
||||
expect(r.ok).toBe(true);
|
||||
if (r.ok) {
|
||||
const after = r.state.players.find((p) => p.id === active.id)!;
|
||||
expect(cellKey(after.position)).toBe(cellKey(warp.to.cell));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("teleport as a counteraction", () => {
|
||||
it("the attack has no chance of hitting you — you are simply elsewhere", () => {
|
||||
let { state } = newGame();
|
||||
@@ -549,32 +620,11 @@ describe("teleport as a counteraction", () => {
|
||||
});
|
||||
state = must(state, defender, { type: "counteract", instanceId: tp.instanceId, params: { cell: escape } });
|
||||
state = must(state, attacker, { type: "pass" });
|
||||
state = must(state, defender, { type: "pass" });
|
||||
const after = state.players.find((p) => p.id === defender)!;
|
||||
expect(after.life).toBe(15);
|
||||
expect(cellKey(after.position)).toBe(cellKey(escape));
|
||||
});
|
||||
|
||||
it("ANTI-ANTI pins the boots in pre-rev-6 games (their stored chains replay)", () => {
|
||||
let { state } = newGame();
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
const fb = giveCard(state, attacker, "fireball");
|
||||
const aa = giveCard(state, attacker, "anti-anti", "AA", 1);
|
||||
const tp = giveCard(state, defender, "teleport", "TP", 0);
|
||||
const d = state.players.find((p) => p.id === defender)!;
|
||||
const home = { ...d.position };
|
||||
state = must(state, attacker, {
|
||||
type: "cast", instanceId: fb.instanceId, target: { kind: "player", playerId: defender },
|
||||
});
|
||||
state = must(state, defender, { type: "counteract", instanceId: tp.instanceId, params: { cell: { x: home.x, y: home.y + 1 } } });
|
||||
state = must(state, attacker, { type: "counteract", instanceId: aa.instanceId });
|
||||
state = must(state, defender, { type: "pass" });
|
||||
const after = state.players.find((p) => p.id === defender)!;
|
||||
expect(cellKey(after.position)).toBe(cellKey(home));
|
||||
expect(after.life).toBe(10);
|
||||
});
|
||||
|
||||
it("reaches at most four spaces", () => {
|
||||
let { state } = newGame();
|
||||
state = toRound2(state);
|
||||
@@ -594,7 +644,7 @@ describe("teleport as a counteraction", () => {
|
||||
|
||||
describe("slime holds spells", () => {
|
||||
function slimeRig() {
|
||||
let { state } = createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"], deckRev: 5 });
|
||||
let { state } = createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
state = toRound2(state);
|
||||
const caster = activePlayer(state);
|
||||
const victim = state.players.find((p) => p.id !== caster.id)!;
|
||||
@@ -647,7 +697,6 @@ describe("slime holds spells", () => {
|
||||
state = must(state, rig.victim, { type: "move", direction: rig.slimeAt.side });
|
||||
state = must(state, rig.victim, { type: "counteract", instanceId: "full-reflection#FR" });
|
||||
state = must(state, rig.caster, { type: "pass" });
|
||||
state = must(state, rig.victim, { type: "pass" });
|
||||
expect(state.players.find((p) => p.id === rig.caster)!.life).toBe(15);
|
||||
expect(state.players.find((p) => p.id === rig.victim)!.life).toBe(15);
|
||||
});
|
||||
@@ -672,12 +721,12 @@ describe("slime holds spells", () => {
|
||||
});
|
||||
|
||||
describe("answering counteractions (FAQ rulings)", () => {
|
||||
function rev6() {
|
||||
return createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic"], deckRev: 6 });
|
||||
function freshGame() {
|
||||
return createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic"] });
|
||||
}
|
||||
|
||||
it("ABSORB SPELL steals a FULL REFLECTION out of the air", () => {
|
||||
let { state } = rev6();
|
||||
let { state } = freshGame();
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
const fb = giveCard(state, attacker, "fireball");
|
||||
@@ -697,7 +746,7 @@ describe("answering counteractions (FAQ rulings)", () => {
|
||||
});
|
||||
|
||||
it("FULL SHIELD cannot be absorbed — it is not cast at you", () => {
|
||||
let { state } = rev6();
|
||||
let { state } = freshGame();
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
const fb = giveCard(state, attacker, "fireball");
|
||||
@@ -712,8 +761,8 @@ describe("answering counteractions (FAQ rulings)", () => {
|
||||
if (!r.ok) expect(r.error).toMatch(/cannot be absorbed/);
|
||||
});
|
||||
|
||||
it("ANTI-ANTI does not work against a teleport escape (rev 6)", () => {
|
||||
let { state } = rev6();
|
||||
it("ANTI-ANTI does not work against a teleport escape", () => {
|
||||
let { state } = freshGame();
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
const fb = giveCard(state, attacker, "fireball");
|
||||
@@ -728,16 +777,15 @@ describe("answering counteractions (FAQ rulings)", () => {
|
||||
const r = applyCommand(state, attacker, { type: "counteract", instanceId: aa.instanceId });
|
||||
expect(r.ok).toBe(false);
|
||||
state = must(state, attacker, { type: "pass" });
|
||||
state = must(state, defender, { type: "pass" });
|
||||
const after = state.players.find((p) => p.id === defender)!;
|
||||
expect(after.life).toBe(15);
|
||||
expect(cellKey(after.position)).toBe(cellKey(escape));
|
||||
});
|
||||
});
|
||||
|
||||
describe("rules revision 8", () => {
|
||||
describe("speed and warp-token creation", () => {
|
||||
it("a SPEED bonus turn burns a turn of durations on the hastened wizard", () => {
|
||||
let { state } = createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic"], deckRev: 8 });
|
||||
let { state } = createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic"] });
|
||||
state = toRound2(state);
|
||||
const me = activePlayer(state);
|
||||
const other = state.players.find((p) => p.id !== me.id)!;
|
||||
@@ -756,7 +804,7 @@ describe("rules revision 8", () => {
|
||||
});
|
||||
|
||||
it("nothing can be created on a dimensional warp token", () => {
|
||||
let { state } = createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"], deckRev: 8 });
|
||||
let { state } = createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
state = toRound2(state);
|
||||
const me = activePlayer(state);
|
||||
const spot = { x: me.position.x + 1, y: me.position.y };
|
||||
@@ -769,3 +817,382 @@ describe("rules revision 8", () => {
|
||||
if (!r.ok) expect(r.error).toMatch(/warp shimmers/);
|
||||
});
|
||||
});
|
||||
|
||||
describe("redirection", () => {
|
||||
it("the two chosen exits connect; their old partners pair with each other", () => {
|
||||
let { state } = createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic"] });
|
||||
state = toRound2(state);
|
||||
const me = activePlayer(state);
|
||||
// Pick two exits that are NOT already partners.
|
||||
const warps = state.board.warps;
|
||||
const wa = warps[0]!;
|
||||
const wb = warps.find((w) => cellKey(w.from.cell) !== cellKey(wa.from.cell) &&
|
||||
cellKey(w.from.cell) !== cellKey(wa.to.cell))!;
|
||||
const paCell = { ...wa.to.cell };
|
||||
const pbCell = { ...wb.to.cell };
|
||||
const rd = giveCard(state, me.id, "redirection", "RD", 0);
|
||||
state = must(state, me.id, {
|
||||
type: "cast", instanceId: rd.instanceId,
|
||||
target: { kind: "cell", cell: wb.from.cell }, params: { cell: wa.from.cell },
|
||||
});
|
||||
const after = (from: Cell) => state.board.warps.find((w) => cellKey(w.from.cell) === cellKey(from))!;
|
||||
expect(cellKey(after(wa.from.cell).to.cell)).toBe(cellKey(wb.from.cell));
|
||||
expect(cellKey(after(wb.from.cell).to.cell)).toBe(cellKey(wa.from.cell));
|
||||
expect(cellKey(after(paCell).to.cell)).toBe(cellKey(pbCell));
|
||||
expect(cellKey(after(pbCell).to.cell)).toBe(cellKey(paCell));
|
||||
});
|
||||
});
|
||||
|
||||
describe("total stops end the exchange", () => {
|
||||
function faceOffRig() {
|
||||
let { state } = createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic"] });
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
return { state, attacker, defender };
|
||||
}
|
||||
|
||||
it("a declined answer to Force Field resolves at once — no goading re-prompt", () => {
|
||||
let { state, attacker, defender } = faceOffRig();
|
||||
const fb = giveCard(state, attacker, "fireball");
|
||||
const d = state.players.find((p) => p.id === defender)!;
|
||||
const lifeBefore = d.life;
|
||||
d.hand[0] = { instanceId: "force-field#T", cardId: "force-field" };
|
||||
|
||||
state = must(state, attacker, { type: "cast", instanceId: fb.instanceId, target: { kind: "player", playerId: defender } });
|
||||
state = must(state, defender, { type: "counteract", instanceId: "force-field#T" });
|
||||
state = must(state, attacker, { type: "pass" });
|
||||
expect(state.stack).toBeNull();
|
||||
expect(state.players.find((p) => p.id === defender)!.life).toBe(lifeBefore);
|
||||
});
|
||||
|
||||
it("a partial counter still invites the defender to stack more", () => {
|
||||
let { state, attacker, defender } = faceOffRig();
|
||||
const fb = giveCard(state, attacker, "fireball");
|
||||
const d = state.players.find((p) => p.id === defender)!;
|
||||
d.hand[0] = { instanceId: "blunt#T", cardId: "blunt" };
|
||||
|
||||
state = must(state, attacker, { type: "cast", instanceId: fb.instanceId, target: { kind: "player", playerId: defender } });
|
||||
state = must(state, defender, { type: "counteract", instanceId: "blunt#T" });
|
||||
state = must(state, attacker, { type: "pass" });
|
||||
expect(state.stack).not.toBeNull();
|
||||
expect(state.stack!.waitingOn).toBe(defender);
|
||||
});
|
||||
|
||||
it("a nullified shield is no stop — the exchange returns to the defender", () => {
|
||||
let { state, attacker, defender } = faceOffRig();
|
||||
const fb = giveCard(state, attacker, "fireball");
|
||||
const a = state.players.find((p) => p.id === attacker)!;
|
||||
const d = state.players.find((p) => p.id === defender)!;
|
||||
a.hand[1] = { instanceId: "anti-anti#T", cardId: "anti-anti" };
|
||||
d.hand[0] = { instanceId: "full-shield#T", cardId: "full-shield" };
|
||||
|
||||
state = must(state, attacker, { type: "cast", instanceId: fb.instanceId, target: { kind: "player", playerId: defender } });
|
||||
state = must(state, defender, { type: "counteract", instanceId: "full-shield#T" });
|
||||
state = must(state, attacker, { type: "counteract", instanceId: "anti-anti#T" });
|
||||
state = must(state, defender, { type: "pass" });
|
||||
expect(state.players.find((p) => p.id === defender)!.life).toBeLessThan(15);
|
||||
});
|
||||
});
|
||||
|
||||
describe("escapes and elemental walls as counteractions", () => {
|
||||
function rigged(attackId: string, defenderCards: { instanceId: string; cardId: string }[]) {
|
||||
let { state } = createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic"] });
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
const atk = giveCard(state, attacker, attackId);
|
||||
const d = state.players.find((p) => p.id === defender)!;
|
||||
defenderCards.forEach((c, i) => { d.hand[i] = c; });
|
||||
state = must(state, attacker, {
|
||||
type: "cast", instanceId: atk.instanceId, target: { kind: "player", playerId: defender },
|
||||
});
|
||||
return { state, attacker, defender, atk };
|
||||
}
|
||||
|
||||
it("invisible vanishes mid-stack: the sustained goes up, the hit needs a 1", () => {
|
||||
let { state, defender } = rigged("fireball", [
|
||||
{ instanceId: "invisible#T", cardId: "invisible" },
|
||||
{ instanceId: "number-3#T", cardId: "number-3" },
|
||||
]);
|
||||
state = must(state, defender, {
|
||||
type: "counteract", instanceId: "invisible#T", numberInstanceIds: ["number-3#T"],
|
||||
});
|
||||
const fx = state.sustained.find((s) => s.cardId === "invisible" && s.targetId === defender);
|
||||
expect(fx).toBeDefined();
|
||||
expect(fx!.remainingTurns).toBe(3);
|
||||
// The attached number left the hand with the spell.
|
||||
const d = state.players.find((p) => p.id === defender)!;
|
||||
expect(d.hand.some((c) => c.instanceId === "number-3#T")).toBe(false);
|
||||
});
|
||||
|
||||
it("anti-anti cannot pin the vanishing — escape is escape", () => {
|
||||
let { state, attacker, defender } = rigged("fireball", [
|
||||
{ instanceId: "invisible#T", cardId: "invisible" },
|
||||
]);
|
||||
state = must(state, defender, { type: "counteract", instanceId: "invisible#T" });
|
||||
const a = state.players.find((p) => p.id === attacker)!;
|
||||
a.hand[1] = { instanceId: "anti-anti#T", cardId: "anti-anti" };
|
||||
const refused = applyCommand(state, attacker, { type: "counteract", instanceId: "anti-anti#T" });
|
||||
expect(refused.ok).toBe(false);
|
||||
});
|
||||
|
||||
it("waterwall meets the fireball and stops it whole", () => {
|
||||
let { state, attacker, defender } = rigged("fireball", [
|
||||
{ instanceId: "waterwall#T", cardId: "waterwall" },
|
||||
]);
|
||||
const lifeBefore = state.players.find((p) => p.id === defender)!.life;
|
||||
state = must(state, defender, { type: "counteract", instanceId: "waterwall#T" });
|
||||
state = must(state, attacker, { type: "pass" });
|
||||
// A total stop: the attacker's declined answer resolves at once.
|
||||
expect(state.stack).toBeNull();
|
||||
expect(state.players.find((p) => p.id === defender)!.life).toBe(lifeBefore);
|
||||
});
|
||||
|
||||
it("waterwall refuses everything that is not a fireball", () => {
|
||||
let { state, defender } = rigged("dagger", [
|
||||
{ instanceId: "waterwall#T", cardId: "waterwall" },
|
||||
]);
|
||||
const refused = applyCommand(state, defender, { type: "counteract", instanceId: "waterwall#T" });
|
||||
expect(refused.ok).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("empathy as a counteraction", () => {
|
||||
function empathyRig() {
|
||||
let { state } = createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
const fb = giveCard(state, attacker, "fireball");
|
||||
const d = state.players.find((p) => p.id === defender)!;
|
||||
d.hand[0] = { instanceId: "empathy#T", cardId: "empathy" };
|
||||
d.hand[1] = { instanceId: "number-3#T", cardId: "number-3" };
|
||||
state = must(state, attacker, {
|
||||
type: "cast", instanceId: fb.instanceId, target: { kind: "player", playerId: defender },
|
||||
});
|
||||
return { state, attacker, defender };
|
||||
}
|
||||
|
||||
it("the blow lands on both — and the link lingers its number's turns", () => {
|
||||
let { state, attacker, defender } = empathyRig();
|
||||
state = must(state, defender, {
|
||||
type: "counteract", instanceId: "empathy#T", numberInstanceIds: ["number-3#T"],
|
||||
});
|
||||
state = must(state, attacker, { type: "pass" });
|
||||
state = must(state, defender, { type: "pass" });
|
||||
expect(state.players.find((p) => p.id === defender)!.life).toBe(10);
|
||||
expect(state.players.find((p) => p.id === attacker)!.life).toBe(10);
|
||||
const fx = state.sustained.find((f) => f.cardId === "empathy" && f.targetId === defender);
|
||||
expect(fx?.remainingTurns).toBe(3);
|
||||
});
|
||||
|
||||
it("anti-anti severs the link: no mirror, no lingering spell", () => {
|
||||
let { state, attacker, defender } = empathyRig();
|
||||
state = must(state, defender, { type: "counteract", instanceId: "empathy#T" });
|
||||
const a = state.players.find((p) => p.id === attacker)!;
|
||||
a.hand[1] = { instanceId: "anti-anti#T", cardId: "anti-anti" };
|
||||
state = must(state, attacker, { type: "counteract", instanceId: "anti-anti#T" });
|
||||
state = must(state, defender, { type: "pass" });
|
||||
expect(state.players.find((p) => p.id === defender)!.life).toBe(10);
|
||||
expect(state.players.find((p) => p.id === attacker)!.life).toBe(15);
|
||||
expect(state.sustained.some((f) => f.cardId === "empathy" && f.targetId === defender)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("empathy mirrors resolution-hook blows", () => {
|
||||
it("a believed illusion bites both wizards", () => {
|
||||
let { state } = createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
const ill = giveCard(state, attacker, "illusionary-attack");
|
||||
const d = state.players.find((p) => p.id === defender)!;
|
||||
d.hand[0] = { instanceId: "empathy#T", cardId: "empathy" };
|
||||
state = must(state, attacker, {
|
||||
type: "cast", instanceId: ill.instanceId,
|
||||
target: { kind: "player", playerId: defender },
|
||||
params: { cardId: "fireball" },
|
||||
});
|
||||
state = must(state, defender, { type: "counteract", instanceId: "empathy#T" });
|
||||
state = must(state, attacker, { type: "pass" });
|
||||
state = must(state, defender, { type: "pass" });
|
||||
const dAfter = state.players.find((p) => p.id === defender)!;
|
||||
const aAfter = state.players.find((p) => p.id === attacker)!;
|
||||
// Whichever way belief rolled, the two lives moved in lockstep.
|
||||
expect(15 - aAfter.life).toBe(15 - dAfter.life);
|
||||
});
|
||||
});
|
||||
|
||||
describe("the reflected-attack window", () => {
|
||||
function reflectRig() {
|
||||
let { state } = createGame({ playerIds: ["a", "b"], seed: 42, sets: ["basic"] });
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
const sd = giveCard(state, attacker, "sudden-death");
|
||||
giveCard(state, defender, "full-reflection", "FR", 0);
|
||||
state = must(state, attacker, {
|
||||
type: "cast", instanceId: sd.instanceId, target: { kind: "player", playerId: defender },
|
||||
});
|
||||
state = must(state, defender, { type: "counteract", instanceId: "full-reflection#FR" });
|
||||
// The attacker's pass meets the total stop and settles the reflection —
|
||||
// which opens the returned spell's window, waiting on the caster.
|
||||
state = must(state, attacker, { type: "pass" });
|
||||
return { state, attacker, defender };
|
||||
}
|
||||
|
||||
it("the returned spell opens a window: absorb soaks the reflected blast", () => {
|
||||
let { state, attacker, defender } = reflectRig();
|
||||
// The reflection settled into a NEW stack: the caster now defends.
|
||||
expect(state.stack).not.toBeNull();
|
||||
expect(state.stack!.defenderId).toBe(attacker);
|
||||
expect(state.stack!.reflectedBase).toEqual({ damage: 10, duration: 0 });
|
||||
giveCard(state, attacker, "absorb", "AB", 0);
|
||||
state = must(state, attacker, { type: "counteract", instanceId: "absorb#AB" });
|
||||
state = must(state, defender, { type: "pass" });
|
||||
state = must(state, attacker, { type: "pass" });
|
||||
// 10 reflected minus absorb's 3.
|
||||
expect(state.players.find((p) => p.id === attacker)!.life).toBe(8);
|
||||
expect(state.players.find((p) => p.id === defender)!.life).toBe(15);
|
||||
});
|
||||
|
||||
it("a second full reflection turns it around again — the ping-pong war", () => {
|
||||
let { state, attacker, defender } = reflectRig();
|
||||
giveCard(state, attacker, "full-reflection", "FR2", 0);
|
||||
state = must(state, attacker, { type: "counteract", instanceId: "full-reflection#FR2" });
|
||||
state = must(state, defender, { type: "pass" });
|
||||
// Turned around again: now the original defender must answer it.
|
||||
expect(state.stack).not.toBeNull();
|
||||
expect(state.stack!.defenderId).toBe(defender);
|
||||
state = must(state, defender, { type: "pass" });
|
||||
expect(state.players.find((p) => p.id === defender)!.life).toBe(5);
|
||||
expect(state.players.find((p) => p.id === attacker)!.life).toBe(15);
|
||||
});
|
||||
});
|
||||
|
||||
describe("a reflected lightning blast ends the caster's turn", () => {
|
||||
function boltRig() {
|
||||
let { state } = createGame({ playerIds: ["a", "b"], seed: 42, sets: ["basic"] });
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
const lb = giveCard(state, attacker, "lightning-blast");
|
||||
giveCard(state, attacker, "number-3", "N", 1);
|
||||
giveCard(state, defender, "full-reflection", "FR", 0);
|
||||
state = must(state, attacker, {
|
||||
type: "cast", instanceId: lb.instanceId, numberInstanceIds: ["number-3#N"],
|
||||
target: { kind: "player", playerId: defender },
|
||||
});
|
||||
state = must(state, defender, { type: "counteract", instanceId: "full-reflection#FR" });
|
||||
state = must(state, attacker, { type: "pass" });
|
||||
// rev 25+: the returned bolt opens its window; the caster declines to answer.
|
||||
if (state.stack) state = must(state, attacker, { type: "pass" });
|
||||
return { state, attacker, defender };
|
||||
}
|
||||
|
||||
it("FAQ: 'you lose the rest of your turn and can't draw cards'", () => {
|
||||
let { state, attacker } = boltRig();
|
||||
expect(state.players.find((p) => p.id === attacker)!.life).toBe(12);
|
||||
expect(state.turn.actionsEnded).toBe(true);
|
||||
// No more marching, and the end-of-turn draw comes up empty.
|
||||
expect(applyCommand(state, attacker, { type: "move", direction: "N" }).ok).toBe(false);
|
||||
const before = state.players.find((p) => p.id === attacker)!.hand.length;
|
||||
state = must(state, attacker, { type: "endTurn", draw: 2 });
|
||||
expect(state.players.find((p) => p.id === attacker)!.hand.length).toBe(before);
|
||||
// And the stun still costs the next turn.
|
||||
expect(state.players.find((p) => p.id === attacker)!.lostTurns
|
||||
+ (activePlayer(state).id === attacker ? 1 : 0)).toBeGreaterThanOrEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("fireball burns only the stones in play", () => {
|
||||
it("a displayed stone dies; a hidden one stays secret and safe", () => {
|
||||
let { state } = createGame({ playerIds: ["a", "b"], seed: 42, sets: ["basic"] });
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
const fb = giveCard(state, attacker, "fireball");
|
||||
const d = state.players.find((p) => p.id === defender)!;
|
||||
d.hand[0] = { instanceId: "powerstone#T", cardId: "powerstone" };
|
||||
d.hand[1] = { instanceId: "speedstone#T", cardId: "speedstone" };
|
||||
d.displayed = ["powerstone#T"]; // only the powerstone is on the table
|
||||
state = must(state, attacker, { type: "cast", instanceId: fb.instanceId, target: { kind: "player", playerId: defender } });
|
||||
state = must(state, defender, { type: "pass" });
|
||||
const after = state.players.find((p) => p.id === defender)!;
|
||||
expect(after.hand.some((c) => c.instanceId === "powerstone#T")).toBe(false);
|
||||
expect(after.hand.some((c) => c.instanceId === "speedstone#T")).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("stone dead counts only the stones in play", () => {
|
||||
it("hidden stones neither add damage nor betray their count", () => {
|
||||
let { state } = createGame({ playerIds: ["a", "b"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
const sd = giveCard(state, attacker, "stone-dead");
|
||||
giveCard(state, attacker, "number-3", "N", 1);
|
||||
const d = state.players.find((p) => p.id === defender)!;
|
||||
d.hand[0] = { instanceId: "powerstone#T", cardId: "powerstone" };
|
||||
d.hand[1] = { instanceId: "speedstone#T", cardId: "speedstone" };
|
||||
d.hand[2] = { instanceId: "bloodstone#T", cardId: "bloodstone" };
|
||||
d.displayed = ["powerstone#T"]; // one on the table, two secret
|
||||
state = must(state, attacker, {
|
||||
type: "cast", instanceId: sd.instanceId, numberInstanceIds: ["number-3#N"],
|
||||
target: { kind: "player", playerId: defender },
|
||||
});
|
||||
state = must(state, defender, { type: "pass" });
|
||||
// 3 x 1 displayed stone = 3; the bloodstone is hidden, so it soaks
|
||||
// nothing: 15 - 3 = 12.
|
||||
expect(state.players.find((p) => p.id === defender)!.life).toBe(12);
|
||||
});
|
||||
});
|
||||
|
||||
describe("MENTAL FORCE respects the victim's three walked spaces", () => {
|
||||
it("a destination beyond the walls is refused up front, card kept", () => {
|
||||
let { state } = newGame();
|
||||
state = toRound2(state);
|
||||
const caster = activePlayer(state);
|
||||
const victim = state.players.find((p) => p.id !== caster.id)!;
|
||||
caster.position = { x: 0, y: 0 };
|
||||
victim.position = { x: 2, y: 4 };
|
||||
// Seal the victim into their square: every walked space is out of
|
||||
// reach, so ANY other destination is beyond three moved spaces.
|
||||
for (const side of SIDES) {
|
||||
state.edgeOverrides[edgeKey(victim.position, side)] = "wall";
|
||||
}
|
||||
const mf = giveCard(state, caster.id, "mental-force", "MF");
|
||||
const far = { x: 4, y: 9 };
|
||||
const refused = applyCommand(state, caster.id, {
|
||||
type: "cast", instanceId: mf.instanceId,
|
||||
target: { kind: "player", playerId: victim.id }, params: { cell: far },
|
||||
});
|
||||
expect(refused.ok).toBe(false);
|
||||
if (!refused.ok) expect(refused.error).toContain("three moved spaces");
|
||||
// The card is still in hand — nothing was spent on the refusal.
|
||||
expect(state.players.find((p) => p.id === caster.id)!.hand.some((c) => c.instanceId === mf.instanceId)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("the bent sight-trace shows AROUND THE CORNER's legs", () => {
|
||||
it("a bentCorner stack yields two auditable legs through a midpoint", () => {
|
||||
let { state } = newGame();
|
||||
state = toRound2(state);
|
||||
const a = activePlayer(state);
|
||||
const d = state.players.find((p) => p.id !== a.id)!;
|
||||
// Diagonal neighbors: center-to-center sight grazes the shared corner
|
||||
// (blocked, strict reading), but the legs through (3,2) are opened.
|
||||
a.position = { x: 2, y: 2 };
|
||||
d.position = { x: 3, y: 3 };
|
||||
state.edgeOverrides[edgeKey({ x: 2, y: 2 }, "E")] = "open";
|
||||
state.edgeOverrides[edgeKey({ x: 3, y: 2 }, "S")] = "open";
|
||||
state.stack = {
|
||||
attackerId: a.id, defenderId: d.id,
|
||||
attackCard: { instanceId: "fireball#T", cardId: "fireball" },
|
||||
numberValue: null, amplifyFactor: 1, extendFactor: 1,
|
||||
powerAttackPoints: 0, params: null, kind: "spell",
|
||||
counters: [], waitingOn: d.id, bentCorner: true,
|
||||
};
|
||||
// Wall the straight diagonal shut so only the bend can answer.
|
||||
state.edgeOverrides[edgeKey({ x: 2, y: 2 }, "S")] = "wall";
|
||||
state.edgeOverrides[edgeKey({ x: 2, y: 3 }, "E")] = "wall";
|
||||
const traced = stackSightTrace(viewFor(state, d.id));
|
||||
expect(traced).not.toBeNull();
|
||||
// The engine promises A workable corner, not which one.
|
||||
expect(traced?.bend).toBeDefined();
|
||||
expect(traced?.bend?.mid).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { applyCommand, activePlayer, boardView, creatureAt, type GameState, type PlayerId, createGame } from "../src/game";
|
||||
import { cellKey, SIDES, stepTarget, type Side } from "../src/board";
|
||||
import {
|
||||
type CreatureState, applyCommand, activePlayer, boardView, creatureAt, type GameState, type PlayerId, createGame } from "../src/game";
|
||||
import { cellKey, edgeKey, SIDES, stepTarget, type Cell, type Side } from "../src/board";
|
||||
import type { CardInstance } from "../src/cards";
|
||||
import { newExpansionGame as newGame, must, giveCard, toRound2, emptyNeighborCell } from "./helpers";
|
||||
import { newExpansionGame as newGame, must, giveCard, toRound2, emptyNeighborCell, pushSustained } from "./helpers";
|
||||
|
||||
/** Summon a creature next to its creator (round 2+, consumes the attack). */
|
||||
function summon(state: GameState, playerId: PlayerId, kind: string, tag = "S") {
|
||||
@@ -17,7 +18,8 @@ function summon(state: GameState, playerId: PlayerId, kind: string, tag = "S") {
|
||||
|
||||
describe("expansion deck", () => {
|
||||
it("basic + expansion1 builds the full 200-card game", () => {
|
||||
const { state } = newGame();
|
||||
// Three seats: two-player games shed LIFESAVER from the build.
|
||||
const { state } = newGame(42, ["a", "b", "c"]);
|
||||
const total = state.deck.length + state.discard.length +
|
||||
state.players.reduce((s, p) => s + p.hand.length, 0);
|
||||
expect(total).toBe(200);
|
||||
@@ -59,6 +61,8 @@ describe("monsters", () => {
|
||||
state = must(state, me, {
|
||||
type: "creatureAttack", creatureId: state.creatures[0]!.id, targetId: victim.id,
|
||||
});
|
||||
// The blow opens the victim's counteraction window; they take it raw.
|
||||
state = must(state, victim.id, { type: "pass" });
|
||||
expect(state.players.find((p) => p.id !== me)!.life).toBe(13);
|
||||
});
|
||||
|
||||
@@ -136,6 +140,7 @@ describe("monsters", () => {
|
||||
break;
|
||||
}
|
||||
}
|
||||
state = must(state, enemy2.id, { type: "pass" });
|
||||
const bitten = state.players.find((p) => p.id !== me)!;
|
||||
expect(bitten.life).toBe(13);
|
||||
expect(bitten.hand.length).toBe(6);
|
||||
@@ -205,6 +210,16 @@ describe("monsters", () => {
|
||||
});
|
||||
expect(state.creatures[0]!.maxDamage).toBe(8);
|
||||
|
||||
// "Doubles the existing life-points OR movement rate" — the other choice.
|
||||
const movesBefore = state.creatures[0]!.movesPerTurn;
|
||||
const mm2 = giveCard(state, me, "mega-monster", "MM2", 3);
|
||||
state = must(state, me, {
|
||||
type: "cast", instanceId: mm2.instanceId, target: { kind: "creature", creatureId: id },
|
||||
params: { boost: "movement" },
|
||||
});
|
||||
expect(state.creatures[0]!.movesPerTurn).toBe(movesBefore * 2);
|
||||
expect(state.creatures[0]!.maxDamage).toBe(8);
|
||||
|
||||
const dc = giveCard(state, me, "dispel-creation", "DC", 2);
|
||||
state = must(state, me, {
|
||||
type: "cast", instanceId: dc.instanceId, target: { kind: "cell", cell: state.creatures[0]!.position },
|
||||
@@ -283,9 +298,9 @@ describe("expansion support cards", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("counteracting a creature's blow (rules rev 4)", () => {
|
||||
function rev4() {
|
||||
return createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"], deckRev: 4 });
|
||||
describe("counteracting a creature's blow", () => {
|
||||
function freshGame() {
|
||||
return createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
}
|
||||
function wraithOnVictim(state: GameState) {
|
||||
state = toRound2(state);
|
||||
@@ -302,7 +317,7 @@ describe("counteracting a creature's blow (rules rev 4)", () => {
|
||||
}
|
||||
|
||||
it("BLUNT halves the wraith's touch; the card theft still lands", () => {
|
||||
let { state } = rev4();
|
||||
let { state } = freshGame();
|
||||
const rig = wraithOnVictim(state);
|
||||
state = rig.state;
|
||||
giveCard(state, rig.victim, "blunt", "B", 0);
|
||||
@@ -318,7 +333,7 @@ describe("counteracting a creature's blow (rules rev 4)", () => {
|
||||
});
|
||||
|
||||
it("FULL REFLECTION turns the touch back on the wraith, theft and all", () => {
|
||||
let { state } = rev4();
|
||||
let { state } = freshGame();
|
||||
const rig = wraithOnVictim(state);
|
||||
state = rig.state;
|
||||
giveCard(state, rig.victim, "full-reflection", "FR", 0);
|
||||
@@ -331,20 +346,11 @@ describe("counteracting a creature's blow (rules rev 4)", () => {
|
||||
const wraith = state.creatures.find((c) => c.id === "w1")!;
|
||||
expect(wraith.damage).toBe(2);
|
||||
});
|
||||
|
||||
it("legacy games (rev < 4) keep the instant touch", () => {
|
||||
let { state } = createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
const rig = wraithOnVictim(state);
|
||||
state = rig.state;
|
||||
state = must(state, rig.controller, { type: "moveCreature", creatureId: "w1", direction: rig.side });
|
||||
expect(state.stack).toBeNull();
|
||||
expect(state.players.find((p) => p.id === rig.victim)!.life).toBe(13);
|
||||
});
|
||||
});
|
||||
|
||||
describe("big man (rules rev 5)", () => {
|
||||
describe("big man", () => {
|
||||
function bigRig() {
|
||||
let { state } = createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"], deckRev: 5 });
|
||||
let { state } = createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
state = toRound2(state);
|
||||
const giant = activePlayer(state);
|
||||
state.sustained.push({
|
||||
@@ -402,8 +408,7 @@ describe("big man (rules rev 5)", () => {
|
||||
expect(r.ok).toBe(false);
|
||||
return;
|
||||
}
|
||||
// Seed offered no walled pocket beside the home; that is fine — the
|
||||
// pushable case above pins the mechanism.
|
||||
throw new Error("setup: seed offered no walled pocket beside the home");
|
||||
});
|
||||
|
||||
it("monsters cannot enter the giant's square", () => {
|
||||
@@ -440,3 +445,345 @@ describe("big man (rules rev 5)", () => {
|
||||
expect(g.inPit).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("monsters roll to hit the hidden", () => {
|
||||
function creatureVsInvisible() {
|
||||
let { state } = createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
state = toRound2(state);
|
||||
const me = activePlayer(state).id;
|
||||
const victim = state.players.find((p) => p.id !== me)!;
|
||||
const r = summon(state, me, "skeleton");
|
||||
state = r.state;
|
||||
const bones = state.creatures[0]!;
|
||||
bones.justCreated = false;
|
||||
bones.attackUsed = false;
|
||||
bones.position = { ...victim.position };
|
||||
state.sustained.push({
|
||||
id: "fx1", cardId: "invisible", casterId: victim.id, targetId: victim.id,
|
||||
remainingTurns: 3, data: {},
|
||||
});
|
||||
return { state, me, victim, skeletonId: bones.id };
|
||||
}
|
||||
|
||||
it("the skeleton's blow takes the 1-in-4 roll — 'any attack' means any", () => {
|
||||
let { state, me, victim, skeletonId } = creatureVsInvisible();
|
||||
const rngBefore = JSON.stringify(state.rng);
|
||||
state = must(state, me, { type: "creatureAttack", creatureId: skeletonId, targetId: victim.id });
|
||||
state = must(state, victim.id, { type: "pass" });
|
||||
// The die was consumed, whichever way it landed.
|
||||
expect(JSON.stringify(state.rng)).not.toBe(rngBefore);
|
||||
});
|
||||
});
|
||||
|
||||
describe("elimination sweeps the board either way", () => {
|
||||
it("a treasure-eliminated wizard's fire imp vanishes with them", () => {
|
||||
let { state } = createGame({ playerIds: ["a", "b", "c"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
const victim = state.players.find((p) => p.id === "c")!;
|
||||
state.creatures.push({
|
||||
id: "imp1", kind: "fire-imp", controllerId: "c",
|
||||
position: { ...victim.position },
|
||||
damage: 0, maxDamage: 5, movesPerTurn: 0, movementUsed: 0,
|
||||
attackUsed: false, justCreated: false,
|
||||
wallPassesPerTurn: 0, wallPassUsed: 0, scorchedThisTurn: [],
|
||||
});
|
||||
state.sustained.push({
|
||||
id: "fx-med", cardId: "medusa", casterId: "a", targetId: "c",
|
||||
remainingTurns: 3, data: {},
|
||||
});
|
||||
// Both of c's treasures sit captured on living enemies' home bases.
|
||||
const mine = state.treasures.filter((t) => t.owner === "c");
|
||||
expect(mine.length).toBe(2);
|
||||
mine[0]!.position = { ...state.players.find((p) => p.id === "a")!.home };
|
||||
mine[0]!.carriedBy = null;
|
||||
mine[1]!.position = { ...state.players.find((p) => p.id === "b")!.home };
|
||||
mine[1]!.carriedBy = null;
|
||||
const active = activePlayer(state).id;
|
||||
const r = applyCommand(state, active, { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
expect(state.players.find((p) => p.id === "c")!.alive).toBe(false);
|
||||
expect(state.creatures.some((c) => c.controllerId === "c")).toBe(false);
|
||||
expect(state.sustained.some((s) => s.targetId === "c")).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("creatures walk open doorways", () => {
|
||||
it("a skeleton passes a door whose lock was removed", () => {
|
||||
let { state } = createGame({ playerIds: ["a", "b"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
state = toRound2(state);
|
||||
const view = boardView(state);
|
||||
for (const [key, edge] of Object.entries(view.edges)) {
|
||||
if (edge !== "door") continue;
|
||||
const [kind, coords] = key.split(":") as [string, string];
|
||||
const [x, y] = coords.split(",").map(Number) as [number, number];
|
||||
const side = kind === "V" ? ("E" as Side) : ("S" as Side);
|
||||
state.doorStates[key] = "removed";
|
||||
state.creatures.push({
|
||||
id: "sk1", kind: "skeleton", controllerId: activePlayer(state).id,
|
||||
position: { x, y }, damage: 0, maxDamage: 4, movesPerTurn: 3,
|
||||
movementUsed: 0, attackUsed: false, justCreated: false,
|
||||
wallPassesPerTurn: 0, wallPassUsed: 0, scorchedThisTurn: [],
|
||||
});
|
||||
const r = applyCommand(state, activePlayer(state).id, {
|
||||
type: "moveCreature", creatureId: "sk1", direction: side,
|
||||
});
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
const sk = r.state.creatures.find((c) => c.id === "sk1")!;
|
||||
expect(cellKey(sk.position)).toBe(cellKey({ x: x + (side === "E" ? 1 : 0), y: y + (side === "S" ? 1 : 0) }));
|
||||
return;
|
||||
}
|
||||
throw new Error("setup: seed 42 grew a maze with no doors");
|
||||
});
|
||||
});
|
||||
|
||||
describe("the wave carries monsters", () => {
|
||||
it("a cornered skeleton takes the waterwall crush", () => {
|
||||
let { state } = createGame({ playerIds: ["a", "b"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
state = toRound2(state);
|
||||
const caster = activePlayer(state);
|
||||
// A skeleton pinned against solid stone, one square from the wave's edge.
|
||||
const view = boardView(state);
|
||||
for (const [key, edge] of Object.entries(view.edges)) {
|
||||
if (edge !== "wall") continue;
|
||||
const [kind, coords] = key.split(":") as [string, string];
|
||||
if (kind !== "H") continue;
|
||||
const [x, y] = coords.split(",").map(Number) as [number, number];
|
||||
// Wave from this wall southward washes the square below.
|
||||
const below = { x, y: y + 1 };
|
||||
if (!view.cells[cellKey(below)]) continue;
|
||||
state.creatures.push({
|
||||
id: "sk1", kind: "skeleton", controllerId: caster.id,
|
||||
position: { ...below }, damage: 0, maxDamage: 4, movesPerTurn: 3,
|
||||
movementUsed: 0, attackUsed: false, justCreated: false,
|
||||
wallPassesPerTurn: 0, wallPassUsed: 0, scorchedThisTurn: [],
|
||||
});
|
||||
// Pin it: stone directly south of it.
|
||||
state.squareContents[cellKey({ x, y: y + 2 })] = { kind: "stone", damage: 0, createdBy: caster.id };
|
||||
caster.position = { x, y };
|
||||
const stw = giveCard(state, caster.id, "stone-to-water");
|
||||
const r = applyCommand(state, caster.id, {
|
||||
type: "cast", instanceId: stw.instanceId,
|
||||
target: { kind: "edge", cell: { x, y }, side: "S" },
|
||||
});
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
const sk = r.state.creatures.find((c) => c.id === "sk1");
|
||||
// Washed against the stone: it took crush damage (or died of it).
|
||||
if (sk) expect(sk.damage).toBeGreaterThan(0);
|
||||
return;
|
||||
}
|
||||
throw new Error("setup: no horizontal wall with a floor below");
|
||||
});
|
||||
});
|
||||
|
||||
describe("the democratic monster's claw survives the first wizard's death", () => {
|
||||
it("refreshes each round even with the roll-off winner dead", () => {
|
||||
let { state } = createGame({ playerIds: ["a", "b", "c"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
state = toRound2(state);
|
||||
const firstId = state.players[state.turn.firstIndex]!.id;
|
||||
const dm = {
|
||||
id: "dm1", kind: "democratic-monster" as const, controllerId: state.players[0]!.id,
|
||||
position: { x: 0, y: 0 }, damage: 0, maxDamage: 5, movesPerTurn: 3,
|
||||
movementUsed: 0, attackUsed: true, justCreated: false,
|
||||
wallPassesPerTurn: 0, wallPassUsed: 0, scorchedThisTurn: [] as string[],
|
||||
};
|
||||
state.creatures.push(dm);
|
||||
// The roll-off winner falls.
|
||||
const first = state.players.find((p) => p.id === firstId)!;
|
||||
first.alive = false;
|
||||
first.finalHand = [...first.hand];
|
||||
// Walk a full round of the survivors: the claw must refresh.
|
||||
for (let i = 0; i < 4 && state.creatures[0]!.attackUsed; i++) {
|
||||
const active = activePlayer(state);
|
||||
const r = applyCommand(state, active.id, { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
expect(state.creatures[0]!.attackUsed).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("a mid-round democratic monster claws on the next turn", () => {
|
||||
it("creation spends the turn, not the round", () => {
|
||||
let { state } = createGame({ playerIds: ["a", "b"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
state = toRound2(state);
|
||||
const creator = activePlayer(state);
|
||||
const r0 = summon(state, creator.id, "democratic-monster");
|
||||
state = r0.state;
|
||||
const dm = state.creatures.find((c) => c.kind === "democratic-monster")!;
|
||||
expect(dm.attackUsed).toBe(false);
|
||||
expect(dm.justCreated).toBe(true);
|
||||
// Next player's turn: justCreated clears; the claw is live.
|
||||
state = must(state, creator.id, { type: "endTurn", draw: 0 });
|
||||
const mover = activePlayer(state);
|
||||
const victim = state.players.find((p) => p.id !== mover.id)!;
|
||||
const fresh = state.creatures.find((c) => c.kind === "democratic-monster")!;
|
||||
expect(fresh.justCreated).toBe(false);
|
||||
// March it onto the victim: the touch must open.
|
||||
fresh.position = { x: victim.position.x - 1, y: victim.position.y };
|
||||
const r = applyCommand(state, mover.id, { type: "moveCreature", creatureId: fresh.id, direction: "E" });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
expect(r.state.stack?.creatureId ?? null).toBe(fresh.id);
|
||||
});
|
||||
});
|
||||
|
||||
describe("collapsing walls crush monsters too", () => {
|
||||
function wallRig() {
|
||||
let { state } = createGame({ playerIds: ["a", "b"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
state = toRound2(state);
|
||||
const view = boardView(state);
|
||||
for (const [key, edge] of Object.entries(view.edges)) {
|
||||
if (edge !== "wall") continue;
|
||||
const [kind, coords] = key.split(":") as [string, string];
|
||||
const [x, y] = coords.split(",").map(Number) as [number, number];
|
||||
const side = kind === "V" ? ("E" as Side) : ("S" as Side);
|
||||
const other = { x: x + (side === "E" ? 1 : 0), y: y + (side === "S" ? 1 : 0) };
|
||||
if (!view.cells[cellKey(other)]) continue;
|
||||
const caster = activePlayer(state);
|
||||
caster.position = { x, y };
|
||||
state.creatures.push({
|
||||
id: "tr1", kind: "troll", controllerId: caster.id,
|
||||
position: { ...other }, damage: 0, maxDamage: 6, movesPerTurn: 3,
|
||||
movementUsed: 0, attackUsed: false, justCreated: false,
|
||||
wallPassesPerTurn: 0, wallPassUsed: 0, scorchedThisTurn: [],
|
||||
});
|
||||
const dw = giveCard(state, caster.id, "destroy-wall");
|
||||
const r = applyCommand(state, caster.id, {
|
||||
type: "cast", instanceId: dw.instanceId, target: { kind: "edge", cell: { x, y }, side },
|
||||
});
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
return r.state;
|
||||
}
|
||||
throw new Error("setup: no interior wall found");
|
||||
}
|
||||
|
||||
it("the adjacent troll takes the four points", () => {
|
||||
const state = wallRig();
|
||||
const troll = state.creatures.find((c) => c.id === "tr1");
|
||||
// Four points on a six-point troll: hurt but standing (or regenerating).
|
||||
expect(troll?.damage).toBe(4);
|
||||
});
|
||||
});
|
||||
|
||||
describe("the self-stack resolves on a pass", () => {
|
||||
function selfTouch() {
|
||||
let { state } = createGame({ playerIds: ["a", "b"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
state = toRound2(state);
|
||||
const creator = activePlayer(state);
|
||||
state.creatures.push({
|
||||
id: "dm1", kind: "democratic-monster", controllerId: creator.id,
|
||||
position: { x: creator.position.x - 1, y: creator.position.y },
|
||||
damage: 0, maxDamage: 5, movesPerTurn: 3, movementUsed: 0,
|
||||
attackUsed: false, justCreated: false,
|
||||
wallPassesPerTurn: 0, wallPassUsed: 0, scorchedThisTurn: [],
|
||||
});
|
||||
const r = applyCommand(state, creator.id, { type: "moveCreature", creatureId: "dm1", direction: "E" });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
return { state: r.state, creator: creator.id };
|
||||
}
|
||||
|
||||
it("passing your own monster's touch takes the claw and moves on", () => {
|
||||
const { state, creator } = selfTouch();
|
||||
if (!state.stack) return; // a wall between: the touch never opened
|
||||
expect(state.stack.attackerId).toBe(creator);
|
||||
expect(state.stack.defenderId).toBe(creator);
|
||||
const r = applyCommand(state, creator, { type: "pass" });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
expect(r.state.stack).toBeNull();
|
||||
expect(r.state.players.find((p) => p.id === creator)!.life).toBe(13);
|
||||
});
|
||||
});
|
||||
|
||||
describe("fear holds off monsters and unwilling feet alike", () => {
|
||||
it("a commanded monster cannot close within three of the fearsome", () => {
|
||||
let { state } = createGame({ playerIds: ["a", "b"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
const a = state.players.find((p) => p.id === "a")!;
|
||||
const b = state.players.find((p) => p.id === "b")!;
|
||||
// b radiates fear; a's troll stands exactly four away, aimed straight at b.
|
||||
pushSustained(state, {
|
||||
id: "fx-fear", cardId: "fear", casterId: "b", targetId: "b",
|
||||
remainingTurns: 5, data: {},
|
||||
});
|
||||
b.position = { x: 2, y: 5 };
|
||||
a.position = { x: 0, y: 0 };
|
||||
state.creatures.push({
|
||||
id: "troll-1", kind: "troll", controllerId: "a", position: { x: 2, y: 9 },
|
||||
damage: 0, maxDamage: 6, movesPerTurn: 3, movementUsed: 0,
|
||||
wallPassesPerTurn: 0, wallPassUsed: 0, attackUsed: false, justCreated: false,
|
||||
scorchedThisTurn: [],
|
||||
});
|
||||
for (const y of [5, 6, 7, 8]) state.edgeOverrides[edgeKey({ x: 2, y }, "S")] = "open";
|
||||
while (state.players[state.turn.activeIndex]!.id !== "a") {
|
||||
const r = applyCommand(state, state.players[state.turn.activeIndex]!.id, { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
const r = applyCommand(state, "a", { type: "moveCreature", creatureId: "troll-1", direction: "N" });
|
||||
expect(r.ok).toBe(false);
|
||||
if (!r.ok) expect(r.error).toContain("dread");
|
||||
});
|
||||
|
||||
it("a wizard caged inside the dread may round a corner to escape", () => {
|
||||
let { state } = createGame({ playerIds: ["a", "b"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
const a = state.players.find((p) => p.id === "a")!;
|
||||
const b = state.players.find((p) => p.id === "b")!;
|
||||
pushSustained(state, {
|
||||
id: "fx-fear", cardId: "fear", casterId: "b", targetId: "b",
|
||||
remainingTurns: 5, data: {},
|
||||
});
|
||||
// b radiates dread from (2,5). a stands in a dead-end pocket at
|
||||
// (2,3): walls on three sides, so the only way out steps SOUTH —
|
||||
// closer to b — before the corridor east leads clear of the dread.
|
||||
b.position = { x: 2, y: 5 };
|
||||
a.position = { x: 2, y: 3 };
|
||||
for (const side of ["N", "E", "W"] as const) {
|
||||
state.edgeOverrides[edgeKey({ x: 2, y: 3 }, side)] = "wall";
|
||||
}
|
||||
state.edgeOverrides[edgeKey({ x: 2, y: 3 }, "S")] = "open";
|
||||
state.edgeOverrides[edgeKey({ x: 2, y: 4 }, "E")] = "open";
|
||||
state.edgeOverrides[edgeKey({ x: 3, y: 4 }, "E")] = "open";
|
||||
state.edgeOverrides[edgeKey({ x: 4, y: 4 }, "N")] = "open";
|
||||
while (state.players[state.turn.activeIndex]!.id !== "a") {
|
||||
const r0 = applyCommand(state, state.players[state.turn.activeIndex]!.id, { type: "endTurn", draw: 0 });
|
||||
if (!r0.ok) throw new Error(r0.error);
|
||||
state = r0.state;
|
||||
}
|
||||
// The closer step is the only way out: permitted.
|
||||
const r = applyCommand(state, "a", { type: "move", direction: "S" });
|
||||
if (!r.ok) throw new Error("escape step refused: " + r.error);
|
||||
});
|
||||
});
|
||||
|
||||
describe("creatures and the dimensional warp", () => {
|
||||
it("a commanded troll steps through the warp tokens", () => {
|
||||
let { state } = createGame({ playerIds: ["a", "b"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
const you = state.players[state.turn.activeIndex]!.id;
|
||||
state.dimWarps.push({ a: { x: 1, y: 1 }, b: { x: 3, y: 8 } });
|
||||
state.creatures.push({
|
||||
id: "troll-w", kind: "troll", controllerId: you, position: { x: 1, y: 1 },
|
||||
damage: 0, maxDamage: 6, movesPerTurn: 2, movementUsed: 0, attackUsed: false,
|
||||
justCreated: false, wallPassesPerTurn: 0, wallPassUsed: 0, scorchedThisTurn: [],
|
||||
});
|
||||
const r = applyCommand(state, you, { type: "creatureWarpStep", creatureId: "troll-w" });
|
||||
expect(r.ok).toBe(true);
|
||||
if (r.ok) {
|
||||
const troll = r.state.creatures.find((c) => c.id === "troll-w")!;
|
||||
expect(cellKey(troll.position)).toBe(cellKey({ x: 3, y: 8 }));
|
||||
expect(troll.movementUsed).toBe(1);
|
||||
}
|
||||
});
|
||||
|
||||
it("solid stone on the far side refuses the beast", () => {
|
||||
let { state } = createGame({ playerIds: ["a", "b"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
const you = state.players[state.turn.activeIndex]!.id;
|
||||
state.dimWarps.push({ a: { x: 1, y: 1 }, b: { x: 3, y: 8 } });
|
||||
state.squareContents[cellKey({ x: 3, y: 8 })] = { kind: "stone", damage: 0, createdBy: "b" };
|
||||
state.creatures.push({
|
||||
id: "troll-w", kind: "troll", controllerId: you, position: { x: 1, y: 1 },
|
||||
damage: 0, maxDamage: 6, movesPerTurn: 2, movementUsed: 0, attackUsed: false,
|
||||
justCreated: false, wallPassesPerTurn: 0, wallPassUsed: 0, scorchedThisTurn: [],
|
||||
});
|
||||
const r = applyCommand(state, you, { type: "creatureWarpStep", creatureId: "troll-w" });
|
||||
expect(r.ok).toBe(false);
|
||||
if (!r.ok) expect(r.error).toContain("stone");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { applyCommand, activePlayer, boardView, sustainedOn, type GameState } from "../src/game";
|
||||
import { cellKey, edgeKey, neighbor, type Side } from "../src/board";
|
||||
import { applyCommand, activePlayer, boardView, createGame, sustainedOn, type GameState } from "../src/game";
|
||||
import { cellKey, edgeKey, neighbor, opposite, type Side } from "../src/board";
|
||||
import type { CardInstance } from "../src/cards";
|
||||
import { newGame, must, giveCard, toRound2, faceOff, castAt } from "./helpers";
|
||||
|
||||
@@ -111,7 +111,7 @@ describe("doors", () => {
|
||||
throw new Error("no door on this board");
|
||||
}
|
||||
|
||||
it("pick lock opens an adjacent door until end of turn", () => {
|
||||
it("pick lock opens an adjacent door — and it relocks behind the walker", () => {
|
||||
let { state } = newGame();
|
||||
const me = activePlayer(state);
|
||||
const door = findDoor(state);
|
||||
@@ -130,9 +130,8 @@ describe("doors", () => {
|
||||
state = must(state, me.id, { type: "move", direction: dir });
|
||||
expect(cellKey(activePlayer(state).position)).toBe(cellKey(other));
|
||||
|
||||
// Relocks when the turn ends.
|
||||
state = must(state, me.id, { type: "endTurn", draw: 0 });
|
||||
state = must(state, activePlayer(state).id, { type: "endTurn", draw: 0 });
|
||||
// "It will relock behind you": shut at the walker's back at once —
|
||||
// the way back is barred without another pick.
|
||||
expect(state.openDoorEdges.length).toBe(0);
|
||||
expect(applyCommand(state, me.id, { type: "move", direction: dir === "E" ? "W" : "N" }).ok).toBe(false);
|
||||
});
|
||||
@@ -340,9 +339,231 @@ describe("cast modifiers", () => {
|
||||
});
|
||||
state = must(state, defender, { type: "counteract", instanceId: "reverse#R" });
|
||||
state = must(state, attacker, { type: "pass" });
|
||||
state = must(state, defender, { type: "pass" });
|
||||
const d = state.players.find((p) => p.id === defender)!;
|
||||
expect(d.life).toBe(19); // gained 4 instead of losing it
|
||||
expect(d.lostTurns).toBe(1); // the stun still applies
|
||||
});
|
||||
});
|
||||
|
||||
describe("holding the door open (Pick Lock / Master Key)", () => {
|
||||
function doorRig() {
|
||||
let { state } = createGame({ playerIds: ["holder", "guest"], seed: 42, sets: ["basic"] });
|
||||
state = toRound2(state);
|
||||
// Find a door edge; stand the acting player beside it.
|
||||
const view = boardView(state);
|
||||
for (const [key, edge] of Object.entries(view.edges)) {
|
||||
if (edge !== "door") continue;
|
||||
const [kind, coords] = key.split(":") as [string, string];
|
||||
const [x, y] = coords.split(",").map(Number) as [number, number];
|
||||
const cell = { x, y };
|
||||
const side = kind === "V" ? ("E" as Side) : ("S" as Side);
|
||||
const holder = activePlayer(state);
|
||||
holder.position = { ...cell };
|
||||
return { state, key, cell, side, holder: holder.id };
|
||||
}
|
||||
throw new Error("setup: seed 42 grew a maze with no doors");
|
||||
}
|
||||
|
||||
it("a held door outlives the turn and admits another wizard", () => {
|
||||
let { state, key, cell, side, holder } = doorRig();
|
||||
const pick = giveCard(state, holder, "pick-lock");
|
||||
state = must(state, holder, {
|
||||
type: "cast", instanceId: pick.instanceId,
|
||||
target: { kind: "edge", cell, side }, params: { hold: true },
|
||||
});
|
||||
state = must(state, holder, { type: "endTurn", draw: 0 });
|
||||
expect(state.heldDoors.some((h) => h.key === key)).toBe(true);
|
||||
const guest = state.players.find((p) => p.id !== holder)!;
|
||||
guest.position = { ...cell };
|
||||
const r = applyCommand(state, guest.id, { type: "move", direction: side });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
const through = r.state.players.find((p) => p.id === guest.id)!;
|
||||
expect(cellKey(through.position)).toBe(cellKey(neighbor(cell, side)));
|
||||
});
|
||||
|
||||
it("the door swings shut the moment the holder steps away", () => {
|
||||
let { state, key, cell, side, holder } = doorRig();
|
||||
const pick = giveCard(state, holder, "pick-lock");
|
||||
state = must(state, holder, {
|
||||
type: "cast", instanceId: pick.instanceId,
|
||||
target: { kind: "edge", cell, side }, params: { hold: true },
|
||||
});
|
||||
expect(state.heldDoors.some((h) => h.key === key)).toBe(true);
|
||||
// March the holder until adjacency breaks; the sweep must release.
|
||||
let walked = state;
|
||||
let released = false;
|
||||
const dirs: Side[] = ["N", "E", "S", "W"];
|
||||
for (const d1 of dirs) {
|
||||
const r1 = applyCommand(walked, holder, { type: "move", direction: d1 });
|
||||
if (!r1.ok) continue;
|
||||
if (!r1.state.heldDoors.some((h) => h.key === key)) { released = true; break; }
|
||||
for (const d2 of dirs) {
|
||||
const r2 = applyCommand(r1.state, holder, { type: "move", direction: d2 });
|
||||
if (!r2.ok) continue;
|
||||
if (!r2.state.heldDoors.some((h) => h.key === key)) { released = true; break; }
|
||||
}
|
||||
if (released) break;
|
||||
}
|
||||
expect(released).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("a held door is an open doorway to the eye", () => {
|
||||
function sightRig() {
|
||||
let { state } = createGame({ playerIds: ["holder", "pursuer"], seed: 42, sets: ["basic"] });
|
||||
state = toRound2(state);
|
||||
const view = boardView(state);
|
||||
for (const [key, edge] of Object.entries(view.edges)) {
|
||||
if (edge !== "door") continue;
|
||||
const [kind, coords] = key.split(":") as [string, string];
|
||||
const [x, y] = coords.split(",").map(Number) as [number, number];
|
||||
const cell = { x, y };
|
||||
const side = kind === "V" ? ("E" as Side) : ("S" as Side);
|
||||
const holder = activePlayer(state);
|
||||
const pursuer = state.players.find((p) => p.id !== holder.id)!;
|
||||
holder.position = { ...cell };
|
||||
pursuer.position = neighbor(cell, side);
|
||||
return { state, cell, side, holder: holder.id, pursuer: pursuer.id };
|
||||
}
|
||||
throw new Error("setup: seed 42 grew a maze with no doors");
|
||||
}
|
||||
|
||||
it("the holder blasts the pursuer through the held doorway", () => {
|
||||
let { state, cell, side, holder, pursuer } = sightRig();
|
||||
const pick = giveCard(state, holder, "pick-lock");
|
||||
state = must(state, holder, {
|
||||
type: "cast", instanceId: pick.instanceId,
|
||||
target: { kind: "edge", cell, side }, params: { hold: true },
|
||||
});
|
||||
const fb = giveCard(state, holder, "fireball", "FB", 1);
|
||||
const lifeBefore = state.players.find((p) => p.id === pursuer)!.life;
|
||||
state = must(state, holder, {
|
||||
type: "cast", instanceId: fb.instanceId, target: { kind: "player", playerId: pursuer },
|
||||
});
|
||||
state = must(state, pursuer, { type: "pass" });
|
||||
expect(state.players.find((p) => p.id === pursuer)!.life).toBeLessThan(lifeBefore);
|
||||
});
|
||||
|
||||
it("an unlocked door is an open doorway to the wizard at its threshold", () => {
|
||||
let { state, cell, side, holder, pursuer } = sightRig();
|
||||
const pick = giveCard(state, holder, "pick-lock");
|
||||
state = must(state, holder, {
|
||||
type: "cast", instanceId: pick.instanceId,
|
||||
target: { kind: "edge", cell, side },
|
||||
});
|
||||
const fb = giveCard(state, holder, "fireball", "FB", 1);
|
||||
const cast = applyCommand(state, holder, {
|
||||
type: "cast", instanceId: fb.instanceId, target: { kind: "player", playerId: pursuer },
|
||||
});
|
||||
expect(cast.ok).toBe(true);
|
||||
});
|
||||
|
||||
it("a lock REMOVED lets any wizard beside the door peek through", () => {
|
||||
let { state, cell, side, holder, pursuer } = sightRig();
|
||||
const rm = giveCard(state, holder, "remove-lock");
|
||||
state = must(state, holder, {
|
||||
type: "cast", instanceId: rm.instanceId,
|
||||
target: { kind: "edge", cell, side },
|
||||
});
|
||||
const fb = giveCard(state, holder, "fireball", "FB", 1);
|
||||
const cast = applyCommand(state, holder, {
|
||||
type: "cast", instanceId: fb.instanceId, target: { kind: "player", playerId: pursuer },
|
||||
});
|
||||
expect(cast.ok).toBe(true);
|
||||
});
|
||||
|
||||
it("PICK LOCK in hand is enough to ease a locked door open a crack", () => {
|
||||
let { state, cell, side, holder, pursuer } = sightRig();
|
||||
giveCard(state, holder, "pick-lock");
|
||||
const fb = giveCard(state, holder, "fireball", "FB", 1);
|
||||
const cast = applyCommand(state, holder, {
|
||||
type: "cast", instanceId: fb.instanceId, target: { kind: "player", playerId: pursuer },
|
||||
});
|
||||
expect(cast.ok).toBe(true);
|
||||
});
|
||||
|
||||
it("the wizard down the hallway sees no further than the shut door", () => {
|
||||
let { state, cell, side, holder, pursuer } = sightRig();
|
||||
// Pull the pursuer one square further down the hall, so the door is
|
||||
// no longer on their threshold; clear their path to the doorway.
|
||||
const near = neighbor(cell, side);
|
||||
const far = neighbor(near, side);
|
||||
if (!boardView(state).cells[cellKey(far)]) {
|
||||
throw new Error("setup: seed 42 lost the hallway this rig stands in");
|
||||
}
|
||||
state.players.find((p) => p.id === pursuer)!.position = far;
|
||||
state.edgeOverrides[edgeKey(near, side)] = "open";
|
||||
const rm = giveCard(state, holder, "remove-lock");
|
||||
state = must(state, holder, {
|
||||
type: "cast", instanceId: rm.instanceId,
|
||||
target: { kind: "edge", cell, side },
|
||||
});
|
||||
state = must(state, holder, { type: "endTurn", draw: 0 });
|
||||
const fb = giveCard(state, pursuer, "fireball", "FB", 1);
|
||||
const refused = applyCommand(state, pursuer, {
|
||||
type: "cast", instanceId: fb.instanceId, target: { kind: "player", playerId: holder },
|
||||
});
|
||||
expect(refused.ok).toBe(false);
|
||||
if (!refused.ok) expect(refused.error).toContain("line of sight");
|
||||
});
|
||||
});
|
||||
|
||||
describe("the displayed MASTER KEY", () => {
|
||||
function keyRig() {
|
||||
let { state } = createGame({ playerIds: ["keeper", "watcher"], seed: 42, sets: ["basic"] });
|
||||
state = toRound2(state);
|
||||
const view = boardView(state);
|
||||
for (const [key, edge] of Object.entries(view.edges)) {
|
||||
if (edge !== "door") continue;
|
||||
const [kind, coords] = key.split(":") as [string, string];
|
||||
const [x, y] = coords.split(",").map(Number) as [number, number];
|
||||
const cell = { x, y };
|
||||
const side = kind === "V" ? ("E" as Side) : ("S" as Side);
|
||||
const keeper = activePlayer(state);
|
||||
keeper.position = { ...cell };
|
||||
return { state, cell, side, key, keeper };
|
||||
}
|
||||
throw new Error("setup: seed 42 grew a maze with no doors");
|
||||
}
|
||||
|
||||
it("cast bare, the key goes on display — once", () => {
|
||||
const { state, keeper } = keyRig();
|
||||
const mk = giveCard(state, keeper.id, "master-key", "MK");
|
||||
const cast = applyCommand(state, keeper.id, { type: "cast", instanceId: mk.instanceId });
|
||||
expect(cast.ok).toBe(true);
|
||||
if (cast.ok) {
|
||||
const after = cast.state.players.find((p) => p.id === keeper.id)!;
|
||||
expect(after.displayed).toContain(mk.instanceId);
|
||||
expect(after.hand.some((c) => c.instanceId === mk.instanceId)).toBe(true);
|
||||
const again = applyCommand(cast.state, keeper.id, { type: "cast", instanceId: mk.instanceId });
|
||||
expect(again.ok).toBe(false);
|
||||
}
|
||||
});
|
||||
|
||||
it("its bearer walks through locked doors, which relock at their back", () => {
|
||||
const { state, cell, side, key, keeper } = keyRig();
|
||||
const mk = giveCard(state, keeper.id, "master-key", "MK");
|
||||
keeper.displayed.push(mk.instanceId);
|
||||
const r = applyCommand(state, keeper.id, { type: "move", direction: side });
|
||||
expect(r.ok).toBe(true);
|
||||
if (r.ok) {
|
||||
const after = r.state.players.find((p) => p.id === keeper.id)!;
|
||||
expect(cellKey(after.position)).toBe(cellKey(neighbor(cell, side)));
|
||||
// "Door relocks behind you": no lingering opening for bystanders.
|
||||
expect(r.state.openDoorEdges).not.toContain(key);
|
||||
expect(r.events.some((e) => e.type === "doorUnlocked")).toBe(true);
|
||||
// The key turns again on the way back.
|
||||
const back = applyCommand(r.state, keeper.id, { type: "move", direction: opposite(side) });
|
||||
expect(back.ok).toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
it("a JAMmed LOCK refuses even the master key", () => {
|
||||
const { state, side, key, keeper } = keyRig();
|
||||
const mk = giveCard(state, keeper.id, "master-key", "MK");
|
||||
keeper.displayed.push(mk.instanceId);
|
||||
state.doorStates[key] = "jammed";
|
||||
const r = applyCommand(state, keeper.id, { type: "move", direction: side });
|
||||
expect(r.ok).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { applyCommand, activePlayer, boardView, gameLos, sustainedOn } from "../src/game";
|
||||
import { cellKey, stepTarget } from "../src/board";
|
||||
import { applyCommand, activePlayer, boardView, createGame, gameLos, sustainedOn } from "../src/game";
|
||||
import { cellKey, edgeKey, stepTarget } from "../src/board";
|
||||
import type { CardInstance } from "../src/cards";
|
||||
import { newExpansionGame as newGame, must, giveCard, toRound2, faceOff, castAt } from "./helpers";
|
||||
|
||||
@@ -106,7 +106,7 @@ describe("expansion combat cards", () => {
|
||||
expect(state.players.find((p) => p.id === attacker)!.life).toBe(10);
|
||||
});
|
||||
|
||||
it("ward springs when a trapped treasure is grabbed", () => {
|
||||
it("ward springs in the moment: the grab hangs on the owner's choice", () => {
|
||||
let { state } = newGame();
|
||||
const me = activePlayer(state);
|
||||
const enemy = state.players.find((p) => p.id !== me.id)!;
|
||||
@@ -114,6 +114,8 @@ describe("expansion combat cards", () => {
|
||||
const treasure = state.treasures.find((t) => t.owner === enemy.id && t.position)!;
|
||||
me.position = { ...treasure.position! };
|
||||
state = must(state, me.id, { type: "pickUpTreasure" });
|
||||
expect(state.wardPending).toEqual({ ownerId: enemy.id, takerId: me.id });
|
||||
state = must(state, enemy.id, { type: "wardChoice", play: true });
|
||||
expect(state.players.find((p) => p.id === me.id)!.life).toBe(12);
|
||||
expect(state.players.find((p) => p.id === enemy.id)!.hand.some((c) => c.cardId === "ward")).toBe(false);
|
||||
});
|
||||
@@ -161,6 +163,114 @@ describe("expansion combat cards", () => {
|
||||
expect(r.error).toMatch(/blocked/);
|
||||
}
|
||||
});
|
||||
|
||||
it("idiot forbids item handling and punches but allows counteractions", () => {
|
||||
let { state } = createGame({
|
||||
playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"],
|
||||
});
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
// The victim carries an OPPONENT'S treasure into the spell.
|
||||
const d = state.players.find((p) => p.id === defender)!;
|
||||
const stolen = state.treasures.find((t) => t.owner === attacker)!;
|
||||
stolen.carriedBy = defender;
|
||||
stolen.position = null;
|
||||
d.carriedTreasureId = stolen.id;
|
||||
const id = giveCard(state, attacker, "idiot");
|
||||
state = castAt(state, attacker, defender, id);
|
||||
expect(sustainedOn(state, defender, "idiot").length).toBe(1);
|
||||
state = must(state, attacker, { type: "endTurn", draw: 0 });
|
||||
|
||||
// No dropping the carried treasure (no capturing it on your home, either).
|
||||
const drop = applyCommand(state, defender, { type: "dropTreasure" });
|
||||
expect(drop.ok).toBe(false);
|
||||
if (!drop.ok) expect(drop.error).toMatch(/treasure/);
|
||||
// No punching the tormentor.
|
||||
expect(applyCommand(state, defender, { type: "punch", targetId: attacker }).ok).toBe(false);
|
||||
// Goal-aiding spells stay castable (FAQ: "You could, however, destroy a wall").
|
||||
const sp = giveCard(state, defender, "speed", "SP", 0);
|
||||
expect(applyCommand(state, defender, { type: "cast", instanceId: sp.instanceId }).ok).toBe(true);
|
||||
// Counteractions are expressly allowed: absorb an incoming fireball.
|
||||
state = must(state, defender, { type: "endTurn", draw: 0 });
|
||||
const fb = giveCard(state, attacker, "fireball", "F", 0);
|
||||
state = must(state, attacker, {
|
||||
type: "cast", instanceId: fb.instanceId, target: { kind: "player", playerId: defender },
|
||||
});
|
||||
giveCard(state, defender, "absorb-spell", "AB", 1);
|
||||
expect(applyCommand(state, defender, { type: "counteract", instanceId: "absorb-spell#AB" }).ok).toBe(true);
|
||||
});
|
||||
|
||||
it("idiot never steers the march — the step goes where asked", () => {
|
||||
let { state } = createGame({
|
||||
playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"],
|
||||
});
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
const id = giveCard(state, attacker, "idiot");
|
||||
state = castAt(state, attacker, defender, id);
|
||||
expect(sustainedOn(state, defender, "idiot").length).toBe(1);
|
||||
state = must(state, attacker, { type: "endTurn", draw: 0 });
|
||||
const d = state.players.find((p) => p.id === defender)!;
|
||||
const board = boardView(state);
|
||||
const open = (["N", "S", "E", "W"] as const)
|
||||
.filter((s) => stepTarget(board, d.position, s).kind === "step");
|
||||
expect(open.length).toBeGreaterThanOrEqual(2);
|
||||
// Plant the victim's own gold one step out one way; walk the other way.
|
||||
|
||||
const toward = stepTarget(board, d.position, open[0]!);
|
||||
const away = stepTarget(board, d.position, open[1]!);
|
||||
if (toward.kind === "blocked" || away.kind === "blocked") throw new Error("unreachable");
|
||||
const own = state.treasures.find((t) => t.owner === defender)!;
|
||||
own.carriedBy = null;
|
||||
own.position = toward.to;
|
||||
state = must(state, defender, { type: "move", direction: open[1]! });
|
||||
expect(cellKey(state.players.find((p) => p.id === defender)!.position)).toBe(cellKey(away.to));
|
||||
});
|
||||
|
||||
it("idiot permits DROP OBJECT that frees the victim's own treasure", () => {
|
||||
let { state } = createGame({
|
||||
playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"],
|
||||
});
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
const thief = state.players.find((p) => p.id === attacker)!;
|
||||
const own = state.treasures.find((t) => t.owner === defender)!;
|
||||
own.carriedBy = attacker;
|
||||
own.position = null;
|
||||
thief.carriedTreasureId = own.id;
|
||||
const id = giveCard(state, attacker, "idiot");
|
||||
state = castAt(state, attacker, defender, id);
|
||||
state = must(state, attacker, { type: "endTurn", draw: 0 });
|
||||
// An attack for its own sake stays forbidden.
|
||||
const fb = giveCard(state, defender, "fireball", "F", 0);
|
||||
expect(applyCommand(state, defender, {
|
||||
type: "cast", instanceId: fb.instanceId, target: { kind: "player", playerId: attacker },
|
||||
}).ok).toBe(false);
|
||||
// Shaking YOUR OWN gold out of the thief's arms serves the march —
|
||||
// while carried it cannot be stood upon.
|
||||
const dr = giveCard(state, defender, "drop-object", "D", 1);
|
||||
const r = applyCommand(state, defender, {
|
||||
type: "cast", instanceId: dr.instanceId,
|
||||
target: { kind: "player", playerId: attacker }, params: { cardId: "treasure" },
|
||||
});
|
||||
expect(r.ok).toBe(true);
|
||||
});
|
||||
|
||||
it("idiot has no effect on a victim carrying their own treasure", () => {
|
||||
let { state } = createGame({
|
||||
playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"],
|
||||
});
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
const d = state.players.find((p) => p.id === defender)!;
|
||||
const own = state.treasures.find((t) => t.owner === defender)!;
|
||||
own.carriedBy = defender;
|
||||
own.position = null;
|
||||
d.carriedTreasureId = own.id;
|
||||
const id = giveCard(state, attacker, "idiot");
|
||||
state = castAt(state, attacker, defender, id);
|
||||
expect(sustainedOn(state, defender, "idiot").length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("swap home bases", () => {
|
||||
@@ -283,3 +393,284 @@ describe("ambushes (async interrupts)", () => {
|
||||
expect(state.ambushes.length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("strength tears treasures from wizards' arms", () => {
|
||||
function grip(seed: number) {
|
||||
let { state } = createGame({ playerIds: ["alice", "bob"], seed, sets: ["basic", "expansion1"] });
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
const d = state.players.find((p) => p.id === defender)!;
|
||||
// The defender carries the ATTACKER's own treasure (no ward window).
|
||||
const stolen = state.treasures.find((t) => t.owner === attacker)!;
|
||||
stolen.carriedBy = defender;
|
||||
stolen.position = null;
|
||||
d.carriedTreasureId = stolen.id;
|
||||
const st = giveCard(state, attacker, "strength");
|
||||
giveCard(state, attacker, "number-2", "N", 1);
|
||||
state = must(state, attacker, {
|
||||
type: "cast", instanceId: st.instanceId, numberInstanceIds: ["number-2#N"],
|
||||
});
|
||||
return { state, attacker, defender, treasure: stolen.id };
|
||||
}
|
||||
|
||||
it("the grip is an attack: the victim keeps the treasure only on a 1", () => {
|
||||
let torn = 0, kept = 0;
|
||||
for (let seed = 1; seed <= 12; seed++) {
|
||||
const { state, attacker, defender, treasure } = grip(seed);
|
||||
const r = applyCommand(state, attacker, { type: "tearTreasure", targetId: defender });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
expect(r.state.turn.attackUsed).toBe(true);
|
||||
// FAQ: tearing is not picking up — the turn's actions continue.
|
||||
expect(r.state.turn.actionsEnded).toBe(false);
|
||||
const a = r.state.players.find((p) => p.id === attacker)!;
|
||||
const d = r.state.players.find((p) => p.id === defender)!;
|
||||
if (a.carriedTreasureId === treasure) {
|
||||
torn++;
|
||||
expect(d.carriedTreasureId).toBeNull();
|
||||
} else {
|
||||
kept++;
|
||||
expect(d.carriedTreasureId).toBe(treasure);
|
||||
}
|
||||
// One attack per turn: a second wrench is refused.
|
||||
expect(applyCommand(r.state, attacker, { type: "tearTreasure", targetId: defender }).ok).toBe(false);
|
||||
}
|
||||
expect(torn).toBeGreaterThan(0);
|
||||
expect(kept).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("without STRENGTH the grip is refused", () => {
|
||||
let { state } = createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
const d = state.players.find((p) => p.id === defender)!;
|
||||
const t = state.treasures.find((t) => t.owner === attacker)!;
|
||||
t.carriedBy = defender;
|
||||
t.position = null;
|
||||
d.carriedTreasureId = t.id;
|
||||
const r = applyCommand(state, attacker, { type: "tearTreasure", targetId: defender });
|
||||
expect(r.ok).toBe(false);
|
||||
});
|
||||
|
||||
it("laden arms tear it loose onto the floor — and the ward's owner gets their window", () => {
|
||||
for (let seed = 1; seed <= 12; seed++) {
|
||||
let { state } = createGame({ playerIds: ["alice", "bob", "cara"], seed, sets: ["basic", "expansion1"] });
|
||||
state = toRound2(state);
|
||||
while (activePlayer(state).id !== "alice") {
|
||||
state = must(state, activePlayer(state).id, { type: "endTurn", draw: 0 });
|
||||
}
|
||||
const alice = state.players.find((p) => p.id === "alice")!;
|
||||
const bob = state.players.find((p) => p.id === "bob")!;
|
||||
bob.position = { ...alice.position };
|
||||
// Alice already hauls her own gold; Bob carries CARA's — and Cara
|
||||
// holds a WARD over it.
|
||||
const mine = state.treasures.find((t) => t.owner === "alice")!;
|
||||
mine.carriedBy = "alice";
|
||||
mine.position = null;
|
||||
alice.carriedTreasureId = mine.id;
|
||||
const caras = state.treasures.find((t) => t.owner === "cara")!;
|
||||
caras.carriedBy = "bob";
|
||||
caras.position = null;
|
||||
bob.carriedTreasureId = caras.id;
|
||||
giveCard(state, "cara", "ward", "W", 0);
|
||||
const st = giveCard(state, "alice", "strength");
|
||||
giveCard(state, "alice", "number-2", "N", 1);
|
||||
state = must(state, "alice", {
|
||||
type: "cast", instanceId: st.instanceId, numberInstanceIds: ["number-2#N"],
|
||||
});
|
||||
const r = applyCommand(state, "alice", { type: "tearTreasure", targetId: "bob" });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
const after = r.state.treasures.find((t) => t.id === caras.id)!;
|
||||
if (after.carriedBy === "bob") continue; // Bob rolled his 1 — try again
|
||||
// Torn loose: Alice's arms are full, so it lands at her feet…
|
||||
expect(after.position).toEqual(alice.position);
|
||||
expect(r.state.players.find((p) => p.id === "alice")!.carriedTreasureId).toBe(mine.id);
|
||||
// …and the seizure hangs on Cara's ward.
|
||||
expect(r.state.wardPending).toEqual({ ownerId: "cara", takerId: "alice" });
|
||||
return;
|
||||
}
|
||||
throw new Error("every seed rolled a 1 — the rig is wrong");
|
||||
});
|
||||
});
|
||||
|
||||
describe("swap meet trades carried items", () => {
|
||||
function rig() {
|
||||
let { state } = createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
const sm = giveCard(state, attacker, "swap-meet");
|
||||
giveCard(state, attacker, "dagger", "D", 1);
|
||||
giveCard(state, defender, "blaster-wand", "W", 0);
|
||||
state = must(state, attacker, {
|
||||
type: "cast", instanceId: sm.instanceId,
|
||||
target: { kind: "player", playerId: defender },
|
||||
params: { cardId: "dagger;blaster-wand" },
|
||||
});
|
||||
state = must(state, defender, { type: "pass" });
|
||||
return { state, attacker, defender };
|
||||
}
|
||||
|
||||
it("a dagger trades for a wand — both are carried items", () => {
|
||||
const { state, attacker, defender } = rig();
|
||||
expect(state.players.find((p) => p.id === attacker)!.hand.some((c) => c.cardId === "blaster-wand")).toBe(true);
|
||||
expect(state.players.find((p) => p.id === defender)!.hand.some((c) => c.cardId === "dagger")).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("swap meet trades treasures too", () => {
|
||||
function treasureRig(theirsToken: string, mineToken: string) {
|
||||
let { state } = createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
const a = state.players.find((p) => p.id === attacker)!;
|
||||
const d = state.players.find((p) => p.id === defender)!;
|
||||
// The defender hauls one of the attacker's own treasures.
|
||||
const stolen = state.treasures.find((t) => t.owner === attacker)!;
|
||||
stolen.position = null; stolen.carriedBy = defender; d.carriedTreasureId = stolen.id;
|
||||
const sm = giveCard(state, attacker, "swap-meet");
|
||||
giveCard(state, attacker, "dagger", "D", 1);
|
||||
state = must(state, attacker, {
|
||||
type: "cast", instanceId: sm.instanceId,
|
||||
target: { kind: "player", playerId: defender },
|
||||
params: { cardId: `${mineToken};${theirsToken}` },
|
||||
});
|
||||
state = must(state, defender, { type: "pass" });
|
||||
return { state, attacker, defender, a, d, stolen };
|
||||
}
|
||||
|
||||
it("a dagger buys back the treasure in the thief's arms", () => {
|
||||
const { state, attacker, defender } = treasureRig("treasure", "dagger");
|
||||
const a = state.players.find((p) => p.id === attacker)!;
|
||||
const d = state.players.find((p) => p.id === defender)!;
|
||||
const t = state.treasures.find((tr) => tr.owner === attacker && tr.carriedBy)!;
|
||||
expect(a.carriedTreasureId).toBe(t.id);
|
||||
expect(t.carriedBy).toBe(attacker);
|
||||
expect(d.carriedTreasureId).toBeNull();
|
||||
expect(d.hand.some((c) => c.cardId === "dagger")).toBe(true);
|
||||
});
|
||||
|
||||
it("the trade refuses to overload full arms", () => {
|
||||
// The attacker also carries a treasure: claiming theirs with a dagger
|
||||
// would mean two in hand — the swap quietly cannot happen.
|
||||
let { state } = createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
const a = state.players.find((p) => p.id === attacker)!;
|
||||
const d = state.players.find((p) => p.id === defender)!;
|
||||
const t1 = state.treasures.find((t) => t.owner === attacker)!;
|
||||
t1.position = null; t1.carriedBy = attacker; a.carriedTreasureId = t1.id;
|
||||
const t2 = state.treasures.find((t) => t.owner === defender)!;
|
||||
t2.position = null; t2.carriedBy = defender; d.carriedTreasureId = t2.id;
|
||||
const sm = giveCard(state, attacker, "swap-meet");
|
||||
giveCard(state, attacker, "dagger", "D", 1);
|
||||
state = must(state, attacker, {
|
||||
type: "cast", instanceId: sm.instanceId,
|
||||
target: { kind: "player", playerId: defender },
|
||||
params: { cardId: "dagger;treasure" },
|
||||
});
|
||||
state = must(state, defender, { type: "pass" });
|
||||
expect(state.players.find((p) => p.id === attacker)!.carriedTreasureId).toBe(t1.id);
|
||||
expect(state.players.find((p) => p.id === defender)!.carriedTreasureId).toBe(t2.id);
|
||||
});
|
||||
|
||||
it("treasure for treasure trades both armfuls", () => {
|
||||
let { state } = createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
const a = state.players.find((p) => p.id === attacker)!;
|
||||
const d = state.players.find((p) => p.id === defender)!;
|
||||
const t1 = state.treasures.find((t) => t.owner === attacker)!;
|
||||
t1.position = null; t1.carriedBy = attacker; a.carriedTreasureId = t1.id;
|
||||
const t2 = state.treasures.find((t) => t.owner === defender)!;
|
||||
t2.position = null; t2.carriedBy = defender; d.carriedTreasureId = t2.id;
|
||||
const sm = giveCard(state, attacker, "swap-meet");
|
||||
state = must(state, attacker, {
|
||||
type: "cast", instanceId: sm.instanceId,
|
||||
target: { kind: "player", playerId: defender },
|
||||
params: { cardId: "treasure;treasure" },
|
||||
});
|
||||
state = must(state, defender, { type: "pass" });
|
||||
expect(state.players.find((p) => p.id === attacker)!.carriedTreasureId).toBe(t2.id);
|
||||
expect(state.players.find((p) => p.id === defender)!.carriedTreasureId).toBe(t1.id);
|
||||
expect(state.treasures.find((t) => t.id === t1.id)!.carriedBy).toBe(defender);
|
||||
expect(state.treasures.find((t) => t.id === t2.id)!.carriedBy).toBe(attacker);
|
||||
});
|
||||
});
|
||||
|
||||
describe("full reflection hands the swap meet choice to the reflector", () => {
|
||||
function reflectedSwapRig(reflectorChoice?: string) {
|
||||
let { state } = createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
const a = state.players.find((p) => p.id === attacker)!;
|
||||
// The caster carries a treasure and offers a dagger; the reflector may
|
||||
// instead demand the trade of their own choosing.
|
||||
const t = state.treasures.find((t) => t.owner === attacker)!;
|
||||
t.position = null; t.carriedBy = attacker; a.carriedTreasureId = t.id;
|
||||
const sm = giveCard(state, attacker, "swap-meet");
|
||||
giveCard(state, attacker, "dagger", "D", 1);
|
||||
giveCard(state, defender, "full-reflection", "FR", 0);
|
||||
giveCard(state, defender, "large-rock", "R", 1);
|
||||
state = must(state, attacker, {
|
||||
type: "cast", instanceId: sm.instanceId,
|
||||
target: { kind: "player", playerId: defender },
|
||||
params: { cardId: "dagger;large-rock" },
|
||||
});
|
||||
state = must(state, defender, {
|
||||
type: "counteract", instanceId: "full-reflection#FR",
|
||||
...(reflectorChoice ? { params: { cardId: reflectorChoice } } : {}),
|
||||
});
|
||||
state = must(state, attacker, { type: "pass" });
|
||||
return { state, attacker, defender, treasureId: t.id };
|
||||
}
|
||||
|
||||
it("the reflector rewrites the trade: their rock for the caster's treasure", () => {
|
||||
const { state, attacker, defender, treasureId } = reflectedSwapRig("large-rock;treasure");
|
||||
const d = state.players.find((p) => p.id === defender)!;
|
||||
expect(d.carriedTreasureId).toBe(treasureId);
|
||||
expect(state.players.find((p) => p.id === attacker)!.hand.some((c) => c.cardId === "large-rock")).toBe(true);
|
||||
expect(state.players.find((p) => p.id === attacker)!.carriedTreasureId).toBeNull();
|
||||
});
|
||||
|
||||
it("the reflector may decline: 'none' trades nothing", () => {
|
||||
const { state, attacker, defender, treasureId } = reflectedSwapRig("none");
|
||||
expect(state.players.find((p) => p.id === attacker)!.carriedTreasureId).toBe(treasureId);
|
||||
expect(state.players.find((p) => p.id === defender)!.hand.some((c) => c.cardId === "large-rock")).toBe(true);
|
||||
});
|
||||
|
||||
it("a bare full reflection with no choice trades nothing", () => {
|
||||
const { state, attacker } = reflectedSwapRig(undefined);
|
||||
expect(state.players.find((p) => p.id === attacker)!.hand.some((c) => c.cardId === "dagger")).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("go away routs around walls", () => {
|
||||
it("a victim against a wall bends the line instead of standing still", () => {
|
||||
let { state } = createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
const a = state.players.find((p) => p.id === attacker)!;
|
||||
const d = state.players.find((p) => p.id === defender)!;
|
||||
// Attacker west of the victim, a wall hard against the victim's east:
|
||||
// the straight line away is blocked from the first step.
|
||||
a.position = { x: 1, y: 5 };
|
||||
d.position = { x: 2, y: 5 };
|
||||
state.edgeOverrides[edgeKey({ x: 1, y: 5 }, "E")] = "open";
|
||||
state.edgeOverrides[edgeKey({ x: 2, y: 5 }, "E")] = "wall";
|
||||
state.edgeOverrides[edgeKey({ x: 2, y: 5 }, "N")] = "open";
|
||||
state.edgeOverrides[edgeKey({ x: 2, y: 5 }, "S")] = "open";
|
||||
state.edgeOverrides[edgeKey({ x: 2, y: 4 }, "N")] = "open";
|
||||
state.edgeOverrides[edgeKey({ x: 2, y: 6 }, "S")] = "open";
|
||||
const ga = giveCard(state, attacker, "go-away");
|
||||
giveCard(state, attacker, "number-3", "N3", 1);
|
||||
state = must(state, attacker, {
|
||||
type: "cast", instanceId: ga.instanceId, numberInstanceIds: ["number-3#N3"],
|
||||
target: { kind: "player", playerId: defender },
|
||||
});
|
||||
state = must(state, defender, { type: "pass" });
|
||||
const after = state.players.find((p) => p.id === defender)!;
|
||||
const dist = Math.abs(after.position.x - 1) + Math.abs(after.position.y - 5);
|
||||
// Three routed spaces: strictly farther than where they stood.
|
||||
expect(dist).toBeGreaterThanOrEqual(3);
|
||||
expect(after.lostTurns).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { applyCommand, activePlayer, boardView, gameLos } from "../src/game";
|
||||
import { cellKey, SIDES, stepTarget, type Cell } from "../src/board";
|
||||
import { applyCommand, activePlayer, boardView, createGame, gameLos } from "../src/game";
|
||||
import { cellKey, edgeKey, SIDES, stepTarget, type Cell, type Side } from "../src/board";
|
||||
import type { CardInstance } from "../src/cards";
|
||||
import { newExpansionGame as newGame, must, giveCard, emptyNeighborCell } from "./helpers";
|
||||
import { eligibleCellsFor, sightedCellsFor, viewFor } from "../src/view";
|
||||
import { newExpansionGame as newGame, must, giveCard, emptyNeighborCell, plainRimWall } from "./helpers";
|
||||
|
||||
describe("expansion terrain", () => {
|
||||
it("killer ooze burns on entry and can drop you on your face", () => {
|
||||
@@ -160,4 +161,220 @@ describe("expansion terrain", () => {
|
||||
expect(state.squareContents[cellKey(spot.cell)]).toBeUndefined();
|
||||
// Wave side effects vary by geometry; the melt itself is the pinned behavior.
|
||||
});
|
||||
|
||||
it("wall of fire takes a rim warp — both mouths burn the crossing", () => {
|
||||
let { state } = createGame({
|
||||
playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"],
|
||||
});
|
||||
const me = activePlayer(state);
|
||||
const warp = state.board.warps[0]!;
|
||||
me.position = { ...warp.from.cell };
|
||||
const wof = giveCard(state, me.id, "wall-of-fire", "WF", 0);
|
||||
const r = applyCommand(state, me.id, {
|
||||
type: "cast", instanceId: wof.instanceId,
|
||||
target: { kind: "edge", cell: warp.from.cell, side: warp.from.side },
|
||||
});
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
const nearKey = edgeKey(warp.from.cell, warp.from.side);
|
||||
const farKey = edgeKey(warp.to.cell, warp.to.side);
|
||||
expect(boardView(state).edges[nearKey]).toBe("firewall");
|
||||
expect(boardView(state).edges[farKey]).toBe("firewall");
|
||||
// The corridor still runs — through flame: the crossing lands on the
|
||||
// far rim and burns for 4.
|
||||
state = must(state, me.id, { type: "move", direction: warp.from.side });
|
||||
const after = state.players.find((p) => p.id === me.id)!;
|
||||
expect(cellKey(after.position)).toBe(cellKey(warp.to.cell));
|
||||
expect(after.life).toBe(11);
|
||||
});
|
||||
|
||||
it("waterwall takes a rim warp — the collapse washes both rims", () => {
|
||||
let { state } = createGame({
|
||||
playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"],
|
||||
});
|
||||
const me = activePlayer(state);
|
||||
const other = state.players.find((p) => p.id !== me.id)!;
|
||||
const warp = state.board.warps[0]!;
|
||||
me.position = { ...warp.from.cell };
|
||||
other.position = { ...warp.to.cell };
|
||||
const ww = giveCard(state, me.id, "waterwall", "WW", 0);
|
||||
const r = applyCommand(state, me.id, {
|
||||
type: "cast", instanceId: ww.instanceId,
|
||||
target: { kind: "edge", cell: warp.from.cell, side: warp.from.side },
|
||||
});
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
// Both wizards stood in the mouths; the collapse washed both inward.
|
||||
const meAfter = r.state.players.find((p) => p.id === me.id)!;
|
||||
const otherAfter = r.state.players.find((p) => p.id === other.id)!;
|
||||
expect(cellKey(meAfter.position)).not.toBe(cellKey(warp.from.cell));
|
||||
expect(cellKey(otherAfter.position)).not.toBe(cellKey(warp.to.cell));
|
||||
});
|
||||
|
||||
it("illusion wall hangs on a rim warp mouth", () => {
|
||||
const { state } = createGame({
|
||||
playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"],
|
||||
});
|
||||
const me = activePlayer(state);
|
||||
const warp = state.board.warps[0]!;
|
||||
me.position = { ...warp.from.cell };
|
||||
const il = giveCard(state, me.id, "illusion-wall", "IL", 0);
|
||||
const r = applyCommand(state, me.id, {
|
||||
type: "cast", instanceId: il.instanceId,
|
||||
target: { kind: "edge", cell: warp.from.cell, side: warp.from.side },
|
||||
});
|
||||
expect(r.ok).toBe(true);
|
||||
if (r.ok) {
|
||||
expect(r.state.illusionWalls[edgeKey(warp.from.cell, warp.from.side)]).toBeDefined();
|
||||
}
|
||||
});
|
||||
|
||||
it("stone to water breaches the outer rim, opening a warp", () => {
|
||||
let { state } = createGame({
|
||||
playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"],
|
||||
});
|
||||
const me = activePlayer(state);
|
||||
const rim = plainRimWall(state);
|
||||
me.position = { ...rim.cell };
|
||||
const warpsBefore = state.board.warps.length;
|
||||
const stw = giveCard(state, me.id, "stone-to-water", "SW", 0);
|
||||
state = must(state, me.id, {
|
||||
type: "cast", instanceId: stw.instanceId,
|
||||
target: { kind: "edge", cell: rim.cell, side: rim.side },
|
||||
});
|
||||
// The far rim melted with it and the wraparound now runs.
|
||||
expect(state.board.warps.length).toBe(warpsBefore + 2);
|
||||
});
|
||||
|
||||
it("no doors through the rim", () => {
|
||||
const { state } = createGame({
|
||||
playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"],
|
||||
});
|
||||
const me = activePlayer(state);
|
||||
const rim = plainRimWall(state);
|
||||
me.position = { ...rim.cell };
|
||||
const cd = giveCard(state, me.id, "create-door", "CD", 0);
|
||||
const r = applyCommand(state, me.id, {
|
||||
type: "cast", instanceId: cd.instanceId,
|
||||
target: { kind: "edge", cell: rim.cell, side: rim.side },
|
||||
});
|
||||
expect(r.ok).toBe(false);
|
||||
});
|
||||
|
||||
it("stone to water melts a door — a small entryway in a stone wall", () => {
|
||||
const { state } = createGame({
|
||||
playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"],
|
||||
});
|
||||
const me = activePlayer(state);
|
||||
const board = boardView(state);
|
||||
// Stand the caster at some door and melt it point-blank.
|
||||
let doorAt: { cell: Cell; side: Side } | null = null;
|
||||
outer: for (const k of Object.keys(board.cells)) {
|
||||
const [x, y] = k.split(",").map(Number) as [number, number];
|
||||
for (const side of SIDES) {
|
||||
if (board.edges[edgeKey({ x, y }, side)] === "door") {
|
||||
doorAt = { cell: { x, y }, side };
|
||||
break outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!doorAt) throw new Error("setup: no door on this board");
|
||||
me.position = { ...doorAt.cell };
|
||||
const stw = giveCard(state, me.id, "stone-to-water", "SW", 0);
|
||||
const r = applyCommand(state, me.id, {
|
||||
type: "cast", instanceId: stw.instanceId,
|
||||
target: { kind: "edge", cell: doorAt.cell, side: doorAt.side },
|
||||
});
|
||||
expect(r.ok).toBe(true);
|
||||
if (r.ok) {
|
||||
const key = edgeKey(doorAt.cell, doorAt.side);
|
||||
expect(boardView(r.state).edges[key] ?? "open").toBe("open");
|
||||
expect(r.state.doorStates[key]).toBeUndefined();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("eligibility dimming mirrors the engine", () => {
|
||||
it("boobytrap tokens go anywhere but solid stone, sight be damned", () => {
|
||||
let { state } = newGame();
|
||||
const caster = activePlayer(state).id;
|
||||
const view = viewFor(state, caster);
|
||||
const lit = eligibleCellsFor(view, "boobytrap")!;
|
||||
// Every board square is fair game (the fresh maze holds no solid stone),
|
||||
// including squares far outside the caster's sight.
|
||||
expect(lit.size).toBe(Object.keys(view.board.cells).length);
|
||||
});
|
||||
|
||||
it("glue lights only sighted squares that hold something", () => {
|
||||
let { state } = newGame();
|
||||
const caster = activePlayer(state);
|
||||
// Drop a dagger at the caster's feet — the one guaranteed-sighted object.
|
||||
const here = { ...caster.position };
|
||||
state.groundObjects[cellKey(here)] = [{ instanceId: "dagger#G", cardId: "dagger" }];
|
||||
const lit = eligibleCellsFor(viewFor(state, caster.id), "glue")!;
|
||||
expect(lit.has(cellKey(here))).toBe(true);
|
||||
// Empty squares stay dim — glue needs something to glue down.
|
||||
const view = viewFor(state, caster.id);
|
||||
for (const k of lit) {
|
||||
const held =
|
||||
(view.groundObjects[k] ?? []).length > 0 ||
|
||||
view.treasures.some((t) => t.position && cellKey(t.position) === k);
|
||||
expect(held).toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
it("dispel dimming lights creatures and demands sight, whoever made them", () => {
|
||||
let { state } = newGame();
|
||||
const caster = activePlayer(state);
|
||||
const other = state.players.find((p) => p.id !== caster.id)!;
|
||||
// An enemy wraith beside the caster: created by the OTHER wizard.
|
||||
state.creatures.push({
|
||||
id: "w1", kind: "wraith", controllerId: other.id,
|
||||
position: { x: caster.position.x, y: caster.position.y },
|
||||
damage: 0, maxDamage: Infinity, movesPerTurn: 3, movementUsed: 0,
|
||||
attackUsed: false, justCreated: false,
|
||||
wallPassesPerTurn: 1, wallPassUsed: 0, scorchedThisTurn: [],
|
||||
});
|
||||
const lit = eligibleCellsFor(viewFor(state, caster.id), "dispel-creation")!;
|
||||
expect(lit.has(cellKey(caster.position))).toBe(true);
|
||||
// Everything lit is created AND sighted.
|
||||
const view = viewFor(state, caster.id);
|
||||
const seen = sightedCellsFor(view);
|
||||
for (const k of lit) expect(seen.has(k)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("a wave's force is spent as it travels", () => {
|
||||
/** Caster at B, one cell above A; the target wall is A's south edge, so
|
||||
* the range-2 wave covers A (dist 0) and B (dist 1). */
|
||||
function rig(behind: "open" | "wall") {
|
||||
const { state } = createGame({ playerIds: ["a", "b"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
const me = activePlayer(state);
|
||||
const A = { x: 4, y: 5 }, B = { x: 4, y: 4 }, Bn = { x: 4, y: 3 }, Bnn = { x: 4, y: 2 };
|
||||
for (const c of [A, B, Bn, Bnn]) expect(boardView(state).cells[cellKey(c)]).toBeTruthy();
|
||||
state.edgeOverrides[edgeKey(A, "S")] = "wall";
|
||||
state.edgeOverrides[edgeKey(A, "N")] = "open";
|
||||
state.edgeOverrides[edgeKey(B, "N")] = behind;
|
||||
state.edgeOverrides[edgeKey(Bn, "N")] = "open";
|
||||
me.position = { ...B };
|
||||
// The other wizard waits far outside the wave.
|
||||
state.players.find((p) => p.id !== me.id)!.position = { x: 0, y: 9 };
|
||||
const stw = giveCard(state, me.id, "stone-to-water", "SW", 0);
|
||||
const after = must(state, me.id, {
|
||||
type: "cast", instanceId: stw.instanceId, target: { kind: "edge", cell: A, side: "S" },
|
||||
});
|
||||
return { me: after.players.find((p) => p.id === me.id)!, B, Bn, Bnn };
|
||||
}
|
||||
|
||||
it("a victim at the wave's far edge is carried one space, unhurt", () => {
|
||||
const { me, Bn } = rig("open");
|
||||
expect(cellKey(me.position)).toBe(cellKey(Bn));
|
||||
expect(me.life).toBe(15);
|
||||
});
|
||||
|
||||
it("only unspent force crushes: one space of push blocked is one damage", () => {
|
||||
const { me, B } = rig("wall");
|
||||
expect(cellKey(me.position)).toBe(cellKey(B));
|
||||
expect(me.life).toBe(14);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { giveCard } from "./helpers";
|
||||
import { edgeKey } from "../src/board";
|
||||
import {
|
||||
applyCommand,
|
||||
activePlayer,
|
||||
@@ -224,3 +226,138 @@ describe("treasures and victory", () => {
|
||||
expect(result.ok).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("elimination by lost treasures drops what the fallen carried", () => {
|
||||
it("the carried treasure lands where the wizard stood", () => {
|
||||
let { state } = createGame({ playerIds: ["a", "b", "c"], seed: 42, sets: ["basic"] });
|
||||
const A = state.players.find((p) => p.id === "a")!;
|
||||
const B = state.players.find((p) => p.id === "b")!;
|
||||
const C = state.players.find((p) => p.id === "c")!;
|
||||
// C's first treasure already sits captured on B's home...
|
||||
const c1 = state.treasures.filter((t) => t.owner === "c")[0]!;
|
||||
c1.position = { ...B.home };
|
||||
// ...C carries one of B's treasures...
|
||||
const bt = state.treasures.filter((t) => t.owner === "b")[0]!;
|
||||
bt.position = null;
|
||||
bt.carriedBy = "c";
|
||||
C.carriedTreasureId = bt.id;
|
||||
// ...and A, standing on their own home, drops C's second treasure there.
|
||||
const c2 = state.treasures.filter((t) => t.owner === "c")[1]!;
|
||||
c2.position = null;
|
||||
c2.carriedBy = "a";
|
||||
A.carriedTreasureId = c2.id;
|
||||
A.position = { ...A.home };
|
||||
while (state.players[state.turn.activeIndex]!.id !== "a") {
|
||||
const r = applyCommand(state, state.players[state.turn.activeIndex]!.id, { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
const r = applyCommand(state, "a", { type: "dropTreasure" });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
// C is eliminated by lost treasures — and B's treasure lies where C stood.
|
||||
const cAfter = state.players.find((p) => p.id === "c")!;
|
||||
expect(cAfter.alive).toBe(false);
|
||||
expect(cAfter.carriedTreasureId).toBeNull();
|
||||
const btAfter = state.treasures.find((t) => t.id === bt.id)!;
|
||||
expect(btAfter.carriedBy).toBeNull();
|
||||
expect(btAfter.position).toEqual(cAfter.position);
|
||||
});
|
||||
});
|
||||
|
||||
describe("the Ward is played in the moment", () => {
|
||||
function grabRig() {
|
||||
let { state } = createGame({ playerIds: ["thief", "owner"], seed: 42, sets: ["basic"] });
|
||||
const thief = state.players.find((p) => p.id === "thief")!;
|
||||
const owner = state.players.find((p) => p.id === "owner")!;
|
||||
giveCard(state, "owner", "ward", "W", 0);
|
||||
const t = state.treasures.find((t) => t.owner === "owner" && t.position)!;
|
||||
thief.position = { ...t.position! };
|
||||
while (state.players[state.turn.activeIndex]!.id !== "thief") {
|
||||
const r = applyCommand(state, state.players[state.turn.activeIndex]!.id, { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
const r = applyCommand(state, "thief", { type: "pickUpTreasure" });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
return { state: r.state, owner, thief };
|
||||
}
|
||||
|
||||
it("the grab hangs on the owner; springing costs the thief 3 and the card", () => {
|
||||
let { state } = grabRig();
|
||||
expect(state.wardPending).toEqual({ ownerId: "owner", takerId: "thief" });
|
||||
// Nobody else may act while it hangs.
|
||||
expect(applyCommand(state, "thief", { type: "endTurn", draw: 0 }).ok).toBe(false);
|
||||
const r = applyCommand(state, "owner", { type: "wardChoice", play: true });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
expect(state.wardPending).toBeNull();
|
||||
expect(state.players.find((p) => p.id === "thief")!.life).toBe(12);
|
||||
expect(state.players.find((p) => p.id === "owner")!.hand.some((c) => c.cardId === "ward")).toBe(false);
|
||||
});
|
||||
|
||||
it("declining lets the thief go, Ward still in hand", () => {
|
||||
let { state } = grabRig();
|
||||
const r = applyCommand(state, "owner", { type: "wardChoice", play: false });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
expect(state.players.find((p) => p.id === "thief")!.life).toBe(15);
|
||||
expect(state.players.find((p) => p.id === "owner")!.hand.some((c) => c.cardId === "ward")).toBe(true);
|
||||
expect(applyCommand(state, "thief", { type: "endTurn", draw: 0 }).ok).toBe(true);
|
||||
});
|
||||
|
||||
it("arming ahead is refused — the ward waits for the grab", () => {
|
||||
let { state } = createGame({ playerIds: ["a", "b"], seed: 42, sets: ["basic"] });
|
||||
giveCard(state, state.players[state.turn.activeIndex]!.id, "ward", "W", 0);
|
||||
const r = applyCommand(state, state.players[state.turn.activeIndex]!.id, { type: "armWard" });
|
||||
expect(r.ok).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("an ambushed teleport carries its destination", () => {
|
||||
it("the trap springs and the victim lands where the trapper said", () => {
|
||||
let { state } = createGame({ playerIds: ["trapper", "prey"], seed: 42, sets: ["basic", "expansion1"] });
|
||||
for (let guard = 0; guard < 10 && !(state.players[state.turn.activeIndex]!.id === "trapper" && state.turn.round > 1); guard++) {
|
||||
const r = applyCommand(state, state.players[state.turn.activeIndex]!.id, { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
}
|
||||
const trapper = state.players.find((p) => p.id === "trapper")!;
|
||||
const prey = state.players.find((p) => p.id === "prey")!;
|
||||
giveCard(state, "trapper", "interrupt", "I", 0);
|
||||
giveCard(state, "trapper", "teleport-opponent", "TO", 1);
|
||||
// Arming without a destination is refused; with one it is stored.
|
||||
const bad = applyCommand(state, "trapper", {
|
||||
type: "setAmbush", instanceId: "interrupt#I", trigger: { kind: "near" },
|
||||
spellInstanceId: "teleport-opponent#TO",
|
||||
});
|
||||
expect(bad.ok).toBe(false);
|
||||
const dest = { x: trapper.home.x, y: trapper.home.y === 0 ? 1 : trapper.home.y - 1 };
|
||||
let r = applyCommand(state, "trapper", {
|
||||
type: "setAmbush", instanceId: "interrupt#I", trigger: { kind: "near" },
|
||||
spellInstanceId: "teleport-opponent#TO", cell: dest,
|
||||
});
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
r = applyCommand(state, "trapper", { type: "endTurn", draw: 0 });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
// The prey walks adjacent; the trap springs; the prey passes; they land
|
||||
// at dest. (Re-find both: applyCommand clones made the handles stale.)
|
||||
const trapperNow = state.players.find((p) => p.id === "trapper")!;
|
||||
const preyNow = state.players.find((p) => p.id === "prey")!;
|
||||
const below = trapperNow.position.y >= 2;
|
||||
preyNow.position = { x: trapperNow.position.x, y: trapperNow.position.y + (below ? -2 : 2) };
|
||||
const dir = below ? "S" : "N";
|
||||
state.edgeOverrides[edgeKey(preyNow.position, dir)] = "open";
|
||||
r = applyCommand(state, "prey", { type: "move", direction: dir });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
expect(state.stack?.attackCard?.cardId).toBe("teleport-opponent");
|
||||
expect(state.stack?.params?.cell).toEqual(dest);
|
||||
r = applyCommand(state, "prey", { type: "pass" });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
expect(state.players.find((p) => p.id === "prey")!.position).toEqual(dest);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -11,8 +11,9 @@ import {
|
||||
type GameState,
|
||||
type PlayerId,
|
||||
} from "../src/game";
|
||||
import { cellKey, SIDES, stepTarget, type Cell, type Side } from "../src/board";
|
||||
import { cellKey, edgeKey, neighbor, SIDES, stepTarget, type Cell, type Side } from "../src/board";
|
||||
import type { CardInstance } from "../src/cards";
|
||||
import type { SustainedEffect } from "../src/game";
|
||||
|
||||
export function newGame(seed = 42, players: PlayerId[] = ["alice", "bob"]) {
|
||||
return createGame({ playerIds: players, seed, sets: ["basic"] });
|
||||
@@ -76,3 +77,26 @@ export function emptyNeighborCell(state: GameState, of: Cell): { cell: Cell; sid
|
||||
}
|
||||
throw new Error("no empty neighbor");
|
||||
}
|
||||
|
||||
/** Some off-board edge that is a bare stone wall — no warp behind it. */
|
||||
export function plainRimWall(state: GameState): { cell: Cell; side: Side } {
|
||||
const board = boardView(state);
|
||||
for (const k of Object.keys(board.cells)) {
|
||||
const [x, y] = k.split(",").map(Number) as [number, number];
|
||||
for (const side of SIDES) {
|
||||
if (board.cells[cellKey(neighbor({ x, y }, side))]) continue;
|
||||
if (board.edges[edgeKey({ x, y }, side)] !== "wall") continue;
|
||||
if (board.warps.some((w) => cellKey(w.from.cell) === k && w.from.side === side)) continue;
|
||||
return { cell: { x, y }, side };
|
||||
}
|
||||
}
|
||||
throw new Error("setup: no plain rim wall on this board");
|
||||
}
|
||||
|
||||
/** Rig a duration spell directly, sparing the cast ceremony. */
|
||||
export function pushSustained(
|
||||
state: GameState,
|
||||
fx: Omit<SustainedEffect, "data"> & { data?: SustainedEffect["data"] },
|
||||
): void {
|
||||
state.sustained.push({ data: {}, ...fx });
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { applyCommand, activePlayer, boardView, gameLos, sustainedOn, viewFor } from "../src";
|
||||
import { cellKey, edgeKey, type Cell } from "../src/board";
|
||||
import { applyCommand, activePlayer, boardView, createGame, gameLos, sustainedOn, viewFor } from "../src";
|
||||
import { cellKey, edgeKey, hasLineOfSight, sightBetween, traceSight, type Cell } from "../src/board";
|
||||
import type { CardInstance } from "../src/cards";
|
||||
import { newGame, must, giveCard, toRound2, emptyNeighborCell } from "./helpers";
|
||||
|
||||
@@ -143,13 +143,16 @@ describe("illusion wall", () => {
|
||||
expect(after.ok).toBe(true);
|
||||
});
|
||||
|
||||
it("opponents test the illusion when they bump it — some see through, some believe", () => {
|
||||
it("an untested illusion blocks the bump; a tested eye rolls its verdict", () => {
|
||||
let believed = 0, sawThrough = 0;
|
||||
for (let seed = 1; seed <= 12; seed++) {
|
||||
const { state, caster, side } = setupIllusion(seed);
|
||||
const other = state.players.find((p) => p.id !== caster)!;
|
||||
other.position = { ...state.players.find((p) => p.id === caster)!.position };
|
||||
let s = must(state, caster, { type: "endTurn", draw: 0 });
|
||||
// Bumping blind is refused: eyes must be tested first.
|
||||
expect(applyCommand(s, other.id, { type: "move", direction: side }).ok).toBe(false);
|
||||
s = must(s, other.id, { type: "testIllusion", cell: other.position, side });
|
||||
const result = applyCommand(s, other.id, { type: "move", direction: side });
|
||||
if (result.ok) sawThrough++;
|
||||
else believed++;
|
||||
@@ -223,11 +226,16 @@ describe("sector manipulation", () => {
|
||||
type: "cast", instanceId: rel.instanceId,
|
||||
target: { kind: "cell", cell: dest }, params: { cell: me.position },
|
||||
});
|
||||
// The maze zero-anchors after the move; measure against the sector's
|
||||
// origin as it settled, not the requested landing.
|
||||
const after = state.players.find((p) => p.id === me.id)!;
|
||||
const dx = dest.x - myOrigin.x, dy = dest.y - myOrigin.y;
|
||||
const newOrigin = state.board.placements[idx]!.origin;
|
||||
const dx = newOrigin.x - myOrigin.x, dy = newOrigin.y - myOrigin.y;
|
||||
expect(after.position).toEqual({ x: posBefore.x + dx, y: posBefore.y + dy });
|
||||
expect(after.home).toEqual({ x: homeBefore.x + dx, y: homeBefore.y + dy });
|
||||
expect(state.board.placements[idx]!.origin).toEqual(dest);
|
||||
// My sector sits east of the other, as asked.
|
||||
const otherAfter = state.board.placements[idx === 0 ? 1 : 0]!.origin;
|
||||
expect(newOrigin).toEqual({ x: otherAfter.x + 5, y: otherAfter.y });
|
||||
// The map reassembled: every treasure/wizard cell exists on the new board.
|
||||
for (const t of state.treasures) {
|
||||
if (t.position) expect(state.board.cells[cellKey(t.position)]).toBe(true);
|
||||
@@ -320,7 +328,6 @@ describe("6e card-face corrections", () => {
|
||||
});
|
||||
state = must(state, defender.id, { type: "counteract", instanceId: "wall-of-fire#WOF" });
|
||||
state = must(state, attacker.id, { type: "pass" });
|
||||
state = must(state, defender.id, { type: "pass" });
|
||||
expect(state.players.find((p) => p.id === defender.id)!.life).toBe(15);
|
||||
|
||||
// But it cannot counter a fireball.
|
||||
@@ -334,3 +341,227 @@ describe("6e card-face corrections", () => {
|
||||
expect(applyCommand(state, defender.id, { type: "counteract", instanceId: "wall-of-fire#WOF2" }).ok).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("relocation past the origin", () => {
|
||||
function freshGame() {
|
||||
const { state } = createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic"] });
|
||||
return state;
|
||||
}
|
||||
|
||||
it("a sector may land at negative coordinates — the maze renormalizes", () => {
|
||||
let state = freshGame();
|
||||
const me = activePlayer(state);
|
||||
const other = state.players.find((p) => p.id !== me.id)!;
|
||||
const idx = state.board.placements.findIndex(
|
||||
(p) => me.position.y >= p.origin.y && me.position.y < p.origin.y + 5,
|
||||
);
|
||||
const otherIdx = idx === 0 ? 1 : 0;
|
||||
const otherOrigin = state.board.placements[otherIdx]!.origin;
|
||||
// Land WEST of the other sector: x = otherOrigin.x - 5, likely negative.
|
||||
const dest = { x: otherOrigin.x - 5, y: otherOrigin.y };
|
||||
const otherPosBefore = { ...other.position };
|
||||
const rel = giveCard(state, me.id, "relocate-sector");
|
||||
state = must(state, me.id, {
|
||||
type: "cast", instanceId: rel.instanceId,
|
||||
target: { kind: "cell", cell: dest }, params: { cell: me.position },
|
||||
});
|
||||
// The maze zero-anchors: origins snug against both axes.
|
||||
const origins = state.board.placements.map((p: { origin: Cell }) => p.origin);
|
||||
expect(Math.min(...origins.map((o: Cell) => o.x))).toBe(0);
|
||||
expect(Math.min(...origins.map((o: Cell) => o.y))).toBe(0);
|
||||
// Everyone stands on a cell the reassembled board knows.
|
||||
for (const p of state.players) {
|
||||
expect(state.board.cells[cellKey(p.position)]).toBe(true);
|
||||
expect(state.board.cells[cellKey(p.home)]).toBe(true);
|
||||
}
|
||||
// The static sector's tenant rode the renormalization shift exactly.
|
||||
const finalOther = state.board.placements[otherIdx]!.origin;
|
||||
const shifted = state.players.find((p: { id: string }) => p.id === other.id)!;
|
||||
expect(shifted.position).toEqual({
|
||||
x: otherPosBefore.x + (finalOther.x - otherOrigin.x),
|
||||
y: otherPosBefore.y + (finalOther.y - otherOrigin.y),
|
||||
});
|
||||
});
|
||||
|
||||
it("a diagonal landing breaks adjacency and is refused", () => {
|
||||
let { state } = newGame();
|
||||
const me = activePlayer(state);
|
||||
const idx = state.board.placements.findIndex(
|
||||
(p) => me.position.y >= p.origin.y && me.position.y < p.origin.y + 5,
|
||||
);
|
||||
const otherOrigin = state.board.placements[idx === 0 ? 1 : 0]!.origin;
|
||||
const rel = giveCard(state, me.id, "relocate-sector");
|
||||
const refused = applyCommand(state, me.id, {
|
||||
type: "cast", instanceId: rel.instanceId,
|
||||
target: { kind: "cell", cell: { x: otherOrigin.x - 5, y: otherOrigin.y - 5 } },
|
||||
params: { cell: me.position },
|
||||
});
|
||||
expect(refused.ok).toBe(false);
|
||||
});
|
||||
|
||||
it("a moving sector carries its creature, glue, warp tokens, and traps", () => {
|
||||
let state = freshGame();
|
||||
const me = activePlayer(state);
|
||||
const idx = state.board.placements.findIndex(
|
||||
(p) => me.position.y >= p.origin.y && me.position.y < p.origin.y + 5,
|
||||
);
|
||||
const myOrigin = state.board.placements[idx]!.origin;
|
||||
const otherOrigin = state.board.placements[idx === 0 ? 1 : 0]!.origin;
|
||||
const inMine = (c: Cell) =>
|
||||
c.x >= myOrigin.x && c.x < myOrigin.x + 5 && c.y >= myOrigin.y && c.y < myOrigin.y + 5;
|
||||
// Seed passengers on the moving sector.
|
||||
const spot = { x: myOrigin.x + 2, y: myOrigin.y + 2 };
|
||||
expect(inMine(spot)).toBe(true);
|
||||
state.creatures.push({
|
||||
id: "c1", kind: "troll", controllerId: me.id, position: { ...spot },
|
||||
damage: 0, maxDamage: 5, movesPerTurn: 3, movementUsed: 0,
|
||||
attackUsed: false, justCreated: false,
|
||||
wallPassesPerTurn: 0, wallPassUsed: 0, scorchedThisTurn: [],
|
||||
});
|
||||
state.gluedCells[cellKey(spot)] = true;
|
||||
state.dimWarps.push({ a: { ...spot }, b: { x: otherOrigin.x + 1, y: otherOrigin.y + 1 } });
|
||||
state.boobytraps.push({ casterId: me.id, cells: [{ ...spot }], realKey: cellKey(spot) });
|
||||
|
||||
const dest = { x: otherOrigin.x + 5, y: otherOrigin.y };
|
||||
const rel = giveCard(state, me.id, "relocate-sector");
|
||||
state = must(state, me.id, {
|
||||
type: "cast", instanceId: rel.instanceId,
|
||||
target: { kind: "cell", cell: dest }, params: { cell: me.position },
|
||||
});
|
||||
// Expected coordinates follow the final placements (move + zero-anchor).
|
||||
const finalMine = state.board.placements[idx]!.origin;
|
||||
const finalOther = state.board.placements[idx === 0 ? 1 : 0]!.origin;
|
||||
const moved = { x: spot.x + finalMine.x - myOrigin.x, y: spot.y + finalMine.y - myOrigin.y };
|
||||
// The warp's far token sat one square inside the static sector.
|
||||
const staticShifted = { x: finalOther.x + 1, y: finalOther.y + 1 };
|
||||
expect(state.creatures[0]!.position).toEqual(moved);
|
||||
expect(state.gluedCells[cellKey(moved)]).toBe(true);
|
||||
expect(state.dimWarps[0]!.a).toEqual(moved);
|
||||
expect(state.dimWarps[0]!.b).toEqual(staticShifted);
|
||||
expect(state.boobytraps[0]!.cells[0]).toEqual(moved);
|
||||
expect(state.boobytraps[0]!.realKey).toBe(cellKey(moved));
|
||||
});
|
||||
});
|
||||
|
||||
describe("junction alterations roll for their sector", () => {
|
||||
it("a conjured wall on the seam obeys the die: 1-2 stays, 3-4 travels", () => {
|
||||
const { state: fresh } = createGame({ playerIds: ["a", "b"], seed: 42, sets: ["basic"] });
|
||||
let state = toRound2(fresh);
|
||||
// The 2p board is two sectors stacked: the seam runs between them.
|
||||
const [p0, p1] = state.board.placements;
|
||||
const seamY = Math.max(p0!.origin.y, p1!.origin.y) - 1;
|
||||
const seamCell = { x: p0!.origin.x + 2, y: seamY };
|
||||
const key = edgeKey(seamCell, "S");
|
||||
// Conjure a wall on the seam (state surgery: the cast needs LOS we may lack).
|
||||
state.edgeOverrides[key] = "wall";
|
||||
state.createdEdges[key] = true;
|
||||
const caster = activePlayer(state);
|
||||
const rot = giveCard(state, caster.id, "rotate-sector");
|
||||
const rngBefore = JSON.stringify(state.rng);
|
||||
state = must(state, caster.id, {
|
||||
type: "cast", instanceId: rot.instanceId,
|
||||
target: { kind: "cell", cell: { x: p1!.origin.x + 2, y: p1!.origin.y + 2 } },
|
||||
params: { clockwise: true },
|
||||
});
|
||||
// A die was consumed for the seam wall.
|
||||
expect(JSON.stringify(state.rng)).not.toBe(rngBefore);
|
||||
// The wall is somewhere: either the old seam key or a remapped edge.
|
||||
const createdKeys = Object.keys(state.createdEdges);
|
||||
expect(createdKeys.length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("sight tracing", () => {
|
||||
it("agrees with sightBetween on every pair and pins entry/exit to the mouths", () => {
|
||||
const { state } = createGame({ playerIds: ["a", "b"], seed: 42, sets: ["basic"] });
|
||||
const board = boardView(state);
|
||||
const cells = Object.keys(board.cells).map((k) => {
|
||||
const [x, y] = k.split(",").map(Number) as [number, number];
|
||||
return { x, y };
|
||||
});
|
||||
let warped = 0;
|
||||
for (const from of cells) {
|
||||
for (const to of cells) {
|
||||
const t = traceSight(board, from, to);
|
||||
expect(t !== null).toBe(sightBetween(board, from, to));
|
||||
if (!t) continue;
|
||||
if (hasLineOfSight(board, from, to)) {
|
||||
expect(t.kind).toBe("direct");
|
||||
} else {
|
||||
expect(t.kind).toBe("warp");
|
||||
if (t.kind === "warp") {
|
||||
warped++;
|
||||
// Each crossing point lies on its mouth's one-cell rim segment.
|
||||
const onRim = (p: { x: number; y: number }, m: { cell: Cell; side: string }) => {
|
||||
if (m.side === "N") return p.y === m.cell.y && p.x > m.cell.x && p.x < m.cell.x + 1;
|
||||
if (m.side === "S") return p.y === m.cell.y + 1 && p.x > m.cell.x && p.x < m.cell.x + 1;
|
||||
if (m.side === "W") return p.x === m.cell.x && p.y > m.cell.y && p.y < m.cell.y + 1;
|
||||
return p.x === m.cell.x + 1 && p.y > m.cell.y && p.y < m.cell.y + 1;
|
||||
};
|
||||
expect(onRim(t.entry, t.mouthA)).toBe(true);
|
||||
expect(onRim(t.exit, t.mouthB)).toBe(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
expect(warped).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("illusions are tested by choice", () => {
|
||||
function shimmerRig() {
|
||||
let { state } = createGame({ playerIds: ["a", "b"], seed: 42, sets: ["basic"] });
|
||||
state = toRound2(state);
|
||||
const caster = activePlayer(state);
|
||||
const mark = state.players.find((p) => p.id !== caster.id)!;
|
||||
// Conjure the illusion on an OPEN edge beside the victim (state surgery
|
||||
// for a deterministic spot; the cast itself is tested elsewhere).
|
||||
const spot = emptyNeighborCell(state, mark.position);
|
||||
const key = edgeKey(mark.position, spot.side);
|
||||
state.illusionWalls[key] = { createdBy: caster.id, belief: {} };
|
||||
state = must(state, caster.id, { type: "endTurn", draw: 0 });
|
||||
return {
|
||||
state, caster: caster.id, victim: mark.id, side: spot.side,
|
||||
cell: { ...state.players.find((p) => p.id === mark.id)!.position },
|
||||
};
|
||||
}
|
||||
|
||||
it("an untested shimmer blocks the walker with its own message, no die rolled", () => {
|
||||
const { state, victim, side } = shimmerRig();
|
||||
const rngBefore = JSON.stringify(state.rng);
|
||||
const r = applyCommand(state, victim, { type: "move", direction: side });
|
||||
expect(r.ok).toBe(false);
|
||||
if (!r.ok) expect(r.error).toContain("shimmers");
|
||||
expect(JSON.stringify(state.rng)).toBe(rngBefore);
|
||||
});
|
||||
|
||||
it("the belief test is an explicit roll; the verdict then governs the wall", () => {
|
||||
let { state, victim, cell, side } = shimmerRig();
|
||||
state = must(state, victim, { type: "testIllusion", cell, side });
|
||||
const verdict = state.illusionWalls[edgeKey(cell, side)]!.belief[victim];
|
||||
expect(verdict === "believes" || verdict === "seesThrough").toBe(true);
|
||||
const r = applyCommand(state, victim, { type: "move", direction: side });
|
||||
if (verdict === "seesThrough") {
|
||||
expect(r.ok).toBe(true);
|
||||
} else {
|
||||
expect(r.ok).toBe(false);
|
||||
if (!r.ok) expect(r.error).toBe("blocked by wall");
|
||||
}
|
||||
// A second test is refused: eyes rule once.
|
||||
expect(applyCommand(state, victim, { type: "testIllusion", cell, side }).ok).toBe(false);
|
||||
});
|
||||
|
||||
it("the creator strolls through their own fake without any test", () => {
|
||||
let { state, caster } = shimmerRig();
|
||||
// Skip to the caster's turn; the wall never blocks its maker.
|
||||
while (activePlayer(state).id !== caster) {
|
||||
state = must(state, activePlayer(state).id, { type: "endTurn", draw: 0 });
|
||||
}
|
||||
const me = state.players.find((p) => p.id === caster)!;
|
||||
const other = state.players.find((p) => p.id !== caster)!;
|
||||
me.position = { ...other.position };
|
||||
const r = applyCommand(state, caster, { type: "move", direction: "E" });
|
||||
// Blocked only if some REAL edge stands there; the illusion itself never objects.
|
||||
if (!r.ok) expect(r.error).not.toContain("shimmers");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { applyCommand, activePlayer, boardView, gameLos, sustainedOn } from "../src/game";
|
||||
import { applyCommand, activePlayer, boardView, createGame, gameLos, sustainedOn } from "../src/game";
|
||||
import { cellKey, edgeKey, neighbor, SIDES } from "../src/board";
|
||||
import type { CardInstance } from "../src/cards";
|
||||
import { newGame, must, giveCard, toRound2, faceOff, castAt, emptyNeighborCell } from "./helpers";
|
||||
@@ -277,3 +277,17 @@ describe("control effects", () => {
|
||||
expect(state.players.find((p) => p.id === me.id)!.hand.some((c) => c.cardId === "create-wall")).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("picking one of two treasures", () => {
|
||||
it("a named treasure is the one taken", () => {
|
||||
let { state } = createGame({ playerIds: ["a", "b"], seed: 42, sets: ["basic"] });
|
||||
state = toRound2(state);
|
||||
const p = activePlayer(state);
|
||||
const [t1, t2] = state.treasures.filter((t) => t.owner !== p.id);
|
||||
t1!.position = { ...p.position }; t1!.carriedBy = null;
|
||||
t2!.position = { ...p.position }; t2!.carriedBy = null;
|
||||
const r = applyCommand(state, p.id, { type: "pickUpTreasure", treasureId: t2!.id });
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
expect(r.state.players.find((q) => q.id === p.id)!.carriedTreasureId).toBe(t2!.id);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
// The telepath guard: every event the engine emits must reach the player —
|
||||
// a log line, an effect, or a modal — and every targeted cast must be
|
||||
// aimable on the board. A new event or card that slips past the client
|
||||
// fails here, instead of surfacing one puzzled bug report at a time.
|
||||
import { readFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
const ENGINE = join(__dirname, "..", "src");
|
||||
const WEB = join(__dirname, "..", "..", "web", "src");
|
||||
const game = readFileSync(join(ENGINE, "game.ts"), "utf8");
|
||||
const app = readFileSync(join(WEB, "App.svelte"), "utf8");
|
||||
const clientSources = ["net.svelte.ts", "fx.ts", "local.svelte.ts", "Replay.svelte", "hints.ts"]
|
||||
.map((f) => readFileSync(join(WEB, f), "utf8"))
|
||||
.concat(app)
|
||||
.join("\n");
|
||||
|
||||
/** Events whose information reaches the player another way — each with the
|
||||
* reason. Add here ONLY with a reason; "I'll wire it later" is not one. */
|
||||
const SILENT_BY_DESIGN: Record<string, string> = {
|
||||
cardsDealt: "the opening deal: the hand tray is the reveal",
|
||||
cardsDealtPrivate: "same — your opening hand appears in the tray",
|
||||
boobytrapPlacedPrivate: "the board marks the caster's real token from the view",
|
||||
};
|
||||
|
||||
function eventTypes(): string[] {
|
||||
const start = game.indexOf("export type GameEvent =");
|
||||
const block = game.slice(start, game.indexOf("\nexport ", start + 10));
|
||||
return [...new Set([...block.matchAll(/\| \{ type: "([a-zA-Z]+)"/g)].map((m) => m[1]!))];
|
||||
}
|
||||
|
||||
describe("every engine event reaches the player", () => {
|
||||
it("is humanized, animated, handled in a modal, or silent by design", () => {
|
||||
const handled = new Set<string>();
|
||||
for (const m of clientSources.matchAll(/case "([a-zA-Z]+)"/g)) handled.add(m[1]!);
|
||||
for (const m of clientSources.matchAll(/type === "([a-zA-Z]+)"/g)) handled.add(m[1]!);
|
||||
const orphans = eventTypes().filter((e) => !handled.has(e) && !(e in SILENT_BY_DESIGN));
|
||||
expect(orphans, `events no client code touches: ${orphans.join(", ")}`).toEqual([]);
|
||||
});
|
||||
|
||||
it("keeps the silent-by-design list honest (no stale entries)", () => {
|
||||
const known = new Set(eventTypes());
|
||||
const stale = Object.keys(SILENT_BY_DESIGN).filter((e) => !known.has(e));
|
||||
expect(stale, `allowlisted events the engine no longer emits: ${stale.join(", ")}`).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("every targeted cast is aimable on the board", () => {
|
||||
/** A card's resolver demanding a cell/edge target must appear in App's
|
||||
* click-targeting sets, or selecting the card leaves it uncastable. */
|
||||
it("cell- and edge-demanding resolvers appear in CELL_CARDS / EDGE_CARDS", () => {
|
||||
const start = game.indexOf("const CARD_EFFECTS");
|
||||
const end = game.indexOf("\n};", start); // the table's own closing brace
|
||||
const entries = game.slice(start, end).split(/\n (?="?[a-z][a-z0-9-]*"?: \{)/);
|
||||
const appSet = (name: string) =>
|
||||
new Set([...(app.match(new RegExp(`${name} = new Set\\(\\[([^\\]]*)\\]`))?.[1] ?? "")
|
||||
.matchAll(/"([a-z-]+)"/g)].map((m) => m[1]!));
|
||||
const cellCards = appSet("CELL_CARDS");
|
||||
const edgeCards = appSet("EDGE_CARDS");
|
||||
const missing: string[] = [];
|
||||
for (const entry of entries) {
|
||||
const id = entry.match(/^"?([a-z][a-z0-9-]*)"?: \{/)?.[1];
|
||||
if (!id) continue;
|
||||
// Only demands stated as refusals bind: `target.kind !== "cell"` etc.
|
||||
// (an optional `target?.kind === ...` branch is not a requirement).
|
||||
if (/target \|\| cmd\.target\.kind !== "cell"/.test(entry) &&
|
||||
!cellCards.has(id)) missing.push(`${id} (cell)`);
|
||||
if (/target \|\| cmd\.target\.kind !== "edge"/.test(entry) &&
|
||||
!edgeCards.has(id)) missing.push(`${id} (edge)`);
|
||||
}
|
||||
expect(missing, `casts the board cannot aim: ${missing.join(", ")}`).toEqual([]);
|
||||
});
|
||||
});
|
||||
@@ -1,8 +1,8 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { applyCommand, activePlayer, boardView } from "../src/game";
|
||||
import { applyCommand, activePlayer, boardView, createGame } from "../src/game";
|
||||
import { cellKey, edgeKey, SIDES, type Cell, type Side } from "../src/board";
|
||||
import type { CardInstance } from "../src/cards";
|
||||
import { newExpansionGame as newGame, must, giveCard, toRound2, faceOff } from "./helpers";
|
||||
import { newExpansionGame as newGame, must, giveCard, toRound2, faceOff, plainRimWall } from "./helpers";
|
||||
|
||||
describe("magic wands", () => {
|
||||
it("blaster wand: charges on first use, once per turn, discards when spent", () => {
|
||||
@@ -12,11 +12,6 @@ describe("magic wands", () => {
|
||||
const wand = giveCard(state, attacker, "blaster-wand");
|
||||
giveCard(state, attacker, "number-2", "N", 1);
|
||||
|
||||
// First use without a number card is refused.
|
||||
expect(applyCommand(state, attacker, {
|
||||
type: "cast", instanceId: wand.instanceId, target: { kind: "player", playerId: defender },
|
||||
}).ok).toBe(false);
|
||||
|
||||
// Charged with a 2: fires (3 damage), one charge left, wand displayed.
|
||||
state = must(state, attacker, {
|
||||
type: "cast", instanceId: wand.instanceId, numberInstanceIds: ["number-2#N"],
|
||||
@@ -148,6 +143,31 @@ describe("magic wands", () => {
|
||||
expect(boardView(state).edges[key]).toBe("wall");
|
||||
});
|
||||
|
||||
it("warp wand bores the rim: a wraparound that closes at turn's end", () => {
|
||||
let { state } = createGame({
|
||||
playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"],
|
||||
});
|
||||
const me = activePlayer(state);
|
||||
const rim = plainRimWall(state);
|
||||
me.position = { ...rim.cell };
|
||||
const warpsBefore = state.board.warps.length;
|
||||
const wand = giveCard(state, me.id, "warp-wand");
|
||||
giveCard(state, me.id, "number-2", "N", 1);
|
||||
state = must(state, me.id, {
|
||||
type: "cast", instanceId: wand.instanceId, numberInstanceIds: ["number-2#N"],
|
||||
target: { kind: "edge", cell: rim.cell, side: rim.side },
|
||||
});
|
||||
expect(state.board.warps.length).toBe(warpsBefore + 2);
|
||||
// The wraparound runs: step off the rim and land on the opposite edge.
|
||||
state = must(state, me.id, { type: "move", direction: rim.side });
|
||||
const across = state.players.find((p) => p.id === me.id)!.position;
|
||||
expect(cellKey(across)).not.toBe(cellKey(rim.cell));
|
||||
// Turn's end: the walls return and the warp closes with them.
|
||||
state = must(state, me.id, { type: "endTurn", draw: 0 });
|
||||
expect(boardView(state).edges[edgeKey(rim.cell, rim.side)]).toBe("wall");
|
||||
expect(state.board.warps.length).toBe(warpsBefore);
|
||||
});
|
||||
|
||||
it("deja-vu retrieves from the discard, but never a wand", () => {
|
||||
let { state } = newGame();
|
||||
const me = activePlayer(state);
|
||||
@@ -210,3 +230,20 @@ describe("dropping objects", () => {
|
||||
expect(refused.ok).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("a bare wand lights a single charge", () => {
|
||||
it("'played without a number card, its power is only 1': one shot, then dust", () => {
|
||||
let { state } = newGame();
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
const bw = giveCard(state, attacker, "blaster-wand");
|
||||
state = must(state, attacker, {
|
||||
type: "cast", instanceId: bw.instanceId, target: { kind: "player", playerId: defender },
|
||||
});
|
||||
state = must(state, defender, { type: "pass" });
|
||||
// The single charge fired (3 flat damage) and the wand crumbled.
|
||||
expect(state.players.find((p) => p.id === defender)!.life).toBe(12);
|
||||
expect(state.players.find((p) => p.id === attacker)!.hand.some((c) => c.cardId === "blaster-wand")).toBe(false);
|
||||
expect(state.wandCharges[bw.instanceId]).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
"compilerOptions": {
|
||||
"noEmit": true
|
||||
},
|
||||
"include": ["src"]
|
||||
"include": ["src", "test"]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
// The automatons' table talk, one voice per temperament. Edit freely — the
|
||||
// server picks from these pools at random, sparingly (menace over chatter).
|
||||
//
|
||||
// Triggers: grabGold (picked up a treasure), deliverGold (dropped one on a
|
||||
// home base), dealPain (hurt somebody), takePain (got hurt), kill, die,
|
||||
// summon (created a creature), buildWall, escape (self-teleported away),
|
||||
// springTrap (drew a TRAP card), dodge (an attack missed them), win.
|
||||
|
||||
import type { AutomatonStyle } from "@wizwar/engine";
|
||||
|
||||
export type BanterTrigger =
|
||||
| "grabGold" | "deliverGold" | "dealPain" | "takePain" | "kill" | "die"
|
||||
| "summon" | "buildWall" | "escape" | "springTrap" | "dodge" | "win";
|
||||
|
||||
export const BOT_LINES: Record<AutomatonStyle, Partial<Record<BanterTrigger, string[]>>> = {
|
||||
hunter: {
|
||||
grabGold: [
|
||||
"ACQUISITION COMPLETE.",
|
||||
"YOUR GOLD HAS BEEN REALLOCATED.",
|
||||
"ASSET SECURED.",
|
||||
"APPRAISAL: ADEQUATE. TAKING IT ANYWAY.",
|
||||
],
|
||||
deliverGold: [
|
||||
"DELIVERY CONFIRMED. PLEASURE DOING BUSINESS.",
|
||||
"LOGISTICS IS MY LOVE LANGUAGE.",
|
||||
"RECEIPT AVAILABLE UPON REQUEST.",
|
||||
],
|
||||
dealPain: [
|
||||
"AN INEFFICIENT USE OF YOUR TURN.",
|
||||
"COSTS HAVE BEEN PASSED TO THE CONSUMER.",
|
||||
"THIS IS BILLABLE.",
|
||||
],
|
||||
takePain: [
|
||||
"DAMAGE NOTED. INVOICE PENDING.",
|
||||
"THAT COMES OUT OF YOUR ESTATE.",
|
||||
],
|
||||
kill: [
|
||||
"INVENTORY TRANSFERRED. CONDOLENCES.",
|
||||
"ACCOUNT CLOSED.",
|
||||
],
|
||||
die: [
|
||||
"FILING FOR BANKRUPTCY.",
|
||||
"THE MARKET HAS CORRECTED.",
|
||||
],
|
||||
summon: ["A SUBCONTRACTOR HAS BEEN RETAINED."],
|
||||
buildWall: ["ZONING APPROVED."],
|
||||
escape: ["RELOCATION EXPENSES: JUSTIFIED."],
|
||||
springTrap: ["AN UNFORESEEN LIABILITY."],
|
||||
dodge: ["PROJECTIONS SAID YOU WOULD MISS."],
|
||||
win: ["PLEASURE DOING BUSINESS WITH ALL OF YOU."],
|
||||
},
|
||||
berserker: {
|
||||
grabGold: [
|
||||
"GOLD IS MERELY BAIT.",
|
||||
"SHINY. IRRELEVANT.",
|
||||
],
|
||||
dealPain: [
|
||||
"YES. AGAIN.",
|
||||
"PAIN RECEIPT PRINTED.",
|
||||
"HOLD STILL. THIS IS THE FUN PART.",
|
||||
"THE MAZE PROVIDES.",
|
||||
],
|
||||
takePain: [
|
||||
"GOOD. NOW IT IS INTERESTING.",
|
||||
"I FELT THAT. DO IT AGAIN.",
|
||||
],
|
||||
kill: [
|
||||
"SCHEDULED DEMISE: DELIVERED.",
|
||||
"NEXT.",
|
||||
"THE PILE GROWS.",
|
||||
],
|
||||
die: [
|
||||
"SAVE MY SEAT.",
|
||||
"I WILL BE BACK FOR THE REMATCH.",
|
||||
],
|
||||
summon: [
|
||||
"I HAVE MADE YOU A FRIEND. IT IS NOT FRIENDLY.",
|
||||
"IT EATS WHAT I TELL IT TO EAT.",
|
||||
],
|
||||
buildWall: ["MORE CORNERS TO TRAP YOU IN."],
|
||||
escape: ["A TACTICAL LEAP. NOT A RETREAT."],
|
||||
springTrap: ["WHO PUT THAT THERE. RESPECT."],
|
||||
dodge: ["SWING HARDER."],
|
||||
win: ["LAST ONE STANDING. AS FORETOLD."],
|
||||
},
|
||||
worrier: {
|
||||
grabGold: [
|
||||
"taking this. sorry. sorry.",
|
||||
"borrowing it. permanently. sorry.",
|
||||
],
|
||||
deliverGold: ["home. safe. breathe."],
|
||||
dealPain: [
|
||||
"ow. logged.",
|
||||
"unnecessary!",
|
||||
"that looked like it hurt. it was supposed to. i think.",
|
||||
],
|
||||
takePain: [
|
||||
"rude.",
|
||||
"i wrote it down. the list is long.",
|
||||
],
|
||||
kill: [
|
||||
"oh no. oh no. it worked?",
|
||||
"i'm not proud. mostly.",
|
||||
],
|
||||
die: [
|
||||
"called it.",
|
||||
"this is fine. this is fine. this is not fine.",
|
||||
],
|
||||
summon: ["please be nice to it. actually don't."],
|
||||
buildWall: [
|
||||
"good wall. safe wall.",
|
||||
"one more wall between me and everything.",
|
||||
],
|
||||
escape: ["nope nope nope."],
|
||||
springTrap: ["i knew the floor was suspicious."],
|
||||
dodge: ["missed me. oh thank goodness. i mean: ha."],
|
||||
win: ["wait. me? check again."],
|
||||
},
|
||||
};
|
||||
@@ -9,16 +9,22 @@
|
||||
// {type:"claimTransfer", code} claim a seat on a new device
|
||||
// {type:"catchUp", sinceSeq} replay of moves missed while away
|
||||
// {type:"chat", text} table talk to the room
|
||||
// {type:"rollDie"} the tabletop D4, published as talk
|
||||
// {type:"addBot", style?, tier?} host seats an automaton
|
||||
// {type:"watch", roomId} join the Peanut Gallery: nameless, read-only
|
||||
// {type:"leave"} detach this socket from table or gallery
|
||||
// {type:"myGames", seats} summaries for held seats
|
||||
// {type:"stats"} the engagement tally
|
||||
// {type:"hotseatReport", ...} anonymous hotseat game counts
|
||||
// server -> client:
|
||||
// {type:"welcome"} on connect
|
||||
// {type:"seat", playerId, token} your seat secret — keep it
|
||||
// {type:"room", roomId, players, hostId, started, colors}
|
||||
// {type:"events", events} redacted for this recipient
|
||||
// {type:"room", roomId, players, hostId, started, audience, colors, bots}
|
||||
// {type:"events", events, replayed?} redacted for this recipient
|
||||
// {type:"state", view, seq} redacted full view (after every change)
|
||||
// {type:"chat", player, text, at} one line of table talk
|
||||
// {type:"watching", roomId} you are seated in the gallery
|
||||
// {type:"audience", count} how many watch from the gallery
|
||||
// {type:"transferCode"|"transferClaimed"|"catchUp"|"games"|"stats"}
|
||||
// {type:"error", message}
|
||||
|
||||
@@ -29,24 +35,35 @@ import { WebSocketServer, WebSocket } from "ws";
|
||||
import type { Command, PlayerId } from "@wizwar/engine";
|
||||
import {
|
||||
catchUpSteps,
|
||||
momentSteps,
|
||||
claimTransferCode,
|
||||
createRoom,
|
||||
pickColor,
|
||||
getRoom,
|
||||
joinRoom,
|
||||
loadPersistedRooms,
|
||||
runningRooms,
|
||||
addAutomaton,
|
||||
addChat,
|
||||
driveOneAutomaton,
|
||||
makeTransferCode,
|
||||
redactFor,
|
||||
roomCount,
|
||||
runCommand,
|
||||
seatTokenValid,
|
||||
SPECTATOR,
|
||||
type CatchUpStep,
|
||||
startGame,
|
||||
summarize,
|
||||
viewForPlayer,
|
||||
type Room,
|
||||
kickSeat,
|
||||
abandonRoom,
|
||||
} from "./rooms";
|
||||
import { engagementStats, recordHotseat } from "./stats";
|
||||
import { getShare, loadShares, mintShare } from "./shares";
|
||||
import { renderSharePng } from "./ogimage";
|
||||
import { BOT_LINES, type BanterTrigger } from "./banter";
|
||||
|
||||
// --- Abuse limits: this is a public server on a small box. -----------------
|
||||
const MAX_SOCKETS = 300; // concurrent connections
|
||||
@@ -55,6 +72,7 @@ const MAX_ROOMS_PER_CONN = 10; // rooms one connection may create
|
||||
const MAX_COMMAND_BYTES = 16384; // serialized game command
|
||||
const MAX_MYGAMES_SEATS = 50; // seats checked per myGames request
|
||||
const CATCHUP_COOLDOWN_MS = 3000; // full-game replays are CPU-heavy
|
||||
const MAX_AUDIENCE = 30; // gallery seats per room
|
||||
const NAME_MAX = 24;
|
||||
|
||||
/** Player/room names: printable, trimmed, bounded. */
|
||||
@@ -67,6 +85,12 @@ const port = Number(process.env.PORT ?? 8787);
|
||||
// is not reachable from the internet. Dev default stays LAN-friendly.
|
||||
const host = process.env.HOST ?? "0.0.0.0";
|
||||
loadPersistedRooms();
|
||||
loadShares();
|
||||
// A restart can land mid-bot-turn: without a kick, a restored room whose
|
||||
// current actor is an automaton waits forever for a human to poke it.
|
||||
setTimeout(() => {
|
||||
for (const room of runningRooms()) runBots(room);
|
||||
}, 2000); // a beat for clients to reconnect before the clockwork stirs
|
||||
|
||||
// One process serves both the built client and the websocket, so production
|
||||
// needs only a TLS proxy in front (or nothing, on a LAN).
|
||||
@@ -79,6 +103,85 @@ const MIME: Record<string, string> = {
|
||||
// The client build may be absent in development (vite serves it instead);
|
||||
// serve a 404 for static requests in that case rather than dying on boot.
|
||||
const staticRoot = existsSync(STATIC_DIR) ? realpathSync(normalize(STATIC_DIR)) : null;
|
||||
|
||||
// --- Share pages: one turn, rebuilt for the nameless viewer. ---------------
|
||||
// Every lookup is a full-game replay, so results rest briefly in memory.
|
||||
|
||||
interface ShareData {
|
||||
steps: CatchUpStep[];
|
||||
actor: string;
|
||||
round: number;
|
||||
/** A whole finished game rather than one turn. */
|
||||
whole?: boolean;
|
||||
}
|
||||
const shareCache = new Map<string, { at: number; data: ShareData | null }>();
|
||||
function shareData(id: string): ShareData | null {
|
||||
const hit = shareCache.get(id);
|
||||
if (hit && Date.now() - hit.at < 30_000) return hit.data;
|
||||
let data: ShareData | null = null;
|
||||
const share = getShare(id);
|
||||
const room = share ? getRoom(share.roomId) : undefined;
|
||||
if (share && room?.state) {
|
||||
if (share.turn < 0) {
|
||||
// The whole tale: a finished game from the deal to the crown.
|
||||
const steps = catchUpSteps(room, SPECTATOR, 0, true);
|
||||
if (!("error" in steps) && steps.length > 0) {
|
||||
let winner = "";
|
||||
for (const st of steps) {
|
||||
for (const e of st.events) if (e.type === "gameWon" && "player" in e) winner = e.player;
|
||||
}
|
||||
data = { steps, actor: winner, round: 0, whole: true };
|
||||
}
|
||||
} else {
|
||||
const reel = momentSteps(room, SPECTATOR, share.turn);
|
||||
if (!("error" in reel) && reel.steps.length > 0) {
|
||||
data = { steps: reel.steps, actor: reel.owner, round: reel.round };
|
||||
}
|
||||
}
|
||||
}
|
||||
if (shareCache.size > 50) shareCache.clear();
|
||||
shareCache.set(id, { at: Date.now(), data });
|
||||
return data;
|
||||
}
|
||||
|
||||
const escapeHtml = (t: string) =>
|
||||
t.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
||||
|
||||
/** index.html with this share's OpenGraph card folded into its head —
|
||||
* crawlers never run the app, so the unfurl must arrive pre-baked. */
|
||||
function shareHtml(id: string, data: ShareData, rawHost: string, rawProto: string): string {
|
||||
// Host and proto arrive from request headers — attacker-writable text
|
||||
// that must never reach an HTML attribute raw.
|
||||
const proto = /^https?$/.test(rawProto) ? rawProto : "https";
|
||||
const host = escapeHtml(rawHost);
|
||||
// The stock page carries its own generic card; strip it, or crawlers
|
||||
// (which take the FIRST tag they meet) never see this turn's.
|
||||
const html = readFileSync(join(staticRoot!, "index.html"), "utf8")
|
||||
.replace(/<meta (?:property="og:|name="twitter:)[^>]*>\s*/g, "")
|
||||
.replace(/<title>[^<]*<\/title>\s*/, "");
|
||||
const base = `${proto}://${host}`;
|
||||
const title = data.whole
|
||||
? "The whole tale — a game of Wiz-War, replayed"
|
||||
: `${escapeHtml(data.actor)}'s turn — a Wiz-War instant replay`;
|
||||
const desc = data.whole
|
||||
? `A full game of Wiz-War, magical combat in a stone labyrinth — every turn through its wizard's own eyes${data.actor ? `, to ${escapeHtml(data.actor)}'s triumph` : ""}. Watch it all, then deal yourself in.`
|
||||
: `Round ${data.round || "?"} of a game of Wiz-War, magical combat in a stone labyrinth. ` +
|
||||
`Watch the turn through ${escapeHtml(data.actor)}'s own eyes, then deal yourself in.`;
|
||||
const metas = [
|
||||
`<title>${title}</title>`,
|
||||
`<meta property="og:type" content="website"/>`,
|
||||
`<meta property="og:site_name" content="Wiz-War"/>`,
|
||||
`<meta property="og:title" content="${title}"/>`,
|
||||
`<meta property="og:description" content="${desc}"/>`,
|
||||
`<meta property="og:url" content="${base}/watch/${id}"/>`,
|
||||
`<meta property="og:image" content="${base}/watch/${id}/og.png"/>`,
|
||||
`<meta property="og:image:width" content="1200"/>`,
|
||||
`<meta property="og:image:height" content="630"/>`,
|
||||
`<meta name="twitter:card" content="summary_large_image"/>`,
|
||||
`<meta name="twitter:image" content="${base}/watch/${id}/og.png"/>`,
|
||||
].join("\n ");
|
||||
return html.replace("</head>", ` ${metas}\n </head>`);
|
||||
}
|
||||
const httpServer = createServer((req, res) => {
|
||||
try {
|
||||
if (req.method !== "GET" && req.method !== "HEAD") {
|
||||
@@ -101,6 +204,35 @@ const httpServer = createServer((req, res) => {
|
||||
res.writeHead(400).end();
|
||||
return;
|
||||
}
|
||||
// Share pages: the turn's data, its card image, and its chrome.
|
||||
const api = url.match(/^\/api\/share\/([a-z0-9]{4,20})$/);
|
||||
if (api) {
|
||||
const data = shareData(api[1]!);
|
||||
if (!data) { res.writeHead(404, { "content-type": "application/json" }).end('{"error":"no such replay"}'); return; }
|
||||
res.writeHead(200, {
|
||||
"content-type": "application/json",
|
||||
"cache-control": "public, max-age=60",
|
||||
"access-control-allow-origin": "*",
|
||||
});
|
||||
res.end(JSON.stringify({ steps: data.steps, actor: data.actor, round: data.round, whole: data.whole === true }));
|
||||
return;
|
||||
}
|
||||
const watch = url.match(/^\/watch\/([a-z0-9]{4,20})(\/og\.png)?$/);
|
||||
if (watch) {
|
||||
const data = shareData(watch[1]!);
|
||||
if (!data) { res.writeHead(404).end("no such replay"); return; }
|
||||
if (watch[2]) {
|
||||
const png = renderSharePng(data.steps[data.steps.length - 1]!.view);
|
||||
res.writeHead(200, { "content-type": "image/png", "cache-control": "public, max-age=300" });
|
||||
res.end(png);
|
||||
return;
|
||||
}
|
||||
const proto = String(req.headers["x-forwarded-proto"] ?? "http").split(",")[0]!.trim();
|
||||
const hostname = String(req.headers.host ?? `localhost:${port}`);
|
||||
res.writeHead(200, { "content-type": "text/html", "cache-control": "no-cache" });
|
||||
res.end(shareHtml(watch[1]!, data, hostname, proto));
|
||||
return;
|
||||
}
|
||||
let file = normalize(join(staticRoot, url === "/" ? "index.html" : url));
|
||||
if (file !== staticRoot && !file.startsWith(staticRoot + sep)) {
|
||||
res.writeHead(403).end();
|
||||
@@ -135,6 +267,9 @@ interface Session {
|
||||
socket: WebSocket;
|
||||
playerId: PlayerId | null;
|
||||
roomId: string | null;
|
||||
/** In the Peanut Gallery: spectator implies playerId === null, so every
|
||||
* handler that requires a seat refuses this session by construction. */
|
||||
spectator: boolean;
|
||||
/** The raw seat token this connection authenticated with (memory only). */
|
||||
token: string | null;
|
||||
claimFails: number;
|
||||
@@ -162,6 +297,25 @@ function send(socket: WebSocket, message: unknown): void {
|
||||
if (socket.readyState === WebSocket.OPEN) socket.send(JSON.stringify(message));
|
||||
}
|
||||
|
||||
function audienceCount(room: Room): number {
|
||||
let n = 0;
|
||||
for (const s of sessions) if (s.roomId === room.id && s.spectator) n++;
|
||||
return n;
|
||||
}
|
||||
|
||||
function broadcastAudience(room: Room): void {
|
||||
broadcast(room, () => ({ type: "audience", count: audienceCount(room) }));
|
||||
}
|
||||
|
||||
/** A watcher leaves the gallery (to sit down, watch elsewhere, or vanish). */
|
||||
function leaveGallery(session: Session): void {
|
||||
if (!session.spectator) return;
|
||||
session.spectator = false;
|
||||
const room = session.roomId ? getRoom(session.roomId) : undefined;
|
||||
session.roomId = null;
|
||||
if (room) broadcastAudience(room);
|
||||
}
|
||||
|
||||
function roomInfo(room: Room) {
|
||||
return {
|
||||
type: "room",
|
||||
@@ -169,18 +323,118 @@ function roomInfo(room: Room) {
|
||||
players: room.players,
|
||||
hostId: room.hostId,
|
||||
started: room.state !== null,
|
||||
audience: audienceCount(room),
|
||||
colors: Object.fromEntries(room.colorChoices),
|
||||
bots: Object.fromEntries(
|
||||
// A mystery machine keeps its mood only while the game lives: once it
|
||||
// ends, the hands go face-up and so does the temperament.
|
||||
[...room.bots].map(([name, b]) => [
|
||||
name,
|
||||
room.state?.phase === "finished"
|
||||
? `${b.tier} ${b.style}${b.secret ? " 🎭" : ""}`
|
||||
: `${b.tier} ${b.secret ? "mystery" : b.style}`,
|
||||
]),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
function broadcast(room: Room, makeMessage: (playerId: PlayerId) => unknown): void {
|
||||
for (const s of sessions) {
|
||||
if (s.roomId === room.id && s.playerId) {
|
||||
send(s.socket, makeMessage(s.playerId));
|
||||
if (s.roomId !== room.id) continue;
|
||||
// The gallery hears everything too, redacted for the nameless viewer.
|
||||
if (s.playerId) send(s.socket, makeMessage(s.playerId));
|
||||
else if (s.spectator) send(s.socket, makeMessage(SPECTATOR));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The clockwork plays at a watchable pace: one command every beat, each
|
||||
* broadcast as it lands, until the maze wants a human again.
|
||||
*/
|
||||
const BOT_STEP_MS = 1000;
|
||||
|
||||
/** What a step's event means to this bot — its own deeds when it acted,
|
||||
* its own suffering whoever caused it. Null: nothing worth a word. */
|
||||
function banterTrigger(
|
||||
e: { type: string; [k: string]: unknown }, seat: string, actor: string,
|
||||
): BanterTrigger | null {
|
||||
if (actor === seat) {
|
||||
if (e.type === "treasurePickedUp" && e.player === seat) return "grabGold";
|
||||
if (e.type === "treasureDropped" && e.player === seat && e.onHomeOf != null) return "deliverGold";
|
||||
if (e.type === "damaged" && e.player !== seat) return "dealPain";
|
||||
if (e.type === "died" && e.killedBy === seat && e.player !== seat) return "kill";
|
||||
if (e.type === "creatureCreated" && e.controller === seat) return "summon";
|
||||
if (e.type === "wallCreated" && e.caster === seat) return "buildWall";
|
||||
if (e.type === "trapSprung" && e.player === seat) return "springTrap";
|
||||
}
|
||||
// A counter-teleport escape resolves during the ATTACKER's step, and a
|
||||
// last-standing win can land on the victim's turn: self-referential
|
||||
// triggers hold whoever acted.
|
||||
if (e.type === "teleported" && e.player === seat && e.by === seat) return "escape";
|
||||
if (e.type === "gameWon" && e.player === seat) return "win";
|
||||
if (e.type === "damaged" && e.player === seat) return "takePain";
|
||||
if (e.type === "died" && e.player === seat) return "die";
|
||||
if (e.type === "attackMissed" && e.defender === seat) return "dodge";
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Every seated bot gets a chance to remark on the step — the actor on its
|
||||
* deeds, bystanders on their suffering. Rarely, and one voice at most. */
|
||||
function botRemark(room: Room, actor: string, events: { type: string; [k: string]: unknown }[]): void {
|
||||
for (const [seat, bot] of room.bots) {
|
||||
const lines = BOT_LINES[bot.style] ?? {};
|
||||
for (const e of events) {
|
||||
const trigger = banterTrigger(e, seat, actor);
|
||||
const pool = trigger ? lines[trigger] : undefined;
|
||||
if (!pool || Math.random() > 0.5) continue;
|
||||
const text = pool[Math.floor(Math.random() * pool.length)]!;
|
||||
const said = addChat(room, seat, text);
|
||||
if (!("error" in said)) {
|
||||
broadcast(room, () => ({ type: "chat", player: seat, text: said.text, at: said.at }));
|
||||
}
|
||||
return; // one remark per step, whole table
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Spoken when a clockwork's chosen command was refused by the engine —
|
||||
* the table sees a stumble instead of an unexplained idle turn. */
|
||||
const HESITATION_LINES = [
|
||||
"RECALCULATING.",
|
||||
"TACTICAL PAUSE. INTENTIONAL. PROBABLY.",
|
||||
"THE MAZE REFUSES MY GENIUS.",
|
||||
"ERROR LOGGED. DIGNITY INTACT.",
|
||||
"I MEANT TO DO THAT.",
|
||||
];
|
||||
|
||||
const pumping = new Set<string>();
|
||||
function runBots(room: Room): void {
|
||||
if (pumping.has(room.id)) return;
|
||||
pumping.add(room.id);
|
||||
const tick = () => {
|
||||
const step = driveOneAutomaton(room);
|
||||
if (!step) {
|
||||
pumping.delete(room.id);
|
||||
return;
|
||||
}
|
||||
broadcast(room, (playerId) => ({ type: "events", events: redactFor(step.events, playerId) }));
|
||||
broadcast(room, (playerId) => ({ type: "state", view: viewForPlayer(room, playerId), seq: room.log.length }));
|
||||
// The game's end unmasks the mystery machines in the roster.
|
||||
if (room.state?.phase === "finished") broadcast(room, () => roomInfo(room));
|
||||
// A refused brain-choice becomes a visible stumble, in character —
|
||||
// an idle bot turn should read as hesitation, never as nothing.
|
||||
if (step.hesitated) {
|
||||
const said = addChat(room, step.seat, HESITATION_LINES[Math.floor(Math.random() * HESITATION_LINES.length)]!);
|
||||
if (!("error" in said)) {
|
||||
broadcast(room, () => ({ type: "chat", player: step.seat, text: said.text, at: said.at }));
|
||||
}
|
||||
}
|
||||
botRemark(room, step.seat, step.events as { type: string }[]);
|
||||
setTimeout(tick, BOT_STEP_MS);
|
||||
};
|
||||
setTimeout(tick, 800); // a beat after the human's own action settles
|
||||
}
|
||||
|
||||
function broadcastRoomState(room: Room): void {
|
||||
broadcast(room, () => roomInfo(room));
|
||||
if (room.state) {
|
||||
@@ -195,14 +449,17 @@ wss.on("connection", (socket) => {
|
||||
return;
|
||||
}
|
||||
const session: Session = {
|
||||
socket, playerId: null, roomId: null, token: null, claimFails: 0,
|
||||
socket, playerId: null, roomId: null, spectator: false, token: null, claimFails: 0,
|
||||
bucket: 30, lastRefill: Date.now(), overLimitStrikes: 0,
|
||||
roomsCreated: 0, lastCatchUpAt: 0, hotseatReports: 0,
|
||||
};
|
||||
sessions.add(session);
|
||||
send(socket, { type: "welcome", game: "wizwar" });
|
||||
|
||||
socket.on("close", () => sessions.delete(session));
|
||||
socket.on("close", () => {
|
||||
sessions.delete(session);
|
||||
leaveGallery(session); // an emptier gallery is news to the table
|
||||
});
|
||||
|
||||
socket.on("message", (data) => {
|
||||
if (!underRateLimit(session)) {
|
||||
@@ -225,6 +482,7 @@ wss.on("connection", (socket) => {
|
||||
return send(socket, { type: "error", message: "no new rooms right now — try again later" });
|
||||
}
|
||||
session.roomsCreated++;
|
||||
leaveGallery(session);
|
||||
const { room, token } = createRoom(name);
|
||||
session.playerId = name;
|
||||
session.roomId = room.id;
|
||||
@@ -241,15 +499,98 @@ wss.on("connection", (socket) => {
|
||||
if (!room) return send(socket, { type: "error", message: "no such room" });
|
||||
const result = joinRoom(room, name, typeof msg.token === "string" ? msg.token : null);
|
||||
if ("error" in result) return send(socket, { type: "error", message: result.error });
|
||||
leaveGallery(session);
|
||||
session.playerId = name;
|
||||
session.roomId = room.id;
|
||||
session.token = result.token;
|
||||
send(socket, { type: "seat", playerId: name, token: result.token });
|
||||
// Rejoining a running game: replay the chronicle so far.
|
||||
// Rejoining a running game: replay the chronicle so far. The
|
||||
// replayed flag keeps one-time fanfare (the opening roll-off)
|
||||
// from firing again on every return to the room.
|
||||
if (room.state) {
|
||||
send(socket, { type: "events", events: redactFor(room.events, name) });
|
||||
send(socket, { type: "events", events: redactFor(room.events, name), replayed: true });
|
||||
}
|
||||
broadcastRoomState(room);
|
||||
runBots(room);
|
||||
break;
|
||||
}
|
||||
case "watch": {
|
||||
// The Peanut Gallery: no name, no seat, no ledger line — a pure
|
||||
// reader of the public broadcast, counted but never identified.
|
||||
const roomId = String(msg.roomId ?? "").trim().slice(0, 8);
|
||||
if (!roomId) return send(socket, { type: "error", message: "roomId required" });
|
||||
const room = getRoom(roomId);
|
||||
if (!room) return send(socket, { type: "error", message: "no such room" });
|
||||
if (audienceCount(room) >= MAX_AUDIENCE) {
|
||||
return send(socket, { type: "error", message: "the gallery is packed — try again later" });
|
||||
}
|
||||
leaveGallery(session); // switching galleries updates the old room's count
|
||||
session.playerId = null;
|
||||
session.token = null;
|
||||
session.spectator = true;
|
||||
session.roomId = room.id;
|
||||
send(socket, { type: "watching", roomId: room.id });
|
||||
send(socket, roomInfo(room));
|
||||
if (room.state) {
|
||||
send(socket, { type: "events", events: redactFor(room.events, SPECTATOR), replayed: true });
|
||||
send(socket, { type: "state", view: viewForPlayer(room, SPECTATOR), seq: room.log.length });
|
||||
}
|
||||
broadcastAudience(room);
|
||||
break;
|
||||
}
|
||||
case "leave": {
|
||||
// Walk away from the table or the gallery: the seat itself (and
|
||||
// its token) survives for a later resume; only this socket detaches.
|
||||
leaveGallery(session);
|
||||
session.playerId = null;
|
||||
session.roomId = null;
|
||||
session.token = null;
|
||||
break;
|
||||
}
|
||||
case "kickSeat": {
|
||||
const room = session.roomId ? getRoom(session.roomId) : undefined;
|
||||
if (!room || !session.playerId) return send(socket, { type: "error", message: "not in a room" });
|
||||
const kickName = String(msg.name ?? "");
|
||||
const problem = kickSeat(room, session.playerId, kickName);
|
||||
if (problem) return send(socket, { type: "error", message: problem });
|
||||
// A kicked live socket is set adrift so it cannot act on a seat it lost.
|
||||
for (const other of sessions) {
|
||||
if (other.roomId === room.id && other.playerId === kickName) {
|
||||
other.playerId = null;
|
||||
other.roomId = null;
|
||||
other.token = null;
|
||||
send(other.socket, { type: "kicked", roomId: room.id });
|
||||
}
|
||||
}
|
||||
broadcastRoomState(room);
|
||||
break;
|
||||
}
|
||||
case "abandonRoom": {
|
||||
const room = session.roomId ? getRoom(session.roomId) : undefined;
|
||||
if (!room || !session.playerId) return send(socket, { type: "error", message: "not in a room" });
|
||||
const problem = abandonRoom(room, session.playerId);
|
||||
if (problem) return send(socket, { type: "error", message: problem });
|
||||
for (const other of sessions) {
|
||||
if (other.roomId === room.id) {
|
||||
other.playerId = null;
|
||||
other.roomId = null;
|
||||
other.token = null;
|
||||
send(other.socket, { type: "roomAbandoned", roomId: room.id });
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "addBot": {
|
||||
const room = session.roomId ? getRoom(session.roomId) : undefined;
|
||||
if (!room || !session.playerId) return send(socket, { type: "error", message: "not in a room" });
|
||||
if (session.playerId !== room.hostId) return send(socket, { type: "error", message: "only the host seats automatons" });
|
||||
const result = addAutomaton(
|
||||
room,
|
||||
typeof msg.style === "string" ? msg.style : undefined,
|
||||
typeof msg.tier === "string" ? msg.tier : undefined,
|
||||
);
|
||||
if ("error" in result) return send(socket, { type: "error", message: result.error });
|
||||
broadcastRoomState(room);
|
||||
break;
|
||||
}
|
||||
case "start": {
|
||||
@@ -260,6 +601,7 @@ wss.on("connection", (socket) => {
|
||||
if ("error" in result) return send(socket, { type: "error", message: result.error });
|
||||
broadcast(room, (playerId) => ({ type: "events", events: redactFor(result.events, playerId) }));
|
||||
broadcastRoomState(room);
|
||||
runBots(room);
|
||||
break;
|
||||
}
|
||||
case "command": {
|
||||
@@ -272,6 +614,10 @@ wss.on("connection", (socket) => {
|
||||
if ("error" in result) return send(socket, { type: "error", message: result.error });
|
||||
broadcast(room, (playerId) => ({ type: "events", events: redactFor(result.events, playerId) }));
|
||||
broadcast(room, (playerId) => ({ type: "state", view: viewForPlayer(room, playerId), seq: room.log.length }));
|
||||
// The game's end unmasks the mystery machines in the roster.
|
||||
if (room.state?.phase === "finished") broadcast(room, () => roomInfo(room));
|
||||
botRemark(room, session.playerId, result.events as { type: string }[]);
|
||||
runBots(room);
|
||||
break;
|
||||
}
|
||||
case "rollDie": {
|
||||
@@ -328,6 +674,40 @@ wss.on("connection", (socket) => {
|
||||
send(socket, { type: "catchUp", steps });
|
||||
break;
|
||||
}
|
||||
case "share": {
|
||||
// Mint (or re-find) the public link for one turn's replay.
|
||||
const room = session.roomId ? getRoom(session.roomId) : undefined;
|
||||
if (!room || !session.playerId) return send(socket, { type: "error", message: "not in a room" });
|
||||
const turn = Number(msg.turn);
|
||||
if (!Number.isInteger(turn) || turn < -1) return send(socket, { type: "error", message: "no such turn" });
|
||||
const now = Date.now();
|
||||
if (now - session.lastCatchUpAt < CATCHUP_COOLDOWN_MS) {
|
||||
return send(socket, { type: "error", message: "catching up already — one moment" });
|
||||
}
|
||||
session.lastCatchUpAt = now;
|
||||
// turn -1 shares the whole finished game; anything else, one turn.
|
||||
const check = turn === -1
|
||||
? catchUpSteps(room, session.playerId, 0, true)
|
||||
: momentSteps(room, session.playerId, turn);
|
||||
if ("error" in check) return send(socket, { type: "error", message: check.error });
|
||||
const share = mintShare(room.id, turn);
|
||||
send(socket, { type: "share", id: share.id, turn });
|
||||
break;
|
||||
}
|
||||
case "moment": {
|
||||
// A chronicle line's instant-replay eye: one turn's reel.
|
||||
const room = session.roomId ? getRoom(session.roomId) : undefined;
|
||||
if (!room || !session.playerId) return send(socket, { type: "error", message: "not in a room" });
|
||||
const now = Date.now();
|
||||
if (now - session.lastCatchUpAt < CATCHUP_COOLDOWN_MS) {
|
||||
return send(socket, { type: "error", message: "catching up already — one moment" });
|
||||
}
|
||||
session.lastCatchUpAt = now;
|
||||
const reel = momentSteps(room, session.playerId, Number(msg.turn ?? -1));
|
||||
if ("error" in reel) return send(socket, { type: "error", message: reel.error });
|
||||
send(socket, { type: "moment", steps: reel.steps, owner: reel.owner });
|
||||
break;
|
||||
}
|
||||
case "pickColor": {
|
||||
const room = session.roomId ? getRoom(session.roomId) : undefined;
|
||||
if (!room || !session.playerId) return send(socket, { type: "error", message: "not in a room" });
|
||||
@@ -354,18 +734,26 @@ wss.on("connection", (socket) => {
|
||||
break;
|
||||
}
|
||||
case "myGames": {
|
||||
// {seats: [{roomId, name, token}]} -> summaries for valid seats.
|
||||
// {seats: [{roomId, name, token}]} -> summaries for valid seats,
|
||||
// plus explicit verdicts on seats PROVEN dead: the room exists
|
||||
// and refused this exact token. A room this server simply does
|
||||
// not know earns no verdict — absence is not evidence (a
|
||||
// restarting or wrong server knows nothing about anything).
|
||||
const seats = Array.isArray(msg.seats) ? msg.seats.slice(0, MAX_MYGAMES_SEATS) : [];
|
||||
const games = [];
|
||||
const voided: string[] = [];
|
||||
for (const seat of seats) {
|
||||
if (typeof seat !== "object" || seat === null) continue;
|
||||
const room = getRoom(String(seat.roomId ?? ""));
|
||||
if (!room) continue;
|
||||
const name = String(seat.name ?? "");
|
||||
if (!seatTokenValid(room, name, typeof seat.token === "string" ? seat.token : null)) continue;
|
||||
if (!seatTokenValid(room, name, typeof seat.token === "string" ? seat.token : null)) {
|
||||
voided.push(`${room.id}:${name}`);
|
||||
continue;
|
||||
}
|
||||
games.push(summarize(room, name));
|
||||
}
|
||||
send(socket, { type: "games", games });
|
||||
send(socket, { type: "games", games, voided });
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
// The share card: a 1200x630 OpenGraph image of the shared turn's maze,
|
||||
// painted from a spectator view and encoded as PNG with nothing but
|
||||
// node's own zlib — no image libraries on this small box. The unfurl
|
||||
// text carries the words; this carries the board.
|
||||
|
||||
import { deflateSync } from "node:zlib";
|
||||
import type { GameView } from "@wizwar/engine";
|
||||
|
||||
// --- Minimal PNG encoding (truecolor, filter 0) ----------------------------
|
||||
|
||||
const CRC_TABLE = new Int32Array(256);
|
||||
for (let n = 0; n < 256; n++) {
|
||||
let c = n;
|
||||
for (let k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
|
||||
CRC_TABLE[n] = c;
|
||||
}
|
||||
function crc32(buf: Uint8Array): number {
|
||||
let c = ~0;
|
||||
for (const b of buf) c = CRC_TABLE[(c ^ b) & 0xff]! ^ (c >>> 8);
|
||||
return ~c >>> 0;
|
||||
}
|
||||
function chunk(type: string, data: Uint8Array): Uint8Array {
|
||||
const out = new Uint8Array(12 + data.length);
|
||||
const dv = new DataView(out.buffer);
|
||||
dv.setUint32(0, data.length);
|
||||
for (let i = 0; i < 4; i++) out[4 + i] = type.charCodeAt(i);
|
||||
out.set(data, 8);
|
||||
dv.setUint32(8 + data.length, crc32(out.subarray(4, 8 + data.length)));
|
||||
return out;
|
||||
}
|
||||
function encodePng(width: number, height: number, rgb: Uint8Array): Buffer {
|
||||
const ihdr = new Uint8Array(13);
|
||||
const dv = new DataView(ihdr.buffer);
|
||||
dv.setUint32(0, width);
|
||||
dv.setUint32(4, height);
|
||||
ihdr[8] = 8; // bit depth
|
||||
ihdr[9] = 2; // truecolor
|
||||
const raw = new Uint8Array(height * (1 + width * 3));
|
||||
for (let y = 0; y < height; y++) {
|
||||
raw.set(rgb.subarray(y * width * 3, (y + 1) * width * 3), y * (1 + width * 3) + 1);
|
||||
}
|
||||
return Buffer.concat([
|
||||
Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]),
|
||||
chunk("IHDR", ihdr),
|
||||
chunk("IDAT", deflateSync(raw)),
|
||||
chunk("IEND", new Uint8Array(0)),
|
||||
]);
|
||||
}
|
||||
|
||||
// --- The painting ----------------------------------------------------------
|
||||
|
||||
type Rgb = [number, number, number];
|
||||
const hex = (s: string): Rgb => [
|
||||
parseInt(s.slice(1, 3), 16), parseInt(s.slice(3, 5), 16), parseInt(s.slice(5, 7), 16),
|
||||
];
|
||||
const BG = hex("#171a20");
|
||||
const CELL = hex("#e9e1cb");
|
||||
const CELL_LINE = hex("#cfc4a8");
|
||||
const WALL = hex("#43331f");
|
||||
const DOOR = hex("#a2703a");
|
||||
const FIRE = hex("#d65c1c");
|
||||
const STONE = hex("#8a8a94");
|
||||
const WARP = hex("#7a4ccc");
|
||||
const CREATURE = hex("#4a4438");
|
||||
const TREASURE = hex("#c9a72a");
|
||||
const HAZARD = hex("#7c8a4a");
|
||||
/** Standee colors, mirroring the client's PLAYER_COLORS. */
|
||||
const PLAYER: Rgb[] = [
|
||||
hex("#1a9c46"), hex("#d3352b"), hex("#c9308f"),
|
||||
hex("#3a3ac0"), hex("#2ab0c9"), hex("#c9a72a"),
|
||||
];
|
||||
|
||||
export function renderSharePng(view: GameView): Buffer {
|
||||
const W = 1200, H = 630;
|
||||
const img = new Uint8Array(W * H * 3);
|
||||
const rect = (x: number, y: number, w: number, h: number, c: Rgb) => {
|
||||
const x0 = Math.max(0, Math.round(x)), y0 = Math.max(0, Math.round(y));
|
||||
const x1 = Math.min(W, Math.round(x + w)), y1 = Math.min(H, Math.round(y + h));
|
||||
for (let yy = y0; yy < y1; yy++) {
|
||||
let o = (yy * W + x0) * 3;
|
||||
for (let xx = x0; xx < x1; xx++) {
|
||||
img[o] = c[0]; img[o + 1] = c[1]; img[o + 2] = c[2];
|
||||
o += 3;
|
||||
}
|
||||
}
|
||||
};
|
||||
const disc = (cx: number, cy: number, r: number, c: Rgb) => {
|
||||
for (let yy = Math.round(cy - r); yy <= cy + r; yy++) {
|
||||
for (let xx = Math.round(cx - r); xx <= cx + r; xx++) {
|
||||
if (xx < 0 || yy < 0 || xx >= W || yy >= H) continue;
|
||||
if ((xx - cx) ** 2 + (yy - cy) ** 2 > r * r) continue;
|
||||
const o = (yy * W + xx) * 3;
|
||||
img[o] = c[0]; img[o + 1] = c[1]; img[o + 2] = c[2];
|
||||
}
|
||||
}
|
||||
};
|
||||
rect(0, 0, W, H, BG);
|
||||
|
||||
const bw = view.board.width, bh = view.board.height;
|
||||
const cell = Math.floor(Math.min((W - 120) / bw, (H - 80) / bh));
|
||||
const ox = Math.round((W - bw * cell) / 2);
|
||||
const oy = Math.round((H - bh * cell) / 2);
|
||||
const px = (cx: number, cy: number) => [ox + cx * cell, oy + cy * cell] as const;
|
||||
const line = Math.max(3, Math.round(cell * 0.1));
|
||||
|
||||
// The rooms of the maze.
|
||||
const has = (cx: number, cy: number) => !!view.board.cells[`${cx},${cy}`];
|
||||
for (const k of Object.keys(view.board.cells)) {
|
||||
const [cx, cy] = k.split(",").map(Number) as [number, number];
|
||||
const [x, y] = px(cx, cy);
|
||||
rect(x, y, cell, cell, CELL);
|
||||
rect(x, y, cell, 1, CELL_LINE);
|
||||
rect(x, y, 1, cell, CELL_LINE);
|
||||
}
|
||||
|
||||
// Home bases wear their owner's color as a floor border.
|
||||
for (const p of view.players) {
|
||||
if (!p.home) continue;
|
||||
const [x, y] = px(p.home.x, p.home.y);
|
||||
const c = PLAYER[p.colorIndex] ?? WALL;
|
||||
const t = Math.max(2, Math.round(cell * 0.08));
|
||||
rect(x + 2, y + 2, cell - 4, t, c);
|
||||
rect(x + 2, y + cell - 2 - t, cell - 4, t, c);
|
||||
rect(x + 2, y + 2, t, cell - 4, c);
|
||||
rect(x + cell - 2 - t, y + 2, t, cell - 4, c);
|
||||
}
|
||||
|
||||
// The floor's furniture: filled stone reads solid; other hazards dot.
|
||||
for (const [k, content] of Object.entries(view.squareContents)) {
|
||||
const [cx, cy] = k.split(",").map(Number) as [number, number];
|
||||
const [x, y] = px(cx, cy);
|
||||
if (content.kind === "stone") rect(x + 1, y + 1, cell - 2, cell - 2, STONE);
|
||||
else disc(x + cell / 2, y + cell / 2, cell * 0.16, HAZARD);
|
||||
}
|
||||
|
||||
// Interior walls, doors, and fire, on their edges.
|
||||
for (const [k, e] of Object.entries(view.board.edges)) {
|
||||
if (e === "open") continue;
|
||||
const [kind, coords] = k.split(":") as [string, string];
|
||||
const [ex, ey] = coords.split(",").map(Number) as [number, number];
|
||||
const c = e === "door" ? DOOR : e === "firewall" ? FIRE : WALL;
|
||||
if (kind === "V") {
|
||||
const [x, y] = px(ex + 1, ey);
|
||||
rect(x - line / 2, y, line, cell, c);
|
||||
} else {
|
||||
const [x, y] = px(ex, ey + 1);
|
||||
rect(x, y - line / 2, cell, line, c);
|
||||
}
|
||||
}
|
||||
|
||||
// The rim: every open side facing nothing is a wall, except warp mouths.
|
||||
const mouth = new Set(view.board.warps.map((w) => `${w.from.cell.x},${w.from.cell.y}:${w.from.side}`));
|
||||
for (const k of Object.keys(view.board.cells)) {
|
||||
const [cx, cy] = k.split(",").map(Number) as [number, number];
|
||||
const [x, y] = px(cx, cy);
|
||||
const side = (missing: boolean, sx: number, sy: number, w: number, h: number, s: string) => {
|
||||
if (!missing) return;
|
||||
rect(sx, sy, w, h, mouth.has(`${cx},${cy}:${s}`) ? WARP : WALL);
|
||||
};
|
||||
side(!has(cx + 1, cy), x + cell - line / 2, y, line, cell, "E");
|
||||
side(!has(cx - 1, cy), x - line / 2, y, line, cell, "W");
|
||||
side(!has(cx, cy + 1), x, y + cell - line / 2, cell, line, "S");
|
||||
side(!has(cx, cy - 1), x, y - line / 2, cell, line, "N");
|
||||
}
|
||||
|
||||
// Loose treasures glint gold.
|
||||
for (const t of view.treasures) {
|
||||
if (!t.position || t.carriedBy) continue;
|
||||
const [x, y] = px(t.position.x, t.position.y);
|
||||
rect(x + cell * 0.6, y + cell * 0.6, cell * 0.25, cell * 0.25, TREASURE);
|
||||
}
|
||||
|
||||
// Creatures crouch dark; wizards stand in their colors.
|
||||
for (const c of view.creatures) {
|
||||
const [x, y] = px(c.position.x, c.position.y);
|
||||
disc(x + cell * 0.3, y + cell * 0.68, cell * 0.18, CREATURE);
|
||||
}
|
||||
const standing = new Map<string, number>();
|
||||
for (const p of view.players) {
|
||||
if (!p.alive) continue;
|
||||
const key = `${p.position.x},${p.position.y}`;
|
||||
const n = standing.get(key) ?? 0;
|
||||
standing.set(key, n + 1);
|
||||
const [x, y] = px(p.position.x, p.position.y);
|
||||
const cx = x + cell / 2 + (n - 0.5) * cell * 0.16;
|
||||
disc(cx, y + cell * 0.42, cell * 0.26, PLAYER[p.colorIndex] ?? WALL);
|
||||
disc(cx, y + cell * 0.42, cell * 0.26 - 2, PLAYER[p.colorIndex] ?? WALL);
|
||||
}
|
||||
|
||||
return encodePng(W, H, img);
|
||||
}
|
||||
@@ -6,16 +6,23 @@
|
||||
import { createHash, randomBytes, randomInt, timingSafeEqual } from "node:crypto";
|
||||
import {
|
||||
applyCommand,
|
||||
automatonCommand,
|
||||
automatonFallback,
|
||||
AUTOMATON_STYLES,
|
||||
AUTOMATON_TIERS,
|
||||
createGame,
|
||||
redactEvent,
|
||||
viewFor,
|
||||
type AutomatonStyle,
|
||||
type AutomatonTier,
|
||||
type Command,
|
||||
type GameEvent,
|
||||
type GameState,
|
||||
type GameView,
|
||||
type PlayerId,
|
||||
CURRENT_RULES_REV,
|
||||
} from "@wizwar/engine";
|
||||
import { appendLine, ensureDataDir, readAllRooms, roomFileExists, type RoomLine } from "./store";
|
||||
import { appendLine, archiveRoomFile, ensureDataDir, readAllRooms, roomFileExists, type RoomLine } from "./store";
|
||||
import { recordRoom } from "./stats";
|
||||
|
||||
export interface LoggedCommand {
|
||||
@@ -41,13 +48,12 @@ export interface Room {
|
||||
events: GameEvent[]; // full history (unredacted — redact per recipient)
|
||||
/** Table talk, persisted with the room (public to all seats). */
|
||||
chat: { player: PlayerId; text: string; at: string }[];
|
||||
/** Seats the server itself plays: temperament, tier, and secrecy. */
|
||||
bots: Map<PlayerId, { style: AutomatonStyle; secret: boolean; tier: AutomatonTier }>;
|
||||
}
|
||||
|
||||
const rooms = new Map<string, Room>();
|
||||
|
||||
/** Rules revision new games are dealt under (stored games keep their own). */
|
||||
const RULES_REV = 8;
|
||||
|
||||
const ROOM_CODE_ALPHABET = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
|
||||
|
||||
/** Tokens live hashed at rest (memory and disk); clients hold the raw form. */
|
||||
@@ -83,6 +89,11 @@ export function roomCount(): number {
|
||||
return rooms.size;
|
||||
}
|
||||
|
||||
/** Every restored, still-running room — so boot can wake their bot pumps. */
|
||||
export function runningRooms(): Room[] {
|
||||
return [...rooms.values()].filter((r) => r.state && r.state.phase === "playing");
|
||||
}
|
||||
|
||||
export function createRoom(hostId: PlayerId): { room: Room; token: string } {
|
||||
const token = randomBytes(16).toString("hex");
|
||||
const room: Room = {
|
||||
@@ -98,6 +109,7 @@ export function createRoom(hostId: PlayerId): { room: Room; token: string } {
|
||||
log: [],
|
||||
events: [],
|
||||
chat: [],
|
||||
bots: new Map(),
|
||||
};
|
||||
rooms.set(room.id, room);
|
||||
recordRoom(room);
|
||||
@@ -136,6 +148,33 @@ export function joinRoom(
|
||||
return { token: fresh };
|
||||
}
|
||||
|
||||
/** The host shows an unclaimed (or unwanted) seat the door — lobby only:
|
||||
* once the deal happens, every seat is a player in the game's record. */
|
||||
export function kickSeat(room: Room, byId: PlayerId, name: PlayerId): string | null {
|
||||
if (byId !== room.hostId) return "only the host may clear a seat";
|
||||
if (room.state) return "the game has started — seats are settled";
|
||||
if (name === room.hostId) return "the host cannot kick themselves — abandon the room instead";
|
||||
if (!room.players.includes(name)) return "no such seat";
|
||||
room.players = room.players.filter((p) => p !== name);
|
||||
room.tokens.delete(name);
|
||||
room.bots.delete(name);
|
||||
room.colorChoices.delete(name);
|
||||
appendLine(room.id, { kind: "kick", name, at: new Date().toISOString() });
|
||||
recordRoom(room);
|
||||
return null;
|
||||
}
|
||||
|
||||
/** The host dissolves the room: a lobby that never dealt, or a finished
|
||||
* game done being remembered. The ledger is archived, never deleted. */
|
||||
export function abandonRoom(room: Room, byId: PlayerId): string | null {
|
||||
if (byId !== room.hostId) return "only the host may abandon the room";
|
||||
if (room.state && room.state.phase === "playing") return "the game is still being played";
|
||||
appendLine(room.id, { kind: "abandon", by: byId, at: new Date().toISOString() });
|
||||
archiveRoomFile(room.id);
|
||||
rooms.delete(room.id);
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Everyone gets their chosen standee; the undecided get the first free one. */
|
||||
export function resolveColors(room: Room): number[] {
|
||||
const taken = new Set<number>();
|
||||
@@ -184,9 +223,9 @@ function startInMemory(room: Room, expansion: boolean, colors?: number[], deckRe
|
||||
export function startGame(room: Room, expansion: boolean): { events: GameEvent[] } | { error: string } {
|
||||
if (room.state) return { error: "already started" };
|
||||
const colors = resolveColors(room);
|
||||
const result = startInMemory(room, expansion, colors, RULES_REV);
|
||||
const result = startInMemory(room, expansion, colors, CURRENT_RULES_REV);
|
||||
if ("error" in result) return result;
|
||||
appendLine(room.id, { kind: "start", expansion, colors, deckRev: RULES_REV });
|
||||
appendLine(room.id, { kind: "start", expansion, colors, deckRev: CURRENT_RULES_REV });
|
||||
recordRoom(room);
|
||||
return result;
|
||||
}
|
||||
@@ -230,6 +269,82 @@ export function addChat(room: Room, playerId: PlayerId, rawText: string): { text
|
||||
return { text, at };
|
||||
}
|
||||
|
||||
const AUTOMATON_NAMES = ["Automaton", "Automaton II", "Automaton III", "Automaton IV", "Automaton V"];
|
||||
|
||||
/** Seat a clockwork wizard (host's choice, before the game starts). */
|
||||
export function addAutomaton(
|
||||
room: Room,
|
||||
styleWanted?: string,
|
||||
tierWanted?: string,
|
||||
): { name: PlayerId } | { error: string } {
|
||||
if (room.state) return { error: "the game has started" };
|
||||
if (room.players.length >= 6) return { error: "room is full" };
|
||||
const name = AUTOMATON_NAMES.find((n) => !room.players.includes(n));
|
||||
if (!name) return { error: "the workshop is empty" };
|
||||
const known = AUTOMATON_STYLES.includes(styleWanted as AutomatonStyle);
|
||||
const style: AutomatonStyle = known
|
||||
? (styleWanted as AutomatonStyle)
|
||||
: AUTOMATON_STYLES[randomInt(AUTOMATON_STYLES.length)]!;
|
||||
const secret = !known; // the mystery machine keeps its mood to itself
|
||||
const tier: AutomatonTier = AUTOMATON_TIERS.includes(tierWanted as AutomatonTier)
|
||||
? (tierWanted as AutomatonTier)
|
||||
: "adept";
|
||||
room.players.push(name);
|
||||
room.bots.set(name, { style, secret, tier });
|
||||
appendLine(room.id, { kind: "join", name, bot: true, style, tier, ...(secret ? { secret: true } : {}) });
|
||||
return { name };
|
||||
}
|
||||
|
||||
/** Whose input does the maze want right now? */
|
||||
function actingSeat(room: Room): PlayerId | null {
|
||||
const s = room.state;
|
||||
if (!s || s.phase !== "playing") return null;
|
||||
return (
|
||||
s.wardPending?.ownerId ??
|
||||
s.stack?.waitingOn ??
|
||||
s.pendingDiscard ??
|
||||
s.chaosPending?.queue[0] ??
|
||||
s.outOfTurnWindow?.playerId ??
|
||||
s.players[s.turn.activeIndex]!.id
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* One automaton command, if the maze is waiting on clockwork. Null when a
|
||||
* human holds the floor (or the game is over, or the clockwork is wedged).
|
||||
*/
|
||||
export function driveOneAutomaton(
|
||||
room: Room,
|
||||
): { seat: PlayerId; events: GameEvent[]; hesitated?: true } | null {
|
||||
const seat = actingSeat(room);
|
||||
if (!seat || !room.bots.has(seat)) return null;
|
||||
const view = viewFor(room.state!, seat);
|
||||
const bot = room.bots.get(seat);
|
||||
const chosen = automatonCommand(view, bot?.style, bot?.tier);
|
||||
let hesitated: true | undefined;
|
||||
let r = runCommand(room, seat, chosen ?? automatonFallback(view, bot?.tier));
|
||||
if ("error" in r) {
|
||||
// A refused choice retries with the fallback — unless the fallback IS
|
||||
// what just failed — then burns down the ladder to endTurn and pass.
|
||||
// The refusal is remembered: a brain whose choice the engine rejects
|
||||
// is a bug in the brain, and the table deserves to see the stumble
|
||||
// rather than an unexplained idle turn.
|
||||
if (chosen) {
|
||||
hesitated = true;
|
||||
console.warn(
|
||||
`automaton ${seat} hesitated in ${room.id}: ${JSON.stringify(chosen)} refused (${r.error})`);
|
||||
r = runCommand(room, seat, automatonFallback(view, bot?.tier));
|
||||
}
|
||||
if ("error" in r) r = runCommand(room, seat, { type: "endTurn", draw: 0 });
|
||||
if ("error" in r) r = runCommand(room, seat, { type: "pass" });
|
||||
if ("error" in r) {
|
||||
console.error(`automaton ${seat} wedged in ${room.id}: ${r.error}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return { seat, events: r.events, ...(hesitated ? { hesitated } : {}) };
|
||||
}
|
||||
|
||||
export interface GameSummary {
|
||||
roomId: string;
|
||||
name: PlayerId;
|
||||
@@ -282,6 +397,12 @@ export function viewForPlayer(room: Room, playerId: PlayerId): GameView | null {
|
||||
return room.state ? viewFor(room.state, playerId) : null;
|
||||
}
|
||||
|
||||
/** The Peanut Gallery's viewer id: the empty name can never hold a seat
|
||||
* (joins reject blank names), so a view built for it shows public knowledge
|
||||
* only — no hand, no ward, no ambushes, no boobytrap truths — and event
|
||||
* redaction drops everything marked visibleTo a player. */
|
||||
export const SPECTATOR: PlayerId = "";
|
||||
|
||||
export interface CatchUpStep {
|
||||
seq: number;
|
||||
actor: PlayerId;
|
||||
@@ -297,7 +418,10 @@ export interface CatchUpStep {
|
||||
*/
|
||||
export function catchUpSteps(room: Room, playerId: PlayerId, sinceSeq: number, full = false): CatchUpStep[] | { error: string } {
|
||||
if (!room.state) return { error: "game not started" };
|
||||
if (!room.players.includes(playerId)) return { error: "you hold no seat in this room" };
|
||||
// The SPECTATOR builds whole-game share pages: public knowledge, no seat.
|
||||
if (playerId !== SPECTATOR && !room.players.includes(playerId)) {
|
||||
return { error: "you hold no seat in this room" };
|
||||
}
|
||||
if (full && room.state.phase !== "finished") return { error: "full replays wait for the game to finish" };
|
||||
const MAX_STEPS = 200;
|
||||
const from = full ? 0 : Math.max(sinceSeq, room.log.length - MAX_STEPS);
|
||||
@@ -329,6 +453,87 @@ export function redactFor(events: GameEvent[], playerId: PlayerId): GameEvent[]
|
||||
return events.map((e) => redactEvent(e, playerId)).filter((e): e is GameEvent => e !== null);
|
||||
}
|
||||
|
||||
/** The events that begin a turn — the client's chronicle counts these
|
||||
* identically, so a turn number names the same stretch on both ends. */
|
||||
const TURN_BOUNDARY = new Set(["turnStarted", "extraTurnStarted", "turnSkipped"]);
|
||||
|
||||
export interface MomentReel {
|
||||
steps: CatchUpStep[];
|
||||
/** The wizard whose turn this is — the reel's eyes. */
|
||||
owner: PlayerId;
|
||||
round: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* One turn's reel: every command whose events touch turn `turnIndex`
|
||||
* (0-counted across boundary events). A command that ends one turn and
|
||||
* starts the next belongs to both, so a reel opens with the blow that
|
||||
* began it and closes on the handover. The owner comes from the very
|
||||
* boundary that opened the turn — which for turn 0 lives in the DEAL,
|
||||
* before any command, so no scan of the steps could find it.
|
||||
*/
|
||||
export function momentSteps(room: Room, playerId: PlayerId, turnIndex: number): MomentReel | { error: string } {
|
||||
if (!room.state) return { error: "game not started" };
|
||||
// The SPECTATOR builds share pages: public knowledge only, no seat.
|
||||
if (playerId !== SPECTATOR && !room.players.includes(playerId)) {
|
||||
return { error: "you hold no seat in this room" };
|
||||
}
|
||||
const MAX_STEPS = 80;
|
||||
const { state: fresh, events: dealt } = createGame(room.state.config);
|
||||
let current = fresh;
|
||||
// The deal's own events open the first turn — count them so turn
|
||||
// numbers match the client chronicle's.
|
||||
let counter = -1;
|
||||
let owner: PlayerId | null = null;
|
||||
let round = 0;
|
||||
const bump = (e: GameEvent) => {
|
||||
if (!TURN_BOUNDARY.has(e.type)) return;
|
||||
counter++;
|
||||
if (counter === turnIndex && owner === null && "player" in e) {
|
||||
owner = (e as { player: PlayerId }).player;
|
||||
if ("round" in e) round = (e as { round: number }).round;
|
||||
}
|
||||
};
|
||||
for (const e of dealt) bump(e);
|
||||
const steps: CatchUpStep[] = [];
|
||||
for (const entry of room.log) {
|
||||
const result = applyCommand(current, entry.playerId, entry.command);
|
||||
if (!result.ok) return { error: `replay diverged at seq ${entry.seq}` };
|
||||
current = result.state;
|
||||
const before = counter;
|
||||
// The straddle commands hold more than this turn: the opener carries
|
||||
// the previous wizard's last breaths, the closer the NEXT wizard's
|
||||
// first. Trim both so the reel is exactly one turn — it opens on
|
||||
// "X's turn begins" and stops at X's turnEnded.
|
||||
let sliceStart = 0;
|
||||
let sliceEnd = result.events.length;
|
||||
result.events.forEach((e, i) => {
|
||||
if (!TURN_BOUNDARY.has(e.type)) return;
|
||||
bump(e);
|
||||
if (counter === turnIndex && before < turnIndex) sliceStart = i;
|
||||
if (counter === turnIndex + 1 && sliceEnd === result.events.length) sliceEnd = i;
|
||||
});
|
||||
if (before > turnIndex) break;
|
||||
if (before <= turnIndex && turnIndex <= counter) {
|
||||
const kept = result.events.slice(sliceStart, sliceEnd);
|
||||
const prevAt = entry.seq > 0 ? room.log[entry.seq - 1]!.at : "";
|
||||
const said = room.chat
|
||||
.filter((c) => c.at > prevAt && c.at <= entry.at)
|
||||
.map((c) => ({ player: c.player, text: c.text }));
|
||||
steps.push({
|
||||
seq: entry.seq,
|
||||
actor: entry.playerId,
|
||||
events: redactFor(kept, playerId),
|
||||
view: viewFor(current, playerId),
|
||||
...(said.length > 0 ? { chat: said } : {}),
|
||||
});
|
||||
if (steps.length >= MAX_STEPS) break;
|
||||
}
|
||||
}
|
||||
if (steps.length === 0) return { error: "no such turn yet" };
|
||||
return { steps, owner: owner ?? steps[steps.length - 1]!.actor, round };
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Seat transfers: a spoken-word one-time code hands a seat to another device.
|
||||
// Ephemeral by design — a server restart voids pending codes, never seats.
|
||||
@@ -427,13 +632,31 @@ export function loadPersistedRooms(): void {
|
||||
log: [],
|
||||
events: [],
|
||||
chat: [],
|
||||
bots: new Map(),
|
||||
};
|
||||
if (lines.some((l) => l.kind === "abandon")) continue;
|
||||
for (const line of lines.slice(1)) {
|
||||
if (line.kind === "join") {
|
||||
if (line.kind === "kick") {
|
||||
room.players = room.players.filter((p) => p !== line.name);
|
||||
room.tokens.delete(line.name);
|
||||
room.bots.delete(line.name);
|
||||
room.colorChoices.delete(line.name);
|
||||
} else if (line.kind === "join") {
|
||||
if (line.bot) {
|
||||
room.players.push(line.name);
|
||||
room.bots.set(line.name, {
|
||||
style: (line.style as AutomatonStyle) ?? "hunter",
|
||||
secret: line.secret === true,
|
||||
// Tier-less join lines predate tiers, when every automaton
|
||||
// played the full repertoire — not the "adept" lobby default.
|
||||
tier: (line.tier as AutomatonTier) ?? "archmage",
|
||||
});
|
||||
} else {
|
||||
const joinHash = line.tokenHash ?? (line.token ? hashToken(line.token) : null);
|
||||
if (!joinHash) throw new Error("join line has no token");
|
||||
room.players.push(line.name);
|
||||
room.tokens.set(line.name, joinHash);
|
||||
}
|
||||
} else if (line.kind === "start") {
|
||||
const r = startInMemory(room, line.expansion, line.colors, line.deckRev);
|
||||
if ("error" in r) throw new Error(`replay start failed: ${r.error}`);
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// Share links: a minted slug names one turn of one game, and anyone
|
||||
// holding it may watch that turn — spectator-redacted, nothing else of
|
||||
// the game visible. Shares persist beside the rooms and survive restarts.
|
||||
|
||||
import { appendFileSync, existsSync, readFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { randomInt } from "node:crypto";
|
||||
import { statsDir } from "./store";
|
||||
|
||||
export interface Share {
|
||||
id: string;
|
||||
roomId: string;
|
||||
turn: number;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
const SHARE_ALPHABET = "abcdefghjkmnpqrstuvwxyz23456789";
|
||||
const SHARE_ID_LENGTH = 10; // 31^10 ≈ 8×10^14 — unguessable, typeable
|
||||
|
||||
const shares = new Map<string, Share>();
|
||||
|
||||
function sharesFile(): string {
|
||||
return join(statsDir(), "shares.jsonl");
|
||||
}
|
||||
|
||||
export function loadShares(): void {
|
||||
const file = sharesFile();
|
||||
if (!existsSync(file)) return;
|
||||
for (const line of readFileSync(file, "utf8").trim().split("\n")) {
|
||||
if (!line) continue;
|
||||
try {
|
||||
const s = JSON.parse(line) as Share;
|
||||
if (s.id) shares.set(s.id, s);
|
||||
} catch {
|
||||
// A torn tail line loses one share, never the server.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function mintShare(roomId: string, turn: number): Share {
|
||||
// One link per (room, turn): sharing the same turn twice hands back
|
||||
// the same slug, so a re-share never splits an audience.
|
||||
for (const s of shares.values()) {
|
||||
if (s.roomId === roomId && s.turn === turn) return s;
|
||||
}
|
||||
let id = "";
|
||||
for (let i = 0; i < SHARE_ID_LENGTH; i++) {
|
||||
id += SHARE_ALPHABET[randomInt(SHARE_ALPHABET.length)];
|
||||
}
|
||||
const share: Share = { id, roomId, turn, createdAt: new Date().toISOString() };
|
||||
shares.set(id, share);
|
||||
appendFileSync(sharesFile(), JSON.stringify(share) + "\n", "utf8");
|
||||
return share;
|
||||
}
|
||||
|
||||
export function getShare(id: string): Share | undefined {
|
||||
return shares.get(id);
|
||||
}
|
||||
@@ -24,6 +24,8 @@ export interface EngagementStats {
|
||||
firstGameAt: string | null;
|
||||
/** How many of the games were hotseat tables reporting in anonymously. */
|
||||
hotseatGames: number;
|
||||
/** Games with at least one clockwork wizard at the table. */
|
||||
automatonGames: number;
|
||||
}
|
||||
|
||||
interface StatsFile extends Omit<EngagementStats, "wizardsSeated"> {
|
||||
@@ -40,7 +42,7 @@ let data: StatsFile = {
|
||||
commandsPlayed: 0, minutesAtTable: 0,
|
||||
winsByTreasure: 0, winsByLastStanding: 0,
|
||||
longestGameCommands: 0, fullestTable: 0, firstGameAt: null,
|
||||
hotseatGames: 0, wizards: [], roomStages: {},
|
||||
hotseatGames: 0, automatonGames: 0, wizards: [], roomStages: {},
|
||||
};
|
||||
let wizardSet = new Set<string>();
|
||||
let loaded = false;
|
||||
@@ -84,6 +86,7 @@ export function recordRoom(room: Room): void {
|
||||
const stage = data.roomStages[room.id];
|
||||
|
||||
for (const p of room.players) {
|
||||
if (room.bots.has(p)) continue; // the clockwork are not wizards seated
|
||||
const key = p.toLowerCase();
|
||||
if (!wizardSet.has(key)) { wizardSet.add(key); dirty = true; }
|
||||
}
|
||||
@@ -95,6 +98,7 @@ export function recordRoom(room: Room): void {
|
||||
}
|
||||
if (room.state && data.roomStages[room.id] === "created") {
|
||||
data.gamesStarted++;
|
||||
if (room.bots.size > 0) data.automatonGames++;
|
||||
data.fullestTable = Math.max(data.fullestTable, room.players.length);
|
||||
data.roomStages[room.id] = "started";
|
||||
dirty = true;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// command. Because the engine is deterministic, replaying a file rebuilds
|
||||
// the exact game state — server restarts lose nothing.
|
||||
|
||||
import { appendFileSync, existsSync, mkdirSync, readdirSync, readFileSync } from "node:fs";
|
||||
import { appendFileSync, existsSync, mkdirSync, readdirSync, readFileSync, renameSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
|
||||
export interface RoomMetaLine {
|
||||
@@ -24,6 +24,14 @@ export interface JoinLine {
|
||||
tokenHash?: string;
|
||||
/** Legacy plaintext token (pre-hashing files only). */
|
||||
token?: string;
|
||||
/** An automaton seat: no token; the server plays it. */
|
||||
bot?: true;
|
||||
/** The automaton's temperament. */
|
||||
style?: string;
|
||||
/** The automaton's difficulty tier. */
|
||||
tier?: string;
|
||||
/** A mystery machine: the temperament is not revealed to the table. */
|
||||
secret?: true;
|
||||
}
|
||||
|
||||
export interface StartLine {
|
||||
@@ -50,7 +58,20 @@ export interface ChatLine {
|
||||
at: string;
|
||||
}
|
||||
|
||||
export type RoomLine = RoomMetaLine | JoinLine | StartLine | CommandLine | ChatLine;
|
||||
export interface KickLine {
|
||||
kind: "kick";
|
||||
/** The seat the host removed from an unstarted room. */
|
||||
name: string;
|
||||
at: string;
|
||||
}
|
||||
|
||||
export interface AbandonLine {
|
||||
kind: "abandon";
|
||||
by: string;
|
||||
at: string;
|
||||
}
|
||||
|
||||
export type RoomLine = RoomMetaLine | JoinLine | StartLine | CommandLine | ChatLine | KickLine | AbandonLine;
|
||||
|
||||
const DATA_DIR = process.env.WIZWAR_DATA_DIR ?? join(process.cwd(), "data", "rooms");
|
||||
|
||||
@@ -95,3 +116,13 @@ export function readAllRooms(): Map<string, RoomLine[]> {
|
||||
}
|
||||
return rooms;
|
||||
}
|
||||
|
||||
/** Retire an abandoned room's ledger to the graveyard — never deleted,
|
||||
* only moved out of the living rooms directory. */
|
||||
export function archiveRoomFile(roomId: string): void {
|
||||
const src = fileFor(roomId);
|
||||
if (!existsSync(src)) return;
|
||||
const graveyard = join(DATA_DIR, "..", "rooms-abandoned");
|
||||
mkdirSync(graveyard, { recursive: true });
|
||||
renameSync(src, join(graveyard, `${roomId}.${Date.now()}.jsonl`));
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 81 KiB |
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 237 KiB |
|
After Width: | Height: | Size: 108 KiB |
|
After Width: | Height: | Size: 169 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 77 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 85 KiB |
|
After Width: | Height: | Size: 89 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 74 KiB |
|
After Width: | Height: | Size: 73 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 123 KiB |
|
After Width: | Height: | Size: 73 KiB |
|
After Width: | Height: | Size: 111 KiB |
@@ -0,0 +1,12 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 144 150" role="img" aria-label="Alter Ego token">
|
||||
<defs>
|
||||
<filter id="w"><feTurbulence baseFrequency=".035" numOctaves="2" seed="4" result="n"/><feDisplacementMap in="SourceGraphic" in2="n" scale=".65"/></filter>
|
||||
<filter id="s"><feGaussianBlur stdDeviation="2"/></filter>
|
||||
<pattern id="paper" width="12" height="12" patternUnits="userSpaceOnUse"><rect width="12" height="12" fill="#f4efd9"/><circle cx="2" cy="4" r=".45" fill="#c8bfa4" opacity=".28"/><path d="M1 10l7-1" stroke="#d8cfb8" stroke-width=".35" opacity=".35"/></pattern>
|
||||
</defs>
|
||||
<rect x="2" y="2" width="140" height="146" rx="3" fill="url(#paper)" stroke="#242822" stroke-width="2"/>
|
||||
<text x="72" y="19" text-anchor="middle" font-family="Trebuchet MS,Arial,sans-serif" font-weight="700" font-size="14" fill="#20251f">Alter Ego</text>
|
||||
<g filter="url(#w)" stroke="#252923" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M35 52 Q65 40 80 66 Q86 88 67 105 Q45 111 31 90Z" fill="#e7c3a1"/>
|
||||
<path d="M40 73q9 -10 19 0M62 70q8 -7 15 1" fill="none"/><circle cx="53" cy="75" r="2.4" fill="#20251f" stroke="none"/><path d="M64 78q-8 8 3 11q-9 9 -19 2" fill="none"/><path d="M111 52 Q81 40 66 66 Q60 88 79 105 Q101 111 115 90Z" fill="#d9b08e"/>
|
||||
<path d="M106 73q9 -10 19 0M84 70q8 -7 15 1" fill="none"/><circle cx="93" cy="75" r="2.4" fill="#20251f" stroke="none"/><path d="M82 78q8 8 3 11q9 9 19 2" fill="none"/><path d="M69 48q4-12 8 0M47 115q25-14 51 0" fill="none"/><path d="M24 67l-10-6m108 5l9-8" fill="none"/></g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 144 150" role="img" aria-label="Boobytrap token">
|
||||
<defs>
|
||||
<filter id="w"><feTurbulence baseFrequency=".035" numOctaves="2" seed="4" result="n"/><feDisplacementMap in="SourceGraphic" in2="n" scale=".65"/></filter>
|
||||
<filter id="s"><feGaussianBlur stdDeviation="2"/></filter>
|
||||
<pattern id="paper" width="12" height="12" patternUnits="userSpaceOnUse"><rect width="12" height="12" fill="#f4efd9"/><circle cx="2" cy="4" r=".45" fill="#c8bfa4" opacity=".28"/><path d="M1 10l7-1" stroke="#d8cfb8" stroke-width=".35" opacity=".35"/></pattern>
|
||||
</defs>
|
||||
<rect x="2" y="2" width="140" height="146" rx="3" fill="url(#paper)" stroke="#242822" stroke-width="2"/>
|
||||
<text x="72" y="19" text-anchor="middle" font-family="Trebuchet MS,Arial,sans-serif" font-weight="700" font-size="14" fill="#20251f">Boobytrap</text>
|
||||
<g filter="url(#w)" stroke="#252923" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M28 105L70 49l43 56Z" fill="#f2ca4f"/><path d="M44 96l26-35 25 35Z" fill="#df5b36"/><path d="M71 70v14m0 7v2" stroke="#fff8da" stroke-width="5"/><path d="M25 62l12 5-9 8m92-11l-11 4 8 9" fill="none"/></g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 144 150" role="img" aria-label="Dagger token">
|
||||
<defs>
|
||||
<filter id="w"><feTurbulence baseFrequency=".035" numOctaves="2" seed="4" result="n"/><feDisplacementMap in="SourceGraphic" in2="n" scale=".65"/></filter>
|
||||
<filter id="s"><feGaussianBlur stdDeviation="2"/></filter>
|
||||
<pattern id="paper" width="12" height="12" patternUnits="userSpaceOnUse"><rect width="12" height="12" fill="#f4efd9"/><circle cx="2" cy="4" r=".45" fill="#c8bfa4" opacity=".28"/><path d="M1 10l7-1" stroke="#d8cfb8" stroke-width=".35" opacity=".35"/></pattern>
|
||||
</defs>
|
||||
<rect x="2" y="2" width="140" height="146" rx="3" fill="url(#paper)" stroke="#242822" stroke-width="2"/>
|
||||
<text x="72" y="19" text-anchor="middle" font-family="Trebuchet MS,Arial,sans-serif" font-weight="700" font-size="14" fill="#20251f">Dagger</text>
|
||||
<g filter="url(#w)" stroke="#252923" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M34 111L90 48l12 12-57 60Z" fill="#c9d5d2"/><path d="M87 51l10-13 13 13-10 10Z" fill="#6c5641"/><path d="M75 58l22 22"/><path d="M30 70l-13-5 10-8m82 36l15 3-9 9" fill="none"/></g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 144 150" role="img" aria-label="Democratic Monster token">
|
||||
<defs>
|
||||
<filter id="w"><feTurbulence baseFrequency=".035" numOctaves="2" seed="4" result="n"/><feDisplacementMap in="SourceGraphic" in2="n" scale=".65"/></filter>
|
||||
<filter id="s"><feGaussianBlur stdDeviation="2"/></filter>
|
||||
<pattern id="paper" width="12" height="12" patternUnits="userSpaceOnUse"><rect width="12" height="12" fill="#f4efd9"/><circle cx="2" cy="4" r=".45" fill="#c8bfa4" opacity=".28"/><path d="M1 10l7-1" stroke="#d8cfb8" stroke-width=".35" opacity=".35"/></pattern>
|
||||
</defs>
|
||||
<rect x="2" y="2" width="140" height="146" rx="3" fill="url(#paper)" stroke="#242822" stroke-width="2"/>
|
||||
<text x="72" y="19" text-anchor="middle" font-family="Trebuchet MS,Arial,sans-serif" font-weight="700" font-size="12" fill="#20251f">Democratic Monster</text>
|
||||
<g filter="url(#w)" stroke="#252923" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M71 120Q28 108 44 72q-18-14 1-25 17-8 26 8 12-23 29-10 14 13-2 29 20 29-27 46Z" fill="#df3f37"/><path d="M43 83l-20 8 18 7m57-16l23 10-21 8" fill="#df3f37"/><circle cx="62" cy="65" r="7" fill="#fff"/><circle cx="82" cy="63" r="7" fill="#fff"/><circle cx="64" cy="66" r="2"/><circle cx="80" cy="64" r="2"/><path d="M56 87q17 13 31-2" fill="none"/></g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 144 150" role="img" aria-label="Dimensional Warp token">
|
||||
<defs>
|
||||
<filter id="w"><feTurbulence baseFrequency=".035" numOctaves="2" seed="4" result="n"/><feDisplacementMap in="SourceGraphic" in2="n" scale=".65"/></filter>
|
||||
<filter id="s"><feGaussianBlur stdDeviation="2"/></filter>
|
||||
<pattern id="paper" width="12" height="12" patternUnits="userSpaceOnUse"><rect width="12" height="12" fill="#f4efd9"/><circle cx="2" cy="4" r=".45" fill="#c8bfa4" opacity=".28"/><path d="M1 10l7-1" stroke="#d8cfb8" stroke-width=".35" opacity=".35"/></pattern>
|
||||
</defs>
|
||||
<rect x="2" y="2" width="140" height="146" rx="3" fill="url(#paper)" stroke="#242822" stroke-width="2"/>
|
||||
<text x="72" y="19" text-anchor="middle" font-family="Trebuchet MS,Arial,sans-serif" font-weight="700" font-size="14" fill="#20251f">Dimensional Warp</text>
|
||||
<g filter="url(#w)" stroke="#252923" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><ellipse cx="72" cy="80" rx="47" ry="22" fill="#5c369b"/><ellipse cx="72" cy="80" rx="34" ry="14" fill="#e4bdff"/><ellipse cx="72" cy="80" rx="20" ry="7" fill="#252036"/><path d="M22 52q13-14 26-17m72 18q-13-14-27-17M22 108q13 14 27 17m71-17q-13 14-27 17" fill="none" stroke="#7849b1"/></g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 144 150" role="img" aria-label="Dustcloud token">
|
||||
<defs>
|
||||
<filter id="w"><feTurbulence baseFrequency=".035" numOctaves="2" seed="4" result="n"/><feDisplacementMap in="SourceGraphic" in2="n" scale=".65"/></filter>
|
||||
<filter id="s"><feGaussianBlur stdDeviation="2"/></filter>
|
||||
<pattern id="paper" width="12" height="12" patternUnits="userSpaceOnUse"><rect width="12" height="12" fill="#f4efd9"/><circle cx="2" cy="4" r=".45" fill="#c8bfa4" opacity=".28"/><path d="M1 10l7-1" stroke="#d8cfb8" stroke-width=".35" opacity=".35"/></pattern>
|
||||
</defs>
|
||||
<rect x="2" y="2" width="140" height="146" rx="3" fill="url(#paper)" stroke="#242822" stroke-width="2"/>
|
||||
<text x="72" y="19" text-anchor="middle" font-family="Trebuchet MS,Arial,sans-serif" font-weight="700" font-size="14" fill="#20251f">Dustcloud</text>
|
||||
<g filter="url(#w)" stroke="#252923" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M27 105q-15-17 7-27-9-24 18-24 8-23 30-9 19-10 28 9 24 2 16 25 17 18-5 30-35 15-74-4Z" fill="#68675d"/><path d="M42 80q15-14 27 1m12-12q15-9 26 5m-61 20q17-12 31 2" fill="none" stroke="#989383"/><circle cx="31" cy="117" r="3"/><circle cx="117" cy="118" r="2"/></g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 144 150" role="img" aria-label="Fire Imp token">
|
||||
<defs>
|
||||
<filter id="w"><feTurbulence baseFrequency=".035" numOctaves="2" seed="4" result="n"/><feDisplacementMap in="SourceGraphic" in2="n" scale=".65"/></filter>
|
||||
<filter id="s"><feGaussianBlur stdDeviation="2"/></filter>
|
||||
<pattern id="paper" width="12" height="12" patternUnits="userSpaceOnUse"><rect width="12" height="12" fill="#f4efd9"/><circle cx="2" cy="4" r=".45" fill="#c8bfa4" opacity=".28"/><path d="M1 10l7-1" stroke="#d8cfb8" stroke-width=".35" opacity=".35"/></pattern>
|
||||
</defs>
|
||||
<rect x="2" y="2" width="140" height="146" rx="3" fill="url(#paper)" stroke="#242822" stroke-width="2"/>
|
||||
<text x="72" y="19" text-anchor="middle" font-family="Trebuchet MS,Arial,sans-serif" font-weight="700" font-size="14" fill="#20251f">Fire Imp</text>
|
||||
<g filter="url(#w)" stroke="#252923" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M71 119q-29-9-26-42-14-16 5-21-2-23 19-12 18-20 24 7 22 8 7 27 8 32-29 41Z" fill="#e8494a"/><path d="M52 52L39 34l23 12m29 4l16-18-6 25" fill="#e8494a"/><circle cx="63" cy="70" r="5" fill="#ffe15a"/><circle cx="84" cy="68" r="5" fill="#ffe15a"/><path d="M59 91q14 10 28-3" fill="none"/><path d="M42 102l-20 13m79-14l20 13" fill="none" stroke="#e8494a" stroke-width="7"/></g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 144 150" role="img" aria-label="Killer Ooze token">
|
||||
<defs>
|
||||
<filter id="w"><feTurbulence baseFrequency=".035" numOctaves="2" seed="4" result="n"/><feDisplacementMap in="SourceGraphic" in2="n" scale=".65"/></filter>
|
||||
<filter id="s"><feGaussianBlur stdDeviation="2"/></filter>
|
||||
<pattern id="paper" width="12" height="12" patternUnits="userSpaceOnUse"><rect width="12" height="12" fill="#f4efd9"/><circle cx="2" cy="4" r=".45" fill="#c8bfa4" opacity=".28"/><path d="M1 10l7-1" stroke="#d8cfb8" stroke-width=".35" opacity=".35"/></pattern>
|
||||
</defs>
|
||||
<rect x="2" y="2" width="140" height="146" rx="3" fill="url(#paper)" stroke="#242822" stroke-width="2"/>
|
||||
<text x="72" y="19" text-anchor="middle" font-family="Trebuchet MS,Arial,sans-serif" font-weight="700" font-size="14" fill="#20251f">Killer Ooze</text>
|
||||
<g filter="url(#w)" stroke="#252923" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M26 115q-2-24 15-27-10-29 12-33 7-29 26-5 26-15 30 17 21 14 4 37 3 21-25 14-19 13-32-2-17 11-30-1Z" fill="#16834f"/><ellipse cx="60" cy="73" rx="10" ry="14" fill="#fff"/><ellipse cx="86" cy="72" rx="10" ry="14" fill="#fff"/><circle cx="64" cy="78" r="3"/><circle cx="82" cy="78" r="3"/><path d="M48 96q25-18 48 1l-8 15-8-11-9 12-8-12-8 11Z" fill="#173b2a"/></g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |