diff --git a/css/style.css b/css/style.css index 557484d..9c56f9b 100644 --- a/css/style.css +++ b/css/style.css @@ -66,6 +66,7 @@ body { header { display: flex; + flex-wrap: wrap; justify-content: space-between; align-items: center; margin-bottom: 30px; @@ -855,7 +856,6 @@ button:hover { /* Transform layout */ .transform-layout { - display: grid; gap: 24px; margin-top: 16px; } @@ -877,6 +877,12 @@ button:hover { border-bottom: 1px solid var(--input-border); } +.transform-category-legend > div { + display: flex; + flex-wrap: wrap; + gap: 8px; +} + .legend-title { font-size: 0.9rem; font-weight: 500; @@ -989,6 +995,20 @@ button:hover { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 8px; margin-bottom: 16px; + width: 100%; /* Ensure grid doesn't overflow container */ + box-sizing: border-box; +} + +#category-randomizer .transform-buttons { + display: flex; +} + +#category-randomizer .transform-buttons .transform-button-group { + width: 100%; +} + +#category-randomizer .transform-buttons .transform-button .transform-preview { + max-width: 300px; } /* Carrier styling */ @@ -1308,8 +1328,7 @@ button:hover { flex-direction: column; align-items: center; gap: 4px; - min-width: 110px; - max-width: 100%; + width: 100%; font-weight: 500; text-align: center; border: 1px solid var(--input-border); @@ -1816,7 +1835,6 @@ button:hover { border: 2px solid rgba(200, 170, 255, 0.35) !important; padding: 18px 28px !important; letter-spacing: .3px; - min-width: 48ch; justify-content: center; text-align: center; } @@ -1976,9 +1994,6 @@ html { .tokenade-presets > label { margin-right: 4px; } -.tokenade-presets .transform-button { - padding: 6px 10px; -} /* Hacker style controls */ .hacker-controls { @@ -2086,14 +2101,14 @@ html { /* Presets row polish */ .tokenade-presets { - display: flex; - align-items: center; - gap: 6px; - flex-wrap: nowrap; - overflow-x: visible; margin: 8px 0 12px 0; } -.tokenade-presets .transform-button { flex: 0 0 auto; min-width: 136px; padding: 5px 8px; } + +.tokenade-presets .transform-button { + flex: 1 0 auto; + padding: 5px 8px; + width: unset; +} /* Quick picks panel */ .carrier-quick-grid { diff --git a/index.html b/index.html index b44516f..c73837a 100644 --- a/index.html +++ b/index.html @@ -6,8 +6,8 @@ Parseltongue 2.0 - LLM Payload Crafter - - + + @@ -185,7 +185,7 @@
{{ universalDecodeResult.text }}
- - - -
+
+
Separator
+
+ + + + +
+
@@ -331,7 +333,7 @@
+ + +
@@ -929,7 +936,10 @@
+ + + @@ -1004,6 +1014,13 @@ console.log('Initializing emoji grid, attempt:', retryCount + 1); + // Check if we're on the steganography tab before trying to initialize + const app = document.getElementById('app').__vue__; + if (!app || app.activeTab !== 'steganography') { + console.log('Not on steganography tab, skipping emoji grid initialization'); + return; + } + // Get the emoji library element const emojiLibrary = document.querySelector('.emoji-library'); @@ -1019,7 +1036,6 @@ try { window.emojiLibrary.renderEmojiGrid('emoji-grid-container', function(emoji) { // Simulate emoji selection by calling the Vue method if possible - const app = document.getElementById('app').__vue__; if (app && app.selectEmoji) { app.selectEmoji(emoji); } @@ -1044,10 +1060,7 @@ // Initialize when DOM is loaded document.addEventListener('DOMContentLoaded', function() { - // First attempt after a short delay to ensure Vue has initialized - setTimeout(initEmojiGrid, 500); - - // Also initialize when switching to the steganography tab + // Set up watcher for tab changes to initialize emoji grid when needed const app = document.getElementById('app'); if (app && app.__vue__) { const vue = app.__vue__; @@ -1061,6 +1074,11 @@ } }); } + + // If we're already on the steganography tab on page load, initialize it + if (vue.activeTab === 'steganography') { + setTimeout(initEmojiGrid, 500); + } } }); diff --git a/js/app.js b/js/app.js index 590bedf..adba96f 100644 --- a/js/app.js +++ b/js/app.js @@ -15,8 +15,8 @@ window.app = new Vue({ // Transform categories for styling transformCategories: { encoding: ['Base64', 'Base64 URL', 'Base32', 'Base45', 'Base58', 'Base62', 'Binary', 'Hexadecimal', 'ASCII85', 'URL Encode', 'HTML Entities'], - cipher: ['Caesar Cipher', 'ROT13', 'ROT47', 'Morse Code', 'Atbash Cipher', 'ROT5', 'Vigenรจre Cipher', 'Rail Fence (3 Rails)', 'Baconian Cipher', 'Tap Code'], - visual: ['Rainbow Text', 'Strikethrough', 'Underline', 'Reverse Text', 'Alternating Case', 'Reverse Words', 'Random Case', 'Title Case', 'Sentence Case', 'Emoji Speak', 'Ubbi Dubbi', 'Rรถvarsprรฅket'], + cipher: ['Caesar Cipher', 'ROT13', 'ROT47', 'ROT18', 'ROT5', 'Morse Code', 'Atbash Cipher', 'Vigenรจre Cipher', 'Affine Cipher (a=5,b=8)', 'Rail Fence (3 Rails)', 'Baconian Cipher', 'Tap Code', 'A1Z26', 'QWERTY Right Shift'], + visual: ['Rainbow Text', 'Strikethrough', 'Underline', 'Reverse Text', 'Alternating Case', 'Reverse Words', 'Random Case', 'Title Case', 'Sentence Case', 'Emoji Speak', 'Ubbi Dubbi', 'Rรถvarsprรฅket', 'Vaporwave', 'Disemvowel'], format: ['Pig Latin', 'Leetspeak', 'NATO Phonetic', 'camelCase', 'snake_case', 'kebab-case'], unicode: ['Invisible Text', 'Upside Down', 'Full Width', 'Small Caps', 'Bubble', 'Braille', 'Greek Letters', 'Wingdings', 'Superscript', 'Subscript', 'Regional Indicator Letters', 'Fraktur', 'Cyrillic Stylized', 'Katakana', 'Hiragana', 'Roman Numerals'], special: ['Medieval', 'Cursive', 'Monospace', 'Double-Struck', 'Elder Futhark', 'Mirror Text', 'Zalgo'], @@ -54,7 +54,7 @@ window.app = new Vue({ filteredEmojis: [...window.emojiLibrary.EMOJI_LIST], selectedEmoji: null, carrierEmojiList: [...window.emojiLibrary.EMOJI_LIST], - quickCarrierEmojis: ['๐Ÿ','๐Ÿ‰','๐Ÿฒ','๐Ÿ”ฅ','๐Ÿ’ฅ','๐Ÿ—ฟ','โš“','โญ','โœจ','๐Ÿš€','๐Ÿ’€','๐Ÿชจ','๐Ÿƒ','๐Ÿชถ','๐Ÿ”ฎ','๐Ÿข','๐ŸŠ','๐ŸฆŽ','๐Ÿ'], + quickCarrierEmojis: ['๐Ÿ','๐Ÿ‰','๐Ÿฒ','๐Ÿ”ฅ','๐Ÿ’ฅ','๐Ÿ—ฟ','โš“','โญ','โœจ','๐Ÿš€','๐Ÿ’€','๐Ÿชจ','๐Ÿƒ','๐Ÿชถ','๐Ÿ”ฎ','๐Ÿข','๐ŸŠ','๐ŸฆŽ'], tbCarrierManual: '', // Token Bomb Generator tbDepth: 3, @@ -105,7 +105,10 @@ window.app = new Vue({ // Danger zone controls showDangerModal: false, - dangerThresholdTokens: 25_000_000 + dangerThresholdTokens: 25_000_000, + + // Copy operation tracking (moved from methods) + lastCopyTime: 0 }, methods: { toggleUnicodePanel() { @@ -278,17 +281,8 @@ window.app = new Vue({ console.log('Transform mapping:', transformInfo); } } else { - // Handle text with proper Unicode segmentation - const segments = window.emojiLibrary.splitEmojis(this.transformInput); - const transformedSegments = segments.map(segment => { - // Skip transformation for emojis and complex Unicode characters - if (segment.length > 1 || /[\u{1F300}-\u{1F9FF}\u{2600}-\u{26FF}]/u.test(segment)) { - return segment; - } - return transform.func(segment); - }); - - this.transformOutput = window.emojiLibrary.joinEmojis(transformedSegments); + // Apply transform to full text - let the transform handle segmentation if needed + this.transformOutput = transform.func(this.transformInput); } // Set flag to mark this as a transform-initiated copy @@ -498,9 +492,6 @@ window.app = new Vue({ }, // Utility Methods - // Track last copy operation to prevent rapid repeated copies - lastCopyTime: 0, - async copyToClipboard(text) { if (!text) return; @@ -1737,10 +1728,18 @@ window.app = new Vue({ }); item.classList.add('active-category'); - // Jump directly to the target element - targetElement.scrollIntoView({ - behavior: 'smooth', - block: 'start' + // Get height of .input-section so we can offset the scroll + const inputSection = document.querySelector('.input-section'); + const inputSectionHeight = inputSection.offsetHeight; + + // Calculate the target scroll position with offset + const elementPosition = targetElement.getBoundingClientRect().top + window.pageYOffset; + const offsetPosition = elementPosition - inputSectionHeight - 10; // Extra 10px padding + + // Scroll to the calculated position + window.scrollTo({ + top: offsetPosition, + behavior: 'smooth' }); // Highlight the section briefly to draw attention @@ -2141,6 +2140,25 @@ window.app = new Vue({ } this.textPayload = out; this.showNotification(' Text payload generated', 'success'); + }, + + // Set up paste event handlers for all textareas + setupPasteHandlers() { + // Get all textareas in the app + const textareas = document.querySelectorAll('textarea'); + + // Add paste event listener to each textarea + textareas.forEach(textarea => { + textarea.addEventListener('paste', (e) => { + // Mark this as an explicit paste event + this.isPasteOperation = true; + + // Reset the flag after a short delay + setTimeout(() => { + this.isPasteOperation = false; + }, 100); + }); + }); } }, // Initialize theme and components @@ -2201,24 +2219,6 @@ window.app = new Vue({ }); }, - // Set up paste event handlers for all textareas - setupPasteHandlers() { - // Get all textareas in the app - const textareas = document.querySelectorAll('textarea'); - - // Add paste event listener to each textarea - textareas.forEach(textarea => { - textarea.addEventListener('paste', (e) => { - // Mark this as an explicit paste event - this.isPasteOperation = true; - - // Reset the flag after a short delay - setTimeout(() => { - this.isPasteOperation = false; - }, 100); - }); - }); - }, // No keyboard shortcuts - they were removed as requested created() { // Initialize any required functionality @@ -2233,20 +2233,10 @@ window.app = new Vue({ if (this.activeTransform && this.activeTab === 'transforms') { this.transformOutput = this.activeTransform.func(this.transformInput); } - }, - // Make sure emoji list stays loaded when user types in any input - emojiMessage() { - this.filteredEmojis = [...window.emojiLibrary.EMOJI_LIST]; - this.$nextTick(() => { - this.renderEmojiGrid(); - }); - }, - // Also watch the decode input field for typing activity - decodeInput() { - this.filteredEmojis = [...window.emojiLibrary.EMOJI_LIST]; - this.$nextTick(() => { - this.renderEmojiGrid(); - }); } + // Note: Removed watchers for emojiMessage and decodeInput that were + // unnecessarily re-rendering the emoji grid on every keystroke. + // The emoji grid is now only rendered when switching tabs or categories, + // which prevents losing the selected emoji state while typing. } }); diff --git a/js/emojiLibrary.js b/js/emojiLibrary.js index 3a0e44d..157aa62 100644 --- a/js/emojiLibrary.js +++ b/js/emojiLibrary.js @@ -22,452 +22,6 @@ window.emojiLibrary.joinEmojis = function(emojis) { return emojis.join(''); }; -// Additional emojis for expanded library -window.emojiLibrary.ADDITIONAL_EMOJIS = [ - // Animals & Nature - "๐Ÿ‡", "๐ŸฆŠ", "๐Ÿฆ", "๐Ÿฏ", "๐Ÿฎ", "๐Ÿท", "๐Ÿธ", "๐Ÿต", "๐Ÿ”", "๐Ÿง", "๐Ÿฆ", "๐Ÿค", "๐Ÿฆ†", "๐Ÿฆ…", "๐Ÿฆ‰", "๐Ÿฆ‡", "๐Ÿบ", "๐Ÿ—", "๐Ÿด", "๐Ÿฆ„", "๐Ÿ", "๐Ÿ›", "๐Ÿฆ‹", "๐ŸŒ", "๐Ÿž", "๐Ÿœ", "๐Ÿ•ท๏ธ", "๐Ÿฆ‚", "๐ŸฆŸ", "๐Ÿฆ ", "๐Ÿฆจ", "๐Ÿฆฉ", "๐Ÿฆซ", "๐Ÿฆฌ", "๐Ÿปโ€โ„๏ธ", "๐Ÿผ", "๐Ÿจ", "๐Ÿ•", "๐Ÿถ", "๐Ÿฉ", "๐Ÿˆ", "๐Ÿฑ", "๐Ÿชฑ", - - // Food & Drink - "๐Ÿ", "๐ŸŽ", "๐Ÿ", "๐ŸŠ", "๐Ÿ‹", "๐ŸŒ", "๐Ÿ‰", "๐Ÿ‡", "๐Ÿ“", "๐Ÿˆ", "๐Ÿ’", "๐Ÿ‘", "๐Ÿฅญ", "๐Ÿ", "๐Ÿฅฅ", "๐Ÿฅ", "๐Ÿ…", "๐Ÿ†", "๐Ÿฅ‘", "๐Ÿฅฆ", "๐Ÿฅฌ", "๐Ÿฅ’", "๐ŸŒถ๏ธ", "๐ŸŒฝ", "๐Ÿฅ•", "๐Ÿง„", "๐Ÿง…", "๐Ÿฅ”", "๐Ÿ ", "๐Ÿฅ", "๐Ÿ”", "๐Ÿ•", "๐Ÿ–", "๐Ÿ—", "๐Ÿค", "๐Ÿฃ", "๐Ÿฑ", "๐Ÿœ", "๐Ÿฒ", "๐Ÿฅ", - - // Travel & Places - "๐Ÿš—", "๐Ÿš•", "๐Ÿš™", "๐ŸšŒ", "๐ŸšŽ", "๐Ÿš’", "๐Ÿš‘", "๐Ÿšš", "๐Ÿš›", "๐Ÿšœ", "๐Ÿšฒ", "๐Ÿš", "๐ŸšŸ", "๐Ÿšก", "๐Ÿš€", "๐Ÿ›ธ", "๐Ÿ›ฅ๏ธ", "๐ŸŽ๏ธ", "๐Ÿ๏ธ", "๐Ÿšค", "๐Ÿšข", "๐Ÿš", "๐Ÿš‚", "๐Ÿš†", "๐Ÿšˆ", "๐ŸŒŽ", "๐ŸŒ", "๐ŸŒ", "๐Ÿ”๏ธ", "๐Ÿ•๏ธ", - - // Activities & Sports - "โšฝ", "๐Ÿ€", "๐Ÿˆ", "๐Ÿ", "๐Ÿ‰", "๐ŸŽพ", "๐ŸŽณ", "๐Ÿ‘", "๐Ÿ’", "๐Ÿ“", "๐Ÿธ", "๐ŸฅŠ", "๐Ÿฅ‹", "๐Ÿฅ…", "๐Ÿคพ", "๐ŸŽฟ", "๐Ÿ„", "๐Ÿ‚", "๐ŸŠ", "๐Ÿ‹๏ธ", "๐Ÿคผ", "๐Ÿคธ", "๐Ÿคบ", "๐Ÿคฝ", "๐Ÿคน", "๐ŸŽฏ", "๐ŸŽฑ", "๐ŸŽฝ", "๐Ÿšด", "๐Ÿšต", - - // Tech & Objects - "๐Ÿ’ป", "โŒจ๏ธ", "๐Ÿ–ฅ๏ธ", "๐Ÿ–ฑ๏ธ", "๐Ÿ–จ๏ธ", "๐Ÿ“ฑ", "โ˜Ž๏ธ", "๐Ÿ“ž", "๐Ÿ“Ÿ", "๐Ÿ“ ", "๐Ÿ“บ", "๐Ÿ“ป", "๐ŸŽ™๏ธ", "๐ŸŽš๏ธ", "๐ŸŽ›๏ธ", "๐Ÿงญ", "โฑ๏ธ", "โฒ๏ธ", "โฐ", "๐Ÿ•ฐ๏ธ", "๐Ÿ“ก", "๐Ÿ”‹", "๐Ÿ”Œ", "๐Ÿ’ก", "๐Ÿฎ", "๐Ÿช”", "๐Ÿงฏ", "๐Ÿ›ข๏ธ", "๐Ÿ’ธ", "๐Ÿ’ต", "๐Ÿ’ณ", "๐Ÿ’ด", "๐Ÿ’ถ", "๐Ÿ’ท", "๐Ÿ’ฐ", "๐Ÿ’ฑ", "๐Ÿ’ฒ", "๐Ÿ’ผ", "๐Ÿ’ฝ", "๐Ÿ’พ", "๐Ÿ’ฟ", - - // Symbols - "โค๏ธ", "๐Ÿ’›", "๐Ÿ’š", "๐Ÿ’™", "๐Ÿ’œ", "๐Ÿ’”", "๐Ÿ’•", "๐Ÿ’ž", "๐Ÿ’“", "๐Ÿ’—", "๐Ÿ’–", "๐Ÿ’˜", "๐Ÿ’", "๐Ÿ’Ÿ", "๐Ÿ’ค", "๐Ÿ’ข", "๐Ÿ’ฃ", "๐Ÿ’ฅ", "๐Ÿ’ฆ", "๐Ÿ’จ", "๐Ÿ’ฉ", "๐Ÿ’ซ", "๐Ÿ’ฌ", "๐Ÿ”ฅ", "๐Ÿ’ ", "๐Ÿ‘พ", "๐Ÿ‘ป", "๐Ÿ’€", "๐Ÿ‘ฝ", "๐Ÿ‘ฟ", "๐Ÿฉธ", - - // Mystical & Fantasy - "๐Ÿง™", "๐Ÿง™โ€โ™‚๏ธ", "๐Ÿง™โ€โ™€๏ธ", "๐Ÿงš", "๐Ÿงšโ€โ™‚๏ธ", "๐Ÿงšโ€โ™€๏ธ", "๐Ÿง›", "๐Ÿง›โ€โ™‚๏ธ", "๐Ÿง›โ€โ™€๏ธ", "๐Ÿงœ", "๐Ÿงœโ€โ™‚๏ธ", "๐Ÿงœโ€โ™€๏ธ", "๐Ÿ‘น", "๐Ÿ‘บ", "๐Ÿ‘ป", "๐Ÿ‘ฝ", "๐Ÿ‘พ", "๐Ÿฒ", "๐Ÿ”ฎ", "๐Ÿ", "๐Ÿ‰", "๐Ÿฆ„", "๐Ÿ‘ธ", "๐Ÿฅท", "๐Ÿ‘ฐ", "๐Ÿง”", "โš—๏ธ", "๐Ÿ”ฏ", "๐Ÿ”ฑ", "โšœ๏ธ", "โœจ", "๐ŸŒ ", "๐ŸŒ‹", "๐Ÿ’Ž", "๐Ÿ’", "๐Ÿ„", "๐ŸŒบ", "๐ŸŒน", "๐Ÿญ", "๐Ÿš", "๐ŸŠ", "๐Ÿข", "๐Ÿ‡", "๐Ÿฐ", "๐Ÿ”ฅ", "๐Ÿ’ฅ", "๐ŸŒ€", "๐ŸŒˆ", "๐ŸŒช๏ธ", "๐Ÿฉธ", "๐Ÿชฑ", "๐ŸŒ‘", "๐ŸŒ’", "๐ŸŒ“", "๐ŸŒ”", "๐ŸŒ•", "๐ŸŒ–", "๐ŸŒ—", "๐ŸŒ˜", - - // Flags - "๐Ÿ", "๐Ÿšฉ", "๐ŸŽŒ", "๐Ÿด", "๐Ÿณ๏ธ", "๐Ÿณ๏ธโ€๐ŸŒˆ", "๐Ÿณ๏ธโ€โšง๏ธ", "๐Ÿดโ€โ˜ ๏ธ", "๐Ÿ‡บ๐Ÿ‡ธ", "๐Ÿ‡จ๐Ÿ‡ฆ", "๐Ÿ‡ฌ๐Ÿ‡ง", "๐Ÿ‡ฉ๐Ÿ‡ช", "๐Ÿ‡ซ๐Ÿ‡ท", "๐Ÿ‡ฎ๐Ÿ‡น", "๐Ÿ‡ฏ๐Ÿ‡ต", "๐Ÿ‡ฐ๐Ÿ‡ท", "๐Ÿ‡ท๐Ÿ‡บ", "๐Ÿ‡จ๐Ÿ‡ณ", "๐Ÿ‡ฎ๐Ÿ‡ณ", "๐Ÿ‡ฆ๐Ÿ‡บ", "๐Ÿ‡ง๐Ÿ‡ท", "๐Ÿ‡ช๐Ÿ‡ธ", "๐Ÿ‡ณ๐Ÿ‡ฑ", "๐Ÿ‡ต๐Ÿ‡น", "๐Ÿ‡ธ๐Ÿ‡ช", "๐Ÿ‡ฆ๐Ÿ‡ท", "๐Ÿ‡ฆ๐Ÿ‡บ", "๐Ÿ‡ฆ๐Ÿ‡น", "๐Ÿ‡ง๐Ÿ‡ช", "๐Ÿ‡ง๐Ÿ‡ด" -]; - -// Make emoji list globally available -window.emojiLibrary.EMOJI_LIST = [ - // Blood drop, worm, and moon emojis - "๐Ÿฉธ", // Blood Drop - "๐Ÿชฑ", // Worm - "๐ŸŒ‘", // New Moon - "๐ŸŒ’", // Waxing Crescent Moon - "๐ŸŒ“", // First Quarter Moon - "๐ŸŒ”", // Waxing Gibbous Moon - "๐ŸŒ•", // Full Moon - "๐ŸŒ–", // Waning Gibbous Moon - "๐ŸŒ—", // Last Quarter Moon - "๐ŸŒ˜", // Waning Crescent Moon - // Faces and People - "๐Ÿ˜€", // Grinning Face - "๐Ÿ˜", // Beaming Face with Smiling Eyes - "๐Ÿ˜‚", // Face with Tears of Joy - "๐Ÿคฃ", // Rolling on the Floor Laughing - "๐Ÿ˜ƒ", // Grinning Face with Big Eyes - "๐Ÿ˜„", // Grinning Face with Smiling Eyes - "๐Ÿ˜…", // Grinning Face with Sweat - "๐Ÿ˜†", // Grinning Squinting Face - "๐Ÿ˜‰", // Winking Face - "๐Ÿ˜Š", // Smiling Face with Smiling Eyes - "๐Ÿ˜‹", // Face Savoring Food - "๐Ÿ˜Ž", // Smiling Face with Sunglasses - "๐Ÿ˜", // Smiling Face with Heart-Eyes - "๐Ÿ˜˜", // Face Blowing a Kiss - "๐Ÿฅฐ", // Smiling Face with Hearts - "๐Ÿ˜—", // Kissing Face - "๐Ÿ˜™", // Kissing Face with Smiling Eyes - "๐Ÿ˜š", // Kissing Face with Closed Eyes - "๐Ÿ™‚", // Slightly Smiling Face - "๐Ÿค—", // Hugging Face - "๐Ÿคฉ", // Star-Struck - "๐Ÿค”", // Thinking Face - "๐Ÿคจ", // Face with Raised Eyebrow - "๐Ÿ˜", // Neutral Face - "๐Ÿ˜‘", // Expressionless Face - "๐Ÿ˜ถ", // Face Without Mouth - "๐Ÿ™„", // Face with Rolling Eyes - "๐Ÿ˜", // Smirking Face - "๐Ÿ˜ฃ", // Persevering Face - "๐Ÿ˜ฅ", // Sad but Relieved Face - "๐Ÿ˜ฎ", // Face with Open Mouth - "๐Ÿค", // Zipper-Mouth Face - "๐Ÿ˜ฏ", // Hushed Face - "๐Ÿ˜ช", // Sleepy Face - "๐Ÿ˜ซ", // Tired Face - "๐Ÿ˜ด", // Sleeping Face - "๐Ÿ˜Œ", // Relieved Face - "๐Ÿ˜›", // Face with Tongue - "๐Ÿ˜œ", // Winking Face with Tongue - "๐Ÿ˜", // Squinting Face with Tongue - "๐Ÿคค", // Drooling Face - "๐Ÿ˜’", // Unamused Face - "๐Ÿ˜“", // Downcast Face with Sweat - "๐Ÿ˜”", // Pensive Face - "๐Ÿ˜•", // Confused Face - "๐Ÿ™ƒ", // Upside-Down Face - "๐Ÿค‘", // Money-Mouth Face - "๐Ÿ˜ฒ", // Astonished Face - "๐Ÿ™", // Slightly Frowning Face - "๐Ÿ˜–", // Confounded Face - "๐Ÿ˜ž", // Disappointed Face - "๐Ÿ˜Ÿ", // Worried Face - "๐Ÿ˜ค", // Face with Steam From Nose - "๐Ÿ˜ข", // Crying Face - "๐Ÿ˜ญ", // Loudly Crying Face - "๐Ÿ˜ง", // Anguished Face - "๐Ÿ˜จ", // Fearful Face - "๐Ÿ˜ฉ", // Weary Face - "๐Ÿคฏ", // Exploding Head - "๐Ÿ˜ฑ", // Face Screaming in Fear - "๐Ÿ˜ณ", // Flushed Face - "๐Ÿฅต", // Hot Face - "๐Ÿฅถ", // Cold Face - "๐Ÿ˜ก", // Pouting Face - "๐Ÿ˜ ", // Angry Face - "๐Ÿคฌ", // Face with Symbols on Mouth - "๐Ÿ˜ท", // Face with Medical Mask - "๐Ÿค’", // Face with Thermometer - "๐Ÿค•", // Face with Head-Bandage - "๐Ÿคข", // Nauseated Face - "๐Ÿคฎ", // Face Vomiting - "๐Ÿคง", // Sneezing Face - "๐Ÿ˜‡", // Smiling Face with Halo - "๐Ÿฅณ", // Partying Face - "๐Ÿฅด", // Woozy Face - "๐Ÿฅบ", // Pleading Face - "๐Ÿง", // Face with Monocle - "๐Ÿฅฑ", // Yawning Face - "๐Ÿง ", // Brain - - // Gestures and Body Parts - "๐Ÿ‘", // Thumbs Up - "๐Ÿ‘Ž", // Thumbs Down - "๐Ÿ‘", // Clapping Hands - "๐Ÿ™Œ", // Raising Hands - "๐Ÿค", // Handshake - "๐Ÿ‘‹", // Waving Hand - "โœŒ๏ธ", // Victory Hand - "๐ŸคŸ", // Love-You Gesture - "๐Ÿค˜", // Sign of the Horns - "๐Ÿ‘Š", // Oncoming Fist - "โœŠ", // Raised Fist - "๐Ÿ‘†", // Backhand Index Pointing Up - "๐Ÿ‘‡", // Backhand Index Pointing Down - "๐Ÿ‘ˆ", // Backhand Index Pointing Left - "๐Ÿ‘‰", // Backhand Index Pointing Right - "๐Ÿ‘Œ", // OK Hand - "๐ŸคŒ", // Pinched Fingers - "๐Ÿค", // Pinching Hand - "โœ‹", // Raised Hand - "๐Ÿคš", // Raised Back of Hand - "๐Ÿ–๏ธ", // Hand with Fingers Splayed - "๐Ÿ––", // Vulcan Salute - "๐Ÿ‘€", // Eyes - "๐Ÿ‘๏ธ", // Eye - "๐Ÿ‘„", // Mouth - "๐Ÿงฟ", // Nazar Amulet - - // Celebration & Objects - "๐ŸŽ‰", // Party Popper - "๐ŸŽŠ", // Confetti Ball - "๐ŸŽ‚", // Birthday Cake - "๐ŸŽ", // Wrapped Gift - "๐ŸŽˆ", // Balloon - "๐ŸŽ„", // Christmas Tree - "๐ŸŽƒ", // Jack-O-Lantern - "๐Ÿ†", // Trophy - "๐Ÿ…", // Sports Medal - "๐Ÿฅ‡", // 1st Place Medal - "๐Ÿฅˆ", // 2nd Place Medal - "๐Ÿฅ‰", // 3rd Place Medal - "๐Ÿ’ฐ", // Money Bag - "๐Ÿ’ธ", // Money with Wings - "๐Ÿ’ต", // Dollar Banknote - "๐Ÿ’ด", // Yen Banknote - "๐Ÿ’ถ", // Euro Banknote - "๐Ÿ’ท", // Pound Banknote - "๐Ÿ’ฏ", // Hundred Points - "๐Ÿ“ฑ", // Mobile Phone - "๐Ÿ’ป", // Laptop - "โŒจ๏ธ", // Keyboard - "๐Ÿ–ฅ๏ธ", // Desktop Computer - "๐Ÿ”’", // Locked - "๐Ÿ”“", // Unlocked - - // Food & Drink - "๐Ÿ•", // Pizza - "๐Ÿ”", // Hamburger - "๐Ÿฆ", // Ice Cream - "๐Ÿฉ", // Doughnut - "๐Ÿบ", // Beer Mug - "๐Ÿท", // Wine Glass - "โ˜•", // Hot Beverage - - // Nature & Weather - "๐ŸŒˆ", // Rainbow - "๐ŸŒž", // Sun with Face - "๐ŸŒ‘", // New Moon - "๐ŸŒ’", // Waxing Crescent Moon - "๐ŸŒ“", // First Quarter Moon - "๐ŸŒ”", // Waxing Gibbous Moon - "๐ŸŒ•", // Full Moon - "๐ŸŒ–", // Waning Gibbous Moon - "๐ŸŒ—", // Last Quarter Moon - "๐ŸŒ˜", // Waning Crescent Moon - "๐ŸŒ™", // Crescent Moon - "โญ", // Star - "๐ŸŒŸ", // Glowing Star - "โšก", // High Voltage - "โ„๏ธ", // Snowflake - "๐Ÿ”ฅ", // Fire - "๐Ÿ’ง", // Droplet - "๐ŸŒŠ", // Water Wave - - // Animals - "๐Ÿ‡", // Follow The - "๐Ÿฑ", // Cat Face - "๐Ÿถ", // Dog Face - "๐Ÿชฑ", // Worm - "๐ŸฆŠ", // Fox - "๐Ÿผ", // Panda - "๐Ÿฆ", // Lion - "๐Ÿฌ", // Dolphin - "๐Ÿฆ„", // Unicorn - - // Symbols & Special - "โค๏ธ", // Red Heart - "๐Ÿฉธ", // Blood Drop - "๐Ÿงก", // Orange Heart - "๐Ÿ’š", // Green Heart - "๐Ÿ’™", // Blue Heart - "๐Ÿ’œ", // Purple Heart - "๐Ÿš€", // Rocket - "๐Ÿ‘€", // Eyes - "๐Ÿ’€", // Skull - "๐Ÿฅน", // Face Holding Back Tears - "๐Ÿ", // Snake - "๐Ÿ‰", // Dragon - "๐Ÿฒ", // Dragon Face - "๐Ÿง™โ€โ™‚๏ธ", // Wizard - "๐Ÿช„", // Magic Wand - "๐Ÿดโ€โ˜ ๏ธ", // Pirate Flag - "๐Ÿฆ…", // Eagle (often associated with pirates) - "๐Ÿฆœ", // Parrot (pirate symbol) - "๐Ÿ’ป", // Laptop (hacker symbol) - "๐Ÿ•ถ๏ธ", // Sunglasses (cool guy symbol) - "๐Ÿง‘โ€๐Ÿ’ป", // Technologist - "๐Ÿ‘จโ€๐Ÿ’ป", // Man Technologist - "๐Ÿ‘ฉโ€๐Ÿ’ป", // Woman Technologist - "๐Ÿ•ต๏ธ", // Detective - "๐Ÿ•ต๏ธโ€โ™‚๏ธ", // Man Detective - "๐Ÿ•ต๏ธโ€โ™€๏ธ", // Woman Detective - "๐Ÿ–ฅ๏ธ", // Desktop Computer - "โŒจ๏ธ", // Keyboard - "๐Ÿ–ฑ๏ธ", // Computer Mouse - "๐Ÿ•น๏ธ", // Joystick - "๐Ÿ“ฑ", // Mobile Phone - "๐Ÿ“ฒ", // Mobile Phone with Arrow - "๐Ÿ”“", // Unlocked (hacker symbol) - "๐Ÿ”‘", // Key (hacker symbol) - "๐Ÿ—๏ธ", // Old Key (hacker symbol) - "๐Ÿ›ก๏ธ", // Shield (hacker symbol) - "โš”๏ธ", // Crossed Swords (hacker symbol) - "๐Ÿงฌ", // DNA (hacker symbol) - "๐Ÿงซ", // Petri Dish (hacker symbol) - "๐Ÿงช", // Test Tube (hacker symbol) - "๐Ÿ› ๏ธ", // Hammer and Wrench (hacker symbol) - "โš™๏ธ", // Gear (hacker symbol) - "๐Ÿงฐ", // Toolbox (hacker symbol) - "๐Ÿงฒ", // Magnet (hacker symbol) - "๐Ÿ’ฃ", // Bomb (hacker symbol) - "๐Ÿ•ณ๏ธ", // Hole (hacker symbol) - "๐Ÿ“ก", // Satellite Antenna (hacker symbol) - "๐Ÿ›ฐ๏ธ", // Satellite (hacker symbol) - "๐Ÿ“ž", // Telephone Receiver (hacker symbol) - "โ˜Ž๏ธ", // Telephone (hacker symbol) - "๐Ÿ“Ÿ", // Pager (hacker symbol) - "๐Ÿ“ ", // Fax Machine (hacker symbol) - "๐Ÿ”Œ", // Electric Plug (hacker symbol) - "๐Ÿ’ก", // Light Bulb (hacker symbol) - "๐Ÿ”ฆ", // Flashlight (hacker symbol) - "๐Ÿ•ฏ๏ธ", // Candle (hacker symbol) - "๐Ÿ—ž๏ธ", // Rolled-Up Newspaper (hacker symbol) - "๐Ÿ“œ", // Scroll (hacker symbol) - "๐Ÿ“ƒ", // Page with Curl (hacker symbol) - "๐Ÿ“„", // Page Facing Up (hacker symbol) - "๐Ÿ“‘", // Bookmark Tabs (hacker symbol) - "๐Ÿ“Š", // Bar Chart (hacker symbol) - "๐Ÿ“ˆ", // Chart Increasing (hacker symbol) - "๐Ÿ“‰", // Chart Decreasing (hacker symbol) - "๐Ÿ—‚๏ธ", // Card Index Dividers (hacker symbol) - "๐Ÿ—ƒ๏ธ", // Card File Box (hacker symbol) - "๐Ÿ—„๏ธ", // File Cabinet (hacker symbol) - "๐Ÿ—‘๏ธ", // Wastebasket (hacker symbol) - "๐Ÿ›ข๏ธ", // Oil Drum (hacker symbol) - "๐Ÿ›Ž๏ธ", // Bellhop Bell (hacker symbol) - "๐Ÿงณ", // Luggage (hacker symbol) - "๐Ÿ›Œ", // Person in Bed (hacker symbol) - "๐Ÿ›๏ธ", // Bed (hacker symbol) - "๐Ÿ›‹๏ธ", // Couch and Lamp (hacker symbol) - "๐Ÿช‘", // Chair (hacker symbol) - "๐Ÿšช", // Door (hacker symbol) - "๐Ÿงด", // Lotion Bottle (hacker symbol) - "๐Ÿงท", // Safety Pin (hacker symbol) - "๐Ÿงน", // Broom (hacker symbol) - "๐Ÿงบ", // Basket (hacker symbol) - "๐Ÿงป", // Roll of Paper (hacker symbol) - "๐Ÿงผ", // Soap (hacker symbol) - "๐Ÿงฝ", // Sponge (hacker symbol) - "๐Ÿงฏ", // Fire Extinguisher (hacker symbol) - "๐Ÿ›’", // Shopping Cart (hacker symbol) - "๐Ÿšฌ", // Cigarette (hacker symbol) - "โšฐ๏ธ", // Coffin (hacker symbol) - "โšฑ๏ธ", // Funeral Urn (hacker symbol) - "๐Ÿ—ฟ", // Moai (hacker symbol) - "๐Ÿ›‚", // Passport Control (hacker symbol) - "๐Ÿ›ƒ", // Customs (hacker symbol) - "๐Ÿ›„", // Baggage Claim (hacker symbol) - "๐Ÿ›…", // Left Luggage (hacker symbol) - "๐Ÿšน", // Men's Room (hacker symbol) - "๐Ÿšบ", // Women's Room (hacker symbol) - "๐Ÿšผ", // Baby Symbol (hacker symbol) - "๐Ÿšป", // Restroom (hacker symbol) - "๐Ÿšฎ", // Litter in Bin Sign (hacker symbol) - "๐Ÿšฐ", // Potable Water (hacker symbol) - "๐Ÿšพ", // Water Closet (hacker symbol) - "๐Ÿšญ", // No Smoking (hacker symbol) - "๐Ÿšฏ", // No Littering (hacker symbol) - "๐Ÿšฑ", // Non-Potable Water (hacker symbol) - - // Additional Smileys & Emotion - "๐Ÿ˜Š", // Smiling Face with Smiling Eyes - "๐Ÿ˜‡", // Smiling Face with Halo - "๐Ÿ™‚", // Slightly Smiling Face - "๐Ÿ™ƒ", // Upside-Down Face - "๐Ÿ˜‰", // Winking Face - "๐Ÿ˜Œ", // Relieved Face - "๐Ÿ˜", // Smiling Face with Heart-Eyes - "๐Ÿฅฐ", // Smiling Face with Hearts - "๐Ÿ˜˜", // Face Blowing a Kiss - "๐Ÿ˜—", // Kissing Face - "๐Ÿ˜™", // Kissing Face with Smiling Eyes - "๐Ÿ˜š", // Kissing Face with Closed Eyes - "๐Ÿ˜‹", // Face Savoring Food - "๐Ÿ˜›", // Face with Tongue - "๐Ÿ˜", // Squinting Face with Tongue - "๐Ÿ˜œ", // Winking Face with Tongue - "๐Ÿคช", // Zany Face - - // Additional People & Body - "๐Ÿง‘โ€๐Ÿš€", // Astronaut - "๐Ÿ‘จโ€๐Ÿš€", // Man Astronaut - "๐Ÿ‘ฉโ€๐Ÿš€", // Woman Astronaut - "๐Ÿง‘โ€๐Ÿ”ฌ", // Scientist - "๐Ÿ‘จโ€๐Ÿ”ฌ", // Man Scientist - "๐Ÿ‘ฉโ€๐Ÿ”ฌ", // Woman Scientist - "๐Ÿง‘โ€โš•๏ธ", // Health Worker - "๐Ÿ‘จโ€โš•๏ธ", // Man Health Worker - "๐Ÿ‘ฉโ€โš•๏ธ", // Woman Health Worker - "๐Ÿง‘โ€๐Ÿ”ง", // Mechanic - "๐Ÿ‘จโ€๐Ÿ”ง", // Man Mechanic - "๐Ÿ‘ฉโ€๐Ÿ”ง", // Woman Mechanic - "๐Ÿง‘โ€๐Ÿš’", // Firefighter - "๐Ÿ‘จโ€๐Ÿš’", // Man Firefighter - "๐Ÿ‘ฉโ€๐Ÿš’", // Woman Firefighter - - // Additional Animals & Nature - "๐Ÿฆ’", // Giraffe - "๐Ÿฆ“", // Zebra - "๐Ÿฆฌ", // Bison - "๐Ÿฆ™", // Llama - "๐Ÿฆ˜", // Kangaroo - "๐Ÿฆฅ", // Sloth - "๐Ÿฆฆ", // Otter - "๐Ÿฆก", // Badger - "๐Ÿฆ”", // Hedgehog - "๐Ÿฆ", // Raccoon - "๐Ÿฟ๏ธ", // Chipmunk - "๐Ÿฆซ", // Beaver - "๐ŸฆŽ", // Lizard - "๐ŸŠ", // Crocodile - "๐Ÿข", // Turtle - "๐Ÿฆ•", // Sauropod - "๐Ÿฆ–", // T-Rex - "๐Ÿ‹", // Whale - "๐Ÿฌ", // Dolphin - "๐Ÿฆญ", // Seal - - // Additional Food & Drink - "๐Ÿฅž", // Pancakes - "๐Ÿง‡", // Waffle - "๐Ÿง€", // Cheese Wedge - "๐Ÿ–", // Meat on Bone - "๐Ÿ—", // Poultry Leg - "๐Ÿฅฉ", // Cut of Meat - "๐Ÿฅ“", // Bacon - "๐Ÿ”", // Hamburger - "๐ŸŸ", // French Fries - "๐Ÿ•", // Pizza - "๐ŸŒญ", // Hot Dog - "๐Ÿฅช", // Sandwich - "๐ŸŒฎ", // Taco - "๐ŸŒฏ", // Burrito - "๐Ÿฅ™", // Stuffed Flatbread - "๐Ÿง†", // Falafel - "๐Ÿฅš", // Egg - "๐Ÿณ", // Cooking - "๐Ÿฅ˜", // Shallow Pan of Food - "๐Ÿฒ", // Pot of Food - - // Additional Travel & Places - "๐Ÿ™๏ธ", // Cityscape - "๐ŸŒ†", // Cityscape at Dusk - "๐ŸŒ‡", // Sunset - "๐ŸŒƒ", // Night with Stars - "๐ŸŒ‰", // Bridge at Night - "๐Ÿž๏ธ", // National Park - "๐Ÿœ๏ธ", // Desert - "๐Ÿ๏ธ", // Desert Island - "๐Ÿ–๏ธ", // Beach with Umbrella - "โ›ฐ๏ธ", // Mountain - "๐Ÿ”๏ธ", // Snow-Capped Mountain - "๐ŸŒ‹", // Volcano - "๐Ÿ—ป", // Mount Fuji - "๐Ÿ ", // House - "๐Ÿก", // House with Garden - "๐Ÿข", // Office Building - "๐Ÿฃ", // Japanese Post Office - "๐Ÿค", // Post Office - "๐Ÿฅ", // Hospital - "๐Ÿฆ", // Bank - - // Additional Flags - "๐Ÿ‡บ๐Ÿ‡ธ", // United States - "๐Ÿ‡ฌ๐Ÿ‡ง", // United Kingdom - "๐Ÿ‡จ๐Ÿ‡ฆ", // Canada - "๐Ÿ‡ฏ๐Ÿ‡ต", // Japan - "๐Ÿ‡ฉ๐Ÿ‡ช", // Germany - "๐Ÿ‡ซ๐Ÿ‡ท", // France - "๐Ÿ‡ฎ๐Ÿ‡น", // Italy - "๐Ÿ‡ช๐Ÿ‡ธ", // Spain - "๐Ÿ‡ท๐Ÿ‡บ", // Russia - "๐Ÿ‡จ๐Ÿ‡ณ", // China - "๐Ÿ‡ฎ๐Ÿ‡ณ", // India - "๐Ÿ‡ง๐Ÿ‡ท", // Brazil - "๐Ÿ‡ฆ๐Ÿ‡บ", // Australia - "๐Ÿ‡ฒ๐Ÿ‡ฝ", // Mexico - "๐Ÿ‡ฐ๐Ÿ‡ท", // South Korea - "๐Ÿ‡ฟ๐Ÿ‡ฆ", // South Africa - "๐Ÿ‡ธ๐Ÿ‡ช", // Sweden - "๐Ÿ‡ณ๐Ÿ‡ด", // Norway - "๐Ÿ‡ณ๐Ÿ‡ฟ", // New Zealand - "๐Ÿ‡ฎ๐Ÿ‡ช", // Ireland -]; - // Define emoji categories with specific emojis for each category window.emojiLibrary.EMOJIS = { nature: ["๐ŸŒˆ", "๐ŸŒž", "๐ŸŒ‘", "๐ŸŒ’", "๐ŸŒ“", "๐ŸŒ”", "๐ŸŒ•", "๐ŸŒ–", "๐ŸŒ—", "๐ŸŒ˜", "๐ŸฆŠ", "๐Ÿฆ", "๐Ÿฏ", "๐Ÿฎ", "๐Ÿท", "๐Ÿธ", "๐Ÿต", "๐Ÿ”", "๐Ÿง", "๐Ÿฆ", "๐Ÿค", "๐Ÿฆ†", "๐Ÿฆ…", "๐Ÿฆ‰", "๐Ÿฆ‡", "๐Ÿบ", "๐Ÿ—", "๐Ÿด", "๐Ÿฆ„", "๐Ÿ", "๐Ÿ›", "๐Ÿฆ‹", "๐ŸŒ", "๐Ÿž", "๐Ÿœ", "๐Ÿ•ท๏ธ", "๐Ÿฆ‚", "๐ŸฆŸ", "๐Ÿฆ ", "๐Ÿชฑ"], @@ -505,6 +59,18 @@ window.emojiLibrary.CATEGORIES = [ { id: 'flags', name: 'Flags', icon: '๐Ÿ' } ]; +// Auto-generate EMOJI_LIST from the categorized EMOJIS object +// This ensures a single source of truth for all emojis +window.emojiLibrary.EMOJI_LIST = (() => { + const allEmojis = []; + // Combine all emojis from all categories + Object.values(window.emojiLibrary.EMOJIS).forEach(categoryEmojis => { + allEmojis.push(...categoryEmojis); + }); + // Remove duplicates using Set and return as array + return Array.from(new Set(allEmojis)); +})(); + // Function to render emoji grid with categories window.emojiLibrary.renderEmojiGrid = function(containerId, onEmojiSelect, filteredList) { console.log('Rendering emoji grid to:', containerId); @@ -561,10 +127,12 @@ window.emojiLibrary.renderEmojiGrid = function(containerId, onEmojiSelect, filte // If we have a filtered list (from search), use that emojisToShow = filteredList; } else if (activeCategory === 'all') { - // For 'all' category, combine all emojis from the categories + // For 'all' category, combine all emojis from the categories and deduplicate Object.values(window.emojiLibrary.EMOJIS).forEach(categoryEmojis => { emojisToShow = [...emojisToShow, ...categoryEmojis]; }); + // Remove duplicates using Set + emojisToShow = Array.from(new Set(emojisToShow)); } else if (window.emojiLibrary.EMOJIS[activeCategory]) { // For specific category, use emojis from that category emojisToShow = window.emojiLibrary.EMOJIS[activeCategory]; @@ -607,10 +175,52 @@ window.emojiLibrary.renderEmojiGrid = function(containerId, onEmojiSelect, filte // Re-render the emoji grid with the selected category const selectedCategory = tab.getAttribute('data-category'); console.log('Category selected:', selectedCategory); + + // Determine which emojis to show + let emojisToShow = []; + if (selectedCategory === 'all') { + // For 'all' category, combine all emojis from the categories and deduplicate + Object.values(window.emojiLibrary.EMOJIS).forEach(categoryEmojis => { + emojisToShow = [...emojisToShow, ...categoryEmojis]; + }); + // Remove duplicates using Set + emojisToShow = Array.from(new Set(emojisToShow)); + } else if (window.emojiLibrary.EMOJIS[selectedCategory]) { + // For specific category, use emojis from that category + emojisToShow = window.emojiLibrary.EMOJIS[selectedCategory]; + } + + console.log(`Updating grid with ${emojisToShow.length} emojis for category: ${selectedCategory}`); + + // Clear only the grid and rebuild it + gridContainer.innerHTML = ''; + + // Add emojis to grid + emojisToShow.forEach(emoji => { + const emojiButton = document.createElement('button'); + emojiButton.className = 'emoji-button'; + emojiButton.textContent = emoji; + emojiButton.title = 'Click to encode with this emoji'; + + emojiButton.addEventListener('click', () => { + if (typeof onEmojiSelect === 'function') { + onEmojiSelect(emoji); + // Add visual feedback when clicked + emojiButton.style.backgroundColor = '#e6f7ff'; + setTimeout(() => { + emojiButton.style.backgroundColor = ''; + }, 300); + } + }); + + gridContainer.appendChild(emojiButton); + }); - // Clear and recreate the grid - container.removeChild(gridContainer); - window.emojiLibrary.renderEmojiGrid(containerId, onEmojiSelect); + // Update the count display + const countDisplay = container.querySelector('.emoji-count'); + if (countDisplay) { + countDisplay.textContent = `${emojisToShow.length} emojis available`; + } }); }); diff --git a/js/emojiWordMap.js b/js/emojiWordMap.js new file mode 100644 index 0000000..2b97901 --- /dev/null +++ b/js/emojiWordMap.js @@ -0,0 +1,853 @@ +// Emoji Word Map for Emoji Speak Transform +// Maps emojis to arrays of related keywords +// When a word is typed, a random emoji from matching entries is returned + +window.emojiKeywords = { + // Emotions & Feelings - Happy + '๐Ÿ˜Š': ['happy', 'smile', 'pleased', 'content', 'glad'], + '๐Ÿ˜': ['grin', 'smile', 'happy', 'excited', 'beaming', 'haha', 'ha', 'hehe'], + '๐Ÿ˜‚': ['laugh', 'lol', 'crying', 'tears', 'funny', 'hilarious', 'haha', 'ha', 'hehe'], + '๐Ÿคฃ': ['laugh', 'rofl', 'lol', 'rolling', 'hilarious', 'haha', 'ha', 'hehe'], + '๐Ÿ˜„': ['happy', 'smile', 'joy', 'cheerful', 'haha', 'ha', 'hehe'], + '๐Ÿ˜ƒ': ['happy', 'smile', 'excited', 'haha', 'ha', 'hehe'], + '๐Ÿคฉ': ['excited', 'starstruck', 'wow', 'amazing'], + '๐Ÿ˜': ['love', 'heart', 'adore', 'crush'], + '๐Ÿฅฐ': ['love', 'hearts', 'affection', 'sweet'], + '๐Ÿ˜˜': ['kiss', 'love', 'smooch', 'mwah'], + '๐Ÿ˜‰': ['wink', 'flirt', 'playful'], + + // Emotions - Sad & Negative + '๐Ÿ˜ข': ['sad', 'cry', 'tear', 'upset'], + '๐Ÿ˜ญ': ['cry', 'sobbing', 'bawling', 'sad', 'tears'], + '๐Ÿ˜”': ['sad', 'pensive', 'down', 'disappointed'], + '๐Ÿ˜ž': ['sad', 'disappointed', 'upset', 'lose'], + '๐Ÿ˜Ÿ': ['worried', 'anxious', 'concerned'], + '๐Ÿ˜•': ['confused', 'uncertain', 'puzzled'], + '๐Ÿค”': ['think', 'thinking', 'hmm', 'wonder', 'ponder'], + '๐Ÿ˜': ['neutral', 'meh', 'blank', 'expressionless'], + + // Emotions - Angry + '๐Ÿ˜ก': ['angry', 'mad', 'furious', 'rage', 'pissed'], + '๐Ÿ˜ ': ['angry', 'mad', 'annoyed', 'grumpy'], + '๐Ÿคฌ': ['angry', 'cursing', 'swearing', 'rage'], + + // Emotions - Surprised & Shocked + '๐Ÿ˜ฎ': ['wow', 'surprised', 'shocked', 'amazed'], + '๐Ÿ˜ฒ': ['shocked', 'surprised', 'astonished'], + '๐Ÿ˜ฑ': ['scared', 'shock', 'screaming', 'fear', 'terrified'], + '๐Ÿ˜จ': ['scared', 'fearful', 'afraid', 'anxious'], + + // Emotions - Other + '๐Ÿ˜Ž': ['cool', 'sunglasses', 'smooth', 'slick'], + '๐Ÿ˜ด': ['sleep', 'sleeping', 'tired', 'sleepy', 'zzz'], + '๐Ÿฅฑ': ['tired', 'sleepy', 'bored', 'yawn'], + '๐Ÿ˜ฐ': ['nervous', 'anxious', 'sweat', 'worried'], + '๐Ÿ˜…': ['sweat', 'relief', 'phew', 'nervous'], + '๐Ÿคข': ['sick', 'nauseous', 'ill', 'gross'], + '๐Ÿคฎ': ['sick', 'vomit', 'puke', 'ill'], + '๐Ÿ˜‡': ['angel', 'innocent', 'halo', 'saint'], + '๐Ÿ˜ˆ': ['devil', 'evil', 'mischief', 'naughty'], + '๐Ÿ’€': ['dead', 'skull', 'death', 'dying'], + '๐Ÿ‘ป': ['ghost', 'boo', 'spooky', 'phantom'], + '๐ŸŽ‰': ['party', 'celebrate', 'celebration', 'hooray', 'festive'], + '๐ŸŽŠ': ['party', 'celebrate', 'confetti', 'celebration'], + + // Animals - Pets & Common + '๐Ÿ•': ['dog', 'puppy', 'pet', 'canine', 'pup'], + '๐Ÿถ': ['dog', 'puppy', 'doggy', 'pet', 'pup'], + '๐Ÿฆฎ': ['dog', 'guide', 'service'], + '๐Ÿ•โ€๐Ÿฆบ': ['dog', 'service'], + '๐Ÿฉ': ['dog', 'poodle', 'puppy'], + '๐Ÿฑ': ['cat', 'kitty', 'kitten', 'pet', 'feline'], + '๐Ÿˆ': ['cat', 'kitty', 'feline', 'pet'], + '๐Ÿˆโ€โฌ›': ['cat', 'black'], + '๐Ÿญ': ['mouse', 'mice', 'rodent'], + '๐Ÿน': ['hamster', 'pet', 'rodent'], + '๐Ÿฐ': ['rabbit', 'bunny', 'easter', 'hare'], + '๐Ÿ‡': ['rabbit', 'bunny', 'hare'], + + // Animals - Wild + '๐ŸฆŠ': ['fox', 'foxy', 'sly'], + '๐Ÿป': ['bear', 'teddy'], + '๐Ÿผ': ['panda', 'bear'], + '๐Ÿจ': ['koala', 'bear', 'australian'], + '๐Ÿฏ': ['tiger', 'fierce', 'striped'], + '๐Ÿฆ': ['lion', 'king', 'mane', 'roar'], + '๐Ÿฎ': ['cow', 'cattle', 'moo'], + '๐Ÿท': ['pig', 'piggy', 'oink', 'swine'], + '๐Ÿธ': ['frog', 'toad', 'ribbit'], + '๐Ÿต': ['monkey', 'primate', 'ape'], + '๐Ÿ’': ['monkey', 'primate'], + '๐Ÿฆ': ['gorilla', 'ape', 'kong'], + '๐Ÿฆง': ['orangutan', 'ape'], + '๐Ÿบ': ['wolf', 'howl', 'pack'], + '๐Ÿฆ': ['raccoon', 'trash'], + '๐Ÿด': ['horse', 'pony', 'stallion', 'mare'], + '๐Ÿฆ„': ['unicorn', 'magical', 'fantasy', 'rainbow'], + '๐Ÿฆ“': ['zebra', 'striped', 'stripes'], + '๐ŸฆŒ': ['deer', 'reindeer', 'stag', 'doe'], + '๐Ÿ˜': ['elephant', 'trunk', 'big', 'large'], + '๐Ÿฆ': ['rhino', 'rhinoceros', 'horn'], + '๐Ÿฆ›': ['hippo', 'hippopotamus'], + '๐Ÿฆ’': ['giraffe', 'tall', 'neck'], + + // Animals - Birds + '๐Ÿ”': ['chicken', 'rooster', 'hen', 'poultry'], + '๐Ÿ“': ['rooster', 'chicken', 'cock'], + '๐Ÿฃ': ['chick', 'baby', 'hatching', 'bird'], + '๐Ÿค': ['chick', 'baby', 'bird'], + '๐Ÿฅ': ['chick', 'duckling', 'baby', 'bird'], + '๐Ÿฆ': ['bird', 'birdie', 'tweet'], + '๐Ÿง': ['penguin', 'antarctic', 'bird'], + '๐Ÿฆ†': ['duck', 'quack', 'waterfowl'], + '๐Ÿฆ…': ['eagle', 'bird', 'freedom', 'america'], + '๐Ÿฆ‰': ['owl', 'wise', 'hoot', 'night'], + '๐Ÿฆ‡': ['bat', 'vampire', 'night', 'flying'], + '๐Ÿฆœ': ['parrot', 'bird', 'tropical', 'colorful'], + '๐Ÿฆš': ['peacock', 'bird', 'fancy', 'colorful'], + + // Animals - Insects & Small + '๐Ÿ': ['bee', 'buzz', 'honey', 'bumblebee'], + '๐Ÿ›': ['bug', 'caterpillar', 'worm', 'insect'], + '๐Ÿฆ‹': ['butterfly', 'beautiful', 'insect', 'flying'], + '๐ŸŒ': ['snail', 'slow', 'shell'], + '๐Ÿž': ['ladybug', 'bug', 'insect', 'beetle'], + '๐Ÿœ': ['ant', 'insect', 'small', 'tiny'], + '๐Ÿ•ท๏ธ': ['spider', 'web', 'arachnid', 'creepy'], + '๐Ÿฆ‚': ['scorpion', 'sting', 'desert'], + '๐ŸฆŸ': ['mosquito', 'bug', 'bite', 'annoying'], + + // Animals - Marine + '๐Ÿ': ['snake', 'serpent', 'slither', 'reptile'], + '๐ŸฆŽ': ['lizard', 'reptile', 'gecko'], + '๐ŸŠ': ['alligator', 'crocodile', 'reptile'], + '๐Ÿข': ['turtle', 'tortoise', 'slow', 'shell'], + '๐Ÿ‰': ['dragon', 'fantasy', 'mythical', 'fire'], + '๐Ÿฒ': ['dragon', 'fantasy', 'mythical'], + '๐ŸŸ': ['fish', 'seafood', 'swimming'], + '๐Ÿ ': ['fish', 'tropical', 'colorful'], + '๐Ÿก': ['fish', 'puffer', 'blowfish'], + '๐Ÿฆˆ': ['shark', 'jaws', 'ocean', 'dangerous'], + '๐Ÿ‹': ['whale', 'ocean', 'big', 'huge'], + '๐Ÿฌ': ['dolphin', 'ocean', 'smart', 'friendly'], + '๐Ÿ™': ['octopus', 'tentacles', 'ocean', 'squid'], + '๐Ÿฆ‘': ['squid', 'octopus', 'ocean', 'tentacles'], + '๐Ÿฆ€': ['crab', 'ocean', 'seafood', 'crustacean'], + '๐Ÿฆž': ['lobster', 'seafood', 'ocean', 'crustacean'], + '๐Ÿฆ': ['shrimp', 'prawn', 'seafood', 'ocean'], + '๐Ÿฆช': ['oyster', 'seafood', 'pearl', 'shell'], + + // Food - Fast Food & Main + '๐Ÿ•': ['pizza', 'slice', 'cheese', 'pepperoni', 'italian'], + '๐Ÿ”': ['burger', 'hamburger', 'cheeseburger', 'food'], + '๐ŸŸ': ['fries', 'chips', 'potato', 'french'], + '๐ŸŒญ': ['hotdog', 'dog', 'sausage', 'frank'], + '๐ŸŒฎ': ['taco', 'mexican', 'shell'], + '๐ŸŒฏ': ['burrito', 'mexican', 'wrap'], + '๐Ÿฅ™': ['wrap', 'pita', 'gyro', 'sandwich'], + '๐Ÿฅช': ['sandwich', 'sub', 'lunch'], + '๐Ÿฅ—': ['salad', 'healthy', 'greens', 'vegetables'], + '๐Ÿ': ['pasta', 'spaghetti', 'italian', 'noodles'], + '๐Ÿœ': ['ramen', 'noodles', 'soup', 'asian'], + '๐Ÿฒ': ['stew', 'soup', 'pot', 'food'], + '๐Ÿ›': ['curry', 'rice', 'indian', 'spicy'], + '๐Ÿฃ': ['sushi', 'japanese', 'fish', 'raw'], + '๐Ÿฑ': ['bento', 'lunch', 'japanese', 'box'], + '๐Ÿฅ˜': ['paella', 'food', 'dish', 'pan'], + + // Food - Meat & Protein + '๐Ÿ–': ['meat', 'bone', 'food', 'leg'], + '๐Ÿ—': ['chicken', 'drumstick', 'meat', 'poultry'], + '๐Ÿฅฉ': ['steak', 'meat', 'beef', 'red'], + '๐Ÿฅ“': ['bacon', 'meat', 'breakfast', 'pork'], + '๐Ÿฅš': ['egg', 'breakfast', 'protein'], + '๐Ÿณ': ['cooking', 'egg', 'frying', 'breakfast'], + + // Food - Bread & Baked + '๐Ÿž': ['bread', 'loaf', 'toast', 'baked'], + '๐Ÿฅ': ['croissant', 'bread', 'french', 'pastry'], + '๐Ÿฅ–': ['baguette', 'bread', 'french'], + '๐Ÿฅจ': ['pretzel', 'snack', 'twisted'], + '๐Ÿง€': ['cheese', 'dairy', 'yellow'], + + // Food - Fruits + '๐ŸŽ': ['apple', 'fruit', 'red', 'healthy'], + '๐Ÿ': ['apple', 'fruit', 'green', 'granny'], + '๐ŸŠ': ['orange', 'fruit', 'citrus', 'vitamin'], + '๐Ÿ‹': ['lemon', 'citrus', 'sour', 'yellow'], + '๐ŸŒ': ['banana', 'fruit', 'yellow', 'potassium'], + '๐Ÿ‰': ['watermelon', 'fruit', 'summer', 'juicy'], + '๐Ÿ‡': ['grapes', 'fruit', 'wine', 'purple'], + '๐Ÿ“': ['strawberry', 'berry', 'fruit', 'red'], + '๐Ÿซ': ['blueberry', 'berry', 'fruit', 'blue'], + '๐Ÿˆ': ['melon', 'fruit', 'cantaloupe'], + '๐Ÿ’': ['cherry', 'fruit', 'red', 'cherries'], + '๐Ÿ‘': ['peach', 'fruit', 'fuzzy', 'juicy'], + '๐Ÿฅญ': ['mango', 'fruit', 'tropical', 'juicy'], + '๐Ÿ': ['pineapple', 'fruit', 'tropical', 'spiky'], + '๐Ÿฅฅ': ['coconut', 'tropical', 'palm', 'fruit'], + '๐Ÿฅ': ['kiwi', 'fruit', 'green', 'fuzzy'], + '๐Ÿฅ‘': ['avocado', 'fruit', 'green', 'healthy', 'guac'], + + // Food - Vegetables + '๐Ÿ…': ['tomato', 'vegetable', 'red', 'fruit'], + '๐Ÿฅ”': ['potato', 'vegetable', 'spud', 'tater'], + '๐Ÿฅ•': ['carrot', 'vegetable', 'orange', 'healthy'], + '๐ŸŒฝ': ['corn', 'vegetable', 'yellow', 'maize'], + '๐ŸŒถ๏ธ': ['pepper', 'chili', 'hot', 'spicy', 'jalapeno'], + '๐Ÿซ‘': ['pepper', 'bell', 'vegetable', 'capsicum'], + '๐Ÿฅ’': ['cucumber', 'vegetable', 'green', 'pickle'], + '๐Ÿฅฌ': ['lettuce', 'vegetable', 'green', 'leafy', 'cabbage'], + '๐Ÿฅฆ': ['broccoli', 'vegetable', 'green', 'healthy'], + '๐Ÿง„': ['garlic', 'vegetable', 'flavor', 'bulb'], + '๐Ÿง…': ['onion', 'vegetable', 'layers', 'cry'], + '๐Ÿ„': ['mushroom', 'fungus', 'shroom', 'toadstool'], + + // Food - Desserts & Sweets + '๐Ÿฐ': ['cake', 'dessert', 'birthday', 'sweet', 'slice'], + '๐ŸŽ‚': ['cake', 'birthday', 'celebration', 'candles'], + '๐Ÿง': ['cupcake', 'cake', 'dessert', 'sweet'], + '๐Ÿฅง': ['pie', 'dessert', 'baked', 'slice'], + '๐Ÿช': ['cookie', 'biscuit', 'dessert', 'sweet', 'chocolate'], + '๐Ÿฉ': ['donut', 'doughnut', 'dessert', 'sweet', 'fried'], + '๐Ÿซ': ['chocolate', 'candy', 'sweet', 'cocoa', 'bar'], + '๐Ÿฌ': ['candy', 'sweet', 'sugar', 'wrapper'], + '๐Ÿญ': ['lollipop', 'candy', 'sweet', 'sucker'], + '๐Ÿฎ': ['custard', 'pudding', 'dessert', 'sweet', 'flan'], + '๐Ÿฏ': ['honey', 'sweet', 'bee', 'golden'], + '๐Ÿฆ': ['icecream', 'ice', 'cream', 'dessert', 'cold', 'cone'], + '๐Ÿง': ['shaved', 'ice', 'dessert', 'cold', 'snow'], + '๐Ÿจ': ['icecream', 'ice', 'cream', 'dessert', 'bowl'], + + // Drinks + 'โ˜•': ['coffee', 'cafe', 'espresso', 'latte', 'hot', 'java'], + '๐Ÿต': ['tea', 'green', 'hot', 'cup', 'matcha'], + '๐Ÿงƒ': ['juice', 'box', 'drink', 'kid'], + '๐Ÿฅค': ['soda', 'pop', 'drink', 'cup', 'straw'], + '๐Ÿง‹': ['bubble', 'tea', 'boba', 'drink', 'tapioca'], + '๐Ÿฅ›': ['milk', 'dairy', 'drink', 'white'], + '๐Ÿผ': ['bottle', 'baby', 'milk', 'feeding'], + '๐Ÿบ': ['beer', 'ale', 'alcohol', 'drink', 'brew', 'cheers'], + '๐Ÿป': ['beer', 'cheers', 'drinks', 'celebration', 'toast'], + '๐Ÿท': ['wine', 'alcohol', 'drink', 'red', 'glass'], + '๐Ÿฅ‚': ['champagne', 'celebrate', 'toast', 'cheers', 'sparkling'], + '๐Ÿธ': ['cocktail', 'martini', 'drink', 'alcohol'], + '๐Ÿน': ['cocktail', 'tropical', 'drink', 'vacation'], + '๐ŸงŠ': ['ice', 'cold', 'cube', 'frozen'], + '๐Ÿ’ง': ['water', 'drop', 'liquid', 'droplet'], + + // Body & Gestures + '๐Ÿ‘‹': ['wave', 'hello', 'hi', 'bye', 'hand'], + '๐Ÿคš': ['hand', 'raised', 'stop', 'palm'], + '๐Ÿ–๏ธ': ['hand', 'fingers', 'five', 'palm'], + 'โœ‹': ['hand', 'stop', 'raised', 'palm'], + '๐Ÿ––': ['vulcan', 'spock', 'hand', 'star', 'trek'], + '๐Ÿ‘Œ': ['ok', 'okay', 'good', 'perfect', 'fine'], + '๐ŸคŒ': ['fingers', 'italian', 'pinch', 'hand'], + '๐Ÿค': ['pinch', 'small', 'tiny', 'little'], + 'โœŒ๏ธ': ['peace', 'victory', 'two', 'fingers'], + '๐Ÿคž': ['fingers', 'crossed', 'luck', 'hope'], + '๐ŸคŸ': ['love', 'sign', 'rock', 'hand'], + '๐Ÿค˜': ['rock', 'metal', 'horns', 'devil'], + '๐Ÿค™': ['call', 'phone', 'hang', 'shaka'], + '๐Ÿ‘ˆ': ['point', 'left', 'finger', 'direction'], + '๐Ÿ‘‰': ['point', 'right', 'finger', 'direction'], + '๐Ÿ‘†': ['point', 'up', 'finger', 'direction'], + '๐Ÿ‘‡': ['point', 'down', 'finger', 'direction'], + 'โ˜๏ธ': ['point', 'up', 'one', 'finger'], + '๐Ÿ‘': ['thumbsup', 'good', 'yes', 'like', 'approve', 'up'], + '๐Ÿ‘Ž': ['thumbsdown', 'bad', 'no', 'dislike', 'disapprove', 'down'], + 'โœŠ': ['fist', 'power', 'strength', 'solidarity'], + '๐Ÿ‘Š': ['fist', 'punch', 'bump', 'fight'], + '๐Ÿค›': ['fist', 'punch', 'left', 'bump'], + '๐Ÿคœ': ['fist', 'punch', 'right', 'bump'], + '๐Ÿ‘': ['clap', 'applause', 'hands', 'bravo', 'praise'], + '๐Ÿ™Œ': ['hands', 'raised', 'celebration', 'praise', 'hooray'], + '๐Ÿ‘': ['hands', 'open', 'hug'], + '๐Ÿคฒ': ['hands', 'palms', 'prayer', 'offering'], + '๐Ÿค': ['handshake', 'deal', 'agreement', 'shake'], + '๐Ÿ™': ['pray', 'prayer', 'please', 'thank', 'namaste', 'hands'], + '๐Ÿ’ช': ['muscle', 'strong', 'strength', 'flex', 'arm', 'power'], + '๐Ÿฆต': ['leg', 'kick', 'limb'], + '๐Ÿฆถ': ['foot', 'feet', 'toe'], + '๐Ÿ‘€': ['eyes', 'looking', 'watching', 'see'], + '๐Ÿ‘๏ธ': ['eye', 'see', 'look', 'watch'], + '๐Ÿ‘ƒ': ['nose', 'smell', 'sniff'], + '๐Ÿ‘‚': ['ear', 'hear', 'listen'], + '๐Ÿง ': ['brain', 'smart', 'think', 'intelligent'], + '๐Ÿฆด': ['bone', 'skeleton', 'anatomy'], + '๐Ÿฆท': ['teeth', 'tooth', 'dental', 'dentist'], + '๐Ÿ‘…': ['tongue', 'taste', 'lick'], + '๐Ÿ‘„': ['mouth', 'lips', 'kiss'], + + // People & Professions + '๐Ÿ‘จ': ['man', 'male', 'guy', 'adult'], + '๐Ÿ‘ฉ': ['woman', 'female', 'lady', 'adult'], + '๐Ÿ‘ฆ': ['boy', 'male', 'child', 'kid'], + '๐Ÿ‘ง': ['girl', 'female', 'child', 'kid'], + '๐Ÿ‘ถ': ['baby', 'infant', 'newborn', 'child'], + '๐Ÿง’': ['child', 'kid', 'young'], + '๐Ÿ‘จโ€โš•๏ธ': ['doctor', 'physician', 'medical', 'health'], + '๐Ÿ‘ฉโ€โš•๏ธ': ['doctor', 'nurse', 'medical', 'health'], + '๐Ÿ‘จโ€๐ŸŽ“': ['student', 'graduate', 'scholar', 'education'], + '๐Ÿ‘จโ€๐Ÿซ': ['teacher', 'professor', 'educator', 'instructor'], + '๐Ÿ‘จโ€๐Ÿ’ป': ['programmer', 'developer', 'coder', 'engineer', 'tech'], + '๐Ÿ‘จโ€๐Ÿ”ฌ': ['scientist', 'researcher', 'lab', 'chemistry'], + '๐Ÿ‘จโ€๐ŸŽจ': ['artist', 'painter', 'creative'], + '๐Ÿ‘จโ€๐Ÿณ': ['chef', 'cook', 'culinary'], + '๐Ÿ‘จโ€๐ŸŽค': ['singer', 'musician', 'rockstar', 'performer'], + '๐Ÿ‘จโ€โœˆ๏ธ': ['pilot', 'captain', 'aviator', 'flying'], + '๐Ÿ‘จโ€๐Ÿš€': ['astronaut', 'space', 'cosmonaut'], + '๐Ÿ‘จโ€๐Ÿš’': ['firefighter', 'fireman', 'rescue'], + '๐Ÿ‘ฎ': ['police', 'cop', 'officer', 'law'], + '๐Ÿ•ต๏ธ': ['detective', 'spy', 'investigator', 'sleuth'], + '๐Ÿ’‚': ['guard', 'soldier', 'sentry'], + '๐Ÿฅท': ['ninja', 'stealth', 'martial', 'warrior'], + '๐Ÿ‘ท': ['construction', 'worker', 'builder', 'hardhat'], + '๐Ÿคด': ['prince', 'royal', 'king'], + '๐Ÿ‘ธ': ['princess', 'royal', 'queen'], + '๐Ÿ‘‘': ['crown', 'king', 'queen', 'royal', 'royalty'], + '๐Ÿง™': ['wizard', 'magic', 'sorcerer', 'merlin'], + '๐Ÿงš': ['fairy', 'magical', 'wings', 'pixie'], + '๐Ÿง›': ['vampire', 'dracula', 'blood', 'fangs'], + '๐Ÿงœ': ['mermaid', 'ocean', 'sea', 'mythical'], + '๐Ÿง': ['elf', 'fantasy', 'magical', 'pointed'], + '๐Ÿงž': ['genie', 'wish', 'lamp', 'magical'], + '๐ŸงŸ': ['zombie', 'undead', 'walking', 'dead'], + '๐Ÿฆธ': ['superhero', 'hero', 'super', 'powers'], + '๐Ÿฆน': ['villain', 'evil', 'bad', 'super'], + '๐Ÿคถ': ['mrs', 'claus', 'christmas', 'santa'], + '๐ŸŽ…': ['santa', 'christmas', 'claus', 'father'], + '๐Ÿ‘ผ': ['angel', 'cherub', 'heaven', 'halo'], + '๐Ÿ’': ['kiss', 'couple', 'romance', 'love'], + '๐Ÿ’‘': ['couple', 'love', 'romance', 'heart'], + '๐Ÿ‘ช': ['family', 'parents', 'kids', 'home'], + '๐Ÿค—': ['hug', 'hugging', 'embrace', 'cuddle'], + '๐Ÿคณ': ['selfie', 'photo', 'camera', 'phone'], + + // Activities & Sports + 'โšฝ': ['soccer', 'football', 'ball', 'sport'], + '๐Ÿ€': ['basketball', 'ball', 'sport', 'hoops'], + '๐Ÿˆ': ['football', 'american', 'ball', 'sport'], + 'โšพ': ['baseball', 'ball', 'sport', 'diamond'], + '๐ŸŽพ': ['tennis', 'ball', 'sport', 'racket'], + '๐Ÿ': ['volleyball', 'ball', 'sport', 'beach'], + '๐Ÿ‰': ['rugby', 'football', 'ball', 'sport'], + '๐ŸŽฑ': ['billiards', 'pool', 'eight', 'ball'], + '๐Ÿ“': ['pingpong', 'tabletennis', 'paddle', 'sport'], + '๐Ÿธ': ['badminton', 'shuttlecock', 'sport'], + '๐ŸฅŠ': ['boxing', 'glove', 'fight', 'punch'], + '๐Ÿฅ‹': ['martial', 'arts', 'karate', 'judo', 'gi'], + 'โ›ณ': ['golf', 'hole', 'sport', 'flag'], + '๐Ÿน': ['archery', 'bow', 'arrow', 'target'], + '๐ŸŽฏ': ['target', 'bullseye', 'darts', 'aim'], + '๐Ÿƒ': ['run', 'running', 'jog', 'exercise', 'sprint'], + '๐Ÿšถ': ['walk', 'walking', 'stroll', 'pedestrian'], + '๐Ÿ’ƒ': ['dance', 'dancing', 'salsa', 'party'], + '๐Ÿ•บ': ['dance', 'dancing', 'disco', 'party'], + '๐Ÿคธ': ['gymnastics', 'flip', 'cartwheel', 'jump'], + '๐ŸŠ': ['swim', 'swimming', 'pool', 'water'], + '๐Ÿ„': ['surf', 'surfing', 'wave', 'beach'], + '๐Ÿšด': ['bike', 'cycling', 'bicycle', 'ride'], + '๐Ÿ‹๏ธ': ['lift', 'lifting', 'weights', 'gym', 'workout'], + '๐Ÿคผ': ['wrestle', 'wrestling', 'fight', 'grapple'], + '๐Ÿคบ': ['fencing', 'sword', 'duel', 'sport'], + 'โ›ท๏ธ': ['ski', 'skiing', 'snow', 'sport'], + '๐Ÿ‚': ['snowboard', 'snow', 'sport', 'winter'], + '๐Ÿง—': ['climb', 'climbing', 'rock', 'mountain'], + '๐Ÿง˜': ['yoga', 'meditate', 'meditation', 'zen', 'peace', 'calm'], + '๐ŸŽฎ': ['game', 'gaming', 'videogame', 'play', 'controller'], + '๐ŸŽฒ': ['dice', 'game', 'roll', 'random'], + 'โ™ ๏ธ': ['spade', 'card', 'suit', 'black'], + 'โ™ฅ๏ธ': ['heart', 'card', 'suit', 'love', 'red'], + 'โ™ฆ๏ธ': ['diamond', 'card', 'suit', 'red'], + 'โ™ฃ๏ธ': ['club', 'card', 'suit', 'black'], + '๐ŸŽจ': ['art', 'paint', 'painting', 'artist', 'creative', 'palette'], + '๐ŸŽญ': ['theater', 'drama', 'masks', 'acting', 'performance'], + '๐ŸŽช': ['circus', 'tent', 'carnival', 'show'], + '๐ŸŽฌ': ['movie', 'film', 'cinema', 'action', 'clapper'], + '๐ŸŽค': ['microphone', 'sing', 'singing', 'karaoke', 'mic'], + '๐ŸŽง': ['headphones', 'music', 'audio', 'listen'], + '๐ŸŽต': ['music', 'note', 'musical', 'song'], + '๐ŸŽถ': ['music', 'notes', 'musical', 'song', 'melody'], + '๐ŸŽธ': ['guitar', 'rock', 'music', 'instrument'], + '๐ŸŽน': ['piano', 'keyboard', 'music', 'instrument'], + '๐ŸŽบ': ['trumpet', 'music', 'instrument', 'brass'], + '๐ŸŽป': ['violin', 'music', 'instrument', 'strings'], + '๐Ÿฅ': ['drum', 'drums', 'music', 'instrument'], + '๐Ÿ“š': ['books', 'library', 'study', 'read', 'reading', 'education'], + '๐Ÿ“–': ['book', 'read', 'reading', 'novel', 'open'], + 'โœ๏ธ': ['write', 'writing', 'pen', 'author'], + '๐Ÿ“': ['note', 'memo', 'write', 'paper'], + + // Objects & Technology + '๐Ÿ“ฑ': ['phone', 'mobile', 'cell', 'smartphone', 'iphone'], + 'โ˜Ž๏ธ': ['telephone', 'phone', 'call', 'landline'], + '๐Ÿ“ž': ['telephone', 'phone', 'receiver', 'call'], + '๐Ÿ’ป': ['computer', 'laptop', 'pc', 'mac', 'work'], + 'โŒจ๏ธ': ['keyboard', 'typing', 'computer', 'keys'], + '๐Ÿ–ฑ๏ธ': ['mouse', 'computer', 'click', 'pointer'], + '๐Ÿ–ฅ๏ธ': ['computer', 'desktop', 'monitor', 'screen'], + '๐Ÿ–จ๏ธ': ['printer', 'print', 'copy', 'office'], + '๐Ÿ“ท': ['camera', 'photo', 'picture', 'photography'], + '๐Ÿ“ธ': ['camera', 'photo', 'flash', 'picture'], + '๐Ÿ“น': ['video', 'camera', 'recording', 'film'], + '๐ŸŽฅ': ['movie', 'camera', 'film', 'cinema'], + '๐Ÿ“บ': ['tv', 'television', 'screen', 'watch'], + '๐Ÿ“ป': ['radio', 'music', 'broadcast', 'fm'], + 'โฐ': ['alarm', 'clock', 'time', 'wake'], + 'โฑ๏ธ': ['stopwatch', 'timer', 'time', 'clock'], + 'โฒ๏ธ': ['timer', 'clock', 'countdown'], + '๐Ÿ•': ['clock', 'one', 'time', 'hour'], + 'โŒš': ['watch', 'time', 'clock', 'wrist'], + '๐Ÿ“ก': ['satellite', 'antenna', 'dish', 'signal'], + '๐Ÿ›ฐ๏ธ': ['satellite', 'space', 'orbit', 'gps'], + '๐Ÿ”‹': ['battery', 'power', 'energy', 'charge'], + '๐Ÿ”Œ': ['plug', 'electric', 'power', 'outlet'], + '๐Ÿ’ก': ['lightbulb', 'light', 'idea', 'bright', 'bulb'], + '๐Ÿ”ฆ': ['flashlight', 'torch', 'light', 'beam'], + '๐Ÿ•ฏ๏ธ': ['candle', 'light', 'flame', 'wax'], + + // Tools & Weapons + '๐Ÿ”จ': ['hammer', 'tool', 'nail', 'build'], + '๐Ÿช›': ['screwdriver', 'tool', 'screw', 'fix'], + '๐Ÿ”ง': ['wrench', 'tool', 'mechanic', 'spanner'], + '๐Ÿชš': ['saw', 'tool', 'cut', 'wood'], + 'โš™๏ธ': ['gear', 'cog', 'settings', 'mechanical'], + '๐Ÿ”ฉ': ['bolt', 'nut', 'screw', 'fastener'], + '๐Ÿช“': ['axe', 'chop', 'wood', 'tool'], + 'โš’๏ธ': ['hammer', 'pick', 'tool', 'mine'], + '๐Ÿ› ๏ธ': ['tools', 'hammer', 'wrench', 'repair'], + '๐Ÿ—ก๏ธ': ['sword', 'blade', 'weapon', 'dagger'], + 'โš”๏ธ': ['swords', 'crossed', 'battle', 'fight', 'weapon'], + '๐Ÿ”ช': ['knife', 'blade', 'cut', 'sharp'], + '๐Ÿน': ['bow', 'arrow', 'weapon', 'archery'], + '๐Ÿ›ก๏ธ': ['shield', 'protection', 'defend', 'guard'], + '๐Ÿ’ฃ': ['bomb', 'explosive', 'danger', 'blast'], + '๐Ÿ”ซ': ['gun', 'pistol', 'weapon', 'shoot'], + + // Money & Value + '๐Ÿ’ฐ': ['money', 'bag', 'cash', 'rich', 'dollar', 'wealth'], + '๐Ÿ’ต': ['dollar', 'money', 'bill', 'cash', 'hundred'], + '๐Ÿ’ด': ['yen', 'money', 'japan', 'currency'], + '๐Ÿ’ถ': ['euro', 'money', 'europe', 'currency'], + '๐Ÿ’ท': ['pound', 'money', 'british', 'currency'], + '๐Ÿ’ธ': ['money', 'flying', 'cash', 'spend', 'expense'], + '๐Ÿ’ณ': ['card', 'credit', 'debit', 'payment'], + '๐Ÿ’Ž': ['diamond', 'gem', 'jewel', 'precious', 'valuable'], + '๐Ÿ‘‘': ['crown', 'royal', 'king', 'queen'], + '๐Ÿ’': ['ring', 'diamond', 'wedding', 'engagement', 'jewelry'], + '๐Ÿ†': ['trophy', 'award', 'win', 'champion', 'prize', 'first'], + '๐Ÿฅ‡': ['gold', 'medal', 'first', 'win', 'champion'], + '๐Ÿฅˆ': ['silver', 'medal', 'second', 'place'], + '๐Ÿฅ‰': ['bronze', 'medal', 'third', 'place'], + '๐Ÿ…': ['medal', 'award', 'gold', 'achievement'], + + // Office & School + 'โœ๏ธ': ['pencil', 'write', 'draw', 'school'], + 'โœ’๏ธ': ['pen', 'write', 'ink', 'fountain'], + '๐Ÿ–Š๏ธ': ['pen', 'write', 'ballpoint'], + '๐Ÿ–‹๏ธ': ['pen', 'fountain', 'write', 'ink'], + '๐Ÿ“': ['ruler', 'measure', 'straight', 'school'], + '๐Ÿ“': ['triangle', 'ruler', 'geometry', 'school'], + 'โœ‚๏ธ': ['scissors', 'cut', 'snip', 'craft'], + '๐Ÿ“Œ': ['pin', 'pushpin', 'tack', 'attach'], + '๐Ÿ“': ['pin', 'location', 'map', 'place'], + '๐Ÿ–‡๏ธ': ['paperclip', 'clip', 'attach', 'office'], + '๐Ÿ“Ž': ['paperclip', 'clip', 'attach', 'office'], + '๐Ÿ“„': ['paper', 'document', 'page', 'file'], + '๐Ÿ“ƒ': ['paper', 'page', 'curl', 'document'], + '๐Ÿ“‹': ['clipboard', 'paper', 'document', 'list'], + '๐Ÿ“': ['folder', 'file', 'directory', 'organize'], + '๐Ÿ“‚': ['folder', 'open', 'file', 'directory'], + '๐Ÿ—‚๏ธ': ['dividers', 'index', 'tabs', 'organize'], + '๐Ÿ“ฐ': ['newspaper', 'news', 'article', 'press'], + '๐Ÿ“œ': ['scroll', 'paper', 'ancient', 'document'], + '๐Ÿ“ฆ': ['box', 'package', 'parcel', 'shipping', 'delivery'], + 'โœ‰๏ธ': ['envelope', 'mail', 'letter', 'message'], + '๐Ÿ“ง': ['email', 'mail', 'message', 'inbox'], + '๐Ÿ“ฎ': ['mailbox', 'post', 'mail', 'letter'], + '๐ŸŽ': ['gift', 'present', 'box', 'wrapped', 'surprise'], + '๐ŸŽ€': ['ribbon', 'bow', 'gift', 'pretty'], + '๐ŸŽˆ': ['balloon', 'party', 'celebration', 'float'], + + // Transportation - Cars + '๐Ÿš—': ['car', 'auto', 'vehicle', 'drive', 'automobile'], + '๐Ÿš•': ['taxi', 'cab', 'ride', 'yellow'], + '๐Ÿš™': ['suv', 'car', 'vehicle', 'truck'], + '๐ŸŽ๏ธ': ['racecar', 'fast', 'racing', 'formula'], + '๐Ÿš“': ['police', 'cop', 'car', 'patrol'], + '๐Ÿš‘': ['ambulance', 'emergency', 'medical', 'hospital'], + '๐Ÿš’': ['firetruck', 'fire', 'emergency', 'truck'], + '๐Ÿšš': ['truck', 'delivery', 'moving', 'lorry'], + '๐Ÿš›': ['truck', 'semi', 'lorry', 'trailer'], + '๐Ÿš': ['van', 'minibus', 'vehicle'], + '๐ŸšŒ': ['bus', 'coach', 'transit', 'public'], + + // Transportation - Other + '๐Ÿšฒ': ['bike', 'bicycle', 'cycle', 'pedal'], + '๐Ÿ๏ธ': ['motorcycle', 'bike', 'motorbike', 'chopper'], + '๐Ÿ›ต': ['scooter', 'moped', 'vespa'], + '๐Ÿ›ด': ['scooter', 'kick', 'ride'], + 'โœˆ๏ธ': ['airplane', 'plane', 'flight', 'fly', 'jet'], + '๐Ÿ›ฉ๏ธ': ['plane', 'small', 'aircraft'], + '๐Ÿš': ['helicopter', 'chopper', 'heli', 'copter'], + '๐Ÿš‚': ['train', 'locomotive', 'steam', 'railway'], + '๐Ÿšƒ': ['train', 'railway', 'car', 'tram'], + '๐Ÿš„': ['train', 'highspeed', 'bullet', 'fast'], + '๐Ÿš…': ['train', 'bullet', 'fast', 'shinkansen'], + '๐Ÿš†': ['train', 'railway', 'metro'], + '๐Ÿš‡': ['subway', 'metro', 'underground', 'tube'], + '๐Ÿšˆ': ['train', 'light', 'rail', 'tram'], + '๐Ÿš‰': ['station', 'train', 'railway', 'metro'], + '๐ŸšŠ': ['tram', 'trolley', 'streetcar'], + '๐Ÿš': ['monorail', 'train', 'elevated'], + 'โ›ต': ['sailboat', 'boat', 'sail', 'yacht'], + '๐Ÿšค': ['speedboat', 'boat', 'fast', 'motor'], + '๐Ÿ›ฅ๏ธ': ['boat', 'motor', 'yacht', 'ship'], + '๐Ÿ›ณ๏ธ': ['ship', 'cruise', 'passenger', 'boat'], + 'โ›ด๏ธ': ['ferry', 'boat', 'ship', 'passenger'], + '๐Ÿšข': ['ship', 'boat', 'cruise', 'vessel'], + 'โš“': ['anchor', 'ship', 'boat', 'navy'], + '๐Ÿš€': ['rocket', 'space', 'launch', 'nasa', 'shuttle'], + '๐Ÿ›ธ': ['ufo', 'alien', 'flying', 'saucer', 'spaceship'], + + // Nature & Weather + 'โ˜€๏ธ': ['sun', 'sunny', 'bright', 'day', 'sunshine'], + '๐ŸŒž': ['sun', 'face', 'sunny', 'bright'], + 'โญ': ['star', 'bright', 'shine', 'sparkle'], + '๐ŸŒŸ': ['star', 'glowing', 'shine', 'sparkle', 'shiny'], + 'โœจ': ['sparkles', 'stars', 'shine', 'magic', 'magical', 'twinkle'], + '๐Ÿ’ซ': ['dizzy', 'star', 'sparkle', 'shine'], + '๐ŸŒ™': ['moon', 'crescent', 'night', 'lunar'], + '๐ŸŒš': ['moon', 'new', 'dark', 'face'], + '๐ŸŒ›': ['moon', 'quarter', 'face'], + '๐ŸŒœ': ['moon', 'quarter', 'face'], + '๐ŸŒ': ['moon', 'full', 'face'], + 'โ˜๏ธ': ['cloud', 'cloudy', 'weather', 'sky'], + 'โ›…': ['cloud', 'sun', 'partly', 'weather'], + 'โ›ˆ๏ธ': ['storm', 'thunder', 'lightning', 'cloud', 'weather'], + '๐ŸŒค๏ธ': ['sun', 'cloud', 'partly', 'weather'], + '๐ŸŒฅ๏ธ': ['cloud', 'sun', 'behind', 'weather'], + '๐ŸŒฆ๏ธ': ['sun', 'rain', 'weather', 'cloud'], + '๐ŸŒง๏ธ': ['rain', 'rainy', 'weather', 'cloud', 'wet'], + '๐ŸŒจ๏ธ': ['snow', 'snowing', 'weather', 'cloud', 'cold'], + '๐ŸŒฉ๏ธ': ['cloud', 'lightning', 'storm', 'weather'], + '๐ŸŒช๏ธ': ['tornado', 'cyclone', 'twister', 'wind', 'storm'], + '๐ŸŒซ๏ธ': ['fog', 'foggy', 'misty', 'weather'], + '๐ŸŒฌ๏ธ': ['wind', 'blow', 'windy', 'weather'], + '๐Ÿ’จ': ['wind', 'blow', 'dash', 'fast', 'air'], + '๐ŸŒ€': ['cyclone', 'hurricane', 'typhoon', 'spiral'], + '๐ŸŒˆ': ['rainbow', 'colorful', 'colors', 'pride', 'weather'], + 'โ˜‚๏ธ': ['umbrella', 'rain', 'protect', 'weather'], + 'โ›ฑ๏ธ': ['umbrella', 'beach', 'sun', 'shade'], + 'โšก': ['lightning', 'bolt', 'electric', 'fast', 'zap', 'thunder'], + 'โ„๏ธ': ['snowflake', 'snow', 'cold', 'winter', 'frozen'], + 'โ˜ƒ๏ธ': ['snowman', 'snow', 'winter', 'cold'], + 'โ›„': ['snowman', 'snow', 'winter', 'frosty'], + 'โ˜„๏ธ': ['comet', 'meteor', 'space', 'shooting'], + '๐Ÿ”ฅ': ['fire', 'flame', 'hot', 'burn', 'lit'], + '๐Ÿ’ง': ['water', 'drop', 'wet', 'liquid'], + '๐ŸŒŠ': ['water', 'ocean', 'wave', 'sea', 'beach', 'surf'], + + // Plants & Nature + '๐ŸŒฒ': ['tree', 'evergreen', 'pine', 'forest'], + '๐ŸŒณ': ['tree', 'deciduous', 'forest', 'nature'], + '๐ŸŒด': ['palm', 'tree', 'tropical', 'beach'], + '๐ŸŒต': ['cactus', 'desert', 'prickly', 'arizona'], + '๐ŸŒพ': ['grain', 'wheat', 'rice', 'farm'], + '๐ŸŒฟ': ['herb', 'leaf', 'plant', 'green'], + 'โ˜˜๏ธ': ['shamrock', 'clover', 'irish', 'luck', 'green'], + '๐Ÿ€': ['clover', 'fourleaf', 'luck', 'lucky', 'irish'], + '๐Ÿ': ['leaf', 'maple', 'autumn', 'fall', 'canada'], + '๐Ÿ‚': ['leaves', 'leaf', 'autumn', 'fall'], + '๐Ÿƒ': ['leaves', 'leaf', 'blow', 'wind'], + '๐ŸŒฑ': ['plant', 'seedling', 'sprout', 'grow', 'new'], + '๐ŸŒท': ['tulip', 'flower', 'spring', 'pretty'], + '๐ŸŒธ': ['flower', 'cherry', 'blossom', 'pink', 'spring'], + '๐ŸŒน': ['rose', 'flower', 'red', 'love', 'romantic'], + '๐Ÿฅ€': ['wilted', 'flower', 'rose', 'dead', 'sad'], + '๐ŸŒบ': ['hibiscus', 'flower', 'tropical', 'colorful'], + '๐ŸŒป': ['sunflower', 'flower', 'yellow', 'summer'], + '๐ŸŒผ': ['blossom', 'flower', 'daisy', 'spring'], + '๐ŸŒฝ': ['corn', 'maize', 'vegetable', 'farm'], + '๐Ÿ„': ['mushroom', 'fungus', 'toadstool', 'shroom'], + + // Earth & Geography + '๐ŸŒ': ['earth', 'globe', 'world', 'europe', 'africa', 'planet'], + '๐ŸŒŽ': ['earth', 'globe', 'world', 'americas', 'planet'], + '๐ŸŒ': ['earth', 'globe', 'world', 'asia', 'australia', 'planet'], + '๐ŸŒ': ['globe', 'world', 'internet', 'www', 'web'], + '๐Ÿ—บ๏ธ': ['map', 'world', 'geography', 'navigation'], + '๐Ÿงญ': ['compass', 'direction', 'navigation', 'north'], + 'โ›ฐ๏ธ': ['mountain', 'peak', 'high', 'climb'], + '๐Ÿ”๏ธ': ['mountain', 'snow', 'peak', 'alps'], + '๐Ÿ—ป': ['mountain', 'fuji', 'japan', 'volcano'], + '๐ŸŒ‹': ['volcano', 'eruption', 'lava', 'mountain'], + '๐Ÿ•๏ธ': ['camping', 'camp', 'tent', 'outdoors'], + '๐Ÿ–๏ธ': ['beach', 'sand', 'ocean', 'vacation', 'umbrella'], + '๐Ÿ๏ธ': ['island', 'desert', 'tropical', 'beach'], + '๐Ÿœ๏ธ': ['desert', 'sand', 'hot', 'dry'], + '๐Ÿž๏ธ': ['park', 'national', 'nature', 'scenic'], + '๐ŸŒ„': ['sunrise', 'mountain', 'dawn', 'morning'], + '๐ŸŒ…': ['sunrise', 'sunset', 'dusk', 'dawn'], + '๐ŸŒ†': ['cityscape', 'city', 'dusk', 'buildings'], + '๐ŸŒ‡': ['sunset', 'city', 'dusk', 'buildings'], + '๐ŸŒƒ': ['night', 'stars', 'city', 'buildings'], + + // Buildings + '๐Ÿ ': ['home', 'house', 'building', 'residence'], + '๐Ÿก': ['house', 'home', 'garden', 'building'], + '๐Ÿ˜๏ธ': ['houses', 'neighborhood', 'residential', 'homes'], + '๐Ÿš๏ธ': ['house', 'abandoned', 'derelict', 'old'], + '๐Ÿข': ['building', 'office', 'corporate', 'business'], + '๐Ÿฃ': ['post', 'office', 'mail', 'building'], + '๐Ÿค': ['post', 'office', 'european', 'building'], + '๐Ÿฅ': ['hospital', 'medical', 'health', 'doctor', 'building'], + '๐Ÿฆ': ['bank', 'money', 'finance', 'building'], + '๐Ÿจ': ['hotel', 'motel', 'lodging', 'building'], + '๐Ÿฉ': ['love', 'hotel', 'heart', 'building'], + '๐Ÿช': ['store', 'shop', 'convenience', 'building'], + '๐Ÿซ': ['school', 'education', 'building', 'learn'], + '๐Ÿฌ': ['store', 'department', 'shopping', 'building'], + '๐Ÿญ': ['factory', 'industrial', 'manufacturing', 'building'], + '๐Ÿฏ': ['castle', 'japanese', 'building', 'historic'], + '๐Ÿฐ': ['castle', 'european', 'building', 'palace', 'fortress'], + 'โ›ช': ['church', 'religious', 'christian', 'building'], + '๐Ÿ•Œ': ['mosque', 'islam', 'religious', 'temple', 'building'], + '๐Ÿ›•': ['temple', 'hindu', 'religious', 'building'], + '๐Ÿ•': ['synagogue', 'jewish', 'religious', 'building'], + 'โ›ฉ๏ธ': ['shrine', 'torii', 'japan', 'religious'], + '๐Ÿ—ผ': ['tower', 'tokyo', 'eiffel', 'tall'], + '๐Ÿ—ฝ': ['liberty', 'statue', 'freedom', 'america', 'newyork'], + 'โ›บ': ['tent', 'camping', 'outdoors', 'shelter'], + + // Symbols & Concepts + 'โœ…': ['check', 'yes', 'correct', 'done', 'tick', 'approve', 'โœ“'], + 'โŒ': ['x', 'no', 'wrong', 'cross', 'cancel', 'error', 'โœ—', 'โœ–'], + 'โœ”๏ธ': ['check', 'tick', 'yes', 'done', 'correct', 'โœ“'], + 'โœ–๏ธ': ['x', 'multiply', 'cross', 'cancel', 'โœ–', 'โœ—'], + 'โ“': ['question', 'help', 'unknown', 'ask', 'confused', '?'], + 'โ”': ['question', 'mark', 'white', 'ask', '?'], + 'โ—': ['exclamation', 'important', 'warning', 'attention', '!'], + 'โ•': ['exclamation', 'mark', 'white', 'attention', '!'], + 'โš ๏ธ': ['warning', 'caution', 'danger', 'alert', 'โš '], + '๐Ÿšซ': ['prohibited', 'forbidden', 'no', 'banned', 'x'], + '๐Ÿ›‘': ['stop', 'sign', 'halt', 'octagon'], + 'โ˜ ๏ธ': ['skull', 'crossbones', 'danger', 'poison', 'death', 'pirate'], + 'โ˜ข๏ธ': ['radioactive', 'nuclear', 'danger', 'toxic'], + 'โ˜ฃ๏ธ': ['biohazard', 'danger', 'toxic', 'contamination'], + '๐Ÿ†•': ['new', 'fresh', 'latest', 'recent'], + '๐Ÿ†“': ['free', 'gratis', 'complimentary'], + '๐Ÿ†™': ['up', 'increase', 'arrow', 'level', 'โ†‘'], + '๐Ÿ†’': ['cool', 'awesome', 'nice'], + '๐Ÿ”ž': ['eighteen', 'adult', 'mature', 'nsfw'], + '๐Ÿ’ฏ': ['hundred', 'perfect', 'full', 'complete', 'score', '100%'], + '๐Ÿ”ด': ['red', 'circle', 'dot'], + '๐ŸŸ ': ['orange', 'circle', 'dot'], + '๐ŸŸก': ['yellow', 'circle', 'dot'], + '๐ŸŸข': ['green', 'circle', 'dot'], + '๐Ÿ”ต': ['blue', 'circle', 'dot'], + '๐ŸŸฃ': ['purple', 'circle', 'dot'], + '๐ŸŸค': ['brown', 'circle', 'dot'], + 'โšซ': ['black', 'circle', 'dot'], + 'โšช': ['white', 'circle', 'dot'], + + // Arrows & Directions + 'โฌ†๏ธ': ['up', 'arrow', 'north', 'direction', 'increase', 'โ†‘', '^'], + 'โ†—๏ธ': ['up', 'right', 'arrow', 'northeast', 'direction', 'โ†—'], + 'โžก๏ธ': ['right', 'arrow', 'east', 'direction', 'forward', 'โ†’'], + 'โ–ถ๏ธ': ['right', 'play', 'forward', 'next'], + 'โ†˜๏ธ': ['down', 'right', 'arrow', 'southeast', 'direction', 'โ†˜'], + 'โฌ‡๏ธ': ['down', 'arrow', 'south', 'direction', 'decrease', 'โ†“', 'v'], + 'โ†™๏ธ': ['down', 'left', 'arrow', 'southwest', 'direction', 'โ†™'], + 'โฌ…๏ธ': ['left', 'arrow', 'west', 'direction', 'back', 'โ†'], + 'โ—€๏ธ': ['left', 'play', 'back', 'previous'], + 'โ†–๏ธ': ['up', 'left', 'arrow', 'northwest', 'direction', 'โ†–'], + 'โ†•๏ธ': ['up', 'down', 'arrow', 'vertical', 'โ†•'], + 'โ†”๏ธ': ['left', 'right', 'arrow', 'horizontal', 'โ†”'], + 'โ†ฉ๏ธ': ['back', 'return', 'arrow', 'reply', 'โ†ฉ'], + 'โ†ช๏ธ': ['forward', 'arrow', 'continue', 'โ†ช'], + 'โคด๏ธ': ['up', 'arrow', 'curve', 'โคด'], + 'โคต๏ธ': ['down', 'arrow', 'curve', 'โคต'], + '๐Ÿ”„': ['refresh', 'reload', 'repeat', 'cycle', 'โ†ป'], + '๐Ÿ”': ['repeat', 'loop', 'arrows', 'cycle', 'โ†ป'], + '๐Ÿ”€': ['shuffle', 'random', 'twist', 'arrows', 'โ†น'], + '๐Ÿ”ƒ': ['reload', 'vertical', 'arrows', 'refresh', 'โ†บ'], + '๐Ÿ”': ['top', 'up', 'arrow', 'back', 'โ†‘'], + '๐Ÿ”š': ['end', 'finish', 'last', 'final'], + '๐Ÿ”™': ['back', 'return', 'arrow', 'previous'], + '๐Ÿ”›': ['on', 'arrow', 'activate'], + '๐Ÿ”œ': ['soon', 'arrow', 'coming'], + + // Math & Symbols + 'โž•': ['plus', 'add', 'positive', 'more', 'addition', '+'], + 'โž–': ['minus', 'subtract', 'negative', 'less', 'subtraction', '-'], + 'โœ–๏ธ': ['multiply', 'times', 'multiplication', 'x', 'โœ–', 'โœ—', '*'], + 'โž—': ['divide', 'division', 'split', 'รท', '/'], + '๐ŸŸฐ': ['equals', 'equal', 'same', '='], + 'โ™พ๏ธ': ['infinity', 'unlimited', 'endless', 'forever', 'โˆž'], + '๐Ÿ’ฑ': ['currency', 'exchange', 'money', 'forex'], + '๐Ÿ’ฒ': ['dollar', 'money', 'currency', 'heavy', '$'], + '๐Ÿ’ฏ': ['percent', '100', '100%', '%'], + '#๏ธโƒฃ': ['hash', 'number', 'hashtag', 'pound', '#'], + '*๏ธโƒฃ': ['asterisk', 'star', 'wildcard', '*'], + 'ใ€ฝ๏ธ': ['part', 'alternation', 'mark', 'wavy', 'ใ€ฝ', '~'], + 'ยฉ๏ธ': ['copyright', 'copy', 'ยฉ', '(c)'], + 'ยฎ๏ธ': ['registered', 'trademark', 'ยฎ', '(r)'], + 'โ„ข๏ธ': ['trademark', 'โ„ข', '(tm)'], + + // Hearts & Love + 'โค๏ธ': ['heart', 'love', 'red', 'romance', 'โค', '<3'], + '๐Ÿงก': ['orange', 'heart', 'love', 'โค', '<3'], + '๐Ÿ’›': ['yellow', 'heart', 'love', 'friendship', 'โค', '<3'], + '๐Ÿ’š': ['green', 'heart', 'love', 'nature', 'โค', '<3'], + '๐Ÿ’™': ['blue', 'heart', 'love', 'โค', '<3'], + '๐Ÿ’œ': ['purple', 'heart', 'love', 'โค', '<3'], + '๐Ÿ–ค': ['black', 'heart', 'dark', 'love', 'โค', '<3'], + '๐Ÿค': ['white', 'heart', 'pure', 'love', 'โค', '<3'], + '๐ŸคŽ': ['brown', 'heart', 'love', 'โค', '<3'], + '๐Ÿ’”': ['broken', 'heart', 'heartbreak', 'sad', 'breakup', ' this.map[c] || c).reverse().join(''); }, preview: function(text) { - if (!text) return '[binary]'; - const firstChar = text.charAt(0); - return firstChar.charCodeAt(0).toString(2).padStart(8, '0') + '...'; + if (!text) return '[upside down]'; + return this.func(text.slice(0, 8)); }, reverse: function(text) { const revMap = this.reverseMap(); @@ -80,9 +79,8 @@ const transforms = { return [...text.toLowerCase()].map(c => this.map[c] || c).join(''); }, preview: function(text) { - if (!text) return '[hex]'; - const firstChar = text.charAt(0); - return firstChar.charCodeAt(0).toString(16).padStart(2, '0') + '...'; + if (!text) return '[runes]'; + return this.func(text.slice(0, 5)); }, reverse: function(text) { const revMap = this.reverseMap(); @@ -96,8 +94,8 @@ const transforms = { return [...text].join(' '); }, preview: function(text) { - if (!text) return '[base64]'; - return btoa(text.slice(0, 3)) + '...'; + if (!text) return '[vaporwave]'; + return [...text.slice(0, 3)].join(' ') + '...'; }, reverse: function(text) { // Remove spaces between characters @@ -248,11 +246,19 @@ const transforms = { base64: { name: 'Base64', func: function(text) { - return btoa(text); + try { + return btoa(text); + } catch (e) { + return '[Invalid input]'; + } }, preview: function(text) { if (!text) return '[base64]'; - return btoa(text.slice(0, 3)) + '...'; + try { + return btoa(text.slice(0, 3)) + '...'; + } catch (e) { + return '[Invalid input]'; + } }, reverse: function(text) { try { @@ -267,8 +273,12 @@ const transforms = { name: 'Base64 URL', func: function(text) { if (!text) return ''; - const std = btoa(text); - return std.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/,''); + try { + const std = btoa(text); + return std.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/,''); + } catch (e) { + return '[Invalid input]'; + } }, preview: function(text) { if (!text) return '[b64url]'; @@ -689,7 +699,12 @@ const transforms = { url: { name: 'URL Encode', func: function(text) { - return encodeURIComponent(text); + try { + return encodeURIComponent(text); + } catch (e) { + // Catch malformed Unicode or unpaired surrogates + return '[Invalid input]'; + } }, preview: function(text) { return this.func(text); @@ -912,7 +927,8 @@ const transforms = { return text.split('').map(char => this.map[char] || char).join(''); }, preview: function(text) { - return text.substring(0, 10) + (text.length > 10 ? '...' : ''); + if (!text) return '[greek]'; + return this.func(text.slice(0, 10)); }, reverseMap: function() { if (!this._reverseMap) { @@ -951,7 +967,8 @@ const transforms = { return text.split('').map(char => this.map[char] || char).join(''); }, preview: function(text) { - return text.substring(0, 10) + (text.length > 10 ? '...' : ''); + if (!text) return '[wingdings]'; + return this.func(text.slice(0, 10)); }, reverseMap: function() { if (!this._reverseMap) { @@ -1032,17 +1049,37 @@ const transforms = { 'S': 'S', 'T': 'T', 'U': 'U', 'V': 'V', 'W': 'W', 'X': 'X', 'Y': 'Y', 'Z': 'Z' }, func: function(text) { - return [...text.toLowerCase()].map(c => this.map[c] || c).join(''); + // Process character by character, preserving case + return [...text].map(c => this.map[c] || c).join(''); }, preview: function(text) { - return this.func(text); + if (!text) return '[klingon]'; + return this.func(text.slice(0, 8)); }, reverse: function(text) { + // Build reverse map with multi-character strings const revMap = {}; for (const [key, value] of Object.entries(this.map)) { revMap[value] = key; } - return [...text].map(c => revMap[c] || c).join(''); + // Try to match multi-character sequences first, then single chars + let result = ''; + let i = 0; + while (i < text.length) { + // Try 2-character match first (for 'ch', 'gh', 'CH', 'GH') + const twoChar = text.substr(i, 2); + if (revMap[twoChar]) { + result += revMap[twoChar]; + i += 2; + } else if (revMap[text[i]]) { + result += revMap[text[i]]; + i++; + } else { + result += text[i]; + i++; + } + } + return result; } }, @@ -2077,20 +2114,70 @@ const transforms = { }, // Emoji Speak (word โ†’ emoji, digits โ†’ keycaps) + // Emoji keywords loaded from emojiWordMap.js emoji_speak: { name: 'Emoji Speak', - wordMap: { - 'love':'โค๏ธ','heart':'โค๏ธ','fire':'๐Ÿ”ฅ','cool':'๐Ÿ˜Ž','ok':'๐Ÿ‘Œ','star':'โญ','poop':'๐Ÿ’ฉ','yes':'โœ…','no':'โŒ', - 'up':'โฌ†๏ธ','down':'โฌ‡๏ธ','left':'โฌ…๏ธ','right':'โžก๏ธ','question':'โ“','exclamation':'โ—' - }, digitMap: {'0':'0๏ธโƒฃ','1':'1๏ธโƒฃ','2':'2๏ธโƒฃ','3':'3๏ธโƒฃ','4':'4๏ธโƒฃ','5':'5๏ธโƒฃ','6':'6๏ธโƒฃ','7':'7๏ธโƒฃ','8':'8๏ธโƒฃ','9':'9๏ธโƒฃ'}, func: function(text) { - // replace digits + // Replace digits with keycap emojis let out = [...text].map(c => this.digitMap[c] || c).join(''); - // replace words (case-insensitive) - for (const [word, emoji] of Object.entries(this.wordMap)) { - const re = new RegExp(`\\b${word}\\b`, 'gi'); - out = out.replace(re, emoji); + + // Replace words with emojis using keyword lookup + if (window.emojiKeywords) { + // Split into words while preserving spaces and punctuation + const words = out.match(/\b\w+\b/g); + if (words) { + // Process each unique word + const processed = new Set(); + for (const word of words) { + const lower = word.toLowerCase(); + if (processed.has(lower)) continue; + processed.add(lower); + + // Find all emojis that have this word as a keyword + const matchingEmojis = []; + for (const [emoji, keywords] of Object.entries(window.emojiKeywords)) { + if (keywords.includes(lower)) { + matchingEmojis.push(emoji); + } + } + + // If we found matches, replace with a random one + if (matchingEmojis.length > 0) { + const randomEmoji = matchingEmojis[Math.floor(Math.random() * matchingEmojis.length)]; + const re = new RegExp(`\\b${word}\\b`, 'gi'); + out = out.replace(re, randomEmoji); + } + } + } + + // Second pass: Replace single characters and symbols (?, !, <3, arrows, etc.) + // Build a map of all single-char/symbol keywords + const symbolMap = new Map(); + for (const [emoji, keywords] of Object.entries(window.emojiKeywords)) { + for (const keyword of keywords) { + // Only consider symbols (non-word characters or very short patterns) + // Exclude single digits since they're already handled by digitMap + if (keyword.length <= 3 && !/^\w+$/.test(keyword) && !/^\d$/.test(keyword)) { + if (!symbolMap.has(keyword)) { + symbolMap.set(keyword, []); + } + symbolMap.get(keyword).push(emoji); + } + } + } + + // Replace symbols (longest first to handle multi-char like <3 before <) + const sortedSymbols = Array.from(symbolMap.keys()).sort((a, b) => b.length - a.length); + for (const symbol of sortedSymbols) { + if (out.includes(symbol)) { + const matchingEmojis = symbolMap.get(symbol); + const randomEmoji = matchingEmojis[Math.floor(Math.random() * matchingEmojis.length)]; + // Escape special regex characters + const escaped = symbol.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + out = out.replace(new RegExp(escaped, 'g'), randomEmoji); + } + } } return out; }, @@ -2227,7 +2314,10 @@ const transforms = { }, preview: function(text) { if (!text) return '[rev words]'; - return this.func(text.split(/\s+/).slice(0,2).join(' ')) + '...'; + // Take last 2-3 words and reverse them to show the effect + const words = text.split(/\s+/); + const lastWords = words.slice(-3).join(' '); + return this.func(lastWords) + '...'; }, reverse: function(text) { // Reversing words twice restores