diff --git a/CHROME_EXTENSION.md b/CHROME_EXTENSION.md
new file mode 100644
index 0000000..2c39c16
--- /dev/null
+++ b/CHROME_EXTENSION.md
@@ -0,0 +1,54 @@
+# Chrome Extension Installation Guide
+
+## Quick Start
+
+1. **Download the Extension**
+ - Clone this repository or download the `chrome-extension` folder
+
+2. **Install in Chrome**
+ - Open Chrome and go to `chrome://extensions/`
+ - Enable "Developer mode" (toggle in top right)
+ - Click "Load unpacked"
+ - Select the `chrome-extension` folder
+ - The extension will be added to Chrome
+
+3. **Use the Extension**
+ - Visit any Wordle game (NY Times, Wordle Unlimited, etc.)
+ - The solver will appear automatically
+ - Play normally and follow the suggestions
+
+## Supported Wordle Sites
+
+- NY Times Wordle (official): `nytimes.com/games/wordle`
+- Wordle Unlimited: `wordleunlimited.com`
+- Wordle Game: `wordlegame.org`
+- Most other Wordle clone sites
+
+## Features
+
+- 🎯 **Real-time suggestions** while you play
+- 📊 **Information theory** based optimal word selection
+- ⚙️ **Hard mode support** with rule enforcement
+- 🌐 **Universal compatibility** across Wordle sites
+- 🔄 **Automatic game state detection** and tracking
+
+## Privacy & Security
+
+- ✅ No data collection or transmission
+- ✅ Works entirely in your browser
+- ✅ Only activates on Wordle game pages
+- ✅ No account required
+
+## Troubleshooting
+
+**Extension not appearing?**
+- Refresh the Wordle page
+- Check that you're on a supported site
+- Verify the extension is enabled in Chrome
+
+**Suggestions not updating?**
+- Make sure you've completed each guess
+- Check the browser console for errors
+- Try refreshing the page
+
+For more help, see the full README in the `chrome-extension` folder.
\ No newline at end of file
diff --git a/chrome-extension/README.md b/chrome-extension/README.md
new file mode 100644
index 0000000..40ced67
--- /dev/null
+++ b/chrome-extension/README.md
@@ -0,0 +1,119 @@
+# Wordle Solver Chrome Extension
+
+A Chrome extension version of the Wordle Solver that provides AI-powered word suggestions while you play Wordle on any website.
+
+## Features
+
+- 🎯 **AI-Powered Suggestions** - Uses information theory to suggest optimal words
+- 📊 **Real-time Analysis** - Automatically tracks your game progress
+- 🌐 **Universal Compatibility** - Works on NY Times Wordle, Wordle Unlimited, and other Wordle sites
+- ⚙️ **Hard Mode Support** - Toggle hard mode for stricter word filtering
+- 🔄 **Live Updates** - Suggestions update automatically as you play
+
+## Installation
+
+### From Chrome Web Store (Coming Soon)
+The extension will be available on the Chrome Web Store.
+
+### Manual Installation (For Development)
+1. Download or clone this repository
+2. Open Chrome and go to `chrome://extensions/`
+3. Enable "Developer mode" (toggle in top right)
+4. Click "Load unpacked"
+5. Select the `chrome-extension` folder
+6. The extension will be added to Chrome
+
+## How to Use
+
+1. **Install the extension** using one of the methods above
+2. **Visit any Wordle game** (NY Times, Wordle Unlimited, etc.)
+3. **Play normally** - the solver appears automatically
+4. **Use the suggestions** to make optimal guesses
+5. **Toggle settings** like Hard Mode as needed
+
+## Understanding Suggestions
+
+- **🎯 Target words** - These are possible correct answers
+- **🔍 Explore words** - These provide maximum information gain
+- **Numbers** - Information entropy scores (higher = better for gathering info)
+
+## Strategy Tips
+
+1. **Start strong** - Use high-entropy words like SOARE, TARES, or RALES
+2. **Explore early** - Use 🔍 explore words in your first 2-3 guesses
+3. **Target late** - Switch to 🎯 target words when few options remain
+4. **Use Hard Mode** - Enable if playing with Wordle's hard mode rules
+
+## Supported Sites
+
+- NY Times Wordle (official)
+- Wordle Unlimited
+- Wordle Game
+- Most Wordle clone sites
+
+The extension automatically detects Wordle games and activates itself.
+
+## Privacy
+
+This extension:
+- ✅ Only runs on Wordle game pages
+- ✅ Processes game data locally in your browser
+- ✅ Does not collect or transmit any personal data
+- ✅ Does not require account creation or login
+
+## Algorithm
+
+Based on information theory principles from 3Blue1Brown's Wordle analysis. The algorithm:
+
+1. **Calculates entropy** for each possible guess
+2. **Filters words** based on previous guesses and feedback
+3. **Ranks suggestions** by information value
+4. **Updates in real-time** as you play
+
+## Development
+
+### File Structure
+```
+chrome-extension/
+├── manifest.json # Extension configuration
+├── content-script.js # Main extension logic
+├── solver-algorithm.js # Core Wordle solving algorithm
+├── extension-styles.css # UI styling
+├── popup.html # Extension popup interface
+├── popup.js # Popup functionality
+├── icons/ # Extension icons
+└── README.md # This file
+```
+
+### Building
+
+No build process required - this is a vanilla JavaScript extension.
+
+### Contributing
+
+1. Fork the repository
+2. Create your feature branch
+3. Make your changes
+4. Test thoroughly on different Wordle sites
+5. Submit a pull request
+
+## License
+
+MIT License - see the main repository for details.
+
+## Related Projects
+
+- [Wordle Solver Web App](https://wordlesolver.github.io) - The original web application
+- [Main Repository](https://github.com/WordleSolver/WordleSolver.github.io) - Source code and documentation
+
+## Support
+
+If you encounter issues:
+1. Check that you're on a supported Wordle site
+2. Refresh the page to restart the extension
+3. Check the browser console for error messages
+4. Report issues on the GitHub repository
+
+---
+
+**Enjoy solving Wordle optimally! 🎯**
\ No newline at end of file
diff --git a/chrome-extension/content-script.js b/chrome-extension/content-script.js
new file mode 100644
index 0000000..9fc5809
--- /dev/null
+++ b/chrome-extension/content-script.js
@@ -0,0 +1,354 @@
+// Wordle Solver Chrome Extension - Content Script
+// Integrates with Wordle game pages to provide solving assistance
+
+(function() {
+ 'use strict';
+
+ let solver = null;
+ let extensionUI = null;
+ let isGameDetected = false;
+
+ // Initialize the extension
+ function initialize() {
+ // Check if we're on a Wordle page
+ if (detectWordlePage()) {
+ console.log('Wordle Solver: Game detected!');
+ isGameDetected = true;
+ solver = new window.WordleSolver();
+ createExtensionUI();
+ observeGameChanges();
+ }
+ }
+
+ // Detect if we're on a Wordle game page
+ function detectWordlePage() {
+ // Check for common Wordle game indicators
+ const indicators = [
+ // NYTimes Wordle
+ '[data-testid="game-app"]',
+ '.Game-container',
+ '#wordle-app-game',
+ // Other Wordle sites
+ '.board',
+ '.game-board',
+ '#game',
+ '.wordle-board'
+ ];
+
+ for (const indicator of indicators) {
+ if (document.querySelector(indicator)) {
+ return true;
+ }
+ }
+
+ // Check URL patterns
+ return window.location.href.includes('wordle') ||
+ window.location.href.includes('/games/wordle') ||
+ document.title.toLowerCase().includes('wordle');
+ }
+
+ // Create the extension UI overlay
+ function createExtensionUI() {
+ // Create container
+ extensionUI = document.createElement('div');
+ extensionUI.id = 'wordle-solver-extension';
+ extensionUI.innerHTML = `
+
+
+
+ 2315 words remaining
+
+ Hard Mode
+
+
+
+
💡 Best Words:
+
+ Analyzing game state...
+
+
+
+ 🔄 Reset
+ ❓ Help
+
+
+ `;
+
+ // Add to page
+ document.body.appendChild(extensionUI);
+
+ // Add event listeners
+ setupEventListeners();
+
+ // Position the UI
+ positionUI();
+
+ // Initial suggestions
+ updateSuggestions();
+ }
+
+ // Position the UI to avoid interfering with the game
+ function positionUI() {
+ // Try to position next to the game board
+ const gameContainer = document.querySelector('[data-testid="game-app"], .Game-container, #game, .board');
+
+ if (gameContainer) {
+ const rect = gameContainer.getBoundingClientRect();
+ const windowWidth = window.innerWidth;
+
+ // Position to the right if there's space, otherwise to the left
+ if (rect.right + 320 < windowWidth) {
+ extensionUI.style.left = `${rect.right + 10}px`;
+ } else {
+ extensionUI.style.right = '10px';
+ }
+
+ extensionUI.style.top = `${Math.max(10, rect.top)}px`;
+ }
+ }
+
+ // Setup event listeners for the UI
+ function setupEventListeners() {
+ // Toggle minimize/maximize
+ document.getElementById('ws-toggle').addEventListener('click', () => {
+ const content = document.querySelector('.ws-content');
+ const toggle = document.getElementById('ws-toggle');
+
+ if (content.style.display === 'none') {
+ content.style.display = 'block';
+ toggle.textContent = '−';
+ toggle.title = 'Minimize';
+ } else {
+ content.style.display = 'none';
+ toggle.textContent = '+';
+ toggle.title = 'Expand';
+ }
+ });
+
+ // Hard mode toggle
+ document.getElementById('ws-hard-mode').addEventListener('change', (e) => {
+ solver.setHardMode(e.target.checked);
+ updateSuggestions();
+ });
+
+ // Reset button
+ document.getElementById('ws-reset').addEventListener('click', () => {
+ solver.reset();
+ updateSuggestions();
+ console.log('Wordle Solver: Reset');
+ });
+
+ // Help button
+ document.getElementById('ws-help').addEventListener('click', showHelp);
+ }
+
+ // Update suggestions display
+ function updateSuggestions() {
+ const suggestions = solver.getSuggestions(8);
+ const suggestionList = document.getElementById('ws-suggestion-list');
+ const remainingSpan = document.getElementById('ws-remaining');
+
+ // Update remaining count
+ remainingSpan.textContent = `${solver.getRemainingWordCount()} words remaining`;
+
+ // Update suggestions list
+ if (suggestions.length === 0) {
+ suggestionList.innerHTML = 'No suggestions available ';
+ return;
+ }
+
+ suggestionList.innerHTML = suggestions.map((suggestion, index) => {
+ const icon = suggestion.inWordList ? '🎯' : '🔍';
+ const className = suggestion.inWordList ? 'ws-in-list' : 'ws-explore';
+ return `
+ ${index + 1}.
+ ${suggestion.word.toUpperCase()}
+ ${suggestion.entropy}
+ ${icon}
+ `;
+ }).join('');
+ }
+
+ // Extract game state from the Wordle board
+ function extractGameState() {
+ const guesses = [];
+
+ try {
+ // Try NYTimes Wordle format
+ const rows = document.querySelectorAll('[data-testid="row"]');
+
+ for (const row of rows) {
+ const tiles = row.querySelectorAll('[data-testid="tile"]');
+ if (tiles.length !== 5) continue;
+
+ let word = '';
+ let colourMap = [];
+ let isComplete = true;
+
+ for (const tile of tiles) {
+ const letter = tile.textContent.toLowerCase();
+ if (!letter) {
+ isComplete = false;
+ break;
+ }
+
+ word += letter;
+
+ // Determine color from classes or aria-label
+ const evaluation = tile.getAttribute('data-state') ||
+ tile.getAttribute('aria-label') ||
+ tile.className;
+
+ if (evaluation.includes('correct') || evaluation.includes('green')) {
+ colourMap.push(2);
+ } else if (evaluation.includes('present') || evaluation.includes('yellow')) {
+ colourMap.push(1);
+ } else if (evaluation.includes('absent') || evaluation.includes('gray') || evaluation.includes('grey')) {
+ colourMap.push(0);
+ } else {
+ isComplete = false;
+ break;
+ }
+ }
+
+ if (isComplete && word.length === 5) {
+ guesses.push({ word, colourMap });
+ } else {
+ break; // Stop at first incomplete row
+ }
+ }
+ } catch (error) {
+ console.log('Wordle Solver: Error extracting game state:', error);
+ }
+
+ return guesses;
+ }
+
+ // Observe changes to the game board
+ function observeGameChanges() {
+ const gameContainer = document.querySelector('[data-testid="game-app"], .Game-container, #game, .board') || document.body;
+
+ const observer = new MutationObserver((mutations) => {
+ let shouldUpdate = false;
+
+ for (const mutation of mutations) {
+ // Look for changes that might indicate a new guess
+ if (mutation.type === 'attributes' &&
+ (mutation.attributeName === 'data-state' ||
+ mutation.attributeName === 'aria-label' ||
+ mutation.attributeName === 'class')) {
+ shouldUpdate = true;
+ break;
+ }
+
+ if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
+ shouldUpdate = true;
+ break;
+ }
+ }
+
+ if (shouldUpdate) {
+ // Debounce updates
+ setTimeout(updateFromGameState, 100);
+ }
+ });
+
+ observer.observe(gameContainer, {
+ childList: true,
+ subtree: true,
+ attributes: true,
+ attributeFilter: ['data-state', 'aria-label', 'class']
+ });
+ }
+
+ // Update solver state from game
+ function updateFromGameState() {
+ const currentGuesses = extractGameState();
+
+ // Check if we have new guesses
+ if (currentGuesses.length > solver.guesses.length) {
+ // Reset solver and replay all guesses
+ solver.reset();
+
+ for (const guess of currentGuesses) {
+ solver.addGuess(guess.word, guess.colourMap);
+ }
+
+ updateSuggestions();
+ console.log('Wordle Solver: Updated with', currentGuesses.length, 'guesses');
+ }
+ }
+
+ // Show help modal
+ function showHelp() {
+ const helpModal = document.createElement('div');
+ helpModal.id = 'ws-help-modal';
+ helpModal.innerHTML = `
+
+
+
+
How it works:
+
+ 🎯 Target words are possible answers
+ 🔍 Explore words give maximum information
+ Numbers show information value (higher = better)
+
+
+
Tips:
+
+ Start with high-entropy words like SOARE or TARES
+ Use explore words early to gather information
+ Switch to target words when few remain
+ Enable Hard Mode if playing with Wordle's hard mode rules
+
+
+
Based on information theory principles from 3Blue1Brown
+
+
+ `;
+
+ document.body.appendChild(helpModal);
+
+ document.getElementById('ws-close-help').addEventListener('click', () => {
+ document.body.removeChild(helpModal);
+ });
+
+ helpModal.addEventListener('click', (e) => {
+ if (e.target === helpModal) {
+ document.body.removeChild(helpModal);
+ }
+ });
+ }
+
+ // Listen for messages from popup
+ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
+ if (request.action === 'getStatus') {
+ if (isGameDetected && solver) {
+ sendResponse({
+ wordCount: solver.getRemainingWordCount(),
+ guessCount: solver.guesses.length,
+ active: true
+ });
+ } else {
+ sendResponse({ active: false });
+ }
+ }
+ });
+
+ // Initialize when DOM is ready
+ if (document.readyState === 'loading') {
+ document.addEventListener('DOMContentLoaded', initialize);
+ } else {
+ initialize();
+ }
+
+ // Also try to initialize after a delay in case the game loads dynamically
+ setTimeout(initialize, 1000);
+
+})();
\ No newline at end of file
diff --git a/chrome-extension/demo.html b/chrome-extension/demo.html
new file mode 100644
index 0000000..190e4bf
--- /dev/null
+++ b/chrome-extension/demo.html
@@ -0,0 +1,212 @@
+
+
+
+
+
+ Wordle Game Demo - Test Extension
+
+
+
+
+
+
+
+
Testing the Chrome Extension:
+
+ Load the Chrome extension in Developer Mode
+ Refresh this page
+ You should see the Wordle Solver appear automatically
+ Click the buttons below to simulate game states
+
+
+
+
+
+
+ Simulate First Guess
+ Simulate Second Guess
+ Reset Board
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chrome-extension/extension-styles.css b/chrome-extension/extension-styles.css
new file mode 100644
index 0000000..e076f9e
--- /dev/null
+++ b/chrome-extension/extension-styles.css
@@ -0,0 +1,332 @@
+/* Wordle Solver Chrome Extension Styles */
+
+#wordle-solver-extension {
+ position: fixed;
+ top: 10px;
+ right: 10px;
+ width: 300px;
+ background: #ffffff;
+ border: 2px solid #d3d6da;
+ border-radius: 8px;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+ font-family: 'Clear Sans', 'Helvetica Neue', Arial, sans-serif;
+ font-size: 14px;
+ z-index: 10000;
+ color: #1a1a1b;
+}
+
+.ws-header {
+ background: #6aaa64;
+ color: white;
+ padding: 10px 15px;
+ border-radius: 6px 6px 0 0;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.ws-header h3 {
+ margin: 0;
+ font-size: 16px;
+ font-weight: 700;
+}
+
+#ws-toggle {
+ background: none;
+ border: none;
+ color: white;
+ font-size: 18px;
+ font-weight: bold;
+ cursor: pointer;
+ padding: 2px 6px;
+ border-radius: 3px;
+ line-height: 1;
+}
+
+#ws-toggle:hover {
+ background: rgba(255, 255, 255, 0.2);
+}
+
+.ws-content {
+ padding: 15px;
+}
+
+.ws-status {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 15px;
+ padding-bottom: 10px;
+ border-bottom: 1px solid #d3d6da;
+}
+
+#ws-remaining {
+ font-weight: 600;
+ color: #787c7e;
+ font-size: 13px;
+}
+
+.ws-hard-mode {
+ display: flex;
+ align-items: center;
+ font-size: 12px;
+ color: #787c7e;
+ cursor: pointer;
+}
+
+.ws-hard-mode input {
+ margin-right: 5px;
+}
+
+.ws-suggestions h4 {
+ margin: 0 0 10px 0;
+ font-size: 14px;
+ font-weight: 600;
+ color: #1a1a1b;
+}
+
+#ws-suggestion-list {
+ list-style: none;
+ padding: 0;
+ margin: 0 0 15px 0;
+ max-height: 200px;
+ overflow-y: auto;
+}
+
+#ws-suggestion-list li {
+ display: flex;
+ align-items: center;
+ padding: 6px 8px;
+ margin-bottom: 2px;
+ border-radius: 4px;
+ background: #f8f9fa;
+ border: 1px solid #e9ecef;
+ font-size: 13px;
+}
+
+#ws-suggestion-list li:hover {
+ background: #e9ecef;
+}
+
+#ws-suggestion-list li.ws-in-list {
+ background: #d4edda;
+ border-color: #c3e6cb;
+}
+
+#ws-suggestion-list li.ws-explore {
+ background: #fff3cd;
+ border-color: #ffeaa7;
+}
+
+.ws-rank {
+ font-weight: 600;
+ color: #6c757d;
+ width: 20px;
+ text-align: right;
+ margin-right: 8px;
+}
+
+.ws-word {
+ font-weight: 700;
+ font-family: 'Clear Sans', monospace;
+ flex: 1;
+ color: #1a1a1b;
+ letter-spacing: 0.5px;
+}
+
+.ws-entropy {
+ font-size: 11px;
+ color: #6c757d;
+ margin-right: 5px;
+ min-width: 35px;
+ text-align: right;
+}
+
+.ws-icon {
+ font-size: 12px;
+}
+
+.ws-loading {
+ text-align: center;
+ color: #6c757d;
+ font-style: italic;
+ padding: 10px;
+}
+
+.ws-no-suggestions {
+ text-align: center;
+ color: #6c757d;
+ padding: 10px;
+}
+
+.ws-controls {
+ display: flex;
+ gap: 8px;
+}
+
+.ws-controls button {
+ flex: 1;
+ padding: 8px 12px;
+ border: 1px solid #d3d6da;
+ border-radius: 4px;
+ background: #f8f9fa;
+ color: #1a1a1b;
+ cursor: pointer;
+ font-size: 12px;
+ font-weight: 600;
+ transition: all 0.1s ease;
+}
+
+.ws-controls button:hover {
+ background: #e9ecef;
+ border-color: #adb5bd;
+}
+
+.ws-controls button:active {
+ background: #dee2e6;
+}
+
+/* Help Modal */
+#ws-help-modal {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: rgba(0, 0, 0, 0.5);
+ z-index: 10001;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.ws-modal-content {
+ background: white;
+ border-radius: 8px;
+ max-width: 500px;
+ width: 90%;
+ max-height: 80%;
+ overflow-y: auto;
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
+}
+
+.ws-modal-header {
+ background: #6aaa64;
+ color: white;
+ padding: 15px 20px;
+ border-radius: 8px 8px 0 0;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.ws-modal-header h3 {
+ margin: 0;
+ font-size: 18px;
+}
+
+#ws-close-help {
+ background: none;
+ border: none;
+ color: white;
+ font-size: 24px;
+ cursor: pointer;
+ padding: 0;
+ line-height: 1;
+}
+
+.ws-modal-body {
+ padding: 20px;
+ font-family: 'Clear Sans', 'Helvetica Neue', Arial, sans-serif;
+}
+
+.ws-modal-body h4 {
+ margin: 0 0 10px 0;
+ color: #1a1a1b;
+}
+
+.ws-modal-body ul {
+ margin: 0 0 15px 0;
+ padding-left: 20px;
+}
+
+.ws-modal-body li {
+ margin-bottom: 5px;
+ line-height: 1.4;
+}
+
+.ws-modal-body p {
+ margin: 15px 0 0 0;
+ text-align: center;
+ color: #6c757d;
+}
+
+/* Responsive adjustments */
+@media (max-width: 768px) {
+ #wordle-solver-extension {
+ width: 280px;
+ right: 5px;
+ top: 5px;
+ }
+
+ .ws-content {
+ padding: 12px;
+ }
+
+ .ws-modal-content {
+ width: 95%;
+ margin: 10px;
+ }
+}
+
+/* Dark mode support for sites that use it */
+@media (prefers-color-scheme: dark) {
+ #wordle-solver-extension {
+ background: #121213;
+ border-color: #3a3a3c;
+ color: #ffffff;
+ }
+
+ .ws-content {
+ background: #121213;
+ }
+
+ #ws-suggestion-list li {
+ background: #1a1a1b;
+ border-color: #3a3a3c;
+ color: #ffffff;
+ }
+
+ #ws-suggestion-list li:hover {
+ background: #2a2a2b;
+ }
+
+ #ws-suggestion-list li.ws-in-list {
+ background: #0d4a1f;
+ border-color: #1a6332;
+ }
+
+ #ws-suggestion-list li.ws-explore {
+ background: #4a3d0d;
+ border-color: #6b5a1a;
+ }
+
+ .ws-controls button {
+ background: #1a1a1b;
+ border-color: #3a3a3c;
+ color: #ffffff;
+ }
+
+ .ws-controls button:hover {
+ background: #2a2a2b;
+ }
+
+ .ws-modal-content {
+ background: #121213;
+ color: #ffffff;
+ }
+
+ .ws-modal-body {
+ background: #121213;
+ }
+}
\ No newline at end of file
diff --git a/chrome-extension/icons/icon128.png b/chrome-extension/icons/icon128.png
new file mode 100644
index 0000000..b30cf7d
--- /dev/null
+++ b/chrome-extension/icons/icon128.png
@@ -0,0 +1 @@
+Placeholder for 128px icon - actual icons would be PNG/SVG files
\ No newline at end of file
diff --git a/chrome-extension/icons/icon16.png b/chrome-extension/icons/icon16.png
new file mode 100644
index 0000000..42650cf
--- /dev/null
+++ b/chrome-extension/icons/icon16.png
@@ -0,0 +1 @@
+Placeholder for 16px icon - actual icons would be PNG/SVG files
\ No newline at end of file
diff --git a/chrome-extension/icons/icon48.png b/chrome-extension/icons/icon48.png
new file mode 100644
index 0000000..03c9167
--- /dev/null
+++ b/chrome-extension/icons/icon48.png
@@ -0,0 +1 @@
+Placeholder for 48px icon - actual icons would be PNG/SVG files
\ No newline at end of file
diff --git a/chrome-extension/manifest.json b/chrome-extension/manifest.json
new file mode 100644
index 0000000..6427d56
--- /dev/null
+++ b/chrome-extension/manifest.json
@@ -0,0 +1,32 @@
+{
+ "manifest_version": 3,
+ "name": "Wordle Solver Assistant",
+ "version": "1.0",
+ "description": "AI-powered Wordle solver that provides optimal word suggestions while you play",
+ "permissions": [
+ "activeTab"
+ ],
+ "content_scripts": [
+ {
+ "matches": [
+ "*://*.nytimes.com/games/wordle/*",
+ "*://www.nytimes.com/games/wordle/*",
+ "*://wordlegame.org/*",
+ "*://wordle.com/*",
+ "*://wordleunlimited.com/*",
+ "*://wordleonline.com/*"
+ ],
+ "js": ["solver-algorithm.js", "content-script.js"],
+ "css": ["extension-styles.css"]
+ }
+ ],
+ "action": {
+ "default_popup": "popup.html",
+ "default_title": "Wordle Solver Assistant"
+ },
+ "icons": {
+ "16": "icons/icon16.png",
+ "48": "icons/icon48.png",
+ "128": "icons/icon128.png"
+ }
+}
\ No newline at end of file
diff --git a/chrome-extension/popup.html b/chrome-extension/popup.html
new file mode 100644
index 0000000..38311ad
--- /dev/null
+++ b/chrome-extension/popup.html
@@ -0,0 +1,217 @@
+
+
+
+
+
+ Wordle Solver Assistant
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chrome-extension/popup.js b/chrome-extension/popup.js
new file mode 100644
index 0000000..9c41d3c
--- /dev/null
+++ b/chrome-extension/popup.js
@@ -0,0 +1,178 @@
+// Popup script for Wordle Solver Chrome Extension
+
+document.addEventListener('DOMContentLoaded', function() {
+ checkActiveTab();
+ setupEventListeners();
+});
+
+function setupEventListeners() {
+ // Help link
+ document.getElementById('help-link').addEventListener('click', function(e) {
+ e.preventDefault();
+ showHelp();
+ });
+}
+
+// Check if extension is active on current tab
+async function checkActiveTab() {
+ try {
+ const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
+
+ if (isWordlePage(tab.url)) {
+ // Try to get status from content script
+ try {
+ const response = await chrome.tabs.sendMessage(tab.id, { action: 'getStatus' });
+ if (response) {
+ showActiveStatus(tab.url, response);
+ } else {
+ showInactive();
+ }
+ } catch (error) {
+ // Content script might not be loaded yet
+ showInactive();
+ }
+ } else {
+ showInactive();
+ }
+ } catch (error) {
+ console.error('Error checking active tab:', error);
+ showInactive();
+ }
+}
+
+// Check if URL is a Wordle page
+function isWordlePage(url) {
+ if (!url) return false;
+
+ const wordlePatterns = [
+ 'nytimes.com/games/wordle',
+ 'wordlegame.org',
+ 'wordle.com',
+ 'wordleunlimited.com',
+ 'wordleonline.com'
+ ];
+
+ return wordlePatterns.some(pattern => url.includes(pattern)) ||
+ url.toLowerCase().includes('wordle');
+}
+
+// Show active status
+function showActiveStatus(url, status) {
+ document.getElementById('not-active').style.display = 'none';
+ document.getElementById('status-section').style.display = 'block';
+
+ // Extract site name from URL
+ const siteName = extractSiteName(url);
+ document.getElementById('current-site').textContent = siteName;
+
+ // Update status if available
+ if (status.wordCount !== undefined) {
+ document.getElementById('word-count').textContent = status.wordCount;
+ }
+ if (status.guessCount !== undefined) {
+ document.getElementById('guess-count').textContent = status.guessCount;
+ }
+}
+
+// Show inactive status
+function showInactive() {
+ document.getElementById('not-active').style.display = 'block';
+ document.getElementById('status-section').style.display = 'none';
+}
+
+// Extract readable site name from URL
+function extractSiteName(url) {
+ try {
+ const hostname = new URL(url).hostname;
+
+ if (hostname.includes('nytimes.com')) return 'NY Times Wordle';
+ if (hostname.includes('wordlegame.org')) return 'Wordle Game';
+ if (hostname.includes('wordleunlimited.com')) return 'Wordle Unlimited';
+ if (hostname.includes('wordleonline.com')) return 'Wordle Online';
+
+ return hostname.replace('www.', '');
+ } catch (error) {
+ return 'Wordle Site';
+ }
+}
+
+// Show help information
+function showHelp() {
+ const helpContent = `
+
+
🎯 Wordle Solver Help
+
+
Understanding Suggestions:
+
+ 🎯 Target words - Possible correct answers
+ 🔍 Explore words - Best for gathering information
+ Numbers - Information value (higher = better)
+
+
+
Strategy Tips:
+
+ Start with high-entropy words (SOARE, TARES, RALES)
+ Use explore words early in the game
+ Switch to target words when few options remain
+ Enable Hard Mode if playing with those rules
+
+
+
Supported Sites:
+
+ NY Times Wordle (official)
+ Wordle Unlimited
+ Most Wordle clone sites
+
+
+
Algorithm based on information theory principles from 3Blue1Brown's Wordle analysis.
+
+ `;
+
+ // Create modal overlay
+ const modal = document.createElement('div');
+ modal.style.cssText = `
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: rgba(0,0,0,0.5);
+ z-index: 1000;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ `;
+
+ const content = document.createElement('div');
+ content.style.cssText = `
+ background: white;
+ border-radius: 8px;
+ padding: 20px;
+ max-width: 400px;
+ width: 90%;
+ position: relative;
+ font-family: inherit;
+ `;
+
+ content.innerHTML = helpContent + `
+ ×
+ `;
+
+ modal.appendChild(content);
+ document.body.appendChild(modal);
+
+ // Close handlers
+ document.getElementById('close-help').onclick = () => document.body.removeChild(modal);
+ modal.onclick = (e) => {
+ if (e.target === modal) document.body.removeChild(modal);
+ };
+}
\ No newline at end of file
diff --git a/chrome-extension/solver-algorithm.js b/chrome-extension/solver-algorithm.js
new file mode 100644
index 0000000..341c90e
--- /dev/null
+++ b/chrome-extension/solver-algorithm.js
@@ -0,0 +1,129 @@
+// Core Wordle Solver Algorithm
+// Adapted from the main WordleSolver.github.io application
+
+// Word list - official Wordle words
+const possibleWords = ["aback","abase","abate","abbey","abbot","abhor","abide","abled","abode","abort","about","above","abuse","abyss","acorn","acrid","actor","acute","adage","adapt","adept","admin","admit","adobe","adopt","adore","adorn","adult","affix","afire","afoot","afoul","after","again","agape","agate","agent","agile","aging","aglow","agony","agree","ahead","aider","aisle","alarm","album","alert","algae","alibi","alien","align","alike","alive","allay","alley","allot","allow","alloy","aloft","alone","along","aloof","aloud","alpha","altar","alter","amass","amaze","amber","amble","amend","amiss","amity","among","ample","amply","amuse","angel","anger","angle","angry","angst","anime","ankle","annex","annoy","annul","anode","antic","anvil","aorta","apart","aphid","aping","apnea","apple","apply","apron","aptly","arbor","ardor","arena","argue","arise","armor","aroma","arose","array","arrow","arson","artsy","ascot","ashen","aside","askew","assay","asset","atoll","atone","attic","audio","audit","augur","aunty","avail","avert","avian","avoid","await","awake","award","aware","awash","awful","awoke","axial","axiom","axion","azure","bacon","badge","badly","bagel","baggy","baker","baler","balmy","banal","banjo","barge","baron","basal","basic","basil","basin","basis","baste","batch","bathe","baton","batty","bawdy","bayou","beach","beady","beard","beast","beech","beefy","befit","began","begat","beget","begin","begun","being","belch","belie","belle","belly","below","bench","beret","berry","berth","beset","betel","bevel","bezel","bible","bicep","biddy","bigot","bilge","billy","binge","bingo","biome","birch","birth","bison","bitty","black","blade","blame","bland","blank","blare","blast","blaze","bleak","bleat","bleed","bleep","blend","bless","blimp","blind","blink","bliss","blitz","bloat","block","bloke","blond","blood","bloom","blown","bluer","bluff","blunt","blurb","blurt","blush","board","boast","bobby","boney","bongo","bonus","booby","boost","booth","booty","booze","boozy","borax","borne","bosom","bossy","botch","bough","boule","bound","bowel","boxer","brace","braid","brain","brake","brand","brash","brass","brave","bravo","brawl","brawn","bread","break","breed","briar","bribe","brick","bride","brief","brine","bring","brink","briny","brisk","broad","broil","broke","brood","brook","broom","broth","brown","brunt","brush","brute","buddy","budge","buggy","bugle","build","built","bulge","bulky","bully","bunch","bunny","burly","burnt","burst","bused","bushy","butch","butte","buxom","buyer","bylaw","cabal","cabby","cabin","cable","cacao","cache","cacti","caddy","cadet","cagey","cairn","camel","cameo","canal","candy","canny","canoe","canon","caper","caput","carat","cargo","carol","carry","carve","caste","catch","cater","catty","caulk","cause","cavil","cease","cedar","cello","chafe","chaff","chain","chair","chalk","champ","chant","chaos","chard","charm","chart","chase","chasm","cheap","cheat","check","cheek","cheer","chess","chest","chick","chide","chief","child","chili","chill","chime","china","chirp","chock","choir","choke","chord","chore","chose","chuck","chump","chunk","churn","chute","cider","cigar","cinch","circa","civic","civil","clack","claim","clamp","clang","clank","clash","clasp","class","clean","clear","cleat","cleft","clerk","click","cliff","climb","cling","clink","cloak","clock","clone","close","cloth","cloud","clout","clove","clown","cluck","clued","clump","clung","coach","coast","cobra","cocoa","colon","color","comet","comfy","comic","comma","conch","condo","conic","copse","coral","corer","corny","couch","cough","could","count","coupe","court","coven","cover","covet","covey","cower","coyly","crack","craft","cramp","crane","crank","crash","crass","crate","crave","crawl","craze","crazy","creak","cream","credo","creed","creek","creep","creme","crepe","crept","cress","crest","crick","cried","crier","crime","crimp","crisp","croak","crock","crone","crony","crook","cross","croup","crowd","crown","crude","cruel","crumb","crump","crush","crust","crypt","cubic","cumin","curio","curly","curry","curse","curve","curvy","cutie","cyber","cycle","cynic","daddy","daily","dairy","daisy","dally","dance","dandy","datum","daunt","dealt","death","debar","debit","debug","debut","decal","decay","decor","decoy","decry","defer","deign","deity","delay","delta","delve","demon","demur","denim","dense","depot","depth","derby","deter","detox","deuce","devil","diary","dicey","digit","dilly","dimly","diner","dingo","dingy","diode","dirge","dirty","disco","ditch","ditto","ditty","diver","dizzy","dodge","dodgy","dogma","doing","dolly","donor","donut","dopey","doubt","dough","dowdy","dowel","downy","dowry","dozen","draft","drain","drake","drama","drank","drape","drawl","drawn","dread","dream","dress","dried","drier","drift","drill","drink","drive","droit","droll","drone","drool","droop","dross","drove","drown","druid","drunk","dryer","dryly","duchy","dully","dummy","dumpy","dunce","dusky","dusty","dutch","duvet","dwarf","dwell","dwelt","dying","eager","eagle","early","earth","easel","eaten","eater","ebony","eclat","edict","edify","eerie","egret","eight","eject","eking","elate","elbow","elder","elect","elegy","elfin","elide","elite","elope","elude","email","embed","ember","emcee","empty","enact","endow","enema","enemy","enjoy","ennui","ensue","enter","entry","envoy","epoch","epoxy","equal","equip","erase","erect","erode","error","erupt","essay","ester","ether","ethic","ethos","etude","evade","event","every","evict","evoke","exact","exalt","excel","exert","exile","exist","expel","extol","extra","exult","eying","fable","facet","faint","fairy","faith","false","fancy","fanny","farce","fatal","fatty","fault","fauna","favor","feast","fecal","feign","fella","felon","femme","femur","fence","feral","ferry","fetal","fetch","fetid","fetus","fever","fewer","fiber","ficus","field","fiend","fiery","fifth","fifty","fight","filer","filet","filly","filmy","filth","final","finch","finer","first","fishy","fixer","fizzy","fjord","flack","flail","flair","flake","flaky","flame","flank","flare","flash","flask","fleck","fleet","flesh","flick","flier","fling","flint","flirt","float","flock","flood","floor","flora","floss","flour","flout","flown","fluff","fluid","fluke","flume","flung","flunk","flush","flute","flyer","foamy","focal","focus","foggy","foist","folio","folly","foray","force","forge","forgo","forte","forth","forty","forum","found","foyer","frail","frame","frank","fraud","freak","freed","freer","fresh","friar","fried","frill","frisk","fritz","frock","frond","front","frost","froth","frown","froze","fruit","fudge","fugue","fully","fungi","funky","funny","furor","furry","fussy","fuzzy","gaffe","gaily","gamer","gamma","gamut","gassy","gaudy","gauge","gaunt","gauze","gavel","gawky","gayer","gayly","gazer","gecko","geeky","geese","genie","genre","ghost","ghoul","giant","giddy","gipsy","girly","girth","given","giver","glade","gland","glare","glass","glaze","gleam","glean","glide","glint","gloat","globe","gloom","glory","gloss","glove","glyph","gnash","gnome","godly","going","golem","golly","gonad","goner","goody","gooey","goofy","goose","gorge","gouge","gourd","grace","grade","graft","grail","grain","grand","grant","grape","graph","grasp","grass","grate","grave","gravy","graze","great","greed","green","greet","grief","grill","grime","grimy","grind","gripe","groan","groin","groom","grope","gross","group","grout","grove","growl","grown","gruel","gruff","grunt","guard","guava","guess","guest","guide","guild","guile","guilt","guise","gulch","gully","gumbo","gummy","guppy","gusto","gusty","gypsy","habit","hairy","halve","handy","happy","hardy","harem","harpy","harry","harsh","haste","hasty","hatch","hater","haunt","haute","haven","havoc","hazel","heady","heard","heart","heath","heave","heavy","hedge","hefty","heist","helix","hello","hence","heron","hilly","hinge","hippo","hippy","hitch","hoard","hobby","hoist","holly","homer","honey","honor","horde","horny","horse","hotel","hotly","hound","house","hovel","hover","howdy","human","humid","humor","humph","humus","hunch","hunky","hurry","husky","hussy","hutch","hydro","hyena","hymen","hyper","icily","icing","ideal","idiom","idiot","idler","idyll","igloo","iliac","image","imbue","impel","imply","inane","inbox","incur","index","inept","inert","infer","ingot","inlay","inlet","inner","input","inter","intro","ionic","irate","irony","islet","issue","itchy","ivory","jaunt","jazzy","jelly","jerky","jetty","jewel","jiffy","joint","joist","joker","jolly","joust","judge","juice","juicy","jumbo","jumpy","junta","junto","juror","kappa","karma","kayak","kebab","khaki","kinky","kiosk","kitty","knack","knave","knead","kneed","kneel","knelt","knife","knock","knoll","known","koala","krill","label","labor","laden","ladle","lager","lance","lanky","lapel","lapse","large","larva","lasso","latch","later","lathe","latte","laugh","layer","leach","leafy","leaky","leant","leapt","learn","lease","leash","least","leave","ledge","leech","leery","lefty","legal","leggy","lemon","lemur","leper","level","lever","libel","liege","light","liken","lilac","limbo","limit","linen","liner","lingo","lipid","lithe","liver","livid","llama","loamy","loath","lobby","local","locus","lodge","lofty","logic","login","loopy","loose","lorry","loser","louse","lousy","lover","lower","lowly","loyal","lucid","lucky","lumen","lumpy","lunar","lunch","lunge","lupus","lurch","lurid","lusty","lying","lymph","lyric","macaw","macho","macro","madam","madly","mafia","magic","magma","maize","major","maker","mambo","mamma","mammy","manga","mange","mango","mangy","mania","manic","manly","manor","maple","march","marry","marsh","mason","masse","match","matey","mauve","maxim","maybe","mayor","mealy","meant","meaty","mecca","medal","media","medic","melee","melon","mercy","merge","merit","merry","metal","meter","metro","micro","midge","midst","might","milky","mimic","mince","miner","minim","minor","minty","minus","mirth","miser","missy","mocha","modal","model","modem","mogul","moist","molar","moldy","money","month","moody","moose","moral","moron","morph","mossy","motel","motif","motor","motto","moult","mound","mount","mourn","mouse","mouth","mover","movie","mower","mucky","mucus","muddy","mulch","mummy","munch","mural","murky","mushy","music","musky","musty","myrrh","nadir","naive","nanny","nasal","nasty","natal","naval","navel","needy","neigh","nerdy","nerve","never","newer","newly","nicer","niche","niece","night","ninja","ninny","ninth","noble","nobly","noise","noisy","nomad","noose","north","nosey","notch","novel","nudge","nurse","nutty","nylon","nymph","oaken","obese","occur","ocean","octal","octet","odder","oddly","offal","offer","often","olden","older","olive","ombre","omega","onion","onset","opera","opine","opium","optic","orbit","order","organ","other","otter","ought","ounce","outdo","outer","outgo","ovary","ovate","overt","ovine","ovoid","owing","owner","oxide","ozone","paddy","pagan","paint","paler","palsy","panel","panic","pansy","papal","paper","parer","parka","parry","parse","party","pasta","paste","pasty","patch","patio","patsy","patty","pause","payee","payer","peace","peach","pearl","pecan","pedal","penal","pence","penne","penny","perch","peril","perky","pesky","pesto","petal","petty","phase","phone","phony","photo","piano","picky","piece","piety","piggy","pilot","pinch","piney","pinky","pinto","piper","pique","pitch","pithy","pivot","pixel","pixie","pizza","place","plaid","plain","plait","plane","plank","plant","plate","plaza","plead","pleat","plied","plier","pluck","plumb","plume","plump","plunk","plush","poesy","point","poise","poker","polar","polka","polyp","pooch","poppy","porch","poser","posit","posse","pouch","pound","pouty","power","prank","prawn","preen","press","price","prick","pride","pried","prime","primo","print","prior","prism","privy","prize","probe","prone","prong","proof","prose","proud","prove","prowl","proxy","prude","prune","psalm","pubic","pudgy","puffy","pulpy","pulse","punch","pupil","puppy","puree","purer","purge","purse","pushy","putty","pygmy","quack","quail","quake","qualm","quark","quart","quash","quasi","queen","queer","quell","query","quest","queue","quick","quiet","quill","quilt","quirk","quite","quota","quote","quoth","rabbi","rabid","racer","radar","radii","radio","rainy","raise","rajah","rally","ralph","ramen","ranch","randy","range","rapid","rarer","raspy","ratio","ratty","raven","rayon","razor","reach","react","ready","realm","rearm","rebar","rebel","rebus","rebut","recap","recur","recut","reedy","refer","refit","regal","rehab","reign","relax","relay","relic","remit","renal","renew","repay","repel","reply","rerun","reset","resin","retch","retro","retry","reuse","revel","revue","rhino","rhyme","rider","ridge","rifle","right","rigid","rigor","rinse","ripen","riper","risen","riser","risky","rival","river","rivet","roach","roast","robin","robot","rocky","rodeo","roger","rogue","roomy","roost","rotor","rouge","rough","round","rouse","route","rover","rowdy","rower","royal","ruddy","ruder","rugby","ruler","rumba","rumor","rupee","rural","rusty","sadly","safer","saint","salad","sally","salon","salsa","salty","salve","salvo","sandy","saner","sappy","sassy","satin","satyr","sauce","saucy","sauna","saute","savor","savoy","savvy","scald","scale","scalp","scaly","scamp","scant","scare","scarf","scary","scene","scent","scion","scoff","scold","scone","scoop","scope","score","scorn","scour","scout","scowl","scram","scrap","scree","screw","scrub","scrum","scuba","sedan","seedy","segue","seize","semen","sense","sepia","serif","serum","serve","setup","seven","sever","sewer","shack","shade","shady","shaft","shake","shaky","shale","shall","shalt","shame","shank","shape","shard","share","shark","sharp","shave","shawl","shear","sheen","sheep","sheer","sheet","sheik","shelf","shell","shied","shift","shine","shiny","shire","shirk","shirt","shoal","shock","shone","shook","shoot","shore","shorn","short","shout","shove","shown","showy","shrew","shrub","shrug","shuck","shunt","shush","shyly","siege","sieve","sight","sigma","silky","silly","since","sinew","singe","siren","sissy","sixth","sixty","skate","skier","skiff","skill","skimp","skirt","skulk","skull","skunk","slack","slain","slang","slant","slash","slate","sleek","sleep","sleet","slept","slice","slick","slide","slime","slimy","sling","slink","sloop","slope","slosh","sloth","slump","slung","slunk","slurp","slush","slyly","smack","small","smart","smash","smear","smell","smelt","smile","smirk","smite","smith","smock","smoke","smoky","smote","snack","snail","snake","snaky","snare","snarl","sneak","sneer","snide","sniff","snipe","snoop","snore","snort","snout","snowy","snuck","snuff","soapy","sober","soggy","solar","solid","solve","sonar","sonic","sooth","sooty","sorry","sound","south","sower","space","spade","spank","spare","spark","spasm","spawn","speak","spear","speck","speed","spell","spelt","spend","spent","sperm","spice","spicy","spied","spiel","spike","spiky","spill","spilt","spine","spiny","spire","spite","splat","split","spoil","spoke","spoof","spook","spool","spoon","spore","sport","spout","spray","spree","sprig","spunk","spurn","spurt","squad","squat","squib","stack","staff","stage","staid","stain","stair","stake","stale","stalk","stall","stamp","stand","stank","stare","stark","start","stash","state","stave","stead","steak","steal","steam","steed","steel","steep","steer","stein","stern","stick","stiff","still","stilt","sting","stink","stint","stock","stoic","stoke","stole","stomp","stone","stony","stood","stool","stoop","store","stork","storm","story","stout","stove","strap","straw","stray","strip","strut","stuck","study","stuff","stump","stung","stunk","stunt","style","suave","sugar","suing","suite","sulky","sully","sumac","sunny","super","surer","surge","surly","sushi","swami","swamp","swarm","swash","swath","swear","sweat","sweep","sweet","swell","swept","swift","swill","swine","swing","swirl","swish","swoon","swoop","sword","swore","sworn","swung","synod","syrup","tabby","table","taboo","tacit","tacky","taffy","taint","taken","taker","tally","talon","tamer","tango","tangy","taper","tapir","tardy","tarot","taste","tasty","tatty","taunt","tawny","teach","teary","tease","teddy","teeth","tempo","tenet","tenor","tense","tenth","tepee","tepid","terra","terse","testy","thank","theft","their","theme","there","these","theta","thick","thief","thigh","thing","think","third","thong","thorn","those","three","threw","throb","throw","thrum","thumb","thump","thyme","tiara","tibia","tidal","tiger","tight","tilde","timer","timid","tipsy","titan","tithe","title","toast","today","toddy","token","tonal","tonga","tonic","tooth","topaz","topic","torch","torso","torus","total","totem","touch","tough","towel","tower","toxic","toxin","trace","track","tract","trade","trail","train","trait","tramp","trash","trawl","tread","treat","trend","triad","trial","tribe","trice","trick","tried","tripe","trite","troll","troop","trope","trout","trove","truce","truck","truer","truly","trump","trunk","truss","trust","truth","tryst","tubal","tuber","tulip","tulle","tumor","tunic","turbo","tutor","twang","tweak","tweed","tweet","twice","twine","twirl","twist","twixt","tying","udder","ulcer","ultra","umbra","uncle","uncut","under","undid","undue","unfed","unfit","unify","union","unite","unity","unlit","unmet","unset","untie","until","unwed","unzip","upper","upset","urban","urine","usage","usher","using","usual","usurp","utile","utter","vague","valet","valid","valor","value","valve","vapid","vapor","vault","vaunt","vegan","venom","venue","verge","verse","verso","verve","vicar","video","vigil","vigor","villa","vinyl","viola","viper","viral","virus","visit","visor","vista","vital","vivid","vixen","vocal","vodka","vogue","voice","voila","vomit","voter","vouch","vowel","vying","wacky","wafer","wager","wagon","waist","waive","waltz","warty","waste","watch","water","waver","waxen","weary","weave","wedge","weedy","weigh","weird","welch","welsh","whack","whale","wharf","wheat","wheel","whelp","where","which","whiff","while","whine","whiny","whirl","whisk","white","whole","whoop","whose","widen","wider","widow","width","wield","wight","willy","wimpy","wince","winch","windy","wiser","wispy","witch","witty","woken","woman","women","woody","wooer","wooly","woozy","wordy","world","worry","worse","worst","worth","would","wound","woven","wrack","wrath","wreak","wreck","wrest","wring","wrist","write","wrong","wrote","wrung","wryly","yacht","yearn","yeast","yield","young","youth","zebra","zesty","zonal"];
+
+// Valid words list (subset for input validation)
+const validWords = possibleWords; // For simplicity, using same list
+
+// Calculate entropy for information theory-based suggestions
+function entrapyArray(listOfLengths) {
+ const listSum = listOfLengths.reduce((acc, cur) => acc + cur, 0);
+ return listOfLengths.reduce((acc, cur) => {
+ if (cur === 0) return acc;
+ const probability = cur / listSum;
+ return acc - probability * Math.log2(probability);
+ }, 0);
+}
+
+// Create color map for a guess against a word
+// Returns: 0 = grey (not in word), 1 = yellow (wrong position), 2 = green (correct position)
+function createColourMap(guess, word) {
+ const guessArr = guess.split("");
+ const wordArr = word.split("");
+ return guessArr.map((letter, index) => {
+ if (letter === wordArr[index]) return 2;
+
+ let lettersInWord = 0;
+ wordArr.forEach(char => char === letter ? lettersInWord += 1 : null);
+
+ for (let i = 0; i < index; i++) {
+ if (guessArr[i] === letter) lettersInWord -= 1;
+ }
+
+ for (let i = index + 1; i < 5; i++) {
+ if (guessArr[i] === letter && wordArr[i] === letter) lettersInWord -= 1;
+ }
+
+ if (0 < lettersInWord) return 1;
+
+ return 0;
+ });
+}
+
+// Find remaining possible words based on guess and feedback
+function findRemainingWords(guess, colourMap, wordList) {
+ const colourMapStr = colourMap.join("");
+ return wordList.filter(word => {
+ return colourMapStr === createColourMap(guess, word).join("");
+ });
+}
+
+// Generate suggestion list with entropy scores
+function makeSuggestionList(wordList, hardMode = false) {
+ const frequenciesMap = new Map();
+
+ // Calculate frequency map for each possible guess
+ possibleWords.forEach(possibleGuess => {
+ const frequencies = [];
+
+ for (let i = 0; i < 243; i++) { // 3^5 possible color combinations
+ frequencies.push(0);
+ }
+
+ wordList.forEach(possibleWord => {
+ const colourMap = createColourMap(possibleGuess, possibleWord);
+ const index = colourMap.reduce((acc, cur, idx) => acc + cur * Math.pow(3, 4 - idx), 0);
+ frequencies[index] += 1;
+ });
+
+ const entrapyVal = entrapyArray(frequencies);
+ frequenciesMap.set(possibleGuess, entrapyVal);
+ });
+
+ // Create sorted suggestion list
+ let suggestionList = Array.from(frequenciesMap.entries()).map(([word, entropy]) => {
+ const inWordList = wordList.includes(word);
+ return [word, entropy, inWordList];
+ }).sort((a, b) => b[1] - a[1]);
+
+ return suggestionList;
+}
+
+// WordleSolver class for the Chrome extension
+class WordleSolver {
+ constructor() {
+ this.wordList = [...possibleWords];
+ this.hardMode = false;
+ this.guesses = [];
+ }
+
+ // Add a guess and get updated suggestions
+ addGuess(word, colourMap) {
+ this.guesses.push({ word, colourMap });
+ this.wordList = findRemainingWords(word, colourMap, this.wordList);
+ return this.getSuggestions();
+ }
+
+ // Get current suggestions
+ getSuggestions(count = 10) {
+ const suggestions = makeSuggestionList(this.wordList, this.hardMode);
+ return suggestions.slice(0, count).map(([word, entropy, inWordList]) => ({
+ word,
+ entropy: entropy.toFixed(3),
+ inWordList
+ }));
+ }
+
+ // Reset the solver
+ reset() {
+ this.wordList = [...possibleWords];
+ this.guesses = [];
+ }
+
+ // Set hard mode
+ setHardMode(enabled) {
+ this.hardMode = enabled;
+ }
+
+ // Get remaining word count
+ getRemainingWordCount() {
+ return this.wordList.length;
+ }
+}
+
+// Export for use in content script
+if (typeof window !== 'undefined') {
+ window.WordleSolver = WordleSolver;
+}
\ No newline at end of file