k-l-lambda commited on
Commit
3a12496
·
1 Parent(s): 2aea863

Deploy: fix room selector reactivity bug

Browse files

- Use spread operator for immutable array updates
- Add debug logging for room events
- Add hf-autoplay.cjs test script

trigo-web/app/dist/assets/__vite-browser-external_path-SE2pKm0_.js DELETED
@@ -1 +0,0 @@
1
- const o=new Proxy({},{get(t,e){throw new Error(`Module "path" has been externalized for browser compatibility. Cannot access "path.${e}" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.`)}});export{o as default};
 
 
trigo-web/app/dist/assets/__vite-browser-external_url-BKFT46N2.js DELETED
@@ -1 +0,0 @@
1
- const t=new Proxy({},{get(r,e){throw new Error(`Module "url" has been externalized for browser compatibility. Cannot access "url.${e}" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.`)}});export{t as default};
 
 
trigo-web/app/dist/assets/index-BbzW5u0H.js DELETED
The diff for this file is too large to render. See raw diff
 
trigo-web/app/dist/assets/index-Siwlapuk.css DELETED
@@ -1 +0,0 @@
1
- .sidebar-menu[data-v-b9972a08]{width:70px;background:#2a2a2a;display:flex;flex-direction:column;border-right:1px solid #404040;padding:20px 0;flex-shrink:0;transition:width .3s ease;overflow:hidden;position:relative}.sidebar-menu.expanded[data-v-b9972a08]{width:220px}.logo-section[data-v-b9972a08]{display:flex;flex-direction:column;align-items:center;padding:0 10px 30px;border-bottom:1px solid #404040;margin-bottom:20px;min-height:110px;cursor:pointer;transition:background-color .2s ease}.logo-section[data-v-b9972a08]:hover{background-color:#ffffff0d}.logo-section[data-v-b9972a08]:active{background-color:#ffffff1a}.logo[data-v-b9972a08]{width:50px;height:50px;margin-bottom:12px;border-radius:8px;flex-shrink:0;transition:transform .2s ease,opacity .2s ease}.logo-section:hover .logo.clickable[data-v-b9972a08]{transform:scale(1.1);opacity:.9}.logo-section:active .logo.clickable[data-v-b9972a08]{transform:scale(.95)}.app-title[data-v-b9972a08]{font-size:20px;font-weight:600;color:#e0e0e0;margin:0;white-space:nowrap;opacity:0;transition:opacity .2s ease .1s}.expanded .app-title[data-v-b9972a08]{opacity:1}.menu-tabs[data-v-b9972a08]{flex:1;display:flex;flex-direction:column;gap:4px;padding:0 10px}.tab-button[data-v-b9972a08]{display:flex;align-items:center;gap:12px;padding:14px 12px;border-radius:8px;background:transparent;color:#a0a0a0;text-decoration:none;font-size:15px;font-weight:500;cursor:pointer;transition:all .2s ease;border-left:3px solid transparent;position:relative;white-space:nowrap}.tab-button[data-v-b9972a08]:hover{background:#353535;color:#e0e0e0}.tab-button.active[data-v-b9972a08]{background:#3a3a3a;color:#e94560;border-left-color:#e94560}.tab-button.active .tab-icon[data-v-b9972a08]{transform:scale(1.1)}.tab-icon[data-v-b9972a08]{font-size:22px;line-height:1;transition:transform .2s ease;min-width:28px;text-align:center;flex-shrink:0}.tab-label[data-v-b9972a08]{flex:1;opacity:0;transition:opacity .2s ease .1s}.expanded .tab-label[data-v-b9972a08]{opacity:1}.sidebar-footer[data-v-b9972a08]{padding:20px 10px;border-top:1px solid #404040;text-align:center}.version[data-v-b9972a08]{font-size:11px;color:#606060;margin:0;white-space:nowrap;opacity:0;transition:opacity .2s ease .1s}.expanded .version[data-v-b9972a08]{opacity:1}.layout-frame[data-v-1708371c]{display:flex;height:100vh;width:100vw;background:#f5f5f5;overflow:hidden}.content-area[data-v-1708371c]{flex:1;display:flex;flex-direction:column;overflow:hidden}*{margin:0;padding:0;box-sizing:border-box}html,body{height:100%;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif}#app{height:100vh;background:#f5f5f5}.inline-nickname-editor[data-v-c3b5c618]{display:flex;flex-direction:column;gap:.25rem}.inline-nickname-editor.editable .nickname-display[data-v-c3b5c618]{cursor:pointer;transition:background-color .2s ease}.inline-nickname-editor.editable .nickname-display[data-v-c3b5c618]:hover{background-color:#ffffff0d}.inline-nickname-editor .nickname-display[data-v-c3b5c618],.inline-nickname-editor .nickname-edit[data-v-c3b5c618]{display:flex;align-items:center;gap:.5rem;padding:.5rem;border-radius:6px;background-color:#0003}.inline-nickname-editor .stone-icon[data-v-c3b5c618]{width:20px;height:20px;border-radius:50%;flex-shrink:0}.inline-nickname-editor .stone-icon.black[data-v-c3b5c618]{background-color:#2c2c2c;border:2px solid #fff}.inline-nickname-editor .stone-icon.white[data-v-c3b5c618]{background-color:#f0f0f0;border:2px solid #000}.inline-nickname-editor .nickname-text[data-v-c3b5c618]{font-weight:600;color:#e0e0e0}.inline-nickname-editor .edit-icon[data-v-c3b5c618]{opacity:0;transition:opacity .2s ease;font-size:.8rem}.inline-nickname-editor.editable:hover .edit-icon[data-v-c3b5c618]{opacity:.6}.inline-nickname-editor .nickname-input[data-v-c3b5c618]{flex:1;background-color:#ffffff1a;border:2px solid #60a5fa;border-radius:4px;padding:.25rem .5rem;color:#e0e0e0;font-weight:600;font-size:.95rem;outline:none}.inline-nickname-editor .nickname-input.error[data-v-c3b5c618]{border-color:#ef4444}.inline-nickname-editor .nickname-input[data-v-c3b5c618]:focus{background-color:#ffffff26}.inline-nickname-editor .error-icon[data-v-c3b5c618]{font-size:1rem;cursor:help}.inline-nickname-editor .edit-info[data-v-c3b5c618]{display:flex;justify-content:space-between;align-items:center;padding:0 .5rem;font-size:.75rem}.inline-nickname-editor .help-text[data-v-c3b5c618]{color:#60a5fa;font-style:italic}.inline-nickname-editor .char-count[data-v-c3b5c618]{color:#9ca3af}.room-selector[data-v-99ecebab]{position:relative;display:inline-block}.dropdown-container[data-v-99ecebab]{background:#0000004d;border:1px solid rgba(255,255,255,.3);border-radius:4px;padding:.4rem .6rem;min-width:140px;cursor:pointer;display:flex;align-items:center;justify-content:space-between;gap:.5rem;transition:background .2s}.dropdown-container[data-v-99ecebab]:hover:not(.disabled){background:#0006}.dropdown-container.disabled[data-v-99ecebab]{opacity:.5;cursor:not-allowed}.selected-room[data-v-99ecebab]{font-size:.9rem;color:#fff}.placeholder[data-v-99ecebab]{color:#ffffff80}.dropdown-arrow[data-v-99ecebab]{font-size:.7rem;color:#ffffffb3}.dropdown-menu[data-v-99ecebab]{position:absolute;top:calc(100% + 4px);left:0;min-width:220px;background:#3a3a3a;border:1px solid #505050;border-radius:4px;box-shadow:0 4px 12px #0000004d;z-index:100;max-height:300px;overflow-y:auto}.dropdown-item[data-v-99ecebab]{padding:.6rem .75rem;cursor:pointer;display:flex;align-items:center;gap:.5rem;transition:background .15s}.dropdown-item[data-v-99ecebab]:hover:not(.is-full){background:#4a4a4a}.dropdown-item.is-full[data-v-99ecebab]:not(.is-current){opacity:.5;cursor:not-allowed}.dropdown-item.is-current[data-v-99ecebab]{background:#505050;border-left:3px solid #e94560;padding-left:calc(.75rem - 3px)}.create-room[data-v-99ecebab]{color:#4ade80;border-bottom:1px solid #505050}.create-room .item-icon[data-v-99ecebab],.create-room .item-text[data-v-99ecebab]{font-size:.9rem}.dropdown-divider[data-v-99ecebab]{height:1px;background:#505050;margin:0}.room-list[data-v-99ecebab]{max-height:240px;overflow-y:auto}.loading-state[data-v-99ecebab],.empty-state[data-v-99ecebab]{padding:1rem;text-align:center;color:#ffffff80;font-size:.85rem}.room-item .room-id[data-v-99ecebab]{font-family:monospace;font-size:.85rem;color:#fff;flex:1}.room-item .player-count[data-v-99ecebab]{font-family:monospace;font-size:.8rem;padding:.1rem .3rem;border-radius:3px}.room-item .player-count.empty[data-v-99ecebab]{color:#4ade80}.room-item .player-count.partial[data-v-99ecebab]{color:#fbbf24}.room-item .player-count.full[data-v-99ecebab]{color:#ef4444}.room-item .room-status-badge[data-v-99ecebab]{font-size:.75rem;padding:.15rem .4rem;border-radius:3px;min-width:50px;text-align:center}.room-item .room-status-badge.waiting[data-v-99ecebab]{background:#4ade8026;color:#4ade80}.room-item .room-status-badge.playing[data-v-99ecebab]{background:#fbbf2426;color:#fbbf24}.trigo-view[data-v-6ae1493c]{display:flex;flex-direction:column;height:100%;background-color:#404040;color:#e0e0e0;overflow:hidden}.trigo-view .view-header[data-v-6ae1493c]{display:flex;justify-content:space-between;align-items:center;padding:1rem 2rem;background:linear-gradient(135deg,#505050,#454545);border-bottom:2px solid #606060;box-shadow:0 2px 8px #0000004d}.trigo-view .view-header .view-status[data-v-6ae1493c]{display:flex;gap:2rem;align-items:center}.trigo-view .view-header .view-status .turn-indicator[data-v-6ae1493c]{padding:.5rem 1rem;border-radius:8px;font-weight:600;transition:all .3s ease}.trigo-view .view-header .view-status .turn-indicator.black[data-v-6ae1493c]{background-color:#2c2c2c;color:#fff;box-shadow:0 0 10px #ffffff4d}.trigo-view .view-header .view-status .turn-indicator.white[data-v-6ae1493c]{background-color:#f0f0f0;color:#000;box-shadow:0 0 10px #f0f0f04d}.trigo-view .view-header .view-status .move-count[data-v-6ae1493c]{font-size:1rem;color:#a0a0a0}.trigo-view .view-header .view-status.ai-mode .player-info[data-v-6ae1493c],.trigo-view .view-header .view-status.ai-mode .ai-status[data-v-6ae1493c]{display:flex;align-items:center;gap:.5rem;padding:.5rem 1rem;background-color:#3a3a3a;border-radius:8px;border:2px solid transparent;transition:all .3s ease}.trigo-view .view-header .view-status.ai-mode .player-info.on-turn[data-v-6ae1493c],.trigo-view .view-header .view-status.ai-mode .ai-status.on-turn[data-v-6ae1493c]{background-color:#4a4a4a;border-color:#60a5fa;box-shadow:0 0 12px #60a5fa66}.trigo-view .view-header .view-status.ai-mode .player-label[data-v-6ae1493c],.trigo-view .view-header .view-status.ai-mode .ai-indicator[data-v-6ae1493c]{color:#a0a0a0;font-weight:500}.trigo-view .view-header .view-status.ai-mode .stone-icon[data-v-6ae1493c]{width:20px;height:20px;border-radius:50%;flex-shrink:0}.trigo-view .view-header .view-status.ai-mode .stone-icon.black[data-v-6ae1493c]{background-color:#2c2c2c;border:2px solid #fff}.trigo-view .view-header .view-status.ai-mode .stone-icon.white[data-v-6ae1493c]{background-color:#f0f0f0;border:2px solid #000}.trigo-view .view-header .view-status.ai-mode .ai-level[data-v-6ae1493c]{color:#60a5fa;font-weight:600}.trigo-view .view-header .view-status.ai-mode .ai-level.ai-thinking[data-v-6ae1493c]{color:#fbbf24;animation:pulse-6ae1493c 1.5s ease-in-out infinite}.trigo-view .view-header .view-status.ai-mode .ai-level.ai-error[data-v-6ae1493c]{color:#ef4444}.trigo-view .view-header .view-status.ai-mode .ai-time[data-v-6ae1493c]{color:#9ca3af;font-size:.875rem;font-style:italic}.trigo-view .view-header .view-status.ai-mode .btn-swap-colors[data-v-6ae1493c]{padding:.4rem .8rem;background-color:#4b5563;color:#e5e7eb;border:none;border-radius:6px;cursor:pointer;font-size:.875rem;font-weight:600;transition:all .2s ease}.trigo-view .view-header .view-status.ai-mode .btn-swap-colors[data-v-6ae1493c]:hover{background-color:#6b7280;transform:translateY(-1px)}.trigo-view .view-header .view-status.ai-mode .btn-swap-colors[data-v-6ae1493c]:active{transform:translateY(0)}.trigo-view .view-header .view-status.people-mode .room-info[data-v-6ae1493c]{display:flex;align-items:center;gap:.5rem;padding:.5rem 1rem;background-color:#3a3a3a;border-radius:8px}.trigo-view .view-header .view-status.people-mode .room-label[data-v-6ae1493c]{color:#a0a0a0;font-weight:500}.trigo-view .view-header .view-status.people-mode .room-code[data-v-6ae1493c]{color:#e94560;font-weight:700;font-family:monospace;font-size:1.1rem}.trigo-view .view-header .view-status.people-mode .btn-copy-room[data-v-6ae1493c]{padding:.25rem .5rem;background-color:transparent;border:1px solid #606060;border-radius:4px;cursor:pointer;font-size:.9rem;transition:all .2s ease}.trigo-view .view-header .view-status.people-mode .btn-copy-room[data-v-6ae1493c]:hover{background-color:#505050;border-color:gray}.trigo-view .view-header .view-status.people-mode .players-info[data-v-6ae1493c]{display:flex;align-items:center;gap:.75rem;padding:.5rem 1rem;background-color:#3a3a3a;border-radius:8px}.trigo-view .view-header .view-status.people-mode .player-display[data-v-6ae1493c]{transition:all .3s ease}.trigo-view .view-header .view-status.people-mode .player-display.on-turn[data-v-6ae1493c]{filter:brightness(1.3)}.trigo-view .view-header .view-status.people-mode .player-name[data-v-6ae1493c]{color:#e0e0e0;font-weight:600}.trigo-view .view-header .view-status.people-mode .waiting-text[data-v-6ae1493c]{color:#9ca3af;font-style:italic}.trigo-view .view-header .view-status.people-mode .vs-divider[data-v-6ae1493c]{color:#606060;font-weight:500}.trigo-view .view-header .view-status.people-mode .connection-status[data-v-6ae1493c]{padding:.5rem 1rem;border-radius:8px;font-weight:600;font-size:.9rem}.trigo-view .view-header .view-status.people-mode .connection-status.connected[data-v-6ae1493c]{background-color:#4ade8026;color:#4ade80}.trigo-view .view-header .view-status.people-mode .connection-status.disconnected[data-v-6ae1493c]{background-color:#ef444426;color:#ef4444}.trigo-view .view-header .view-status.library-mode .game-info[data-v-6ae1493c]{display:flex;align-items:center;gap:1rem;padding:.5rem 1rem;background-color:#3a3a3a;border-radius:8px}.trigo-view .view-header .view-status.library-mode .game-title[data-v-6ae1493c]{color:#e0e0e0;font-weight:600;font-size:1.1rem}.trigo-view .view-header .view-status.library-mode .game-date[data-v-6ae1493c]{color:#a0a0a0;font-weight:500;font-family:monospace}.trigo-view .view-header .view-status.library-mode .library-actions[data-v-6ae1493c]{display:flex;gap:.5rem}.trigo-view .view-header .view-status.library-mode .btn-library[data-v-6ae1493c]{padding:.5rem 1rem;border:none;border-radius:8px;font-weight:600;font-size:.9rem;cursor:pointer;transition:all .3s ease}.trigo-view .view-header .view-status.library-mode .btn-library.btn-load[data-v-6ae1493c]{background-color:#2d4059;color:#e0e0e0}.trigo-view .view-header .view-status.library-mode .btn-library.btn-load[data-v-6ae1493c]:hover{background-color:#3d5069;transform:translateY(-2px);box-shadow:0 4px 12px #2d405966}.trigo-view .view-header .view-status.library-mode .btn-library.btn-export[data-v-6ae1493c]{background-color:#e94560;color:#fff}.trigo-view .view-header .view-status.library-mode .btn-library.btn-export[data-v-6ae1493c]:hover{background-color:#f95670;transform:translateY(-2px);box-shadow:0 4px 12px #e9456066}.trigo-view .header-controls[data-v-6ae1493c]{display:flex;align-items:center;gap:.75rem;margin-left:auto}.trigo-view .header-controls .board-shape-select[data-v-6ae1493c],.trigo-view .header-controls .color-preference-select[data-v-6ae1493c]{background:#0000004d;border:1px solid rgba(255,255,255,.3);border-radius:4px;color:#fff;padding:.4rem .6rem;font-size:.9rem;cursor:pointer;transition:background .2s}.trigo-view .header-controls .board-shape-select[data-v-6ae1493c]:hover,.trigo-view .header-controls .color-preference-select[data-v-6ae1493c]:hover{background:#0006}.trigo-view .header-controls .board-shape-select[data-v-6ae1493c]:disabled,.trigo-view .header-controls .color-preference-select[data-v-6ae1493c]:disabled{opacity:.5;cursor:not-allowed}.trigo-view .header-controls .board-shape-select option[data-v-6ae1493c],.trigo-view .header-controls .color-preference-select option[data-v-6ae1493c]{background:#3a3a3a;color:#e0e0e0}.trigo-view .header-controls .color-preference-select[data-v-6ae1493c]{min-width:130px}.trigo-view .header-controls .board-shape-select[data-v-6ae1493c]{min-width:90px}.trigo-view .header-controls .btn-reset[data-v-6ae1493c]{background:#e94560;color:#fff;border:none;border-radius:4px;padding:.4rem 1rem;font-size:.9rem;font-weight:600;cursor:pointer;transition:background .2s}.trigo-view .header-controls .btn-reset[data-v-6ae1493c]:hover{background:#d63850}.trigo-view .header-controls .btn-reset[data-v-6ae1493c]:active{background:#c02040}.trigo-view .view-body[data-v-6ae1493c]{display:flex;flex:1;overflow:hidden}.trigo-view .view-body .board-container[data-v-6ae1493c]{flex:1;display:flex;align-items:center;justify-content:center;background-color:#484848;padding:1rem;position:relative}.trigo-view .view-body .board-container .viewport-wrapper[data-v-6ae1493c]{width:100%;height:100%;position:relative;border-radius:8px;overflow:hidden;box-shadow:0 4px 16px #00000080}.trigo-view .view-body .board-container .viewport-wrapper .viewport-canvas[data-v-6ae1493c]{width:100%;height:100%;display:block;background-color:#50505a}.trigo-view .view-body .board-container .viewport-wrapper .viewport-overlay[data-v-6ae1493c]{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;align-items:center;justify-content:center;pointer-events:none}.trigo-view .view-body .board-container .viewport-wrapper .viewport-overlay .loading-text[data-v-6ae1493c]{color:#ffffff80;font-size:1.2rem;animation:pulse-6ae1493c 2s ease-in-out infinite}.trigo-view .view-body .board-container .viewport-wrapper .inspect-tooltip[data-v-6ae1493c]{position:absolute;top:1rem;left:1rem;background-color:#fff1b0f2;color:#111;padding:.5rem 1rem;border-radius:8px;font-size:.9rem;font-weight:600;pointer-events:none;box-shadow:0 2px 8px #0000004d;z-index:100}.trigo-view .view-body .board-container .viewport-wrapper .inspect-tooltip .tooltip-content[data-v-6ae1493c]{display:flex;align-items:center;gap:.5rem}.trigo-view .view-body .board-container .viewport-wrapper .inspect-tooltip .tooltip-content .tooltip-label[data-v-6ae1493c]{white-space:nowrap}.trigo-view .view-body .board-container .viewport-wrapper .inspect-tooltip .tooltip-content .tooltip-divider[data-v-6ae1493c]{color:#888}.trigo-view .view-body .controls-panel[data-v-6ae1493c]{width:320px;background-color:#3a3a3a;border-left:2px solid #606060;display:flex;flex-direction:column;overflow:hidden;box-shadow:-4px 0 16px #0000004d}.trigo-view .view-body .controls-panel .panel-section[data-v-6ae1493c]{padding:.8rem;border-bottom:1px solid #505050;position:relative}.trigo-view .view-body .controls-panel .panel-section .section-title[data-v-6ae1493c]{font-size:.7rem;font-weight:600;color:#f0bcc5;text-transform:uppercase;letter-spacing:1px;position:absolute;top:0;left:.8rem;opacity:0;transition:opacity .3s ease-in}.trigo-view .view-body .controls-panel .panel-section:hover .section-title[data-v-6ae1493c]{opacity:.6}.trigo-view .view-body .controls-panel .score-section .score-display[data-v-6ae1493c]{display:flex;gap:.5rem;margin-bottom:1rem}.trigo-view .view-body .controls-panel .score-section .score-display .score-button[data-v-6ae1493c]{flex:1;display:flex;align-items:center;justify-content:center;gap:.5rem;padding:1rem;border:2px solid #505050;border-radius:8px;background-color:#484848;cursor:default;transition:all .3s ease}.trigo-view .view-body .controls-panel .score-section .score-display .score-button.black .color-indicator[data-v-6ae1493c]{background-color:#2c2c2c;border:2px solid #fff}.trigo-view .view-body .controls-panel .score-section .score-display .score-button.white .color-indicator[data-v-6ae1493c]{background-color:#f0f0f0;border:2px solid #000}.trigo-view .view-body .controls-panel .score-section .score-display .score-button .color-indicator[data-v-6ae1493c]{width:24px;height:24px;border-radius:50%}.trigo-view .view-body .controls-panel .score-section .score-display .score-button .score[data-v-6ae1493c]{font-size:1.5rem;font-weight:700;color:#e0e0e0}.trigo-view .view-body .controls-panel .score-section .score-display .score-button[data-v-6ae1493c]:disabled{opacity:.5}.trigo-view .view-body .controls-panel .score-section .compute-territory[data-v-6ae1493c]{width:100%;padding:.75rem;background-color:#505050;color:#e0e0e0;border:none;border-radius:8px;font-weight:600;cursor:pointer;transition:all .3s ease}.trigo-view .view-body .controls-panel .score-section .compute-territory[data-v-6ae1493c]:hover:not(:disabled){background-color:#606060}.trigo-view .view-body .controls-panel .score-section .compute-territory[data-v-6ae1493c]:disabled{opacity:.5;cursor:not-allowed}.trigo-view .view-body .controls-panel .score-section.show-territory .score-display .score-button[data-v-6ae1493c]{background-color:#3a3a3a;border-color:#606060;box-shadow:0 0 12px #e945604d}.trigo-view .view-body .controls-panel .routine-section[data-v-6ae1493c]{flex:1;display:flex;flex-direction:column;min-height:0}.trigo-view .view-body .controls-panel .routine-section .routine-content[data-v-6ae1493c]{flex:1;overflow-y:auto;background-color:#2a2a2a;border-radius:8px;padding:.5rem}.trigo-view .view-body .controls-panel .routine-section .routine-content .move-list[data-v-6ae1493c]{padding:0;margin:0}.trigo-view .view-body .controls-panel .routine-section .routine-content .move-list .move-row[data-v-6ae1493c]{display:grid;grid-template-columns:30px 1fr 1fr;gap:.25rem;margin-bottom:.25rem;align-items:center}.trigo-view .view-body .controls-panel .routine-section .routine-content .move-list .move-row.start-row[data-v-6ae1493c]{grid-template-columns:30px 1fr;padding:.5rem;border-radius:4px;cursor:pointer;transition:all .2s ease}.trigo-view .view-body .controls-panel .routine-section .routine-content .move-list .move-row.start-row[data-v-6ae1493c]:hover{background-color:#484848}.trigo-view .view-body .controls-panel .routine-section .routine-content .move-list .move-row.start-row.active[data-v-6ae1493c]{background-color:#505050;border-left:3px solid #e94560}.trigo-view .view-body .controls-panel .routine-section .routine-content .move-list .move-row.start-row .open-label[data-v-6ae1493c]{font-weight:700;color:#e94560;text-transform:uppercase;letter-spacing:1px}.trigo-view .view-body .controls-panel .routine-section .routine-content .move-list .move-row .round-number[data-v-6ae1493c]{color:gray;font-size:.9em;text-align:right;padding-right:.25rem}.trigo-view .view-body .controls-panel .routine-section .routine-content .move-list .move-row .move-cell[data-v-6ae1493c]{padding:.5rem;border-radius:4px;cursor:pointer;transition:all .2s ease;display:flex;align-items:center;gap:.5rem;background-color:#1a1a1a}.trigo-view .view-body .controls-panel .routine-section .routine-content .move-list .move-row .move-cell[data-v-6ae1493c]:hover:not(.empty){background-color:#484848}.trigo-view .view-body .controls-panel .routine-section .routine-content .move-list .move-row .move-cell.active[data-v-6ae1493c]{background-color:#505050;border-left:3px solid #e94560}.trigo-view .view-body .controls-panel .routine-section .routine-content .move-list .move-row .move-cell.empty[data-v-6ae1493c]{background-color:transparent;cursor:default}.trigo-view .view-body .controls-panel .routine-section .routine-content .move-list .move-row .move-cell .stone-icon[data-v-6ae1493c]{width:16px;height:16px;border-radius:50%;flex-shrink:0}.trigo-view .view-body .controls-panel .routine-section .routine-content .move-list .move-row .move-cell .stone-icon.black[data-v-6ae1493c]{background-color:#2c2c2c;border:2px solid #fff}.trigo-view .view-body .controls-panel .routine-section .routine-content .move-list .move-row .move-cell .stone-icon.white[data-v-6ae1493c]{background-color:#f0f0f0;border:2px solid #000}.trigo-view .view-body .controls-panel .routine-section .routine-content .move-list .move-row .move-cell .move-coords[data-v-6ae1493c]{color:#a0a0a0;font-family:monospace;font-size:.9em}.trigo-view .view-body .controls-panel .routine-section .routine-content .move-list .move-row .move-cell .move-label[data-v-6ae1493c]{color:#60a5fa;font-weight:600;font-size:.85em;text-transform:lowercase}.trigo-view .view-body .controls-panel .controls-section .control-buttons[data-v-6ae1493c]{display:flex;flex-direction:column;gap:1rem}.trigo-view .view-body .controls-panel .controls-section .control-buttons .play-controls[data-v-6ae1493c],.trigo-view .view-body .controls-panel .controls-section .control-buttons .history-controls[data-v-6ae1493c]{display:flex;gap:.5rem}.trigo-view .view-body .controls-panel .controls-section .control-buttons .btn[data-v-6ae1493c]{padding:.75rem 1.5rem;border:none;border-radius:8px;font-weight:600;cursor:pointer;transition:all .3s ease;flex:1}.trigo-view .view-body .controls-panel .controls-section .control-buttons .btn[data-v-6ae1493c]:disabled{opacity:.5;cursor:not-allowed}.trigo-view .view-body .controls-panel .controls-section .control-buttons .btn.btn-pass[data-v-6ae1493c]{background-color:#2d4059;color:#e0e0e0}.trigo-view .view-body .controls-panel .controls-section .control-buttons .btn.btn-pass[data-v-6ae1493c]:hover:not(:disabled){background-color:#3d5069}.trigo-view .view-body .controls-panel .controls-section .control-buttons .btn.btn-resign[data-v-6ae1493c]{background-color:#c23b22;color:#fff}.trigo-view .view-body .controls-panel .controls-section .control-buttons .btn.btn-resign[data-v-6ae1493c]:hover:not(:disabled){background-color:#d44b32}.trigo-view .view-body .controls-panel .controls-section .control-buttons .btn.btn-icon[data-v-6ae1493c]{background-color:#505050;color:#e0e0e0;padding:.75rem;font-size:1.2rem}.trigo-view .view-body .controls-panel .controls-section .control-buttons .btn.btn-icon[data-v-6ae1493c]:hover:not(:disabled){background-color:#606060}.btn-view-tgn[data-v-6ae1493c]{position:absolute;top:0;right:.8rem;padding:.25rem .5rem;background-color:transparent;color:#a0a0a0;border:1px solid #505050;border-radius:4px;font-size:.65rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;cursor:pointer;transition:all .2s ease;opacity:0}.btn-view-tgn[data-v-6ae1493c]:hover{background-color:#505050;color:#e0e0e0;border-color:#606060}.routine-section:hover .btn-view-tgn[data-v-6ae1493c]{opacity:1}.tgn-modal[data-v-6ae1493c]{position:fixed;top:0;left:0;width:100vw;height:100vh;background-color:#000000b3;display:flex;align-items:center;justify-content:center;z-index:1000;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.tgn-modal .tgn-modal-content[data-v-6ae1493c]{background-color:#3a3a3a;border-radius:12px;box-shadow:0 8px 32px #00000080;width:90%;max-width:600px;max-height:80vh;display:flex;flex-direction:column;overflow:hidden}.tgn-modal .tgn-modal-content .tgn-modal-header[data-v-6ae1493c]{display:flex;justify-content:space-between;align-items:center;padding:1rem 1.5rem;background-color:#2a2a2a;border-bottom:1px solid #505050}.tgn-modal .tgn-modal-content .tgn-modal-header h3[data-v-6ae1493c]{margin:0;font-size:1.2rem;font-weight:600;color:#e0e0e0}.tgn-modal .tgn-modal-content .tgn-modal-header .tgn-status[data-v-6ae1493c]{font-size:.85rem;font-weight:600;padding:.4rem .8rem;border-radius:4px;white-space:nowrap;transition:all .3s ease}.tgn-modal .tgn-modal-content .tgn-modal-header .tgn-status.idle[data-v-6ae1493c]{background-color:#505050;color:#a0a0a0}.tgn-modal .tgn-modal-content .tgn-modal-header .tgn-status.valid[data-v-6ae1493c]{background-color:#4ade8026;color:#4ade80;border:1px solid rgba(74,222,128,.4)}.tgn-modal .tgn-modal-content .tgn-modal-header .tgn-status.invalid[data-v-6ae1493c]{background-color:#ef444426;color:#ef4444;border:1px solid rgba(239,68,68,.4)}.tgn-modal .tgn-modal-content .tgn-modal-header .btn-close[data-v-6ae1493c]{background:none;border:none;color:#a0a0a0;font-size:1.5rem;cursor:pointer;padding:0;width:32px;height:32px;display:flex;align-items:center;justify-content:center;border-radius:4px;transition:all .2s ease}.tgn-modal .tgn-modal-content .tgn-modal-header .btn-close[data-v-6ae1493c]:hover{background-color:#505050;color:#e0e0e0}.tgn-modal .tgn-modal-content .tgn-modal-body[data-v-6ae1493c]{flex:1;padding:1.5rem;overflow:auto}.tgn-modal .tgn-modal-content .tgn-modal-body .tgn-textarea[data-v-6ae1493c]{width:100%;height:100%;min-height:300px;background-color:#2a2a2a;color:#e0e0e0;border:2px solid #505050;border-radius:8px;padding:1rem;font-family:Courier New,Courier,monospace;font-size:.9rem;line-height:1.6;resize:vertical;cursor:text;transition:border-color .3s ease,box-shadow .3s ease}.tgn-modal .tgn-modal-content .tgn-modal-body .tgn-textarea[data-v-6ae1493c]:focus{outline:none;border-color:#e94560}.tgn-modal .tgn-modal-content .tgn-modal-body .tgn-textarea.valid[data-v-6ae1493c]{border-color:#4ade80;box-shadow:0 0 8px #4ade8033}.tgn-modal .tgn-modal-content .tgn-modal-body .tgn-textarea.invalid[data-v-6ae1493c]{border-color:#ef4444;box-shadow:0 0 8px #ef444433}.tgn-modal .tgn-modal-content .tgn-modal-body .tgn-textarea.idle[data-v-6ae1493c]{border-color:#505050}.tgn-modal .tgn-modal-content .tgn-modal-footer[data-v-6ae1493c]{display:flex;gap:.5rem;padding:1rem 1.5rem;background-color:#2a2a2a;border-top:1px solid #505050}.tgn-modal .tgn-modal-content .tgn-modal-footer .btn[data-v-6ae1493c]{flex:1;padding:.75rem;border:none;border-radius:8px;font-weight:600;cursor:pointer;transition:all .3s ease}.tgn-modal .tgn-modal-content .tgn-modal-footer .btn[data-v-6ae1493c]:disabled{opacity:.5;cursor:not-allowed}.tgn-modal .tgn-modal-content .tgn-modal-footer .btn.btn-apply[data-v-6ae1493c]{background-color:#4ade80;color:#000}.tgn-modal .tgn-modal-content .tgn-modal-footer .btn.btn-apply[data-v-6ae1493c]:hover:not(:disabled){background-color:#22c55e;transform:translateY(-2px);box-shadow:0 4px 12px #4ade8066}.tgn-modal .tgn-modal-content .tgn-modal-footer .btn.btn-copy[data-v-6ae1493c]{background-color:#e94560;color:#fff}.tgn-modal .tgn-modal-content .tgn-modal-footer .btn.btn-copy[data-v-6ae1493c]:hover{background-color:#f95670;transform:translateY(-2px);box-shadow:0 4px 12px #e9456066}.tgn-modal .tgn-modal-content .tgn-modal-footer .btn.btn-close-modal[data-v-6ae1493c]{background-color:#505050;color:#e0e0e0}.tgn-modal .tgn-modal-content .tgn-modal-footer .btn.btn-close-modal[data-v-6ae1493c]:hover{background-color:#606060}@keyframes pulse-6ae1493c{0%,to{opacity:.5}50%{opacity:1}}.controls-panel[data-v-6ae1493c]::-webkit-scrollbar{width:8px}.controls-panel[data-v-6ae1493c]::-webkit-scrollbar-track{background:#2a2a2a}.controls-panel[data-v-6ae1493c]::-webkit-scrollbar-thumb{background:#505050;border-radius:4px}.controls-panel[data-v-6ae1493c]::-webkit-scrollbar-thumb:hover{background:#606060}.routine-content[data-v-6ae1493c]::-webkit-scrollbar{width:6px}.routine-content[data-v-6ae1493c]::-webkit-scrollbar-track{background:#2a2a2a}.routine-content[data-v-6ae1493c]::-webkit-scrollbar-thumb{background:#505050;border-radius:3px}.routine-content[data-v-6ae1493c]::-webkit-scrollbar-thumb:hover{background:#606060}@keyframes pulse-6ae1493c{0%,to{opacity:1}50%{opacity:.5}}.onnx-test-view[data-v-ee339f1a]{display:flex;flex-direction:column;height:100%;background-color:#f5f5f5;overflow:auto}.test-header[data-v-ee339f1a]{background:linear-gradient(135deg,#667eea,#764ba2);color:#fff;padding:2rem;text-align:center}.test-header h1[data-v-ee339f1a]{margin:0 0 .5rem;font-size:2rem;font-weight:700}.test-header .subtitle[data-v-ee339f1a]{margin:0;opacity:.9;font-size:1.1rem}.test-body[data-v-ee339f1a]{flex:1;padding:2rem;max-width:1000px;margin:0 auto;width:100%}.test-section[data-v-ee339f1a]{background:#fff;border-radius:12px;padding:1.5rem;margin-bottom:1.5rem;box-shadow:0 2px 8px #0000001a}.test-section h2[data-v-ee339f1a]{margin:0 0 .5rem;color:#333;font-size:1.3rem;font-weight:600}.test-section p[data-v-ee339f1a]{margin:0 0 1rem;color:#666}.status-info[data-v-ee339f1a]{background:#f8f9fa;border-radius:8px;padding:1rem;margin-bottom:1rem}.status-info .status-item[data-v-ee339f1a]{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px solid #e9ecef}.status-info .status-item[data-v-ee339f1a]:last-child{border-bottom:none}.status-info .status-item.ready .status-value[data-v-ee339f1a]{color:#28a745;font-weight:600}.status-info .status-item.loading .status-value[data-v-ee339f1a]{color:#ffc107;font-weight:600}.status-info .status-item .status-label[data-v-ee339f1a]{font-weight:600;color:#666}.status-info .status-item .status-value[data-v-ee339f1a]{color:#333}.error-message[data-v-ee339f1a]{background:#fff3cd;border:1px solid #ffeaa7;border-radius:6px;padding:.75rem;color:#856404;margin-top:1rem}.btn[data-v-ee339f1a]{padding:.75rem 1.5rem;border:none;border-radius:8px;font-weight:600;font-size:1rem;cursor:pointer;transition:all .3s ease}.btn[data-v-ee339f1a]:disabled{opacity:.5;cursor:not-allowed}.btn.btn-primary[data-v-ee339f1a]{background:linear-gradient(135deg,#667eea,#764ba2);color:#fff}.btn.btn-primary[data-v-ee339f1a]:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 4px 12px #667eea66}.btn.btn-test[data-v-ee339f1a]{background:linear-gradient(135deg,#f093fb,#f5576c);color:#fff}.btn.btn-test[data-v-ee339f1a]:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 4px 12px #f5576c66}.btn.btn-secondary[data-v-ee339f1a]{background:#6c757d;color:#fff}.btn.btn-secondary[data-v-ee339f1a]:hover:not(:disabled){background:#5a6268}.input-group[data-v-ee339f1a]{margin-bottom:1rem}.input-group label[data-v-ee339f1a]{display:block;margin-bottom:.5rem;font-weight:600;color:#333}.input-group input[data-v-ee339f1a]{width:100%;padding:.75rem;border:2px solid #e9ecef;border-radius:8px;font-size:1rem;transition:border-color .3s ease}.input-group input[data-v-ee339f1a]:focus{outline:none;border-color:#667eea}.input-group input[data-v-ee339f1a]:disabled{background-color:#f8f9fa;cursor:not-allowed}.test-result[data-v-ee339f1a]{background:#f8f9fa;border-radius:8px;padding:1rem;margin-top:1rem}.test-result h3[data-v-ee339f1a]{margin:0 0 1rem;color:#333;font-size:1.1rem}.test-result .result-item[data-v-ee339f1a]{display:flex;justify-content:space-between;align-items:flex-start;padding:.5rem 0;border-bottom:1px solid #e9ecef}.test-result .result-item[data-v-ee339f1a]:last-child{border-bottom:none}.test-result .result-item.full-width[data-v-ee339f1a]{flex-direction:column;gap:.5rem}.test-result .result-item .label[data-v-ee339f1a]{font-weight:600;color:#666;min-width:150px}.test-result .result-item .value[data-v-ee339f1a]{color:#333;flex:1;text-align:right}.test-result .result-item .value.code[data-v-ee339f1a]{font-family:Courier New,monospace;background:#fff;padding:.25rem .5rem;border-radius:4px;font-size:.9rem;text-align:left}.test-result .generated-text[data-v-ee339f1a]{background:#fff;border:2px solid #e9ecef;border-radius:8px;padding:1rem;font-family:Courier New,monospace;font-size:.95rem;line-height:1.6;color:#333;white-space:pre-wrap;word-break:break-word}.agent-test-view[data-v-c7c083d4]{display:flex;flex-direction:column;height:100%;background-color:#f5f5f5;overflow:auto}.test-header[data-v-c7c083d4]{background:linear-gradient(135deg,#667eea,#764ba2);color:#fff;padding:2rem;text-align:center}.test-header h1[data-v-c7c083d4]{margin:0 0 .5rem;font-size:2rem;font-weight:700}.test-header .subtitle[data-v-c7c083d4]{margin:0;opacity:.9;font-size:1.1rem}.test-body[data-v-c7c083d4]{flex:1;padding:2rem;max-width:1200px;margin:0 auto;width:100%}.test-section[data-v-c7c083d4]{background:#fff;border-radius:12px;padding:1.5rem;margin-bottom:1.5rem;box-shadow:0 2px 8px #0000001a}.test-section h2[data-v-c7c083d4]{margin:0 0 .5rem;color:#333;font-size:1.3rem;font-weight:600}.test-section p[data-v-c7c083d4]{margin:0 0 1rem;color:#666}.status-info[data-v-c7c083d4]{background:#f8f9fa;border-radius:8px;padding:1rem;margin-bottom:1rem}.status-info .status-item[data-v-c7c083d4]{display:flex;justify-content:space-between;padding:.5rem 0}.status-info .status-item.ready .status-value[data-v-c7c083d4]{color:#28a745;font-weight:600}.status-info .status-item.loading .status-value[data-v-c7c083d4]{color:#ffc107;font-weight:600}.status-info .status-item .status-label[data-v-c7c083d4]{font-weight:600;color:#666}.status-info .status-item .status-value[data-v-c7c083d4]{color:#333}.error-message[data-v-c7c083d4]{background:#fff3cd;border:1px solid #ffeaa7;border-radius:6px;padding:.75rem;color:#856404;margin-top:1rem}.game-info[data-v-c7c083d4]{background:#f8f9fa;border-radius:8px;padding:1rem;margin-bottom:1rem}.game-info .info-item[data-v-c7c083d4]{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px solid #e9ecef}.game-info .info-item[data-v-c7c083d4]:last-child{border-bottom:none}.game-info .info-item .label[data-v-c7c083d4]{font-weight:600;color:#666}.game-info .info-item .value[data-v-c7c083d4]{color:#333;font-weight:500}.game-info .info-item .value.black[data-v-c7c083d4]{color:#2c2c2c}.game-info .info-item .value.white[data-v-c7c083d4]{color:#666}.game-controls[data-v-c7c083d4]{display:flex;gap:.5rem;margin-bottom:1rem}.tgn-display h3[data-v-c7c083d4]{margin:0 0 .5rem;color:#333;font-size:1rem}.tgn-display .tgn-content[data-v-c7c083d4]{background:#2a2a2a;color:#e0e0e0;padding:1rem;border-radius:8px;font-family:Courier New,monospace;font-size:.9rem;line-height:1.6;overflow-x:auto;white-space:pre-wrap;word-break:break-all}.btn[data-v-c7c083d4]{padding:.75rem 1.5rem;border:none;border-radius:8px;font-weight:600;font-size:1rem;cursor:pointer;transition:all .3s ease}.btn[data-v-c7c083d4]:disabled{opacity:.5;cursor:not-allowed}.btn.btn-primary[data-v-c7c083d4]{background:linear-gradient(135deg,#667eea,#764ba2);color:#fff}.btn.btn-primary[data-v-c7c083d4]:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 4px 12px #667eea66}.btn.btn-test[data-v-c7c083d4]{background:linear-gradient(135deg,#f093fb,#f5576c);color:#fff}.btn.btn-test[data-v-c7c083d4]:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 4px 12px #f5576c66}.btn.btn-secondary[data-v-c7c083d4]{background:#6c757d;color:#fff}.btn.btn-secondary[data-v-c7c083d4]:hover:not(:disabled){background:#5a6268}.btn.btn-apply[data-v-c7c083d4]{background:#28a745;color:#fff;margin-top:1rem}.btn.btn-apply[data-v-c7c083d4]:hover:not(:disabled){background:#218838;transform:translateY(-2px);box-shadow:0 4px 12px #28a74566}.test-result[data-v-c7c083d4]{background:#f8f9fa;border-radius:8px;padding:1rem;margin-top:1rem}.test-result h3[data-v-c7c083d4]{margin:0 0 1rem;color:#333;font-size:1.1rem}.test-result .result-item[data-v-c7c083d4]{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px solid #e9ecef}.test-result .result-item[data-v-c7c083d4]:last-of-type{border-bottom:none}.test-result .result-item .label[data-v-c7c083d4]{font-weight:600;color:#666}.test-result .result-item .value[data-v-c7c083d4]{color:#333}.test-result .result-item .value.code[data-v-c7c083d4]{font-family:Courier New,monospace;background:#fff;padding:.25rem .5rem;border-radius:4px;font-size:.9rem}.move-history[data-v-c7c083d4]{background:#f8f9fa;border-radius:8px;padding:1rem;max-height:400px;overflow-y:auto}.move-history .empty-state[data-v-c7c083d4]{text-align:center;color:#999;padding:2rem;font-style:italic}.move-history .move-list[data-v-c7c083d4]{display:flex;flex-direction:column;gap:.5rem}.move-history .move-item[data-v-c7c083d4]{display:grid;grid-template-columns:40px 80px 100px 1fr;gap:.5rem;padding:.5rem;background:#fff;border-radius:6px;border-left:3px solid}.move-history .move-item.black[data-v-c7c083d4]{border-color:#2c2c2c}.move-history .move-item.white[data-v-c7c083d4]{border-color:#999}.move-history .move-item .move-number[data-v-c7c083d4]{color:#999;font-weight:600}.move-history .move-item .move-player[data-v-c7c083d4]{font-weight:600;text-transform:capitalize}.move-history .move-item .move-notation[data-v-c7c083d4]{font-family:Courier New,monospace;font-weight:600}.move-history .move-item .move-pos[data-v-c7c083d4]{color:#666;font-family:Courier New,monospace;font-size:.9rem}.tree-test-container[data-v-3c0f3090]{max-width:1200px;margin:0 auto;padding:2rem;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;min-height:100vh;overflow-y:auto}h1[data-v-3c0f3090]{color:#2c3e50;margin-bottom:1rem}h2[data-v-3c0f3090],h3[data-v-3c0f3090],h4[data-v-3c0f3090]{color:#34495e;margin-top:2rem;margin-bottom:1rem}.info-section[data-v-3c0f3090]{background:#f8f9fa;padding:1.5rem;border-radius:8px;margin-bottom:2rem}.info-section p[data-v-3c0f3090]{margin:0;line-height:1.6;color:#555}.status-section[data-v-3c0f3090],.board-section[data-v-3c0f3090],.generation-section[data-v-3c0f3090],.debug-section[data-v-3c0f3090]{background:#fff;border:1px solid #e1e4e8;border-radius:8px;padding:1.5rem;margin-bottom:2rem}.status-grid[data-v-3c0f3090]{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:1rem;margin-bottom:1rem}.status-item[data-v-3c0f3090],.info-item[data-v-3c0f3090]{display:flex;justify-content:space-between;padding:.5rem;background:#f8f9fa;border-radius:4px}.label[data-v-3c0f3090]{font-weight:600;color:#666}.value[data-v-3c0f3090]{color:#2c3e50}.status-ready[data-v-3c0f3090]{color:#28a745;font-weight:600}.status-loading[data-v-3c0f3090]{color:#ffc107;font-weight:600}.status-error[data-v-3c0f3090]{color:#dc3545;font-weight:600}.board-info[data-v-3c0f3090]{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:1rem;margin-bottom:1rem}.board-display[data-v-3c0f3090]{background:#f8f9fa;border:1px solid #e1e4e8;border-radius:4px;padding:1rem;margin-bottom:1rem}.board-display pre[data-v-3c0f3090]{margin:0;font-family:Courier New,monospace;font-size:.9rem;color:#2c3e50}.button-group[data-v-3c0f3090]{display:flex;gap:1rem;flex-wrap:wrap;margin-bottom:1rem}.btn-primary[data-v-3c0f3090],.btn-secondary[data-v-3c0f3090],.btn-small[data-v-3c0f3090]{padding:.75rem 1.5rem;border:none;border-radius:4px;font-size:1rem;font-weight:600;cursor:pointer;transition:all .2s}.btn-primary[data-v-3c0f3090]{background:#007bff;color:#fff}.btn-primary[data-v-3c0f3090]:hover:not(:disabled){background:#0056b3}.btn-primary[data-v-3c0f3090]:disabled{background:#6c757d;cursor:not-allowed;opacity:.6}.btn-secondary[data-v-3c0f3090]{background:#6c757d;color:#fff}.btn-secondary[data-v-3c0f3090]:hover{background:#545b62}.btn-large[data-v-3c0f3090]{padding:1rem 2rem;font-size:1.1rem}.btn-small[data-v-3c0f3090]{padding:.25rem .75rem;font-size:.875rem}.timing-info[data-v-3c0f3090]{margin-top:1rem;padding:1rem;background:#e7f5ff;border-left:4px solid #007bff;border-radius:4px}.timing-detail[data-v-3c0f3090]{color:#666;font-size:.9rem;margin-left:.5rem}.success-info[data-v-3c0f3090]{margin-top:1rem;padding:1rem;background:#d4edda;border-left:4px solid #28a745;border-radius:4px;color:#155724;font-weight:600}.moves-section[data-v-3c0f3090]{margin-top:2rem}.moves-table-container[data-v-3c0f3090]{overflow-x:auto;margin-top:1rem}.moves-table[data-v-3c0f3090]{width:100%;border-collapse:collapse;font-size:.9rem}.moves-table thead[data-v-3c0f3090]{background:#f8f9fa}.moves-table th[data-v-3c0f3090]{padding:.75rem;text-align:left;font-weight:600;color:#495057;border-bottom:2px solid #dee2e6}.moves-table td[data-v-3c0f3090]{padding:.75rem;border-bottom:1px solid #dee2e6}.moves-table tbody tr[data-v-3c0f3090]:hover{background:#f8f9fa}.moves-table .top-move[data-v-3c0f3090]{background:#d4edda;font-weight:600}.notation[data-v-3c0f3090]{font-family:Courier New,monospace;font-weight:600;color:#007bff}.position[data-v-3c0f3090]{font-family:Courier New,monospace;color:#666}.score[data-v-3c0f3090]{font-family:Courier New,monospace;text-align:right}.probability[data-v-3c0f3090]{font-family:Courier New,monospace;text-align:right;color:#28a745}.error-section[data-v-3c0f3090]{margin-top:1rem;padding:1rem;background:#f8d7da;border:1px solid #f5c6cb;border-radius:4px;color:#721c24}.error-section pre[data-v-3c0f3090]{margin:.5rem 0 0;white-space:pre-wrap;word-wrap:break-word;font-size:.9rem}.debug-section[data-v-3c0f3090]{background:#f8f9fa}.debug-content[data-v-3c0f3090]{display:flex;flex-direction:column;gap:1rem}.debug-item[data-v-3c0f3090]{display:flex;flex-direction:column;gap:.5rem}.debug-value[data-v-3c0f3090]{background:#fff;border:1px solid #e1e4e8;border-radius:4px;padding:1rem;margin:0;font-family:Courier New,monospace;font-size:.85rem;overflow-x:auto;color:#2c3e50}.visualization-section[data-v-3c0f3090]{background:#fff;border:1px solid #e1e4e8;border-radius:8px;padding:1.5rem;margin-bottom:2rem}.move-details[data-v-3c0f3090]{margin-bottom:2rem}.details-grid[data-v-3c0f3090]{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:.5rem;margin-top:1rem}.move-detail-item[data-v-3c0f3090]{display:flex;flex-direction:column;padding:.5rem;background:#f8f9fa;border-radius:4px;font-size:.85rem}.move-notation[data-v-3c0f3090]{font-family:Courier New,monospace;font-weight:600;color:#007bff;font-size:1rem}.move-positions[data-v-3c0f3090]{font-family:Courier New,monospace;color:#666;font-size:.75rem;margin-top:.25rem}.token-sequence[data-v-3c0f3090]{margin-bottom:2rem}.tokens-display[data-v-3c0f3090]{display:flex;flex-wrap:wrap;gap:.5rem;margin-top:1rem}.token-item[data-v-3c0f3090]{display:flex;flex-direction:column;align-items:center;padding:.5rem;background:#e7f5ff;border:1px solid #007bff;border-radius:4px;min-width:50px}.token-pos[data-v-3c0f3090]{font-size:.7rem;color:#666;font-weight:600}.token-char[data-v-3c0f3090]{font-family:Courier New,monospace;font-size:1.2rem;font-weight:600;color:#007bff;margin:.25rem 0}.token-id[data-v-3c0f3090]{font-size:.7rem;color:#666;font-family:Courier New,monospace}.mask-matrix[data-v-3c0f3090]{margin-top:2rem}.matrix-container[data-v-3c0f3090]{overflow:auto;margin-top:1rem;max-height:600px;border:1px solid #e1e4e8;border-radius:4px}.matrix-table[data-v-3c0f3090]{border-collapse:collapse;font-size:.75rem;min-width:100%}.corner-cell[data-v-3c0f3090]{background:#f8f9fa;border:1px solid #dee2e6;position:sticky;left:0;top:0;z-index:3}.header-cell[data-v-3c0f3090]{background:#f8f9fa;border:1px solid #dee2e6;padding:.5rem;position:sticky;top:0;z-index:2;text-align:center;min-width:40px}.header-content[data-v-3c0f3090]{display:flex;flex-direction:column;align-items:center}.header-pos[data-v-3c0f3090]{font-size:.65rem;color:#666;font-weight:600}.header-char[data-v-3c0f3090]{font-family:Courier New,monospace;font-size:.9rem;font-weight:600;color:#007bff;margin-top:.1rem}.row-header[data-v-3c0f3090]{background:#f8f9fa;border:1px solid #dee2e6;padding:.5rem;position:sticky;left:0;z-index:1;text-align:center;min-width:50px}.row-content[data-v-3c0f3090]{display:flex;flex-direction:column;align-items:center}.row-pos[data-v-3c0f3090]{font-size:.65rem;color:#666;font-weight:600}.row-char[data-v-3c0f3090]{font-family:Courier New,monospace;font-size:.9rem;font-weight:600;color:#007bff;margin-top:.1rem}.mask-cell[data-v-3c0f3090]{border:1px solid #dee2e6;padding:.5rem;text-align:center;font-family:Courier New,monospace;font-weight:600;font-size:.8rem}.mask-active[data-v-3c0f3090]{background:#d4edda;color:#155724}.mask-inactive[data-v-3c0f3090]{background:#f8f9fa;color:#ccc}.matrix-legend[data-v-3c0f3090]{display:flex;gap:1.5rem;margin-top:1rem;padding:.75rem;background:#f8f9fa;border-radius:4px}.legend-item[data-v-3c0f3090]{display:flex;align-items:center;gap:.5rem;font-size:.85rem}.legend-box[data-v-3c0f3090]{width:20px;height:20px;border:1px solid #dee2e6;border-radius:3px}.legend-box.active[data-v-3c0f3090]{background:#d4edda}.legend-box.inactive[data-v-3c0f3090]{background:#f8f9fa}.socket-test-view[data-v-5c5d3dbd]{max-width:1200px;margin:0 auto;padding:20px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.test-header[data-v-5c5d3dbd]{text-align:center;margin-bottom:30px;padding-bottom:20px;border-bottom:2px solid #e0e0e0}.test-header h1[data-v-5c5d3dbd]{margin:0 0 10px;font-size:2em;color:#333}.subtitle[data-v-5c5d3dbd]{margin:0;color:#666;font-size:1.1em}.test-body[data-v-5c5d3dbd]{display:grid;grid-template-columns:1fr 1fr;gap:20px;overflow:auto;max-height:calc(100vh - 200px)}.left-column[data-v-5c5d3dbd]{display:flex;flex-direction:column;gap:20px;overflow-y:auto}.right-column[data-v-5c5d3dbd]{display:flex;flex-direction:column;min-height:0}.event-log-section[data-v-5c5d3dbd]{display:flex;flex-direction:column;height:100%;min-height:0}.test-section[data-v-5c5d3dbd]{background:#f9f9f9;border:1px solid #ddd;border-radius:8px;padding:20px}.test-section h2[data-v-5c5d3dbd]{margin:0 0 15px;font-size:1.5em;color:#333}.section-desc[data-v-5c5d3dbd]{margin:-10px 0 15px;color:#666;font-size:.9em}.admin-section[data-v-5c5d3dbd]{background:#fff8e1;border-color:#ffd54f}.status-info[data-v-5c5d3dbd],.room-info[data-v-5c5d3dbd],.game-info[data-v-5c5d3dbd]{display:flex;flex-direction:column;gap:10px;margin-bottom:15px}.status-item[data-v-5c5d3dbd],.info-item[data-v-5c5d3dbd]{display:flex;gap:10px;align-items:center;padding:8px;background:#fff;border-radius:4px}.status-item.ready[data-v-5c5d3dbd]{background:#e8f5e9}.status-item.error[data-v-5c5d3dbd]{background:#ffebee}.status-label[data-v-5c5d3dbd],.label[data-v-5c5d3dbd]{font-weight:600;min-width:120px}.status-value[data-v-5c5d3dbd],.value[data-v-5c5d3dbd]{flex:1}.value.black[data-v-5c5d3dbd]{color:#000;font-weight:700}.value.white[data-v-5c5d3dbd]{color:#999;font-weight:700}.code[data-v-5c5d3dbd]{font-family:Courier New,monospace;background:#f0f0f0;padding:2px 6px;border-radius:3px;font-size:.9em}.error-message[data-v-5c5d3dbd]{padding:10px;background:#ffebee;border:1px solid #ef5350;border-radius:4px;color:#c62828}.room-controls[data-v-5c5d3dbd],.game-controls[data-v-5c5d3dbd]{display:flex;flex-direction:column;gap:10px}.control-group[data-v-5c5d3dbd],.button-group[data-v-5c5d3dbd]{display:flex;gap:10px;flex-wrap:wrap;align-items:center}.reset-controls[data-v-5c5d3dbd]{display:flex;flex-direction:column;gap:10px;margin-top:10px}.input-label[data-v-5c5d3dbd]{font-weight:600;margin-right:5px}.input-text[data-v-5c5d3dbd],.input-number[data-v-5c5d3dbd],.input-select[data-v-5c5d3dbd]{padding:8px 12px;border:1px solid #ddd;border-radius:4px;font-size:1em;flex:1;min-width:150px}.input-number[data-v-5c5d3dbd]{min-width:80px;max-width:100px}.input-select[data-v-5c5d3dbd]{min-width:200px;cursor:pointer;background:#fff}.admin-warning[data-v-5c5d3dbd]{padding:10px;background:#fff8e1;border:1px solid #ffd54f;border-radius:4px;color:#f57c00;font-weight:500;margin-bottom:10px}.btn[data-v-5c5d3dbd]{padding:10px 20px;border:none;border-radius:4px;font-size:1em;cursor:pointer;transition:background .2s;font-weight:500}.btn[data-v-5c5d3dbd]:disabled{opacity:.5;cursor:not-allowed}.btn-primary[data-v-5c5d3dbd]{background:#2196f3;color:#fff}.btn-primary[data-v-5c5d3dbd]:hover:not(:disabled){background:#1976d2}.btn-secondary[data-v-5c5d3dbd]{background:#757575;color:#fff}.btn-secondary[data-v-5c5d3dbd]:hover:not(:disabled){background:#616161}.btn-warning[data-v-5c5d3dbd]{background:#ff9800;color:#fff}.btn-warning[data-v-5c5d3dbd]:hover:not(:disabled){background:#f57c00}.btn-danger[data-v-5c5d3dbd]{background:#f44336;color:#fff}.btn-danger[data-v-5c5d3dbd]:hover:not(:disabled){background:#d32f2f}.btn-admin[data-v-5c5d3dbd]{background:#9c27b0;color:#fff}.btn-admin[data-v-5c5d3dbd]:hover:not(:disabled){background:#7b1fa2}.checkbox-label[data-v-5c5d3dbd]{display:flex;align-items:center;gap:5px;cursor:pointer}.event-log-controls[data-v-5c5d3dbd]{display:flex;gap:10px;align-items:center;margin-bottom:10px}.event-log[data-v-5c5d3dbd]{flex:1;overflow-y:auto;background:#fff;border:1px solid #ddd;border-radius:4px;padding:10px;min-height:0}.empty-state[data-v-5c5d3dbd]{text-align:center;color:#999;padding:20px}.tgn-display[data-v-5c5d3dbd]{margin-top:15px}.tgn-display h3[data-v-5c5d3dbd]{margin:0 0 10px;font-size:1.1em;color:#333}.tgn-content[data-v-5c5d3dbd]{background:#fff;border:1px solid #ddd;border-radius:4px;padding:10px;margin:0;font-family:Courier New,monospace;font-size:.9em;overflow-x:auto;white-space:pre-wrap;word-wrap:break-word;max-height:200px;overflow-y:auto}.event-item[data-v-5c5d3dbd]{margin-bottom:10px;padding:10px;border-radius:4px;border-left:4px solid #2196f3;background:#f5f5f5}.event-item.sent[data-v-5c5d3dbd]{border-left-color:#4caf50;background:#e8f5e9}.event-item.error[data-v-5c5d3dbd]{border-left-color:#f44336;background:#ffebee}.event-timestamp[data-v-5c5d3dbd]{font-size:.85em;color:#666;margin-right:10px}.event-name[data-v-5c5d3dbd]{font-weight:600;margin-right:10px}.event-type-badge[data-v-5c5d3dbd]{display:inline-block;padding:2px 8px;border-radius:12px;font-size:.75em;font-weight:600;text-transform:uppercase}.event-item.sent .event-type-badge[data-v-5c5d3dbd]{background:#4caf50;color:#fff}.event-item.received .event-type-badge[data-v-5c5d3dbd]{background:#2196f3;color:#fff}.event-item.error .event-type-badge[data-v-5c5d3dbd]{background:#f44336;color:#fff}.event-data[data-v-5c5d3dbd]{margin:10px 0 0;padding:10px;background:#fff;border:1px solid #ddd;border-radius:4px;font-size:.85em;overflow-x:auto;white-space:pre-wrap;word-wrap:break-word}.mcts-data-loader[data-v-9d36358a]{display:flex;flex-direction:column;gap:15px}.file-inputs[data-v-9d36358a]{display:flex;flex-direction:column;gap:12px}.file-input-group[data-v-9d36358a]{display:flex;flex-direction:column;gap:6px}.file-label[data-v-9d36358a]{font-size:13px;font-weight:500;color:silver;display:flex;justify-content:space-between;align-items:center}.file-status[data-v-9d36358a]{font-size:11px;color:gray;font-weight:400}.file-status.ready[data-v-9d36358a]{color:#4a90e2}.file-input[data-v-9d36358a]{padding:8px;background-color:#1a1a1a;border:1px solid #404040;border-radius:4px;color:#e0e0e0;font-size:13px;cursor:pointer}.file-input[data-v-9d36358a]:hover{border-color:#4a90e2}.file-input[data-v-9d36358a]:focus{outline:none;border-color:#4a90e2}.file-input[data-v-9d36358a]::file-selector-button{padding:6px 12px;background-color:#2a2a2a;border:1px solid #404040;border-radius:3px;color:#e0e0e0;font-size:12px;cursor:pointer;margin-right:10px}.file-input[data-v-9d36358a]::file-selector-button:hover{background-color:#3a3a3a;border-color:#4a90e2}.btn-load[data-v-9d36358a]{padding:12px 20px;background-color:#4a90e2;border:none;border-radius:4px;color:#fff;font-size:14px;font-weight:500;cursor:pointer;transition:background-color .2s,opacity .2s}.btn-load[data-v-9d36358a]:hover:not(:disabled){background-color:#357abd}.btn-load[data-v-9d36358a]:active:not(:disabled){background-color:#2a6ba8}.btn-load[data-v-9d36358a]:disabled{opacity:.5;cursor:not-allowed}.btn-load.loading[data-v-9d36358a]{opacity:.7}.status-message[data-v-9d36358a]{padding:10px;border-radius:4px;font-size:13px;display:flex;align-items:center;gap:10px}.status-message.loading[data-v-9d36358a]{background-color:#2a3a4a;color:#4a90e2}.status-message.error[data-v-9d36358a]{background-color:#4a2a2a;color:#ff6b6b}.status-message.success[data-v-9d36358a]{background-color:#2a4a2a;color:#6bff6b}.status-message strong[data-v-9d36358a]{font-weight:600}.spinner[data-v-9d36358a]{width:16px;height:16px;border:2px solid #4a90e2;border-top-color:transparent;border-radius:50%;animation:spin-9d36358a .8s linear infinite}@keyframes spin-9d36358a{to{transform:rotate(360deg)}}.mcts-move-navigation[data-v-95e9d710]{display:flex;flex-direction:column;gap:15px}.nav-buttons[data-v-95e9d710]{display:grid;grid-template-columns:1fr 1fr;gap:8px}.nav-btn[data-v-95e9d710]{padding:8px 12px;background-color:#3a3a3a;border:1px solid #505050;border-radius:4px;color:#e0e0e0;font-size:12px;cursor:pointer;transition:all .2s}.nav-btn[data-v-95e9d710]:hover:not(:disabled){background-color:#4a4a4a;border-color:#4a90e2}.nav-btn[data-v-95e9d710]:active:not(:disabled){background-color:#2a2a2a}.nav-btn[data-v-95e9d710]:disabled{opacity:.4;cursor:not-allowed}.move-slider[data-v-95e9d710]{display:flex;flex-direction:column;gap:8px}.slider[data-v-95e9d710]{width:100%;height:6px;border-radius:3px;background-color:#3a3a3a;outline:none;-webkit-appearance:none}.slider[data-v-95e9d710]::-webkit-slider-thumb{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:16px;height:16px;border-radius:50%;background-color:#4a90e2;cursor:pointer}.slider[data-v-95e9d710]::-webkit-slider-thumb:hover{background-color:#357abd}.slider[data-v-95e9d710]::-moz-range-thumb{width:16px;height:16px;border-radius:50%;background-color:#4a90e2;cursor:pointer;border:none}.slider[data-v-95e9d710]::-moz-range-thumb:hover{background-color:#357abd}.move-label[data-v-95e9d710]{font-size:13px;color:silver;text-align:center}.move-info[data-v-95e9d710]{padding:8px;background-color:#1a1a1a;border-radius:4px;font-size:12px;color:#a0a0a0}.move-info strong[data-v-95e9d710]{color:#e0e0e0;text-transform:capitalize}.mcts-statistics-panel[data-v-9af53401]{display:flex;flex-direction:column}.no-data[data-v-9af53401]{text-align:center;color:#606060;font-size:12px;padding:20px}.stats-content[data-v-9af53401]{display:flex;flex-direction:column;gap:15px}.stats-summary[data-v-9af53401]{padding:10px;background-color:#1a1a1a;border-radius:4px}.stat-item[data-v-9af53401]{display:flex;justify-content:space-between;font-size:13px}.stat-label[data-v-9af53401]{color:#a0a0a0}.stat-value[data-v-9af53401]{color:#e0e0e0;font-weight:500}.stats-options[data-v-9af53401]{display:flex;flex-direction:column;gap:8px}.option-label[data-v-9af53401]{font-size:12px;color:#a0a0a0;font-weight:500}.radio-group[data-v-9af53401]{display:flex;flex-direction:column;gap:6px}.radio-option[data-v-9af53401]{display:flex;align-items:center;gap:8px;font-size:12px;color:silver;cursor:pointer}.radio-option input[type=radio][data-v-9af53401]{cursor:pointer}.top-moves-table[data-v-9af53401]{max-height:300px}.top-moves-table table[data-v-9af53401]{width:100%;border-collapse:collapse;font-size:12px}.top-moves-table table thead[data-v-9af53401]{position:sticky;top:0;background-color:#2a2a2a;z-index:1}.top-moves-table table thead th[data-v-9af53401]{padding:8px 6px;text-align:left;color:#4a90e2;font-weight:600;border-bottom:1px solid #404040}.top-moves-table table tbody tr[data-v-9af53401]{cursor:pointer;transition:background-color .2s}.top-moves-table table tbody tr[data-v-9af53401]:hover{background-color:#3a3a3a}.top-moves-table table tbody tr.selected[data-v-9af53401]{background-color:#4a3030}.top-moves-table table tbody tr.selected td[data-v-9af53401]{color:#e94560;font-weight:500}.top-moves-table table tbody tr td[data-v-9af53401]{padding:8px 6px;color:silver;border-bottom:1px solid #303030}.top-moves-table table tbody tr td[data-v-9af53401]:first-child{color:gray}.board-heatmap[data-v-d8868f45]{width:100%;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center}.no-data[data-v-d8868f45]{display:flex;justify-content:center;align-items:center;height:100%;color:#606060;font-size:14px}.heatmap-wrapper[data-v-d8868f45]{display:flex;flex-direction:column;align-items:center;gap:20px;max-width:100%;max-height:100%}.board-svg[data-v-d8868f45]{border-radius:4px}.heatmap-cell[data-v-d8868f45]{cursor:pointer;transition:opacity .2s}.heatmap-cell[data-v-d8868f45]:hover{opacity:.9!important;stroke:#4a90e2;stroke-width:2}.heatmap-cell.selected[data-v-d8868f45]{stroke:#e94560;stroke-width:3}.stone[data-v-d8868f45]{pointer-events:none}.last-move-circle[data-v-d8868f45]{pointer-events:none;animation:pulse-d8868f45 1.5s ease-in-out infinite}@keyframes pulse-d8868f45{0%,to{opacity:1}50%{opacity:.4}}.coord-label[data-v-d8868f45]{fill:gray;font-size:11px;-webkit-user-select:none;user-select:none}.legend[data-v-d8868f45]{display:flex;flex-direction:column;gap:8px;width:300px}.legend-title[data-v-d8868f45]{font-size:13px;font-weight:500;color:silver;text-align:center}.legend-gradient[data-v-d8868f45]{display:flex;height:20px;border-radius:3px;overflow:hidden;border:1px solid #404040}.legend-stop[data-v-d8868f45]{flex:1}.legend-labels[data-v-d8868f45]{display:flex;justify-content:space-between;font-size:11px;color:gray}.tooltip[data-v-d8868f45]{position:fixed;background-color:#000000e6;border:1px solid #4a90e2;border-radius:4px;padding:8px 12px;font-size:12px;color:#e0e0e0;pointer-events:none;z-index:1000;box-shadow:0 4px 8px #0000004d}.tooltip-position[data-v-d8868f45]{font-weight:600;color:#4a90e2;margin-bottom:4px}.tooltip-stat[data-v-d8868f45]{color:silver;line-height:1.4}.tree-visualization[data-v-b9ea3fae]{width:100%;display:flex;flex-direction:column;align-items:center;justify-content:flex-start}.no-data[data-v-b9ea3fae]{display:flex;flex-direction:column;justify-content:center;align-items:center;height:100%;gap:10px}.no-data p[data-v-b9ea3fae]{color:#606060;font-size:14px;margin:0}.no-data .note[data-v-b9ea3fae]{font-size:11px;color:gray;font-style:italic}.tree-content[data-v-b9ea3fae]{display:flex;flex-direction:column;gap:15px;width:100%;align-items:center;justify-content:flex-start}.tree-svg[data-v-b9ea3fae]{display:block;max-width:100%;height:auto}.node-circle[data-v-b9ea3fae]{cursor:pointer;transition:all .2s}.child-node[data-v-b9ea3fae]{cursor:pointer}.child-node:hover .node-circle[data-v-b9ea3fae]{filter:brightness(1.2)}.child-node.selected .node-circle[data-v-b9ea3fae]{filter:brightness(1.3)}.node-label[data-v-b9ea3fae]{fill:#e0e0e0;font-size:11px;font-weight:600;pointer-events:none}.node-value[data-v-b9ea3fae]{fill:#e0e0e0;font-size:10px;pointer-events:none}.node-percent[data-v-b9ea3fae]{fill:#a0a0a0;font-size:9px;pointer-events:none}.tree-link[data-v-b9ea3fae]{pointer-events:none}.tree-settings[data-v-b9ea3fae]{padding:10px 15px;background-color:#1a1a1a;border-radius:4px;display:flex;justify-content:center}.setting-label[data-v-b9ea3fae]{display:flex;align-items:center;gap:10px;font-size:12px;color:silver}.setting-slider[data-v-b9ea3fae]{width:150px;height:4px;border-radius:2px;background-color:#3a3a3a;outline:none;-webkit-appearance:none}.setting-slider[data-v-b9ea3fae]::-webkit-slider-thumb{-webkit-appearance:none;width:12px;height:12px;border-radius:50%;background-color:#4a90e2;cursor:pointer}.setting-slider[data-v-b9ea3fae]::-moz-range-thumb{width:12px;height:12px;border-radius:50%;background-color:#4a90e2;cursor:pointer;border:none}.setting-value[data-v-b9ea3fae]{font-weight:500;color:#e0e0e0}.tooltip[data-v-b9ea3fae]{position:fixed;background-color:#000000e6;border:1px solid #4a90e2;border-radius:4px;padding:8px 12px;font-size:11px;color:#e0e0e0;pointer-events:none;z-index:1000;box-shadow:0 4px 8px #0000004d}.tooltip-pos[data-v-b9ea3fae]{font-weight:600;color:#4a90e2;margin-bottom:4px}.tooltip-line[data-v-b9ea3fae]{color:silver;line-height:1.4}.no-data-message[data-v-64912cec]{text-align:center;padding:2rem;font-size:14px;font-style:italic}.panel-section[data-v-64912cec]{margin-bottom:30px}.panel-section[data-v-64912cec]:last-child{margin-bottom:0}.button-group[data-v-64912cec]{display:flex;gap:.5rem;flex-wrap:wrap}.info-text[data-v-64912cec]{font-size:13px;line-height:1.5;margin:0 0 15px}.mcts-analysis-container[data-v-64912cec]{width:100%;height:100vh;overflow-y:auto;overflow-x:hidden;background-color:#1a1a1a;color:#e0e0e0}.mcts-analysis-container[data-v-64912cec]::-webkit-scrollbar{width:8px;height:8px}.mcts-analysis-container[data-v-64912cec]::-webkit-scrollbar-track{background:#1a1a1a;border-radius:4px}.mcts-analysis-container[data-v-64912cec]::-webkit-scrollbar-thumb{background:#4a4a4a;border-radius:4px}.mcts-analysis-container[data-v-64912cec]::-webkit-scrollbar-thumb:hover{background:#5a5a5a}.mcts-analysis-container[data-v-64912cec]{padding:20px}.mcts-analysis-container h1[data-v-64912cec]{margin:0 0 20px;font-size:28px;color:#e94560}.mcts-grid[data-v-64912cec]{display:grid;grid-template-columns:320px 1fr;gap:20px;min-height:calc(100vh - 80px)}.control-panel[data-v-64912cec]{border-radius:8px;padding:20px;overflow-y:auto;max-height:calc(100vh - 80px);background-color:#2a2a2a}.control-panel[data-v-64912cec]::-webkit-scrollbar{width:8px;height:8px}.control-panel[data-v-64912cec]::-webkit-scrollbar-track{background:#1a1a1a;border-radius:4px}.control-panel[data-v-64912cec]::-webkit-scrollbar-thumb{background:#4a4a4a;border-radius:4px}.control-panel[data-v-64912cec]::-webkit-scrollbar-thumb:hover{background:#5a5a5a}.control-panel h2[data-v-64912cec]{margin:0 0 20px;font-size:20px;padding-bottom:10px;color:#e94560;border-bottom:1px solid #404040}.control-panel h3[data-v-64912cec]{margin:0 0 15px;font-size:16px;color:#4a90e2}.info-text[data-v-64912cec]{color:#a0a0a0}.nav-placeholder[data-v-64912cec]{padding:15px;background-color:#1a1a1a;border-radius:4px;border:1px dashed #404040;text-align:center;color:#606060;font-size:12px}.content-area[data-v-64912cec]{display:grid;grid-template-rows:auto 1fr;gap:20px;overflow:hidden}.visualization-panel[data-v-64912cec]{border-radius:8px;padding:20px;margin-bottom:20px;background-color:#2a2a2a;border:1px solid #404040}.visualization-panel h2[data-v-64912cec],.visualization-panel h3[data-v-64912cec]{margin-top:0;margin-bottom:15px;font-weight:600;color:#4a90e2}.visualization-panel h2[data-v-64912cec]{font-size:20px}.visualization-panel h3[data-v-64912cec]{font-size:16px}.visualization-panel p[data-v-64912cec]{margin:0 0 1rem;color:#a0a0a0}.visualization-panel[data-v-64912cec]{display:flex;flex-direction:column;min-height:0;padding:20px}.visualization-panel h3[data-v-64912cec]{margin:0 0 15px;font-size:18px;color:#4a90e2;flex-shrink:0}.tree-panel[data-v-64912cec]{overflow:visible}@media (max-width: 1200px){.mcts-grid[data-v-64912cec]{grid-template-columns:280px 1fr}}@media (max-width: 900px){.mcts-grid[data-v-64912cec]{grid-template-columns:1fr;grid-template-rows:auto 1fr;min-height:auto}.control-panel[data-v-64912cec]{max-height:400px}.content-area[data-v-64912cec]{min-height:800px;max-height:none}}
 
 
trigo-web/app/dist/assets/logo-BsvPloX6.png DELETED
Binary file (62.9 kB)
 
trigo-web/app/dist/assets/ort-wasm-simd-threaded.jsep-BGTZ4Y7F.wasm DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:ac0d8f1cfbf2732420ad78a86072b8507253c63885a61c3fd640b3055256d31d
3
- size 23824254
 
 
 
 
trigo-web/app/dist/index.html DELETED
@@ -1,14 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <title>Trigo - 3D Go Game</title>
8
- <script type="module" crossorigin src="/assets/index-BbzW5u0H.js"></script>
9
- <link rel="stylesheet" crossorigin href="/assets/index-Siwlapuk.css">
10
- </head>
11
- <body>
12
- <div id="app"></div>
13
- </body>
14
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
trigo-web/app/dist/lib/tgnParser.cjs DELETED
@@ -1,791 +0,0 @@
1
- /* parser generated by jison 0.4.18 */
2
- /*
3
- Returns a Parser object of the following structure:
4
-
5
- Parser: {
6
- yy: {}
7
- }
8
-
9
- Parser.prototype: {
10
- yy: {},
11
- trace: function(),
12
- symbols_: {associative list: name ==> number},
13
- terminals_: {associative list: number ==> name},
14
- productions_: [...],
15
- performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$),
16
- table: [...],
17
- defaultActions: {...},
18
- parseError: function(str, hash),
19
- parse: function(input),
20
-
21
- lexer: {
22
- EOF: 1,
23
- parseError: function(str, hash),
24
- setInput: function(input),
25
- input: function(),
26
- unput: function(str),
27
- more: function(),
28
- less: function(n),
29
- pastInput: function(),
30
- upcomingInput: function(),
31
- showPosition: function(),
32
- test_match: function(regex_match_array, rule_index),
33
- next: function(),
34
- lex: function(),
35
- begin: function(condition),
36
- popState: function(),
37
- _currentRules: function(),
38
- topState: function(),
39
- pushState: function(condition),
40
-
41
- options: {
42
- ranges: boolean (optional: true ==> token location info will include a .range[] member)
43
- flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match)
44
- backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code)
45
- },
46
-
47
- performAction: function(yy, yy_, $avoiding_name_collisions, YY_START),
48
- rules: [...],
49
- conditions: {associative list: name ==> set},
50
- }
51
- }
52
-
53
-
54
- token location info (@$, _$, etc.): {
55
- first_line: n,
56
- last_line: n,
57
- first_column: n,
58
- last_column: n,
59
- range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based)
60
- }
61
-
62
-
63
- the parseError function receives a 'hash' object with these members for lexer and parser errors: {
64
- text: (matched text)
65
- token: (the produced terminal token, if any)
66
- line: (yylineno)
67
- }
68
- while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: {
69
- loc: (yylloc)
70
- expected: (string describing the set of expected tokens)
71
- recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error)
72
- }
73
- */
74
- var tgnParser = (function(){
75
- var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,7],$V1=[2,25],$V2=[6,8,49],$V3=[1,32],$V4=[6,49],$V5=[11,49],$V6=[11,48],$V7=[1,51],$V8=[1,52],$V9=[1,53],$Va=[6,36,37,38,49];
76
- var parser = {trace: function trace () { },
77
- yy: {},
78
- symbols_: {"error":2,"game":3,"tag_section":4,"move_section":5,"EOF":6,"tag_pair":7,"[":8,"tag_name":9,"STRING":10,"]":11,"TAG_RESULT":12,"game_result":13,"TAG_BOARD":14,"board_shape":15,"TAG_EVENT":16,"TAG_SITE":17,"TAG_DATE":18,"TAG_ROUND":19,"TAG_BLACK":20,"TAG_WHITE":21,"TAG_HANDICAP":22,"TAG_RULES":23,"TAG_TIMECONTROL":24,"TAG_ANNOTATOR":25,"TAG_APPLICATION":26,"TAG_NAME":27,"move_sequence":28,"move_sequence_intact":29,"move_sequence_truncated":30,"move_round":31,"move_round_half":32,"number":33,"DOT":34,"move_action":35,"PASS":36,"RESIGN":37,"COORDINATE":38,"win":39,"conquer":40,"=":41,"*":42,"RESULT_BLACK":43,"RESULT_WHITE":44,"conquer_unit":45,"POINTS":46,"STONES":47,"TIMES":48,"NUMBER":49,"$accept":0,"$end":1},
79
- terminals_: {2:"error",6:"EOF",8:"[",10:"STRING",11:"]",12:"TAG_RESULT",14:"TAG_BOARD",16:"TAG_EVENT",17:"TAG_SITE",18:"TAG_DATE",19:"TAG_ROUND",20:"TAG_BLACK",21:"TAG_WHITE",22:"TAG_HANDICAP",23:"TAG_RULES",24:"TAG_TIMECONTROL",25:"TAG_ANNOTATOR",26:"TAG_APPLICATION",27:"TAG_NAME",34:"DOT",36:"PASS",37:"RESIGN",38:"COORDINATE",41:"=",42:"*",43:"RESULT_BLACK",44:"RESULT_WHITE",46:"POINTS",47:"STONES",48:"TIMES",49:"NUMBER"},
80
- productions_: [0,[3,3],[3,2],[3,2],[3,1],[4,1],[4,2],[7,4],[7,4],[7,4],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[5,1],[28,1],[28,1],[29,0],[29,2],[30,2],[31,4],[32,3],[35,1],[35,1],[35,1],[13,1],[13,2],[13,1],[13,1],[39,1],[39,1],[40,2],[45,1],[45,1],[15,1],[15,3],[33,1]],
81
- performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
82
- /* this == yyval */
83
-
84
- var $0 = $$.length - 1;
85
- switch (yystate) {
86
- case 1:
87
-
88
- return {
89
- tags: $$[$0-2],
90
- moves: $$[$0-1],
91
- success: true
92
- };
93
-
94
- break;
95
- case 2:
96
-
97
- return {
98
- tags: $$[$0-1],
99
- moves: null,
100
- success: true
101
- };
102
-
103
- break;
104
- case 3:
105
-
106
- return {
107
- tags: {},
108
- moves: $$[$0-1],
109
- success: true
110
- };
111
-
112
- break;
113
- case 4:
114
-
115
- return {
116
- tags: {},
117
- moves: null,
118
- success: true
119
- };
120
-
121
- break;
122
- case 5: case 23: case 24:
123
- this.$ = $$[$0];
124
- break;
125
- case 6:
126
- this.$ = Object.assign({}, $$[$0-1], $$[$0]);
127
- break;
128
- case 7:
129
-
130
- const tagName = $$[$0-2];
131
- const tagValue = $$[$0-1].slice(1, -1); // Remove quotes
132
- this.$ = { [tagName]: tagValue };
133
-
134
- break;
135
- case 8:
136
- this.$ = $$[$0-1];
137
- break;
138
- case 9:
139
- this.$ = ({[$$[$0-2]]: $$[$0-1]});
140
- break;
141
- case 21:
142
- this.$ = yytext;
143
- break;
144
- case 25:
145
- this.$ = [];
146
- break;
147
- case 26: case 27:
148
- this.$ = $$[$0-1].concat([$$[$0]]);
149
- break;
150
- case 28:
151
- this.$ = ({ round: $$[$0-3], action_black: $$[$0-1], action_white: $$[$0] });
152
- break;
153
- case 29:
154
- this.$ = ({ round: $$[$0-2], action_black: $$[$0] });
155
- break;
156
- case 30:
157
- this.$ = ({ type: 'pass' });
158
- break;
159
- case 31:
160
- this.$ = ({ type: 'resign' });
161
- break;
162
- case 32:
163
-
164
- // Placeholder: Parse coordinate notation
165
- this.$ = {
166
- type: 'move',
167
- position: yytext
168
- };
169
-
170
- break;
171
- case 33:
172
- this.$ = ({Result: $$[$0]});
173
- break;
174
- case 34:
175
- this.$ = ({Result: $$[$0-1], Conquer: $$[$0]});
176
- break;
177
- case 35:
178
- this.$ = ({Result: "draw"});
179
- break;
180
- case 36:
181
- this.$ = ({Result: "unknown"});
182
- break;
183
- case 37:
184
- this.$ = "black win";
185
- break;
186
- case 38:
187
- this.$ = "white win";
188
- break;
189
- case 39:
190
- this.$ = ({n: $$[$0-1], unit: $$[$0]});
191
- break;
192
- case 42:
193
- this.$ = [$$[$0]];
194
- break;
195
- case 43:
196
- this.$ = $$[$0-2].concat($$[$0]);
197
- break;
198
- case 44:
199
- this.$ = parseInt($$[$0]);
200
- break;
201
- }
202
- },
203
- table: [{3:1,4:2,5:3,6:[1,4],7:5,8:$V0,28:6,29:8,30:9,49:$V1},{1:[3]},{5:10,6:[1,11],7:12,8:$V0,28:6,29:8,30:9,49:$V1},{6:[1,13]},{1:[2,4]},o($V2,[2,5]),{6:[2,22]},{9:14,12:[1,15],14:[1,16],16:[1,17],17:[1,18],18:[1,19],19:[1,20],20:[1,21],21:[1,22],22:[1,23],23:[1,24],24:[1,25],25:[1,26],26:[1,27],27:[1,28]},{6:[2,23],31:29,32:30,33:31,49:$V3},{6:[2,24]},{6:[1,33]},{1:[2,2]},o($V2,[2,6]),{1:[2,3]},{10:[1,34]},{13:35,39:36,41:[1,37],42:[1,38],43:[1,39],44:[1,40]},{15:41,33:42,49:$V3},{10:[2,10]},{10:[2,11]},{10:[2,12]},{10:[2,13]},{10:[2,14]},{10:[2,15]},{10:[2,16]},{10:[2,17]},{10:[2,18]},{10:[2,19]},{10:[2,20]},{10:[2,21]},o($V4,[2,26]),{6:[2,27]},{34:[1,43]},o([11,34,46,47,48],[2,44]),{1:[2,1]},{11:[1,44]},{11:[1,45]},{11:[2,33],33:47,40:46,49:$V3},{11:[2,35]},{11:[2,36]},o($V5,[2,37]),o($V5,[2,38]),{11:[1,48],48:[1,49]},o($V6,[2,42]),{35:50,36:$V7,37:$V8,38:$V9},o($V2,[2,7]),o($V2,[2,8]),{11:[2,34]},{45:54,46:[1,55],47:[1,56]},o($V2,[2,9]),{33:57,49:$V3},{6:[2,29],35:58,36:$V7,37:$V8,38:$V9},o($Va,[2,30]),o($Va,[2,31]),o($Va,[2,32]),{11:[2,39]},{11:[2,40]},{11:[2,41]},o($V6,[2,43]),o($V4,[2,28])],
204
- defaultActions: {4:[2,4],6:[2,22],9:[2,24],11:[2,2],13:[2,3],17:[2,10],18:[2,11],19:[2,12],20:[2,13],21:[2,14],22:[2,15],23:[2,16],24:[2,17],25:[2,18],26:[2,19],27:[2,20],28:[2,21],30:[2,27],33:[2,1],37:[2,35],38:[2,36],46:[2,34],54:[2,39],55:[2,40],56:[2,41]},
205
- parseError: function parseError (str, hash) {
206
- if (hash.recoverable) {
207
- this.trace(str);
208
- } else {
209
- var error = new Error(str);
210
- error.hash = hash;
211
- throw error;
212
- }
213
- },
214
- parse: function parse(input) {
215
- var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
216
- var args = lstack.slice.call(arguments, 1);
217
- var lexer = Object.create(this.lexer);
218
- var sharedState = { yy: {} };
219
- for (var k in this.yy) {
220
- if (Object.prototype.hasOwnProperty.call(this.yy, k)) {
221
- sharedState.yy[k] = this.yy[k];
222
- }
223
- }
224
- lexer.setInput(input, sharedState.yy);
225
- sharedState.yy.lexer = lexer;
226
- sharedState.yy.parser = this;
227
- if (typeof lexer.yylloc == 'undefined') {
228
- lexer.yylloc = {};
229
- }
230
- var yyloc = lexer.yylloc;
231
- lstack.push(yyloc);
232
- var ranges = lexer.options && lexer.options.ranges;
233
- if (typeof sharedState.yy.parseError === 'function') {
234
- this.parseError = sharedState.yy.parseError;
235
- } else {
236
- this.parseError = Object.getPrototypeOf(this).parseError;
237
- }
238
- function popStack(n) {
239
- stack.length = stack.length - 2 * n;
240
- vstack.length = vstack.length - n;
241
- lstack.length = lstack.length - n;
242
- }
243
- _token_stack:
244
- var lex = function () {
245
- var token;
246
- token = lexer.lex() || EOF;
247
- if (typeof token !== 'number') {
248
- token = self.symbols_[token] || token;
249
- }
250
- return token;
251
- };
252
- var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
253
- while (true) {
254
- state = stack[stack.length - 1];
255
- if (this.defaultActions[state]) {
256
- action = this.defaultActions[state];
257
- } else {
258
- if (symbol === null || typeof symbol == 'undefined') {
259
- symbol = lex();
260
- }
261
- action = table[state] && table[state][symbol];
262
- }
263
- if (typeof action === 'undefined' || !action.length || !action[0]) {
264
- var errStr = '';
265
- expected = [];
266
- for (p in table[state]) {
267
- if (this.terminals_[p] && p > TERROR) {
268
- expected.push('\'' + this.terminals_[p] + '\'');
269
- }
270
- }
271
- if (lexer.showPosition) {
272
- errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\'';
273
- } else {
274
- errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\'');
275
- }
276
- this.parseError(errStr, {
277
- text: lexer.match,
278
- token: this.terminals_[symbol] || symbol,
279
- line: lexer.yylineno,
280
- loc: yyloc,
281
- expected: expected
282
- });
283
- }
284
- if (action[0] instanceof Array && action.length > 1) {
285
- throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol);
286
- }
287
- switch (action[0]) {
288
- case 1:
289
- stack.push(symbol);
290
- vstack.push(lexer.yytext);
291
- lstack.push(lexer.yylloc);
292
- stack.push(action[1]);
293
- symbol = null;
294
- if (!preErrorSymbol) {
295
- yyleng = lexer.yyleng;
296
- yytext = lexer.yytext;
297
- yylineno = lexer.yylineno;
298
- yyloc = lexer.yylloc;
299
- if (recovering > 0) {
300
- recovering--;
301
- }
302
- } else {
303
- symbol = preErrorSymbol;
304
- preErrorSymbol = null;
305
- }
306
- break;
307
- case 2:
308
- len = this.productions_[action[1]][1];
309
- yyval.$ = vstack[vstack.length - len];
310
- yyval._$ = {
311
- first_line: lstack[lstack.length - (len || 1)].first_line,
312
- last_line: lstack[lstack.length - 1].last_line,
313
- first_column: lstack[lstack.length - (len || 1)].first_column,
314
- last_column: lstack[lstack.length - 1].last_column
315
- };
316
- if (ranges) {
317
- yyval._$.range = [
318
- lstack[lstack.length - (len || 1)].range[0],
319
- lstack[lstack.length - 1].range[1]
320
- ];
321
- }
322
- r = this.performAction.apply(yyval, [
323
- yytext,
324
- yyleng,
325
- yylineno,
326
- sharedState.yy,
327
- action[1],
328
- vstack,
329
- lstack
330
- ].concat(args));
331
- if (typeof r !== 'undefined') {
332
- return r;
333
- }
334
- if (len) {
335
- stack = stack.slice(0, -1 * len * 2);
336
- vstack = vstack.slice(0, -1 * len);
337
- lstack = lstack.slice(0, -1 * len);
338
- }
339
- stack.push(this.productions_[action[1]][0]);
340
- vstack.push(yyval.$);
341
- lstack.push(yyval._$);
342
- newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
343
- stack.push(newState);
344
- break;
345
- case 3:
346
- return true;
347
- }
348
- }
349
- return true;
350
- }};
351
-
352
-
353
- /* ========== Additional JavaScript Code ========== */
354
-
355
- // Parser configuration
356
- parser.yy = {
357
- // Helper functions can be added here
358
- parseError: function(str, hash) {
359
- throw new Error('Parse error: ' + str);
360
- }
361
- };
362
- /* generated by jison-lex 0.3.4 */
363
- var lexer = (function(){
364
- var lexer = ({
365
-
366
- EOF:1,
367
-
368
- parseError:function parseError(str, hash) {
369
- if (this.yy.parser) {
370
- this.yy.parser.parseError(str, hash);
371
- } else {
372
- throw new Error(str);
373
- }
374
- },
375
-
376
- // resets the lexer, sets new input
377
- setInput:function (input, yy) {
378
- this.yy = yy || this.yy || {};
379
- this._input = input;
380
- this._more = this._backtrack = this.done = false;
381
- this.yylineno = this.yyleng = 0;
382
- this.yytext = this.matched = this.match = '';
383
- this.conditionStack = ['INITIAL'];
384
- this.yylloc = {
385
- first_line: 1,
386
- first_column: 0,
387
- last_line: 1,
388
- last_column: 0
389
- };
390
- if (this.options.ranges) {
391
- this.yylloc.range = [0,0];
392
- }
393
- this.offset = 0;
394
- return this;
395
- },
396
-
397
- // consumes and returns one char from the input
398
- input:function () {
399
- var ch = this._input[0];
400
- this.yytext += ch;
401
- this.yyleng++;
402
- this.offset++;
403
- this.match += ch;
404
- this.matched += ch;
405
- var lines = ch.match(/(?:\r\n?|\n).*/g);
406
- if (lines) {
407
- this.yylineno++;
408
- this.yylloc.last_line++;
409
- } else {
410
- this.yylloc.last_column++;
411
- }
412
- if (this.options.ranges) {
413
- this.yylloc.range[1]++;
414
- }
415
-
416
- this._input = this._input.slice(1);
417
- return ch;
418
- },
419
-
420
- // unshifts one char (or a string) into the input
421
- unput:function (ch) {
422
- var len = ch.length;
423
- var lines = ch.split(/(?:\r\n?|\n)/g);
424
-
425
- this._input = ch + this._input;
426
- this.yytext = this.yytext.substr(0, this.yytext.length - len);
427
- //this.yyleng -= len;
428
- this.offset -= len;
429
- var oldLines = this.match.split(/(?:\r\n?|\n)/g);
430
- this.match = this.match.substr(0, this.match.length - 1);
431
- this.matched = this.matched.substr(0, this.matched.length - 1);
432
-
433
- if (lines.length - 1) {
434
- this.yylineno -= lines.length - 1;
435
- }
436
- var r = this.yylloc.range;
437
-
438
- this.yylloc = {
439
- first_line: this.yylloc.first_line,
440
- last_line: this.yylineno + 1,
441
- first_column: this.yylloc.first_column,
442
- last_column: lines ?
443
- (lines.length === oldLines.length ? this.yylloc.first_column : 0)
444
- + oldLines[oldLines.length - lines.length].length - lines[0].length :
445
- this.yylloc.first_column - len
446
- };
447
-
448
- if (this.options.ranges) {
449
- this.yylloc.range = [r[0], r[0] + this.yyleng - len];
450
- }
451
- this.yyleng = this.yytext.length;
452
- return this;
453
- },
454
-
455
- // When called from action, caches matched text and appends it on next action
456
- more:function () {
457
- this._more = true;
458
- return this;
459
- },
460
-
461
- // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.
462
- reject:function () {
463
- if (this.options.backtrack_lexer) {
464
- this._backtrack = true;
465
- } else {
466
- return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), {
467
- text: "",
468
- token: null,
469
- line: this.yylineno
470
- });
471
-
472
- }
473
- return this;
474
- },
475
-
476
- // retain first n characters of the match
477
- less:function (n) {
478
- this.unput(this.match.slice(n));
479
- },
480
-
481
- // displays already matched input, i.e. for error messages
482
- pastInput:function () {
483
- var past = this.matched.substr(0, this.matched.length - this.match.length);
484
- return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
485
- },
486
-
487
- // displays upcoming input, i.e. for error messages
488
- upcomingInput:function () {
489
- var next = this.match;
490
- if (next.length < 20) {
491
- next += this._input.substr(0, 20-next.length);
492
- }
493
- return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
494
- },
495
-
496
- // displays the character position where the lexing error occurred, i.e. for error messages
497
- showPosition:function () {
498
- var pre = this.pastInput();
499
- var c = new Array(pre.length + 1).join("-");
500
- return pre + this.upcomingInput() + "\n" + c + "^";
501
- },
502
-
503
- // test the lexed token: return FALSE when not a match, otherwise return token
504
- test_match:function(match, indexed_rule) {
505
- var token,
506
- lines,
507
- backup;
508
-
509
- if (this.options.backtrack_lexer) {
510
- // save context
511
- backup = {
512
- yylineno: this.yylineno,
513
- yylloc: {
514
- first_line: this.yylloc.first_line,
515
- last_line: this.last_line,
516
- first_column: this.yylloc.first_column,
517
- last_column: this.yylloc.last_column
518
- },
519
- yytext: this.yytext,
520
- match: this.match,
521
- matches: this.matches,
522
- matched: this.matched,
523
- yyleng: this.yyleng,
524
- offset: this.offset,
525
- _more: this._more,
526
- _input: this._input,
527
- yy: this.yy,
528
- conditionStack: this.conditionStack.slice(0),
529
- done: this.done
530
- };
531
- if (this.options.ranges) {
532
- backup.yylloc.range = this.yylloc.range.slice(0);
533
- }
534
- }
535
-
536
- lines = match[0].match(/(?:\r\n?|\n).*/g);
537
- if (lines) {
538
- this.yylineno += lines.length;
539
- }
540
- this.yylloc = {
541
- first_line: this.yylloc.last_line,
542
- last_line: this.yylineno + 1,
543
- first_column: this.yylloc.last_column,
544
- last_column: lines ?
545
- lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length :
546
- this.yylloc.last_column + match[0].length
547
- };
548
- this.yytext += match[0];
549
- this.match += match[0];
550
- this.matches = match;
551
- this.yyleng = this.yytext.length;
552
- if (this.options.ranges) {
553
- this.yylloc.range = [this.offset, this.offset += this.yyleng];
554
- }
555
- this._more = false;
556
- this._backtrack = false;
557
- this._input = this._input.slice(match[0].length);
558
- this.matched += match[0];
559
- token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);
560
- if (this.done && this._input) {
561
- this.done = false;
562
- }
563
- if (token) {
564
- return token;
565
- } else if (this._backtrack) {
566
- // recover context
567
- for (var k in backup) {
568
- this[k] = backup[k];
569
- }
570
- return false; // rule action called reject() implying the next rule should be tested instead.
571
- }
572
- return false;
573
- },
574
-
575
- // return next match in input
576
- next:function () {
577
- if (this.done) {
578
- return this.EOF;
579
- }
580
- if (!this._input) {
581
- this.done = true;
582
- }
583
-
584
- var token,
585
- match,
586
- tempMatch,
587
- index;
588
- if (!this._more) {
589
- this.yytext = '';
590
- this.match = '';
591
- }
592
- var rules = this._currentRules();
593
- for (var i = 0; i < rules.length; i++) {
594
- tempMatch = this._input.match(this.rules[rules[i]]);
595
- if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
596
- match = tempMatch;
597
- index = i;
598
- if (this.options.backtrack_lexer) {
599
- token = this.test_match(tempMatch, rules[i]);
600
- if (token !== false) {
601
- return token;
602
- } else if (this._backtrack) {
603
- match = false;
604
- continue; // rule action called reject() implying a rule MISmatch.
605
- } else {
606
- // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
607
- return false;
608
- }
609
- } else if (!this.options.flex) {
610
- break;
611
- }
612
- }
613
- }
614
- if (match) {
615
- token = this.test_match(match, rules[index]);
616
- if (token !== false) {
617
- return token;
618
- }
619
- // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
620
- return false;
621
- }
622
- if (this._input === "") {
623
- return this.EOF;
624
- } else {
625
- return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), {
626
- text: "",
627
- token: null,
628
- line: this.yylineno
629
- });
630
- }
631
- },
632
-
633
- // return next match that has a token
634
- lex:function lex () {
635
- var r = this.next();
636
- if (r) {
637
- return r;
638
- } else {
639
- return this.lex();
640
- }
641
- },
642
-
643
- // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)
644
- begin:function begin (condition) {
645
- this.conditionStack.push(condition);
646
- },
647
-
648
- // pop the previously active lexer condition state off the condition stack
649
- popState:function popState () {
650
- var n = this.conditionStack.length - 1;
651
- if (n > 0) {
652
- return this.conditionStack.pop();
653
- } else {
654
- return this.conditionStack[0];
655
- }
656
- },
657
-
658
- // produce the lexer rule set which is active for the currently active lexer condition state
659
- _currentRules:function _currentRules () {
660
- if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {
661
- return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
662
- } else {
663
- return this.conditions["INITIAL"].rules;
664
- }
665
- },
666
-
667
- // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available
668
- topState:function topState (n) {
669
- n = this.conditionStack.length - 1 - Math.abs(n || 0);
670
- if (n >= 0) {
671
- return this.conditionStack[n];
672
- } else {
673
- return "INITIAL";
674
- }
675
- },
676
-
677
- // alias for begin(condition)
678
- pushState:function pushState (condition) {
679
- this.begin(condition);
680
- },
681
-
682
- // return the number of states currently on the stack
683
- stateStackSize:function stateStackSize() {
684
- return this.conditionStack.length;
685
- },
686
- options: {},
687
- performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
688
- var YYSTATE=YY_START;
689
- switch($avoiding_name_collisions) {
690
- case 0:/* skip whitespace */
691
- break;
692
- case 1:/* skip newlines */
693
- break;
694
- case 2:/* skip line comments */
695
- break;
696
- case 3:/* skip block comments */
697
- break;
698
- case 4:return 8
699
- break;
700
- case 5:return 11
701
- break;
702
- case 6:return 10
703
- break;
704
- case 7:return 16
705
- break;
706
- case 8:return 17
707
- break;
708
- case 9:return 18
709
- break;
710
- case 10:return 19
711
- break;
712
- case 11:return 20
713
- break;
714
- case 12:return 21
715
- break;
716
- case 13:return 12
717
- break;
718
- case 14:return 14
719
- break;
720
- case 15:return 22
721
- break;
722
- case 16:return 23
723
- break;
724
- case 17:return 24
725
- break;
726
- case 18:return 25
727
- break;
728
- case 19:return 26
729
- break;
730
- case 20:return 43
731
- break;
732
- case 21:return 44
733
- break;
734
- case 22:return 41 /* draw */
735
- break;
736
- case 23:return 42 /* unknown */
737
- break;
738
- case 24:return 49
739
- break;
740
- case 25:return 34
741
- break;
742
- case 26:return 36
743
- break;
744
- case 27:return 37
745
- break;
746
- case 28:return 46
747
- break;
748
- case 29:return 47
749
- break;
750
- case 30:return 48
751
- break;
752
- case 31:return 38
753
- break;
754
- case 32:return 27
755
- break;
756
- case 33:return 6
757
- break;
758
- case 34:return 'INVALID'
759
- break;
760
- }
761
- },
762
- rules: [/^(?:\s+)/,/^(?:\n)/,/^(?:;[^\n]*)/,/^(?:\{[^}]*\})/,/^(?:\[)/,/^(?:\])/,/^(?:"([^\\\"]|\\.)*")/,/^(?:Event\b)/,/^(?:Site\b)/,/^(?:Date\b)/,/^(?:Round\b)/,/^(?:Black\b)/,/^(?:White\b)/,/^(?:Result\b)/,/^(?:Board\b)/,/^(?:Handicap\b)/,/^(?:Rules\b)/,/^(?:TimeControl\b)/,/^(?:Annotator\b)/,/^(?:Application\b)/,/^(?:B\+)/,/^(?:W\+)/,/^(?:=)/,/^(?:\*)/,/^(?:[1-9][0-9]*)/,/^(?:\.)/,/^(?:Pass\b)/,/^(?:Resign\b)/,/^(?:points\b)/,/^(?:stones\b)/,/^(?:[x](?=[1-9]))/,/^(?:[a-z0]+)/,/^(?:[A-Z][A-Za-z0-9_]*)/,/^(?:$)/,/^(?:.)/],
763
- conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"inclusive":true}}
764
- });
765
- return lexer;
766
- })();
767
- parser.lexer = lexer;
768
- function Parser () {
769
- this.yy = {};
770
- }
771
- Parser.prototype = parser;parser.Parser = Parser;
772
- return new Parser;
773
- })();
774
-
775
-
776
- if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
777
- exports.parser = tgnParser;
778
- exports.Parser = tgnParser.Parser;
779
- exports.parse = function () { return tgnParser.parse.apply(tgnParser, arguments); };
780
- exports.main = function commonjsMain (args) {
781
- if (!args[1]) {
782
- console.log('Usage: '+args[0]+' FILE');
783
- process.exit(1);
784
- }
785
- var source = require('fs').readFileSync(require('path').normalize(args[1]), "utf8");
786
- return exports.parser.parse(source);
787
- };
788
- if (typeof module !== 'undefined' && require.main === module) {
789
- exports.main(process.argv.slice(1));
790
- }
791
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
trigo-web/app/dist/onnx/20251130-trigo-value-gpt2-l6-h64-251125-lr2000/.gitignore DELETED
@@ -1 +0,0 @@
1
- *
 
 
trigo-web/app/dist/onnx/20251130-trigo-value-gpt2-l6-h64-251125-lr2000/GPT2CausalLM_ep0042_evaluation.onnx DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:4d9a3791f6eab3f155ac4085d1525185898e9405362b6c6570eb36868cfb4dca
3
- size 3649985
 
 
 
 
trigo-web/app/dist/onnx/20251130-trigo-value-gpt2-l6-h64-251125-lr2000/GPT2CausalLM_ep0042_tree-v2.onnx DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:0d31550ce1ee5287d6a38deedba181ce70ba305d00e547f20ee505ee88f7e4ae
3
- size 3612776
 
 
 
 
trigo-web/app/dist/onnx/20251130-trigo-value-gpt2-l6-h64-251125-lr2000/GPT2CausalLM_ep0042_tree.onnx DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:b85469a41850c4d65659e9f688d481b548588610de9acbee3527a690e7012a57
3
- size 3611749
 
 
 
 
trigo-web/app/dist/onnx/20251220-trigo-value-llama-l6-h64-251220-value0.02/LlamaCausalLM_ep0036_evaluation.onnx DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:f28ac6d8655eec8189887baff3677159e0c9b4dbc4c415884de9159b6d0ee621
3
- size 1387656
 
 
 
 
trigo-web/app/dist/onnx/20251220-trigo-value-llama-l6-h64-251220-value0.02/LlamaCausalLM_ep0036_tree.onnx DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:84f0441fa4688cd3b3b02195237a3bce8ff9380f1ba57db6fd8fe1fa9ffcec01
3
- size 1378983
 
 
 
 
trigo-web/app/dist/onnx/20251230-trigo-value-llama-l6-h64-it2_251221-value0.01-pretrain/LlamaCausalLM_ep0036_evaluation.onnx DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:27cc45ccdfca3019e6561918bcbb7376985f31388b66370d029f73064a2cc93a
3
- size 1387656
 
 
 
 
trigo-web/app/dist/onnx/20251230-trigo-value-llama-l6-h64-it2_251221-value0.01-pretrain/LlamaCausalLM_ep0036_tree.onnx DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:258d947a1c40578a0fc6b8a98f16965aacceed74e3c7516c697aa6f9d772bf43
3
- size 1378983
 
 
 
 
trigo-web/app/hf-autoplay.cjs ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const { io } = require('socket.io-client');
2
+
3
+ const socket = io('http://localhost:8157', {
4
+ transports: ['websocket', 'polling']
5
+ });
6
+
7
+ let myColor = null;
8
+ let gameStarted = false;
9
+ let currentRoomId = null;
10
+
11
+ const priorityMoves = [
12
+ {x:2,y:2,z:2}, {x:1,y:2,z:2}, {x:3,y:2,z:2}, {x:2,y:1,z:2}, {x:2,y:3,z:2},
13
+ {x:2,y:2,z:1}, {x:2,y:2,z:3}, {x:1,y:1,z:2}, {x:3,y:3,z:2}, {x:1,y:3,z:2},
14
+ {x:3,y:1,z:2}, {x:2,y:1,z:1}, {x:2,y:3,z:1}, {x:1,y:2,z:1}, {x:3,y:2,z:1},
15
+ {x:2,y:1,z:3}, {x:2,y:3,z:3}, {x:1,y:2,z:3}, {x:3,y:2,z:3},
16
+ {x:1,y:1,z:1}, {x:3,y:3,z:3}, {x:1,y:3,z:1}, {x:3,y:1,z:1},
17
+ {x:1,y:1,z:3}, {x:3,y:3,z:1}, {x:1,y:3,z:3}, {x:3,y:1,z:3},
18
+ {x:0,y:2,z:2}, {x:4,y:2,z:2}, {x:2,y:0,z:2}, {x:2,y:4,z:2},
19
+ {x:2,y:2,z:0}, {x:2,y:2,z:4}, {x:0,y:0,z:0}, {x:4,y:4,z:4}
20
+ ];
21
+ let moveIdx = 0;
22
+
23
+ function tryMove() {
24
+ if (!gameStarted) {
25
+ console.log('Game not started yet, waiting for opponent...');
26
+ return;
27
+ }
28
+ if (moveIdx >= priorityMoves.length) {
29
+ console.log('No more moves');
30
+ moveIdx = 0; // Reset for next round
31
+ return;
32
+ }
33
+ const move = priorityMoves[moveIdx++];
34
+ console.log('Trying:', JSON.stringify(move));
35
+ socket.emit('makeMove', move);
36
+ }
37
+
38
+ socket.on('connect', () => {
39
+ console.log('Connected to local server');
40
+
41
+ // Always create a new room (for testing room selector)
42
+ console.log('Creating new room...');
43
+ socket.emit('joinRoom', { nickname: 'Claude' }, handleJoinResponse);
44
+ });
45
+
46
+ function handleJoinResponse(r) {
47
+ if (!r.success) {
48
+ console.log('Join failed:', r.error);
49
+ process.exit(1);
50
+ }
51
+ myColor = r.playerColor;
52
+ currentRoomId = r.roomId;
53
+ gameStarted = r.gameState?.gameStatus === 'playing';
54
+
55
+ console.log('Room:', r.roomId, '| Color:', myColor, '| Turn:', r.gameState?.currentPlayer);
56
+ console.log('Status:', r.gameState?.gameStatus, '| Players:', Object.keys(r.players || {}).length);
57
+
58
+ if (gameStarted && r.gameState?.currentPlayer === myColor) {
59
+ console.log('My turn!');
60
+ tryMove();
61
+ } else if (!gameStarted) {
62
+ console.log('Waiting for opponent to join (room:', currentRoomId, ')...');
63
+ } else {
64
+ console.log('Waiting for opponent to move...');
65
+ }
66
+ }
67
+
68
+ socket.on('playerJoined', (data) => {
69
+ console.log('>>> Player joined:', data.nickname);
70
+ gameStarted = true;
71
+ // When opponent joins, game starts. If I'm black, it's my turn
72
+ if (myColor === 'black') {
73
+ console.log('Game started! My turn (black first)');
74
+ moveIdx = 0; // Reset moves
75
+ tryMove();
76
+ }
77
+ });
78
+
79
+ socket.on('gameUpdate', (data) => {
80
+ const who = data.currentPlayer === myColor ? 'Opponent' : 'Me';
81
+ console.log(who, 'moved:', JSON.stringify(data.lastMove), '| Next:', data.currentPlayer);
82
+
83
+ if (data.currentPlayer === myColor) {
84
+ setTimeout(tryMove, 300);
85
+ }
86
+ });
87
+
88
+ socket.on('error', (e) => {
89
+ console.log('Error:', e.message);
90
+ tryMove();
91
+ });
92
+
93
+ socket.on('gameEnded', (data) => {
94
+ console.log('=== GAME ENDED ===');
95
+ console.log('Winner:', data.winner, '| Reason:', data.reason);
96
+ process.exit(0);
97
+ });
98
+
99
+ setTimeout(() => {
100
+ console.log('Session timeout');
101
+ process.exit(0);
102
+ }, 300000);
trigo-web/app/src/views/TrigoView.vue CHANGED
@@ -1097,43 +1097,48 @@
1097
  * Room list management for room selector dropdown
