Spaces:
Running
Running
Commit
·
be5c8a6
1
Parent(s):
23c0c0a
Skip vite build by committing pre-built frontend dist
Browse files- Include pre-built dist folder with all frontend assets
- Skip vite build step in Dockerfile (now just copies dist)
- Large files (.wasm, .onnx) tracked via Git LFS
- This avoids HF Space build failures
Co-Authored-By: Claude <noreply@anthropic.com>
- .dockerignore +2 -2
- .gitignore +2 -0
- Dockerfile +8 -10
- trigo-web/app/dist/assets/__vite-browser-external_path-SE2pKm0_.js +1 -0
- trigo-web/app/dist/assets/__vite-browser-external_url-BKFT46N2.js +1 -0
- trigo-web/app/dist/assets/index-BCjNK5tk.js +0 -0
- trigo-web/app/dist/assets/index-Siwlapuk.css +1 -0
- trigo-web/app/dist/assets/logo-BsvPloX6.png +0 -0
- trigo-web/app/dist/assets/ort-wasm-simd-threaded.jsep-BGTZ4Y7F.wasm +3 -0
- trigo-web/app/dist/index.html +14 -0
- trigo-web/app/dist/lib/tgnParser.cjs +791 -0
- trigo-web/app/dist/onnx/20251130-trigo-value-gpt2-l6-h64-251125-lr2000/.gitignore +1 -0
- trigo-web/app/dist/onnx/20251130-trigo-value-gpt2-l6-h64-251125-lr2000/GPT2CausalLM_ep0042_evaluation.onnx +3 -0
- trigo-web/app/dist/onnx/20251130-trigo-value-gpt2-l6-h64-251125-lr2000/GPT2CausalLM_ep0042_tree-v2.onnx +3 -0
- trigo-web/app/dist/onnx/20251130-trigo-value-gpt2-l6-h64-251125-lr2000/GPT2CausalLM_ep0042_tree.onnx +3 -0
- trigo-web/app/dist/onnx/20251220-trigo-value-llama-l6-h64-251220-value0.02/LlamaCausalLM_ep0036_evaluation.onnx +3 -0
- trigo-web/app/dist/onnx/20251220-trigo-value-llama-l6-h64-251220-value0.02/LlamaCausalLM_ep0036_tree.onnx +3 -0
- trigo-web/app/dist/onnx/20251230-trigo-value-llama-l6-h64-it2_251221-value0.01-pretrain/LlamaCausalLM_ep0036_evaluation.onnx +3 -0
- trigo-web/app/dist/onnx/20251230-trigo-value-llama-l6-h64-it2_251221-value0.01-pretrain/LlamaCausalLM_ep0036_tree.onnx +3 -0
.dockerignore
CHANGED
|
@@ -12,9 +12,9 @@ README.md
|
|
| 12 |
node_modules
|
| 13 |
**/node_modules
|
| 14 |
|
| 15 |
-
# Build outputs (will be generated during build)
|
| 16 |
-
dist
|
| 17 |
**/dist
|
|
|
|
| 18 |
|
| 19 |
# Test files
|
| 20 |
tests
|
|
|
|
| 12 |
node_modules
|
| 13 |
**/node_modules
|
| 14 |
|
| 15 |
+
# Build outputs (will be generated during build) - keep app/dist for pre-built frontend
|
|
|
|
| 16 |
**/dist
|
| 17 |
+
!trigo-web/app/dist
|
| 18 |
|
| 19 |
# Test files
|
| 20 |
tests
|
.gitignore
CHANGED
|
@@ -1,2 +1,4 @@
|
|
| 1 |
node_modules/
|
|
|
|
| 2 |
dist/
|
|
|
|
|
|
| 1 |
node_modules/
|
| 2 |
+
# Don't ignore trigo-web/app/dist - we commit pre-built frontend
|
| 3 |
dist/
|
| 4 |
+
!trigo-web/app/dist/
|
Dockerfile
CHANGED
|
@@ -3,7 +3,7 @@ FROM node:20-slim
|
|
| 3 |
# Set noninteractive installation
|
| 4 |
ENV DEBIAN_FRONTEND=noninteractive
|
| 5 |
|
| 6 |
-
# Build timestamp to force cache invalidation: 2026-01-12T19:
|
| 7 |
|
| 8 |
# Install build dependencies
|
| 9 |
RUN apt-get update && apt-get install -y \
|
|
@@ -14,9 +14,10 @@ RUN apt-get update && apt-get install -y \
|
|
| 14 |
# Create app directory
|
| 15 |
WORKDIR /app
|
| 16 |
|
| 17 |
-
# Copy trigo-web project
|
| 18 |
COPY trigo-web/ ./
|
| 19 |
-
|
|
|
|
| 20 |
RUN rm -rf public/onnx
|
| 21 |
|
| 22 |
# Install build tools globally
|
|
@@ -24,22 +25,19 @@ RUN npm install -g tsx jison typescript esbuild
|
|
| 24 |
|
| 25 |
# Install dependencies
|
| 26 |
# Root: production only (skip onnxruntime-node which requires native compilation)
|
| 27 |
-
# App & Backend: all deps needed for
|
| 28 |
RUN npm install --omit=dev && \
|
| 29 |
-
cd app && npm install && \
|
| 30 |
cd ../backend && npm install && \
|
| 31 |
cd ..
|
| 32 |
|
| 33 |
# Skip jison parser build - pre-built tgnParser.cjs is already in public/lib/
|
| 34 |
-
#
|
| 35 |
-
|
| 36 |
-
# Build frontend (generates dist folder) - use node directly
|
| 37 |
-
RUN cd app && NODE_OPTIONS="--max-old-space-size=4096" node ./node_modules/vite/bin/vite.js build
|
| 38 |
|
| 39 |
# Build backend with esbuild (handles ESM imports without .js extensions)
|
| 40 |
RUN esbuild backend/src/server.ts --bundle --platform=node --target=node20 --format=esm --outfile=backend/dist/server.js --external:express --external:socket.io --external:cors --external:dotenv --external:uuid
|
| 41 |
|
| 42 |
-
# Copy ONNX files to dist (they don't need to be
|
| 43 |
COPY trigo-web/public/onnx/ ./app/dist/onnx/
|
| 44 |
|
| 45 |
# Set environment variables for Hugging Face Spaces
|
|
|
|
| 3 |
# Set noninteractive installation
|
| 4 |
ENV DEBIAN_FRONTEND=noninteractive
|
| 5 |
|
| 6 |
+
# Build timestamp to force cache invalidation: 2026-01-12T19:50
|
| 7 |
|
| 8 |
# Install build dependencies
|
| 9 |
RUN apt-get update && apt-get install -y \
|
|
|
|
| 14 |
# Create app directory
|
| 15 |
WORKDIR /app
|
| 16 |
|
| 17 |
+
# Copy trigo-web project (includes pre-built app/dist)
|
| 18 |
COPY trigo-web/ ./
|
| 19 |
+
|
| 20 |
+
# Remove large ONNX files from public (already in dist)
|
| 21 |
RUN rm -rf public/onnx
|
| 22 |
|
| 23 |
# Install build tools globally
|
|
|
|
| 25 |
|
| 26 |
# Install dependencies
|
| 27 |
# Root: production only (skip onnxruntime-node which requires native compilation)
|
| 28 |
+
# App & Backend: all deps needed for runtime
|
| 29 |
RUN npm install --omit=dev && \
|
| 30 |
+
cd app && npm install --omit=dev && \
|
| 31 |
cd ../backend && npm install && \
|
| 32 |
cd ..
|
| 33 |
|
| 34 |
# Skip jison parser build - pre-built tgnParser.cjs is already in public/lib/
|
| 35 |
+
# Skip vite build - pre-built dist is already included
|
|
|
|
|
|
|
|
|
|
| 36 |
|
| 37 |
# Build backend with esbuild (handles ESM imports without .js extensions)
|
| 38 |
RUN esbuild backend/src/server.ts --bundle --platform=node --target=node20 --format=esm --outfile=backend/dist/server.js --external:express --external:socket.io --external:cors --external:dotenv --external:uuid
|
| 39 |
|
| 40 |
+
# Copy ONNX files to dist (they don't need to be in public anymore)
|
| 41 |
COPY trigo-web/public/onnx/ ./app/dist/onnx/
|
| 42 |
|
| 43 |
# Set environment variables for Hugging Face Spaces
|
trigo-web/app/dist/assets/__vite-browser-external_path-SE2pKm0_.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 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
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 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-BCjNK5tk.js
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
trigo-web/app/dist/assets/index-Siwlapuk.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 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
ADDED
|
trigo-web/app/dist/assets/ort-wasm-simd-threaded.jsep-BGTZ4Y7F.wasm
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:ac0d8f1cfbf2732420ad78a86072b8507253c63885a61c3fd640b3055256d31d
|
| 3 |
+
size 23824254
|
trigo-web/app/dist/index.html
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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-BCjNK5tk.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
ADDED
|
@@ -0,0 +1,791 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
*
|
trigo-web/app/dist/onnx/20251130-trigo-value-gpt2-l6-h64-251125-lr2000/GPT2CausalLM_ep0042_evaluation.onnx
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:258d947a1c40578a0fc6b8a98f16965aacceed74e3c7516c697aa6f9d772bf43
|
| 3 |
+
size 1378983
|