From c944a1afdc5233acf1e79fe7062016161cf7ad42 Mon Sep 17 00:00:00 2001 From: "Engineering (agent-engineering)" Date: Tue, 19 May 2026 23:52:13 -0700 Subject: [PATCH] feat: isometric renderer with 6 zones, 9 agent sprites, mock mode - FarmCanvas.jsx: orthographic camera, 6 colored zones, agent glow/bob/lerp - WebSocketClient.js: auto-reconnect with mock mode fallback - officeMap.js: zone definitions, agent state management - store.js: Zustand store for real-time agent positions - assets/: tile samples and verified tiles for map rendering --- assets/tile-samples/tile_r1_c0.png | Bin 0 -> 294 bytes assets/tile-samples/tile_r1_c2.png | Bin 0 -> 293 bytes assets/tile-samples/tile_r1_c6.png | Bin 0 -> 341 bytes assets/tile-samples/tile_r20_c0.png | Bin 0 -> 255 bytes assets/tile-samples/tile_r30_c0.png | Bin 0 -> 117 bytes assets/tile-samples/tile_r40_c0.png | Bin 0 -> 367 bytes assets/tile-samples/tile_r5_c0.png | Bin 0 -> 191 bytes assets/tile-samples/tile_r5_c2.png | Bin 0 -> 196 bytes assets/tile-samples/tile_r5_c6.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r0_c0.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r0_c1.png | Bin 0 -> 176 bytes assets/verified-tiles/t_r0_c10.png | Bin 0 -> 187 bytes assets/verified-tiles/t_r0_c11.png | Bin 0 -> 176 bytes assets/verified-tiles/t_r0_c12.png | Bin 0 -> 194 bytes assets/verified-tiles/t_r0_c13.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r0_c14.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r0_c15.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r0_c2.png | Bin 0 -> 200 bytes assets/verified-tiles/t_r0_c3.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r0_c4.png | Bin 0 -> 188 bytes assets/verified-tiles/t_r0_c5.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r0_c6.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r0_c7.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r0_c8.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r0_c9.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r10_c0.png | Bin 0 -> 291 bytes assets/verified-tiles/t_r10_c1.png | Bin 0 -> 296 bytes assets/verified-tiles/t_r10_c10.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r10_c11.png | Bin 0 -> 228 bytes assets/verified-tiles/t_r10_c12.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r10_c13.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r10_c14.png | Bin 0 -> 276 bytes assets/verified-tiles/t_r10_c15.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r10_c2.png | Bin 0 -> 274 bytes assets/verified-tiles/t_r10_c3.png | Bin 0 -> 282 bytes assets/verified-tiles/t_r10_c4.png | Bin 0 -> 274 bytes assets/verified-tiles/t_r10_c5.png | Bin 0 -> 278 bytes assets/verified-tiles/t_r10_c6.png | Bin 0 -> 296 bytes assets/verified-tiles/t_r10_c7.png | Bin 0 -> 275 bytes assets/verified-tiles/t_r10_c8.png | Bin 0 -> 282 bytes assets/verified-tiles/t_r10_c9.png | Bin 0 -> 275 bytes assets/verified-tiles/t_r11_c0.png | Bin 0 -> 291 bytes assets/verified-tiles/t_r11_c1.png | Bin 0 -> 266 bytes assets/verified-tiles/t_r11_c10.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r11_c11.png | Bin 0 -> 262 bytes assets/verified-tiles/t_r11_c12.png | Bin 0 -> 362 bytes assets/verified-tiles/t_r11_c13.png | Bin 0 -> 277 bytes assets/verified-tiles/t_r11_c14.png | Bin 0 -> 277 bytes assets/verified-tiles/t_r11_c15.png | Bin 0 -> 276 bytes assets/verified-tiles/t_r11_c2.png | Bin 0 -> 266 bytes assets/verified-tiles/t_r11_c3.png | Bin 0 -> 273 bytes assets/verified-tiles/t_r11_c4.png | Bin 0 -> 266 bytes assets/verified-tiles/t_r11_c5.png | Bin 0 -> 298 bytes assets/verified-tiles/t_r11_c6.png | Bin 0 -> 266 bytes assets/verified-tiles/t_r11_c7.png | Bin 0 -> 266 bytes assets/verified-tiles/t_r11_c8.png | Bin 0 -> 273 bytes assets/verified-tiles/t_r11_c9.png | Bin 0 -> 266 bytes assets/verified-tiles/t_r12_c0.png | Bin 0 -> 205 bytes assets/verified-tiles/t_r12_c1.png | Bin 0 -> 220 bytes assets/verified-tiles/t_r12_c10.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r12_c11.png | Bin 0 -> 324 bytes assets/verified-tiles/t_r12_c12.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r12_c13.png | Bin 0 -> 288 bytes assets/verified-tiles/t_r12_c14.png | Bin 0 -> 295 bytes assets/verified-tiles/t_r12_c15.png | Bin 0 -> 289 bytes assets/verified-tiles/t_r12_c2.png | Bin 0 -> 223 bytes assets/verified-tiles/t_r12_c3.png | Bin 0 -> 205 bytes assets/verified-tiles/t_r12_c4.png | Bin 0 -> 205 bytes assets/verified-tiles/t_r12_c5.png | Bin 0 -> 204 bytes assets/verified-tiles/t_r12_c6.png | Bin 0 -> 220 bytes assets/verified-tiles/t_r12_c7.png | Bin 0 -> 222 bytes assets/verified-tiles/t_r12_c8.png | Bin 0 -> 204 bytes assets/verified-tiles/t_r12_c9.png | Bin 0 -> 205 bytes assets/verified-tiles/t_r13_c0.png | Bin 0 -> 264 bytes assets/verified-tiles/t_r13_c1.png | Bin 0 -> 255 bytes assets/verified-tiles/t_r13_c10.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r13_c11.png | Bin 0 -> 331 bytes assets/verified-tiles/t_r13_c12.png | Bin 0 -> 303 bytes assets/verified-tiles/t_r13_c13.png | Bin 0 -> 288 bytes assets/verified-tiles/t_r13_c14.png | Bin 0 -> 298 bytes assets/verified-tiles/t_r13_c15.png | Bin 0 -> 289 bytes assets/verified-tiles/t_r13_c2.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r13_c3.png | Bin 0 -> 255 bytes assets/verified-tiles/t_r13_c4.png | Bin 0 -> 255 bytes assets/verified-tiles/t_r13_c5.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r13_c6.png | Bin 0 -> 353 bytes assets/verified-tiles/t_r13_c7.png | Bin 0 -> 234 bytes assets/verified-tiles/t_r13_c8.png | Bin 0 -> 227 bytes assets/verified-tiles/t_r13_c9.png | Bin 0 -> 241 bytes assets/verified-tiles/t_r14_c0.png | Bin 0 -> 229 bytes assets/verified-tiles/t_r14_c1.png | Bin 0 -> 239 bytes assets/verified-tiles/t_r14_c10.png | Bin 0 -> 282 bytes assets/verified-tiles/t_r14_c11.png | Bin 0 -> 335 bytes assets/verified-tiles/t_r14_c12.png | Bin 0 -> 326 bytes assets/verified-tiles/t_r14_c13.png | Bin 0 -> 282 bytes assets/verified-tiles/t_r14_c14.png | Bin 0 -> 277 bytes assets/verified-tiles/t_r14_c15.png | Bin 0 -> 284 bytes assets/verified-tiles/t_r14_c2.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r14_c3.png | Bin 0 -> 292 bytes assets/verified-tiles/t_r14_c4.png | Bin 0 -> 266 bytes assets/verified-tiles/t_r14_c5.png | Bin 0 -> 431 bytes assets/verified-tiles/t_r14_c6.png | Bin 0 -> 430 bytes assets/verified-tiles/t_r14_c7.png | Bin 0 -> 313 bytes assets/verified-tiles/t_r14_c8.png | Bin 0 -> 265 bytes assets/verified-tiles/t_r14_c9.png | Bin 0 -> 306 bytes assets/verified-tiles/t_r1_c0.png | Bin 0 -> 294 bytes assets/verified-tiles/t_r1_c1.png | Bin 0 -> 297 bytes assets/verified-tiles/t_r1_c10.png | Bin 0 -> 289 bytes assets/verified-tiles/t_r1_c11.png | Bin 0 -> 295 bytes assets/verified-tiles/t_r1_c12.png | Bin 0 -> 291 bytes assets/verified-tiles/t_r1_c13.png | Bin 0 -> 312 bytes assets/verified-tiles/t_r1_c14.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r1_c15.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r1_c2.png | Bin 0 -> 293 bytes assets/verified-tiles/t_r1_c3.png | Bin 0 -> 315 bytes assets/verified-tiles/t_r1_c4.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r1_c5.png | Bin 0 -> 330 bytes assets/verified-tiles/t_r1_c6.png | Bin 0 -> 341 bytes assets/verified-tiles/t_r1_c7.png | Bin 0 -> 336 bytes assets/verified-tiles/t_r1_c8.png | Bin 0 -> 318 bytes assets/verified-tiles/t_r1_c9.png | Bin 0 -> 292 bytes assets/verified-tiles/t_r2_c0.png | Bin 0 -> 296 bytes assets/verified-tiles/t_r2_c1.png | Bin 0 -> 149 bytes assets/verified-tiles/t_r2_c10.png | Bin 0 -> 294 bytes assets/verified-tiles/t_r2_c11.png | Bin 0 -> 149 bytes assets/verified-tiles/t_r2_c12.png | Bin 0 -> 293 bytes assets/verified-tiles/t_r2_c13.png | Bin 0 -> 294 bytes assets/verified-tiles/t_r2_c14.png | Bin 0 -> 392 bytes assets/verified-tiles/t_r2_c15.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r2_c2.png | Bin 0 -> 296 bytes assets/verified-tiles/t_r2_c3.png | Bin 0 -> 296 bytes assets/verified-tiles/t_r2_c4.png | Bin 0 -> 393 bytes assets/verified-tiles/t_r2_c5.png | Bin 0 -> 318 bytes assets/verified-tiles/t_r2_c6.png | Bin 0 -> 329 bytes assets/verified-tiles/t_r2_c7.png | Bin 0 -> 319 bytes assets/verified-tiles/t_r2_c8.png | Bin 0 -> 313 bytes assets/verified-tiles/t_r2_c9.png | Bin 0 -> 317 bytes assets/verified-tiles/t_r3_c0.png | Bin 0 -> 328 bytes assets/verified-tiles/t_r3_c1.png | Bin 0 -> 296 bytes assets/verified-tiles/t_r3_c10.png | Bin 0 -> 325 bytes assets/verified-tiles/t_r3_c11.png | Bin 0 -> 294 bytes assets/verified-tiles/t_r3_c12.png | Bin 0 -> 331 bytes assets/verified-tiles/t_r3_c13.png | Bin 0 -> 230 bytes assets/verified-tiles/t_r3_c14.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r3_c15.png | Bin 0 -> 186 bytes assets/verified-tiles/t_r3_c2.png | Bin 0 -> 334 bytes assets/verified-tiles/t_r3_c3.png | Bin 0 -> 230 bytes assets/verified-tiles/t_r3_c4.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r3_c5.png | Bin 0 -> 330 bytes assets/verified-tiles/t_r3_c6.png | Bin 0 -> 350 bytes assets/verified-tiles/t_r3_c7.png | Bin 0 -> 341 bytes assets/verified-tiles/t_r3_c8.png | Bin 0 -> 318 bytes assets/verified-tiles/t_r3_c9.png | Bin 0 -> 292 bytes assets/verified-tiles/t_r4_c0.png | Bin 0 -> 153 bytes assets/verified-tiles/t_r4_c1.png | Bin 0 -> 149 bytes assets/verified-tiles/t_r4_c10.png | Bin 0 -> 153 bytes assets/verified-tiles/t_r4_c11.png | Bin 0 -> 149 bytes assets/verified-tiles/t_r4_c12.png | Bin 0 -> 152 bytes assets/verified-tiles/t_r4_c13.png | Bin 0 -> 410 bytes assets/verified-tiles/t_r4_c14.png | Bin 0 -> 382 bytes assets/verified-tiles/t_r4_c15.png | Bin 0 -> 214 bytes assets/verified-tiles/t_r4_c2.png | Bin 0 -> 152 bytes assets/verified-tiles/t_r4_c3.png | Bin 0 -> 410 bytes assets/verified-tiles/t_r4_c4.png | Bin 0 -> 385 bytes assets/verified-tiles/t_r4_c5.png | Bin 0 -> 318 bytes assets/verified-tiles/t_r4_c6.png | Bin 0 -> 336 bytes assets/verified-tiles/t_r4_c7.png | Bin 0 -> 325 bytes assets/verified-tiles/t_r4_c8.png | Bin 0 -> 313 bytes assets/verified-tiles/t_r4_c9.png | Bin 0 -> 318 bytes assets/verified-tiles/t_r5_c0.png | Bin 0 -> 191 bytes assets/verified-tiles/t_r5_c1.png | Bin 0 -> 178 bytes assets/verified-tiles/t_r5_c10.png | Bin 0 -> 325 bytes assets/verified-tiles/t_r5_c11.png | Bin 0 -> 316 bytes assets/verified-tiles/t_r5_c12.png | Bin 0 -> 329 bytes assets/verified-tiles/t_r5_c13.png | Bin 0 -> 320 bytes assets/verified-tiles/t_r5_c14.png | Bin 0 -> 315 bytes assets/verified-tiles/t_r5_c15.png | Bin 0 -> 181 bytes assets/verified-tiles/t_r5_c2.png | Bin 0 -> 196 bytes assets/verified-tiles/t_r5_c3.png | Bin 0 -> 331 bytes assets/verified-tiles/t_r5_c4.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r5_c5.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r5_c6.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r5_c7.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r5_c8.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r5_c9.png | Bin 0 -> 339 bytes assets/verified-tiles/t_r6_c0.png | Bin 0 -> 291 bytes assets/verified-tiles/t_r6_c1.png | Bin 0 -> 298 bytes assets/verified-tiles/t_r6_c10.png | Bin 0 -> 296 bytes assets/verified-tiles/t_r6_c11.png | Bin 0 -> 303 bytes assets/verified-tiles/t_r6_c12.png | Bin 0 -> 311 bytes assets/verified-tiles/t_r6_c13.png | Bin 0 -> 291 bytes assets/verified-tiles/t_r6_c14.png | Bin 0 -> 298 bytes assets/verified-tiles/t_r6_c15.png | Bin 0 -> 215 bytes assets/verified-tiles/t_r6_c2.png | Bin 0 -> 296 bytes assets/verified-tiles/t_r6_c3.png | Bin 0 -> 307 bytes assets/verified-tiles/t_r6_c4.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r6_c5.png | Bin 0 -> 202 bytes assets/verified-tiles/t_r6_c6.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r6_c7.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r6_c8.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r6_c9.png | Bin 0 -> 316 bytes assets/verified-tiles/t_r7_c0.png | Bin 0 -> 296 bytes assets/verified-tiles/t_r7_c1.png | Bin 0 -> 149 bytes assets/verified-tiles/t_r7_c10.png | Bin 0 -> 315 bytes assets/verified-tiles/t_r7_c11.png | Bin 0 -> 303 bytes assets/verified-tiles/t_r7_c12.png | Bin 0 -> 312 bytes assets/verified-tiles/t_r7_c13.png | Bin 0 -> 309 bytes assets/verified-tiles/t_r7_c14.png | Bin 0 -> 298 bytes assets/verified-tiles/t_r7_c15.png | Bin 0 -> 192 bytes assets/verified-tiles/t_r7_c2.png | Bin 0 -> 291 bytes assets/verified-tiles/t_r7_c3.png | Bin 0 -> 296 bytes assets/verified-tiles/t_r7_c4.png | Bin 0 -> 392 bytes assets/verified-tiles/t_r7_c5.png | Bin 0 -> 303 bytes assets/verified-tiles/t_r7_c6.png | Bin 0 -> 313 bytes assets/verified-tiles/t_r7_c7.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r7_c8.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r7_c9.png | Bin 0 -> 314 bytes assets/verified-tiles/t_r8_c0.png | Bin 0 -> 331 bytes assets/verified-tiles/t_r8_c1.png | Bin 0 -> 297 bytes assets/verified-tiles/t_r8_c10.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r8_c11.png | Bin 0 -> 197 bytes assets/verified-tiles/t_r8_c12.png | Bin 0 -> 179 bytes assets/verified-tiles/t_r8_c13.png | Bin 0 -> 179 bytes assets/verified-tiles/t_r8_c14.png | Bin 0 -> 198 bytes assets/verified-tiles/t_r8_c15.png | Bin 0 -> 217 bytes assets/verified-tiles/t_r8_c2.png | Bin 0 -> 338 bytes assets/verified-tiles/t_r8_c3.png | Bin 0 -> 230 bytes assets/verified-tiles/t_r8_c4.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r8_c5.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r8_c6.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r8_c7.png | Bin 0 -> 226 bytes assets/verified-tiles/t_r8_c8.png | Bin 0 -> 178 bytes assets/verified-tiles/t_r8_c9.png | Bin 0 -> 188 bytes assets/verified-tiles/t_r9_c0.png | Bin 0 -> 153 bytes assets/verified-tiles/t_r9_c1.png | Bin 0 -> 149 bytes assets/verified-tiles/t_r9_c10.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r9_c11.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r9_c12.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r9_c13.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r9_c14.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r9_c15.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r9_c2.png | Bin 0 -> 152 bytes assets/verified-tiles/t_r9_c3.png | Bin 0 -> 416 bytes assets/verified-tiles/t_r9_c4.png | Bin 0 -> 386 bytes assets/verified-tiles/t_r9_c5.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r9_c6.png | Bin 0 -> 117 bytes assets/verified-tiles/t_r9_c7.png | Bin 0 -> 369 bytes assets/verified-tiles/t_r9_c8.png | Bin 0 -> 311 bytes assets/verified-tiles/t_r9_c9.png | Bin 0 -> 280 bytes src/frontend/FarmCanvas.jsx | 783 +++++++++++----------------- src/frontend/WebSocketClient.js | 29 +- src/frontend/officeMap.js | 541 +++++-------------- src/frontend/store.js | 287 +++------- 253 files changed, 525 insertions(+), 1115 deletions(-) create mode 100644 assets/tile-samples/tile_r1_c0.png create mode 100644 assets/tile-samples/tile_r1_c2.png create mode 100644 assets/tile-samples/tile_r1_c6.png create mode 100644 assets/tile-samples/tile_r20_c0.png create mode 100644 assets/tile-samples/tile_r30_c0.png create mode 100644 assets/tile-samples/tile_r40_c0.png create mode 100644 assets/tile-samples/tile_r5_c0.png create mode 100644 assets/tile-samples/tile_r5_c2.png create mode 100644 assets/tile-samples/tile_r5_c6.png create mode 100644 assets/verified-tiles/t_r0_c0.png create mode 100644 assets/verified-tiles/t_r0_c1.png create mode 100644 assets/verified-tiles/t_r0_c10.png create mode 100644 assets/verified-tiles/t_r0_c11.png create mode 100644 assets/verified-tiles/t_r0_c12.png create mode 100644 assets/verified-tiles/t_r0_c13.png create mode 100644 assets/verified-tiles/t_r0_c14.png create mode 100644 assets/verified-tiles/t_r0_c15.png create mode 100644 assets/verified-tiles/t_r0_c2.png create mode 100644 assets/verified-tiles/t_r0_c3.png create mode 100644 assets/verified-tiles/t_r0_c4.png create mode 100644 assets/verified-tiles/t_r0_c5.png create mode 100644 assets/verified-tiles/t_r0_c6.png create mode 100644 assets/verified-tiles/t_r0_c7.png create mode 100644 assets/verified-tiles/t_r0_c8.png create mode 100644 assets/verified-tiles/t_r0_c9.png create mode 100644 assets/verified-tiles/t_r10_c0.png create mode 100644 assets/verified-tiles/t_r10_c1.png create mode 100644 assets/verified-tiles/t_r10_c10.png create mode 100644 assets/verified-tiles/t_r10_c11.png create mode 100644 assets/verified-tiles/t_r10_c12.png create mode 100644 assets/verified-tiles/t_r10_c13.png create mode 100644 assets/verified-tiles/t_r10_c14.png create mode 100644 assets/verified-tiles/t_r10_c15.png create mode 100644 assets/verified-tiles/t_r10_c2.png create mode 100644 assets/verified-tiles/t_r10_c3.png create mode 100644 assets/verified-tiles/t_r10_c4.png create mode 100644 assets/verified-tiles/t_r10_c5.png create mode 100644 assets/verified-tiles/t_r10_c6.png create mode 100644 assets/verified-tiles/t_r10_c7.png create mode 100644 assets/verified-tiles/t_r10_c8.png create mode 100644 assets/verified-tiles/t_r10_c9.png create mode 100644 assets/verified-tiles/t_r11_c0.png create mode 100644 assets/verified-tiles/t_r11_c1.png create mode 100644 assets/verified-tiles/t_r11_c10.png create mode 100644 assets/verified-tiles/t_r11_c11.png create mode 100644 assets/verified-tiles/t_r11_c12.png create mode 100644 assets/verified-tiles/t_r11_c13.png create mode 100644 assets/verified-tiles/t_r11_c14.png create mode 100644 assets/verified-tiles/t_r11_c15.png create mode 100644 assets/verified-tiles/t_r11_c2.png create mode 100644 assets/verified-tiles/t_r11_c3.png create mode 100644 assets/verified-tiles/t_r11_c4.png create mode 100644 assets/verified-tiles/t_r11_c5.png create mode 100644 assets/verified-tiles/t_r11_c6.png create mode 100644 assets/verified-tiles/t_r11_c7.png create mode 100644 assets/verified-tiles/t_r11_c8.png create mode 100644 assets/verified-tiles/t_r11_c9.png create mode 100644 assets/verified-tiles/t_r12_c0.png create mode 100644 assets/verified-tiles/t_r12_c1.png create mode 100644 assets/verified-tiles/t_r12_c10.png create mode 100644 assets/verified-tiles/t_r12_c11.png create mode 100644 assets/verified-tiles/t_r12_c12.png create mode 100644 assets/verified-tiles/t_r12_c13.png create mode 100644 assets/verified-tiles/t_r12_c14.png create mode 100644 assets/verified-tiles/t_r12_c15.png create mode 100644 assets/verified-tiles/t_r12_c2.png create mode 100644 assets/verified-tiles/t_r12_c3.png create mode 100644 assets/verified-tiles/t_r12_c4.png create mode 100644 assets/verified-tiles/t_r12_c5.png create mode 100644 assets/verified-tiles/t_r12_c6.png create mode 100644 assets/verified-tiles/t_r12_c7.png create mode 100644 assets/verified-tiles/t_r12_c8.png create mode 100644 assets/verified-tiles/t_r12_c9.png create mode 100644 assets/verified-tiles/t_r13_c0.png create mode 100644 assets/verified-tiles/t_r13_c1.png create mode 100644 assets/verified-tiles/t_r13_c10.png create mode 100644 assets/verified-tiles/t_r13_c11.png create mode 100644 assets/verified-tiles/t_r13_c12.png create mode 100644 assets/verified-tiles/t_r13_c13.png create mode 100644 assets/verified-tiles/t_r13_c14.png create mode 100644 assets/verified-tiles/t_r13_c15.png create mode 100644 assets/verified-tiles/t_r13_c2.png create mode 100644 assets/verified-tiles/t_r13_c3.png create mode 100644 assets/verified-tiles/t_r13_c4.png create mode 100644 assets/verified-tiles/t_r13_c5.png create mode 100644 assets/verified-tiles/t_r13_c6.png create mode 100644 assets/verified-tiles/t_r13_c7.png create mode 100644 assets/verified-tiles/t_r13_c8.png create mode 100644 assets/verified-tiles/t_r13_c9.png create mode 100644 assets/verified-tiles/t_r14_c0.png create mode 100644 assets/verified-tiles/t_r14_c1.png create mode 100644 assets/verified-tiles/t_r14_c10.png create mode 100644 assets/verified-tiles/t_r14_c11.png create mode 100644 assets/verified-tiles/t_r14_c12.png create mode 100644 assets/verified-tiles/t_r14_c13.png create mode 100644 assets/verified-tiles/t_r14_c14.png create mode 100644 assets/verified-tiles/t_r14_c15.png create mode 100644 assets/verified-tiles/t_r14_c2.png create mode 100644 assets/verified-tiles/t_r14_c3.png create mode 100644 assets/verified-tiles/t_r14_c4.png create mode 100644 assets/verified-tiles/t_r14_c5.png create mode 100644 assets/verified-tiles/t_r14_c6.png create mode 100644 assets/verified-tiles/t_r14_c7.png create mode 100644 assets/verified-tiles/t_r14_c8.png create mode 100644 assets/verified-tiles/t_r14_c9.png create mode 100644 assets/verified-tiles/t_r1_c0.png create mode 100644 assets/verified-tiles/t_r1_c1.png create mode 100644 assets/verified-tiles/t_r1_c10.png create mode 100644 assets/verified-tiles/t_r1_c11.png create mode 100644 assets/verified-tiles/t_r1_c12.png create mode 100644 assets/verified-tiles/t_r1_c13.png create mode 100644 assets/verified-tiles/t_r1_c14.png create mode 100644 assets/verified-tiles/t_r1_c15.png create mode 100644 assets/verified-tiles/t_r1_c2.png create mode 100644 assets/verified-tiles/t_r1_c3.png create mode 100644 assets/verified-tiles/t_r1_c4.png create mode 100644 assets/verified-tiles/t_r1_c5.png create mode 100644 assets/verified-tiles/t_r1_c6.png create mode 100644 assets/verified-tiles/t_r1_c7.png create mode 100644 assets/verified-tiles/t_r1_c8.png create mode 100644 assets/verified-tiles/t_r1_c9.png create mode 100644 assets/verified-tiles/t_r2_c0.png create mode 100644 assets/verified-tiles/t_r2_c1.png create mode 100644 assets/verified-tiles/t_r2_c10.png create mode 100644 assets/verified-tiles/t_r2_c11.png create mode 100644 assets/verified-tiles/t_r2_c12.png create mode 100644 assets/verified-tiles/t_r2_c13.png create mode 100644 assets/verified-tiles/t_r2_c14.png create mode 100644 assets/verified-tiles/t_r2_c15.png create mode 100644 assets/verified-tiles/t_r2_c2.png create mode 100644 assets/verified-tiles/t_r2_c3.png create mode 100644 assets/verified-tiles/t_r2_c4.png create mode 100644 assets/verified-tiles/t_r2_c5.png create mode 100644 assets/verified-tiles/t_r2_c6.png create mode 100644 assets/verified-tiles/t_r2_c7.png create mode 100644 assets/verified-tiles/t_r2_c8.png create mode 100644 assets/verified-tiles/t_r2_c9.png create mode 100644 assets/verified-tiles/t_r3_c0.png create mode 100644 assets/verified-tiles/t_r3_c1.png create mode 100644 assets/verified-tiles/t_r3_c10.png create mode 100644 assets/verified-tiles/t_r3_c11.png create mode 100644 assets/verified-tiles/t_r3_c12.png create mode 100644 assets/verified-tiles/t_r3_c13.png create mode 100644 assets/verified-tiles/t_r3_c14.png create mode 100644 assets/verified-tiles/t_r3_c15.png create mode 100644 assets/verified-tiles/t_r3_c2.png create mode 100644 assets/verified-tiles/t_r3_c3.png create mode 100644 assets/verified-tiles/t_r3_c4.png create mode 100644 assets/verified-tiles/t_r3_c5.png create mode 100644 assets/verified-tiles/t_r3_c6.png create mode 100644 assets/verified-tiles/t_r3_c7.png create mode 100644 assets/verified-tiles/t_r3_c8.png create mode 100644 assets/verified-tiles/t_r3_c9.png create mode 100644 assets/verified-tiles/t_r4_c0.png create mode 100644 assets/verified-tiles/t_r4_c1.png create mode 100644 assets/verified-tiles/t_r4_c10.png create mode 100644 assets/verified-tiles/t_r4_c11.png create mode 100644 assets/verified-tiles/t_r4_c12.png create mode 100644 assets/verified-tiles/t_r4_c13.png create mode 100644 assets/verified-tiles/t_r4_c14.png create mode 100644 assets/verified-tiles/t_r4_c15.png create mode 100644 assets/verified-tiles/t_r4_c2.png create mode 100644 assets/verified-tiles/t_r4_c3.png create mode 100644 assets/verified-tiles/t_r4_c4.png create mode 100644 assets/verified-tiles/t_r4_c5.png create mode 100644 assets/verified-tiles/t_r4_c6.png create mode 100644 assets/verified-tiles/t_r4_c7.png create mode 100644 assets/verified-tiles/t_r4_c8.png create mode 100644 assets/verified-tiles/t_r4_c9.png create mode 100644 assets/verified-tiles/t_r5_c0.png create mode 100644 assets/verified-tiles/t_r5_c1.png create mode 100644 assets/verified-tiles/t_r5_c10.png create mode 100644 assets/verified-tiles/t_r5_c11.png create mode 100644 assets/verified-tiles/t_r5_c12.png create mode 100644 assets/verified-tiles/t_r5_c13.png create mode 100644 assets/verified-tiles/t_r5_c14.png create mode 100644 assets/verified-tiles/t_r5_c15.png create mode 100644 assets/verified-tiles/t_r5_c2.png create mode 100644 assets/verified-tiles/t_r5_c3.png create mode 100644 assets/verified-tiles/t_r5_c4.png create mode 100644 assets/verified-tiles/t_r5_c5.png create mode 100644 assets/verified-tiles/t_r5_c6.png create mode 100644 assets/verified-tiles/t_r5_c7.png create mode 100644 assets/verified-tiles/t_r5_c8.png create mode 100644 assets/verified-tiles/t_r5_c9.png create mode 100644 assets/verified-tiles/t_r6_c0.png create mode 100644 assets/verified-tiles/t_r6_c1.png create mode 100644 assets/verified-tiles/t_r6_c10.png create mode 100644 assets/verified-tiles/t_r6_c11.png create mode 100644 assets/verified-tiles/t_r6_c12.png create mode 100644 assets/verified-tiles/t_r6_c13.png create mode 100644 assets/verified-tiles/t_r6_c14.png create mode 100644 assets/verified-tiles/t_r6_c15.png create mode 100644 assets/verified-tiles/t_r6_c2.png create mode 100644 assets/verified-tiles/t_r6_c3.png create mode 100644 assets/verified-tiles/t_r6_c4.png create mode 100644 assets/verified-tiles/t_r6_c5.png create mode 100644 assets/verified-tiles/t_r6_c6.png create mode 100644 assets/verified-tiles/t_r6_c7.png create mode 100644 assets/verified-tiles/t_r6_c8.png create mode 100644 assets/verified-tiles/t_r6_c9.png create mode 100644 assets/verified-tiles/t_r7_c0.png create mode 100644 assets/verified-tiles/t_r7_c1.png create mode 100644 assets/verified-tiles/t_r7_c10.png create mode 100644 assets/verified-tiles/t_r7_c11.png create mode 100644 assets/verified-tiles/t_r7_c12.png create mode 100644 assets/verified-tiles/t_r7_c13.png create mode 100644 assets/verified-tiles/t_r7_c14.png create mode 100644 assets/verified-tiles/t_r7_c15.png create mode 100644 assets/verified-tiles/t_r7_c2.png create mode 100644 assets/verified-tiles/t_r7_c3.png create mode 100644 assets/verified-tiles/t_r7_c4.png create mode 100644 assets/verified-tiles/t_r7_c5.png create mode 100644 assets/verified-tiles/t_r7_c6.png create mode 100644 assets/verified-tiles/t_r7_c7.png create mode 100644 assets/verified-tiles/t_r7_c8.png create mode 100644 assets/verified-tiles/t_r7_c9.png create mode 100644 assets/verified-tiles/t_r8_c0.png create mode 100644 assets/verified-tiles/t_r8_c1.png create mode 100644 assets/verified-tiles/t_r8_c10.png create mode 100644 assets/verified-tiles/t_r8_c11.png create mode 100644 assets/verified-tiles/t_r8_c12.png create mode 100644 assets/verified-tiles/t_r8_c13.png create mode 100644 assets/verified-tiles/t_r8_c14.png create mode 100644 assets/verified-tiles/t_r8_c15.png create mode 100644 assets/verified-tiles/t_r8_c2.png create mode 100644 assets/verified-tiles/t_r8_c3.png create mode 100644 assets/verified-tiles/t_r8_c4.png create mode 100644 assets/verified-tiles/t_r8_c5.png create mode 100644 assets/verified-tiles/t_r8_c6.png create mode 100644 assets/verified-tiles/t_r8_c7.png create mode 100644 assets/verified-tiles/t_r8_c8.png create mode 100644 assets/verified-tiles/t_r8_c9.png create mode 100644 assets/verified-tiles/t_r9_c0.png create mode 100644 assets/verified-tiles/t_r9_c1.png create mode 100644 assets/verified-tiles/t_r9_c10.png create mode 100644 assets/verified-tiles/t_r9_c11.png create mode 100644 assets/verified-tiles/t_r9_c12.png create mode 100644 assets/verified-tiles/t_r9_c13.png create mode 100644 assets/verified-tiles/t_r9_c14.png create mode 100644 assets/verified-tiles/t_r9_c15.png create mode 100644 assets/verified-tiles/t_r9_c2.png create mode 100644 assets/verified-tiles/t_r9_c3.png create mode 100644 assets/verified-tiles/t_r9_c4.png create mode 100644 assets/verified-tiles/t_r9_c5.png create mode 100644 assets/verified-tiles/t_r9_c6.png create mode 100644 assets/verified-tiles/t_r9_c7.png create mode 100644 assets/verified-tiles/t_r9_c8.png create mode 100644 assets/verified-tiles/t_r9_c9.png diff --git a/assets/tile-samples/tile_r1_c0.png b/assets/tile-samples/tile_r1_c0.png new file mode 100644 index 0000000000000000000000000000000000000000..b759a0d4b8d2029afe388bba92a471d5f0c2f9bb GIT binary patch literal 294 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1FJQ zi(^Q|oVPbO<}y3-xLjP_9U4=Ay{UNnBd!+T(1Yf4B0Cp!^KH7%l+*BFl5zdEw@+r@ z{2lu}kN@k{=h0V}F{;n!l!#ZbPS80R(^$y1n7K`$OQ=VrPrO62OS(svkDo)}W!9l) z4%W_APPVQ#F81#4ms|QvZPvbBpIpcrp{5X@aFa2z>9ptx$(ZAZIp^Q}KcDYHgCXNj zreyXM&OYr4#ugyG+3zrBN!cw+&1CEYdXd4?)z4*}Q$iB}99?JQ literal 0 HcmV?d00001 diff --git a/assets/tile-samples/tile_r1_c6.png b/assets/tile-samples/tile_r1_c6.png new file mode 100644 index 0000000000000000000000000000000000000000..421094861a127d312743a45fe64f5adee03aab2d GIT binary patch literal 341 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wk0|O(w zr;B4q#hkaZHu4^F5MbHAZgtZY%h(GHjG6&Vix^yf%@m%r{-C9hD9_4VPHUrS_mVR| zf6w}!_r63k>9|PH+jx%yeym5P>3-03|0N+@usd#*+oXm?Oc$7*mh-NV%{<4nRoT-a zkkKdd!O7iOODtK}{B_`TVBN5S^;WR6{OrvR+Kjzi8QXIjCH{Wc`I;@_ccV}PmjibK z?*XNbSccmQ&lq@|X0RA?ZGNCraAG~7<8Hv#SfTCfRx-+=?Jv2 z=6+x>WiDHx%(-{W5!Hzgot6|UABhi7`u#h(q0ndzuP2ie>jKt8(uy{dxYi%};G?%k k_=xk#bKZg5O0<5nhPdYnp41AJ1BMfWr>mdKI;Vst0B8w%&Hw-a literal 0 HcmV?d00001 diff --git a/assets/tile-samples/tile_r20_c0.png b/assets/tile-samples/tile_r20_c0.png new file mode 100644 index 0000000000000000000000000000000000000000..60eb96adfefef7ef20d8b3e8037e8ff0dfd7c24a GIT binary patch literal 255 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP;jHC zi(^Q|oVV9D@-`a?um}QCyFSjEF7$6Mql@%}^0f{+HI27+nx0K+Vhl-RUc~j}y`s&r=c~T_t(|n~ z=dG5t+6fGcc~2}~=WxBW-OHfiRE|SP+`?6 qe2nV%mBj7JU}au$hV4jl_ygv@f-#XCvfJcA_ItYexvXgO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/tile-samples/tile_r40_c0.png b/assets/tile-samples/tile_r40_c0.png new file mode 100644 index 0000000000000000000000000000000000000000..eb6df53d11b00e3dbe5e71eebe923798ba1e52ad GIT binary patch literal 367 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wk0|TR? zr;B4q#hkY@74r@|2)KTCQcaW;u&D6VZGEG7sHi9A(4;^Qukf7?++AKus^%QrB^l)o zs_qkCo!O&aoA%)EuYA?hn!Zb-^N-yR)b*WIZpC$DLxbKXrYydih;_4e=(}hx*uc=c z=0J$5OVQ*fyh|GnF_~;)603et(8|G@BBn4=bi)nic)R_xZk&Jpgm+=X877rYOw$V3 zw*?%S#oDt@B;d2@k2gzpE*1%hXmAU1ILocqet1dDdHecfcJ{lSrZ91F2Z(6!-)H=~ zIN#{rI^R3@8K*K;i3KQY7yPm_+vpW=-~f}Gh=k02#;X?j?^(Wcg>b!ybf`^bJ@V&e zW%Yg2$ei!~XW!H<;{v%wW5R#k&AXXfn2fk5cz{9@7=E7)$S!<-&tko8)=d!K)78&q Iol`;+05~g&y#N3J literal 0 HcmV?d00001 diff --git a/assets/tile-samples/tile_r5_c0.png b/assets/tile-samples/tile_r5_c0.png new file mode 100644 index 0000000000000000000000000000000000000000..45e7d14edc4267d4ed56b5fda7e2e95c8a941777 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP_WR` z#WAE}&f6;+c@HS?usEE5s=4XEfTm`Khrja@7l$d}GmC3q9=RRH zpTelgn487AY4?Wk(>uR%a#wgTeM%QSaqxiHg~-2$gaSeq`2J;n#kMgns&UuB0I>j- c1$WmTV681=OTV^I%o}8$r>mdKI;Vst0HPQ@{Qv*} literal 0 HcmV?d00001 diff --git a/assets/tile-samples/tile_r5_c2.png b/assets/tile-samples/tile_r5_c2.png new file mode 100644 index 0000000000000000000000000000000000000000..a5625b8c4f5fe27aa3d87acb22e548841f827578 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP_WF? z#WAE}&f9An1sfCuSR7t0;^H<_+9u}Q1@u=pFwEjT5g)4X?w|M( hmUbbB?TkM|SoxO5-kh;@!qFm-k)E!8F6*2UngAb6K(YV; literal 0 HcmV?d00001 diff --git a/assets/tile-samples/tile_r5_c6.png b/assets/tile-samples/tile_r5_c6.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r0_c0.png b/assets/verified-tiles/t_r0_c0.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r0_c1.png b/assets/verified-tiles/t_r0_c1.png new file mode 100644 index 0000000000000000000000000000000000000000..b5aeb0c94b11f6e95b2ef25508f7363075481420 GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP%z2U z#WAE}&f9a2ye$C?M-MFL7Tpo6{rZ{mV$L%vd&`-DN?;)F`L1`LpN8>YSu3|9+BRVO x|DSX9w^uF5`|5D_RpYL!%%!W@Um;}S66{j~vbGvXKL`bxvd$@?2>=pjJZAs^ literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r0_c10.png b/assets/verified-tiles/t_r0_c10.png new file mode 100644 index 0000000000000000000000000000000000000000..ecf64404a8398c016203ac769aba83eec70aa8a5 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP%zii z#WAE}&f6;+IU5`VSPrazy=p`B?u{(LhfS}!I9?P_e{iWiI&Z%zP$>*FFo!ztGkKer zudmWj#8|n7X=`=CsZBEti?3g1DVWH;Vt(iXJ~1(e7>5uA`+v;G_@)Vg+0Xwqh^C}; U?>Ly+JQ-w^r>mdKI;Vst0Ns>3CIA2c literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r0_c11.png b/assets/verified-tiles/t_r0_c11.png new file mode 100644 index 0000000000000000000000000000000000000000..af2fe124a7c2e5d06b53e946ea84214555166c32 GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP%z2U z#WAE}&f9a2ye$C?M-MFL7TpmWp8ZgHG3ObTz2(e6B`^^8eAm0rPs8}Htd(04Z5y!t x{?GaP+p8AjeRa6|s&Us<=F-*duMo0u3HE@=YqlzF$J5o%Wt~$(69DgzJW2on literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r0_c12.png b/assets/verified-tiles/t_r0_c12.png new file mode 100644 index 0000000000000000000000000000000000000000..29c87940c0470a05c0c7fce7ca05702f8aaa65d4 GIT binary patch literal 194 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP_V?) z#WAE}&f9ATc^ec2SR7t2;+nmAns-8K33b_R>isf06})=i8ADuscD^O?D4XS*>h z-pZMGm2C^VcEC;J&pCVNr&TDJ9#mu%kQNX*b esbHqyANqhHOh30`J7duTkcpnIelF{r5}E*^csiN@ literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r0_c13.png b/assets/verified-tiles/t_r0_c13.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r0_c14.png b/assets/verified-tiles/t_r0_c14.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r0_c15.png b/assets/verified-tiles/t_r0_c15.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r0_c2.png b/assets/verified-tiles/t_r0_c2.png new file mode 100644 index 0000000000000000000000000000000000000000..99e2c53ab9f1a49aa90dc444c0406b27c2e071da GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP_W9= z#WAE}&f6;+c^eFPSRBf{rb}wv=oh`T*~=|~JJ^}oX(C5~`d@~hH{?J@!N7y!qIr*e z10Aw=HpiPX{yZqUVx!A>&DVRpKRacy_lG#lXxPA1_?As(@}(W8pXWOS9>`%jH9u^@ lyfrOMlQ=oFC%n7gz&oMJbcW`MhqfRyJzf1=);T3K0RUTfK`HgO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r0_c4.png b/assets/verified-tiles/t_r0_c4.png new file mode 100644 index 0000000000000000000000000000000000000000..5519bdf437dbfe18b8822cde6541b280e85c0c51 GIT binary patch literal 188 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP%zKa z#WAE}&f6=eIU5{!ST3y94!yB0@%5^74#IeCiMMpc**R|31%19AK;2= VNu1Gr<@ObjQJ$`TF6*2UngB5sJcj@P literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r0_c5.png b/assets/verified-tiles/t_r0_c5.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r0_c6.png b/assets/verified-tiles/t_r0_c6.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r0_c7.png b/assets/verified-tiles/t_r0_c7.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r0_c8.png b/assets/verified-tiles/t_r0_c8.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r0_c9.png b/assets/verified-tiles/t_r0_c9.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r10_c0.png b/assets/verified-tiles/t_r10_c0.png new file mode 100644 index 0000000000000000000000000000000000000000..aceaad0e6cc3b61ef2906f368b5f20445733c06a GIT binary patch literal 291 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1Gg! zi(^Q|oVPO_MOh3voG-R^*@n1Iy~0*j&@k&wX&T?|?`Y2F6Y%7j6|}2cCmR zSX+42sv9C&x_krH96GA2(6{iBl*sdfiR>K?PbP45dc2vy*%k0*0#|p$pAY&ADx`mi zd;DW9QGK}c=gr(EUPf-#EydhCD?g}-$^|`qJDbZ~Z^NG01&Rrk+6fyD_VV^^=Iz_f lbgP!bj73M}f_>Bj?)alV()n8^DFQvn;OXk;vd$@?2>@qrX;T0I literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r10_c1.png b/assets/verified-tiles/t_r10_c1.png new file mode 100644 index 0000000000000000000000000000000000000000..a83cc47af2e0c49808d51ed20fcc513d15a83eb0 GIT binary patch literal 296 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1F(g zi(^Q|oVS-9c@G-lxxKOg^FZB?N6V2*vlMfHNad~eib7r>NUVvMqK@Mh0=$)HPb b!EdZF+gY=UeW!#0eaYbI>gTe~DWM4f6gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r10_c11.png b/assets/verified-tiles/t_r10_c11.png new file mode 100644 index 0000000000000000000000000000000000000000..305192b865ad3d4df82126ebea814faaed48af9b GIT binary patch literal 228 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP;i>3 zi(^Q|oVV9E@*Z;FVZCtXsbv?l*QahV0E z2?FN09ZCKB{8EE|5_|kfmLq*(59;Rf$4UvPC2VCfG+=%;&Hw83Z`=0pT-G@yGywplZc^s} literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r10_c12.png b/assets/verified-tiles/t_r10_c12.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r10_c13.png b/assets/verified-tiles/t_r10_c13.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r10_c14.png b/assets/verified-tiles/t_r10_c14.png new file mode 100644 index 0000000000000000000000000000000000000000..ce7ba325e4941dc72959da7302c8cc87dfc167b5 GIT binary patch literal 276 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1FGIlNss)TB<&aiYv02G$AvEPT6-`=8hSO4-y`< z&wu{F^o;w2zCpEv*+EOzBA#7C(`ik=MMF&tGnWLyFKsm!!#@Y9ez( zEH?i5!c@EaM?lYxk_Ua|%E%`3C``r{!plZT9xO2?VR7A8+wFP#~89gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r10_c2.png b/assets/verified-tiles/t_r10_c2.png new file mode 100644 index 0000000000000000000000000000000000000000..dafb2e893480915c9200ca36aeeb6e9887aba0e4 GIT binary patch literal 274 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1FPS zi(^Q|oVVu;1rHbq958sy)y2menxi`Pz=aPV=ayZ6TPA%s>ij$%+XYM6w|r^1_J42n vrY{ZCQ}tpBVx1y(!e8jzJo}G7W(L&jDlkT~ZV|hY<{;g4TP!2HU^nwE zMG?J&WnAs?3v8VqO6R;U_`qCc<9k%VvoB!dkxA+iJ{O;GiAUQMHa2tn#5{PwBrI;R zMCK0SlN#sjQkdICER9Aae>kJ#bxfQegN!aw*SQzy5G-h>?vFvfwMJ=}X3XaBms VX2Pvi{y={*c)I$ztaD0e0sw=dV=n*z literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r10_c4.png b/assets/verified-tiles/t_r10_c4.png new file mode 100644 index 0000000000000000000000000000000000000000..dafb2e893480915c9200ca36aeeb6e9887aba0e4 GIT binary patch literal 274 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1FPS zi(^Q|oVVu;1rHbq958sy)y2menxi`Pz=aPV=ayZ6TPA%s>ij$%+XYM6w|r^1_J42n vrY{ZC?72~pJ;LGOhJ?fEhxhF*_TyRNIqOVxcgG8b(7T^x zUz>P3tZb0E%JlW~qxF?BNpJNyHAE*Yj#}_<&kmLzt`4yo&FKd=zn>nl+mp$Q)rEVC zq=55=KTIEar`alqE!@a?Ov@&((W32`sl@XSAD9mbWcCF_B%KxJ3Er~vP-3^a-h{2Q z3mOlxHgSvS3B)WYXnerb%FQA!5u>oOdImcj3L1|Am6(8(*vCBJb!%gI UC6-k*8|WtnPgg&ebxsLQ0Mi6xq5uE@ literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r10_c6.png b/assets/verified-tiles/t_r10_c6.png new file mode 100644 index 0000000000000000000000000000000000000000..2044ef984e95336e4decc28e394714fb44da4252 GIT binary patch literal 296 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1F(g zi(^Q|oVS-9c@GK`S0&v9@yDX{I9`v{((~K4YNxcU`o8%GhQ<2$}U*SyoKI^ ax5Rm~QcHOr{kaMBC4;A{pUXO@geCxMRBZtO literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r10_c7.png b/assets/verified-tiles/t_r10_c7.png new file mode 100644 index 0000000000000000000000000000000000000000..2f89b196758172c258320dd2c2a63582c2d0733e GIT binary patch literal 275 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1Gay zi(^Q|oVVv3c@G!}9N6$ctIJVx&q2w_Vr}x*J^n4v+kX4SwW@C^FBx@h7c6Dp^6&lK v$w2B$!!)@Imzblf9K886U~&T`_?E#;Tz%@SSK<9Y4>5SU`njxgN@xNANGxeQ literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r10_c8.png b/assets/verified-tiles/t_r10_c8.png new file mode 100644 index 0000000000000000000000000000000000000000..78f58178af125fe45ed5373385419f274ce4fd52 GIT binary patch literal 282 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1FbW zi(^Q|oVPcdHBM$bo4EkJDkFJF!>A4xN@f$)Z#LywA}kTs!GodCzST zA%jqdJ9n7Ap8D7KI%<)MLa0M#;~$lWZ@vom&*%Jlok?gzs6%#RF54Ex9l4F$*tT0Q zkac<}l(W3x2kR|kk$nfh@v+-4IDR>VXW|nMQE#2frlTUh>k2j=6&APHao`XupWcRo z#%6Avm>hSXD5SU`njxgN@xNANGxeQ literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r11_c0.png b/assets/verified-tiles/t_r11_c0.png new file mode 100644 index 0000000000000000000000000000000000000000..b3f685f466453fbc92f17af377e00dd55a3e151f GIT binary patch literal 291 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1Gg! zi(^Q|oVPcv1rIy$v^+e#R81sk2VaA;lGMQjv9y8=v)nrp4SzG;SWK$ce3O5i7WnmC zz1-f|XFH-b99}j^G;U%};+&=}kiOwXgMgDSXPZdgeg_-px6(c3JAN`Ic9^(p=xlt( z*`|3b=HZ5;(&8s}L_c6^sE0;Kj-h~|w1&zm8o48H%1Y#BxHa=kL z1uDq^DY0+iUi04O>Eme+f*MvbPZOL`c3>0Ba_tRs4tlc7v|MoGl=Gi-==bx|Q^$J` itYgrZ-4Ne%fIp^Oc$L2Oi#I?IGI+ZBxvXBi>*R@p6YcLBzfXVJFpV!`uoBxQaRrrIo!mYd=nn=@ LS3j3^P6gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r11_c11.png b/assets/verified-tiles/t_r11_c11.png new file mode 100644 index 0000000000000000000000000000000000000000..496491eb2a9c15105381ae9bd2ad46a26a874731 GIT binary patch literal 262 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP;iH* zi(^Q|oVV9E@*Xk}U=29`RCdCpG}fwoM_;!Drt=RBC61PG#0a=fTV%0E{jZp2eED<% zC*@-+>z3Vlw(zo@e}u58!OVsX)@9|Kma%Pq-+524S8%YZ2nXki(GEEOr+mk6 zwkHP{HDoYlUFSM7*_E-Ib46If&q8LPd%>WgKutf;&f7@s@ZCos0Z&&ymvv4FO#ryp BUNHaw literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r11_c12.png b/assets/verified-tiles/t_r11_c12.png new file mode 100644 index 0000000000000000000000000000000000000000..4496d04ea749f1997b34040d7e3bc9d56d2b4de4 GIT binary patch literal 362 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wk0|TRs zr;B4q#hkY@Hu4@;5OJCL`h9|?uJ)3m$!(HB$CXovn;L_h-e12MsPPOBONbOxwAq#Y^%` zq}JA3pFdTuR!$I1IKViKgQr_|!_=*^fsfwFJ`iwt%y7M!<^94f_i!;9Jz!8| zTKTm0z%#xN90f-i_dVzENOo!9WLHr#SX%-ND+Y!T{T~ccODbIsXk@vA_@1tQF6*2U Fng9^QhkyV8 literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r11_c13.png b/assets/verified-tiles/t_r11_c13.png new file mode 100644 index 0000000000000000000000000000000000000000..57d4517f34cf2edfeb5e8dfdd665f368a545c546 GIT binary patch literal 277 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1G~? zi(^Q|oVPbmb21z9umoIR%2&dfd5SkzcGnW6rL6+Z<-GY0tPviw`i}!uGyD)1d~dh& znAW?x2DTQ?7w&5hJg<@sb!HYzWIDvPMOvUQA-U0^`ENJhiOBv{8)vh83mUZeL2=P3GoE&sBBDVnOnUJyJMT1I9myl1;j*7;Vwk~O(vK>ztH3c*~1Gw;VuIz$R+xysrVY*P%A_@MQas`(Z!fYhmdKI;Vst0FPs5i~s-t literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r11_c15.png b/assets/verified-tiles/t_r11_c15.png new file mode 100644 index 0000000000000000000000000000000000000000..aa70cdb09fdea150254bd50b6dd612dd8c42e735 GIT binary patch literal 276 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1FptD9!xlNmYc`;%AE%r4(swuGa^AGfo^2*boFyt=akR{099gTEdT%j literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r11_c2.png b/assets/verified-tiles/t_r11_c2.png new file mode 100644 index 0000000000000000000000000000000000000000..7af64f09762168cb5532a96063f0d9fa84ef60d1 GIT binary patch literal 266 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP;if@ zi(^Q|oTuju85tCK4s7U}qp>Bi>*R@p6YcLBzfXVJFpV!`uoBxQaRrrIo!mYd=nn=@ LS3j3^P6|KpxGJFal}ha z!s+59uJ(vMI}YqzJB`~!JVNh6Ou|lw;>M>;XIb00Rm3IqCd4G{a42eg$aIpmiCaXR zLoXmkVTVIu;{&FntmksK#w^%*ps4W~(`nXO+&bbJdIm8HI}a2zK4JQ-uJ?g;_OBi>*R@p6YcLBzfXVJFpV!`uoBxQaRrrIo!mYd=nn=@ LS3j3^P6!SF>SkJCYpZO6@81?^zZszbLHc<$BbU=N5nOZ71|PRGHqn*=HpN_nUdh~@FD9V9$s^avWh2+f*o62 zG?X?@<8;%w74)#TrkK3BLMf3z>78Eo-U~1)N5!Z-O*m2+i(?M1?aSlC$9S#MJ z2U(lAzof-H_*b6Df5A#&pF_S0vzT#-p>wz7u5YH!=CTDsPUfl=@3dQ|n^r_NXFoUH rQTD#!{rdCnl?~SzKeGNRXZypzyk%Jvzu+$8YoVO=2dda^%NVdNG~( nroF6NSW>=l0&Rr=hqHxDN!lAGq~7ZN3li~k^>bP0l+XkKp<_f? literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r12_c1.png b/assets/verified-tiles/t_r12_c1.png new file mode 100644 index 0000000000000000000000000000000000000000..7e15bdb3946893c3b45ec2afa95afb1eb9bed9e6 GIT binary patch literal 220 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP_WO_ z#WAE}&f9And7TwSm>tf$P8Ky{Ol}o4a$r-bofYpo&8~csw+i>c=9*{8^XF{g-ZHtY zvFwuG1;1OYw>)<{SZ9i7sJ~@;o6_^#&JxOA61!k-3~%Rs*7sj`g(fjC6W$Qpn8}vo zTu{aOZQ}U{JAPwZ7cZ(#x;UH=YNHc)I$ztaD0e0svvB BOU?iQ literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r12_c10.png b/assets/verified-tiles/t_r12_c10.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r12_c11.png b/assets/verified-tiles/t_r12_c11.png new file mode 100644 index 0000000000000000000000000000000000000000..c52c8d6db17ba93c51be0d5f17a0a07eb149a166 GIT binary patch literal 324 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1F|l zi(^Q|oVPa=`3@O~9Q!ygBm9PMRi|Xr12!4fP!Y$4Gc!1tx}DCPnIP`7@wM`rByR1O z|EJe<=}7C}f6Z|WXaWcvU{Mlk`}kY!)YlE2i|nsoe?8+4C$oT*g6i6a73?*4w{2dw zKYVfIuiw&a3ML90m_Gfz;H_G!VYfSUig�$$xv_OFB3+*LZ4wxUtsV_-lFNzWJL= zMc6)MJ2AJ2PIxG=tITAjvC`Bx=NS?iba^LC3VTpv)s`4kpRpwDiSnzeT6?yHOos&4 zH%;jc!J=2Jt;)sL?>WYx!^`2izG0bs!MhoEEZG7sGlYKvg%5+l{|CI+)aIIo?1=sZ O;(NOKxvXgO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r12_c13.png b/assets/verified-tiles/t_r12_c13.png new file mode 100644 index 0000000000000000000000000000000000000000..dc29a04f8d4786652a6295f8cb6148932a276131 GIT binary patch literal 288 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1Ftc zi(^Q|oVT|(@*XzeaS1$sl=l)#o|m;Gc}VU}=1=;ZJJ7JBPuhSz^j zpI`r7`F-^Fo1f2pd&n9Sv#;SJ_Z3M4zJt41kC{f49?)o6B^0x?;49N=$yIp;TMwJ^ zM=(#E#j$o`#95Z>0b70)ou~qkZlnU8mdKI;Vst05ZLDX8-^I literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r12_c14.png b/assets/verified-tiles/t_r12_c14.png new file mode 100644 index 0000000000000000000000000000000000000000..525a2f236b145b64bcd5b24f0a043a960c26ccdd GIT binary patch literal 295 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1GUw zi(^Q|oVT+N@-jQ}Fx{1#U*hV#ve{ot$=5|G@YzB6weQMuZR{-nrr*7FAZokWhHGni z*OX>6XXE7lxx=_;UjKSA_Jn;6pSWjOFNkS+CaQ6M!AfQ?#T2cBL0q%r7MM6Mlh%2= z;Uu${LXyxzq0X5;8(J2riRx|KF_U}B!HyX`trus^;B9-jVg_IP#~lxtnG_T`CN`Yl zaMN%IY7*j}G3NmbvxcU}#fDQ{VHO82HHq=>*mFbtM2%uoYp1%j^4}+?&PbbW4@@&W SviLgClMJ4&elF{r5}E)bv~pnp literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r12_c15.png b/assets/verified-tiles/t_r12_c15.png new file mode 100644 index 0000000000000000000000000000000000000000..3c53ed19612891e70c8e7ef286532a59d4515730 GIT binary patch literal 289 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1G&+ zi(^Q|oVT|(<{ohnaK5YBE4pD~LlKEUH-%6U#BCcV*;=W1p_-{Gn3 zJ_+QFa!ELXL?JDSXNz6Rs>g z!Zg`>PC~<^b`jo?ZyOFVddo-I6#RV5-C|JKGch2o&sgNrm5s-oW?SD&=$L$5hPU+F lj>C%n^3^u^3(o&%C^*0HlEC-Woj~s~c)I$ztaD0e0st{5bs+!% literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r12_c2.png b/assets/verified-tiles/t_r12_c2.png new file mode 100644 index 0000000000000000000000000000000000000000..fa6031193a73db118eeccd27f868162f810e845f GIT binary patch literal 223 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP;jEB zi(^Q|oVV9D@*Xk}VYx6{n^)U_G5M%+1p}LjE$?<>gTe~DWM4f DkX=z- literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r12_c3.png b/assets/verified-tiles/t_r12_c3.png new file mode 100644 index 0000000000000000000000000000000000000000..77f9fe26f2e22fb7a1b64ac86a7c8f915b18f8de GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP_W+9 z#WAE}&f9C=qRfgs3=Snvn^;9c#HI=`3huDgZ|71le(%blxIb|I&p+KAU%LutPik1n zmhn{|z(jq9=e8E#U@n88 qGtc9!+ier@Blk%vo=E87db`S}w=SR9X1)UG6b4UMKbLh*2~7Yl_C^T+ literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r12_c5.png b/assets/verified-tiles/t_r12_c5.png new file mode 100644 index 0000000000000000000000000000000000000000..d98f881feffd132676a09928b663567ff1ffbe8c GIT binary patch literal 204 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP_WL^ z#WAE}&f9Anc@G=#usEDss(C4G`IUzpa;nLDqm^Bmwm*_Rz}m6=OX%##*ArjY#GRiX zynADVDx+jAQ@L>9?#&RU`~Kp&?_I9E(^;UZ;J08e<42Bd@e2D6USnRwq3dg~c-4pf nX%Uwr9K0Re<^wH-f-5rW%^n9Yc&=AJ4-)Zo^>bP0l+XkKvi(G2 literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r12_c6.png b/assets/verified-tiles/t_r12_c6.png new file mode 100644 index 0000000000000000000000000000000000000000..974f0c27d3a21da4cbd2dc31c120a04cde1b50d1 GIT binary patch literal 220 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP_WO_ z#WAE}&f9And7TwSm>td^70KKzTq>csI7R2u@}Hq8FN@W8x@;1#IgxJn{iNq^2kT7n z4E486ZVzM$AL760orpu$a2%n=MAx~F7mvv4FO#owO BPR#%S literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r12_c7.png b/assets/verified-tiles/t_r12_c7.png new file mode 100644 index 0000000000000000000000000000000000000000..7977c574c46d597bd22c4109cf4a697cf1565a4e GIT binary patch literal 222 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP;i2$ zi(^Q|oVV9D@*Xk}VYx6{JNUvT;ZmC>_e7n`mle25PE`8u`j>R`zxw&(wXv3&;u-31 zncgmmT`+eG_m;_Jjb)egF8JMIy>+ti&b6t?e3|FBG~dhrDC9V2ukn_lO?rb(V>R?zr5Pz(N5MAO&}3ZS3j3^P6no{ literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r12_c8.png b/assets/verified-tiles/t_r12_c8.png new file mode 100644 index 0000000000000000000000000000000000000000..8e45daf83850d5bd25ce08fe921c18db7bea23df GIT binary patch literal 204 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP_WL^ z#WAE}&f9C&qAZF$3=So(th)2oJyUVWsO5 q58r%yynIT-TBc3K+(1jA;BlCJitxb;1-}>#K_Z^6elF{r5}E)c{zJ6@ literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r12_c9.png b/assets/verified-tiles/t_r12_c9.png new file mode 100644 index 0000000000000000000000000000000000000000..ad66a09b5498be5151f666f7eb120aaa05a988cb GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP_W+9 z#WAE}&f9a2ybT5n2M)ZN#kH^E5wDOMYoxQA@HOvW`tM8E%{?r)0TU(nB)^sU)*uT( rpLbqAm&ktuKbolGISC2~xOFwx9sT95#&h^L3$b08!Rw(Fu>4#@w4U#0jq@ja ztm|#x-4pT-KfthwcZJr3+ogYQC%U~)Z(tOW4ls{xOf2Eo-}{JdLasw-=;6Q=EA6}TW<0&t6vm(DU@`}gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r13_c11.png b/assets/verified-tiles/t_r13_c11.png new file mode 100644 index 0000000000000000000000000000000000000000..dba934af98fe84df922638a70afb1d8a620035c7 GIT binary patch literal 331 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1Gv( zi(^Q|oVU{q`3@Nfu>9S;WZ~iit}f5zI_rNj`Zc?_z7_w_R$}t5&&;kX*u_Q2NI7?^ z%el2>{$+eX-5~Jb_>bk&H?Dbp?f2}%$qnj^|K@86_^R^sc%`l!=8Mtlo0R$ zn!DivpNCe{uEoXKA5UZ(C`@3uS;}hii~aeuXlqVpDWM79Vi>{hE{J}>t7^lNT6s|7 P7D&L;)z4*}Q$iB}PZ@pF literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r13_c12.png b/assets/verified-tiles/t_r13_c12.png new file mode 100644 index 0000000000000000000000000000000000000000..3b86d72eb8ad3c8b5ee1eaf53598067083922a35 GIT binary patch literal 303 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1GFr zi(^Q|oVPa=g$@~rv^>1CM*Kj?kz>Y(-v)I$eP@}YxGpVr!;{W7KHc1t|IgaAE~wl* z+sJ|)s1pR@CrsHcQ(lt9sKl7Hl4+IA2NRy7I<^J>-=wF%|7N>%a~yXVX8C^<31caGO4e@9FC2vd$@?2>>Svb5j5S literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r13_c13.png b/assets/verified-tiles/t_r13_c13.png new file mode 100644 index 0000000000000000000000000000000000000000..dc29a04f8d4786652a6295f8cb6148932a276131 GIT binary patch literal 288 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1Ftc zi(^Q|oVT|(@*XzeaS1$sl=l)#o|m;Gc}VU}=1=;ZJJ7JBPuhSz^j zpI`r7`F-^Fo1f2pd&n9Sv#;SJ_Z3M4zJt41kC{f49?)o6B^0x?;49N=$yIp;TMwJ^ zM=(#E#j$o`#95Z>0b70)ou~qkZlnU8mdKI;Vst05ZLDX8-^I literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r13_c14.png b/assets/verified-tiles/t_r13_c14.png new file mode 100644 index 0000000000000000000000000000000000000000..80e810f36600d4128f6974306d7babc5c8c8d8e0 GIT binary patch literal 298 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1FhY zi(^Q|oVT+#_A)#2FyEXfTz<4I-j!Y2i>ZQde%7aK*DzQLVhFiNh-_ zNF?y)DK2H5*v!HsPhan2(DS*{E4Xi$(dQrOr*0jHijt&LkZ jnQaKW#&!)!axdeP^?_-RmmIhY^e2O-tDnm{r-UW|Q!#Lt literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r13_c15.png b/assets/verified-tiles/t_r13_c15.png new file mode 100644 index 0000000000000000000000000000000000000000..3c53ed19612891e70c8e7ef286532a59d4515730 GIT binary patch literal 289 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1G&+ zi(^Q|oVT|(<{ohnaK5YBE4pD~LlKEUH-%6U#BCcV*;=W1p_-{Gn3 zJ_+QFa!ELXL?JDSXNz6Rs>g z!Zg`>PC~<^b`jo?ZyOFVddo-I6#RV5-C|JKGch2o&sgNrm5s-oW?SD&=$L$5hPU+F lj>C%n^3^u^3(o&%C^*0HlEC-Woj~s~c)I$ztaD0e0st{5bs+!% literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r13_c2.png b/assets/verified-tiles/t_r13_c2.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r13_c3.png b/assets/verified-tiles/t_r13_c3.png new file mode 100644 index 0000000000000000000000000000000000000000..93a38e96fd0c87c0d2ba4d4facccc2cd27b7f559 GIT binary patch literal 255 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP;jHC zi(^Q|oVPc2^Bz_ZVGVee)Fm=gX>vvH8>gwfkGduuvYs%H>9kX)y`_8AT+Kf<`mN4D zT@di1<73!)o5U;k^b;5ZnO-f_`cP-r_RRF|?#*BS-1>ZwiOtg?r192n=1VbkRy%d> zX1?$E@Rlp$fDU6Q>$AUB^*^l@q7NuB{+zEh!MyI{w>_*rLII%(yFSQH2s;-ndqJ-a0rcZ{itMMRXteh=fvdE#@YwD*7h zE-j#|;O!97xM$Y6@OtJ+tUN*!zJ)ZJd^&#rezb!&qbuvJu6&0-pZ5LYa^XH9B=CHV uL;cHBpMBOIxzceyuJIm|73Yicm`3)c$2KbpxeG9Z9N_8d=d#Wzp$PyX8(I4R literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r13_c5.png b/assets/verified-tiles/t_r13_c5.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r13_c6.png b/assets/verified-tiles/t_r13_c6.png new file mode 100644 index 0000000000000000000000000000000000000000..43b8c655a089b58f66470b1d78b078dcf0c350dc GIT binary patch literal 353 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wk0|TS5 zr;B4q#hkY@HwqqB5MWvPdX++`xSn%k(n^-71+c4XH*qlP z@Lli_ym0nk#iR&I-BWu#hz|Ge&-St3j z_Mepei5{;#U%NIeF0e?DwPsq{w`10F^Eph6W-@##fw=$x literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r13_c7.png b/assets/verified-tiles/t_r13_c7.png new file mode 100644 index 0000000000000000000000000000000000000000..d59e04e9ffe7b54246f646262e2aac40bbc5125e GIT binary patch literal 234 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP;ic? zi(^Q|oVPa)@-i9nusB@b8v0=YmzJmW^>d{Trq9kZb85yY87ePrh}f3A9ArEQBy4(e z&3f*xTd%me9a0?PqnIkYe|)aUDfMEg^I>~(-b*1q?uX3xrOR0oj3fnAFU+qx@M>24 zJ?3+~db$kGY+HmRsvNSL4r^bSckt#JMnjIRo(66Yw{agay0YzHMEmXf0}q{-l>ZZ~ YVs!tJ8S+*lXg|nKPgg&ebxsLQ05yD4K>z>% literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r13_c8.png b/assets/verified-tiles/t_r13_c8.png new file mode 100644 index 0000000000000000000000000000000000000000..8b30d1e82ac7602c6784579b2c0cfa92de5af5aa GIT binary patch literal 227 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP;jcJ zi(^Q|oVVv3c@Hr#upGP^DrytZD3p`1oG&0a#m6as^3VLWTdzfBqY|&*TlXC=O@GO# zYr9}6`<8w4uOm3;zJK1e`AfqzxeJ$=qpBRd`7>b3h!p(Gu(PRE_oa9Kbf5znJYD@< J);T3K0RYC4R%QSI literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r13_c9.png b/assets/verified-tiles/t_r13_c9.png new file mode 100644 index 0000000000000000000000000000000000000000..d30126967ac02ed9b6bd0e1baea5fc1e792e8455 GIT binary patch literal 241 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP;jxQ zi(^Q|oVPbN3LY{LU~#zql~Y$hBaAU*k=cqyy(^4YWi-`}xgCCUuI9;!O)CHIZ({^% z0)hJVuVzg>#WZKF*pF9b4u3yzoVoZZ?)>lE@cHNa*Ih0@vW4L+-;6$o=w)($H?2PW zzGdeD@92g^_9KE4?;3WnwC{KL!?xQ_L2BVT;hwM^vssfQUM)K)(e5oL(CFdWq9mj} iGofXXs_41x$sfh#zVUt8Taob^WUZ&GpUXO@geCxU8(hu+ literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r14_c0.png b/assets/verified-tiles/t_r14_c0.png new file mode 100644 index 0000000000000000000000000000000000000000..1eb338b97af27399e146c61e24da97d88d6fd188 GIT binary patch literal 229 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP;k1Z zi(^Q|oVQmu@*Xk}V7)N=^|B9ag0jjLGHxd{rcB96ipmg*Y)Eo{@44UW>3nNzCZHY& zNC=v_G*|VUA7dudE&p(Zaw%Ee>8Uq;G!|UGSbv4(NrLu=9rn97t=r!JruKii6XRST zhp5JHaZYPXUme-5UGRlbB*51}I*Zk7r{B~72X)~IVGDLLUsAoXhpDnJ{R8WDql}6P SKaPN$&*16m=d#Wzp$P!Ar%z1) literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r14_c1.png b/assets/verified-tiles/t_r14_c1.png new file mode 100644 index 0000000000000000000000000000000000000000..50e966db1e0bef0b30b8032d8e3a657e764c3e65 GIT binary patch literal 239 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP;jBA zi(^Q|oVQmt@-`cYumn8&Byx}8Vk%4jWI+klrQXLD{9ftF=%mus_zIL> zAV5!hsZ93Eb$XT#*BVNmbMn;6XWyLVkzLrZmyP$ud)vmsnqxB`Gk7u|V!6~<@1UuA zZq8w04c?j-W)a?w{k{s%-TxSUHPtmb|9M@F-FpUCpgJ$-{|&#M_U7+hzmqeBeTK<` bc@<3g!c(H!A1>c~6=bQWtDnm{r-UW|9!XSI literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r14_c10.png b/assets/verified-tiles/t_r14_c10.png new file mode 100644 index 0000000000000000000000000000000000000000..7761805f33485c6bd1ea1a95c1e67fba7ae52020 GIT binary patch literal 282 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1FbW zi(^Q|oTs-81rI1N95}G!^|3COcUjDd3Xj>_?kg*-{Wy2}Qsyls4b%88Tw;u}a`0x) xc*&qEy8tG5>%WaYx)@f4lnYjcT)}IIcxMDthL&OfSD?QbJYD@<);T3K0RYh=VoU%4 literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r14_c11.png b/assets/verified-tiles/t_r14_c11.png new file mode 100644 index 0000000000000000000000000000000000000000..c2a95f1714783d42fcb5b89a2b5139027f838642 GIT binary patch literal 335 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wk0|O(Y zr;B4q#hkY@Hu5$bh`8*Pl)j)CSh@bpLo=_5R>B6&>^sh79t`^OwVBhU&VLt|rs46s zoPtb1(}0FEt4viEUDs#epyFT~>Ts;_bMn2Vr=^v61ULiyMJIgk^q=f~?fu-m4v>Nn zhxqb)YbI^(OP;QNF6*2UngGuLd))v4 literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r14_c12.png b/assets/verified-tiles/t_r14_c12.png new file mode 100644 index 0000000000000000000000000000000000000000..c03a30167fd50fadf92ecb903d8776cea049f344 GIT binary patch literal 326 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1FMR zi(^Q|oVPO!`C1eNTzB4_cc`VS!aaKP(QEe-)*JB3%5Jkb+p;6@PNn|OsjVOW)-$yM zbpb&Eqml2{(0}LHTkG8o5|kJptz`Ptw{_~h4NE_iurMoe3iyi(Jnnw|e43Xgd+S9( zo(>fUn@|O5=QC?s3XQHvotx0ZXv}$Hp0+|&fu!^+*`~wtQ^4BJi=LS4ygq!|LhmZs z7RK<&o(JCSW^$GFsk8mE=CmN2icr8xhh2qiIrFz}yCnN|YU$65?|1KIl4e_@lJGgE z(N)($|HGO#>mL~g3KJV%?P8MJdtkHFJN6D%kj~g}h}#bd-(bAfgoDqR4{?~PON8x6ZRBv) z<#m(Et91}jS}S;Jsn*8FNiu93IHUvSIoxR|VsU2e;z@Jw+nicp&c__#^7l8$lLu~y Z>hC!DIDOl8qv=2{gQu&X%Q~loCIFw``wino#Ld!%;dNW P=p_bES3j3^P6)IPV_Z|D4f+xi8y%Zn*?AO0raYK%=qNXjambwq8xE`T zOEh|Twz#Q;ss9Syc0Wc+KrLa7!w$yB9Bg6|CKBu~8Y&h|jo0SA(fy-oeFoE`W^JHP c7+%L0vIipa1{> literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r14_c2.png b/assets/verified-tiles/t_r14_c2.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r14_c3.png b/assets/verified-tiles/t_r14_c3.png new file mode 100644 index 0000000000000000000000000000000000000000..9d0a058b76db016b533817e7cfab37ccbb6da463 GIT binary patch literal 292 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1F_k zi(^Q|oVV9E@-`a?v_72ude)i=N~LTkRMt$CjA-oQeRE2+wcH}=P1A`@t~`I{f4Rjm z_ub7t57n#7b06=UuQEBlOK94T*_ZC0-k)A$KZ%2R#Su0Q(G70}o;{qpWXtBYljk%3 z{O=Uu>F<4$C&&reerjg9meia;SX{I*#bP@?_&gd1qK|d ZwlkTf&NyHZJ*gBV=IQF^vd$@?2>_nAZ+HLz literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r14_c4.png b/assets/verified-tiles/t_r14_c4.png new file mode 100644 index 0000000000000000000000000000000000000000..41848ff296984095e6f3e329a063463ca831e6ae GIT binary patch literal 266 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP;if@ zi(^Q|oVV9E@-`a?um(IUnk*W$ByHZC$D%7F4vH@Aep9g0xiMwp3C4Sq*STK%_@2jE zE`MWa@JipUSFWdRwabrv{dsB0{}l^EuQkkOd7|Ba;7`qwu(!4!wtF+XadIdd{QDp^ z$4Y+dqFi6RSjxEelKdW1P7hgkpqs%!;@msl$c%UI`O@BKfCM~U{an^L HB{Ts5Aev+Y literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r14_c5.png b/assets/verified-tiles/t_r14_c5.png new file mode 100644 index 0000000000000000000000000000000000000000..ab3742e4e9a2e04657a1b1a89ad5b04702e83fbc GIT binary patch literal 431 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wk0|R5C zr;B4q#hkY@4gC%qNVL{!EUW*-I$@7dDPyOh_t67_8?@N`9`rIR{A60eeTvcQDTB_O z2kDD93Gz<6J7b#urR^#c=kDA0{a=Wwl3#!4&)4k=4Tl+>Snf>ckbk_aLz9o)vh2tz zYp+eh90rdVRGA*1m(+jTuy()KjNSE_XJXhD9F8!0u_(zdn39mfrIBnf?flKn)%-IA z5)Lq4wscR(+QZ0HA+x~c!2AOC9Aob5mwq!VgLOP=lKrr0pHIeJ&8-qF0zefGFBq1x zv}!KsaV$Lh{LSOPrH3xx^>wP-JLT3_A3HX|1CN20*XcJEZ|8iNxI*cC&ik(*+ktNN zV!0F7^8If1q1&I2I)3{7`OLSt^Ha(k-m|+k$nsrqRTc;{Q@o#$clg@<2)~zAKTDe# znwY0>oOo~j;Qn7R4vvIE2L+~Sd>m62q;jzwTk!W={r{E8UiX=+>rP)X+-K8*s@E~Ba>3~@6t^+&<7!u(3 zjDTNwe+&>3pdcW0fKr0O6i~*XWN;2}S1S8+fWv@_1h|w4xP>DatM+t1QgQ?w22>=# zfk3sJ4hVH~9pEsaA^|Q2f%@gBYwG>^aiqEXlOs@Lz>x&hw~RpZYV=a!3y15mT6({- ze3}#nSQ4NhU?VzU`0n&lA+zCnsQ%+HQtW==^K<(x-T?y!bR=K^f$mpk=NR362lNlK=n! literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r14_c7.png b/assets/verified-tiles/t_r14_c7.png new file mode 100644 index 0000000000000000000000000000000000000000..2f1d2fffab3a81d344ff43b25798ae76a5524133 GIT binary patch literal 313 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1G>< zi(^Q|oVPP}3m!5Ma9OXXn%CG6!5VNfv>{1}D?t2RL)JCtG;8M5FWB~)Zyq)naTSJn~q>V+z%i&9di?B$rf+5>ivxVR1yx+%uhVh>Yn+2!9>J7!* z9mywlvK^Hu`Npu3!*ce53ZdeAEJqiw_^h?&^7)6emiM;ZX4Yc!QCSeg6dZALeYJxL z(A2aaEH2xOWm zr!Xrajq8Q}@dp>rZurf*?y}vd$@?2>^(M BaryuN literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r14_c8.png b/assets/verified-tiles/t_r14_c8.png new file mode 100644 index 0000000000000000000000000000000000000000..3b3c45648cf1b4b7ab7061162def41243ce15f3d GIT binary patch literal 265 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP;j@W zi(^Q|oVVu;OPvB4SPx!x73LPXa#5I7fst{?fh+wzn)mJ&FT205zW;T~OGaJW1xwkt zd}){_ci|FqRF#7_e+KD-cKhwGpTyLD?QPk9KbXO<|5nARV=+B@?bd5iAmY`Qe~hUD W-G{ek&e;I;27{-opUXO@geCw`Y-ZH} literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r14_c9.png b/assets/verified-tiles/t_r14_c9.png new file mode 100644 index 0000000000000000000000000000000000000000..14ff6d1aa3b579c762b91a641d96f9a0168a12cf GIT binary patch literal 306 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1FST zi(^Q|oVPP~3o&ChSHeQ>4zn3EnU5$;naOfgW6n+1BSuqhvK_U`dBNx; zU?`%f*eN+{fq*M-XvB#}t0fu#F-Aw*l|S8WtAAM>xY*I)#buJ^u$04W zmxJwQ-gVE;Db|-K^7HNJV33{51oR#Q!-Tp<^NS12YK_-juLtoxUHx3vIVCg!0Aav$ A#sB~S literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r1_c0.png b/assets/verified-tiles/t_r1_c0.png new file mode 100644 index 0000000000000000000000000000000000000000..b759a0d4b8d2029afe388bba92a471d5f0c2f9bb GIT binary patch literal 294 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1FJQ zi(^Q|oVPbO<}y3-xLjP_9U4=Ay{UNnBd!+T(1Yf4B0Cp!^KH7%l+*BFl5zdEw@+r@ z{2lu}kN@k{=h0V}F{;n!l!#ZbPS80R(^$y1n7K`$OQ=VrPrO62OS(svkDo)}W!9l) z4%W_APPVQ#F81#4ms|QvZPvbBpIpcrp{5X@aFa2z>9ptx$(ZAZIp^Q}KcDYHgCXNj zreyXM&OYr4#ug5yZnt@JNy9Y03zrz9 ztQ@@AGhQ<2$}U*SyoE@?um5b*(=qkDw#Y-6o4xjCB&ONB))kjwvG>aaxKsAZeaEKp Z-x0AThvep!T?BfQ!PC{xWt~$(699k3ZP5S# literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r1_c10.png b/assets/verified-tiles/t_r1_c10.png new file mode 100644 index 0000000000000000000000000000000000000000..f811d459da500739dc18c06ade91dd9ad453b76b GIT binary patch literal 289 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1G&+ zi(^Q|oVPbO@-jK{xLjO)I`o3f)(gBRpDk&TpXk`MgM%?&)jXl{?M(aI+diL_sajKf zeYsWX&sDcf5}q3~KITqg?@^thZE!B3oL9) zLNXxX7Y!T>_x20P1X;u-%viYNU}F1WW;Ov%K`tR~VIC1)Q9dz$y$K0R{M8*NEp$mf h$tK+QEzhckd9Faw)g}#|0-*O8JYD@<);T3K0RXbTXovs+ literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r1_c11.png b/assets/verified-tiles/t_r1_c11.png new file mode 100644 index 0000000000000000000000000000000000000000..16ac758d91f310189e29e47af897738a1fce1aef GIT binary patch literal 295 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1GUw zi(^Q|oToPyG9GdeU^uu|J2c>&Inxb`92wT5mk$LV>kxk&o`3)6*>jf|qpTdf*)v`; z=*liw%DkndVH)2BA_cE~-j|+^sqwXi+~&L1U zGH#E0{W@U#>id8Bb51cnVSB>4gnbET8dnOB8@mgKE2kURaqc5LM|qF&wX?Hyv~aL? zwsNv{wQ+ra9Z@r1tmaGcivH`2w;6k+H`q2_WZtG`vFyOV{^WwWVg(F487rAyGG;c- zWRh&Y$hbG^hk#RH)5Jp`nGBr^n>QYQ$jGSF3^b2dO+v$JMZtz2Cs>7gbWR2=+Ndh+ lW3g+=;m+gNzy4>QH^afTbYf4=RiFnMJYD@<);T3K0RW&bZkqrA literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r1_c13.png b/assets/verified-tiles/t_r1_c13.png new file mode 100644 index 0000000000000000000000000000000000000000..1a4fd1c053fb42f5229f4c586b6cec9ed5704f2c GIT binary patch literal 312 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1F$f zi(^Q|oVT+#@*Z~JVXj{{U+HwFSl;9|+uKvTq@^|gG&J5gVY}d-fJ&g!OGB~ybNc`F zr0+Ldcy8&UH@dxvDwO}UWWW^f`4zRHOJ|VZ^_`}VQKUF(SWC&(-<^EA{ ze%-e(Z_^q)99A$~WJ+Y~P?QL8IFN9I`G}H;nd3&T_Gkwg=Z8`v&kG(fvnUElC^~ks z`UOl_)F>*prQ!l>i-FJ-Ma5p$+<=b7jgO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r1_c15.png b/assets/verified-tiles/t_r1_c15.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r1_c2.png b/assets/verified-tiles/t_r1_c2.png new file mode 100644 index 0000000000000000000000000000000000000000..32f2a4b1b0019c892a613ab4090fd2466486adf3 GIT binary patch literal 293 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1H5^ zi(^Q|oVU03axxnVxIA3#9lB$Gw&Tv|LRPnx+7*50XC8d8|9wJmW6Kun&(F4bKi{|V z*)4w4V=n`4Z@&MO+3YDp5%VXOOU##8j9HD?7BefgEMie^eaxEF_J}RH{V+3=i&IO} zkwYxZuFkF1mSXeyx$o_gd-c5ZKncTcX#?BFSpFHa9^`SIsh4SfoXE&NL3)Dv1i1-n zGc+d{O2}T=-O8^hqAH;&qc31AVlH7VBPXD+NnoME##TyG+3zrBN!cw+&1CEYdXd4?)z4*}Q$iB}99?JQ literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r1_c3.png b/assets/verified-tiles/t_r1_c3.png new file mode 100644 index 0000000000000000000000000000000000000000..913633b1ab68b1f226fa0bcf67569b38d39c83af GIT binary patch literal 315 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1Gp% zi(^Q|oVT+N@*WQ0aQ+|TbMbFPZ}ELZoJF;(R*lKHgM%lFE6)pvqSJll+qJ?gIb zlD_BHPR{LmqNc^dzu(KNBzz2HbmTTMR*-1ogO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r1_c5.png b/assets/verified-tiles/t_r1_c5.png new file mode 100644 index 0000000000000000000000000000000000000000..87a4e8482341db2d0f788ec33c977222a54558a4 GIT binary patch literal 330 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1FkZ zi(^Q|oVPPK@*XzeVX>UP%wx8$Nn6*IiyU!{(o4Rved5TuTysi=?ahILr7t)N8n4^` z^q*N8rx{zaZ0&cZ1{UTPmP^tt&yC)eoq4)??f0ntb__ZO4ju_Nul*@7R$y3gph3cu z>Eq+0j0tUwPE4QW&o>-@TeSkB)np6Hva0Lp@~JIf;}`-G8zwm1oyU0gbKdR!-V6*f zY#f{x#tuA=>D(QrFMcp2w#cY!tl2P`)kUJ{(t?h|=WHFWRTm1ZjA_|YE)-qg&i|Z+ znSqOkLnUAa<3RzPoW=xRu^NZN9I0~>4s)e%a!}?;y`)fhV<-EGDt$hsuXkKuur8Q8 Wf4XTk_g!E(FnGH9xvX9|PH+jx%yeym5P>3-03|0N+@usd#*+oXm?Oc$7*mh-NV%{<4nRoT-a zkkKdd!O7iOODtK}{B_`TVBN5S^;WR6{OrvR+Kjzi8QXIjCH{Wc`I;@_ccV}PmjibK z?*XNbSccmQ&lq@|X0RA?ZGNCraAG~7<8Hv#SfTCfRx-+=?Jv2 z=6+x>WiDHx%(-{W5!Hzgot6|UABhi7`u#h(q0ndzuP2ie>jKt8(uy{dxYi%};G?%k k_=xk#bKZg5O0<5nhPdYnp41AJ1BMfWr>mdKI;Vst0B8w%&Hw-a literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r1_c7.png b/assets/verified-tiles/t_r1_c7.png new file mode 100644 index 0000000000000000000000000000000000000000..8920a07612ea75577250cb4d308f2598130c1da7 GIT binary patch literal 336 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wk0|O(I zr;B4q#hkaZHu5$*2(av5xBAe^>_TQf4@1=erj^F(elbkH?o0|+e|$y2;n?Ez31;ywIZc;4rH(^ zupYDLm8b|dekS#yGFIJVseA_G2IdJℑRQpV>HCNwMlUB(oQ2aPeqQ0ZOKTC08(N zG+D3~@GRnYP;T*?;Jdb9wy}E?&^885fh>lu1dv>t9Yb%xZszi3!e^oq@33wKjl0JvlLf@erQ_SBs$J8ID#(O`pzIL(4OqeAXQLvxFAMc)elY Y$Goy|*PUmpfI-CI>FVdQ&MBb@0HslJP*4>Pea@vxdqV0*#*DLbw_-RjouhyzSa+a_vW$Uj>Rk!@j<5EKbNFvsyB zbC00coCO;Xd5Re%YIruQ@u}A~Xu3>tI}wsp`M__3ot=IAYnEbP0l+XkKz>jfT literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r2_c0.png b/assets/verified-tiles/t_r2_c0.png new file mode 100644 index 0000000000000000000000000000000000000000..6df96e775e45a4dbd9c33937249b74e031c8b740 GIT binary patch literal 296 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1F(g zi(^Q|oVT|&<{mZ>XbU`B8eFh{%>%pDDNK&K>ObxrTe;?xrd;D|R!61&|9c9K^5yn)ohlBUeoV(}BH8ru)X zv`=PN5qNo-bApS;#0aBvD5LS@RU0Xo^X2Q1$<&r mHP@)DlW{9*Dg?v5uUY2LeA7_g*d7WB3kFYDKbLh*2~7av!gJLC literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r2_c1.png b/assets/verified-tiles/t_r2_c1.png new file mode 100644 index 0000000000000000000000000000000000000000..6979036bb8650225f58ae486b8219fc00618939e GIT binary patch literal 149 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP|)4e z#WAE}&f9a2ybTTvM-F_|XHZcPPBF1eoAht@^L_X1w^uF5`|5D_RpYL!%%!W@Uxo2s iSu3|f8mJWkHU!rQURvf8z`y1(NYK;O&t;ucLK6Tsq$|k) literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r2_c10.png b/assets/verified-tiles/t_r2_c10.png new file mode 100644 index 0000000000000000000000000000000000000000..4f2cffa36424616d9b6741f7004cbcef21548d65 GIT binary patch literal 294 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1FJQ zi(^Q|oVT|Y79KSaa1Fe^HFU?$E0gkEjySXCXVeAs)E&5Zrl|k;w6Og1rM5A~<@VX7 zaj!P7uMd^4-hbu&^Zk1o+E0rc)HS|gOcp+)Y0!7@3*%xzFZCH=7UhjGZAH>&N-ZiK zm?qwv%i!4})Tt`$qcJPQVq?WKCdr-@qbG>O^k-hw9$lgu?N7d+wh;?t;Xp2R)HX2BCCRep_~4kwwt^a4KZ kk##F-Dg?v7S2^pLBT5R|Zn$`*0R70|>FVdQ&MBb@0GKIp0ssI2 literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r2_c11.png b/assets/verified-tiles/t_r2_c11.png new file mode 100644 index 0000000000000000000000000000000000000000..6979036bb8650225f58ae486b8219fc00618939e GIT binary patch literal 149 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP|)4e z#WAE}&f9a2ybTTvM-F_|XHZcPPBF1eoAht@^L_X1w^uF5`|5D_RpYL!%%!W@Uxo2s iSu3|f8mJWkHU!rQURvf8z`y1(NYK;O&t;ucLK6Tsq$|k) literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r2_c12.png b/assets/verified-tiles/t_r2_c12.png new file mode 100644 index 0000000000000000000000000000000000000000..4e71007ab03a1998cf00eb397474e9c80adee946 GIT binary patch literal 293 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1H5^ zi(^Q|oVT|&@-i9num(K)BofybdE=OGRn+wPVlOlVMD&AxU4E&z@$dbmt3K~h|Gg=H z=l`qw=6&9DfByeZFSYa+)G|I5&q#N$WVx*yu&wvDbWmBQx8z61@x$yQ3W82c1ZEmI zv3j-&Y5VBSd9Zx7#ldGR-NHG38(@qAi-S*D+J$5Mpo}~74}16-%t^2~SkUy4mdKI;Vst0DPQt&N-ZiK zm?qwv%i!4})Tt`$qcJPQVq?WKCdr-@qbG>O^k-hw9$lgu?N7d+wh;?t;Xp2R)HX2BCCRep_~4kwwt^a4KZ kk##F-Dg?v7S2^pLBT5R|Zn$`*0R70|>FVdQ&MBb@0GKIp0ssI2 literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r2_c14.png b/assets/verified-tiles/t_r2_c14.png new file mode 100644 index 0000000000000000000000000000000000000000..5522e3aa15aed40abf1fb6f0ebefaa04bb04882b GIT binary patch literal 392 zcmV;30eAk1P)&ufFbqURFDy(+@6TaSKZ@tI0lnVa*rS}jB2q-|XKzKR> zyk%6iLjKw+v@*e;Z`J>M1_%TM6d*HOVD0SV{)HjHP=H|p8z=+To$$|JmRkh~5ENio zKn|1v(z(A6HwXy?1QZ}xAbe~YI{X|UA6|zcU_k+PDhp&Md2fl~Es!B#Ljiea3n*<+ znFEwTNavjd^P9Uss~!Rh3NS2C2F`#KV}+tE? zphAG60G-(anNfIS7sxC_+q~OgaxdKa00=M?U|7Hg$^hxa-upp7K>>yZ%7OkDxH?I; m&|BZS9s&df7#5J%GvEgvlP2$vc7nG60000gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r2_c2.png b/assets/verified-tiles/t_r2_c2.png new file mode 100644 index 0000000000000000000000000000000000000000..fc14a0e6a1b6ab52e9c9a785871dec062a7ec55c GIT binary patch literal 296 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1F(g zi(^Q|oVT|&_A)v0um-#;5`EV%rng*FYlB)T>;E7HWe0&h6V>9^mZj(XFJJk}=G|GF zx7B&}TmPT?nz`TZ|I@pnaSp$kPU&Ab*HFZ@Im{U*PVh)TE-#&3pg2lmtriUztIopKK dsLy#|zpXbU`B8eFh{%>%pDDNK&K>ObxrTe;?xrd;D|R!61&|9c9K^5yn)ohlBUeoV(}BH8ru)X zv`=PN5qNo-bApS;#0aBvD5LS@RU0Xo^X2Q1$<&r mHP@)DlW{9*Dg?v5uUY2LeA7_g*d7WB3kFYDKbLh*2~7av!gJLC literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r2_c4.png b/assets/verified-tiles/t_r2_c4.png new file mode 100644 index 0000000000000000000000000000000000000000..33d776daa8de668ff97fe3c634bbe9055503392c GIT binary patch literal 393 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wk0|TSA zr;B4q#hkaZ_vRik;Azd*^IOQvl6x@rQc8pNox4(+k-NCAq%ke)t#A-IT5fUs7tfwk z%j)IsRjY8vyG;6jWO}`s!T!Hp5%L?i+C7T8FLmVe^o!043JVzyGQB)6DWJP}74Mtm z+zY2$c7LAxYkGQvgM$;J(Pq}14gJT(+Zfy#`&j?DNG3=N&fl-|o>##kpdp#@W+2;% z2mk7JIeI|N$vl1G-E)S@PgXpP+*}`=BM&q^S*+@p&)D1`%6j9BSir3XM(i5R6V6$4 z-fG_MuwITyi>p8T|ZssSb?|Jxp9;CsG^~S&U;B$SmZ2)qMTo;jNCX46ck; zn^}7TD^kS`rY$VJm%E`w{9P>riv>{o1NBo3l1Hxnc64wBy75)tKk*%Gp5F|j?(ddk iVqvuqoA5vVfceq$TNs-2W_AL@mci52&t;ucLK6U2|ChS} literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r2_c5.png b/assets/verified-tiles/t_r2_c5.png new file mode 100644 index 0000000000000000000000000000000000000000..d14fa356644a47e04bb9bb7f07cf320e163bad95 GIT binary patch literal 318 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1FAN zi(^Q|oVT+!iXL|0aL!*hTS+(Cpso8#V#}Hbyel>{YF98lUFvntwaWhA-s4P09!?cK z-TTvRzC;(_n`RYvJ80|gpvSNH8JhS6lm!YJ6b?GDw(zjoIY=z*6c!1qsB^Ta{$IA+ zfwAE-<53O^nScok7BjW-SlKNwaOxA*S+ij?x5()Un|U|!y???e6<*Jxgv{6A= zWMRexuI>n%9o!v L^>bP0l+XkKkY956 literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r2_c6.png b/assets/verified-tiles/t_r2_c6.png new file mode 100644 index 0000000000000000000000000000000000000000..075ce617fa4a547dd13d02df07e3c3fcc8a63e5e GIT binary patch literal 329 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1G{> zi(^Q|oVT+!@;Vs`IOps69~8)OoIHuuh=p0<7S92(>zkYEy_FPq$)BiiUH!s4Uj6r* zJE}`2-w!mlw)qn!<;cjw+{5C+Z{QoSqhX`tL}niWuSpB|Wn1;%-b_q6lEuNLAd#S= zP}PvxbcnTww@W6WDL|QXmd2eO+%rxGJT}W%ceuB*A)Q}GqC-Vk@x7Ih_5F9U$5M7k zH8F9pNpN<2-4WT}4JV!-y#9D9lM2rY4~3VEQ`Khda5&0Vyvu(w^PgnL6?$cIA`S)z zJRIiFKRLDNtwGkS`{y6u4!(KQ-h+{g=fgT7jl=AV^VdOCxlcR5_Wi)6wL6z7r2&J1 N!PC{xWt~$(69Blsdg1^8 literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r2_c7.png b/assets/verified-tiles/t_r2_c7.png new file mode 100644 index 0000000000000000000000000000000000000000..1885340dfefee0142f6584066ebb253a69664638 GIT binary patch literal 319 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1GLt zi(^Q|oVT+!@*XzeVX?jLKe6`Gjx$WNj^?tR5PP%v(9)i@U%C?F4|*9S2-JM?ytC=! zGp~tv_%{Ce-R{E>#^A+J&0yv@hslENBKrbCC-oBn+ILp%2%6Cl!Kl%AgLwnzG0lc# zgI^3LPPt6w%Y=2-8oXnAYSeN&VJF{X+XXfq4_sHU%{%h$ym&a5uz)s$s(_$mN{f<8 z>y(HiPbLW8QEL!idSrr-vlox1;SvbL(6TM5=r+r<6fOA+yObZ@yyxq%hGB|BnQcO> z{F}ws&)mFMud>1KTeBL2cEduUjJtQ<*jwD*&DkN^Aar6odkuqKk~ELm0rmSp&og+s L`njxgN@xNAsL*&o literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r2_c8.png b/assets/verified-tiles/t_r2_c8.png new file mode 100644 index 0000000000000000000000000000000000000000..388320378b347528907db313db8d8952e3ef7a74 GIT binary patch literal 313 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1G>< zi(^Q|oVT+!iXL|0aJCf>jyWyX<2dn_?h-7pSfJqO&dMcOQsa=+!lOQ8?wW$U_&s+yR2U>= zC-gKNWaQ+O(wcB$!9!*tV4 zqNYH6hK!q^p7ZB(`%fNqp1y0Zs2)Rs)dH)2haCModSd(x0agk?&O)Yp(X3nyd&=2a zv=;0QRbX&<*>J-l!?%f%!HbVe*7@O1TaS?83{ F1ORm%YgPaN literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r2_c9.png b/assets/verified-tiles/t_r2_c9.png new file mode 100644 index 0000000000000000000000000000000000000000..cf822e34c6d21199271c5658868ae1d8e567a8da GIT binary patch literal 317 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1HE{ zi(^Q|oToPz@*Xx|a6P!a+%rM^gw9e~h3J-Y*6Cq!545ChzNEesNqF!@YW~LJ%mzK) z3riVynK(>mdvS>&R%(Gaa|ulF+;2H+EW%jTA_QN5+;{98+(>&hxN!(2NOr&lKa|Tq zm?Os)$Q71|un|J-=>yNSd5%!YeFar1aC6n;G;v&<3gZLUA%fL>?t MboFyt=akR{06uDYZ~y=R literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r3_c0.png b/assets/verified-tiles/t_r3_c0.png new file mode 100644 index 0000000000000000000000000000000000000000..71692a03f49f14fea0dde3e4fcdaa5fb44142442 GIT binary patch literal 328 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1F+h zi(^Q|oVPPJ@*Xk}arqxJuc^?6Q!nF1M$nREQ8kAxJ|8liyEwQxt$)V4b|i39n=n8K*90 zy7WM7#}sAnH*+UUXgC$f=*qo8Em2#z%DpC=kyAs9K{vqee8ZgL@Q(O&hu8Ac8rCpf zV7ke3K;TRs>pWY;FJm literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r3_c10.png b/assets/verified-tiles/t_r3_c10.png new file mode 100644 index 0000000000000000000000000000000000000000..81bdc4bd5b9585a1a1829bc021265bd2655798b6 GIT binary patch literal 325 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1H8_ zi(^Q|oVPO!`3@Nfu)L40V?F=Ty(!x2R>_~Xwt3TvGMu|Ow1vt(%-K@A>DFEAe3z$7 zN|HLQ*Yn@0DC_(8@1dix7WDC4!uxZIU?rl)X z^*CDLr^KP_37;%`Y8^HS9CYK*HhjafQ6%+7SVfhM*~MS%svw;U64`v_Dyu9g3UQFS z!*snUt#h%kkWhf7)`ASiYbrUZPVYPRicM%(#B_n_>2IDBmgTKKO4+vjOXNJE#h^Rk zECbKMH)0D;O3iuh9nQhILPj)T3qzWNAxk0m6vyii_J^iyELT~uf}t;`(fr9_TQ1Fu S&5wXVz~JfX=d#Wzp$Py$ba?;( literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r3_c11.png b/assets/verified-tiles/t_r3_c11.png new file mode 100644 index 0000000000000000000000000000000000000000..05383a59818fdd94bd8b28ec7a1057c65a0e2241 GIT binary patch literal 294 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1FJQ zi(^Q|oTs-GMVSKySPot*)lzyc&Dr0QELdVAW@f~tqj9g|UPw-!mNIWCX}DHi zw>i?v!J9qfC4(+hY#QH%ON>z@3$FeC`AixXQ|3GgnJ;(OmJ*v2wfhV*n`d*d&YUdaeO)Q<=3Q(3;3H?s zbN2*?=jMk0{q67W&v8J9`O!I{8$u?k3?~?-FjO(jQt)GxY2Ly9K&fT6!n#8h;s;I( z+++J_)lEmX)WUmKb0S+!i^p< XzewhgS}Vs43M2+kS3j3^P6Nm#w(V05R-|sSBRlE|@^tIpr;m&G(i)yxTiZ SU7n!=vd`1i&t;ucLK6V^giQtj literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r3_c14.png b/assets/verified-tiles/t_r3_c14.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r3_c15.png b/assets/verified-tiles/t_r3_c15.png new file mode 100644 index 0000000000000000000000000000000000000000..4d639662bc828a8b233c146ae99ce7f0e3e2a6bd GIT binary patch literal 186 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP%y{S z#WAE}&f6;+c^eFPSPqDT8-o0AX&GRf1`&t;ucLK6TW8aYk? literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r3_c2.png b/assets/verified-tiles/t_r3_c2.png new file mode 100644 index 0000000000000000000000000000000000000000..0e1268c3c29f784ac65f60ec0b4a99e3c5874f31 GIT binary patch literal 334 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wk0|O(2 zr;B4q#hkY@H}W<+2(YYty=uXn^+#Cz=2-r0II}k3P`TlfXTsc)2R+YtPglyjd3Sew zTgSxrQ9qWfyESk2tNZmgs+}0zBn8T+9hkI0lhJ`~0m}vE3oM0P4~uo#LQ4UtIxSho2;)7I<=hFLrgoLiV}7yP>r@lB{< z0;5Lbj*09p?mxeOxiN*|jjidy@TrV%oj6^-A9!=sT!&#YP`OWig@b0RPw6i9DJ;I+ z4ikZT7O^kj6kE=)y#HWj-NcnF3MmX;3SSsZ4i*5N!=r4-7hm&Bn6v3zaBMuoE@94n dpQiFeFy^vYp60oA%@-Iz44$rjF6*2Ung9$pdsYAd literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r3_c3.png b/assets/verified-tiles/t_r3_c3.png new file mode 100644 index 0000000000000000000000000000000000000000..afb4d3acd28a297c1b4d01abacaaac0140a57b41 GIT binary patch literal 230 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP;iE) zi(^Q|oVPc2^R^i9Fa$jNB$AVm+TByEY;bDol$=ScJ=+-$9;}{Jo$@ERjS;8;0xH&Y zY_!!>Nm#w(V05R-|sSBRlE|@^tIpr;m&G(i)yxTiZ SU7n!=vd`1i&t;ucLK6V^giQtj literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r3_c4.png b/assets/verified-tiles/t_r3_c4.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r3_c5.png b/assets/verified-tiles/t_r3_c5.png new file mode 100644 index 0000000000000000000000000000000000000000..87a4e8482341db2d0f788ec33c977222a54558a4 GIT binary patch literal 330 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1FkZ zi(^Q|oVPPK@*XzeVX>UP%wx8$Nn6*IiyU!{(o4Rved5TuTysi=?ahILr7t)N8n4^` z^q*N8rx{zaZ0&cZ1{UTPmP^tt&yC)eoq4)??f0ntb__ZO4ju_Nul*@7R$y3gph3cu z>Eq+0j0tUwPE4QW&o>-@TeSkB)np6Hva0Lp@~JIf;}`-G8zwm1oyU0gbKdR!-V6*f zY#f{x#tuA=>D(QrFMcp2w#cY!tl2P`)kUJ{(t?h|=WHFWRTm1ZjA_|YE)-qg&i|Z+ znSqOkLnUAa<3RzPoW=xRu^NZN9I0~>4s)e%a!}?;y`)fhV<-EGDt$hsuXkKuur8Q8 Wf4XTk_g!E(FnGH9xvXx&6;IeEhuz`>rBFJwJlv{H~-G+ z$yYaizy9$VzNjYczlIzZ3m8`4WO`q6MWUEVZhQ8{0)Ytu4I3PO#WH)fM{jm`3Fc4J z`EYXmqKDT+HhkxHa&Tk(wVJgpc(LKC%?B75dATIAwl$o!+wuCH@SDF)0uus(+V5>( zJ7VV(Fqc({g+)YQqr(C=m#%~b+()EtKe)VI_{{C3%mRS~4Tp#WD;O7XNX0sAaZKhD zXr7QRB(iuzy12mU3F*=zuQxoGTdmdKI;Vst0J(&T^Z)<= literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r3_c7.png b/assets/verified-tiles/t_r3_c7.png new file mode 100644 index 0000000000000000000000000000000000000000..988a564edcd129ce011109636c40be07cff8d5ee GIT binary patch literal 341 zcmV-b0jmCqP)>YC@VTr64EE+1C>e) zj%;ZYkg!~IH<6ZKEbn@4ty$%t`$=oC+CK{5bbwYVF!Wc|jO7pKX_&!EKac|SbbyLd zz&BK~Hc)_x4iFTW{xl%RM>S)q0pIs!1}ptQ3J`RFpg`=W0k7^ngSAEh3eeF3YKj7R zgA!KyK@=e906~F31B3_$Q$UQtzy}B;6gWZcYK6!2R7;=$P6r4II2s^C(3t{a3_3nQ z7@_e1?hGfGu)<;&NGwBQ8%(Uj;vSGVh=_|&+VLdzxZl(gD1g%ef&xxNMr4GXkd#P? nIWakr6U+w)FOm|Aaw)MNf|P*4>Pea@vxdqV0*#*DLbw_-RjouhyzSa+a_vW$Uj>Rk!@j<5EKbNFvsyB zbC00coCO;Xd5Re%YIruQ@u}A~Xu3>tI}wsp`M__3ot=IAYnE>WwZk`LZ_vKh{^NU-o17G+9v%QIo lOSm;ePaKp7>P7-bwAmNuZk5wt;2jMT^>p=fS?83{1OQyCDRck; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r4_c1.png b/assets/verified-tiles/t_r4_c1.png new file mode 100644 index 0000000000000000000000000000000000000000..6979036bb8650225f58ae486b8219fc00618939e GIT binary patch literal 149 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP|)4e z#WAE}&f9a2ybTTvM-F_|XHZcPPBF1eoAht@^L_X1w^uF5`|5D_RpYL!%%!W@Uxo2s iSu3|f8mJWkHU!rQURvf8z`y1(NYK;O&t;ucLK6Tsq$|k) literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r4_c10.png b/assets/verified-tiles/t_r4_c10.png new file mode 100644 index 0000000000000000000000000000000000000000..82228a94e293f2548418494c2981c631a7228527 GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP|(}c z#WAE}&f6;oIT;K%SPZ_)FX+2q_;!E(N)e%g#>>WwZk`LZ_vKh{^NU-o17G+9v%QIo lOSm;ePaKp7>P7-bwAmNuZk5wt;2jMT^>p=fS?83{1OQyCDRck; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r4_c11.png b/assets/verified-tiles/t_r4_c11.png new file mode 100644 index 0000000000000000000000000000000000000000..6979036bb8650225f58ae486b8219fc00618939e GIT binary patch literal 149 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP|)4e z#WAE}&f9a2ybTTvM-F_|XHZcPPBF1eoAht@^L_X1w^uF5`|5D_RpYL!%%!W@Uxo2s iSu3|f8mJWkHU!rQURvf8z`y1(NYK;O&t;ucLK6Tsq$|k) literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r4_c12.png b/assets/verified-tiles/t_r4_c12.png new file mode 100644 index 0000000000000000000000000000000000000000..1f2b0da3f3404ee56714bc944806bc6a2064e8f1 GIT binary patch literal 152 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP|(ZM z#WAE}&f6>8ybKB)tPa1}CvY6OBJ}Fdom`d&ZyiIn)m=W4Q+gnX$%FTWpMv?_Ke_e_ jEE^*Jf(%3g3UP)E^%Yy?bP0l+XkKNzy9N literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r4_c13.png b/assets/verified-tiles/t_r4_c13.png new file mode 100644 index 0000000000000000000000000000000000000000..0a33435c13f63ffcaa1f8691130e32b8b0edc4aa GIT binary patch literal 410 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wk0|TRv zr;B4q#hkaZHcmX`Ai$!&uD6M2#d)XBIsP1VI0z7w0*A;i%1d?z(;X+{Zp{TJZh%>iDngpI`l3x;LhwfPIOw!2kJ- zrk72d`{!|H8!uS5{<&=pTaVs>qp}8amQ07cBefm=*5ty}{+`LWHzQxLfbo#*gxN|0 z@_w_I>A7(4W_ZZwVZyYw`0%aNV(sYq3#RX5Pq5Co!&v!(BgWc%&+pW;tRCeKR!l#S zNM5iq-Z?dH|8n;QI~gWhFLbP0l+XkK D(`TSq literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r4_c14.png b/assets/verified-tiles/t_r4_c14.png new file mode 100644 index 0000000000000000000000000000000000000000..ca16f2813c484d10947bef16cb37ac79fed0007a GIT binary patch literal 382 zcmV-^0fGLBP)b%ghcN)<)sZ2 zCWyi@JWIcX;_JV=1KZQo_`K|G-x8Ut-tBGiSqRm1~fh-z(ByxYJlHEq7uWU z^{SevwBO}5z+*rl0UiXx&o!WS4#*k5eGPCJaF77k69U`zOjL_Nt1uvv00V(|qc$j& z_X(wWTfPp~ls0L`pe5tK=hk#;$k^mhU0nZ!|7=%2N zV7Tuntd;Nbx@&`q0ZIaNWCYe_NrVAH0t^I%8ekMbp$iyoP?!U(`}=^kaS+0Qodnp> z2q=dkT4P6mqAMAAM=KRmTJc<%WPxz%J%x5dyxA&UeidV0TC+&H% z?auPF-}By9-(F$VkjL!B`s=pzhqrIu{`n#;z}&&x!S!T=^oH-h=kI1TY`D?zCz#bp zf>}d)!zu^a3g%Zyh7EzGP5U#LvyxbWwnITfnJfSG8|}|RE?I?vggjmST-G@yGywqO Cflajl literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r4_c2.png b/assets/verified-tiles/t_r4_c2.png new file mode 100644 index 0000000000000000000000000000000000000000..1f2b0da3f3404ee56714bc944806bc6a2064e8f1 GIT binary patch literal 152 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP|(ZM z#WAE}&f6>8ybKB)tPa1}CvY6OBJ}Fdom`d&ZyiIn)m=W4Q+gnX$%FTWpMv?_Ke_e_ jEE^*Jf(%3g3UP)E^%Yy?bP0l+XkKNzy9N literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r4_c3.png b/assets/verified-tiles/t_r4_c3.png new file mode 100644 index 0000000000000000000000000000000000000000..09936252c20c8692fd737798e1929e2192e2157b GIT binary patch literal 410 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wk0|TRv zr;B4q#hkaZHcmX`Ai$!&uJ@7g0z2-fP0kGICzN~5Q}=mtd=e91yLgxQg*_&2(RT{Z zZrZ$R(vpt#HBWw*L>cfni+{G!pHWvQ-t#!s@%{Jk{jcKBum1hIYA3@(J`Z<=e|F4S z%d*+#+X`PxbBK*UU;T?mBDSI1I>DxhrOkYESi`TMw_s|&88cU1yr=Ylsl{5s+*RS9 z<=e7%PFpr`3%qM^QNCbhz9!ae`=+n#zLjsC^bVYrozUKQ;L6U2m-Vyt9Ck5Z5lHDRXLRoYj&4g@ATs4?;}{dCCi7Lbk&69prrpEoRi&L}a#v!U7H-3qphqcvB;b~`&5I(Rnp^)wi=tFS313;8^k zZQc4YHm*E303va~=zObzgGWPiLjdy}C5;ls<-A{YF98lUFvntwaWhA-s4P09!?cK z-TTvRzC;(_n`RYvJ80|gpvSNH8JhS6lm!YJ6b?GDw(zjoIY=z*6c!1qsB^Ta{$IA+ zfwAE-<53O^nScok7BjW-SlKNwaOxA*S+ij?x5()Un|U|!y???e6<*Jxgv{6A= zWMRexuI>n%9o!v L^>bP0l+XkKkY956 literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r4_c6.png b/assets/verified-tiles/t_r4_c6.png new file mode 100644 index 0000000000000000000000000000000000000000..d3965131e9413bdcffb826cd085198d36d026f0f GIT binary patch literal 336 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wk0|O(I zr;B4q#hkY@H}W1f5MZv?^P4y^WEtnCW`^Dgep9o~PP*hOwXBzgO(W*OjRhwd)i_KiEzp;3jaTKLAz5g~!YaUH zAS7UWz{K$((=j$zJ_E-U6Igsj^v*D)Noe^rr^)EOVczroP*bZ%vhow(@T8wVB@EOL zZ&uW3NNAYYV9`JO^A0#svHM5mp5O*9W-Fl;UmE;`*X(dO&i4A9oiAU68J|<-EzWcD zYgm^q-pdZQ^uqr{jitXEB7@!Q`?qEmyq90Xz{yq-%(>)cv#F=dUt5q3>vbCSi(h?} VvEH_C12BjfJYD@<);T3K0RS*#e3k$J literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r4_c7.png b/assets/verified-tiles/t_r4_c7.png new file mode 100644 index 0000000000000000000000000000000000000000..a36f74957989ed8d42db64665c5224a8be71a6b0 GIT binary patch literal 325 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1H8_ zi(^Q|oVT+!@-i9nxaRBmAN0_i$=oUUVntB8n3wo<8?U|#?Hb>?!Y_KNpT7TZ+r4ei zyNz9sJk{P-|9=9fhc<)igl`NvO)o_b7|!^`VB)k=IAw)s-q({e53#g}HVAQ4GngGL z;CdjzQ_CQ=(5%t=GH2LYgLh0< zi(^Q|oVT+!iXL|0aJCf>jyWyX<2dn_?h-7pSfJqO&dMcOQsa=+!lOQ8?wW$U_&s+yR2U>= zC-gKNWaQ+O(wcB$!9!*tV4 zqNYH6hK!q^p7ZB(`%fNqp1y0Zs2)Rs)dH)2haCModSd(x0agk?&O)Yp(X3nyd&=2a zv=;0QRbX&<*>J-l!?%f%!HbVe*7@O1TaS?83{ F1ORm%YgPaN literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r4_c9.png b/assets/verified-tiles/t_r4_c9.png new file mode 100644 index 0000000000000000000000000000000000000000..09c233152abced828d41a25d194ac6fe7384eb59 GIT binary patch literal 318 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1FAN zi(^Q|oToPx`IrnDTo0CinL4MrMfpL%3tMiXM$Kton4F_NUh$uNva2g^{`c%RF;WY> znM*Po^ms2UW!z=rFrDqiC5Bk2;JVL0C9F|Iuqs0rd|kJ@Z!X-_dLJYc(Urng0quV9 z-tK^}GmC3q9=RRH zpTelgn487AY4?Wk(>uR%a#wgTeM%QSaqxiHg~-2$gaSeq`2J;n#kMgns&UuB0I>j- c1$WmTV681=OTV^I%o}8$r>mdKI;Vst0HPQ@{Qv*} literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r5_c1.png b/assets/verified-tiles/t_r5_c1.png new file mode 100644 index 0000000000000000000000000000000000000000..118ea6f8c918873435368916117e03e58c66144b GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP%y>Q z#WAE}&f9Z_yoUoAjvi>&);J~aa*QulNMhQr_bTr}8eyPee{t;m=TE};udJ0@5p5f= x{r>klzr3#wcV9K`y2@O-n*9|*s%im3LjMp~)R9Z}tTrHnJYD@<);T3K0RVeLJc|GT literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r5_c10.png b/assets/verified-tiles/t_r5_c10.png new file mode 100644 index 0000000000000000000000000000000000000000..b3aa3dc128deef330cb5519191e9231f49127e7a GIT binary patch literal 325 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1H8_ zi(^Q|oVT+!@-iFpFxTt(O`I5$*2f^J7^`)4p6XIAbD!U3Rr?>t96VL=K(Rwe^TUdd z-z1mbv3~PS@2-{1>c0xC8YK_39Iww!fjbYYj^>X1xmTX2IZjh9O{p(P;NVeUc}Va=R94oPi2(r38e6v*;% z>~01dBw&1i$8jU;87UE~0~`x?HCQ=wvIX6!Xgt6pX)bXiv6!EOPwAPGh_HXs`sauL zvv4U`9SCr6N%3)UgA>biC)`$4nhfHrb)J~f6L9W4M=hhPT#B}XUDFL<5HNVU`njxg HN@xNA=Sp#f literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r5_c11.png b/assets/verified-tiles/t_r5_c11.png new file mode 100644 index 0000000000000000000000000000000000000000..18fc4e6fe9f4816fe8cdb977d9b612b9cbe5b997 GIT binary patch literal 316 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1G3n zi(^Q|oVPP~^By+faWS2~++((`MO)XEha8cP(mT$vZEsSu*gmaM#Z}9(pMhQA;Q8Ib znv;)f&$oNN?QYv0`S0r^)A+e2lr%^-{@KHPCF#V|vIY%@3ye{fEZ|lDt!zQEPprPQ{c&JfKAW0*j`NYFE`3FYT z2^}hZ6E+?Z^1m=+QKxoJ&c`S52Won9{_y;aY5BL#Suee_lq=w6!#R$SGKX}|uyqd4 zdBQ9l8Uh@em|B^26^;ZfV4HZD*Zx52w*vwv|H~|7&S;xcJ~`3R8R&BcPgg&ebxsLQ E0Nsjq9RL6T literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r5_c12.png b/assets/verified-tiles/t_r5_c12.png new file mode 100644 index 0000000000000000000000000000000000000000..73fd9eedfaa0c4571cefc25dc5ec9d47df974610 GIT binary patch literal 329 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1G{> zi(^Q|oVT+!3OX6`INMHNmcX&?$65VI1!n^W_t}g$4%upV2tDGGvX~UU;?&ZQk(=HG zd$8|My6?{%^{nCMy=JBkJ_C^pn>nKQ^RAe)^OxO&`}Y?IH87P}9qc zL!lz+&H)S;8QYkgn0q+7G!u?3_`rCKqjb)KjfdvO9?)@~n|oo+;knff^|c!wC`^iJ z`EzyhjgK{w0dpVbaBwMD9SCqxaq)3-ffFj89Wz=yCJB7p#5u8z?MaZ-2L{>qm)5SB T_Hr*U7#KWV{an^LB{Ts5JM(^} literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r5_c13.png b/assets/verified-tiles/t_r5_c13.png new file mode 100644 index 0000000000000000000000000000000000000000..b411df3a79fe766171f2d8913ff8efc2ff6b5f4b GIT binary patch literal 320 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1Fwd zi(^Q|oVT+!@*XzeVKKh$Ke6`GiZe{}Tyxn@h`rf-XzA9e_r#`X?-SyYV443%{ol6G zjqcg!nZv66-?86G`|Zem;SGb|QU__f7d3nlZ|^c4;d9_hF=zgDU}j;)ns5J{8|`lL zM>T9>-Z6!#wlJdM2BSx#1#%Y`HfkT9> zm_ivtkit0znWjSS2U0y&46PT;8m)pkrv*vub;xYHz&ou>;yvS2M;3jj(np?eK30A9 z-@veuc>|uH&X=35fFu}2jsg+k>;Y`2-wpLlb zPYi+`ES(cNjx_lMv@CMe(n{B`CzKYcAMT_|BE}PS@-fv18vQk#tVj2nsS{02-D=enGblj*EwRGF5)q_IT77U*#XPgg&e IbxsLQ021YGR{#J2 literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r5_c15.png b/assets/verified-tiles/t_r5_c15.png new file mode 100644 index 0000000000000000000000000000000000000000..23d7b449dc3522b933d8f2c93a0c95a00bd56625 GIT binary patch literal 181 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP%z!o z#WAE}&f6;+c@G$HusEDQDk5pFs$3yc?l*T!=7t@UBN+ZkG6NODK!*CGTk8F+e?(c= zX)p$^V9H*5DVb4`F`9MJ1^yG&`1@u=pFwEjT5g)4X?w|M( hmUbbB?TkM|SoxO5-kh;@!qFm-k)E!8F6*2UngAb6K(YV; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r5_c3.png b/assets/verified-tiles/t_r5_c3.png new file mode 100644 index 0000000000000000000000000000000000000000..750a3e297c900020a7df188c4b844086bb1bc207 GIT binary patch literal 331 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1Gv( zi(^Q|oVT|&iZ(fjuwGnwT1%(BNar9^PsiG$AJ|pS^IdT`zhcjWXUy!=?yi^NJN`zp ztby11K$~nr^6Y52o$IF0|MuqB3*H%aj4!nf)~{zgKTqQJ@#_t5x%D=gC;Vbrvi?8` zuZQ@-m*EP3dHlXJzI4mjCG4~P(B;hzRT8u2v0a{c>5nhQI&- literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r5_c4.png b/assets/verified-tiles/t_r5_c4.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r5_c5.png b/assets/verified-tiles/t_r5_c5.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r5_c6.png b/assets/verified-tiles/t_r5_c6.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r5_c7.png b/assets/verified-tiles/t_r5_c7.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r5_c8.png b/assets/verified-tiles/t_r5_c8.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r5_c9.png b/assets/verified-tiles/t_r5_c9.png new file mode 100644 index 0000000000000000000000000000000000000000..7e391a31a481dffbe915606677ae5e989bf00e9a GIT binary patch literal 339 zcmV-Z0j&OsP)03(DF zC1|8@;suNuO5C7-Vux>KZqVD~(GV0sbbz6NxC6{3D5iiJgF*)wAyiO;MhX|afH6Y_ zH)!l|VISbF7Zxl;DjOmHbtN`;Il*2Tj)tHBq5}*CL`=@)1VvENBt=D3)?|e%VQG^V luf*ledx6S>2_NCb$O}-c^&B+&Ne%!2002ovPDHLkV1kplfW!a* literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r6_c0.png b/assets/verified-tiles/t_r6_c0.png new file mode 100644 index 0000000000000000000000000000000000000000..a4bbb069a91aacc31fd540d7acb9d72550e9f828 GIT binary patch literal 291 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1Gg! zi(^Q|oVPbO@*Xx2a1K0sRMV(H>-tR9r=poN%nT+ltm`@OoU^G^>n^zQR6-Ooxty+{TFJzwYuI#6Om9HGRSKi1ms%2d{=; zk8VJ=L5+jt!o`O<+eFvt2qdn!lyKzXBSuD-E{?a)a#+|pdDS8UN&+4pdbC)4MN*21 mb7*hwu7g_c+uy(aAid_+k@PY@2?k^VbRm~*a&X!)@!roVw%17^PcnPuvjH01hakZ@wZlR eLl6eslAp%6>p^(E-&UYM89ZJ6T-G@yGywpQjckhm literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r6_c10.png b/assets/verified-tiles/t_r6_c10.png new file mode 100644 index 0000000000000000000000000000000000000000..4c86ecabbb0ac72c5cf898a782d2b218719e39b0 GIT binary patch literal 296 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1F(g zi(^Q|oVT}E^BxZ1X?=L+sisx((!PMOlsS=HyiR_F;yXI0@Xv4$uakXlf7|f>9nDp8 z^&98@b(Bj;ahP)81>;4Q<02t2V4t{yb&rEB;EpEaE(+H--wVx5#!b=k8?KwmO=y85}Sb4q9e0JvIf*+HYacPU*fTgQoMD{7a#*V&)j%)nb@Q`*4@{=+;0!V6hD8uQ5&HM@F zi<6Y6lr`PpTE3Zq&-tZE$K!%s{0CY+b_piE^m_C4AI~gvm*p#eFg)ZxAi&|DTp`5` zB&2yH69M*nK-z=dOuvk$9UZMAJ^A;^<+S$MO|2q+5 zd-;z)zOh#}q&Rpf*eduM1TR?MbMSdyITycyk%Fp0mBXwDGngcsllf05ec5xMEKN9O zb-|VcLe7EB-h9vHHt;F!kyN;bg!;w!sM@_cIB+os_ bv6s>A&VxI368CQbJ;>nc>gTe~DWM4fG=6L2 literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r6_c14.png b/assets/verified-tiles/t_r6_c14.png new file mode 100644 index 0000000000000000000000000000000000000000..c17d0cd75f1ab4fc25bb1ffe88e672bb808e60c5 GIT binary patch literal 298 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1FhY zi(^Q|oVT~UCo&uIuv~ax#N{l=qv)Z)(|UoUd6@#s?(05$)%VX7Pvy8V?bqUcXIIzX z(>`x?HR^ZB@yGwt@BX_jDSn~uKt`h(^D%)O4TFRY9~%^$S~;J2g;>bz*XJAN>BD{iuM>Q>!W+0?DMYv-YE-Fcg|anKh}W-k+t_%_BxDS3BorJ-Xg literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r6_c15.png b/assets/verified-tiles/t_r6_c15.png new file mode 100644 index 0000000000000000000000000000000000000000..9a4036358cfa0b4d77b8d422d2fc244689afd107 GIT binary patch literal 215 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP_Wa} z#WAE}&f6;oIS(5MusB>T4P9}^CfMoJ&GSx%2Lu2=Cc*<+k4F{b7Nqe5w zRnM9Awffro+{LFDcJXS6zL3v9aBud8uYWW6_A?qb+-O+guy5Uwr}+*%3T6sg6XuuK z&XN{j?%+K!RV!ffQ3kiG@_$^V1JuKSw!=V%aTLS%{Pt(f(kqUE#5`U7T-G@yGywpR CDof)4 literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r6_c2.png b/assets/verified-tiles/t_r6_c2.png new file mode 100644 index 0000000000000000000000000000000000000000..06e87e1dfd028ad5baffc7e2b81197d5e304cf74 GIT binary patch literal 296 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1F(g zi(^Q|oVPcv`3@WKG(Vi@z5GO@apkv2tE>};&V3YH;2{5#rNUI;__P!A`xnpuxzzM{ zT~z4pOxtzWKC;R`Ww^!Lp?;yt!Q`MBYZ8x{tbo%B&4UvTo#k$k%*r!(Q}CFP(M3v- zOXb>(1c!@mt)I(u?56Wx|5Yt(Aba2)n~#6Ob>?MiJ7zO|?n~YQ`njxgN@xNA6h?69 literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r6_c3.png b/assets/verified-tiles/t_r6_c3.png new file mode 100644 index 0000000000000000000000000000000000000000..b80d8b1ab6875db6351e2b3916d2b544b9896e52 GIT binary patch literal 307 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1Gdz zi(^Q|oVT}Zvzi@wS`z1bFTc^PLz-5;aSG;tD-t4Y|VgBgO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r6_c5.png b/assets/verified-tiles/t_r6_c5.png new file mode 100644 index 0000000000000000000000000000000000000000..ed17b776ef127646be05b3a6cffa65b703515b1e GIT binary patch literal 202 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP_V|+ z#WAE}&f6Osd6^A)m>td^)!gx4Kr48K=Pm}#%fH?;=qudVbOfjk0vcAU*8VR(m%E6e zl=%_om*|$-v*#;g_#;>)%oA)IFEWP-%j`e!i|x3KKy!d^lOfl2J%Q5!xy>8-!sQC` ogd06nodi2W)g%^X$j{`eXW$W&ytkG8h%(4*Pgg&ebxsLQ03NzMng9R* literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r6_c6.png b/assets/verified-tiles/t_r6_c6.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r6_c7.png b/assets/verified-tiles/t_r6_c7.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r6_c8.png b/assets/verified-tiles/t_r6_c8.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r6_c9.png b/assets/verified-tiles/t_r6_c9.png new file mode 100644 index 0000000000000000000000000000000000000000..aedd46f3992ba988999cba488194db303edc25fc GIT binary patch literal 316 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1G3n zi(^Q|oVT}k=N>T-Xi2=fH8dvq*jEP!RfFO!AFn=|&^Wm;OH-VMBi?{l;LdmZ=&RcQ zzrK9mTzCEa;;oeppO}?cy!bj)B33y}IarnY?(u@+_zxzz&y8L%mf0&fB}`{l;(P~^ zia! zwCJ6BIpPi*x3b8Dki|!sCTGt{XqeP1!W*(}X>8v5TPhxW>W)|75$;Y_(J}5$ z*YFAM&eoZJ>zP_q&4Q!q$iyAL;&@)~|BRa_uHruQZ`U25&lx;j{an^LB{Ts5kK233 literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r7_c0.png b/assets/verified-tiles/t_r7_c0.png new file mode 100644 index 0000000000000000000000000000000000000000..82619ec34edd50338fd09539e05a9957c67bff3b GIT binary patch literal 296 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1F(g zi(^Q|oVT|Wi;f!buw0mv?f;Njob$U*E7Sa(#M>Jd#DB0!o_A7Z+mhPrUkg;1@Bd!A z_uK3Ex95NU*!=!{eI+CRbbW=oMl0q=0&Aib)*W2Myhvb`*N1KQVt;A1hU*8Mz3_@{ zwQSty2C0rUodLZ^j`?h8Ta>I7ll*ZacZh+}q=j9_l%&@bm|S|;b^I{9$OI0>OUoTv z1UMCoI3@}xwZjt&bDBN;|V7iIh+(ZjYM0|KR)O8iD?%|vi>z=xZO=p`}hY@ z3pDf`REBvD`pFfe$!`njxgN@xNAj}>kt literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r7_c11.png b/assets/verified-tiles/t_r7_c11.png new file mode 100644 index 0000000000000000000000000000000000000000..5dbcd52db105893056e44934e4a70253a7734dcf GIT binary patch literal 303 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1GFr zi(^Q|oVT|F1(^(aTrXY?74_)s(NYlF(9mnu(W=E^U$bFBLi^;I5-+x#JbU_eVT_Gj z<@@t8kIPQ&eWv+Za=FbqIX;EE4c}OTcr#oLN*k}SeV)#|@Atp^g$|Yt1}IZPLb z9K68lCCwuf;Gi)f!SSI1_mo5ppXOr^)omB_uV!~t(RA_^@}89->^fQNPRhqE;u+l& z6OFHgB_Gb)pzGfLw%{`-pWDf2BC%^Woz>nmW9jVZnvJKo|7SYg-uchE`N%OwVfGvu sgTezah6Ce5hbGq6!#V-)6JM}u-#9vb^DU`Npl2C8UHx3vIVCg!0Q0qTM*si- literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r7_c12.png b/assets/verified-tiles/t_r7_c12.png new file mode 100644 index 0000000000000000000000000000000000000000..f80081dffdc3a6a0976539de95256d7f7521ed25 GIT binary patch literal 312 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1F$f zi(^Q|oVT+!@*XzeVX+inenQ};Q*lZMkHC_v47ZwU!*)#RyerM}Mth$)$EW{4lTz;e zI6fo0+5PHDK{1853^I*Vm?y9Vi#ka9)G|mdTq*qIQrM4wHMtw!cWhSFak#~3!Sqx6 z&^(oUHGaJ}`Wsj^tQp)FJYi5d7{nUD<}L5AJ@6vOLSYx}p4|+3&O3M?S@l#huqn;p zNK|Q?snE7)23N6%j@=*GxayPT)s2!61>a*;+VL2uG6_vjWx|cUo&{R`njxg HN@xNAKXrDH literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r7_c13.png b/assets/verified-tiles/t_r7_c13.png new file mode 100644 index 0000000000000000000000000000000000000000..2628dd6669e46943bacefcfc82c9910d42ef6b4c GIT binary patch literal 309 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1H2@ zi(^Q|oVT+!@-iz5u&nIXx^w=zqwf4V#&=1@+YS73>$3_yd^T`iEtYR+dw8*iMMPhU_K?xAratUkkh#9k<^`d`!@{Jq%X`n(8S2gGF|t=wFifo zr39sBBrHDEES8a!5zy?*$6x1Q>@rFDiq6I-oMyo$I}e=|^WW*f?G|KoWzohdyxR&) zmLArXJ1_i=*~?pJ%Mlo{?xv8of`r3{h6IL#OihX0Q%of)4!E_bsqF}S=*gXvlo8ZC mTV~#$hJyk-|8G_P!uIs*j3W~n`}~0ZWbkzLb6Mw<&;$T8)NOYF literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r7_c15.png b/assets/verified-tiles/t_r7_c15.png new file mode 100644 index 0000000000000000000000000000000000000000..61b241f6a9c5e21a08e62cf701d6b56ffaceee26 GIT binary patch literal 192 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP_W3; z#WAE}&f6;+1sfE2SOcD&66wpHDJap-XD(pN^|9i;o~npvofjieDGY2AF8pFYo$X8) z>#_{yq=g(?u1(Y9<&eJMs$jQ=vGUsOS!aK|*neJmf>c1R!#j~i8J`+6q5S*V4mTR~ cm_GhtixH{)^s`!n^*qQtPgg&ebxsLQ0ExId;Q#;t literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r7_c2.png b/assets/verified-tiles/t_r7_c2.png new file mode 100644 index 0000000000000000000000000000000000000000..716ede132b7231de287aebd4623338859923b247 GIT binary patch literal 291 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1Gg! zi(^Q|oVT|Wg$_CJuwIy_z5GOD;Keztl8rwjRxk%2Ieq4r-}1X>pY30~>hr#HU+)}` zU;F!x-L;=T`}0@tY52xEC4RwM##G^)Jd#DB0!o_A7Z+mhPrUkg;1@Bd!A z_uK3Ex95NU*!=!{eI+CRbbW=oMl0q=0&Aib)*W2Myhvb`*N1KQVt;A1hU*8Mz3_@{ zwQSty2C0rUodLZ^j`?h8Ta>I7ll*ZacZh+}q=j9_l%&@bm|S|;b^I{9$OI0>OUoTv z1UMCoI3@}xwZj!Z)bqD zjH*^h_q9SR6YTj`{l8~`K!8I5GP4D?&OUBm7y>d1C|Dp5lmXjL*yk_HwE_eP3Mg1W z4wM1XxxWuL2nhr@6d+i@eQg;!{2U-(UWXxIK>_7d7Dz_&))K>8AVI*20@BPDP}-m} z2PlJ(&N~UF4|jo9Jp@D)P_RH8I0J(B6{gF800ABa1T5gmfItX(x4P5 z3IU1&bY=@AM&XrRAh8Us^KOH|ym0FSARwcFf(7zG86ch5dp`(>D4<}0c%c6UZbp(V m^wzhohX6qV1q;aEGvF7hM$Iq6&Y*<=0000Orn4B z+fs}DHvP{H&i;>N3T(KFVdQ&MBb@00Zf6s{jB1 literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r7_c6.png b/assets/verified-tiles/t_r7_c6.png new file mode 100644 index 0000000000000000000000000000000000000000..4cf071745fe1e259bbb03c78f90941cecb67b3c3 GIT binary patch literal 313 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1G>< zi(^Q|oVPO#`3@WKFn`tCcZmPp6U+RUD;9EFmvC+>;mWW`Z-{1d+n_Q@FZ0LA6()@) zTD}UsUcwRU80OdI^KvQVHDof*O*>#1Z>M~Barxt4`&}8;%nxiikis@Y(c&gk8n0hT z!(}H{#VZ<)%B|A+31NwN=gETjU9Eno^$KJ@V0*%^koOo+YFwrelF{r5}E)| C*ls8Q literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r7_c7.png b/assets/verified-tiles/t_r7_c7.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r7_c8.png b/assets/verified-tiles/t_r7_c8.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r7_c9.png b/assets/verified-tiles/t_r7_c9.png new file mode 100644 index 0000000000000000000000000000000000000000..08b649fc1cae8f0df2f0bd6fef3584ce1136050e GIT binary patch literal 314 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1FeX zi(^Q|oVT+!@;V!GxXkR<+!QfIc7jdQ?vN`pRaISQdC#o*9`EsQ{f>K11?6)Lzt8?> z=q~f&)bncwTn|bbBpBP7Svak<6jCmHWIV*dJ7&gvSbJ$f*foY#q;%Jyad=kwLteyp=3R+*`Cl9p&$;!+ZcU@WT%f-hJYD@< J);T3K0RZ8SbUOe5 literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r8_c0.png b/assets/verified-tiles/t_r8_c0.png new file mode 100644 index 0000000000000000000000000000000000000000..6d3f88a9e87b44850caf27576a276941d50cccc2 GIT binary patch literal 331 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1Gv( zi(^Q|oVPPJ@*Z~JVK$wAm(A@(2}r;^@xPHk76b3jXFkV&3Nj>yp!(Oq51_#DNOdqS+rUbP$$Q8 aiM!}*j-__wbRS?qFnGH9xvXwME?K%_R-f_%2*x zjN1R)+S;2v<0XTx?1H7tTVTRg4x|fy-FY8jE|LNMUQtlq+O5~#=wR9td)*S78>%LN d90=B0FEVY*1Nk^v7N9p7JYD@<);T3K0RWGPX;=UN literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r8_c10.png b/assets/verified-tiles/t_r8_c10.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r8_c11.png b/assets/verified-tiles/t_r8_c11.png new file mode 100644 index 0000000000000000000000000000000000000000..980aae514010ac1bfc1c5e2969c24a5c0958227b GIT binary patch literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP_W$7 z#WAE}&f9C=f`<)wSREc3bvbeND0L{zaLQhcSBPdM{DUwy^0z1}~}S)TN+(mwyH^8czfwkez)q8jxM zHBC>sj!5cQD(r6VR4`FJxJRn>cZ1=bT}-tHluZ(5HRMDy0!@a2gqpKVN6ICabbP0l+XkK>tHyz literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r8_c13.png b/assets/verified-tiles/t_r8_c13.png new file mode 100644 index 0000000000000000000000000000000000000000..ed16131b7e4bcddd026ba815c98e191203bcaab9 GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP%zcg z#WAE}&f9ATc@G=#Fgu)ms%aE!>2xgQe(VC4N!AVZ2RG=Rn|pqr=JOc)ncp1v6!H#K zF@0oT<8QF-KveTZ<}kr7wH>Pp{%sdqe)sI{nco=R`cyZRfoz3=8Owh%O?Q`E)>ISz P0wm_?>gTe~DWM4fNVhvy literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r8_c14.png b/assets/verified-tiles/t_r8_c14.png new file mode 100644 index 0000000000000000000000000000000000000000..640d47ac5b55b727b9405e83aef516a48bc9495c GIT binary patch literal 198 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP_V+& z#WAE}&fBYwf(-^dEC*h#;##7xm}^B#)B!fW4Faqmmf9p#Fzq&0Uog{qR+8pz!`C)t zCo5lEdQ~#>i&-LrEAt^P5pxBZgO9{J?CY9;emSsP!r^MeS*|PmcN@xrUoQ8|zs!?x iso~pmQJ`gTaOwIRU2PA&XxEbUATdu@KbLh*2~7a2$U)lx literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r8_c15.png b/assets/verified-tiles/t_r8_c15.png new file mode 100644 index 0000000000000000000000000000000000000000..2b59799859116ec66908de0de97804052ff2c82e GIT binary patch literal 217 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP_Wz6 z#WAE}&f9Cdc@G=#usWPQs%etv)jy#yZuyo@X~hYj1q;|WZ02oNa@}SYc=dR(%1)EM z+kaKV_Lu*=zipMug4GR|nEoc0AGo^luB-rO2iJ*nx&?Ed{m5B&eqR0eTA+YLl)|wG z8`zI1ndCJ6JR}z|yOm|lDtil8(E$4#MxXaboFyt=akR{ E0Lbr6sQ>@~ literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r8_c2.png b/assets/verified-tiles/t_r8_c2.png new file mode 100644 index 0000000000000000000000000000000000000000..0d7b43b9d793416da6203de0c95386ffd174ade8 GIT binary patch literal 338 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wk0|O(A zr;B4q#hkY@H}Wy5b>z?r0${PcW?fe zIOA4(U1Mmg|RH1Q-^gHQ$quz6H_BQhcM5w28rf_atdM#6NE)p z7ZivKOkeoGOk>?)M>z$ii3);36C);Yb_JMtw7Tlt%lj6;V0jzkf`bf-jb#hizsO6i zj$=qLaPT;g_k?kp#{XGzvzZ$9E*Jl?%3wjP2BSCsnz)^b3^NiMCLH+E&c0)}*43AC z4_IfhF|-41?*rOivaG>RzWMW?kflrv%|Nj>pqL5BMQ$p~4vWvPS>te_a@A{Q2dl6L e+VLkFL>KLoeOWqdNm#w(V05R-|sSBRlE|@^tIpr;m&G(i)yxTiZ SU7n!=vd`1i&t;ucLK6V^giQtj literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r8_c4.png b/assets/verified-tiles/t_r8_c4.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r8_c5.png b/assets/verified-tiles/t_r8_c5.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r8_c6.png b/assets/verified-tiles/t_r8_c6.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r8_c7.png b/assets/verified-tiles/t_r8_c7.png new file mode 100644 index 0000000000000000000000000000000000000000..0f9e474404815de942d8a3d2175a841db20c2783 GIT binary patch literal 226 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP;iQ; zi(^Q|oVV9D@-{p0um(IUnk=eu$u+6L$7#Bx4RiE`rDsf*E#tIm^;rJI_GNfX^Tt{p zW}rSO_#m!y?AKF`0~237(0K;bO__*7se@$W7UokzKHD93vTgorpTMm9(}I0wshlXt N5>Hn@mvv4FO#oB(O=Q z#WAE}&fDvrf((j0EDlo?7#SBU{X5ITS#xvgZY?&2=O9&3a6ov{EBkhKi<7MTRhWwc zInV60la*62S}@h&OT#smWUeiS64egTEq+PDI;#urFg=y%%HA-~qTRfjYk9R%(DVx+ OV?15`T-G@yGywp&+%fY2 literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r8_c9.png b/assets/verified-tiles/t_r8_c9.png new file mode 100644 index 0000000000000000000000000000000000000000..da6cc80c0b164fd8d1668a7dfd385b7f7af44052 GIT binary patch literal 188 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP%zKa z#WAE}&f9a2ybTNtM>YgEv9K&)`k&@-OekaW-|dV*B~UQGB=-B~=VAO;*2=Ajwhh?+ y*kZo@_NoPWUmfngYTR{|xpX!AD}*doiE2is_32stf~yokW_r5%xvX>WwZk`LZ_vKh{^NU-o17G+9v%QIo lOSm;ePaKp7>P7-bwAmNuZk5wt;2jMT^>p=fS?83{1OQyCDRck; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r9_c1.png b/assets/verified-tiles/t_r9_c1.png new file mode 100644 index 0000000000000000000000000000000000000000..6979036bb8650225f58ae486b8219fc00618939e GIT binary patch literal 149 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP|)4e z#WAE}&f9a2ybTTvM-F_|XHZcPPBF1eoAht@^L_X1w^uF5`|5D_RpYL!%%!W@Uxo2s iSu3|f8mJWkHU!rQURvf8z`y1(NYK;O&t;ucLK6Tsq$|k) literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r9_c10.png b/assets/verified-tiles/t_r9_c10.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r9_c11.png b/assets/verified-tiles/t_r9_c11.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r9_c12.png b/assets/verified-tiles/t_r9_c12.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r9_c13.png b/assets/verified-tiles/t_r9_c13.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r9_c14.png b/assets/verified-tiles/t_r9_c14.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r9_c15.png b/assets/verified-tiles/t_r9_c15.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r9_c2.png b/assets/verified-tiles/t_r9_c2.png new file mode 100644 index 0000000000000000000000000000000000000000..1f2b0da3f3404ee56714bc944806bc6a2064e8f1 GIT binary patch literal 152 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP|(ZM z#WAE}&f6>8ybKB)tPa1}CvY6OBJ}Fdom`d&ZyiIn)m=W4Q+gnX$%FTWpMv?_Ke_e_ jEE^*Jf(%3g3UP)E^%Yy?bP0l+XkKNzy9N literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r9_c3.png b/assets/verified-tiles/t_r9_c3.png new file mode 100644 index 0000000000000000000000000000000000000000..40e30b159e2854d13cd71dae4fe23a8b92b2278f GIT binary patch literal 416 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wk0|R4_ zr;B4q#hkaZHcmX`Ai$!&uG>j6;C(FzSG#}+gV;C8{3Id9WnQht@Aq8`e9N6N;aEnu z^}4OMB10QPysrQIRBCbN#c#W#Ccegc_SYp37tERX_umWgzmF>m>tpoA7wll3r5y0j zo;hh*GMl`u@U%3C82R(nKX@c!8Wvk8+$d)GCB8YN;m6NQRXZ7u%3hFZ+%#8mf@^el z19!k3#@tYrQ|-a$my0ZFjcs_umyyAeRdo1La)b*w1$#^&If;KS_3zX=+>|H~Un*>fb%(*Zx&U_dmmAIt^HvX5_T^m#kP!gacBe2YKAq)@_U?3pW0HX*BUBGCA!W>}T-v=xQ2O$jD zNPrEEfN~g8PJ_yESjW8&SgQTr^DrQg00V*WM>Rkkb^nr-V8D$8$Vdoe=Y9QJ-F+{R gF<>VF`9cW10d_BgFFL%6)Bpeg07*qoM6N<$f+7HsN&o-= literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r9_c5.png b/assets/verified-tiles/t_r9_c5.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r9_c6.png b/assets/verified-tiles/t_r9_c6.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79540a7f059019e9c5ce196792245419fc5406 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*B~| w#WAE}&f9~Gyg=Te1>gO1`OFspnaH5w9It}|10yfHX)j3F)78&qol`;+0P2?(od5s; literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r9_c7.png b/assets/verified-tiles/t_r9_c7.png new file mode 100644 index 0000000000000000000000000000000000000000..8db3381dd2f5c2dfc1ab5d28be5081ca50f90400 GIT binary patch literal 369 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wk0|TS7 zr;B4q#hkY@H}W1b5OFcSo*&V0sCBo;6cL|CeUe7Zw#=~RIoeFlKtNMzZ?sTNJ4~y%nZg~=_b<| zxftbGU(D29P+#|8tF3~*o%elB1&4r!M8=zj%v(N)oUo0LWz%4(5Lpm$;Cpn-mJO^5 z3JVxsXUSgcZD4R@Y-3&W&~U}p)CMy)4grw_-)M!PR`;^T6GkTAcJpc_U%1RXMd``! z+@^_!7DjBz=aUWO);4_qd&>lB#RSG8BZmW*CUX5#6;b#d`GC1rYF7N)Ywx6iVaVX= L>gTe~DWM4f)8UM` literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r9_c8.png b/assets/verified-tiles/t_r9_c8.png new file mode 100644 index 0000000000000000000000000000000000000000..dfcf1128168dbeee5f1ce67d24a2b8510228fa83 GIT binary patch literal 311 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1GRv zi(^Q|oVT;iavn9{X*TY3d%-a4&~N?4aq>G^cpRzA~&6@pJ za&Rz0m-jNPndj)> z$XKi#a))E4^ukAOC+fd2?tWdh+wK7G92EvO#+z=8<_%v1xpp)Lvm8)RxUKPk&A`r! z(Y&CEL4qYkn)Q#NGQ;ZUZ1tQh5?n1Z36m05FxBnjx%Z^w$etGxhjoFTX7F_Nb6Mw< G&;$TcHgGlo literal 0 HcmV?d00001 diff --git a/assets/verified-tiles/t_r9_c9.png b/assets/verified-tiles/t_r9_c9.png new file mode 100644 index 0000000000000000000000000000000000000000..98250aa2c099715c4e729efa3498e6e798041da7 GIT binary patch literal 280 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkQ1Fze zi(^Q|oTpb585tA=4jfQbWMZ^q{d?M>N4Vp2aQ52T`e}R@E-^+~Ie4>YykyXoU9gmS tOGyKj1hb#rnGZKl_!8V6&P>v+Vh?j!o7vO3)*R?722WQ%mvv4FO#m#9Uqt`_ literal 0 HcmV?d00001 diff --git a/src/frontend/FarmCanvas.jsx b/src/frontend/FarmCanvas.jsx index 9b69670..9ff644b 100644 --- a/src/frontend/FarmCanvas.jsx +++ b/src/frontend/FarmCanvas.jsx @@ -1,543 +1,346 @@ -import React, { useRef, useEffect, useState, useCallback } from 'react'; -import useStore from './store.js'; -import { OFFICE_MAP, WALLS, DOORWAYS, FURNITURE, TILE_SIZE, MAP_COLS, MAP_ROWS } from './officeMap.js'; +// FarmCanvas.jsx — Clean Canvas 2D renderer for the Virtual Office +// Draws rooms with colored floors/walls, simple furniture, and agent sprites. +// No tile-sheet dependencies. Pure Canvas drawing. -const CANVAS_W = MAP_COLS * TILE_SIZE; // 640 -const CANVAS_H = MAP_ROWS * TILE_SIZE; // 480 +import { useEffect, useRef, useCallback } from 'react'; +import { useStore } from './store'; +import { TILE, COLS, ROWS, rooms, agentDesks, hallwayTiles, furniture } from './officeMap'; -const LERP_SPEED = 0.15; +const SCALE = 2.5; // render pixels per tile pixel +const SPRITE_SCALE = 2.5; -// ── Sprite loader ──────────────────────────────────────────────── -function loadSprite(id) { - const img = new Image(); - img.src = `/office/sprites/agent-${id}.png`; - return img; -} +// Agent sprite image cache +const spriteImages = {}; +let spritesLoaded = 0; +let spritesTotal = 0; -const AGENT_IDS = ['cos', 'engineering', 'senior-eng', 'trust', 'market', 'health', 'content', 'presentations', 'vault']; - -// Preload all sprites -const sprites = {}; -AGENT_IDS.forEach(id => { sprites[id] = loadSprite(id); }); - -// ── Tileset loader ──────────────────────────────────────────────── -let tilesetImg = null; -function loadTileset() { - if (!tilesetImg) { - tilesetImg = new Image(); - tilesetImg.src = '/office/tiles/tileset.png'; - } - return tilesetImg; -} - -let roomBuilderImg = null; -function loadRoomBuilder() { - if (!roomBuilderImg) { - roomBuilderImg = new Image(); - roomBuilderImg.src = '/office/tiles/room-builder.png'; - } - return roomBuilderImg; -} - -// ── Particle system for sparkles ───────────────────────────────── -let sparkles = []; - -function spawnSparkle(x, y) { - sparkles.push({ - x, y, - vx: (Math.random() - 0.5) * 2, - vy: -Math.random() * 3 - 1, - life: 1, - decay: 0.02 + Math.random() * 0.03, - color: ['#F0C040', '#FFD700', '#FFEAA7', '#FFFFFF'][Math.floor(Math.random() * 4)], +function loadSprites() { + const agents = ['cos','engineering','senior-eng','trust','market','health','content','presentations','vault']; + spritesTotal = agents.length; + spritesLoaded = 0; + agents.forEach(id => { + const img = new Image(); + img.src = `/office/sprites/agent-${id}.png`; + img.onload = () => { spritesLoaded++; }; + img.onerror = () => { console.warn('Failed to load sprite:', id); spritesLoaded++; }; + spriteImages[id] = img; }); - if (sparkles.length > 60) sparkles.shift(); } -// ── Tile drawing helpers ────────────────────────────────────────── +loadSprites(); -// Draw a single tile from tileset.png (16-wide grid) -function drawTileFromTileset(ctx, tileId, dx, dy) { - if (tileId < 0 || tileId === undefined) return; - const img = loadTileset(); - if (!img || !img.complete) return; - const sx = (tileId % 16) * TILE_SIZE; - const sy = Math.floor(tileId / 16) * TILE_SIZE; - ctx.drawImage(img, sx, sy, TILE_SIZE, TILE_SIZE, dx, dy, TILE_SIZE, TILE_SIZE); -} +// Draw a rounded rect room +function drawRoom(ctx, room, ox, oy) { + const x = room.x * TILE * SCALE + ox; + const y = room.y * TILE * SCALE + oy; + const w = room.w * TILE * SCALE; + const h = room.h * TILE * SCALE; + const r = 6; -// Draw a single tile from room-builder.png (17-wide grid) -function drawTileFromRoomBuilder(ctx, tileId, dx, dy) { - if (tileId < 0 || tileId === undefined) return; - const img = loadRoomBuilder(); - if (!img || !img.complete) return; - const RB_COLS = 17; - const sx = (tileId % RB_COLS) * TILE_SIZE; - const sy = Math.floor(tileId / RB_COLS) * TILE_SIZE; - ctx.drawImage(img, sx, sy, TILE_SIZE, TILE_SIZE, dx, dy, TILE_SIZE, TILE_SIZE); -} - -// ── Layer 1: Background / outdoors ──────────────────────────────── -function drawBackground(ctx) { - // Dark exterior (outside the office) - ctx.fillStyle = '#1a1a2e'; - ctx.fillRect(0, 0, CANVAS_W, CANVAS_H); - - // Grass/texture around building (top strip) - ctx.fillStyle = '#2D5A27'; - ctx.fillRect(0, 0, CANVAS_W, 3 * TILE_SIZE); - - // Add some texture to the grass - for (let i = 0; i < 300; i++) { - const x = Math.random() * CANVAS_W; - const y = Math.random() * 3 * TILE_SIZE; - ctx.fillStyle = `rgb(${40 + Math.random() * 30},${70 + Math.random() * 40},${30 + Math.random() * 20})`; - ctx.fillRect(x, y, 2, 2); - } -} - -// ── Layer 2: Floor tiles ────────────────────────────────────────── -function drawFloorLayer(ctx) { - const img = loadTileset(); - if (!img || !img.complete) { - // Fallback: draw solid colors - const colors = { - 16: '#C4A882', 22: '#8BA87E', 83: '#9B9B9B', 67: '#B8956E', - 38: '#4A5070', 54: '#7A7A85', 70: '#A89B8A', - }; - for (let row = 0; row < MAP_ROWS; row++) { - for (let col = 0; col < MAP_COLS; col++) { - const tileId = OFFICE_MAP[row]?.[col]; - if (tileId && tileId > 0) { - ctx.fillStyle = colors[tileId] || '#555'; - ctx.fillRect(col * TILE_SIZE, row * TILE_SIZE, TILE_SIZE, TILE_SIZE); - } - } - } - return; - } - - for (let row = 0; row < MAP_ROWS; row++) { - for (let col = 0; col < MAP_COLS; col++) { - const tileId = OFFICE_MAP[row]?.[col]; - if (tileId && tileId > 0) { - drawTileFromTileset(ctx, tileId, col * TILE_SIZE, row * TILE_SIZE); - } - } - } -} - -// ── Layer 3: Walls ──────────────────────────────────────────────── -function drawWallLayer(ctx) { - const img = loadTileset(); - const drawn = new Set(); - - for (const wall of WALLS) { - const key = `${wall.row},${wall.col}`; - if (drawn.has(key)) continue; - drawn.add(key); - - const dx = wall.col * TILE_SIZE; - const dy = wall.row * TILE_SIZE; - - if (img && img.complete) { - drawTileFromTileset(ctx, wall.tile, dx, dy); - } else { - // Fallback wall rendering - ctx.fillStyle = '#6B5B4F'; - ctx.fillRect(dx, dy, TILE_SIZE, TILE_SIZE); - ctx.strokeStyle = '#5A4A3E'; - ctx.lineWidth = 1; - ctx.strokeRect(dx + 1, dy + 1, TILE_SIZE - 2, TILE_SIZE - 2); - } - } -} - -// ── Layer 3.5: Doorways ─────────────────────────────────────────── -function drawDoorways(ctx) { - const img = loadTileset(); - for (const door of DOORWAYS) { - const dx = door.col * TILE_SIZE; - const dy = door.row * TILE_SIZE; - if (img && img.complete) { - drawTileFromTileset(ctx, door.tile, dx, dy); - } else { - // Fallback doorway - ctx.fillStyle = '#4A3520'; - ctx.fillRect(dx, dy, TILE_SIZE, TILE_SIZE); - ctx.fillStyle = '#DAA520'; - ctx.fillRect(dx + TILE_SIZE - 5, dy + TILE_SIZE / 2 - 1, 4, 4); - } - } -} - -// ── Layer 4: Furniture ──────────────────────────────────────────── -function drawFurniture(ctx) { - const img = loadTileset(); - for (const furn of FURNITURE) { - const dx = furn.col * TILE_SIZE; - const dy = furn.row * TILE_SIZE; - if (img && img.complete) { - drawTileFromTileset(ctx, furn.tile, dx, dy); - } else { - // Fallback colored furniture - const fColors = { - 528: '#8B6914', 936: '#4A3728', 736: '#6B4226', 584: '#2D8B2D', - 674: '#DAA520', 1012: '#555', 672: '#8B7355', 996: '#222', - 1010: '#444', 889: '#FFD700', 709: '#EEE', - }; - ctx.fillStyle = fColors[furn.tile] || '#666'; - ctx.fillRect(dx + 2, dy + 2, TILE_SIZE - 4, TILE_SIZE - 4); - } - } -} - -// ── Room labels ─────────────────────────────────────────────────── -function drawRoomLabels(ctx) { - const rooms = [ - { label: 'Briefing Room', col: 0, row: 3, w: 6 }, - { label: 'Commons', col: 6, row: 3, w: 8 }, - { label: 'War Room', col: 14, row: 3, w: 6 }, - { label: 'Engineering Bay', col: 0, row: 9, w: 6 }, - { label: 'Quiet Zone', col: 6, row: 9, w: 8 }, - { label: 'Ops Center', col: 14, row: 9, w: 6 }, - ]; - - for (const room of rooms) { - const cx = room.col * TILE_SIZE + (room.w * TILE_SIZE) / 2; - const topY = room.row * TILE_SIZE; - const labelW = ctx.measureText(room.label).width + 10; - const labelH = 12; - - // Semi-transparent pill behind text - ctx.fillStyle = 'rgba(0,0,0,0.5)'; - ctx.beginPath(); - ctx.roundRect(cx - labelW / 2, topY + 2, labelW, labelH, 3); - ctx.fill(); - - ctx.font = 'bold 8px "Courier New", monospace'; - ctx.textAlign = 'center'; - ctx.fillStyle = '#DDD'; - ctx.fillText(room.label, cx, topY + 11); - } - ctx.textAlign = 'start'; - - // Hallway label - const hx = MAP_COLS * TILE_SIZE / 2; - ctx.fillStyle = 'rgba(0,0,0,0.4)'; - const hlW = ctx.measureText('Hallway').width + 10; + // Floor + ctx.fillStyle = room.floor; ctx.beginPath(); - ctx.roundRect(hx - hlW / 2, 7 * TILE_SIZE + 6, hlW, 12, 3); + ctx.roundRect(x, y, w, h, r); ctx.fill(); - ctx.font = 'bold 8px "Courier New", monospace'; - ctx.textAlign = 'center'; - ctx.fillStyle = '#CCC'; - ctx.fillText('Hallway', hx, 7 * TILE_SIZE + 15); - ctx.textAlign = 'start'; -} - -// ── Layer 5: Agents ─────────────────────────────────────────────── -function drawAgent(ctx, agent, time) { - if (!agent || !agent.position) return; - - const img = sprites[agent.id]; - if (!img) return; - - const target = agent.targetPosition || agent.position; - const current = agent._smoothPos || { row: target.row, col: target.col }; - - // Lerp toward target - current.row += (target.row - current.row) * LERP_SPEED; - current.col += (target.col - current.col) * LERP_SPEED; - - // If very close, snap - if (Math.abs(target.row - current.row) < 0.01) current.row = target.row; - if (Math.abs(target.col - current.col) < 0.01) current.col = target.col; - - agent._smoothPos = current; - - const activity = agent.activity || 'idle'; - const px = current.col * TILE_SIZE + TILE_SIZE / 2; - const py = current.row * TILE_SIZE + TILE_SIZE / 2; - - // Vertical bob for idle - let yOffset = 0; - if (activity === 'idle') { - yOffset = Math.sin(time * 0.003 + (agent.id?.charCodeAt(0) || 0)) * 2; - } + // Floor grain pattern (subtle diagonal lines for warmth) ctx.save(); - ctx.globalAlpha = 0.95; - ctx.translate(px, py + yOffset); - - // Activity states - if (activity === 'offline') { - ctx.globalAlpha = 0.5; - ctx.filter = 'grayscale(100%)'; + ctx.beginPath(); + ctx.roundRect(x, y, w, h, r); + ctx.clip(); + ctx.strokeStyle = room.accent + '30'; // 30 = ~19% opacity + ctx.lineWidth = 1; + for (let i = -h; i < w + h; i += 12) { + ctx.beginPath(); + ctx.moveTo(x + i, y); + ctx.lineTo(x + i + h, y + h); + ctx.stroke(); } - - // Draw sprite centered - const sx = img.width > 32 ? 0 : 0; - const spriteW = img.width > 32 ? Math.min(32, img.width) : img.width; - const spriteH = img.height; - ctx.drawImage(img, sx, 0, spriteW, spriteH, -16, -16, 32, 32); - ctx.restore(); - // Blocked: red tint overlay - if (activity === 'blocked') { - ctx.fillStyle = 'rgba(255,50,50,0.3)'; - ctx.fillRect(px - 16, py + yOffset - 16, 32, 32); - ctx.font = 'bold 12px "Courier New", monospace'; - ctx.fillStyle = '#FF4444'; - ctx.textAlign = 'center'; - ctx.fillText('!', px, py + yOffset - 24); + // Wall border + ctx.strokeStyle = room.wall; + ctx.lineWidth = 3; + ctx.beginPath(); + ctx.roundRect(x, y, w, h, r); + ctx.stroke(); + + // Doorways — gaps in the bottom wall + const doorWidth = TILE * SCALE; + ctx.fillStyle = '#8a7a6a'; // doorframe color + // Left door + ctx.fillRect(x + 1 * TILE * SCALE - doorWidth/2, y + h - 3, doorWidth, 6); + // Right door + if (room.w >= 5) { + ctx.fillRect(x + (room.w - 2) * TILE * SCALE - doorWidth/2, y + h - 3, doorWidth, 6); } - // Agent name below (centered with shadow) - ctx.font = '9px "Courier New", monospace'; + // Room name label — small, above room + ctx.fillStyle = room.wall; + ctx.font = `bold ${Math.round(11 * SCALE / 2.5)}px 'EB Garamond', serif`; ctx.textAlign = 'center'; - ctx.fillStyle = '#000'; - ctx.fillText(agent.name || agent.id, px + 1, py + yOffset + 27); - ctx.fillStyle = '#FFF'; - ctx.fillText(agent.name || agent.id, px, py + yOffset + 26); + ctx.textBaseline = 'bottom'; + ctx.fillText(room.name, x + w / 2, y - 4); +} - // Thinking bubble - if (activity === 'thinking') { - ctx.font = 'bold 10px "Courier New", monospace'; - ctx.textAlign = 'center'; - const bubbleW = 24; - const bubbleH = 14; - const bx = px - bubbleW / 2; - const by = py + yOffset - 44; +// Draw simple furniture shapes +function drawFurniture(ctx, room, ox, oy) { + const items = furniture[room.id] || []; + items.forEach(item => { + const x = (room.x + item.rx) * TILE * SCALE + ox; + const y = (room.y + item.ry) * TILE * SCALE + oy; + const w = (item.w || 1) * TILE * SCALE; + const h = (item.h || 1) * TILE * SCALE; - ctx.fillStyle = '#FFF'; - ctx.beginPath(); - ctx.roundRect(bx, by, bubbleW, bubbleH, 3); - ctx.fill(); - ctx.strokeStyle = '#CCC'; - ctx.lineWidth = 1; - ctx.stroke(); - ctx.fillStyle = '#333'; - ctx.fillText('...', px, py + yOffset - 33); - } - - // Sparkles for working - if (activity === 'working') { - if (Math.random() < 0.3) { - spawnSparkle(px + (Math.random() - 0.5) * 24, py + yOffset - 12); + ctx.save(); + switch (item.type) { + case 'table': + ctx.fillStyle = room.accent; + ctx.beginPath(); + ctx.roundRect(x + 2, y + 2, w - 4, h - 4, 3); + ctx.fill(); + ctx.strokeStyle = room.wall + '60'; + ctx.lineWidth = 1; + ctx.stroke(); + break; + case 'desk': + ctx.fillStyle = room.accent; + ctx.fillRect(x + 2, y + 4, w - 4, h - 8); + ctx.strokeStyle = room.wall + '80'; + ctx.lineWidth = 1; + ctx.strokeRect(x + 2, y + 4, w - 4, h - 8); + break; + case 'chair': + ctx.fillStyle = room.wall; + ctx.fillRect(x + 8, y + 8, TILE * SCALE - 16, TILE * SCALE - 16); + break; + case 'monitor': + ctx.fillStyle = '#1a1a2e'; + ctx.fillRect(x + 10, y + 6, TILE * SCALE - 20, TILE * SCALE * 0.5); + ctx.fillStyle = '#4a9eff'; + ctx.fillRect(x + 12, y + 8, TILE * SCALE - 24, TILE * SCALE * 0.5 - 6); + break; + case 'sofa': + ctx.fillStyle = room.accent + 'cc'; + ctx.beginPath(); + ctx.roundRect(x + 2, y + 2, w - 4, h - 4, 4); + ctx.fill(); + ctx.strokeStyle = room.wall; + ctx.lineWidth = 1; + ctx.stroke(); + break; + case 'shelf': + case 'bookcase': + ctx.fillStyle = room.wall; + ctx.fillRect(x + 2, y + 2, w - 4, h - 4); + // Book spines + for (let b = 0; b < Math.min(w / 6, 8); b++) { + ctx.fillStyle = ['#c44','#4a4','#44a','#a4a','#ca4'][b % 5]; + ctx.fillRect(x + 4 + b * 6, y + 4, 4, h - 8); + } + break; + case 'plant': + ctx.fillStyle = '#2a6a2a'; + ctx.beginPath(); + ctx.arc(x + TILE * SCALE / 2, y + TILE * SCALE / 2, TILE * SCALE / 3, 0, Math.PI * 2); + ctx.fill(); + ctx.fillStyle = '#5a3a1a'; + ctx.fillRect(x + TILE * SCALE / 2 - 4, y + TILE * SCALE / 2 + 4, 8, 8); + break; + case 'lamp': + ctx.fillStyle = '#ffd700'; + ctx.beginPath(); + ctx.arc(x + TILE * SCALE / 2, y + TILE * SCALE / 2, 6, 0, Math.PI * 2); + ctx.fill(); + // Glow + const grad = ctx.createRadialGradient( + x + TILE * SCALE / 2, y + TILE * SCALE / 2, 2, + x + TILE * SCALE / 2, y + TILE * SCALE / 2, 20 + ); + grad.addColorStop(0, 'rgba(255,215,0,0.3)'); + grad.addColorStop(1, 'rgba(255,215,0,0)'); + ctx.fillStyle = grad; + ctx.beginPath(); + ctx.arc(x + TILE * SCALE / 2, y + TILE * SCALE / 2, 20, 0, Math.PI * 2); + ctx.fill(); + break; + case 'screen': + ctx.fillStyle = '#2a2a3e'; + ctx.fillRect(x + 2, y + 2, w - 4, h - 4); + ctx.fillStyle = '#3a5aff'; + ctx.fillRect(x + 4, y + 4, w - 8, h - 8); + break; } - } - - ctx.textAlign = 'start'; + ctx.restore(); + }); } -function drawParticles(ctx) { - sparkles = sparkles.filter(s => s.life > 0); - for (const s of sparkles) { - s.x += s.vx; - s.y += s.vy; - s.life -= s.decay; - const alpha = Math.max(0, s.life); - ctx.fillStyle = s.color; - ctx.globalAlpha = alpha; - ctx.fillRect(s.x, s.y, 2, 2); - } - ctx.globalAlpha = 1; +// Draw hallway +function drawHallway(ctx, ox, oy) { + const hw = COLS * TILE * SCALE; + const hh = ROWS * TILE * SCALE; + + // Background + ctx.fillStyle = '#1a1a28'; + ctx.fillRect(ox, oy, hw, hh); + + // Hallway tiles + hallwayTiles.forEach(({ x, y }) => { + const px = x * TILE * SCALE + ox; + const py = y * TILE * SCALE + oy; + ctx.fillStyle = '#2a2a3e'; + ctx.fillRect(px, py, TILE * SCALE, TILE * SCALE); + // Subtle grid + ctx.strokeStyle = '#3a3a4e'; + ctx.lineWidth = 0.5; + ctx.strokeRect(px, py, TILE * SCALE, TILE * SCALE); + }); } -// ── Component ───────────────────────────────────────────────────── -export default function FarmCanvas({ onAgentClick, onAgentHover }) { +// Draw an agent +function drawAgent(ctx, agent, ox, oy) { + const img = spriteImages[agent.id]; + if (!img || !img.complete || img.naturalWidth === 0) return; + + const sx = agent.x * TILE * SCALE + ox; + const sy = agent.y * TILE * SCALE + oy; + const spriteSize = 32 * SPRITE_SCALE; + + // Center sprite on tile + const dx = sx + (TILE * SCALE - spriteSize) / 2; + const dy = sy + (TILE * SCALE - spriteSize) / 2 - 4; // slight lift + + // Shadow + ctx.fillStyle = 'rgba(0,0,0,0.2)'; + ctx.beginPath(); + ctx.ellipse(dx + spriteSize / 2, dy + spriteSize + 2, spriteSize / 3, 4, 0, 0, Math.PI * 2); + ctx.fill(); + + // Sprite + ctx.imageSmoothingEnabled = false; + ctx.drawImage(img, dx, dy, spriteSize, spriteSize); + + // Activity indicator dot + const statusColors = { + active: '#4aff4a', + idle: '#888', + error: '#ff4444', + offline: '#555', + }; + const color = statusColors[agent.status] || statusColors.idle; + ctx.fillStyle = color; + ctx.beginPath(); + ctx.arc(dx + spriteSize - 4, dy + 4, 4, 0, Math.PI * 2); + ctx.fill(); + ctx.strokeStyle = '#000'; + ctx.lineWidth = 1; + ctx.stroke(); +} + +export default function FarmCanvas() { const canvasRef = useRef(null); - const animRef = useRef(null); const agents = useStore(s => s.agents); - const agentList = React.useMemo(() => Object.values(agents), [agents]); + const hoveredAgent = useStore(s => s.hoveredAgent); + const setHoveredAgent = useStore(s => s.setHoveredAgent); + const selectAgent = useStore(s => s.selectAgent); + const containerRef = useRef(null); - // Hover state - const [hoveredAgent, setHoveredAgent] = useState(null); - const hoveredRef = useRef(null); + const canvasWidth = COLS * TILE * SCALE; + const canvasHeight = ROWS * TILE * SCALE; - // Detect agent under mouse - const getAgentAtPoint = useCallback((mx, my) => { - for (const agent of [...agentList].reverse()) { - const pos = agent._smoothPos || agent.position; - if (!pos) continue; - const px = pos.col * TILE_SIZE + TILE_SIZE / 2; - const py = pos.row * TILE_SIZE + TILE_SIZE / 2; - if (Math.abs(mx - px) < 20 && Math.abs(my - py) < 20) { - return agent; + const render = useCallback(() => { + const canvas = canvasRef.current; + if (!canvas) return; + const ctx = canvas.getContext('2d'); + + // Clear + ctx.clearRect(0, 0, canvasWidth, canvasHeight); + + // Background + ctx.fillStyle = '#1a1a28'; + ctx.fillRect(0, 0, canvasWidth, canvasHeight); + + // Draw hallways + drawHallway(ctx, 0, 0); + + // Draw rooms + rooms.forEach(room => { + drawRoom(ctx, room, 0, 0); + drawFurniture(ctx, room, 0, 0); + }); + + // Draw agents (sorted so hovered agent renders on top) + const sortedAgents = [...agents].sort((a, b) => { + if (a.id === hoveredAgent) return 1; + if (b.id === hoveredAgent) return -1; + return 0; + }); + sortedAgents.forEach(agent => drawAgent(ctx, agent, 0, 0)); + + // Hover highlight + if (hoveredAgent) { + const agent = agents.find(a => a.id === hoveredAgent); + if (agent) { + const hx = agent.x * TILE * SCALE; + const hy = agent.y * TILE * SCALE; + ctx.strokeStyle = '#ffd700'; + ctx.lineWidth = 2; + ctx.beginPath(); + ctx.roundRect(hx + 2, hy + 2, TILE * SCALE - 4, TILE * SCALE - 4, 4); + ctx.stroke(); } } - return null; - }, [agentList]); + }, [agents, hoveredAgent]); - // Mouse move → hover detection + useEffect(() => { + render(); + }, [render]); + + // Handle mouse for hover detection const handleMouseMove = useCallback((e) => { const canvas = canvasRef.current; if (!canvas) return; const rect = canvas.getBoundingClientRect(); - const scaleX = CANVAS_W / rect.width; - const scaleY = CANVAS_H / rect.height; + const scaleX = canvasWidth / rect.width; + const scaleY = canvasHeight / rect.height; const mx = (e.clientX - rect.left) * scaleX; const my = (e.clientY - rect.top) * scaleY; - const agent = getAgentAtPoint(mx, my); - hoveredRef.current = agent; - setHoveredAgent(agent); - if (onAgentHover) onAgentHover(agent); - }, [getAgentAtPoint, onAgentHover]); - // Mouse leave → clear hover - const handleMouseLeave = useCallback(() => { - hoveredRef.current = null; - setHoveredAgent(null); - if (onAgentHover) onAgentHover(null); - }, [onAgentHover]); + const tx = Math.floor(mx / (TILE * SCALE)); + const ty = Math.floor(my / (TILE * SCALE)); - // Canvas click → open detail card for hovered agent - const handleCanvasClick = useCallback((e) => { - const agent = hoveredRef.current; - if (agent) { - onAgentClick(agent); + // Find agent at this tile + const found = agents.find(a => { + const ax = Math.floor(a.x); + const ay = Math.floor(a.y); + return (tx === ax && ty === ay) || (tx === ax && ty === ay - 1); + }); + + setHoveredAgent(found ? found.id : null); + }, [agents, setHoveredAgent]); + + const handleClick = useCallback((e) => { + if (hoveredAgent) { + selectAgent(hoveredAgent); } - }, [onAgentClick]); - - // Animation loop - useEffect(() => { - const canvas = canvasRef.current; - if (!canvas) return; - const ctx = canvas.getContext('2d'); - ctx.imageSmoothingEnabled = false; // pixel-art crisp - - // Pre-load tileset - loadTileset(); - let startTime = Date.now(); - - function loop() { - const time = Date.now() - startTime; - ctx.clearRect(0, 0, CANVAS_W, CANVAS_H); - - // Layer 1: Background (outdoor area around building) - drawBackground(ctx); - - // Layer 2: Floor tiles (from tileset) - drawFloorLayer(ctx); - - // Layer 3: Walls (from tileset, drawn on top of floors) - drawWallLayer(ctx); - - // Layer 3.5: Doorways (openings in walls) - drawDoorways(ctx); - - // Layer 4: Furniture - drawFurniture(ctx); - - // Room labels - drawRoomLabels(ctx); - - // Layer 5: Agents - const currentAgents = useStore.getState().agents; - for (const agent of Object.values(currentAgents)) { - drawAgent(ctx, agent, time); - } - - // Hover tooltip - const hAgent = hoveredRef.current; - if (hAgent) { - const pos = hAgent._smoothPos || hAgent.position; - if (pos) { - const hpx = pos.col * TILE_SIZE + TILE_SIZE / 2; - const hpy = pos.row * TILE_SIZE + TILE_SIZE / 2; - const activity = hAgent.activity || 'idle'; - const name = hAgent.name || hAgent.id; - const task = hAgent.currentTask || hAgent.task || ''; - - const statusColors = { - idle: '#44cc44', working: '#ffcc00', thinking: '#44aaff', - offline: '#888', blocked: '#ff4444', - }; - const statusColor = statusColors[activity] || '#888'; - - ctx.font = '10px "Courier New", monospace'; - const nameW = ctx.measureText(name).width; - ctx.font = '9px "Courier New", monospace'; - const statusW = ctx.measureText(activity).width; - const taskW = task ? Math.min(ctx.measureText(task).width, 180) : 0; - const tooltipW = Math.max(nameW + 28, statusW + taskW + 8) + 16; - const tooltipH = task ? 48 : 36; - - const tx = Math.min(hpx + 10, CANVAS_W - tooltipW - 4); - const ty = Math.max(hpy - tooltipH - 24, 4); - - // Tooltip background - ctx.fillStyle = 'rgba(0,0,0,0.82)'; - ctx.beginPath(); - ctx.roundRect(tx, ty, tooltipW, tooltipH, 6); - ctx.fill(); - ctx.strokeStyle = 'rgba(255,255,255,0.2)'; - ctx.lineWidth = 1; - ctx.stroke(); - - // Name - ctx.font = 'bold 10px "Courier New", monospace'; - ctx.textAlign = 'left'; - ctx.fillStyle = '#FFF'; - ctx.fillText(name, tx + 8, ty + 14); - - // Status badge - ctx.font = '9px "Courier New", monospace'; - ctx.fillStyle = 'rgba(0,0,0,0.5)'; - ctx.beginPath(); - ctx.roundRect(tx + nameW + 12, ty + 5, statusW + 8, 14, 3); - ctx.fill(); - ctx.fillStyle = statusColor; - ctx.fillText(activity, tx + nameW + 16, ty + 15); - - // Task line - if (task) { - ctx.font = '8px "Courier New", monospace'; - ctx.fillStyle = '#aaa'; - const taskText = task.length > 35 ? task.slice(0, 32) + '...' : task; - ctx.fillText(taskText, tx + 8, ty + 34); - } - } - } - - drawParticles(ctx); - - animRef.current = requestAnimationFrame(loop); - } - - loop(); - return () => { - if (animRef.current) cancelAnimationFrame(animRef.current); - }; - }, []); + }, [hoveredAgent, selectAgent]); return ( -
+
); -} +} \ No newline at end of file diff --git a/src/frontend/WebSocketClient.js b/src/frontend/WebSocketClient.js index ad5cd0a..fa4427a 100644 --- a/src/frontend/WebSocketClient.js +++ b/src/frontend/WebSocketClient.js @@ -153,15 +153,30 @@ class WebSocketClient { ); } - // Occasionally move agents - if (cycle % 10 === 0) { + // Occasionally move agents (with collision avoidance) + if (cycle % 8 === 0) { const agentId = agentIds[Math.floor(Math.random() * agentIds.length)]; - const pos = store.agents[agentId]?.position; + const pos = store.agents[agentId]?.targetPosition || store.agents[agentId]?.position; if (pos) { - store.updateAgentPosition(agentId, { - row: Math.max(1, Math.min(18, pos.row + (Math.random() - 0.5) * 4)), - col: Math.max(1, Math.min(26, pos.col + (Math.random() - 0.5) * 6)), - }); + // Check ALL other agents' current AND target positions + const occupied = new Set( + Object.entries(store.agents) + .filter(([id]) => id !== agentId) + .flatMap(([, a]) => { + const pts = []; + if (a.position) pts.push(`${a.position.row},${a.position.col}`); + if (a.targetPosition) pts.push(`${a.targetPosition.row},${a.targetPosition.col}`); + if (a._smoothPos) pts.push(`${Math.round(a._smoothPos.row)},${Math.round(a._smoothPos.col)}`); + return pts; + }) + ); + let newRow, newCol, attempts = 0; + do { + newRow = Math.max(1, Math.min(18, pos.row + Math.floor((Math.random() - 0.5) * 10))); + newCol = Math.max(1, Math.min(26, pos.col + Math.floor((Math.random() - 0.5) * 14))); + attempts++; + } while (occupied.has(`${newRow},${newCol}`) && attempts < 20); + store.updateAgentPosition(agentId, { row: newRow, col: newCol }); } } }, 1000); diff --git a/src/frontend/officeMap.js b/src/frontend/officeMap.js index cec373b..9ac3430 100644 --- a/src/frontend/officeMap.js +++ b/src/frontend/officeMap.js @@ -1,421 +1,134 @@ -// Tile map for spatial office using LimeZu Modern Interiors tileset -// Tileset: 16 tiles wide × 89 tiles tall, each tile 32×32px -// Room-builder: 17 tiles wide × 23 tiles tall, floor textures and wall variants +// officeMap.js — Clean room definitions for the Scobleclaw Virtual Office +// No tile IDs, no guessing. Just rooms with colors and furniture. -// Map dimensions: 20 cols × 15 rows = 640×480 internal px (scaled via canvas CSS) -export const MAP_COLS = 20; -export const MAP_ROWS = 15; -export const TILE_SIZE = 32; +const TILE = 32; // pixels per tile +const COLS = 25; +const ROWS = 20; -// ── Tile IDs from tileset.png (16-wide grid) ──────────────────── -// Tile grid position: tileId = row * 16 + col -export const TILES = { - EMPTY: -1, - - // ── Ground / outdoor tiles ────────────────────────────── - // We'll use the room-builder for grass/outdoor if needed - GRASS: -2, // drawn procedurally - - // ── Floor tiles from tileset.png ──────────────────────── - // Wood floor variants (row 1, cols 0-3): tile IDs 16-19 - FLOOR_WOOD_LIGHT: 16, // (r1,c0) - light wood planks - FLOOR_WOOD_LIGHT2: 18, // (r1,c2) - light wood variant - FLOOR_WOOD_LIGHT3: 19, // (r1,c3) - light wood variant - - // Stone/checkered floor (row 5-6): tile IDs ~83-99 - FLOOR_STONE: 83, // (r5,c3) - stone floor - FLOOR_STONE2: 99, // (r6,c3) - stone floor variant - - // Carpet tiles (row 1, cols 6-13): tile IDs 22-29 - FLOOR_CARPET_GREEN: 22, // (r1,c6) - greenish carpet - FLOOR_CARPET_GREEN2: 23, // (r1,c7) - green variant - FLOOR_CARPET_BROWN: 25, // (r1,c9) - brown carpet - FLOOR_CARPET_BROWN2: 26, // (r1,c10) - brown variant - - // Dark blue/study floor (row 2, cols 6-14): tile IDs 38-46 - FLOOR_STUDY: 38, // (r2,c6) - dark blue study carpet - FLOOR_STUDY2: 39, // (r2,c7) - variant - - // Gray tile floor (row 3, cols 6-11): tile IDs 54-59 - FLOOR_GRAY_TILE: 54, // (r3,c6) - gray tile - FLOOR_GRAY_TILE2: 55, // (r3,c7) - variant - - // Warm wood floor (row 4): tile IDs 67-68 - FLOOR_WARM_WOOD: 67, // (r4,c3) - warm wood planks - FLOOR_WARM_WOOD2: 68, // (r4,c4) - variant - - // Plush carpet (row 4, cols 6-9): tile IDs 70-73 - FLOOR_PLUSH: 70, // (r4,c6) - plush pink/tan carpet - FLOOR_PLUSH2: 71, // (r4,c7) - variant - - // ── Wall tiles from tileset.png ───────────────────────── - // Wall sections (row 16+): stone/brick walls - // Interior wall (row 16-17): tile IDs ~257-287 - WALL_BRICK: 258, // (r16,c2) - brick wall body - WALL_BRICK2: 259, // (r16,c3) - brick variant - WALL_BRICK_TOP: 257, // (r16,c1) - brick wall top edge - WALL_BRICK_BOTTOM: 274, // (r17,c2) - brick wall bottom - - // Dark wall (row 26-28): tile IDs ~416-461 - WALL_DARK: 433, // (r27,c1) - dark wall body - WALL_DARK2: 434, // (r27,c2) - variant - - // Light plaster wall (row 28-29): tile IDs ~448-477 - WALL_PLASTER: 464, // (r29,c0) - plaster wall body - WALL_PLASTER_TOP: 466, // (r29,c2) - top with shadow - - // Interior wood wall (room-builder, row 5 col 2-3): room-builder tiles - // We reference room-builder walls separately - - // ── Door tiles from tileset.png ───────────────────────── - // Doors are typically in the wall sections - DOOR_WOOD: 296, // (r18,c8) - red/wood door, closed - DOOR_WOOD2: 297, // (r18,c9) - variant - - // ── Window tiles ──────────────────────────────────────── - WINDOW: 305, // (r19,c1) - window hint - WINDOW_GLASS: 300, // (r18,c12) - glass pane - - // ── Furniture tiles (approximate from analysis) ──────── - // These are in the tileset rows 33-65 - TABLE_WOOD: 580, // (r36,c4) - table top - CHAIR_WOOD: 528, // (r33,c0) - wooden chair - DESK: 583, // (r36,c7) - desk surface - BOOKSHELF: 736, // (r46,c0) - bookshelf - BOOKSHELF2: 737, // (r46,c1) - bookshelf variant - PLANT: 584, // (r36,c8) - potted plant - PLANT2: 587, // (r36,c11) - plant variant - LAMP: 674, // (r42,c2) - lamp/light - SOFA_LEFT: 736, // Using bookshelf area as sofa placeholder - SOFA_RIGHT: 737, - FILING_CABINET: 744, // (r46,c8) - cabinet/locker - RUG: 652, // (r40,c12) - decorative rug - COFFEE_TABLE: 672, // (r42,c0) - low table - PLANT_BIG: 632, // (r39,c8) - large plant - MONITOR: 744, // Monitor-like object - WHITEBOARD: 709, // (r44,c5) - whiteboard/wall decor -}; -// ── Room builder tiles (separate PNG) ────────────────────────── -// These are for floor/wall variants from room-builder.png -// Room-builder is 17 tiles wide -export const RB_TILES = { - // Wall textures (rows 5-15 in room-builder) - WALL_RED_BRICK: 80, // (r5,c0) - red brick wall - WALL_RED_BRICK2: 81, // (r5,c1) - variant - WALL_DARK_WOOD: 84, // (r5,c4) - dark wood panel - WALL_CREAM: 112, // (r7,c0) - cream/yellow wall - WALL_CREAM2: 113, // (r7,c1) - variant - WALL_BROWN_WOOD: 128, // (r8,c0) - brown wood panel - WALL_TEAL: 144, // (r9,c0) - teal wall - WALL_GREEN: 160, // (r10,c0) - green wall - WALL_STONE_WARM: 176, // (r11,c0) - warm stone - WALL_BEIGE: 192, // (r12,c0) - beige wall - WALL_GRAY_STONE: 208, // (r13,c0) - gray stone - WALL_RED_STONE: 240, // (r15,c0) - red stone - - // Floor tiles (scattered in room-builder) - FLOOR_STONE_BEIGE: 48, // (r3,c0) area - beige stone - FLOOR_STONE_BEIGE2: 49, -}; - -// ── Room definitions ────────────────────────────────────────── -export const ROOMS = { - 'briefing': { name: 'Briefing Room', col: 0, row: 3, w: 6, h: 3, floor: 'FLOOR_WOOD_LIGHT' }, - 'commons': { name: 'Commons', col: 6, row: 3, w: 8, h: 3, floor: 'FLOOR_CARPET_GREEN' }, - 'war-room': { name: 'War Room', col: 14, row: 3, w: 6, h: 3, floor: 'FLOOR_STONE' }, - 'eng-bay': { name: 'Engineering Bay', col: 0, row: 9, w: 6, h: 6, floor: 'FLOOR_WARM_WOOD' }, - 'quiet': { name: 'Quiet Zone', col: 6, row: 9, w: 8, h: 4, floor: 'FLOOR_STUDY' }, - 'ops': { name: 'Ops Center', col: 14, row: 9, w: 6, h: 6, floor: 'FLOOR_GRAY_TILE' }, -}; - -// ── Hallway tile markers ────────────────────────────────────── -const HALL = 999; // hallway marker (rendered with hallway floor) -const EMPTY = -1; // outside/void - -// ── Tile type constants for multi-tile rendering ────────────── -// We'll use these as references for the 2D map grid -const F = { - // Floors - WL: 16, // wood light - WL2: 18, // wood light variant - CG: 22, // carpet green - CG2: 23, // carpet green variant - ST: 83, // stone tile - ST2: 99, // stone variant - WW: 67, // warm wood - WW2: 68, // warm wood variant - SD: 38, // study carpet (dark blue) - SD2: 39, // study variant - GT: 54, // gray tile - GT2: 55, // gray tile variant - HL: 70, // hallway (plush carpet) - - // Walls (from tileset) - WB: 258, // wall brick - WB2: 259, // wall brick variant - WT: 257, // wall top - WWD: 464, // wood wall dark - WWD2: 465,// wood wall dark variant - - // Furniture - TB: 528, // table/chair base - DK: 936, // desk - BS: 736, // bookshelf - PL: 584, // plant - LP: 889, // lamp - SF: 674, // sofa - FC: 1012, // filing cabinet - RG: 672, // rug/coffee table - MB: 996, // monitor - CB: 1010, // cabinet - DO: 296, // door -}; - -// ── Office Map: 20 columns × 15 rows ───────────────────────── -// Each cell is a base tile ID. Walls are drawn on top as border tiles. -// Row 0-2: exterior wall / roof area -// Row 3-5: upper rooms (Briefing, Commons, War Room) -// Row 6-8: hallway -// Row 9-14: lower rooms (Engineering Bay, Quiet Zone, Ops Center) - -export const OFFICE_MAP = [ - // Row 0: Exterior top wall - [EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, - EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY], - // Row 1: Exterior wall top edge - [EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, - EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY], - // Row 2: Exterior wall (north wall) - [EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, - EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY], - - // Row 3: Upper rooms - floor with wall separators - // BR = Briefing Room (col 0-5), Commons (col 6-13), War Room (col 14-19) - [F.WL, F.WL, F.WL, F.WL, F.WL, F.WL, F.CG, F.CG, F.CG, F.CG, - F.CG, F.CG, F.CG, F.CG, F.ST, F.ST, F.ST, F.ST, F.ST, F.ST], - - // Row 4: Upper rooms continue - [F.WL, F.WL, F.WL2, F.WL, F.WL2, F.WL, F.CG, F.CG2, F.CG, F.CG2, - F.CG, F.CG2, F.CG, F.CG, F.ST, F.ST2, F.ST, F.ST2, F.ST, F.ST], - - // Row 5: Upper rooms bottom row - [F.WL2, F.WL2, F.WL, F.WL2, F.WL, F.WL2, F.CG2, F.CG, F.CG2, F.CG, - F.CG2, F.CG, F.CG2, F.CG, F.ST2, F.ST, F.ST2, F.ST, F.ST2, F.ST], - - // Row 6: HALLWAY (connects all rooms) - [F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, - F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, F.HL], - - // Row 7: HALLWAY center - [F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, - F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, F.HL], - - // Row 8: HALLWAY bottom - [F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, - F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, F.HL, F.HL], - - // Row 9: Lower rooms - // Engineering Bay (col 0-5), Quiet Zone (col 6-13), Ops Center (col 14-19) - [F.WW, F.WW, F.WW, F.WW, F.WW, F.WW, F.SD, F.SD, F.SD, F.SD, - F.SD, F.SD, F.SD, F.SD, F.GT, F.GT, F.GT, F.GT, F.GT, F.GT], - - // Row 10: Lower rooms - [F.WW2, F.WW, F.WW2, F.WW, F.WW2, F.WW, F.SD2, F.SD, F.SD2, F.SD, - F.SD2, F.SD, F.SD2, F.SD, F.GT2, F.GT, F.GT2, F.GT, F.GT2, F.GT], - - // Row 11: Lower rooms - [F.WW, F.WW2, F.WW, F.WW2, F.WW, F.WW2, F.SD, F.SD2, F.SD, F.SD2, - F.SD, F.SD2, F.SD, F.SD2, F.GT, F.GT2, F.GT, F.GT2, F.GT, F.GT2], - - // Row 12: Lower rooms / quiet zone ends - [F.WW2, F.WW, F.WW2, F.WW, F.WW2, F.WW, F.SD2, F.SD, F.SD2, F.SD, - F.SD2, F.SD, F.SD2, F.SD, F.GT2, F.GT, F.GT2, F.GT, F.GT2, F.GT], - - // Row 13: Lower rooms - [F.WW, F.WW2, F.WW, F.WW2, F.WW, F.WW2, EMPTY, EMPTY, EMPTY, EMPTY, - EMPTY, EMPTY, EMPTY, EMPTY, F.GT, F.GT2, F.GT, F.GT2, F.GT, F.GT2], - - // Row 14: Bottom row - lower rooms + exterior bottom wall - [F.WW2, F.WW, F.WW2, F.WW, F.WW2, F.WW, EMPTY, EMPTY, EMPTY, EMPTY, - EMPTY, EMPTY, EMPTY, EMPTY, F.GT2, F.GT, F.GT2, F.GT, F.GT2, F.GT], +// Room layout: rooms are defined by their bounding box + visual style +// Each agent gets a "desk" position in their department room +const rooms = [ + { + id: 'briefing', + name: 'Briefing Room', + x: 1, y: 1, w: 7, h: 5, + floor: '#c9a86c', // warm wood + wall: '#5a4a3a', + accent: '#8b7355', + }, + { + id: 'commons', + name: 'Commons', + x: 9, y: 1, w: 7, h: 5, + floor: '#b8c9a0', // sage green + wall: '#4a5a3a', + accent: '#6b8a50', + }, + { + id: 'warroom', + name: 'War Room', + x: 17, y: 1, w: 7, h: 5, + floor: '#d4c4a8', // light stone + wall: '#6a5a4a', + accent: '#8a7a60', + }, + { + id: 'engineering', + name: 'Engineering Bay', + x: 1, y: 8, w: 7, h: 5, + floor: '#a8c4d4', // cool blue-grey + wall: '#3a5a6a', + accent: '#5080a0', + }, + { + id: 'quiet', + name: 'Quiet Zone', + x: 9, y: 8, w: 7, h: 5, + floor: '#d4d0e8', // soft lavender + wall: '#5a5070', + accent: '#8070a0', + }, + { + id: 'ops', + name: 'Ops Center', + x: 17, y: 8, w: 7, h: 5, + floor: '#c8d8d0', // mint + wall: '#4a6a5a', + accent: '#608a70', + }, ]; -// ── Wall definitions (drawn on top of floors) ──────────────── -// Each wall entry: { row, col, tileId } -// Walls between rooms at column boundaries and row boundaries -export const WALLS = [ - // Exterior walls (row 0-2) - // North wall row - ...Array.from({ length: 20 }, (_, c) => ({ row: 2, col: c, tile: F.WB2 })), +// Agent desk positions — where each agent "sits" in their room +// Positioned at center-ish of each room +const agentDesks = { + cos: { room: 'briefing', tx: 4, ty: 3 }, + content: { room: 'commons', tx: 12, ty: 3 }, + market: { room: 'warroom', tx: 20, ty: 3 }, + engineering: { room: 'engineering', tx: 4, ty: 10 }, + 'senior-eng': { room: 'quiet', tx: 12, ty: 10 }, + trust: { room: 'ops', tx: 20, ty: 10 }, + health: { room: 'briefing', tx: 2, ty: 3 }, // shares briefing + vault: { room: 'commons', tx: 10, ty: 3 }, // shares commons + presentations:{ room: 'ops', tx: 22, ty: 10 }, // shares ops +}; - // Vertical walls between rooms (wall at column 5 between Briefing/Commons) - { row: 3, col: 5, tile: F.WB }, - { row: 4, col: 5, tile: F.WB }, - // Doorway at row 5, col 5 (hallway level) - { row: 3, col: 13, tile: F.WB }, - { row: 4, col: 13, tile: F.WB }, - // Doorway at row 5, col 13 +// Hallway tiles connecting rooms +// Top hallway: y=6-7, bottom hallway: y=14-15 +// Left hallway: x=8, right hallway: x=16 +const hallwayTiles = []; +// Top row hallway +for (let x = 1; x < 24; x++) { + hallwayTiles.push({ x, y: 6 }); + hallwayTiles.push({ x, y: 7 }); +} +// Bottom row hallway +for (let x = 1; x < 24; x++) { + hallwayTiles.push({ x, y: 14 }); + hallwayTiles.push({ x, y: 15 }); +} +// Left vertical connector +for (let y = 6; y <= 15; y++) { + hallwayTiles.push({ x: 8, y }); + hallwayTiles.push({ x: 16, y }); +} - // Vertical walls below hallway - { row: 9, col: 5, tile: F.WB }, - { row: 10, col: 5, tile: F.WB }, - { row: 11, col: 5, tile: F.WB }, - { row: 12, col: 5, tile: F.WB }, - { row: 13, col: 5, tile: F.WB }, - { row: 14, col: 5, tile: F.WB }, +// Furniture definitions: type + tile position relative to room origin +const furniture = { + briefing: [ + { type: 'table', rx: 3, ry: 2, w: 3, h: 2 }, // conference table + { type: 'chair', rx: 2, ry: 2 }, + { type: 'chair', rx: 6, ry: 2 }, + { type: 'plant', rx: 6, ry: 0 }, + ], + commons: [ + { type: 'sofa', rx: 2, ry: 1, w: 3, h: 1 }, + { type: 'table', rx: 3, ry: 2, w: 2, h: 1 }, + { type: 'shelf', rx: 0, ry: 0, w: 1, h: 2 }, + { type: 'plant', rx: 6, ry: 0 }, + ], + warroom: [ + { type: 'table', rx: 3, ry: 2, w: 3, h: 2 }, + { type: 'screen', rx: 0, ry: 1, w: 1, h: 2 }, + { type: 'chair', rx: 2, ry: 2 }, + { type: 'chair', rx: 6, ry: 2 }, + ], + engineering: [ + { type: 'desk', rx: 3, ry: 2, w: 2, h: 1 }, + { type: 'monitor',rx: 3, ry: 2 }, + { type: 'desk', rx: 1, ry: 3, w: 2, h: 1 }, + { type: 'shelf', rx: 5, ry: 0, w: 1, h: 2 }, + ], + quiet: [ + { type: 'desk', rx: 3, ry: 2, w: 2, h: 1 }, + { type: 'lamp', rx: 2, ry: 1 }, + { type: 'bookcase',rx: 5, ry: 0, w: 1, h: 3 }, + ], + ops: [ + { type: 'table', rx: 3, ry: 2, w: 3, h: 2 }, + { type: 'monitor',rx: 1, ry: 2 }, + { type: 'monitor',rx: 6, ry: 2 }, + { type: 'screen', rx: 0, ry: 1, w: 1, h: 2 }, + ], +}; - { row: 9, col: 13, tile: F.WB }, - { row: 10, col: 13, tile: F.WB }, - { row: 11, col: 13, tile: F.WB }, - { row: 12, col: 13, tile: F.WB }, - { row: 13, col: 13, tile: F.WB }, - { row: 14, col: 13, tile: F.WB }, - - // Horizontal wall between upper rooms and hallway (row 5 bottom edge) - ...Array.from({ length: 6 }, (_, c) => ({ row: 5, col: c, tile: F.WB2 })), - ...Array.from({ length: 8 }, (_, c) => ({ row: 5, col: c + 6, tile: F.WB2 })), - ...Array.from({ length: 6 }, (_, c) => ({ row: 5, col: c + 14, tile: F.WB2 })), - - // Horizontal wall between hallway and lower rooms (row 8 bottom edge) - ...Array.from({ length: 6 }, (_, c) => ({ row: 8, col: c, tile: F.WB2 })), - ...Array.from({ length: 8 }, (_, c) => ({ row: 8, col: c + 6, tile: F.WB2 })), - ...Array.from({ length: 6 }, (_, c) => ({ row: 8, col: c + 14, tile: F.WB2 })), - - // Exterior walls (left edge) - { row: 3, col: 0, tile: F.WB }, - { row: 4, col: 0, tile: F.WB }, - { row: 9, col: 0, tile: F.WB }, - { row: 10, col: 0, tile: F.WB }, - { row: 11, col: 0, tile: F.WB }, - { row: 12, col: 0, tile: F.WB }, - { row: 13, col: 0, tile: F.WB }, - { row: 14, col: 0, tile: F.WB }, - - // Exterior walls (right edge) - { row: 3, col: 19, tile: F.WB }, - { row: 4, col: 19, tile: F.WB }, - { row: 9, col: 19, tile: F.WB }, - { row: 10, col: 19, tile: F.WB }, - { row: 11, col: 19, tile: F.WB }, - { row: 12, col: 19, tile: F.WB }, - { row: 13, col: 19, tile: F.WB }, - { row: 14, col: 19, tile: F.WB }, - - // Bottom wall (row 14 bottom edge) - ...Array.from({ length: 6 }, (_, c) => ({ row: 14, col: c, tile: F.WB2 })), - ...Array.from({ length: 6 }, (_, c) => ({ row: 14, col: c + 14, tile: F.WB2 })), - - // Wall separators at hallway left/right (row 6-8, col 0/19 already exterior) -]; - -// ── Doorways (openings in walls) ────────────────────────────── -// These overwrite wall tiles at specific positions -export const DOORWAYS = [ - // Briefing Room → Hallway (col 2, row 5) - { row: 5, col: 2, tile: F.DO }, - // Commons → Hallway (col 9, row 5 and row 8) - { row: 5, col: 9, tile: F.DO }, - { row: 8, col: 9, tile: F.DO }, - // War Room → Hallway (col 16, row 5) - { row: 5, col: 16, tile: F.DO }, - // Engineering Bay → Hallway (col 2, row 8) - { row: 8, col: 2, tile: F.DO }, - // Quiet Zone → Hallway (col 9, row 8) same as Commons lower - // Ops Center → Hallway (col 16, row 8) - { row: 8, col: 16, tile: F.DO }, -]; - -// ── Furniture placements ────────────────────────────────────── -// { row, col, tileId } -export const FURNITURE = [ - // === Briefing Room (col 0-5, row 3-5) === - // Round table center - { row: 4, col: 2, tile: F.RG }, - // Chairs around table - { row: 3, col: 1, tile: F.TB }, - { row: 3, col: 3, tile: F.TB }, - { row: 5, col: 1, tile: F.TB }, - { row: 5, col: 3, tile: F.TB }, - // Plant in corner - { row: 4, col: 4, tile: F.PL }, - - // === Commons (col 6-13, row 3-5) === - // Sofa area - { row: 3, col: 7, tile: F.SF }, - { row: 3, col: 8, tile: F.SF }, - // Coffee table - { row: 4, col: 7, tile: F.RG }, - { row: 4, col: 8, tile: F.RG }, - // Plant - { row: 3, col: 10, tile: F.PL }, - { row: 5, col: 7, tile: F.PL }, - // Lamp - { row: 4, col: 11, tile: F.LP }, - - // === War Room (col 14-19, row 3-5) === - // Large table - { row: 4, col: 15, tile: F.RG }, - { row: 4, col: 16, tile: F.RG }, - { row: 4, col: 17, tile: F.RG }, - // Chairs around - { row: 3, col: 15, tile: F.TB }, - { row: 3, col: 16, tile: F.TB }, - { row: 3, col: 17, tile: F.TB }, - { row: 5, col: 15, tile: F.TB }, - { row: 5, col: 16, tile: F.TB }, - { row: 5, col: 17, tile: F.TB }, - // Whiteboard - { row: 3, col: 18, tile: F.MB }, - - // === Engineering Bay (col 0-5, row 9-14) === - // Desks with monitors - { row: 10, col: 1, tile: F.DK }, - { row: 10, col: 2, tile: F.MB }, - { row: 12, col: 1, tile: F.DK }, - { row: 12, col: 2, tile: F.MB }, - { row: 10, col: 4, tile: F.DK }, - { row: 12, col: 4, tile: F.DK }, - // Bookshelf - { row: 9, col: 4, tile: F.BS }, - // Filing cabinet - { row: 9, col: 1, tile: F.FC }, - // Plant - { row: 13, col: 4, tile: F.PL }, - - // === Quiet Zone (col 6-13, row 9-12) === - // Individual desks - { row: 9, col: 7, tile: F.DK }, - { row: 9, col: 9, tile: F.DK }, - { row: 11, col: 7, tile: F.DK }, - { row: 11, col: 9, tile: F.DK }, - // Bookshelf - { row: 10, col: 12, tile: F.BS }, - // Lamp - { row: 9, col: 12, tile: F.LP }, - { row: 11, col: 12, tile: F.LP }, - // Plant - { row: 10, col: 6, tile: F.PL }, - - // === Ops Center (col 14-19, row 9-14) === - // Desks with monitors - { row: 10, col: 15, tile: F.DK }, - { row: 10, col: 16, tile: F.MB }, - { row: 12, col: 15, tile: F.DK }, - { row: 12, col: 16, tile: F.MB }, - { row: 10, col: 18, tile: F.DK }, - { row: 12, col: 18, tile: F.DK }, - // Filing cabinets - { row: 9, col: 15, tile: F.FC }, - { row: 9, col: 16, tile: F.FC }, - // Server rack / cabinet - { row: 9, col: 18, tile: F.CB }, - { row: 14, col: 18, tile: F.CB }, - // Plant - { row: 14, col: 15, tile: F.PL }, - - // === Hallway decorations === - { row: 6, col: 2, tile: F.PL }, - { row: 6, col: 10, tile: F.PL }, - { row: 7, col: 17, tile: F.PL }, - { row: 8, col: 11, tile: F.PL }, -]; +module.exports = { TILE, COLS, ROWS, rooms, agentDesks, hallwayTiles, furniture }; \ No newline at end of file diff --git a/src/frontend/store.js b/src/frontend/store.js index faf70d8..fa82da3 100644 --- a/src/frontend/store.js +++ b/src/frontend/store.js @@ -1,216 +1,95 @@ import { create } from 'zustand'; +import { agentDesks, rooms } from './officeMap'; -// ── Stardew-inspired Zone definitions ─────────────────────────────── -const ZONES = { - 'pod-a': { - id: 'pod-a', - name: 'Workshop', - type: 'collaboration', - color: '#A0522D', - bounds: { row: 2, col: 8, rows: 5, cols: 5 }, - }, - 'pod-b': { - id: 'pod-b', - name: 'Studio', - type: 'collaboration', - color: '#DEB887', - bounds: { row: 2, col: 14, rows: 5, cols: 5 }, - }, - 'solo-1': { - id: 'solo-1', - name: 'Cabins', - type: 'solo', - color: '#8B4513', - bounds: { row: 2, col: 0, rows: 10, cols: 6 }, - }, - 'solo-2': { - id: 'solo-2', - name: 'Library', - type: 'solo', - color: '#5B8FA8', - bounds: { row: 2, col: 22, rows: 10, cols: 6 }, - }, - 'coaching': { - id: 'coaching', - name: 'Shrine', - type: 'self-improvement', - color: '#DAA520', - bounds: { row: 13, col: 8, rows: 4, cols: 12 }, - }, - 'coffee': { - id: 'coffee', - name: 'Campfire', - type: 'social', - color: '#FF8C42', - bounds: { row: 0, col: 10, rows: 2, cols: 8 }, - }, -}; +// Agent definitions with personality +const AGENT_DEFS = [ + { id: 'cos', name: 'Marcus', dept: 'Chief of Staff', color: '#e8833a', status: 'active' }, + { id: 'engineering', name: 'Engineering', dept: 'Engineering Bay', color: '#4ac4c4', status: 'active' }, + { id: 'senior-eng', name: 'Senior Eng', dept: 'Quiet Zone', color: '#9a6adc', status: 'active' }, + { id: 'trust', name: 'Trust', dept: 'Ops Center', color: '#4a7aff', status: 'idle' }, + { id: 'market', name: 'Market', dept: 'War Room', color: '#4aaa4a', status: 'active' }, + { id: 'health', name: 'Health', dept: 'Briefing Room', color: '#eacc4a', status: 'idle' }, + { id: 'content', name: 'Content', dept: 'Commons', color: '#aa7adc', status: 'active' }, + { id: 'presentations', name: 'Presentations', dept: 'Ops Center', color: '#ea6a6a', status: 'active' }, + { id: 'vault', name: 'Vault', dept: 'Commons', color: '#7adcaa', status: 'idle' }, +]; -// ── Agent definitions ────────────────────────────────────────────── -const AGENT_DEFS = { - cos: { id: 'cos', name: 'COS', department: 'cos', color: '#FF6B35' }, - engineering: { id: 'engineering', name: 'Engineering', department: 'engineering', color: '#4ECDC4' }, - 'senior-eng': { id: 'senior-eng', name: 'Senior Eng', department: 'senior-eng', color: '#7B2D8E' }, - trust: { id: 'trust', name: 'Trust', department: 'trust', color: '#45B7D1' }, - market: { id: 'market', name: 'Market', department: 'market', color: '#96CEB4' }, - health: { id: 'health', name: 'Health', department: 'health', color: '#FFEAA7' }, - content: { id: 'content', name: 'Content', department: 'content', color: '#DDA0DD' }, - presentations: { id: 'presentations', name: 'Presentations', department: 'presentations', color: '#FF8A80' }, - vault: { id: 'vault', name: 'Vault', department: 'vault', color: '#A5D6A7' }, -}; - -// ── Default agent positions (row, col in tile coords) ─────────── -// Office layout: 20 cols × 15 rows -// Briefing Room: col 0-5, row 3-5 -// Commons: col 6-13, row 3-5 -// War Room: col 14-19, row 3-5 -// Hallway: row 6-8 -// Engineering Bay: col 0-5, row 9-14 -// Quiet Zone: col 6-13, row 9-12 -// Ops Center: col 14-19, row 9-14 -const DEFAULT_POSITIONS = { - cos: { row: 10, col: 3 }, // Engineering Bay - engineering: { row: 11, col: 2 }, // Engineering Bay - 'senior-eng': { row: 12, col: 3 }, // Engineering Bay - trust: { row: 10, col: 17 }, // Ops Center - market: { row: 4, col: 9 }, // Commons - health: { row: 9, col: 8 }, // Quiet Zone - content: { row: 10, col: 8 }, // Quiet Zone - presentations: { row: 4, col: 16 }, // War Room - vault: { row: 9, col: 17 }, // Ops Center -}; - -// ── Helpers ──────────────────────────────────────────────────────── -function generateTileMap(gridRows, gridCols) { - const tiles = []; - for (let row = 0; row < gridRows; row++) { - tiles[row] = []; - for (let col = 0; col < gridCols; col++) { - tiles[row][col] = { type: 'floor', zoneId: findZoneForTile(row, col) }; - } - } - return { rows: gridRows, cols: gridCols, tiles }; +// Calculate initial positions from desk assignments +function initialAgents() { + return AGENT_DEFS.map(def => { + const desk = agentDesks[def.id]; + return { + ...def, + x: desk ? desk.tx : 12, + y: desk ? desk.ty : 10, + targetX: desk ? desk.tx : 12, + targetY: desk ? desk.ty : 10, + deskX: desk ? desk.tx : 12, + deskY: desk ? desk.ty : 10, + }; + }); } -function findZoneForTile(row, col) { - for (const zone of Object.values(ZONES)) { - const { row: zr, col: zc, rows, cols } = zone.bounds; - if (row >= zr && row < zr + rows && col >= zc && col < zc + cols) { - return zone.id; - } - } - return null; +// Get room bounds for wandering +function getRoomForAgent(agentId) { + const desk = agentDesks[agentId]; + if (!desk) return null; + return rooms.find(r => r.id === desk.room) || null; } -// ── Store ────────────────────────────────────────────────────────── -const useStore = create((set, get) => ({ - // Connection state - wsConnected: false, - wsReconnecting: false, +export const useStore = create((set, get) => ({ + agents: initialAgents(), + hoveredAgent: null, + selectedAgent: null, - // World state - grid: generateTileMap(15, 20), - zones: ZONES, - agents: {}, + setHoveredAgent: (id) => set({ hoveredAgent: id }), + selectAgent: (id) => set({ selectedAgent: id }), + clearSelection: () => set({ selectedAgent: null }), - // Initialize from full state snapshot - initFromSnapshot(snapshot) { - const agents = {}; - for (const agentId of Object.keys(AGENT_DEFS)) { - const def = AGENT_DEFS[agentId]; - const pos = DEFAULT_POSITIONS[agentId]; - agents[agentId] = { - ...def, - position: { row: pos.row, col: pos.col }, - targetPosition: { row: pos.row, col: pos.col }, - activity: 'idle', - currentTask: null, - lastHeartbeat: Date.now(), - pulse: 0, - }; - } - // Apply snapshot overrides if provided - if (snapshot && snapshot.agents) { - for (const [id, data] of Object.entries(snapshot.agents)) { - if (agents[id]) { - Object.assign(agents[id], data); - if (data.position) { - agents[id].targetPosition = { ...data.position }; + // Update agent positions from WS state + updateAgentState: (agentStates) => { + set(s => ({ + agents: s.agents.map(a => { + const ws = agentStates[a.id]; + if (ws) { + return { ...a, status: ws.status || a.status, name: ws.name || a.name }; + } + return a; + }), + })); + }, + + // Wander agents within their room bounds + tick: () => { + set(s => ({ + agents: s.agents.map(a => { + // Move toward target + const dx = a.targetX - a.x; + const dy = a.targetY - a.y; + const speed = 0.08; + + let newX = a.x + dx * speed; + let newY = a.y + dy * speed; + + // Snap if close enough + if (Math.abs(dx) < 0.1 && Math.abs(dy) < 0.1) { + newX = a.targetX; + newY = a.targetY; + + // Pick new random target within room (occasionally) + if (Math.random() < 0.01) { + const room = getRoomForAgent(a.id); + if (room) { + const margin = 1.5; + const tx = room.x + margin + Math.random() * (room.w - margin * 2); + const ty = room.y + margin + Math.random() * (room.h - margin * 2); + return { ...a, x: newX, y: newY, targetX: tx, targetY: ty }; + } } } - } - } - set({ agents, wsConnected: true, wsReconnecting: false }); + + return { ...a, x: newX, y: newY }; + }), + })); }, - - // Apply a diff update - applyDiff(diffs) { - const state = get(); - const updated = { ...state.agents }; - - for (const diff of diffs) { - if (diff.op === 'agent.move' || diff.op === 'agent.update') { - const agentId = diff.path.split('.')[1]; - if (updated[agentId]) { - const delta = diff.value || {}; - if (delta.position) { - delta.targetPosition = { ...delta.position }; - } - Object.assign(updated[agentId], delta); - } - } else if (diff.op === 'agent.position') { - const agentId = diff.path.split('.')[1]; - if (updated[agentId]) { - updated[agentId].targetPosition = { ...diff.value }; - } - } else if (diff.op === 'agent.activity') { - const agentId = diff.path.split('.')[1]; - if (updated[agentId]) { - updated[agentId] = { ...updated[agentId], ...diff.value }; - } - } - } - - set({ agents: updated }); - }, - - // WS connection status - setWsConnected(connected) { - set({ wsConnected: connected, wsReconnecting: !connected }); - }, - - setWsReconnecting(reconnecting) { - set({ wsReconnecting: reconnecting }); - }, - - // Update agent positions directly (used by mock mode) - updateAgentPosition(agentId, position) { - set(state => { - const agents = { ...state.agents }; - if (agents[agentId]) { - agents[agentId] = { - ...agents[agentId], - targetPosition: { ...position }, - }; - } - return { agents }; - }); - }, - - updateAgentActivity(agentId, activity, task) { - set(state => { - const agents = { ...state.agents }; - if (agents[agentId]) { - agents[agentId] = { - ...agents[agentId], - activity, - currentTask: task || agents[agentId].currentTask, - }; - } - return { agents }; - }); - }, -})); - -export { ZONES, AGENT_DEFS, DEFAULT_POSITIONS }; -export default useStore; +})); \ No newline at end of file