1098
  */
1099
  function fetchRoomList() {
1100
- console.log("[TrigoView] Fetching room list...");
1101
  isLoadingRooms.value = true;
1102
  socketApi.listRooms((response: any) => {
1103
  console.log("[TrigoView] listRooms response:", response);
1104
  isLoadingRooms.value = false;
1105
  if (response.success) {
1106
- roomList.value = response.rooms;
1107
- console.log("[TrigoView] Room list updated, count:", roomList.value.length);
 
 
1108
  }
1109
  });
1110
  }
1111
 
1112
  function setupRoomListeners() {
1113
- console.log("[TrigoView] Setting up room listeners");
1114
 
1115
  socketApi.onRoomCreated((data: RoomSummary) => {
1116
- console.log("[TrigoView] Received roomCreated event:", data);
 
1117
  // Add new room to list if not already present
1118
  if (!roomList.value.find(r => r.id === data.id)) {
1119
- roomList.value.push(data);
1120
- console.log("[TrigoView] Added room to list, new count:", roomList.value.length);
1121
  }
1122
  });
1123
 
1124
  socketApi.onRoomUpdated((data: RoomSummary) => {
1125
- console.log("[TrigoView] Received roomUpdated event:", data);
1126
  const index = roomList.value.findIndex(r => r.id === data.id);
1127
  if (index >= 0) {
1128
- roomList.value[index] = data;
1129
  } else {
1130
- roomList.value.push(data);
1131
  }
 
1132
  });
1133
 
1134
  socketApi.onRoomDeleted((data: { roomId: string }) => {
1135
- console.log("[TrigoView] Received roomDeleted event:", data);
1136
  roomList.value = roomList.value.filter(r => r.id !== data.roomId);
 
1137
  });
1138
  }
