ATlast — you'll never need to find your favorites on another platform again. Find your favs in the ATmosphere.
atproto
16
fork

Configure Feed

Select the types of activity you want to include in your feed.

chore: remove gitignored files from tracking

Remove files that were tracked before being added to .gitignore:
- .github/workflows/ (GitHub Actions)
- docs/ (decision graph exports)
- CLAUDE.md, PLAN.md (project docs)

byarielm.fyi 2c45a574 61cf0db8

verified
-10400
-79
.github/workflows/cleanup-decision-graphs.yml
··· 1 - name: Cleanup Decision Graph PNGs 2 - 3 - on: 4 - pull_request: 5 - types: [closed] 6 - 7 - jobs: 8 - cleanup: 9 - # Only run if PR was merged (not just closed) 10 - if: github.event.pull_request.merged == true 11 - runs-on: ubuntu-latest 12 - 13 - steps: 14 - - name: Checkout 15 - uses: actions/checkout@v4 16 - with: 17 - fetch-depth: 0 18 - token: ${{ secrets.GITHUB_TOKEN }} 19 - 20 - - name: Find and remove decision graph PNGs 21 - id: find-pngs 22 - run: | 23 - # Find decision graph PNGs (in docs/ or root) 24 - PNGS=$(find . -name "decision-graph*.png" -o -name "deciduous-graph*.png" 2>/dev/null | grep -v node_modules || true) 25 - 26 - if [ -z "$PNGS" ]; then 27 - echo "No decision graph PNGs found" 28 - echo "found=false" >> $GITHUB_OUTPUT 29 - else 30 - echo "Found PNGs to clean up:" 31 - echo "$PNGS" 32 - echo "found=true" >> $GITHUB_OUTPUT 33 - 34 - # Remove the files 35 - echo "$PNGS" | xargs rm -f 36 - 37 - # Also remove corresponding .dot files 38 - for png in $PNGS; do 39 - dot_file="${png%.png}.dot" 40 - if [ -f "$dot_file" ]; then 41 - rm -f "$dot_file" 42 - echo "Also removed: $dot_file" 43 - fi 44 - done 45 - fi 46 - 47 - - name: Create cleanup PR 48 - if: steps.find-pngs.outputs.found == 'true' 49 - run: | 50 - # Check if there are changes to commit 51 - if git diff --quiet && git diff --staged --quiet; then 52 - echo "No changes to commit" 53 - exit 0 54 - fi 55 - 56 - # Configure git 57 - git config user.name "github-actions[bot]" 58 - git config user.email "github-actions[bot]@users.noreply.github.com" 59 - 60 - # Create branch and commit 61 - BRANCH="cleanup/decision-graphs-pr-${{ github.event.pull_request.number }}" 62 - git checkout -b "$BRANCH" 63 - git add -A 64 - git commit -m "chore: cleanup decision graph assets from PR #${{ github.event.pull_request.number }}" 65 - git push origin "$BRANCH" 66 - 67 - # Create and auto-merge PR 68 - gh pr create \ 69 - --title "chore: cleanup decision graph assets from PR #${{ github.event.pull_request.number }}" \ 70 - --body "Automated cleanup of decision graph PNG/DOT files that were used in PR #${{ github.event.pull_request.number }}. 71 - 72 - These files served their purpose for PR review and are no longer needed." \ 73 - --head "$BRANCH" \ 74 - --base main 75 - 76 - # Auto-merge (requires auto-merge enabled on repo) 77 - gh pr merge "$BRANCH" --auto --squash --delete-branch || echo "Auto-merge not enabled, PR created for manual merge" 78 - env: 79 - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-25
.github/workflows/deploy-pages.yml
··· 1 - name: Deploy Decision Graph to Pages 2 - 3 - on: 4 - push: 5 - branches: [main] 6 - paths: 7 - - 'docs/**' 8 - workflow_dispatch: 9 - 10 - permissions: 11 - contents: write 12 - 13 - jobs: 14 - deploy: 15 - runs-on: ubuntu-latest 16 - steps: 17 - - uses: actions/checkout@v4 18 - 19 - - name: Deploy to gh-pages branch 20 - uses: peaceiris/actions-gh-pages@v4 21 - with: 22 - github_token: ${{ secrets.GITHUB_TOKEN }} 23 - publish_dir: ./docs 24 - publish_branch: gh-pages 25 - force_orphan: true
-602
CLAUDE.md
··· 1 - # CLAUDE.md 2 - 3 - This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. 4 - 5 - # Project Instructions 6 - 7 - ## Decision Graph Workflow 8 - 9 - **THIS IS MANDATORY. Log decisions IN REAL-TIME, not retroactively.** 10 - 11 - ### The Core Rule 12 - 13 - ``` 14 - BEFORE you do something -> Log what you're ABOUT to do 15 - AFTER it succeeds/fails -> Log the outcome 16 - CONNECT immediately -> Link every node to its parent 17 - AUDIT regularly -> Check for missing connections 18 - ``` 19 - 20 - ### Behavioral Triggers - MUST LOG WHEN: 21 - 22 - | Trigger | Log Type | Example | 23 - |---------|----------|---------| 24 - | User asks for a new feature | `goal` **with -p** | "Add dark mode" | 25 - | Choosing between approaches | `decision` | "Choose state management" | 26 - | About to write/edit code | `action` | "Implementing Redux store" | 27 - | Something worked or failed | `outcome` | "Redux integration successful" | 28 - | Notice something interesting | `observation` | "Existing code uses hooks" | 29 - 30 - ### CRITICAL: Capture VERBATIM User Prompts 31 - 32 - **Prompts must be the EXACT user message, not a summary.** When a user request triggers new work, capture their full message word-for-word. 33 - 34 - **BAD - summaries are useless for context recovery:** 35 - ```bash 36 - # DON'T DO THIS - this is a summary, not a prompt 37 - deciduous add goal "Add auth" -p "User asked: add login to the app" 38 - ``` 39 - 40 - **GOOD - verbatim prompts enable full context recovery:** 41 - ```bash 42 - # Use --prompt-stdin for multi-line prompts 43 - deciduous add goal "Add auth" -c 90 --prompt-stdin << 'EOF' 44 - I need to add user authentication to the app. Users should be able to sign up 45 - with email/password, and we need OAuth support for Google and GitHub. The auth 46 - should use JWT tokens with refresh token rotation. 47 - EOF 48 - 49 - # Or use the prompt command to update existing nodes 50 - deciduous prompt 42 << 'EOF' 51 - The full verbatim user message goes here... 52 - EOF 53 - ``` 54 - 55 - **When to capture prompts:** 56 - - Root `goal` nodes: YES - the FULL original request 57 - - Major direction changes: YES - when user redirects the work 58 - - Routine downstream nodes: NO - they inherit context via edges 59 - 60 - **Updating prompts on existing nodes:** 61 - ```bash 62 - deciduous prompt <node_id> "full verbatim prompt here" 63 - cat prompt.txt | deciduous prompt <node_id> # Multi-line from stdin 64 - ``` 65 - 66 - Prompts are viewable in the TUI detail panel (`deciduous tui`) and web viewer. 67 - 68 - ### ⚠️ CRITICAL: Maintain Connections 69 - 70 - **The graph's value is in its CONNECTIONS, not just nodes.** 71 - 72 - | When you create... | IMMEDIATELY link to... | 73 - |-------------------|------------------------| 74 - | `outcome` | The action/goal it resolves | 75 - | `action` | The goal/decision that spawned it | 76 - | `option` | Its parent decision | 77 - | `observation` | Related goal/action | 78 - 79 - **Root `goal` nodes are the ONLY valid orphans.** 80 - 81 - ### Node Lifecycle Management 82 - 83 - **Every node has a lifecycle. Update status in REAL-TIME:** 84 - 85 - ```bash 86 - # 1. Create node (defaults to 'pending') 87 - deciduous add action "Implementing feature X" -c 85 88 - 89 - # 2. IMMEDIATELY link to parent (before doing anything else) 90 - deciduous link <parent_id> <new_node_id> -r "Reason for connection" 91 - 92 - # 3. Mark as in_progress BEFORE starting work 93 - deciduous status <node_id> in_progress 94 - 95 - # 4. Do the work... 96 - 97 - # 5. Mark as completed IMMEDIATELY after work finishes 98 - deciduous status <node_id> completed 99 - ``` 100 - 101 - **Status Transitions:** 102 - - `pending` → Default state when created 103 - - `in_progress` → Mark BEFORE starting work (only ONE at a time) 104 - - `completed` → Mark IMMEDIATELY when done (proven by git commit, test pass, etc.) 105 - 106 - **CRITICAL RULES:** 107 - - ✅ Link nodes IMMEDIATELY after creation (same command sequence) 108 - - ✅ Update status to `completed` as soon as work is done 109 - - ✅ Only ONE node should be `in_progress` at a time 110 - - ✅ Verify link exists before moving on (check `deciduous edges`) 111 - - ❌ NEVER leave completed work marked as `pending` 112 - - ❌ NEVER create orphan nodes (except root goals) 113 - - ❌ NEVER batch status updates - update immediately 114 - 115 - **Verification Workflow:** 116 - ```bash 117 - # After creating and linking a node, verify: 118 - deciduous edges | grep <new_node_id> # Should show incoming edge 119 - deciduous nodes | grep <new_node_id> # Check status is correct 120 - ``` 121 - 122 - **Common Mistakes That Break the Graph:** 123 - 124 - 1. **Creating nodes without linking** → Orphans 125 - ```bash 126 - # WRONG 127 - deciduous add action "Fix bug" -c 85 128 - # (forget to link, move on to next task) 129 - 130 - # RIGHT 131 - deciduous add action "Fix bug" -c 85 132 - deciduous link 42 43 -r "Action to resolve goal #42" 133 - ``` 134 - 135 - 2. **Leaving nodes as "pending" after work completes** → Stale status 136 - ```bash 137 - # WRONG 138 - git commit -m "fix: bug fixed" 139 - # (forget to update node status) 140 - 141 - # RIGHT 142 - git commit -m "fix: bug fixed" 143 - deciduous status 43 completed 144 - ``` 145 - 146 - 3. **Batch-creating multiple nodes before linking** → Connection gaps 147 - ```bash 148 - # WRONG 149 - deciduous add action "Task 1" -c 85 150 - deciduous add action "Task 2" -c 85 151 - deciduous add action "Task 3" -c 85 152 - # (now have to remember all IDs to link) 153 - 154 - # RIGHT 155 - deciduous add action "Task 1" -c 85 156 - deciduous link 42 43 -r "First task" 157 - deciduous add action "Task 2" -c 85 158 - deciduous link 42 44 -r "Second task" 159 - ``` 160 - 161 - 4. **Not regenerating parent list during orphan checks** → False positives 162 - ```bash 163 - # WRONG 164 - # (generate parent list once) 165 - deciduous link X Y -r "fix orphan" 166 - # (check orphans with stale parent list) 167 - 168 - # RIGHT 169 - deciduous link X Y -r "fix orphan" 170 - # Regenerate parent list before checking again 171 - deciduous edges | tail -n+3 | awk '{print $3}' | sort -u > /tmp/has_parent.txt 172 - ``` 173 - 174 - ### Quick Commands 175 - 176 - ```bash 177 - deciduous add goal "Title" -c 90 -p "User's original request" 178 - deciduous add action "Title" -c 85 179 - deciduous link FROM TO -r "reason" # DO THIS IMMEDIATELY! 180 - deciduous serve # View live (auto-refreshes every 30s) 181 - deciduous sync # Export for static hosting 182 - 183 - # Metadata flags 184 - # -c, --confidence 0-100 Confidence level 185 - # -p, --prompt "..." Store the user prompt (use when semantically meaningful) 186 - # -f, --files "a.rs,b.rs" Associate files 187 - # -b, --branch <name> Git branch (auto-detected) 188 - # --commit <hash|HEAD> Link to git commit (use HEAD for current commit) 189 - 190 - # Branch filtering 191 - deciduous nodes --branch main 192 - deciduous nodes -b feature-auth 193 - ``` 194 - 195 - ### ⚠️ CRITICAL: Link Commits to Actions/Outcomes 196 - 197 - **After every git commit, link it to the decision graph!** 198 - 199 - ```bash 200 - git commit -m "feat: add auth" 201 - deciduous add action "Implemented auth" -c 90 --commit HEAD 202 - deciduous link <goal_id> <action_id> -r "Implementation" 203 - ``` 204 - 205 - The `--commit HEAD` flag captures the commit hash and links it to the node. The web viewer will show commit messages, authors, and dates. 206 - 207 - ### Git Commit Message Format 208 - 209 - **Keep commit messages clean and concise:** 210 - - NO "Generated with Claude Code" or similar by-lines 211 - - NO "Co-Authored-By:" lines 212 - - NO "Files updated:" sections or file lists 213 - - Use concise summary line describing the change 214 - - Add additional details if needed, but keep it focused 215 - 216 - **CRITICAL: Commit separate concerns separately** 217 - - Each commit should address ONE specific fix or feature 218 - - DO NOT bundle multiple unrelated changes into a single commit 219 - - If fixing multiple bugs, create separate commits for each bug fix 220 - - Example: Login typeahead fix, card spacing fix, and toast refactor = 3 commits 221 - 222 - **Example:** 223 - ```bash 224 - git commit -m "remove deprecated 'followed' field and cleanup codebase 225 - 226 - Removed backward compatibility code for deprecated 'followed' field: 227 - - Removed from AtprotoMatch type 228 - - Updated 6 files to use only followStatus Record 229 - - Replaced simple boolean check with multi-lexicon support 230 - - Database schema preserved (no migration needed) 231 - 232 - Also removed empty 'nul' file created accidentally." 233 - ``` 234 - 235 - ### Git History & Deployment 236 - 237 - **CRITICAL: Include decision graph in code commits** 238 - 239 - Always run `deciduous sync` BEFORE committing code changes, then include the graph updates in the same commit: 240 - 241 - ```bash 242 - # After making code changes and adding decision nodes: 243 - deciduous sync # Export graph 244 - git add src/your-file.ts docs/ # Stage code + graph 245 - git commit -m "your change" # Single commit with both 246 - ``` 247 - 248 - **DO NOT create separate commits for graph updates.** The decision graph is part of the code history and should be committed together. 249 - 250 - ```bash 251 - # Export graph AND git history for web viewer 252 - deciduous sync 253 - 254 - # This creates: 255 - # - docs/graph-data.json (decision graph) 256 - # - docs/git-history.json (commit info for linked nodes) 257 - ``` 258 - 259 - To deploy to GitHub Pages: 260 - 1. `deciduous sync` to export 261 - 2. Push to GitHub 262 - 3. Settings > Pages > Deploy from branch > /docs folder 263 - 264 - Your graph will be live at `https://<user>.github.io/<repo>/` 265 - 266 - ### Branch-Based Grouping 267 - 268 - Nodes are auto-tagged with the current git branch. Configure in `.deciduous/config.toml`: 269 - ```toml 270 - [branch] 271 - main_branches = ["main", "master"] 272 - auto_detect = true 273 - ``` 274 - 275 - ### Audit Checklist (Before Every Sync) 276 - 277 - Run these checks before `deciduous sync`: 278 - 279 - 1. **Connection integrity**: Does every non-goal node have a parent? 280 - ```bash 281 - deciduous edges | tail -n+3 | awk '{print $3}' | sort -u > /tmp/has_parent.txt 282 - deciduous nodes | tail -n+3 | awk '{print $1}' > /tmp/all_nodes.txt 283 - while read id; do grep -q "^$id$" /tmp/has_parent.txt || echo "CHECK: $id"; done < /tmp/all_nodes.txt 284 - # Only root goals should appear 285 - ``` 286 - 287 - 2. **Status accuracy**: Are completed nodes marked `completed`? 288 - ```bash 289 - deciduous nodes | grep pending 290 - # Review: is this work actually still pending, or is it done? 291 - ``` 292 - 293 - 3. **Active work**: Is there exactly ONE `in_progress` node? 294 - ```bash 295 - deciduous nodes | grep in_progress 296 - # Should see 0-1 nodes, not multiple 297 - ``` 298 - 299 - 4. **Logical flow**: Does every outcome link back to what caused it? 300 - - `outcome` → `action` or `goal` 301 - - `action` → `goal` or `decision` 302 - - `observation` → related `goal` or `action` 303 - 304 - ### Session Start Checklist 305 - 306 - ```bash 307 - deciduous nodes # What decisions exist? 308 - deciduous edges # How are they connected? Any gaps? 309 - git status # Current state 310 - ``` 311 - 312 - ### Multi-User Sync 313 - 314 - Share decisions across teammates: 315 - 316 - ```bash 317 - # Export your branch's decisions 318 - deciduous diff export --branch feature-x -o .deciduous/patches/my-feature.json 319 - 320 - # Apply patches from teammates (idempotent) 321 - deciduous diff apply .deciduous/patches/*.json 322 - 323 - # Preview before applying 324 - deciduous diff apply --dry-run .deciduous/patches/teammate.json 325 - ``` 326 - 327 - PR workflow: Export patch → commit patch file → PR → teammates apply. 328 - 329 - ### API Trace Capture 330 - 331 - Capture Claude API traffic to correlate decisions with actual API work: 332 - 333 - ```bash 334 - # Run Claude through the deciduous proxy 335 - deciduous proxy -- claude 336 - 337 - # View traces in TUI (press 't' for Trace view) 338 - deciduous tui 339 - 340 - # View traces in web viewer (click "Traces" tab) 341 - deciduous serve 342 - ``` 343 - 344 - **Auto-linking**: When running through `deciduous proxy`, any `deciduous add` commands automatically link to the active API span. You'll see output like: 345 - 346 - ``` 347 - Created action #42 "Implementing auth" [traced: span #7] 348 - ``` 349 - 350 - This lets you see exactly which API calls produced which decisions - perfect for "vibe coding" visibility. 351 - 352 - **Trace commands:** 353 - ```bash 354 - deciduous trace sessions # List all sessions 355 - deciduous trace spans <session_id> # List spans in a session 356 - deciduous trace link <session_id> <node_id> # Manual linking 357 - deciduous trace prune --days 30 # Cleanup old traces 358 - ``` 359 - 360 - ## Project Overview 361 - 362 - ATlast is a web application that helps users find their followed accounts from other social platforms (TikTok, Instagram, Twitter/X) on Bluesky/AT Protocol. Users upload their data export files, which are parsed for usernames, then searched in the AT Protocol network. 363 - 364 - ## Development Commands 365 - 366 - ### Monorepo Structure 367 - 368 - This project uses pnpm workspaces with three packages: 369 - - `packages/web` - React frontend 370 - - `packages/functions` - Netlify serverless functions 371 - - `packages/shared` - Shared TypeScript types 372 - 373 - ### Local Development 374 - 375 - **IMPORTANT**: Due to Netlify CLI monorepo detection, you must use the `--filter` flag: 376 - 377 - ```bash 378 - # Mock mode (frontend only, no backend/OAuth/database) 379 - pnpm run dev:mock 380 - 381 - # Full mode (with backend, OAuth, database) - RECOMMENDED 382 - npx netlify-cli dev --filter @atlast/web 383 - 384 - # Alternative: Update root package.json scripts to use npx netlify-cli 385 - pnpm run dev # If scripts are updated 386 - 387 - # Build for production 388 - pnpm run build 389 - 390 - # Initialize local database 391 - pnpm run init-db 392 - 393 - # Generate encryption keys for OAuth 394 - pnpm run generate-key 395 - ``` 396 - 397 - **Note**: On Windows, `netlify` command may not work in Git Bash. Use `npx netlify-cli` instead, or run from Windows CMD/PowerShell. 398 - 399 - ### Environment Configuration 400 - 401 - Two development modes supported: 402 - 403 - **Mock Mode** (.env.mock): 404 - - Set `VITE_LOCAL_MOCK=true` 405 - - No database or OAuth required 406 - - Uses MockApiAdapter for fake data 407 - 408 - **Full Mode** (.env): 409 - - Set `VITE_LOCAL_MOCK=false` 410 - - Requires PostgreSQL (local or Neon) 411 - - Requires OAuth keys and configuration 412 - - Must use `http://127.0.0.1:8888` (NOT localhost) for OAuth to work 413 - - See CONTRIBUTING.md for detailed setup 414 - 415 - ## Architecture Overview 416 - 417 - ### Frontend (React + TypeScript + Vite) 418 - 419 - **Core Structure:** 420 - - `src/pages/` - Page components (Login, Upload, Results, etc.) 421 - - `src/components/` - Reusable UI components 422 - - `src/lib/parsers/` - File parsing logic for different platforms 423 - - `src/lib/api/` - API client with adapter pattern (Real vs Mock) 424 - - `src/contexts/` - React contexts (SettingsContext for theme/preferences) 425 - - `src/hooks/` - Custom React hooks 426 - 427 - **API Client Pattern:** 428 - The app uses an adapter pattern for the API layer: 429 - - `src/lib/api/client.ts` - Factory that returns Real or Mock adapter based on ENV.IS_LOCAL_MOCK 430 - - `src/lib/api/adapters/RealApiAdapter.ts` - Calls Netlify Functions 431 - - `src/lib/api/adapters/MockApiAdapter.ts` - Returns fake data for frontend development 432 - - `src/lib/api/IApiClient.ts` - Interface both adapters implement 433 - 434 - **Platform Parsers:** 435 - - `src/lib/parsers/platformDefinitions.ts` - Defines parsing rules for each platform (Instagram, TikTok, etc.) 436 - - `src/lib/parsers/fileExtractor.ts` - Handles ZIP file uploads and extracts usernames 437 - - `src/lib/parsers/parserLogic.ts` - Implements extraction logic (HTML regex, JSON path traversal, TEXT regex) 438 - 439 - Each platform has multiple ParseRule entries defining: 440 - - `zipPath` - Location inside ZIP archive 441 - - `format` - "HTML" | "TEXT" | "JSON" 442 - - `rule` - Regex pattern string or JSON key path array 443 - 444 - ### Backend (Netlify Functions) 445 - 446 - **Function Structure:** 447 - ``` 448 - netlify/functions/ 449 - ├── core/ 450 - │ ├── middleware/ # Auth, error handling, session security 451 - │ ├── types/ # Shared types 452 - │ ├── errors/ # Custom error classes 453 - │ └── config/ # Configuration 454 - ├── infrastructure/ 455 - │ ├── oauth/ # OAuth client factory, stores 456 - │ ├── database/ # Database connection, service layer 457 - │ ├── cache/ # Caching utilities 458 - │ └── lexicons/ # AT Protocol lexicons 459 - ├── services/ # Business logic (SessionService, FollowService, etc.) 460 - ├── repositories/ # Data access layer 461 - └── utils/ # Shared utilities 462 - ``` 463 - 464 - **Key Functions:** 465 - - `oauth-start.ts` / `oauth-callback.ts` - AT Protocol OAuth flow 466 - - `session.ts` - Session management and validation 467 - - `batch-search-actors.ts` - Searches multiple usernames on Bluesky (includes ranking algorithm) 468 - - `check-follow-status.ts` - Checks if user follows specific DIDs 469 - - `batch-follow-users.ts` - Bulk follow operations 470 - - `save-results.ts` - Persists search results to database 471 - - `get-uploads.ts` - Retrieves user's upload history 472 - 473 - **Authentication Pattern:** 474 - All protected endpoints use: 475 - 1. `withAuthErrorHandling()` middleware wrapper 476 - 2. `AuthenticatedHandler` type (provides `context.sessionId`, `context.did`, `context.event`) 477 - 3. `SessionService.getAgentForSession()` to get authenticated AT Protocol agent 478 - 479 - **Database:** 480 - - PostgreSQL via Neon serverless 481 - - Accessed through `DatabaseService` (infrastructure/database/) 482 - - Repositories pattern for data access (repositories/) 483 - 484 - **OAuth:** 485 - - AT Protocol OAuth using `@atproto/oauth-client-node` 486 - - OAuth client factory creates client with session/state stores 487 - - Private key (ES256) stored in `OAUTH_PRIVATE_KEY` env var 488 - - Public JWK served at `/jwks` endpoint 489 - - Must use `127.0.0.1` (not localhost) for local OAuth redirects 490 - 491 - ### UI/Styling 492 - 493 - **Tailwind CSS with dual theme support:** 494 - - Light mode: purple/cyan color scheme 495 - - Dark mode: cyan/purple inverted 496 - - All components use `dark:` variant classes 497 - 498 - **Color System (from CONTRIBUTING.md):** 499 - - Text: purple-950/cyan-50 (primary), purple-750/cyan-250 (secondary) 500 - - Borders: cyan-500/purple-500 with opacity variants 501 - - Buttons: orange-600 (primary CTA), slate-600/700 (secondary) 502 - - Backgrounds: white/slate-900 (primary), purple-50/slate-900 (secondary) 503 - - Selected states: cyan-50 border-cyan-500 / purple-950/30 border-purple-500 504 - - Accents: orange-500/amber-500 (badges, progress) 505 - 506 - **Key Patterns:** 507 - - Mobile-first responsive design 508 - - List virtualization with `@tanstack/react-virtual` for large result sets 509 - - Code splitting and lazy loading for pages 510 - - Error boundaries throughout the app 511 - - Loading skeletons for async operations 512 - 513 - ### Search & Matching Algorithm 514 - 515 - **Username Matching (batch-search-actors.ts):** 516 - The search uses a scoring system (0-100): 517 - 1. Exact handle match (before first dot): 100 518 - 2. Exact full handle match: 90 519 - 3. Exact display name match: 80 520 - 4. Partial handle match (contains): 60 521 - 5. Partial full handle match: 50 522 - 6. Partial display name match: 40 523 - 7. Reverse partial match: 30 524 - 525 - All comparisons use normalized strings (lowercase, no special chars). 526 - Returns top 5 ranked results per username. 527 - 528 - **Result Enrichment:** 529 - - Fetches profiles in batches of 25 for post/follower counts 530 - - Checks follow status using custom lexicons (default: `app.bsky.graph.follow`) 531 - - Attaches follow status to each actor result 532 - 533 - ## Key Technical Details 534 - 535 - ### AT Protocol Integration 536 - - Uses `@atproto/api` for Bluesky API interactions 537 - - Uses `@atcute/identity-resolver` for DID resolution 538 - - Supports custom lexicons for experimental features 539 - - OAuth flow follows AT Protocol OAuth spec 540 - 541 - ### File Upload Flow 542 - 1. User uploads ZIP file (Instagram/TikTok data export) 543 - 2. `fileExtractor.ts` reads ZIP in browser (using JSZip) 544 - 3. Matches file paths to platform rules from `platformDefinitions.ts` 545 - 4. `parserLogic.ts` extracts usernames (regex for HTML/TEXT, path traversal for JSON) 546 - 5. Deduplicates and returns username list 547 - 6. Frontend calls `/batch-search-actors` with username batches (max 50) 548 - 7. Results stored in database via `/save-results` 549 - 550 - ### Session Management 551 - - Session IDs stored in httpOnly cookies 552 - - Sessions linked to encrypted OAuth state stores 553 - - Session validation middleware checks database and expiry 554 - - Sessions tied to specific DIDs (user accounts) 555 - 556 - ### Deployment 557 - - Hosted on Netlify 558 - - Static frontend built with Vite 559 - - Serverless functions for backend 560 - - Database on Neon (PostgreSQL) 561 - - OAuth redirects configured in netlify.toml 562 - 563 - ## Adding New Features 564 - 565 - ### Adding a New Social Platform 566 - 1. Add parsing rules to `src/lib/parsers/platformDefinitions.ts`: 567 - ```typescript 568 - export const PLATFORM_RULES: Record<string, ParseRule[]> = { 569 - newplatform: [ 570 - { 571 - zipPath: "path/in/zip/file.json", 572 - format: "JSON", 573 - rule: ["key", "path", "to", "username"], 574 - }, 575 - ], 576 - }; 577 - ``` 578 - 2. Test with real data export from that platform 579 - 3. Update UI in platform selection components 580 - 581 - ### Adding a New API Endpoint 582 - 1. Create function in `netlify/functions/your-endpoint.ts` 583 - 2. Use `withAuthErrorHandling()` for protected endpoints 584 - 3. Implement `AuthenticatedHandler` type 585 - 4. Add method to `IApiClient.ts` interface 586 - 5. Implement in both `RealApiAdapter.ts` and `MockApiAdapter.ts` 587 - 6. Use via `apiClient.yourMethod()` in components 588 - 589 - ### Adding Database Models 590 - 1. Create migration script in `scripts/` 591 - 2. Run against local database 592 - 3. Update repository in `netlify/functions/repositories/` 593 - 4. Update DatabaseService if needed 594 - 595 - ## Important Notes 596 - 597 - - **OAuth Localhost Issue**: Must use `127.0.0.1:8888` not `localhost:8888` for local OAuth to work 598 - - **Batch Limits**: Search endpoint limited to 50 usernames per request 599 - - **Profile Fetching**: Batched in groups of 25 to avoid rate limits 600 - - **Normalization**: All username comparisons use lowercase + special char removal 601 - - **Security**: CSP headers configured in netlify.toml, session security middleware prevents CSRF 602 - - **Error Handling**: Custom error classes (ValidationError, AuthenticationError, etc.) with proper HTTP status codes
-640
PLAN.md
··· 1 - # ATlast Twitter/X Support Plan 2 - 3 - ## Current Status (2025-12-27) 4 - 5 - **Phase 1 Status:** ✅ COMPLETE - Ready for production testing and Chrome Web Store submission 6 - 7 - **All Completed (Dec 2024 - Jan 2025):** 8 - - ✅ Environment configuration (dev/prod builds with correct API URLs) 9 - - ✅ Server health check and offline state handling 10 - - ✅ Authentication flow (session check before upload) 11 - - ✅ Removed temporary storage approach (extension_imports table) 12 - - ✅ Refactored to require login first (matches file upload flow) 13 - - ✅ Fixed NaN database error (missing matchedUsers parameter) 14 - - ✅ Database initialized for dev environment 15 - - ✅ Fixed API response unwrapping (uploadToATlast and checkSession) 16 - - ✅ Loading screen during extension upload search 17 - - ✅ Timezone fixes with TIMESTAMPTZ 18 - - ✅ Vite dev server optimization 19 - - ✅ Decision graph integrity fixes (18 orphan nodes resolved) 20 - - ✅ Documentation improvements (CLAUDE.md with lifecycle management) 21 - 22 - **Ready For:** 23 - - Production testing 24 - - Chrome Web Store submission 25 - - Firefox Add-ons development 26 - 27 - **Decision Graph:** 332 nodes, 333 edges - [View live graph](https://notactuallytreyanastasio.github.io/deciduous/) 28 - 29 - --- 30 - 31 - ## Problem Statement 32 - 33 - Twitter/X data exports only contain `user_id` values, not usernames. Example: 34 - ``` 35 - https://twitter.com/intent/user?user_id=1103954565026775041 36 - ``` 37 - 38 - This makes data export files unusable for our existing parser-based workflow. We need a live scraping approach to extract usernames from the user's Following page. 39 - 40 - ## Research Findings 41 - 42 - ### Why Data Export Doesn't Work 43 - - Twitter exports contain only numeric `user_id` in URLs 44 - - Resolving `user_id` → `screen_name` requires API access ($42k/year Enterprise tier) or scraping 45 - - Nitter is dead (Feb 2024) - Twitter killed guest accounts 46 - - Third-party ID lookup tools don't support bulk/API access 47 - 48 - ### Live Scraping Approach 49 - Users are typically logged into Twitter. We can scrape usernames directly from the DOM of `x.com/following` using stable selectors: 50 - - `[data-testid="UserName"]` - stable, recommended 51 - - CSS class selectors - volatile, change frequently 52 - 53 - ### Platform Support Matrix 54 - 55 - | Platform | Extension Support | Bookmarklet JS | Solution | 56 - |----------|------------------|----------------|----------| 57 - | Desktop Chrome/Edge | Full | Yes | WebExtension | 58 - | Desktop Firefox | Full | Yes | WebExtension | 59 - | Desktop Safari | Full | Yes | WebExtension | 60 - | Android Firefox | Full | Yes | WebExtension | 61 - | Android Chrome | None | Via address bar | Recommend Firefox | 62 - | iOS Safari | Via App Store app | Blocked since iOS 15 | Safari Web Extension | 63 - 64 - ### iOS-Specific Findings 65 - 66 - **iOS Shortcuts "Run JavaScript on Webpage":** 67 - - CAN access authenticated Safari session via Share Sheet 68 - - BUT has strict timeout (few seconds) 69 - - Infinite scroll would timeout immediately 70 - - Only viable for grabbing currently visible content 71 - 72 - **iOS Safari Web Extensions (iOS 15+):** 73 - - Uses same WebExtensions API as Chrome/Firefox 74 - - Content scripts run without timeout limits 75 - - REQUIRES App Store distribution as part of iOS app 76 - - Full capability: auto-scroll, scrape, upload 77 - 78 - ## Architecture Decisions 79 - 80 - ### Monorepo Structure (pnpm workspaces) 81 - 82 - ``` 83 - ATlast/ 84 - ├── pnpm-workspace.yaml 85 - ├── package.json # Root workspace config 86 - ├── packages/ 87 - │ ├── web/ # Existing web app (moved from src/) 88 - │ │ ├── src/ 89 - │ │ ├── package.json 90 - │ │ └── vite.config.ts 91 - │ ├── extension/ # ATlast Importer browser extension 92 - │ │ ├── src/ 93 - │ │ ├── manifest.json 94 - │ │ ├── package.json 95 - │ │ └── build.config.ts 96 - │ ├── shared/ # Shared types and utilities 97 - │ │ ├── src/ 98 - │ │ │ ├── types/ 99 - │ │ │ │ ├── platform.ts # Platform enum, configs 100 - │ │ │ │ ├── import.ts # Import request/response types 101 - │ │ │ │ └── index.ts 102 - │ │ │ └── utils/ 103 - │ │ │ └── username.ts # Username normalization 104 - │ │ └── package.json 105 - │ └── functions/ # Netlify functions (moved from netlify/) 106 - │ ├── src/ 107 - │ ├── package.json 108 - │ └── tsconfig.json 109 - ├── netlify.toml 110 - └── docs/ # Decision graph output 111 - ``` 112 - 113 - ### Extension Name 114 - **ATlast Importer** - Clear purpose, searchable in extension stores. 115 - 116 - ### WebExtension Targets 117 - - Chrome/Edge (Manifest V3) 118 - - Firefox (Manifest V2/V3) 119 - - Safari (desktop + iOS via App Store wrapper) - deferred 120 - 121 - --- 122 - 123 - ## Extension Architecture 124 - 125 - ### High-Level Flow 126 - 127 - ``` 128 - ┌─────────────────────────────────────────────────────────────────┐ 129 - │ ATlast Browser Extension │ 130 - ├─────────────────────────────────────────────────────────────────┤ 131 - │ │ 132 - │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ 133 - │ │ Popup UI │ │ Content │ │ Background │ │ 134 - │ │ │◄──►│ Script │◄──►│ Service │ │ 135 - │ │ - Status │ │ │ │ Worker │ │ 136 - │ │ - Progress │ │ - Scrape │ │ │ │ 137 - │ │ - Actions │ │ - Scroll │ │ - Storage │ │ 138 - │ └──────────────┘ │ - Collect │ │ - Messaging │ │ 139 - │ └──────────────┘ └──────────────┘ │ 140 - │ │ 141 - └─────────────────────────────────────────────────────────────────┘ 142 - 143 - 144 - ┌──────────────────┐ 145 - │ ATlast Web App │ 146 - │ │ 147 - │ - Receive data │ 148 - │ - Search Bsky │ 149 - │ - Show matches │ 150 - └──────────────────┘ 151 - ``` 152 - 153 - ### Component Breakdown 154 - 155 - #### 1. Manifest Configuration 156 - ``` 157 - extension/ 158 - ├── manifest.json # Extension manifest (V3 for Chrome, V2 for Firefox) 159 - ├── manifest.firefox.json # Firefox-specific overrides (if needed) 160 - └── manifest.safari.json # Safari-specific overrides (if needed) 161 - ``` 162 - 163 - #### 2. Content Script (`content.js`) 164 - Injected into `x.com` / `twitter.com` pages. 165 - 166 - **Responsibilities:** 167 - - Detect if on Following/Followers page 168 - - Auto-scroll to load all users 169 - - Extract usernames using `[data-testid="UserName"]` 170 - - Report progress to popup/background 171 - - Handle rate limiting and pagination 172 - 173 - **Scraping Logic (pseudo-code):** 174 - ```javascript 175 - async function scrapeFollowing() { 176 - const usernames = new Set(); 177 - let lastCount = 0; 178 - let stableCount = 0; 179 - 180 - while (stableCount < 3) { // Stop after 3 scrolls with no new users 181 - // Collect visible usernames 182 - document.querySelectorAll('[data-testid="UserName"]').forEach(el => { 183 - const username = extractUsername(el); 184 - if (username) usernames.add(username); 185 - }); 186 - 187 - // Report progress 188 - sendProgress(usernames.size); 189 - 190 - // Scroll down 191 - window.scrollBy(0, 1000); 192 - await sleep(500); 193 - 194 - // Check if we found new users 195 - if (usernames.size === lastCount) { 196 - stableCount++; 197 - } else { 198 - stableCount = 0; 199 - lastCount = usernames.size; 200 - } 201 - } 202 - 203 - return Array.from(usernames); 204 - } 205 - ``` 206 - 207 - #### 3. Popup UI (`popup.html`, `popup.js`) 208 - User interface when clicking extension icon. 209 - 210 - **States:** 211 - - **Inactive**: "Go to x.com/following to start" 212 - - **Ready**: "Found Following page. Click to scan." 213 - - **Scanning**: Progress bar, count of found users 214 - - **Complete**: "Found 847 users. Open in ATlast" 215 - - **Error**: Error message with retry option 216 - 217 - #### 4. Background Service Worker (`background.js`) 218 - Coordinates between content script and popup. 219 - 220 - **Responsibilities:** 221 - - Store scraped data temporarily 222 - - Handle cross-tab communication 223 - - Manage extension state 224 - - Generate handoff URL/data for ATlast 225 - 226 - ### Data Handoff to ATlast 227 - 228 - **Decision: POST to API endpoint** 229 - 230 - Extension will POST scraped usernames to a new Netlify function endpoint. 231 - 232 - ``` 233 - ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ 234 - │ Extension │ POST │ Netlify Func │ Store │ Database │ 235 - │ │────────►│ /extension- │────────►│ │ 236 - │ usernames[] │ │ import │ │ pending_import │ 237 - │ platform: "x" │ │ │ │ │ 238 - └─────────────────┘ └────────┬────────┘ └─────────────────┘ 239 - 240 - │ Returns: { importId: "abc123" } 241 - 242 - ┌─────────────────┐ 243 - │ Redirect to │ 244 - │ atlast.app/ │ 245 - │ import/abc123 │ 246 - └─────────────────┘ 247 - ``` 248 - 249 - **API Endpoint: `POST /extension-import`** 250 - 251 - Request: 252 - ```json 253 - { 254 - "platform": "twitter", 255 - "usernames": ["user1", "user2", ...], 256 - "metadata": { 257 - "extensionVersion": "1.0.0", 258 - "scrapedAt": "2024-01-15T...", 259 - "pageType": "following" 260 - } 261 - } 262 - ``` 263 - 264 - Response: 265 - ```json 266 - { 267 - "importId": "abc123", 268 - "redirectUrl": "https://atlast.app/import/abc123" 269 - } 270 - ``` 271 - 272 - **Why POST over other options:** 273 - - No URL length limits (supports 10k+ usernames) 274 - - Secure (HTTPS, can add rate limiting) 275 - - Seamless UX (extension opens ATlast directly) 276 - - Audit trail (imports stored in database) 277 - 278 - ### Extension Package Structure (`packages/extension/`) 279 - 280 - ``` 281 - packages/extension/ 282 - ├── manifest.json # Base manifest (Chrome MV3) 283 - ├── manifest.firefox.json # Firefox overrides (if needed) 284 - ├── package.json # Extension package config 285 - ├── tsconfig.json 286 - ├── build.config.ts # Build script config 287 - ├── src/ 288 - │ ├── content/ 289 - │ │ ├── scrapers/ 290 - │ │ │ ├── base-scraper.ts # Abstract base class 291 - │ │ │ ├── twitter-scraper.ts # Twitter/X implementation 292 - │ │ │ ├── threads-scraper.ts # (Future) Threads 293 - │ │ │ ├── instagram-scraper.ts # (Future) Instagram 294 - │ │ │ └── tiktok-scraper.ts # (Future) TikTok 295 - │ │ ├── scroll-handler.ts # Generic infinite scroll 296 - │ │ └── index.ts # Content script entry, platform detection 297 - │ ├── popup/ 298 - │ │ ├── popup.html 299 - │ │ ├── popup.css 300 - │ │ └── popup.ts 301 - │ ├── background/ 302 - │ │ └── service-worker.ts 303 - │ └── lib/ 304 - │ ├── messaging.ts # Extension messaging 305 - │ ├── storage.ts # chrome.storage wrapper 306 - │ └── api-client.ts # POST to ATlast API 307 - ├── assets/ 308 - │ ├── icon-16.png 309 - │ ├── icon-48.png 310 - │ └── icon-128.png 311 - └── dist/ 312 - ├── chrome/ # Built extension for Chrome 313 - ├── firefox/ # Built extension for Firefox 314 - └── chrome.zip # Store submission package 315 - ``` 316 - 317 - ### Shared Package Structure (`packages/shared/`) 318 - 319 - ``` 320 - packages/shared/ 321 - ├── package.json 322 - ├── tsconfig.json 323 - ├── src/ 324 - │ ├── types/ 325 - │ │ ├── platform.ts # Platform enum, URL patterns 326 - │ │ ├── import.ts # ExtensionImportRequest, ExtensionImportResponse 327 - │ │ ├── scraper.ts # ScraperResult, ScraperProgress 328 - │ │ └── index.ts # Re-exports 329 - │ ├── utils/ 330 - │ │ ├── username.ts # normalizeUsername(), validateUsername() 331 - │ │ └── index.ts 332 - │ └── index.ts # Main entry 333 - └── dist/ # Compiled output 334 - ``` 335 - 336 - ### Shared Types Example 337 - 338 - ```typescript 339 - // packages/shared/src/types/platform.ts 340 - export enum Platform { 341 - Twitter = 'twitter', 342 - Threads = 'threads', 343 - Instagram = 'instagram', 344 - TikTok = 'tiktok', 345 - } 346 - 347 - export interface PlatformConfig { 348 - platform: Platform; 349 - displayName: string; 350 - hostPatterns: string[]; 351 - followingPathPattern: RegExp; 352 - iconUrl: string; 353 - } 354 - 355 - export const PLATFORM_CONFIGS: Record<Platform, PlatformConfig> = { 356 - [Platform.Twitter]: { 357 - platform: Platform.Twitter, 358 - displayName: 'Twitter/X', 359 - hostPatterns: ['twitter.com', 'x.com'], 360 - followingPathPattern: /^\/[^/]+\/following$/, 361 - iconUrl: 'https://abs.twimg.com/favicons/twitter.ico', 362 - }, 363 - // ... future platforms 364 - }; 365 - ``` 366 - 367 - ```typescript 368 - // packages/shared/src/types/import.ts 369 - import { Platform } from './platform'; 370 - 371 - export interface ExtensionImportRequest { 372 - platform: Platform; 373 - usernames: string[]; 374 - metadata: { 375 - extensionVersion: string; 376 - scrapedAt: string; 377 - pageType: 'following' | 'followers' | 'list'; 378 - sourceUrl: string; 379 - }; 380 - } 381 - 382 - export interface ExtensionImportResponse { 383 - importId: string; 384 - usernameCount: number; 385 - redirectUrl: string; 386 - } 387 - ``` 388 - 389 - ### Platform Detection & Extensibility 390 - 391 - Content script detects platform from URL and loads appropriate scraper: 392 - 393 - ```javascript 394 - // src/content/index.js 395 - const PLATFORM_PATTERNS = { 396 - twitter: { 397 - hostPatterns: ['twitter.com', 'x.com'], 398 - followingPath: /^\/[^/]+\/following$/, 399 - scraper: () => import('./scrapers/twitter-scraper.js') 400 - }, 401 - threads: { 402 - hostPatterns: ['threads.net'], 403 - followingPath: /^\/[^/]+\/following$/, 404 - scraper: () => import('./scrapers/threads-scraper.js') 405 - }, 406 - // ... future platforms 407 - }; 408 - 409 - function detectPlatform() { 410 - const host = window.location.hostname; 411 - const path = window.location.pathname; 412 - 413 - for (const [name, config] of Object.entries(PLATFORM_PATTERNS)) { 414 - if (config.hostPatterns.some(h => host.includes(h))) { 415 - if (config.followingPath.test(path)) { 416 - return { platform: name, pageType: 'following', ...config }; 417 - } 418 - } 419 - } 420 - return null; 421 - } 422 - ``` 423 - 424 - ### Base Scraper Interface 425 - 426 - ```javascript 427 - // src/content/scrapers/base-scraper.js 428 - export class BaseScraper { 429 - constructor(options = {}) { 430 - this.onProgress = options.onProgress || (() => {}); 431 - this.onComplete = options.onComplete || (() => {}); 432 - this.onError = options.onError || (() => {}); 433 - } 434 - 435 - // Must be implemented by subclasses 436 - getUsernameSelector() { throw new Error('Not implemented'); } 437 - extractUsername(element) { throw new Error('Not implemented'); } 438 - 439 - // Shared infinite scroll logic 440 - async scrape() { 441 - const usernames = new Set(); 442 - let stableCount = 0; 443 - 444 - while (stableCount < 3) { 445 - const before = usernames.size; 446 - 447 - document.querySelectorAll(this.getUsernameSelector()).forEach(el => { 448 - const username = this.extractUsername(el); 449 - if (username) usernames.add(username); 450 - }); 451 - 452 - this.onProgress({ count: usernames.size }); 453 - 454 - window.scrollBy(0, 1000); 455 - await this.sleep(500); 456 - 457 - stableCount = (usernames.size === before) ? stableCount + 1 : 0; 458 - } 459 - 460 - this.onComplete({ usernames: Array.from(usernames) }); 461 - return Array.from(usernames); 462 - } 463 - 464 - sleep(ms) { 465 - return new Promise(resolve => setTimeout(resolve, ms)); 466 - } 467 - } 468 - ``` 469 - 470 - ### Twitter Scraper Implementation 471 - 472 - ```javascript 473 - // src/content/scrapers/twitter-scraper.js 474 - import { BaseScraper } from './base-scraper.js'; 475 - 476 - export class TwitterScraper extends BaseScraper { 477 - getUsernameSelector() { 478 - // Primary selector (stable) 479 - return '[data-testid="UserName"]'; 480 - } 481 - 482 - extractUsername(element) { 483 - // UserName element contains display name and @handle 484 - // Structure: <div><span>Display Name</span></div><div><span>@handle</span></div> 485 - const spans = element.querySelectorAll('span'); 486 - for (const span of spans) { 487 - const text = span.textContent?.trim(); 488 - if (text?.startsWith('@')) { 489 - return text.slice(1).toLowerCase(); // Remove @ prefix 490 - } 491 - } 492 - return null; 493 - } 494 - } 495 - ``` 496 - 497 - ### iOS App Wrapper (Future) 498 - 499 - For iOS Safari extension, need minimal Swift app: 500 - 501 - ``` 502 - ATlastApp/ 503 - ├── ATlast/ 504 - │ ├── ATlastApp.swift # Minimal app entry 505 - │ ├── ContentView.swift # Simple "Open Safari" UI 506 - │ └── Info.plist 507 - ├── ATlast Extension/ 508 - │ ├── SafariWebExtensionHandler.swift 509 - │ ├── Info.plist 510 - │ └── Resources/ 511 - │ └── (same extension files as above) 512 - └── ATlast.xcodeproj 513 - ``` 514 - 515 - --- 516 - 517 - ## Decisions Made 518 - 519 - | Question | Decision | Rationale | 520 - |----------|----------|-----------| 521 - | **Data Handoff** | POST to API endpoint | No size limits, seamless UX, audit trail | 522 - | **MVP Scope** | Twitter Following page only | Fastest path to value | 523 - | **iOS Priority** | Deferred | Focus on desktop Chrome/Firefox first | 524 - | **Platform Scope** | Twitter v1, architecture for multi-platform | Plan for Threads/Instagram/TikTok later | 525 - | **Extension Name** | ATlast Importer | Clear purpose, searchable in stores | 526 - | **Code Location** | Monorepo with pnpm workspaces | Clean shared types, isolated builds | 527 - | **Monorepo Tool** | pnpm workspaces | Fast, disk-efficient, minimal config | 528 - 529 - ## Remaining Questions 530 - 531 - ### Q1: Extension Branding 532 - - Name options: "ATlast", "ATlast Importer", "ATlast Social Bridge" 533 - - Icon design needed 534 - 535 - ### Q2: Error Recovery Strategy 536 - Twitter/X changes DOM frequently. Strategy for handling breaks: 537 - - Ship updates quickly when breaks detected 538 - - Build selector fallback chain 539 - - User-reportable "not working" flow 540 - - **Recommendation: All of the above** 541 - 542 - ### Q3: Extension Store Distribution 543 - - Chrome Web Store (requires $5 developer fee) 544 - - Firefox Add-ons (free) 545 - - Safari Extensions (requires Apple Developer account, $99/year - defer with iOS) 546 - 547 - --- 548 - 549 - ## Implementation Phases 550 - 551 - ### Phase 0: Monorepo Migration ✅ COMPLETE 552 - - [x] **0.1** Install pnpm globally if needed 553 - - [x] **0.2** Create pnpm-workspace.yaml 554 - - [x] **0.3** Create packages/ directory structure 555 - - [x] **0.4** Move src/ → packages/web/src/ 556 - - [x] **0.5** Move netlify/functions/ → packages/functions/ 557 - - [x] **0.6** Create packages/shared/ with types 558 - - [x] **0.7** Update import paths in web and functions 559 - - [x] **0.8** Update netlify.toml for new paths 560 - - [x] **0.9** Update root package.json scripts 561 - - [x] **0.10** Test build and dev commands 562 - - [x] **0.11** Commit monorepo migration 563 - 564 - ### Phase 1: Chrome Extension MVP ✅ COMPLETE 565 - - [x] **1.1** Create packages/extension/ structure 566 - - [x] **1.2** Write manifest.json (Manifest V3) 567 - - [x] **1.3** Implement base-scraper.ts abstract class 568 - - [x] **1.4** Implement twitter-scraper.ts 569 - - [x] **1.5** Implement content/index.ts (platform detection) 570 - - [x] **1.6** Implement popup UI (HTML/CSS/TS) 571 - - [x] **1.7** Implement background service worker 572 - - [x] **1.8** Implement api-client.ts (POST to ATlast) 573 - - [x] **1.9** Create Netlify function: extension-import.ts 574 - - [x] **1.10** ~~Create ATlast import page: /import/[id]~~ (Not needed - uses /results?uploadId) 575 - - [x] **1.11** Add extension build script 576 - - [x] **1.12** Test end-to-end flow locally - All bugs resolved 577 - - [ ] **1.13** Chrome Web Store submission - Next step 578 - 579 - ### Phase 2: Firefox Support 580 - - [ ] **2.1** Create manifest.firefox.json (MV2 if needed) 581 - - [ ] **2.2** Test on Firefox desktop 582 - - [ ] **2.3** Test on Firefox Android 583 - - [ ] **2.4** Firefox Add-ons submission 584 - 585 - ### Phase 3: Enhanced Twitter Features 586 - - [ ] **3.1** Support Followers page 587 - - [ ] **3.2** Support Twitter Lists 588 - - [ ] **3.3** Add selector fallback chain 589 - - [ ] **3.4** Add user-reportable error flow 590 - 591 - ### Phase 4: Additional Platforms (Future) 592 - - [ ] **4.1** Threads scraper 593 - - [ ] **4.2** Instagram scraper 594 - - [ ] **4.3** TikTok scraper 595 - 596 - ### Phase 5: iOS Support (Future) 597 - - [ ] **5.1** iOS app wrapper (Swift) 598 - - [ ] **5.2** Safari Web Extension integration 599 - - [ ] **5.3** App Store submission 600 - 601 - --- 602 - 603 - ## Related Decision Graph Nodes 604 - 605 - - **Goal**: #184 (Support Twitter/X file uploads) 606 - - **Problem Analysis**: #185-186 (user_id issue, resolution approach decision) 607 - - **Initial Options**: #187-192 (server-side, extension, CLI, BYOK, hybrid) 608 - - **Research**: #193-204 (Nitter dead, Sky Follower Bridge, DOM scraping) 609 - - **iOS Research**: #212-216 (Shortcuts timeout, Safari Web Extensions) 610 - - **Architecture Decisions**: #218-222 611 - - #219: POST to API endpoint 612 - - #220: Twitter Following page MVP 613 - - #221: iOS deferred 614 - - #222: Multi-platform architecture 615 - - **Implementation Decisions**: #224-227 616 - - #225: Monorepo with shared packages 617 - - #226: Extension name "ATlast Importer" 618 - - #227: pnpm workspaces tooling 619 - 620 - View live graph: https://notactuallytreyanastasio.github.io/deciduous/ 621 - 622 - --- 623 - 624 - ## Changelog 625 - 626 - | Date | Change | 627 - |------|--------| 628 - | 2024-12-25 | Initial plan created with research findings and architecture | 629 - | 2024-12-25 | Decisions made: POST API, Twitter MVP, iOS deferred, extensible architecture | 630 - | 2024-12-25 | Added: Extension name (ATlast Importer), monorepo structure (pnpm workspaces) | 631 - | 2024-12-25 | Added: Phase 0 (monorepo migration), detailed package structures, shared types | 632 - | 2025-12-26 | Phase 0 complete (monorepo migration) | 633 - | 2025-12-26 | Phase 1 nearly complete - core implementation done, active debugging | 634 - | 2025-12-26 | Architecture refactored: extension requires login first, uses /results?uploadId | 635 - | 2025-12-26 | Fixed: NaN database error, environment config, auth flow, CORS permissions | 636 - | 2025-12-26 | Fixed: API response unwrapping - extension now correctly handles ApiResponse structure | 637 - | 2025-12-26 | Phase 1 ready for testing - all bugs resolved, decision graph: 295 nodes tracked | 638 - | 2025-12-27 | Phase 1 COMPLETE - all extension bugs fixed, ready for Chrome Web Store submission | 639 - | 2025-12-27 | Added: Loading screen, timezone fixes, Vite optimization, decision graph improvements | 640 - | 2025-12-27 | Decision graph: 332 nodes, 333 edges - orphan nodes resolved, documentation improved |
docs/.nojekyll

This is a binary file and will not be displayed.

-298
docs/git-history.json
··· 1 - [ 2 - { 3 - "hash": "18f4ca7017ea6ca5d959f5d9596690c17b171bc3", 4 - "short_hash": "18f4ca7", 5 - "author": "Ariel M. Lighty", 6 - "date": "2025-12-28T21:38:11-05:00", 7 - "message": "fix: pass event to errorResponse for proper CORS on errors\n\n- Error middleware now passes event parameter to errorResponse\n- Fixes Firefox extension CORS headers on authentication errors\n- Both withErrorHandling and withAuthErrorHandling updated\n- Extension origin properly reflected in all error responses", 8 - "files_changed": 3 9 - }, 10 - { 11 - "hash": "603cf0a187850664336a12c9e5cbb49038906f53", 12 - "short_hash": "603cf0a", 13 - "author": "Ariel M. Lighty", 14 - "date": "2025-12-27T22:42:43-05:00", 15 - "message": "fix: CORS for extension credentialed requests\n\nUpdated CORS headers to support credentials from Chrome extensions:\n- Added getCorsHeaders() to detect chrome-extension:// origins\n- Changed from wildcard Access-Control-Allow-Origin to specific origin\n- Added Access-Control-Allow-Credentials: true for credentialed requests\n- Updated session endpoint to pass event for CORS header detection", 16 - "files_changed": 4 17 - }, 18 - { 19 - "hash": "603cf0a187850664336a12c9e5cbb49038906f53", 20 - "short_hash": "603cf0a", 21 - "author": "Ariel M. Lighty", 22 - "date": "2025-12-27T22:42:43-05:00", 23 - "message": "fix: CORS for extension credentialed requests\n\nUpdated CORS headers to support credentials from Chrome extensions:\n- Added getCorsHeaders() to detect chrome-extension:// origins\n- Changed from wildcard Access-Control-Allow-Origin to specific origin\n- Added Access-Control-Allow-Credentials: true for credentialed requests\n- Updated session endpoint to pass event for CORS header detection", 24 - "files_changed": 4 25 - }, 26 - { 27 - "hash": "bd3aabb75abb1875aef125610fcdccb14967a8e3", 28 - "short_hash": "bd3aabb", 29 - "author": "Ariel M. Lighty", 30 - "date": "2025-12-27T22:10:11-05:00", 31 - "message": "fix: extension dark mode and build mode messaging\n\n- Changed darkMode from 'class' to 'media' for automatic system preference detection\n- Made server offline message conditional on build mode (dev vs prod)\n- Hide dev server instructions in production builds", 32 - "files_changed": 5 33 - }, 34 - { 35 - "hash": "d07180cd3a19328b82b35118e525b59d4e2e060b", 36 - "short_hash": "d07180c", 37 - "author": "Ariel M. Lighty", 38 - "date": "2025-12-27T18:38:39-05:00", 39 - "message": "feat: add Tailwind CSS to extension\n\nReplaced 299 lines of vanilla CSS with Tailwind for design consistency with web app. Production build minified to 13KB.", 40 - "files_changed": 9 41 - }, 42 - { 43 - "hash": "fe29bb3e5faa0151f63c14724f7509af669860de", 44 - "short_hash": "fe29bb3", 45 - "author": "Ariel M. Lighty", 46 - "date": "2025-12-27T16:02:10-05:00", 47 - "message": "docs: update all .md files to reflect current project status\n\nUpdated 4 markdown files with current state:\n\nEXTENSION_STATUS.md:\n- Changed status from DEBUGGING to COMPLETE\n- Updated decision graph count (295 → 332 nodes)\n- Added recently completed section (nodes 296-332)\n- Marked all extension bugs as resolved\n\nCONTRIBUTING.md:\n- Replaced npm with pnpm throughout\n- Added monorepo structure documentation\n- Updated development commands (netlify-cli dev --filter)\n- Added extension development workflow\n\nPLAN.md:\n- Updated status to Phase 1 COMPLETE\n- Added all recent fixes to completion list\n- Updated decision graph count to 332 nodes\n- Added changelog entries for latest work\n\npackages/extension/README.md:\n- Added prerequisites section (dev server + login required)\n- Updated build commands with dev/prod distinction\n- Added Step 0: Start ATlast Dev Server\n- Added common issues for auth and server states\n\nAll files now accurately reflect completion status and use pnpm.", 48 - "files_changed": 6 49 - }, 50 - { 51 - "hash": "fcf682bb8969aca108262348e7e17531077713be", 52 - "short_hash": "fcf682b", 53 - "author": "Ariel M. Lighty", 54 - "date": "2025-12-27T15:48:44-05:00", 55 - "message": "docs: improve decision graph workflow with lifecycle management\n\nUpdated CLAUDE.md with comprehensive node lifecycle management:\n- Added node status transitions (pending → in_progress → completed)\n- Correct orphan detection commands (awk instead of cut)\n- Common mistakes section with examples\n- Enhanced audit checklist with status verification\n- Verification workflow after node creation\n\nAlso updated extension popup with ATmosphere branding.\n\nDecision graph now at 331 nodes, 332 edges - all orphans resolved.", 56 - "files_changed": 4 57 - }, 58 - { 59 - "hash": "e04934ffb5e2d78791fcd23bc3afeb4d438a5546", 60 - "short_hash": "e04934f", 61 - "author": "Ariel M. Lighty", 62 - "date": "2025-12-26T21:57:05-05:00", 63 - "message": "perf: optimize Vite dev server startup\n\nAdded explicit optimizeDeps.include to pre-bundle common dependencies:\n- React ecosystem (react, react-dom, react-router-dom)\n- Icon libraries (@icons-pack/react-simple-icons, lucide-react)\n- Other deps (date-fns, jszip, zustand, @tanstack/react-virtual)\n\nAlso added server.fs.allow config for monorepo file serving.\n\nThis should speed up subsequent dev server starts by ensuring these\ndependencies are consistently pre-bundled.", 64 - "files_changed": 1 65 - }, 66 - { 67 - "hash": "aacbbaa27797781098dacdfd0194c93cd71d7bd2", 68 - "short_hash": "aacbbaa", 69 - "author": "Ariel M. Lighty", 70 - "date": "2025-12-26T21:46:06-05:00", 71 - "message": "fix: use TIMESTAMPTZ for all timestamp columns\n\nChanged all TIMESTAMP columns to TIMESTAMPTZ (timestamp with timezone) to\nproperly handle timezone-aware timestamps across all tables:\n- oauth_states (created_at, expires_at)\n- oauth_sessions (created_at, expires_at)\n- user_sessions (created_at, expires_at)\n- user_uploads (created_at, last_checked)\n- source_accounts (last_checked, match_found_at, created_at)\n- user_source_follows (created_at)\n- atproto_matches (found_at, last_verified, last_follow_check)\n- user_match_status (notified_at, viewed_at, followed_at, dismissed_at)\n- notification_queue (created_at, sent_at)\n\nThis fixes the 5-hour timezone offset issue where timestamps were stored\nwithout timezone info, causing display errors across different timezones.", 72 - "files_changed": 1 73 - }, 74 - { 75 - "hash": "46626f4a18eaaaaf42368361130bb1ddc7bd9677", 76 - "short_hash": "46626f4", 77 - "author": "Ariel M. Lighty", 78 - "date": "2025-12-26T21:20:34-05:00", 79 - "message": "fix: show loading screen during extension upload search\n\nPreviously when loading an upload from extension that hadn't been searched yet,\nthe app would immediately navigate to the results page showing 'none' for all\nmatches, then update them as the search progressed.\n\nNow it behaves like the file upload flow:\n- Shows loading screen during search\n- Navigates to results only after search completes and results are saved\n- If upload already has matches, navigates to results immediately", 80 - "files_changed": 1 81 - }, 82 - { 83 - "hash": "212660a996d6b0f1db59f9532d2b3968c7113f10", 84 - "short_hash": "212660a", 85 - "author": "Ariel M. Lighty", 86 - "date": "2025-12-26T20:58:45-05:00", 87 - "message": "fix: pass final search results to onComplete callback\n\nFixes issue where results were displayed but not saved to database until\npage refresh. Root cause: onComplete callback accessed stale searchResults\nfrom closure instead of updated state.\n\nChanges:\n- useSearch.searchAllUsers: onComplete now receives SearchResult[] param\n- useSearch: uses setSearchResults updater to get current state\n- App.tsx: updated all 3 searchAllUsers calls to use finalResults\n- Removed setTimeout workarounds\n\nResult: Extension and file upload flows now save immediately after search.", 88 - "files_changed": 4 89 - }, 90 - { 91 - "hash": "6ced3f0b015af1c9126559a393996576402cfd03", 92 - "short_hash": "6ced3f0", 93 - "author": "Ariel M. Lighty", 94 - "date": "2025-12-26T14:12:46-05:00", 95 - "message": "fix extension flow: create user_source_follows, auto-search, time display\n\nBackend (extension-import.ts):\n- Now creates user_source_follows entries linking upload to source accounts\n- Without these, get-upload-details returned empty (queries FROM user_source_follows)\n- Uses bulkCreate return value (Map<username, id>) to create links\n\nFrontend (App.tsx):\n- handleLoadUpload now detects if upload has no matches yet\n- Sets isSearching: true for new uploads\n- Automatically triggers searchAllUsers for new uploads\n- Saves results after search completes\n- Changed platform from hardcoded \"tiktok\" to \"twitter\"\n\nFrontend (HistoryTab.tsx):\n- Fixed time display: removed \"Uploaded\" prefix\n- Now shows \"about 5 hours ago\" instead of \"Uploaded in about 5 hours\"\n- formatRelativeTime with addSuffix already provides complete sentence\n\nResolves:\n- Empty results on page load\n- No automatic searching\n- History navigation not working (will work after search)\n- Grammatically incorrect time display", 96 - "files_changed": 5 97 - }, 98 - { 99 - "hash": "581ed00fec3c0c5f472c6ff92e00bf4ed5b27e9a", 100 - "short_hash": "581ed00", 101 - "author": "Ariel M. Lighty", 102 - "date": "2025-12-26T13:47:37-05:00", 103 - "message": "fix extension import: use bulkCreate and handle uploadId param\n\nBackend fixes:\n- Use SourceAccountRepository.bulkCreate() instead of non-existent upsertSourceAccount()\n- Change redirectUrl from /results?uploadId= to /?uploadId=\n- More efficient bulk insert instead of loop\n\nFrontend fixes:\n- Add useEffect to load results when uploadId param present\n- Calls loadUploadResults(uploadId) automatically on page load\n- Cleans up URL param after loading\n\nResolves:\n- \"sourceAccountRepo.upsertSourceAccount is not a function\" error\n- \"No routes matched location /results?uploadId=...\" routing error", 104 - "files_changed": 4 105 - }, 106 - { 107 - "hash": "9ca734749fbaa014828f8437afc5e515610afd31", 108 - "short_hash": "9ca7347", 109 - "author": "Ariel M. Lighty", 110 - "date": "2025-12-26T13:37:24-05:00", 111 - "message": "update documentation: extension ready for testing after API response fix", 112 - "files_changed": 4 113 - }, 114 - { 115 - "hash": "95636330f387598f55017eda668fb9f91ccde509", 116 - "short_hash": "9563633", 117 - "author": "Ariel M. Lighty", 118 - "date": "2025-12-26T13:35:52-05:00", 119 - "message": "fix extension api-client: unwrap ApiResponse.data structure\n\nBackend endpoints use successResponse() which wraps data in:\n { success: true, data: {...} }\n\nExtension was expecting flat response structure, causing:\n- uploadToATlast to return undefined (missing importId, redirectUrl)\n- checkSession to return wrapped object instead of user data\n- Invalid URL error: \"http://127.0.0.1:8888undefined\"\n\nFixed both uploadToATlast and checkSession to access apiResponse.data", 120 - "files_changed": 2 121 - }, 122 - { 123 - "hash": "34bd9dcd1237971a87627b148c0452b8484e4871", 124 - "short_hash": "34bd9dc", 125 - "author": "Ariel M. Lighty", 126 - "date": "2025-12-26T00:50:44-05:00", 127 - "message": "update documentation with current debugging status\n\nPLAN.md updates:\n- Added current status section with recent fixes and active work\n- Marked Phase 0 as complete\n- Marked Phase 1 as in progress (debugging)\n- Updated changelog with 2025-12-26 progress\n- Updated decision graph count to 288 nodes\n\nEXTENSION_STATUS.md updates:\n- Changed state from READY FOR TESTING to DEBUGGING\n- Added fixed issues section (NaN bug, database init)\n- Added active debugging section\n- Updated decision graph summary to 288 nodes\n- Added node references for recent fixes (#287-288)\n\nDecision graph:\n- Synced with latest nodes (288 total, 276 edges)\n- Tracked database initialization outcome", 128 - "files_changed": 4 129 - }, 130 - { 131 - "hash": "1a355fe785eb1768dba3f4c3a8ba631904d1d6d6", 132 - "short_hash": "1a355fe", 133 - "author": "Ariel M. Lighty", 134 - "date": "2025-12-26T00:33:21-05:00", 135 - "message": "fix extension-import: add missing matchedUsers parameter to createUpload\n\nThe createUpload method expects 5 parameters but we were only passing 4,\ncausing NaN to be inserted for unmatched_users calculation. Now passing 0\nfor matchedUsers (will be updated after search is performed).", 136 - "files_changed": 1 137 - }, 138 - { 139 - "hash": "d0bcf337b6d223a86443f6f67767e87b74e4dd7d", 140 - "short_hash": "d0bcf33", 141 - "author": "Ariel M. Lighty", 142 - "date": "2025-12-26T00:26:09-05:00", 143 - "message": "refactor extension to require authentication and use proper upload flow\n\nRemoved temporary storage approach and implemented proper authentication flow:\n\nExtension changes:\n- Added session check to popup init flow (checkSession in api-client)\n- Added \"not logged in\" state with login prompts\n- Updated uploadToATlast to include credentials for cookie-based auth\n- Extension now requires user to be logged in BEFORE scanning\n\nBackend changes:\n- Converted extension-import to AuthenticatedHandler (requires auth)\n- Now creates upload records immediately (no temporary storage)\n- Removed extension_imports table from database schema\n- Deleted get-extension-import function (no longer needed)\n- Deleted import-store utility (temporary approach removed)\n\nFrontend changes:\n- Removed ExtensionImport page and /import/:id route\n- Extension uploads now use same flow as file uploads\n\nThis matches the correct user flow: user logs in to ATlast first, then\nextension creates permanent upload records directly (same as file uploads).\n\nBuilt extension successfully for dev environment.", 144 - "files_changed": 12 145 - }, 146 - { 147 - "hash": "c35fb0d83202607facc203dfe10325e8672ea67e", 148 - "short_hash": "c35fb0d", 149 - "author": "Ariel M. Lighty", 150 - "date": "2025-12-25T19:16:38-05:00", 151 - "message": "add validation to prevent uploading empty results\n\nCheck if usernames array has items before attempting upload.\nShows clear error message instead of hanging.", 152 - "files_changed": 1 153 - }, 154 - { 155 - "hash": "0718100fbf6342cb21e8877e32b6f590b0b8cc57", 156 - "short_hash": "0718100", 157 - "author": "Ariel M. Lighty", 158 - "date": "2025-12-25T18:52:32-05:00", 159 - "message": "fix critical messaging bug: onMessage was discarding return values\n\nThe onMessage wrapper in messaging.ts was only sending {success: true}\ninstead of the actual handler return value. This caused the popup to\nreceive undefined state even though the background worker was correctly\nstoring it.\n\nChanges:\n- messaging.ts: Changed onMessage to forward handler return values\n- background service-worker.ts: Added comprehensive logging\n- popup.ts: Added state change listener and detailed logging\n\nThis fixes the issue where popup showed 'Go to...' even when on the\nfollowing page.", 160 - "files_changed": 3 161 - }, 162 - { 163 - "hash": "ba29fd68872913ba0a587aa7f29f97b3d373a732", 164 - "short_hash": "ba29fd6", 165 - "author": "Ariel M. Lighty", 166 - "date": "2025-12-25T13:22:32-05:00", 167 - "message": "configure Netlify dev for monorepo with --filter flag\n\nFixed Netlify CLI monorepo detection issue by using --filter flag:\n- Updated root package.json scripts to use 'npx netlify-cli dev --filter @atlast/web'\n- Updated netlify.toml [dev] section to use npm with --prefix for framework command\n- Added monorepo development instructions to CLAUDE.md\n- Documented Windows Git Bash compatibility issue with netlify command\n\nSolution: Use 'npx netlify-cli dev --filter @atlast/web' to bypass monorepo\nproject selection prompt and specify which workspace package to run.\n\nDev server now runs successfully at http://localhost:8888 with all backend\nfunctions loaded.", 168 - "files_changed": 5 169 - }, 170 - { 171 - "hash": "32cdee3aeac7ef986df47e0fff786b5f7471e55b", 172 - "short_hash": "32cdee3", 173 - "author": "Ariel M. Lighty", 174 - "date": "2025-12-25T13:22:32-05:00", 175 - "message": "configure Netlify dev for monorepo with --filter flag\n\nFixed Netlify CLI monorepo detection issue by using --filter flag:\n- Updated root package.json scripts to use 'npx netlify-cli dev --filter @atlast/web'\n- Updated netlify.toml [dev] section to use npm with --prefix for framework command\n- Added monorepo development instructions to CLAUDE.md\n- Documented Windows Git Bash compatibility issue with netlify command\n\nSolution: Use 'npx netlify-cli dev --filter @atlast/web' to bypass monorepo\nproject selection prompt and specify which workspace package to run.\n\nDev server now runs successfully at http://localhost:8888 with all backend\nfunctions loaded.", 176 - "files_changed": 4 177 - }, 178 - { 179 - "hash": "c3e7afad396d130791d801a85cbfc9643bcd6309", 180 - "short_hash": "c3e7afa", 181 - "author": "Ariel M. Lighty", 182 - "date": "2025-12-25T12:47:38-05:00", 183 - "message": "migrate to pnpm monorepo structure\n\nRestructured codebase into pnpm workspace with three packages:\n- packages/web: React frontend (from src/)\n- packages/functions: Netlify serverless functions (from netlify/functions/)\n- packages/shared: Shared TypeScript types for Platform and Import APIs\n\nChanges:\n- Created pnpm-workspace.yaml for workspace configuration\n- Moved all web app files to packages/web/\n- Moved all Netlify functions to packages/functions/src/\n- Created packages/shared with Platform enum and ExtensionImportRequest/Response types\n- Updated netlify.toml to point to new paths\n- Updated root package.json scripts to use pnpm workspace commands\n- All dependencies split appropriately between packages\n\nPhase 0 (Monorepo Migration) from PLAN.md completed successfully.\nBuilds and dev server tested and working.", 184 - "files_changed": 317 185 - }, 186 - { 187 - "hash": "e2d6a7e940ea402570c9397a722a4050c735cb6d", 188 - "short_hash": "e2d6a7e", 189 - "author": "Ariel M. Lighty", 190 - "date": "2025-12-24T21:09:33-05:00", 191 - "message": "remove .claude/ and dist/ from repository\n\nThese directories are already in .gitignore but were committed\nbefore the ignore rules were added. Removed from tracking while\nkeeping local files intact.", 192 - "files_changed": 6 193 - }, 194 - { 195 - "hash": "f79a669dd6528340d453cb28e9fed2bd5232d46c", 196 - "short_hash": "f79a669", 197 - "author": "Ariel M. Lighty", 198 - "date": "2025-12-24T19:38:51-05:00", 199 - "message": "move tooltip from hero to login form as superscript\n\n- Removed tooltip from HeroSection (ATmosphere now plain text)\n- Added superscript info icon next to 'ATmosphere' in login form text\n- Tooltip content left-aligned for better readability\n- Maintains platform-agnostic design", 200 - "files_changed": 2 201 - }, 202 - { 203 - "hash": "9bdca934948a284e1315961b4430bae0b6617cbe", 204 - "short_hash": "9bdca93", 205 - "author": "Ariel M. Lighty", 206 - "date": "2025-12-24T18:35:00-05:00", 207 - "message": "fix login avatar display by fetching from Bluesky API\n\nactor-typeahead component doesn't expose avatar data via events or attributes.\nAdded debounced API fetch (300ms) to searchActorsTypeahead endpoint when\nhandle is entered. Avatar now displays for both typeahead selections and\nmanually entered handles.", 208 - "files_changed": 1 209 - }, 210 - { 211 - "hash": "6cd4d622930e2a43531f2df40d930ceb5d2b4dbc", 212 - "short_hash": "6cd4d62", 213 - "author": "Ariel M. Lighty", 214 - "date": "2025-12-24T00:27:50-05:00", 215 - "message": "use shared card component for history and results", 216 - "files_changed": 4 217 - }, 218 - { 219 - "hash": "cc586d28ea8d4544467392be1083fdec11731814", 220 - "short_hash": "cc586d2", 221 - "author": "Ariel M. Lighty", 222 - "date": "2025-12-23T21:11:19-05:00", 223 - "message": "replace excessive toasts with aria-live announcer\n\nRemove redundant success/info toasts (logout, upload loaded, no results).\nKeep only error toasts for critical feedback.\nAdd AriaLiveAnnouncer component for screen reader accessibility.", 224 - "files_changed": 2 225 - }, 226 - { 227 - "hash": "ebb1e05cac477f02e1901aab6f3a8005016472f9", 228 - "short_hash": "ebb1e05", 229 - "author": "Ariel M. Lighty", 230 - "date": "2025-12-23T21:10:58-05:00", 231 - "message": "fix mobile alignment: badges and descriptions align with avatar", 232 - "files_changed": 1 233 - }, 234 - { 235 - "hash": "4c3ae0dbca215d10b499fc646ae7f53c43c658ac", 236 - "short_hash": "4c3ae0d", 237 - "author": "Ariel M. Lighty", 238 - "date": "2025-12-23T20:58:15-05:00", 239 - "message": "fix login typeahead autofill and auto-strip @ symbol\n\nTypeahead fix:\n- Add event listeners for input/change/blur to sync actor-typeahead selections with form state\n- Ensures Enter/Tab selections from typeahead dropdown properly update form\n- Allows Enter key to submit form after selection\n\n@ stripping:\n- Automatically remove leading @ from handle input\n- Show helpful inline message when @ is stripped\n- Inform users the @ symbol isn't needed", 240 - "files_changed": 1 241 - }, 242 - { 243 - "hash": "8e9efd2577b82cb61b0162a28b4ab072bbccf00b", 244 - "short_hash": "8e9efd2", 245 - "author": "Ariel M. Lighty", 246 - "date": "2025-12-23T20:57:21-05:00", 247 - "message": "update CLAUDE.md with separate commit guidance\n\nAdd critical note that each commit should address ONE specific fix or feature.\nMultiple unrelated changes should be committed separately for clearer history.", 248 - "files_changed": 1 249 - }, 250 - { 251 - "hash": "587a9b0314546b91e00c94bf87d28d29f6527456", 252 - "short_hash": "587a9b0", 253 - "author": "Ariel M. Lighty", 254 - "date": "2025-12-23T19:34:34-05:00", 255 - "message": "add rate limiting to batch endpoints\n\nOptimization #12:\n- created rateLimit.middleware with in-memory rate limiting\n- batch-search-actors: 5 requests/min (conservative)\n- batch-follow-users: 8 requests/hr (conservative)\n- calculated based on AT Protocol limits with 50% buffer\n- DRY implementation with applyRateLimit helper function\n- prevents users from exhausting AT Protocol API limits\n- leaves buffer for likes, replies, posts\n\nNote: In-memory (resets on cold starts). Upgrade to Upstash Redis for production-grade shared state.", 256 - "files_changed": 3 257 - }, 258 - { 259 - "hash": "35061ae467e17724d85493c94827c361dc84e6d1", 260 - "short_hash": "35061ae", 261 - "author": "Ariel M. Lighty", 262 - "date": "2025-12-23T19:12:00-05:00", 263 - "message": "move inline animations to Tailwind config\n\nOptimization #11:\n- added float-1, float-2, float-3 animation variants to tailwind.config.js\n- replaced inline animation and animationDelay styles with Tailwind classes\n- use modulo pattern to cycle through 3 animation variants\n- maintains visual variety without Math.random() for animation timing\n- consistent with Tailwind conventions, easier to maintain", 264 - "files_changed": 2 265 - }, 266 - { 267 - "hash": "6b5cf20f95ea43d18c5d05fa80ff7e94d7aa26d2", 268 - "short_hash": "6b5cf20", 269 - "author": "Ariel M. Lighty", 270 - "date": "2025-12-23T19:05:42-05:00", 271 - "message": "replace localStorage context with zustand persist store\n\nOptimization #10:\n- created useSettingsStore with zustand persist middleware\n- removed SettingsContext.tsx (88 lines) and provider wrapper\n- added SSR-safe storage with cross-tab synchronization\n- automatic JSON serialization, no manual parse/stringify\n- maintained backward-compatible API (useSettings hook)\n- bundle size: +2.3KB for zustand library", 272 - "files_changed": 6 273 - }, 274 - { 275 - "hash": "43710263eec21891c899f57e4d0434322612d353", 276 - "short_hash": "4371026", 277 - "author": "Ariel M. Lighty", 278 - "date": "2025-12-23T18:11:36-05:00", 279 - "message": "replace any types with AT Protocol interfaces\n\nOptimization #9:\n- created atproto.types.ts with proper AT Protocol interfaces\n- replaced 7 any types in batch-search-actors.ts\n- added ATProtoActor, ATProtoProfile, RankedActor, EnrichedActor types\n- improves type safety, compile-time error catching, IDE support", 280 - "files_changed": 3 281 - }, 282 - { 283 - "hash": "65ac856188d644baed837eea7775aed307ca0a56", 284 - "short_hash": "65ac856", 285 - "author": "Ariel M. Lighty", 286 - "date": "2025-12-23T16:07:44-05:00", 287 - "message": "remove duplicate type definitions from Results.tsx\n\nOptimization #8:\n- removed 3 duplicate type definitions (atprotoSession, SourceUser, SearchResult)\n- import AtprotoSession and SearchResult from central types\n- prevents type drift, establishes single source of truth", 288 - "files_changed": 1 289 - }, 290 - { 291 - "hash": "093b47d63a6324c2e4bc231d45c5d9d6792383ed", 292 - "short_hash": "093b47d", 293 - "author": "Ariel M. Lighty", 294 - "date": "2025-12-23T15:58:35-05:00", 295 - "message": "replace duplicate validation with Zod schemas\n\nOptimizations #6 & #7:\n- #6: verified early exit optimization already implemented in FollowService\n- #7: created validation.utils.ts with Zod schemas for array validation\n- replaced 3 duplicate validation blocks with reusable Zod schemas\n- updated batch-follow-users, check-follow-status, batch-search-actors", 296 - "files_changed": 5 297 - } 298 - ]
-8674
docs/graph-data.json
··· 1 - { 2 - "nodes": [ 3 - { 4 - "id": 1, 5 - "change_id": "9aee494f-f327-4068-9ef1-86ff07fdb2f5", 6 - "node_type": "goal", 7 - "title": "Parallelize batch follow operations", 8 - "description": null, 9 - "status": "completed", 10 - "created_at": "2025-12-23T00:16:11.769939800-05:00", 11 - "updated_at": "2025-12-24T16:16:53.207578700-05:00", 12 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95,\"prompt\":\"fix #1, make sure using deciduous\"}" 13 - }, 14 - { 15 - "id": 2, 16 - "change_id": "c0fca49e-faff-48e9-bf4d-d851ce0d1e87", 17 - "node_type": "action", 18 - "title": "Reading batch-follow-users.ts to understand current implementation", 19 - "description": null, 20 - "status": "completed", 21 - "created_at": "2025-12-23T00:16:18.073585300-05:00", 22 - "updated_at": "2025-12-24T16:16:03.193879100-05:00", 23 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 24 - }, 25 - { 26 - "id": 3, 27 - "change_id": "d53e1547-1f6a-4398-a734-a36d13c328c8", 28 - "node_type": "observation", 29 - "title": "Sequential for-loop follows users one-by-one with rate limit backoff. Has consecutive error tracking (max 3) and DB updates after each follow.", 30 - "description": null, 31 - "status": "completed", 32 - "created_at": "2025-12-23T00:16:51.265234600-05:00", 33 - "updated_at": "2025-12-24T16:16:03.275394800-05:00", 34 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 35 - }, 36 - { 37 - "id": 4, 38 - "change_id": "73ad63ab-0889-4790-b7e9-32fb4967d74a", 39 - "node_type": "decision", 40 - "title": "Choose parallelization strategy: p-limit vs manual Promise.allSettled with chunking", 41 - "description": null, 42 - "status": "completed", 43 - "created_at": "2025-12-23T00:16:59.199124800-05:00", 44 - "updated_at": "2025-12-24T16:16:22.088332700-05:00", 45 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 46 - }, 47 - { 48 - "id": 5, 49 - "change_id": "45d5d04a-27f7-47cb-8171-b1036584e40f", 50 - "node_type": "option", 51 - "title": "Use p-limit package for concurrency control", 52 - "description": null, 53 - "status": "completed", 54 - "created_at": "2025-12-23T00:17:12.093807100-05:00", 55 - "updated_at": "2025-12-24T16:16:22.149136900-05:00", 56 - "metadata_json": "{\"branch\":\"master\",\"confidence\":75}" 57 - }, 58 - { 59 - "id": 6, 60 - "change_id": "87b7f433-fe62-4470-aaf2-de1d3447bdea", 61 - "node_type": "option", 62 - "title": "Manual Promise.allSettled with chunking - no new dependencies", 63 - "description": null, 64 - "status": "completed", 65 - "created_at": "2025-12-23T00:17:13.545639900-05:00", 66 - "updated_at": "2025-12-24T16:16:22.216560800-05:00", 67 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 68 - }, 69 - { 70 - "id": 7, 71 - "change_id": "66bb6ba2-961c-4008-a6cf-fb27aa29d934", 72 - "node_type": "outcome", 73 - "title": "Chose manual Promise.allSettled with concurrency=5. Reason: No new deps, better control over rate limiting, preserves existing error handling logic.", 74 - "description": null, 75 - "status": "completed", 76 - "created_at": "2025-12-23T00:17:24.728183300-05:00", 77 - "updated_at": "2025-12-24T16:16:03.343117300-05:00", 78 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 79 - }, 80 - { 81 - "id": 8, 82 - "change_id": "d670e4b0-a74e-4098-be81-111a07df214d", 83 - "node_type": "action", 84 - "title": "Implementing parallel follow logic with Promise.allSettled and concurrency control", 85 - "description": null, 86 - "status": "completed", 87 - "created_at": "2025-12-23T00:17:32.813066700-05:00", 88 - "updated_at": "2025-12-24T16:16:03.404671400-05:00", 89 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"files\":[\"netlify/functions/batch-follow-users.ts\"]}" 90 - }, 91 - { 92 - "id": 9, 93 - "change_id": "c6179665-8883-4414-91c6-6f7d6c58c977", 94 - "node_type": "outcome", 95 - "title": "Successfully refactored batch-follow-users.ts to use Promise.allSettled with CONCURRENCY=5. Processes follows 5 at a time instead of sequentially. Preserved rate limiting and DB updates.", 96 - "description": null, 97 - "status": "completed", 98 - "created_at": "2025-12-23T00:19:14.724719700-05:00", 99 - "updated_at": "2025-12-24T16:16:03.467894600-05:00", 100 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95,\"files\":[\"netlify/functions/batch-follow-users.ts\"]}" 101 - }, 102 - { 103 - "id": 10, 104 - "change_id": "1ea05092-5ad4-4d66-96a7-ff40c12a7d8a", 105 - "node_type": "goal", 106 - "title": "Fix excessive re-renders in search hook", 107 - "description": null, 108 - "status": "completed", 109 - "created_at": "2025-12-23T00:22:24.138197600-05:00", 110 - "updated_at": "2025-12-24T16:16:53.306130800-05:00", 111 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95,\"prompt\":\"fix #2\"}" 112 - }, 113 - { 114 - "id": 11, 115 - "change_id": "3af4cfc5-fb60-4b2e-a05a-d1eba3905cc4", 116 - "node_type": "action", 117 - "title": "Reading useSearch.ts to analyze re-render issues", 118 - "description": null, 119 - "status": "completed", 120 - "created_at": "2025-12-23T00:22:25.586446300-05:00", 121 - "updated_at": "2025-12-24T16:16:03.529806600-05:00", 122 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"files\":[\"src/hooks/useSearch.ts\"]}" 123 - }, 124 - { 125 - "id": 12, 126 - "change_id": "3a6744f3-e1e1-4532-8f54-a7d84e0c6b9b", 127 - "node_type": "observation", 128 - "title": "searchAllUsers calls setSearchResults 2-3 times per batch (lines 50, 82, 115). Each call maps entire array even though only updating BATCH_SIZE items. For 100 users in batches of 50 = 4 complete array iterations.", 129 - "description": null, 130 - "status": "completed", 131 - "created_at": "2025-12-23T00:22:45.558974700-05:00", 132 - "updated_at": "2025-12-24T16:16:03.594310900-05:00", 133 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95,\"files\":[\"src/hooks/useSearch.ts\"]}" 134 - }, 135 - { 136 - "id": 13, 137 - "change_id": "413df68c-2575-4794-abdb-4a4e9bf8f4c0", 138 - "node_type": "decision", 139 - "title": "Choose optimization strategy: combine setState calls vs use index-based updates vs use immer", 140 - "description": null, 141 - "status": "completed", 142 - "created_at": "2025-12-23T00:22:56.329200300-05:00", 143 - "updated_at": "2025-12-24T16:16:22.284595200-05:00", 144 - "metadata_json": "{\"branch\":\"master\",\"confidence\":80}" 145 - }, 146 - { 147 - "id": 14, 148 - "change_id": "692a157c-d7e7-439c-a137-856efafd3e4f", 149 - "node_type": "option", 150 - "title": "Combine the 2 setSearchResults calls into 1 per batch - set isSearching and results together", 151 - "description": null, 152 - "status": "completed", 153 - "created_at": "2025-12-23T00:22:59.164800400-05:00", 154 - "updated_at": "2025-12-24T16:16:22.350892600-05:00", 155 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 156 - }, 157 - { 158 - "id": 15, 159 - "change_id": "b525b78e-be8e-4eeb-9eda-8d90c2ea045a", 160 - "node_type": "option", 161 - "title": "Use Map/index-based updates - build updates object, apply once", 162 - "description": null, 163 - "status": "completed", 164 - "created_at": "2025-12-23T00:23:00.699483600-05:00", 165 - "updated_at": "2025-12-24T16:16:22.422867800-05:00", 166 - "metadata_json": "{\"branch\":\"master\",\"confidence\":70}" 167 - }, 168 - { 169 - "id": 16, 170 - "change_id": "2532bab6-bfb4-4202-9ca7-83c80fb64183", 171 - "node_type": "option", 172 - "title": "Use immer library for immutable updates", 173 - "description": null, 174 - "status": "completed", 175 - "created_at": "2025-12-23T00:23:02.152773-05:00", 176 - "updated_at": "2025-12-24T16:16:22.490430-05:00", 177 - "metadata_json": "{\"branch\":\"master\",\"confidence\":60}" 178 - }, 179 - { 180 - "id": 17, 181 - "change_id": "30e11366-da8b-4222-8e9d-118fbbb36123", 182 - "node_type": "outcome", 183 - "title": "Chose option A: Remove the pre-search setSearchResults call (isSearching: true). Only update state once per batch after API response. Reduces from 2 calls per batch to 1.", 184 - "description": null, 185 - "status": "completed", 186 - "created_at": "2025-12-23T00:23:15.327852500-05:00", 187 - "updated_at": "2025-12-24T16:16:03.654968400-05:00", 188 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 189 - }, 190 - { 191 - "id": 18, 192 - "change_id": "bc0b23c3-0428-4e5c-b625-511185775d84", 193 - "node_type": "action", 194 - "title": "Refactoring searchAllUsers to batch state updates - removing pre-search setState call", 195 - "description": null, 196 - "status": "completed", 197 - "created_at": "2025-12-23T00:23:39.289122300-05:00", 198 - "updated_at": "2025-12-24T16:16:03.716544600-05:00", 199 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"files\":[\"src/hooks/useSearch.ts\"]}" 200 - }, 201 - { 202 - "id": 19, 203 - "change_id": "1e44b460-476c-4b7c-8440-69ce34db7764", 204 - "node_type": "observation", 205 - "title": "toggleMatchSelection also maps entire array but only updates 1 item. Should use index-based update for better performance.", 206 - "description": null, 207 - "status": "completed", 208 - "created_at": "2025-12-23T00:24:00.076355600-05:00", 209 - "updated_at": "2025-12-24T16:16:03.779907800-05:00", 210 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85,\"files\":[\"src/hooks/useSearch.ts\"]}" 211 - }, 212 - { 213 - "id": 20, 214 - "change_id": "8966232e-79e8-4a77-8ef4-0b149c56582c", 215 - "node_type": "outcome", 216 - "title": "Successfully optimized useSearch hook: Removed pre-search setState (50% fewer re-renders in searchAllUsers). Optimized toggleMatchSelection to use index-based update instead of mapping entire array.", 217 - "description": null, 218 - "status": "completed", 219 - "created_at": "2025-12-23T00:24:17.083389500-05:00", 220 - "updated_at": "2025-12-24T16:16:03.839933300-05:00", 221 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95,\"files\":[\"src/hooks/useSearch.ts\"]}" 222 - }, 223 - { 224 - "id": 21, 225 - "change_id": "5c5628db-b79f-4c85-8c25-b03e1d0f8b3f", 226 - "node_type": "goal", 227 - "title": "Add useCallback to hook-returned functions", 228 - "description": null, 229 - "status": "completed", 230 - "created_at": "2025-12-23T00:28:01.356743800-05:00", 231 - "updated_at": "2025-12-24T16:16:53.376617-05:00", 232 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95,\"prompt\":\"fix #3\"}" 233 - }, 234 - { 235 - "id": 22, 236 - "change_id": "52249f48-bd1d-4242-aeb9-0812ff508bc3", 237 - "node_type": "action", 238 - "title": "Analyzing useSearch.ts and useFollows.ts for missing useCallback", 239 - "description": null, 240 - "status": "completed", 241 - "created_at": "2025-12-23T00:28:03.293791400-05:00", 242 - "updated_at": "2025-12-24T16:16:03.897528300-05:00", 243 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"files\":[\"src/hooks/useSearch.ts\",\"src/hooks/useFollows.ts\"]}" 244 - }, 245 - { 246 - "id": 23, 247 - "change_id": "446cf6f8-bd4d-4a11-bd74-cfab9a9aa869", 248 - "node_type": "observation", 249 - "title": "useSearch returns 5 unmemoized functions: searchAllUsers, toggleMatchSelection, toggleExpandResult, selectAllMatches, deselectAllMatches. useFollow returns 1 unmemoized function: followSelectedUsers. All create new references on every render.", 250 - "description": null, 251 - "status": "completed", 252 - "created_at": "2025-12-23T00:28:19.007514800-05:00", 253 - "updated_at": "2025-12-24T16:16:03.974459400-05:00", 254 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 255 - }, 256 - { 257 - "id": 24, 258 - "change_id": "40abf558-716f-4533-91b7-3a51163d50f6", 259 - "node_type": "action", 260 - "title": "Adding useCallback to all functions in useSearch.ts", 261 - "description": null, 262 - "status": "completed", 263 - "created_at": "2025-12-23T00:28:30.294574100-05:00", 264 - "updated_at": "2025-12-24T16:16:04.037038400-05:00", 265 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"files\":[\"src/hooks/useSearch.ts\"]}" 266 - }, 267 - { 268 - "id": 25, 269 - "change_id": "03e77df3-970c-4443-b497-09b7976be42e", 270 - "node_type": "outcome", 271 - "title": "Successfully added useCallback to all 5 functions in useSearch.ts. Functions now maintain stable references across re-renders.", 272 - "description": null, 273 - "status": "completed", 274 - "created_at": "2025-12-23T00:29:17.807201300-05:00", 275 - "updated_at": "2025-12-24T16:16:04.099138600-05:00", 276 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95,\"files\":[\"src/hooks/useSearch.ts\"]}" 277 - }, 278 - { 279 - "id": 26, 280 - "change_id": "bad40d96-109e-4acb-9d5f-7c8ba11586e0", 281 - "node_type": "action", 282 - "title": "Adding useCallback to followSelectedUsers in useFollows.ts", 283 - "description": null, 284 - "status": "completed", 285 - "created_at": "2025-12-23T00:29:27.586937300-05:00", 286 - "updated_at": "2025-12-24T16:16:04.174102200-05:00", 287 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"files\":[\"src/hooks/useFollows.ts\"]}" 288 - }, 289 - { 290 - "id": 27, 291 - "change_id": "a1a3c887-b702-45ac-bac0-5162cbfe6d42", 292 - "node_type": "outcome", 293 - "title": "Successfully added useCallback to followSelectedUsers in useFollows.ts with proper dependencies [session, searchResults, setSearchResults, destinationAppId, isFollowing].", 294 - "description": null, 295 - "status": "completed", 296 - "created_at": "2025-12-23T00:29:57.207898500-05:00", 297 - "updated_at": "2025-12-24T16:16:04.238261100-05:00", 298 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95,\"files\":[\"src/hooks/useFollows.ts\"]}" 299 - }, 300 - { 301 - "id": 28, 302 - "change_id": "b022604c-fe3a-4ab0-8863-bfb0b641af49", 303 - "node_type": "goal", 304 - "title": "Replace custom date formatting with date-fns library", 305 - "description": null, 306 - "status": "completed", 307 - "created_at": "2025-12-23T00:31:20.958877100-05:00", 308 - "updated_at": "2025-12-24T16:16:53.437106400-05:00", 309 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95,\"prompt\":\"fix #4\"}" 310 - }, 311 - { 312 - "id": 29, 313 - "change_id": "e6db1fc5-62e1-4092-85db-ae8a6767882f", 314 - "node_type": "action", 315 - "title": "Reading current date.ts implementation", 316 - "description": null, 317 - "status": "completed", 318 - "created_at": "2025-12-23T00:31:22.590022300-05:00", 319 - "updated_at": "2025-12-24T16:16:04.298586400-05:00", 320 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"files\":[\"src/lib/utils/date.ts\"]}" 321 - }, 322 - { 323 - "id": 30, 324 - "change_id": "ce6b969f-f167-4370-826c-f053922df20d", 325 - "node_type": "observation", 326 - "title": "Custom date formatting with 2 functions: formatDate (toLocaleDateString) and formatRelativeTime (manual ms calculations). 27 lines of custom logic that date-fns handles better.", 327 - "description": null, 328 - "status": "completed", 329 - "created_at": "2025-12-23T00:31:38.159002400-05:00", 330 - "updated_at": "2025-12-24T16:16:04.359940700-05:00", 331 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95,\"files\":[\"src/lib/utils/date.ts\"]}" 332 - }, 333 - { 334 - "id": 31, 335 - "change_id": "fbf37117-f225-40a9-b563-011b3e0b118a", 336 - "node_type": "action", 337 - "title": "Installing date-fns package", 338 - "description": null, 339 - "status": "completed", 340 - "created_at": "2025-12-23T00:31:54.278956500-05:00", 341 - "updated_at": "2025-12-24T16:16:04.420763100-05:00", 342 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 343 - }, 344 - { 345 - "id": 32, 346 - "change_id": "7168cc35-a99a-4b6d-a6d3-000a1040a2f0", 347 - "node_type": "outcome", 348 - "title": "Successfully installed date-fns package", 349 - "description": null, 350 - "status": "completed", 351 - "created_at": "2025-12-23T00:34:03.450685-05:00", 352 - "updated_at": "2025-12-24T16:16:04.482131300-05:00", 353 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 354 - }, 355 - { 356 - "id": 33, 357 - "change_id": "2a443551-bd2f-40a6-9464-8de496a248b4", 358 - "node_type": "action", 359 - "title": "Replacing custom date functions with date-fns in date.ts and fixing HistoryTab.tsx", 360 - "description": null, 361 - "status": "completed", 362 - "created_at": "2025-12-23T00:34:06.381483900-05:00", 363 - "updated_at": "2025-12-24T16:16:04.543323800-05:00", 364 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"files\":[\"src/lib/utils/date.ts\",\"src/components/HistoryTab.tsx\"]}" 365 - }, 366 - { 367 - "id": 34, 368 - "change_id": "1aea7359-8009-40e1-a75a-78a3c31ec0ee", 369 - "node_type": "outcome", 370 - "title": "Successfully replaced custom date formatting with date-fns. Reduced from 27 lines to 11 lines. Fixed bug in HistoryTab.tsx where formatDate was incorrectly converting dates.", 371 - "description": null, 372 - "status": "completed", 373 - "created_at": "2025-12-23T00:34:58.706981500-05:00", 374 - "updated_at": "2025-12-24T16:16:04.605649-05:00", 375 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95,\"files\":[\"src/lib/utils/date.ts\",\"src/components/HistoryTab.tsx\"]}" 376 - }, 377 - { 378 - "id": 35, 379 - "change_id": "9a55a4c5-c1f3-4475-98b2-c0c7f02ea48e", 380 - "node_type": "goal", 381 - "title": "Replace custom validation with Zod schemas", 382 - "description": null, 383 - "status": "completed", 384 - "created_at": "2025-12-23T00:37:17.894369-05:00", 385 - "updated_at": "2025-12-24T16:16:53.501617500-05:00", 386 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95,\"prompt\":\"fix #5\"}" 387 - }, 388 - { 389 - "id": 36, 390 - "change_id": "bb55eb60-dd7f-479c-93a1-bf95fed58de0", 391 - "node_type": "action", 392 - "title": "Reading current validation.ts implementation", 393 - "description": null, 394 - "status": "completed", 395 - "created_at": "2025-12-23T00:37:19.640126500-05:00", 396 - "updated_at": "2025-12-24T16:16:04.670106300-05:00", 397 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"files\":[\"src/lib/validation.ts\"]}" 398 - }, 399 - { 400 - "id": 37, 401 - "change_id": "6350c610-e3cc-4f18-8d98-42adedd8459b", 402 - "node_type": "observation", 403 - "title": "Custom validation with 5 functions totaling 142 lines. Returns custom ValidationResult interface. No type inference, manual error messages, repetitive patterns. Zod would provide type safety + schema composition.", 404 - "description": null, 405 - "status": "completed", 406 - "created_at": "2025-12-23T00:37:37.922000700-05:00", 407 - "updated_at": "2025-12-24T16:16:04.734940700-05:00", 408 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95,\"files\":[\"src/lib/validation.ts\"]}" 409 - }, 410 - { 411 - "id": 38, 412 - "change_id": "e6bc1cd1-d51b-4410-a7d6-b25e24c14398", 413 - "node_type": "decision", 414 - "title": "Choose Zod integration strategy: wrap Zod in ValidationResult vs replace useFormValidation vs use react-hook-form", 415 - "description": null, 416 - "status": "completed", 417 - "created_at": "2025-12-23T00:38:10.152854400-05:00", 418 - "updated_at": "2025-12-24T16:16:22.562023300-05:00", 419 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 420 - }, 421 - { 422 - "id": 39, 423 - "change_id": "8754ba8f-6c78-453c-995b-2ac67e5bc44b", 424 - "node_type": "option", 425 - "title": "Wrap Zod schemas to return ValidationResult - maintains backward compatibility", 426 - "description": null, 427 - "status": "completed", 428 - "created_at": "2025-12-23T00:38:13.195992700-05:00", 429 - "updated_at": "2025-12-24T16:16:22.639785600-05:00", 430 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 431 - }, 432 - { 433 - "id": 40, 434 - "change_id": "bb8db74f-f1a3-44b7-bfd6-73a040e712f1", 435 - "node_type": "option", 436 - "title": "Modify useFormValidation to work directly with Zod schemas", 437 - "description": null, 438 - "status": "completed", 439 - "created_at": "2025-12-23T00:38:15.211052400-05:00", 440 - "updated_at": "2025-12-24T16:16:22.716820900-05:00", 441 - "metadata_json": "{\"branch\":\"master\",\"confidence\":70}" 442 - }, 443 - { 444 - "id": 41, 445 - "change_id": "b5817928-cabe-4dcc-843c-3b7278a0fb4c", 446 - "node_type": "option", 447 - "title": "Replace with react-hook-form + Zod resolver", 448 - "description": null, 449 - "status": "completed", 450 - "created_at": "2025-12-23T00:38:17.043346600-05:00", 451 - "updated_at": "2025-12-24T16:16:22.796829700-05:00", 452 - "metadata_json": "{\"branch\":\"master\",\"confidence\":60}" 453 - }, 454 - { 455 - "id": 42, 456 - "change_id": "6a0dc295-b19e-4889-8980-767cfd49e258", 457 - "node_type": "outcome", 458 - "title": "Chose option A: Wrap Zod schemas in ValidationResult interface. Provides Zod benefits (type safety, composability) while maintaining existing useFormValidation API. Zero breaking changes.", 459 - "description": null, 460 - "status": "completed", 461 - "created_at": "2025-12-23T00:38:29.141881500-05:00", 462 - "updated_at": "2025-12-24T16:16:04.799054700-05:00", 463 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 464 - }, 465 - { 466 - "id": 43, 467 - "change_id": "0423e6ea-2491-44bb-bf0a-16c67085826c", 468 - "node_type": "action", 469 - "title": "Installing zod package", 470 - "description": null, 471 - "status": "completed", 472 - "created_at": "2025-12-23T00:38:33.152791300-05:00", 473 - "updated_at": "2025-12-24T16:16:04.863242100-05:00", 474 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 475 - }, 476 - { 477 - "id": 44, 478 - "change_id": "8ada1961-6fdd-4eaa-a6db-1bcc78da914d", 479 - "node_type": "outcome", 480 - "title": "Successfully installed zod package", 481 - "description": null, 482 - "status": "completed", 483 - "created_at": "2025-12-23T00:39:02.762606100-05:00", 484 - "updated_at": "2025-12-24T16:16:04.927366600-05:00", 485 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 486 - }, 487 - { 488 - "id": 45, 489 - "change_id": "32f3ede8-5d4d-4764-84f5-55e69f11ed81", 490 - "node_type": "action", 491 - "title": "Refactoring validation.ts to use Zod schemas with ValidationResult wrapper", 492 - "description": null, 493 - "status": "completed", 494 - "created_at": "2025-12-23T00:39:06.040655-05:00", 495 - "updated_at": "2025-12-24T16:16:04.996586800-05:00", 496 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"files\":[\"src/lib/validation.ts\"]}" 497 - }, 498 - { 499 - "id": 46, 500 - "change_id": "620eaba1-4306-4cd5-abe7-07ea82e17ca4", 501 - "node_type": "outcome", 502 - "title": "Successfully refactored validation.ts to use Zod. Reduced from 142 to 116 lines. Maintained API compatibility. Added type-safe schemas with better error messages and composability.", 503 - "description": null, 504 - "status": "completed", 505 - "created_at": "2025-12-23T00:39:38.146899400-05:00", 506 - "updated_at": "2025-12-24T16:16:05.064301900-05:00", 507 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95,\"files\":[\"src/lib/validation.ts\"]}" 508 - }, 509 - { 510 - "id": 47, 511 - "change_id": "d0845848-9edf-4cfd-b770-457be0a6c11d", 512 - "node_type": "action", 513 - "title": "Creating plan.md for remaining optimizations", 514 - "description": null, 515 - "status": "completed", 516 - "created_at": "2025-12-23T00:50:17.383831900-05:00", 517 - "updated_at": "2025-12-24T16:16:05.128275200-05:00", 518 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"files\":[\"plan.md\"]}" 519 - }, 520 - { 521 - "id": 48, 522 - "change_id": "44b3b8eb-4676-4a29-afa9-a2aab3e8c9a8", 523 - "node_type": "outcome", 524 - "title": "Successfully created plan.md documenting 12 optimization tasks, 5 completed, 7 remaining. Includes priority levels, effort estimates, implementation order, and testing checklist.", 525 - "description": null, 526 - "status": "completed", 527 - "created_at": "2025-12-23T00:50:33.372643700-05:00", 528 - "updated_at": "2025-12-24T16:16:05.193304700-05:00", 529 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95,\"files\":[\"plan.md\"]}" 530 - }, 531 - { 532 - "id": 49, 533 - "change_id": "31331aa1-1938-479f-8527-65346d2fa764", 534 - "node_type": "goal", 535 - "title": "Optimize ATlast codebase: fix performance issues, eliminate code inefficiencies, enforce DRY principles, adopt standard practices", 536 - "description": null, 537 - "status": "completed", 538 - "created_at": "2025-12-23T00:50:36.438231400-05:00", 539 - "updated_at": "2025-12-24T16:16:53.561781-05:00", 540 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100,\"prompt\":\"Anaylze the code base to identify execution inefficiencies, code inefficiencies due to custom-coded implementations where existing packages may perform better, failure to comply with DRY principles, and non-standard practices for code bases with its technologies.\"}" 541 - }, 542 - { 543 - "id": 50, 544 - "change_id": "9ee094c0-c179-4350-a9bb-cd67f5fdd3af", 545 - "node_type": "observation", 546 - "title": "Session 1 complete: 5 of 12 optimizations finished. Performance gains: 5x faster follows, 50% fewer re-renders. Code quality: replaced 169 lines of custom code with battle-tested libraries (date-fns, zod). All goals linked to master optimization goal.", 547 - "description": null, 548 - "status": "completed", 549 - "created_at": "2025-12-23T14:23:52.428288600-05:00", 550 - "updated_at": "2025-12-24T16:16:05.256752300-05:00", 551 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 552 - }, 553 - { 554 - "id": 51, 555 - "change_id": "a5d144e1-535a-4d6e-89dc-8800813fca72", 556 - "node_type": "outcome", 557 - "title": "Recreated PLAN.md (uppercase) after accidental deletion", 558 - "description": null, 559 - "status": "completed", 560 - "created_at": "2025-12-23T14:56:59.128500900-05:00", 561 - "updated_at": "2025-12-24T16:16:05.318502200-05:00", 562 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100,\"files\":[\"PLAN.md\"]}" 563 - }, 564 - { 565 - "id": 52, 566 - "change_id": "c047c9ac-eccb-4545-ad40-b40292d8e39c", 567 - "node_type": "goal", 568 - "title": "Fix inefficient follow status check - add early exit when all DIDs found", 569 - "description": null, 570 - "status": "completed", 571 - "created_at": "2025-12-23T15:06:40.950801500-05:00", 572 - "updated_at": "2025-12-24T16:16:53.625670500-05:00", 573 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"prompt\":\"User asked: pushed changes. yes, start with #6\\n\\nContext: Optimization #6 from PLAN.md - FollowService fetches ALL follow records even when checking only 10 DIDs. Need to add early exit after finding all target DIDs to reduce API calls from ~50 to ~1-2.\"}" 574 - }, 575 - { 576 - "id": 53, 577 - "change_id": "8c19132d-7a6b-4103-92f7-d8899e89819a", 578 - "node_type": "action", 579 - "title": "Reading FollowService.ts to understand current follow status check implementation", 580 - "description": null, 581 - "status": "completed", 582 - "created_at": "2025-12-23T15:06:45.574037700-05:00", 583 - "updated_at": "2025-12-24T16:16:05.379881-05:00", 584 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 585 - }, 586 - { 587 - "id": 54, 588 - "change_id": "f98802fa-4302-401e-8e10-a31f241cc912", 589 - "node_type": "observation", 590 - "title": "Early exit optimization already implemented! Lines 38 (loop condition) and 59-61 (explicit break) both handle early exit when all DIDs found. didsSet.delete() on line 51 tracks found DIDs. No changes needed.", 591 - "description": null, 592 - "status": "completed", 593 - "created_at": "2025-12-23T15:07:07.424848-05:00", 594 - "updated_at": "2025-12-24T16:16:05.442879300-05:00", 595 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 596 - }, 597 - { 598 - "id": 55, 599 - "change_id": "71c3ad1c-3194-4b3c-8b29-a28187d092cd", 600 - "node_type": "outcome", 601 - "title": "Optimization #6 already complete - no changes needed. Early exit logic properly implemented with dual safeguards (loop condition + explicit break). Code already optimal.", 602 - "description": null, 603 - "status": "completed", 604 - "created_at": "2025-12-23T15:07:18.197533300-05:00", 605 - "updated_at": "2025-12-24T16:16:05.501550200-05:00", 606 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 607 - }, 608 - { 609 - "id": 56, 610 - "change_id": "5c435252-d5f5-44bb-a11b-60be41faf611", 611 - "node_type": "goal", 612 - "title": "Extract duplicate validation logic into utility function", 613 - "description": null, 614 - "status": "completed", 615 - "created_at": "2025-12-23T15:09:30.859474400-05:00", 616 - "updated_at": "2025-12-24T16:16:53.689525900-05:00", 617 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"prompt\":\"Optimization #7 from PLAN.md: Same array validation pattern repeated 8+ times across Netlify functions. Need to create utility function for DRY principle and consistent error messages.\"}" 618 - }, 619 - { 620 - "id": 57, 621 - "change_id": "d6259df0-3a53-42e9-bbf9-77eb220fb8b8", 622 - "node_type": "action", 623 - "title": "Searching for duplicate array validation patterns in netlify/functions/", 624 - "description": null, 625 - "status": "completed", 626 - "created_at": "2025-12-23T15:09:35.649290300-05:00", 627 - "updated_at": "2025-12-24T16:16:05.577614600-05:00", 628 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 629 - }, 630 - { 631 - "id": 58, 632 - "change_id": "94a34242-7d31-405e-b1b7-ad1b456954b6", 633 - "node_type": "observation", 634 - "title": "Found 3 files with duplicate validation: batch-follow-users.ts (lines 13-19, dids max 100), check-follow-status.ts (lines 12-18, dids max 100), batch-search-actors.ts (lines 12-20, usernames max 50). Same pattern: isArray check, length > 0, max length.", 635 - "description": null, 636 - "status": "completed", 637 - "created_at": "2025-12-23T15:10:25.769666600-05:00", 638 - "updated_at": "2025-12-24T16:16:05.654710700-05:00", 639 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 640 - }, 641 - { 642 - "id": 59, 643 - "change_id": "a9af8b98-06d6-4cb5-adde-97c38daabb72", 644 - "node_type": "decision", 645 - "title": "Choose validation utility design: generic function vs class-based validators vs Zod backend schemas", 646 - "description": null, 647 - "status": "completed", 648 - "created_at": "2025-12-23T15:11:55.535915900-05:00", 649 - "updated_at": "2025-12-24T16:16:22.874373300-05:00", 650 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 651 - }, 652 - { 653 - "id": 60, 654 - "change_id": "a51e3154-2cf7-49eb-a4c9-5bd1108db5b7", 655 - "node_type": "option", 656 - "title": "Generic validateArrayInput<T>() function - simple, matches existing utils pattern", 657 - "description": null, 658 - "status": "completed", 659 - "created_at": "2025-12-23T15:16:03.351511600-05:00", 660 - "updated_at": "2025-12-24T16:16:22.949962600-05:00", 661 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 662 - }, 663 - { 664 - "id": 61, 665 - "change_id": "13982cbf-a6ce-4216-ae4a-2d11b543df14", 666 - "node_type": "option", 667 - "title": "Extend Zod to backend - consistent with frontend but adds dependency", 668 - "description": null, 669 - "status": "completed", 670 - "created_at": "2025-12-23T15:16:07.915736-05:00", 671 - "updated_at": "2025-12-24T16:16:23.030802600-05:00", 672 - "metadata_json": "{\"branch\":\"master\",\"confidence\":70}" 673 - }, 674 - { 675 - "id": 62, 676 - "change_id": "2a441228-42e2-410a-931d-a70cac938cb8", 677 - "node_type": "outcome", 678 - "title": "Chose option A: Generic function. Reason: Matches existing utils pattern (simple exports), no new deps, low complexity, directly solves duplication. Zod would be overkill for simple array checks.", 679 - "description": null, 680 - "status": "completed", 681 - "created_at": "2025-12-23T15:16:12.514984600-05:00", 682 - "updated_at": "2025-12-24T16:16:05.721109400-05:00", 683 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 684 - }, 685 - { 686 - "id": 63, 687 - "change_id": "12297d1b-f757-4307-898a-3913e54599a7", 688 - "node_type": "outcome", 689 - "title": "Changed decision: Use Zod for backend validation. Reason: Already installed from frontend work, provides type safety, schema composition, better error messages. Consistent with modern practices.", 690 - "description": null, 691 - "status": "completed", 692 - "created_at": "2025-12-23T15:17:23.428158100-05:00", 693 - "updated_at": "2025-12-24T16:16:05.787503400-05:00", 694 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 695 - }, 696 - { 697 - "id": 64, 698 - "change_id": "110b0df4-2d27-4920-a722-28a7bb309c1f", 699 - "node_type": "action", 700 - "title": "Creating validation.utils.ts with Zod schemas for array validation", 701 - "description": null, 702 - "status": "completed", 703 - "created_at": "2025-12-23T15:17:27.863664900-05:00", 704 - "updated_at": "2025-12-24T16:16:05.853523600-05:00", 705 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 706 - }, 707 - { 708 - "id": 65, 709 - "change_id": "6a128a77-e514-4b6a-aeb7-20bd0159a0f3", 710 - "node_type": "action", 711 - "title": "Updating 3 files to use Zod validation: batch-follow-users, check-follow-status, batch-search-actors", 712 - "description": null, 713 - "status": "completed", 714 - "created_at": "2025-12-23T15:18:41.034460700-05:00", 715 - "updated_at": "2025-12-24T16:16:05.935274700-05:00", 716 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"files\":[\"netlify/functions/batch-follow-users.ts\",\"netlify/functions/check-follow-status.ts\",\"netlify/functions/batch-search-actors.ts\"]}" 717 - }, 718 - { 719 - "id": 66, 720 - "change_id": "a139806c-7a1a-4c18-8199-558f765670c4", 721 - "node_type": "outcome", 722 - "title": "Successfully replaced duplicate validation with Zod. Created validation.utils.ts with reusable schemas. Updated 3 files (batch-follow-users, check-follow-status, batch-search-actors). Reduced duplication, improved type safety. Build passes.", 723 - "description": null, 724 - "status": "completed", 725 - "created_at": "2025-12-23T15:24:47.216285700-05:00", 726 - "updated_at": "2025-12-24T16:16:06.014177600-05:00", 727 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95,\"files\":[\"netlify/functions/utils/validation.utils.ts\",\"netlify/functions/batch-follow-users.ts\",\"netlify/functions/check-follow-status.ts\",\"netlify/functions/batch-search-actors.ts\"]}" 728 - }, 729 - { 730 - "id": 67, 731 - "change_id": "6aef16a0-0524-4ad9-a8ff-b335069c860d", 732 - "node_type": "action", 733 - "title": "Reading Results.tsx to identify duplicate type definitions", 734 - "description": null, 735 - "status": "completed", 736 - "created_at": "2025-12-23T15:46:50.835459600-05:00", 737 - "updated_at": "2025-12-24T16:16:06.080248500-05:00", 738 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 739 - }, 740 - { 741 - "id": 68, 742 - "change_id": "10c05711-9c49-47d8-b032-caa6e3bc887e", 743 - "node_type": "action", 744 - "title": "Committed optimizations #6 and #7", 745 - "description": null, 746 - "status": "completed", 747 - "created_at": "2025-12-23T15:58:41.016251900-05:00", 748 - "updated_at": "2025-12-24T16:16:06.139903800-05:00", 749 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"093b47d\",\"confidence\":100}" 750 - }, 751 - { 752 - "id": 69, 753 - "change_id": "5754ca49-f09b-489f-a4b0-f412159f4cd4", 754 - "node_type": "goal", 755 - "title": "Remove duplicate type definitions - use central type files", 756 - "description": null, 757 - "status": "completed", 758 - "created_at": "2025-12-23T15:59:33.110529100-05:00", 759 - "updated_at": "2025-12-24T16:16:53.749544400-05:00", 760 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"prompt\":\"Optimization #8 from PLAN.md: Types redefined locally in Results.tsx that exist in central type files (atprotoSession, SearchResult). Need to remove duplicates and import from src/types for single source of truth to prevent type drift.\"}" 761 - }, 762 - { 763 - "id": 70, 764 - "change_id": "e14bd69e-6821-4586-b96d-0ef16490c803", 765 - "node_type": "action", 766 - "title": "Comparing Results.tsx type definitions with src/types/index.ts", 767 - "description": null, 768 - "status": "completed", 769 - "created_at": "2025-12-23T15:59:38.186338800-05:00", 770 - "updated_at": "2025-12-24T16:16:06.200517300-05:00", 771 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 772 - }, 773 - { 774 - "id": 71, 775 - "change_id": "0a4aa61e-96d5-4606-b088-39161105dc82", 776 - "node_type": "observation", 777 - "title": "Found 3 duplicate type definitions in Results.tsx: atprotoSession (should be AtprotoSession from auth.types), SourceUser (exact match in search.types), SearchResult (exact match in search.types). All can be imported from central types.", 778 - "description": null, 779 - "status": "completed", 780 - "created_at": "2025-12-23T16:00:18.257643800-05:00", 781 - "updated_at": "2025-12-24T16:16:06.275102-05:00", 782 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 783 - }, 784 - { 785 - "id": 72, 786 - "change_id": "25010f9a-2b6a-4a72-80ac-8449710ad222", 787 - "node_type": "action", 788 - "title": "Removing duplicate types from Results.tsx and importing from central types", 789 - "description": null, 790 - "status": "completed", 791 - "created_at": "2025-12-23T16:00:30.964264400-05:00", 792 - "updated_at": "2025-12-24T16:16:06.336968800-05:00", 793 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"files\":[\"src/pages/Results.tsx\"]}" 794 - }, 795 - { 796 - "id": 73, 797 - "change_id": "9ec33280-3c44-4e86-a133-aa3e1e839927", 798 - "node_type": "outcome", 799 - "title": "Successfully removed 3 duplicate type definitions from Results.tsx (atprotoSession, SourceUser, SearchResult). Now imports from central types (AtprotoSession, SearchResult). Prevents type drift. Build passes.", 800 - "description": null, 801 - "status": "completed", 802 - "created_at": "2025-12-23T16:06:47.345117500-05:00", 803 - "updated_at": "2025-12-24T16:16:06.396688400-05:00", 804 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100,\"files\":[\"src/pages/Results.tsx\"]}" 805 - }, 806 - { 807 - "id": 74, 808 - "change_id": "1f337abb-4b6f-486e-a7d0-3ce0c014952a", 809 - "node_type": "action", 810 - "title": "Committed optimization #8", 811 - "description": null, 812 - "status": "completed", 813 - "created_at": "2025-12-23T16:09:39.504709200-05:00", 814 - "updated_at": "2025-12-24T16:16:06.457715900-05:00", 815 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"65ac856\",\"confidence\":100}" 816 - }, 817 - { 818 - "id": 75, 819 - "change_id": "54175447-ee48-47a2-91b3-0dc01b00ce2f", 820 - "node_type": "observation", 821 - "title": "Session 2 complete: Optimizations #6, #7, #8 finished. #6 already done, #7 added Zod validation (reduced duplication), #8 removed duplicate types. 8 of 12 optimizations now complete.", 822 - "description": null, 823 - "status": "completed", 824 - "created_at": "2025-12-23T16:10:02.032621900-05:00", 825 - "updated_at": "2025-12-24T16:16:06.520328100-05:00", 826 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 827 - }, 828 - { 829 - "id": 76, 830 - "change_id": "557cb7ea-db8d-41f9-910d-2cfc3c1f221d", 831 - "node_type": "goal", 832 - "title": "Replace excessive any types with AT Protocol interfaces", 833 - "description": null, 834 - "status": "completed", 835 - "created_at": "2025-12-23T17:57:28.124648600-05:00", 836 - "updated_at": "2025-12-24T16:16:53.812618200-05:00", 837 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"prompt\":\"Optimization #9 from PLAN.md: 6+ Netlify functions use `any` types for AT Protocol responses (response.data.actors.map((actor: any) => ...)). Need to define proper ATProtoActor and ATProtoSearchResponse interfaces for type safety and better IDE support.\"}" 838 - }, 839 - { 840 - "id": 77, 841 - "change_id": "44915a01-c89b-4c75-b370-b1860400d262", 842 - "node_type": "action", 843 - "title": "Searching for any type usage in netlify/functions/", 844 - "description": null, 845 - "status": "completed", 846 - "created_at": "2025-12-23T18:00:40.715233-05:00", 847 - "updated_at": "2025-12-24T16:16:06.598178300-05:00", 848 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 849 - }, 850 - { 851 - "id": 78, 852 - "change_id": "5d181171-7525-4304-8185-0e0a6f95ef4f", 853 - "node_type": "observation", 854 - "title": "Found 20+ any types across 9 files. Main issues: batch-search-actors.ts (7 actor/profile any types), core OAuth types (dpopKey, tokenSet - from @atproto libs, can stay any), database types (2 files). Focus on AT Protocol actor/profile interfaces.", 855 - "description": null, 856 - "status": "completed", 857 - "created_at": "2025-12-23T18:01:58.164011900-05:00", 858 - "updated_at": "2025-12-24T16:16:06.659264300-05:00", 859 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 860 - }, 861 - { 862 - "id": 79, 863 - "change_id": "6afe3ed4-b165-418f-9ad7-24a43593c5b5", 864 - "node_type": "action", 865 - "title": "Creating AT Protocol type interfaces in netlify/functions/types/atproto.types.ts", 866 - "description": null, 867 - "status": "completed", 868 - "created_at": "2025-12-23T18:02:17.601819900-05:00", 869 - "updated_at": "2025-12-24T16:16:06.724525200-05:00", 870 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 871 - }, 872 - { 873 - "id": 80, 874 - "change_id": "b7f96cec-120b-4001-94e7-0e85e3e21ba5", 875 - "node_type": "action", 876 - "title": "Updating batch-search-actors.ts to use AT Protocol types", 877 - "description": null, 878 - "status": "completed", 879 - "created_at": "2025-12-23T18:02:53.018555100-05:00", 880 - "updated_at": "2025-12-24T16:16:06.791429600-05:00", 881 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"files\":[\"netlify/functions/batch-search-actors.ts\"]}" 882 - }, 883 - { 884 - "id": 81, 885 - "change_id": "aad16dbf-1aa6-41e4-bff2-2a64d228233d", 886 - "node_type": "outcome", 887 - "title": "Successfully replaced 7 any types in batch-search-actors.ts with AT Protocol interfaces. Created atproto.types.ts with ATProtoActor, ATProtoProfile, RankedActor, EnrichedActor. Improved type safety and IDE support. Build passes.", 888 - "description": null, 889 - "status": "completed", 890 - "created_at": "2025-12-23T18:10:19.387547900-05:00", 891 - "updated_at": "2025-12-24T16:16:06.871045100-05:00", 892 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95,\"files\":[\"netlify/functions/core/types/atproto.types.ts\",\"netlify/functions/batch-search-actors.ts\"]}" 893 - }, 894 - { 895 - "id": 82, 896 - "change_id": "af29c2c8-9bf6-4b3d-8f48-34e94074ce7f", 897 - "node_type": "action", 898 - "title": "Committed optimization #9", 899 - "description": null, 900 - "status": "completed", 901 - "created_at": "2025-12-23T18:11:40.473776700-05:00", 902 - "updated_at": "2025-12-24T16:16:06.932435800-05:00", 903 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"4371026\",\"confidence\":100}" 904 - }, 905 - { 906 - "id": 83, 907 - "change_id": "582f617e-c13a-4643-88ad-a7ed9941c3e7", 908 - "node_type": "goal", 909 - "title": "Replace direct localStorage usage with zustand persist middleware", 910 - "description": null, 911 - "status": "completed", 912 - "created_at": "2025-12-23T18:46:51.110946500-05:00", 913 - "updated_at": "2025-12-24T16:16:53.877378500-05:00", 914 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"prompt\":\"Optimization #10 from PLAN.md: SettingsContext.tsx uses manual localStorage with JSON parse/stringify, no SSR checks, no tab sync. Replace with zustand + persist middleware for type safety, SSR compatibility, cross-tab sync, and less boilerplate.\"}" 915 - }, 916 - { 917 - "id": 84, 918 - "change_id": "62c63a96-f0da-4cee-8dfb-e691ebd01fef", 919 - "node_type": "action", 920 - "title": "Reading current SettingsContext.tsx implementation", 921 - "description": null, 922 - "status": "completed", 923 - "created_at": "2025-12-23T18:46:56.642863100-05:00", 924 - "updated_at": "2025-12-24T16:16:06.993561300-05:00", 925 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 926 - }, 927 - { 928 - "id": 85, 929 - "change_id": "d07dc9e0-4a15-4b6a-837f-af7522a658d3", 930 - "node_type": "observation", 931 - "title": "Current implementation: 88 lines, manual localStorage (lines 43, 59, 72), JSON parse/stringify, no SSR checks, 2 useEffects, isLoading state. Context exports: settings, updateSettings, resetSettings, isLoading.", 932 - "description": null, 933 - "status": "completed", 934 - "created_at": "2025-12-23T18:47:19.683239-05:00", 935 - "updated_at": "2025-12-24T16:16:07.051584500-05:00", 936 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 937 - }, 938 - { 939 - "id": 86, 940 - "change_id": "9c4b383c-b743-4f6b-a551-8e568a68b854", 941 - "node_type": "action", 942 - "title": "Installing zustand package", 943 - "description": null, 944 - "status": "completed", 945 - "created_at": "2025-12-23T18:47:27.959087700-05:00", 946 - "updated_at": "2025-12-24T16:16:07.116912800-05:00", 947 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 948 - }, 949 - { 950 - "id": 87, 951 - "change_id": "557b339e-2aeb-4eef-b8f5-6ce93bdf7f61", 952 - "node_type": "action", 953 - "title": "Creating zustand store in src/stores/useSettingsStore.ts", 954 - "description": null, 955 - "status": "completed", 956 - "created_at": "2025-12-23T18:52:25.776831100-05:00", 957 - "updated_at": "2025-12-24T16:16:07.180030-05:00", 958 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 959 - }, 960 - { 961 - "id": 88, 962 - "change_id": "39f0e1dd-dae2-48d8-926d-491b05419b3d", 963 - "node_type": "action", 964 - "title": "Updating App.tsx to use zustand store instead of context", 965 - "description": null, 966 - "status": "completed", 967 - "created_at": "2025-12-23T18:53:20.360682600-05:00", 968 - "updated_at": "2025-12-24T16:16:07.245309200-05:00", 969 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"files\":[\"src/App.tsx\"]}" 970 - }, 971 - { 972 - "id": 89, 973 - "change_id": "a2e92cda-43cb-4659-a8be-512c2bf2feb4", 974 - "node_type": "outcome", 975 - "title": "Successfully replaced localStorage context with zustand. Created useSettingsStore with persist middleware. Removed SettingsContext (88 lines), added zustand store (66 lines). Features: SSR-safe, cross-tab sync, auto JSON serialization, type-safe. Build passes, bundle +2.3KB.", 976 - "description": null, 977 - "status": "completed", 978 - "created_at": "2025-12-23T19:05:06.189375800-05:00", 979 - "updated_at": "2025-12-24T16:16:07.309161700-05:00", 980 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95,\"files\":[\"src/stores/useSettingsStore.ts\",\"src/App.tsx\",\"src/main.tsx\"]}" 981 - }, 982 - { 983 - "id": 90, 984 - "change_id": "52b07eae-66e2-4bfd-8bdc-dcf940b50095", 985 - "node_type": "action", 986 - "title": "Committed optimization #10", 987 - "description": null, 988 - "status": "completed", 989 - "created_at": "2025-12-23T19:06:56.082106400-05:00", 990 - "updated_at": "2025-12-24T16:16:07.374354400-05:00", 991 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"6b5cf20\",\"confidence\":100}" 992 - }, 993 - { 994 - "id": 91, 995 - "change_id": "a981ce23-a49d-46fb-8291-ce540551bb1b", 996 - "node_type": "goal", 997 - "title": "Move inline animations to Tailwind config", 998 - "description": null, 999 - "status": "completed", 1000 - "created_at": "2025-12-23T19:08:53.210004400-05:00", 1001 - "updated_at": "2025-12-24T16:16:53.936430900-05:00", 1002 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"prompt\":\"Optimization #11 from PLAN.md: Results.tsx uses inline style animations with Math.random() instead of defining them in tailwind.config.js. Need to move animations to config for consistency with Tailwind conventions and easier maintenance.\"}" 1003 - }, 1004 - { 1005 - "id": 92, 1006 - "change_id": "28492b66-8405-4c7e-a80a-c874e2bdb391", 1007 - "node_type": "action", 1008 - "title": "Reading Results.tsx to locate inline animation styles", 1009 - "description": null, 1010 - "status": "completed", 1011 - "created_at": "2025-12-23T19:08:55.970364200-05:00", 1012 - "updated_at": "2025-12-24T16:16:07.435075300-05:00", 1013 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 1014 - }, 1015 - { 1016 - "id": 93, 1017 - "change_id": "145cfde7-8444-4ef1-b8e0-0659de30a5b2", 1018 - "node_type": "observation", 1019 - "title": "Found inline animation at lines 107-112: Firefly component with Math.random() for animation duration (2-3s) and delay (0-1s). Uses float animation with ease-in-out. Need to define float keyframes in Tailwind config and create animation variants.", 1020 - "description": null, 1021 - "status": "completed", 1022 - "created_at": "2025-12-23T19:09:14.794172400-05:00", 1023 - "updated_at": "2025-12-24T16:16:07.495486300-05:00", 1024 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1025 - }, 1026 - { 1027 - "id": 94, 1028 - "change_id": "ade1253d-4dcb-4a30-bf41-d8c8cbfb99b9", 1029 - "node_type": "action", 1030 - "title": "Updating tailwind.config.js to add float animation keyframes and variants", 1031 - "description": null, 1032 - "status": "completed", 1033 - "created_at": "2025-12-23T19:09:30.566533800-05:00", 1034 - "updated_at": "2025-12-24T16:16:07.571931400-05:00", 1035 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"files\":[\"tailwind.config.js\"]}" 1036 - }, 1037 - { 1038 - "id": 95, 1039 - "change_id": "4471c934-81e1-413b-83ce-0860b5f629e0", 1040 - "node_type": "action", 1041 - "title": "Updating Results.tsx to use Tailwind animation classes", 1042 - "description": null, 1043 - "status": "completed", 1044 - "created_at": "2025-12-23T19:09:48.857273300-05:00", 1045 - "updated_at": "2025-12-24T16:16:07.647593100-05:00", 1046 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"files\":[\"src/pages/Results.tsx\"]}" 1047 - }, 1048 - { 1049 - "id": 96, 1050 - "change_id": "214a1dab-def7-4e0d-9c9f-333713753b4c", 1051 - "node_type": "outcome", 1052 - "title": "Successfully moved inline animations to Tailwind config. Added 3 animation variants (float-1, float-2, float-3) with different durations/delays. Replaced inline style object with Tailwind classes. Reduced inline styles from 2 properties to 0 (kept positioning). CSS +180 bytes.", 1053 - "description": null, 1054 - "status": "completed", 1055 - "created_at": "2025-12-23T19:11:26.307592500-05:00", 1056 - "updated_at": "2025-12-24T16:16:07.729253300-05:00", 1057 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95,\"files\":[\"tailwind.config.js\",\"src/pages/Results.tsx\"]}" 1058 - }, 1059 - { 1060 - "id": 97, 1061 - "change_id": "85f0bd33-5e62-4889-b14d-c365b2c389c3", 1062 - "node_type": "action", 1063 - "title": "Committed optimization #11", 1064 - "description": null, 1065 - "status": "completed", 1066 - "created_at": "2025-12-23T19:12:02.797882300-05:00", 1067 - "updated_at": "2025-12-24T16:16:07.792009200-05:00", 1068 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"35061ae\",\"confidence\":100}" 1069 - }, 1070 - { 1071 - "id": 98, 1072 - "change_id": "c7dea418-336e-4696-84f2-d7cb09edd3f6", 1073 - "node_type": "action", 1074 - "title": "Analyzing rate limiting requirements and options for user decision", 1075 - "description": null, 1076 - "status": "completed", 1077 - "created_at": "2025-12-23T19:15:12.175078900-05:00", 1078 - "updated_at": "2025-12-24T16:16:07.854168700-05:00", 1079 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 1080 - }, 1081 - { 1082 - "id": 99, 1083 - "change_id": "7839b10b-c5e0-4179-8590-7fe7b2ef132d", 1084 - "node_type": "observation", 1085 - "title": "Rate limiting analysis: 2 vulnerable endpoints (batch-search-actors: ~50 API calls, batch-follow-users: ~100 API calls). Risk: abuse could trigger AT Protocol rate limits on app. 3 options: Netlify built-in, Upstash Redis, or in-memory (dev only).", 1086 - "description": null, 1087 - "status": "completed", 1088 - "created_at": "2025-12-23T19:15:54.656870800-05:00", 1089 - "updated_at": "2025-12-24T16:16:07.929560700-05:00", 1090 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 1091 - }, 1092 - { 1093 - "id": 100, 1094 - "change_id": "9aa09f86-4411-4dac-add2-c19171372d63", 1095 - "node_type": "action", 1096 - "title": "Waiting for AT Protocol rate limit info to calculate appropriate Netlify limits with buffer", 1097 - "description": null, 1098 - "status": "completed", 1099 - "created_at": "2025-12-23T19:20:28.608323400-05:00", 1100 - "updated_at": "2025-12-24T16:16:07.994428300-05:00", 1101 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 1102 - }, 1103 - { 1104 - "id": 101, 1105 - "change_id": "e79276e8-80f0-4f18-acc1-b630182fac97", 1106 - "node_type": "observation", 1107 - "title": "AT Protocol limits: PDS 5000 points/hr (CREATE=3, UPDATE=2, DELETE=1), IP 3000 req/5min (600/min), AppView generous but undocumented. Need to calculate limits with buffer for both endpoints.", 1108 - "description": null, 1109 - "status": "completed", 1110 - "created_at": "2025-12-23T19:23:56.050582900-05:00", 1111 - "updated_at": "2025-12-24T16:16:08.057016-05:00", 1112 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1113 - }, 1114 - { 1115 - "id": 102, 1116 - "change_id": "970c1d5d-c6c2-417e-a3e3-6ccc198e07f7", 1117 - "node_type": "decision", 1118 - "title": "Choose rate limit configuration: Conservative (5/min search, 8/hr follow) vs Balanced (6/min search, 10/hr follow) vs Generous (8/min search, 12/hr follow)", 1119 - "description": null, 1120 - "status": "completed", 1121 - "created_at": "2025-12-23T19:24:15.366341900-05:00", 1122 - "updated_at": "2025-12-24T16:16:23.112651200-05:00", 1123 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 1124 - }, 1125 - { 1126 - "id": 103, 1127 - "change_id": "3f0e407c-7691-4d3c-8b7b-da2e4697d29c", 1128 - "node_type": "outcome", 1129 - "title": "Chose conservative limits: batch-search-actors 5/min, batch-follow-users 8/hour. Provides ~50% buffer for other AT Protocol actions (likes, replies, posts).", 1130 - "description": null, 1131 - "status": "completed", 1132 - "created_at": "2025-12-23T19:27:38.570209500-05:00", 1133 - "updated_at": "2025-12-24T16:16:08.120585700-05:00", 1134 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 1135 - }, 1136 - { 1137 - "id": 104, 1138 - "change_id": "5f61a35e-4982-40a6-8b53-ab06640cc36b", 1139 - "node_type": "action", 1140 - "title": "Implementing Netlify rate limiting for 2 endpoints", 1141 - "description": null, 1142 - "status": "completed", 1143 - "created_at": "2025-12-23T19:27:44.866665700-05:00", 1144 - "updated_at": "2025-12-24T16:16:08.180988400-05:00", 1145 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"files\":[\"netlify.toml\"]}" 1146 - }, 1147 - { 1148 - "id": 105, 1149 - "change_id": "af86b0ed-efa4-4070-a8f9-bd1a46e3434b", 1150 - "node_type": "observation", 1151 - "title": "Netlify doesn't have simple declarative rate limiting in free tier. Need to implement via middleware. Will use in-memory Map with cleanup - works per function instance but better than nothing. Can upgrade to Upstash later if needed.", 1152 - "description": null, 1153 - "status": "completed", 1154 - "created_at": "2025-12-23T19:28:22.960204400-05:00", 1155 - "updated_at": "2025-12-24T16:16:08.242546700-05:00", 1156 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 1157 - }, 1158 - { 1159 - "id": 106, 1160 - "change_id": "037f0c9c-a1bb-406f-9a28-f48c562bf064", 1161 - "node_type": "outcome", 1162 - "title": "Successfully implemented rate limiting with DRY principles. Created rateLimit.middleware with applyRateLimit helper. Applied conservative limits: batch-search 5/min, batch-follow 8/hr. In-memory (resets on cold start) but provides basic protection. Can upgrade to Upstash later.", 1163 - "description": null, 1164 - "status": "completed", 1165 - "created_at": "2025-12-23T19:33:44.434527-05:00", 1166 - "updated_at": "2025-12-24T16:16:08.306915400-05:00", 1167 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"files\":[\"netlify/functions/core/middleware/rateLimit.middleware.ts\",\"netlify/functions/batch-search-actors.ts\",\"netlify/functions/batch-follow-users.ts\"]}" 1168 - }, 1169 - { 1170 - "id": 107, 1171 - "change_id": "44aff04f-b6c9-46c6-a8a7-1cdb99d4124a", 1172 - "node_type": "action", 1173 - "title": "Committed optimization #12", 1174 - "description": null, 1175 - "status": "completed", 1176 - "created_at": "2025-12-23T19:34:37.351599600-05:00", 1177 - "updated_at": "2025-12-24T16:16:08.370465100-05:00", 1178 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"587a9b0\",\"confidence\":100}" 1179 - }, 1180 - { 1181 - "id": 108, 1182 - "change_id": "aba3305e-74ef-4c32-b534-68fcc0527202", 1183 - "node_type": "observation", 1184 - "title": "ALL 12 OPTIMIZATIONS COMPLETE! Session 2 total: 7 optimizations (#6-#12), 6 commits, 107 decision nodes tracked. Performance improved, code quality enhanced, security added. Ready for production.", 1185 - "description": null, 1186 - "status": "completed", 1187 - "created_at": "2025-12-23T19:34:50.861995600-05:00", 1188 - "updated_at": "2025-12-24T16:16:08.431171700-05:00", 1189 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 1190 - }, 1191 - { 1192 - "id": 109, 1193 - "change_id": "a18b89e9-eb13-428c-939b-4db60fe1a496", 1194 - "node_type": "goal", 1195 - "title": "Add rate limiting to prevent AT Protocol API abuse", 1196 - "description": null, 1197 - "status": "completed", 1198 - "created_at": "2025-12-23T19:41:46.487312500-05:00", 1199 - "updated_at": "2025-12-24T16:16:53.997863400-05:00", 1200 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95,\"prompt\":\"Optimization #12 from PLAN.md: Add rate limiting to expensive batch endpoints to prevent users from exhausting AT Protocol API limits and ensure buffer room for other operations (likes, replies, posts).\"}" 1201 - }, 1202 - { 1203 - "id": 110, 1204 - "change_id": "22b9c3db-9f95-45d7-a3ed-bdfac54677db", 1205 - "node_type": "goal", 1206 - "title": "Cleanup codebase - remove unused code and backward compatibility artifacts", 1207 - "description": null, 1208 - "status": "completed", 1209 - "created_at": "2025-12-23T20:04:14.947114-05:00", 1210 - "updated_at": "2025-12-24T16:16:54.076098300-05:00", 1211 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"prompt\":\"Cleanup the codebase by removing anything unused, including anything left for backward compatibility and make sure the new implementation is fully used.\"}" 1212 - }, 1213 - { 1214 - "id": 111, 1215 - "change_id": "c817c7d7-69cb-4fa3-934e-9ff210027ebf", 1216 - "node_type": "action", 1217 - "title": "Searching for old implementation files that should be removed after optimizations", 1218 - "description": null, 1219 - "status": "completed", 1220 - "created_at": "2025-12-23T20:04:25.643508300-05:00", 1221 - "updated_at": "2025-12-24T16:16:08.496920700-05:00", 1222 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 1223 - }, 1224 - { 1225 - "id": 112, 1226 - "change_id": "4b680ad7-6517-4e7c-8722-ffe6d5c70d4d", 1227 - "node_type": "observation", 1228 - "title": "Found deprecated 'followed' field used in 3 locations with followStatus fallback pattern. Need to verify if database schema includes followed field before removing.", 1229 - "description": null, 1230 - "status": "completed", 1231 - "created_at": "2025-12-23T20:07:02.695049300-05:00", 1232 - "updated_at": "2025-12-24T16:16:08.575812600-05:00", 1233 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 1234 - }, 1235 - { 1236 - "id": 113, 1237 - "change_id": "437de2d2-6de6-4a4c-a306-d6491e661f97", 1238 - "node_type": "decision", 1239 - "title": "Strategy for removing deprecated 'followed' field: Remove from types, frontend code, and database schema vs Keep database field but stop using it", 1240 - "description": null, 1241 - "status": "completed", 1242 - "created_at": "2025-12-23T20:08:11.130497400-05:00", 1243 - "updated_at": "2025-12-24T16:16:23.192211800-05:00", 1244 - "metadata_json": "{\"branch\":\"master\",\"confidence\":80}" 1245 - }, 1246 - { 1247 - "id": 114, 1248 - "change_id": "af90cd04-bdd3-4a33-9c91-6233c4487306", 1249 - "node_type": "outcome", 1250 - "title": "Decision: Remove 'followed' field from frontend types and code. Keep database field to avoid migration, but stop reading/using it. Only use followStatus going forward.", 1251 - "description": null, 1252 - "status": "completed", 1253 - "created_at": "2025-12-23T20:08:28.212329-05:00", 1254 - "updated_at": "2025-12-24T16:16:08.640913500-05:00", 1255 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 1256 - }, 1257 - { 1258 - "id": 115, 1259 - "change_id": "36762e5f-cb24-4e86-9b8d-24182ae53671", 1260 - "node_type": "action", 1261 - "title": "Removing deprecated 'followed' field from types and frontend code", 1262 - "description": null, 1263 - "status": "completed", 1264 - "created_at": "2025-12-23T20:08:41.239991100-05:00", 1265 - "updated_at": "2025-12-24T16:16:08.704361400-05:00", 1266 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 1267 - }, 1268 - { 1269 - "id": 116, 1270 - "change_id": "0e63dec2-b38f-40cb-af00-4b5da44d6212", 1271 - "node_type": "observation", 1272 - "title": "Removed 'followed' field from 6 locations: search.types.ts, SearchResultCard.tsx, App.tsx, useFollows.ts, get-upload-details.ts, MatchRepository.ts. Database schema kept unchanged to avoid migration.", 1273 - "description": null, 1274 - "status": "completed", 1275 - "created_at": "2025-12-23T20:10:58.568272-05:00", 1276 - "updated_at": "2025-12-24T16:16:08.766377900-05:00", 1277 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1278 - }, 1279 - { 1280 - "id": 117, 1281 - "change_id": "d78b544a-8897-4149-ac48-4f35f6def985", 1282 - "node_type": "observation", 1283 - "title": "Removed empty 'nul' file (likely created by accident on Windows)", 1284 - "description": null, 1285 - "status": "completed", 1286 - "created_at": "2025-12-23T20:12:28.266830900-05:00", 1287 - "updated_at": "2025-12-24T16:19:16.669975200-05:00", 1288 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 1289 - }, 1290 - { 1291 - "id": 118, 1292 - "change_id": "e16cb229-81a4-4215-a35f-48f33d217290", 1293 - "node_type": "outcome", 1294 - "title": "Successfully cleaned up codebase: removed deprecated 'followed' field from 6 files, deleted empty 'nul' file. Build passes. All new implementations (zustand, date-fns, Zod) fully integrated.", 1295 - "description": null, 1296 - "status": "completed", 1297 - "created_at": "2025-12-23T20:13:15.750443600-05:00", 1298 - "updated_at": "2025-12-24T16:16:08.843310900-05:00", 1299 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1300 - }, 1301 - { 1302 - "id": 119, 1303 - "change_id": "462bb6d0-8ce9-4305-a11e-c34b9fe6e946", 1304 - "node_type": "action", 1305 - "title": "Removing backward-compatible useSettings hook and updating App.tsx to use zustand store directly", 1306 - "description": null, 1307 - "status": "completed", 1308 - "created_at": "2025-12-23T20:18:42.243820600-05:00", 1309 - "updated_at": "2025-12-24T16:16:08.904482900-05:00", 1310 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 1311 - }, 1312 - { 1313 - "id": 120, 1314 - "change_id": "d982f0be-e0bd-43db-bb6e-96129ca4561d", 1315 - "node_type": "outcome", 1316 - "title": "Successfully removed backward-compatible useSettings hook. Updated App.tsx to use zustand store directly. Build passes with smaller bundle (284.11 KB vs 284.27 KB).", 1317 - "description": null, 1318 - "status": "completed", 1319 - "created_at": "2025-12-23T20:20:47.820117300-05:00", 1320 - "updated_at": "2025-12-24T16:16:08.969548400-05:00", 1321 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1322 - }, 1323 - { 1324 - "id": 121, 1325 - "change_id": "226c05bc-6da6-4343-9204-0dfb819ed57b", 1326 - "node_type": "observation", 1327 - "title": "Cleanup complete: removed all backward compatibility code (followed field, useSettings hook), updated CLAUDE.md with commit message guidelines. 120 decision nodes tracked.", 1328 - "description": null, 1329 - "status": "completed", 1330 - "created_at": "2025-12-23T20:22:30.966505200-05:00", 1331 - "updated_at": "2025-12-24T16:16:09.028032800-05:00", 1332 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1333 - }, 1334 - { 1335 - "id": 122, 1336 - "change_id": "0357c76e-2c91-46e7-941e-4466d520b8c2", 1337 - "node_type": "goal", 1338 - "title": "Fix login UX bugs and results page layout issues", 1339 - "description": null, 1340 - "status": "completed", 1341 - "created_at": "2025-12-23T20:36:38.865460900-05:00", 1342 - "updated_at": "2025-12-24T16:16:54.146211-05:00", 1343 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"prompt\":\"Various bug and small fixes are needed, some of which were introduced in commit 151f5336. Enter and tab should save the full handle from the typeahead and users should be able to hit enter again to login. Auto-strip the leading @ if entered in the handle field, with a message to the user letting them know that's not needed. The results page cards are spaced weirdly and sometimes overlap. In some cases you can't even click the \\\"show x more option(s)\\\" button because it's covered. Previously I made a fix to left-algin the follow info + user descriptions on the results to be left-algined with the avatar not the user handle on mobile; re-implement this. The toast notifications don't match well with the UI and feel excessive. Analyze which are actually needed, keeping in mind accessibility and screen readers, and suggest alternative options that don't cover important screen information; keep in mind this will primarily be used on mobile too.\"}" 1344 - }, 1345 - { 1346 - "id": 123, 1347 - "change_id": "b699928b-e0bd-45e0-8dcd-b5ab3b8945c4", 1348 - "node_type": "observation", 1349 - "title": "Commit 151f5336 added error boundaries, lazy loading, form validation, list virtualization. Broke autofill login handle (mentioned in commit message)", 1350 - "description": null, 1351 - "status": "completed", 1352 - "created_at": "2025-12-23T20:37:01.299493800-05:00", 1353 - "updated_at": "2025-12-24T16:16:09.092233400-05:00", 1354 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1355 - }, 1356 - { 1357 - "id": 124, 1358 - "change_id": "5852a83b-88bb-4938-ae0b-c2791a7bdeba", 1359 - "node_type": "observation", 1360 - "title": "Analyzed codebase: Login uses actor-typeahead + useFormValidation hook (not syncing on Enter/Tab). Results page uses VirtualizedResultsList with estimateSize: 200px (causing overlap). Toast notifications at top-right fixed position (8 total: 2 logout, 2 login, 2 upload load, 2 follow status messages)", 1361 - "description": null, 1362 - "status": "completed", 1363 - "created_at": "2025-12-23T20:38:30.501600300-05:00", 1364 - "updated_at": "2025-12-24T16:16:09.156499800-05:00", 1365 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 1366 - }, 1367 - { 1368 - "id": 125, 1369 - "change_id": "f5475891-0269-4c90-9968-baab1db0a583", 1370 - "node_type": "action", 1371 - "title": "Fixing Login.tsx: handle typeahead selection events, strip leading @, update form state", 1372 - "description": null, 1373 - "status": "completed", 1374 - "created_at": "2025-12-23T20:38:41.692719900-05:00", 1375 - "updated_at": "2025-12-24T16:16:09.218077100-05:00", 1376 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 1377 - }, 1378 - { 1379 - "id": 126, 1380 - "change_id": "43dee7b4-082e-42dd-b245-4b6dec800458", 1381 - "node_type": "outcome", 1382 - "title": "Login fixes complete: typeahead syncs with form state via input/change/blur events, @ auto-stripped with helpful message", 1383 - "description": null, 1384 - "status": "completed", 1385 - "created_at": "2025-12-23T20:40:29.725356600-05:00", 1386 - "updated_at": "2025-12-24T16:16:09.277592400-05:00", 1387 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1388 - }, 1389 - { 1390 - "id": 127, 1391 - "change_id": "995ffe5d-4614-4f5f-8afc-04754bd54efc", 1392 - "node_type": "action", 1393 - "title": "Fixing VirtualizedResultsList: dynamic size estimation based on match count and expansion state", 1394 - "description": null, 1395 - "status": "completed", 1396 - "created_at": "2025-12-23T20:40:32.953580100-05:00", 1397 - "updated_at": "2025-12-24T16:16:09.340031600-05:00", 1398 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 1399 - }, 1400 - { 1401 - "id": 128, 1402 - "change_id": "94d4ca47-69ed-4cbd-91b8-652936b01b98", 1403 - "node_type": "outcome", 1404 - "title": "VirtualizedResultsList fixed: dynamic size estimation based on match count and expansion state prevents overlap", 1405 - "description": null, 1406 - "status": "completed", 1407 - "created_at": "2025-12-23T20:41:06.394977600-05:00", 1408 - "updated_at": "2025-12-24T16:16:09.400449800-05:00", 1409 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1410 - }, 1411 - { 1412 - "id": 129, 1413 - "change_id": "12e7e24a-6730-4d3b-9a0f-220e35aacb7f", 1414 - "node_type": "action", 1415 - "title": "Re-implementing mobile left-align: follow stats and descriptions align with avatar edge on mobile", 1416 - "description": null, 1417 - "status": "completed", 1418 - "created_at": "2025-12-23T20:41:09.306543800-05:00", 1419 - "updated_at": "2025-12-24T16:16:09.473525700-05:00", 1420 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 1421 - }, 1422 - { 1423 - "id": 130, 1424 - "change_id": "a83f4dba-ec0c-41c6-b51c-a8347d600f3c", 1425 - "node_type": "outcome", 1426 - "title": "Mobile layout fixed: badges/stats and descriptions now align with avatar edge (pl-0) on mobile, indent on desktop (md:pl-[60px])", 1427 - "description": null, 1428 - "status": "completed", 1429 - "created_at": "2025-12-23T20:41:57.894282800-05:00", 1430 - "updated_at": "2025-12-24T16:16:09.554292600-05:00", 1431 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1432 - }, 1433 - { 1434 - "id": 131, 1435 - "change_id": "7d0d2907-6dfc-4160-9d5a-1114fca7924a", 1436 - "node_type": "action", 1437 - "title": "Analyzing toast notification usage and creating recommendation for mobile-friendly alternatives", 1438 - "description": null, 1439 - "status": "completed", 1440 - "created_at": "2025-12-23T20:42:00.888543-05:00", 1441 - "updated_at": "2025-12-24T16:16:09.617580800-05:00", 1442 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 1443 - }, 1444 - { 1445 - "id": 132, 1446 - "change_id": "b66ab07d-5c6c-443b-a6bb-1738f45911f8", 1447 - "node_type": "decision", 1448 - "title": "Choose toast notification strategy: Keep all with mobile positioning vs Reduce to errors only vs Inline contextual messages vs Bottom sheet notifications", 1449 - "description": null, 1450 - "status": "completed", 1451 - "created_at": "2025-12-23T20:42:11.073767900-05:00", 1452 - "updated_at": "2025-12-24T16:16:23.275761-05:00", 1453 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 1454 - }, 1455 - { 1456 - "id": 133, 1457 - "change_id": "88f7884c-cde3-4f41-aa78-10065619517f", 1458 - "node_type": "outcome", 1459 - "title": "User chose inline contextual messages: keep only error toasts (login, logout, upload load), remove success/info toasts, add invisible aria-live regions", 1460 - "description": null, 1461 - "status": "completed", 1462 - "created_at": "2025-12-23T20:46:17.007983500-05:00", 1463 - "updated_at": "2025-12-24T16:16:09.677727800-05:00", 1464 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1465 - }, 1466 - { 1467 - "id": 134, 1468 - "change_id": "32d6f48c-48cb-41cc-8b0e-fe270dd070e2", 1469 - "node_type": "action", 1470 - "title": "Implementing inline feedback system: removing redundant toasts, keeping error-only toasts, adding invisible aria-live announcer", 1471 - "description": null, 1472 - "status": "completed", 1473 - "created_at": "2025-12-23T20:46:20.532190700-05:00", 1474 - "updated_at": "2025-12-24T16:16:09.738182600-05:00", 1475 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 1476 - }, 1477 - { 1478 - "id": 135, 1479 - "change_id": "1c3644b9-0c3a-499b-b34a-79aad9682702", 1480 - "node_type": "outcome", 1481 - "title": "Toast notification refactor complete: removed 3 redundant toasts (logout success, upload success, no results info), kept errors only, added AriaLiveAnnouncer for screen reader accessibility. Build passes.", 1482 - "description": null, 1483 - "status": "completed", 1484 - "created_at": "2025-12-23T20:53:30.408923500-05:00", 1485 - "updated_at": "2025-12-24T16:16:09.799366300-05:00", 1486 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1487 - }, 1488 - { 1489 - "id": 136, 1490 - "change_id": "442a6396-4f7f-4f05-9d19-762d4b9f9896", 1491 - "node_type": "action", 1492 - "title": "Committing CLAUDE.md update with separate commit guidance", 1493 - "description": null, 1494 - "status": "completed", 1495 - "created_at": "2025-12-23T20:57:23.825052400-05:00", 1496 - "updated_at": "2025-12-24T16:16:09.860089-05:00", 1497 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"8e9efd2\",\"confidence\":95}" 1498 - }, 1499 - { 1500 - "id": 137, 1501 - "change_id": "11e99520-1e49-4fce-be63-7f3af3523f6f", 1502 - "node_type": "outcome", 1503 - "title": "Committed login typeahead and @ stripping fixes", 1504 - "description": null, 1505 - "status": "completed", 1506 - "created_at": "2025-12-23T20:58:17.828634400-05:00", 1507 - "updated_at": "2025-12-24T16:16:09.923776400-05:00", 1508 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"4c3ae0d\",\"confidence\":95}" 1509 - }, 1510 - { 1511 - "id": 138, 1512 - "change_id": "f3687af3-fa58-424f-89e3-9e64d18322c9", 1513 - "node_type": "outcome", 1514 - "title": "Committed results page card spacing fix", 1515 - "description": null, 1516 - "status": "completed", 1517 - "created_at": "2025-12-23T21:10:27.704228-05:00", 1518 - "updated_at": "2025-12-24T16:16:09.985308100-05:00", 1519 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"4c3ae0d\",\"confidence\":95}" 1520 - }, 1521 - { 1522 - "id": 139, 1523 - "change_id": "79bc3a4c-d528-451b-8706-66e8aa7f50ff", 1524 - "node_type": "outcome", 1525 - "title": "Committed mobile alignment fix", 1526 - "description": null, 1527 - "status": "completed", 1528 - "created_at": "2025-12-23T21:11:00.152727100-05:00", 1529 - "updated_at": "2025-12-24T16:16:10.043043-05:00", 1530 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"ebb1e05\",\"confidence\":95}" 1531 - }, 1532 - { 1533 - "id": 140, 1534 - "change_id": "45efeea7-9759-405c-9ab4-568cfb7f083c", 1535 - "node_type": "outcome", 1536 - "title": "Committed toast notification refactor", 1537 - "description": null, 1538 - "status": "completed", 1539 - "created_at": "2025-12-23T21:11:21.224146800-05:00", 1540 - "updated_at": "2025-12-24T16:16:10.120401700-05:00", 1541 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"cc586d2\",\"confidence\":95}" 1542 - }, 1543 - { 1544 - "id": 141, 1545 - "change_id": "954f8b75-05eb-44de-afd6-89c349587b2e", 1546 - "node_type": "observation", 1547 - "title": "All bug fixes complete and committed separately: 5 commits (CLAUDE.md update, login typeahead/@ stripping, card overlap fix, mobile alignment, toast refactor). Build passes. Ready for testing.", 1548 - "description": null, 1549 - "status": "completed", 1550 - "created_at": "2025-12-23T21:11:46.224288400-05:00", 1551 - "updated_at": "2025-12-24T16:16:10.183597600-05:00", 1552 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1553 - }, 1554 - { 1555 - "id": 142, 1556 - "change_id": "6b5a1e7d-27d5-4a7a-9eba-8c0495987ba6", 1557 - "node_type": "action", 1558 - "title": "Re-fixing VirtualizedResultsList spacing - fixed gap between cards", 1559 - "description": null, 1560 - "status": "completed", 1561 - "created_at": "2025-12-23T21:22:44.904557100-05:00", 1562 - "updated_at": "2025-12-24T16:16:10.248817-05:00", 1563 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 1564 - }, 1565 - { 1566 - "id": 143, 1567 - "change_id": "b6a1f3ef-068a-4ae7-a3a4-130fe830fe4c", 1568 - "node_type": "observation", 1569 - "title": "Current implementation uses estimateSize to guess heights (80px base + 140px per match). Virtualizer positions cards based on estimates via translateY. When actual height != estimate, cards overlap. pb-4 gap is inside card, not between virtual items. Need dynamic measurement with measureElement.", 1570 - "description": null, 1571 - "status": "completed", 1572 - "created_at": "2025-12-23T21:23:22.876915400-05:00", 1573 - "updated_at": "2025-12-24T16:16:10.308572900-05:00", 1574 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1575 - }, 1576 - { 1577 - "id": 144, 1578 - "change_id": "37bbbbd0-0fdd-4ce3-aa86-dd88d45513fc", 1579 - "node_type": "outcome", 1580 - "title": "Successfully refactored VirtualizedResultsList to use dynamic measurement. Replaced complex estimateSize (40 lines) with simple 200px estimate + measureElement callback. Added data-index and ref={virtualizer.measureElement}. Virtualizer now measures actual rendered heights and positions cards correctly with fixed pb-4 gap. Build passes.", 1581 - "description": null, 1582 - "status": "completed", 1583 - "created_at": "2025-12-23T21:24:18.072543400-05:00", 1584 - "updated_at": "2025-12-24T16:16:10.393413500-05:00", 1585 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1586 - }, 1587 - { 1588 - "id": 145, 1589 - "change_id": "e8b327a0-372f-478b-a33a-2e1ce554bed2", 1590 - "node_type": "action", 1591 - "title": "Analyzing badge alignment pattern in HistoryTab vs SearchResultCard", 1592 - "description": null, 1593 - "status": "completed", 1594 - "created_at": "2025-12-23T21:46:16.661717400-05:00", 1595 - "updated_at": "2025-12-24T16:16:10.456497400-05:00", 1596 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 1597 - }, 1598 - { 1599 - "id": 146, 1600 - "change_id": "9eae410e-0b10-442f-8291-6f54b9e2f900", 1601 - "node_type": "observation", 1602 - "title": "HistoryTab pattern (line 135): 'sm:ml-0 -ml-14' = small screens shift left 56px to align with avatar, medium+ no shift to align with Platform+Link content. SearchResultCard (lines 65, 77): '-ml-4 pl-0 sm:pl-[60px]' = small screens at -4px (wrong, shifts too far left), medium+ at 56px from card edge but should be 72px to align with Name/Handle. The -ml-4 causes misalignment. Standard pattern should be responsive padding: pl-0 on small (align with avatar), sm:pl-[60px] on medium+ (align with Name/Handle).", 1603 - "description": null, 1604 - "status": "completed", 1605 - "created_at": "2025-12-23T21:48:58.458041400-05:00", 1606 - "updated_at": "2025-12-24T16:16:10.521211-05:00", 1607 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1608 - }, 1609 - { 1610 - "id": 147, 1611 - "change_id": "31952cd1-2b20-4df9-b99e-2a8fecd45845", 1612 - "node_type": "outcome", 1613 - "title": "Fixed badge alignment in SearchResultCard. Removed -ml-4 negative margin that shifted badges 4px left of card edge on mobile. Changed sm:pl-[60px] to md:pl-[60px] for medium breakpoint. Pattern now matches HistoryTab: mobile aligns with avatar (pl-0), medium+ indents to align with Name/Handle (md:pl-[60px]). Fixed both badges (line 65) and description (line 77). Build passes.", 1614 - "description": null, 1615 - "status": "completed", 1616 - "created_at": "2025-12-23T21:50:51.492205100-05:00", 1617 - "updated_at": "2025-12-24T16:16:10.586658700-05:00", 1618 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1619 - }, 1620 - { 1621 - "id": 148, 1622 - "change_id": "adec9fe9-7462-4734-9b87-ab30558da687", 1623 - "node_type": "action", 1624 - "title": "Applying SearchResultCard spacing pattern to HistoryTab upload cards", 1625 - "description": null, 1626 - "status": "completed", 1627 - "created_at": "2025-12-23T21:59:29.095361600-05:00", 1628 - "updated_at": "2025-12-24T16:16:10.650392500-05:00", 1629 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 1630 - }, 1631 - { 1632 - "id": 149, 1633 - "change_id": "6b36b07d-75af-49a7-a095-7ff93ef9f4db", 1634 - "node_type": "outcome", 1635 - "title": "Applied consistent spacing pattern to HistoryTab upload cards. Changed badges from 'py-1.5 sm:ml-0 -ml-14' to 'pl-0 sm:pl-[56px]' to match SearchResultCard pattern. Badge alignment: mobile aligns with avatar edge (pl-0), medium+ indents to align with Platform/Link content (sm:pl-[56px] = 40px avatar + 16px gap). Build passes.", 1636 - "description": null, 1637 - "status": "completed", 1638 - "created_at": "2025-12-23T22:02:18.638925800-05:00", 1639 - "updated_at": "2025-12-24T16:16:10.709227900-05:00", 1640 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1641 - }, 1642 - { 1643 - "id": 150, 1644 - "change_id": "a11f624c-93ae-49e7-81e1-d8d68ac9eca8", 1645 - "node_type": "action", 1646 - "title": "Analyzing SearchResultCard structure: wrapper div with p-3, top flex row with gap-3, badges as sibling row with pl-0 sm:pl-[44px]. HistoryTab currently has different structure - Card IS the flex container with badges INSIDE flex-1. Need to restructure to match pattern.", 1647 - "description": null, 1648 - "status": "completed", 1649 - "created_at": "2025-12-23T22:06:39.534009400-05:00", 1650 - "updated_at": "2025-12-24T16:16:10.774548800-05:00", 1651 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 1652 - }, 1653 - { 1654 - "id": 151, 1655 - "change_id": "87d57666-91a4-45c9-a3f1-628dcc395db3", 1656 - "node_type": "outcome", 1657 - "title": "Restructured HistoryTab to match SearchResultCard pattern. Moved p-4 from Card to wrapper div. Created top flex row (flex gap-4 mb-1) with avatar + content. Moved badges out of flex-1 to be sibling row with pl-0 sm:pl-[56px]. Now badges align with avatar on mobile (pl-0) and indent to match Platform name on medium+ (56px = 40px avatar + 16px gap). Build passes.", 1658 - "description": null, 1659 - "status": "completed", 1660 - "created_at": "2025-12-23T22:08:28.819634300-05:00", 1661 - "updated_at": "2025-12-24T16:16:10.838290200-05:00", 1662 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1663 - }, 1664 - { 1665 - "id": 152, 1666 - "change_id": "eb1b6810-9528-4e4e-b35e-43a02ccf8f3c", 1667 - "node_type": "action", 1668 - "title": "Analyzing shared component feasibility for card structure pattern", 1669 - "description": null, 1670 - "status": "completed", 1671 - "created_at": "2025-12-23T22:28:44.491047100-05:00", 1672 - "updated_at": "2025-12-24T16:16:10.898326300-05:00", 1673 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 1674 - }, 1675 - { 1676 - "id": 153, 1677 - "change_id": "0099b286-7090-459e-8fc6-1abccf3488bb", 1678 - "node_type": "action", 1679 - "title": "Creating shared CardItem component with composition pattern: avatar/content/action/badges/description slots, configurable padding and responsive badge indent", 1680 - "description": null, 1681 - "status": "completed", 1682 - "created_at": "2025-12-24T00:20:16.938290100-05:00", 1683 - "updated_at": "2025-12-24T16:16:10.963675500-05:00", 1684 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 1685 - }, 1686 - { 1687 - "id": 154, 1688 - "change_id": "41384be8-f128-4424-9419-2626fc7ac8f4", 1689 - "node_type": "outcome", 1690 - "title": "Successfully created CardItem component and refactored both SearchResultCard and HistoryTab to use it. Extracted 60+ lines of duplicate structure into reusable component. CardItem provides: avatar/content/action/badges/description slots, configurable padding (p-3/p-4), responsive badge indent (sm:pl-[44px]/sm:pl-[56px]). Code now follows composition pattern with single source of truth for layout. Build passes, bundle size unchanged (284.39 KB).", 1691 - "description": null, 1692 - "status": "completed", 1693 - "created_at": "2025-12-24T00:22:11.342098400-05:00", 1694 - "updated_at": "2025-12-24T16:16:11.030380600-05:00", 1695 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1696 - }, 1697 - { 1698 - "id": 155, 1699 - "change_id": "76e2700c-0324-4563-81d1-b31dc3e85460", 1700 - "node_type": "goal", 1701 - "title": "Refactor UI components: create shared components for wizard/upload/settings, fix progress bar", 1702 - "description": null, 1703 - "status": "completed", 1704 - "created_at": "2025-12-24T00:58:08.581579500-05:00", 1705 - "updated_at": "2025-12-24T16:16:54.203388600-05:00", 1706 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"prompt\":\"Follow React+Tailwild best practices, use DRY principles. Make shared components for repeated patterns across setup wizard and upload / settings tabs. Prefer the settings toggle to checkboxes. Keep the upload vs. which platform colors as-is. Make drop-downs a separate component too, and describe options for using .ico files from platform in the drop-down next to the text similar to the history card social link. Re-implement progress bar on the setup wizard, it was broken by commit f3c536d1.\"}" 1707 - }, 1708 - { 1709 - "id": 156, 1710 - "change_id": "28f2b394-61e7-4840-9c33-838a1bcf0e04", 1711 - "node_type": "observation", 1712 - "title": "Progress bar broken: ProgressBar wizard variant missing bg color, wrong className usage in SetupWizard line 103", 1713 - "description": null, 1714 - "status": "completed", 1715 - "created_at": "2025-12-24T00:58:56.442852800-05:00", 1716 - "updated_at": "2025-12-24T16:16:11.117072500-05:00", 1717 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1718 - }, 1719 - { 1720 - "id": 157, 1721 - "change_id": "3b149b2b-0e2d-4e38-a2ed-858836cb2e24", 1722 - "node_type": "observation", 1723 - "title": "Found repeated patterns: Toggle (2x in Settings), Dropdown (4x across files), segmented progress bar (replaced incorrectly)", 1724 - "description": null, 1725 - "status": "completed", 1726 - "created_at": "2025-12-24T00:59:33.374749300-05:00", 1727 - "updated_at": "2025-12-24T16:16:11.196310800-05:00", 1728 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1729 - }, 1730 - { 1731 - "id": 158, 1732 - "change_id": "37ab3ef1-445b-46cc-bf51-25ad24f6c131", 1733 - "node_type": "decision", 1734 - "title": "Choose component architecture: Extract Toggle, Dropdown, FormField + fix ProgressBar vs larger form library", 1735 - "description": null, 1736 - "status": "completed", 1737 - "created_at": "2025-12-24T00:59:55.890141500-05:00", 1738 - "updated_at": "2025-12-24T16:16:23.361700900-05:00", 1739 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 1740 - }, 1741 - { 1742 - "id": 159, 1743 - "change_id": "8a6cd252-e3a1-4c68-a50f-05f3574016ed", 1744 - "node_type": "option", 1745 - "title": "Extract individual components - lightweight, follows existing pattern", 1746 - "description": null, 1747 - "status": "completed", 1748 - "created_at": "2025-12-24T00:59:57.448827700-05:00", 1749 - "updated_at": "2025-12-24T16:16:23.443919200-05:00", 1750 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 1751 - }, 1752 - { 1753 - "id": 160, 1754 - "change_id": "369d275f-5ad7-4d13-aad6-7bcd69ef9e3d", 1755 - "node_type": "outcome", 1756 - "title": "Chose option A: Extract individual shared components. Matches existing component pattern (Card, Badge, etc), no new deps, easier to maintain", 1757 - "description": null, 1758 - "status": "completed", 1759 - "created_at": "2025-12-24T00:59:59.084055-05:00", 1760 - "updated_at": "2025-12-24T16:16:11.263831-05:00", 1761 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1762 - }, 1763 - { 1764 - "id": 161, 1765 - "change_id": "3e38a61f-16f1-4a68-a943-e66b11df29ae", 1766 - "node_type": "action", 1767 - "title": "Creating Toggle component", 1768 - "description": null, 1769 - "status": "completed", 1770 - "created_at": "2025-12-24T01:00:28.980093800-05:00", 1771 - "updated_at": "2025-12-24T16:16:11.344727300-05:00", 1772 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 1773 - }, 1774 - { 1775 - "id": 162, 1776 - "change_id": "1be7b49c-5da2-4b2c-bd81-7900fdcf8584", 1777 - "node_type": "outcome", 1778 - "title": "Created Toggle, Dropdown, DropdownWithIcons components. Fixed ProgressBar wizard variant to use segmented display", 1779 - "description": null, 1780 - "status": "completed", 1781 - "created_at": "2025-12-24T01:02:12.402352600-05:00", 1782 - "updated_at": "2025-12-24T16:16:11.422156500-05:00", 1783 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1784 - }, 1785 - { 1786 - "id": 163, 1787 - "change_id": "6a840fe3-5500-4fbf-8f8f-c3e25e2182c6", 1788 - "node_type": "action", 1789 - "title": "Refactoring SetupWizard to use Toggle and DropdownWithIcons", 1790 - "description": null, 1791 - "status": "completed", 1792 - "created_at": "2025-12-24T01:03:20.596911400-05:00", 1793 - "updated_at": "2025-12-24T16:16:11.483696-05:00", 1794 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 1795 - }, 1796 - { 1797 - "id": 164, 1798 - "change_id": "70c0a116-1c27-4d07-b1b7-4eaf6fe094e3", 1799 - "node_type": "outcome", 1800 - "title": "Refactored SetupWizard and Settings to use shared Toggle and DropdownWithIcons components. Build passes. Bundle size unchanged (284.39 KB)", 1801 - "description": null, 1802 - "status": "completed", 1803 - "created_at": "2025-12-24T01:05:57.779632600-05:00", 1804 - "updated_at": "2025-12-24T16:16:11.563714900-05:00", 1805 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1806 - }, 1807 - { 1808 - "id": 165, 1809 - "change_id": "2ec5c20a-6d22-40b5-bf9c-ebddbd08d6e8", 1810 - "node_type": "action", 1811 - "title": "Committing shared component refactoring", 1812 - "description": null, 1813 - "status": "completed", 1814 - "created_at": "2025-12-24T01:07:44.847703900-05:00", 1815 - "updated_at": "2025-12-24T16:16:11.630543-05:00", 1816 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"6cd4d62\",\"confidence\":95}" 1817 - }, 1818 - { 1819 - "id": 166, 1820 - "change_id": "19750fc5-2408-41a7-bc14-453458d4c32f", 1821 - "node_type": "goal", 1822 - "title": "Refactor Login page: DRY principles, add @ symbol/avatar, ATmosphere explanations, rotating placeholders", 1823 - "description": null, 1824 - "status": "completed", 1825 - "created_at": "2025-12-24T17:31:12.960079400-05:00", 1826 - "updated_at": "2025-12-24T18:22:36.883909400-05:00", 1827 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95,\"prompt\":\"Update the login page to use DRY principles. Is it reasonable for the file to be 389 lines? If not, address that following Typescript+React+Tailwind best practices. Add a visual @ symbol in front of the username in the input field. Replace it with the user profile pic when a handle is selected from the typeahead. Suggest text and UI ways to add information on what \\\"ATmosphere\\\" to a lay audience. Suggest ways we might modify the \\\"username.bsky.social\\\" to be platform-agnostic, e.g., rotating the provider platform btwn options like \\\".blacksky.app\\\", \\\"tngl.sh\\\", \\\".com\\\" - but this shouldn't feel cluttering or overwhelming to users. Stage and commit as you go, separate concerns.\"}" 1828 - }, 1829 - { 1830 - "id": 167, 1831 - "change_id": "9f3909fd-b51d-4a00-8425-e03426bc230f", 1832 - "node_type": "outcome", 1833 - "title": "Login page refactored: 389→258 lines (33% reduction), 5 new components, @ symbol with avatar replacement, rotating placeholders, ATmosphere tooltips", 1834 - "description": null, 1835 - "status": "completed", 1836 - "created_at": "2025-12-24T17:31:24.903737600-05:00", 1837 - "updated_at": "2025-12-24T18:22:39.123902500-05:00", 1838 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"HEAD~5\",\"confidence\":95}" 1839 - }, 1840 - { 1841 - "id": 168, 1842 - "change_id": "3caaaa83-caa9-4695-b043-37e5367ffb4a", 1843 - "node_type": "goal", 1844 - "title": "Fix avatar not displaying when handle selected/entered in login", 1845 - "description": null, 1846 - "status": "completed", 1847 - "created_at": "2025-12-24T18:22:48.900518500-05:00", 1848 - "updated_at": "2025-12-24T18:35:14.800218900-05:00", 1849 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 1850 - }, 1851 - { 1852 - "id": 169, 1853 - "change_id": "5c0cdde6-1079-4390-aab2-7e8ef8bd94b7", 1854 - "node_type": "action", 1855 - "title": "Reading HandleInput component to understand avatar display logic", 1856 - "description": null, 1857 - "status": "completed", 1858 - "created_at": "2025-12-24T18:23:05.987261100-05:00", 1859 - "updated_at": "2025-12-25T20:28:31.354062300-05:00", 1860 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 1861 - }, 1862 - { 1863 - "id": 170, 1864 - "change_id": "9269b746-5275-484c-9314-b436847bf835", 1865 - "node_type": "observation", 1866 - "title": "actor-typeahead stores avatar in private #actors array but doesn't expose it via events or attributes. When user selects a suggestion, it only sets input.value - no avatar data accessible. Need alternative approach to get avatar.", 1867 - "description": null, 1868 - "status": "completed", 1869 - "created_at": "2025-12-24T18:24:33.075823300-05:00", 1870 - "updated_at": "2025-12-25T20:28:31.517807100-05:00", 1871 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1872 - }, 1873 - { 1874 - "id": 171, 1875 - "change_id": "182aab31-aa57-42bb-8d63-cf15a7e80105", 1876 - "node_type": "decision", 1877 - "title": "Choose approach for avatar display: 1) Fetch avatar via Bluesky API when handle entered, 2) Fork actor-typeahead to emit events, 3) Use MutationObserver to watch dropdown DOM", 1878 - "description": null, 1879 - "status": "completed", 1880 - "created_at": "2025-12-24T18:24:37.875781600-05:00", 1881 - "updated_at": "2025-12-25T20:28:31.661275800-05:00", 1882 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 1883 - }, 1884 - { 1885 - "id": 172, 1886 - "change_id": "a0764baa-c522-495b-ae4c-a51b22b786bc", 1887 - "node_type": "outcome", 1888 - "title": "Chose approach 1: Fetch avatar via Bluesky API. Reasons: Works for both typeahead + manual entry, no need to fork component, simple implementation, validates handle exists.", 1889 - "description": null, 1890 - "status": "completed", 1891 - "created_at": "2025-12-24T18:24:51.231785800-05:00", 1892 - "updated_at": "2025-12-25T20:28:31.802909200-05:00", 1893 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 1894 - }, 1895 - { 1896 - "id": 173, 1897 - "change_id": "328ea1bd-379a-4133-8dc8-300b03943ec8", 1898 - "node_type": "action", 1899 - "title": "Implementing avatar fetch from Bluesky API on handle input change", 1900 - "description": null, 1901 - "status": "completed", 1902 - "created_at": "2025-12-24T18:24:56.020367200-05:00", 1903 - "updated_at": "2025-12-25T20:28:31.949390600-05:00", 1904 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 1905 - }, 1906 - { 1907 - "id": 174, 1908 - "change_id": "d9a4f78c-d1e0-4fa6-bd0b-296eba8064e5", 1909 - "node_type": "outcome", 1910 - "title": "Successfully implemented avatar fetch from Bluesky API. Added debounced fetch (300ms) that calls searchActorsTypeahead API when handle entered. Works for both typeahead selections and manual entry. Avatar displays when valid handle found. Build passes.", 1911 - "description": null, 1912 - "status": "completed", 1913 - "created_at": "2025-12-24T18:27:32.316881600-05:00", 1914 - "updated_at": "2025-12-25T20:28:32.120324300-05:00", 1915 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1916 - }, 1917 - { 1918 - "id": 175, 1919 - "change_id": "dde6eb8d-4d35-414e-9d2e-8a577c4338df", 1920 - "node_type": "action", 1921 - "title": "Committed avatar fix to git", 1922 - "description": null, 1923 - "status": "completed", 1924 - "created_at": "2025-12-24T18:35:10.368162900-05:00", 1925 - "updated_at": "2025-12-25T20:28:32.280586200-05:00", 1926 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"9bdca93\",\"confidence\":100}" 1927 - }, 1928 - { 1929 - "id": 176, 1930 - "change_id": "85d33a42-5cbc-44b8-8e97-afd3edb1eeda", 1931 - "node_type": "goal", 1932 - "title": "Refactor ATmosphere tooltip: make HeroSection clickable instead of hover, add tooltip to login input, left-align text", 1933 - "description": null, 1934 - "status": "completed", 1935 - "created_at": "2025-12-24T18:50:43.883772100-05:00", 1936 - "updated_at": "2025-12-24T19:39:08.057232200-05:00", 1937 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 1938 - }, 1939 - { 1940 - "id": 177, 1941 - "change_id": "dbe4421e-0496-4e3d-8548-e1c9156ce023", 1942 - "node_type": "action", 1943 - "title": "Reading HeroSection to understand current tooltip implementation", 1944 - "description": null, 1945 - "status": "completed", 1946 - "created_at": "2025-12-24T18:50:46.648351400-05:00", 1947 - "updated_at": "2025-12-25T20:28:32.440957600-05:00", 1948 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 1949 - }, 1950 - { 1951 - "id": 178, 1952 - "change_id": "96b417f2-4236-48bb-8ad3-3104f9f9c3b7", 1953 - "node_type": "action", 1954 - "title": "Implementing clickable tooltip for HeroSection and adding tooltip to HandleInput", 1955 - "description": null, 1956 - "status": "completed", 1957 - "created_at": "2025-12-24T18:51:19.077525300-05:00", 1958 - "updated_at": "2025-12-25T20:28:32.590991700-05:00", 1959 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 1960 - }, 1961 - { 1962 - "id": 179, 1963 - "change_id": "21ac5b6e-575e-46fb-8695-1a7b44fd0f68", 1964 - "node_type": "outcome", 1965 - "title": "Successfully refactored tooltips: HeroSection ATmosphere tooltip now clickable (trigger='click') with click-outside-to-close, added 'Your Bluesky Handle' label with left-aligned tooltip on login form, enhanced Tooltip component with trigger and align props. Build passes.", 1966 - "description": null, 1967 - "status": "completed", 1968 - "created_at": "2025-12-24T18:54:08.099877300-05:00", 1969 - "updated_at": "2025-12-25T20:28:32.747426300-05:00", 1970 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1971 - }, 1972 - { 1973 - "id": 180, 1974 - "change_id": "28e2400d-a153-4c27-a75b-e6b249355649", 1975 - "node_type": "outcome", 1976 - "title": "Successfully moved tooltip from HeroSection to Login form. Removed tooltip from HeroSection 'ATmosphere' text. Added superscript info icon next to 'ATmosphere' in login form with left-aligned tooltip content. Platform-agnostic design maintained.", 1977 - "description": null, 1978 - "status": "completed", 1979 - "created_at": "2025-12-24T19:06:33.954975-05:00", 1980 - "updated_at": "2025-12-25T20:28:32.905315400-05:00", 1981 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 1982 - }, 1983 - { 1984 - "id": 181, 1985 - "change_id": "acba6854-0d74-4547-91ba-391149cc5e57", 1986 - "node_type": "action", 1987 - "title": "Committed tooltip refactor to git", 1988 - "description": null, 1989 - "status": "completed", 1990 - "created_at": "2025-12-24T19:39:04.481280600-05:00", 1991 - "updated_at": "2025-12-25T20:28:33.066343500-05:00", 1992 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"f79a669\",\"confidence\":100}" 1993 - }, 1994 - { 1995 - "id": 182, 1996 - "change_id": "afd62144-3edc-479e-bc6e-7bb28de124e9", 1997 - "node_type": "observation", 1998 - "title": "Updated CLAUDE.md to document workflow: run deciduous sync before commits, stage graph updates with code changes. Decision graph is part of code history.", 1999 - "description": null, 2000 - "status": "completed", 2001 - "created_at": "2025-12-24T19:43:00.524530200-05:00", 2002 - "updated_at": "2025-12-25T20:28:33.275537500-05:00", 2003 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 2004 - }, 2005 - { 2006 - "id": 183, 2007 - "change_id": "6e1851e2-134c-4c8f-86af-5487fda7d05c", 2008 - "node_type": "action", 2009 - "title": "Removed .claude/ and dist/ from repository", 2010 - "description": null, 2011 - "status": "completed", 2012 - "created_at": "2025-12-24T21:09:41.558024500-05:00", 2013 - "updated_at": "2025-12-25T20:28:33.476127300-05:00", 2014 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"e2d6a7e\",\"confidence\":95}" 2015 - }, 2016 - { 2017 - "id": 184, 2018 - "change_id": "919c42ef-9fae-473f-b755-ee32d8999204", 2019 - "node_type": "goal", 2020 - "title": "Support Twitter/X file uploads for finding follows on Bluesky", 2021 - "description": null, 2022 - "status": "completed", 2023 - "created_at": "2025-12-24T21:26:53.493477900-05:00", 2024 - "updated_at": "2025-12-25T20:28:50.067903-05:00", 2025 - "metadata_json": "{\"branch\":\"master\",\"confidence\":70,\"prompt\":\"Let's plan how to support twitter file uploads. Log with deciduous, but we're otherwise not coding solutions yet. This data doesn't include the usernames in file exports (see twitter_following file). For the \\\"userLink\\\" we have e.g. \\\"https://twitter.com/intent/user?user_id=1103954565026775041\\\". If I visit that in browser, it returns \\\"https://x.com/intent/user?screen_name=veggero\\\" where veggero is the username I want to extract. X is notoriously problematic and I don't want to pay to use their API. What options are there for helping users extract their follows?\"}" 2026 - }, 2027 - { 2028 - "id": 185, 2029 - "change_id": "f3768231-dac9-4575-a2db-e7e5dddabdeb", 2030 - "node_type": "observation", 2031 - "title": "Twitter exports contain user_id URLs not usernames. URL redirect reveals screen_name but requires HTTP request per user. X API is paid/restrictive.", 2032 - "description": null, 2033 - "status": "completed", 2034 - "created_at": "2025-12-24T21:27:01.471000200-05:00", 2035 - "updated_at": "2025-12-25T20:28:50.217388700-05:00", 2036 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 2037 - }, 2038 - { 2039 - "id": 186, 2040 - "change_id": "9035ca16-d7d0-4d5b-8892-3a1cee6c9f4e", 2041 - "node_type": "decision", 2042 - "title": "Choose approach for resolving Twitter user_ids to usernames without paid API", 2043 - "description": null, 2044 - "status": "completed", 2045 - "created_at": "2025-12-24T21:27:09.956279700-05:00", 2046 - "updated_at": "2025-12-25T20:28:50.393807600-05:00", 2047 - "metadata_json": "{\"branch\":\"master\",\"confidence\":60}" 2048 - }, 2049 - { 2050 - "id": 187, 2051 - "change_id": "2d0633f7-64a2-46b0-b709-c3da769f15d2", 2052 - "node_type": "option", 2053 - "title": "Server-side redirect following - Backend fetches URLs, follows redirects to extract screen_name", 2054 - "description": null, 2055 - "status": "completed", 2056 - "created_at": "2025-12-24T21:27:34.979800400-05:00", 2057 - "updated_at": "2025-12-25T20:28:50.575555600-05:00", 2058 - "metadata_json": "{\"branch\":\"master\",\"confidence\":50}" 2059 - }, 2060 - { 2061 - "id": 188, 2062 - "change_id": "ddd29814-8c96-4c7f-bfec-40ce9fcd21f7", 2063 - "node_type": "option", 2064 - "title": "Browser extension - User installs extension that can bypass CORS and resolve URLs client-side", 2065 - "description": null, 2066 - "status": "completed", 2067 - "created_at": "2025-12-24T21:27:36.674409200-05:00", 2068 - "updated_at": "2025-12-25T20:28:50.776512300-05:00", 2069 - "metadata_json": "{\"branch\":\"master\",\"confidence\":55}" 2070 - }, 2071 - { 2072 - "id": 189, 2073 - "change_id": "2456641c-b70d-453f-aed1-4fb26ad94dc0", 2074 - "node_type": "option", 2075 - "title": "Local CLI tool - User downloads script, runs on their machine, uploads resolved usernames", 2076 - "description": null, 2077 - "status": "completed", 2078 - "created_at": "2025-12-24T21:27:38.389965800-05:00", 2079 - "updated_at": "2025-12-25T20:28:50.969735900-05:00", 2080 - "metadata_json": "{\"branch\":\"master\",\"confidence\":60}" 2081 - }, 2082 - { 2083 - "id": 190, 2084 - "change_id": "43e3c358-ccb7-4fd5-93ca-52d9b9d1c8fc", 2085 - "node_type": "option", 2086 - "title": "Third-party lookup services - Use existing services that cache Twitter user data", 2087 - "description": null, 2088 - "status": "completed", 2089 - "created_at": "2025-12-24T21:27:40.189045-05:00", 2090 - "updated_at": "2025-12-25T20:28:51.158043200-05:00", 2091 - "metadata_json": "{\"branch\":\"master\",\"confidence\":40}" 2092 - }, 2093 - { 2094 - "id": 191, 2095 - "change_id": "fe37a4eb-7247-4625-8ef4-e45986b11e24", 2096 - "node_type": "option", 2097 - "title": "BYOK (Bring Your Own Key) - User provides their X API credentials", 2098 - "description": null, 2099 - "status": "completed", 2100 - "created_at": "2025-12-24T21:27:42.001403800-05:00", 2101 - "updated_at": "2025-12-25T20:28:51.330860100-05:00", 2102 - "metadata_json": "{\"branch\":\"master\",\"confidence\":35}" 2103 - }, 2104 - { 2105 - "id": 192, 2106 - "change_id": "32e7fcf9-548e-4464-9ccb-c35da5840553", 2107 - "node_type": "option", 2108 - "title": "Hybrid: try public resolution first, fall back to manual/assisted workflow for failures", 2109 - "description": null, 2110 - "status": "completed", 2111 - "created_at": "2025-12-24T21:27:43.817921400-05:00", 2112 - "updated_at": "2025-12-25T20:28:51.511337600-05:00", 2113 - "metadata_json": "{\"branch\":\"master\",\"confidence\":65}" 2114 - }, 2115 - { 2116 - "id": 193, 2117 - "change_id": "73099c58-2157-452a-b943-fc04d117070a", 2118 - "node_type": "action", 2119 - "title": "Exploring Nitter instances and codebase for user_id to screen_name resolution", 2120 - "description": null, 2121 - "status": "completed", 2122 - "created_at": "2025-12-24T21:34:28.812168300-05:00", 2123 - "updated_at": "2025-12-25T20:28:51.682957-05:00", 2124 - "metadata_json": "{\"branch\":\"master\",\"confidence\":70}" 2125 - }, 2126 - { 2127 - "id": 194, 2128 - "change_id": "5c420dfa-78e6-4450-86fb-05488beb7141", 2129 - "node_type": "observation", 2130 - "title": "Nitter is dead (Feb 2024) - Twitter killed guest accounts. Running instances now require real account tokens. Not viable for our use case.", 2131 - "description": null, 2132 - "status": "completed", 2133 - "created_at": "2025-12-24T21:37:02.191252500-05:00", 2134 - "updated_at": "2025-12-25T20:28:51.868644100-05:00", 2135 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 2136 - }, 2137 - { 2138 - "id": 195, 2139 - "change_id": "00c634a0-1ad3-43b4-b130-41742a8581b2", 2140 - "node_type": "observation", 2141 - "title": "Sky Follower Bridge extension works differently - extracts usernames from visible X Following page (no user_id resolution needed), searches Bluesky API. But requires user to visit X in browser.", 2142 - "description": null, 2143 - "status": "completed", 2144 - "created_at": "2025-12-24T21:37:13.017860100-05:00", 2145 - "updated_at": "2025-12-25T20:28:52.021584300-05:00", 2146 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 2147 - }, 2148 - { 2149 - "id": 196, 2150 - "change_id": "ca3f4ccf-ca13-4f54-9f21-b267c4f202fb", 2151 - "node_type": "observation", 2152 - "title": "Free web tools (tweethunter.io, get-id-x.foundtt.com) convert user_id to screen_name, but single lookups only - no bulk/API access. Likely use Twitter API under hood.", 2153 - "description": null, 2154 - "status": "completed", 2155 - "created_at": "2025-12-24T21:37:14.862442-05:00", 2156 - "updated_at": "2025-12-25T20:28:52.177672200-05:00", 2157 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 2158 - }, 2159 - { 2160 - "id": 197, 2161 - "change_id": "6e7a605c-f9f0-4922-b677-e39b073fe852", 2162 - "node_type": "observation", 2163 - "title": "bird.makeup uses Twitter's internal GraphQL API (UserByScreenName endpoint) with guest tokens + hard-coded bearer tokens from Twitter's web client. Mimics browser behavior. Requires guest token rotation.", 2164 - "description": null, 2165 - "status": "completed", 2166 - "created_at": "2025-12-24T21:44:03.348278800-05:00", 2167 - "updated_at": "2025-12-25T20:28:52.329588100-05:00", 2168 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 2169 - }, 2170 - { 2171 - "id": 198, 2172 - "change_id": "06dd9486-e23d-413f-a5d5-121a5985b946", 2173 - "node_type": "observation", 2174 - "title": "Twitter GraphQL has UsersByRestIds endpoint - takes user_ids, returns full user data including screen_name. Batched (efficient). Available via twitter-api-client Python library. Requires cookies or guest session.", 2175 - "description": null, 2176 - "status": "completed", 2177 - "created_at": "2025-12-24T21:44:05.652057700-05:00", 2178 - "updated_at": "2025-12-25T20:28:52.486498700-05:00", 2179 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 2180 - }, 2181 - { 2182 - "id": 199, 2183 - "change_id": "a2c5b920-3f7d-4fbb-98a9-e47ebbea1d53", 2184 - "node_type": "option", 2185 - "title": "Use Twitter's internal GraphQL API (UsersByRestIds) with guest tokens - server-side batch resolution like bird.makeup does", 2186 - "description": null, 2187 - "status": "completed", 2188 - "created_at": "2025-12-24T21:44:18.877137600-05:00", 2189 - "updated_at": "2025-12-25T20:28:52.662921500-05:00", 2190 - "metadata_json": "{\"branch\":\"master\",\"confidence\":55}" 2191 - }, 2192 - { 2193 - "id": 200, 2194 - "change_id": "b35cc106-827b-453b-9cef-8c3d5b21f153", 2195 - "node_type": "option", 2196 - "title": "Recommend Sky Follower Bridge extension - user visits X Following page, extension extracts visible usernames (no user_id resolution needed)", 2197 - "description": null, 2198 - "status": "completed", 2199 - "created_at": "2025-12-24T21:44:20.815603600-05:00", 2200 - "updated_at": "2025-12-25T20:28:52.833590700-05:00", 2201 - "metadata_json": "{\"branch\":\"master\",\"confidence\":70}" 2202 - }, 2203 - { 2204 - "id": 201, 2205 - "change_id": "8c5b84c3-2fe7-4295-900f-46da5aa5bc7d", 2206 - "node_type": "action", 2207 - "title": "Exploring: logged-in user scenarios, guided extension flow, mobile browser extension support", 2208 - "description": null, 2209 - "status": "completed", 2210 - "created_at": "2025-12-24T21:49:50.584503-05:00", 2211 - "updated_at": "2025-12-25T20:28:52.985059400-05:00", 2212 - "metadata_json": "{\"branch\":\"master\",\"confidence\":75}" 2213 - }, 2214 - { 2215 - "id": 202, 2216 - "change_id": "c75bd7d2-2f72-462f-bcb9-96fdf0596f78", 2217 - "node_type": "observation", 2218 - "title": "Nitter with logged-in accounts: possible but fragile. Requires cookie extraction (twikit), accounts get locked after ~1 month, needs 2FA. Still requires operator to maintain sessions - not viable for user self-service.", 2219 - "description": null, 2220 - "status": "completed", 2221 - "created_at": "2025-12-24T21:54:10.472455-05:00", 2222 - "updated_at": "2025-12-25T20:28:53.154229500-05:00", 2223 - "metadata_json": "{\"branch\":\"master\",\"confidence\":80}" 2224 - }, 2225 - { 2226 - "id": 203, 2227 - "change_id": "de39bf24-50de-468b-8c96-beb48fb0b4dc", 2228 - "node_type": "observation", 2229 - "title": "Mobile extension support: Android (Firefox, Kiwi, Lemur) supports extensions. iOS Safari blocks bookmarklet JS execution since iOS 15. Chrome Android bookmarklets work via address bar typing. iOS is problematic.", 2230 - "description": null, 2231 - "status": "completed", 2232 - "created_at": "2025-12-24T21:54:12.748288800-05:00", 2233 - "updated_at": "2025-12-25T20:28:53.304032600-05:00", 2234 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 2235 - }, 2236 - { 2237 - "id": 204, 2238 - "change_id": "3edc8b99-be7b-4275-bc7a-95244c504def", 2239 - "node_type": "observation", 2240 - "title": "Twitter DOM scraping: data-testid selectors (UserName, tweet) are stable. Class names are volatile (css-xxxxx). Can scroll + collect via setTimeout loop. Works from browser console or extension.", 2241 - "description": null, 2242 - "status": "completed", 2243 - "created_at": "2025-12-24T21:54:14.693164400-05:00", 2244 - "updated_at": "2025-12-25T20:28:53.447433100-05:00", 2245 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 2246 - }, 2247 - { 2248 - "id": 205, 2249 - "change_id": "94cd0e5a-e336-4338-b1fe-06f736724d61", 2250 - "node_type": "decision", 2251 - "title": "Choose Twitter extraction approach: extension-only vs hybrid (extension + bookmarklet) vs defer to existing tools (Sky Follower Bridge)", 2252 - "description": null, 2253 - "status": "completed", 2254 - "created_at": "2025-12-24T21:54:33.357036500-05:00", 2255 - "updated_at": "2025-12-25T20:28:53.598287400-05:00", 2256 - "metadata_json": "{\"branch\":\"master\",\"confidence\":65}" 2257 - }, 2258 - { 2259 - "id": 206, 2260 - "change_id": "b24507a7-5afe-4cae-bd72-8bbf360d4f05", 2261 - "node_type": "option", 2262 - "title": "Build ATlast browser extension: scrapes Following page, auto-uploads to ATlast, searches Bluesky. Desktop Chrome/Firefox/Edge only.", 2263 - "description": null, 2264 - "status": "completed", 2265 - "created_at": "2025-12-24T21:54:37.257977100-05:00", 2266 - "updated_at": "2025-12-25T20:28:53.764906800-05:00", 2267 - "metadata_json": "{\"branch\":\"master\",\"confidence\":70}" 2268 - }, 2269 - { 2270 - "id": 207, 2271 - "change_id": "b632ca63-ee7d-4ad0-b20e-d1acf1528f29", 2272 - "node_type": "option", 2273 - "title": "Guided console script flow: ATlast provides copy-paste JS, user runs in DevTools, copies output, pastes into ATlast. Works on any desktop browser.", 2274 - "description": null, 2275 - "status": "completed", 2276 - "created_at": "2025-12-24T21:54:39.243220600-05:00", 2277 - "updated_at": "2025-12-25T20:28:53.946062600-05:00", 2278 - "metadata_json": "{\"branch\":\"master\",\"confidence\":60}" 2279 - }, 2280 - { 2281 - "id": 208, 2282 - "change_id": "f9c4aa5c-d73c-4e1b-b9cf-c724c17c24ea", 2283 - "node_type": "option", 2284 - "title": "Partner with/recommend Sky Follower Bridge: already built, maintained, multi-platform. ATlast focuses on data export files only.", 2285 - "description": null, 2286 - "status": "completed", 2287 - "created_at": "2025-12-24T21:54:41.213585600-05:00", 2288 - "updated_at": "2025-12-25T20:28:54.119472-05:00", 2289 - "metadata_json": "{\"branch\":\"master\",\"confidence\":75}" 2290 - }, 2291 - { 2292 - "id": 209, 2293 - "change_id": "d74af719-eb3c-4686-87d4-0a628b94435c", 2294 - "node_type": "option", 2295 - "title": "Hybrid mobile approach: Android users use Firefox+extension, iOS users directed to desktop or data export workflow.", 2296 - "description": null, 2297 - "status": "completed", 2298 - "created_at": "2025-12-24T21:54:43.197638400-05:00", 2299 - "updated_at": "2025-12-25T20:28:54.279188900-05:00", 2300 - "metadata_json": "{\"branch\":\"master\",\"confidence\":55}" 2301 - }, 2302 - { 2303 - "id": 210, 2304 - "change_id": "7d9749ae-a2df-49c7-b460-4d67699da0d2", 2305 - "node_type": "outcome", 2306 - "title": "Decision: Build ATlast extension rather than defer to Sky Follower Bridge. Provides integrated UX, ATlast branding, control over features.", 2307 - "description": null, 2308 - "status": "completed", 2309 - "created_at": "2025-12-24T21:57:28.158619100-05:00", 2310 - "updated_at": "2025-12-25T20:28:54.440713700-05:00", 2311 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 2312 - }, 2313 - { 2314 - "id": 211, 2315 - "change_id": "2af38501-9513-4890-b22f-a9093f347f1b", 2316 - "node_type": "observation", 2317 - "title": "Twitter data export confirmed: only contains user_ids, not usernames. Data export path not viable for Twitter - must use live scraping approach.", 2318 - "description": null, 2319 - "status": "completed", 2320 - "created_at": "2025-12-24T21:57:29.885392-05:00", 2321 - "updated_at": "2025-12-25T20:28:54.599116900-05:00", 2322 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 2323 - }, 2324 - { 2325 - "id": 212, 2326 - "change_id": "747db6d8-45f0-4598-84c0-521318603a47", 2327 - "node_type": "action", 2328 - "title": "Exploring iOS Shortcuts as alternative to browser extension for iOS users", 2329 - "description": null, 2330 - "status": "completed", 2331 - "created_at": "2025-12-24T21:57:33.637829900-05:00", 2332 - "updated_at": "2025-12-25T20:28:54.780851500-05:00", 2333 - "metadata_json": "{\"branch\":\"master\",\"confidence\":60}" 2334 - }, 2335 - { 2336 - "id": 213, 2337 - "change_id": "9b8df205-85ae-4907-bd67-d98606b99b80", 2338 - "node_type": "observation", 2339 - "title": "iOS Shortcuts 'Run JavaScript on Webpage' CAN access authenticated Safari pages via share sheet. BUT has strict timeout (few seconds). Infinite scroll with setTimeout would fail. Can only grab currently visible content.", 2340 - "description": null, 2341 - "status": "completed", 2342 - "created_at": "2025-12-25T11:44:56.295986200-05:00", 2343 - "updated_at": "2025-12-25T20:28:54.964208100-05:00", 2344 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 2345 - }, 2346 - { 2347 - "id": 214, 2348 - "change_id": "c6e020c1-3444-43fb-9b75-a35cef160b5e", 2349 - "node_type": "observation", 2350 - "title": "iOS Safari Web Extensions (iOS 15+) use WebExtensions API - same as Chrome/Firefox. Content scripts run without timeout limits. BUT requires App Store distribution as part of an iOS app.", 2351 - "description": null, 2352 - "status": "completed", 2353 - "created_at": "2025-12-25T11:44:57.917114500-05:00", 2354 - "updated_at": "2025-12-25T20:28:55.180690-05:00", 2355 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 2356 - }, 2357 - { 2358 - "id": 215, 2359 - "change_id": "83fabf36-857a-4b0c-9713-d8062374fb6d", 2360 - "node_type": "option", 2361 - "title": "iOS Safari Web Extension: Build iOS app with Safari extension component. Full scraping capability. Requires App Store approval and iOS app wrapper.", 2362 - "description": null, 2363 - "status": "completed", 2364 - "created_at": "2025-12-25T11:44:59.390903800-05:00", 2365 - "updated_at": "2025-12-25T20:28:55.363281300-05:00", 2366 - "metadata_json": "{\"branch\":\"master\",\"confidence\":50}" 2367 - }, 2368 - { 2369 - "id": 216, 2370 - "change_id": "d8c3f311-545b-4021-bc0a-424bdad2b26c", 2371 - "node_type": "option", 2372 - "title": "iOS Shortcuts partial solution: User manually scrolls to load all follows, then runs Shortcut to grab visible usernames. Multiple runs needed. Friction but no app install.", 2373 - "description": null, 2374 - "status": "completed", 2375 - "created_at": "2025-12-25T11:45:00.878455400-05:00", 2376 - "updated_at": "2025-12-25T20:28:55.528923400-05:00", 2377 - "metadata_json": "{\"branch\":\"master\",\"confidence\":45}" 2378 - }, 2379 - { 2380 - "id": 217, 2381 - "change_id": "8b8c65da-aa6b-4c0c-9cef-9dd7bee671bc", 2382 - "node_type": "action", 2383 - "title": "Documenting Twitter extension plan in PLAN.md", 2384 - "description": null, 2385 - "status": "completed", 2386 - "created_at": "2025-12-25T11:49:19.000575700-05:00", 2387 - "updated_at": "2025-12-25T20:28:55.685318400-05:00", 2388 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 2389 - }, 2390 - { 2391 - "id": 218, 2392 - "change_id": "24a151a3-df0c-495f-bdaf-bef7d10a19d3", 2393 - "node_type": "decision", 2394 - "title": "Choose data handoff method: URL params vs POST API vs File download vs Clipboard", 2395 - "description": null, 2396 - "status": "completed", 2397 - "created_at": "2025-12-25T11:52:07.068146500-05:00", 2398 - "updated_at": "2025-12-25T20:28:55.872754500-05:00", 2399 - "metadata_json": "{\"branch\":\"master\",\"confidence\":65}" 2400 - }, 2401 - { 2402 - "id": 219, 2403 - "change_id": "c80b61ff-bb1b-4867-9e1e-0ab48a0c64db", 2404 - "node_type": "outcome", 2405 - "title": "Data handoff: POST to API endpoint. New Netlify function will receive usernames from extension.", 2406 - "description": null, 2407 - "status": "completed", 2408 - "created_at": "2025-12-25T11:59:54.233674400-05:00", 2409 - "updated_at": "2025-12-25T20:28:56.042547300-05:00", 2410 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 2411 - }, 2412 - { 2413 - "id": 220, 2414 - "change_id": "e51fb65e-6765-4f93-a5cd-ca7076f69490", 2415 - "node_type": "outcome", 2416 - "title": "MVP scope: Twitter Following page only. Fastest path to value. Followers/Lists deferred.", 2417 - "description": null, 2418 - "status": "completed", 2419 - "created_at": "2025-12-25T11:59:55.996600300-05:00", 2420 - "updated_at": "2025-12-25T20:28:56.175260300-05:00", 2421 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 2422 - }, 2423 - { 2424 - "id": 221, 2425 - "change_id": "914e0cd4-cac2-44e4-a588-2e75c946cba1", 2426 - "node_type": "outcome", 2427 - "title": "iOS deferred: Focus on desktop Chrome/Firefox first. iOS users use desktop browser for now.", 2428 - "description": null, 2429 - "status": "completed", 2430 - "created_at": "2025-12-25T11:59:57.486482-05:00", 2431 - "updated_at": "2025-12-25T20:28:56.311595300-05:00", 2432 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 2433 - }, 2434 - { 2435 - "id": 222, 2436 - "change_id": "92ef5b60-58ae-4f28-8d1e-d3209fa37295", 2437 - "node_type": "outcome", 2438 - "title": "Platform scope: Twitter only for v1, but architecture accommodates Threads/Instagram/TikTok for later.", 2439 - "description": null, 2440 - "status": "completed", 2441 - "created_at": "2025-12-25T11:59:59.101111400-05:00", 2442 - "updated_at": "2025-12-25T20:28:56.454453700-05:00", 2443 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 2444 - }, 2445 - { 2446 - "id": 223, 2447 - "change_id": "94e9d9ba-3e00-4adc-8842-ec22ba6a3296", 2448 - "node_type": "outcome", 2449 - "title": "PLAN.md created with full architecture: extensible scraper pattern, POST API handoff, platform detection, implementation phases", 2450 - "description": null, 2451 - "status": "completed", 2452 - "created_at": "2025-12-25T12:02:29.281090400-05:00", 2453 - "updated_at": "2025-12-25T20:28:56.619252700-05:00", 2454 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 2455 - }, 2456 - { 2457 - "id": 224, 2458 - "change_id": "90b12791-3381-4392-a6f0-efba9272d3cf", 2459 - "node_type": "decision", 2460 - "title": "Choose extension code location: subdirectory vs monorepo vs separate repo", 2461 - "description": null, 2462 - "status": "completed", 2463 - "created_at": "2025-12-25T12:16:10.959595900-05:00", 2464 - "updated_at": "2025-12-25T20:28:56.804059500-05:00", 2465 - "metadata_json": "{\"branch\":\"master\",\"confidence\":70}" 2466 - }, 2467 - { 2468 - "id": 225, 2469 - "change_id": "a28cc1c3-f650-4bfd-a013-de15d75c3c50", 2470 - "node_type": "outcome", 2471 - "title": "Code location: Monorepo with shared packages. Cleaner shared types, explicit separation, easier extension build isolation.", 2472 - "description": null, 2473 - "status": "completed", 2474 - "created_at": "2025-12-25T12:22:56.833471-05:00", 2475 - "updated_at": "2025-12-25T20:28:56.996599800-05:00", 2476 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 2477 - }, 2478 - { 2479 - "id": 226, 2480 - "change_id": "b9735e16-f3dd-4846-9356-67d4f2a650c4", 2481 - "node_type": "outcome", 2482 - "title": "Extension name: ATlast Importer", 2483 - "description": null, 2484 - "status": "completed", 2485 - "created_at": "2025-12-25T12:22:58.495651600-05:00", 2486 - "updated_at": "2025-12-25T20:28:57.152995400-05:00", 2487 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 2488 - }, 2489 - { 2490 - "id": 227, 2491 - "change_id": "783fef0a-758c-43da-9e06-81194666f91c", 2492 - "node_type": "outcome", 2493 - "title": "Monorepo tool: pnpm workspaces. Fast, disk-efficient, no extra config needed.", 2494 - "description": null, 2495 - "status": "completed", 2496 - "created_at": "2025-12-25T12:23:38.264057800-05:00", 2497 - "updated_at": "2025-12-25T20:28:57.330076100-05:00", 2498 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 2499 - }, 2500 - { 2501 - "id": 228, 2502 - "change_id": "7958ec7b-ff18-41d4-b1e1-fc9fa5603a1b", 2503 - "node_type": "action", 2504 - "title": "Installing pnpm globally", 2505 - "description": null, 2506 - "status": "completed", 2507 - "created_at": "2025-12-25T12:31:53.304358200-05:00", 2508 - "updated_at": "2025-12-25T20:28:57.476758600-05:00", 2509 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 2510 - }, 2511 - { 2512 - "id": 229, 2513 - "change_id": "34e48e73-6186-4652-b2a3-bdb9c1f8b1b9", 2514 - "node_type": "outcome", 2515 - "title": "pnpm installed successfully", 2516 - "description": null, 2517 - "status": "completed", 2518 - "created_at": "2025-12-25T12:32:05.671781500-05:00", 2519 - "updated_at": "2025-12-25T20:28:57.616991200-05:00", 2520 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 2521 - }, 2522 - { 2523 - "id": 230, 2524 - "change_id": "32ad3821-b4b6-4388-81b1-7463376cc527", 2525 - "node_type": "action", 2526 - "title": "Creating pnpm workspace configuration", 2527 - "description": null, 2528 - "status": "completed", 2529 - "created_at": "2025-12-25T12:32:27.346988300-05:00", 2530 - "updated_at": "2025-12-25T20:28:57.785245300-05:00", 2531 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 2532 - }, 2533 - { 2534 - "id": 231, 2535 - "change_id": "3420ad4c-dfc2-49bf-b860-acac0d7da5cf", 2536 - "node_type": "outcome", 2537 - "title": "Created packages/ directory structure", 2538 - "description": null, 2539 - "status": "completed", 2540 - "created_at": "2025-12-25T12:32:48.932847100-05:00", 2541 - "updated_at": "2025-12-25T20:28:57.946014900-05:00", 2542 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 2543 - }, 2544 - { 2545 - "id": 232, 2546 - "change_id": "97cf813e-4710-48d4-ae53-f240896d6441", 2547 - "node_type": "outcome", 2548 - "title": "Moved web app files to packages/web/", 2549 - "description": null, 2550 - "status": "completed", 2551 - "created_at": "2025-12-25T12:39:06.906855200-05:00", 2552 - "updated_at": "2025-12-25T20:28:58.093258700-05:00", 2553 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 2554 - }, 2555 - { 2556 - "id": 233, 2557 - "change_id": "dafc1ae8-e56b-48a8-a9be-0729cfd5f45e", 2558 - "node_type": "outcome", 2559 - "title": "Moved Netlify functions to packages/functions/", 2560 - "description": null, 2561 - "status": "completed", 2562 - "created_at": "2025-12-25T12:39:30.244695200-05:00", 2563 - "updated_at": "2025-12-25T20:28:58.242753600-05:00", 2564 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 2565 - }, 2566 - { 2567 - "id": 234, 2568 - "change_id": "2f522f67-f084-4b85-afb0-ac11f8d3e62d", 2569 - "node_type": "outcome", 2570 - "title": "Created packages/shared with Platform and Import types", 2571 - "description": null, 2572 - "status": "completed", 2573 - "created_at": "2025-12-25T12:40:10.860005900-05:00", 2574 - "updated_at": "2025-12-25T20:28:58.388876500-05:00", 2575 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 2576 - }, 2577 - { 2578 - "id": 235, 2579 - "change_id": "237ca2f4-5cc4-4203-88de-0d266a76448c", 2580 - "node_type": "outcome", 2581 - "title": "Created package.json for web and functions packages", 2582 - "description": null, 2583 - "status": "completed", 2584 - "created_at": "2025-12-25T12:40:48.235525500-05:00", 2585 - "updated_at": "2025-12-25T20:28:58.530209-05:00", 2586 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 2587 - }, 2588 - { 2589 - "id": 236, 2590 - "change_id": "481375b2-6a7d-4e94-af79-7c40fc44d9b9", 2591 - "node_type": "outcome", 2592 - "title": "Updated netlify.toml for monorepo paths", 2593 - "description": null, 2594 - "status": "completed", 2595 - "created_at": "2025-12-25T12:41:14.525795300-05:00", 2596 - "updated_at": "2025-12-25T20:28:58.696573900-05:00", 2597 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 2598 - }, 2599 - { 2600 - "id": 237, 2601 - "change_id": "04b2be42-4708-477b-96f7-aecb428913b9", 2602 - "node_type": "outcome", 2603 - "title": "Updated root package.json for monorepo", 2604 - "description": null, 2605 - "status": "completed", 2606 - "created_at": "2025-12-25T12:41:32.390877100-05:00", 2607 - "updated_at": "2025-12-25T20:28:58.883354700-05:00", 2608 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 2609 - }, 2610 - { 2611 - "id": 238, 2612 - "change_id": "58798ef2-4fa4-46b3-9b5d-98610031a0e6", 2613 - "node_type": "action", 2614 - "title": "Installing pnpm dependencies", 2615 - "description": null, 2616 - "status": "completed", 2617 - "created_at": "2025-12-25T12:41:47.124126700-05:00", 2618 - "updated_at": "2025-12-25T20:28:59.032552600-05:00", 2619 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 2620 - }, 2621 - { 2622 - "id": 239, 2623 - "change_id": "e155bd76-d5ed-4eca-99a4-51db8f76364d", 2624 - "node_type": "outcome", 2625 - "title": "pnpm dependencies installed successfully", 2626 - "description": null, 2627 - "status": "completed", 2628 - "created_at": "2025-12-25T12:45:05.585546200-05:00", 2629 - "updated_at": "2025-12-25T20:28:59.211963-05:00", 2630 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 2631 - }, 2632 - { 2633 - "id": 240, 2634 - "change_id": "99a056dc-09c8-4626-8e55-70ce9362327b", 2635 - "node_type": "outcome", 2636 - "title": "Build and dev commands working correctly", 2637 - "description": null, 2638 - "status": "completed", 2639 - "created_at": "2025-12-25T12:46:17.696750-05:00", 2640 - "updated_at": "2025-12-25T20:28:59.409127800-05:00", 2641 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 2642 - }, 2643 - { 2644 - "id": 241, 2645 - "change_id": "d1305e02-4692-4c26-8d67-5591ce4b27b3", 2646 - "node_type": "outcome", 2647 - "title": "Phase 0 monorepo migration completed successfully", 2648 - "description": null, 2649 - "status": "completed", 2650 - "created_at": "2025-12-25T12:47:54.577738400-05:00", 2651 - "updated_at": "2025-12-25T20:28:59.608666700-05:00", 2652 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"c3e7afa\",\"confidence\":100}" 2653 - }, 2654 - { 2655 - "id": 242, 2656 - "change_id": "c5dd8e44-1c7b-45d9-817e-1998c87e4ffe", 2657 - "node_type": "action", 2658 - "title": "Configured Netlify dev for monorepo with --filter flag", 2659 - "description": null, 2660 - "status": "completed", 2661 - "created_at": "2025-12-25T13:21:13.981980400-05:00", 2662 - "updated_at": "2025-12-25T20:28:59.822236700-05:00", 2663 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 2664 - }, 2665 - { 2666 - "id": 243, 2667 - "change_id": "af843252-682e-4c02-a62c-a26188054044", 2668 - "node_type": "outcome", 2669 - "title": "Dev server working with npx netlify-cli dev --filter @atlast/web", 2670 - "description": null, 2671 - "status": "completed", 2672 - "created_at": "2025-12-25T13:21:15.443574800-05:00", 2673 - "updated_at": "2025-12-25T20:28:59.981665700-05:00", 2674 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 2675 - }, 2676 - { 2677 - "id": 244, 2678 - "change_id": "4c0a968c-c569-418f-93f3-ca6b09b24f50", 2679 - "node_type": "outcome", 2680 - "title": "Committed Netlify dev configuration for monorepo", 2681 - "description": null, 2682 - "status": "completed", 2683 - "created_at": "2025-12-25T13:22:42.743106400-05:00", 2684 - "updated_at": "2025-12-25T20:29:00.147960800-05:00", 2685 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"32cdee3\",\"confidence\":100}" 2686 - }, 2687 - { 2688 - "id": 245, 2689 - "change_id": "8efca7fe-42f2-4e40-adee-34ccfcc6e475", 2690 - "node_type": "action", 2691 - "title": "Implementing Phase 1: Chrome Extension MVP", 2692 - "description": null, 2693 - "status": "completed", 2694 - "created_at": "2025-12-25T13:33:30.200281700-05:00", 2695 - "updated_at": "2025-12-25T20:29:00.308394-05:00", 2696 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 2697 - }, 2698 - { 2699 - "id": 246, 2700 - "change_id": "d4d45374-5507-48ef-be2a-4e21a4a109a7", 2701 - "node_type": "outcome", 2702 - "title": "Phase 1 Chrome Extension MVP complete: Built browser extension with Twitter scraping, Netlify backend API, and web app integration. Extension scrapes Twitter Following page, uploads to ATlast API, searches Bluesky. All 13 tasks completed successfully.", 2703 - "description": null, 2704 - "status": "completed", 2705 - "created_at": "2025-12-25T13:52:32.693778200-05:00", 2706 - "updated_at": "2025-12-25T20:29:00.488222-05:00", 2707 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"ba29fd6\",\"confidence\":95}" 2708 - }, 2709 - { 2710 - "id": 247, 2711 - "change_id": "c8276478-87e3-43b3-b763-e7964a776fad", 2712 - "node_type": "action", 2713 - "title": "Fixing Phase 1 issues: UI consistency, URL updates, extension detection debugging, UX improvements", 2714 - "description": null, 2715 - "status": "completed", 2716 - "created_at": "2025-12-25T14:06:47.786619100-05:00", 2717 - "updated_at": "2025-12-25T20:29:00.686531100-05:00", 2718 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 2719 - }, 2720 - { 2721 - "id": 248, 2722 - "change_id": "c887a416-080a-4b42-a1fc-536c8d6edd74", 2723 - "node_type": "outcome", 2724 - "title": "Fixed Phase 1 issues: Updated popup UI to match web app colors (purple/cyan/orange), updated API URL to atlast.byarielm.fyi, fixed URL pattern to detect following pages (added flexibility for trailing slashes), added comprehensive console logging for debugging. Documented testing steps in README. Proposed UX improvements: auto-navigate button + contextual hints.", 2725 - "description": null, 2726 - "status": "completed", 2727 - "created_at": "2025-12-25T16:28:54.299966500-05:00", 2728 - "updated_at": "2025-12-25T20:29:00.854847500-05:00", 2729 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 2730 - }, 2731 - { 2732 - "id": 249, 2733 - "change_id": "582e4e97-99df-4686-a9ef-762b851a62ec", 2734 - "node_type": "action", 2735 - "title": "Debugging extension state communication: content script detects page but popup shows idle state", 2736 - "description": null, 2737 - "status": "completed", 2738 - "created_at": "2025-12-25T18:35:58.553577600-05:00", 2739 - "updated_at": "2025-12-25T20:29:01.021646300-05:00", 2740 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 2741 - }, 2742 - { 2743 - "id": 250, 2744 - "change_id": "4655082d-fab8-4415-a088-c41552402127", 2745 - "node_type": "outcome", 2746 - "title": "Fixed critical messaging bug in extension: onMessage wrapper was discarding handler return values, only sending {success: true}. This prevented popup from receiving state updates from background worker. Now properly forwards actual data.", 2747 - "description": null, 2748 - "status": "completed", 2749 - "created_at": "2025-12-25T18:52:37.132035600-05:00", 2750 - "updated_at": "2025-12-25T20:29:01.201613200-05:00", 2751 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"0718100\",\"confidence\":95}" 2752 - }, 2753 - { 2754 - "id": 251, 2755 - "change_id": "072f963c-3e06-445a-be4f-0a045e27c6c2", 2756 - "node_type": "action", 2757 - "title": "Adding dark mode support to extension popup UI", 2758 - "description": null, 2759 - "status": "completed", 2760 - "created_at": "2025-12-25T18:56:20.061388800-05:00", 2761 - "updated_at": "2025-12-25T20:29:01.368606700-05:00", 2762 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 2763 - }, 2764 - { 2765 - "id": 252, 2766 - "change_id": "b5cd9aed-c8cc-4d70-8790-b11a21d751fc", 2767 - "node_type": "outcome", 2768 - "title": "Added dark mode support to extension popup using CSS media queries for prefers-color-scheme. All UI elements now have dark variants matching web app's dark theme.", 2769 - "description": null, 2770 - "status": "completed", 2771 - "created_at": "2025-12-25T19:00:24.260632-05:00", 2772 - "updated_at": "2025-12-25T20:29:01.534399500-05:00", 2773 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"0718100\",\"confidence\":90}" 2774 - }, 2775 - { 2776 - "id": 253, 2777 - "change_id": "af40219a-2094-4e5f-8e96-4b5c9850669b", 2778 - "node_type": "action", 2779 - "title": "Testing extension scraping functionality end-to-end", 2780 - "description": null, 2781 - "status": "completed", 2782 - "created_at": "2025-12-25T19:03:39.068139400-05:00", 2783 - "updated_at": "2025-12-25T20:29:01.739170100-05:00", 2784 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 2785 - }, 2786 - { 2787 - "id": 254, 2788 - "change_id": "c765751c-c23b-4a27-bfc9-e118b799e1cc", 2789 - "node_type": "observation", 2790 - "title": "Twitter scraper found 0 users despite 3 visible on page", 2791 - "description": null, 2792 - "status": "completed", 2793 - "created_at": "2025-12-25T19:16:57.382459700-05:00", 2794 - "updated_at": "2025-12-25T20:29:01.901149200-05:00", 2795 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 2796 - }, 2797 - { 2798 - "id": 255, 2799 - "change_id": "9f99eb8c-d15b-41b0-af92-c36de5048fdd", 2800 - "node_type": "action", 2801 - "title": "Inspecting Twitter DOM to identify correct user element selector", 2802 - "description": null, 2803 - "status": "completed", 2804 - "created_at": "2025-12-25T19:17:04.041798100-05:00", 2805 - "updated_at": "2025-12-25T20:29:02.085218400-05:00", 2806 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"HEAD~1\",\"confidence\":95}" 2807 - }, 2808 - { 2809 - "id": 256, 2810 - "change_id": "3f9c13ee-b216-4e00-ab04-9ad45712228a", 2811 - "node_type": "outcome", 2812 - "title": "Discovered [data-testid=\"UserCell\"] is correct selector, not UserName", 2813 - "description": null, 2814 - "status": "completed", 2815 - "created_at": "2025-12-25T19:17:11.208998400-05:00", 2816 - "updated_at": "2025-12-25T20:29:02.251368700-05:00", 2817 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 2818 - }, 2819 - { 2820 - "id": 257, 2821 - "change_id": "eccb2bb1-413e-4d9f-8eb8-eb753bd5b82b", 2822 - "node_type": "outcome", 2823 - "title": "Fixed scraper selector and added upload validation for 0 results", 2824 - "description": null, 2825 - "status": "completed", 2826 - "created_at": "2025-12-25T19:17:27.907683600-05:00", 2827 - "updated_at": "2025-12-25T20:29:02.401055-05:00", 2828 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"c35fb0d\",\"confidence\":95,\"files\":[\"packages/extension/src/content/scrapers/twitter-scraper.ts\",\"packages/extension/src/popup/popup.ts\"]}" 2829 - }, 2830 - { 2831 - "id": 258, 2832 - "change_id": "b8c6cd90-7f32-461e-aad5-537cc1cbfafe", 2833 - "node_type": "goal", 2834 - "title": "Fix extension 'Open on ATlast' button hanging issue", 2835 - "description": null, 2836 - "status": "completed", 2837 - "created_at": "2025-12-25T20:33:35.514071900-05:00", 2838 - "updated_at": "2025-12-25T20:55:39.361373900-05:00", 2839 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"prompt\":\"let's working on 2, right now the \\\"open on atlast\\\" just hangs. we need this to work for a dev env and production. dev should test against twitter acct following from justadev_atlast and use dev server for atlast web + db actions. production should use atlast.byarielm.fyi\"}" 2840 - }, 2841 - { 2842 - "id": 259, 2843 - "change_id": "c68dfdc1-7f88-446d-b5dd-7eb514bc26c8", 2844 - "node_type": "action", 2845 - "title": "Analyzing extension build process and environment configuration", 2846 - "description": null, 2847 - "status": "completed", 2848 - "created_at": "2025-12-25T20:35:13.533009500-05:00", 2849 - "updated_at": "2025-12-25T20:55:39.533175900-05:00", 2850 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 2851 - }, 2852 - { 2853 - "id": 260, 2854 - "change_id": "7083c996-e161-497c-abfd-07e90be3fdc9", 2855 - "node_type": "observation", 2856 - "title": "Extension build doesn't inject environment variables - import.meta.env is undefined at runtime", 2857 - "description": null, 2858 - "status": "completed", 2859 - "created_at": "2025-12-25T20:35:29.938536500-05:00", 2860 - "updated_at": "2025-12-25T20:55:39.689178100-05:00", 2861 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 2862 - }, 2863 - { 2864 - "id": 261, 2865 - "change_id": "570173f7-1960-479f-a99a-3d2433e1f8ee", 2866 - "node_type": "action", 2867 - "title": "Update extension build to inject environment variables at build time", 2868 - "description": null, 2869 - "status": "completed", 2870 - "created_at": "2025-12-25T20:35:40.623066400-05:00", 2871 - "updated_at": "2025-12-25T20:55:39.870362300-05:00", 2872 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 2873 - }, 2874 - { 2875 - "id": 262, 2876 - "change_id": "b8097a68-a63f-4cb6-aeac-2ed746e90126", 2877 - "node_type": "observation", 2878 - "title": "extension-import endpoint exists and works - stores data in-memory, returns /import/{id} redirectUrl", 2879 - "description": null, 2880 - "status": "completed", 2881 - "created_at": "2025-12-25T20:39:48.726836800-05:00", 2882 - "updated_at": "2025-12-25T20:55:40.038602600-05:00", 2883 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 2884 - }, 2885 - { 2886 - "id": 263, 2887 - "change_id": "b5109344-a5d3-43b3-b743-b06730453514", 2888 - "node_type": "observation", 2889 - "title": "Web app missing React Router setup - ExtensionImport page exists but no routing configured", 2890 - "description": null, 2891 - "status": "completed", 2892 - "created_at": "2025-12-25T20:41:08.737003400-05:00", 2893 - "updated_at": "2025-12-25T20:55:40.194612-05:00", 2894 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 2895 - }, 2896 - { 2897 - "id": 264, 2898 - "change_id": "4e9b17fd-14c8-4fbb-8b23-020dbc6ba364", 2899 - "node_type": "decision", 2900 - "title": "Choose approach for handling extension import: Add React Router vs URL params vs localStorage", 2901 - "description": null, 2902 - "status": "completed", 2903 - "created_at": "2025-12-25T20:41:17.897166200-05:00", 2904 - "updated_at": "2025-12-25T20:55:40.355350300-05:00", 2905 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 2906 - }, 2907 - { 2908 - "id": 265, 2909 - "change_id": "ae943152-ffe4-468e-b4ca-e806996be861", 2910 - "node_type": "outcome", 2911 - "title": "Add React Router - ExtensionImport page already uses routing hooks, cleanest approach for URL-based navigation", 2912 - "description": null, 2913 - "status": "completed", 2914 - "created_at": "2025-12-25T20:41:32.594148300-05:00", 2915 - "updated_at": "2025-12-25T20:55:40.513677-05:00", 2916 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 2917 - }, 2918 - { 2919 - "id": 266, 2920 - "change_id": "b2720400-7337-4fac-aca8-822cfb79e33f", 2921 - "node_type": "action", 2922 - "title": "Installing react-router-dom and setting up routes", 2923 - "description": null, 2924 - "status": "completed", 2925 - "created_at": "2025-12-25T20:41:46.555915400-05:00", 2926 - "updated_at": "2025-12-25T20:55:40.663101700-05:00", 2927 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 2928 - }, 2929 - { 2930 - "id": 267, 2931 - "change_id": "72263b57-78a4-4282-a805-0af9722677e1", 2932 - "node_type": "observation", 2933 - "title": "CRITICAL BUG: extension-import and get-extension-import use separate in-memory Maps - data not shared between serverless functions", 2934 - "description": null, 2935 - "status": "completed", 2936 - "created_at": "2025-12-25T20:43:54.283917100-05:00", 2937 - "updated_at": "2025-12-25T20:55:40.816595200-05:00", 2938 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 2939 - }, 2940 - { 2941 - "id": 268, 2942 - "change_id": "440f0c78-a314-4ec5-b56d-4c00ce7df8d4", 2943 - "node_type": "action", 2944 - "title": "Create shared import store module to fix serverless function data sharing", 2945 - "description": null, 2946 - "status": "completed", 2947 - "created_at": "2025-12-25T20:44:17.619685100-05:00", 2948 - "updated_at": "2025-12-25T20:55:40.977099300-05:00", 2949 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 2950 - }, 2951 - { 2952 - "id": 269, 2953 - "change_id": "25c635ed-46d5-4933-9e90-b67556bbdf27", 2954 - "node_type": "outcome", 2955 - "title": "Fixed 'Open on ATlast' hanging issues: added React Router, created shared import store, configured dev/prod builds", 2956 - "description": null, 2957 - "status": "completed", 2958 - "created_at": "2025-12-25T20:45:43.007046800-05:00", 2959 - "updated_at": "2025-12-25T20:55:41.141035900-05:00", 2960 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 2961 - }, 2962 - { 2963 - "id": 270, 2964 - "change_id": "8cf80c58-e909-4f0b-85e8-ac15d7cf3640", 2965 - "node_type": "goal", 2966 - "title": "Fix port 8888 conflict and add dev server detection to extension", 2967 - "description": null, 2968 - "status": "completed", 2969 - "created_at": "2025-12-25T21:29:47.036747-05:00", 2970 - "updated_at": "2025-12-25T21:43:03.775606200-05:00", 2971 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"prompt\":\"attempts to initiate the dev server fail with \\\" Could not acquire required 'port': '8888'\\\". how to fix? dev mode should detect when dev server hasn't been initiated, prompt to initiate, then allow retry.\"}" 2972 - }, 2973 - { 2974 - "id": 271, 2975 - "change_id": "74b3bc73-4ff1-4a27-a347-69673f93cbb0", 2976 - "node_type": "action", 2977 - "title": "Killing existing process on port 8888 (PID 20728)", 2978 - "description": null, 2979 - "status": "completed", 2980 - "created_at": "2025-12-25T21:35:33.154605400-05:00", 2981 - "updated_at": "2025-12-25T21:43:03.916212100-05:00", 2982 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 2983 - }, 2984 - { 2985 - "id": 272, 2986 - "change_id": "67ad4d3b-3b47-4b18-b7f3-e75695ba295d", 2987 - "node_type": "observation", 2988 - "title": "Port 8888 was held by orphaned node.exe process (PID 20728) - previous dev server didn't shut down cleanly", 2989 - "description": null, 2990 - "status": "completed", 2991 - "created_at": "2025-12-25T21:37:21.438328400-05:00", 2992 - "updated_at": "2025-12-25T21:43:04.056912900-05:00", 2993 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 2994 - }, 2995 - { 2996 - "id": 273, 2997 - "change_id": "78b22c65-3381-4ea1-b48d-1d7784a7ca0f", 2998 - "node_type": "action", 2999 - "title": "Adding dev server health check and retry UI to extension popup", 3000 - "description": null, 3001 - "status": "completed", 3002 - "created_at": "2025-12-25T21:37:55.537373500-05:00", 3003 - "updated_at": "2025-12-25T21:43:04.188262300-05:00", 3004 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3005 - }, 3006 - { 3007 - "id": 274, 3008 - "change_id": "daa6b960-c5d9-44bf-ad62-edb27fedf593", 3009 - "node_type": "outcome", 3010 - "title": "Fixed port conflict and added dev server health check with retry UI to extension", 3011 - "description": null, 3012 - "status": "completed", 3013 - "created_at": "2025-12-25T21:42:36.650415200-05:00", 3014 - "updated_at": "2025-12-25T21:43:04.320629200-05:00", 3015 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3016 - }, 3017 - { 3018 - "id": 275, 3019 - "change_id": "dcc9f401-1a68-479e-97de-7a04e5597e00", 3020 - "node_type": "observation", 3021 - "title": "Extension health check blocked by CORS - need host_permissions for 127.0.0.1:8888", 3022 - "description": null, 3023 - "status": "completed", 3024 - "created_at": "2025-12-25T21:56:33.707675400-05:00", 3025 - "updated_at": "2025-12-25T21:59:40.704989700-05:00", 3026 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 3027 - }, 3028 - { 3029 - "id": 276, 3030 - "change_id": "b587d77b-624e-4d37-9e56-9c58b6229860", 3031 - "node_type": "action", 3032 - "title": "Adding dev and prod server URLs to extension host_permissions", 3033 - "description": null, 3034 - "status": "completed", 3035 - "created_at": "2025-12-25T21:56:49.799305500-05:00", 3036 - "updated_at": "2025-12-25T21:59:40.885927600-05:00", 3037 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3038 - }, 3039 - { 3040 - "id": 277, 3041 - "change_id": "edd49d41-7b40-4e2a-b168-816faccf223c", 3042 - "node_type": "outcome", 3043 - "title": "Fixed CORS by adding ATlast server URLs to extension host_permissions", 3044 - "description": null, 3045 - "status": "completed", 3046 - "created_at": "2025-12-25T21:59:27.214048800-05:00", 3047 - "updated_at": "2025-12-25T21:59:41.037717800-05:00", 3048 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3049 - }, 3050 - { 3051 - "id": 278, 3052 - "change_id": "fa11e7d7-ac30-4d0e-bc8a-d2332f724d92", 3053 - "node_type": "goal", 3054 - "title": "Store extension imports in database and integrate with existing upload flow", 3055 - "description": null, 3056 - "status": "completed", 3057 - "created_at": "2025-12-25T22:05:53.102585900-05:00", 3058 - "updated_at": "2025-12-25T22:20:26.309175100-05:00", 3059 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"prompt\":\"Import Error: Import not found or expired. Please try scanning again. - received after \\\"Open in ATlast\\\". We should be storing this in the existing DB schema with a \\\"save to ATlast\\\" button that also navigates to the results for that upload in atlast.\"}" 3060 - }, 3061 - { 3062 - "id": 279, 3063 - "change_id": "0710252d-bcf6-4708-b67f-d9615a0dad6e", 3064 - "node_type": "observation", 3065 - "title": "In-memory store doesn't work in serverless - each Netlify function can run in different process. Need database storage.", 3066 - "description": null, 3067 - "status": "completed", 3068 - "created_at": "2025-12-25T22:06:43.366406500-05:00", 3069 - "updated_at": "2025-12-25T22:20:26.419201900-05:00", 3070 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 3071 - }, 3072 - { 3073 - "id": 280, 3074 - "change_id": "f38929d4-0ad0-43ec-a25c-a9dd6f9ee7fd", 3075 - "node_type": "action", 3076 - "title": "Create extension_imports table and update endpoints to use database", 3077 - "description": null, 3078 - "status": "completed", 3079 - "created_at": "2025-12-25T22:06:46.169277300-05:00", 3080 - "updated_at": "2025-12-25T22:20:26.516060800-05:00", 3081 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3082 - }, 3083 - { 3084 - "id": 281, 3085 - "change_id": "0e917ade-9f83-4246-9a66-1aa2dfef7c41", 3086 - "node_type": "outcome", 3087 - "title": "Replaced in-memory storage with database persistence for extension imports", 3088 - "description": null, 3089 - "status": "completed", 3090 - "created_at": "2025-12-25T22:20:19.197297700-05:00", 3091 - "updated_at": "2025-12-25T22:20:26.608871700-05:00", 3092 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3093 - }, 3094 - { 3095 - "id": 282, 3096 - "change_id": "206347b5-4178-43dd-bb05-657b3788a6b0", 3097 - "node_type": "action", 3098 - "title": "Refactoring to proper flow: check session, save immediately, match real upload behavior", 3099 - "description": null, 3100 - "status": "completed", 3101 - "created_at": "2025-12-26T00:00:13.136356300-05:00", 3102 - "updated_at": "2025-12-26T00:19:11.083067300-05:00", 3103 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3104 - }, 3105 - { 3106 - "id": 283, 3107 - "change_id": "e3adddaf-9126-4bfa-8d75-aa8b94323077", 3108 - "node_type": "observation", 3109 - "title": "Extension-import now requires auth, creates upload immediately, saves to source_accounts - matches file upload flow", 3110 - "description": null, 3111 - "status": "completed", 3112 - "created_at": "2025-12-26T00:13:01.938755900-05:00", 3113 - "updated_at": "2025-12-26T00:19:11.191827900-05:00", 3114 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3115 - }, 3116 - { 3117 - "id": 284, 3118 - "change_id": "3d9caa98-6f9c-4613-9c05-92566f9ee0d5", 3119 - "node_type": "outcome", 3120 - "title": "Refactored extension flow: requires login first, creates upload immediately, matches file upload behavior", 3121 - "description": null, 3122 - "status": "completed", 3123 - "created_at": "2025-12-26T00:18:53.900318900-05:00", 3124 - "updated_at": "2025-12-26T00:19:11.322802200-05:00", 3125 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3126 - }, 3127 - { 3128 - "id": 285, 3129 - "change_id": "f0da412f-562b-4e45-b83d-eba28fc22eea", 3130 - "node_type": "outcome", 3131 - "title": "Extension built successfully for dev environment", 3132 - "description": null, 3133 - "status": "completed", 3134 - "created_at": "2025-12-26T00:24:02.307648100-05:00", 3135 - "updated_at": "2025-12-26T13:22:38.789519700-05:00", 3136 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95,\"files\":[\"packages/extension/build.js\",\"packages/extension/dist/\"]}" 3137 - }, 3138 - { 3139 - "id": 286, 3140 - "change_id": "60c9ec75-7e3f-4aa4-b8cf-0691ef92d260", 3141 - "node_type": "outcome", 3142 - "title": "Committed extension refactor with decision graph", 3143 - "description": null, 3144 - "status": "completed", 3145 - "created_at": "2025-12-26T00:26:17.378515100-05:00", 3146 - "updated_at": "2025-12-26T13:22:40.829054100-05:00", 3147 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"d0bcf33\",\"confidence\":100}" 3148 - }, 3149 - { 3150 - "id": 287, 3151 - "change_id": "e01c6989-6c0b-42f8-b7c7-60aca059f7c3", 3152 - "node_type": "action", 3153 - "title": "Fixed NaN database error in extension-import", 3154 - "description": null, 3155 - "status": "completed", 3156 - "created_at": "2025-12-26T00:33:28.860934100-05:00", 3157 - "updated_at": "2025-12-26T13:22:42.926736300-05:00", 3158 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"1a355fe\",\"confidence\":95,\"files\":[\"packages/functions/src/extension-import.ts\"]}" 3159 - }, 3160 - { 3161 - "id": 288, 3162 - "change_id": "5fa82fdc-7796-4263-be72-e1877279881b", 3163 - "node_type": "outcome", 3164 - "title": "Database initialized successfully for dev environment", 3165 - "description": null, 3166 - "status": "completed", 3167 - "created_at": "2025-12-26T00:47:09.629444300-05:00", 3168 - "updated_at": "2025-12-26T13:22:45.174366200-05:00", 3169 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100,\"files\":[\"packages/functions/src/init-db.ts\"]}" 3170 - }, 3171 - { 3172 - "id": 289, 3173 - "change_id": "dd2aa029-7ca9-4379-a966-762c9137bcc8", 3174 - "node_type": "action", 3175 - "title": "Updated PLAN.md and EXTENSION_STATUS.md with current debugging status", 3176 - "description": null, 3177 - "status": "completed", 3178 - "created_at": "2025-12-26T00:50:51.291667400-05:00", 3179 - "updated_at": "2025-12-26T13:22:47.378106200-05:00", 3180 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"34bd9dc\",\"confidence\":100,\"files\":[\"PLAN.md\",\"EXTENSION_STATUS.md\"]}" 3181 - }, 3182 - { 3183 - "id": 290, 3184 - "change_id": "d73fc969-78c0-4721-8db5-88014cb4a0a6", 3185 - "node_type": "goal", 3186 - "title": "Fix extension upload errors - undefined response and invalid URL", 3187 - "description": null, 3188 - "status": "completed", 3189 - "created_at": "2025-12-26T13:31:45.695565800-05:00", 3190 - "updated_at": "2025-12-27T17:49:55.246500-05:00", 3191 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 3192 - }, 3193 - { 3194 - "id": 291, 3195 - "change_id": "1d88fcb9-3f0e-400b-aabd-7b1564064fd9", 3196 - "node_type": "observation", 3197 - "title": "Backend returns correct structure but response might be wrapped by successResponse helper", 3198 - "description": null, 3199 - "status": "completed", 3200 - "created_at": "2025-12-26T13:32:20.697112800-05:00", 3201 - "updated_at": "2025-12-27T17:49:55.310376600-05:00", 3202 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3203 - }, 3204 - { 3205 - "id": 292, 3206 - "change_id": "22c007f9-6e84-4a72-bc6f-462b94655b40", 3207 - "node_type": "observation", 3208 - "title": "successResponse wraps data in {success: true, data: {...}} structure - extension expects flat response", 3209 - "description": null, 3210 - "status": "completed", 3211 - "created_at": "2025-12-26T13:32:50.409160400-05:00", 3212 - "updated_at": "2025-12-27T17:49:55.384830800-05:00", 3213 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3214 - }, 3215 - { 3216 - "id": 293, 3217 - "change_id": "59087762-06cf-4be1-8a15-fb2244070951", 3218 - "node_type": "action", 3219 - "title": "Fix api-client.ts to unwrap ApiResponse.data field", 3220 - "description": null, 3221 - "status": "completed", 3222 - "created_at": "2025-12-26T13:32:54.625124500-05:00", 3223 - "updated_at": "2025-12-27T17:49:55.449186500-05:00", 3224 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3225 - }, 3226 - { 3227 - "id": 294, 3228 - "change_id": "6a2f6150-4b32-45ee-b2c7-cd5094fdd8c6", 3229 - "node_type": "outcome", 3230 - "title": "Fixed API client to unwrap ApiResponse.data - both uploadToATlast and checkSession now correctly access nested data field", 3231 - "description": null, 3232 - "status": "completed", 3233 - "created_at": "2025-12-26T13:34:09.012837500-05:00", 3234 - "updated_at": "2025-12-27T17:49:55.512809400-05:00", 3235 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3236 - }, 3237 - { 3238 - "id": 295, 3239 - "change_id": "ceaed4fe-5fd0-4542-8f3a-bd4640dfaadf", 3240 - "node_type": "outcome", 3241 - "title": "Committed API response fix to git", 3242 - "description": null, 3243 - "status": "completed", 3244 - "created_at": "2025-12-26T13:36:02.733197600-05:00", 3245 - "updated_at": "2025-12-27T17:49:55.576426900-05:00", 3246 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"9563633\",\"confidence\":95}" 3247 - }, 3248 - { 3249 - "id": 296, 3250 - "change_id": "e2427bfe-84a1-4dee-adf4-28a9c1b739e2", 3251 - "node_type": "observation", 3252 - "title": "Extension upload flow fixed and ready for testing - API response unwrapping resolves undefined errors", 3253 - "description": null, 3254 - "status": "completed", 3255 - "created_at": "2025-12-26T13:37:35.844832-05:00", 3256 - "updated_at": "2025-12-27T17:49:55.653339900-05:00", 3257 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"9ca7347\",\"confidence\":95}" 3258 - }, 3259 - { 3260 - "id": 297, 3261 - "change_id": "74ea361f-577c-4058-b833-6666e777ee00", 3262 - "node_type": "goal", 3263 - "title": "Fix backend repository method error and missing frontend route", 3264 - "description": null, 3265 - "status": "completed", 3266 - "created_at": "2025-12-26T13:43:03.332690700-05:00", 3267 - "updated_at": "2025-12-27T17:49:55.729232100-05:00", 3268 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3269 - }, 3270 - { 3271 - "id": 298, 3272 - "change_id": "c373be70-157a-420d-bc11-4364fe22d091", 3273 - "node_type": "observation", 3274 - "title": "Two issues: 1) SourceAccountRepository has getOrCreate/bulkCreate not upsertSourceAccount, 2) Router only has / route, no /results route", 3275 - "description": null, 3276 - "status": "completed", 3277 - "created_at": "2025-12-26T13:43:28.902663600-05:00", 3278 - "updated_at": "2025-12-27T17:49:55.791246300-05:00", 3279 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3280 - }, 3281 - { 3282 - "id": 299, 3283 - "change_id": "8edd7e11-54b4-4c5b-8379-37b1ec1e7d7d", 3284 - "node_type": "action", 3285 - "title": "Fix backend to use bulkCreate and frontend to handle uploadId param", 3286 - "description": null, 3287 - "status": "completed", 3288 - "created_at": "2025-12-26T13:44:28.406069900-05:00", 3289 - "updated_at": "2025-12-27T17:49:55.863335500-05:00", 3290 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3291 - }, 3292 - { 3293 - "id": 300, 3294 - "change_id": "876412ec-a214-4bf7-b48a-b7706c698085", 3295 - "node_type": "outcome", 3296 - "title": "Fixed both issues: backend uses bulkCreate, redirects to /?uploadId, frontend loads results from uploadId param", 3297 - "description": null, 3298 - "status": "completed", 3299 - "created_at": "2025-12-26T13:45:58.309042200-05:00", 3300 - "updated_at": "2025-12-27T17:49:55.947393200-05:00", 3301 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3302 - }, 3303 - { 3304 - "id": 301, 3305 - "change_id": "b3f870cc-406f-4cf7-8ab4-04d9f76fb2ab", 3306 - "node_type": "outcome", 3307 - "title": "Committed fixes for bulkCreate and uploadId handling", 3308 - "description": null, 3309 - "status": "completed", 3310 - "created_at": "2025-12-26T13:47:48.770693200-05:00", 3311 - "updated_at": "2025-12-27T17:49:56.029469300-05:00", 3312 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"581ed00\",\"confidence\":95}" 3313 - }, 3314 - { 3315 - "id": 302, 3316 - "change_id": "e2cf6ed0-c80f-420a-bdd2-98369f58de2a", 3317 - "node_type": "observation", 3318 - "title": "Frontend error: loadUploadResults not defined - need to check function scope", 3319 - "description": null, 3320 - "status": "completed", 3321 - "created_at": "2025-12-26T13:50:59.977950500-05:00", 3322 - "updated_at": "2025-12-27T17:49:56.093781100-05:00", 3323 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3324 - }, 3325 - { 3326 - "id": 303, 3327 - "change_id": "7a7a19a6-4abf-4c30-9072-14beaa12b106", 3328 - "node_type": "action", 3329 - "title": "Fix useEffect to call handleLoadUpload instead of non-existent loadUploadResults", 3330 - "description": null, 3331 - "status": "completed", 3332 - "created_at": "2025-12-26T13:51:36.007564400-05:00", 3333 - "updated_at": "2025-12-27T17:49:56.169258900-05:00", 3334 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3335 - }, 3336 - { 3337 - "id": 304, 3338 - "change_id": "dff4aef7-8732-4aae-a6be-f44fb42b4941", 3339 - "node_type": "outcome", 3340 - "title": "Fixed function name - now calls handleLoadUpload correctly", 3341 - "description": null, 3342 - "status": "completed", 3343 - "created_at": "2025-12-26T13:51:52.256909300-05:00", 3344 - "updated_at": "2025-12-27T17:49:56.234188500-05:00", 3345 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3346 - }, 3347 - { 3348 - "id": 305, 3349 - "change_id": "8ad6ef53-29a2-442e-b88f-9e0541634950", 3350 - "node_type": "goal", 3351 - "title": "Fix extension flow: auto-search after load, history navigation, time formatting", 3352 - "description": null, 3353 - "status": "completed", 3354 - "created_at": "2025-12-26T14:05:53.798547500-05:00", 3355 - "updated_at": "2025-12-27T17:49:56.309329800-05:00", 3356 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3357 - }, 3358 - { 3359 - "id": 306, 3360 - "change_id": "481942f8-5905-4948-a1cb-ee320a98271b", 3361 - "node_type": "observation", 3362 - "title": "handleLoadUpload expects existing results but extension creates empty upload - need to load source accounts and trigger search", 3363 - "description": null, 3364 - "status": "completed", 3365 - "created_at": "2025-12-26T14:06:18.067673100-05:00", 3366 - "updated_at": "2025-12-27T17:49:56.384145700-05:00", 3367 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3368 - }, 3369 - { 3370 - "id": 307, 3371 - "change_id": "ae01acc1-f5ff-481b-823f-de2d4f1843a2", 3372 - "node_type": "observation", 3373 - "title": "Extension-import creates upload and source_accounts but NOT user_source_follows - get-upload-details returns empty because it queries FROM user_source_follows", 3374 - "description": null, 3375 - "status": "completed", 3376 - "created_at": "2025-12-26T14:08:57.918421600-05:00", 3377 - "updated_at": "2025-12-27T17:49:56.459539400-05:00", 3378 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 3379 - }, 3380 - { 3381 - "id": 308, 3382 - "change_id": "2368cae0-9ae1-4ca0-9ace-8c3555f9e679", 3383 - "node_type": "action", 3384 - "title": "Add user_source_follows creation to extension-import endpoint", 3385 - "description": null, 3386 - "status": "completed", 3387 - "created_at": "2025-12-26T14:09:03.035871-05:00", 3388 - "updated_at": "2025-12-27T17:49:56.523841100-05:00", 3389 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3390 - }, 3391 - { 3392 - "id": 309, 3393 - "change_id": "cd9b88e7-fe8d-4ee0-a187-e99eef0b7e64", 3394 - "node_type": "outcome", 3395 - "title": "Fixed all extension flow issues: added user_source_follows creation, auto-search after load, time formatting", 3396 - "description": null, 3397 - "status": "completed", 3398 - "created_at": "2025-12-26T14:11:09.055850200-05:00", 3399 - "updated_at": "2025-12-27T17:49:56.588486100-05:00", 3400 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3401 - }, 3402 - { 3403 - "id": 310, 3404 - "change_id": "51369a2c-17ec-4be3-ba4f-240b770d7211", 3405 - "node_type": "outcome", 3406 - "title": "Committed all extension flow fixes", 3407 - "description": null, 3408 - "status": "completed", 3409 - "created_at": "2025-12-26T14:16:08.387214900-05:00", 3410 - "updated_at": "2025-12-27T17:49:56.670180800-05:00", 3411 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"6ced3f0\",\"confidence\":95}" 3412 - }, 3413 - { 3414 - "id": 311, 3415 - "change_id": "91d7bad2-a8a3-47c3-8fad-558919b207b0", 3416 - "node_type": "observation", 3417 - "title": "searchAllUsers called with wrong parameters - missing onProgressUpdate callback", 3418 - "description": null, 3419 - "status": "completed", 3420 - "created_at": "2025-12-26T16:07:21.838974100-05:00", 3421 - "updated_at": "2025-12-27T17:49:56.746464900-05:00", 3422 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3423 - }, 3424 - { 3425 - "id": 312, 3426 - "change_id": "9a95c7e6-6339-475f-9b20-5fa3057e0a9f", 3427 - "node_type": "action", 3428 - "title": "Fix searchAllUsers call with correct parameters and callbacks", 3429 - "description": null, 3430 - "status": "completed", 3431 - "created_at": "2025-12-26T16:08:18.523845400-05:00", 3432 - "updated_at": "2025-12-27T17:49:56.809583600-05:00", 3433 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3434 - }, 3435 - { 3436 - "id": 313, 3437 - "change_id": "5fae9da8-2a31-4f99-9686-7bfb28c443e8", 3438 - "node_type": "outcome", 3439 - "title": "Fixed searchAllUsers call - now passes onProgressUpdate and onComplete callbacks", 3440 - "description": null, 3441 - "status": "completed", 3442 - "created_at": "2025-12-26T16:08:24.248208800-05:00", 3443 - "updated_at": "2025-12-27T17:49:56.884711900-05:00", 3444 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3445 - }, 3446 - { 3447 - "id": 314, 3448 - "change_id": "6837403f-1e30-4a71-bcf5-71db0cac6afc", 3449 - "node_type": "goal", 3450 - "title": "Fix validation error and undefined localeCompare in extension flow", 3451 - "description": null, 3452 - "status": "completed", 3453 - "created_at": "2025-12-26T20:17:59.516959100-05:00", 3454 - "updated_at": "2025-12-27T17:49:56.971434500-05:00", 3455 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3456 - }, 3457 - { 3458 - "id": 315, 3459 - "change_id": "a08d22fc-5970-4a5d-8454-4a1ef2efc7e4", 3460 - "node_type": "observation", 3461 - "title": "Two errors: 1) batch-search-actors gets null in usernames array, 2) Frontend localeCompare on undefined - likely wrong SearchResult structure", 3462 - "description": null, 3463 - "status": "completed", 3464 - "created_at": "2025-12-26T20:18:03.693879700-05:00", 3465 - "updated_at": "2025-12-27T17:49:57.049131800-05:00", 3466 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3467 - }, 3468 - { 3469 - "id": 316, 3470 - "change_id": "58ef0c82-402c-4fff-8421-83c5417475b1", 3471 - "node_type": "action", 3472 - "title": "Fix SearchResult structure - sourceUser should be object not string", 3473 - "description": null, 3474 - "status": "completed", 3475 - "created_at": "2025-12-26T20:19:47.621459800-05:00", 3476 - "updated_at": "2025-12-27T17:49:57.127563700-05:00", 3477 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3478 - }, 3479 - { 3480 - "id": 317, 3481 - "change_id": "3a24a4a2-b4d0-4629-a29b-b33994d50e75", 3482 - "node_type": "outcome", 3483 - "title": "Fixed SearchResult structure - sourceUser is now correct SourceUser object instead of string", 3484 - "description": null, 3485 - "status": "completed", 3486 - "created_at": "2025-12-26T20:20:22.507291300-05:00", 3487 - "updated_at": "2025-12-27T17:49:57.190209200-05:00", 3488 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3489 - }, 3490 - { 3491 - "id": 318, 3492 - "change_id": "371f788d-46df-4651-b338-f9310f8ae810", 3493 - "node_type": "goal", 3494 - "title": "Fix results not saving to database and timestamp timezone issue", 3495 - "description": null, 3496 - "status": "completed", 3497 - "created_at": "2025-12-26T20:37:03.493239600-05:00", 3498 - "updated_at": "2025-12-27T17:49:57.263765-05:00", 3499 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3500 - }, 3501 - { 3502 - "id": 319, 3503 - "change_id": "28681ed9-6d12-476e-a60d-291ee2034952", 3504 - "node_type": "observation", 3505 - "title": "save-results has hasRecentUpload check that skips saving if upload created within 5 seconds - extension-import creates upload then save-results is called immediately, gets skipped!", 3506 - "description": null, 3507 - "status": "completed", 3508 - "created_at": "2025-12-26T20:37:34.735156200-05:00", 3509 - "updated_at": "2025-12-27T15:37:51.134056500-05:00", 3510 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 3511 - }, 3512 - { 3513 - "id": 320, 3514 - "change_id": "04f6a182-c5a1-4844-b186-24605a8e74a9", 3515 - "node_type": "action", 3516 - "title": "Fix save-results to skip duplicate check for extension uploads and handle timestamps correctly", 3517 - "description": null, 3518 - "status": "completed", 3519 - "created_at": "2025-12-26T20:38:45.703038700-05:00", 3520 - "updated_at": "2025-12-27T15:37:51.269445900-05:00", 3521 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3522 - }, 3523 - { 3524 - "id": 321, 3525 - "change_id": "ac843fbc-1953-4b61-8ef3-4c88c98572f5", 3526 - "node_type": "outcome", 3527 - "title": "Fixed save-results to check if upload exists by ID instead of recent time check - extension flow now saves matches", 3528 - "description": null, 3529 - "status": "completed", 3530 - "created_at": "2025-12-26T20:39:45.657720100-05:00", 3531 - "updated_at": "2025-12-27T15:37:51.395550200-05:00", 3532 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3533 - }, 3534 - { 3535 - "id": 322, 3536 - "change_id": "2e824556-15c7-4656-b771-1b85cc628edc", 3537 - "node_type": "observation", 3538 - "title": "onComplete callback in handleLoadUpload accesses stale searchResults from closure - state updated by searchAllUsers not visible to callback", 3539 - "description": null, 3540 - "status": "completed", 3541 - "created_at": "2025-12-26T20:51:55.431293100-05:00", 3542 - "updated_at": "2025-12-27T15:37:51.544390300-05:00", 3543 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3544 - }, 3545 - { 3546 - "id": 323, 3547 - "change_id": "88fc65bc-c2da-4df7-b79e-ba80d93e5b77", 3548 - "node_type": "outcome", 3549 - "title": "Fixed stale closure issue - onComplete now receives finalResults from useSearch state", 3550 - "description": null, 3551 - "status": "completed", 3552 - "created_at": "2025-12-26T20:55:36.922743800-05:00", 3553 - "updated_at": "2025-12-27T15:37:51.688947900-05:00", 3554 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3555 - }, 3556 - { 3557 - "id": 324, 3558 - "change_id": "c941c916-0fcb-44d6-9786-dfd53447cebe", 3559 - "node_type": "outcome", 3560 - "title": "Committed stale closure fix - results now save immediately after search completes", 3561 - "description": null, 3562 - "status": "completed", 3563 - "created_at": "2025-12-26T20:58:48.266958800-05:00", 3564 - "updated_at": "2025-12-27T15:37:51.824656100-05:00", 3565 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"212660a\",\"confidence\":95}" 3566 - }, 3567 - { 3568 - "id": 325, 3569 - "change_id": "e44f45f8-bac9-4a49-ac68-ac9d7d113226", 3570 - "node_type": "outcome", 3571 - "title": "Loading screen now shows during extension upload search", 3572 - "description": null, 3573 - "status": "completed", 3574 - "created_at": "2025-12-26T21:20:42.635515100-05:00", 3575 - "updated_at": "2025-12-27T15:37:51.996612500-05:00", 3576 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"46626f4\",\"confidence\":95}" 3577 - }, 3578 - { 3579 - "id": 326, 3580 - "change_id": "af76ea64-b0b1-4577-b521-4ec21cc555e1", 3581 - "node_type": "outcome", 3582 - "title": "Fixed timezone issue - all timestamp columns now use TIMESTAMPTZ", 3583 - "description": null, 3584 - "status": "completed", 3585 - "created_at": "2025-12-26T21:46:14.340967100-05:00", 3586 - "updated_at": "2025-12-27T15:37:52.151895800-05:00", 3587 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"aacbbaa\",\"confidence\":95}" 3588 - }, 3589 - { 3590 - "id": 327, 3591 - "change_id": "ed9ceca3-e53e-430c-8f0f-386b287b0915", 3592 - "node_type": "outcome", 3593 - "title": "Optimized Vite config with explicit dependency pre-bundling", 3594 - "description": null, 3595 - "status": "completed", 3596 - "created_at": "2025-12-26T21:57:16.155112400-05:00", 3597 - "updated_at": "2025-12-27T15:37:52.289922500-05:00", 3598 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"e04934f\",\"confidence\":85}" 3599 - }, 3600 - { 3601 - "id": 328, 3602 - "change_id": "7823be1a-fca9-4cb5-9e62-dfbc8cb71e55", 3603 - "node_type": "outcome", 3604 - "title": "Fixed decision graph integrity - linked 18 orphan nodes to parent goals, marked nodes 319-327 as completed", 3605 - "description": null, 3606 - "status": "completed", 3607 - "created_at": "2025-12-27T15:38:21.291457500-05:00", 3608 - "updated_at": "2025-12-27T17:49:54.129059900-05:00", 3609 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 3610 - }, 3611 - { 3612 - "id": 329, 3613 - "change_id": "c839ec54-b098-4030-8ff4-857549b17363", 3614 - "node_type": "observation", 3615 - "title": "Decision graph audit revealed systematic issues: 18 orphan nodes, incorrect status (pending vs completed), wrong orphan detection commands in recovery workflow", 3616 - "description": null, 3617 - "status": "completed", 3618 - "created_at": "2025-12-27T15:40:23.238704300-05:00", 3619 - "updated_at": "2025-12-27T17:49:57.327650700-05:00", 3620 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3621 - }, 3622 - { 3623 - "id": 330, 3624 - "change_id": "1f554b87-3775-450b-a3a1-b23eeebc7e38", 3625 - "node_type": "action", 3626 - "title": "Analyzing decision graph issues and updating CLAUDE.md with improved workflow", 3627 - "description": null, 3628 - "status": "completed", 3629 - "created_at": "2025-12-27T15:41:04.067444-05:00", 3630 - "updated_at": "2025-12-27T17:49:57.403361400-05:00", 3631 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3632 - }, 3633 - { 3634 - "id": 331, 3635 - "change_id": "8c746dd6-d571-4446-8a53-af6279fc9c21", 3636 - "node_type": "outcome", 3637 - "title": "Updated CLAUDE.md and .claude/ files with node lifecycle management, correct orphan detection commands, and common mistakes section", 3638 - "description": null, 3639 - "status": "completed", 3640 - "created_at": "2025-12-27T15:47:49.308750700-05:00", 3641 - "updated_at": "2025-12-27T17:49:57.478252800-05:00", 3642 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 3643 - }, 3644 - { 3645 - "id": 332, 3646 - "change_id": "c4338df4-a22f-4dd5-b60c-84c7cd1c0c5c", 3647 - "node_type": "action", 3648 - "title": "Committed documentation improvements", 3649 - "description": null, 3650 - "status": "completed", 3651 - "created_at": "2025-12-27T15:48:47.658343800-05:00", 3652 - "updated_at": "2025-12-27T17:49:57.553143200-05:00", 3653 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"fcf682b\",\"confidence\":100}" 3654 - }, 3655 - { 3656 - "id": 333, 3657 - "change_id": "0a0375e9-bcef-4459-b9f1-f5868276e8e4", 3658 - "node_type": "goal", 3659 - "title": "Review and update all .md files to reflect current project status", 3660 - "description": null, 3661 - "status": "completed", 3662 - "created_at": "2025-12-27T15:50:48.815758500-05:00", 3663 - "updated_at": "2025-12-27T17:49:57.630386-05:00", 3664 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"prompt\":\"review and update the .md files thru the project based on current project status.\"}" 3665 - }, 3666 - { 3667 - "id": 334, 3668 - "change_id": "fe108b87-356f-4c02-85cb-7260e175d8ad", 3669 - "node_type": "action", 3670 - "title": "Identifying all project .md files excluding dependencies", 3671 - "description": null, 3672 - "status": "completed", 3673 - "created_at": "2025-12-27T15:51:22.583189100-05:00", 3674 - "updated_at": "2025-12-27T17:49:57.707946400-05:00", 3675 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3676 - }, 3677 - { 3678 - "id": 335, 3679 - "change_id": "3aac85f7-c11c-48f6-b9da-2cd333605fb2", 3680 - "node_type": "observation", 3681 - "title": "Analyzed all project .md files - found outdated information in CONTRIBUTING.md (npm→pnpm), EXTENSION_STATUS.md (debugging→completed), PLAN.md (optimization status), extension README (build commands)", 3682 - "description": null, 3683 - "status": "completed", 3684 - "created_at": "2025-12-27T15:52:06.741629200-05:00", 3685 - "updated_at": "2025-12-27T17:49:57.786343300-05:00", 3686 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3687 - }, 3688 - { 3689 - "id": 336, 3690 - "change_id": "d1a23826-c660-4f2a-bdc0-bcbbce9d0293", 3691 - "node_type": "decision", 3692 - "title": "Choose which .md files to update based on priority and impact", 3693 - "description": null, 3694 - "status": "completed", 3695 - "created_at": "2025-12-27T15:52:30.322805700-05:00", 3696 - "updated_at": "2025-12-27T17:49:57.849977800-05:00", 3697 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 3698 - }, 3699 - { 3700 - "id": 337, 3701 - "change_id": "28eeefda-3813-4777-8006-924a9b030c61", 3702 - "node_type": "outcome", 3703 - "title": "User chose Option B: Complete update of EXTENSION_STATUS.md, CONTRIBUTING.md, PLAN.md, extension README", 3704 - "description": null, 3705 - "status": "completed", 3706 - "created_at": "2025-12-27T15:54:31.514053500-05:00", 3707 - "updated_at": "2025-12-27T15:59:48.206341500-05:00", 3708 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 3709 - }, 3710 - { 3711 - "id": 338, 3712 - "change_id": "594942d8-4981-4557-9687-522d51e86ecb", 3713 - "node_type": "action", 3714 - "title": "Updating EXTENSION_STATUS.md with current completion status and recent fixes", 3715 - "description": null, 3716 - "status": "completed", 3717 - "created_at": "2025-12-27T15:54:35.960795700-05:00", 3718 - "updated_at": "2025-12-27T15:55:47.472404200-05:00", 3719 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3720 - }, 3721 - { 3722 - "id": 339, 3723 - "change_id": "4c8c5b0d-468b-4ad6-80e9-02141949aba9", 3724 - "node_type": "action", 3725 - "title": "Updating CONTRIBUTING.md to use pnpm and reflect monorepo structure", 3726 - "description": null, 3727 - "status": "completed", 3728 - "created_at": "2025-12-27T15:55:49.596595900-05:00", 3729 - "updated_at": "2025-12-27T15:57:12.280431-05:00", 3730 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3731 - }, 3732 - { 3733 - "id": 340, 3734 - "change_id": "4e3987a4-538f-4912-b6ce-39c5971e0966", 3735 - "node_type": "action", 3736 - "title": "Reviewing and updating PLAN.md optimization status", 3737 - "description": null, 3738 - "status": "completed", 3739 - "created_at": "2025-12-27T15:57:14.603410600-05:00", 3740 - "updated_at": "2025-12-27T15:58:21.116083200-05:00", 3741 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3742 - }, 3743 - { 3744 - "id": 341, 3745 - "change_id": "42bf8d79-2c24-420f-b8b8-89273fecc30d", 3746 - "node_type": "action", 3747 - "title": "Updating packages/extension/README.md with pnpm commands and current context", 3748 - "description": null, 3749 - "status": "completed", 3750 - "created_at": "2025-12-27T15:58:23.453147600-05:00", 3751 - "updated_at": "2025-12-27T15:59:39.189409100-05:00", 3752 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3753 - }, 3754 - { 3755 - "id": 342, 3756 - "change_id": "a6d1f3fb-650d-4227-b1dc-ddb24810464c", 3757 - "node_type": "outcome", 3758 - "title": "Successfully updated all 4 markdown files with current project status, pnpm commands, monorepo structure, and completion status", 3759 - "description": null, 3760 - "status": "completed", 3761 - "created_at": "2025-12-27T15:59:41.457774700-05:00", 3762 - "updated_at": "2025-12-27T15:59:45.883622500-05:00", 3763 - "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 3764 - }, 3765 - { 3766 - "id": 343, 3767 - "change_id": "9e0fcead-ea30-4b31-974b-4e07f7fc6787", 3768 - "node_type": "action", 3769 - "title": "Committed all markdown documentation updates", 3770 - "description": null, 3771 - "status": "completed", 3772 - "created_at": "2025-12-27T16:02:13.397776700-05:00", 3773 - "updated_at": "2025-12-27T16:02:56.131931100-05:00", 3774 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"fe29bb3\",\"confidence\":100}" 3775 - }, 3776 - { 3777 - "id": 344, 3778 - "change_id": "2a06900e-ea62-4adf-81d5-7f0cf1a29b31", 3779 - "node_type": "goal", 3780 - "title": "Add Tailwind CSS to extension for design consistency", 3781 - "description": null, 3782 - "status": "completed", 3783 - "created_at": "2025-12-27T17:59:23.523767600-05:00", 3784 - "updated_at": "2025-12-27T18:07:53.271415-05:00", 3785 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"prompt\":\"yes\"}" 3786 - }, 3787 - { 3788 - "id": 345, 3789 - "change_id": "0ef352ed-538b-4632-8b62-ebb17603f944", 3790 - "node_type": "action", 3791 - "title": "Installing Tailwind CSS and PostCSS dependencies", 3792 - "description": null, 3793 - "status": "completed", 3794 - "created_at": "2025-12-27T18:00:41.652670100-05:00", 3795 - "updated_at": "2025-12-27T18:00:43.901523100-05:00", 3796 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3797 - }, 3798 - { 3799 - "id": 346, 3800 - "change_id": "888e6ad0-5002-4cdb-b35e-f4214ca07dfa", 3801 - "node_type": "action", 3802 - "title": "Creating Tailwind and PostCSS config files", 3803 - "description": null, 3804 - "status": "completed", 3805 - "created_at": "2025-12-27T18:01:27.404433500-05:00", 3806 - "updated_at": "2025-12-27T18:01:29.980132200-05:00", 3807 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3808 - }, 3809 - { 3810 - "id": 347, 3811 - "change_id": "fae7a634-d921-4b6f-9620-0c58d88b863e", 3812 - "node_type": "action", 3813 - "title": "Updating build.js to process CSS with PostCSS + Tailwind", 3814 - "description": null, 3815 - "status": "completed", 3816 - "created_at": "2025-12-27T18:01:50.537140900-05:00", 3817 - "updated_at": "2025-12-27T18:01:53.031316700-05:00", 3818 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3819 - }, 3820 - { 3821 - "id": 348, 3822 - "change_id": "c25a8f4b-8bf1-4a33-bef9-3731dfd83627", 3823 - "node_type": "action", 3824 - "title": "Converting popup.css to use Tailwind directives", 3825 - "description": null, 3826 - "status": "completed", 3827 - "created_at": "2025-12-27T18:02:42.167814700-05:00", 3828 - "updated_at": "2025-12-27T18:02:44.488653900-05:00", 3829 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3830 - }, 3831 - { 3832 - "id": 349, 3833 - "change_id": "c65ee3d9-62a0-47aa-870a-f6422ff2536a", 3834 - "node_type": "action", 3835 - "title": "Converting popup.html to use Tailwind utility classes", 3836 - "description": null, 3837 - "status": "completed", 3838 - "created_at": "2025-12-27T18:03:00.465637900-05:00", 3839 - "updated_at": "2025-12-27T18:03:02.815261100-05:00", 3840 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3841 - }, 3842 - { 3843 - "id": 350, 3844 - "change_id": "8136e615-5baa-4fe5-9a7d-d672ff1a6f85", 3845 - "node_type": "outcome", 3846 - "title": "Successfully integrated Tailwind CSS into extension", 3847 - "description": null, 3848 - "status": "completed", 3849 - "created_at": "2025-12-27T18:07:49.869572400-05:00", 3850 - "updated_at": "2025-12-27T18:07:52.136827400-05:00", 3851 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3852 - }, 3853 - { 3854 - "id": 351, 3855 - "change_id": "9468bcb3-78ec-4dae-8d8f-968ba6f5b3fe", 3856 - "node_type": "outcome", 3857 - "title": "Committed Tailwind CSS integration to git", 3858 - "description": null, 3859 - "status": "completed", 3860 - "created_at": "2025-12-27T18:38:55.689869700-05:00", 3861 - "updated_at": "2025-12-27T18:39:01.013284600-05:00", 3862 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"d07180c\",\"confidence\":95}" 3863 - }, 3864 - { 3865 - "id": 352, 3866 - "change_id": "b852ce18-1747-4c26-a65e-acfbbed2b1a5", 3867 - "node_type": "goal", 3868 - "title": "Fix extension dark mode and dev/prod detection issues", 3869 - "description": null, 3870 - "status": "completed", 3871 - "created_at": "2025-12-27T22:05:50.675487800-05:00", 3872 - "updated_at": "2025-12-27T22:09:32.111749500-05:00", 3873 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"prompt\":\"there now seems to be an issue with dark mode not activating, and either an issue with detecting dev vs prod or the copy is just wrong. analyze and fix.\"}" 3874 - }, 3875 - { 3876 - "id": 353, 3877 - "change_id": "eaed6e9b-9f16-4b45-8783-44ea2ea1f2a9", 3878 - "node_type": "observation", 3879 - "title": "Found two issues: 1) darkMode: 'class' requires manual .dark class addition, 2) Dev/prod detection may be incorrect", 3880 - "description": null, 3881 - "status": "completed", 3882 - "created_at": "2025-12-27T22:06:19.509001-05:00", 3883 - "updated_at": "2025-12-27T22:06:23.515277300-05:00", 3884 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3885 - }, 3886 - { 3887 - "id": 354, 3888 - "change_id": "d66fc83e-9737-4047-8ce2-e2ba857aeea9", 3889 - "node_type": "decision", 3890 - "title": "Choose dark mode strategy: media queries vs class-based with JS", 3891 - "description": null, 3892 - "status": "completed", 3893 - "created_at": "2025-12-27T22:07:01.587088200-05:00", 3894 - "updated_at": "2025-12-27T22:07:07.798171700-05:00", 3895 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 3896 - }, 3897 - { 3898 - "id": 355, 3899 - "change_id": "76e2a379-7803-4c82-8013-be6b62f2d360", 3900 - "node_type": "outcome", 3901 - "title": "Chose media queries - simpler and matches original behavior", 3902 - "description": null, 3903 - "status": "completed", 3904 - "created_at": "2025-12-27T22:07:04.660558100-05:00", 3905 - "updated_at": "2025-12-27T22:07:07.897193100-05:00", 3906 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3907 - }, 3908 - { 3909 - "id": 356, 3910 - "change_id": "df681aa8-e470-4ead-a0d2-a4095febfa3d", 3911 - "node_type": "action", 3912 - "title": "Fixing dark mode config to use media queries", 3913 - "description": null, 3914 - "status": "completed", 3915 - "created_at": "2025-12-27T22:07:24.774976300-05:00", 3916 - "updated_at": "2025-12-27T22:07:30.392290200-05:00", 3917 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3918 - }, 3919 - { 3920 - "id": 357, 3921 - "change_id": "57060303-5a30-4f11-a752-a02376df5ea7", 3922 - "node_type": "action", 3923 - "title": "Making server offline message conditional on build mode", 3924 - "description": null, 3925 - "status": "completed", 3926 - "created_at": "2025-12-27T22:07:49.952419800-05:00", 3927 - "updated_at": "2025-12-27T22:09:00.514201500-05:00", 3928 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3929 - }, 3930 - { 3931 - "id": 358, 3932 - "change_id": "fc211ac7-7a1a-4b69-835a-992c354e8237", 3933 - "node_type": "outcome", 3934 - "title": "Successfully fixed dark mode and dev/prod messaging", 3935 - "description": null, 3936 - "status": "completed", 3937 - "created_at": "2025-12-27T22:09:28.843864300-05:00", 3938 - "updated_at": "2025-12-27T22:09:32.017503200-05:00", 3939 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3940 - }, 3941 - { 3942 - "id": 359, 3943 - "change_id": "4a7d5885-1713-4ba7-ad13-bb12b58c9410", 3944 - "node_type": "outcome", 3945 - "title": "Committed fixes to git", 3946 - "description": null, 3947 - "status": "completed", 3948 - "created_at": "2025-12-27T22:10:25.576235500-05:00", 3949 - "updated_at": "2025-12-27T22:10:28.961887300-05:00", 3950 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"bd3aabb\",\"confidence\":95}" 3951 - }, 3952 - { 3953 - "id": 360, 3954 - "change_id": "706d5a7f-08ed-43f7-aee5-0bed28d9402a", 3955 - "node_type": "goal", 3956 - "title": "Fix extension not detecting login session despite dev server running", 3957 - "description": null, 3958 - "status": "completed", 3959 - "created_at": "2025-12-27T22:23:13.072419900-05:00", 3960 - "updated_at": "2025-12-27T22:41:49.160848100-05:00", 3961 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"prompt\":\"dark mode is fixed, but the extension in /chrome/ uploaded still is saying login with atlast and dev server is running\"}" 3962 - }, 3963 - { 3964 - "id": 361, 3965 - "change_id": "aecf2327-d20d-4c6c-b6b0-06ccf26a2b27", 3966 - "node_type": "observation", 3967 - "title": "Extension dist/chrome contains production build, not dev build. User ran build:prod last.", 3968 - "description": null, 3969 - "status": "completed", 3970 - "created_at": "2025-12-27T22:23:45.918832500-05:00", 3971 - "updated_at": "2025-12-27T22:23:48.919570500-05:00", 3972 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3973 - }, 3974 - { 3975 - "id": 362, 3976 - "change_id": "e897db97-44d8-4993-b4c3-0d829265b2f8", 3977 - "node_type": "observation", 3978 - "title": "Dev build now deployed. Extension will check session at http://127.0.0.1:8888/.netlify/functions/session with credentials:include", 3979 - "description": null, 3980 - "status": "completed", 3981 - "created_at": "2025-12-27T22:24:17.767230200-05:00", 3982 - "updated_at": "2025-12-27T22:24:20.981953100-05:00", 3983 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3984 - }, 3985 - { 3986 - "id": 363, 3987 - "change_id": "2c62bfa3-d148-4448-8c2b-d0cf1e94ceb0", 3988 - "node_type": "observation", 3989 - "title": "Found CORS issue: successResponse uses 'Access-Control-Allow-Origin: *' which blocks credentialed requests from extension", 3990 - "description": null, 3991 - "status": "completed", 3992 - "created_at": "2025-12-27T22:24:51.861265800-05:00", 3993 - "updated_at": "2025-12-27T22:24:55.482724500-05:00", 3994 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3995 - }, 3996 - { 3997 - "id": 364, 3998 - "change_id": "560d6bea-47ec-408d-919b-15ca7198aac9", 3999 - "node_type": "action", 4000 - "title": "Updating CORS headers to support credentialed requests from extension", 4001 - "description": null, 4002 - "status": "completed", 4003 - "created_at": "2025-12-27T22:25:23.035212700-05:00", 4004 - "updated_at": "2025-12-27T22:26:03.046221900-05:00", 4005 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 4006 - }, 4007 - { 4008 - "id": 365, 4009 - "change_id": "3ef0c9e9-aa40-4914-a5f4-32bcfaf68d04", 4010 - "node_type": "outcome", 4011 - "title": "Fixed CORS to support credentialed requests from extensions", 4012 - "description": null, 4013 - "status": "completed", 4014 - "created_at": "2025-12-27T22:41:38.430661200-05:00", 4015 - "updated_at": "2025-12-27T22:41:48.981429600-05:00", 4016 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4017 - }, 4018 - { 4019 - "id": 366, 4020 - "change_id": "77b7ed7e-a113-41f6-a677-50d376f3f008", 4021 - "node_type": "outcome", 4022 - "title": "Committed CORS fixes to git", 4023 - "description": null, 4024 - "status": "completed", 4025 - "created_at": "2025-12-27T22:42:49.037783-05:00", 4026 - "updated_at": "2025-12-27T22:42:54.162857-05:00", 4027 - "metadata_json": "{\"branch\":\"master\",\"commit\":\"603cf0a\",\"confidence\":95}" 4028 - }, 4029 - { 4030 - "id": 367, 4031 - "change_id": "df6abf7a-e7a4-45f3-8485-b933319416d9", 4032 - "node_type": "goal", 4033 - "title": "Create Firefox-compatible version of Twitter scraper extension", 4034 - "description": null, 4035 - "status": "completed", 4036 - "created_at": "2025-12-28T18:09:33.241860800-05:00", 4037 - "updated_at": "2025-12-28T19:21:32.412499-05:00", 4038 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85,\"prompt\":\"let's make the extension have a firefox compatible version too.\"}" 4039 - }, 4040 - { 4041 - "id": 368, 4042 - "change_id": "79721edf-aa05-4580-8c28-7d20941ef155", 4043 - "node_type": "observation", 4044 - "title": "Current extension uses Manifest V3 with Chrome-specific APIs", 4045 - "description": null, 4046 - "status": "pending", 4047 - "created_at": "2025-12-28T18:10:08.441348100-05:00", 4048 - "updated_at": "2025-12-28T18:10:08.441348100-05:00", 4049 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4050 - }, 4051 - { 4052 - "id": 369, 4053 - "change_id": "783841d0-c096-48f6-be18-193a9dcc7d4b", 4054 - "node_type": "observation", 4055 - "title": "Firefox compatibility analysis: Extension uses chrome.* APIs (runtime.sendMessage, storage.local, tabs.query/sendMessage), MV3 service worker. Firefox supports MV3 but has differences. Options: 1) Use webextension-polyfill for cross-browser, 2) Dual manifests (MV3 Chrome + MV2 Firefox), 3) Keep MV3 for both with minimal changes. Current build outputs to dist/chrome only.", 4056 - "description": null, 4057 - "status": "pending", 4058 - "created_at": "2025-12-28T18:10:48.087066800-05:00", 4059 - "updated_at": "2025-12-28T18:10:48.087066800-05:00", 4060 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 4061 - }, 4062 - { 4063 - "id": 370, 4064 - "change_id": "fd2d5b63-c26c-4592-89a6-3ccb4234c3c6", 4065 - "node_type": "decision", 4066 - "title": "Choose Firefox compatibility approach: webextension-polyfill, dual manifests, or minimal MV3 changes", 4067 - "description": null, 4068 - "status": "pending", 4069 - "created_at": "2025-12-28T18:10:50.375270400-05:00", 4070 - "updated_at": "2025-12-28T18:10:50.375270400-05:00", 4071 - "metadata_json": "{\"branch\":\"master\",\"confidence\":80}" 4072 - }, 4073 - { 4074 - "id": 371, 4075 - "change_id": "159906da-984f-4a1d-a1a6-98e0fc0cf369", 4076 - "node_type": "option", 4077 - "title": "Use webextension-polyfill library for unified cross-browser API", 4078 - "description": null, 4079 - "status": "pending", 4080 - "created_at": "2025-12-28T18:11:05.947924200-05:00", 4081 - "updated_at": "2025-12-28T18:11:05.947924200-05:00", 4082 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 4083 - }, 4084 - { 4085 - "id": 372, 4086 - "change_id": "df5e42e6-53c1-4b30-8b6f-f2385cd9e247", 4087 - "node_type": "option", 4088 - "title": "Dual manifests: MV3 for Chrome, MV2 for Firefox with separate builds", 4089 - "description": null, 4090 - "status": "pending", 4091 - "created_at": "2025-12-28T18:11:08.179938100-05:00", 4092 - "updated_at": "2025-12-28T18:11:08.179938100-05:00", 4093 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 4094 - }, 4095 - { 4096 - "id": 373, 4097 - "change_id": "7bb58202-7a9b-4e8b-8b9e-927e5106bce7", 4098 - "node_type": "option", 4099 - "title": "Keep MV3 for both browsers with minimal manifest tweaks", 4100 - "description": null, 4101 - "status": "pending", 4102 - "created_at": "2025-12-28T18:11:10.370113600-05:00", 4103 - "updated_at": "2025-12-28T18:11:10.370113600-05:00", 4104 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 4105 - }, 4106 - { 4107 - "id": 374, 4108 - "change_id": "d41b29e0-cd48-4dac-a6c8-c6179612702e", 4109 - "node_type": "outcome", 4110 - "title": "Chose webextension-polyfill approach. Provides unified browser.* API, Promise-based, future-proof MV3 for both browsers, +20KB but cleaner codebase", 4111 - "description": null, 4112 - "status": "pending", 4113 - "created_at": "2025-12-28T19:04:24.676770900-05:00", 4114 - "updated_at": "2025-12-28T19:04:24.676770900-05:00", 4115 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4116 - }, 4117 - { 4118 - "id": 375, 4119 - "change_id": "5bb34b8b-aec4-4f84-993e-eb9bf7a2d13f", 4120 - "node_type": "action", 4121 - "title": "Installing webextension-polyfill and updating source files to use browser.* API", 4122 - "description": null, 4123 - "status": "completed", 4124 - "created_at": "2025-12-28T19:08:14.642882400-05:00", 4125 - "updated_at": "2025-12-28T19:21:32.531034800-05:00", 4126 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 4127 - }, 4128 - { 4129 - "id": 376, 4130 - "change_id": "644181ee-5a44-4967-9657-e9dd5f648c5e", 4131 - "node_type": "outcome", 4132 - "title": "Successfully implemented Firefox compatibility with webextension-polyfill. Both Chrome and Firefox builds compile successfully. Chrome uses service_worker (MV3), Firefox uses scripts array with browser_specific_settings. All chrome.* API calls replaced with browser.* imports.", 4133 - "description": null, 4134 - "status": "completed", 4135 - "created_at": "2025-12-28T19:14:22.309457600-05:00", 4136 - "updated_at": "2025-12-28T19:21:32.658297400-05:00", 4137 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4138 - }, 4139 - { 4140 - "id": 377, 4141 - "change_id": "1dffa024-413f-4a95-b069-66db350abfaa", 4142 - "node_type": "goal", 4143 - "title": "Fix Firefox extension server detection and login check", 4144 - "description": null, 4145 - "status": "completed", 4146 - "created_at": "2025-12-28T20:14:51.646204800-05:00", 4147 - "updated_at": "2025-12-28T20:32:19.249555-05:00", 4148 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85,\"prompt\":\"The extension works in chrome. In firefox, it's failing to detect that the dev server is running and open + logged in on firefox. There's no right-click to inspect on the popup either.\"}" 4149 - }, 4150 - { 4151 - "id": 378, 4152 - "change_id": "9d5626d2-a9ae-42aa-8fda-be3c7528156f", 4153 - "node_type": "observation", 4154 - "title": "Firefox extension debugging differs from Chrome - need to use about:debugging Inspect button or Browser Console, not right-click popup", 4155 - "description": null, 4156 - "status": "pending", 4157 - "created_at": "2025-12-28T20:15:11.710473-05:00", 4158 - "updated_at": "2025-12-28T20:15:11.710473-05:00", 4159 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4160 - }, 4161 - { 4162 - "id": 379, 4163 - "change_id": "7a5af3fe-8567-4f1c-85cd-e47891704974", 4164 - "node_type": "observation", 4165 - "title": "Potential Firefox issues: 1) CORS with credentials:include may be stricter, 2) Cookie partitioning/third-party cookie blocking, 3) Extension needs explicit host_permissions for cookies to work. Firefox manifest has host_permissions but may need additional cookie permissions.", 4166 - "description": null, 4167 - "status": "pending", 4168 - "created_at": "2025-12-28T20:15:31.278249900-05:00", 4169 - "updated_at": "2025-12-28T20:15:31.278249900-05:00", 4170 - "metadata_json": "{\"branch\":\"master\",\"confidence\":85}" 4171 - }, 4172 - { 4173 - "id": 380, 4174 - "change_id": "9c197aae-18d5-46ae-87e7-82c240c8f313", 4175 - "node_type": "action", 4176 - "title": "Adding cookies permission to Firefox manifest for credentials:include support", 4177 - "description": null, 4178 - "status": "pending", 4179 - "created_at": "2025-12-28T20:16:12.019659700-05:00", 4180 - "updated_at": "2025-12-28T20:16:12.019659700-05:00", 4181 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 4182 - }, 4183 - { 4184 - "id": 381, 4185 - "change_id": "485a03b0-8a25-4fdf-a8e2-9d3a25c8edf8", 4186 - "node_type": "outcome", 4187 - "title": "Fixed Firefox cookie issue by adding cookies permission to manifest. Firefox requires explicit permission even with host_permissions. Rebuild successful.", 4188 - "description": null, 4189 - "status": "pending", 4190 - "created_at": "2025-12-28T20:16:41.702322300-05:00", 4191 - "updated_at": "2025-12-28T20:16:41.702322300-05:00", 4192 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4193 - }, 4194 - { 4195 - "id": 382, 4196 - "change_id": "35b13d37-0228-435f-a4bc-c5c42811fec3", 4197 - "node_type": "observation", 4198 - "title": "Firefox blocks extension fetch with CORS error despite host_permissions. Server responds 200 but missing Access-Control-Allow-Origin header. Firefox stricter than Chrome on extension CORS.", 4199 - "description": null, 4200 - "status": "pending", 4201 - "created_at": "2025-12-28T20:17:23.414134300-05:00", 4202 - "updated_at": "2025-12-28T20:17:23.414134300-05:00", 4203 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4204 - }, 4205 - { 4206 - "id": 383, 4207 - "change_id": "adc120cd-e56d-400a-9b3e-8207880378c3", 4208 - "node_type": "action", 4209 - "title": "Adding CORS headers to netlify.toml for extension compatibility - wildcard origin with credentials for dev", 4210 - "description": null, 4211 - "status": "pending", 4212 - "created_at": "2025-12-28T20:18:22.172869600-05:00", 4213 - "updated_at": "2025-12-28T20:18:22.172869600-05:00", 4214 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 4215 - }, 4216 - { 4217 - "id": 384, 4218 - "change_id": "0f77bfd9-590f-4f1e-be08-78a9deef6d8a", 4219 - "node_type": "outcome", 4220 - "title": "Added CORS headers to netlify.toml for all paths including root and functions. Headers include Access-Control-Allow-Origin:*, Allow-Credentials:true for dev environment. User needs to restart dev server.", 4221 - "description": null, 4222 - "status": "pending", 4223 - "created_at": "2025-12-28T20:19:54.829093600-05:00", 4224 - "updated_at": "2025-12-28T20:19:54.829093600-05:00", 4225 - "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 4226 - }, 4227 - { 4228 - "id": 385, 4229 - "change_id": "cc0910f0-2381-4aee-bb5d-397cb0f804d1", 4230 - "node_type": "observation", 4231 - "title": "CORS wildcard (*) incompatible with credentials:include. Browser security prevents wildcard CORS with credentialed requests. Extension origins are dynamic (moz-extension://, chrome-extension://). Need to handle CORS in serverless functions by reflecting request origin.", 4232 - "description": null, 4233 - "status": "pending", 4234 - "created_at": "2025-12-28T20:27:31.848523900-05:00", 4235 - "updated_at": "2025-12-28T20:27:31.848523900-05:00", 4236 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4237 - }, 4238 - { 4239 - "id": 386, 4240 - "change_id": "ad4a5ca7-15d1-4776-8ede-6b615613f6e1", 4241 - "node_type": "action", 4242 - "title": "Adding moz-extension:// origin detection to CORS handler for Firefox extension support", 4243 - "description": null, 4244 - "status": "completed", 4245 - "created_at": "2025-12-28T20:28:31.661326900-05:00", 4246 - "updated_at": "2025-12-28T20:32:19.367968600-05:00", 4247 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4248 - }, 4249 - { 4250 - "id": 387, 4251 - "change_id": "cffdee0f-8535-4d88-83ed-fdf6101f7ac3", 4252 - "node_type": "outcome", 4253 - "title": "Fixed Firefox extension CORS by adding moz-extension:// origin detection to response.utils.ts. Reverted netlify.toml changes as functions handle CORS correctly. User needs to restart dev server.", 4254 - "description": null, 4255 - "status": "completed", 4256 - "created_at": "2025-12-28T20:29:39.856303800-05:00", 4257 - "updated_at": "2025-12-28T20:32:19.494690-05:00", 4258 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4259 - }, 4260 - { 4261 - "id": 388, 4262 - "change_id": "0ada864e-be98-4a2f-a14e-ffd3eea9aaa9", 4263 - "node_type": "observation", 4264 - "title": "Health check uses HEAD request to root URL (Vite server), not a Netlify function. Doesn't get CORS headers from getCorsHeaders. Need dedicated health endpoint or change check to use existing function.", 4265 - "description": null, 4266 - "status": "completed", 4267 - "created_at": "2025-12-28T20:37:22.132717600-05:00", 4268 - "updated_at": "2025-12-28T20:38:41.630020900-05:00", 4269 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4270 - }, 4271 - { 4272 - "id": 389, 4273 - "change_id": "f522d5b2-c325-4f34-9f27-b8ea5c50618d", 4274 - "node_type": "outcome", 4275 - "title": "Created /health function endpoint with CORS support. Updated checkServerHealth to use /.netlify/functions/health instead of root URL. Extension rebuilt successfully.", 4276 - "description": null, 4277 - "status": "completed", 4278 - "created_at": "2025-12-28T20:38:19.981309500-05:00", 4279 - "updated_at": "2025-12-28T20:38:41.780183300-05:00", 4280 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4281 - }, 4282 - { 4283 - "id": 390, 4284 - "change_id": "cfdcf45b-47b3-4239-8053-417bd31957ed", 4285 - "node_type": "observation", 4286 - "title": "Server receives session request but returns CORS wildcard (*) instead of extension origin. No session cookie received. Origin header might not be sent by Firefox extension or not detected correctly.", 4287 - "description": null, 4288 - "status": "pending", 4289 - "created_at": "2025-12-28T20:48:12.770638500-05:00", 4290 - "updated_at": "2025-12-28T20:48:12.770638500-05:00", 4291 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4292 - }, 4293 - { 4294 - "id": 391, 4295 - "change_id": "2b53a419-9a47-4285-9a12-9bdfaeeb9ff0", 4296 - "node_type": "observation", 4297 - "title": "Health endpoint gets CORS headers correctly (moz-extension detected). Session endpoint error middleware doesn't pass event to errorResponse, returns wildcard CORS. Need to fix error middleware to pass event.", 4298 - "description": null, 4299 - "status": "completed", 4300 - "created_at": "2025-12-28T20:55:32.024834200-05:00", 4301 - "updated_at": "2025-12-28T21:38:14.729731500-05:00", 4302 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4303 - }, 4304 - { 4305 - "id": 392, 4306 - "change_id": "c941d136-3405-483d-bf34-7fb011f6d072", 4307 - "node_type": "action", 4308 - "title": "Fixed error middleware to pass event to errorResponse for proper CORS headers on errors", 4309 - "description": null, 4310 - "status": "completed", 4311 - "created_at": "2025-12-28T20:56:38.876266200-05:00", 4312 - "updated_at": "2025-12-28T21:38:14.888627800-05:00", 4313 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4314 - }, 4315 - { 4316 - "id": 393, 4317 - "change_id": "aafd9977-8800-4152-9f7f-b817db6df573", 4318 - "node_type": "outcome", 4319 - "title": "Fixed Firefox extension CORS completely. Error middleware now passes event to errorResponse so Firefox extension origin is properly reflected in error responses with credentials. Debug logging removed.", 4320 - "description": null, 4321 - "status": "completed", 4322 - "created_at": "2025-12-28T21:37:22.780953600-05:00", 4323 - "updated_at": "2025-12-28T21:38:15.071425500-05:00", 4324 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4325 - }, 4326 - { 4327 - "id": 394, 4328 - "change_id": "3b0dea7a-c3cd-45a8-ba1a-f1040aa4e1d9", 4329 - "node_type": "observation", 4330 - "title": "CORS fully working - Firefox extension origin properly reflected with credentials. But cookies not sent from extension despite credentials:include. Cookie set in web context not accessible from extension context due to Firefox cookie partitioning.", 4331 - "description": null, 4332 - "status": "completed", 4333 - "created_at": "2025-12-28T21:46:45.822343200-05:00", 4334 - "updated_at": "2025-12-28T22:51:46.665792900-05:00", 4335 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4336 - }, 4337 - { 4338 - "id": 395, 4339 - "change_id": "8a93413f-a09c-4cc1-8693-4fe90dc055c4", 4340 - "node_type": "action", 4341 - "title": "Updated extension checkSession to read cookie via browser.cookies API and pass as query parameter. Workaround for Firefox SameSite=Lax cookie partitioning.", 4342 - "description": null, 4343 - "status": "completed", 4344 - "created_at": "2025-12-28T21:52:22.059862700-05:00", 4345 - "updated_at": "2025-12-28T22:51:46.765539200-05:00", 4346 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4347 - }, 4348 - { 4349 - "id": 396, 4350 - "change_id": "864dd973-5f15-4e31-a7da-c548dbbe1f0e", 4351 - "node_type": "outcome", 4352 - "title": "Extension now uses browser.cookies.get() API to read session cookie and pass as query parameter. Workaround for Firefox SameSite=Lax cookie partitioning in extensions. Extension rebuilt successfully.", 4353 - "description": null, 4354 - "status": "completed", 4355 - "created_at": "2025-12-28T22:51:31.578965200-05:00", 4356 - "updated_at": "2025-12-28T22:51:46.868827600-05:00", 4357 - "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4358 - } 4359 - ], 4360 - "edges": [ 4361 - { 4362 - "id": 1, 4363 - "from_node_id": 1, 4364 - "to_node_id": 2, 4365 - "from_change_id": "9aee494f-f327-4068-9ef1-86ff07fdb2f5", 4366 - "to_change_id": "c0fca49e-faff-48e9-bf4d-d851ce0d1e87", 4367 - "edge_type": "leads_to", 4368 - "weight": 1.0, 4369 - "rationale": "Action to understand current implementation", 4370 - "created_at": "2025-12-23T00:16:49.771310300-05:00" 4371 - }, 4372 - { 4373 - "id": 2, 4374 - "from_node_id": 2, 4375 - "to_node_id": 3, 4376 - "from_change_id": "c0fca49e-faff-48e9-bf4d-d851ce0d1e87", 4377 - "to_change_id": "d53e1547-1f6a-4398-a734-a36d13c328c8", 4378 - "edge_type": "leads_to", 4379 - "weight": 1.0, 4380 - "rationale": "Observation from reading code", 4381 - "created_at": "2025-12-23T00:16:57.683291600-05:00" 4382 - }, 4383 - { 4384 - "id": 3, 4385 - "from_node_id": 3, 4386 - "to_node_id": 4, 4387 - "from_change_id": "d53e1547-1f6a-4398-a734-a36d13c328c8", 4388 - "to_change_id": "73ad63ab-0889-4790-b7e9-32fb4967d74a", 4389 - "edge_type": "leads_to", 4390 - "weight": 1.0, 4391 - "rationale": "Decision based on observation", 4392 - "created_at": "2025-12-23T00:17:10.599317900-05:00" 4393 - }, 4394 - { 4395 - "id": 4, 4396 - "from_node_id": 4, 4397 - "to_node_id": 5, 4398 - "from_change_id": "73ad63ab-0889-4790-b7e9-32fb4967d74a", 4399 - "to_change_id": "45d5d04a-27f7-47cb-8171-b1036584e40f", 4400 - "edge_type": "leads_to", 4401 - "weight": 1.0, 4402 - "rationale": "Option A for decision", 4403 - "created_at": "2025-12-23T00:17:21.837515-05:00" 4404 - }, 4405 - { 4406 - "id": 5, 4407 - "from_node_id": 4, 4408 - "to_node_id": 6, 4409 - "from_change_id": "73ad63ab-0889-4790-b7e9-32fb4967d74a", 4410 - "to_change_id": "87b7f433-fe62-4470-aaf2-de1d3447bdea", 4411 - "edge_type": "leads_to", 4412 - "weight": 1.0, 4413 - "rationale": "Option B for decision", 4414 - "created_at": "2025-12-23T00:17:23.251852-05:00" 4415 - }, 4416 - { 4417 - "id": 6, 4418 - "from_node_id": 4, 4419 - "to_node_id": 7, 4420 - "from_change_id": "73ad63ab-0889-4790-b7e9-32fb4967d74a", 4421 - "to_change_id": "66bb6ba2-961c-4008-a6cf-fb27aa29d934", 4422 - "edge_type": "leads_to", 4423 - "weight": 1.0, 4424 - "rationale": "Decision outcome", 4425 - "created_at": "2025-12-23T00:17:31.331616100-05:00" 4426 - }, 4427 - { 4428 - "id": 7, 4429 - "from_node_id": 7, 4430 - "to_node_id": 8, 4431 - "from_change_id": "66bb6ba2-961c-4008-a6cf-fb27aa29d934", 4432 - "to_change_id": "d670e4b0-a74e-4098-be81-111a07df214d", 4433 - "edge_type": "leads_to", 4434 - "weight": 1.0, 4435 - "rationale": "Action based on decision outcome", 4436 - "created_at": "2025-12-23T00:17:56.636925900-05:00" 4437 - }, 4438 - { 4439 - "id": 8, 4440 - "from_node_id": 8, 4441 - "to_node_id": 9, 4442 - "from_change_id": "d670e4b0-a74e-4098-be81-111a07df214d", 4443 - "to_change_id": "c6179665-8883-4414-91c6-6f7d6c58c977", 4444 - "edge_type": "leads_to", 4445 - "weight": 1.0, 4446 - "rationale": "Implementation completed successfully", 4447 - "created_at": "2025-12-23T00:19:16.187268400-05:00" 4448 - }, 4449 - { 4450 - "id": 9, 4451 - "from_node_id": 10, 4452 - "to_node_id": 11, 4453 - "from_change_id": "1ea05092-5ad4-4d66-96a7-ff40c12a7d8a", 4454 - "to_change_id": "3af4cfc5-fb60-4b2e-a05a-d1eba3905cc4", 4455 - "edge_type": "leads_to", 4456 - "weight": 1.0, 4457 - "rationale": "Action to analyze re-render problem", 4458 - "created_at": "2025-12-23T00:22:44.153313700-05:00" 4459 - }, 4460 - { 4461 - "id": 10, 4462 - "from_node_id": 11, 4463 - "to_node_id": 12, 4464 - "from_change_id": "3af4cfc5-fb60-4b2e-a05a-d1eba3905cc4", 4465 - "to_change_id": "3a6744f3-e1e1-4532-8f54-a7d84e0c6b9b", 4466 - "edge_type": "leads_to", 4467 - "weight": 1.0, 4468 - "rationale": "Observation from code analysis", 4469 - "created_at": "2025-12-23T00:22:46.970089400-05:00" 4470 - }, 4471 - { 4472 - "id": 11, 4473 - "from_node_id": 12, 4474 - "to_node_id": 13, 4475 - "from_change_id": "3a6744f3-e1e1-4532-8f54-a7d84e0c6b9b", 4476 - "to_change_id": "413df68c-2575-4794-abdb-4a4e9bf8f4c0", 4477 - "edge_type": "leads_to", 4478 - "weight": 1.0, 4479 - "rationale": "Decision based on observation", 4480 - "created_at": "2025-12-23T00:22:57.735421800-05:00" 4481 - }, 4482 - { 4483 - "id": 12, 4484 - "from_node_id": 13, 4485 - "to_node_id": 14, 4486 - "from_change_id": "413df68c-2575-4794-abdb-4a4e9bf8f4c0", 4487 - "to_change_id": "692a157c-d7e7-439c-a137-856efafd3e4f", 4488 - "edge_type": "leads_to", 4489 - "weight": 1.0, 4490 - "rationale": "Option A", 4491 - "created_at": "2025-12-23T00:23:13.692014-05:00" 4492 - }, 4493 - { 4494 - "id": 13, 4495 - "from_node_id": 13, 4496 - "to_node_id": 15, 4497 - "from_change_id": "413df68c-2575-4794-abdb-4a4e9bf8f4c0", 4498 - "to_change_id": "b525b78e-be8e-4eeb-9eda-8d90c2ea045a", 4499 - "edge_type": "leads_to", 4500 - "weight": 1.0, 4501 - "rationale": "Option B", 4502 - "created_at": "2025-12-23T00:23:13.781139600-05:00" 4503 - }, 4504 - { 4505 - "id": 14, 4506 - "from_node_id": 13, 4507 - "to_node_id": 16, 4508 - "from_change_id": "413df68c-2575-4794-abdb-4a4e9bf8f4c0", 4509 - "to_change_id": "2532bab6-bfb4-4202-9ca7-83c80fb64183", 4510 - "edge_type": "leads_to", 4511 - "weight": 1.0, 4512 - "rationale": "Option C", 4513 - "created_at": "2025-12-23T00:23:13.878475400-05:00" 4514 - }, 4515 - { 4516 - "id": 15, 4517 - "from_node_id": 13, 4518 - "to_node_id": 17, 4519 - "from_change_id": "413df68c-2575-4794-abdb-4a4e9bf8f4c0", 4520 - "to_change_id": "30e11366-da8b-4222-8e9d-118fbbb36123", 4521 - "edge_type": "leads_to", 4522 - "weight": 1.0, 4523 - "rationale": "Decision outcome", 4524 - "created_at": "2025-12-23T00:23:16.770626200-05:00" 4525 - }, 4526 - { 4527 - "id": 16, 4528 - "from_node_id": 17, 4529 - "to_node_id": 18, 4530 - "from_change_id": "30e11366-da8b-4222-8e9d-118fbbb36123", 4531 - "to_change_id": "bc0b23c3-0428-4e5c-b625-511185775d84", 4532 - "edge_type": "leads_to", 4533 - "weight": 1.0, 4534 - "rationale": "Action based on decision", 4535 - "created_at": "2025-12-23T00:23:40.924482800-05:00" 4536 - }, 4537 - { 4538 - "id": 17, 4539 - "from_node_id": 18, 4540 - "to_node_id": 19, 4541 - "from_change_id": "bc0b23c3-0428-4e5c-b625-511185775d84", 4542 - "to_change_id": "1e44b460-476c-4b7c-8440-69ce34db7764", 4543 - "edge_type": "leads_to", 4544 - "weight": 1.0, 4545 - "rationale": "Additional optimization opportunity found", 4546 - "created_at": "2025-12-23T00:24:01.488521800-05:00" 4547 - }, 4548 - { 4549 - "id": 18, 4550 - "from_node_id": 19, 4551 - "to_node_id": 20, 4552 - "from_change_id": "1e44b460-476c-4b7c-8440-69ce34db7764", 4553 - "to_change_id": "8966232e-79e8-4a77-8ef4-0b149c56582c", 4554 - "edge_type": "leads_to", 4555 - "weight": 1.0, 4556 - "rationale": "Implementation completed successfully", 4557 - "created_at": "2025-12-23T00:24:18.570613500-05:00" 4558 - }, 4559 - { 4560 - "id": 19, 4561 - "from_node_id": 21, 4562 - "to_node_id": 22, 4563 - "from_change_id": "5c5628db-b79f-4c85-8c25-b03e1d0f8b3f", 4564 - "to_change_id": "52249f48-bd1d-4242-aeb9-0812ff508bc3", 4565 - "edge_type": "leads_to", 4566 - "weight": 1.0, 4567 - "rationale": "Action to analyze hooks", 4568 - "created_at": "2025-12-23T00:28:17.512532400-05:00" 4569 - }, 4570 - { 4571 - "id": 20, 4572 - "from_node_id": 22, 4573 - "to_node_id": 23, 4574 - "from_change_id": "52249f48-bd1d-4242-aeb9-0812ff508bc3", 4575 - "to_change_id": "446cf6f8-bd4d-4a11-bd74-cfab9a9aa869", 4576 - "edge_type": "leads_to", 4577 - "weight": 1.0, 4578 - "rationale": "Observation from analysis", 4579 - "created_at": "2025-12-23T00:28:20.425036-05:00" 4580 - }, 4581 - { 4582 - "id": 21, 4583 - "from_node_id": 23, 4584 - "to_node_id": 24, 4585 - "from_change_id": "446cf6f8-bd4d-4a11-bd74-cfab9a9aa869", 4586 - "to_change_id": "40abf558-716f-4533-91b7-3a51163d50f6", 4587 - "edge_type": "leads_to", 4588 - "weight": 1.0, 4589 - "rationale": "Implementation action", 4590 - "created_at": "2025-12-23T00:28:31.882410900-05:00" 4591 - }, 4592 - { 4593 - "id": 22, 4594 - "from_node_id": 24, 4595 - "to_node_id": 25, 4596 - "from_change_id": "40abf558-716f-4533-91b7-3a51163d50f6", 4597 - "to_change_id": "03e77df3-970c-4443-b497-09b7976be42e", 4598 - "edge_type": "leads_to", 4599 - "weight": 1.0, 4600 - "rationale": "Implementation completed for useSearch", 4601 - "created_at": "2025-12-23T00:29:25.953911200-05:00" 4602 - }, 4603 - { 4604 - "id": 23, 4605 - "from_node_id": 25, 4606 - "to_node_id": 26, 4607 - "from_change_id": "03e77df3-970c-4443-b497-09b7976be42e", 4608 - "to_change_id": "bad40d96-109e-4acb-9d5f-7c8ba11586e0", 4609 - "edge_type": "leads_to", 4610 - "weight": 1.0, 4611 - "rationale": "Next action", 4612 - "created_at": "2025-12-23T00:29:29.160300700-05:00" 4613 - }, 4614 - { 4615 - "id": 24, 4616 - "from_node_id": 26, 4617 - "to_node_id": 27, 4618 - "from_change_id": "bad40d96-109e-4acb-9d5f-7c8ba11586e0", 4619 - "to_change_id": "a1a3c887-b702-45ac-bac0-5162cbfe6d42", 4620 - "edge_type": "leads_to", 4621 - "weight": 1.0, 4622 - "rationale": "Implementation completed for useFollows", 4623 - "created_at": "2025-12-23T00:29:58.824034200-05:00" 4624 - }, 4625 - { 4626 - "id": 25, 4627 - "from_node_id": 28, 4628 - "to_node_id": 29, 4629 - "from_change_id": "b022604c-fe3a-4ab0-8863-bfb0b641af49", 4630 - "to_change_id": "e6db1fc5-62e1-4092-85db-ae8a6767882f", 4631 - "edge_type": "leads_to", 4632 - "weight": 1.0, 4633 - "rationale": "Action to understand current implementation", 4634 - "created_at": "2025-12-23T00:31:36.669305800-05:00" 4635 - }, 4636 - { 4637 - "id": 26, 4638 - "from_node_id": 29, 4639 - "to_node_id": 30, 4640 - "from_change_id": "e6db1fc5-62e1-4092-85db-ae8a6767882f", 4641 - "to_change_id": "ce6b969f-f167-4370-826c-f053922df20d", 4642 - "edge_type": "leads_to", 4643 - "weight": 1.0, 4644 - "rationale": "Observation from code analysis", 4645 - "created_at": "2025-12-23T00:31:39.697218200-05:00" 4646 - }, 4647 - { 4648 - "id": 27, 4649 - "from_node_id": 30, 4650 - "to_node_id": 31, 4651 - "from_change_id": "ce6b969f-f167-4370-826c-f053922df20d", 4652 - "to_change_id": "fbf37117-f225-40a9-b563-011b3e0b118a", 4653 - "edge_type": "leads_to", 4654 - "weight": 1.0, 4655 - "rationale": "Next action: install date-fns", 4656 - "created_at": "2025-12-23T00:31:55.744366100-05:00" 4657 - }, 4658 - { 4659 - "id": 28, 4660 - "from_node_id": 31, 4661 - "to_node_id": 32, 4662 - "from_change_id": "fbf37117-f225-40a9-b563-011b3e0b118a", 4663 - "to_change_id": "7168cc35-a99a-4b6d-a6d3-000a1040a2f0", 4664 - "edge_type": "leads_to", 4665 - "weight": 1.0, 4666 - "rationale": "Installation completed", 4667 - "created_at": "2025-12-23T00:34:04.813216600-05:00" 4668 - }, 4669 - { 4670 - "id": 29, 4671 - "from_node_id": 32, 4672 - "to_node_id": 33, 4673 - "from_change_id": "7168cc35-a99a-4b6d-a6d3-000a1040a2f0", 4674 - "to_change_id": "2a443551-bd2f-40a6-9464-8de496a248b4", 4675 - "edge_type": "leads_to", 4676 - "weight": 1.0, 4677 - "rationale": "Next action: replace implementations", 4678 - "created_at": "2025-12-23T00:34:07.803829-05:00" 4679 - }, 4680 - { 4681 - "id": 30, 4682 - "from_node_id": 33, 4683 - "to_node_id": 34, 4684 - "from_change_id": "2a443551-bd2f-40a6-9464-8de496a248b4", 4685 - "to_change_id": "1aea7359-8009-40e1-a75a-78a3c31ec0ee", 4686 - "edge_type": "leads_to", 4687 - "weight": 1.0, 4688 - "rationale": "Implementation completed successfully", 4689 - "created_at": "2025-12-23T00:35:00.269876100-05:00" 4690 - }, 4691 - { 4692 - "id": 31, 4693 - "from_node_id": 35, 4694 - "to_node_id": 36, 4695 - "from_change_id": "9a55a4c5-c1f3-4475-98b2-c0c7f02ea48e", 4696 - "to_change_id": "bb55eb60-dd7f-479c-93a1-bf95fed58de0", 4697 - "edge_type": "leads_to", 4698 - "weight": 1.0, 4699 - "rationale": "Action to understand current validation", 4700 - "created_at": "2025-12-23T00:37:36.398329800-05:00" 4701 - }, 4702 - { 4703 - "id": 32, 4704 - "from_node_id": 36, 4705 - "to_node_id": 37, 4706 - "from_change_id": "bb55eb60-dd7f-479c-93a1-bf95fed58de0", 4707 - "to_change_id": "6350c610-e3cc-4f18-8d98-42adedd8459b", 4708 - "edge_type": "leads_to", 4709 - "weight": 1.0, 4710 - "rationale": "Observation from code analysis", 4711 - "created_at": "2025-12-23T00:37:39.427592400-05:00" 4712 - }, 4713 - { 4714 - "id": 33, 4715 - "from_node_id": 37, 4716 - "to_node_id": 38, 4717 - "from_change_id": "6350c610-e3cc-4f18-8d98-42adedd8459b", 4718 - "to_change_id": "e6bc1cd1-d51b-4410-a7d6-b25e24c14398", 4719 - "edge_type": "leads_to", 4720 - "weight": 1.0, 4721 - "rationale": "Decision on integration approach", 4722 - "created_at": "2025-12-23T00:38:11.567636500-05:00" 4723 - }, 4724 - { 4725 - "id": 34, 4726 - "from_node_id": 38, 4727 - "to_node_id": 39, 4728 - "from_change_id": "e6bc1cd1-d51b-4410-a7d6-b25e24c14398", 4729 - "to_change_id": "8754ba8f-6c78-453c-995b-2ac67e5bc44b", 4730 - "edge_type": "leads_to", 4731 - "weight": 1.0, 4732 - "rationale": "Option A", 4733 - "created_at": "2025-12-23T00:38:27.129562800-05:00" 4734 - }, 4735 - { 4736 - "id": 35, 4737 - "from_node_id": 38, 4738 - "to_node_id": 40, 4739 - "from_change_id": "e6bc1cd1-d51b-4410-a7d6-b25e24c14398", 4740 - "to_change_id": "bb8db74f-f1a3-44b7-bfd6-73a040e712f1", 4741 - "edge_type": "leads_to", 4742 - "weight": 1.0, 4743 - "rationale": "Option B", 4744 - "created_at": "2025-12-23T00:38:27.210327-05:00" 4745 - }, 4746 - { 4747 - "id": 36, 4748 - "from_node_id": 38, 4749 - "to_node_id": 41, 4750 - "from_change_id": "e6bc1cd1-d51b-4410-a7d6-b25e24c14398", 4751 - "to_change_id": "b5817928-cabe-4dcc-843c-3b7278a0fb4c", 4752 - "edge_type": "leads_to", 4753 - "weight": 1.0, 4754 - "rationale": "Option C", 4755 - "created_at": "2025-12-23T00:38:27.320703600-05:00" 4756 - }, 4757 - { 4758 - "id": 37, 4759 - "from_node_id": 38, 4760 - "to_node_id": 42, 4761 - "from_change_id": "e6bc1cd1-d51b-4410-a7d6-b25e24c14398", 4762 - "to_change_id": "6a0dc295-b19e-4889-8980-767cfd49e258", 4763 - "edge_type": "leads_to", 4764 - "weight": 1.0, 4765 - "rationale": "Decision outcome", 4766 - "created_at": "2025-12-23T00:38:30.944356300-05:00" 4767 - }, 4768 - { 4769 - "id": 38, 4770 - "from_node_id": 42, 4771 - "to_node_id": 43, 4772 - "from_change_id": "6a0dc295-b19e-4889-8980-767cfd49e258", 4773 - "to_change_id": "0423e6ea-2491-44bb-bf0a-16c67085826c", 4774 - "edge_type": "leads_to", 4775 - "weight": 1.0, 4776 - "rationale": "Next action: install zod", 4777 - "created_at": "2025-12-23T00:38:35.182524-05:00" 4778 - }, 4779 - { 4780 - "id": 39, 4781 - "from_node_id": 43, 4782 - "to_node_id": 44, 4783 - "from_change_id": "0423e6ea-2491-44bb-bf0a-16c67085826c", 4784 - "to_change_id": "8ada1961-6fdd-4eaa-a6db-1bcc78da914d", 4785 - "edge_type": "leads_to", 4786 - "weight": 1.0, 4787 - "rationale": "Installation completed", 4788 - "created_at": "2025-12-23T00:39:04.546943100-05:00" 4789 - }, 4790 - { 4791 - "id": 40, 4792 - "from_node_id": 44, 4793 - "to_node_id": 45, 4794 - "from_change_id": "8ada1961-6fdd-4eaa-a6db-1bcc78da914d", 4795 - "to_change_id": "32f3ede8-5d4d-4764-84f5-55e69f11ed81", 4796 - "edge_type": "leads_to", 4797 - "weight": 1.0, 4798 - "rationale": "Next action: refactor validation", 4799 - "created_at": "2025-12-23T00:39:07.551539-05:00" 4800 - }, 4801 - { 4802 - "id": 41, 4803 - "from_node_id": 45, 4804 - "to_node_id": 46, 4805 - "from_change_id": "32f3ede8-5d4d-4764-84f5-55e69f11ed81", 4806 - "to_change_id": "620eaba1-4306-4cd5-abe7-07ea82e17ca4", 4807 - "edge_type": "leads_to", 4808 - "weight": 1.0, 4809 - "rationale": "Implementation completed successfully", 4810 - "created_at": "2025-12-23T00:39:39.619645200-05:00" 4811 - }, 4812 - { 4813 - "id": 42, 4814 - "from_node_id": 47, 4815 - "to_node_id": 48, 4816 - "from_change_id": "d0845848-9edf-4cfd-b770-457be0a6c11d", 4817 - "to_change_id": "44b3b8eb-4676-4a29-afa9-a2aab3e8c9a8", 4818 - "edge_type": "leads_to", 4819 - "weight": 1.0, 4820 - "rationale": "Plan creation completed", 4821 - "created_at": "2025-12-23T00:50:34.767098400-05:00" 4822 - }, 4823 - { 4824 - "id": 43, 4825 - "from_node_id": 49, 4826 - "to_node_id": 1, 4827 - "from_change_id": "31331aa1-1938-479f-8527-65346d2fa764", 4828 - "to_change_id": "9aee494f-f327-4068-9ef1-86ff07fdb2f5", 4829 - "edge_type": "leads_to", 4830 - "weight": 1.0, 4831 - "rationale": "Sub-goal: Parallelize batch follow operations (#1)", 4832 - "created_at": "2025-12-23T14:23:30.301632200-05:00" 4833 - }, 4834 - { 4835 - "id": 44, 4836 - "from_node_id": 49, 4837 - "to_node_id": 10, 4838 - "from_change_id": "31331aa1-1938-479f-8527-65346d2fa764", 4839 - "to_change_id": "1ea05092-5ad4-4d66-96a7-ff40c12a7d8a", 4840 - "edge_type": "leads_to", 4841 - "weight": 1.0, 4842 - "rationale": "Sub-goal: Fix excessive re-renders in search hook (#2)", 4843 - "created_at": "2025-12-23T14:23:32.455615700-05:00" 4844 - }, 4845 - { 4846 - "id": 45, 4847 - "from_node_id": 49, 4848 - "to_node_id": 21, 4849 - "from_change_id": "31331aa1-1938-479f-8527-65346d2fa764", 4850 - "to_change_id": "5c5628db-b79f-4c85-8c25-b03e1d0f8b3f", 4851 - "edge_type": "leads_to", 4852 - "weight": 1.0, 4853 - "rationale": "Sub-goal: Add useCallback to hook-returned functions (#3)", 4854 - "created_at": "2025-12-23T14:23:34.607186900-05:00" 4855 - }, 4856 - { 4857 - "id": 46, 4858 - "from_node_id": 49, 4859 - "to_node_id": 28, 4860 - "from_change_id": "31331aa1-1938-479f-8527-65346d2fa764", 4861 - "to_change_id": "b022604c-fe3a-4ab0-8863-bfb0b641af49", 4862 - "edge_type": "leads_to", 4863 - "weight": 1.0, 4864 - "rationale": "Sub-goal: Replace custom date formatting with date-fns (#4)", 4865 - "created_at": "2025-12-23T14:23:36.686953-05:00" 4866 - }, 4867 - { 4868 - "id": 47, 4869 - "from_node_id": 49, 4870 - "to_node_id": 35, 4871 - "from_change_id": "31331aa1-1938-479f-8527-65346d2fa764", 4872 - "to_change_id": "9a55a4c5-c1f3-4475-98b2-c0c7f02ea48e", 4873 - "edge_type": "leads_to", 4874 - "weight": 1.0, 4875 - "rationale": "Sub-goal: Replace custom validation with Zod (#5)", 4876 - "created_at": "2025-12-23T14:23:38.891395500-05:00" 4877 - }, 4878 - { 4879 - "id": 48, 4880 - "from_node_id": 49, 4881 - "to_node_id": 47, 4882 - "from_change_id": "31331aa1-1938-479f-8527-65346d2fa764", 4883 - "to_change_id": "d0845848-9edf-4cfd-b770-457be0a6c11d", 4884 - "edge_type": "leads_to", 4885 - "weight": 1.0, 4886 - "rationale": "Sub-goal: Create implementation plan for remaining work", 4887 - "created_at": "2025-12-23T14:23:41.067572500-05:00" 4888 - }, 4889 - { 4890 - "id": 49, 4891 - "from_node_id": 48, 4892 - "to_node_id": 50, 4893 - "from_change_id": "44b3b8eb-4676-4a29-afa9-a2aab3e8c9a8", 4894 - "to_change_id": "9ee094c0-c179-4350-a9bb-cd67f5fdd3af", 4895 - "edge_type": "leads_to", 4896 - "weight": 1.0, 4897 - "rationale": "Session summary", 4898 - "created_at": "2025-12-23T14:23:54.618588400-05:00" 4899 - }, 4900 - { 4901 - "id": 50, 4902 - "from_node_id": 50, 4903 - "to_node_id": 51, 4904 - "from_change_id": "9ee094c0-c179-4350-a9bb-cd67f5fdd3af", 4905 - "to_change_id": "a5d144e1-535a-4d6e-89dc-8800813fca72", 4906 - "edge_type": "leads_to", 4907 - "weight": 1.0, 4908 - "rationale": "PLAN.md recreated", 4909 - "created_at": "2025-12-23T14:57:01.323762900-05:00" 4910 - }, 4911 - { 4912 - "id": 51, 4913 - "from_node_id": 49, 4914 - "to_node_id": 52, 4915 - "from_change_id": "31331aa1-1938-479f-8527-65346d2fa764", 4916 - "to_change_id": "c047c9ac-eccb-4545-ad40-b40292d8e39c", 4917 - "edge_type": "leads_to", 4918 - "weight": 1.0, 4919 - "rationale": "Sub-goal: Optimization #6 from master optimization plan", 4920 - "created_at": "2025-12-23T15:06:43.116328700-05:00" 4921 - }, 4922 - { 4923 - "id": 52, 4924 - "from_node_id": 52, 4925 - "to_node_id": 53, 4926 - "from_change_id": "c047c9ac-eccb-4545-ad40-b40292d8e39c", 4927 - "to_change_id": "8c19132d-7a6b-4103-92f7-d8899e89819a", 4928 - "edge_type": "leads_to", 4929 - "weight": 1.0, 4930 - "rationale": "First action for goal #52", 4931 - "created_at": "2025-12-23T15:06:47.781445500-05:00" 4932 - }, 4933 - { 4934 - "id": 53, 4935 - "from_node_id": 53, 4936 - "to_node_id": 54, 4937 - "from_change_id": "8c19132d-7a6b-4103-92f7-d8899e89819a", 4938 - "to_change_id": "f98802fa-4302-401e-8e10-a31f241cc912", 4939 - "edge_type": "leads_to", 4940 - "weight": 1.0, 4941 - "rationale": "Observation from reading code", 4942 - "created_at": "2025-12-23T15:07:09.567009-05:00" 4943 - }, 4944 - { 4945 - "id": 54, 4946 - "from_node_id": 54, 4947 - "to_node_id": 55, 4948 - "from_change_id": "f98802fa-4302-401e-8e10-a31f241cc912", 4949 - "to_change_id": "71c3ad1c-3194-4b3c-8b29-a28187d092cd", 4950 - "edge_type": "leads_to", 4951 - "weight": 1.0, 4952 - "rationale": "Outcome from observation", 4953 - "created_at": "2025-12-23T15:07:20.321268700-05:00" 4954 - }, 4955 - { 4956 - "id": 55, 4957 - "from_node_id": 49, 4958 - "to_node_id": 56, 4959 - "from_change_id": "31331aa1-1938-479f-8527-65346d2fa764", 4960 - "to_change_id": "5c435252-d5f5-44bb-a11b-60be41faf611", 4961 - "edge_type": "leads_to", 4962 - "weight": 1.0, 4963 - "rationale": "Sub-goal: Optimization #7 from master optimization plan", 4964 - "created_at": "2025-12-23T15:09:33.204012400-05:00" 4965 - }, 4966 - { 4967 - "id": 56, 4968 - "from_node_id": 56, 4969 - "to_node_id": 57, 4970 - "from_change_id": "5c435252-d5f5-44bb-a11b-60be41faf611", 4971 - "to_change_id": "d6259df0-3a53-42e9-bbf9-77eb220fb8b8", 4972 - "edge_type": "leads_to", 4973 - "weight": 1.0, 4974 - "rationale": "First action for goal #56", 4975 - "created_at": "2025-12-23T15:09:38.098415800-05:00" 4976 - }, 4977 - { 4978 - "id": 57, 4979 - "from_node_id": 57, 4980 - "to_node_id": 58, 4981 - "from_change_id": "d6259df0-3a53-42e9-bbf9-77eb220fb8b8", 4982 - "to_change_id": "94a34242-7d31-405e-b1b7-ad1b456954b6", 4983 - "edge_type": "leads_to", 4984 - "weight": 1.0, 4985 - "rationale": "Observation from search", 4986 - "created_at": "2025-12-23T15:10:27.802949700-05:00" 4987 - }, 4988 - { 4989 - "id": 58, 4990 - "from_node_id": 58, 4991 - "to_node_id": 59, 4992 - "from_change_id": "94a34242-7d31-405e-b1b7-ad1b456954b6", 4993 - "to_change_id": "a9af8b98-06d6-4cb5-adde-97c38daabb72", 4994 - "edge_type": "leads_to", 4995 - "weight": 1.0, 4996 - "rationale": "Decision on implementation approach", 4997 - "created_at": "2025-12-23T15:11:58.141205800-05:00" 4998 - }, 4999 - { 5000 - "id": 59, 5001 - "from_node_id": 59, 5002 - "to_node_id": 60, 5003 - "from_change_id": "a9af8b98-06d6-4cb5-adde-97c38daabb72", 5004 - "to_change_id": "a51e3154-2cf7-49eb-a4c9-5bd1108db5b7", 5005 - "edge_type": "leads_to", 5006 - "weight": 1.0, 5007 - "rationale": "Option A", 5008 - "created_at": "2025-12-23T15:16:05.603082-05:00" 5009 - }, 5010 - { 5011 - "id": 60, 5012 - "from_node_id": 59, 5013 - "to_node_id": 61, 5014 - "from_change_id": "a9af8b98-06d6-4cb5-adde-97c38daabb72", 5015 - "to_change_id": "13982cbf-a6ce-4216-ae4a-2d11b543df14", 5016 - "edge_type": "leads_to", 5017 - "weight": 1.0, 5018 - "rationale": "Option B", 5019 - "created_at": "2025-12-23T15:16:10.138600-05:00" 5020 - }, 5021 - { 5022 - "id": 61, 5023 - "from_node_id": 59, 5024 - "to_node_id": 62, 5025 - "from_change_id": "a9af8b98-06d6-4cb5-adde-97c38daabb72", 5026 - "to_change_id": "2a441228-42e2-410a-931d-a70cac938cb8", 5027 - "edge_type": "leads_to", 5028 - "weight": 1.0, 5029 - "rationale": "Decision outcome", 5030 - "created_at": "2025-12-23T15:16:14.819265200-05:00" 5031 - }, 5032 - { 5033 - "id": 62, 5034 - "from_node_id": 62, 5035 - "to_node_id": 63, 5036 - "from_change_id": "2a441228-42e2-410a-931d-a70cac938cb8", 5037 - "to_change_id": "12297d1b-f757-4307-898a-3913e54599a7", 5038 - "edge_type": "leads_to", 5039 - "weight": 1.0, 5040 - "rationale": "Decision updated based on user input", 5041 - "created_at": "2025-12-23T15:17:48.885010400-05:00" 5042 - }, 5043 - { 5044 - "id": 63, 5045 - "from_node_id": 63, 5046 - "to_node_id": 64, 5047 - "from_change_id": "12297d1b-f757-4307-898a-3913e54599a7", 5048 - "to_change_id": "110b0df4-2d27-4920-a722-28a7bb309c1f", 5049 - "edge_type": "leads_to", 5050 - "weight": 1.0, 5051 - "rationale": "Implementation action", 5052 - "created_at": "2025-12-23T15:17:51.050688700-05:00" 5053 - }, 5054 - { 5055 - "id": 64, 5056 - "from_node_id": 64, 5057 - "to_node_id": 65, 5058 - "from_change_id": "110b0df4-2d27-4920-a722-28a7bb309c1f", 5059 - "to_change_id": "6a128a77-e514-4b6a-aeb7-20bd0159a0f3", 5060 - "edge_type": "leads_to", 5061 - "weight": 1.0, 5062 - "rationale": "Next action: update files", 5063 - "created_at": "2025-12-23T15:18:43.223303700-05:00" 5064 - }, 5065 - { 5066 - "id": 65, 5067 - "from_node_id": 65, 5068 - "to_node_id": 66, 5069 - "from_change_id": "6a128a77-e514-4b6a-aeb7-20bd0159a0f3", 5070 - "to_change_id": "a139806c-7a1a-4c18-8199-558f765670c4", 5071 - "edge_type": "leads_to", 5072 - "weight": 1.0, 5073 - "rationale": "Implementation completed successfully", 5074 - "created_at": "2025-12-23T15:24:49.467490800-05:00" 5075 - }, 5076 - { 5077 - "id": 66, 5078 - "from_node_id": 66, 5079 - "to_node_id": 68, 5080 - "from_change_id": "a139806c-7a1a-4c18-8199-558f765670c4", 5081 - "to_change_id": "10c05711-9c49-47d8-b032-caa6e3bc887e", 5082 - "edge_type": "leads_to", 5083 - "weight": 1.0, 5084 - "rationale": "Changes committed", 5085 - "created_at": "2025-12-23T15:58:51.773855900-05:00" 5086 - }, 5087 - { 5088 - "id": 67, 5089 - "from_node_id": 49, 5090 - "to_node_id": 69, 5091 - "from_change_id": "31331aa1-1938-479f-8527-65346d2fa764", 5092 - "to_change_id": "5754ca49-f09b-489f-a4b0-f412159f4cd4", 5093 - "edge_type": "leads_to", 5094 - "weight": 1.0, 5095 - "rationale": "Sub-goal: Optimization #8 from master optimization plan", 5096 - "created_at": "2025-12-23T15:59:35.484567600-05:00" 5097 - }, 5098 - { 5099 - "id": 68, 5100 - "from_node_id": 69, 5101 - "to_node_id": 70, 5102 - "from_change_id": "5754ca49-f09b-489f-a4b0-f412159f4cd4", 5103 - "to_change_id": "e14bd69e-6821-4586-b96d-0ef16490c803", 5104 - "edge_type": "leads_to", 5105 - "weight": 1.0, 5106 - "rationale": "First action for goal #69", 5107 - "created_at": "2025-12-23T15:59:40.656346500-05:00" 5108 - }, 5109 - { 5110 - "id": 69, 5111 - "from_node_id": 70, 5112 - "to_node_id": 71, 5113 - "from_change_id": "e14bd69e-6821-4586-b96d-0ef16490c803", 5114 - "to_change_id": "0a4aa61e-96d5-4606-b088-39161105dc82", 5115 - "edge_type": "leads_to", 5116 - "weight": 1.0, 5117 - "rationale": "Observation from comparison", 5118 - "created_at": "2025-12-23T16:00:20.594363-05:00" 5119 - }, 5120 - { 5121 - "id": 70, 5122 - "from_node_id": 71, 5123 - "to_node_id": 72, 5124 - "from_change_id": "0a4aa61e-96d5-4606-b088-39161105dc82", 5125 - "to_change_id": "25010f9a-2b6a-4a72-80ac-8449710ad222", 5126 - "edge_type": "leads_to", 5127 - "weight": 1.0, 5128 - "rationale": "Implementation action", 5129 - "created_at": "2025-12-23T16:00:33.269030400-05:00" 5130 - }, 5131 - { 5132 - "id": 71, 5133 - "from_node_id": 72, 5134 - "to_node_id": 73, 5135 - "from_change_id": "25010f9a-2b6a-4a72-80ac-8449710ad222", 5136 - "to_change_id": "9ec33280-3c44-4e86-a133-aa3e1e839927", 5137 - "edge_type": "leads_to", 5138 - "weight": 1.0, 5139 - "rationale": "Implementation completed successfully", 5140 - "created_at": "2025-12-23T16:06:49.730904100-05:00" 5141 - }, 5142 - { 5143 - "id": 72, 5144 - "from_node_id": 73, 5145 - "to_node_id": 74, 5146 - "from_change_id": "9ec33280-3c44-4e86-a133-aa3e1e839927", 5147 - "to_change_id": "1f337abb-4b6f-486e-a7d0-3ce0c014952a", 5148 - "edge_type": "leads_to", 5149 - "weight": 1.0, 5150 - "rationale": "Changes committed", 5151 - "created_at": "2025-12-23T16:09:45.962708600-05:00" 5152 - }, 5153 - { 5154 - "id": 73, 5155 - "from_node_id": 74, 5156 - "to_node_id": 75, 5157 - "from_change_id": "1f337abb-4b6f-486e-a7d0-3ce0c014952a", 5158 - "to_change_id": "54175447-ee48-47a2-91b3-0dc01b00ce2f", 5159 - "edge_type": "leads_to", 5160 - "weight": 1.0, 5161 - "rationale": "Session summary", 5162 - "created_at": "2025-12-23T16:10:04.080510800-05:00" 5163 - }, 5164 - { 5165 - "id": 74, 5166 - "from_node_id": 49, 5167 - "to_node_id": 76, 5168 - "from_change_id": "31331aa1-1938-479f-8527-65346d2fa764", 5169 - "to_change_id": "557cb7ea-db8d-41f9-910d-2cfc3c1f221d", 5170 - "edge_type": "leads_to", 5171 - "weight": 1.0, 5172 - "rationale": "Sub-goal: Optimization #9 from master optimization plan", 5173 - "created_at": "2025-12-23T18:00:37.302317900-05:00" 5174 - }, 5175 - { 5176 - "id": 75, 5177 - "from_node_id": 76, 5178 - "to_node_id": 77, 5179 - "from_change_id": "557cb7ea-db8d-41f9-910d-2cfc3c1f221d", 5180 - "to_change_id": "44915a01-c89b-4c75-b370-b1860400d262", 5181 - "edge_type": "leads_to", 5182 - "weight": 1.0, 5183 - "rationale": "First action for goal #76", 5184 - "created_at": "2025-12-23T18:00:43.213937300-05:00" 5185 - }, 5186 - { 5187 - "id": 76, 5188 - "from_node_id": 77, 5189 - "to_node_id": 78, 5190 - "from_change_id": "44915a01-c89b-4c75-b370-b1860400d262", 5191 - "to_change_id": "5d181171-7525-4304-8185-0e0a6f95ef4f", 5192 - "edge_type": "leads_to", 5193 - "weight": 1.0, 5194 - "rationale": "Observation from search", 5195 - "created_at": "2025-12-23T18:02:00.252642100-05:00" 5196 - }, 5197 - { 5198 - "id": 77, 5199 - "from_node_id": 78, 5200 - "to_node_id": 79, 5201 - "from_change_id": "5d181171-7525-4304-8185-0e0a6f95ef4f", 5202 - "to_change_id": "6afe3ed4-b165-418f-9ad7-24a43593c5b5", 5203 - "edge_type": "leads_to", 5204 - "weight": 1.0, 5205 - "rationale": "Implementation action", 5206 - "created_at": "2025-12-23T18:02:19.722802300-05:00" 5207 - }, 5208 - { 5209 - "id": 78, 5210 - "from_node_id": 79, 5211 - "to_node_id": 80, 5212 - "from_change_id": "6afe3ed4-b165-418f-9ad7-24a43593c5b5", 5213 - "to_change_id": "b7f96cec-120b-4001-94e7-0e85e3e21ba5", 5214 - "edge_type": "leads_to", 5215 - "weight": 1.0, 5216 - "rationale": "Next action", 5217 - "created_at": "2025-12-23T18:02:55.146412900-05:00" 5218 - }, 5219 - { 5220 - "id": 79, 5221 - "from_node_id": 80, 5222 - "to_node_id": 81, 5223 - "from_change_id": "b7f96cec-120b-4001-94e7-0e85e3e21ba5", 5224 - "to_change_id": "aad16dbf-1aa6-41e4-bff2-2a64d228233d", 5225 - "edge_type": "leads_to", 5226 - "weight": 1.0, 5227 - "rationale": "Implementation completed successfully", 5228 - "created_at": "2025-12-23T18:10:22.329706800-05:00" 5229 - }, 5230 - { 5231 - "id": 80, 5232 - "from_node_id": 81, 5233 - "to_node_id": 82, 5234 - "from_change_id": "aad16dbf-1aa6-41e4-bff2-2a64d228233d", 5235 - "to_change_id": "af29c2c8-9bf6-4b3d-8f48-34e94074ce7f", 5236 - "edge_type": "leads_to", 5237 - "weight": 1.0, 5238 - "rationale": "Changes committed", 5239 - "created_at": "2025-12-23T18:11:43.633307200-05:00" 5240 - }, 5241 - { 5242 - "id": 81, 5243 - "from_node_id": 49, 5244 - "to_node_id": 83, 5245 - "from_change_id": "31331aa1-1938-479f-8527-65346d2fa764", 5246 - "to_change_id": "582f617e-c13a-4643-88ad-a7ed9941c3e7", 5247 - "edge_type": "leads_to", 5248 - "weight": 1.0, 5249 - "rationale": "Sub-goal: Optimization #10 from master optimization plan", 5250 - "created_at": "2025-12-23T18:46:53.588178100-05:00" 5251 - }, 5252 - { 5253 - "id": 82, 5254 - "from_node_id": 83, 5255 - "to_node_id": 84, 5256 - "from_change_id": "582f617e-c13a-4643-88ad-a7ed9941c3e7", 5257 - "to_change_id": "62c63a96-f0da-4cee-8dfb-e691ebd01fef", 5258 - "edge_type": "leads_to", 5259 - "weight": 1.0, 5260 - "rationale": "First action for goal #83", 5261 - "created_at": "2025-12-23T18:46:58.917436700-05:00" 5262 - }, 5263 - { 5264 - "id": 83, 5265 - "from_node_id": 84, 5266 - "to_node_id": 85, 5267 - "from_change_id": "62c63a96-f0da-4cee-8dfb-e691ebd01fef", 5268 - "to_change_id": "d07dc9e0-4a15-4b6a-837f-af7522a658d3", 5269 - "edge_type": "leads_to", 5270 - "weight": 1.0, 5271 - "rationale": "Observation from reading code", 5272 - "created_at": "2025-12-23T18:47:21.458833600-05:00" 5273 - }, 5274 - { 5275 - "id": 84, 5276 - "from_node_id": 85, 5277 - "to_node_id": 86, 5278 - "from_change_id": "d07dc9e0-4a15-4b6a-837f-af7522a658d3", 5279 - "to_change_id": "9c4b383c-b743-4f6b-a551-8e568a68b854", 5280 - "edge_type": "leads_to", 5281 - "weight": 1.0, 5282 - "rationale": "Next action", 5283 - "created_at": "2025-12-23T18:47:29.514781600-05:00" 5284 - }, 5285 - { 5286 - "id": 85, 5287 - "from_node_id": 86, 5288 - "to_node_id": 87, 5289 - "from_change_id": "9c4b383c-b743-4f6b-a551-8e568a68b854", 5290 - "to_change_id": "557b339e-2aeb-4eef-b8f5-6ce93bdf7f61", 5291 - "edge_type": "leads_to", 5292 - "weight": 1.0, 5293 - "rationale": "Next action", 5294 - "created_at": "2025-12-23T18:52:27.412511700-05:00" 5295 - }, 5296 - { 5297 - "id": 86, 5298 - "from_node_id": 87, 5299 - "to_node_id": 88, 5300 - "from_change_id": "557b339e-2aeb-4eef-b8f5-6ce93bdf7f61", 5301 - "to_change_id": "39f0e1dd-dae2-48d8-926d-491b05419b3d", 5302 - "edge_type": "leads_to", 5303 - "weight": 1.0, 5304 - "rationale": "Next action", 5305 - "created_at": "2025-12-23T18:53:22.228797200-05:00" 5306 - }, 5307 - { 5308 - "id": 87, 5309 - "from_node_id": 88, 5310 - "to_node_id": 89, 5311 - "from_change_id": "39f0e1dd-dae2-48d8-926d-491b05419b3d", 5312 - "to_change_id": "a2e92cda-43cb-4659-a8be-512c2bf2feb4", 5313 - "edge_type": "leads_to", 5314 - "weight": 1.0, 5315 - "rationale": "Implementation completed successfully", 5316 - "created_at": "2025-12-23T19:05:08.062180500-05:00" 5317 - }, 5318 - { 5319 - "id": 88, 5320 - "from_node_id": 89, 5321 - "to_node_id": 90, 5322 - "from_change_id": "a2e92cda-43cb-4659-a8be-512c2bf2feb4", 5323 - "to_change_id": "52b07eae-66e2-4bfd-8bdc-dcf940b50095", 5324 - "edge_type": "leads_to", 5325 - "weight": 1.0, 5326 - "rationale": "Changes committed", 5327 - "created_at": "2025-12-23T19:06:59.883305200-05:00" 5328 - }, 5329 - { 5330 - "id": 89, 5331 - "from_node_id": 49, 5332 - "to_node_id": 91, 5333 - "from_change_id": "31331aa1-1938-479f-8527-65346d2fa764", 5334 - "to_change_id": "a981ce23-a49d-46fb-8291-ce540551bb1b", 5335 - "edge_type": "leads_to", 5336 - "weight": 1.0, 5337 - "rationale": "Sub-goal: Optimization #11 from master optimization plan", 5338 - "created_at": "2025-12-23T19:08:54.585384200-05:00" 5339 - }, 5340 - { 5341 - "id": 90, 5342 - "from_node_id": 91, 5343 - "to_node_id": 92, 5344 - "from_change_id": "a981ce23-a49d-46fb-8291-ce540551bb1b", 5345 - "to_change_id": "28492b66-8405-4c7e-a80a-c874e2bdb391", 5346 - "edge_type": "leads_to", 5347 - "weight": 1.0, 5348 - "rationale": "First action for goal #91", 5349 - "created_at": "2025-12-23T19:08:57.333090500-05:00" 5350 - }, 5351 - { 5352 - "id": 91, 5353 - "from_node_id": 92, 5354 - "to_node_id": 93, 5355 - "from_change_id": "28492b66-8405-4c7e-a80a-c874e2bdb391", 5356 - "to_change_id": "145cfde7-8444-4ef1-b8e0-0659de30a5b2", 5357 - "edge_type": "leads_to", 5358 - "weight": 1.0, 5359 - "rationale": "Observation from reading code", 5360 - "created_at": "2025-12-23T19:09:16.211050400-05:00" 5361 - }, 5362 - { 5363 - "id": 92, 5364 - "from_node_id": 93, 5365 - "to_node_id": 94, 5366 - "from_change_id": "145cfde7-8444-4ef1-b8e0-0659de30a5b2", 5367 - "to_change_id": "ade1253d-4dcb-4a30-bf41-d8c8cbfb99b9", 5368 - "edge_type": "leads_to", 5369 - "weight": 1.0, 5370 - "rationale": "Implementation action", 5371 - "created_at": "2025-12-23T19:09:32.041743-05:00" 5372 - }, 5373 - { 5374 - "id": 93, 5375 - "from_node_id": 94, 5376 - "to_node_id": 95, 5377 - "from_change_id": "ade1253d-4dcb-4a30-bf41-d8c8cbfb99b9", 5378 - "to_change_id": "4471c934-81e1-413b-83ce-0860b5f629e0", 5379 - "edge_type": "leads_to", 5380 - "weight": 1.0, 5381 - "rationale": "Next action", 5382 - "created_at": "2025-12-23T19:09:50.309162800-05:00" 5383 - }, 5384 - { 5385 - "id": 94, 5386 - "from_node_id": 95, 5387 - "to_node_id": 96, 5388 - "from_change_id": "4471c934-81e1-413b-83ce-0860b5f629e0", 5389 - "to_change_id": "214a1dab-def7-4e0d-9c9f-333713753b4c", 5390 - "edge_type": "leads_to", 5391 - "weight": 1.0, 5392 - "rationale": "Implementation completed successfully", 5393 - "created_at": "2025-12-23T19:11:28.086930400-05:00" 5394 - }, 5395 - { 5396 - "id": 95, 5397 - "from_node_id": 96, 5398 - "to_node_id": 97, 5399 - "from_change_id": "214a1dab-def7-4e0d-9c9f-333713753b4c", 5400 - "to_change_id": "85f0bd33-5e62-4889-b14d-c365b2c389c3", 5401 - "edge_type": "leads_to", 5402 - "weight": 1.0, 5403 - "rationale": "Changes committed", 5404 - "created_at": "2025-12-23T19:12:06.970585500-05:00" 5405 - }, 5406 - { 5407 - "id": 96, 5408 - "from_node_id": 91, 5409 - "to_node_id": 98, 5410 - "from_change_id": "a981ce23-a49d-46fb-8291-ce540551bb1b", 5411 - "to_change_id": "c7dea418-336e-4696-84f2-d7cb09edd3f6", 5412 - "edge_type": "leads_to", 5413 - "weight": 1.0, 5414 - "rationale": "Analysis action before implementing #12", 5415 - "created_at": "2025-12-23T19:15:14.513450600-05:00" 5416 - }, 5417 - { 5418 - "id": 97, 5419 - "from_node_id": 98, 5420 - "to_node_id": 99, 5421 - "from_change_id": "c7dea418-336e-4696-84f2-d7cb09edd3f6", 5422 - "to_change_id": "7839b10b-c5e0-4179-8590-7fe7b2ef132d", 5423 - "edge_type": "leads_to", 5424 - "weight": 1.0, 5425 - "rationale": "Analysis complete", 5426 - "created_at": "2025-12-23T19:15:56.395244800-05:00" 5427 - }, 5428 - { 5429 - "id": 98, 5430 - "from_node_id": 99, 5431 - "to_node_id": 100, 5432 - "from_change_id": "7839b10b-c5e0-4179-8590-7fe7b2ef132d", 5433 - "to_change_id": "9aa09f86-4411-4dac-add2-c19171372d63", 5434 - "edge_type": "leads_to", 5435 - "weight": 1.0, 5436 - "rationale": "Next step: get rate limit info", 5437 - "created_at": "2025-12-23T19:20:30.249866900-05:00" 5438 - }, 5439 - { 5440 - "id": 99, 5441 - "from_node_id": 100, 5442 - "to_node_id": 101, 5443 - "from_change_id": "9aa09f86-4411-4dac-add2-c19171372d63", 5444 - "to_change_id": "e79276e8-80f0-4f18-acc1-b630182fac97", 5445 - "edge_type": "leads_to", 5446 - "weight": 1.0, 5447 - "rationale": "Received rate limit info", 5448 - "created_at": "2025-12-23T19:23:57.620431-05:00" 5449 - }, 5450 - { 5451 - "id": 100, 5452 - "from_node_id": 101, 5453 - "to_node_id": 102, 5454 - "from_change_id": "e79276e8-80f0-4f18-acc1-b630182fac97", 5455 - "to_change_id": "970c1d5d-c6c2-417e-a3e3-6ccc198e07f7", 5456 - "edge_type": "leads_to", 5457 - "weight": 1.0, 5458 - "rationale": "Decision on specific limits", 5459 - "created_at": "2025-12-23T19:24:16.768379400-05:00" 5460 - }, 5461 - { 5462 - "id": 101, 5463 - "from_node_id": 102, 5464 - "to_node_id": 103, 5465 - "from_change_id": "970c1d5d-c6c2-417e-a3e3-6ccc198e07f7", 5466 - "to_change_id": "3f0e407c-7691-4d3c-8b7b-da2e4697d29c", 5467 - "edge_type": "leads_to", 5468 - "weight": 1.0, 5469 - "rationale": "Conservative configuration selected", 5470 - "created_at": "2025-12-23T19:27:40.578124800-05:00" 5471 - }, 5472 - { 5473 - "id": 102, 5474 - "from_node_id": 103, 5475 - "to_node_id": 104, 5476 - "from_change_id": "3f0e407c-7691-4d3c-8b7b-da2e4697d29c", 5477 - "to_change_id": "5f61a35e-4982-40a6-8b53-ab06640cc36b", 5478 - "edge_type": "leads_to", 5479 - "weight": 1.0, 5480 - "rationale": "Implementation action", 5481 - "created_at": "2025-12-23T19:27:46.790822-05:00" 5482 - }, 5483 - { 5484 - "id": 103, 5485 - "from_node_id": 104, 5486 - "to_node_id": 105, 5487 - "from_change_id": "5f61a35e-4982-40a6-8b53-ab06640cc36b", 5488 - "to_change_id": "af86b0ed-efa4-4070-a8f9-bd1a46e3434b", 5489 - "edge_type": "leads_to", 5490 - "weight": 1.0, 5491 - "rationale": "Implementation approach decided", 5492 - "created_at": "2025-12-23T19:28:24.732815700-05:00" 5493 - }, 5494 - { 5495 - "id": 104, 5496 - "from_node_id": 105, 5497 - "to_node_id": 106, 5498 - "from_change_id": "af86b0ed-efa4-4070-a8f9-bd1a46e3434b", 5499 - "to_change_id": "037f0c9c-a1bb-406f-9a28-f48c562bf064", 5500 - "edge_type": "leads_to", 5501 - "weight": 1.0, 5502 - "rationale": "Implementation completed successfully", 5503 - "created_at": "2025-12-23T19:33:45.901151800-05:00" 5504 - }, 5505 - { 5506 - "id": 105, 5507 - "from_node_id": 106, 5508 - "to_node_id": 107, 5509 - "from_change_id": "037f0c9c-a1bb-406f-9a28-f48c562bf064", 5510 - "to_change_id": "44aff04f-b6c9-46c6-a8a7-1cdb99d4124a", 5511 - "edge_type": "leads_to", 5512 - "weight": 1.0, 5513 - "rationale": "Changes committed", 5514 - "created_at": "2025-12-23T19:34:38.927360100-05:00" 5515 - }, 5516 - { 5517 - "id": 106, 5518 - "from_node_id": 107, 5519 - "to_node_id": 108, 5520 - "from_change_id": "44aff04f-b6c9-46c6-a8a7-1cdb99d4124a", 5521 - "to_change_id": "aba3305e-74ef-4c32-b534-68fcc0527202", 5522 - "edge_type": "leads_to", 5523 - "weight": 1.0, 5524 - "rationale": "Final session summary", 5525 - "created_at": "2025-12-23T19:34:52.313760500-05:00" 5526 - }, 5527 - { 5528 - "id": 107, 5529 - "from_node_id": 49, 5530 - "to_node_id": 109, 5531 - "from_change_id": "31331aa1-1938-479f-8527-65346d2fa764", 5532 - "to_change_id": "a18b89e9-eb13-428c-939b-4db60fe1a496", 5533 - "edge_type": "leads_to", 5534 - "weight": 1.0, 5535 - "rationale": "Sub-goal: Optimization #12 from master optimization plan", 5536 - "created_at": "2025-12-23T19:41:48.331607800-05:00" 5537 - }, 5538 - { 5539 - "id": 108, 5540 - "from_node_id": 109, 5541 - "to_node_id": 98, 5542 - "from_change_id": "a18b89e9-eb13-428c-939b-4db60fe1a496", 5543 - "to_change_id": "c7dea418-336e-4696-84f2-d7cb09edd3f6", 5544 - "edge_type": "leads_to", 5545 - "weight": 1.0, 5546 - "rationale": "First action for goal #109", 5547 - "created_at": "2025-12-23T19:41:50.150904500-05:00" 5548 - }, 5549 - { 5550 - "id": 109, 5551 - "from_node_id": 110, 5552 - "to_node_id": 111, 5553 - "from_change_id": "22b9c3db-9f95-45d7-a3ed-bdfac54677db", 5554 - "to_change_id": "c817c7d7-69cb-4fa3-934e-9ff210027ebf", 5555 - "edge_type": "leads_to", 5556 - "weight": 1.0, 5557 - "rationale": "First action for cleanup goal", 5558 - "created_at": "2025-12-23T20:04:57.796506700-05:00" 5559 - }, 5560 - { 5561 - "id": 110, 5562 - "from_node_id": 111, 5563 - "to_node_id": 112, 5564 - "from_change_id": "c817c7d7-69cb-4fa3-934e-9ff210027ebf", 5565 - "to_change_id": "4b680ad7-6517-4e7c-8722-ffe6d5c70d4d", 5566 - "edge_type": "leads_to", 5567 - "weight": 1.0, 5568 - "rationale": "Observation from searching for backward compat code", 5569 - "created_at": "2025-12-23T20:07:37.703932800-05:00" 5570 - }, 5571 - { 5572 - "id": 111, 5573 - "from_node_id": 112, 5574 - "to_node_id": 113, 5575 - "from_change_id": "4b680ad7-6517-4e7c-8722-ffe6d5c70d4d", 5576 - "to_change_id": "437de2d2-6de6-4a4c-a306-d6491e661f97", 5577 - "edge_type": "leads_to", 5578 - "weight": 1.0, 5579 - "rationale": "Decision on how to handle deprecated field", 5580 - "created_at": "2025-12-23T20:08:39.647918700-05:00" 5581 - }, 5582 - { 5583 - "id": 112, 5584 - "from_node_id": 113, 5585 - "to_node_id": 114, 5586 - "from_change_id": "437de2d2-6de6-4a4c-a306-d6491e661f97", 5587 - "to_change_id": "af90cd04-bdd3-4a33-9c91-6233c4487306", 5588 - "edge_type": "leads_to", 5589 - "weight": 1.0, 5590 - "rationale": "Decision outcome", 5591 - "created_at": "2025-12-23T20:08:39.735671200-05:00" 5592 - }, 5593 - { 5594 - "id": 113, 5595 - "from_node_id": 114, 5596 - "to_node_id": 115, 5597 - "from_change_id": "af90cd04-bdd3-4a33-9c91-6233c4487306", 5598 - "to_change_id": "36762e5f-cb24-4e86-9b8d-24182ae53671", 5599 - "edge_type": "leads_to", 5600 - "weight": 1.0, 5601 - "rationale": "Action based on decision", 5602 - "created_at": "2025-12-23T20:08:49.957587300-05:00" 5603 - }, 5604 - { 5605 - "id": 114, 5606 - "from_node_id": 115, 5607 - "to_node_id": 116, 5608 - "from_change_id": "36762e5f-cb24-4e86-9b8d-24182ae53671", 5609 - "to_change_id": "0e63dec2-b38f-40cb-af00-4b5da44d6212", 5610 - "edge_type": "leads_to", 5611 - "weight": 1.0, 5612 - "rationale": "Observation after removing deprecated field", 5613 - "created_at": "2025-12-23T20:11:00.067479400-05:00" 5614 - }, 5615 - { 5616 - "id": 115, 5617 - "from_node_id": 116, 5618 - "to_node_id": 118, 5619 - "from_change_id": "0e63dec2-b38f-40cb-af00-4b5da44d6212", 5620 - "to_change_id": "e16cb229-81a4-4215-a35f-48f33d217290", 5621 - "edge_type": "leads_to", 5622 - "weight": 1.0, 5623 - "rationale": "Cleanup outcome", 5624 - "created_at": "2025-12-23T20:13:17.159621900-05:00" 5625 - }, 5626 - { 5627 - "id": 116, 5628 - "from_node_id": 118, 5629 - "to_node_id": 119, 5630 - "from_change_id": "e16cb229-81a4-4215-a35f-48f33d217290", 5631 - "to_change_id": "462bb6d0-8ce9-4305-a11e-c34b9fe6e946", 5632 - "edge_type": "leads_to", 5633 - "weight": 1.0, 5634 - "rationale": "Additional cleanup action", 5635 - "created_at": "2025-12-23T20:20:47.683039100-05:00" 5636 - }, 5637 - { 5638 - "id": 117, 5639 - "from_node_id": 119, 5640 - "to_node_id": 120, 5641 - "from_change_id": "462bb6d0-8ce9-4305-a11e-c34b9fe6e946", 5642 - "to_change_id": "d982f0be-e0bd-43db-bb6e-96129ca4561d", 5643 - "edge_type": "leads_to", 5644 - "weight": 1.0, 5645 - "rationale": "Outcome of removing backward compat hook", 5646 - "created_at": "2025-12-23T20:20:49.325863400-05:00" 5647 - }, 5648 - { 5649 - "id": 118, 5650 - "from_node_id": 120, 5651 - "to_node_id": 121, 5652 - "from_change_id": "d982f0be-e0bd-43db-bb6e-96129ca4561d", 5653 - "to_change_id": "226c05bc-6da6-4343-9204-0dfb819ed57b", 5654 - "edge_type": "leads_to", 5655 - "weight": 1.0, 5656 - "rationale": "Final observation for cleanup session", 5657 - "created_at": "2025-12-23T20:22:32.411718300-05:00" 5658 - }, 5659 - { 5660 - "id": 119, 5661 - "from_node_id": 122, 5662 - "to_node_id": 123, 5663 - "from_change_id": "0357c76e-2c91-46e7-941e-4466d520b8c2", 5664 - "to_change_id": "b699928b-e0bd-45e0-8dcd-b5ab3b8945c4", 5665 - "edge_type": "leads_to", 5666 - "weight": 1.0, 5667 - "rationale": "Understanding what changed in 151f5336", 5668 - "created_at": "2025-12-23T20:37:02.757223400-05:00" 5669 - }, 5670 - { 5671 - "id": 120, 5672 - "from_node_id": 122, 5673 - "to_node_id": 124, 5674 - "from_change_id": "0357c76e-2c91-46e7-941e-4466d520b8c2", 5675 - "to_change_id": "5852a83b-88bb-4938-ae0b-c2791a7bdeba", 5676 - "edge_type": "leads_to", 5677 - "weight": 1.0, 5678 - "rationale": "Analysis of current implementation issues", 5679 - "created_at": "2025-12-23T20:38:31.895716500-05:00" 5680 - }, 5681 - { 5682 - "id": 121, 5683 - "from_node_id": 124, 5684 - "to_node_id": 125, 5685 - "from_change_id": "5852a83b-88bb-4938-ae0b-c2791a7bdeba", 5686 - "to_change_id": "f5475891-0269-4c90-9968-baab1db0a583", 5687 - "edge_type": "leads_to", 5688 - "weight": 1.0, 5689 - "rationale": "First fix to implement", 5690 - "created_at": "2025-12-23T20:38:43.158707100-05:00" 5691 - }, 5692 - { 5693 - "id": 122, 5694 - "from_node_id": 125, 5695 - "to_node_id": 126, 5696 - "from_change_id": "f5475891-0269-4c90-9968-baab1db0a583", 5697 - "to_change_id": "43dee7b4-082e-42dd-b245-4b6dec800458", 5698 - "edge_type": "leads_to", 5699 - "weight": 1.0, 5700 - "rationale": "Implementation successful", 5701 - "created_at": "2025-12-23T20:40:31.302734-05:00" 5702 - }, 5703 - { 5704 - "id": 123, 5705 - "from_node_id": 124, 5706 - "to_node_id": 127, 5707 - "from_change_id": "5852a83b-88bb-4938-ae0b-c2791a7bdeba", 5708 - "to_change_id": "995ffe5d-4614-4f5f-8afc-04754bd54efc", 5709 - "edge_type": "leads_to", 5710 - "weight": 1.0, 5711 - "rationale": "Next fix to implement", 5712 - "created_at": "2025-12-23T20:40:34.451048200-05:00" 5713 - }, 5714 - { 5715 - "id": 124, 5716 - "from_node_id": 127, 5717 - "to_node_id": 128, 5718 - "from_change_id": "995ffe5d-4614-4f5f-8afc-04754bd54efc", 5719 - "to_change_id": "94d4ca47-69ed-4cbd-91b8-652936b01b98", 5720 - "edge_type": "leads_to", 5721 - "weight": 1.0, 5722 - "rationale": "Implementation successful", 5723 - "created_at": "2025-12-23T20:41:07.800487200-05:00" 5724 - }, 5725 - { 5726 - "id": 125, 5727 - "from_node_id": 124, 5728 - "to_node_id": 129, 5729 - "from_change_id": "5852a83b-88bb-4938-ae0b-c2791a7bdeba", 5730 - "to_change_id": "12e7e24a-6730-4d3b-9a0f-220e35aacb7f", 5731 - "edge_type": "leads_to", 5732 - "weight": 1.0, 5733 - "rationale": "Next fix to implement", 5734 - "created_at": "2025-12-23T20:41:10.753085200-05:00" 5735 - }, 5736 - { 5737 - "id": 126, 5738 - "from_node_id": 129, 5739 - "to_node_id": 130, 5740 - "from_change_id": "12e7e24a-6730-4d3b-9a0f-220e35aacb7f", 5741 - "to_change_id": "a83f4dba-ec0c-41c6-b51c-a8347d600f3c", 5742 - "edge_type": "leads_to", 5743 - "weight": 1.0, 5744 - "rationale": "Implementation successful", 5745 - "created_at": "2025-12-23T20:41:59.353654-05:00" 5746 - }, 5747 - { 5748 - "id": 127, 5749 - "from_node_id": 124, 5750 - "to_node_id": 131, 5751 - "from_change_id": "5852a83b-88bb-4938-ae0b-c2791a7bdeba", 5752 - "to_change_id": "7d0d2907-6dfc-4160-9d5a-1114fca7924a", 5753 - "edge_type": "leads_to", 5754 - "weight": 1.0, 5755 - "rationale": "Final fix to analyze", 5756 - "created_at": "2025-12-23T20:42:02.433228600-05:00" 5757 - }, 5758 - { 5759 - "id": 128, 5760 - "from_node_id": 131, 5761 - "to_node_id": 132, 5762 - "from_change_id": "7d0d2907-6dfc-4160-9d5a-1114fca7924a", 5763 - "to_change_id": "b66ab07d-5c6c-443b-a6bb-1738f45911f8", 5764 - "edge_type": "leads_to", 5765 - "weight": 1.0, 5766 - "rationale": "Analysis complete, presenting options", 5767 - "created_at": "2025-12-23T20:42:12.649645800-05:00" 5768 - }, 5769 - { 5770 - "id": 129, 5771 - "from_node_id": 132, 5772 - "to_node_id": 133, 5773 - "from_change_id": "b66ab07d-5c6c-443b-a6bb-1738f45911f8", 5774 - "to_change_id": "88f7884c-cde3-4f41-aa78-10065619517f", 5775 - "edge_type": "leads_to", 5776 - "weight": 1.0, 5777 - "rationale": "User decision", 5778 - "created_at": "2025-12-23T20:46:18.786053200-05:00" 5779 - }, 5780 - { 5781 - "id": 130, 5782 - "from_node_id": 133, 5783 - "to_node_id": 134, 5784 - "from_change_id": "88f7884c-cde3-4f41-aa78-10065619517f", 5785 - "to_change_id": "32d6f48c-48cb-41cc-8b0e-fe270dd070e2", 5786 - "edge_type": "leads_to", 5787 - "weight": 1.0, 5788 - "rationale": "Implementation based on decision", 5789 - "created_at": "2025-12-23T20:46:22.116041400-05:00" 5790 - }, 5791 - { 5792 - "id": 131, 5793 - "from_node_id": 134, 5794 - "to_node_id": 135, 5795 - "from_change_id": "32d6f48c-48cb-41cc-8b0e-fe270dd070e2", 5796 - "to_change_id": "1c3644b9-0c3a-499b-b34a-79aad9682702", 5797 - "edge_type": "leads_to", 5798 - "weight": 1.0, 5799 - "rationale": "Implementation successful", 5800 - "created_at": "2025-12-23T20:53:32.109691600-05:00" 5801 - }, 5802 - { 5803 - "id": 132, 5804 - "from_node_id": 122, 5805 - "to_node_id": 136, 5806 - "from_change_id": "0357c76e-2c91-46e7-941e-4466d520b8c2", 5807 - "to_change_id": "442a6396-4f7f-4f05-9d19-762d4b9f9896", 5808 - "edge_type": "leads_to", 5809 - "weight": 1.0, 5810 - "rationale": "Documentation update", 5811 - "created_at": "2025-12-23T20:57:25.902405300-05:00" 5812 - }, 5813 - { 5814 - "id": 133, 5815 - "from_node_id": 126, 5816 - "to_node_id": 137, 5817 - "from_change_id": "43dee7b4-082e-42dd-b245-4b6dec800458", 5818 - "to_change_id": "11e99520-1e49-4fce-be63-7f3af3523f6f", 5819 - "edge_type": "leads_to", 5820 - "weight": 1.0, 5821 - "rationale": "Committed to git", 5822 - "created_at": "2025-12-23T20:58:19.430183700-05:00" 5823 - }, 5824 - { 5825 - "id": 134, 5826 - "from_node_id": 128, 5827 - "to_node_id": 138, 5828 - "from_change_id": "94d4ca47-69ed-4cbd-91b8-652936b01b98", 5829 - "to_change_id": "f3687af3-fa58-424f-89e3-9e64d18322c9", 5830 - "edge_type": "leads_to", 5831 - "weight": 1.0, 5832 - "rationale": "Committed to git", 5833 - "created_at": "2025-12-23T21:10:29.304486700-05:00" 5834 - }, 5835 - { 5836 - "id": 135, 5837 - "from_node_id": 130, 5838 - "to_node_id": 139, 5839 - "from_change_id": "a83f4dba-ec0c-41c6-b51c-a8347d600f3c", 5840 - "to_change_id": "79bc3a4c-d528-451b-8706-66e8aa7f50ff", 5841 - "edge_type": "leads_to", 5842 - "weight": 1.0, 5843 - "rationale": "Committed to git", 5844 - "created_at": "2025-12-23T21:11:01.683361600-05:00" 5845 - }, 5846 - { 5847 - "id": 136, 5848 - "from_node_id": 135, 5849 - "to_node_id": 140, 5850 - "from_change_id": "1c3644b9-0c3a-499b-b34a-79aad9682702", 5851 - "to_change_id": "45efeea7-9759-405c-9ab4-568cfb7f083c", 5852 - "edge_type": "leads_to", 5853 - "weight": 1.0, 5854 - "rationale": "Committed to git", 5855 - "created_at": "2025-12-23T21:11:22.724479-05:00" 5856 - }, 5857 - { 5858 - "id": 137, 5859 - "from_node_id": 122, 5860 - "to_node_id": 141, 5861 - "from_change_id": "0357c76e-2c91-46e7-941e-4466d520b8c2", 5862 - "to_change_id": "954f8b75-05eb-44de-afd6-89c349587b2e", 5863 - "edge_type": "leads_to", 5864 - "weight": 1.0, 5865 - "rationale": "Session complete", 5866 - "created_at": "2025-12-23T21:11:47.686638-05:00" 5867 - }, 5868 - { 5869 - "id": 138, 5870 - "from_node_id": 128, 5871 - "to_node_id": 142, 5872 - "from_change_id": "94d4ca47-69ed-4cbd-91b8-652936b01b98", 5873 - "to_change_id": "6b5a1e7d-27d5-4a7a-9eba-8c0495987ba6", 5874 - "edge_type": "leads_to", 5875 - "weight": 1.0, 5876 - "rationale": "Previous dynamic size fix didn't solve spacing issue, need fixed gap approach", 5877 - "created_at": "2025-12-23T21:22:46.652776-05:00" 5878 - }, 5879 - { 5880 - "id": 139, 5881 - "from_node_id": 142, 5882 - "to_node_id": 143, 5883 - "from_change_id": "6b5a1e7d-27d5-4a7a-9eba-8c0495987ba6", 5884 - "to_change_id": "b6a1f3ef-068a-4ae7-a3a4-130fe830fe4c", 5885 - "edge_type": "leads_to", 5886 - "weight": 1.0, 5887 - "rationale": "Analysis of current implementation", 5888 - "created_at": "2025-12-23T21:23:24.547472-05:00" 5889 - }, 5890 - { 5891 - "id": 140, 5892 - "from_node_id": 143, 5893 - "to_node_id": 144, 5894 - "from_change_id": "b6a1f3ef-068a-4ae7-a3a4-130fe830fe4c", 5895 - "to_change_id": "37bbbbd0-0fdd-4ce3-aa86-dd88d45513fc", 5896 - "edge_type": "leads_to", 5897 - "weight": 1.0, 5898 - "rationale": "Implementation complete", 5899 - "created_at": "2025-12-23T21:24:19.701031200-05:00" 5900 - }, 5901 - { 5902 - "id": 141, 5903 - "from_node_id": 122, 5904 - "to_node_id": 142, 5905 - "from_change_id": "0357c76e-2c91-46e7-941e-4466d520b8c2", 5906 - "to_change_id": "6b5a1e7d-27d5-4a7a-9eba-8c0495987ba6", 5907 - "edge_type": "leads_to", 5908 - "weight": 1.0, 5909 - "rationale": "Additional bug fix - card spacing issue", 5910 - "created_at": "2025-12-23T21:24:27.116742400-05:00" 5911 - }, 5912 - { 5913 - "id": 142, 5914 - "from_node_id": 142, 5915 - "to_node_id": 145, 5916 - "from_change_id": "6b5a1e7d-27d5-4a7a-9eba-8c0495987ba6", 5917 - "to_change_id": "e8b327a0-372f-478b-a33a-2e1ce554bed2", 5918 - "edge_type": "leads_to", 5919 - "weight": 1.0, 5920 - "rationale": "Related alignment issue in results cards", 5921 - "created_at": "2025-12-23T21:46:18.418360700-05:00" 5922 - }, 5923 - { 5924 - "id": 143, 5925 - "from_node_id": 145, 5926 - "to_node_id": 146, 5927 - "from_change_id": "e8b327a0-372f-478b-a33a-2e1ce554bed2", 5928 - "to_change_id": "9eae410e-0b10-442f-8291-6f54b9e2f900", 5929 - "edge_type": "leads_to", 5930 - "weight": 1.0, 5931 - "rationale": "Analysis complete", 5932 - "created_at": "2025-12-23T21:48:59.917425500-05:00" 5933 - }, 5934 - { 5935 - "id": 144, 5936 - "from_node_id": 146, 5937 - "to_node_id": 147, 5938 - "from_change_id": "9eae410e-0b10-442f-8291-6f54b9e2f900", 5939 - "to_change_id": "31952cd1-2b20-4df9-b99e-2a8fecd45845", 5940 - "edge_type": "leads_to", 5941 - "weight": 1.0, 5942 - "rationale": "Fix implemented", 5943 - "created_at": "2025-12-23T21:50:53.429967100-05:00" 5944 - }, 5945 - { 5946 - "id": 145, 5947 - "from_node_id": 147, 5948 - "to_node_id": 148, 5949 - "from_change_id": "31952cd1-2b20-4df9-b99e-2a8fecd45845", 5950 - "to_change_id": "adec9fe9-7462-4734-9b87-ab30558da687", 5951 - "edge_type": "leads_to", 5952 - "weight": 1.0, 5953 - "rationale": "Applying consistent spacing across components", 5954 - "created_at": "2025-12-23T21:59:30.811465900-05:00" 5955 - }, 5956 - { 5957 - "id": 146, 5958 - "from_node_id": 148, 5959 - "to_node_id": 149, 5960 - "from_change_id": "adec9fe9-7462-4734-9b87-ab30558da687", 5961 - "to_change_id": "6b36b07d-75af-49a7-a095-7ff93ef9f4db", 5962 - "edge_type": "leads_to", 5963 - "weight": 1.0, 5964 - "rationale": "Implementation complete", 5965 - "created_at": "2025-12-23T22:02:20.157839200-05:00" 5966 - }, 5967 - { 5968 - "id": 147, 5969 - "from_node_id": 149, 5970 - "to_node_id": 150, 5971 - "from_change_id": "6b36b07d-75af-49a7-a095-7ff93ef9f4db", 5972 - "to_change_id": "a11f624c-93ae-49e7-81e1-d8d68ac9eca8", 5973 - "edge_type": "leads_to", 5974 - "weight": 1.0, 5975 - "rationale": "Previous fix incorrect - need structural change", 5976 - "created_at": "2025-12-23T22:06:41.194038-05:00" 5977 - }, 5978 - { 5979 - "id": 148, 5980 - "from_node_id": 150, 5981 - "to_node_id": 151, 5982 - "from_change_id": "a11f624c-93ae-49e7-81e1-d8d68ac9eca8", 5983 - "to_change_id": "87d57666-91a4-45c9-a3f1-628dcc395db3", 5984 - "edge_type": "leads_to", 5985 - "weight": 1.0, 5986 - "rationale": "Restructure complete", 5987 - "created_at": "2025-12-23T22:08:30.246959100-05:00" 5988 - }, 5989 - { 5990 - "id": 149, 5991 - "from_node_id": 151, 5992 - "to_node_id": 152, 5993 - "from_change_id": "87d57666-91a4-45c9-a3f1-628dcc395db3", 5994 - "to_change_id": "eb1b6810-9528-4e4e-b35e-43a02ccf8f3c", 5995 - "edge_type": "leads_to", 5996 - "weight": 1.0, 5997 - "rationale": "Exploring further abstraction", 5998 - "created_at": "2025-12-23T22:28:46.077917-05:00" 5999 - }, 6000 - { 6001 - "id": 150, 6002 - "from_node_id": 152, 6003 - "to_node_id": 153, 6004 - "from_change_id": "eb1b6810-9528-4e4e-b35e-43a02ccf8f3c", 6005 - "to_change_id": "0099b286-7090-459e-8fc6-1abccf3488bb", 6006 - "edge_type": "leads_to", 6007 - "weight": 1.0, 6008 - "rationale": "Implementation approved", 6009 - "created_at": "2025-12-24T00:20:18.402987400-05:00" 6010 - }, 6011 - { 6012 - "id": 151, 6013 - "from_node_id": 153, 6014 - "to_node_id": 154, 6015 - "from_change_id": "0099b286-7090-459e-8fc6-1abccf3488bb", 6016 - "to_change_id": "41384be8-f128-4424-9419-2626fc7ac8f4", 6017 - "edge_type": "leads_to", 6018 - "weight": 1.0, 6019 - "rationale": "Refactor complete", 6020 - "created_at": "2025-12-24T00:22:12.798856800-05:00" 6021 - }, 6022 - { 6023 - "id": 152, 6024 - "from_node_id": 110, 6025 - "to_node_id": 122, 6026 - "from_change_id": "22b9c3db-9f95-45d7-a3ed-bdfac54677db", 6027 - "to_change_id": "0357c76e-2c91-46e7-941e-4466d520b8c2", 6028 - "edge_type": "leads_to", 6029 - "weight": 1.0, 6030 - "rationale": "UX bug fixes discovered during cleanup/testing phase", 6031 - "created_at": "2025-12-24T00:46:02.097576300-05:00" 6032 - }, 6033 - { 6034 - "id": 153, 6035 - "from_node_id": 155, 6036 - "to_node_id": 156, 6037 - "from_change_id": "76e2700c-0324-4563-81d1-b31dc3e85460", 6038 - "to_change_id": "28f2b394-61e7-4840-9c33-838a1bcf0e04", 6039 - "edge_type": "leads_to", 6040 - "weight": 1.0, 6041 - "rationale": "Initial exploration", 6042 - "created_at": "2025-12-24T00:59:34.910795600-05:00" 6043 - }, 6044 - { 6045 - "id": 154, 6046 - "from_node_id": 155, 6047 - "to_node_id": 157, 6048 - "from_change_id": "76e2700c-0324-4563-81d1-b31dc3e85460", 6049 - "to_change_id": "3b149b2b-0e2d-4e38-a2ed-858836cb2e24", 6050 - "edge_type": "leads_to", 6051 - "weight": 1.0, 6052 - "rationale": "Pattern analysis", 6053 - "created_at": "2025-12-24T01:00:00.710587900-05:00" 6054 - }, 6055 - { 6056 - "id": 155, 6057 - "from_node_id": 157, 6058 - "to_node_id": 158, 6059 - "from_change_id": "3b149b2b-0e2d-4e38-a2ed-858836cb2e24", 6060 - "to_change_id": "37ab3ef1-445b-46cc-bf51-25ad24f6c131", 6061 - "edge_type": "leads_to", 6062 - "weight": 1.0, 6063 - "rationale": "Needs architecture decision", 6064 - "created_at": "2025-12-24T01:00:00.835830200-05:00" 6065 - }, 6066 - { 6067 - "id": 156, 6068 - "from_node_id": 158, 6069 - "to_node_id": 159, 6070 - "from_change_id": "37ab3ef1-445b-46cc-bf51-25ad24f6c131", 6071 - "to_change_id": "8a6cd252-e3a1-4c68-a50f-05f3574016ed", 6072 - "edge_type": "leads_to", 6073 - "weight": 1.0, 6074 - "rationale": "Option", 6075 - "created_at": "2025-12-24T01:00:00.947049900-05:00" 6076 - }, 6077 - { 6078 - "id": 157, 6079 - "from_node_id": 158, 6080 - "to_node_id": 160, 6081 - "from_change_id": "37ab3ef1-445b-46cc-bf51-25ad24f6c131", 6082 - "to_change_id": "369d275f-5ad7-4d13-aad6-7bcd69ef9e3d", 6083 - "edge_type": "leads_to", 6084 - "weight": 1.0, 6085 - "rationale": "Decision made", 6086 - "created_at": "2025-12-24T01:00:01.064823900-05:00" 6087 - }, 6088 - { 6089 - "id": 158, 6090 - "from_node_id": 160, 6091 - "to_node_id": 161, 6092 - "from_change_id": "369d275f-5ad7-4d13-aad6-7bcd69ef9e3d", 6093 - "to_change_id": "3e38a61f-16f1-4a68-a943-e66b11df29ae", 6094 - "edge_type": "leads_to", 6095 - "weight": 1.0, 6096 - "rationale": "Implementation action", 6097 - "created_at": "2025-12-24T01:00:31.107625600-05:00" 6098 - }, 6099 - { 6100 - "id": 159, 6101 - "from_node_id": 161, 6102 - "to_node_id": 162, 6103 - "from_change_id": "3e38a61f-16f1-4a68-a943-e66b11df29ae", 6104 - "to_change_id": "1be7b49c-5da2-4b2c-bd81-7900fdcf8584", 6105 - "edge_type": "leads_to", 6106 - "weight": 1.0, 6107 - "rationale": "Components created", 6108 - "created_at": "2025-12-24T01:02:14.259713700-05:00" 6109 - }, 6110 - { 6111 - "id": 160, 6112 - "from_node_id": 162, 6113 - "to_node_id": 163, 6114 - "from_change_id": "1be7b49c-5da2-4b2c-bd81-7900fdcf8584", 6115 - "to_change_id": "6a840fe3-5500-4fbf-8f8f-c3e25e2182c6", 6116 - "edge_type": "leads_to", 6117 - "weight": 1.0, 6118 - "rationale": "Next refactoring step", 6119 - "created_at": "2025-12-24T01:03:35.697505700-05:00" 6120 - }, 6121 - { 6122 - "id": 161, 6123 - "from_node_id": 163, 6124 - "to_node_id": 164, 6125 - "from_change_id": "6a840fe3-5500-4fbf-8f8f-c3e25e2182c6", 6126 - "to_change_id": "70c0a116-1c27-4d07-b1b7-4eaf6fe094e3", 6127 - "edge_type": "leads_to", 6128 - "weight": 1.0, 6129 - "rationale": "Refactoring complete", 6130 - "created_at": "2025-12-24T01:05:59.564455400-05:00" 6131 - }, 6132 - { 6133 - "id": 162, 6134 - "from_node_id": 164, 6135 - "to_node_id": 165, 6136 - "from_change_id": "70c0a116-1c27-4d07-b1b7-4eaf6fe094e3", 6137 - "to_change_id": "2ec5c20a-6d22-40b5-bf9c-ebddbd08d6e8", 6138 - "edge_type": "leads_to", 6139 - "weight": 1.0, 6140 - "rationale": "Commit action", 6141 - "created_at": "2025-12-24T01:07:46.216122700-05:00" 6142 - }, 6143 - { 6144 - "id": 163, 6145 - "from_node_id": 166, 6146 - "to_node_id": 167, 6147 - "from_change_id": "19750fc5-2408-41a7-bc14-453458d4c32f", 6148 - "to_change_id": "9f3909fd-b51d-4a00-8425-e03426bc230f", 6149 - "edge_type": "leads_to", 6150 - "weight": 1.0, 6151 - "rationale": "Refactoring complete", 6152 - "created_at": "2025-12-24T17:31:25.070485100-05:00" 6153 - }, 6154 - { 6155 - "id": 164, 6156 - "from_node_id": 166, 6157 - "to_node_id": 168, 6158 - "from_change_id": "19750fc5-2408-41a7-bc14-453458d4c32f", 6159 - "to_change_id": "3caaaa83-caa9-4695-b043-37e5367ffb4a", 6160 - "edge_type": "leads_to", 6161 - "weight": 1.0, 6162 - "rationale": "Follow-up bug discovered during testing", 6163 - "created_at": "2025-12-24T18:22:51.047366300-05:00" 6164 - }, 6165 - { 6166 - "id": 165, 6167 - "from_node_id": 168, 6168 - "to_node_id": 169, 6169 - "from_change_id": "3caaaa83-caa9-4695-b043-37e5367ffb4a", 6170 - "to_change_id": "5c0cdde6-1079-4390-aab2-7e8ef8bd94b7", 6171 - "edge_type": "leads_to", 6172 - "weight": 1.0, 6173 - "rationale": "Investigation action", 6174 - "created_at": "2025-12-24T18:23:19.896584600-05:00" 6175 - }, 6176 - { 6177 - "id": 166, 6178 - "from_node_id": 169, 6179 - "to_node_id": 170, 6180 - "from_change_id": "5c0cdde6-1079-4390-aab2-7e8ef8bd94b7", 6181 - "to_change_id": "9269b746-5275-484c-9314-b436847bf835", 6182 - "edge_type": "leads_to", 6183 - "weight": 1.0, 6184 - "rationale": "Finding from code analysis", 6185 - "created_at": "2025-12-24T18:24:35.392542800-05:00" 6186 - }, 6187 - { 6188 - "id": 167, 6189 - "from_node_id": 170, 6190 - "to_node_id": 171, 6191 - "from_change_id": "9269b746-5275-484c-9314-b436847bf835", 6192 - "to_change_id": "182aab31-aa57-42bb-8d63-cf15a7e80105", 6193 - "edge_type": "leads_to", 6194 - "weight": 1.0, 6195 - "rationale": "Decision based on finding", 6196 - "created_at": "2025-12-24T18:24:40.260592400-05:00" 6197 - }, 6198 - { 6199 - "id": 168, 6200 - "from_node_id": 171, 6201 - "to_node_id": 172, 6202 - "from_change_id": "182aab31-aa57-42bb-8d63-cf15a7e80105", 6203 - "to_change_id": "a0764baa-c522-495b-ae4c-a51b22b786bc", 6204 - "edge_type": "leads_to", 6205 - "weight": 1.0, 6206 - "rationale": "Decision made", 6207 - "created_at": "2025-12-24T18:24:53.563493800-05:00" 6208 - }, 6209 - { 6210 - "id": 169, 6211 - "from_node_id": 172, 6212 - "to_node_id": 173, 6213 - "from_change_id": "a0764baa-c522-495b-ae4c-a51b22b786bc", 6214 - "to_change_id": "328ea1bd-379a-4133-8dc8-300b03943ec8", 6215 - "edge_type": "leads_to", 6216 - "weight": 1.0, 6217 - "rationale": "Implementation based on decision", 6218 - "created_at": "2025-12-24T18:24:58.977763900-05:00" 6219 - }, 6220 - { 6221 - "id": 170, 6222 - "from_node_id": 173, 6223 - "to_node_id": 174, 6224 - "from_change_id": "328ea1bd-379a-4133-8dc8-300b03943ec8", 6225 - "to_change_id": "d9a4f78c-d1e0-4fa6-bd0b-296eba8064e5", 6226 - "edge_type": "leads_to", 6227 - "weight": 1.0, 6228 - "rationale": "Implementation complete", 6229 - "created_at": "2025-12-24T18:27:34.433837500-05:00" 6230 - }, 6231 - { 6232 - "id": 171, 6233 - "from_node_id": 174, 6234 - "to_node_id": 175, 6235 - "from_change_id": "d9a4f78c-d1e0-4fa6-bd0b-296eba8064e5", 6236 - "to_change_id": "dde6eb8d-4d35-414e-9d2e-8a577c4338df", 6237 - "edge_type": "leads_to", 6238 - "weight": 1.0, 6239 - "rationale": "Committed to repository", 6240 - "created_at": "2025-12-24T18:35:12.609336500-05:00" 6241 - }, 6242 - { 6243 - "id": 172, 6244 - "from_node_id": 176, 6245 - "to_node_id": 177, 6246 - "from_change_id": "85d33a42-5cbc-44b8-8e97-afd3edb1eeda", 6247 - "to_change_id": "dbe4421e-0496-4e3d-8548-e1c9156ce023", 6248 - "edge_type": "leads_to", 6249 - "weight": 1.0, 6250 - "rationale": "Investigation action", 6251 - "created_at": "2025-12-24T18:50:49.358413200-05:00" 6252 - }, 6253 - { 6254 - "id": 173, 6255 - "from_node_id": 177, 6256 - "to_node_id": 178, 6257 - "from_change_id": "dbe4421e-0496-4e3d-8548-e1c9156ce023", 6258 - "to_change_id": "96b417f2-4236-48bb-8ad3-3104f9f9c3b7", 6259 - "edge_type": "leads_to", 6260 - "weight": 1.0, 6261 - "rationale": "Implementation based on analysis", 6262 - "created_at": "2025-12-24T18:51:21.616689800-05:00" 6263 - }, 6264 - { 6265 - "id": 174, 6266 - "from_node_id": 178, 6267 - "to_node_id": 179, 6268 - "from_change_id": "96b417f2-4236-48bb-8ad3-3104f9f9c3b7", 6269 - "to_change_id": "21ac5b6e-575e-46fb-8695-1a7b44fd0f68", 6270 - "edge_type": "leads_to", 6271 - "weight": 1.0, 6272 - "rationale": "Implementation complete", 6273 - "created_at": "2025-12-24T18:54:10.755729900-05:00" 6274 - }, 6275 - { 6276 - "id": 175, 6277 - "from_node_id": 178, 6278 - "to_node_id": 180, 6279 - "from_change_id": "96b417f2-4236-48bb-8ad3-3104f9f9c3b7", 6280 - "to_change_id": "28e2400d-a153-4c27-a75b-e6b249355649", 6281 - "edge_type": "leads_to", 6282 - "weight": 1.0, 6283 - "rationale": "Implementation complete", 6284 - "created_at": "2025-12-24T19:06:36.936132900-05:00" 6285 - }, 6286 - { 6287 - "id": 176, 6288 - "from_node_id": 180, 6289 - "to_node_id": 181, 6290 - "from_change_id": "28e2400d-a153-4c27-a75b-e6b249355649", 6291 - "to_change_id": "acba6854-0d74-4547-91ba-391149cc5e57", 6292 - "edge_type": "leads_to", 6293 - "weight": 1.0, 6294 - "rationale": "Committed to repository", 6295 - "created_at": "2025-12-24T19:39:06.240788400-05:00" 6296 - }, 6297 - { 6298 - "id": 177, 6299 - "from_node_id": 176, 6300 - "to_node_id": 182, 6301 - "from_change_id": "85d33a42-5cbc-44b8-8e97-afd3edb1eeda", 6302 - "to_change_id": "afd62144-3edc-479e-bc6e-7bb28de124e9", 6303 - "edge_type": "leads_to", 6304 - "weight": 1.0, 6305 - "rationale": "Documentation update based on user feedback", 6306 - "created_at": "2025-12-24T19:43:02.196469100-05:00" 6307 - }, 6308 - { 6309 - "id": 178, 6310 - "from_node_id": 184, 6311 - "to_node_id": 185, 6312 - "from_change_id": "919c42ef-9fae-473f-b755-ee32d8999204", 6313 - "to_change_id": "f3768231-dac9-4575-a2db-e7e5dddabdeb", 6314 - "edge_type": "leads_to", 6315 - "weight": 1.0, 6316 - "rationale": "Problem analysis", 6317 - "created_at": "2025-12-24T21:27:03.104567500-05:00" 6318 - }, 6319 - { 6320 - "id": 179, 6321 - "from_node_id": 185, 6322 - "to_node_id": 186, 6323 - "from_change_id": "f3768231-dac9-4575-a2db-e7e5dddabdeb", 6324 - "to_change_id": "9035ca16-d7d0-4d5b-8892-3a1cee6c9f4e", 6325 - "edge_type": "leads_to", 6326 - "weight": 1.0, 6327 - "rationale": "Need to decide resolution approach", 6328 - "created_at": "2025-12-24T21:27:11.968219200-05:00" 6329 - }, 6330 - { 6331 - "id": 180, 6332 - "from_node_id": 186, 6333 - "to_node_id": 187, 6334 - "from_change_id": "9035ca16-d7d0-4d5b-8892-3a1cee6c9f4e", 6335 - "to_change_id": "2d0633f7-64a2-46b0-b709-c3da769f15d2", 6336 - "edge_type": "leads_to", 6337 - "weight": 1.0, 6338 - "rationale": "Option A", 6339 - "created_at": "2025-12-24T21:27:50.483443200-05:00" 6340 - }, 6341 - { 6342 - "id": 181, 6343 - "from_node_id": 186, 6344 - "to_node_id": 188, 6345 - "from_change_id": "9035ca16-d7d0-4d5b-8892-3a1cee6c9f4e", 6346 - "to_change_id": "ddd29814-8c96-4c7f-bfec-40ce9fcd21f7", 6347 - "edge_type": "leads_to", 6348 - "weight": 1.0, 6349 - "rationale": "Option B", 6350 - "created_at": "2025-12-24T21:27:50.604598900-05:00" 6351 - }, 6352 - { 6353 - "id": 182, 6354 - "from_node_id": 186, 6355 - "to_node_id": 189, 6356 - "from_change_id": "9035ca16-d7d0-4d5b-8892-3a1cee6c9f4e", 6357 - "to_change_id": "2456641c-b70d-453f-aed1-4fb26ad94dc0", 6358 - "edge_type": "leads_to", 6359 - "weight": 1.0, 6360 - "rationale": "Option C", 6361 - "created_at": "2025-12-24T21:27:50.742460100-05:00" 6362 - }, 6363 - { 6364 - "id": 183, 6365 - "from_node_id": 186, 6366 - "to_node_id": 190, 6367 - "from_change_id": "9035ca16-d7d0-4d5b-8892-3a1cee6c9f4e", 6368 - "to_change_id": "43e3c358-ccb7-4fd5-93ca-52d9b9d1c8fc", 6369 - "edge_type": "leads_to", 6370 - "weight": 1.0, 6371 - "rationale": "Option D", 6372 - "created_at": "2025-12-24T21:27:50.880948-05:00" 6373 - }, 6374 - { 6375 - "id": 184, 6376 - "from_node_id": 186, 6377 - "to_node_id": 191, 6378 - "from_change_id": "9035ca16-d7d0-4d5b-8892-3a1cee6c9f4e", 6379 - "to_change_id": "fe37a4eb-7247-4625-8ef4-e45986b11e24", 6380 - "edge_type": "leads_to", 6381 - "weight": 1.0, 6382 - "rationale": "Option E", 6383 - "created_at": "2025-12-24T21:27:51.026663300-05:00" 6384 - }, 6385 - { 6386 - "id": 185, 6387 - "from_node_id": 186, 6388 - "to_node_id": 192, 6389 - "from_change_id": "9035ca16-d7d0-4d5b-8892-3a1cee6c9f4e", 6390 - "to_change_id": "32e7fcf9-548e-4464-9ccb-c35da5840553", 6391 - "edge_type": "leads_to", 6392 - "weight": 1.0, 6393 - "rationale": "Option F", 6394 - "created_at": "2025-12-24T21:27:51.173782400-05:00" 6395 - }, 6396 - { 6397 - "id": 186, 6398 - "from_node_id": 186, 6399 - "to_node_id": 193, 6400 - "from_change_id": "9035ca16-d7d0-4d5b-8892-3a1cee6c9f4e", 6401 - "to_change_id": "73099c58-2157-452a-b943-fc04d117070a", 6402 - "edge_type": "leads_to", 6403 - "weight": 1.0, 6404 - "rationale": "Exploring alternative approach", 6405 - "created_at": "2025-12-24T21:34:30.517175400-05:00" 6406 - }, 6407 - { 6408 - "id": 187, 6409 - "from_node_id": 193, 6410 - "to_node_id": 194, 6411 - "from_change_id": "73099c58-2157-452a-b943-fc04d117070a", 6412 - "to_change_id": "5c420dfa-78e6-4450-86fb-05488beb7141", 6413 - "edge_type": "leads_to", 6414 - "weight": 1.0, 6415 - "rationale": "Finding from research", 6416 - "created_at": "2025-12-24T21:37:16.672298500-05:00" 6417 - }, 6418 - { 6419 - "id": 188, 6420 - "from_node_id": 193, 6421 - "to_node_id": 195, 6422 - "from_change_id": "73099c58-2157-452a-b943-fc04d117070a", 6423 - "to_change_id": "00c634a0-1ad3-43b4-b130-41742a8581b2", 6424 - "edge_type": "leads_to", 6425 - "weight": 1.0, 6426 - "rationale": "Alternative approach found", 6427 - "created_at": "2025-12-24T21:37:16.795876600-05:00" 6428 - }, 6429 - { 6430 - "id": 189, 6431 - "from_node_id": 193, 6432 - "to_node_id": 196, 6433 - "from_change_id": "73099c58-2157-452a-b943-fc04d117070a", 6434 - "to_change_id": "ca3f4ccf-ca13-4f54-9f21-b267c4f202fb", 6435 - "edge_type": "leads_to", 6436 - "weight": 1.0, 6437 - "rationale": "Possible workaround", 6438 - "created_at": "2025-12-24T21:37:16.911182300-05:00" 6439 - }, 6440 - { 6441 - "id": 190, 6442 - "from_node_id": 193, 6443 - "to_node_id": 197, 6444 - "from_change_id": "73099c58-2157-452a-b943-fc04d117070a", 6445 - "to_change_id": "6e7a605c-f9f0-4922-b677-e39b073fe852", 6446 - "edge_type": "leads_to", 6447 - "weight": 1.0, 6448 - "rationale": "Technical implementation details", 6449 - "created_at": "2025-12-24T21:44:07.795203500-05:00" 6450 - }, 6451 - { 6452 - "id": 191, 6453 - "from_node_id": 193, 6454 - "to_node_id": 198, 6455 - "from_change_id": "73099c58-2157-452a-b943-fc04d117070a", 6456 - "to_change_id": "06dd9486-e23d-413f-a5d5-121a5985b946", 6457 - "edge_type": "leads_to", 6458 - "weight": 1.0, 6459 - "rationale": "Key endpoint discovered", 6460 - "created_at": "2025-12-24T21:44:07.907029900-05:00" 6461 - }, 6462 - { 6463 - "id": 192, 6464 - "from_node_id": 186, 6465 - "to_node_id": 199, 6466 - "from_change_id": "9035ca16-d7d0-4d5b-8892-3a1cee6c9f4e", 6467 - "to_change_id": "a2c5b920-3f7d-4fbb-98a9-e47ebbea1d53", 6468 - "edge_type": "leads_to", 6469 - "weight": 1.0, 6470 - "rationale": "New option from research", 6471 - "created_at": "2025-12-24T21:44:22.787319500-05:00" 6472 - }, 6473 - { 6474 - "id": 193, 6475 - "from_node_id": 186, 6476 - "to_node_id": 200, 6477 - "from_change_id": "9035ca16-d7d0-4d5b-8892-3a1cee6c9f4e", 6478 - "to_change_id": "b35cc106-827b-453b-9cef-8c3d5b21f153", 6479 - "edge_type": "leads_to", 6480 - "weight": 1.0, 6481 - "rationale": "Alternative workflow option", 6482 - "created_at": "2025-12-24T21:44:22.888227300-05:00" 6483 - }, 6484 - { 6485 - "id": 194, 6486 - "from_node_id": 193, 6487 - "to_node_id": 201, 6488 - "from_change_id": "73099c58-2157-452a-b943-fc04d117070a", 6489 - "to_change_id": "8c5b84c3-2fe7-4295-900f-46da5aa5bc7d", 6490 - "edge_type": "leads_to", 6491 - "weight": 1.0, 6492 - "rationale": "Continued exploration based on user feedback", 6493 - "created_at": "2025-12-24T21:49:52.267604500-05:00" 6494 - }, 6495 - { 6496 - "id": 195, 6497 - "from_node_id": 201, 6498 - "to_node_id": 202, 6499 - "from_change_id": "8c5b84c3-2fe7-4295-900f-46da5aa5bc7d", 6500 - "to_change_id": "c75bd7d2-2f72-462f-bcb9-96fdf0596f78", 6501 - "edge_type": "leads_to", 6502 - "weight": 1.0, 6503 - "rationale": "Nitter viability assessment", 6504 - "created_at": "2025-12-24T21:54:16.604621-05:00" 6505 - }, 6506 - { 6507 - "id": 196, 6508 - "from_node_id": 201, 6509 - "to_node_id": 203, 6510 - "from_change_id": "8c5b84c3-2fe7-4295-900f-46da5aa5bc7d", 6511 - "to_change_id": "de39bf24-50de-468b-8c96-beb48fb0b4dc", 6512 - "edge_type": "leads_to", 6513 - "weight": 1.0, 6514 - "rationale": "Mobile platform analysis", 6515 - "created_at": "2025-12-24T21:54:16.718232400-05:00" 6516 - }, 6517 - { 6518 - "id": 197, 6519 - "from_node_id": 201, 6520 - "to_node_id": 204, 6521 - "from_change_id": "8c5b84c3-2fe7-4295-900f-46da5aa5bc7d", 6522 - "to_change_id": "3edc8b99-be7b-4275-bc7a-95244c504def", 6523 - "edge_type": "leads_to", 6524 - "weight": 1.0, 6525 - "rationale": "Technical implementation insight", 6526 - "created_at": "2025-12-24T21:54:16.834294600-05:00" 6527 - }, 6528 - { 6529 - "id": 198, 6530 - "from_node_id": 204, 6531 - "to_node_id": 205, 6532 - "from_change_id": "3edc8b99-be7b-4275-bc7a-95244c504def", 6533 - "to_change_id": "94cd0e5a-e336-4338-b1fe-06f736724d61", 6534 - "edge_type": "leads_to", 6535 - "weight": 1.0, 6536 - "rationale": "Need to decide implementation approach", 6537 - "created_at": "2025-12-24T21:54:35.275715400-05:00" 6538 - }, 6539 - { 6540 - "id": 199, 6541 - "from_node_id": 205, 6542 - "to_node_id": 206, 6543 - "from_change_id": "94cd0e5a-e336-4338-b1fe-06f736724d61", 6544 - "to_change_id": "b24507a7-5afe-4cae-bd72-8bbf360d4f05", 6545 - "edge_type": "leads_to", 6546 - "weight": 1.0, 6547 - "rationale": "Option A", 6548 - "created_at": "2025-12-24T21:54:45.129237700-05:00" 6549 - }, 6550 - { 6551 - "id": 200, 6552 - "from_node_id": 205, 6553 - "to_node_id": 207, 6554 - "from_change_id": "94cd0e5a-e336-4338-b1fe-06f736724d61", 6555 - "to_change_id": "b632ca63-ee7d-4ad0-b20e-d1acf1528f29", 6556 - "edge_type": "leads_to", 6557 - "weight": 1.0, 6558 - "rationale": "Option B", 6559 - "created_at": "2025-12-24T21:54:45.254757100-05:00" 6560 - }, 6561 - { 6562 - "id": 201, 6563 - "from_node_id": 205, 6564 - "to_node_id": 208, 6565 - "from_change_id": "94cd0e5a-e336-4338-b1fe-06f736724d61", 6566 - "to_change_id": "f9c4aa5c-d73c-4e1b-b9cf-c724c17c24ea", 6567 - "edge_type": "leads_to", 6568 - "weight": 1.0, 6569 - "rationale": "Option C", 6570 - "created_at": "2025-12-24T21:54:45.371353600-05:00" 6571 - }, 6572 - { 6573 - "id": 202, 6574 - "from_node_id": 205, 6575 - "to_node_id": 209, 6576 - "from_change_id": "94cd0e5a-e336-4338-b1fe-06f736724d61", 6577 - "to_change_id": "d74af719-eb3c-4686-87d4-0a628b94435c", 6578 - "edge_type": "leads_to", 6579 - "weight": 1.0, 6580 - "rationale": "Option D", 6581 - "created_at": "2025-12-24T21:54:45.503470500-05:00" 6582 - }, 6583 - { 6584 - "id": 203, 6585 - "from_node_id": 205, 6586 - "to_node_id": 210, 6587 - "from_change_id": "94cd0e5a-e336-4338-b1fe-06f736724d61", 6588 - "to_change_id": "7d9749ae-a2df-49c7-b460-4d67699da0d2", 6589 - "edge_type": "leads_to", 6590 - "weight": 1.0, 6591 - "rationale": "User decision", 6592 - "created_at": "2025-12-24T21:57:31.714571200-05:00" 6593 - }, 6594 - { 6595 - "id": 204, 6596 - "from_node_id": 186, 6597 - "to_node_id": 211, 6598 - "from_change_id": "9035ca16-d7d0-4d5b-8892-3a1cee6c9f4e", 6599 - "to_change_id": "2af38501-9513-4890-b22f-a9093f347f1b", 6600 - "edge_type": "leads_to", 6601 - "weight": 1.0, 6602 - "rationale": "Confirms original problem", 6603 - "created_at": "2025-12-24T21:57:31.851686800-05:00" 6604 - }, 6605 - { 6606 - "id": 205, 6607 - "from_node_id": 210, 6608 - "to_node_id": 212, 6609 - "from_change_id": "7d9749ae-a2df-49c7-b460-4d67699da0d2", 6610 - "to_change_id": "747db6d8-45f0-4598-84c0-521318603a47", 6611 - "edge_type": "leads_to", 6612 - "weight": 1.0, 6613 - "rationale": "Exploring iOS workaround", 6614 - "created_at": "2025-12-24T21:57:35.346804200-05:00" 6615 - }, 6616 - { 6617 - "id": 206, 6618 - "from_node_id": 212, 6619 - "to_node_id": 213, 6620 - "from_change_id": "747db6d8-45f0-4598-84c0-521318603a47", 6621 - "to_change_id": "9b8df205-85ae-4907-bd67-d98606b99b80", 6622 - "edge_type": "leads_to", 6623 - "weight": 1.0, 6624 - "rationale": "Key limitation found", 6625 - "created_at": "2025-12-25T11:45:02.482564500-05:00" 6626 - }, 6627 - { 6628 - "id": 207, 6629 - "from_node_id": 212, 6630 - "to_node_id": 214, 6631 - "from_change_id": "747db6d8-45f0-4598-84c0-521318603a47", 6632 - "to_change_id": "c6e020c1-3444-43fb-9b75-a35cef160b5e", 6633 - "edge_type": "leads_to", 6634 - "weight": 1.0, 6635 - "rationale": "Alternative iOS approach", 6636 - "created_at": "2025-12-25T11:45:02.578034300-05:00" 6637 - }, 6638 - { 6639 - "id": 208, 6640 - "from_node_id": 212, 6641 - "to_node_id": 215, 6642 - "from_change_id": "747db6d8-45f0-4598-84c0-521318603a47", 6643 - "to_change_id": "83fabf36-857a-4b0c-9713-d8062374fb6d", 6644 - "edge_type": "leads_to", 6645 - "weight": 1.0, 6646 - "rationale": "iOS option A", 6647 - "created_at": "2025-12-25T11:45:02.659232300-05:00" 6648 - }, 6649 - { 6650 - "id": 209, 6651 - "from_node_id": 212, 6652 - "to_node_id": 216, 6653 - "from_change_id": "747db6d8-45f0-4598-84c0-521318603a47", 6654 - "to_change_id": "d8c3f311-545b-4021-bc0a-424bdad2b26c", 6655 - "edge_type": "leads_to", 6656 - "weight": 1.0, 6657 - "rationale": "iOS option B", 6658 - "created_at": "2025-12-25T11:45:02.737254400-05:00" 6659 - }, 6660 - { 6661 - "id": 210, 6662 - "from_node_id": 210, 6663 - "to_node_id": 217, 6664 - "from_change_id": "7d9749ae-a2df-49c7-b460-4d67699da0d2", 6665 - "to_change_id": "8b8c65da-aa6b-4c0c-9cef-9dd7bee671bc", 6666 - "edge_type": "leads_to", 6667 - "weight": 1.0, 6668 - "rationale": "Documentation phase", 6669 - "created_at": "2025-12-25T11:49:25.753239900-05:00" 6670 - }, 6671 - { 6672 - "id": 211, 6673 - "from_node_id": 217, 6674 - "to_node_id": 218, 6675 - "from_change_id": "8b8c65da-aa6b-4c0c-9cef-9dd7bee671bc", 6676 - "to_change_id": "24a151a3-df0c-495f-bdaf-bef7d10a19d3", 6677 - "edge_type": "leads_to", 6678 - "weight": 1.0, 6679 - "rationale": "Key architecture decision needed", 6680 - "created_at": "2025-12-25T11:52:08.373690800-05:00" 6681 - }, 6682 - { 6683 - "id": 212, 6684 - "from_node_id": 218, 6685 - "to_node_id": 219, 6686 - "from_change_id": "24a151a3-df0c-495f-bdaf-bef7d10a19d3", 6687 - "to_change_id": "c80b61ff-bb1b-4867-9e1e-0ab48a0c64db", 6688 - "edge_type": "leads_to", 6689 - "weight": 1.0, 6690 - "rationale": "User decision", 6691 - "created_at": "2025-12-25T12:00:00.706490400-05:00" 6692 - }, 6693 - { 6694 - "id": 213, 6695 - "from_node_id": 218, 6696 - "to_node_id": 220, 6697 - "from_change_id": "24a151a3-df0c-495f-bdaf-bef7d10a19d3", 6698 - "to_change_id": "e51fb65e-6765-4f93-a5cd-ca7076f69490", 6699 - "edge_type": "leads_to", 6700 - "weight": 1.0, 6701 - "rationale": "User decision", 6702 - "created_at": "2025-12-25T12:00:00.784333900-05:00" 6703 - }, 6704 - { 6705 - "id": 214, 6706 - "from_node_id": 218, 6707 - "to_node_id": 221, 6708 - "from_change_id": "24a151a3-df0c-495f-bdaf-bef7d10a19d3", 6709 - "to_change_id": "914e0cd4-cac2-44e4-a588-2e75c946cba1", 6710 - "edge_type": "leads_to", 6711 - "weight": 1.0, 6712 - "rationale": "User decision", 6713 - "created_at": "2025-12-25T12:00:00.865831300-05:00" 6714 - }, 6715 - { 6716 - "id": 215, 6717 - "from_node_id": 218, 6718 - "to_node_id": 222, 6719 - "from_change_id": "24a151a3-df0c-495f-bdaf-bef7d10a19d3", 6720 - "to_change_id": "92ef5b60-58ae-4f28-8d1e-d3209fa37295", 6721 - "edge_type": "leads_to", 6722 - "weight": 1.0, 6723 - "rationale": "User decision", 6724 - "created_at": "2025-12-25T12:00:00.963412500-05:00" 6725 - }, 6726 - { 6727 - "id": 216, 6728 - "from_node_id": 217, 6729 - "to_node_id": 223, 6730 - "from_change_id": "8b8c65da-aa6b-4c0c-9cef-9dd7bee671bc", 6731 - "to_change_id": "94e9d9ba-3e00-4adc-8842-ec22ba6a3296", 6732 - "edge_type": "leads_to", 6733 - "weight": 1.0, 6734 - "rationale": "Documentation complete", 6735 - "created_at": "2025-12-25T12:02:30.578889900-05:00" 6736 - }, 6737 - { 6738 - "id": 217, 6739 - "from_node_id": 223, 6740 - "to_node_id": 224, 6741 - "from_change_id": "94e9d9ba-3e00-4adc-8842-ec22ba6a3296", 6742 - "to_change_id": "90b12791-3381-4392-a6f0-efba9272d3cf", 6743 - "edge_type": "leads_to", 6744 - "weight": 1.0, 6745 - "rationale": "Implementation decision needed", 6746 - "created_at": "2025-12-25T12:16:12.703356200-05:00" 6747 - }, 6748 - { 6749 - "id": 218, 6750 - "from_node_id": 224, 6751 - "to_node_id": 225, 6752 - "from_change_id": "90b12791-3381-4392-a6f0-efba9272d3cf", 6753 - "to_change_id": "a28cc1c3-f650-4bfd-a013-de15d75c3c50", 6754 - "edge_type": "leads_to", 6755 - "weight": 1.0, 6756 - "rationale": "User decision", 6757 - "created_at": "2025-12-25T12:23:00.070817-05:00" 6758 - }, 6759 - { 6760 - "id": 219, 6761 - "from_node_id": 224, 6762 - "to_node_id": 226, 6763 - "from_change_id": "90b12791-3381-4392-a6f0-efba9272d3cf", 6764 - "to_change_id": "b9735e16-f3dd-4846-9356-67d4f2a650c4", 6765 - "edge_type": "leads_to", 6766 - "weight": 1.0, 6767 - "rationale": "User decision", 6768 - "created_at": "2025-12-25T12:23:00.186776100-05:00" 6769 - }, 6770 - { 6771 - "id": 220, 6772 - "from_node_id": 225, 6773 - "to_node_id": 227, 6774 - "from_change_id": "a28cc1c3-f650-4bfd-a013-de15d75c3c50", 6775 - "to_change_id": "783fef0a-758c-43da-9e06-81194666f91c", 6776 - "edge_type": "leads_to", 6777 - "weight": 1.0, 6778 - "rationale": "Tooling choice", 6779 - "created_at": "2025-12-25T12:23:39.869630700-05:00" 6780 - }, 6781 - { 6782 - "id": 221, 6783 - "from_node_id": 228, 6784 - "to_node_id": 229, 6785 - "from_change_id": "7958ec7b-ff18-41d4-b1e1-fc9fa5603a1b", 6786 - "to_change_id": "34e48e73-6186-4652-b2a3-bdb9c1f8b1b9", 6787 - "edge_type": "leads_to", 6788 - "weight": 1.0, 6789 - "rationale": "Installation result", 6790 - "created_at": "2025-12-25T12:32:05.803918100-05:00" 6791 - }, 6792 - { 6793 - "id": 222, 6794 - "from_node_id": 227, 6795 - "to_node_id": 230, 6796 - "from_change_id": "783fef0a-758c-43da-9e06-81194666f91c", 6797 - "to_change_id": "32ad3821-b4b6-4388-81b1-7463376cc527", 6798 - "edge_type": "leads_to", 6799 - "weight": 1.0, 6800 - "rationale": "Next implementation step", 6801 - "created_at": "2025-12-25T12:32:27.448966600-05:00" 6802 - }, 6803 - { 6804 - "id": 223, 6805 - "from_node_id": 230, 6806 - "to_node_id": 231, 6807 - "from_change_id": "32ad3821-b4b6-4388-81b1-7463376cc527", 6808 - "to_change_id": "3420ad4c-dfc2-49bf-b860-acac0d7da5cf", 6809 - "edge_type": "leads_to", 6810 - "weight": 1.0, 6811 - "rationale": "Directory creation result", 6812 - "created_at": "2025-12-25T12:32:49.040747300-05:00" 6813 - }, 6814 - { 6815 - "id": 224, 6816 - "from_node_id": 231, 6817 - "to_node_id": 232, 6818 - "from_change_id": "3420ad4c-dfc2-49bf-b860-acac0d7da5cf", 6819 - "to_change_id": "97cf813e-4710-48d4-ae53-f240896d6441", 6820 - "edge_type": "leads_to", 6821 - "weight": 1.0, 6822 - "rationale": "File migration result", 6823 - "created_at": "2025-12-25T12:39:07.002739900-05:00" 6824 - }, 6825 - { 6826 - "id": 225, 6827 - "from_node_id": 232, 6828 - "to_node_id": 233, 6829 - "from_change_id": "97cf813e-4710-48d4-ae53-f240896d6441", 6830 - "to_change_id": "dafc1ae8-e56b-48a8-a9be-0729cfd5f45e", 6831 - "edge_type": "leads_to", 6832 - "weight": 1.0, 6833 - "rationale": "Functions migration result", 6834 - "created_at": "2025-12-25T12:39:30.329627600-05:00" 6835 - }, 6836 - { 6837 - "id": 226, 6838 - "from_node_id": 233, 6839 - "to_node_id": 234, 6840 - "from_change_id": "dafc1ae8-e56b-48a8-a9be-0729cfd5f45e", 6841 - "to_change_id": "2f522f67-f084-4b85-afb0-ac11f8d3e62d", 6842 - "edge_type": "leads_to", 6843 - "weight": 1.0, 6844 - "rationale": "Shared package creation", 6845 - "created_at": "2025-12-25T12:40:10.946379200-05:00" 6846 - }, 6847 - { 6848 - "id": 227, 6849 - "from_node_id": 234, 6850 - "to_node_id": 235, 6851 - "from_change_id": "2f522f67-f084-4b85-afb0-ac11f8d3e62d", 6852 - "to_change_id": "237ca2f4-5cc4-4203-88de-0d266a76448c", 6853 - "edge_type": "leads_to", 6854 - "weight": 1.0, 6855 - "rationale": "Package config creation", 6856 - "created_at": "2025-12-25T12:40:48.302397300-05:00" 6857 - }, 6858 - { 6859 - "id": 228, 6860 - "from_node_id": 235, 6861 - "to_node_id": 236, 6862 - "from_change_id": "237ca2f4-5cc4-4203-88de-0d266a76448c", 6863 - "to_change_id": "481375b2-6a7d-4e94-af79-7c40fc44d9b9", 6864 - "edge_type": "leads_to", 6865 - "weight": 1.0, 6866 - "rationale": "Config update", 6867 - "created_at": "2025-12-25T12:41:14.580693700-05:00" 6868 - }, 6869 - { 6870 - "id": 229, 6871 - "from_node_id": 236, 6872 - "to_node_id": 237, 6873 - "from_change_id": "481375b2-6a7d-4e94-af79-7c40fc44d9b9", 6874 - "to_change_id": "04b2be42-4708-477b-96f7-aecb428913b9", 6875 - "edge_type": "leads_to", 6876 - "weight": 1.0, 6877 - "rationale": "Root config update", 6878 - "created_at": "2025-12-25T12:41:32.469259-05:00" 6879 - }, 6880 - { 6881 - "id": 230, 6882 - "from_node_id": 237, 6883 - "to_node_id": 238, 6884 - "from_change_id": "04b2be42-4708-477b-96f7-aecb428913b9", 6885 - "to_change_id": "58798ef2-4fa4-46b3-9b5d-98610031a0e6", 6886 - "edge_type": "leads_to", 6887 - "weight": 1.0, 6888 - "rationale": "Next step", 6889 - "created_at": "2025-12-25T12:41:47.201836800-05:00" 6890 - }, 6891 - { 6892 - "id": 231, 6893 - "from_node_id": 238, 6894 - "to_node_id": 239, 6895 - "from_change_id": "58798ef2-4fa4-46b3-9b5d-98610031a0e6", 6896 - "to_change_id": "e155bd76-d5ed-4eca-99a4-51db8f76364d", 6897 - "edge_type": "leads_to", 6898 - "weight": 1.0, 6899 - "rationale": "Installation result", 6900 - "created_at": "2025-12-25T12:45:05.646965200-05:00" 6901 - }, 6902 - { 6903 - "id": 232, 6904 - "from_node_id": 239, 6905 - "to_node_id": 240, 6906 - "from_change_id": "e155bd76-d5ed-4eca-99a4-51db8f76364d", 6907 - "to_change_id": "99a056dc-09c8-4626-8e55-70ce9362327b", 6908 - "edge_type": "leads_to", 6909 - "weight": 1.0, 6910 - "rationale": "Testing result", 6911 - "created_at": "2025-12-25T12:46:17.758631-05:00" 6912 - }, 6913 - { 6914 - "id": 233, 6915 - "from_node_id": 240, 6916 - "to_node_id": 241, 6917 - "from_change_id": "99a056dc-09c8-4626-8e55-70ce9362327b", 6918 - "to_change_id": "d1305e02-4692-4c26-8d67-5591ce4b27b3", 6919 - "edge_type": "leads_to", 6920 - "weight": 1.0, 6921 - "rationale": "Final outcome", 6922 - "created_at": "2025-12-25T12:47:54.643486-05:00" 6923 - }, 6924 - { 6925 - "id": 234, 6926 - "from_node_id": 241, 6927 - "to_node_id": 242, 6928 - "from_change_id": "d1305e02-4692-4c26-8d67-5591ce4b27b3", 6929 - "to_change_id": "c5dd8e44-1c7b-45d9-817e-1998c87e4ffe", 6930 - "edge_type": "leads_to", 6931 - "weight": 1.0, 6932 - "rationale": "Next action", 6933 - "created_at": "2025-12-25T13:21:15.535870500-05:00" 6934 - }, 6935 - { 6936 - "id": 235, 6937 - "from_node_id": 242, 6938 - "to_node_id": 243, 6939 - "from_change_id": "c5dd8e44-1c7b-45d9-817e-1998c87e4ffe", 6940 - "to_change_id": "af843252-682e-4c02-a62c-a26188054044", 6941 - "edge_type": "leads_to", 6942 - "weight": 1.0, 6943 - "rationale": "Configuration result", 6944 - "created_at": "2025-12-25T13:21:15.627686800-05:00" 6945 - }, 6946 - { 6947 - "id": 236, 6948 - "from_node_id": 243, 6949 - "to_node_id": 244, 6950 - "from_change_id": "af843252-682e-4c02-a62c-a26188054044", 6951 - "to_change_id": "4c0a968c-c569-418f-93f3-ca6b09b24f50", 6952 - "edge_type": "leads_to", 6953 - "weight": 1.0, 6954 - "rationale": "Final commit", 6955 - "created_at": "2025-12-25T13:22:42.836562800-05:00" 6956 - }, 6957 - { 6958 - "id": 237, 6959 - "from_node_id": 184, 6960 - "to_node_id": 245, 6961 - "from_change_id": "919c42ef-9fae-473f-b755-ee32d8999204", 6962 - "to_change_id": "8efca7fe-42f2-4e40-adee-34ccfcc6e475", 6963 - "edge_type": "leads_to", 6964 - "weight": 1.0, 6965 - "rationale": "Implementation phase for Twitter extension goal", 6966 - "created_at": "2025-12-25T13:33:31.408944600-05:00" 6967 - }, 6968 - { 6969 - "id": 238, 6970 - "from_node_id": 245, 6971 - "to_node_id": 246, 6972 - "from_change_id": "8efca7fe-42f2-4e40-adee-34ccfcc6e475", 6973 - "to_change_id": "d4d45374-5507-48ef-be2a-4e21a4a109a7", 6974 - "edge_type": "leads_to", 6975 - "weight": 1.0, 6976 - "rationale": "Implementation complete with successful build", 6977 - "created_at": "2025-12-25T13:52:34.014142700-05:00" 6978 - }, 6979 - { 6980 - "id": 239, 6981 - "from_node_id": 184, 6982 - "to_node_id": 247, 6983 - "from_change_id": "919c42ef-9fae-473f-b755-ee32d8999204", 6984 - "to_change_id": "c8276478-87e3-43b3-b763-e7964a776fad", 6985 - "edge_type": "leads_to", 6986 - "weight": 1.0, 6987 - "rationale": "Post-implementation fixes and improvements", 6988 - "created_at": "2025-12-25T14:06:49.088067800-05:00" 6989 - }, 6990 - { 6991 - "id": 240, 6992 - "from_node_id": 247, 6993 - "to_node_id": 248, 6994 - "from_change_id": "c8276478-87e3-43b3-b763-e7964a776fad", 6995 - "to_change_id": "c887a416-080a-4b42-a1fc-536c8d6edd74", 6996 - "edge_type": "leads_to", 6997 - "weight": 1.0, 6998 - "rationale": "Fixes complete and documented", 6999 - "created_at": "2025-12-25T16:28:55.599385300-05:00" 7000 - }, 7001 - { 7002 - "id": 241, 7003 - "from_node_id": 247, 7004 - "to_node_id": 249, 7005 - "from_change_id": "c8276478-87e3-43b3-b763-e7964a776fad", 7006 - "to_change_id": "582e4e97-99df-4686-a9ef-762b851a62ec", 7007 - "edge_type": "leads_to", 7008 - "weight": 1.0, 7009 - "rationale": "Follow-up debugging after initial fixes", 7010 - "created_at": "2025-12-25T18:36:00.949506600-05:00" 7011 - }, 7012 - { 7013 - "id": 242, 7014 - "from_node_id": 249, 7015 - "to_node_id": 250, 7016 - "from_change_id": "582e4e97-99df-4686-a9ef-762b851a62ec", 7017 - "to_change_id": "4655082d-fab8-4415-a088-c41552402127", 7018 - "edge_type": "leads_to", 7019 - "weight": 1.0, 7020 - "rationale": "Root cause identified and fixed", 7021 - "created_at": "2025-12-25T18:52:40.291421600-05:00" 7022 - }, 7023 - { 7024 - "id": 243, 7025 - "from_node_id": 184, 7026 - "to_node_id": 251, 7027 - "from_change_id": "919c42ef-9fae-473f-b755-ee32d8999204", 7028 - "to_change_id": "072f963c-3e06-445a-be4f-0a045e27c6c2", 7029 - "edge_type": "leads_to", 7030 - "weight": 1.0, 7031 - "rationale": "UI polish for extension", 7032 - "created_at": "2025-12-25T18:56:23.458768300-05:00" 7033 - }, 7034 - { 7035 - "id": 244, 7036 - "from_node_id": 251, 7037 - "to_node_id": 252, 7038 - "from_change_id": "072f963c-3e06-445a-be4f-0a045e27c6c2", 7039 - "to_change_id": "b5cd9aed-c8cc-4d70-8790-b11a21d751fc", 7040 - "edge_type": "leads_to", 7041 - "weight": 1.0, 7042 - "rationale": "Dark mode implementation complete", 7043 - "created_at": "2025-12-25T19:00:27.045687800-05:00" 7044 - }, 7045 - { 7046 - "id": 245, 7047 - "from_node_id": 184, 7048 - "to_node_id": 253, 7049 - "from_change_id": "919c42ef-9fae-473f-b755-ee32d8999204", 7050 - "to_change_id": "af40219a-2094-4e5f-8e96-4b5c9850669b", 7051 - "edge_type": "leads_to", 7052 - "weight": 1.0, 7053 - "rationale": "Testing actual scraping after fixing detection", 7054 - "created_at": "2025-12-25T19:03:41.610950300-05:00" 7055 - }, 7056 - { 7057 - "id": 246, 7058 - "from_node_id": 184, 7059 - "to_node_id": 254, 7060 - "from_change_id": "919c42ef-9fae-473f-b755-ee32d8999204", 7061 - "to_change_id": "c765751c-c23b-4a27-bfc9-e118b799e1cc", 7062 - "edge_type": "leads_to", 7063 - "weight": 1.0, 7064 - "rationale": "Bug found during testing", 7065 - "created_at": "2025-12-25T19:17:19.516534800-05:00" 7066 - }, 7067 - { 7068 - "id": 247, 7069 - "from_node_id": 254, 7070 - "to_node_id": 255, 7071 - "from_change_id": "c765751c-c23b-4a27-bfc9-e118b799e1cc", 7072 - "to_change_id": "9f99eb8c-d15b-41b0-af92-c36de5048fdd", 7073 - "edge_type": "leads_to", 7074 - "weight": 1.0, 7075 - "rationale": "Needed to debug selector", 7076 - "created_at": "2025-12-25T19:17:19.704435600-05:00" 7077 - }, 7078 - { 7079 - "id": 248, 7080 - "from_node_id": 255, 7081 - "to_node_id": 256, 7082 - "from_change_id": "9f99eb8c-d15b-41b0-af92-c36de5048fdd", 7083 - "to_change_id": "3f9c13ee-b216-4e00-ab04-9ad45712228a", 7084 - "edge_type": "leads_to", 7085 - "weight": 1.0, 7086 - "rationale": "Found correct selector via browser inspection", 7087 - "created_at": "2025-12-25T19:17:19.896961300-05:00" 7088 - }, 7089 - { 7090 - "id": 249, 7091 - "from_node_id": 256, 7092 - "to_node_id": 257, 7093 - "from_change_id": "3f9c13ee-b216-4e00-ab04-9ad45712228a", 7094 - "to_change_id": "eccb2bb1-413e-4d9f-8eb8-eb753bd5b82b", 7095 - "edge_type": "leads_to", 7096 - "weight": 1.0, 7097 - "rationale": "Implemented fix based on discovery", 7098 - "created_at": "2025-12-25T19:17:34.829447100-05:00" 7099 - }, 7100 - { 7101 - "id": 250, 7102 - "from_node_id": 258, 7103 - "to_node_id": 259, 7104 - "from_change_id": "b8c6cd90-7f32-461e-aad5-537cc1cbfafe", 7105 - "to_change_id": "c68dfdc1-7f88-446d-b5dd-7eb514bc26c8", 7106 - "edge_type": "leads_to", 7107 - "weight": 1.0, 7108 - "rationale": "Investigation step for goal", 7109 - "created_at": "2025-12-25T20:35:27.600584800-05:00" 7110 - }, 7111 - { 7112 - "id": 251, 7113 - "from_node_id": 259, 7114 - "to_node_id": 260, 7115 - "from_change_id": "c68dfdc1-7f88-446d-b5dd-7eb514bc26c8", 7116 - "to_change_id": "7083c996-e161-497c-abfd-07e90be3fdc9", 7117 - "edge_type": "leads_to", 7118 - "weight": 1.0, 7119 - "rationale": "Finding from analysis", 7120 - "created_at": "2025-12-25T20:35:38.315750700-05:00" 7121 - }, 7122 - { 7123 - "id": 252, 7124 - "from_node_id": 260, 7125 - "to_node_id": 261, 7126 - "from_change_id": "7083c996-e161-497c-abfd-07e90be3fdc9", 7127 - "to_change_id": "570173f7-1960-479f-a99a-3d2433e1f8ee", 7128 - "edge_type": "leads_to", 7129 - "weight": 1.0, 7130 - "rationale": "Action based on finding", 7131 - "created_at": "2025-12-25T20:36:00.910717800-05:00" 7132 - }, 7133 - { 7134 - "id": 253, 7135 - "from_node_id": 263, 7136 - "to_node_id": 264, 7137 - "from_change_id": "b5109344-a5d3-43b3-b743-b06730453514", 7138 - "to_change_id": "4e9b17fd-14c8-4fbb-8b23-020dbc6ba364", 7139 - "edge_type": "leads_to", 7140 - "weight": 1.0, 7141 - "rationale": "Decision based on observation", 7142 - "created_at": "2025-12-25T20:41:30.258496100-05:00" 7143 - }, 7144 - { 7145 - "id": 254, 7146 - "from_node_id": 264, 7147 - "to_node_id": 265, 7148 - "from_change_id": "4e9b17fd-14c8-4fbb-8b23-020dbc6ba364", 7149 - "to_change_id": "ae943152-ffe4-468e-b4ca-e806996be861", 7150 - "edge_type": "leads_to", 7151 - "weight": 1.0, 7152 - "rationale": "Decision outcome", 7153 - "created_at": "2025-12-25T20:41:44.053117400-05:00" 7154 - }, 7155 - { 7156 - "id": 255, 7157 - "from_node_id": 265, 7158 - "to_node_id": 266, 7159 - "from_change_id": "ae943152-ffe4-468e-b4ca-e806996be861", 7160 - "to_change_id": "b2720400-7337-4fac-aca8-822cfb79e33f", 7161 - "edge_type": "leads_to", 7162 - "weight": 1.0, 7163 - "rationale": "Action based on outcome", 7164 - "created_at": "2025-12-25T20:42:29.679655600-05:00" 7165 - }, 7166 - { 7167 - "id": 256, 7168 - "from_node_id": 266, 7169 - "to_node_id": 267, 7170 - "from_change_id": "b2720400-7337-4fac-aca8-822cfb79e33f", 7171 - "to_change_id": "72263b57-78a4-4282-a805-0af9722677e1", 7172 - "edge_type": "leads_to", 7173 - "weight": 1.0, 7174 - "rationale": "Root cause discovered during implementation", 7175 - "created_at": "2025-12-25T20:44:15.140752600-05:00" 7176 - }, 7177 - { 7178 - "id": 257, 7179 - "from_node_id": 267, 7180 - "to_node_id": 268, 7181 - "from_change_id": "72263b57-78a4-4282-a805-0af9722677e1", 7182 - "to_change_id": "440f0c78-a314-4ec5-b56d-4c00ce7df8d4", 7183 - "edge_type": "leads_to", 7184 - "weight": 1.0, 7185 - "rationale": "Action to fix the issue", 7186 - "created_at": "2025-12-25T20:44:44.317390900-05:00" 7187 - }, 7188 - { 7189 - "id": 258, 7190 - "from_node_id": 268, 7191 - "to_node_id": 269, 7192 - "from_change_id": "440f0c78-a314-4ec5-b56d-4c00ce7df8d4", 7193 - "to_change_id": "25c635ed-46d5-4933-9e90-b67556bbdf27", 7194 - "edge_type": "leads_to", 7195 - "weight": 1.0, 7196 - "rationale": "Implementation complete", 7197 - "created_at": "2025-12-25T20:45:58.408835800-05:00" 7198 - }, 7199 - { 7200 - "id": 259, 7201 - "from_node_id": 258, 7202 - "to_node_id": 269, 7203 - "from_change_id": "b8c6cd90-7f32-461e-aad5-537cc1cbfafe", 7204 - "to_change_id": "25c635ed-46d5-4933-9e90-b67556bbdf27", 7205 - "edge_type": "leads_to", 7206 - "weight": 1.0, 7207 - "rationale": "Goal achieved", 7208 - "created_at": "2025-12-25T20:46:01.117086400-05:00" 7209 - }, 7210 - { 7211 - "id": 260, 7212 - "from_node_id": 270, 7213 - "to_node_id": 271, 7214 - "from_change_id": "8cf80c58-e909-4f0b-85e8-ac15d7cf3640", 7215 - "to_change_id": "74b3bc73-4ff1-4a27-a347-69673f93cbb0", 7216 - "edge_type": "leads_to", 7217 - "weight": 1.0, 7218 - "rationale": "First action to fix port conflict", 7219 - "created_at": "2025-12-25T21:37:18.845105100-05:00" 7220 - }, 7221 - { 7222 - "id": 261, 7223 - "from_node_id": 271, 7224 - "to_node_id": 272, 7225 - "from_change_id": "74b3bc73-4ff1-4a27-a347-69673f93cbb0", 7226 - "to_change_id": "67ad4d3b-3b47-4b18-b7f3-e75695ba295d", 7227 - "edge_type": "leads_to", 7228 - "weight": 1.0, 7229 - "rationale": "Finding from killing process", 7230 - "created_at": "2025-12-25T21:37:53.189999500-05:00" 7231 - }, 7232 - { 7233 - "id": 262, 7234 - "from_node_id": 272, 7235 - "to_node_id": 273, 7236 - "from_change_id": "67ad4d3b-3b47-4b18-b7f3-e75695ba295d", 7237 - "to_change_id": "78b22c65-3381-4ea1-b48d-1d7784a7ca0f", 7238 - "edge_type": "leads_to", 7239 - "weight": 1.0, 7240 - "rationale": "Action based on observation", 7241 - "created_at": "2025-12-25T21:38:07.178898700-05:00" 7242 - }, 7243 - { 7244 - "id": 263, 7245 - "from_node_id": 273, 7246 - "to_node_id": 274, 7247 - "from_change_id": "78b22c65-3381-4ea1-b48d-1d7784a7ca0f", 7248 - "to_change_id": "daa6b960-c5d9-44bf-ad62-edb27fedf593", 7249 - "edge_type": "leads_to", 7250 - "weight": 1.0, 7251 - "rationale": "Implementation complete", 7252 - "created_at": "2025-12-25T21:42:41.329103-05:00" 7253 - }, 7254 - { 7255 - "id": 264, 7256 - "from_node_id": 270, 7257 - "to_node_id": 274, 7258 - "from_change_id": "8cf80c58-e909-4f0b-85e8-ac15d7cf3640", 7259 - "to_change_id": "daa6b960-c5d9-44bf-ad62-edb27fedf593", 7260 - "edge_type": "leads_to", 7261 - "weight": 1.0, 7262 - "rationale": "Goal achieved", 7263 - "created_at": "2025-12-25T21:42:41.474856-05:00" 7264 - }, 7265 - { 7266 - "id": 265, 7267 - "from_node_id": 275, 7268 - "to_node_id": 276, 7269 - "from_change_id": "dcc9f401-1a68-479e-97de-7a04e5597e00", 7270 - "to_change_id": "b587d77b-624e-4d37-9e56-9c58b6229860", 7271 - "edge_type": "leads_to", 7272 - "weight": 1.0, 7273 - "rationale": "Action to fix CORS issue", 7274 - "created_at": "2025-12-25T21:59:24.884598200-05:00" 7275 - }, 7276 - { 7277 - "id": 266, 7278 - "from_node_id": 276, 7279 - "to_node_id": 277, 7280 - "from_change_id": "b587d77b-624e-4d37-9e56-9c58b6229860", 7281 - "to_change_id": "edd49d41-7b40-4e2a-b168-816faccf223c", 7282 - "edge_type": "leads_to", 7283 - "weight": 1.0, 7284 - "rationale": "Fix complete", 7285 - "created_at": "2025-12-25T21:59:40.544320600-05:00" 7286 - }, 7287 - { 7288 - "id": 267, 7289 - "from_node_id": 278, 7290 - "to_node_id": 279, 7291 - "from_change_id": "fa11e7d7-ac30-4d0e-bc8a-d2332f724d92", 7292 - "to_change_id": "0710252d-bcf6-4708-b67f-d9615a0dad6e", 7293 - "edge_type": "leads_to", 7294 - "weight": 1.0, 7295 - "rationale": "Root cause identified", 7296 - "created_at": "2025-12-25T22:07:08.406207600-05:00" 7297 - }, 7298 - { 7299 - "id": 268, 7300 - "from_node_id": 279, 7301 - "to_node_id": 280, 7302 - "from_change_id": "0710252d-bcf6-4708-b67f-d9615a0dad6e", 7303 - "to_change_id": "f38929d4-0ad0-43ec-a25c-a9dd6f9ee7fd", 7304 - "edge_type": "leads_to", 7305 - "weight": 1.0, 7306 - "rationale": "Action to fix", 7307 - "created_at": "2025-12-25T22:07:08.525762700-05:00" 7308 - }, 7309 - { 7310 - "id": 269, 7311 - "from_node_id": 280, 7312 - "to_node_id": 281, 7313 - "from_change_id": "f38929d4-0ad0-43ec-a25c-a9dd6f9ee7fd", 7314 - "to_change_id": "0e917ade-9f83-4246-9a66-1aa2dfef7c41", 7315 - "edge_type": "leads_to", 7316 - "weight": 1.0, 7317 - "rationale": "Implementation complete", 7318 - "created_at": "2025-12-25T22:20:23.139445800-05:00" 7319 - }, 7320 - { 7321 - "id": 270, 7322 - "from_node_id": 278, 7323 - "to_node_id": 281, 7324 - "from_change_id": "fa11e7d7-ac30-4d0e-bc8a-d2332f724d92", 7325 - "to_change_id": "0e917ade-9f83-4246-9a66-1aa2dfef7c41", 7326 - "edge_type": "leads_to", 7327 - "weight": 1.0, 7328 - "rationale": "Goal achieved", 7329 - "created_at": "2025-12-25T22:20:23.242682400-05:00" 7330 - }, 7331 - { 7332 - "id": 271, 7333 - "from_node_id": 282, 7334 - "to_node_id": 284, 7335 - "from_change_id": "206347b5-4178-43dd-bb05-657b3788a6b0", 7336 - "to_change_id": "3d9caa98-6f9c-4613-9c05-92566f9ee0d5", 7337 - "edge_type": "leads_to", 7338 - "weight": 1.0, 7339 - "rationale": "Refactor complete", 7340 - "created_at": "2025-12-26T00:18:57.785597400-05:00" 7341 - }, 7342 - { 7343 - "id": 272, 7344 - "from_node_id": 283, 7345 - "to_node_id": 284, 7346 - "from_change_id": "e3adddaf-9126-4bfa-8d75-aa8b94323077", 7347 - "to_change_id": "3d9caa98-6f9c-4613-9c05-92566f9ee0d5", 7348 - "edge_type": "leads_to", 7349 - "weight": 1.0, 7350 - "rationale": "Key observation about flow", 7351 - "created_at": "2025-12-26T00:18:57.901372200-05:00" 7352 - }, 7353 - { 7354 - "id": 273, 7355 - "from_node_id": 284, 7356 - "to_node_id": 285, 7357 - "from_change_id": "3d9caa98-6f9c-4613-9c05-92566f9ee0d5", 7358 - "to_change_id": "f0da412f-562b-4e45-b83d-eba28fc22eea", 7359 - "edge_type": "leads_to", 7360 - "weight": 1.0, 7361 - "rationale": "Build completed after refactoring extension flow", 7362 - "created_at": "2025-12-26T00:24:07.711141900-05:00" 7363 - }, 7364 - { 7365 - "id": 274, 7366 - "from_node_id": 285, 7367 - "to_node_id": 286, 7368 - "from_change_id": "f0da412f-562b-4e45-b83d-eba28fc22eea", 7369 - "to_change_id": "60c9ec75-7e3f-4aa4-b8cf-0691ef92d260", 7370 - "edge_type": "leads_to", 7371 - "weight": 1.0, 7372 - "rationale": "Committed after successful build", 7373 - "created_at": "2025-12-26T00:26:22.985765600-05:00" 7374 - }, 7375 - { 7376 - "id": 275, 7377 - "from_node_id": 286, 7378 - "to_node_id": 287, 7379 - "from_change_id": "60c9ec75-7e3f-4aa4-b8cf-0691ef92d260", 7380 - "to_change_id": "e01c6989-6c0b-42f8-b7c7-60aca059f7c3", 7381 - "edge_type": "leads_to", 7382 - "weight": 1.0, 7383 - "rationale": "Found and fixed bug during testing", 7384 - "created_at": "2025-12-26T00:33:34.834072700-05:00" 7385 - }, 7386 - { 7387 - "id": 276, 7388 - "from_node_id": 287, 7389 - "to_node_id": 288, 7390 - "from_change_id": "e01c6989-6c0b-42f8-b7c7-60aca059f7c3", 7391 - "to_change_id": "5fa82fdc-7796-4263-be72-e1877279881b", 7392 - "edge_type": "leads_to", 7393 - "weight": 1.0, 7394 - "rationale": "Initialized database after fixing parameter bug", 7395 - "created_at": "2025-12-26T00:47:11.206746500-05:00" 7396 - }, 7397 - { 7398 - "id": 277, 7399 - "from_node_id": 288, 7400 - "to_node_id": 289, 7401 - "from_change_id": "5fa82fdc-7796-4263-be72-e1877279881b", 7402 - "to_change_id": "dd2aa029-7ca9-4379-a966-762c9137bcc8", 7403 - "edge_type": "leads_to", 7404 - "weight": 1.0, 7405 - "rationale": "Documented current state after fixes", 7406 - "created_at": "2025-12-26T00:50:58.391390400-05:00" 7407 - }, 7408 - { 7409 - "id": 278, 7410 - "from_node_id": 290, 7411 - "to_node_id": 291, 7412 - "from_change_id": "d73fc969-78c0-4721-8db5-88014cb4a0a6", 7413 - "to_change_id": "1d88fcb9-3f0e-400b-aabd-7b1564064fd9", 7414 - "edge_type": "leads_to", 7415 - "weight": 1.0, 7416 - "rationale": "Initial observation", 7417 - "created_at": "2025-12-26T13:32:22.732622800-05:00" 7418 - }, 7419 - { 7420 - "id": 279, 7421 - "from_node_id": 291, 7422 - "to_node_id": 292, 7423 - "from_change_id": "1d88fcb9-3f0e-400b-aabd-7b1564064fd9", 7424 - "to_change_id": "22c007f9-6e84-4a72-bc6f-462b94655b40", 7425 - "edge_type": "leads_to", 7426 - "weight": 1.0, 7427 - "rationale": "Found root cause", 7428 - "created_at": "2025-12-26T13:32:52.519089400-05:00" 7429 - }, 7430 - { 7431 - "id": 280, 7432 - "from_node_id": 292, 7433 - "to_node_id": 293, 7434 - "from_change_id": "22c007f9-6e84-4a72-bc6f-462b94655b40", 7435 - "to_change_id": "59087762-06cf-4be1-8a15-fb2244070951", 7436 - "edge_type": "leads_to", 7437 - "weight": 1.0, 7438 - "rationale": "Action to fix", 7439 - "created_at": "2025-12-26T13:32:56.783062600-05:00" 7440 - }, 7441 - { 7442 - "id": 281, 7443 - "from_node_id": 293, 7444 - "to_node_id": 294, 7445 - "from_change_id": "59087762-06cf-4be1-8a15-fb2244070951", 7446 - "to_change_id": "6a2f6150-4b32-45ee-b2c7-cd5094fdd8c6", 7447 - "edge_type": "leads_to", 7448 - "weight": 1.0, 7449 - "rationale": "Implementation complete", 7450 - "created_at": "2025-12-26T13:34:11.125730600-05:00" 7451 - }, 7452 - { 7453 - "id": 282, 7454 - "from_node_id": 294, 7455 - "to_node_id": 295, 7456 - "from_change_id": "6a2f6150-4b32-45ee-b2c7-cd5094fdd8c6", 7457 - "to_change_id": "ceaed4fe-5fd0-4542-8f3a-bd4640dfaadf", 7458 - "edge_type": "leads_to", 7459 - "weight": 1.0, 7460 - "rationale": "Committed to repository", 7461 - "created_at": "2025-12-26T13:36:04.808506400-05:00" 7462 - }, 7463 - { 7464 - "id": 283, 7465 - "from_node_id": 290, 7466 - "to_node_id": 295, 7467 - "from_change_id": "d73fc969-78c0-4721-8db5-88014cb4a0a6", 7468 - "to_change_id": "ceaed4fe-5fd0-4542-8f3a-bd4640dfaadf", 7469 - "edge_type": "leads_to", 7470 - "weight": 1.0, 7471 - "rationale": "Goal achieved", 7472 - "created_at": "2025-12-26T13:36:06.860603400-05:00" 7473 - }, 7474 - { 7475 - "id": 284, 7476 - "from_node_id": 295, 7477 - "to_node_id": 296, 7478 - "from_change_id": "ceaed4fe-5fd0-4542-8f3a-bd4640dfaadf", 7479 - "to_change_id": "e2427bfe-84a1-4dee-adf4-28a9c1b739e2", 7480 - "edge_type": "leads_to", 7481 - "weight": 1.0, 7482 - "rationale": "Documentation updated", 7483 - "created_at": "2025-12-26T13:37:37.858859900-05:00" 7484 - }, 7485 - { 7486 - "id": 285, 7487 - "from_node_id": 296, 7488 - "to_node_id": 297, 7489 - "from_change_id": "e2427bfe-84a1-4dee-adf4-28a9c1b739e2", 7490 - "to_change_id": "74ea361f-577c-4058-b833-6666e777ee00", 7491 - "edge_type": "leads_to", 7492 - "weight": 1.0, 7493 - "rationale": "New issues found during testing", 7494 - "created_at": "2025-12-26T13:43:05.419406600-05:00" 7495 - }, 7496 - { 7497 - "id": 286, 7498 - "from_node_id": 297, 7499 - "to_node_id": 298, 7500 - "from_change_id": "74ea361f-577c-4058-b833-6666e777ee00", 7501 - "to_change_id": "c373be70-157a-420d-bc11-4364fe22d091", 7502 - "edge_type": "leads_to", 7503 - "weight": 1.0, 7504 - "rationale": "Root cause analysis", 7505 - "created_at": "2025-12-26T13:43:31.032670900-05:00" 7506 - }, 7507 - { 7508 - "id": 287, 7509 - "from_node_id": 298, 7510 - "to_node_id": 299, 7511 - "from_change_id": "c373be70-157a-420d-bc11-4364fe22d091", 7512 - "to_change_id": "8edd7e11-54b4-4c5b-8379-37b1ec1e7d7d", 7513 - "edge_type": "leads_to", 7514 - "weight": 1.0, 7515 - "rationale": "Action to fix both issues", 7516 - "created_at": "2025-12-26T13:44:30.495551600-05:00" 7517 - }, 7518 - { 7519 - "id": 288, 7520 - "from_node_id": 299, 7521 - "to_node_id": 300, 7522 - "from_change_id": "8edd7e11-54b4-4c5b-8379-37b1ec1e7d7d", 7523 - "to_change_id": "876412ec-a214-4bf7-b48a-b7706c698085", 7524 - "edge_type": "leads_to", 7525 - "weight": 1.0, 7526 - "rationale": "Implementation complete", 7527 - "created_at": "2025-12-26T13:46:00.313229300-05:00" 7528 - }, 7529 - { 7530 - "id": 289, 7531 - "from_node_id": 300, 7532 - "to_node_id": 301, 7533 - "from_change_id": "876412ec-a214-4bf7-b48a-b7706c698085", 7534 - "to_change_id": "b3f870cc-406f-4cf7-8ab4-04d9f76fb2ab", 7535 - "edge_type": "leads_to", 7536 - "weight": 1.0, 7537 - "rationale": "Committed to repository", 7538 - "created_at": "2025-12-26T13:47:50.881789900-05:00" 7539 - }, 7540 - { 7541 - "id": 290, 7542 - "from_node_id": 297, 7543 - "to_node_id": 301, 7544 - "from_change_id": "74ea361f-577c-4058-b833-6666e777ee00", 7545 - "to_change_id": "b3f870cc-406f-4cf7-8ab4-04d9f76fb2ab", 7546 - "edge_type": "leads_to", 7547 - "weight": 1.0, 7548 - "rationale": "Goal achieved", 7549 - "created_at": "2025-12-26T13:47:52.948372300-05:00" 7550 - }, 7551 - { 7552 - "id": 291, 7553 - "from_node_id": 301, 7554 - "to_node_id": 302, 7555 - "from_change_id": "b3f870cc-406f-4cf7-8ab4-04d9f76fb2ab", 7556 - "to_change_id": "e2cf6ed0-c80f-420a-bdd2-98369f58de2a", 7557 - "edge_type": "leads_to", 7558 - "weight": 1.0, 7559 - "rationale": "New error found in testing", 7560 - "created_at": "2025-12-26T13:51:02.588994500-05:00" 7561 - }, 7562 - { 7563 - "id": 292, 7564 - "from_node_id": 302, 7565 - "to_node_id": 303, 7566 - "from_change_id": "e2cf6ed0-c80f-420a-bdd2-98369f58de2a", 7567 - "to_change_id": "7a7a19a6-4abf-4c30-9072-14beaa12b106", 7568 - "edge_type": "leads_to", 7569 - "weight": 1.0, 7570 - "rationale": "Fix identified", 7571 - "created_at": "2025-12-26T13:51:38.127298700-05:00" 7572 - }, 7573 - { 7574 - "id": 293, 7575 - "from_node_id": 303, 7576 - "to_node_id": 304, 7577 - "from_change_id": "7a7a19a6-4abf-4c30-9072-14beaa12b106", 7578 - "to_change_id": "dff4aef7-8732-4aae-a6be-f44fb42b4941", 7579 - "edge_type": "leads_to", 7580 - "weight": 1.0, 7581 - "rationale": "Implementation complete", 7582 - "created_at": "2025-12-26T13:51:54.561857100-05:00" 7583 - }, 7584 - { 7585 - "id": 294, 7586 - "from_node_id": 304, 7587 - "to_node_id": 305, 7588 - "from_change_id": "dff4aef7-8732-4aae-a6be-f44fb42b4941", 7589 - "to_change_id": "8ad6ef53-29a2-442e-b88f-9e0541634950", 7590 - "edge_type": "leads_to", 7591 - "weight": 1.0, 7592 - "rationale": "New issues found in testing", 7593 - "created_at": "2025-12-26T14:05:56.045966300-05:00" 7594 - }, 7595 - { 7596 - "id": 295, 7597 - "from_node_id": 305, 7598 - "to_node_id": 306, 7599 - "from_change_id": "8ad6ef53-29a2-442e-b88f-9e0541634950", 7600 - "to_change_id": "481942f8-5905-4948-a1cb-ee320a98271b", 7601 - "edge_type": "leads_to", 7602 - "weight": 1.0, 7603 - "rationale": "Root cause identified", 7604 - "created_at": "2025-12-26T14:06:20.512128100-05:00" 7605 - }, 7606 - { 7607 - "id": 296, 7608 - "from_node_id": 306, 7609 - "to_node_id": 307, 7610 - "from_change_id": "481942f8-5905-4948-a1cb-ee320a98271b", 7611 - "to_change_id": "ae01acc1-f5ff-481b-823f-de2d4f1843a2", 7612 - "edge_type": "leads_to", 7613 - "weight": 1.0, 7614 - "rationale": "Root cause found", 7615 - "created_at": "2025-12-26T14:09:00.202061-05:00" 7616 - }, 7617 - { 7618 - "id": 297, 7619 - "from_node_id": 307, 7620 - "to_node_id": 308, 7621 - "from_change_id": "ae01acc1-f5ff-481b-823f-de2d4f1843a2", 7622 - "to_change_id": "2368cae0-9ae1-4ca0-9ace-8c3555f9e679", 7623 - "edge_type": "leads_to", 7624 - "weight": 1.0, 7625 - "rationale": "Action to fix", 7626 - "created_at": "2025-12-26T14:09:05.743608600-05:00" 7627 - }, 7628 - { 7629 - "id": 298, 7630 - "from_node_id": 308, 7631 - "to_node_id": 309, 7632 - "from_change_id": "2368cae0-9ae1-4ca0-9ace-8c3555f9e679", 7633 - "to_change_id": "cd9b88e7-fe8d-4ee0-a187-e99eef0b7e64", 7634 - "edge_type": "leads_to", 7635 - "weight": 1.0, 7636 - "rationale": "Implementation complete", 7637 - "created_at": "2025-12-26T14:11:11.543447500-05:00" 7638 - }, 7639 - { 7640 - "id": 299, 7641 - "from_node_id": 309, 7642 - "to_node_id": 310, 7643 - "from_change_id": "cd9b88e7-fe8d-4ee0-a187-e99eef0b7e64", 7644 - "to_change_id": "51369a2c-17ec-4be3-ba4f-240b770d7211", 7645 - "edge_type": "leads_to", 7646 - "weight": 1.0, 7647 - "rationale": "Committed to repository", 7648 - "created_at": "2025-12-26T14:16:10.702697200-05:00" 7649 - }, 7650 - { 7651 - "id": 300, 7652 - "from_node_id": 305, 7653 - "to_node_id": 310, 7654 - "from_change_id": "8ad6ef53-29a2-442e-b88f-9e0541634950", 7655 - "to_change_id": "51369a2c-17ec-4be3-ba4f-240b770d7211", 7656 - "edge_type": "leads_to", 7657 - "weight": 1.0, 7658 - "rationale": "All goals achieved", 7659 - "created_at": "2025-12-26T14:16:12.935280500-05:00" 7660 - }, 7661 - { 7662 - "id": 301, 7663 - "from_node_id": 310, 7664 - "to_node_id": 311, 7665 - "from_change_id": "51369a2c-17ec-4be3-ba4f-240b770d7211", 7666 - "to_change_id": "91d7bad2-a8a3-47c3-8fad-558919b207b0", 7667 - "edge_type": "leads_to", 7668 - "weight": 1.0, 7669 - "rationale": "New error found", 7670 - "created_at": "2025-12-26T16:07:24.117669300-05:00" 7671 - }, 7672 - { 7673 - "id": 302, 7674 - "from_node_id": 311, 7675 - "to_node_id": 312, 7676 - "from_change_id": "91d7bad2-a8a3-47c3-8fad-558919b207b0", 7677 - "to_change_id": "9a95c7e6-6339-475f-9b20-5fa3057e0a9f", 7678 - "edge_type": "leads_to", 7679 - "weight": 1.0, 7680 - "rationale": "Fix applied", 7681 - "created_at": "2025-12-26T16:08:21.431326200-05:00" 7682 - }, 7683 - { 7684 - "id": 303, 7685 - "from_node_id": 312, 7686 - "to_node_id": 313, 7687 - "from_change_id": "9a95c7e6-6339-475f-9b20-5fa3057e0a9f", 7688 - "to_change_id": "5fae9da8-2a31-4f99-9686-7bfb28c443e8", 7689 - "edge_type": "leads_to", 7690 - "weight": 1.0, 7691 - "rationale": "Implementation complete", 7692 - "created_at": "2025-12-26T16:08:26.942822600-05:00" 7693 - }, 7694 - { 7695 - "id": 304, 7696 - "from_node_id": 313, 7697 - "to_node_id": 314, 7698 - "from_change_id": "5fae9da8-2a31-4f99-9686-7bfb28c443e8", 7699 - "to_change_id": "6837403f-1e30-4a71-bcf5-71db0cac6afc", 7700 - "edge_type": "leads_to", 7701 - "weight": 1.0, 7702 - "rationale": "New errors found", 7703 - "created_at": "2025-12-26T20:18:01.626612100-05:00" 7704 - }, 7705 - { 7706 - "id": 305, 7707 - "from_node_id": 314, 7708 - "to_node_id": 315, 7709 - "from_change_id": "6837403f-1e30-4a71-bcf5-71db0cac6afc", 7710 - "to_change_id": "a08d22fc-5970-4a5d-8454-4a1ef2efc7e4", 7711 - "edge_type": "leads_to", 7712 - "weight": 1.0, 7713 - "rationale": "Initial analysis", 7714 - "created_at": "2025-12-26T20:18:45.898518700-05:00" 7715 - }, 7716 - { 7717 - "id": 306, 7718 - "from_node_id": 315, 7719 - "to_node_id": 316, 7720 - "from_change_id": "a08d22fc-5970-4a5d-8454-4a1ef2efc7e4", 7721 - "to_change_id": "58ef0c82-402c-4fff-8421-83c5417475b1", 7722 - "edge_type": "leads_to", 7723 - "weight": 1.0, 7724 - "rationale": "Fix identified", 7725 - "created_at": "2025-12-26T20:19:50.103362300-05:00" 7726 - }, 7727 - { 7728 - "id": 307, 7729 - "from_node_id": 316, 7730 - "to_node_id": 317, 7731 - "from_change_id": "58ef0c82-402c-4fff-8421-83c5417475b1", 7732 - "to_change_id": "3a24a4a2-b4d0-4629-a29b-b33994d50e75", 7733 - "edge_type": "leads_to", 7734 - "weight": 1.0, 7735 - "rationale": "Implementation complete", 7736 - "created_at": "2025-12-26T20:20:24.693529800-05:00" 7737 - }, 7738 - { 7739 - "id": 308, 7740 - "from_node_id": 314, 7741 - "to_node_id": 317, 7742 - "from_change_id": "6837403f-1e30-4a71-bcf5-71db0cac6afc", 7743 - "to_change_id": "3a24a4a2-b4d0-4629-a29b-b33994d50e75", 7744 - "edge_type": "leads_to", 7745 - "weight": 1.0, 7746 - "rationale": "Goal achieved", 7747 - "created_at": "2025-12-26T20:20:26.885283800-05:00" 7748 - }, 7749 - { 7750 - "id": 309, 7751 - "from_node_id": 317, 7752 - "to_node_id": 318, 7753 - "from_change_id": "3a24a4a2-b4d0-4629-a29b-b33994d50e75", 7754 - "to_change_id": "371f788d-46df-4651-b338-f9310f8ae810", 7755 - "edge_type": "leads_to", 7756 - "weight": 1.0, 7757 - "rationale": "New issues found", 7758 - "created_at": "2025-12-26T20:37:06.303637800-05:00" 7759 - }, 7760 - { 7761 - "id": 310, 7762 - "from_node_id": 318, 7763 - "to_node_id": 319, 7764 - "from_change_id": "371f788d-46df-4651-b338-f9310f8ae810", 7765 - "to_change_id": "28681ed9-6d12-476e-a60d-291ee2034952", 7766 - "edge_type": "leads_to", 7767 - "weight": 1.0, 7768 - "rationale": "Root cause found", 7769 - "created_at": "2025-12-26T20:37:37.527168300-05:00" 7770 - }, 7771 - { 7772 - "id": 311, 7773 - "from_node_id": 319, 7774 - "to_node_id": 320, 7775 - "from_change_id": "28681ed9-6d12-476e-a60d-291ee2034952", 7776 - "to_change_id": "04f6a182-c5a1-4844-b186-24605a8e74a9", 7777 - "edge_type": "leads_to", 7778 - "weight": 1.0, 7779 - "rationale": "Action to fix", 7780 - "created_at": "2025-12-26T20:38:48.486046-05:00" 7781 - }, 7782 - { 7783 - "id": 312, 7784 - "from_node_id": 320, 7785 - "to_node_id": 321, 7786 - "from_change_id": "04f6a182-c5a1-4844-b186-24605a8e74a9", 7787 - "to_change_id": "ac843fbc-1953-4b61-8ef3-4c88c98572f5", 7788 - "edge_type": "leads_to", 7789 - "weight": 1.0, 7790 - "rationale": "Implementation complete", 7791 - "created_at": "2025-12-26T20:39:48.757903800-05:00" 7792 - }, 7793 - { 7794 - "id": 313, 7795 - "from_node_id": 321, 7796 - "to_node_id": 322, 7797 - "from_change_id": "ac843fbc-1953-4b61-8ef3-4c88c98572f5", 7798 - "to_change_id": "2e824556-15c7-4656-b771-1b85cc628edc", 7799 - "edge_type": "leads_to", 7800 - "weight": 1.0, 7801 - "rationale": "New UX issue found", 7802 - "created_at": "2025-12-26T20:51:58.153139700-05:00" 7803 - }, 7804 - { 7805 - "id": 314, 7806 - "from_node_id": 322, 7807 - "to_node_id": 323, 7808 - "from_change_id": "2e824556-15c7-4656-b771-1b85cc628edc", 7809 - "to_change_id": "88fc65bc-c2da-4df7-b79e-ba80d93e5b77", 7810 - "edge_type": "leads_to", 7811 - "weight": 1.0, 7812 - "rationale": "Implementation complete", 7813 - "created_at": "2025-12-26T20:55:40.014892600-05:00" 7814 - }, 7815 - { 7816 - "id": 315, 7817 - "from_node_id": 323, 7818 - "to_node_id": 324, 7819 - "from_change_id": "88fc65bc-c2da-4df7-b79e-ba80d93e5b77", 7820 - "to_change_id": "c941c916-0fcb-44d6-9786-dfd53447cebe", 7821 - "edge_type": "leads_to", 7822 - "weight": 1.0, 7823 - "rationale": "Committed to repository", 7824 - "created_at": "2025-12-26T20:58:50.561027500-05:00" 7825 - }, 7826 - { 7827 - "id": 316, 7828 - "from_node_id": 324, 7829 - "to_node_id": 325, 7830 - "from_change_id": "c941c916-0fcb-44d6-9786-dfd53447cebe", 7831 - "to_change_id": "e44f45f8-bac9-4a49-ac68-ac9d7d113226", 7832 - "edge_type": "leads_to", 7833 - "weight": 1.0, 7834 - "rationale": "User reported results showing 'none' before search completes - needed to keep user on loading screen", 7835 - "created_at": "2025-12-26T21:20:53.976836200-05:00" 7836 - }, 7837 - { 7838 - "id": 317, 7839 - "from_node_id": 325, 7840 - "to_node_id": 326, 7841 - "from_change_id": "e44f45f8-bac9-4a49-ac68-ac9d7d113226", 7842 - "to_change_id": "af76ea64-b0b1-4577-b521-4ec21cc555e1", 7843 - "edge_type": "leads_to", 7844 - "weight": 1.0, 7845 - "rationale": "User reported upload times showing 5 hours ahead - timezone offset issue", 7846 - "created_at": "2025-12-26T21:46:24.801578500-05:00" 7847 - }, 7848 - { 7849 - "id": 318, 7850 - "from_node_id": 326, 7851 - "to_node_id": 327, 7852 - "from_change_id": "af76ea64-b0b1-4577-b521-4ec21cc555e1", 7853 - "to_change_id": "ed9ceca3-e53e-430c-8f0f-386b287b0915", 7854 - "edge_type": "leads_to", 7855 - "weight": 1.0, 7856 - "rationale": "User reported slow dev server startup - 4.5s from Vite", 7857 - "created_at": "2025-12-26T21:57:18.723545100-05:00" 7858 - }, 7859 - { 7860 - "id": 319, 7861 - "from_node_id": 305, 7862 - "to_node_id": 325, 7863 - "from_change_id": "8ad6ef53-29a2-442e-b88f-9e0541634950", 7864 - "to_change_id": "e44f45f8-bac9-4a49-ac68-ac9d7d113226", 7865 - "edge_type": "leads_to", 7866 - "weight": 1.0, 7867 - "rationale": "Implemented loading screen for extension upload flow", 7868 - "created_at": "2025-12-27T15:22:53.706223600-05:00" 7869 - }, 7870 - { 7871 - "id": 320, 7872 - "from_node_id": 318, 7873 - "to_node_id": 326, 7874 - "from_change_id": "371f788d-46df-4651-b338-f9310f8ae810", 7875 - "to_change_id": "af76ea64-b0b1-4577-b521-4ec21cc555e1", 7876 - "edge_type": "leads_to", 7877 - "weight": 1.0, 7878 - "rationale": "Fixed timezone issue with TIMESTAMPTZ migration", 7879 - "created_at": "2025-12-27T15:22:56.160485500-05:00" 7880 - }, 7881 - { 7882 - "id": 321, 7883 - "from_node_id": 69, 7884 - "to_node_id": 67, 7885 - "from_change_id": "5754ca49-f09b-489f-a4b0-f412159f4cd4", 7886 - "to_change_id": "6aef16a0-0524-4ad9-a8ff-b335069c860d", 7887 - "edge_type": "leads_to", 7888 - "weight": 1.0, 7889 - "rationale": "Action to understand current duplicate types", 7890 - "created_at": "2025-12-27T15:36:45.647337400-05:00" 7891 - }, 7892 - { 7893 - "id": 322, 7894 - "from_node_id": 110, 7895 - "to_node_id": 117, 7896 - "from_change_id": "22b9c3db-9f95-45d7-a3ed-bdfac54677db", 7897 - "to_change_id": "d78b544a-8897-4149-ac48-4f35f6def985", 7898 - "edge_type": "leads_to", 7899 - "weight": 1.0, 7900 - "rationale": "Cleanup observation during codebase cleanup", 7901 - "created_at": "2025-12-27T15:36:47.932994300-05:00" 7902 - }, 7903 - { 7904 - "id": 323, 7905 - "from_node_id": 110, 7906 - "to_node_id": 183, 7907 - "from_change_id": "22b9c3db-9f95-45d7-a3ed-bdfac54677db", 7908 - "to_change_id": "6e1851e2-134c-4c8f-86af-5487fda7d05c", 7909 - "edge_type": "leads_to", 7910 - "weight": 1.0, 7911 - "rationale": "Removed build artifacts from git history", 7912 - "created_at": "2025-12-27T15:36:50.152456600-05:00" 7913 - }, 7914 - { 7915 - "id": 324, 7916 - "from_node_id": 184, 7917 - "to_node_id": 228, 7918 - "from_change_id": "919c42ef-9fae-473f-b755-ee32d8999204", 7919 - "to_change_id": "7958ec7b-ff18-41d4-b1e1-fc9fa5603a1b", 7920 - "edge_type": "leads_to", 7921 - "weight": 1.0, 7922 - "rationale": "Installing pnpm for monorepo structure", 7923 - "created_at": "2025-12-27T15:36:52.522283200-05:00" 7924 - }, 7925 - { 7926 - "id": 325, 7927 - "from_node_id": 258, 7928 - "to_node_id": 262, 7929 - "from_change_id": "b8c6cd90-7f32-461e-aad5-537cc1cbfafe", 7930 - "to_change_id": "b8097a68-a63f-4cb6-aeac-2ed746e90126", 7931 - "edge_type": "leads_to", 7932 - "weight": 1.0, 7933 - "rationale": "Discovered extension-import endpoint during debugging", 7934 - "created_at": "2025-12-27T15:36:55.150261400-05:00" 7935 - }, 7936 - { 7937 - "id": 326, 7938 - "from_node_id": 258, 7939 - "to_node_id": 263, 7940 - "from_change_id": "b8c6cd90-7f32-461e-aad5-537cc1cbfafe", 7941 - "to_change_id": "b5109344-a5d3-43b3-b743-b06730453514", 7942 - "edge_type": "leads_to", 7943 - "weight": 1.0, 7944 - "rationale": "Discovered routing issue during debugging", 7945 - "created_at": "2025-12-27T15:36:57.690344600-05:00" 7946 - }, 7947 - { 7948 - "id": 327, 7949 - "from_node_id": 270, 7950 - "to_node_id": 275, 7951 - "from_change_id": "8cf80c58-e909-4f0b-85e8-ac15d7cf3640", 7952 - "to_change_id": "dcc9f401-1a68-479e-97de-7a04e5597e00", 7953 - "edge_type": "leads_to", 7954 - "weight": 1.0, 7955 - "rationale": "Discovered CORS blocking health check", 7956 - "created_at": "2025-12-27T15:37:00.388733200-05:00" 7957 - }, 7958 - { 7959 - "id": 328, 7960 - "from_node_id": 278, 7961 - "to_node_id": 282, 7962 - "from_change_id": "fa11e7d7-ac30-4d0e-bc8a-d2332f724d92", 7963 - "to_change_id": "206347b5-4178-43dd-bb05-657b3788a6b0", 7964 - "edge_type": "leads_to", 7965 - "weight": 1.0, 7966 - "rationale": "Refactoring extension flow to match upload behavior", 7967 - "created_at": "2025-12-27T15:37:02.697547600-05:00" 7968 - }, 7969 - { 7970 - "id": 329, 7971 - "from_node_id": 278, 7972 - "to_node_id": 283, 7973 - "from_change_id": "fa11e7d7-ac30-4d0e-bc8a-d2332f724d92", 7974 - "to_change_id": "e3adddaf-9126-4bfa-8d75-aa8b94323077", 7975 - "edge_type": "leads_to", 7976 - "weight": 1.0, 7977 - "rationale": "Observation after implementing auth and upload creation", 7978 - "created_at": "2025-12-27T15:37:04.961909600-05:00" 7979 - }, 7980 - { 7981 - "id": 330, 7982 - "from_node_id": 328, 7983 - "to_node_id": 329, 7984 - "from_change_id": "7823be1a-fca9-4cb5-9e62-dfbc8cb71e55", 7985 - "to_change_id": "c839ec54-b098-4030-8ff4-857549b17363", 7986 - "edge_type": "leads_to", 7987 - "weight": 1.0, 7988 - "rationale": "Analysis of what went wrong during graph maintenance", 7989 - "created_at": "2025-12-27T15:40:25.442264900-05:00" 7990 - }, 7991 - { 7992 - "id": 331, 7993 - "from_node_id": 329, 7994 - "to_node_id": 330, 7995 - "from_change_id": "c839ec54-b098-4030-8ff4-857549b17363", 7996 - "to_change_id": "1f554b87-3775-450b-a3a1-b23eeebc7e38", 7997 - "edge_type": "leads_to", 7998 - "weight": 1.0, 7999 - "rationale": "Action to prevent future graph integrity issues", 8000 - "created_at": "2025-12-27T15:41:06.239618300-05:00" 8001 - }, 8002 - { 8003 - "id": 332, 8004 - "from_node_id": 330, 8005 - "to_node_id": 331, 8006 - "from_change_id": "1f554b87-3775-450b-a3a1-b23eeebc7e38", 8007 - "to_change_id": "8c746dd6-d571-4446-8a53-af6279fc9c21", 8008 - "edge_type": "leads_to", 8009 - "weight": 1.0, 8010 - "rationale": "Successfully completed documentation updates", 8011 - "created_at": "2025-12-27T15:47:51.427087400-05:00" 8012 - }, 8013 - { 8014 - "id": 333, 8015 - "from_node_id": 331, 8016 - "to_node_id": 332, 8017 - "from_change_id": "8c746dd6-d571-4446-8a53-af6279fc9c21", 8018 - "to_change_id": "c4338df4-a22f-4dd5-b60c-84c7cd1c0c5c", 8019 - "edge_type": "leads_to", 8020 - "weight": 1.0, 8021 - "rationale": "Git commit documenting the improvements", 8022 - "created_at": "2025-12-27T15:48:49.907152400-05:00" 8023 - }, 8024 - { 8025 - "id": 334, 8026 - "from_node_id": 328, 8027 - "to_node_id": 333, 8028 - "from_change_id": "7823be1a-fca9-4cb5-9e62-dfbc8cb71e55", 8029 - "to_change_id": "0a0375e9-bcef-4459-b9f1-f5868276e8e4", 8030 - "edge_type": "leads_to", 8031 - "weight": 1.0, 8032 - "rationale": "New goal from user request", 8033 - "created_at": "2025-12-27T15:50:58.493301500-05:00" 8034 - }, 8035 - { 8036 - "id": 335, 8037 - "from_node_id": 333, 8038 - "to_node_id": 334, 8039 - "from_change_id": "0a0375e9-bcef-4459-b9f1-f5868276e8e4", 8040 - "to_change_id": "fe108b87-356f-4c02-85cb-7260e175d8ad", 8041 - "edge_type": "leads_to", 8042 - "weight": 1.0, 8043 - "rationale": "First step to review markdown files", 8044 - "created_at": "2025-12-27T15:51:25.165313400-05:00" 8045 - }, 8046 - { 8047 - "id": 336, 8048 - "from_node_id": 334, 8049 - "to_node_id": 335, 8050 - "from_change_id": "fe108b87-356f-4c02-85cb-7260e175d8ad", 8051 - "to_change_id": "3aac85f7-c11c-48f6-b9da-2cd333605fb2", 8052 - "edge_type": "leads_to", 8053 - "weight": 1.0, 8054 - "rationale": "Analysis complete with findings", 8055 - "created_at": "2025-12-27T15:52:08.782592-05:00" 8056 - }, 8057 - { 8058 - "id": 337, 8059 - "from_node_id": 335, 8060 - "to_node_id": 336, 8061 - "from_change_id": "3aac85f7-c11c-48f6-b9da-2cd333605fb2", 8062 - "to_change_id": "d1a23826-c660-4f2a-bdc0-bcbbce9d0293", 8063 - "edge_type": "leads_to", 8064 - "weight": 1.0, 8065 - "rationale": "Need to decide update approach", 8066 - "created_at": "2025-12-27T15:52:32.515520400-05:00" 8067 - }, 8068 - { 8069 - "id": 338, 8070 - "from_node_id": 336, 8071 - "to_node_id": 337, 8072 - "from_change_id": "d1a23826-c660-4f2a-bdc0-bcbbce9d0293", 8073 - "to_change_id": "28eeefda-3813-4777-8006-924a9b030c61", 8074 - "edge_type": "leads_to", 8075 - "weight": 1.0, 8076 - "rationale": "User decision", 8077 - "created_at": "2025-12-27T15:54:33.702061900-05:00" 8078 - }, 8079 - { 8080 - "id": 339, 8081 - "from_node_id": 337, 8082 - "to_node_id": 338, 8083 - "from_change_id": "28eeefda-3813-4777-8006-924a9b030c61", 8084 - "to_change_id": "594942d8-4981-4557-9687-522d51e86ecb", 8085 - "edge_type": "leads_to", 8086 - "weight": 1.0, 8087 - "rationale": "First file to update", 8088 - "created_at": "2025-12-27T15:54:38.126450100-05:00" 8089 - }, 8090 - { 8091 - "id": 340, 8092 - "from_node_id": 337, 8093 - "to_node_id": 339, 8094 - "from_change_id": "28eeefda-3813-4777-8006-924a9b030c61", 8095 - "to_change_id": "4c8c5b0d-468b-4ad6-80e9-02141949aba9", 8096 - "edge_type": "leads_to", 8097 - "weight": 1.0, 8098 - "rationale": "Second file to update", 8099 - "created_at": "2025-12-27T15:55:51.716239-05:00" 8100 - }, 8101 - { 8102 - "id": 341, 8103 - "from_node_id": 337, 8104 - "to_node_id": 340, 8105 - "from_change_id": "28eeefda-3813-4777-8006-924a9b030c61", 8106 - "to_change_id": "4e3987a4-538f-4912-b6ce-39c5971e0966", 8107 - "edge_type": "leads_to", 8108 - "weight": 1.0, 8109 - "rationale": "Third file to update", 8110 - "created_at": "2025-12-27T15:57:16.830452200-05:00" 8111 - }, 8112 - { 8113 - "id": 342, 8114 - "from_node_id": 337, 8115 - "to_node_id": 341, 8116 - "from_change_id": "28eeefda-3813-4777-8006-924a9b030c61", 8117 - "to_change_id": "42bf8d79-2c24-420f-b8b8-89273fecc30d", 8118 - "edge_type": "leads_to", 8119 - "weight": 1.0, 8120 - "rationale": "Fourth and final file to update", 8121 - "created_at": "2025-12-27T15:58:25.682627400-05:00" 8122 - }, 8123 - { 8124 - "id": 343, 8125 - "from_node_id": 337, 8126 - "to_node_id": 342, 8127 - "from_change_id": "28eeefda-3813-4777-8006-924a9b030c61", 8128 - "to_change_id": "a6d1f3fb-650d-4227-b1dc-ddb24810464c", 8129 - "edge_type": "leads_to", 8130 - "weight": 1.0, 8131 - "rationale": "All updates completed successfully", 8132 - "created_at": "2025-12-27T15:59:43.630208500-05:00" 8133 - }, 8134 - { 8135 - "id": 344, 8136 - "from_node_id": 342, 8137 - "to_node_id": 343, 8138 - "from_change_id": "a6d1f3fb-650d-4227-b1dc-ddb24810464c", 8139 - "to_change_id": "9e0fcead-ea30-4b31-974b-4e07f7fc6787", 8140 - "edge_type": "leads_to", 8141 - "weight": 1.0, 8142 - "rationale": "Git commit with all documentation updates", 8143 - "created_at": "2025-12-27T16:02:15.712335700-05:00" 8144 - }, 8145 - { 8146 - "id": 345, 8147 - "from_node_id": 344, 8148 - "to_node_id": 345, 8149 - "from_change_id": "2a06900e-ea62-4adf-81d5-7f0cf1a29b31", 8150 - "to_change_id": "0ef352ed-538b-4632-8b62-ebb17603f944", 8151 - "edge_type": "leads_to", 8152 - "weight": 1.0, 8153 - "rationale": "Installation step for Tailwind integration", 8154 - "created_at": "2025-12-27T18:00:42.787737600-05:00" 8155 - }, 8156 - { 8157 - "id": 346, 8158 - "from_node_id": 344, 8159 - "to_node_id": 346, 8160 - "from_change_id": "2a06900e-ea62-4adf-81d5-7f0cf1a29b31", 8161 - "to_change_id": "888e6ad0-5002-4cdb-b35e-f4214ca07dfa", 8162 - "edge_type": "leads_to", 8163 - "weight": 1.0, 8164 - "rationale": "Configuration step for Tailwind", 8165 - "created_at": "2025-12-27T18:01:28.695956-05:00" 8166 - }, 8167 - { 8168 - "id": 347, 8169 - "from_node_id": 344, 8170 - "to_node_id": 347, 8171 - "from_change_id": "2a06900e-ea62-4adf-81d5-7f0cf1a29b31", 8172 - "to_change_id": "fae7a634-d921-4b6f-9620-0c58d88b863e", 8173 - "edge_type": "leads_to", 8174 - "weight": 1.0, 8175 - "rationale": "Build process integration", 8176 - "created_at": "2025-12-27T18:01:51.815468700-05:00" 8177 - }, 8178 - { 8179 - "id": 348, 8180 - "from_node_id": 344, 8181 - "to_node_id": 348, 8182 - "from_change_id": "2a06900e-ea62-4adf-81d5-7f0cf1a29b31", 8183 - "to_change_id": "c25a8f4b-8bf1-4a33-bef9-3731dfd83627", 8184 - "edge_type": "leads_to", 8185 - "weight": 1.0, 8186 - "rationale": "CSS conversion step", 8187 - "created_at": "2025-12-27T18:02:43.312580-05:00" 8188 - }, 8189 - { 8190 - "id": 349, 8191 - "from_node_id": 344, 8192 - "to_node_id": 349, 8193 - "from_change_id": "2a06900e-ea62-4adf-81d5-7f0cf1a29b31", 8194 - "to_change_id": "c65ee3d9-62a0-47aa-870a-f6422ff2536a", 8195 - "edge_type": "leads_to", 8196 - "weight": 1.0, 8197 - "rationale": "HTML conversion step", 8198 - "created_at": "2025-12-27T18:03:01.642571400-05:00" 8199 - }, 8200 - { 8201 - "id": 350, 8202 - "from_node_id": 344, 8203 - "to_node_id": 350, 8204 - "from_change_id": "2a06900e-ea62-4adf-81d5-7f0cf1a29b31", 8205 - "to_change_id": "8136e615-5baa-4fe5-9a7d-d672ff1a6f85", 8206 - "edge_type": "leads_to", 8207 - "weight": 1.0, 8208 - "rationale": "Final outcome of Tailwind integration", 8209 - "created_at": "2025-12-27T18:07:51.011406300-05:00" 8210 - }, 8211 - { 8212 - "id": 351, 8213 - "from_node_id": 344, 8214 - "to_node_id": 351, 8215 - "from_change_id": "2a06900e-ea62-4adf-81d5-7f0cf1a29b31", 8216 - "to_change_id": "9468bcb3-78ec-4dae-8d8f-968ba6f5b3fe", 8217 - "edge_type": "leads_to", 8218 - "weight": 1.0, 8219 - "rationale": "Git commit for Tailwind integration", 8220 - "created_at": "2025-12-27T18:38:58.347778400-05:00" 8221 - }, 8222 - { 8223 - "id": 352, 8224 - "from_node_id": 352, 8225 - "to_node_id": 353, 8226 - "from_change_id": "b852ce18-1747-4c26-a65e-acfbbed2b1a5", 8227 - "to_change_id": "eaed6e9b-9f16-4b45-8783-44ea2ea1f2a9", 8228 - "edge_type": "leads_to", 8229 - "weight": 1.0, 8230 - "rationale": "Initial analysis of issues", 8231 - "created_at": "2025-12-27T22:06:21.516165300-05:00" 8232 - }, 8233 - { 8234 - "id": 353, 8235 - "from_node_id": 352, 8236 - "to_node_id": 354, 8237 - "from_change_id": "b852ce18-1747-4c26-a65e-acfbbed2b1a5", 8238 - "to_change_id": "d66fc83e-9737-4047-8ce2-e2ba857aeea9", 8239 - "edge_type": "leads_to", 8240 - "weight": 1.0, 8241 - "rationale": "Need to decide dark mode approach", 8242 - "created_at": "2025-12-27T22:07:03.103941500-05:00" 8243 - }, 8244 - { 8245 - "id": 354, 8246 - "from_node_id": 354, 8247 - "to_node_id": 355, 8248 - "from_change_id": "d66fc83e-9737-4047-8ce2-e2ba857aeea9", 8249 - "to_change_id": "76e2a379-7803-4c82-8013-be6b62f2d360", 8250 - "edge_type": "leads_to", 8251 - "weight": 1.0, 8252 - "rationale": "Decision outcome", 8253 - "created_at": "2025-12-27T22:07:06.239151500-05:00" 8254 - }, 8255 - { 8256 - "id": 355, 8257 - "from_node_id": 352, 8258 - "to_node_id": 356, 8259 - "from_change_id": "b852ce18-1747-4c26-a65e-acfbbed2b1a5", 8260 - "to_change_id": "df681aa8-e470-4ead-a0d2-a4095febfa3d", 8261 - "edge_type": "leads_to", 8262 - "weight": 1.0, 8263 - "rationale": "Implementation of dark mode fix", 8264 - "created_at": "2025-12-27T22:07:26.713411300-05:00" 8265 - }, 8266 - { 8267 - "id": 356, 8268 - "from_node_id": 352, 8269 - "to_node_id": 357, 8270 - "from_change_id": "b852ce18-1747-4c26-a65e-acfbbed2b1a5", 8271 - "to_change_id": "57060303-5a30-4f11-a752-a02376df5ea7", 8272 - "edge_type": "leads_to", 8273 - "weight": 1.0, 8274 - "rationale": "Implementation of server message fix", 8275 - "created_at": "2025-12-27T22:07:51.662925600-05:00" 8276 - }, 8277 - { 8278 - "id": 357, 8279 - "from_node_id": 352, 8280 - "to_node_id": 358, 8281 - "from_change_id": "b852ce18-1747-4c26-a65e-acfbbed2b1a5", 8282 - "to_change_id": "fc211ac7-7a1a-4b69-835a-992c354e8237", 8283 - "edge_type": "leads_to", 8284 - "weight": 1.0, 8285 - "rationale": "Final outcome of fixes", 8286 - "created_at": "2025-12-27T22:09:30.425884400-05:00" 8287 - }, 8288 - { 8289 - "id": 358, 8290 - "from_node_id": 352, 8291 - "to_node_id": 359, 8292 - "from_change_id": "b852ce18-1747-4c26-a65e-acfbbed2b1a5", 8293 - "to_change_id": "4a7d5885-1713-4ba7-ad13-bb12b58c9410", 8294 - "edge_type": "leads_to", 8295 - "weight": 1.0, 8296 - "rationale": "Git commit for fixes", 8297 - "created_at": "2025-12-27T22:10:27.225192300-05:00" 8298 - }, 8299 - { 8300 - "id": 359, 8301 - "from_node_id": 360, 8302 - "to_node_id": 361, 8303 - "from_change_id": "706d5a7f-08ed-43f7-aee5-0bed28d9402a", 8304 - "to_change_id": "aecf2327-d20d-4c6c-b6b0-06ccf26a2b27", 8305 - "edge_type": "leads_to", 8306 - "weight": 1.0, 8307 - "rationale": "Root cause analysis", 8308 - "created_at": "2025-12-27T22:23:47.445630900-05:00" 8309 - }, 8310 - { 8311 - "id": 360, 8312 - "from_node_id": 360, 8313 - "to_node_id": 362, 8314 - "from_change_id": "706d5a7f-08ed-43f7-aee5-0bed28d9402a", 8315 - "to_change_id": "e897db97-44d8-4993-b4c3-0d829265b2f8", 8316 - "edge_type": "leads_to", 8317 - "weight": 1.0, 8318 - "rationale": "Rebuilt dev version", 8319 - "created_at": "2025-12-27T22:24:19.438433600-05:00" 8320 - }, 8321 - { 8322 - "id": 361, 8323 - "from_node_id": 360, 8324 - "to_node_id": 363, 8325 - "from_change_id": "706d5a7f-08ed-43f7-aee5-0bed28d9402a", 8326 - "to_change_id": "2c62bfa3-d148-4448-8c2b-d0cf1e94ceb0", 8327 - "edge_type": "leads_to", 8328 - "weight": 1.0, 8329 - "rationale": "Root cause: CORS configuration", 8330 - "created_at": "2025-12-27T22:24:53.741163700-05:00" 8331 - }, 8332 - { 8333 - "id": 362, 8334 - "from_node_id": 360, 8335 - "to_node_id": 364, 8336 - "from_change_id": "706d5a7f-08ed-43f7-aee5-0bed28d9402a", 8337 - "to_change_id": "560d6bea-47ec-408d-919b-15ca7198aac9", 8338 - "edge_type": "leads_to", 8339 - "weight": 1.0, 8340 - "rationale": "Implementation of CORS fix", 8341 - "created_at": "2025-12-27T22:25:24.843330900-05:00" 8342 - }, 8343 - { 8344 - "id": 363, 8345 - "from_node_id": 360, 8346 - "to_node_id": 365, 8347 - "from_change_id": "706d5a7f-08ed-43f7-aee5-0bed28d9402a", 8348 - "to_change_id": "3ef0c9e9-aa40-4914-a5f4-32bcfaf68d04", 8349 - "edge_type": "leads_to", 8350 - "weight": 1.0, 8351 - "rationale": "CORS fix completed", 8352 - "created_at": "2025-12-27T22:41:44.160528300-05:00" 8353 - }, 8354 - { 8355 - "id": 364, 8356 - "from_node_id": 360, 8357 - "to_node_id": 366, 8358 - "from_change_id": "706d5a7f-08ed-43f7-aee5-0bed28d9402a", 8359 - "to_change_id": "77b7ed7e-a113-41f6-a677-50d376f3f008", 8360 - "edge_type": "leads_to", 8361 - "weight": 1.0, 8362 - "rationale": "Git commit for CORS fixes", 8363 - "created_at": "2025-12-27T22:42:51.663598100-05:00" 8364 - }, 8365 - { 8366 - "id": 365, 8367 - "from_node_id": 367, 8368 - "to_node_id": 368, 8369 - "from_change_id": "df6abf7a-e7a4-45f3-8485-b933319416d9", 8370 - "to_change_id": "79721edf-aa05-4580-8c28-7d20941ef155", 8371 - "edge_type": "leads_to", 8372 - "weight": 1.0, 8373 - "rationale": "Analysis step for Firefox compatibility", 8374 - "created_at": "2025-12-28T18:10:09.484445500-05:00" 8375 - }, 8376 - { 8377 - "id": 366, 8378 - "from_node_id": 368, 8379 - "to_node_id": 369, 8380 - "from_change_id": "79721edf-aa05-4580-8c28-7d20941ef155", 8381 - "to_change_id": "783841d0-c096-48f6-be18-193a9dcc7d4b", 8382 - "edge_type": "leads_to", 8383 - "weight": 1.0, 8384 - "rationale": "Detailed analysis of compatibility issues", 8385 - "created_at": "2025-12-28T18:10:49.163552300-05:00" 8386 - }, 8387 - { 8388 - "id": 367, 8389 - "from_node_id": 369, 8390 - "to_node_id": 370, 8391 - "from_change_id": "783841d0-c096-48f6-be18-193a9dcc7d4b", 8392 - "to_change_id": "fd2d5b63-c26c-4592-89a6-3ccb4234c3c6", 8393 - "edge_type": "leads_to", 8394 - "weight": 1.0, 8395 - "rationale": "Need to decide implementation strategy", 8396 - "created_at": "2025-12-28T18:10:51.434960600-05:00" 8397 - }, 8398 - { 8399 - "id": 368, 8400 - "from_node_id": 370, 8401 - "to_node_id": 371, 8402 - "from_change_id": "fd2d5b63-c26c-4592-89a6-3ccb4234c3c6", 8403 - "to_change_id": "159906da-984f-4a1d-a1a6-98e0fc0cf369", 8404 - "edge_type": "leads_to", 8405 - "weight": 1.0, 8406 - "rationale": "Option A", 8407 - "created_at": "2025-12-28T18:11:07.060637-05:00" 8408 - }, 8409 - { 8410 - "id": 369, 8411 - "from_node_id": 370, 8412 - "to_node_id": 372, 8413 - "from_change_id": "fd2d5b63-c26c-4592-89a6-3ccb4234c3c6", 8414 - "to_change_id": "df5e42e6-53c1-4b30-8b6f-f2385cd9e247", 8415 - "edge_type": "leads_to", 8416 - "weight": 1.0, 8417 - "rationale": "Option B", 8418 - "created_at": "2025-12-28T18:11:09.223792400-05:00" 8419 - }, 8420 - { 8421 - "id": 370, 8422 - "from_node_id": 370, 8423 - "to_node_id": 373, 8424 - "from_change_id": "fd2d5b63-c26c-4592-89a6-3ccb4234c3c6", 8425 - "to_change_id": "7bb58202-7a9b-4e8b-8b9e-927e5106bce7", 8426 - "edge_type": "leads_to", 8427 - "weight": 1.0, 8428 - "rationale": "Option C", 8429 - "created_at": "2025-12-28T18:11:11.439827800-05:00" 8430 - }, 8431 - { 8432 - "id": 371, 8433 - "from_node_id": 370, 8434 - "to_node_id": 374, 8435 - "from_change_id": "fd2d5b63-c26c-4592-89a6-3ccb4234c3c6", 8436 - "to_change_id": "d41b29e0-cd48-4dac-a6c8-c6179612702e", 8437 - "edge_type": "leads_to", 8438 - "weight": 1.0, 8439 - "rationale": "User selected option 1", 8440 - "created_at": "2025-12-28T19:04:26.708742600-05:00" 8441 - }, 8442 - { 8443 - "id": 372, 8444 - "from_node_id": 374, 8445 - "to_node_id": 375, 8446 - "from_change_id": "d41b29e0-cd48-4dac-a6c8-c6179612702e", 8447 - "to_change_id": "5bb34b8b-aec4-4f84-993e-eb9bf7a2d13f", 8448 - "edge_type": "leads_to", 8449 - "weight": 1.0, 8450 - "rationale": "Implementation based on decision", 8451 - "created_at": "2025-12-28T19:08:16.677078600-05:00" 8452 - }, 8453 - { 8454 - "id": 373, 8455 - "from_node_id": 375, 8456 - "to_node_id": 376, 8457 - "from_change_id": "5bb34b8b-aec4-4f84-993e-eb9bf7a2d13f", 8458 - "to_change_id": "644181ee-5a44-4967-9657-e9dd5f648c5e", 8459 - "edge_type": "leads_to", 8460 - "weight": 1.0, 8461 - "rationale": "Implementation completed successfully", 8462 - "created_at": "2025-12-28T19:14:24.961595600-05:00" 8463 - }, 8464 - { 8465 - "id": 374, 8466 - "from_node_id": 377, 8467 - "to_node_id": 378, 8468 - "from_change_id": "1dffa024-413f-4a95-b069-66db350abfaa", 8469 - "to_change_id": "9d5626d2-a9ae-42aa-8fda-be3c7528156f", 8470 - "edge_type": "leads_to", 8471 - "weight": 1.0, 8472 - "rationale": "First observation about debugging", 8473 - "created_at": "2025-12-28T20:15:13.725635900-05:00" 8474 - }, 8475 - { 8476 - "id": 375, 8477 - "from_node_id": 378, 8478 - "to_node_id": 379, 8479 - "from_change_id": "9d5626d2-a9ae-42aa-8fda-be3c7528156f", 8480 - "to_change_id": "7a5af3fe-8567-4f1c-85cd-e47891704974", 8481 - "edge_type": "leads_to", 8482 - "weight": 1.0, 8483 - "rationale": "Hypothesis about root causes", 8484 - "created_at": "2025-12-28T20:15:33.187041700-05:00" 8485 - }, 8486 - { 8487 - "id": 376, 8488 - "from_node_id": 379, 8489 - "to_node_id": 380, 8490 - "from_change_id": "7a5af3fe-8567-4f1c-85cd-e47891704974", 8491 - "to_change_id": "9c197aae-18d5-46ae-87e7-82c240c8f313", 8492 - "edge_type": "leads_to", 8493 - "weight": 1.0, 8494 - "rationale": "Fix based on hypothesis", 8495 - "created_at": "2025-12-28T20:16:14.104406300-05:00" 8496 - }, 8497 - { 8498 - "id": 377, 8499 - "from_node_id": 380, 8500 - "to_node_id": 381, 8501 - "from_change_id": "9c197aae-18d5-46ae-87e7-82c240c8f313", 8502 - "to_change_id": "485a03b0-8a25-4fdf-a8e2-9d3a25c8edf8", 8503 - "edge_type": "leads_to", 8504 - "weight": 1.0, 8505 - "rationale": "Fix implemented and tested", 8506 - "created_at": "2025-12-28T20:16:43.953511400-05:00" 8507 - }, 8508 - { 8509 - "id": 378, 8510 - "from_node_id": 381, 8511 - "to_node_id": 382, 8512 - "from_change_id": "485a03b0-8a25-4fdf-a8e2-9d3a25c8edf8", 8513 - "to_change_id": "35b13d37-0228-435f-a4bc-c5c42811fec3", 8514 - "edge_type": "leads_to", 8515 - "weight": 1.0, 8516 - "rationale": "Root cause identified from error logs", 8517 - "created_at": "2025-12-28T20:17:25.488041200-05:00" 8518 - }, 8519 - { 8520 - "id": 379, 8521 - "from_node_id": 382, 8522 - "to_node_id": 383, 8523 - "from_change_id": "35b13d37-0228-435f-a4bc-c5c42811fec3", 8524 - "to_change_id": "adc120cd-e56d-400a-9b3e-8207880378c3", 8525 - "edge_type": "leads_to", 8526 - "weight": 1.0, 8527 - "rationale": "Fix for CORS issue", 8528 - "created_at": "2025-12-28T20:19:41.484076700-05:00" 8529 - }, 8530 - { 8531 - "id": 380, 8532 - "from_node_id": 383, 8533 - "to_node_id": 384, 8534 - "from_change_id": "adc120cd-e56d-400a-9b3e-8207880378c3", 8535 - "to_change_id": "0f77bfd9-590f-4f1e-be08-78a9deef6d8a", 8536 - "edge_type": "leads_to", 8537 - "weight": 1.0, 8538 - "rationale": "Implementation complete", 8539 - "created_at": "2025-12-28T20:19:56.872404900-05:00" 8540 - }, 8541 - { 8542 - "id": 381, 8543 - "from_node_id": 384, 8544 - "to_node_id": 385, 8545 - "from_change_id": "0f77bfd9-590f-4f1e-be08-78a9deef6d8a", 8546 - "to_change_id": "cc0910f0-2381-4aee-bb5d-397cb0f804d1", 8547 - "edge_type": "leads_to", 8548 - "weight": 1.0, 8549 - "rationale": "New error reveals real issue", 8550 - "created_at": "2025-12-28T20:27:34.035766400-05:00" 8551 - }, 8552 - { 8553 - "id": 382, 8554 - "from_node_id": 385, 8555 - "to_node_id": 386, 8556 - "from_change_id": "cc0910f0-2381-4aee-bb5d-397cb0f804d1", 8557 - "to_change_id": "ad4a5ca7-15d1-4776-8ede-6b615613f6e1", 8558 - "edge_type": "leads_to", 8559 - "weight": 1.0, 8560 - "rationale": "Fix for Firefox extension origin", 8561 - "created_at": "2025-12-28T20:28:33.839045700-05:00" 8562 - }, 8563 - { 8564 - "id": 383, 8565 - "from_node_id": 386, 8566 - "to_node_id": 387, 8567 - "from_change_id": "ad4a5ca7-15d1-4776-8ede-6b615613f6e1", 8568 - "to_change_id": "cffdee0f-8535-4d88-83ed-fdf6101f7ac3", 8569 - "edge_type": "leads_to", 8570 - "weight": 1.0, 8571 - "rationale": "Complete fix implemented", 8572 - "created_at": "2025-12-28T20:30:09.745415200-05:00" 8573 - }, 8574 - { 8575 - "id": 384, 8576 - "from_node_id": 387, 8577 - "to_node_id": 388, 8578 - "from_change_id": "cffdee0f-8535-4d88-83ed-fdf6101f7ac3", 8579 - "to_change_id": "0ada864e-be98-4a2f-a14e-ffd3eea9aaa9", 8580 - "edge_type": "leads_to", 8581 - "weight": 1.0, 8582 - "rationale": "New issue discovered in health check", 8583 - "created_at": "2025-12-28T20:37:24.355885500-05:00" 8584 - }, 8585 - { 8586 - "id": 385, 8587 - "from_node_id": 388, 8588 - "to_node_id": 389, 8589 - "from_change_id": "0ada864e-be98-4a2f-a14e-ffd3eea9aaa9", 8590 - "to_change_id": "f522d5b2-c325-4f34-9f27-b8ea5c50618d", 8591 - "edge_type": "leads_to", 8592 - "weight": 1.0, 8593 - "rationale": "Fix implemented", 8594 - "created_at": "2025-12-28T20:38:22.044029100-05:00" 8595 - }, 8596 - { 8597 - "id": 386, 8598 - "from_node_id": 389, 8599 - "to_node_id": 390, 8600 - "from_change_id": "f522d5b2-c325-4f34-9f27-b8ea5c50618d", 8601 - "to_change_id": "cfdcf45b-47b3-4239-8053-417bd31957ed", 8602 - "edge_type": "leads_to", 8603 - "weight": 1.0, 8604 - "rationale": "Issue persists - need to debug headers", 8605 - "created_at": "2025-12-28T20:48:14.949702100-05:00" 8606 - }, 8607 - { 8608 - "id": 387, 8609 - "from_node_id": 390, 8610 - "to_node_id": 391, 8611 - "from_change_id": "cfdcf45b-47b3-4239-8053-417bd31957ed", 8612 - "to_change_id": "2b53a419-9a47-4285-9a12-9bdfaeeb9ff0", 8613 - "edge_type": "leads_to", 8614 - "weight": 1.0, 8615 - "rationale": "Root cause identified from debug logs", 8616 - "created_at": "2025-12-28T20:55:34.094943700-05:00" 8617 - }, 8618 - { 8619 - "id": 388, 8620 - "from_node_id": 391, 8621 - "to_node_id": 392, 8622 - "from_change_id": "2b53a419-9a47-4285-9a12-9bdfaeeb9ff0", 8623 - "to_change_id": "c941d136-3405-483d-bf34-7fb011f6d072", 8624 - "edge_type": "leads_to", 8625 - "weight": 1.0, 8626 - "rationale": "Fix implemented", 8627 - "created_at": "2025-12-28T20:57:35.872426900-05:00" 8628 - }, 8629 - { 8630 - "id": 389, 8631 - "from_node_id": 392, 8632 - "to_node_id": 393, 8633 - "from_change_id": "c941d136-3405-483d-bf34-7fb011f6d072", 8634 - "to_change_id": "aafd9977-8800-4152-9f7f-b817db6df573", 8635 - "edge_type": "leads_to", 8636 - "weight": 1.0, 8637 - "rationale": "Complete fix with cleanup", 8638 - "created_at": "2025-12-28T21:37:27.704906300-05:00" 8639 - }, 8640 - { 8641 - "id": 390, 8642 - "from_node_id": 393, 8643 - "to_node_id": 394, 8644 - "from_change_id": "aafd9977-8800-4152-9f7f-b817db6df573", 8645 - "to_change_id": "3b0dea7a-c3cd-45a8-ba1a-f1040aa4e1d9", 8646 - "edge_type": "leads_to", 8647 - "weight": 1.0, 8648 - "rationale": "New issue - cookie partitioning", 8649 - "created_at": "2025-12-28T21:46:48.417911400-05:00" 8650 - }, 8651 - { 8652 - "id": 391, 8653 - "from_node_id": 394, 8654 - "to_node_id": 395, 8655 - "from_change_id": "3b0dea7a-c3cd-45a8-ba1a-f1040aa4e1d9", 8656 - "to_change_id": "8a93413f-a09c-4cc1-8693-4fe90dc055c4", 8657 - "edge_type": "leads_to", 8658 - "weight": 1.0, 8659 - "rationale": "Workaround using browser.cookies API", 8660 - "created_at": "2025-12-28T21:52:52.704792400-05:00" 8661 - }, 8662 - { 8663 - "id": 392, 8664 - "from_node_id": 395, 8665 - "to_node_id": 396, 8666 - "from_change_id": "8a93413f-a09c-4cc1-8693-4fe90dc055c4", 8667 - "to_change_id": "864dd973-5f15-4e31-a7da-c548dbbe1f0e", 8668 - "edge_type": "leads_to", 8669 - "weight": 1.0, 8670 - "rationale": "Complete workaround", 8671 - "created_at": "2025-12-28T22:51:33.159870400-05:00" 8672 - } 8673 - ] 8674 - }
-82
docs/index.html
··· 1 - <!DOCTYPE html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="UTF-8" /> 5 - <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> 6 - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 7 - <meta name="description" content="Deciduous - Decision Graph Viewer" /> 8 - <title>Deciduous - Decision Graph</title> 9 - <script type="module" crossorigin>function dk(e,t){for(var n=0;n<t.length;n++){const r=t[n];if(typeof r!="string"&&!Array.isArray(r)){for(const i in r)if(i!=="default"&&!(i in e)){const o=Object.getOwnPropertyDescriptor(r,i);o&&Object.defineProperty(e,i,o.get?o:{enumerable:!0,get:()=>r[i]})}}}return Object.freeze(Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}))}(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))r(i);new MutationObserver(i=>{for(const o of i)if(o.type==="childList")for(const a of o.addedNodes)a.tagName==="LINK"&&a.rel==="modulepreload"&&r(a)}).observe(document,{childList:!0,subtree:!0});function n(i){const o={};return i.integrity&&(o.integrity=i.integrity),i.referrerPolicy&&(o.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?o.credentials="include":i.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function r(i){if(i.ep)return;i.ep=!0;const o=n(i);fetch(i.href,o)}})();var So=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function Dx(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var $x={exports:{}},Va={},Bx={exports:{}},G={};/** 10 - * @license React 11 - * react.production.min.js 12 - * 13 - * Copyright (c) Facebook, Inc. and its affiliates. 14 - * 15 - * This source code is licensed under the MIT license found in the 16 - * LICENSE file in the root directory of this source tree. 17 - */var ro=Symbol.for("react.element"),hk=Symbol.for("react.portal"),pk=Symbol.for("react.fragment"),vk=Symbol.for("react.strict_mode"),gk=Symbol.for("react.profiler"),mk=Symbol.for("react.provider"),yk=Symbol.for("react.context"),_k=Symbol.for("react.forward_ref"),xk=Symbol.for("react.suspense"),wk=Symbol.for("react.memo"),Sk=Symbol.for("react.lazy"),Wv=Symbol.iterator;function Ek(e){return e===null||typeof e!="object"?null:(e=Wv&&e[Wv]||e["@@iterator"],typeof e=="function"?e:null)}var Ux={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},Hx=Object.assign,Vx={};function Vr(e,t,n){this.props=e,this.context=t,this.refs=Vx,this.updater=n||Ux}Vr.prototype.isReactComponent={};Vr.prototype.setState=function(e,t){if(typeof e!="object"&&typeof e!="function"&&e!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")};Vr.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")};function Gx(){}Gx.prototype=Vr.prototype;function dp(e,t,n){this.props=e,this.context=t,this.refs=Vx,this.updater=n||Ux}var hp=dp.prototype=new Gx;hp.constructor=dp;Hx(hp,Vr.prototype);hp.isPureReactComponent=!0;var Kv=Array.isArray,Wx=Object.prototype.hasOwnProperty,pp={current:null},Kx={key:!0,ref:!0,__self:!0,__source:!0};function Yx(e,t,n){var r,i={},o=null,a=null;if(t!=null)for(r in t.ref!==void 0&&(a=t.ref),t.key!==void 0&&(o=""+t.key),t)Wx.call(t,r)&&!Kx.hasOwnProperty(r)&&(i[r]=t[r]);var s=arguments.length-2;if(s===1)i.children=n;else if(1<s){for(var u=Array(s),l=0;l<s;l++)u[l]=arguments[l+2];i.children=u}if(e&&e.defaultProps)for(r in s=e.defaultProps,s)i[r]===void 0&&(i[r]=s[r]);return{$$typeof:ro,type:e,key:o,ref:a,props:i,_owner:pp.current}}function Ck(e,t){return{$$typeof:ro,type:e.type,key:t,ref:e.ref,props:e.props,_owner:e._owner}}function vp(e){return typeof e=="object"&&e!==null&&e.$$typeof===ro}function kk(e){var t={"=":"=0",":":"=2"};return"$"+e.replace(/[=:]/g,function(n){return t[n]})}var Yv=/\/+/g;function Ps(e,t){return typeof e=="object"&&e!==null&&e.key!=null?kk(""+e.key):t.toString(36)}function Wo(e,t,n,r,i){var o=typeof e;(o==="undefined"||o==="boolean")&&(e=null);var a=!1;if(e===null)a=!0;else switch(o){case"string":case"number":a=!0;break;case"object":switch(e.$$typeof){case ro:case hk:a=!0}}if(a)return a=e,i=i(a),e=r===""?"."+Ps(a,0):r,Kv(i)?(n="",e!=null&&(n=e.replace(Yv,"$&/")+"/"),Wo(i,t,n,"",function(l){return l})):i!=null&&(vp(i)&&(i=Ck(i,n+(!i.key||a&&a.key===i.key?"":(""+i.key).replace(Yv,"$&/")+"/")+e)),t.push(i)),1;if(a=0,r=r===""?".":r+":",Kv(e))for(var s=0;s<e.length;s++){o=e[s];var u=r+Ps(o,s);a+=Wo(o,t,n,u,i)}else if(u=Ek(e),typeof u=="function")for(e=u.call(e),s=0;!(o=e.next()).done;)o=o.value,u=r+Ps(o,s++),a+=Wo(o,t,n,u,i);else if(o==="object")throw t=String(e),Error("Objects are not valid as a React child (found: "+(t==="[object Object]"?"object with keys {"+Object.keys(e).join(", ")+"}":t)+"). If you meant to render a collection of children, use an array instead.");return a}function Eo(e,t,n){if(e==null)return e;var r=[],i=0;return Wo(e,r,"","",function(o){return t.call(n,o,i++)}),r}function bk(e){if(e._status===-1){var t=e._result;t=t(),t.then(function(n){(e._status===0||e._status===-1)&&(e._status=1,e._result=n)},function(n){(e._status===0||e._status===-1)&&(e._status=2,e._result=n)}),e._status===-1&&(e._status=0,e._result=t)}if(e._status===1)return e._result.default;throw e._result}var Me={current:null},Ko={transition:null},Tk={ReactCurrentDispatcher:Me,ReactCurrentBatchConfig:Ko,ReactCurrentOwner:pp};function Qx(){throw Error("act(...) is not supported in production builds of React.")}G.Children={map:Eo,forEach:function(e,t,n){Eo(e,function(){t.apply(this,arguments)},n)},count:function(e){var t=0;return Eo(e,function(){t++}),t},toArray:function(e){return Eo(e,function(t){return t})||[]},only:function(e){if(!vp(e))throw Error("React.Children.only expected to receive a single React element child.");return e}};G.Component=Vr;G.Fragment=pk;G.Profiler=gk;G.PureComponent=dp;G.StrictMode=vk;G.Suspense=xk;G.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=Tk;G.act=Qx;G.cloneElement=function(e,t,n){if(e==null)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+e+".");var r=Hx({},e.props),i=e.key,o=e.ref,a=e._owner;if(t!=null){if(t.ref!==void 0&&(o=t.ref,a=pp.current),t.key!==void 0&&(i=""+t.key),e.type&&e.type.defaultProps)var s=e.type.defaultProps;for(u in t)Wx.call(t,u)&&!Kx.hasOwnProperty(u)&&(r[u]=t[u]===void 0&&s!==void 0?s[u]:t[u])}var u=arguments.length-2;if(u===1)r.children=n;else if(1<u){s=Array(u);for(var l=0;l<u;l++)s[l]=arguments[l+2];r.children=s}return{$$typeof:ro,type:e.type,key:i,ref:o,props:r,_owner:a}};G.createContext=function(e){return e={$$typeof:yk,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null},e.Provider={$$typeof:mk,_context:e},e.Consumer=e};G.createElement=Yx;G.createFactory=function(e){var t=Yx.bind(null,e);return t.type=e,t};G.createRef=function(){return{current:null}};G.forwardRef=function(e){return{$$typeof:_k,render:e}};G.isValidElement=vp;G.lazy=function(e){return{$$typeof:Sk,_payload:{_status:-1,_result:e},_init:bk}};G.memo=function(e,t){return{$$typeof:wk,type:e,compare:t===void 0?null:t}};G.startTransition=function(e){var t=Ko.transition;Ko.transition={};try{e()}finally{Ko.transition=t}};G.unstable_act=Qx;G.useCallback=function(e,t){return Me.current.useCallback(e,t)};G.useContext=function(e){return Me.current.useContext(e)};G.useDebugValue=function(){};G.useDeferredValue=function(e){return Me.current.useDeferredValue(e)};G.useEffect=function(e,t){return Me.current.useEffect(e,t)};G.useId=function(){return Me.current.useId()};G.useImperativeHandle=function(e,t,n){return Me.current.useImperativeHandle(e,t,n)};G.useInsertionEffect=function(e,t){return Me.current.useInsertionEffect(e,t)};G.useLayoutEffect=function(e,t){return Me.current.useLayoutEffect(e,t)};G.useMemo=function(e,t){return Me.current.useMemo(e,t)};G.useReducer=function(e,t,n){return Me.current.useReducer(e,t,n)};G.useRef=function(e){return Me.current.useRef(e)};G.useState=function(e){return Me.current.useState(e)};G.useSyncExternalStore=function(e,t,n){return Me.current.useSyncExternalStore(e,t,n)};G.useTransition=function(){return Me.current.useTransition()};G.version="18.3.1";Bx.exports=G;var N=Bx.exports;const gp=Dx(N),Rk=dk({__proto__:null,default:gp},[N]);/** 18 - * @license React 19 - * react-jsx-runtime.production.min.js 20 - * 21 - * Copyright (c) Facebook, Inc. and its affiliates. 22 - * 23 - * This source code is licensed under the MIT license found in the 24 - * LICENSE file in the root directory of this source tree. 25 - */var Nk=N,Ik=Symbol.for("react.element"),Pk=Symbol.for("react.fragment"),jk=Object.prototype.hasOwnProperty,qk=Nk.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,Ak={key:!0,ref:!0,__self:!0,__source:!0};function Xx(e,t,n){var r,i={},o=null,a=null;n!==void 0&&(o=""+n),t.key!==void 0&&(o=""+t.key),t.ref!==void 0&&(a=t.ref);for(r in t)jk.call(t,r)&&!Ak.hasOwnProperty(r)&&(i[r]=t[r]);if(e&&e.defaultProps)for(r in t=e.defaultProps,t)i[r]===void 0&&(i[r]=t[r]);return{$$typeof:Ik,type:e,key:o,ref:a,props:i,_owner:qk.current}}Va.Fragment=Pk;Va.jsx=Xx;Va.jsxs=Xx;$x.exports=Va;var w=$x.exports,rh={},Zx={exports:{}},et={},Jx={exports:{}},ew={};/** 26 - * @license React 27 - * scheduler.production.min.js 28 - * 29 - * Copyright (c) Facebook, Inc. and its affiliates. 30 - * 31 - * This source code is licensed under the MIT license found in the 32 - * LICENSE file in the root directory of this source tree. 33 - */(function(e){function t(I,A){var L=I.length;I.push(A);e:for(;0<L;){var F=L-1>>>1,U=I[F];if(0<i(U,A))I[F]=A,I[L]=U,L=F;else break e}}function n(I){return I.length===0?null:I[0]}function r(I){if(I.length===0)return null;var A=I[0],L=I.pop();if(L!==A){I[0]=L;e:for(var F=0,U=I.length,Ee=U>>>1;F<Ee;){var J=2*(F+1)-1,Ce=I[J],me=J+1,xe=I[me];if(0>i(Ce,L))me<U&&0>i(xe,Ce)?(I[F]=xe,I[me]=L,F=me):(I[F]=Ce,I[J]=L,F=J);else if(me<U&&0>i(xe,L))I[F]=xe,I[me]=L,F=me;else break e}}return A}function i(I,A){var L=I.sortIndex-A.sortIndex;return L!==0?L:I.id-A.id}if(typeof performance=="object"&&typeof performance.now=="function"){var o=performance;e.unstable_now=function(){return o.now()}}else{var a=Date,s=a.now();e.unstable_now=function(){return a.now()-s}}var u=[],l=[],c=1,f=null,d=3,h=!1,g=!1,v=!1,y=typeof setTimeout=="function"?setTimeout:null,p=typeof clearTimeout=="function"?clearTimeout:null,m=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function _(I){for(var A=n(l);A!==null;){if(A.callback===null)r(l);else if(A.startTime<=I)r(l),A.sortIndex=A.expirationTime,t(u,A);else break;A=n(l)}}function x(I){if(v=!1,_(I),!g)if(n(u)!==null)g=!0,R(S);else{var A=n(l);A!==null&&O(x,A.startTime-I)}}function S(I,A){g=!1,v&&(v=!1,p(T),T=-1),h=!0;var L=d;try{for(_(A),f=n(u);f!==null&&(!(f.expirationTime>A)||I&&!j());){var F=f.callback;if(typeof F=="function"){f.callback=null,d=f.priorityLevel;var U=F(f.expirationTime<=A);A=e.unstable_now(),typeof U=="function"?f.callback=U:f===n(u)&&r(u),_(A)}else r(u);f=n(u)}if(f!==null)var Ee=!0;else{var J=n(l);J!==null&&O(x,J.startTime-A),Ee=!1}return Ee}finally{f=null,d=L,h=!1}}var E=!1,C=null,T=-1,M=5,k=-1;function j(){return!(e.unstable_now()-k<M)}function B(){if(C!==null){var I=e.unstable_now();k=I;var A=!0;try{A=C(!0,I)}finally{A?H():(E=!1,C=null)}}else E=!1}var H;if(typeof m=="function")H=function(){m(B)};else if(typeof MessageChannel<"u"){var b=new MessageChannel,P=b.port2;b.port1.onmessage=B,H=function(){P.postMessage(null)}}else H=function(){y(B,0)};function R(I){C=I,E||(E=!0,H())}function O(I,A){T=y(function(){I(e.unstable_now())},A)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(I){I.callback=null},e.unstable_continueExecution=function(){g||h||(g=!0,R(S))},e.unstable_forceFrameRate=function(I){0>I||125<I?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):M=0<I?Math.floor(1e3/I):5},e.unstable_getCurrentPriorityLevel=function(){return d},e.unstable_getFirstCallbackNode=function(){return n(u)},e.unstable_next=function(I){switch(d){case 1:case 2:case 3:var A=3;break;default:A=d}var L=d;d=A;try{return I()}finally{d=L}},e.unstable_pauseExecution=function(){},e.unstable_requestPaint=function(){},e.unstable_runWithPriority=function(I,A){switch(I){case 1:case 2:case 3:case 4:case 5:break;default:I=3}var L=d;d=I;try{return A()}finally{d=L}},e.unstable_scheduleCallback=function(I,A,L){var F=e.unstable_now();switch(typeof L=="object"&&L!==null?(L=L.delay,L=typeof L=="number"&&0<L?F+L:F):L=F,I){case 1:var U=-1;break;case 2:U=250;break;case 5:U=1073741823;break;case 4:U=1e4;break;default:U=5e3}return U=L+U,I={id:c++,callback:A,priorityLevel:I,startTime:L,expirationTime:U,sortIndex:-1},L>F?(I.sortIndex=L,t(l,I),n(u)===null&&I===n(l)&&(v?(p(T),T=-1):v=!0,O(x,L-F))):(I.sortIndex=U,t(u,I),g||h||(g=!0,R(S))),I},e.unstable_shouldYield=j,e.unstable_wrapCallback=function(I){var A=d;return function(){var L=d;d=A;try{return I.apply(this,arguments)}finally{d=L}}}})(ew);Jx.exports=ew;var Mk=Jx.exports;/** 34 - * @license React 35 - * react-dom.production.min.js 36 - * 37 - * Copyright (c) Facebook, Inc. and its affiliates. 38 - * 39 - * This source code is licensed under the MIT license found in the 40 - * LICENSE file in the root directory of this source tree. 41 - */var Lk=N,Ze=Mk;function q(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var tw=new Set,qi={};function Jn(e,t){Ar(e,t),Ar(e+"Capture",t)}function Ar(e,t){for(qi[e]=t,e=0;e<t.length;e++)tw.add(t[e])}var Ht=!(typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),ih=Object.prototype.hasOwnProperty,Ok=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,Qv={},Xv={};function zk(e){return ih.call(Xv,e)?!0:ih.call(Qv,e)?!1:Ok.test(e)?Xv[e]=!0:(Qv[e]=!0,!1)}function Fk(e,t,n,r){if(n!==null&&n.type===0)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return r?!1:n!==null?!n.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function Dk(e,t,n,r){if(t===null||typeof t>"u"||Fk(e,t,n,r))return!0;if(r)return!1;if(n!==null)switch(n.type){case 3:return!t;case 4:return t===!1;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}function Le(e,t,n,r,i,o,a){this.acceptsBooleans=t===2||t===3||t===4,this.attributeName=r,this.attributeNamespace=i,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=o,this.removeEmptyString=a}var Te={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){Te[e]=new Le(e,0,!1,e,null,!1,!1)});[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var t=e[0];Te[t]=new Le(t,1,!1,e[1],null,!1,!1)});["contentEditable","draggable","spellCheck","value"].forEach(function(e){Te[e]=new Le(e,2,!1,e.toLowerCase(),null,!1,!1)});["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){Te[e]=new Le(e,2,!1,e,null,!1,!1)});"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){Te[e]=new Le(e,3,!1,e.toLowerCase(),null,!1,!1)});["checked","multiple","muted","selected"].forEach(function(e){Te[e]=new Le(e,3,!0,e,null,!1,!1)});["capture","download"].forEach(function(e){Te[e]=new Le(e,4,!1,e,null,!1,!1)});["cols","rows","size","span"].forEach(function(e){Te[e]=new Le(e,6,!1,e,null,!1,!1)});["rowSpan","start"].forEach(function(e){Te[e]=new Le(e,5,!1,e.toLowerCase(),null,!1,!1)});var mp=/[\-:]([a-z])/g;function yp(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var t=e.replace(mp,yp);Te[t]=new Le(t,1,!1,e,null,!1,!1)});"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var t=e.replace(mp,yp);Te[t]=new Le(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)});["xml:base","xml:lang","xml:space"].forEach(function(e){var t=e.replace(mp,yp);Te[t]=new Le(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)});["tabIndex","crossOrigin"].forEach(function(e){Te[e]=new Le(e,1,!1,e.toLowerCase(),null,!1,!1)});Te.xlinkHref=new Le("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1);["src","href","action","formAction"].forEach(function(e){Te[e]=new Le(e,1,!1,e.toLowerCase(),null,!0,!0)});function _p(e,t,n,r){var i=Te.hasOwnProperty(t)?Te[t]:null;(i!==null?i.type!==0:r||!(2<t.length)||t[0]!=="o"&&t[0]!=="O"||t[1]!=="n"&&t[1]!=="N")&&(Dk(t,n,i,r)&&(n=null),r||i===null?zk(t)&&(n===null?e.removeAttribute(t):e.setAttribute(t,""+n)):i.mustUseProperty?e[i.propertyName]=n===null?i.type===3?!1:"":n:(t=i.attributeName,r=i.attributeNamespace,n===null?e.removeAttribute(t):(i=i.type,n=i===3||i===4&&n===!0?"":""+n,r?e.setAttributeNS(r,t,n):e.setAttribute(t,n))))}var Qt=Lk.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,Co=Symbol.for("react.element"),pr=Symbol.for("react.portal"),vr=Symbol.for("react.fragment"),xp=Symbol.for("react.strict_mode"),oh=Symbol.for("react.profiler"),nw=Symbol.for("react.provider"),rw=Symbol.for("react.context"),wp=Symbol.for("react.forward_ref"),ah=Symbol.for("react.suspense"),sh=Symbol.for("react.suspense_list"),Sp=Symbol.for("react.memo"),rn=Symbol.for("react.lazy"),iw=Symbol.for("react.offscreen"),Zv=Symbol.iterator;function ni(e){return e===null||typeof e!="object"?null:(e=Zv&&e[Zv]||e["@@iterator"],typeof e=="function"?e:null)}var fe=Object.assign,js;function di(e){if(js===void 0)try{throw Error()}catch(n){var t=n.stack.trim().match(/\n( *(at )?)/);js=t&&t[1]||""}return` 42 - `+js+e}var qs=!1;function As(e,t){if(!e||qs)return"";qs=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(t)if(t=function(){throw Error()},Object.defineProperty(t.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(t,[])}catch(l){var r=l}Reflect.construct(e,[],t)}else{try{t.call()}catch(l){r=l}e.call(t.prototype)}else{try{throw Error()}catch(l){r=l}e()}}catch(l){if(l&&r&&typeof l.stack=="string"){for(var i=l.stack.split(` 43 - `),o=r.stack.split(` 44 - `),a=i.length-1,s=o.length-1;1<=a&&0<=s&&i[a]!==o[s];)s--;for(;1<=a&&0<=s;a--,s--)if(i[a]!==o[s]){if(a!==1||s!==1)do if(a--,s--,0>s||i[a]!==o[s]){var u=` 45 - `+i[a].replace(" at new "," at ");return e.displayName&&u.includes("<anonymous>")&&(u=u.replace("<anonymous>",e.displayName)),u}while(1<=a&&0<=s);break}}}finally{qs=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?di(e):""}function $k(e){switch(e.tag){case 5:return di(e.type);case 16:return di("Lazy");case 13:return di("Suspense");case 19:return di("SuspenseList");case 0:case 2:case 15:return e=As(e.type,!1),e;case 11:return e=As(e.type.render,!1),e;case 1:return e=As(e.type,!0),e;default:return""}}function uh(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case vr:return"Fragment";case pr:return"Portal";case oh:return"Profiler";case xp:return"StrictMode";case ah:return"Suspense";case sh:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case rw:return(e.displayName||"Context")+".Consumer";case nw:return(e._context.displayName||"Context")+".Provider";case wp:var t=e.render;return e=e.displayName,e||(e=t.displayName||t.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case Sp:return t=e.displayName||null,t!==null?t:uh(e.type)||"Memo";case rn:t=e._payload,e=e._init;try{return uh(e(t))}catch{}}return null}function Bk(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=t.render,e=e.displayName||e.name||"",t.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return uh(t);case 8:return t===xp?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof t=="function")return t.displayName||t.name||null;if(typeof t=="string")return t}return null}function Cn(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function ow(e){var t=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(t==="checkbox"||t==="radio")}function Uk(e){var t=ow(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&typeof n<"u"&&typeof n.get=="function"&&typeof n.set=="function"){var i=n.get,o=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return i.call(this)},set:function(a){r=""+a,o.call(this,a)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(a){r=""+a},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}function ko(e){e._valueTracker||(e._valueTracker=Uk(e))}function aw(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=ow(e)?e.checked?"true":"false":e.value),e=r,e!==n?(t.setValue(e),!0):!1}function la(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}function lh(e,t){var n=t.checked;return fe({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:n??e._wrapperState.initialChecked})}function Jv(e,t){var n=t.defaultValue==null?"":t.defaultValue,r=t.checked!=null?t.checked:t.defaultChecked;n=Cn(t.value!=null?t.value:n),e._wrapperState={initialChecked:r,initialValue:n,controlled:t.type==="checkbox"||t.type==="radio"?t.checked!=null:t.value!=null}}function sw(e,t){t=t.checked,t!=null&&_p(e,"checked",t,!1)}function ch(e,t){sw(e,t);var n=Cn(t.value),r=t.type;if(n!=null)r==="number"?(n===0&&e.value===""||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if(r==="submit"||r==="reset"){e.removeAttribute("value");return}t.hasOwnProperty("value")?fh(e,t.type,n):t.hasOwnProperty("defaultValue")&&fh(e,t.type,Cn(t.defaultValue)),t.checked==null&&t.defaultChecked!=null&&(e.defaultChecked=!!t.defaultChecked)}function eg(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var r=t.type;if(!(r!=="submit"&&r!=="reset"||t.value!==void 0&&t.value!==null))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}n=e.name,n!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,n!==""&&(e.name=n)}function fh(e,t,n){(t!=="number"||la(e.ownerDocument)!==e)&&(n==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}var hi=Array.isArray;function br(e,t,n,r){if(e=e.options,t){t={};for(var i=0;i<n.length;i++)t["$"+n[i]]=!0;for(n=0;n<e.length;n++)i=t.hasOwnProperty("$"+e[n].value),e[n].selected!==i&&(e[n].selected=i),i&&r&&(e[n].defaultSelected=!0)}else{for(n=""+Cn(n),t=null,i=0;i<e.length;i++){if(e[i].value===n){e[i].selected=!0,r&&(e[i].defaultSelected=!0);return}t!==null||e[i].disabled||(t=e[i])}t!==null&&(t.selected=!0)}}function dh(e,t){if(t.dangerouslySetInnerHTML!=null)throw Error(q(91));return fe({},t,{value:void 0,defaultValue:void 0,children:""+e._wrapperState.initialValue})}function tg(e,t){var n=t.value;if(n==null){if(n=t.children,t=t.defaultValue,n!=null){if(t!=null)throw Error(q(92));if(hi(n)){if(1<n.length)throw Error(q(93));n=n[0]}t=n}t==null&&(t=""),n=t}e._wrapperState={initialValue:Cn(n)}}function uw(e,t){var n=Cn(t.value),r=Cn(t.defaultValue);n!=null&&(n=""+n,n!==e.value&&(e.value=n),t.defaultValue==null&&e.defaultValue!==n&&(e.defaultValue=n)),r!=null&&(e.defaultValue=""+r)}function ng(e){var t=e.textContent;t===e._wrapperState.initialValue&&t!==""&&t!==null&&(e.value=t)}function lw(e){switch(e){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function hh(e,t){return e==null||e==="http://www.w3.org/1999/xhtml"?lw(t):e==="http://www.w3.org/2000/svg"&&t==="foreignObject"?"http://www.w3.org/1999/xhtml":e}var bo,cw=function(e){return typeof MSApp<"u"&&MSApp.execUnsafeLocalFunction?function(t,n,r,i){MSApp.execUnsafeLocalFunction(function(){return e(t,n,r,i)})}:e}(function(e,t){if(e.namespaceURI!=="http://www.w3.org/2000/svg"||"innerHTML"in e)e.innerHTML=t;else{for(bo=bo||document.createElement("div"),bo.innerHTML="<svg>"+t.valueOf().toString()+"</svg>",t=bo.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}});function Ai(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&n.nodeType===3){n.nodeValue=t;return}}e.textContent=t}var Ci={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},Hk=["Webkit","ms","Moz","O"];Object.keys(Ci).forEach(function(e){Hk.forEach(function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),Ci[t]=Ci[e]})});function fw(e,t,n){return t==null||typeof t=="boolean"||t===""?"":n||typeof t!="number"||t===0||Ci.hasOwnProperty(e)&&Ci[e]?(""+t).trim():t+"px"}function dw(e,t){e=e.style;for(var n in t)if(t.hasOwnProperty(n)){var r=n.indexOf("--")===0,i=fw(n,t[n],r);n==="float"&&(n="cssFloat"),r?e.setProperty(n,i):e[n]=i}}var Vk=fe({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function ph(e,t){if(t){if(Vk[e]&&(t.children!=null||t.dangerouslySetInnerHTML!=null))throw Error(q(137,e));if(t.dangerouslySetInnerHTML!=null){if(t.children!=null)throw Error(q(60));if(typeof t.dangerouslySetInnerHTML!="object"||!("__html"in t.dangerouslySetInnerHTML))throw Error(q(61))}if(t.style!=null&&typeof t.style!="object")throw Error(q(62))}}function vh(e,t){if(e.indexOf("-")===-1)return typeof t.is=="string";switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var gh=null;function Ep(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var mh=null,Tr=null,Rr=null;function rg(e){if(e=ao(e)){if(typeof mh!="function")throw Error(q(280));var t=e.stateNode;t&&(t=Qa(t),mh(e.stateNode,e.type,t))}}function hw(e){Tr?Rr?Rr.push(e):Rr=[e]:Tr=e}function pw(){if(Tr){var e=Tr,t=Rr;if(Rr=Tr=null,rg(e),t)for(e=0;e<t.length;e++)rg(t[e])}}function vw(e,t){return e(t)}function gw(){}var Ms=!1;function mw(e,t,n){if(Ms)return e(t,n);Ms=!0;try{return vw(e,t,n)}finally{Ms=!1,(Tr!==null||Rr!==null)&&(gw(),pw())}}function Mi(e,t){var n=e.stateNode;if(n===null)return null;var r=Qa(n);if(r===null)return null;n=r[t];e:switch(t){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":case"onMouseEnter":(r=!r.disabled)||(e=e.type,r=!(e==="button"||e==="input"||e==="select"||e==="textarea")),e=!r;break e;default:e=!1}if(e)return null;if(n&&typeof n!="function")throw Error(q(231,t,typeof n));return n}var yh=!1;if(Ht)try{var ri={};Object.defineProperty(ri,"passive",{get:function(){yh=!0}}),window.addEventListener("test",ri,ri),window.removeEventListener("test",ri,ri)}catch{yh=!1}function Gk(e,t,n,r,i,o,a,s,u){var l=Array.prototype.slice.call(arguments,3);try{t.apply(n,l)}catch(c){this.onError(c)}}var ki=!1,ca=null,fa=!1,_h=null,Wk={onError:function(e){ki=!0,ca=e}};function Kk(e,t,n,r,i,o,a,s,u){ki=!1,ca=null,Gk.apply(Wk,arguments)}function Yk(e,t,n,r,i,o,a,s,u){if(Kk.apply(this,arguments),ki){if(ki){var l=ca;ki=!1,ca=null}else throw Error(q(198));fa||(fa=!0,_h=l)}}function er(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do t=e,t.flags&4098&&(n=t.return),e=t.return;while(e)}return t.tag===3?n:null}function yw(e){if(e.tag===13){var t=e.memoizedState;if(t===null&&(e=e.alternate,e!==null&&(t=e.memoizedState)),t!==null)return t.dehydrated}return null}function ig(e){if(er(e)!==e)throw Error(q(188))}function Qk(e){var t=e.alternate;if(!t){if(t=er(e),t===null)throw Error(q(188));return t!==e?null:e}for(var n=e,r=t;;){var i=n.return;if(i===null)break;var o=i.alternate;if(o===null){if(r=i.return,r!==null){n=r;continue}break}if(i.child===o.child){for(o=i.child;o;){if(o===n)return ig(i),e;if(o===r)return ig(i),t;o=o.sibling}throw Error(q(188))}if(n.return!==r.return)n=i,r=o;else{for(var a=!1,s=i.child;s;){if(s===n){a=!0,n=i,r=o;break}if(s===r){a=!0,r=i,n=o;break}s=s.sibling}if(!a){for(s=o.child;s;){if(s===n){a=!0,n=o,r=i;break}if(s===r){a=!0,r=o,n=i;break}s=s.sibling}if(!a)throw Error(q(189))}}if(n.alternate!==r)throw Error(q(190))}if(n.tag!==3)throw Error(q(188));return n.stateNode.current===n?e:t}function _w(e){return e=Qk(e),e!==null?xw(e):null}function xw(e){if(e.tag===5||e.tag===6)return e;for(e=e.child;e!==null;){var t=xw(e);if(t!==null)return t;e=e.sibling}return null}var ww=Ze.unstable_scheduleCallback,og=Ze.unstable_cancelCallback,Xk=Ze.unstable_shouldYield,Zk=Ze.unstable_requestPaint,he=Ze.unstable_now,Jk=Ze.unstable_getCurrentPriorityLevel,Cp=Ze.unstable_ImmediatePriority,Sw=Ze.unstable_UserBlockingPriority,da=Ze.unstable_NormalPriority,e2=Ze.unstable_LowPriority,Ew=Ze.unstable_IdlePriority,Ga=null,Tt=null;function t2(e){if(Tt&&typeof Tt.onCommitFiberRoot=="function")try{Tt.onCommitFiberRoot(Ga,e,void 0,(e.current.flags&128)===128)}catch{}}var mt=Math.clz32?Math.clz32:i2,n2=Math.log,r2=Math.LN2;function i2(e){return e>>>=0,e===0?32:31-(n2(e)/r2|0)|0}var To=64,Ro=4194304;function pi(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function ha(e,t){var n=e.pendingLanes;if(n===0)return 0;var r=0,i=e.suspendedLanes,o=e.pingedLanes,a=n&268435455;if(a!==0){var s=a&~i;s!==0?r=pi(s):(o&=a,o!==0&&(r=pi(o)))}else a=n&~i,a!==0?r=pi(a):o!==0&&(r=pi(o));if(r===0)return 0;if(t!==0&&t!==r&&!(t&i)&&(i=r&-r,o=t&-t,i>=o||i===16&&(o&4194240)!==0))return t;if(r&4&&(r|=n&16),t=e.entangledLanes,t!==0)for(e=e.entanglements,t&=r;0<t;)n=31-mt(t),i=1<<n,r|=e[n],t&=~i;return r}function o2(e,t){switch(e){case 1:case 2:case 4:return t+250;case 8:case 16:case 32:case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return-1;case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function a2(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,i=e.expirationTimes,o=e.pendingLanes;0<o;){var a=31-mt(o),s=1<<a,u=i[a];u===-1?(!(s&n)||s&r)&&(i[a]=o2(s,t)):u<=t&&(e.expiredLanes|=s),o&=~s}}function xh(e){return e=e.pendingLanes&-1073741825,e!==0?e:e&1073741824?1073741824:0}function Cw(){var e=To;return To<<=1,!(To&4194240)&&(To=64),e}function Ls(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function io(e,t,n){e.pendingLanes|=t,t!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,t=31-mt(t),e[t]=n}function s2(e,t){var n=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var r=e.eventTimes;for(e=e.expirationTimes;0<n;){var i=31-mt(n),o=1<<i;t[i]=0,r[i]=-1,e[i]=-1,n&=~o}}function kp(e,t){var n=e.entangledLanes|=t;for(e=e.entanglements;n;){var r=31-mt(n),i=1<<r;i&t|e[r]&t&&(e[r]|=t),n&=~i}}var X=0;function kw(e){return e&=-e,1<e?4<e?e&268435455?16:536870912:4:1}var bw,bp,Tw,Rw,Nw,wh=!1,No=[],pn=null,vn=null,gn=null,Li=new Map,Oi=new Map,sn=[],u2="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit".split(" ");function ag(e,t){switch(e){case"focusin":case"focusout":pn=null;break;case"dragenter":case"dragleave":vn=null;break;case"mouseover":case"mouseout":gn=null;break;case"pointerover":case"pointerout":Li.delete(t.pointerId);break;case"gotpointercapture":case"lostpointercapture":Oi.delete(t.pointerId)}}function ii(e,t,n,r,i,o){return e===null||e.nativeEvent!==o?(e={blockedOn:t,domEventName:n,eventSystemFlags:r,nativeEvent:o,targetContainers:[i]},t!==null&&(t=ao(t),t!==null&&bp(t)),e):(e.eventSystemFlags|=r,t=e.targetContainers,i!==null&&t.indexOf(i)===-1&&t.push(i),e)}function l2(e,t,n,r,i){switch(t){case"focusin":return pn=ii(pn,e,t,n,r,i),!0;case"dragenter":return vn=ii(vn,e,t,n,r,i),!0;case"mouseover":return gn=ii(gn,e,t,n,r,i),!0;case"pointerover":var o=i.pointerId;return Li.set(o,ii(Li.get(o)||null,e,t,n,r,i)),!0;case"gotpointercapture":return o=i.pointerId,Oi.set(o,ii(Oi.get(o)||null,e,t,n,r,i)),!0}return!1}function Iw(e){var t=zn(e.target);if(t!==null){var n=er(t);if(n!==null){if(t=n.tag,t===13){if(t=yw(n),t!==null){e.blockedOn=t,Nw(e.priority,function(){Tw(n)});return}}else if(t===3&&n.stateNode.current.memoizedState.isDehydrated){e.blockedOn=n.tag===3?n.stateNode.containerInfo:null;return}}}e.blockedOn=null}function Yo(e){if(e.blockedOn!==null)return!1;for(var t=e.targetContainers;0<t.length;){var n=Sh(e.domEventName,e.eventSystemFlags,t[0],e.nativeEvent);if(n===null){n=e.nativeEvent;var r=new n.constructor(n.type,n);gh=r,n.target.dispatchEvent(r),gh=null}else return t=ao(n),t!==null&&bp(t),e.blockedOn=n,!1;t.shift()}return!0}function sg(e,t,n){Yo(e)&&n.delete(t)}function c2(){wh=!1,pn!==null&&Yo(pn)&&(pn=null),vn!==null&&Yo(vn)&&(vn=null),gn!==null&&Yo(gn)&&(gn=null),Li.forEach(sg),Oi.forEach(sg)}function oi(e,t){e.blockedOn===t&&(e.blockedOn=null,wh||(wh=!0,Ze.unstable_scheduleCallback(Ze.unstable_NormalPriority,c2)))}function zi(e){function t(i){return oi(i,e)}if(0<No.length){oi(No[0],e);for(var n=1;n<No.length;n++){var r=No[n];r.blockedOn===e&&(r.blockedOn=null)}}for(pn!==null&&oi(pn,e),vn!==null&&oi(vn,e),gn!==null&&oi(gn,e),Li.forEach(t),Oi.forEach(t),n=0;n<sn.length;n++)r=sn[n],r.blockedOn===e&&(r.blockedOn=null);for(;0<sn.length&&(n=sn[0],n.blockedOn===null);)Iw(n),n.blockedOn===null&&sn.shift()}var Nr=Qt.ReactCurrentBatchConfig,pa=!0;function f2(e,t,n,r){var i=X,o=Nr.transition;Nr.transition=null;try{X=1,Tp(e,t,n,r)}finally{X=i,Nr.transition=o}}function d2(e,t,n,r){var i=X,o=Nr.transition;Nr.transition=null;try{X=4,Tp(e,t,n,r)}finally{X=i,Nr.transition=o}}function Tp(e,t,n,r){if(pa){var i=Sh(e,t,n,r);if(i===null)Gs(e,t,r,va,n),ag(e,r);else if(l2(i,e,t,n,r))r.stopPropagation();else if(ag(e,r),t&4&&-1<u2.indexOf(e)){for(;i!==null;){var o=ao(i);if(o!==null&&bw(o),o=Sh(e,t,n,r),o===null&&Gs(e,t,r,va,n),o===i)break;i=o}i!==null&&r.stopPropagation()}else Gs(e,t,r,null,n)}}var va=null;function Sh(e,t,n,r){if(va=null,e=Ep(r),e=zn(e),e!==null)if(t=er(e),t===null)e=null;else if(n=t.tag,n===13){if(e=yw(t),e!==null)return e;e=null}else if(n===3){if(t.stateNode.current.memoizedState.isDehydrated)return t.tag===3?t.stateNode.containerInfo:null;e=null}else t!==e&&(e=null);return va=e,null}function Pw(e){switch(e){case"cancel":case"click":case"close":case"contextmenu":case"copy":case"cut":case"auxclick":case"dblclick":case"dragend":case"dragstart":case"drop":case"focusin":case"focusout":case"input":case"invalid":case"keydown":case"keypress":case"keyup":case"mousedown":case"mouseup":case"paste":case"pause":case"play":case"pointercancel":case"pointerdown":case"pointerup":case"ratechange":case"reset":case"resize":case"seeked":case"submit":case"touchcancel":case"touchend":case"touchstart":case"volumechange":case"change":case"selectionchange":case"textInput":case"compositionstart":case"compositionend":case"compositionupdate":case"beforeblur":case"afterblur":case"beforeinput":case"blur":case"fullscreenchange":case"focus":case"hashchange":case"popstate":case"select":case"selectstart":return 1;case"drag":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"mousemove":case"mouseout":case"mouseover":case"pointermove":case"pointerout":case"pointerover":case"scroll":case"toggle":case"touchmove":case"wheel":case"mouseenter":case"mouseleave":case"pointerenter":case"pointerleave":return 4;case"message":switch(Jk()){case Cp:return 1;case Sw:return 4;case da:case e2:return 16;case Ew:return 536870912;default:return 16}default:return 16}}var cn=null,Rp=null,Qo=null;function jw(){if(Qo)return Qo;var e,t=Rp,n=t.length,r,i="value"in cn?cn.value:cn.textContent,o=i.length;for(e=0;e<n&&t[e]===i[e];e++);var a=n-e;for(r=1;r<=a&&t[n-r]===i[o-r];r++);return Qo=i.slice(e,1<r?1-r:void 0)}function Xo(e){var t=e.keyCode;return"charCode"in e?(e=e.charCode,e===0&&t===13&&(e=13)):e=t,e===10&&(e=13),32<=e||e===13?e:0}function Io(){return!0}function ug(){return!1}function tt(e){function t(n,r,i,o,a){this._reactName=n,this._targetInst=i,this.type=r,this.nativeEvent=o,this.target=a,this.currentTarget=null;for(var s in e)e.hasOwnProperty(s)&&(n=e[s],this[s]=n?n(o):o[s]);return this.isDefaultPrevented=(o.defaultPrevented!=null?o.defaultPrevented:o.returnValue===!1)?Io:ug,this.isPropagationStopped=ug,this}return fe(t.prototype,{preventDefault:function(){this.defaultPrevented=!0;var n=this.nativeEvent;n&&(n.preventDefault?n.preventDefault():typeof n.returnValue!="unknown"&&(n.returnValue=!1),this.isDefaultPrevented=Io)},stopPropagation:function(){var n=this.nativeEvent;n&&(n.stopPropagation?n.stopPropagation():typeof n.cancelBubble!="unknown"&&(n.cancelBubble=!0),this.isPropagationStopped=Io)},persist:function(){},isPersistent:Io}),t}var Gr={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},Np=tt(Gr),oo=fe({},Gr,{view:0,detail:0}),h2=tt(oo),Os,zs,ai,Wa=fe({},oo,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:Ip,button:0,buttons:0,relatedTarget:function(e){return e.relatedTarget===void 0?e.fromElement===e.srcElement?e.toElement:e.fromElement:e.relatedTarget},movementX:function(e){return"movementX"in e?e.movementX:(e!==ai&&(ai&&e.type==="mousemove"?(Os=e.screenX-ai.screenX,zs=e.screenY-ai.screenY):zs=Os=0,ai=e),Os)},movementY:function(e){return"movementY"in e?e.movementY:zs}}),lg=tt(Wa),p2=fe({},Wa,{dataTransfer:0}),v2=tt(p2),g2=fe({},oo,{relatedTarget:0}),Fs=tt(g2),m2=fe({},Gr,{animationName:0,elapsedTime:0,pseudoElement:0}),y2=tt(m2),_2=fe({},Gr,{clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}}),x2=tt(_2),w2=fe({},Gr,{data:0}),cg=tt(w2),S2={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},E2={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},C2={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function k2(e){var t=this.nativeEvent;return t.getModifierState?t.getModifierState(e):(e=C2[e])?!!t[e]:!1}function Ip(){return k2}var b2=fe({},oo,{key:function(e){if(e.key){var t=S2[e.key]||e.key;if(t!=="Unidentified")return t}return e.type==="keypress"?(e=Xo(e),e===13?"Enter":String.fromCharCode(e)):e.type==="keydown"||e.type==="keyup"?E2[e.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:Ip,charCode:function(e){return e.type==="keypress"?Xo(e):0},keyCode:function(e){return e.type==="keydown"||e.type==="keyup"?e.keyCode:0},which:function(e){return e.type==="keypress"?Xo(e):e.type==="keydown"||e.type==="keyup"?e.keyCode:0}}),T2=tt(b2),R2=fe({},Wa,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0}),fg=tt(R2),N2=fe({},oo,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:Ip}),I2=tt(N2),P2=fe({},Gr,{propertyName:0,elapsedTime:0,pseudoElement:0}),j2=tt(P2),q2=fe({},Wa,{deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:0,deltaMode:0}),A2=tt(q2),M2=[9,13,27,32],Pp=Ht&&"CompositionEvent"in window,bi=null;Ht&&"documentMode"in document&&(bi=document.documentMode);var L2=Ht&&"TextEvent"in window&&!bi,qw=Ht&&(!Pp||bi&&8<bi&&11>=bi),dg=" ",hg=!1;function Aw(e,t){switch(e){case"keyup":return M2.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Mw(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var gr=!1;function O2(e,t){switch(e){case"compositionend":return Mw(t);case"keypress":return t.which!==32?null:(hg=!0,dg);case"textInput":return e=t.data,e===dg&&hg?null:e;default:return null}}function z2(e,t){if(gr)return e==="compositionend"||!Pp&&Aw(e,t)?(e=jw(),Qo=Rp=cn=null,gr=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1<t.char.length)return t.char;if(t.which)return String.fromCharCode(t.which)}return null;case"compositionend":return qw&&t.locale!=="ko"?null:t.data;default:return null}}var F2={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function pg(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t==="input"?!!F2[e.type]:t==="textarea"}function Lw(e,t,n,r){hw(r),t=ga(t,"onChange"),0<t.length&&(n=new Np("onChange","change",null,n,r),e.push({event:n,listeners:t}))}var Ti=null,Fi=null;function D2(e){Ww(e,0)}function Ka(e){var t=_r(e);if(aw(t))return e}function $2(e,t){if(e==="change")return t}var Ow=!1;if(Ht){var Ds;if(Ht){var $s="oninput"in document;if(!$s){var vg=document.createElement("div");vg.setAttribute("oninput","return;"),$s=typeof vg.oninput=="function"}Ds=$s}else Ds=!1;Ow=Ds&&(!document.documentMode||9<document.documentMode)}function gg(){Ti&&(Ti.detachEvent("onpropertychange",zw),Fi=Ti=null)}function zw(e){if(e.propertyName==="value"&&Ka(Fi)){var t=[];Lw(t,Fi,e,Ep(e)),mw(D2,t)}}function B2(e,t,n){e==="focusin"?(gg(),Ti=t,Fi=n,Ti.attachEvent("onpropertychange",zw)):e==="focusout"&&gg()}function U2(e){if(e==="selectionchange"||e==="keyup"||e==="keydown")return Ka(Fi)}function H2(e,t){if(e==="click")return Ka(t)}function V2(e,t){if(e==="input"||e==="change")return Ka(t)}function G2(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var _t=typeof Object.is=="function"?Object.is:G2;function Di(e,t){if(_t(e,t))return!0;if(typeof e!="object"||e===null||typeof t!="object"||t===null)return!1;var n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(r=0;r<n.length;r++){var i=n[r];if(!ih.call(t,i)||!_t(e[i],t[i]))return!1}return!0}function mg(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function yg(e,t){var n=mg(e);e=0;for(var r;n;){if(n.nodeType===3){if(r=e+n.textContent.length,e<=t&&r>=t)return{node:n,offset:t-e};e=r}e:{for(;n;){if(n.nextSibling){n=n.nextSibling;break e}n=n.parentNode}n=void 0}n=mg(n)}}function Fw(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Fw(e,t.parentNode):"contains"in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Dw(){for(var e=window,t=la();t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href=="string"}catch{n=!1}if(n)e=t.contentWindow;else break;t=la(e.document)}return t}function jp(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||t==="textarea"||e.contentEditable==="true")}function W2(e){var t=Dw(),n=e.focusedElem,r=e.selectionRange;if(t!==n&&n&&n.ownerDocument&&Fw(n.ownerDocument.documentElement,n)){if(r!==null&&jp(n)){if(t=r.start,e=r.end,e===void 0&&(e=t),"selectionStart"in n)n.selectionStart=t,n.selectionEnd=Math.min(e,n.value.length);else if(e=(t=n.ownerDocument||document)&&t.defaultView||window,e.getSelection){e=e.getSelection();var i=n.textContent.length,o=Math.min(r.start,i);r=r.end===void 0?o:Math.min(r.end,i),!e.extend&&o>r&&(i=r,r=o,o=i),i=yg(n,o);var a=yg(n,r);i&&a&&(e.rangeCount!==1||e.anchorNode!==i.node||e.anchorOffset!==i.offset||e.focusNode!==a.node||e.focusOffset!==a.offset)&&(t=t.createRange(),t.setStart(i.node,i.offset),e.removeAllRanges(),o>r?(e.addRange(t),e.extend(a.node,a.offset)):(t.setEnd(a.node,a.offset),e.addRange(t)))}}for(t=[],e=n;e=e.parentNode;)e.nodeType===1&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof n.focus=="function"&&n.focus(),n=0;n<t.length;n++)e=t[n],e.element.scrollLeft=e.left,e.element.scrollTop=e.top}}var K2=Ht&&"documentMode"in document&&11>=document.documentMode,mr=null,Eh=null,Ri=null,Ch=!1;function _g(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;Ch||mr==null||mr!==la(r)||(r=mr,"selectionStart"in r&&jp(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Ri&&Di(Ri,r)||(Ri=r,r=ga(Eh,"onSelect"),0<r.length&&(t=new Np("onSelect","select",null,t,n),e.push({event:t,listeners:r}),t.target=mr)))}function Po(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n}var yr={animationend:Po("Animation","AnimationEnd"),animationiteration:Po("Animation","AnimationIteration"),animationstart:Po("Animation","AnimationStart"),transitionend:Po("Transition","TransitionEnd")},Bs={},$w={};Ht&&($w=document.createElement("div").style,"AnimationEvent"in window||(delete yr.animationend.animation,delete yr.animationiteration.animation,delete yr.animationstart.animation),"TransitionEvent"in window||delete yr.transitionend.transition);function Ya(e){if(Bs[e])return Bs[e];if(!yr[e])return e;var t=yr[e],n;for(n in t)if(t.hasOwnProperty(n)&&n in $w)return Bs[e]=t[n];return e}var Bw=Ya("animationend"),Uw=Ya("animationiteration"),Hw=Ya("animationstart"),Vw=Ya("transitionend"),Gw=new Map,xg="abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel".split(" ");function Rn(e,t){Gw.set(e,t),Jn(t,[e])}for(var Us=0;Us<xg.length;Us++){var Hs=xg[Us],Y2=Hs.toLowerCase(),Q2=Hs[0].toUpperCase()+Hs.slice(1);Rn(Y2,"on"+Q2)}Rn(Bw,"onAnimationEnd");Rn(Uw,"onAnimationIteration");Rn(Hw,"onAnimationStart");Rn("dblclick","onDoubleClick");Rn("focusin","onFocus");Rn("focusout","onBlur");Rn(Vw,"onTransitionEnd");Ar("onMouseEnter",["mouseout","mouseover"]);Ar("onMouseLeave",["mouseout","mouseover"]);Ar("onPointerEnter",["pointerout","pointerover"]);Ar("onPointerLeave",["pointerout","pointerover"]);Jn("onChange","change click focusin focusout input keydown keyup selectionchange".split(" "));Jn("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" "));Jn("onBeforeInput",["compositionend","keypress","textInput","paste"]);Jn("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" "));Jn("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" "));Jn("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "));var vi="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),X2=new Set("cancel close invalid load scroll toggle".split(" ").concat(vi));function wg(e,t,n){var r=e.type||"unknown-event";e.currentTarget=n,Yk(r,t,void 0,e),e.currentTarget=null}function Ww(e,t){t=(t&4)!==0;for(var n=0;n<e.length;n++){var r=e[n],i=r.event;r=r.listeners;e:{var o=void 0;if(t)for(var a=r.length-1;0<=a;a--){var s=r[a],u=s.instance,l=s.currentTarget;if(s=s.listener,u!==o&&i.isPropagationStopped())break e;wg(i,s,l),o=u}else for(a=0;a<r.length;a++){if(s=r[a],u=s.instance,l=s.currentTarget,s=s.listener,u!==o&&i.isPropagationStopped())break e;wg(i,s,l),o=u}}}if(fa)throw e=_h,fa=!1,_h=null,e}function oe(e,t){var n=t[Nh];n===void 0&&(n=t[Nh]=new Set);var r=e+"__bubble";n.has(r)||(Kw(t,e,2,!1),n.add(r))}function Vs(e,t,n){var r=0;t&&(r|=4),Kw(n,e,r,t)}var jo="_reactListening"+Math.random().toString(36).slice(2);function $i(e){if(!e[jo]){e[jo]=!0,tw.forEach(function(n){n!=="selectionchange"&&(X2.has(n)||Vs(n,!1,e),Vs(n,!0,e))});var t=e.nodeType===9?e:e.ownerDocument;t===null||t[jo]||(t[jo]=!0,Vs("selectionchange",!1,t))}}function Kw(e,t,n,r){switch(Pw(t)){case 1:var i=f2;break;case 4:i=d2;break;default:i=Tp}n=i.bind(null,t,n,e),i=void 0,!yh||t!=="touchstart"&&t!=="touchmove"&&t!=="wheel"||(i=!0),r?i!==void 0?e.addEventListener(t,n,{capture:!0,passive:i}):e.addEventListener(t,n,!0):i!==void 0?e.addEventListener(t,n,{passive:i}):e.addEventListener(t,n,!1)}function Gs(e,t,n,r,i){var o=r;if(!(t&1)&&!(t&2)&&r!==null)e:for(;;){if(r===null)return;var a=r.tag;if(a===3||a===4){var s=r.stateNode.containerInfo;if(s===i||s.nodeType===8&&s.parentNode===i)break;if(a===4)for(a=r.return;a!==null;){var u=a.tag;if((u===3||u===4)&&(u=a.stateNode.containerInfo,u===i||u.nodeType===8&&u.parentNode===i))return;a=a.return}for(;s!==null;){if(a=zn(s),a===null)return;if(u=a.tag,u===5||u===6){r=o=a;continue e}s=s.parentNode}}r=r.return}mw(function(){var l=o,c=Ep(n),f=[];e:{var d=Gw.get(e);if(d!==void 0){var h=Np,g=e;switch(e){case"keypress":if(Xo(n)===0)break e;case"keydown":case"keyup":h=T2;break;case"focusin":g="focus",h=Fs;break;case"focusout":g="blur",h=Fs;break;case"beforeblur":case"afterblur":h=Fs;break;case"click":if(n.button===2)break e;case"auxclick":case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":h=lg;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":h=v2;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":h=I2;break;case Bw:case Uw:case Hw:h=y2;break;case Vw:h=j2;break;case"scroll":h=h2;break;case"wheel":h=A2;break;case"copy":case"cut":case"paste":h=x2;break;case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":h=fg}var v=(t&4)!==0,y=!v&&e==="scroll",p=v?d!==null?d+"Capture":null:d;v=[];for(var m=l,_;m!==null;){_=m;var x=_.stateNode;if(_.tag===5&&x!==null&&(_=x,p!==null&&(x=Mi(m,p),x!=null&&v.push(Bi(m,x,_)))),y)break;m=m.return}0<v.length&&(d=new h(d,g,null,n,c),f.push({event:d,listeners:v}))}}if(!(t&7)){e:{if(d=e==="mouseover"||e==="pointerover",h=e==="mouseout"||e==="pointerout",d&&n!==gh&&(g=n.relatedTarget||n.fromElement)&&(zn(g)||g[Vt]))break e;if((h||d)&&(d=c.window===c?c:(d=c.ownerDocument)?d.defaultView||d.parentWindow:window,h?(g=n.relatedTarget||n.toElement,h=l,g=g?zn(g):null,g!==null&&(y=er(g),g!==y||g.tag!==5&&g.tag!==6)&&(g=null)):(h=null,g=l),h!==g)){if(v=lg,x="onMouseLeave",p="onMouseEnter",m="mouse",(e==="pointerout"||e==="pointerover")&&(v=fg,x="onPointerLeave",p="onPointerEnter",m="pointer"),y=h==null?d:_r(h),_=g==null?d:_r(g),d=new v(x,m+"leave",h,n,c),d.target=y,d.relatedTarget=_,x=null,zn(c)===l&&(v=new v(p,m+"enter",g,n,c),v.target=_,v.relatedTarget=y,x=v),y=x,h&&g)t:{for(v=h,p=g,m=0,_=v;_;_=cr(_))m++;for(_=0,x=p;x;x=cr(x))_++;for(;0<m-_;)v=cr(v),m--;for(;0<_-m;)p=cr(p),_--;for(;m--;){if(v===p||p!==null&&v===p.alternate)break t;v=cr(v),p=cr(p)}v=null}else v=null;h!==null&&Sg(f,d,h,v,!1),g!==null&&y!==null&&Sg(f,y,g,v,!0)}}e:{if(d=l?_r(l):window,h=d.nodeName&&d.nodeName.toLowerCase(),h==="select"||h==="input"&&d.type==="file")var S=$2;else if(pg(d))if(Ow)S=V2;else{S=U2;var E=B2}else(h=d.nodeName)&&h.toLowerCase()==="input"&&(d.type==="checkbox"||d.type==="radio")&&(S=H2);if(S&&(S=S(e,l))){Lw(f,S,n,c);break e}E&&E(e,d,l),e==="focusout"&&(E=d._wrapperState)&&E.controlled&&d.type==="number"&&fh(d,"number",d.value)}switch(E=l?_r(l):window,e){case"focusin":(pg(E)||E.contentEditable==="true")&&(mr=E,Eh=l,Ri=null);break;case"focusout":Ri=Eh=mr=null;break;case"mousedown":Ch=!0;break;case"contextmenu":case"mouseup":case"dragend":Ch=!1,_g(f,n,c);break;case"selectionchange":if(K2)break;case"keydown":case"keyup":_g(f,n,c)}var C;if(Pp)e:{switch(e){case"compositionstart":var T="onCompositionStart";break e;case"compositionend":T="onCompositionEnd";break e;case"compositionupdate":T="onCompositionUpdate";break e}T=void 0}else gr?Aw(e,n)&&(T="onCompositionEnd"):e==="keydown"&&n.keyCode===229&&(T="onCompositionStart");T&&(qw&&n.locale!=="ko"&&(gr||T!=="onCompositionStart"?T==="onCompositionEnd"&&gr&&(C=jw()):(cn=c,Rp="value"in cn?cn.value:cn.textContent,gr=!0)),E=ga(l,T),0<E.length&&(T=new cg(T,e,null,n,c),f.push({event:T,listeners:E}),C?T.data=C:(C=Mw(n),C!==null&&(T.data=C)))),(C=L2?O2(e,n):z2(e,n))&&(l=ga(l,"onBeforeInput"),0<l.length&&(c=new cg("onBeforeInput","beforeinput",null,n,c),f.push({event:c,listeners:l}),c.data=C))}Ww(f,t)})}function Bi(e,t,n){return{instance:e,listener:t,currentTarget:n}}function ga(e,t){for(var n=t+"Capture",r=[];e!==null;){var i=e,o=i.stateNode;i.tag===5&&o!==null&&(i=o,o=Mi(e,n),o!=null&&r.unshift(Bi(e,o,i)),o=Mi(e,t),o!=null&&r.push(Bi(e,o,i))),e=e.return}return r}function cr(e){if(e===null)return null;do e=e.return;while(e&&e.tag!==5);return e||null}function Sg(e,t,n,r,i){for(var o=t._reactName,a=[];n!==null&&n!==r;){var s=n,u=s.alternate,l=s.stateNode;if(u!==null&&u===r)break;s.tag===5&&l!==null&&(s=l,i?(u=Mi(n,o),u!=null&&a.unshift(Bi(n,u,s))):i||(u=Mi(n,o),u!=null&&a.push(Bi(n,u,s)))),n=n.return}a.length!==0&&e.push({event:t,listeners:a})}var Z2=/\r\n?/g,J2=/\u0000|\uFFFD/g;function Eg(e){return(typeof e=="string"?e:""+e).replace(Z2,` 46 - `).replace(J2,"")}function qo(e,t,n){if(t=Eg(t),Eg(e)!==t&&n)throw Error(q(425))}function ma(){}var kh=null,bh=null;function Th(e,t){return e==="textarea"||e==="noscript"||typeof t.children=="string"||typeof t.children=="number"||typeof t.dangerouslySetInnerHTML=="object"&&t.dangerouslySetInnerHTML!==null&&t.dangerouslySetInnerHTML.__html!=null}var Rh=typeof setTimeout=="function"?setTimeout:void 0,eb=typeof clearTimeout=="function"?clearTimeout:void 0,Cg=typeof Promise=="function"?Promise:void 0,tb=typeof queueMicrotask=="function"?queueMicrotask:typeof Cg<"u"?function(e){return Cg.resolve(null).then(e).catch(nb)}:Rh;function nb(e){setTimeout(function(){throw e})}function Ws(e,t){var n=t,r=0;do{var i=n.nextSibling;if(e.removeChild(n),i&&i.nodeType===8)if(n=i.data,n==="/$"){if(r===0){e.removeChild(i),zi(t);return}r--}else n!=="$"&&n!=="$?"&&n!=="$!"||r++;n=i}while(n);zi(t)}function mn(e){for(;e!=null;e=e.nextSibling){var t=e.nodeType;if(t===1||t===3)break;if(t===8){if(t=e.data,t==="$"||t==="$!"||t==="$?")break;if(t==="/$")return null}}return e}function kg(e){e=e.previousSibling;for(var t=0;e;){if(e.nodeType===8){var n=e.data;if(n==="$"||n==="$!"||n==="$?"){if(t===0)return e;t--}else n==="/$"&&t++}e=e.previousSibling}return null}var Wr=Math.random().toString(36).slice(2),kt="__reactFiber$"+Wr,Ui="__reactProps$"+Wr,Vt="__reactContainer$"+Wr,Nh="__reactEvents$"+Wr,rb="__reactListeners$"+Wr,ib="__reactHandles$"+Wr;function zn(e){var t=e[kt];if(t)return t;for(var n=e.parentNode;n;){if(t=n[Vt]||n[kt]){if(n=t.alternate,t.child!==null||n!==null&&n.child!==null)for(e=kg(e);e!==null;){if(n=e[kt])return n;e=kg(e)}return t}e=n,n=e.parentNode}return null}function ao(e){return e=e[kt]||e[Vt],!e||e.tag!==5&&e.tag!==6&&e.tag!==13&&e.tag!==3?null:e}function _r(e){if(e.tag===5||e.tag===6)return e.stateNode;throw Error(q(33))}function Qa(e){return e[Ui]||null}var Ih=[],xr=-1;function Nn(e){return{current:e}}function ae(e){0>xr||(e.current=Ih[xr],Ih[xr]=null,xr--)}function re(e,t){xr++,Ih[xr]=e.current,e.current=t}var kn={},Pe=Nn(kn),Ue=Nn(!1),Wn=kn;function Mr(e,t){var n=e.type.contextTypes;if(!n)return kn;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var i={},o;for(o in n)i[o]=t[o];return r&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=i),i}function He(e){return e=e.childContextTypes,e!=null}function ya(){ae(Ue),ae(Pe)}function bg(e,t,n){if(Pe.current!==kn)throw Error(q(168));re(Pe,t),re(Ue,n)}function Yw(e,t,n){var r=e.stateNode;if(t=t.childContextTypes,typeof r.getChildContext!="function")return n;r=r.getChildContext();for(var i in r)if(!(i in t))throw Error(q(108,Bk(e)||"Unknown",i));return fe({},n,r)}function _a(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||kn,Wn=Pe.current,re(Pe,e),re(Ue,Ue.current),!0}function Tg(e,t,n){var r=e.stateNode;if(!r)throw Error(q(169));n?(e=Yw(e,t,Wn),r.__reactInternalMemoizedMergedChildContext=e,ae(Ue),ae(Pe),re(Pe,e)):ae(Ue),re(Ue,n)}var Ot=null,Xa=!1,Ks=!1;function Qw(e){Ot===null?Ot=[e]:Ot.push(e)}function ob(e){Xa=!0,Qw(e)}function In(){if(!Ks&&Ot!==null){Ks=!0;var e=0,t=X;try{var n=Ot;for(X=1;e<n.length;e++){var r=n[e];do r=r(!0);while(r!==null)}Ot=null,Xa=!1}catch(i){throw Ot!==null&&(Ot=Ot.slice(e+1)),ww(Cp,In),i}finally{X=t,Ks=!1}}return null}var wr=[],Sr=0,xa=null,wa=0,nt=[],rt=0,Kn=null,zt=1,Ft="";function Mn(e,t){wr[Sr++]=wa,wr[Sr++]=xa,xa=e,wa=t}function Xw(e,t,n){nt[rt++]=zt,nt[rt++]=Ft,nt[rt++]=Kn,Kn=e;var r=zt;e=Ft;var i=32-mt(r)-1;r&=~(1<<i),n+=1;var o=32-mt(t)+i;if(30<o){var a=i-i%5;o=(r&(1<<a)-1).toString(32),r>>=a,i-=a,zt=1<<32-mt(t)+i|n<<i|r,Ft=o+e}else zt=1<<o|n<<i|r,Ft=e}function qp(e){e.return!==null&&(Mn(e,1),Xw(e,1,0))}function Ap(e){for(;e===xa;)xa=wr[--Sr],wr[Sr]=null,wa=wr[--Sr],wr[Sr]=null;for(;e===Kn;)Kn=nt[--rt],nt[rt]=null,Ft=nt[--rt],nt[rt]=null,zt=nt[--rt],nt[rt]=null}var Xe=null,Qe=null,se=!1,vt=null;function Zw(e,t){var n=it(5,null,null,0);n.elementType="DELETED",n.stateNode=t,n.return=e,t=e.deletions,t===null?(e.deletions=[n],e.flags|=16):t.push(n)}function Rg(e,t){switch(e.tag){case 5:var n=e.type;return t=t.nodeType!==1||n.toLowerCase()!==t.nodeName.toLowerCase()?null:t,t!==null?(e.stateNode=t,Xe=e,Qe=mn(t.firstChild),!0):!1;case 6:return t=e.pendingProps===""||t.nodeType!==3?null:t,t!==null?(e.stateNode=t,Xe=e,Qe=null,!0):!1;case 13:return t=t.nodeType!==8?null:t,t!==null?(n=Kn!==null?{id:zt,overflow:Ft}:null,e.memoizedState={dehydrated:t,treeContext:n,retryLane:1073741824},n=it(18,null,null,0),n.stateNode=t,n.return=e,e.child=n,Xe=e,Qe=null,!0):!1;default:return!1}}function Ph(e){return(e.mode&1)!==0&&(e.flags&128)===0}function jh(e){if(se){var t=Qe;if(t){var n=t;if(!Rg(e,t)){if(Ph(e))throw Error(q(418));t=mn(n.nextSibling);var r=Xe;t&&Rg(e,t)?Zw(r,n):(e.flags=e.flags&-4097|2,se=!1,Xe=e)}}else{if(Ph(e))throw Error(q(418));e.flags=e.flags&-4097|2,se=!1,Xe=e}}}function Ng(e){for(e=e.return;e!==null&&e.tag!==5&&e.tag!==3&&e.tag!==13;)e=e.return;Xe=e}function Ao(e){if(e!==Xe)return!1;if(!se)return Ng(e),se=!0,!1;var t;if((t=e.tag!==3)&&!(t=e.tag!==5)&&(t=e.type,t=t!=="head"&&t!=="body"&&!Th(e.type,e.memoizedProps)),t&&(t=Qe)){if(Ph(e))throw Jw(),Error(q(418));for(;t;)Zw(e,t),t=mn(t.nextSibling)}if(Ng(e),e.tag===13){if(e=e.memoizedState,e=e!==null?e.dehydrated:null,!e)throw Error(q(317));e:{for(e=e.nextSibling,t=0;e;){if(e.nodeType===8){var n=e.data;if(n==="/$"){if(t===0){Qe=mn(e.nextSibling);break e}t--}else n!=="$"&&n!=="$!"&&n!=="$?"||t++}e=e.nextSibling}Qe=null}}else Qe=Xe?mn(e.stateNode.nextSibling):null;return!0}function Jw(){for(var e=Qe;e;)e=mn(e.nextSibling)}function Lr(){Qe=Xe=null,se=!1}function Mp(e){vt===null?vt=[e]:vt.push(e)}var ab=Qt.ReactCurrentBatchConfig;function si(e,t,n){if(e=n.ref,e!==null&&typeof e!="function"&&typeof e!="object"){if(n._owner){if(n=n._owner,n){if(n.tag!==1)throw Error(q(309));var r=n.stateNode}if(!r)throw Error(q(147,e));var i=r,o=""+e;return t!==null&&t.ref!==null&&typeof t.ref=="function"&&t.ref._stringRef===o?t.ref:(t=function(a){var s=i.refs;a===null?delete s[o]:s[o]=a},t._stringRef=o,t)}if(typeof e!="string")throw Error(q(284));if(!n._owner)throw Error(q(290,e))}return e}function Mo(e,t){throw e=Object.prototype.toString.call(t),Error(q(31,e==="[object Object]"?"object with keys {"+Object.keys(t).join(", ")+"}":e))}function Ig(e){var t=e._init;return t(e._payload)}function eS(e){function t(p,m){if(e){var _=p.deletions;_===null?(p.deletions=[m],p.flags|=16):_.push(m)}}function n(p,m){if(!e)return null;for(;m!==null;)t(p,m),m=m.sibling;return null}function r(p,m){for(p=new Map;m!==null;)m.key!==null?p.set(m.key,m):p.set(m.index,m),m=m.sibling;return p}function i(p,m){return p=wn(p,m),p.index=0,p.sibling=null,p}function o(p,m,_){return p.index=_,e?(_=p.alternate,_!==null?(_=_.index,_<m?(p.flags|=2,m):_):(p.flags|=2,m)):(p.flags|=1048576,m)}function a(p){return e&&p.alternate===null&&(p.flags|=2),p}function s(p,m,_,x){return m===null||m.tag!==6?(m=tu(_,p.mode,x),m.return=p,m):(m=i(m,_),m.return=p,m)}function u(p,m,_,x){var S=_.type;return S===vr?c(p,m,_.props.children,x,_.key):m!==null&&(m.elementType===S||typeof S=="object"&&S!==null&&S.$$typeof===rn&&Ig(S)===m.type)?(x=i(m,_.props),x.ref=si(p,m,_),x.return=p,x):(x=ia(_.type,_.key,_.props,null,p.mode,x),x.ref=si(p,m,_),x.return=p,x)}function l(p,m,_,x){return m===null||m.tag!==4||m.stateNode.containerInfo!==_.containerInfo||m.stateNode.implementation!==_.implementation?(m=nu(_,p.mode,x),m.return=p,m):(m=i(m,_.children||[]),m.return=p,m)}function c(p,m,_,x,S){return m===null||m.tag!==7?(m=Hn(_,p.mode,x,S),m.return=p,m):(m=i(m,_),m.return=p,m)}function f(p,m,_){if(typeof m=="string"&&m!==""||typeof m=="number")return m=tu(""+m,p.mode,_),m.return=p,m;if(typeof m=="object"&&m!==null){switch(m.$$typeof){case Co:return _=ia(m.type,m.key,m.props,null,p.mode,_),_.ref=si(p,null,m),_.return=p,_;case pr:return m=nu(m,p.mode,_),m.return=p,m;case rn:var x=m._init;return f(p,x(m._payload),_)}if(hi(m)||ni(m))return m=Hn(m,p.mode,_,null),m.return=p,m;Mo(p,m)}return null}function d(p,m,_,x){var S=m!==null?m.key:null;if(typeof _=="string"&&_!==""||typeof _=="number")return S!==null?null:s(p,m,""+_,x);if(typeof _=="object"&&_!==null){switch(_.$$typeof){case Co:return _.key===S?u(p,m,_,x):null;case pr:return _.key===S?l(p,m,_,x):null;case rn:return S=_._init,d(p,m,S(_._payload),x)}if(hi(_)||ni(_))return S!==null?null:c(p,m,_,x,null);Mo(p,_)}return null}function h(p,m,_,x,S){if(typeof x=="string"&&x!==""||typeof x=="number")return p=p.get(_)||null,s(m,p,""+x,S);if(typeof x=="object"&&x!==null){switch(x.$$typeof){case Co:return p=p.get(x.key===null?_:x.key)||null,u(m,p,x,S);case pr:return p=p.get(x.key===null?_:x.key)||null,l(m,p,x,S);case rn:var E=x._init;return h(p,m,_,E(x._payload),S)}if(hi(x)||ni(x))return p=p.get(_)||null,c(m,p,x,S,null);Mo(m,x)}return null}function g(p,m,_,x){for(var S=null,E=null,C=m,T=m=0,M=null;C!==null&&T<_.length;T++){C.index>T?(M=C,C=null):M=C.sibling;var k=d(p,C,_[T],x);if(k===null){C===null&&(C=M);break}e&&C&&k.alternate===null&&t(p,C),m=o(k,m,T),E===null?S=k:E.sibling=k,E=k,C=M}if(T===_.length)return n(p,C),se&&Mn(p,T),S;if(C===null){for(;T<_.length;T++)C=f(p,_[T],x),C!==null&&(m=o(C,m,T),E===null?S=C:E.sibling=C,E=C);return se&&Mn(p,T),S}for(C=r(p,C);T<_.length;T++)M=h(C,p,T,_[T],x),M!==null&&(e&&M.alternate!==null&&C.delete(M.key===null?T:M.key),m=o(M,m,T),E===null?S=M:E.sibling=M,E=M);return e&&C.forEach(function(j){return t(p,j)}),se&&Mn(p,T),S}function v(p,m,_,x){var S=ni(_);if(typeof S!="function")throw Error(q(150));if(_=S.call(_),_==null)throw Error(q(151));for(var E=S=null,C=m,T=m=0,M=null,k=_.next();C!==null&&!k.done;T++,k=_.next()){C.index>T?(M=C,C=null):M=C.sibling;var j=d(p,C,k.value,x);if(j===null){C===null&&(C=M);break}e&&C&&j.alternate===null&&t(p,C),m=o(j,m,T),E===null?S=j:E.sibling=j,E=j,C=M}if(k.done)return n(p,C),se&&Mn(p,T),S;if(C===null){for(;!k.done;T++,k=_.next())k=f(p,k.value,x),k!==null&&(m=o(k,m,T),E===null?S=k:E.sibling=k,E=k);return se&&Mn(p,T),S}for(C=r(p,C);!k.done;T++,k=_.next())k=h(C,p,T,k.value,x),k!==null&&(e&&k.alternate!==null&&C.delete(k.key===null?T:k.key),m=o(k,m,T),E===null?S=k:E.sibling=k,E=k);return e&&C.forEach(function(B){return t(p,B)}),se&&Mn(p,T),S}function y(p,m,_,x){if(typeof _=="object"&&_!==null&&_.type===vr&&_.key===null&&(_=_.props.children),typeof _=="object"&&_!==null){switch(_.$$typeof){case Co:e:{for(var S=_.key,E=m;E!==null;){if(E.key===S){if(S=_.type,S===vr){if(E.tag===7){n(p,E.sibling),m=i(E,_.props.children),m.return=p,p=m;break e}}else if(E.elementType===S||typeof S=="object"&&S!==null&&S.$$typeof===rn&&Ig(S)===E.type){n(p,E.sibling),m=i(E,_.props),m.ref=si(p,E,_),m.return=p,p=m;break e}n(p,E);break}else t(p,E);E=E.sibling}_.type===vr?(m=Hn(_.props.children,p.mode,x,_.key),m.return=p,p=m):(x=ia(_.type,_.key,_.props,null,p.mode,x),x.ref=si(p,m,_),x.return=p,p=x)}return a(p);case pr:e:{for(E=_.key;m!==null;){if(m.key===E)if(m.tag===4&&m.stateNode.containerInfo===_.containerInfo&&m.stateNode.implementation===_.implementation){n(p,m.sibling),m=i(m,_.children||[]),m.return=p,p=m;break e}else{n(p,m);break}else t(p,m);m=m.sibling}m=nu(_,p.mode,x),m.return=p,p=m}return a(p);case rn:return E=_._init,y(p,m,E(_._payload),x)}if(hi(_))return g(p,m,_,x);if(ni(_))return v(p,m,_,x);Mo(p,_)}return typeof _=="string"&&_!==""||typeof _=="number"?(_=""+_,m!==null&&m.tag===6?(n(p,m.sibling),m=i(m,_),m.return=p,p=m):(n(p,m),m=tu(_,p.mode,x),m.return=p,p=m),a(p)):n(p,m)}return y}var Or=eS(!0),tS=eS(!1),Sa=Nn(null),Ea=null,Er=null,Lp=null;function Op(){Lp=Er=Ea=null}function zp(e){var t=Sa.current;ae(Sa),e._currentValue=t}function qh(e,t,n){for(;e!==null;){var r=e.alternate;if((e.childLanes&t)!==t?(e.childLanes|=t,r!==null&&(r.childLanes|=t)):r!==null&&(r.childLanes&t)!==t&&(r.childLanes|=t),e===n)break;e=e.return}}function Ir(e,t){Ea=e,Lp=Er=null,e=e.dependencies,e!==null&&e.firstContext!==null&&(e.lanes&t&&($e=!0),e.firstContext=null)}function at(e){var t=e._currentValue;if(Lp!==e)if(e={context:e,memoizedValue:t,next:null},Er===null){if(Ea===null)throw Error(q(308));Er=e,Ea.dependencies={lanes:0,firstContext:e}}else Er=Er.next=e;return t}var Fn=null;function Fp(e){Fn===null?Fn=[e]:Fn.push(e)}function nS(e,t,n,r){var i=t.interleaved;return i===null?(n.next=n,Fp(t)):(n.next=i.next,i.next=n),t.interleaved=n,Gt(e,r)}function Gt(e,t){e.lanes|=t;var n=e.alternate;for(n!==null&&(n.lanes|=t),n=e,e=e.return;e!==null;)e.childLanes|=t,n=e.alternate,n!==null&&(n.childLanes|=t),n=e,e=e.return;return n.tag===3?n.stateNode:null}var on=!1;function Dp(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function rS(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function Ut(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function yn(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,W&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,Gt(e,n)}return i=r.interleaved,i===null?(t.next=t,Fp(r)):(t.next=i.next,i.next=t),r.interleaved=t,Gt(e,n)}function Zo(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,(n&4194240)!==0)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,kp(e,n)}}function Pg(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var i=null,o=null;if(n=n.firstBaseUpdate,n!==null){do{var a={eventTime:n.eventTime,lane:n.lane,tag:n.tag,payload:n.payload,callback:n.callback,next:null};o===null?i=o=a:o=o.next=a,n=n.next}while(n!==null);o===null?i=o=t:o=o.next=t}else i=o=t;n={baseState:r.baseState,firstBaseUpdate:i,lastBaseUpdate:o,shared:r.shared,effects:r.effects},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}function Ca(e,t,n,r){var i=e.updateQueue;on=!1;var o=i.firstBaseUpdate,a=i.lastBaseUpdate,s=i.shared.pending;if(s!==null){i.shared.pending=null;var u=s,l=u.next;u.next=null,a===null?o=l:a.next=l,a=u;var c=e.alternate;c!==null&&(c=c.updateQueue,s=c.lastBaseUpdate,s!==a&&(s===null?c.firstBaseUpdate=l:s.next=l,c.lastBaseUpdate=u))}if(o!==null){var f=i.baseState;a=0,c=l=u=null,s=o;do{var d=s.lane,h=s.eventTime;if((r&d)===d){c!==null&&(c=c.next={eventTime:h,lane:0,tag:s.tag,payload:s.payload,callback:s.callback,next:null});e:{var g=e,v=s;switch(d=t,h=n,v.tag){case 1:if(g=v.payload,typeof g=="function"){f=g.call(h,f,d);break e}f=g;break e;case 3:g.flags=g.flags&-65537|128;case 0:if(g=v.payload,d=typeof g=="function"?g.call(h,f,d):g,d==null)break e;f=fe({},f,d);break e;case 2:on=!0}}s.callback!==null&&s.lane!==0&&(e.flags|=64,d=i.effects,d===null?i.effects=[s]:d.push(s))}else h={eventTime:h,lane:d,tag:s.tag,payload:s.payload,callback:s.callback,next:null},c===null?(l=c=h,u=f):c=c.next=h,a|=d;if(s=s.next,s===null){if(s=i.shared.pending,s===null)break;d=s,s=d.next,d.next=null,i.lastBaseUpdate=d,i.shared.pending=null}}while(!0);if(c===null&&(u=f),i.baseState=u,i.firstBaseUpdate=l,i.lastBaseUpdate=c,t=i.shared.interleaved,t!==null){i=t;do a|=i.lane,i=i.next;while(i!==t)}else o===null&&(i.shared.lanes=0);Qn|=a,e.lanes=a,e.memoizedState=f}}function jg(e,t,n){if(e=t.effects,t.effects=null,e!==null)for(t=0;t<e.length;t++){var r=e[t],i=r.callback;if(i!==null){if(r.callback=null,r=n,typeof i!="function")throw Error(q(191,i));i.call(r)}}}var so={},Rt=Nn(so),Hi=Nn(so),Vi=Nn(so);function Dn(e){if(e===so)throw Error(q(174));return e}function $p(e,t){switch(re(Vi,t),re(Hi,e),re(Rt,so),e=t.nodeType,e){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:hh(null,"");break;default:e=e===8?t.parentNode:t,t=e.namespaceURI||null,e=e.tagName,t=hh(t,e)}ae(Rt),re(Rt,t)}function zr(){ae(Rt),ae(Hi),ae(Vi)}function iS(e){Dn(Vi.current);var t=Dn(Rt.current),n=hh(t,e.type);t!==n&&(re(Hi,e),re(Rt,n))}function Bp(e){Hi.current===e&&(ae(Rt),ae(Hi))}var le=Nn(0);function ka(e){for(var t=e;t!==null;){if(t.tag===13){var n=t.memoizedState;if(n!==null&&(n=n.dehydrated,n===null||n.data==="$?"||n.data==="$!"))return t}else if(t.tag===19&&t.memoizedProps.revealOrder!==void 0){if(t.flags&128)return t}else if(t.child!==null){t.child.return=t,t=t.child;continue}if(t===e)break;for(;t.sibling===null;){if(t.return===null||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}var Ys=[];function Up(){for(var e=0;e<Ys.length;e++)Ys[e]._workInProgressVersionPrimary=null;Ys.length=0}var Jo=Qt.ReactCurrentDispatcher,Qs=Qt.ReactCurrentBatchConfig,Yn=0,ce=null,ye=null,we=null,ba=!1,Ni=!1,Gi=0,sb=0;function Re(){throw Error(q(321))}function Hp(e,t){if(t===null)return!1;for(var n=0;n<t.length&&n<e.length;n++)if(!_t(e[n],t[n]))return!1;return!0}function Vp(e,t,n,r,i,o){if(Yn=o,ce=t,t.memoizedState=null,t.updateQueue=null,t.lanes=0,Jo.current=e===null||e.memoizedState===null?fb:db,e=n(r,i),Ni){o=0;do{if(Ni=!1,Gi=0,25<=o)throw Error(q(301));o+=1,we=ye=null,t.updateQueue=null,Jo.current=hb,e=n(r,i)}while(Ni)}if(Jo.current=Ta,t=ye!==null&&ye.next!==null,Yn=0,we=ye=ce=null,ba=!1,t)throw Error(q(300));return e}function Gp(){var e=Gi!==0;return Gi=0,e}function Ct(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return we===null?ce.memoizedState=we=e:we=we.next=e,we}function st(){if(ye===null){var e=ce.alternate;e=e!==null?e.memoizedState:null}else e=ye.next;var t=we===null?ce.memoizedState:we.next;if(t!==null)we=t,ye=e;else{if(e===null)throw Error(q(310));ye=e,e={memoizedState:ye.memoizedState,baseState:ye.baseState,baseQueue:ye.baseQueue,queue:ye.queue,next:null},we===null?ce.memoizedState=we=e:we=we.next=e}return we}function Wi(e,t){return typeof t=="function"?t(e):t}function Xs(e){var t=st(),n=t.queue;if(n===null)throw Error(q(311));n.lastRenderedReducer=e;var r=ye,i=r.baseQueue,o=n.pending;if(o!==null){if(i!==null){var a=i.next;i.next=o.next,o.next=a}r.baseQueue=i=o,n.pending=null}if(i!==null){o=i.next,r=r.baseState;var s=a=null,u=null,l=o;do{var c=l.lane;if((Yn&c)===c)u!==null&&(u=u.next={lane:0,action:l.action,hasEagerState:l.hasEagerState,eagerState:l.eagerState,next:null}),r=l.hasEagerState?l.eagerState:e(r,l.action);else{var f={lane:c,action:l.action,hasEagerState:l.hasEagerState,eagerState:l.eagerState,next:null};u===null?(s=u=f,a=r):u=u.next=f,ce.lanes|=c,Qn|=c}l=l.next}while(l!==null&&l!==o);u===null?a=r:u.next=s,_t(r,t.memoizedState)||($e=!0),t.memoizedState=r,t.baseState=a,t.baseQueue=u,n.lastRenderedState=r}if(e=n.interleaved,e!==null){i=e;do o=i.lane,ce.lanes|=o,Qn|=o,i=i.next;while(i!==e)}else i===null&&(n.lanes=0);return[t.memoizedState,n.dispatch]}function Zs(e){var t=st(),n=t.queue;if(n===null)throw Error(q(311));n.lastRenderedReducer=e;var r=n.dispatch,i=n.pending,o=t.memoizedState;if(i!==null){n.pending=null;var a=i=i.next;do o=e(o,a.action),a=a.next;while(a!==i);_t(o,t.memoizedState)||($e=!0),t.memoizedState=o,t.baseQueue===null&&(t.baseState=o),n.lastRenderedState=o}return[o,r]}function oS(){}function aS(e,t){var n=ce,r=st(),i=t(),o=!_t(r.memoizedState,i);if(o&&(r.memoizedState=i,$e=!0),r=r.queue,Wp(lS.bind(null,n,r,e),[e]),r.getSnapshot!==t||o||we!==null&&we.memoizedState.tag&1){if(n.flags|=2048,Ki(9,uS.bind(null,n,r,i,t),void 0,null),Se===null)throw Error(q(349));Yn&30||sS(n,t,i)}return i}function sS(e,t,n){e.flags|=16384,e={getSnapshot:t,value:n},t=ce.updateQueue,t===null?(t={lastEffect:null,stores:null},ce.updateQueue=t,t.stores=[e]):(n=t.stores,n===null?t.stores=[e]:n.push(e))}function uS(e,t,n,r){t.value=n,t.getSnapshot=r,cS(t)&&fS(e)}function lS(e,t,n){return n(function(){cS(t)&&fS(e)})}function cS(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!_t(e,n)}catch{return!0}}function fS(e){var t=Gt(e,1);t!==null&&yt(t,e,1,-1)}function qg(e){var t=Ct();return typeof e=="function"&&(e=e()),t.memoizedState=t.baseState=e,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:Wi,lastRenderedState:e},t.queue=e,e=e.dispatch=cb.bind(null,ce,e),[t.memoizedState,e]}function Ki(e,t,n,r){return e={tag:e,create:t,destroy:n,deps:r,next:null},t=ce.updateQueue,t===null?(t={lastEffect:null,stores:null},ce.updateQueue=t,t.lastEffect=e.next=e):(n=t.lastEffect,n===null?t.lastEffect=e.next=e:(r=n.next,n.next=e,e.next=r,t.lastEffect=e)),e}function dS(){return st().memoizedState}function ea(e,t,n,r){var i=Ct();ce.flags|=e,i.memoizedState=Ki(1|t,n,void 0,r===void 0?null:r)}function Za(e,t,n,r){var i=st();r=r===void 0?null:r;var o=void 0;if(ye!==null){var a=ye.memoizedState;if(o=a.destroy,r!==null&&Hp(r,a.deps)){i.memoizedState=Ki(t,n,o,r);return}}ce.flags|=e,i.memoizedState=Ki(1|t,n,o,r)}function Ag(e,t){return ea(8390656,8,e,t)}function Wp(e,t){return Za(2048,8,e,t)}function hS(e,t){return Za(4,2,e,t)}function pS(e,t){return Za(4,4,e,t)}function vS(e,t){if(typeof t=="function")return e=e(),t(e),function(){t(null)};if(t!=null)return e=e(),t.current=e,function(){t.current=null}}function gS(e,t,n){return n=n!=null?n.concat([e]):null,Za(4,4,vS.bind(null,t,e),n)}function Kp(){}function mS(e,t){var n=st();t=t===void 0?null:t;var r=n.memoizedState;return r!==null&&t!==null&&Hp(t,r[1])?r[0]:(n.memoizedState=[e,t],e)}function yS(e,t){var n=st();t=t===void 0?null:t;var r=n.memoizedState;return r!==null&&t!==null&&Hp(t,r[1])?r[0]:(e=e(),n.memoizedState=[e,t],e)}function _S(e,t,n){return Yn&21?(_t(n,t)||(n=Cw(),ce.lanes|=n,Qn|=n,e.baseState=!0),t):(e.baseState&&(e.baseState=!1,$e=!0),e.memoizedState=n)}function ub(e,t){var n=X;X=n!==0&&4>n?n:4,e(!0);var r=Qs.transition;Qs.transition={};try{e(!1),t()}finally{X=n,Qs.transition=r}}function xS(){return st().memoizedState}function lb(e,t,n){var r=xn(e);if(n={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null},wS(e))SS(t,n);else if(n=nS(e,t,n,r),n!==null){var i=Ae();yt(n,e,r,i),ES(n,t,r)}}function cb(e,t,n){var r=xn(e),i={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null};if(wS(e))SS(t,i);else{var o=e.alternate;if(e.lanes===0&&(o===null||o.lanes===0)&&(o=t.lastRenderedReducer,o!==null))try{var a=t.lastRenderedState,s=o(a,n);if(i.hasEagerState=!0,i.eagerState=s,_t(s,a)){var u=t.interleaved;u===null?(i.next=i,Fp(t)):(i.next=u.next,u.next=i),t.interleaved=i;return}}catch{}finally{}n=nS(e,t,i,r),n!==null&&(i=Ae(),yt(n,e,r,i),ES(n,t,r))}}function wS(e){var t=e.alternate;return e===ce||t!==null&&t===ce}function SS(e,t){Ni=ba=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function ES(e,t,n){if(n&4194240){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,kp(e,n)}}var Ta={readContext:at,useCallback:Re,useContext:Re,useEffect:Re,useImperativeHandle:Re,useInsertionEffect:Re,useLayoutEffect:Re,useMemo:Re,useReducer:Re,useRef:Re,useState:Re,useDebugValue:Re,useDeferredValue:Re,useTransition:Re,useMutableSource:Re,useSyncExternalStore:Re,useId:Re,unstable_isNewReconciler:!1},fb={readContext:at,useCallback:function(e,t){return Ct().memoizedState=[e,t===void 0?null:t],e},useContext:at,useEffect:Ag,useImperativeHandle:function(e,t,n){return n=n!=null?n.concat([e]):null,ea(4194308,4,vS.bind(null,t,e),n)},useLayoutEffect:function(e,t){return ea(4194308,4,e,t)},useInsertionEffect:function(e,t){return ea(4,2,e,t)},useMemo:function(e,t){var n=Ct();return t=t===void 0?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=Ct();return t=n!==void 0?n(t):t,r.memoizedState=r.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},r.queue=e,e=e.dispatch=lb.bind(null,ce,e),[r.memoizedState,e]},useRef:function(e){var t=Ct();return e={current:e},t.memoizedState=e},useState:qg,useDebugValue:Kp,useDeferredValue:function(e){return Ct().memoizedState=e},useTransition:function(){var e=qg(!1),t=e[0];return e=ub.bind(null,e[1]),Ct().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,n){var r=ce,i=Ct();if(se){if(n===void 0)throw Error(q(407));n=n()}else{if(n=t(),Se===null)throw Error(q(349));Yn&30||sS(r,t,n)}i.memoizedState=n;var o={value:n,getSnapshot:t};return i.queue=o,Ag(lS.bind(null,r,o,e),[e]),r.flags|=2048,Ki(9,uS.bind(null,r,o,n,t),void 0,null),n},useId:function(){var e=Ct(),t=Se.identifierPrefix;if(se){var n=Ft,r=zt;n=(r&~(1<<32-mt(r)-1)).toString(32)+n,t=":"+t+"R"+n,n=Gi++,0<n&&(t+="H"+n.toString(32)),t+=":"}else n=sb++,t=":"+t+"r"+n.toString(32)+":";return e.memoizedState=t},unstable_isNewReconciler:!1},db={readContext:at,useCallback:mS,useContext:at,useEffect:Wp,useImperativeHandle:gS,useInsertionEffect:hS,useLayoutEffect:pS,useMemo:yS,useReducer:Xs,useRef:dS,useState:function(){return Xs(Wi)},useDebugValue:Kp,useDeferredValue:function(e){var t=st();return _S(t,ye.memoizedState,e)},useTransition:function(){var e=Xs(Wi)[0],t=st().memoizedState;return[e,t]},useMutableSource:oS,useSyncExternalStore:aS,useId:xS,unstable_isNewReconciler:!1},hb={readContext:at,useCallback:mS,useContext:at,useEffect:Wp,useImperativeHandle:gS,useInsertionEffect:hS,useLayoutEffect:pS,useMemo:yS,useReducer:Zs,useRef:dS,useState:function(){return Zs(Wi)},useDebugValue:Kp,useDeferredValue:function(e){var t=st();return ye===null?t.memoizedState=e:_S(t,ye.memoizedState,e)},useTransition:function(){var e=Zs(Wi)[0],t=st().memoizedState;return[e,t]},useMutableSource:oS,useSyncExternalStore:aS,useId:xS,unstable_isNewReconciler:!1};function ht(e,t){if(e&&e.defaultProps){t=fe({},t),e=e.defaultProps;for(var n in e)t[n]===void 0&&(t[n]=e[n]);return t}return t}function Ah(e,t,n,r){t=e.memoizedState,n=n(r,t),n=n==null?t:fe({},t,n),e.memoizedState=n,e.lanes===0&&(e.updateQueue.baseState=n)}var Ja={isMounted:function(e){return(e=e._reactInternals)?er(e)===e:!1},enqueueSetState:function(e,t,n){e=e._reactInternals;var r=Ae(),i=xn(e),o=Ut(r,i);o.payload=t,n!=null&&(o.callback=n),t=yn(e,o,i),t!==null&&(yt(t,e,i,r),Zo(t,e,i))},enqueueReplaceState:function(e,t,n){e=e._reactInternals;var r=Ae(),i=xn(e),o=Ut(r,i);o.tag=1,o.payload=t,n!=null&&(o.callback=n),t=yn(e,o,i),t!==null&&(yt(t,e,i,r),Zo(t,e,i))},enqueueForceUpdate:function(e,t){e=e._reactInternals;var n=Ae(),r=xn(e),i=Ut(n,r);i.tag=2,t!=null&&(i.callback=t),t=yn(e,i,r),t!==null&&(yt(t,e,r,n),Zo(t,e,r))}};function Mg(e,t,n,r,i,o,a){return e=e.stateNode,typeof e.shouldComponentUpdate=="function"?e.shouldComponentUpdate(r,o,a):t.prototype&&t.prototype.isPureReactComponent?!Di(n,r)||!Di(i,o):!0}function CS(e,t,n){var r=!1,i=kn,o=t.contextType;return typeof o=="object"&&o!==null?o=at(o):(i=He(t)?Wn:Pe.current,r=t.contextTypes,o=(r=r!=null)?Mr(e,i):kn),t=new t(n,o),e.memoizedState=t.state!==null&&t.state!==void 0?t.state:null,t.updater=Ja,e.stateNode=t,t._reactInternals=e,r&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=i,e.__reactInternalMemoizedMaskedChildContext=o),t}function Lg(e,t,n,r){e=t.state,typeof t.componentWillReceiveProps=="function"&&t.componentWillReceiveProps(n,r),typeof t.UNSAFE_componentWillReceiveProps=="function"&&t.UNSAFE_componentWillReceiveProps(n,r),t.state!==e&&Ja.enqueueReplaceState(t,t.state,null)}function Mh(e,t,n,r){var i=e.stateNode;i.props=n,i.state=e.memoizedState,i.refs={},Dp(e);var o=t.contextType;typeof o=="object"&&o!==null?i.context=at(o):(o=He(t)?Wn:Pe.current,i.context=Mr(e,o)),i.state=e.memoizedState,o=t.getDerivedStateFromProps,typeof o=="function"&&(Ah(e,t,o,n),i.state=e.memoizedState),typeof t.getDerivedStateFromProps=="function"||typeof i.getSnapshotBeforeUpdate=="function"||typeof i.UNSAFE_componentWillMount!="function"&&typeof i.componentWillMount!="function"||(t=i.state,typeof i.componentWillMount=="function"&&i.componentWillMount(),typeof i.UNSAFE_componentWillMount=="function"&&i.UNSAFE_componentWillMount(),t!==i.state&&Ja.enqueueReplaceState(i,i.state,null),Ca(e,n,i,r),i.state=e.memoizedState),typeof i.componentDidMount=="function"&&(e.flags|=4194308)}function Fr(e,t){try{var n="",r=t;do n+=$k(r),r=r.return;while(r);var i=n}catch(o){i=` 47 - Error generating stack: `+o.message+` 48 - `+o.stack}return{value:e,source:t,stack:i,digest:null}}function Js(e,t,n){return{value:e,source:null,stack:n??null,digest:t??null}}function Lh(e,t){try{console.error(t.value)}catch(n){setTimeout(function(){throw n})}}var pb=typeof WeakMap=="function"?WeakMap:Map;function kS(e,t,n){n=Ut(-1,n),n.tag=3,n.payload={element:null};var r=t.value;return n.callback=function(){Na||(Na=!0,Gh=r),Lh(e,t)},n}function bS(e,t,n){n=Ut(-1,n),n.tag=3;var r=e.type.getDerivedStateFromError;if(typeof r=="function"){var i=t.value;n.payload=function(){return r(i)},n.callback=function(){Lh(e,t)}}var o=e.stateNode;return o!==null&&typeof o.componentDidCatch=="function"&&(n.callback=function(){Lh(e,t),typeof r!="function"&&(_n===null?_n=new Set([this]):_n.add(this));var a=t.stack;this.componentDidCatch(t.value,{componentStack:a!==null?a:""})}),n}function Og(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new pb;var i=new Set;r.set(t,i)}else i=r.get(t),i===void 0&&(i=new Set,r.set(t,i));i.has(n)||(i.add(n),e=Rb.bind(null,e,t,n),t.then(e,e))}function zg(e){do{var t;if((t=e.tag===13)&&(t=e.memoizedState,t=t!==null?t.dehydrated!==null:!0),t)return e;e=e.return}while(e!==null);return null}function Fg(e,t,n,r,i){return e.mode&1?(e.flags|=65536,e.lanes=i,e):(e===t?e.flags|=65536:(e.flags|=128,n.flags|=131072,n.flags&=-52805,n.tag===1&&(n.alternate===null?n.tag=17:(t=Ut(-1,1),t.tag=2,yn(n,t,1))),n.lanes|=1),e)}var vb=Qt.ReactCurrentOwner,$e=!1;function je(e,t,n,r){t.child=e===null?tS(t,null,n,r):Or(t,e.child,n,r)}function Dg(e,t,n,r,i){n=n.render;var o=t.ref;return Ir(t,i),r=Vp(e,t,n,r,o,i),n=Gp(),e!==null&&!$e?(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~i,Wt(e,t,i)):(se&&n&&qp(t),t.flags|=1,je(e,t,r,i),t.child)}function $g(e,t,n,r,i){if(e===null){var o=n.type;return typeof o=="function"&&!nv(o)&&o.defaultProps===void 0&&n.compare===null&&n.defaultProps===void 0?(t.tag=15,t.type=o,TS(e,t,o,r,i)):(e=ia(n.type,null,r,t,t.mode,i),e.ref=t.ref,e.return=t,t.child=e)}if(o=e.child,!(e.lanes&i)){var a=o.memoizedProps;if(n=n.compare,n=n!==null?n:Di,n(a,r)&&e.ref===t.ref)return Wt(e,t,i)}return t.flags|=1,e=wn(o,r),e.ref=t.ref,e.return=t,t.child=e}function TS(e,t,n,r,i){if(e!==null){var o=e.memoizedProps;if(Di(o,r)&&e.ref===t.ref)if($e=!1,t.pendingProps=r=o,(e.lanes&i)!==0)e.flags&131072&&($e=!0);else return t.lanes=e.lanes,Wt(e,t,i)}return Oh(e,t,n,r,i)}function RS(e,t,n){var r=t.pendingProps,i=r.children,o=e!==null?e.memoizedState:null;if(r.mode==="hidden")if(!(t.mode&1))t.memoizedState={baseLanes:0,cachePool:null,transitions:null},re(kr,Ke),Ke|=n;else{if(!(n&1073741824))return e=o!==null?o.baseLanes|n:n,t.lanes=t.childLanes=1073741824,t.memoizedState={baseLanes:e,cachePool:null,transitions:null},t.updateQueue=null,re(kr,Ke),Ke|=e,null;t.memoizedState={baseLanes:0,cachePool:null,transitions:null},r=o!==null?o.baseLanes:n,re(kr,Ke),Ke|=r}else o!==null?(r=o.baseLanes|n,t.memoizedState=null):r=n,re(kr,Ke),Ke|=r;return je(e,t,i,n),t.child}function NS(e,t){var n=t.ref;(e===null&&n!==null||e!==null&&e.ref!==n)&&(t.flags|=512,t.flags|=2097152)}function Oh(e,t,n,r,i){var o=He(n)?Wn:Pe.current;return o=Mr(t,o),Ir(t,i),n=Vp(e,t,n,r,o,i),r=Gp(),e!==null&&!$e?(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~i,Wt(e,t,i)):(se&&r&&qp(t),t.flags|=1,je(e,t,n,i),t.child)}function Bg(e,t,n,r,i){if(He(n)){var o=!0;_a(t)}else o=!1;if(Ir(t,i),t.stateNode===null)ta(e,t),CS(t,n,r),Mh(t,n,r,i),r=!0;else if(e===null){var a=t.stateNode,s=t.memoizedProps;a.props=s;var u=a.context,l=n.contextType;typeof l=="object"&&l!==null?l=at(l):(l=He(n)?Wn:Pe.current,l=Mr(t,l));var c=n.getDerivedStateFromProps,f=typeof c=="function"||typeof a.getSnapshotBeforeUpdate=="function";f||typeof a.UNSAFE_componentWillReceiveProps!="function"&&typeof a.componentWillReceiveProps!="function"||(s!==r||u!==l)&&Lg(t,a,r,l),on=!1;var d=t.memoizedState;a.state=d,Ca(t,r,a,i),u=t.memoizedState,s!==r||d!==u||Ue.current||on?(typeof c=="function"&&(Ah(t,n,c,r),u=t.memoizedState),(s=on||Mg(t,n,s,r,d,u,l))?(f||typeof a.UNSAFE_componentWillMount!="function"&&typeof a.componentWillMount!="function"||(typeof a.componentWillMount=="function"&&a.componentWillMount(),typeof a.UNSAFE_componentWillMount=="function"&&a.UNSAFE_componentWillMount()),typeof a.componentDidMount=="function"&&(t.flags|=4194308)):(typeof a.componentDidMount=="function"&&(t.flags|=4194308),t.memoizedProps=r,t.memoizedState=u),a.props=r,a.state=u,a.context=l,r=s):(typeof a.componentDidMount=="function"&&(t.flags|=4194308),r=!1)}else{a=t.stateNode,rS(e,t),s=t.memoizedProps,l=t.type===t.elementType?s:ht(t.type,s),a.props=l,f=t.pendingProps,d=a.context,u=n.contextType,typeof u=="object"&&u!==null?u=at(u):(u=He(n)?Wn:Pe.current,u=Mr(t,u));var h=n.getDerivedStateFromProps;(c=typeof h=="function"||typeof a.getSnapshotBeforeUpdate=="function")||typeof a.UNSAFE_componentWillReceiveProps!="function"&&typeof a.componentWillReceiveProps!="function"||(s!==f||d!==u)&&Lg(t,a,r,u),on=!1,d=t.memoizedState,a.state=d,Ca(t,r,a,i);var g=t.memoizedState;s!==f||d!==g||Ue.current||on?(typeof h=="function"&&(Ah(t,n,h,r),g=t.memoizedState),(l=on||Mg(t,n,l,r,d,g,u)||!1)?(c||typeof a.UNSAFE_componentWillUpdate!="function"&&typeof a.componentWillUpdate!="function"||(typeof a.componentWillUpdate=="function"&&a.componentWillUpdate(r,g,u),typeof a.UNSAFE_componentWillUpdate=="function"&&a.UNSAFE_componentWillUpdate(r,g,u)),typeof a.componentDidUpdate=="function"&&(t.flags|=4),typeof a.getSnapshotBeforeUpdate=="function"&&(t.flags|=1024)):(typeof a.componentDidUpdate!="function"||s===e.memoizedProps&&d===e.memoizedState||(t.flags|=4),typeof a.getSnapshotBeforeUpdate!="function"||s===e.memoizedProps&&d===e.memoizedState||(t.flags|=1024),t.memoizedProps=r,t.memoizedState=g),a.props=r,a.state=g,a.context=u,r=l):(typeof a.componentDidUpdate!="function"||s===e.memoizedProps&&d===e.memoizedState||(t.flags|=4),typeof a.getSnapshotBeforeUpdate!="function"||s===e.memoizedProps&&d===e.memoizedState||(t.flags|=1024),r=!1)}return zh(e,t,n,r,o,i)}function zh(e,t,n,r,i,o){NS(e,t);var a=(t.flags&128)!==0;if(!r&&!a)return i&&Tg(t,n,!1),Wt(e,t,o);r=t.stateNode,vb.current=t;var s=a&&typeof n.getDerivedStateFromError!="function"?null:r.render();return t.flags|=1,e!==null&&a?(t.child=Or(t,e.child,null,o),t.child=Or(t,null,s,o)):je(e,t,s,o),t.memoizedState=r.state,i&&Tg(t,n,!0),t.child}function IS(e){var t=e.stateNode;t.pendingContext?bg(e,t.pendingContext,t.pendingContext!==t.context):t.context&&bg(e,t.context,!1),$p(e,t.containerInfo)}function Ug(e,t,n,r,i){return Lr(),Mp(i),t.flags|=256,je(e,t,n,r),t.child}var Fh={dehydrated:null,treeContext:null,retryLane:0};function Dh(e){return{baseLanes:e,cachePool:null,transitions:null}}function PS(e,t,n){var r=t.pendingProps,i=le.current,o=!1,a=(t.flags&128)!==0,s;if((s=a)||(s=e!==null&&e.memoizedState===null?!1:(i&2)!==0),s?(o=!0,t.flags&=-129):(e===null||e.memoizedState!==null)&&(i|=1),re(le,i&1),e===null)return jh(t),e=t.memoizedState,e!==null&&(e=e.dehydrated,e!==null)?(t.mode&1?e.data==="$!"?t.lanes=8:t.lanes=1073741824:t.lanes=1,null):(a=r.children,e=r.fallback,o?(r=t.mode,o=t.child,a={mode:"hidden",children:a},!(r&1)&&o!==null?(o.childLanes=0,o.pendingProps=a):o=ns(a,r,0,null),e=Hn(e,r,n,null),o.return=t,e.return=t,o.sibling=e,t.child=o,t.child.memoizedState=Dh(n),t.memoizedState=Fh,e):Yp(t,a));if(i=e.memoizedState,i!==null&&(s=i.dehydrated,s!==null))return gb(e,t,a,r,s,i,n);if(o){o=r.fallback,a=t.mode,i=e.child,s=i.sibling;var u={mode:"hidden",children:r.children};return!(a&1)&&t.child!==i?(r=t.child,r.childLanes=0,r.pendingProps=u,t.deletions=null):(r=wn(i,u),r.subtreeFlags=i.subtreeFlags&14680064),s!==null?o=wn(s,o):(o=Hn(o,a,n,null),o.flags|=2),o.return=t,r.return=t,r.sibling=o,t.child=r,r=o,o=t.child,a=e.child.memoizedState,a=a===null?Dh(n):{baseLanes:a.baseLanes|n,cachePool:null,transitions:a.transitions},o.memoizedState=a,o.childLanes=e.childLanes&~n,t.memoizedState=Fh,r}return o=e.child,e=o.sibling,r=wn(o,{mode:"visible",children:r.children}),!(t.mode&1)&&(r.lanes=n),r.return=t,r.sibling=null,e!==null&&(n=t.deletions,n===null?(t.deletions=[e],t.flags|=16):n.push(e)),t.child=r,t.memoizedState=null,r}function Yp(e,t){return t=ns({mode:"visible",children:t},e.mode,0,null),t.return=e,e.child=t}function Lo(e,t,n,r){return r!==null&&Mp(r),Or(t,e.child,null,n),e=Yp(t,t.pendingProps.children),e.flags|=2,t.memoizedState=null,e}function gb(e,t,n,r,i,o,a){if(n)return t.flags&256?(t.flags&=-257,r=Js(Error(q(422))),Lo(e,t,a,r)):t.memoizedState!==null?(t.child=e.child,t.flags|=128,null):(o=r.fallback,i=t.mode,r=ns({mode:"visible",children:r.children},i,0,null),o=Hn(o,i,a,null),o.flags|=2,r.return=t,o.return=t,r.sibling=o,t.child=r,t.mode&1&&Or(t,e.child,null,a),t.child.memoizedState=Dh(a),t.memoizedState=Fh,o);if(!(t.mode&1))return Lo(e,t,a,null);if(i.data==="$!"){if(r=i.nextSibling&&i.nextSibling.dataset,r)var s=r.dgst;return r=s,o=Error(q(419)),r=Js(o,r,void 0),Lo(e,t,a,r)}if(s=(a&e.childLanes)!==0,$e||s){if(r=Se,r!==null){switch(a&-a){case 4:i=2;break;case 16:i=8;break;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:i=32;break;case 536870912:i=268435456;break;default:i=0}i=i&(r.suspendedLanes|a)?0:i,i!==0&&i!==o.retryLane&&(o.retryLane=i,Gt(e,i),yt(r,e,i,-1))}return tv(),r=Js(Error(q(421))),Lo(e,t,a,r)}return i.data==="$?"?(t.flags|=128,t.child=e.child,t=Nb.bind(null,e),i._reactRetry=t,null):(e=o.treeContext,Qe=mn(i.nextSibling),Xe=t,se=!0,vt=null,e!==null&&(nt[rt++]=zt,nt[rt++]=Ft,nt[rt++]=Kn,zt=e.id,Ft=e.overflow,Kn=t),t=Yp(t,r.children),t.flags|=4096,t)}function Hg(e,t,n){e.lanes|=t;var r=e.alternate;r!==null&&(r.lanes|=t),qh(e.return,t,n)}function eu(e,t,n,r,i){var o=e.memoizedState;o===null?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:r,tail:n,tailMode:i}:(o.isBackwards=t,o.rendering=null,o.renderingStartTime=0,o.last=r,o.tail=n,o.tailMode=i)}function jS(e,t,n){var r=t.pendingProps,i=r.revealOrder,o=r.tail;if(je(e,t,r.children,n),r=le.current,r&2)r=r&1|2,t.flags|=128;else{if(e!==null&&e.flags&128)e:for(e=t.child;e!==null;){if(e.tag===13)e.memoizedState!==null&&Hg(e,n,t);else if(e.tag===19)Hg(e,n,t);else if(e.child!==null){e.child.return=e,e=e.child;continue}if(e===t)break e;for(;e.sibling===null;){if(e.return===null||e.return===t)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}r&=1}if(re(le,r),!(t.mode&1))t.memoizedState=null;else switch(i){case"forwards":for(n=t.child,i=null;n!==null;)e=n.alternate,e!==null&&ka(e)===null&&(i=n),n=n.sibling;n=i,n===null?(i=t.child,t.child=null):(i=n.sibling,n.sibling=null),eu(t,!1,i,n,o);break;case"backwards":for(n=null,i=t.child,t.child=null;i!==null;){if(e=i.alternate,e!==null&&ka(e)===null){t.child=i;break}e=i.sibling,i.sibling=n,n=i,i=e}eu(t,!0,n,null,o);break;case"together":eu(t,!1,null,null,void 0);break;default:t.memoizedState=null}return t.child}function ta(e,t){!(t.mode&1)&&e!==null&&(e.alternate=null,t.alternate=null,t.flags|=2)}function Wt(e,t,n){if(e!==null&&(t.dependencies=e.dependencies),Qn|=t.lanes,!(n&t.childLanes))return null;if(e!==null&&t.child!==e.child)throw Error(q(153));if(t.child!==null){for(e=t.child,n=wn(e,e.pendingProps),t.child=n,n.return=t;e.sibling!==null;)e=e.sibling,n=n.sibling=wn(e,e.pendingProps),n.return=t;n.sibling=null}return t.child}function mb(e,t,n){switch(t.tag){case 3:IS(t),Lr();break;case 5:iS(t);break;case 1:He(t.type)&&_a(t);break;case 4:$p(t,t.stateNode.containerInfo);break;case 10:var r=t.type._context,i=t.memoizedProps.value;re(Sa,r._currentValue),r._currentValue=i;break;case 13:if(r=t.memoizedState,r!==null)return r.dehydrated!==null?(re(le,le.current&1),t.flags|=128,null):n&t.child.childLanes?PS(e,t,n):(re(le,le.current&1),e=Wt(e,t,n),e!==null?e.sibling:null);re(le,le.current&1);break;case 19:if(r=(n&t.childLanes)!==0,e.flags&128){if(r)return jS(e,t,n);t.flags|=128}if(i=t.memoizedState,i!==null&&(i.rendering=null,i.tail=null,i.lastEffect=null),re(le,le.current),r)break;return null;case 22:case 23:return t.lanes=0,RS(e,t,n)}return Wt(e,t,n)}var qS,$h,AS,MS;qS=function(e,t){for(var n=t.child;n!==null;){if(n.tag===5||n.tag===6)e.appendChild(n.stateNode);else if(n.tag!==4&&n.child!==null){n.child.return=n,n=n.child;continue}if(n===t)break;for(;n.sibling===null;){if(n.return===null||n.return===t)return;n=n.return}n.sibling.return=n.return,n=n.sibling}};$h=function(){};AS=function(e,t,n,r){var i=e.memoizedProps;if(i!==r){e=t.stateNode,Dn(Rt.current);var o=null;switch(n){case"input":i=lh(e,i),r=lh(e,r),o=[];break;case"select":i=fe({},i,{value:void 0}),r=fe({},r,{value:void 0}),o=[];break;case"textarea":i=dh(e,i),r=dh(e,r),o=[];break;default:typeof i.onClick!="function"&&typeof r.onClick=="function"&&(e.onclick=ma)}ph(n,r);var a;n=null;for(l in i)if(!r.hasOwnProperty(l)&&i.hasOwnProperty(l)&&i[l]!=null)if(l==="style"){var s=i[l];for(a in s)s.hasOwnProperty(a)&&(n||(n={}),n[a]="")}else l!=="dangerouslySetInnerHTML"&&l!=="children"&&l!=="suppressContentEditableWarning"&&l!=="suppressHydrationWarning"&&l!=="autoFocus"&&(qi.hasOwnProperty(l)?o||(o=[]):(o=o||[]).push(l,null));for(l in r){var u=r[l];if(s=i!=null?i[l]:void 0,r.hasOwnProperty(l)&&u!==s&&(u!=null||s!=null))if(l==="style")if(s){for(a in s)!s.hasOwnProperty(a)||u&&u.hasOwnProperty(a)||(n||(n={}),n[a]="");for(a in u)u.hasOwnProperty(a)&&s[a]!==u[a]&&(n||(n={}),n[a]=u[a])}else n||(o||(o=[]),o.push(l,n)),n=u;else l==="dangerouslySetInnerHTML"?(u=u?u.__html:void 0,s=s?s.__html:void 0,u!=null&&s!==u&&(o=o||[]).push(l,u)):l==="children"?typeof u!="string"&&typeof u!="number"||(o=o||[]).push(l,""+u):l!=="suppressContentEditableWarning"&&l!=="suppressHydrationWarning"&&(qi.hasOwnProperty(l)?(u!=null&&l==="onScroll"&&oe("scroll",e),o||s===u||(o=[])):(o=o||[]).push(l,u))}n&&(o=o||[]).push("style",n);var l=o;(t.updateQueue=l)&&(t.flags|=4)}};MS=function(e,t,n,r){n!==r&&(t.flags|=4)};function ui(e,t){if(!se)switch(e.tailMode){case"hidden":t=e.tail;for(var n=null;t!==null;)t.alternate!==null&&(n=t),t=t.sibling;n===null?e.tail=null:n.sibling=null;break;case"collapsed":n=e.tail;for(var r=null;n!==null;)n.alternate!==null&&(r=n),n=n.sibling;r===null?t||e.tail===null?e.tail=null:e.tail.sibling=null:r.sibling=null}}function Ne(e){var t=e.alternate!==null&&e.alternate.child===e.child,n=0,r=0;if(t)for(var i=e.child;i!==null;)n|=i.lanes|i.childLanes,r|=i.subtreeFlags&14680064,r|=i.flags&14680064,i.return=e,i=i.sibling;else for(i=e.child;i!==null;)n|=i.lanes|i.childLanes,r|=i.subtreeFlags,r|=i.flags,i.return=e,i=i.sibling;return e.subtreeFlags|=r,e.childLanes=n,t}function yb(e,t,n){var r=t.pendingProps;switch(Ap(t),t.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return Ne(t),null;case 1:return He(t.type)&&ya(),Ne(t),null;case 3:return r=t.stateNode,zr(),ae(Ue),ae(Pe),Up(),r.pendingContext&&(r.context=r.pendingContext,r.pendingContext=null),(e===null||e.child===null)&&(Ao(t)?t.flags|=4:e===null||e.memoizedState.isDehydrated&&!(t.flags&256)||(t.flags|=1024,vt!==null&&(Yh(vt),vt=null))),$h(e,t),Ne(t),null;case 5:Bp(t);var i=Dn(Vi.current);if(n=t.type,e!==null&&t.stateNode!=null)AS(e,t,n,r,i),e.ref!==t.ref&&(t.flags|=512,t.flags|=2097152);else{if(!r){if(t.stateNode===null)throw Error(q(166));return Ne(t),null}if(e=Dn(Rt.current),Ao(t)){r=t.stateNode,n=t.type;var o=t.memoizedProps;switch(r[kt]=t,r[Ui]=o,e=(t.mode&1)!==0,n){case"dialog":oe("cancel",r),oe("close",r);break;case"iframe":case"object":case"embed":oe("load",r);break;case"video":case"audio":for(i=0;i<vi.length;i++)oe(vi[i],r);break;case"source":oe("error",r);break;case"img":case"image":case"link":oe("error",r),oe("load",r);break;case"details":oe("toggle",r);break;case"input":Jv(r,o),oe("invalid",r);break;case"select":r._wrapperState={wasMultiple:!!o.multiple},oe("invalid",r);break;case"textarea":tg(r,o),oe("invalid",r)}ph(n,o),i=null;for(var a in o)if(o.hasOwnProperty(a)){var s=o[a];a==="children"?typeof s=="string"?r.textContent!==s&&(o.suppressHydrationWarning!==!0&&qo(r.textContent,s,e),i=["children",s]):typeof s=="number"&&r.textContent!==""+s&&(o.suppressHydrationWarning!==!0&&qo(r.textContent,s,e),i=["children",""+s]):qi.hasOwnProperty(a)&&s!=null&&a==="onScroll"&&oe("scroll",r)}switch(n){case"input":ko(r),eg(r,o,!0);break;case"textarea":ko(r),ng(r);break;case"select":case"option":break;default:typeof o.onClick=="function"&&(r.onclick=ma)}r=i,t.updateQueue=r,r!==null&&(t.flags|=4)}else{a=i.nodeType===9?i:i.ownerDocument,e==="http://www.w3.org/1999/xhtml"&&(e=lw(n)),e==="http://www.w3.org/1999/xhtml"?n==="script"?(e=a.createElement("div"),e.innerHTML="<script><\/script>",e=e.removeChild(e.firstChild)):typeof r.is=="string"?e=a.createElement(n,{is:r.is}):(e=a.createElement(n),n==="select"&&(a=e,r.multiple?a.multiple=!0:r.size&&(a.size=r.size))):e=a.createElementNS(e,n),e[kt]=t,e[Ui]=r,qS(e,t,!1,!1),t.stateNode=e;e:{switch(a=vh(n,r),n){case"dialog":oe("cancel",e),oe("close",e),i=r;break;case"iframe":case"object":case"embed":oe("load",e),i=r;break;case"video":case"audio":for(i=0;i<vi.length;i++)oe(vi[i],e);i=r;break;case"source":oe("error",e),i=r;break;case"img":case"image":case"link":oe("error",e),oe("load",e),i=r;break;case"details":oe("toggle",e),i=r;break;case"input":Jv(e,r),i=lh(e,r),oe("invalid",e);break;case"option":i=r;break;case"select":e._wrapperState={wasMultiple:!!r.multiple},i=fe({},r,{value:void 0}),oe("invalid",e);break;case"textarea":tg(e,r),i=dh(e,r),oe("invalid",e);break;default:i=r}ph(n,i),s=i;for(o in s)if(s.hasOwnProperty(o)){var u=s[o];o==="style"?dw(e,u):o==="dangerouslySetInnerHTML"?(u=u?u.__html:void 0,u!=null&&cw(e,u)):o==="children"?typeof u=="string"?(n!=="textarea"||u!=="")&&Ai(e,u):typeof u=="number"&&Ai(e,""+u):o!=="suppressContentEditableWarning"&&o!=="suppressHydrationWarning"&&o!=="autoFocus"&&(qi.hasOwnProperty(o)?u!=null&&o==="onScroll"&&oe("scroll",e):u!=null&&_p(e,o,u,a))}switch(n){case"input":ko(e),eg(e,r,!1);break;case"textarea":ko(e),ng(e);break;case"option":r.value!=null&&e.setAttribute("value",""+Cn(r.value));break;case"select":e.multiple=!!r.multiple,o=r.value,o!=null?br(e,!!r.multiple,o,!1):r.defaultValue!=null&&br(e,!!r.multiple,r.defaultValue,!0);break;default:typeof i.onClick=="function"&&(e.onclick=ma)}switch(n){case"button":case"input":case"select":case"textarea":r=!!r.autoFocus;break e;case"img":r=!0;break e;default:r=!1}}r&&(t.flags|=4)}t.ref!==null&&(t.flags|=512,t.flags|=2097152)}return Ne(t),null;case 6:if(e&&t.stateNode!=null)MS(e,t,e.memoizedProps,r);else{if(typeof r!="string"&&t.stateNode===null)throw Error(q(166));if(n=Dn(Vi.current),Dn(Rt.current),Ao(t)){if(r=t.stateNode,n=t.memoizedProps,r[kt]=t,(o=r.nodeValue!==n)&&(e=Xe,e!==null))switch(e.tag){case 3:qo(r.nodeValue,n,(e.mode&1)!==0);break;case 5:e.memoizedProps.suppressHydrationWarning!==!0&&qo(r.nodeValue,n,(e.mode&1)!==0)}o&&(t.flags|=4)}else r=(n.nodeType===9?n:n.ownerDocument).createTextNode(r),r[kt]=t,t.stateNode=r}return Ne(t),null;case 13:if(ae(le),r=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(se&&Qe!==null&&t.mode&1&&!(t.flags&128))Jw(),Lr(),t.flags|=98560,o=!1;else if(o=Ao(t),r!==null&&r.dehydrated!==null){if(e===null){if(!o)throw Error(q(318));if(o=t.memoizedState,o=o!==null?o.dehydrated:null,!o)throw Error(q(317));o[kt]=t}else Lr(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;Ne(t),o=!1}else vt!==null&&(Yh(vt),vt=null),o=!0;if(!o)return t.flags&65536?t:null}return t.flags&128?(t.lanes=n,t):(r=r!==null,r!==(e!==null&&e.memoizedState!==null)&&r&&(t.child.flags|=8192,t.mode&1&&(e===null||le.current&1?_e===0&&(_e=3):tv())),t.updateQueue!==null&&(t.flags|=4),Ne(t),null);case 4:return zr(),$h(e,t),e===null&&$i(t.stateNode.containerInfo),Ne(t),null;case 10:return zp(t.type._context),Ne(t),null;case 17:return He(t.type)&&ya(),Ne(t),null;case 19:if(ae(le),o=t.memoizedState,o===null)return Ne(t),null;if(r=(t.flags&128)!==0,a=o.rendering,a===null)if(r)ui(o,!1);else{if(_e!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(a=ka(e),a!==null){for(t.flags|=128,ui(o,!1),r=a.updateQueue,r!==null&&(t.updateQueue=r,t.flags|=4),t.subtreeFlags=0,r=n,n=t.child;n!==null;)o=n,e=r,o.flags&=14680066,a=o.alternate,a===null?(o.childLanes=0,o.lanes=e,o.child=null,o.subtreeFlags=0,o.memoizedProps=null,o.memoizedState=null,o.updateQueue=null,o.dependencies=null,o.stateNode=null):(o.childLanes=a.childLanes,o.lanes=a.lanes,o.child=a.child,o.subtreeFlags=0,o.deletions=null,o.memoizedProps=a.memoizedProps,o.memoizedState=a.memoizedState,o.updateQueue=a.updateQueue,o.type=a.type,e=a.dependencies,o.dependencies=e===null?null:{lanes:e.lanes,firstContext:e.firstContext}),n=n.sibling;return re(le,le.current&1|2),t.child}e=e.sibling}o.tail!==null&&he()>Dr&&(t.flags|=128,r=!0,ui(o,!1),t.lanes=4194304)}else{if(!r)if(e=ka(a),e!==null){if(t.flags|=128,r=!0,n=e.updateQueue,n!==null&&(t.updateQueue=n,t.flags|=4),ui(o,!0),o.tail===null&&o.tailMode==="hidden"&&!a.alternate&&!se)return Ne(t),null}else 2*he()-o.renderingStartTime>Dr&&n!==1073741824&&(t.flags|=128,r=!0,ui(o,!1),t.lanes=4194304);o.isBackwards?(a.sibling=t.child,t.child=a):(n=o.last,n!==null?n.sibling=a:t.child=a,o.last=a)}return o.tail!==null?(t=o.tail,o.rendering=t,o.tail=t.sibling,o.renderingStartTime=he(),t.sibling=null,n=le.current,re(le,r?n&1|2:n&1),t):(Ne(t),null);case 22:case 23:return ev(),r=t.memoizedState!==null,e!==null&&e.memoizedState!==null!==r&&(t.flags|=8192),r&&t.mode&1?Ke&1073741824&&(Ne(t),t.subtreeFlags&6&&(t.flags|=8192)):Ne(t),null;case 24:return null;case 25:return null}throw Error(q(156,t.tag))}function _b(e,t){switch(Ap(t),t.tag){case 1:return He(t.type)&&ya(),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return zr(),ae(Ue),ae(Pe),Up(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 5:return Bp(t),null;case 13:if(ae(le),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(q(340));Lr()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return ae(le),null;case 4:return zr(),null;case 10:return zp(t.type._context),null;case 22:case 23:return ev(),null;case 24:return null;default:return null}}var Oo=!1,Ie=!1,xb=typeof WeakSet=="function"?WeakSet:Set,z=null;function Cr(e,t){var n=e.ref;if(n!==null)if(typeof n=="function")try{n(null)}catch(r){de(e,t,r)}else n.current=null}function Bh(e,t,n){try{n()}catch(r){de(e,t,r)}}var Vg=!1;function wb(e,t){if(kh=pa,e=Dw(),jp(e)){if("selectionStart"in e)var n={start:e.selectionStart,end:e.selectionEnd};else e:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var i=r.anchorOffset,o=r.focusNode;r=r.focusOffset;try{n.nodeType,o.nodeType}catch{n=null;break e}var a=0,s=-1,u=-1,l=0,c=0,f=e,d=null;t:for(;;){for(var h;f!==n||i!==0&&f.nodeType!==3||(s=a+i),f!==o||r!==0&&f.nodeType!==3||(u=a+r),f.nodeType===3&&(a+=f.nodeValue.length),(h=f.firstChild)!==null;)d=f,f=h;for(;;){if(f===e)break t;if(d===n&&++l===i&&(s=a),d===o&&++c===r&&(u=a),(h=f.nextSibling)!==null)break;f=d,d=f.parentNode}f=h}n=s===-1||u===-1?null:{start:s,end:u}}else n=null}n=n||{start:0,end:0}}else n=null;for(bh={focusedElem:e,selectionRange:n},pa=!1,z=t;z!==null;)if(t=z,e=t.child,(t.subtreeFlags&1028)!==0&&e!==null)e.return=t,z=e;else for(;z!==null;){t=z;try{var g=t.alternate;if(t.flags&1024)switch(t.tag){case 0:case 11:case 15:break;case 1:if(g!==null){var v=g.memoizedProps,y=g.memoizedState,p=t.stateNode,m=p.getSnapshotBeforeUpdate(t.elementType===t.type?v:ht(t.type,v),y);p.__reactInternalSnapshotBeforeUpdate=m}break;case 3:var _=t.stateNode.containerInfo;_.nodeType===1?_.textContent="":_.nodeType===9&&_.documentElement&&_.removeChild(_.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(q(163))}}catch(x){de(t,t.return,x)}if(e=t.sibling,e!==null){e.return=t.return,z=e;break}z=t.return}return g=Vg,Vg=!1,g}function Ii(e,t,n){var r=t.updateQueue;if(r=r!==null?r.lastEffect:null,r!==null){var i=r=r.next;do{if((i.tag&e)===e){var o=i.destroy;i.destroy=void 0,o!==void 0&&Bh(t,n,o)}i=i.next}while(i!==r)}}function es(e,t){if(t=t.updateQueue,t=t!==null?t.lastEffect:null,t!==null){var n=t=t.next;do{if((n.tag&e)===e){var r=n.create;n.destroy=r()}n=n.next}while(n!==t)}}function Uh(e){var t=e.ref;if(t!==null){var n=e.stateNode;switch(e.tag){case 5:e=n;break;default:e=n}typeof t=="function"?t(e):t.current=e}}function LS(e){var t=e.alternate;t!==null&&(e.alternate=null,LS(t)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(t=e.stateNode,t!==null&&(delete t[kt],delete t[Ui],delete t[Nh],delete t[rb],delete t[ib])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function OS(e){return e.tag===5||e.tag===3||e.tag===4}function Gg(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||OS(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Hh(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.nodeType===8?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(n.nodeType===8?(t=n.parentNode,t.insertBefore(e,n)):(t=n,t.appendChild(e)),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=ma));else if(r!==4&&(e=e.child,e!==null))for(Hh(e,t,n),e=e.sibling;e!==null;)Hh(e,t,n),e=e.sibling}function Vh(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(e=e.child,e!==null))for(Vh(e,t,n),e=e.sibling;e!==null;)Vh(e,t,n),e=e.sibling}var ke=null,pt=!1;function tn(e,t,n){for(n=n.child;n!==null;)zS(e,t,n),n=n.sibling}function zS(e,t,n){if(Tt&&typeof Tt.onCommitFiberUnmount=="function")try{Tt.onCommitFiberUnmount(Ga,n)}catch{}switch(n.tag){case 5:Ie||Cr(n,t);case 6:var r=ke,i=pt;ke=null,tn(e,t,n),ke=r,pt=i,ke!==null&&(pt?(e=ke,n=n.stateNode,e.nodeType===8?e.parentNode.removeChild(n):e.removeChild(n)):ke.removeChild(n.stateNode));break;case 18:ke!==null&&(pt?(e=ke,n=n.stateNode,e.nodeType===8?Ws(e.parentNode,n):e.nodeType===1&&Ws(e,n),zi(e)):Ws(ke,n.stateNode));break;case 4:r=ke,i=pt,ke=n.stateNode.containerInfo,pt=!0,tn(e,t,n),ke=r,pt=i;break;case 0:case 11:case 14:case 15:if(!Ie&&(r=n.updateQueue,r!==null&&(r=r.lastEffect,r!==null))){i=r=r.next;do{var o=i,a=o.destroy;o=o.tag,a!==void 0&&(o&2||o&4)&&Bh(n,t,a),i=i.next}while(i!==r)}tn(e,t,n);break;case 1:if(!Ie&&(Cr(n,t),r=n.stateNode,typeof r.componentWillUnmount=="function"))try{r.props=n.memoizedProps,r.state=n.memoizedState,r.componentWillUnmount()}catch(s){de(n,t,s)}tn(e,t,n);break;case 21:tn(e,t,n);break;case 22:n.mode&1?(Ie=(r=Ie)||n.memoizedState!==null,tn(e,t,n),Ie=r):tn(e,t,n);break;default:tn(e,t,n)}}function Wg(e){var t=e.updateQueue;if(t!==null){e.updateQueue=null;var n=e.stateNode;n===null&&(n=e.stateNode=new xb),t.forEach(function(r){var i=Ib.bind(null,e,r);n.has(r)||(n.add(r),r.then(i,i))})}}function dt(e,t){var n=t.deletions;if(n!==null)for(var r=0;r<n.length;r++){var i=n[r];try{var o=e,a=t,s=a;e:for(;s!==null;){switch(s.tag){case 5:ke=s.stateNode,pt=!1;break e;case 3:ke=s.stateNode.containerInfo,pt=!0;break e;case 4:ke=s.stateNode.containerInfo,pt=!0;break e}s=s.return}if(ke===null)throw Error(q(160));zS(o,a,i),ke=null,pt=!1;var u=i.alternate;u!==null&&(u.return=null),i.return=null}catch(l){de(i,t,l)}}if(t.subtreeFlags&12854)for(t=t.child;t!==null;)FS(t,e),t=t.sibling}function FS(e,t){var n=e.alternate,r=e.flags;switch(e.tag){case 0:case 11:case 14:case 15:if(dt(t,e),Et(e),r&4){try{Ii(3,e,e.return),es(3,e)}catch(v){de(e,e.return,v)}try{Ii(5,e,e.return)}catch(v){de(e,e.return,v)}}break;case 1:dt(t,e),Et(e),r&512&&n!==null&&Cr(n,n.return);break;case 5:if(dt(t,e),Et(e),r&512&&n!==null&&Cr(n,n.return),e.flags&32){var i=e.stateNode;try{Ai(i,"")}catch(v){de(e,e.return,v)}}if(r&4&&(i=e.stateNode,i!=null)){var o=e.memoizedProps,a=n!==null?n.memoizedProps:o,s=e.type,u=e.updateQueue;if(e.updateQueue=null,u!==null)try{s==="input"&&o.type==="radio"&&o.name!=null&&sw(i,o),vh(s,a);var l=vh(s,o);for(a=0;a<u.length;a+=2){var c=u[a],f=u[a+1];c==="style"?dw(i,f):c==="dangerouslySetInnerHTML"?cw(i,f):c==="children"?Ai(i,f):_p(i,c,f,l)}switch(s){case"input":ch(i,o);break;case"textarea":uw(i,o);break;case"select":var d=i._wrapperState.wasMultiple;i._wrapperState.wasMultiple=!!o.multiple;var h=o.value;h!=null?br(i,!!o.multiple,h,!1):d!==!!o.multiple&&(o.defaultValue!=null?br(i,!!o.multiple,o.defaultValue,!0):br(i,!!o.multiple,o.multiple?[]:"",!1))}i[Ui]=o}catch(v){de(e,e.return,v)}}break;case 6:if(dt(t,e),Et(e),r&4){if(e.stateNode===null)throw Error(q(162));i=e.stateNode,o=e.memoizedProps;try{i.nodeValue=o}catch(v){de(e,e.return,v)}}break;case 3:if(dt(t,e),Et(e),r&4&&n!==null&&n.memoizedState.isDehydrated)try{zi(t.containerInfo)}catch(v){de(e,e.return,v)}break;case 4:dt(t,e),Et(e);break;case 13:dt(t,e),Et(e),i=e.child,i.flags&8192&&(o=i.memoizedState!==null,i.stateNode.isHidden=o,!o||i.alternate!==null&&i.alternate.memoizedState!==null||(Zp=he())),r&4&&Wg(e);break;case 22:if(c=n!==null&&n.memoizedState!==null,e.mode&1?(Ie=(l=Ie)||c,dt(t,e),Ie=l):dt(t,e),Et(e),r&8192){if(l=e.memoizedState!==null,(e.stateNode.isHidden=l)&&!c&&e.mode&1)for(z=e,c=e.child;c!==null;){for(f=z=c;z!==null;){switch(d=z,h=d.child,d.tag){case 0:case 11:case 14:case 15:Ii(4,d,d.return);break;case 1:Cr(d,d.return);var g=d.stateNode;if(typeof g.componentWillUnmount=="function"){r=d,n=d.return;try{t=r,g.props=t.memoizedProps,g.state=t.memoizedState,g.componentWillUnmount()}catch(v){de(r,n,v)}}break;case 5:Cr(d,d.return);break;case 22:if(d.memoizedState!==null){Yg(f);continue}}h!==null?(h.return=d,z=h):Yg(f)}c=c.sibling}e:for(c=null,f=e;;){if(f.tag===5){if(c===null){c=f;try{i=f.stateNode,l?(o=i.style,typeof o.setProperty=="function"?o.setProperty("display","none","important"):o.display="none"):(s=f.stateNode,u=f.memoizedProps.style,a=u!=null&&u.hasOwnProperty("display")?u.display:null,s.style.display=fw("display",a))}catch(v){de(e,e.return,v)}}}else if(f.tag===6){if(c===null)try{f.stateNode.nodeValue=l?"":f.memoizedProps}catch(v){de(e,e.return,v)}}else if((f.tag!==22&&f.tag!==23||f.memoizedState===null||f===e)&&f.child!==null){f.child.return=f,f=f.child;continue}if(f===e)break e;for(;f.sibling===null;){if(f.return===null||f.return===e)break e;c===f&&(c=null),f=f.return}c===f&&(c=null),f.sibling.return=f.return,f=f.sibling}}break;case 19:dt(t,e),Et(e),r&4&&Wg(e);break;case 21:break;default:dt(t,e),Et(e)}}function Et(e){var t=e.flags;if(t&2){try{e:{for(var n=e.return;n!==null;){if(OS(n)){var r=n;break e}n=n.return}throw Error(q(160))}switch(r.tag){case 5:var i=r.stateNode;r.flags&32&&(Ai(i,""),r.flags&=-33);var o=Gg(e);Vh(e,o,i);break;case 3:case 4:var a=r.stateNode.containerInfo,s=Gg(e);Hh(e,s,a);break;default:throw Error(q(161))}}catch(u){de(e,e.return,u)}e.flags&=-3}t&4096&&(e.flags&=-4097)}function Sb(e,t,n){z=e,DS(e)}function DS(e,t,n){for(var r=(e.mode&1)!==0;z!==null;){var i=z,o=i.child;if(i.tag===22&&r){var a=i.memoizedState!==null||Oo;if(!a){var s=i.alternate,u=s!==null&&s.memoizedState!==null||Ie;s=Oo;var l=Ie;if(Oo=a,(Ie=u)&&!l)for(z=i;z!==null;)a=z,u=a.child,a.tag===22&&a.memoizedState!==null?Qg(i):u!==null?(u.return=a,z=u):Qg(i);for(;o!==null;)z=o,DS(o),o=o.sibling;z=i,Oo=s,Ie=l}Kg(e)}else i.subtreeFlags&8772&&o!==null?(o.return=i,z=o):Kg(e)}}function Kg(e){for(;z!==null;){var t=z;if(t.flags&8772){var n=t.alternate;try{if(t.flags&8772)switch(t.tag){case 0:case 11:case 15:Ie||es(5,t);break;case 1:var r=t.stateNode;if(t.flags&4&&!Ie)if(n===null)r.componentDidMount();else{var i=t.elementType===t.type?n.memoizedProps:ht(t.type,n.memoizedProps);r.componentDidUpdate(i,n.memoizedState,r.__reactInternalSnapshotBeforeUpdate)}var o=t.updateQueue;o!==null&&jg(t,o,r);break;case 3:var a=t.updateQueue;if(a!==null){if(n=null,t.child!==null)switch(t.child.tag){case 5:n=t.child.stateNode;break;case 1:n=t.child.stateNode}jg(t,a,n)}break;case 5:var s=t.stateNode;if(n===null&&t.flags&4){n=s;var u=t.memoizedProps;switch(t.type){case"button":case"input":case"select":case"textarea":u.autoFocus&&n.focus();break;case"img":u.src&&(n.src=u.src)}}break;case 6:break;case 4:break;case 12:break;case 13:if(t.memoizedState===null){var l=t.alternate;if(l!==null){var c=l.memoizedState;if(c!==null){var f=c.dehydrated;f!==null&&zi(f)}}}break;case 19:case 17:case 21:case 22:case 23:case 25:break;default:throw Error(q(163))}Ie||t.flags&512&&Uh(t)}catch(d){de(t,t.return,d)}}if(t===e){z=null;break}if(n=t.sibling,n!==null){n.return=t.return,z=n;break}z=t.return}}function Yg(e){for(;z!==null;){var t=z;if(t===e){z=null;break}var n=t.sibling;if(n!==null){n.return=t.return,z=n;break}z=t.return}}function Qg(e){for(;z!==null;){var t=z;try{switch(t.tag){case 0:case 11:case 15:var n=t.return;try{es(4,t)}catch(u){de(t,n,u)}break;case 1:var r=t.stateNode;if(typeof r.componentDidMount=="function"){var i=t.return;try{r.componentDidMount()}catch(u){de(t,i,u)}}var o=t.return;try{Uh(t)}catch(u){de(t,o,u)}break;case 5:var a=t.return;try{Uh(t)}catch(u){de(t,a,u)}}}catch(u){de(t,t.return,u)}if(t===e){z=null;break}var s=t.sibling;if(s!==null){s.return=t.return,z=s;break}z=t.return}}var Eb=Math.ceil,Ra=Qt.ReactCurrentDispatcher,Qp=Qt.ReactCurrentOwner,ot=Qt.ReactCurrentBatchConfig,W=0,Se=null,ve=null,be=0,Ke=0,kr=Nn(0),_e=0,Yi=null,Qn=0,ts=0,Xp=0,Pi=null,Fe=null,Zp=0,Dr=1/0,Mt=null,Na=!1,Gh=null,_n=null,zo=!1,fn=null,Ia=0,ji=0,Wh=null,na=-1,ra=0;function Ae(){return W&6?he():na!==-1?na:na=he()}function xn(e){return e.mode&1?W&2&&be!==0?be&-be:ab.transition!==null?(ra===0&&(ra=Cw()),ra):(e=X,e!==0||(e=window.event,e=e===void 0?16:Pw(e.type)),e):1}function yt(e,t,n,r){if(50<ji)throw ji=0,Wh=null,Error(q(185));io(e,n,r),(!(W&2)||e!==Se)&&(e===Se&&(!(W&2)&&(ts|=n),_e===4&&un(e,be)),Ve(e,r),n===1&&W===0&&!(t.mode&1)&&(Dr=he()+500,Xa&&In()))}function Ve(e,t){var n=e.callbackNode;a2(e,t);var r=ha(e,e===Se?be:0);if(r===0)n!==null&&og(n),e.callbackNode=null,e.callbackPriority=0;else if(t=r&-r,e.callbackPriority!==t){if(n!=null&&og(n),t===1)e.tag===0?ob(Xg.bind(null,e)):Qw(Xg.bind(null,e)),tb(function(){!(W&6)&&In()}),n=null;else{switch(kw(r)){case 1:n=Cp;break;case 4:n=Sw;break;case 16:n=da;break;case 536870912:n=Ew;break;default:n=da}n=KS(n,$S.bind(null,e))}e.callbackPriority=t,e.callbackNode=n}}function $S(e,t){if(na=-1,ra=0,W&6)throw Error(q(327));var n=e.callbackNode;if(Pr()&&e.callbackNode!==n)return null;var r=ha(e,e===Se?be:0);if(r===0)return null;if(r&30||r&e.expiredLanes||t)t=Pa(e,r);else{t=r;var i=W;W|=2;var o=US();(Se!==e||be!==t)&&(Mt=null,Dr=he()+500,Un(e,t));do try{bb();break}catch(s){BS(e,s)}while(!0);Op(),Ra.current=o,W=i,ve!==null?t=0:(Se=null,be=0,t=_e)}if(t!==0){if(t===2&&(i=xh(e),i!==0&&(r=i,t=Kh(e,i))),t===1)throw n=Yi,Un(e,0),un(e,r),Ve(e,he()),n;if(t===6)un(e,r);else{if(i=e.current.alternate,!(r&30)&&!Cb(i)&&(t=Pa(e,r),t===2&&(o=xh(e),o!==0&&(r=o,t=Kh(e,o))),t===1))throw n=Yi,Un(e,0),un(e,r),Ve(e,he()),n;switch(e.finishedWork=i,e.finishedLanes=r,t){case 0:case 1:throw Error(q(345));case 2:Ln(e,Fe,Mt);break;case 3:if(un(e,r),(r&130023424)===r&&(t=Zp+500-he(),10<t)){if(ha(e,0)!==0)break;if(i=e.suspendedLanes,(i&r)!==r){Ae(),e.pingedLanes|=e.suspendedLanes&i;break}e.timeoutHandle=Rh(Ln.bind(null,e,Fe,Mt),t);break}Ln(e,Fe,Mt);break;case 4:if(un(e,r),(r&4194240)===r)break;for(t=e.eventTimes,i=-1;0<r;){var a=31-mt(r);o=1<<a,a=t[a],a>i&&(i=a),r&=~o}if(r=i,r=he()-r,r=(120>r?120:480>r?480:1080>r?1080:1920>r?1920:3e3>r?3e3:4320>r?4320:1960*Eb(r/1960))-r,10<r){e.timeoutHandle=Rh(Ln.bind(null,e,Fe,Mt),r);break}Ln(e,Fe,Mt);break;case 5:Ln(e,Fe,Mt);break;default:throw Error(q(329))}}}return Ve(e,he()),e.callbackNode===n?$S.bind(null,e):null}function Kh(e,t){var n=Pi;return e.current.memoizedState.isDehydrated&&(Un(e,t).flags|=256),e=Pa(e,t),e!==2&&(t=Fe,Fe=n,t!==null&&Yh(t)),e}function Yh(e){Fe===null?Fe=e:Fe.push.apply(Fe,e)}function Cb(e){for(var t=e;;){if(t.flags&16384){var n=t.updateQueue;if(n!==null&&(n=n.stores,n!==null))for(var r=0;r<n.length;r++){var i=n[r],o=i.getSnapshot;i=i.value;try{if(!_t(o(),i))return!1}catch{return!1}}}if(n=t.child,t.subtreeFlags&16384&&n!==null)n.return=t,t=n;else{if(t===e)break;for(;t.sibling===null;){if(t.return===null||t.return===e)return!0;t=t.return}t.sibling.return=t.return,t=t.sibling}}return!0}function un(e,t){for(t&=~Xp,t&=~ts,e.suspendedLanes|=t,e.pingedLanes&=~t,e=e.expirationTimes;0<t;){var n=31-mt(t),r=1<<n;e[n]=-1,t&=~r}}function Xg(e){if(W&6)throw Error(q(327));Pr();var t=ha(e,0);if(!(t&1))return Ve(e,he()),null;var n=Pa(e,t);if(e.tag!==0&&n===2){var r=xh(e);r!==0&&(t=r,n=Kh(e,r))}if(n===1)throw n=Yi,Un(e,0),un(e,t),Ve(e,he()),n;if(n===6)throw Error(q(345));return e.finishedWork=e.current.alternate,e.finishedLanes=t,Ln(e,Fe,Mt),Ve(e,he()),null}function Jp(e,t){var n=W;W|=1;try{return e(t)}finally{W=n,W===0&&(Dr=he()+500,Xa&&In())}}function Xn(e){fn!==null&&fn.tag===0&&!(W&6)&&Pr();var t=W;W|=1;var n=ot.transition,r=X;try{if(ot.transition=null,X=1,e)return e()}finally{X=r,ot.transition=n,W=t,!(W&6)&&In()}}function ev(){Ke=kr.current,ae(kr)}function Un(e,t){e.finishedWork=null,e.finishedLanes=0;var n=e.timeoutHandle;if(n!==-1&&(e.timeoutHandle=-1,eb(n)),ve!==null)for(n=ve.return;n!==null;){var r=n;switch(Ap(r),r.tag){case 1:r=r.type.childContextTypes,r!=null&&ya();break;case 3:zr(),ae(Ue),ae(Pe),Up();break;case 5:Bp(r);break;case 4:zr();break;case 13:ae(le);break;case 19:ae(le);break;case 10:zp(r.type._context);break;case 22:case 23:ev()}n=n.return}if(Se=e,ve=e=wn(e.current,null),be=Ke=t,_e=0,Yi=null,Xp=ts=Qn=0,Fe=Pi=null,Fn!==null){for(t=0;t<Fn.length;t++)if(n=Fn[t],r=n.interleaved,r!==null){n.interleaved=null;var i=r.next,o=n.pending;if(o!==null){var a=o.next;o.next=i,r.next=a}n.pending=r}Fn=null}return e}function BS(e,t){do{var n=ve;try{if(Op(),Jo.current=Ta,ba){for(var r=ce.memoizedState;r!==null;){var i=r.queue;i!==null&&(i.pending=null),r=r.next}ba=!1}if(Yn=0,we=ye=ce=null,Ni=!1,Gi=0,Qp.current=null,n===null||n.return===null){_e=1,Yi=t,ve=null;break}e:{var o=e,a=n.return,s=n,u=t;if(t=be,s.flags|=32768,u!==null&&typeof u=="object"&&typeof u.then=="function"){var l=u,c=s,f=c.tag;if(!(c.mode&1)&&(f===0||f===11||f===15)){var d=c.alternate;d?(c.updateQueue=d.updateQueue,c.memoizedState=d.memoizedState,c.lanes=d.lanes):(c.updateQueue=null,c.memoizedState=null)}var h=zg(a);if(h!==null){h.flags&=-257,Fg(h,a,s,o,t),h.mode&1&&Og(o,l,t),t=h,u=l;var g=t.updateQueue;if(g===null){var v=new Set;v.add(u),t.updateQueue=v}else g.add(u);break e}else{if(!(t&1)){Og(o,l,t),tv();break e}u=Error(q(426))}}else if(se&&s.mode&1){var y=zg(a);if(y!==null){!(y.flags&65536)&&(y.flags|=256),Fg(y,a,s,o,t),Mp(Fr(u,s));break e}}o=u=Fr(u,s),_e!==4&&(_e=2),Pi===null?Pi=[o]:Pi.push(o),o=a;do{switch(o.tag){case 3:o.flags|=65536,t&=-t,o.lanes|=t;var p=kS(o,u,t);Pg(o,p);break e;case 1:s=u;var m=o.type,_=o.stateNode;if(!(o.flags&128)&&(typeof m.getDerivedStateFromError=="function"||_!==null&&typeof _.componentDidCatch=="function"&&(_n===null||!_n.has(_)))){o.flags|=65536,t&=-t,o.lanes|=t;var x=bS(o,s,t);Pg(o,x);break e}}o=o.return}while(o!==null)}VS(n)}catch(S){t=S,ve===n&&n!==null&&(ve=n=n.return);continue}break}while(!0)}function US(){var e=Ra.current;return Ra.current=Ta,e===null?Ta:e}function tv(){(_e===0||_e===3||_e===2)&&(_e=4),Se===null||!(Qn&268435455)&&!(ts&268435455)||un(Se,be)}function Pa(e,t){var n=W;W|=2;var r=US();(Se!==e||be!==t)&&(Mt=null,Un(e,t));do try{kb();break}catch(i){BS(e,i)}while(!0);if(Op(),W=n,Ra.current=r,ve!==null)throw Error(q(261));return Se=null,be=0,_e}function kb(){for(;ve!==null;)HS(ve)}function bb(){for(;ve!==null&&!Xk();)HS(ve)}function HS(e){var t=WS(e.alternate,e,Ke);e.memoizedProps=e.pendingProps,t===null?VS(e):ve=t,Qp.current=null}function VS(e){var t=e;do{var n=t.alternate;if(e=t.return,t.flags&32768){if(n=_b(n,t),n!==null){n.flags&=32767,ve=n;return}if(e!==null)e.flags|=32768,e.subtreeFlags=0,e.deletions=null;else{_e=6,ve=null;return}}else if(n=yb(n,t,Ke),n!==null){ve=n;return}if(t=t.sibling,t!==null){ve=t;return}ve=t=e}while(t!==null);_e===0&&(_e=5)}function Ln(e,t,n){var r=X,i=ot.transition;try{ot.transition=null,X=1,Tb(e,t,n,r)}finally{ot.transition=i,X=r}return null}function Tb(e,t,n,r){do Pr();while(fn!==null);if(W&6)throw Error(q(327));n=e.finishedWork;var i=e.finishedLanes;if(n===null)return null;if(e.finishedWork=null,e.finishedLanes=0,n===e.current)throw Error(q(177));e.callbackNode=null,e.callbackPriority=0;var o=n.lanes|n.childLanes;if(s2(e,o),e===Se&&(ve=Se=null,be=0),!(n.subtreeFlags&2064)&&!(n.flags&2064)||zo||(zo=!0,KS(da,function(){return Pr(),null})),o=(n.flags&15990)!==0,n.subtreeFlags&15990||o){o=ot.transition,ot.transition=null;var a=X;X=1;var s=W;W|=4,Qp.current=null,wb(e,n),FS(n,e),W2(bh),pa=!!kh,bh=kh=null,e.current=n,Sb(n),Zk(),W=s,X=a,ot.transition=o}else e.current=n;if(zo&&(zo=!1,fn=e,Ia=i),o=e.pendingLanes,o===0&&(_n=null),t2(n.stateNode),Ve(e,he()),t!==null)for(r=e.onRecoverableError,n=0;n<t.length;n++)i=t[n],r(i.value,{componentStack:i.stack,digest:i.digest});if(Na)throw Na=!1,e=Gh,Gh=null,e;return Ia&1&&e.tag!==0&&Pr(),o=e.pendingLanes,o&1?e===Wh?ji++:(ji=0,Wh=e):ji=0,In(),null}function Pr(){if(fn!==null){var e=kw(Ia),t=ot.transition,n=X;try{if(ot.transition=null,X=16>e?16:e,fn===null)var r=!1;else{if(e=fn,fn=null,Ia=0,W&6)throw Error(q(331));var i=W;for(W|=4,z=e.current;z!==null;){var o=z,a=o.child;if(z.flags&16){var s=o.deletions;if(s!==null){for(var u=0;u<s.length;u++){var l=s[u];for(z=l;z!==null;){var c=z;switch(c.tag){case 0:case 11:case 15:Ii(8,c,o)}var f=c.child;if(f!==null)f.return=c,z=f;else for(;z!==null;){c=z;var d=c.sibling,h=c.return;if(LS(c),c===l){z=null;break}if(d!==null){d.return=h,z=d;break}z=h}}}var g=o.alternate;if(g!==null){var v=g.child;if(v!==null){g.child=null;do{var y=v.sibling;v.sibling=null,v=y}while(v!==null)}}z=o}}if(o.subtreeFlags&2064&&a!==null)a.return=o,z=a;else e:for(;z!==null;){if(o=z,o.flags&2048)switch(o.tag){case 0:case 11:case 15:Ii(9,o,o.return)}var p=o.sibling;if(p!==null){p.return=o.return,z=p;break e}z=o.return}}var m=e.current;for(z=m;z!==null;){a=z;var _=a.child;if(a.subtreeFlags&2064&&_!==null)_.return=a,z=_;else e:for(a=m;z!==null;){if(s=z,s.flags&2048)try{switch(s.tag){case 0:case 11:case 15:es(9,s)}}catch(S){de(s,s.return,S)}if(s===a){z=null;break e}var x=s.sibling;if(x!==null){x.return=s.return,z=x;break e}z=s.return}}if(W=i,In(),Tt&&typeof Tt.onPostCommitFiberRoot=="function")try{Tt.onPostCommitFiberRoot(Ga,e)}catch{}r=!0}return r}finally{X=n,ot.transition=t}}return!1}function Zg(e,t,n){t=Fr(n,t),t=kS(e,t,1),e=yn(e,t,1),t=Ae(),e!==null&&(io(e,1,t),Ve(e,t))}function de(e,t,n){if(e.tag===3)Zg(e,e,n);else for(;t!==null;){if(t.tag===3){Zg(t,e,n);break}else if(t.tag===1){var r=t.stateNode;if(typeof t.type.getDerivedStateFromError=="function"||typeof r.componentDidCatch=="function"&&(_n===null||!_n.has(r))){e=Fr(n,e),e=bS(t,e,1),t=yn(t,e,1),e=Ae(),t!==null&&(io(t,1,e),Ve(t,e));break}}t=t.return}}function Rb(e,t,n){var r=e.pingCache;r!==null&&r.delete(t),t=Ae(),e.pingedLanes|=e.suspendedLanes&n,Se===e&&(be&n)===n&&(_e===4||_e===3&&(be&130023424)===be&&500>he()-Zp?Un(e,0):Xp|=n),Ve(e,t)}function GS(e,t){t===0&&(e.mode&1?(t=Ro,Ro<<=1,!(Ro&130023424)&&(Ro=4194304)):t=1);var n=Ae();e=Gt(e,t),e!==null&&(io(e,t,n),Ve(e,n))}function Nb(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),GS(e,n)}function Ib(e,t){var n=0;switch(e.tag){case 13:var r=e.stateNode,i=e.memoizedState;i!==null&&(n=i.retryLane);break;case 19:r=e.stateNode;break;default:throw Error(q(314))}r!==null&&r.delete(t),GS(e,n)}var WS;WS=function(e,t,n){if(e!==null)if(e.memoizedProps!==t.pendingProps||Ue.current)$e=!0;else{if(!(e.lanes&n)&&!(t.flags&128))return $e=!1,mb(e,t,n);$e=!!(e.flags&131072)}else $e=!1,se&&t.flags&1048576&&Xw(t,wa,t.index);switch(t.lanes=0,t.tag){case 2:var r=t.type;ta(e,t),e=t.pendingProps;var i=Mr(t,Pe.current);Ir(t,n),i=Vp(null,t,r,e,i,n);var o=Gp();return t.flags|=1,typeof i=="object"&&i!==null&&typeof i.render=="function"&&i.$$typeof===void 0?(t.tag=1,t.memoizedState=null,t.updateQueue=null,He(r)?(o=!0,_a(t)):o=!1,t.memoizedState=i.state!==null&&i.state!==void 0?i.state:null,Dp(t),i.updater=Ja,t.stateNode=i,i._reactInternals=t,Mh(t,r,e,n),t=zh(null,t,r,!0,o,n)):(t.tag=0,se&&o&&qp(t),je(null,t,i,n),t=t.child),t;case 16:r=t.elementType;e:{switch(ta(e,t),e=t.pendingProps,i=r._init,r=i(r._payload),t.type=r,i=t.tag=jb(r),e=ht(r,e),i){case 0:t=Oh(null,t,r,e,n);break e;case 1:t=Bg(null,t,r,e,n);break e;case 11:t=Dg(null,t,r,e,n);break e;case 14:t=$g(null,t,r,ht(r.type,e),n);break e}throw Error(q(306,r,""))}return t;case 0:return r=t.type,i=t.pendingProps,i=t.elementType===r?i:ht(r,i),Oh(e,t,r,i,n);case 1:return r=t.type,i=t.pendingProps,i=t.elementType===r?i:ht(r,i),Bg(e,t,r,i,n);case 3:e:{if(IS(t),e===null)throw Error(q(387));r=t.pendingProps,o=t.memoizedState,i=o.element,rS(e,t),Ca(t,r,null,n);var a=t.memoizedState;if(r=a.element,o.isDehydrated)if(o={element:r,isDehydrated:!1,cache:a.cache,pendingSuspenseBoundaries:a.pendingSuspenseBoundaries,transitions:a.transitions},t.updateQueue.baseState=o,t.memoizedState=o,t.flags&256){i=Fr(Error(q(423)),t),t=Ug(e,t,r,n,i);break e}else if(r!==i){i=Fr(Error(q(424)),t),t=Ug(e,t,r,n,i);break e}else for(Qe=mn(t.stateNode.containerInfo.firstChild),Xe=t,se=!0,vt=null,n=tS(t,null,r,n),t.child=n;n;)n.flags=n.flags&-3|4096,n=n.sibling;else{if(Lr(),r===i){t=Wt(e,t,n);break e}je(e,t,r,n)}t=t.child}return t;case 5:return iS(t),e===null&&jh(t),r=t.type,i=t.pendingProps,o=e!==null?e.memoizedProps:null,a=i.children,Th(r,i)?a=null:o!==null&&Th(r,o)&&(t.flags|=32),NS(e,t),je(e,t,a,n),t.child;case 6:return e===null&&jh(t),null;case 13:return PS(e,t,n);case 4:return $p(t,t.stateNode.containerInfo),r=t.pendingProps,e===null?t.child=Or(t,null,r,n):je(e,t,r,n),t.child;case 11:return r=t.type,i=t.pendingProps,i=t.elementType===r?i:ht(r,i),Dg(e,t,r,i,n);case 7:return je(e,t,t.pendingProps,n),t.child;case 8:return je(e,t,t.pendingProps.children,n),t.child;case 12:return je(e,t,t.pendingProps.children,n),t.child;case 10:e:{if(r=t.type._context,i=t.pendingProps,o=t.memoizedProps,a=i.value,re(Sa,r._currentValue),r._currentValue=a,o!==null)if(_t(o.value,a)){if(o.children===i.children&&!Ue.current){t=Wt(e,t,n);break e}}else for(o=t.child,o!==null&&(o.return=t);o!==null;){var s=o.dependencies;if(s!==null){a=o.child;for(var u=s.firstContext;u!==null;){if(u.context===r){if(o.tag===1){u=Ut(-1,n&-n),u.tag=2;var l=o.updateQueue;if(l!==null){l=l.shared;var c=l.pending;c===null?u.next=u:(u.next=c.next,c.next=u),l.pending=u}}o.lanes|=n,u=o.alternate,u!==null&&(u.lanes|=n),qh(o.return,n,t),s.lanes|=n;break}u=u.next}}else if(o.tag===10)a=o.type===t.type?null:o.child;else if(o.tag===18){if(a=o.return,a===null)throw Error(q(341));a.lanes|=n,s=a.alternate,s!==null&&(s.lanes|=n),qh(a,n,t),a=o.sibling}else a=o.child;if(a!==null)a.return=o;else for(a=o;a!==null;){if(a===t){a=null;break}if(o=a.sibling,o!==null){o.return=a.return,a=o;break}a=a.return}o=a}je(e,t,i.children,n),t=t.child}return t;case 9:return i=t.type,r=t.pendingProps.children,Ir(t,n),i=at(i),r=r(i),t.flags|=1,je(e,t,r,n),t.child;case 14:return r=t.type,i=ht(r,t.pendingProps),i=ht(r.type,i),$g(e,t,r,i,n);case 15:return TS(e,t,t.type,t.pendingProps,n);case 17:return r=t.type,i=t.pendingProps,i=t.elementType===r?i:ht(r,i),ta(e,t),t.tag=1,He(r)?(e=!0,_a(t)):e=!1,Ir(t,n),CS(t,r,i),Mh(t,r,i,n),zh(null,t,r,!0,e,n);case 19:return jS(e,t,n);case 22:return RS(e,t,n)}throw Error(q(156,t.tag))};function KS(e,t){return ww(e,t)}function Pb(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function it(e,t,n,r){return new Pb(e,t,n,r)}function nv(e){return e=e.prototype,!(!e||!e.isReactComponent)}function jb(e){if(typeof e=="function")return nv(e)?1:0;if(e!=null){if(e=e.$$typeof,e===wp)return 11;if(e===Sp)return 14}return 2}function wn(e,t){var n=e.alternate;return n===null?(n=it(e.tag,t,e.key,e.mode),n.elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=e.flags&14680064,n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function ia(e,t,n,r,i,o){var a=2;if(r=e,typeof e=="function")nv(e)&&(a=1);else if(typeof e=="string")a=5;else e:switch(e){case vr:return Hn(n.children,i,o,t);case xp:a=8,i|=8;break;case oh:return e=it(12,n,t,i|2),e.elementType=oh,e.lanes=o,e;case ah:return e=it(13,n,t,i),e.elementType=ah,e.lanes=o,e;case sh:return e=it(19,n,t,i),e.elementType=sh,e.lanes=o,e;case iw:return ns(n,i,o,t);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case nw:a=10;break e;case rw:a=9;break e;case wp:a=11;break e;case Sp:a=14;break e;case rn:a=16,r=null;break e}throw Error(q(130,e==null?e:typeof e,""))}return t=it(a,n,t,i),t.elementType=e,t.type=r,t.lanes=o,t}function Hn(e,t,n,r){return e=it(7,e,r,t),e.lanes=n,e}function ns(e,t,n,r){return e=it(22,e,r,t),e.elementType=iw,e.lanes=n,e.stateNode={isHidden:!1},e}function tu(e,t,n){return e=it(6,e,null,t),e.lanes=n,e}function nu(e,t,n){return t=it(4,e.children!==null?e.children:[],e.key,t),t.lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function qb(e,t,n,r,i){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=Ls(0),this.expirationTimes=Ls(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Ls(0),this.identifierPrefix=r,this.onRecoverableError=i,this.mutableSourceEagerHydrationData=null}function rv(e,t,n,r,i,o,a,s,u){return e=new qb(e,t,n,s,u),t===1?(t=1,o===!0&&(t|=8)):t=0,o=it(3,null,null,t),e.current=o,o.stateNode=e,o.memoizedState={element:r,isDehydrated:n,cache:null,transitions:null,pendingSuspenseBoundaries:null},Dp(o),e}function Ab(e,t,n){var r=3<arguments.length&&arguments[3]!==void 0?arguments[3]:null;return{$$typeof:pr,key:r==null?null:""+r,children:e,containerInfo:t,implementation:n}}function YS(e){if(!e)return kn;e=e._reactInternals;e:{if(er(e)!==e||e.tag!==1)throw Error(q(170));var t=e;do{switch(t.tag){case 3:t=t.stateNode.context;break e;case 1:if(He(t.type)){t=t.stateNode.__reactInternalMemoizedMergedChildContext;break e}}t=t.return}while(t!==null);throw Error(q(171))}if(e.tag===1){var n=e.type;if(He(n))return Yw(e,n,t)}return t}function QS(e,t,n,r,i,o,a,s,u){return e=rv(n,r,!0,e,i,o,a,s,u),e.context=YS(null),n=e.current,r=Ae(),i=xn(n),o=Ut(r,i),o.callback=t??null,yn(n,o,i),e.current.lanes=i,io(e,i,r),Ve(e,r),e}function rs(e,t,n,r){var i=t.current,o=Ae(),a=xn(i);return n=YS(n),t.context===null?t.context=n:t.pendingContext=n,t=Ut(o,a),t.payload={element:e},r=r===void 0?null:r,r!==null&&(t.callback=r),e=yn(i,t,a),e!==null&&(yt(e,i,a,o),Zo(e,i,a)),a}function ja(e){if(e=e.current,!e.child)return null;switch(e.child.tag){case 5:return e.child.stateNode;default:return e.child.stateNode}}function Jg(e,t){if(e=e.memoizedState,e!==null&&e.dehydrated!==null){var n=e.retryLane;e.retryLane=n!==0&&n<t?n:t}}function iv(e,t){Jg(e,t),(e=e.alternate)&&Jg(e,t)}function Mb(){return null}var XS=typeof reportError=="function"?reportError:function(e){console.error(e)};function ov(e){this._internalRoot=e}is.prototype.render=ov.prototype.render=function(e){var t=this._internalRoot;if(t===null)throw Error(q(409));rs(e,t,null,null)};is.prototype.unmount=ov.prototype.unmount=function(){var e=this._internalRoot;if(e!==null){this._internalRoot=null;var t=e.containerInfo;Xn(function(){rs(null,e,null,null)}),t[Vt]=null}};function is(e){this._internalRoot=e}is.prototype.unstable_scheduleHydration=function(e){if(e){var t=Rw();e={blockedOn:null,target:e,priority:t};for(var n=0;n<sn.length&&t!==0&&t<sn[n].priority;n++);sn.splice(n,0,e),n===0&&Iw(e)}};function av(e){return!(!e||e.nodeType!==1&&e.nodeType!==9&&e.nodeType!==11)}function os(e){return!(!e||e.nodeType!==1&&e.nodeType!==9&&e.nodeType!==11&&(e.nodeType!==8||e.nodeValue!==" react-mount-point-unstable "))}function em(){}function Lb(e,t,n,r,i){if(i){if(typeof r=="function"){var o=r;r=function(){var l=ja(a);o.call(l)}}var a=QS(t,r,e,0,null,!1,!1,"",em);return e._reactRootContainer=a,e[Vt]=a.current,$i(e.nodeType===8?e.parentNode:e),Xn(),a}for(;i=e.lastChild;)e.removeChild(i);if(typeof r=="function"){var s=r;r=function(){var l=ja(u);s.call(l)}}var u=rv(e,0,!1,null,null,!1,!1,"",em);return e._reactRootContainer=u,e[Vt]=u.current,$i(e.nodeType===8?e.parentNode:e),Xn(function(){rs(t,u,n,r)}),u}function as(e,t,n,r,i){var o=n._reactRootContainer;if(o){var a=o;if(typeof i=="function"){var s=i;i=function(){var u=ja(a);s.call(u)}}rs(t,a,e,i)}else a=Lb(n,t,e,i,r);return ja(a)}bw=function(e){switch(e.tag){case 3:var t=e.stateNode;if(t.current.memoizedState.isDehydrated){var n=pi(t.pendingLanes);n!==0&&(kp(t,n|1),Ve(t,he()),!(W&6)&&(Dr=he()+500,In()))}break;case 13:Xn(function(){var r=Gt(e,1);if(r!==null){var i=Ae();yt(r,e,1,i)}}),iv(e,1)}};bp=function(e){if(e.tag===13){var t=Gt(e,134217728);if(t!==null){var n=Ae();yt(t,e,134217728,n)}iv(e,134217728)}};Tw=function(e){if(e.tag===13){var t=xn(e),n=Gt(e,t);if(n!==null){var r=Ae();yt(n,e,t,r)}iv(e,t)}};Rw=function(){return X};Nw=function(e,t){var n=X;try{return X=e,t()}finally{X=n}};mh=function(e,t,n){switch(t){case"input":if(ch(e,n),t=n.name,n.type==="radio"&&t!=null){for(n=e;n.parentNode;)n=n.parentNode;for(n=n.querySelectorAll("input[name="+JSON.stringify(""+t)+'][type="radio"]'),t=0;t<n.length;t++){var r=n[t];if(r!==e&&r.form===e.form){var i=Qa(r);if(!i)throw Error(q(90));aw(r),ch(r,i)}}}break;case"textarea":uw(e,n);break;case"select":t=n.value,t!=null&&br(e,!!n.multiple,t,!1)}};vw=Jp;gw=Xn;var Ob={usingClientEntryPoint:!1,Events:[ao,_r,Qa,hw,pw,Jp]},li={findFiberByHostInstance:zn,bundleType:0,version:"18.3.1",rendererPackageName:"react-dom"},zb={bundleType:li.bundleType,version:li.version,rendererPackageName:li.rendererPackageName,rendererConfig:li.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setErrorHandler:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:Qt.ReactCurrentDispatcher,findHostInstanceByFiber:function(e){return e=_w(e),e===null?null:e.stateNode},findFiberByHostInstance:li.findFiberByHostInstance||Mb,findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null,reconcilerVersion:"18.3.1-next-f1338f8080-20240426"};if(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"){var Fo=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!Fo.isDisabled&&Fo.supportsFiber)try{Ga=Fo.inject(zb),Tt=Fo}catch{}}et.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=Ob;et.createPortal=function(e,t){var n=2<arguments.length&&arguments[2]!==void 0?arguments[2]:null;if(!av(t))throw Error(q(200));return Ab(e,t,null,n)};et.createRoot=function(e,t){if(!av(e))throw Error(q(299));var n=!1,r="",i=XS;return t!=null&&(t.unstable_strictMode===!0&&(n=!0),t.identifierPrefix!==void 0&&(r=t.identifierPrefix),t.onRecoverableError!==void 0&&(i=t.onRecoverableError)),t=rv(e,1,!1,null,null,n,!1,r,i),e[Vt]=t.current,$i(e.nodeType===8?e.parentNode:e),new ov(t)};et.findDOMNode=function(e){if(e==null)return null;if(e.nodeType===1)return e;var t=e._reactInternals;if(t===void 0)throw typeof e.render=="function"?Error(q(188)):(e=Object.keys(e).join(","),Error(q(268,e)));return e=_w(t),e=e===null?null:e.stateNode,e};et.flushSync=function(e){return Xn(e)};et.hydrate=function(e,t,n){if(!os(t))throw Error(q(200));return as(null,e,t,!0,n)};et.hydrateRoot=function(e,t,n){if(!av(e))throw Error(q(405));var r=n!=null&&n.hydratedSources||null,i=!1,o="",a=XS;if(n!=null&&(n.unstable_strictMode===!0&&(i=!0),n.identifierPrefix!==void 0&&(o=n.identifierPrefix),n.onRecoverableError!==void 0&&(a=n.onRecoverableError)),t=QS(t,null,e,1,n??null,i,!1,o,a),e[Vt]=t.current,$i(e),r)for(e=0;e<r.length;e++)n=r[e],i=n._getVersion,i=i(n._source),t.mutableSourceEagerHydrationData==null?t.mutableSourceEagerHydrationData=[n,i]:t.mutableSourceEagerHydrationData.push(n,i);return new is(t)};et.render=function(e,t,n){if(!os(t))throw Error(q(200));return as(null,e,t,!1,n)};et.unmountComponentAtNode=function(e){if(!os(e))throw Error(q(40));return e._reactRootContainer?(Xn(function(){as(null,null,e,!1,function(){e._reactRootContainer=null,e[Vt]=null})}),!0):!1};et.unstable_batchedUpdates=Jp;et.unstable_renderSubtreeIntoContainer=function(e,t,n,r){if(!os(n))throw Error(q(200));if(e==null||e._reactInternals===void 0)throw Error(q(38));return as(e,t,n,!1,r)};et.version="18.3.1-next-f1338f8080-20240426";function ZS(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(ZS)}catch(e){console.error(e)}}ZS(),Zx.exports=et;var Fb=Zx.exports,tm=Fb;rh.createRoot=tm.createRoot,rh.hydrateRoot=tm.hydrateRoot;/** 49 - * @remix-run/router v1.23.1 50 - * 51 - * Copyright (c) Remix Software Inc. 52 - * 53 - * This source code is licensed under the MIT license found in the 54 - * LICENSE.md file in the root directory of this source tree. 55 - * 56 - * @license MIT 57 - */function Qi(){return Qi=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},Qi.apply(this,arguments)}var dn;(function(e){e.Pop="POP",e.Push="PUSH",e.Replace="REPLACE"})(dn||(dn={}));const nm="popstate";function Db(e){e===void 0&&(e={});function t(i,o){let{pathname:a="/",search:s="",hash:u=""}=tr(i.location.hash.substr(1));return!a.startsWith("/")&&!a.startsWith(".")&&(a="/"+a),Qh("",{pathname:a,search:s,hash:u},o.state&&o.state.usr||null,o.state&&o.state.key||"default")}function n(i,o){let a=i.document.querySelector("base"),s="";if(a&&a.getAttribute("href")){let u=i.location.href,l=u.indexOf("#");s=l===-1?u:u.slice(0,l)}return s+"#"+(typeof o=="string"?o:qa(o))}function r(i,o){ss(i.pathname.charAt(0)==="/","relative pathnames are not supported in hash history.push("+JSON.stringify(o)+")")}return Bb(t,n,r,e)}function pe(e,t){if(e===!1||e===null||typeof e>"u")throw new Error(t)}function ss(e,t){if(!e){typeof console<"u"&&console.warn(t);try{throw new Error(t)}catch{}}}function $b(){return Math.random().toString(36).substr(2,8)}function rm(e,t){return{usr:e.state,key:e.key,idx:t}}function Qh(e,t,n,r){return n===void 0&&(n=null),Qi({pathname:typeof e=="string"?e:e.pathname,search:"",hash:""},typeof t=="string"?tr(t):t,{state:n,key:t&&t.key||r||$b()})}function qa(e){let{pathname:t="/",search:n="",hash:r=""}=e;return n&&n!=="?"&&(t+=n.charAt(0)==="?"?n:"?"+n),r&&r!=="#"&&(t+=r.charAt(0)==="#"?r:"#"+r),t}function tr(e){let t={};if(e){let n=e.indexOf("#");n>=0&&(t.hash=e.substr(n),e=e.substr(0,n));let r=e.indexOf("?");r>=0&&(t.search=e.substr(r),e=e.substr(0,r)),e&&(t.pathname=e)}return t}function Bb(e,t,n,r){r===void 0&&(r={});let{window:i=document.defaultView,v5Compat:o=!1}=r,a=i.history,s=dn.Pop,u=null,l=c();l==null&&(l=0,a.replaceState(Qi({},a.state,{idx:l}),""));function c(){return(a.state||{idx:null}).idx}function f(){s=dn.Pop;let y=c(),p=y==null?null:y-l;l=y,u&&u({action:s,location:v.location,delta:p})}function d(y,p){s=dn.Push;let m=Qh(v.location,y,p);n&&n(m,y),l=c()+1;let _=rm(m,l),x=v.createHref(m);try{a.pushState(_,"",x)}catch(S){if(S instanceof DOMException&&S.name==="DataCloneError")throw S;i.location.assign(x)}o&&u&&u({action:s,location:v.location,delta:1})}function h(y,p){s=dn.Replace;let m=Qh(v.location,y,p);n&&n(m,y),l=c();let _=rm(m,l),x=v.createHref(m);a.replaceState(_,"",x),o&&u&&u({action:s,location:v.location,delta:0})}function g(y){let p=i.location.origin!=="null"?i.location.origin:i.location.href,m=typeof y=="string"?y:qa(y);return m=m.replace(/ $/,"%20"),pe(p,"No window.location.(origin|href) available to create URL for href: "+m),new URL(m,p)}let v={get action(){return s},get location(){return e(i,a)},listen(y){if(u)throw new Error("A history only accepts one active listener");return i.addEventListener(nm,f),u=y,()=>{i.removeEventListener(nm,f),u=null}},createHref(y){return t(i,y)},createURL:g,encodeLocation(y){let p=g(y);return{pathname:p.pathname,search:p.search,hash:p.hash}},push:d,replace:h,go(y){return a.go(y)}};return v}var im;(function(e){e.data="data",e.deferred="deferred",e.redirect="redirect",e.error="error"})(im||(im={}));function Ub(e,t,n){return n===void 0&&(n="/"),Hb(e,t,n)}function Hb(e,t,n,r){let i=typeof t=="string"?tr(t):t,o=sv(i.pathname||"/",n);if(o==null)return null;let a=JS(e);Vb(a);let s=null;for(let u=0;s==null&&u<a.length;++u){let l=rT(o);s=eT(a[u],l)}return s}function JS(e,t,n,r){t===void 0&&(t=[]),n===void 0&&(n=[]),r===void 0&&(r="");let i=(o,a,s)=>{let u={relativePath:s===void 0?o.path||"":s,caseSensitive:o.caseSensitive===!0,childrenIndex:a,route:o};u.relativePath.startsWith("/")&&(pe(u.relativePath.startsWith(r),'Absolute route path "'+u.relativePath+'" nested under path '+('"'+r+'" is not valid. An absolute child route path ')+"must start with the combined path of all its parent routes."),u.relativePath=u.relativePath.slice(r.length));let l=Sn([r,u.relativePath]),c=n.concat(u);o.children&&o.children.length>0&&(pe(o.index!==!0,"Index routes must not have child routes. Please remove "+('all child routes from route path "'+l+'".')),JS(o.children,t,c,l)),!(o.path==null&&!o.index)&&t.push({path:l,score:Zb(l,o.index),routesMeta:c})};return e.forEach((o,a)=>{var s;if(o.path===""||!((s=o.path)!=null&&s.includes("?")))i(o,a);else for(let u of eE(o.path))i(o,a,u)}),t}function eE(e){let t=e.split("/");if(t.length===0)return[];let[n,...r]=t,i=n.endsWith("?"),o=n.replace(/\?$/,"");if(r.length===0)return i?[o,""]:[o];let a=eE(r.join("/")),s=[];return s.push(...a.map(u=>u===""?o:[o,u].join("/"))),i&&s.push(...a),s.map(u=>e.startsWith("/")&&u===""?"/":u)}function Vb(e){e.sort((t,n)=>t.score!==n.score?n.score-t.score:Jb(t.routesMeta.map(r=>r.childrenIndex),n.routesMeta.map(r=>r.childrenIndex)))}const Gb=/^:[\w-]+$/,Wb=3,Kb=2,Yb=1,Qb=10,Xb=-2,om=e=>e==="*";function Zb(e,t){let n=e.split("/"),r=n.length;return n.some(om)&&(r+=Xb),t&&(r+=Kb),n.filter(i=>!om(i)).reduce((i,o)=>i+(Gb.test(o)?Wb:o===""?Yb:Qb),r)}function Jb(e,t){return e.length===t.length&&e.slice(0,-1).every((r,i)=>r===t[i])?e[e.length-1]-t[t.length-1]:0}function eT(e,t,n){let{routesMeta:r}=e,i={},o="/",a=[];for(let s=0;s<r.length;++s){let u=r[s],l=s===r.length-1,c=o==="/"?t:t.slice(o.length)||"/",f=tT({path:u.relativePath,caseSensitive:u.caseSensitive,end:l},c),d=u.route;if(!f)return null;Object.assign(i,f.params),a.push({params:i,pathname:Sn([o,f.pathname]),pathnameBase:uT(Sn([o,f.pathnameBase])),route:d}),f.pathnameBase!=="/"&&(o=Sn([o,f.pathnameBase]))}return a}function tT(e,t){typeof e=="string"&&(e={path:e,caseSensitive:!1,end:!0});let[n,r]=nT(e.path,e.caseSensitive,e.end),i=t.match(n);if(!i)return null;let o=i[0],a=o.replace(/(.)\/+$/,"$1"),s=i.slice(1);return{params:r.reduce((l,c,f)=>{let{paramName:d,isOptional:h}=c;if(d==="*"){let v=s[f]||"";a=o.slice(0,o.length-v.length).replace(/(.)\/+$/,"$1")}const g=s[f];return h&&!g?l[d]=void 0:l[d]=(g||"").replace(/%2F/g,"/"),l},{}),pathname:o,pathnameBase:a,pattern:e}}function nT(e,t,n){t===void 0&&(t=!1),n===void 0&&(n=!0),ss(e==="*"||!e.endsWith("*")||e.endsWith("/*"),'Route path "'+e+'" will be treated as if it were '+('"'+e.replace(/\*$/,"/*")+'" because the `*` character must ')+"always follow a `/` in the pattern. To get rid of this warning, "+('please change the route path to "'+e.replace(/\*$/,"/*")+'".'));let r=[],i="^"+e.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(a,s,u)=>(r.push({paramName:s,isOptional:u!=null}),u?"/?([^\\/]+)?":"/([^\\/]+)"));return e.endsWith("*")?(r.push({paramName:"*"}),i+=e==="*"||e==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):n?i+="\\/*$":e!==""&&e!=="/"&&(i+="(?:(?=\\/|$))"),[new RegExp(i,t?void 0:"i"),r]}function rT(e){try{return e.split("/").map(t=>decodeURIComponent(t).replace(/\//g,"%2F")).join("/")}catch(t){return ss(!1,'The URL path "'+e+'" could not be decoded because it is is a malformed URL segment. This is probably due to a bad percent '+("encoding ("+t+").")),e}}function sv(e,t){if(t==="/")return e;if(!e.toLowerCase().startsWith(t.toLowerCase()))return null;let n=t.endsWith("/")?t.length-1:t.length,r=e.charAt(n);return r&&r!=="/"?null:e.slice(n)||"/"}const iT=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,oT=e=>iT.test(e);function aT(e,t){t===void 0&&(t="/");let{pathname:n,search:r="",hash:i=""}=typeof e=="string"?tr(e):e,o;if(n)if(oT(n))o=n;else{if(n.includes("//")){let a=n;n=n.replace(/\/\/+/g,"/"),ss(!1,"Pathnames cannot have embedded double slashes - normalizing "+(a+" -> "+n))}n.startsWith("/")?o=am(n.substring(1),"/"):o=am(n,t)}else o=t;return{pathname:o,search:lT(r),hash:cT(i)}}function am(e,t){let n=t.replace(/\/+$/,"").split("/");return e.split("/").forEach(i=>{i===".."?n.length>1&&n.pop():i!=="."&&n.push(i)}),n.length>1?n.join("/"):"/"}function ru(e,t,n,r){return"Cannot include a '"+e+"' character in a manually specified "+("`to."+t+"` field ["+JSON.stringify(r)+"]. Please separate it out to the ")+("`to."+n+"` field. Alternatively you may provide the full path as ")+'a string in <Link to="..."> and the router will parse it for you.'}function sT(e){return e.filter((t,n)=>n===0||t.route.path&&t.route.path.length>0)}function uv(e,t){let n=sT(e);return t?n.map((r,i)=>i===n.length-1?r.pathname:r.pathnameBase):n.map(r=>r.pathnameBase)}function lv(e,t,n,r){r===void 0&&(r=!1);let i;typeof e=="string"?i=tr(e):(i=Qi({},e),pe(!i.pathname||!i.pathname.includes("?"),ru("?","pathname","search",i)),pe(!i.pathname||!i.pathname.includes("#"),ru("#","pathname","hash",i)),pe(!i.search||!i.search.includes("#"),ru("#","search","hash",i)));let o=e===""||i.pathname==="",a=o?"/":i.pathname,s;if(a==null)s=n;else{let f=t.length-1;if(!r&&a.startsWith("..")){let d=a.split("/");for(;d[0]==="..";)d.shift(),f-=1;i.pathname=d.join("/")}s=f>=0?t[f]:"/"}let u=aT(i,s),l=a&&a!=="/"&&a.endsWith("/"),c=(o||a===".")&&n.endsWith("/");return!u.pathname.endsWith("/")&&(l||c)&&(u.pathname+="/"),u}const Sn=e=>e.join("/").replace(/\/\/+/g,"/"),uT=e=>e.replace(/\/+$/,"").replace(/^\/*/,"/"),lT=e=>!e||e==="?"?"":e.startsWith("?")?e:"?"+e,cT=e=>!e||e==="#"?"":e.startsWith("#")?e:"#"+e;function fT(e){return e!=null&&typeof e.status=="number"&&typeof e.statusText=="string"&&typeof e.internal=="boolean"&&"data"in e}const tE=["post","put","patch","delete"];new Set(tE);const dT=["get",...tE];new Set(dT);/** 58 - * React Router v6.30.2 59 - * 60 - * Copyright (c) Remix Software Inc. 61 - * 62 - * This source code is licensed under the MIT license found in the 63 - * LICENSE.md file in the root directory of this source tree. 64 - * 65 - * @license MIT 66 - */function Xi(){return Xi=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},Xi.apply(this,arguments)}const cv=N.createContext(null),hT=N.createContext(null),Pn=N.createContext(null),us=N.createContext(null),jn=N.createContext({outlet:null,matches:[],isDataRoute:!1}),nE=N.createContext(null);function pT(e,t){let{relative:n}=t===void 0?{}:t;Kr()||pe(!1);let{basename:r,navigator:i}=N.useContext(Pn),{hash:o,pathname:a,search:s}=oE(e,{relative:n}),u=a;return r!=="/"&&(u=a==="/"?r:Sn([r,a])),i.createHref({pathname:u,search:s,hash:o})}function Kr(){return N.useContext(us)!=null}function Yr(){return Kr()||pe(!1),N.useContext(us).location}function rE(e){N.useContext(Pn).static||N.useLayoutEffect(e)}function iE(){let{isDataRoute:e}=N.useContext(jn);return e?TT():vT()}function vT(){Kr()||pe(!1);let e=N.useContext(cv),{basename:t,future:n,navigator:r}=N.useContext(Pn),{matches:i}=N.useContext(jn),{pathname:o}=Yr(),a=JSON.stringify(uv(i,n.v7_relativeSplatPath)),s=N.useRef(!1);return rE(()=>{s.current=!0}),N.useCallback(function(l,c){if(c===void 0&&(c={}),!s.current)return;if(typeof l=="number"){r.go(l);return}let f=lv(l,JSON.parse(a),o,c.relative==="path");e==null&&t!=="/"&&(f.pathname=f.pathname==="/"?t:Sn([t,f.pathname])),(c.replace?r.replace:r.push)(f,c.state,c)},[t,r,a,o,e])}function oE(e,t){let{relative:n}=t===void 0?{}:t,{future:r}=N.useContext(Pn),{matches:i}=N.useContext(jn),{pathname:o}=Yr(),a=JSON.stringify(uv(i,r.v7_relativeSplatPath));return N.useMemo(()=>lv(e,JSON.parse(a),o,n==="path"),[e,a,o,n])}function gT(e,t){return mT(e,t)}function mT(e,t,n,r){Kr()||pe(!1);let{navigator:i}=N.useContext(Pn),{matches:o}=N.useContext(jn),a=o[o.length-1],s=a?a.params:{};a&&a.pathname;let u=a?a.pathnameBase:"/";a&&a.route;let l=Yr(),c;if(t){var f;let y=typeof t=="string"?tr(t):t;u==="/"||(f=y.pathname)!=null&&f.startsWith(u)||pe(!1),c=y}else c=l;let d=c.pathname||"/",h=d;if(u!=="/"){let y=u.replace(/^\//,"").split("/");h="/"+d.replace(/^\//,"").split("/").slice(y.length).join("/")}let g=Ub(e,{pathname:h}),v=ST(g&&g.map(y=>Object.assign({},y,{params:Object.assign({},s,y.params),pathname:Sn([u,i.encodeLocation?i.encodeLocation(y.pathname).pathname:y.pathname]),pathnameBase:y.pathnameBase==="/"?u:Sn([u,i.encodeLocation?i.encodeLocation(y.pathnameBase).pathname:y.pathnameBase])})),o,n,r);return t&&v?N.createElement(us.Provider,{value:{location:Xi({pathname:"/",search:"",hash:"",state:null,key:"default"},c),navigationType:dn.Pop}},v):v}function yT(){let e=bT(),t=fT(e)?e.status+" "+e.statusText:e instanceof Error?e.message:JSON.stringify(e),n=e instanceof Error?e.stack:null,i={padding:"0.5rem",backgroundColor:"rgba(200,200,200, 0.5)"};return N.createElement(N.Fragment,null,N.createElement("h2",null,"Unexpected Application Error!"),N.createElement("h3",{style:{fontStyle:"italic"}},t),n?N.createElement("pre",{style:i},n):null,null)}const _T=N.createElement(yT,null);class xT extends N.Component{constructor(t){super(t),this.state={location:t.location,revalidation:t.revalidation,error:t.error}}static getDerivedStateFromError(t){return{error:t}}static getDerivedStateFromProps(t,n){return n.location!==t.location||n.revalidation!=="idle"&&t.revalidation==="idle"?{error:t.error,location:t.location,revalidation:t.revalidation}:{error:t.error!==void 0?t.error:n.error,location:n.location,revalidation:t.revalidation||n.revalidation}}componentDidCatch(t,n){console.error("React Router caught the following error during render",t,n)}render(){return this.state.error!==void 0?N.createElement(jn.Provider,{value:this.props.routeContext},N.createElement(nE.Provider,{value:this.state.error,children:this.props.component})):this.props.children}}function wT(e){let{routeContext:t,match:n,children:r}=e,i=N.useContext(cv);return i&&i.static&&i.staticContext&&(n.route.errorElement||n.route.ErrorBoundary)&&(i.staticContext._deepestRenderedBoundaryId=n.route.id),N.createElement(jn.Provider,{value:t},r)}function ST(e,t,n,r){var i;if(t===void 0&&(t=[]),n===void 0&&(n=null),r===void 0&&(r=null),e==null){var o;if(!n)return null;if(n.errors)e=n.matches;else if((o=r)!=null&&o.v7_partialHydration&&t.length===0&&!n.initialized&&n.matches.length>0)e=n.matches;else return null}let a=e,s=(i=n)==null?void 0:i.errors;if(s!=null){let c=a.findIndex(f=>f.route.id&&(s==null?void 0:s[f.route.id])!==void 0);c>=0||pe(!1),a=a.slice(0,Math.min(a.length,c+1))}let u=!1,l=-1;if(n&&r&&r.v7_partialHydration)for(let c=0;c<a.length;c++){let f=a[c];if((f.route.HydrateFallback||f.route.hydrateFallbackElement)&&(l=c),f.route.id){let{loaderData:d,errors:h}=n,g=f.route.loader&&d[f.route.id]===void 0&&(!h||h[f.route.id]===void 0);if(f.route.lazy||g){u=!0,l>=0?a=a.slice(0,l+1):a=[a[0]];break}}}return a.reduceRight((c,f,d)=>{let h,g=!1,v=null,y=null;n&&(h=s&&f.route.id?s[f.route.id]:void 0,v=f.route.errorElement||_T,u&&(l<0&&d===0?(RT("route-fallback"),g=!0,y=null):l===d&&(g=!0,y=f.route.hydrateFallbackElement||null)));let p=t.concat(a.slice(0,d+1)),m=()=>{let _;return h?_=v:g?_=y:f.route.Component?_=N.createElement(f.route.Component,null):f.route.element?_=f.route.element:_=c,N.createElement(wT,{match:f,routeContext:{outlet:c,matches:p,isDataRoute:n!=null},children:_})};return n&&(f.route.ErrorBoundary||f.route.errorElement||d===0)?N.createElement(xT,{location:n.location,revalidation:n.revalidation,component:v,error:h,children:m(),routeContext:{outlet:null,matches:p,isDataRoute:!0}}):m()},null)}var aE=function(e){return e.UseBlocker="useBlocker",e.UseRevalidator="useRevalidator",e.UseNavigateStable="useNavigate",e}(aE||{}),sE=function(e){return e.UseBlocker="useBlocker",e.UseLoaderData="useLoaderData",e.UseActionData="useActionData",e.UseRouteError="useRouteError",e.UseNavigation="useNavigation",e.UseRouteLoaderData="useRouteLoaderData",e.UseMatches="useMatches",e.UseRevalidator="useRevalidator",e.UseNavigateStable="useNavigate",e.UseRouteId="useRouteId",e}(sE||{});function ET(e){let t=N.useContext(cv);return t||pe(!1),t}function CT(e){let t=N.useContext(hT);return t||pe(!1),t}function kT(e){let t=N.useContext(jn);return t||pe(!1),t}function uE(e){let t=kT(),n=t.matches[t.matches.length-1];return n.route.id||pe(!1),n.route.id}function bT(){var e;let t=N.useContext(nE),n=CT(),r=uE();return t!==void 0?t:(e=n.errors)==null?void 0:e[r]}function TT(){let{router:e}=ET(aE.UseNavigateStable),t=uE(sE.UseNavigateStable),n=N.useRef(!1);return rE(()=>{n.current=!0}),N.useCallback(function(i,o){o===void 0&&(o={}),n.current&&(typeof i=="number"?e.navigate(i):e.navigate(i,Xi({fromRouteId:t},o)))},[e,t])}const sm={};function RT(e,t,n){sm[e]||(sm[e]=!0)}function NT(e,t){e==null||e.v7_startTransition,e==null||e.v7_relativeSplatPath}function IT(e){let{to:t,replace:n,state:r,relative:i}=e;Kr()||pe(!1);let{future:o,static:a}=N.useContext(Pn),{matches:s}=N.useContext(jn),{pathname:u}=Yr(),l=iE(),c=lv(t,uv(s,o.v7_relativeSplatPath),u,i==="path"),f=JSON.stringify(c);return N.useEffect(()=>l(JSON.parse(f),{replace:n,state:r,relative:i}),[l,f,i,n,r]),null}function hr(e){pe(!1)}function PT(e){let{basename:t="/",children:n=null,location:r,navigationType:i=dn.Pop,navigator:o,static:a=!1,future:s}=e;Kr()&&pe(!1);let u=t.replace(/^\/*/,"/"),l=N.useMemo(()=>({basename:u,navigator:o,static:a,future:Xi({v7_relativeSplatPath:!1},s)}),[u,s,o,a]);typeof r=="string"&&(r=tr(r));let{pathname:c="/",search:f="",hash:d="",state:h=null,key:g="default"}=r,v=N.useMemo(()=>{let y=sv(c,u);return y==null?null:{location:{pathname:y,search:f,hash:d,state:h,key:g},navigationType:i}},[u,c,f,d,h,g,i]);return v==null?null:N.createElement(Pn.Provider,{value:l},N.createElement(us.Provider,{children:n,value:v}))}function jT(e){let{children:t,location:n}=e;return gT(Xh(t),n)}new Promise(()=>{});function Xh(e,t){t===void 0&&(t=[]);let n=[];return N.Children.forEach(e,(r,i)=>{if(!N.isValidElement(r))return;let o=[...t,i];if(r.type===N.Fragment){n.push.apply(n,Xh(r.props.children,o));return}r.type!==hr&&pe(!1),!r.props.index||!r.props.children||pe(!1);let a={id:r.props.id||o.join("-"),caseSensitive:r.props.caseSensitive,element:r.props.element,Component:r.props.Component,index:r.props.index,path:r.props.path,loader:r.props.loader,action:r.props.action,errorElement:r.props.errorElement,ErrorBoundary:r.props.ErrorBoundary,hasErrorBoundary:r.props.ErrorBoundary!=null||r.props.errorElement!=null,shouldRevalidate:r.props.shouldRevalidate,handle:r.props.handle,lazy:r.props.lazy};r.props.children&&(a.children=Xh(r.props.children,o)),n.push(a)}),n}/** 67 - * React Router DOM v6.30.2 68 - * 69 - * Copyright (c) Remix Software Inc. 70 - * 71 - * This source code is licensed under the MIT license found in the 72 - * LICENSE.md file in the root directory of this source tree. 73 - * 74 - * @license MIT 75 - */function Zh(){return Zh=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},Zh.apply(this,arguments)}function qT(e,t){if(e==null)return{};var n={},r=Object.keys(e),i,o;for(o=0;o<r.length;o++)i=r[o],!(t.indexOf(i)>=0)&&(n[i]=e[i]);return n}function AT(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function MT(e,t){return e.button===0&&(!t||t==="_self")&&!AT(e)}const LT=["onClick","relative","reloadDocument","replace","state","target","to","preventScrollReset","viewTransition"],OT="6";try{window.__reactRouterVersion=OT}catch{}const zT="startTransition",um=Rk[zT];function FT(e){let{basename:t,children:n,future:r,window:i}=e,o=N.useRef();o.current==null&&(o.current=Db({window:i,v5Compat:!0}));let a=o.current,[s,u]=N.useState({action:a.action,location:a.location}),{v7_startTransition:l}=r||{},c=N.useCallback(f=>{l&&um?um(()=>u(f)):u(f)},[u,l]);return N.useLayoutEffect(()=>a.listen(c),[a,c]),N.useEffect(()=>NT(r),[r]),N.createElement(PT,{basename:t,children:n,location:s.location,navigationType:s.action,navigator:a,future:r})}const DT=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u",$T=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,BT=N.forwardRef(function(t,n){let{onClick:r,relative:i,reloadDocument:o,replace:a,state:s,target:u,to:l,preventScrollReset:c,viewTransition:f}=t,d=qT(t,LT),{basename:h}=N.useContext(Pn),g,v=!1;if(typeof l=="string"&&$T.test(l)&&(g=l,DT))try{let _=new URL(window.location.href),x=l.startsWith("//")?new URL(_.protocol+l):new URL(l),S=sv(x.pathname,h);x.origin===_.origin&&S!=null?l=S+x.search+x.hash:v=!0}catch{}let y=pT(l,{relative:i}),p=UT(l,{replace:a,state:s,target:u,preventScrollReset:c,relative:i,viewTransition:f});function m(_){r&&r(_),_.defaultPrevented||p(_)}return N.createElement("a",Zh({},d,{href:g||y,onClick:v||o?r:m,ref:n,target:u}))});var lm;(function(e){e.UseScrollRestoration="useScrollRestoration",e.UseSubmit="useSubmit",e.UseSubmitFetcher="useSubmitFetcher",e.UseFetcher="useFetcher",e.useViewTransitionState="useViewTransitionState"})(lm||(lm={}));var cm;(function(e){e.UseFetcher="useFetcher",e.UseFetchers="useFetchers",e.UseScrollRestoration="useScrollRestoration"})(cm||(cm={}));function UT(e,t){let{target:n,replace:r,state:i,preventScrollReset:o,relative:a,viewTransition:s}=t===void 0?{}:t,u=iE(),l=Yr(),c=oE(e,{relative:a});return N.useCallback(f=>{if(MT(f,n)){f.preventDefault();let d=r!==void 0?r:qa(l)===qa(c);u(e,{replace:d,state:i,preventScrollReset:o,relative:a,viewTransition:s})}},[l,u,c,r,i,n,e,o,a,s])}function HT(e={}){const{graphUrl:t=VT(),gitHistoryUrl:n,enableSSE:r=!1,sseUrl:i="/api/events",pollInterval:o=0}=e,[a,s]=N.useState(null),[u,l]=N.useState([]),[c,f]=N.useState(!0),[d,h]=N.useState(null),[g,v]=N.useState(null),y=N.useCallback(async()=>{try{const _=await fetch(t);if(!_.ok)throw new Error(`Failed to fetch graph: ${_.status} ${_.statusText}`);const x=await _.json(),S=x.data??x;if(x.ok===!1&&x.error)throw new Error(x.error);s(S),v(new Date),h(null)}catch(_){const x=_ instanceof Error?_.message:"Failed to load graph data";h(x),console.error("Graph fetch error:",_)}},[t]),p=N.useCallback(async()=>{if(n)try{const _=await fetch(n);if(_.ok){const x=await _.json();l(x)}}catch(_){console.warn("Could not load git history:",_)}},[n]),m=N.useCallback(async()=>{f(!0),await Promise.all([y(),p()]),f(!1)},[y,p]);return N.useEffect(()=>{let _=!0;return(async()=>{f(!0),await Promise.all([y(),p()]),_&&f(!1)})(),()=>{_=!1}},[y,p]),N.useEffect(()=>{if(!r)return;let _=null,x=null;const S=()=>{try{_=new EventSource(i),_.onmessage=E=>{(E.data==="refresh"||E.data==="update")&&y()},_.onerror=()=>{_==null||_.close(),x=setTimeout(S,5e3)},_.onopen=()=>{console.log("SSE connected for live updates")}}catch(E){console.warn("SSE not available:",E)}};return S(),()=>{_==null||_.close(),x&&clearTimeout(x)}},[r,i,y]),N.useEffect(()=>{if(o<=0)return;const _=setInterval(()=>{y()},o);return()=>clearInterval(_)},[o,y]),{graphData:a,gitHistory:u,loading:c,error:d,lastUpdated:g,refresh:m}}function VT(){return"./graph-data.json"}const fm=["goal","decision","option","action","outcome","observation"];function fv(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}function $r(e){const t=fv(e.metadata_json);return(t==null?void 0:t.confidence)??null}function bn(e){const t=fv(e.metadata_json);return(t==null?void 0:t.commit)??null}function lE(e){const t=fv(e.metadata_json);return(t==null?void 0:t.branch)??null}function GT(e){const t=new Set;for(const n of e){const r=lE(n);r&&t.add(r)}return Array.from(t).sort()}function WT(e){return e?e.slice(0,7):null}function KT(e){return e===null?null:e>=70?"high":e>=40?"med":"low"}function YT(e,t="notactuallytreyanastasio/losselot"){return`https://github.com/${t}/commit/${e}`}function ut(e,t){return e?e.length>t?e.substring(0,t)+"...":e:""}function QT(e,t){const n=new Date(t).getTime()-new Date(e).getTime(),r=Math.floor(n/6e4);if(r<60)return`${r}m`;const i=Math.floor(r/60);return i<24?`${i}h ${r%60}m`:`${Math.floor(i/24)}d ${i%24}h`}const dm=4*60*60*1e3;function cE(e,t){const n=new Map,r=new Map;return e.forEach(i=>{n.set(i.id,[]),r.set(i.id,[])}),t.forEach(i=>{var o,a;(o=n.get(i.from_node_id))==null||o.push({to:i.to_node_id,edge:i}),(a=r.get(i.to_node_id))==null||a.push({from:i.from_node_id,edge:i})}),{outgoing:n,incoming:r}}function XT(e){const{nodes:t,edges:n}=e,{outgoing:r,incoming:i}=cE(t,n),o=new Set,a=[],s=t.filter(l=>{var c;return l.node_type==="goal"||(((c=i.get(l.id))==null?void 0:c.length)??0)===0}).sort((l,c)=>l.node_type==="goal"&&c.node_type!=="goal"?-1:c.node_type==="goal"&&l.node_type!=="goal"?1:new Date(l.created_at).getTime()-new Date(c.created_at).getTime());function u(l){var d;if(o.has(l))return null;const c={root:null,nodes:[],edges:[]},f=[l];for(;f.length>0;){const h=f.shift();if(o.has(h))continue;o.add(h);const g=t.find(v=>v.id===h);g&&(c.nodes.push(g),c.root||(c.root=g)),(d=r.get(h))==null||d.forEach(({to:v,edge:y})=>{o.has(v)||(f.push(v),c.edges.push(y))})}return c.nodes.sort((h,g)=>new Date(h.created_at).getTime()-new Date(g.created_at).getTime()),c.nodes.length>0?c:null}return s.forEach(l=>{const c=u(l.id);c&&a.push(c)}),t.forEach(l=>{if(!o.has(l.id)){const c=u(l.id);c&&a.push(c)}}),a.sort((l,c)=>new Date(c.nodes[0].created_at).getTime()-new Date(l.nodes[0].created_at).getTime()),a}function ZT(e,t){const n=[...e].sort((o,a)=>new Date(o.created_at).getTime()-new Date(a.created_at).getTime()),r=[];let i=null;return n.forEach(o=>{const a=new Date(o.created_at).getTime();!i||a-i.endTime>dm?(i={startTime:a,endTime:a,nodes:[o],chains:[]},r.push(i)):(i.endTime=a,i.nodes.push(o))}),t.forEach(o=>{const a=new Date(o.nodes[0].created_at).getTime(),s=r.find(u=>a>=u.startTime&&a<=u.endTime+dm);s&&s.chains.push(o)}),r.reverse(),r}function JT(e,t){const{nodes:n,edges:r}=t,i=[],o=new Set;let a=e;for(;a!==null&&!o.has(a);){o.add(a);const s=n.find(l=>l.id===a);s&&i.unshift(s);const u=r.find(l=>l.to_node_id===a);a=u?u.from_node_id:null}return i}function eR(e,t){var s;const{nodes:n,edges:r}=t,{outgoing:i}=cE(n,r),o=new Set,a=[e];for(;a.length>0;){const u=a.shift();o.has(u)||(o.add(u),(s=i.get(u))==null||s.forEach(({to:l})=>{o.has(l)||a.push(l)}))}return o}function tR(e,t){const n=[],r=new Map(t.map(o=>[o.hash,o])),i=new Map(t.map(o=>[o.short_hash,o]));return e.forEach(o=>{const a=bn(o),s=[];if(a){const u=r.get(a)||i.get(a.slice(0,7));u&&s.push(u)}n.push({type:"node",timestamp:new Date(o.created_at),node:o,linkedCommits:s})}),t.forEach(o=>{const a=e.filter(s=>{const u=bn(s);return u===o.hash||(u==null?void 0:u.slice(0,7))===o.short_hash});n.push({type:"commit",timestamp:new Date(o.date),commit:o,linkedNodes:a})}),n.sort((o,a)=>a.timestamp.getTime()-o.timestamp.getTime()),n}function nR(e,t,n){const r={};let i=0;return e.nodes.forEach(o=>{r[o.node_type]=(r[o.node_type]||0)+1,bn(o)&&i++}),{nodeCount:e.nodes.length,edgeCount:e.edges.length,chainCount:t.length,sessionCount:n.length,linkedCommitCount:i,nodesByType:r}}function rR(e){return N.useMemo(()=>{if(!e)return{chains:[],sessions:[],stats:{nodeCount:0,edgeCount:0,chainCount:0,sessionCount:0,linkedCommitCount:0,nodesByType:{}}};const t=XT(e),n=ZT(e.nodes,t),r=nR(e,t,n);return{chains:t,sessions:n,stats:r}},[e])}const iR=[{id:"chains",label:"Chains",path:"/"},{id:"timeline",label:"Timeline",path:"/timeline"},{id:"graph",label:"Graph",path:"/graph"},{id:"dag",label:"DAG",path:"/dag"}],oR=({children:e,stats:t,lastUpdated:n,branches:r,selectedBranch:i,onBranchChange:o})=>{const a=Yr(),u=(()=>{const l=a.pathname;return l==="/timeline"?"timeline":l==="/graph"?"graph":l==="/dag"?"dag":"chains"})();return w.jsxs("div",{style:K.container,children:[w.jsx("header",{style:K.header,children:w.jsxs("div",{style:K.headerContent,children:[w.jsxs("div",{children:[w.jsx("h1",{style:K.title,children:"Deciduous"}),w.jsx("p",{style:K.subtitle,children:"Decision Graph Viewer"})]}),w.jsx("nav",{style:K.nav,children:iR.map(l=>w.jsx(BT,{to:l.path,style:{...K.tab,...u===l.id?K.tabActive:{}},children:l.label},l.id))}),w.jsx("div",{style:K.navLinks,children:w.jsx("a",{href:"https://github.com/notactuallytreyanastasio/losselot",target:"_blank",rel:"noopener noreferrer",style:K.link,children:"GitHub"})})]})}),t&&w.jsxs("div",{style:K.statsBar,children:[w.jsxs("div",{style:K.stat,children:[w.jsx("div",{style:K.statNum,children:t.nodeCount}),w.jsx("div",{style:K.statLabel,children:"Nodes"})]}),w.jsxs("div",{style:K.stat,children:[w.jsx("div",{style:K.statNum,children:t.edgeCount}),w.jsx("div",{style:K.statLabel,children:"Edges"})]}),w.jsxs("div",{style:K.stat,children:[w.jsx("div",{style:K.statNum,children:t.chainCount}),w.jsx("div",{style:K.statLabel,children:"Chains"})]}),w.jsxs("div",{style:K.stat,children:[w.jsx("div",{style:K.statNum,children:t.sessionCount}),w.jsx("div",{style:K.statLabel,children:"Sessions"})]}),t.linkedCommitCount>0&&w.jsxs("div",{style:K.stat,children:[w.jsx("div",{style:K.statNum,children:t.linkedCommitCount}),w.jsx("div",{style:K.statLabel,children:"Commits"})]}),r&&r.length>0&&w.jsx("div",{style:{...K.stat,marginLeft:"auto"},children:w.jsxs("select",{value:i||"",onChange:l=>o==null?void 0:o(l.target.value||null),style:K.branchSelect,children:[w.jsx("option",{value:"",children:"All branches"}),r.map(l=>w.jsx("option",{value:l,children:l},l))]})}),n&&w.jsx("div",{style:{...K.stat,marginLeft:r!=null&&r.length?"10px":"auto"},children:w.jsxs("div",{style:{...K.statLabel,fontSize:"10px"},children:["Updated ",n.toLocaleTimeString()]})})]}),w.jsx("main",{style:K.main,children:e})]})},K={container:{minHeight:"100vh",backgroundColor:"#1a1a2e",color:"#eee",fontFamily:"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif"},header:{backgroundColor:"#16213e",borderBottom:"1px solid #0f3460",padding:"0 20px"},headerContent:{display:"flex",alignItems:"center",gap:"30px",maxWidth:"1800px",margin:"0 auto",padding:"15px 0"},title:{fontSize:"20px",margin:0,color:"#00d9ff"},subtitle:{fontSize:"12px",color:"#888",margin:"4px 0 0 0"},nav:{display:"flex",gap:"4px",flex:1},tab:{padding:"10px 20px",fontSize:"13px",color:"#888",textDecoration:"none",borderRadius:"6px 6px 0 0",backgroundColor:"transparent",transition:"all 0.2s"},tabActive:{backgroundColor:"#1a1a2e",color:"#00d9ff"},navLinks:{display:"flex",gap:"15px"},link:{color:"#888",textDecoration:"none",fontSize:"13px"},statsBar:{display:"flex",gap:"20px",padding:"12px 20px",backgroundColor:"#16213e",margin:"15px",borderRadius:"8px",maxWidth:"1800px",marginLeft:"auto",marginRight:"auto"},stat:{textAlign:"center",minWidth:"60px"},statNum:{fontSize:"20px",fontWeight:"bold",color:"#00d9ff"},statLabel:{fontSize:"10px",color:"#888",textTransform:"uppercase"},branchSelect:{backgroundColor:"#1a1a2e",color:"#00d9ff",border:"1px solid #0f3460",borderRadius:"4px",padding:"6px 10px",fontSize:"12px",cursor:"pointer",minWidth:"120px"},main:{height:"calc(100vh - 140px)",maxWidth:"1800px",margin:"0 auto",padding:"0 15px"}},dv={goal:"#22c55e",decision:"#eab308",option:"#06b6d4",action:"#ef4444",outcome:"#a855f7",observation:"#6b7280"};function It(e){return dv[e]||"#6b7280"}const aR={leads_to:"#3b82f6",requires:"#8b5cf6",chosen:"#22c55e",rejected:"#ef4444",blocks:"#f97316",enables:"#06b6d4"};function sR(e){return aR[e]||"#6b7280"}const uR={high:{bg:"#22c55e33",text:"#4ade80"},med:{bg:"#eab30833",text:"#fbbf24"},low:{bg:"#ef444433",text:"#f87171"}};function lR(e){return e?uR[e]:null}const Ge=({type:e,size:t="md"})=>{const n=It(e),r=["goal","decision","option"].includes(e),i={fontSize:t==="sm"?"9px":"10px",textTransform:"uppercase",padding:t==="sm"?"2px 5px":"2px 6px",borderRadius:"3px",display:"inline-block",backgroundColor:n,color:r?"#000":"#fff",fontWeight:500};return w.jsx("span",{style:i,children:e})},uo=({confidence:e})=>{if(e==null)return null;const t=KT(e),n=lR(t);if(!n)return null;const r={fontSize:"10px",padding:"2px 6px",borderRadius:"10px",fontWeight:600,backgroundColor:n.bg,color:n.text};return w.jsxs("span",{style:r,children:[e,"%"]})},Br=({commit:e,repo:t="notactuallytreyanastasio/losselot"})=>{if(!e)return null;const n=WT(e),r=YT(e,t),i={fontSize:"10px",padding:"2px 6px",borderRadius:"4px",fontWeight:500,fontFamily:"monospace",backgroundColor:"#3b82f633",color:"#60a5fa",textDecoration:"none",transition:"all 0.2s"};return w.jsx("a",{href:r,target:"_blank",rel:"noopener noreferrer",style:i,title:`View commit ${n}`,onMouseOver:o=>{o.currentTarget.style.backgroundColor="#3b82f655",o.currentTarget.style.color="#93c5fd"},onMouseOut:o=>{o.currentTarget.style.backgroundColor="#3b82f633",o.currentTarget.style.color="#60a5fa"},children:n})},Aa=({type:e})=>{const t=e==="chosen",r={fontSize:"10px",padding:"2px 6px",borderRadius:"3px",backgroundColor:t?"#22c55e":e==="rejected"?"#ef4444":"#333",color:t?"#000":"#fff"};return w.jsx("span",{style:r,children:e})},cR=({node:e,repo:t})=>{const n=$r(e),r=bn(e);return w.jsxs("span",{style:{display:"inline-flex",gap:"6px",alignItems:"center"},children:[w.jsx(Ge,{type:e.node_type}),w.jsx(uo,{confidence:n}),w.jsx(Br,{commit:r,repo:t})]})},fR=({status:e})=>{const t={pending:{bg:"#6b728033",text:"#9ca3af"},active:{bg:"#3b82f633",text:"#60a5fa"},completed:{bg:"#22c55e33",text:"#4ade80"},rejected:{bg:"#ef444433",text:"#f87171"}},n=t[e]||t.pending,r={fontSize:"10px",padding:"2px 6px",borderRadius:"10px",backgroundColor:n.bg,color:n.text};return w.jsx("span",{style:r,children:e})},fE=({node:e,graphData:t,onSelectNode:n,onClose:r,repo:i="notactuallytreyanastasio/losselot"})=>{if(!e)return w.jsx("div",{style:ie.panel,children:w.jsxs("div",{style:ie.empty,children:[w.jsxs("svg",{width:"64",height:"64",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1",style:{opacity:.3},children:[w.jsx("circle",{cx:"12",cy:"12",r:"10"}),w.jsx("path",{d:"M12 6v6l4 2"})]}),w.jsx("p",{style:{marginTop:"20px"},children:"Select a node to see details"})]})});const o=t.edges.filter(u=>u.to_node_id===e.id),a=t.edges.filter(u=>u.from_node_id===e.id),s=u=>{const l=t.nodes.find(c=>c.id===u);return(l==null?void 0:l.title)||"Unknown"};return w.jsxs("div",{style:ie.panel,children:[r&&w.jsx("button",{onClick:r,style:ie.closeButton,children:"×"}),w.jsxs("div",{style:ie.header,children:[w.jsx(cR,{node:e,repo:i}),w.jsx("h2",{style:ie.title,children:e.title}),w.jsxs("div",{style:ie.meta,children:[w.jsxs("span",{children:["ID: ",e.id]}),w.jsx("span",{children:w.jsx(fR,{status:e.status})}),w.jsxs("span",{children:["Created: ",new Date(e.created_at).toLocaleDateString()]})]})]}),e.description&&w.jsx("div",{style:ie.description,children:e.description}),o.length>0&&w.jsxs("div",{style:ie.section,children:[w.jsxs("h3",{style:ie.sectionTitle,children:["Incoming (",o.length,")"]}),o.map(u=>w.jsxs("div",{style:ie.connection,onClick:()=>n(u.from_node_id),children:[w.jsxs("div",{style:ie.connectionHeader,children:[w.jsx(Aa,{type:u.edge_type}),w.jsx("span",{style:ie.arrow,children:"←"}),w.jsx("span",{style:ie.connectionTitle,children:s(u.from_node_id)})]}),u.rationale&&w.jsx("div",{style:ie.connectionRationale,children:u.rationale})]},u.id))]}),a.length>0&&w.jsxs("div",{style:ie.section,children:[w.jsxs("h3",{style:ie.sectionTitle,children:["Outgoing (",a.length,")"]}),a.map(u=>w.jsxs("div",{style:ie.connection,onClick:()=>n(u.to_node_id),children:[w.jsxs("div",{style:ie.connectionHeader,children:[w.jsx(Aa,{type:u.edge_type}),w.jsx("span",{style:ie.arrow,children:"→"}),w.jsx("span",{style:ie.connectionTitle,children:s(u.to_node_id)})]}),u.rationale&&w.jsx("div",{style:ie.connectionRationale,children:u.rationale})]},u.id))]}),w.jsxs("div",{style:ie.navLinks,children:[w.jsx("a",{href:"../decision-graph",style:ie.link,children:"Learn about the graph →"}),w.jsx("a",{href:"../claude-tooling",style:ie.link,children:"See the tooling →"})]})]})},ie={panel:{padding:"25px",height:"100%",overflowY:"auto",backgroundColor:"#1a1a2e",position:"relative"},empty:{textAlign:"center",color:"#666",paddingTop:"80px"},closeButton:{position:"absolute",top:"15px",right:"15px",width:"30px",height:"30px",border:"none",background:"#333",color:"#fff",borderRadius:"4px",fontSize:"20px",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center"},header:{marginBottom:"20px"},title:{fontSize:"24px",margin:"12px 0 8px 0",color:"#eee"},meta:{display:"flex",gap:"20px",fontSize:"14px",color:"#888",flexWrap:"wrap"},description:{backgroundColor:"#16213e",padding:"20px",borderRadius:"8px",marginBottom:"20px",lineHeight:1.6,color:"#ddd"},section:{marginTop:"20px"},sectionTitle:{fontSize:"16px",marginBottom:"12px",color:"#888"},connection:{padding:"12px",backgroundColor:"#16213e",borderRadius:"6px",marginBottom:"8px",cursor:"pointer",transition:"background-color 0.2s"},connectionHeader:{display:"flex",alignItems:"center",gap:"8px",flexWrap:"wrap"},connectionTitle:{color:"#eee",fontSize:"13px",flex:1,minWidth:0},connectionRationale:{color:"#888",fontSize:"12px",marginTop:"8px",paddingTop:"8px",borderTop:"1px solid #0f3460",lineHeight:1.4},arrow:{color:"#666",flexShrink:0},navLinks:{marginTop:"20px",paddingTop:"20px",borderTop:"1px solid #333"},link:{color:"#00d9ff",textDecoration:"none",marginRight:"20px",fontSize:"13px"}},dR=({graphData:e,chains:t,sessions:n})=>{const[r,i]=N.useState("chains"),[o,a]=N.useState(null),[s,u]=N.useState(null),l=o!==null?t[o]:null,c=N.useMemo(()=>{if(!l)return new Map;const g=new Map;return l.edges.forEach(v=>g.set(v.to_node_id,v)),g},[l]),f=g=>{a(g),u(null)},d=g=>{const v=e.nodes.find(y=>y.id===g);v&&(u(v),a(null))},h=g=>{const v=e.nodes.find(y=>y.id===g);v&&u(v)};return w.jsxs("div",{style:D.container,children:[w.jsxs("div",{style:D.sidebar,children:[w.jsx("div",{style:D.viewToggle,children:["chains","sessions","all"].map(g=>w.jsx("button",{onClick:()=>i(g),style:{...D.viewBtn,...r===g?D.viewBtnActive:{}},children:g==="all"?"All Nodes":g.charAt(0).toUpperCase()+g.slice(1)},g))}),w.jsxs("div",{style:D.sidebarContent,children:[r==="chains"&&w.jsx(hR,{chains:t,selectedIndex:o,onSelect:f}),r==="sessions"&&w.jsx(pR,{sessions:n,chains:t,selectedChainIndex:o,onSelectChain:f}),r==="all"&&w.jsx(vR,{nodes:e.nodes,selectedNode:s,onSelect:d})]})]}),w.jsx("div",{style:D.detailPanel,children:l&&!s?w.jsx(gR,{chain:l,edgeMap:c,selectedNode:s,onSelectNode:h}):w.jsx(fE,{node:s,graphData:e,onSelectNode:d})})]})},hR=({chains:e,selectedIndex:t,onSelect:n})=>w.jsx("div",{style:D.nodeList,children:e.map((r,i)=>{const o=[...new Set(r.nodes.map(s=>s.node_type))],a=t===i;return w.jsxs("div",{onClick:()=>n(i),style:{...D.chainItem,...a?D.chainItemSelected:{}},children:[w.jsxs("div",{style:D.chainSummary,children:[w.jsx(Ge,{type:r.root.node_type,size:"sm"}),w.jsx("span",{style:D.chainTitle,children:ut(r.root.title,40)})]}),w.jsxs("div",{style:D.chainStats,children:[r.nodes.length," nodes · ",r.edges.length," edges"]}),w.jsx("div",{style:D.chainTypes,children:o.map(s=>w.jsx("span",{style:{...D.chainTypeDot,backgroundColor:It(s)},title:s},s))})]},i)})}),pR=({sessions:e,chains:t,selectedChainIndex:n,onSelectChain:r})=>{const[i,o]=N.useState(new Set),a=s=>{o(u=>{const l=new Set(u);return l.has(s)?l.delete(s):l.add(s),l})};return w.jsx("div",{children:e.map((s,u)=>{const l=new Date(s.startTime),c=l.toLocaleDateString("en-US",{month:"short",day:"numeric"}),f=l.toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit"}),d=i.has(u);return w.jsxs("div",{style:D.sessionGroup,children:[w.jsxs("div",{onClick:()=>a(u),style:{...D.sessionHeader,...d?D.sessionHeaderExpanded:{}},children:[w.jsx("span",{style:{...D.sessionToggle,transform:d?"rotate(90deg)":"none"},children:"▶"}),w.jsxs("span",{style:D.sessionTitle,children:[c," @ ",f]}),w.jsxs("span",{style:D.sessionCount,children:[s.nodes.length," nodes"]})]}),d&&w.jsx("div",{style:D.chainList,children:s.chains.length>0?s.chains.map(h=>{const g=t.indexOf(h),v=[...new Set(h.nodes.map(y=>y.node_type))];return w.jsxs("div",{onClick:()=>r(g),style:{...D.chainItem,...n===g?D.chainItemSelected:{}},children:[w.jsxs("div",{style:D.chainSummary,children:[w.jsx(Ge,{type:h.root.node_type,size:"sm"}),w.jsx("span",{style:D.chainTitle,children:ut(h.root.title,35)})]}),w.jsxs("div",{style:D.chainStats,children:[h.nodes.length," nodes · ",h.edges.length," edges"]}),w.jsx("div",{style:D.chainTypes,children:v.map(y=>w.jsx("span",{style:{...D.chainTypeDot,backgroundColor:It(y)},title:y},y))})]},g)}):w.jsx("div",{style:{color:"#666",fontSize:"12px",padding:"10px"},children:"No complete chains in this session"})})]},u)})})},vR=({nodes:e,selectedNode:t,onSelect:n})=>w.jsx("div",{style:D.nodeList,children:e.map(r=>w.jsxs("div",{onClick:()=>n(r.id),style:{...D.nodeItem,...(t==null?void 0:t.id)===r.id?D.nodeItemSelected:{}},children:[w.jsx(Ge,{type:r.node_type}),w.jsx("div",{style:D.nodeTitle,children:r.title})]},r.id))}),gR=({chain:e,edgeMap:t,selectedNode:n,onSelectNode:r})=>{const i=QT(e.nodes[0].created_at,e.nodes[e.nodes.length-1].created_at);return w.jsxs("div",{style:D.chainFlow,children:[w.jsxs("div",{style:D.chainFlowHeader,children:[w.jsx(Ge,{type:e.root.node_type}),w.jsx("h2",{style:D.chainFlowTitle,children:e.root.title}),w.jsxs("div",{style:D.chainFlowMeta,children:[e.nodes.length," nodes · ",e.edges.length," connections · ",i]})]}),w.jsx("div",{style:D.flowTimeline,children:e.nodes.map(o=>{const a=t.get(o.id),s=(n==null?void 0:n.id)===o.id,u=new Date(o.created_at).toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit"}),l=$r(o),c=bn(o);return w.jsxs(gp.Fragment,{children:[(a==null?void 0:a.rationale)&&w.jsxs("div",{style:D.flowEdgeLabel,children:["↳ ",a.rationale]}),w.jsxs("div",{onClick:()=>r(o.id),style:{...D.flowNode,borderColor:s?"#00d9ff":"#0f3460",backgroundColor:s?"#1c2844":"#16213e"},children:[w.jsx("div",{style:{...D.flowNodeMarker,backgroundColor:It(o.node_type),borderColor:It(o.node_type)}}),w.jsxs("div",{style:D.flowNodeHeader,children:[w.jsx(Ge,{type:o.node_type,size:"sm"}),w.jsx(uo,{confidence:l}),w.jsx(Br,{commit:c}),w.jsx("span",{style:D.flowNodeTitle,children:o.title}),w.jsx("span",{style:D.flowNodeTime,children:u})]}),o.description&&w.jsx("div",{style:D.flowNodeDesc,children:o.description})]})]},o.id)})}),w.jsxs("div",{style:D.navLinks,children:[w.jsx("a",{href:"../decision-graph",style:D.link,children:"Learn about the graph →"}),w.jsx("a",{href:"../claude-tooling",style:D.link,children:"See the tooling →"})]})]})},D={container:{display:"flex",height:"100%",gap:"0"},sidebar:{width:"380px",backgroundColor:"#16213e",borderRight:"1px solid #0f3460",display:"flex",flexDirection:"column",flexShrink:0},viewToggle:{display:"flex",padding:"10px",gap:"5px",borderBottom:"1px solid #0f3460"},viewBtn:{flex:1,padding:"8px",border:"none",backgroundColor:"#1a1a2e",color:"#888",borderRadius:"4px",cursor:"pointer",fontSize:"12px"},viewBtnActive:{backgroundColor:"#0f3460",color:"#00d9ff"},sidebarContent:{flex:1,overflowY:"auto"},nodeList:{padding:"10px"},chainItem:{padding:"10px 12px",margin:"4px 0",backgroundColor:"#252547",borderRadius:"6px",cursor:"pointer",borderLeft:"3px solid transparent"},chainItemSelected:{borderLeftColor:"#00d9ff",backgroundColor:"#2d2d5a"},chainSummary:{display:"flex",alignItems:"center",gap:"8px",marginBottom:"4px"},chainTitle:{fontSize:"13px",flex:1},chainStats:{fontSize:"10px",color:"#666"},chainTypes:{display:"flex",gap:"3px",marginTop:"6px"},chainTypeDot:{width:"8px",height:"8px",borderRadius:"50%"},sessionGroup:{borderBottom:"1px solid #0f3460"},sessionHeader:{padding:"12px 15px",backgroundColor:"#1a1a2e",cursor:"pointer",display:"flex",alignItems:"center",gap:"10px"},sessionHeaderExpanded:{},sessionToggle:{width:"16px",height:"16px",display:"flex",alignItems:"center",justifyContent:"center",color:"#666",transition:"transform 0.2s"},sessionTitle:{flex:1,fontSize:"13px",fontWeight:600},sessionCount:{fontSize:"11px",color:"#666",backgroundColor:"#0f3460",padding:"2px 8px",borderRadius:"10px"},chainList:{padding:"5px 10px 10px"},nodeItem:{padding:"12px",marginBottom:"8px",backgroundColor:"#1a1a2e",borderRadius:"6px",cursor:"pointer",borderLeft:"4px solid transparent"},nodeItemSelected:{borderLeftColor:"#00d9ff",backgroundColor:"#252547"},nodeTitle:{fontSize:"14px",lineHeight:1.4,marginTop:"6px"},detailPanel:{flex:1,overflowY:"auto",backgroundColor:"#1a1a2e"},chainFlow:{maxWidth:"700px",padding:"25px"},chainFlowHeader:{marginBottom:"25px"},chainFlowTitle:{fontSize:"20px",marginTop:"8px",marginBottom:"8px"},chainFlowMeta:{fontSize:"12px",color:"#666"},flowTimeline:{position:"relative",paddingLeft:"30px"},flowEdgeLabel:{fontSize:"11px",color:"#4ade80",margin:"-10px 0 10px 0",paddingLeft:"5px",fontWeight:500},flowNode:{position:"relative",marginBottom:"20px",padding:"15px",backgroundColor:"#16213e",borderRadius:"8px",border:"1px solid #0f3460",cursor:"pointer",transition:"all 0.2s"},flowNodeMarker:{position:"absolute",left:"-26px",top:"20px",width:"12px",height:"12px",borderRadius:"50%",border:"2px solid"},flowNodeHeader:{display:"flex",alignItems:"center",gap:"10px",marginBottom:"8px",flexWrap:"wrap"},flowNodeTitle:{fontSize:"14px",fontWeight:500,flex:1,color:"#eee"},flowNodeTime:{fontSize:"10px",color:"#888"},flowNodeDesc:{fontSize:"12px",color:"#aaa",lineHeight:1.5},navLinks:{marginTop:"20px",paddingTop:"20px",borderTop:"1px solid #333"},link:{color:"#00d9ff",textDecoration:"none",marginRight:"20px",fontSize:"13px"}},mR=({graphData:e,gitHistory:t=[]})=>{const[n,r]=N.useState("all"),[i,o]=N.useState(""),[a,s]=N.useState(null),u=N.useMemo(()=>tR(e.nodes,t),[e.nodes,t]),l=N.useMemo(()=>{let f=u;if(n==="nodes"?f=f.filter(d=>d.type==="node"):n==="commits"?f=f.filter(d=>d.type==="commit"):n==="linked"&&(f=f.filter(d=>d.type==="node"&&d.linkedCommits&&d.linkedCommits.length>0||d.type==="commit"&&d.linkedNodes&&d.linkedNodes.length>0)),i){const d=i.toLowerCase();f=f.filter(h=>{var g;return h.type==="node"?h.node.title.toLowerCase().includes(d)||(((g=h.node.description)==null?void 0:g.toLowerCase().includes(d))??!1):h.commit.message.toLowerCase().includes(d)})}return f},[u,n,i]),c=f=>{const d=e.nodes.find(h=>h.id===f);d&&s(d)};return w.jsxs("div",{style:Z.container,children:[w.jsxs("div",{style:Z.controls,children:[w.jsx("h2",{style:Z.title,children:"Timeline"}),w.jsx("div",{style:Z.filterButtons,children:["all","nodes","commits","linked"].map(f=>w.jsx("button",{onClick:()=>r(f),style:{...Z.filterBtn,...n===f?Z.filterBtnActive:{}},children:f==="all"?"All":f.charAt(0).toUpperCase()+f.slice(1)},f))}),w.jsx("input",{type:"text",placeholder:"Search...",value:i,onChange:f=>o(f.target.value),style:Z.search})]}),w.jsx("div",{style:Z.timelineContainer,children:w.jsxs("div",{style:Z.timeline,children:[l.map((f,d)=>w.jsx(yR,{item:f,onSelectNode:c},d)),l.length===0&&w.jsx("div",{style:Z.empty,children:"No items match your filters"})]})}),w.jsx("div",{style:Z.detailPanel,children:w.jsx(fE,{node:a,graphData:e,onSelectNode:c,onClose:()=>s(null)})})]})},yR=({item:e,onSelectNode:t})=>{const n=e.timestamp.toLocaleDateString("en-US",{month:"short",day:"numeric"}),r=e.timestamp.toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit"});if(e.type==="node"&&e.node){const i=e.node,o=$r(i),a=bn(i);return w.jsxs("div",{style:Z.timelineItem,onClick:()=>t(i.id),children:[w.jsx("div",{style:{...Z.marker,backgroundColor:It(i.node_type)}}),w.jsxs("div",{style:Z.itemContent,children:[w.jsxs("div",{style:Z.itemHeader,children:[w.jsx(Ge,{type:i.node_type,size:"sm"}),w.jsx(uo,{confidence:o}),a&&w.jsx(Br,{commit:a}),w.jsxs("span",{style:Z.itemTime,children:[n," ",r]})]}),w.jsx("div",{style:Z.itemTitle,children:i.title}),i.description&&w.jsx("div",{style:Z.itemDesc,children:ut(i.description,100)}),e.linkedCommits&&e.linkedCommits.length>0&&w.jsxs("div",{style:Z.linked,children:["Linked to ",e.linkedCommits.length," commit(s)"]})]})]})}if(e.type==="commit"&&e.commit){const i=e.commit;return w.jsxs("div",{style:Z.timelineItem,children:[w.jsx("div",{style:{...Z.marker,backgroundColor:"#3b82f6"}}),w.jsxs("div",{style:Z.itemContent,children:[w.jsxs("div",{style:Z.itemHeader,children:[w.jsx("span",{style:Z.commitBadgeSmall,children:"commit"}),w.jsx(Br,{commit:i.hash}),w.jsxs("span",{style:Z.itemTime,children:[n," ",r]})]}),w.jsx("div",{style:Z.itemTitle,children:ut(i.message,60)}),w.jsxs("div",{style:Z.itemMeta,children:["by ",i.author,i.files_changed&&` · ${i.files_changed} files`]}),e.linkedNodes&&e.linkedNodes.length>0&&w.jsxs("div",{style:Z.linked,children:["Linked to ",e.linkedNodes.length," decision(s)"]})]})]})}return null},Z={container:{height:"100%",display:"flex",gap:"0"},controls:{width:"200px",padding:"20px",backgroundColor:"#16213e",borderRight:"1px solid #0f3460",flexShrink:0},title:{fontSize:"16px",margin:"0 0 15px 0",color:"#eee"},filterButtons:{display:"flex",flexDirection:"column",gap:"4px"},filterBtn:{padding:"8px 12px",fontSize:"12px",border:"none",backgroundColor:"#1a1a2e",color:"#888",borderRadius:"4px",cursor:"pointer",textAlign:"left"},filterBtnActive:{backgroundColor:"#0f3460",color:"#00d9ff"},search:{width:"100%",padding:"8px",marginTop:"15px",backgroundColor:"#1a1a2e",border:"1px solid #333",borderRadius:"4px",color:"#eee",fontSize:"12px"},timelineContainer:{flex:2,overflowY:"auto",padding:"20px"},timeline:{maxWidth:"700px",position:"relative",paddingLeft:"30px"},timelineItem:{position:"relative",marginBottom:"15px",padding:"15px",backgroundColor:"#16213e",borderRadius:"8px",border:"1px solid #0f3460",cursor:"pointer",transition:"border-color 0.2s"},marker:{position:"absolute",left:"-24px",top:"20px",width:"12px",height:"12px",borderRadius:"50%",border:"2px solid #1a1a2e"},itemContent:{},itemHeader:{display:"flex",alignItems:"center",gap:"8px",marginBottom:"6px",flexWrap:"wrap"},itemTime:{fontSize:"11px",color:"#666",marginLeft:"auto"},itemTitle:{fontSize:"14px",color:"#eee",marginBottom:"4px"},itemDesc:{fontSize:"12px",color:"#888",lineHeight:1.4},itemMeta:{fontSize:"11px",color:"#666"},linked:{fontSize:"11px",color:"#4ade80",marginTop:"8px"},commitBadgeSmall:{fontSize:"9px",padding:"2px 6px",backgroundColor:"#3b82f633",color:"#60a5fa",borderRadius:"3px",textTransform:"uppercase"},detailPanel:{flex:1,minWidth:"350px",borderLeft:"1px solid #0f3460"},empty:{textAlign:"center",color:"#666",padding:"40px"}};var _R={value:()=>{}};function lo(){for(var e=0,t=arguments.length,n={},r;e<t;++e){if(!(r=arguments[e]+"")||r in n||/[\s.]/.test(r))throw new Error("illegal type: "+r);n[r]=[]}return new oa(n)}function oa(e){this._=e}function xR(e,t){return e.trim().split(/^|\s+/).map(function(n){var r="",i=n.indexOf(".");if(i>=0&&(r=n.slice(i+1),n=n.slice(0,i)),n&&!t.hasOwnProperty(n))throw new Error("unknown type: "+n);return{type:n,name:r}})}oa.prototype=lo.prototype={constructor:oa,on:function(e,t){var n=this._,r=xR(e+"",n),i,o=-1,a=r.length;if(arguments.length<2){for(;++o<a;)if((i=(e=r[o]).type)&&(i=wR(n[i],e.name)))return i;return}if(t!=null&&typeof t!="function")throw new Error("invalid callback: "+t);for(;++o<a;)if(i=(e=r[o]).type)n[i]=hm(n[i],e.name,t);else if(t==null)for(i in n)n[i]=hm(n[i],e.name,null);return this},copy:function(){var e={},t=this._;for(var n in t)e[n]=t[n].slice();return new oa(e)},call:function(e,t){if((i=arguments.length-2)>0)for(var n=new Array(i),r=0,i,o;r<i;++r)n[r]=arguments[r+2];if(!this._.hasOwnProperty(e))throw new Error("unknown type: "+e);for(o=this._[e],r=0,i=o.length;r<i;++r)o[r].value.apply(t,n)},apply:function(e,t,n){if(!this._.hasOwnProperty(e))throw new Error("unknown type: "+e);for(var r=this._[e],i=0,o=r.length;i<o;++i)r[i].value.apply(t,n)}};function wR(e,t){for(var n=0,r=e.length,i;n<r;++n)if((i=e[n]).name===t)return i.value}function hm(e,t,n){for(var r=0,i=e.length;r<i;++r)if(e[r].name===t){e[r]=_R,e=e.slice(0,r).concat(e.slice(r+1));break}return n!=null&&e.push({name:t,value:n}),e}var Jh="http://www.w3.org/1999/xhtml";const pm={svg:"http://www.w3.org/2000/svg",xhtml:Jh,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function ls(e){var t=e+="",n=t.indexOf(":");return n>=0&&(t=e.slice(0,n))!=="xmlns"&&(e=e.slice(n+1)),pm.hasOwnProperty(t)?{space:pm[t],local:e}:e}function SR(e){return function(){var t=this.ownerDocument,n=this.namespaceURI;return n===Jh&&t.documentElement.namespaceURI===Jh?t.createElement(e):t.createElementNS(n,e)}}function ER(e){return function(){return this.ownerDocument.createElementNS(e.space,e.local)}}function dE(e){var t=ls(e);return(t.local?ER:SR)(t)}function CR(){}function hv(e){return e==null?CR:function(){return this.querySelector(e)}}function kR(e){typeof e!="function"&&(e=hv(e));for(var t=this._groups,n=t.length,r=new Array(n),i=0;i<n;++i)for(var o=t[i],a=o.length,s=r[i]=new Array(a),u,l,c=0;c<a;++c)(u=o[c])&&(l=e.call(u,u.__data__,c,o))&&("__data__"in u&&(l.__data__=u.__data__),s[c]=l);return new Je(r,this._parents)}function bR(e){return e==null?[]:Array.isArray(e)?e:Array.from(e)}function TR(){return[]}function hE(e){return e==null?TR:function(){return this.querySelectorAll(e)}}function RR(e){return function(){return bR(e.apply(this,arguments))}}function NR(e){typeof e=="function"?e=RR(e):e=hE(e);for(var t=this._groups,n=t.length,r=[],i=[],o=0;o<n;++o)for(var a=t[o],s=a.length,u,l=0;l<s;++l)(u=a[l])&&(r.push(e.call(u,u.__data__,l,a)),i.push(u));return new Je(r,i)}function pE(e){return function(){return this.matches(e)}}function vE(e){return function(t){return t.matches(e)}}var IR=Array.prototype.find;function PR(e){return function(){return IR.call(this.children,e)}}function jR(){return this.firstElementChild}function qR(e){return this.select(e==null?jR:PR(typeof e=="function"?e:vE(e)))}var AR=Array.prototype.filter;function MR(){return Array.from(this.children)}function LR(e){return function(){return AR.call(this.children,e)}}function OR(e){return this.selectAll(e==null?MR:LR(typeof e=="function"?e:vE(e)))}function zR(e){typeof e!="function"&&(e=pE(e));for(var t=this._groups,n=t.length,r=new Array(n),i=0;i<n;++i)for(var o=t[i],a=o.length,s=r[i]=[],u,l=0;l<a;++l)(u=o[l])&&e.call(u,u.__data__,l,o)&&s.push(u);return new Je(r,this._parents)}function gE(e){return new Array(e.length)}function FR(){return new Je(this._enter||this._groups.map(gE),this._parents)}function Ma(e,t){this.ownerDocument=e.ownerDocument,this.namespaceURI=e.namespaceURI,this._next=null,this._parent=e,this.__data__=t}Ma.prototype={constructor:Ma,appendChild:function(e){return this._parent.insertBefore(e,this._next)},insertBefore:function(e,t){return this._parent.insertBefore(e,t)},querySelector:function(e){return this._parent.querySelector(e)},querySelectorAll:function(e){return this._parent.querySelectorAll(e)}};function DR(e){return function(){return e}}function $R(e,t,n,r,i,o){for(var a=0,s,u=t.length,l=o.length;a<l;++a)(s=t[a])?(s.__data__=o[a],r[a]=s):n[a]=new Ma(e,o[a]);for(;a<u;++a)(s=t[a])&&(i[a]=s)}function BR(e,t,n,r,i,o,a){var s,u,l=new Map,c=t.length,f=o.length,d=new Array(c),h;for(s=0;s<c;++s)(u=t[s])&&(d[s]=h=a.call(u,u.__data__,s,t)+"",l.has(h)?i[s]=u:l.set(h,u));for(s=0;s<f;++s)h=a.call(e,o[s],s,o)+"",(u=l.get(h))?(r[s]=u,u.__data__=o[s],l.delete(h)):n[s]=new Ma(e,o[s]);for(s=0;s<c;++s)(u=t[s])&&l.get(d[s])===u&&(i[s]=u)}function UR(e){return e.__data__}function HR(e,t){if(!arguments.length)return Array.from(this,UR);var n=t?BR:$R,r=this._parents,i=this._groups;typeof e!="function"&&(e=DR(e));for(var o=i.length,a=new Array(o),s=new Array(o),u=new Array(o),l=0;l<o;++l){var c=r[l],f=i[l],d=f.length,h=VR(e.call(c,c&&c.__data__,l,r)),g=h.length,v=s[l]=new Array(g),y=a[l]=new Array(g),p=u[l]=new Array(d);n(c,f,v,y,p,h,t);for(var m=0,_=0,x,S;m<g;++m)if(x=v[m]){for(m>=_&&(_=m+1);!(S=y[_])&&++_<g;);x._next=S||null}}return a=new Je(a,r),a._enter=s,a._exit=u,a}function VR(e){return typeof e=="object"&&"length"in e?e:Array.from(e)}function GR(){return new Je(this._exit||this._groups.map(gE),this._parents)}function WR(e,t,n){var r=this.enter(),i=this,o=this.exit();return typeof e=="function"?(r=e(r),r&&(r=r.selection())):r=r.append(e+""),t!=null&&(i=t(i),i&&(i=i.selection())),n==null?o.remove():n(o),r&&i?r.merge(i).order():i}function KR(e){for(var t=e.selection?e.selection():e,n=this._groups,r=t._groups,i=n.length,o=r.length,a=Math.min(i,o),s=new Array(i),u=0;u<a;++u)for(var l=n[u],c=r[u],f=l.length,d=s[u]=new Array(f),h,g=0;g<f;++g)(h=l[g]||c[g])&&(d[g]=h);for(;u<i;++u)s[u]=n[u];return new Je(s,this._parents)}function YR(){for(var e=this._groups,t=-1,n=e.length;++t<n;)for(var r=e[t],i=r.length-1,o=r[i],a;--i>=0;)(a=r[i])&&(o&&a.compareDocumentPosition(o)^4&&o.parentNode.insertBefore(a,o),o=a);return this}function QR(e){e||(e=XR);function t(f,d){return f&&d?e(f.__data__,d.__data__):!f-!d}for(var n=this._groups,r=n.length,i=new Array(r),o=0;o<r;++o){for(var a=n[o],s=a.length,u=i[o]=new Array(s),l,c=0;c<s;++c)(l=a[c])&&(u[c]=l);u.sort(t)}return new Je(i,this._parents).order()}function XR(e,t){return e<t?-1:e>t?1:e>=t?0:NaN}function ZR(){var e=arguments[0];return arguments[0]=this,e.apply(null,arguments),this}function JR(){return Array.from(this)}function eN(){for(var e=this._groups,t=0,n=e.length;t<n;++t)for(var r=e[t],i=0,o=r.length;i<o;++i){var a=r[i];if(a)return a}return null}function tN(){let e=0;for(const t of this)++e;return e}function nN(){return!this.node()}function rN(e){for(var t=this._groups,n=0,r=t.length;n<r;++n)for(var i=t[n],o=0,a=i.length,s;o<a;++o)(s=i[o])&&e.call(s,s.__data__,o,i);return this}function iN(e){return function(){this.removeAttribute(e)}}function oN(e){return function(){this.removeAttributeNS(e.space,e.local)}}function aN(e,t){return function(){this.setAttribute(e,t)}}function sN(e,t){return function(){this.setAttributeNS(e.space,e.local,t)}}function uN(e,t){return function(){var n=t.apply(this,arguments);n==null?this.removeAttribute(e):this.setAttribute(e,n)}}function lN(e,t){return function(){var n=t.apply(this,arguments);n==null?this.removeAttributeNS(e.space,e.local):this.setAttributeNS(e.space,e.local,n)}}function cN(e,t){var n=ls(e);if(arguments.length<2){var r=this.node();return n.local?r.getAttributeNS(n.space,n.local):r.getAttribute(n)}return this.each((t==null?n.local?oN:iN:typeof t=="function"?n.local?lN:uN:n.local?sN:aN)(n,t))}function mE(e){return e.ownerDocument&&e.ownerDocument.defaultView||e.document&&e||e.defaultView}function fN(e){return function(){this.style.removeProperty(e)}}function dN(e,t,n){return function(){this.style.setProperty(e,t,n)}}function hN(e,t,n){return function(){var r=t.apply(this,arguments);r==null?this.style.removeProperty(e):this.style.setProperty(e,r,n)}}function pN(e,t,n){return arguments.length>1?this.each((t==null?fN:typeof t=="function"?hN:dN)(e,t,n??"")):Ur(this.node(),e)}function Ur(e,t){return e.style.getPropertyValue(t)||mE(e).getComputedStyle(e,null).getPropertyValue(t)}function vN(e){return function(){delete this[e]}}function gN(e,t){return function(){this[e]=t}}function mN(e,t){return function(){var n=t.apply(this,arguments);n==null?delete this[e]:this[e]=n}}function yN(e,t){return arguments.length>1?this.each((t==null?vN:typeof t=="function"?mN:gN)(e,t)):this.node()[e]}function yE(e){return e.trim().split(/^|\s+/)}function pv(e){return e.classList||new _E(e)}function _E(e){this._node=e,this._names=yE(e.getAttribute("class")||"")}_E.prototype={add:function(e){var t=this._names.indexOf(e);t<0&&(this._names.push(e),this._node.setAttribute("class",this._names.join(" ")))},remove:function(e){var t=this._names.indexOf(e);t>=0&&(this._names.splice(t,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(e){return this._names.indexOf(e)>=0}};function xE(e,t){for(var n=pv(e),r=-1,i=t.length;++r<i;)n.add(t[r])}function wE(e,t){for(var n=pv(e),r=-1,i=t.length;++r<i;)n.remove(t[r])}function _N(e){return function(){xE(this,e)}}function xN(e){return function(){wE(this,e)}}function wN(e,t){return function(){(t.apply(this,arguments)?xE:wE)(this,e)}}function SN(e,t){var n=yE(e+"");if(arguments.length<2){for(var r=pv(this.node()),i=-1,o=n.length;++i<o;)if(!r.contains(n[i]))return!1;return!0}return this.each((typeof t=="function"?wN:t?_N:xN)(n,t))}function EN(){this.textContent=""}function CN(e){return function(){this.textContent=e}}function kN(e){return function(){var t=e.apply(this,arguments);this.textContent=t??""}}function bN(e){return arguments.length?this.each(e==null?EN:(typeof e=="function"?kN:CN)(e)):this.node().textContent}function TN(){this.innerHTML=""}function RN(e){return function(){this.innerHTML=e}}function NN(e){return function(){var t=e.apply(this,arguments);this.innerHTML=t??""}}function IN(e){return arguments.length?this.each(e==null?TN:(typeof e=="function"?NN:RN)(e)):this.node().innerHTML}function PN(){this.nextSibling&&this.parentNode.appendChild(this)}function jN(){return this.each(PN)}function qN(){this.previousSibling&&this.parentNode.insertBefore(this,this.parentNode.firstChild)}function AN(){return this.each(qN)}function MN(e){var t=typeof e=="function"?e:dE(e);return this.select(function(){return this.appendChild(t.apply(this,arguments))})}function LN(){return null}function ON(e,t){var n=typeof e=="function"?e:dE(e),r=t==null?LN:typeof t=="function"?t:hv(t);return this.select(function(){return this.insertBefore(n.apply(this,arguments),r.apply(this,arguments)||null)})}function zN(){var e=this.parentNode;e&&e.removeChild(this)}function FN(){return this.each(zN)}function DN(){var e=this.cloneNode(!1),t=this.parentNode;return t?t.insertBefore(e,this.nextSibling):e}function $N(){var e=this.cloneNode(!0),t=this.parentNode;return t?t.insertBefore(e,this.nextSibling):e}function BN(e){return this.select(e?$N:DN)}function UN(e){return arguments.length?this.property("__data__",e):this.node().__data__}function HN(e){return function(t){e.call(this,t,this.__data__)}}function VN(e){return e.trim().split(/^|\s+/).map(function(t){var n="",r=t.indexOf(".");return r>=0&&(n=t.slice(r+1),t=t.slice(0,r)),{type:t,name:n}})}function GN(e){return function(){var t=this.__on;if(t){for(var n=0,r=-1,i=t.length,o;n<i;++n)o=t[n],(!e.type||o.type===e.type)&&o.name===e.name?this.removeEventListener(o.type,o.listener,o.options):t[++r]=o;++r?t.length=r:delete this.__on}}}function WN(e,t,n){return function(){var r=this.__on,i,o=HN(t);if(r){for(var a=0,s=r.length;a<s;++a)if((i=r[a]).type===e.type&&i.name===e.name){this.removeEventListener(i.type,i.listener,i.options),this.addEventListener(i.type,i.listener=o,i.options=n),i.value=t;return}}this.addEventListener(e.type,o,n),i={type:e.type,name:e.name,value:t,listener:o,options:n},r?r.push(i):this.__on=[i]}}function KN(e,t,n){var r=VN(e+""),i,o=r.length,a;if(arguments.length<2){var s=this.node().__on;if(s){for(var u=0,l=s.length,c;u<l;++u)for(i=0,c=s[u];i<o;++i)if((a=r[i]).type===c.type&&a.name===c.name)return c.value}return}for(s=t?WN:GN,i=0;i<o;++i)this.each(s(r[i],t,n));return this}function SE(e,t,n){var r=mE(e),i=r.CustomEvent;typeof i=="function"?i=new i(t,n):(i=r.document.createEvent("Event"),n?(i.initEvent(t,n.bubbles,n.cancelable),i.detail=n.detail):i.initEvent(t,!1,!1)),e.dispatchEvent(i)}function YN(e,t){return function(){return SE(this,e,t)}}function QN(e,t){return function(){return SE(this,e,t.apply(this,arguments))}}function XN(e,t){return this.each((typeof t=="function"?QN:YN)(e,t))}function*ZN(){for(var e=this._groups,t=0,n=e.length;t<n;++t)for(var r=e[t],i=0,o=r.length,a;i<o;++i)(a=r[i])&&(yield a)}var EE=[null];function Je(e,t){this._groups=e,this._parents=t}function co(){return new Je([[document.documentElement]],EE)}function JN(){return this}Je.prototype=co.prototype={constructor:Je,select:kR,selectAll:NR,selectChild:qR,selectChildren:OR,filter:zR,data:HR,enter:FR,exit:GR,join:WR,merge:KR,selection:JN,order:YR,sort:QR,call:ZR,nodes:JR,node:eN,size:tN,empty:nN,each:rN,attr:cN,style:pN,property:yN,classed:SN,text:bN,html:IN,raise:jN,lower:AN,append:MN,insert:ON,remove:FN,clone:BN,datum:UN,on:KN,dispatch:XN,[Symbol.iterator]:ZN};function De(e){return typeof e=="string"?new Je([[document.querySelector(e)]],[document.documentElement]):new Je([[e]],EE)}function eI(e){let t;for(;t=e.sourceEvent;)e=t;return e}function Lt(e,t){if(e=eI(e),t===void 0&&(t=e.currentTarget),t){var n=t.ownerSVGElement||t;if(n.createSVGPoint){var r=n.createSVGPoint();return r.x=e.clientX,r.y=e.clientY,r=r.matrixTransform(t.getScreenCTM().inverse()),[r.x,r.y]}if(t.getBoundingClientRect){var i=t.getBoundingClientRect();return[e.clientX-i.left-t.clientLeft,e.clientY-i.top-t.clientTop]}}return[e.pageX,e.pageY]}const tI={passive:!1},Zi={capture:!0,passive:!1};function iu(e){e.stopImmediatePropagation()}function jr(e){e.preventDefault(),e.stopImmediatePropagation()}function CE(e){var t=e.document.documentElement,n=De(e).on("dragstart.drag",jr,Zi);"onselectstart"in t?n.on("selectstart.drag",jr,Zi):(t.__noselect=t.style.MozUserSelect,t.style.MozUserSelect="none")}function kE(e,t){var n=e.document.documentElement,r=De(e).on("dragstart.drag",null);t&&(r.on("click.drag",jr,Zi),setTimeout(function(){r.on("click.drag",null)},0)),"onselectstart"in n?r.on("selectstart.drag",null):(n.style.MozUserSelect=n.__noselect,delete n.__noselect)}const Do=e=>()=>e;function ep(e,{sourceEvent:t,subject:n,target:r,identifier:i,active:o,x:a,y:s,dx:u,dy:l,dispatch:c}){Object.defineProperties(this,{type:{value:e,enumerable:!0,configurable:!0},sourceEvent:{value:t,enumerable:!0,configurable:!0},subject:{value:n,enumerable:!0,configurable:!0},target:{value:r,enumerable:!0,configurable:!0},identifier:{value:i,enumerable:!0,configurable:!0},active:{value:o,enumerable:!0,configurable:!0},x:{value:a,enumerable:!0,configurable:!0},y:{value:s,enumerable:!0,configurable:!0},dx:{value:u,enumerable:!0,configurable:!0},dy:{value:l,enumerable:!0,configurable:!0},_:{value:c}})}ep.prototype.on=function(){var e=this._.on.apply(this._,arguments);return e===this._?this:e};function nI(e){return!e.ctrlKey&&!e.button}function rI(){return this.parentNode}function iI(e,t){return t??{x:e.x,y:e.y}}function oI(){return navigator.maxTouchPoints||"ontouchstart"in this}function aI(){var e=nI,t=rI,n=iI,r=oI,i={},o=lo("start","drag","end"),a=0,s,u,l,c,f=0;function d(x){x.on("mousedown.drag",h).filter(r).on("touchstart.drag",y).on("touchmove.drag",p,tI).on("touchend.drag touchcancel.drag",m).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function h(x,S){if(!(c||!e.call(this,x,S))){var E=_(this,t.call(this,x,S),x,S,"mouse");E&&(De(x.view).on("mousemove.drag",g,Zi).on("mouseup.drag",v,Zi),CE(x.view),iu(x),l=!1,s=x.clientX,u=x.clientY,E("start",x))}}function g(x){if(jr(x),!l){var S=x.clientX-s,E=x.clientY-u;l=S*S+E*E>f}i.mouse("drag",x)}function v(x){De(x.view).on("mousemove.drag mouseup.drag",null),kE(x.view,l),jr(x),i.mouse("end",x)}function y(x,S){if(e.call(this,x,S)){var E=x.changedTouches,C=t.call(this,x,S),T=E.length,M,k;for(M=0;M<T;++M)(k=_(this,C,x,S,E[M].identifier,E[M]))&&(iu(x),k("start",x,E[M]))}}function p(x){var S=x.changedTouches,E=S.length,C,T;for(C=0;C<E;++C)(T=i[S[C].identifier])&&(jr(x),T("drag",x,S[C]))}function m(x){var S=x.changedTouches,E=S.length,C,T;for(c&&clearTimeout(c),c=setTimeout(function(){c=null},500),C=0;C<E;++C)(T=i[S[C].identifier])&&(iu(x),T("end",x,S[C]))}function _(x,S,E,C,T,M){var k=o.copy(),j=Lt(M||E,S),B,H,b;if((b=n.call(x,new ep("beforestart",{sourceEvent:E,target:d,identifier:T,active:a,x:j[0],y:j[1],dx:0,dy:0,dispatch:k}),C))!=null)return B=b.x-j[0]||0,H=b.y-j[1]||0,function P(R,O,I){var A=j,L;switch(R){case"start":i[T]=P,L=a++;break;case"end":delete i[T],--a;case"drag":j=Lt(I||O,S),L=a;break}k.call(R,x,new ep(R,{sourceEvent:O,subject:b,target:d,identifier:T,active:L,x:j[0]+B,y:j[1]+H,dx:j[0]-A[0],dy:j[1]-A[1],dispatch:k}),C)}}return d.filter=function(x){return arguments.length?(e=typeof x=="function"?x:Do(!!x),d):e},d.container=function(x){return arguments.length?(t=typeof x=="function"?x:Do(x),d):t},d.subject=function(x){return arguments.length?(n=typeof x=="function"?x:Do(x),d):n},d.touchable=function(x){return arguments.length?(r=typeof x=="function"?x:Do(!!x),d):r},d.on=function(){var x=o.on.apply(o,arguments);return x===o?d:x},d.clickDistance=function(x){return arguments.length?(f=(x=+x)*x,d):Math.sqrt(f)},d}function vv(e,t,n){e.prototype=t.prototype=n,n.constructor=e}function bE(e,t){var n=Object.create(e.prototype);for(var r in t)n[r]=t[r];return n}function fo(){}var Ji=.7,La=1/Ji,qr="\\s*([+-]?\\d+)\\s*",eo="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*",Nt="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*",sI=/^#([0-9a-f]{3,8})$/,uI=new RegExp(`^rgb\\(${qr},${qr},${qr}\\)$`),lI=new RegExp(`^rgb\\(${Nt},${Nt},${Nt}\\)$`),cI=new RegExp(`^rgba\\(${qr},${qr},${qr},${eo}\\)$`),fI=new RegExp(`^rgba\\(${Nt},${Nt},${Nt},${eo}\\)$`),dI=new RegExp(`^hsl\\(${eo},${Nt},${Nt}\\)$`),hI=new RegExp(`^hsla\\(${eo},${Nt},${Nt},${eo}\\)$`),vm={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};vv(fo,to,{copy(e){return Object.assign(new this.constructor,this,e)},displayable(){return this.rgb().displayable()},hex:gm,formatHex:gm,formatHex8:pI,formatHsl:vI,formatRgb:mm,toString:mm});function gm(){return this.rgb().formatHex()}function pI(){return this.rgb().formatHex8()}function vI(){return TE(this).formatHsl()}function mm(){return this.rgb().formatRgb()}function to(e){var t,n;return e=(e+"").trim().toLowerCase(),(t=sI.exec(e))?(n=t[1].length,t=parseInt(t[1],16),n===6?ym(t):n===3?new Be(t>>8&15|t>>4&240,t>>4&15|t&240,(t&15)<<4|t&15,1):n===8?$o(t>>24&255,t>>16&255,t>>8&255,(t&255)/255):n===4?$o(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|t&240,((t&15)<<4|t&15)/255):null):(t=uI.exec(e))?new Be(t[1],t[2],t[3],1):(t=lI.exec(e))?new Be(t[1]*255/100,t[2]*255/100,t[3]*255/100,1):(t=cI.exec(e))?$o(t[1],t[2],t[3],t[4]):(t=fI.exec(e))?$o(t[1]*255/100,t[2]*255/100,t[3]*255/100,t[4]):(t=dI.exec(e))?wm(t[1],t[2]/100,t[3]/100,1):(t=hI.exec(e))?wm(t[1],t[2]/100,t[3]/100,t[4]):vm.hasOwnProperty(e)?ym(vm[e]):e==="transparent"?new Be(NaN,NaN,NaN,0):null}function ym(e){return new Be(e>>16&255,e>>8&255,e&255,1)}function $o(e,t,n,r){return r<=0&&(e=t=n=NaN),new Be(e,t,n,r)}function gI(e){return e instanceof fo||(e=to(e)),e?(e=e.rgb(),new Be(e.r,e.g,e.b,e.opacity)):new Be}function tp(e,t,n,r){return arguments.length===1?gI(e):new Be(e,t,n,r??1)}function Be(e,t,n,r){this.r=+e,this.g=+t,this.b=+n,this.opacity=+r}vv(Be,tp,bE(fo,{brighter(e){return e=e==null?La:Math.pow(La,e),new Be(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=e==null?Ji:Math.pow(Ji,e),new Be(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new Be(Vn(this.r),Vn(this.g),Vn(this.b),Oa(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:_m,formatHex:_m,formatHex8:mI,formatRgb:xm,toString:xm}));function _m(){return`#${$n(this.r)}${$n(this.g)}${$n(this.b)}`}function mI(){return`#${$n(this.r)}${$n(this.g)}${$n(this.b)}${$n((isNaN(this.opacity)?1:this.opacity)*255)}`}function xm(){const e=Oa(this.opacity);return`${e===1?"rgb(":"rgba("}${Vn(this.r)}, ${Vn(this.g)}, ${Vn(this.b)}${e===1?")":`, ${e})`}`}function Oa(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function Vn(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function $n(e){return e=Vn(e),(e<16?"0":"")+e.toString(16)}function wm(e,t,n,r){return r<=0?e=t=n=NaN:n<=0||n>=1?e=t=NaN:t<=0&&(e=NaN),new gt(e,t,n,r)}function TE(e){if(e instanceof gt)return new gt(e.h,e.s,e.l,e.opacity);if(e instanceof fo||(e=to(e)),!e)return new gt;if(e instanceof gt)return e;e=e.rgb();var t=e.r/255,n=e.g/255,r=e.b/255,i=Math.min(t,n,r),o=Math.max(t,n,r),a=NaN,s=o-i,u=(o+i)/2;return s?(t===o?a=(n-r)/s+(n<r)*6:n===o?a=(r-t)/s+2:a=(t-n)/s+4,s/=u<.5?o+i:2-o-i,a*=60):s=u>0&&u<1?0:a,new gt(a,s,u,e.opacity)}function yI(e,t,n,r){return arguments.length===1?TE(e):new gt(e,t,n,r??1)}function gt(e,t,n,r){this.h=+e,this.s=+t,this.l=+n,this.opacity=+r}vv(gt,yI,bE(fo,{brighter(e){return e=e==null?La:Math.pow(La,e),new gt(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=e==null?Ji:Math.pow(Ji,e),new gt(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+(this.h<0)*360,t=isNaN(e)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*t,i=2*n-r;return new Be(ou(e>=240?e-240:e+120,i,r),ou(e,i,r),ou(e<120?e+240:e-120,i,r),this.opacity)},clamp(){return new gt(Sm(this.h),Bo(this.s),Bo(this.l),Oa(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const e=Oa(this.opacity);return`${e===1?"hsl(":"hsla("}${Sm(this.h)}, ${Bo(this.s)*100}%, ${Bo(this.l)*100}%${e===1?")":`, ${e})`}`}}));function Sm(e){return e=(e||0)%360,e<0?e+360:e}function Bo(e){return Math.max(0,Math.min(1,e||0))}function ou(e,t,n){return(e<60?t+(n-t)*e/60:e<180?n:e<240?t+(n-t)*(240-e)/60:t)*255}const RE=e=>()=>e;function _I(e,t){return function(n){return e+n*t}}function xI(e,t,n){return e=Math.pow(e,n),t=Math.pow(t,n)-e,n=1/n,function(r){return Math.pow(e+r*t,n)}}function wI(e){return(e=+e)==1?NE:function(t,n){return n-t?xI(t,n,e):RE(isNaN(t)?n:t)}}function NE(e,t){var n=t-e;return n?_I(e,n):RE(isNaN(e)?t:e)}const Em=function e(t){var n=wI(t);function r(i,o){var a=n((i=tp(i)).r,(o=tp(o)).r),s=n(i.g,o.g),u=n(i.b,o.b),l=NE(i.opacity,o.opacity);return function(c){return i.r=a(c),i.g=s(c),i.b=u(c),i.opacity=l(c),i+""}}return r.gamma=e,r}(1);function an(e,t){return e=+e,t=+t,function(n){return e*(1-n)+t*n}}var np=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,au=new RegExp(np.source,"g");function SI(e){return function(){return e}}function EI(e){return function(t){return e(t)+""}}function CI(e,t){var n=np.lastIndex=au.lastIndex=0,r,i,o,a=-1,s=[],u=[];for(e=e+"",t=t+"";(r=np.exec(e))&&(i=au.exec(t));)(o=i.index)>n&&(o=t.slice(n,o),s[a]?s[a]+=o:s[++a]=o),(r=r[0])===(i=i[0])?s[a]?s[a]+=i:s[++a]=i:(s[++a]=null,u.push({i:a,x:an(r,i)})),n=au.lastIndex;return n<t.length&&(o=t.slice(n),s[a]?s[a]+=o:s[++a]=o),s.length<2?u[0]?EI(u[0].x):SI(t):(t=u.length,function(l){for(var c=0,f;c<t;++c)s[(f=u[c]).i]=f.x(l);return s.join("")})}var Cm=180/Math.PI,rp={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};function IE(e,t,n,r,i,o){var a,s,u;return(a=Math.sqrt(e*e+t*t))&&(e/=a,t/=a),(u=e*n+t*r)&&(n-=e*u,r-=t*u),(s=Math.sqrt(n*n+r*r))&&(n/=s,r/=s,u/=s),e*r<t*n&&(e=-e,t=-t,u=-u,a=-a),{translateX:i,translateY:o,rotate:Math.atan2(t,e)*Cm,skewX:Math.atan(u)*Cm,scaleX:a,scaleY:s}}var Uo;function kI(e){const t=new(typeof DOMMatrix=="function"?DOMMatrix:WebKitCSSMatrix)(e+"");return t.isIdentity?rp:IE(t.a,t.b,t.c,t.d,t.e,t.f)}function bI(e){return e==null||(Uo||(Uo=document.createElementNS("http://www.w3.org/2000/svg","g")),Uo.setAttribute("transform",e),!(e=Uo.transform.baseVal.consolidate()))?rp:(e=e.matrix,IE(e.a,e.b,e.c,e.d,e.e,e.f))}function PE(e,t,n,r){function i(l){return l.length?l.pop()+" ":""}function o(l,c,f,d,h,g){if(l!==f||c!==d){var v=h.push("translate(",null,t,null,n);g.push({i:v-4,x:an(l,f)},{i:v-2,x:an(c,d)})}else(f||d)&&h.push("translate("+f+t+d+n)}function a(l,c,f,d){l!==c?(l-c>180?c+=360:c-l>180&&(l+=360),d.push({i:f.push(i(f)+"rotate(",null,r)-2,x:an(l,c)})):c&&f.push(i(f)+"rotate("+c+r)}function s(l,c,f,d){l!==c?d.push({i:f.push(i(f)+"skewX(",null,r)-2,x:an(l,c)}):c&&f.push(i(f)+"skewX("+c+r)}function u(l,c,f,d,h,g){if(l!==f||c!==d){var v=h.push(i(h)+"scale(",null,",",null,")");g.push({i:v-4,x:an(l,f)},{i:v-2,x:an(c,d)})}else(f!==1||d!==1)&&h.push(i(h)+"scale("+f+","+d+")")}return function(l,c){var f=[],d=[];return l=e(l),c=e(c),o(l.translateX,l.translateY,c.translateX,c.translateY,f,d),a(l.rotate,c.rotate,f,d),s(l.skewX,c.skewX,f,d),u(l.scaleX,l.scaleY,c.scaleX,c.scaleY,f,d),l=c=null,function(h){for(var g=-1,v=d.length,y;++g<v;)f[(y=d[g]).i]=y.x(h);return f.join("")}}}var TI=PE(kI,"px, ","px)","deg)"),RI=PE(bI,", ",")",")"),NI=1e-12;function km(e){return((e=Math.exp(e))+1/e)/2}function II(e){return((e=Math.exp(e))-1/e)/2}function PI(e){return((e=Math.exp(2*e))-1)/(e+1)}const jI=function e(t,n,r){function i(o,a){var s=o[0],u=o[1],l=o[2],c=a[0],f=a[1],d=a[2],h=c-s,g=f-u,v=h*h+g*g,y,p;if(v<NI)p=Math.log(d/l)/t,y=function(C){return[s+C*h,u+C*g,l*Math.exp(t*C*p)]};else{var m=Math.sqrt(v),_=(d*d-l*l+r*v)/(2*l*n*m),x=(d*d-l*l-r*v)/(2*d*n*m),S=Math.log(Math.sqrt(_*_+1)-_),E=Math.log(Math.sqrt(x*x+1)-x);p=(E-S)/t,y=function(C){var T=C*p,M=km(S),k=l/(n*m)*(M*PI(t*T+S)-II(S));return[s+k*h,u+k*g,l*M/km(t*T+S)]}}return y.duration=p*1e3*t/Math.SQRT2,y}return i.rho=function(o){var a=Math.max(.001,+o),s=a*a,u=s*s;return e(a,s,u)},i}(Math.SQRT2,2,4);var Hr=0,gi=0,ci=0,jE=1e3,za,mi,Fa=0,Zn=0,cs=0,no=typeof performance=="object"&&performance.now?performance:Date,qE=typeof window=="object"&&window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(e){setTimeout(e,17)};function gv(){return Zn||(qE(qI),Zn=no.now()+cs)}function qI(){Zn=0}function Da(){this._call=this._time=this._next=null}Da.prototype=mv.prototype={constructor:Da,restart:function(e,t,n){if(typeof e!="function")throw new TypeError("callback is not a function");n=(n==null?gv():+n)+(t==null?0:+t),!this._next&&mi!==this&&(mi?mi._next=this:za=this,mi=this),this._call=e,this._time=n,ip()},stop:function(){this._call&&(this._call=null,this._time=1/0,ip())}};function mv(e,t,n){var r=new Da;return r.restart(e,t,n),r}function AI(){gv(),++Hr;for(var e=za,t;e;)(t=Zn-e._time)>=0&&e._call.call(void 0,t),e=e._next;--Hr}function bm(){Zn=(Fa=no.now())+cs,Hr=gi=0;try{AI()}finally{Hr=0,LI(),Zn=0}}function MI(){var e=no.now(),t=e-Fa;t>jE&&(cs-=t,Fa=e)}function LI(){for(var e,t=za,n,r=1/0;t;)t._call?(r>t._time&&(r=t._time),e=t,t=t._next):(n=t._next,t._next=null,t=e?e._next=n:za=n);mi=e,ip(r)}function ip(e){if(!Hr){gi&&(gi=clearTimeout(gi));var t=e-Zn;t>24?(e<1/0&&(gi=setTimeout(bm,e-no.now()-cs)),ci&&(ci=clearInterval(ci))):(ci||(Fa=no.now(),ci=setInterval(MI,jE)),Hr=1,qE(bm))}}function Tm(e,t,n){var r=new Da;return t=t==null?0:+t,r.restart(i=>{r.stop(),e(i+t)},t,n),r}var OI=lo("start","end","cancel","interrupt"),zI=[],AE=0,Rm=1,op=2,aa=3,Nm=4,ap=5,sa=6;function fs(e,t,n,r,i,o){var a=e.__transition;if(!a)e.__transition={};else if(n in a)return;FI(e,n,{name:t,index:r,group:i,on:OI,tween:zI,time:o.time,delay:o.delay,duration:o.duration,ease:o.ease,timer:null,state:AE})}function yv(e,t){var n=xt(e,t);if(n.state>AE)throw new Error("too late; already scheduled");return n}function Pt(e,t){var n=xt(e,t);if(n.state>aa)throw new Error("too late; already running");return n}function xt(e,t){var n=e.__transition;if(!n||!(n=n[t]))throw new Error("transition not found");return n}function FI(e,t,n){var r=e.__transition,i;r[t]=n,n.timer=mv(o,0,n.time);function o(l){n.state=Rm,n.timer.restart(a,n.delay,n.time),n.delay<=l&&a(l-n.delay)}function a(l){var c,f,d,h;if(n.state!==Rm)return u();for(c in r)if(h=r[c],h.name===n.name){if(h.state===aa)return Tm(a);h.state===Nm?(h.state=sa,h.timer.stop(),h.on.call("interrupt",e,e.__data__,h.index,h.group),delete r[c]):+c<t&&(h.state=sa,h.timer.stop(),h.on.call("cancel",e,e.__data__,h.index,h.group),delete r[c])}if(Tm(function(){n.state===aa&&(n.state=Nm,n.timer.restart(s,n.delay,n.time),s(l))}),n.state=op,n.on.call("start",e,e.__data__,n.index,n.group),n.state===op){for(n.state=aa,i=new Array(d=n.tween.length),c=0,f=-1;c<d;++c)(h=n.tween[c].value.call(e,e.__data__,n.index,n.group))&&(i[++f]=h);i.length=f+1}}function s(l){for(var c=l<n.duration?n.ease.call(null,l/n.duration):(n.timer.restart(u),n.state=ap,1),f=-1,d=i.length;++f<d;)i[f].call(e,c);n.state===ap&&(n.on.call("end",e,e.__data__,n.index,n.group),u())}function u(){n.state=sa,n.timer.stop(),delete r[t];for(var l in r)return;delete e.__transition}}function ua(e,t){var n=e.__transition,r,i,o=!0,a;if(n){t=t==null?null:t+"";for(a in n){if((r=n[a]).name!==t){o=!1;continue}i=r.state>op&&r.state<ap,r.state=sa,r.timer.stop(),r.on.call(i?"interrupt":"cancel",e,e.__data__,r.index,r.group),delete n[a]}o&&delete e.__transition}}function DI(e){return this.each(function(){ua(this,e)})}function $I(e,t){var n,r;return function(){var i=Pt(this,e),o=i.tween;if(o!==n){r=n=o;for(var a=0,s=r.length;a<s;++a)if(r[a].name===t){r=r.slice(),r.splice(a,1);break}}i.tween=r}}function BI(e,t,n){var r,i;if(typeof n!="function")throw new Error;return function(){var o=Pt(this,e),a=o.tween;if(a!==r){i=(r=a).slice();for(var s={name:t,value:n},u=0,l=i.length;u<l;++u)if(i[u].name===t){i[u]=s;break}u===l&&i.push(s)}o.tween=i}}function UI(e,t){var n=this._id;if(e+="",arguments.length<2){for(var r=xt(this.node(),n).tween,i=0,o=r.length,a;i<o;++i)if((a=r[i]).name===e)return a.value;return null}return this.each((t==null?$I:BI)(n,e,t))}function _v(e,t,n){var r=e._id;return e.each(function(){var i=Pt(this,r);(i.value||(i.value={}))[t]=n.apply(this,arguments)}),function(i){return xt(i,r).value[t]}}function ME(e,t){var n;return(typeof t=="number"?an:t instanceof to?Em:(n=to(t))?(t=n,Em):CI)(e,t)}function HI(e){return function(){this.removeAttribute(e)}}function VI(e){return function(){this.removeAttributeNS(e.space,e.local)}}function GI(e,t,n){var r,i=n+"",o;return function(){var a=this.getAttribute(e);return a===i?null:a===r?o:o=t(r=a,n)}}function WI(e,t,n){var r,i=n+"",o;return function(){var a=this.getAttributeNS(e.space,e.local);return a===i?null:a===r?o:o=t(r=a,n)}}function KI(e,t,n){var r,i,o;return function(){var a,s=n(this),u;return s==null?void this.removeAttribute(e):(a=this.getAttribute(e),u=s+"",a===u?null:a===r&&u===i?o:(i=u,o=t(r=a,s)))}}function YI(e,t,n){var r,i,o;return function(){var a,s=n(this),u;return s==null?void this.removeAttributeNS(e.space,e.local):(a=this.getAttributeNS(e.space,e.local),u=s+"",a===u?null:a===r&&u===i?o:(i=u,o=t(r=a,s)))}}function QI(e,t){var n=ls(e),r=n==="transform"?RI:ME;return this.attrTween(e,typeof t=="function"?(n.local?YI:KI)(n,r,_v(this,"attr."+e,t)):t==null?(n.local?VI:HI)(n):(n.local?WI:GI)(n,r,t))}function XI(e,t){return function(n){this.setAttribute(e,t.call(this,n))}}function ZI(e,t){return function(n){this.setAttributeNS(e.space,e.local,t.call(this,n))}}function JI(e,t){var n,r;function i(){var o=t.apply(this,arguments);return o!==r&&(n=(r=o)&&ZI(e,o)),n}return i._value=t,i}function eP(e,t){var n,r;function i(){var o=t.apply(this,arguments);return o!==r&&(n=(r=o)&&XI(e,o)),n}return i._value=t,i}function tP(e,t){var n="attr."+e;if(arguments.length<2)return(n=this.tween(n))&&n._value;if(t==null)return this.tween(n,null);if(typeof t!="function")throw new Error;var r=ls(e);return this.tween(n,(r.local?JI:eP)(r,t))}function nP(e,t){return function(){yv(this,e).delay=+t.apply(this,arguments)}}function rP(e,t){return t=+t,function(){yv(this,e).delay=t}}function iP(e){var t=this._id;return arguments.length?this.each((typeof e=="function"?nP:rP)(t,e)):xt(this.node(),t).delay}function oP(e,t){return function(){Pt(this,e).duration=+t.apply(this,arguments)}}function aP(e,t){return t=+t,function(){Pt(this,e).duration=t}}function sP(e){var t=this._id;return arguments.length?this.each((typeof e=="function"?oP:aP)(t,e)):xt(this.node(),t).duration}function uP(e,t){if(typeof t!="function")throw new Error;return function(){Pt(this,e).ease=t}}function lP(e){var t=this._id;return arguments.length?this.each(uP(t,e)):xt(this.node(),t).ease}function cP(e,t){return function(){var n=t.apply(this,arguments);if(typeof n!="function")throw new Error;Pt(this,e).ease=n}}function fP(e){if(typeof e!="function")throw new Error;return this.each(cP(this._id,e))}function dP(e){typeof e!="function"&&(e=pE(e));for(var t=this._groups,n=t.length,r=new Array(n),i=0;i<n;++i)for(var o=t[i],a=o.length,s=r[i]=[],u,l=0;l<a;++l)(u=o[l])&&e.call(u,u.__data__,l,o)&&s.push(u);return new Kt(r,this._parents,this._name,this._id)}function hP(e){if(e._id!==this._id)throw new Error;for(var t=this._groups,n=e._groups,r=t.length,i=n.length,o=Math.min(r,i),a=new Array(r),s=0;s<o;++s)for(var u=t[s],l=n[s],c=u.length,f=a[s]=new Array(c),d,h=0;h<c;++h)(d=u[h]||l[h])&&(f[h]=d);for(;s<r;++s)a[s]=t[s];return new Kt(a,this._parents,this._name,this._id)}function pP(e){return(e+"").trim().split(/^|\s+/).every(function(t){var n=t.indexOf(".");return n>=0&&(t=t.slice(0,n)),!t||t==="start"})}function vP(e,t,n){var r,i,o=pP(t)?yv:Pt;return function(){var a=o(this,e),s=a.on;s!==r&&(i=(r=s).copy()).on(t,n),a.on=i}}function gP(e,t){var n=this._id;return arguments.length<2?xt(this.node(),n).on.on(e):this.each(vP(n,e,t))}function mP(e){return function(){var t=this.parentNode;for(var n in this.__transition)if(+n!==e)return;t&&t.removeChild(this)}}function yP(){return this.on("end.remove",mP(this._id))}function _P(e){var t=this._name,n=this._id;typeof e!="function"&&(e=hv(e));for(var r=this._groups,i=r.length,o=new Array(i),a=0;a<i;++a)for(var s=r[a],u=s.length,l=o[a]=new Array(u),c,f,d=0;d<u;++d)(c=s[d])&&(f=e.call(c,c.__data__,d,s))&&("__data__"in c&&(f.__data__=c.__data__),l[d]=f,fs(l[d],t,n,d,l,xt(c,n)));return new Kt(o,this._parents,t,n)}function xP(e){var t=this._name,n=this._id;typeof e!="function"&&(e=hE(e));for(var r=this._groups,i=r.length,o=[],a=[],s=0;s<i;++s)for(var u=r[s],l=u.length,c,f=0;f<l;++f)if(c=u[f]){for(var d=e.call(c,c.__data__,f,u),h,g=xt(c,n),v=0,y=d.length;v<y;++v)(h=d[v])&&fs(h,t,n,v,d,g);o.push(d),a.push(c)}return new Kt(o,a,t,n)}var wP=co.prototype.constructor;function SP(){return new wP(this._groups,this._parents)}function EP(e,t){var n,r,i;return function(){var o=Ur(this,e),a=(this.style.removeProperty(e),Ur(this,e));return o===a?null:o===n&&a===r?i:i=t(n=o,r=a)}}function LE(e){return function(){this.style.removeProperty(e)}}function CP(e,t,n){var r,i=n+"",o;return function(){var a=Ur(this,e);return a===i?null:a===r?o:o=t(r=a,n)}}function kP(e,t,n){var r,i,o;return function(){var a=Ur(this,e),s=n(this),u=s+"";return s==null&&(u=s=(this.style.removeProperty(e),Ur(this,e))),a===u?null:a===r&&u===i?o:(i=u,o=t(r=a,s))}}function bP(e,t){var n,r,i,o="style."+t,a="end."+o,s;return function(){var u=Pt(this,e),l=u.on,c=u.value[o]==null?s||(s=LE(t)):void 0;(l!==n||i!==c)&&(r=(n=l).copy()).on(a,i=c),u.on=r}}function TP(e,t,n){var r=(e+="")=="transform"?TI:ME;return t==null?this.styleTween(e,EP(e,r)).on("end.style."+e,LE(e)):typeof t=="function"?this.styleTween(e,kP(e,r,_v(this,"style."+e,t))).each(bP(this._id,e)):this.styleTween(e,CP(e,r,t),n).on("end.style."+e,null)}function RP(e,t,n){return function(r){this.style.setProperty(e,t.call(this,r),n)}}function NP(e,t,n){var r,i;function o(){var a=t.apply(this,arguments);return a!==i&&(r=(i=a)&&RP(e,a,n)),r}return o._value=t,o}function IP(e,t,n){var r="style."+(e+="");if(arguments.length<2)return(r=this.tween(r))&&r._value;if(t==null)return this.tween(r,null);if(typeof t!="function")throw new Error;return this.tween(r,NP(e,t,n??""))}function PP(e){return function(){this.textContent=e}}function jP(e){return function(){var t=e(this);this.textContent=t??""}}function qP(e){return this.tween("text",typeof e=="function"?jP(_v(this,"text",e)):PP(e==null?"":e+""))}function AP(e){return function(t){this.textContent=e.call(this,t)}}function MP(e){var t,n;function r(){var i=e.apply(this,arguments);return i!==n&&(t=(n=i)&&AP(i)),t}return r._value=e,r}function LP(e){var t="text";if(arguments.length<1)return(t=this.tween(t))&&t._value;if(e==null)return this.tween(t,null);if(typeof e!="function")throw new Error;return this.tween(t,MP(e))}function OP(){for(var e=this._name,t=this._id,n=OE(),r=this._groups,i=r.length,o=0;o<i;++o)for(var a=r[o],s=a.length,u,l=0;l<s;++l)if(u=a[l]){var c=xt(u,t);fs(u,e,n,l,a,{time:c.time+c.delay+c.duration,delay:0,duration:c.duration,ease:c.ease})}return new Kt(r,this._parents,e,n)}function zP(){var e,t,n=this,r=n._id,i=n.size();return new Promise(function(o,a){var s={value:a},u={value:function(){--i===0&&o()}};n.each(function(){var l=Pt(this,r),c=l.on;c!==e&&(t=(e=c).copy(),t._.cancel.push(s),t._.interrupt.push(s),t._.end.push(u)),l.on=t}),i===0&&o()})}var FP=0;function Kt(e,t,n,r){this._groups=e,this._parents=t,this._name=n,this._id=r}function OE(){return++FP}var qt=co.prototype;Kt.prototype={constructor:Kt,select:_P,selectAll:xP,selectChild:qt.selectChild,selectChildren:qt.selectChildren,filter:dP,merge:hP,selection:SP,transition:OP,call:qt.call,nodes:qt.nodes,node:qt.node,size:qt.size,empty:qt.empty,each:qt.each,on:gP,attr:QI,attrTween:tP,style:TP,styleTween:IP,text:qP,textTween:LP,remove:yP,tween:UI,delay:iP,duration:sP,ease:lP,easeVarying:fP,end:zP,[Symbol.iterator]:qt[Symbol.iterator]};function DP(e){return((e*=2)<=1?e*e*e:(e-=2)*e*e+2)/2}var $P={time:null,delay:0,duration:250,ease:DP};function BP(e,t){for(var n;!(n=e.__transition)||!(n=n[t]);)if(!(e=e.parentNode))throw new Error(`transition ${t} not found`);return n}function UP(e){var t,n;e instanceof Kt?(t=e._id,e=e._name):(t=OE(),(n=$P).time=gv(),e=e==null?null:e+"");for(var r=this._groups,i=r.length,o=0;o<i;++o)for(var a=r[o],s=a.length,u,l=0;l<s;++l)(u=a[l])&&fs(u,e,t,l,a,n||BP(u,t));return new Kt(r,this._parents,e,t)}co.prototype.interrupt=DI;co.prototype.transition=UP;const sp=Math.PI,up=2*sp,On=1e-6,HP=up-On;function zE(e){this._+=e[0];for(let t=1,n=e.length;t<n;++t)this._+=arguments[t]+e[t]}function VP(e){let t=Math.floor(e);if(!(t>=0))throw new Error(`invalid digits: ${e}`);if(t>15)return zE;const n=10**t;return function(r){this._+=r[0];for(let i=1,o=r.length;i<o;++i)this._+=Math.round(arguments[i]*n)/n+r[i]}}class GP{constructor(t){this._x0=this._y0=this._x1=this._y1=null,this._="",this._append=t==null?zE:VP(t)}moveTo(t,n){this._append`M${this._x0=this._x1=+t},${this._y0=this._y1=+n}`}closePath(){this._x1!==null&&(this._x1=this._x0,this._y1=this._y0,this._append`Z`)}lineTo(t,n){this._append`L${this._x1=+t},${this._y1=+n}`}quadraticCurveTo(t,n,r,i){this._append`Q${+t},${+n},${this._x1=+r},${this._y1=+i}`}bezierCurveTo(t,n,r,i,o,a){this._append`C${+t},${+n},${+r},${+i},${this._x1=+o},${this._y1=+a}`}arcTo(t,n,r,i,o){if(t=+t,n=+n,r=+r,i=+i,o=+o,o<0)throw new Error(`negative radius: ${o}`);let a=this._x1,s=this._y1,u=r-t,l=i-n,c=a-t,f=s-n,d=c*c+f*f;if(this._x1===null)this._append`M${this._x1=t},${this._y1=n}`;else if(d>On)if(!(Math.abs(f*u-l*c)>On)||!o)this._append`L${this._x1=t},${this._y1=n}`;else{let h=r-a,g=i-s,v=u*u+l*l,y=h*h+g*g,p=Math.sqrt(v),m=Math.sqrt(d),_=o*Math.tan((sp-Math.acos((v+d-y)/(2*p*m)))/2),x=_/m,S=_/p;Math.abs(x-1)>On&&this._append`L${t+x*c},${n+x*f}`,this._append`A${o},${o},0,0,${+(f*h>c*g)},${this._x1=t+S*u},${this._y1=n+S*l}`}}arc(t,n,r,i,o,a){if(t=+t,n=+n,r=+r,a=!!a,r<0)throw new Error(`negative radius: ${r}`);let s=r*Math.cos(i),u=r*Math.sin(i),l=t+s,c=n+u,f=1^a,d=a?i-o:o-i;this._x1===null?this._append`M${l},${c}`:(Math.abs(this._x1-l)>On||Math.abs(this._y1-c)>On)&&this._append`L${l},${c}`,r&&(d<0&&(d=d%up+up),d>HP?this._append`A${r},${r},0,1,${f},${t-s},${n-u}A${r},${r},0,1,${f},${this._x1=l},${this._y1=c}`:d>On&&this._append`A${r},${r},0,${+(d>=sp)},${f},${this._x1=t+r*Math.cos(o)},${this._y1=n+r*Math.sin(o)}`)}rect(t,n,r,i){this._append`M${this._x0=this._x1=+t},${this._y0=this._y1=+n}h${r=+r}v${+i}h${-r}Z`}toString(){return this._}}function WP(e,t){var n,r=1;e==null&&(e=0),t==null&&(t=0);function i(){var o,a=n.length,s,u=0,l=0;for(o=0;o<a;++o)s=n[o],u+=s.x,l+=s.y;for(u=(u/a-e)*r,l=(l/a-t)*r,o=0;o<a;++o)s=n[o],s.x-=u,s.y-=l}return i.initialize=function(o){n=o},i.x=function(o){return arguments.length?(e=+o,i):e},i.y=function(o){return arguments.length?(t=+o,i):t},i.strength=function(o){return arguments.length?(r=+o,i):r},i}function KP(e){const t=+this._x.call(null,e),n=+this._y.call(null,e);return FE(this.cover(t,n),t,n,e)}function FE(e,t,n,r){if(isNaN(t)||isNaN(n))return e;var i,o=e._root,a={data:r},s=e._x0,u=e._y0,l=e._x1,c=e._y1,f,d,h,g,v,y,p,m;if(!o)return e._root=a,e;for(;o.length;)if((v=t>=(f=(s+l)/2))?s=f:l=f,(y=n>=(d=(u+c)/2))?u=d:c=d,i=o,!(o=o[p=y<<1|v]))return i[p]=a,e;if(h=+e._x.call(null,o.data),g=+e._y.call(null,o.data),t===h&&n===g)return a.next=o,i?i[p]=a:e._root=a,e;do i=i?i[p]=new Array(4):e._root=new Array(4),(v=t>=(f=(s+l)/2))?s=f:l=f,(y=n>=(d=(u+c)/2))?u=d:c=d;while((p=y<<1|v)===(m=(g>=d)<<1|h>=f));return i[m]=o,i[p]=a,e}function YP(e){var t,n,r=e.length,i,o,a=new Array(r),s=new Array(r),u=1/0,l=1/0,c=-1/0,f=-1/0;for(n=0;n<r;++n)isNaN(i=+this._x.call(null,t=e[n]))||isNaN(o=+this._y.call(null,t))||(a[n]=i,s[n]=o,i<u&&(u=i),i>c&&(c=i),o<l&&(l=o),o>f&&(f=o));if(u>c||l>f)return this;for(this.cover(u,l).cover(c,f),n=0;n<r;++n)FE(this,a[n],s[n],e[n]);return this}function QP(e,t){if(isNaN(e=+e)||isNaN(t=+t))return this;var n=this._x0,r=this._y0,i=this._x1,o=this._y1;if(isNaN(n))i=(n=Math.floor(e))+1,o=(r=Math.floor(t))+1;else{for(var a=i-n||1,s=this._root,u,l;n>e||e>=i||r>t||t>=o;)switch(l=(t<r)<<1|e<n,u=new Array(4),u[l]=s,s=u,a*=2,l){case 0:i=n+a,o=r+a;break;case 1:n=i-a,o=r+a;break;case 2:i=n+a,r=o-a;break;case 3:n=i-a,r=o-a;break}this._root&&this._root.length&&(this._root=s)}return this._x0=n,this._y0=r,this._x1=i,this._y1=o,this}function XP(){var e=[];return this.visit(function(t){if(!t.length)do e.push(t.data);while(t=t.next)}),e}function ZP(e){return arguments.length?this.cover(+e[0][0],+e[0][1]).cover(+e[1][0],+e[1][1]):isNaN(this._x0)?void 0:[[this._x0,this._y0],[this._x1,this._y1]]}function qe(e,t,n,r,i){this.node=e,this.x0=t,this.y0=n,this.x1=r,this.y1=i}function JP(e,t,n){var r,i=this._x0,o=this._y0,a,s,u,l,c=this._x1,f=this._y1,d=[],h=this._root,g,v;for(h&&d.push(new qe(h,i,o,c,f)),n==null?n=1/0:(i=e-n,o=t-n,c=e+n,f=t+n,n*=n);g=d.pop();)if(!(!(h=g.node)||(a=g.x0)>c||(s=g.y0)>f||(u=g.x1)<i||(l=g.y1)<o))if(h.length){var y=(a+u)/2,p=(s+l)/2;d.push(new qe(h[3],y,p,u,l),new qe(h[2],a,p,y,l),new qe(h[1],y,s,u,p),new qe(h[0],a,s,y,p)),(v=(t>=p)<<1|e>=y)&&(g=d[d.length-1],d[d.length-1]=d[d.length-1-v],d[d.length-1-v]=g)}else{var m=e-+this._x.call(null,h.data),_=t-+this._y.call(null,h.data),x=m*m+_*_;if(x<n){var S=Math.sqrt(n=x);i=e-S,o=t-S,c=e+S,f=t+S,r=h.data}}return r}function ej(e){if(isNaN(c=+this._x.call(null,e))||isNaN(f=+this._y.call(null,e)))return this;var t,n=this._root,r,i,o,a=this._x0,s=this._y0,u=this._x1,l=this._y1,c,f,d,h,g,v,y,p;if(!n)return this;if(n.length)for(;;){if((g=c>=(d=(a+u)/2))?a=d:u=d,(v=f>=(h=(s+l)/2))?s=h:l=h,t=n,!(n=n[y=v<<1|g]))return this;if(!n.length)break;(t[y+1&3]||t[y+2&3]||t[y+3&3])&&(r=t,p=y)}for(;n.data!==e;)if(i=n,!(n=n.next))return this;return(o=n.next)&&delete n.next,i?(o?i.next=o:delete i.next,this):t?(o?t[y]=o:delete t[y],(n=t[0]||t[1]||t[2]||t[3])&&n===(t[3]||t[2]||t[1]||t[0])&&!n.length&&(r?r[p]=n:this._root=n),this):(this._root=o,this)}function tj(e){for(var t=0,n=e.length;t<n;++t)this.remove(e[t]);return this}function nj(){return this._root}function rj(){var e=0;return this.visit(function(t){if(!t.length)do++e;while(t=t.next)}),e}function ij(e){var t=[],n,r=this._root,i,o,a,s,u;for(r&&t.push(new qe(r,this._x0,this._y0,this._x1,this._y1));n=t.pop();)if(!e(r=n.node,o=n.x0,a=n.y0,s=n.x1,u=n.y1)&&r.length){var l=(o+s)/2,c=(a+u)/2;(i=r[3])&&t.push(new qe(i,l,c,s,u)),(i=r[2])&&t.push(new qe(i,o,c,l,u)),(i=r[1])&&t.push(new qe(i,l,a,s,c)),(i=r[0])&&t.push(new qe(i,o,a,l,c))}return this}function oj(e){var t=[],n=[],r;for(this._root&&t.push(new qe(this._root,this._x0,this._y0,this._x1,this._y1));r=t.pop();){var i=r.node;if(i.length){var o,a=r.x0,s=r.y0,u=r.x1,l=r.y1,c=(a+u)/2,f=(s+l)/2;(o=i[0])&&t.push(new qe(o,a,s,c,f)),(o=i[1])&&t.push(new qe(o,c,s,u,f)),(o=i[2])&&t.push(new qe(o,a,f,c,l)),(o=i[3])&&t.push(new qe(o,c,f,u,l))}n.push(r)}for(;r=n.pop();)e(r.node,r.x0,r.y0,r.x1,r.y1);return this}function aj(e){return e[0]}function sj(e){return arguments.length?(this._x=e,this):this._x}function uj(e){return e[1]}function lj(e){return arguments.length?(this._y=e,this):this._y}function xv(e,t,n){var r=new wv(t??aj,n??uj,NaN,NaN,NaN,NaN);return e==null?r:r.addAll(e)}function wv(e,t,n,r,i,o){this._x=e,this._y=t,this._x0=n,this._y0=r,this._x1=i,this._y1=o,this._root=void 0}function Im(e){for(var t={data:e.data},n=t;e=e.next;)n=n.next={data:e.data};return t}var Oe=xv.prototype=wv.prototype;Oe.copy=function(){var e=new wv(this._x,this._y,this._x0,this._y0,this._x1,this._y1),t=this._root,n,r;if(!t)return e;if(!t.length)return e._root=Im(t),e;for(n=[{source:t,target:e._root=new Array(4)}];t=n.pop();)for(var i=0;i<4;++i)(r=t.source[i])&&(r.length?n.push({source:r,target:t.target[i]=new Array(4)}):t.target[i]=Im(r));return e};Oe.add=KP;Oe.addAll=YP;Oe.cover=QP;Oe.data=XP;Oe.extent=ZP;Oe.find=JP;Oe.remove=ej;Oe.removeAll=tj;Oe.root=nj;Oe.size=rj;Oe.visit=ij;Oe.visitAfter=oj;Oe.x=sj;Oe.y=lj;function Gn(e){return function(){return e}}function hn(e){return(e()-.5)*1e-6}function cj(e){return e.x+e.vx}function fj(e){return e.y+e.vy}function dj(e){var t,n,r,i=1,o=1;typeof e!="function"&&(e=Gn(e==null?1:+e));function a(){for(var l,c=t.length,f,d,h,g,v,y,p=0;p<o;++p)for(f=xv(t,cj,fj).visitAfter(s),l=0;l<c;++l)d=t[l],v=n[d.index],y=v*v,h=d.x+d.vx,g=d.y+d.vy,f.visit(m);function m(_,x,S,E,C){var T=_.data,M=_.r,k=v+M;if(T){if(T.index>d.index){var j=h-T.x-T.vx,B=g-T.y-T.vy,H=j*j+B*B;H<k*k&&(j===0&&(j=hn(r),H+=j*j),B===0&&(B=hn(r),H+=B*B),H=(k-(H=Math.sqrt(H)))/H*i,d.vx+=(j*=H)*(k=(M*=M)/(y+M)),d.vy+=(B*=H)*k,T.vx-=j*(k=1-k),T.vy-=B*k)}return}return x>h+k||E<h-k||S>g+k||C<g-k}}function s(l){if(l.data)return l.r=n[l.data.index];for(var c=l.r=0;c<4;++c)l[c]&&l[c].r>l.r&&(l.r=l[c].r)}function u(){if(t){var l,c=t.length,f;for(n=new Array(c),l=0;l<c;++l)f=t[l],n[f.index]=+e(f,l,t)}}return a.initialize=function(l,c){t=l,r=c,u()},a.iterations=function(l){return arguments.length?(o=+l,a):o},a.strength=function(l){return arguments.length?(i=+l,a):i},a.radius=function(l){return arguments.length?(e=typeof l=="function"?l:Gn(+l),u(),a):e},a}function hj(e){return e.index}function Pm(e,t){var n=e.get(t);if(!n)throw new Error("node not found: "+t);return n}function pj(e){var t=hj,n=f,r,i=Gn(30),o,a,s,u,l,c=1;e==null&&(e=[]);function f(y){return 1/Math.min(s[y.source.index],s[y.target.index])}function d(y){for(var p=0,m=e.length;p<c;++p)for(var _=0,x,S,E,C,T,M,k;_<m;++_)x=e[_],S=x.source,E=x.target,C=E.x+E.vx-S.x-S.vx||hn(l),T=E.y+E.vy-S.y-S.vy||hn(l),M=Math.sqrt(C*C+T*T),M=(M-o[_])/M*y*r[_],C*=M,T*=M,E.vx-=C*(k=u[_]),E.vy-=T*k,S.vx+=C*(k=1-k),S.vy+=T*k}function h(){if(a){var y,p=a.length,m=e.length,_=new Map(a.map((S,E)=>[t(S,E,a),S])),x;for(y=0,s=new Array(p);y<m;++y)x=e[y],x.index=y,typeof x.source!="object"&&(x.source=Pm(_,x.source)),typeof x.target!="object"&&(x.target=Pm(_,x.target)),s[x.source.index]=(s[x.source.index]||0)+1,s[x.target.index]=(s[x.target.index]||0)+1;for(y=0,u=new Array(m);y<m;++y)x=e[y],u[y]=s[x.source.index]/(s[x.source.index]+s[x.target.index]);r=new Array(m),g(),o=new Array(m),v()}}function g(){if(a)for(var y=0,p=e.length;y<p;++y)r[y]=+n(e[y],y,e)}function v(){if(a)for(var y=0,p=e.length;y<p;++y)o[y]=+i(e[y],y,e)}return d.initialize=function(y,p){a=y,l=p,h()},d.links=function(y){return arguments.length?(e=y,h(),d):e},d.id=function(y){return arguments.length?(t=y,d):t},d.iterations=function(y){return arguments.length?(c=+y,d):c},d.strength=function(y){return arguments.length?(n=typeof y=="function"?y:Gn(+y),g(),d):n},d.distance=function(y){return arguments.length?(i=typeof y=="function"?y:Gn(+y),v(),d):i},d}const vj=1664525,gj=1013904223,jm=4294967296;function mj(){let e=1;return()=>(e=(vj*e+gj)%jm)/jm}function yj(e){return e.x}function _j(e){return e.y}var xj=10,wj=Math.PI*(3-Math.sqrt(5));function Sj(e){var t,n=1,r=.001,i=1-Math.pow(r,1/300),o=0,a=.6,s=new Map,u=mv(f),l=lo("tick","end"),c=mj();e==null&&(e=[]);function f(){d(),l.call("tick",t),n<r&&(u.stop(),l.call("end",t))}function d(v){var y,p=e.length,m;v===void 0&&(v=1);for(var _=0;_<v;++_)for(n+=(o-n)*i,s.forEach(function(x){x(n)}),y=0;y<p;++y)m=e[y],m.fx==null?m.x+=m.vx*=a:(m.x=m.fx,m.vx=0),m.fy==null?m.y+=m.vy*=a:(m.y=m.fy,m.vy=0);return t}function h(){for(var v=0,y=e.length,p;v<y;++v){if(p=e[v],p.index=v,p.fx!=null&&(p.x=p.fx),p.fy!=null&&(p.y=p.fy),isNaN(p.x)||isNaN(p.y)){var m=xj*Math.sqrt(.5+v),_=v*wj;p.x=m*Math.cos(_),p.y=m*Math.sin(_)}(isNaN(p.vx)||isNaN(p.vy))&&(p.vx=p.vy=0)}}function g(v){return v.initialize&&v.initialize(e,c),v}return h(),t={tick:d,restart:function(){return u.restart(f),t},stop:function(){return u.stop(),t},nodes:function(v){return arguments.length?(e=v,h(),s.forEach(g),t):e},alpha:function(v){return arguments.length?(n=+v,t):n},alphaMin:function(v){return arguments.length?(r=+v,t):r},alphaDecay:function(v){return arguments.length?(i=+v,t):+i},alphaTarget:function(v){return arguments.length?(o=+v,t):o},velocityDecay:function(v){return arguments.length?(a=1-v,t):1-a},randomSource:function(v){return arguments.length?(c=v,s.forEach(g),t):c},force:function(v,y){return arguments.length>1?(y==null?s.delete(v):s.set(v,g(y)),t):s.get(v)},find:function(v,y,p){var m=0,_=e.length,x,S,E,C,T;for(p==null?p=1/0:p*=p,m=0;m<_;++m)C=e[m],x=v-C.x,S=y-C.y,E=x*x+S*S,E<p&&(T=C,p=E);return T},on:function(v,y){return arguments.length>1?(l.on(v,y),t):l.on(v)}}}function Ej(){var e,t,n,r,i=Gn(-30),o,a=1,s=1/0,u=.81;function l(h){var g,v=e.length,y=xv(e,yj,_j).visitAfter(f);for(r=h,g=0;g<v;++g)t=e[g],y.visit(d)}function c(){if(e){var h,g=e.length,v;for(o=new Array(g),h=0;h<g;++h)v=e[h],o[v.index]=+i(v,h,e)}}function f(h){var g=0,v,y,p=0,m,_,x;if(h.length){for(m=_=x=0;x<4;++x)(v=h[x])&&(y=Math.abs(v.value))&&(g+=v.value,p+=y,m+=y*v.x,_+=y*v.y);h.x=m/p,h.y=_/p}else{v=h,v.x=v.data.x,v.y=v.data.y;do g+=o[v.data.index];while(v=v.next)}h.value=g}function d(h,g,v,y){if(!h.value)return!0;var p=h.x-t.x,m=h.y-t.y,_=y-g,x=p*p+m*m;if(_*_/u<x)return x<s&&(p===0&&(p=hn(n),x+=p*p),m===0&&(m=hn(n),x+=m*m),x<a&&(x=Math.sqrt(a*x)),t.vx+=p*h.value*r/x,t.vy+=m*h.value*r/x),!0;if(h.length||x>=s)return;(h.data!==t||h.next)&&(p===0&&(p=hn(n),x+=p*p),m===0&&(m=hn(n),x+=m*m),x<a&&(x=Math.sqrt(a*x)));do h.data!==t&&(_=o[h.data.index]*r/x,t.vx+=p*_,t.vy+=m*_);while(h=h.next)}return l.initialize=function(h,g){e=h,n=g,c()},l.strength=function(h){return arguments.length?(i=typeof h=="function"?h:Gn(+h),c(),l):i},l.distanceMin=function(h){return arguments.length?(a=h*h,l):Math.sqrt(a)},l.distanceMax=function(h){return arguments.length?(s=h*h,l):Math.sqrt(s)},l.theta=function(h){return arguments.length?(u=h*h,l):Math.sqrt(u)},l}function fr(e){return function(){return e}}function Cj(e){let t=3;return e.digits=function(n){if(!arguments.length)return t;if(n==null)t=null;else{const r=Math.floor(n);if(!(r>=0))throw new RangeError(`invalid digits: ${n}`);t=r}return e},()=>new GP(t)}function kj(e){return typeof e=="object"&&"length"in e?e:Array.from(e)}function DE(e){this._context=e}DE.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;default:this._context.lineTo(e,t);break}}};function bj(e){return new DE(e)}function Tj(e){return e[0]}function Rj(e){return e[1]}function Nj(e,t){var n=fr(!0),r=null,i=bj,o=null,a=Cj(s);e=typeof e=="function"?e:e===void 0?Tj:fr(e),t=typeof t=="function"?t:t===void 0?Rj:fr(t);function s(u){var l,c=(u=kj(u)).length,f,d=!1,h;for(r==null&&(o=i(h=a())),l=0;l<=c;++l)!(l<c&&n(f=u[l],l,u))===d&&((d=!d)?o.lineStart():o.lineEnd()),d&&o.point(+e(f,l,u),+t(f,l,u));if(h)return o=null,h+""||null}return s.x=function(u){return arguments.length?(e=typeof u=="function"?u:fr(+u),s):e},s.y=function(u){return arguments.length?(t=typeof u=="function"?u:fr(+u),s):t},s.defined=function(u){return arguments.length?(n=typeof u=="function"?u:fr(!!u),s):n},s.curve=function(u){return arguments.length?(i=u,r!=null&&(o=i(r)),s):i},s.context=function(u){return arguments.length?(u==null?r=o=null:o=i(r=u),s):r},s}function qm(e,t,n){e._context.bezierCurveTo((2*e._x0+e._x1)/3,(2*e._y0+e._y1)/3,(e._x0+2*e._x1)/3,(e._y0+2*e._y1)/3,(e._x0+4*e._x1+t)/6,(e._y0+4*e._y1+n)/6)}function $E(e){this._context=e}$E.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:qm(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:qm(this,e,t);break}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t}};function Ij(e){return new $E(e)}const Ho=e=>()=>e;function Pj(e,{sourceEvent:t,target:n,transform:r,dispatch:i}){Object.defineProperties(this,{type:{value:e,enumerable:!0,configurable:!0},sourceEvent:{value:t,enumerable:!0,configurable:!0},target:{value:n,enumerable:!0,configurable:!0},transform:{value:r,enumerable:!0,configurable:!0},_:{value:i}})}function Dt(e,t,n){this.k=e,this.x=t,this.y=n}Dt.prototype={constructor:Dt,scale:function(e){return e===1?this:new Dt(this.k*e,this.x,this.y)},translate:function(e,t){return e===0&t===0?this:new Dt(this.k,this.x+this.k*e,this.y+this.k*t)},apply:function(e){return[e[0]*this.k+this.x,e[1]*this.k+this.y]},applyX:function(e){return e*this.k+this.x},applyY:function(e){return e*this.k+this.y},invert:function(e){return[(e[0]-this.x)/this.k,(e[1]-this.y)/this.k]},invertX:function(e){return(e-this.x)/this.k},invertY:function(e){return(e-this.y)/this.k},rescaleX:function(e){return e.copy().domain(e.range().map(this.invertX,this).map(e.invert,e))},rescaleY:function(e){return e.copy().domain(e.range().map(this.invertY,this).map(e.invert,e))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};var Sv=new Dt(1,0,0);Dt.prototype;function su(e){e.stopImmediatePropagation()}function fi(e){e.preventDefault(),e.stopImmediatePropagation()}function jj(e){return(!e.ctrlKey||e.type==="wheel")&&!e.button}function qj(){var e=this;return e instanceof SVGElement?(e=e.ownerSVGElement||e,e.hasAttribute("viewBox")?(e=e.viewBox.baseVal,[[e.x,e.y],[e.x+e.width,e.y+e.height]]):[[0,0],[e.width.baseVal.value,e.height.baseVal.value]]):[[0,0],[e.clientWidth,e.clientHeight]]}function Am(){return this.__zoom||Sv}function Aj(e){return-e.deltaY*(e.deltaMode===1?.05:e.deltaMode?1:.002)*(e.ctrlKey?10:1)}function Mj(){return navigator.maxTouchPoints||"ontouchstart"in this}function Lj(e,t,n){var r=e.invertX(t[0][0])-n[0][0],i=e.invertX(t[1][0])-n[1][0],o=e.invertY(t[0][1])-n[0][1],a=e.invertY(t[1][1])-n[1][1];return e.translate(i>r?(r+i)/2:Math.min(0,r)||Math.max(0,i),a>o?(o+a)/2:Math.min(0,o)||Math.max(0,a))}function BE(){var e=jj,t=qj,n=Lj,r=Aj,i=Mj,o=[0,1/0],a=[[-1/0,-1/0],[1/0,1/0]],s=250,u=jI,l=lo("start","zoom","end"),c,f,d,h=500,g=150,v=0,y=10;function p(b){b.property("__zoom",Am).on("wheel.zoom",T,{passive:!1}).on("mousedown.zoom",M).on("dblclick.zoom",k).filter(i).on("touchstart.zoom",j).on("touchmove.zoom",B).on("touchend.zoom touchcancel.zoom",H).style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}p.transform=function(b,P,R,O){var I=b.selection?b.selection():b;I.property("__zoom",Am),b!==I?S(b,P,R,O):I.interrupt().each(function(){E(this,arguments).event(O).start().zoom(null,typeof P=="function"?P.apply(this,arguments):P).end()})},p.scaleBy=function(b,P,R,O){p.scaleTo(b,function(){var I=this.__zoom.k,A=typeof P=="function"?P.apply(this,arguments):P;return I*A},R,O)},p.scaleTo=function(b,P,R,O){p.transform(b,function(){var I=t.apply(this,arguments),A=this.__zoom,L=R==null?x(I):typeof R=="function"?R.apply(this,arguments):R,F=A.invert(L),U=typeof P=="function"?P.apply(this,arguments):P;return n(_(m(A,U),L,F),I,a)},R,O)},p.translateBy=function(b,P,R,O){p.transform(b,function(){return n(this.__zoom.translate(typeof P=="function"?P.apply(this,arguments):P,typeof R=="function"?R.apply(this,arguments):R),t.apply(this,arguments),a)},null,O)},p.translateTo=function(b,P,R,O,I){p.transform(b,function(){var A=t.apply(this,arguments),L=this.__zoom,F=O==null?x(A):typeof O=="function"?O.apply(this,arguments):O;return n(Sv.translate(F[0],F[1]).scale(L.k).translate(typeof P=="function"?-P.apply(this,arguments):-P,typeof R=="function"?-R.apply(this,arguments):-R),A,a)},O,I)};function m(b,P){return P=Math.max(o[0],Math.min(o[1],P)),P===b.k?b:new Dt(P,b.x,b.y)}function _(b,P,R){var O=P[0]-R[0]*b.k,I=P[1]-R[1]*b.k;return O===b.x&&I===b.y?b:new Dt(b.k,O,I)}function x(b){return[(+b[0][0]+ +b[1][0])/2,(+b[0][1]+ +b[1][1])/2]}function S(b,P,R,O){b.on("start.zoom",function(){E(this,arguments).event(O).start()}).on("interrupt.zoom end.zoom",function(){E(this,arguments).event(O).end()}).tween("zoom",function(){var I=this,A=arguments,L=E(I,A).event(O),F=t.apply(I,A),U=R==null?x(F):typeof R=="function"?R.apply(I,A):R,Ee=Math.max(F[1][0]-F[0][0],F[1][1]-F[0][1]),J=I.__zoom,Ce=typeof P=="function"?P.apply(I,A):P,me=u(J.invert(U).concat(Ee/J.k),Ce.invert(U).concat(Ee/Ce.k));return function(xe){if(xe===1)xe=Ce;else{var ft=me(xe),ti=Ee/ft[2];xe=new Dt(ti,U[0]-ft[0]*ti,U[1]-ft[1]*ti)}L.zoom(null,xe)}})}function E(b,P,R){return!R&&b.__zooming||new C(b,P)}function C(b,P){this.that=b,this.args=P,this.active=0,this.sourceEvent=null,this.extent=t.apply(b,P),this.taps=0}C.prototype={event:function(b){return b&&(this.sourceEvent=b),this},start:function(){return++this.active===1&&(this.that.__zooming=this,this.emit("start")),this},zoom:function(b,P){return this.mouse&&b!=="mouse"&&(this.mouse[1]=P.invert(this.mouse[0])),this.touch0&&b!=="touch"&&(this.touch0[1]=P.invert(this.touch0[0])),this.touch1&&b!=="touch"&&(this.touch1[1]=P.invert(this.touch1[0])),this.that.__zoom=P,this.emit("zoom"),this},end:function(){return--this.active===0&&(delete this.that.__zooming,this.emit("end")),this},emit:function(b){var P=De(this.that).datum();l.call(b,this.that,new Pj(b,{sourceEvent:this.sourceEvent,target:p,transform:this.that.__zoom,dispatch:l}),P)}};function T(b,...P){if(!e.apply(this,arguments))return;var R=E(this,P).event(b),O=this.__zoom,I=Math.max(o[0],Math.min(o[1],O.k*Math.pow(2,r.apply(this,arguments)))),A=Lt(b);if(R.wheel)(R.mouse[0][0]!==A[0]||R.mouse[0][1]!==A[1])&&(R.mouse[1]=O.invert(R.mouse[0]=A)),clearTimeout(R.wheel);else{if(O.k===I)return;R.mouse=[A,O.invert(A)],ua(this),R.start()}fi(b),R.wheel=setTimeout(L,g),R.zoom("mouse",n(_(m(O,I),R.mouse[0],R.mouse[1]),R.extent,a));function L(){R.wheel=null,R.end()}}function M(b,...P){if(d||!e.apply(this,arguments))return;var R=b.currentTarget,O=E(this,P,!0).event(b),I=De(b.view).on("mousemove.zoom",U,!0).on("mouseup.zoom",Ee,!0),A=Lt(b,R),L=b.clientX,F=b.clientY;CE(b.view),su(b),O.mouse=[A,this.__zoom.invert(A)],ua(this),O.start();function U(J){if(fi(J),!O.moved){var Ce=J.clientX-L,me=J.clientY-F;O.moved=Ce*Ce+me*me>v}O.event(J).zoom("mouse",n(_(O.that.__zoom,O.mouse[0]=Lt(J,R),O.mouse[1]),O.extent,a))}function Ee(J){I.on("mousemove.zoom mouseup.zoom",null),kE(J.view,O.moved),fi(J),O.event(J).end()}}function k(b,...P){if(e.apply(this,arguments)){var R=this.__zoom,O=Lt(b.changedTouches?b.changedTouches[0]:b,this),I=R.invert(O),A=R.k*(b.shiftKey?.5:2),L=n(_(m(R,A),O,I),t.apply(this,P),a);fi(b),s>0?De(this).transition().duration(s).call(S,L,O,b):De(this).call(p.transform,L,O,b)}}function j(b,...P){if(e.apply(this,arguments)){var R=b.touches,O=R.length,I=E(this,P,b.changedTouches.length===O).event(b),A,L,F,U;for(su(b),L=0;L<O;++L)F=R[L],U=Lt(F,this),U=[U,this.__zoom.invert(U),F.identifier],I.touch0?!I.touch1&&I.touch0[2]!==U[2]&&(I.touch1=U,I.taps=0):(I.touch0=U,A=!0,I.taps=1+!!c);c&&(c=clearTimeout(c)),A&&(I.taps<2&&(f=U[0],c=setTimeout(function(){c=null},h)),ua(this),I.start())}}function B(b,...P){if(this.__zooming){var R=E(this,P).event(b),O=b.changedTouches,I=O.length,A,L,F,U;for(fi(b),A=0;A<I;++A)L=O[A],F=Lt(L,this),R.touch0&&R.touch0[2]===L.identifier?R.touch0[0]=F:R.touch1&&R.touch1[2]===L.identifier&&(R.touch1[0]=F);if(L=R.that.__zoom,R.touch1){var Ee=R.touch0[0],J=R.touch0[1],Ce=R.touch1[0],me=R.touch1[1],xe=(xe=Ce[0]-Ee[0])*xe+(xe=Ce[1]-Ee[1])*xe,ft=(ft=me[0]-J[0])*ft+(ft=me[1]-J[1])*ft;L=m(L,Math.sqrt(xe/ft)),F=[(Ee[0]+Ce[0])/2,(Ee[1]+Ce[1])/2],U=[(J[0]+me[0])/2,(J[1]+me[1])/2]}else if(R.touch0)F=R.touch0[0],U=R.touch0[1];else return;R.zoom("touch",n(_(L,F,U),R.extent,a))}}function H(b,...P){if(this.__zooming){var R=E(this,P).event(b),O=b.changedTouches,I=O.length,A,L;for(su(b),d&&clearTimeout(d),d=setTimeout(function(){d=null},h),A=0;A<I;++A)L=O[A],R.touch0&&R.touch0[2]===L.identifier?delete R.touch0:R.touch1&&R.touch1[2]===L.identifier&&delete R.touch1;if(R.touch1&&!R.touch0&&(R.touch0=R.touch1,delete R.touch1),R.touch0)R.touch0[1]=this.__zoom.invert(R.touch0[0]);else if(R.end(),R.taps===2&&(L=Lt(L,this),Math.hypot(f[0]-L[0],f[1]-L[1])<y)){var F=De(this).on("dblclick.zoom");F&&F.apply(this,arguments)}}}return p.wheelDelta=function(b){return arguments.length?(r=typeof b=="function"?b:Ho(+b),p):r},p.filter=function(b){return arguments.length?(e=typeof b=="function"?b:Ho(!!b),p):e},p.touchable=function(b){return arguments.length?(i=typeof b=="function"?b:Ho(!!b),p):i},p.extent=function(b){return arguments.length?(t=typeof b=="function"?b:Ho([[+b[0][0],+b[0][1]],[+b[1][0],+b[1][1]]]),p):t},p.scaleExtent=function(b){return arguments.length?(o[0]=+b[0],o[1]=+b[1],p):[o[0],o[1]]},p.translateExtent=function(b){return arguments.length?(a[0][0]=+b[0][0],a[1][0]=+b[1][0],a[0][1]=+b[0][1],a[1][1]=+b[1][1],p):[[a[0][0],a[0][1]],[a[1][0],a[1][1]]]},p.constrain=function(b){return arguments.length?(n=b,p):n},p.duration=function(b){return arguments.length?(s=+b,p):s},p.interpolate=function(b){return arguments.length?(u=b,p):u},p.on=function(){var b=l.on.apply(l,arguments);return b===l?p:b},p.clickDistance=function(b){return arguments.length?(v=(b=+b)*b,p):Math.sqrt(v)},p.tapDistance=function(b){return arguments.length?(y=+b,p):y},p}const Oj=({value:e,onChange:t,showAll:n=!0})=>{const r=n?["all",...fm]:[...fm];return w.jsx("div",{style:uu.container,children:r.map(i=>w.jsx("button",{onClick:()=>t(i),style:{...uu.button,...e===i?uu.buttonActive:{},...i!=="all"?{borderLeftColor:It(i)}:{}},children:i==="all"?"All":i.charAt(0).toUpperCase()+i.slice(1)},i))})},uu={container:{display:"flex",gap:"4px",flexWrap:"wrap"},button:{padding:"6px 12px",fontSize:"11px",border:"none",borderLeft:"3px solid transparent",backgroundColor:"#1a1a2e",color:"#888",borderRadius:"4px",cursor:"pointer",transition:"all 0.2s"},buttonActive:{backgroundColor:"#0f3460",color:"#00d9ff"}},zj=({graphData:e})=>{const t=N.useRef(null),n=N.useRef(null),[r,i]=N.useState(null),[o,a]=N.useState("all"),[s,u]=N.useState(""),l=N.useRef(null),c=N.useCallback(g=>{i(g)},[]),f=N.useCallback(g=>{const v=e.nodes.find(y=>y.id===g);v&&i(v)},[e.nodes]),d=N.useCallback(()=>{i(null)},[]);N.useEffect(()=>{if(!t.current||!n.current)return;const g=De(t.current),v=n.current,y=v.clientWidth,p=v.clientHeight;g.selectAll("*").remove();const m=g.append("g"),_=BE().scaleExtent([.1,4]).on("zoom",k=>m.attr("transform",k.transform));g.call(_);const x=e.nodes.map(k=>({...k})),S=new Map(x.map(k=>[k.id,k])),E=e.edges.map(k=>({source:S.get(k.from_node_id),target:S.get(k.to_node_id),type:k.edge_type,rationale:k.rationale})).filter(k=>k.source&&k.target),C=Sj(x).force("link",pj(E).id(k=>k.id).distance(80)).force("charge",Ej().strength(-200)).force("center",WP(y/2,p/2)).force("collision",dj().radius(30));l.current=C;const T=m.append("g").selectAll("line").data(E).join("line").attr("class","link").attr("stroke",k=>k.type==="chosen"?"#22c55e":k.type==="rejected"?"#ef4444":"#3b82f6").attr("stroke-width",1.5).attr("stroke-opacity",.6).attr("stroke-dasharray",k=>k.type==="rejected"?"5,5":null),M=m.append("g").selectAll(".node").data(x).join("g").attr("class","node").style("cursor","pointer").call(aI().on("start",(k,j)=>{k.active||C.alphaTarget(.3).restart(),j.fx=j.x,j.fy=j.y}).on("drag",(k,j)=>{j.fx=k.x,j.fy=k.y}).on("end",(k,j)=>{k.active||C.alphaTarget(0),j.fx=null,j.fy=null}));return M.append("circle").attr("r",k=>k.node_type==="goal"?18:k.node_type==="decision"?15:12).attr("fill",k=>It(k.node_type)).attr("stroke","#fff").attr("stroke-width",2),M.filter(k=>k.node_type==="goal"||k.node_type==="decision").append("text").attr("dy",30).attr("text-anchor","middle").attr("fill","#888").attr("font-size","10px").text(k=>ut(k.title,20)),M.on("click",(k,j)=>{c(j)}),M.append("title").text(k=>{const j=$r(k);return`${k.title} 76 - ${k.node_type}${j!==null?` · ${j}%`:""}`}),C.on("tick",()=>{T.attr("x1",k=>k.source.x).attr("y1",k=>k.source.y).attr("x2",k=>k.target.x).attr("y2",k=>k.target.y),M.attr("transform",k=>`translate(${k.x},${k.y})`)}),()=>{C.stop()}},[e,c]),N.useEffect(()=>{if(!t.current)return;const g=De(t.current),v=s.toLowerCase();g.selectAll(".node").style("opacity",y=>{var p;return s&&!(y.title.toLowerCase().includes(v)||(((p=y.description)==null?void 0:p.toLowerCase().includes(v))??!1))||o!=="all"&&y.node_type!==o?.15:1})},[o,s]),N.useEffect(()=>{if(!t.current)return;const g=De(t.current);g.selectAll(".node").classed("selected",v=>v.id===(r==null?void 0:r.id)),g.selectAll(".link").attr("stroke-width",v=>v.source.id===(r==null?void 0:r.id)||v.target.id===(r==null?void 0:r.id)?3:1.5).attr("stroke-opacity",v=>v.source.id===(r==null?void 0:r.id)||v.target.id===(r==null?void 0:r.id)?1:.6)},[r]);const h=r?JT(r.id,e):[];return w.jsxs("div",{style:ee.container,children:[w.jsxs("div",{style:ee.controls,children:[w.jsx("h2",{style:ee.title,children:"Graph Explorer"}),w.jsx(Oj,{value:o,onChange:a}),w.jsx("input",{type:"text",placeholder:"Search nodes...",value:s,onChange:g=>u(g.target.value),style:ee.search}),w.jsx("div",{style:ee.legend,children:Object.entries(dv).map(([g,v])=>w.jsxs("div",{style:ee.legendItem,children:[w.jsx("div",{style:{...ee.legendDot,backgroundColor:v}}),w.jsx("span",{children:g.charAt(0).toUpperCase()+g.slice(1)})]},g))})]}),w.jsx("div",{ref:n,style:ee.svgContainer,children:w.jsx("svg",{ref:t,style:ee.svg})}),r&&w.jsxs("div",{style:ee.detailPanel,children:[w.jsx("button",{onClick:d,style:ee.closeBtn,children:"×"}),w.jsxs("div",{style:ee.detailHeader,children:[w.jsx(Ge,{type:r.node_type}),w.jsx(uo,{confidence:$r(r)}),w.jsx(Br,{commit:bn(r)})]}),w.jsx("h3",{style:ee.detailTitle,children:r.title}),w.jsxs("p",{style:ee.detailMeta,children:["Node #",r.id," · ",new Date(r.created_at).toLocaleString()]}),r.description&&w.jsxs("div",{style:ee.detailSection,children:[w.jsx("h4",{style:ee.sectionTitle,children:"Description"}),w.jsx("p",{style:ee.description,children:r.description})]}),h.length>1&&w.jsxs("div",{style:ee.detailSection,children:[w.jsx("h4",{style:ee.sectionTitle,children:"Path to Root"}),h.map(g=>w.jsxs("div",{onClick:()=>f(g.id),style:ee.pathNode,children:[w.jsx(Ge,{type:g.node_type,size:"sm"}),w.jsx("span",{children:ut(g.title,35)})]},g.id))]}),w.jsx(Fj,{node:r,graphData:e,onSelectNode:f})]})]})},Fj=({node:e,graphData:t,onSelectNode:n})=>{const r=t.edges.filter(a=>a.to_node_id===e.id),i=t.edges.filter(a=>a.from_node_id===e.id),o=a=>t.nodes.find(s=>s.id===a);return w.jsxs(w.Fragment,{children:[r.length>0&&w.jsxs("div",{style:ee.detailSection,children:[w.jsxs("h4",{style:ee.sectionTitle,children:["Incoming (",r.length,")"]}),r.map(a=>{const s=o(a.from_node_id);return w.jsxs("div",{onClick:()=>n(a.from_node_id),style:ee.connection,children:[w.jsx(Ge,{type:(s==null?void 0:s.node_type)||"observation",size:"sm"}),w.jsx("span",{children:ut((s==null?void 0:s.title)||"Unknown",30)})]},a.id)})]}),i.length>0&&w.jsxs("div",{style:ee.detailSection,children:[w.jsxs("h4",{style:ee.sectionTitle,children:["Outgoing (",i.length,")"]}),i.map(a=>{const s=o(a.to_node_id);return w.jsxs("div",{onClick:()=>n(a.to_node_id),style:ee.connection,children:[w.jsx(Aa,{type:a.edge_type}),w.jsx(Ge,{type:(s==null?void 0:s.node_type)||"observation",size:"sm"}),w.jsx("span",{children:ut((s==null?void 0:s.title)||"Unknown",25)}),a.rationale&&w.jsx("span",{style:ee.rationale,children:a.rationale})]},a.id)})]})]})},ee={container:{height:"100%",display:"flex",position:"relative",backgroundColor:"#0d1117"},controls:{position:"absolute",top:"20px",left:"20px",backgroundColor:"#16213e",padding:"15px",borderRadius:"8px",zIndex:10,maxWidth:"250px"},title:{fontSize:"16px",margin:"0 0 12px 0",color:"#eee"},search:{width:"100%",padding:"8px 12px",marginTop:"12px",backgroundColor:"#1a1a2e",border:"1px solid #333",borderRadius:"4px",color:"#eee",fontSize:"13px"},legend:{marginTop:"15px",display:"flex",flexDirection:"column",gap:"6px"},legendItem:{display:"flex",alignItems:"center",gap:"8px",fontSize:"11px",color:"#888"},legendDot:{width:"10px",height:"10px",borderRadius:"50%"},svgContainer:{flex:1,height:"100%"},svg:{width:"100%",height:"100%"},detailPanel:{position:"absolute",top:"20px",right:"20px",bottom:"20px",width:"350px",backgroundColor:"#16213e",borderRadius:"8px",padding:"20px",overflowY:"auto",zIndex:10},closeBtn:{position:"absolute",top:"10px",right:"10px",width:"28px",height:"28px",border:"none",background:"#333",color:"#fff",borderRadius:"4px",fontSize:"18px",cursor:"pointer"},detailHeader:{display:"flex",gap:"8px",marginBottom:"10px",flexWrap:"wrap"},detailTitle:{fontSize:"16px",margin:"0 0 8px 0",color:"#eee"},detailMeta:{fontSize:"12px",color:"#888",margin:0},detailSection:{marginTop:"20px"},sectionTitle:{fontSize:"12px",color:"#888",margin:"0 0 10px 0",textTransform:"uppercase"},description:{fontSize:"13px",color:"#ccc",lineHeight:1.5,margin:0},pathNode:{display:"flex",alignItems:"center",gap:"8px",padding:"8px",backgroundColor:"#1a1a2e",borderRadius:"4px",marginBottom:"6px",cursor:"pointer",fontSize:"12px"},connection:{display:"flex",alignItems:"center",gap:"8px",padding:"8px",backgroundColor:"#1a1a2e",borderRadius:"4px",marginBottom:"6px",cursor:"pointer",fontSize:"12px"},rationale:{color:"#666",fontSize:"11px",marginLeft:"auto"}};function Ev(e){throw new Error('Could not dynamically require "'+e+'". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.')}var lu,Mm;function Dj(){if(Mm)return lu;Mm=1;function e(){this.__data__=[],this.size=0}return lu=e,lu}var cu,Lm;function Qr(){if(Lm)return cu;Lm=1;function e(t,n){return t===n||t!==t&&n!==n}return cu=e,cu}var fu,Om;function ds(){if(Om)return fu;Om=1;var e=Qr();function t(n,r){for(var i=n.length;i--;)if(e(n[i][0],r))return i;return-1}return fu=t,fu}var du,zm;function $j(){if(zm)return du;zm=1;var e=ds(),t=Array.prototype,n=t.splice;function r(i){var o=this.__data__,a=e(o,i);if(a<0)return!1;var s=o.length-1;return a==s?o.pop():n.call(o,a,1),--this.size,!0}return du=r,du}var hu,Fm;function Bj(){if(Fm)return hu;Fm=1;var e=ds();function t(n){var r=this.__data__,i=e(r,n);return i<0?void 0:r[i][1]}return hu=t,hu}var pu,Dm;function Uj(){if(Dm)return pu;Dm=1;var e=ds();function t(n){return e(this.__data__,n)>-1}return pu=t,pu}var vu,$m;function Hj(){if($m)return vu;$m=1;var e=ds();function t(n,r){var i=this.__data__,o=e(i,n);return o<0?(++this.size,i.push([n,r])):i[o][1]=r,this}return vu=t,vu}var gu,Bm;function hs(){if(Bm)return gu;Bm=1;var e=Dj(),t=$j(),n=Bj(),r=Uj(),i=Hj();function o(a){var s=-1,u=a==null?0:a.length;for(this.clear();++s<u;){var l=a[s];this.set(l[0],l[1])}}return o.prototype.clear=e,o.prototype.delete=t,o.prototype.get=n,o.prototype.has=r,o.prototype.set=i,gu=o,gu}var mu,Um;function Vj(){if(Um)return mu;Um=1;var e=hs();function t(){this.__data__=new e,this.size=0}return mu=t,mu}var yu,Hm;function Gj(){if(Hm)return yu;Hm=1;function e(t){var n=this.__data__,r=n.delete(t);return this.size=n.size,r}return yu=e,yu}var _u,Vm;function Wj(){if(Vm)return _u;Vm=1;function e(t){return this.__data__.get(t)}return _u=e,_u}var xu,Gm;function Kj(){if(Gm)return xu;Gm=1;function e(t){return this.__data__.has(t)}return xu=e,xu}var wu,Wm;function UE(){if(Wm)return wu;Wm=1;var e=typeof So=="object"&&So&&So.Object===Object&&So;return wu=e,wu}var Su,Km;function wt(){if(Km)return Su;Km=1;var e=UE(),t=typeof self=="object"&&self&&self.Object===Object&&self,n=e||t||Function("return this")();return Su=n,Su}var Eu,Ym;function Xr(){if(Ym)return Eu;Ym=1;var e=wt(),t=e.Symbol;return Eu=t,Eu}var Cu,Qm;function Yj(){if(Qm)return Cu;Qm=1;var e=Xr(),t=Object.prototype,n=t.hasOwnProperty,r=t.toString,i=e?e.toStringTag:void 0;function o(a){var s=n.call(a,i),u=a[i];try{a[i]=void 0;var l=!0}catch{}var c=r.call(a);return l&&(s?a[i]=u:delete a[i]),c}return Cu=o,Cu}var ku,Xm;function Qj(){if(Xm)return ku;Xm=1;var e=Object.prototype,t=e.toString;function n(r){return t.call(r)}return ku=n,ku}var bu,Zm;function nr(){if(Zm)return bu;Zm=1;var e=Xr(),t=Yj(),n=Qj(),r="[object Null]",i="[object Undefined]",o=e?e.toStringTag:void 0;function a(s){return s==null?s===void 0?i:r:o&&o in Object(s)?t(s):n(s)}return bu=a,bu}var Tu,Jm;function lt(){if(Jm)return Tu;Jm=1;function e(t){var n=typeof t;return t!=null&&(n=="object"||n=="function")}return Tu=e,Tu}var Ru,ey;function ho(){if(ey)return Ru;ey=1;var e=nr(),t=lt(),n="[object AsyncFunction]",r="[object Function]",i="[object GeneratorFunction]",o="[object Proxy]";function a(s){if(!t(s))return!1;var u=e(s);return u==r||u==i||u==n||u==o}return Ru=a,Ru}var Nu,ty;function Xj(){if(ty)return Nu;ty=1;var e=wt(),t=e["__core-js_shared__"];return Nu=t,Nu}var Iu,ny;function Zj(){if(ny)return Iu;ny=1;var e=Xj(),t=function(){var r=/[^.]+$/.exec(e&&e.keys&&e.keys.IE_PROTO||"");return r?"Symbol(src)_1."+r:""}();function n(r){return!!t&&t in r}return Iu=n,Iu}var Pu,ry;function HE(){if(ry)return Pu;ry=1;var e=Function.prototype,t=e.toString;function n(r){if(r!=null){try{return t.call(r)}catch{}try{return r+""}catch{}}return""}return Pu=n,Pu}var ju,iy;function Jj(){if(iy)return ju;iy=1;var e=ho(),t=Zj(),n=lt(),r=HE(),i=/[\\^$.*+?()[\]{}|]/g,o=/^\[object .+?Constructor\]$/,a=Function.prototype,s=Object.prototype,u=a.toString,l=s.hasOwnProperty,c=RegExp("^"+u.call(l).replace(i,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function f(d){if(!n(d)||t(d))return!1;var h=e(d)?c:o;return h.test(r(d))}return ju=f,ju}var qu,oy;function e3(){if(oy)return qu;oy=1;function e(t,n){return t==null?void 0:t[n]}return qu=e,qu}var Au,ay;function rr(){if(ay)return Au;ay=1;var e=Jj(),t=e3();function n(r,i){var o=t(r,i);return e(o)?o:void 0}return Au=n,Au}var Mu,sy;function Cv(){if(sy)return Mu;sy=1;var e=rr(),t=wt(),n=e(t,"Map");return Mu=n,Mu}var Lu,uy;function ps(){if(uy)return Lu;uy=1;var e=rr(),t=e(Object,"create");return Lu=t,Lu}var Ou,ly;function t3(){if(ly)return Ou;ly=1;var e=ps();function t(){this.__data__=e?e(null):{},this.size=0}return Ou=t,Ou}var zu,cy;function n3(){if(cy)return zu;cy=1;function e(t){var n=this.has(t)&&delete this.__data__[t];return this.size-=n?1:0,n}return zu=e,zu}var Fu,fy;function r3(){if(fy)return Fu;fy=1;var e=ps(),t="__lodash_hash_undefined__",n=Object.prototype,r=n.hasOwnProperty;function i(o){var a=this.__data__;if(e){var s=a[o];return s===t?void 0:s}return r.call(a,o)?a[o]:void 0}return Fu=i,Fu}var Du,dy;function i3(){if(dy)return Du;dy=1;var e=ps(),t=Object.prototype,n=t.hasOwnProperty;function r(i){var o=this.__data__;return e?o[i]!==void 0:n.call(o,i)}return Du=r,Du}var $u,hy;function o3(){if(hy)return $u;hy=1;var e=ps(),t="__lodash_hash_undefined__";function n(r,i){var o=this.__data__;return this.size+=this.has(r)?0:1,o[r]=e&&i===void 0?t:i,this}return $u=n,$u}var Bu,py;function a3(){if(py)return Bu;py=1;var e=t3(),t=n3(),n=r3(),r=i3(),i=o3();function o(a){var s=-1,u=a==null?0:a.length;for(this.clear();++s<u;){var l=a[s];this.set(l[0],l[1])}}return o.prototype.clear=e,o.prototype.delete=t,o.prototype.get=n,o.prototype.has=r,o.prototype.set=i,Bu=o,Bu}var Uu,vy;function s3(){if(vy)return Uu;vy=1;var e=a3(),t=hs(),n=Cv();function r(){this.size=0,this.__data__={hash:new e,map:new(n||t),string:new e}}return Uu=r,Uu}var Hu,gy;function u3(){if(gy)return Hu;gy=1;function e(t){var n=typeof t;return n=="string"||n=="number"||n=="symbol"||n=="boolean"?t!=="__proto__":t===null}return Hu=e,Hu}var Vu,my;function vs(){if(my)return Vu;my=1;var e=u3();function t(n,r){var i=n.__data__;return e(r)?i[typeof r=="string"?"string":"hash"]:i.map}return Vu=t,Vu}var Gu,yy;function l3(){if(yy)return Gu;yy=1;var e=vs();function t(n){var r=e(this,n).delete(n);return this.size-=r?1:0,r}return Gu=t,Gu}var Wu,_y;function c3(){if(_y)return Wu;_y=1;var e=vs();function t(n){return e(this,n).get(n)}return Wu=t,Wu}var Ku,xy;function f3(){if(xy)return Ku;xy=1;var e=vs();function t(n){return e(this,n).has(n)}return Ku=t,Ku}var Yu,wy;function d3(){if(wy)return Yu;wy=1;var e=vs();function t(n,r){var i=e(this,n),o=i.size;return i.set(n,r),this.size+=i.size==o?0:1,this}return Yu=t,Yu}var Qu,Sy;function kv(){if(Sy)return Qu;Sy=1;var e=s3(),t=l3(),n=c3(),r=f3(),i=d3();function o(a){var s=-1,u=a==null?0:a.length;for(this.clear();++s<u;){var l=a[s];this.set(l[0],l[1])}}return o.prototype.clear=e,o.prototype.delete=t,o.prototype.get=n,o.prototype.has=r,o.prototype.set=i,Qu=o,Qu}var Xu,Ey;function h3(){if(Ey)return Xu;Ey=1;var e=hs(),t=Cv(),n=kv(),r=200;function i(o,a){var s=this.__data__;if(s instanceof e){var u=s.__data__;if(!t||u.length<r-1)return u.push([o,a]),this.size=++s.size,this;s=this.__data__=new n(u)}return s.set(o,a),this.size=s.size,this}return Xu=i,Xu}var Zu,Cy;function gs(){if(Cy)return Zu;Cy=1;var e=hs(),t=Vj(),n=Gj(),r=Wj(),i=Kj(),o=h3();function a(s){var u=this.__data__=new e(s);this.size=u.size}return a.prototype.clear=t,a.prototype.delete=n,a.prototype.get=r,a.prototype.has=i,a.prototype.set=o,Zu=a,Zu}var Ju,ky;function bv(){if(ky)return Ju;ky=1;function e(t,n){for(var r=-1,i=t==null?0:t.length;++r<i&&n(t[r],r,t)!==!1;);return t}return Ju=e,Ju}var el,by;function VE(){if(by)return el;by=1;var e=rr(),t=function(){try{var n=e(Object,"defineProperty");return n({},"",{}),n}catch{}}();return el=t,el}var tl,Ty;function ms(){if(Ty)return tl;Ty=1;var e=VE();function t(n,r,i){r=="__proto__"&&e?e(n,r,{configurable:!0,enumerable:!0,value:i,writable:!0}):n[r]=i}return tl=t,tl}var nl,Ry;function ys(){if(Ry)return nl;Ry=1;var e=ms(),t=Qr(),n=Object.prototype,r=n.hasOwnProperty;function i(o,a,s){var u=o[a];(!(r.call(o,a)&&t(u,s))||s===void 0&&!(a in o))&&e(o,a,s)}return nl=i,nl}var rl,Ny;function po(){if(Ny)return rl;Ny=1;var e=ys(),t=ms();function n(r,i,o,a){var s=!o;o||(o={});for(var u=-1,l=i.length;++u<l;){var c=i[u],f=a?a(o[c],r[c],c,o,r):void 0;f===void 0&&(f=r[c]),s?t(o,c,f):e(o,c,f)}return o}return rl=n,rl}var il,Iy;function p3(){if(Iy)return il;Iy=1;function e(t,n){for(var r=-1,i=Array(t);++r<t;)i[r]=n(r);return i}return il=e,il}var ol,Py;function jt(){if(Py)return ol;Py=1;function e(t){return t!=null&&typeof t=="object"}return ol=e,ol}var al,jy;function v3(){if(jy)return al;jy=1;var e=nr(),t=jt(),n="[object Arguments]";function r(i){return t(i)&&e(i)==n}return al=r,al}var sl,qy;function vo(){if(qy)return sl;qy=1;var e=v3(),t=jt(),n=Object.prototype,r=n.hasOwnProperty,i=n.propertyIsEnumerable,o=e(function(){return arguments}())?e:function(a){return t(a)&&r.call(a,"callee")&&!i.call(a,"callee")};return sl=o,sl}var ul,Ay;function ge(){if(Ay)return ul;Ay=1;var e=Array.isArray;return ul=e,ul}var yi={exports:{}},ll,My;function g3(){if(My)return ll;My=1;function e(){return!1}return ll=e,ll}yi.exports;var Ly;function Zr(){return Ly||(Ly=1,function(e,t){var n=wt(),r=g3(),i=t&&!t.nodeType&&t,o=i&&!0&&e&&!e.nodeType&&e,a=o&&o.exports===i,s=a?n.Buffer:void 0,u=s?s.isBuffer:void 0,l=u||r;e.exports=l}(yi,yi.exports)),yi.exports}var cl,Oy;function _s(){if(Oy)return cl;Oy=1;var e=9007199254740991,t=/^(?:0|[1-9]\d*)$/;function n(r,i){var o=typeof r;return i=i??e,!!i&&(o=="number"||o!="symbol"&&t.test(r))&&r>-1&&r%1==0&&r<i}return cl=n,cl}var fl,zy;function Tv(){if(zy)return fl;zy=1;var e=9007199254740991;function t(n){return typeof n=="number"&&n>-1&&n%1==0&&n<=e}return fl=t,fl}var dl,Fy;function m3(){if(Fy)return dl;Fy=1;var e=nr(),t=Tv(),n=jt(),r="[object Arguments]",i="[object Array]",o="[object Boolean]",a="[object Date]",s="[object Error]",u="[object Function]",l="[object Map]",c="[object Number]",f="[object Object]",d="[object RegExp]",h="[object Set]",g="[object String]",v="[object WeakMap]",y="[object ArrayBuffer]",p="[object DataView]",m="[object Float32Array]",_="[object Float64Array]",x="[object Int8Array]",S="[object Int16Array]",E="[object Int32Array]",C="[object Uint8Array]",T="[object Uint8ClampedArray]",M="[object Uint16Array]",k="[object Uint32Array]",j={};j[m]=j[_]=j[x]=j[S]=j[E]=j[C]=j[T]=j[M]=j[k]=!0,j[r]=j[i]=j[y]=j[o]=j[p]=j[a]=j[s]=j[u]=j[l]=j[c]=j[f]=j[d]=j[h]=j[g]=j[v]=!1;function B(H){return n(H)&&t(H.length)&&!!j[e(H)]}return dl=B,dl}var hl,Dy;function xs(){if(Dy)return hl;Dy=1;function e(t){return function(n){return t(n)}}return hl=e,hl}var _i={exports:{}};_i.exports;var $y;function Rv(){return $y||($y=1,function(e,t){var n=UE(),r=t&&!t.nodeType&&t,i=r&&!0&&e&&!e.nodeType&&e,o=i&&i.exports===r,a=o&&n.process,s=function(){try{var u=i&&i.require&&i.require("util").types;return u||a&&a.binding&&a.binding("util")}catch{}}();e.exports=s}(_i,_i.exports)),_i.exports}var pl,By;function go(){if(By)return pl;By=1;var e=m3(),t=xs(),n=Rv(),r=n&&n.isTypedArray,i=r?t(r):e;return pl=i,pl}var vl,Uy;function GE(){if(Uy)return vl;Uy=1;var e=p3(),t=vo(),n=ge(),r=Zr(),i=_s(),o=go(),a=Object.prototype,s=a.hasOwnProperty;function u(l,c){var f=n(l),d=!f&&t(l),h=!f&&!d&&r(l),g=!f&&!d&&!h&&o(l),v=f||d||h||g,y=v?e(l.length,String):[],p=y.length;for(var m in l)(c||s.call(l,m))&&!(v&&(m=="length"||h&&(m=="offset"||m=="parent")||g&&(m=="buffer"||m=="byteLength"||m=="byteOffset")||i(m,p)))&&y.push(m);return y}return vl=u,vl}var gl,Hy;function ws(){if(Hy)return gl;Hy=1;var e=Object.prototype;function t(n){var r=n&&n.constructor,i=typeof r=="function"&&r.prototype||e;return n===i}return gl=t,gl}var ml,Vy;function WE(){if(Vy)return ml;Vy=1;function e(t,n){return function(r){return t(n(r))}}return ml=e,ml}var yl,Gy;function y3(){if(Gy)return yl;Gy=1;var e=WE(),t=e(Object.keys,Object);return yl=t,yl}var _l,Wy;function Nv(){if(Wy)return _l;Wy=1;var e=ws(),t=y3(),n=Object.prototype,r=n.hasOwnProperty;function i(o){if(!e(o))return t(o);var a=[];for(var s in Object(o))r.call(o,s)&&s!="constructor"&&a.push(s);return a}return _l=i,_l}var xl,Ky;function Xt(){if(Ky)return xl;Ky=1;var e=ho(),t=Tv();function n(r){return r!=null&&t(r.length)&&!e(r)}return xl=n,xl}var wl,Yy;function qn(){if(Yy)return wl;Yy=1;var e=GE(),t=Nv(),n=Xt();function r(i){return n(i)?e(i):t(i)}return wl=r,wl}var Sl,Qy;function _3(){if(Qy)return Sl;Qy=1;var e=po(),t=qn();function n(r,i){return r&&e(i,t(i),r)}return Sl=n,Sl}var El,Xy;function x3(){if(Xy)return El;Xy=1;function e(t){var n=[];if(t!=null)for(var r in Object(t))n.push(r);return n}return El=e,El}var Cl,Zy;function w3(){if(Zy)return Cl;Zy=1;var e=lt(),t=ws(),n=x3(),r=Object.prototype,i=r.hasOwnProperty;function o(a){if(!e(a))return n(a);var s=t(a),u=[];for(var l in a)l=="constructor"&&(s||!i.call(a,l))||u.push(l);return u}return Cl=o,Cl}var kl,Jy;function ir(){if(Jy)return kl;Jy=1;var e=GE(),t=w3(),n=Xt();function r(i){return n(i)?e(i,!0):t(i)}return kl=r,kl}var bl,e0;function S3(){if(e0)return bl;e0=1;var e=po(),t=ir();function n(r,i){return r&&e(i,t(i),r)}return bl=n,bl}var xi={exports:{}};xi.exports;var t0;function KE(){return t0||(t0=1,function(e,t){var n=wt(),r=t&&!t.nodeType&&t,i=r&&!0&&e&&!e.nodeType&&e,o=i&&i.exports===r,a=o?n.Buffer:void 0,s=a?a.allocUnsafe:void 0;function u(l,c){if(c)return l.slice();var f=l.length,d=s?s(f):new l.constructor(f);return l.copy(d),d}e.exports=u}(xi,xi.exports)),xi.exports}var Tl,n0;function YE(){if(n0)return Tl;n0=1;function e(t,n){var r=-1,i=t.length;for(n||(n=Array(i));++r<i;)n[r]=t[r];return n}return Tl=e,Tl}var Rl,r0;function QE(){if(r0)return Rl;r0=1;function e(t,n){for(var r=-1,i=t==null?0:t.length,o=0,a=[];++r<i;){var s=t[r];n(s,r,t)&&(a[o++]=s)}return a}return Rl=e,Rl}var Nl,i0;function XE(){if(i0)return Nl;i0=1;function e(){return[]}return Nl=e,Nl}var Il,o0;function Iv(){if(o0)return Il;o0=1;var e=QE(),t=XE(),n=Object.prototype,r=n.propertyIsEnumerable,i=Object.getOwnPropertySymbols,o=i?function(a){return a==null?[]:(a=Object(a),e(i(a),function(s){return r.call(a,s)}))}:t;return Il=o,Il}var Pl,a0;function E3(){if(a0)return Pl;a0=1;var e=po(),t=Iv();function n(r,i){return e(r,t(r),i)}return Pl=n,Pl}var jl,s0;function Pv(){if(s0)return jl;s0=1;function e(t,n){for(var r=-1,i=n.length,o=t.length;++r<i;)t[o+r]=n[r];return t}return jl=e,jl}var ql,u0;function Ss(){if(u0)return ql;u0=1;var e=WE(),t=e(Object.getPrototypeOf,Object);return ql=t,ql}var Al,l0;function ZE(){if(l0)return Al;l0=1;var e=Pv(),t=Ss(),n=Iv(),r=XE(),i=Object.getOwnPropertySymbols,o=i?function(a){for(var s=[];a;)e(s,n(a)),a=t(a);return s}:r;return Al=o,Al}var Ml,c0;function C3(){if(c0)return Ml;c0=1;var e=po(),t=ZE();function n(r,i){return e(r,t(r),i)}return Ml=n,Ml}var Ll,f0;function JE(){if(f0)return Ll;f0=1;var e=Pv(),t=ge();function n(r,i,o){var a=i(r);return t(r)?a:e(a,o(r))}return Ll=n,Ll}var Ol,d0;function eC(){if(d0)return Ol;d0=1;var e=JE(),t=Iv(),n=qn();function r(i){return e(i,n,t)}return Ol=r,Ol}var zl,h0;function k3(){if(h0)return zl;h0=1;var e=JE(),t=ZE(),n=ir();function r(i){return e(i,n,t)}return zl=r,zl}var Fl,p0;function b3(){if(p0)return Fl;p0=1;var e=rr(),t=wt(),n=e(t,"DataView");return Fl=n,Fl}var Dl,v0;function T3(){if(v0)return Dl;v0=1;var e=rr(),t=wt(),n=e(t,"Promise");return Dl=n,Dl}var $l,g0;function tC(){if(g0)return $l;g0=1;var e=rr(),t=wt(),n=e(t,"Set");return $l=n,$l}var Bl,m0;function R3(){if(m0)return Bl;m0=1;var e=rr(),t=wt(),n=e(t,"WeakMap");return Bl=n,Bl}var Ul,y0;function Jr(){if(y0)return Ul;y0=1;var e=b3(),t=Cv(),n=T3(),r=tC(),i=R3(),o=nr(),a=HE(),s="[object Map]",u="[object Object]",l="[object Promise]",c="[object Set]",f="[object WeakMap]",d="[object DataView]",h=a(e),g=a(t),v=a(n),y=a(r),p=a(i),m=o;return(e&&m(new e(new ArrayBuffer(1)))!=d||t&&m(new t)!=s||n&&m(n.resolve())!=l||r&&m(new r)!=c||i&&m(new i)!=f)&&(m=function(_){var x=o(_),S=x==u?_.constructor:void 0,E=S?a(S):"";if(E)switch(E){case h:return d;case g:return s;case v:return l;case y:return c;case p:return f}return x}),Ul=m,Ul}var Hl,_0;function N3(){if(_0)return Hl;_0=1;var e=Object.prototype,t=e.hasOwnProperty;function n(r){var i=r.length,o=new r.constructor(i);return i&&typeof r[0]=="string"&&t.call(r,"index")&&(o.index=r.index,o.input=r.input),o}return Hl=n,Hl}var Vl,x0;function nC(){if(x0)return Vl;x0=1;var e=wt(),t=e.Uint8Array;return Vl=t,Vl}var Gl,w0;function jv(){if(w0)return Gl;w0=1;var e=nC();function t(n){var r=new n.constructor(n.byteLength);return new e(r).set(new e(n)),r}return Gl=t,Gl}var Wl,S0;function I3(){if(S0)return Wl;S0=1;var e=jv();function t(n,r){var i=r?e(n.buffer):n.buffer;return new n.constructor(i,n.byteOffset,n.byteLength)}return Wl=t,Wl}var Kl,E0;function P3(){if(E0)return Kl;E0=1;var e=/\w*$/;function t(n){var r=new n.constructor(n.source,e.exec(n));return r.lastIndex=n.lastIndex,r}return Kl=t,Kl}var Yl,C0;function j3(){if(C0)return Yl;C0=1;var e=Xr(),t=e?e.prototype:void 0,n=t?t.valueOf:void 0;function r(i){return n?Object(n.call(i)):{}}return Yl=r,Yl}var Ql,k0;function rC(){if(k0)return Ql;k0=1;var e=jv();function t(n,r){var i=r?e(n.buffer):n.buffer;return new n.constructor(i,n.byteOffset,n.length)}return Ql=t,Ql}var Xl,b0;function q3(){if(b0)return Xl;b0=1;var e=jv(),t=I3(),n=P3(),r=j3(),i=rC(),o="[object Boolean]",a="[object Date]",s="[object Map]",u="[object Number]",l="[object RegExp]",c="[object Set]",f="[object String]",d="[object Symbol]",h="[object ArrayBuffer]",g="[object DataView]",v="[object Float32Array]",y="[object Float64Array]",p="[object Int8Array]",m="[object Int16Array]",_="[object Int32Array]",x="[object Uint8Array]",S="[object Uint8ClampedArray]",E="[object Uint16Array]",C="[object Uint32Array]";function T(M,k,j){var B=M.constructor;switch(k){case h:return e(M);case o:case a:return new B(+M);case g:return t(M,j);case v:case y:case p:case m:case _:case x:case S:case E:case C:return i(M,j);case s:return new B;case u:case f:return new B(M);case l:return n(M);case c:return new B;case d:return r(M)}}return Xl=T,Xl}var Zl,T0;function iC(){if(T0)return Zl;T0=1;var e=lt(),t=Object.create,n=function(){function r(){}return function(i){if(!e(i))return{};if(t)return t(i);r.prototype=i;var o=new r;return r.prototype=void 0,o}}();return Zl=n,Zl}var Jl,R0;function oC(){if(R0)return Jl;R0=1;var e=iC(),t=Ss(),n=ws();function r(i){return typeof i.constructor=="function"&&!n(i)?e(t(i)):{}}return Jl=r,Jl}var ec,N0;function A3(){if(N0)return ec;N0=1;var e=Jr(),t=jt(),n="[object Map]";function r(i){return t(i)&&e(i)==n}return ec=r,ec}var tc,I0;function M3(){if(I0)return tc;I0=1;var e=A3(),t=xs(),n=Rv(),r=n&&n.isMap,i=r?t(r):e;return tc=i,tc}var nc,P0;function L3(){if(P0)return nc;P0=1;var e=Jr(),t=jt(),n="[object Set]";function r(i){return t(i)&&e(i)==n}return nc=r,nc}var rc,j0;function O3(){if(j0)return rc;j0=1;var e=L3(),t=xs(),n=Rv(),r=n&&n.isSet,i=r?t(r):e;return rc=i,rc}var ic,q0;function aC(){if(q0)return ic;q0=1;var e=gs(),t=bv(),n=ys(),r=_3(),i=S3(),o=KE(),a=YE(),s=E3(),u=C3(),l=eC(),c=k3(),f=Jr(),d=N3(),h=q3(),g=oC(),v=ge(),y=Zr(),p=M3(),m=lt(),_=O3(),x=qn(),S=ir(),E=1,C=2,T=4,M="[object Arguments]",k="[object Array]",j="[object Boolean]",B="[object Date]",H="[object Error]",b="[object Function]",P="[object GeneratorFunction]",R="[object Map]",O="[object Number]",I="[object Object]",A="[object RegExp]",L="[object Set]",F="[object String]",U="[object Symbol]",Ee="[object WeakMap]",J="[object ArrayBuffer]",Ce="[object DataView]",me="[object Float32Array]",xe="[object Float64Array]",ft="[object Int8Array]",ti="[object Int16Array]",ik="[object Int32Array]",ok="[object Uint8Array]",ak="[object Uint8ClampedArray]",sk="[object Uint16Array]",uk="[object Uint32Array]",te={};te[M]=te[k]=te[J]=te[Ce]=te[j]=te[B]=te[me]=te[xe]=te[ft]=te[ti]=te[ik]=te[R]=te[O]=te[I]=te[A]=te[L]=te[F]=te[U]=te[ok]=te[ak]=te[sk]=te[uk]=!0,te[H]=te[b]=te[Ee]=!1;function yo(Q,sr,ur,lk,_o,Jt){var ze,xo=sr&E,wo=sr&C,ck=sr&T;if(ur&&(ze=_o?ur(Q,lk,_o,Jt):ur(Q)),ze!==void 0)return ze;if(!m(Q))return Q;var Uv=v(Q);if(Uv){if(ze=d(Q),!xo)return a(Q,ze)}else{var lr=f(Q),Hv=lr==b||lr==P;if(y(Q))return o(Q,xo);if(lr==I||lr==M||Hv&&!_o){if(ze=wo||Hv?{}:g(Q),!xo)return wo?u(Q,i(ze,Q)):s(Q,r(ze,Q))}else{if(!te[lr])return _o?Q:{};ze=h(Q,lr,xo)}}Jt||(Jt=new e);var Vv=Jt.get(Q);if(Vv)return Vv;Jt.set(Q,ze),_(Q)?Q.forEach(function(en){ze.add(yo(en,sr,ur,en,Q,Jt))}):p(Q)&&Q.forEach(function(en,An){ze.set(An,yo(en,sr,ur,An,Q,Jt))});var fk=ck?wo?c:l:wo?S:x,Gv=Uv?void 0:fk(Q);return t(Gv||Q,function(en,An){Gv&&(An=en,en=Q[An]),n(ze,An,yo(en,sr,ur,An,Q,Jt))}),ze}return ic=yo,ic}var oc,A0;function z3(){if(A0)return oc;A0=1;var e=aC(),t=4;function n(r){return e(r,t)}return oc=n,oc}var ac,M0;function qv(){if(M0)return ac;M0=1;function e(t){return function(){return t}}return ac=e,ac}var sc,L0;function F3(){if(L0)return sc;L0=1;function e(t){return function(n,r,i){for(var o=-1,a=Object(n),s=i(n),u=s.length;u--;){var l=s[t?u:++o];if(r(a[l],l,a)===!1)break}return n}}return sc=e,sc}var uc,O0;function Av(){if(O0)return uc;O0=1;var e=F3(),t=e();return uc=t,uc}var lc,z0;function Mv(){if(z0)return lc;z0=1;var e=Av(),t=qn();function n(r,i){return r&&e(r,i,t)}return lc=n,lc}var cc,F0;function D3(){if(F0)return cc;F0=1;var e=Xt();function t(n,r){return function(i,o){if(i==null)return i;if(!e(i))return n(i,o);for(var a=i.length,s=r?a:-1,u=Object(i);(r?s--:++s<a)&&o(u[s],s,u)!==!1;);return i}}return cc=t,cc}var fc,D0;function Es(){if(D0)return fc;D0=1;var e=Mv(),t=D3(),n=t(e);return fc=n,fc}var dc,$0;function or(){if($0)return dc;$0=1;function e(t){return t}return dc=e,dc}var hc,B0;function sC(){if(B0)return hc;B0=1;var e=or();function t(n){return typeof n=="function"?n:e}return hc=t,hc}var pc,U0;function uC(){if(U0)return pc;U0=1;var e=bv(),t=Es(),n=sC(),r=ge();function i(o,a){var s=r(o)?e:t;return s(o,n(a))}return pc=i,pc}var vc,H0;function lC(){return H0||(H0=1,vc=uC()),vc}var gc,V0;function $3(){if(V0)return gc;V0=1;var e=Es();function t(n,r){var i=[];return e(n,function(o,a,s){r(o,a,s)&&i.push(o)}),i}return gc=t,gc}var mc,G0;function B3(){if(G0)return mc;G0=1;var e="__lodash_hash_undefined__";function t(n){return this.__data__.set(n,e),this}return mc=t,mc}var yc,W0;function U3(){if(W0)return yc;W0=1;function e(t){return this.__data__.has(t)}return yc=e,yc}var _c,K0;function cC(){if(K0)return _c;K0=1;var e=kv(),t=B3(),n=U3();function r(i){var o=-1,a=i==null?0:i.length;for(this.__data__=new e;++o<a;)this.add(i[o])}return r.prototype.add=r.prototype.push=t,r.prototype.has=n,_c=r,_c}var xc,Y0;function H3(){if(Y0)return xc;Y0=1;function e(t,n){for(var r=-1,i=t==null?0:t.length;++r<i;)if(n(t[r],r,t))return!0;return!1}return xc=e,xc}var wc,Q0;function fC(){if(Q0)return wc;Q0=1;function e(t,n){return t.has(n)}return wc=e,wc}var Sc,X0;function dC(){if(X0)return Sc;X0=1;var e=cC(),t=H3(),n=fC(),r=1,i=2;function o(a,s,u,l,c,f){var d=u&r,h=a.length,g=s.length;if(h!=g&&!(d&&g>h))return!1;var v=f.get(a),y=f.get(s);if(v&&y)return v==s&&y==a;var p=-1,m=!0,_=u&i?new e:void 0;for(f.set(a,s),f.set(s,a);++p<h;){var x=a[p],S=s[p];if(l)var E=d?l(S,x,p,s,a,f):l(x,S,p,a,s,f);if(E!==void 0){if(E)continue;m=!1;break}if(_){if(!t(s,function(C,T){if(!n(_,T)&&(x===C||c(x,C,u,l,f)))return _.push(T)})){m=!1;break}}else if(!(x===S||c(x,S,u,l,f))){m=!1;break}}return f.delete(a),f.delete(s),m}return Sc=o,Sc}var Ec,Z0;function V3(){if(Z0)return Ec;Z0=1;function e(t){var n=-1,r=Array(t.size);return t.forEach(function(i,o){r[++n]=[o,i]}),r}return Ec=e,Ec}var Cc,J0;function Lv(){if(J0)return Cc;J0=1;function e(t){var n=-1,r=Array(t.size);return t.forEach(function(i){r[++n]=i}),r}return Cc=e,Cc}var kc,e1;function G3(){if(e1)return kc;e1=1;var e=Xr(),t=nC(),n=Qr(),r=dC(),i=V3(),o=Lv(),a=1,s=2,u="[object Boolean]",l="[object Date]",c="[object Error]",f="[object Map]",d="[object Number]",h="[object RegExp]",g="[object Set]",v="[object String]",y="[object Symbol]",p="[object ArrayBuffer]",m="[object DataView]",_=e?e.prototype:void 0,x=_?_.valueOf:void 0;function S(E,C,T,M,k,j,B){switch(T){case m:if(E.byteLength!=C.byteLength||E.byteOffset!=C.byteOffset)return!1;E=E.buffer,C=C.buffer;case p:return!(E.byteLength!=C.byteLength||!j(new t(E),new t(C)));case u:case l:case d:return n(+E,+C);case c:return E.name==C.name&&E.message==C.message;case h:case v:return E==C+"";case f:var H=i;case g:var b=M&a;if(H||(H=o),E.size!=C.size&&!b)return!1;var P=B.get(E);if(P)return P==C;M|=s,B.set(E,C);var R=r(H(E),H(C),M,k,j,B);return B.delete(E),R;case y:if(x)return x.call(E)==x.call(C)}return!1}return kc=S,kc}var bc,t1;function W3(){if(t1)return bc;t1=1;var e=eC(),t=1,n=Object.prototype,r=n.hasOwnProperty;function i(o,a,s,u,l,c){var f=s&t,d=e(o),h=d.length,g=e(a),v=g.length;if(h!=v&&!f)return!1;for(var y=h;y--;){var p=d[y];if(!(f?p in a:r.call(a,p)))return!1}var m=c.get(o),_=c.get(a);if(m&&_)return m==a&&_==o;var x=!0;c.set(o,a),c.set(a,o);for(var S=f;++y<h;){p=d[y];var E=o[p],C=a[p];if(u)var T=f?u(C,E,p,a,o,c):u(E,C,p,o,a,c);if(!(T===void 0?E===C||l(E,C,s,u,c):T)){x=!1;break}S||(S=p=="constructor")}if(x&&!S){var M=o.constructor,k=a.constructor;M!=k&&"constructor"in o&&"constructor"in a&&!(typeof M=="function"&&M instanceof M&&typeof k=="function"&&k instanceof k)&&(x=!1)}return c.delete(o),c.delete(a),x}return bc=i,bc}var Tc,n1;function K3(){if(n1)return Tc;n1=1;var e=gs(),t=dC(),n=G3(),r=W3(),i=Jr(),o=ge(),a=Zr(),s=go(),u=1,l="[object Arguments]",c="[object Array]",f="[object Object]",d=Object.prototype,h=d.hasOwnProperty;function g(v,y,p,m,_,x){var S=o(v),E=o(y),C=S?c:i(v),T=E?c:i(y);C=C==l?f:C,T=T==l?f:T;var M=C==f,k=T==f,j=C==T;if(j&&a(v)){if(!a(y))return!1;S=!0,M=!1}if(j&&!M)return x||(x=new e),S||s(v)?t(v,y,p,m,_,x):n(v,y,C,p,m,_,x);if(!(p&u)){var B=M&&h.call(v,"__wrapped__"),H=k&&h.call(y,"__wrapped__");if(B||H){var b=B?v.value():v,P=H?y.value():y;return x||(x=new e),_(b,P,p,m,x)}}return j?(x||(x=new e),r(v,y,p,m,_,x)):!1}return Tc=g,Tc}var Rc,r1;function hC(){if(r1)return Rc;r1=1;var e=K3(),t=jt();function n(r,i,o,a,s){return r===i?!0:r==null||i==null||!t(r)&&!t(i)?r!==r&&i!==i:e(r,i,o,a,n,s)}return Rc=n,Rc}var Nc,i1;function Y3(){if(i1)return Nc;i1=1;var e=gs(),t=hC(),n=1,r=2;function i(o,a,s,u){var l=s.length,c=l,f=!u;if(o==null)return!c;for(o=Object(o);l--;){var d=s[l];if(f&&d[2]?d[1]!==o[d[0]]:!(d[0]in o))return!1}for(;++l<c;){d=s[l];var h=d[0],g=o[h],v=d[1];if(f&&d[2]){if(g===void 0&&!(h in o))return!1}else{var y=new e;if(u)var p=u(g,v,h,o,a,y);if(!(p===void 0?t(v,g,n|r,u,y):p))return!1}}return!0}return Nc=i,Nc}var Ic,o1;function pC(){if(o1)return Ic;o1=1;var e=lt();function t(n){return n===n&&!e(n)}return Ic=t,Ic}var Pc,a1;function Q3(){if(a1)return Pc;a1=1;var e=pC(),t=qn();function n(r){for(var i=t(r),o=i.length;o--;){var a=i[o],s=r[a];i[o]=[a,s,e(s)]}return i}return Pc=n,Pc}var jc,s1;function vC(){if(s1)return jc;s1=1;function e(t,n){return function(r){return r==null?!1:r[t]===n&&(n!==void 0||t in Object(r))}}return jc=e,jc}var qc,u1;function X3(){if(u1)return qc;u1=1;var e=Y3(),t=Q3(),n=vC();function r(i){var o=t(i);return o.length==1&&o[0][2]?n(o[0][0],o[0][1]):function(a){return a===i||e(a,i,o)}}return qc=r,qc}var Ac,l1;function ei(){if(l1)return Ac;l1=1;var e=nr(),t=jt(),n="[object Symbol]";function r(i){return typeof i=="symbol"||t(i)&&e(i)==n}return Ac=r,Ac}var Mc,c1;function Ov(){if(c1)return Mc;c1=1;var e=ge(),t=ei(),n=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,r=/^\w*$/;function i(o,a){if(e(o))return!1;var s=typeof o;return s=="number"||s=="symbol"||s=="boolean"||o==null||t(o)?!0:r.test(o)||!n.test(o)||a!=null&&o in Object(a)}return Mc=i,Mc}var Lc,f1;function Z3(){if(f1)return Lc;f1=1;var e=kv(),t="Expected a function";function n(r,i){if(typeof r!="function"||i!=null&&typeof i!="function")throw new TypeError(t);var o=function(){var a=arguments,s=i?i.apply(this,a):a[0],u=o.cache;if(u.has(s))return u.get(s);var l=r.apply(this,a);return o.cache=u.set(s,l)||u,l};return o.cache=new(n.Cache||e),o}return n.Cache=e,Lc=n,Lc}var Oc,d1;function J3(){if(d1)return Oc;d1=1;var e=Z3(),t=500;function n(r){var i=e(r,function(a){return o.size===t&&o.clear(),a}),o=i.cache;return i}return Oc=n,Oc}var zc,h1;function eq(){if(h1)return zc;h1=1;var e=J3(),t=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,n=/\\(\\)?/g,r=e(function(i){var o=[];return i.charCodeAt(0)===46&&o.push(""),i.replace(t,function(a,s,u,l){o.push(u?l.replace(n,"$1"):s||a)}),o});return zc=r,zc}var Fc,p1;function Cs(){if(p1)return Fc;p1=1;function e(t,n){for(var r=-1,i=t==null?0:t.length,o=Array(i);++r<i;)o[r]=n(t[r],r,t);return o}return Fc=e,Fc}var Dc,v1;function tq(){if(v1)return Dc;v1=1;var e=Xr(),t=Cs(),n=ge(),r=ei(),i=e?e.prototype:void 0,o=i?i.toString:void 0;function a(s){if(typeof s=="string")return s;if(n(s))return t(s,a)+"";if(r(s))return o?o.call(s):"";var u=s+"";return u=="0"&&1/s==-1/0?"-0":u}return Dc=a,Dc}var $c,g1;function gC(){if(g1)return $c;g1=1;var e=tq();function t(n){return n==null?"":e(n)}return $c=t,$c}var Bc,m1;function ks(){if(m1)return Bc;m1=1;var e=ge(),t=Ov(),n=eq(),r=gC();function i(o,a){return e(o)?o:t(o,a)?[o]:n(r(o))}return Bc=i,Bc}var Uc,y1;function mo(){if(y1)return Uc;y1=1;var e=ei();function t(n){if(typeof n=="string"||e(n))return n;var r=n+"";return r=="0"&&1/n==-1/0?"-0":r}return Uc=t,Uc}var Hc,_1;function bs(){if(_1)return Hc;_1=1;var e=ks(),t=mo();function n(r,i){i=e(i,r);for(var o=0,a=i.length;r!=null&&o<a;)r=r[t(i[o++])];return o&&o==a?r:void 0}return Hc=n,Hc}var Vc,x1;function nq(){if(x1)return Vc;x1=1;var e=bs();function t(n,r,i){var o=n==null?void 0:e(n,r);return o===void 0?i:o}return Vc=t,Vc}var Gc,w1;function rq(){if(w1)return Gc;w1=1;function e(t,n){return t!=null&&n in Object(t)}return Gc=e,Gc}var Wc,S1;function mC(){if(S1)return Wc;S1=1;var e=ks(),t=vo(),n=ge(),r=_s(),i=Tv(),o=mo();function a(s,u,l){u=e(u,s);for(var c=-1,f=u.length,d=!1;++c<f;){var h=o(u[c]);if(!(d=s!=null&&l(s,h)))break;s=s[h]}return d||++c!=f?d:(f=s==null?0:s.length,!!f&&i(f)&&r(h,f)&&(n(s)||t(s)))}return Wc=a,Wc}var Kc,E1;function yC(){if(E1)return Kc;E1=1;var e=rq(),t=mC();function n(r,i){return r!=null&&t(r,i,e)}return Kc=n,Kc}var Yc,C1;function iq(){if(C1)return Yc;C1=1;var e=hC(),t=nq(),n=yC(),r=Ov(),i=pC(),o=vC(),a=mo(),s=1,u=2;function l(c,f){return r(c)&&i(f)?o(a(c),f):function(d){var h=t(d,c);return h===void 0&&h===f?n(d,c):e(f,h,s|u)}}return Yc=l,Yc}var Qc,k1;function _C(){if(k1)return Qc;k1=1;function e(t){return function(n){return n==null?void 0:n[t]}}return Qc=e,Qc}var Xc,b1;function oq(){if(b1)return Xc;b1=1;var e=bs();function t(n){return function(r){return e(r,n)}}return Xc=t,Xc}var Zc,T1;function aq(){if(T1)return Zc;T1=1;var e=_C(),t=oq(),n=Ov(),r=mo();function i(o){return n(o)?e(r(o)):t(o)}return Zc=i,Zc}var Jc,R1;function Zt(){if(R1)return Jc;R1=1;var e=X3(),t=iq(),n=or(),r=ge(),i=aq();function o(a){return typeof a=="function"?a:a==null?n:typeof a=="object"?r(a)?t(a[0],a[1]):e(a):i(a)}return Jc=o,Jc}var ef,N1;function xC(){if(N1)return ef;N1=1;var e=QE(),t=$3(),n=Zt(),r=ge();function i(o,a){var s=r(o)?e:t;return s(o,n(a,3))}return ef=i,ef}var tf,I1;function sq(){if(I1)return tf;I1=1;var e=Object.prototype,t=e.hasOwnProperty;function n(r,i){return r!=null&&t.call(r,i)}return tf=n,tf}var nf,P1;function wC(){if(P1)return nf;P1=1;var e=sq(),t=mC();function n(r,i){return r!=null&&t(r,i,e)}return nf=n,nf}var rf,j1;function uq(){if(j1)return rf;j1=1;var e=Nv(),t=Jr(),n=vo(),r=ge(),i=Xt(),o=Zr(),a=ws(),s=go(),u="[object Map]",l="[object Set]",c=Object.prototype,f=c.hasOwnProperty;function d(h){if(h==null)return!0;if(i(h)&&(r(h)||typeof h=="string"||typeof h.splice=="function"||o(h)||s(h)||n(h)))return!h.length;var g=t(h);if(g==u||g==l)return!h.size;if(a(h))return!e(h).length;for(var v in h)if(f.call(h,v))return!1;return!0}return rf=d,rf}var of,q1;function SC(){if(q1)return of;q1=1;function e(t){return t===void 0}return of=e,of}var af,A1;function EC(){if(A1)return af;A1=1;var e=Es(),t=Xt();function n(r,i){var o=-1,a=t(r)?Array(r.length):[];return e(r,function(s,u,l){a[++o]=i(s,u,l)}),a}return af=n,af}var sf,M1;function CC(){if(M1)return sf;M1=1;var e=Cs(),t=Zt(),n=EC(),r=ge();function i(o,a){var s=r(o)?e:n;return s(o,t(a,3))}return sf=i,sf}var uf,L1;function lq(){if(L1)return uf;L1=1;function e(t,n,r,i){var o=-1,a=t==null?0:t.length;for(i&&a&&(r=t[++o]);++o<a;)r=n(r,t[o],o,t);return r}return uf=e,uf}var lf,O1;function cq(){if(O1)return lf;O1=1;function e(t,n,r,i,o){return o(t,function(a,s,u){r=i?(i=!1,a):n(r,a,s,u)}),r}return lf=e,lf}var cf,z1;function kC(){if(z1)return cf;z1=1;var e=lq(),t=Es(),n=Zt(),r=cq(),i=ge();function o(a,s,u){var l=i(a)?e:r,c=arguments.length<3;return l(a,n(s,4),u,c,t)}return cf=o,cf}var ff,F1;function fq(){if(F1)return ff;F1=1;var e=nr(),t=ge(),n=jt(),r="[object String]";function i(o){return typeof o=="string"||!t(o)&&n(o)&&e(o)==r}return ff=i,ff}var df,D1;function dq(){if(D1)return df;D1=1;var e=_C(),t=e("length");return df=t,df}var hf,$1;function hq(){if($1)return hf;$1=1;var e="\\ud800-\\udfff",t="\\u0300-\\u036f",n="\\ufe20-\\ufe2f",r="\\u20d0-\\u20ff",i=t+n+r,o="\\ufe0e\\ufe0f",a="\\u200d",s=RegExp("["+a+e+i+o+"]");function u(l){return s.test(l)}return hf=u,hf}var pf,B1;function pq(){if(B1)return pf;B1=1;var e="\\ud800-\\udfff",t="\\u0300-\\u036f",n="\\ufe20-\\ufe2f",r="\\u20d0-\\u20ff",i=t+n+r,o="\\ufe0e\\ufe0f",a="["+e+"]",s="["+i+"]",u="\\ud83c[\\udffb-\\udfff]",l="(?:"+s+"|"+u+")",c="[^"+e+"]",f="(?:\\ud83c[\\udde6-\\uddff]){2}",d="[\\ud800-\\udbff][\\udc00-\\udfff]",h="\\u200d",g=l+"?",v="["+o+"]?",y="(?:"+h+"(?:"+[c,f,d].join("|")+")"+v+g+")*",p=v+g+y,m="(?:"+[c+s+"?",s,f,d,a].join("|")+")",_=RegExp(u+"(?="+u+")|"+m+p,"g");function x(S){for(var E=_.lastIndex=0;_.test(S);)++E;return E}return pf=x,pf}var vf,U1;function vq(){if(U1)return vf;U1=1;var e=dq(),t=hq(),n=pq();function r(i){return t(i)?n(i):e(i)}return vf=r,vf}var gf,H1;function gq(){if(H1)return gf;H1=1;var e=Nv(),t=Jr(),n=Xt(),r=fq(),i=vq(),o="[object Map]",a="[object Set]";function s(u){if(u==null)return 0;if(n(u))return r(u)?i(u):u.length;var l=t(u);return l==o||l==a?u.size:e(u).length}return gf=s,gf}var mf,V1;function mq(){if(V1)return mf;V1=1;var e=bv(),t=iC(),n=Mv(),r=Zt(),i=Ss(),o=ge(),a=Zr(),s=ho(),u=lt(),l=go();function c(f,d,h){var g=o(f),v=g||a(f)||l(f);if(d=r(d,4),h==null){var y=f&&f.constructor;v?h=g?new y:[]:u(f)?h=s(y)?t(i(f)):{}:h={}}return(v?e:n)(f,function(p,m,_){return d(h,p,m,_)}),h}return mf=c,mf}var yf,G1;function yq(){if(G1)return yf;G1=1;var e=Xr(),t=vo(),n=ge(),r=e?e.isConcatSpreadable:void 0;function i(o){return n(o)||t(o)||!!(r&&o&&o[r])}return yf=i,yf}var _f,W1;function zv(){if(W1)return _f;W1=1;var e=Pv(),t=yq();function n(r,i,o,a,s){var u=-1,l=r.length;for(o||(o=t),s||(s=[]);++u<l;){var c=r[u];i>0&&o(c)?i>1?n(c,i-1,o,a,s):e(s,c):a||(s[s.length]=c)}return s}return _f=n,_f}var xf,K1;function _q(){if(K1)return xf;K1=1;function e(t,n,r){switch(r.length){case 0:return t.call(n);case 1:return t.call(n,r[0]);case 2:return t.call(n,r[0],r[1]);case 3:return t.call(n,r[0],r[1],r[2])}return t.apply(n,r)}return xf=e,xf}var wf,Y1;function bC(){if(Y1)return wf;Y1=1;var e=_q(),t=Math.max;function n(r,i,o){return i=t(i===void 0?r.length-1:i,0),function(){for(var a=arguments,s=-1,u=t(a.length-i,0),l=Array(u);++s<u;)l[s]=a[i+s];s=-1;for(var c=Array(i+1);++s<i;)c[s]=a[s];return c[i]=o(l),e(r,this,c)}}return wf=n,wf}var Sf,Q1;function xq(){if(Q1)return Sf;Q1=1;var e=qv(),t=VE(),n=or(),r=t?function(i,o){return t(i,"toString",{configurable:!0,enumerable:!1,value:e(o),writable:!0})}:n;return Sf=r,Sf}var Ef,X1;function wq(){if(X1)return Ef;X1=1;var e=800,t=16,n=Date.now;function r(i){var o=0,a=0;return function(){var s=n(),u=t-(s-a);if(a=s,u>0){if(++o>=e)return arguments[0]}else o=0;return i.apply(void 0,arguments)}}return Ef=r,Ef}var Cf,Z1;function TC(){if(Z1)return Cf;Z1=1;var e=xq(),t=wq(),n=t(e);return Cf=n,Cf}var kf,J1;function Ts(){if(J1)return kf;J1=1;var e=or(),t=bC(),n=TC();function r(i,o){return n(t(i,o,e),i+"")}return kf=r,kf}var bf,e_;function RC(){if(e_)return bf;e_=1;function e(t,n,r,i){for(var o=t.length,a=r+(i?1:-1);i?a--:++a<o;)if(n(t[a],a,t))return a;return-1}return bf=e,bf}var Tf,t_;function Sq(){if(t_)return Tf;t_=1;function e(t){return t!==t}return Tf=e,Tf}var Rf,n_;function Eq(){if(n_)return Rf;n_=1;function e(t,n,r){for(var i=r-1,o=t.length;++i<o;)if(t[i]===n)return i;return-1}return Rf=e,Rf}var Nf,r_;function Cq(){if(r_)return Nf;r_=1;var e=RC(),t=Sq(),n=Eq();function r(i,o,a){return o===o?n(i,o,a):e(i,t,a)}return Nf=r,Nf}var If,i_;function kq(){if(i_)return If;i_=1;var e=Cq();function t(n,r){var i=n==null?0:n.length;return!!i&&e(n,r,0)>-1}return If=t,If}var Pf,o_;function bq(){if(o_)return Pf;o_=1;function e(t,n,r){for(var i=-1,o=t==null?0:t.length;++i<o;)if(r(n,t[i]))return!0;return!1}return Pf=e,Pf}var jf,a_;function Tq(){if(a_)return jf;a_=1;function e(){}return jf=e,jf}var qf,s_;function Rq(){if(s_)return qf;s_=1;var e=tC(),t=Tq(),n=Lv(),r=1/0,i=e&&1/n(new e([,-0]))[1]==r?function(o){return new e(o)}:t;return qf=i,qf}var Af,u_;function Nq(){if(u_)return Af;u_=1;var e=cC(),t=kq(),n=bq(),r=fC(),i=Rq(),o=Lv(),a=200;function s(u,l,c){var f=-1,d=t,h=u.length,g=!0,v=[],y=v;if(c)g=!1,d=n;else if(h>=a){var p=l?null:i(u);if(p)return o(p);g=!1,d=r,y=new e}else y=l?[]:v;e:for(;++f<h;){var m=u[f],_=l?l(m):m;if(m=c||m!==0?m:0,g&&_===_){for(var x=y.length;x--;)if(y[x]===_)continue e;l&&y.push(_),v.push(m)}else d(y,_,c)||(y!==v&&y.push(_),v.push(m))}return v}return Af=s,Af}var Mf,l_;function NC(){if(l_)return Mf;l_=1;var e=Xt(),t=jt();function n(r){return t(r)&&e(r)}return Mf=n,Mf}var Lf,c_;function Iq(){if(c_)return Lf;c_=1;var e=zv(),t=Ts(),n=Nq(),r=NC(),i=t(function(o){return n(e(o,1,r,!0))});return Lf=i,Lf}var Of,f_;function Pq(){if(f_)return Of;f_=1;var e=Cs();function t(n,r){return e(r,function(i){return n[i]})}return Of=t,Of}var zf,d_;function IC(){if(d_)return zf;d_=1;var e=Pq(),t=qn();function n(r){return r==null?[]:e(r,t(r))}return zf=n,zf}var Ff,h_;function ct(){if(h_)return Ff;h_=1;var e;if(typeof Ev=="function")try{e={clone:z3(),constant:qv(),each:lC(),filter:xC(),has:wC(),isArray:ge(),isEmpty:uq(),isFunction:ho(),isUndefined:SC(),keys:qn(),map:CC(),reduce:kC(),size:gq(),transform:mq(),union:Iq(),values:IC()}}catch{}return e||(e=window._),Ff=e,Ff}var Df,p_;function Fv(){if(p_)return Df;p_=1;var e=ct();Df=i;var t="\0",n="\0",r="";function i(c){this._isDirected=e.has(c,"directed")?c.directed:!0,this._isMultigraph=e.has(c,"multigraph")?c.multigraph:!1,this._isCompound=e.has(c,"compound")?c.compound:!1,this._label=void 0,this._defaultNodeLabelFn=e.constant(void 0),this._defaultEdgeLabelFn=e.constant(void 0),this._nodes={},this._isCompound&&(this._parent={},this._children={},this._children[n]={}),this._in={},this._preds={},this._out={},this._sucs={},this._edgeObjs={},this._edgeLabels={}}i.prototype._nodeCount=0,i.prototype._edgeCount=0,i.prototype.isDirected=function(){return this._isDirected},i.prototype.isMultigraph=function(){return this._isMultigraph},i.prototype.isCompound=function(){return this._isCompound},i.prototype.setGraph=function(c){return this._label=c,this},i.prototype.graph=function(){return this._label},i.prototype.setDefaultNodeLabel=function(c){return e.isFunction(c)||(c=e.constant(c)),this._defaultNodeLabelFn=c,this},i.prototype.nodeCount=function(){return this._nodeCount},i.prototype.nodes=function(){return e.keys(this._nodes)},i.prototype.sources=function(){var c=this;return e.filter(this.nodes(),function(f){return e.isEmpty(c._in[f])})},i.prototype.sinks=function(){var c=this;return e.filter(this.nodes(),function(f){return e.isEmpty(c._out[f])})},i.prototype.setNodes=function(c,f){var d=arguments,h=this;return e.each(c,function(g){d.length>1?h.setNode(g,f):h.setNode(g)}),this},i.prototype.setNode=function(c,f){return e.has(this._nodes,c)?(arguments.length>1&&(this._nodes[c]=f),this):(this._nodes[c]=arguments.length>1?f:this._defaultNodeLabelFn(c),this._isCompound&&(this._parent[c]=n,this._children[c]={},this._children[n][c]=!0),this._in[c]={},this._preds[c]={},this._out[c]={},this._sucs[c]={},++this._nodeCount,this)},i.prototype.node=function(c){return this._nodes[c]},i.prototype.hasNode=function(c){return e.has(this._nodes,c)},i.prototype.removeNode=function(c){var f=this;if(e.has(this._nodes,c)){var d=function(h){f.removeEdge(f._edgeObjs[h])};delete this._nodes[c],this._isCompound&&(this._removeFromParentsChildList(c),delete this._parent[c],e.each(this.children(c),function(h){f.setParent(h)}),delete this._children[c]),e.each(e.keys(this._in[c]),d),delete this._in[c],delete this._preds[c],e.each(e.keys(this._out[c]),d),delete this._out[c],delete this._sucs[c],--this._nodeCount}return this},i.prototype.setParent=function(c,f){if(!this._isCompound)throw new Error("Cannot set parent in a non-compound graph");if(e.isUndefined(f))f=n;else{f+="";for(var d=f;!e.isUndefined(d);d=this.parent(d))if(d===c)throw new Error("Setting "+f+" as parent of "+c+" would create a cycle");this.setNode(f)}return this.setNode(c),this._removeFromParentsChildList(c),this._parent[c]=f,this._children[f][c]=!0,this},i.prototype._removeFromParentsChildList=function(c){delete this._children[this._parent[c]][c]},i.prototype.parent=function(c){if(this._isCompound){var f=this._parent[c];if(f!==n)return f}},i.prototype.children=function(c){if(e.isUndefined(c)&&(c=n),this._isCompound){var f=this._children[c];if(f)return e.keys(f)}else{if(c===n)return this.nodes();if(this.hasNode(c))return[]}},i.prototype.predecessors=function(c){var f=this._preds[c];if(f)return e.keys(f)},i.prototype.successors=function(c){var f=this._sucs[c];if(f)return e.keys(f)},i.prototype.neighbors=function(c){var f=this.predecessors(c);if(f)return e.union(f,this.successors(c))},i.prototype.isLeaf=function(c){var f;return this.isDirected()?f=this.successors(c):f=this.neighbors(c),f.length===0},i.prototype.filterNodes=function(c){var f=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});f.setGraph(this.graph());var d=this;e.each(this._nodes,function(v,y){c(y)&&f.setNode(y,v)}),e.each(this._edgeObjs,function(v){f.hasNode(v.v)&&f.hasNode(v.w)&&f.setEdge(v,d.edge(v))});var h={};function g(v){var y=d.parent(v);return y===void 0||f.hasNode(y)?(h[v]=y,y):y in h?h[y]:g(y)}return this._isCompound&&e.each(f.nodes(),function(v){f.setParent(v,g(v))}),f},i.prototype.setDefaultEdgeLabel=function(c){return e.isFunction(c)||(c=e.constant(c)),this._defaultEdgeLabelFn=c,this},i.prototype.edgeCount=function(){return this._edgeCount},i.prototype.edges=function(){return e.values(this._edgeObjs)},i.prototype.setPath=function(c,f){var d=this,h=arguments;return e.reduce(c,function(g,v){return h.length>1?d.setEdge(g,v,f):d.setEdge(g,v),v}),this},i.prototype.setEdge=function(){var c,f,d,h,g=!1,v=arguments[0];typeof v=="object"&&v!==null&&"v"in v?(c=v.v,f=v.w,d=v.name,arguments.length===2&&(h=arguments[1],g=!0)):(c=v,f=arguments[1],d=arguments[3],arguments.length>2&&(h=arguments[2],g=!0)),c=""+c,f=""+f,e.isUndefined(d)||(d=""+d);var y=s(this._isDirected,c,f,d);if(e.has(this._edgeLabels,y))return g&&(this._edgeLabels[y]=h),this;if(!e.isUndefined(d)&&!this._isMultigraph)throw new Error("Cannot set a named edge when isMultigraph = false");this.setNode(c),this.setNode(f),this._edgeLabels[y]=g?h:this._defaultEdgeLabelFn(c,f,d);var p=u(this._isDirected,c,f,d);return c=p.v,f=p.w,Object.freeze(p),this._edgeObjs[y]=p,o(this._preds[f],c),o(this._sucs[c],f),this._in[f][y]=p,this._out[c][y]=p,this._edgeCount++,this},i.prototype.edge=function(c,f,d){var h=arguments.length===1?l(this._isDirected,arguments[0]):s(this._isDirected,c,f,d);return this._edgeLabels[h]},i.prototype.hasEdge=function(c,f,d){var h=arguments.length===1?l(this._isDirected,arguments[0]):s(this._isDirected,c,f,d);return e.has(this._edgeLabels,h)},i.prototype.removeEdge=function(c,f,d){var h=arguments.length===1?l(this._isDirected,arguments[0]):s(this._isDirected,c,f,d),g=this._edgeObjs[h];return g&&(c=g.v,f=g.w,delete this._edgeLabels[h],delete this._edgeObjs[h],a(this._preds[f],c),a(this._sucs[c],f),delete this._in[f][h],delete this._out[c][h],this._edgeCount--),this},i.prototype.inEdges=function(c,f){var d=this._in[c];if(d){var h=e.values(d);return f?e.filter(h,function(g){return g.v===f}):h}},i.prototype.outEdges=function(c,f){var d=this._out[c];if(d){var h=e.values(d);return f?e.filter(h,function(g){return g.w===f}):h}},i.prototype.nodeEdges=function(c,f){var d=this.inEdges(c,f);if(d)return d.concat(this.outEdges(c,f))};function o(c,f){c[f]?c[f]++:c[f]=1}function a(c,f){--c[f]||delete c[f]}function s(c,f,d,h){var g=""+f,v=""+d;if(!c&&g>v){var y=g;g=v,v=y}return g+r+v+r+(e.isUndefined(h)?t:h)}function u(c,f,d,h){var g=""+f,v=""+d;if(!c&&g>v){var y=g;g=v,v=y}var p={v:g,w:v};return h&&(p.name=h),p}function l(c,f){return s(c,f.v,f.w,f.name)}return Df}var $f,v_;function jq(){return v_||(v_=1,$f="2.1.8"),$f}var Bf,g_;function qq(){return g_||(g_=1,Bf={Graph:Fv(),version:jq()}),Bf}var Uf,m_;function Aq(){if(m_)return Uf;m_=1;var e=ct(),t=Fv();Uf={write:n,read:o};function n(a){var s={options:{directed:a.isDirected(),multigraph:a.isMultigraph(),compound:a.isCompound()},nodes:r(a),edges:i(a)};return e.isUndefined(a.graph())||(s.value=e.clone(a.graph())),s}function r(a){return e.map(a.nodes(),function(s){var u=a.node(s),l=a.parent(s),c={v:s};return e.isUndefined(u)||(c.value=u),e.isUndefined(l)||(c.parent=l),c})}function i(a){return e.map(a.edges(),function(s){var u=a.edge(s),l={v:s.v,w:s.w};return e.isUndefined(s.name)||(l.name=s.name),e.isUndefined(u)||(l.value=u),l})}function o(a){var s=new t(a.options).setGraph(a.value);return e.each(a.nodes,function(u){s.setNode(u.v,u.value),u.parent&&s.setParent(u.v,u.parent)}),e.each(a.edges,function(u){s.setEdge({v:u.v,w:u.w,name:u.name},u.value)}),s}return Uf}var Hf,y_;function Mq(){if(y_)return Hf;y_=1;var e=ct();Hf=t;function t(n){var r={},i=[],o;function a(s){e.has(r,s)||(r[s]=!0,o.push(s),e.each(n.successors(s),a),e.each(n.predecessors(s),a))}return e.each(n.nodes(),function(s){o=[],a(s),o.length&&i.push(o)}),i}return Hf}var Vf,__;function PC(){if(__)return Vf;__=1;var e=ct();Vf=t;function t(){this._arr=[],this._keyIndices={}}return t.prototype.size=function(){return this._arr.length},t.prototype.keys=function(){return this._arr.map(function(n){return n.key})},t.prototype.has=function(n){return e.has(this._keyIndices,n)},t.prototype.priority=function(n){var r=this._keyIndices[n];if(r!==void 0)return this._arr[r].priority},t.prototype.min=function(){if(this.size()===0)throw new Error("Queue underflow");return this._arr[0].key},t.prototype.add=function(n,r){var i=this._keyIndices;if(n=String(n),!e.has(i,n)){var o=this._arr,a=o.length;return i[n]=a,o.push({key:n,priority:r}),this._decrease(a),!0}return!1},t.prototype.removeMin=function(){this._swap(0,this._arr.length-1);var n=this._arr.pop();return delete this._keyIndices[n.key],this._heapify(0),n.key},t.prototype.decrease=function(n,r){var i=this._keyIndices[n];if(r>this._arr[i].priority)throw new Error("New priority is greater than current priority. Key: "+n+" Old: "+this._arr[i].priority+" New: "+r);this._arr[i].priority=r,this._decrease(i)},t.prototype._heapify=function(n){var r=this._arr,i=2*n,o=i+1,a=n;i<r.length&&(a=r[i].priority<r[a].priority?i:a,o<r.length&&(a=r[o].priority<r[a].priority?o:a),a!==n&&(this._swap(n,a),this._heapify(a)))},t.prototype._decrease=function(n){for(var r=this._arr,i=r[n].priority,o;n!==0&&(o=n>>1,!(r[o].priority<i));)this._swap(n,o),n=o},t.prototype._swap=function(n,r){var i=this._arr,o=this._keyIndices,a=i[n],s=i[r];i[n]=s,i[r]=a,o[s.key]=n,o[a.key]=r},Vf}var Gf,x_;function jC(){if(x_)return Gf;x_=1;var e=ct(),t=PC();Gf=r;var n=e.constant(1);function r(o,a,s,u){return i(o,String(a),s||n,u||function(l){return o.outEdges(l)})}function i(o,a,s,u){var l={},c=new t,f,d,h=function(g){var v=g.v!==f?g.v:g.w,y=l[v],p=s(g),m=d.distance+p;if(p<0)throw new Error("dijkstra does not allow negative edge weights. Bad edge: "+g+" Weight: "+p);m<y.distance&&(y.distance=m,y.predecessor=f,c.decrease(v,m))};for(o.nodes().forEach(function(g){var v=g===a?0:Number.POSITIVE_INFINITY;l[g]={distance:v},c.add(g,v)});c.size()>0&&(f=c.removeMin(),d=l[f],d.distance!==Number.POSITIVE_INFINITY);)u(f).forEach(h);return l}return Gf}var Wf,w_;function Lq(){if(w_)return Wf;w_=1;var e=jC(),t=ct();Wf=n;function n(r,i,o){return t.transform(r.nodes(),function(a,s){a[s]=e(r,s,i,o)},{})}return Wf}var Kf,S_;function qC(){if(S_)return Kf;S_=1;var e=ct();Kf=t;function t(n){var r=0,i=[],o={},a=[];function s(u){var l=o[u]={onStack:!0,lowlink:r,index:r++};if(i.push(u),n.successors(u).forEach(function(d){e.has(o,d)?o[d].onStack&&(l.lowlink=Math.min(l.lowlink,o[d].index)):(s(d),l.lowlink=Math.min(l.lowlink,o[d].lowlink))}),l.lowlink===l.index){var c=[],f;do f=i.pop(),o[f].onStack=!1,c.push(f);while(u!==f);a.push(c)}}return n.nodes().forEach(function(u){e.has(o,u)||s(u)}),a}return Kf}var Yf,E_;function Oq(){if(E_)return Yf;E_=1;var e=ct(),t=qC();Yf=n;function n(r){return e.filter(t(r),function(i){return i.length>1||i.length===1&&r.hasEdge(i[0],i[0])})}return Yf}var Qf,C_;function zq(){if(C_)return Qf;C_=1;var e=ct();Qf=n;var t=e.constant(1);function n(i,o,a){return r(i,o||t,a||function(s){return i.outEdges(s)})}function r(i,o,a){var s={},u=i.nodes();return u.forEach(function(l){s[l]={},s[l][l]={distance:0},u.forEach(function(c){l!==c&&(s[l][c]={distance:Number.POSITIVE_INFINITY})}),a(l).forEach(function(c){var f=c.v===l?c.w:c.v,d=o(c);s[l][f]={distance:d,predecessor:l}})}),u.forEach(function(l){var c=s[l];u.forEach(function(f){var d=s[f];u.forEach(function(h){var g=d[l],v=c[h],y=d[h],p=g.distance+v.distance;p<y.distance&&(y.distance=p,y.predecessor=v.predecessor)})})}),s}return Qf}var Xf,k_;function AC(){if(k_)return Xf;k_=1;var e=ct();Xf=t,t.CycleException=n;function t(r){var i={},o={},a=[];function s(u){if(e.has(o,u))throw new n;e.has(i,u)||(o[u]=!0,i[u]=!0,e.each(r.predecessors(u),s),delete o[u],a.push(u))}if(e.each(r.sinks(),s),e.size(i)!==r.nodeCount())throw new n;return a}function n(){}return n.prototype=new Error,Xf}var Zf,b_;function Fq(){if(b_)return Zf;b_=1;var e=AC();Zf=t;function t(n){try{e(n)}catch(r){if(r instanceof e.CycleException)return!1;throw r}return!0}return Zf}var Jf,T_;function MC(){if(T_)return Jf;T_=1;var e=ct();Jf=t;function t(r,i,o){e.isArray(i)||(i=[i]);var a=(r.isDirected()?r.successors:r.neighbors).bind(r),s=[],u={};return e.each(i,function(l){if(!r.hasNode(l))throw new Error("Graph does not have node: "+l);n(r,l,o==="post",u,a,s)}),s}function n(r,i,o,a,s,u){e.has(a,i)||(a[i]=!0,o||u.push(i),e.each(s(i),function(l){n(r,l,o,a,s,u)}),o&&u.push(i))}return Jf}var ed,R_;function Dq(){if(R_)return ed;R_=1;var e=MC();ed=t;function t(n,r){return e(n,r,"post")}return ed}var td,N_;function $q(){if(N_)return td;N_=1;var e=MC();td=t;function t(n,r){return e(n,r,"pre")}return td}var nd,I_;function Bq(){if(I_)return nd;I_=1;var e=ct(),t=Fv(),n=PC();nd=r;function r(i,o){var a=new t,s={},u=new n,l;function c(d){var h=d.v===l?d.w:d.v,g=u.priority(h);if(g!==void 0){var v=o(d);v<g&&(s[h]=l,u.decrease(h,v))}}if(i.nodeCount()===0)return a;e.each(i.nodes(),function(d){u.add(d,Number.POSITIVE_INFINITY),a.setNode(d)}),u.decrease(i.nodes()[0],0);for(var f=!1;u.size()>0;){if(l=u.removeMin(),e.has(s,l))a.setEdge(l,s[l]);else{if(f)throw new Error("Input graph is not connected: "+i);f=!0}i.nodeEdges(l).forEach(c)}return a}return nd}var rd,P_;function Uq(){return P_||(P_=1,rd={components:Mq(),dijkstra:jC(),dijkstraAll:Lq(),findCycles:Oq(),floydWarshall:zq(),isAcyclic:Fq(),postorder:Dq(),preorder:$q(),prim:Bq(),tarjan:qC(),topsort:AC()}),rd}var id,j_;function Hq(){if(j_)return id;j_=1;var e=qq();return id={Graph:e.Graph,json:Aq(),alg:Uq(),version:e.version},id}var $a;if(typeof Ev=="function")try{$a=Hq()}catch{}$a||($a=window.graphlib);var St=$a,od,q_;function Vq(){if(q_)return od;q_=1;var e=aC(),t=1,n=4;function r(i){return e(i,t|n)}return od=r,od}var ad,A_;function Rs(){if(A_)return ad;A_=1;var e=Qr(),t=Xt(),n=_s(),r=lt();function i(o,a,s){if(!r(s))return!1;var u=typeof a;return(u=="number"?t(s)&&n(a,s.length):u=="string"&&a in s)?e(s[a],o):!1}return ad=i,ad}var sd,M_;function Gq(){if(M_)return sd;M_=1;var e=Ts(),t=Qr(),n=Rs(),r=ir(),i=Object.prototype,o=i.hasOwnProperty,a=e(function(s,u){s=Object(s);var l=-1,c=u.length,f=c>2?u[2]:void 0;for(f&&n(u[0],u[1],f)&&(c=1);++l<c;)for(var d=u[l],h=r(d),g=-1,v=h.length;++g<v;){var y=h[g],p=s[y];(p===void 0||t(p,i[y])&&!o.call(s,y))&&(s[y]=d[y])}return s});return sd=a,sd}var ud,L_;function Wq(){if(L_)return ud;L_=1;var e=Zt(),t=Xt(),n=qn();function r(i){return function(o,a,s){var u=Object(o);if(!t(o)){var l=e(a,3);o=n(o),a=function(f){return l(u[f],f,u)}}var c=i(o,a,s);return c>-1?u[l?o[c]:c]:void 0}}return ud=r,ud}var ld,O_;function Kq(){if(O_)return ld;O_=1;var e=/\s/;function t(n){for(var r=n.length;r--&&e.test(n.charAt(r)););return r}return ld=t,ld}var cd,z_;function Yq(){if(z_)return cd;z_=1;var e=Kq(),t=/^\s+/;function n(r){return r&&r.slice(0,e(r)+1).replace(t,"")}return cd=n,cd}var fd,F_;function Qq(){if(F_)return fd;F_=1;var e=Yq(),t=lt(),n=ei(),r=NaN,i=/^[-+]0x[0-9a-f]+$/i,o=/^0b[01]+$/i,a=/^0o[0-7]+$/i,s=parseInt;function u(l){if(typeof l=="number")return l;if(n(l))return r;if(t(l)){var c=typeof l.valueOf=="function"?l.valueOf():l;l=t(c)?c+"":c}if(typeof l!="string")return l===0?l:+l;l=e(l);var f=o.test(l);return f||a.test(l)?s(l.slice(2),f?2:8):i.test(l)?r:+l}return fd=u,fd}var dd,D_;function LC(){if(D_)return dd;D_=1;var e=Qq(),t=1/0,n=17976931348623157e292;function r(i){if(!i)return i===0?i:0;if(i=e(i),i===t||i===-t){var o=i<0?-1:1;return o*n}return i===i?i:0}return dd=r,dd}var hd,$_;function Xq(){if($_)return hd;$_=1;var e=LC();function t(n){var r=e(n),i=r%1;return r===r?i?r-i:r:0}return hd=t,hd}var pd,B_;function Zq(){if(B_)return pd;B_=1;var e=RC(),t=Zt(),n=Xq(),r=Math.max;function i(o,a,s){var u=o==null?0:o.length;if(!u)return-1;var l=s==null?0:n(s);return l<0&&(l=r(u+l,0)),e(o,t(a,3),l)}return pd=i,pd}var vd,U_;function Jq(){if(U_)return vd;U_=1;var e=Wq(),t=Zq(),n=e(t);return vd=n,vd}var gd,H_;function OC(){if(H_)return gd;H_=1;var e=zv();function t(n){var r=n==null?0:n.length;return r?e(n,1):[]}return gd=t,gd}var md,V_;function eA(){if(V_)return md;V_=1;var e=Av(),t=sC(),n=ir();function r(i,o){return i==null?i:e(i,t(o),n)}return md=r,md}var yd,G_;function tA(){if(G_)return yd;G_=1;function e(t){var n=t==null?0:t.length;return n?t[n-1]:void 0}return yd=e,yd}var _d,W_;function nA(){if(W_)return _d;W_=1;var e=ms(),t=Mv(),n=Zt();function r(i,o){var a={};return o=n(o,3),t(i,function(s,u,l){e(a,u,o(s,u,l))}),a}return _d=r,_d}var xd,K_;function Dv(){if(K_)return xd;K_=1;var e=ei();function t(n,r,i){for(var o=-1,a=n.length;++o<a;){var s=n[o],u=r(s);if(u!=null&&(l===void 0?u===u&&!e(u):i(u,l)))var l=u,c=s}return c}return xd=t,xd}var wd,Y_;function rA(){if(Y_)return wd;Y_=1;function e(t,n){return t>n}return wd=e,wd}var Sd,Q_;function iA(){if(Q_)return Sd;Q_=1;var e=Dv(),t=rA(),n=or();function r(i){return i&&i.length?e(i,n,t):void 0}return Sd=r,Sd}var Ed,X_;function zC(){if(X_)return Ed;X_=1;var e=ms(),t=Qr();function n(r,i,o){(o!==void 0&&!t(r[i],o)||o===void 0&&!(i in r))&&e(r,i,o)}return Ed=n,Ed}var Cd,Z_;function oA(){if(Z_)return Cd;Z_=1;var e=nr(),t=Ss(),n=jt(),r="[object Object]",i=Function.prototype,o=Object.prototype,a=i.toString,s=o.hasOwnProperty,u=a.call(Object);function l(c){if(!n(c)||e(c)!=r)return!1;var f=t(c);if(f===null)return!0;var d=s.call(f,"constructor")&&f.constructor;return typeof d=="function"&&d instanceof d&&a.call(d)==u}return Cd=l,Cd}var kd,J_;function FC(){if(J_)return kd;J_=1;function e(t,n){if(!(n==="constructor"&&typeof t[n]=="function")&&n!="__proto__")return t[n]}return kd=e,kd}var bd,ex;function aA(){if(ex)return bd;ex=1;var e=po(),t=ir();function n(r){return e(r,t(r))}return bd=n,bd}var Td,tx;function sA(){if(tx)return Td;tx=1;var e=zC(),t=KE(),n=rC(),r=YE(),i=oC(),o=vo(),a=ge(),s=NC(),u=Zr(),l=ho(),c=lt(),f=oA(),d=go(),h=FC(),g=aA();function v(y,p,m,_,x,S,E){var C=h(y,m),T=h(p,m),M=E.get(T);if(M){e(y,m,M);return}var k=S?S(C,T,m+"",y,p,E):void 0,j=k===void 0;if(j){var B=a(T),H=!B&&u(T),b=!B&&!H&&d(T);k=T,B||H||b?a(C)?k=C:s(C)?k=r(C):H?(j=!1,k=t(T,!0)):b?(j=!1,k=n(T,!0)):k=[]:f(T)||o(T)?(k=C,o(C)?k=g(C):(!c(C)||l(C))&&(k=i(T))):j=!1}j&&(E.set(T,k),x(k,T,_,S,E),E.delete(T)),e(y,m,k)}return Td=v,Td}var Rd,nx;function uA(){if(nx)return Rd;nx=1;var e=gs(),t=zC(),n=Av(),r=sA(),i=lt(),o=ir(),a=FC();function s(u,l,c,f,d){u!==l&&n(l,function(h,g){if(d||(d=new e),i(h))r(u,l,g,c,s,f,d);else{var v=f?f(a(u,g),h,g+"",u,l,d):void 0;v===void 0&&(v=h),t(u,g,v)}},o)}return Rd=s,Rd}var Nd,rx;function lA(){if(rx)return Nd;rx=1;var e=Ts(),t=Rs();function n(r){return e(function(i,o){var a=-1,s=o.length,u=s>1?o[s-1]:void 0,l=s>2?o[2]:void 0;for(u=r.length>3&&typeof u=="function"?(s--,u):void 0,l&&t(o[0],o[1],l)&&(u=s<3?void 0:u,s=1),i=Object(i);++a<s;){var c=o[a];c&&r(i,c,a,u)}return i})}return Nd=n,Nd}var Id,ix;function cA(){if(ix)return Id;ix=1;var e=uA(),t=lA(),n=t(function(r,i,o){e(r,i,o)});return Id=n,Id}var Pd,ox;function DC(){if(ox)return Pd;ox=1;function e(t,n){return t<n}return Pd=e,Pd}var jd,ax;function fA(){if(ax)return jd;ax=1;var e=Dv(),t=DC(),n=or();function r(i){return i&&i.length?e(i,n,t):void 0}return jd=r,jd}var qd,sx;function dA(){if(sx)return qd;sx=1;var e=Dv(),t=Zt(),n=DC();function r(i,o){return i&&i.length?e(i,t(o,2),n):void 0}return qd=r,qd}var Ad,ux;function hA(){if(ux)return Ad;ux=1;var e=wt(),t=function(){return e.Date.now()};return Ad=t,Ad}var Md,lx;function pA(){if(lx)return Md;lx=1;var e=ys(),t=ks(),n=_s(),r=lt(),i=mo();function o(a,s,u,l){if(!r(a))return a;s=t(s,a);for(var c=-1,f=s.length,d=f-1,h=a;h!=null&&++c<f;){var g=i(s[c]),v=u;if(g==="__proto__"||g==="constructor"||g==="prototype")return a;if(c!=d){var y=h[g];v=l?l(y,g,h):void 0,v===void 0&&(v=r(y)?y:n(s[c+1])?[]:{})}e(h,g,v),h=h[g]}return a}return Md=o,Md}var Ld,cx;function vA(){if(cx)return Ld;cx=1;var e=bs(),t=pA(),n=ks();function r(i,o,a){for(var s=-1,u=o.length,l={};++s<u;){var c=o[s],f=e(i,c);a(f,c)&&t(l,n(c,i),f)}return l}return Ld=r,Ld}var Od,fx;function gA(){if(fx)return Od;fx=1;var e=vA(),t=yC();function n(r,i){return e(r,i,function(o,a){return t(r,a)})}return Od=n,Od}var zd,dx;function mA(){if(dx)return zd;dx=1;var e=OC(),t=bC(),n=TC();function r(i){return n(t(i,void 0,e),i+"")}return zd=r,zd}var Fd,hx;function yA(){if(hx)return Fd;hx=1;var e=gA(),t=mA(),n=t(function(r,i){return r==null?{}:e(r,i)});return Fd=n,Fd}var Dd,px;function _A(){if(px)return Dd;px=1;var e=Math.ceil,t=Math.max;function n(r,i,o,a){for(var s=-1,u=t(e((i-r)/(o||1)),0),l=Array(u);u--;)l[a?u:++s]=r,r+=o;return l}return Dd=n,Dd}var $d,vx;function xA(){if(vx)return $d;vx=1;var e=_A(),t=Rs(),n=LC();function r(i){return function(o,a,s){return s&&typeof s!="number"&&t(o,a,s)&&(a=s=void 0),o=n(o),a===void 0?(a=o,o=0):a=n(a),s=s===void 0?o<a?1:-1:n(s),e(o,a,s,i)}}return $d=r,$d}var Bd,gx;function wA(){if(gx)return Bd;gx=1;var e=xA(),t=e();return Bd=t,Bd}var Ud,mx;function SA(){if(mx)return Ud;mx=1;function e(t,n){var r=t.length;for(t.sort(n);r--;)t[r]=t[r].value;return t}return Ud=e,Ud}var Hd,yx;function EA(){if(yx)return Hd;yx=1;var e=ei();function t(n,r){if(n!==r){var i=n!==void 0,o=n===null,a=n===n,s=e(n),u=r!==void 0,l=r===null,c=r===r,f=e(r);if(!l&&!f&&!s&&n>r||s&&u&&c&&!l&&!f||o&&u&&c||!i&&c||!a)return 1;if(!o&&!s&&!f&&n<r||f&&i&&a&&!o&&!s||l&&i&&a||!u&&a||!c)return-1}return 0}return Hd=t,Hd}var Vd,_x;function CA(){if(_x)return Vd;_x=1;var e=EA();function t(n,r,i){for(var o=-1,a=n.criteria,s=r.criteria,u=a.length,l=i.length;++o<u;){var c=e(a[o],s[o]);if(c){if(o>=l)return c;var f=i[o];return c*(f=="desc"?-1:1)}}return n.index-r.index}return Vd=t,Vd}var Gd,xx;function kA(){if(xx)return Gd;xx=1;var e=Cs(),t=bs(),n=Zt(),r=EC(),i=SA(),o=xs(),a=CA(),s=or(),u=ge();function l(c,f,d){f.length?f=e(f,function(v){return u(v)?function(y){return t(y,v.length===1?v[0]:v)}:v}):f=[s];var h=-1;f=e(f,o(n));var g=r(c,function(v,y,p){var m=e(f,function(_){return _(v)});return{criteria:m,index:++h,value:v}});return i(g,function(v,y){return a(v,y,d)})}return Gd=l,Gd}var Wd,wx;function bA(){if(wx)return Wd;wx=1;var e=zv(),t=kA(),n=Ts(),r=Rs(),i=n(function(o,a){if(o==null)return[];var s=a.length;return s>1&&r(o,a[0],a[1])?a=[]:s>2&&r(a[0],a[1],a[2])&&(a=[a[0]]),t(o,e(a,1),[])});return Wd=i,Wd}var Kd,Sx;function TA(){if(Sx)return Kd;Sx=1;var e=gC(),t=0;function n(r){var i=++t;return e(r)+i}return Kd=n,Kd}var Yd,Ex;function RA(){if(Ex)return Yd;Ex=1;function e(t,n,r){for(var i=-1,o=t.length,a=n.length,s={};++i<o;){var u=i<a?n[i]:void 0;r(s,t[i],u)}return s}return Yd=e,Yd}var Qd,Cx;function NA(){if(Cx)return Qd;Cx=1;var e=ys(),t=RA();function n(r,i){return t(r||[],i||[],e)}return Qd=n,Qd}var Ba;if(typeof Ev=="function")try{Ba={cloneDeep:Vq(),constant:qv(),defaults:Gq(),each:lC(),filter:xC(),find:Jq(),flatten:OC(),forEach:uC(),forIn:eA(),has:wC(),isUndefined:SC(),last:tA(),map:CC(),mapValues:nA(),max:iA(),merge:cA(),min:fA(),minBy:dA(),now:hA(),pick:yA(),range:wA(),reduce:kC(),sortBy:bA(),uniqueId:TA(),values:IC(),zipObject:NA()}}catch{}Ba||(Ba=window._);var ue=Ba,IA=Ns;function Ns(){var e={};e._next=e._prev=e,this._sentinel=e}Ns.prototype.dequeue=function(){var e=this._sentinel,t=e._prev;if(t!==e)return $C(t),t};Ns.prototype.enqueue=function(e){var t=this._sentinel;e._prev&&e._next&&$C(e),e._next=t._next,t._next._prev=e,t._next=e,e._prev=t};Ns.prototype.toString=function(){for(var e=[],t=this._sentinel,n=t._prev;n!==t;)e.push(JSON.stringify(n,PA)),n=n._prev;return"["+e.join(", ")+"]"};function $C(e){e._prev._next=e._next,e._next._prev=e._prev,delete e._next,delete e._prev}function PA(e,t){if(e!=="_next"&&e!=="_prev")return t}var $t=ue,jA=St.Graph,qA=IA,AA=LA,MA=$t.constant(1);function LA(e,t){if(e.nodeCount()<=1)return[];var n=zA(e,t||MA),r=OA(n.graph,n.buckets,n.zeroIdx);return $t.flatten($t.map(r,function(i){return e.outEdges(i.v,i.w)}),!0)}function OA(e,t,n){for(var r=[],i=t[t.length-1],o=t[0],a;e.nodeCount();){for(;a=o.dequeue();)Xd(e,t,n,a);for(;a=i.dequeue();)Xd(e,t,n,a);if(e.nodeCount()){for(var s=t.length-2;s>0;--s)if(a=t[s].dequeue(),a){r=r.concat(Xd(e,t,n,a,!0));break}}}return r}function Xd(e,t,n,r,i){var o=i?[]:void 0;return $t.forEach(e.inEdges(r.v),function(a){var s=e.edge(a),u=e.node(a.v);i&&o.push({v:a.v,w:a.w}),u.out-=s,lp(t,n,u)}),$t.forEach(e.outEdges(r.v),function(a){var s=e.edge(a),u=a.w,l=e.node(u);l.in-=s,lp(t,n,l)}),e.removeNode(r.v),o}function zA(e,t){var n=new jA,r=0,i=0;$t.forEach(e.nodes(),function(s){n.setNode(s,{v:s,in:0,out:0})}),$t.forEach(e.edges(),function(s){var u=n.edge(s.v,s.w)||0,l=t(s),c=u+l;n.setEdge(s.v,s.w,c),i=Math.max(i,n.node(s.v).out+=l),r=Math.max(r,n.node(s.w).in+=l)});var o=$t.range(i+r+3).map(function(){return new qA}),a=r+1;return $t.forEach(n.nodes(),function(s){lp(o,a,n.node(s))}),{graph:n,buckets:o,zeroIdx:a}}function lp(e,t,n){n.out?n.in?e[n.out-n.in+t].enqueue(n):e[e.length-1].enqueue(n):e[0].enqueue(n)}var Bn=ue,FA=AA,DA={run:$A,undo:UA};function $A(e){var t=e.graph().acyclicer==="greedy"?FA(e,n(e)):BA(e);Bn.forEach(t,function(r){var i=e.edge(r);e.removeEdge(r),i.forwardName=r.name,i.reversed=!0,e.setEdge(r.w,r.v,i,Bn.uniqueId("rev"))});function n(r){return function(i){return r.edge(i).weight}}}function BA(e){var t=[],n={},r={};function i(o){Bn.has(r,o)||(r[o]=!0,n[o]=!0,Bn.forEach(e.outEdges(o),function(a){Bn.has(n,a.w)?t.push(a):i(a.w)}),delete n[o])}return Bn.forEach(e.nodes(),i),t}function UA(e){Bn.forEach(e.edges(),function(t){var n=e.edge(t);if(n.reversed){e.removeEdge(t);var r=n.forwardName;delete n.reversed,delete n.forwardName,e.setEdge(t.w,t.v,n,r)}})}var Y=ue,BC=St.Graph,We={addDummyNode:UC,simplify:HA,asNonCompoundGraph:VA,successorWeights:GA,predecessorWeights:WA,intersectRect:KA,buildLayerMatrix:YA,normalizeRanks:QA,removeEmptyRanks:XA,addBorderNode:ZA,maxRank:HC,partition:JA,time:eM,notime:tM};function UC(e,t,n,r){var i;do i=Y.uniqueId(r);while(e.hasNode(i));return n.dummy=t,e.setNode(i,n),i}function HA(e){var t=new BC().setGraph(e.graph());return Y.forEach(e.nodes(),function(n){t.setNode(n,e.node(n))}),Y.forEach(e.edges(),function(n){var r=t.edge(n.v,n.w)||{weight:0,minlen:1},i=e.edge(n);t.setEdge(n.v,n.w,{weight:r.weight+i.weight,minlen:Math.max(r.minlen,i.minlen)})}),t}function VA(e){var t=new BC({multigraph:e.isMultigraph()}).setGraph(e.graph());return Y.forEach(e.nodes(),function(n){e.children(n).length||t.setNode(n,e.node(n))}),Y.forEach(e.edges(),function(n){t.setEdge(n,e.edge(n))}),t}function GA(e){var t=Y.map(e.nodes(),function(n){var r={};return Y.forEach(e.outEdges(n),function(i){r[i.w]=(r[i.w]||0)+e.edge(i).weight}),r});return Y.zipObject(e.nodes(),t)}function WA(e){var t=Y.map(e.nodes(),function(n){var r={};return Y.forEach(e.inEdges(n),function(i){r[i.v]=(r[i.v]||0)+e.edge(i).weight}),r});return Y.zipObject(e.nodes(),t)}function KA(e,t){var n=e.x,r=e.y,i=t.x-n,o=t.y-r,a=e.width/2,s=e.height/2;if(!i&&!o)throw new Error("Not possible to find intersection inside of the rectangle");var u,l;return Math.abs(o)*a>Math.abs(i)*s?(o<0&&(s=-s),u=s*i/o,l=s):(i<0&&(a=-a),u=a,l=a*o/i),{x:n+u,y:r+l}}function YA(e){var t=Y.map(Y.range(HC(e)+1),function(){return[]});return Y.forEach(e.nodes(),function(n){var r=e.node(n),i=r.rank;Y.isUndefined(i)||(t[i][r.order]=n)}),t}function QA(e){var t=Y.min(Y.map(e.nodes(),function(n){return e.node(n).rank}));Y.forEach(e.nodes(),function(n){var r=e.node(n);Y.has(r,"rank")&&(r.rank-=t)})}function XA(e){var t=Y.min(Y.map(e.nodes(),function(o){return e.node(o).rank})),n=[];Y.forEach(e.nodes(),function(o){var a=e.node(o).rank-t;n[a]||(n[a]=[]),n[a].push(o)});var r=0,i=e.graph().nodeRankFactor;Y.forEach(n,function(o,a){Y.isUndefined(o)&&a%i!==0?--r:r&&Y.forEach(o,function(s){e.node(s).rank+=r})})}function ZA(e,t,n,r){var i={width:0,height:0};return arguments.length>=4&&(i.rank=n,i.order=r),UC(e,"border",i,t)}function HC(e){return Y.max(Y.map(e.nodes(),function(t){var n=e.node(t).rank;if(!Y.isUndefined(n))return n}))}function JA(e,t){var n={lhs:[],rhs:[]};return Y.forEach(e,function(r){t(r)?n.lhs.push(r):n.rhs.push(r)}),n}function eM(e,t){var n=Y.now();try{return t()}finally{console.log(e+" time: "+(Y.now()-n)+"ms")}}function tM(e,t){return t()}var VC=ue,nM=We,rM={run:iM,undo:aM};function iM(e){e.graph().dummyChains=[],VC.forEach(e.edges(),function(t){oM(e,t)})}function oM(e,t){var n=t.v,r=e.node(n).rank,i=t.w,o=e.node(i).rank,a=t.name,s=e.edge(t),u=s.labelRank;if(o!==r+1){e.removeEdge(t);var l,c,f;for(f=0,++r;r<o;++f,++r)s.points=[],c={width:0,height:0,edgeLabel:s,edgeObj:t,rank:r},l=nM.addDummyNode(e,"edge",c,"_d"),r===u&&(c.width=s.width,c.height=s.height,c.dummy="edge-label",c.labelpos=s.labelpos),e.setEdge(n,l,{weight:s.weight},a),f===0&&e.graph().dummyChains.push(l),n=l;e.setEdge(n,i,{weight:s.weight},a)}}function aM(e){VC.forEach(e.graph().dummyChains,function(t){var n=e.node(t),r=n.edgeLabel,i;for(e.setEdge(n.edgeObj,r);n.dummy;)i=e.successors(t)[0],e.removeNode(t),r.points.push({x:n.x,y:n.y}),n.dummy==="edge-label"&&(r.x=n.x,r.y=n.y,r.width=n.width,r.height=n.height),t=i,n=e.node(t)})}var Vo=ue,Is={longestPath:sM,slack:uM};function sM(e){var t={};function n(r){var i=e.node(r);if(Vo.has(t,r))return i.rank;t[r]=!0;var o=Vo.min(Vo.map(e.outEdges(r),function(a){return n(a.w)-e.edge(a).minlen}));return(o===Number.POSITIVE_INFINITY||o===void 0||o===null)&&(o=0),i.rank=o}Vo.forEach(e.sources(),n)}function uM(e,t){return e.node(t.w).rank-e.node(t.v).rank-e.edge(t).minlen}var Ua=ue,lM=St.Graph,Ha=Is.slack,GC=cM;function cM(e){var t=new lM({directed:!1}),n=e.nodes()[0],r=e.nodeCount();t.setNode(n,{});for(var i,o;fM(t,e)<r;)i=dM(t,e),o=t.hasNode(i.v)?Ha(e,i):-Ha(e,i),hM(t,e,o);return t}function fM(e,t){function n(r){Ua.forEach(t.nodeEdges(r),function(i){var o=i.v,a=r===o?i.w:o;!e.hasNode(a)&&!Ha(t,i)&&(e.setNode(a,{}),e.setEdge(r,a,{}),n(a))})}return Ua.forEach(e.nodes(),n),e.nodeCount()}function dM(e,t){return Ua.minBy(t.edges(),function(n){if(e.hasNode(n.v)!==e.hasNode(n.w))return Ha(t,n)})}function hM(e,t,n){Ua.forEach(e.nodes(),function(r){t.node(r).rank+=n})}var Yt=ue,pM=GC,vM=Is.slack,gM=Is.longestPath,mM=St.alg.preorder,yM=St.alg.postorder,_M=We.simplify,xM=ar;ar.initLowLimValues=Bv;ar.initCutValues=$v;ar.calcCutValue=WC;ar.leaveEdge=YC;ar.enterEdge=QC;ar.exchangeEdges=XC;function ar(e){e=_M(e),gM(e);var t=pM(e);Bv(t),$v(t,e);for(var n,r;n=YC(t);)r=QC(t,e,n),XC(t,e,n,r)}function $v(e,t){var n=yM(e,e.nodes());n=n.slice(0,n.length-1),Yt.forEach(n,function(r){wM(e,t,r)})}function wM(e,t,n){var r=e.node(n),i=r.parent;e.edge(n,i).cutvalue=WC(e,t,n)}function WC(e,t,n){var r=e.node(n),i=r.parent,o=!0,a=t.edge(n,i),s=0;return a||(o=!1,a=t.edge(i,n)),s=a.weight,Yt.forEach(t.nodeEdges(n),function(u){var l=u.v===n,c=l?u.w:u.v;if(c!==i){var f=l===o,d=t.edge(u).weight;if(s+=f?d:-d,EM(e,n,c)){var h=e.edge(n,c).cutvalue;s+=f?-h:h}}}),s}function Bv(e,t){arguments.length<2&&(t=e.nodes()[0]),KC(e,{},1,t)}function KC(e,t,n,r,i){var o=n,a=e.node(r);return t[r]=!0,Yt.forEach(e.neighbors(r),function(s){Yt.has(t,s)||(n=KC(e,t,n,s,r))}),a.low=o,a.lim=n++,i?a.parent=i:delete a.parent,n}function YC(e){return Yt.find(e.edges(),function(t){return e.edge(t).cutvalue<0})}function QC(e,t,n){var r=n.v,i=n.w;t.hasEdge(r,i)||(r=n.w,i=n.v);var o=e.node(r),a=e.node(i),s=o,u=!1;o.lim>a.lim&&(s=a,u=!0);var l=Yt.filter(t.edges(),function(c){return u===kx(e,e.node(c.v),s)&&u!==kx(e,e.node(c.w),s)});return Yt.minBy(l,function(c){return vM(t,c)})}function XC(e,t,n,r){var i=n.v,o=n.w;e.removeEdge(i,o),e.setEdge(r.v,r.w,{}),Bv(e),$v(e,t),SM(e,t)}function SM(e,t){var n=Yt.find(e.nodes(),function(i){return!t.node(i).parent}),r=mM(e,n);r=r.slice(1),Yt.forEach(r,function(i){var o=e.node(i).parent,a=t.edge(i,o),s=!1;a||(a=t.edge(o,i),s=!0),t.node(i).rank=t.node(o).rank+(s?a.minlen:-a.minlen)})}function EM(e,t,n){return e.hasEdge(t,n)}function kx(e,t,n){return n.low<=t.lim&&t.lim<=n.lim}var CM=Is,ZC=CM.longestPath,kM=GC,bM=xM,TM=RM;function RM(e){switch(e.graph().ranker){case"network-simplex":bx(e);break;case"tight-tree":IM(e);break;case"longest-path":NM(e);break;default:bx(e)}}var NM=ZC;function IM(e){ZC(e),kM(e)}function bx(e){bM(e)}var cp=ue,PM=jM;function jM(e){var t=AM(e);cp.forEach(e.graph().dummyChains,function(n){for(var r=e.node(n),i=r.edgeObj,o=qM(e,t,i.v,i.w),a=o.path,s=o.lca,u=0,l=a[u],c=!0;n!==i.w;){if(r=e.node(n),c){for(;(l=a[u])!==s&&e.node(l).maxRank<r.rank;)u++;l===s&&(c=!1)}if(!c){for(;u<a.length-1&&e.node(l=a[u+1]).minRank<=r.rank;)u++;l=a[u]}e.setParent(n,l),n=e.successors(n)[0]}})}function qM(e,t,n,r){var i=[],o=[],a=Math.min(t[n].low,t[r].low),s=Math.max(t[n].lim,t[r].lim),u,l;u=n;do u=e.parent(u),i.push(u);while(u&&(t[u].low>a||s>t[u].lim));for(l=u,u=r;(u=e.parent(u))!==l;)o.push(u);return{path:i.concat(o.reverse()),lca:l}}function AM(e){var t={},n=0;function r(i){var o=n;cp.forEach(e.children(i),r),t[i]={low:o,lim:n++}}return cp.forEach(e.children(),r),t}var Bt=ue,fp=We,MM={run:LM,cleanup:FM};function LM(e){var t=fp.addDummyNode(e,"root",{},"_root"),n=OM(e),r=Bt.max(Bt.values(n))-1,i=2*r+1;e.graph().nestingRoot=t,Bt.forEach(e.edges(),function(a){e.edge(a).minlen*=i});var o=zM(e)+1;Bt.forEach(e.children(),function(a){JC(e,t,i,o,r,n,a)}),e.graph().nodeRankFactor=i}function JC(e,t,n,r,i,o,a){var s=e.children(a);if(!s.length){a!==t&&e.setEdge(t,a,{weight:0,minlen:n});return}var u=fp.addBorderNode(e,"_bt"),l=fp.addBorderNode(e,"_bb"),c=e.node(a);e.setParent(u,a),c.borderTop=u,e.setParent(l,a),c.borderBottom=l,Bt.forEach(s,function(f){JC(e,t,n,r,i,o,f);var d=e.node(f),h=d.borderTop?d.borderTop:f,g=d.borderBottom?d.borderBottom:f,v=d.borderTop?r:2*r,y=h!==g?1:i-o[a]+1;e.setEdge(u,h,{weight:v,minlen:y,nestingEdge:!0}),e.setEdge(g,l,{weight:v,minlen:y,nestingEdge:!0})}),e.parent(a)||e.setEdge(t,u,{weight:0,minlen:i+o[a]})}function OM(e){var t={};function n(r,i){var o=e.children(r);o&&o.length&&Bt.forEach(o,function(a){n(a,i+1)}),t[r]=i}return Bt.forEach(e.children(),function(r){n(r,1)}),t}function zM(e){return Bt.reduce(e.edges(),function(t,n){return t+e.edge(n).weight},0)}function FM(e){var t=e.graph();e.removeNode(t.nestingRoot),delete t.nestingRoot,Bt.forEach(e.edges(),function(n){var r=e.edge(n);r.nestingEdge&&e.removeEdge(n)})}var Zd=ue,DM=We,$M=BM;function BM(e){function t(n){var r=e.children(n),i=e.node(n);if(r.length&&Zd.forEach(r,t),Zd.has(i,"minRank")){i.borderLeft=[],i.borderRight=[];for(var o=i.minRank,a=i.maxRank+1;o<a;++o)Tx(e,"borderLeft","_bl",n,i,o),Tx(e,"borderRight","_br",n,i,o)}}Zd.forEach(e.children(),t)}function Tx(e,t,n,r,i,o){var a={width:0,height:0,rank:o,borderType:t},s=i[t][o-1],u=DM.addDummyNode(e,"border",a,n);i[t][o]=u,e.setParent(u,r),s&&e.setEdge(s,u,{weight:1})}var bt=ue,UM={adjust:HM,undo:VM};function HM(e){var t=e.graph().rankdir.toLowerCase();(t==="lr"||t==="rl")&&ek(e)}function VM(e){var t=e.graph().rankdir.toLowerCase();(t==="bt"||t==="rl")&&GM(e),(t==="lr"||t==="rl")&&(WM(e),ek(e))}function ek(e){bt.forEach(e.nodes(),function(t){Rx(e.node(t))}),bt.forEach(e.edges(),function(t){Rx(e.edge(t))})}function Rx(e){var t=e.width;e.width=e.height,e.height=t}function GM(e){bt.forEach(e.nodes(),function(t){Jd(e.node(t))}),bt.forEach(e.edges(),function(t){var n=e.edge(t);bt.forEach(n.points,Jd),bt.has(n,"y")&&Jd(n)})}function Jd(e){e.y=-e.y}function WM(e){bt.forEach(e.nodes(),function(t){eh(e.node(t))}),bt.forEach(e.edges(),function(t){var n=e.edge(t);bt.forEach(n.points,eh),bt.has(n,"x")&&eh(n)})}function eh(e){var t=e.x;e.x=e.y,e.y=t}var At=ue,KM=YM;function YM(e){var t={},n=At.filter(e.nodes(),function(s){return!e.children(s).length}),r=At.max(At.map(n,function(s){return e.node(s).rank})),i=At.map(At.range(r+1),function(){return[]});function o(s){if(!At.has(t,s)){t[s]=!0;var u=e.node(s);i[u.rank].push(s),At.forEach(e.successors(s),o)}}var a=At.sortBy(n,function(s){return e.node(s).rank});return At.forEach(a,o),i}var nn=ue,QM=XM;function XM(e,t){for(var n=0,r=1;r<t.length;++r)n+=ZM(e,t[r-1],t[r]);return n}function ZM(e,t,n){for(var r=nn.zipObject(n,nn.map(n,function(l,c){return c})),i=nn.flatten(nn.map(t,function(l){return nn.sortBy(nn.map(e.outEdges(l),function(c){return{pos:r[c.w],weight:e.edge(c).weight}}),"pos")}),!0),o=1;o<n.length;)o<<=1;var a=2*o-1;o-=1;var s=nn.map(new Array(a),function(){return 0}),u=0;return nn.forEach(i.forEach(function(l){var c=l.pos+o;s[c]+=l.weight;for(var f=0;c>0;)c%2&&(f+=s[c+1]),c=c-1>>1,s[c]+=l.weight;u+=l.weight*f})),u}var Nx=ue,JM=eL;function eL(e,t){return Nx.map(t,function(n){var r=e.inEdges(n);if(r.length){var i=Nx.reduce(r,function(o,a){var s=e.edge(a),u=e.node(a.v);return{sum:o.sum+s.weight*u.order,weight:o.weight+s.weight}},{sum:0,weight:0});return{v:n,barycenter:i.sum/i.weight,weight:i.weight}}else return{v:n}})}var Ye=ue,tL=nL;function nL(e,t){var n={};Ye.forEach(e,function(i,o){var a=n[i.v]={indegree:0,in:[],out:[],vs:[i.v],i:o};Ye.isUndefined(i.barycenter)||(a.barycenter=i.barycenter,a.weight=i.weight)}),Ye.forEach(t.edges(),function(i){var o=n[i.v],a=n[i.w];!Ye.isUndefined(o)&&!Ye.isUndefined(a)&&(a.indegree++,o.out.push(n[i.w]))});var r=Ye.filter(n,function(i){return!i.indegree});return rL(r)}function rL(e){var t=[];function n(o){return function(a){a.merged||(Ye.isUndefined(a.barycenter)||Ye.isUndefined(o.barycenter)||a.barycenter>=o.barycenter)&&iL(o,a)}}function r(o){return function(a){a.in.push(o),--a.indegree===0&&e.push(a)}}for(;e.length;){var i=e.pop();t.push(i),Ye.forEach(i.in.reverse(),n(i)),Ye.forEach(i.out,r(i))}return Ye.map(Ye.filter(t,function(o){return!o.merged}),function(o){return Ye.pick(o,["vs","i","barycenter","weight"])})}function iL(e,t){var n=0,r=0;e.weight&&(n+=e.barycenter*e.weight,r+=e.weight),t.weight&&(n+=t.barycenter*t.weight,r+=t.weight),e.vs=t.vs.concat(e.vs),e.barycenter=n/r,e.weight=r,e.i=Math.min(t.i,e.i),t.merged=!0}var wi=ue,oL=We,aL=sL;function sL(e,t){var n=oL.partition(e,function(c){return wi.has(c,"barycenter")}),r=n.lhs,i=wi.sortBy(n.rhs,function(c){return-c.i}),o=[],a=0,s=0,u=0;r.sort(uL(!!t)),u=Ix(o,i,u),wi.forEach(r,function(c){u+=c.vs.length,o.push(c.vs),a+=c.barycenter*c.weight,s+=c.weight,u=Ix(o,i,u)});var l={vs:wi.flatten(o,!0)};return s&&(l.barycenter=a/s,l.weight=s),l}function Ix(e,t,n){for(var r;t.length&&(r=wi.last(t)).i<=n;)t.pop(),e.push(r.vs),n++;return n}function uL(e){return function(t,n){return t.barycenter<n.barycenter?-1:t.barycenter>n.barycenter?1:e?n.i-t.i:t.i-n.i}}var ln=ue,lL=JM,cL=tL,fL=aL,dL=tk;function tk(e,t,n,r){var i=e.children(t),o=e.node(t),a=o?o.borderLeft:void 0,s=o?o.borderRight:void 0,u={};a&&(i=ln.filter(i,function(g){return g!==a&&g!==s}));var l=lL(e,i);ln.forEach(l,function(g){if(e.children(g.v).length){var v=tk(e,g.v,n,r);u[g.v]=v,ln.has(v,"barycenter")&&pL(g,v)}});var c=cL(l,n);hL(c,u);var f=fL(c,r);if(a&&(f.vs=ln.flatten([a,f.vs,s],!0),e.predecessors(a).length)){var d=e.node(e.predecessors(a)[0]),h=e.node(e.predecessors(s)[0]);ln.has(f,"barycenter")||(f.barycenter=0,f.weight=0),f.barycenter=(f.barycenter*f.weight+d.order+h.order)/(f.weight+2),f.weight+=2}return f}function hL(e,t){ln.forEach(e,function(n){n.vs=ln.flatten(n.vs.map(function(r){return t[r]?t[r].vs:r}),!0)})}function pL(e,t){ln.isUndefined(e.barycenter)?(e.barycenter=t.barycenter,e.weight=t.weight):(e.barycenter=(e.barycenter*e.weight+t.barycenter*t.weight)/(e.weight+t.weight),e.weight+=t.weight)}var Si=ue,vL=St.Graph,gL=mL;function mL(e,t,n){var r=yL(e),i=new vL({compound:!0}).setGraph({root:r}).setDefaultNodeLabel(function(o){return e.node(o)});return Si.forEach(e.nodes(),function(o){var a=e.node(o),s=e.parent(o);(a.rank===t||a.minRank<=t&&t<=a.maxRank)&&(i.setNode(o),i.setParent(o,s||r),Si.forEach(e[n](o),function(u){var l=u.v===o?u.w:u.v,c=i.edge(l,o),f=Si.isUndefined(c)?0:c.weight;i.setEdge(l,o,{weight:e.edge(u).weight+f})}),Si.has(a,"minRank")&&i.setNode(o,{borderLeft:a.borderLeft[t],borderRight:a.borderRight[t]}))}),i}function yL(e){for(var t;e.hasNode(t=Si.uniqueId("_root")););return t}var _L=ue,xL=wL;function wL(e,t,n){var r={},i;_L.forEach(n,function(o){for(var a=e.parent(o),s,u;a;){if(s=e.parent(a),s?(u=r[s],r[s]=a):(u=i,i=a),u&&u!==a){t.setEdge(u,a);return}a=s}})}var En=ue,SL=KM,EL=QM,CL=dL,kL=gL,bL=xL,TL=St.Graph,Px=We,RL=NL;function NL(e){var t=Px.maxRank(e),n=jx(e,En.range(1,t+1),"inEdges"),r=jx(e,En.range(t-1,-1,-1),"outEdges"),i=SL(e);qx(e,i);for(var o=Number.POSITIVE_INFINITY,a,s=0,u=0;u<4;++s,++u){IL(s%2?n:r,s%4>=2),i=Px.buildLayerMatrix(e);var l=EL(e,i);l<o&&(u=0,a=En.cloneDeep(i),o=l)}qx(e,a)}function jx(e,t,n){return En.map(t,function(r){return kL(e,r,n)})}function IL(e,t){var n=new TL;En.forEach(e,function(r){var i=r.graph().root,o=CL(r,i,n,t);En.forEach(o.vs,function(a,s){r.node(a).order=s}),bL(r,n,o.vs)})}function qx(e,t){En.forEach(t,function(n){En.forEach(n,function(r,i){e.node(r).order=i})})}var $=ue,PL=St.Graph,jL=We,qL={positionX:HL};function AL(e,t){var n={};function r(i,o){var a=0,s=0,u=i.length,l=$.last(o);return $.forEach(o,function(c,f){var d=LL(e,c),h=d?e.node(d).order:u;(d||c===l)&&($.forEach(o.slice(s,f+1),function(g){$.forEach(e.predecessors(g),function(v){var y=e.node(v),p=y.order;(p<a||h<p)&&!(y.dummy&&e.node(g).dummy)&&nk(n,v,g)})}),s=f+1,a=h)}),o}return $.reduce(t,r),n}function ML(e,t){var n={};function r(o,a,s,u,l){var c;$.forEach($.range(a,s),function(f){c=o[f],e.node(c).dummy&&$.forEach(e.predecessors(c),function(d){var h=e.node(d);h.dummy&&(h.order<u||h.order>l)&&nk(n,d,c)})})}function i(o,a){var s=-1,u,l=0;return $.forEach(a,function(c,f){if(e.node(c).dummy==="border"){var d=e.predecessors(c);d.length&&(u=e.node(d[0]).order,r(a,l,f,s,u),l=f,s=u)}r(a,l,a.length,u,o.length)}),a}return $.reduce(t,i),n}function LL(e,t){if(e.node(t).dummy)return $.find(e.predecessors(t),function(n){return e.node(n).dummy})}function nk(e,t,n){if(t>n){var r=t;t=n,n=r}var i=e[t];i||(e[t]=i={}),i[n]=!0}function OL(e,t,n){if(t>n){var r=t;t=n,n=r}return $.has(e[t],n)}function zL(e,t,n,r){var i={},o={},a={};return $.forEach(t,function(s){$.forEach(s,function(u,l){i[u]=u,o[u]=u,a[u]=l})}),$.forEach(t,function(s){var u=-1;$.forEach(s,function(l){var c=r(l);if(c.length){c=$.sortBy(c,function(v){return a[v]});for(var f=(c.length-1)/2,d=Math.floor(f),h=Math.ceil(f);d<=h;++d){var g=c[d];o[l]===l&&u<a[g]&&!OL(n,l,g)&&(o[g]=l,o[l]=i[l]=i[g],u=a[g])}}})}),{root:i,align:o}}function FL(e,t,n,r,i){var o={},a=DL(e,t,n,i),s=i?"borderLeft":"borderRight";function u(f,d){for(var h=a.nodes(),g=h.pop(),v={};g;)v[g]?f(g):(v[g]=!0,h.push(g),h=h.concat(d(g))),g=h.pop()}function l(f){o[f]=a.inEdges(f).reduce(function(d,h){return Math.max(d,o[h.v]+a.edge(h))},0)}function c(f){var d=a.outEdges(f).reduce(function(g,v){return Math.min(g,o[v.w]-a.edge(v))},Number.POSITIVE_INFINITY),h=e.node(f);d!==Number.POSITIVE_INFINITY&&h.borderType!==s&&(o[f]=Math.max(o[f],d))}return u(l,a.predecessors.bind(a)),u(c,a.successors.bind(a)),$.forEach(r,function(f){o[f]=o[n[f]]}),o}function DL(e,t,n,r){var i=new PL,o=e.graph(),a=VL(o.nodesep,o.edgesep,r);return $.forEach(t,function(s){var u;$.forEach(s,function(l){var c=n[l];if(i.setNode(c),u){var f=n[u],d=i.edge(f,c);i.setEdge(f,c,Math.max(a(e,l,u),d||0))}u=l})}),i}function $L(e,t){return $.minBy($.values(t),function(n){var r=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY;return $.forIn(n,function(o,a){var s=GL(e,a)/2;r=Math.max(o+s,r),i=Math.min(o-s,i)}),r-i})}function BL(e,t){var n=$.values(t),r=$.min(n),i=$.max(n);$.forEach(["u","d"],function(o){$.forEach(["l","r"],function(a){var s=o+a,u=e[s],l;if(u!==t){var c=$.values(u);l=a==="l"?r-$.min(c):i-$.max(c),l&&(e[s]=$.mapValues(u,function(f){return f+l}))}})})}function UL(e,t){return $.mapValues(e.ul,function(n,r){if(t)return e[t.toLowerCase()][r];var i=$.sortBy($.map(e,r));return(i[1]+i[2])/2})}function HL(e){var t=jL.buildLayerMatrix(e),n=$.merge(AL(e,t),ML(e,t)),r={},i;$.forEach(["u","d"],function(a){i=a==="u"?t:$.values(t).reverse(),$.forEach(["l","r"],function(s){s==="r"&&(i=$.map(i,function(f){return $.values(f).reverse()}));var u=(a==="u"?e.predecessors:e.successors).bind(e),l=zL(e,i,n,u),c=FL(e,i,l.root,l.align,s==="r");s==="r"&&(c=$.mapValues(c,function(f){return-f})),r[a+s]=c})});var o=$L(e,r);return BL(r,o),UL(r,e.graph().align)}function VL(e,t,n){return function(r,i,o){var a=r.node(i),s=r.node(o),u=0,l;if(u+=a.width/2,$.has(a,"labelpos"))switch(a.labelpos.toLowerCase()){case"l":l=-a.width/2;break;case"r":l=a.width/2;break}if(l&&(u+=n?l:-l),l=0,u+=(a.dummy?t:e)/2,u+=(s.dummy?t:e)/2,u+=s.width/2,$.has(s,"labelpos"))switch(s.labelpos.toLowerCase()){case"l":l=s.width/2;break;case"r":l=-s.width/2;break}return l&&(u+=n?l:-l),l=0,u}}function GL(e,t){return e.node(t).width}var Ei=ue,rk=We,WL=qL.positionX,KL=YL;function YL(e){e=rk.asNonCompoundGraph(e),QL(e),Ei.forEach(WL(e),function(t,n){e.node(n).x=t})}function QL(e){var t=rk.buildLayerMatrix(e),n=e.graph().ranksep,r=0;Ei.forEach(t,function(i){var o=Ei.max(Ei.map(i,function(a){return e.node(a).height}));Ei.forEach(i,function(a){e.node(a).y=r+o/2}),r+=o+n})}var V=ue,Ax=DA,Mx=rM,XL=TM,ZL=We.normalizeRanks,JL=PM,eO=We.removeEmptyRanks,Lx=MM,tO=$M,Ox=UM,nO=RL,rO=KL,Tn=We,iO=St.Graph,oO=aO;function aO(e,t){var n=t&&t.debugTiming?Tn.time:Tn.notime;n("layout",function(){var r=n(" buildLayoutGraph",function(){return mO(e)});n(" runLayout",function(){sO(r,n)}),n(" updateInputGraph",function(){uO(e,r)})})}function sO(e,t){t(" makeSpaceForEdgeLabels",function(){yO(e)}),t(" removeSelfEdges",function(){TO(e)}),t(" acyclic",function(){Ax.run(e)}),t(" nestingGraph.run",function(){Lx.run(e)}),t(" rank",function(){XL(Tn.asNonCompoundGraph(e))}),t(" injectEdgeLabelProxies",function(){_O(e)}),t(" removeEmptyRanks",function(){eO(e)}),t(" nestingGraph.cleanup",function(){Lx.cleanup(e)}),t(" normalizeRanks",function(){ZL(e)}),t(" assignRankMinMax",function(){xO(e)}),t(" removeEdgeLabelProxies",function(){wO(e)}),t(" normalize.run",function(){Mx.run(e)}),t(" parentDummyChains",function(){JL(e)}),t(" addBorderSegments",function(){tO(e)}),t(" order",function(){nO(e)}),t(" insertSelfEdges",function(){RO(e)}),t(" adjustCoordinateSystem",function(){Ox.adjust(e)}),t(" position",function(){rO(e)}),t(" positionSelfEdges",function(){NO(e)}),t(" removeBorderNodes",function(){bO(e)}),t(" normalize.undo",function(){Mx.undo(e)}),t(" fixupEdgeLabelCoords",function(){CO(e)}),t(" undoCoordinateSystem",function(){Ox.undo(e)}),t(" translateGraph",function(){SO(e)}),t(" assignNodeIntersects",function(){EO(e)}),t(" reversePoints",function(){kO(e)}),t(" acyclic.undo",function(){Ax.undo(e)})}function uO(e,t){V.forEach(e.nodes(),function(n){var r=e.node(n),i=t.node(n);r&&(r.x=i.x,r.y=i.y,t.children(n).length&&(r.width=i.width,r.height=i.height))}),V.forEach(e.edges(),function(n){var r=e.edge(n),i=t.edge(n);r.points=i.points,V.has(i,"x")&&(r.x=i.x,r.y=i.y)}),e.graph().width=t.graph().width,e.graph().height=t.graph().height}var lO=["nodesep","edgesep","ranksep","marginx","marginy"],cO={ranksep:50,edgesep:20,nodesep:50,rankdir:"tb"},fO=["acyclicer","ranker","rankdir","align"],dO=["width","height"],hO={width:0,height:0},pO=["minlen","weight","width","height","labeloffset"],vO={minlen:1,weight:1,width:0,height:0,labeloffset:10,labelpos:"r"},gO=["labelpos"];function mO(e){var t=new iO({multigraph:!0,compound:!0}),n=nh(e.graph());return t.setGraph(V.merge({},cO,th(n,lO),V.pick(n,fO))),V.forEach(e.nodes(),function(r){var i=nh(e.node(r));t.setNode(r,V.defaults(th(i,dO),hO)),t.setParent(r,e.parent(r))}),V.forEach(e.edges(),function(r){var i=nh(e.edge(r));t.setEdge(r,V.merge({},vO,th(i,pO),V.pick(i,gO)))}),t}function yO(e){var t=e.graph();t.ranksep/=2,V.forEach(e.edges(),function(n){var r=e.edge(n);r.minlen*=2,r.labelpos.toLowerCase()!=="c"&&(t.rankdir==="TB"||t.rankdir==="BT"?r.width+=r.labeloffset:r.height+=r.labeloffset)})}function _O(e){V.forEach(e.edges(),function(t){var n=e.edge(t);if(n.width&&n.height){var r=e.node(t.v),i=e.node(t.w),o={rank:(i.rank-r.rank)/2+r.rank,e:t};Tn.addDummyNode(e,"edge-proxy",o,"_ep")}})}function xO(e){var t=0;V.forEach(e.nodes(),function(n){var r=e.node(n);r.borderTop&&(r.minRank=e.node(r.borderTop).rank,r.maxRank=e.node(r.borderBottom).rank,t=V.max(t,r.maxRank))}),e.graph().maxRank=t}function wO(e){V.forEach(e.nodes(),function(t){var n=e.node(t);n.dummy==="edge-proxy"&&(e.edge(n.e).labelRank=n.rank,e.removeNode(t))})}function SO(e){var t=Number.POSITIVE_INFINITY,n=0,r=Number.POSITIVE_INFINITY,i=0,o=e.graph(),a=o.marginx||0,s=o.marginy||0;function u(l){var c=l.x,f=l.y,d=l.width,h=l.height;t=Math.min(t,c-d/2),n=Math.max(n,c+d/2),r=Math.min(r,f-h/2),i=Math.max(i,f+h/2)}V.forEach(e.nodes(),function(l){u(e.node(l))}),V.forEach(e.edges(),function(l){var c=e.edge(l);V.has(c,"x")&&u(c)}),t-=a,r-=s,V.forEach(e.nodes(),function(l){var c=e.node(l);c.x-=t,c.y-=r}),V.forEach(e.edges(),function(l){var c=e.edge(l);V.forEach(c.points,function(f){f.x-=t,f.y-=r}),V.has(c,"x")&&(c.x-=t),V.has(c,"y")&&(c.y-=r)}),o.width=n-t+a,o.height=i-r+s}function EO(e){V.forEach(e.edges(),function(t){var n=e.edge(t),r=e.node(t.v),i=e.node(t.w),o,a;n.points?(o=n.points[0],a=n.points[n.points.length-1]):(n.points=[],o=i,a=r),n.points.unshift(Tn.intersectRect(r,o)),n.points.push(Tn.intersectRect(i,a))})}function CO(e){V.forEach(e.edges(),function(t){var n=e.edge(t);if(V.has(n,"x"))switch((n.labelpos==="l"||n.labelpos==="r")&&(n.width-=n.labeloffset),n.labelpos){case"l":n.x-=n.width/2+n.labeloffset;break;case"r":n.x+=n.width/2+n.labeloffset;break}})}function kO(e){V.forEach(e.edges(),function(t){var n=e.edge(t);n.reversed&&n.points.reverse()})}function bO(e){V.forEach(e.nodes(),function(t){if(e.children(t).length){var n=e.node(t),r=e.node(n.borderTop),i=e.node(n.borderBottom),o=e.node(V.last(n.borderLeft)),a=e.node(V.last(n.borderRight));n.width=Math.abs(a.x-o.x),n.height=Math.abs(i.y-r.y),n.x=o.x+n.width/2,n.y=r.y+n.height/2}}),V.forEach(e.nodes(),function(t){e.node(t).dummy==="border"&&e.removeNode(t)})}function TO(e){V.forEach(e.edges(),function(t){if(t.v===t.w){var n=e.node(t.v);n.selfEdges||(n.selfEdges=[]),n.selfEdges.push({e:t,label:e.edge(t)}),e.removeEdge(t)}})}function RO(e){var t=Tn.buildLayerMatrix(e);V.forEach(t,function(n){var r=0;V.forEach(n,function(i,o){var a=e.node(i);a.order=o+r,V.forEach(a.selfEdges,function(s){Tn.addDummyNode(e,"selfedge",{width:s.label.width,height:s.label.height,rank:a.rank,order:o+ ++r,e:s.e,label:s.label},"_se")}),delete a.selfEdges})})}function NO(e){V.forEach(e.nodes(),function(t){var n=e.node(t);if(n.dummy==="selfedge"){var r=e.node(n.e.v),i=r.x+r.width/2,o=r.y,a=n.x-i,s=r.height/2;e.setEdge(n.e,n.label),e.removeNode(t),n.label.points=[{x:i+2*a/3,y:o-s},{x:i+5*a/6,y:o-s},{x:i+a,y:o},{x:i+5*a/6,y:o+s},{x:i+2*a/3,y:o+s}],n.label.x=n.x,n.label.y=n.y}})}function th(e,t){return V.mapValues(V.pick(e,t),Number)}function nh(e){var t={};return V.forEach(e,function(n,r){t[r.toLowerCase()]=n}),t}var Go=ue,IO=We,PO=St.Graph,jO={debugOrdering:qO};function qO(e){var t=IO.buildLayerMatrix(e),n=new PO({compound:!0,multigraph:!0}).setGraph({});return Go.forEach(e.nodes(),function(r){n.setNode(r,{label:r}),n.setParent(r,"layer"+e.node(r).rank)}),Go.forEach(e.edges(),function(r){n.setEdge(r.v,r.w,{},r.name)}),Go.forEach(t,function(r,i){var o="layer"+i;n.setNode(o,{rank:"same"}),Go.reduce(r,function(a,s){return n.setEdge(a,s,{style:"invis"}),s})}),n}var AO="0.8.5",MO={graphlib:St,layout:oO,debug:jO,util:{time:We.time,notime:We.notime},version:AO};const zx=Dx(MO),LO=({graphData:e,chains:t})=>{const n=N.useRef(null),r=N.useRef(null),[i,o]=N.useState(null),[a,s]=N.useState(null),[u,l]=N.useState(1),c=N.useMemo(()=>{if(a===null)return null;const g=t[a];return g?eR(g.root.id,e):null},[a,t,e]),f=N.useCallback(g=>{o(g)},[]),d=N.useCallback(g=>{const v=e.nodes.find(y=>y.id===g);v&&o(v)},[e.nodes]);N.useEffect(()=>{if(!n.current||!r.current)return;const g=De(n.current),v=r.current,y=v.clientWidth,p=v.clientHeight;g.selectAll("*").remove();const m=c?e.nodes.filter(P=>c.has(P.id)):e.nodes,_=new Set(m.map(P=>P.id)),x=e.edges.filter(P=>_.has(P.from_node_id)&&_.has(P.to_node_id));if(m.length===0)return;const S=new zx.graphlib.Graph;S.setGraph({rankdir:"TB",nodesep:80,ranksep:100,marginx:50,marginy:50}),S.setDefaultEdgeLabel(()=>({})),m.forEach(P=>{S.setNode(String(P.id),{width:150,height:60,node:P})}),x.forEach(P=>{S.setEdge(String(P.from_node_id),String(P.to_node_id),{edge:P})}),zx.layout(S);const E=S.graph().width||y,C=S.graph().height||p,T=g.append("g"),M=BE().scaleExtent([.1,3]).on("zoom",P=>{T.attr("transform",P.transform),l(P.transform.k)});g.call(M);const k=Math.min((y-100)/E,(p-100)/C,1),j=(y-E*k)/2,B=(p-C*k)/2;g.call(M.transform,Sv.translate(j,B).scale(k)),T.append("g").selectAll(".edge").data(S.edges()).join("g").attr("class","edge").each(function(P){const R=S.edge(P),O=R.edge,I=Nj().x(A=>A.x).y(A=>A.y).curve(Ij);De(this).append("path").attr("d",I(R.points)).attr("fill","none").attr("stroke",sR(O.edge_type)).attr("stroke-width",2).attr("stroke-opacity",.6).attr("stroke-dasharray",O.edge_type==="rejected"?"5,5":null).attr("marker-end","url(#arrowhead)")}),g.append("defs").append("marker").attr("id","arrowhead").attr("viewBox","-5 -5 10 10").attr("refX",8).attr("refY",0).attr("markerWidth",6).attr("markerHeight",6).attr("orient","auto").append("path").attr("d","M-5,-5L5,0L-5,5Z").attr("fill","#666");const b=T.append("g").selectAll(".node").data(S.nodes()).join("g").attr("class","node").attr("transform",P=>{const R=S.node(P);return`translate(${R.x-R.width/2},${R.y-R.height/2})`}).style("cursor","pointer").on("click",(P,R)=>{const O=S.node(R).node;f(O)});return b.append("rect").attr("width",P=>S.node(P).width).attr("height",P=>S.node(P).height).attr("rx",8).attr("fill",P=>{const R=S.node(P).node;return It(R.node_type)}).attr("fill-opacity",.2).attr("stroke",P=>{const R=S.node(P).node;return It(R.node_type)}).attr("stroke-width",2),b.append("text").attr("x",10).attr("y",18).attr("fill","#666").attr("font-size","10px").text(P=>`#${P}`),b.append("text").attr("x",P=>S.node(P).width/2).attr("y",38).attr("text-anchor","middle").attr("fill","#eee").attr("font-size","12px").text(P=>{const R=S.node(P).node;return ut(R.title,20)}),()=>{g.on(".zoom",null)}},[e,c,f]);const h=t.filter(g=>g.root.node_type==="goal");return w.jsxs("div",{style:ne.container,children:[w.jsxs("div",{style:ne.controls,children:[w.jsx("h2",{style:ne.title,children:"DAG View"}),w.jsxs("div",{style:ne.section,children:[w.jsx("label",{style:ne.label,children:"Focus Chain"}),w.jsxs("select",{value:a??"",onChange:g=>s(g.target.value?Number(g.target.value):null),style:ne.select,children:[w.jsx("option",{value:"",children:"All Nodes"}),h.map((g,v)=>w.jsx("option",{value:t.indexOf(g),children:ut(g.root.title,30)},v))]})]}),w.jsxs("div",{style:ne.legend,children:[w.jsx("div",{style:ne.legendTitle,children:"Node Types"}),Object.entries(dv).map(([g,v])=>w.jsxs("div",{style:ne.legendItem,children:[w.jsx("div",{style:{...ne.legendDot,backgroundColor:v}}),w.jsx("span",{children:g})]},g))]}),w.jsxs("div",{style:ne.zoomInfo,children:["Zoom: ",Math.round(u*100),"%"]})]}),w.jsx("div",{ref:r,style:ne.svgContainer,children:w.jsx("svg",{ref:n,style:ne.svg})}),i&&w.jsxs("div",{style:ne.detailPanel,children:[w.jsx("button",{onClick:()=>o(null),style:ne.closeBtn,children:"×"}),w.jsxs("div",{style:ne.detailHeader,children:[w.jsx(Ge,{type:i.node_type}),w.jsx(uo,{confidence:$r(i)}),w.jsx(Br,{commit:bn(i)})]}),w.jsx("h3",{style:ne.detailTitle,children:i.title}),w.jsxs("p",{style:ne.detailMeta,children:["Node #",i.id," · ",new Date(i.created_at).toLocaleString()]}),i.description&&w.jsx("div",{style:ne.detailSection,children:w.jsx("p",{style:ne.description,children:i.description})}),w.jsx(OO,{node:i,graphData:e,onSelectNode:d})]})]})},OO=({node:e,graphData:t,onSelectNode:n})=>{const r=t.edges.filter(a=>a.to_node_id===e.id),i=t.edges.filter(a=>a.from_node_id===e.id),o=a=>t.nodes.find(s=>s.id===a);return w.jsxs(w.Fragment,{children:[r.length>0&&w.jsxs("div",{style:ne.detailSection,children:[w.jsxs("h4",{style:ne.sectionTitle,children:["Incoming (",r.length,")"]}),r.map(a=>{const s=o(a.from_node_id);return w.jsxs("div",{onClick:()=>n(a.from_node_id),style:ne.connection,children:[w.jsx(Ge,{type:(s==null?void 0:s.node_type)||"observation",size:"sm"}),w.jsx("span",{children:ut((s==null?void 0:s.title)||"Unknown",25)})]},a.id)})]}),i.length>0&&w.jsxs("div",{style:ne.detailSection,children:[w.jsxs("h4",{style:ne.sectionTitle,children:["Outgoing (",i.length,")"]}),i.map(a=>{const s=o(a.to_node_id);return w.jsxs("div",{onClick:()=>n(a.to_node_id),style:ne.connection,children:[w.jsx(Aa,{type:a.edge_type}),w.jsx(Ge,{type:(s==null?void 0:s.node_type)||"observation",size:"sm"}),w.jsx("span",{children:ut((s==null?void 0:s.title)||"Unknown",20)})]},a.id)})]})]})},ne={container:{height:"100%",display:"flex",position:"relative",backgroundColor:"#0d1117"},controls:{position:"absolute",top:"20px",left:"20px",backgroundColor:"#16213e",padding:"15px",borderRadius:"8px",zIndex:10,width:"220px"},title:{fontSize:"16px",margin:"0 0 15px 0",color:"#eee"},section:{marginBottom:"15px"},label:{display:"block",fontSize:"11px",color:"#888",marginBottom:"6px",textTransform:"uppercase"},select:{width:"100%",padding:"8px",backgroundColor:"#1a1a2e",border:"1px solid #333",borderRadius:"4px",color:"#eee",fontSize:"12px"},legend:{marginTop:"20px"},legendTitle:{fontSize:"11px",color:"#888",marginBottom:"8px",textTransform:"uppercase"},legendItem:{display:"flex",alignItems:"center",gap:"8px",fontSize:"11px",color:"#aaa",marginBottom:"4px"},legendDot:{width:"10px",height:"10px",borderRadius:"50%"},zoomInfo:{marginTop:"15px",fontSize:"11px",color:"#666"},svgContainer:{flex:1,height:"100%"},svg:{width:"100%",height:"100%"},detailPanel:{position:"absolute",top:"20px",right:"20px",bottom:"20px",width:"300px",backgroundColor:"#16213e",borderRadius:"8px",padding:"20px",overflowY:"auto",zIndex:10},closeBtn:{position:"absolute",top:"10px",right:"10px",width:"28px",height:"28px",border:"none",background:"#333",color:"#fff",borderRadius:"4px",fontSize:"18px",cursor:"pointer"},detailHeader:{display:"flex",gap:"8px",marginBottom:"10px",flexWrap:"wrap"},detailTitle:{fontSize:"16px",margin:"0 0 8px 0",color:"#eee"},detailMeta:{fontSize:"12px",color:"#888",margin:0},detailSection:{marginTop:"15px"},sectionTitle:{fontSize:"11px",color:"#888",margin:"0 0 8px 0",textTransform:"uppercase"},description:{fontSize:"13px",color:"#ccc",lineHeight:1.5,margin:0},connection:{display:"flex",alignItems:"center",gap:"6px",padding:"6px 8px",backgroundColor:"#1a1a2e",borderRadius:"4px",marginBottom:"4px",cursor:"pointer",fontSize:"11px"}},Fx=typeof window<"u"&&(window.location.hostname==="localhost"||window.location.hostname==="127.0.0.1"),zO=()=>{const{graphData:e,gitHistory:t,loading:n,error:r,lastUpdated:i}=HT({graphUrl:Fx?"/api/graph":"./graph-data.json",gitHistoryUrl:"./git-history.json",enableSSE:!1,pollInterval:Fx?3e4:0}),[o,a]=N.useState(null),s=N.useMemo(()=>e?GT(e.nodes):[],[e]),u=N.useMemo(()=>{if(!e)return null;if(!o)return e;const d=e.nodes.filter(v=>lE(v)===o),h=new Set(d.map(v=>v.id)),g=e.edges.filter(v=>h.has(v.from_node_id)&&h.has(v.to_node_id));return{nodes:d,edges:g}},[e,o]),{chains:l,sessions:c,stats:f}=rR(u);return n?w.jsxs("div",{style:dr.loading,children:[w.jsx("div",{style:dr.spinner}),w.jsx("p",{children:"Loading decision graph..."})]}):r?w.jsxs("div",{style:dr.error,children:[w.jsx("h2",{children:"Error Loading Graph"}),w.jsx("p",{children:r}),w.jsxs("p",{style:dr.hint,children:["Make sure graph-data.json exists, or run ",w.jsx("code",{children:"deciduous serve"})," for live data."]})]}):!e||e.nodes.length===0?w.jsxs("div",{style:dr.empty,children:[w.jsx("h2",{children:"No Decision Data"}),w.jsx("p",{children:"The graph is empty. Start adding decisions!"}),w.jsx("pre",{style:dr.code,children:'deciduous add goal "My first goal" -c 90'})]}):w.jsx(FT,{children:w.jsx(oR,{stats:f,lastUpdated:i,branches:s,selectedBranch:o,onBranchChange:a,children:w.jsxs(jT,{children:[w.jsx(hr,{path:"/",element:w.jsx(dR,{graphData:u,chains:l,sessions:c})}),w.jsx(hr,{path:"/timeline",element:w.jsx(mR,{graphData:u,gitHistory:t})}),w.jsx(hr,{path:"/graph",element:w.jsx(zj,{graphData:u})}),w.jsx(hr,{path:"/dag",element:w.jsx(LO,{graphData:u,chains:l})}),w.jsx(hr,{path:"*",element:w.jsx(IT,{to:"/",replace:!0})})]})})})},dr={loading:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",height:"100vh",backgroundColor:"#1a1a2e",color:"#888"},spinner:{width:"40px",height:"40px",border:"3px solid #333",borderTopColor:"#00d9ff",borderRadius:"50%",animation:"spin 1s linear infinite",marginBottom:"20px"},error:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",height:"100vh",backgroundColor:"#1a1a2e",color:"#eee",textAlign:"center",padding:"20px"},hint:{color:"#888",fontSize:"14px"},empty:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",height:"100vh",backgroundColor:"#1a1a2e",color:"#eee",textAlign:"center",padding:"20px"},code:{backgroundColor:"#16213e",padding:"15px 20px",borderRadius:"8px",fontFamily:"monospace",fontSize:"14px",color:"#00d9ff",marginTop:"10px"}};rh.createRoot(document.getElementById("root")).render(w.jsx(gp.StrictMode,{children:w.jsx(zO,{})}));</script> 77 - <style rel="stylesheet" crossorigin>*{box-sizing:border-box;margin:0;padding:0}html,body,#root{height:100%;width:100%}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;background-color:#1a1a2e;color:#eee;line-height:1.5;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:#1a1a2e}::-webkit-scrollbar-thumb{background:#333;border-radius:4px}::-webkit-scrollbar-thumb:hover{background:#444}a{color:#00d9ff;text-decoration:none}a:hover{text-decoration:underline}:focus-visible{outline:2px solid #00d9ff;outline-offset:2px}::selection{background:#00d9ff33}</style> 78 - </head> 79 - <body> 80 - <div id="root"></div> 81 - </body> 82 - </html>