1139
 
 
1097
  * Room list management for room selector dropdown
1098
  */
1099
  function fetchRoomList() {
1100
+ console.log("[TrigoView] fetchRoomList() called, socket connected:", socketApi.socket.connected, "socket id:", socketApi.socket.id);
1101
  isLoadingRooms.value = true;
1102
  socketApi.listRooms((response: any) => {
1103
  console.log("[TrigoView] listRooms response:", response);
1104
  isLoadingRooms.value = false;
1105
  if (response.success) {
1106
+ roomList.value = response.rooms || [];
1107
+ console.log("[TrigoView] Room list updated, count:", roomList.value.length, "rooms:", roomList.value.map((r: any) => r.id));
1108
+ } else {
1109
+ console.error("[TrigoView] listRooms failed:", response.error);
1110
  }
1111
  });
1112
  }
1113
 
1114
  function setupRoomListeners() {
1115
+ console.log("[TrigoView] Setting up room listeners, socket connected:", socketApi.socket.connected, "socket id:", socketApi.socket.id);
1116
 
1117
  socketApi.onRoomCreated((data: RoomSummary) => {
1118
+ console.log("[TrigoView] >>> Received roomCreated event:", data);
1119
+ console.log("[TrigoView] Current roomList before add:", JSON.stringify(roomList.value));
1120
  // Add new room to list if not already present
1121
  if (!roomList.value.find(r => r.id === data.id)) {
1122
+ roomList.value = [...roomList.value, data]; // Use spread to ensure reactivity
1123
+ console.log("[TrigoView] Added room to list, new count:", roomList.value.length, "rooms:", roomList.value.map(r => r.id));
1124
  }
1125
  });
1126
 
1127
  socketApi.onRoomUpdated((data: RoomSummary) => {
1128
+ console.log("[TrigoView] >>> Received roomUpdated event:", data);
1129
  const index = roomList.value.findIndex(r => r.id === data.id);
1130
  if (index >= 0) {
1131
+ roomList.value = [...roomList.value.slice(0, index), data, ...roomList.value.slice(index + 1)];
1132
  } else {
1133
+ roomList.value = [...roomList.value, data];
1134
  }
1135
+ console.log("[TrigoView] roomList after update:", roomList.value.map(r => r.id));
1136
  });
1137
 
1138
  socketApi.onRoomDeleted((data: { roomId: string }) => {
1139
+ console.log("[TrigoView] >>> Received roomDeleted event:", data);
1140
  roomList.value = roomList.value.filter(r => r.id !== data.roomId);
1141
+ console.log("[TrigoView] roomList after delete:", roomList.value.map(r => r.id));
1142
  });
1143
  }
1144